Protocol Buffers Language Guideのprotoファイルタイプフォーマット解析[キー翻訳]



2009-7-21 by陳相礼
1.メッセージのタイプを定義します.
message SearchRequest {
  required string query = 1;
  optional int32 page_number = 2;
  optional int32 result_per_page = 3;
}
A.特定ドメインのタイプ:2つの整数変数page_numberとresult_per_Page、stringタイプの変数query.列挙や他のmessageタイプなどの他のタイプとして定義することもできます.
B.ラベルを割り当てる:このラベルは唯一で、その範囲は1~229-1にすることができ、もちろん19000~1999はprotocol buffer内部で使用できない.このうち1~15は、頻繁に使用されるメッセージ要素として保持される.
C.フィールドルールの指定:指定されたメッセージフィールドのルールは以下の通りである:a.required構造の良いmessageにはこのようなフィールドが必要である.b.optional構造の良いmessageには、ゼロまたはそのようなフィールドがあります.c.repeatedこのフィールドは任意の回数(ゼロ回を含む)繰り返すことができる.説明:repeatedの後に[packed=true]を付けると、より効率的な符号化が得られます.例えば、repeated int 32 samples=4[package=true];
D.1つのファイルに複数のメッセージを追加し、コンパイルしてcppコードを生成すると、複数のクラスに対応します.
E.Protoコメントの追加はcppと同様に、二重スラッシュでOKです.
F.protocol bufferコンパイラを実行し、指定したオプションに従って特定の言語のコードを生成し、生成したコードにはprotoファイルに宣言された変数の設定、取得、シーケンス化メッセージから出力ストリームへ、入力ストリームからあなたのメッセージを分解する操作が含まれています.詳細は、対応言語のprotocol buffer APIを参照してください.
2、スカラー値タイプ
スカラー・メッセージ・フィールドには、自動生成されたクラスのタイプに対応する表のいくつかがあります.
.proto Type
Notes
C++ Type
Java Type
double
 
double
double
float
 
float
float
int32
Uses variable-length encoding. Inefficient for encoding negative numbers – if your field is likely to have negative values, use sint32 instead.
int32
int
int64
Uses variable-length encoding. Inefficient for encoding negative numbers – if your field is likely to have negative values, use sint64 instead.
int64
long
uint32
Uses variable-length encoding.
uint32
int[1]
uint64
変長符号化の使用
uint64
long[1]
sint32
Uses variable-length encoding. Signed int value. These more efficiently encode negative numbers than regular int32s.
int32
int
sint64
Uses variable-length encoding. Signed int value. These more efficiently encode negative numbers than regular int64s.
int64
long
fixed32
Always four bytes. More efficient than uint32 if values are often greater than 228.
uint32
int[1]
fixed64
Always eight bytes. More efficient than uint64 if values are often greater than 256.
uint64
long[1]
sfixed32
Always four bytes.
int32
int
sfixed64
Always eight bytes.
int64
long
bool
 
bool
boolean
string
A string must always contain UTF-8 encoded or 7-bit ASCII text.
string
String
bytes
May contain any arbitrary sequence of bytes.
string
ByteString
 
3、Optionalフィールドのデフォルト値
設定方法:optional int 32 result_per_page = 3 [default = 10];
指定されていない場合:stringのデフォルト値は空白列、boolはfalse、数値タイプはゼロ、列挙タイプのデフォルト値は列挙定義リストの最初の値です.
4、列挙
message SearchRequest {
  required string query = 1;
  optional int32 page_number = 2;
  optional int32 result_per_page = 3 [default = 10];
  enum Corpus {
    UNIVERSAL = 0;
    WEB = 1;
    IMAGES = 2;
    LOCAL = 3;
    NEWS = 4;
    PRODUCTS = 5;
    VIDEO = 6;
  }
  optional Corpus corpus = 4 [default = UNIVERSAL];
}

外部メッセージは、MessageType.EnumTypeで取得できます.
5、他のメッセージタイプを使う
Messageは、次のようなタイプとして使用することもできます.
message SearchResponse {
  repeated Result result = 1;
}
 
