blob: 32d9be812f6777a5121c8b66c7a0a37cb5f5936d [file] [log] [blame]
Herbie Ong800c9902018-12-06 15:28:53 -08001// Copyright 2018 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 prototext_test
Herbie Ong800c9902018-12-06 15:28:53 -08006
7import (
8 "math"
9 "testing"
10
11 protoV1 "github.com/golang/protobuf/proto"
Damien Neil5c5b5312019-05-14 12:44:37 -070012 "google.golang.org/protobuf/encoding/prototext"
Damien Neile89e6242019-05-13 23:55:40 -070013 pimpl "google.golang.org/protobuf/internal/impl"
14 "google.golang.org/protobuf/internal/scalar"
15 "google.golang.org/protobuf/proto"
16 preg "google.golang.org/protobuf/reflect/protoregistry"
Herbie Ong800c9902018-12-06 15:28:53 -080017
Damien Neile89e6242019-05-13 23:55:40 -070018 "google.golang.org/protobuf/encoding/testprotos/pb2"
19 "google.golang.org/protobuf/encoding/testprotos/pb3"
Joe Tsaia95b29f2019-05-16 12:47:20 -070020 "google.golang.org/protobuf/types/known/anypb"
Herbie Ong800c9902018-12-06 15:28:53 -080021)
22
23func TestUnmarshal(t *testing.T) {
Herbie Ong800c9902018-12-06 15:28:53 -080024 tests := []struct {
25 desc string
Damien Neil5c5b5312019-05-14 12:44:37 -070026 umo prototext.UnmarshalOptions
Herbie Ong70651952018-12-13 14:19:50 -080027 inputMessage proto.Message
Herbie Ong800c9902018-12-06 15:28:53 -080028 inputText string
Herbie Ong70651952018-12-13 14:19:50 -080029 wantMessage proto.Message
Herbie Ong300cff02019-03-20 18:05:16 -070030 wantErr bool // TODO: Verify error message content.
Herbie Ong800c9902018-12-06 15:28:53 -080031 }{{
32 desc: "proto2 empty message",
33 inputMessage: &pb2.Scalars{},
34 wantMessage: &pb2.Scalars{},
35 }, {
Herbie Ong8170d692019-02-13 14:13:21 -080036 desc: "proto2 optional scalars set to zero values",
Herbie Ong800c9902018-12-06 15:28:53 -080037 inputMessage: &pb2.Scalars{},
38 inputText: `opt_bool: false
39opt_int32: 0
40opt_int64: 0
41opt_uint32: 0
42opt_uint64: 0
43opt_sint32: 0
44opt_sint64: 0
45opt_fixed32: 0
46opt_fixed64: 0
47opt_sfixed32: 0
48opt_sfixed64: 0
49opt_float: 0
50opt_double: 0
51opt_bytes: ""
52opt_string: ""
53`,
54 wantMessage: &pb2.Scalars{
55 OptBool: scalar.Bool(false),
56 OptInt32: scalar.Int32(0),
57 OptInt64: scalar.Int64(0),
58 OptUint32: scalar.Uint32(0),
59 OptUint64: scalar.Uint64(0),
60 OptSint32: scalar.Int32(0),
61 OptSint64: scalar.Int64(0),
62 OptFixed32: scalar.Uint32(0),
63 OptFixed64: scalar.Uint64(0),
64 OptSfixed32: scalar.Int32(0),
65 OptSfixed64: scalar.Int64(0),
66 OptFloat: scalar.Float32(0),
67 OptDouble: scalar.Float64(0),
68 OptBytes: []byte{},
69 OptString: scalar.String(""),
70 },
71 }, {
Herbie Ong8170d692019-02-13 14:13:21 -080072 desc: "proto3 scalars set to zero values",
Herbie Ong800c9902018-12-06 15:28:53 -080073 inputMessage: &pb3.Scalars{},
74 inputText: `s_bool: false
75s_int32: 0
76s_int64: 0
77s_uint32: 0
78s_uint64: 0
79s_sint32: 0
80s_sint64: 0
81s_fixed32: 0
82s_fixed64: 0
83s_sfixed32: 0
84s_sfixed64: 0
85s_float: 0
86s_double: 0
87s_bytes: ""
88s_string: ""
89`,
90 wantMessage: &pb3.Scalars{},
91 }, {
Herbie Ong8170d692019-02-13 14:13:21 -080092 desc: "proto2 optional scalars",
Herbie Ong800c9902018-12-06 15:28:53 -080093 inputMessage: &pb2.Scalars{},
94 inputText: `opt_bool: true
95opt_int32: 255
96opt_int64: 3735928559
97opt_uint32: 0xff
98opt_uint64: 0xdeadbeef
99opt_sint32: -1001
100opt_sint64: -0xffff
101opt_fixed64: 64
102opt_sfixed32: -32
103opt_float: 1.234
104opt_double: 1.23e+100
105opt_bytes: "\xe8\xb0\xb7\xe6\xad\x8c"
106opt_string: "谷歌"
107`,
108 wantMessage: &pb2.Scalars{
109 OptBool: scalar.Bool(true),
110 OptInt32: scalar.Int32(0xff),
111 OptInt64: scalar.Int64(0xdeadbeef),
112 OptUint32: scalar.Uint32(0xff),
113 OptUint64: scalar.Uint64(0xdeadbeef),
114 OptSint32: scalar.Int32(-1001),
115 OptSint64: scalar.Int64(-0xffff),
116 OptFixed64: scalar.Uint64(64),
117 OptSfixed32: scalar.Int32(-32),
118 OptFloat: scalar.Float32(1.234),
119 OptDouble: scalar.Float64(1.23e100),
120 OptBytes: []byte("\xe8\xb0\xb7\xe6\xad\x8c"),
121 OptString: scalar.String("谷歌"),
122 },
123 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800124 desc: "proto3 scalars",
Herbie Ong800c9902018-12-06 15:28:53 -0800125 inputMessage: &pb3.Scalars{},
126 inputText: `s_bool: true
127s_int32: 255
128s_int64: 3735928559
129s_uint32: 0xff
130s_uint64: 0xdeadbeef
131s_sint32: -1001
132s_sint64: -0xffff
133s_fixed64: 64
134s_sfixed32: -32
135s_float: 1.234
136s_double: 1.23e+100
137s_bytes: "\xe8\xb0\xb7\xe6\xad\x8c"
138s_string: "谷歌"
139`,
140 wantMessage: &pb3.Scalars{
141 SBool: true,
142 SInt32: 0xff,
143 SInt64: 0xdeadbeef,
144 SUint32: 0xff,
145 SUint64: 0xdeadbeef,
146 SSint32: -1001,
147 SSint64: -0xffff,
148 SFixed64: 64,
149 SSfixed32: -32,
150 SFloat: 1.234,
151 SDouble: 1.23e100,
152 SBytes: []byte("\xe8\xb0\xb7\xe6\xad\x8c"),
153 SString: "谷歌",
154 },
155 }, {
Herbie Ong21a39742019-04-08 17:32:44 -0700156 desc: "string with invalid UTF-8",
157 inputMessage: &pb3.Scalars{},
158 inputText: `s_string: "abc\xff"`,
Damien Neil8c86fc52019-06-19 09:28:29 -0700159 wantErr: true,
Herbie Ong21a39742019-04-08 17:32:44 -0700160 }, {
Herbie Ong800c9902018-12-06 15:28:53 -0800161 desc: "proto2 message contains unknown field",
162 inputMessage: &pb2.Scalars{},
163 inputText: "unknown_field: 123",
164 wantErr: true,
165 }, {
166 desc: "proto3 message contains unknown field",
167 inputMessage: &pb3.Scalars{},
168 inputText: "unknown_field: 456",
169 wantErr: true,
170 }, {
171 desc: "proto2 numeric key field",
172 inputMessage: &pb2.Scalars{},
173 inputText: "1: true",
174 wantErr: true,
175 }, {
176 desc: "proto3 numeric key field",
177 inputMessage: &pb3.Scalars{},
178 inputText: "1: true",
179 wantErr: true,
180 }, {
181 desc: "invalid bool value",
182 inputMessage: &pb3.Scalars{},
183 inputText: "s_bool: 123",
184 wantErr: true,
185 }, {
186 desc: "invalid int32 value",
187 inputMessage: &pb3.Scalars{},
188 inputText: "s_int32: not_a_num",
189 wantErr: true,
190 }, {
191 desc: "invalid int64 value",
192 inputMessage: &pb3.Scalars{},
193 inputText: "s_int64: 'not a num either'",
194 wantErr: true,
195 }, {
196 desc: "invalid uint32 value",
197 inputMessage: &pb3.Scalars{},
198 inputText: "s_fixed32: -42",
199 wantErr: true,
200 }, {
201 desc: "invalid uint64 value",
202 inputMessage: &pb3.Scalars{},
203 inputText: "s_uint64: -47",
204 wantErr: true,
205 }, {
206 desc: "invalid sint32 value",
207 inputMessage: &pb3.Scalars{},
208 inputText: "s_sint32: '42'",
209 wantErr: true,
210 }, {
211 desc: "invalid sint64 value",
212 inputMessage: &pb3.Scalars{},
213 inputText: "s_sint64: '-47'",
214 wantErr: true,
215 }, {
216 desc: "invalid fixed32 value",
217 inputMessage: &pb3.Scalars{},
218 inputText: "s_fixed32: -42",
219 wantErr: true,
220 }, {
221 desc: "invalid fixed64 value",
222 inputMessage: &pb3.Scalars{},
223 inputText: "s_fixed64: -42",
224 wantErr: true,
225 }, {
226 desc: "invalid sfixed32 value",
227 inputMessage: &pb3.Scalars{},
228 inputText: "s_sfixed32: 'not valid'",
229 wantErr: true,
230 }, {
231 desc: "invalid sfixed64 value",
232 inputMessage: &pb3.Scalars{},
233 inputText: "s_sfixed64: bad",
234 wantErr: true,
235 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800236 desc: "float positive infinity",
Herbie Ong800c9902018-12-06 15:28:53 -0800237 inputMessage: &pb3.Scalars{},
238 inputText: "s_float: inf",
239 wantMessage: &pb3.Scalars{
240 SFloat: float32(math.Inf(1)),
241 },
242 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800243 desc: "float negative infinity",
Herbie Ong800c9902018-12-06 15:28:53 -0800244 inputMessage: &pb3.Scalars{},
245 inputText: "s_float: -inf",
246 wantMessage: &pb3.Scalars{
247 SFloat: float32(math.Inf(-1)),
248 },
249 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800250 desc: "double positive infinity",
Herbie Ong800c9902018-12-06 15:28:53 -0800251 inputMessage: &pb3.Scalars{},
252 inputText: "s_double: inf",
253 wantMessage: &pb3.Scalars{
254 SDouble: math.Inf(1),
255 },
256 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800257 desc: "double negative infinity",
Herbie Ong800c9902018-12-06 15:28:53 -0800258 inputMessage: &pb3.Scalars{},
259 inputText: "s_double: -inf",
260 wantMessage: &pb3.Scalars{
261 SDouble: math.Inf(-1),
262 },
263 }, {
264 desc: "invalid string value",
265 inputMessage: &pb3.Scalars{},
266 inputText: "s_string: invalid_string",
267 wantErr: true,
268 }, {
269 desc: "proto2 bytes set to empty string",
270 inputMessage: &pb2.Scalars{},
271 inputText: "opt_bytes: ''",
272 wantMessage: &pb2.Scalars{
273 OptBytes: []byte(""),
274 },
275 }, {
276 desc: "proto3 bytes set to empty string",
277 inputMessage: &pb3.Scalars{},
278 inputText: "s_bytes: ''",
279 wantMessage: &pb3.Scalars{},
280 }, {
281 desc: "proto2 duplicate singular field",
282 inputMessage: &pb2.Scalars{},
283 inputText: `
284opt_bool: true
285opt_bool: false
286`,
287 wantErr: true,
288 }, {
Herbie Ong800c9902018-12-06 15:28:53 -0800289 desc: "proto2 more duplicate singular field",
290 inputMessage: &pb2.Scalars{},
291 inputText: `
292opt_bool: true
293opt_string: "hello"
294opt_bool: false
295`,
296 wantErr: true,
297 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800298 desc: "proto2 invalid singular field",
299 inputMessage: &pb2.Scalars{},
300 inputText: `
301opt_bool: [true, false]
302`,
303 wantErr: true,
304 }, {
Herbie Ong800c9902018-12-06 15:28:53 -0800305 desc: "proto3 duplicate singular field",
306 inputMessage: &pb3.Scalars{},
307 inputText: `
308s_bool: false
309s_bool: true
310`,
311 wantErr: true,
312 }, {
313 desc: "proto3 more duplicate singular field",
314 inputMessage: &pb3.Scalars{},
315 inputText: `
316s_bool: false
317s_string: ""
318s_bool: true
319`,
320 wantErr: true,
321 }, {
322 desc: "proto2 enum",
323 inputMessage: &pb2.Enums{},
324 inputText: `
Herbie Ong8170d692019-02-13 14:13:21 -0800325opt_enum: ONE
Herbie Ong800c9902018-12-06 15:28:53 -0800326opt_nested_enum: UNO
327`,
328 wantMessage: &pb2.Enums{
Herbie Ong8170d692019-02-13 14:13:21 -0800329 OptEnum: pb2.Enum_ONE.Enum(),
Herbie Ong800c9902018-12-06 15:28:53 -0800330 OptNestedEnum: pb2.Enums_UNO.Enum(),
331 },
332 }, {
333 desc: "proto2 enum set to numeric values",
334 inputMessage: &pb2.Enums{},
335 inputText: `
Herbie Ong8170d692019-02-13 14:13:21 -0800336opt_enum: 2
Herbie Ong800c9902018-12-06 15:28:53 -0800337opt_nested_enum: 2
338`,
339 wantMessage: &pb2.Enums{
Herbie Ong8170d692019-02-13 14:13:21 -0800340 OptEnum: pb2.Enum_TWO.Enum(),
Herbie Ong800c9902018-12-06 15:28:53 -0800341 OptNestedEnum: pb2.Enums_DOS.Enum(),
342 },
343 }, {
344 desc: "proto2 enum set to unnamed numeric values",
345 inputMessage: &pb2.Enums{},
346 inputText: `
347opt_enum: 101
348opt_nested_enum: -101
349`,
350 wantMessage: &pb2.Enums{
351 OptEnum: pb2Enum(101),
352 OptNestedEnum: pb2Enums_NestedEnum(-101),
353 },
354 }, {
355 desc: "proto2 enum set to invalid named",
356 inputMessage: &pb2.Enums{},
357 inputText: `
Herbie Ong8170d692019-02-13 14:13:21 -0800358opt_enum: UNNAMED
Herbie Ong800c9902018-12-06 15:28:53 -0800359opt_nested_enum: UNNAMED_TOO
360`,
361 wantErr: true,
362 }, {
363 desc: "proto3 enum name value",
364 inputMessage: &pb3.Enums{},
365 inputText: `
366s_enum: ONE
367s_nested_enum: DIEZ
368`,
369 wantMessage: &pb3.Enums{
370 SEnum: pb3.Enum_ONE,
371 SNestedEnum: pb3.Enums_DIEZ,
372 },
373 }, {
374 desc: "proto3 enum numeric value",
375 inputMessage: &pb3.Enums{},
376 inputText: `
377s_enum: 2
Herbie Ong8170d692019-02-13 14:13:21 -0800378s_nested_enum: 2
Herbie Ong800c9902018-12-06 15:28:53 -0800379`,
380 wantMessage: &pb3.Enums{
381 SEnum: pb3.Enum_TWO,
Herbie Ong8170d692019-02-13 14:13:21 -0800382 SNestedEnum: pb3.Enums_DOS,
Herbie Ong800c9902018-12-06 15:28:53 -0800383 },
384 }, {
385 desc: "proto3 enum unnamed numeric value",
386 inputMessage: &pb3.Enums{},
387 inputText: `
388s_enum: 0x7fffffff
389s_nested_enum: -0x80000000
390`,
391 wantMessage: &pb3.Enums{
392 SEnum: 0x7fffffff,
393 SNestedEnum: -0x80000000,
394 },
395 }, {
396 desc: "proto2 nested empty messages",
397 inputMessage: &pb2.Nests{},
398 inputText: `
399opt_nested: {}
Herbie Ong0dcfb9a2019-01-14 15:32:26 -0800400OptGroup: {}
Herbie Ong800c9902018-12-06 15:28:53 -0800401`,
402 wantMessage: &pb2.Nests{
403 OptNested: &pb2.Nested{},
404 Optgroup: &pb2.Nests_OptGroup{},
405 },
406 }, {
407 desc: "proto2 nested messages",
408 inputMessage: &pb2.Nests{},
409 inputText: `
410opt_nested: {
411 opt_string: "nested message"
412 opt_nested: {
413 opt_string: "another nested message"
414 }
415}
416`,
417 wantMessage: &pb2.Nests{
418 OptNested: &pb2.Nested{
419 OptString: scalar.String("nested message"),
420 OptNested: &pb2.Nested{
421 OptString: scalar.String("another nested message"),
422 },
423 },
424 },
425 }, {
426 desc: "proto3 nested empty message",
427 inputMessage: &pb3.Nests{},
428 inputText: "s_nested: {}",
429 wantMessage: &pb3.Nests{
430 SNested: &pb3.Nested{},
431 },
432 }, {
433 desc: "proto3 nested message",
434 inputMessage: &pb3.Nests{},
435 inputText: `
436s_nested: {
437 s_string: "nested message"
438 s_nested: {
439 s_string: "another nested message"
440 }
441}
442`,
443 wantMessage: &pb3.Nests{
444 SNested: &pb3.Nested{
445 SString: "nested message",
446 SNested: &pb3.Nested{
447 SString: "another nested message",
448 },
449 },
450 },
451 }, {
Herbie Ong21a39742019-04-08 17:32:44 -0700452 desc: "proto3 nested message contains invalid UTF-8",
453 inputMessage: &pb3.Nests{},
454 inputText: `s_nested: {
455 s_string: "abc\xff"
456}
457`,
Herbie Ong21a39742019-04-08 17:32:44 -0700458 wantErr: true,
459 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800460 desc: "oneof set to empty string",
461 inputMessage: &pb3.Oneofs{},
462 inputText: "oneof_string: ''",
463 wantMessage: &pb3.Oneofs{
464 Union: &pb3.Oneofs_OneofString{},
Herbie Ong800c9902018-12-06 15:28:53 -0800465 },
466 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800467 desc: "oneof set to string",
468 inputMessage: &pb3.Oneofs{},
469 inputText: "oneof_string: 'hello'",
470 wantMessage: &pb3.Oneofs{
471 Union: &pb3.Oneofs_OneofString{
472 OneofString: "hello",
Herbie Ong800c9902018-12-06 15:28:53 -0800473 },
474 },
475 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800476 desc: "oneof set to enum",
477 inputMessage: &pb3.Oneofs{},
478 inputText: "oneof_enum: TEN",
479 wantMessage: &pb3.Oneofs{
480 Union: &pb3.Oneofs_OneofEnum{
481 OneofEnum: pb3.Enum_TEN,
Herbie Ong800c9902018-12-06 15:28:53 -0800482 },
483 },
484 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800485 desc: "oneof set to empty message",
486 inputMessage: &pb3.Oneofs{},
487 inputText: "oneof_nested: {}",
488 wantMessage: &pb3.Oneofs{
489 Union: &pb3.Oneofs_OneofNested{
490 OneofNested: &pb3.Nested{},
491 },
492 },
493 }, {
494 desc: "oneof set to message",
495 inputMessage: &pb3.Oneofs{},
Herbie Ong800c9902018-12-06 15:28:53 -0800496 inputText: `
Herbie Ong8170d692019-02-13 14:13:21 -0800497oneof_nested: {
498 s_string: "nested message"
Herbie Ong800c9902018-12-06 15:28:53 -0800499}
500`,
Herbie Ong8170d692019-02-13 14:13:21 -0800501 wantMessage: &pb3.Oneofs{
502 Union: &pb3.Oneofs_OneofNested{
503 OneofNested: &pb3.Nested{
504 SString: "nested message",
Herbie Ong800c9902018-12-06 15:28:53 -0800505 },
506 },
507 },
508 }, {
Herbie Ong8a1d4602019-04-02 20:19:36 -0700509 desc: "oneof set to more than one field",
Herbie Ong8170d692019-02-13 14:13:21 -0800510 inputMessage: &pb3.Oneofs{},
Herbie Ong6470ea62019-01-07 18:56:57 -0800511 inputText: `
Herbie Ong8a1d4602019-04-02 20:19:36 -0700512oneof_enum: ZERO
513oneof_string: "hello"
Herbie Ong6470ea62019-01-07 18:56:57 -0800514`,
Herbie Ong8a1d4602019-04-02 20:19:36 -0700515 wantErr: true,
Herbie Ong6470ea62019-01-07 18:56:57 -0800516 }, {
Herbie Ong800c9902018-12-06 15:28:53 -0800517 desc: "repeated scalar using same field name",
518 inputMessage: &pb2.Repeats{},
519 inputText: `
520rpt_string: "a"
521rpt_string: "b"
522rpt_int32: 0xff
523rpt_float: 1.23
524rpt_bytes: "bytes"
525`,
526 wantMessage: &pb2.Repeats{
527 RptString: []string{"a", "b"},
528 RptInt32: []int32{0xff},
529 RptFloat: []float32{1.23},
530 RptBytes: [][]byte{[]byte("bytes")},
531 },
532 }, {
533 desc: "repeated using mix of [] and repeated field name",
534 inputMessage: &pb2.Repeats{},
535 inputText: `
536rpt_string: "a"
537rpt_bool: true
538rpt_string: ["x", "y"]
539rpt_bool: [ false, true ]
540rpt_string: "b"
541`,
542 wantMessage: &pb2.Repeats{
543 RptString: []string{"a", "x", "y", "b"},
544 RptBool: []bool{true, false, true},
545 },
546 }, {
Herbie Ong21a39742019-04-08 17:32:44 -0700547 desc: "repeated contains invalid UTF-8",
548 inputMessage: &pb2.Repeats{},
549 inputText: `rpt_string: "abc\xff"`,
Damien Neil8c86fc52019-06-19 09:28:29 -0700550 wantErr: true,
Herbie Ong21a39742019-04-08 17:32:44 -0700551 }, {
Herbie Ong800c9902018-12-06 15:28:53 -0800552 desc: "repeated enums",
553 inputMessage: &pb2.Enums{},
554 inputText: `
Herbie Ong8170d692019-02-13 14:13:21 -0800555rpt_enum: TEN
Herbie Ong800c9902018-12-06 15:28:53 -0800556rpt_enum: 1
557rpt_nested_enum: [DOS, 2]
558rpt_enum: 42
559rpt_nested_enum: -47
560`,
561 wantMessage: &pb2.Enums{
Herbie Ong8170d692019-02-13 14:13:21 -0800562 RptEnum: []pb2.Enum{pb2.Enum_TEN, pb2.Enum_ONE, 42},
Herbie Ong800c9902018-12-06 15:28:53 -0800563 RptNestedEnum: []pb2.Enums_NestedEnum{pb2.Enums_DOS, pb2.Enums_DOS, -47},
564 },
565 }, {
566 desc: "repeated nested messages",
567 inputMessage: &pb2.Nests{},
568 inputText: `
569rpt_nested: {
570 opt_string: "repeat nested one"
571}
572rpt_nested: {
573 opt_string: "repeat nested two"
574 opt_nested: {
575 opt_string: "inside repeat nested two"
576 }
577}
578rpt_nested: {}
579`,
580 wantMessage: &pb2.Nests{
581 RptNested: []*pb2.Nested{
582 {
583 OptString: scalar.String("repeat nested one"),
584 },
585 {
586 OptString: scalar.String("repeat nested two"),
587 OptNested: &pb2.Nested{
588 OptString: scalar.String("inside repeat nested two"),
589 },
590 },
591 {},
592 },
593 },
594 }, {
595 desc: "repeated group fields",
596 inputMessage: &pb2.Nests{},
597 inputText: `
Herbie Ong0dcfb9a2019-01-14 15:32:26 -0800598RptGroup: {
Herbie Ong8170d692019-02-13 14:13:21 -0800599 rpt_string: "hello"
600 rpt_string: "world"
Herbie Ong800c9902018-12-06 15:28:53 -0800601}
Herbie Ong0dcfb9a2019-01-14 15:32:26 -0800602RptGroup: {}
Herbie Ong800c9902018-12-06 15:28:53 -0800603`,
604 wantMessage: &pb2.Nests{
605 Rptgroup: []*pb2.Nests_RptGroup{
606 {
Herbie Ong8170d692019-02-13 14:13:21 -0800607 RptString: []string{"hello", "world"},
Herbie Ong800c9902018-12-06 15:28:53 -0800608 },
609 {},
610 },
611 },
612 }, {
613 desc: "map fields 1",
Herbie Ong8170d692019-02-13 14:13:21 -0800614 inputMessage: &pb3.Maps{},
Herbie Ong800c9902018-12-06 15:28:53 -0800615 inputText: `
616int32_to_str: {
617 key: -101
618 value: "-101"
619}
620int32_to_str: {
621 key: 0
622 value: "zero"
623}
Herbie Ong8170d692019-02-13 14:13:21 -0800624bool_to_uint32: {
625 key: false
626 value: 101
Herbie Ong800c9902018-12-06 15:28:53 -0800627}
628int32_to_str: {
629 key: 255
630 value: "0xff"
631}
632bool_to_uint32: {
Herbie Ong800c9902018-12-06 15:28:53 -0800633 key: true
634 value: 42
635}
636`,
Herbie Ong8170d692019-02-13 14:13:21 -0800637 wantMessage: &pb3.Maps{
Herbie Ong800c9902018-12-06 15:28:53 -0800638 Int32ToStr: map[int32]string{
639 -101: "-101",
640 0xff: "0xff",
641 0: "zero",
642 },
Herbie Ong800c9902018-12-06 15:28:53 -0800643 BoolToUint32: map[bool]uint32{
644 true: 42,
645 false: 101,
646 },
647 },
648 }, {
649 desc: "map fields 2",
Herbie Ong8170d692019-02-13 14:13:21 -0800650 inputMessage: &pb3.Maps{},
Herbie Ong800c9902018-12-06 15:28:53 -0800651 inputText: `
652uint64_to_enum: {
653 key: 1
Herbie Ong8170d692019-02-13 14:13:21 -0800654 value: ONE
Herbie Ong800c9902018-12-06 15:28:53 -0800655}
656uint64_to_enum: {
657 key: 2
Herbie Ong8170d692019-02-13 14:13:21 -0800658 value: 2
Herbie Ong800c9902018-12-06 15:28:53 -0800659}
660uint64_to_enum: {
661 key: 10
Herbie Ong8170d692019-02-13 14:13:21 -0800662 value: 101
Herbie Ong800c9902018-12-06 15:28:53 -0800663}
664`,
Herbie Ong8170d692019-02-13 14:13:21 -0800665 wantMessage: &pb3.Maps{
666 Uint64ToEnum: map[uint64]pb3.Enum{
667 1: pb3.Enum_ONE,
668 2: pb3.Enum_TWO,
669 10: 101,
Herbie Ong800c9902018-12-06 15:28:53 -0800670 },
671 },
672 }, {
673 desc: "map fields 3",
Herbie Ong8170d692019-02-13 14:13:21 -0800674 inputMessage: &pb3.Maps{},
Herbie Ong800c9902018-12-06 15:28:53 -0800675 inputText: `
676str_to_nested: {
677 key: "nested_one"
678 value: {
Herbie Ong8170d692019-02-13 14:13:21 -0800679 s_string: "nested in a map"
Herbie Ong800c9902018-12-06 15:28:53 -0800680 }
681}
682`,
Herbie Ong8170d692019-02-13 14:13:21 -0800683 wantMessage: &pb3.Maps{
684 StrToNested: map[string]*pb3.Nested{
685 "nested_one": &pb3.Nested{
686 SString: "nested in a map",
Herbie Ong800c9902018-12-06 15:28:53 -0800687 },
688 },
689 },
690 }, {
691 desc: "map fields 4",
Herbie Ong8170d692019-02-13 14:13:21 -0800692 inputMessage: &pb3.Maps{},
Herbie Ong800c9902018-12-06 15:28:53 -0800693 inputText: `
694str_to_oneofs: {
695 key: "nested"
696 value: {
Herbie Ong8170d692019-02-13 14:13:21 -0800697 oneof_nested: {
698 s_string: "nested oneof in map field value"
Herbie Ong800c9902018-12-06 15:28:53 -0800699 }
700 }
701}
702str_to_oneofs: {
703 key: "string"
704 value: {
Herbie Ong8170d692019-02-13 14:13:21 -0800705 oneof_string: "hello"
Herbie Ong800c9902018-12-06 15:28:53 -0800706 }
707}
708`,
Herbie Ong8170d692019-02-13 14:13:21 -0800709 wantMessage: &pb3.Maps{
710 StrToOneofs: map[string]*pb3.Oneofs{
711 "string": &pb3.Oneofs{
712 Union: &pb3.Oneofs_OneofString{
713 OneofString: "hello",
Herbie Ong800c9902018-12-06 15:28:53 -0800714 },
715 },
Herbie Ong8170d692019-02-13 14:13:21 -0800716 "nested": &pb3.Oneofs{
717 Union: &pb3.Oneofs_OneofNested{
718 OneofNested: &pb3.Nested{
719 SString: "nested oneof in map field value",
Herbie Ong800c9902018-12-06 15:28:53 -0800720 },
721 },
722 },
723 },
724 },
725 }, {
726 desc: "map contains duplicate keys",
Herbie Ong8170d692019-02-13 14:13:21 -0800727 inputMessage: &pb3.Maps{},
Herbie Ong800c9902018-12-06 15:28:53 -0800728 inputText: `
729int32_to_str: {
730 key: 0
731 value: "cero"
732}
733int32_to_str: {
734 key: 0
735 value: "zero"
736}
737`,
Herbie Ong8170d692019-02-13 14:13:21 -0800738 wantMessage: &pb3.Maps{
Herbie Ong800c9902018-12-06 15:28:53 -0800739 Int32ToStr: map[int32]string{
740 0: "zero",
741 },
742 },
743 }, {
744 desc: "map contains duplicate key fields",
Herbie Ong8170d692019-02-13 14:13:21 -0800745 inputMessage: &pb3.Maps{},
Herbie Ong800c9902018-12-06 15:28:53 -0800746 inputText: `
747int32_to_str: {
748 key: 0
749 key: 1
750 value: "cero"
751}
752`,
753 wantErr: true,
754 }, {
755 desc: "map contains duplicate value fields",
Herbie Ong8170d692019-02-13 14:13:21 -0800756 inputMessage: &pb3.Maps{},
Herbie Ong800c9902018-12-06 15:28:53 -0800757 inputText: `
758int32_to_str: {
759 key: 1
760 value: "cero"
761 value: "uno"
762}
763`,
764 wantErr: true,
765 }, {
766 desc: "map contains missing key",
Herbie Ong8170d692019-02-13 14:13:21 -0800767 inputMessage: &pb3.Maps{},
Herbie Ong800c9902018-12-06 15:28:53 -0800768 inputText: `
769int32_to_str: {
770 value: "zero"
771}
Herbie Ong8170d692019-02-13 14:13:21 -0800772bool_to_uint32: {
773 value: 47
774}
775str_to_nested: {
776 value: {}
777}
Herbie Ong800c9902018-12-06 15:28:53 -0800778`,
Herbie Ong8170d692019-02-13 14:13:21 -0800779 wantMessage: &pb3.Maps{
Herbie Ong800c9902018-12-06 15:28:53 -0800780 Int32ToStr: map[int32]string{
781 0: "zero",
782 },
Herbie Ong8170d692019-02-13 14:13:21 -0800783 BoolToUint32: map[bool]uint32{
784 false: 47,
785 },
786 StrToNested: map[string]*pb3.Nested{
787 "": {},
788 },
Herbie Ong800c9902018-12-06 15:28:53 -0800789 },
790 }, {
791 desc: "map contains missing value",
Herbie Ong8170d692019-02-13 14:13:21 -0800792 inputMessage: &pb3.Maps{},
Herbie Ong800c9902018-12-06 15:28:53 -0800793 inputText: `
794int32_to_str: {
795 key: 100
796}
Herbie Ong8170d692019-02-13 14:13:21 -0800797bool_to_uint32: {
798 key: true
799}
800uint64_to_enum: {
801 key: 101
802}
803str_to_nested: {
804 key: "hello"
805}
Herbie Ong800c9902018-12-06 15:28:53 -0800806`,
Herbie Ong8170d692019-02-13 14:13:21 -0800807 wantMessage: &pb3.Maps{
Herbie Ong800c9902018-12-06 15:28:53 -0800808 Int32ToStr: map[int32]string{
809 100: "",
810 },
Herbie Ong8170d692019-02-13 14:13:21 -0800811 BoolToUint32: map[bool]uint32{
812 true: 0,
813 },
814 Uint64ToEnum: map[uint64]pb3.Enum{
815 101: pb3.Enum_ZERO,
816 },
817 StrToNested: map[string]*pb3.Nested{
818 "hello": {},
819 },
Herbie Ong800c9902018-12-06 15:28:53 -0800820 },
821 }, {
822 desc: "map contains missing key and value",
Herbie Ong8170d692019-02-13 14:13:21 -0800823 inputMessage: &pb3.Maps{},
Herbie Ong800c9902018-12-06 15:28:53 -0800824 inputText: `
825int32_to_str: {}
Herbie Ong8170d692019-02-13 14:13:21 -0800826bool_to_uint32: {}
827uint64_to_enum: {}
828str_to_nested: {}
Herbie Ong800c9902018-12-06 15:28:53 -0800829`,
Herbie Ong8170d692019-02-13 14:13:21 -0800830 wantMessage: &pb3.Maps{
831 Int32ToStr: map[int32]string{
832 0: "",
833 },
834 BoolToUint32: map[bool]uint32{
835 false: 0,
836 },
837 Uint64ToEnum: map[uint64]pb3.Enum{
838 0: pb3.Enum_ZERO,
839 },
840 StrToNested: map[string]*pb3.Nested{
841 "": {},
842 },
843 },
844 }, {
845 desc: "map contains overriding entries",
846 inputMessage: &pb3.Maps{},
847 inputText: `
848int32_to_str: {
849 key: 0
850}
851int32_to_str: {
852 value: "empty"
853}
854int32_to_str: {}
855`,
856 wantMessage: &pb3.Maps{
Herbie Ong800c9902018-12-06 15:28:53 -0800857 Int32ToStr: map[int32]string{
858 0: "",
859 },
860 },
861 }, {
Herbie Ong21a39742019-04-08 17:32:44 -0700862 desc: "map field value contains invalid UTF-8",
863 inputMessage: &pb3.Maps{},
864 inputText: `int32_to_str: {
865 key: 101
866 value: "abc\xff"
867}
868`,
Herbie Ong21a39742019-04-08 17:32:44 -0700869 wantErr: true,
870 }, {
871 desc: "map field key contains invalid UTF-8",
872 inputMessage: &pb3.Maps{},
873 inputText: `str_to_nested: {
874 key: "abc\xff"
875 value: {}
876}
877`,
Herbie Ong21a39742019-04-08 17:32:44 -0700878 wantErr: true,
879 }, {
Herbie Ong800c9902018-12-06 15:28:53 -0800880 desc: "map contains unknown field",
Herbie Ong8170d692019-02-13 14:13:21 -0800881 inputMessage: &pb3.Maps{},
Herbie Ong800c9902018-12-06 15:28:53 -0800882 inputText: `
883int32_to_str: {
884 key: 0
885 value: "cero"
886 unknown: "bad"
887}
888`,
889 wantErr: true,
890 }, {
891 desc: "map contains extension-like key field",
Herbie Ong8170d692019-02-13 14:13:21 -0800892 inputMessage: &pb3.Maps{},
Herbie Ong800c9902018-12-06 15:28:53 -0800893 inputText: `
894int32_to_str: {
895 [key]: 10
896 value: "ten"
897}
898`,
899 wantErr: true,
900 }, {
901 desc: "map contains invalid key",
Herbie Ong8170d692019-02-13 14:13:21 -0800902 inputMessage: &pb3.Maps{},
Herbie Ong800c9902018-12-06 15:28:53 -0800903 inputText: `
904int32_to_str: {
905 key: "invalid"
906 value: "cero"
907}
908`,
909 wantErr: true,
910 }, {
911 desc: "map contains invalid value",
Herbie Ong8170d692019-02-13 14:13:21 -0800912 inputMessage: &pb3.Maps{},
Herbie Ong800c9902018-12-06 15:28:53 -0800913 inputText: `
914int32_to_str: {
915 key: 100
916 value: 101
917}
918`,
919 wantErr: true,
920 }, {
921 desc: "map using mix of [] and repeated",
Herbie Ong8170d692019-02-13 14:13:21 -0800922 inputMessage: &pb3.Maps{},
Herbie Ong800c9902018-12-06 15:28:53 -0800923 inputText: `
924int32_to_str: {
925 key: 1
926 value: "one"
927}
928int32_to_str: [
929 {
930 key: 2
931 value: "not this"
932 },
933 {
934 },
935 {
936 key: 3
937 value: "three"
938 }
939]
940int32_to_str: {
941 key: 2
942 value: "two"
943}
944`,
Herbie Ong8170d692019-02-13 14:13:21 -0800945 wantMessage: &pb3.Maps{
Herbie Ong800c9902018-12-06 15:28:53 -0800946 Int32ToStr: map[int32]string{
947 0: "",
948 1: "one",
949 2: "two",
950 3: "three",
951 },
952 },
953 }, {
Herbie Ong42577ea2019-03-26 16:26:22 -0700954 desc: "required fields not set",
Herbie Ong800c9902018-12-06 15:28:53 -0800955 inputMessage: &pb2.Requireds{},
956 wantErr: true,
957 }, {
Herbie Ong42577ea2019-03-26 16:26:22 -0700958 desc: "required field set",
Herbie Ong800c9902018-12-06 15:28:53 -0800959 inputMessage: &pb2.PartialRequired{},
960 inputText: "req_string: 'this is required'",
961 wantMessage: &pb2.PartialRequired{
962 ReqString: scalar.String("this is required"),
963 },
964 }, {
Herbie Ong42577ea2019-03-26 16:26:22 -0700965 desc: "required fields partially set",
Herbie Ong800c9902018-12-06 15:28:53 -0800966 inputMessage: &pb2.Requireds{},
967 inputText: `
968req_bool: false
Herbie Ong800c9902018-12-06 15:28:53 -0800969req_sfixed64: 3203386110
970req_string: "hello"
Herbie Ong8170d692019-02-13 14:13:21 -0800971req_enum: ONE
Herbie Ong800c9902018-12-06 15:28:53 -0800972`,
973 wantMessage: &pb2.Requireds{
974 ReqBool: scalar.Bool(false),
Herbie Ong800c9902018-12-06 15:28:53 -0800975 ReqSfixed64: scalar.Int64(0xbeefcafe),
976 ReqString: scalar.String("hello"),
Herbie Ong8170d692019-02-13 14:13:21 -0800977 ReqEnum: pb2.Enum_ONE.Enum(),
Herbie Ong800c9902018-12-06 15:28:53 -0800978 },
979 wantErr: true,
980 }, {
Herbie Ong42577ea2019-03-26 16:26:22 -0700981 desc: "required fields partially set with AllowPartial",
Damien Neil5c5b5312019-05-14 12:44:37 -0700982 umo: prototext.UnmarshalOptions{AllowPartial: true},
Herbie Ong42577ea2019-03-26 16:26:22 -0700983 inputMessage: &pb2.Requireds{},
984 inputText: `
985req_bool: false
986req_sfixed64: 3203386110
987req_string: "hello"
988req_enum: ONE
989`,
990 wantMessage: &pb2.Requireds{
991 ReqBool: scalar.Bool(false),
992 ReqSfixed64: scalar.Int64(0xbeefcafe),
993 ReqString: scalar.String("hello"),
994 ReqEnum: pb2.Enum_ONE.Enum(),
995 },
996 }, {
997 desc: "required fields all set",
Herbie Ong800c9902018-12-06 15:28:53 -0800998 inputMessage: &pb2.Requireds{},
999 inputText: `
1000req_bool: false
Herbie Ong800c9902018-12-06 15:28:53 -08001001req_sfixed64: 0
Herbie Ong800c9902018-12-06 15:28:53 -08001002req_double: 0
1003req_string: ""
Herbie Ong8170d692019-02-13 14:13:21 -08001004req_enum: ONE
Herbie Ong800c9902018-12-06 15:28:53 -08001005req_nested: {}
1006`,
1007 wantMessage: &pb2.Requireds{
1008 ReqBool: scalar.Bool(false),
Herbie Ong800c9902018-12-06 15:28:53 -08001009 ReqSfixed64: scalar.Int64(0),
Herbie Ong800c9902018-12-06 15:28:53 -08001010 ReqDouble: scalar.Float64(0),
1011 ReqString: scalar.String(""),
Herbie Ong8170d692019-02-13 14:13:21 -08001012 ReqEnum: pb2.Enum_ONE.Enum(),
Herbie Ong800c9902018-12-06 15:28:53 -08001013 ReqNested: &pb2.Nested{},
1014 },
1015 }, {
1016 desc: "indirect required field",
1017 inputMessage: &pb2.IndirectRequired{},
1018 inputText: "opt_nested: {}",
1019 wantMessage: &pb2.IndirectRequired{
1020 OptNested: &pb2.NestedWithRequired{},
1021 },
1022 wantErr: true,
1023 }, {
Herbie Ong42577ea2019-03-26 16:26:22 -07001024 desc: "indirect required field with AllowPartial",
Damien Neil5c5b5312019-05-14 12:44:37 -07001025 umo: prototext.UnmarshalOptions{AllowPartial: true},
Herbie Ong42577ea2019-03-26 16:26:22 -07001026 inputMessage: &pb2.IndirectRequired{},
1027 inputText: "opt_nested: {}",
1028 wantMessage: &pb2.IndirectRequired{
1029 OptNested: &pb2.NestedWithRequired{},
1030 },
1031 }, {
Herbie Ong800c9902018-12-06 15:28:53 -08001032 desc: "indirect required field in repeated",
1033 inputMessage: &pb2.IndirectRequired{},
1034 inputText: `
1035rpt_nested: {
1036 req_string: "one"
1037}
1038rpt_nested: {}
Herbie Ong800c9902018-12-06 15:28:53 -08001039`,
1040 wantMessage: &pb2.IndirectRequired{
1041 RptNested: []*pb2.NestedWithRequired{
1042 {
1043 ReqString: scalar.String("one"),
1044 },
1045 {},
Herbie Ong800c9902018-12-06 15:28:53 -08001046 },
1047 },
1048 wantErr: true,
1049 }, {
Herbie Ong42577ea2019-03-26 16:26:22 -07001050 desc: "indirect required field in repeated with AllowPartial",
Damien Neil5c5b5312019-05-14 12:44:37 -07001051 umo: prototext.UnmarshalOptions{AllowPartial: true},
Herbie Ong42577ea2019-03-26 16:26:22 -07001052 inputMessage: &pb2.IndirectRequired{},
1053 inputText: `
1054rpt_nested: {
1055 req_string: "one"
1056}
1057rpt_nested: {}
1058`,
1059 wantMessage: &pb2.IndirectRequired{
1060 RptNested: []*pb2.NestedWithRequired{
1061 {
1062 ReqString: scalar.String("one"),
1063 },
1064 {},
1065 },
1066 },
1067 }, {
Herbie Ong800c9902018-12-06 15:28:53 -08001068 desc: "indirect required field in map",
1069 inputMessage: &pb2.IndirectRequired{},
1070 inputText: `
1071str_to_nested: {
1072 key: "missing"
1073}
1074str_to_nested: {
1075 key: "contains"
1076 value: {
1077 req_string: "here"
1078 }
1079}
1080`,
1081 wantMessage: &pb2.IndirectRequired{
1082 StrToNested: map[string]*pb2.NestedWithRequired{
1083 "missing": &pb2.NestedWithRequired{},
1084 "contains": &pb2.NestedWithRequired{
1085 ReqString: scalar.String("here"),
1086 },
1087 },
1088 },
1089 wantErr: true,
Herbie Ong7c624e22018-12-13 14:41:22 -08001090 }, {
Herbie Ong42577ea2019-03-26 16:26:22 -07001091 desc: "indirect required field in map with AllowPartial",
Damien Neil5c5b5312019-05-14 12:44:37 -07001092 umo: prototext.UnmarshalOptions{AllowPartial: true},
Herbie Ong42577ea2019-03-26 16:26:22 -07001093 inputMessage: &pb2.IndirectRequired{},
1094 inputText: `
1095str_to_nested: {
1096 key: "missing"
1097}
1098str_to_nested: {
1099 key: "contains"
1100 value: {
1101 req_string: "here"
1102 }
1103}
1104`,
1105 wantMessage: &pb2.IndirectRequired{
1106 StrToNested: map[string]*pb2.NestedWithRequired{
1107 "missing": &pb2.NestedWithRequired{},
1108 "contains": &pb2.NestedWithRequired{
1109 ReqString: scalar.String("here"),
1110 },
1111 },
1112 },
1113 }, {
Herbie Ong8170d692019-02-13 14:13:21 -08001114 desc: "indirect required field in oneof",
1115 inputMessage: &pb2.IndirectRequired{},
1116 inputText: `oneof_nested: {}
1117`,
1118 wantMessage: &pb2.IndirectRequired{
1119 Union: &pb2.IndirectRequired_OneofNested{
1120 OneofNested: &pb2.NestedWithRequired{},
1121 },
1122 },
1123 wantErr: true,
1124 }, {
Herbie Ong42577ea2019-03-26 16:26:22 -07001125 desc: "indirect required field in oneof with AllowPartial",
Damien Neil5c5b5312019-05-14 12:44:37 -07001126 umo: prototext.UnmarshalOptions{AllowPartial: true},
Herbie Ong42577ea2019-03-26 16:26:22 -07001127 inputMessage: &pb2.IndirectRequired{},
1128 inputText: `oneof_nested: {}
1129`,
1130 wantMessage: &pb2.IndirectRequired{
1131 Union: &pb2.IndirectRequired_OneofNested{
1132 OneofNested: &pb2.NestedWithRequired{},
1133 },
1134 },
1135 }, {
Herbie Ong7c624e22018-12-13 14:41:22 -08001136 desc: "ignore reserved field",
1137 inputMessage: &pb2.Nests{},
1138 inputText: "reserved_field: 'ignore this'",
1139 wantMessage: &pb2.Nests{},
Herbie Ongc525c972018-12-18 18:04:31 -08001140 }, {
1141 desc: "extensions of non-repeated fields",
1142 inputMessage: &pb2.Extensions{},
1143 inputText: `opt_string: "non-extension field"
1144[pb2.opt_ext_bool]: true
1145opt_bool: true
1146[pb2.opt_ext_nested]: {
1147 opt_string: "nested in an extension"
1148 opt_nested: {
1149 opt_string: "another nested in an extension"
1150 }
1151}
1152[pb2.opt_ext_string]: "extension field"
1153opt_int32: 42
Herbie Ong8170d692019-02-13 14:13:21 -08001154[pb2.opt_ext_enum]: TEN
Herbie Ongc525c972018-12-18 18:04:31 -08001155`,
1156 wantMessage: func() proto.Message {
1157 m := &pb2.Extensions{
1158 OptString: scalar.String("non-extension field"),
1159 OptBool: scalar.Bool(true),
1160 OptInt32: scalar.Int32(42),
1161 }
1162 setExtension(m, pb2.E_OptExtBool, true)
1163 setExtension(m, pb2.E_OptExtString, "extension field")
Herbie Ong8170d692019-02-13 14:13:21 -08001164 setExtension(m, pb2.E_OptExtEnum, pb2.Enum_TEN)
Herbie Ongc525c972018-12-18 18:04:31 -08001165 setExtension(m, pb2.E_OptExtNested, &pb2.Nested{
1166 OptString: scalar.String("nested in an extension"),
1167 OptNested: &pb2.Nested{
1168 OptString: scalar.String("another nested in an extension"),
1169 },
1170 })
1171 return m
1172 }(),
1173 }, {
Herbie Ong21a39742019-04-08 17:32:44 -07001174 desc: "extension field contains invalid UTF-8",
1175 inputMessage: &pb2.Extensions{},
1176 inputText: `[pb2.opt_ext_string]: "abc\xff"`,
Damien Neil8c86fc52019-06-19 09:28:29 -07001177 wantErr: true,
Herbie Ong21a39742019-04-08 17:32:44 -07001178 }, {
Herbie Ongc525c972018-12-18 18:04:31 -08001179 desc: "extensions of repeated fields",
1180 inputMessage: &pb2.Extensions{},
Herbie Ong8170d692019-02-13 14:13:21 -08001181 inputText: `[pb2.rpt_ext_enum]: TEN
Herbie Ongc525c972018-12-18 18:04:31 -08001182[pb2.rpt_ext_enum]: 101
1183[pb2.rpt_ext_fixed32]: 42
Herbie Ong8170d692019-02-13 14:13:21 -08001184[pb2.rpt_ext_enum]: ONE
Herbie Ongc525c972018-12-18 18:04:31 -08001185[pb2.rpt_ext_nested]: {
1186 opt_string: "one"
1187}
1188[pb2.rpt_ext_nested]: {
1189 opt_string: "two"
1190}
1191[pb2.rpt_ext_fixed32]: 47
1192[pb2.rpt_ext_nested]: {
1193 opt_string: "three"
1194}
1195`,
1196 wantMessage: func() proto.Message {
1197 m := &pb2.Extensions{}
Herbie Ong8170d692019-02-13 14:13:21 -08001198 setExtension(m, pb2.E_RptExtEnum, &[]pb2.Enum{pb2.Enum_TEN, 101, pb2.Enum_ONE})
Herbie Ongc525c972018-12-18 18:04:31 -08001199 setExtension(m, pb2.E_RptExtFixed32, &[]uint32{42, 47})
1200 setExtension(m, pb2.E_RptExtNested, &[]*pb2.Nested{
1201 &pb2.Nested{OptString: scalar.String("one")},
1202 &pb2.Nested{OptString: scalar.String("two")},
1203 &pb2.Nested{OptString: scalar.String("three")},
1204 })
1205 return m
1206 }(),
1207 }, {
1208 desc: "extensions of non-repeated fields in another message",
1209 inputMessage: &pb2.Extensions{},
1210 inputText: `[pb2.ExtensionsContainer.opt_ext_bool]: true
Herbie Ong8170d692019-02-13 14:13:21 -08001211[pb2.ExtensionsContainer.opt_ext_enum]: TEN
Herbie Ongc525c972018-12-18 18:04:31 -08001212[pb2.ExtensionsContainer.opt_ext_nested]: {
1213 opt_string: "nested in an extension"
1214 opt_nested: {
1215 opt_string: "another nested in an extension"
1216 }
1217}
1218[pb2.ExtensionsContainer.opt_ext_string]: "extension field"
1219`,
1220 wantMessage: func() proto.Message {
1221 m := &pb2.Extensions{}
1222 setExtension(m, pb2.E_ExtensionsContainer_OptExtBool, true)
1223 setExtension(m, pb2.E_ExtensionsContainer_OptExtString, "extension field")
Herbie Ong8170d692019-02-13 14:13:21 -08001224 setExtension(m, pb2.E_ExtensionsContainer_OptExtEnum, pb2.Enum_TEN)
Herbie Ongc525c972018-12-18 18:04:31 -08001225 setExtension(m, pb2.E_ExtensionsContainer_OptExtNested, &pb2.Nested{
1226 OptString: scalar.String("nested in an extension"),
1227 OptNested: &pb2.Nested{
1228 OptString: scalar.String("another nested in an extension"),
1229 },
1230 })
1231 return m
1232 }(),
1233 }, {
1234 desc: "extensions of repeated fields in another message",
1235 inputMessage: &pb2.Extensions{},
1236 inputText: `opt_string: "non-extension field"
1237opt_bool: true
1238opt_int32: 42
1239[pb2.ExtensionsContainer.rpt_ext_nested]: {
1240 opt_string: "one"
1241}
Herbie Ong8170d692019-02-13 14:13:21 -08001242[pb2.ExtensionsContainer.rpt_ext_enum]: TEN
Herbie Ongc525c972018-12-18 18:04:31 -08001243[pb2.ExtensionsContainer.rpt_ext_nested]: {
1244 opt_string: "two"
1245}
1246[pb2.ExtensionsContainer.rpt_ext_enum]: 101
1247[pb2.ExtensionsContainer.rpt_ext_string]: "hello"
Herbie Ong8170d692019-02-13 14:13:21 -08001248[pb2.ExtensionsContainer.rpt_ext_enum]: ONE
Herbie Ongc525c972018-12-18 18:04:31 -08001249[pb2.ExtensionsContainer.rpt_ext_nested]: {
1250 opt_string: "three"
1251}
1252[pb2.ExtensionsContainer.rpt_ext_string]: "world"
1253`,
1254 wantMessage: func() proto.Message {
1255 m := &pb2.Extensions{
1256 OptString: scalar.String("non-extension field"),
1257 OptBool: scalar.Bool(true),
1258 OptInt32: scalar.Int32(42),
1259 }
Herbie Ong8170d692019-02-13 14:13:21 -08001260 setExtension(m, pb2.E_ExtensionsContainer_RptExtEnum, &[]pb2.Enum{pb2.Enum_TEN, 101, pb2.Enum_ONE})
Herbie Ongc525c972018-12-18 18:04:31 -08001261 setExtension(m, pb2.E_ExtensionsContainer_RptExtString, &[]string{"hello", "world"})
1262 setExtension(m, pb2.E_ExtensionsContainer_RptExtNested, &[]*pb2.Nested{
1263 &pb2.Nested{OptString: scalar.String("one")},
1264 &pb2.Nested{OptString: scalar.String("two")},
1265 &pb2.Nested{OptString: scalar.String("three")},
1266 })
1267 return m
1268 }(),
1269 }, {
1270 desc: "invalid extension field name",
1271 inputMessage: &pb2.Extensions{},
1272 inputText: "[pb2.invalid_message_field]: true",
1273 wantErr: true,
Herbie Ong66c365c2019-01-04 14:08:41 -08001274 }, {
Herbie Ong6470ea62019-01-07 18:56:57 -08001275 desc: "MessageSet",
1276 inputMessage: &pb2.MessageSet{},
1277 inputText: `
1278[pb2.MessageSetExtension]: {
1279 opt_string: "a messageset extension"
1280}
1281[pb2.MessageSetExtension.ext_nested]: {
1282 opt_string: "just a regular extension"
1283}
1284[pb2.MessageSetExtension.not_message_set_extension]: {
1285 opt_string: "not a messageset extension"
1286}
1287`,
1288 wantMessage: func() proto.Message {
1289 m := &pb2.MessageSet{}
1290 setExtension(m, pb2.E_MessageSetExtension_MessageSetExtension, &pb2.MessageSetExtension{
1291 OptString: scalar.String("a messageset extension"),
1292 })
1293 setExtension(m, pb2.E_MessageSetExtension_NotMessageSetExtension, &pb2.MessageSetExtension{
1294 OptString: scalar.String("not a messageset extension"),
1295 })
1296 setExtension(m, pb2.E_MessageSetExtension_ExtNested, &pb2.Nested{
1297 OptString: scalar.String("just a regular extension"),
1298 })
1299 return m
1300 }(),
1301 }, {
1302 desc: "not real MessageSet 1",
1303 inputMessage: &pb2.FakeMessageSet{},
1304 inputText: `
1305[pb2.FakeMessageSetExtension.message_set_extension]: {
1306 opt_string: "not a messageset extension"
1307}
1308`,
1309 wantMessage: func() proto.Message {
1310 m := &pb2.FakeMessageSet{}
1311 setExtension(m, pb2.E_FakeMessageSetExtension_MessageSetExtension, &pb2.FakeMessageSetExtension{
1312 OptString: scalar.String("not a messageset extension"),
1313 })
1314 return m
1315 }(),
1316 }, {
1317 desc: "not real MessageSet 2",
1318 inputMessage: &pb2.FakeMessageSet{},
1319 inputText: `
1320[pb2.FakeMessageSetExtension]: {
1321 opt_string: "not a messageset extension"
1322}
1323`,
1324 wantErr: true,
1325 }, {
1326 desc: "not real MessageSet 3",
1327 inputMessage: &pb2.MessageSet{},
1328 inputText: `
1329[pb2.message_set_extension]: {
1330 opt_string: "another not a messageset extension"
Herbie Ong300cff02019-03-20 18:05:16 -07001331}`,
Herbie Ong6470ea62019-01-07 18:56:57 -08001332 wantMessage: func() proto.Message {
1333 m := &pb2.MessageSet{}
1334 setExtension(m, pb2.E_MessageSetExtension, &pb2.FakeMessageSetExtension{
1335 OptString: scalar.String("another not a messageset extension"),
1336 })
1337 return m
1338 }(),
1339 }, {
Herbie Ong66c365c2019-01-04 14:08:41 -08001340 desc: "Any not expanded",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001341 inputMessage: &anypb.Any{},
Herbie Ong300cff02019-03-20 18:05:16 -07001342 inputText: `
Herbie Ong66c365c2019-01-04 14:08:41 -08001343type_url: "pb2.Nested"
1344value: "some bytes"
Herbie Ong66c365c2019-01-04 14:08:41 -08001345`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001346 wantMessage: &anypb.Any{
Herbie Ong300cff02019-03-20 18:05:16 -07001347 TypeUrl: "pb2.Nested",
1348 Value: []byte("some bytes"),
Herbie Ong66c365c2019-01-04 14:08:41 -08001349 },
1350 }, {
1351 desc: "Any not expanded missing value",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001352 inputMessage: &anypb.Any{},
Herbie Ong300cff02019-03-20 18:05:16 -07001353 inputText: `type_url: "pb2.Nested"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001354 wantMessage: &anypb.Any{
Herbie Ong300cff02019-03-20 18:05:16 -07001355 TypeUrl: "pb2.Nested",
Herbie Ong66c365c2019-01-04 14:08:41 -08001356 },
1357 }, {
1358 desc: "Any not expanded missing type_url",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001359 inputMessage: &anypb.Any{},
Herbie Ong300cff02019-03-20 18:05:16 -07001360 inputText: `value: "some bytes"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001361 wantMessage: &anypb.Any{
Herbie Ong300cff02019-03-20 18:05:16 -07001362 Value: []byte("some bytes"),
Herbie Ong66c365c2019-01-04 14:08:41 -08001363 },
1364 }, {
1365 desc: "Any expanded",
Damien Neil5c5b5312019-05-14 12:44:37 -07001366 umo: prototext.UnmarshalOptions{
Joe Tsai0fc49f82019-05-01 12:29:25 -07001367 Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&pb2.Nested{})),
Herbie Ong300cff02019-03-20 18:05:16 -07001368 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07001369 inputMessage: &anypb.Any{},
Herbie Ong300cff02019-03-20 18:05:16 -07001370 inputText: `
1371[foobar/pb2.Nested]: {
1372 opt_string: "embedded inside Any"
1373 opt_nested: {
1374 opt_string: "inception"
Herbie Ong66c365c2019-01-04 14:08:41 -08001375 }
1376}
1377`,
1378 wantMessage: func() proto.Message {
1379 m := &pb2.Nested{
1380 OptString: scalar.String("embedded inside Any"),
1381 OptNested: &pb2.Nested{
1382 OptString: scalar.String("inception"),
1383 },
1384 }
Herbie Onge0cf15b2019-03-15 19:32:38 -07001385 b, err := proto.MarshalOptions{Deterministic: true}.Marshal(m)
Herbie Ong66c365c2019-01-04 14:08:41 -08001386 if err != nil {
1387 t.Fatalf("error in binary marshaling message for Any.value: %v", err)
1388 }
Joe Tsaia95b29f2019-05-16 12:47:20 -07001389 return &anypb.Any{
Herbie Ong300cff02019-03-20 18:05:16 -07001390 TypeUrl: "foobar/pb2.Nested",
1391 Value: b,
Herbie Ong66c365c2019-01-04 14:08:41 -08001392 }
1393 }(),
1394 }, {
1395 desc: "Any expanded with empty value",
Damien Neil5c5b5312019-05-14 12:44:37 -07001396 umo: prototext.UnmarshalOptions{
Joe Tsai0fc49f82019-05-01 12:29:25 -07001397 Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&pb2.Nested{})),
Herbie Ong300cff02019-03-20 18:05:16 -07001398 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07001399 inputMessage: &anypb.Any{},
Herbie Ong300cff02019-03-20 18:05:16 -07001400 inputText: `[foo.com/pb2.Nested]: {}`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001401 wantMessage: &anypb.Any{
Herbie Ong300cff02019-03-20 18:05:16 -07001402 TypeUrl: "foo.com/pb2.Nested",
Herbie Ong66c365c2019-01-04 14:08:41 -08001403 },
1404 }, {
Damien Neil0c9f0a92019-06-19 10:41:09 -07001405 desc: "Any expanded with missing required",
Damien Neil5c5b5312019-05-14 12:44:37 -07001406 umo: prototext.UnmarshalOptions{
Joe Tsai0fc49f82019-05-01 12:29:25 -07001407 Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&pb2.PartialRequired{})),
Herbie Ong300cff02019-03-20 18:05:16 -07001408 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07001409 inputMessage: &anypb.Any{},
Herbie Ong300cff02019-03-20 18:05:16 -07001410 inputText: `
1411[pb2.PartialRequired]: {
1412 opt_string: "embedded inside Any"
Herbie Ong66c365c2019-01-04 14:08:41 -08001413}
1414`,
1415 wantMessage: func() proto.Message {
1416 m := &pb2.PartialRequired{
1417 OptString: scalar.String("embedded inside Any"),
1418 }
Damien Neil96c229a2019-04-03 12:17:24 -07001419 b, err := proto.MarshalOptions{
1420 AllowPartial: true,
1421 Deterministic: true,
1422 }.Marshal(m)
Herbie Ong300cff02019-03-20 18:05:16 -07001423 if err != nil {
Herbie Ong66c365c2019-01-04 14:08:41 -08001424 t.Fatalf("error in binary marshaling message for Any.value: %v", err)
1425 }
Joe Tsaia95b29f2019-05-16 12:47:20 -07001426 return &anypb.Any{
Herbie Ong300cff02019-03-20 18:05:16 -07001427 TypeUrl: "pb2.PartialRequired",
1428 Value: b,
Herbie Ong66c365c2019-01-04 14:08:41 -08001429 }
1430 }(),
Herbie Ong66c365c2019-01-04 14:08:41 -08001431 }, {
Herbie Ong21a39742019-04-08 17:32:44 -07001432 desc: "Any with invalid UTF-8",
Damien Neil5c5b5312019-05-14 12:44:37 -07001433 umo: prototext.UnmarshalOptions{
Joe Tsai0fc49f82019-05-01 12:29:25 -07001434 Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&pb3.Nested{})),
Herbie Ong21a39742019-04-08 17:32:44 -07001435 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07001436 inputMessage: &anypb.Any{},
Herbie Ong21a39742019-04-08 17:32:44 -07001437 inputText: `
1438[pb3.Nested]: {
1439 s_string: "abc\xff"
1440}
1441`,
Herbie Ong21a39742019-04-08 17:32:44 -07001442 wantErr: true,
1443 }, {
Herbie Ong66c365c2019-01-04 14:08:41 -08001444 desc: "Any expanded with unregistered type",
Damien Neil5c5b5312019-05-14 12:44:37 -07001445 umo: prototext.UnmarshalOptions{Resolver: preg.NewTypes()},
Joe Tsaia95b29f2019-05-16 12:47:20 -07001446 inputMessage: &anypb.Any{},
Herbie Ong300cff02019-03-20 18:05:16 -07001447 inputText: `[SomeMessage]: {}`,
1448 wantErr: true,
Herbie Ong66c365c2019-01-04 14:08:41 -08001449 }, {
1450 desc: "Any expanded with invalid value",
Damien Neil5c5b5312019-05-14 12:44:37 -07001451 umo: prototext.UnmarshalOptions{
Joe Tsai0fc49f82019-05-01 12:29:25 -07001452 Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&pb2.Nested{})),
Herbie Ong300cff02019-03-20 18:05:16 -07001453 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07001454 inputMessage: &anypb.Any{},
Herbie Ong300cff02019-03-20 18:05:16 -07001455 inputText: `[pb2.Nested]: 123`,
1456 wantErr: true,
Herbie Ong66c365c2019-01-04 14:08:41 -08001457 }, {
1458 desc: "Any expanded with unknown fields",
Damien Neil5c5b5312019-05-14 12:44:37 -07001459 umo: prototext.UnmarshalOptions{
Joe Tsai0fc49f82019-05-01 12:29:25 -07001460 Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&pb2.Nested{})),
Herbie Ong300cff02019-03-20 18:05:16 -07001461 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07001462 inputMessage: &anypb.Any{},
Herbie Ong300cff02019-03-20 18:05:16 -07001463 inputText: `
Herbie Ong66c365c2019-01-04 14:08:41 -08001464[pb2.Nested]: {}
1465unknown: ""
Herbie Ong66c365c2019-01-04 14:08:41 -08001466`,
1467 wantErr: true,
1468 }, {
1469 desc: "Any contains expanded and unexpanded fields",
Damien Neil5c5b5312019-05-14 12:44:37 -07001470 umo: prototext.UnmarshalOptions{
Joe Tsai0fc49f82019-05-01 12:29:25 -07001471 Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&pb2.Nested{})),
Herbie Ong300cff02019-03-20 18:05:16 -07001472 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07001473 inputMessage: &anypb.Any{},
Herbie Ong300cff02019-03-20 18:05:16 -07001474 inputText: `
Herbie Ong66c365c2019-01-04 14:08:41 -08001475[pb2.Nested]: {}
1476type_url: "pb2.Nested"
Herbie Ong66c365c2019-01-04 14:08:41 -08001477`,
1478 wantErr: true,
Herbie Ong800c9902018-12-06 15:28:53 -08001479 }}
1480
1481 for _, tt := range tests {
1482 tt := tt
1483 t.Run(tt.desc, func(t *testing.T) {
Joe Tsaicdb77732019-05-14 16:05:06 -07001484 err := tt.umo.Unmarshal([]byte(tt.inputText), tt.inputMessage)
Herbie Ong800c9902018-12-06 15:28:53 -08001485 if err != nil && !tt.wantErr {
1486 t.Errorf("Unmarshal() returned error: %v\n\n", err)
1487 }
1488 if err == nil && tt.wantErr {
1489 t.Error("Unmarshal() got nil error, want error\n\n")
1490 }
Herbie Ong70651952018-12-13 14:19:50 -08001491 if tt.wantMessage != nil && !protoV1.Equal(tt.inputMessage.(protoV1.Message), tt.wantMessage.(protoV1.Message)) {
Herbie Ong800c9902018-12-06 15:28:53 -08001492 t.Errorf("Unmarshal()\n<got>\n%v\n<want>\n%v\n", tt.inputMessage, tt.wantMessage)
1493 }
1494 })
1495 }
1496}