Closed
Description
Sample proto file
syntax = "proto2";
package pb;
message Foo {
optional google.protobuf.Any iany = 1;
}
Sample code that stores a dynamic message into Foo.iany field.
package test
import (
"strings"
"testing"
"test/pb"
"github.com/golang/protobuf/jsonpb"
"github.com/golang/protobuf/proto"
anypb "github.com/golang/protobuf/ptypes/any"
)
type dynamic struct {
Json []byte `protobuf:"bytes,1,opt,name=json" json:"json,omitempty"`
}
func (d *dynamic) Reset() {
d.Json = nil
}
func (d *dynamic) String() string {
return string(d.Json)
}
func (d *dynamic) ProtoMessage() {}
func (d *dynamic) MarshalJSONPB(_ *jsonpb.Marshaler) ([]byte, error) {
return d.Json, nil
}
func (d *dynamic) UnmarshalJSONPB(_ *jsonpb.Unmarshaler, jstr []byte) error {
d.Json = jstr
return nil
}
func init() {
proto.RegisterType((*dynamic)(nil), "pb.Dynamic")
}
func TestMarshalAnyDynamic(t *testing.T) {
d := &dynamic{Json: []byte(`{"hello": "world"}`)}
b, err := proto.Marshal(d)
if err != nil {
t.Fatal(err)
}
foo := &pb.Foo{
Iany: &anypb.Any{
TypeUrl: "ok.com/pb.Dynamic",
Value: b,
},
}
m := &jsonpb.Marshaler{}
s, err := m.MarshalToString(foo)
if err != nil {
t.Error(err)
} else {
t.Log(s)
}
}
Outputs:
{"iany":{"hello": "world"}}
Per JSON mapping spec (https://developers.google.com/protocol-buffers/docs/proto3#json)
If the Any contains a value that has a special JSON mapping, it will be converted as follows: {"@type": xxx, "value": yyy}. Otherwise, the value will be converted into a JSON object, and the "@type" field will be inserted to indicate the actual data type.
Output is missing "@type" key-value. I'm going to treat dynamic message as the latter case, i.e. not having any special JSON mapping. So, above should have output
{"iany":{"@type":"ok.com/pb.Dynamic", "hello": "dynamic"}}
Metadata
Metadata
Assignees
Labels
No labels