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