Managed mode is Buf's solution for decoupling API producer concerns from consumer concerns. Protobuf code generation includes a set of options related to language and package output, optimization strategies, and other details that give API consumers fine-grained controls over their generated code. However, Protobuf requires these options to be defined by the API producers and specified in the schema, taking away some of the freedom that the options attempt to offer (since different consumers of the same API might want to generate code differently).
When managed mode is enabled, both producers and consumers can work with these options optimally:
- Producers can leave them out of the API definition entirely, freeing them from determining a “correct” implementation when there may be many acceptable ways of generating code from their schemas.
- Consumers actually have the control over generated code output that the options imply, and because managed mode has a thoughtful set of default values, may not need to specify the options further. They can simply enable it with two lines of code and get the output they need.
For example in this weather.proto
file, four file options are set:
syntax = "proto3";
package acme.weather.v1;
option go_package = "github.com/acme/weather/gen/proto/go/acme/weather/v1";
option java_multiple_files = true;
option java_outer_classname = "WeatherProto";
option java_package = "com.acme.weather.v1";
// Messages, enums, etc.
None of them have anything to do with the actual API definition in Protobuf, and different consumers may want to use
different values for these options. A Java developer, for example, may want to specify a java_package
that matches
their organization.
The problem really comes to a head when it comes to import paths. With protoc
, a Go developer would either need to:
- specify a value for
go_package
in their.proto
file, or - use
Mfile=go_package
via--go_opt
on a per-file basis to set or override thego_package
value in a.proto
file (this would be the flag for the.proto
file above):
--go_opt=Macme/weather/v1/weather.proto=github.com/acme/weather/gen/proto/go/acme/weather/v1
When managed mode is enabled in your buf.gen.yaml
configuration file,
the Buf CLI sets your specified file options on the fly during code generation so that you don't need to hard-code them
in your .proto
files. If its defaults match your desired output, you won't need to set the individual options at all.
Managed mode provides options for choosing an optimization strategy, and for these languages:
- C++
- C#
- Go
- Java
- Objective-C
- PHP
- Ruby
If you're generating code for a language that isn't on this list, managed mode has no implications and enabling it has
no effect. And if you're generating Swift code, Protobuf does offer a swift_prefix
option, but Apple specifically
counsels against using it,
so managed mode doesn't support it.
Configuration
To enable managed mode, set the managed.enabled
option in your buf.gen.yaml
configuration file. This will cause the
file options to match the default behavior described below.
version: v1
managed:
enabled: true
// Managed mode options
// Plugins and other configuration options
Managed mode only supports the
standard file options
included in Protobuf. If you're using custom file options, you'll still need to include them in your .proto
files.
See the buf.gen.yaml
reference for a full explanation of managed mode's fields
and usage.
Default behavior
When managed mode is enabled without any other settings, it uses the following defaults for all .proto
files contained
in the input, unless otherwise overridden:
cc_enable_arenas
is not modified. Protobuf's default istrue
.csharp_namespace
is set to the package name with each package sub-part capitalized.go_package_prefix
does not modifygo_package
. Itsdefault
must be set to have an effect.java_multiple_files
is set totrue
. Protobuf's default isfalse
.java_outer_classname
is set to the PascalCase-equivalent of the file name, removing the.
for the.proto
extension.java_package_prefix
is set to the package name withcom.
prepended to it.java_string_check_utf8
is not modified. Protobuf's default isfalse
.objc_class_prefix
is set to the uppercase first letter of each package sub-name, not including the package version, with the following rules:- If the resulting abbreviation is 2 characters, append
X
. - If the resulting abbreviation is 1 character, append
XX
. - If the resulting abbreviation is
GPB
, change it toGPX
.GPB
is reserved by Google for the Protocol Buffers implementation.
- If the resulting abbreviation is 2 characters, append
optimize_for
is not modified. Protobuf's default isSPEED
.php_namespace
is set to the package name with each package sub-name capitalized, with\
substituted for.
.php_metadata_namespace
is set to the same value asphp_namespace
, with\GPBMetadata
appended.ruby_package
is set to the package name with each package sub-name capitalized, with::
substituted for.
.
For example, enabling managed mode for the acme/weather/v1/weather.proto
file below with no other settings:
syntax = "proto3";
package acme.weather.v1;
// Messages, enums, etc.
sets its file options to the equivalent of this .proto
file before it's sent to the compiler to generate code for the
requested languages:
syntax = "proto3";
package acme.weather.v1;
option csharp_namespace = "Acme.Weather.V1";
option java_multiple_files = true;
option java_outer_classname = "WeatherProto";
option java_package = "com.acme.weather.v1";
option objc_class_prefix = "AWX";
option php_namespace = "Acme\Weather\V1";
option php_metadata_namespace = "Acme\Weather\V1\GPBMetadata";
option ruby_package = "Acme::Weather::V1";
// Messages, enums, etc.
Several of the standard file option fields can only be defined as
per-file overrides: java_outer_classname
, php_namespace
,
and php_metadata_namespace
.
Related docs
To see a complete file set illustrating managed mode, visit the managed-mode project.
- Try out code generation with the
buf generate
tutorial - Learn more about managed mode's fields and usage in the
buf.gen.yaml
reference - Browse the
buf generate
command reference