github.com/turingchain2020/turingchain@v1.1.21/types/jsonpb/jsonpb_test.go (about)

     1  // Copyright Turing Corp. 2018 All Rights Reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  // Go support for Protocol Buffers - Google's data interchange format
     6  //
     7  // Copyright 2015 The Go Authors.  All rights reserved.
     8  // https://github.com/golang/protobuf
     9  //
    10  // Redistribution and use in source and binary forms, with or without
    11  // modification, are permitted provided that the following conditions are
    12  // met:
    13  //
    14  //     * Redistributions of source code must retain the above copyright
    15  // notice, this list of conditions and the following disclaimer.
    16  //     * Redistributions in binary form must reproduce the above
    17  // copyright notice, this list of conditions and the following disclaimer
    18  // in the documentation and/or other materials provided with the
    19  // distribution.
    20  //     * Neither the name of Google Inc. nor the names of its
    21  // contributors may be used to endorse or promote products derived from
    22  // this software without specific prior written permission.
    23  //
    24  // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    25  // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    26  // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    27  // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    28  // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    29  // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    30  // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    31  // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    32  // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    33  // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    34  // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    35  
    36  package jsonpb
    37  
    38  import (
    39  	"bytes"
    40  	"encoding/json"
    41  	"io"
    42  	"math"
    43  	"reflect"
    44  	"strings"
    45  	"testing"
    46  
    47  	"github.com/golang/protobuf/proto"
    48  
    49  	pb "github.com/golang/protobuf/jsonpb/jsonpb_test_proto"
    50  	proto3pb "github.com/golang/protobuf/proto/proto3_proto"
    51  	"github.com/golang/protobuf/ptypes"
    52  	anypb "github.com/golang/protobuf/ptypes/any"
    53  	durpb "github.com/golang/protobuf/ptypes/duration"
    54  	stpb "github.com/golang/protobuf/ptypes/struct"
    55  	tspb "github.com/golang/protobuf/ptypes/timestamp"
    56  	wpb "github.com/golang/protobuf/ptypes/wrappers"
    57  )
    58  
    59  var (
    60  	marshaler = Marshaler{}
    61  
    62  	marshalerAllOptions = Marshaler{
    63  		Indent: "  ",
    64  	}
    65  
    66  	simpleObject = &pb.Simple{
    67  		OInt32:     proto.Int32(-32),
    68  		OInt32Str:  proto.Int32(-32),
    69  		OInt64:     proto.Int64(-6400000000),
    70  		OInt64Str:  proto.Int64(-6400000000),
    71  		OUint32:    proto.Uint32(32),
    72  		OUint32Str: proto.Uint32(32),
    73  		OUint64:    proto.Uint64(6400000000),
    74  		OUint64Str: proto.Uint64(6400000000),
    75  		OSint32:    proto.Int32(-13),
    76  		OSint32Str: proto.Int32(-13),
    77  		OSint64:    proto.Int64(-2600000000),
    78  		OSint64Str: proto.Int64(-2600000000),
    79  		OFloat:     proto.Float32(3.14),
    80  		OFloatStr:  proto.Float32(3.14),
    81  		ODouble:    proto.Float64(6.02214179e23),
    82  		ODoubleStr: proto.Float64(6.02214179e23),
    83  		OBool:      proto.Bool(true),
    84  		OString:    proto.String("hello \"there\""),
    85  		OBytes:     []byte("beep boop"),
    86  	}
    87  
    88  	simpleObjectInputJSON = `{` +
    89  		`"oBool":true,` +
    90  		`"oInt32":-32,` +
    91  		`"oInt32Str":"-32",` +
    92  		`"oInt64":-6400000000,` +
    93  		`"oInt64Str":"-6400000000",` +
    94  		`"oUint32":32,` +
    95  		`"oUint32Str":"32",` +
    96  		`"oUint64":6400000000,` +
    97  		`"oUint64Str":"6400000000",` +
    98  		`"oSint32":-13,` +
    99  		`"oSint32Str":"-13",` +
   100  		`"oSint64":-2600000000,` +
   101  		`"oSint64Str":"-2600000000",` +
   102  		`"oFloat":3.14,` +
   103  		`"oFloatStr":"3.14",` +
   104  		`"oDouble":6.02214179e+23,` +
   105  		`"oDoubleStr":"6.02214179e+23",` +
   106  		`"oString":"hello \"there\"",` +
   107  		`"oBytes":"0x6265657020626f6f70"` +
   108  		`}`
   109  
   110  	simpleObjectOutputJSON = `{` +
   111  		`"oBool":true,` +
   112  		`"oInt32":-32,` +
   113  		`"oInt32Str":-32,` +
   114  		`"oInt64":"-6400000000",` +
   115  		`"oInt64Str":"-6400000000",` +
   116  		`"oUint32":32,` +
   117  		`"oUint32Str":32,` +
   118  		`"oUint64":"6400000000",` +
   119  		`"oUint64Str":"6400000000",` +
   120  		`"oSint32":-13,` +
   121  		`"oSint32Str":-13,` +
   122  		`"oSint64":"-2600000000",` +
   123  		`"oSint64Str":"-2600000000",` +
   124  		`"oFloat":3.14,` +
   125  		`"oFloatStr":3.14,` +
   126  		`"oDouble":6.02214179e+23,` +
   127  		`"oDoubleStr":6.02214179e+23,` +
   128  		`"oString":"hello \"there\"",` +
   129  		`"oBytes":"0x6265657020626f6f70"` +
   130  		`}`
   131  
   132  	simpleObjectInputPrettyJSON = `{
   133    "oBool": true,
   134    "oInt32": -32,
   135    "oInt32Str": "-32",
   136    "oInt64": -6400000000,
   137    "oInt64Str": "-6400000000",
   138    "oUint32": 32,
   139    "oUint32Str": "32",
   140    "oUint64": 6400000000,
   141    "oUint64Str": "6400000000",
   142    "oSint32": -13,
   143    "oSint32Str": "-13",
   144    "oSint64": -2600000000,
   145    "oSint64Str": "-2600000000",
   146    "oFloat": 3.14,
   147    "oFloatStr": "3.14",
   148    "oDouble": 6.02214179e+23,
   149    "oDoubleStr": "6.02214179e+23",
   150    "oString": "hello \"there\"",
   151    "oBytes": "0x6265657020626f6f70"
   152  }`
   153  
   154  	simpleObjectOutputPrettyJSON = `{
   155    "oBool": true,
   156    "oInt32": -32,
   157    "oInt32Str": -32,
   158    "oInt64": "-6400000000",
   159    "oInt64Str": "-6400000000",
   160    "oUint32": 32,
   161    "oUint32Str": 32,
   162    "oUint64": "6400000000",
   163    "oUint64Str": "6400000000",
   164    "oSint32": -13,
   165    "oSint32Str": -13,
   166    "oSint64": "-2600000000",
   167    "oSint64Str": "-2600000000",
   168    "oFloat": 3.14,
   169    "oFloatStr": 3.14,
   170    "oDouble": 6.02214179e+23,
   171    "oDoubleStr": 6.02214179e+23,
   172    "oString": "hello \"there\"",
   173    "oBytes": "0x6265657020626f6f70"
   174  }`
   175  
   176  	repeatsObject = &pb.Repeats{
   177  		RBool:   []bool{true, false, true},
   178  		RInt32:  []int32{-3, -4, -5},
   179  		RInt64:  []int64{-123456789, -987654321},
   180  		RUint32: []uint32{1, 2, 3},
   181  		RUint64: []uint64{6789012345, 3456789012},
   182  		RSint32: []int32{-1, -2, -3},
   183  		RSint64: []int64{-6789012345, -3456789012},
   184  		RFloat:  []float32{3.14, 6.28},
   185  		RDouble: []float64{299792458 * 1e20, 6.62606957e-34},
   186  		RString: []string{"happy", "days"},
   187  		RBytes:  [][]byte{[]byte("skittles"), []byte("m&m's")},
   188  	}
   189  
   190  	repeatsObjectJSON = `{` +
   191  		`"rBool":[true,false,true],` +
   192  		`"rInt32":[-3,-4,-5],` +
   193  		`"rInt64":["-123456789","-987654321"],` +
   194  		`"rUint32":[1,2,3],` +
   195  		`"rUint64":["6789012345","3456789012"],` +
   196  		`"rSint32":[-1,-2,-3],` +
   197  		`"rSint64":["-6789012345","-3456789012"],` +
   198  		`"rFloat":[3.14,6.28],` +
   199  		`"rDouble":[2.99792458e+28,6.62606957e-34],` +
   200  		`"rString":["happy","days"],` +
   201  		`"rBytes":["0x736b6974746c6573","0x6d266d2773"]` +
   202  		`}`
   203  
   204  	repeatsObjectPrettyJSON = `{
   205    "rBool": [
   206      true,
   207      false,
   208      true
   209    ],
   210    "rInt32": [
   211      -3,
   212      -4,
   213      -5
   214    ],
   215    "rInt64": [
   216      "-123456789",
   217      "-987654321"
   218    ],
   219    "rUint32": [
   220      1,
   221      2,
   222      3
   223    ],
   224    "rUint64": [
   225      "6789012345",
   226      "3456789012"
   227    ],
   228    "rSint32": [
   229      -1,
   230      -2,
   231      -3
   232    ],
   233    "rSint64": [
   234      "-6789012345",
   235      "-3456789012"
   236    ],
   237    "rFloat": [
   238      3.14,
   239      6.28
   240    ],
   241    "rDouble": [
   242      2.99792458e+28,
   243      6.62606957e-34
   244    ],
   245    "rString": [
   246      "happy",
   247      "days"
   248    ],
   249    "rBytes": [
   250      "0x736b6974746c6573",
   251      "0x6d266d2773"
   252    ]
   253  }`
   254  
   255  	innerSimple   = &pb.Simple{OInt32: proto.Int32(-32)}
   256  	innerSimple2  = &pb.Simple{OInt64: proto.Int64(25)}
   257  	innerRepeats  = &pb.Repeats{RString: []string{"roses", "red"}}
   258  	innerRepeats2 = &pb.Repeats{RString: []string{"violets", "blue"}}
   259  	complexObject = &pb.Widget{
   260  		Color:    pb.Widget_GREEN.Enum(),
   261  		RColor:   []pb.Widget_Color{pb.Widget_RED, pb.Widget_GREEN, pb.Widget_BLUE},
   262  		Simple:   innerSimple,
   263  		RSimple:  []*pb.Simple{innerSimple, innerSimple2},
   264  		Repeats:  innerRepeats,
   265  		RRepeats: []*pb.Repeats{innerRepeats, innerRepeats2},
   266  	}
   267  
   268  	complexObjectJSON = `{"color":"GREEN",` +
   269  		`"rColor":["RED","GREEN","BLUE"],` +
   270  		`"simple":{"oInt32":-32},` +
   271  		`"rSimple":[{"oInt32":-32},{"oInt64":"25"}],` +
   272  		`"repeats":{"rString":["roses","red"]},` +
   273  		`"rRepeats":[{"rString":["roses","red"]},{"rString":["violets","blue"]}]` +
   274  		`}`
   275  
   276  	complexObjectPrettyJSON = `{
   277    "color": "GREEN",
   278    "rColor": [
   279      "RED",
   280      "GREEN",
   281      "BLUE"
   282    ],
   283    "simple": {
   284      "oInt32": -32
   285    },
   286    "rSimple": [
   287      {
   288        "oInt32": -32
   289      },
   290      {
   291        "oInt64": "25"
   292      }
   293    ],
   294    "repeats": {
   295      "rString": [
   296        "roses",
   297        "red"
   298      ]
   299    },
   300    "rRepeats": [
   301      {
   302        "rString": [
   303          "roses",
   304          "red"
   305        ]
   306      },
   307      {
   308        "rString": [
   309          "violets",
   310          "blue"
   311        ]
   312      }
   313    ]
   314  }`
   315  
   316  	colorPrettyJSON = `{
   317   "color": 2
   318  }`
   319  
   320  	colorListPrettyJSON = `{
   321    "color": 1000,
   322    "rColor": [
   323      "RED"
   324    ]
   325  }`
   326  
   327  	nummyPrettyJSON = `{
   328    "nummy": {
   329      "1": 2,
   330      "3": 4
   331    }
   332  }`
   333  
   334  	objjyPrettyJSON = `{
   335    "objjy": {
   336      "1": {
   337        "dub": 1
   338      }
   339    }
   340  }`
   341  	realNumber     = &pb.Real{Value: proto.Float64(3.14159265359)}
   342  	realNumberName = "Pi"
   343  	complexNumber  = &pb.Complex{Imaginary: proto.Float64(0.5772156649)}
   344  	realNumberJSON = `{` +
   345  		`"value":3.14159265359,` +
   346  		`"[jsonpb.Complex.real_extension]":{"imaginary":0.5772156649},` +
   347  		`"[jsonpb.name]":"Pi"` +
   348  		`}`
   349  
   350  	anySimple = &pb.KnownTypes{
   351  		An: &anypb.Any{
   352  			TypeUrl: "something.example.com/jsonpb.Simple",
   353  			Value: []byte{
   354  				// &pb.Simple{OBool:true}
   355  				1 << 3, 1,
   356  			},
   357  		},
   358  	}
   359  	anySimpleJSON       = `{"an":{"@type":"something.example.com/jsonpb.Simple","oBool":true}}`
   360  	anySimplePrettyJSON = `{
   361    "an": {
   362      "@type": "something.example.com/jsonpb.Simple",
   363      "oBool": true
   364    }
   365  }`
   366  
   367  	anyWellKnown = &pb.KnownTypes{
   368  		An: &anypb.Any{
   369  			TypeUrl: "type.googleapis.com/google.protobuf.Duration",
   370  			Value: []byte{
   371  				// &durpb.Duration{Seconds: 1, Nanos: 212000000 }
   372  				1 << 3, 1, // seconds
   373  				2 << 3, 0x80, 0xba, 0x8b, 0x65, // nanos
   374  			},
   375  		},
   376  	}
   377  	anyWellKnownJSON       = `{"an":{"@type":"type.googleapis.com/google.protobuf.Duration","value":"1.212s"}}`
   378  	anyWellKnownPrettyJSON = `{
   379    "an": {
   380      "@type": "type.googleapis.com/google.protobuf.Duration",
   381      "value": "1.212s"
   382    }
   383  }`
   384  
   385  	nonFinites = &pb.NonFinites{
   386  		FNan:  proto.Float32(float32(math.NaN())),
   387  		FPinf: proto.Float32(float32(math.Inf(1))),
   388  		FNinf: proto.Float32(float32(math.Inf(-1))),
   389  		DNan:  proto.Float64(math.NaN()),
   390  		DPinf: proto.Float64(math.Inf(1)),
   391  		DNinf: proto.Float64(math.Inf(-1)),
   392  	}
   393  	nonFinitesJSON = `{` +
   394  		`"fNan":"NaN",` +
   395  		`"fPinf":"Infinity",` +
   396  		`"fNinf":"-Infinity",` +
   397  		`"dNan":"NaN",` +
   398  		`"dPinf":"Infinity",` +
   399  		`"dNinf":"-Infinity"` +
   400  		`}`
   401  )
   402  
   403  func init() {
   404  	if err := proto.SetExtension(realNumber, pb.E_Name, &realNumberName); err != nil {
   405  		panic(err)
   406  	}
   407  	if err := proto.SetExtension(realNumber, pb.E_Complex_RealExtension, complexNumber); err != nil {
   408  		panic(err)
   409  	}
   410  }
   411  
   412  var marshalingTests = []struct {
   413  	desc      string
   414  	marshaler Marshaler
   415  	pb        proto.Message
   416  	json      string
   417  }{
   418  	{"simple flat object", marshaler, simpleObject, simpleObjectOutputJSON},
   419  	{"simple pretty object", marshalerAllOptions, simpleObject, simpleObjectOutputPrettyJSON},
   420  	{"non-finite floats fields object", marshaler, nonFinites, nonFinitesJSON},
   421  	{"repeated fields flat object", marshaler, repeatsObject, repeatsObjectJSON},
   422  	{"repeated fields pretty object", marshalerAllOptions, repeatsObject, repeatsObjectPrettyJSON},
   423  	{"nested message/enum flat object", marshaler, complexObject, complexObjectJSON},
   424  	{"nested message/enum pretty object", marshalerAllOptions, complexObject, complexObjectPrettyJSON},
   425  	{"enum-string flat object", Marshaler{},
   426  		&pb.Widget{Color: pb.Widget_BLUE.Enum()}, `{"color":"BLUE"}`},
   427  	{"enum-value pretty object", Marshaler{EnumsAsInts: true, Indent: " "},
   428  		&pb.Widget{Color: pb.Widget_BLUE.Enum()}, colorPrettyJSON},
   429  	{"unknown enum value object", marshalerAllOptions,
   430  		&pb.Widget{Color: pb.Widget_Color(1000).Enum(), RColor: []pb.Widget_Color{pb.Widget_RED}}, colorListPrettyJSON},
   431  	{"repeated proto3 enum", Marshaler{},
   432  		&proto3pb.Message{RFunny: []proto3pb.Message_Humour{
   433  			proto3pb.Message_PUNS,
   434  			proto3pb.Message_SLAPSTICK,
   435  		}},
   436  		`{"rFunny":["PUNS","SLAPSTICK"]}`},
   437  	{"repeated proto3 enum as int", Marshaler{EnumsAsInts: true},
   438  		&proto3pb.Message{RFunny: []proto3pb.Message_Humour{
   439  			proto3pb.Message_PUNS,
   440  			proto3pb.Message_SLAPSTICK,
   441  		}},
   442  		`{"rFunny":[1,2]}`},
   443  	{"empty value", marshaler, &pb.Simple3{}, `{}`},
   444  	{"empty value emitted", Marshaler{EmitDefaults: true}, &pb.Simple3{}, `{"dub":0}`},
   445  	{"empty repeated emitted", Marshaler{EmitDefaults: true}, &pb.SimpleSlice3{}, `{"slices":[]}`},
   446  	{"empty map emitted", Marshaler{EmitDefaults: true}, &pb.SimpleMap3{}, `{"stringy":{}}`},
   447  	{"nested struct null", Marshaler{EmitDefaults: true}, &pb.SimpleNull3{}, `{"simple":null}`},
   448  	{"map<int64, int32>", marshaler, &pb.Mappy{Nummy: map[int64]int32{1: 2, 3: 4}}, `{"nummy":{"1":2,"3":4}}`},
   449  	{"map<int64, int32>", marshalerAllOptions, &pb.Mappy{Nummy: map[int64]int32{1: 2, 3: 4}}, nummyPrettyJSON},
   450  	{"map<string, string>", marshaler,
   451  		&pb.Mappy{Strry: map[string]string{`"one"`: "two", "three": "four"}},
   452  		`{"strry":{"\"one\"":"two","three":"four"}}`},
   453  	{"map<int32, Object>", marshaler,
   454  		&pb.Mappy{Objjy: map[int32]*pb.Simple3{1: {Dub: 1}}}, `{"objjy":{"1":{"dub":1}}}`},
   455  	{"map<int32, Object>", marshalerAllOptions,
   456  		&pb.Mappy{Objjy: map[int32]*pb.Simple3{1: {Dub: 1}}}, objjyPrettyJSON},
   457  	{"map<int64, string>", marshaler, &pb.Mappy{Buggy: map[int64]string{1234: "yup"}},
   458  		`{"buggy":{"1234":"yup"}}`},
   459  	{"map<bool, bool>", marshaler, &pb.Mappy{Booly: map[bool]bool{false: true}}, `{"booly":{"false":true}}`},
   460  	{"map<string, enum>", marshaler, &pb.Mappy{Enumy: map[string]pb.Numeral{"XIV": pb.Numeral_ROMAN}}, `{"enumy":{"XIV":"ROMAN"}}`},
   461  	{"map<string, enum as int>", Marshaler{EnumsAsInts: true}, &pb.Mappy{Enumy: map[string]pb.Numeral{"XIV": pb.Numeral_ROMAN}}, `{"enumy":{"XIV":2}}`},
   462  	{"map<int32, bool>", marshaler, &pb.Mappy{S32Booly: map[int32]bool{1: true, 3: false, 10: true, 12: false}}, `{"s32booly":{"1":true,"3":false,"10":true,"12":false}}`},
   463  	{"map<int64, bool>", marshaler, &pb.Mappy{S64Booly: map[int64]bool{1: true, 3: false, 10: true, 12: false}}, `{"s64booly":{"1":true,"3":false,"10":true,"12":false}}`},
   464  	{"map<uint32, bool>", marshaler, &pb.Mappy{U32Booly: map[uint32]bool{1: true, 3: false, 10: true, 12: false}}, `{"u32booly":{"1":true,"3":false,"10":true,"12":false}}`},
   465  	{"map<uint64, bool>", marshaler, &pb.Mappy{U64Booly: map[uint64]bool{1: true, 3: false, 10: true, 12: false}}, `{"u64booly":{"1":true,"3":false,"10":true,"12":false}}`},
   466  	{"proto2 map<int64, string>", marshaler, &pb.Maps{MInt64Str: map[int64]string{213: "cat"}},
   467  		`{"mInt64Str":{"213":"cat"}}`},
   468  	{"proto2 map<bool, Object>", marshaler,
   469  		&pb.Maps{MBoolSimple: map[bool]*pb.Simple{true: {OInt32: proto.Int32(1)}}},
   470  		`{"mBoolSimple":{"true":{"oInt32":1}}}`},
   471  	{"oneof, not set", marshaler, &pb.MsgWithOneof{}, `{}`},
   472  	{"oneof, set", marshaler, &pb.MsgWithOneof{Union: &pb.MsgWithOneof_Title{Title: "Grand Poobah"}}, `{"title":"Grand Poobah"}`},
   473  	{"force orig_name", Marshaler{OrigName: true}, &pb.Simple{OInt32: proto.Int32(4)},
   474  		`{"o_int32":4}`},
   475  	{"proto2 extension", marshaler, realNumber, realNumberJSON},
   476  	{"Any with message", marshaler, anySimple, anySimpleJSON},
   477  	{"Any with message and indent", marshalerAllOptions, anySimple, anySimplePrettyJSON},
   478  	{"Any with WKT", marshaler, anyWellKnown, anyWellKnownJSON},
   479  	{"Any with WKT and indent", marshalerAllOptions, anyWellKnown, anyWellKnownPrettyJSON},
   480  	{"Duration", marshaler, &pb.KnownTypes{Dur: &durpb.Duration{Seconds: 3}}, `{"dur":"3s"}`},
   481  	{"Duration", marshaler, &pb.KnownTypes{Dur: &durpb.Duration{Seconds: 3, Nanos: 1e6}}, `{"dur":"3.001s"}`},
   482  	{"Duration beyond float64 precision", marshaler, &pb.KnownTypes{Dur: &durpb.Duration{Seconds: 100000000, Nanos: 1}}, `{"dur":"100000000.000000001s"}`},
   483  	{"negative Duration", marshaler, &pb.KnownTypes{Dur: &durpb.Duration{Seconds: -123, Nanos: -456}}, `{"dur":"-123.000000456s"}`},
   484  	{"Struct", marshaler, &pb.KnownTypes{St: &stpb.Struct{
   485  		Fields: map[string]*stpb.Value{
   486  			"one": {Kind: &stpb.Value_StringValue{StringValue: "loneliest number"}},
   487  			"two": {Kind: &stpb.Value_NullValue{NullValue: stpb.NullValue_NULL_VALUE}},
   488  		},
   489  	}}, `{"st":{"one":"loneliest number","two":null}}`},
   490  	{"empty ListValue", marshaler, &pb.KnownTypes{Lv: &stpb.ListValue{}}, `{"lv":[]}`},
   491  	{"basic ListValue", marshaler, &pb.KnownTypes{Lv: &stpb.ListValue{Values: []*stpb.Value{
   492  		{Kind: &stpb.Value_StringValue{StringValue: "x"}},
   493  		{Kind: &stpb.Value_NullValue{}},
   494  		{Kind: &stpb.Value_NumberValue{NumberValue: 3}},
   495  		{Kind: &stpb.Value_BoolValue{BoolValue: true}},
   496  	}}}, `{"lv":["x",null,3,true]}`},
   497  	{"Timestamp", marshaler, &pb.KnownTypes{Ts: &tspb.Timestamp{Seconds: 14e8, Nanos: 21e6}}, `{"ts":"2014-05-13T16:53:20.021Z"}`},
   498  	{"Timestamp", marshaler, &pb.KnownTypes{Ts: &tspb.Timestamp{Seconds: 14e8, Nanos: 0}}, `{"ts":"2014-05-13T16:53:20Z"}`},
   499  	{"number Value", marshaler, &pb.KnownTypes{Val: &stpb.Value{Kind: &stpb.Value_NumberValue{NumberValue: 1}}}, `{"val":1}`},
   500  	{"null Value", marshaler, &pb.KnownTypes{Val: &stpb.Value{Kind: &stpb.Value_NullValue{NullValue: stpb.NullValue_NULL_VALUE}}}, `{"val":null}`},
   501  	{"string number value", marshaler, &pb.KnownTypes{Val: &stpb.Value{Kind: &stpb.Value_StringValue{StringValue: "9223372036854775807"}}}, `{"val":"9223372036854775807"}`},
   502  	{"list of lists Value", marshaler, &pb.KnownTypes{Val: &stpb.Value{
   503  		Kind: &stpb.Value_ListValue{ListValue: &stpb.ListValue{
   504  			Values: []*stpb.Value{
   505  				{Kind: &stpb.Value_StringValue{StringValue: "x"}},
   506  				{Kind: &stpb.Value_ListValue{ListValue: &stpb.ListValue{
   507  					Values: []*stpb.Value{
   508  						{Kind: &stpb.Value_ListValue{ListValue: &stpb.ListValue{
   509  							Values: []*stpb.Value{{Kind: &stpb.Value_StringValue{StringValue: "y"}}},
   510  						}}},
   511  						{Kind: &stpb.Value_StringValue{StringValue: "z"}},
   512  					},
   513  				}}},
   514  			},
   515  		}},
   516  	}}, `{"val":["x",[["y"],"z"]]}`},
   517  
   518  	{"DoubleValue", marshaler, &pb.KnownTypes{Dbl: &wpb.DoubleValue{Value: 1.2}}, `{"dbl":1.2}`},
   519  	{"FloatValue", marshaler, &pb.KnownTypes{Flt: &wpb.FloatValue{Value: 1.2}}, `{"flt":1.2}`},
   520  	{"Int64Value", marshaler, &pb.KnownTypes{I64: &wpb.Int64Value{Value: -3}}, `{"i64":"-3"}`},
   521  	{"UInt64Value", marshaler, &pb.KnownTypes{U64: &wpb.UInt64Value{Value: 3}}, `{"u64":"3"}`},
   522  	{"Int32Value", marshaler, &pb.KnownTypes{I32: &wpb.Int32Value{Value: -4}}, `{"i32":-4}`},
   523  	{"UInt32Value", marshaler, &pb.KnownTypes{U32: &wpb.UInt32Value{Value: 4}}, `{"u32":4}`},
   524  	{"BoolValue", marshaler, &pb.KnownTypes{Bool: &wpb.BoolValue{Value: true}}, `{"bool":true}`},
   525  	{"StringValue", marshaler, &pb.KnownTypes{Str: &wpb.StringValue{Value: "plush"}}, `{"str":"plush"}`},
   526  	{"BytesValue", marshaler, &pb.KnownTypes{Bytes: &wpb.BytesValue{Value: []byte("wow")}}, `{"bytes":"0x776f77"}`},
   527  	{"required", marshaler, &pb.MsgWithRequired{Str: proto.String("hello")}, `{"str":"hello"}`},
   528  	{"required bytes", marshaler, &pb.MsgWithRequiredBytes{Byts: []byte{}}, `{"byts":""}`},
   529  }
   530  
   531  func TestMarshaling(t *testing.T) {
   532  	for _, tt := range marshalingTests {
   533  		json, err := tt.marshaler.MarshalToString(tt.pb)
   534  		if err != nil {
   535  			t.Errorf("%s: marshaling error: %v", tt.desc, err)
   536  		} else if tt.json != json {
   537  			t.Errorf("%s: got [%v] want [%v]", tt.desc, json, tt.json)
   538  		}
   539  	}
   540  }
   541  
   542  func TestMarshalingNil(t *testing.T) {
   543  	var msg *pb.Simple
   544  	m := &Marshaler{}
   545  	if _, err := m.MarshalToString(msg); err == nil {
   546  		t.Errorf("mashaling nil returned no error")
   547  	}
   548  }
   549  
   550  func TestMarshalIllegalTime(t *testing.T) {
   551  	tests := []struct {
   552  		pb   proto.Message
   553  		fail bool
   554  	}{
   555  		{&pb.KnownTypes{Dur: &durpb.Duration{Seconds: 1, Nanos: 0}}, false},
   556  		{&pb.KnownTypes{Dur: &durpb.Duration{Seconds: -1, Nanos: 0}}, false},
   557  		{&pb.KnownTypes{Dur: &durpb.Duration{Seconds: 1, Nanos: -1}}, true},
   558  		{&pb.KnownTypes{Dur: &durpb.Duration{Seconds: -1, Nanos: 1}}, true},
   559  		{&pb.KnownTypes{Dur: &durpb.Duration{Seconds: 1, Nanos: 1000000000}}, true},
   560  		{&pb.KnownTypes{Dur: &durpb.Duration{Seconds: -1, Nanos: -1000000000}}, true},
   561  		{&pb.KnownTypes{Ts: &tspb.Timestamp{Seconds: 1, Nanos: 1}}, false},
   562  		{&pb.KnownTypes{Ts: &tspb.Timestamp{Seconds: 1, Nanos: -1}}, true},
   563  		{&pb.KnownTypes{Ts: &tspb.Timestamp{Seconds: 1, Nanos: 1000000000}}, true},
   564  	}
   565  	for _, tt := range tests {
   566  		_, err := marshaler.MarshalToString(tt.pb)
   567  		if err == nil && tt.fail {
   568  			t.Errorf("marshaler.MarshalToString(%v) = _, <nil>; want _, <non-nil>", tt.pb)
   569  		}
   570  		if err != nil && !tt.fail {
   571  			t.Errorf("marshaler.MarshalToString(%v) = _, %v; want _, <nil>", tt.pb, err)
   572  		}
   573  	}
   574  }
   575  
   576  func TestMarshalJSONPBMarshaler(t *testing.T) {
   577  	rawJSON := `{ "foo": "bar", "baz": [0, 1, 2, 3] }`
   578  	msg := dynamicMessage{RawJSON: rawJSON}
   579  	str, err := new(Marshaler).MarshalToString(&msg)
   580  	if err != nil {
   581  		t.Errorf("an unexpected error occurred when marshalling JSONPBMarshaler: %v", err)
   582  	}
   583  	if str != rawJSON {
   584  		t.Errorf("marshalling JSON produced incorrect output: got %s, wanted %s", str, rawJSON)
   585  	}
   586  }
   587  
   588  func TestMarshalAnyJSONPBMarshaler(t *testing.T) {
   589  	msg := dynamicMessage{RawJSON: `{ "foo": "bar", "baz": [0, 1, 2, 3] }`}
   590  	a, err := ptypes.MarshalAny(&msg)
   591  	if err != nil {
   592  		t.Errorf("an unexpected error occurred when marshalling to Any: %v", err)
   593  	}
   594  	str, err := new(Marshaler).MarshalToString(a)
   595  	if err != nil {
   596  		t.Errorf("an unexpected error occurred when marshalling Any to JSON: %v", err)
   597  	}
   598  	// after custom marshaling, it's round-tripped through JSON decoding/encoding already,
   599  	// so the keys are sorted, whitespace is compacted, and "@type" key has been added
   600  	expected := `{"@type":"type.googleapis.com/` + dynamicMessageName + `","baz":[0,1,2,3],"foo":"bar"}`
   601  	if str != expected {
   602  		t.Errorf("marshalling JSON produced incorrect output: got %s, wanted %s", str, expected)
   603  	}
   604  }
   605  
   606  func TestMarshalWithCustomValidation(t *testing.T) {
   607  	msg := dynamicMessage{RawJSON: `{ "foo": "bar", "baz": [0, 1, 2, 3] }`, Dummy: &dynamicMessage{}}
   608  
   609  	js, err := new(Marshaler).MarshalToString(&msg)
   610  	if err != nil {
   611  		t.Errorf("an unexpected error occurred when marshalling to json: %v", err)
   612  	}
   613  	err = Unmarshal(strings.NewReader(js), &msg)
   614  	if err != nil {
   615  		t.Errorf("an unexpected error occurred when unmarshalling from json: %v", err)
   616  	}
   617  }
   618  
   619  // Test marshaling message containing unset required fields should produce error.
   620  func TestMarshalUnsetRequiredFields(t *testing.T) {
   621  	msgExt := &pb.Real{}
   622  	proto.SetExtension(msgExt, pb.E_Extm, &pb.MsgWithRequired{})
   623  
   624  	tests := []struct {
   625  		desc      string
   626  		marshaler *Marshaler
   627  		pb        proto.Message
   628  	}{
   629  		{
   630  			desc:      "direct required field",
   631  			marshaler: &Marshaler{},
   632  			pb:        &pb.MsgWithRequired{},
   633  		},
   634  		{
   635  			desc:      "direct required field + emit defaults",
   636  			marshaler: &Marshaler{EmitDefaults: true},
   637  			pb:        &pb.MsgWithRequired{},
   638  		},
   639  		{
   640  			desc:      "indirect required field",
   641  			marshaler: &Marshaler{},
   642  			pb:        &pb.MsgWithIndirectRequired{Subm: &pb.MsgWithRequired{}},
   643  		},
   644  		{
   645  			desc:      "indirect required field + emit defaults",
   646  			marshaler: &Marshaler{EmitDefaults: true},
   647  			pb:        &pb.MsgWithIndirectRequired{Subm: &pb.MsgWithRequired{}},
   648  		},
   649  		{
   650  			desc:      "direct required wkt field",
   651  			marshaler: &Marshaler{},
   652  			pb:        &pb.MsgWithRequiredWKT{},
   653  		},
   654  		{
   655  			desc:      "direct required wkt field + emit defaults",
   656  			marshaler: &Marshaler{EmitDefaults: true},
   657  			pb:        &pb.MsgWithRequiredWKT{},
   658  		},
   659  		{
   660  			desc:      "direct required bytes field",
   661  			marshaler: &Marshaler{},
   662  			pb:        &pb.MsgWithRequiredBytes{},
   663  		},
   664  		{
   665  			desc:      "required in map value",
   666  			marshaler: &Marshaler{},
   667  			pb: &pb.MsgWithIndirectRequired{
   668  				MapField: map[string]*pb.MsgWithRequired{
   669  					"key": {},
   670  				},
   671  			},
   672  		},
   673  		{
   674  			desc:      "required in repeated item",
   675  			marshaler: &Marshaler{},
   676  			pb: &pb.MsgWithIndirectRequired{
   677  				SliceField: []*pb.MsgWithRequired{
   678  					{Str: proto.String("hello")},
   679  					{},
   680  				},
   681  			},
   682  		},
   683  		{
   684  			desc:      "required inside oneof",
   685  			marshaler: &Marshaler{},
   686  			pb: &pb.MsgWithOneof{
   687  				Union: &pb.MsgWithOneof_MsgWithRequired{MsgWithRequired: &pb.MsgWithRequired{}},
   688  			},
   689  		},
   690  		{
   691  			desc:      "required inside extension",
   692  			marshaler: &Marshaler{},
   693  			pb:        msgExt,
   694  		},
   695  	}
   696  
   697  	for _, tc := range tests {
   698  		if _, err := tc.marshaler.MarshalToString(tc.pb); err == nil {
   699  			t.Errorf("%s: expecting error in marshaling with unset required fields %+v", tc.desc, tc.pb)
   700  		}
   701  	}
   702  }
   703  
   704  var unmarshalingTests = []struct {
   705  	desc        string
   706  	unmarshaler Unmarshaler
   707  	json        string
   708  	pb          proto.Message
   709  }{
   710  	{"simple flat object", Unmarshaler{}, simpleObjectInputJSON, simpleObject},
   711  	{"simple pretty object", Unmarshaler{}, simpleObjectInputPrettyJSON, simpleObject},
   712  	{"repeated fields flat object", Unmarshaler{}, repeatsObjectJSON, repeatsObject},
   713  	{"repeated fields pretty object", Unmarshaler{}, repeatsObjectPrettyJSON, repeatsObject},
   714  	{"nested message/enum flat object", Unmarshaler{}, complexObjectJSON, complexObject},
   715  	{"nested message/enum pretty object", Unmarshaler{}, complexObjectPrettyJSON, complexObject},
   716  	{"enum-string object", Unmarshaler{}, `{"color":"BLUE"}`, &pb.Widget{Color: pb.Widget_BLUE.Enum()}},
   717  	{"enum-value object", Unmarshaler{}, "{\n \"color\": 2\n}", &pb.Widget{Color: pb.Widget_BLUE.Enum()}},
   718  	{"unknown field with allowed option", Unmarshaler{AllowUnknownFields: true}, `{"unknown": "foo"}`, new(pb.Simple)},
   719  	{"proto3 enum string", Unmarshaler{}, `{"hilarity":"PUNS"}`, &proto3pb.Message{Hilarity: proto3pb.Message_PUNS}},
   720  	{"proto3 enum value", Unmarshaler{}, `{"hilarity":1}`, &proto3pb.Message{Hilarity: proto3pb.Message_PUNS}},
   721  	{"unknown enum value object",
   722  		Unmarshaler{},
   723  		"{\n  \"color\": 1000,\n  \"r_color\": [\n    \"RED\"\n  ]\n}",
   724  		&pb.Widget{Color: pb.Widget_Color(1000).Enum(), RColor: []pb.Widget_Color{pb.Widget_RED}}},
   725  	{"repeated proto3 enum", Unmarshaler{}, `{"rFunny":["PUNS","SLAPSTICK"]}`,
   726  		&proto3pb.Message{RFunny: []proto3pb.Message_Humour{
   727  			proto3pb.Message_PUNS,
   728  			proto3pb.Message_SLAPSTICK,
   729  		}}},
   730  	{"repeated proto3 enum as int", Unmarshaler{}, `{"rFunny":[1,2]}`,
   731  		&proto3pb.Message{RFunny: []proto3pb.Message_Humour{
   732  			proto3pb.Message_PUNS,
   733  			proto3pb.Message_SLAPSTICK,
   734  		}}},
   735  	{"repeated proto3 enum as mix of strings and ints", Unmarshaler{}, `{"rFunny":["PUNS",2]}`,
   736  		&proto3pb.Message{RFunny: []proto3pb.Message_Humour{
   737  			proto3pb.Message_PUNS,
   738  			proto3pb.Message_SLAPSTICK,
   739  		}}},
   740  	{"unquoted int64 object", Unmarshaler{}, `{"oInt64":-314}`, &pb.Simple{OInt64: proto.Int64(-314)}},
   741  	{"unquoted uint64 object", Unmarshaler{}, `{"oUint64":123}`, &pb.Simple{OUint64: proto.Uint64(123)}},
   742  	{"NaN", Unmarshaler{}, `{"oDouble":"NaN"}`, &pb.Simple{ODouble: proto.Float64(math.NaN())}},
   743  	{"Inf", Unmarshaler{}, `{"oFloat":"Infinity"}`, &pb.Simple{OFloat: proto.Float32(float32(math.Inf(1)))}},
   744  	{"-Inf", Unmarshaler{}, `{"oDouble":"-Infinity"}`, &pb.Simple{ODouble: proto.Float64(math.Inf(-1))}},
   745  	{"map<int64, int32>", Unmarshaler{}, `{"nummy":{"1":2,"3":4}}`, &pb.Mappy{Nummy: map[int64]int32{1: 2, 3: 4}}},
   746  	{"map<string, string>", Unmarshaler{}, `{"strry":{"\"one\"":"two","three":"four"}}`, &pb.Mappy{Strry: map[string]string{`"one"`: "two", "three": "four"}}},
   747  	{"map<int32, Object>", Unmarshaler{}, `{"objjy":{"1":{"dub":1}}}`, &pb.Mappy{Objjy: map[int32]*pb.Simple3{1: {Dub: 1}}}},
   748  	{"proto2 extension", Unmarshaler{}, realNumberJSON, realNumber},
   749  	{"Any with message", Unmarshaler{}, anySimpleJSON, anySimple},
   750  	{"Any with message and indent", Unmarshaler{}, anySimplePrettyJSON, anySimple},
   751  	{"Any with WKT", Unmarshaler{}, anyWellKnownJSON, anyWellKnown},
   752  	{"Any with WKT and indent", Unmarshaler{}, anyWellKnownPrettyJSON, anyWellKnown},
   753  	{"map<string, enum>", Unmarshaler{}, `{"enumy":{"XIV":"ROMAN"}}`, &pb.Mappy{Enumy: map[string]pb.Numeral{"XIV": pb.Numeral_ROMAN}}},
   754  	{"map<string, enum as int>", Unmarshaler{}, `{"enumy":{"XIV":2}}`, &pb.Mappy{Enumy: map[string]pb.Numeral{"XIV": pb.Numeral_ROMAN}}},
   755  	{"oneof", Unmarshaler{}, `{"salary":31000}`, &pb.MsgWithOneof{Union: &pb.MsgWithOneof_Salary{Salary: 31000}}},
   756  	{"oneof spec name", Unmarshaler{}, `{"Country":"Australia"}`, &pb.MsgWithOneof{Union: &pb.MsgWithOneof_Country{Country: "Australia"}}},
   757  	{"oneof orig_name", Unmarshaler{}, `{"Country":"Australia"}`, &pb.MsgWithOneof{Union: &pb.MsgWithOneof_Country{Country: "Australia"}}},
   758  	{"oneof spec name2", Unmarshaler{}, `{"homeAddress":"Australia"}`, &pb.MsgWithOneof{Union: &pb.MsgWithOneof_HomeAddress{HomeAddress: "Australia"}}},
   759  	{"oneof orig_name2", Unmarshaler{}, `{"home_address":"Australia"}`, &pb.MsgWithOneof{Union: &pb.MsgWithOneof_HomeAddress{HomeAddress: "Australia"}}},
   760  	{"orig_name input", Unmarshaler{}, `{"o_bool":true}`, &pb.Simple{OBool: proto.Bool(true)}},
   761  	{"camelName input", Unmarshaler{}, `{"oBool":true}`, &pb.Simple{OBool: proto.Bool(true)}},
   762  
   763  	{"Duration", Unmarshaler{}, `{"dur":"3.000s"}`, &pb.KnownTypes{Dur: &durpb.Duration{Seconds: 3}}},
   764  	{"Duration", Unmarshaler{}, `{"dur":"4s"}`, &pb.KnownTypes{Dur: &durpb.Duration{Seconds: 4}}},
   765  	{"Duration with unicode", Unmarshaler{}, `{"dur": "3\u0073"}`, &pb.KnownTypes{Dur: &durpb.Duration{Seconds: 3}}},
   766  	{"null Duration", Unmarshaler{}, `{"dur":null}`, &pb.KnownTypes{Dur: nil}},
   767  	{"Timestamp", Unmarshaler{}, `{"ts":"2014-05-13T16:53:20.021Z"}`, &pb.KnownTypes{Ts: &tspb.Timestamp{Seconds: 14e8, Nanos: 21e6}}},
   768  	{"Timestamp", Unmarshaler{}, `{"ts":"2014-05-13T16:53:20Z"}`, &pb.KnownTypes{Ts: &tspb.Timestamp{Seconds: 14e8, Nanos: 0}}},
   769  	{"Timestamp with unicode", Unmarshaler{}, `{"ts": "2014-05-13T16:53:20\u005a"}`, &pb.KnownTypes{Ts: &tspb.Timestamp{Seconds: 14e8, Nanos: 0}}},
   770  	{"PreEpochTimestamp", Unmarshaler{}, `{"ts":"1969-12-31T23:59:58.999999995Z"}`, &pb.KnownTypes{Ts: &tspb.Timestamp{Seconds: -2, Nanos: 999999995}}},
   771  	{"ZeroTimeTimestamp", Unmarshaler{}, `{"ts":"0001-01-01T00:00:00Z"}`, &pb.KnownTypes{Ts: &tspb.Timestamp{Seconds: -62135596800, Nanos: 0}}},
   772  	{"null Timestamp", Unmarshaler{}, `{"ts":null}`, &pb.KnownTypes{Ts: nil}},
   773  	{"null Struct", Unmarshaler{}, `{"st": null}`, &pb.KnownTypes{St: nil}},
   774  	{"empty Struct", Unmarshaler{}, `{"st": {}}`, &pb.KnownTypes{St: &stpb.Struct{}}},
   775  	{"basic Struct", Unmarshaler{}, `{"st": {"a": "x", "b": null, "c": 3, "d": true}}`, &pb.KnownTypes{St: &stpb.Struct{Fields: map[string]*stpb.Value{
   776  		"a": {Kind: &stpb.Value_StringValue{StringValue: "x"}},
   777  		"b": {Kind: &stpb.Value_NullValue{}},
   778  		"c": {Kind: &stpb.Value_NumberValue{NumberValue: 3}},
   779  		"d": {Kind: &stpb.Value_BoolValue{BoolValue: true}},
   780  	}}}},
   781  	{"nested Struct", Unmarshaler{}, `{"st": {"a": {"b": 1, "c": [{"d": true}, "f"]}}}`, &pb.KnownTypes{St: &stpb.Struct{Fields: map[string]*stpb.Value{
   782  		"a": {Kind: &stpb.Value_StructValue{StructValue: &stpb.Struct{Fields: map[string]*stpb.Value{
   783  			"b": {Kind: &stpb.Value_NumberValue{NumberValue: 1}},
   784  			"c": {Kind: &stpb.Value_ListValue{ListValue: &stpb.ListValue{Values: []*stpb.Value{
   785  				{Kind: &stpb.Value_StructValue{StructValue: &stpb.Struct{Fields: map[string]*stpb.Value{"d": {Kind: &stpb.Value_BoolValue{BoolValue: true}}}}}},
   786  				{Kind: &stpb.Value_StringValue{StringValue: "f"}},
   787  			}}}},
   788  		}}}},
   789  	}}}},
   790  	{"null ListValue", Unmarshaler{}, `{"lv": null}`, &pb.KnownTypes{Lv: nil}},
   791  	{"empty ListValue", Unmarshaler{}, `{"lv": []}`, &pb.KnownTypes{Lv: &stpb.ListValue{}}},
   792  	{"basic ListValue", Unmarshaler{}, `{"lv": ["x", null, 3, true]}`, &pb.KnownTypes{Lv: &stpb.ListValue{Values: []*stpb.Value{
   793  		{Kind: &stpb.Value_StringValue{StringValue: "x"}},
   794  		{Kind: &stpb.Value_NullValue{}},
   795  		{Kind: &stpb.Value_NumberValue{NumberValue: 3}},
   796  		{Kind: &stpb.Value_BoolValue{BoolValue: true}},
   797  	}}}},
   798  	{"number Value", Unmarshaler{}, `{"val":1}`, &pb.KnownTypes{Val: &stpb.Value{Kind: &stpb.Value_NumberValue{NumberValue: 1}}}},
   799  	{"null Value", Unmarshaler{}, `{"val":null}`, &pb.KnownTypes{Val: &stpb.Value{Kind: &stpb.Value_NullValue{NullValue: stpb.NullValue_NULL_VALUE}}}},
   800  	{"bool Value", Unmarshaler{}, `{"val":true}`, &pb.KnownTypes{Val: &stpb.Value{Kind: &stpb.Value_BoolValue{BoolValue: true}}}},
   801  	{"string Value", Unmarshaler{}, `{"val":"x"}`, &pb.KnownTypes{Val: &stpb.Value{Kind: &stpb.Value_StringValue{StringValue: "x"}}}},
   802  	{"string number value", Unmarshaler{}, `{"val":"9223372036854775807"}`, &pb.KnownTypes{Val: &stpb.Value{Kind: &stpb.Value_StringValue{StringValue: "9223372036854775807"}}}},
   803  	{"list of lists Value", Unmarshaler{}, `{"val":["x", [["y"], "z"]]}`, &pb.KnownTypes{Val: &stpb.Value{
   804  		Kind: &stpb.Value_ListValue{ListValue: &stpb.ListValue{
   805  			Values: []*stpb.Value{
   806  				{Kind: &stpb.Value_StringValue{StringValue: "x"}},
   807  				{Kind: &stpb.Value_ListValue{ListValue: &stpb.ListValue{
   808  					Values: []*stpb.Value{
   809  						{Kind: &stpb.Value_ListValue{ListValue: &stpb.ListValue{
   810  							Values: []*stpb.Value{{Kind: &stpb.Value_StringValue{StringValue: "y"}}},
   811  						}}},
   812  						{Kind: &stpb.Value_StringValue{StringValue: "z"}},
   813  					},
   814  				}}},
   815  			},
   816  		}}}}},
   817  
   818  	{"DoubleValue", Unmarshaler{}, `{"dbl":1.2}`, &pb.KnownTypes{Dbl: &wpb.DoubleValue{Value: 1.2}}},
   819  	{"FloatValue", Unmarshaler{}, `{"flt":1.2}`, &pb.KnownTypes{Flt: &wpb.FloatValue{Value: 1.2}}},
   820  	{"Int64Value", Unmarshaler{}, `{"i64":"-3"}`, &pb.KnownTypes{I64: &wpb.Int64Value{Value: -3}}},
   821  	{"UInt64Value", Unmarshaler{}, `{"u64":"3"}`, &pb.KnownTypes{U64: &wpb.UInt64Value{Value: 3}}},
   822  	{"Int32Value", Unmarshaler{}, `{"i32":-4}`, &pb.KnownTypes{I32: &wpb.Int32Value{Value: -4}}},
   823  	{"UInt32Value", Unmarshaler{}, `{"u32":4}`, &pb.KnownTypes{U32: &wpb.UInt32Value{Value: 4}}},
   824  	{"BoolValue", Unmarshaler{}, `{"bool":true}`, &pb.KnownTypes{Bool: &wpb.BoolValue{Value: true}}},
   825  	{"StringValue", Unmarshaler{}, `{"str":"plush"}`, &pb.KnownTypes{Str: &wpb.StringValue{Value: "plush"}}},
   826  	{"StringValue containing escaped character", Unmarshaler{}, `{"str":"a\/b"}`, &pb.KnownTypes{Str: &wpb.StringValue{Value: "a/b"}}},
   827  	{"StructValue containing StringValue's", Unmarshaler{}, `{"escaped": "a\/b", "unicode": "\u00004E16\u0000754C"}`,
   828  		&stpb.Struct{
   829  			Fields: map[string]*stpb.Value{
   830  				"escaped": {Kind: &stpb.Value_StringValue{StringValue: "a/b"}},
   831  				"unicode": {Kind: &stpb.Value_StringValue{StringValue: "\u00004E16\u0000754C"}},
   832  			},
   833  		}},
   834  	{"BytesValue", Unmarshaler{}, `{"bytes":"0x776f77"}`, &pb.KnownTypes{Bytes: &wpb.BytesValue{Value: []byte("wow")}}},
   835  	{"BytesValue", Unmarshaler{}, `{"bytes":"0X776f77"}`, &pb.KnownTypes{Bytes: &wpb.BytesValue{Value: []byte("wow")}}},
   836  	{"BytesValue", Unmarshaler{}, `{"bytes":"str://wow"}`, &pb.KnownTypes{Bytes: &wpb.BytesValue{Value: []byte("wow")}}},
   837  	{"BytesValue", Unmarshaler{}, `{"bytes":"str://"}`, &pb.KnownTypes{Bytes: &wpb.BytesValue{Value: []byte("")}}},
   838  	// Ensure that `null` as a value ends up with a nil pointer instead of a [type]Value struct.
   839  	{"null DoubleValue", Unmarshaler{}, `{"dbl":null}`, &pb.KnownTypes{Dbl: nil}},
   840  	{"null FloatValue", Unmarshaler{}, `{"flt":null}`, &pb.KnownTypes{Flt: nil}},
   841  	{"null Int64Value", Unmarshaler{}, `{"i64":null}`, &pb.KnownTypes{I64: nil}},
   842  	{"null UInt64Value", Unmarshaler{}, `{"u64":null}`, &pb.KnownTypes{U64: nil}},
   843  	{"null Int32Value", Unmarshaler{}, `{"i32":null}`, &pb.KnownTypes{I32: nil}},
   844  	{"null UInt32Value", Unmarshaler{}, `{"u32":null}`, &pb.KnownTypes{U32: nil}},
   845  	{"null BoolValue", Unmarshaler{}, `{"bool":null}`, &pb.KnownTypes{Bool: nil}},
   846  	{"null StringValue", Unmarshaler{}, `{"str":null}`, &pb.KnownTypes{Str: nil}},
   847  	{"null BytesValue", Unmarshaler{}, `{"bytes":null}`, &pb.KnownTypes{Bytes: nil}},
   848  
   849  	{"required", Unmarshaler{}, `{"str":"hello"}`, &pb.MsgWithRequired{Str: proto.String("hello")}},
   850  	{"required bytes", Unmarshaler{}, `{"byts": []}`, &pb.MsgWithRequiredBytes{Byts: []byte{}}},
   851  }
   852  
   853  func TestUnmarshaling(t *testing.T) {
   854  	for _, tt := range unmarshalingTests {
   855  		// Make a new instance of the type of our expected object.
   856  		p := reflect.New(reflect.TypeOf(tt.pb).Elem()).Interface().(proto.Message)
   857  
   858  		err := tt.unmarshaler.Unmarshal(strings.NewReader(tt.json), p)
   859  		if err != nil {
   860  			t.Errorf("unmarshalling %s: %v", tt.desc, err)
   861  			continue
   862  		}
   863  
   864  		// For easier diffs, compare text strings of the protos.
   865  		exp := proto.MarshalTextString(tt.pb)
   866  		act := proto.MarshalTextString(p)
   867  		if exp != act {
   868  			t.Errorf("%s: got [%s] want [%s]", tt.desc, act, exp)
   869  		}
   870  	}
   871  }
   872  
   873  func TestUnmarshalNullArray(t *testing.T) {
   874  	var repeats pb.Repeats
   875  	if err := UnmarshalString(`{"rBool":null}`, &repeats); err != nil {
   876  		t.Fatal(err)
   877  	}
   878  	if !reflect.DeepEqual(repeats, pb.Repeats{}) {
   879  		t.Errorf("got non-nil fields in [%#v]", repeats)
   880  	}
   881  }
   882  
   883  func TestUnmarshalNullObject(t *testing.T) {
   884  	var maps pb.Maps
   885  	if err := UnmarshalString(`{"mInt64Str":null}`, &maps); err != nil {
   886  		t.Fatal(err)
   887  	}
   888  	if !reflect.DeepEqual(maps, pb.Maps{}) {
   889  		t.Errorf("got non-nil fields in [%#v]", maps)
   890  	}
   891  }
   892  
   893  func TestUnmarshalNext(t *testing.T) {
   894  	// We only need to check against a few, not all of them.
   895  	tests := unmarshalingTests[:5]
   896  
   897  	// Create a buffer with many concatenated JSON objects.
   898  	var b bytes.Buffer
   899  	for _, tt := range tests {
   900  		b.WriteString(tt.json)
   901  	}
   902  
   903  	dec := json.NewDecoder(&b)
   904  	for _, tt := range tests {
   905  		// Make a new instance of the type of our expected object.
   906  		p := reflect.New(reflect.TypeOf(tt.pb).Elem()).Interface().(proto.Message)
   907  
   908  		err := tt.unmarshaler.UnmarshalNext(dec, p)
   909  		if err != nil {
   910  			t.Errorf("%s: %v", tt.desc, err)
   911  			continue
   912  		}
   913  
   914  		// For easier diffs, compare text strings of the protos.
   915  		exp := proto.MarshalTextString(tt.pb)
   916  		act := proto.MarshalTextString(p)
   917  		if exp != act {
   918  			t.Errorf("%s: got [%s] want [%s]", tt.desc, act, exp)
   919  		}
   920  	}
   921  
   922  	p := &pb.Simple{}
   923  	err := new(Unmarshaler).UnmarshalNext(dec, p)
   924  	if err != io.EOF {
   925  		t.Errorf("eof: got %v, expected io.EOF", err)
   926  	}
   927  }
   928  
   929  var unmarshalingShouldError = []struct {
   930  	desc string
   931  	in   string
   932  	pb   proto.Message
   933  }{
   934  	{"a value", "666", new(pb.Simple)},
   935  	{"gibberish", "{adskja123;l23=-=", new(pb.Simple)},
   936  	{"unknown field", `{"unknown": "foo"}`, new(pb.Simple)},
   937  	{"unknown enum name", `{"hilarity":"DAVE"}`, new(proto3pb.Message)},
   938  	{"Duration containing invalid character", `{"dur": "3\U0073"}`, &pb.KnownTypes{}},
   939  	{"Timestamp containing invalid character", `{"ts": "2014-05-13T16:53:20\U005a"}`, &pb.KnownTypes{}},
   940  	{"StringValue containing invalid character", `{"str": "\U00004E16\U0000754C"}`, &pb.KnownTypes{}},
   941  	{"StructValue containing invalid character", `{"str": "\U00004E16\U0000754C"}`, &stpb.Struct{}},
   942  	{"repeated proto3 enum with non array input", `{"rFunny":"PUNS"}`, &proto3pb.Message{RFunny: []proto3pb.Message_Humour{}}},
   943  }
   944  
   945  func TestUnmarshalingBadInput(t *testing.T) {
   946  	for _, tt := range unmarshalingShouldError {
   947  		err := UnmarshalString(tt.in, tt.pb)
   948  		if err == nil {
   949  			t.Errorf("an error was expected when parsing %q instead of an object", tt.desc)
   950  		}
   951  	}
   952  }
   953  
   954  type funcResolver func(turl string) (proto.Message, error)
   955  
   956  func (fn funcResolver) Resolve(turl string) (proto.Message, error) {
   957  	return fn(turl)
   958  }
   959  
   960  func TestAnyWithCustomResolver(t *testing.T) {
   961  	var resolvedTypeUrls []string
   962  	resolver := funcResolver(func(turl string) (proto.Message, error) {
   963  		resolvedTypeUrls = append(resolvedTypeUrls, turl)
   964  		return new(pb.Simple), nil
   965  	})
   966  	msg := &pb.Simple{
   967  		OBytes:  []byte{1, 2, 3, 4},
   968  		OBool:   proto.Bool(true),
   969  		OString: proto.String("foobar"),
   970  		OInt64:  proto.Int64(1020304),
   971  	}
   972  	msgBytes, err := proto.Marshal(msg)
   973  	if err != nil {
   974  		t.Errorf("an unexpected error occurred when marshaling message: %v", err)
   975  	}
   976  	// make an Any with a type URL that won't resolve w/out custom resolver
   977  	any := &anypb.Any{
   978  		TypeUrl: "https://foobar.com/some.random.MessageKind",
   979  		Value:   msgBytes,
   980  	}
   981  
   982  	m := Marshaler{AnyResolver: resolver}
   983  	js, err := m.MarshalToString(any)
   984  	if err != nil {
   985  		t.Errorf("an unexpected error occurred when marshaling any to JSON: %v", err)
   986  	}
   987  	if len(resolvedTypeUrls) != 1 {
   988  		t.Errorf("custom resolver was not invoked during marshaling")
   989  	} else if resolvedTypeUrls[0] != "https://foobar.com/some.random.MessageKind" {
   990  		t.Errorf("custom resolver was invoked with wrong URL: got %q, wanted %q", resolvedTypeUrls[0], "https://foobar.com/some.random.MessageKind")
   991  	}
   992  	wanted := `{"@type":"https://foobar.com/some.random.MessageKind","oBool":true,"oInt64":"1020304","oString":"foobar","oBytes":"0x01020304"}`
   993  	if js != wanted {
   994  		t.Errorf("marshalling JSON produced incorrect output: got %s, wanted %s", js, wanted)
   995  	}
   996  
   997  	u := Unmarshaler{AnyResolver: resolver}
   998  	roundTrip := &anypb.Any{}
   999  	err = u.Unmarshal(bytes.NewReader([]byte(js)), roundTrip)
  1000  	if err != nil {
  1001  		t.Errorf("an unexpected error occurred when unmarshaling any from JSON: %v", err)
  1002  	}
  1003  	if len(resolvedTypeUrls) != 2 {
  1004  		t.Errorf("custom resolver was not invoked during marshaling")
  1005  	} else if resolvedTypeUrls[1] != "https://foobar.com/some.random.MessageKind" {
  1006  		t.Errorf("custom resolver was invoked with wrong URL: got %q, wanted %q", resolvedTypeUrls[1], "https://foobar.com/some.random.MessageKind")
  1007  	}
  1008  	if !proto.Equal(any, roundTrip) {
  1009  		t.Errorf("message contents not set correctly after unmarshalling JSON: got %s, wanted %s", roundTrip, any)
  1010  	}
  1011  }
  1012  
  1013  func TestUnmarshalJSONPBUnmarshaler(t *testing.T) {
  1014  	rawJSON := `{ "foo": "bar", "baz": [0, 1, 2, 3] }`
  1015  	var msg dynamicMessage
  1016  	if err := Unmarshal(strings.NewReader(rawJSON), &msg); err != nil {
  1017  		t.Errorf("an unexpected error occurred when parsing into JSONPBUnmarshaler: %v", err)
  1018  	}
  1019  	if msg.RawJSON != rawJSON {
  1020  		t.Errorf("message contents not set correctly after unmarshalling JSON: got %s, wanted %s", msg.RawJSON, rawJSON)
  1021  	}
  1022  }
  1023  
  1024  func TestUnmarshalNullWithJSONPBUnmarshaler(t *testing.T) {
  1025  	rawJSON := `{"stringField":null}`
  1026  	var ptrFieldMsg ptrFieldMessage
  1027  	if err := Unmarshal(strings.NewReader(rawJSON), &ptrFieldMsg); err != nil {
  1028  		t.Errorf("unmarshal error: %v", err)
  1029  	}
  1030  
  1031  	want := ptrFieldMessage{StringField: &stringField{IsSet: true, StringValue: "null"}}
  1032  	if !proto.Equal(&ptrFieldMsg, &want) {
  1033  		t.Errorf("unmarshal result StringField: got %v, want %v", ptrFieldMsg, want)
  1034  	}
  1035  }
  1036  
  1037  func TestUnmarshalAnyJSONPBUnmarshaler(t *testing.T) {
  1038  	rawJSON := `{ "@type": "blah.com/` + dynamicMessageName + `", "foo": "bar", "baz": [0, 1, 2, 3] }`
  1039  	var got anypb.Any
  1040  	if err := Unmarshal(strings.NewReader(rawJSON), &got); err != nil {
  1041  		t.Errorf("an unexpected error occurred when parsing into JSONPBUnmarshaler: %v", err)
  1042  	}
  1043  
  1044  	dm := &dynamicMessage{RawJSON: `{"baz":[0,1,2,3],"foo":"bar"}`}
  1045  	var want anypb.Any
  1046  	if b, err := proto.Marshal(dm); err != nil {
  1047  		t.Errorf("an unexpected error occurred when marshaling message: %v", err)
  1048  	} else {
  1049  		want.TypeUrl = "blah.com/" + dynamicMessageName
  1050  		want.Value = b
  1051  	}
  1052  
  1053  	if !proto.Equal(&got, &want) {
  1054  		t.Errorf("message contents not set correctly after unmarshalling JSON: got %v, wanted %v", got, want)
  1055  	}
  1056  }
  1057  
  1058  const (
  1059  	dynamicMessageName = "google.protobuf.jsonpb.testing.dynamicMessage"
  1060  )
  1061  
  1062  func init() {
  1063  	// we register the custom type below so that we can use it in Any types
  1064  	proto.RegisterType((*dynamicMessage)(nil), dynamicMessageName)
  1065  }
  1066  
  1067  type ptrFieldMessage struct {
  1068  	StringField *stringField `protobuf:"bytes,1,opt,name=stringField"`
  1069  }
  1070  
  1071  func (m *ptrFieldMessage) Reset() {
  1072  }
  1073  
  1074  func (m *ptrFieldMessage) String() string {
  1075  	return m.StringField.StringValue
  1076  }
  1077  
  1078  func (m *ptrFieldMessage) ProtoMessage() {
  1079  }
  1080  
  1081  type stringField struct {
  1082  	IsSet       bool   `protobuf:"varint,1,opt,name=isSet"`
  1083  	StringValue string `protobuf:"bytes,2,opt,name=stringValue"`
  1084  }
  1085  
  1086  func (s *stringField) Reset() {
  1087  }
  1088  
  1089  func (s *stringField) String() string {
  1090  	return s.StringValue
  1091  }
  1092  
  1093  func (s *stringField) ProtoMessage() {
  1094  }
  1095  
  1096  func (s *stringField) UnmarshalJSONPB(jum *Unmarshaler, js []byte) error {
  1097  	s.IsSet = true
  1098  	s.StringValue = string(js)
  1099  	return nil
  1100  }
  1101  
  1102  // dynamicMessage implements protobuf.Message but is not a normal generated message type.
  1103  // It provides implementations of JSONPBMarshaler and JSONPBUnmarshaler for JSON support.
  1104  type dynamicMessage struct {
  1105  	RawJSON string `protobuf:"bytes,1,opt,name=rawJSON"`
  1106  
  1107  	// an unexported nested message is present just to ensure that it
  1108  	// won't result in a panic (see issue #509)
  1109  	Dummy *dynamicMessage `protobuf:"bytes,2,opt,name=dummy"`
  1110  }
  1111  
  1112  func (m *dynamicMessage) Reset() {
  1113  	m.RawJSON = "{}"
  1114  }
  1115  
  1116  func (m *dynamicMessage) String() string {
  1117  	return m.RawJSON
  1118  }
  1119  
  1120  func (m *dynamicMessage) ProtoMessage() {
  1121  }
  1122  
  1123  func (m *dynamicMessage) MarshalJSONPB(jm *Marshaler) ([]byte, error) {
  1124  	return []byte(m.RawJSON), nil
  1125  }
  1126  
  1127  func (m *dynamicMessage) UnmarshalJSONPB(jum *Unmarshaler, js []byte) error {
  1128  	m.RawJSON = string(js)
  1129  	return nil
  1130  }
  1131  
  1132  // Test unmarshaling message containing unset required fields should produce error.
  1133  func TestUnmarshalUnsetRequiredFields(t *testing.T) {
  1134  	tests := []struct {
  1135  		desc string
  1136  		pb   proto.Message
  1137  		json string
  1138  	}{
  1139  		{
  1140  			desc: "direct required field missing",
  1141  			pb:   &pb.MsgWithRequired{},
  1142  			json: `{}`,
  1143  		},
  1144  		{
  1145  			desc: "direct required field set to null",
  1146  			pb:   &pb.MsgWithRequired{},
  1147  			json: `{"str": null}`,
  1148  		},
  1149  		{
  1150  			desc: "indirect required field missing",
  1151  			pb:   &pb.MsgWithIndirectRequired{},
  1152  			json: `{"subm": {}}`,
  1153  		},
  1154  		{
  1155  			desc: "indirect required field set to null",
  1156  			pb:   &pb.MsgWithIndirectRequired{},
  1157  			json: `{"subm": {"str": null}}`,
  1158  		},
  1159  		{
  1160  			desc: "direct required bytes field missing",
  1161  			pb:   &pb.MsgWithRequiredBytes{},
  1162  			json: `{}`,
  1163  		},
  1164  		{
  1165  			desc: "direct required bytes field set to null",
  1166  			pb:   &pb.MsgWithRequiredBytes{},
  1167  			json: `{"byts": null}`,
  1168  		},
  1169  		{
  1170  			desc: "direct required wkt field missing",
  1171  			pb:   &pb.MsgWithRequiredWKT{},
  1172  			json: `{}`,
  1173  		},
  1174  		{
  1175  			desc: "direct required wkt field set to null",
  1176  			pb:   &pb.MsgWithRequiredWKT{},
  1177  			json: `{"str": null}`,
  1178  		},
  1179  		{
  1180  			desc: "any containing message with required field set to null",
  1181  			pb:   &pb.KnownTypes{},
  1182  			json: `{"an": {"@type": "example.com/jsonpb.MsgWithRequired", "str": null}}`,
  1183  		},
  1184  		{
  1185  			desc: "any containing message with missing required field",
  1186  			pb:   &pb.KnownTypes{},
  1187  			json: `{"an": {"@type": "example.com/jsonpb.MsgWithRequired"}}`,
  1188  		},
  1189  		{
  1190  			desc: "missing required in map value",
  1191  			pb:   &pb.MsgWithIndirectRequired{},
  1192  			json: `{"map_field": {"a": {}, "b": {"str": "hi"}}}`,
  1193  		},
  1194  		{
  1195  			desc: "required in map value set to null",
  1196  			pb:   &pb.MsgWithIndirectRequired{},
  1197  			json: `{"map_field": {"a": {"str": "hello"}, "b": {"str": null}}}`,
  1198  		},
  1199  		{
  1200  			desc: "missing required in slice item",
  1201  			pb:   &pb.MsgWithIndirectRequired{},
  1202  			json: `{"slice_field": [{}, {"str": "hi"}]}`,
  1203  		},
  1204  		{
  1205  			desc: "required in slice item set to null",
  1206  			pb:   &pb.MsgWithIndirectRequired{},
  1207  			json: `{"slice_field": [{"str": "hello"}, {"str": null}]}`,
  1208  		},
  1209  		{
  1210  			desc: "required inside oneof missing",
  1211  			pb:   &pb.MsgWithOneof{},
  1212  			json: `{"msgWithRequired": {}}`,
  1213  		},
  1214  		{
  1215  			desc: "required inside oneof set to null",
  1216  			pb:   &pb.MsgWithOneof{},
  1217  			json: `{"msgWithRequired": {"str": null}}`,
  1218  		},
  1219  		{
  1220  			desc: "required field in extension missing",
  1221  			pb:   &pb.Real{},
  1222  			json: `{"[jsonpb.extm]":{}}`,
  1223  		},
  1224  		{
  1225  			desc: "required field in extension set to null",
  1226  			pb:   &pb.Real{},
  1227  			json: `{"[jsonpb.extm]":{"str": null}}`,
  1228  		},
  1229  	}
  1230  
  1231  	for _, tc := range tests {
  1232  		if err := UnmarshalString(tc.json, tc.pb); err == nil {
  1233  			t.Errorf("%s: expecting error in unmarshaling with unset required fields %s", tc.desc, tc.json)
  1234  		}
  1235  	}
  1236  }