@@ -29,35 +29,57 @@ act like proto2 or proto3 files. For more information on how Editions and
2929Features work together to set behavior, see
3030[ Protobuf Editions Overview] ( /editions/overview ) .
3131
32- Each of the following sections has an entry for what scope the feature applies
33- to. This can include file, enum, message, or field. The following sample shows a
34- mock feature applied to each scope:
32+ <span id =" cascading " > Feature settings apply at different levels:</span >
33+
34+ ** File-level:** These settings apply to all elements (messages, fields, enums,
35+ and so on) that don't have an overriding setting.
36+
37+ ** Non-nested:** Messages, enums, and services can override settings made at the
38+ file level. They apply to everything within them (message fields, enum values)
39+ that aren't overridden, but don't apply to other parallel messages and enums.
40+
41+ ** Nested:** Oneofs, messages, and enums can override settings from the message
42+ they're nested in.
43+
44+ ** Lowest-level:** Fields, extensions, enum values, extension ranges, and methods
45+ are the lowest level at which you can override settings.
46+
47+ Each of the following sections has a comment that states what scope the feature
48+ can be applied to. The following sample shows a mock feature applied to each
49+ scope:
3550
3651``` proto
3752edition = "2023";
3853
39- // File-scope definition
54+ // File-level scope definition
4055option features.bar = BAZ;
4156
4257enum Foo {
43- // Enum- scope definition
58+ // Enum (non-nested scope) definition
4459 option features.bar = QUX;
4560
4661 A = 1;
4762 B = 2;
4863}
4964
5065message Corge {
51- // Message- scope definition
66+ // Message (non-nested scope) definition
5267 option features.bar = QUUX;
5368
54- // Field-scope definition
69+ message Garply {
70+ // Message (nested scope) definition
71+ option features.bar = WALDO;
72+ string id = 1;
73+ }
74+
75+ // Field (lowest-level scope) definition
5576 Foo A = 1 [features.bar = GRAULT];
5677}
5778```
5879
59- In this example, the setting ` GRAULT ` in the field-scope feature definition
60- overrides the message-scope QUUX setting.
80+ In this example, the setting "` GRAULT" ` in the lowest-level scope feature
81+ definition overrides the non-nested-scope "` QUUX ` " setting. And within the
82+ Garply message, "` WALDO ` " overrides "` QUUX ` ."
6183
6284### ` features.enum_type ` {#enum_type}
6385
@@ -83,6 +105,9 @@ and after of a proto3 file.
83105
84106** Behavior in proto3:** ` OPEN `
85107
108+ ** Note:** Feature settings on different schema elements
109+ [ have different scopes] ( #cascading ) .
110+
86111The following code sample shows a proto2 file:
87112
88113``` proto
@@ -102,6 +127,7 @@ this:
102127edition = "2023";
103128
104129enum Foo {
130+ // Setting the enum_type feature overrides the default OPEN enum
105131 option features.enum_type = CLOSED;
106132 A = 2;
107133 B = 4;
@@ -129,7 +155,7 @@ whether a protobuf field has a value.
129155
130156** Applicable to the following scopes:** File, Field
131157
132- ** Default value in the Edition 2023:** ` EXPLICIT `
158+ ** Default behavior in the Edition 2023:** ` EXPLICIT `
133159
134160** Behavior in proto2:** ` EXPLICIT `
135161
@@ -138,6 +164,9 @@ which case it behaves like `EXPLICIT`. See
138164[ Presence in Proto3 APIs] ( /programming-guides/field_presence#presence-in-proto3-apis )
139165for more information.
140166
167+ ** Note:** Feature settings on different schema elements
168+ [ have different scopes] ( #cascading ) .
169+
141170The following code sample shows a proto2 file:
142171
143172``` proto
@@ -156,6 +185,7 @@ After running Prototiller, the equivalent code might look like this:
156185edition = "2023";
157186
158187message Foo {
188+ // Setting the field_presence feature retains the proto2 required behavior
159189 int32 x = 1 [features.field_presence = LEGACY_REQUIRED];
160190 int32 y = 2;
161191 repeated int32 z = 3;
@@ -178,10 +208,13 @@ After running Prototiller, the equivalent code might look like this:
178208
179209``` proto
180210edition = "2023";
211+ // Setting the file-level field_presence feature matches the proto3 implicit default
181212option features.field_presence = IMPLICIT;
182213
183214message Bar {
184215 int32 x = 1;
216+ // Setting the field_presence here retains the explicit state that the proto3
217+ // field has because of the optional syntax
185218 int32 y = 2 [features.field_presence = EXPLICIT];
186219 repeated int32 z = 3;
187220}
@@ -214,6 +247,9 @@ and after of a proto3 file. Editions behavior matches the behavior in proto3.
214247
215248** Behavior in proto3:** ` ALLOW `
216249
250+ ** Note:** Feature settings on different schema elements
251+ [ have different scopes] ( #cascading ) .
252+
217253The following code sample shows a proto2 file:
218254
219255``` proto
@@ -230,7 +266,7 @@ After running Prototiller, the equivalent code might look like this:
230266
231267``` proto
232268edition = "2023";
233- features.json_format = LEGACY_BEST_EFFORT;
269+ option features.json_format = LEGACY_BEST_EFFORT;
234270
235271message Foo {
236272 string bar = 1;
@@ -270,6 +306,9 @@ the following conditions are met:
270306
271307** Behavior in proto3:** ` LENGTH_PREFIXED ` . Proto3 doesn't support ` DELIMITED ` .
272308
309+ ** Note:** Feature settings on different schema elements
310+ [ have different scopes] ( #cascading ) .
311+
273312The following code sample shows a proto2 file:
274313
275314``` proto
@@ -318,6 +357,9 @@ for `repeated` fields has been migrated to in Editions.
318357
319358** Behavior in proto3:** ` PACKED `
320359
360+ ** Note:** Feature settings on different schema elements
361+ [ have different scopes] ( #cascading ) .
362+
321363The following code sample shows a proto2 file:
322364
323365``` proto
@@ -389,6 +431,9 @@ and after of a proto3 file.
389431
390432** Behavior in proto3:** ` VERIFY `
391433
434+ ** Note:** Feature settings on different schema elements
435+ [ have different scopes] ( #cascading ) .
436+
392437The following code sample shows a proto2 file:
393438
394439``` proto
@@ -441,6 +486,9 @@ before and after of a proto3 file.
441486
442487** Behavior in proto3:** ` false `
443488
489+ ** Note:** Feature settings on different schema elements
490+ [ have different scopes] ( #cascading ) .
491+
444492The following code sample shows a proto2 file:
445493
446494``` proto
@@ -495,6 +543,9 @@ specified on a field, but not both.
495543
496544** Behavior in proto3:** ` STRING `
497545
546+ ** Note:** Feature settings on different schema elements
547+ [ have different scopes] ( #cascading ) .
548+
498549The following code sample shows a proto2 file:
499550
500551``` proto
@@ -568,6 +619,9 @@ before and after of a proto3 file.
568619
569620** Behavior in proto3:** ` DEFAULT `
570621
622+ ** Note:** Feature settings on different schema elements
623+ [ have different scopes] ( #cascading ) .
624+
571625The following code sample shows a proto2 file:
572626
573627``` proto
@@ -592,6 +646,7 @@ option features.utf8_validation = NONE;
592646option features.(pb.java).utf8_validation = VERIFY;
593647message MyMessage {
594648 string foo = 1;
649+ string bar = 2;
595650}
596651```
597652
@@ -618,6 +673,9 @@ files.
618673
619674** Behavior in proto3:** ` false `
620675
676+ ** Note:** Feature settings on different schema elements
677+ [ have different scopes] ( #cascading ) .
678+
621679## Preserving proto2 or proto3 Behavior {#preserving}
622680
623681You may want to move to the editions format but not deal with updates to the way
0 commit comments