Changes Announced on June 29, 2023

Changes announced for Protocol Buffers 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.

Editions lifecycle
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.