Skip to content

Commit

Permalink
Merge pull request #1744 from murgatroid99/proto-loader_null_message_…
Browse files Browse the repository at this point in the history
…type

proto-loader: generator: allow for null message values
  • Loading branch information
murgatroid99 committed Apr 14, 2021
2 parents 48afaf1 + 799bd16 commit aefc9d1
Show file tree
Hide file tree
Showing 18 changed files with 72 additions and 71 deletions.
39 changes: 20 additions & 19 deletions packages/proto-loader/bin/proto-loader-gen-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ function formatComment(formatter: TextFormatter, comment?: string | null) {

// GENERATOR FUNCTIONS

function getTypeNamePermissive(fieldType: string, resolvedType: Protobuf.Type | Protobuf.Enum | null): string {
function getTypeNamePermissive(fieldType: string, resolvedType: Protobuf.Type | Protobuf.Enum | null, repeated: boolean, map: boolean): string {
switch (fieldType) {
case 'double':
case 'float':
Expand Down Expand Up @@ -199,15 +199,19 @@ function getTypeNamePermissive(fieldType: string, resolvedType: Protobuf.Type |
}
const typeInterfaceName = getTypeInterfaceName(resolvedType);
if (resolvedType instanceof Protobuf.Type) {
return typeInterfaceName;
if (repeated || map) {
return typeInterfaceName;
} else {
return `${typeInterfaceName} | null`;
}
} else {
return `${typeInterfaceName} | keyof typeof ${typeInterfaceName}`;
}
}
}

function getFieldTypePermissive(field: Protobuf.FieldBase): string {
const valueType = getTypeNamePermissive(field.type, field.resolvedType);
const valueType = getTypeNamePermissive(field.type, field.resolvedType, field.repeated, field.map);
if (field instanceof Protobuf.MapField) {
const keyType = field.keyType === 'string' ? 'string' : 'number';
return `{[key: ${keyType}]: ${valueType}}`;
Expand Down Expand Up @@ -250,7 +254,7 @@ function generatePermissiveMessageInterface(formatter: TextFormatter, messageTyp
formatter.writeLine('}');
}

function getTypeNameRestricted(fieldType: string, resolvedType: Protobuf.Type | Protobuf.Enum | null, options: GeneratorOptions): string {
function getTypeNameRestricted(fieldType: string, resolvedType: Protobuf.Type | Protobuf.Enum | null, repeated: boolean, map: boolean, options: GeneratorOptions): string {
switch (fieldType) {
case 'double':
case 'float':
Expand Down Expand Up @@ -295,7 +299,13 @@ function getTypeNameRestricted(fieldType: string, resolvedType: Protobuf.Type |
}
const typeInterfaceName = getTypeInterfaceName(resolvedType);
if (resolvedType instanceof Protobuf.Type) {
return typeInterfaceName + '__Output';
/* null is only used to represent absent message values if the defaults
* option is set, and only for non-repeated, non-map fields. */
if (options.defaults && !repeated && !map) {
return `${typeInterfaceName}__Output | null`;
} else {
return `${typeInterfaceName}__Output`;
}
} else {
if (options.enums == String) {
return `keyof typeof ${typeInterfaceName}`;
Expand All @@ -307,7 +317,7 @@ function getTypeNameRestricted(fieldType: string, resolvedType: Protobuf.Type |
}
function getFieldTypeRestricted(field: Protobuf.FieldBase, options: GeneratorOptions): string {
const valueType = getTypeNameRestricted(field.type, field.resolvedType, options);
const valueType = getTypeNameRestricted(field.type, field.resolvedType, field.repeated, field.map, options);
if (field instanceof Protobuf.MapField) {
const keyType = field.keyType === 'string' ? 'string' : 'number';
return `{[key: ${keyType}]: ${valueType}}`;
Expand All @@ -326,7 +336,7 @@ function generateRestrictedMessageInterface(formatter: TextFormatter, messageTyp
let optionalString = options.defaults ? '' : '?';
formatter.writeLine('export type Any__Output = AnyExtension | {');
formatter.writeLine(` type_url${optionalString}: string;`);
formatter.writeLine(` value${optionalString}: ${getTypeNameRestricted('bytes', null, options)};`);
formatter.writeLine(` value${optionalString}: ${getTypeNameRestricted('bytes', null, false, false, options)};`);
formatter.writeLine('}');
return;
}
Expand All @@ -339,19 +349,10 @@ function generateRestrictedMessageInterface(formatter: TextFormatter, messageTyp
fieldGuaranteed = false;
} else if (field.repeated) {
fieldGuaranteed = (options.defaults || options.arrays) ?? false;
} else if (field.resolvedType) {
if (field.resolvedType instanceof Protobuf.Enum) {
fieldGuaranteed = options.defaults ?? false;
} else {
// Message fields can always be omitted
fieldGuaranteed = false;
}
} else if (field.map) {
fieldGuaranteed = (options.defaults || options.objects) ?? false;
} else {
if (field.map) {
fieldGuaranteed = (options.defaults || options.objects) ?? false;
} else {
fieldGuaranteed = options.defaults ?? false;
}
fieldGuaranteed = options.defaults ?? false;
}
const optionalString = fieldGuaranteed ? '' : '?';
const repeatedString = field.repeated ? '[]' : '';
Expand Down
4 changes: 2 additions & 2 deletions packages/proto-loader/golden-generated/google/api/HttpRule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -317,7 +317,7 @@ export interface HttpRule {
* HTTP method unspecified for this rule. The wild-card rule is useful
* for services that provide content to Web (HTML) clients.
*/
'custom'?: (_google_api_CustomHttpPattern);
'custom'?: (_google_api_CustomHttpPattern | null);
/**
* Additional HTTP bindings for the selector. Nested bindings must
* not contain an `additional_bindings` field themselves (that is,
Expand Down Expand Up @@ -655,7 +655,7 @@ export interface HttpRule__Output {
* HTTP method unspecified for this rule. The wild-card rule is useful
* for services that provide content to Web (HTML) clients.
*/
'custom'?: (_google_api_CustomHttpPattern__Output);
'custom'?: (_google_api_CustomHttpPattern__Output | null);
/**
* Additional HTTP bindings for the selector. Nested bindings must
* not contain an `additional_bindings` field themselves (that is,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ export interface Operation {
* Some services might not provide such metadata. Any method that returns a
* long-running operation should document the metadata type, if any.
*/
'metadata'?: (_google_protobuf_Any);
'metadata'?: (_google_protobuf_Any | null);
/**
* If the value is `false`, it means the operation is still in progress.
* If `true`, the operation is completed, and either `error` or `response` is
Expand All @@ -30,7 +30,7 @@ export interface Operation {
/**
* The error result of the operation in case of failure or cancellation.
*/
'error'?: (_google_rpc_Status);
'error'?: (_google_rpc_Status | null);
/**
* The normal response of the operation in case of success. If the original
* method returns no data on success, such as `Delete`, the response is
Expand All @@ -41,7 +41,7 @@ export interface Operation {
* is `TakeSnapshot()`, the inferred response type is
* `TakeSnapshotResponse`.
*/
'response'?: (_google_protobuf_Any);
'response'?: (_google_protobuf_Any | null);
/**
* The operation result, which can be either an `error` or a valid `response`.
* If `done` == `false`, neither `error` nor `response` is set.
Expand All @@ -67,7 +67,7 @@ export interface Operation__Output {
* Some services might not provide such metadata. Any method that returns a
* long-running operation should document the metadata type, if any.
*/
'metadata'?: (_google_protobuf_Any__Output);
'metadata': (_google_protobuf_Any__Output | null);
/**
* If the value is `false`, it means the operation is still in progress.
* If `true`, the operation is completed, and either `error` or `response` is
Expand All @@ -77,7 +77,7 @@ export interface Operation__Output {
/**
* The error result of the operation in case of failure or cancellation.
*/
'error'?: (_google_rpc_Status__Output);
'error'?: (_google_rpc_Status__Output | null);
/**
* The normal response of the operation in case of success. If the original
* method returns no data on success, such as `Delete`, the response is
Expand All @@ -88,7 +88,7 @@ export interface Operation__Output {
* is `TakeSnapshot()`, the inferred response type is
* `TakeSnapshotResponse`.
*/
'response'?: (_google_protobuf_Any__Output);
'response'?: (_google_protobuf_Any__Output | null);
/**
* The operation result, which can be either an `error` or a valid `response`.
* If `done` == `false`, neither `error` nor `response` is set.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ export interface WaitOperationRequest {
* will be at most the time permitted by the underlying HTTP/RPC protocol.
* If RPC context deadline is also specified, the shorter one will be used.
*/
'timeout'?: (_google_protobuf_Duration);
'timeout'?: (_google_protobuf_Duration | null);
}

/**
Expand All @@ -31,5 +31,5 @@ export interface WaitOperationRequest__Output {
* will be at most the time permitted by the underlying HTTP/RPC protocol.
* If RPC context deadline is also specified, the shorter one will be used.
*/
'timeout'?: (_google_protobuf_Duration__Output);
'timeout': (_google_protobuf_Duration__Output | null);
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ export interface DescriptorProto {
'enumType'?: (_google_protobuf_EnumDescriptorProto)[];
'extensionRange'?: (_google_protobuf_DescriptorProto_ExtensionRange)[];
'extension'?: (_google_protobuf_FieldDescriptorProto)[];
'options'?: (_google_protobuf_MessageOptions);
'options'?: (_google_protobuf_MessageOptions | null);
'oneofDecl'?: (_google_protobuf_OneofDescriptorProto)[];
'reservedRange'?: (_google_protobuf_DescriptorProto_ReservedRange)[];
'reservedName'?: (string)[];
Expand All @@ -46,7 +46,7 @@ export interface DescriptorProto__Output {
'enumType': (_google_protobuf_EnumDescriptorProto__Output)[];
'extensionRange': (_google_protobuf_DescriptorProto_ExtensionRange__Output)[];
'extension': (_google_protobuf_FieldDescriptorProto__Output)[];
'options'?: (_google_protobuf_MessageOptions__Output);
'options': (_google_protobuf_MessageOptions__Output | null);
'oneofDecl': (_google_protobuf_OneofDescriptorProto__Output)[];
'reservedRange': (_google_protobuf_DescriptorProto_ReservedRange__Output)[];
'reservedName': (string)[];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@ import type { EnumOptions as _google_protobuf_EnumOptions, EnumOptions__Output a
export interface EnumDescriptorProto {
'name'?: (string);
'value'?: (_google_protobuf_EnumValueDescriptorProto)[];
'options'?: (_google_protobuf_EnumOptions);
'options'?: (_google_protobuf_EnumOptions | null);
}

export interface EnumDescriptorProto__Output {
'name': (string);
'value': (_google_protobuf_EnumValueDescriptorProto__Output)[];
'options'?: (_google_protobuf_EnumOptions__Output);
'options': (_google_protobuf_EnumOptions__Output | null);
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@ import type { EnumValueOptions as _google_protobuf_EnumValueOptions, EnumValueOp
export interface EnumValueDescriptorProto {
'name'?: (string);
'number'?: (number);
'options'?: (_google_protobuf_EnumValueOptions);
'options'?: (_google_protobuf_EnumValueOptions | null);
}

export interface EnumValueDescriptorProto__Output {
'name': (string);
'number': (number);
'options'?: (_google_protobuf_EnumValueOptions__Output);
'options': (_google_protobuf_EnumValueOptions__Output | null);
}
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ export interface FieldDescriptorProto {
'type'?: (_google_protobuf_FieldDescriptorProto_Type | keyof typeof _google_protobuf_FieldDescriptorProto_Type);
'typeName'?: (string);
'defaultValue'?: (string);
'options'?: (_google_protobuf_FieldOptions);
'options'?: (_google_protobuf_FieldOptions | null);
'oneofIndex'?: (number);
'jsonName'?: (string);
}
Expand All @@ -54,7 +54,7 @@ export interface FieldDescriptorProto__Output {
'type': (keyof typeof _google_protobuf_FieldDescriptorProto_Type);
'typeName': (string);
'defaultValue': (string);
'options'?: (_google_protobuf_FieldOptions__Output);
'options': (_google_protobuf_FieldOptions__Output | null);
'oneofIndex': (number);
'jsonName': (string);
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ export interface FileDescriptorProto {
'enumType'?: (_google_protobuf_EnumDescriptorProto)[];
'service'?: (_google_protobuf_ServiceDescriptorProto)[];
'extension'?: (_google_protobuf_FieldDescriptorProto)[];
'options'?: (_google_protobuf_FileOptions);
'sourceCodeInfo'?: (_google_protobuf_SourceCodeInfo);
'options'?: (_google_protobuf_FileOptions | null);
'sourceCodeInfo'?: (_google_protobuf_SourceCodeInfo | null);
'publicDependency'?: (number)[];
'weakDependency'?: (number)[];
'syntax'?: (string);
Expand All @@ -30,8 +30,8 @@ export interface FileDescriptorProto__Output {
'enumType': (_google_protobuf_EnumDescriptorProto__Output)[];
'service': (_google_protobuf_ServiceDescriptorProto__Output)[];
'extension': (_google_protobuf_FieldDescriptorProto__Output)[];
'options'?: (_google_protobuf_FileOptions__Output);
'sourceCodeInfo'?: (_google_protobuf_SourceCodeInfo__Output);
'options': (_google_protobuf_FileOptions__Output | null);
'sourceCodeInfo': (_google_protobuf_SourceCodeInfo__Output | null);
'publicDependency': (number)[];
'weakDependency': (number)[];
'syntax': (string);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ export interface MethodDescriptorProto {
'name'?: (string);
'inputType'?: (string);
'outputType'?: (string);
'options'?: (_google_protobuf_MethodOptions);
'options'?: (_google_protobuf_MethodOptions | null);
'clientStreaming'?: (boolean);
'serverStreaming'?: (boolean);
}
Expand All @@ -15,7 +15,7 @@ export interface MethodDescriptorProto__Output {
'name': (string);
'inputType': (string);
'outputType': (string);
'options'?: (_google_protobuf_MethodOptions__Output);
'options': (_google_protobuf_MethodOptions__Output | null);
'clientStreaming': (boolean);
'serverStreaming': (boolean);
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,15 @@ import type { HttpRule as _google_api_HttpRule, HttpRule__Output as _google_api_
export interface MethodOptions {
'deprecated'?: (boolean);
'uninterpretedOption'?: (_google_protobuf_UninterpretedOption)[];
'.google.longrunning.operation_info'?: (_google_longrunning_OperationInfo);
'.google.longrunning.operation_info'?: (_google_longrunning_OperationInfo | null);
'.google.api.method_signature'?: (string)[];
'.google.api.http'?: (_google_api_HttpRule);
'.google.api.http'?: (_google_api_HttpRule | null);
}

export interface MethodOptions__Output {
'deprecated': (boolean);
'uninterpretedOption': (_google_protobuf_UninterpretedOption__Output)[];
'.google.longrunning.operation_info'?: (_google_longrunning_OperationInfo__Output);
'.google.longrunning.operation_info': (_google_longrunning_OperationInfo__Output | null);
'.google.api.method_signature': (string)[];
'.google.api.http'?: (_google_api_HttpRule__Output);
'.google.api.http': (_google_api_HttpRule__Output | null);
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@ import type { OneofOptions as _google_protobuf_OneofOptions, OneofOptions__Outpu

export interface OneofDescriptorProto {
'name'?: (string);
'options'?: (_google_protobuf_OneofOptions);
'options'?: (_google_protobuf_OneofOptions | null);
}

export interface OneofDescriptorProto__Output {
'name': (string);
'options'?: (_google_protobuf_OneofOptions__Output);
'options': (_google_protobuf_OneofOptions__Output | null);
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@ import type { ServiceOptions as _google_protobuf_ServiceOptions, ServiceOptions_
export interface ServiceDescriptorProto {
'name'?: (string);
'method'?: (_google_protobuf_MethodDescriptorProto)[];
'options'?: (_google_protobuf_ServiceOptions);
'options'?: (_google_protobuf_ServiceOptions | null);
}

export interface ServiceDescriptorProto__Output {
'name': (string);
'method': (_google_protobuf_MethodDescriptorProto__Output)[];
'options'?: (_google_protobuf_ServiceOptions__Output);
'options': (_google_protobuf_ServiceOptions__Output | null);
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,16 @@ export interface BlockRequest {
/**
* The amount of time to block before returning a response.
*/
'response_delay'?: (_google_protobuf_Duration);
'response_delay'?: (_google_protobuf_Duration | null);
/**
* The error that will be returned by the server. If this code is specified
* to be the OK rpc code, an empty response will be returned.
*/
'error'?: (_google_rpc_Status);
'error'?: (_google_rpc_Status | null);
/**
* The response to be returned that will signify successful method call.
*/
'success'?: (_google_showcase_v1beta1_BlockResponse);
'success'?: (_google_showcase_v1beta1_BlockResponse | null);
'response'?: "error"|"success";
}

Expand All @@ -31,15 +31,15 @@ export interface BlockRequest__Output {
/**
* The amount of time to block before returning a response.
*/
'response_delay'?: (_google_protobuf_Duration__Output);
'response_delay': (_google_protobuf_Duration__Output | null);
/**
* The error that will be returned by the server. If this code is specified
* to be the OK rpc code, an empty response will be returned.
*/
'error'?: (_google_rpc_Status__Output);
'error'?: (_google_rpc_Status__Output | null);
/**
* The response to be returned that will signify successful method call.
*/
'success'?: (_google_showcase_v1beta1_BlockResponse__Output);
'success'?: (_google_showcase_v1beta1_BlockResponse__Output | null);
'response': "error"|"success";
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ export interface EchoRequest {
/**
* The error to be thrown by the server.
*/
'error'?: (_google_rpc_Status);
'error'?: (_google_rpc_Status | null);
/**
* The severity to be echoed by the server.
*/
Expand All @@ -39,7 +39,7 @@ export interface EchoRequest__Output {
/**
* The error to be thrown by the server.
*/
'error'?: (_google_rpc_Status__Output);
'error'?: (_google_rpc_Status__Output | null);
/**
* The severity to be echoed by the server.
*/
Expand Down

0 comments on commit aefc9d1

Please sign in to comment.