protoc-gen-template
A protoc
plugin for generic code generation, backed by golang's
templates.
protoc --template_out=template_dir:output_dir example.proto
The template_out
argument consists of two configuration values
delimited by a colon. The first value is a directory or path containing
templates to be evaluated and the second value is the output directory.
If the template value refers to a directory its contents (files and directories) will be written to the output directory. If the template value refers to a file, the file will be written to the output directory.
Files with the suffix .associated.tmpl
will be parsed as "associated"
templates. These templates will be present in the template execution scope but
will not generate output files. For instance, if your template directory
contains a file named foo/bar.associated.tmpl
you can include its output in
another template with {{ template "foo/bar" }}
- there will be no file
named foo.associated
in the output.
Files named with the suffix .tmpl
will be parsed and evaluated using
golang's text/template
package, and the output will be written to a file
with the .tmpl
suffix stripped.
Templates are executed with dot set to a TemplateData
describing the
plugin.CodeGeneratorRequest
generated by protoc
.
protoc-gen-template
provides some additional parsing of the source structure
to make template writing easier:
- Associates
SourceCodeInfo
with the described data - Options defined in
src/template/meta.proto
are parsed and associated with the data they describe - Mappings from type's canonical names to their definitions are provided.
// docs.md.tpl
# Protobufs
{{ range .Files }}
## File {{ .Name }}
File {{ .Name }} contains the following services:
{{ range $key, $service := .Service }}
* {{ $service }}
{{ end }}
File {{ .Name }} contains the following message types:
{{ range $key, $messageType := .MessageType }}
* {{ $messageType }}
{{ end }}
{{ end }}
protoc --template_out=template.md.tpl:. data/testdata/test.proto
Will generate something like:
// docs.md
# Protobufs
## File test.proto
File test.proto contains the following services:
* Discovery
File test.proto contains the following message types:
* GetImapConfigRequest
* ImapDocumentation
* ImapConfig
Install
go get -u github.com/kerinin/protoc-gen-template
Build
A compile step is necessary for the plugin to handle the annotations defined
in meta/extensions.proto
. After making changes to this protobuf you'll need
to recompile meta.extensions.pb.go
for the changes to be recognized:
docker-compose build compile
docker-compose run compile
Testing
For quickly checking output
go build && cat data/testdata/dump.pb | ./protoc-gen-template -template data/testdata/template.tmpl | go run decode/main.go
To update testdata with the contents of testdata/*.proto
docker-compose run app bash -c 'protoc -I=/root/include -I=. --dump_out=protoc-gen-template/data/testdata protoc-gen-template/data/testdata/*.proto'