Protocol Buffers Language Specification (Proto3)

Language specification reference for the Protocol Buffers language (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"."}enumName

Integer 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" ) [ "+" | "-" ] decimals

Boolean

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 hexDigit

EmptyStatement

emptyStatement = ";"

Constant

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

MessageValue 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"="constant

Examples:

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"="constant

Example:

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|service

An 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;}