コーヒー飲みながら仕事したい

仕事で使う技術的なことの備忘録とか

protobuf-c で今度こそ遊んでみる(proto2とproto3の違い編)

あらすじ

もともと軽い気持ちで Protocol Buffers のC言語版を遊んでみようと思っていたら、意図せず Docker を巻き込んだ一大イベントに発展した。

やっとこさ準備ができたので、楽しく遊ぼうとしていた。が、しかし・・・

protocol buffers のバージョン2とバージョン3は互換性がない件について

protobuf-c の wikiを読みながらチュートリアルに取り組んでみた。

amessage.proto という名前で以下の内容のファイルを作る。

message AMessage {
  required int32 a=1; 
  optional int32 b=2;
}

で、さっそく protobuf-c を実行させて AMessage 構造体のシリアライザーとデシリアライザーを作ろうと以下を実行した。

root@e834aae66aee:/work/ProtocolBuffersTest# protoc-c --c_out=. amessage.proto
[libprotobuf WARNING google/protobuf/compiler/parser.cc:546] No syntax specified for the proto file: amessage.proto. Please use 'syntax = "proto2";' or 'syntax = "proto3";' to specify a syntax version. (Defaulted to proto2 syntax.)

なんか警告が出る!
直訳すると、「 proto2 と proto3 のどっちで動作させるかちゃんと明記('syntax = "proto2";' か 'syntax = "proto3";')してくれ。じゃないと proto2 で動作するよ。」って感じだと思う。
なんとなくだけど、新しいほうがいいと思うので、amessage.proto を以下のように変更してみた。

syntax = "proto3";

message AMessage {
  required int32 a=1; 
  optional int32 b=2;
}

で、実行するとエラーになる・・・

root@e834aae66aee:/work/ProtocolBuffersTest# protoc-c --c_out=. amessage.proto
amessage.proto:5:12: Explicit 'optional' labels are disallowed in the Proto3 syntax. To define 'optional' fields in Proto3, simply remove the 'optional' label, as fields are 'optional' by default.

調べてみると、どうやら proto2 と proto3 で protoファイルの記法がかわったとのこと。
具体的には、proto3 では requiredoptional が削除されたらしい。
なんで?って感じだけど、以下の stackoverflow に質問と回答があったので、一応載せとく。よく読んでないけど、拡張性を考慮するとそれらを削除するという流れになったそうだ。

stackoverflow.com

protocol buffers バージョン3を選択する

ということで、再々度 amessage.proto を変更する。

syntax = "proto3";

message AMessage {
  int32 a=1; 
  int32 b=2;
}

これで、 protoc-c --c_out=. amessage.proto が正常に動作して、以下のファイルが出力された。

  • amessage.pb-c.c
  • amessage.pb-c.h

引き続き、wiki の Examples に従ってチュートリアルしてみるけど、まんま wiki の通りになるので割愛します。