亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

如何使用 github.com/jhump/protoreflect 解析知道消息描述符

如何使用 github.com/jhump/protoreflect 解析知道消息描述符

Go
LEATH 2023-07-04 16:54:37
我有一個文件,其中包含以下原始消息的字節片段。syntax = "proto3";package main;message Address {    string street = 1;    string country = 2;    string state = 3;}我的消息類型描述如下:func GetProtoDescriptor() (*descriptor.DescriptorProto, error) {    return &descriptor.DescriptorProto{        Name: proto.String("Address"),        Field: []*descriptor.FieldDescriptorProto{            &descriptor.FieldDescriptorProto{                Name:     proto.String("street"),                JsonName: proto.String("street"),                Number:   proto.Int(1),                Label:    descriptor.FieldDescriptorProto_LABEL_OPTIONAL.Enum(),                Type:     descriptor.FieldDescriptorProto_TYPE_STRING.Enum(),            },            &descriptor.FieldDescriptorProto{                Name:     proto.String("state"),                JsonName: proto.String("state"),                Number:   proto.Int(2),                Label:    descriptor.FieldDescriptorProto_LABEL_OPTIONAL.Enum(),                Type:     descriptor.FieldDescriptorProto_TYPE_STRING.Enum(),            },            &descriptor.FieldDescriptorProto{                Name:     proto.String("country"),                JsonName: proto.String("country"),                Number:   proto.Int(2),                Label:    descriptor.FieldDescriptorProto_LABEL_OPTIONAL.Enum(),                Type:     descriptor.FieldDescriptorProto_TYPE_STRING.Enum(),            },        },    }, nil}我想知道如何最好地使用jhump/protoreflect使用上面的消息描述符來解析文件的內容。感謝您的幫助。
查看完整描述

1 回答

?
慕森王

TA貢獻1777條經驗 獲得超3個贊

典型的方法是使用以下命令將協議編譯protoc為 Go 代碼:

protoc?main.proto?--go_out=.

這將生成main.pb.go,其類型稱為Address

var?addr?Address
err?:=?proto.Unmarshal(bytes,?&addr)

如果由于某種原因這是不可能的(例如,您必須使用描述符動態地執行此操作),那么還有其他選擇。(但情況要復雜得多。)

  1. 使用protoc生成的描述符。您可以protoc導出到描述符文件(通過-o標志)。如果這是用于 RPC,請讓服務器使用服務器反射;然后,您可以使用github.com/jhump/protoreflect/grpcreflect包下載服務器的描述符(大概由 生成protoc)。

  2. 如果您必須以編程方式創建描述符,而不是使用protoc,我建議使用github.com/jhump/protoreflect/desc/builder包來構造它(而不是嘗試手動創建原始原型)。例如,您的原始原型是不夠的,因為它們沒有parent?FileDescriptorProto,它是任何描述符層次結構的根。該構建器包可以為您處理類似的細節(例如,如果需要,它將合成父文件描述符)。

無論如何,您想要的描述符是 a?desc.Descriptor(來自github.com/jhump/protoreflect/desc包)。上面的提示(使用其他 protoreflect 子包)將返回desc.Descriptor實例。如果您只有原始描述符原型(如示例代碼中所示),您需要首先使用desc#CreateFileDescriptor*descriptor.FileDescriptorProto函數將其轉換為 a?。*desc.FileDescriptor

如果您正在使用protoc及其-o選項來創建描述符集文件(也不要忘記標志),您可以使用desc#CreateFileDescriptorFromSet--include_imports函數加載它并將其轉換為描述符集文件。這是一個例子:*desc.FileDescriptor

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`

一旦有了正確的描述符,您就可以創建一個*dynamic.Message。然后,您可以使用該proto#Unmarshal函數或使用動態消息的Unmarshal方法對其進行解組。


查看完整回答
反對 回復 2023-07-04
  • 1 回答
  • 0 關注
  • 268 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號