Skip to content

Commit b66e327

Browse files
tatethurstonTate
and
Tate
authored
update compiler output for empty messages (#101)
Co-authored-by: Tate <[email protected]>
1 parent d50734e commit b66e327

File tree

9 files changed

+717
-2618
lines changed

9 files changed

+717
-2618
lines changed

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -581,6 +581,8 @@ TwirpScript aims to be zero config, but can be configured by creating a `.twirp.
581581
```protobuf
582582
import "B.proto";
583583
```
584+
585+
TypeScript projects will generally want to set this value to match their `rootDir`, particularly when using [Protocol Buffers Well-Known Types](https://developers.google.com/protocol-buffers/docs/reference/google.protobuf) so that the generated well-known type files are under the `rootDir`.
584586
</td>
585587
<td>string (filepath)</td>
586588
</tr>

clientcompat/src/clientcompat.pb.ts

Lines changed: 2 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -134,14 +134,14 @@ export const Empty = {
134134
* Serializes a Empty to protobuf.
135135
*/
136136
encode: function (empty: Partial<Empty>): Uint8Array {
137-
return Empty._writeMessage(empty, new BinaryWriter()).getResultBuffer();
137+
return new Uint8Array();
138138
},
139139

140140
/**
141141
* Deserializes a Empty from protobuf.
142142
*/
143143
decode: function (bytes: ByteSource): Empty {
144-
return Empty._readMessage(Empty.initialize(), new BinaryReader(bytes));
144+
return {};
145145
},
146146

147147
/**
@@ -150,32 +150,6 @@ export const Empty = {
150150
initialize: function (): Empty {
151151
return {};
152152
},
153-
154-
/**
155-
* @private
156-
*/
157-
_writeMessage: function (
158-
msg: Partial<Empty>,
159-
writer: BinaryWriter
160-
): BinaryWriter {
161-
return writer;
162-
},
163-
164-
/**
165-
* @private
166-
*/
167-
_readMessage: function (msg: Empty, reader: BinaryReader): Empty {
168-
while (reader.nextField()) {
169-
const field = reader.getFieldNumber();
170-
switch (field) {
171-
default: {
172-
reader.skipField();
173-
break;
174-
}
175-
}
176-
}
177-
return msg;
178-
},
179153
};
180154

181155
export const Req = {

src/autogenerate/index.ts

Lines changed: 49 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -73,16 +73,23 @@ function writeSerializers(types: ProtoTypes[], isTopLevel = true): string {
7373

7474
switch (node.type) {
7575
case "message": {
76+
const isEmpty = node.content.fields.length === 0;
77+
7678
result += `\
7779
/**
7880
* Serializes a ${node.content.fullyQualifiedName} to protobuf.
7981
*/
8082
encode: function(${lowerCase(node.content.name)}${printIfTypescript(
8183
`: Partial<${node.content.fullyQualifiedName}>`
8284
)})${printIfTypescript(`: Uint8Array`)} {
85+
${
86+
isEmpty
87+
? "return new Uint8Array();"
88+
: `
8389
return ${node.content.fullyQualifiedName}._writeMessage(${lowerCase(
84-
node.content.name
85-
)}, new BinaryWriter()).getResultBuffer();
90+
node.content.name
91+
)}, new BinaryWriter()).getResultBuffer();`
92+
}
8693
},
8794
8895
/**
@@ -91,9 +98,13 @@ function writeSerializers(types: ProtoTypes[], isTopLevel = true): string {
9198
decode: function(bytes${printIfTypescript(
9299
`: ByteSource`
93100
)})${printIfTypescript(`: ${node.content.fullyQualifiedName}`)} {
94-
return ${node.content.fullyQualifiedName}._readMessage(${
95-
node.content.fullyQualifiedName
96-
}.initialize(), new BinaryReader(bytes));
101+
${
102+
isEmpty
103+
? "return {};"
104+
: `
105+
return ${node.content.fullyQualifiedName}._readMessage(${node.content.fullyQualifiedName}.initialize(), new BinaryReader(bytes));
106+
`
107+
}
97108
},
98109
99110
/**
@@ -119,14 +130,16 @@ function writeSerializers(types: ProtoTypes[], isTopLevel = true): string {
119130
};
120131
},
121132
122-
/**
133+
${printIf(
134+
!isEmpty,
135+
`/**
123136
* @private
124137
*/
125138
_writeMessage: function(msg ${printIfTypescript(
126139
`: Partial<${node.content.fullyQualifiedName}>`
127140
)}, writer${printIfTypescript(`: BinaryWriter`)})${printIfTypescript(
128-
`: BinaryWriter`
129-
)} {
141+
`: BinaryWriter`
142+
)} {
130143
${node.content.fields
131144
.map((field) => {
132145
let res = "";
@@ -177,8 +190,8 @@ function writeSerializers(types: ProtoTypes[], isTopLevel = true): string {
177190
_readMessage: function(msg${printIfTypescript(
178191
`: ${node.content.fullyQualifiedName}`
179192
)}, reader${printIfTypescript(`: BinaryReader`)})${printIfTypescript(
180-
`: ${node.content.fullyQualifiedName} `
181-
)}{
193+
`: ${node.content.fullyQualifiedName} `
194+
)}{
182195
while (reader.nextField()) {
183196
const field = reader.getFieldNumber();
184197
switch (field) {
@@ -248,7 +261,8 @@ function writeSerializers(types: ProtoTypes[], isTopLevel = true): string {
248261
}
249262
}
250263
return msg;
251-
},
264+
},`
265+
)}
252266
253267
`;
254268
const childrenWithouMaps = node.children.filter(
@@ -430,7 +444,11 @@ function writeServers(
430444

431445
let isTS = false;
432446
function printIfTypescript(str: string): string {
433-
return isTS ? str : "";
447+
return printIf(isTS, str);
448+
}
449+
450+
function printIf(cond: boolean, str: string): string {
451+
return cond ? str : "";
434452
}
435453

436454
export function generate(
@@ -451,29 +469,30 @@ export function generate(
451469
}
452470

453471
const hasServices = services.length > 0;
472+
const hasTypes = types.length > 0;
454473

455474
return `\
456475
// THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
457476
// Source: ${sourceFile}
458477
459-
${printIfTypescript(
460-
`import type { ByteSource ${
461-
hasServices ? ", ClientConfiguration" : ""
462-
}} from 'twirpscript';`
463-
)};
478+
479+
${printIf(
480+
isTS && (hasServices || hasTypes),
481+
`import type {
482+
${printIf(hasTypes, "ByteSource,\n")}
483+
${printIf(hasServices, "ClientConfiguration")}} from 'twirpscript';`
484+
)}
464485
import {
465-
BinaryReader,
466-
BinaryWriter
467-
${hasServices ? `,\nJSONrequest,\nPBrequest` : ""}} from 'twirpscript';
468-
${
469-
hasServices
470-
? `\
486+
${printIf(hasTypes, "BinaryReader,\nBinaryWriter,\n")}
487+
${printIf(hasServices, "JSONrequest,\nPBrequest")}} from 'twirpscript';
488+
${printIf(
489+
hasServices,
490+
`\
471491
// This is the minimum version supported by the current runtime.
472492
// If this line fails typechecking, breaking changes have been introduced and this
473493
// file needs to be regenerated by running \`yarn twirpscript\`.
474494
export { ${RUNTIME_MIN_CODE_GEN_SUPPORTED_VERSION} } from "twirpscript";`
475-
: ""
476-
}
495+
)}
477496
478497
${imports
479498
.map(
@@ -486,10 +505,12 @@ ${writeClients(services, packageName)}
486505
487506
${writeServers(services, packageName)}
488507
489-
${printIfTypescript(printHeading("Types"))}
508+
${printIf(
509+
hasTypes,
510+
`${printIfTypescript(printHeading("Types"))}
490511
${printIfTypescript(writeTypes(types))}
491-
492512
${printHeading("Protobuf Encode / Decode")}
493-
${writeSerializers(types)}
513+
${writeSerializers(types)}`
514+
)}
494515
`;
495516
}

src/cli/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,8 @@ type Config = {
6060
* ```proto
6161
* import "B.proto";
6262
* ```
63+
*
64+
* TypeScript projects will generally want to set this value to match their `rootDir`, particularly when using [Protocol Buffers Well-Known Types](https://developers.google.com/protocol-buffers/docs/reference/google.protobuf) so that the generated well-known type files are under the `rootDir`.
6365
*/
6466
root: string;
6567
/** The destination folder for generated files.

0 commit comments

Comments
 (0)