Skip to content

Commit ed5980c

Browse files
Change config flag to --null-semantics and update comments
1 parent 31f85e9 commit ed5980c

File tree

1 file changed

+17
-16
lines changed

1 file changed

+17
-16
lines changed

cli/targets/static.js

Lines changed: 17 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -409,22 +409,23 @@ function buildType(ref, type) {
409409
prop = prop.substring(1, prop.charAt(0) === "[" ? prop.length - 1 : prop.length);
410410
var jsType = toJsType(field);
411411
var nullable = false;
412-
413-
// New behaviour - respect explicit optional semantics in both proto2 and proto3
414-
if (config["force-optional"]) {
412+
if (config["null-semantics"]) {
413+
// With semantic nulls, decide which fields are required for the current protobuf version
414+
// Fields with implicit defaults in proto3 are required for the purpose of constructing objects
415+
// Optional fields can be undefined, i.e. they can be omitted for the source object altogether
415416
if (isOptional(field, syntax) || field.partOf || field.repeated || field.map) {
416-
jsType = jsType + "|null";
417+
jsType = jsType + "|null|undefined";
417418
nullable = true;
418419
}
419420
}
420-
// Old behaviour - field.optional is true for all fields in proto3
421421
else {
422+
// Without semantic nulls, everything is optional in proto3
423+
// Do not allow |undefined to keep backwards compatibility
422424
if (field.optional) {
423425
jsType = jsType + "|null";
424426
nullable = true;
425427
}
426428
}
427-
428429
typeDef.push("@property {" + jsType + "} " + (nullable ? "[" + prop + "]" : prop) + " " + (field.comment || type.name + " " + field.name));
429430
});
430431
push("");
@@ -451,19 +452,19 @@ function buildType(ref, type) {
451452
if (config.comments) {
452453
push("");
453454
var jsType = toJsType(field);
454-
455-
// New behaviour - fields explicitly marked as optional and members of a one-of are nullable
456-
// Maps and repeated fields are not nullable, they default to empty instances
457-
if (config["force-optional"]) {
455+
if (config["null-semantics"]) {
456+
// With semantic nulls, fields are nullable if they are explicitly optional or part of a one-of
457+
// Maps, repeated values and fields with implicit defaults are never null after construction
458+
// Members are never undefined, at a minimum they are initialized to null
458459
if (isOptional(field, syntax) || field.partOf)
459-
jsType = jsType + "|null|undefined";
460+
jsType = jsType + "|null";
460461
}
461-
// Old behaviour - field.optional is true for all fields in proto3
462462
else {
463+
// Without semantic nulls, everything is optional in proto3
464+
// Keep |undefined for backwards compatibility
463465
if (field.optional && !field.map && !field.repeated && (field.resolvedType instanceof Type || config["null-defaults"]) || field.partOf)
464466
jsType = jsType + "|null|undefined";
465467
}
466-
467468
pushComment([
468469
field.comment || type.name + " " + field.name + ".",
469470
"@member {" + jsType + "} " + field.name,
@@ -474,9 +475,9 @@ function buildType(ref, type) {
474475
push("");
475476
firstField = false;
476477
}
477-
// New behaviour sets a null default when the optional keyword is used explicitly
478-
// Old behaviour considers all proto3 fields optional and uses the null-defaults config flag
479-
var nullDefault = config["force-optional"]
478+
// Semantic nulls respect the optional semantics for the current protobuf version
479+
// Otherwise use field.optional, which doesn't consider proto3, maps, repeated fields etc.
480+
var nullDefault = config["null-semantics"]
480481
? isOptional(field, syntax)
481482
: field.optional && config["null-defaults"];
482483
if (field.repeated)

0 commit comments

Comments
 (0)