1

I have a dynamic proto created using jhump/protoreflect. When I try to marshal the proto object using gogo jsonpb I end up with below mentioned error.

Code:

import "github.com/gogo/protobuf/types"

...

p := protoparse.Parser{
    Accessor: protoparse.FileContentsFromMap(map[string]string{
        "foo/bar.proto": `
            syntax = "proto3";
            package foo;
            message Bar {
                string name = 1;
                int32 id = 2;
            }
            `,
    }),
    ImportPaths: []string{"foo"},
}
fds, err := p.ParseFilesButDoNotLink("foo/bar.proto")
if err != nil {
    return nil, err
}
linkedFiles, err := desc.CreateFileDescriptors(fds)
if err != nil {
    return nil, err
}
fd := linkedFiles["foo/bar.proto"]
md := fd.FindMessage("foo.Bar")
dm := dynamic.NewMessage(md)

proto.RegisterType((*dynamic.Message)(nil), "foo.Bar")
golang_proto.RegisterType((*dynamic.Message)(nil), "foo.Bar")

dm = dynamic.NewMessage(md)
dm.SetFieldByNumber(1, "kishore")
dm.SetFieldByNumber(2, int32(123))

a1, err := types.MarshalAny(dm)
if err != nil {
    return nil, err
}
fmt.Printf("Create Any Marshalled Data is : %v\n", a1)

resp := &data.CreateAnyResponse{Object: a1}
fmt.Printf("Final Resp is : %v\n", resp)

resolver := dynamic.AnyResolver(nil, fd)
golangMarshaller := golang_jsonpb.Marshaler{AnyResolver: resolver}
js1, err := golangMarshaller.MarshalToString(resp)
if err != nil {
    fmt.Printf("Error is is : %v\n", err)
    return nil, err
}
fmt.Printf("After Marshal Resp1 is : %v\n", js1)

So far it works and prints After Marshal Resp1 is : {"object":{"@type":"type.googleapis.com/foo.Bar","id":123,"name":"kishore"}} as all objects are defined as Go protobuf. However when I try similar approach using gogo marshaler (As my grpc runtime uses gogo), I get below mentioned error.

jsm := &gateway.JSONPb{
    OrigName:     true,
    EnumsAsInts:  false,
    EmitDefaults: true,
    AnyResolver:  resolver,
}
js, err := jsm.Marshal(resp)
if err != nil {
    fmt.Printf("Error is is : %v\n", err)
    return nil, err
}
fmt.Printf("After Marshal Resp is : %s\n", string(js))

Error:

cannot use resolver (type "github.com/golang/protobuf/jsonpb".AnyResolver) as type "github.com/gogo/protobuf/jsonpb".AnyResolver in field value:
    "github.com/golang/protobuf/jsonpb".AnyResolver does not implement "github.com/gogo/protobuf/jsonpb".AnyResolver (wrong type for Resolve method)
            have Resolve(string) ("github.com/golang/protobuf/proto".Message, error)
            want Resolve(string) ("github.com/gogo/protobuf/proto".Message, error)

Structure of CreateAnyResponse:

message CreateAnyResponse {
    google.protobuf.Any object = 1;
}

I tried cloning & customizing AnyResolver in my local and using gogo proto.Message, but after Marshalling the data was not marshaled After Marshal Resp is : {"object":{"@type":"type.googleapis.com/foo.Bar"}}

Is there a way to convert these dynamic proto using gogo jsonpb marshaller?

Jonathan Hall
  • 75,165
  • 16
  • 143
  • 189
Kishore Bandi
  • 5,537
  • 2
  • 31
  • 52

0 Answers0