blob: 799de2eb6a58eb31c79f030ae49fea74302644bd [file] [log] [blame]
Herbie Ong800c9902018-12-06 15:28:53 -08001// Copyright 2018 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
Damien Neil5c5b5312019-05-14 12:44:37 -07005package prototext_test
Herbie Ong800c9902018-12-06 15:28:53 -08006
7import (
8 "math"
9 "testing"
10
Damien Neil5c5b5312019-05-14 12:44:37 -070011 "google.golang.org/protobuf/encoding/prototext"
Damien Neile89e6242019-05-13 23:55:40 -070012 pimpl "google.golang.org/protobuf/internal/impl"
13 "google.golang.org/protobuf/internal/scalar"
14 "google.golang.org/protobuf/proto"
15 preg "google.golang.org/protobuf/reflect/protoregistry"
Herbie Ong800c9902018-12-06 15:28:53 -080016
Damien Neile89e6242019-05-13 23:55:40 -070017 "google.golang.org/protobuf/encoding/testprotos/pb2"
18 "google.golang.org/protobuf/encoding/testprotos/pb3"
Joe Tsaia95b29f2019-05-16 12:47:20 -070019 "google.golang.org/protobuf/types/known/anypb"
Herbie Ong800c9902018-12-06 15:28:53 -080020)
21
22func TestUnmarshal(t *testing.T) {
Herbie Ong800c9902018-12-06 15:28:53 -080023 tests := []struct {
24 desc string
Damien Neil5c5b5312019-05-14 12:44:37 -070025 umo prototext.UnmarshalOptions
Herbie Ong70651952018-12-13 14:19:50 -080026 inputMessage proto.Message
Herbie Ong800c9902018-12-06 15:28:53 -080027 inputText string
Herbie Ong70651952018-12-13 14:19:50 -080028 wantMessage proto.Message
Herbie Ong300cff02019-03-20 18:05:16 -070029 wantErr bool // TODO: Verify error message content.
Herbie Ong800c9902018-12-06 15:28:53 -080030 }{{
31 desc: "proto2 empty message",
32 inputMessage: &pb2.Scalars{},
33 wantMessage: &pb2.Scalars{},
34 }, {
Herbie Ong8170d692019-02-13 14:13:21 -080035 desc: "proto2 optional scalars set to zero values",
Herbie Ong800c9902018-12-06 15:28:53 -080036 inputMessage: &pb2.Scalars{},
37 inputText: `opt_bool: false
38opt_int32: 0
39opt_int64: 0
40opt_uint32: 0
41opt_uint64: 0
42opt_sint32: 0
43opt_sint64: 0
44opt_fixed32: 0
45opt_fixed64: 0
46opt_sfixed32: 0
47opt_sfixed64: 0
48opt_float: 0
49opt_double: 0
50opt_bytes: ""
51opt_string: ""
52`,
53 wantMessage: &pb2.Scalars{
54 OptBool: scalar.Bool(false),
55 OptInt32: scalar.Int32(0),
56 OptInt64: scalar.Int64(0),
57 OptUint32: scalar.Uint32(0),
58 OptUint64: scalar.Uint64(0),
59 OptSint32: scalar.Int32(0),
60 OptSint64: scalar.Int64(0),
61 OptFixed32: scalar.Uint32(0),
62 OptFixed64: scalar.Uint64(0),
63 OptSfixed32: scalar.Int32(0),
64 OptSfixed64: scalar.Int64(0),
65 OptFloat: scalar.Float32(0),
66 OptDouble: scalar.Float64(0),
67 OptBytes: []byte{},
68 OptString: scalar.String(""),
69 },
70 }, {
Herbie Ong8170d692019-02-13 14:13:21 -080071 desc: "proto3 scalars set to zero values",
Herbie Ong800c9902018-12-06 15:28:53 -080072 inputMessage: &pb3.Scalars{},
73 inputText: `s_bool: false
74s_int32: 0
75s_int64: 0
76s_uint32: 0
77s_uint64: 0
78s_sint32: 0
79s_sint64: 0
80s_fixed32: 0
81s_fixed64: 0
82s_sfixed32: 0
83s_sfixed64: 0
84s_float: 0
85s_double: 0
86s_bytes: ""
87s_string: ""
88`,
89 wantMessage: &pb3.Scalars{},
90 }, {
Herbie Ong8170d692019-02-13 14:13:21 -080091 desc: "proto2 optional scalars",
Herbie Ong800c9902018-12-06 15:28:53 -080092 inputMessage: &pb2.Scalars{},
93 inputText: `opt_bool: true
94opt_int32: 255
95opt_int64: 3735928559
96opt_uint32: 0xff
97opt_uint64: 0xdeadbeef
98opt_sint32: -1001
99opt_sint64: -0xffff
100opt_fixed64: 64
101opt_sfixed32: -32
102opt_float: 1.234
103opt_double: 1.23e+100
104opt_bytes: "\xe8\xb0\xb7\xe6\xad\x8c"
105opt_string: "谷歌"
106`,
107 wantMessage: &pb2.Scalars{
108 OptBool: scalar.Bool(true),
109 OptInt32: scalar.Int32(0xff),
110 OptInt64: scalar.Int64(0xdeadbeef),
111 OptUint32: scalar.Uint32(0xff),
112 OptUint64: scalar.Uint64(0xdeadbeef),
113 OptSint32: scalar.Int32(-1001),
114 OptSint64: scalar.Int64(-0xffff),
115 OptFixed64: scalar.Uint64(64),
116 OptSfixed32: scalar.Int32(-32),
117 OptFloat: scalar.Float32(1.234),
118 OptDouble: scalar.Float64(1.23e100),
119 OptBytes: []byte("\xe8\xb0\xb7\xe6\xad\x8c"),
120 OptString: scalar.String("谷歌"),
121 },
122 }, {
Herbie Ong20aefe92019-06-24 19:21:46 -0700123 desc: "case sensitive",
124 inputMessage: &pb3.Scalars{},
125 inputText: `S_BOOL: true`,
126 wantErr: true,
127 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800128 desc: "proto3 scalars",
Herbie Ong800c9902018-12-06 15:28:53 -0800129 inputMessage: &pb3.Scalars{},
130 inputText: `s_bool: true
131s_int32: 255
132s_int64: 3735928559
133s_uint32: 0xff
134s_uint64: 0xdeadbeef
135s_sint32: -1001
136s_sint64: -0xffff
137s_fixed64: 64
138s_sfixed32: -32
139s_float: 1.234
140s_double: 1.23e+100
141s_bytes: "\xe8\xb0\xb7\xe6\xad\x8c"
142s_string: "谷歌"
143`,
144 wantMessage: &pb3.Scalars{
145 SBool: true,
146 SInt32: 0xff,
147 SInt64: 0xdeadbeef,
148 SUint32: 0xff,
149 SUint64: 0xdeadbeef,
150 SSint32: -1001,
151 SSint64: -0xffff,
152 SFixed64: 64,
153 SSfixed32: -32,
154 SFloat: 1.234,
155 SDouble: 1.23e100,
156 SBytes: []byte("\xe8\xb0\xb7\xe6\xad\x8c"),
157 SString: "谷歌",
158 },
159 }, {
Herbie Ong21a39742019-04-08 17:32:44 -0700160 desc: "string with invalid UTF-8",
161 inputMessage: &pb3.Scalars{},
162 inputText: `s_string: "abc\xff"`,
Damien Neil8c86fc52019-06-19 09:28:29 -0700163 wantErr: true,
Herbie Ong21a39742019-04-08 17:32:44 -0700164 }, {
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 }, {
Herbie Ong20aefe92019-06-24 19:21:46 -0700411 desc: "group field name",
412 inputMessage: &pb2.Nests{},
413 inputText: `optgroup: {}`,
414 wantErr: true,
415 }, {
Herbie Ong800c9902018-12-06 15:28:53 -0800416 desc: "proto2 nested messages",
417 inputMessage: &pb2.Nests{},
418 inputText: `
419opt_nested: {
420 opt_string: "nested message"
421 opt_nested: {
422 opt_string: "another nested message"
423 }
424}
425`,
426 wantMessage: &pb2.Nests{
427 OptNested: &pb2.Nested{
428 OptString: scalar.String("nested message"),
429 OptNested: &pb2.Nested{
430 OptString: scalar.String("another nested message"),
431 },
432 },
433 },
434 }, {
435 desc: "proto3 nested empty message",
436 inputMessage: &pb3.Nests{},
437 inputText: "s_nested: {}",
438 wantMessage: &pb3.Nests{
439 SNested: &pb3.Nested{},
440 },
441 }, {
442 desc: "proto3 nested message",
443 inputMessage: &pb3.Nests{},
444 inputText: `
445s_nested: {
446 s_string: "nested message"
447 s_nested: {
448 s_string: "another nested message"
449 }
450}
451`,
452 wantMessage: &pb3.Nests{
453 SNested: &pb3.Nested{
454 SString: "nested message",
455 SNested: &pb3.Nested{
456 SString: "another nested message",
457 },
458 },
459 },
460 }, {
Herbie Ong21a39742019-04-08 17:32:44 -0700461 desc: "proto3 nested message contains invalid UTF-8",
462 inputMessage: &pb3.Nests{},
463 inputText: `s_nested: {
464 s_string: "abc\xff"
465}
466`,
Herbie Ong21a39742019-04-08 17:32:44 -0700467 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"`,
Damien Neil8c86fc52019-06-19 09:28:29 -0700559 wantErr: true,
Herbie Ong21a39742019-04-08 17:32:44 -0700560 }, {
Herbie Ong800c9902018-12-06 15:28:53 -0800561 desc: "repeated enums",
562 inputMessage: &pb2.Enums{},
563 inputText: `
Herbie Ong8170d692019-02-13 14:13:21 -0800564rpt_enum: TEN
Herbie Ong800c9902018-12-06 15:28:53 -0800565rpt_enum: 1
566rpt_nested_enum: [DOS, 2]
567rpt_enum: 42
568rpt_nested_enum: -47
569`,
570 wantMessage: &pb2.Enums{
Herbie Ong8170d692019-02-13 14:13:21 -0800571 RptEnum: []pb2.Enum{pb2.Enum_TEN, pb2.Enum_ONE, 42},
Herbie Ong800c9902018-12-06 15:28:53 -0800572 RptNestedEnum: []pb2.Enums_NestedEnum{pb2.Enums_DOS, pb2.Enums_DOS, -47},
573 },
574 }, {
575 desc: "repeated nested messages",
576 inputMessage: &pb2.Nests{},
577 inputText: `
578rpt_nested: {
579 opt_string: "repeat nested one"
580}
581rpt_nested: {
582 opt_string: "repeat nested two"
583 opt_nested: {
584 opt_string: "inside repeat nested two"
585 }
586}
587rpt_nested: {}
588`,
589 wantMessage: &pb2.Nests{
590 RptNested: []*pb2.Nested{
591 {
592 OptString: scalar.String("repeat nested one"),
593 },
594 {
595 OptString: scalar.String("repeat nested two"),
596 OptNested: &pb2.Nested{
597 OptString: scalar.String("inside repeat nested two"),
598 },
599 },
600 {},
601 },
602 },
603 }, {
604 desc: "repeated group fields",
605 inputMessage: &pb2.Nests{},
606 inputText: `
Herbie Ong0dcfb9a2019-01-14 15:32:26 -0800607RptGroup: {
Herbie Ong8170d692019-02-13 14:13:21 -0800608 rpt_string: "hello"
609 rpt_string: "world"
Herbie Ong800c9902018-12-06 15:28:53 -0800610}
Herbie Ong0dcfb9a2019-01-14 15:32:26 -0800611RptGroup: {}
Herbie Ong800c9902018-12-06 15:28:53 -0800612`,
613 wantMessage: &pb2.Nests{
614 Rptgroup: []*pb2.Nests_RptGroup{
615 {
Herbie Ong8170d692019-02-13 14:13:21 -0800616 RptString: []string{"hello", "world"},
Herbie Ong800c9902018-12-06 15:28:53 -0800617 },
618 {},
619 },
620 },
621 }, {
622 desc: "map fields 1",
Herbie Ong8170d692019-02-13 14:13:21 -0800623 inputMessage: &pb3.Maps{},
Herbie Ong800c9902018-12-06 15:28:53 -0800624 inputText: `
625int32_to_str: {
626 key: -101
627 value: "-101"
628}
629int32_to_str: {
630 key: 0
631 value: "zero"
632}
Herbie Ong8170d692019-02-13 14:13:21 -0800633bool_to_uint32: {
634 key: false
635 value: 101
Herbie Ong800c9902018-12-06 15:28:53 -0800636}
637int32_to_str: {
638 key: 255
639 value: "0xff"
640}
641bool_to_uint32: {
Herbie Ong800c9902018-12-06 15:28:53 -0800642 key: true
643 value: 42
644}
645`,
Herbie Ong8170d692019-02-13 14:13:21 -0800646 wantMessage: &pb3.Maps{
Herbie Ong800c9902018-12-06 15:28:53 -0800647 Int32ToStr: map[int32]string{
648 -101: "-101",
649 0xff: "0xff",
650 0: "zero",
651 },
Herbie Ong800c9902018-12-06 15:28:53 -0800652 BoolToUint32: map[bool]uint32{
653 true: 42,
654 false: 101,
655 },
656 },
657 }, {
658 desc: "map fields 2",
Herbie Ong8170d692019-02-13 14:13:21 -0800659 inputMessage: &pb3.Maps{},
Herbie Ong800c9902018-12-06 15:28:53 -0800660 inputText: `
661uint64_to_enum: {
662 key: 1
Herbie Ong8170d692019-02-13 14:13:21 -0800663 value: ONE
Herbie Ong800c9902018-12-06 15:28:53 -0800664}
665uint64_to_enum: {
666 key: 2
Herbie Ong8170d692019-02-13 14:13:21 -0800667 value: 2
Herbie Ong800c9902018-12-06 15:28:53 -0800668}
669uint64_to_enum: {
670 key: 10
Herbie Ong8170d692019-02-13 14:13:21 -0800671 value: 101
Herbie Ong800c9902018-12-06 15:28:53 -0800672}
673`,
Herbie Ong8170d692019-02-13 14:13:21 -0800674 wantMessage: &pb3.Maps{
675 Uint64ToEnum: map[uint64]pb3.Enum{
676 1: pb3.Enum_ONE,
677 2: pb3.Enum_TWO,
678 10: 101,
Herbie Ong800c9902018-12-06 15:28:53 -0800679 },
680 },
681 }, {
682 desc: "map fields 3",
Herbie Ong8170d692019-02-13 14:13:21 -0800683 inputMessage: &pb3.Maps{},
Herbie Ong800c9902018-12-06 15:28:53 -0800684 inputText: `
685str_to_nested: {
686 key: "nested_one"
687 value: {
Herbie Ong8170d692019-02-13 14:13:21 -0800688 s_string: "nested in a map"
Herbie Ong800c9902018-12-06 15:28:53 -0800689 }
690}
691`,
Herbie Ong8170d692019-02-13 14:13:21 -0800692 wantMessage: &pb3.Maps{
693 StrToNested: map[string]*pb3.Nested{
694 "nested_one": &pb3.Nested{
695 SString: "nested in a map",
Herbie Ong800c9902018-12-06 15:28:53 -0800696 },
697 },
698 },
699 }, {
700 desc: "map fields 4",
Herbie Ong8170d692019-02-13 14:13:21 -0800701 inputMessage: &pb3.Maps{},
Herbie Ong800c9902018-12-06 15:28:53 -0800702 inputText: `
703str_to_oneofs: {
704 key: "nested"
705 value: {
Herbie Ong8170d692019-02-13 14:13:21 -0800706 oneof_nested: {
707 s_string: "nested oneof in map field value"
Herbie Ong800c9902018-12-06 15:28:53 -0800708 }
709 }
710}
711str_to_oneofs: {
712 key: "string"
713 value: {
Herbie Ong8170d692019-02-13 14:13:21 -0800714 oneof_string: "hello"
Herbie Ong800c9902018-12-06 15:28:53 -0800715 }
716}
717`,
Herbie Ong8170d692019-02-13 14:13:21 -0800718 wantMessage: &pb3.Maps{
719 StrToOneofs: map[string]*pb3.Oneofs{
720 "string": &pb3.Oneofs{
721 Union: &pb3.Oneofs_OneofString{
722 OneofString: "hello",
Herbie Ong800c9902018-12-06 15:28:53 -0800723 },
724 },
Herbie Ong8170d692019-02-13 14:13:21 -0800725 "nested": &pb3.Oneofs{
726 Union: &pb3.Oneofs_OneofNested{
727 OneofNested: &pb3.Nested{
728 SString: "nested oneof in map field value",
Herbie Ong800c9902018-12-06 15:28:53 -0800729 },
730 },
731 },
732 },
733 },
734 }, {
735 desc: "map contains duplicate keys",
Herbie Ong8170d692019-02-13 14:13:21 -0800736 inputMessage: &pb3.Maps{},
Herbie Ong800c9902018-12-06 15:28:53 -0800737 inputText: `
738int32_to_str: {
739 key: 0
740 value: "cero"
741}
742int32_to_str: {
743 key: 0
744 value: "zero"
745}
746`,
Herbie Ong8170d692019-02-13 14:13:21 -0800747 wantMessage: &pb3.Maps{
Herbie Ong800c9902018-12-06 15:28:53 -0800748 Int32ToStr: map[int32]string{
749 0: "zero",
750 },
751 },
752 }, {
753 desc: "map contains duplicate key fields",
Herbie Ong8170d692019-02-13 14:13:21 -0800754 inputMessage: &pb3.Maps{},
Herbie Ong800c9902018-12-06 15:28:53 -0800755 inputText: `
756int32_to_str: {
757 key: 0
758 key: 1
759 value: "cero"
760}
761`,
762 wantErr: true,
763 }, {
764 desc: "map contains duplicate value fields",
Herbie Ong8170d692019-02-13 14:13:21 -0800765 inputMessage: &pb3.Maps{},
Herbie Ong800c9902018-12-06 15:28:53 -0800766 inputText: `
767int32_to_str: {
768 key: 1
769 value: "cero"
770 value: "uno"
771}
772`,
773 wantErr: true,
774 }, {
775 desc: "map contains missing key",
Herbie Ong8170d692019-02-13 14:13:21 -0800776 inputMessage: &pb3.Maps{},
Herbie Ong800c9902018-12-06 15:28:53 -0800777 inputText: `
778int32_to_str: {
779 value: "zero"
780}
Herbie Ong8170d692019-02-13 14:13:21 -0800781bool_to_uint32: {
782 value: 47
783}
784str_to_nested: {
785 value: {}
786}
Herbie Ong800c9902018-12-06 15:28:53 -0800787`,
Herbie Ong8170d692019-02-13 14:13:21 -0800788 wantMessage: &pb3.Maps{
Herbie Ong800c9902018-12-06 15:28:53 -0800789 Int32ToStr: map[int32]string{
790 0: "zero",
791 },
Herbie Ong8170d692019-02-13 14:13:21 -0800792 BoolToUint32: map[bool]uint32{
793 false: 47,
794 },
795 StrToNested: map[string]*pb3.Nested{
796 "": {},
797 },
Herbie Ong800c9902018-12-06 15:28:53 -0800798 },
799 }, {
800 desc: "map contains missing value",
Herbie Ong8170d692019-02-13 14:13:21 -0800801 inputMessage: &pb3.Maps{},
Herbie Ong800c9902018-12-06 15:28:53 -0800802 inputText: `
803int32_to_str: {
804 key: 100
805}
Herbie Ong8170d692019-02-13 14:13:21 -0800806bool_to_uint32: {
807 key: true
808}
809uint64_to_enum: {
810 key: 101
811}
812str_to_nested: {
813 key: "hello"
814}
Herbie Ong800c9902018-12-06 15:28:53 -0800815`,
Herbie Ong8170d692019-02-13 14:13:21 -0800816 wantMessage: &pb3.Maps{
Herbie Ong800c9902018-12-06 15:28:53 -0800817 Int32ToStr: map[int32]string{
818 100: "",
819 },
Herbie Ong8170d692019-02-13 14:13:21 -0800820 BoolToUint32: map[bool]uint32{
821 true: 0,
822 },
823 Uint64ToEnum: map[uint64]pb3.Enum{
824 101: pb3.Enum_ZERO,
825 },
826 StrToNested: map[string]*pb3.Nested{
827 "hello": {},
828 },
Herbie Ong800c9902018-12-06 15:28:53 -0800829 },
830 }, {
831 desc: "map contains missing key and value",
Herbie Ong8170d692019-02-13 14:13:21 -0800832 inputMessage: &pb3.Maps{},
Herbie Ong800c9902018-12-06 15:28:53 -0800833 inputText: `
834int32_to_str: {}
Herbie Ong8170d692019-02-13 14:13:21 -0800835bool_to_uint32: {}
836uint64_to_enum: {}
837str_to_nested: {}
Herbie Ong800c9902018-12-06 15:28:53 -0800838`,
Herbie Ong8170d692019-02-13 14:13:21 -0800839 wantMessage: &pb3.Maps{
840 Int32ToStr: map[int32]string{
841 0: "",
842 },
843 BoolToUint32: map[bool]uint32{
844 false: 0,
845 },
846 Uint64ToEnum: map[uint64]pb3.Enum{
847 0: pb3.Enum_ZERO,
848 },
849 StrToNested: map[string]*pb3.Nested{
850 "": {},
851 },
852 },
853 }, {
854 desc: "map contains overriding entries",
855 inputMessage: &pb3.Maps{},
856 inputText: `
857int32_to_str: {
858 key: 0
859}
860int32_to_str: {
861 value: "empty"
862}
863int32_to_str: {}
864`,
865 wantMessage: &pb3.Maps{
Herbie Ong800c9902018-12-06 15:28:53 -0800866 Int32ToStr: map[int32]string{
867 0: "",
868 },
869 },
870 }, {
Herbie Ong21a39742019-04-08 17:32:44 -0700871 desc: "map field value contains invalid UTF-8",
872 inputMessage: &pb3.Maps{},
873 inputText: `int32_to_str: {
874 key: 101
875 value: "abc\xff"
876}
877`,
Herbie Ong21a39742019-04-08 17:32:44 -0700878 wantErr: true,
879 }, {
880 desc: "map field key contains invalid UTF-8",
881 inputMessage: &pb3.Maps{},
882 inputText: `str_to_nested: {
883 key: "abc\xff"
884 value: {}
885}
886`,
Herbie Ong21a39742019-04-08 17:32:44 -0700887 wantErr: true,
888 }, {
Herbie Ong800c9902018-12-06 15:28:53 -0800889 desc: "map contains unknown field",
Herbie Ong8170d692019-02-13 14:13:21 -0800890 inputMessage: &pb3.Maps{},
Herbie Ong800c9902018-12-06 15:28:53 -0800891 inputText: `
892int32_to_str: {
893 key: 0
894 value: "cero"
895 unknown: "bad"
896}
897`,
898 wantErr: true,
899 }, {
900 desc: "map contains extension-like key field",
Herbie Ong8170d692019-02-13 14:13:21 -0800901 inputMessage: &pb3.Maps{},
Herbie Ong800c9902018-12-06 15:28:53 -0800902 inputText: `
903int32_to_str: {
904 [key]: 10
905 value: "ten"
906}
907`,
908 wantErr: true,
909 }, {
910 desc: "map contains invalid key",
Herbie Ong8170d692019-02-13 14:13:21 -0800911 inputMessage: &pb3.Maps{},
Herbie Ong800c9902018-12-06 15:28:53 -0800912 inputText: `
913int32_to_str: {
914 key: "invalid"
915 value: "cero"
916}
917`,
918 wantErr: true,
919 }, {
920 desc: "map contains invalid value",
Herbie Ong8170d692019-02-13 14:13:21 -0800921 inputMessage: &pb3.Maps{},
Herbie Ong800c9902018-12-06 15:28:53 -0800922 inputText: `
923int32_to_str: {
924 key: 100
925 value: 101
926}
927`,
928 wantErr: true,
929 }, {
930 desc: "map using mix of [] and repeated",
Herbie Ong8170d692019-02-13 14:13:21 -0800931 inputMessage: &pb3.Maps{},
Herbie Ong800c9902018-12-06 15:28:53 -0800932 inputText: `
933int32_to_str: {
934 key: 1
935 value: "one"
936}
937int32_to_str: [
938 {
939 key: 2
940 value: "not this"
941 },
942 {
943 },
944 {
945 key: 3
946 value: "three"
947 }
948]
949int32_to_str: {
950 key: 2
951 value: "two"
952}
953`,
Herbie Ong8170d692019-02-13 14:13:21 -0800954 wantMessage: &pb3.Maps{
Herbie Ong800c9902018-12-06 15:28:53 -0800955 Int32ToStr: map[int32]string{
956 0: "",
957 1: "one",
958 2: "two",
959 3: "three",
960 },
961 },
962 }, {
Herbie Ong42577ea2019-03-26 16:26:22 -0700963 desc: "required fields not set",
Herbie Ong800c9902018-12-06 15:28:53 -0800964 inputMessage: &pb2.Requireds{},
965 wantErr: true,
966 }, {
Herbie Ong42577ea2019-03-26 16:26:22 -0700967 desc: "required field set",
Herbie Ong800c9902018-12-06 15:28:53 -0800968 inputMessage: &pb2.PartialRequired{},
969 inputText: "req_string: 'this is required'",
970 wantMessage: &pb2.PartialRequired{
971 ReqString: scalar.String("this is required"),
972 },
973 }, {
Herbie Ong42577ea2019-03-26 16:26:22 -0700974 desc: "required fields partially set",
Herbie Ong800c9902018-12-06 15:28:53 -0800975 inputMessage: &pb2.Requireds{},
976 inputText: `
977req_bool: false
Herbie Ong800c9902018-12-06 15:28:53 -0800978req_sfixed64: 3203386110
979req_string: "hello"
Herbie Ong8170d692019-02-13 14:13:21 -0800980req_enum: ONE
Herbie Ong800c9902018-12-06 15:28:53 -0800981`,
982 wantMessage: &pb2.Requireds{
983 ReqBool: scalar.Bool(false),
Herbie Ong800c9902018-12-06 15:28:53 -0800984 ReqSfixed64: scalar.Int64(0xbeefcafe),
985 ReqString: scalar.String("hello"),
Herbie Ong8170d692019-02-13 14:13:21 -0800986 ReqEnum: pb2.Enum_ONE.Enum(),
Herbie Ong800c9902018-12-06 15:28:53 -0800987 },
988 wantErr: true,
989 }, {
Herbie Ong42577ea2019-03-26 16:26:22 -0700990 desc: "required fields partially set with AllowPartial",
Damien Neil5c5b5312019-05-14 12:44:37 -0700991 umo: prototext.UnmarshalOptions{AllowPartial: true},
Herbie Ong42577ea2019-03-26 16:26:22 -0700992 inputMessage: &pb2.Requireds{},
993 inputText: `
994req_bool: false
995req_sfixed64: 3203386110
996req_string: "hello"
997req_enum: ONE
998`,
999 wantMessage: &pb2.Requireds{
1000 ReqBool: scalar.Bool(false),
1001 ReqSfixed64: scalar.Int64(0xbeefcafe),
1002 ReqString: scalar.String("hello"),
1003 ReqEnum: pb2.Enum_ONE.Enum(),
1004 },
1005 }, {
1006 desc: "required fields all set",
Herbie Ong800c9902018-12-06 15:28:53 -08001007 inputMessage: &pb2.Requireds{},
1008 inputText: `
1009req_bool: false
Herbie Ong800c9902018-12-06 15:28:53 -08001010req_sfixed64: 0
Herbie Ong800c9902018-12-06 15:28:53 -08001011req_double: 0
1012req_string: ""
Herbie Ong8170d692019-02-13 14:13:21 -08001013req_enum: ONE
Herbie Ong800c9902018-12-06 15:28:53 -08001014req_nested: {}
1015`,
1016 wantMessage: &pb2.Requireds{
1017 ReqBool: scalar.Bool(false),
Herbie Ong800c9902018-12-06 15:28:53 -08001018 ReqSfixed64: scalar.Int64(0),
Herbie Ong800c9902018-12-06 15:28:53 -08001019 ReqDouble: scalar.Float64(0),
1020 ReqString: scalar.String(""),
Herbie Ong8170d692019-02-13 14:13:21 -08001021 ReqEnum: pb2.Enum_ONE.Enum(),
Herbie Ong800c9902018-12-06 15:28:53 -08001022 ReqNested: &pb2.Nested{},
1023 },
1024 }, {
1025 desc: "indirect required field",
1026 inputMessage: &pb2.IndirectRequired{},
1027 inputText: "opt_nested: {}",
1028 wantMessage: &pb2.IndirectRequired{
1029 OptNested: &pb2.NestedWithRequired{},
1030 },
1031 wantErr: true,
1032 }, {
Herbie Ong42577ea2019-03-26 16:26:22 -07001033 desc: "indirect required field with AllowPartial",
Damien Neil5c5b5312019-05-14 12:44:37 -07001034 umo: prototext.UnmarshalOptions{AllowPartial: true},
Herbie Ong42577ea2019-03-26 16:26:22 -07001035 inputMessage: &pb2.IndirectRequired{},
1036 inputText: "opt_nested: {}",
1037 wantMessage: &pb2.IndirectRequired{
1038 OptNested: &pb2.NestedWithRequired{},
1039 },
1040 }, {
Herbie Ong800c9902018-12-06 15:28:53 -08001041 desc: "indirect required field in repeated",
1042 inputMessage: &pb2.IndirectRequired{},
1043 inputText: `
1044rpt_nested: {
1045 req_string: "one"
1046}
1047rpt_nested: {}
Herbie Ong800c9902018-12-06 15:28:53 -08001048`,
1049 wantMessage: &pb2.IndirectRequired{
1050 RptNested: []*pb2.NestedWithRequired{
1051 {
1052 ReqString: scalar.String("one"),
1053 },
1054 {},
Herbie Ong800c9902018-12-06 15:28:53 -08001055 },
1056 },
1057 wantErr: true,
1058 }, {
Herbie Ong42577ea2019-03-26 16:26:22 -07001059 desc: "indirect required field in repeated with AllowPartial",
Damien Neil5c5b5312019-05-14 12:44:37 -07001060 umo: prototext.UnmarshalOptions{AllowPartial: true},
Herbie Ong42577ea2019-03-26 16:26:22 -07001061 inputMessage: &pb2.IndirectRequired{},
1062 inputText: `
1063rpt_nested: {
1064 req_string: "one"
1065}
1066rpt_nested: {}
1067`,
1068 wantMessage: &pb2.IndirectRequired{
1069 RptNested: []*pb2.NestedWithRequired{
1070 {
1071 ReqString: scalar.String("one"),
1072 },
1073 {},
1074 },
1075 },
1076 }, {
Herbie Ong800c9902018-12-06 15:28:53 -08001077 desc: "indirect required field in map",
1078 inputMessage: &pb2.IndirectRequired{},
1079 inputText: `
1080str_to_nested: {
1081 key: "missing"
1082}
1083str_to_nested: {
1084 key: "contains"
1085 value: {
1086 req_string: "here"
1087 }
1088}
1089`,
1090 wantMessage: &pb2.IndirectRequired{
1091 StrToNested: map[string]*pb2.NestedWithRequired{
1092 "missing": &pb2.NestedWithRequired{},
1093 "contains": &pb2.NestedWithRequired{
1094 ReqString: scalar.String("here"),
1095 },
1096 },
1097 },
1098 wantErr: true,
Herbie Ong7c624e22018-12-13 14:41:22 -08001099 }, {
Herbie Ong42577ea2019-03-26 16:26:22 -07001100 desc: "indirect required field in map with AllowPartial",
Damien Neil5c5b5312019-05-14 12:44:37 -07001101 umo: prototext.UnmarshalOptions{AllowPartial: true},
Herbie Ong42577ea2019-03-26 16:26:22 -07001102 inputMessage: &pb2.IndirectRequired{},
1103 inputText: `
1104str_to_nested: {
1105 key: "missing"
1106}
1107str_to_nested: {
1108 key: "contains"
1109 value: {
1110 req_string: "here"
1111 }
1112}
1113`,
1114 wantMessage: &pb2.IndirectRequired{
1115 StrToNested: map[string]*pb2.NestedWithRequired{
1116 "missing": &pb2.NestedWithRequired{},
1117 "contains": &pb2.NestedWithRequired{
1118 ReqString: scalar.String("here"),
1119 },
1120 },
1121 },
1122 }, {
Herbie Ong8170d692019-02-13 14:13:21 -08001123 desc: "indirect required field in oneof",
1124 inputMessage: &pb2.IndirectRequired{},
1125 inputText: `oneof_nested: {}
1126`,
1127 wantMessage: &pb2.IndirectRequired{
1128 Union: &pb2.IndirectRequired_OneofNested{
1129 OneofNested: &pb2.NestedWithRequired{},
1130 },
1131 },
1132 wantErr: true,
1133 }, {
Herbie Ong42577ea2019-03-26 16:26:22 -07001134 desc: "indirect required field in oneof with AllowPartial",
Damien Neil5c5b5312019-05-14 12:44:37 -07001135 umo: prototext.UnmarshalOptions{AllowPartial: true},
Herbie Ong42577ea2019-03-26 16:26:22 -07001136 inputMessage: &pb2.IndirectRequired{},
1137 inputText: `oneof_nested: {}
1138`,
1139 wantMessage: &pb2.IndirectRequired{
1140 Union: &pb2.IndirectRequired_OneofNested{
1141 OneofNested: &pb2.NestedWithRequired{},
1142 },
1143 },
1144 }, {
Herbie Ong7c624e22018-12-13 14:41:22 -08001145 desc: "ignore reserved field",
1146 inputMessage: &pb2.Nests{},
1147 inputText: "reserved_field: 'ignore this'",
1148 wantMessage: &pb2.Nests{},
Herbie Ongc525c972018-12-18 18:04:31 -08001149 }, {
1150 desc: "extensions of non-repeated fields",
1151 inputMessage: &pb2.Extensions{},
1152 inputText: `opt_string: "non-extension field"
1153[pb2.opt_ext_bool]: true
1154opt_bool: true
1155[pb2.opt_ext_nested]: {
1156 opt_string: "nested in an extension"
1157 opt_nested: {
1158 opt_string: "another nested in an extension"
1159 }
1160}
1161[pb2.opt_ext_string]: "extension field"
1162opt_int32: 42
Herbie Ong8170d692019-02-13 14:13:21 -08001163[pb2.opt_ext_enum]: TEN
Herbie Ongc525c972018-12-18 18:04:31 -08001164`,
1165 wantMessage: func() proto.Message {
1166 m := &pb2.Extensions{
1167 OptString: scalar.String("non-extension field"),
1168 OptBool: scalar.Bool(true),
1169 OptInt32: scalar.Int32(42),
1170 }
1171 setExtension(m, pb2.E_OptExtBool, true)
1172 setExtension(m, pb2.E_OptExtString, "extension field")
Herbie Ong8170d692019-02-13 14:13:21 -08001173 setExtension(m, pb2.E_OptExtEnum, pb2.Enum_TEN)
Herbie Ongc525c972018-12-18 18:04:31 -08001174 setExtension(m, pb2.E_OptExtNested, &pb2.Nested{
1175 OptString: scalar.String("nested in an extension"),
1176 OptNested: &pb2.Nested{
1177 OptString: scalar.String("another nested in an extension"),
1178 },
1179 })
1180 return m
1181 }(),
1182 }, {
Herbie Ong21a39742019-04-08 17:32:44 -07001183 desc: "extension field contains invalid UTF-8",
1184 inputMessage: &pb2.Extensions{},
1185 inputText: `[pb2.opt_ext_string]: "abc\xff"`,
Damien Neil8c86fc52019-06-19 09:28:29 -07001186 wantErr: true,
Herbie Ong21a39742019-04-08 17:32:44 -07001187 }, {
Herbie Ongc525c972018-12-18 18:04:31 -08001188 desc: "extensions of repeated fields",
1189 inputMessage: &pb2.Extensions{},
Herbie Ong8170d692019-02-13 14:13:21 -08001190 inputText: `[pb2.rpt_ext_enum]: TEN
Herbie Ongc525c972018-12-18 18:04:31 -08001191[pb2.rpt_ext_enum]: 101
1192[pb2.rpt_ext_fixed32]: 42
Herbie Ong8170d692019-02-13 14:13:21 -08001193[pb2.rpt_ext_enum]: ONE
Herbie Ongc525c972018-12-18 18:04:31 -08001194[pb2.rpt_ext_nested]: {
1195 opt_string: "one"
1196}
1197[pb2.rpt_ext_nested]: {
1198 opt_string: "two"
1199}
1200[pb2.rpt_ext_fixed32]: 47
1201[pb2.rpt_ext_nested]: {
1202 opt_string: "three"
1203}
1204`,
1205 wantMessage: func() proto.Message {
1206 m := &pb2.Extensions{}
Herbie Ong8170d692019-02-13 14:13:21 -08001207 setExtension(m, pb2.E_RptExtEnum, &[]pb2.Enum{pb2.Enum_TEN, 101, pb2.Enum_ONE})
Herbie Ongc525c972018-12-18 18:04:31 -08001208 setExtension(m, pb2.E_RptExtFixed32, &[]uint32{42, 47})
1209 setExtension(m, pb2.E_RptExtNested, &[]*pb2.Nested{
1210 &pb2.Nested{OptString: scalar.String("one")},
1211 &pb2.Nested{OptString: scalar.String("two")},
1212 &pb2.Nested{OptString: scalar.String("three")},
1213 })
1214 return m
1215 }(),
1216 }, {
1217 desc: "extensions of non-repeated fields in another message",
1218 inputMessage: &pb2.Extensions{},
1219 inputText: `[pb2.ExtensionsContainer.opt_ext_bool]: true
Herbie Ong8170d692019-02-13 14:13:21 -08001220[pb2.ExtensionsContainer.opt_ext_enum]: TEN
Herbie Ongc525c972018-12-18 18:04:31 -08001221[pb2.ExtensionsContainer.opt_ext_nested]: {
1222 opt_string: "nested in an extension"
1223 opt_nested: {
1224 opt_string: "another nested in an extension"
1225 }
1226}
1227[pb2.ExtensionsContainer.opt_ext_string]: "extension field"
1228`,
1229 wantMessage: func() proto.Message {
1230 m := &pb2.Extensions{}
1231 setExtension(m, pb2.E_ExtensionsContainer_OptExtBool, true)
1232 setExtension(m, pb2.E_ExtensionsContainer_OptExtString, "extension field")
Herbie Ong8170d692019-02-13 14:13:21 -08001233 setExtension(m, pb2.E_ExtensionsContainer_OptExtEnum, pb2.Enum_TEN)
Herbie Ongc525c972018-12-18 18:04:31 -08001234 setExtension(m, pb2.E_ExtensionsContainer_OptExtNested, &pb2.Nested{
1235 OptString: scalar.String("nested in an extension"),
1236 OptNested: &pb2.Nested{
1237 OptString: scalar.String("another nested in an extension"),
1238 },
1239 })
1240 return m
1241 }(),
1242 }, {
1243 desc: "extensions of repeated fields in another message",
1244 inputMessage: &pb2.Extensions{},
1245 inputText: `opt_string: "non-extension field"
1246opt_bool: true
1247opt_int32: 42
1248[pb2.ExtensionsContainer.rpt_ext_nested]: {
1249 opt_string: "one"
1250}
Herbie Ong8170d692019-02-13 14:13:21 -08001251[pb2.ExtensionsContainer.rpt_ext_enum]: TEN
Herbie Ongc525c972018-12-18 18:04:31 -08001252[pb2.ExtensionsContainer.rpt_ext_nested]: {
1253 opt_string: "two"
1254}
1255[pb2.ExtensionsContainer.rpt_ext_enum]: 101
1256[pb2.ExtensionsContainer.rpt_ext_string]: "hello"
Herbie Ong8170d692019-02-13 14:13:21 -08001257[pb2.ExtensionsContainer.rpt_ext_enum]: ONE
Herbie Ongc525c972018-12-18 18:04:31 -08001258[pb2.ExtensionsContainer.rpt_ext_nested]: {
1259 opt_string: "three"
1260}
1261[pb2.ExtensionsContainer.rpt_ext_string]: "world"
1262`,
1263 wantMessage: func() proto.Message {
1264 m := &pb2.Extensions{
1265 OptString: scalar.String("non-extension field"),
1266 OptBool: scalar.Bool(true),
1267 OptInt32: scalar.Int32(42),
1268 }
Herbie Ong8170d692019-02-13 14:13:21 -08001269 setExtension(m, pb2.E_ExtensionsContainer_RptExtEnum, &[]pb2.Enum{pb2.Enum_TEN, 101, pb2.Enum_ONE})
Herbie Ongc525c972018-12-18 18:04:31 -08001270 setExtension(m, pb2.E_ExtensionsContainer_RptExtString, &[]string{"hello", "world"})
1271 setExtension(m, pb2.E_ExtensionsContainer_RptExtNested, &[]*pb2.Nested{
1272 &pb2.Nested{OptString: scalar.String("one")},
1273 &pb2.Nested{OptString: scalar.String("two")},
1274 &pb2.Nested{OptString: scalar.String("three")},
1275 })
1276 return m
1277 }(),
1278 }, {
1279 desc: "invalid extension field name",
1280 inputMessage: &pb2.Extensions{},
1281 inputText: "[pb2.invalid_message_field]: true",
1282 wantErr: true,
Herbie Ong66c365c2019-01-04 14:08:41 -08001283 }, {
Herbie Ong6470ea62019-01-07 18:56:57 -08001284 desc: "MessageSet",
1285 inputMessage: &pb2.MessageSet{},
1286 inputText: `
1287[pb2.MessageSetExtension]: {
1288 opt_string: "a messageset extension"
1289}
1290[pb2.MessageSetExtension.ext_nested]: {
1291 opt_string: "just a regular extension"
1292}
1293[pb2.MessageSetExtension.not_message_set_extension]: {
1294 opt_string: "not a messageset extension"
1295}
1296`,
1297 wantMessage: func() proto.Message {
1298 m := &pb2.MessageSet{}
1299 setExtension(m, pb2.E_MessageSetExtension_MessageSetExtension, &pb2.MessageSetExtension{
1300 OptString: scalar.String("a messageset extension"),
1301 })
1302 setExtension(m, pb2.E_MessageSetExtension_NotMessageSetExtension, &pb2.MessageSetExtension{
1303 OptString: scalar.String("not a messageset extension"),
1304 })
1305 setExtension(m, pb2.E_MessageSetExtension_ExtNested, &pb2.Nested{
1306 OptString: scalar.String("just a regular extension"),
1307 })
1308 return m
1309 }(),
1310 }, {
1311 desc: "not real MessageSet 1",
1312 inputMessage: &pb2.FakeMessageSet{},
1313 inputText: `
1314[pb2.FakeMessageSetExtension.message_set_extension]: {
1315 opt_string: "not a messageset extension"
1316}
1317`,
1318 wantMessage: func() proto.Message {
1319 m := &pb2.FakeMessageSet{}
1320 setExtension(m, pb2.E_FakeMessageSetExtension_MessageSetExtension, &pb2.FakeMessageSetExtension{
1321 OptString: scalar.String("not a messageset extension"),
1322 })
1323 return m
1324 }(),
1325 }, {
1326 desc: "not real MessageSet 2",
1327 inputMessage: &pb2.FakeMessageSet{},
1328 inputText: `
1329[pb2.FakeMessageSetExtension]: {
1330 opt_string: "not a messageset extension"
1331}
1332`,
1333 wantErr: true,
1334 }, {
1335 desc: "not real MessageSet 3",
1336 inputMessage: &pb2.MessageSet{},
1337 inputText: `
1338[pb2.message_set_extension]: {
1339 opt_string: "another not a messageset extension"
Herbie Ong300cff02019-03-20 18:05:16 -07001340}`,
Herbie Ong6470ea62019-01-07 18:56:57 -08001341 wantMessage: func() proto.Message {
1342 m := &pb2.MessageSet{}
1343 setExtension(m, pb2.E_MessageSetExtension, &pb2.FakeMessageSetExtension{
1344 OptString: scalar.String("another not a messageset extension"),
1345 })
1346 return m
1347 }(),
1348 }, {
Herbie Ong66c365c2019-01-04 14:08:41 -08001349 desc: "Any not expanded",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001350 inputMessage: &anypb.Any{},
Herbie Ong300cff02019-03-20 18:05:16 -07001351 inputText: `
Herbie Ong66c365c2019-01-04 14:08:41 -08001352type_url: "pb2.Nested"
1353value: "some bytes"
Herbie Ong66c365c2019-01-04 14:08:41 -08001354`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001355 wantMessage: &anypb.Any{
Herbie Ong300cff02019-03-20 18:05:16 -07001356 TypeUrl: "pb2.Nested",
1357 Value: []byte("some bytes"),
Herbie Ong66c365c2019-01-04 14:08:41 -08001358 },
1359 }, {
1360 desc: "Any not expanded missing value",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001361 inputMessage: &anypb.Any{},
Herbie Ong300cff02019-03-20 18:05:16 -07001362 inputText: `type_url: "pb2.Nested"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001363 wantMessage: &anypb.Any{
Herbie Ong300cff02019-03-20 18:05:16 -07001364 TypeUrl: "pb2.Nested",
Herbie Ong66c365c2019-01-04 14:08:41 -08001365 },
1366 }, {
1367 desc: "Any not expanded missing type_url",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001368 inputMessage: &anypb.Any{},
Herbie Ong300cff02019-03-20 18:05:16 -07001369 inputText: `value: "some bytes"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001370 wantMessage: &anypb.Any{
Herbie Ong300cff02019-03-20 18:05:16 -07001371 Value: []byte("some bytes"),
Herbie Ong66c365c2019-01-04 14:08:41 -08001372 },
1373 }, {
1374 desc: "Any expanded",
Damien Neil5c5b5312019-05-14 12:44:37 -07001375 umo: prototext.UnmarshalOptions{
Joe Tsai0fc49f82019-05-01 12:29:25 -07001376 Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&pb2.Nested{})),
Herbie Ong300cff02019-03-20 18:05:16 -07001377 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07001378 inputMessage: &anypb.Any{},
Herbie Ong300cff02019-03-20 18:05:16 -07001379 inputText: `
1380[foobar/pb2.Nested]: {
1381 opt_string: "embedded inside Any"
1382 opt_nested: {
1383 opt_string: "inception"
Herbie Ong66c365c2019-01-04 14:08:41 -08001384 }
1385}
1386`,
1387 wantMessage: func() proto.Message {
1388 m := &pb2.Nested{
1389 OptString: scalar.String("embedded inside Any"),
1390 OptNested: &pb2.Nested{
1391 OptString: scalar.String("inception"),
1392 },
1393 }
Herbie Onge0cf15b2019-03-15 19:32:38 -07001394 b, err := proto.MarshalOptions{Deterministic: true}.Marshal(m)
Herbie Ong66c365c2019-01-04 14:08:41 -08001395 if err != nil {
1396 t.Fatalf("error in binary marshaling message for Any.value: %v", err)
1397 }
Joe Tsaia95b29f2019-05-16 12:47:20 -07001398 return &anypb.Any{
Herbie Ong300cff02019-03-20 18:05:16 -07001399 TypeUrl: "foobar/pb2.Nested",
1400 Value: b,
Herbie Ong66c365c2019-01-04 14:08:41 -08001401 }
1402 }(),
1403 }, {
1404 desc: "Any expanded with empty value",
Damien Neil5c5b5312019-05-14 12:44:37 -07001405 umo: prototext.UnmarshalOptions{
Joe Tsai0fc49f82019-05-01 12:29:25 -07001406 Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&pb2.Nested{})),
Herbie Ong300cff02019-03-20 18:05:16 -07001407 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07001408 inputMessage: &anypb.Any{},
Herbie Ong300cff02019-03-20 18:05:16 -07001409 inputText: `[foo.com/pb2.Nested]: {}`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001410 wantMessage: &anypb.Any{
Herbie Ong300cff02019-03-20 18:05:16 -07001411 TypeUrl: "foo.com/pb2.Nested",
Herbie Ong66c365c2019-01-04 14:08:41 -08001412 },
1413 }, {
Damien Neil0c9f0a92019-06-19 10:41:09 -07001414 desc: "Any expanded with missing required",
Damien Neil5c5b5312019-05-14 12:44:37 -07001415 umo: prototext.UnmarshalOptions{
Joe Tsai0fc49f82019-05-01 12:29:25 -07001416 Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&pb2.PartialRequired{})),
Herbie Ong300cff02019-03-20 18:05:16 -07001417 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07001418 inputMessage: &anypb.Any{},
Herbie Ong300cff02019-03-20 18:05:16 -07001419 inputText: `
1420[pb2.PartialRequired]: {
1421 opt_string: "embedded inside Any"
Herbie Ong66c365c2019-01-04 14:08:41 -08001422}
1423`,
1424 wantMessage: func() proto.Message {
1425 m := &pb2.PartialRequired{
1426 OptString: scalar.String("embedded inside Any"),
1427 }
Damien Neil96c229a2019-04-03 12:17:24 -07001428 b, err := proto.MarshalOptions{
1429 AllowPartial: true,
1430 Deterministic: true,
1431 }.Marshal(m)
Herbie Ong300cff02019-03-20 18:05:16 -07001432 if err != nil {
Herbie Ong66c365c2019-01-04 14:08:41 -08001433 t.Fatalf("error in binary marshaling message for Any.value: %v", err)
1434 }
Joe Tsaia95b29f2019-05-16 12:47:20 -07001435 return &anypb.Any{
Herbie Ong300cff02019-03-20 18:05:16 -07001436 TypeUrl: "pb2.PartialRequired",
1437 Value: b,
Herbie Ong66c365c2019-01-04 14:08:41 -08001438 }
1439 }(),
Herbie Ong66c365c2019-01-04 14:08:41 -08001440 }, {
Herbie Ong21a39742019-04-08 17:32:44 -07001441 desc: "Any with invalid UTF-8",
Damien Neil5c5b5312019-05-14 12:44:37 -07001442 umo: prototext.UnmarshalOptions{
Joe Tsai0fc49f82019-05-01 12:29:25 -07001443 Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&pb3.Nested{})),
Herbie Ong21a39742019-04-08 17:32:44 -07001444 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07001445 inputMessage: &anypb.Any{},
Herbie Ong21a39742019-04-08 17:32:44 -07001446 inputText: `
1447[pb3.Nested]: {
1448 s_string: "abc\xff"
1449}
1450`,
Herbie Ong21a39742019-04-08 17:32:44 -07001451 wantErr: true,
1452 }, {
Herbie Ong66c365c2019-01-04 14:08:41 -08001453 desc: "Any expanded with unregistered type",
Damien Neil5c5b5312019-05-14 12:44:37 -07001454 umo: prototext.UnmarshalOptions{Resolver: preg.NewTypes()},
Joe Tsaia95b29f2019-05-16 12:47:20 -07001455 inputMessage: &anypb.Any{},
Herbie Ong300cff02019-03-20 18:05:16 -07001456 inputText: `[SomeMessage]: {}`,
1457 wantErr: true,
Herbie Ong66c365c2019-01-04 14:08:41 -08001458 }, {
1459 desc: "Any expanded with invalid value",
Damien Neil5c5b5312019-05-14 12:44:37 -07001460 umo: prototext.UnmarshalOptions{
Joe Tsai0fc49f82019-05-01 12:29:25 -07001461 Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&pb2.Nested{})),
Herbie Ong300cff02019-03-20 18:05:16 -07001462 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07001463 inputMessage: &anypb.Any{},
Herbie Ong300cff02019-03-20 18:05:16 -07001464 inputText: `[pb2.Nested]: 123`,
1465 wantErr: true,
Herbie Ong66c365c2019-01-04 14:08:41 -08001466 }, {
1467 desc: "Any expanded with unknown fields",
Damien Neil5c5b5312019-05-14 12:44:37 -07001468 umo: prototext.UnmarshalOptions{
Joe Tsai0fc49f82019-05-01 12:29:25 -07001469 Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&pb2.Nested{})),
Herbie Ong300cff02019-03-20 18:05:16 -07001470 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07001471 inputMessage: &anypb.Any{},
Herbie Ong300cff02019-03-20 18:05:16 -07001472 inputText: `
Herbie Ong66c365c2019-01-04 14:08:41 -08001473[pb2.Nested]: {}
1474unknown: ""
Herbie Ong66c365c2019-01-04 14:08:41 -08001475`,
1476 wantErr: true,
1477 }, {
1478 desc: "Any contains expanded and unexpanded fields",
Damien Neil5c5b5312019-05-14 12:44:37 -07001479 umo: prototext.UnmarshalOptions{
Joe Tsai0fc49f82019-05-01 12:29:25 -07001480 Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&pb2.Nested{})),
Herbie Ong300cff02019-03-20 18:05:16 -07001481 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07001482 inputMessage: &anypb.Any{},
Herbie Ong300cff02019-03-20 18:05:16 -07001483 inputText: `
Herbie Ong66c365c2019-01-04 14:08:41 -08001484[pb2.Nested]: {}
1485type_url: "pb2.Nested"
Herbie Ong66c365c2019-01-04 14:08:41 -08001486`,
1487 wantErr: true,
Herbie Ong800c9902018-12-06 15:28:53 -08001488 }}
1489
1490 for _, tt := range tests {
1491 tt := tt
1492 t.Run(tt.desc, func(t *testing.T) {
Joe Tsaicdb77732019-05-14 16:05:06 -07001493 err := tt.umo.Unmarshal([]byte(tt.inputText), tt.inputMessage)
Herbie Ong800c9902018-12-06 15:28:53 -08001494 if err != nil && !tt.wantErr {
1495 t.Errorf("Unmarshal() returned error: %v\n\n", err)
1496 }
1497 if err == nil && tt.wantErr {
1498 t.Error("Unmarshal() got nil error, want error\n\n")
1499 }
Joe Tsai8d30bbe2019-05-16 15:53:25 -07001500 if tt.wantMessage != nil && !proto.Equal(tt.inputMessage, tt.wantMessage) {
Herbie Ong800c9902018-12-06 15:28:53 -08001501 t.Errorf("Unmarshal()\n<got>\n%v\n<want>\n%v\n", tt.inputMessage, tt.wantMessage)
1502 }
1503 })
1504 }
1505}