HINWEIS: Diese Website wurde eingestellt. Die Website wird nach dem 31. Januar 2023 eingestellt. Der Traffic wird auf die neue Website unter https://Protop.dev weitergeleitet. In der Zwischenzeit werden nur Änderungen an aufgeführt.

Protocol Buffers Version 2 – Sprachspezifikation

Mit Sammlungen den Überblick behalten Sie können Inhalte basierend auf Ihren Einstellungen speichern und kategorisieren.

Dies ist eine Sprachspezifikationsreferenz für Version 2 der Protokollzwischenspeicher-Sprache (proto2). Die Syntax wird mit Extended Backus-Naur Form (EBNF) angegeben:

|   alternation
()  grouping
[]  option (zero or one time)
{}  repetition (any number of times)

Weitere Informationen zur Verwendung von proto2 finden Sie im Sprachleitfaden.

Lexikalische Elemente

Buchstaben und Ziffern

letter = "A" … "Z" | "a" … "z"
capitalLetter =  "A" … "Z"
decimalDigit = "0" … "9"
octalDigit   = "0" … "7"
hexDigit     = "0" … "9" | "A" … "F" | "a" … "f"

Kennungen

ident = letter { letter | decimalDigit | "_" }
fullIdent = ident { "." ident }
messageName = ident
enumName = ident
fieldName = ident
oneofName = ident
mapName = ident
serviceName = ident
rpcName = ident
streamName = ident
messageType = [ "." ] { ident "." } messageName
enumType = [ "." ] { ident "." } enumName
groupName = capitalLetter { letter | decimalDigit | "_" }

Ganzzahlliterale

intLit     = decimalLit | octalLit | hexLit
decimalLit = ( "1" … "9" ) { decimalDigit }
octalLit   = "0" { octalDigit }
hexLit     = "0" ( "x" | "X" ) hexDigit { hexDigit } 

Gleitkommaliterale

floatLit = ( decimals "." [ decimals ] [ exponent ] | decimals exponent | "."decimals [ exponent ] ) | "inf" | "nan"
decimals  = decimalDigit { decimalDigit }
exponent  = ( "e" | "E" ) [ "+" | "-" ] decimals 

Boolesch

boolLit = "true" | "false" 

Stringliterale

strLit = ( "'" { charValue } "'" ) | ( '"' { charValue } '"' )
charValue = hexEscape | octEscape | charEscape | /[^\0\n\\]/
hexEscape = '\' ( "x" | "X" ) hexDigit hexDigit
octEscape = '\' octalDigit octalDigit octalDigit
charEscape = '\' ( "a" | "b" | "f" | "n" | "r" | "t" | "v" | '\' | "'" | '"' )

Leere Aufstellung

emptyStatement = ";"

Konstante

constant = fullIdent | ( [ "-" | "+" ] intLit ) | ( [ "-" | "+" ] floatLit ) |
                strLit | boolLit 

Syntax

Mit der Syntaxanweisung wird die Protobuf-Version definiert.

syntax = "syntax" "=" ("'" "proto2" "'" | '"' "proto2" '"') ";"

Importanweisung

Mit der Importanweisung werden die Definitionen einer anderen .proto-Datei importiert.

import = "import" [ "weak" | "public" ] strLit ";" 

Beispiel:

import public "other.proto";

Paket

Mit dem Paketbezeichner können Namenskonflikte zwischen Protokollnachrichtentypen vermieden werden.

package = "package" fullIdent ";"

Beispiel:

package foo.bar;

Option

Optionen können in Proto-Dateien, Nachrichten, Enums und Diensten verwendet werden. Eine Option kann eine vom Protobuf definierte Option oder eine benutzerdefinierte Option sein. Weitere Informationen finden Sie im Leitfaden für die Sprache.

option = "option" optionName  "=" constant ";"
optionName = ( ident | "(" fullIdent ")" ) { "." ident }

Beispiele:

option java_package = "com.example.foo";

Felder

Felder sind die grundlegenden Elemente einer Protokollpuffernachricht. Felder können normale Felder, Gruppenfelder, einmalige Felder oder Zuordnungsfelder sein. Ein Feld hat ein Label, einen Typ und eine Feldnummer.

label = "required" | "optional" | "repeated"
type = "double" | "float" | "int32" | "int64" | "uint32" | "uint64"
      | "sint32" | "sint64" | "fixed32" | "fixed64" | "sfixed32" | "sfixed64"
      | "bool" | "string" | "bytes" | messageType | enumType
fieldNumber = intLit;

Normales Feld

Jedes Feld hat ein Label, einen Typ, einen Namen und eine Feldnummer. Er kann Feldoptionen enthalten.

field = label type fieldName "=" fieldNumber [ "[" fieldOptions "]" ] ";"
fieldOptions = fieldOption { ","  fieldOption }
fieldOption = optionName "=" constant

Beispiele:

optional foo.bar nested_message = 2;
repeated int32 samples = 4 [packed=true];

Gruppenfeld

Beachten Sie, dass diese Funktion eingestellt wurde und nicht für neue Nachrichtentypen verwendet werden sollte. Verwenden Sie stattdessen verschachtelte Nachrichtentypen.

Gruppen sind eine Möglichkeit, Informationen in Nachrichtendefinitionen zu verschachteln. Der Gruppenname muss mit einem Großbuchstaben beginnen.

group = label "group" groupName "=" fieldNumber messageBody

Beispiel:

repeated group Result = 1 {
    required string url = 2;
    optional string title = 3;
    repeated string snippets = 4;
}

