github.com/jhump/protoreflect@v1.16.0/dynamic/json_test.go (about)

     1  package dynamic
     2  
     3  import (
     4  	"bytes"
     5  	"fmt"
     6  	"io/ioutil"
     7  	"reflect"
     8  	"strings"
     9  	"testing"
    10  	"time"
    11  
    12  	"github.com/golang/protobuf/jsonpb"
    13  	"github.com/golang/protobuf/proto"
    14  	"github.com/golang/protobuf/ptypes"
    15  	"google.golang.org/protobuf/types/descriptorpb"
    16  	"google.golang.org/protobuf/types/known/anypb"
    17  	"google.golang.org/protobuf/types/known/durationpb"
    18  	"google.golang.org/protobuf/types/known/structpb"
    19  	"google.golang.org/protobuf/types/known/timestamppb"
    20  	"google.golang.org/protobuf/types/known/wrapperspb"
    21  
    22  	"github.com/jhump/protoreflect/desc"
    23  	"github.com/jhump/protoreflect/internal/testprotos"
    24  	"github.com/jhump/protoreflect/internal/testutil"
    25  )
    26  
    27  func TestJSONUnaryFields(t *testing.T) {
    28  	jsonTranslationParty(t, unaryFieldsPosMsg, false)
    29  	jsonTranslationParty(t, unaryFieldsNegMsg, false)
    30  	jsonTranslationParty(t, unaryFieldsPosInfMsg, false)
    31  	jsonTranslationParty(t, unaryFieldsNegInfMsg, false)
    32  	jsonTranslationParty(t, unaryFieldsNanMsg, true)
    33  }
    34  
    35  func TestJSONRepeatedFields(t *testing.T) {
    36  	jsonTranslationParty(t, repeatedFieldsMsg, false)
    37  	jsonTranslationParty(t, repeatedFieldsInfNanMsg, true)
    38  }
    39  
    40  func TestJSONMapKeyFields(t *testing.T) {
    41  	jsonTranslationParty(t, mapKeyFieldsMsg, false)
    42  }
    43  
    44  func TestJSONMapValueFields(t *testing.T) {
    45  	jsonTranslationParty(t, mapValueFieldsMsg, false)
    46  	jsonTranslationParty(t, mapValueFieldsInfNanMsg, true)
    47  	jsonTranslationParty(t, mapValueFieldsNilMsg, false)
    48  	jsonTranslationParty(t, mapValueFieldsNilUnknownMsg, false)
    49  }
    50  
    51  func TestJSONExtensionFields(t *testing.T) {
    52  	// TODO
    53  }
    54  
    55  func createTestFileDescriptor(t *testing.T, packageName string) *desc.FileDescriptor {
    56  	// Create a new type that could only be resolved via custom resolver
    57  	// because it does not exist in compiled form
    58  	fdp := descriptorpb.FileDescriptorProto{
    59  		Name:       proto.String(fmt.Sprintf("%s.proto", packageName)),
    60  		Dependency: []string{"google/protobuf/any.proto"},
    61  		Package:    proto.String(packageName),
    62  		MessageType: []*descriptorpb.DescriptorProto{
    63  			{
    64  				Name: proto.String("MyMessage"),
    65  				Field: []*descriptorpb.FieldDescriptorProto{
    66  					{
    67  						Name:   proto.String("abc"),
    68  						Number: proto.Int(1),
    69  						Label:  descriptorpb.FieldDescriptorProto_LABEL_OPTIONAL.Enum(),
    70  						Type:   descriptorpb.FieldDescriptorProto_TYPE_STRING.Enum(),
    71  					},
    72  					{
    73  						Name:   proto.String("def"),
    74  						Number: proto.Int(2),
    75  						Label:  descriptorpb.FieldDescriptorProto_LABEL_OPTIONAL.Enum(),
    76  						Type:   descriptorpb.FieldDescriptorProto_TYPE_INT32.Enum(),
    77  					},
    78  					{
    79  						Name:     proto.String("ghi"),
    80  						Number:   proto.Int(3),
    81  						Label:    descriptorpb.FieldDescriptorProto_LABEL_REPEATED.Enum(),
    82  						Type:     descriptorpb.FieldDescriptorProto_TYPE_MESSAGE.Enum(),
    83  						TypeName: proto.String(".google.protobuf.Any"),
    84  					},
    85  				},
    86  			},
    87  		},
    88  	}
    89  	anyfd, err := desc.LoadFileDescriptor("google/protobuf/any.proto")
    90  	testutil.Ok(t, err)
    91  	fd, err := desc.CreateFileDescriptor(&fdp, anyfd)
    92  	testutil.Ok(t, err)
    93  	return fd
    94  }
    95  
    96  func TestJSONAnyResolver(t *testing.T) {
    97  	fd1 := createTestFileDescriptor(t, "foobar")
    98  	fd2 := createTestFileDescriptor(t, "snafu")
    99  	md := fd1.FindMessage("foobar.MyMessage")
   100  	dm := NewMessage(md)
   101  	dm.SetFieldByNumber(1, "fubar")
   102  	dm.SetFieldByNumber(2, int32(123))
   103  	a1, err := ptypes.MarshalAny(dm)
   104  	testutil.Ok(t, err)
   105  	md = fd2.FindMessage("snafu.MyMessage")
   106  	dm = NewMessage(md)
   107  	dm.SetFieldByNumber(1, "snafu")
   108  	dm.SetFieldByNumber(2, int32(456))
   109  	a2, err := ptypes.MarshalAny(dm)
   110  	testutil.Ok(t, err)
   111  
   112  	msg := &testprotos.TestWellKnownTypes{Extras: []*anypb.Any{a1, a2}}
   113  	resolver := AnyResolver(nil, fd1, fd2)
   114  
   115  	jsm := jsonpb.Marshaler{AnyResolver: resolver}
   116  	js, err := jsm.MarshalToString(msg)
   117  	testutil.Ok(t, err)
   118  	expected := `{"extras":[{"@type":"type.googleapis.com/foobar.MyMessage","abc":"fubar","def":123},{"@type":"type.googleapis.com/snafu.MyMessage","abc":"snafu","def":456}]}`
   119  	testutil.Eq(t, expected, js)
   120  
   121  	jsu := jsonpb.Unmarshaler{AnyResolver: resolver}
   122  	msg2 := &testprotos.TestWellKnownTypes{}
   123  	err = jsu.Unmarshal(strings.NewReader(js), msg2)
   124  	testutil.Ok(t, err)
   125  
   126  	testutil.Ceq(t, msg, msg2, eqpm)
   127  }
   128  
   129  func TestJSONAnyResolver_AutomaticForDynamicMessage(t *testing.T) {
   130  	// marshaling and unmarshaling a dynamic message automatically enables
   131  	// resolving Any messages for known types (a known type is one that is
   132  	// in the dynamic message's file descriptor or that file's transitive
   133  	// dependencies)
   134  	fd := createTestFileDescriptor(t, "foobar")
   135  	md := fd.FindMessage("foobar.MyMessage")
   136  	dm := NewMessageFactoryWithDefaults().NewMessage(md).(*Message)
   137  	dm.SetFieldByNumber(1, "fubar")
   138  	dm.SetFieldByNumber(2, int32(123))
   139  	a1, err := ptypes.MarshalAny(dm)
   140  	testutil.Ok(t, err)
   141  	dm.SetFieldByNumber(1, "snafu")
   142  	dm.SetFieldByNumber(2, int32(456))
   143  	a2, err := ptypes.MarshalAny(dm)
   144  	testutil.Ok(t, err)
   145  	dm.SetFieldByNumber(1, "xyz")
   146  	dm.SetFieldByNumber(2, int32(-987))
   147  	dm.SetFieldByNumber(3, []*anypb.Any{a1, a2})
   148  
   149  	js, err := dm.MarshalJSON()
   150  	testutil.Ok(t, err)
   151  	expected := `{"abc":"xyz","def":-987,"ghi":[{"@type":"type.googleapis.com/foobar.MyMessage","abc":"fubar","def":123},{"@type":"type.googleapis.com/foobar.MyMessage","abc":"snafu","def":456}]}`
   152  	testutil.Eq(t, expected, string(js))
   153  
   154  	dm2 := NewMessageFactoryWithDefaults().NewMessage(md).(*Message)
   155  	err = dm2.UnmarshalJSON(js)
   156  	testutil.Ok(t, err)
   157  
   158  	testutil.Ceq(t, dm, dm2, eqdm)
   159  }
   160  
   161  func TestMarshalJSONEmitDefaults(t *testing.T) {
   162  	md, err := desc.LoadMessageDescriptorForMessage((*testprotos.ReallySimpleMessage)(nil))
   163  	testutil.Ok(t, err)
   164  	dm := NewMessage(md)
   165  	js, err := dm.MarshalJSON()
   166  	testutil.Ok(t, err)
   167  	testutil.Eq(t, `{}`, string(js))
   168  	jsDefaults, err := dm.MarshalJSONPB(&jsonpb.Marshaler{EmitDefaults: true})
   169  	testutil.Ok(t, err)
   170  	testutil.Eq(t, `{"id":"0","name":""}`, string(jsDefaults))
   171  }
   172  
   173  func TestMarshalJSONEmitDefaultsMapKeyFields(t *testing.T) {
   174  	md, err := desc.LoadMessageDescriptorForMessage((*testprotos.MapKeyFields)(nil))
   175  	testutil.Ok(t, err)
   176  	dm := NewMessage(md)
   177  	m := &jsonpb.Marshaler{EmitDefaults: true}
   178  	jsDefaults, err := dm.MarshalJSONPB(m)
   179  	testutil.Ok(t, err)
   180  	testutil.Eq(t, `{"i":{},"j":{},"k":{},"l":{},"m":{},"n":{},"o":{},"p":{},"q":{},"r":{},"s":{},"t":{}}`, string(jsDefaults))
   181  
   182  	jsDefaults2, err := m.MarshalToString(&testprotos.MapKeyFields{})
   183  	testutil.Ok(t, err)
   184  	testutil.Eq(t, string(jsDefaults), string(jsDefaults2))
   185  }
   186  
   187  func TestMarshalJSONEmitDefaultsOneOfFields(t *testing.T) {
   188  	// we don't include default values for fields in a one-of
   189  	// since it would not round-trip correctly
   190  	testCases := []struct {
   191  		msg          *testprotos.OneOfMessage
   192  		expectedJson string
   193  	}{
   194  		{
   195  			msg:          &testprotos.OneOfMessage{},
   196  			expectedJson: `{}`,
   197  		},
   198  		{
   199  			msg:          &testprotos.OneOfMessage{Value: &testprotos.OneOfMessage_IntValue{IntValue: 12345}},
   200  			expectedJson: `{"intValue":12345}`,
   201  		},
   202  		{
   203  			msg:          &testprotos.OneOfMessage{Value: &testprotos.OneOfMessage_StringValue{StringValue: "foobar"}},
   204  			expectedJson: `{"stringValue":"foobar"}`,
   205  		},
   206  		{
   207  			msg:          &testprotos.OneOfMessage{Value: &testprotos.OneOfMessage_MsgValue{MsgValue: &testprotos.OneOfMessage{}}},
   208  			expectedJson: `{"msgValue":{}}`,
   209  		},
   210  		{
   211  			msg:          &testprotos.OneOfMessage{Value: &testprotos.OneOfMessage_MsgValue{MsgValue: nil}},
   212  			expectedJson: `{"msgValue":null}`,
   213  		},
   214  	}
   215  	m := &jsonpb.Marshaler{EmitDefaults: true}
   216  	for _, testCase := range testCases {
   217  		dm, err := AsDynamicMessageWithMessageFactory(testCase.msg, NewMessageFactoryWithDefaults())
   218  		testutil.Ok(t, err)
   219  		asJson, err := dm.MarshalJSONPB(m)
   220  		testutil.Ok(t, err)
   221  		actualJson := string(asJson)
   222  		testutil.Eq(t, testCase.expectedJson, actualJson)
   223  
   224  		// round-trip
   225  		err = jsonpb.UnmarshalString(actualJson, dm)
   226  		testutil.Ok(t, err)
   227  		var roundtripped testprotos.OneOfMessage
   228  		err = dm.ConvertTo(&roundtripped)
   229  		testutil.Ok(t, err)
   230  		testutil.Ceq(t, testCase.msg, &roundtripped, eqpm)
   231  	}
   232  }
   233  
   234  func TestMarshalJSONEnumsAsInts(t *testing.T) {
   235  	md, err := desc.LoadMessageDescriptorForMessage((*testprotos.TestRequest)(nil))
   236  	testutil.Ok(t, err)
   237  	dm := NewMessage(md)
   238  	dm.SetFieldByNumber(1, []int32{1})
   239  	dm.SetFieldByNumber(2, "bedazzle")
   240  	js, err := dm.MarshalJSONPB(&jsonpb.Marshaler{EnumsAsInts: true})
   241  	testutil.Ok(t, err)
   242  	testutil.Eq(t, `{"foo":[1],"bar":"bedazzle"}`, string(js))
   243  }
   244  
   245  func TestMarshalJSONOrigName(t *testing.T) {
   246  	// TODO
   247  }
   248  
   249  func TestMarshalJSONIndent(t *testing.T) {
   250  	md, err := desc.LoadMessageDescriptorForMessage((*testprotos.TestRequest)(nil))
   251  	testutil.Ok(t, err)
   252  	dm := NewMessage(md)
   253  	dm.SetFieldByNumber(1, []int32{1})
   254  	dm.SetFieldByNumber(2, "bedazzle")
   255  	js, err := dm.MarshalJSON()
   256  	testutil.Ok(t, err)
   257  	testutil.Eq(t, `{"foo":["VALUE1"],"bar":"bedazzle"}`, string(js))
   258  	jsIndent, err := dm.MarshalJSONIndent()
   259  	testutil.Ok(t, err)
   260  	testutil.Eq(t, `{
   261    "foo": [
   262      "VALUE1"
   263    ],
   264    "bar": "bedazzle"
   265  }`, string(jsIndent))
   266  	jsIndent, err = dm.MarshalJSONPB(&jsonpb.Marshaler{Indent: "\t"})
   267  	testutil.Ok(t, err)
   268  	testutil.Eq(t, `{
   269  	"foo": [
   270  		"VALUE1"
   271  	],
   272  	"bar": "bedazzle"
   273  }`, string(jsIndent))
   274  }
   275  
   276  func TestMarshalJSONIndentEmbedWellKnownTypes(t *testing.T) {
   277  	// testing the formatting of dynamic message that embeds non-dynamic message,
   278  	// both those w/ special/simple JSON encoding (like timestamp) and those with
   279  	// more structure (Any).
   280  	md, err := desc.LoadMessageDescriptorForMessage((*testprotos.TestWellKnownTypes)(nil))
   281  	testutil.Ok(t, err)
   282  	dm := NewMessage(md)
   283  
   284  	ts, err := ptypes.TimestampProto(time.Date(2010, 3, 4, 5, 6, 7, 809000, time.UTC))
   285  	testutil.Ok(t, err)
   286  	dm.SetFieldByNumber(1, ts)
   287  
   288  	anys := make([]*anypb.Any, 3)
   289  	anys[0], err = ptypes.MarshalAny(&testprotos.TestRequest{Bar: "foo"})
   290  	testutil.Ok(t, err)
   291  	anys[1], err = ptypes.MarshalAny(&testprotos.TestRequest{Bar: "bar"})
   292  	testutil.Ok(t, err)
   293  	anys[2], err = ptypes.MarshalAny(&testprotos.TestRequest{Bar: "baz"})
   294  	testutil.Ok(t, err)
   295  	dm.SetFieldByNumber(13, anys)
   296  
   297  	js, err := dm.MarshalJSON()
   298  	testutil.Ok(t, err)
   299  	testutil.Eq(t, `{"startTime":"2010-03-04T05:06:07.000809Z","extras":[{"@type":"type.googleapis.com/testprotos.TestRequest","bar":"foo"},{"@type":"type.googleapis.com/testprotos.TestRequest","bar":"bar"},{"@type":"type.googleapis.com/testprotos.TestRequest","bar":"baz"}]}`, string(js))
   300  	jsIndent, err := dm.MarshalJSONIndent()
   301  	testutil.Ok(t, err)
   302  	testutil.Eq(t, `{
   303    "startTime": "2010-03-04T05:06:07.000809Z",
   304    "extras": [
   305      {
   306        "@type": "type.googleapis.com/testprotos.TestRequest",
   307        "bar": "foo"
   308      },
   309      {
   310        "@type": "type.googleapis.com/testprotos.TestRequest",
   311        "bar": "bar"
   312      },
   313      {
   314        "@type": "type.googleapis.com/testprotos.TestRequest",
   315        "bar": "baz"
   316      }
   317    ]
   318  }`, string(jsIndent))
   319  	jsIndent, err = dm.MarshalJSONPB(&jsonpb.Marshaler{Indent: "\t"})
   320  	testutil.Ok(t, err)
   321  	testutil.Eq(t, `{
   322  	"startTime": "2010-03-04T05:06:07.000809Z",
   323  	"extras": [
   324  		{
   325  			"@type": "type.googleapis.com/testprotos.TestRequest",
   326  			"bar": "foo"
   327  		},
   328  		{
   329  			"@type": "type.googleapis.com/testprotos.TestRequest",
   330  			"bar": "bar"
   331  		},
   332  		{
   333  			"@type": "type.googleapis.com/testprotos.TestRequest",
   334  			"bar": "baz"
   335  		}
   336  	]
   337  }`, string(jsIndent))
   338  }
   339  
   340  func TestUnmarshalJSONAllowUnknownFields(t *testing.T) {
   341  	md, err := desc.LoadMessageDescriptorForMessage((*testprotos.TestRequest)(nil))
   342  	testutil.Ok(t, err)
   343  	js := []byte(`{"foo":["VALUE1"],"bar":"bedazzle","xxx": 1}`)
   344  	dm := NewMessage(md)
   345  	err = dm.UnmarshalJSON(js)
   346  	testutil.Nok(t, err)
   347  	unmarshaler := &jsonpb.Unmarshaler{AllowUnknownFields: true}
   348  	err = dm.UnmarshalJSONPB(unmarshaler, js)
   349  	testutil.Ok(t, err)
   350  	foo := dm.GetFieldByNumber(1)
   351  	bar := dm.GetFieldByNumber(2)
   352  	testutil.Eq(t, []int32{1}, foo)
   353  	testutil.Eq(t, "bedazzle", bar)
   354  }
   355  
   356  func TestUnmarshalJSONValueFromList(t *testing.T) {
   357  	js := `{"list":[1,2,3]}`
   358  	md, err := desc.LoadMessageDescriptorForMessage((*testprotos.SimpleValue)(nil))
   359  	testutil.Ok(t, err)
   360  	dm := NewMessage(md)
   361  	testutil.Ok(t, err)
   362  	unmarshaler := &jsonpb.Unmarshaler{}
   363  	err = dm.UnmarshalJSONPB(unmarshaler, []byte(js))
   364  	testutil.Ok(t, err)
   365  	msg := reflect.New(reflect.TypeOf(&testprotos.SimpleValue{}).Elem()).Interface().(proto.Message)
   366  	err = unmarshaler.Unmarshal(strings.NewReader(js), msg)
   367  	testutil.Ok(t, err)
   368  	dm2 := NewMessage(md)
   369  	err = dm2.ConvertFrom(msg)
   370  	testutil.Ok(t, err)
   371  	testutil.Ceq(t, dm2, dm, eqpm)
   372  }
   373  
   374  func TestJSONWellKnownType(t *testing.T) {
   375  	any1, err := ptypes.MarshalAny(&testprotos.TestRequest{
   376  		Foo: []testprotos.Proto3Enum{testprotos.Proto3Enum_VALUE1, testprotos.Proto3Enum_VALUE2},
   377  		Bar: "bar",
   378  		Baz: &testprotos.TestMessage{Ne: []testprotos.TestMessage_NestedEnum{testprotos.TestMessage_VALUE1}},
   379  	})
   380  	testutil.Ok(t, err)
   381  	any2, err := ptypes.MarshalAny(ptypes.TimestampNow())
   382  	testutil.Ok(t, err)
   383  
   384  	wkts := &testprotos.TestWellKnownTypes{
   385  		StartTime: &timestamppb.Timestamp{Seconds: 1010101, Nanos: 20202},
   386  		Elapsed:   &durationpb.Duration{Seconds: 30303, Nanos: 40404},
   387  		Dbl:       &wrapperspb.DoubleValue{Value: 3.14159},
   388  		Flt:       &wrapperspb.FloatValue{Value: -1.0101010},
   389  		Bl:        &wrapperspb.BoolValue{Value: true},
   390  		I32:       &wrapperspb.Int32Value{Value: -42},
   391  		I64:       &wrapperspb.Int64Value{Value: -9090909090},
   392  		U32:       &wrapperspb.UInt32Value{Value: 42},
   393  		U64:       &wrapperspb.UInt64Value{Value: 9090909090},
   394  		Str:       &wrapperspb.StringValue{Value: "foobar"},
   395  		Byt:       &wrapperspb.BytesValue{Value: []byte("snafu")},
   396  		Json: []*structpb.Value{
   397  			{Kind: &structpb.Value_BoolValue{BoolValue: true}},
   398  			{Kind: &structpb.Value_ListValue{ListValue: &structpb.ListValue{Values: []*structpb.Value{
   399  				{Kind: &structpb.Value_NullValue{}},
   400  				{Kind: &structpb.Value_StringValue{StringValue: "fubar"}},
   401  				{Kind: &structpb.Value_NumberValue{NumberValue: 10101.20202}},
   402  			}}}},
   403  			{Kind: &structpb.Value_StructValue{StructValue: &structpb.Struct{Fields: map[string]*structpb.Value{
   404  				"foo": {Kind: &structpb.Value_NullValue{}},
   405  				"bar": {Kind: &structpb.Value_StringValue{StringValue: "snafu"}},
   406  				"baz": {Kind: &structpb.Value_NumberValue{NumberValue: 30303.40404}},
   407  			}}}},
   408  		},
   409  		Extras: []*anypb.Any{any1, any2},
   410  	}
   411  
   412  	jsm := jsonpb.Marshaler{}
   413  	js, err := jsm.MarshalToString(wkts)
   414  	testutil.Ok(t, err)
   415  
   416  	md, err := desc.LoadMessageDescriptorForMessage(wkts)
   417  	testutil.Ok(t, err)
   418  	dm := NewMessage(md)
   419  	err = dm.UnmarshalJSON([]byte(js))
   420  	testutil.Ok(t, err)
   421  
   422  	// check that the unmarshalled fields were constructed correctly with the
   423  	// right value and type (e.g. generated well-known-type, not dynamic message)
   424  	ts, ok := dm.GetFieldByNumber(1).(*timestamppb.Timestamp)
   425  	testutil.Require(t, ok)
   426  	testutil.Ceq(t, wkts.StartTime, ts, eqpm)
   427  
   428  	dur, ok := dm.GetFieldByNumber(2).(*durationpb.Duration)
   429  	testutil.Require(t, ok)
   430  	testutil.Ceq(t, wkts.Elapsed, dur, eqpm)
   431  
   432  	dbl, ok := dm.GetFieldByNumber(3).(*wrapperspb.DoubleValue)
   433  	testutil.Require(t, ok)
   434  	testutil.Eq(t, wkts.Dbl.Value, dbl.Value)
   435  
   436  	flt, ok := dm.GetFieldByNumber(4).(*wrapperspb.FloatValue)
   437  	testutil.Require(t, ok)
   438  	testutil.Eq(t, wkts.Flt.Value, flt.Value)
   439  
   440  	bl, ok := dm.GetFieldByNumber(5).(*wrapperspb.BoolValue)
   441  	testutil.Require(t, ok)
   442  	testutil.Eq(t, wkts.Bl.Value, bl.Value)
   443  
   444  	i32, ok := dm.GetFieldByNumber(6).(*wrapperspb.Int32Value)
   445  	testutil.Require(t, ok)
   446  	testutil.Eq(t, wkts.I32.Value, i32.Value)
   447  
   448  	i64, ok := dm.GetFieldByNumber(7).(*wrapperspb.Int64Value)
   449  	testutil.Require(t, ok)
   450  	testutil.Eq(t, wkts.I64.Value, i64.Value)
   451  
   452  	u32, ok := dm.GetFieldByNumber(8).(*wrapperspb.UInt32Value)
   453  	testutil.Require(t, ok)
   454  	testutil.Eq(t, wkts.U32.Value, u32.Value)
   455  
   456  	u64, ok := dm.GetFieldByNumber(9).(*wrapperspb.UInt64Value)
   457  	testutil.Require(t, ok)
   458  	testutil.Eq(t, wkts.U64.Value, u64.Value)
   459  
   460  	str, ok := dm.GetFieldByNumber(10).(*wrapperspb.StringValue)
   461  	testutil.Require(t, ok)
   462  	testutil.Eq(t, wkts.Str.Value, str.Value)
   463  
   464  	byt, ok := dm.GetFieldByNumber(11).(*wrapperspb.BytesValue)
   465  	testutil.Require(t, ok)
   466  	testutil.Eq(t, wkts.Byt.Value, byt.Value)
   467  
   468  	vals, ok := dm.GetFieldByNumber(12).([]interface{})
   469  	testutil.Require(t, ok)
   470  	testutil.Eq(t, len(wkts.Json), len(vals))
   471  	for i := range vals {
   472  		v, ok := vals[i].(*structpb.Value)
   473  		testutil.Require(t, ok)
   474  		testutil.Ceq(t, wkts.Json[i], v, eqpm)
   475  	}
   476  
   477  	extras, ok := dm.GetFieldByNumber(13).([]interface{})
   478  	testutil.Require(t, ok)
   479  	testutil.Eq(t, len(wkts.Extras), len(extras))
   480  	for i := range extras {
   481  		v, ok := extras[i].(*anypb.Any)
   482  		testutil.Require(t, ok)
   483  		testutil.Eq(t, wkts.Extras[i].TypeUrl, v.TypeUrl)
   484  		testutil.Eq(t, wkts.Extras[i].Value, v.Value)
   485  	}
   486  }
   487  
   488  func TestJSONWellKnownTypeFromFileDescriptorSet(t *testing.T) {
   489  	// TODO: generalize this so it tests all well-known types, not just duration
   490  
   491  	data, err := ioutil.ReadFile("../internal/testprotos/duration.protoset")
   492  	testutil.Ok(t, err)
   493  	fds := &descriptorpb.FileDescriptorSet{}
   494  	err = proto.Unmarshal(data, fds)
   495  	testutil.Ok(t, err)
   496  	fd, err := desc.CreateFileDescriptorFromSet(fds)
   497  	testutil.Ok(t, err)
   498  	md := fd.FindMessage("google.protobuf.Duration")
   499  	testutil.Neq(t, nil, md)
   500  
   501  	dur := &durationpb.Duration{Seconds: 30303, Nanos: 40404}
   502  
   503  	// marshal duration to JSON
   504  	jsm := jsonpb.Marshaler{}
   505  	js, err := jsm.MarshalToString(dur)
   506  	testutil.Ok(t, err)
   507  
   508  	// make sure we can unmarshal it
   509  	dm := NewMessage(md)
   510  	err = dm.UnmarshalJSON([]byte(js))
   511  	testutil.Ok(t, err)
   512  
   513  	// and then marshal it again with same output as original
   514  	dynJs, err := jsm.MarshalToString(dm)
   515  	testutil.Ok(t, err)
   516  	testutil.Eq(t, js, dynJs)
   517  }
   518  
   519  func jsonTranslationParty(t *testing.T, msg proto.Message, includesNaN bool) {
   520  	doTranslationParty(t, msg,
   521  		func(pm proto.Message) ([]byte, error) {
   522  			m := jsonpb.Marshaler{}
   523  			var b bytes.Buffer
   524  			err := m.Marshal(&b, pm)
   525  			if err != nil {
   526  				return nil, err
   527  			} else {
   528  				return b.Bytes(), nil
   529  			}
   530  		},
   531  		func(b []byte, pm proto.Message) error {
   532  			return jsonpb.Unmarshal(bytes.NewReader(b), pm)
   533  		},
   534  		(*Message).MarshalJSON, (*Message).UnmarshalJSON, includesNaN, true, true)
   535  }