Protocol Buffers 常用类型
google.protobuf
包的 API 文档。索引
Any
(消息)Api
(消息)BoolValue
(消息)BytesValue
(消息)DoubleValue
(消息)Duration
(消息)Empty
(消息)Enum
(消息)EnumValue
(消息)Field
(消息)Field.Cardinality
(枚举)Field.Kind
(枚举)FieldMask
(消息)FloatValue
(消息)Int32Value
(消息)Int64Value
(消息)ListValue
(消息)Method
(消息)Mixin
(消息)NullValue
(枚举)Option
(消息)SourceContext
(消息)StringValue
(消息)Struct
(消息)Syntax
(枚举)Timestamp
(消息)Type
(消息)UInt32Value
(消息)UInt64Value
(消息)Value
(消息)
以“Value
”结尾的常用类型是其他类型的包装消息,例如 BoolValue
和 EnumValue
。这些现在已过时。如今使用包装器的唯一原因可能是:
- 与已使用它们的消息保持传输兼容性。
- 如果你想将标量值放入
Any
消息中。
在大多数情况下,有更好的选择:
- 对于新消息,最好使用常规的显式存在字段(在 proto2/proto3 中为
optional
,在 edition >= 2023 中为常规字段)。 - 扩展通常是比
Any
字段更好的选择。
Any
Any
包含任意序列化的消息以及描述该序列化消息类型的 URL。
JSON
Any
值的 JSON 表示使用反序列化的嵌入式消息的常规表示,并附加一个字段 @type
,其中包含类型 URL。例如:
package google.profile;
message Person {
string first_name = 1;
string last_name = 2;
}
{
"@type": "type.googleapis.com/google.profile.Person",
"firstName": <string>,
"lastName": <string>
}
如果嵌入的消息类型是常用类型且具有自定义的 JSON 表示,则该表示将被嵌入,并添加一个 value
字段,该字段持有自定义的 JSON,此外还有 @type
字段。示例(对于消息 google.protobuf.Duration
):
{
"@type": "type.googleapis.com/google.protobuf.Duration",
"value": "1.212s"
}
字段名称 | Type | 描述 |
---|---|---|
type_url | string | 一个 URL/资源名,其内容描述了序列化消息的类型。 对于使用
除 |
value | bytes | 必须是上述指定类型的有效序列化数据。 |
Api
Api 是 protocol buffer 服务的轻量级描述符。
字段名称 | Type | 描述 |
---|---|---|
name | string | 此 api 的完全限定名称,包括包名和 api 的简单名称。 |
methods | Method | 此 api 的方法,顺序不确定。 |
options | 选项 | 附加到 API 的任何元数据。 |
version | string | 此 api 的版本字符串。如果指定,必须采用 版本控制方案使用语义化版本,其中主版本号表示重大更改,次版本号表示附加的、非重大的更改。两个版本号都向用户表明不同版本的预期行为,应根据产品计划仔细选择。 主版本号也反映在 API 的包名中,该包名必须以 |
source_context |
| 此消息所代表的 protocol buffer 服务的源上下文。 |
mixins |
| 包含的 API。请参阅 Mixin 。 |
syntax | 语法 | 服务的源语法。 |
BoolValue
bool
的包装消息。
BoolValue
的 JSON 表示是 JSON 的 true
和 false
。
字段名称 | Type | 描述 |
---|---|---|
value | bool | 布尔值。 |
BytesValue
bytes
的包装消息。
BytesValue
的 JSON 表示是 JSON 字符串。
字段名称 | Type | 描述 |
---|---|---|
value | bytes | 字节值。 |
DoubleValue
double
的包装消息。
DoubleValue
的 JSON 表示是 JSON 数字。
字段名称 | Type | 描述 |
---|---|---|
value | double | double 值。 |
Duration
Duration 表示一个有符号的、固定长度的时间跨度,以秒和纳秒分辨率的秒的小数部分计数表示。它独立于任何日历和“天”或“月”等概念。它与 Timestamp 相关,因为两个 Timestamp 值之间的差是一个 Duration,并且它可以与 Timestamp 相加或相减。范围大约为 +-10,000 年。
示例 1:在伪代码中从两个 Timestamp 计算 Duration。
Timestamp start = ...;
Timestamp end = ...;
Duration duration = ...;
duration.seconds = end.seconds - start.seconds;
duration.nanos = end.nanos - start.nanos;
if (duration.seconds < 0 && duration.nanos > 0) {
duration.seconds += 1;
duration.nanos -= 1000000000;
} else if (duration.seconds > 0 && duration.nanos < 0) {
duration.seconds -= 1;
duration.nanos += 1000000000;
}
示例 2:在伪代码中从 Timestamp + Duration 计算 Timestamp。
Timestamp start = ...;
Duration duration = ...;
Timestamp end = ...;
end.seconds = start.seconds + duration.seconds;
end.nanos = start.nanos + duration.nanos;
if (end.nanos < 0) {
end.seconds -= 1;
end.nanos += 1000000000;
} else if (end.nanos >= 1000000000) {
end.seconds += 1;
end.nanos -= 1000000000;
}
Duration
的 JSON 表示是一个以 s
结尾的 String
,表示秒,前面是秒数,纳秒表示为小数秒。
字段名称 | Type | 描述 |
---|---|---|
seconds | int64 | 有符号的时间跨度秒数。必须在 -315,576,000,000 到 +315,576,000,000 之间(含)。 |
nanos | int32 | 有符号的时间跨度的纳秒分辨率秒的小数部分。小于一秒的持续时间用 0 seconds 字段和正或负 nanos 字段表示。对于一秒或更长的持续时间,nanos 字段的非零值必须与 seconds 字段的符号相同。必须在 -999,999,999 到 +999,999,999 之间(含)。 |
Empty
一个通用的空消息,您可以重复使用它以避免在 API 中定义重复的空消息。一个典型的例子是将其用作 API 方法的请求或响应类型。例如:
service Foo {
rpc Bar(google.protobuf.Empty) returns (google.protobuf.Empty);
}
Empty
的 JSON 表示是空 JSON 对象 {}
。
Enum
枚举类型定义
字段名称 | Type | 描述 |
---|---|---|
name | string | 枚举类型名称。 |
enumvalue | EnumValue | 枚举值定义。 |
options | 选项 | Protocol buffer 选项。 |
source_context | SourceContext | 源上下文。 |
syntax | 语法 | 源语法。 |
EnumValue
枚举值定义。
字段名称 | Type | 描述 |
---|---|---|
name | string | 枚举值名称。 |
number | int32 | 枚举值编号。 |
options | 选项 | Protocol buffer 选项。 |
Field
消息类型的单个字段。
字段名称 | Type | 描述 |
---|---|---|
kind | Kind | 字段类型。 |
cardinality | Cardinality | 字段基数。 |
number | int32 | 字段编号。 |
name | string | 字段名称。 |
type_url | string | 消息或枚举类型的字段类型 URL,不带 schema。示例:"type.googleapis.com/google.protobuf.Timestamp" 。 |
oneof_index | int32 | 对于消息或枚举类型,该字段类型在 Type.oneofs 中的索引。第一个类型的索引为 1;零表示该类型不在列表中。 |
packed | bool | 是否使用可选的 packed 传输表示。 |
options | 选项 | protocol buffer 选项。 |
json_name | string | 字段的 JSON 名称。 |
default_value | string | 此字段默认值的字符串值。仅限 Proto2 语法。 |
Cardinality
字段是 optional、required 还是 repeated。
枚举值 | 描述 |
---|---|
CARDINALITY_UNKNOWN | 对于基数未知的字段。 |
CARDINALITY_OPTIONAL | 对于 optional 字段。 |
CARDINALITY_REQUIRED | 对于 required 字段。仅限 Proto2 语法。 |
CARDINALITY_REPEATED | 对于 repeated 字段。 |
Kind
基本字段类型。
枚举值 | 描述 |
---|---|
TYPE_UNKNOWN | 字段类型未知。 |
TYPE_DOUBLE | 字段类型 double。 |
TYPE_FLOAT | 字段类型 float。 |
TYPE_INT64 | 字段类型 int64。 |
TYPE_UINT64 | 字段类型 uint64。 |
TYPE_INT32 | 字段类型 int32。 |
TYPE_FIXED64 | 字段类型 fixed64。 |
TYPE_FIXED32 | 字段类型 fixed32。 |
TYPE_BOOL | 字段类型 bool。 |
TYPE_STRING | 字段类型 string。 |
TYPE_GROUP | 字段类型 group。仅限 Proto2 语法,且已弃用。 |
TYPE_MESSAGE | 字段类型 message。 |
TYPE_BYTES | 字段类型 bytes。 |
TYPE_UINT32 | 字段类型 uint32。 |
TYPE_ENUM | 字段类型 enum。 |
TYPE_SFIXED32 | 字段类型 sfixed32。 |
TYPE_SFIXED64 | 字段类型 sfixed64。 |
TYPE_SINT32 | 字段类型 sint32。 |
TYPE_SINT64 | 字段类型 sint64。 |
FieldMask
FieldMask
表示一组符号化的字段路径,例如:
paths: "f.a"
paths: "f.b.d"
这里 f
表示某个根消息中的一个字段,a
和 b
是 f
中消息的字段,而 d
是 f.b
中消息的字段。
字段掩码用于指定 get 操作应返回的字段子集(投影),或由 update 操作修改的字段。字段掩码也有自定义的 JSON 编码(见下文)。
投影中的字段掩码
当 FieldMask
指定一个投影时,API 将过滤响应消息(或子消息),使其只包含掩码中指定的那些字段。例如,考虑这个“预掩码”响应消息:
f {
a : 22
b {
d : 1
x : 2
}
y : 13
}
z: 8
在应用了前一个示例中的掩码后,API 响应将不会包含字段 x、y 或 z 的特定值(它们的值将被设置为默认值,并在 proto 文本输出中省略):
f {
a : 22
b {
d : 1
}
}
重复字段不允许出现在字段掩码的最后一个位置之外。
如果 get 操作中不存在 FieldMask
对象,则该操作适用于所有字段(就像指定了所有字段的 FieldMask 一样)。
请注意,字段掩码不一定适用于顶层响应消息。对于 REST get 操作,字段掩码直接应用于响应,但对于 REST list 操作,掩码则应用于返回的资源列表中的每个单独消息。对于 REST 自定义方法,可能会使用其他定义。掩码的应用位置将与其在 API 中的声明一起明确记录。无论如何,对返回的资源/资源的影响是 API 的必需行为。
更新操作中的字段掩码
更新操作中的字段掩码指定了目标资源的哪些字段将被更新。API 必须只更改掩码中指定的字段的值,并保持其他字段不变。如果传入一个资源来描述更新后的值,API 会忽略掩码未覆盖的所有字段的值。
为了将字段的值重置为默认值,该字段必须在掩码中,并在提供的资源中设置为默认值。因此,为了重置资源的所有字段,请提供该资源的默认实例并在掩码中设置所有字段,或者如下所述不提供掩码。
如果更新时不存在字段掩码,则该操作适用于所有字段(就像指定了所有字段的字段掩码一样)。请注意,在存在 schema 演进的情况下,这可能意味着客户端不知道因此未在请求中填写的字段将被重置为其默认值。如果这是不希望的行为,特定服务可能会要求客户端始终指定字段掩码,否则会产生错误。
与 get 操作一样,描述请求消息中更新值的资源位置取决于操作类型。无论如何,API 必须遵守字段掩码的效果。
HTTP REST 的注意事项
使用字段掩码的更新操作的 HTTP 类型必须设置为 PATCH 而不是 PUT,以满足 HTTP 语义(PUT 只能用于完全更新)。
字段掩码的 JSON 编码
在 JSON 中,字段掩码被编码为单个字符串,其中路径由逗号分隔。每个路径中的字段名称会与小驼峰命名约定进行转换。
例如,考虑以下消息声明:
message Profile {
User user = 1;
Photo photo = 2;
}
message User {
string display_name = 1;
string address = 2;
}
在 proto 中,Profile
的字段掩码可能如下所示:
mask {
paths: "user.display_name"
paths: "photo"
}
在 JSON 中,相同的掩码表示如下:
{
mask: "user.displayName,photo"
}
字段名称 | Type | 描述 |
---|---|---|
paths | string | 字段掩码路径的集合。 |
FloatValue
float
的包装消息。
FloatValue
的 JSON 表示是 JSON 数字。
字段名称 | Type | 描述 |
---|---|---|
value | float | float 值。 |
Int32Value
int32
的包装消息。
Int32Value
的 JSON 表示是 JSON 数字。
字段名称 | Type | 描述 |
---|---|---|
value | int32 | int32 值。 |
Int64Value
int64
的包装消息。
Int64Value
的 JSON 表示是 JSON 字符串。
字段名称 | Type | 描述 |
---|---|---|
value | int64 | int64 值。 |
ListValue
ListValue
是一个包装了重复值字段的结构。
ListValue
的 JSON 表示是 JSON 数组。
字段名称 | Type | 描述 |
---|---|---|
values | Value | 动态类型值的重复字段。 |
Method
Method 表示一个 api 的方法。
字段名称 | Type | 描述 |
---|---|---|
name | string | 此方法的简单名称。 |
request_type_url | string | 输入消息类型的 URL。 |
request_streaming | bool | 如果为 true,则请求是流式的。 |
response_type_url | string | 输出消息类型的 URL。 |
response_streaming | bool | 如果为 true,则响应是流式的。 |
options | 选项 | 附加到方法的任何元数据。 |
syntax | 语法 | 此方法的源语法。 |
Mixin
声明要包含在此 API 中的 API。包含方 API 必须重新声明被包含 API 的所有方法,但文档和选项按如下方式继承:
如果在去除注释和空白后,重新声明的方法的文档字符串为空,它将从原始方法继承。
属于服务配置(http、visibility)的每个注解,如果在重新声明的方法中未设置,将被继承。
如果继承了 http 注解,路径模式将按如下方式修改。任何版本前缀都将被替换为包含方 API 的版本,如果指定了
root
路径,则会加上该路径。
一个简单 mixin 的示例:
package google.acl.v1;
service AccessControl {
// Get the underlying ACL object.
rpc GetAcl(GetAclRequest) returns (Acl) {
option (google.api.http).get = "/v1/{resource=**}:getAcl";
}
}
package google.storage.v2;
service Storage {
// rpc GetAcl(GetAclRequest) returns (Acl);
// Get a data record.
rpc GetData(GetDataRequest) returns (Data) {
option (google.api.http).get = "/v2/{resource=**}";
}
}
一个 mixin 配置的示例:
apis:
- name: google.storage.v2.Storage
mixins:
- name: google.acl.v1.AccessControl
mixin 结构意味着 AccessControl
中的所有方法也以相同的名称和请求/响应类型在 Storage
中声明。文档生成器或注解处理器在继承文档和注解后将看到有效的 Storage.GetAcl
方法,如下所示:
service Storage {
// Get the underlying ACL object.
rpc GetAcl(GetAclRequest) returns (Acl) {
option (google.api.http).get = "/v2/{resource=**}:getAcl";
}
...
}
注意路径模式中的版本如何从 v1
变为 v2
。
如果 mixin 中的 root
字段被指定,它应该是一个相对路径,继承的 HTTP 路径将置于其下。示例:
apis:
- name: google.storage.v2.Storage
mixins:
- name: google.acl.v1.AccessControl
root: acls
这意味着以下继承的 HTTP 注解:
service Storage {
// Get the underlying ACL object.
rpc GetAcl(GetAclRequest) returns (Acl) {
option (google.api.http).get = "/v2/acls/{resource=**}:getAcl";
}
...
}
字段名称 | Type | 描述 |
---|---|---|
name | string | 被包含的 API 的完全限定名称。 |
root | string | 如果非空,则指定一个路径,继承的 HTTP 路径将以此为根。 |
NullValue
NullValue
是一个单例枚举,用于表示 Value
类型联合的 null 值。
NullValue
的 JSON 表示是 JSON null
。
枚举值 | 描述 |
---|---|
NULL_VALUE | Null 值。 |
选项
一个 protocol buffer 选项,可以附加到消息、字段、枚举等。
字段名称 | Type | 描述 |
---|---|---|
name | string | 选项的名称。例如,"java_package" 。 |
value | Any | 选项的值。例如,"com.google.protobuf" 。 |
SourceContext
SourceContext
表示有关 protobuf 元素来源的信息,例如它被定义的文件。
字段名称 | Type | 描述 |
---|---|---|
file_name | string | 包含关联 protobuf 元素的 .proto 文件的路径限定名称。例如:"google/protobuf/source.proto" 。 |
StringValue
string
的包装消息。
StringValue
的 JSON 表示是 JSON 字符串。
字段名称 | Type | 描述 |
---|---|---|
value | string | 字符串值。 |
Struct
Struct
表示一个结构化数据值,由映射到动态类型值的字段组成。在某些语言中,Struct
可能由原生表示支持。例如,在像 JS 这样的脚本语言中,结构体表示为一个对象。该表示的细节与该语言的 proto 支持一起描述。
Struct
的 JSON 表示是 JSON 对象。
字段名称 | Type | 描述 |
---|---|---|
fields | map<string, Value> | 动态类型值的映射。 |
语法
定义 protocol buffer 元素的语法。
枚举值 | 描述 |
---|---|
SYNTAX_PROTO2 | 语法 proto2 。 |
SYNTAX_PROTO3 | 语法 proto3 。 |
Timestamp
Timestamp 表示一个与任何时区或日历无关的时间点,表示为自 UTC 纪元以来的秒数和纳秒分辨率的秒的小数部分。它使用前推公历(Proleptic Gregorian Calendar)编码,该日历将公历向后延伸至公元一年。它的编码假设所有分钟都是 60 秒长,即闰秒被“抹平”,因此不需要闰秒表进行解释。范围从 0001-01-01T00:00:00Z 到 9999-12-31T23:59:59.999999999Z。通过限制在该范围内,我们确保可以与 RFC 3339 日期字符串进行相互转换。请参阅 https://www.ietf.org/rfc/rfc3339.txt。
Timestamp 类型在 RFC 3339 格式中编码为字符串:“{year}-{month}-{day}T{hour}:{min}:{sec}[.{frac_sec}]Z
”,其中 {year}
总是用四位数字表示,而 {month}
、{day}
、{hour}
、{min}
和 {sec}
则用零填充到两位数。小数秒最多可达 9 位(即纳秒分辨率),是可选的。“Z”后缀表示时区(“UTC”);时区是必需的。proto3 JSON 序列化器在打印 Timestamp 类型时应始终使用 UTC(由“Z”表示),而 proto3 JSON 解析器应能接受 UTC 和其他时区(由偏移量表示)。
示例 1:从 POSIX time()
计算 Timestamp。
Timestamp timestamp;
timestamp.set_seconds(time(NULL));
timestamp.set_nanos(0);
示例 2:从 POSIX gettimeofday()
计算 Timestamp。
struct timeval tv;
gettimeofday(&tv, NULL);
Timestamp timestamp;
timestamp.set_seconds(tv.tv_sec);
timestamp.set_nanos(tv.tv_usec * 1000);
示例 3:从 Win32 GetSystemTimeAsFileTime()
计算 Timestamp。
FILETIME ft;
GetSystemTimeAsFileTime(&ft);
UINT64 ticks = (((UINT64)ft.dwHighDateTime) << 32) | ft.dwLowDateTime;
// A Windows tick is 100 nanoseconds. Windows epoch 1601-01-01T00:00:00Z
// is 11644473600 seconds before Unix epoch 1970-01-01T00:00:00Z.
Timestamp timestamp;
timestamp.set_seconds((INT64) ((ticks / 10000000) - 11644473600LL));
timestamp.set_nanos((INT32) ((ticks % 10000000) * 100));
示例 4:从 Java System.currentTimeMillis()
计算 Timestamp。
long millis = System.currentTimeMillis();
Timestamp timestamp = Timestamp.newBuilder().setSeconds(millis / 1000)
.setNanos((int) ((millis % 1000) * 1000000)).build();
示例 5:在 Python 中从当前时间计算 Timestamp。
now = time.time()
seconds = int(now)
nanos = int((now - seconds) * 10**9)
timestamp = Timestamp(seconds=seconds, nanos=nanos)
字段名称 | Type | 描述 |
---|---|---|
seconds | int64 | 表示自 Unix 纪元 1970-01-01T00:00:00Z 以来的 UTC 时间秒数。必须在 0001-01-01T00:00:00Z 到 9999-12-31T23:59:59Z 之间(含)。 |
nanos | int32 | 纳秒分辨率的非负秒的小数部分。负秒值带小数部分时,仍必须有非负的 nanos 值,用于向前计时。必须在 0 到 999,999,999 之间(含)。 |
Type
一个 protocol buffer 消息类型。
字段名称 | Type | 描述 |
---|---|---|
name | string | 完全限定的消息名称。 |
fields | Field | 字段列表。 |
oneofs | string | 此类型中出现在 oneof 定义中的类型列表。 |
options | 选项 | protocol buffer 选项。 |
source_context | SourceContext | 源上下文。 |
syntax | 语法 | 源语法。 |
UInt32Value
uint32
的包装消息。
UInt32Value
的 JSON 表示是 JSON 数字。
字段名称 | Type | 描述 |
---|---|---|
value | uint32 | uint32 值。 |
UInt64Value
uint64
的包装消息。
UInt64Value
的 JSON 表示是 JSON 字符串。
字段名称 | Type | 描述 |
---|---|---|
value | uint64 | uint64 值。 |
Value
Value
表示一个动态类型的值,可以是 null、数字、字符串、布尔值、递归的结构值或值列表。值的生产者应设置其中一个变体,任何变体的缺失都表示错误。
Value
的 JSON 表示是 JSON 值。
字段名称 | Type | 描述 |
---|---|---|
联合字段,只能是以下之一: | ||
null_value | NullValue | 表示一个 null 值。 |
number_value | double | 表示一个 double 值。请注意,尝试序列化 NaN 或 Infinity 会导致错误。(我们不能像处理常规字段那样将它们序列化为字符串 "NaN" 或 "Infinity",因为它们会被解析为 string_value,而不是 number_value)。 |
string_value | string | 表示一个字符串值。 |
bool_value | bool | 表示一个布尔值。 |
struct_value | Struct | 表示一个结构化值。 |
list_value | ListValue | 表示一个重复的 Value 。 |