blob: 66c77f31eeb2a8ec17076167f5eb948235ddaf99 [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"
Damien Neile89e6242019-05-13 23:55:40 -070013 "google.golang.org/protobuf/proto"
14 preg "google.golang.org/protobuf/reflect/protoregistry"
Herbie Ong800c9902018-12-06 15:28:53 -080015
Damien Neile89e6242019-05-13 23:55:40 -070016 "google.golang.org/protobuf/encoding/testprotos/pb2"
17 "google.golang.org/protobuf/encoding/testprotos/pb3"
Joe Tsaia95b29f2019-05-16 12:47:20 -070018 "google.golang.org/protobuf/types/known/anypb"
Herbie Ong800c9902018-12-06 15:28:53 -080019)
20
21func TestUnmarshal(t *testing.T) {
Herbie Ong800c9902018-12-06 15:28:53 -080022 tests := []struct {
23 desc string
Damien Neil5c5b5312019-05-14 12:44:37 -070024 umo prototext.UnmarshalOptions
Herbie Ong70651952018-12-13 14:19:50 -080025 inputMessage proto.Message
Herbie Ong800c9902018-12-06 15:28:53 -080026 inputText string
Herbie Ong70651952018-12-13 14:19:50 -080027 wantMessage proto.Message
Herbie Ong300cff02019-03-20 18:05:16 -070028 wantErr bool // TODO: Verify error message content.
Herbie Ong800c9902018-12-06 15:28:53 -080029 }{{
30 desc: "proto2 empty message",
31 inputMessage: &pb2.Scalars{},
32 wantMessage: &pb2.Scalars{},
33 }, {
Herbie Ong8170d692019-02-13 14:13:21 -080034 desc: "proto2 optional scalars set to zero values",
Herbie Ong800c9902018-12-06 15:28:53 -080035 inputMessage: &pb2.Scalars{},
36 inputText: `opt_bool: false
37opt_int32: 0
38opt_int64: 0
39opt_uint32: 0
40opt_uint64: 0
41opt_sint32: 0
42opt_sint64: 0
43opt_fixed32: 0
44opt_fixed64: 0
45opt_sfixed32: 0
46opt_sfixed64: 0
47opt_float: 0
48opt_double: 0
49opt_bytes: ""
50opt_string: ""
51`,
52 wantMessage: &pb2.Scalars{
Damien Neila8a2cea2019-07-10 16:17:16 -070053 OptBool: proto.Bool(false),
54 OptInt32: proto.Int32(0),
55 OptInt64: proto.Int64(0),
56 OptUint32: proto.Uint32(0),
57 OptUint64: proto.Uint64(0),
58 OptSint32: proto.Int32(0),
59 OptSint64: proto.Int64(0),
60 OptFixed32: proto.Uint32(0),
61 OptFixed64: proto.Uint64(0),
62 OptSfixed32: proto.Int32(0),
63 OptSfixed64: proto.Int64(0),
64 OptFloat: proto.Float32(0),
65 OptDouble: proto.Float64(0),
Herbie Ong800c9902018-12-06 15:28:53 -080066 OptBytes: []byte{},
Damien Neila8a2cea2019-07-10 16:17:16 -070067 OptString: proto.String(""),
Herbie Ong800c9902018-12-06 15:28:53 -080068 },
69 }, {
Herbie Ong8170d692019-02-13 14:13:21 -080070 desc: "proto3 scalars set to zero values",
Herbie Ong800c9902018-12-06 15:28:53 -080071 inputMessage: &pb3.Scalars{},
72 inputText: `s_bool: false
73s_int32: 0
74s_int64: 0
75s_uint32: 0
76s_uint64: 0
77s_sint32: 0
78s_sint64: 0
79s_fixed32: 0
80s_fixed64: 0
81s_sfixed32: 0
82s_sfixed64: 0
83s_float: 0
84s_double: 0
85s_bytes: ""
86s_string: ""
87`,
88 wantMessage: &pb3.Scalars{},
89 }, {
Herbie Ong8170d692019-02-13 14:13:21 -080090 desc: "proto2 optional scalars",
Herbie Ong800c9902018-12-06 15:28:53 -080091 inputMessage: &pb2.Scalars{},
92 inputText: `opt_bool: true
93opt_int32: 255
94opt_int64: 3735928559
95opt_uint32: 0xff
96opt_uint64: 0xdeadbeef
97opt_sint32: -1001
98opt_sint64: -0xffff
99opt_fixed64: 64
100opt_sfixed32: -32
101opt_float: 1.234
102opt_double: 1.23e+100
103opt_bytes: "\xe8\xb0\xb7\xe6\xad\x8c"
104opt_string: "谷歌"
105`,
106 wantMessage: &pb2.Scalars{
Damien Neila8a2cea2019-07-10 16:17:16 -0700107 OptBool: proto.Bool(true),
108 OptInt32: proto.Int32(0xff),
109 OptInt64: proto.Int64(0xdeadbeef),
110 OptUint32: proto.Uint32(0xff),
111 OptUint64: proto.Uint64(0xdeadbeef),
112 OptSint32: proto.Int32(-1001),
113 OptSint64: proto.Int64(-0xffff),
114 OptFixed64: proto.Uint64(64),
115 OptSfixed32: proto.Int32(-32),
116 OptFloat: proto.Float32(1.234),
117 OptDouble: proto.Float64(1.23e100),
Herbie Ong800c9902018-12-06 15:28:53 -0800118 OptBytes: []byte("\xe8\xb0\xb7\xe6\xad\x8c"),
Damien Neila8a2cea2019-07-10 16:17:16 -0700119 OptString: proto.String("谷歌"),
Herbie Ong800c9902018-12-06 15:28:53 -0800120 },
121 }, {
Herbie Ong20aefe92019-06-24 19:21:46 -0700122 desc: "case sensitive",
123 inputMessage: &pb3.Scalars{},
124 inputText: `S_BOOL: true`,
125 wantErr: true,
126 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800127 desc: "proto3 scalars",
Herbie Ong800c9902018-12-06 15:28:53 -0800128 inputMessage: &pb3.Scalars{},
129 inputText: `s_bool: true
130s_int32: 255
131s_int64: 3735928559
132s_uint32: 0xff
133s_uint64: 0xdeadbeef
134s_sint32: -1001
135s_sint64: -0xffff
136s_fixed64: 64
137s_sfixed32: -32
138s_float: 1.234
139s_double: 1.23e+100
140s_bytes: "\xe8\xb0\xb7\xe6\xad\x8c"
141s_string: "谷歌"
142`,
143 wantMessage: &pb3.Scalars{
144 SBool: true,
145 SInt32: 0xff,
146 SInt64: 0xdeadbeef,
147 SUint32: 0xff,
148 SUint64: 0xdeadbeef,
149 SSint32: -1001,
150 SSint64: -0xffff,
151 SFixed64: 64,
152 SSfixed32: -32,
153 SFloat: 1.234,
154 SDouble: 1.23e100,
155 SBytes: []byte("\xe8\xb0\xb7\xe6\xad\x8c"),
156 SString: "谷歌",
157 },
158 }, {
Herbie Ong21a39742019-04-08 17:32:44 -0700159 desc: "string with invalid UTF-8",
160 inputMessage: &pb3.Scalars{},
161 inputText: `s_string: "abc\xff"`,
Damien Neil8c86fc52019-06-19 09:28:29 -0700162 wantErr: true,
Herbie Ong21a39742019-04-08 17:32:44 -0700163 }, {
Herbie Ong800c9902018-12-06 15:28:53 -0800164 desc: "proto2 message contains unknown field",
165 inputMessage: &pb2.Scalars{},
166 inputText: "unknown_field: 123",
167 wantErr: true,
168 }, {
169 desc: "proto3 message contains unknown field",
170 inputMessage: &pb3.Scalars{},
171 inputText: "unknown_field: 456",
172 wantErr: true,
173 }, {
174 desc: "proto2 numeric key field",
175 inputMessage: &pb2.Scalars{},
176 inputText: "1: true",
177 wantErr: true,
178 }, {
179 desc: "proto3 numeric key field",
180 inputMessage: &pb3.Scalars{},
181 inputText: "1: true",
182 wantErr: true,
183 }, {
184 desc: "invalid bool value",
185 inputMessage: &pb3.Scalars{},
186 inputText: "s_bool: 123",
187 wantErr: true,
188 }, {
189 desc: "invalid int32 value",
190 inputMessage: &pb3.Scalars{},
191 inputText: "s_int32: not_a_num",
192 wantErr: true,
193 }, {
194 desc: "invalid int64 value",
195 inputMessage: &pb3.Scalars{},
196 inputText: "s_int64: 'not a num either'",
197 wantErr: true,
198 }, {
199 desc: "invalid uint32 value",
200 inputMessage: &pb3.Scalars{},
201 inputText: "s_fixed32: -42",
202 wantErr: true,
203 }, {
204 desc: "invalid uint64 value",
205 inputMessage: &pb3.Scalars{},
206 inputText: "s_uint64: -47",
207 wantErr: true,
208 }, {
209 desc: "invalid sint32 value",
210 inputMessage: &pb3.Scalars{},
211 inputText: "s_sint32: '42'",
212 wantErr: true,
213 }, {
214 desc: "invalid sint64 value",
215 inputMessage: &pb3.Scalars{},
216 inputText: "s_sint64: '-47'",
217 wantErr: true,
218 }, {
219 desc: "invalid fixed32 value",
220 inputMessage: &pb3.Scalars{},
221 inputText: "s_fixed32: -42",
222 wantErr: true,
223 }, {
224 desc: "invalid fixed64 value",
225 inputMessage: &pb3.Scalars{},
226 inputText: "s_fixed64: -42",
227 wantErr: true,
228 }, {
229 desc: "invalid sfixed32 value",
230 inputMessage: &pb3.Scalars{},
231 inputText: "s_sfixed32: 'not valid'",
232 wantErr: true,
233 }, {
234 desc: "invalid sfixed64 value",
235 inputMessage: &pb3.Scalars{},
236 inputText: "s_sfixed64: bad",
237 wantErr: true,
238 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800239 desc: "float positive infinity",
Herbie Ong800c9902018-12-06 15:28:53 -0800240 inputMessage: &pb3.Scalars{},
241 inputText: "s_float: inf",
242 wantMessage: &pb3.Scalars{
243 SFloat: float32(math.Inf(1)),
244 },
245 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800246 desc: "float negative infinity",
Herbie Ong800c9902018-12-06 15:28:53 -0800247 inputMessage: &pb3.Scalars{},
248 inputText: "s_float: -inf",
249 wantMessage: &pb3.Scalars{
250 SFloat: float32(math.Inf(-1)),
251 },
252 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800253 desc: "double positive infinity",
Herbie Ong800c9902018-12-06 15:28:53 -0800254 inputMessage: &pb3.Scalars{},
255 inputText: "s_double: inf",
256 wantMessage: &pb3.Scalars{
257 SDouble: math.Inf(1),
258 },
259 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800260 desc: "double negative infinity",
Herbie Ong800c9902018-12-06 15:28:53 -0800261 inputMessage: &pb3.Scalars{},
262 inputText: "s_double: -inf",
263 wantMessage: &pb3.Scalars{
264 SDouble: math.Inf(-1),
265 },
266 }, {
267 desc: "invalid string value",
268 inputMessage: &pb3.Scalars{},
269 inputText: "s_string: invalid_string",
270 wantErr: true,
271 }, {
272 desc: "proto2 bytes set to empty string",
273 inputMessage: &pb2.Scalars{},
274 inputText: "opt_bytes: ''",
275 wantMessage: &pb2.Scalars{
276 OptBytes: []byte(""),
277 },
278 }, {
279 desc: "proto3 bytes set to empty string",
280 inputMessage: &pb3.Scalars{},
281 inputText: "s_bytes: ''",
282 wantMessage: &pb3.Scalars{},
283 }, {
284 desc: "proto2 duplicate singular field",
285 inputMessage: &pb2.Scalars{},
286 inputText: `
287opt_bool: true
288opt_bool: false
289`,
290 wantErr: true,
291 }, {
Herbie Ong800c9902018-12-06 15:28:53 -0800292 desc: "proto2 more duplicate singular field",
293 inputMessage: &pb2.Scalars{},
294 inputText: `
295opt_bool: true
296opt_string: "hello"
297opt_bool: false
298`,
299 wantErr: true,
300 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800301 desc: "proto2 invalid singular field",
302 inputMessage: &pb2.Scalars{},
303 inputText: `
304opt_bool: [true, false]
305`,
306 wantErr: true,
307 }, {
Herbie Ong800c9902018-12-06 15:28:53 -0800308 desc: "proto3 duplicate singular field",
309 inputMessage: &pb3.Scalars{},
310 inputText: `
311s_bool: false
312s_bool: true
313`,
314 wantErr: true,
315 }, {
316 desc: "proto3 more duplicate singular field",
317 inputMessage: &pb3.Scalars{},
318 inputText: `
319s_bool: false
320s_string: ""
321s_bool: true
322`,
323 wantErr: true,
324 }, {
325 desc: "proto2 enum",
326 inputMessage: &pb2.Enums{},
327 inputText: `
Herbie Ong8170d692019-02-13 14:13:21 -0800328opt_enum: ONE
Herbie Ong800c9902018-12-06 15:28:53 -0800329opt_nested_enum: UNO
330`,
331 wantMessage: &pb2.Enums{
Herbie Ong8170d692019-02-13 14:13:21 -0800332 OptEnum: pb2.Enum_ONE.Enum(),
Herbie Ong800c9902018-12-06 15:28:53 -0800333 OptNestedEnum: pb2.Enums_UNO.Enum(),
334 },
335 }, {
336 desc: "proto2 enum set to numeric values",
337 inputMessage: &pb2.Enums{},
338 inputText: `
Herbie Ong8170d692019-02-13 14:13:21 -0800339opt_enum: 2
Herbie Ong800c9902018-12-06 15:28:53 -0800340opt_nested_enum: 2
341`,
342 wantMessage: &pb2.Enums{
Herbie Ong8170d692019-02-13 14:13:21 -0800343 OptEnum: pb2.Enum_TWO.Enum(),
Herbie Ong800c9902018-12-06 15:28:53 -0800344 OptNestedEnum: pb2.Enums_DOS.Enum(),
345 },
346 }, {
347 desc: "proto2 enum set to unnamed numeric values",
348 inputMessage: &pb2.Enums{},
349 inputText: `
350opt_enum: 101
351opt_nested_enum: -101
352`,
353 wantMessage: &pb2.Enums{
Joe Tsai6dc168e2019-07-09 23:11:13 -0700354 OptEnum: pb2.Enum(101).Enum(),
355 OptNestedEnum: pb2.Enums_NestedEnum(-101).Enum(),
Herbie Ong800c9902018-12-06 15:28:53 -0800356 },
357 }, {
358 desc: "proto2 enum set to invalid named",
359 inputMessage: &pb2.Enums{},
360 inputText: `
Herbie Ong8170d692019-02-13 14:13:21 -0800361opt_enum: UNNAMED
Herbie Ong800c9902018-12-06 15:28:53 -0800362opt_nested_enum: UNNAMED_TOO
363`,
364 wantErr: true,
365 }, {
366 desc: "proto3 enum name value",
367 inputMessage: &pb3.Enums{},
368 inputText: `
369s_enum: ONE
370s_nested_enum: DIEZ
371`,
372 wantMessage: &pb3.Enums{
373 SEnum: pb3.Enum_ONE,
374 SNestedEnum: pb3.Enums_DIEZ,
375 },
376 }, {
377 desc: "proto3 enum numeric value",
378 inputMessage: &pb3.Enums{},
379 inputText: `
380s_enum: 2
Herbie Ong8170d692019-02-13 14:13:21 -0800381s_nested_enum: 2
Herbie Ong800c9902018-12-06 15:28:53 -0800382`,
383 wantMessage: &pb3.Enums{
384 SEnum: pb3.Enum_TWO,
Herbie Ong8170d692019-02-13 14:13:21 -0800385 SNestedEnum: pb3.Enums_DOS,
Herbie Ong800c9902018-12-06 15:28:53 -0800386 },
387 }, {
388 desc: "proto3 enum unnamed numeric value",
389 inputMessage: &pb3.Enums{},
390 inputText: `
391s_enum: 0x7fffffff
392s_nested_enum: -0x80000000
393`,
394 wantMessage: &pb3.Enums{
395 SEnum: 0x7fffffff,
396 SNestedEnum: -0x80000000,
397 },
398 }, {
399 desc: "proto2 nested empty messages",
400 inputMessage: &pb2.Nests{},
401 inputText: `
402opt_nested: {}
Herbie Ong0dcfb9a2019-01-14 15:32:26 -0800403OptGroup: {}
Herbie Ong800c9902018-12-06 15:28:53 -0800404`,
405 wantMessage: &pb2.Nests{
406 OptNested: &pb2.Nested{},
407 Optgroup: &pb2.Nests_OptGroup{},
408 },
409 }, {
Herbie Ong20aefe92019-06-24 19:21:46 -0700410 desc: "group field name",
411 inputMessage: &pb2.Nests{},
412 inputText: `optgroup: {}`,
413 wantErr: true,
414 }, {
Herbie Ong800c9902018-12-06 15:28:53 -0800415 desc: "proto2 nested messages",
416 inputMessage: &pb2.Nests{},
417 inputText: `
418opt_nested: {
419 opt_string: "nested message"
420 opt_nested: {
421 opt_string: "another nested message"
422 }
423}
424`,
425 wantMessage: &pb2.Nests{
426 OptNested: &pb2.Nested{
Damien Neila8a2cea2019-07-10 16:17:16 -0700427 OptString: proto.String("nested message"),
Herbie Ong800c9902018-12-06 15:28:53 -0800428 OptNested: &pb2.Nested{
Damien Neila8a2cea2019-07-10 16:17:16 -0700429 OptString: proto.String("another nested message"),
Herbie Ong800c9902018-12-06 15:28:53 -0800430 },
431 },
432 },
433 }, {
434 desc: "proto3 nested empty message",
435 inputMessage: &pb3.Nests{},
436 inputText: "s_nested: {}",
437 wantMessage: &pb3.Nests{
438 SNested: &pb3.Nested{},
439 },
440 }, {
441 desc: "proto3 nested message",
442 inputMessage: &pb3.Nests{},
443 inputText: `
444s_nested: {
445 s_string: "nested message"
446 s_nested: {
447 s_string: "another nested message"
448 }
449}
450`,
451 wantMessage: &pb3.Nests{
452 SNested: &pb3.Nested{
453 SString: "nested message",
454 SNested: &pb3.Nested{
455 SString: "another nested message",
456 },
457 },
458 },
459 }, {
Herbie Ong21a39742019-04-08 17:32:44 -0700460 desc: "proto3 nested message contains invalid UTF-8",
461 inputMessage: &pb3.Nests{},
462 inputText: `s_nested: {
463 s_string: "abc\xff"
464}
465`,
Herbie Ong21a39742019-04-08 17:32:44 -0700466 wantErr: true,
467 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800468 desc: "oneof set to empty string",
469 inputMessage: &pb3.Oneofs{},
470 inputText: "oneof_string: ''",
471 wantMessage: &pb3.Oneofs{
472 Union: &pb3.Oneofs_OneofString{},
Herbie Ong800c9902018-12-06 15:28:53 -0800473 },
474 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800475 desc: "oneof set to string",
476 inputMessage: &pb3.Oneofs{},
477 inputText: "oneof_string: 'hello'",
478 wantMessage: &pb3.Oneofs{
479 Union: &pb3.Oneofs_OneofString{
480 OneofString: "hello",
Herbie Ong800c9902018-12-06 15:28:53 -0800481 },
482 },
483 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800484 desc: "oneof set to enum",
485 inputMessage: &pb3.Oneofs{},
486 inputText: "oneof_enum: TEN",
487 wantMessage: &pb3.Oneofs{
488 Union: &pb3.Oneofs_OneofEnum{
489 OneofEnum: pb3.Enum_TEN,
Herbie Ong800c9902018-12-06 15:28:53 -0800490 },
491 },
492 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800493 desc: "oneof set to empty message",
494 inputMessage: &pb3.Oneofs{},
495 inputText: "oneof_nested: {}",
496 wantMessage: &pb3.Oneofs{
497 Union: &pb3.Oneofs_OneofNested{
498 OneofNested: &pb3.Nested{},
499 },
500 },
501 }, {
502 desc: "oneof set to message",
503 inputMessage: &pb3.Oneofs{},
Herbie Ong800c9902018-12-06 15:28:53 -0800504 inputText: `
Herbie Ong8170d692019-02-13 14:13:21 -0800505oneof_nested: {
506 s_string: "nested message"
Herbie Ong800c9902018-12-06 15:28:53 -0800507}
508`,
Herbie Ong8170d692019-02-13 14:13:21 -0800509 wantMessage: &pb3.Oneofs{
510 Union: &pb3.Oneofs_OneofNested{
511 OneofNested: &pb3.Nested{
512 SString: "nested message",
Herbie Ong800c9902018-12-06 15:28:53 -0800513 },
514 },
515 },
516 }, {
Herbie Ong8a1d4602019-04-02 20:19:36 -0700517 desc: "oneof set to more than one field",
Herbie Ong8170d692019-02-13 14:13:21 -0800518 inputMessage: &pb3.Oneofs{},
Herbie Ong6470ea62019-01-07 18:56:57 -0800519 inputText: `
Herbie Ong8a1d4602019-04-02 20:19:36 -0700520oneof_enum: ZERO
521oneof_string: "hello"
Herbie Ong6470ea62019-01-07 18:56:57 -0800522`,
Herbie Ong8a1d4602019-04-02 20:19:36 -0700523 wantErr: true,
Herbie Ong6470ea62019-01-07 18:56:57 -0800524 }, {
Herbie Ong800c9902018-12-06 15:28:53 -0800525 desc: "repeated scalar using same field name",
526 inputMessage: &pb2.Repeats{},
527 inputText: `
528rpt_string: "a"
529rpt_string: "b"
530rpt_int32: 0xff
531rpt_float: 1.23
532rpt_bytes: "bytes"
533`,
534 wantMessage: &pb2.Repeats{
535 RptString: []string{"a", "b"},
536 RptInt32: []int32{0xff},
537 RptFloat: []float32{1.23},
538 RptBytes: [][]byte{[]byte("bytes")},
539 },
540 }, {
541 desc: "repeated using mix of [] and repeated field name",
542 inputMessage: &pb2.Repeats{},
543 inputText: `
544rpt_string: "a"
545rpt_bool: true
546rpt_string: ["x", "y"]
547rpt_bool: [ false, true ]
548rpt_string: "b"
549`,
550 wantMessage: &pb2.Repeats{
551 RptString: []string{"a", "x", "y", "b"},
552 RptBool: []bool{true, false, true},
553 },
554 }, {
Herbie Ong21a39742019-04-08 17:32:44 -0700555 desc: "repeated contains invalid UTF-8",
556 inputMessage: &pb2.Repeats{},
557 inputText: `rpt_string: "abc\xff"`,
Damien Neil8c86fc52019-06-19 09:28:29 -0700558 wantErr: true,
Herbie Ong21a39742019-04-08 17:32:44 -0700559 }, {
Herbie Ong800c9902018-12-06 15:28:53 -0800560 desc: "repeated enums",
561 inputMessage: &pb2.Enums{},
562 inputText: `
Herbie Ong8170d692019-02-13 14:13:21 -0800563rpt_enum: TEN
Herbie Ong800c9902018-12-06 15:28:53 -0800564rpt_enum: 1
565rpt_nested_enum: [DOS, 2]
566rpt_enum: 42
567rpt_nested_enum: -47
568`,
569 wantMessage: &pb2.Enums{
Herbie Ong8170d692019-02-13 14:13:21 -0800570 RptEnum: []pb2.Enum{pb2.Enum_TEN, pb2.Enum_ONE, 42},
Herbie Ong800c9902018-12-06 15:28:53 -0800571 RptNestedEnum: []pb2.Enums_NestedEnum{pb2.Enums_DOS, pb2.Enums_DOS, -47},
572 },
573 }, {
574 desc: "repeated nested messages",
575 inputMessage: &pb2.Nests{},
576 inputText: `
577rpt_nested: {
578 opt_string: "repeat nested one"
579}
580rpt_nested: {
581 opt_string: "repeat nested two"
582 opt_nested: {
583 opt_string: "inside repeat nested two"
584 }
585}
586rpt_nested: {}
587`,
588 wantMessage: &pb2.Nests{
589 RptNested: []*pb2.Nested{
590 {
Damien Neila8a2cea2019-07-10 16:17:16 -0700591 OptString: proto.String("repeat nested one"),
Herbie Ong800c9902018-12-06 15:28:53 -0800592 },
593 {
Damien Neila8a2cea2019-07-10 16:17:16 -0700594 OptString: proto.String("repeat nested two"),
Herbie Ong800c9902018-12-06 15:28:53 -0800595 OptNested: &pb2.Nested{
Damien Neila8a2cea2019-07-10 16:17:16 -0700596 OptString: proto.String("inside repeat nested two"),
Herbie Ong800c9902018-12-06 15:28:53 -0800597 },
598 },
599 {},
600 },
601 },
602 }, {
603 desc: "repeated group fields",
604 inputMessage: &pb2.Nests{},
605 inputText: `
Herbie Ong0dcfb9a2019-01-14 15:32:26 -0800606RptGroup: {
Herbie Ong8170d692019-02-13 14:13:21 -0800607 rpt_string: "hello"
608 rpt_string: "world"
Herbie Ong800c9902018-12-06 15:28:53 -0800609}
Herbie Ong0dcfb9a2019-01-14 15:32:26 -0800610RptGroup: {}
Herbie Ong800c9902018-12-06 15:28:53 -0800611`,
612 wantMessage: &pb2.Nests{
613 Rptgroup: []*pb2.Nests_RptGroup{
614 {
Herbie Ong8170d692019-02-13 14:13:21 -0800615 RptString: []string{"hello", "world"},
Herbie Ong800c9902018-12-06 15:28:53 -0800616 },
617 {},
618 },
619 },
620 }, {
621 desc: "map fields 1",
Herbie Ong8170d692019-02-13 14:13:21 -0800622 inputMessage: &pb3.Maps{},
Herbie Ong800c9902018-12-06 15:28:53 -0800623 inputText: `
624int32_to_str: {
625 key: -101
626 value: "-101"
627}
628int32_to_str: {
629 key: 0
630 value: "zero"
631}
Herbie Ong8170d692019-02-13 14:13:21 -0800632bool_to_uint32: {
633 key: false
634 value: 101
Herbie Ong800c9902018-12-06 15:28:53 -0800635}
636int32_to_str: {
637 key: 255
638 value: "0xff"
639}
640bool_to_uint32: {
Herbie Ong800c9902018-12-06 15:28:53 -0800641 key: true
642 value: 42
643}
644`,
Herbie Ong8170d692019-02-13 14:13:21 -0800645 wantMessage: &pb3.Maps{
Herbie Ong800c9902018-12-06 15:28:53 -0800646 Int32ToStr: map[int32]string{
647 -101: "-101",
648 0xff: "0xff",
649 0: "zero",
650 },
Herbie Ong800c9902018-12-06 15:28:53 -0800651 BoolToUint32: map[bool]uint32{
652 true: 42,
653 false: 101,
654 },
655 },
656 }, {
657 desc: "map fields 2",
Herbie Ong8170d692019-02-13 14:13:21 -0800658 inputMessage: &pb3.Maps{},
Herbie Ong800c9902018-12-06 15:28:53 -0800659 inputText: `
660uint64_to_enum: {
661 key: 1
Herbie Ong8170d692019-02-13 14:13:21 -0800662 value: ONE
Herbie Ong800c9902018-12-06 15:28:53 -0800663}
664uint64_to_enum: {
665 key: 2
Herbie Ong8170d692019-02-13 14:13:21 -0800666 value: 2
Herbie Ong800c9902018-12-06 15:28:53 -0800667}
668uint64_to_enum: {
669 key: 10
Herbie Ong8170d692019-02-13 14:13:21 -0800670 value: 101
Herbie Ong800c9902018-12-06 15:28:53 -0800671}
672`,
Herbie Ong8170d692019-02-13 14:13:21 -0800673 wantMessage: &pb3.Maps{
674 Uint64ToEnum: map[uint64]pb3.Enum{
675 1: pb3.Enum_ONE,
676 2: pb3.Enum_TWO,
677 10: 101,
Herbie Ong800c9902018-12-06 15:28:53 -0800678 },
679 },
680 }, {
681 desc: "map fields 3",
Herbie Ong8170d692019-02-13 14:13:21 -0800682 inputMessage: &pb3.Maps{},
Herbie Ong800c9902018-12-06 15:28:53 -0800683 inputText: `
684str_to_nested: {
685 key: "nested_one"
686 value: {
Herbie Ong8170d692019-02-13 14:13:21 -0800687 s_string: "nested in a map"
Herbie Ong800c9902018-12-06 15:28:53 -0800688 }
689}
690`,
Herbie Ong8170d692019-02-13 14:13:21 -0800691 wantMessage: &pb3.Maps{
692 StrToNested: map[string]*pb3.Nested{
693 "nested_one": &pb3.Nested{
694 SString: "nested in a map",
Herbie Ong800c9902018-12-06 15:28:53 -0800695 },
696 },
697 },
698 }, {
699 desc: "map fields 4",
Herbie Ong8170d692019-02-13 14:13:21 -0800700 inputMessage: &pb3.Maps{},
Herbie Ong800c9902018-12-06 15:28:53 -0800701 inputText: `
702str_to_oneofs: {
703 key: "nested"
704 value: {
Herbie Ong8170d692019-02-13 14:13:21 -0800705 oneof_nested: {
706 s_string: "nested oneof in map field value"
Herbie Ong800c9902018-12-06 15:28:53 -0800707 }
708 }
709}
710str_to_oneofs: {
711 key: "string"
712 value: {
Herbie Ong8170d692019-02-13 14:13:21 -0800713 oneof_string: "hello"
Herbie Ong800c9902018-12-06 15:28:53 -0800714 }
715}
716`,
Herbie Ong8170d692019-02-13 14:13:21 -0800717 wantMessage: &pb3.Maps{
718 StrToOneofs: map[string]*pb3.Oneofs{
719 "string": &pb3.Oneofs{
720 Union: &pb3.Oneofs_OneofString{
721 OneofString: "hello",
Herbie Ong800c9902018-12-06 15:28:53 -0800722 },
723 },
Herbie Ong8170d692019-02-13 14:13:21 -0800724 "nested": &pb3.Oneofs{
725 Union: &pb3.Oneofs_OneofNested{
726 OneofNested: &pb3.Nested{
727 SString: "nested oneof in map field value",
Herbie Ong800c9902018-12-06 15:28:53 -0800728 },
729 },
730 },
731 },
732 },
733 }, {
734 desc: "map contains duplicate keys",
Herbie Ong8170d692019-02-13 14:13:21 -0800735 inputMessage: &pb3.Maps{},
Herbie Ong800c9902018-12-06 15:28:53 -0800736 inputText: `
737int32_to_str: {
738 key: 0
739 value: "cero"
740}
741int32_to_str: {
742 key: 0
743 value: "zero"
744}
745`,
Herbie Ong8170d692019-02-13 14:13:21 -0800746 wantMessage: &pb3.Maps{
Herbie Ong800c9902018-12-06 15:28:53 -0800747 Int32ToStr: map[int32]string{
748 0: "zero",
749 },
750 },
751 }, {
752 desc: "map contains duplicate key fields",
Herbie Ong8170d692019-02-13 14:13:21 -0800753 inputMessage: &pb3.Maps{},
Herbie Ong800c9902018-12-06 15:28:53 -0800754 inputText: `
755int32_to_str: {
756 key: 0
757 key: 1
758 value: "cero"
759}
760`,
761 wantErr: true,
762 }, {
763 desc: "map contains duplicate value fields",
Herbie Ong8170d692019-02-13 14:13:21 -0800764 inputMessage: &pb3.Maps{},
Herbie Ong800c9902018-12-06 15:28:53 -0800765 inputText: `
766int32_to_str: {
767 key: 1
768 value: "cero"
769 value: "uno"
770}
771`,
772 wantErr: true,
773 }, {
774 desc: "map contains missing key",
Herbie Ong8170d692019-02-13 14:13:21 -0800775 inputMessage: &pb3.Maps{},
Herbie Ong800c9902018-12-06 15:28:53 -0800776 inputText: `
777int32_to_str: {
778 value: "zero"
779}
Herbie Ong8170d692019-02-13 14:13:21 -0800780bool_to_uint32: {
781 value: 47
782}
783str_to_nested: {
784 value: {}
785}
Herbie Ong800c9902018-12-06 15:28:53 -0800786`,
Herbie Ong8170d692019-02-13 14:13:21 -0800787 wantMessage: &pb3.Maps{
Herbie Ong800c9902018-12-06 15:28:53 -0800788 Int32ToStr: map[int32]string{
789 0: "zero",
790 },
Herbie Ong8170d692019-02-13 14:13:21 -0800791 BoolToUint32: map[bool]uint32{
792 false: 47,
793 },
794 StrToNested: map[string]*pb3.Nested{
795 "": {},
796 },
Herbie Ong800c9902018-12-06 15:28:53 -0800797 },
798 }, {
799 desc: "map contains missing value",
Herbie Ong8170d692019-02-13 14:13:21 -0800800 inputMessage: &pb3.Maps{},
Herbie Ong800c9902018-12-06 15:28:53 -0800801 inputText: `
802int32_to_str: {
803 key: 100
804}
Herbie Ong8170d692019-02-13 14:13:21 -0800805bool_to_uint32: {
806 key: true
807}
808uint64_to_enum: {
809 key: 101
810}
811str_to_nested: {
812 key: "hello"
813}
Herbie Ong800c9902018-12-06 15:28:53 -0800814`,
Herbie Ong8170d692019-02-13 14:13:21 -0800815 wantMessage: &pb3.Maps{
Herbie Ong800c9902018-12-06 15:28:53 -0800816 Int32ToStr: map[int32]string{
817 100: "",
818 },
Herbie Ong8170d692019-02-13 14:13:21 -0800819 BoolToUint32: map[bool]uint32{
820 true: 0,
821 },
822 Uint64ToEnum: map[uint64]pb3.Enum{
823 101: pb3.Enum_ZERO,
824 },
825 StrToNested: map[string]*pb3.Nested{
826 "hello": {},
827 },
Herbie Ong800c9902018-12-06 15:28:53 -0800828 },
829 }, {
830 desc: "map contains missing key and value",
Herbie Ong8170d692019-02-13 14:13:21 -0800831 inputMessage: &pb3.Maps{},
Herbie Ong800c9902018-12-06 15:28:53 -0800832 inputText: `
833int32_to_str: {}
Herbie Ong8170d692019-02-13 14:13:21 -0800834bool_to_uint32: {}
835uint64_to_enum: {}
836str_to_nested: {}
Herbie Ong800c9902018-12-06 15:28:53 -0800837`,
Herbie Ong8170d692019-02-13 14:13:21 -0800838 wantMessage: &pb3.Maps{
839 Int32ToStr: map[int32]string{
840 0: "",
841 },
842 BoolToUint32: map[bool]uint32{
843 false: 0,
844 },
845 Uint64ToEnum: map[uint64]pb3.Enum{
846 0: pb3.Enum_ZERO,
847 },
848 StrToNested: map[string]*pb3.Nested{
849 "": {},
850 },
851 },
852 }, {
853 desc: "map contains overriding entries",
854 inputMessage: &pb3.Maps{},
855 inputText: `
856int32_to_str: {
857 key: 0
858}
859int32_to_str: {
860 value: "empty"
861}
862int32_to_str: {}
863`,
864 wantMessage: &pb3.Maps{
Herbie Ong800c9902018-12-06 15:28:53 -0800865 Int32ToStr: map[int32]string{
866 0: "",
867 },
868 },
869 }, {
Herbie Ong21a39742019-04-08 17:32:44 -0700870 desc: "map field value contains invalid UTF-8",
871 inputMessage: &pb3.Maps{},
872 inputText: `int32_to_str: {
873 key: 101
874 value: "abc\xff"
875}
876`,
Herbie Ong21a39742019-04-08 17:32:44 -0700877 wantErr: true,
878 }, {
879 desc: "map field key contains invalid UTF-8",
880 inputMessage: &pb3.Maps{},
881 inputText: `str_to_nested: {
882 key: "abc\xff"
883 value: {}
884}
885`,
Herbie Ong21a39742019-04-08 17:32:44 -0700886 wantErr: true,
887 }, {
Herbie Ong800c9902018-12-06 15:28:53 -0800888 desc: "map contains unknown field",
Herbie Ong8170d692019-02-13 14:13:21 -0800889 inputMessage: &pb3.Maps{},
Herbie Ong800c9902018-12-06 15:28:53 -0800890 inputText: `
891int32_to_str: {
892 key: 0
893 value: "cero"
894 unknown: "bad"
895}
896`,
897 wantErr: true,
898 }, {
899 desc: "map contains extension-like key field",
Herbie Ong8170d692019-02-13 14:13:21 -0800900 inputMessage: &pb3.Maps{},
Herbie Ong800c9902018-12-06 15:28:53 -0800901 inputText: `
902int32_to_str: {
903 [key]: 10
904 value: "ten"
905}
906`,
907 wantErr: true,
908 }, {
909 desc: "map contains invalid key",
Herbie Ong8170d692019-02-13 14:13:21 -0800910 inputMessage: &pb3.Maps{},
Herbie Ong800c9902018-12-06 15:28:53 -0800911 inputText: `
912int32_to_str: {
913 key: "invalid"
914 value: "cero"
915}
916`,
917 wantErr: true,
918 }, {
919 desc: "map contains invalid value",
Herbie Ong8170d692019-02-13 14:13:21 -0800920 inputMessage: &pb3.Maps{},
Herbie Ong800c9902018-12-06 15:28:53 -0800921 inputText: `
922int32_to_str: {
923 key: 100
924 value: 101
925}
926`,
927 wantErr: true,
928 }, {
929 desc: "map using mix of [] and repeated",
Herbie Ong8170d692019-02-13 14:13:21 -0800930 inputMessage: &pb3.Maps{},
Herbie Ong800c9902018-12-06 15:28:53 -0800931 inputText: `
932int32_to_str: {
933 key: 1
934 value: "one"
935}
936int32_to_str: [
937 {
938 key: 2
939 value: "not this"
940 },
941 {
942 },
943 {
944 key: 3
945 value: "three"
946 }
947]
948int32_to_str: {
949 key: 2
950 value: "two"
951}
952`,
Herbie Ong8170d692019-02-13 14:13:21 -0800953 wantMessage: &pb3.Maps{
Herbie Ong800c9902018-12-06 15:28:53 -0800954 Int32ToStr: map[int32]string{
955 0: "",
956 1: "one",
957 2: "two",
958 3: "three",
959 },
960 },
961 }, {
Herbie Ong42577ea2019-03-26 16:26:22 -0700962 desc: "required fields not set",
Herbie Ong800c9902018-12-06 15:28:53 -0800963 inputMessage: &pb2.Requireds{},
964 wantErr: true,
965 }, {
Herbie Ong42577ea2019-03-26 16:26:22 -0700966 desc: "required field set",
Herbie Ong800c9902018-12-06 15:28:53 -0800967 inputMessage: &pb2.PartialRequired{},
968 inputText: "req_string: 'this is required'",
969 wantMessage: &pb2.PartialRequired{
Damien Neila8a2cea2019-07-10 16:17:16 -0700970 ReqString: proto.String("this is required"),
Herbie Ong800c9902018-12-06 15:28:53 -0800971 },
972 }, {
Herbie Ong42577ea2019-03-26 16:26:22 -0700973 desc: "required fields partially set",
Herbie Ong800c9902018-12-06 15:28:53 -0800974 inputMessage: &pb2.Requireds{},
975 inputText: `
976req_bool: false
Herbie Ong800c9902018-12-06 15:28:53 -0800977req_sfixed64: 3203386110
978req_string: "hello"
Herbie Ong8170d692019-02-13 14:13:21 -0800979req_enum: ONE
Herbie Ong800c9902018-12-06 15:28:53 -0800980`,
981 wantMessage: &pb2.Requireds{
Damien Neila8a2cea2019-07-10 16:17:16 -0700982 ReqBool: proto.Bool(false),
983 ReqSfixed64: proto.Int64(0xbeefcafe),
984 ReqString: proto.String("hello"),
Herbie Ong8170d692019-02-13 14:13:21 -0800985 ReqEnum: pb2.Enum_ONE.Enum(),
Herbie Ong800c9902018-12-06 15:28:53 -0800986 },
987 wantErr: true,
988 }, {
Herbie Ong42577ea2019-03-26 16:26:22 -0700989 desc: "required fields partially set with AllowPartial",
Damien Neil5c5b5312019-05-14 12:44:37 -0700990 umo: prototext.UnmarshalOptions{AllowPartial: true},
Herbie Ong42577ea2019-03-26 16:26:22 -0700991 inputMessage: &pb2.Requireds{},
992 inputText: `
993req_bool: false
994req_sfixed64: 3203386110
995req_string: "hello"
996req_enum: ONE
997`,
998 wantMessage: &pb2.Requireds{
Damien Neila8a2cea2019-07-10 16:17:16 -0700999 ReqBool: proto.Bool(false),
1000 ReqSfixed64: proto.Int64(0xbeefcafe),
1001 ReqString: proto.String("hello"),
Herbie Ong42577ea2019-03-26 16:26:22 -07001002 ReqEnum: pb2.Enum_ONE.Enum(),
1003 },
1004 }, {
1005 desc: "required fields all set",
Herbie Ong800c9902018-12-06 15:28:53 -08001006 inputMessage: &pb2.Requireds{},
1007 inputText: `
1008req_bool: false
Herbie Ong800c9902018-12-06 15:28:53 -08001009req_sfixed64: 0
Herbie Ong800c9902018-12-06 15:28:53 -08001010req_double: 0
1011req_string: ""
Herbie Ong8170d692019-02-13 14:13:21 -08001012req_enum: ONE
Herbie Ong800c9902018-12-06 15:28:53 -08001013req_nested: {}
1014`,
1015 wantMessage: &pb2.Requireds{
Damien Neila8a2cea2019-07-10 16:17:16 -07001016 ReqBool: proto.Bool(false),
1017 ReqSfixed64: proto.Int64(0),
1018 ReqDouble: proto.Float64(0),
1019 ReqString: proto.String(""),
Herbie Ong8170d692019-02-13 14:13:21 -08001020 ReqEnum: pb2.Enum_ONE.Enum(),
Herbie Ong800c9902018-12-06 15:28:53 -08001021 ReqNested: &pb2.Nested{},
1022 },
1023 }, {
1024 desc: "indirect required field",
1025 inputMessage: &pb2.IndirectRequired{},
1026 inputText: "opt_nested: {}",
1027 wantMessage: &pb2.IndirectRequired{
1028 OptNested: &pb2.NestedWithRequired{},
1029 },
1030 wantErr: true,
1031 }, {
Herbie Ong42577ea2019-03-26 16:26:22 -07001032 desc: "indirect required field with AllowPartial",
Damien Neil5c5b5312019-05-14 12:44:37 -07001033 umo: prototext.UnmarshalOptions{AllowPartial: true},
Herbie Ong42577ea2019-03-26 16:26:22 -07001034 inputMessage: &pb2.IndirectRequired{},
1035 inputText: "opt_nested: {}",
1036 wantMessage: &pb2.IndirectRequired{
1037 OptNested: &pb2.NestedWithRequired{},
1038 },
1039 }, {
Herbie Ong800c9902018-12-06 15:28:53 -08001040 desc: "indirect required field in repeated",
1041 inputMessage: &pb2.IndirectRequired{},
1042 inputText: `
1043rpt_nested: {
1044 req_string: "one"
1045}
1046rpt_nested: {}
Herbie Ong800c9902018-12-06 15:28:53 -08001047`,
1048 wantMessage: &pb2.IndirectRequired{
1049 RptNested: []*pb2.NestedWithRequired{
1050 {
Damien Neila8a2cea2019-07-10 16:17:16 -07001051 ReqString: proto.String("one"),
Herbie Ong800c9902018-12-06 15:28:53 -08001052 },
1053 {},
Herbie Ong800c9902018-12-06 15:28:53 -08001054 },
1055 },
1056 wantErr: true,
1057 }, {
Herbie Ong42577ea2019-03-26 16:26:22 -07001058 desc: "indirect required field in repeated with AllowPartial",
Damien Neil5c5b5312019-05-14 12:44:37 -07001059 umo: prototext.UnmarshalOptions{AllowPartial: true},
Herbie Ong42577ea2019-03-26 16:26:22 -07001060 inputMessage: &pb2.IndirectRequired{},
1061 inputText: `
1062rpt_nested: {
1063 req_string: "one"
1064}
1065rpt_nested: {}
1066`,
1067 wantMessage: &pb2.IndirectRequired{
1068 RptNested: []*pb2.NestedWithRequired{
1069 {
Damien Neila8a2cea2019-07-10 16:17:16 -07001070 ReqString: proto.String("one"),
Herbie Ong42577ea2019-03-26 16:26:22 -07001071 },
1072 {},
1073 },
1074 },
1075 }, {
Herbie Ong800c9902018-12-06 15:28:53 -08001076 desc: "indirect required field in map",
1077 inputMessage: &pb2.IndirectRequired{},
1078 inputText: `
1079str_to_nested: {
1080 key: "missing"
1081}
1082str_to_nested: {
1083 key: "contains"
1084 value: {
1085 req_string: "here"
1086 }
1087}
1088`,
1089 wantMessage: &pb2.IndirectRequired{
1090 StrToNested: map[string]*pb2.NestedWithRequired{
1091 "missing": &pb2.NestedWithRequired{},
1092 "contains": &pb2.NestedWithRequired{
Damien Neila8a2cea2019-07-10 16:17:16 -07001093 ReqString: proto.String("here"),
Herbie Ong800c9902018-12-06 15:28:53 -08001094 },
1095 },
1096 },
1097 wantErr: true,
Herbie Ong7c624e22018-12-13 14:41:22 -08001098 }, {
Herbie Ong42577ea2019-03-26 16:26:22 -07001099 desc: "indirect required field in map with AllowPartial",
Damien Neil5c5b5312019-05-14 12:44:37 -07001100 umo: prototext.UnmarshalOptions{AllowPartial: true},
Herbie Ong42577ea2019-03-26 16:26:22 -07001101 inputMessage: &pb2.IndirectRequired{},
1102 inputText: `
1103str_to_nested: {
1104 key: "missing"
1105}
1106str_to_nested: {
1107 key: "contains"
1108 value: {
1109 req_string: "here"
1110 }
1111}
1112`,
1113 wantMessage: &pb2.IndirectRequired{
1114 StrToNested: map[string]*pb2.NestedWithRequired{
1115 "missing": &pb2.NestedWithRequired{},
1116 "contains": &pb2.NestedWithRequired{
Damien Neila8a2cea2019-07-10 16:17:16 -07001117 ReqString: proto.String("here"),
Herbie Ong42577ea2019-03-26 16:26:22 -07001118 },
1119 },
1120 },
1121 }, {
Herbie Ong8170d692019-02-13 14:13:21 -08001122 desc: "indirect required field in oneof",
1123 inputMessage: &pb2.IndirectRequired{},
1124 inputText: `oneof_nested: {}
1125`,
1126 wantMessage: &pb2.IndirectRequired{
1127 Union: &pb2.IndirectRequired_OneofNested{
1128 OneofNested: &pb2.NestedWithRequired{},
1129 },
1130 },
1131 wantErr: true,
1132 }, {
Herbie Ong42577ea2019-03-26 16:26:22 -07001133 desc: "indirect required field in oneof with AllowPartial",
Damien Neil5c5b5312019-05-14 12:44:37 -07001134 umo: prototext.UnmarshalOptions{AllowPartial: true},
Herbie Ong42577ea2019-03-26 16:26:22 -07001135 inputMessage: &pb2.IndirectRequired{},
1136 inputText: `oneof_nested: {}
1137`,
1138 wantMessage: &pb2.IndirectRequired{
1139 Union: &pb2.IndirectRequired_OneofNested{
1140 OneofNested: &pb2.NestedWithRequired{},
1141 },
1142 },
1143 }, {
Herbie Ong7c624e22018-12-13 14:41:22 -08001144 desc: "ignore reserved field",
1145 inputMessage: &pb2.Nests{},
1146 inputText: "reserved_field: 'ignore this'",
1147 wantMessage: &pb2.Nests{},
Herbie Ongc525c972018-12-18 18:04:31 -08001148 }, {
1149 desc: "extensions of non-repeated fields",
1150 inputMessage: &pb2.Extensions{},
1151 inputText: `opt_string: "non-extension field"
1152[pb2.opt_ext_bool]: true
1153opt_bool: true
1154[pb2.opt_ext_nested]: {
1155 opt_string: "nested in an extension"
1156 opt_nested: {
1157 opt_string: "another nested in an extension"
1158 }
1159}
1160[pb2.opt_ext_string]: "extension field"
1161opt_int32: 42
Herbie Ong8170d692019-02-13 14:13:21 -08001162[pb2.opt_ext_enum]: TEN
Herbie Ongc525c972018-12-18 18:04:31 -08001163`,
1164 wantMessage: func() proto.Message {
1165 m := &pb2.Extensions{
Damien Neila8a2cea2019-07-10 16:17:16 -07001166 OptString: proto.String("non-extension field"),
1167 OptBool: proto.Bool(true),
1168 OptInt32: proto.Int32(42),
Herbie Ongc525c972018-12-18 18:04:31 -08001169 }
1170 setExtension(m, pb2.E_OptExtBool, true)
1171 setExtension(m, pb2.E_OptExtString, "extension field")
Herbie Ong8170d692019-02-13 14:13:21 -08001172 setExtension(m, pb2.E_OptExtEnum, pb2.Enum_TEN)
Herbie Ongc525c972018-12-18 18:04:31 -08001173 setExtension(m, pb2.E_OptExtNested, &pb2.Nested{
Damien Neila8a2cea2019-07-10 16:17:16 -07001174 OptString: proto.String("nested in an extension"),
Herbie Ongc525c972018-12-18 18:04:31 -08001175 OptNested: &pb2.Nested{
Damien Neila8a2cea2019-07-10 16:17:16 -07001176 OptString: proto.String("another nested in an extension"),
Herbie Ongc525c972018-12-18 18:04:31 -08001177 },
1178 })
1179 return m
1180 }(),
1181 }, {
Herbie Ong21a39742019-04-08 17:32:44 -07001182 desc: "extension field contains invalid UTF-8",
1183 inputMessage: &pb2.Extensions{},
1184 inputText: `[pb2.opt_ext_string]: "abc\xff"`,
Damien Neil8c86fc52019-06-19 09:28:29 -07001185 wantErr: true,
Herbie Ong21a39742019-04-08 17:32:44 -07001186 }, {
Herbie Ongc525c972018-12-18 18:04:31 -08001187 desc: "extensions of repeated fields",
1188 inputMessage: &pb2.Extensions{},
Herbie Ong8170d692019-02-13 14:13:21 -08001189 inputText: `[pb2.rpt_ext_enum]: TEN
Herbie Ongc525c972018-12-18 18:04:31 -08001190[pb2.rpt_ext_enum]: 101
1191[pb2.rpt_ext_fixed32]: 42
Herbie Ong8170d692019-02-13 14:13:21 -08001192[pb2.rpt_ext_enum]: ONE
Herbie Ongc525c972018-12-18 18:04:31 -08001193[pb2.rpt_ext_nested]: {
1194 opt_string: "one"
1195}
1196[pb2.rpt_ext_nested]: {
1197 opt_string: "two"
1198}
1199[pb2.rpt_ext_fixed32]: 47
1200[pb2.rpt_ext_nested]: {
1201 opt_string: "three"
1202}
1203`,
1204 wantMessage: func() proto.Message {
1205 m := &pb2.Extensions{}
Herbie Ong8170d692019-02-13 14:13:21 -08001206 setExtension(m, pb2.E_RptExtEnum, &[]pb2.Enum{pb2.Enum_TEN, 101, pb2.Enum_ONE})
Herbie Ongc525c972018-12-18 18:04:31 -08001207 setExtension(m, pb2.E_RptExtFixed32, &[]uint32{42, 47})
1208 setExtension(m, pb2.E_RptExtNested, &[]*pb2.Nested{
Damien Neila8a2cea2019-07-10 16:17:16 -07001209 &pb2.Nested{OptString: proto.String("one")},
1210 &pb2.Nested{OptString: proto.String("two")},
1211 &pb2.Nested{OptString: proto.String("three")},
Herbie Ongc525c972018-12-18 18:04:31 -08001212 })
1213 return m
1214 }(),
1215 }, {
1216 desc: "extensions of non-repeated fields in another message",
1217 inputMessage: &pb2.Extensions{},
1218 inputText: `[pb2.ExtensionsContainer.opt_ext_bool]: true
Herbie Ong8170d692019-02-13 14:13:21 -08001219[pb2.ExtensionsContainer.opt_ext_enum]: TEN
Herbie Ongc525c972018-12-18 18:04:31 -08001220[pb2.ExtensionsContainer.opt_ext_nested]: {
1221 opt_string: "nested in an extension"
1222 opt_nested: {
1223 opt_string: "another nested in an extension"
1224 }
1225}
1226[pb2.ExtensionsContainer.opt_ext_string]: "extension field"
1227`,
1228 wantMessage: func() proto.Message {
1229 m := &pb2.Extensions{}
1230 setExtension(m, pb2.E_ExtensionsContainer_OptExtBool, true)
1231 setExtension(m, pb2.E_ExtensionsContainer_OptExtString, "extension field")
Herbie Ong8170d692019-02-13 14:13:21 -08001232 setExtension(m, pb2.E_ExtensionsContainer_OptExtEnum, pb2.Enum_TEN)
Herbie Ongc525c972018-12-18 18:04:31 -08001233 setExtension(m, pb2.E_ExtensionsContainer_OptExtNested, &pb2.Nested{
Damien Neila8a2cea2019-07-10 16:17:16 -07001234 OptString: proto.String("nested in an extension"),
Herbie Ongc525c972018-12-18 18:04:31 -08001235 OptNested: &pb2.Nested{
Damien Neila8a2cea2019-07-10 16:17:16 -07001236 OptString: proto.String("another nested in an extension"),
Herbie Ongc525c972018-12-18 18:04:31 -08001237 },
1238 })
1239 return m
1240 }(),
1241 }, {
1242 desc: "extensions of repeated fields in another message",
1243 inputMessage: &pb2.Extensions{},
1244 inputText: `opt_string: "non-extension field"
1245opt_bool: true
1246opt_int32: 42
1247[pb2.ExtensionsContainer.rpt_ext_nested]: {
1248 opt_string: "one"
1249}
Herbie Ong8170d692019-02-13 14:13:21 -08001250[pb2.ExtensionsContainer.rpt_ext_enum]: TEN
Herbie Ongc525c972018-12-18 18:04:31 -08001251[pb2.ExtensionsContainer.rpt_ext_nested]: {
1252 opt_string: "two"
1253}
1254[pb2.ExtensionsContainer.rpt_ext_enum]: 101
1255[pb2.ExtensionsContainer.rpt_ext_string]: "hello"
Herbie Ong8170d692019-02-13 14:13:21 -08001256[pb2.ExtensionsContainer.rpt_ext_enum]: ONE
Herbie Ongc525c972018-12-18 18:04:31 -08001257[pb2.ExtensionsContainer.rpt_ext_nested]: {
1258 opt_string: "three"
1259}
1260[pb2.ExtensionsContainer.rpt_ext_string]: "world"
1261`,
1262 wantMessage: func() proto.Message {
1263 m := &pb2.Extensions{
Damien Neila8a2cea2019-07-10 16:17:16 -07001264 OptString: proto.String("non-extension field"),
1265 OptBool: proto.Bool(true),
1266 OptInt32: proto.Int32(42),
Herbie Ongc525c972018-12-18 18:04:31 -08001267 }
Herbie Ong8170d692019-02-13 14:13:21 -08001268 setExtension(m, pb2.E_ExtensionsContainer_RptExtEnum, &[]pb2.Enum{pb2.Enum_TEN, 101, pb2.Enum_ONE})
Herbie Ongc525c972018-12-18 18:04:31 -08001269 setExtension(m, pb2.E_ExtensionsContainer_RptExtString, &[]string{"hello", "world"})
1270 setExtension(m, pb2.E_ExtensionsContainer_RptExtNested, &[]*pb2.Nested{
Damien Neila8a2cea2019-07-10 16:17:16 -07001271 &pb2.Nested{OptString: proto.String("one")},
1272 &pb2.Nested{OptString: proto.String("two")},
1273 &pb2.Nested{OptString: proto.String("three")},
Herbie Ongc525c972018-12-18 18:04:31 -08001274 })
1275 return m
1276 }(),
1277 }, {
1278 desc: "invalid extension field name",
1279 inputMessage: &pb2.Extensions{},
1280 inputText: "[pb2.invalid_message_field]: true",
1281 wantErr: true,
Herbie Ong66c365c2019-01-04 14:08:41 -08001282 }, {
Herbie Ong6470ea62019-01-07 18:56:57 -08001283 desc: "MessageSet",
1284 inputMessage: &pb2.MessageSet{},
1285 inputText: `
1286[pb2.MessageSetExtension]: {
1287 opt_string: "a messageset extension"
1288}
1289[pb2.MessageSetExtension.ext_nested]: {
1290 opt_string: "just a regular extension"
1291}
1292[pb2.MessageSetExtension.not_message_set_extension]: {
1293 opt_string: "not a messageset extension"
1294}
1295`,
1296 wantMessage: func() proto.Message {
1297 m := &pb2.MessageSet{}
1298 setExtension(m, pb2.E_MessageSetExtension_MessageSetExtension, &pb2.MessageSetExtension{
Damien Neila8a2cea2019-07-10 16:17:16 -07001299 OptString: proto.String("a messageset extension"),
Herbie Ong6470ea62019-01-07 18:56:57 -08001300 })
1301 setExtension(m, pb2.E_MessageSetExtension_NotMessageSetExtension, &pb2.MessageSetExtension{
Damien Neila8a2cea2019-07-10 16:17:16 -07001302 OptString: proto.String("not a messageset extension"),
Herbie Ong6470ea62019-01-07 18:56:57 -08001303 })
1304 setExtension(m, pb2.E_MessageSetExtension_ExtNested, &pb2.Nested{
Damien Neila8a2cea2019-07-10 16:17:16 -07001305 OptString: proto.String("just a regular extension"),
Herbie Ong6470ea62019-01-07 18:56:57 -08001306 })
1307 return m
1308 }(),
1309 }, {
1310 desc: "not real MessageSet 1",
1311 inputMessage: &pb2.FakeMessageSet{},
1312 inputText: `
1313[pb2.FakeMessageSetExtension.message_set_extension]: {
1314 opt_string: "not a messageset extension"
1315}
1316`,
1317 wantMessage: func() proto.Message {
1318 m := &pb2.FakeMessageSet{}
1319 setExtension(m, pb2.E_FakeMessageSetExtension_MessageSetExtension, &pb2.FakeMessageSetExtension{
Damien Neila8a2cea2019-07-10 16:17:16 -07001320 OptString: proto.String("not a messageset extension"),
Herbie Ong6470ea62019-01-07 18:56:57 -08001321 })
1322 return m
1323 }(),
1324 }, {
1325 desc: "not real MessageSet 2",
1326 inputMessage: &pb2.FakeMessageSet{},
1327 inputText: `
1328[pb2.FakeMessageSetExtension]: {
1329 opt_string: "not a messageset extension"
1330}
1331`,
1332 wantErr: true,
1333 }, {
1334 desc: "not real MessageSet 3",
1335 inputMessage: &pb2.MessageSet{},
1336 inputText: `
1337[pb2.message_set_extension]: {
1338 opt_string: "another not a messageset extension"
Herbie Ong300cff02019-03-20 18:05:16 -07001339}`,
Herbie Ong6470ea62019-01-07 18:56:57 -08001340 wantMessage: func() proto.Message {
1341 m := &pb2.MessageSet{}
1342 setExtension(m, pb2.E_MessageSetExtension, &pb2.FakeMessageSetExtension{
Damien Neila8a2cea2019-07-10 16:17:16 -07001343 OptString: proto.String("another not a messageset extension"),
Herbie Ong6470ea62019-01-07 18:56:57 -08001344 })
1345 return m
1346 }(),
1347 }, {
Herbie Ong66c365c2019-01-04 14:08:41 -08001348 desc: "Any not expanded",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001349 inputMessage: &anypb.Any{},
Herbie Ong300cff02019-03-20 18:05:16 -07001350 inputText: `
Herbie Ong66c365c2019-01-04 14:08:41 -08001351type_url: "pb2.Nested"
1352value: "some bytes"
Herbie Ong66c365c2019-01-04 14:08:41 -08001353`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001354 wantMessage: &anypb.Any{
Herbie Ong300cff02019-03-20 18:05:16 -07001355 TypeUrl: "pb2.Nested",
1356 Value: []byte("some bytes"),
Herbie Ong66c365c2019-01-04 14:08:41 -08001357 },
1358 }, {
1359 desc: "Any not expanded missing value",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001360 inputMessage: &anypb.Any{},
Herbie Ong300cff02019-03-20 18:05:16 -07001361 inputText: `type_url: "pb2.Nested"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001362 wantMessage: &anypb.Any{
Herbie Ong300cff02019-03-20 18:05:16 -07001363 TypeUrl: "pb2.Nested",
Herbie Ong66c365c2019-01-04 14:08:41 -08001364 },
1365 }, {
1366 desc: "Any not expanded missing type_url",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001367 inputMessage: &anypb.Any{},
Herbie Ong300cff02019-03-20 18:05:16 -07001368 inputText: `value: "some bytes"`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001369 wantMessage: &anypb.Any{
Herbie Ong300cff02019-03-20 18:05:16 -07001370 Value: []byte("some bytes"),
Herbie Ong66c365c2019-01-04 14:08:41 -08001371 },
1372 }, {
1373 desc: "Any expanded",
Damien Neil5c5b5312019-05-14 12:44:37 -07001374 umo: prototext.UnmarshalOptions{
Joe Tsai0fc49f82019-05-01 12:29:25 -07001375 Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&pb2.Nested{})),
Herbie Ong300cff02019-03-20 18:05:16 -07001376 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07001377 inputMessage: &anypb.Any{},
Herbie Ong300cff02019-03-20 18:05:16 -07001378 inputText: `
1379[foobar/pb2.Nested]: {
1380 opt_string: "embedded inside Any"
1381 opt_nested: {
1382 opt_string: "inception"
Herbie Ong66c365c2019-01-04 14:08:41 -08001383 }
1384}
1385`,
1386 wantMessage: func() proto.Message {
1387 m := &pb2.Nested{
Damien Neila8a2cea2019-07-10 16:17:16 -07001388 OptString: proto.String("embedded inside Any"),
Herbie Ong66c365c2019-01-04 14:08:41 -08001389 OptNested: &pb2.Nested{
Damien Neila8a2cea2019-07-10 16:17:16 -07001390 OptString: proto.String("inception"),
Herbie Ong66c365c2019-01-04 14:08:41 -08001391 },
1392 }
Herbie Onge0cf15b2019-03-15 19:32:38 -07001393 b, err := proto.MarshalOptions{Deterministic: true}.Marshal(m)
Herbie Ong66c365c2019-01-04 14:08:41 -08001394 if err != nil {
1395 t.Fatalf("error in binary marshaling message for Any.value: %v", err)
1396 }
Joe Tsaia95b29f2019-05-16 12:47:20 -07001397 return &anypb.Any{
Herbie Ong300cff02019-03-20 18:05:16 -07001398 TypeUrl: "foobar/pb2.Nested",
1399 Value: b,
Herbie Ong66c365c2019-01-04 14:08:41 -08001400 }
1401 }(),
1402 }, {
1403 desc: "Any expanded with empty value",
Damien Neil5c5b5312019-05-14 12:44:37 -07001404 umo: prototext.UnmarshalOptions{
Joe Tsai0fc49f82019-05-01 12:29:25 -07001405 Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&pb2.Nested{})),
Herbie Ong300cff02019-03-20 18:05:16 -07001406 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07001407 inputMessage: &anypb.Any{},
Herbie Ong300cff02019-03-20 18:05:16 -07001408 inputText: `[foo.com/pb2.Nested]: {}`,
Joe Tsaia95b29f2019-05-16 12:47:20 -07001409 wantMessage: &anypb.Any{
Herbie Ong300cff02019-03-20 18:05:16 -07001410 TypeUrl: "foo.com/pb2.Nested",
Herbie Ong66c365c2019-01-04 14:08:41 -08001411 },
1412 }, {
Damien Neil0c9f0a92019-06-19 10:41:09 -07001413 desc: "Any expanded with missing required",
Damien Neil5c5b5312019-05-14 12:44:37 -07001414 umo: prototext.UnmarshalOptions{
Joe Tsai0fc49f82019-05-01 12:29:25 -07001415 Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&pb2.PartialRequired{})),
Herbie Ong300cff02019-03-20 18:05:16 -07001416 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07001417 inputMessage: &anypb.Any{},
Herbie Ong300cff02019-03-20 18:05:16 -07001418 inputText: `
1419[pb2.PartialRequired]: {
1420 opt_string: "embedded inside Any"
Herbie Ong66c365c2019-01-04 14:08:41 -08001421}
1422`,
1423 wantMessage: func() proto.Message {
1424 m := &pb2.PartialRequired{
Damien Neila8a2cea2019-07-10 16:17:16 -07001425 OptString: proto.String("embedded inside Any"),
Herbie Ong66c365c2019-01-04 14:08:41 -08001426 }
Damien Neil96c229a2019-04-03 12:17:24 -07001427 b, err := proto.MarshalOptions{
1428 AllowPartial: true,
1429 Deterministic: true,
1430 }.Marshal(m)
Herbie Ong300cff02019-03-20 18:05:16 -07001431 if err != nil {
Herbie Ong66c365c2019-01-04 14:08:41 -08001432 t.Fatalf("error in binary marshaling message for Any.value: %v", err)
1433 }
Joe Tsaia95b29f2019-05-16 12:47:20 -07001434 return &anypb.Any{
Herbie Ong300cff02019-03-20 18:05:16 -07001435 TypeUrl: "pb2.PartialRequired",
1436 Value: b,
Herbie Ong66c365c2019-01-04 14:08:41 -08001437 }
1438 }(),
Herbie Ong66c365c2019-01-04 14:08:41 -08001439 }, {
Herbie Ong21a39742019-04-08 17:32:44 -07001440 desc: "Any with invalid UTF-8",
Damien Neil5c5b5312019-05-14 12:44:37 -07001441 umo: prototext.UnmarshalOptions{
Joe Tsai0fc49f82019-05-01 12:29:25 -07001442 Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&pb3.Nested{})),
Herbie Ong21a39742019-04-08 17:32:44 -07001443 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07001444 inputMessage: &anypb.Any{},
Herbie Ong21a39742019-04-08 17:32:44 -07001445 inputText: `
1446[pb3.Nested]: {
1447 s_string: "abc\xff"
1448}
1449`,
Herbie Ong21a39742019-04-08 17:32:44 -07001450 wantErr: true,
1451 }, {
Herbie Ong66c365c2019-01-04 14:08:41 -08001452 desc: "Any expanded with unregistered type",
Damien Neil5c5b5312019-05-14 12:44:37 -07001453 umo: prototext.UnmarshalOptions{Resolver: preg.NewTypes()},
Joe Tsaia95b29f2019-05-16 12:47:20 -07001454 inputMessage: &anypb.Any{},
Herbie Ong300cff02019-03-20 18:05:16 -07001455 inputText: `[SomeMessage]: {}`,
1456 wantErr: true,
Herbie Ong66c365c2019-01-04 14:08:41 -08001457 }, {
1458 desc: "Any expanded with invalid value",
Damien Neil5c5b5312019-05-14 12:44:37 -07001459 umo: prototext.UnmarshalOptions{
Joe Tsai0fc49f82019-05-01 12:29:25 -07001460 Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&pb2.Nested{})),
Herbie Ong300cff02019-03-20 18:05:16 -07001461 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07001462 inputMessage: &anypb.Any{},
Herbie Ong300cff02019-03-20 18:05:16 -07001463 inputText: `[pb2.Nested]: 123`,
1464 wantErr: true,
Herbie Ong66c365c2019-01-04 14:08:41 -08001465 }, {
1466 desc: "Any expanded with unknown fields",
Damien Neil5c5b5312019-05-14 12:44:37 -07001467 umo: prototext.UnmarshalOptions{
Joe Tsai0fc49f82019-05-01 12:29:25 -07001468 Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&pb2.Nested{})),
Herbie Ong300cff02019-03-20 18:05:16 -07001469 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07001470 inputMessage: &anypb.Any{},
Herbie Ong300cff02019-03-20 18:05:16 -07001471 inputText: `
Herbie Ong66c365c2019-01-04 14:08:41 -08001472[pb2.Nested]: {}
1473unknown: ""
Herbie Ong66c365c2019-01-04 14:08:41 -08001474`,
1475 wantErr: true,
1476 }, {
1477 desc: "Any contains expanded and unexpanded fields",
Damien Neil5c5b5312019-05-14 12:44:37 -07001478 umo: prototext.UnmarshalOptions{
Joe Tsai0fc49f82019-05-01 12:29:25 -07001479 Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&pb2.Nested{})),
Herbie Ong300cff02019-03-20 18:05:16 -07001480 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07001481 inputMessage: &anypb.Any{},
Herbie Ong300cff02019-03-20 18:05:16 -07001482 inputText: `
Herbie Ong66c365c2019-01-04 14:08:41 -08001483[pb2.Nested]: {}
1484type_url: "pb2.Nested"
Herbie Ong66c365c2019-01-04 14:08:41 -08001485`,
1486 wantErr: true,
Herbie Ong800c9902018-12-06 15:28:53 -08001487 }}
1488
1489 for _, tt := range tests {
1490 tt := tt
1491 t.Run(tt.desc, func(t *testing.T) {
Joe Tsaicdb77732019-05-14 16:05:06 -07001492 err := tt.umo.Unmarshal([]byte(tt.inputText), tt.inputMessage)
Herbie Ong800c9902018-12-06 15:28:53 -08001493 if err != nil && !tt.wantErr {
1494 t.Errorf("Unmarshal() returned error: %v\n\n", err)
1495 }
1496 if err == nil && tt.wantErr {
1497 t.Error("Unmarshal() got nil error, want error\n\n")
1498 }
Joe Tsai8d30bbe2019-05-16 15:53:25 -07001499 if tt.wantMessage != nil && !proto.Equal(tt.inputMessage, tt.wantMessage) {
Herbie Ong800c9902018-12-06 15:28:53 -08001500 t.Errorf("Unmarshal()\n<got>\n%v\n<want>\n%v\n", tt.inputMessage, tt.wantMessage)
1501 }
1502 })
1503 }
1504}