フィールド番号の基本
Protocol Buffers の .proto
ファイルの型定義では、各フィールドの末尾に フィールド番号
を割り当てておく必要があります。
=
記号が使われていますが、そのフィールドに値を代入しているわけではないので注意してください。
Protocol Buffers は、メッセージ送信用にデータをシリアライズ(バイナリ化)するとき、フィールド名の代わりにこのフィールド番号を使用します。
これにより、Protocol Buffers は効率的なデータ転送を実現しています。
フィールド番号は 1 以上の整数(最大値は 229-1 = 536,870,911)で、メッセージの定義内(同じ階層)で一意になっている必要があります。
必ずしも 1、2、3 のように連番で割り当てる必要はなく、ほぼ任意の数値を割り当てることができますが、19000 ~ 19999 の値は使えません。
これらは、Protocol Buffers ライブラリが内部実装用に予約している値です。
これらの不正な値を使用していると、protoc
コマンドなどでコンパイルしようとしたときにエラーになります。
データをシリアライズするとき、フィールド番号 1~15 の数値は、わずか 1 バイトのデータに変換されるため、頻繁に使用するフィールドには 1~15 のフィールド番号を割り当てておくと効率的な通信を行えます。 とはいえ、フィールド番号が 16~2047 であっても、2 バイトのデータで表現できるので、シビアな通信速度が求められている環境でなければそれほど気にする必要はないでしょう。
reserved と deprecated
reserved
一度割り当てたフィールド番号は、将来にわたって変更してはいけません。
なぜなら、過去のバージョンの .proto
を使って実装されたアプリケーションは、古い .proto
で割り当てられたフィールド番号で通信しようとするためです。
同じフィールド番号で異なるデータが送られてきたら、アプリケーションはうまく動作しなくなってしまいます。
.proto
を更新して非推奨になったフィールドを削除するときは、フィールド番号やフィールド名を使いまわしてしまわないように、reserved
キーワードを使って次のように定義しておきます。
この例では、2
、5~10
、40~最大値
のフィールド番号の使用と、FOO_AAA
と FOO_BBB
というフィールド名(この例の場合は列挙値)の使用を制限しています。
1 つの reserved
行では、数値のリストあるいは文字列のリストのどちらかしか定義できないので、上記のように 2 行に分けて定義する必要があります。
reserved
キーワードは、その名前が示しているように、将来的にこれらのフィールド番号を使うために「予約」しておく、という用途でも使用できます。
deprecated
フィールドオプション (field option) の機能を使って、既存のフィールドに deprecated
(非推奨)の印を付けることができます。
int32 old_field = 6 [deprecated = true];
このオプションが付いたフィールドを、Java や Kotlin のコードとして出力すると、@Deprecated
アノテーションとして出力されますが、言語によっては何も効果がないことがあります。
ただ、ドキュメンテーションコメントとしては役に立つので活用するとよいです。