Protocol Buffersの定義をMarkdownで出力するためのカスタムテンプレートを作った

# モチベーション

現在のプロジェクトではProtocol Buffersの定義ファイルは画面が必要としている関心事ごとに
サービスが分割されており1サービスが1つのpackageに紐づくよう設計されています。
そのためProtocol Buffersは以下のような複数ファイル構成になっています。

```config
src
└ proto
　 └ app
　 　 ├ user
　 　 │ └ user.proto
　 　 ├ comment
　 　 │ └ comment.proto
　 　 └ search
　 　 　 └ search.proto
```

リクエストパラメータのvalidationもProtocol Buffers上で定義されており、現在[mwitkow/go-proto-validators](https://github.com/mwitkow/go-proto-validators) と [envoyproxy/protoc-gen-validate](https://github.com/envoyproxy/protoc-gen-validate) が使用されています。

このvalidationの閾値をProtocol Buffersを設計しているバックエンダー以外へ連携する際に
そのままprotoファイルを見せても分かりにくいので、1つのMarkdownにまとめてドキュメント化しようというのが今回やりたかったことです。

Protocol Buffersをドキュメント化する事自体は[pseudomuto/protoc-gen-doc](https://github.com/pseudomuto/protoc-gen-doc) というlibraryで既に提供されているためこちらを使用します。
しかし、デフォルトの状態で出力されるMarkdownファイルはファイル毎に分割されてしまう上にそもそもvalidationの設定が出力されないためカスタムテンプレートを用意することにしました。

# 作成したもの

以下のテンプレートを作成しました。
https://gist.github.com/tomtwinkle/074bfc9cd4db53b58bb4ff368157f3ed

使い方としては

```config
src
├ proto
│ └ app
│ 　 ├ user
│ 　 │ └ user.proto
│ 　 ├ comment
│ 　 │ └ comment.proto
│ 　 └ search
│ 　 　 └ search.proto
└ custom_markdown.tmpl # <--- custom template
```

のように配置し `--doc_out` にドキュメントの出力先、`--doc_opt` にテンプレートの設定とファイル名を追加して `protoc` を実行します。

```bash
cd src
protoc -I . -I <validatorのパス> --proto_path=proto --doc_out=../docs --doc_opt=custom_markdown.tmpl,doc.md ./proto/app/**/*.proto
```

```config
src
├ proto
│ └ app
│ 　 ├ user
│ 　 │ └ user.proto
│ 　 ├ comment
│ 　 │ └ comment.proto
│ 　 └ search
│ 　 　 └ search.proto
├ custom_markdown.tmpl # <--- custom template
docs
└ doc.md # <--- generate markdown document
```

コードジェネレートとセットで行うことも出来ます。
例えばgolangとgrpc-webのコードジェネレートとセットで行う場合は以下のようになります。

```bash
protoc -I . -I <validatorのパス> --proto_path=proto --doc_out=../docs --doc_opt=custom_markdown.tmpl,doc.md --proto_path=proto --go_out="plugins=grpc:../go" --validate_out="lang=go:../go" --grpc-web_out=import_style=commonjs+dts,mode=grpcwebtext:../web --js_out=import_style=commonjs:../web ./proto/app/**/*.proto
```

# おまけ：validatorのパスを書きたくない

Protocol Buffersの定義をMarkdownで出力するネタとは全然関係ないですが
validatorをProtocol Buffersで定義する場合どうしてもvalidator自身のproto fileのパスをprotocに読ませる必要があるため

```bash
GO111MODULE=off go get github.com/envoyproxy/protoc-gen-validate
protoc -I $GOPATH/src/github.com/envoyproxy/protoc-gen-validate
```

みたいな手順を開発環境の構築手順に加えてあげる必要が出てきてしまいます。
`go get`してくるpackageは開発者毎に異なる可能性があり環境差分が生まれる原因ともなります。

解決するためにはProtocol Buffersのソース内にvalidatorのpackage名のディレクトリを掘りvalidator自体のprotoファイルをライセンスファイルとセットで置いてあげるのが良さそうです。(Apache License 2.0なので)
protoファイルを取り込む場合はそれぞれのvalidatorのライセンスをよく確認してください。

```config
src
├ proto
│ ├ app
│ │ ├ user
│ │ │ └ user.proto
│ │ ├ comment
│ │ │ └ comment.proto
│ │ └ search
│ │ 　 └ search.proto
│ └ github.com # <------ validator proto files
│ 　 ├ envoyproxy
│ 　 │ └ protoc-gen-validate
│ 　 │ 　 ├ validate
│ 　 │ 　 │ └ validate.proto
│ 　 │ 　 ├ LICENSE
│ 　 │ 　 └ NOTICE
│ 　 └ mwitkow
│ 　 　 └ go-proto-validators
│ 　 　 　 ├ validator.proto
│ 　 　 　 └ LICENSE.txt
├ custom_markdown.tmpl
docs
├ doc.md
go
web
```

使うvalidatorが `envoyproxy/protoc-gen-validate` だけで良いなら `mwitkow/go-proto-validators` のディレクトリは不要です。逆もまた然り。

validatorを使用したいprotoファイル内では以下のようにimportします。

```protobuf
import "github.com/envoyproxy/protoc-gen-validate/validate/validate.proto";
```

package名と同じディレクトリを作成することにより

```bash:Before
protoc -I . -I <validatorのパス> <build options> ./proto/app/**/*.proto
```

と参照パスをオプションで指定する必要があったものが

```bash:After
protoc <build options> ./proto/app/**/*.proto
```

だけでbuild出来るようになります。