本文并非 Protobuf 的基础、语法介绍,更加关注 Protobuf 的扩展用法以及实际案例基础
这部分可以参考官方文档,proto3的语法在这里只做简要的介绍和整理。
一个 基础Message 的定义如下
syntax = "proto3";
import "other.proto";
message SearchRequest {
string query = 1;
int32 page_number = 2;
int32 result_per_page = 3;
}
[ "repeated" ] type fieldName "=" fieldNumber [ "[" fieldOptions "]" ] ";"
格式定义的"option" optionName "=" constant ";"
, 比如 option java_package = "com.example.foo";
options 有内置也有自定义的。这部分和高级部分关系比较大。google/protobuf/descriptor.proto
找到,不同的 option 和他所在的位置对应。extend
语法,下面给出了一个例子import "google/protobuf/descriptor.proto";
extend google.protobuf.MessageOptions {
optional string my_option = 51234;
}
message MyMessage {
option (my_option) = "Hello world!";
}
// Java 中获取这个 option
value = my_proto_file_pb2.MyMessage.DESCRIPTOR.GetOptions()
.Extensions[my_proto_file_pb2.my_option]
另一个真实的例子,来自 google 的 http 扩展,这里插件会获取 名为 google.api.http 的 option,然后转换为 http 结构
extend google.protobuf.MethodOptions {
// See `HttpRule`.
HttpRule http = 72295728;
}
// 实际使用
service Messaging {
rpc GetMessage(GetMessageRequest) returns (Message) {
option (google.api.http) = {
get:"/v1/messages/{message_id}"
};
}
}
本质上,protobuf 的能力是描述 entity
和 method
,基本上 entity、method 外加一些约定,就可以描述所有的协议了。事实上 google 的 api 定义 基本上都可以都可以找到 protobuf 的描述
这里 protobuf 的描述作用就可以是
甚至,protobuf 能够描述 protobuf 自己。protoc 以及插件的解析 proto 文件原理中最重要的是一个 descriptor 结构,而这个结构也是 protobuf 描述的,这是一个鸡生蛋还是蛋生鸡的关系,事实上,最初的 descriptor 是开发 compile 的开发者手动写的,经过一段时间,再用 protoc 生成 descriptor 文件,用于 protoc 文件 (似乎是一种循环依赖)。
如上所述,google api 中定义了如何将 grpc 映射成 http 的协议,理解这套协议以及实现,是理解扩展 protobuf 的一个很好的出发点。
entity
, 这个 entity比较简单,文件 大部分实在描述映射的协议,以便于实际实现方参考这个描述来实现。google.http.rule
, 比如 option (google.api.http) = {get:"/v1/messages/{message_id}}
gogo-protobuf 是 protoc 的 go 语言插件的实现,在实现特定语言代码生成的基础了,实现了多种 扩展特性,原始的定义在 这里 , 有以下几类
实际实现和一般的 protoc 的插件并无不同,descriptor 结构由 protoc 解析,插件从 descriptor 进一步的解析出 proto 文件结构,以及各种扩展的选项,然后生成go 语言的文件。
以 nullable 这个选项为例,生成语言文件的时候会使用 帮助函数 判断对应 field 是否设置了 Nullable 的 Extension,如果没设置或者设置为True,则生成的结构则带指针,默认值为 nil。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。