Skip to content

Generators

protogen runs four in-process generators over the compiled descriptors. By default all of them run; select a subset with --generators (or generators: in the config file).

NameOutputSource
messages*.pb.goprotoc-gen-go's internal_gengo, imported directly
grpc*_grpc.pb.goown protogen generator (unary + all streaming)
gateway*.pb.gw.goown protogen generator + vendored httprule
openapiv3openapi.yamlgoogle/gnostic, then enriched
sh
# only messages + gRPC, no gateway or OpenAPI
protogenall --proto_path=proto --generators=messages,grpc --out=gen proto

messages

*.pb.go is produced by the very generator protoc-gen-go uses. The trick is that its package path element is internal_gengo (not internal), so Go's internal-import rule doesn't block it — protogen imports it and calls GenerateFile directly. Output is identical to running protoc --go_out.

grpc

*_grpc.pb.go contains, per service:

  • a <Service>Client interface and implementation,
  • a <Service>Server interface, Unimplemented<Service>Server, and Register<Service>Server,
  • unary handlers and streaming handlers,
  • the <Service>_ServiceDesc.

All four RPC kinds are generated using grpc-go's generics-based stream types (grpc.ServerStreamingClient[T], grpc.BidiStreamingServer[Req, Resp], …), matching protoc-gen-go-grpc v1.6+. See Streaming.

gateway

*.pb.gw.go is a grpc-gateway reverse proxy for every method that has a google.api.http binding:

  • Register<Service>HandlerServer — calls your server in-process,
  • Register<Service>Handler / Register<Service>HandlerFromEndpoint — forward over a *grpc.ClientConn,
  • request decoders for path params, */field/empty bodies, and query parameters.

Path templates are compiled by internal/gateway/httprule — the one grpc-gateway package that lives in internal/ upstream, vendored here (it depends only on the public utilities package). Unary and server-streaming methods are supported; client/bidi streaming can't be expressed over REST and are skipped with a note. See Streaming.

openapiv3

openapi.yaml is generated by gnostic (honoring google.api.http) and then post-processed by internal/openapival to add everything gnostic doesn't know about — protovalidate constraints, enum value names, field_behavior, and a 400 response. See Validation and OpenAPI.

Document metadata comes from --openapi-title / --openapi-version:

sh
protogenall --proto_path=proto --openapi-title="My API" --openapi-version=2.1.0 --out=gen proto

Descriptor set

Independently of the generators, --descriptor-set-out writes a FileDescriptorSet (the same "image" format protoc --descriptor_set_out and buf produce):

sh
protogenall --proto_path=proto --descriptor-set-out=api.binpb --out=gen proto

Extending

Each generator implements a small interface:

go
type Generator interface {
	Name() string
	Generate(gen *protogen.Plugin) error
}

New generators implement it and are appended in cmd/protogenall/main.go.

Released under the MIT License.