先日protoc-gen-gohttpの依存パッケージをしようと思って色々触っていたら以下のようなWARNINGが出てきた。

2020/05/24 11:36:51 WARNING: Deprecated use of 'go_package' option without a full import path in "greeter.proto", please specify:
        option go_package = ".;main";
A future release of protoc-gen-go will require the import path be specified.
See https://developers.google.com/protocol-buffers/docs/reference/go-generated#package for more information.

以下のファイルのように go_package のオプションにGoのimport pathを記述しなかったことが問題だった。

syntax = "proto3";

package helloworld;

option go_package = "main";

service Greeter {
  rpc SayHello(HelloRequest) returns (HelloReply);
}

message HelloRequest {
  string name = 1;
}

message HelloReply {
  string message = 1;
}

一応WARNINGには「go_package = ".;main"; みたいに指定してください」と書いてあり、そのとおりに指定すると問題なく生成はできた。

しかし、その下にあるLinkには ; に関する情報が記載されていない(執筆時点)。

また、上記のように ; で区切った文字列を go_package に指定するとprotoc-gen-gohttpでエラーを吐いてしまった。

実装を反映させる都合上、 protoc-gen-go; がどのような扱いになっているのかを調べる必要があったため、せっかくなので調べた結果をまとめておこうと思う。

この記事で挙動を確認した protoc-gen-go のバージョンはv1.4.2、protocのバージョンはv3.12.0。

結論 Link to heading

  • go_package にimport pathを指定した場合、/ で区切った最後の文字列がGoのpackage名に使われる
    • ex.) github.com/nametake/protoc-gen-gohttp/examples -> package examples
  • go_package; が含まれていた場合、 ; より後の文字がGoのpackage名に使われる
    • ex.) github.com/nametake/protoc-gen-gohttp/examples;main -> package main

実装の該当箇所はこちら

このIssue がProposalで実装自体は2年ほど前にされていた。

ただ、このWARNING自体もこのIssueで議論されている通り、第三者に配布したときの挙動として適切かどうかはまだ議論されている段階のようだった。

とはいえ、実装と仕組み自体はわかったのでprotoc-gen-gohttpのパッケージ名生成部分では ; で区切られたパターンは対応した。

一応自分でも追いかけてはいきますが、Protocol Buffersはまだまだ開発が活発なため追いつけないことも多々あると思うので、もしprotoc-gen-gohttpで動かない挙動があった場合はIssueを立てていただけると助かります。