Skip to content

Commit aefc9d1

Browse files
authored
Merge pull request #1744 from murgatroid99/proto-loader_null_message_type
proto-loader: generator: allow for null message values
2 parents 48afaf1 + 799bd16 commit aefc9d1

18 files changed

+72
-71
lines changed

packages/proto-loader/bin/proto-loader-gen-types.ts

+20-19
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,7 @@ function formatComment(formatter: TextFormatter, comment?: string | null) {
170170
171171
// GENERATOR FUNCTIONS
172172
173-
function getTypeNamePermissive(fieldType: string, resolvedType: Protobuf.Type | Protobuf.Enum | null): string {
173+
function getTypeNamePermissive(fieldType: string, resolvedType: Protobuf.Type | Protobuf.Enum | null, repeated: boolean, map: boolean): string {
174174
switch (fieldType) {
175175
case 'double':
176176
case 'float':
@@ -199,15 +199,19 @@ function getTypeNamePermissive(fieldType: string, resolvedType: Protobuf.Type |
199199
}
200200
const typeInterfaceName = getTypeInterfaceName(resolvedType);
201201
if (resolvedType instanceof Protobuf.Type) {
202-
return typeInterfaceName;
202+
if (repeated || map) {
203+
return typeInterfaceName;
204+
} else {
205+
return `${typeInterfaceName} | null`;
206+
}
203207
} else {
204208
return `${typeInterfaceName} | keyof typeof ${typeInterfaceName}`;
205209
}
206210
}
207211
}
208212
209213
function getFieldTypePermissive(field: Protobuf.FieldBase): string {
210-
const valueType = getTypeNamePermissive(field.type, field.resolvedType);
214+
const valueType = getTypeNamePermissive(field.type, field.resolvedType, field.repeated, field.map);
211215
if (field instanceof Protobuf.MapField) {
212216
const keyType = field.keyType === 'string' ? 'string' : 'number';
213217
return `{[key: ${keyType}]: ${valueType}}`;
@@ -250,7 +254,7 @@ function generatePermissiveMessageInterface(formatter: TextFormatter, messageTyp
250254
formatter.writeLine('}');
251255
}
252256
253-
function getTypeNameRestricted(fieldType: string, resolvedType: Protobuf.Type | Protobuf.Enum | null, options: GeneratorOptions): string {
257+
function getTypeNameRestricted(fieldType: string, resolvedType: Protobuf.Type | Protobuf.Enum | null, repeated: boolean, map: boolean, options: GeneratorOptions): string {
254258
switch (fieldType) {
255259
case 'double':
256260
case 'float':
@@ -295,7 +299,13 @@ function getTypeNameRestricted(fieldType: string, resolvedType: Protobuf.Type |
295299
}
296300
const typeInterfaceName = getTypeInterfaceName(resolvedType);
297301
if (resolvedType instanceof Protobuf.Type) {
298-
return typeInterfaceName + '__Output';
302+
/* null is only used to represent absent message values if the defaults
303+
* option is set, and only for non-repeated, non-map fields. */
304+
if (options.defaults && !repeated && !map) {
305+
return `${typeInterfaceName}__Output | null`;
306+
} else {
307+
return `${typeInterfaceName}__Output`;
308+
}
299309
} else {
300310
if (options.enums == String) {
301311
return `keyof typeof ${typeInterfaceName}`;
@@ -307,7 +317,7 @@ function getTypeNameRestricted(fieldType: string, resolvedType: Protobuf.Type |
307317
}
308318
309319
function getFieldTypeRestricted(field: Protobuf.FieldBase, options: GeneratorOptions): string {
310-
const valueType = getTypeNameRestricted(field.type, field.resolvedType, options);
320+
const valueType = getTypeNameRestricted(field.type, field.resolvedType, field.repeated, field.map, options);
311321
if (field instanceof Protobuf.MapField) {
312322
const keyType = field.keyType === 'string' ? 'string' : 'number';
313323
return `{[key: ${keyType}]: ${valueType}}`;
@@ -326,7 +336,7 @@ function generateRestrictedMessageInterface(formatter: TextFormatter, messageTyp
326336
let optionalString = options.defaults ? '' : '?';
327337
formatter.writeLine('export type Any__Output = AnyExtension | {');
328338
formatter.writeLine(` type_url${optionalString}: string;`);
329-
formatter.writeLine(` value${optionalString}: ${getTypeNameRestricted('bytes', null, options)};`);
339+
formatter.writeLine(` value${optionalString}: ${getTypeNameRestricted('bytes', null, false, false, options)};`);
330340
formatter.writeLine('}');
331341
return;
332342
}
@@ -339,19 +349,10 @@ function generateRestrictedMessageInterface(formatter: TextFormatter, messageTyp
339349
fieldGuaranteed = false;
340350
} else if (field.repeated) {
341351
fieldGuaranteed = (options.defaults || options.arrays) ?? false;
342-
} else if (field.resolvedType) {
343-
if (field.resolvedType instanceof Protobuf.Enum) {
344-
fieldGuaranteed = options.defaults ?? false;
345-
} else {
346-
// Message fields can always be omitted
347-
fieldGuaranteed = false;
348-
}
352+
} else if (field.map) {
353+
fieldGuaranteed = (options.defaults || options.objects) ?? false;
349354
} else {
350-
if (field.map) {
351-
fieldGuaranteed = (options.defaults || options.objects) ?? false;
352-
} else {
353-
fieldGuaranteed = options.defaults ?? false;
354-
}
355+
fieldGuaranteed = options.defaults ?? false;
355356
}
356357
const optionalString = fieldGuaranteed ? '' : '?';
357358
const repeatedString = field.repeated ? '[]' : '';

packages/proto-loader/golden-generated/google/api/HttpRule.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -317,7 +317,7 @@ export interface HttpRule {
317317
* HTTP method unspecified for this rule. The wild-card rule is useful
318318
* for services that provide content to Web (HTML) clients.
319319
*/
320-
'custom'?: (_google_api_CustomHttpPattern);
320+
'custom'?: (_google_api_CustomHttpPattern | null);
321321
/**
322322
* Additional HTTP bindings for the selector. Nested bindings must
323323
* not contain an `additional_bindings` field themselves (that is,
@@ -655,7 +655,7 @@ export interface HttpRule__Output {
655655
* HTTP method unspecified for this rule. The wild-card rule is useful
656656
* for services that provide content to Web (HTML) clients.
657657
*/
658-
'custom'?: (_google_api_CustomHttpPattern__Output);
658+
'custom'?: (_google_api_CustomHttpPattern__Output | null);
659659
/**
660660
* Additional HTTP bindings for the selector. Nested bindings must
661661
* not contain an `additional_bindings` field themselves (that is,

packages/proto-loader/golden-generated/google/longrunning/Operation.ts

+6-6
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ export interface Operation {
2020
* Some services might not provide such metadata. Any method that returns a
2121
* long-running operation should document the metadata type, if any.
2222
*/
23-
'metadata'?: (_google_protobuf_Any);
23+
'metadata'?: (_google_protobuf_Any | null);
2424
/**
2525
* If the value is `false`, it means the operation is still in progress.
2626
* If `true`, the operation is completed, and either `error` or `response` is
@@ -30,7 +30,7 @@ export interface Operation {
3030
/**
3131
* The error result of the operation in case of failure or cancellation.
3232
*/
33-
'error'?: (_google_rpc_Status);
33+
'error'?: (_google_rpc_Status | null);
3434
/**
3535
* The normal response of the operation in case of success. If the original
3636
* method returns no data on success, such as `Delete`, the response is
@@ -41,7 +41,7 @@ export interface Operation {
4141
* is `TakeSnapshot()`, the inferred response type is
4242
* `TakeSnapshotResponse`.
4343
*/
44-
'response'?: (_google_protobuf_Any);
44+
'response'?: (_google_protobuf_Any | null);
4545
/**
4646
* The operation result, which can be either an `error` or a valid `response`.
4747
* If `done` == `false`, neither `error` nor `response` is set.
@@ -67,7 +67,7 @@ export interface Operation__Output {
6767
* Some services might not provide such metadata. Any method that returns a
6868
* long-running operation should document the metadata type, if any.
6969
*/
70-
'metadata'?: (_google_protobuf_Any__Output);
70+
'metadata': (_google_protobuf_Any__Output | null);
7171
/**
7272
* If the value is `false`, it means the operation is still in progress.
7373
* If `true`, the operation is completed, and either `error` or `response` is
@@ -77,7 +77,7 @@ export interface Operation__Output {
7777
/**
7878
* The error result of the operation in case of failure or cancellation.
7979
*/
80-
'error'?: (_google_rpc_Status__Output);
80+
'error'?: (_google_rpc_Status__Output | null);
8181
/**
8282
* The normal response of the operation in case of success. If the original
8383
* method returns no data on success, such as `Delete`, the response is
@@ -88,7 +88,7 @@ export interface Operation__Output {
8888
* is `TakeSnapshot()`, the inferred response type is
8989
* `TakeSnapshotResponse`.
9090
*/
91-
'response'?: (_google_protobuf_Any__Output);
91+
'response'?: (_google_protobuf_Any__Output | null);
9292
/**
9393
* The operation result, which can be either an `error` or a valid `response`.
9494
* If `done` == `false`, neither `error` nor `response` is set.

packages/proto-loader/golden-generated/google/longrunning/WaitOperationRequest.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ export interface WaitOperationRequest {
1515
* will be at most the time permitted by the underlying HTTP/RPC protocol.
1616
* If RPC context deadline is also specified, the shorter one will be used.
1717
*/
18-
'timeout'?: (_google_protobuf_Duration);
18+
'timeout'?: (_google_protobuf_Duration | null);
1919
}
2020

2121
/**
@@ -31,5 +31,5 @@ export interface WaitOperationRequest__Output {
3131
* will be at most the time permitted by the underlying HTTP/RPC protocol.
3232
* If RPC context deadline is also specified, the shorter one will be used.
3333
*/
34-
'timeout'?: (_google_protobuf_Duration__Output);
34+
'timeout': (_google_protobuf_Duration__Output | null);
3535
}

packages/proto-loader/golden-generated/google/protobuf/DescriptorProto.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ export interface DescriptorProto {
3333
'enumType'?: (_google_protobuf_EnumDescriptorProto)[];
3434
'extensionRange'?: (_google_protobuf_DescriptorProto_ExtensionRange)[];
3535
'extension'?: (_google_protobuf_FieldDescriptorProto)[];
36-
'options'?: (_google_protobuf_MessageOptions);
36+
'options'?: (_google_protobuf_MessageOptions | null);
3737
'oneofDecl'?: (_google_protobuf_OneofDescriptorProto)[];
3838
'reservedRange'?: (_google_protobuf_DescriptorProto_ReservedRange)[];
3939
'reservedName'?: (string)[];
@@ -46,7 +46,7 @@ export interface DescriptorProto__Output {
4646
'enumType': (_google_protobuf_EnumDescriptorProto__Output)[];
4747
'extensionRange': (_google_protobuf_DescriptorProto_ExtensionRange__Output)[];
4848
'extension': (_google_protobuf_FieldDescriptorProto__Output)[];
49-
'options'?: (_google_protobuf_MessageOptions__Output);
49+
'options': (_google_protobuf_MessageOptions__Output | null);
5050
'oneofDecl': (_google_protobuf_OneofDescriptorProto__Output)[];
5151
'reservedRange': (_google_protobuf_DescriptorProto_ReservedRange__Output)[];
5252
'reservedName': (string)[];

packages/proto-loader/golden-generated/google/protobuf/EnumDescriptorProto.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,11 @@ import type { EnumOptions as _google_protobuf_EnumOptions, EnumOptions__Output a
66
export interface EnumDescriptorProto {
77
'name'?: (string);
88
'value'?: (_google_protobuf_EnumValueDescriptorProto)[];
9-
'options'?: (_google_protobuf_EnumOptions);
9+
'options'?: (_google_protobuf_EnumOptions | null);
1010
}
1111

1212
export interface EnumDescriptorProto__Output {
1313
'name': (string);
1414
'value': (_google_protobuf_EnumValueDescriptorProto__Output)[];
15-
'options'?: (_google_protobuf_EnumOptions__Output);
15+
'options': (_google_protobuf_EnumOptions__Output | null);
1616
}

packages/proto-loader/golden-generated/google/protobuf/EnumValueDescriptorProto.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,11 @@ import type { EnumValueOptions as _google_protobuf_EnumValueOptions, EnumValueOp
55
export interface EnumValueDescriptorProto {
66
'name'?: (string);
77
'number'?: (number);
8-
'options'?: (_google_protobuf_EnumValueOptions);
8+
'options'?: (_google_protobuf_EnumValueOptions | null);
99
}
1010

1111
export interface EnumValueDescriptorProto__Output {
1212
'name': (string);
1313
'number': (number);
14-
'options'?: (_google_protobuf_EnumValueOptions__Output);
14+
'options': (_google_protobuf_EnumValueOptions__Output | null);
1515
}

packages/proto-loader/golden-generated/google/protobuf/FieldDescriptorProto.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ export interface FieldDescriptorProto {
4141
'type'?: (_google_protobuf_FieldDescriptorProto_Type | keyof typeof _google_protobuf_FieldDescriptorProto_Type);
4242
'typeName'?: (string);
4343
'defaultValue'?: (string);
44-
'options'?: (_google_protobuf_FieldOptions);
44+
'options'?: (_google_protobuf_FieldOptions | null);
4545
'oneofIndex'?: (number);
4646
'jsonName'?: (string);
4747
}
@@ -54,7 +54,7 @@ export interface FieldDescriptorProto__Output {
5454
'type': (keyof typeof _google_protobuf_FieldDescriptorProto_Type);
5555
'typeName': (string);
5656
'defaultValue': (string);
57-
'options'?: (_google_protobuf_FieldOptions__Output);
57+
'options': (_google_protobuf_FieldOptions__Output | null);
5858
'oneofIndex': (number);
5959
'jsonName': (string);
6060
}

packages/proto-loader/golden-generated/google/protobuf/FileDescriptorProto.ts

+4-4
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@ export interface FileDescriptorProto {
1515
'enumType'?: (_google_protobuf_EnumDescriptorProto)[];
1616
'service'?: (_google_protobuf_ServiceDescriptorProto)[];
1717
'extension'?: (_google_protobuf_FieldDescriptorProto)[];
18-
'options'?: (_google_protobuf_FileOptions);
19-
'sourceCodeInfo'?: (_google_protobuf_SourceCodeInfo);
18+
'options'?: (_google_protobuf_FileOptions | null);
19+
'sourceCodeInfo'?: (_google_protobuf_SourceCodeInfo | null);
2020
'publicDependency'?: (number)[];
2121
'weakDependency'?: (number)[];
2222
'syntax'?: (string);
@@ -30,8 +30,8 @@ export interface FileDescriptorProto__Output {
3030
'enumType': (_google_protobuf_EnumDescriptorProto__Output)[];
3131
'service': (_google_protobuf_ServiceDescriptorProto__Output)[];
3232
'extension': (_google_protobuf_FieldDescriptorProto__Output)[];
33-
'options'?: (_google_protobuf_FileOptions__Output);
34-
'sourceCodeInfo'?: (_google_protobuf_SourceCodeInfo__Output);
33+
'options': (_google_protobuf_FileOptions__Output | null);
34+
'sourceCodeInfo': (_google_protobuf_SourceCodeInfo__Output | null);
3535
'publicDependency': (number)[];
3636
'weakDependency': (number)[];
3737
'syntax': (string);

packages/proto-loader/golden-generated/google/protobuf/MethodDescriptorProto.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ export interface MethodDescriptorProto {
66
'name'?: (string);
77
'inputType'?: (string);
88
'outputType'?: (string);
9-
'options'?: (_google_protobuf_MethodOptions);
9+
'options'?: (_google_protobuf_MethodOptions | null);
1010
'clientStreaming'?: (boolean);
1111
'serverStreaming'?: (boolean);
1212
}
@@ -15,7 +15,7 @@ export interface MethodDescriptorProto__Output {
1515
'name': (string);
1616
'inputType': (string);
1717
'outputType': (string);
18-
'options'?: (_google_protobuf_MethodOptions__Output);
18+
'options': (_google_protobuf_MethodOptions__Output | null);
1919
'clientStreaming': (boolean);
2020
'serverStreaming': (boolean);
2121
}

packages/proto-loader/golden-generated/google/protobuf/MethodOptions.ts

+4-4
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,15 @@ import type { HttpRule as _google_api_HttpRule, HttpRule__Output as _google_api_
77
export interface MethodOptions {
88
'deprecated'?: (boolean);
99
'uninterpretedOption'?: (_google_protobuf_UninterpretedOption)[];
10-
'.google.longrunning.operation_info'?: (_google_longrunning_OperationInfo);
10+
'.google.longrunning.operation_info'?: (_google_longrunning_OperationInfo | null);
1111
'.google.api.method_signature'?: (string)[];
12-
'.google.api.http'?: (_google_api_HttpRule);
12+
'.google.api.http'?: (_google_api_HttpRule | null);
1313
}
1414

1515
export interface MethodOptions__Output {
1616
'deprecated': (boolean);
1717
'uninterpretedOption': (_google_protobuf_UninterpretedOption__Output)[];
18-
'.google.longrunning.operation_info'?: (_google_longrunning_OperationInfo__Output);
18+
'.google.longrunning.operation_info': (_google_longrunning_OperationInfo__Output | null);
1919
'.google.api.method_signature': (string)[];
20-
'.google.api.http'?: (_google_api_HttpRule__Output);
20+
'.google.api.http': (_google_api_HttpRule__Output | null);
2121
}

packages/proto-loader/golden-generated/google/protobuf/OneofDescriptorProto.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,10 @@ import type { OneofOptions as _google_protobuf_OneofOptions, OneofOptions__Outpu
44

55
export interface OneofDescriptorProto {
66
'name'?: (string);
7-
'options'?: (_google_protobuf_OneofOptions);
7+
'options'?: (_google_protobuf_OneofOptions | null);
88
}
99

1010
export interface OneofDescriptorProto__Output {
1111
'name': (string);
12-
'options'?: (_google_protobuf_OneofOptions__Output);
12+
'options': (_google_protobuf_OneofOptions__Output | null);
1313
}

packages/proto-loader/golden-generated/google/protobuf/ServiceDescriptorProto.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,11 @@ import type { ServiceOptions as _google_protobuf_ServiceOptions, ServiceOptions_
66
export interface ServiceDescriptorProto {
77
'name'?: (string);
88
'method'?: (_google_protobuf_MethodDescriptorProto)[];
9-
'options'?: (_google_protobuf_ServiceOptions);
9+
'options'?: (_google_protobuf_ServiceOptions | null);
1010
}
1111

1212
export interface ServiceDescriptorProto__Output {
1313
'name': (string);
1414
'method': (_google_protobuf_MethodDescriptorProto__Output)[];
15-
'options'?: (_google_protobuf_ServiceOptions__Output);
15+
'options': (_google_protobuf_ServiceOptions__Output | null);
1616
}

packages/proto-loader/golden-generated/google/showcase/v1beta1/BlockRequest.ts

+6-6
Original file line numberDiff line numberDiff line change
@@ -11,16 +11,16 @@ export interface BlockRequest {
1111
/**
1212
* The amount of time to block before returning a response.
1313
*/
14-
'response_delay'?: (_google_protobuf_Duration);
14+
'response_delay'?: (_google_protobuf_Duration | null);
1515
/**
1616
* The error that will be returned by the server. If this code is specified
1717
* to be the OK rpc code, an empty response will be returned.
1818
*/
19-
'error'?: (_google_rpc_Status);
19+
'error'?: (_google_rpc_Status | null);
2020
/**
2121
* The response to be returned that will signify successful method call.
2222
*/
23-
'success'?: (_google_showcase_v1beta1_BlockResponse);
23+
'success'?: (_google_showcase_v1beta1_BlockResponse | null);
2424
'response'?: "error"|"success";
2525
}
2626

@@ -31,15 +31,15 @@ export interface BlockRequest__Output {
3131
/**
3232
* The amount of time to block before returning a response.
3333
*/
34-
'response_delay'?: (_google_protobuf_Duration__Output);
34+
'response_delay': (_google_protobuf_Duration__Output | null);
3535
/**
3636
* The error that will be returned by the server. If this code is specified
3737
* to be the OK rpc code, an empty response will be returned.
3838
*/
39-
'error'?: (_google_rpc_Status__Output);
39+
'error'?: (_google_rpc_Status__Output | null);
4040
/**
4141
* The response to be returned that will signify successful method call.
4242
*/
43-
'success'?: (_google_showcase_v1beta1_BlockResponse__Output);
43+
'success'?: (_google_showcase_v1beta1_BlockResponse__Output | null);
4444
'response': "error"|"success";
4545
}

packages/proto-loader/golden-generated/google/showcase/v1beta1/EchoRequest.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ export interface EchoRequest {
1717
/**
1818
* The error to be thrown by the server.
1919
*/
20-
'error'?: (_google_rpc_Status);
20+
'error'?: (_google_rpc_Status | null);
2121
/**
2222
* The severity to be echoed by the server.
2323
*/
@@ -39,7 +39,7 @@ export interface EchoRequest__Output {
3939
/**
4040
* The error to be thrown by the server.
4141
*/
42-
'error'?: (_google_rpc_Status__Output);
42+
'error'?: (_google_rpc_Status__Output | null);
4343
/**
4444
* The severity to be echoed by the server.
4545
*/

0 commit comments

Comments
 (0)