Protocol Buffers Language Specification (Proto3)
The syntax is specified usingExtended Backus-Naur Form (EBNF):
| alternation() grouping[] option (zero or one time){} repetition (any number of times)For more information about using proto3, see thelanguage guide.
Lexical Elements
Letters and Digits
letter = "A" ... "Z" | "a" ... "z"decimalDigit = "0" ... "9"octalDigit = "0" ... "7"hexDigit = "0" ... "9" | "A" ... "F" | "a" ... "f"Identifiers
ident=letter{letter|decimalDigit|"_"}fullIdent=ident{"."ident}messageName=identenumName=identfieldName=identoneofName=identmapName=identserviceName=identrpcName=identmessageType=["."]{ident"."}messageNameenumType=["."]{ident"."}enumNameInteger Literals
intLit = decimalLit | octalLit | hexLitdecimalLit = [-] ( "1" ... "9" ) { decimalDigit }octalLit = [-] "0" { octalDigit }hexLit = [-] "0" ( "x" | "X" ) hexDigit { hexDigit }Floating-point Literals
floatLit = [-] ( decimals "." [ decimals ] [ exponent ] | decimals exponent | "."decimals [ exponent ] ) | "inf" | "nan"decimals = [-] decimalDigit { decimalDigit }exponent = ( "e" | "E" ) [ "+" | "-" ] decimalsBoolean
boolLit = "true" | "false"String Literals
strLit = strLitSingle { strLitSingle }strLitSingle = ( "'" { charValue } "'" ) | ( '"' { charValue } '"' )charValue = hexEscape | octEscape | charEscape | unicodeEscape | unicodeLongEscape | /[^\0\n\\]/hexEscape = '\' ( "x" | "X" ) hexDigit [ hexDigit ]octEscape = '\' octalDigit [ octalDigit [ octalDigit ] ]charEscape = '\' ( "a" | "b" | "f" | "n" | "r" | "t" | "v" | '\' | "'" | '"' )unicodeEscape = '\' "u" hexDigit hexDigit hexDigit hexDigitunicodeLongEscape = '\' "U" ( "000" hexDigit hexDigit hexDigit hexDigit hexDigit | "0010" hexDigit hexDigit hexDigit hexDigitEmptyStatement
emptyStatement = ";"Constant
constant=fullIdent|(["-"|"+"]intLit)|(["-"|"+"]floatLit)|strLit|boolLit|MessageValueMessageValue is defined in theText Format Language Specification.
Syntax
The syntax statement is used to define the protobuf version.
syntax = "syntax" "=" ("'" "proto3" "'" | '"' "proto3" '"') ";"Example:
syntax="proto3";Import Statement
The import statement is used to import another .proto’s definitions.
import = "import" [ "weak" | "public" ] strLit ";"Example:
importpublic"other.proto";Package
The package specifier can be used to prevent name clashes between protocolmessage types.
package="package"fullIdent";"Example:
packagefoo.bar;Option
Options can be used in proto files, messages, enums and services. An option canbe a protobuf defined option or a custom option. For more information, seeOptions in thelanguage guide.
option="option"optionName"="constant";"optionName=(ident|bracedFullIdent){"."(ident|bracedFullIdent)}bracedFullIdent="("["."]fullIdent")"optionNamePart={ident|"("["."]fullIdent")"}Example:
optionjava_package="com.example.foo";Fields
Fields are the basic elements of a protocol buffer message. Fields can be normalfields, oneof fields, or map fields. A field has a type and field number.
type="double"|"float"|"int32"|"int64"|"uint32"|"uint64"|"sint32"|"sint64"|"fixed32"|"fixed64"|"sfixed32"|"sfixed64"|"bool"|"string"|"bytes"|messageType|enumTypefieldNumber=intLit;Normal Field
Each field has type, name and field number. It may have field options.
field=["repeated"|"optional"]typefieldName"="fieldNumber["["fieldOptions"]"]";"fieldOptions=fieldOption{","fieldOption}fieldOption=optionName"="constantExamples:
foo.Barnested_message=2;repeatedint32samples=4[packed=true];Oneof and Oneof Field
A oneof consists of oneof fields and a oneof name.
oneof = "oneof" oneofName "{" { option | oneofField } "}"oneofField = type fieldName "=" fieldNumber [ "[" fieldOptions "]" ] ";"Example:
oneoffoo{stringname=4;SubMessagesub_message=9;}Map Field
A map field has a key type, value type, name, and field number. The key type canbe any integral or string type.
mapField = "map" "<" keyType "," type ">" mapName "=" fieldNumber [ "[" fieldOptions "]" ] ";"keyType = "int32" | "int64" | "uint32" | "uint64" | "sint32" | "sint64" | "fixed32" | "fixed64" | "sfixed32" | "sfixed64" | "bool" | "string"Example:
map<string,Project>projects=3;Reserved
Reserved statements declare a range of field numbers or field names that cannotbe used in this message.
reserved = "reserved" ( ranges | strFieldNames ) ";"ranges = range { "," range }range = intLit [ "to" ( intLit | "max" ) ]strFieldNames = strFieldName { "," strFieldName }strFieldName = "'" fieldName "'" | '"' fieldName '"'Examples:
reserved2,15,9to11;reserved"foo","bar";Top Level Definitions
Enum Definition
The enum definition consists of a name and an enum body. The enum body can haveoptions, enum fields, and reserved statements.
enum="enum"enumNameenumBodyenumBody="{"{option|enumField|emptyStatement|reserved}"}"enumField=ident"="["-"]intLit["["enumValueOption{","enumValueOption}"]"]";"enumValueOption=optionName"="constantExample:
enumEnumAllowingAlias{optionallow_alias=true;EAA_UNSPECIFIED=0;EAA_STARTED=1;EAA_RUNNING=2[(custom_option)="hello world"];}Message Definition
A message consists of a message name and a message body. The message body canhave fields, nested enum definitions, nested message definitions, options,oneofs, map fields, and reserved statements. A message cannot contain two fieldswith the same name in the same message schema.
message="message"messageNamemessageBodymessageBody="{"{field|enum|message|option|oneof|mapField|reserved|emptyStatement}"}"Example:
messageOuter{option(my_option).a=true;messageInner{// Level 2int64ival=1;}map<int32,string>my_map=2;}None of the entities declared inside a message may have conflicting names. Allof the following are prohibited:
messageMyMessage{optionalstringfoo=1;messagefoo{}}messageMyMessage{optionalstringfoo=1;oneoffoo{stringbar=2;}}messageMyMessage{optionalstringfoo=1;enumE{foo=0;}}Service Definition
service = "service" serviceName "{" { option | rpc | emptyStatement } "}"rpc = "rpc" rpcName "(" [ "stream" ] messageType ")" "returns" "(" [ "stream" ]messageType ")" (( "{" {option | emptyStatement } "}" ) | ";")Example:
serviceSearchService{rpcSearch(SearchRequest)returns(SearchResponse);}Proto File
proto=[syntax]{import|package|option|topLevelDef|emptyStatement}topLevelDef=message|enum|serviceAn example .proto file:
syntax="proto3";importpublic"other.proto";optionjava_package="com.example.foo";enumEnumAllowingAlias{optionallow_alias=true;EAA_UNSPECIFIED=0;EAA_STARTED=1;EAA_RUNNING=1;EAA_FINISHED=2[(custom_option)="hello world"];}messageOuter{option(my_option).a=true;messageInner{// Level 2int64ival=1;}repeatedInnerinner_message=2;EnumAllowingAliasenum_field=3;map<int32,string>my_map=4;}