Protocol Buffers Language Specification (Proto3)

Language specification reference for the Protocol Buffers language (Proto3).

The syntax is specified using Extended Backus-Naur Form (EBNF) :

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

For more information about using proto3, see the language 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 
 = 
 ident 
 
 
   enumName 
 = 
 ident 
 
 
   fieldName 
 = 
 ident 
 
 
   oneofName 
 = 
 ident 
 
 
   mapName 
 = 
 ident 
 
 
   serviceName 
 = 
 ident 
 
 
   rpcName 
 = 
 ident 
 
 
   messageType 
 = 
 [ 
 "." 
 ] 
 { 
 ident 
 "." 
 } 
 messageName 
 
 
   enumType 
 = 
 [ 
 "." 
 ] 
 { 
 ident 
 "." 
 } 
 enumName 
 
 
 

Integer Literals

   intLit     = decimalLit | octalLit | hexLit 
 
  decimalLit = [-] ( "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 hexDigit 
 
  unicodeLongEscape = '\' "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 the Text 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:

    import 
 public 
 "other.proto" 
 ; 
 
 
 

Package

The package specifier can be used to prevent name clashes between protocol message types.

    package 
 = 
 "package" 
 fullIdent 
 ";" 
 
 
 

Example:

    package 
 foo 
 . 
 bar 
 ; 
 
 
 

Option

Options can be used in proto files, messages, enums and services. An option can be a protobuf defined option or a custom option. For more information, see Options in the language guide.

    option 
 = 
 "option" 
 optionName 
 "=" 
 constant 
 ";" 
 
 
   optionName 
 = 
 ( 
 ident 
 | 
 bracedFullIdent 
 ) 
 { 
 "." 
 ( 
 ident 
 | 
 bracedFullIdent 
 ) 
 } 
 
 
   bracedFullIdent 
 = 
 "(" 
 [ 
 "." 
 ] 
 fullIdent 
 ")" 
 
 
   optionNamePart 
 = 
 { 
 ident 
 | 
 "(" 
 [ 
 "." 
 ] 
 fullIdent 
 ")" 
 } 
 
 
 

Example:

    option 
 java_package 
 = 
 "com.example.foo" 
 ; 
 
 
 

Fields

Fields are the basic elements of a protocol buffer message. Fields can be normal fields, 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 
 | 
 enumType 
 
 
   fieldNumber 
 = 
 intLit 
 ; 
 
 
 

Normal Field

Each field has type, name and field number. It may have field options.

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

Examples:

    foo.Bar 
 nested_message 
 = 
 2 
 ; 
 
 
   repeated 
 int32 
 samples 
 = 
 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:

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

Map Field

A map field has a key type, value type, name, and field number. The key type can be 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 cannot be used in this message.

   reserved = "reserved" ( ranges | strFieldNames ) ";" 
 
  ranges = range { "," range } 
 
  range =  intLit [ "to" ( intLit | "max" ) ] 
 
  strFieldNames = strFieldName { "," strFieldName } 
 
  strFieldName = "'" fieldName "'" | '"' fieldName '"' 
 
 

Examples:

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

Top Level Definitions

Enum Definition

The enum definition consists of a name and an enum body. The enum body can have options, enum fields, and reserved statements.

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

Example:

    enum 
 EnumAllowingAlias 
 { 
 
 
   option 
 allow_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 can have fields, nested enum definitions, nested message definitions, options, oneofs, map fields, and reserved statements. A message cannot contain two fields with the same name in the same message schema.

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

Example:

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

None of the entities declared inside a message may have conflicting names. All of the following are prohibited:

    message 
 MyMessage 
 { 
 
 
   optional 
 string 
 foo 
 = 
 1 
 ; 
 
 
   message 
 foo 
 {} 
 
 
   } 
 
 
   message 
 MyMessage 
 { 
 
 
   optional 
 string 
 foo 
 = 
 1 
 ; 
 
 
   oneof 
 foo 
 { 
 
 
   string 
 bar 
 = 
 2 
 ; 
 
 
   } 
 
 
   } 
 
 
   message 
 MyMessage 
 { 
 
 
   optional 
 string 
 foo 
 = 
 1 
 ; 
 
 
   enum 
 E 
 { 
 
 
   foo 
 = 
 0 
 ; 
 
 
   } 
 
 
   } 
 
 
 

Service Definition

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

Example:

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

Proto File

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

An example .proto file:

    syntax 
 = 
 "proto3" 
 ; 
 
 
   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 
 
 
   int64 
 ival 
 = 
 1 
 ; 
 
 
   } 
 
 
   repeated 
 Inner 
 inner_message 
 = 
 2 
 ; 
 
 
   EnumAllowingAlias 
 enum_field 
 = 
 3 
 ; 
 
 
   map 
 < 
 int32 
 , 
 string 
 > 
 my_map 
 = 
 4 
 ; 
 
 
   }