Ars*_*ene 1 go protocol-buffers
我有一个包含以下 protomessage 字节片段的文件。
syntax = "proto3";
package main;
message Address {
string street = 1;
string country = 2;
string state = 3;
}
Run Code Online (Sandbox Code Playgroud)
我的消息类型描述如下:
syntax = "proto3";
package main;
message Address {
string street = 1;
string country = 2;
string state = 3;
}
Run Code Online (Sandbox Code Playgroud)
我想知道如何最好地使用jhump/protoreflect使用上面的消息描述符来解析文件的内容。
感谢您的帮助。
小智 5
典型的方法是使用以下命令将协议编译为 Go 代码protoc:
protoc main.proto --go_out=.
Run Code Online (Sandbox Code Playgroud)
这将生成main.pb.go,它将具有一个名为 的类型Address:
var addr Address
err := proto.Unmarshal(bytes, &addr)
Run Code Online (Sandbox Code Playgroud)
如果由于某种原因无法做到这一点(例如,您必须使用描述符动态地进行),则有一些选项。(但它要复杂得多。)
protoc生成的描述符。您可以protoc导出到描述符文件(通过-o标志)。如果这是为了 RPC,让服务器使用服务器反射;然后,您可以使用github.com/jhump/protoreflect/grpcreflect包下载服务器的描述符(大概由 生成protoc)。protoc,我建议使用github.com/jhump/protoreflect/desc/builder包来构建它(而不是尝试手动创建原始原型)。例如,您的原始原型是不够的,因为它们没有 parent FileDescriptorProto,它是任何描述符层次结构的根。该构建器包可以为您处理类似的细节(例如,如果需要,它将合成一个父文件描述符)。无论如何,您想要的描述符是一个desc.Descriptor(来自github.com/jhump/protoreflect/desc包)。上面的提示(使用其他 protoreflect 子包)将返回desc.Descriptor实例。如果您只有原始描述符原型(如在您的示例代码中),您首先要使用desc#CreateFileDescriptor函数将您的*descriptor.FileDescriptorProto变成一个。*desc.FileDescriptor
如果您正在使用protoc它的-o选项来创建描述符集文件(也不要忘记--include_imports标志),您可以加载它并将其转换为*desc.FileDescriptor使用desc#CreateFileDescriptorFromSet函数。下面是一个例子:
bytes, err := ioutil.ReadFile("protoset-from-protoc")
if err != nil {
panic(err)
}
var fileSet descriptor.FileDescriptorSet
if err := proto.Unmarshal(bytes, &fileSet); err != nil {
panic(err)
}
fd, err := desc.CreateFileDescriptorFromSet(&fileSet)
if err != nil {
panic(err)
}
// Now you have a *desc.FileDescriptor in `fd`
Run Code Online (Sandbox Code Playgroud)
一旦你有了那种正确的描述符,你就可以创建一个*dynamic.Message。然后,您可以使用该proto#Unmarshal函数或使用动态消息的Unmarshal方法解组到它。
| 归档时间: |
|
| 查看次数: |
1299 次 |
| 最近记录: |