The plugin types define the protocol for protoc compiler plugins, enabling development of custom code generators. The gofeaturespb package provides Go-specific feature flags for controlling code generation behavior.
import (
"google.golang.org/protobuf/types/pluginpb"
"google.golang.org/protobuf/types/gofeaturespb"
"google.golang.org/protobuf/types/descriptorpb"
"google.golang.org/protobuf/reflect/protoreflect"
)The input message sent by protoc to a plugin via stdin.
// CodeGeneratorRequest is written to the plugin's stdin
type CodeGeneratorRequest struct {
// The .proto files that were explicitly listed on the command-line
// The code generator should generate code only for these files
// Each file's descriptor will be included in proto_file, below
FileToGenerate []string `protobuf:"bytes,1,rep,name=file_to_generate,json=fileToGenerate" json:"file_to_generate,omitempty"`
// The generator parameter passed on the command-line
Parameter *string `protobuf:"bytes,2,opt,name=parameter" json:"parameter,omitempty"`
// FileDescriptorProtos for all files in files_to_generate and everything
// they import. The files will appear in topological order, so each file
// appears before any file that imports it.
//
// Note: the files listed in files_to_generate will include runtime-retention
// options only, but all other files will include source-retention options.
// The source_file_descriptors field below is available in case you need
// source-retention options for files_to_generate.
//
// Type names of fields and extensions in the FileDescriptorProto are always
// fully qualified.
ProtoFile []*descriptorpb.FileDescriptorProto `protobuf:"bytes,15,rep,name=proto_file,json=protoFile" json:"proto_file,omitempty"`
// File descriptors with all options, including source-retention options
// These descriptors are only provided for the files listed in
// files_to_generate
SourceFileDescriptors []*descriptorpb.FileDescriptorProto `protobuf:"bytes,17,rep,name=source_file_descriptors,json=sourceFileDescriptors" json:"source_file_descriptors,omitempty"`
// The version number of protocol compiler
CompilerVersion *Version `protobuf:"bytes,3,opt,name=compiler_version,json=compilerVersion" json:"compiler_version,omitempty"`
// Has unexported fields.
}
func (*CodeGeneratorRequest) ProtoMessage()
func (x *CodeGeneratorRequest) ProtoReflect() protoreflect.Message
func (x *CodeGeneratorRequest) Reset()
func (x *CodeGeneratorRequest) String() string
func (*CodeGeneratorRequest) Descriptor() ([]byte, []int) // Deprecated
func (x *CodeGeneratorRequest) GetFileToGenerate() []string
func (x *CodeGeneratorRequest) GetParameter() string
func (x *CodeGeneratorRequest) GetProtoFile() []*descriptorpb.FileDescriptorProto
func (x *CodeGeneratorRequest) GetSourceFileDescriptors() []*descriptorpb.FileDescriptorProto
func (x *CodeGeneratorRequest) GetCompilerVersion() *VersionThe output message written by a plugin to stdout.
// CodeGeneratorResponse is written to stdout by the plugin
type CodeGeneratorResponse struct {
// Error message. If non-empty, code generation failed
// The plugin process should exit with status code zero even if it reports
// an error in this way.
//
// This should be used to indicate errors in .proto files which prevent the
// code generator from generating correct code. Errors which indicate a
// problem in protoc itself should be reported by writing a message to stderr
// and exiting with a non-zero status code.
Error *string `protobuf:"bytes,1,opt,name=error" json:"error,omitempty"`
// A bitmask of supported features that the code generator supports
// This is a bitwise "or" of values from the Feature enum
SupportedFeatures *uint64 `protobuf:"varint,2,opt,name=supported_features,json=supportedFeatures" json:"supported_features,omitempty"`
// The minimum edition this plugin supports
// This will be treated as an Edition enum value, not the edition number
// Only takes effect for plugins that have FEATURE_SUPPORTS_EDITIONS set
MinimumEdition *int32 `protobuf:"varint,3,opt,name=minimum_edition,json=minimumEdition" json:"minimum_edition,omitempty"`
// The maximum edition this plugin supports
// This will be treated as an Edition enum value, not the edition number
// Only takes effect for plugins that have FEATURE_SUPPORTS_EDITIONS set
MaximumEdition *int32 `protobuf:"varint,4,opt,name=maximum_edition,json=maximumEdition" json:"maximum_edition,omitempty"`
// Generated files
File []*CodeGeneratorResponse_File `protobuf:"bytes,15,rep,name=file" json:"file,omitempty"`
// Has unexported fields.
}
func (*CodeGeneratorResponse) ProtoMessage()
func (x *CodeGeneratorResponse) ProtoReflect() protoreflect.Message
func (x *CodeGeneratorResponse) Reset()
func (x *CodeGeneratorResponse) String() string
func (*CodeGeneratorResponse) Descriptor() ([]byte, []int) // Deprecated
func (x *CodeGeneratorResponse) GetError() string
func (x *CodeGeneratorResponse) GetSupportedFeatures() uint64
func (x *CodeGeneratorResponse) GetMinimumEdition() int32
func (x *CodeGeneratorResponse) GetMaximumEdition() int32
func (x *CodeGeneratorResponse) GetFile() []*CodeGeneratorResponse_FileRepresents a single generated file in the response.
// CodeGeneratorResponse_File represents a generated file
type CodeGeneratorResponse_File struct {
// The file name, relative to the output directory
// The name must not contain "." or ".." components and must be relative
// "/" must be used as the path separator, not "\"
//
// If the name is omitted, the content will be appended to the previous file
// This allows the generator to break large files into small chunks
Name *string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"`
// If non-empty, indicates that the named file should already exist, and the
// content here is to be inserted into that file at a defined insertion point
// This feature allows a code generator to extend the output produced by
// another code generator
//
// The original generator may provide insertion points by placing special
// annotations in the file that look like:
// @@protoc_insertion_point(NAME)
//
// Code inserted at this point will be placed immediately above the line
// containing the insertion point
InsertionPoint *string `protobuf:"bytes,2,opt,name=insertion_point,json=insertionPoint" json:"insertion_point,omitempty"`
// The file contents
Content *string `protobuf:"bytes,15,opt,name=content" json:"content,omitempty"`
// Information describing the file content being inserted
// If an insertion point is used, this information will be appropriately
// offset and inserted into the code generation metadata for the generated
// file to which the file is being inserted
GeneratedCodeInfo *descriptorpb.GeneratedCodeInfo `protobuf:"bytes,16,opt,name=generated_code_info,json=generatedCodeInfo" json:"generated_code_info,omitempty"`
// Has unexported fields.
}
func (*CodeGeneratorResponse_File) ProtoMessage()
func (x *CodeGeneratorResponse_File) ProtoReflect() protoreflect.Message
func (x *CodeGeneratorResponse_File) Reset()
func (x *CodeGeneratorResponse_File) String() string
func (x *CodeGeneratorResponse_File) GetName() string
func (x *CodeGeneratorResponse_File) GetInsertionPoint() string
func (x *CodeGeneratorResponse_File) GetContent() string
func (x *CodeGeneratorResponse_File) GetGeneratedCodeInfo() *descriptorpb.GeneratedCodeInfoFeature flags that plugins can report support for.
// CodeGeneratorResponse_Feature enumerates plugin features
type CodeGeneratorResponse_Feature int32
const (
CodeGeneratorResponse_FEATURE_NONE CodeGeneratorResponse_Feature = 0
CodeGeneratorResponse_FEATURE_PROTO3_OPTIONAL CodeGeneratorResponse_Feature = 1
CodeGeneratorResponse_FEATURE_SUPPORTS_EDITIONS CodeGeneratorResponse_Feature = 2
)
func (CodeGeneratorResponse_Feature) Descriptor() protoreflect.EnumDescriptor
func (x CodeGeneratorResponse_Feature) Enum() *CodeGeneratorResponse_Feature
func (CodeGeneratorResponse_Feature) EnumDescriptor() ([]byte, []int) // Deprecated
func (x CodeGeneratorResponse_Feature) Number() protoreflect.EnumNumber
func (x CodeGeneratorResponse_Feature) String() string
func (CodeGeneratorResponse_Feature) Type() protoreflect.EnumType
func (x *CodeGeneratorResponse_Feature) UnmarshalJSON(b []byte) error // DeprecatedInformation about the protoc compiler version.
// Version represents the version of protocol compiler
type Version struct {
Major *int32 `protobuf:"varint,1,opt,name=major" json:"major,omitempty"`
Minor *int32 `protobuf:"varint,2,opt,name=minor" json:"minor,omitempty"`
Patch *int32 `protobuf:"varint,3,opt,name=patch" json:"patch,omitempty"`
// A suffix for alpha, beta or rc release, e.g., "alpha-1", "rc2"
Suffix *string `protobuf:"bytes,4,opt,name=suffix" json:"suffix,omitempty"`
// Has unexported fields.
}
func (*Version) ProtoMessage()
func (x *Version) ProtoReflect() protoreflect.Message
func (x *Version) Reset()
func (x *Version) String() string
func (x *Version) GetMajor() int32
func (x *Version) GetMinor() int32
func (x *Version) GetPatch() int32
func (x *Version) GetSuffix() stringUsage example for a plugin:
import (
"io"
"os"
"google.golang.org/protobuf/proto"
"google.golang.org/protobuf/types/pluginpb"
)
func main() {
// Read request from stdin
input, err := io.ReadAll(os.Stdin)
if err != nil {
panic(err)
}
// Parse request
req := &pluginpb.CodeGeneratorRequest{}
if err := proto.Unmarshal(input, req); err != nil {
panic(err)
}
// Generate code
resp := &pluginpb.CodeGeneratorResponse{
SupportedFeatures: proto.Uint64(
uint64(pluginpb.CodeGeneratorResponse_FEATURE_PROTO3_OPTIONAL),
),
}
// Process files to generate
for _, filename := range req.FileToGenerate {
// Find file descriptor
var fd *descriptorpb.FileDescriptorProto
for _, f := range req.ProtoFile {
if f.GetName() == filename {
fd = f
break
}
}
// Generate code for this file
content := generateCode(fd)
resp.File = append(resp.File, &pluginpb.CodeGeneratorResponse_File{
Name: proto.String(filename + ".generated.go"),
Content: proto.String(content),
})
}
// Write response to stdout
output, err := proto.Marshal(resp)
if err != nil {
panic(err)
}
os.Stdout.Write(output)
}Go-specific feature flags that control code generation behavior.
// GoFeatures contains Go-specific feature flags
type GoFeatures struct {
// Whether or not to generate the deprecated UnmarshalJSON method for enums
// Can only be true for proto using the Open Struct api
LegacyUnmarshalJsonEnum *bool `protobuf:"varint,1,opt,name=legacy_unmarshal_json_enum,json=legacyUnmarshalJsonEnum" json:"legacy_unmarshal_json_enum,omitempty"`
// One of OPEN, HYBRID or OPAQUE
ApiLevel *GoFeatures_APILevel `protobuf:"varint,2,opt,name=api_level,json=apiLevel,enum=pb.GoFeatures_APILevel" json:"api_level,omitempty"`
// How to handle enum prefix stripping
StripEnumPrefix *GoFeatures_StripEnumPrefix `protobuf:"varint,3,opt,name=strip_enum_prefix,json=stripEnumPrefix,enum=pb.GoFeatures_StripEnumPrefix" json:"strip_enum_prefix,omitempty"`
// Has unexported fields.
}
func (*GoFeatures) ProtoMessage()
func (x *GoFeatures) ProtoReflect() protoreflect.Message
func (x *GoFeatures) Reset()
func (x *GoFeatures) String() string
func (*GoFeatures) Descriptor() ([]byte, []int) // Deprecated
func (x *GoFeatures) GetLegacyUnmarshalJsonEnum() bool
func (x *GoFeatures) GetApiLevel() GoFeatures_APILevel
func (x *GoFeatures) GetStripEnumPrefix() GoFeatures_StripEnumPrefixControls which Go API level to use for generated code.
// GoFeatures_APILevel specifies the API level for generated Go code
type GoFeatures_APILevel int32
const (
// API_LEVEL_UNSPECIFIED results in selecting the OPEN API,
// but needs to be a separate value to distinguish between
// an explicitly set api level or a missing api level
GoFeatures_API_LEVEL_UNSPECIFIED GoFeatures_APILevel = 0
GoFeatures_API_OPEN GoFeatures_APILevel = 1
GoFeatures_API_HYBRID GoFeatures_APILevel = 2
GoFeatures_API_OPAQUE GoFeatures_APILevel = 3
)
func (GoFeatures_APILevel) Descriptor() protoreflect.EnumDescriptor
func (x GoFeatures_APILevel) Enum() *GoFeatures_APILevel
func (GoFeatures_APILevel) EnumDescriptor() ([]byte, []int) // Deprecated
func (x GoFeatures_APILevel) Number() protoreflect.EnumNumber
func (x GoFeatures_APILevel) String() string
func (GoFeatures_APILevel) Type() protoreflect.EnumTypeControls how enum value names are generated.
// GoFeatures_StripEnumPrefix controls enum prefix stripping
type GoFeatures_StripEnumPrefix int32
const (
GoFeatures_STRIP_ENUM_PREFIX_UNSPECIFIED GoFeatures_StripEnumPrefix = 0
GoFeatures_STRIP_ENUM_PREFIX_KEEP GoFeatures_StripEnumPrefix = 1
GoFeatures_STRIP_ENUM_PREFIX_GENERATE_BOTH GoFeatures_StripEnumPrefix = 2
GoFeatures_STRIP_ENUM_PREFIX_STRIP GoFeatures_StripEnumPrefix = 3
)
func (GoFeatures_StripEnumPrefix) Descriptor() protoreflect.EnumDescriptor
func (x GoFeatures_StripEnumPrefix) Enum() *GoFeatures_StripEnumPrefix
func (GoFeatures_StripEnumPrefix) EnumDescriptor() ([]byte, []int) // Deprecated
func (x GoFeatures_StripEnumPrefix) Number() protoreflect.EnumNumber
func (x GoFeatures_StripEnumPrefix) String() string
func (GoFeatures_StripEnumPrefix) Type() protoreflect.EnumTypeExtension field for FeatureSet to specify Go features.
// Extension fields to descriptorpb.FeatureSet
var (
// optional pb.GoFeatures go = 1002;
E_Go = &file_google_protobuf_go_features_proto_extTypes[0]
)Mapping between enum names and values for code generator features.
var (
CodeGeneratorResponse_Feature_name = map[int32]string{
0: "FEATURE_NONE",
1: "FEATURE_PROTO3_OPTIONAL",
2: "FEATURE_SUPPORTS_EDITIONS",
}
CodeGeneratorResponse_Feature_value = map[string]int32{
"FEATURE_NONE": 0,
"FEATURE_PROTO3_OPTIONAL": 1,
"FEATURE_SUPPORTS_EDITIONS": 2,
}
)
var (
GoFeatures_APILevel_name = map[int32]string{
0: "API_LEVEL_UNSPECIFIED",
1: "API_OPEN",
2: "API_HYBRID",
3: "API_OPAQUE",
}
GoFeatures_APILevel_value = map[string]int32{
"API_LEVEL_UNSPECIFIED": 0,
"API_OPEN": 1,
"API_HYBRID": 2,
"API_OPAQUE": 3,
}
)
var (
GoFeatures_StripEnumPrefix_name = map[int32]string{
0: "STRIP_ENUM_PREFIX_UNSPECIFIED",
1: "STRIP_ENUM_PREFIX_KEEP",
2: "STRIP_ENUM_PREFIX_GENERATE_BOTH",
3: "STRIP_ENUM_PREFIX_STRIP",
}
GoFeatures_StripEnumPrefix_value = map[string]int32{
"STRIP_ENUM_PREFIX_UNSPECIFIED": 0,
"STRIP_ENUM_PREFIX_KEEP": 1,
"STRIP_ENUM_PREFIX_GENERATE_BOTH": 2,
"STRIP_ENUM_PREFIX_STRIP": 3,
}
)// File descriptor for plugin proto
var File_google_protobuf_compiler_plugin_proto protoreflect.FileDescriptor
// File descriptor for go features proto
var File_google_protobuf_go_features_proto protoreflect.FileDescriptorThese types define the complete protocol for building protoc plugins that generate code from protocol buffer definitions. The plugin protocol is language-agnostic, allowing plugins to be written in any language that can read from stdin and write to stdout.