Dynamic types using Any in protobuf and go

1,525 views
Skip to first unread message

Ankur

unread,
Aug 22, 2022, 2:08:26 AM8/22/22
to grpc.io
1. I have created a generic API using Any field. Clients can define any new message in a proto file, and send the data using this API in Any field. The client also shares the proto file to the server beforehand.
Input for API:

message Document {
     DocumentMeta meta = 1;
     bytes data = 2;
     google.protobuf.Any details = 3;
}

2. On server-side, I am trying to register the new MessageType from the shared .proto file in protoregistry.GlobalTypes.

tmp_file := filename + "tmp.pb"
cmd := exec.Command("protoc","--descriptor_set_out=" + tmp_file, "-I"+src_dir,path.Join(src_dir, filename))

protoFile, err := ioutil.ReadFile(tmp_file)
pb_set := new(descriptorpb.FileDescriptorSet)
if err := proto.Unmarshal(protoFile, pb_set); err != nil {
return err
}
pb := pb_set.GetFile()[0]
fd, err := protodesc.NewFile(pb, protoregistry.GlobalFiles)
if err = protoregistry.GlobalFiles.RegisterFile(fd); err != nil {
return err
}
msgType = dynamicpb.NewMessageType(fd.Messages().Get(0))
err = protoregistry.GlobalTypes.RegisterMessage(msgType)

This works fine. Eg: On client side, I created a message named Dog. After registering, I print GlobalTypes in server and it lists
com.test.eventbus.pb.events.Dog

3. From the API input, I convert the Any type to a proto.Message as follows
basic, err := anypb.UnmarshalNew(doc.GetDetails(), proto.UnmarshalOptions{})

UnmarshalNew uses protoregistry.GlobalTypes as default resolver and that is why I am registering Dog type in GlobalTypes

4. From the proto.Message type in step 3 (basic), I want to obtain the schema of the message.
msgV1 := proto.MessageV1(basic)
desc, err := desc.LoadMessageDescriptorForMessage(msgV1)

This fails in LoadMessageDescriptorForMessage with error
error interface conversion: *dynamicpb.Message is not desc.protoMessage: missing method Descriptor

It seems to me either there is some error in Type registration or unmarshalling of actual data. Can someone point out the right way to do this?

Regards



Reply all
Reply to author
Forward
0 new messages