blob: ddebffad1653295b608a45e172eea6e8ea709d4b [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
5package textpb_test
6
7import (
8 "math"
9 "testing"
10
11 protoV1 "github.com/golang/protobuf/proto"
12 "github.com/golang/protobuf/v2/encoding/textpb"
Herbie Ong21a39742019-04-08 17:32:44 -070013 "github.com/golang/protobuf/v2/internal/errors"
Herbie Ong800c9902018-12-06 15:28:53 -080014 "github.com/golang/protobuf/v2/internal/scalar"
Herbie Ong70651952018-12-13 14:19:50 -080015 "github.com/golang/protobuf/v2/proto"
Herbie Ongc525c972018-12-18 18:04:31 -080016 preg "github.com/golang/protobuf/v2/reflect/protoregistry"
Herbie Ong800c9902018-12-06 15:28:53 -080017
Herbie Ong8170d692019-02-13 14:13:21 -080018 "github.com/golang/protobuf/v2/encoding/testprotos/pb2"
19 "github.com/golang/protobuf/v2/encoding/testprotos/pb3"
Joe Tsai19058432019-02-27 21:46:29 -080020 knownpb "github.com/golang/protobuf/v2/types/known"
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
Herbie Ong66c365c2019-01-04 14:08:41 -080026 umo textpb.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"`,
159 wantMessage: &pb3.Scalars{
160 SString: "abc\xff",
161 },
162 wantErr: true,
163 }, {
Herbie Ong800c9902018-12-06 15:28:53 -0800164 desc: "proto2 message contains unknown field",
165 inputMessage: &pb2.Scalars{},
166 inputText: "unknown_field: 123",
167 wantErr: true,
168 }, {
169 desc: "proto3 message contains unknown field",
170 inputMessage: &pb3.Scalars{},
171 inputText: "unknown_field: 456",
172 wantErr: true,
173 }, {
174 desc: "proto2 numeric key field",
175 inputMessage: &pb2.Scalars{},
176 inputText: "1: true",
177 wantErr: true,
178 }, {
179 desc: "proto3 numeric key field",
180 inputMessage: &pb3.Scalars{},
181 inputText: "1: true",
182 wantErr: true,
183 }, {
184 desc: "invalid bool value",
185 inputMessage: &pb3.Scalars{},
186 inputText: "s_bool: 123",
187 wantErr: true,
188 }, {
189 desc: "invalid int32 value",
190 inputMessage: &pb3.Scalars{},
191 inputText: "s_int32: not_a_num",
192 wantErr: true,
193 }, {
194 desc: "invalid int64 value",
195 inputMessage: &pb3.Scalars{},
196 inputText: "s_int64: 'not a num either'",
197 wantErr: true,
198 }, {
199 desc: "invalid uint32 value",
200 inputMessage: &pb3.Scalars{},
201 inputText: "s_fixed32: -42",
202 wantErr: true,
203 }, {
204 desc: "invalid uint64 value",
205 inputMessage: &pb3.Scalars{},
206 inputText: "s_uint64: -47",
207 wantErr: true,
208 }, {
209 desc: "invalid sint32 value",
210 inputMessage: &pb3.Scalars{},
211 inputText: "s_sint32: '42'",
212 wantErr: true,
213 }, {
214 desc: "invalid sint64 value",
215 inputMessage: &pb3.Scalars{},
216 inputText: "s_sint64: '-47'",
217 wantErr: true,
218 }, {
219 desc: "invalid fixed32 value",
220 inputMessage: &pb3.Scalars{},
221 inputText: "s_fixed32: -42",
222 wantErr: true,
223 }, {
224 desc: "invalid fixed64 value",
225 inputMessage: &pb3.Scalars{},
226 inputText: "s_fixed64: -42",
227 wantErr: true,
228 }, {
229 desc: "invalid sfixed32 value",
230 inputMessage: &pb3.Scalars{},
231 inputText: "s_sfixed32: 'not valid'",
232 wantErr: true,
233 }, {
234 desc: "invalid sfixed64 value",
235 inputMessage: &pb3.Scalars{},
236 inputText: "s_sfixed64: bad",
237 wantErr: true,
238 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800239 desc: "float positive infinity",
Herbie Ong800c9902018-12-06 15:28:53 -0800240 inputMessage: &pb3.Scalars{},
241 inputText: "s_float: inf",
242 wantMessage: &pb3.Scalars{
243 SFloat: float32(math.Inf(1)),
244 },
245 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800246 desc: "float negative infinity",
Herbie Ong800c9902018-12-06 15:28:53 -0800247 inputMessage: &pb3.Scalars{},
248 inputText: "s_float: -inf",
249 wantMessage: &pb3.Scalars{
250 SFloat: float32(math.Inf(-1)),
251 },
252 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800253 desc: "double positive infinity",
Herbie Ong800c9902018-12-06 15:28:53 -0800254 inputMessage: &pb3.Scalars{},
255 inputText: "s_double: inf",
256 wantMessage: &pb3.Scalars{
257 SDouble: math.Inf(1),
258 },
259 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800260 desc: "double negative infinity",
Herbie Ong800c9902018-12-06 15:28:53 -0800261 inputMessage: &pb3.Scalars{},
262 inputText: "s_double: -inf",
263 wantMessage: &pb3.Scalars{
264 SDouble: math.Inf(-1),
265 },
266 }, {
267 desc: "invalid string value",
268 inputMessage: &pb3.Scalars{},
269 inputText: "s_string: invalid_string",
270 wantErr: true,
271 }, {
272 desc: "proto2 bytes set to empty string",
273 inputMessage: &pb2.Scalars{},
274 inputText: "opt_bytes: ''",
275 wantMessage: &pb2.Scalars{
276 OptBytes: []byte(""),
277 },
278 }, {
279 desc: "proto3 bytes set to empty string",
280 inputMessage: &pb3.Scalars{},
281 inputText: "s_bytes: ''",
282 wantMessage: &pb3.Scalars{},
283 }, {
284 desc: "proto2 duplicate singular field",
285 inputMessage: &pb2.Scalars{},
286 inputText: `
287opt_bool: true
288opt_bool: false
289`,
290 wantErr: true,
291 }, {
Herbie Ong800c9902018-12-06 15:28:53 -0800292 desc: "proto2 more duplicate singular field",
293 inputMessage: &pb2.Scalars{},
294 inputText: `
295opt_bool: true
296opt_string: "hello"
297opt_bool: false
298`,
299 wantErr: true,
300 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800301 desc: "proto2 invalid singular field",
302 inputMessage: &pb2.Scalars{},
303 inputText: `
304opt_bool: [true, false]
305`,
306 wantErr: true,
307 }, {
Herbie Ong800c9902018-12-06 15:28:53 -0800308 desc: "proto3 duplicate singular field",
309 inputMessage: &pb3.Scalars{},
310 inputText: `
311s_bool: false
312s_bool: true
313`,
314 wantErr: true,
315 }, {
316 desc: "proto3 more duplicate singular field",
317 inputMessage: &pb3.Scalars{},
318 inputText: `
319s_bool: false
320s_string: ""
321s_bool: true
322`,
323 wantErr: true,
324 }, {
325 desc: "proto2 enum",
326 inputMessage: &pb2.Enums{},
327 inputText: `
Herbie Ong8170d692019-02-13 14:13:21 -0800328opt_enum: ONE
Herbie Ong800c9902018-12-06 15:28:53 -0800329opt_nested_enum: UNO
330`,
331 wantMessage: &pb2.Enums{
Herbie Ong8170d692019-02-13 14:13:21 -0800332 OptEnum: pb2.Enum_ONE.Enum(),
Herbie Ong800c9902018-12-06 15:28:53 -0800333 OptNestedEnum: pb2.Enums_UNO.Enum(),
334 },
335 }, {
336 desc: "proto2 enum set to numeric values",
337 inputMessage: &pb2.Enums{},
338 inputText: `
Herbie Ong8170d692019-02-13 14:13:21 -0800339opt_enum: 2
Herbie Ong800c9902018-12-06 15:28:53 -0800340opt_nested_enum: 2
341`,
342 wantMessage: &pb2.Enums{
Herbie Ong8170d692019-02-13 14:13:21 -0800343 OptEnum: pb2.Enum_TWO.Enum(),
Herbie Ong800c9902018-12-06 15:28:53 -0800344 OptNestedEnum: pb2.Enums_DOS.Enum(),
345 },
346 }, {
347 desc: "proto2 enum set to unnamed numeric values",
348 inputMessage: &pb2.Enums{},
349 inputText: `
350opt_enum: 101
351opt_nested_enum: -101
352`,
353 wantMessage: &pb2.Enums{
354 OptEnum: pb2Enum(101),
355 OptNestedEnum: pb2Enums_NestedEnum(-101),
356 },
357 }, {
358 desc: "proto2 enum set to invalid named",
359 inputMessage: &pb2.Enums{},
360 inputText: `
Herbie Ong8170d692019-02-13 14:13:21 -0800361opt_enum: UNNAMED
Herbie Ong800c9902018-12-06 15:28:53 -0800362opt_nested_enum: UNNAMED_TOO
363`,
364 wantErr: true,
365 }, {
366 desc: "proto3 enum name value",
367 inputMessage: &pb3.Enums{},
368 inputText: `
369s_enum: ONE
370s_nested_enum: DIEZ
371`,
372 wantMessage: &pb3.Enums{
373 SEnum: pb3.Enum_ONE,
374 SNestedEnum: pb3.Enums_DIEZ,
375 },
376 }, {
377 desc: "proto3 enum numeric value",
378 inputMessage: &pb3.Enums{},
379 inputText: `
380s_enum: 2
Herbie Ong8170d692019-02-13 14:13:21 -0800381s_nested_enum: 2
Herbie Ong800c9902018-12-06 15:28:53 -0800382`,
383 wantMessage: &pb3.Enums{
384 SEnum: pb3.Enum_TWO,
Herbie Ong8170d692019-02-13 14:13:21 -0800385 SNestedEnum: pb3.Enums_DOS,
Herbie Ong800c9902018-12-06 15:28:53 -0800386 },
387 }, {
388 desc: "proto3 enum unnamed numeric value",
389 inputMessage: &pb3.Enums{},
390 inputText: `
391s_enum: 0x7fffffff
392s_nested_enum: -0x80000000
393`,
394 wantMessage: &pb3.Enums{
395 SEnum: 0x7fffffff,
396 SNestedEnum: -0x80000000,
397 },
398 }, {
399 desc: "proto2 nested empty messages",
400 inputMessage: &pb2.Nests{},
401 inputText: `
402opt_nested: {}
Herbie Ong0dcfb9a2019-01-14 15:32:26 -0800403OptGroup: {}
Herbie Ong800c9902018-12-06 15:28:53 -0800404`,
405 wantMessage: &pb2.Nests{
406 OptNested: &pb2.Nested{},
407 Optgroup: &pb2.Nests_OptGroup{},
408 },
409 }, {
410 desc: "proto2 nested messages",
411 inputMessage: &pb2.Nests{},
412 inputText: `
413opt_nested: {
414 opt_string: "nested message"
415 opt_nested: {
416 opt_string: "another nested message"
417 }
418}
419`,
420 wantMessage: &pb2.Nests{
421 OptNested: &pb2.Nested{
422 OptString: scalar.String("nested message"),
423 OptNested: &pb2.Nested{
424 OptString: scalar.String("another nested message"),
425 },
426 },
427 },
428 }, {
429 desc: "proto3 nested empty message",
430 inputMessage: &pb3.Nests{},
431 inputText: "s_nested: {}",
432 wantMessage: &pb3.Nests{
433 SNested: &pb3.Nested{},
434 },
435 }, {
436 desc: "proto3 nested message",
437 inputMessage: &pb3.Nests{},
438 inputText: `
439s_nested: {
440 s_string: "nested message"
441 s_nested: {
442 s_string: "another nested message"
443 }
444}
445`,
446 wantMessage: &pb3.Nests{
447 SNested: &pb3.Nested{
448 SString: "nested message",
449 SNested: &pb3.Nested{
450 SString: "another nested message",
451 },
452 },
453 },
454 }, {
Herbie Ong21a39742019-04-08 17:32:44 -0700455 desc: "proto3 nested message contains invalid UTF-8",
456 inputMessage: &pb3.Nests{},
457 inputText: `s_nested: {
458 s_string: "abc\xff"
459}
460`,
461 wantMessage: &pb3.Nests{
462 SNested: &pb3.Nested{
463 SString: "abc\xff",
464 },
465 },
466 wantErr: true,
467 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800468 desc: "oneof set to empty string",
469 inputMessage: &pb3.Oneofs{},
470 inputText: "oneof_string: ''",
471 wantMessage: &pb3.Oneofs{
472 Union: &pb3.Oneofs_OneofString{},
Herbie Ong800c9902018-12-06 15:28:53 -0800473 },
474 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800475 desc: "oneof set to string",
476 inputMessage: &pb3.Oneofs{},
477 inputText: "oneof_string: 'hello'",
478 wantMessage: &pb3.Oneofs{
479 Union: &pb3.Oneofs_OneofString{
480 OneofString: "hello",
Herbie Ong800c9902018-12-06 15:28:53 -0800481 },
482 },
483 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800484 desc: "oneof set to enum",
485 inputMessage: &pb3.Oneofs{},
486 inputText: "oneof_enum: TEN",
487 wantMessage: &pb3.Oneofs{
488 Union: &pb3.Oneofs_OneofEnum{
489 OneofEnum: pb3.Enum_TEN,
Herbie Ong800c9902018-12-06 15:28:53 -0800490 },
491 },
492 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800493 desc: "oneof set to empty message",
494 inputMessage: &pb3.Oneofs{},
495 inputText: "oneof_nested: {}",
496 wantMessage: &pb3.Oneofs{
497 Union: &pb3.Oneofs_OneofNested{
498 OneofNested: &pb3.Nested{},
499 },
500 },
501 }, {
502 desc: "oneof set to message",
503 inputMessage: &pb3.Oneofs{},
Herbie Ong800c9902018-12-06 15:28:53 -0800504 inputText: `
Herbie Ong8170d692019-02-13 14:13:21 -0800505oneof_nested: {
506 s_string: "nested message"
Herbie Ong800c9902018-12-06 15:28:53 -0800507}
508`,
Herbie Ong8170d692019-02-13 14:13:21 -0800509 wantMessage: &pb3.Oneofs{
510 Union: &pb3.Oneofs_OneofNested{
511 OneofNested: &pb3.Nested{
512 SString: "nested message",
Herbie Ong800c9902018-12-06 15:28:53 -0800513 },
514 },
515 },
516 }, {
Herbie Ong8a1d4602019-04-02 20:19:36 -0700517 desc: "oneof set to more than one field",
Herbie Ong8170d692019-02-13 14:13:21 -0800518 inputMessage: &pb3.Oneofs{},
Herbie Ong6470ea62019-01-07 18:56:57 -0800519 inputText: `
Herbie Ong8a1d4602019-04-02 20:19:36 -0700520oneof_enum: ZERO
521oneof_string: "hello"
Herbie Ong6470ea62019-01-07 18:56:57 -0800522`,
Herbie Ong8a1d4602019-04-02 20:19:36 -0700523 wantErr: true,
Herbie Ong6470ea62019-01-07 18:56:57 -0800524 }, {
Herbie Ong800c9902018-12-06 15:28:53 -0800525 desc: "repeated scalar using same field name",
526 inputMessage: &pb2.Repeats{},
527 inputText: `
528rpt_string: "a"
529rpt_string: "b"
530rpt_int32: 0xff
531rpt_float: 1.23
532rpt_bytes: "bytes"
533`,
534 wantMessage: &pb2.Repeats{
535 RptString: []string{"a", "b"},
536 RptInt32: []int32{0xff},
537 RptFloat: []float32{1.23},
538 RptBytes: [][]byte{[]byte("bytes")},
539 },
540 }, {
541 desc: "repeated using mix of [] and repeated field name",
542 inputMessage: &pb2.Repeats{},
543 inputText: `
544rpt_string: "a"
545rpt_bool: true
546rpt_string: ["x", "y"]
547rpt_bool: [ false, true ]
548rpt_string: "b"
549`,
550 wantMessage: &pb2.Repeats{
551 RptString: []string{"a", "x", "y", "b"},
552 RptBool: []bool{true, false, true},
553 },
554 }, {
Herbie Ong21a39742019-04-08 17:32:44 -0700555 desc: "repeated contains invalid UTF-8",
556 inputMessage: &pb2.Repeats{},
557 inputText: `rpt_string: "abc\xff"`,
558 wantMessage: &pb2.Repeats{
559 RptString: []string{"abc\xff"},
560 },
561 wantErr: true,
562 }, {
Herbie Ong800c9902018-12-06 15:28:53 -0800563 desc: "repeated enums",
564 inputMessage: &pb2.Enums{},
565 inputText: `
Herbie Ong8170d692019-02-13 14:13:21 -0800566rpt_enum: TEN
Herbie Ong800c9902018-12-06 15:28:53 -0800567rpt_enum: 1
568rpt_nested_enum: [DOS, 2]
569rpt_enum: 42
570rpt_nested_enum: -47
571`,
572 wantMessage: &pb2.Enums{
Herbie Ong8170d692019-02-13 14:13:21 -0800573 RptEnum: []pb2.Enum{pb2.Enum_TEN, pb2.Enum_ONE, 42},
Herbie Ong800c9902018-12-06 15:28:53 -0800574 RptNestedEnum: []pb2.Enums_NestedEnum{pb2.Enums_DOS, pb2.Enums_DOS, -47},
575 },
576 }, {
577 desc: "repeated nested messages",
578 inputMessage: &pb2.Nests{},
579 inputText: `
580rpt_nested: {
581 opt_string: "repeat nested one"
582}
583rpt_nested: {
584 opt_string: "repeat nested two"
585 opt_nested: {
586 opt_string: "inside repeat nested two"
587 }
588}
589rpt_nested: {}
590`,
591 wantMessage: &pb2.Nests{
592 RptNested: []*pb2.Nested{
593 {
594 OptString: scalar.String("repeat nested one"),
595 },
596 {
597 OptString: scalar.String("repeat nested two"),
598 OptNested: &pb2.Nested{
599 OptString: scalar.String("inside repeat nested two"),
600 },
601 },
602 {},
603 },
604 },
605 }, {
606 desc: "repeated group fields",
607 inputMessage: &pb2.Nests{},
608 inputText: `
Herbie Ong0dcfb9a2019-01-14 15:32:26 -0800609RptGroup: {
Herbie Ong8170d692019-02-13 14:13:21 -0800610 rpt_string: "hello"
611 rpt_string: "world"
Herbie Ong800c9902018-12-06 15:28:53 -0800612}
Herbie Ong0dcfb9a2019-01-14 15:32:26 -0800613RptGroup: {}
Herbie Ong800c9902018-12-06 15:28:53 -0800614`,
615 wantMessage: &pb2.Nests{
616 Rptgroup: []*pb2.Nests_RptGroup{
617 {
Herbie Ong8170d692019-02-13 14:13:21 -0800618 RptString: []string{"hello", "world"},
Herbie Ong800c9902018-12-06 15:28:53 -0800619 },
620 {},
621 },
622 },
623 }, {
624 desc: "map fields 1",
Herbie Ong8170d692019-02-13 14:13:21 -0800625 inputMessage: &pb3.Maps{},
Herbie Ong800c9902018-12-06 15:28:53 -0800626 inputText: `
627int32_to_str: {
628 key: -101
629 value: "-101"
630}
631int32_to_str: {
632 key: 0
633 value: "zero"
634}
Herbie Ong8170d692019-02-13 14:13:21 -0800635bool_to_uint32: {
636 key: false
637 value: 101
Herbie Ong800c9902018-12-06 15:28:53 -0800638}
639int32_to_str: {
640 key: 255
641 value: "0xff"
642}
643bool_to_uint32: {
Herbie Ong800c9902018-12-06 15:28:53 -0800644 key: true
645 value: 42
646}
647`,
Herbie Ong8170d692019-02-13 14:13:21 -0800648 wantMessage: &pb3.Maps{
Herbie Ong800c9902018-12-06 15:28:53 -0800649 Int32ToStr: map[int32]string{
650 -101: "-101",
651 0xff: "0xff",
652 0: "zero",
653 },
Herbie Ong800c9902018-12-06 15:28:53 -0800654 BoolToUint32: map[bool]uint32{
655 true: 42,
656 false: 101,
657 },
658 },
659 }, {
660 desc: "map fields 2",
Herbie Ong8170d692019-02-13 14:13:21 -0800661 inputMessage: &pb3.Maps{},
Herbie Ong800c9902018-12-06 15:28:53 -0800662 inputText: `
663uint64_to_enum: {
664 key: 1
Herbie Ong8170d692019-02-13 14:13:21 -0800665 value: ONE
Herbie Ong800c9902018-12-06 15:28:53 -0800666}
667uint64_to_enum: {
668 key: 2
Herbie Ong8170d692019-02-13 14:13:21 -0800669 value: 2
Herbie Ong800c9902018-12-06 15:28:53 -0800670}
671uint64_to_enum: {
672 key: 10
Herbie Ong8170d692019-02-13 14:13:21 -0800673 value: 101
Herbie Ong800c9902018-12-06 15:28:53 -0800674}
675`,
Herbie Ong8170d692019-02-13 14:13:21 -0800676 wantMessage: &pb3.Maps{
677 Uint64ToEnum: map[uint64]pb3.Enum{
678 1: pb3.Enum_ONE,
679 2: pb3.Enum_TWO,
680 10: 101,
Herbie Ong800c9902018-12-06 15:28:53 -0800681 },
682 },
683 }, {
684 desc: "map fields 3",
Herbie Ong8170d692019-02-13 14:13:21 -0800685 inputMessage: &pb3.Maps{},
Herbie Ong800c9902018-12-06 15:28:53 -0800686 inputText: `
687str_to_nested: {
688 key: "nested_one"
689 value: {
Herbie Ong8170d692019-02-13 14:13:21 -0800690 s_string: "nested in a map"
Herbie Ong800c9902018-12-06 15:28:53 -0800691 }
692}
693`,
Herbie Ong8170d692019-02-13 14:13:21 -0800694 wantMessage: &pb3.Maps{
695 StrToNested: map[string]*pb3.Nested{
696 "nested_one": &pb3.Nested{
697 SString: "nested in a map",
Herbie Ong800c9902018-12-06 15:28:53 -0800698 },
699 },
700 },
701 }, {
702 desc: "map fields 4",
Herbie Ong8170d692019-02-13 14:13:21 -0800703 inputMessage: &pb3.Maps{},
Herbie Ong800c9902018-12-06 15:28:53 -0800704 inputText: `
705str_to_oneofs: {
706 key: "nested"
707 value: {
Herbie Ong8170d692019-02-13 14:13:21 -0800708 oneof_nested: {
709 s_string: "nested oneof in map field value"
Herbie Ong800c9902018-12-06 15:28:53 -0800710 }
711 }
712}
713str_to_oneofs: {
714 key: "string"
715 value: {
Herbie Ong8170d692019-02-13 14:13:21 -0800716 oneof_string: "hello"
Herbie Ong800c9902018-12-06 15:28:53 -0800717 }
718}
719`,
Herbie Ong8170d692019-02-13 14:13:21 -0800720 wantMessage: &pb3.Maps{
721 StrToOneofs: map[string]*pb3.Oneofs{
722 "string": &pb3.Oneofs{
723 Union: &pb3.Oneofs_OneofString{
724 OneofString: "hello",
Herbie Ong800c9902018-12-06 15:28:53 -0800725 },
726 },
Herbie Ong8170d692019-02-13 14:13:21 -0800727 "nested": &pb3.Oneofs{
728 Union: &pb3.Oneofs_OneofNested{
729 OneofNested: &pb3.Nested{
730 SString: "nested oneof in map field value",
Herbie Ong800c9902018-12-06 15:28:53 -0800731 },
732 },
733 },
734 },
735 },
736 }, {
737 desc: "map contains duplicate keys",
Herbie Ong8170d692019-02-13 14:13:21 -0800738 inputMessage: &pb3.Maps{},
Herbie Ong800c9902018-12-06 15:28:53 -0800739 inputText: `
740int32_to_str: {
741 key: 0
742 value: "cero"
743}
744int32_to_str: {
745 key: 0
746 value: "zero"
747}
748`,
Herbie Ong8170d692019-02-13 14:13:21 -0800749 wantMessage: &pb3.Maps{
Herbie Ong800c9902018-12-06 15:28:53 -0800750 Int32ToStr: map[int32]string{
751 0: "zero",
752 },
753 },
754 }, {
755 desc: "map contains duplicate key 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: 0
760 key: 1
761 value: "cero"
762}
763`,
764 wantErr: true,
765 }, {
766 desc: "map contains duplicate value fields",
Herbie Ong8170d692019-02-13 14:13:21 -0800767 inputMessage: &pb3.Maps{},
Herbie Ong800c9902018-12-06 15:28:53 -0800768 inputText: `
769int32_to_str: {
770 key: 1
771 value: "cero"
772 value: "uno"
773}
774`,
775 wantErr: true,
776 }, {
777 desc: "map contains missing key",
Herbie Ong8170d692019-02-13 14:13:21 -0800778 inputMessage: &pb3.Maps{},
Herbie Ong800c9902018-12-06 15:28:53 -0800779 inputText: `
780int32_to_str: {
781 value: "zero"
782}
Herbie Ong8170d692019-02-13 14:13:21 -0800783bool_to_uint32: {
784 value: 47
785}
786str_to_nested: {
787 value: {}
788}
Herbie Ong800c9902018-12-06 15:28:53 -0800789`,
Herbie Ong8170d692019-02-13 14:13:21 -0800790 wantMessage: &pb3.Maps{
Herbie Ong800c9902018-12-06 15:28:53 -0800791 Int32ToStr: map[int32]string{
792 0: "zero",
793 },
Herbie Ong8170d692019-02-13 14:13:21 -0800794 BoolToUint32: map[bool]uint32{
795 false: 47,
796 },
797 StrToNested: map[string]*pb3.Nested{
798 "": {},
799 },
Herbie Ong800c9902018-12-06 15:28:53 -0800800 },
801 }, {
802 desc: "map contains missing value",
Herbie Ong8170d692019-02-13 14:13:21 -0800803 inputMessage: &pb3.Maps{},
Herbie Ong800c9902018-12-06 15:28:53 -0800804 inputText: `
805int32_to_str: {
806 key: 100
807}
Herbie Ong8170d692019-02-13 14:13:21 -0800808bool_to_uint32: {
809 key: true
810}
811uint64_to_enum: {
812 key: 101
813}
814str_to_nested: {
815 key: "hello"
816}
Herbie Ong800c9902018-12-06 15:28:53 -0800817`,
Herbie Ong8170d692019-02-13 14:13:21 -0800818 wantMessage: &pb3.Maps{
Herbie Ong800c9902018-12-06 15:28:53 -0800819 Int32ToStr: map[int32]string{
820 100: "",
821 },
Herbie Ong8170d692019-02-13 14:13:21 -0800822 BoolToUint32: map[bool]uint32{
823 true: 0,
824 },
825 Uint64ToEnum: map[uint64]pb3.Enum{
826 101: pb3.Enum_ZERO,
827 },
828 StrToNested: map[string]*pb3.Nested{
829 "hello": {},
830 },
Herbie Ong800c9902018-12-06 15:28:53 -0800831 },
832 }, {
833 desc: "map contains missing key and value",
Herbie Ong8170d692019-02-13 14:13:21 -0800834 inputMessage: &pb3.Maps{},
Herbie Ong800c9902018-12-06 15:28:53 -0800835 inputText: `
836int32_to_str: {}
Herbie Ong8170d692019-02-13 14:13:21 -0800837bool_to_uint32: {}
838uint64_to_enum: {}
839str_to_nested: {}
Herbie Ong800c9902018-12-06 15:28:53 -0800840`,
Herbie Ong8170d692019-02-13 14:13:21 -0800841 wantMessage: &pb3.Maps{
842 Int32ToStr: map[int32]string{
843 0: "",
844 },
845 BoolToUint32: map[bool]uint32{
846 false: 0,
847 },
848 Uint64ToEnum: map[uint64]pb3.Enum{
849 0: pb3.Enum_ZERO,
850 },
851 StrToNested: map[string]*pb3.Nested{
852 "": {},
853 },
854 },
855 }, {
856 desc: "map contains overriding entries",
857 inputMessage: &pb3.Maps{},
858 inputText: `
859int32_to_str: {
860 key: 0
861}
862int32_to_str: {
863 value: "empty"
864}
865int32_to_str: {}
866`,
867 wantMessage: &pb3.Maps{
Herbie Ong800c9902018-12-06 15:28:53 -0800868 Int32ToStr: map[int32]string{
869 0: "",
870 },
871 },
872 }, {
Herbie Ong21a39742019-04-08 17:32:44 -0700873 desc: "map field value contains invalid UTF-8",
874 inputMessage: &pb3.Maps{},
875 inputText: `int32_to_str: {
876 key: 101
877 value: "abc\xff"
878}
879`,
880 wantMessage: &pb3.Maps{
881 Int32ToStr: map[int32]string{
882 101: "abc\xff",
883 },
884 },
885 wantErr: true,
886 }, {
887 desc: "map field key contains invalid UTF-8",
888 inputMessage: &pb3.Maps{},
889 inputText: `str_to_nested: {
890 key: "abc\xff"
891 value: {}
892}
893`,
894 wantMessage: &pb3.Maps{
895 StrToNested: map[string]*pb3.Nested{
896 "abc\xff": {},
897 },
898 },
899 wantErr: true,
900 }, {
Herbie Ong800c9902018-12-06 15:28:53 -0800901 desc: "map contains unknown field",
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: 0
906 value: "cero"
907 unknown: "bad"
908}
909`,
910 wantErr: true,
911 }, {
912 desc: "map contains extension-like key field",
Herbie Ong8170d692019-02-13 14:13:21 -0800913 inputMessage: &pb3.Maps{},
Herbie Ong800c9902018-12-06 15:28:53 -0800914 inputText: `
915int32_to_str: {
916 [key]: 10
917 value: "ten"
918}
919`,
920 wantErr: true,
921 }, {
922 desc: "map contains invalid key",
Herbie Ong8170d692019-02-13 14:13:21 -0800923 inputMessage: &pb3.Maps{},
Herbie Ong800c9902018-12-06 15:28:53 -0800924 inputText: `
925int32_to_str: {
926 key: "invalid"
927 value: "cero"
928}
929`,
930 wantErr: true,
931 }, {
932 desc: "map contains invalid value",
Herbie Ong8170d692019-02-13 14:13:21 -0800933 inputMessage: &pb3.Maps{},
Herbie Ong800c9902018-12-06 15:28:53 -0800934 inputText: `
935int32_to_str: {
936 key: 100
937 value: 101
938}
939`,
940 wantErr: true,
941 }, {
942 desc: "map using mix of [] and repeated",
Herbie Ong8170d692019-02-13 14:13:21 -0800943 inputMessage: &pb3.Maps{},
Herbie Ong800c9902018-12-06 15:28:53 -0800944 inputText: `
945int32_to_str: {
946 key: 1
947 value: "one"
948}
949int32_to_str: [
950 {
951 key: 2
952 value: "not this"
953 },
954 {
955 },
956 {
957 key: 3
958 value: "three"
959 }
960]
961int32_to_str: {
962 key: 2
963 value: "two"
964}
965`,
Herbie Ong8170d692019-02-13 14:13:21 -0800966 wantMessage: &pb3.Maps{
Herbie Ong800c9902018-12-06 15:28:53 -0800967 Int32ToStr: map[int32]string{
968 0: "",
969 1: "one",
970 2: "two",
971 3: "three",
972 },
973 },
974 }, {
Herbie Ong42577ea2019-03-26 16:26:22 -0700975 desc: "required fields not set",
Herbie Ong800c9902018-12-06 15:28:53 -0800976 inputMessage: &pb2.Requireds{},
977 wantErr: true,
978 }, {
Herbie Ong42577ea2019-03-26 16:26:22 -0700979 desc: "required field set",
Herbie Ong800c9902018-12-06 15:28:53 -0800980 inputMessage: &pb2.PartialRequired{},
981 inputText: "req_string: 'this is required'",
982 wantMessage: &pb2.PartialRequired{
983 ReqString: scalar.String("this is required"),
984 },
985 }, {
Herbie Ong42577ea2019-03-26 16:26:22 -0700986 desc: "required fields partially set",
Herbie Ong800c9902018-12-06 15:28:53 -0800987 inputMessage: &pb2.Requireds{},
988 inputText: `
989req_bool: false
Herbie Ong800c9902018-12-06 15:28:53 -0800990req_sfixed64: 3203386110
991req_string: "hello"
Herbie Ong8170d692019-02-13 14:13:21 -0800992req_enum: ONE
Herbie Ong800c9902018-12-06 15:28:53 -0800993`,
994 wantMessage: &pb2.Requireds{
995 ReqBool: scalar.Bool(false),
Herbie Ong800c9902018-12-06 15:28:53 -0800996 ReqSfixed64: scalar.Int64(0xbeefcafe),
997 ReqString: scalar.String("hello"),
Herbie Ong8170d692019-02-13 14:13:21 -0800998 ReqEnum: pb2.Enum_ONE.Enum(),
Herbie Ong800c9902018-12-06 15:28:53 -0800999 },
1000 wantErr: true,
1001 }, {
Herbie Ong42577ea2019-03-26 16:26:22 -07001002 desc: "required fields partially set with AllowPartial",
1003 umo: textpb.UnmarshalOptions{AllowPartial: true},
1004 inputMessage: &pb2.Requireds{},
1005 inputText: `
1006req_bool: false
1007req_sfixed64: 3203386110
1008req_string: "hello"
1009req_enum: ONE
1010`,
1011 wantMessage: &pb2.Requireds{
1012 ReqBool: scalar.Bool(false),
1013 ReqSfixed64: scalar.Int64(0xbeefcafe),
1014 ReqString: scalar.String("hello"),
1015 ReqEnum: pb2.Enum_ONE.Enum(),
1016 },
1017 }, {
1018 desc: "required fields all set",
Herbie Ong800c9902018-12-06 15:28:53 -08001019 inputMessage: &pb2.Requireds{},
1020 inputText: `
1021req_bool: false
Herbie Ong800c9902018-12-06 15:28:53 -08001022req_sfixed64: 0
Herbie Ong800c9902018-12-06 15:28:53 -08001023req_double: 0
1024req_string: ""
Herbie Ong8170d692019-02-13 14:13:21 -08001025req_enum: ONE
Herbie Ong800c9902018-12-06 15:28:53 -08001026req_nested: {}
1027`,
1028 wantMessage: &pb2.Requireds{
1029 ReqBool: scalar.Bool(false),
Herbie Ong800c9902018-12-06 15:28:53 -08001030 ReqSfixed64: scalar.Int64(0),
Herbie Ong800c9902018-12-06 15:28:53 -08001031 ReqDouble: scalar.Float64(0),
1032 ReqString: scalar.String(""),
Herbie Ong8170d692019-02-13 14:13:21 -08001033 ReqEnum: pb2.Enum_ONE.Enum(),
Herbie Ong800c9902018-12-06 15:28:53 -08001034 ReqNested: &pb2.Nested{},
1035 },
1036 }, {
1037 desc: "indirect required field",
1038 inputMessage: &pb2.IndirectRequired{},
1039 inputText: "opt_nested: {}",
1040 wantMessage: &pb2.IndirectRequired{
1041 OptNested: &pb2.NestedWithRequired{},
1042 },
1043 wantErr: true,
1044 }, {
Herbie Ong42577ea2019-03-26 16:26:22 -07001045 desc: "indirect required field with AllowPartial",
1046 umo: textpb.UnmarshalOptions{AllowPartial: true},
1047 inputMessage: &pb2.IndirectRequired{},
1048 inputText: "opt_nested: {}",
1049 wantMessage: &pb2.IndirectRequired{
1050 OptNested: &pb2.NestedWithRequired{},
1051 },
1052 }, {
Herbie Ong800c9902018-12-06 15:28:53 -08001053 desc: "indirect required field in repeated",
1054 inputMessage: &pb2.IndirectRequired{},
1055 inputText: `
1056rpt_nested: {
1057 req_string: "one"
1058}
1059rpt_nested: {}
Herbie Ong800c9902018-12-06 15:28:53 -08001060`,
1061 wantMessage: &pb2.IndirectRequired{
1062 RptNested: []*pb2.NestedWithRequired{
1063 {
1064 ReqString: scalar.String("one"),
1065 },
1066 {},
Herbie Ong800c9902018-12-06 15:28:53 -08001067 },
1068 },
1069 wantErr: true,
1070 }, {
Herbie Ong42577ea2019-03-26 16:26:22 -07001071 desc: "indirect required field in repeated with AllowPartial",
1072 umo: textpb.UnmarshalOptions{AllowPartial: true},
1073 inputMessage: &pb2.IndirectRequired{},
1074 inputText: `
1075rpt_nested: {
1076 req_string: "one"
1077}
1078rpt_nested: {}
1079`,
1080 wantMessage: &pb2.IndirectRequired{
1081 RptNested: []*pb2.NestedWithRequired{
1082 {
1083 ReqString: scalar.String("one"),
1084 },
1085 {},
1086 },
1087 },
1088 }, {
Herbie Ong800c9902018-12-06 15:28:53 -08001089 desc: "indirect required field in map",
1090 inputMessage: &pb2.IndirectRequired{},
1091 inputText: `
1092str_to_nested: {
1093 key: "missing"
1094}
1095str_to_nested: {
1096 key: "contains"
1097 value: {
1098 req_string: "here"
1099 }
1100}
1101`,
1102 wantMessage: &pb2.IndirectRequired{
1103 StrToNested: map[string]*pb2.NestedWithRequired{
1104 "missing": &pb2.NestedWithRequired{},
1105 "contains": &pb2.NestedWithRequired{
1106 ReqString: scalar.String("here"),
1107 },
1108 },
1109 },
1110 wantErr: true,
Herbie Ong7c624e22018-12-13 14:41:22 -08001111 }, {
Herbie Ong42577ea2019-03-26 16:26:22 -07001112 desc: "indirect required field in map with AllowPartial",
1113 umo: textpb.UnmarshalOptions{AllowPartial: true},
1114 inputMessage: &pb2.IndirectRequired{},
1115 inputText: `
1116str_to_nested: {
1117 key: "missing"
1118}
1119str_to_nested: {
1120 key: "contains"
1121 value: {
1122 req_string: "here"
1123 }
1124}
1125`,
1126 wantMessage: &pb2.IndirectRequired{
1127 StrToNested: map[string]*pb2.NestedWithRequired{
1128 "missing": &pb2.NestedWithRequired{},
1129 "contains": &pb2.NestedWithRequired{
1130 ReqString: scalar.String("here"),
1131 },
1132 },
1133 },
1134 }, {
Herbie Ong8170d692019-02-13 14:13:21 -08001135 desc: "indirect required field in oneof",
1136 inputMessage: &pb2.IndirectRequired{},
1137 inputText: `oneof_nested: {}
1138`,
1139 wantMessage: &pb2.IndirectRequired{
1140 Union: &pb2.IndirectRequired_OneofNested{
1141 OneofNested: &pb2.NestedWithRequired{},
1142 },
1143 },
1144 wantErr: true,
1145 }, {
Herbie Ong42577ea2019-03-26 16:26:22 -07001146 desc: "indirect required field in oneof with AllowPartial",
1147 umo: textpb.UnmarshalOptions{AllowPartial: true},
1148 inputMessage: &pb2.IndirectRequired{},
1149 inputText: `oneof_nested: {}
1150`,
1151 wantMessage: &pb2.IndirectRequired{
1152 Union: &pb2.IndirectRequired_OneofNested{
1153 OneofNested: &pb2.NestedWithRequired{},
1154 },
1155 },
1156 }, {
Herbie Ong7c624e22018-12-13 14:41:22 -08001157 desc: "ignore reserved field",
1158 inputMessage: &pb2.Nests{},
1159 inputText: "reserved_field: 'ignore this'",
1160 wantMessage: &pb2.Nests{},
Herbie Ongc525c972018-12-18 18:04:31 -08001161 }, {
1162 desc: "extensions of non-repeated fields",
1163 inputMessage: &pb2.Extensions{},
1164 inputText: `opt_string: "non-extension field"
1165[pb2.opt_ext_bool]: true
1166opt_bool: true
1167[pb2.opt_ext_nested]: {
1168 opt_string: "nested in an extension"
1169 opt_nested: {
1170 opt_string: "another nested in an extension"
1171 }
1172}
1173[pb2.opt_ext_string]: "extension field"
1174opt_int32: 42
Herbie Ong8170d692019-02-13 14:13:21 -08001175[pb2.opt_ext_enum]: TEN
Herbie Ongc525c972018-12-18 18:04:31 -08001176`,
1177 wantMessage: func() proto.Message {
1178 m := &pb2.Extensions{
1179 OptString: scalar.String("non-extension field"),
1180 OptBool: scalar.Bool(true),
1181 OptInt32: scalar.Int32(42),
1182 }
1183 setExtension(m, pb2.E_OptExtBool, true)
1184 setExtension(m, pb2.E_OptExtString, "extension field")
Herbie Ong8170d692019-02-13 14:13:21 -08001185 setExtension(m, pb2.E_OptExtEnum, pb2.Enum_TEN)
Herbie Ongc525c972018-12-18 18:04:31 -08001186 setExtension(m, pb2.E_OptExtNested, &pb2.Nested{
1187 OptString: scalar.String("nested in an extension"),
1188 OptNested: &pb2.Nested{
1189 OptString: scalar.String("another nested in an extension"),
1190 },
1191 })
1192 return m
1193 }(),
1194 }, {
Herbie Ong21a39742019-04-08 17:32:44 -07001195 desc: "extension field contains invalid UTF-8",
1196 inputMessage: &pb2.Extensions{},
1197 inputText: `[pb2.opt_ext_string]: "abc\xff"`,
1198 wantMessage: func() proto.Message {
1199 m := &pb2.Extensions{}
1200 setExtension(m, pb2.E_OptExtString, "abc\xff")
1201 return m
1202 }(),
1203 wantErr: true,
1204 }, {
Herbie Ongc525c972018-12-18 18:04:31 -08001205 desc: "extensions of repeated fields",
1206 inputMessage: &pb2.Extensions{},
Herbie Ong8170d692019-02-13 14:13:21 -08001207 inputText: `[pb2.rpt_ext_enum]: TEN
Herbie Ongc525c972018-12-18 18:04:31 -08001208[pb2.rpt_ext_enum]: 101
1209[pb2.rpt_ext_fixed32]: 42
Herbie Ong8170d692019-02-13 14:13:21 -08001210[pb2.rpt_ext_enum]: ONE
Herbie Ongc525c972018-12-18 18:04:31 -08001211[pb2.rpt_ext_nested]: {
1212 opt_string: "one"
1213}
1214[pb2.rpt_ext_nested]: {
1215 opt_string: "two"
1216}
1217[pb2.rpt_ext_fixed32]: 47
1218[pb2.rpt_ext_nested]: {
1219 opt_string: "three"
1220}
1221`,
1222 wantMessage: func() proto.Message {
1223 m := &pb2.Extensions{}
Herbie Ong8170d692019-02-13 14:13:21 -08001224 setExtension(m, pb2.E_RptExtEnum, &[]pb2.Enum{pb2.Enum_TEN, 101, pb2.Enum_ONE})
Herbie Ongc525c972018-12-18 18:04:31 -08001225 setExtension(m, pb2.E_RptExtFixed32, &[]uint32{42, 47})
1226 setExtension(m, pb2.E_RptExtNested, &[]*pb2.Nested{
1227 &pb2.Nested{OptString: scalar.String("one")},
1228 &pb2.Nested{OptString: scalar.String("two")},
1229 &pb2.Nested{OptString: scalar.String("three")},
1230 })
1231 return m
1232 }(),
1233 }, {
1234 desc: "extensions of non-repeated fields in another message",
1235 inputMessage: &pb2.Extensions{},
1236 inputText: `[pb2.ExtensionsContainer.opt_ext_bool]: true
Herbie Ong8170d692019-02-13 14:13:21 -08001237[pb2.ExtensionsContainer.opt_ext_enum]: TEN
Herbie Ongc525c972018-12-18 18:04:31 -08001238[pb2.ExtensionsContainer.opt_ext_nested]: {
1239 opt_string: "nested in an extension"
1240 opt_nested: {
1241 opt_string: "another nested in an extension"
1242 }
1243}
1244[pb2.ExtensionsContainer.opt_ext_string]: "extension field"
1245`,
1246 wantMessage: func() proto.Message {
1247 m := &pb2.Extensions{}
1248 setExtension(m, pb2.E_ExtensionsContainer_OptExtBool, true)
1249 setExtension(m, pb2.E_ExtensionsContainer_OptExtString, "extension field")
Herbie Ong8170d692019-02-13 14:13:21 -08001250 setExtension(m, pb2.E_ExtensionsContainer_OptExtEnum, pb2.Enum_TEN)
Herbie Ongc525c972018-12-18 18:04:31 -08001251 setExtension(m, pb2.E_ExtensionsContainer_OptExtNested, &pb2.Nested{
1252 OptString: scalar.String("nested in an extension"),
1253 OptNested: &pb2.Nested{
1254 OptString: scalar.String("another nested in an extension"),
1255 },
1256 })
1257 return m
1258 }(),
1259 }, {
1260 desc: "extensions of repeated fields in another message",
1261 inputMessage: &pb2.Extensions{},
1262 inputText: `opt_string: "non-extension field"
1263opt_bool: true
1264opt_int32: 42
1265[pb2.ExtensionsContainer.rpt_ext_nested]: {
1266 opt_string: "one"
1267}
Herbie Ong8170d692019-02-13 14:13:21 -08001268[pb2.ExtensionsContainer.rpt_ext_enum]: TEN
Herbie Ongc525c972018-12-18 18:04:31 -08001269[pb2.ExtensionsContainer.rpt_ext_nested]: {
1270 opt_string: "two"
1271}
1272[pb2.ExtensionsContainer.rpt_ext_enum]: 101
1273[pb2.ExtensionsContainer.rpt_ext_string]: "hello"
Herbie Ong8170d692019-02-13 14:13:21 -08001274[pb2.ExtensionsContainer.rpt_ext_enum]: ONE
Herbie Ongc525c972018-12-18 18:04:31 -08001275[pb2.ExtensionsContainer.rpt_ext_nested]: {
1276 opt_string: "three"
1277}
1278[pb2.ExtensionsContainer.rpt_ext_string]: "world"
1279`,
1280 wantMessage: func() proto.Message {
1281 m := &pb2.Extensions{
1282 OptString: scalar.String("non-extension field"),
1283 OptBool: scalar.Bool(true),
1284 OptInt32: scalar.Int32(42),
1285 }
Herbie Ong8170d692019-02-13 14:13:21 -08001286 setExtension(m, pb2.E_ExtensionsContainer_RptExtEnum, &[]pb2.Enum{pb2.Enum_TEN, 101, pb2.Enum_ONE})
Herbie Ongc525c972018-12-18 18:04:31 -08001287 setExtension(m, pb2.E_ExtensionsContainer_RptExtString, &[]string{"hello", "world"})
1288 setExtension(m, pb2.E_ExtensionsContainer_RptExtNested, &[]*pb2.Nested{
1289 &pb2.Nested{OptString: scalar.String("one")},
1290 &pb2.Nested{OptString: scalar.String("two")},
1291 &pb2.Nested{OptString: scalar.String("three")},
1292 })
1293 return m
1294 }(),
1295 }, {
1296 desc: "invalid extension field name",
1297 inputMessage: &pb2.Extensions{},
1298 inputText: "[pb2.invalid_message_field]: true",
1299 wantErr: true,
Herbie Ong66c365c2019-01-04 14:08:41 -08001300 }, {
Herbie Ong6470ea62019-01-07 18:56:57 -08001301 desc: "MessageSet",
1302 inputMessage: &pb2.MessageSet{},
1303 inputText: `
1304[pb2.MessageSetExtension]: {
1305 opt_string: "a messageset extension"
1306}
1307[pb2.MessageSetExtension.ext_nested]: {
1308 opt_string: "just a regular extension"
1309}
1310[pb2.MessageSetExtension.not_message_set_extension]: {
1311 opt_string: "not a messageset extension"
1312}
1313`,
1314 wantMessage: func() proto.Message {
1315 m := &pb2.MessageSet{}
1316 setExtension(m, pb2.E_MessageSetExtension_MessageSetExtension, &pb2.MessageSetExtension{
1317 OptString: scalar.String("a messageset extension"),
1318 })
1319 setExtension(m, pb2.E_MessageSetExtension_NotMessageSetExtension, &pb2.MessageSetExtension{
1320 OptString: scalar.String("not a messageset extension"),
1321 })
1322 setExtension(m, pb2.E_MessageSetExtension_ExtNested, &pb2.Nested{
1323 OptString: scalar.String("just a regular extension"),
1324 })
1325 return m
1326 }(),
1327 }, {
1328 desc: "not real MessageSet 1",
1329 inputMessage: &pb2.FakeMessageSet{},
1330 inputText: `
1331[pb2.FakeMessageSetExtension.message_set_extension]: {
1332 opt_string: "not a messageset extension"
1333}
1334`,
1335 wantMessage: func() proto.Message {
1336 m := &pb2.FakeMessageSet{}
1337 setExtension(m, pb2.E_FakeMessageSetExtension_MessageSetExtension, &pb2.FakeMessageSetExtension{
1338 OptString: scalar.String("not a messageset extension"),
1339 })
1340 return m
1341 }(),
1342 }, {
1343 desc: "not real MessageSet 2",
1344 inputMessage: &pb2.FakeMessageSet{},
1345 inputText: `
1346[pb2.FakeMessageSetExtension]: {
1347 opt_string: "not a messageset extension"
1348}
1349`,
1350 wantErr: true,
1351 }, {
1352 desc: "not real MessageSet 3",
1353 inputMessage: &pb2.MessageSet{},
1354 inputText: `
1355[pb2.message_set_extension]: {
1356 opt_string: "another not a messageset extension"
Herbie Ong300cff02019-03-20 18:05:16 -07001357}`,
Herbie Ong6470ea62019-01-07 18:56:57 -08001358 wantMessage: func() proto.Message {
1359 m := &pb2.MessageSet{}
1360 setExtension(m, pb2.E_MessageSetExtension, &pb2.FakeMessageSetExtension{
1361 OptString: scalar.String("another not a messageset extension"),
1362 })
1363 return m
1364 }(),
1365 }, {
Herbie Ong66c365c2019-01-04 14:08:41 -08001366 desc: "Any not expanded",
Herbie Ong300cff02019-03-20 18:05:16 -07001367 inputMessage: &knownpb.Any{},
1368 inputText: `
Herbie Ong66c365c2019-01-04 14:08:41 -08001369type_url: "pb2.Nested"
1370value: "some bytes"
Herbie Ong66c365c2019-01-04 14:08:41 -08001371`,
Herbie Ong300cff02019-03-20 18:05:16 -07001372 wantMessage: &knownpb.Any{
1373 TypeUrl: "pb2.Nested",
1374 Value: []byte("some bytes"),
Herbie Ong66c365c2019-01-04 14:08:41 -08001375 },
1376 }, {
1377 desc: "Any not expanded missing value",
Herbie Ong300cff02019-03-20 18:05:16 -07001378 inputMessage: &knownpb.Any{},
1379 inputText: `type_url: "pb2.Nested"`,
1380 wantMessage: &knownpb.Any{
1381 TypeUrl: "pb2.Nested",
Herbie Ong66c365c2019-01-04 14:08:41 -08001382 },
1383 }, {
1384 desc: "Any not expanded missing type_url",
Herbie Ong300cff02019-03-20 18:05:16 -07001385 inputMessage: &knownpb.Any{},
1386 inputText: `value: "some bytes"`,
1387 wantMessage: &knownpb.Any{
1388 Value: []byte("some bytes"),
Herbie Ong66c365c2019-01-04 14:08:41 -08001389 },
1390 }, {
1391 desc: "Any expanded",
Herbie Ong300cff02019-03-20 18:05:16 -07001392 umo: textpb.UnmarshalOptions{
1393 Resolver: preg.NewTypes((&pb2.Nested{}).ProtoReflect().Type()),
1394 },
1395 inputMessage: &knownpb.Any{},
1396 inputText: `
1397[foobar/pb2.Nested]: {
1398 opt_string: "embedded inside Any"
1399 opt_nested: {
1400 opt_string: "inception"
Herbie Ong66c365c2019-01-04 14:08:41 -08001401 }
1402}
1403`,
1404 wantMessage: func() proto.Message {
1405 m := &pb2.Nested{
1406 OptString: scalar.String("embedded inside Any"),
1407 OptNested: &pb2.Nested{
1408 OptString: scalar.String("inception"),
1409 },
1410 }
Herbie Onge0cf15b2019-03-15 19:32:38 -07001411 b, err := proto.MarshalOptions{Deterministic: true}.Marshal(m)
Herbie Ong66c365c2019-01-04 14:08:41 -08001412 if err != nil {
1413 t.Fatalf("error in binary marshaling message for Any.value: %v", err)
1414 }
Herbie Ong300cff02019-03-20 18:05:16 -07001415 return &knownpb.Any{
1416 TypeUrl: "foobar/pb2.Nested",
1417 Value: b,
Herbie Ong66c365c2019-01-04 14:08:41 -08001418 }
1419 }(),
1420 }, {
1421 desc: "Any expanded with empty value",
Herbie Ong300cff02019-03-20 18:05:16 -07001422 umo: textpb.UnmarshalOptions{
1423 Resolver: preg.NewTypes((&pb2.Nested{}).ProtoReflect().Type()),
1424 },
1425 inputMessage: &knownpb.Any{},
1426 inputText: `[foo.com/pb2.Nested]: {}`,
1427 wantMessage: &knownpb.Any{
1428 TypeUrl: "foo.com/pb2.Nested",
Herbie Ong66c365c2019-01-04 14:08:41 -08001429 },
1430 }, {
1431 desc: "Any expanded with missing required error",
Herbie Ong300cff02019-03-20 18:05:16 -07001432 umo: textpb.UnmarshalOptions{
1433 Resolver: preg.NewTypes((&pb2.PartialRequired{}).ProtoReflect().Type()),
1434 },
1435 inputMessage: &knownpb.Any{},
1436 inputText: `
1437[pb2.PartialRequired]: {
1438 opt_string: "embedded inside Any"
Herbie Ong66c365c2019-01-04 14:08:41 -08001439}
1440`,
1441 wantMessage: func() proto.Message {
1442 m := &pb2.PartialRequired{
1443 OptString: scalar.String("embedded inside Any"),
1444 }
Damien Neil96c229a2019-04-03 12:17:24 -07001445 b, err := proto.MarshalOptions{
1446 AllowPartial: true,
1447 Deterministic: true,
1448 }.Marshal(m)
Herbie Ong300cff02019-03-20 18:05:16 -07001449 if err != nil {
Herbie Ong66c365c2019-01-04 14:08:41 -08001450 t.Fatalf("error in binary marshaling message for Any.value: %v", err)
1451 }
Herbie Ong300cff02019-03-20 18:05:16 -07001452 return &knownpb.Any{
1453 TypeUrl: "pb2.PartialRequired",
1454 Value: b,
Herbie Ong66c365c2019-01-04 14:08:41 -08001455 }
1456 }(),
1457 wantErr: true,
1458 }, {
Herbie Ong21a39742019-04-08 17:32:44 -07001459 desc: "Any with invalid UTF-8",
1460 umo: textpb.UnmarshalOptions{
1461 Resolver: preg.NewTypes((&pb3.Nested{}).ProtoReflect().Type()),
1462 },
1463 inputMessage: &knownpb.Any{},
1464 inputText: `
1465[pb3.Nested]: {
1466 s_string: "abc\xff"
1467}
1468`,
1469 wantMessage: func() proto.Message {
1470 m := &pb3.Nested{
1471 SString: "abc\xff",
1472 }
1473 var nerr errors.NonFatal
1474 b, err := proto.MarshalOptions{Deterministic: true}.Marshal(m)
1475 if !nerr.Merge(err) {
1476 t.Fatalf("error in binary marshaling message for Any.value: %v", err)
1477 }
1478 return &knownpb.Any{
1479 TypeUrl: string(m.ProtoReflect().Type().FullName()),
1480 Value: b,
1481 }
1482 }(),
1483 wantErr: true,
1484 }, {
Herbie Ong66c365c2019-01-04 14:08:41 -08001485 desc: "Any expanded with unregistered type",
1486 umo: textpb.UnmarshalOptions{Resolver: preg.NewTypes()},
Herbie Ong300cff02019-03-20 18:05:16 -07001487 inputMessage: &knownpb.Any{},
1488 inputText: `[SomeMessage]: {}`,
1489 wantErr: true,
Herbie Ong66c365c2019-01-04 14:08:41 -08001490 }, {
1491 desc: "Any expanded with invalid value",
Herbie Ong300cff02019-03-20 18:05:16 -07001492 umo: textpb.UnmarshalOptions{
1493 Resolver: preg.NewTypes((&pb2.Nested{}).ProtoReflect().Type()),
1494 },
1495 inputMessage: &knownpb.Any{},
1496 inputText: `[pb2.Nested]: 123`,
1497 wantErr: true,
Herbie Ong66c365c2019-01-04 14:08:41 -08001498 }, {
1499 desc: "Any expanded with unknown fields",
Herbie Ong300cff02019-03-20 18:05:16 -07001500 umo: textpb.UnmarshalOptions{
1501 Resolver: preg.NewTypes((&pb2.Nested{}).ProtoReflect().Type()),
1502 },
1503 inputMessage: &knownpb.Any{},
1504 inputText: `
Herbie Ong66c365c2019-01-04 14:08:41 -08001505[pb2.Nested]: {}
1506unknown: ""
Herbie Ong66c365c2019-01-04 14:08:41 -08001507`,
1508 wantErr: true,
1509 }, {
1510 desc: "Any contains expanded and unexpanded fields",
Herbie Ong300cff02019-03-20 18:05:16 -07001511 umo: textpb.UnmarshalOptions{
1512 Resolver: preg.NewTypes((&pb2.Nested{}).ProtoReflect().Type()),
1513 },
1514 inputMessage: &knownpb.Any{},
1515 inputText: `
Herbie Ong66c365c2019-01-04 14:08:41 -08001516[pb2.Nested]: {}
1517type_url: "pb2.Nested"
Herbie Ong66c365c2019-01-04 14:08:41 -08001518`,
1519 wantErr: true,
Herbie Ong800c9902018-12-06 15:28:53 -08001520 }}
1521
1522 for _, tt := range tests {
1523 tt := tt
1524 t.Run(tt.desc, func(t *testing.T) {
Herbie Ong66c365c2019-01-04 14:08:41 -08001525 err := tt.umo.Unmarshal(tt.inputMessage, []byte(tt.inputText))
Herbie Ong800c9902018-12-06 15:28:53 -08001526 if err != nil && !tt.wantErr {
1527 t.Errorf("Unmarshal() returned error: %v\n\n", err)
1528 }
1529 if err == nil && tt.wantErr {
1530 t.Error("Unmarshal() got nil error, want error\n\n")
1531 }
Herbie Ong70651952018-12-13 14:19:50 -08001532 if tt.wantMessage != nil && !protoV1.Equal(tt.inputMessage.(protoV1.Message), tt.wantMessage.(protoV1.Message)) {
Herbie Ong800c9902018-12-06 15:28:53 -08001533 t.Errorf("Unmarshal()\n<got>\n%v\n<want>\n%v\n", tt.inputMessage, tt.wantMessage)
1534 }
1535 })
1536 }
1537}