TL;DR

Protocol Buffers のスキーマからコードを生成する Buf CLI のコマンド。生成には buf.gen.yaml が必要である。

仕組み

buf.gen.yaml

コード生成のための設定ファイルで、buf.yaml と同じくワークスペースのルートに置く。出力する言語、使うプラグイン、protoc に渡していたオプションなどを指定できる。

version: v2
plugins:
  - protoc_builtin: cpp
    out: gen/cpp

プラグインはローカルにインストールして使う(Local plugins)こともできるし、インストールせずに使う(Remote plugins)こともできる。Remote plugins の実体は BSR で管理されている。

Managed mode

proto ファイルには、生成するコードのパッケージ名など、言語ごとのオプションがある。これらは proto ファイルに書くので、クライアント側のコード生成のためのオプションまで、スキーマの作成者が書くことになる。

option java_multiple_files = true;
option java_outer_classname = "WeatherProto";
option java_package = "com.acme.weather.v1";

Managed mode を使うと、こうしたオプションを proto ファイルから取り除き、buf.gen.yaml 側で指定できる。スキーマの設計者は API の設計に集中できる。有効にするには managed.enabled を true にし、値は managed.override で指定する。

version: v2
managed:
  enabled: true
  override:
    - file_option: go_package_prefix
      value: github.com/acme/weather/gen/go

例

Remote plugins で Go のコードを生成する。go_package を指定していない proto ファイルで実行すると、Go のインポートパスが決まらずに失敗する。

Failure: plugin "buf.build/protocolbuffers/go:v1.34.2" exited with non-zero status 1: protoc-gen-go: unable to determine Go import path for "radish/weather/v1/weather.proto"

proto ファイルに go_package を足す代わりに、Managed mode で指定すれば成功する。opt: paths=source_relative は、生成したファイルを proto ファイルからの相対パスに置くためのオプションである。gRPC のサーバのコードも生成するなら、buf.build/grpc/go を足す。

version: v2
managed:
  enabled: true
  override:
    - file_option: go_package_prefix
      value: github.com/acme/weather/gen
plugins:
  - remote: buf.build/protocolbuffers/go
    out: gen/go
    opt: paths=source_relative
  - remote: buf.build/grpc/go
    out: gen/go
    opt: paths=source_relative
$ buf generate proto

生成したコードで gRPC サーバを立てれば、buf curl や gRPCurl で動作を確かめられる。

関連

出典