Changes Announced on June 29, 2023
TL;DR: We are planning to release Protobuf Editions to the open source project in the second half of 2023. While there is no requirement to move from proto2/proto3 syntax to Editions syntax at initial release, we encourage you to plan a move in your software project’s future timeline.
Protobuf Editions
Protobuf Editions replace the proto2 and proto3 designations that we have used
for Protocol Buffers. Instead of adding syntax = "proto2"
or syntax = "proto3"
at the top of proto definition files, you use an edition number, such
as edition = "2024"
, to specify the default behaviors your file will have.
Editions enable the language to evolve incrementally over time.
Instead of the hardcoded behaviors in older versions, editions will represent a collection of “features” with a default value (behavior) per feature, which you can override. Features are options on a file, message, field, enum, and so on that specify the behavior of protoc, the code generators, and protobuf runtimes. You can explicitly override the desired behavior at those different levels (file, message, field, …) when your needs don’t match the default behavior for the edition you’ve selected.
Editions won’t break existing binaries, and the first edition will be minimally disruptive; it will establish the baseline and will combine proto2 and proto3 definitions into a new single definition format. It won’t require any changes to your code. We will be providing a tool, called Prototiller, to migrate .proto files. The following examples show a proto2 definition file and a proto3 file, and what each might look like after using Prototiller to convert them to Protobuf Editions format:
Proto2 syntax
// proto2 file
syntax = "proto2";
message Player {
// in proto2, optional fields have explicit presence
optional string name = 1;
// proto2 still supports the problematic "required" field rule
required int32 id = 2;
// in proto2 this is not packed by default
repeated int32 scores = 3;
enum Handed {
HANDED_UNSPECIFIED = 0,
HANDED_LEFT = 1,
HANDED_RIGHT = 2,
HANDED_AMBIDEXTROUS = 3,
}
// in proto2 enums are closed
optional Handed handed = 4;
}
Editions syntax
// Editions version of proto2 file
edition = "2023";
message Player {
string name = 1;
int32 id = 2 [features.field_presence = LEGACY_REQUIRED];
repeated int32 scores = 3 [features.repeated_field_encoding = EXPANDED];
enum Handed {
// this overrides the default Edition 2023 behavior, which is OPEN
option features.enum = CLOSED;
HANDED_UNSPECIFIED = 0,
HANDED_LEFT = 1,
HANDED_RIGHT = 2,
HANDED_AMBIDEXTROUS = 3,
}
Handed handed = 4;
}
And this is what a similar proto3 definition file might look like:
Proto3 syntax
// proto3 file
syntax = "proto3";
message Player {
// in proto3, optional fields have explicit presence
optional string name = 1;
// in proto3 no specified field rule defaults to implicit presence
int32 id = 2;
// in proto3 this is packed by default
repeated int32 scores = 3;
enum Handed {
HANDED_UNSPECIFIED = 0,
HANDED_LEFT = 1,
HANDED_RIGHT = 2,
HANDED_AMBIDEXTROUS = 3,
}
// in proto3 enums are open
optional Handed handed = 4;
}
Editions syntax
// Editions version of proto3 file
edition = "2023";
message Player {
string name = 1;
int32 id = 2 [features.field_presence = IMPLICIT];
repeated int32 scores = 3;
enum Handed {
HANDED_UNSPECIFIED = 0,
HANDED_LEFT = 1,
HANDED_RIGHT = 2,
HANDED_AMBIDEXTROUS = 3,
}
Handed handed = 4;
}
While the examples provided in this topic show a direct translation of proto2 and proto3 to the equivalent representation using Protobuf Editions, you will be able to mix and match the settings to your project’s needs.
Features have a lifecycle that is governed by the releases of editions. For
example, features.awesome_new_feature
might be added in Edition 2031, with the
new behavior applying to all definitions that don’t explicitly override the new
behavior. In Edition 2033, the new feature is deprecated. Overrides still work,
but developers are alerted to the fact that they need to adapt to the new
behavior soon. In Edition 2036, the feature is removed and the new behavior
applies to all protos; there is no way to override the new behavior at this
point.
Figure 1: Editions lifecycle flowchart
Editions are planned to be released roughly once a year. For more information on Protobuf Editions, see the overview at https://protobuf.dev/editions/overview.