Это справочник по спецификации языка для версии 2 языка протокольных буферов (proto2). Синтаксис указан с использованием расширенной формы Бэкуса-Наура (EBNF) :
| alternation () grouping [] option (zero or one time) {} repetition (any number of times)
Дополнительные сведения об использовании proto2 см. в руководстве по языку .
Лексические элементы
Буквы и цифры
letter = "A" … "Z" | "a" … "z" capitalLetter = "A" … "Z" decimalDigit = "0" … "9" octalDigit = "0" … "7" hexDigit = "0" … "9" | "A" … "F" | "a" … "f"
Идентификаторы
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 | "_" }
Целочисленные литералы
intLit = decimalLit | octalLit | hexLit decimalLit = ( "1" … "9" ) { decimalDigit } octalLit = "0" { octalDigit } hexLit = "0" ( "x" | "X" ) hexDigit { hexDigit }
Литералы с плавающей запятой
floatLit = ( decimals "." [ decimals ] [ exponent ] | decimals exponent | "."decimals [ exponent ] ) | "inf" | "nan" decimals = decimalDigit { decimalDigit } exponent = ( "e" | "E" ) [ "+" | "-" ] decimals
логический
boolLit = "true" | "false"
Строковые литералы
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" | '\' | "'" | '"' )
Пустое заявление
emptyStatement = ";"
Постоянный
constant = fullIdent | ( [ "-" | "+" ] intLit ) | ( [ "-" | "+" ] floatLit ) | strLit | boolLit
Синтаксис
Оператор синтаксиса используется для определения версии protobuf.
syntax = "syntax" "=" ("'" "proto2" "'" | '"' "proto2" '"') ";"
Заявление об импорте
Оператор import используется для импорта определений другого .proto.
import = "import" [ "weak" | "public" ] strLit ";"
Пример:
import public "other.proto";
Упаковка
Спецификатор пакета можно использовать для предотвращения конфликтов имен между типами протокольных сообщений.
package = "package" fullIdent ";"
Пример:
package foo.bar;
Вариант
Параметры можно использовать в прото-файлах, сообщениях, перечислениях и службах. Опция может быть опцией, определенной protobuf, или пользовательской опцией. Дополнительные сведения см. в разделе « Параметры » в справочнике по языку.
option = "option" optionName "=" constant ";" optionName = ( ident | "(" fullIdent ")" ) { "." ident }
Например:
option java_package = "com.example.foo";
Поля
Поля являются основными элементами буферного сообщения протокола. Поля могут быть обычными полями, групповыми полями, одним из полей или полями карты. Поле имеет метку, тип и номер поля.
label = "required" | "optional" | "repeated" type = "double" | "float" | "int32" | "int64" | "uint32" | "uint64" | "sint32" | "sint64" | "fixed32" | "fixed64" | "sfixed32" | "sfixed64" | "bool" | "string" | "bytes" | messageType | enumType fieldNumber = intLit;
Нормальное поле
Каждое поле имеет метку, тип, имя и номер поля. Он может иметь параметры поля.
field = label type fieldName "=" fieldNumber [ "[" fieldOptions "]" ] ";" fieldOptions = fieldOption { "," fieldOption } fieldOption = optionName "=" constant
Примеры:
optional foo.bar nested_message = 2; repeated int32 samples = 4 [packed=true];
Поле группы
Обратите внимание, что эта функция устарела и не должна использоваться при создании новых типов сообщений — вместо этого используйте вложенные типы сообщений.
Группы — это один из способов вложения информации в определения сообщений. Имя группы должно начинаться с заглавной буквы.
group = label "group" groupName "=" fieldNumber messageBody
Пример:
repeated group Result = 1 { required string url = 2; optional string title = 3; repeated string snippets = 4; }
Oneof и одно из полей
Oneof состоит из полей oneof и имени oneof. Одно из полей не имеет меток.
oneof = "oneof" oneofName "{" { option | oneofField | emptyStatement } "}" oneofField = type fieldName "=" fieldNumber [ "[" fieldOptions "]" ] ";"
Пример:
oneof foo { string name = 4; SubMessage sub_message = 9; }
Поле карты
Поле карты имеет тип ключа, тип значения, имя и номер поля. Тип ключа может быть любым целочисленным или строковым типом. Обратите внимание, тип ключа не может быть перечислением.
mapField = "map" "<" keyType "," type ">" mapName "=" fieldNumber [ "[" fieldOptions "]" ] ";" keyType = "int32" | "int64" | "uint32" | "uint64" | "sint32" | "sint64" | "fixed32" | "fixed64" | "sfixed32" | "sfixed64" | "bool" | "string"
Пример:
map<string, Project> projects = 3;
Расширения и зарезервировано
Расширения и зарезервировано — это элементы сообщения, которые объявляют диапазон номеров полей или имен полей.
Расширения
Расширения заявляют, что диапазон номеров полей в сообщении доступен для сторонних расширений. Другие люди могут объявлять новые поля для вашего типа сообщения с этими числовыми тегами в своих собственных файлах .proto, не редактируя исходный файл.
extensions = "extensions" ranges ";" ranges = range { "," range } range = intLit [ "to" ( intLit | "max" ) ]
Примеры:
extensions 100 to 199; extensions 4, 20 to max;
Зарезервированный
Зарезервировано объявляет диапазон номеров полей или имен полей в сообщении, которые нельзя использовать.
reserved = "reserved" ( ranges | strFieldNames ) ";" strFieldNames = strFieldName { "," strFieldName } strFieldName = "'" fieldName "'" | '"' fieldName '"'
Примеры:
reserved 2, 15, 9 to 11; reserved "foo", "bar";
Определения верхнего уровня
Определение перечисления
Определение перечисления состоит из имени и тела перечисления. Тело перечисления может иметь параметры, поля перечисления и зарезервированные операторы.
enum = "enum" enumName enumBody enumBody = "{" { option | enumField | emptyStatement | reserved } "}" enumField = ident "=" [ "-" ] intLit [ "[" enumValueOption { "," enumValueOption } "]" ]";" enumValueOption = optionName "=" constant
Пример:
enum EnumAllowingAlias { option allow_alias = true; EAA_UNSPECIFIED = 0; EAA_STARTED = 1; EAA_RUNNING = 2 [(custom_option) = "hello world"]; }
Определение сообщения
Сообщение состоит из имени сообщения и тела сообщения. Тело сообщения может содержать поля, определения вложенных перечислений, определения вложенных сообщений, операторы расширения, расширения, группы, параметры, oneofs, поля сопоставления и зарезервированные операторы.
message = "message" messageName messageBody messageBody = "{" { field | enum | message | extend | extensions | group | option | oneof | mapField | reserved | emptyStatement } "}"
Пример:
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; }
Продлевать
Если сообщение в том же или импортированном файле .proto зарезервировало диапазон для расширений, сообщение можно расширить.
extend = "extend" messageType "{" {field | group | emptyStatement} "}"
Пример:
extend Foo { optional int32 bar = 126; }
Определение услуги
service = "service" serviceName "{" { option | rpc | stream | emptyStatement } "}" rpc = "rpc" rpcName "(" [ "stream" ] messageType ")" "returns" "(" [ "stream" ] messageType ")" (( "{" { option | emptyStatement } "}" ) | ";" ) stream = "stream" streamName "(" messageType "," messageType ")" (( "{" { option | emptyStatement } "}") | ";" )
Пример:
service SearchService { rpc Search (SearchRequest) returns (SearchResponse); }
Прото файл
proto = syntax { import | package | option | topLevelDef | emptyStatement } topLevelDef = message | enum | extend | service
Пример файла .proto:
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; } }