Extension Declarations
Introduction
This page describes in detail what extension declarations are, why we need them, and how we use them.
Note
Proto3 does not support extensions (except for declaring custom options). Extensions are fully supported in proto2 and editions though.If you need an introduction to extensions, read this extensions guide
Motivation
Extension declarations aim to strike a happy medium between regular fields and extensions. Like extensions, they avoid creating a dependency on the message type of the field, which therefore results in a leaner build graph and smaller binaries in environments where unused messages are difficult or impossible to strip. Like regular fields, the field name/number appear in the enclosing message, which makes it easier to avoid conflicts and see a convenient listing of what fields are declared.
Listing the occupied extension numbers with extension declarations makes it easier for users to pick an available extension number and to avoid conflicts.
Usage
Extension declarations are an option of extension ranges. Like forward
declarations in C++, you can declare the field type, field name, and cardinality
(singular or repeated) of an extension field without importing the .proto file
containing the full extension definition:
edition = "2023";
message Foo {
extensions 4 to 1000 [
declaration = {
number: 4,
full_name: ".my.package.event_annotations",
type: ".logs.proto.ValidationAnnotations",
repeated: true },
declaration = {
number: 999,
full_name: ".foo.package.bar",
type: "int32"}];
}
This syntax has the following semantics:
- Multiple
declarations with distinct extension numbers can be defined in a single extension range if the size of the range allows. - If there is any declaration for the extension range, all extensions of the range must also be declared. This prevents non-declared extensions from being added, and enforces that any new extensions use declarations for the range.
- The given message type (
.logs.proto.ValidationAnnotations) does not need to have been previously defined or imported. We check only that it is a valid name that could potentially be defined in another.protofile. - When this or another
.protofile defines an extension of this message (Foo) with this name or number, we enforce that the number, type, and full name of the extension match what is forward-declared here.
Warning
Avoid using declarations for extension range groups such asextensions 4, 999.
It is unclear which extension range the declarations apply to, and it is
currently unsupported.The extension declarations expect two extension fields with different packages:
package my.package;
extend Foo {
repeated logs.proto.ValidationAnnotations event_annotations = 4;
}
package foo.package;
extend Foo {
optional int32 bar = 999;
}
Reserved Declarations
An extension declaration can be marked reserved: true to indicate that it is
no longer actively used and the extension definition has been deleted. Do not
delete the extension declaration or edit its type or full_name value.
This reserved tag is separate from the reserved keyword for regular fields and
does not require breaking up the extension range.
edition = "2023";