blob: d1e7b14d3572fc8f3bfc8603e053e94c23da05b9 [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"
Damien Neile89e6242019-05-13 23:55:40 -070012 "google.golang.org/protobuf/encoding/textpb"
13 "google.golang.org/protobuf/internal/errors"
14 pimpl "google.golang.org/protobuf/internal/impl"
15 "google.golang.org/protobuf/internal/scalar"
16 "google.golang.org/protobuf/proto"
17 preg "google.golang.org/protobuf/reflect/protoregistry"
Herbie Ong800c9902018-12-06 15:28:53 -080018
Damien Neile89e6242019-05-13 23:55:40 -070019 "google.golang.org/protobuf/encoding/testprotos/pb2"
20 "google.golang.org/protobuf/encoding/testprotos/pb3"
21 knownpb "google.golang.org/protobuf/types/known"
Herbie Ong800c9902018-12-06 15:28:53 -080022)
23
24func TestUnmarshal(t *testing.T) {
Herbie Ong800c9902018-12-06 15:28:53 -080025 tests := []struct {
26 desc string
Herbie Ong66c365c2019-01-04 14:08:41 -080027 umo textpb.UnmarshalOptions
Herbie Ong70651952018-12-13 14:19:50 -080028 inputMessage proto.Message
Herbie Ong800c9902018-12-06 15:28:53 -080029 inputText string
Herbie Ong70651952018-12-13 14:19:50 -080030 wantMessage proto.Message
Herbie Ong300cff02019-03-20 18:05:16 -070031 wantErr bool // TODO: Verify error message content.
Herbie Ong800c9902018-12-06 15:28:53 -080032 }{{
33 desc: "proto2 empty message",
34 inputMessage: &pb2.Scalars{},
35 wantMessage: &pb2.Scalars{},
36 }, {
Herbie Ong8170d692019-02-13 14:13:21 -080037 desc: "proto2 optional scalars set to zero values",
Herbie Ong800c9902018-12-06 15:28:53 -080038 inputMessage: &pb2.Scalars{},
39 inputText: `opt_bool: false
40opt_int32: 0
41opt_int64: 0
42opt_uint32: 0
43opt_uint64: 0
44opt_sint32: 0
45opt_sint64: 0
46opt_fixed32: 0
47opt_fixed64: 0
48opt_sfixed32: 0
49opt_sfixed64: 0
50opt_float: 0
51opt_double: 0
52opt_bytes: ""
53opt_string: ""
54`,
55 wantMessage: &pb2.Scalars{
56 OptBool: scalar.Bool(false),
57 OptInt32: scalar.Int32(0),
58 OptInt64: scalar.Int64(0),
59 OptUint32: scalar.Uint32(0),
60 OptUint64: scalar.Uint64(0),
61 OptSint32: scalar.Int32(0),
62 OptSint64: scalar.Int64(0),
63 OptFixed32: scalar.Uint32(0),
64 OptFixed64: scalar.Uint64(0),
65 OptSfixed32: scalar.Int32(0),
66 OptSfixed64: scalar.Int64(0),
67 OptFloat: scalar.Float32(0),
68 OptDouble: scalar.Float64(0),
69 OptBytes: []byte{},
70 OptString: scalar.String(""),
71 },
72 }, {
Herbie Ong8170d692019-02-13 14:13:21 -080073 desc: "proto3 scalars set to zero values",
Herbie Ong800c9902018-12-06 15:28:53 -080074 inputMessage: &pb3.Scalars{},
75 inputText: `s_bool: false
76s_int32: 0
77s_int64: 0
78s_uint32: 0
79s_uint64: 0
80s_sint32: 0
81s_sint64: 0
82s_fixed32: 0
83s_fixed64: 0
84s_sfixed32: 0
85s_sfixed64: 0
86s_float: 0
87s_double: 0
88s_bytes: ""
89s_string: ""
90`,
91 wantMessage: &pb3.Scalars{},
92 }, {
Herbie Ong8170d692019-02-13 14:13:21 -080093 desc: "proto2 optional scalars",
Herbie Ong800c9902018-12-06 15:28:53 -080094 inputMessage: &pb2.Scalars{},
95 inputText: `opt_bool: true
96opt_int32: 255
97opt_int64: 3735928559
98opt_uint32: 0xff
99opt_uint64: 0xdeadbeef
100opt_sint32: -1001
101opt_sint64: -0xffff
102opt_fixed64: 64
103opt_sfixed32: -32
104opt_float: 1.234
105opt_double: 1.23e+100
106opt_bytes: "\xe8\xb0\xb7\xe6\xad\x8c"
107opt_string: "谷歌"
108`,
109 wantMessage: &pb2.Scalars{
110 OptBool: scalar.Bool(true),
111 OptInt32: scalar.Int32(0xff),
112 OptInt64: scalar.Int64(0xdeadbeef),
113 OptUint32: scalar.Uint32(0xff),
114 OptUint64: scalar.Uint64(0xdeadbeef),
115 OptSint32: scalar.Int32(-1001),
116 OptSint64: scalar.Int64(-0xffff),
117 OptFixed64: scalar.Uint64(64),
118 OptSfixed32: scalar.Int32(-32),
119 OptFloat: scalar.Float32(1.234),
120 OptDouble: scalar.Float64(1.23e100),
121 OptBytes: []byte("\xe8\xb0\xb7\xe6\xad\x8c"),
122 OptString: scalar.String("谷歌"),
123 },
124 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800125 desc: "proto3 scalars",
Herbie Ong800c9902018-12-06 15:28:53 -0800126 inputMessage: &pb3.Scalars{},
127 inputText: `s_bool: true
128s_int32: 255
129s_int64: 3735928559
130s_uint32: 0xff
131s_uint64: 0xdeadbeef
132s_sint32: -1001
133s_sint64: -0xffff
134s_fixed64: 64
135s_sfixed32: -32
136s_float: 1.234
137s_double: 1.23e+100
138s_bytes: "\xe8\xb0\xb7\xe6\xad\x8c"
139s_string: "谷歌"
140`,
141 wantMessage: &pb3.Scalars{
142 SBool: true,
143 SInt32: 0xff,
144 SInt64: 0xdeadbeef,
145 SUint32: 0xff,
146 SUint64: 0xdeadbeef,
147 SSint32: -1001,
148 SSint64: -0xffff,
149 SFixed64: 64,
150 SSfixed32: -32,
151 SFloat: 1.234,
152 SDouble: 1.23e100,
153 SBytes: []byte("\xe8\xb0\xb7\xe6\xad\x8c"),
154 SString: "谷歌",
155 },
156 }, {
Herbie Ong21a39742019-04-08 17:32:44 -0700157 desc: "string with invalid UTF-8",
158 inputMessage: &pb3.Scalars{},
159 inputText: `s_string: "abc\xff"`,
160 wantMessage: &pb3.Scalars{
161 SString: "abc\xff",
162 },
163 wantErr: true,
164 }, {
Herbie Ong800c9902018-12-06 15:28:53 -0800165 desc: "proto2 message contains unknown field",
166 inputMessage: &pb2.Scalars{},
167 inputText: "unknown_field: 123",
168 wantErr: true,
169 }, {
170 desc: "proto3 message contains unknown field",
171 inputMessage: &pb3.Scalars{},
172 inputText: "unknown_field: 456",
173 wantErr: true,
174 }, {
175 desc: "proto2 numeric key field",
176 inputMessage: &pb2.Scalars{},
177 inputText: "1: true",
178 wantErr: true,
179 }, {
180 desc: "proto3 numeric key field",
181 inputMessage: &pb3.Scalars{},
182 inputText: "1: true",
183 wantErr: true,
184 }, {
185 desc: "invalid bool value",
186 inputMessage: &pb3.Scalars{},
187 inputText: "s_bool: 123",
188 wantErr: true,
189 }, {
190 desc: "invalid int32 value",
191 inputMessage: &pb3.Scalars{},
192 inputText: "s_int32: not_a_num",
193 wantErr: true,
194 }, {
195 desc: "invalid int64 value",
196 inputMessage: &pb3.Scalars{},
197 inputText: "s_int64: 'not a num either'",
198 wantErr: true,
199 }, {
200 desc: "invalid uint32 value",
201 inputMessage: &pb3.Scalars{},
202 inputText: "s_fixed32: -42",
203 wantErr: true,
204 }, {
205 desc: "invalid uint64 value",
206 inputMessage: &pb3.Scalars{},
207 inputText: "s_uint64: -47",
208 wantErr: true,
209 }, {
210 desc: "invalid sint32 value",
211 inputMessage: &pb3.Scalars{},
212 inputText: "s_sint32: '42'",
213 wantErr: true,
214 }, {
215 desc: "invalid sint64 value",
216 inputMessage: &pb3.Scalars{},
217 inputText: "s_sint64: '-47'",
218 wantErr: true,
219 }, {
220 desc: "invalid fixed32 value",
221 inputMessage: &pb3.Scalars{},
222 inputText: "s_fixed32: -42",
223 wantErr: true,
224 }, {
225 desc: "invalid fixed64 value",
226 inputMessage: &pb3.Scalars{},
227 inputText: "s_fixed64: -42",
228 wantErr: true,
229 }, {
230 desc: "invalid sfixed32 value",
231 inputMessage: &pb3.Scalars{},
232 inputText: "s_sfixed32: 'not valid'",
233 wantErr: true,
234 }, {
235 desc: "invalid sfixed64 value",
236 inputMessage: &pb3.Scalars{},
237 inputText: "s_sfixed64: bad",
238 wantErr: true,
239 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800240 desc: "float positive infinity",
Herbie Ong800c9902018-12-06 15:28:53 -0800241 inputMessage: &pb3.Scalars{},
242 inputText: "s_float: inf",
243 wantMessage: &pb3.Scalars{
244 SFloat: float32(math.Inf(1)),
245 },
246 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800247 desc: "float negative infinity",
Herbie Ong800c9902018-12-06 15:28:53 -0800248 inputMessage: &pb3.Scalars{},
249 inputText: "s_float: -inf",
250 wantMessage: &pb3.Scalars{
251 SFloat: float32(math.Inf(-1)),
252 },
253 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800254 desc: "double positive infinity",
Herbie Ong800c9902018-12-06 15:28:53 -0800255 inputMessage: &pb3.Scalars{},
256 inputText: "s_double: inf",
257 wantMessage: &pb3.Scalars{
258 SDouble: math.Inf(1),
259 },
260 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800261 desc: "double negative infinity",
Herbie Ong800c9902018-12-06 15:28:53 -0800262 inputMessage: &pb3.Scalars{},
263 inputText: "s_double: -inf",
264 wantMessage: &pb3.Scalars{
265 SDouble: math.Inf(-1),
266 },
267 }, {
268 desc: "invalid string value",
269 inputMessage: &pb3.Scalars{},
270 inputText: "s_string: invalid_string",
271 wantErr: true,
272 }, {
273 desc: "proto2 bytes set to empty string",
274 inputMessage: &pb2.Scalars{},
275 inputText: "opt_bytes: ''",
276 wantMessage: &pb2.Scalars{
277 OptBytes: []byte(""),
278 },
279 }, {
280 desc: "proto3 bytes set to empty string",
281 inputMessage: &pb3.Scalars{},
282 inputText: "s_bytes: ''",
283 wantMessage: &pb3.Scalars{},
284 }, {
285 desc: "proto2 duplicate singular field",
286 inputMessage: &pb2.Scalars{},
287 inputText: `
288opt_bool: true
289opt_bool: false
290`,
291 wantErr: true,
292 }, {
Herbie Ong800c9902018-12-06 15:28:53 -0800293 desc: "proto2 more duplicate singular field",
294 inputMessage: &pb2.Scalars{},
295 inputText: `
296opt_bool: true
297opt_string: "hello"
298opt_bool: false
299`,
300 wantErr: true,
301 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800302 desc: "proto2 invalid singular field",
303 inputMessage: &pb2.Scalars{},
304 inputText: `
305opt_bool: [true, false]
306`,
307 wantErr: true,
308 }, {
Herbie Ong800c9902018-12-06 15:28:53 -0800309 desc: "proto3 duplicate singular field",
310 inputMessage: &pb3.Scalars{},
311 inputText: `
312s_bool: false
313s_bool: true
314`,
315 wantErr: true,
316 }, {
317 desc: "proto3 more duplicate singular field",
318 inputMessage: &pb3.Scalars{},
319 inputText: `
320s_bool: false
321s_string: ""
322s_bool: true
323`,
324 wantErr: true,
325 }, {
326 desc: "proto2 enum",
327 inputMessage: &pb2.Enums{},
328 inputText: `
Herbie Ong8170d692019-02-13 14:13:21 -0800329opt_enum: ONE
Herbie Ong800c9902018-12-06 15:28:53 -0800330opt_nested_enum: UNO
331`,
332 wantMessage: &pb2.Enums{
Herbie Ong8170d692019-02-13 14:13:21 -0800333 OptEnum: pb2.Enum_ONE.Enum(),
Herbie Ong800c9902018-12-06 15:28:53 -0800334 OptNestedEnum: pb2.Enums_UNO.Enum(),
335 },
336 }, {
337 desc: "proto2 enum set to numeric values",
338 inputMessage: &pb2.Enums{},
339 inputText: `
Herbie Ong8170d692019-02-13 14:13:21 -0800340opt_enum: 2
Herbie Ong800c9902018-12-06 15:28:53 -0800341opt_nested_enum: 2
342`,
343 wantMessage: &pb2.Enums{
Herbie Ong8170d692019-02-13 14:13:21 -0800344 OptEnum: pb2.Enum_TWO.Enum(),
Herbie Ong800c9902018-12-06 15:28:53 -0800345 OptNestedEnum: pb2.Enums_DOS.Enum(),
346 },
347 }, {
348 desc: "proto2 enum set to unnamed numeric values",
349 inputMessage: &pb2.Enums{},
350 inputText: `
351opt_enum: 101
352opt_nested_enum: -101
353`,
354 wantMessage: &pb2.Enums{
355 OptEnum: pb2Enum(101),
356 OptNestedEnum: pb2Enums_NestedEnum(-101),
357 },
358 }, {
359 desc: "proto2 enum set to invalid named",
360 inputMessage: &pb2.Enums{},
361 inputText: `
Herbie Ong8170d692019-02-13 14:13:21 -0800362opt_enum: UNNAMED
Herbie Ong800c9902018-12-06 15:28:53 -0800363opt_nested_enum: UNNAMED_TOO
364`,
365 wantErr: true,
366 }, {
367 desc: "proto3 enum name value",
368 inputMessage: &pb3.Enums{},
369 inputText: `
370s_enum: ONE
371s_nested_enum: DIEZ
372`,
373 wantMessage: &pb3.Enums{
374 SEnum: pb3.Enum_ONE,
375 SNestedEnum: pb3.Enums_DIEZ,
376 },
377 }, {
378 desc: "proto3 enum numeric value",
379 inputMessage: &pb3.Enums{},
380 inputText: `
381s_enum: 2
Herbie Ong8170d692019-02-13 14:13:21 -0800382s_nested_enum: 2
Herbie Ong800c9902018-12-06 15:28:53 -0800383`,
384 wantMessage: &pb3.Enums{
385 SEnum: pb3.Enum_TWO,
Herbie Ong8170d692019-02-13 14:13:21 -0800386 SNestedEnum: pb3.Enums_DOS,
Herbie Ong800c9902018-12-06 15:28:53 -0800387 },
388 }, {
389 desc: "proto3 enum unnamed numeric value",
390 inputMessage: &pb3.Enums{},
391 inputText: `
392s_enum: 0x7fffffff
393s_nested_enum: -0x80000000
394`,
395 wantMessage: &pb3.Enums{
396 SEnum: 0x7fffffff,
397 SNestedEnum: -0x80000000,
398 },
399 }, {
400 desc: "proto2 nested empty messages",
401 inputMessage: &pb2.Nests{},
402 inputText: `
403opt_nested: {}
Herbie Ong0dcfb9a2019-01-14 15:32:26 -0800404OptGroup: {}
Herbie Ong800c9902018-12-06 15:28:53 -0800405`,
406 wantMessage: &pb2.Nests{
407 OptNested: &pb2.Nested{},
408 Optgroup: &pb2.Nests_OptGroup{},
409 },
410 }, {
411 desc: "proto2 nested messages",
412 inputMessage: &pb2.Nests{},
413 inputText: `
414opt_nested: {
415 opt_string: "nested message"
416 opt_nested: {
417 opt_string: "another nested message"
418 }
419}
420`,
421 wantMessage: &pb2.Nests{
422 OptNested: &pb2.Nested{
423 OptString: scalar.String("nested message"),
424 OptNested: &pb2.Nested{
425 OptString: scalar.String("another nested message"),
426 },
427 },
428 },
429 }, {
430 desc: "proto3 nested empty message",
431 inputMessage: &pb3.Nests{},
432 inputText: "s_nested: {}",
433 wantMessage: &pb3.Nests{
434 SNested: &pb3.Nested{},
435 },
436 }, {
437 desc: "proto3 nested message",
438 inputMessage: &pb3.Nests{},
439 inputText: `
440s_nested: {
441 s_string: "nested message"
442 s_nested: {
443 s_string: "another nested message"
444 }
445}
446`,
447 wantMessage: &pb3.Nests{
448 SNested: &pb3.Nested{
449 SString: "nested message",
450 SNested: &pb3.Nested{
451 SString: "another nested message",
452 },
453 },
454 },
455 }, {
Herbie Ong21a39742019-04-08 17:32:44 -0700456 desc: "proto3 nested message contains invalid UTF-8",
457 inputMessage: &pb3.Nests{},
458 inputText: `s_nested: {
459 s_string: "abc\xff"
460}
461`,
462 wantMessage: &pb3.Nests{
463 SNested: &pb3.Nested{
464 SString: "abc\xff",
465 },
466 },
467 wantErr: true,
468 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800469 desc: "oneof set to empty string",
470 inputMessage: &pb3.Oneofs{},
471 inputText: "oneof_string: ''",
472 wantMessage: &pb3.Oneofs{
473 Union: &pb3.Oneofs_OneofString{},
Herbie Ong800c9902018-12-06 15:28:53 -0800474 },
475 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800476 desc: "oneof set to string",
477 inputMessage: &pb3.Oneofs{},
478 inputText: "oneof_string: 'hello'",
479 wantMessage: &pb3.Oneofs{
480 Union: &pb3.Oneofs_OneofString{
481 OneofString: "hello",
Herbie Ong800c9902018-12-06 15:28:53 -0800482 },
483 },
484 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800485 desc: "oneof set to enum",
486 inputMessage: &pb3.Oneofs{},
487 inputText: "oneof_enum: TEN",
488 wantMessage: &pb3.Oneofs{
489 Union: &pb3.Oneofs_OneofEnum{
490 OneofEnum: pb3.Enum_TEN,
Herbie Ong800c9902018-12-06 15:28:53 -0800491 },
492 },
493 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800494 desc: "oneof set to empty message",
495 inputMessage: &pb3.Oneofs{},
496 inputText: "oneof_nested: {}",
497 wantMessage: &pb3.Oneofs{
498 Union: &pb3.Oneofs_OneofNested{
499 OneofNested: &pb3.Nested{},
500 },
501 },
502 }, {
503 desc: "oneof set to message",
504 inputMessage: &pb3.Oneofs{},
Herbie Ong800c9902018-12-06 15:28:53 -0800505 inputText: `
Herbie Ong8170d692019-02-13 14:13:21 -0800506oneof_nested: {
507 s_string: "nested message"
Herbie Ong800c9902018-12-06 15:28:53 -0800508}
509`,
Herbie Ong8170d692019-02-13 14:13:21 -0800510 wantMessage: &pb3.Oneofs{
511 Union: &pb3.Oneofs_OneofNested{
512 OneofNested: &pb3.Nested{
513 SString: "nested message",
Herbie Ong800c9902018-12-06 15:28:53 -0800514 },
515 },
516 },
517 }, {
Herbie Ong8a1d4602019-04-02 20:19:36 -0700518 desc: "oneof set to more than one field",
Herbie Ong8170d692019-02-13 14:13:21 -0800519 inputMessage: &pb3.Oneofs{},
Herbie Ong6470ea62019-01-07 18:56:57 -0800520 inputText: `
Herbie Ong8a1d4602019-04-02 20:19:36 -0700521oneof_enum: ZERO
522oneof_string: "hello"
Herbie Ong6470ea62019-01-07 18:56:57 -0800523`,
Herbie Ong8a1d4602019-04-02 20:19:36 -0700524 wantErr: true,
Herbie Ong6470ea62019-01-07 18:56:57 -0800525 }, {
Herbie Ong800c9902018-12-06 15:28:53 -0800526 desc: "repeated scalar using same field name",
527 inputMessage: &pb2.Repeats{},
528 inputText: `
529rpt_string: "a"
530rpt_string: "b"
531rpt_int32: 0xff
532rpt_float: 1.23
533rpt_bytes: "bytes"
534`,
535 wantMessage: &pb2.Repeats{
536 RptString: []string{"a", "b"},
537 RptInt32: []int32{0xff},
538 RptFloat: []float32{1.23},
539 RptBytes: [][]byte{[]byte("bytes")},
540 },
541 }, {
542 desc: "repeated using mix of [] and repeated field name",
543 inputMessage: &pb2.Repeats{},
544 inputText: `
545rpt_string: "a"
546rpt_bool: true
547rpt_string: ["x", "y"]
548rpt_bool: [ false, true ]
549rpt_string: "b"
550`,
551 wantMessage: &pb2.Repeats{
552 RptString: []string{"a", "x", "y", "b"},
553 RptBool: []bool{true, false, true},
554 },
555 }, {
Herbie Ong21a39742019-04-08 17:32:44 -0700556 desc: "repeated contains invalid UTF-8",
557 inputMessage: &pb2.Repeats{},
558 inputText: `rpt_string: "abc\xff"`,
559 wantMessage: &pb2.Repeats{
560 RptString: []string{"abc\xff"},
561 },
562 wantErr: true,
563 }, {
Herbie Ong800c9902018-12-06 15:28:53 -0800564 desc: "repeated enums",
565 inputMessage: &pb2.Enums{},
566 inputText: `
Herbie Ong8170d692019-02-13 14:13:21 -0800567rpt_enum: TEN
Herbie Ong800c9902018-12-06 15:28:53 -0800568rpt_enum: 1
569rpt_nested_enum: [DOS, 2]
570rpt_enum: 42
571rpt_nested_enum: -47
572`,
573 wantMessage: &pb2.Enums{
Herbie Ong8170d692019-02-13 14:13:21 -0800574 RptEnum: []pb2.Enum{pb2.Enum_TEN, pb2.Enum_ONE, 42},
Herbie Ong800c9902018-12-06 15:28:53 -0800575 RptNestedEnum: []pb2.Enums_NestedEnum{pb2.Enums_DOS, pb2.Enums_DOS, -47},
576 },
577 }, {
578 desc: "repeated nested messages",
579 inputMessage: &pb2.Nests{},
580 inputText: `
581rpt_nested: {
582 opt_string: "repeat nested one"
583}
584rpt_nested: {
585 opt_string: "repeat nested two"
586 opt_nested: {
587 opt_string: "inside repeat nested two"
588 }
589}
590rpt_nested: {}
591`,
592 wantMessage: &pb2.Nests{
593 RptNested: []*pb2.Nested{
594 {
595 OptString: scalar.String("repeat nested one"),
596 },
597 {
598 OptString: scalar.String("repeat nested two"),
599 OptNested: &pb2.Nested{
600 OptString: scalar.String("inside repeat nested two"),
601 },
602 },
603 {},
604 },
605 },
606 }, {
607 desc: "repeated group fields",
608 inputMessage: &pb2.Nests{},
609 inputText: `
Herbie Ong0dcfb9a2019-01-14 15:32:26 -0800610RptGroup: {
Herbie Ong8170d692019-02-13 14:13:21 -0800611 rpt_string: "hello"
612 rpt_string: "world"
Herbie Ong800c9902018-12-06 15:28:53 -0800613}
Herbie Ong0dcfb9a2019-01-14 15:32:26 -0800614RptGroup: {}
Herbie Ong800c9902018-12-06 15:28:53 -0800615`,
616 wantMessage: &pb2.Nests{
617 Rptgroup: []*pb2.Nests_RptGroup{
618 {
Herbie Ong8170d692019-02-13 14:13:21 -0800619 RptString: []string{"hello", "world"},
Herbie Ong800c9902018-12-06 15:28:53 -0800620 },
621 {},
622 },
623 },
624 }, {
625 desc: "map fields 1",
Herbie Ong8170d692019-02-13 14:13:21 -0800626 inputMessage: &pb3.Maps{},
Herbie Ong800c9902018-12-06 15:28:53 -0800627 inputText: `
628int32_to_str: {
629 key: -101
630 value: "-101"
631}
632int32_to_str: {
633 key: 0
634 value: "zero"
635}
Herbie Ong8170d692019-02-13 14:13:21 -0800636bool_to_uint32: {
637 key: false
638 value: 101
Herbie Ong800c9902018-12-06 15:28:53 -0800639}
640int32_to_str: {
641 key: 255
642 value: "0xff"
643}
644bool_to_uint32: {
Herbie Ong800c9902018-12-06 15:28:53 -0800645 key: true
646 value: 42
647}
648`,
Herbie Ong8170d692019-02-13 14:13:21 -0800649 wantMessage: &pb3.Maps{
Herbie Ong800c9902018-12-06 15:28:53 -0800650 Int32ToStr: map[int32]string{
651 -101: "-101",
652 0xff: "0xff",
653 0: "zero",
654 },
Herbie Ong800c9902018-12-06 15:28:53 -0800655 BoolToUint32: map[bool]uint32{
656 true: 42,
657 false: 101,
658 },
659 },
660 }, {
661 desc: "map fields 2",
Herbie Ong8170d692019-02-13 14:13:21 -0800662 inputMessage: &pb3.Maps{},
Herbie Ong800c9902018-12-06 15:28:53 -0800663 inputText: `
664uint64_to_enum: {
665 key: 1
Herbie Ong8170d692019-02-13 14:13:21 -0800666 value: ONE
Herbie Ong800c9902018-12-06 15:28:53 -0800667}
668uint64_to_enum: {
669 key: 2
Herbie Ong8170d692019-02-13 14:13:21 -0800670 value: 2
Herbie Ong800c9902018-12-06 15:28:53 -0800671}
672uint64_to_enum: {
673 key: 10
Herbie Ong8170d692019-02-13 14:13:21 -0800674 value: 101
Herbie Ong800c9902018-12-06 15:28:53 -0800675}
676`,
Herbie Ong8170d692019-02-13 14:13:21 -0800677 wantMessage: &pb3.Maps{
678 Uint64ToEnum: map[uint64]pb3.Enum{
679 1: pb3.Enum_ONE,
680 2: pb3.Enum_TWO,
681 10: 101,
Herbie Ong800c9902018-12-06 15:28:53 -0800682 },
683 },
684 }, {
685 desc: "map fields 3",
Herbie Ong8170d692019-02-13 14:13:21 -0800686 inputMessage: &pb3.Maps{},
Herbie Ong800c9902018-12-06 15:28:53 -0800687 inputText: `
688str_to_nested: {
689 key: "nested_one"
690 value: {
Herbie Ong8170d692019-02-13 14:13:21 -0800691 s_string: "nested in a map"
Herbie Ong800c9902018-12-06 15:28:53 -0800692 }
693}
694`,
Herbie Ong8170d692019-02-13 14:13:21 -0800695 wantMessage: &pb3.Maps{
696 StrToNested: map[string]*pb3.Nested{
697 "nested_one": &pb3.Nested{
698 SString: "nested in a map",
Herbie Ong800c9902018-12-06 15:28:53 -0800699 },
700 },
701 },
702 }, {
703 desc: "map fields 4",
Herbie Ong8170d692019-02-13 14:13:21 -0800704 inputMessage: &pb3.Maps{},
Herbie Ong800c9902018-12-06 15:28:53 -0800705 inputText: `
706str_to_oneofs: {
707 key: "nested"
708 value: {
Herbie Ong8170d692019-02-13 14:13:21 -0800709 oneof_nested: {
710 s_string: "nested oneof in map field value"
Herbie Ong800c9902018-12-06 15:28:53 -0800711 }
712 }
713}
714str_to_oneofs: {
715 key: "string"
716 value: {
Herbie Ong8170d692019-02-13 14:13:21 -0800717 oneof_string: "hello"
Herbie Ong800c9902018-12-06 15:28:53 -0800718 }
719}
720`,
Herbie Ong8170d692019-02-13 14:13:21 -0800721 wantMessage: &pb3.Maps{
722 StrToOneofs: map[string]*pb3.Oneofs{
723 "string": &pb3.Oneofs{
724 Union: &pb3.Oneofs_OneofString{
725 OneofString: "hello",
Herbie Ong800c9902018-12-06 15:28:53 -0800726 },
727 },
Herbie Ong8170d692019-02-13 14:13:21 -0800728 "nested": &pb3.Oneofs{
729 Union: &pb3.Oneofs_OneofNested{
730 OneofNested: &pb3.Nested{
731 SString: "nested oneof in map field value",
Herbie Ong800c9902018-12-06 15:28:53 -0800732 },
733 },
734 },
735 },
736 },
737 }, {
738 desc: "map contains duplicate keys",
Herbie Ong8170d692019-02-13 14:13:21 -0800739 inputMessage: &pb3.Maps{},
Herbie Ong800c9902018-12-06 15:28:53 -0800740 inputText: `
741int32_to_str: {
742 key: 0
743 value: "cero"
744}
745int32_to_str: {
746 key: 0
747 value: "zero"
748}
749`,
Herbie Ong8170d692019-02-13 14:13:21 -0800750 wantMessage: &pb3.Maps{
Herbie Ong800c9902018-12-06 15:28:53 -0800751 Int32ToStr: map[int32]string{
752 0: "zero",
753 },
754 },
755 }, {
756 desc: "map contains duplicate key fields",
Herbie Ong8170d692019-02-13 14:13:21 -0800757 inputMessage: &pb3.Maps{},
Herbie Ong800c9902018-12-06 15:28:53 -0800758 inputText: `
759int32_to_str: {
760 key: 0
761 key: 1
762 value: "cero"
763}
764`,
765 wantErr: true,
766 }, {
767 desc: "map contains duplicate value fields",
Herbie Ong8170d692019-02-13 14:13:21 -0800768 inputMessage: &pb3.Maps{},
Herbie Ong800c9902018-12-06 15:28:53 -0800769 inputText: `
770int32_to_str: {
771 key: 1
772 value: "cero"
773 value: "uno"
774}
775`,
776 wantErr: true,
777 }, {
778 desc: "map contains missing key",
Herbie Ong8170d692019-02-13 14:13:21 -0800779 inputMessage: &pb3.Maps{},
Herbie Ong800c9902018-12-06 15:28:53 -0800780 inputText: `
781int32_to_str: {
782 value: "zero"
783}
Herbie Ong8170d692019-02-13 14:13:21 -0800784bool_to_uint32: {
785 value: 47
786}
787str_to_nested: {
788 value: {}
789}
Herbie Ong800c9902018-12-06 15:28:53 -0800790`,
Herbie Ong8170d692019-02-13 14:13:21 -0800791 wantMessage: &pb3.Maps{
Herbie Ong800c9902018-12-06 15:28:53 -0800792 Int32ToStr: map[int32]string{
793 0: "zero",
794 },
Herbie Ong8170d692019-02-13 14:13:21 -0800795 BoolToUint32: map[bool]uint32{
796 false: 47,
797 },
798 StrToNested: map[string]*pb3.Nested{
799 "": {},
800 },
Herbie Ong800c9902018-12-06 15:28:53 -0800801 },
802 }, {
803 desc: "map contains missing value",
Herbie Ong8170d692019-02-13 14:13:21 -0800804 inputMessage: &pb3.Maps{},
Herbie Ong800c9902018-12-06 15:28:53 -0800805 inputText: `
806int32_to_str: {
807 key: 100
808}
Herbie Ong8170d692019-02-13 14:13:21 -0800809bool_to_uint32: {
810 key: true
811}
812uint64_to_enum: {
813 key: 101
814}
815str_to_nested: {
816 key: "hello"
817}
Herbie Ong800c9902018-12-06 15:28:53 -0800818`,
Herbie Ong8170d692019-02-13 14:13:21 -0800819 wantMessage: &pb3.Maps{
Herbie Ong800c9902018-12-06 15:28:53 -0800820 Int32ToStr: map[int32]string{
821 100: "",
822 },
Herbie Ong8170d692019-02-13 14:13:21 -0800823 BoolToUint32: map[bool]uint32{
824 true: 0,
825 },
826 Uint64ToEnum: map[uint64]pb3.Enum{
827 101: pb3.Enum_ZERO,
828 },
829 StrToNested: map[string]*pb3.Nested{
830 "hello": {},
831 },
Herbie Ong800c9902018-12-06 15:28:53 -0800832 },
833 }, {
834 desc: "map contains missing key and value",
Herbie Ong8170d692019-02-13 14:13:21 -0800835 inputMessage: &pb3.Maps{},
Herbie Ong800c9902018-12-06 15:28:53 -0800836 inputText: `
837int32_to_str: {}
Herbie Ong8170d692019-02-13 14:13:21 -0800838bool_to_uint32: {}
839uint64_to_enum: {}
840str_to_nested: {}
Herbie Ong800c9902018-12-06 15:28:53 -0800841`,
Herbie Ong8170d692019-02-13 14:13:21 -0800842 wantMessage: &pb3.Maps{
843 Int32ToStr: map[int32]string{
844 0: "",
845 },
846 BoolToUint32: map[bool]uint32{
847 false: 0,
848 },
849 Uint64ToEnum: map[uint64]pb3.Enum{
850 0: pb3.Enum_ZERO,
851 },
852 StrToNested: map[string]*pb3.Nested{
853 "": {},
854 },
855 },
856 }, {
857 desc: "map contains overriding entries",
858 inputMessage: &pb3.Maps{},
859 inputText: `
860int32_to_str: {
861 key: 0
862}
863int32_to_str: {
864 value: "empty"
865}
866int32_to_str: {}
867`,
868 wantMessage: &pb3.Maps{
Herbie Ong800c9902018-12-06 15:28:53 -0800869 Int32ToStr: map[int32]string{
870 0: "",
871 },
872 },
873 }, {
Herbie Ong21a39742019-04-08 17:32:44 -0700874 desc: "map field value contains invalid UTF-8",
875 inputMessage: &pb3.Maps{},
876 inputText: `int32_to_str: {
877 key: 101
878 value: "abc\xff"
879}
880`,
881 wantMessage: &pb3.Maps{
882 Int32ToStr: map[int32]string{
883 101: "abc\xff",
884 },
885 },
886 wantErr: true,
887 }, {
888 desc: "map field key contains invalid UTF-8",
889 inputMessage: &pb3.Maps{},
890 inputText: `str_to_nested: {
891 key: "abc\xff"
892 value: {}
893}
894`,
895 wantMessage: &pb3.Maps{
896 StrToNested: map[string]*pb3.Nested{
897 "abc\xff": {},
898 },
899 },
900 wantErr: true,
901 }, {
Herbie Ong800c9902018-12-06 15:28:53 -0800902 desc: "map contains unknown field",
Herbie Ong8170d692019-02-13 14:13:21 -0800903 inputMessage: &pb3.Maps{},
Herbie Ong800c9902018-12-06 15:28:53 -0800904 inputText: `
905int32_to_str: {
906 key: 0
907 value: "cero"
908 unknown: "bad"
909}
910`,
911 wantErr: true,
912 }, {
913 desc: "map contains extension-like key field",
Herbie Ong8170d692019-02-13 14:13:21 -0800914 inputMessage: &pb3.Maps{},
Herbie Ong800c9902018-12-06 15:28:53 -0800915 inputText: `
916int32_to_str: {
917 [key]: 10
918 value: "ten"
919}
920`,
921 wantErr: true,
922 }, {
923 desc: "map contains invalid key",
Herbie Ong8170d692019-02-13 14:13:21 -0800924 inputMessage: &pb3.Maps{},
Herbie Ong800c9902018-12-06 15:28:53 -0800925 inputText: `
926int32_to_str: {
927 key: "invalid"
928 value: "cero"
929}
930`,
931 wantErr: true,
932 }, {
933 desc: "map contains invalid value",
Herbie Ong8170d692019-02-13 14:13:21 -0800934 inputMessage: &pb3.Maps{},
Herbie Ong800c9902018-12-06 15:28:53 -0800935 inputText: `
936int32_to_str: {
937 key: 100
938 value: 101
939}
940`,
941 wantErr: true,
942 }, {
943 desc: "map using mix of [] and repeated",
Herbie Ong8170d692019-02-13 14:13:21 -0800944 inputMessage: &pb3.Maps{},
Herbie Ong800c9902018-12-06 15:28:53 -0800945 inputText: `
946int32_to_str: {
947 key: 1
948 value: "one"
949}
950int32_to_str: [
951 {
952 key: 2
953 value: "not this"
954 },
955 {
956 },
957 {
958 key: 3
959 value: "three"
960 }
961]
962int32_to_str: {
963 key: 2
964 value: "two"
965}
966`,
Herbie Ong8170d692019-02-13 14:13:21 -0800967 wantMessage: &pb3.Maps{
Herbie Ong800c9902018-12-06 15:28:53 -0800968 Int32ToStr: map[int32]string{
969 0: "",
970 1: "one",
971 2: "two",
972 3: "three",
973 },
974 },
975 }, {
Herbie Ong42577ea2019-03-26 16:26:22 -0700976 desc: "required fields not set",
Herbie Ong800c9902018-12-06 15:28:53 -0800977 inputMessage: &pb2.Requireds{},
978 wantErr: true,
979 }, {
Herbie Ong42577ea2019-03-26 16:26:22 -0700980 desc: "required field set",
Herbie Ong800c9902018-12-06 15:28:53 -0800981 inputMessage: &pb2.PartialRequired{},
982 inputText: "req_string: 'this is required'",
983 wantMessage: &pb2.PartialRequired{
984 ReqString: scalar.String("this is required"),
985 },
986 }, {
Herbie Ong42577ea2019-03-26 16:26:22 -0700987 desc: "required fields partially set",
Herbie Ong800c9902018-12-06 15:28:53 -0800988 inputMessage: &pb2.Requireds{},
989 inputText: `
990req_bool: false
Herbie Ong800c9902018-12-06 15:28:53 -0800991req_sfixed64: 3203386110
992req_string: "hello"
Herbie Ong8170d692019-02-13 14:13:21 -0800993req_enum: ONE
Herbie Ong800c9902018-12-06 15:28:53 -0800994`,
995 wantMessage: &pb2.Requireds{
996 ReqBool: scalar.Bool(false),
Herbie Ong800c9902018-12-06 15:28:53 -0800997 ReqSfixed64: scalar.Int64(0xbeefcafe),
998 ReqString: scalar.String("hello"),
Herbie Ong8170d692019-02-13 14:13:21 -0800999 ReqEnum: pb2.Enum_ONE.Enum(),
Herbie Ong800c9902018-12-06 15:28:53 -08001000 },
1001 wantErr: true,
1002 }, {
Herbie Ong42577ea2019-03-26 16:26:22 -07001003 desc: "required fields partially set with AllowPartial",
1004 umo: textpb.UnmarshalOptions{AllowPartial: true},
1005 inputMessage: &pb2.Requireds{},
1006 inputText: `
1007req_bool: false
1008req_sfixed64: 3203386110
1009req_string: "hello"
1010req_enum: ONE
1011`,
1012 wantMessage: &pb2.Requireds{
1013 ReqBool: scalar.Bool(false),
1014 ReqSfixed64: scalar.Int64(0xbeefcafe),
1015 ReqString: scalar.String("hello"),
1016 ReqEnum: pb2.Enum_ONE.Enum(),
1017 },
1018 }, {
1019 desc: "required fields all set",
Herbie Ong800c9902018-12-06 15:28:53 -08001020 inputMessage: &pb2.Requireds{},
1021 inputText: `
1022req_bool: false
Herbie Ong800c9902018-12-06 15:28:53 -08001023req_sfixed64: 0
Herbie Ong800c9902018-12-06 15:28:53 -08001024req_double: 0
1025req_string: ""
Herbie Ong8170d692019-02-13 14:13:21 -08001026req_enum: ONE
Herbie Ong800c9902018-12-06 15:28:53 -08001027req_nested: {}
1028`,
1029 wantMessage: &pb2.Requireds{
1030 ReqBool: scalar.Bool(false),
Herbie Ong800c9902018-12-06 15:28:53 -08001031 ReqSfixed64: scalar.Int64(0),
Herbie Ong800c9902018-12-06 15:28:53 -08001032 ReqDouble: scalar.Float64(0),
1033 ReqString: scalar.String(""),
Herbie Ong8170d692019-02-13 14:13:21 -08001034 ReqEnum: pb2.Enum_ONE.Enum(),
Herbie Ong800c9902018-12-06 15:28:53 -08001035 ReqNested: &pb2.Nested{},
1036 },
1037 }, {
1038 desc: "indirect required field",
1039 inputMessage: &pb2.IndirectRequired{},
1040 inputText: "opt_nested: {}",
1041 wantMessage: &pb2.IndirectRequired{
1042 OptNested: &pb2.NestedWithRequired{},
1043 },
1044 wantErr: true,
1045 }, {
Herbie Ong42577ea2019-03-26 16:26:22 -07001046 desc: "indirect required field with AllowPartial",
1047 umo: textpb.UnmarshalOptions{AllowPartial: true},
1048 inputMessage: &pb2.IndirectRequired{},
1049 inputText: "opt_nested: {}",
1050 wantMessage: &pb2.IndirectRequired{
1051 OptNested: &pb2.NestedWithRequired{},
1052 },
1053 }, {
Herbie Ong800c9902018-12-06 15:28:53 -08001054 desc: "indirect required field in repeated",
1055 inputMessage: &pb2.IndirectRequired{},
1056 inputText: `
1057rpt_nested: {
1058 req_string: "one"
1059}
1060rpt_nested: {}
Herbie Ong800c9902018-12-06 15:28:53 -08001061`,
1062 wantMessage: &pb2.IndirectRequired{
1063 RptNested: []*pb2.NestedWithRequired{
1064 {
1065 ReqString: scalar.String("one"),
1066 },
1067 {},
Herbie Ong800c9902018-12-06 15:28:53 -08001068 },
1069 },
1070 wantErr: true,
1071 }, {
Herbie Ong42577ea2019-03-26 16:26:22 -07001072 desc: "indirect required field in repeated with AllowPartial",
1073 umo: textpb.UnmarshalOptions{AllowPartial: true},
1074 inputMessage: &pb2.IndirectRequired{},
1075 inputText: `
1076rpt_nested: {
1077 req_string: "one"
1078}
1079rpt_nested: {}
1080`,
1081 wantMessage: &pb2.IndirectRequired{
1082 RptNested: []*pb2.NestedWithRequired{
1083 {
1084 ReqString: scalar.String("one"),
1085 },
1086 {},
1087 },
1088 },
1089 }, {
Herbie Ong800c9902018-12-06 15:28:53 -08001090 desc: "indirect required field in map",
1091 inputMessage: &pb2.IndirectRequired{},
1092 inputText: `
1093str_to_nested: {
1094 key: "missing"
1095}
1096str_to_nested: {
1097 key: "contains"
1098 value: {
1099 req_string: "here"
1100 }
1101}
1102`,
1103 wantMessage: &pb2.IndirectRequired{
1104 StrToNested: map[string]*pb2.NestedWithRequired{
1105 "missing": &pb2.NestedWithRequired{},
1106 "contains": &pb2.NestedWithRequired{
1107 ReqString: scalar.String("here"),
1108 },
1109 },
1110 },
1111 wantErr: true,
Herbie Ong7c624e22018-12-13 14:41:22 -08001112 }, {
Herbie Ong42577ea2019-03-26 16:26:22 -07001113 desc: "indirect required field in map with AllowPartial",
1114 umo: textpb.UnmarshalOptions{AllowPartial: true},
1115 inputMessage: &pb2.IndirectRequired{},
1116 inputText: `
1117str_to_nested: {
1118 key: "missing"
1119}
1120str_to_nested: {
1121 key: "contains"
1122 value: {
1123 req_string: "here"
1124 }
1125}
1126`,
1127 wantMessage: &pb2.IndirectRequired{
1128 StrToNested: map[string]*pb2.NestedWithRequired{
1129 "missing": &pb2.NestedWithRequired{},
1130 "contains": &pb2.NestedWithRequired{
1131 ReqString: scalar.String("here"),
1132 },
1133 },
1134 },
1135 }, {
Herbie Ong8170d692019-02-13 14:13:21 -08001136 desc: "indirect required field in oneof",
1137 inputMessage: &pb2.IndirectRequired{},
1138 inputText: `oneof_nested: {}
1139`,
1140 wantMessage: &pb2.IndirectRequired{
1141 Union: &pb2.IndirectRequired_OneofNested{
1142 OneofNested: &pb2.NestedWithRequired{},
1143 },
1144 },
1145 wantErr: true,
1146 }, {
Herbie Ong42577ea2019-03-26 16:26:22 -07001147 desc: "indirect required field in oneof with AllowPartial",
1148 umo: textpb.UnmarshalOptions{AllowPartial: true},
1149 inputMessage: &pb2.IndirectRequired{},
1150 inputText: `oneof_nested: {}
1151`,
1152 wantMessage: &pb2.IndirectRequired{
1153 Union: &pb2.IndirectRequired_OneofNested{
1154 OneofNested: &pb2.NestedWithRequired{},
1155 },
1156 },
1157 }, {
Herbie Ong7c624e22018-12-13 14:41:22 -08001158 desc: "ignore reserved field",
1159 inputMessage: &pb2.Nests{},
1160 inputText: "reserved_field: 'ignore this'",
1161 wantMessage: &pb2.Nests{},
Herbie Ongc525c972018-12-18 18:04:31 -08001162 }, {
1163 desc: "extensions of non-repeated fields",
1164 inputMessage: &pb2.Extensions{},
1165 inputText: `opt_string: "non-extension field"
1166[pb2.opt_ext_bool]: true
1167opt_bool: true
1168[pb2.opt_ext_nested]: {
1169 opt_string: "nested in an extension"
1170 opt_nested: {
1171 opt_string: "another nested in an extension"
1172 }
1173}
1174[pb2.opt_ext_string]: "extension field"
1175opt_int32: 42
Herbie Ong8170d692019-02-13 14:13:21 -08001176[pb2.opt_ext_enum]: TEN
Herbie Ongc525c972018-12-18 18:04:31 -08001177`,
1178 wantMessage: func() proto.Message {
1179 m := &pb2.Extensions{
1180 OptString: scalar.String("non-extension field"),
1181 OptBool: scalar.Bool(true),
1182 OptInt32: scalar.Int32(42),
1183 }
1184 setExtension(m, pb2.E_OptExtBool, true)
1185 setExtension(m, pb2.E_OptExtString, "extension field")
Herbie Ong8170d692019-02-13 14:13:21 -08001186 setExtension(m, pb2.E_OptExtEnum, pb2.Enum_TEN)
Herbie Ongc525c972018-12-18 18:04:31 -08001187 setExtension(m, pb2.E_OptExtNested, &pb2.Nested{
1188 OptString: scalar.String("nested in an extension"),
1189 OptNested: &pb2.Nested{
1190 OptString: scalar.String("another nested in an extension"),
1191 },
1192 })
1193 return m
1194 }(),
1195 }, {
Herbie Ong21a39742019-04-08 17:32:44 -07001196 desc: "extension field contains invalid UTF-8",
1197 inputMessage: &pb2.Extensions{},
1198 inputText: `[pb2.opt_ext_string]: "abc\xff"`,
1199 wantMessage: func() proto.Message {
1200 m := &pb2.Extensions{}
1201 setExtension(m, pb2.E_OptExtString, "abc\xff")
1202 return m
1203 }(),
1204 wantErr: true,
1205 }, {
Herbie Ongc525c972018-12-18 18:04:31 -08001206 desc: "extensions of repeated fields",
1207 inputMessage: &pb2.Extensions{},
Herbie Ong8170d692019-02-13 14:13:21 -08001208 inputText: `[pb2.rpt_ext_enum]: TEN
Herbie Ongc525c972018-12-18 18:04:31 -08001209[pb2.rpt_ext_enum]: 101
1210[pb2.rpt_ext_fixed32]: 42
Herbie Ong8170d692019-02-13 14:13:21 -08001211[pb2.rpt_ext_enum]: ONE
Herbie Ongc525c972018-12-18 18:04:31 -08001212[pb2.rpt_ext_nested]: {
1213 opt_string: "one"
1214}
1215[pb2.rpt_ext_nested]: {
1216 opt_string: "two"
1217}
1218[pb2.rpt_ext_fixed32]: 47
1219[pb2.rpt_ext_nested]: {
1220 opt_string: "three"
1221}
1222`,
1223 wantMessage: func() proto.Message {
1224 m := &pb2.Extensions{}
Herbie Ong8170d692019-02-13 14:13:21 -08001225 setExtension(m, pb2.E_RptExtEnum, &[]pb2.Enum{pb2.Enum_TEN, 101, pb2.Enum_ONE})
Herbie Ongc525c972018-12-18 18:04:31 -08001226 setExtension(m, pb2.E_RptExtFixed32, &[]uint32{42, 47})
1227 setExtension(m, pb2.E_RptExtNested, &[]*pb2.Nested{
1228 &pb2.Nested{OptString: scalar.String("one")},
1229 &pb2.Nested{OptString: scalar.String("two")},
1230 &pb2.Nested{OptString: scalar.String("three")},
1231 })
1232 return m
1233 }(),
1234 }, {
1235 desc: "extensions of non-repeated fields in another message",
1236 inputMessage: &pb2.Extensions{},
1237 inputText: `[pb2.ExtensionsContainer.opt_ext_bool]: true
Herbie Ong8170d692019-02-13 14:13:21 -08001238[pb2.ExtensionsContainer.opt_ext_enum]: TEN
Herbie Ongc525c972018-12-18 18:04:31 -08001239[pb2.ExtensionsContainer.opt_ext_nested]: {
1240 opt_string: "nested in an extension"
1241 opt_nested: {
1242 opt_string: "another nested in an extension"
1243 }
1244}
1245[pb2.ExtensionsContainer.opt_ext_string]: "extension field"
1246`,
1247 wantMessage: func() proto.Message {
1248 m := &pb2.Extensions{}
1249 setExtension(m, pb2.E_ExtensionsContainer_OptExtBool, true)
1250 setExtension(m, pb2.E_ExtensionsContainer_OptExtString, "extension field")
Herbie Ong8170d692019-02-13 14:13:21 -08001251 setExtension(m, pb2.E_ExtensionsContainer_OptExtEnum, pb2.Enum_TEN)
Herbie Ongc525c972018-12-18 18:04:31 -08001252 setExtension(m, pb2.E_ExtensionsContainer_OptExtNested, &pb2.Nested{
1253 OptString: scalar.String("nested in an extension"),
1254 OptNested: &pb2.Nested{
1255 OptString: scalar.String("another nested in an extension"),
1256 },
1257 })
1258 return m
1259 }(),
1260 }, {
1261 desc: "extensions of repeated fields in another message",
1262 inputMessage: &pb2.Extensions{},
1263 inputText: `opt_string: "non-extension field"
1264opt_bool: true
1265opt_int32: 42
1266[pb2.ExtensionsContainer.rpt_ext_nested]: {
1267 opt_string: "one"
1268}
Herbie Ong8170d692019-02-13 14:13:21 -08001269[pb2.ExtensionsContainer.rpt_ext_enum]: TEN
Herbie Ongc525c972018-12-18 18:04:31 -08001270[pb2.ExtensionsContainer.rpt_ext_nested]: {
1271 opt_string: "two"
1272}
1273[pb2.ExtensionsContainer.rpt_ext_enum]: 101
1274[pb2.ExtensionsContainer.rpt_ext_string]: "hello"
Herbie Ong8170d692019-02-13 14:13:21 -08001275[pb2.ExtensionsContainer.rpt_ext_enum]: ONE
Herbie Ongc525c972018-12-18 18:04:31 -08001276[pb2.ExtensionsContainer.rpt_ext_nested]: {
1277 opt_string: "three"
1278}
1279[pb2.ExtensionsContainer.rpt_ext_string]: "world"
1280`,
1281 wantMessage: func() proto.Message {
1282 m := &pb2.Extensions{
1283 OptString: scalar.String("non-extension field"),
1284 OptBool: scalar.Bool(true),
1285 OptInt32: scalar.Int32(42),
1286 }
Herbie Ong8170d692019-02-13 14:13:21 -08001287 setExtension(m, pb2.E_ExtensionsContainer_RptExtEnum, &[]pb2.Enum{pb2.Enum_TEN, 101, pb2.Enum_ONE})
Herbie Ongc525c972018-12-18 18:04:31 -08001288 setExtension(m, pb2.E_ExtensionsContainer_RptExtString, &[]string{"hello", "world"})
1289 setExtension(m, pb2.E_ExtensionsContainer_RptExtNested, &[]*pb2.Nested{
1290 &pb2.Nested{OptString: scalar.String("one")},
1291 &pb2.Nested{OptString: scalar.String("two")},
1292 &pb2.Nested{OptString: scalar.String("three")},
1293 })
1294 return m
1295 }(),
1296 }, {
1297 desc: "invalid extension field name",
1298 inputMessage: &pb2.Extensions{},
1299 inputText: "[pb2.invalid_message_field]: true",
1300 wantErr: true,
Herbie Ong66c365c2019-01-04 14:08:41 -08001301 }, {
Herbie Ong6470ea62019-01-07 18:56:57 -08001302 desc: "MessageSet",
1303 inputMessage: &pb2.MessageSet{},
1304 inputText: `
1305[pb2.MessageSetExtension]: {
1306 opt_string: "a messageset extension"
1307}
1308[pb2.MessageSetExtension.ext_nested]: {
1309 opt_string: "just a regular extension"
1310}
1311[pb2.MessageSetExtension.not_message_set_extension]: {
1312 opt_string: "not a messageset extension"
1313}
1314`,
1315 wantMessage: func() proto.Message {
1316 m := &pb2.MessageSet{}
1317 setExtension(m, pb2.E_MessageSetExtension_MessageSetExtension, &pb2.MessageSetExtension{
1318 OptString: scalar.String("a messageset extension"),
1319 })
1320 setExtension(m, pb2.E_MessageSetExtension_NotMessageSetExtension, &pb2.MessageSetExtension{
1321 OptString: scalar.String("not a messageset extension"),
1322 })
1323 setExtension(m, pb2.E_MessageSetExtension_ExtNested, &pb2.Nested{
1324 OptString: scalar.String("just a regular extension"),
1325 })
1326 return m
1327 }(),
1328 }, {
1329 desc: "not real MessageSet 1",
1330 inputMessage: &pb2.FakeMessageSet{},
1331 inputText: `
1332[pb2.FakeMessageSetExtension.message_set_extension]: {
1333 opt_string: "not a messageset extension"
1334}
1335`,
1336 wantMessage: func() proto.Message {
1337 m := &pb2.FakeMessageSet{}
1338 setExtension(m, pb2.E_FakeMessageSetExtension_MessageSetExtension, &pb2.FakeMessageSetExtension{
1339 OptString: scalar.String("not a messageset extension"),
1340 })
1341 return m
1342 }(),
1343 }, {
1344 desc: "not real MessageSet 2",
1345 inputMessage: &pb2.FakeMessageSet{},
1346 inputText: `
1347[pb2.FakeMessageSetExtension]: {
1348 opt_string: "not a messageset extension"
1349}
1350`,
1351 wantErr: true,
1352 }, {
1353 desc: "not real MessageSet 3",
1354 inputMessage: &pb2.MessageSet{},
1355 inputText: `
1356[pb2.message_set_extension]: {
1357 opt_string: "another not a messageset extension"
Herbie Ong300cff02019-03-20 18:05:16 -07001358}`,
Herbie Ong6470ea62019-01-07 18:56:57 -08001359 wantMessage: func() proto.Message {
1360 m := &pb2.MessageSet{}
1361 setExtension(m, pb2.E_MessageSetExtension, &pb2.FakeMessageSetExtension{
1362 OptString: scalar.String("another not a messageset extension"),
1363 })
1364 return m
1365 }(),
1366 }, {
Herbie Ong66c365c2019-01-04 14:08:41 -08001367 desc: "Any not expanded",
Herbie Ong300cff02019-03-20 18:05:16 -07001368 inputMessage: &knownpb.Any{},
1369 inputText: `
Herbie Ong66c365c2019-01-04 14:08:41 -08001370type_url: "pb2.Nested"
1371value: "some bytes"
Herbie Ong66c365c2019-01-04 14:08:41 -08001372`,
Herbie Ong300cff02019-03-20 18:05:16 -07001373 wantMessage: &knownpb.Any{
1374 TypeUrl: "pb2.Nested",
1375 Value: []byte("some bytes"),
Herbie Ong66c365c2019-01-04 14:08:41 -08001376 },
1377 }, {
1378 desc: "Any not expanded missing value",
Herbie Ong300cff02019-03-20 18:05:16 -07001379 inputMessage: &knownpb.Any{},
1380 inputText: `type_url: "pb2.Nested"`,
1381 wantMessage: &knownpb.Any{
1382 TypeUrl: "pb2.Nested",
Herbie Ong66c365c2019-01-04 14:08:41 -08001383 },
1384 }, {
1385 desc: "Any not expanded missing type_url",
Herbie Ong300cff02019-03-20 18:05:16 -07001386 inputMessage: &knownpb.Any{},
1387 inputText: `value: "some bytes"`,
1388 wantMessage: &knownpb.Any{
1389 Value: []byte("some bytes"),
Herbie Ong66c365c2019-01-04 14:08:41 -08001390 },
1391 }, {
1392 desc: "Any expanded",
Herbie Ong300cff02019-03-20 18:05:16 -07001393 umo: textpb.UnmarshalOptions{
Joe Tsai0fc49f82019-05-01 12:29:25 -07001394 Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&pb2.Nested{})),
Herbie Ong300cff02019-03-20 18:05:16 -07001395 },
1396 inputMessage: &knownpb.Any{},
1397 inputText: `
1398[foobar/pb2.Nested]: {
1399 opt_string: "embedded inside Any"
1400 opt_nested: {
1401 opt_string: "inception"
Herbie Ong66c365c2019-01-04 14:08:41 -08001402 }
1403}
1404`,
1405 wantMessage: func() proto.Message {
1406 m := &pb2.Nested{
1407 OptString: scalar.String("embedded inside Any"),
1408 OptNested: &pb2.Nested{
1409 OptString: scalar.String("inception"),
1410 },
1411 }
Herbie Onge0cf15b2019-03-15 19:32:38 -07001412 b, err := proto.MarshalOptions{Deterministic: true}.Marshal(m)
Herbie Ong66c365c2019-01-04 14:08:41 -08001413 if err != nil {
1414 t.Fatalf("error in binary marshaling message for Any.value: %v", err)
1415 }
Herbie Ong300cff02019-03-20 18:05:16 -07001416 return &knownpb.Any{
1417 TypeUrl: "foobar/pb2.Nested",
1418 Value: b,
Herbie Ong66c365c2019-01-04 14:08:41 -08001419 }
1420 }(),
1421 }, {
1422 desc: "Any expanded with empty value",
Herbie Ong300cff02019-03-20 18:05:16 -07001423 umo: textpb.UnmarshalOptions{
Joe Tsai0fc49f82019-05-01 12:29:25 -07001424 Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&pb2.Nested{})),
Herbie Ong300cff02019-03-20 18:05:16 -07001425 },
1426 inputMessage: &knownpb.Any{},
1427 inputText: `[foo.com/pb2.Nested]: {}`,
1428 wantMessage: &knownpb.Any{
1429 TypeUrl: "foo.com/pb2.Nested",
Herbie Ong66c365c2019-01-04 14:08:41 -08001430 },
1431 }, {
1432 desc: "Any expanded with missing required error",
Herbie Ong300cff02019-03-20 18:05:16 -07001433 umo: textpb.UnmarshalOptions{
Joe Tsai0fc49f82019-05-01 12:29:25 -07001434 Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&pb2.PartialRequired{})),
Herbie Ong300cff02019-03-20 18:05:16 -07001435 },
1436 inputMessage: &knownpb.Any{},
1437 inputText: `
1438[pb2.PartialRequired]: {
1439 opt_string: "embedded inside Any"
Herbie Ong66c365c2019-01-04 14:08:41 -08001440}
1441`,
1442 wantMessage: func() proto.Message {
1443 m := &pb2.PartialRequired{
1444 OptString: scalar.String("embedded inside Any"),
1445 }
Damien Neil96c229a2019-04-03 12:17:24 -07001446 b, err := proto.MarshalOptions{
1447 AllowPartial: true,
1448 Deterministic: true,
1449 }.Marshal(m)
Herbie Ong300cff02019-03-20 18:05:16 -07001450 if err != nil {
Herbie Ong66c365c2019-01-04 14:08:41 -08001451 t.Fatalf("error in binary marshaling message for Any.value: %v", err)
1452 }
Herbie Ong300cff02019-03-20 18:05:16 -07001453 return &knownpb.Any{
1454 TypeUrl: "pb2.PartialRequired",
1455 Value: b,
Herbie Ong66c365c2019-01-04 14:08:41 -08001456 }
1457 }(),
1458 wantErr: true,
1459 }, {
Herbie Ong21a39742019-04-08 17:32:44 -07001460 desc: "Any with invalid UTF-8",
1461 umo: textpb.UnmarshalOptions{
Joe Tsai0fc49f82019-05-01 12:29:25 -07001462 Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&pb3.Nested{})),
Herbie Ong21a39742019-04-08 17:32:44 -07001463 },
1464 inputMessage: &knownpb.Any{},
1465 inputText: `
1466[pb3.Nested]: {
1467 s_string: "abc\xff"
1468}
1469`,
1470 wantMessage: func() proto.Message {
1471 m := &pb3.Nested{
1472 SString: "abc\xff",
1473 }
1474 var nerr errors.NonFatal
1475 b, err := proto.MarshalOptions{Deterministic: true}.Marshal(m)
1476 if !nerr.Merge(err) {
1477 t.Fatalf("error in binary marshaling message for Any.value: %v", err)
1478 }
1479 return &knownpb.Any{
Joe Tsai0fc49f82019-05-01 12:29:25 -07001480 TypeUrl: string(m.ProtoReflect().Descriptor().FullName()),
Herbie Ong21a39742019-04-08 17:32:44 -07001481 Value: b,
1482 }
1483 }(),
1484 wantErr: true,
1485 }, {
Herbie Ong66c365c2019-01-04 14:08:41 -08001486 desc: "Any expanded with unregistered type",
1487 umo: textpb.UnmarshalOptions{Resolver: preg.NewTypes()},
Herbie Ong300cff02019-03-20 18:05:16 -07001488 inputMessage: &knownpb.Any{},
1489 inputText: `[SomeMessage]: {}`,
1490 wantErr: true,
Herbie Ong66c365c2019-01-04 14:08:41 -08001491 }, {
1492 desc: "Any expanded with invalid value",
Herbie Ong300cff02019-03-20 18:05:16 -07001493 umo: textpb.UnmarshalOptions{
Joe Tsai0fc49f82019-05-01 12:29:25 -07001494 Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&pb2.Nested{})),
Herbie Ong300cff02019-03-20 18:05:16 -07001495 },
1496 inputMessage: &knownpb.Any{},
1497 inputText: `[pb2.Nested]: 123`,
1498 wantErr: true,
Herbie Ong66c365c2019-01-04 14:08:41 -08001499 }, {
1500 desc: "Any expanded with unknown fields",
Herbie Ong300cff02019-03-20 18:05:16 -07001501 umo: textpb.UnmarshalOptions{
Joe Tsai0fc49f82019-05-01 12:29:25 -07001502 Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&pb2.Nested{})),
Herbie Ong300cff02019-03-20 18:05:16 -07001503 },
1504 inputMessage: &knownpb.Any{},
1505 inputText: `
Herbie Ong66c365c2019-01-04 14:08:41 -08001506[pb2.Nested]: {}
1507unknown: ""
Herbie Ong66c365c2019-01-04 14:08:41 -08001508`,
1509 wantErr: true,
1510 }, {
1511 desc: "Any contains expanded and unexpanded fields",
Herbie Ong300cff02019-03-20 18:05:16 -07001512 umo: textpb.UnmarshalOptions{
Joe Tsai0fc49f82019-05-01 12:29:25 -07001513 Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&pb2.Nested{})),
Herbie Ong300cff02019-03-20 18:05:16 -07001514 },
1515 inputMessage: &knownpb.Any{},
1516 inputText: `
Herbie Ong66c365c2019-01-04 14:08:41 -08001517[pb2.Nested]: {}
1518type_url: "pb2.Nested"
Herbie Ong66c365c2019-01-04 14:08:41 -08001519`,
1520 wantErr: true,
Herbie Ong800c9902018-12-06 15:28:53 -08001521 }}
1522
1523 for _, tt := range tests {
1524 tt := tt
1525 t.Run(tt.desc, func(t *testing.T) {
Herbie Ong66c365c2019-01-04 14:08:41 -08001526 err := tt.umo.Unmarshal(tt.inputMessage, []byte(tt.inputText))
Herbie Ong800c9902018-12-06 15:28:53 -08001527 if err != nil && !tt.wantErr {
1528 t.Errorf("Unmarshal() returned error: %v\n\n", err)
1529 }
1530 if err == nil && tt.wantErr {
1531 t.Error("Unmarshal() got nil error, want error\n\n")
1532 }
Herbie Ong70651952018-12-13 14:19:50 -08001533 if tt.wantMessage != nil && !protoV1.Equal(tt.inputMessage.(protoV1.Message), tt.wantMessage.(protoV1.Message)) {
Herbie Ong800c9902018-12-06 15:28:53 -08001534 t.Errorf("Unmarshal()\n<got>\n%v\n<want>\n%v\n", tt.inputMessage, tt.wantMessage)
1535 }
1536 })
1537 }
1538}