@@ -62,6 +62,13 @@ enum Edition {
6262 // A placeholder for an unknown edition value.
6363 EDITION_UNKNOWN = 0 ;
6464
65+ // Legacy syntax "editions". These pre-date editions, but behave much like
66+ // distinct editions. These can't be used to specify the edition of proto
67+ // files, but feature definitions must supply proto2/proto3 defaults for
68+ // backwards compatibility.
69+ EDITION_PROTO2 = 998 ;
70+ EDITION_PROTO3 = 999 ;
71+
6572 // Editions that have been released. The specific values are arbitrary and
6673 // should not be depended on, but they will always be time-ordered for easy
6774 // comparison.
@@ -74,6 +81,11 @@ enum Edition {
7481 EDITION_99997_TEST_ONLY = 99997 ;
7582 EDITION_99998_TEST_ONLY = 99998 ;
7683 EDITION_99999_TEST_ONLY = 99999 ;
84+
85+ // Placeholder for specifying unbounded edition support. This should only
86+ // ever be used by plugins that can expect to never require any changes to
87+ // support a new edition.
88+ EDITION_MAX = 0x7FFFFFFF ;
7789}
7890
7991// Describes a complete .proto file.
@@ -109,12 +121,8 @@ message FileDescriptorProto {
109121 // If `edition` is present, this value must be "editions".
110122 optional string syntax = 12 ;
111123
112- // The edition of the proto file, which is an opaque string.
113- // TODO(b/297898292) Deprecate and remove this field in favor of enums.
114- optional string edition = 13 ;
115-
116124 // The edition of the proto file.
117- optional Edition edition_enum = 14 ;
125+ optional Edition edition = 14 ;
118126}
119127
120128// Describes a message type.
@@ -197,9 +205,10 @@ message ExtensionRangeOptions {
197205 }
198206
199207 // The verification state of the range.
200- // TODO(b/278783756) : flip the default to DECLARATION once all empty ranges
208+ // TODO: flip the default to DECLARATION once all empty ranges
201209 // are marked as UNVERIFIED.
202- optional VerificationState verification = 3 [default = UNVERIFIED ];
210+ optional VerificationState verification = 3
211+ [default = UNVERIFIED , retention = RETENTION_SOURCE ];
203212
204213 // Clients can define custom options in extensions of this message. See above.
205214 extensions 1000 to max;
@@ -224,9 +233,10 @@ message FieldDescriptorProto {
224233 TYPE_BOOL = 8 ;
225234 TYPE_STRING = 9 ;
226235 // Tag-delimited aggregate.
227- // Group type is deprecated and not supported in proto3 . However, Proto3
236+ // Group type is deprecated and not supported after google.protobuf . However, Proto3
228237 // implementations should still be able to parse the group wire format and
229- // treat group fields as unknown fields.
238+ // treat group fields as unknown fields. In Editions, the group wire format
239+ // can be enabled via the `message_encoding` feature.
230240 TYPE_GROUP = 10 ;
231241 TYPE_MESSAGE = 11 ; // Length-delimited aggregate.
232242
@@ -243,8 +253,11 @@ message FieldDescriptorProto {
243253 enum Label {
244254 // 0 is reserved for errors
245255 LABEL_OPTIONAL = 1 ;
246- LABEL_REQUIRED = 2 ;
247256 LABEL_REPEATED = 3 ;
257+ // The required label is only allowed in google.protobuf. In proto3 and Editions
258+ // it's explicitly prohibited. In Editions, the `field_presence` feature
259+ // can be used to get this behavior.
260+ LABEL_REQUIRED = 2 ;
248261 }
249262
250263 optional string name = 1 ;
@@ -287,12 +300,12 @@ message FieldDescriptorProto {
287300 // If true, this is a proto3 "optional". When a proto3 field is optional, it
288301 // tracks presence regardless of field type.
289302 //
290- // When proto3_optional is true, this field must be belong to a oneof to
291- // signal to old proto3 clients that presence is tracked for this field. This
292- // oneof is known as a "synthetic" oneof, and this field must be its sole
293- // member (each proto3 optional field gets its own synthetic oneof). Synthetic
294- // oneofs exist in the descriptor only, and do not generate any API. Synthetic
295- // oneofs must be ordered after all "real" oneofs.
303+ // When proto3_optional is true, this field must belong to a oneof to signal
304+ // to old proto3 clients that presence is tracked for this field. This oneof
305+ // is known as a "synthetic" oneof, and this field must be its sole member
306+ // (each proto3 optional field gets its own synthetic oneof). Synthetic oneofs
307+ // exist in the descriptor only, and do not generate any API. Synthetic oneofs
308+ // must be ordered after all "real" oneofs.
296309 //
297310 // For message fields, proto3_optional doesn't create any semantic change,
298311 // since non-repeated message fields always track presence. However it still
@@ -597,7 +610,7 @@ message MessageOptions {
597610 // This should only be used as a temporary measure against broken builds due
598611 // to the change in behavior for JSON field name conflicts.
599612 //
600- // TODO(b/261750190) This is legacy behavior we plan to remove once downstream
613+ // TODO This is legacy behavior we plan to remove once downstream
601614 // teams have had time to migrate.
602615 optional bool deprecated_legacy_json_field_conflicts = 11 [deprecated = true ];
603616
@@ -637,7 +650,9 @@ message FieldOptions {
637650 // a more efficient representation on the wire. Rather than repeatedly
638651 // writing the tag and type for each element, the entire array is encoded as
639652 // a single length-delimited blob. In proto3, only explicit setting it to
640- // false will avoid using packed encoding.
653+ // false will avoid using packed encoding. This option is prohibited in
654+ // Editions, but the `repeated_field_encoding` feature can be used to control
655+ // the behavior.
641656 optional bool packed = 2 ;
642657
643658 // The jstype option determines the JavaScript type used for values of the
@@ -744,9 +759,7 @@ message FieldOptions {
744759 repeated OptionTargetType targets = 19 ;
745760
746761 message EditionDefault {
747- // TODO(b/297898292) Deprecate and remove this field in favor of enums.
748- optional string edition = 1 ;
749- optional Edition edition_enum = 3 ;
762+ optional Edition edition = 3 ;
750763 optional string value = 2 ; // Textproto value.
751764 }
752765 repeated EditionDefault edition_defaults = 20 ;
@@ -793,7 +806,7 @@ message EnumOptions {
793806 // and strips underscored from the fields before comparison in proto3 only.
794807 // The new behavior takes `json_name` into account and applies to proto2 as
795808 // well.
796- // TODO(b/261750190) Remove this legacy behavior once downstream teams have
809+ // TODO Remove this legacy behavior once downstream teams have
797810 // had time to migrate.
798811 optional bool deprecated_legacy_json_field_conflicts = 6 [deprecated = true ];
799812
@@ -917,7 +930,7 @@ message UninterpretedOption {
917930// ===================================================================
918931// Features
919932
920- // TODO(b/274655146) Enums in C++ gencode (and potentially other languages) are
933+ // TODO Enums in C++ gencode (and potentially other languages) are
921934// not well scoped. This means that each of the feature enums below can clash
922935// with each other. The short names we've chosen maximize call-site
923936// readability, but leave us very open to this scenario. A future feature will
@@ -934,7 +947,9 @@ message FeatureSet {
934947 retention = RETENTION_RUNTIME ,
935948 targets = TARGET_TYPE_FIELD ,
936949 targets = TARGET_TYPE_FILE ,
937- edition_defaults = { edition_enum : EDITION_2023, value : "EXPLICIT" }
950+ edition_defaults = { edition : EDITION_PROTO2, value : "EXPLICIT" },
951+ edition_defaults = { edition : EDITION_PROTO3, value : "IMPLICIT" },
952+ edition_defaults = { edition : EDITION_2023, value : "EXPLICIT" }
938953 ];
939954
940955 enum EnumType {
@@ -946,7 +961,8 @@ message FeatureSet {
946961 retention = RETENTION_RUNTIME ,
947962 targets = TARGET_TYPE_ENUM ,
948963 targets = TARGET_TYPE_FILE ,
949- edition_defaults = { edition_enum : EDITION_2023, value : "OPEN" }
964+ edition_defaults = { edition : EDITION_PROTO2, value : "CLOSED" },
965+ edition_defaults = { edition : EDITION_PROTO3, value : "OPEN" }
950966 ];
951967
952968 enum RepeatedFieldEncoding {
@@ -958,7 +974,21 @@ message FeatureSet {
958974 retention = RETENTION_RUNTIME ,
959975 targets = TARGET_TYPE_FIELD ,
960976 targets = TARGET_TYPE_FILE ,
961- edition_defaults = { edition_enum : EDITION_2023, value : "PACKED" }
977+ edition_defaults = { edition : EDITION_PROTO2, value : "EXPANDED" },
978+ edition_defaults = { edition : EDITION_PROTO3, value : "PACKED" }
979+ ];
980+
981+ enum Utf8Validation {
982+ UTF8_VALIDATION_UNKNOWN = 0 ;
983+ VERIFY = 2 ;
984+ NONE = 3 ;
985+ }
986+ optional Utf8Validation utf8_validation = 4 [
987+ retention = RETENTION_RUNTIME ,
988+ targets = TARGET_TYPE_FIELD ,
989+ targets = TARGET_TYPE_FILE ,
990+ edition_defaults = { edition : EDITION_PROTO2, value : "NONE" },
991+ edition_defaults = { edition : EDITION_PROTO3, value : "VERIFY" }
962992 ];
963993
964994 enum MessageEncoding {
@@ -970,7 +1000,7 @@ message FeatureSet {
9701000 retention = RETENTION_RUNTIME ,
9711001 targets = TARGET_TYPE_FIELD ,
9721002 targets = TARGET_TYPE_FILE ,
973- edition_defaults = { edition_enum : EDITION_2023 , value : "LENGTH_PREFIXED" }
1003+ edition_defaults = { edition : EDITION_PROTO2 , value : "LENGTH_PREFIXED" }
9741004 ];
9751005
9761006 enum JsonFormat {
@@ -983,10 +1013,11 @@ message FeatureSet {
9831013 targets = TARGET_TYPE_MESSAGE ,
9841014 targets = TARGET_TYPE_ENUM ,
9851015 targets = TARGET_TYPE_FILE ,
986- edition_defaults = { edition_enum : EDITION_2023, value : "ALLOW" }
1016+ edition_defaults = { edition : EDITION_PROTO2, value : "LEGACY_BEST_EFFORT" },
1017+ edition_defaults = { edition : EDITION_PROTO3, value : "ALLOW" }
9871018 ];
9881019
989- reserved 4 , 999 ;
1020+ reserved 999 ;
9901021
9911022 extensions 1000; // for Protobuf C++
9921023 extensions 1001; // for Protobuf Java
@@ -1004,24 +1035,18 @@ message FeatureSetDefaults {
10041035 // the defaults at the closest matching edition ordered at or before it should
10051036 // be used. This field must be in strict ascending order by edition.
10061037 message FeatureSetEditionDefault {
1007- // TODO(b/297898292) Deprecate and remove this field in favor of enums.
1008- optional string edition = 1 ;
1009- optional Edition edition_enum = 3 ;
1038+ optional Edition edition = 3 ;
10101039 optional FeatureSet features = 2 ;
10111040 }
10121041 repeated FeatureSetEditionDefault defaults = 1 ;
10131042
1014- // TODO(b/297898292) Deprecate and remove these fields in favor of enums.
1015- optional string minimum_edition = 2 ;
1016- optional string maximum_edition = 3 ;
1017-
10181043 // The minimum supported edition (inclusive) when this was constructed.
10191044 // Editions before this will not have defaults.
1020- optional Edition minimum_edition_enum = 4 ;
1045+ optional Edition minimum_edition = 4 ;
10211046
10221047 // The maximum known edition (inclusive) when this was constructed. Editions
10231048 // after this will not have reliable defaults.
1024- optional Edition maximum_edition_enum = 5 ;
1049+ optional Edition maximum_edition = 5 ;
10251050}
10261051
10271052// ===================================================================
0 commit comments