Merge pull request #1744 from murgatroid99/proto-loader_null_message_type

proto-loader: generator: allow for null message values
This commit is contained in:
Michael Lumish 2021-04-14 13:58:09 -07:00 committed by GitHub
commit aefc9d12ab
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 72 additions and 71 deletions

View File

@ -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':
@ -199,7 +199,11 @@ 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}`;
}
@ -207,7 +211,7 @@ function getTypeNamePermissive(fieldType: string, resolvedType: Protobuf.Type |
}
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}}`;
@ -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':
@ -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}`;
@ -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}}`;
@ -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;
}
@ -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 ? '[]' : '';

View File

@ -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,
@ -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,

View File

@ -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
@ -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
@ -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.
@ -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
@ -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
@ -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.

View File

@ -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);
}
/**
@ -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);
}

View File

@ -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)[];
@ -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)[];

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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);
}
@ -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);
}

View File

@ -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);
@ -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);

View File

@ -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);
}
@ -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);
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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";
}
@ -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";
}

View File

@ -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.
*/
@ -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.
*/

View File

@ -13,7 +13,7 @@ export interface ExpandRequest {
/**
* The error that is thrown after all words are sent on the stream.
*/
'error'?: (_google_rpc_Status);
'error'?: (_google_rpc_Status | null);
}
/**
@ -27,5 +27,5 @@ export interface ExpandRequest__Output {
/**
* The error that is thrown after all words are sent on the stream.
*/
'error'?: (_google_rpc_Status__Output);
'error': (_google_rpc_Status__Output | null);
}

View File

@ -9,7 +9,7 @@ export interface WaitMetadata {
/**
* The time that this operation will complete.
*/
'end_time'?: (_google_protobuf_Timestamp);
'end_time'?: (_google_protobuf_Timestamp | null);
}
/**
@ -19,5 +19,5 @@ export interface WaitMetadata__Output {
/**
* The time that this operation will complete.
*/
'end_time'?: (_google_protobuf_Timestamp__Output);
'end_time': (_google_protobuf_Timestamp__Output | null);
}

View File

@ -12,20 +12,20 @@ export interface WaitRequest {
/**
* The time that this operation will complete.
*/
'end_time'?: (_google_protobuf_Timestamp);
'end_time'?: (_google_protobuf_Timestamp | 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 on operation completion.
*/
'success'?: (_google_showcase_v1beta1_WaitResponse);
'success'?: (_google_showcase_v1beta1_WaitResponse | null);
/**
* The duration of this operation.
*/
'ttl'?: (_google_protobuf_Duration);
'ttl'?: (_google_protobuf_Duration | null);
'end'?: "end_time"|"ttl";
'response'?: "error"|"success";
}
@ -37,20 +37,20 @@ export interface WaitRequest__Output {
/**
* The time that this operation will complete.
*/
'end_time'?: (_google_protobuf_Timestamp__Output);
'end_time'?: (_google_protobuf_Timestamp__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 on operation completion.
*/
'success'?: (_google_showcase_v1beta1_WaitResponse__Output);
'success'?: (_google_showcase_v1beta1_WaitResponse__Output | null);
/**
* The duration of this operation.
*/
'ttl'?: (_google_protobuf_Duration__Output);
'ttl'?: (_google_protobuf_Duration__Output | null);
'end': "end_time"|"ttl";
'response': "error"|"success";
}