Protocol Buffers 常用类型
索引
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
,版本 >= 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
,除了 @type
字段之外,该字段还包含自定义 JSON。示例 (对于消息 google.protobuf.Duration
)
{
"@type": "type.googleapis.com/google.protobuf.Duration",
"value": "1.212s"
}
字段名称 | Type | 描述 |
---|---|---|
type_url | string | URL/资源名称,其内容描述了序列化消息的类型。 对于使用 schema
除了 |
value | bytes | 必须是上述指定类型的有效序列化数据。 |
Api
Api 是协议缓冲区服务的轻量级描述符。
字段名称 | Type | 描述 |
---|---|---|
name | string | 此 API 的完全限定名称,包括包名称,后跟 API 的简单名称。 |
methods | Method | 此 API 的方法,顺序未指定。 |
options | Option | 附加到 API 的任何元数据。 |
version | string | 此 API 的版本字符串。如果指定,则必须具有 版本控制 schema 使用 语义版本控制,其中主版本号表示重大更改,次版本号表示附加的、非重大更改。两个版本号都是向用户发出的信号,表明对不同版本的期望,应根据产品计划仔细选择。 主版本也反映在 API 的包名称中,该名称必须以 |
source_context |
| 此消息表示的协议缓冲区服务的源上下文。 |
mixins |
| 包含的 API。请参阅 Mixin 。 |
syntax | Syntax | 服务的源语法。 |
BoolValue
bool
的包装消息。
BoolValue
的 JSON 表示形式是 JSON true
和 false
。
字段名称 | Type | 描述 |
---|---|---|
value | bool | bool 值。 |
BytesValue
bytes
的包装消息。
BytesValue
的 JSON 表示形式是 JSON 字符串。
字段名称 | Type | 描述 |
---|---|---|
value | bytes | bytes 值。 |
DoubleValue
double
的包装消息。
DoubleValue
的 JSON 表示形式是 JSON 数字。
字段名称 | Type | 描述 |
---|---|---|
value | double | double 值。 |
Duration
Duration 表示有符号的、固定长度的时间跨度,表示为秒数和纳秒分辨率的秒的小数。它独立于任何日历和“天”或“月”之类的概念。它与 Timestamp 相关,因为两个 Timestamp 值之间的差是 Duration,并且可以从 Timestamp 中添加或减去。范围约为 +-10,000 年。
示例 1:在伪代码中从两个时间戳计算 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:在伪代码中从时间戳 + Duration 计算时间戳。
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 表示形式是一个 String
,它以 s
结尾以指示秒,并且前面是秒数,纳秒表示为秒的小数。
字段名称 | Type | 描述 |
---|---|---|
seconds | int64 | 时间跨度的有符号秒数。必须在 -315,576,000,000 到 +315,576,000,000 之间,包括端点。 |
nanos | int32 | 时间跨度的纳秒分辨率的秒的有符号小数。小于 1 秒的持续时间用 0 seconds 字段和正或负 nanos 字段表示。对于 1 秒或更长时间的持续时间,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 | Option | 协议缓冲区选项。 |
source_context | SourceContext | 源上下文。 |
syntax | Syntax | 源语法。 |
EnumValue
枚举值定义。
字段名称 | Type | 描述 |
---|---|---|
name | string | 枚举值名称。 |
number | int32 | 枚举值编号。 |
options | Option | 协议缓冲区选项。 |
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 | 是否使用备用打包线路表示形式。 |
options | Option | 协议缓冲区选项。 |
json_name | string | 字段 JSON 名称。 |
default_value | string | 此字段的默认值的字符串值。仅限 Proto2 语法。 |
Cardinality
字段是可选的、必需的还是重复的。
枚举值 | 描述 |
---|---|
CARDINALITY_UNKNOWN | 对于基数未知的字段。 |
CARDINALITY_OPTIONAL | 对于可选字段。 |
CARDINALITY_REQUIRED | 对于必需字段。仅限 Proto2 语法。 |
CARDINALITY_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 操作(projection)返回或由 update 操作修改的字段子集。字段掩码还具有自定义 JSON 编码(请参见下文)。
投影中的字段掩码
当 FieldMask
指定 projection 时,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 中,字段掩码编码为单个字符串,其中路径用逗号分隔。每个路径中的字段名称都转换为/从 lower-camel 命名约定转换而来。
作为示例,请考虑以下消息声明
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 | Option | 附加到该方法的任何元数据。 |
syntax | Syntax | 此方法的源语法。 |
Mixin
声明要包含在此 API 中的 API。包含 API 必须重新声明包含 API 中的所有方法,但是文档和选项的继承方式如下
如果在剥离注释和空格后,重新声明的方法的文档字符串为空,则将从原始方法继承。
将继承服务配置(http,可见性)的每个注释,这些注释未在重新声明的方法中设置。
如果继承了 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
类型联合的空值。
NullValue
的 JSON 表示形式是 JSON null
。
枚举值 | 描述 |
---|---|
NULL_VALUE | 空值。 |
Option
协议缓冲区选项,可以附加到消息、字段、枚举等。
字段名称 | 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 | string 值。 |
Struct
Struct
表示结构化数据值,由映射到动态类型值的字段组成。在某些语言中,Struct
可能受本机表示形式支持。例如,在 JS 等脚本语言中,结构表示为对象。该表示形式的详细信息与该语言的 proto 支持一起描述。
Struct
的 JSON 表示形式是 JSON 对象。
字段名称 | Type | 描述 |
---|---|---|
fields | map<string, Value> | 动态类型值的映射。 |
Syntax
定义协议缓冲区元素的语法。
枚举值 | 描述 |
---|---|
SYNTAX_PROTO2 | 语法 proto2 。 |
SYNTAX_PROTO3 | 语法 proto3 。 |
Timestamp
Timestamp 表示独立于任何时区或日历的时间点,以 UTC Epoch 时间的纳秒分辨率的秒和秒的小数表示。它使用 Proleptic Gregorian Calendar 进行编码,该日历将 Gregorian 日历向后扩展到一年。它被编码为假定所有分钟均为 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 位数字,即高达 1 纳秒分辨率)是可选的。“Z”后缀表示时区(“UTC”);时区是必需的。proto3 JSON 序列化器在打印 Timestamp 类型时应始终使用 UTC(如“Z”所示),并且 proto3 JSON 解析器应能够接受 UTC 和其他时区(如偏移量所示)。
示例 1:从 POSIX time()
计算时间戳。
Timestamp timestamp;
timestamp.set_seconds(time(NULL));
timestamp.set_nanos(0);
示例 2:从 POSIX gettimeofday()
计算时间戳。
struct timeval tv;
gettimeofday(&tv, NULL);
Timestamp timestamp;
timestamp.set_seconds(tv.tv_sec);
timestamp.set_nanos(tv.tv_usec * 1000);
示例 3:从 Win32 GetSystemTimeAsFileTime()
计算时间戳。
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()
计算时间戳。
long millis = System.currentTimeMillis();
Timestamp timestamp = Timestamp.newBuilder().setSeconds(millis / 1000)
.setNanos((int) ((millis % 1000) * 1000000)).build();
示例 5:从 Python 中的当前时间计算时间戳。
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 | 纳秒分辨率的秒的非负小数。具有小数的负秒值仍然必须具有向前计时的非负纳秒值。必须在 0 到 999,999,999 之间,包括端点。 |
Type
协议缓冲区消息类型。
字段名称 | Type | 描述 |
---|---|---|
name | string | 完全限定的消息名称。 |
fields | Field | 字段列表。 |
oneofs | string | 此类型的 oneof 定义中出现的类型列表。 |
options | Option | 协议缓冲区选项。 |
source_context | SourceContext | 源上下文。 |
syntax | 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 | 表示空值。 |
number_value | double | 表示双精度值。请注意,尝试序列化 NaN 或 Infinity 会导致错误。(我们不能像对常规字段那样将它们序列化为字符串“NaN”或“Infinity”值,因为它们将被解析为 string_value,而不是 number_value)。 |
string_value | string | 表示字符串值。 |
bool_value | bool | 表示布尔值。 |
struct_value | Struct | 表示结构化值。 |
list_value | ListValue | 表示重复的 Value 。 |