ПРИМЕЧАНИЕ. Этот сайт устарел. Сайт будет отключен после 31 января 2023 года, и трафик будет перенаправлен на новый сайт по адресу https://protobuf.dev . А пока обновления будут производиться только для protobuf.dev.

Спецификация языка версии 2 буферов протокола

Оптимизируйте свои подборки Сохраняйте и классифицируйте контент в соответствии со своими настройками.

Это справочник по спецификации языка для версии 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;
  }
}