09-proto3规范

这是Protocol Buffers语言(proto3)第3版的语言规范参考。使用Extended Backus-Naur Form(EBNF)指定语法:

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

有关使用proto3的更多信息,请参阅语言指南

0.1. 词汇元素

0.1.1. 字母和数字

letter = "A""Z" | "a""z"
decimalDigit = "0""9"
octalDigit = "0""7"
hexDigit = "0""9" | "A""F" | "a""f"

0.1.2. 身份标识

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

0.1.3. 整数

intLit = decimalLit | octalLit | hexLit
decimalLit = ( "1""9" ) { decimalDigit }
octalLit = "0" { octalDigit }
hexLit = "0" ( "x" | "X" ) hexDigit { hexDigit }

0.1.4. 浮点数

floatLit = ( decimals "." [ decimals ] [ exponent ] | decimals exponent | "."decimals [ exponent ] ) | "inf" | "nan"
decimals = decimalDigit { decimalDigit }
exponent = ( "e" | "E" ) [ "+" | "-" ] decimals

0.1.5. 布尔

boolLit = "true" | "false"

0.1.6. 字符串

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" | '\' | "'" | '"' )
quote = "'" | '"'

0.1.7. 空声明

emptyStatement = ";"

0.1.8. 常量

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

0.2. 句法

语法(syntax)语句用于定义protobuf版本。

syntax = "syntax" "=" quote "proto3" quote ";"
# 例如
syntax = "proto3";

0.3. 导入语句

import语句用于导入另一个.proto的定义。

import = "import" [ "weak" | "public" ] strLit ";"
# 例如
import public "other.proto";

0.4. 包

包说明符可用于防止协议消息类型之间的名称冲突。

package = "package" fullIdent ";"
# 例如
package foo.bar;

0.5. 可用选项

选项可用于proto文件,消息,枚举和服务。可用选项可以是protobuf定义的选项或自定义选项。有关更多信息,请参阅语言指南中的选项

option = "option" optionName "=" constant ";"
optionName = ( ident | "(" fullIdent ")" ) { "." ident }
// 例如
option java_package = "com.example.foo";

0.6. 字段

字段是protocol buffers消息的基本元素。字段可以是普通字段,oneof字段或map字段。字段具有类型和字段编号。

type = "double" | "float" | "int32" | "int64" | "uint32" | "uint64"
| "sint32" | "sint64" | "fixed32" | "fixed64" | "sfixed32" | "sfixed64"
| "bool" | "string" | "bytes" | messageType | enumType
fieldNumber = intLit;

0.6.1. 普通字段

每个字段都有类型,名称和字段编号。它可能有字段选项。

field = [ "repeated" ] type fieldName "=" fieldNumber [ "[" fieldOptions "]" ] ";"
fieldOptions = fieldOption { "," fieldOption }
fieldOption = optionName "=" constant
// 例如
foo.bar nested_message = 2;
repeated int32 samples = 4 [packed=true];

0.6.2. Oneof集合oneof字段

oneofoneof字段和oneof名称组成。

oneof = "oneof" oneofName "{" { oneofField | emptyStatement } "}"
oneofField = type fieldName "=" fieldNumber [ "[" fieldOptions "]" ] ";"
// 例如
oneof foo {
string name = 4;
SubMessage sub_message = 9;
}

0.6.3. Map字段

map字段具有键类型,值类型,名称和字段编号。键类型可以是任何整数或字符串类型。

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;

0.7. 保留的(Reserved)

保留语句声明了一系列不能在此消息中使用的字段编号或字段名称。

reserved = "reserved" ( ranges | fieldNames ) ";"
ranges = range { "," range }
range = intLit [ "to" ( intLit | "max" ) ]
fieldNames = fieldName { "," fieldName }
// 例如
reserved 2, 15, 9 to 11;
reserved "foo", "bar";

0.8. 顶级定义

0.8.1. 枚举定义

枚举定义由名称和枚举主体组成。枚举主体可以有选项和枚举字段。枚举定义必须以枚举值零开始。

enum = "enum" enumName enumBody
enumBody = "{" { option | enumField | emptyStatement } "}"
enumField = ident "=" intLit [ "[" enumValueOption { "," enumValueOption } "]" ]";"
enumValueOption = optionName "=" constant
// 例如
enum EnumAllowingAlias {
option allow_alias = true;
UNKNOWN = 0;
STARTED = 1;
RUNNING = 2 [(custom_option) = "hello world"];
}

0.8.2. 消息定义

消息由消息名称和消息正文组成。消息正文可以包含字段,嵌套枚举定义,嵌套消息定义,可用选项,oneof字段,map字段和保留语句。

message = "message" messageName messageBody
messageBody = "{" { field | enum | message | option | oneof | mapField |
reserved | emptyStatement } "}"
// 例如
message Outer {
option (my_option).a = true;
message Inner { // Level 2
int64 ival = 1;
}
map<int32, string> my_map = 2;
}

0.8.3. 服务定义

service = "service" serviceName "{" { option | rpc | emptyStatement } "}"
rpc = "rpc" rpcName "(" [ "stream" ] messageType ")" "returns" "(" [ "stream" ]
messageType ")" (( "{" {option | emptyStatement } "}" ) | ";")
// 例如
service SearchService {
rpc Search (SearchRequest) returns (SearchResponse);
}

0.9. Proto文件

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

示例.proto文件

syntax = "proto3";
import public "other.proto";
option java_package = "com.example.foo";
enum EnumAllowingAlias {
option allow_alias = true;
UNKNOWN = 0;
STARTED = 1;
RUNNING = 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;
}
上次修改: 14 April 2020