@bufbuild/protoc-gen-es 1.8.0 → 2.0.0-alpha.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/src/javascript.ts DELETED
@@ -1,652 +0,0 @@
1
- // Copyright 2021-2024 Buf Technologies, Inc.
2
- //
3
- // Licensed under the Apache License, Version 2.0 (the "License");
4
- // you may not use this file except in compliance with the License.
5
- // You may obtain a copy of the License at
6
- //
7
- // http://www.apache.org/licenses/LICENSE-2.0
8
- //
9
- // Unless required by applicable law or agreed to in writing, software
10
- // distributed under the License is distributed on an "AS IS" BASIS,
11
- // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
- // See the License for the specific language governing permissions and
13
- // limitations under the License.
14
-
15
- import {
16
- DescEnum,
17
- DescExtension,
18
- DescField,
19
- DescMessage,
20
- FieldDescriptorProto_Label,
21
- } from "@bufbuild/protobuf";
22
- import {
23
- FieldDescriptorProto_Type,
24
- LongType,
25
- proto2,
26
- proto3,
27
- ScalarType,
28
- } from "@bufbuild/protobuf";
29
- import type {
30
- GeneratedFile,
31
- Printable,
32
- Schema,
33
- } from "@bufbuild/protoplugin/ecmascript";
34
- import { localName, reifyWkt } from "@bufbuild/protoplugin/ecmascript";
35
- import { getNonEditionRuntime } from "./editions.js";
36
- import { getFieldDefaultValueExpression } from "./util.js";
37
-
38
- export function generateJs(schema: Schema) {
39
- for (const file of schema.files) {
40
- const f = schema.generateFile(file.name + "_pb.js");
41
- f.preamble(file);
42
- for (const enumeration of file.enums) {
43
- generateEnum(schema, f, enumeration);
44
- }
45
- for (const message of file.messages) {
46
- generateMessage(schema, f, message);
47
- }
48
- for (const extension of file.extensions) {
49
- generateExtension(schema, f, extension);
50
- }
51
- // We do not generate anything for services
52
- }
53
- }
54
-
55
- // prettier-ignore
56
- function generateEnum(schema: Schema, f: GeneratedFile, enumeration: DescEnum) {
57
- const protoN = getNonEditionRuntime(schema, enumeration.file);
58
- f.print(f.jsDoc(enumeration));
59
- f.print(f.exportDecl("const", enumeration), " = /*@__PURE__*/ ", protoN, ".makeEnum(")
60
- f.print(` "`, enumeration.typeName, `",`)
61
- f.print(` [`)
62
- if (enumeration.sharedPrefix === undefined) {
63
- for (const value of enumeration.values) {
64
- f.print(" {no: ", value.number, ", name: ", f.string(value.name), "},")
65
- }
66
- } else {
67
- for (const value of enumeration.values) {
68
- const localName = value.name.substring(enumeration.sharedPrefix.length);
69
- f.print(" {no: ", value.number, ", name: ", f.string(value.name), ", localName: ", f.string(localName), "},")
70
- }
71
- }
72
- f.print(` ],`)
73
- f.print(");")
74
- f.print()
75
- }
76
-
77
- // prettier-ignore
78
- function generateMessage(schema: Schema, f: GeneratedFile, message: DescMessage) {
79
- const protoN = getNonEditionRuntime(schema, message.file);
80
- f.print(f.jsDoc(message));
81
- f.print(f.exportDecl("const", message), " = /*@__PURE__*/ ", protoN, ".makeMessageType(")
82
- f.print(` `, f.string(message.typeName), `,`)
83
- if (message.fields.length == 0) {
84
- f.print(" [],")
85
- } else {
86
- f.print(" () => [")
87
- for (const field of message.fields) {
88
- generateFieldInfo(schema, f, field);
89
- }
90
- f.print(" ],")
91
- }
92
- const needsLocalName = localName(message) !==
93
- (message.file.syntax == "proto3" ? proto2 : proto3)
94
- .makeMessageType(message.typeName, []).name;
95
- if (needsLocalName) {
96
- // local name is not inferrable from the type name, we need to provide it
97
- f.print(` {localName: `, f.string(localName(message)), `},`)
98
- }
99
- f.print(");")
100
- f.print()
101
- generateWktMethods(schema, f, message)
102
- generateWktStaticMethods(schema, f, message)
103
- for (const nestedEnum of message.nestedEnums) {
104
- generateEnum(schema, f, nestedEnum);
105
- }
106
- for (const nestedMessage of message.nestedMessages) {
107
- generateMessage(schema, f, nestedMessage);
108
- }
109
- for (const nestedExtension of message.nestedExtensions) {
110
- generateExtension(schema, f, nestedExtension);
111
- }
112
- }
113
-
114
- // prettier-ignore
115
- export function generateFieldInfo(schema: Schema, f: GeneratedFile, field: DescField | DescExtension) {
116
- f.print(" ", getFieldInfoLiteral(schema, field), ",");
117
- }
118
-
119
- // prettier-ignore
120
- export function getFieldInfoLiteral(schema: Schema, field: DescField | DescExtension): Printable {
121
- const protoN = getNonEditionRuntime(schema, field.kind == "extension" ? field.file : field.parent.file);
122
- const e: Printable = [];
123
- e.push("{ no: ", field.number, `, `);
124
- if (field.kind == "field") {
125
- e.push(`name: "`, field.name, `", `);
126
- if (field.jsonName !== undefined) {
127
- e.push(`jsonName: "`, field.jsonName, `", `);
128
- }
129
- }
130
- switch (field.fieldKind) {
131
- case "scalar":
132
- e.push(`kind: "scalar", T: `, field.scalar, ` /* ScalarType.`, ScalarType[field.scalar], ` */, `);
133
- if (field.longType != LongType.BIGINT) {
134
- e.push(`L: `, field.longType, ` /* LongType.`, LongType[field.longType], ` */, `);
135
- }
136
- break;
137
- case "map":
138
- e.push(`kind: "map", K: `, field.mapKey, ` /* ScalarType.`, ScalarType[field.mapKey], ` */, `);
139
- switch (field.mapValue.kind) {
140
- case "scalar":
141
- e.push(`V: {kind: "scalar", T: `, field.mapValue.scalar, ` /* ScalarType.`, ScalarType[field.mapValue.scalar], ` */}, `);
142
- break;
143
- case "message":
144
- e.push(`V: {kind: "message", T: `, field.mapValue.message, `}, `);
145
- break;
146
- case "enum":
147
- e.push(`V: {kind: "enum", T: `, protoN, `.getEnumType(`, field.mapValue.enum, `)}, `);
148
- break;
149
- }
150
- break;
151
- case "message":
152
- e.push(`kind: "message", T: `, field.message, `, `);
153
- if (field.proto.type === FieldDescriptorProto_Type.GROUP) {
154
- e.push(`delimited: true, `);
155
- }
156
- break;
157
- case "enum":
158
- e.push(`kind: "enum", T: `, protoN, `.getEnumType(`, field.enum, `), `);
159
- break;
160
- }
161
- if (field.repeated) {
162
- e.push(`repeated: true, `);
163
- if (field.packed !== field.packedByDefault) {
164
- e.push(`packed: `, field.packed, `, `);
165
- }
166
- }
167
- if (field.optional) {
168
- e.push(`opt: true, `);
169
- } else if (field.proto.label === FieldDescriptorProto_Label.REQUIRED) {
170
- e.push(`req: true, `);
171
- }
172
- const defaultValue = getFieldDefaultValueExpression(field);
173
- if (defaultValue !== undefined) {
174
- e.push(`default: `, defaultValue, `, `);
175
- }
176
- if (field.oneof) {
177
- e.push(`oneof: "`, field.oneof.name, `", `);
178
- }
179
- const lastE = e[e.length - 1];
180
- if (typeof lastE == "string" && lastE.endsWith(", ")) {
181
- e[e.length - 1] = lastE.substring(0, lastE.length - 2);
182
- }
183
- e.push(" }");
184
- return e;
185
- }
186
-
187
- // prettier-ignore
188
- function generateExtension(
189
- schema: Schema,
190
- f: GeneratedFile,
191
- ext: DescExtension,
192
- ) {
193
- const protoN = getNonEditionRuntime(schema, ext.file);
194
- f.print(f.jsDoc(ext));
195
- f.print(f.exportDecl("const", ext), " = ", protoN, ".makeExtension(");
196
- f.print(" ", f.string(ext.typeName), ", ");
197
- f.print(" ", ext.extendee, ", ");
198
- if (ext.fieldKind == "scalar") {
199
- f.print(" ", getFieldInfoLiteral(schema, ext), ",");
200
- } else {
201
- f.print(" () => (", getFieldInfoLiteral(schema, ext), "),");
202
- }
203
- f.print(");");
204
- f.print();
205
- }
206
-
207
- // prettier-ignore
208
- function generateWktMethods(schema: Schema, f: GeneratedFile, message: DescMessage) {
209
- const ref = reifyWkt(message);
210
- if (ref === undefined) {
211
- return;
212
- }
213
- const {
214
- ScalarType: rtScalarType,
215
- protoInt64,
216
- } = schema.runtime;
217
- const protoN = getNonEditionRuntime(schema, message.file);
218
- switch (ref.typeName) {
219
- case "google.protobuf.Any":
220
- f.print(message, ".prototype.toJson = function toJson(options) {")
221
- f.print(` if (this.`, localName(ref.typeUrl), ` === "") {`);
222
- f.print(" return {};");
223
- f.print(" }");
224
- f.print(" const typeName = this.typeUrlToName(this.", localName(ref.typeUrl), ");");
225
- f.print(" const messageType = options?.typeRegistry?.findMessage(typeName);");
226
- f.print(" if (!messageType) {");
227
- f.print(" throw new Error(`cannot encode message ", message.typeName, ' to JSON: "${this.', localName(ref.typeUrl), '}" is not in the type registry`);');
228
- f.print(" }");
229
- f.print(" const message = messageType.fromBinary(this.", localName(ref.value), ");");
230
- f.print(" let json = message.toJson(options);");
231
- f.print(` if (typeName.startsWith("google.protobuf.") || (json === null || Array.isArray(json) || typeof json !== "object")) {`);
232
- f.print(" json = {value: json};");
233
- f.print(" }");
234
- f.print(` json["@type"] = this.`, localName(ref.typeUrl), `;`);
235
- f.print(" return json;");
236
- f.print("};");
237
- f.print();
238
- f.print(message, ".prototype.fromJson = function fromJson(json, options) {")
239
- f.print(` if (json === null || Array.isArray(json) || typeof json != "object") {`);
240
- f.print(" throw new Error(`cannot decode message ", message.typeName, ' from JSON: expected object but got ${json === null ? "null" : Array.isArray(json) ? "array" : typeof json}`);');
241
- f.print(" }");
242
- f.print(` if (Object.keys(json).length == 0) {`);
243
- f.print(` return this;`);
244
- f.print(` }`);
245
- f.print(` const typeUrl = json["@type"];`);
246
- f.print(` if (typeof typeUrl != "string" || typeUrl == "") {`);
247
- f.print(" throw new Error(`cannot decode message ", message.typeName, ' from JSON: "@type" is empty`);');
248
- f.print(" }");
249
- f.print(" const typeName = this.typeUrlToName(typeUrl), messageType = options?.typeRegistry?.findMessage(typeName);");
250
- f.print(" if (!messageType) {");
251
- f.print(" throw new Error(`cannot decode message ", message.typeName, " from JSON: ${typeUrl} is not in the type registry`);");
252
- f.print(" }");
253
- f.print(" let message;");
254
- f.print(` if (typeName.startsWith("google.protobuf.") && Object.prototype.hasOwnProperty.call(json, "value")) {`);
255
- f.print(` message = messageType.fromJson(json["value"], options);`);
256
- f.print(" } else {");
257
- f.print(" const copy = Object.assign({}, json);");
258
- f.print(` delete copy["@type"];`);
259
- f.print(" message = messageType.fromJson(copy, options);");
260
- f.print(" }");
261
- f.print(" this.packFrom(message);");
262
- f.print(" return this;");
263
- f.print("};");
264
- f.print();
265
- f.print(message, ".prototype.packFrom = function packFrom(message) {")
266
- f.print(" this.", localName(ref.value), " = message.toBinary();");
267
- f.print(" this.", localName(ref.typeUrl), " = this.typeNameToUrl(message.getType().typeName);");
268
- f.print("};");
269
- f.print();
270
- f.print(message, ".prototype.unpackTo = function unpackTo(target) {")
271
- f.print(" if (!this.is(target.getType())) {");
272
- f.print(" return false;");
273
- f.print(" }");
274
- f.print(" target.fromBinary(this.", localName(ref.value), ");");
275
- f.print(" return true;");
276
- f.print("};");
277
- f.print();
278
- f.print(message, ".prototype.unpack = function unpack(registry) {")
279
- f.print(" if (this.", localName(ref.typeUrl), ` === "") {`);
280
- f.print(" return undefined;");
281
- f.print(" }");
282
- f.print(" const messageType = registry.findMessage(this.typeUrlToName(this.", localName(ref.typeUrl), "));");
283
- f.print(" if (!messageType) {");
284
- f.print(" return undefined;");
285
- f.print(" }");
286
- f.print(" return messageType.fromBinary(this.", localName(ref.value), ");");
287
- f.print(" }");
288
- f.print();
289
- f.print(message, ".prototype.is = function is(type) {")
290
- f.print(" if (this.typeUrl === '') {");
291
- f.print(" return false;");
292
- f.print(" }");
293
- f.print(" const name = this.typeUrlToName(this.", localName(ref.typeUrl), ");");
294
- f.print(" let typeName = '';");
295
- f.print(" if (typeof type === 'string') {");
296
- f.print(" typeName = type;");
297
- f.print(" } else {");
298
- f.print(" typeName = type.typeName;");
299
- f.print(" }");
300
- f.print(" return name === typeName;");
301
- f.print("};");
302
- f.print();
303
- f.print(message, ".prototype.typeNameToUrl = function typeNameToUrl(name) {")
304
- f.print(" return `type.googleapis.com/${name}`;");
305
- f.print("};");
306
- f.print();
307
- f.print(message, ".prototype.typeUrlToName = function typeUrlToName(url) {")
308
- f.print(" if (!url.length) {");
309
- f.print(" throw new Error(`invalid type url: ${url}`);");
310
- f.print(" }");
311
- f.print(` const slash = url.lastIndexOf("/");`);
312
- f.print(" const name = slash >= 0 ? url.substring(slash + 1) : url;");
313
- f.print(" if (!name.length) {");
314
- f.print(" throw new Error(`invalid type url: ${url}`);");
315
- f.print(" }");
316
- f.print(" return name;");
317
- f.print("};");
318
- f.print();
319
- break;
320
- case "google.protobuf.Timestamp":
321
- f.print(message, ".prototype.fromJson = function fromJson(json, options) {")
322
- f.print(` if (typeof json !== "string") {`);
323
- f.print(" throw new Error(`cannot decode ", message.typeName, " from JSON: ${", protoN, ".json.debug(json)}`);");
324
- f.print(" }");
325
- f.print(` const matches = json.match(/^([0-9]{4})-([0-9]{2})-([0-9]{2})T([0-9]{2}):([0-9]{2}):([0-9]{2})(?:Z|\\.([0-9]{3,9})Z|([+-][0-9][0-9]:[0-9][0-9]))$/);`);
326
- f.print(" if (!matches) {");
327
- f.print(" throw new Error(`cannot decode ", message.typeName, " from JSON: invalid RFC 3339 string`);");
328
- f.print(" }");
329
- f.print(` const ms = Date.parse(matches[1] + "-" + matches[2] + "-" + matches[3] + "T" + matches[4] + ":" + matches[5] + ":" + matches[6] + (matches[8] ? matches[8] : "Z"));`);
330
- f.print(" if (Number.isNaN(ms)) {");
331
- f.print(" throw new Error(`cannot decode ", message.typeName, " from JSON: invalid RFC 3339 string`);");
332
- f.print(" }");
333
- f.print(` if (ms < Date.parse("0001-01-01T00:00:00Z") || ms > Date.parse("9999-12-31T23:59:59Z")) {`);
334
- f.print(" throw new Error(`cannot decode message ", message.typeName, " from JSON: must be from 0001-01-01T00:00:00Z to 9999-12-31T23:59:59Z inclusive`);");
335
- f.print(" }");
336
- f.print(" this.", localName(ref.seconds), " = ", protoInt64, ".parse(ms / 1000);");
337
- f.print(" this.", localName(ref.nanos), " = 0;");
338
- f.print(" if (matches[7]) {");
339
- f.print(` this.`, localName(ref.nanos), ` = (parseInt("1" + matches[7] + "0".repeat(9 - matches[7].length)) - 1000000000);` );
340
- f.print(" }");
341
- f.print(" return this;");
342
- f.print("};");
343
- f.print();
344
- f.print(message, ".prototype.toJson = function toJson(options) {")
345
- f.print(" const ms = Number(this.", localName(ref.seconds), ") * 1000;");
346
- f.print(` if (ms < Date.parse("0001-01-01T00:00:00Z") || ms > Date.parse("9999-12-31T23:59:59Z")) {`);
347
- f.print(" throw new Error(`cannot encode ", message.typeName, " to JSON: must be from 0001-01-01T00:00:00Z to 9999-12-31T23:59:59Z inclusive`);");
348
- f.print(" }");
349
- f.print(" if (this.", localName(ref.nanos), " < 0) {");
350
- f.print(" throw new Error(`cannot encode ", message.typeName, " to JSON: nanos must not be negative`);");
351
- f.print(" }");
352
- f.print(` let z = "Z";`);
353
- f.print(" if (this.", localName(ref.nanos), " > 0) {");
354
- f.print(" const nanosStr = (this.", localName(ref.nanos), " + 1000000000).toString().substring(1);");
355
- f.print(` if (nanosStr.substring(3) === "000000") {`);
356
- f.print(` z = "." + nanosStr.substring(0, 3) + "Z";`);
357
- f.print(` } else if (nanosStr.substring(6) === "000") {`);
358
- f.print(` z = "." + nanosStr.substring(0, 6) + "Z";`);
359
- f.print(" } else {");
360
- f.print(` z = "." + nanosStr + "Z";`);
361
- f.print(" }");
362
- f.print(" }");
363
- f.print(` return new Date(ms).toISOString().replace(".000Z", z);`);
364
- f.print("};");
365
- f.print();
366
- f.print(message, ".prototype.toDate = function toDate() {")
367
- f.print(" return new Date(Number(this.", localName(ref.seconds), ") * 1000 + Math.ceil(this.", localName(ref.nanos), " / 1000000));");
368
- f.print("};");
369
- f.print();
370
- break;
371
- case "google.protobuf.Duration":
372
- f.print(message, ".prototype.fromJson = function fromJson(json, options) {")
373
- f.print(` if (typeof json !== "string") {`)
374
- f.print(" throw new Error(`cannot decode ", message.typeName, " from JSON: ${proto3.json.debug(json)}`);")
375
- f.print(" }")
376
- f.print(` const match = json.match(/^(-?[0-9]+)(?:\\.([0-9]+))?s/);`)
377
- f.print(" if (match === null) {")
378
- f.print(" throw new Error(`cannot decode ", message.typeName, " from JSON: ${", protoN, ".json.debug(json)}`);")
379
- f.print(" }")
380
- f.print(" const longSeconds = Number(match[1]);")
381
- f.print(" if (longSeconds > 315576000000 || longSeconds < -315576000000) {")
382
- f.print(" throw new Error(`cannot decode ", message.typeName, " from JSON: ${", protoN, ".json.debug(json)}`);")
383
- f.print(" }")
384
- f.print(" this.", localName(ref.seconds), " = ", protoInt64, ".parse(longSeconds);")
385
- f.print(` if (typeof match[2] == "string") {`)
386
- f.print(` const nanosStr = match[2] + "0".repeat(9 - match[2].length);`)
387
- f.print(" this.", localName(ref.nanos), " = parseInt(nanosStr);")
388
- f.print(" if (longSeconds < 0 || Object.is(longSeconds, -0)) {");
389
- f.print(" this.", localName(ref.nanos), " = -this.", localName(ref.nanos), ";")
390
- f.print(" }")
391
- f.print(" }")
392
- f.print(" return this;")
393
- f.print("};");
394
- f.print()
395
- f.print(message, ".prototype.toJson = function toJson(options) {")
396
- f.print(" if (Number(this.", localName(ref.seconds), ") > 315576000000 || Number(this.", localName(ref.seconds), ") < -315576000000) {")
397
- f.print(" throw new Error(`cannot encode ", message.typeName, " to JSON: value out of range`);")
398
- f.print(" }")
399
- f.print(" let text = this.", localName(ref.seconds), ".toString();")
400
- f.print(" if (this.", localName(ref.nanos), " !== 0) {")
401
- f.print(" let nanosStr = Math.abs(this.", localName(ref.nanos), ").toString();")
402
- f.print(` nanosStr = "0".repeat(9 - nanosStr.length) + nanosStr;`)
403
- f.print(` if (nanosStr.substring(3) === "000000") {`)
404
- f.print(" nanosStr = nanosStr.substring(0, 3);")
405
- f.print(` } else if (nanosStr.substring(6) === "000") {`)
406
- f.print(" nanosStr = nanosStr.substring(0, 6);")
407
- f.print(` }`)
408
- f.print(` text += "." + nanosStr;`)
409
- f.print(" if (this.", localName(ref.nanos), " < 0 && this.", localName(ref.seconds), " === ", protoInt64, ".zero) {");
410
- f.print(` text = "-" + text;`);
411
- f.print(` }`);
412
- f.print(" }")
413
- f.print(` return text + "s";`)
414
- f.print("};");
415
- f.print()
416
- break;
417
- case "google.protobuf.Struct":
418
- f.print(message, ".prototype.toJson = function toJson(options) {")
419
- f.print(" const json = {}")
420
- f.print(" for (const [k, v] of Object.entries(this.", localName(ref.fields), ")) {")
421
- f.print(" json[k] = v.toJson(options);")
422
- f.print(" }")
423
- f.print(" return json;")
424
- f.print("};")
425
- f.print()
426
- f.print(message, ".prototype.fromJson = function fromJson(json, options) {")
427
- f.print(` if (typeof json != "object" || json == null || Array.isArray(json)) {`)
428
- f.print(` throw new Error("cannot decode `, message.typeName, ` from JSON " + `, protoN, `.json.debug(json));`)
429
- f.print(" }")
430
- f.print(" for (const [k, v] of Object.entries(json)) {")
431
- f.print(" this.", localName(ref.fields), "[k] = ", ref.fields.mapValue.message ?? "", ".fromJson(v);")
432
- f.print(" }")
433
- f.print(" return this;")
434
- f.print("};");
435
- f.print()
436
- break;
437
- case "google.protobuf.Value":
438
- f.print(message, ".prototype.toJson = function toJson(options) {")
439
- f.print(" switch (this.", localName(ref.kind), ".case) {")
440
- f.print(` case "`, localName(ref.nullValue), `":`)
441
- f.print(" return null;")
442
- f.print(` case "`, localName(ref.numberValue), `":`)
443
- f.print(` if (!Number.isFinite(this.`, localName(ref.kind), `.value)) {`);
444
- f.print(` throw new Error("google.protobuf.Value cannot be NaN or Infinity");`);
445
- f.print(` }`);
446
- f.print(` case "`, localName(ref.boolValue), `":`)
447
- f.print(` case "`, localName(ref.stringValue), `":`)
448
- f.print(" return this.", localName(ref.kind), ".value;")
449
- f.print(` case "`, localName(ref.structValue), `":`)
450
- f.print(` case "`, localName(ref.listValue), `":`)
451
- f.print(` return this.`, localName(ref.kind), `.value.toJson({...options, emitDefaultValues: true});`)
452
- f.print(" }")
453
- f.print(` throw new Error("`, message.typeName, ` must have a value");`)
454
- f.print("};");
455
- f.print()
456
- f.print(message, ".prototype.fromJson = function fromJson(json, options) {")
457
- f.print(" switch (typeof json) {")
458
- f.print(` case "number":`)
459
- f.print(` this.kind = { case: "`, localName(ref.numberValue), `", value: json };`)
460
- f.print(" break;")
461
- f.print(` case "string":`)
462
- f.print(` this.kind = { case: "`, localName(ref.stringValue), `", value: json };`)
463
- f.print(" break;")
464
- f.print(` case "boolean":`)
465
- f.print(` this.kind = { case: "`, localName(ref.boolValue), `", value: json };`)
466
- f.print(" break;")
467
- f.print(` case "object":`)
468
- f.print(" if (json === null) {")
469
- f.print(` this.kind = { case: "`, localName(ref.nullValue), `", value: `, ref.nullValue.enum, `.`, localName(ref.nullValue.enum.values[0]), ` };`)
470
- f.print(" } else if (Array.isArray(json)) {")
471
- f.print(` this.kind = { case: "`, localName(ref.listValue), `", value: `, ref.listValue.message, `.fromJson(json) };`)
472
- f.print(" } else {")
473
- f.print(` this.kind = { case: "`, localName(ref.structValue), `", value: `, ref.structValue.message, `.fromJson(json) };`)
474
- f.print(" }")
475
- f.print(" break;")
476
- f.print(" default:")
477
- f.print(` throw new Error("cannot decode `, message.typeName, ` from JSON " + `, protoN, `.json.debug(json));`)
478
- f.print(" }")
479
- f.print(" return this;")
480
- f.print("};");
481
- f.print()
482
- break;
483
- case "google.protobuf.ListValue":
484
- f.print(message, ".prototype.toJson = function toJson(options) {")
485
- f.print(` return this.`, localName(ref.values), `.map(v => v.toJson());`)
486
- f.print(`}`)
487
- f.print()
488
- f.print(message, ".prototype.fromJson = function fromJson(json, options) {")
489
- f.print(` if (!Array.isArray(json)) {`)
490
- f.print(` throw new Error("cannot decode `, message.typeName, ` from JSON " + `, protoN, `.json.debug(json));`)
491
- f.print(` }`)
492
- f.print(` for (let e of json) {`)
493
- f.print(` this.`, localName(ref.values), `.push(`, ref.values.message, `.fromJson(e));`)
494
- f.print(` }`)
495
- f.print(` return this;`)
496
- f.print("};");
497
- f.print()
498
- break;
499
- case "google.protobuf.FieldMask":
500
- f.print(message, ".prototype.toJson = function toJson(options) {")
501
- f.print(` // Converts snake_case to protoCamelCase according to the convention`)
502
- f.print(` // used by protoc to convert a field name to a JSON name.`)
503
- f.print(` function protoCamelCase(snakeCase) {`)
504
- f.print(` let capNext = false;`)
505
- f.print(` const b = [];`)
506
- f.print(` for (let i = 0; i < snakeCase.length; i++) {`)
507
- f.print(` let c = snakeCase.charAt(i);`)
508
- f.print(` switch (c) {`)
509
- f.print(` case '_':`)
510
- f.print(` capNext = true;`)
511
- f.print(` break;`)
512
- f.print(` case '0':`)
513
- f.print(` case '1':`)
514
- f.print(` case '2':`)
515
- f.print(` case '3':`)
516
- f.print(` case '4':`)
517
- f.print(` case '5':`)
518
- f.print(` case '6':`)
519
- f.print(` case '7':`)
520
- f.print(` case '8':`)
521
- f.print(` case '9':`)
522
- f.print(` b.push(c);`)
523
- f.print(` capNext = false;`)
524
- f.print(` break;`)
525
- f.print(` default:`)
526
- f.print(` if (capNext) {`)
527
- f.print(` capNext = false;`)
528
- f.print(` c = c.toUpperCase();`)
529
- f.print(` }`)
530
- f.print(` b.push(c);`)
531
- f.print(` break;`)
532
- f.print(` }`)
533
- f.print(` }`)
534
- f.print(` return b.join('');`)
535
- f.print(` }`)
536
- f.print(` return this.`, localName(ref.paths), `.map(p => {`)
537
- f.print(` if (p.match(/_[0-9]?_/g) || p.match(/[A-Z]/g)) {`)
538
- f.print(` throw new Error("cannot encode `, message.typeName, ` to JSON: lowerCamelCase of path name \\"" + p + "\\" is irreversible");`)
539
- f.print(` }`)
540
- f.print(` return protoCamelCase(p);`)
541
- f.print(` }).join(",");`)
542
- f.print("};");
543
- f.print()
544
- f.print(message, ".prototype.fromJson = function fromJson(json, options) {")
545
- f.print(` if (typeof json !== "string") {`)
546
- f.print(` throw new Error("cannot decode `, message.typeName, ` from JSON: " + proto3.json.debug(json));`)
547
- f.print(` }`)
548
- f.print(` if (json === "") {`)
549
- f.print(` return this;`)
550
- f.print(` }`)
551
- f.print(` function camelToSnake (str) {`)
552
- f.print(` if (str.includes("_")) {`)
553
- f.print(` throw new Error("cannot decode `, message.typeName, ` from JSON: path names must be lowerCamelCase");`)
554
- f.print(` }`)
555
- f.print(` const sc = str.replace(/[A-Z]/g, letter => "_" + letter.toLowerCase());`)
556
- f.print(` return (sc[0] === "_") ? sc.substring(1) : sc;`)
557
- f.print(` }`)
558
- f.print(` this.`, localName(ref.paths), ` = json.split(",").map(camelToSnake);`)
559
- f.print(` return this;`)
560
- f.print("};");
561
- f.print()
562
- break;
563
- case "google.protobuf.DoubleValue":
564
- case "google.protobuf.FloatValue":
565
- case "google.protobuf.Int64Value":
566
- case "google.protobuf.UInt64Value":
567
- case "google.protobuf.Int32Value":
568
- case "google.protobuf.UInt32Value":
569
- case "google.protobuf.BoolValue":
570
- case "google.protobuf.StringValue":
571
- case "google.protobuf.BytesValue":
572
- f.print(message, ".prototype.toJson = function toJson(options) {")
573
- f.print(" return proto3.json.writeScalar(", rtScalarType, ".", ScalarType[ref.value.scalar], ", this.value, true);")
574
- f.print("}")
575
- f.print()
576
- f.print(message, ".prototype.fromJson = function fromJson(json, options) {")
577
- f.print(" try {")
578
- f.print(" this.value = ", protoN, ".json.readScalar(", rtScalarType, ".", ScalarType[ref.value.scalar], ", json);")
579
- f.print(" } catch (e) {")
580
- f.print(" let m = `cannot decode message ", message.typeName, " from JSON\"`;")
581
- f.print(" if (e instanceof Error && e.message.length > 0) {")
582
- f.print(" m += `: ${e.message}`")
583
- f.print(" }")
584
- f.print(" throw new Error(m);")
585
- f.print(" }")
586
- f.print(" return this;")
587
- f.print("};");
588
- f.print()
589
- break;
590
- }
591
- }
592
-
593
- // prettier-ignore
594
- function generateWktStaticMethods(schema: Schema, f: GeneratedFile, message: DescMessage) {
595
- const ref = reifyWkt(message);
596
- if (ref === undefined) {
597
- return;
598
- }
599
- const {
600
- protoInt64,
601
- } = schema.runtime;
602
- switch (ref.typeName) {
603
- case "google.protobuf.Any":
604
- f.print(message, ".pack = function pack(message) {")
605
- f.print(" const any = new ", message, "();")
606
- f.print(" any.packFrom(message);")
607
- f.print(" return any;")
608
- f.print("};")
609
- f.print()
610
- break;
611
- case "google.protobuf.Timestamp":
612
- f.print(message, ".now = function now() {")
613
- f.print(" return ", message, ".fromDate(new Date())")
614
- f.print("};")
615
- f.print()
616
- f.print(message, ".fromDate = function fromDate(date) {")
617
- f.print(" const ms = date.getTime();")
618
- f.print(" return new ", message, "({")
619
- f.print(" ", localName(ref.seconds), ": ", protoInt64, ".parse(Math.floor(ms / 1000)),")
620
- f.print(" ", localName(ref.nanos), ": (ms % 1000) * 1000000,")
621
- f.print(" });")
622
- f.print("};")
623
- f.print()
624
- break;
625
- case "google.protobuf.DoubleValue":
626
- case "google.protobuf.FloatValue":
627
- case "google.protobuf.Int64Value":
628
- case "google.protobuf.UInt64Value":
629
- case "google.protobuf.Int32Value":
630
- case "google.protobuf.UInt32Value":
631
- case "google.protobuf.BoolValue":
632
- case "google.protobuf.StringValue":
633
- case "google.protobuf.BytesValue": {
634
- f.print(message, ".fieldWrapper = {")
635
- f.print(" wrapField(value) {")
636
- f.print(" return new ", message, "({value});")
637
- f.print(" },")
638
- f.print(" unwrapField(value) {")
639
- f.print(" return value.", localName(ref.value), ";")
640
- f.print(" }")
641
- f.print("};")
642
- f.print()
643
- break;
644
- }
645
- case "google.protobuf.Duration":
646
- case "google.protobuf.Struct":
647
- case "google.protobuf.Value":
648
- case "google.protobuf.ListValue":
649
- case "google.protobuf.FieldMask":
650
- break;
651
- }
652
- }