blob: e5385f4db38d41b01fefa196486eadea0214cb99 [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"
9 "testing"
10
Damien Neil5c5b5312019-05-14 12:44:37 -070011 "google.golang.org/protobuf/encoding/protojson"
Joe Tsaid47ea192019-07-09 22:38:15 -070012 "google.golang.org/protobuf/internal/flags"
Damien Neile89e6242019-05-13 23:55:40 -070013 pimpl "google.golang.org/protobuf/internal/impl"
Damien Neile89e6242019-05-13 23:55:40 -070014 "google.golang.org/protobuf/proto"
15 preg "google.golang.org/protobuf/reflect/protoregistry"
Herbie Onge63c4c42019-03-22 22:20:22 -070016
Joe Tsaid47ea192019-07-09 22:38:15 -070017 "google.golang.org/protobuf/encoding/testprotos/pb2"
18 "google.golang.org/protobuf/encoding/testprotos/pb3"
19 testpb "google.golang.org/protobuf/internal/testprotos/test"
20 weakpb "google.golang.org/protobuf/internal/testprotos/test/weak1"
Joe Tsaia95b29f2019-05-16 12:47:20 -070021 "google.golang.org/protobuf/types/known/anypb"
22 "google.golang.org/protobuf/types/known/durationpb"
23 "google.golang.org/protobuf/types/known/emptypb"
24 "google.golang.org/protobuf/types/known/fieldmaskpb"
25 "google.golang.org/protobuf/types/known/structpb"
26 "google.golang.org/protobuf/types/known/timestamppb"
27 "google.golang.org/protobuf/types/known/wrapperspb"
Herbie Ongc96a79d2019-03-08 10:49:17 -080028)
29
30func TestUnmarshal(t *testing.T) {
31 tests := []struct {
32 desc string
Damien Neil5c5b5312019-05-14 12:44:37 -070033 umo protojson.UnmarshalOptions
Herbie Ongc96a79d2019-03-08 10:49:17 -080034 inputMessage proto.Message
35 inputText string
36 wantMessage proto.Message
37 // TODO: verify expected error message substring.
38 wantErr bool
Joe Tsaid47ea192019-07-09 22:38:15 -070039 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: "{} {}",
49 wantErr: true,
50 }, {
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"}`,
161 wantErr: true,
162 }, {
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}`,
210 wantErr: true,
211 }, {
212 desc: "float in string exceeds limit",
213 inputMessage: &pb3.Scalars{},
214 inputText: `{"sFloat": "-3.4e39"}`,
215 wantErr: true,
216 }, {
217 desc: "double exceeds limit",
218 inputMessage: &pb3.Scalars{},
219 inputText: `{"sFloat": -1.79e+309}`,
220 wantErr: true,
221 }, {
222 desc: "double in string exceeds limit",
223 inputMessage: &pb3.Scalars{},
224 inputText: `{"sFloat": "1.79e+309"}`,
225 wantErr: true,
226 }, {
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"}`,
238 wantErr: true,
239 }, {
240 desc: "double string with trailing space",
241 inputMessage: &pb3.Scalars{},
242 inputText: `{"sDouble": "5.678 "}`,
243 wantErr: true,
244 }, {
Herbie Ongc96a79d2019-03-08 10:49:17 -0800245 desc: "not float",
246 inputMessage: &pb3.Scalars{},
247 inputText: `{"sFloat": true}`,
248 wantErr: true,
249 }, {
250 desc: "not double",
251 inputMessage: &pb3.Scalars{},
252 inputText: `{"sDouble": "not a number"}`,
253 wantErr: true,
254 }, {
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"}`,
319 wantErr: true,
320 }, {
321 desc: "integer string with trailing space",
322 inputMessage: &pb3.Scalars{},
323 inputText: `{"sUint32": "1e2 "}`,
324 wantErr: true,
325 }, {
Herbie Ongc96a79d2019-03-08 10:49:17 -0800326 desc: "number is not an integer",
327 inputMessage: &pb3.Scalars{},
328 inputText: `{"sInt32": 1.001}`,
329 wantErr: true,
330 }, {
331 desc: "32-bit int exceeds limit",
332 inputMessage: &pb3.Scalars{},
333 inputText: `{"sInt32": 2e10}`,
334 wantErr: true,
335 }, {
336 desc: "64-bit int exceeds limit",
337 inputMessage: &pb3.Scalars{},
338 inputText: `{"sSfixed64": -9e19}`,
339 wantErr: true,
340 }, {
341 desc: "not integer",
342 inputMessage: &pb3.Scalars{},
343 inputText: `{"sInt32": "not a number"}`,
344 wantErr: true,
345 }, {
346 desc: "not unsigned integer",
347 inputMessage: &pb3.Scalars{},
348 inputText: `{"sUint32": "not a number"}`,
349 wantErr: true,
350 }, {
351 desc: "number is not an unsigned integer",
352 inputMessage: &pb3.Scalars{},
353 inputText: `{"sUint32": -1}`,
354 wantErr: true,
355 }, {
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\"}",
Damien Neil8c86fc52019-06-19 09:28:29 -0700366 wantErr: true,
Herbie Ongc96a79d2019-03-08 10:49:17 -0800367 }, {
368 desc: "not string",
369 inputMessage: &pb2.Scalars{},
370 inputText: `{"optString": 42}`,
371 wantErr: true,
372 }, {
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}`,
390 wantErr: true,
391 }, {
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}`,
441 wantErr: true,
442 }, {
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}`,
448 wantErr: true,
449 }, {
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}`,
455 wantErr: true,
456 }, {
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}`,
498 wantErr: true,
499 }, {
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}`,
506 wantErr: true,
507 }, {
508 desc: "duplicate field names",
509 inputMessage: &pb3.JSONNames{},
510 inputText: `{
511 "foo_bar": "one",
512 "foo_bar": "two",
513}`,
514 wantErr: true,
515 }, {
516 desc: "null message",
517 inputMessage: &pb2.Nests{},
518 inputText: "null",
519 wantErr: true,
520 }, {
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"`,
628 wantErr: true,
629 }, {
630 desc: "nested message set to non-message",
631 inputMessage: &pb3.Nests{},
632 inputText: `{"sNested": true}`,
633 wantErr: true,
634 }, {
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}`,
695 wantErr: true,
696 }, {
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" + `"]}`,
Damien Neil8c86fc52019-06-19 09:28:29 -0700797 wantErr: true,
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" + `"}]}`,
Damien Neil8c86fc52019-06-19 09:28:29 -0700802 wantErr: true,
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"]}`,
807 wantErr: true,
808 }, {
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]}`,
812 wantErr: true,
813 }, {
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",
911 "0": "zero"
912 }
913}
914`,
915 wantErr: true,
916 }, {
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"
935}`,
936 wantErr: true,
937 }, {
938 desc: "map contains invalid key 2",
939 inputMessage: &pb3.Maps{},
940 inputText: `{
941 "int32ToStr": {
942 "1.02": "float"
943}`,
944 wantErr: true,
945 }, {
946 desc: "map contains invalid key 3",
947 inputMessage: &pb3.Maps{},
948 inputText: `{
949 "int32ToStr": {
950 "2147483648": "exceeds 32-bit integer max limit"
951}`,
952 wantErr: true,
953 }, {
954 desc: "map contains invalid key 4",
955 inputMessage: &pb3.Maps{},
956 inputText: `{
957 "uint64ToEnum": {
958 "-1": 0
959 }
960}`,
961 wantErr: true,
962 }, {
963 desc: "map contains invalid value",
964 inputMessage: &pb3.Maps{},
965 inputText: `{
966 "int32ToStr": {
967 "101": true
968}`,
969 wantErr: true,
970 }, {
971 desc: "map contains null for scalar value",
972 inputMessage: &pb3.Maps{},
973 inputText: `{
974 "int32ToStr": {
975 "101": null
976}`,
977 wantErr: true,
978 }, {
979 desc: "map contains null for message value",
980 inputMessage: &pb3.Maps{},
981 inputText: `{
982 "strToNested": {
983 "hello": null
984 }
985}`,
986 wantErr: true,
Herbie Onge52379a2019-03-15 18:00:19 -0700987 }, {
Herbie Onge63c4c42019-03-22 22:20:22 -0700988 desc: "map contains contains message value with invalid UTF8",
989 inputMessage: &pb3.Maps{},
990 inputText: `{
991 "strToNested": {
992 "hello": {
993 "sString": "` + "abc\xff" + `"
994 }
995 }
996}`,
Herbie Onge63c4c42019-03-22 22:20:22 -0700997 wantErr: true,
998 }, {
999 desc: "map key contains invalid UTF8",
1000 inputMessage: &pb3.Maps{},
1001 inputText: `{
1002 "strToNested": {
1003 "` + "abc\xff" + `": {}
1004 }
1005}`,
Herbie Onge63c4c42019-03-22 22:20:22 -07001006 wantErr: true,
1007 }, {
Herbie Ong329be5b2019-03-27 14:47:59 -07001008 desc: "required fields not set",
1009 inputMessage: &pb2.Requireds{},
1010 wantErr: true,
1011 }, {
1012 desc: "required field set",
1013 inputMessage: &pb2.PartialRequired{},
1014 inputText: `{
1015 "reqString": "this is required"
1016}`,
1017 wantMessage: &pb2.PartialRequired{
Damien Neila8a2cea2019-07-10 16:17:16 -07001018 ReqString: proto.String("this is required"),
Herbie Ong329be5b2019-03-27 14:47:59 -07001019 },
1020 }, {
1021 desc: "required fields partially set",
1022 inputMessage: &pb2.Requireds{},
1023 inputText: `{
1024 "reqBool": false,
1025 "reqSfixed64": 42,
1026 "reqString": "hello",
1027 "reqEnum": "ONE"
1028}`,
1029 wantMessage: &pb2.Requireds{
Damien Neila8a2cea2019-07-10 16:17:16 -07001030 ReqBool: proto.Bool(false),
1031 ReqSfixed64: proto.Int64(42),
1032 ReqString: proto.String("hello"),
Herbie Ong329be5b2019-03-27 14:47:59 -07001033 ReqEnum: pb2.Enum_ONE.Enum(),
1034 },
1035 wantErr: true,
1036 }, {
1037 desc: "required fields partially set with AllowPartial",
Damien Neil5c5b5312019-05-14 12:44:37 -07001038 umo: protojson.UnmarshalOptions{AllowPartial: true},
Herbie Ong329be5b2019-03-27 14:47:59 -07001039 inputMessage: &pb2.Requireds{},
1040 inputText: `{
1041 "reqBool": false,
1042 "reqSfixed64": 42,
1043 "reqString": "hello",
1044 "reqEnum": "ONE"
1045}`,
1046 wantMessage: &pb2.Requireds{
Damien Neila8a2cea2019-07-10 16:17:16 -07001047 ReqBool: proto.Bool(false),
1048 ReqSfixed64: proto.Int64(42),
1049 ReqString: proto.String("hello"),
Herbie Ong329be5b2019-03-27 14:47:59 -07001050 ReqEnum: pb2.Enum_ONE.Enum(),
1051 },
1052 }, {
1053 desc: "required fields all set",
1054 inputMessage: &pb2.Requireds{},
1055 inputText: `{
1056 "reqBool": false,
1057 "reqSfixed64": 42,
1058 "reqDouble": 1.23,
1059 "reqString": "hello",
1060 "reqEnum": "ONE",
1061 "reqNested": {}
1062}`,
1063 wantMessage: &pb2.Requireds{
Damien Neila8a2cea2019-07-10 16:17:16 -07001064 ReqBool: proto.Bool(false),
1065 ReqSfixed64: proto.Int64(42),
1066 ReqDouble: proto.Float64(1.23),
1067 ReqString: proto.String("hello"),
Herbie Ong329be5b2019-03-27 14:47:59 -07001068 ReqEnum: pb2.Enum_ONE.Enum(),
1069 ReqNested: &pb2.Nested{},
1070 },
1071 }, {
1072 desc: "indirect required field",
1073 inputMessage: &pb2.IndirectRequired{},
1074 inputText: `{
1075 "optNested": {}
1076}`,
1077 wantMessage: &pb2.IndirectRequired{
1078 OptNested: &pb2.NestedWithRequired{},
1079 },
1080 wantErr: true,
1081 }, {
1082 desc: "indirect required field with AllowPartial",
Damien Neil5c5b5312019-05-14 12:44:37 -07001083 umo: protojson.UnmarshalOptions{AllowPartial: true},
Herbie Ong329be5b2019-03-27 14:47:59 -07001084 inputMessage: &pb2.IndirectRequired{},
1085 inputText: `{
1086 "optNested": {}
1087}`,
1088 wantMessage: &pb2.IndirectRequired{
1089 OptNested: &pb2.NestedWithRequired{},
1090 },
1091 }, {
1092 desc: "indirect required field in repeated",
1093 inputMessage: &pb2.IndirectRequired{},
1094 inputText: `{
1095 "rptNested": [
1096 {"reqString": "one"},
1097 {}
1098 ]
1099}`,
1100 wantMessage: &pb2.IndirectRequired{
1101 RptNested: []*pb2.NestedWithRequired{
1102 {
Damien Neila8a2cea2019-07-10 16:17:16 -07001103 ReqString: proto.String("one"),
Herbie Ong329be5b2019-03-27 14:47:59 -07001104 },
1105 {},
1106 },
1107 },
1108 wantErr: true,
1109 }, {
1110 desc: "indirect required field in repeated with AllowPartial",
Damien Neil5c5b5312019-05-14 12:44:37 -07001111 umo: protojson.UnmarshalOptions{AllowPartial: true},
Herbie Ong329be5b2019-03-27 14:47:59 -07001112 inputMessage: &pb2.IndirectRequired{},
1113 inputText: `{
1114 "rptNested": [
1115 {"reqString": "one"},
1116 {}
1117 ]
1118}`,
1119 wantMessage: &pb2.IndirectRequired{
1120 RptNested: []*pb2.NestedWithRequired{
1121 {
Damien Neila8a2cea2019-07-10 16:17:16 -07001122 ReqString: proto.String("one"),
Herbie Ong329be5b2019-03-27 14:47:59 -07001123 },
1124 {},
1125 },
1126 },
1127 }, {
1128 desc: "indirect required field in map",
1129 inputMessage: &pb2.IndirectRequired{},
1130 inputText: `{
1131 "strToNested": {
1132 "missing": {},
1133 "contains": {
1134 "reqString": "here"
1135 }
1136 }
1137}`,
1138 wantMessage: &pb2.IndirectRequired{
1139 StrToNested: map[string]*pb2.NestedWithRequired{
1140 "missing": &pb2.NestedWithRequired{},
1141 "contains": &pb2.NestedWithRequired{
Damien Neila8a2cea2019-07-10 16:17:16 -07001142 ReqString: proto.String("here"),
Herbie Ong329be5b2019-03-27 14:47:59 -07001143 },
1144 },
1145 },
1146 wantErr: true,
1147 }, {
1148 desc: "indirect required field in map with AllowPartial",
Damien Neil5c5b5312019-05-14 12:44:37 -07001149 umo: protojson.UnmarshalOptions{AllowPartial: true},
Herbie Ong329be5b2019-03-27 14:47:59 -07001150 inputMessage: &pb2.IndirectRequired{},
1151 inputText: `{
1152 "strToNested": {
1153 "missing": {},
1154 "contains": {
1155 "reqString": "here"
1156 }
1157 }
1158}`,
1159 wantMessage: &pb2.IndirectRequired{
1160 StrToNested: map[string]*pb2.NestedWithRequired{
1161 "missing": &pb2.NestedWithRequired{},
1162 "contains": &pb2.NestedWithRequired{
Damien Neila8a2cea2019-07-10 16:17:16 -07001163 ReqString: proto.String("here"),
Herbie Ong329be5b2019-03-27 14:47:59 -07001164 },
1165 },
1166 },
1167 }, {
1168 desc: "indirect required field in oneof",
1169 inputMessage: &pb2.IndirectRequired{},
1170 inputText: `{
1171 "oneofNested": {}
1172}`,
1173 wantMessage: &pb2.IndirectRequired{
1174 Union: &pb2.IndirectRequired_OneofNested{
1175 OneofNested: &pb2.NestedWithRequired{},
1176 },
1177 },
1178 wantErr: true,
1179 }, {
1180 desc: "indirect required field in oneof with AllowPartial",
Damien Neil5c5b5312019-05-14 12:44:37 -07001181 umo: protojson.UnmarshalOptions{AllowPartial: true},
Herbie Ong329be5b2019-03-27 14:47:59 -07001182 inputMessage: &pb2.IndirectRequired{},
1183 inputText: `{
1184 "oneofNested": {}
1185}`,
1186 wantMessage: &pb2.IndirectRequired{
1187 Union: &pb2.IndirectRequired_OneofNested{
1188 OneofNested: &pb2.NestedWithRequired{},
1189 },
1190 },
1191 }, {
Herbie Onge52379a2019-03-15 18:00:19 -07001192 desc: "extensions of non-repeated fields",
1193 inputMessage: &pb2.Extensions{},
1194 inputText: `{
1195 "optString": "non-extension field",
1196 "optBool": true,
1197 "optInt32": 42,
1198 "[pb2.opt_ext_bool]": true,
1199 "[pb2.opt_ext_nested]": {
1200 "optString": "nested in an extension",
Herbie Onge63c4c42019-03-22 22:20:22 -07001201 "optNested": {
1202 "optString": "another nested in an extension"
Herbie Onge52379a2019-03-15 18:00:19 -07001203 }
1204 },
1205 "[pb2.opt_ext_string]": "extension field",
1206 "[pb2.opt_ext_enum]": "TEN"
1207}`,
1208 wantMessage: func() proto.Message {
1209 m := &pb2.Extensions{
Damien Neila8a2cea2019-07-10 16:17:16 -07001210 OptString: proto.String("non-extension field"),
1211 OptBool: proto.Bool(true),
1212 OptInt32: proto.Int32(42),
Herbie Onge52379a2019-03-15 18:00:19 -07001213 }
Damien Neil92f76182019-08-02 16:58:08 -07001214 proto.SetExtension(m, pb2.E_OptExtBool, true)
1215 proto.SetExtension(m, pb2.E_OptExtString, "extension field")
1216 proto.SetExtension(m, pb2.E_OptExtEnum, pb2.Enum_TEN)
1217 proto.SetExtension(m, pb2.E_OptExtNested, &pb2.Nested{
Damien Neila8a2cea2019-07-10 16:17:16 -07001218 OptString: proto.String("nested in an extension"),
Herbie Onge52379a2019-03-15 18:00:19 -07001219 OptNested: &pb2.Nested{
Damien Neila8a2cea2019-07-10 16:17:16 -07001220 OptString: proto.String("another nested in an extension"),
Herbie Onge52379a2019-03-15 18:00:19 -07001221 },
1222 })
1223 return m
1224 }(),
1225 }, {
1226 desc: "extensions of repeated fields",
1227 inputMessage: &pb2.Extensions{},
1228 inputText: `{
1229 "[pb2.rpt_ext_enum]": ["TEN", 101, "ONE"],
1230 "[pb2.rpt_ext_fixed32]": [42, 47],
1231 "[pb2.rpt_ext_nested]": [
1232 {"optString": "one"},
1233 {"optString": "two"},
1234 {"optString": "three"}
1235 ]
1236}`,
1237 wantMessage: func() proto.Message {
1238 m := &pb2.Extensions{}
Damien Neil293dc762019-08-29 11:42:57 -07001239 proto.SetExtension(m, pb2.E_RptExtEnum, []pb2.Enum{pb2.Enum_TEN, 101, pb2.Enum_ONE})
1240 proto.SetExtension(m, pb2.E_RptExtFixed32, []uint32{42, 47})
1241 proto.SetExtension(m, pb2.E_RptExtNested, []*pb2.Nested{
Damien Neila8a2cea2019-07-10 16:17:16 -07001242 &pb2.Nested{OptString: proto.String("one")},
1243 &pb2.Nested{OptString: proto.String("two")},
1244 &pb2.Nested{OptString: proto.String("three")},
Herbie Onge52379a2019-03-15 18:00:19 -07001245 })
1246 return m
1247 }(),
1248 }, {
1249 desc: "extensions of non-repeated fields in another message",
1250 inputMessage: &pb2.Extensions{},
1251 inputText: `{
1252 "[pb2.ExtensionsContainer.opt_ext_bool]": true,
1253 "[pb2.ExtensionsContainer.opt_ext_enum]": "TEN",
1254 "[pb2.ExtensionsContainer.opt_ext_nested]": {
1255 "optString": "nested in an extension",
1256 "optNested": {
1257 "optString": "another nested in an extension"
1258 }
1259 },
1260 "[pb2.ExtensionsContainer.opt_ext_string]": "extension field"
1261}`,
1262 wantMessage: func() proto.Message {
1263 m := &pb2.Extensions{}
Damien Neil92f76182019-08-02 16:58:08 -07001264 proto.SetExtension(m, pb2.E_ExtensionsContainer_OptExtBool, true)
1265 proto.SetExtension(m, pb2.E_ExtensionsContainer_OptExtString, "extension field")
1266 proto.SetExtension(m, pb2.E_ExtensionsContainer_OptExtEnum, pb2.Enum_TEN)
1267 proto.SetExtension(m, pb2.E_ExtensionsContainer_OptExtNested, &pb2.Nested{
Damien Neila8a2cea2019-07-10 16:17:16 -07001268 OptString: proto.String("nested in an extension"),
Herbie Onge52379a2019-03-15 18:00:19 -07001269 OptNested: &pb2.Nested{
Damien Neila8a2cea2019-07-10 16:17:16 -07001270 OptString: proto.String("another nested in an extension"),
Herbie Onge52379a2019-03-15 18:00:19 -07001271 },
1272 })
1273 return m
1274 }(),
1275 }, {
1276 desc: "extensions of repeated fields in another message",
1277 inputMessage: &pb2.Extensions{},
1278 inputText: `{
1279 "optString": "non-extension field",
1280 "optBool": true,
1281 "optInt32": 42,
1282 "[pb2.ExtensionsContainer.rpt_ext_nested]": [
1283 {"optString": "one"},
1284 {"optString": "two"},
1285 {"optString": "three"}
1286 ],
1287 "[pb2.ExtensionsContainer.rpt_ext_enum]": ["TEN", 101, "ONE"],
1288 "[pb2.ExtensionsContainer.rpt_ext_string]": ["hello", "world"]
1289}`,
1290 wantMessage: func() proto.Message {
1291 m := &pb2.Extensions{
Damien Neila8a2cea2019-07-10 16:17:16 -07001292 OptString: proto.String("non-extension field"),
1293 OptBool: proto.Bool(true),
1294 OptInt32: proto.Int32(42),
Herbie Onge52379a2019-03-15 18:00:19 -07001295 }
Damien Neil293dc762019-08-29 11:42:57 -07001296 proto.SetExtension(m, pb2.E_ExtensionsContainer_RptExtEnum, []pb2.Enum{pb2.Enum_TEN, 101, pb2.Enum_ONE})
1297 proto.SetExtension(m, pb2.E_ExtensionsContainer_RptExtString, []string{"hello", "world"})
1298 proto.SetExtension(m, pb2.E_ExtensionsContainer_RptExtNested, []*pb2.Nested{
Damien Neila8a2cea2019-07-10 16:17:16 -07001299 &pb2.Nested{OptString: proto.String("one")},
1300 &pb2.Nested{OptString: proto.String("two")},
1301 &pb2.Nested{OptString: proto.String("three")},
Herbie Onge52379a2019-03-15 18:00:19 -07001302 })
1303 return m
1304 }(),
1305 }, {
1306 desc: "invalid extension field name",
1307 inputMessage: &pb2.Extensions{},
1308 inputText: `{ "[pb2.invalid_message_field]": true }`,
1309 wantErr: true,
1310 }, {
Joe Tsai5ae10aa2019-07-11 18:23:08 -07001311 desc: "extensions of repeated field contains null",
1312 inputMessage: &pb2.Extensions{},
1313 inputText: `{
1314 "[pb2.ExtensionsContainer.rpt_ext_nested]": [
1315 {"optString": "one"},
1316 null,
1317 {"optString": "three"}
1318 ],
1319}`,
1320 wantErr: true,
1321 }, {
Herbie Onge52379a2019-03-15 18:00:19 -07001322 desc: "MessageSet",
1323 inputMessage: &pb2.MessageSet{},
1324 inputText: `{
1325 "[pb2.MessageSetExtension]": {
1326 "optString": "a messageset extension"
1327 },
1328 "[pb2.MessageSetExtension.ext_nested]": {
1329 "optString": "just a regular extension"
1330 },
1331 "[pb2.MessageSetExtension.not_message_set_extension]": {
1332 "optString": "not a messageset extension"
1333 }
1334}`,
1335 wantMessage: func() proto.Message {
1336 m := &pb2.MessageSet{}
Damien Neil92f76182019-08-02 16:58:08 -07001337 proto.SetExtension(m, pb2.E_MessageSetExtension_MessageSetExtension, &pb2.MessageSetExtension{
Damien Neila8a2cea2019-07-10 16:17:16 -07001338 OptString: proto.String("a messageset extension"),
Herbie Onge52379a2019-03-15 18:00:19 -07001339 })
Damien Neil92f76182019-08-02 16:58:08 -07001340 proto.SetExtension(m, pb2.E_MessageSetExtension_NotMessageSetExtension, &pb2.MessageSetExtension{
Damien Neila8a2cea2019-07-10 16:17:16 -07001341 OptString: proto.String("not a messageset extension"),
Herbie Onge52379a2019-03-15 18:00:19 -07001342 })
Damien Neil92f76182019-08-02 16:58:08 -07001343 proto.SetExtension(m, pb2.E_MessageSetExtension_ExtNested, &pb2.Nested{
Damien Neila8a2cea2019-07-10 16:17:16 -07001344 OptString: proto.String("just a regular extension"),
Herbie Onge52379a2019-03-15 18:00:19 -07001345 })
1346 return m
1347 }(),
Joe Tsai1799d112019-08-08 13:31:59 -07001348 skip: !flags.ProtoLegacy,
Herbie Onge52379a2019-03-15 18:00:19 -07001349 }, {
1350 desc: "not real MessageSet 1",
1351 inputMessage: &pb2.FakeMessageSet{},
1352 inputText: `{
1353 "[pb2.FakeMessageSetExtension.message_set_extension]": {
1354 "optString": "not a messageset extension"
1355 }
1356}`,
1357 wantMessage: func() proto.Message {
1358 m := &pb2.FakeMessageSet{}
Damien Neil92f76182019-08-02 16:58:08 -07001359 proto.SetExtension(m, pb2.E_FakeMessageSetExtension_MessageSetExtension, &pb2.FakeMessageSetExtension{
Damien Neila8a2cea2019-07-10 16:17:16 -07001360 OptString: proto.String("not a messageset extension"),
Herbie Onge52379a2019-03-15 18:00:19 -07001361 })
1362 return m
1363 }(),
Joe Tsai1799d112019-08-08 13:31:59 -07001364 skip: !flags.ProtoLegacy,
Herbie Onge52379a2019-03-15 18:00:19 -07001365 }, {
1366 desc: "not real MessageSet 2",
1367 inputMessage: &pb2.FakeMessageSet{},
1368 inputText: `{
1369 "[pb2.FakeMessageSetExtension]": {
1370 "optString": "not a messageset extension"
1371 }
1372}`,
1373 wantErr: true,
Joe Tsai1799d112019-08-08 13:31:59 -07001374 skip: !flags.ProtoLegacy,
Herbie Onge52379a2019-03-15 18:00:19 -07001375 }, {
1376 desc: "not real MessageSet 3",
1377 inputMessage: &pb2.MessageSet{},
1378 inputText: `{
1379 "[pb2.message_set_extension]": {
1380 "optString": "another not a messageset extension"
1381 }
1382}`,
1383 wantMessage: func() proto.Message {
1384 m := &pb2.MessageSet{}
Damien Neil92f76182019-08-02 16:58:08 -07001385 proto.SetExtension(m, pb2.E_MessageSetExtension, &pb2.FakeMessageSetExtension{
Damien Neila8a2cea2019-07-10 16:17:16 -07001386 OptString: proto.String("another not a messageset extension"),
Herbie Onge52379a2019-03-15 18:00:19 -07001387 })
1388 return m
1389 }(),
Joe Tsai1799d112019-08-08 13:31:59 -07001390 skip: !flags.ProtoLegacy,
Herbie Onge63c4c42019-03-22 22:20:22 -07001391 }, {
1392 desc: "Empty",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001393 inputMessage: &emptypb.Empty{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001394 inputText: `{}`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001395 wantMessage: &emptypb.Empty{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001396 }, {
1397 desc: "Empty contains unknown",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001398 inputMessage: &emptypb.Empty{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001399 inputText: `{"unknown": null}`,
1400 wantErr: true,
1401 }, {
1402 desc: "BoolValue false",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001403 inputMessage: &wrapperspb.BoolValue{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001404 inputText: `false`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001405 wantMessage: &wrapperspb.BoolValue{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001406 }, {
1407 desc: "BoolValue true",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001408 inputMessage: &wrapperspb.BoolValue{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001409 inputText: `true`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001410 wantMessage: &wrapperspb.BoolValue{Value: true},
Herbie Onge63c4c42019-03-22 22:20:22 -07001411 }, {
1412 desc: "BoolValue invalid value",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001413 inputMessage: &wrapperspb.BoolValue{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001414 inputText: `{}`,
1415 wantErr: true,
1416 }, {
1417 desc: "Int32Value",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001418 inputMessage: &wrapperspb.Int32Value{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001419 inputText: `42`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001420 wantMessage: &wrapperspb.Int32Value{Value: 42},
Herbie Onge63c4c42019-03-22 22:20:22 -07001421 }, {
1422 desc: "Int32Value in JSON string",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001423 inputMessage: &wrapperspb.Int32Value{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001424 inputText: `"1.23e3"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001425 wantMessage: &wrapperspb.Int32Value{Value: 1230},
Herbie Onge63c4c42019-03-22 22:20:22 -07001426 }, {
1427 desc: "Int64Value",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001428 inputMessage: &wrapperspb.Int64Value{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001429 inputText: `"42"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001430 wantMessage: &wrapperspb.Int64Value{Value: 42},
Herbie Onge63c4c42019-03-22 22:20:22 -07001431 }, {
1432 desc: "UInt32Value",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001433 inputMessage: &wrapperspb.UInt32Value{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001434 inputText: `42`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001435 wantMessage: &wrapperspb.UInt32Value{Value: 42},
Herbie Onge63c4c42019-03-22 22:20:22 -07001436 }, {
1437 desc: "UInt64Value",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001438 inputMessage: &wrapperspb.UInt64Value{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001439 inputText: `"42"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001440 wantMessage: &wrapperspb.UInt64Value{Value: 42},
Herbie Onge63c4c42019-03-22 22:20:22 -07001441 }, {
1442 desc: "FloatValue",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001443 inputMessage: &wrapperspb.FloatValue{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001444 inputText: `1.02`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001445 wantMessage: &wrapperspb.FloatValue{Value: 1.02},
Herbie Onge63c4c42019-03-22 22:20:22 -07001446 }, {
1447 desc: "FloatValue exceeds max limit",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001448 inputMessage: &wrapperspb.FloatValue{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001449 inputText: `1.23+40`,
1450 wantErr: true,
1451 }, {
1452 desc: "FloatValue Infinity",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001453 inputMessage: &wrapperspb.FloatValue{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001454 inputText: `"-Infinity"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001455 wantMessage: &wrapperspb.FloatValue{Value: float32(math.Inf(-1))},
Herbie Onge63c4c42019-03-22 22:20:22 -07001456 }, {
1457 desc: "DoubleValue",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001458 inputMessage: &wrapperspb.DoubleValue{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001459 inputText: `1.02`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001460 wantMessage: &wrapperspb.DoubleValue{Value: 1.02},
Herbie Onge63c4c42019-03-22 22:20:22 -07001461 }, {
1462 desc: "DoubleValue Infinity",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001463 inputMessage: &wrapperspb.DoubleValue{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001464 inputText: `"Infinity"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001465 wantMessage: &wrapperspb.DoubleValue{Value: math.Inf(+1)},
Herbie Onge63c4c42019-03-22 22:20:22 -07001466 }, {
1467 desc: "StringValue empty",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001468 inputMessage: &wrapperspb.StringValue{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001469 inputText: `""`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001470 wantMessage: &wrapperspb.StringValue{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001471 }, {
1472 desc: "StringValue",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001473 inputMessage: &wrapperspb.StringValue{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001474 inputText: `"谷歌"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001475 wantMessage: &wrapperspb.StringValue{Value: "谷歌"},
Herbie Onge63c4c42019-03-22 22:20:22 -07001476 }, {
1477 desc: "StringValue with invalid UTF8 error",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001478 inputMessage: &wrapperspb.StringValue{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001479 inputText: "\"abc\xff\"",
Herbie Onge63c4c42019-03-22 22:20:22 -07001480 wantErr: true,
1481 }, {
1482 desc: "StringValue field with invalid UTF8 error",
1483 inputMessage: &pb2.KnownTypes{},
1484 inputText: "{\n \"optString\": \"abc\xff\"\n}",
Damien Neil8c86fc52019-06-19 09:28:29 -07001485 wantErr: true,
Herbie Onge63c4c42019-03-22 22:20:22 -07001486 }, {
Herbie Ong300b9fe2019-03-29 15:42:20 -07001487 desc: "NullValue field with JSON null",
1488 inputMessage: &pb2.KnownTypes{},
1489 inputText: `{
1490 "optNull": null
1491}`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001492 wantMessage: &pb2.KnownTypes{OptNull: new(structpb.NullValue)},
Herbie Ong300b9fe2019-03-29 15:42:20 -07001493 }, {
1494 desc: "NullValue field with string",
1495 inputMessage: &pb2.KnownTypes{},
1496 inputText: `{
1497 "optNull": "NULL_VALUE"
1498}`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001499 wantMessage: &pb2.KnownTypes{OptNull: new(structpb.NullValue)},
Herbie Ong300b9fe2019-03-29 15:42:20 -07001500 }, {
Herbie Onge63c4c42019-03-22 22:20:22 -07001501 desc: "BytesValue",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001502 inputMessage: &wrapperspb.BytesValue{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001503 inputText: `"aGVsbG8="`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001504 wantMessage: &wrapperspb.BytesValue{Value: []byte("hello")},
Herbie Onge63c4c42019-03-22 22:20:22 -07001505 }, {
1506 desc: "Value null",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001507 inputMessage: &structpb.Value{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001508 inputText: `null`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001509 wantMessage: &structpb.Value{Kind: &structpb.Value_NullValue{}},
Herbie Onge63c4c42019-03-22 22:20:22 -07001510 }, {
1511 desc: "Value field null",
1512 inputMessage: &pb2.KnownTypes{},
1513 inputText: `{
1514 "optValue": null
1515}`,
1516 wantMessage: &pb2.KnownTypes{
Joe Tsaia95b29f2019-05-16 12:47:20 -07001517 OptValue: &structpb.Value{Kind: &structpb.Value_NullValue{}},
Herbie Onge63c4c42019-03-22 22:20:22 -07001518 },
1519 }, {
1520 desc: "Value bool",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001521 inputMessage: &structpb.Value{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001522 inputText: `false`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001523 wantMessage: &structpb.Value{Kind: &structpb.Value_BoolValue{}},
Herbie Onge63c4c42019-03-22 22:20:22 -07001524 }, {
1525 desc: "Value field bool",
1526 inputMessage: &pb2.KnownTypes{},
1527 inputText: `{
1528 "optValue": true
1529}`,
1530 wantMessage: &pb2.KnownTypes{
Joe Tsaia95b29f2019-05-16 12:47:20 -07001531 OptValue: &structpb.Value{Kind: &structpb.Value_BoolValue{true}},
Herbie Onge63c4c42019-03-22 22:20:22 -07001532 },
1533 }, {
1534 desc: "Value number",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001535 inputMessage: &structpb.Value{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001536 inputText: `1.02`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001537 wantMessage: &structpb.Value{Kind: &structpb.Value_NumberValue{1.02}},
Herbie Onge63c4c42019-03-22 22:20:22 -07001538 }, {
1539 desc: "Value field number",
1540 inputMessage: &pb2.KnownTypes{},
1541 inputText: `{
1542 "optValue": 1.02
1543}`,
1544 wantMessage: &pb2.KnownTypes{
Joe Tsaia95b29f2019-05-16 12:47:20 -07001545 OptValue: &structpb.Value{Kind: &structpb.Value_NumberValue{1.02}},
Herbie Onge63c4c42019-03-22 22:20:22 -07001546 },
1547 }, {
1548 desc: "Value string",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001549 inputMessage: &structpb.Value{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001550 inputText: `"hello"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001551 wantMessage: &structpb.Value{Kind: &structpb.Value_StringValue{"hello"}},
Herbie Onge63c4c42019-03-22 22:20:22 -07001552 }, {
1553 desc: "Value string with invalid UTF8",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001554 inputMessage: &structpb.Value{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001555 inputText: "\"\xff\"",
Herbie Onge63c4c42019-03-22 22:20:22 -07001556 wantErr: true,
1557 }, {
1558 desc: "Value field string",
1559 inputMessage: &pb2.KnownTypes{},
1560 inputText: `{
1561 "optValue": "NaN"
1562}`,
1563 wantMessage: &pb2.KnownTypes{
Joe Tsaia95b29f2019-05-16 12:47:20 -07001564 OptValue: &structpb.Value{Kind: &structpb.Value_StringValue{"NaN"}},
Herbie Onge63c4c42019-03-22 22:20:22 -07001565 },
1566 }, {
1567 desc: "Value field string with invalid UTF8",
1568 inputMessage: &pb2.KnownTypes{},
1569 inputText: `{
1570 "optValue": "` + "\xff" + `"
1571}`,
Herbie Onge63c4c42019-03-22 22:20:22 -07001572 wantErr: true,
1573 }, {
1574 desc: "Value empty struct",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001575 inputMessage: &structpb.Value{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001576 inputText: `{}`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001577 wantMessage: &structpb.Value{
1578 Kind: &structpb.Value_StructValue{
1579 &structpb.Struct{Fields: map[string]*structpb.Value{}},
Herbie Onge63c4c42019-03-22 22:20:22 -07001580 },
1581 },
1582 }, {
1583 desc: "Value struct",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001584 inputMessage: &structpb.Value{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001585 inputText: `{
1586 "string": "hello",
1587 "number": 123,
1588 "null": null,
1589 "bool": false,
1590 "struct": {
1591 "string": "world"
1592 },
1593 "list": []
1594}`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001595 wantMessage: &structpb.Value{
1596 Kind: &structpb.Value_StructValue{
1597 &structpb.Struct{
1598 Fields: map[string]*structpb.Value{
1599 "string": {Kind: &structpb.Value_StringValue{"hello"}},
1600 "number": {Kind: &structpb.Value_NumberValue{123}},
1601 "null": {Kind: &structpb.Value_NullValue{}},
1602 "bool": {Kind: &structpb.Value_BoolValue{false}},
Herbie Onge63c4c42019-03-22 22:20:22 -07001603 "struct": {
Joe Tsaia95b29f2019-05-16 12:47:20 -07001604 Kind: &structpb.Value_StructValue{
1605 &structpb.Struct{
1606 Fields: map[string]*structpb.Value{
1607 "string": {Kind: &structpb.Value_StringValue{"world"}},
Herbie Onge63c4c42019-03-22 22:20:22 -07001608 },
1609 },
1610 },
1611 },
1612 "list": {
Joe Tsaia95b29f2019-05-16 12:47:20 -07001613 Kind: &structpb.Value_ListValue{&structpb.ListValue{}},
Herbie Onge63c4c42019-03-22 22:20:22 -07001614 },
1615 },
1616 },
1617 },
1618 },
1619 }, {
1620 desc: "Value struct with invalid UTF8 string",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001621 inputMessage: &structpb.Value{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001622 inputText: "{\"string\": \"abc\xff\"}",
Damien Neil8c86fc52019-06-19 09:28:29 -07001623 wantErr: true,
Herbie Onge63c4c42019-03-22 22:20:22 -07001624 }, {
1625 desc: "Value field struct",
1626 inputMessage: &pb2.KnownTypes{},
1627 inputText: `{
1628 "optValue": {
1629 "string": "hello"
1630 }
1631}`,
1632 wantMessage: &pb2.KnownTypes{
Joe Tsaia95b29f2019-05-16 12:47:20 -07001633 OptValue: &structpb.Value{
1634 Kind: &structpb.Value_StructValue{
1635 &structpb.Struct{
1636 Fields: map[string]*structpb.Value{
1637 "string": {Kind: &structpb.Value_StringValue{"hello"}},
Herbie Onge63c4c42019-03-22 22:20:22 -07001638 },
1639 },
1640 },
1641 },
1642 },
1643 }, {
1644 desc: "Value empty list",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001645 inputMessage: &structpb.Value{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001646 inputText: `[]`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001647 wantMessage: &structpb.Value{
1648 Kind: &structpb.Value_ListValue{
1649 &structpb.ListValue{Values: []*structpb.Value{}},
Herbie Onge63c4c42019-03-22 22:20:22 -07001650 },
1651 },
1652 }, {
1653 desc: "Value list",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001654 inputMessage: &structpb.Value{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001655 inputText: `[
1656 "string",
1657 123,
1658 null,
1659 true,
1660 {},
1661 [
1662 "string",
1663 1.23,
1664 null,
1665 false
1666 ]
1667]`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001668 wantMessage: &structpb.Value{
1669 Kind: &structpb.Value_ListValue{
1670 &structpb.ListValue{
1671 Values: []*structpb.Value{
1672 {Kind: &structpb.Value_StringValue{"string"}},
1673 {Kind: &structpb.Value_NumberValue{123}},
1674 {Kind: &structpb.Value_NullValue{}},
1675 {Kind: &structpb.Value_BoolValue{true}},
1676 {Kind: &structpb.Value_StructValue{&structpb.Struct{}}},
Herbie Onge63c4c42019-03-22 22:20:22 -07001677 {
Joe Tsaia95b29f2019-05-16 12:47:20 -07001678 Kind: &structpb.Value_ListValue{
1679 &structpb.ListValue{
1680 Values: []*structpb.Value{
1681 {Kind: &structpb.Value_StringValue{"string"}},
1682 {Kind: &structpb.Value_NumberValue{1.23}},
1683 {Kind: &structpb.Value_NullValue{}},
1684 {Kind: &structpb.Value_BoolValue{false}},
Herbie Onge63c4c42019-03-22 22:20:22 -07001685 },
1686 },
1687 },
1688 },
1689 },
1690 },
1691 },
1692 },
1693 }, {
1694 desc: "Value list with invalid UTF8 string",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001695 inputMessage: &structpb.Value{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001696 inputText: "[\"abc\xff\"]",
Damien Neil8c86fc52019-06-19 09:28:29 -07001697 wantErr: true,
Herbie Onge63c4c42019-03-22 22:20:22 -07001698 }, {
1699 desc: "Value field list with invalid UTF8 string",
1700 inputMessage: &pb2.KnownTypes{},
1701 inputText: `{
1702 "optValue": [ "` + "abc\xff" + `"]
1703}`,
Herbie Onge63c4c42019-03-22 22:20:22 -07001704 wantErr: true,
1705 }, {
Herbie Ongc4450372019-03-27 09:59:51 -07001706 desc: "Duration empty string",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001707 inputMessage: &durationpb.Duration{},
Herbie Ongc4450372019-03-27 09:59:51 -07001708 inputText: `""`,
1709 wantErr: true,
1710 }, {
1711 desc: "Duration with secs",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001712 inputMessage: &durationpb.Duration{},
Herbie Ongc4450372019-03-27 09:59:51 -07001713 inputText: `"3s"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001714 wantMessage: &durationpb.Duration{Seconds: 3},
Herbie Ongc4450372019-03-27 09:59:51 -07001715 }, {
1716 desc: "Duration with escaped unicode",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001717 inputMessage: &durationpb.Duration{},
Herbie Ongc4450372019-03-27 09:59:51 -07001718 inputText: `"\u0033s"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001719 wantMessage: &durationpb.Duration{Seconds: 3},
Herbie Ongc4450372019-03-27 09:59:51 -07001720 }, {
1721 desc: "Duration with -secs",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001722 inputMessage: &durationpb.Duration{},
Herbie Ongc4450372019-03-27 09:59:51 -07001723 inputText: `"-3s"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001724 wantMessage: &durationpb.Duration{Seconds: -3},
Herbie Ongc4450372019-03-27 09:59:51 -07001725 }, {
Herbie Ong17523eb2019-03-29 17:46:57 -07001726 desc: "Duration with plus sign",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001727 inputMessage: &durationpb.Duration{},
Herbie Ong17523eb2019-03-29 17:46:57 -07001728 inputText: `"+3s"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001729 wantMessage: &durationpb.Duration{Seconds: 3},
Herbie Ong17523eb2019-03-29 17:46:57 -07001730 }, {
Herbie Ongc4450372019-03-27 09:59:51 -07001731 desc: "Duration with nanos",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001732 inputMessage: &durationpb.Duration{},
Herbie Ongc4450372019-03-27 09:59:51 -07001733 inputText: `"0.001s"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001734 wantMessage: &durationpb.Duration{Nanos: 1e6},
Herbie Ongc4450372019-03-27 09:59:51 -07001735 }, {
1736 desc: "Duration with -nanos",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001737 inputMessage: &durationpb.Duration{},
Herbie Ongc4450372019-03-27 09:59:51 -07001738 inputText: `"-0.001s"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001739 wantMessage: &durationpb.Duration{Nanos: -1e6},
Herbie Ongc4450372019-03-27 09:59:51 -07001740 }, {
Herbie Ong17523eb2019-03-29 17:46:57 -07001741 desc: "Duration with -nanos",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001742 inputMessage: &durationpb.Duration{},
Herbie Ong17523eb2019-03-29 17:46:57 -07001743 inputText: `"-.001s"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001744 wantMessage: &durationpb.Duration{Nanos: -1e6},
Herbie Ong17523eb2019-03-29 17:46:57 -07001745 }, {
1746 desc: "Duration with +nanos",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001747 inputMessage: &durationpb.Duration{},
Herbie Ong17523eb2019-03-29 17:46:57 -07001748 inputText: `"+.001s"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001749 wantMessage: &durationpb.Duration{Nanos: 1e6},
Herbie Ong17523eb2019-03-29 17:46:57 -07001750 }, {
Herbie Ongc4450372019-03-27 09:59:51 -07001751 desc: "Duration with -secs -nanos",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001752 inputMessage: &durationpb.Duration{},
Herbie Ongc4450372019-03-27 09:59:51 -07001753 inputText: `"-123.000000450s"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001754 wantMessage: &durationpb.Duration{Seconds: -123, Nanos: -450},
Herbie Ongc4450372019-03-27 09:59:51 -07001755 }, {
1756 desc: "Duration with large secs",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001757 inputMessage: &durationpb.Duration{},
Herbie Ongc4450372019-03-27 09:59:51 -07001758 inputText: `"10000000000.000000001s"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001759 wantMessage: &durationpb.Duration{Seconds: 1e10, Nanos: 1},
Herbie Ongc4450372019-03-27 09:59:51 -07001760 }, {
1761 desc: "Duration with decimal without fractional",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001762 inputMessage: &durationpb.Duration{},
Herbie Ongc4450372019-03-27 09:59:51 -07001763 inputText: `"3.s"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001764 wantMessage: &durationpb.Duration{Seconds: 3},
Herbie Ongc4450372019-03-27 09:59:51 -07001765 }, {
1766 desc: "Duration with decimal without integer",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001767 inputMessage: &durationpb.Duration{},
Herbie Ongc4450372019-03-27 09:59:51 -07001768 inputText: `"0.5s"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001769 wantMessage: &durationpb.Duration{Nanos: 5e8},
Herbie Ongc4450372019-03-27 09:59:51 -07001770 }, {
Herbie Ongad9c1252019-04-24 20:51:28 -07001771 desc: "Duration max value",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001772 inputMessage: &durationpb.Duration{},
Herbie Ongad9c1252019-04-24 20:51:28 -07001773 inputText: `"315576000000.999999999s"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001774 wantMessage: &durationpb.Duration{Seconds: 315576000000, Nanos: 999999999},
Herbie Ongad9c1252019-04-24 20:51:28 -07001775 }, {
1776 desc: "Duration min value",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001777 inputMessage: &durationpb.Duration{},
Herbie Ongad9c1252019-04-24 20:51:28 -07001778 inputText: `"-315576000000.999999999s"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001779 wantMessage: &durationpb.Duration{Seconds: -315576000000, Nanos: -999999999},
Herbie Ongad9c1252019-04-24 20:51:28 -07001780 }, {
Herbie Ongc4450372019-03-27 09:59:51 -07001781 desc: "Duration with +secs out of range",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001782 inputMessage: &durationpb.Duration{},
Herbie Ongc4450372019-03-27 09:59:51 -07001783 inputText: `"315576000001s"`,
1784 wantErr: true,
1785 }, {
1786 desc: "Duration with -secs out of range",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001787 inputMessage: &durationpb.Duration{},
Herbie Ongc4450372019-03-27 09:59:51 -07001788 inputText: `"-315576000001s"`,
1789 wantErr: true,
1790 }, {
1791 desc: "Duration with nanos beyond 9 digits",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001792 inputMessage: &durationpb.Duration{},
Herbie Ong17523eb2019-03-29 17:46:57 -07001793 inputText: `"0.1000000000s"`,
Herbie Ongc4450372019-03-27 09:59:51 -07001794 wantErr: true,
1795 }, {
1796 desc: "Duration without suffix s",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001797 inputMessage: &durationpb.Duration{},
Herbie Ongc4450372019-03-27 09:59:51 -07001798 inputText: `"123"`,
1799 wantErr: true,
1800 }, {
Herbie Ong17523eb2019-03-29 17:46:57 -07001801 desc: "Duration invalid signed fraction",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001802 inputMessage: &durationpb.Duration{},
Herbie Ong17523eb2019-03-29 17:46:57 -07001803 inputText: `"123.+123s"`,
1804 wantErr: true,
1805 }, {
1806 desc: "Duration invalid multiple .",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001807 inputMessage: &durationpb.Duration{},
Herbie Ong17523eb2019-03-29 17:46:57 -07001808 inputText: `"123.123.s"`,
1809 wantErr: true,
1810 }, {
1811 desc: "Duration invalid integer",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001812 inputMessage: &durationpb.Duration{},
Herbie Ong17523eb2019-03-29 17:46:57 -07001813 inputText: `"01s"`,
1814 wantErr: true,
1815 }, {
Herbie Ongc4450372019-03-27 09:59:51 -07001816 desc: "Timestamp zero",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001817 inputMessage: &timestamppb.Timestamp{},
Herbie Ongc4450372019-03-27 09:59:51 -07001818 inputText: `"1970-01-01T00:00:00Z"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001819 wantMessage: &timestamppb.Timestamp{},
Herbie Ongc4450372019-03-27 09:59:51 -07001820 }, {
1821 desc: "Timestamp with tz adjustment",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001822 inputMessage: &timestamppb.Timestamp{},
Herbie Ongc4450372019-03-27 09:59:51 -07001823 inputText: `"1970-01-01T00:00:00+01:00"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001824 wantMessage: &timestamppb.Timestamp{Seconds: -3600},
Herbie Ongc4450372019-03-27 09:59:51 -07001825 }, {
1826 desc: "Timestamp UTC",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001827 inputMessage: &timestamppb.Timestamp{},
Herbie Ongc4450372019-03-27 09:59:51 -07001828 inputText: `"2019-03-19T23:03:21Z"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001829 wantMessage: &timestamppb.Timestamp{Seconds: 1553036601},
Herbie Ongc4450372019-03-27 09:59:51 -07001830 }, {
1831 desc: "Timestamp with escaped unicode",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001832 inputMessage: &timestamppb.Timestamp{},
Herbie Ongc4450372019-03-27 09:59:51 -07001833 inputText: `"2019-0\u0033-19T23:03:21Z"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001834 wantMessage: &timestamppb.Timestamp{Seconds: 1553036601},
Herbie Ongc4450372019-03-27 09:59:51 -07001835 }, {
1836 desc: "Timestamp with nanos",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001837 inputMessage: &timestamppb.Timestamp{},
Herbie Ongc4450372019-03-27 09:59:51 -07001838 inputText: `"2019-03-19T23:03:21.000000001Z"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001839 wantMessage: &timestamppb.Timestamp{Seconds: 1553036601, Nanos: 1},
Herbie Ongc4450372019-03-27 09:59:51 -07001840 }, {
Herbie Ongad9c1252019-04-24 20:51:28 -07001841 desc: "Timestamp max value",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001842 inputMessage: &timestamppb.Timestamp{},
Herbie Ongc4450372019-03-27 09:59:51 -07001843 inputText: `"9999-12-31T23:59:59.999999999Z"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001844 wantMessage: &timestamppb.Timestamp{Seconds: 253402300799, Nanos: 999999999},
Herbie Ongc4450372019-03-27 09:59:51 -07001845 }, {
Herbie Ongad9c1252019-04-24 20:51:28 -07001846 desc: "Timestamp above max value",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001847 inputMessage: &timestamppb.Timestamp{},
Herbie Ongc4450372019-03-27 09:59:51 -07001848 inputText: `"9999-12-31T23:59:59-01:00"`,
1849 wantErr: true,
1850 }, {
Herbie Ongad9c1252019-04-24 20:51:28 -07001851 desc: "Timestamp min value",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001852 inputMessage: &timestamppb.Timestamp{},
Herbie Ongc4450372019-03-27 09:59:51 -07001853 inputText: `"0001-01-01T00:00:00Z"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001854 wantMessage: &timestamppb.Timestamp{Seconds: -62135596800},
Herbie Ongc4450372019-03-27 09:59:51 -07001855 }, {
Herbie Ongad9c1252019-04-24 20:51:28 -07001856 desc: "Timestamp below min value",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001857 inputMessage: &timestamppb.Timestamp{},
Herbie Ongc4450372019-03-27 09:59:51 -07001858 inputText: `"0001-01-01T00:00:00+01:00"`,
1859 wantErr: true,
1860 }, {
1861 desc: "Timestamp with nanos beyond 9 digits",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001862 inputMessage: &timestamppb.Timestamp{},
Herbie Ongc4450372019-03-27 09:59:51 -07001863 inputText: `"1970-01-01T00:00:00.0000000001Z"`,
1864 wantErr: true,
1865 }, {
Herbie Onge63c4c42019-03-22 22:20:22 -07001866 desc: "FieldMask empty",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001867 inputMessage: &fieldmaskpb.FieldMask{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001868 inputText: `""`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001869 wantMessage: &fieldmaskpb.FieldMask{Paths: []string{}},
Herbie Onge63c4c42019-03-22 22:20:22 -07001870 }, {
1871 desc: "FieldMask",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001872 inputMessage: &fieldmaskpb.FieldMask{},
Herbie Onge63c4c42019-03-22 22:20:22 -07001873 inputText: `"foo,fooBar , foo.barQux ,Foo"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001874 wantMessage: &fieldmaskpb.FieldMask{
Herbie Onge63c4c42019-03-22 22:20:22 -07001875 Paths: []string{
1876 "foo",
1877 "foo_bar",
1878 "foo.bar_qux",
1879 "_foo",
1880 },
1881 },
1882 }, {
1883 desc: "FieldMask field",
1884 inputMessage: &pb2.KnownTypes{},
1885 inputText: `{
1886 "optFieldmask": "foo, qux.fooBar"
1887}`,
1888 wantMessage: &pb2.KnownTypes{
Joe Tsaia95b29f2019-05-16 12:47:20 -07001889 OptFieldmask: &fieldmaskpb.FieldMask{
Herbie Onge63c4c42019-03-22 22:20:22 -07001890 Paths: []string{
1891 "foo",
1892 "qux.foo_bar",
1893 },
1894 },
1895 },
Herbie Ong8ac9dd22019-03-27 12:20:50 -07001896 }, {
1897 desc: "Any empty",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001898 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07001899 inputText: `{}`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001900 wantMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07001901 }, {
1902 desc: "Any with non-custom message",
Damien Neil5c5b5312019-05-14 12:44:37 -07001903 umo: protojson.UnmarshalOptions{
Joe Tsai0fc49f82019-05-01 12:29:25 -07001904 Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&pb2.Nested{})),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07001905 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07001906 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07001907 inputText: `{
1908 "@type": "foo/pb2.Nested",
1909 "optString": "embedded inside Any",
1910 "optNested": {
1911 "optString": "inception"
1912 }
1913}`,
1914 wantMessage: func() proto.Message {
1915 m := &pb2.Nested{
Damien Neila8a2cea2019-07-10 16:17:16 -07001916 OptString: proto.String("embedded inside Any"),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07001917 OptNested: &pb2.Nested{
Damien Neila8a2cea2019-07-10 16:17:16 -07001918 OptString: proto.String("inception"),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07001919 },
1920 }
1921 b, err := proto.MarshalOptions{Deterministic: true}.Marshal(m)
1922 if err != nil {
1923 t.Fatalf("error in binary marshaling message for Any.value: %v", err)
1924 }
Joe Tsaia95b29f2019-05-16 12:47:20 -07001925 return &anypb.Any{
Herbie Ong8ac9dd22019-03-27 12:20:50 -07001926 TypeUrl: "foo/pb2.Nested",
1927 Value: b,
1928 }
1929 }(),
1930 }, {
1931 desc: "Any with empty embedded message",
Damien Neil5c5b5312019-05-14 12:44:37 -07001932 umo: protojson.UnmarshalOptions{
Joe Tsai0fc49f82019-05-01 12:29:25 -07001933 Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&pb2.Nested{})),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07001934 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07001935 inputMessage: &anypb.Any{},
Herbie Ong4f0be712019-04-25 17:57:12 -07001936 inputText: `{"@type": "foo/pb2.Nested"}`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001937 wantMessage: &anypb.Any{TypeUrl: "foo/pb2.Nested"},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07001938 }, {
1939 desc: "Any without registered type",
Damien Neil5c5b5312019-05-14 12:44:37 -07001940 umo: protojson.UnmarshalOptions{Resolver: preg.NewTypes()},
Joe Tsaia95b29f2019-05-16 12:47:20 -07001941 inputMessage: &anypb.Any{},
Herbie Ong4f0be712019-04-25 17:57:12 -07001942 inputText: `{"@type": "foo/pb2.Nested"}`,
1943 wantErr: true,
Herbie Ong8ac9dd22019-03-27 12:20:50 -07001944 }, {
Damien Neil0c9f0a92019-06-19 10:41:09 -07001945 desc: "Any with missing required",
Damien Neil5c5b5312019-05-14 12:44:37 -07001946 umo: protojson.UnmarshalOptions{
Joe Tsai0fc49f82019-05-01 12:29:25 -07001947 Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&pb2.PartialRequired{})),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07001948 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07001949 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07001950 inputText: `{
1951 "@type": "pb2.PartialRequired",
1952 "optString": "embedded inside Any"
1953}`,
1954 wantMessage: func() proto.Message {
1955 m := &pb2.PartialRequired{
Damien Neila8a2cea2019-07-10 16:17:16 -07001956 OptString: proto.String("embedded inside Any"),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07001957 }
Damien Neil96c229a2019-04-03 12:17:24 -07001958 b, err := proto.MarshalOptions{
1959 Deterministic: true,
1960 AllowPartial: true,
1961 }.Marshal(m)
Herbie Ong8ac9dd22019-03-27 12:20:50 -07001962 if err != nil {
1963 t.Fatalf("error in binary marshaling message for Any.value: %v", err)
1964 }
Joe Tsaia95b29f2019-05-16 12:47:20 -07001965 return &anypb.Any{
Joe Tsai0fc49f82019-05-01 12:29:25 -07001966 TypeUrl: string(m.ProtoReflect().Descriptor().FullName()),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07001967 Value: b,
1968 }
1969 }(),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07001970 }, {
1971 desc: "Any with partial required and AllowPartial",
Damien Neil5c5b5312019-05-14 12:44:37 -07001972 umo: protojson.UnmarshalOptions{
Herbie Ong8ac9dd22019-03-27 12:20:50 -07001973 AllowPartial: true,
Joe Tsai0fc49f82019-05-01 12:29:25 -07001974 Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&pb2.PartialRequired{})),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07001975 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07001976 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07001977 inputText: `{
1978 "@type": "pb2.PartialRequired",
1979 "optString": "embedded inside Any"
1980}`,
1981 wantMessage: func() proto.Message {
1982 m := &pb2.PartialRequired{
Damien Neila8a2cea2019-07-10 16:17:16 -07001983 OptString: proto.String("embedded inside Any"),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07001984 }
Damien Neil96c229a2019-04-03 12:17:24 -07001985 b, err := proto.MarshalOptions{
1986 Deterministic: true,
1987 AllowPartial: true,
1988 }.Marshal(m)
Herbie Ong8ac9dd22019-03-27 12:20:50 -07001989 if err != nil {
1990 t.Fatalf("error in binary marshaling message for Any.value: %v", err)
1991 }
Joe Tsaia95b29f2019-05-16 12:47:20 -07001992 return &anypb.Any{
Joe Tsai0fc49f82019-05-01 12:29:25 -07001993 TypeUrl: string(m.ProtoReflect().Descriptor().FullName()),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07001994 Value: b,
1995 }
1996 }(),
1997 }, {
1998 desc: "Any with invalid UTF8",
Damien Neil5c5b5312019-05-14 12:44:37 -07001999 umo: protojson.UnmarshalOptions{
Joe Tsai0fc49f82019-05-01 12:29:25 -07002000 Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&pb2.Nested{})),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002001 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07002002 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002003 inputText: `{
2004 "optString": "` + "abc\xff" + `",
2005 "@type": "foo/pb2.Nested"
2006}`,
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002007 wantErr: true,
2008 }, {
2009 desc: "Any with BoolValue",
Damien Neil5c5b5312019-05-14 12:44:37 -07002010 umo: protojson.UnmarshalOptions{
Joe Tsaia95b29f2019-05-16 12:47:20 -07002011 Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&wrapperspb.BoolValue{})),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002012 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07002013 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002014 inputText: `{
2015 "@type": "type.googleapis.com/google.protobuf.BoolValue",
2016 "value": true
2017}`,
2018 wantMessage: func() proto.Message {
Joe Tsaia95b29f2019-05-16 12:47:20 -07002019 m := &wrapperspb.BoolValue{Value: true}
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002020 b, err := proto.MarshalOptions{Deterministic: true}.Marshal(m)
2021 if err != nil {
2022 t.Fatalf("error in binary marshaling message for Any.value: %v", err)
2023 }
Joe Tsaia95b29f2019-05-16 12:47:20 -07002024 return &anypb.Any{
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002025 TypeUrl: "type.googleapis.com/google.protobuf.BoolValue",
2026 Value: b,
2027 }
2028 }(),
2029 }, {
2030 desc: "Any with Empty",
Damien Neil5c5b5312019-05-14 12:44:37 -07002031 umo: protojson.UnmarshalOptions{
Joe Tsaia95b29f2019-05-16 12:47:20 -07002032 Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&emptypb.Empty{})),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002033 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07002034 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002035 inputText: `{
2036 "value": {},
2037 "@type": "type.googleapis.com/google.protobuf.Empty"
2038}`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07002039 wantMessage: &anypb.Any{
Herbie Ong4f0be712019-04-25 17:57:12 -07002040 TypeUrl: "type.googleapis.com/google.protobuf.Empty",
2041 },
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002042 }, {
2043 desc: "Any with missing Empty",
Damien Neil5c5b5312019-05-14 12:44:37 -07002044 umo: protojson.UnmarshalOptions{
Joe Tsaia95b29f2019-05-16 12:47:20 -07002045 Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&emptypb.Empty{})),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002046 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07002047 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002048 inputText: `{
2049 "@type": "type.googleapis.com/google.protobuf.Empty"
2050}`,
2051 wantErr: true,
2052 }, {
2053 desc: "Any with StringValue containing invalid UTF8",
Damien Neil5c5b5312019-05-14 12:44:37 -07002054 umo: protojson.UnmarshalOptions{
Joe Tsaia95b29f2019-05-16 12:47:20 -07002055 Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&wrapperspb.StringValue{})),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002056 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07002057 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002058 inputText: `{
2059 "@type": "google.protobuf.StringValue",
2060 "value": "` + "abc\xff" + `"
2061}`,
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002062 wantErr: true,
2063 }, {
2064 desc: "Any with Int64Value",
Damien Neil5c5b5312019-05-14 12:44:37 -07002065 umo: protojson.UnmarshalOptions{
Joe Tsaia95b29f2019-05-16 12:47:20 -07002066 Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&wrapperspb.Int64Value{})),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002067 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07002068 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002069 inputText: `{
2070 "@type": "google.protobuf.Int64Value",
2071 "value": "42"
2072}`,
2073 wantMessage: func() proto.Message {
Joe Tsaia95b29f2019-05-16 12:47:20 -07002074 m := &wrapperspb.Int64Value{Value: 42}
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002075 b, err := proto.MarshalOptions{Deterministic: true}.Marshal(m)
2076 if err != nil {
2077 t.Fatalf("error in binary marshaling message for Any.value: %v", err)
2078 }
Joe Tsaia95b29f2019-05-16 12:47:20 -07002079 return &anypb.Any{
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002080 TypeUrl: "google.protobuf.Int64Value",
2081 Value: b,
2082 }
2083 }(),
2084 }, {
2085 desc: "Any with invalid Int64Value",
Damien Neil5c5b5312019-05-14 12:44:37 -07002086 umo: protojson.UnmarshalOptions{
Joe Tsaia95b29f2019-05-16 12:47:20 -07002087 Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&wrapperspb.Int64Value{})),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002088 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07002089 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002090 inputText: `{
2091 "@type": "google.protobuf.Int64Value",
2092 "value": "forty-two"
2093}`,
2094 wantErr: true,
2095 }, {
2096 desc: "Any with invalid UInt64Value",
Damien Neil5c5b5312019-05-14 12:44:37 -07002097 umo: protojson.UnmarshalOptions{
Joe Tsaia95b29f2019-05-16 12:47:20 -07002098 Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&wrapperspb.UInt64Value{})),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002099 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07002100 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002101 inputText: `{
2102 "@type": "google.protobuf.UInt64Value",
2103 "value": -42
2104}`,
2105 wantErr: true,
2106 }, {
2107 desc: "Any with Duration",
Damien Neil5c5b5312019-05-14 12:44:37 -07002108 umo: protojson.UnmarshalOptions{
Joe Tsaia95b29f2019-05-16 12:47:20 -07002109 Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&durationpb.Duration{})),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002110 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07002111 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002112 inputText: `{
2113 "@type": "type.googleapis.com/google.protobuf.Duration",
2114 "value": "0s"
2115}`,
2116 wantMessage: func() proto.Message {
Joe Tsaia95b29f2019-05-16 12:47:20 -07002117 m := &durationpb.Duration{}
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002118 b, err := proto.MarshalOptions{Deterministic: true}.Marshal(m)
2119 if err != nil {
2120 t.Fatalf("error in binary marshaling message for Any.value: %v", err)
2121 }
Joe Tsaia95b29f2019-05-16 12:47:20 -07002122 return &anypb.Any{
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002123 TypeUrl: "type.googleapis.com/google.protobuf.Duration",
2124 Value: b,
2125 }
2126 }(),
2127 }, {
2128 desc: "Any with Value of StringValue",
Damien Neil5c5b5312019-05-14 12:44:37 -07002129 umo: protojson.UnmarshalOptions{
Joe Tsaia95b29f2019-05-16 12:47:20 -07002130 Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&structpb.Value{})),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002131 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07002132 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002133 inputText: `{
2134 "@type": "google.protobuf.Value",
2135 "value": "` + "abc\xff" + `"
2136}`,
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002137 wantErr: true,
2138 }, {
2139 desc: "Any with Value of NullValue",
Damien Neil5c5b5312019-05-14 12:44:37 -07002140 umo: protojson.UnmarshalOptions{
Joe Tsaia95b29f2019-05-16 12:47:20 -07002141 Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&structpb.Value{})),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002142 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07002143 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002144 inputText: `{
2145 "@type": "google.protobuf.Value",
2146 "value": null
2147}`,
2148 wantMessage: func() proto.Message {
Joe Tsaia95b29f2019-05-16 12:47:20 -07002149 m := &structpb.Value{Kind: &structpb.Value_NullValue{}}
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002150 b, err := proto.MarshalOptions{Deterministic: true}.Marshal(m)
2151 if err != nil {
2152 t.Fatalf("error in binary marshaling message for Any.value: %v", err)
2153 }
Joe Tsaia95b29f2019-05-16 12:47:20 -07002154 return &anypb.Any{
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002155 TypeUrl: "google.protobuf.Value",
2156 Value: b,
2157 }
2158 }(),
2159 }, {
2160 desc: "Any with Struct",
Damien Neil5c5b5312019-05-14 12:44:37 -07002161 umo: protojson.UnmarshalOptions{
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002162 Resolver: preg.NewTypes(
Joe Tsaia95b29f2019-05-16 12:47:20 -07002163 pimpl.Export{}.MessageTypeOf(&structpb.Struct{}),
2164 pimpl.Export{}.MessageTypeOf(&structpb.Value{}),
2165 pimpl.Export{}.MessageTypeOf(&wrapperspb.BoolValue{}),
2166 pimpl.Export{}.EnumTypeOf(structpb.NullValue_NULL_VALUE),
2167 pimpl.Export{}.MessageTypeOf(&wrapperspb.StringValue{}),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002168 ),
2169 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07002170 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002171 inputText: `{
2172 "@type": "google.protobuf.Struct",
2173 "value": {
2174 "bool": true,
2175 "null": null,
2176 "string": "hello",
2177 "struct": {
2178 "string": "world"
2179 }
2180 }
2181}`,
2182 wantMessage: func() proto.Message {
Joe Tsaia95b29f2019-05-16 12:47:20 -07002183 m := &structpb.Struct{
2184 Fields: map[string]*structpb.Value{
2185 "bool": {Kind: &structpb.Value_BoolValue{true}},
2186 "null": {Kind: &structpb.Value_NullValue{}},
2187 "string": {Kind: &structpb.Value_StringValue{"hello"}},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002188 "struct": {
Joe Tsaia95b29f2019-05-16 12:47:20 -07002189 Kind: &structpb.Value_StructValue{
2190 &structpb.Struct{
2191 Fields: map[string]*structpb.Value{
2192 "string": {Kind: &structpb.Value_StringValue{"world"}},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002193 },
2194 },
2195 },
2196 },
2197 },
2198 }
2199 b, err := proto.MarshalOptions{Deterministic: true}.Marshal(m)
2200 if err != nil {
2201 t.Fatalf("error in binary marshaling message for Any.value: %v", err)
2202 }
Joe Tsaia95b29f2019-05-16 12:47:20 -07002203 return &anypb.Any{
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002204 TypeUrl: "google.protobuf.Struct",
2205 Value: b,
2206 }
2207 }(),
2208 }, {
2209 desc: "Any with missing @type",
Damien Neil5c5b5312019-05-14 12:44:37 -07002210 umo: protojson.UnmarshalOptions{},
Joe Tsaia95b29f2019-05-16 12:47:20 -07002211 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002212 inputText: `{
2213 "value": {}
2214}`,
2215 wantErr: true,
2216 }, {
2217 desc: "Any with empty @type",
Joe Tsaia95b29f2019-05-16 12:47:20 -07002218 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002219 inputText: `{
2220 "@type": ""
2221}`,
2222 wantErr: true,
2223 }, {
2224 desc: "Any with duplicate @type",
Damien Neil5c5b5312019-05-14 12:44:37 -07002225 umo: protojson.UnmarshalOptions{
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002226 Resolver: preg.NewTypes(
Joe Tsai0fc49f82019-05-01 12:29:25 -07002227 pimpl.Export{}.MessageTypeOf(&pb2.Nested{}),
Joe Tsaia95b29f2019-05-16 12:47:20 -07002228 pimpl.Export{}.MessageTypeOf(&wrapperspb.StringValue{}),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002229 ),
2230 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07002231 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002232 inputText: `{
2233 "@type": "google.protobuf.StringValue",
2234 "value": "hello",
2235 "@type": "pb2.Nested"
2236}`,
2237 wantErr: true,
2238 }, {
2239 desc: "Any with duplicate value",
Damien Neil5c5b5312019-05-14 12:44:37 -07002240 umo: protojson.UnmarshalOptions{
Joe Tsaia95b29f2019-05-16 12:47:20 -07002241 Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&wrapperspb.StringValue{})),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002242 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07002243 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002244 inputText: `{
2245 "@type": "google.protobuf.StringValue",
2246 "value": "hello",
2247 "value": "world"
2248}`,
2249 wantErr: true,
2250 }, {
2251 desc: "Any with unknown field",
Damien Neil5c5b5312019-05-14 12:44:37 -07002252 umo: protojson.UnmarshalOptions{
Joe Tsai0fc49f82019-05-01 12:29:25 -07002253 Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&pb2.Nested{})),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002254 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07002255 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002256 inputText: `{
2257 "@type": "pb2.Nested",
2258 "optString": "hello",
2259 "unknown": "world"
2260}`,
2261 wantErr: true,
2262 }, {
2263 desc: "Any with embedded type containing Any",
Damien Neil5c5b5312019-05-14 12:44:37 -07002264 umo: protojson.UnmarshalOptions{
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002265 Resolver: preg.NewTypes(
Joe Tsai0fc49f82019-05-01 12:29:25 -07002266 pimpl.Export{}.MessageTypeOf(&pb2.KnownTypes{}),
Joe Tsaia95b29f2019-05-16 12:47:20 -07002267 pimpl.Export{}.MessageTypeOf(&anypb.Any{}),
2268 pimpl.Export{}.MessageTypeOf(&wrapperspb.StringValue{}),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002269 ),
2270 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07002271 inputMessage: &anypb.Any{},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002272 inputText: `{
2273 "@type": "pb2.KnownTypes",
2274 "optAny": {
2275 "@type": "google.protobuf.StringValue",
2276 "value": "` + "abc\xff" + `"
2277 }
2278}`,
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002279 wantErr: true,
2280 }, {
2281 desc: "well known types as field values",
Damien Neil5c5b5312019-05-14 12:44:37 -07002282 umo: protojson.UnmarshalOptions{
Joe Tsaia95b29f2019-05-16 12:47:20 -07002283 Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&emptypb.Empty{})),
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002284 },
2285 inputMessage: &pb2.KnownTypes{},
2286 inputText: `{
2287 "optBool": false,
2288 "optInt32": 42,
2289 "optInt64": "42",
2290 "optUint32": 42,
2291 "optUint64": "42",
2292 "optFloat": 1.23,
2293 "optDouble": 3.1415,
2294 "optString": "hello",
2295 "optBytes": "aGVsbG8=",
2296 "optDuration": "123s",
2297 "optTimestamp": "2019-03-19T23:03:21Z",
2298 "optStruct": {
2299 "string": "hello"
2300 },
2301 "optList": [
2302 null,
2303 "",
2304 {},
2305 []
2306 ],
2307 "optValue": "world",
2308 "optEmpty": {},
2309 "optAny": {
2310 "@type": "google.protobuf.Empty",
2311 "value": {}
2312 },
2313 "optFieldmask": "fooBar,barFoo"
2314}`,
2315 wantMessage: &pb2.KnownTypes{
Joe Tsaia95b29f2019-05-16 12:47:20 -07002316 OptBool: &wrapperspb.BoolValue{Value: false},
2317 OptInt32: &wrapperspb.Int32Value{Value: 42},
2318 OptInt64: &wrapperspb.Int64Value{Value: 42},
2319 OptUint32: &wrapperspb.UInt32Value{Value: 42},
2320 OptUint64: &wrapperspb.UInt64Value{Value: 42},
2321 OptFloat: &wrapperspb.FloatValue{Value: 1.23},
2322 OptDouble: &wrapperspb.DoubleValue{Value: 3.1415},
2323 OptString: &wrapperspb.StringValue{Value: "hello"},
2324 OptBytes: &wrapperspb.BytesValue{Value: []byte("hello")},
2325 OptDuration: &durationpb.Duration{Seconds: 123},
2326 OptTimestamp: &timestamppb.Timestamp{Seconds: 1553036601},
2327 OptStruct: &structpb.Struct{
2328 Fields: map[string]*structpb.Value{
2329 "string": {Kind: &structpb.Value_StringValue{"hello"}},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002330 },
2331 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07002332 OptList: &structpb.ListValue{
2333 Values: []*structpb.Value{
2334 {Kind: &structpb.Value_NullValue{}},
2335 {Kind: &structpb.Value_StringValue{}},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002336 {
Joe Tsaia95b29f2019-05-16 12:47:20 -07002337 Kind: &structpb.Value_StructValue{
2338 &structpb.Struct{Fields: map[string]*structpb.Value{}},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002339 },
2340 },
2341 {
Joe Tsaia95b29f2019-05-16 12:47:20 -07002342 Kind: &structpb.Value_ListValue{
2343 &structpb.ListValue{Values: []*structpb.Value{}},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002344 },
2345 },
2346 },
2347 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07002348 OptValue: &structpb.Value{
2349 Kind: &structpb.Value_StringValue{"world"},
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002350 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07002351 OptEmpty: &emptypb.Empty{},
2352 OptAny: &anypb.Any{
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002353 TypeUrl: "google.protobuf.Empty",
2354 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07002355 OptFieldmask: &fieldmaskpb.FieldMask{
Herbie Ong8ac9dd22019-03-27 12:20:50 -07002356 Paths: []string{"foo_bar", "bar_foo"},
2357 },
2358 },
Herbie Ong4f0be712019-04-25 17:57:12 -07002359 }, {
2360 desc: "DiscardUnknown: regular messages",
Damien Neil5c5b5312019-05-14 12:44:37 -07002361 umo: protojson.UnmarshalOptions{DiscardUnknown: true},
Herbie Ong4f0be712019-04-25 17:57:12 -07002362 inputMessage: &pb3.Nests{},
2363 inputText: `{
2364 "sNested": {
2365 "unknown": {
2366 "foo": 1,
2367 "bar": [1, 2, 3]
2368 }
2369 },
2370 "unknown": "not known"
2371}`,
2372 wantMessage: &pb3.Nests{SNested: &pb3.Nested{}},
2373 }, {
2374 desc: "DiscardUnknown: repeated",
Damien Neil5c5b5312019-05-14 12:44:37 -07002375 umo: protojson.UnmarshalOptions{DiscardUnknown: true},
Herbie Ong4f0be712019-04-25 17:57:12 -07002376 inputMessage: &pb2.Nests{},
2377 inputText: `{
2378 "rptNested": [
2379 {"unknown": "blah"},
2380 {"optString": "hello"}
2381 ]
2382}`,
2383 wantMessage: &pb2.Nests{
2384 RptNested: []*pb2.Nested{
2385 {},
Damien Neila8a2cea2019-07-10 16:17:16 -07002386 {OptString: proto.String("hello")},
Herbie Ong4f0be712019-04-25 17:57:12 -07002387 },
2388 },
2389 }, {
2390 desc: "DiscardUnknown: map",
Damien Neil5c5b5312019-05-14 12:44:37 -07002391 umo: protojson.UnmarshalOptions{DiscardUnknown: true},
Herbie Ong4f0be712019-04-25 17:57:12 -07002392 inputMessage: &pb3.Maps{},
2393 inputText: `{
2394 "strToNested": {
2395 "nested_one": {
2396 "unknown": "what you see is not"
2397 }
2398 }
2399}`,
2400 wantMessage: &pb3.Maps{
2401 StrToNested: map[string]*pb3.Nested{
2402 "nested_one": {},
2403 },
2404 },
2405 }, {
2406 desc: "DiscardUnknown: extension",
Damien Neil5c5b5312019-05-14 12:44:37 -07002407 umo: protojson.UnmarshalOptions{DiscardUnknown: true},
Herbie Ong4f0be712019-04-25 17:57:12 -07002408 inputMessage: &pb2.Extensions{},
2409 inputText: `{
2410 "[pb2.opt_ext_nested]": {
2411 "unknown": []
2412 }
2413}`,
2414 wantMessage: func() proto.Message {
2415 m := &pb2.Extensions{}
Damien Neil92f76182019-08-02 16:58:08 -07002416 proto.SetExtension(m, pb2.E_OptExtNested, &pb2.Nested{})
Herbie Ong4f0be712019-04-25 17:57:12 -07002417 return m
2418 }(),
2419 }, {
2420 desc: "DiscardUnknown: Empty",
Damien Neil5c5b5312019-05-14 12:44:37 -07002421 umo: protojson.UnmarshalOptions{DiscardUnknown: true},
Joe Tsaia95b29f2019-05-16 12:47:20 -07002422 inputMessage: &emptypb.Empty{},
Herbie Ong4f0be712019-04-25 17:57:12 -07002423 inputText: `{"unknown": "something"}`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07002424 wantMessage: &emptypb.Empty{},
Herbie Ong4f0be712019-04-25 17:57:12 -07002425 }, {
2426 desc: "DiscardUnknown: Any without type",
Damien Neil5c5b5312019-05-14 12:44:37 -07002427 umo: protojson.UnmarshalOptions{DiscardUnknown: true},
Joe Tsaia95b29f2019-05-16 12:47:20 -07002428 inputMessage: &anypb.Any{},
Herbie Ong4f0be712019-04-25 17:57:12 -07002429 inputText: `{
2430 "value": {"foo": "bar"},
2431 "unknown": true
2432}`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07002433 wantMessage: &anypb.Any{},
Herbie Ong4f0be712019-04-25 17:57:12 -07002434 }, {
2435 desc: "DiscardUnknown: Any",
Damien Neil5c5b5312019-05-14 12:44:37 -07002436 umo: protojson.UnmarshalOptions{
Herbie Ong4f0be712019-04-25 17:57:12 -07002437 DiscardUnknown: true,
Joe Tsai0fc49f82019-05-01 12:29:25 -07002438 Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&pb2.Nested{})),
Herbie Ong4f0be712019-04-25 17:57:12 -07002439 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07002440 inputMessage: &anypb.Any{},
Herbie Ong4f0be712019-04-25 17:57:12 -07002441 inputText: `{
2442 "@type": "foo/pb2.Nested",
2443 "unknown": "none"
2444}`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07002445 wantMessage: &anypb.Any{
Herbie Ong4f0be712019-04-25 17:57:12 -07002446 TypeUrl: "foo/pb2.Nested",
2447 },
2448 }, {
2449 desc: "DiscardUnknown: Any with Empty",
Damien Neil5c5b5312019-05-14 12:44:37 -07002450 umo: protojson.UnmarshalOptions{
Herbie Ong4f0be712019-04-25 17:57:12 -07002451 DiscardUnknown: true,
Joe Tsaia95b29f2019-05-16 12:47:20 -07002452 Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&emptypb.Empty{})),
Herbie Ong4f0be712019-04-25 17:57:12 -07002453 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07002454 inputMessage: &anypb.Any{},
Herbie Ong4f0be712019-04-25 17:57:12 -07002455 inputText: `{
2456 "@type": "type.googleapis.com/google.protobuf.Empty",
2457 "value": {"unknown": 47}
2458}`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07002459 wantMessage: &anypb.Any{
Herbie Ong4f0be712019-04-25 17:57:12 -07002460 TypeUrl: "type.googleapis.com/google.protobuf.Empty",
2461 },
Joe Tsaid47ea192019-07-09 22:38:15 -07002462 }, {
2463 desc: "weak fields",
2464 inputMessage: &testpb.TestWeak{},
2465 inputText: `{"weak_message1":{"a":1}}`,
2466 wantMessage: func() *testpb.TestWeak {
2467 m := new(testpb.TestWeak)
2468 m.SetWeakMessage1(&weakpb.WeakImportMessage1{A: proto.Int32(1)})
2469 return m
2470 }(),
Joe Tsai1799d112019-08-08 13:31:59 -07002471 skip: !flags.ProtoLegacy,
Joe Tsaid47ea192019-07-09 22:38:15 -07002472 }, {
2473 desc: "weak fields; unknown field",
2474 inputMessage: &testpb.TestWeak{},
2475 inputText: `{"weak_message1":{"a":1}, "weak_message2":{"a":1}}`,
2476 wantErr: true, // weak_message2 is unknown since the package containing it is not imported
Joe Tsai1799d112019-08-08 13:31:59 -07002477 skip: !flags.ProtoLegacy,
Herbie Ongc96a79d2019-03-08 10:49:17 -08002478 }}
2479
2480 for _, tt := range tests {
2481 tt := tt
Joe Tsaid47ea192019-07-09 22:38:15 -07002482 if tt.skip {
2483 continue
2484 }
Herbie Ongc96a79d2019-03-08 10:49:17 -08002485 t.Run(tt.desc, func(t *testing.T) {
Joe Tsaicdb77732019-05-14 16:05:06 -07002486 err := tt.umo.Unmarshal([]byte(tt.inputText), tt.inputMessage)
Herbie Ongc96a79d2019-03-08 10:49:17 -08002487 if err != nil && !tt.wantErr {
2488 t.Errorf("Unmarshal() returned error: %v\n\n", err)
2489 }
2490 if err == nil && tt.wantErr {
2491 t.Error("Unmarshal() got nil error, want error\n\n")
2492 }
Joe Tsai8d30bbe2019-05-16 15:53:25 -07002493 if tt.wantMessage != nil && !proto.Equal(tt.inputMessage, tt.wantMessage) {
Herbie Ongc96a79d2019-03-08 10:49:17 -08002494 t.Errorf("Unmarshal()\n<got>\n%v\n<want>\n%v\n", tt.inputMessage, tt.wantMessage)
2495 }
2496 })
2497 }
2498}