init
This commit is contained in:
@@ -0,0 +1,135 @@
|
||||
# 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
|
||||
Reference in New Issue
Block a user