blob: 5ef4594455b7b52f97220a9f418b94c503b7c93e [file] [log] [blame]
Herbie Ongc96a79d2019-03-08 10:49:17 -08001// Copyright 2019 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
Damien Neil5c5b5312019-05-14 12:44:37 -07005package protojson_test
Herbie Ongc96a79d2019-03-08 10:49:17 -08006
7import (
8 "math"
Herbie Ongd2ece132020-01-07 16:45:24 -08009 "strings"
Herbie Ongc96a79d2019-03-08 10:49:17 -080010 "testing"
11
Damien Neil5c5b5312019-05-14 12:44:37 -070012 "google.golang.org/protobuf/encoding/protojson"
Herbie Ongd2ece132020-01-07 16:45:24 -080013 "google.golang.org/protobuf/internal/errors"
Joe Tsaid47ea192019-07-09 22:38:15 -070014 "google.golang.org/protobuf/internal/flags"
Damien Neile89e6242019-05-13 23:55:40 -070015 "google.golang.org/protobuf/proto"
16 preg "google.golang.org/protobuf/reflect/protoregistry"
Herbie Onge63c4c42019-03-22 22:20:22 -070017
Joe Tsaid47ea192019-07-09 22:38:15 -070018 testpb "google.golang.org/protobuf/internal/testprotos/test"
19 weakpb "google.golang.org/protobuf/internal/testprotos/test/weak1"
Joe Tsai94e730b2020-01-10 23:31:25 -080020 pb2 "google.golang.org/protobuf/internal/testprotos/textpb2"
21 pb3 "google.golang.org/protobuf/internal/testprotos/textpb3"
Joe Tsaia95b29f2019-05-16 12:47:20 -070022 "google.golang.org/protobuf/types/known/anypb"
23 "google.golang.org/protobuf/types/known/durationpb"
24 "google.golang.org/protobuf/types/known/emptypb"
25 "google.golang.org/protobuf/types/known/fieldmaskpb"
26 "google.golang.org/protobuf/types/known/structpb"
27 "google.golang.org/protobuf/types/known/timestamppb"
28 "google.golang.org/protobuf/types/known/wrapperspb"
Herbie Ongc96a79d2019-03-08 10:49:17 -080029)
30
31func TestUnmarshal(t *testing.T) {
32 tests := []struct {
33 desc string
Damien Neil5c5b5312019-05-14 12:44:37 -070034 umo protojson.UnmarshalOptions
Herbie Ongc96a79d2019-03-08 10:49:17 -080035 inputMessage proto.Message
36 inputText string
37 wantMessage proto.Message
Herbie Ongd2ece132020-01-07 16:45:24 -080038 wantErr string // Expected error substring.
39 skip bool
Herbie Ongc96a79d2019-03-08 10:49:17 -080040 }{{
41 desc: "proto2 empty message",
42 inputMessage: &pb2.Scalars{},
43 inputText: "{}",
44 wantMessage: &pb2.Scalars{},
45 }, {
46 desc: "unexpected value instead of EOF",
47 inputMessage: &pb2.Scalars{},
48 inputText: "{} {}",
Herbie Ongd2ece132020-01-07 16:45:24 -080049 wantErr: `(line 1:4): unexpected token {`,
Herbie Ongc96a79d2019-03-08 10:49:17 -080050 }, {
51 desc: "proto2 optional scalars set to zero values",
52 inputMessage: &pb2.Scalars{},
53 inputText: `{
54 "optBool": false,
55 "optInt32": 0,
56 "optInt64": 0,
57 "optUint32": 0,
58 "optUint64": 0,
59 "optSint32": 0,
60 "optSint64": 0,
61 "optFixed32": 0,
62 "optFixed64": 0,
63 "optSfixed32": 0,
64 "optSfixed64": 0,
65 "optFloat": 0,
66 "optDouble": 0,
67 "optBytes": "",
68 "optString": ""
69}`,
70 wantMessage: &pb2.Scalars{
Damien Neila8a2cea2019-07-10 16:17:16 -070071 OptBool: proto.Bool(false),
72 OptInt32: proto.Int32(0),
73 OptInt64: proto.Int64(0),
74 OptUint32: proto.Uint32(0),
75 OptUint64: proto.Uint64(0),
76 OptSint32: proto.Int32(0),
77 OptSint64: proto.Int64(0),
78 OptFixed32: proto.Uint32(0),
79 OptFixed64: proto.Uint64(0),
80 OptSfixed32: proto.Int32(0),
81 OptSfixed64: proto.Int64(0),
82 OptFloat: proto.Float32(0),
83 OptDouble: proto.Float64(0),
Herbie Ongc96a79d2019-03-08 10:49:17 -080084 OptBytes: []byte{},
Damien Neila8a2cea2019-07-10 16:17:16 -070085 OptString: proto.String(""),
Herbie Ongc96a79d2019-03-08 10:49:17 -080086 },
87 }, {
88 desc: "proto3 scalars set to zero values",
89 inputMessage: &pb3.Scalars{},
90 inputText: `{
91 "sBool": false,
92 "sInt32": 0,
93 "sInt64": 0,
94 "sUint32": 0,
95 "sUint64": 0,
96 "sSint32": 0,
97 "sSint64": 0,
98 "sFixed32": 0,
99 "sFixed64": 0,
100 "sSfixed32": 0,
101 "sSfixed64": 0,
102 "sFloat": 0,
103 "sDouble": 0,
104 "sBytes": "",
105 "sString": ""
106}`,
107 wantMessage: &pb3.Scalars{},
108 }, {
109 desc: "proto2 optional scalars set to null",
110 inputMessage: &pb2.Scalars{},
111 inputText: `{
112 "optBool": null,
113 "optInt32": null,
114 "optInt64": null,
115 "optUint32": null,
116 "optUint64": null,
117 "optSint32": null,
118 "optSint64": null,
119 "optFixed32": null,
120 "optFixed64": null,
121 "optSfixed32": null,
122 "optSfixed64": null,
123 "optFloat": null,
124 "optDouble": null,
125 "optBytes": null,
126 "optString": null
127}`,
128 wantMessage: &pb2.Scalars{},
129 }, {
130 desc: "proto3 scalars set to null",
131 inputMessage: &pb3.Scalars{},
132 inputText: `{
133 "sBool": null,
134 "sInt32": null,
135 "sInt64": null,
136 "sUint32": null,
137 "sUint64": null,
138 "sSint32": null,
139 "sSint64": null,
140 "sFixed32": null,
141 "sFixed64": null,
142 "sSfixed32": null,
143 "sSfixed64": null,
144 "sFloat": null,
145 "sDouble": null,
146 "sBytes": null,
147 "sString": null
148}`,
149 wantMessage: &pb3.Scalars{},
150 }, {
151 desc: "boolean",
152 inputMessage: &pb3.Scalars{},
153 inputText: `{"sBool": true}`,
154 wantMessage: &pb3.Scalars{
155 SBool: true,
156 },
157 }, {
158 desc: "not boolean",
159 inputMessage: &pb3.Scalars{},
160 inputText: `{"sBool": "true"}`,
Herbie Ongd2ece132020-01-07 16:45:24 -0800161 wantErr: `invalid value for bool type: "true"`,
Herbie Ongc96a79d2019-03-08 10:49:17 -0800162 }, {
163 desc: "float and double",
164 inputMessage: &pb3.Scalars{},
165 inputText: `{
166 "sFloat": 1.234,
167 "sDouble": 5.678
168}`,
169 wantMessage: &pb3.Scalars{
170 SFloat: 1.234,
171 SDouble: 5.678,
172 },
173 }, {
174 desc: "float and double in string",
175 inputMessage: &pb3.Scalars{},
176 inputText: `{
177 "sFloat": "1.234",
178 "sDouble": "5.678"
179}`,
180 wantMessage: &pb3.Scalars{
181 SFloat: 1.234,
182 SDouble: 5.678,
183 },
184 }, {
185 desc: "float and double in E notation",
186 inputMessage: &pb3.Scalars{},
187 inputText: `{
188 "sFloat": 12.34E-1,
189 "sDouble": 5.678e4
190}`,
191 wantMessage: &pb3.Scalars{
192 SFloat: 1.234,
193 SDouble: 56780,
194 },
195 }, {
196 desc: "float and double in string E notation",
197 inputMessage: &pb3.Scalars{},
198 inputText: `{
199 "sFloat": "12.34E-1",
200 "sDouble": "5.678e4"
201}`,
202 wantMessage: &pb3.Scalars{
203 SFloat: 1.234,
204 SDouble: 56780,
205 },
206 }, {
207 desc: "float exceeds limit",
208 inputMessage: &pb3.Scalars{},
209 inputText: `{"sFloat": 3.4e39}`,
Herbie Ongd2ece132020-01-07 16:45:24 -0800210 wantErr: `invalid value for float type: 3.4e39`,
Herbie Ongc96a79d2019-03-08 10:49:17 -0800211 }, {
212 desc: "float in string exceeds limit",
213 inputMessage: &pb3.Scalars{},
214 inputText: `{"sFloat": "-3.4e39"}`,
Herbie Ongd2ece132020-01-07 16:45:24 -0800215 wantErr: `invalid value for float type: "-3.4e39"`,
Herbie Ongc96a79d2019-03-08 10:49:17 -0800216 }, {
217 desc: "double exceeds limit",
218 inputMessage: &pb3.Scalars{},
Herbie Ongd2ece132020-01-07 16:45:24 -0800219 inputText: `{"sDouble": -1.79e+309}`,
220 wantErr: `invalid value for double type: -1.79e+309`,
Herbie Ongc96a79d2019-03-08 10:49:17 -0800221 }, {
222 desc: "double in string exceeds limit",
223 inputMessage: &pb3.Scalars{},
Herbie Ongd2ece132020-01-07 16:45:24 -0800224 inputText: `{"sDouble": "1.79e+309"}`,
225 wantErr: `invalid value for double type: "1.79e+309"`,
Herbie Ongc96a79d2019-03-08 10:49:17 -0800226 }, {
227 desc: "infinites",
228 inputMessage: &pb3.Scalars{},
229 inputText: `{"sFloat": "Infinity", "sDouble": "-Infinity"}`,
230 wantMessage: &pb3.Scalars{
231 SFloat: float32(math.Inf(+1)),
232 SDouble: math.Inf(-1),
233 },
234 }, {
Herbie Ong06a6b0b2019-04-24 21:15:45 -0700235 desc: "float string with leading space",
236 inputMessage: &pb3.Scalars{},
237 inputText: `{"sFloat": " 1.234"}`,
Herbie Ongd2ece132020-01-07 16:45:24 -0800238 wantErr: `invalid value for float type: " 1.234"`,
Herbie Ong06a6b0b2019-04-24 21:15:45 -0700239 }, {
240 desc: "double string with trailing space",
241 inputMessage: &pb3.Scalars{},
242 inputText: `{"sDouble": "5.678 "}`,
Herbie Ongd2ece132020-01-07 16:45:24 -0800243 wantErr: `invalid value for double type: "5.678 "`,
Herbie Ong06a6b0b2019-04-24 21:15:45 -0700244 }, {
Herbie Ongc96a79d2019-03-08 10:49:17 -0800245 desc: "not float",
246 inputMessage: &pb3.Scalars{},
247 inputText: `{"sFloat": true}`,
Herbie Ongd2ece132020-01-07 16:45:24 -0800248 wantErr: `invalid value for float type: true`,
Herbie Ongc96a79d2019-03-08 10:49:17 -0800249 }, {
250 desc: "not double",
251 inputMessage: &pb3.Scalars{},
252 inputText: `{"sDouble": "not a number"}`,
Herbie Ongd2ece132020-01-07 16:45:24 -0800253 wantErr: `invalid value for double type: "not a number"`,
Herbie Ongc96a79d2019-03-08 10:49:17 -0800254 }, {
255 desc: "integers",
256 inputMessage: &pb3.Scalars{},
257 inputText: `{
258 "sInt32": 1234,
259 "sInt64": -1234,
260 "sUint32": 1e2,
261 "sUint64": 100E-2,
262 "sSint32": 1.0,
263 "sSint64": -1.0,
264 "sFixed32": 1.234e+5,
265 "sFixed64": 1200E-2,
266 "sSfixed32": -1.234e05,
267 "sSfixed64": -1200e-02
268}`,
269 wantMessage: &pb3.Scalars{
270 SInt32: 1234,
271 SInt64: -1234,
272 SUint32: 100,
273 SUint64: 1,
274 SSint32: 1,
275 SSint64: -1,
276 SFixed32: 123400,
277 SFixed64: 12,
278 SSfixed32: -123400,
279 SSfixed64: -12,
280 },
281 }, {
282 desc: "integers in string",
283 inputMessage: &pb3.Scalars{},
284 inputText: `{
285 "sInt32": "1234",
286 "sInt64": "-1234",
287 "sUint32": "1e2",
288 "sUint64": "100E-2",
289 "sSint32": "1.0",
290 "sSint64": "-1.0",
291 "sFixed32": "1.234e+5",
292 "sFixed64": "1200E-2",
293 "sSfixed32": "-1.234e05",
294 "sSfixed64": "-1200e-02"
295}`,
296 wantMessage: &pb3.Scalars{
297 SInt32: 1234,
298 SInt64: -1234,
299 SUint32: 100,
300 SUint64: 1,
301 SSint32: 1,
302 SSint64: -1,
303 SFixed32: 123400,
304 SFixed64: 12,
305 SSfixed32: -123400,
306 SSfixed64: -12,
307 },
308 }, {
309 desc: "integers in escaped string",
310 inputMessage: &pb3.Scalars{},
311 inputText: `{"sInt32": "\u0031\u0032"}`,
312 wantMessage: &pb3.Scalars{
313 SInt32: 12,
314 },
315 }, {
Herbie Ong06a6b0b2019-04-24 21:15:45 -0700316 desc: "integer string with leading space",
317 inputMessage: &pb3.Scalars{},
318 inputText: `{"sInt32": " 1234"}`,
Herbie Ongd2ece132020-01-07 16:45:24 -0800319 wantErr: `invalid value for int32 type: " 1234"`,
Herbie Ong06a6b0b2019-04-24 21:15:45 -0700320 }, {
321 desc: "integer string with trailing space",
322 inputMessage: &pb3.Scalars{},
323 inputText: `{"sUint32": "1e2 "}`,
Herbie Ongd2ece132020-01-07 16:45:24 -0800324 wantErr: `invalid value for uint32 type: "1e2 "`,
Herbie Ong06a6b0b2019-04-24 21:15:45 -0700325 }, {
Herbie Ongc96a79d2019-03-08 10:49:17 -0800326 desc: "number is not an integer",
327 inputMessage: &pb3.Scalars{},
328 inputText: `{"sInt32": 1.001}`,
Herbie Ongd2ece132020-01-07 16:45:24 -0800329 wantErr: `invalid value for int32 type: 1.001`,
Herbie Ongc96a79d2019-03-08 10:49:17 -0800330 }, {
331 desc: "32-bit int exceeds limit",
332 inputMessage: &pb3.Scalars{},
333 inputText: `{"sInt32": 2e10}`,
Herbie Ongd2ece132020-01-07 16:45:24 -0800334 wantErr: `invalid value for int32 type: 2e10`,
Herbie Ongc96a79d2019-03-08 10:49:17 -0800335 }, {
336 desc: "64-bit int exceeds limit",
337 inputMessage: &pb3.Scalars{},
338 inputText: `{"sSfixed64": -9e19}`,
Herbie Ongd2ece132020-01-07 16:45:24 -0800339 wantErr: `invalid value for sfixed64 type: -9e19`,
Herbie Ongc96a79d2019-03-08 10:49:17 -0800340 }, {
341 desc: "not integer",
342 inputMessage: &pb3.Scalars{},
343 inputText: `{"sInt32": "not a number"}`,
Herbie Ongd2ece132020-01-07 16:45:24 -0800344 wantErr: `invalid value for int32 type: "not a number"`,
Herbie Ongc96a79d2019-03-08 10:49:17 -0800345 }, {
346 desc: "not unsigned integer",
347 inputMessage: &pb3.Scalars{},
348 inputText: `{"sUint32": "not a number"}`,
Herbie Ongd2ece132020-01-07 16:45:24 -0800349 wantErr: `invalid value for uint32 type: "not a number"`,
Herbie Ongc96a79d2019-03-08 10:49:17 -0800350 }, {
351 desc: "number is not an unsigned integer",
352 inputMessage: &pb3.Scalars{},
353 inputText: `{"sUint32": -1}`,
Herbie Ongd2ece132020-01-07 16:45:24 -0800354 wantErr: `invalid value for uint32 type: -1`,
Herbie Ongc96a79d2019-03-08 10:49:17 -0800355 }, {
356 desc: "string",
357 inputMessage: &pb2.Scalars{},
358 inputText: `{"optString": "谷歌"}`,
359 wantMessage: &pb2.Scalars{
Damien Neila8a2cea2019-07-10 16:17:16 -0700360 OptString: proto.String("谷歌"),
Herbie Ongc96a79d2019-03-08 10:49:17 -0800361 },
362 }, {
363 desc: "string with invalid UTF-8",
364 inputMessage: &pb3.Scalars{},
365 inputText: "{\"sString\": \"\xff\"}",
Herbie Ongd2ece132020-01-07 16:45:24 -0800366 wantErr: `(line 1:13): invalid UTF-8 in string`,
Herbie Ongc96a79d2019-03-08 10:49:17 -0800367 }, {
368 desc: "not string",
369 inputMessage: &pb2.Scalars{},
370 inputText: `{"optString": 42}`,
Herbie Ongd2ece132020-01-07 16:45:24 -0800371 wantErr: `invalid value for string type: 42`,
Herbie Ongc96a79d2019-03-08 10:49:17 -0800372 }, {
373 desc: "bytes",
374 inputMessage: &pb3.Scalars{},
375 inputText: `{"sBytes": "aGVsbG8gd29ybGQ"}`,
376 wantMessage: &pb3.Scalars{
377 SBytes: []byte("hello world"),
378 },
379 }, {
380 desc: "bytes padded",
381 inputMessage: &pb3.Scalars{},
382 inputText: `{"sBytes": "aGVsbG8gd29ybGQ="}`,
383 wantMessage: &pb3.Scalars{
384 SBytes: []byte("hello world"),
385 },
386 }, {
387 desc: "not bytes",
388 inputMessage: &pb3.Scalars{},
389 inputText: `{"sBytes": true}`,
Herbie Ongd2ece132020-01-07 16:45:24 -0800390 wantErr: `invalid value for bytes type: true`,
Herbie Ongc96a79d2019-03-08 10:49:17 -0800391 }, {
392 desc: "proto2 enum",
393 inputMessage: &pb2.Enums{},
394 inputText: `{
395 "optEnum": "ONE",
396 "optNestedEnum": "UNO"
397}`,
398 wantMessage: &pb2.Enums{
399 OptEnum: pb2.Enum_ONE.Enum(),
400 OptNestedEnum: pb2.Enums_UNO.Enum(),
401 },
402 }, {
403 desc: "proto3 enum",
404 inputMessage: &pb3.Enums{},
405 inputText: `{
406 "sEnum": "ONE",
407 "sNestedEnum": "DIEZ"
408}`,
409 wantMessage: &pb3.Enums{
410 SEnum: pb3.Enum_ONE,
411 SNestedEnum: pb3.Enums_DIEZ,
412 },
413 }, {
414 desc: "enum numeric value",
415 inputMessage: &pb3.Enums{},
416 inputText: `{
417 "sEnum": 2,
418 "sNestedEnum": 2
419}`,
420 wantMessage: &pb3.Enums{
421 SEnum: pb3.Enum_TWO,
422 SNestedEnum: pb3.Enums_DOS,
423 },
424 }, {
425 desc: "enum unnamed numeric value",
426 inputMessage: &pb3.Enums{},
427 inputText: `{
428 "sEnum": 101,
429 "sNestedEnum": -101
430}`,
431 wantMessage: &pb3.Enums{
432 SEnum: 101,
433 SNestedEnum: -101,
434 },
435 }, {
436 desc: "enum set to number string",
437 inputMessage: &pb3.Enums{},
438 inputText: `{
Herbie Ong300b9fe2019-03-29 15:42:20 -0700439 "sEnum": "1"
Herbie Ongc96a79d2019-03-08 10:49:17 -0800440}`,
Herbie Ongd2ece132020-01-07 16:45:24 -0800441 wantErr: `invalid value for enum type: "1"`,
Herbie Ongc96a79d2019-03-08 10:49:17 -0800442 }, {
443 desc: "enum set to invalid named",
444 inputMessage: &pb3.Enums{},
445 inputText: `{
Herbie Ong300b9fe2019-03-29 15:42:20 -0700446 "sEnum": "UNNAMED"
Herbie Ongc96a79d2019-03-08 10:49:17 -0800447}`,
Herbie Ongd2ece132020-01-07 16:45:24 -0800448 wantErr: `invalid value for enum type: "UNNAMED"`,
Herbie Ongc96a79d2019-03-08 10:49:17 -0800449 }, {
450 desc: "enum set to not enum",
451 inputMessage: &pb3.Enums{},
452 inputText: `{
Herbie Ong300b9fe2019-03-29 15:42:20 -0700453 "sEnum": true
Herbie Ongc96a79d2019-03-08 10:49:17 -0800454}`,
Herbie Ongd2ece132020-01-07 16:45:24 -0800455 wantErr: `invalid value for enum type: true`,
Herbie Ongc96a79d2019-03-08 10:49:17 -0800456 }, {
Herbie Ong300b9fe2019-03-29 15:42:20 -0700457 desc: "enum set to JSON null",
458 inputMessage: &pb3.Enums{},
459 inputText: `{
460 "sEnum": null
461}`,
462 wantMessage: &pb3.Enums{},
463 }, {
Herbie Ongc96a79d2019-03-08 10:49:17 -0800464 desc: "proto name",
465 inputMessage: &pb3.JSONNames{},
466 inputText: `{
467 "s_string": "proto name used"
468}`,
469 wantMessage: &pb3.JSONNames{
470 SString: "proto name used",
471 },
472 }, {
Joe Tsai7fa1ee52019-09-15 00:32:55 -0700473 desc: "proto group name",
474 inputMessage: &pb2.Nests{},
475 inputText: `{
476 "OptGroup": {"optString": "hello"},
477 "RptGroup": [{"rptString": ["goodbye"]}]
478 }`,
479 wantMessage: &pb2.Nests{
480 Optgroup: &pb2.Nests_OptGroup{OptString: proto.String("hello")},
481 Rptgroup: []*pb2.Nests_RptGroup{{RptString: []string{"goodbye"}}},
482 },
483 }, {
Herbie Ongc96a79d2019-03-08 10:49:17 -0800484 desc: "json_name",
485 inputMessage: &pb3.JSONNames{},
486 inputText: `{
487 "foo_bar": "json_name used"
488}`,
489 wantMessage: &pb3.JSONNames{
490 SString: "json_name used",
491 },
492 }, {
493 desc: "camelCase name",
494 inputMessage: &pb3.JSONNames{},
495 inputText: `{
496 "sString": "camelcase used"
497}`,
Herbie Ongd2ece132020-01-07 16:45:24 -0800498 wantErr: `unknown field "sString"`,
Herbie Ongc96a79d2019-03-08 10:49:17 -0800499 }, {
500 desc: "proto name and json_name",
501 inputMessage: &pb3.JSONNames{},
502 inputText: `{
503 "foo_bar": "json_name used",
504 "s_string": "proto name used"
505}`,
Herbie Ongd2ece132020-01-07 16:45:24 -0800506 wantErr: `(line 3:3): duplicate field "s_string"`,
Herbie Ongc96a79d2019-03-08 10:49:17 -0800507 }, {
508 desc: "duplicate field names",
509 inputMessage: &pb3.JSONNames{},
510 inputText: `{
511 "foo_bar": "one",
512 "foo_bar": "two",
513}`,
Herbie Ongd2ece132020-01-07 16:45:24 -0800514 wantErr: `(line 3:3): duplicate field "foo_bar"`,
Herbie Ongc96a79d2019-03-08 10:49:17 -0800515 }, {
516 desc: "null message",
517 inputMessage: &pb2.Nests{},
518 inputText: "null",
Herbie Ongd2ece132020-01-07 16:45:24 -0800519 wantErr: `unexpected token null`,
Herbie Ongc96a79d2019-03-08 10:49:17 -0800520 }, {
521 desc: "proto2 nested message not set",
522 inputMessage: &pb2.Nests{},
523 inputText: "{}",
524 wantMessage: &pb2.Nests{},
525 }, {
526 desc: "proto2 nested message set to null",
527 inputMessage: &pb2.Nests{},
528 inputText: `{
529 "optNested": null,
530 "optgroup": null
531}`,
532 wantMessage: &pb2.Nests{},
533 }, {
534 desc: "proto2 nested message set to empty",
535 inputMessage: &pb2.Nests{},
536 inputText: `{
537 "optNested": {},
538 "optgroup": {}
539}`,
540 wantMessage: &pb2.Nests{
541 OptNested: &pb2.Nested{},
542 Optgroup: &pb2.Nests_OptGroup{},
543 },
544 }, {
545 desc: "proto2 nested messages",
546 inputMessage: &pb2.Nests{},
547 inputText: `{
548 "optNested": {
549 "optString": "nested message",
550 "optNested": {
551 "optString": "another nested message"
552 }
553 }
554}`,
555 wantMessage: &pb2.Nests{
556 OptNested: &pb2.Nested{
Damien Neila8a2cea2019-07-10 16:17:16 -0700557 OptString: proto.String("nested message"),
Herbie Ongc96a79d2019-03-08 10:49:17 -0800558 OptNested: &pb2.Nested{
Damien Neila8a2cea2019-07-10 16:17:16 -0700559 OptString: proto.String("another nested message"),
Herbie Ongc96a79d2019-03-08 10:49:17 -0800560 },
561 },
562 },
563 }, {
564 desc: "proto2 groups",
565 inputMessage: &pb2.Nests{},
566 inputText: `{
567 "optgroup": {
568 "optString": "inside a group",
569 "optNested": {
570 "optString": "nested message inside a group"
571 },
572 "optnestedgroup": {
573 "optFixed32": 47
574 }
575 }
576}`,
577 wantMessage: &pb2.Nests{
578 Optgroup: &pb2.Nests_OptGroup{
Damien Neila8a2cea2019-07-10 16:17:16 -0700579 OptString: proto.String("inside a group"),
Herbie Ongc96a79d2019-03-08 10:49:17 -0800580 OptNested: &pb2.Nested{
Damien Neila8a2cea2019-07-10 16:17:16 -0700581 OptString: proto.String("nested message inside a group"),
Herbie Ongc96a79d2019-03-08 10:49:17 -0800582 },
583 Optnestedgroup: &pb2.Nests_OptGroup_OptNestedGroup{
Damien Neila8a2cea2019-07-10 16:17:16 -0700584 OptFixed32: proto.Uint32(47),
Herbie Ongc96a79d2019-03-08 10:49:17 -0800585 },
586 },
587 },
588 }, {
589 desc: "proto3 nested message not set",
590 inputMessage: &pb3.Nests{},
591 inputText: "{}",
592 wantMessage: &pb3.Nests{},
593 }, {
594 desc: "proto3 nested message set to null",
595 inputMessage: &pb3.Nests{},
596 inputText: `{"sNested": null}`,
597 wantMessage: &pb3.Nests{},
598 }, {
599 desc: "proto3 nested message set to empty",
600 inputMessage: &pb3.Nests{},
601 inputText: `{"sNested": {}}`,
602 wantMessage: &pb3.Nests{
603 SNested: &pb3.Nested{},
604 },
605 }, {
606 desc: "proto3 nested message",
607 inputMessage: &pb3.Nests{},
608 inputText: `{
609 "sNested": {
610 "sString": "nested message",
611 "sNested": {
612 "sString": "another nested message"
613 }
614 }
615}`,
616 wantMessage: &pb3.Nests{
617 SNested: &pb3.Nested{
618 SString: "nested message",
619 SNested: &pb3.Nested{
620 SString: "another nested message",
621 },
622 },
623 },
624 }, {
625 desc: "message set to non-message",
626 inputMessage: &pb3.Nests{},
627 inputText: `"not valid"`,
Herbie Ongd2ece132020-01-07 16:45:24 -0800628 wantErr: `unexpected token "not valid"`,
Herbie Ongc96a79d2019-03-08 10:49:17 -0800629 }, {
630 desc: "nested message set to non-message",
631 inputMessage: &pb3.Nests{},
632 inputText: `{"sNested": true}`,
Herbie Ongd2ece132020-01-07 16:45:24 -0800633 wantErr: `(line 1:13): unexpected token true`,
Herbie Ongc96a79d2019-03-08 10:49:17 -0800634 }, {
635 desc: "oneof not set",
636 inputMessage: &pb3.Oneofs{},
637 inputText: "{}",
638 wantMessage: &pb3.Oneofs{},
639 }, {
640 desc: "oneof set to empty string",
641 inputMessage: &pb3.Oneofs{},
642 inputText: `{"oneofString": ""}`,
643 wantMessage: &pb3.Oneofs{
644 Union: &pb3.Oneofs_OneofString{},
645 },
646 }, {
647 desc: "oneof set to string",
648 inputMessage: &pb3.Oneofs{},
649 inputText: `{"oneofString": "hello"}`,
650 wantMessage: &pb3.Oneofs{
651 Union: &pb3.Oneofs_OneofString{
652 OneofString: "hello",
653 },
654 },
655 }, {
656 desc: "oneof set to enum",
657 inputMessage: &pb3.Oneofs{},
658 inputText: `{"oneofEnum": "ZERO"}`,
659 wantMessage: &pb3.Oneofs{
660 Union: &pb3.Oneofs_OneofEnum{
661 OneofEnum: pb3.Enum_ZERO,
662 },
663 },
664 }, {
665 desc: "oneof set to empty message",
666 inputMessage: &pb3.Oneofs{},
667 inputText: `{"oneofNested": {}}`,
668 wantMessage: &pb3.Oneofs{
669 Union: &pb3.Oneofs_OneofNested{
670 OneofNested: &pb3.Nested{},
671 },
672 },
673 }, {
674 desc: "oneof set to message",
675 inputMessage: &pb3.Oneofs{},
676 inputText: `{
677 "oneofNested": {
678 "sString": "nested message"
679 }
680}`,
681 wantMessage: &pb3.Oneofs{
682 Union: &pb3.Oneofs_OneofNested{
683 OneofNested: &pb3.Nested{
684 SString: "nested message",
685 },
686 },
687 },
688 }, {
Herbie Ong8a1d4602019-04-02 20:19:36 -0700689 desc: "oneof set to more than one field",
690 inputMessage: &pb3.Oneofs{},
691 inputText: `{
692 "oneofEnum": "ZERO",
693 "oneofString": "hello"
694}`,
Herbie Ongd2ece132020-01-07 16:45:24 -0800695 wantErr: `(line 3:3): error parsing "oneofString", oneof pb3.Oneofs.union is already set`,
Herbie Ong8a1d4602019-04-02 20:19:36 -0700696 }, {
697 desc: "oneof set to null and value",
698 inputMessage: &pb3.Oneofs{},
699 inputText: `{
700 "oneofEnum": "ZERO",
701 "oneofString": null
702}`,
703 wantMessage: &pb3.Oneofs{
704 Union: &pb3.Oneofs_OneofEnum{
705 OneofEnum: pb3.Enum_ZERO,
706 },
707 },
708 }, {
Herbie Ongc96a79d2019-03-08 10:49:17 -0800709 desc: "repeated null fields",
710 inputMessage: &pb2.Repeats{},
711 inputText: `{
712 "rptString": null,
713 "rptInt32" : null,
714 "rptFloat" : null,
715 "rptBytes" : null
716}`,
717 wantMessage: &pb2.Repeats{},
718 }, {
719 desc: "repeated scalars",
720 inputMessage: &pb2.Repeats{},
721 inputText: `{
722 "rptString": ["hello", "world"],
723 "rptInt32" : [-1, 0, 1],
724 "rptBool" : [false, true]
725}`,
726 wantMessage: &pb2.Repeats{
727 RptString: []string{"hello", "world"},
728 RptInt32: []int32{-1, 0, 1},
729 RptBool: []bool{false, true},
730 },
731 }, {
732 desc: "repeated enums",
733 inputMessage: &pb2.Enums{},
734 inputText: `{
735 "rptEnum" : ["TEN", 1, 42],
736 "rptNestedEnum": ["DOS", 2, -47]
737}`,
738 wantMessage: &pb2.Enums{
739 RptEnum: []pb2.Enum{pb2.Enum_TEN, pb2.Enum_ONE, 42},
740 RptNestedEnum: []pb2.Enums_NestedEnum{pb2.Enums_DOS, pb2.Enums_DOS, -47},
741 },
742 }, {
743 desc: "repeated messages",
744 inputMessage: &pb2.Nests{},
745 inputText: `{
746 "rptNested": [
747 {
748 "optString": "repeat nested one"
749 },
750 {
751 "optString": "repeat nested two",
752 "optNested": {
753 "optString": "inside repeat nested two"
754 }
755 },
756 {}
757 ]
758}`,
759 wantMessage: &pb2.Nests{
760 RptNested: []*pb2.Nested{
761 {
Damien Neila8a2cea2019-07-10 16:17:16 -0700762 OptString: proto.String("repeat nested one"),
Herbie Ongc96a79d2019-03-08 10:49:17 -0800763 },
764 {
Damien Neila8a2cea2019-07-10 16:17:16 -0700765 OptString: proto.String("repeat nested two"),
Herbie Ongc96a79d2019-03-08 10:49:17 -0800766 OptNested: &pb2.Nested{
Damien Neila8a2cea2019-07-10 16:17:16 -0700767 OptString: proto.String("inside repeat nested two"),
Herbie Ongc96a79d2019-03-08 10:49:17 -0800768 },
769 },
770 {},
771 },
772 },
773 }, {
774 desc: "repeated groups",
775 inputMessage: &pb2.Nests{},
776 inputText: `{
777 "rptgroup": [
778 {
779 "rptString": ["hello", "world"]
780 },
781 {}
782 ]
783}
784`,
785 wantMessage: &pb2.Nests{
786 Rptgroup: []*pb2.Nests_RptGroup{
787 {
788 RptString: []string{"hello", "world"},
789 },
790 {},
791 },
792 },
793 }, {
Herbie Onge63c4c42019-03-22 22:20:22 -0700794 desc: "repeated string contains invalid UTF8",
795 inputMessage: &pb2.Repeats{},
796 inputText: `{"rptString": ["` + "abc\xff" + `"]}`,
Herbie Ongd2ece132020-01-07 16:45:24 -0800797 wantErr: `invalid UTF-8`,
Herbie Onge63c4c42019-03-22 22:20:22 -0700798 }, {
799 desc: "repeated messages contain invalid UTF8",
800 inputMessage: &pb2.Nests{},
801 inputText: `{"rptNested": [{"optString": "` + "abc\xff" + `"}]}`,
Herbie Ongd2ece132020-01-07 16:45:24 -0800802 wantErr: `invalid UTF-8`,
Herbie Onge63c4c42019-03-22 22:20:22 -0700803 }, {
804 desc: "repeated scalars contain invalid type",
Herbie Ongc96a79d2019-03-08 10:49:17 -0800805 inputMessage: &pb2.Repeats{},
806 inputText: `{"rptString": ["hello", null, "world"]}`,
Herbie Ongd2ece132020-01-07 16:45:24 -0800807 wantErr: `invalid value for string type: null`,
Herbie Ongc96a79d2019-03-08 10:49:17 -0800808 }, {
Herbie Onge63c4c42019-03-22 22:20:22 -0700809 desc: "repeated messages contain invalid type",
Herbie Ongc96a79d2019-03-08 10:49:17 -0800810 inputMessage: &pb2.Nests{},
811 inputText: `{"rptNested": [{}, null]}`,
Herbie Ongd2ece132020-01-07 16:45:24 -0800812 wantErr: `unexpected token null`,
Herbie Ongc96a79d2019-03-08 10:49:17 -0800813 }, {
814 desc: "map fields 1",
815 inputMessage: &pb3.Maps{},
816 inputText: `{
817 "int32ToStr": {
818 "-101": "-101",
819 "0" : "zero",
820 "255" : "0xff"
821 },
822 "boolToUint32": {
823 "false": 101,
824 "true" : "42"
825 }
826}`,
827 wantMessage: &pb3.Maps{
828 Int32ToStr: map[int32]string{
829 -101: "-101",
830 0xff: "0xff",
831 0: "zero",
832 },
833 BoolToUint32: map[bool]uint32{
834 true: 42,
835 false: 101,
836 },
837 },
838 }, {
839 desc: "map fields 2",
840 inputMessage: &pb3.Maps{},
841 inputText: `{
842 "uint64ToEnum": {
843 "1" : "ONE",
844 "2" : 2,
845 "10": 101
846 }
847}`,
848 wantMessage: &pb3.Maps{
849 Uint64ToEnum: map[uint64]pb3.Enum{
850 1: pb3.Enum_ONE,
851 2: pb3.Enum_TWO,
852 10: 101,
853 },
854 },
855 }, {
856 desc: "map fields 3",
857 inputMessage: &pb3.Maps{},
858 inputText: `{
859 "strToNested": {
860 "nested_one": {
861 "sString": "nested in a map"
862 },
863 "nested_two": {}
864 }
865}`,
866 wantMessage: &pb3.Maps{
867 StrToNested: map[string]*pb3.Nested{
868 "nested_one": {
869 SString: "nested in a map",
870 },
871 "nested_two": {},
872 },
873 },
874 }, {
875 desc: "map fields 4",
876 inputMessage: &pb3.Maps{},
877 inputText: `{
878 "strToOneofs": {
879 "nested": {
880 "oneofNested": {
881 "sString": "nested oneof in map field value"
882 }
883 },
884 "string": {
885 "oneofString": "hello"
886 }
887 }
888}`,
889 wantMessage: &pb3.Maps{
890 StrToOneofs: map[string]*pb3.Oneofs{
891 "string": {
892 Union: &pb3.Oneofs_OneofString{
893 OneofString: "hello",
894 },
895 },
896 "nested": {
897 Union: &pb3.Oneofs_OneofNested{
898 OneofNested: &pb3.Nested{
899 SString: "nested oneof in map field value",
900 },
901 },
902 },
903 },
904 },
905 }, {
906 desc: "map contains duplicate keys",
907 inputMessage: &pb3.Maps{},
908 inputText: `{
909 "int32ToStr": {
910 "0": "cero",
Herbie Ongd2ece132020-01-07 16:45:24 -0800911 "0": "zero"
Herbie Ongc96a79d2019-03-08 10:49:17 -0800912 }
913}
914`,
Herbie Ongd2ece132020-01-07 16:45:24 -0800915 wantErr: `(line 4:5): duplicate map key "0"`,
Herbie Ongc96a79d2019-03-08 10:49:17 -0800916 }, {
917 desc: "map key empty string",
918 inputMessage: &pb3.Maps{},
919 inputText: `{
920 "strToNested": {
921 "": {}
922 }
923}`,
924 wantMessage: &pb3.Maps{
925 StrToNested: map[string]*pb3.Nested{
926 "": {},
927 },
928 },
929 }, {
930 desc: "map contains invalid key 1",
931 inputMessage: &pb3.Maps{},
932 inputText: `{
933 "int32ToStr": {
934 "invalid": "cero"
Herbie Ongd2ece132020-01-07 16:45:24 -0800935 }
Herbie Ongc96a79d2019-03-08 10:49:17 -0800936}`,
Herbie Ongd2ece132020-01-07 16:45:24 -0800937 wantErr: `invalid value for int32 key: "invalid"`,
Herbie Ongc96a79d2019-03-08 10:49:17 -0800938 }, {
939 desc: "map contains invalid key 2",
940 inputMessage: &pb3.Maps{},
941 inputText: `{
942 "int32ToStr": {
943 "1.02": "float"
Herbie Ongd2ece132020-01-07 16:45:24 -0800944 }
Herbie Ongc96a79d2019-03-08 10:49:17 -0800945}`,
Herbie Ongd2ece132020-01-07 16:45:24 -0800946 wantErr: `invalid value for int32 key: "1.02"`,
Herbie Ongc96a79d2019-03-08 10:49:17 -0800947 }, {
948 desc: "map contains invalid key 3",
949 inputMessage: &pb3.Maps{},
950 inputText: `{
951 "int32ToStr": {
952 "2147483648": "exceeds 32-bit integer max limit"
Herbie Ongd2ece132020-01-07 16:45:24 -0800953 }
Herbie Ongc96a79d2019-03-08 10:49:17 -0800954}`,
Herbie Ongd2ece132020-01-07 16:45:24 -0800955 wantErr: `invalid value for int32 key: "2147483648"`,
Herbie Ongc96a79d2019-03-08 10:49:17 -0800956 }, {
957 desc: "map contains invalid key 4",
958 inputMessage: &pb3.Maps{},
959 inputText: `{
960 "uint64ToEnum": {
961 "-1": 0
962 }
963}`,
Herbie Ongd2ece132020-01-07 16:45:24 -0800964 wantErr: `invalid value for uint64 key: "-1"`,
Herbie Ongc96a79d2019-03-08 10:49:17 -0800965 }, {
966 desc: "map contains invalid value",
967 inputMessage: &pb3.Maps{},
968 inputText: `{
969 "int32ToStr": {
970 "101": true
971}`,
Herbie Ongd2ece132020-01-07 16:45:24 -0800972 wantErr: `invalid value for string type: true`,
Herbie Ongc96a79d2019-03-08 10:49:17 -0800973 }, {
974 desc: "map contains null for scalar value",
975 inputMessage: &pb3.Maps{},
976 inputText: `{
977 "int32ToStr": {
978 "101": null
979}`,
Herbie Ongd2ece132020-01-07 16:45:24 -0800980 wantErr: `invalid value for string type: null`,
Herbie Ongc96a79d2019-03-08 10:49:17 -0800981 }, {
982 desc: "map contains null for message value",
983 inputMessage: &pb3.Maps{},
984 inputText: `{
985 "strToNested": {
986 "hello": null
987 }
988}`,
Herbie Ongd2ece132020-01-07 16:45:24 -0800989 wantErr: `unexpected token null`,
Herbie Onge52379a2019-03-15 18:00:19 -0700990 }, {
Herbie Onge63c4c42019-03-22 22:20:22 -0700991 desc: "map contains contains message value with invalid UTF8",
992 inputMessage: &pb3.Maps{},
993 inputText: `{
994 "strToNested": {
995 "hello": {
996 "sString": "` + "abc\xff" + `"
997 }
998 }
999}`,
Herbie Ongd2ece132020-01-07 16:45:24 -08001000 wantErr: `invalid UTF-8`,
Herbie Onge63c4c42019-03-22 22:20:22 -07001001 }, {
1002 desc: "map key contains invalid UTF8",
1003 inputMessage: &pb3.Maps{},
1004 inputText: `{
1005 "strToNested": {
1006 "` + "abc\xff" + `": {}
1007 }
1008}`,
Herbie Ongd2ece132020-01-07 16:45:24 -08001009 wantErr: `invalid UTF-8`,
Herbie Onge63c4c42019-03-22 22:20:22 -07001010 }, {
Herbie Ong329be5b2019-03-27 14:47:59 -07001011 desc: "required fields not set",
1012 inputMessage: &pb2.Requireds{},
Herbie Ongd2ece132020-01-07 16:45:24 -08001013 inputText: `{}`,
1014 wantErr: errors.RequiredNotSet("pb2.Requireds.req_bool").Error(),
Herbie Ong329be5b2019-03-27 14:47:59 -07001015 }, {
1016 desc: "required field set",
1017 inputMessage: &pb2.PartialRequired{},
1018 inputText: `{
1019 "reqString": "this is required"
1020}`,
1021 wantMessage: &pb2.PartialRequired{
Damien Neila8a2cea2019-07-10 16:17:16 -07001022 ReqString: proto.String("this is required"),
Herbie Ong329be5b2019-03-27 14:47:59 -07001023 },
1024 }, {
1025 desc: "required fields partially set",
1026 inputMessage: &pb2.Requireds{},
1027 inputText: `{
1028 "reqBool": false,
1029 "reqSfixed64": 42,
1030 "reqString": "hello",
1031 "reqEnum": "ONE"
1032}`,
1033 wantMessage: &pb2.Requireds{
Damien Neila8a2cea2019-07-10 16:17:16 -07001034 ReqBool: proto.Bool(false),
1035 ReqSfixed64: proto.Int64(42),
1036 ReqString: proto.String("hello"),
Herbie Ong329be5b2019-03-27 14:47:59 -07001037 ReqEnum: pb2.Enum_ONE.Enum(),
1038 },
Herbie Ongd2ece132020-01-07 16:45:24 -08001039 wantErr: errors.RequiredNotSet("pb2.Requireds.req_double").Error(),
Herbie Ong329be5b2019-03-27 14:47:59 -07001040 }, {
1041 desc: "required fields partially set with AllowPartial",
Damien Neil5c5b5312019-05-14 12:44:37 -07001042 umo: protojson.UnmarshalOptions{AllowPartial: true},
Herbie Ong329be5b2019-03-27 14:47:59 -07001043 inputMessage: &pb2.Requireds{},
1044 inputText: `{
1045 "reqBool": false,
1046 "reqSfixed64": 42,
1047 "reqString": "hello",
1048 "reqEnum": "ONE"
1049}`,
1050 wantMessage: &pb2.Requireds{
Damien Neila8a2cea2019-07-10 16:17:16 -07001051 ReqBool: proto.Bool(false),
1052 ReqSfixed64: proto.Int64(42),
1053 ReqString: proto.String("hello"),
Herbie Ong329be5b2019-03-27 14:47:59 -07001054 ReqEnum: pb2.Enum_ONE.Enum(),
1055 },
1056 }, {
1057 desc: "required fields all set",
1058 inputMessage: &pb2.Requireds{},
1059 inputText: `{
1060 "reqBool": false,
1061 "reqSfixed64": 42,
1062 "reqDouble": 1.23,
1063 "reqString": "hello",
1064 "reqEnum": "ONE",
1065 "reqNested": {}
1066}`,
1067 wantMessage: &pb2.Requireds{
Damien Neila8a2cea2019-07-10 16:17:16 -07001068 ReqBool: proto.Bool(false),
1069 ReqSfixed64: proto.Int64(42),
1070 ReqDouble: proto.Float64(1.23),
1071 ReqString: proto.String("hello"),
Herbie Ong329be5b2019-03-27 14:47:59 -07001072 ReqEnum: pb2.Enum_ONE.Enum(),
1073 ReqNested: &pb2.Nested{},
1074 },
1075 }, {
1076 desc: "indirect required field",
1077 inputMessage: &pb2.IndirectRequired{},
1078 inputText: `{
1079 "optNested": {}
1080}`,
1081 wantMessage: &pb2.IndirectRequired{
1082 OptNested: &pb2.NestedWithRequired{},
1083 },
Herbie Ongd2ece132020-01-07 16:45:24 -08001084 wantErr: errors.RequiredNotSet("pb2.NestedWithRequired.req_string").Error(),
Herbie Ong329be5b2019-03-27 14:47:59 -07001085 }, {
1086 desc: "indirect required field with AllowPartial",
Damien Neil5c5b5312019-05-14 12:44:37 -07001087 umo: protojson.UnmarshalOptions{AllowPartial: true},
Herbie Ong329be5b2019-03-27 14:47:59 -07001088 inputMessage: &pb2.IndirectRequired{},
1089 inputText: `{
1090 "optNested": {}
1091}`,
1092 wantMessage: &pb2.IndirectRequired{
1093 OptNested: &pb2.NestedWithRequired{},
1094 },
1095 }, {
1096 desc: "indirect required field in repeated",
1097 inputMessage: &pb2.IndirectRequired{},
1098 inputText: `{
1099 "rptNested": [
1100 {"reqString": "one"},
1101 {}
1102 ]
1103}`,
1104 wantMessage: &pb2.IndirectRequired{
1105 RptNested: []*pb2.NestedWithRequired{
1106 {
Damien Neila8a2cea2019-07-10 16:17:16 -07001107 ReqString: proto.String("one"),
Herbie Ong329be5b2019-03-27 14:47:59 -07001108 },
1109 {},
1110 },
1111 },
Herbie Ongd2ece132020-01-07 16:45:24 -08001112 wantErr: errors.RequiredNotSet("pb2.NestedWithRequired.req_string").Error(),
Herbie Ong329be5b2019-03-27 14:47:59 -07001113 }, {
1114 desc: "indirect required field in repeated with AllowPartial",
Damien Neil5c5b5312019-05-14 12:44:37 -07001115 umo: protojson.UnmarshalOptions{AllowPartial: true},
Herbie Ong329be5b2019-03-27 14:47:59 -07001116 inputMessage: &pb2.IndirectRequired{},
1117 inputText: `{
1118 "rptNested": [
1119 {"reqString": "one"},
1120 {}
1121 ]
1122}`,
1123 wantMessage: &pb2.IndirectRequired{
1124 RptNested: []*pb2.NestedWithRequired{
1125 {
Damien Neila8a2cea2019-07-10 16:17:16 -07001126 ReqString: proto.String("one"),
Herbie Ong329be5b2019-03-27 14:47:59 -07001127 },
1128 {},
1129 },
1130 },
1131 }, {
1132 desc: "indirect required field in map",
1133 inputMessage: &pb2.IndirectRequired{},
1134 inputText: `{
1135 "strToNested": {
1136 "missing": {},
1137 "contains": {
1138 "reqString": "here"
1139 }
1140 }
1141}`,
1142 wantMessage: &pb2.IndirectRequired{
1143 StrToNested: map[string]*pb2.NestedWithRequired{
1144 "missing": &pb2.NestedWithRequired{},
1145 "contains": &pb2.NestedWithRequired{
Damien Neila8a2cea2019-07-10 16:17:16 -07001146 ReqString: proto.String("here"),
Herbie Ong329be5b2019-03-27 14:47:59 -07001147 },
1148 },
1149 },
Herbie Ongd2ece132020-01-07 16:45:24 -08001150 wantErr: errors.RequiredNotSet("pb2.NestedWithRequired.req_string").Error(),
Herbie Ong329be5b2019-03-27 14:47:59 -07001151 }, {
1152 desc: "indirect required field in map with AllowPartial",
Damien Neil5c5b5312019-05-14 12:44:37 -07001153 umo: protojson.UnmarshalOptions{AllowPartial: true},
Herbie Ong329be5b2019-03-27 14:47:59 -07001154 inputMessage: &pb2.IndirectRequired{},
1155 inputText: `{
1156 "strToNested": {
1157 "missing": {},
1158 "contains": {
1159 "reqString": "here"
1160 }
1161 }
1162}`,
1163 wantMessage: &pb2.IndirectRequired{
1164 StrToNested: map[string]*pb2.NestedWithRequired{
1165 "missing": &pb2.NestedWithRequired{},
1166 "contains": &pb2.NestedWithRequired{
Damien Neila8a2cea2019-07-10 16:17:16 -07001167 ReqString: proto.String("here"),
Herbie Ong329be5b2019-03-27 14:47:59 -07001168 },
1169 },
1170 },
1171 }, {
1172 desc: "indirect required field in oneof",
1173 inputMessage: &pb2.IndirectRequired{},
1174 inputText: `{
1175 "oneofNested": {}
1176}`,
1177 wantMessage: &pb2.IndirectRequired{
1178 Union: &pb2.IndirectRequired_OneofNested{
1179 OneofNested: &pb2.NestedWithRequired{},
1180 },
1181 },
Herbie Ongd2ece132020-01-07 16:45:24 -08001182 wantErr: errors.RequiredNotSet("pb2.NestedWithRequired.req_string").Error(),
Herbie Ong329be5b2019-03-27 14:47:59 -07001183 }, {
1184 desc: "indirect required field in oneof with AllowPartial",
Damien Neil5c5b5312019-05-14 12:44:37 -07001185 umo: protojson.UnmarshalOptions{AllowPartial: true},
Herbie Ong329be5b2019-03-27 14:47:59 -07001186 inputMessage: &pb2.IndirectRequired{},
1187 inputText: `{
1188 "oneofNested": {}
1189}`,
1190 wantMessage: &pb2.IndirectRequired{
1191 Union: &pb2.IndirectRequired_OneofNested{
1192 OneofNested: &pb2.NestedWithRequired{},
1193 },
1194 },
1195 }, {
Herbie Onge52379a2019-03-15 18:00:19 -07001196 desc: "extensions of non-repeated fields",
1197 inputMessage: &pb2.Extensions{},
1198 inputText: `{
1199 "optString": "non-extension field",
1200 "optBool": true,
1201 "optInt32": 42,
1202 "[pb2.opt_ext_bool]": true,
1203 "[pb2.opt_ext_nested]": {
1204 "optString": "nested in an extension",
Herbie Onge63c4c42019-03-22 22:20:22 -07001205 "optNested": {
1206 "optString": "another nested in an extension"
Herbie Onge52379a2019-03-15 18:00:19 -07001207 }
1208 },
1209 "[pb2.opt_ext_string]": "extension field",
1210 "[pb2.opt_ext_enum]": "TEN"
1211}`,
1212 wantMessage: func() proto.Message {
1213 m := &pb2.Extensions{
Damien Neila8a2cea2019-07-10 16:17:16 -07001214 OptString: proto.String("non-extension field"),
1215 OptBool: proto.Bool(true),
1216 OptInt32: proto.Int32(42),
Herbie Onge52379a2019-03-15 18:00:19 -07001217 }
Damien Neil92f76182019-08-02 16:58:08 -07001218 proto.SetExtension(m, pb2.E_OptExtBool, true)
1219 proto.SetExtension(m, pb2.E_OptExtString, "extension field")
1220 proto.SetExtension(m, pb2.E_OptExtEnum, pb2.Enum_TEN)
1221 proto.SetExtension(m, pb2.E_OptExtNested, &pb2.Nested{
Damien Neila8a2cea2019-07-10 16:17:16 -07001222 OptString: proto.String("nested in an extension"),
Herbie Onge52379a2019-03-15 18:00:19 -07001223 OptNested: &pb2.Nested{
Damien Neila8a2cea2019-07-10 16:17:16 -07001224 OptString: proto.String("another nested in an extension"),
Herbie Onge52379a2019-03-15 18:00:19 -07001225 },
1226 })
1227 return m
1228 }(),
1229 }, {
1230 desc: "extensions of repeated fields",
1231 inputMessage: &pb2.Extensions{},
1232 inputText: `{
1233 "[pb2.rpt_ext_enum]": ["TEN", 101, "ONE"],
1234 "[pb2.rpt_ext_fixed32]": [42, 47],
1235 "[pb2.rpt_ext_nested]": [
1236 {"optString": "one"},
1237 {"optString": "two"},
1238 {"optString": "three"}
1239 ]
1240}`,
1241 wantMessage: func() proto.Message {
1242 m := &pb2.Extensions{}
Damien Neil293dc762019-08-29 11:42:57 -07001243 proto.SetExtension(m, pb2.E_RptExtEnum, []pb2.Enum{pb2.Enum_TEN, 101, pb2.Enum_ONE})
1244 proto.SetExtension(m, pb2.E_RptExtFixed32, []uint32{42, 47})
1245 proto.SetExtension(m, pb2.E_RptExtNested, []*pb2.Nested{
Damien Neila8a2cea2019-07-10 16:17:16 -07001246 &pb2.Nested{OptString: proto.String("one")},
1247 &pb2.Nested{OptString: proto.String("two")},
1248 &pb2.Nested{OptString: proto.String("three")},
Herbie Onge52379a2019-03-15 18:00:19 -07001249 })
1250 return m
1251 }(),
1252 }, {
1253 desc: "extensions of non-repeated fields in another message",
1254 inputMessage: &pb2.Extensions{},
1255 inputText: `{
1256 "[pb2.ExtensionsContainer.opt_ext_bool]": true,
1257 "[pb2.ExtensionsContainer.opt_ext_enum]": "TEN",
1258 "[pb2.ExtensionsContainer.opt_ext_nested]": {
1259 "optString": "nested in an extension",
1260 "optNested": {
1261 "optString": "another nested in an extension"
1262 }
1263 },
1264 "[pb2.ExtensionsContainer.opt_ext_string]": "extension field"
1265}`,
1266 wantMessage: func() proto.Message {
1267 m := &pb2.Extensions{}
Damien Neil92f76182019-08-02 16:58:08 -07001268 proto.SetExtension(m, pb2.E_ExtensionsContainer_OptExtBool, true)
1269 proto.SetExtension(m, pb2.E_ExtensionsContainer_OptExtString, "extension field")
1270 proto.SetExtension(m, pb2.E_ExtensionsContainer_OptExtEnum, pb2.Enum_TEN)
1271 proto.SetExtension(m, pb2.E_ExtensionsContainer_OptExtNested, &pb2.Nested{
Damien Neila8a2cea2019-07-10 16:17:16 -07001272 OptString: proto.String("nested in an extension"),
Herbie Onge52379a2019-03-15 18:00:19 -07001273 OptNested: &pb2.Nested{
Damien Neila8a2cea2019-07-10 16:17:16 -07001274 OptString: proto.String("another nested in an extension"),
Herbie Onge52379a2019-03-15 18:00:19 -07001275 },
1276 })
1277 return m
1278 }(),
1279 }, {
1280 desc: "extensions of repeated fields in another message",
1281 inputMessage: &pb2.Extensions{},
1282 inputText: `{
1283 "optString": "non-extension field",
1284 "optBool": true,
1285 "optInt32": 42,
1286 "[pb2.ExtensionsContainer.rpt_ext_nested]": [
1287 {"optString": "one"},
1288 {"optString": "two"},
1289 {"optString": "three"}
1290 ],
1291 "[pb2.ExtensionsContainer.rpt_ext_enum]": ["TEN", 101, "ONE"],
1292 "[pb2.ExtensionsContainer.rpt_ext_string]": ["hello", "world"]
1293}`,
1294 wantMessage: func() proto.Message {
1295 m := &pb2.Extensions{
Damien Neila8a2cea2019-07-10 16:17:16 -07001296 OptString: proto.String("non-extension field"),
1297 OptBool: proto.Bool(true),
1298 OptInt32: proto.Int32(42),
Herbie Onge52379a2019-03-15 18:00:19 -07001299 }
Damien Neil293dc762019-08-29 11:42:57 -07001300 proto.SetExtension(m, pb2.E_ExtensionsContainer_RptExtEnum, []pb2.Enum{pb2.Enum_TEN, 101, pb2.Enum_ONE})
1301 proto.SetExtension(m, pb2.E_ExtensionsContainer_RptExtString, []string{"hello", "world"})
1302 proto.SetExtension(m, pb2.E_ExtensionsContainer_RptExtNested, []*pb2.Nested{
Damien Neila8a2cea2019-07-10 16:17:16 -07001303 &pb2.Nested{OptString: proto.String("one")},
1304 &pb2.Nested{OptString: proto.String("two")},
1305 &pb2.Nested{OptString: proto.String("three")},
Herbie Onge52379a2019-03-15 18:00:19 -07001306 })
1307 return m
1308 }(),
1309 }, {
1310 desc: "invalid extension field name",
1311 inputMessage: &pb2.Extensions{},
1312 inputText: `{ "[pb2.invalid_message_field]": true }`,
Herbie Ongd2ece132020-01-07 16:45:24 -08001313 wantErr: `(line 1:3): unknown field "[pb2.invalid_message_field]"`,
Herbie Onge52379a2019-03-15 18:00:19 -07001314 }, {
Joe Tsai5ae10aa2019-07-11 18:23:08 -07001315 desc: "extensions of repeated field contains null",
1316 inputMessage: &pb2.Extensions{},
1317 inputText: `{
1318 "[pb2.ExtensionsContainer.rpt_ext_nested]": [
1319 {"optString": "one"},
Herbie Ongd2ece132020-01-07 16:45:24 -08001320 null,
Joe Tsai5ae10aa2019-07-11 18:23:08 -07001321 {"optString": "three"}
1322 ],
1323}`,
Herbie Ongd2ece132020-01-07 16:45:24 -08001324 wantErr: `(line 4:5): unexpected token null`,
Joe Tsai5ae10aa2019-07-11 18:23:08 -07001325 }, {
Herbie Onge52379a2019-03-15 18:00:19 -07001326 desc: "MessageSet",
1327 inputMessage: &pb2.MessageSet{},
1328 inputText: `{
1329 "[pb2.MessageSetExtension]": {
1330 "optString": "a messageset extension"
1331 },
1332 "[pb2.MessageSetExtension.ext_nested]": {
1333 "optString": "just a regular extension"
1334 },
1335 "[pb2.MessageSetExtension.not_message_set_extension]": {
1336 "optString": "not a messageset extension"
1337 }
1338}`,
1339 wantMessage: func() proto.Message {
1340 m := &pb2.MessageSet{}
Damien Neil92f76182019-08-02 16:58:08 -07001341 proto.SetExtension(m, pb2.E_MessageSetExtension_MessageSetExtension, &pb2.MessageSetExtension{
Damien Neila8a2cea2019-07-10 16:17:16 -07001342 OptString: proto.String("a messageset extension"),
Herbie Onge52379a2019-03-15 18:00:19 -07001343 })
Damien Neil92f76182019-08-02 16:58:08 -07001344 proto.SetExtension(m, pb2.E_MessageSetExtension_NotMessageSetExtension, &pb2.MessageSetExtension{
Damien Neila8a2cea2019-07-10 16:17:16 -07001345 OptString: proto.String("not a messageset extension"),
Herbie Onge52379a2019-03-15 18:00:19 -07001346 })
Damien Neil92f76182019-08-02 16:58:08 -07001347 proto.SetExtension(m, pb2.E_MessageSetExtension_ExtNested, &pb2.Nested{
Damien Neila8a2cea2019-07-10 16:17:16 -07001348 OptString: proto.String("just a regular extension"),
Herbie Onge52379a2019-03-15 18:00:19 -07001349 })
1350 return m
1351 }(),
Joe Tsai1799d112019-08-08 13:31:59 -07001352 skip: !flags.ProtoLegacy,
Herbie Onge52379a2019-03-15 18:00:19 -07001353 }, {
1354 desc: "not real MessageSet 1",
1355 inputMessage: &pb2.FakeMessageSet{},
1356 inputText: `{
1357 "[pb2.FakeMessageSetExtension.message_set_extension]": {
1358 "optString": "not a messageset extension"
1359 }
1360}`,
1361 wantMessage: func() proto.Message {
1362 m := &pb2.FakeMessageSet{}
Damien Neil92f76182019-08-02 16:58:08 -07001363 proto.SetExtension(m, pb2.E_FakeMessageSetExtension_MessageSetExtension, &pb2.FakeMessageSetExtension{
Damien Neila8a2cea2019-07-10 16:17:16 -07001364 OptString: proto.String("not a messageset extension"),
Herbie Onge52379a2019-03-15 18:00:19 -07001365 })
1366 return m
1367 }(),
Joe Tsai1799d112019-08-08 13:31:59 -07001368 skip: !flags.ProtoLegacy,
Herbie Onge52379a2019-03-15 18:00:19 -07001369 }, {
1370 desc: "not real MessageSet 2",
1371 inputMessage: &pb2.FakeMessageSet{},
1372 inputText: `{
1373 "[pb2.FakeMessageSetExtension]": {
1374 "optString": "not a messageset extension"
1375 }
1376}`,
Herbie Ongd2ece132020-01-07 16:45:24 -08001377 wantErr: `unknown field "[pb2.FakeMessageSetExtension]"`,
Joe Tsai1799d112019-08-08 13:31:59 -07001378 skip: !flags.ProtoLegacy,
Herbie Onge52379a2019-03-15 18:00:19 -07001379 }, {
1380 desc: "not real MessageSet 3",
1381 inputMessage: &pb2.MessageSet{},
1382 inputText: `{
1383 "[pb2.message_set_extension]": {
1384 "optString": "another not a messageset extension"
1385 }
1386}`,
1387 wantMessage: func() proto.Message {
1388 m := &pb2.MessageSet{}
Damien Neil92f76182019-08-02 16:58:08 -07001389 proto.SetExtension(m, pb2.E_MessageSetExtension, &pb2.FakeMessageSetExtension{
Damien Neila8a2cea2019-07-10 16:17:16 -07001390 OptString: proto.String("another not a messageset extension"),
Herbie Onge52379a2019-03-15 18:00:19 -07001391 })
1392 return m
1393 }(),
Joe Tsai1799d112019-08-08 13:31:59 -07001394 skip: !flags.ProtoLegacy,
Herbie Onge63c4c42019-03-22 22:20:22 -07001395 }, {
1396 desc: "Empty",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001397 inputMessage: &emptypb.Empty{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001398 inputText: `{}`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001399 wantMessage: &emptypb.Empty{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001400 }, {
1401 desc: "Empty contains unknown",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001402 inputMessage: &emptypb.Empty{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001403 inputText: `{"unknown": null}`,
Herbie Ongd2ece132020-01-07 16:45:24 -08001404 wantErr: `unknown field "unknown"`,
Herbie Onge63c4c42019-03-22 22:20:22 -07001405 }, {
1406 desc: "BoolValue false",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001407 inputMessage: &wrapperspb.BoolValue{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001408 inputText: `false`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001409 wantMessage: &wrapperspb.BoolValue{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001410 }, {
1411 desc: "BoolValue true",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001412 inputMessage: &wrapperspb.BoolValue{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001413 inputText: `true`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001414 wantMessage: &wrapperspb.BoolValue{Value: true},
Herbie Onge63c4c42019-03-22 22:20:22 -07001415 }, {
1416 desc: "BoolValue invalid value",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001417 inputMessage: &wrapperspb.BoolValue{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001418 inputText: `{}`,
Herbie Ongd2ece132020-01-07 16:45:24 -08001419 wantErr: `invalid value for bool type: {`,
Herbie Onge63c4c42019-03-22 22:20:22 -07001420 }, {
1421 desc: "Int32Value",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001422 inputMessage: &wrapperspb.Int32Value{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001423 inputText: `42`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001424 wantMessage: &wrapperspb.Int32Value{Value: 42},
Herbie Onge63c4c42019-03-22 22:20:22 -07001425 }, {
1426 desc: "Int32Value in JSON string",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001427 inputMessage: &wrapperspb.Int32Value{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001428 inputText: `"1.23e3"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001429 wantMessage: &wrapperspb.Int32Value{Value: 1230},
Herbie Onge63c4c42019-03-22 22:20:22 -07001430 }, {
1431 desc: "Int64Value",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001432 inputMessage: &wrapperspb.Int64Value{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001433 inputText: `"42"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001434 wantMessage: &wrapperspb.Int64Value{Value: 42},
Herbie Onge63c4c42019-03-22 22:20:22 -07001435 }, {
1436 desc: "UInt32Value",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001437 inputMessage: &wrapperspb.UInt32Value{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001438 inputText: `42`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001439 wantMessage: &wrapperspb.UInt32Value{Value: 42},
Herbie Onge63c4c42019-03-22 22:20:22 -07001440 }, {
1441 desc: "UInt64Value",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001442 inputMessage: &wrapperspb.UInt64Value{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001443 inputText: `"42"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001444 wantMessage: &wrapperspb.UInt64Value{Value: 42},
Herbie Onge63c4c42019-03-22 22:20:22 -07001445 }, {
1446 desc: "FloatValue",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001447 inputMessage: &wrapperspb.FloatValue{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001448 inputText: `1.02`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001449 wantMessage: &wrapperspb.FloatValue{Value: 1.02},
Herbie Onge63c4c42019-03-22 22:20:22 -07001450 }, {
1451 desc: "FloatValue exceeds max limit",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001452 inputMessage: &wrapperspb.FloatValue{},
Herbie Ongd2ece132020-01-07 16:45:24 -08001453 inputText: `1.23e+40`,
1454 wantErr: `invalid value for float type: 1.23e+40`,
Herbie Onge63c4c42019-03-22 22:20:22 -07001455 }, {
1456 desc: "FloatValue Infinity",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001457 inputMessage: &wrapperspb.FloatValue{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001458 inputText: `"-Infinity"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001459 wantMessage: &wrapperspb.FloatValue{Value: float32(math.Inf(-1))},
Herbie Onge63c4c42019-03-22 22:20:22 -07001460 }, {
1461 desc: "DoubleValue",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001462 inputMessage: &wrapperspb.DoubleValue{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001463 inputText: `1.02`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001464 wantMessage: &wrapperspb.DoubleValue{Value: 1.02},
Herbie Onge63c4c42019-03-22 22:20:22 -07001465 }, {
1466 desc: "DoubleValue Infinity",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001467 inputMessage: &wrapperspb.DoubleValue{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001468 inputText: `"Infinity"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001469 wantMessage: &wrapperspb.DoubleValue{Value: math.Inf(+1)},
Herbie Onge63c4c42019-03-22 22:20:22 -07001470 }, {
1471 desc: "StringValue empty",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001472 inputMessage: &wrapperspb.StringValue{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001473 inputText: `""`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001474 wantMessage: &wrapperspb.StringValue{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001475 }, {
1476 desc: "StringValue",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001477 inputMessage: &wrapperspb.StringValue{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001478 inputText: `"谷歌"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001479 wantMessage: &wrapperspb.StringValue{Value: "谷歌"},
Herbie Onge63c4c42019-03-22 22:20:22 -07001480 }, {
1481 desc: "StringValue with invalid UTF8 error",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001482 inputMessage: &wrapperspb.StringValue{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001483 inputText: "\"abc\xff\"",
Herbie Ongd2ece132020-01-07 16:45:24 -08001484 wantErr: `invalid UTF-8`,
Herbie Onge63c4c42019-03-22 22:20:22 -07001485 }, {
1486 desc: "StringValue field with invalid UTF8 error",
1487 inputMessage: &pb2.KnownTypes{},
1488 inputText: "{\n \"optString\": \"abc\xff\"\n}",
Herbie Ongd2ece132020-01-07 16:45:24 -08001489 wantErr: `invalid UTF-8`,
Herbie Onge63c4c42019-03-22 22:20:22 -07001490 }, {
Herbie Ong300b9fe2019-03-29 15:42:20 -07001491 desc: "NullValue field with JSON null",
1492 inputMessage: &pb2.KnownTypes{},
1493 inputText: `{
1494 "optNull": null
1495}`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001496 wantMessage: &pb2.KnownTypes{OptNull: new(structpb.NullValue)},
Herbie Ong300b9fe2019-03-29 15:42:20 -07001497 }, {
1498 desc: "NullValue field with string",
1499 inputMessage: &pb2.KnownTypes{},
1500 inputText: `{
1501 "optNull": "NULL_VALUE"
1502}`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001503 wantMessage: &pb2.KnownTypes{OptNull: new(structpb.NullValue)},
Herbie Ong300b9fe2019-03-29 15:42:20 -07001504 }, {
Herbie Onge63c4c42019-03-22 22:20:22 -07001505 desc: "BytesValue",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001506 inputMessage: &wrapperspb.BytesValue{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001507 inputText: `"aGVsbG8="`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001508 wantMessage: &wrapperspb.BytesValue{Value: []byte("hello")},
Herbie Onge63c4c42019-03-22 22:20:22 -07001509 }, {
1510 desc: "Value null",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001511 inputMessage: &structpb.Value{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001512 inputText: `null`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001513 wantMessage: &structpb.Value{Kind: &structpb.Value_NullValue{}},
Herbie Onge63c4c42019-03-22 22:20:22 -07001514 }, {
1515 desc: "Value field null",
1516 inputMessage: &pb2.KnownTypes{},
1517 inputText: `{
1518 "optValue": null
1519}`,
1520 wantMessage: &pb2.KnownTypes{
Joe Tsaia95b29f2019-05-16 12:47:20 -07001521 OptValue: &structpb.Value{Kind: &structpb.Value_NullValue{}},
Herbie Onge63c4c42019-03-22 22:20:22 -07001522 },
1523 }, {
1524 desc: "Value bool",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001525 inputMessage: &structpb.Value{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001526 inputText: `false`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001527 wantMessage: &structpb.Value{Kind: &structpb.Value_BoolValue{}},
Herbie Onge63c4c42019-03-22 22:20:22 -07001528 }, {
1529 desc: "Value field bool",
1530 inputMessage: &pb2.KnownTypes{},
1531 inputText: `{
1532 "optValue": true
1533}`,
1534 wantMessage: &pb2.KnownTypes{
Joe Tsaia95b29f2019-05-16 12:47:20 -07001535 OptValue: &structpb.Value{Kind: &structpb.Value_BoolValue{true}},
Herbie Onge63c4c42019-03-22 22:20:22 -07001536 },
1537 }, {
1538 desc: "Value number",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001539 inputMessage: &structpb.Value{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001540 inputText: `1.02`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001541 wantMessage: &structpb.Value{Kind: &structpb.Value_NumberValue{1.02}},
Herbie Onge63c4c42019-03-22 22:20:22 -07001542 }, {
1543 desc: "Value field number",
1544 inputMessage: &pb2.KnownTypes{},
1545 inputText: `{
1546 "optValue": 1.02
1547}`,
1548 wantMessage: &pb2.KnownTypes{
Joe Tsaia95b29f2019-05-16 12:47:20 -07001549 OptValue: &structpb.Value{Kind: &structpb.Value_NumberValue{1.02}},
Herbie Onge63c4c42019-03-22 22:20:22 -07001550 },
1551 }, {
1552 desc: "Value string",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001553 inputMessage: &structpb.Value{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001554 inputText: `"hello"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001555 wantMessage: &structpb.Value{Kind: &structpb.Value_StringValue{"hello"}},
Herbie Onge63c4c42019-03-22 22:20:22 -07001556 }, {
1557 desc: "Value string with invalid UTF8",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001558 inputMessage: &structpb.Value{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001559 inputText: "\"\xff\"",
Herbie Ongd2ece132020-01-07 16:45:24 -08001560 wantErr: `invalid UTF-8`,
Herbie Onge63c4c42019-03-22 22:20:22 -07001561 }, {
1562 desc: "Value field string",
1563 inputMessage: &pb2.KnownTypes{},
1564 inputText: `{
1565 "optValue": "NaN"
1566}`,
1567 wantMessage: &pb2.KnownTypes{
Joe Tsaia95b29f2019-05-16 12:47:20 -07001568 OptValue: &structpb.Value{Kind: &structpb.Value_StringValue{"NaN"}},
Herbie Onge63c4c42019-03-22 22:20:22 -07001569 },
1570 }, {
1571 desc: "Value field string with invalid UTF8",
1572 inputMessage: &pb2.KnownTypes{},
1573 inputText: `{
1574 "optValue": "` + "\xff" + `"
1575}`,
Herbie Ongd2ece132020-01-07 16:45:24 -08001576 wantErr: `invalid UTF-8`,
Herbie Onge63c4c42019-03-22 22:20:22 -07001577 }, {
1578 desc: "Value empty struct",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001579 inputMessage: &structpb.Value{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001580 inputText: `{}`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001581 wantMessage: &structpb.Value{
1582 Kind: &structpb.Value_StructValue{
1583 &structpb.Struct{Fields: map[string]*structpb.Value{}},
Herbie Onge63c4c42019-03-22 22:20:22 -07001584 },
1585 },
1586 }, {
1587 desc: "Value struct",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001588 inputMessage: &structpb.Value{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001589 inputText: `{
1590 "string": "hello",
1591 "number": 123,
1592 "null": null,
1593 "bool": false,
1594 "struct": {
1595 "string": "world"
1596 },
1597 "list": []
1598}`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001599 wantMessage: &structpb.Value{
1600 Kind: &structpb.Value_StructValue{
1601 &structpb.Struct{
1602 Fields: map[string]*structpb.Value{
1603 "string": {Kind: &structpb.Value_StringValue{"hello"}},
1604 "number": {Kind: &structpb.Value_NumberValue{123}},
1605 "null": {Kind: &structpb.Value_NullValue{}},
1606 "bool": {Kind: &structpb.Value_BoolValue{false}},
Herbie Onge63c4c42019-03-22 22:20:22 -07001607 "struct": {
Joe Tsaia95b29f2019-05-16 12:47:20 -07001608 Kind: &structpb.Value_StructValue{
1609 &structpb.Struct{
1610 Fields: map[string]*structpb.Value{
1611 "string": {Kind: &structpb.Value_StringValue{"world"}},
Herbie Onge63c4c42019-03-22 22:20:22 -07001612 },
1613 },
1614 },
1615 },
1616 "list": {
Joe Tsaia95b29f2019-05-16 12:47:20 -07001617 Kind: &structpb.Value_ListValue{&structpb.ListValue{}},
Herbie Onge63c4c42019-03-22 22:20:22 -07001618 },
1619 },
1620 },
1621 },
1622 },
1623 }, {
1624 desc: "Value struct with invalid UTF8 string",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001625 inputMessage: &structpb.Value{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001626 inputText: "{\"string\": \"abc\xff\"}",
Herbie Ongd2ece132020-01-07 16:45:24 -08001627 wantErr: `invalid UTF-8`,
Herbie Onge63c4c42019-03-22 22:20:22 -07001628 }, {
1629 desc: "Value field struct",
1630 inputMessage: &pb2.KnownTypes{},
1631 inputText: `{
1632 "optValue": {
1633 "string": "hello"
1634 }
1635}`,
1636 wantMessage: &pb2.KnownTypes{
Joe Tsaia95b29f2019-05-16 12:47:20 -07001637 OptValue: &structpb.Value{
1638 Kind: &structpb.Value_StructValue{
1639 &structpb.Struct{
1640 Fields: map[string]*structpb.Value{
1641 "string": {Kind: &structpb.Value_StringValue{"hello"}},
Herbie Onge63c4c42019-03-22 22:20:22 -07001642 },
1643 },
1644 },
1645 },
1646 },
1647 }, {
1648 desc: "Value empty list",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001649 inputMessage: &structpb.Value{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001650 inputText: `[]`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001651 wantMessage: &structpb.Value{
1652 Kind: &structpb.Value_ListValue{
1653 &structpb.ListValue{Values: []*structpb.Value{}},
Herbie Onge63c4c42019-03-22 22:20:22 -07001654 },
1655 },
1656 }, {
1657 desc: "Value list",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001658 inputMessage: &structpb.Value{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001659 inputText: `[
1660 "string",
1661 123,
1662 null,
1663 true,
1664 {},
1665 [
1666 "string",
1667 1.23,
1668 null,
1669 false
1670 ]
1671]`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001672 wantMessage: &structpb.Value{
1673 Kind: &structpb.Value_ListValue{
1674 &structpb.ListValue{
1675 Values: []*structpb.Value{
1676 {Kind: &structpb.Value_StringValue{"string"}},
1677 {Kind: &structpb.Value_NumberValue{123}},
1678 {Kind: &structpb.Value_NullValue{}},
1679 {Kind: &structpb.Value_BoolValue{true}},
1680 {Kind: &structpb.Value_StructValue{&structpb.Struct{}}},
Herbie Onge63c4c42019-03-22 22:20:22 -07001681 {
Joe Tsaia95b29f2019-05-16 12:47:20 -07001682 Kind: &structpb.Value_ListValue{
1683 &structpb.ListValue{
1684 Values: []*structpb.Value{
1685 {Kind: &structpb.Value_StringValue{"string"}},
1686 {Kind: &structpb.Value_NumberValue{1.23}},
1687 {Kind: &structpb.Value_NullValue{}},
1688 {Kind: &structpb.Value_BoolValue{false}},
Herbie Onge63c4c42019-03-22 22:20:22 -07001689 },
1690 },
1691 },
1692 },
1693 },
1694 },
1695 },
1696 },
1697 }, {
1698 desc: "Value list with invalid UTF8 string",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001699 inputMessage: &structpb.Value{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001700 inputText: "[\"abc\xff\"]",
Herbie Ongd2ece132020-01-07 16:45:24 -08001701 wantErr: `invalid UTF-8`,
Herbie Onge63c4c42019-03-22 22:20:22 -07001702 }, {
1703 desc: "Value field list with invalid UTF8 string",
1704 inputMessage: &pb2.KnownTypes{},
1705 inputText: `{
1706 "optValue": [ "` + "abc\xff" + `"]
1707}`,
Herbie Ongd2ece132020-01-07 16:45:24 -08001708 wantErr: `(line 2:17): invalid UTF-8`,
Herbie Onge63c4c42019-03-22 22:20:22 -07001709 }, {
Herbie Ongc4450372019-03-27 09:59:51 -07001710 desc: "Duration empty string",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001711 inputMessage: &durationpb.Duration{},
Herbie Ongc4450372019-03-27 09:59:51 -07001712 inputText: `""`,
Herbie Ongd2ece132020-01-07 16:45:24 -08001713 wantErr: `invalid google.protobuf.Duration value ""`,
Herbie Ongc4450372019-03-27 09:59:51 -07001714 }, {
1715 desc: "Duration with secs",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001716 inputMessage: &durationpb.Duration{},
Herbie Ongc4450372019-03-27 09:59:51 -07001717 inputText: `"3s"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001718 wantMessage: &durationpb.Duration{Seconds: 3},
Herbie Ongc4450372019-03-27 09:59:51 -07001719 }, {
1720 desc: "Duration with escaped unicode",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001721 inputMessage: &durationpb.Duration{},
Herbie Ongc4450372019-03-27 09:59:51 -07001722 inputText: `"\u0033s"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001723 wantMessage: &durationpb.Duration{Seconds: 3},
Herbie Ongc4450372019-03-27 09:59:51 -07001724 }, {
1725 desc: "Duration with -secs",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001726 inputMessage: &durationpb.Duration{},
Herbie Ongc4450372019-03-27 09:59:51 -07001727 inputText: `"-3s"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001728 wantMessage: &durationpb.Duration{Seconds: -3},
Herbie Ongc4450372019-03-27 09:59:51 -07001729 }, {
Herbie Ong17523eb2019-03-29 17:46:57 -07001730 desc: "Duration with plus sign",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001731 inputMessage: &durationpb.Duration{},
Herbie Ong17523eb2019-03-29 17:46:57 -07001732 inputText: `"+3s"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001733 wantMessage: &durationpb.Duration{Seconds: 3},
Herbie Ong17523eb2019-03-29 17:46:57 -07001734 }, {
Herbie Ongc4450372019-03-27 09:59:51 -07001735 desc: "Duration with nanos",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001736 inputMessage: &durationpb.Duration{},
Herbie Ongc4450372019-03-27 09:59:51 -07001737 inputText: `"0.001s"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001738 wantMessage: &durationpb.Duration{Nanos: 1e6},
Herbie Ongc4450372019-03-27 09:59:51 -07001739 }, {
1740 desc: "Duration with -nanos",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001741 inputMessage: &durationpb.Duration{},
Herbie Ongc4450372019-03-27 09:59:51 -07001742 inputText: `"-0.001s"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001743 wantMessage: &durationpb.Duration{Nanos: -1e6},
Herbie Ongc4450372019-03-27 09:59:51 -07001744 }, {
Herbie Ong17523eb2019-03-29 17:46:57 -07001745 desc: "Duration with -nanos",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001746 inputMessage: &durationpb.Duration{},
Herbie Ong17523eb2019-03-29 17:46:57 -07001747 inputText: `"-.001s"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001748 wantMessage: &durationpb.Duration{Nanos: -1e6},
Herbie Ong17523eb2019-03-29 17:46:57 -07001749 }, {
1750 desc: "Duration with +nanos",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001751 inputMessage: &durationpb.Duration{},
Herbie Ong17523eb2019-03-29 17:46:57 -07001752 inputText: `"+.001s"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001753 wantMessage: &durationpb.Duration{Nanos: 1e6},
Herbie Ong17523eb2019-03-29 17:46:57 -07001754 }, {
Herbie Ongc4450372019-03-27 09:59:51 -07001755 desc: "Duration with -secs -nanos",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001756 inputMessage: &durationpb.Duration{},
Herbie Ongc4450372019-03-27 09:59:51 -07001757 inputText: `"-123.000000450s"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001758 wantMessage: &durationpb.Duration{Seconds: -123, Nanos: -450},
Herbie Ongc4450372019-03-27 09:59:51 -07001759 }, {
1760 desc: "Duration with large secs",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001761 inputMessage: &durationpb.Duration{},
Herbie Ongc4450372019-03-27 09:59:51 -07001762 inputText: `"10000000000.000000001s"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001763 wantMessage: &durationpb.Duration{Seconds: 1e10, Nanos: 1},
Herbie Ongc4450372019-03-27 09:59:51 -07001764 }, {
1765 desc: "Duration with decimal without fractional",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001766 inputMessage: &durationpb.Duration{},
Herbie Ongc4450372019-03-27 09:59:51 -07001767 inputText: `"3.s"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001768 wantMessage: &durationpb.Duration{Seconds: 3},
Herbie Ongc4450372019-03-27 09:59:51 -07001769 }, {
1770 desc: "Duration with decimal without integer",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001771 inputMessage: &durationpb.Duration{},
Herbie Ongc4450372019-03-27 09:59:51 -07001772 inputText: `"0.5s"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001773 wantMessage: &durationpb.Duration{Nanos: 5e8},
Herbie Ongc4450372019-03-27 09:59:51 -07001774 }, {
Herbie Ongad9c1252019-04-24 20:51:28 -07001775 desc: "Duration max value",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001776 inputMessage: &durationpb.Duration{},
Herbie Ongad9c1252019-04-24 20:51:28 -07001777 inputText: `"315576000000.999999999s"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001778 wantMessage: &durationpb.Duration{Seconds: 315576000000, Nanos: 999999999},
Herbie Ongad9c1252019-04-24 20:51:28 -07001779 }, {
1780 desc: "Duration min value",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001781 inputMessage: &durationpb.Duration{},
Herbie Ongad9c1252019-04-24 20:51:28 -07001782 inputText: `"-315576000000.999999999s"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001783 wantMessage: &durationpb.Duration{Seconds: -315576000000, Nanos: -999999999},
Herbie Ongad9c1252019-04-24 20:51:28 -07001784 }, {
Herbie Ongc4450372019-03-27 09:59:51 -07001785 desc: "Duration with +secs out of range",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001786 inputMessage: &durationpb.Duration{},
Herbie Ongc4450372019-03-27 09:59:51 -07001787 inputText: `"315576000001s"`,
Herbie Ongd2ece132020-01-07 16:45:24 -08001788 wantErr: `google.protobuf.Duration value out of range: "315576000001s"`,
Herbie Ongc4450372019-03-27 09:59:51 -07001789 }, {
1790 desc: "Duration with -secs out of range",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001791 inputMessage: &durationpb.Duration{},
Herbie Ongc4450372019-03-27 09:59:51 -07001792 inputText: `"-315576000001s"`,
Herbie Ongd2ece132020-01-07 16:45:24 -08001793 wantErr: `google.protobuf.Duration value out of range: "-315576000001s"`,
Herbie Ongc4450372019-03-27 09:59:51 -07001794 }, {
1795 desc: "Duration with nanos beyond 9 digits",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001796 inputMessage: &durationpb.Duration{},
Herbie Ong17523eb2019-03-29 17:46:57 -07001797 inputText: `"0.1000000000s"`,
Herbie Ongd2ece132020-01-07 16:45:24 -08001798 wantErr: `invalid google.protobuf.Duration value "0.1000000000s"`,
Herbie Ongc4450372019-03-27 09:59:51 -07001799 }, {
1800 desc: "Duration without suffix s",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001801 inputMessage: &durationpb.Duration{},
Herbie Ongc4450372019-03-27 09:59:51 -07001802 inputText: `"123"`,
Herbie Ongd2ece132020-01-07 16:45:24 -08001803 wantErr: `invalid google.protobuf.Duration value "123"`,
Herbie Ongc4450372019-03-27 09:59:51 -07001804 }, {
Herbie Ong17523eb2019-03-29 17:46:57 -07001805 desc: "Duration invalid signed fraction",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001806 inputMessage: &durationpb.Duration{},
Herbie Ong17523eb2019-03-29 17:46:57 -07001807 inputText: `"123.+123s"`,
Herbie Ongd2ece132020-01-07 16:45:24 -08001808 wantErr: `invalid google.protobuf.Duration value "123.+123s"`,
Herbie Ong17523eb2019-03-29 17:46:57 -07001809 }, {
1810 desc: "Duration invalid multiple .",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001811 inputMessage: &durationpb.Duration{},
Herbie Ong17523eb2019-03-29 17:46:57 -07001812 inputText: `"123.123.s"`,
Herbie Ongd2ece132020-01-07 16:45:24 -08001813 wantErr: `invalid google.protobuf.Duration value "123.123.s"`,
Herbie Ong17523eb2019-03-29 17:46:57 -07001814 }, {
1815 desc: "Duration invalid integer",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001816 inputMessage: &durationpb.Duration{},
Herbie Ong17523eb2019-03-29 17:46:57 -07001817 inputText: `"01s"`,
Herbie Ongd2ece132020-01-07 16:45:24 -08001818 wantErr: `invalid google.protobuf.Duration value "01s"`,
Herbie Ong17523eb2019-03-29 17:46:57 -07001819 }, {
Herbie Ongc4450372019-03-27 09:59:51 -07001820 desc: "Timestamp zero",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001821 inputMessage: &timestamppb.Timestamp{},
Herbie Ongc4450372019-03-27 09:59:51 -07001822 inputText: `"1970-01-01T00:00:00Z"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001823 wantMessage: &timestamppb.Timestamp{},
Herbie Ongc4450372019-03-27 09:59:51 -07001824 }, {
1825 desc: "Timestamp with tz adjustment",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001826 inputMessage: &timestamppb.Timestamp{},
Herbie Ongc4450372019-03-27 09:59:51 -07001827 inputText: `"1970-01-01T00:00:00+01:00"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001828 wantMessage: &timestamppb.Timestamp{Seconds: -3600},
Herbie Ongc4450372019-03-27 09:59:51 -07001829 }, {
1830 desc: "Timestamp UTC",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001831 inputMessage: &timestamppb.Timestamp{},
Herbie Ongc4450372019-03-27 09:59:51 -07001832 inputText: `"2019-03-19T23:03:21Z"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001833 wantMessage: &timestamppb.Timestamp{Seconds: 1553036601},
Herbie Ongc4450372019-03-27 09:59:51 -07001834 }, {
1835 desc: "Timestamp with escaped unicode",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001836 inputMessage: &timestamppb.Timestamp{},
Herbie Ongc4450372019-03-27 09:59:51 -07001837 inputText: `"2019-0\u0033-19T23:03:21Z"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001838 wantMessage: &timestamppb.Timestamp{Seconds: 1553036601},
Herbie Ongc4450372019-03-27 09:59:51 -07001839 }, {
1840 desc: "Timestamp with nanos",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001841 inputMessage: &timestamppb.Timestamp{},
Herbie Ongc4450372019-03-27 09:59:51 -07001842 inputText: `"2019-03-19T23:03:21.000000001Z"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001843 wantMessage: &timestamppb.Timestamp{Seconds: 1553036601, Nanos: 1},
Herbie Ongc4450372019-03-27 09:59:51 -07001844 }, {
Herbie Ongad9c1252019-04-24 20:51:28 -07001845 desc: "Timestamp max value",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001846 inputMessage: &timestamppb.Timestamp{},
Herbie Ongc4450372019-03-27 09:59:51 -07001847 inputText: `"9999-12-31T23:59:59.999999999Z"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001848 wantMessage: &timestamppb.Timestamp{Seconds: 253402300799, Nanos: 999999999},
Herbie Ongc4450372019-03-27 09:59:51 -07001849 }, {
Herbie Ongad9c1252019-04-24 20:51:28 -07001850 desc: "Timestamp above max value",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001851 inputMessage: &timestamppb.Timestamp{},
Herbie Ongc4450372019-03-27 09:59:51 -07001852 inputText: `"9999-12-31T23:59:59-01:00"`,
Herbie Ongd2ece132020-01-07 16:45:24 -08001853 wantErr: `google.protobuf.Timestamp value out of range: "9999-12-31T23:59:59-01:00"`,
Herbie Ongc4450372019-03-27 09:59:51 -07001854 }, {
Herbie Ongad9c1252019-04-24 20:51:28 -07001855 desc: "Timestamp min value",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001856 inputMessage: &timestamppb.Timestamp{},
Herbie Ongc4450372019-03-27 09:59:51 -07001857 inputText: `"0001-01-01T00:00:00Z"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001858 wantMessage: &timestamppb.Timestamp{Seconds: -62135596800},
Herbie Ongc4450372019-03-27 09:59:51 -07001859 }, {
Herbie Ongad9c1252019-04-24 20:51:28 -07001860 desc: "Timestamp below min value",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001861 inputMessage: &timestamppb.Timestamp{},
Herbie Ongc4450372019-03-27 09:59:51 -07001862 inputText: `"0001-01-01T00:00:00+01:00"`,
Herbie Ongd2ece132020-01-07 16:45:24 -08001863 wantErr: `google.protobuf.Timestamp value out of range: "0001-01-01T00:00:00+01:00"`,
Herbie Ongc4450372019-03-27 09:59:51 -07001864 }, {
1865 desc: "Timestamp with nanos beyond 9 digits",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001866 inputMessage: &timestamppb.Timestamp{},
Herbie Ongc4450372019-03-27 09:59:51 -07001867 inputText: `"1970-01-01T00:00:00.0000000001Z"`,
Herbie Ongd2ece132020-01-07 16:45:24 -08001868 wantErr: `invalid google.protobuf.Timestamp value`,
Herbie Ongc4450372019-03-27 09:59:51 -07001869 }, {
Herbie Onge63c4c42019-03-22 22:20:22 -07001870 desc: "FieldMask empty",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001871 inputMessage: &fieldmaskpb.FieldMask{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001872 inputText: `""`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001873 wantMessage: &fieldmaskpb.FieldMask{Paths: []string{}},
Herbie Onge63c4c42019-03-22 22:20:22 -07001874 }, {
1875 desc: "FieldMask",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001876 inputMessage: &fieldmaskpb.FieldMask{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001877 inputText: `"foo,fooBar , foo.barQux ,Foo"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001878 wantMessage: &fieldmaskpb.FieldMask{
Herbie Onge63c4c42019-03-22 22:20:22 -07001879 Paths: []string{
1880 "foo",
1881 "foo_bar",
1882 "foo.bar_qux",
1883 "_foo",
1884 },
1885 },
1886 }, {
1887 desc: "FieldMask field",
1888 inputMessage: &pb2.KnownTypes{},
1889 inputText: `{
1890 "optFieldmask": "foo, qux.fooBar"
1891}`,
1892 wantMessage: &pb2.KnownTypes{
Joe Tsaia95b29f2019-05-16 12:47:20 -07001893 OptFieldmask: &fieldmaskpb.FieldMask{
Herbie Onge63c4c42019-03-22 22:20:22 -07001894 Paths: []string{
1895 "foo",
1896 "qux.foo_bar",
1897 },
1898 },
1899 },
Herbie Ong8ac9dd22019-03-27 12:20:50 -07001900 }, {
1901 desc: "Any empty",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001902 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07001903 inputText: `{}`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001904 wantMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07001905 }, {
Damien Neilc1507ac2019-10-08 13:24:16 -07001906 desc: "Any with non-custom message",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001907 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07001908 inputText: `{
1909 "@type": "foo/pb2.Nested",
1910 "optString": "embedded inside Any",
1911 "optNested": {
1912 "optString": "inception"
1913 }
1914}`,
1915 wantMessage: func() proto.Message {
1916 m := &pb2.Nested{
Damien Neila8a2cea2019-07-10 16:17:16 -07001917 OptString: proto.String("embedded inside Any"),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07001918 OptNested: &pb2.Nested{
Damien Neila8a2cea2019-07-10 16:17:16 -07001919 OptString: proto.String("inception"),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07001920 },
1921 }
1922 b, err := proto.MarshalOptions{Deterministic: true}.Marshal(m)
1923 if err != nil {
1924 t.Fatalf("error in binary marshaling message for Any.value: %v", err)
1925 }
Joe Tsaia95b29f2019-05-16 12:47:20 -07001926 return &anypb.Any{
Herbie Ong8ac9dd22019-03-27 12:20:50 -07001927 TypeUrl: "foo/pb2.Nested",
1928 Value: b,
1929 }
1930 }(),
1931 }, {
Damien Neilc1507ac2019-10-08 13:24:16 -07001932 desc: "Any with empty embedded message",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001933 inputMessage: &anypb.Any{},
Herbie Ong4f0be712019-04-25 17:57:12 -07001934 inputText: `{"@type": "foo/pb2.Nested"}`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001935 wantMessage: &anypb.Any{TypeUrl: "foo/pb2.Nested"},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07001936 }, {
1937 desc: "Any without registered type",
Damien Neilc1507ac2019-10-08 13:24:16 -07001938 umo: protojson.UnmarshalOptions{Resolver: new(preg.Types)},
Joe Tsaia95b29f2019-05-16 12:47:20 -07001939 inputMessage: &anypb.Any{},
Herbie Ong4f0be712019-04-25 17:57:12 -07001940 inputText: `{"@type": "foo/pb2.Nested"}`,
Herbie Ongd2ece132020-01-07 16:45:24 -08001941 wantErr: `(line 1:11): unable to resolve "foo/pb2.Nested":`,
Herbie Ong8ac9dd22019-03-27 12:20:50 -07001942 }, {
Damien Neilc1507ac2019-10-08 13:24:16 -07001943 desc: "Any with missing required",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001944 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07001945 inputText: `{
1946 "@type": "pb2.PartialRequired",
1947 "optString": "embedded inside Any"
1948}`,
1949 wantMessage: func() proto.Message {
1950 m := &pb2.PartialRequired{
Damien Neila8a2cea2019-07-10 16:17:16 -07001951 OptString: proto.String("embedded inside Any"),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07001952 }
Damien Neil96c229a2019-04-03 12:17:24 -07001953 b, err := proto.MarshalOptions{
1954 Deterministic: true,
1955 AllowPartial: true,
1956 }.Marshal(m)
Herbie Ong8ac9dd22019-03-27 12:20:50 -07001957 if err != nil {
1958 t.Fatalf("error in binary marshaling message for Any.value: %v", err)
1959 }
Joe Tsaia95b29f2019-05-16 12:47:20 -07001960 return &anypb.Any{
Joe Tsai0fc49f82019-05-01 12:29:25 -07001961 TypeUrl: string(m.ProtoReflect().Descriptor().FullName()),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07001962 Value: b,
1963 }
1964 }(),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07001965 }, {
1966 desc: "Any with partial required and AllowPartial",
Damien Neil5c5b5312019-05-14 12:44:37 -07001967 umo: protojson.UnmarshalOptions{
Herbie Ong8ac9dd22019-03-27 12:20:50 -07001968 AllowPartial: true,
Herbie Ong8ac9dd22019-03-27 12:20:50 -07001969 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07001970 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07001971 inputText: `{
1972 "@type": "pb2.PartialRequired",
1973 "optString": "embedded inside Any"
1974}`,
1975 wantMessage: func() proto.Message {
1976 m := &pb2.PartialRequired{
Damien Neila8a2cea2019-07-10 16:17:16 -07001977 OptString: proto.String("embedded inside Any"),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07001978 }
Damien Neil96c229a2019-04-03 12:17:24 -07001979 b, err := proto.MarshalOptions{
1980 Deterministic: true,
1981 AllowPartial: true,
1982 }.Marshal(m)
Herbie Ong8ac9dd22019-03-27 12:20:50 -07001983 if err != nil {
1984 t.Fatalf("error in binary marshaling message for Any.value: %v", err)
1985 }
Joe Tsaia95b29f2019-05-16 12:47:20 -07001986 return &anypb.Any{
Joe Tsai0fc49f82019-05-01 12:29:25 -07001987 TypeUrl: string(m.ProtoReflect().Descriptor().FullName()),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07001988 Value: b,
1989 }
1990 }(),
1991 }, {
Damien Neilc1507ac2019-10-08 13:24:16 -07001992 desc: "Any with invalid UTF8",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001993 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07001994 inputText: `{
1995 "optString": "` + "abc\xff" + `",
1996 "@type": "foo/pb2.Nested"
1997}`,
Herbie Ongd2ece132020-01-07 16:45:24 -08001998 wantErr: `(line 2:16): invalid UTF-8`,
Herbie Ong8ac9dd22019-03-27 12:20:50 -07001999 }, {
Damien Neilc1507ac2019-10-08 13:24:16 -07002000 desc: "Any with BoolValue",
Joe Tsaia95b29f2019-05-16 12:47:20 -07002001 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002002 inputText: `{
2003 "@type": "type.googleapis.com/google.protobuf.BoolValue",
2004 "value": true
2005}`,
2006 wantMessage: func() proto.Message {
Joe Tsaia95b29f2019-05-16 12:47:20 -07002007 m := &wrapperspb.BoolValue{Value: true}
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002008 b, err := proto.MarshalOptions{Deterministic: true}.Marshal(m)
2009 if err != nil {
2010 t.Fatalf("error in binary marshaling message for Any.value: %v", err)
2011 }
Joe Tsaia95b29f2019-05-16 12:47:20 -07002012 return &anypb.Any{
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002013 TypeUrl: "type.googleapis.com/google.protobuf.BoolValue",
2014 Value: b,
2015 }
2016 }(),
2017 }, {
Damien Neilc1507ac2019-10-08 13:24:16 -07002018 desc: "Any with Empty",
Joe Tsaia95b29f2019-05-16 12:47:20 -07002019 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002020 inputText: `{
2021 "value": {},
2022 "@type": "type.googleapis.com/google.protobuf.Empty"
2023}`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07002024 wantMessage: &anypb.Any{
Herbie Ong4f0be712019-04-25 17:57:12 -07002025 TypeUrl: "type.googleapis.com/google.protobuf.Empty",
2026 },
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002027 }, {
Damien Neilc1507ac2019-10-08 13:24:16 -07002028 desc: "Any with missing Empty",
Joe Tsaia95b29f2019-05-16 12:47:20 -07002029 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002030 inputText: `{
2031 "@type": "type.googleapis.com/google.protobuf.Empty"
2032}`,
Herbie Ongd2ece132020-01-07 16:45:24 -08002033 wantErr: `(line 3:1): missing "value" field`,
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002034 }, {
Damien Neilc1507ac2019-10-08 13:24:16 -07002035 desc: "Any with StringValue containing invalid UTF8",
Joe Tsaia95b29f2019-05-16 12:47:20 -07002036 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002037 inputText: `{
2038 "@type": "google.protobuf.StringValue",
2039 "value": "` + "abc\xff" + `"
2040}`,
Herbie Ongd2ece132020-01-07 16:45:24 -08002041 wantErr: `(line 3:12): invalid UTF-8`,
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002042 }, {
Damien Neilc1507ac2019-10-08 13:24:16 -07002043 desc: "Any with Int64Value",
Joe Tsaia95b29f2019-05-16 12:47:20 -07002044 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002045 inputText: `{
2046 "@type": "google.protobuf.Int64Value",
2047 "value": "42"
2048}`,
2049 wantMessage: func() proto.Message {
Joe Tsaia95b29f2019-05-16 12:47:20 -07002050 m := &wrapperspb.Int64Value{Value: 42}
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002051 b, err := proto.MarshalOptions{Deterministic: true}.Marshal(m)
2052 if err != nil {
2053 t.Fatalf("error in binary marshaling message for Any.value: %v", err)
2054 }
Joe Tsaia95b29f2019-05-16 12:47:20 -07002055 return &anypb.Any{
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002056 TypeUrl: "google.protobuf.Int64Value",
2057 Value: b,
2058 }
2059 }(),
2060 }, {
Damien Neilc1507ac2019-10-08 13:24:16 -07002061 desc: "Any with invalid Int64Value",
Joe Tsaia95b29f2019-05-16 12:47:20 -07002062 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002063 inputText: `{
2064 "@type": "google.protobuf.Int64Value",
2065 "value": "forty-two"
2066}`,
Herbie Ongd2ece132020-01-07 16:45:24 -08002067 wantErr: `(line 3:12): invalid value for int64 type: "forty-two"`,
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002068 }, {
Damien Neilc1507ac2019-10-08 13:24:16 -07002069 desc: "Any with invalid UInt64Value",
Joe Tsaia95b29f2019-05-16 12:47:20 -07002070 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002071 inputText: `{
2072 "@type": "google.protobuf.UInt64Value",
2073 "value": -42
2074}`,
Herbie Ongd2ece132020-01-07 16:45:24 -08002075 wantErr: `(line 3:12): invalid value for uint64 type: -42`,
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002076 }, {
Damien Neilc1507ac2019-10-08 13:24:16 -07002077 desc: "Any with Duration",
Joe Tsaia95b29f2019-05-16 12:47:20 -07002078 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002079 inputText: `{
2080 "@type": "type.googleapis.com/google.protobuf.Duration",
2081 "value": "0s"
2082}`,
2083 wantMessage: func() proto.Message {
Joe Tsaia95b29f2019-05-16 12:47:20 -07002084 m := &durationpb.Duration{}
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002085 b, err := proto.MarshalOptions{Deterministic: true}.Marshal(m)
2086 if err != nil {
2087 t.Fatalf("error in binary marshaling message for Any.value: %v", err)
2088 }
Joe Tsaia95b29f2019-05-16 12:47:20 -07002089 return &anypb.Any{
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002090 TypeUrl: "type.googleapis.com/google.protobuf.Duration",
2091 Value: b,
2092 }
2093 }(),
2094 }, {
Damien Neilc1507ac2019-10-08 13:24:16 -07002095 desc: "Any with Value of StringValue",
Joe Tsaia95b29f2019-05-16 12:47:20 -07002096 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002097 inputText: `{
2098 "@type": "google.protobuf.Value",
2099 "value": "` + "abc\xff" + `"
2100}`,
Herbie Ongd2ece132020-01-07 16:45:24 -08002101 wantErr: `(line 3:12): invalid UTF-8`,
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002102 }, {
Damien Neilc1507ac2019-10-08 13:24:16 -07002103 desc: "Any with Value of NullValue",
Joe Tsaia95b29f2019-05-16 12:47:20 -07002104 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002105 inputText: `{
2106 "@type": "google.protobuf.Value",
2107 "value": null
2108}`,
2109 wantMessage: func() proto.Message {
Joe Tsaia95b29f2019-05-16 12:47:20 -07002110 m := &structpb.Value{Kind: &structpb.Value_NullValue{}}
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002111 b, err := proto.MarshalOptions{Deterministic: true}.Marshal(m)
2112 if err != nil {
2113 t.Fatalf("error in binary marshaling message for Any.value: %v", err)
2114 }
Joe Tsaia95b29f2019-05-16 12:47:20 -07002115 return &anypb.Any{
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002116 TypeUrl: "google.protobuf.Value",
2117 Value: b,
2118 }
2119 }(),
2120 }, {
Damien Neilc1507ac2019-10-08 13:24:16 -07002121 desc: "Any with Struct",
Joe Tsaia95b29f2019-05-16 12:47:20 -07002122 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002123 inputText: `{
2124 "@type": "google.protobuf.Struct",
2125 "value": {
2126 "bool": true,
2127 "null": null,
2128 "string": "hello",
2129 "struct": {
2130 "string": "world"
2131 }
2132 }
2133}`,
2134 wantMessage: func() proto.Message {
Joe Tsaia95b29f2019-05-16 12:47:20 -07002135 m := &structpb.Struct{
2136 Fields: map[string]*structpb.Value{
2137 "bool": {Kind: &structpb.Value_BoolValue{true}},
2138 "null": {Kind: &structpb.Value_NullValue{}},
2139 "string": {Kind: &structpb.Value_StringValue{"hello"}},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002140 "struct": {
Joe Tsaia95b29f2019-05-16 12:47:20 -07002141 Kind: &structpb.Value_StructValue{
2142 &structpb.Struct{
2143 Fields: map[string]*structpb.Value{
2144 "string": {Kind: &structpb.Value_StringValue{"world"}},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002145 },
2146 },
2147 },
2148 },
2149 },
2150 }
2151 b, err := proto.MarshalOptions{Deterministic: true}.Marshal(m)
2152 if err != nil {
2153 t.Fatalf("error in binary marshaling message for Any.value: %v", err)
2154 }
Joe Tsaia95b29f2019-05-16 12:47:20 -07002155 return &anypb.Any{
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002156 TypeUrl: "google.protobuf.Struct",
2157 Value: b,
2158 }
2159 }(),
2160 }, {
2161 desc: "Any with missing @type",
Damien Neil5c5b5312019-05-14 12:44:37 -07002162 umo: protojson.UnmarshalOptions{},
Joe Tsaia95b29f2019-05-16 12:47:20 -07002163 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002164 inputText: `{
2165 "value": {}
2166}`,
Herbie Ongd2ece132020-01-07 16:45:24 -08002167 wantErr: `(line 1:1): missing "@type" field`,
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002168 }, {
2169 desc: "Any with empty @type",
Joe Tsaia95b29f2019-05-16 12:47:20 -07002170 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002171 inputText: `{
2172 "@type": ""
2173}`,
Herbie Ongd2ece132020-01-07 16:45:24 -08002174 wantErr: `(line 2:12): @type field contains empty value`,
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002175 }, {
Damien Neilc1507ac2019-10-08 13:24:16 -07002176 desc: "Any with duplicate @type",
Joe Tsaia95b29f2019-05-16 12:47:20 -07002177 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002178 inputText: `{
2179 "@type": "google.protobuf.StringValue",
2180 "value": "hello",
2181 "@type": "pb2.Nested"
2182}`,
Herbie Ongd2ece132020-01-07 16:45:24 -08002183 wantErr: `(line 4:3): duplicate "@type" field`,
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002184 }, {
Damien Neilc1507ac2019-10-08 13:24:16 -07002185 desc: "Any with duplicate value",
Joe Tsaia95b29f2019-05-16 12:47:20 -07002186 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002187 inputText: `{
2188 "@type": "google.protobuf.StringValue",
2189 "value": "hello",
2190 "value": "world"
2191}`,
Herbie Ongd2ece132020-01-07 16:45:24 -08002192 wantErr: `(line 4:3): duplicate "value" field`,
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002193 }, {
Damien Neilc1507ac2019-10-08 13:24:16 -07002194 desc: "Any with unknown field",
Joe Tsaia95b29f2019-05-16 12:47:20 -07002195 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002196 inputText: `{
2197 "@type": "pb2.Nested",
2198 "optString": "hello",
2199 "unknown": "world"
2200}`,
Herbie Ongd2ece132020-01-07 16:45:24 -08002201 wantErr: `(line 4:3): unknown field "unknown"`,
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002202 }, {
Damien Neilc1507ac2019-10-08 13:24:16 -07002203 desc: "Any with embedded type containing Any",
Joe Tsaia95b29f2019-05-16 12:47:20 -07002204 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002205 inputText: `{
2206 "@type": "pb2.KnownTypes",
2207 "optAny": {
2208 "@type": "google.protobuf.StringValue",
Herbie Ongd2ece132020-01-07 16:45:24 -08002209 "value": "` + "abc\xff" + `"
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002210 }
2211}`,
Herbie Ongd2ece132020-01-07 16:45:24 -08002212 wantErr: `(line 5:14): invalid UTF-8`,
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002213 }, {
Damien Neilc1507ac2019-10-08 13:24:16 -07002214 desc: "well known types as field values",
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002215 inputMessage: &pb2.KnownTypes{},
2216 inputText: `{
2217 "optBool": false,
2218 "optInt32": 42,
2219 "optInt64": "42",
2220 "optUint32": 42,
2221 "optUint64": "42",
2222 "optFloat": 1.23,
2223 "optDouble": 3.1415,
2224 "optString": "hello",
2225 "optBytes": "aGVsbG8=",
2226 "optDuration": "123s",
2227 "optTimestamp": "2019-03-19T23:03:21Z",
2228 "optStruct": {
2229 "string": "hello"
2230 },
2231 "optList": [
2232 null,
2233 "",
2234 {},
2235 []
2236 ],
2237 "optValue": "world",
2238 "optEmpty": {},
2239 "optAny": {
2240 "@type": "google.protobuf.Empty",
2241 "value": {}
2242 },
2243 "optFieldmask": "fooBar,barFoo"
2244}`,
2245 wantMessage: &pb2.KnownTypes{
Joe Tsaia95b29f2019-05-16 12:47:20 -07002246 OptBool: &wrapperspb.BoolValue{Value: false},
2247 OptInt32: &wrapperspb.Int32Value{Value: 42},
2248 OptInt64: &wrapperspb.Int64Value{Value: 42},
2249 OptUint32: &wrapperspb.UInt32Value{Value: 42},
2250 OptUint64: &wrapperspb.UInt64Value{Value: 42},
2251 OptFloat: &wrapperspb.FloatValue{Value: 1.23},
2252 OptDouble: &wrapperspb.DoubleValue{Value: 3.1415},
2253 OptString: &wrapperspb.StringValue{Value: "hello"},
2254 OptBytes: &wrapperspb.BytesValue{Value: []byte("hello")},
2255 OptDuration: &durationpb.Duration{Seconds: 123},
2256 OptTimestamp: &timestamppb.Timestamp{Seconds: 1553036601},
2257 OptStruct: &structpb.Struct{
2258 Fields: map[string]*structpb.Value{
2259 "string": {Kind: &structpb.Value_StringValue{"hello"}},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002260 },
2261 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07002262 OptList: &structpb.ListValue{
2263 Values: []*structpb.Value{
2264 {Kind: &structpb.Value_NullValue{}},
2265 {Kind: &structpb.Value_StringValue{}},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002266 {
Joe Tsaia95b29f2019-05-16 12:47:20 -07002267 Kind: &structpb.Value_StructValue{
2268 &structpb.Struct{Fields: map[string]*structpb.Value{}},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002269 },
2270 },
2271 {
Joe Tsaia95b29f2019-05-16 12:47:20 -07002272 Kind: &structpb.Value_ListValue{
2273 &structpb.ListValue{Values: []*structpb.Value{}},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002274 },
2275 },
2276 },
2277 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07002278 OptValue: &structpb.Value{
2279 Kind: &structpb.Value_StringValue{"world"},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002280 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07002281 OptEmpty: &emptypb.Empty{},
2282 OptAny: &anypb.Any{
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002283 TypeUrl: "google.protobuf.Empty",
2284 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07002285 OptFieldmask: &fieldmaskpb.FieldMask{
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002286 Paths: []string{"foo_bar", "bar_foo"},
2287 },
2288 },
Herbie Ong4f0be712019-04-25 17:57:12 -07002289 }, {
2290 desc: "DiscardUnknown: regular messages",
Damien Neil5c5b5312019-05-14 12:44:37 -07002291 umo: protojson.UnmarshalOptions{DiscardUnknown: true},
Herbie Ong4f0be712019-04-25 17:57:12 -07002292 inputMessage: &pb3.Nests{},
2293 inputText: `{
2294 "sNested": {
2295 "unknown": {
2296 "foo": 1,
2297 "bar": [1, 2, 3]
2298 }
2299 },
2300 "unknown": "not known"
2301}`,
2302 wantMessage: &pb3.Nests{SNested: &pb3.Nested{}},
2303 }, {
2304 desc: "DiscardUnknown: repeated",
Damien Neil5c5b5312019-05-14 12:44:37 -07002305 umo: protojson.UnmarshalOptions{DiscardUnknown: true},
Herbie Ong4f0be712019-04-25 17:57:12 -07002306 inputMessage: &pb2.Nests{},
2307 inputText: `{
2308 "rptNested": [
2309 {"unknown": "blah"},
2310 {"optString": "hello"}
2311 ]
2312}`,
2313 wantMessage: &pb2.Nests{
2314 RptNested: []*pb2.Nested{
2315 {},
Damien Neila8a2cea2019-07-10 16:17:16 -07002316 {OptString: proto.String("hello")},
Herbie Ong4f0be712019-04-25 17:57:12 -07002317 },
2318 },
2319 }, {
2320 desc: "DiscardUnknown: map",
Damien Neil5c5b5312019-05-14 12:44:37 -07002321 umo: protojson.UnmarshalOptions{DiscardUnknown: true},
Herbie Ong4f0be712019-04-25 17:57:12 -07002322 inputMessage: &pb3.Maps{},
2323 inputText: `{
2324 "strToNested": {
2325 "nested_one": {
2326 "unknown": "what you see is not"
2327 }
2328 }
2329}`,
2330 wantMessage: &pb3.Maps{
2331 StrToNested: map[string]*pb3.Nested{
2332 "nested_one": {},
2333 },
2334 },
2335 }, {
2336 desc: "DiscardUnknown: extension",
Damien Neil5c5b5312019-05-14 12:44:37 -07002337 umo: protojson.UnmarshalOptions{DiscardUnknown: true},
Herbie Ong4f0be712019-04-25 17:57:12 -07002338 inputMessage: &pb2.Extensions{},
2339 inputText: `{
2340 "[pb2.opt_ext_nested]": {
2341 "unknown": []
2342 }
2343}`,
2344 wantMessage: func() proto.Message {
2345 m := &pb2.Extensions{}
Damien Neil92f76182019-08-02 16:58:08 -07002346 proto.SetExtension(m, pb2.E_OptExtNested, &pb2.Nested{})
Herbie Ong4f0be712019-04-25 17:57:12 -07002347 return m
2348 }(),
2349 }, {
2350 desc: "DiscardUnknown: Empty",
Damien Neil5c5b5312019-05-14 12:44:37 -07002351 umo: protojson.UnmarshalOptions{DiscardUnknown: true},
Joe Tsaia95b29f2019-05-16 12:47:20 -07002352 inputMessage: &emptypb.Empty{},
Herbie Ong4f0be712019-04-25 17:57:12 -07002353 inputText: `{"unknown": "something"}`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07002354 wantMessage: &emptypb.Empty{},
Herbie Ong4f0be712019-04-25 17:57:12 -07002355 }, {
2356 desc: "DiscardUnknown: Any without type",
Damien Neil5c5b5312019-05-14 12:44:37 -07002357 umo: protojson.UnmarshalOptions{DiscardUnknown: true},
Joe Tsaia95b29f2019-05-16 12:47:20 -07002358 inputMessage: &anypb.Any{},
Herbie Ong4f0be712019-04-25 17:57:12 -07002359 inputText: `{
2360 "value": {"foo": "bar"},
2361 "unknown": true
2362}`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07002363 wantMessage: &anypb.Any{},
Herbie Ong4f0be712019-04-25 17:57:12 -07002364 }, {
2365 desc: "DiscardUnknown: Any",
Damien Neil5c5b5312019-05-14 12:44:37 -07002366 umo: protojson.UnmarshalOptions{
Herbie Ong4f0be712019-04-25 17:57:12 -07002367 DiscardUnknown: true,
Herbie Ong4f0be712019-04-25 17:57:12 -07002368 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07002369 inputMessage: &anypb.Any{},
Herbie Ong4f0be712019-04-25 17:57:12 -07002370 inputText: `{
2371 "@type": "foo/pb2.Nested",
2372 "unknown": "none"
2373}`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07002374 wantMessage: &anypb.Any{
Herbie Ong4f0be712019-04-25 17:57:12 -07002375 TypeUrl: "foo/pb2.Nested",
2376 },
2377 }, {
2378 desc: "DiscardUnknown: Any with Empty",
Damien Neil5c5b5312019-05-14 12:44:37 -07002379 umo: protojson.UnmarshalOptions{
Herbie Ong4f0be712019-04-25 17:57:12 -07002380 DiscardUnknown: true,
Herbie Ong4f0be712019-04-25 17:57:12 -07002381 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07002382 inputMessage: &anypb.Any{},
Herbie Ong4f0be712019-04-25 17:57:12 -07002383 inputText: `{
2384 "@type": "type.googleapis.com/google.protobuf.Empty",
2385 "value": {"unknown": 47}
2386}`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07002387 wantMessage: &anypb.Any{
Herbie Ong4f0be712019-04-25 17:57:12 -07002388 TypeUrl: "type.googleapis.com/google.protobuf.Empty",
2389 },
Joe Tsaid47ea192019-07-09 22:38:15 -07002390 }, {
2391 desc: "weak fields",
2392 inputMessage: &testpb.TestWeak{},
2393 inputText: `{"weak_message1":{"a":1}}`,
2394 wantMessage: func() *testpb.TestWeak {
2395 m := new(testpb.TestWeak)
2396 m.SetWeakMessage1(&weakpb.WeakImportMessage1{A: proto.Int32(1)})
2397 return m
2398 }(),
Joe Tsai1799d112019-08-08 13:31:59 -07002399 skip: !flags.ProtoLegacy,
Joe Tsaid47ea192019-07-09 22:38:15 -07002400 }, {
2401 desc: "weak fields; unknown field",
2402 inputMessage: &testpb.TestWeak{},
2403 inputText: `{"weak_message1":{"a":1}, "weak_message2":{"a":1}}`,
Herbie Ongd2ece132020-01-07 16:45:24 -08002404 wantErr: `unknown field "weak_message2"`, // weak_message2 is unknown since the package containing it is not imported
Joe Tsai1799d112019-08-08 13:31:59 -07002405 skip: !flags.ProtoLegacy,
Herbie Ongc96a79d2019-03-08 10:49:17 -08002406 }}
2407
2408 for _, tt := range tests {
2409 tt := tt
Joe Tsaid47ea192019-07-09 22:38:15 -07002410 if tt.skip {
2411 continue
2412 }
Herbie Ongc96a79d2019-03-08 10:49:17 -08002413 t.Run(tt.desc, func(t *testing.T) {
Joe Tsaicdb77732019-05-14 16:05:06 -07002414 err := tt.umo.Unmarshal([]byte(tt.inputText), tt.inputMessage)
Herbie Ongd2ece132020-01-07 16:45:24 -08002415 if err != nil {
2416 if tt.wantErr == "" {
2417 t.Errorf("Unmarshal() got unexpected error: %v", err)
2418 } else if !strings.Contains(err.Error(), tt.wantErr) {
2419 t.Errorf("Unmarshal() error got %q, want %q", err, tt.wantErr)
2420 }
2421 return
Herbie Ongc96a79d2019-03-08 10:49:17 -08002422 }
Herbie Ongd2ece132020-01-07 16:45:24 -08002423 if tt.wantErr != "" {
2424 t.Errorf("Unmarshal() got nil error, want error %q", tt.wantErr)
Herbie Ongc96a79d2019-03-08 10:49:17 -08002425 }
Joe Tsai8d30bbe2019-05-16 15:53:25 -07002426 if tt.wantMessage != nil && !proto.Equal(tt.inputMessage, tt.wantMessage) {
Herbie Ongc96a79d2019-03-08 10:49:17 -08002427 t.Errorf("Unmarshal()\n<got>\n%v\n<want>\n%v\n", tt.inputMessage, tt.wantMessage)
2428 }
2429 })
2430 }
2431}