1*1c12ee1eSDan Willemsen// Copyright 2019 The Go Authors. All rights reserved. 2*1c12ee1eSDan Willemsen// Use of this source code is governed by a BSD-style 3*1c12ee1eSDan Willemsen// license that can be found in the LICENSE file. 4*1c12ee1eSDan Willemsen 5*1c12ee1eSDan Willemsenpackage protojson_test 6*1c12ee1eSDan Willemsen 7*1c12ee1eSDan Willemsenimport ( 8*1c12ee1eSDan Willemsen "bytes" 9*1c12ee1eSDan Willemsen "math" 10*1c12ee1eSDan Willemsen "testing" 11*1c12ee1eSDan Willemsen 12*1c12ee1eSDan Willemsen "github.com/google/go-cmp/cmp" 13*1c12ee1eSDan Willemsen 14*1c12ee1eSDan Willemsen "google.golang.org/protobuf/encoding/protojson" 15*1c12ee1eSDan Willemsen "google.golang.org/protobuf/internal/detrand" 16*1c12ee1eSDan Willemsen "google.golang.org/protobuf/internal/flags" 17*1c12ee1eSDan Willemsen "google.golang.org/protobuf/proto" 18*1c12ee1eSDan Willemsen "google.golang.org/protobuf/reflect/protoregistry" 19*1c12ee1eSDan Willemsen "google.golang.org/protobuf/testing/protopack" 20*1c12ee1eSDan Willemsen 21*1c12ee1eSDan Willemsen pb2 "google.golang.org/protobuf/internal/testprotos/textpb2" 22*1c12ee1eSDan Willemsen pb3 "google.golang.org/protobuf/internal/testprotos/textpb3" 23*1c12ee1eSDan Willemsen "google.golang.org/protobuf/types/known/anypb" 24*1c12ee1eSDan Willemsen "google.golang.org/protobuf/types/known/durationpb" 25*1c12ee1eSDan Willemsen "google.golang.org/protobuf/types/known/emptypb" 26*1c12ee1eSDan Willemsen "google.golang.org/protobuf/types/known/fieldmaskpb" 27*1c12ee1eSDan Willemsen "google.golang.org/protobuf/types/known/structpb" 28*1c12ee1eSDan Willemsen "google.golang.org/protobuf/types/known/timestamppb" 29*1c12ee1eSDan Willemsen "google.golang.org/protobuf/types/known/wrapperspb" 30*1c12ee1eSDan Willemsen) 31*1c12ee1eSDan Willemsen 32*1c12ee1eSDan Willemsen// Disable detrand to enable direct comparisons on outputs. 33*1c12ee1eSDan Willemsenfunc init() { detrand.Disable() } 34*1c12ee1eSDan Willemsen 35*1c12ee1eSDan Willemsenfunc TestMarshal(t *testing.T) { 36*1c12ee1eSDan Willemsen tests := []struct { 37*1c12ee1eSDan Willemsen desc string 38*1c12ee1eSDan Willemsen mo protojson.MarshalOptions 39*1c12ee1eSDan Willemsen input proto.Message 40*1c12ee1eSDan Willemsen want string 41*1c12ee1eSDan Willemsen wantErr bool // TODO: Verify error message substring. 42*1c12ee1eSDan Willemsen skip bool 43*1c12ee1eSDan Willemsen }{{ 44*1c12ee1eSDan Willemsen desc: "proto2 optional scalars not set", 45*1c12ee1eSDan Willemsen input: &pb2.Scalars{}, 46*1c12ee1eSDan Willemsen want: "{}", 47*1c12ee1eSDan Willemsen }, { 48*1c12ee1eSDan Willemsen desc: "proto3 scalars not set", 49*1c12ee1eSDan Willemsen input: &pb3.Scalars{}, 50*1c12ee1eSDan Willemsen want: "{}", 51*1c12ee1eSDan Willemsen }, { 52*1c12ee1eSDan Willemsen desc: "proto3 optional not set", 53*1c12ee1eSDan Willemsen input: &pb3.Proto3Optional{}, 54*1c12ee1eSDan Willemsen want: "{}", 55*1c12ee1eSDan Willemsen }, { 56*1c12ee1eSDan Willemsen desc: "proto2 optional scalars set to zero values", 57*1c12ee1eSDan Willemsen input: &pb2.Scalars{ 58*1c12ee1eSDan Willemsen OptBool: proto.Bool(false), 59*1c12ee1eSDan Willemsen OptInt32: proto.Int32(0), 60*1c12ee1eSDan Willemsen OptInt64: proto.Int64(0), 61*1c12ee1eSDan Willemsen OptUint32: proto.Uint32(0), 62*1c12ee1eSDan Willemsen OptUint64: proto.Uint64(0), 63*1c12ee1eSDan Willemsen OptSint32: proto.Int32(0), 64*1c12ee1eSDan Willemsen OptSint64: proto.Int64(0), 65*1c12ee1eSDan Willemsen OptFixed32: proto.Uint32(0), 66*1c12ee1eSDan Willemsen OptFixed64: proto.Uint64(0), 67*1c12ee1eSDan Willemsen OptSfixed32: proto.Int32(0), 68*1c12ee1eSDan Willemsen OptSfixed64: proto.Int64(0), 69*1c12ee1eSDan Willemsen OptFloat: proto.Float32(0), 70*1c12ee1eSDan Willemsen OptDouble: proto.Float64(0), 71*1c12ee1eSDan Willemsen OptBytes: []byte{}, 72*1c12ee1eSDan Willemsen OptString: proto.String(""), 73*1c12ee1eSDan Willemsen }, 74*1c12ee1eSDan Willemsen want: `{ 75*1c12ee1eSDan Willemsen "optBool": false, 76*1c12ee1eSDan Willemsen "optInt32": 0, 77*1c12ee1eSDan Willemsen "optInt64": "0", 78*1c12ee1eSDan Willemsen "optUint32": 0, 79*1c12ee1eSDan Willemsen "optUint64": "0", 80*1c12ee1eSDan Willemsen "optSint32": 0, 81*1c12ee1eSDan Willemsen "optSint64": "0", 82*1c12ee1eSDan Willemsen "optFixed32": 0, 83*1c12ee1eSDan Willemsen "optFixed64": "0", 84*1c12ee1eSDan Willemsen "optSfixed32": 0, 85*1c12ee1eSDan Willemsen "optSfixed64": "0", 86*1c12ee1eSDan Willemsen "optFloat": 0, 87*1c12ee1eSDan Willemsen "optDouble": 0, 88*1c12ee1eSDan Willemsen "optBytes": "", 89*1c12ee1eSDan Willemsen "optString": "" 90*1c12ee1eSDan Willemsen}`, 91*1c12ee1eSDan Willemsen }, { 92*1c12ee1eSDan Willemsen desc: "proto3 optional set to zero values", 93*1c12ee1eSDan Willemsen input: &pb3.Proto3Optional{ 94*1c12ee1eSDan Willemsen OptBool: proto.Bool(false), 95*1c12ee1eSDan Willemsen OptInt32: proto.Int32(0), 96*1c12ee1eSDan Willemsen OptInt64: proto.Int64(0), 97*1c12ee1eSDan Willemsen OptUint32: proto.Uint32(0), 98*1c12ee1eSDan Willemsen OptUint64: proto.Uint64(0), 99*1c12ee1eSDan Willemsen OptFloat: proto.Float32(0), 100*1c12ee1eSDan Willemsen OptDouble: proto.Float64(0), 101*1c12ee1eSDan Willemsen OptString: proto.String(""), 102*1c12ee1eSDan Willemsen OptBytes: []byte{}, 103*1c12ee1eSDan Willemsen OptEnum: pb3.Enum_ZERO.Enum(), 104*1c12ee1eSDan Willemsen OptMessage: &pb3.Nested{}, 105*1c12ee1eSDan Willemsen }, 106*1c12ee1eSDan Willemsen want: `{ 107*1c12ee1eSDan Willemsen "optBool": false, 108*1c12ee1eSDan Willemsen "optInt32": 0, 109*1c12ee1eSDan Willemsen "optInt64": "0", 110*1c12ee1eSDan Willemsen "optUint32": 0, 111*1c12ee1eSDan Willemsen "optUint64": "0", 112*1c12ee1eSDan Willemsen "optFloat": 0, 113*1c12ee1eSDan Willemsen "optDouble": 0, 114*1c12ee1eSDan Willemsen "optString": "", 115*1c12ee1eSDan Willemsen "optBytes": "", 116*1c12ee1eSDan Willemsen "optEnum": "ZERO", 117*1c12ee1eSDan Willemsen "optMessage": {} 118*1c12ee1eSDan Willemsen}`, 119*1c12ee1eSDan Willemsen }, { 120*1c12ee1eSDan Willemsen desc: "proto2 optional scalars set to some values", 121*1c12ee1eSDan Willemsen input: &pb2.Scalars{ 122*1c12ee1eSDan Willemsen OptBool: proto.Bool(true), 123*1c12ee1eSDan Willemsen OptInt32: proto.Int32(0xff), 124*1c12ee1eSDan Willemsen OptInt64: proto.Int64(0xdeadbeef), 125*1c12ee1eSDan Willemsen OptUint32: proto.Uint32(47), 126*1c12ee1eSDan Willemsen OptUint64: proto.Uint64(0xdeadbeef), 127*1c12ee1eSDan Willemsen OptSint32: proto.Int32(-1001), 128*1c12ee1eSDan Willemsen OptSint64: proto.Int64(-0xffff), 129*1c12ee1eSDan Willemsen OptFixed64: proto.Uint64(64), 130*1c12ee1eSDan Willemsen OptSfixed32: proto.Int32(-32), 131*1c12ee1eSDan Willemsen OptFloat: proto.Float32(1.02), 132*1c12ee1eSDan Willemsen OptDouble: proto.Float64(1.234), 133*1c12ee1eSDan Willemsen OptBytes: []byte("谷歌"), 134*1c12ee1eSDan Willemsen OptString: proto.String("谷歌"), 135*1c12ee1eSDan Willemsen }, 136*1c12ee1eSDan Willemsen want: `{ 137*1c12ee1eSDan Willemsen "optBool": true, 138*1c12ee1eSDan Willemsen "optInt32": 255, 139*1c12ee1eSDan Willemsen "optInt64": "3735928559", 140*1c12ee1eSDan Willemsen "optUint32": 47, 141*1c12ee1eSDan Willemsen "optUint64": "3735928559", 142*1c12ee1eSDan Willemsen "optSint32": -1001, 143*1c12ee1eSDan Willemsen "optSint64": "-65535", 144*1c12ee1eSDan Willemsen "optFixed64": "64", 145*1c12ee1eSDan Willemsen "optSfixed32": -32, 146*1c12ee1eSDan Willemsen "optFloat": 1.02, 147*1c12ee1eSDan Willemsen "optDouble": 1.234, 148*1c12ee1eSDan Willemsen "optBytes": "6LC35q2M", 149*1c12ee1eSDan Willemsen "optString": "谷歌" 150*1c12ee1eSDan Willemsen}`, 151*1c12ee1eSDan Willemsen }, { 152*1c12ee1eSDan Willemsen desc: "string", 153*1c12ee1eSDan Willemsen input: &pb3.Scalars{ 154*1c12ee1eSDan Willemsen SString: "谷歌", 155*1c12ee1eSDan Willemsen }, 156*1c12ee1eSDan Willemsen want: `{ 157*1c12ee1eSDan Willemsen "sString": "谷歌" 158*1c12ee1eSDan Willemsen}`, 159*1c12ee1eSDan Willemsen }, { 160*1c12ee1eSDan Willemsen desc: "string with invalid UTF8", 161*1c12ee1eSDan Willemsen input: &pb3.Scalars{ 162*1c12ee1eSDan Willemsen SString: "abc\xff", 163*1c12ee1eSDan Willemsen }, 164*1c12ee1eSDan Willemsen wantErr: true, 165*1c12ee1eSDan Willemsen }, { 166*1c12ee1eSDan Willemsen desc: "float nan", 167*1c12ee1eSDan Willemsen input: &pb3.Scalars{ 168*1c12ee1eSDan Willemsen SFloat: float32(math.NaN()), 169*1c12ee1eSDan Willemsen }, 170*1c12ee1eSDan Willemsen want: `{ 171*1c12ee1eSDan Willemsen "sFloat": "NaN" 172*1c12ee1eSDan Willemsen}`, 173*1c12ee1eSDan Willemsen }, { 174*1c12ee1eSDan Willemsen desc: "float positive infinity", 175*1c12ee1eSDan Willemsen input: &pb3.Scalars{ 176*1c12ee1eSDan Willemsen SFloat: float32(math.Inf(1)), 177*1c12ee1eSDan Willemsen }, 178*1c12ee1eSDan Willemsen want: `{ 179*1c12ee1eSDan Willemsen "sFloat": "Infinity" 180*1c12ee1eSDan Willemsen}`, 181*1c12ee1eSDan Willemsen }, { 182*1c12ee1eSDan Willemsen desc: "float negative infinity", 183*1c12ee1eSDan Willemsen input: &pb3.Scalars{ 184*1c12ee1eSDan Willemsen SFloat: float32(math.Inf(-1)), 185*1c12ee1eSDan Willemsen }, 186*1c12ee1eSDan Willemsen want: `{ 187*1c12ee1eSDan Willemsen "sFloat": "-Infinity" 188*1c12ee1eSDan Willemsen}`, 189*1c12ee1eSDan Willemsen }, { 190*1c12ee1eSDan Willemsen desc: "double nan", 191*1c12ee1eSDan Willemsen input: &pb3.Scalars{ 192*1c12ee1eSDan Willemsen SDouble: math.NaN(), 193*1c12ee1eSDan Willemsen }, 194*1c12ee1eSDan Willemsen want: `{ 195*1c12ee1eSDan Willemsen "sDouble": "NaN" 196*1c12ee1eSDan Willemsen}`, 197*1c12ee1eSDan Willemsen }, { 198*1c12ee1eSDan Willemsen desc: "double positive infinity", 199*1c12ee1eSDan Willemsen input: &pb3.Scalars{ 200*1c12ee1eSDan Willemsen SDouble: math.Inf(1), 201*1c12ee1eSDan Willemsen }, 202*1c12ee1eSDan Willemsen want: `{ 203*1c12ee1eSDan Willemsen "sDouble": "Infinity" 204*1c12ee1eSDan Willemsen}`, 205*1c12ee1eSDan Willemsen }, { 206*1c12ee1eSDan Willemsen desc: "double negative infinity", 207*1c12ee1eSDan Willemsen input: &pb3.Scalars{ 208*1c12ee1eSDan Willemsen SDouble: math.Inf(-1), 209*1c12ee1eSDan Willemsen }, 210*1c12ee1eSDan Willemsen want: `{ 211*1c12ee1eSDan Willemsen "sDouble": "-Infinity" 212*1c12ee1eSDan Willemsen}`, 213*1c12ee1eSDan Willemsen }, { 214*1c12ee1eSDan Willemsen desc: "proto2 enum not set", 215*1c12ee1eSDan Willemsen input: &pb2.Enums{}, 216*1c12ee1eSDan Willemsen want: "{}", 217*1c12ee1eSDan Willemsen }, { 218*1c12ee1eSDan Willemsen desc: "proto2 enum set to zero value", 219*1c12ee1eSDan Willemsen input: &pb2.Enums{ 220*1c12ee1eSDan Willemsen OptEnum: pb2.Enum(0).Enum(), 221*1c12ee1eSDan Willemsen OptNestedEnum: pb2.Enums_NestedEnum(0).Enum(), 222*1c12ee1eSDan Willemsen }, 223*1c12ee1eSDan Willemsen want: `{ 224*1c12ee1eSDan Willemsen "optEnum": 0, 225*1c12ee1eSDan Willemsen "optNestedEnum": 0 226*1c12ee1eSDan Willemsen}`, 227*1c12ee1eSDan Willemsen }, { 228*1c12ee1eSDan Willemsen desc: "proto2 enum", 229*1c12ee1eSDan Willemsen input: &pb2.Enums{ 230*1c12ee1eSDan Willemsen OptEnum: pb2.Enum_ONE.Enum(), 231*1c12ee1eSDan Willemsen OptNestedEnum: pb2.Enums_UNO.Enum(), 232*1c12ee1eSDan Willemsen }, 233*1c12ee1eSDan Willemsen want: `{ 234*1c12ee1eSDan Willemsen "optEnum": "ONE", 235*1c12ee1eSDan Willemsen "optNestedEnum": "UNO" 236*1c12ee1eSDan Willemsen}`, 237*1c12ee1eSDan Willemsen }, { 238*1c12ee1eSDan Willemsen desc: "proto2 enum set to numeric values", 239*1c12ee1eSDan Willemsen input: &pb2.Enums{ 240*1c12ee1eSDan Willemsen OptEnum: pb2.Enum(2).Enum(), 241*1c12ee1eSDan Willemsen OptNestedEnum: pb2.Enums_NestedEnum(2).Enum(), 242*1c12ee1eSDan Willemsen }, 243*1c12ee1eSDan Willemsen want: `{ 244*1c12ee1eSDan Willemsen "optEnum": "TWO", 245*1c12ee1eSDan Willemsen "optNestedEnum": "DOS" 246*1c12ee1eSDan Willemsen}`, 247*1c12ee1eSDan Willemsen }, { 248*1c12ee1eSDan Willemsen desc: "proto2 enum set to unnamed numeric values", 249*1c12ee1eSDan Willemsen input: &pb2.Enums{ 250*1c12ee1eSDan Willemsen OptEnum: pb2.Enum(101).Enum(), 251*1c12ee1eSDan Willemsen OptNestedEnum: pb2.Enums_NestedEnum(-101).Enum(), 252*1c12ee1eSDan Willemsen }, 253*1c12ee1eSDan Willemsen want: `{ 254*1c12ee1eSDan Willemsen "optEnum": 101, 255*1c12ee1eSDan Willemsen "optNestedEnum": -101 256*1c12ee1eSDan Willemsen}`, 257*1c12ee1eSDan Willemsen }, { 258*1c12ee1eSDan Willemsen desc: "proto3 enum not set", 259*1c12ee1eSDan Willemsen input: &pb3.Enums{}, 260*1c12ee1eSDan Willemsen want: "{}", 261*1c12ee1eSDan Willemsen }, { 262*1c12ee1eSDan Willemsen desc: "proto3 enum set to zero value", 263*1c12ee1eSDan Willemsen input: &pb3.Enums{ 264*1c12ee1eSDan Willemsen SEnum: pb3.Enum_ZERO, 265*1c12ee1eSDan Willemsen SNestedEnum: pb3.Enums_CERO, 266*1c12ee1eSDan Willemsen }, 267*1c12ee1eSDan Willemsen want: "{}", 268*1c12ee1eSDan Willemsen }, { 269*1c12ee1eSDan Willemsen desc: "proto3 enum", 270*1c12ee1eSDan Willemsen input: &pb3.Enums{ 271*1c12ee1eSDan Willemsen SEnum: pb3.Enum_ONE, 272*1c12ee1eSDan Willemsen SNestedEnum: pb3.Enums_UNO, 273*1c12ee1eSDan Willemsen }, 274*1c12ee1eSDan Willemsen want: `{ 275*1c12ee1eSDan Willemsen "sEnum": "ONE", 276*1c12ee1eSDan Willemsen "sNestedEnum": "UNO" 277*1c12ee1eSDan Willemsen}`, 278*1c12ee1eSDan Willemsen }, { 279*1c12ee1eSDan Willemsen desc: "proto3 enum set to numeric values", 280*1c12ee1eSDan Willemsen input: &pb3.Enums{ 281*1c12ee1eSDan Willemsen SEnum: 2, 282*1c12ee1eSDan Willemsen SNestedEnum: 2, 283*1c12ee1eSDan Willemsen }, 284*1c12ee1eSDan Willemsen want: `{ 285*1c12ee1eSDan Willemsen "sEnum": "TWO", 286*1c12ee1eSDan Willemsen "sNestedEnum": "DOS" 287*1c12ee1eSDan Willemsen}`, 288*1c12ee1eSDan Willemsen }, { 289*1c12ee1eSDan Willemsen desc: "proto3 enum set to unnamed numeric values", 290*1c12ee1eSDan Willemsen input: &pb3.Enums{ 291*1c12ee1eSDan Willemsen SEnum: -47, 292*1c12ee1eSDan Willemsen SNestedEnum: 47, 293*1c12ee1eSDan Willemsen }, 294*1c12ee1eSDan Willemsen want: `{ 295*1c12ee1eSDan Willemsen "sEnum": -47, 296*1c12ee1eSDan Willemsen "sNestedEnum": 47 297*1c12ee1eSDan Willemsen}`, 298*1c12ee1eSDan Willemsen }, { 299*1c12ee1eSDan Willemsen desc: "proto2 nested message not set", 300*1c12ee1eSDan Willemsen input: &pb2.Nests{}, 301*1c12ee1eSDan Willemsen want: "{}", 302*1c12ee1eSDan Willemsen }, { 303*1c12ee1eSDan Willemsen desc: "proto2 nested message set to empty", 304*1c12ee1eSDan Willemsen input: &pb2.Nests{ 305*1c12ee1eSDan Willemsen OptNested: &pb2.Nested{}, 306*1c12ee1eSDan Willemsen Optgroup: &pb2.Nests_OptGroup{}, 307*1c12ee1eSDan Willemsen }, 308*1c12ee1eSDan Willemsen want: `{ 309*1c12ee1eSDan Willemsen "optNested": {}, 310*1c12ee1eSDan Willemsen "optgroup": {} 311*1c12ee1eSDan Willemsen}`, 312*1c12ee1eSDan Willemsen }, { 313*1c12ee1eSDan Willemsen desc: "proto2 nested messages", 314*1c12ee1eSDan Willemsen input: &pb2.Nests{ 315*1c12ee1eSDan Willemsen OptNested: &pb2.Nested{ 316*1c12ee1eSDan Willemsen OptString: proto.String("nested message"), 317*1c12ee1eSDan Willemsen OptNested: &pb2.Nested{ 318*1c12ee1eSDan Willemsen OptString: proto.String("another nested message"), 319*1c12ee1eSDan Willemsen }, 320*1c12ee1eSDan Willemsen }, 321*1c12ee1eSDan Willemsen }, 322*1c12ee1eSDan Willemsen want: `{ 323*1c12ee1eSDan Willemsen "optNested": { 324*1c12ee1eSDan Willemsen "optString": "nested message", 325*1c12ee1eSDan Willemsen "optNested": { 326*1c12ee1eSDan Willemsen "optString": "another nested message" 327*1c12ee1eSDan Willemsen } 328*1c12ee1eSDan Willemsen } 329*1c12ee1eSDan Willemsen}`, 330*1c12ee1eSDan Willemsen }, { 331*1c12ee1eSDan Willemsen desc: "proto2 groups", 332*1c12ee1eSDan Willemsen input: &pb2.Nests{ 333*1c12ee1eSDan Willemsen Optgroup: &pb2.Nests_OptGroup{ 334*1c12ee1eSDan Willemsen OptString: proto.String("inside a group"), 335*1c12ee1eSDan Willemsen OptNested: &pb2.Nested{ 336*1c12ee1eSDan Willemsen OptString: proto.String("nested message inside a group"), 337*1c12ee1eSDan Willemsen }, 338*1c12ee1eSDan Willemsen Optnestedgroup: &pb2.Nests_OptGroup_OptNestedGroup{ 339*1c12ee1eSDan Willemsen OptFixed32: proto.Uint32(47), 340*1c12ee1eSDan Willemsen }, 341*1c12ee1eSDan Willemsen }, 342*1c12ee1eSDan Willemsen }, 343*1c12ee1eSDan Willemsen want: `{ 344*1c12ee1eSDan Willemsen "optgroup": { 345*1c12ee1eSDan Willemsen "optString": "inside a group", 346*1c12ee1eSDan Willemsen "optNested": { 347*1c12ee1eSDan Willemsen "optString": "nested message inside a group" 348*1c12ee1eSDan Willemsen }, 349*1c12ee1eSDan Willemsen "optnestedgroup": { 350*1c12ee1eSDan Willemsen "optFixed32": 47 351*1c12ee1eSDan Willemsen } 352*1c12ee1eSDan Willemsen } 353*1c12ee1eSDan Willemsen}`, 354*1c12ee1eSDan Willemsen }, { 355*1c12ee1eSDan Willemsen desc: "proto3 nested message not set", 356*1c12ee1eSDan Willemsen input: &pb3.Nests{}, 357*1c12ee1eSDan Willemsen want: "{}", 358*1c12ee1eSDan Willemsen }, { 359*1c12ee1eSDan Willemsen desc: "proto3 nested message set to empty", 360*1c12ee1eSDan Willemsen input: &pb3.Nests{ 361*1c12ee1eSDan Willemsen SNested: &pb3.Nested{}, 362*1c12ee1eSDan Willemsen }, 363*1c12ee1eSDan Willemsen want: `{ 364*1c12ee1eSDan Willemsen "sNested": {} 365*1c12ee1eSDan Willemsen}`, 366*1c12ee1eSDan Willemsen }, { 367*1c12ee1eSDan Willemsen desc: "proto3 nested message", 368*1c12ee1eSDan Willemsen input: &pb3.Nests{ 369*1c12ee1eSDan Willemsen SNested: &pb3.Nested{ 370*1c12ee1eSDan Willemsen SString: "nested message", 371*1c12ee1eSDan Willemsen SNested: &pb3.Nested{ 372*1c12ee1eSDan Willemsen SString: "another nested message", 373*1c12ee1eSDan Willemsen }, 374*1c12ee1eSDan Willemsen }, 375*1c12ee1eSDan Willemsen }, 376*1c12ee1eSDan Willemsen want: `{ 377*1c12ee1eSDan Willemsen "sNested": { 378*1c12ee1eSDan Willemsen "sString": "nested message", 379*1c12ee1eSDan Willemsen "sNested": { 380*1c12ee1eSDan Willemsen "sString": "another nested message" 381*1c12ee1eSDan Willemsen } 382*1c12ee1eSDan Willemsen } 383*1c12ee1eSDan Willemsen}`, 384*1c12ee1eSDan Willemsen }, { 385*1c12ee1eSDan Willemsen desc: "oneof not set", 386*1c12ee1eSDan Willemsen input: &pb3.Oneofs{}, 387*1c12ee1eSDan Willemsen want: "{}", 388*1c12ee1eSDan Willemsen }, { 389*1c12ee1eSDan Willemsen desc: "oneof set to empty string", 390*1c12ee1eSDan Willemsen input: &pb3.Oneofs{ 391*1c12ee1eSDan Willemsen Union: &pb3.Oneofs_OneofString{}, 392*1c12ee1eSDan Willemsen }, 393*1c12ee1eSDan Willemsen want: `{ 394*1c12ee1eSDan Willemsen "oneofString": "" 395*1c12ee1eSDan Willemsen}`, 396*1c12ee1eSDan Willemsen }, { 397*1c12ee1eSDan Willemsen desc: "oneof set to string", 398*1c12ee1eSDan Willemsen input: &pb3.Oneofs{ 399*1c12ee1eSDan Willemsen Union: &pb3.Oneofs_OneofString{ 400*1c12ee1eSDan Willemsen OneofString: "hello", 401*1c12ee1eSDan Willemsen }, 402*1c12ee1eSDan Willemsen }, 403*1c12ee1eSDan Willemsen want: `{ 404*1c12ee1eSDan Willemsen "oneofString": "hello" 405*1c12ee1eSDan Willemsen}`, 406*1c12ee1eSDan Willemsen }, { 407*1c12ee1eSDan Willemsen desc: "oneof set to enum", 408*1c12ee1eSDan Willemsen input: &pb3.Oneofs{ 409*1c12ee1eSDan Willemsen Union: &pb3.Oneofs_OneofEnum{ 410*1c12ee1eSDan Willemsen OneofEnum: pb3.Enum_ZERO, 411*1c12ee1eSDan Willemsen }, 412*1c12ee1eSDan Willemsen }, 413*1c12ee1eSDan Willemsen want: `{ 414*1c12ee1eSDan Willemsen "oneofEnum": "ZERO" 415*1c12ee1eSDan Willemsen}`, 416*1c12ee1eSDan Willemsen }, { 417*1c12ee1eSDan Willemsen desc: "oneof set to empty message", 418*1c12ee1eSDan Willemsen input: &pb3.Oneofs{ 419*1c12ee1eSDan Willemsen Union: &pb3.Oneofs_OneofNested{ 420*1c12ee1eSDan Willemsen OneofNested: &pb3.Nested{}, 421*1c12ee1eSDan Willemsen }, 422*1c12ee1eSDan Willemsen }, 423*1c12ee1eSDan Willemsen want: `{ 424*1c12ee1eSDan Willemsen "oneofNested": {} 425*1c12ee1eSDan Willemsen}`, 426*1c12ee1eSDan Willemsen }, { 427*1c12ee1eSDan Willemsen desc: "oneof set to message", 428*1c12ee1eSDan Willemsen input: &pb3.Oneofs{ 429*1c12ee1eSDan Willemsen Union: &pb3.Oneofs_OneofNested{ 430*1c12ee1eSDan Willemsen OneofNested: &pb3.Nested{ 431*1c12ee1eSDan Willemsen SString: "nested message", 432*1c12ee1eSDan Willemsen }, 433*1c12ee1eSDan Willemsen }, 434*1c12ee1eSDan Willemsen }, 435*1c12ee1eSDan Willemsen want: `{ 436*1c12ee1eSDan Willemsen "oneofNested": { 437*1c12ee1eSDan Willemsen "sString": "nested message" 438*1c12ee1eSDan Willemsen } 439*1c12ee1eSDan Willemsen}`, 440*1c12ee1eSDan Willemsen }, { 441*1c12ee1eSDan Willemsen desc: "repeated fields not set", 442*1c12ee1eSDan Willemsen input: &pb2.Repeats{}, 443*1c12ee1eSDan Willemsen want: "{}", 444*1c12ee1eSDan Willemsen }, { 445*1c12ee1eSDan Willemsen desc: "repeated fields set to empty slices", 446*1c12ee1eSDan Willemsen input: &pb2.Repeats{ 447*1c12ee1eSDan Willemsen RptBool: []bool{}, 448*1c12ee1eSDan Willemsen RptInt32: []int32{}, 449*1c12ee1eSDan Willemsen RptInt64: []int64{}, 450*1c12ee1eSDan Willemsen RptUint32: []uint32{}, 451*1c12ee1eSDan Willemsen RptUint64: []uint64{}, 452*1c12ee1eSDan Willemsen RptFloat: []float32{}, 453*1c12ee1eSDan Willemsen RptDouble: []float64{}, 454*1c12ee1eSDan Willemsen RptBytes: [][]byte{}, 455*1c12ee1eSDan Willemsen }, 456*1c12ee1eSDan Willemsen want: "{}", 457*1c12ee1eSDan Willemsen }, { 458*1c12ee1eSDan Willemsen desc: "repeated fields set to some values", 459*1c12ee1eSDan Willemsen input: &pb2.Repeats{ 460*1c12ee1eSDan Willemsen RptBool: []bool{true, false, true, true}, 461*1c12ee1eSDan Willemsen RptInt32: []int32{1, 6, 0, 0}, 462*1c12ee1eSDan Willemsen RptInt64: []int64{-64, 47}, 463*1c12ee1eSDan Willemsen RptUint32: []uint32{0xff, 0xffff}, 464*1c12ee1eSDan Willemsen RptUint64: []uint64{0xdeadbeef}, 465*1c12ee1eSDan Willemsen RptFloat: []float32{float32(math.NaN()), float32(math.Inf(1)), float32(math.Inf(-1)), 1.034}, 466*1c12ee1eSDan Willemsen RptDouble: []float64{math.NaN(), math.Inf(1), math.Inf(-1), 1.23e-308}, 467*1c12ee1eSDan Willemsen RptString: []string{"hello", "世界"}, 468*1c12ee1eSDan Willemsen RptBytes: [][]byte{ 469*1c12ee1eSDan Willemsen []byte("hello"), 470*1c12ee1eSDan Willemsen []byte("\xe4\xb8\x96\xe7\x95\x8c"), 471*1c12ee1eSDan Willemsen }, 472*1c12ee1eSDan Willemsen }, 473*1c12ee1eSDan Willemsen want: `{ 474*1c12ee1eSDan Willemsen "rptBool": [ 475*1c12ee1eSDan Willemsen true, 476*1c12ee1eSDan Willemsen false, 477*1c12ee1eSDan Willemsen true, 478*1c12ee1eSDan Willemsen true 479*1c12ee1eSDan Willemsen ], 480*1c12ee1eSDan Willemsen "rptInt32": [ 481*1c12ee1eSDan Willemsen 1, 482*1c12ee1eSDan Willemsen 6, 483*1c12ee1eSDan Willemsen 0, 484*1c12ee1eSDan Willemsen 0 485*1c12ee1eSDan Willemsen ], 486*1c12ee1eSDan Willemsen "rptInt64": [ 487*1c12ee1eSDan Willemsen "-64", 488*1c12ee1eSDan Willemsen "47" 489*1c12ee1eSDan Willemsen ], 490*1c12ee1eSDan Willemsen "rptUint32": [ 491*1c12ee1eSDan Willemsen 255, 492*1c12ee1eSDan Willemsen 65535 493*1c12ee1eSDan Willemsen ], 494*1c12ee1eSDan Willemsen "rptUint64": [ 495*1c12ee1eSDan Willemsen "3735928559" 496*1c12ee1eSDan Willemsen ], 497*1c12ee1eSDan Willemsen "rptFloat": [ 498*1c12ee1eSDan Willemsen "NaN", 499*1c12ee1eSDan Willemsen "Infinity", 500*1c12ee1eSDan Willemsen "-Infinity", 501*1c12ee1eSDan Willemsen 1.034 502*1c12ee1eSDan Willemsen ], 503*1c12ee1eSDan Willemsen "rptDouble": [ 504*1c12ee1eSDan Willemsen "NaN", 505*1c12ee1eSDan Willemsen "Infinity", 506*1c12ee1eSDan Willemsen "-Infinity", 507*1c12ee1eSDan Willemsen 1.23e-308 508*1c12ee1eSDan Willemsen ], 509*1c12ee1eSDan Willemsen "rptString": [ 510*1c12ee1eSDan Willemsen "hello", 511*1c12ee1eSDan Willemsen "世界" 512*1c12ee1eSDan Willemsen ], 513*1c12ee1eSDan Willemsen "rptBytes": [ 514*1c12ee1eSDan Willemsen "aGVsbG8=", 515*1c12ee1eSDan Willemsen "5LiW55WM" 516*1c12ee1eSDan Willemsen ] 517*1c12ee1eSDan Willemsen}`, 518*1c12ee1eSDan Willemsen }, { 519*1c12ee1eSDan Willemsen desc: "repeated enums", 520*1c12ee1eSDan Willemsen input: &pb2.Enums{ 521*1c12ee1eSDan Willemsen RptEnum: []pb2.Enum{pb2.Enum_ONE, 2, pb2.Enum_TEN, 42}, 522*1c12ee1eSDan Willemsen RptNestedEnum: []pb2.Enums_NestedEnum{2, 47, 10}, 523*1c12ee1eSDan Willemsen }, 524*1c12ee1eSDan Willemsen want: `{ 525*1c12ee1eSDan Willemsen "rptEnum": [ 526*1c12ee1eSDan Willemsen "ONE", 527*1c12ee1eSDan Willemsen "TWO", 528*1c12ee1eSDan Willemsen "TEN", 529*1c12ee1eSDan Willemsen 42 530*1c12ee1eSDan Willemsen ], 531*1c12ee1eSDan Willemsen "rptNestedEnum": [ 532*1c12ee1eSDan Willemsen "DOS", 533*1c12ee1eSDan Willemsen 47, 534*1c12ee1eSDan Willemsen "DIEZ" 535*1c12ee1eSDan Willemsen ] 536*1c12ee1eSDan Willemsen}`, 537*1c12ee1eSDan Willemsen }, { 538*1c12ee1eSDan Willemsen desc: "repeated messages set to empty", 539*1c12ee1eSDan Willemsen input: &pb2.Nests{ 540*1c12ee1eSDan Willemsen RptNested: []*pb2.Nested{}, 541*1c12ee1eSDan Willemsen Rptgroup: []*pb2.Nests_RptGroup{}, 542*1c12ee1eSDan Willemsen }, 543*1c12ee1eSDan Willemsen want: "{}", 544*1c12ee1eSDan Willemsen }, { 545*1c12ee1eSDan Willemsen desc: "repeated messages", 546*1c12ee1eSDan Willemsen input: &pb2.Nests{ 547*1c12ee1eSDan Willemsen RptNested: []*pb2.Nested{ 548*1c12ee1eSDan Willemsen { 549*1c12ee1eSDan Willemsen OptString: proto.String("repeat nested one"), 550*1c12ee1eSDan Willemsen }, 551*1c12ee1eSDan Willemsen { 552*1c12ee1eSDan Willemsen OptString: proto.String("repeat nested two"), 553*1c12ee1eSDan Willemsen OptNested: &pb2.Nested{ 554*1c12ee1eSDan Willemsen OptString: proto.String("inside repeat nested two"), 555*1c12ee1eSDan Willemsen }, 556*1c12ee1eSDan Willemsen }, 557*1c12ee1eSDan Willemsen {}, 558*1c12ee1eSDan Willemsen }, 559*1c12ee1eSDan Willemsen }, 560*1c12ee1eSDan Willemsen want: `{ 561*1c12ee1eSDan Willemsen "rptNested": [ 562*1c12ee1eSDan Willemsen { 563*1c12ee1eSDan Willemsen "optString": "repeat nested one" 564*1c12ee1eSDan Willemsen }, 565*1c12ee1eSDan Willemsen { 566*1c12ee1eSDan Willemsen "optString": "repeat nested two", 567*1c12ee1eSDan Willemsen "optNested": { 568*1c12ee1eSDan Willemsen "optString": "inside repeat nested two" 569*1c12ee1eSDan Willemsen } 570*1c12ee1eSDan Willemsen }, 571*1c12ee1eSDan Willemsen {} 572*1c12ee1eSDan Willemsen ] 573*1c12ee1eSDan Willemsen}`, 574*1c12ee1eSDan Willemsen }, { 575*1c12ee1eSDan Willemsen desc: "repeated messages contains nil value", 576*1c12ee1eSDan Willemsen input: &pb2.Nests{ 577*1c12ee1eSDan Willemsen RptNested: []*pb2.Nested{nil, {}}, 578*1c12ee1eSDan Willemsen }, 579*1c12ee1eSDan Willemsen want: `{ 580*1c12ee1eSDan Willemsen "rptNested": [ 581*1c12ee1eSDan Willemsen {}, 582*1c12ee1eSDan Willemsen {} 583*1c12ee1eSDan Willemsen ] 584*1c12ee1eSDan Willemsen}`, 585*1c12ee1eSDan Willemsen }, { 586*1c12ee1eSDan Willemsen desc: "repeated groups", 587*1c12ee1eSDan Willemsen input: &pb2.Nests{ 588*1c12ee1eSDan Willemsen Rptgroup: []*pb2.Nests_RptGroup{ 589*1c12ee1eSDan Willemsen { 590*1c12ee1eSDan Willemsen RptString: []string{"hello", "world"}, 591*1c12ee1eSDan Willemsen }, 592*1c12ee1eSDan Willemsen {}, 593*1c12ee1eSDan Willemsen nil, 594*1c12ee1eSDan Willemsen }, 595*1c12ee1eSDan Willemsen }, 596*1c12ee1eSDan Willemsen want: `{ 597*1c12ee1eSDan Willemsen "rptgroup": [ 598*1c12ee1eSDan Willemsen { 599*1c12ee1eSDan Willemsen "rptString": [ 600*1c12ee1eSDan Willemsen "hello", 601*1c12ee1eSDan Willemsen "world" 602*1c12ee1eSDan Willemsen ] 603*1c12ee1eSDan Willemsen }, 604*1c12ee1eSDan Willemsen {}, 605*1c12ee1eSDan Willemsen {} 606*1c12ee1eSDan Willemsen ] 607*1c12ee1eSDan Willemsen}`, 608*1c12ee1eSDan Willemsen }, { 609*1c12ee1eSDan Willemsen desc: "map fields not set", 610*1c12ee1eSDan Willemsen input: &pb3.Maps{}, 611*1c12ee1eSDan Willemsen want: "{}", 612*1c12ee1eSDan Willemsen }, { 613*1c12ee1eSDan Willemsen desc: "map fields set to empty", 614*1c12ee1eSDan Willemsen input: &pb3.Maps{ 615*1c12ee1eSDan Willemsen Int32ToStr: map[int32]string{}, 616*1c12ee1eSDan Willemsen BoolToUint32: map[bool]uint32{}, 617*1c12ee1eSDan Willemsen Uint64ToEnum: map[uint64]pb3.Enum{}, 618*1c12ee1eSDan Willemsen StrToNested: map[string]*pb3.Nested{}, 619*1c12ee1eSDan Willemsen StrToOneofs: map[string]*pb3.Oneofs{}, 620*1c12ee1eSDan Willemsen }, 621*1c12ee1eSDan Willemsen want: "{}", 622*1c12ee1eSDan Willemsen }, { 623*1c12ee1eSDan Willemsen desc: "map fields 1", 624*1c12ee1eSDan Willemsen input: &pb3.Maps{ 625*1c12ee1eSDan Willemsen BoolToUint32: map[bool]uint32{ 626*1c12ee1eSDan Willemsen true: 42, 627*1c12ee1eSDan Willemsen false: 101, 628*1c12ee1eSDan Willemsen }, 629*1c12ee1eSDan Willemsen }, 630*1c12ee1eSDan Willemsen want: `{ 631*1c12ee1eSDan Willemsen "boolToUint32": { 632*1c12ee1eSDan Willemsen "false": 101, 633*1c12ee1eSDan Willemsen "true": 42 634*1c12ee1eSDan Willemsen } 635*1c12ee1eSDan Willemsen}`, 636*1c12ee1eSDan Willemsen }, { 637*1c12ee1eSDan Willemsen desc: "map fields 2", 638*1c12ee1eSDan Willemsen input: &pb3.Maps{ 639*1c12ee1eSDan Willemsen Int32ToStr: map[int32]string{ 640*1c12ee1eSDan Willemsen -101: "-101", 641*1c12ee1eSDan Willemsen 0xff: "0xff", 642*1c12ee1eSDan Willemsen 0: "zero", 643*1c12ee1eSDan Willemsen }, 644*1c12ee1eSDan Willemsen }, 645*1c12ee1eSDan Willemsen want: `{ 646*1c12ee1eSDan Willemsen "int32ToStr": { 647*1c12ee1eSDan Willemsen "-101": "-101", 648*1c12ee1eSDan Willemsen "0": "zero", 649*1c12ee1eSDan Willemsen "255": "0xff" 650*1c12ee1eSDan Willemsen } 651*1c12ee1eSDan Willemsen}`, 652*1c12ee1eSDan Willemsen }, { 653*1c12ee1eSDan Willemsen desc: "map fields 3", 654*1c12ee1eSDan Willemsen input: &pb3.Maps{ 655*1c12ee1eSDan Willemsen Uint64ToEnum: map[uint64]pb3.Enum{ 656*1c12ee1eSDan Willemsen 1: pb3.Enum_ONE, 657*1c12ee1eSDan Willemsen 2: pb3.Enum_TWO, 658*1c12ee1eSDan Willemsen 10: pb3.Enum_TEN, 659*1c12ee1eSDan Willemsen 47: 47, 660*1c12ee1eSDan Willemsen }, 661*1c12ee1eSDan Willemsen }, 662*1c12ee1eSDan Willemsen want: `{ 663*1c12ee1eSDan Willemsen "uint64ToEnum": { 664*1c12ee1eSDan Willemsen "1": "ONE", 665*1c12ee1eSDan Willemsen "2": "TWO", 666*1c12ee1eSDan Willemsen "10": "TEN", 667*1c12ee1eSDan Willemsen "47": 47 668*1c12ee1eSDan Willemsen } 669*1c12ee1eSDan Willemsen}`, 670*1c12ee1eSDan Willemsen }, { 671*1c12ee1eSDan Willemsen desc: "map fields 4", 672*1c12ee1eSDan Willemsen input: &pb3.Maps{ 673*1c12ee1eSDan Willemsen StrToNested: map[string]*pb3.Nested{ 674*1c12ee1eSDan Willemsen "nested": &pb3.Nested{ 675*1c12ee1eSDan Willemsen SString: "nested in a map", 676*1c12ee1eSDan Willemsen }, 677*1c12ee1eSDan Willemsen }, 678*1c12ee1eSDan Willemsen }, 679*1c12ee1eSDan Willemsen want: `{ 680*1c12ee1eSDan Willemsen "strToNested": { 681*1c12ee1eSDan Willemsen "nested": { 682*1c12ee1eSDan Willemsen "sString": "nested in a map" 683*1c12ee1eSDan Willemsen } 684*1c12ee1eSDan Willemsen } 685*1c12ee1eSDan Willemsen}`, 686*1c12ee1eSDan Willemsen }, { 687*1c12ee1eSDan Willemsen desc: "map fields 5", 688*1c12ee1eSDan Willemsen input: &pb3.Maps{ 689*1c12ee1eSDan Willemsen StrToOneofs: map[string]*pb3.Oneofs{ 690*1c12ee1eSDan Willemsen "string": &pb3.Oneofs{ 691*1c12ee1eSDan Willemsen Union: &pb3.Oneofs_OneofString{ 692*1c12ee1eSDan Willemsen OneofString: "hello", 693*1c12ee1eSDan Willemsen }, 694*1c12ee1eSDan Willemsen }, 695*1c12ee1eSDan Willemsen "nested": &pb3.Oneofs{ 696*1c12ee1eSDan Willemsen Union: &pb3.Oneofs_OneofNested{ 697*1c12ee1eSDan Willemsen OneofNested: &pb3.Nested{ 698*1c12ee1eSDan Willemsen SString: "nested oneof in map field value", 699*1c12ee1eSDan Willemsen }, 700*1c12ee1eSDan Willemsen }, 701*1c12ee1eSDan Willemsen }, 702*1c12ee1eSDan Willemsen }, 703*1c12ee1eSDan Willemsen }, 704*1c12ee1eSDan Willemsen want: `{ 705*1c12ee1eSDan Willemsen "strToOneofs": { 706*1c12ee1eSDan Willemsen "nested": { 707*1c12ee1eSDan Willemsen "oneofNested": { 708*1c12ee1eSDan Willemsen "sString": "nested oneof in map field value" 709*1c12ee1eSDan Willemsen } 710*1c12ee1eSDan Willemsen }, 711*1c12ee1eSDan Willemsen "string": { 712*1c12ee1eSDan Willemsen "oneofString": "hello" 713*1c12ee1eSDan Willemsen } 714*1c12ee1eSDan Willemsen } 715*1c12ee1eSDan Willemsen}`, 716*1c12ee1eSDan Willemsen }, { 717*1c12ee1eSDan Willemsen desc: "map field contains nil value", 718*1c12ee1eSDan Willemsen input: &pb3.Maps{ 719*1c12ee1eSDan Willemsen StrToNested: map[string]*pb3.Nested{ 720*1c12ee1eSDan Willemsen "nil": nil, 721*1c12ee1eSDan Willemsen }, 722*1c12ee1eSDan Willemsen }, 723*1c12ee1eSDan Willemsen want: `{ 724*1c12ee1eSDan Willemsen "strToNested": { 725*1c12ee1eSDan Willemsen "nil": {} 726*1c12ee1eSDan Willemsen } 727*1c12ee1eSDan Willemsen}`, 728*1c12ee1eSDan Willemsen }, { 729*1c12ee1eSDan Willemsen desc: "required fields not set", 730*1c12ee1eSDan Willemsen input: &pb2.Requireds{}, 731*1c12ee1eSDan Willemsen want: `{}`, 732*1c12ee1eSDan Willemsen wantErr: true, 733*1c12ee1eSDan Willemsen }, { 734*1c12ee1eSDan Willemsen desc: "required fields partially set", 735*1c12ee1eSDan Willemsen input: &pb2.Requireds{ 736*1c12ee1eSDan Willemsen ReqBool: proto.Bool(false), 737*1c12ee1eSDan Willemsen ReqSfixed64: proto.Int64(0), 738*1c12ee1eSDan Willemsen ReqDouble: proto.Float64(1.23), 739*1c12ee1eSDan Willemsen ReqString: proto.String("hello"), 740*1c12ee1eSDan Willemsen ReqEnum: pb2.Enum_ONE.Enum(), 741*1c12ee1eSDan Willemsen }, 742*1c12ee1eSDan Willemsen want: `{ 743*1c12ee1eSDan Willemsen "reqBool": false, 744*1c12ee1eSDan Willemsen "reqSfixed64": "0", 745*1c12ee1eSDan Willemsen "reqDouble": 1.23, 746*1c12ee1eSDan Willemsen "reqString": "hello", 747*1c12ee1eSDan Willemsen "reqEnum": "ONE" 748*1c12ee1eSDan Willemsen}`, 749*1c12ee1eSDan Willemsen wantErr: true, 750*1c12ee1eSDan Willemsen }, { 751*1c12ee1eSDan Willemsen desc: "required fields not set with AllowPartial", 752*1c12ee1eSDan Willemsen mo: protojson.MarshalOptions{AllowPartial: true}, 753*1c12ee1eSDan Willemsen input: &pb2.Requireds{ 754*1c12ee1eSDan Willemsen ReqBool: proto.Bool(false), 755*1c12ee1eSDan Willemsen ReqSfixed64: proto.Int64(0), 756*1c12ee1eSDan Willemsen ReqDouble: proto.Float64(1.23), 757*1c12ee1eSDan Willemsen ReqString: proto.String("hello"), 758*1c12ee1eSDan Willemsen ReqEnum: pb2.Enum_ONE.Enum(), 759*1c12ee1eSDan Willemsen }, 760*1c12ee1eSDan Willemsen want: `{ 761*1c12ee1eSDan Willemsen "reqBool": false, 762*1c12ee1eSDan Willemsen "reqSfixed64": "0", 763*1c12ee1eSDan Willemsen "reqDouble": 1.23, 764*1c12ee1eSDan Willemsen "reqString": "hello", 765*1c12ee1eSDan Willemsen "reqEnum": "ONE" 766*1c12ee1eSDan Willemsen}`, 767*1c12ee1eSDan Willemsen }, { 768*1c12ee1eSDan Willemsen desc: "required fields all set", 769*1c12ee1eSDan Willemsen input: &pb2.Requireds{ 770*1c12ee1eSDan Willemsen ReqBool: proto.Bool(false), 771*1c12ee1eSDan Willemsen ReqSfixed64: proto.Int64(0), 772*1c12ee1eSDan Willemsen ReqDouble: proto.Float64(1.23), 773*1c12ee1eSDan Willemsen ReqString: proto.String("hello"), 774*1c12ee1eSDan Willemsen ReqEnum: pb2.Enum_ONE.Enum(), 775*1c12ee1eSDan Willemsen ReqNested: &pb2.Nested{}, 776*1c12ee1eSDan Willemsen }, 777*1c12ee1eSDan Willemsen want: `{ 778*1c12ee1eSDan Willemsen "reqBool": false, 779*1c12ee1eSDan Willemsen "reqSfixed64": "0", 780*1c12ee1eSDan Willemsen "reqDouble": 1.23, 781*1c12ee1eSDan Willemsen "reqString": "hello", 782*1c12ee1eSDan Willemsen "reqEnum": "ONE", 783*1c12ee1eSDan Willemsen "reqNested": {} 784*1c12ee1eSDan Willemsen}`, 785*1c12ee1eSDan Willemsen }, { 786*1c12ee1eSDan Willemsen desc: "indirect required field", 787*1c12ee1eSDan Willemsen input: &pb2.IndirectRequired{ 788*1c12ee1eSDan Willemsen OptNested: &pb2.NestedWithRequired{}, 789*1c12ee1eSDan Willemsen }, 790*1c12ee1eSDan Willemsen want: `{ 791*1c12ee1eSDan Willemsen "optNested": {} 792*1c12ee1eSDan Willemsen}`, 793*1c12ee1eSDan Willemsen wantErr: true, 794*1c12ee1eSDan Willemsen }, { 795*1c12ee1eSDan Willemsen desc: "indirect required field with AllowPartial", 796*1c12ee1eSDan Willemsen mo: protojson.MarshalOptions{AllowPartial: true}, 797*1c12ee1eSDan Willemsen input: &pb2.IndirectRequired{ 798*1c12ee1eSDan Willemsen OptNested: &pb2.NestedWithRequired{}, 799*1c12ee1eSDan Willemsen }, 800*1c12ee1eSDan Willemsen want: `{ 801*1c12ee1eSDan Willemsen "optNested": {} 802*1c12ee1eSDan Willemsen}`, 803*1c12ee1eSDan Willemsen }, { 804*1c12ee1eSDan Willemsen desc: "indirect required field in empty repeated", 805*1c12ee1eSDan Willemsen input: &pb2.IndirectRequired{ 806*1c12ee1eSDan Willemsen RptNested: []*pb2.NestedWithRequired{}, 807*1c12ee1eSDan Willemsen }, 808*1c12ee1eSDan Willemsen want: `{}`, 809*1c12ee1eSDan Willemsen }, { 810*1c12ee1eSDan Willemsen desc: "indirect required field in repeated", 811*1c12ee1eSDan Willemsen input: &pb2.IndirectRequired{ 812*1c12ee1eSDan Willemsen RptNested: []*pb2.NestedWithRequired{ 813*1c12ee1eSDan Willemsen &pb2.NestedWithRequired{}, 814*1c12ee1eSDan Willemsen }, 815*1c12ee1eSDan Willemsen }, 816*1c12ee1eSDan Willemsen want: `{ 817*1c12ee1eSDan Willemsen "rptNested": [ 818*1c12ee1eSDan Willemsen {} 819*1c12ee1eSDan Willemsen ] 820*1c12ee1eSDan Willemsen}`, 821*1c12ee1eSDan Willemsen wantErr: true, 822*1c12ee1eSDan Willemsen }, { 823*1c12ee1eSDan Willemsen desc: "indirect required field in repeated with AllowPartial", 824*1c12ee1eSDan Willemsen mo: protojson.MarshalOptions{AllowPartial: true}, 825*1c12ee1eSDan Willemsen input: &pb2.IndirectRequired{ 826*1c12ee1eSDan Willemsen RptNested: []*pb2.NestedWithRequired{ 827*1c12ee1eSDan Willemsen &pb2.NestedWithRequired{}, 828*1c12ee1eSDan Willemsen }, 829*1c12ee1eSDan Willemsen }, 830*1c12ee1eSDan Willemsen want: `{ 831*1c12ee1eSDan Willemsen "rptNested": [ 832*1c12ee1eSDan Willemsen {} 833*1c12ee1eSDan Willemsen ] 834*1c12ee1eSDan Willemsen}`, 835*1c12ee1eSDan Willemsen }, { 836*1c12ee1eSDan Willemsen desc: "indirect required field in empty map", 837*1c12ee1eSDan Willemsen input: &pb2.IndirectRequired{ 838*1c12ee1eSDan Willemsen StrToNested: map[string]*pb2.NestedWithRequired{}, 839*1c12ee1eSDan Willemsen }, 840*1c12ee1eSDan Willemsen want: "{}", 841*1c12ee1eSDan Willemsen }, { 842*1c12ee1eSDan Willemsen desc: "indirect required field in map", 843*1c12ee1eSDan Willemsen input: &pb2.IndirectRequired{ 844*1c12ee1eSDan Willemsen StrToNested: map[string]*pb2.NestedWithRequired{ 845*1c12ee1eSDan Willemsen "fail": &pb2.NestedWithRequired{}, 846*1c12ee1eSDan Willemsen }, 847*1c12ee1eSDan Willemsen }, 848*1c12ee1eSDan Willemsen want: `{ 849*1c12ee1eSDan Willemsen "strToNested": { 850*1c12ee1eSDan Willemsen "fail": {} 851*1c12ee1eSDan Willemsen } 852*1c12ee1eSDan Willemsen}`, 853*1c12ee1eSDan Willemsen wantErr: true, 854*1c12ee1eSDan Willemsen }, { 855*1c12ee1eSDan Willemsen desc: "indirect required field in map with AllowPartial", 856*1c12ee1eSDan Willemsen mo: protojson.MarshalOptions{AllowPartial: true}, 857*1c12ee1eSDan Willemsen input: &pb2.IndirectRequired{ 858*1c12ee1eSDan Willemsen StrToNested: map[string]*pb2.NestedWithRequired{ 859*1c12ee1eSDan Willemsen "fail": &pb2.NestedWithRequired{}, 860*1c12ee1eSDan Willemsen }, 861*1c12ee1eSDan Willemsen }, 862*1c12ee1eSDan Willemsen want: `{ 863*1c12ee1eSDan Willemsen "strToNested": { 864*1c12ee1eSDan Willemsen "fail": {} 865*1c12ee1eSDan Willemsen } 866*1c12ee1eSDan Willemsen}`, 867*1c12ee1eSDan Willemsen }, { 868*1c12ee1eSDan Willemsen desc: "indirect required field in oneof", 869*1c12ee1eSDan Willemsen input: &pb2.IndirectRequired{ 870*1c12ee1eSDan Willemsen Union: &pb2.IndirectRequired_OneofNested{ 871*1c12ee1eSDan Willemsen OneofNested: &pb2.NestedWithRequired{}, 872*1c12ee1eSDan Willemsen }, 873*1c12ee1eSDan Willemsen }, 874*1c12ee1eSDan Willemsen want: `{ 875*1c12ee1eSDan Willemsen "oneofNested": {} 876*1c12ee1eSDan Willemsen}`, 877*1c12ee1eSDan Willemsen wantErr: true, 878*1c12ee1eSDan Willemsen }, { 879*1c12ee1eSDan Willemsen desc: "indirect required field in oneof with AllowPartial", 880*1c12ee1eSDan Willemsen mo: protojson.MarshalOptions{AllowPartial: true}, 881*1c12ee1eSDan Willemsen input: &pb2.IndirectRequired{ 882*1c12ee1eSDan Willemsen Union: &pb2.IndirectRequired_OneofNested{ 883*1c12ee1eSDan Willemsen OneofNested: &pb2.NestedWithRequired{}, 884*1c12ee1eSDan Willemsen }, 885*1c12ee1eSDan Willemsen }, 886*1c12ee1eSDan Willemsen want: `{ 887*1c12ee1eSDan Willemsen "oneofNested": {} 888*1c12ee1eSDan Willemsen}`, 889*1c12ee1eSDan Willemsen }, { 890*1c12ee1eSDan Willemsen desc: "unknown fields are ignored", 891*1c12ee1eSDan Willemsen input: func() proto.Message { 892*1c12ee1eSDan Willemsen m := &pb2.Scalars{ 893*1c12ee1eSDan Willemsen OptString: proto.String("no unknowns"), 894*1c12ee1eSDan Willemsen } 895*1c12ee1eSDan Willemsen m.ProtoReflect().SetUnknown(protopack.Message{ 896*1c12ee1eSDan Willemsen protopack.Tag{101, protopack.BytesType}, protopack.String("hello world"), 897*1c12ee1eSDan Willemsen }.Marshal()) 898*1c12ee1eSDan Willemsen return m 899*1c12ee1eSDan Willemsen }(), 900*1c12ee1eSDan Willemsen want: `{ 901*1c12ee1eSDan Willemsen "optString": "no unknowns" 902*1c12ee1eSDan Willemsen}`, 903*1c12ee1eSDan Willemsen }, { 904*1c12ee1eSDan Willemsen desc: "json_name", 905*1c12ee1eSDan Willemsen input: &pb3.JSONNames{ 906*1c12ee1eSDan Willemsen SString: "json_name", 907*1c12ee1eSDan Willemsen }, 908*1c12ee1eSDan Willemsen want: `{ 909*1c12ee1eSDan Willemsen "foo_bar": "json_name" 910*1c12ee1eSDan Willemsen}`, 911*1c12ee1eSDan Willemsen }, { 912*1c12ee1eSDan Willemsen desc: "extensions of non-repeated fields", 913*1c12ee1eSDan Willemsen input: func() proto.Message { 914*1c12ee1eSDan Willemsen m := &pb2.Extensions{ 915*1c12ee1eSDan Willemsen OptString: proto.String("non-extension field"), 916*1c12ee1eSDan Willemsen OptBool: proto.Bool(true), 917*1c12ee1eSDan Willemsen OptInt32: proto.Int32(42), 918*1c12ee1eSDan Willemsen } 919*1c12ee1eSDan Willemsen proto.SetExtension(m, pb2.E_OptExtBool, true) 920*1c12ee1eSDan Willemsen proto.SetExtension(m, pb2.E_OptExtString, "extension field") 921*1c12ee1eSDan Willemsen proto.SetExtension(m, pb2.E_OptExtEnum, pb2.Enum_TEN) 922*1c12ee1eSDan Willemsen proto.SetExtension(m, pb2.E_OptExtNested, &pb2.Nested{ 923*1c12ee1eSDan Willemsen OptString: proto.String("nested in an extension"), 924*1c12ee1eSDan Willemsen OptNested: &pb2.Nested{ 925*1c12ee1eSDan Willemsen OptString: proto.String("another nested in an extension"), 926*1c12ee1eSDan Willemsen }, 927*1c12ee1eSDan Willemsen }) 928*1c12ee1eSDan Willemsen return m 929*1c12ee1eSDan Willemsen }(), 930*1c12ee1eSDan Willemsen want: `{ 931*1c12ee1eSDan Willemsen "optString": "non-extension field", 932*1c12ee1eSDan Willemsen "optBool": true, 933*1c12ee1eSDan Willemsen "optInt32": 42, 934*1c12ee1eSDan Willemsen "[pb2.opt_ext_bool]": true, 935*1c12ee1eSDan Willemsen "[pb2.opt_ext_enum]": "TEN", 936*1c12ee1eSDan Willemsen "[pb2.opt_ext_nested]": { 937*1c12ee1eSDan Willemsen "optString": "nested in an extension", 938*1c12ee1eSDan Willemsen "optNested": { 939*1c12ee1eSDan Willemsen "optString": "another nested in an extension" 940*1c12ee1eSDan Willemsen } 941*1c12ee1eSDan Willemsen }, 942*1c12ee1eSDan Willemsen "[pb2.opt_ext_string]": "extension field" 943*1c12ee1eSDan Willemsen}`, 944*1c12ee1eSDan Willemsen }, { 945*1c12ee1eSDan Willemsen desc: "extensions of repeated fields", 946*1c12ee1eSDan Willemsen input: func() proto.Message { 947*1c12ee1eSDan Willemsen m := &pb2.Extensions{} 948*1c12ee1eSDan Willemsen proto.SetExtension(m, pb2.E_RptExtEnum, []pb2.Enum{pb2.Enum_TEN, 101, pb2.Enum_ONE}) 949*1c12ee1eSDan Willemsen proto.SetExtension(m, pb2.E_RptExtFixed32, []uint32{42, 47}) 950*1c12ee1eSDan Willemsen proto.SetExtension(m, pb2.E_RptExtNested, []*pb2.Nested{ 951*1c12ee1eSDan Willemsen &pb2.Nested{OptString: proto.String("one")}, 952*1c12ee1eSDan Willemsen &pb2.Nested{OptString: proto.String("two")}, 953*1c12ee1eSDan Willemsen &pb2.Nested{OptString: proto.String("three")}, 954*1c12ee1eSDan Willemsen }) 955*1c12ee1eSDan Willemsen return m 956*1c12ee1eSDan Willemsen }(), 957*1c12ee1eSDan Willemsen want: `{ 958*1c12ee1eSDan Willemsen "[pb2.rpt_ext_enum]": [ 959*1c12ee1eSDan Willemsen "TEN", 960*1c12ee1eSDan Willemsen 101, 961*1c12ee1eSDan Willemsen "ONE" 962*1c12ee1eSDan Willemsen ], 963*1c12ee1eSDan Willemsen "[pb2.rpt_ext_fixed32]": [ 964*1c12ee1eSDan Willemsen 42, 965*1c12ee1eSDan Willemsen 47 966*1c12ee1eSDan Willemsen ], 967*1c12ee1eSDan Willemsen "[pb2.rpt_ext_nested]": [ 968*1c12ee1eSDan Willemsen { 969*1c12ee1eSDan Willemsen "optString": "one" 970*1c12ee1eSDan Willemsen }, 971*1c12ee1eSDan Willemsen { 972*1c12ee1eSDan Willemsen "optString": "two" 973*1c12ee1eSDan Willemsen }, 974*1c12ee1eSDan Willemsen { 975*1c12ee1eSDan Willemsen "optString": "three" 976*1c12ee1eSDan Willemsen } 977*1c12ee1eSDan Willemsen ] 978*1c12ee1eSDan Willemsen}`, 979*1c12ee1eSDan Willemsen }, { 980*1c12ee1eSDan Willemsen desc: "extensions of non-repeated fields in another message", 981*1c12ee1eSDan Willemsen input: func() proto.Message { 982*1c12ee1eSDan Willemsen m := &pb2.Extensions{} 983*1c12ee1eSDan Willemsen proto.SetExtension(m, pb2.E_ExtensionsContainer_OptExtBool, true) 984*1c12ee1eSDan Willemsen proto.SetExtension(m, pb2.E_ExtensionsContainer_OptExtString, "extension field") 985*1c12ee1eSDan Willemsen proto.SetExtension(m, pb2.E_ExtensionsContainer_OptExtEnum, pb2.Enum_TEN) 986*1c12ee1eSDan Willemsen proto.SetExtension(m, pb2.E_ExtensionsContainer_OptExtNested, &pb2.Nested{ 987*1c12ee1eSDan Willemsen OptString: proto.String("nested in an extension"), 988*1c12ee1eSDan Willemsen OptNested: &pb2.Nested{ 989*1c12ee1eSDan Willemsen OptString: proto.String("another nested in an extension"), 990*1c12ee1eSDan Willemsen }, 991*1c12ee1eSDan Willemsen }) 992*1c12ee1eSDan Willemsen return m 993*1c12ee1eSDan Willemsen }(), 994*1c12ee1eSDan Willemsen want: `{ 995*1c12ee1eSDan Willemsen "[pb2.ExtensionsContainer.opt_ext_bool]": true, 996*1c12ee1eSDan Willemsen "[pb2.ExtensionsContainer.opt_ext_enum]": "TEN", 997*1c12ee1eSDan Willemsen "[pb2.ExtensionsContainer.opt_ext_nested]": { 998*1c12ee1eSDan Willemsen "optString": "nested in an extension", 999*1c12ee1eSDan Willemsen "optNested": { 1000*1c12ee1eSDan Willemsen "optString": "another nested in an extension" 1001*1c12ee1eSDan Willemsen } 1002*1c12ee1eSDan Willemsen }, 1003*1c12ee1eSDan Willemsen "[pb2.ExtensionsContainer.opt_ext_string]": "extension field" 1004*1c12ee1eSDan Willemsen}`, 1005*1c12ee1eSDan Willemsen }, { 1006*1c12ee1eSDan Willemsen desc: "extensions of repeated fields in another message", 1007*1c12ee1eSDan Willemsen input: func() proto.Message { 1008*1c12ee1eSDan Willemsen m := &pb2.Extensions{ 1009*1c12ee1eSDan Willemsen OptString: proto.String("non-extension field"), 1010*1c12ee1eSDan Willemsen OptBool: proto.Bool(true), 1011*1c12ee1eSDan Willemsen OptInt32: proto.Int32(42), 1012*1c12ee1eSDan Willemsen } 1013*1c12ee1eSDan Willemsen proto.SetExtension(m, pb2.E_ExtensionsContainer_RptExtEnum, []pb2.Enum{pb2.Enum_TEN, 101, pb2.Enum_ONE}) 1014*1c12ee1eSDan Willemsen proto.SetExtension(m, pb2.E_ExtensionsContainer_RptExtString, []string{"hello", "world"}) 1015*1c12ee1eSDan Willemsen proto.SetExtension(m, pb2.E_ExtensionsContainer_RptExtNested, []*pb2.Nested{ 1016*1c12ee1eSDan Willemsen &pb2.Nested{OptString: proto.String("one")}, 1017*1c12ee1eSDan Willemsen &pb2.Nested{OptString: proto.String("two")}, 1018*1c12ee1eSDan Willemsen &pb2.Nested{OptString: proto.String("three")}, 1019*1c12ee1eSDan Willemsen }) 1020*1c12ee1eSDan Willemsen return m 1021*1c12ee1eSDan Willemsen }(), 1022*1c12ee1eSDan Willemsen want: `{ 1023*1c12ee1eSDan Willemsen "optString": "non-extension field", 1024*1c12ee1eSDan Willemsen "optBool": true, 1025*1c12ee1eSDan Willemsen "optInt32": 42, 1026*1c12ee1eSDan Willemsen "[pb2.ExtensionsContainer.rpt_ext_enum]": [ 1027*1c12ee1eSDan Willemsen "TEN", 1028*1c12ee1eSDan Willemsen 101, 1029*1c12ee1eSDan Willemsen "ONE" 1030*1c12ee1eSDan Willemsen ], 1031*1c12ee1eSDan Willemsen "[pb2.ExtensionsContainer.rpt_ext_nested]": [ 1032*1c12ee1eSDan Willemsen { 1033*1c12ee1eSDan Willemsen "optString": "one" 1034*1c12ee1eSDan Willemsen }, 1035*1c12ee1eSDan Willemsen { 1036*1c12ee1eSDan Willemsen "optString": "two" 1037*1c12ee1eSDan Willemsen }, 1038*1c12ee1eSDan Willemsen { 1039*1c12ee1eSDan Willemsen "optString": "three" 1040*1c12ee1eSDan Willemsen } 1041*1c12ee1eSDan Willemsen ], 1042*1c12ee1eSDan Willemsen "[pb2.ExtensionsContainer.rpt_ext_string]": [ 1043*1c12ee1eSDan Willemsen "hello", 1044*1c12ee1eSDan Willemsen "world" 1045*1c12ee1eSDan Willemsen ] 1046*1c12ee1eSDan Willemsen}`, 1047*1c12ee1eSDan Willemsen }, { 1048*1c12ee1eSDan Willemsen desc: "MessageSet", 1049*1c12ee1eSDan Willemsen input: func() proto.Message { 1050*1c12ee1eSDan Willemsen m := &pb2.MessageSet{} 1051*1c12ee1eSDan Willemsen proto.SetExtension(m, pb2.E_MessageSetExtension_MessageSetExtension, &pb2.MessageSetExtension{ 1052*1c12ee1eSDan Willemsen OptString: proto.String("a messageset extension"), 1053*1c12ee1eSDan Willemsen }) 1054*1c12ee1eSDan Willemsen proto.SetExtension(m, pb2.E_MessageSetExtension_NotMessageSetExtension, &pb2.MessageSetExtension{ 1055*1c12ee1eSDan Willemsen OptString: proto.String("not a messageset extension"), 1056*1c12ee1eSDan Willemsen }) 1057*1c12ee1eSDan Willemsen proto.SetExtension(m, pb2.E_MessageSetExtension_ExtNested, &pb2.Nested{ 1058*1c12ee1eSDan Willemsen OptString: proto.String("just a regular extension"), 1059*1c12ee1eSDan Willemsen }) 1060*1c12ee1eSDan Willemsen return m 1061*1c12ee1eSDan Willemsen }(), 1062*1c12ee1eSDan Willemsen want: `{ 1063*1c12ee1eSDan Willemsen "[pb2.MessageSetExtension.ext_nested]": { 1064*1c12ee1eSDan Willemsen "optString": "just a regular extension" 1065*1c12ee1eSDan Willemsen }, 1066*1c12ee1eSDan Willemsen "[pb2.MessageSetExtension]": { 1067*1c12ee1eSDan Willemsen "optString": "a messageset extension" 1068*1c12ee1eSDan Willemsen }, 1069*1c12ee1eSDan Willemsen "[pb2.MessageSetExtension.not_message_set_extension]": { 1070*1c12ee1eSDan Willemsen "optString": "not a messageset extension" 1071*1c12ee1eSDan Willemsen } 1072*1c12ee1eSDan Willemsen}`, 1073*1c12ee1eSDan Willemsen skip: !flags.ProtoLegacy, 1074*1c12ee1eSDan Willemsen }, { 1075*1c12ee1eSDan Willemsen desc: "not real MessageSet 1", 1076*1c12ee1eSDan Willemsen input: func() proto.Message { 1077*1c12ee1eSDan Willemsen m := &pb2.FakeMessageSet{} 1078*1c12ee1eSDan Willemsen proto.SetExtension(m, pb2.E_FakeMessageSetExtension_MessageSetExtension, &pb2.FakeMessageSetExtension{ 1079*1c12ee1eSDan Willemsen OptString: proto.String("not a messageset extension"), 1080*1c12ee1eSDan Willemsen }) 1081*1c12ee1eSDan Willemsen return m 1082*1c12ee1eSDan Willemsen }(), 1083*1c12ee1eSDan Willemsen want: `{ 1084*1c12ee1eSDan Willemsen "[pb2.FakeMessageSetExtension.message_set_extension]": { 1085*1c12ee1eSDan Willemsen "optString": "not a messageset extension" 1086*1c12ee1eSDan Willemsen } 1087*1c12ee1eSDan Willemsen}`, 1088*1c12ee1eSDan Willemsen skip: !flags.ProtoLegacy, 1089*1c12ee1eSDan Willemsen }, { 1090*1c12ee1eSDan Willemsen desc: "not real MessageSet 2", 1091*1c12ee1eSDan Willemsen input: func() proto.Message { 1092*1c12ee1eSDan Willemsen m := &pb2.MessageSet{} 1093*1c12ee1eSDan Willemsen proto.SetExtension(m, pb2.E_MessageSetExtension, &pb2.FakeMessageSetExtension{ 1094*1c12ee1eSDan Willemsen OptString: proto.String("another not a messageset extension"), 1095*1c12ee1eSDan Willemsen }) 1096*1c12ee1eSDan Willemsen return m 1097*1c12ee1eSDan Willemsen }(), 1098*1c12ee1eSDan Willemsen want: `{ 1099*1c12ee1eSDan Willemsen "[pb2.message_set_extension]": { 1100*1c12ee1eSDan Willemsen "optString": "another not a messageset extension" 1101*1c12ee1eSDan Willemsen } 1102*1c12ee1eSDan Willemsen}`, 1103*1c12ee1eSDan Willemsen skip: !flags.ProtoLegacy, 1104*1c12ee1eSDan Willemsen }, { 1105*1c12ee1eSDan Willemsen desc: "BoolValue empty", 1106*1c12ee1eSDan Willemsen input: &wrapperspb.BoolValue{}, 1107*1c12ee1eSDan Willemsen want: `false`, 1108*1c12ee1eSDan Willemsen }, { 1109*1c12ee1eSDan Willemsen desc: "BoolValue", 1110*1c12ee1eSDan Willemsen input: &wrapperspb.BoolValue{Value: true}, 1111*1c12ee1eSDan Willemsen want: `true`, 1112*1c12ee1eSDan Willemsen }, { 1113*1c12ee1eSDan Willemsen desc: "Int32Value empty", 1114*1c12ee1eSDan Willemsen input: &wrapperspb.Int32Value{}, 1115*1c12ee1eSDan Willemsen want: `0`, 1116*1c12ee1eSDan Willemsen }, { 1117*1c12ee1eSDan Willemsen desc: "Int32Value", 1118*1c12ee1eSDan Willemsen input: &wrapperspb.Int32Value{Value: 42}, 1119*1c12ee1eSDan Willemsen want: `42`, 1120*1c12ee1eSDan Willemsen }, { 1121*1c12ee1eSDan Willemsen desc: "Int64Value", 1122*1c12ee1eSDan Willemsen input: &wrapperspb.Int64Value{Value: 42}, 1123*1c12ee1eSDan Willemsen want: `"42"`, 1124*1c12ee1eSDan Willemsen }, { 1125*1c12ee1eSDan Willemsen desc: "UInt32Value", 1126*1c12ee1eSDan Willemsen input: &wrapperspb.UInt32Value{Value: 42}, 1127*1c12ee1eSDan Willemsen want: `42`, 1128*1c12ee1eSDan Willemsen }, { 1129*1c12ee1eSDan Willemsen desc: "UInt64Value", 1130*1c12ee1eSDan Willemsen input: &wrapperspb.UInt64Value{Value: 42}, 1131*1c12ee1eSDan Willemsen want: `"42"`, 1132*1c12ee1eSDan Willemsen }, { 1133*1c12ee1eSDan Willemsen desc: "FloatValue", 1134*1c12ee1eSDan Willemsen input: &wrapperspb.FloatValue{Value: 1.02}, 1135*1c12ee1eSDan Willemsen want: `1.02`, 1136*1c12ee1eSDan Willemsen }, { 1137*1c12ee1eSDan Willemsen desc: "FloatValue Infinity", 1138*1c12ee1eSDan Willemsen input: &wrapperspb.FloatValue{Value: float32(math.Inf(-1))}, 1139*1c12ee1eSDan Willemsen want: `"-Infinity"`, 1140*1c12ee1eSDan Willemsen }, { 1141*1c12ee1eSDan Willemsen desc: "DoubleValue", 1142*1c12ee1eSDan Willemsen input: &wrapperspb.DoubleValue{Value: 1.02}, 1143*1c12ee1eSDan Willemsen want: `1.02`, 1144*1c12ee1eSDan Willemsen }, { 1145*1c12ee1eSDan Willemsen desc: "DoubleValue NaN", 1146*1c12ee1eSDan Willemsen input: &wrapperspb.DoubleValue{Value: math.NaN()}, 1147*1c12ee1eSDan Willemsen want: `"NaN"`, 1148*1c12ee1eSDan Willemsen }, { 1149*1c12ee1eSDan Willemsen desc: "StringValue empty", 1150*1c12ee1eSDan Willemsen input: &wrapperspb.StringValue{}, 1151*1c12ee1eSDan Willemsen want: `""`, 1152*1c12ee1eSDan Willemsen }, { 1153*1c12ee1eSDan Willemsen desc: "StringValue", 1154*1c12ee1eSDan Willemsen input: &wrapperspb.StringValue{Value: "谷歌"}, 1155*1c12ee1eSDan Willemsen want: `"谷歌"`, 1156*1c12ee1eSDan Willemsen }, { 1157*1c12ee1eSDan Willemsen desc: "StringValue with invalid UTF8 error", 1158*1c12ee1eSDan Willemsen input: &wrapperspb.StringValue{Value: "abc\xff"}, 1159*1c12ee1eSDan Willemsen wantErr: true, 1160*1c12ee1eSDan Willemsen }, { 1161*1c12ee1eSDan Willemsen desc: "StringValue field with invalid UTF8 error", 1162*1c12ee1eSDan Willemsen input: &pb2.KnownTypes{ 1163*1c12ee1eSDan Willemsen OptString: &wrapperspb.StringValue{Value: "abc\xff"}, 1164*1c12ee1eSDan Willemsen }, 1165*1c12ee1eSDan Willemsen wantErr: true, 1166*1c12ee1eSDan Willemsen }, { 1167*1c12ee1eSDan Willemsen desc: "BytesValue", 1168*1c12ee1eSDan Willemsen input: &wrapperspb.BytesValue{Value: []byte("hello")}, 1169*1c12ee1eSDan Willemsen want: `"aGVsbG8="`, 1170*1c12ee1eSDan Willemsen }, { 1171*1c12ee1eSDan Willemsen desc: "Empty", 1172*1c12ee1eSDan Willemsen input: &emptypb.Empty{}, 1173*1c12ee1eSDan Willemsen want: `{}`, 1174*1c12ee1eSDan Willemsen }, { 1175*1c12ee1eSDan Willemsen desc: "NullValue field", 1176*1c12ee1eSDan Willemsen input: &pb2.KnownTypes{OptNull: new(structpb.NullValue)}, 1177*1c12ee1eSDan Willemsen want: `{ 1178*1c12ee1eSDan Willemsen "optNull": null 1179*1c12ee1eSDan Willemsen}`, 1180*1c12ee1eSDan Willemsen }, { 1181*1c12ee1eSDan Willemsen desc: "Value empty", 1182*1c12ee1eSDan Willemsen input: &structpb.Value{}, 1183*1c12ee1eSDan Willemsen wantErr: true, 1184*1c12ee1eSDan Willemsen }, { 1185*1c12ee1eSDan Willemsen desc: "Value empty field", 1186*1c12ee1eSDan Willemsen input: &pb2.KnownTypes{ 1187*1c12ee1eSDan Willemsen OptValue: &structpb.Value{}, 1188*1c12ee1eSDan Willemsen }, 1189*1c12ee1eSDan Willemsen wantErr: true, 1190*1c12ee1eSDan Willemsen }, { 1191*1c12ee1eSDan Willemsen desc: "Value contains NullValue", 1192*1c12ee1eSDan Willemsen input: &structpb.Value{Kind: &structpb.Value_NullValue{}}, 1193*1c12ee1eSDan Willemsen want: `null`, 1194*1c12ee1eSDan Willemsen }, { 1195*1c12ee1eSDan Willemsen desc: "Value contains BoolValue", 1196*1c12ee1eSDan Willemsen input: &structpb.Value{Kind: &structpb.Value_BoolValue{}}, 1197*1c12ee1eSDan Willemsen want: `false`, 1198*1c12ee1eSDan Willemsen }, { 1199*1c12ee1eSDan Willemsen desc: "Value contains NumberValue", 1200*1c12ee1eSDan Willemsen input: &structpb.Value{Kind: &structpb.Value_NumberValue{1.02}}, 1201*1c12ee1eSDan Willemsen want: `1.02`, 1202*1c12ee1eSDan Willemsen }, { 1203*1c12ee1eSDan Willemsen desc: "Value contains StringValue", 1204*1c12ee1eSDan Willemsen input: &structpb.Value{Kind: &structpb.Value_StringValue{"hello"}}, 1205*1c12ee1eSDan Willemsen want: `"hello"`, 1206*1c12ee1eSDan Willemsen }, { 1207*1c12ee1eSDan Willemsen desc: "Value contains StringValue with invalid UTF8", 1208*1c12ee1eSDan Willemsen input: &structpb.Value{Kind: &structpb.Value_StringValue{"\xff"}}, 1209*1c12ee1eSDan Willemsen wantErr: true, 1210*1c12ee1eSDan Willemsen }, { 1211*1c12ee1eSDan Willemsen desc: "Value contains Struct", 1212*1c12ee1eSDan Willemsen input: &structpb.Value{ 1213*1c12ee1eSDan Willemsen Kind: &structpb.Value_StructValue{ 1214*1c12ee1eSDan Willemsen &structpb.Struct{ 1215*1c12ee1eSDan Willemsen Fields: map[string]*structpb.Value{ 1216*1c12ee1eSDan Willemsen "null": {Kind: &structpb.Value_NullValue{}}, 1217*1c12ee1eSDan Willemsen "number": {Kind: &structpb.Value_NumberValue{}}, 1218*1c12ee1eSDan Willemsen "string": {Kind: &structpb.Value_StringValue{}}, 1219*1c12ee1eSDan Willemsen "struct": {Kind: &structpb.Value_StructValue{}}, 1220*1c12ee1eSDan Willemsen "list": {Kind: &structpb.Value_ListValue{}}, 1221*1c12ee1eSDan Willemsen "bool": {Kind: &structpb.Value_BoolValue{}}, 1222*1c12ee1eSDan Willemsen }, 1223*1c12ee1eSDan Willemsen }, 1224*1c12ee1eSDan Willemsen }, 1225*1c12ee1eSDan Willemsen }, 1226*1c12ee1eSDan Willemsen want: `{ 1227*1c12ee1eSDan Willemsen "bool": false, 1228*1c12ee1eSDan Willemsen "list": [], 1229*1c12ee1eSDan Willemsen "null": null, 1230*1c12ee1eSDan Willemsen "number": 0, 1231*1c12ee1eSDan Willemsen "string": "", 1232*1c12ee1eSDan Willemsen "struct": {} 1233*1c12ee1eSDan Willemsen}`, 1234*1c12ee1eSDan Willemsen }, { 1235*1c12ee1eSDan Willemsen desc: "Value contains ListValue", 1236*1c12ee1eSDan Willemsen input: &structpb.Value{ 1237*1c12ee1eSDan Willemsen Kind: &structpb.Value_ListValue{ 1238*1c12ee1eSDan Willemsen &structpb.ListValue{ 1239*1c12ee1eSDan Willemsen Values: []*structpb.Value{ 1240*1c12ee1eSDan Willemsen {Kind: &structpb.Value_BoolValue{}}, 1241*1c12ee1eSDan Willemsen {Kind: &structpb.Value_NullValue{}}, 1242*1c12ee1eSDan Willemsen {Kind: &structpb.Value_NumberValue{}}, 1243*1c12ee1eSDan Willemsen {Kind: &structpb.Value_StringValue{}}, 1244*1c12ee1eSDan Willemsen {Kind: &structpb.Value_StructValue{}}, 1245*1c12ee1eSDan Willemsen {Kind: &structpb.Value_ListValue{}}, 1246*1c12ee1eSDan Willemsen }, 1247*1c12ee1eSDan Willemsen }, 1248*1c12ee1eSDan Willemsen }, 1249*1c12ee1eSDan Willemsen }, 1250*1c12ee1eSDan Willemsen want: `[ 1251*1c12ee1eSDan Willemsen false, 1252*1c12ee1eSDan Willemsen null, 1253*1c12ee1eSDan Willemsen 0, 1254*1c12ee1eSDan Willemsen "", 1255*1c12ee1eSDan Willemsen {}, 1256*1c12ee1eSDan Willemsen [] 1257*1c12ee1eSDan Willemsen]`, 1258*1c12ee1eSDan Willemsen }, { 1259*1c12ee1eSDan Willemsen desc: "Value with NaN", 1260*1c12ee1eSDan Willemsen input: structpb.NewNumberValue(math.NaN()), 1261*1c12ee1eSDan Willemsen wantErr: true, 1262*1c12ee1eSDan Willemsen }, { 1263*1c12ee1eSDan Willemsen desc: "Value with -Inf", 1264*1c12ee1eSDan Willemsen input: structpb.NewNumberValue(math.Inf(-1)), 1265*1c12ee1eSDan Willemsen wantErr: true, 1266*1c12ee1eSDan Willemsen }, { 1267*1c12ee1eSDan Willemsen desc: "Value with +Inf", 1268*1c12ee1eSDan Willemsen input: structpb.NewNumberValue(math.Inf(+1)), 1269*1c12ee1eSDan Willemsen wantErr: true, 1270*1c12ee1eSDan Willemsen }, { 1271*1c12ee1eSDan Willemsen desc: "Struct with nil map", 1272*1c12ee1eSDan Willemsen input: &structpb.Struct{}, 1273*1c12ee1eSDan Willemsen want: `{}`, 1274*1c12ee1eSDan Willemsen }, { 1275*1c12ee1eSDan Willemsen desc: "Struct with empty map", 1276*1c12ee1eSDan Willemsen input: &structpb.Struct{ 1277*1c12ee1eSDan Willemsen Fields: map[string]*structpb.Value{}, 1278*1c12ee1eSDan Willemsen }, 1279*1c12ee1eSDan Willemsen want: `{}`, 1280*1c12ee1eSDan Willemsen }, { 1281*1c12ee1eSDan Willemsen desc: "Struct", 1282*1c12ee1eSDan Willemsen input: &structpb.Struct{ 1283*1c12ee1eSDan Willemsen Fields: map[string]*structpb.Value{ 1284*1c12ee1eSDan Willemsen "bool": {Kind: &structpb.Value_BoolValue{true}}, 1285*1c12ee1eSDan Willemsen "null": {Kind: &structpb.Value_NullValue{}}, 1286*1c12ee1eSDan Willemsen "number": {Kind: &structpb.Value_NumberValue{3.1415}}, 1287*1c12ee1eSDan Willemsen "string": {Kind: &structpb.Value_StringValue{"hello"}}, 1288*1c12ee1eSDan Willemsen "struct": { 1289*1c12ee1eSDan Willemsen Kind: &structpb.Value_StructValue{ 1290*1c12ee1eSDan Willemsen &structpb.Struct{ 1291*1c12ee1eSDan Willemsen Fields: map[string]*structpb.Value{ 1292*1c12ee1eSDan Willemsen "string": {Kind: &structpb.Value_StringValue{"world"}}, 1293*1c12ee1eSDan Willemsen }, 1294*1c12ee1eSDan Willemsen }, 1295*1c12ee1eSDan Willemsen }, 1296*1c12ee1eSDan Willemsen }, 1297*1c12ee1eSDan Willemsen "list": { 1298*1c12ee1eSDan Willemsen Kind: &structpb.Value_ListValue{ 1299*1c12ee1eSDan Willemsen &structpb.ListValue{ 1300*1c12ee1eSDan Willemsen Values: []*structpb.Value{ 1301*1c12ee1eSDan Willemsen {Kind: &structpb.Value_BoolValue{}}, 1302*1c12ee1eSDan Willemsen {Kind: &structpb.Value_NullValue{}}, 1303*1c12ee1eSDan Willemsen {Kind: &structpb.Value_NumberValue{}}, 1304*1c12ee1eSDan Willemsen }, 1305*1c12ee1eSDan Willemsen }, 1306*1c12ee1eSDan Willemsen }, 1307*1c12ee1eSDan Willemsen }, 1308*1c12ee1eSDan Willemsen }, 1309*1c12ee1eSDan Willemsen }, 1310*1c12ee1eSDan Willemsen want: `{ 1311*1c12ee1eSDan Willemsen "bool": true, 1312*1c12ee1eSDan Willemsen "list": [ 1313*1c12ee1eSDan Willemsen false, 1314*1c12ee1eSDan Willemsen null, 1315*1c12ee1eSDan Willemsen 0 1316*1c12ee1eSDan Willemsen ], 1317*1c12ee1eSDan Willemsen "null": null, 1318*1c12ee1eSDan Willemsen "number": 3.1415, 1319*1c12ee1eSDan Willemsen "string": "hello", 1320*1c12ee1eSDan Willemsen "struct": { 1321*1c12ee1eSDan Willemsen "string": "world" 1322*1c12ee1eSDan Willemsen } 1323*1c12ee1eSDan Willemsen}`, 1324*1c12ee1eSDan Willemsen }, { 1325*1c12ee1eSDan Willemsen desc: "Struct message with invalid UTF8 string", 1326*1c12ee1eSDan Willemsen input: &structpb.Struct{ 1327*1c12ee1eSDan Willemsen Fields: map[string]*structpb.Value{ 1328*1c12ee1eSDan Willemsen "string": {Kind: &structpb.Value_StringValue{"\xff"}}, 1329*1c12ee1eSDan Willemsen }, 1330*1c12ee1eSDan Willemsen }, 1331*1c12ee1eSDan Willemsen wantErr: true, 1332*1c12ee1eSDan Willemsen }, { 1333*1c12ee1eSDan Willemsen desc: "ListValue with nil values", 1334*1c12ee1eSDan Willemsen input: &structpb.ListValue{}, 1335*1c12ee1eSDan Willemsen want: `[]`, 1336*1c12ee1eSDan Willemsen }, { 1337*1c12ee1eSDan Willemsen desc: "ListValue with empty values", 1338*1c12ee1eSDan Willemsen input: &structpb.ListValue{ 1339*1c12ee1eSDan Willemsen Values: []*structpb.Value{}, 1340*1c12ee1eSDan Willemsen }, 1341*1c12ee1eSDan Willemsen want: `[]`, 1342*1c12ee1eSDan Willemsen }, { 1343*1c12ee1eSDan Willemsen desc: "ListValue", 1344*1c12ee1eSDan Willemsen input: &structpb.ListValue{ 1345*1c12ee1eSDan Willemsen Values: []*structpb.Value{ 1346*1c12ee1eSDan Willemsen {Kind: &structpb.Value_BoolValue{true}}, 1347*1c12ee1eSDan Willemsen {Kind: &structpb.Value_NullValue{}}, 1348*1c12ee1eSDan Willemsen {Kind: &structpb.Value_NumberValue{3.1415}}, 1349*1c12ee1eSDan Willemsen {Kind: &structpb.Value_StringValue{"hello"}}, 1350*1c12ee1eSDan Willemsen { 1351*1c12ee1eSDan Willemsen Kind: &structpb.Value_ListValue{ 1352*1c12ee1eSDan Willemsen &structpb.ListValue{ 1353*1c12ee1eSDan Willemsen Values: []*structpb.Value{ 1354*1c12ee1eSDan Willemsen {Kind: &structpb.Value_BoolValue{}}, 1355*1c12ee1eSDan Willemsen {Kind: &structpb.Value_NullValue{}}, 1356*1c12ee1eSDan Willemsen {Kind: &structpb.Value_NumberValue{}}, 1357*1c12ee1eSDan Willemsen }, 1358*1c12ee1eSDan Willemsen }, 1359*1c12ee1eSDan Willemsen }, 1360*1c12ee1eSDan Willemsen }, 1361*1c12ee1eSDan Willemsen { 1362*1c12ee1eSDan Willemsen Kind: &structpb.Value_StructValue{ 1363*1c12ee1eSDan Willemsen &structpb.Struct{ 1364*1c12ee1eSDan Willemsen Fields: map[string]*structpb.Value{ 1365*1c12ee1eSDan Willemsen "string": {Kind: &structpb.Value_StringValue{"world"}}, 1366*1c12ee1eSDan Willemsen }, 1367*1c12ee1eSDan Willemsen }, 1368*1c12ee1eSDan Willemsen }, 1369*1c12ee1eSDan Willemsen }, 1370*1c12ee1eSDan Willemsen }, 1371*1c12ee1eSDan Willemsen }, 1372*1c12ee1eSDan Willemsen want: `[ 1373*1c12ee1eSDan Willemsen true, 1374*1c12ee1eSDan Willemsen null, 1375*1c12ee1eSDan Willemsen 3.1415, 1376*1c12ee1eSDan Willemsen "hello", 1377*1c12ee1eSDan Willemsen [ 1378*1c12ee1eSDan Willemsen false, 1379*1c12ee1eSDan Willemsen null, 1380*1c12ee1eSDan Willemsen 0 1381*1c12ee1eSDan Willemsen ], 1382*1c12ee1eSDan Willemsen { 1383*1c12ee1eSDan Willemsen "string": "world" 1384*1c12ee1eSDan Willemsen } 1385*1c12ee1eSDan Willemsen]`, 1386*1c12ee1eSDan Willemsen }, { 1387*1c12ee1eSDan Willemsen desc: "ListValue with invalid UTF8 string", 1388*1c12ee1eSDan Willemsen input: &structpb.ListValue{ 1389*1c12ee1eSDan Willemsen Values: []*structpb.Value{ 1390*1c12ee1eSDan Willemsen {Kind: &structpb.Value_StringValue{"\xff"}}, 1391*1c12ee1eSDan Willemsen }, 1392*1c12ee1eSDan Willemsen }, 1393*1c12ee1eSDan Willemsen wantErr: true, 1394*1c12ee1eSDan Willemsen }, { 1395*1c12ee1eSDan Willemsen desc: "Duration empty", 1396*1c12ee1eSDan Willemsen input: &durationpb.Duration{}, 1397*1c12ee1eSDan Willemsen want: `"0s"`, 1398*1c12ee1eSDan Willemsen }, { 1399*1c12ee1eSDan Willemsen desc: "Duration with secs", 1400*1c12ee1eSDan Willemsen input: &durationpb.Duration{Seconds: 3}, 1401*1c12ee1eSDan Willemsen want: `"3s"`, 1402*1c12ee1eSDan Willemsen }, { 1403*1c12ee1eSDan Willemsen desc: "Duration with -secs", 1404*1c12ee1eSDan Willemsen input: &durationpb.Duration{Seconds: -3}, 1405*1c12ee1eSDan Willemsen want: `"-3s"`, 1406*1c12ee1eSDan Willemsen }, { 1407*1c12ee1eSDan Willemsen desc: "Duration with nanos", 1408*1c12ee1eSDan Willemsen input: &durationpb.Duration{Nanos: 1e6}, 1409*1c12ee1eSDan Willemsen want: `"0.001s"`, 1410*1c12ee1eSDan Willemsen }, { 1411*1c12ee1eSDan Willemsen desc: "Duration with -nanos", 1412*1c12ee1eSDan Willemsen input: &durationpb.Duration{Nanos: -1e6}, 1413*1c12ee1eSDan Willemsen want: `"-0.001s"`, 1414*1c12ee1eSDan Willemsen }, { 1415*1c12ee1eSDan Willemsen desc: "Duration with large secs", 1416*1c12ee1eSDan Willemsen input: &durationpb.Duration{Seconds: 1e10, Nanos: 1}, 1417*1c12ee1eSDan Willemsen want: `"10000000000.000000001s"`, 1418*1c12ee1eSDan Willemsen }, { 1419*1c12ee1eSDan Willemsen desc: "Duration with 6-digit nanos", 1420*1c12ee1eSDan Willemsen input: &durationpb.Duration{Nanos: 1e4}, 1421*1c12ee1eSDan Willemsen want: `"0.000010s"`, 1422*1c12ee1eSDan Willemsen }, { 1423*1c12ee1eSDan Willemsen desc: "Duration with 3-digit nanos", 1424*1c12ee1eSDan Willemsen input: &durationpb.Duration{Nanos: 1e6}, 1425*1c12ee1eSDan Willemsen want: `"0.001s"`, 1426*1c12ee1eSDan Willemsen }, { 1427*1c12ee1eSDan Willemsen desc: "Duration with -secs -nanos", 1428*1c12ee1eSDan Willemsen input: &durationpb.Duration{Seconds: -123, Nanos: -450}, 1429*1c12ee1eSDan Willemsen want: `"-123.000000450s"`, 1430*1c12ee1eSDan Willemsen }, { 1431*1c12ee1eSDan Willemsen desc: "Duration max value", 1432*1c12ee1eSDan Willemsen input: &durationpb.Duration{Seconds: 315576000000, Nanos: 999999999}, 1433*1c12ee1eSDan Willemsen want: `"315576000000.999999999s"`, 1434*1c12ee1eSDan Willemsen }, { 1435*1c12ee1eSDan Willemsen desc: "Duration min value", 1436*1c12ee1eSDan Willemsen input: &durationpb.Duration{Seconds: -315576000000, Nanos: -999999999}, 1437*1c12ee1eSDan Willemsen want: `"-315576000000.999999999s"`, 1438*1c12ee1eSDan Willemsen }, { 1439*1c12ee1eSDan Willemsen desc: "Duration with +secs -nanos", 1440*1c12ee1eSDan Willemsen input: &durationpb.Duration{Seconds: 1, Nanos: -1}, 1441*1c12ee1eSDan Willemsen wantErr: true, 1442*1c12ee1eSDan Willemsen }, { 1443*1c12ee1eSDan Willemsen desc: "Duration with -secs +nanos", 1444*1c12ee1eSDan Willemsen input: &durationpb.Duration{Seconds: -1, Nanos: 1}, 1445*1c12ee1eSDan Willemsen wantErr: true, 1446*1c12ee1eSDan Willemsen }, { 1447*1c12ee1eSDan Willemsen desc: "Duration with +secs out of range", 1448*1c12ee1eSDan Willemsen input: &durationpb.Duration{Seconds: 315576000001}, 1449*1c12ee1eSDan Willemsen wantErr: true, 1450*1c12ee1eSDan Willemsen }, { 1451*1c12ee1eSDan Willemsen desc: "Duration with -secs out of range", 1452*1c12ee1eSDan Willemsen input: &durationpb.Duration{Seconds: -315576000001}, 1453*1c12ee1eSDan Willemsen wantErr: true, 1454*1c12ee1eSDan Willemsen }, { 1455*1c12ee1eSDan Willemsen desc: "Duration with +nanos out of range", 1456*1c12ee1eSDan Willemsen input: &durationpb.Duration{Seconds: 0, Nanos: 1e9}, 1457*1c12ee1eSDan Willemsen wantErr: true, 1458*1c12ee1eSDan Willemsen }, { 1459*1c12ee1eSDan Willemsen desc: "Duration with -nanos out of range", 1460*1c12ee1eSDan Willemsen input: &durationpb.Duration{Seconds: 0, Nanos: -1e9}, 1461*1c12ee1eSDan Willemsen wantErr: true, 1462*1c12ee1eSDan Willemsen }, { 1463*1c12ee1eSDan Willemsen desc: "Timestamp zero", 1464*1c12ee1eSDan Willemsen input: ×tamppb.Timestamp{}, 1465*1c12ee1eSDan Willemsen want: `"1970-01-01T00:00:00Z"`, 1466*1c12ee1eSDan Willemsen }, { 1467*1c12ee1eSDan Willemsen desc: "Timestamp", 1468*1c12ee1eSDan Willemsen input: ×tamppb.Timestamp{Seconds: 1553036601}, 1469*1c12ee1eSDan Willemsen want: `"2019-03-19T23:03:21Z"`, 1470*1c12ee1eSDan Willemsen }, { 1471*1c12ee1eSDan Willemsen desc: "Timestamp with nanos", 1472*1c12ee1eSDan Willemsen input: ×tamppb.Timestamp{Seconds: 1553036601, Nanos: 1}, 1473*1c12ee1eSDan Willemsen want: `"2019-03-19T23:03:21.000000001Z"`, 1474*1c12ee1eSDan Willemsen }, { 1475*1c12ee1eSDan Willemsen desc: "Timestamp with 6-digit nanos", 1476*1c12ee1eSDan Willemsen input: ×tamppb.Timestamp{Nanos: 1e3}, 1477*1c12ee1eSDan Willemsen want: `"1970-01-01T00:00:00.000001Z"`, 1478*1c12ee1eSDan Willemsen }, { 1479*1c12ee1eSDan Willemsen desc: "Timestamp with 3-digit nanos", 1480*1c12ee1eSDan Willemsen input: ×tamppb.Timestamp{Nanos: 1e7}, 1481*1c12ee1eSDan Willemsen want: `"1970-01-01T00:00:00.010Z"`, 1482*1c12ee1eSDan Willemsen }, { 1483*1c12ee1eSDan Willemsen desc: "Timestamp max value", 1484*1c12ee1eSDan Willemsen input: ×tamppb.Timestamp{Seconds: 253402300799, Nanos: 999999999}, 1485*1c12ee1eSDan Willemsen want: `"9999-12-31T23:59:59.999999999Z"`, 1486*1c12ee1eSDan Willemsen }, { 1487*1c12ee1eSDan Willemsen desc: "Timestamp min value", 1488*1c12ee1eSDan Willemsen input: ×tamppb.Timestamp{Seconds: -62135596800}, 1489*1c12ee1eSDan Willemsen want: `"0001-01-01T00:00:00Z"`, 1490*1c12ee1eSDan Willemsen }, { 1491*1c12ee1eSDan Willemsen desc: "Timestamp with +secs out of range", 1492*1c12ee1eSDan Willemsen input: ×tamppb.Timestamp{Seconds: 253402300800}, 1493*1c12ee1eSDan Willemsen wantErr: true, 1494*1c12ee1eSDan Willemsen }, { 1495*1c12ee1eSDan Willemsen desc: "Timestamp with -secs out of range", 1496*1c12ee1eSDan Willemsen input: ×tamppb.Timestamp{Seconds: -62135596801}, 1497*1c12ee1eSDan Willemsen wantErr: true, 1498*1c12ee1eSDan Willemsen }, { 1499*1c12ee1eSDan Willemsen desc: "Timestamp with -nanos", 1500*1c12ee1eSDan Willemsen input: ×tamppb.Timestamp{Nanos: -1}, 1501*1c12ee1eSDan Willemsen wantErr: true, 1502*1c12ee1eSDan Willemsen }, { 1503*1c12ee1eSDan Willemsen desc: "Timestamp with +nanos out of range", 1504*1c12ee1eSDan Willemsen input: ×tamppb.Timestamp{Nanos: 1e9}, 1505*1c12ee1eSDan Willemsen wantErr: true, 1506*1c12ee1eSDan Willemsen }, { 1507*1c12ee1eSDan Willemsen desc: "FieldMask empty", 1508*1c12ee1eSDan Willemsen input: &fieldmaskpb.FieldMask{}, 1509*1c12ee1eSDan Willemsen want: `""`, 1510*1c12ee1eSDan Willemsen }, { 1511*1c12ee1eSDan Willemsen desc: "FieldMask", 1512*1c12ee1eSDan Willemsen input: &fieldmaskpb.FieldMask{ 1513*1c12ee1eSDan Willemsen Paths: []string{ 1514*1c12ee1eSDan Willemsen "foo", 1515*1c12ee1eSDan Willemsen "foo_bar", 1516*1c12ee1eSDan Willemsen "foo.bar_qux", 1517*1c12ee1eSDan Willemsen "_foo", 1518*1c12ee1eSDan Willemsen }, 1519*1c12ee1eSDan Willemsen }, 1520*1c12ee1eSDan Willemsen want: `"foo,fooBar,foo.barQux,Foo"`, 1521*1c12ee1eSDan Willemsen }, { 1522*1c12ee1eSDan Willemsen desc: "FieldMask empty string path", 1523*1c12ee1eSDan Willemsen input: &fieldmaskpb.FieldMask{ 1524*1c12ee1eSDan Willemsen Paths: []string{""}, 1525*1c12ee1eSDan Willemsen }, 1526*1c12ee1eSDan Willemsen wantErr: true, 1527*1c12ee1eSDan Willemsen }, { 1528*1c12ee1eSDan Willemsen desc: "FieldMask path contains spaces only", 1529*1c12ee1eSDan Willemsen input: &fieldmaskpb.FieldMask{ 1530*1c12ee1eSDan Willemsen Paths: []string{" "}, 1531*1c12ee1eSDan Willemsen }, 1532*1c12ee1eSDan Willemsen wantErr: true, 1533*1c12ee1eSDan Willemsen }, { 1534*1c12ee1eSDan Willemsen desc: "FieldMask irreversible error 1", 1535*1c12ee1eSDan Willemsen input: &fieldmaskpb.FieldMask{ 1536*1c12ee1eSDan Willemsen Paths: []string{"foo_"}, 1537*1c12ee1eSDan Willemsen }, 1538*1c12ee1eSDan Willemsen wantErr: true, 1539*1c12ee1eSDan Willemsen }, { 1540*1c12ee1eSDan Willemsen desc: "FieldMask irreversible error 2", 1541*1c12ee1eSDan Willemsen input: &fieldmaskpb.FieldMask{ 1542*1c12ee1eSDan Willemsen Paths: []string{"foo__bar"}, 1543*1c12ee1eSDan Willemsen }, 1544*1c12ee1eSDan Willemsen wantErr: true, 1545*1c12ee1eSDan Willemsen }, { 1546*1c12ee1eSDan Willemsen desc: "FieldMask invalid char", 1547*1c12ee1eSDan Willemsen input: &fieldmaskpb.FieldMask{ 1548*1c12ee1eSDan Willemsen Paths: []string{"foo@bar"}, 1549*1c12ee1eSDan Willemsen }, 1550*1c12ee1eSDan Willemsen wantErr: true, 1551*1c12ee1eSDan Willemsen }, { 1552*1c12ee1eSDan Willemsen desc: "Any empty", 1553*1c12ee1eSDan Willemsen input: &anypb.Any{}, 1554*1c12ee1eSDan Willemsen want: `{}`, 1555*1c12ee1eSDan Willemsen }, { 1556*1c12ee1eSDan Willemsen desc: "Any with non-custom message", 1557*1c12ee1eSDan Willemsen input: func() proto.Message { 1558*1c12ee1eSDan Willemsen m := &pb2.Nested{ 1559*1c12ee1eSDan Willemsen OptString: proto.String("embedded inside Any"), 1560*1c12ee1eSDan Willemsen OptNested: &pb2.Nested{ 1561*1c12ee1eSDan Willemsen OptString: proto.String("inception"), 1562*1c12ee1eSDan Willemsen }, 1563*1c12ee1eSDan Willemsen } 1564*1c12ee1eSDan Willemsen b, err := proto.MarshalOptions{Deterministic: true}.Marshal(m) 1565*1c12ee1eSDan Willemsen if err != nil { 1566*1c12ee1eSDan Willemsen t.Fatalf("error in binary marshaling message for Any.value: %v", err) 1567*1c12ee1eSDan Willemsen } 1568*1c12ee1eSDan Willemsen return &anypb.Any{ 1569*1c12ee1eSDan Willemsen TypeUrl: "foo/pb2.Nested", 1570*1c12ee1eSDan Willemsen Value: b, 1571*1c12ee1eSDan Willemsen } 1572*1c12ee1eSDan Willemsen }(), 1573*1c12ee1eSDan Willemsen want: `{ 1574*1c12ee1eSDan Willemsen "@type": "foo/pb2.Nested", 1575*1c12ee1eSDan Willemsen "optString": "embedded inside Any", 1576*1c12ee1eSDan Willemsen "optNested": { 1577*1c12ee1eSDan Willemsen "optString": "inception" 1578*1c12ee1eSDan Willemsen } 1579*1c12ee1eSDan Willemsen}`, 1580*1c12ee1eSDan Willemsen }, { 1581*1c12ee1eSDan Willemsen desc: "Any with empty embedded message", 1582*1c12ee1eSDan Willemsen input: &anypb.Any{TypeUrl: "foo/pb2.Nested"}, 1583*1c12ee1eSDan Willemsen want: `{ 1584*1c12ee1eSDan Willemsen "@type": "foo/pb2.Nested" 1585*1c12ee1eSDan Willemsen}`, 1586*1c12ee1eSDan Willemsen }, { 1587*1c12ee1eSDan Willemsen desc: "Any without registered type", 1588*1c12ee1eSDan Willemsen mo: protojson.MarshalOptions{Resolver: new(protoregistry.Types)}, 1589*1c12ee1eSDan Willemsen input: &anypb.Any{TypeUrl: "foo/pb2.Nested"}, 1590*1c12ee1eSDan Willemsen wantErr: true, 1591*1c12ee1eSDan Willemsen }, { 1592*1c12ee1eSDan Willemsen desc: "Any with missing required", 1593*1c12ee1eSDan Willemsen input: func() proto.Message { 1594*1c12ee1eSDan Willemsen m := &pb2.PartialRequired{ 1595*1c12ee1eSDan Willemsen OptString: proto.String("embedded inside Any"), 1596*1c12ee1eSDan Willemsen } 1597*1c12ee1eSDan Willemsen b, err := proto.MarshalOptions{ 1598*1c12ee1eSDan Willemsen AllowPartial: true, 1599*1c12ee1eSDan Willemsen Deterministic: true, 1600*1c12ee1eSDan Willemsen }.Marshal(m) 1601*1c12ee1eSDan Willemsen if err != nil { 1602*1c12ee1eSDan Willemsen t.Fatalf("error in binary marshaling message for Any.value: %v", err) 1603*1c12ee1eSDan Willemsen } 1604*1c12ee1eSDan Willemsen return &anypb.Any{ 1605*1c12ee1eSDan Willemsen TypeUrl: string(m.ProtoReflect().Descriptor().FullName()), 1606*1c12ee1eSDan Willemsen Value: b, 1607*1c12ee1eSDan Willemsen } 1608*1c12ee1eSDan Willemsen }(), 1609*1c12ee1eSDan Willemsen want: `{ 1610*1c12ee1eSDan Willemsen "@type": "pb2.PartialRequired", 1611*1c12ee1eSDan Willemsen "optString": "embedded inside Any" 1612*1c12ee1eSDan Willemsen}`, 1613*1c12ee1eSDan Willemsen }, { 1614*1c12ee1eSDan Willemsen desc: "Any with partial required and AllowPartial", 1615*1c12ee1eSDan Willemsen mo: protojson.MarshalOptions{ 1616*1c12ee1eSDan Willemsen AllowPartial: true, 1617*1c12ee1eSDan Willemsen }, 1618*1c12ee1eSDan Willemsen input: func() proto.Message { 1619*1c12ee1eSDan Willemsen m := &pb2.PartialRequired{ 1620*1c12ee1eSDan Willemsen OptString: proto.String("embedded inside Any"), 1621*1c12ee1eSDan Willemsen } 1622*1c12ee1eSDan Willemsen b, err := proto.MarshalOptions{ 1623*1c12ee1eSDan Willemsen AllowPartial: true, 1624*1c12ee1eSDan Willemsen Deterministic: true, 1625*1c12ee1eSDan Willemsen }.Marshal(m) 1626*1c12ee1eSDan Willemsen if err != nil { 1627*1c12ee1eSDan Willemsen t.Fatalf("error in binary marshaling message for Any.value: %v", err) 1628*1c12ee1eSDan Willemsen } 1629*1c12ee1eSDan Willemsen return &anypb.Any{ 1630*1c12ee1eSDan Willemsen TypeUrl: string(m.ProtoReflect().Descriptor().FullName()), 1631*1c12ee1eSDan Willemsen Value: b, 1632*1c12ee1eSDan Willemsen } 1633*1c12ee1eSDan Willemsen }(), 1634*1c12ee1eSDan Willemsen want: `{ 1635*1c12ee1eSDan Willemsen "@type": "pb2.PartialRequired", 1636*1c12ee1eSDan Willemsen "optString": "embedded inside Any" 1637*1c12ee1eSDan Willemsen}`, 1638*1c12ee1eSDan Willemsen }, { 1639*1c12ee1eSDan Willemsen desc: "Any with EmitUnpopulated", 1640*1c12ee1eSDan Willemsen mo: protojson.MarshalOptions{ 1641*1c12ee1eSDan Willemsen EmitUnpopulated: true, 1642*1c12ee1eSDan Willemsen }, 1643*1c12ee1eSDan Willemsen input: func() proto.Message { 1644*1c12ee1eSDan Willemsen return &anypb.Any{ 1645*1c12ee1eSDan Willemsen TypeUrl: string(new(pb3.Scalars).ProtoReflect().Descriptor().FullName()), 1646*1c12ee1eSDan Willemsen } 1647*1c12ee1eSDan Willemsen }(), 1648*1c12ee1eSDan Willemsen want: `{ 1649*1c12ee1eSDan Willemsen "@type": "pb3.Scalars", 1650*1c12ee1eSDan Willemsen "sBool": false, 1651*1c12ee1eSDan Willemsen "sInt32": 0, 1652*1c12ee1eSDan Willemsen "sInt64": "0", 1653*1c12ee1eSDan Willemsen "sUint32": 0, 1654*1c12ee1eSDan Willemsen "sUint64": "0", 1655*1c12ee1eSDan Willemsen "sSint32": 0, 1656*1c12ee1eSDan Willemsen "sSint64": "0", 1657*1c12ee1eSDan Willemsen "sFixed32": 0, 1658*1c12ee1eSDan Willemsen "sFixed64": "0", 1659*1c12ee1eSDan Willemsen "sSfixed32": 0, 1660*1c12ee1eSDan Willemsen "sSfixed64": "0", 1661*1c12ee1eSDan Willemsen "sFloat": 0, 1662*1c12ee1eSDan Willemsen "sDouble": 0, 1663*1c12ee1eSDan Willemsen "sBytes": "", 1664*1c12ee1eSDan Willemsen "sString": "" 1665*1c12ee1eSDan Willemsen}`, 1666*1c12ee1eSDan Willemsen }, { 1667*1c12ee1eSDan Willemsen desc: "Any with invalid UTF8", 1668*1c12ee1eSDan Willemsen input: func() proto.Message { 1669*1c12ee1eSDan Willemsen m := &pb2.Nested{ 1670*1c12ee1eSDan Willemsen OptString: proto.String("abc\xff"), 1671*1c12ee1eSDan Willemsen } 1672*1c12ee1eSDan Willemsen b, err := proto.MarshalOptions{Deterministic: true}.Marshal(m) 1673*1c12ee1eSDan Willemsen if err != nil { 1674*1c12ee1eSDan Willemsen t.Fatalf("error in binary marshaling message for Any.value: %v", err) 1675*1c12ee1eSDan Willemsen } 1676*1c12ee1eSDan Willemsen return &anypb.Any{ 1677*1c12ee1eSDan Willemsen TypeUrl: "foo/pb2.Nested", 1678*1c12ee1eSDan Willemsen Value: b, 1679*1c12ee1eSDan Willemsen } 1680*1c12ee1eSDan Willemsen }(), 1681*1c12ee1eSDan Willemsen wantErr: true, 1682*1c12ee1eSDan Willemsen }, { 1683*1c12ee1eSDan Willemsen desc: "Any with invalid value", 1684*1c12ee1eSDan Willemsen input: &anypb.Any{ 1685*1c12ee1eSDan Willemsen TypeUrl: "foo/pb2.Nested", 1686*1c12ee1eSDan Willemsen Value: []byte("\x80"), 1687*1c12ee1eSDan Willemsen }, 1688*1c12ee1eSDan Willemsen wantErr: true, 1689*1c12ee1eSDan Willemsen }, { 1690*1c12ee1eSDan Willemsen desc: "Any with BoolValue", 1691*1c12ee1eSDan Willemsen input: func() proto.Message { 1692*1c12ee1eSDan Willemsen m := &wrapperspb.BoolValue{Value: true} 1693*1c12ee1eSDan Willemsen b, err := proto.MarshalOptions{Deterministic: true}.Marshal(m) 1694*1c12ee1eSDan Willemsen if err != nil { 1695*1c12ee1eSDan Willemsen t.Fatalf("error in binary marshaling message for Any.value: %v", err) 1696*1c12ee1eSDan Willemsen } 1697*1c12ee1eSDan Willemsen return &anypb.Any{ 1698*1c12ee1eSDan Willemsen TypeUrl: "type.googleapis.com/google.protobuf.BoolValue", 1699*1c12ee1eSDan Willemsen Value: b, 1700*1c12ee1eSDan Willemsen } 1701*1c12ee1eSDan Willemsen }(), 1702*1c12ee1eSDan Willemsen want: `{ 1703*1c12ee1eSDan Willemsen "@type": "type.googleapis.com/google.protobuf.BoolValue", 1704*1c12ee1eSDan Willemsen "value": true 1705*1c12ee1eSDan Willemsen}`, 1706*1c12ee1eSDan Willemsen }, { 1707*1c12ee1eSDan Willemsen desc: "Any with Empty", 1708*1c12ee1eSDan Willemsen input: func() proto.Message { 1709*1c12ee1eSDan Willemsen m := &emptypb.Empty{} 1710*1c12ee1eSDan Willemsen b, err := proto.MarshalOptions{Deterministic: true}.Marshal(m) 1711*1c12ee1eSDan Willemsen if err != nil { 1712*1c12ee1eSDan Willemsen t.Fatalf("error in binary marshaling message for Any.value: %v", err) 1713*1c12ee1eSDan Willemsen } 1714*1c12ee1eSDan Willemsen return &anypb.Any{ 1715*1c12ee1eSDan Willemsen TypeUrl: "type.googleapis.com/google.protobuf.Empty", 1716*1c12ee1eSDan Willemsen Value: b, 1717*1c12ee1eSDan Willemsen } 1718*1c12ee1eSDan Willemsen }(), 1719*1c12ee1eSDan Willemsen want: `{ 1720*1c12ee1eSDan Willemsen "@type": "type.googleapis.com/google.protobuf.Empty", 1721*1c12ee1eSDan Willemsen "value": {} 1722*1c12ee1eSDan Willemsen}`, 1723*1c12ee1eSDan Willemsen }, { 1724*1c12ee1eSDan Willemsen desc: "Any with StringValue containing invalid UTF8", 1725*1c12ee1eSDan Willemsen input: func() proto.Message { 1726*1c12ee1eSDan Willemsen m := &wrapperspb.StringValue{Value: "abcd"} 1727*1c12ee1eSDan Willemsen b, err := proto.MarshalOptions{Deterministic: true}.Marshal(m) 1728*1c12ee1eSDan Willemsen if err != nil { 1729*1c12ee1eSDan Willemsen t.Fatalf("error in binary marshaling message for Any.value: %v", err) 1730*1c12ee1eSDan Willemsen } 1731*1c12ee1eSDan Willemsen return &anypb.Any{ 1732*1c12ee1eSDan Willemsen TypeUrl: "google.protobuf.StringValue", 1733*1c12ee1eSDan Willemsen Value: bytes.Replace(b, []byte("abcd"), []byte("abc\xff"), -1), 1734*1c12ee1eSDan Willemsen } 1735*1c12ee1eSDan Willemsen }(), 1736*1c12ee1eSDan Willemsen wantErr: true, 1737*1c12ee1eSDan Willemsen }, { 1738*1c12ee1eSDan Willemsen desc: "Any with Int64Value", 1739*1c12ee1eSDan Willemsen input: func() proto.Message { 1740*1c12ee1eSDan Willemsen m := &wrapperspb.Int64Value{Value: 42} 1741*1c12ee1eSDan Willemsen b, err := proto.MarshalOptions{Deterministic: true}.Marshal(m) 1742*1c12ee1eSDan Willemsen if err != nil { 1743*1c12ee1eSDan Willemsen t.Fatalf("error in binary marshaling message for Any.value: %v", err) 1744*1c12ee1eSDan Willemsen } 1745*1c12ee1eSDan Willemsen return &anypb.Any{ 1746*1c12ee1eSDan Willemsen TypeUrl: "google.protobuf.Int64Value", 1747*1c12ee1eSDan Willemsen Value: b, 1748*1c12ee1eSDan Willemsen } 1749*1c12ee1eSDan Willemsen }(), 1750*1c12ee1eSDan Willemsen want: `{ 1751*1c12ee1eSDan Willemsen "@type": "google.protobuf.Int64Value", 1752*1c12ee1eSDan Willemsen "value": "42" 1753*1c12ee1eSDan Willemsen}`, 1754*1c12ee1eSDan Willemsen }, { 1755*1c12ee1eSDan Willemsen desc: "Any with Duration", 1756*1c12ee1eSDan Willemsen input: func() proto.Message { 1757*1c12ee1eSDan Willemsen m := &durationpb.Duration{} 1758*1c12ee1eSDan Willemsen b, err := proto.MarshalOptions{Deterministic: true}.Marshal(m) 1759*1c12ee1eSDan Willemsen if err != nil { 1760*1c12ee1eSDan Willemsen t.Fatalf("error in binary marshaling message for Any.value: %v", err) 1761*1c12ee1eSDan Willemsen } 1762*1c12ee1eSDan Willemsen return &anypb.Any{ 1763*1c12ee1eSDan Willemsen TypeUrl: "type.googleapis.com/google.protobuf.Duration", 1764*1c12ee1eSDan Willemsen Value: b, 1765*1c12ee1eSDan Willemsen } 1766*1c12ee1eSDan Willemsen }(), 1767*1c12ee1eSDan Willemsen want: `{ 1768*1c12ee1eSDan Willemsen "@type": "type.googleapis.com/google.protobuf.Duration", 1769*1c12ee1eSDan Willemsen "value": "0s" 1770*1c12ee1eSDan Willemsen}`, 1771*1c12ee1eSDan Willemsen }, { 1772*1c12ee1eSDan Willemsen desc: "Any with empty Value", 1773*1c12ee1eSDan Willemsen input: func() proto.Message { 1774*1c12ee1eSDan Willemsen m := &structpb.Value{} 1775*1c12ee1eSDan Willemsen b, err := proto.Marshal(m) 1776*1c12ee1eSDan Willemsen if err != nil { 1777*1c12ee1eSDan Willemsen t.Fatalf("error in binary marshaling message for Any.value: %v", err) 1778*1c12ee1eSDan Willemsen } 1779*1c12ee1eSDan Willemsen return &anypb.Any{ 1780*1c12ee1eSDan Willemsen TypeUrl: "type.googleapis.com/google.protobuf.Value", 1781*1c12ee1eSDan Willemsen Value: b, 1782*1c12ee1eSDan Willemsen } 1783*1c12ee1eSDan Willemsen }(), 1784*1c12ee1eSDan Willemsen wantErr: true, 1785*1c12ee1eSDan Willemsen }, { 1786*1c12ee1eSDan Willemsen desc: "Any with Value of StringValue", 1787*1c12ee1eSDan Willemsen input: func() proto.Message { 1788*1c12ee1eSDan Willemsen m := &structpb.Value{Kind: &structpb.Value_StringValue{"abcd"}} 1789*1c12ee1eSDan Willemsen b, err := proto.MarshalOptions{Deterministic: true}.Marshal(m) 1790*1c12ee1eSDan Willemsen if err != nil { 1791*1c12ee1eSDan Willemsen t.Fatalf("error in binary marshaling message for Any.value: %v", err) 1792*1c12ee1eSDan Willemsen } 1793*1c12ee1eSDan Willemsen return &anypb.Any{ 1794*1c12ee1eSDan Willemsen TypeUrl: "type.googleapis.com/google.protobuf.Value", 1795*1c12ee1eSDan Willemsen Value: bytes.Replace(b, []byte("abcd"), []byte("abc\xff"), -1), 1796*1c12ee1eSDan Willemsen } 1797*1c12ee1eSDan Willemsen }(), 1798*1c12ee1eSDan Willemsen wantErr: true, 1799*1c12ee1eSDan Willemsen }, { 1800*1c12ee1eSDan Willemsen desc: "Any with Value of NullValue", 1801*1c12ee1eSDan Willemsen input: func() proto.Message { 1802*1c12ee1eSDan Willemsen m := &structpb.Value{Kind: &structpb.Value_NullValue{}} 1803*1c12ee1eSDan Willemsen b, err := proto.MarshalOptions{Deterministic: true}.Marshal(m) 1804*1c12ee1eSDan Willemsen if err != nil { 1805*1c12ee1eSDan Willemsen t.Fatalf("error in binary marshaling message for Any.value: %v", err) 1806*1c12ee1eSDan Willemsen } 1807*1c12ee1eSDan Willemsen return &anypb.Any{ 1808*1c12ee1eSDan Willemsen TypeUrl: "type.googleapis.com/google.protobuf.Value", 1809*1c12ee1eSDan Willemsen Value: b, 1810*1c12ee1eSDan Willemsen } 1811*1c12ee1eSDan Willemsen }(), 1812*1c12ee1eSDan Willemsen want: `{ 1813*1c12ee1eSDan Willemsen "@type": "type.googleapis.com/google.protobuf.Value", 1814*1c12ee1eSDan Willemsen "value": null 1815*1c12ee1eSDan Willemsen}`, 1816*1c12ee1eSDan Willemsen }, { 1817*1c12ee1eSDan Willemsen desc: "Any with Struct", 1818*1c12ee1eSDan Willemsen input: func() proto.Message { 1819*1c12ee1eSDan Willemsen m := &structpb.Struct{ 1820*1c12ee1eSDan Willemsen Fields: map[string]*structpb.Value{ 1821*1c12ee1eSDan Willemsen "bool": {Kind: &structpb.Value_BoolValue{true}}, 1822*1c12ee1eSDan Willemsen "null": {Kind: &structpb.Value_NullValue{}}, 1823*1c12ee1eSDan Willemsen "string": {Kind: &structpb.Value_StringValue{"hello"}}, 1824*1c12ee1eSDan Willemsen "struct": { 1825*1c12ee1eSDan Willemsen Kind: &structpb.Value_StructValue{ 1826*1c12ee1eSDan Willemsen &structpb.Struct{ 1827*1c12ee1eSDan Willemsen Fields: map[string]*structpb.Value{ 1828*1c12ee1eSDan Willemsen "string": {Kind: &structpb.Value_StringValue{"world"}}, 1829*1c12ee1eSDan Willemsen }, 1830*1c12ee1eSDan Willemsen }, 1831*1c12ee1eSDan Willemsen }, 1832*1c12ee1eSDan Willemsen }, 1833*1c12ee1eSDan Willemsen }, 1834*1c12ee1eSDan Willemsen } 1835*1c12ee1eSDan Willemsen b, err := proto.MarshalOptions{Deterministic: true}.Marshal(m) 1836*1c12ee1eSDan Willemsen if err != nil { 1837*1c12ee1eSDan Willemsen t.Fatalf("error in binary marshaling message for Any.value: %v", err) 1838*1c12ee1eSDan Willemsen } 1839*1c12ee1eSDan Willemsen return &anypb.Any{ 1840*1c12ee1eSDan Willemsen TypeUrl: "google.protobuf.Struct", 1841*1c12ee1eSDan Willemsen Value: b, 1842*1c12ee1eSDan Willemsen } 1843*1c12ee1eSDan Willemsen }(), 1844*1c12ee1eSDan Willemsen want: `{ 1845*1c12ee1eSDan Willemsen "@type": "google.protobuf.Struct", 1846*1c12ee1eSDan Willemsen "value": { 1847*1c12ee1eSDan Willemsen "bool": true, 1848*1c12ee1eSDan Willemsen "null": null, 1849*1c12ee1eSDan Willemsen "string": "hello", 1850*1c12ee1eSDan Willemsen "struct": { 1851*1c12ee1eSDan Willemsen "string": "world" 1852*1c12ee1eSDan Willemsen } 1853*1c12ee1eSDan Willemsen } 1854*1c12ee1eSDan Willemsen}`, 1855*1c12ee1eSDan Willemsen }, { 1856*1c12ee1eSDan Willemsen desc: "Any with missing type_url", 1857*1c12ee1eSDan Willemsen input: func() proto.Message { 1858*1c12ee1eSDan Willemsen m := &wrapperspb.BoolValue{Value: true} 1859*1c12ee1eSDan Willemsen b, err := proto.MarshalOptions{Deterministic: true}.Marshal(m) 1860*1c12ee1eSDan Willemsen if err != nil { 1861*1c12ee1eSDan Willemsen t.Fatalf("error in binary marshaling message for Any.value: %v", err) 1862*1c12ee1eSDan Willemsen } 1863*1c12ee1eSDan Willemsen return &anypb.Any{ 1864*1c12ee1eSDan Willemsen Value: b, 1865*1c12ee1eSDan Willemsen } 1866*1c12ee1eSDan Willemsen }(), 1867*1c12ee1eSDan Willemsen wantErr: true, 1868*1c12ee1eSDan Willemsen }, { 1869*1c12ee1eSDan Willemsen desc: "well known types as field values", 1870*1c12ee1eSDan Willemsen input: &pb2.KnownTypes{ 1871*1c12ee1eSDan Willemsen OptBool: &wrapperspb.BoolValue{Value: false}, 1872*1c12ee1eSDan Willemsen OptInt32: &wrapperspb.Int32Value{Value: 42}, 1873*1c12ee1eSDan Willemsen OptInt64: &wrapperspb.Int64Value{Value: 42}, 1874*1c12ee1eSDan Willemsen OptUint32: &wrapperspb.UInt32Value{Value: 42}, 1875*1c12ee1eSDan Willemsen OptUint64: &wrapperspb.UInt64Value{Value: 42}, 1876*1c12ee1eSDan Willemsen OptFloat: &wrapperspb.FloatValue{Value: 1.23}, 1877*1c12ee1eSDan Willemsen OptDouble: &wrapperspb.DoubleValue{Value: 3.1415}, 1878*1c12ee1eSDan Willemsen OptString: &wrapperspb.StringValue{Value: "hello"}, 1879*1c12ee1eSDan Willemsen OptBytes: &wrapperspb.BytesValue{Value: []byte("hello")}, 1880*1c12ee1eSDan Willemsen OptDuration: &durationpb.Duration{Seconds: 123}, 1881*1c12ee1eSDan Willemsen OptTimestamp: ×tamppb.Timestamp{Seconds: 1553036601}, 1882*1c12ee1eSDan Willemsen OptStruct: &structpb.Struct{ 1883*1c12ee1eSDan Willemsen Fields: map[string]*structpb.Value{ 1884*1c12ee1eSDan Willemsen "string": {Kind: &structpb.Value_StringValue{"hello"}}, 1885*1c12ee1eSDan Willemsen }, 1886*1c12ee1eSDan Willemsen }, 1887*1c12ee1eSDan Willemsen OptList: &structpb.ListValue{ 1888*1c12ee1eSDan Willemsen Values: []*structpb.Value{ 1889*1c12ee1eSDan Willemsen {Kind: &structpb.Value_NullValue{}}, 1890*1c12ee1eSDan Willemsen {Kind: &structpb.Value_StringValue{}}, 1891*1c12ee1eSDan Willemsen {Kind: &structpb.Value_StructValue{}}, 1892*1c12ee1eSDan Willemsen {Kind: &structpb.Value_ListValue{}}, 1893*1c12ee1eSDan Willemsen }, 1894*1c12ee1eSDan Willemsen }, 1895*1c12ee1eSDan Willemsen OptValue: &structpb.Value{ 1896*1c12ee1eSDan Willemsen Kind: &structpb.Value_StringValue{"world"}, 1897*1c12ee1eSDan Willemsen }, 1898*1c12ee1eSDan Willemsen OptEmpty: &emptypb.Empty{}, 1899*1c12ee1eSDan Willemsen OptAny: &anypb.Any{ 1900*1c12ee1eSDan Willemsen TypeUrl: "google.protobuf.Empty", 1901*1c12ee1eSDan Willemsen }, 1902*1c12ee1eSDan Willemsen OptFieldmask: &fieldmaskpb.FieldMask{ 1903*1c12ee1eSDan Willemsen Paths: []string{"foo_bar", "bar_foo"}, 1904*1c12ee1eSDan Willemsen }, 1905*1c12ee1eSDan Willemsen }, 1906*1c12ee1eSDan Willemsen want: `{ 1907*1c12ee1eSDan Willemsen "optBool": false, 1908*1c12ee1eSDan Willemsen "optInt32": 42, 1909*1c12ee1eSDan Willemsen "optInt64": "42", 1910*1c12ee1eSDan Willemsen "optUint32": 42, 1911*1c12ee1eSDan Willemsen "optUint64": "42", 1912*1c12ee1eSDan Willemsen "optFloat": 1.23, 1913*1c12ee1eSDan Willemsen "optDouble": 3.1415, 1914*1c12ee1eSDan Willemsen "optString": "hello", 1915*1c12ee1eSDan Willemsen "optBytes": "aGVsbG8=", 1916*1c12ee1eSDan Willemsen "optDuration": "123s", 1917*1c12ee1eSDan Willemsen "optTimestamp": "2019-03-19T23:03:21Z", 1918*1c12ee1eSDan Willemsen "optStruct": { 1919*1c12ee1eSDan Willemsen "string": "hello" 1920*1c12ee1eSDan Willemsen }, 1921*1c12ee1eSDan Willemsen "optList": [ 1922*1c12ee1eSDan Willemsen null, 1923*1c12ee1eSDan Willemsen "", 1924*1c12ee1eSDan Willemsen {}, 1925*1c12ee1eSDan Willemsen [] 1926*1c12ee1eSDan Willemsen ], 1927*1c12ee1eSDan Willemsen "optValue": "world", 1928*1c12ee1eSDan Willemsen "optEmpty": {}, 1929*1c12ee1eSDan Willemsen "optAny": { 1930*1c12ee1eSDan Willemsen "@type": "google.protobuf.Empty", 1931*1c12ee1eSDan Willemsen "value": {} 1932*1c12ee1eSDan Willemsen }, 1933*1c12ee1eSDan Willemsen "optFieldmask": "fooBar,barFoo" 1934*1c12ee1eSDan Willemsen}`, 1935*1c12ee1eSDan Willemsen }, { 1936*1c12ee1eSDan Willemsen desc: "EmitUnpopulated: proto2 optional scalars", 1937*1c12ee1eSDan Willemsen mo: protojson.MarshalOptions{EmitUnpopulated: true}, 1938*1c12ee1eSDan Willemsen input: &pb2.Scalars{}, 1939*1c12ee1eSDan Willemsen want: `{ 1940*1c12ee1eSDan Willemsen "optBool": null, 1941*1c12ee1eSDan Willemsen "optInt32": null, 1942*1c12ee1eSDan Willemsen "optInt64": null, 1943*1c12ee1eSDan Willemsen "optUint32": null, 1944*1c12ee1eSDan Willemsen "optUint64": null, 1945*1c12ee1eSDan Willemsen "optSint32": null, 1946*1c12ee1eSDan Willemsen "optSint64": null, 1947*1c12ee1eSDan Willemsen "optFixed32": null, 1948*1c12ee1eSDan Willemsen "optFixed64": null, 1949*1c12ee1eSDan Willemsen "optSfixed32": null, 1950*1c12ee1eSDan Willemsen "optSfixed64": null, 1951*1c12ee1eSDan Willemsen "optFloat": null, 1952*1c12ee1eSDan Willemsen "optDouble": null, 1953*1c12ee1eSDan Willemsen "optBytes": null, 1954*1c12ee1eSDan Willemsen "optString": null 1955*1c12ee1eSDan Willemsen}`, 1956*1c12ee1eSDan Willemsen }, { 1957*1c12ee1eSDan Willemsen desc: "EmitUnpopulated: proto3 scalars", 1958*1c12ee1eSDan Willemsen mo: protojson.MarshalOptions{EmitUnpopulated: true}, 1959*1c12ee1eSDan Willemsen input: &pb3.Scalars{}, 1960*1c12ee1eSDan Willemsen want: `{ 1961*1c12ee1eSDan Willemsen "sBool": false, 1962*1c12ee1eSDan Willemsen "sInt32": 0, 1963*1c12ee1eSDan Willemsen "sInt64": "0", 1964*1c12ee1eSDan Willemsen "sUint32": 0, 1965*1c12ee1eSDan Willemsen "sUint64": "0", 1966*1c12ee1eSDan Willemsen "sSint32": 0, 1967*1c12ee1eSDan Willemsen "sSint64": "0", 1968*1c12ee1eSDan Willemsen "sFixed32": 0, 1969*1c12ee1eSDan Willemsen "sFixed64": "0", 1970*1c12ee1eSDan Willemsen "sSfixed32": 0, 1971*1c12ee1eSDan Willemsen "sSfixed64": "0", 1972*1c12ee1eSDan Willemsen "sFloat": 0, 1973*1c12ee1eSDan Willemsen "sDouble": 0, 1974*1c12ee1eSDan Willemsen "sBytes": "", 1975*1c12ee1eSDan Willemsen "sString": "" 1976*1c12ee1eSDan Willemsen}`, 1977*1c12ee1eSDan Willemsen }, { 1978*1c12ee1eSDan Willemsen desc: "EmitUnpopulated: proto2 enum", 1979*1c12ee1eSDan Willemsen mo: protojson.MarshalOptions{EmitUnpopulated: true}, 1980*1c12ee1eSDan Willemsen input: &pb2.Enums{}, 1981*1c12ee1eSDan Willemsen want: `{ 1982*1c12ee1eSDan Willemsen "optEnum": null, 1983*1c12ee1eSDan Willemsen "rptEnum": [], 1984*1c12ee1eSDan Willemsen "optNestedEnum": null, 1985*1c12ee1eSDan Willemsen "rptNestedEnum": [] 1986*1c12ee1eSDan Willemsen}`, 1987*1c12ee1eSDan Willemsen }, { 1988*1c12ee1eSDan Willemsen desc: "EmitUnpopulated: proto3 enum", 1989*1c12ee1eSDan Willemsen mo: protojson.MarshalOptions{EmitUnpopulated: true}, 1990*1c12ee1eSDan Willemsen input: &pb3.Enums{}, 1991*1c12ee1eSDan Willemsen want: `{ 1992*1c12ee1eSDan Willemsen "sEnum": "ZERO", 1993*1c12ee1eSDan Willemsen "sNestedEnum": "CERO" 1994*1c12ee1eSDan Willemsen}`, 1995*1c12ee1eSDan Willemsen }, { 1996*1c12ee1eSDan Willemsen desc: "EmitUnpopulated: proto2 message and group fields", 1997*1c12ee1eSDan Willemsen mo: protojson.MarshalOptions{EmitUnpopulated: true}, 1998*1c12ee1eSDan Willemsen input: &pb2.Nests{}, 1999*1c12ee1eSDan Willemsen want: `{ 2000*1c12ee1eSDan Willemsen "optNested": null, 2001*1c12ee1eSDan Willemsen "optgroup": null, 2002*1c12ee1eSDan Willemsen "rptNested": [], 2003*1c12ee1eSDan Willemsen "rptgroup": [] 2004*1c12ee1eSDan Willemsen}`, 2005*1c12ee1eSDan Willemsen }, { 2006*1c12ee1eSDan Willemsen desc: "EmitUnpopulated: proto3 message field", 2007*1c12ee1eSDan Willemsen mo: protojson.MarshalOptions{EmitUnpopulated: true}, 2008*1c12ee1eSDan Willemsen input: &pb3.Nests{}, 2009*1c12ee1eSDan Willemsen want: `{ 2010*1c12ee1eSDan Willemsen "sNested": null 2011*1c12ee1eSDan Willemsen}`, 2012*1c12ee1eSDan Willemsen }, { 2013*1c12ee1eSDan Willemsen desc: "EmitUnpopulated: proto2 empty message and group fields", 2014*1c12ee1eSDan Willemsen mo: protojson.MarshalOptions{EmitUnpopulated: true}, 2015*1c12ee1eSDan Willemsen input: &pb2.Nests{ 2016*1c12ee1eSDan Willemsen OptNested: &pb2.Nested{}, 2017*1c12ee1eSDan Willemsen Optgroup: &pb2.Nests_OptGroup{}, 2018*1c12ee1eSDan Willemsen }, 2019*1c12ee1eSDan Willemsen want: `{ 2020*1c12ee1eSDan Willemsen "optNested": { 2021*1c12ee1eSDan Willemsen "optString": null, 2022*1c12ee1eSDan Willemsen "optNested": null 2023*1c12ee1eSDan Willemsen }, 2024*1c12ee1eSDan Willemsen "optgroup": { 2025*1c12ee1eSDan Willemsen "optString": null, 2026*1c12ee1eSDan Willemsen "optNested": null, 2027*1c12ee1eSDan Willemsen "optnestedgroup": null 2028*1c12ee1eSDan Willemsen }, 2029*1c12ee1eSDan Willemsen "rptNested": [], 2030*1c12ee1eSDan Willemsen "rptgroup": [] 2031*1c12ee1eSDan Willemsen}`, 2032*1c12ee1eSDan Willemsen }, { 2033*1c12ee1eSDan Willemsen desc: "EmitUnpopulated: proto3 empty message field", 2034*1c12ee1eSDan Willemsen mo: protojson.MarshalOptions{EmitUnpopulated: true}, 2035*1c12ee1eSDan Willemsen input: &pb3.Nests{ 2036*1c12ee1eSDan Willemsen SNested: &pb3.Nested{}, 2037*1c12ee1eSDan Willemsen }, 2038*1c12ee1eSDan Willemsen want: `{ 2039*1c12ee1eSDan Willemsen "sNested": { 2040*1c12ee1eSDan Willemsen "sString": "", 2041*1c12ee1eSDan Willemsen "sNested": null 2042*1c12ee1eSDan Willemsen } 2043*1c12ee1eSDan Willemsen}`, 2044*1c12ee1eSDan Willemsen }, { 2045*1c12ee1eSDan Willemsen desc: "EmitUnpopulated: proto2 required fields", 2046*1c12ee1eSDan Willemsen mo: protojson.MarshalOptions{ 2047*1c12ee1eSDan Willemsen AllowPartial: true, 2048*1c12ee1eSDan Willemsen EmitUnpopulated: true, 2049*1c12ee1eSDan Willemsen }, 2050*1c12ee1eSDan Willemsen input: &pb2.Requireds{}, 2051*1c12ee1eSDan Willemsen want: `{ 2052*1c12ee1eSDan Willemsen "reqBool": null, 2053*1c12ee1eSDan Willemsen "reqSfixed64": null, 2054*1c12ee1eSDan Willemsen "reqDouble": null, 2055*1c12ee1eSDan Willemsen "reqString": null, 2056*1c12ee1eSDan Willemsen "reqEnum": null, 2057*1c12ee1eSDan Willemsen "reqNested": null 2058*1c12ee1eSDan Willemsen}`, 2059*1c12ee1eSDan Willemsen }, { 2060*1c12ee1eSDan Willemsen desc: "EmitUnpopulated: repeated fields", 2061*1c12ee1eSDan Willemsen mo: protojson.MarshalOptions{EmitUnpopulated: true}, 2062*1c12ee1eSDan Willemsen input: &pb2.Repeats{}, 2063*1c12ee1eSDan Willemsen want: `{ 2064*1c12ee1eSDan Willemsen "rptBool": [], 2065*1c12ee1eSDan Willemsen "rptInt32": [], 2066*1c12ee1eSDan Willemsen "rptInt64": [], 2067*1c12ee1eSDan Willemsen "rptUint32": [], 2068*1c12ee1eSDan Willemsen "rptUint64": [], 2069*1c12ee1eSDan Willemsen "rptFloat": [], 2070*1c12ee1eSDan Willemsen "rptDouble": [], 2071*1c12ee1eSDan Willemsen "rptString": [], 2072*1c12ee1eSDan Willemsen "rptBytes": [] 2073*1c12ee1eSDan Willemsen}`, 2074*1c12ee1eSDan Willemsen }, { 2075*1c12ee1eSDan Willemsen desc: "EmitUnpopulated: repeated containing empty message", 2076*1c12ee1eSDan Willemsen mo: protojson.MarshalOptions{EmitUnpopulated: true}, 2077*1c12ee1eSDan Willemsen input: &pb2.Nests{ 2078*1c12ee1eSDan Willemsen RptNested: []*pb2.Nested{nil, {}}, 2079*1c12ee1eSDan Willemsen }, 2080*1c12ee1eSDan Willemsen want: `{ 2081*1c12ee1eSDan Willemsen "optNested": null, 2082*1c12ee1eSDan Willemsen "optgroup": null, 2083*1c12ee1eSDan Willemsen "rptNested": [ 2084*1c12ee1eSDan Willemsen { 2085*1c12ee1eSDan Willemsen "optString": null, 2086*1c12ee1eSDan Willemsen "optNested": null 2087*1c12ee1eSDan Willemsen }, 2088*1c12ee1eSDan Willemsen { 2089*1c12ee1eSDan Willemsen "optString": null, 2090*1c12ee1eSDan Willemsen "optNested": null 2091*1c12ee1eSDan Willemsen } 2092*1c12ee1eSDan Willemsen ], 2093*1c12ee1eSDan Willemsen "rptgroup": [] 2094*1c12ee1eSDan Willemsen}`, 2095*1c12ee1eSDan Willemsen }, { 2096*1c12ee1eSDan Willemsen desc: "EmitUnpopulated: map fields", 2097*1c12ee1eSDan Willemsen mo: protojson.MarshalOptions{EmitUnpopulated: true}, 2098*1c12ee1eSDan Willemsen input: &pb3.Maps{}, 2099*1c12ee1eSDan Willemsen want: `{ 2100*1c12ee1eSDan Willemsen "int32ToStr": {}, 2101*1c12ee1eSDan Willemsen "boolToUint32": {}, 2102*1c12ee1eSDan Willemsen "uint64ToEnum": {}, 2103*1c12ee1eSDan Willemsen "strToNested": {}, 2104*1c12ee1eSDan Willemsen "strToOneofs": {} 2105*1c12ee1eSDan Willemsen}`, 2106*1c12ee1eSDan Willemsen }, { 2107*1c12ee1eSDan Willemsen desc: "EmitUnpopulated: map containing empty message", 2108*1c12ee1eSDan Willemsen mo: protojson.MarshalOptions{EmitUnpopulated: true}, 2109*1c12ee1eSDan Willemsen input: &pb3.Maps{ 2110*1c12ee1eSDan Willemsen StrToNested: map[string]*pb3.Nested{ 2111*1c12ee1eSDan Willemsen "nested": &pb3.Nested{}, 2112*1c12ee1eSDan Willemsen }, 2113*1c12ee1eSDan Willemsen StrToOneofs: map[string]*pb3.Oneofs{ 2114*1c12ee1eSDan Willemsen "nested": &pb3.Oneofs{}, 2115*1c12ee1eSDan Willemsen }, 2116*1c12ee1eSDan Willemsen }, 2117*1c12ee1eSDan Willemsen want: `{ 2118*1c12ee1eSDan Willemsen "int32ToStr": {}, 2119*1c12ee1eSDan Willemsen "boolToUint32": {}, 2120*1c12ee1eSDan Willemsen "uint64ToEnum": {}, 2121*1c12ee1eSDan Willemsen "strToNested": { 2122*1c12ee1eSDan Willemsen "nested": { 2123*1c12ee1eSDan Willemsen "sString": "", 2124*1c12ee1eSDan Willemsen "sNested": null 2125*1c12ee1eSDan Willemsen } 2126*1c12ee1eSDan Willemsen }, 2127*1c12ee1eSDan Willemsen "strToOneofs": { 2128*1c12ee1eSDan Willemsen "nested": {} 2129*1c12ee1eSDan Willemsen } 2130*1c12ee1eSDan Willemsen}`, 2131*1c12ee1eSDan Willemsen }, { 2132*1c12ee1eSDan Willemsen desc: "EmitUnpopulated: oneof fields", 2133*1c12ee1eSDan Willemsen mo: protojson.MarshalOptions{EmitUnpopulated: true}, 2134*1c12ee1eSDan Willemsen input: &pb3.Oneofs{}, 2135*1c12ee1eSDan Willemsen want: `{}`, 2136*1c12ee1eSDan Willemsen }, { 2137*1c12ee1eSDan Willemsen desc: "EmitUnpopulated: extensions", 2138*1c12ee1eSDan Willemsen mo: protojson.MarshalOptions{EmitUnpopulated: true}, 2139*1c12ee1eSDan Willemsen input: func() proto.Message { 2140*1c12ee1eSDan Willemsen m := &pb2.Extensions{} 2141*1c12ee1eSDan Willemsen proto.SetExtension(m, pb2.E_OptExtNested, &pb2.Nested{}) 2142*1c12ee1eSDan Willemsen proto.SetExtension(m, pb2.E_RptExtNested, []*pb2.Nested{ 2143*1c12ee1eSDan Willemsen nil, 2144*1c12ee1eSDan Willemsen {}, 2145*1c12ee1eSDan Willemsen }) 2146*1c12ee1eSDan Willemsen return m 2147*1c12ee1eSDan Willemsen }(), 2148*1c12ee1eSDan Willemsen want: `{ 2149*1c12ee1eSDan Willemsen "optString": null, 2150*1c12ee1eSDan Willemsen "optBool": null, 2151*1c12ee1eSDan Willemsen "optInt32": null, 2152*1c12ee1eSDan Willemsen "[pb2.opt_ext_nested]": { 2153*1c12ee1eSDan Willemsen "optString": null, 2154*1c12ee1eSDan Willemsen "optNested": null 2155*1c12ee1eSDan Willemsen }, 2156*1c12ee1eSDan Willemsen "[pb2.rpt_ext_nested]": [ 2157*1c12ee1eSDan Willemsen { 2158*1c12ee1eSDan Willemsen "optString": null, 2159*1c12ee1eSDan Willemsen "optNested": null 2160*1c12ee1eSDan Willemsen }, 2161*1c12ee1eSDan Willemsen { 2162*1c12ee1eSDan Willemsen "optString": null, 2163*1c12ee1eSDan Willemsen "optNested": null 2164*1c12ee1eSDan Willemsen } 2165*1c12ee1eSDan Willemsen ] 2166*1c12ee1eSDan Willemsen}`, 2167*1c12ee1eSDan Willemsen }, { 2168*1c12ee1eSDan Willemsen desc: "EmitUnpopulated: with populated fields", 2169*1c12ee1eSDan Willemsen mo: protojson.MarshalOptions{EmitUnpopulated: true}, 2170*1c12ee1eSDan Willemsen input: &pb2.Scalars{ 2171*1c12ee1eSDan Willemsen OptInt32: proto.Int32(0xff), 2172*1c12ee1eSDan Willemsen OptUint32: proto.Uint32(47), 2173*1c12ee1eSDan Willemsen OptSint32: proto.Int32(-1001), 2174*1c12ee1eSDan Willemsen OptFixed32: proto.Uint32(32), 2175*1c12ee1eSDan Willemsen OptSfixed32: proto.Int32(-32), 2176*1c12ee1eSDan Willemsen OptFloat: proto.Float32(1.02), 2177*1c12ee1eSDan Willemsen OptBytes: []byte("谷歌"), 2178*1c12ee1eSDan Willemsen }, 2179*1c12ee1eSDan Willemsen want: `{ 2180*1c12ee1eSDan Willemsen "optBool": null, 2181*1c12ee1eSDan Willemsen "optInt32": 255, 2182*1c12ee1eSDan Willemsen "optInt64": null, 2183*1c12ee1eSDan Willemsen "optUint32": 47, 2184*1c12ee1eSDan Willemsen "optUint64": null, 2185*1c12ee1eSDan Willemsen "optSint32": -1001, 2186*1c12ee1eSDan Willemsen "optSint64": null, 2187*1c12ee1eSDan Willemsen "optFixed32": 32, 2188*1c12ee1eSDan Willemsen "optFixed64": null, 2189*1c12ee1eSDan Willemsen "optSfixed32": -32, 2190*1c12ee1eSDan Willemsen "optSfixed64": null, 2191*1c12ee1eSDan Willemsen "optFloat": 1.02, 2192*1c12ee1eSDan Willemsen "optDouble": null, 2193*1c12ee1eSDan Willemsen "optBytes": "6LC35q2M", 2194*1c12ee1eSDan Willemsen "optString": null 2195*1c12ee1eSDan Willemsen}`, 2196*1c12ee1eSDan Willemsen }, { 2197*1c12ee1eSDan Willemsen desc: "UseEnumNumbers in singular field", 2198*1c12ee1eSDan Willemsen mo: protojson.MarshalOptions{UseEnumNumbers: true}, 2199*1c12ee1eSDan Willemsen input: &pb2.Enums{ 2200*1c12ee1eSDan Willemsen OptEnum: pb2.Enum_ONE.Enum(), 2201*1c12ee1eSDan Willemsen OptNestedEnum: pb2.Enums_UNO.Enum(), 2202*1c12ee1eSDan Willemsen }, 2203*1c12ee1eSDan Willemsen want: `{ 2204*1c12ee1eSDan Willemsen "optEnum": 1, 2205*1c12ee1eSDan Willemsen "optNestedEnum": 1 2206*1c12ee1eSDan Willemsen}`, 2207*1c12ee1eSDan Willemsen }, { 2208*1c12ee1eSDan Willemsen desc: "UseEnumNumbers in repeated field", 2209*1c12ee1eSDan Willemsen mo: protojson.MarshalOptions{UseEnumNumbers: true}, 2210*1c12ee1eSDan Willemsen input: &pb2.Enums{ 2211*1c12ee1eSDan Willemsen RptEnum: []pb2.Enum{pb2.Enum_ONE, 2, pb2.Enum_TEN, 42}, 2212*1c12ee1eSDan Willemsen RptNestedEnum: []pb2.Enums_NestedEnum{pb2.Enums_UNO, pb2.Enums_DOS, 47}, 2213*1c12ee1eSDan Willemsen }, 2214*1c12ee1eSDan Willemsen want: `{ 2215*1c12ee1eSDan Willemsen "rptEnum": [ 2216*1c12ee1eSDan Willemsen 1, 2217*1c12ee1eSDan Willemsen 2, 2218*1c12ee1eSDan Willemsen 10, 2219*1c12ee1eSDan Willemsen 42 2220*1c12ee1eSDan Willemsen ], 2221*1c12ee1eSDan Willemsen "rptNestedEnum": [ 2222*1c12ee1eSDan Willemsen 1, 2223*1c12ee1eSDan Willemsen 2, 2224*1c12ee1eSDan Willemsen 47 2225*1c12ee1eSDan Willemsen ] 2226*1c12ee1eSDan Willemsen}`, 2227*1c12ee1eSDan Willemsen }, { 2228*1c12ee1eSDan Willemsen desc: "UseEnumNumbers in map field", 2229*1c12ee1eSDan Willemsen mo: protojson.MarshalOptions{UseEnumNumbers: true}, 2230*1c12ee1eSDan Willemsen input: &pb3.Maps{ 2231*1c12ee1eSDan Willemsen Uint64ToEnum: map[uint64]pb3.Enum{ 2232*1c12ee1eSDan Willemsen 1: pb3.Enum_ONE, 2233*1c12ee1eSDan Willemsen 2: pb3.Enum_TWO, 2234*1c12ee1eSDan Willemsen 10: pb3.Enum_TEN, 2235*1c12ee1eSDan Willemsen 47: 47, 2236*1c12ee1eSDan Willemsen }, 2237*1c12ee1eSDan Willemsen }, 2238*1c12ee1eSDan Willemsen want: `{ 2239*1c12ee1eSDan Willemsen "uint64ToEnum": { 2240*1c12ee1eSDan Willemsen "1": 1, 2241*1c12ee1eSDan Willemsen "2": 2, 2242*1c12ee1eSDan Willemsen "10": 10, 2243*1c12ee1eSDan Willemsen "47": 47 2244*1c12ee1eSDan Willemsen } 2245*1c12ee1eSDan Willemsen}`, 2246*1c12ee1eSDan Willemsen }, { 2247*1c12ee1eSDan Willemsen desc: "UseProtoNames", 2248*1c12ee1eSDan Willemsen mo: protojson.MarshalOptions{UseProtoNames: true}, 2249*1c12ee1eSDan Willemsen input: &pb2.Nests{ 2250*1c12ee1eSDan Willemsen OptNested: &pb2.Nested{}, 2251*1c12ee1eSDan Willemsen Optgroup: &pb2.Nests_OptGroup{ 2252*1c12ee1eSDan Willemsen OptString: proto.String("inside a group"), 2253*1c12ee1eSDan Willemsen OptNested: &pb2.Nested{ 2254*1c12ee1eSDan Willemsen OptString: proto.String("nested message inside a group"), 2255*1c12ee1eSDan Willemsen }, 2256*1c12ee1eSDan Willemsen Optnestedgroup: &pb2.Nests_OptGroup_OptNestedGroup{ 2257*1c12ee1eSDan Willemsen OptFixed32: proto.Uint32(47), 2258*1c12ee1eSDan Willemsen }, 2259*1c12ee1eSDan Willemsen }, 2260*1c12ee1eSDan Willemsen Rptgroup: []*pb2.Nests_RptGroup{ 2261*1c12ee1eSDan Willemsen { 2262*1c12ee1eSDan Willemsen RptString: []string{"hello", "world"}, 2263*1c12ee1eSDan Willemsen }, 2264*1c12ee1eSDan Willemsen }, 2265*1c12ee1eSDan Willemsen }, 2266*1c12ee1eSDan Willemsen want: `{ 2267*1c12ee1eSDan Willemsen "opt_nested": {}, 2268*1c12ee1eSDan Willemsen "OptGroup": { 2269*1c12ee1eSDan Willemsen "opt_string": "inside a group", 2270*1c12ee1eSDan Willemsen "opt_nested": { 2271*1c12ee1eSDan Willemsen "opt_string": "nested message inside a group" 2272*1c12ee1eSDan Willemsen }, 2273*1c12ee1eSDan Willemsen "OptNestedGroup": { 2274*1c12ee1eSDan Willemsen "opt_fixed32": 47 2275*1c12ee1eSDan Willemsen } 2276*1c12ee1eSDan Willemsen }, 2277*1c12ee1eSDan Willemsen "RptGroup": [ 2278*1c12ee1eSDan Willemsen { 2279*1c12ee1eSDan Willemsen "rpt_string": [ 2280*1c12ee1eSDan Willemsen "hello", 2281*1c12ee1eSDan Willemsen "world" 2282*1c12ee1eSDan Willemsen ] 2283*1c12ee1eSDan Willemsen } 2284*1c12ee1eSDan Willemsen ] 2285*1c12ee1eSDan Willemsen}`, 2286*1c12ee1eSDan Willemsen }} 2287*1c12ee1eSDan Willemsen 2288*1c12ee1eSDan Willemsen for _, tt := range tests { 2289*1c12ee1eSDan Willemsen tt := tt 2290*1c12ee1eSDan Willemsen if tt.skip { 2291*1c12ee1eSDan Willemsen continue 2292*1c12ee1eSDan Willemsen } 2293*1c12ee1eSDan Willemsen t.Run(tt.desc, func(t *testing.T) { 2294*1c12ee1eSDan Willemsen // Use 2-space indentation on all MarshalOptions. 2295*1c12ee1eSDan Willemsen tt.mo.Indent = " " 2296*1c12ee1eSDan Willemsen b, err := tt.mo.Marshal(tt.input) 2297*1c12ee1eSDan Willemsen if err != nil && !tt.wantErr { 2298*1c12ee1eSDan Willemsen t.Errorf("Marshal() returned error: %v\n", err) 2299*1c12ee1eSDan Willemsen } 2300*1c12ee1eSDan Willemsen if err == nil && tt.wantErr { 2301*1c12ee1eSDan Willemsen t.Errorf("Marshal() got nil error, want error\n") 2302*1c12ee1eSDan Willemsen } 2303*1c12ee1eSDan Willemsen got := string(b) 2304*1c12ee1eSDan Willemsen if got != tt.want { 2305*1c12ee1eSDan Willemsen t.Errorf("Marshal()\n<got>\n%v\n<want>\n%v\n", got, tt.want) 2306*1c12ee1eSDan Willemsen if diff := cmp.Diff(tt.want, got); diff != "" { 2307*1c12ee1eSDan Willemsen t.Errorf("Marshal() diff -want +got\n%v\n", diff) 2308*1c12ee1eSDan Willemsen } 2309*1c12ee1eSDan Willemsen } 2310*1c12ee1eSDan Willemsen }) 2311*1c12ee1eSDan Willemsen } 2312*1c12ee1eSDan Willemsen} 2313