message Result {
  required string url = 1;
  optional string title = 2;
  repeated string snippets = 3;
}
もちろん、1つのmessageは異なるファイルで定義できます.使用するときはimportを使用して追加できます.import「myproject/other_protos.proto」.
6、ネストタイプ
message SearchResponse {
  message Result {
    required string url = 1;
    optional string title = 2;
    repeated string snippets = 3;
  }
  repeated Result result = 1;
}
上記の例では、resultはSearchResponseで定義されています.外部のmessageでresultを呼び出す場合は、:Parent.Type:
message SomeOtherMessage {
  optional SearchResponse.Result result = 1;
}
もちろん、メッセージの任意の深さをネストすることもできます.
message Outer {                  // Level 0
  message MiddleAA {  // Level 1
    message Inner {   // Level 2
      required int64 ival = 1;
      optional bool  booly = 2;
    }
  }
  message MiddleBB = {  // Level 1
    message Inner = {   // Level 2
      required int32 ival = 1;
      optional bool  booly = 2;
    }
  }
}

グループ化:新しいmessageタイプを作成する場合、この特徴は一般的に使用に賛成されず、ネストされたmessageタイプで置き換えられることが多い.
message SearchResponse {
  repeated group Result = 1 {
    required string url = 2;
    optional string title = 3;
    repeated string snippets = 4;
  }
}
括弧で囲むだけで、句読点に注意!これは上の例と一致している.
7、メッセージタイプを更新する
既存のmessageタイプは、以前定義したフォーマットを変更することなく更新されます.次の規則に従います.
A、既存フィールドの数値ラベルは変更しないでください.
B、追加した新しいフィールドはoptionalまたはrepeatedタイプである必要があります.
C、必須でないフィールドは削除できますが、ラベル数は更新したmessageタイプでは使用されません.(より良い方法はフィールドの名前を変更することです.OBSOLETE_接頭辞を加えることができます.そうすれば、将来protoファイルを使用するユーザーは意外にもこの数字を使用できません.)
D、必須でないフィールドは、タイプと数字が一定に保たれながら、拡張に変換できます.
E、int 32、uint 32、int 64、uint 64、boolは互換性があります.
F,sint 32,sint 64は互換性があるが,他の整数数とは互換性がない.
G、string、bytesは互いに互換性がある.
H、埋め込みmessageとbytes互換
I、fixed 32およびsfixed 32、fixed 64およびsfixed 64互換性
8、拡張
例:
message Foo {
  // ...
  extensions 100 to 199;
}

フィールド番号[100,199]は拡張のために使用され、他のユーザは、以下のように、これらのタグ番号を使用して新しいフィールドを追加することができる.
extend Foo {
  optional int32 bar = 126;
}
これにより、Fooにint 32のタイプの新しいフィールドbarが追加され、生成されたファイルをコンパイルして拡張フィールドにアクセスする方法が少し異なります.
Foo foo; 
foo.SetExtension(bar, 15);
その他の処理方法としては、、HasExtension()ClearExtension()GetExtension()MutableExtension()、、andAddExtension()がある.
説明:拡張フィールドは、messageタイプを含む任意のフィールドタイプであってもよい.
拡張ネスト:
message Baz {
  extend Foo {
    optional int32 bar = 126;
  }
  ...
}
C++アクセス拡張方法:
Foo foo;
foo.SetExtension(Baz::bar, 15);
唯一違うのはbarの前にBazを追加したことです.簡単です.
ネストされた拡張ではないことを提唱します.
拡張ラベル数の選択:
message Foo {
  extensions 1000 to max;
} max=229-1、または536870911.ただし19000~1999は含まれておらず、具体的な理由は上記を参照.
9、バッグ
例:
package foo.bar;
message Open { ... }
別のメッセージでこのパッケージを使用する方法:
message Foo {
  ...
  required foo.bar.Open open = 1;
  ...
}
生成されたC++コードにpackageがネーミングスペースとして宣言されます.Openはネーミングスペースfoo::barにあります.
10、サービスの定義
例を次に示します.
service SearchService {
  rpc Search (SearchRequest) returns (SearchResponse);
}
 
11、オプション
 ...
12、あなたのクラスを生み出す
ソースをダウンロードし、ソース生成コンパイラを構成してコンパイルします.コンパイルパラメータ:
protoc --proto_path=IMPORT_PATH --cpp_out=DST_DIR --java_out=DST_DIR --python_out=DST_DIR path/to/file.proto
説明:
a.       LMPORT_PATHはあなたを指定したのです.protoファイルが座っているディレクトリ.
b.以下の出力を提供する:
--cpp_DSTでアウトDIRはC++コードを生成する
--java_DSTでアウトDIR生成Javaコード
--python_DSTでアウトDIRはpythonコードを生成する
c.入力として1つ以上の.protoファイルを指定する必要があります.もちろん複数です.protoファイルは同時にコンパイルを指定できます.