# Protobuf Editions Design: Features **Author:** [@haberman](https://github.com/haberman), [@fowles](https://github.com/fowles) **Approved:** 2022-10-13 A proposal to use custom options as our way of defining and representing features. ## Background The [Protobuf Editions](what-are-protobuf-editions.md) project uses "editions" to allow Protobuf to safely evolve over time. An edition is formally a set of "features" with a default value per feature. Features define the specific points of change and evolution on a per entity basis within a .proto file. ## Sample Usage ``` edition = "2023"; package experimental.users.kfm.editions; import "net/proto2/proto/features_cpp.proto"; option features.repeated_field_encoding = EXPANDED; option features.enum = OPEN; option features.(pb.cpp).string_field_type = STRING; message Lab { enum Mouse { UNKNOWN_MOUSE = 0; PINKY = 1; THE_BRAIN = 2; } repeated Mouse mice = 1 [features.repeated_field_encoding = PACKED]; string name = 2; string address = 3 [features.(pb.cpp).string_field_type = CORD]; } ``` ## Language-Specific Features Extensions manage features specific to individual code generators: ``` message Features { ... extensions 1000; // for features_cpp.proto extensions 1001; // for features_java.proto } ``` ## Inheritance Feature inheritance is exactly the behavior of `MergeFrom`: ``` void InheritFrom(const Features& parent, Features* child) { Features tmp(parent); tmp.MergeFrom(child); child->Swap(&tmp); } ``` ## Target Attributes ``` enum FeatureTargetType { FILE = 0; MESSAGE = 1; ENUM = 2; FIELD = 3; ... }; ``` ## Retention ``` enum FeatureRetention { SOURCE = 0; RUNTIME = 1; } ``` ## Edition Zero Features ``` message Features { enum FieldPresence { EXPLICIT = 0; IMPLICIT = 1; LEGACY_REQUIRED = 2; } optional FieldPresence field_presence = 1 [ retention = RUNTIME, target = FIELD, (edition_defaults) = { edition: "2023", default: "EXPLICIT" } ]; enum EnumType { OPEN = 0; CLOSED = 1; } optional EnumType enum = 2 [ retention = RUNTIME, target = ENUM, (edition_defaults) = { edition: "2023", default: "OPEN" } ]; enum RepeatedFieldEncoding { PACKED = 0; EXPANDED = 1; } optional RepeatedFieldEncoding repeated_field_encoding = 3 [ retention = RUNTIME, target = FIELD, (edition_defaults) = { edition: "2023", default: "PACKED" } ]; enum MessageEncoding { LENGTH_PREFIXED = 0; DELIMITED = 1; } optional MessageEncoding message_encoding = 5 [ retention = RUNTIME, target = FIELD, (edition_defaults) = { edition: "2023", default: "LENGTH_PREFIXED" } ]; extensions 1000; // for features_cpp.proto extensions 1001; // for features_java.proto } ``` --- Source: https://raw.githubusercontent.com/protocolbuffers/protobuf/main/docs/design/editions/protobuf-editions-design-features.md Downloaded: 2026-06-07