Skip to content

Commit f04ded3

Browse files
authored
Merge pull request #2051 from mkruskal-google/edition2023
feat: add Edition 2023 Support
2 parents 00d5f1a + ac9a3b9 commit f04ded3

29 files changed

+1794
-312
lines changed

cli/targets/proto.js

+29-14
Original file line numberDiff line numberDiff line change
@@ -184,8 +184,12 @@ function buildType(type) {
184184
}
185185

186186
function buildField(field, passExtend) {
187-
if (field.partOf || field.declaringField || field.extend !== undefined && !passExtend)
187+
if (field.partOf && !field.partOf.isProto3Optional) {
188188
return;
189+
}
190+
if (field.declaringField || field.extend !== undefined && !passExtend) {
191+
return;
192+
}
189193
if (first) {
190194
first = false;
191195
push("");
@@ -199,8 +203,10 @@ function buildField(field, passExtend) {
199203
sb.push("map<" + field.keyType + ", " + field.type + ">");
200204
else if (field.repeated)
201205
sb.push("repeated", field.type);
202-
else if (syntax === 2 || field.parent.group)
206+
else if (syntax === 2)
203207
sb.push(field.required ? "required" : "optional", field.type);
208+
else if (syntax === 3 && field.hasPresence)
209+
sb.push("optional", field.type);
204210
else
205211
sb.push(field.type);
206212
sb.push(underScore(field.name), "=", field.id);
@@ -211,7 +217,7 @@ function buildField(field, passExtend) {
211217
}
212218

213219
function buildGroup(field) {
214-
push(field.rule + " group " + field.resolvedType.name + " = " + field.id + " {");
220+
push((field.rule || "optional") + " group " + field.resolvedType.name + " = " + field.id + " {");
215221
++indent;
216222
buildOptions(field.resolvedType);
217223
first = true;
@@ -223,20 +229,16 @@ function buildGroup(field) {
223229
}
224230

225231
function buildFieldOptions(field) {
226-
var keys;
227-
if (!field.options || !(keys = Object.keys(field.options)).length)
228-
return null;
232+
var keys = [];
233+
if (field.options) {
234+
keys = Object.keys(field.options);
235+
}
229236
var sb = [];
230237
keys.forEach(function(key) {
238+
if (key === "proto3_optional" || key === "packed" || key === "features") return;
239+
231240
var val = field.options[key];
232-
var wireType = types.packed[field.resolvedType instanceof Enum ? "int32" : field.type];
233241
switch (key) {
234-
case "packed":
235-
val = Boolean(val);
236-
// skip when not packable or syntax default
237-
if (wireType === undefined || syntax === 3 === val)
238-
return;
239-
break;
240242
case "default":
241243
if (syntax === 3)
242244
return;
@@ -253,6 +255,14 @@ function buildFieldOptions(field) {
253255
}
254256
sb.push(key + "=" + val);
255257
});
258+
var packable = types.packed[field.resolvedType instanceof Enum ? "int32" : field.type];
259+
if (packable !== undefined) {
260+
if (field.packed && syntax === 2) {
261+
sb.push("packed=true");
262+
} else if(!field.packed && syntax === 3) {
263+
sb.push("packed=false");
264+
}
265+
}
256266
return sb.length
257267
? "[" + sb.join(", ") + "]"
258268
: null;
@@ -282,6 +292,10 @@ function consolidateExtends(nested) {
282292
}
283293

284294
function buildOneOf(oneof) {
295+
if (oneof.isProto3Optional) {
296+
return;
297+
}
298+
285299
push("");
286300
push("oneof " + underScore(oneof.name) + " {");
287301
++indent; first = true;
@@ -311,11 +325,12 @@ function buildMethod(method) {
311325
push(method.type + " " + method.name + " (" + (method.requestStream ? "stream " : "") + method.requestType + ") returns (" + (method.responseStream ? "stream " : "") + method.responseType + ");");
312326
}
313327

314-
function buildOptions(object) {
328+
function buildOptions(object, ignore = []) {
315329
if (!object.options)
316330
return;
317331
first = true;
318332
Object.keys(object.options).forEach(function(key) {
333+
if (ignore.includes(key) || key === "features") return;
319334
if (first) {
320335
first = false;
321336
push("");

cli/targets/static.js

+14-72
Original file line numberDiff line numberDiff line change
@@ -362,72 +362,12 @@ function toJsType(field, parentIsInterface = false) {
362362
return type;
363363
}
364364

365-
function syntaxForType(type) {
366-
367-
var syntax = null;
368-
var namespace = type;
369-
370-
while (syntax === null && namespace !== null) {
371-
if (namespace.options != null && "syntax" in namespace.options) {
372-
syntax = namespace.options["syntax"];
373-
}
374-
else {
375-
namespace = namespace.parent;
376-
}
377-
}
378-
379-
return syntax !== null ? syntax : "proto2";
380-
}
381-
382-
function isExplicitPresence(field, syntax) {
383-
384-
// In proto3, optional fields are explicit
385-
if (syntax === "proto3") {
386-
return field.options != null && field.options["proto3_optional"] === true;
387-
}
388-
389-
// In proto2, fields are explicitly optional if they are not part of a map, array or oneOf group
390-
if (syntax === "proto2") {
391-
return field.optional && !(field.partOf || field.repeated || field.map);
392-
}
393-
394-
throw new Error("Unknown proto syntax: [" + syntax + "]");
395-
}
396-
397-
function isImplicitPresence(field, syntax) {
398-
399-
// In proto3, everything not marked optional has implicit presence (including maps and repeated fields)
400-
if (syntax === "proto3") {
401-
return field.options == null || field.options["proto3_optional"] !== true;
402-
}
403-
404-
// In proto2, nothing has implicit presence
405-
if (syntax === "proto2") {
406-
return false;
407-
}
408-
409-
throw new Error("Unknown proto syntax: [" + syntax + "]");
410-
}
411-
412-
function isOptionalOneOf(oneof, syntax) {
413-
414-
if (syntax === "proto2") {
415-
return false;
416-
}
417-
418-
if (oneof.fieldsArray == null || oneof.fieldsArray.length !== 1) {
419-
return false;
420-
}
421-
422-
var field = oneof.fieldsArray[0];
423-
424-
return field.options != null && field.options["proto3_optional"] === true;
365+
function isNullable(field) {
366+
return field.hasPresence && !field.required;
425367
}
426368

427369
function buildType(ref, type) {
428370

429-
var syntax = syntaxForType(type);
430-
431371
if (config.comments) {
432372
var typeDef = [
433373
"Properties of " + aOrAn(type.name) + ".",
@@ -443,13 +383,15 @@ function buildType(ref, type) {
443383
// With semantic nulls, only explicit optional fields and one-of members can be set to null
444384
// Implicit fields (proto3), maps and lists can be omitted, but if specified must be non-null
445385
// Implicit fields will take their default value when the message is constructed
446-
if (isExplicitPresence(field, syntax) || field.partOf) {
447-
jsType = jsType + "|null|undefined";
448-
nullable = true;
449-
}
450-
else if (isImplicitPresence(field, syntax) || field.repeated || field.map) {
451-
jsType = jsType + "|undefined";
452-
nullable = true;
386+
if (field.optional) {
387+
if (isNullable(field)) {
388+
jsType = jsType + "|null|undefined";
389+
nullable = true;
390+
}
391+
else {
392+
jsType = jsType + "|undefined";
393+
nullable = true;
394+
}
453395
}
454396
}
455397
else {
@@ -490,7 +432,7 @@ function buildType(ref, type) {
490432
// With semantic nulls, fields are nullable if they are explicitly optional or part of a one-of
491433
// Maps, repeated values and fields with implicit defaults are never null after construction
492434
// Members are never undefined, at a minimum they are initialized to null
493-
if (isExplicitPresence(field, syntax) || field.partOf) {
435+
if (isNullable(field)) {
494436
jsType = jsType + "|null";
495437
}
496438
}
@@ -514,7 +456,7 @@ function buildType(ref, type) {
514456
// With semantic nulls, only explict optional fields and one-of members are null by default
515457
// Otherwise use field.optional, which doesn't consider proto3, maps, repeated fields etc.
516458
var nullDefault = config["null-semantics"]
517-
? isExplicitPresence(field, syntax)
459+
? isNullable(field)
518460
: field.optional && config["null-defaults"];
519461
if (field.repeated)
520462
push(escapeName(type.name) + ".prototype" + prop + " = $util.emptyArray;"); // overwritten in constructor
@@ -546,7 +488,7 @@ function buildType(ref, type) {
546488
}
547489
oneof.resolve();
548490
push("");
549-
if (isOptionalOneOf(oneof, syntax)) {
491+
if (oneof.isProto3Optional) {
550492
push("// Virtual OneOf for proto3 optional field");
551493
}
552494
else {

0 commit comments

Comments
 (0)