Oneof- und Oneof-Feld

Eine davon besteht aus einem Feld und einem Namen. Eines der Felder hat keine Labels.

oneof = "oneof" oneofName "{" { option | oneofField | emptyStatement } "}"
oneofField = type fieldName "=" fieldNumber [ "[" fieldOptions "]" ] ";"

Beispiel:

oneof foo {
    string name = 4;
    SubMessage sub_message = 9;
}

Kartenfeld

Ein Zuordnungsfeld hat einen Schlüsseltyp, einen Werttyp, einen Namen und eine Feldnummer. Der Schlüsseltyp kann ein beliebiger Integral- oder Stringtyp sein. Der Schlüsseltyp ist möglicherweise kein Enum.

mapField = "map" "<" keyType "," type ">" mapName "=" fieldNumber [ "[" fieldOptions "]" ] ";"
keyType = "int32" | "int64" | "uint32" | "uint64" | "sint32" | "sint64" |
          "fixed32" | "fixed64" | "sfixed32" | "sfixed64" | "bool" | "string"

Beispiel:

map<string, Project> projects = 3;

Erweiterungen und reserviert

Erweiterungen und reservierte Elemente sind Nachrichtenelemente, die einen Bereich von Feldnummern oder Feldnamen deklarieren.

Erweiterungen

Erweiterungen deklarieren, dass in einer Nachricht eine Reihe von Feldnummern für Erweiterungen von Drittanbietern verfügbar sind. Andere Nutzer können neue Felder für Ihren Nachrichtentyp mit diesen numerischen Tags in ihren eigenen .proto-Dateien deklarieren, ohne die ursprüngliche Datei bearbeiten zu müssen.

extensions = "extensions" ranges ";"
ranges = range { "," range }
range =  intLit [ "to" ( intLit | "max" ) ]

Beispiele:

extensions 100 to 199;
extensions 4, 20 to max;

Reserviert

Reserviert deklariert eine Reihe von Feldnummern oder Feldnamen in einer Nachricht, die nicht verwendet werden kann.

reserved = "reserved" ( ranges | strFieldNames ) ";"
strFieldNames = strFieldName { "," strFieldName }
strFieldName = "'" fieldName "'" | '"' fieldName '"'

Beispiele:

reserved 2, 15, 9 to 11;
reserved "foo", "bar";

Definitionen der obersten Ebene

Enum-Definition

Die Enum-Definition besteht aus einem Namen und einem Enum-Text. Der Enum-Textkörper kann Optionen, Enumerationsfelder und reservierte Anweisungen enthalten.

enum = "enum" enumName enumBody
enumBody = "{" { option | enumField | emptyStatement | reserved } "}"
enumField = ident "=" [ "-" ] intLit [ "[" enumValueOption { ","  enumValueOption } "]" ]";"
enumValueOption = optionName "=" constant

Beispiel:

enum EnumAllowingAlias {
  option allow_alias = true;
  EAA_UNSPECIFIED = 0;
  EAA_STARTED = 1;
  EAA_RUNNING = 2 [(custom_option) = "hello world"];
}

Nachrichtendefinition

Eine Nachricht besteht aus einem Nachrichtennamen und einem Nachrichtentext. Der Nachrichtentext kann Felder, verschachtelte Enum-Definitionen, verschachtelte Nachrichtendefinitionen, Erweiterungsanweisungen, Erweiterungen, Gruppen, Optionen, Ones, Map-Felder und reservierte Anweisungen enthalten.

message = "message" messageName messageBody
messageBody = "{" { field | enum | message | extend | extensions | group |
option | oneof | mapField | reserved | emptyStatement } "}"

Beispiel:

message Outer {
  option (my_option).a = true;
  message Inner {   // Level 2
    required int64 ival = 1;
  }
  map<int32, string> my_map = 2;
  extensions 20 to 30;
}

Erweiterung

Wenn eine Nachricht in derselben oder importierten .proto-Datei einen Bereich für Erweiterungen reserviert hat, kann die Nachricht verlängert werden.

extend = "extend" messageType "{" {field | group | emptyStatement} "}"

Beispiel:

extend Foo {
  optional int32 bar = 126;
}

Dienstdefinition

service = "service" serviceName "{" { option | rpc | stream | emptyStatement } "}"
rpc = "rpc" rpcName "(" [ "stream" ] messageType ")" "returns" "(" [ "stream" ]
messageType ")" (( "{" { option | emptyStatement } "}" ) | ";" )
stream = "stream" streamName "(" messageType "," messageType ")" (( "{"
{ option | emptyStatement } "}") | ";" )

Beispiel:

service SearchService {
  rpc Search (SearchRequest) returns (SearchResponse);
}

.proto-Datei

proto = syntax { import | package | option | topLevelDef | emptyStatement }
topLevelDef = message | enum | extend | service

Eine .proto-Beispieldatei:

syntax = "proto2";
import public "other.proto";
option java_package = "com.example.foo";
enum EnumAllowingAlias {
  option allow_alias = true;
  EAA_UNSPECIFIED = 0;
  EAA_STARTED = 1;
  EAA_RUNNING = 1;
  EAA_FINISHED = 2 [(custom_option) = "hello world"];
}
message Outer {
  option (my_option).a = true;
  message Inner {   // Level 2
    required int64 ival = 1;
  }
  repeated Inner inner_message = 2;
  optional EnumAllowingAlias enum_field = 3;
  map<int32, string> my_map = 4;
  extensions 20 to 30;
}
message Foo {
  optional group GroupMessage = 1 {
    optional bool a = 1;
  }
}