blob: 493a229611873866605aa9114fe59becb5f7a289 [file] [log] [blame]
Herbie Ongcddf8192018-11-28 18:25:20 -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 Ongcddf8192018-11-28 18:25:20 -08006
7import (
8 "math"
Herbie Ongcddf8192018-11-28 18:25:20 -08009 "testing"
10
Herbie Ongcddf8192018-11-28 18:25:20 -080011 "github.com/google/go-cmp/cmp"
Damien Neil5c5b5312019-05-14 12:44:37 -070012 "google.golang.org/protobuf/encoding/prototext"
Damien Neile89e6242019-05-13 23:55:40 -070013 "google.golang.org/protobuf/internal/detrand"
14 "google.golang.org/protobuf/internal/encoding/pack"
Joe Tsai5ae10aa2019-07-11 18:23:08 -070015 "google.golang.org/protobuf/internal/flags"
Damien Neile89e6242019-05-13 23:55:40 -070016 pimpl "google.golang.org/protobuf/internal/impl"
Damien Neile89e6242019-05-13 23:55:40 -070017 "google.golang.org/protobuf/proto"
18 preg "google.golang.org/protobuf/reflect/protoregistry"
Herbie Ongcddf8192018-11-28 18:25:20 -080019
Damien Neile89e6242019-05-13 23:55:40 -070020 "google.golang.org/protobuf/encoding/testprotos/pb2"
21 "google.golang.org/protobuf/encoding/testprotos/pb3"
Joe Tsaia95b29f2019-05-16 12:47:20 -070022 "google.golang.org/protobuf/types/known/anypb"
Herbie Ongcddf8192018-11-28 18:25:20 -080023)
24
25func init() {
26 // Disable detrand to enable direct comparisons on outputs.
27 detrand.Disable()
28}
29
Herbie Ongcddf8192018-11-28 18:25:20 -080030func TestMarshal(t *testing.T) {
31 tests := []struct {
32 desc string
Damien Neil5c5b5312019-05-14 12:44:37 -070033 mo prototext.MarshalOptions
Herbie Ong70651952018-12-13 14:19:50 -080034 input proto.Message
Herbie Ongcddf8192018-11-28 18:25:20 -080035 want string
Herbie Ong300cff02019-03-20 18:05:16 -070036 wantErr bool // TODO: Verify error message content.
Joe Tsai5ae10aa2019-07-11 18:23:08 -070037 skip bool
Herbie Ongcddf8192018-11-28 18:25:20 -080038 }{{
Herbie Ong8170d692019-02-13 14:13:21 -080039 desc: "proto2 optional scalars not set",
Herbie Ong800c9902018-12-06 15:28:53 -080040 input: &pb2.Scalars{},
Herbie Ongcddf8192018-11-28 18:25:20 -080041 want: "\n",
42 }, {
Herbie Ong8170d692019-02-13 14:13:21 -080043 desc: "proto3 scalars not set",
Herbie Ong800c9902018-12-06 15:28:53 -080044 input: &pb3.Scalars{},
Herbie Ongcddf8192018-11-28 18:25:20 -080045 want: "\n",
46 }, {
Herbie Ong8170d692019-02-13 14:13:21 -080047 desc: "proto2 optional scalars set to zero values",
Herbie Ong800c9902018-12-06 15:28:53 -080048 input: &pb2.Scalars{
Damien Neila8a2cea2019-07-10 16:17:16 -070049 OptBool: proto.Bool(false),
50 OptInt32: proto.Int32(0),
51 OptInt64: proto.Int64(0),
52 OptUint32: proto.Uint32(0),
53 OptUint64: proto.Uint64(0),
54 OptSint32: proto.Int32(0),
55 OptSint64: proto.Int64(0),
56 OptFixed32: proto.Uint32(0),
57 OptFixed64: proto.Uint64(0),
58 OptSfixed32: proto.Int32(0),
59 OptSfixed64: proto.Int64(0),
60 OptFloat: proto.Float32(0),
61 OptDouble: proto.Float64(0),
Herbie Ongcddf8192018-11-28 18:25:20 -080062 OptBytes: []byte{},
Damien Neila8a2cea2019-07-10 16:17:16 -070063 OptString: proto.String(""),
Herbie Ong800c9902018-12-06 15:28:53 -080064 },
Herbie Ongcddf8192018-11-28 18:25:20 -080065 want: `opt_bool: false
66opt_int32: 0
67opt_int64: 0
68opt_uint32: 0
69opt_uint64: 0
70opt_sint32: 0
71opt_sint64: 0
72opt_fixed32: 0
73opt_fixed64: 0
74opt_sfixed32: 0
75opt_sfixed64: 0
76opt_float: 0
77opt_double: 0
78opt_bytes: ""
79opt_string: ""
80`,
81 }, {
Herbie Ong8170d692019-02-13 14:13:21 -080082 desc: "proto3 scalars set to zero values",
Herbie Ong800c9902018-12-06 15:28:53 -080083 input: &pb3.Scalars{
Herbie Ongcddf8192018-11-28 18:25:20 -080084 SBool: false,
85 SInt32: 0,
86 SInt64: 0,
87 SUint32: 0,
88 SUint64: 0,
89 SSint32: 0,
90 SSint64: 0,
91 SFixed32: 0,
92 SFixed64: 0,
93 SSfixed32: 0,
94 SSfixed64: 0,
95 SFloat: 0,
96 SDouble: 0,
97 SBytes: []byte{},
98 SString: "",
Herbie Ong800c9902018-12-06 15:28:53 -080099 },
Herbie Ongcddf8192018-11-28 18:25:20 -0800100 want: "\n",
101 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800102 desc: "proto2 optional scalars set to some values",
Herbie Ong800c9902018-12-06 15:28:53 -0800103 input: &pb2.Scalars{
Damien Neila8a2cea2019-07-10 16:17:16 -0700104 OptBool: proto.Bool(true),
105 OptInt32: proto.Int32(0xff),
106 OptInt64: proto.Int64(0xdeadbeef),
107 OptUint32: proto.Uint32(47),
108 OptUint64: proto.Uint64(0xdeadbeef),
109 OptSint32: proto.Int32(-1001),
110 OptSint64: proto.Int64(-0xffff),
111 OptFixed64: proto.Uint64(64),
112 OptSfixed32: proto.Int32(-32),
113 OptFloat: proto.Float32(1.02),
114 OptDouble: proto.Float64(1.0199999809265137),
Herbie Ong8170d692019-02-13 14:13:21 -0800115 OptBytes: []byte("\xe8\xb0\xb7\xe6\xad\x8c"),
Damien Neila8a2cea2019-07-10 16:17:16 -0700116 OptString: proto.String("谷歌"),
Herbie Ong800c9902018-12-06 15:28:53 -0800117 },
Herbie Ongcddf8192018-11-28 18:25:20 -0800118 want: `opt_bool: true
119opt_int32: 255
120opt_int64: 3735928559
121opt_uint32: 47
122opt_uint64: 3735928559
123opt_sint32: -1001
124opt_sint64: -65535
125opt_fixed64: 64
126opt_sfixed32: -32
Herbie Ong84f09602019-01-17 19:31:47 -0800127opt_float: 1.02
128opt_double: 1.0199999809265137
Herbie Ongcddf8192018-11-28 18:25:20 -0800129opt_bytes: "谷歌"
130opt_string: "谷歌"
131`,
132 }, {
Herbie Ong21a39742019-04-08 17:32:44 -0700133 desc: "string with invalid UTF-8",
134 input: &pb3.Scalars{
135 SString: "abc\xff",
136 },
Herbie Ong21a39742019-04-08 17:32:44 -0700137 wantErr: true,
138 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800139 desc: "float nan",
Herbie Ong800c9902018-12-06 15:28:53 -0800140 input: &pb3.Scalars{
Herbie Ongcddf8192018-11-28 18:25:20 -0800141 SFloat: float32(math.NaN()),
Herbie Ong800c9902018-12-06 15:28:53 -0800142 },
Herbie Ongcddf8192018-11-28 18:25:20 -0800143 want: "s_float: nan\n",
144 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800145 desc: "float positive infinity",
Herbie Ong800c9902018-12-06 15:28:53 -0800146 input: &pb3.Scalars{
Herbie Ongcddf8192018-11-28 18:25:20 -0800147 SFloat: float32(math.Inf(1)),
Herbie Ong800c9902018-12-06 15:28:53 -0800148 },
Herbie Ongcddf8192018-11-28 18:25:20 -0800149 want: "s_float: inf\n",
150 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800151 desc: "float negative infinity",
Herbie Ong800c9902018-12-06 15:28:53 -0800152 input: &pb3.Scalars{
Herbie Ongcddf8192018-11-28 18:25:20 -0800153 SFloat: float32(math.Inf(-1)),
Herbie Ong800c9902018-12-06 15:28:53 -0800154 },
Herbie Ongcddf8192018-11-28 18:25:20 -0800155 want: "s_float: -inf\n",
156 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800157 desc: "double nan",
Herbie Ong800c9902018-12-06 15:28:53 -0800158 input: &pb3.Scalars{
Herbie Ongcddf8192018-11-28 18:25:20 -0800159 SDouble: math.NaN(),
Herbie Ong800c9902018-12-06 15:28:53 -0800160 },
Herbie Ongcddf8192018-11-28 18:25:20 -0800161 want: "s_double: nan\n",
162 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800163 desc: "double positive infinity",
Herbie Ong800c9902018-12-06 15:28:53 -0800164 input: &pb3.Scalars{
Herbie Ongcddf8192018-11-28 18:25:20 -0800165 SDouble: math.Inf(1),
Herbie Ong800c9902018-12-06 15:28:53 -0800166 },
Herbie Ongcddf8192018-11-28 18:25:20 -0800167 want: "s_double: inf\n",
168 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800169 desc: "double negative infinity",
Herbie Ong800c9902018-12-06 15:28:53 -0800170 input: &pb3.Scalars{
Herbie Ongcddf8192018-11-28 18:25:20 -0800171 SDouble: math.Inf(-1),
Herbie Ong800c9902018-12-06 15:28:53 -0800172 },
Herbie Ongcddf8192018-11-28 18:25:20 -0800173 want: "s_double: -inf\n",
174 }, {
Herbie Ong800c9902018-12-06 15:28:53 -0800175 desc: "proto2 enum not set",
176 input: &pb2.Enums{},
Herbie Ongcddf8192018-11-28 18:25:20 -0800177 want: "\n",
178 }, {
Herbie Ong800c9902018-12-06 15:28:53 -0800179 desc: "proto2 enum set to zero value",
180 input: &pb2.Enums{
Joe Tsai6dc168e2019-07-09 23:11:13 -0700181 OptEnum: pb2.Enum(0).Enum(),
182 OptNestedEnum: pb2.Enums_NestedEnum(0).Enum(),
Herbie Ong800c9902018-12-06 15:28:53 -0800183 },
Herbie Ong8170d692019-02-13 14:13:21 -0800184 want: `opt_enum: 0
Herbie Ong800c9902018-12-06 15:28:53 -0800185opt_nested_enum: 0
186`,
187 }, {
188 desc: "proto2 enum",
189 input: &pb2.Enums{
Herbie Ong8170d692019-02-13 14:13:21 -0800190 OptEnum: pb2.Enum_ONE.Enum(),
Herbie Ong800c9902018-12-06 15:28:53 -0800191 OptNestedEnum: pb2.Enums_UNO.Enum(),
192 },
Herbie Ong8170d692019-02-13 14:13:21 -0800193 want: `opt_enum: ONE
Herbie Ong800c9902018-12-06 15:28:53 -0800194opt_nested_enum: UNO
195`,
196 }, {
197 desc: "proto2 enum set to numeric values",
198 input: &pb2.Enums{
Joe Tsai6dc168e2019-07-09 23:11:13 -0700199 OptEnum: pb2.Enum(2).Enum(),
200 OptNestedEnum: pb2.Enums_NestedEnum(2).Enum(),
Herbie Ong800c9902018-12-06 15:28:53 -0800201 },
Herbie Ong8170d692019-02-13 14:13:21 -0800202 want: `opt_enum: TWO
Herbie Ong800c9902018-12-06 15:28:53 -0800203opt_nested_enum: DOS
204`,
205 }, {
206 desc: "proto2 enum set to unnamed numeric values",
207 input: &pb2.Enums{
Joe Tsai6dc168e2019-07-09 23:11:13 -0700208 OptEnum: pb2.Enum(101).Enum(),
209 OptNestedEnum: pb2.Enums_NestedEnum(-101).Enum(),
Herbie Ong800c9902018-12-06 15:28:53 -0800210 },
211 want: `opt_enum: 101
212opt_nested_enum: -101
213`,
214 }, {
215 desc: "proto3 enum not set",
216 input: &pb3.Enums{},
217 want: "\n",
218 }, {
219 desc: "proto3 enum set to zero value",
220 input: &pb3.Enums{
221 SEnum: pb3.Enum_ZERO,
222 SNestedEnum: pb3.Enums_CERO,
223 },
224 want: "\n",
225 }, {
226 desc: "proto3 enum",
227 input: &pb3.Enums{
228 SEnum: pb3.Enum_ONE,
Herbie Ong8170d692019-02-13 14:13:21 -0800229 SNestedEnum: pb3.Enums_UNO,
Herbie Ong800c9902018-12-06 15:28:53 -0800230 },
231 want: `s_enum: ONE
Herbie Ong8170d692019-02-13 14:13:21 -0800232s_nested_enum: UNO
Herbie Ong800c9902018-12-06 15:28:53 -0800233`,
234 }, {
235 desc: "proto3 enum set to numeric values",
236 input: &pb3.Enums{
237 SEnum: 2,
Herbie Ong8170d692019-02-13 14:13:21 -0800238 SNestedEnum: 2,
Herbie Ong800c9902018-12-06 15:28:53 -0800239 },
240 want: `s_enum: TWO
Herbie Ong8170d692019-02-13 14:13:21 -0800241s_nested_enum: DOS
Herbie Ong800c9902018-12-06 15:28:53 -0800242`,
243 }, {
244 desc: "proto3 enum set to unnamed numeric values",
245 input: &pb3.Enums{
246 SEnum: -47,
247 SNestedEnum: 47,
248 },
249 want: `s_enum: -47
250s_nested_enum: 47
251`,
252 }, {
253 desc: "proto2 nested message not set",
254 input: &pb2.Nests{},
255 want: "\n",
256 }, {
257 desc: "proto2 nested message set to empty",
258 input: &pb2.Nests{
259 OptNested: &pb2.Nested{},
260 Optgroup: &pb2.Nests_OptGroup{},
261 },
262 want: `opt_nested: {}
Herbie Ong0dcfb9a2019-01-14 15:32:26 -0800263OptGroup: {}
Herbie Ong800c9902018-12-06 15:28:53 -0800264`,
265 }, {
266 desc: "proto2 nested messages",
267 input: &pb2.Nests{
268 OptNested: &pb2.Nested{
Damien Neila8a2cea2019-07-10 16:17:16 -0700269 OptString: proto.String("nested message"),
Herbie Ong800c9902018-12-06 15:28:53 -0800270 OptNested: &pb2.Nested{
Damien Neila8a2cea2019-07-10 16:17:16 -0700271 OptString: proto.String("another nested message"),
Herbie Ong800c9902018-12-06 15:28:53 -0800272 },
273 },
274 },
275 want: `opt_nested: {
276 opt_string: "nested message"
277 opt_nested: {
278 opt_string: "another nested message"
279 }
280}
281`,
282 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800283 desc: "proto2 groups",
Herbie Ong800c9902018-12-06 15:28:53 -0800284 input: &pb2.Nests{
285 Optgroup: &pb2.Nests_OptGroup{
Damien Neila8a2cea2019-07-10 16:17:16 -0700286 OptString: proto.String("inside a group"),
Herbie Ong800c9902018-12-06 15:28:53 -0800287 OptNested: &pb2.Nested{
Damien Neila8a2cea2019-07-10 16:17:16 -0700288 OptString: proto.String("nested message inside a group"),
Herbie Ong800c9902018-12-06 15:28:53 -0800289 },
290 Optnestedgroup: &pb2.Nests_OptGroup_OptNestedGroup{
Damien Neila8a2cea2019-07-10 16:17:16 -0700291 OptFixed32: proto.Uint32(47),
Herbie Ong800c9902018-12-06 15:28:53 -0800292 },
293 },
294 },
Herbie Ong0dcfb9a2019-01-14 15:32:26 -0800295 want: `OptGroup: {
Herbie Ong800c9902018-12-06 15:28:53 -0800296 opt_string: "inside a group"
297 opt_nested: {
298 opt_string: "nested message inside a group"
299 }
Herbie Ong0dcfb9a2019-01-14 15:32:26 -0800300 OptNestedGroup: {
Herbie Ong8170d692019-02-13 14:13:21 -0800301 opt_fixed32: 47
Herbie Ong800c9902018-12-06 15:28:53 -0800302 }
303}
304`,
305 }, {
306 desc: "proto3 nested message not set",
307 input: &pb3.Nests{},
308 want: "\n",
309 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800310 desc: "proto3 nested message set to empty",
311 input: &pb3.Nests{
312 SNested: &pb3.Nested{},
313 },
314 want: "s_nested: {}\n",
315 }, {
Herbie Ong800c9902018-12-06 15:28:53 -0800316 desc: "proto3 nested message",
317 input: &pb3.Nests{
318 SNested: &pb3.Nested{
319 SString: "nested message",
320 SNested: &pb3.Nested{
321 SString: "another nested message",
322 },
323 },
324 },
325 want: `s_nested: {
326 s_string: "nested message"
327 s_nested: {
328 s_string: "another nested message"
329 }
330}
331`,
332 }, {
Herbie Ong21a39742019-04-08 17:32:44 -0700333 desc: "proto3 nested message contains invalid UTF-8",
334 input: &pb3.Nests{
335 SNested: &pb3.Nested{
336 SString: "abc\xff",
337 },
338 },
Herbie Ong21a39742019-04-08 17:32:44 -0700339 wantErr: true,
340 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800341 desc: "oneof not set",
342 input: &pb3.Oneofs{},
Herbie Ong800c9902018-12-06 15:28:53 -0800343 want: "\n",
344 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800345 desc: "oneof set to empty string",
346 input: &pb3.Oneofs{
347 Union: &pb3.Oneofs_OneofString{},
Herbie Ong800c9902018-12-06 15:28:53 -0800348 },
Herbie Ong8170d692019-02-13 14:13:21 -0800349 want: `oneof_string: ""
350`,
Herbie Ong800c9902018-12-06 15:28:53 -0800351 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800352 desc: "oneof set to string",
353 input: &pb3.Oneofs{
354 Union: &pb3.Oneofs_OneofString{
355 OneofString: "hello",
Herbie Ong800c9902018-12-06 15:28:53 -0800356 },
357 },
Herbie Ong8170d692019-02-13 14:13:21 -0800358 want: `oneof_string: "hello"
359`,
Herbie Ong800c9902018-12-06 15:28:53 -0800360 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800361 desc: "oneof set to enum",
362 input: &pb3.Oneofs{
363 Union: &pb3.Oneofs_OneofEnum{
364 OneofEnum: pb3.Enum_ZERO,
Herbie Ong800c9902018-12-06 15:28:53 -0800365 },
366 },
Herbie Ong8170d692019-02-13 14:13:21 -0800367 want: `oneof_enum: ZERO
368`,
Herbie Ong800c9902018-12-06 15:28:53 -0800369 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800370 desc: "oneof set to empty message",
371 input: &pb3.Oneofs{
372 Union: &pb3.Oneofs_OneofNested{
373 OneofNested: &pb3.Nested{},
374 },
375 },
376 want: "oneof_nested: {}\n",
377 }, {
378 desc: "oneof set to message",
379 input: &pb3.Oneofs{
380 Union: &pb3.Oneofs_OneofNested{
381 OneofNested: &pb3.Nested{
382 SString: "nested message",
Herbie Ong800c9902018-12-06 15:28:53 -0800383 },
384 },
385 },
Herbie Ong8170d692019-02-13 14:13:21 -0800386 want: `oneof_nested: {
387 s_string: "nested message"
Herbie Ong800c9902018-12-06 15:28:53 -0800388}
389`,
390 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800391 desc: "repeated fields not set",
Herbie Ong800c9902018-12-06 15:28:53 -0800392 input: &pb2.Repeats{},
393 want: "\n",
394 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800395 desc: "repeated fields set to empty slices",
Herbie Ong800c9902018-12-06 15:28:53 -0800396 input: &pb2.Repeats{
Herbie Ongcddf8192018-11-28 18:25:20 -0800397 RptBool: []bool{},
398 RptInt32: []int32{},
399 RptInt64: []int64{},
400 RptUint32: []uint32{},
401 RptUint64: []uint64{},
402 RptFloat: []float32{},
403 RptDouble: []float64{},
404 RptBytes: [][]byte{},
Herbie Ong800c9902018-12-06 15:28:53 -0800405 },
Herbie Ongcddf8192018-11-28 18:25:20 -0800406 want: "\n",
407 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800408 desc: "repeated fields set to some values",
Herbie Ong800c9902018-12-06 15:28:53 -0800409 input: &pb2.Repeats{
Herbie Ongcddf8192018-11-28 18:25:20 -0800410 RptBool: []bool{true, false, true, true},
411 RptInt32: []int32{1, 6, 0, 0},
412 RptInt64: []int64{-64, 47},
413 RptUint32: []uint32{0xff, 0xffff},
414 RptUint64: []uint64{0xdeadbeef},
Herbie Ong84f09602019-01-17 19:31:47 -0800415 RptFloat: []float32{float32(math.NaN()), float32(math.Inf(1)), float32(math.Inf(-1)), 1.034},
Herbie Ongcddf8192018-11-28 18:25:20 -0800416 RptDouble: []float64{math.NaN(), math.Inf(1), math.Inf(-1), 1.23e-308},
417 RptString: []string{"hello", "世界"},
418 RptBytes: [][]byte{
419 []byte("hello"),
420 []byte("\xe4\xb8\x96\xe7\x95\x8c"),
421 },
Herbie Ong800c9902018-12-06 15:28:53 -0800422 },
Herbie Ongcddf8192018-11-28 18:25:20 -0800423 want: `rpt_bool: true
424rpt_bool: false
425rpt_bool: true
426rpt_bool: true
427rpt_int32: 1
428rpt_int32: 6
429rpt_int32: 0
430rpt_int32: 0
431rpt_int64: -64
432rpt_int64: 47
433rpt_uint32: 255
434rpt_uint32: 65535
435rpt_uint64: 3735928559
Herbie Ong84f09602019-01-17 19:31:47 -0800436rpt_float: nan
437rpt_float: inf
438rpt_float: -inf
439rpt_float: 1.034
Herbie Ongcddf8192018-11-28 18:25:20 -0800440rpt_double: nan
441rpt_double: inf
442rpt_double: -inf
443rpt_double: 1.23e-308
444rpt_string: "hello"
445rpt_string: "世界"
446rpt_bytes: "hello"
447rpt_bytes: "世界"
448`,
449 }, {
Herbie Ong21a39742019-04-08 17:32:44 -0700450 desc: "repeated contains invalid UTF-8",
451 input: &pb2.Repeats{
452 RptString: []string{"abc\xff"},
453 },
Herbie Ong21a39742019-04-08 17:32:44 -0700454 wantErr: true,
455 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800456 desc: "repeated enums",
Herbie Ong800c9902018-12-06 15:28:53 -0800457 input: &pb2.Enums{
Herbie Ong8170d692019-02-13 14:13:21 -0800458 RptEnum: []pb2.Enum{pb2.Enum_ONE, 2, pb2.Enum_TEN, 42},
Herbie Ongcddf8192018-11-28 18:25:20 -0800459 RptNestedEnum: []pb2.Enums_NestedEnum{2, 47, 10},
Herbie Ong800c9902018-12-06 15:28:53 -0800460 },
Herbie Ong8170d692019-02-13 14:13:21 -0800461 want: `rpt_enum: ONE
462rpt_enum: TWO
463rpt_enum: TEN
Herbie Ongcddf8192018-11-28 18:25:20 -0800464rpt_enum: 42
Herbie Ongcddf8192018-11-28 18:25:20 -0800465rpt_nested_enum: DOS
466rpt_nested_enum: 47
467rpt_nested_enum: DIEZ
468`,
469 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800470 desc: "repeated messages set to empty",
Herbie Ong800c9902018-12-06 15:28:53 -0800471 input: &pb2.Nests{
Herbie Ongcddf8192018-11-28 18:25:20 -0800472 RptNested: []*pb2.Nested{},
473 Rptgroup: []*pb2.Nests_RptGroup{},
Herbie Ong800c9902018-12-06 15:28:53 -0800474 },
475 want: "\n",
Herbie Ongcddf8192018-11-28 18:25:20 -0800476 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800477 desc: "repeated messages",
Herbie Ong800c9902018-12-06 15:28:53 -0800478 input: &pb2.Nests{
Herbie Ongcddf8192018-11-28 18:25:20 -0800479 RptNested: []*pb2.Nested{
480 {
Damien Neila8a2cea2019-07-10 16:17:16 -0700481 OptString: proto.String("repeat nested one"),
Herbie Ongcddf8192018-11-28 18:25:20 -0800482 },
483 {
Damien Neila8a2cea2019-07-10 16:17:16 -0700484 OptString: proto.String("repeat nested two"),
Herbie Ongcddf8192018-11-28 18:25:20 -0800485 OptNested: &pb2.Nested{
Damien Neila8a2cea2019-07-10 16:17:16 -0700486 OptString: proto.String("inside repeat nested two"),
Herbie Ongcddf8192018-11-28 18:25:20 -0800487 },
488 },
489 {},
490 },
Herbie Ong800c9902018-12-06 15:28:53 -0800491 },
492 want: `rpt_nested: {
Herbie Ongcddf8192018-11-28 18:25:20 -0800493 opt_string: "repeat nested one"
494}
495rpt_nested: {
496 opt_string: "repeat nested two"
497 opt_nested: {
498 opt_string: "inside repeat nested two"
499 }
500}
501rpt_nested: {}
502`,
503 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800504 desc: "repeated messages contains nil value",
Herbie Ongf5db2df2019-02-07 20:17:45 -0800505 input: &pb2.Nests{
506 RptNested: []*pb2.Nested{nil, {}},
507 },
508 want: `rpt_nested: {}
509rpt_nested: {}
510`,
511 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800512 desc: "repeated groups",
Herbie Ong800c9902018-12-06 15:28:53 -0800513 input: &pb2.Nests{
Herbie Ongcddf8192018-11-28 18:25:20 -0800514 Rptgroup: []*pb2.Nests_RptGroup{
515 {
Herbie Ong8170d692019-02-13 14:13:21 -0800516 RptString: []string{"hello", "world"},
Herbie Ongcddf8192018-11-28 18:25:20 -0800517 },
518 {},
Herbie Ong8170d692019-02-13 14:13:21 -0800519 nil,
Herbie Ongcddf8192018-11-28 18:25:20 -0800520 },
Herbie Ong800c9902018-12-06 15:28:53 -0800521 },
Herbie Ongde7313b2019-01-14 19:26:50 -0800522 want: `RptGroup: {
Herbie Ong8170d692019-02-13 14:13:21 -0800523 rpt_string: "hello"
524 rpt_string: "world"
Herbie Ongcddf8192018-11-28 18:25:20 -0800525}
Herbie Ongde7313b2019-01-14 19:26:50 -0800526RptGroup: {}
Herbie Ong8170d692019-02-13 14:13:21 -0800527RptGroup: {}
Herbie Ongcddf8192018-11-28 18:25:20 -0800528`,
529 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800530 desc: "map fields not set",
531 input: &pb3.Maps{},
Herbie Ongcddf8192018-11-28 18:25:20 -0800532 want: "\n",
533 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800534 desc: "map fields set to empty",
535 input: &pb3.Maps{
536 Int32ToStr: map[int32]string{},
537 BoolToUint32: map[bool]uint32{},
538 Uint64ToEnum: map[uint64]pb3.Enum{},
539 StrToNested: map[string]*pb3.Nested{},
540 StrToOneofs: map[string]*pb3.Oneofs{},
Herbie Ong800c9902018-12-06 15:28:53 -0800541 },
Herbie Ongcddf8192018-11-28 18:25:20 -0800542 want: "\n",
543 }, {
544 desc: "map fields 1",
Herbie Ong8170d692019-02-13 14:13:21 -0800545 input: &pb3.Maps{
Herbie Ongcddf8192018-11-28 18:25:20 -0800546 Int32ToStr: map[int32]string{
547 -101: "-101",
548 0xff: "0xff",
549 0: "zero",
550 },
Herbie Ongcddf8192018-11-28 18:25:20 -0800551 BoolToUint32: map[bool]uint32{
552 true: 42,
553 false: 101,
554 },
Herbie Ong800c9902018-12-06 15:28:53 -0800555 },
Herbie Ongcddf8192018-11-28 18:25:20 -0800556 want: `int32_to_str: {
557 key: -101
558 value: "-101"
559}
560int32_to_str: {
561 key: 0
562 value: "zero"
563}
564int32_to_str: {
565 key: 255
566 value: "0xff"
567}
Herbie Ongcddf8192018-11-28 18:25:20 -0800568bool_to_uint32: {
569 key: false
570 value: 101
571}
572bool_to_uint32: {
573 key: true
574 value: 42
575}
576`,
577 }, {
578 desc: "map fields 2",
Herbie Ong8170d692019-02-13 14:13:21 -0800579 input: &pb3.Maps{
580 Uint64ToEnum: map[uint64]pb3.Enum{
581 1: pb3.Enum_ONE,
582 2: pb3.Enum_TWO,
583 10: pb3.Enum_TEN,
584 47: 47,
Herbie Ongcddf8192018-11-28 18:25:20 -0800585 },
Herbie Ong800c9902018-12-06 15:28:53 -0800586 },
Herbie Ongcddf8192018-11-28 18:25:20 -0800587 want: `uint64_to_enum: {
588 key: 1
Herbie Ong8170d692019-02-13 14:13:21 -0800589 value: ONE
Herbie Ongcddf8192018-11-28 18:25:20 -0800590}
591uint64_to_enum: {
592 key: 2
Herbie Ong8170d692019-02-13 14:13:21 -0800593 value: TWO
Herbie Ongcddf8192018-11-28 18:25:20 -0800594}
595uint64_to_enum: {
596 key: 10
Herbie Ong8170d692019-02-13 14:13:21 -0800597 value: TEN
598}
599uint64_to_enum: {
600 key: 47
601 value: 47
Herbie Ongcddf8192018-11-28 18:25:20 -0800602}
603`,
604 }, {
605 desc: "map fields 3",
Herbie Ong8170d692019-02-13 14:13:21 -0800606 input: &pb3.Maps{
607 StrToNested: map[string]*pb3.Nested{
608 "nested": &pb3.Nested{
609 SString: "nested in a map",
Herbie Ongcddf8192018-11-28 18:25:20 -0800610 },
611 },
Herbie Ong800c9902018-12-06 15:28:53 -0800612 },
Herbie Ongcddf8192018-11-28 18:25:20 -0800613 want: `str_to_nested: {
Herbie Ong8170d692019-02-13 14:13:21 -0800614 key: "nested"
Herbie Ongcddf8192018-11-28 18:25:20 -0800615 value: {
Herbie Ong8170d692019-02-13 14:13:21 -0800616 s_string: "nested in a map"
Herbie Ongcddf8192018-11-28 18:25:20 -0800617 }
618}
619`,
620 }, {
621 desc: "map fields 4",
Herbie Ong8170d692019-02-13 14:13:21 -0800622 input: &pb3.Maps{
623 StrToOneofs: map[string]*pb3.Oneofs{
624 "string": &pb3.Oneofs{
625 Union: &pb3.Oneofs_OneofString{
626 OneofString: "hello",
Herbie Ongcddf8192018-11-28 18:25:20 -0800627 },
628 },
Herbie Ong8170d692019-02-13 14:13:21 -0800629 "nested": &pb3.Oneofs{
630 Union: &pb3.Oneofs_OneofNested{
631 OneofNested: &pb3.Nested{
632 SString: "nested oneof in map field value",
Herbie Ongcddf8192018-11-28 18:25:20 -0800633 },
634 },
635 },
636 },
Herbie Ong800c9902018-12-06 15:28:53 -0800637 },
Herbie Ongcddf8192018-11-28 18:25:20 -0800638 want: `str_to_oneofs: {
639 key: "nested"
640 value: {
Herbie Ong8170d692019-02-13 14:13:21 -0800641 oneof_nested: {
642 s_string: "nested oneof in map field value"
Herbie Ongcddf8192018-11-28 18:25:20 -0800643 }
644 }
645}
646str_to_oneofs: {
647 key: "string"
648 value: {
Herbie Ong8170d692019-02-13 14:13:21 -0800649 oneof_string: "hello"
Herbie Ongcddf8192018-11-28 18:25:20 -0800650 }
651}
652`,
653 }, {
Herbie Ong21a39742019-04-08 17:32:44 -0700654 desc: "map field value contains invalid UTF-8",
655 input: &pb3.Maps{
656 Int32ToStr: map[int32]string{
657 101: "abc\xff",
658 },
659 },
Herbie Ong21a39742019-04-08 17:32:44 -0700660 wantErr: true,
661 }, {
662 desc: "map field key contains invalid UTF-8",
663 input: &pb3.Maps{
664 StrToNested: map[string]*pb3.Nested{
665 "abc\xff": {},
666 },
667 },
Herbie Ong21a39742019-04-08 17:32:44 -0700668 wantErr: true,
669 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800670 desc: "map field contains nil value",
671 input: &pb3.Maps{
672 StrToNested: map[string]*pb3.Nested{
Herbie Ongf5db2df2019-02-07 20:17:45 -0800673 "nil": nil,
674 },
675 },
676 want: `str_to_nested: {
677 key: "nil"
678 value: {}
679}
680`,
681 }, {
Herbie Ong42577ea2019-03-26 16:26:22 -0700682 desc: "required fields not set",
Herbie Ong800c9902018-12-06 15:28:53 -0800683 input: &pb2.Requireds{},
684 want: "\n",
685 wantErr: true,
Herbie Ongcddf8192018-11-28 18:25:20 -0800686 }, {
Herbie Ong42577ea2019-03-26 16:26:22 -0700687 desc: "required fields partially set",
Herbie Ong800c9902018-12-06 15:28:53 -0800688 input: &pb2.Requireds{
Damien Neila8a2cea2019-07-10 16:17:16 -0700689 ReqBool: proto.Bool(false),
690 ReqSfixed64: proto.Int64(0xbeefcafe),
691 ReqDouble: proto.Float64(math.NaN()),
692 ReqString: proto.String("hello"),
Herbie Ong8170d692019-02-13 14:13:21 -0800693 ReqEnum: pb2.Enum_ONE.Enum(),
Herbie Ong800c9902018-12-06 15:28:53 -0800694 },
695 want: `req_bool: false
Herbie Ong800c9902018-12-06 15:28:53 -0800696req_sfixed64: 3203386110
697req_double: nan
698req_string: "hello"
Herbie Ong8170d692019-02-13 14:13:21 -0800699req_enum: ONE
Herbie Ong800c9902018-12-06 15:28:53 -0800700`,
701 wantErr: true,
702 }, {
Herbie Ong42577ea2019-03-26 16:26:22 -0700703 desc: "required fields not set with AllowPartial",
Damien Neil5c5b5312019-05-14 12:44:37 -0700704 mo: prototext.MarshalOptions{AllowPartial: true},
Herbie Ong42577ea2019-03-26 16:26:22 -0700705 input: &pb2.Requireds{
Damien Neila8a2cea2019-07-10 16:17:16 -0700706 ReqBool: proto.Bool(false),
707 ReqSfixed64: proto.Int64(0xbeefcafe),
708 ReqDouble: proto.Float64(math.NaN()),
709 ReqString: proto.String("hello"),
Herbie Ong42577ea2019-03-26 16:26:22 -0700710 ReqEnum: pb2.Enum_ONE.Enum(),
711 },
712 want: `req_bool: false
713req_sfixed64: 3203386110
714req_double: nan
715req_string: "hello"
716req_enum: ONE
717`,
718 }, {
719 desc: "required fields all set",
Herbie Ong800c9902018-12-06 15:28:53 -0800720 input: &pb2.Requireds{
Damien Neila8a2cea2019-07-10 16:17:16 -0700721 ReqBool: proto.Bool(false),
722 ReqSfixed64: proto.Int64(0),
723 ReqDouble: proto.Float64(1.23),
724 ReqString: proto.String(""),
Herbie Ong8170d692019-02-13 14:13:21 -0800725 ReqEnum: pb2.Enum_ONE.Enum(),
Herbie Ong800c9902018-12-06 15:28:53 -0800726 ReqNested: &pb2.Nested{},
727 },
728 want: `req_bool: false
Herbie Ong800c9902018-12-06 15:28:53 -0800729req_sfixed64: 0
Herbie Ong8170d692019-02-13 14:13:21 -0800730req_double: 1.23
Herbie Ong800c9902018-12-06 15:28:53 -0800731req_string: ""
Herbie Ong8170d692019-02-13 14:13:21 -0800732req_enum: ONE
Herbie Ong800c9902018-12-06 15:28:53 -0800733req_nested: {}
Herbie Ongcddf8192018-11-28 18:25:20 -0800734`,
735 }, {
Herbie Ong800c9902018-12-06 15:28:53 -0800736 desc: "indirect required field",
737 input: &pb2.IndirectRequired{
738 OptNested: &pb2.NestedWithRequired{},
739 },
740 want: "opt_nested: {}\n",
741 wantErr: true,
Herbie Ongcddf8192018-11-28 18:25:20 -0800742 }, {
Herbie Ong42577ea2019-03-26 16:26:22 -0700743 desc: "indirect required field with AllowPartial",
Damien Neil5c5b5312019-05-14 12:44:37 -0700744 mo: prototext.MarshalOptions{AllowPartial: true},
Herbie Ong42577ea2019-03-26 16:26:22 -0700745 input: &pb2.IndirectRequired{
746 OptNested: &pb2.NestedWithRequired{},
747 },
748 want: "opt_nested: {}\n",
749 }, {
Herbie Ong800c9902018-12-06 15:28:53 -0800750 desc: "indirect required field in empty repeated",
751 input: &pb2.IndirectRequired{
752 RptNested: []*pb2.NestedWithRequired{},
753 },
754 want: "\n",
Herbie Ongcddf8192018-11-28 18:25:20 -0800755 }, {
Herbie Ong800c9902018-12-06 15:28:53 -0800756 desc: "indirect required field in repeated",
757 input: &pb2.IndirectRequired{
758 RptNested: []*pb2.NestedWithRequired{
759 &pb2.NestedWithRequired{},
Herbie Ongcddf8192018-11-28 18:25:20 -0800760 },
Herbie Ong800c9902018-12-06 15:28:53 -0800761 },
762 want: "rpt_nested: {}\n",
763 wantErr: true,
764 }, {
Herbie Ong42577ea2019-03-26 16:26:22 -0700765 desc: "indirect required field in repeated with AllowPartial",
Damien Neil5c5b5312019-05-14 12:44:37 -0700766 mo: prototext.MarshalOptions{AllowPartial: true},
Herbie Ong42577ea2019-03-26 16:26:22 -0700767 input: &pb2.IndirectRequired{
768 RptNested: []*pb2.NestedWithRequired{
769 &pb2.NestedWithRequired{},
770 },
771 },
772 want: "rpt_nested: {}\n",
773 }, {
Herbie Ong800c9902018-12-06 15:28:53 -0800774 desc: "indirect required field in empty map",
775 input: &pb2.IndirectRequired{
776 StrToNested: map[string]*pb2.NestedWithRequired{},
777 },
778 want: "\n",
779 }, {
780 desc: "indirect required field in map",
781 input: &pb2.IndirectRequired{
782 StrToNested: map[string]*pb2.NestedWithRequired{
783 "fail": &pb2.NestedWithRequired{},
784 },
785 },
786 want: `str_to_nested: {
787 key: "fail"
788 value: {}
Herbie Ongcddf8192018-11-28 18:25:20 -0800789}
790`,
Herbie Ong800c9902018-12-06 15:28:53 -0800791 wantErr: true,
Herbie Ong20a1d312018-12-11 21:08:58 -0800792 }, {
Herbie Ong42577ea2019-03-26 16:26:22 -0700793 desc: "indirect required field in map with AllowPartial",
Damien Neil5c5b5312019-05-14 12:44:37 -0700794 mo: prototext.MarshalOptions{AllowPartial: true},
Herbie Ong42577ea2019-03-26 16:26:22 -0700795 input: &pb2.IndirectRequired{
796 StrToNested: map[string]*pb2.NestedWithRequired{
797 "fail": &pb2.NestedWithRequired{},
798 },
799 },
800 want: `str_to_nested: {
801 key: "fail"
802 value: {}
803}
804`,
805 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800806 desc: "indirect required field in oneof",
807 input: &pb2.IndirectRequired{
808 Union: &pb2.IndirectRequired_OneofNested{
809 OneofNested: &pb2.NestedWithRequired{},
810 },
811 },
812 want: "oneof_nested: {}\n",
813 wantErr: true,
814 }, {
Herbie Ong42577ea2019-03-26 16:26:22 -0700815 desc: "indirect required field in oneof with AllowPartial",
Damien Neil5c5b5312019-05-14 12:44:37 -0700816 mo: prototext.MarshalOptions{AllowPartial: true},
Herbie Ong42577ea2019-03-26 16:26:22 -0700817 input: &pb2.IndirectRequired{
818 Union: &pb2.IndirectRequired_OneofNested{
819 OneofNested: &pb2.NestedWithRequired{},
820 },
821 },
822 want: "oneof_nested: {}\n",
823 }, {
Herbie Ong20a1d312018-12-11 21:08:58 -0800824 desc: "unknown varint and fixed types",
Joe Tsai28216c72019-06-22 13:20:09 -0700825 input: func() proto.Message {
826 m := &pb2.Scalars{
Damien Neila8a2cea2019-07-10 16:17:16 -0700827 OptString: proto.String("this message contains unknown fields"),
Joe Tsai28216c72019-06-22 13:20:09 -0700828 }
829 m.ProtoReflect().SetUnknown(pack.Message{
Herbie Ong20a1d312018-12-11 21:08:58 -0800830 pack.Tag{101, pack.VarintType}, pack.Bool(true),
831 pack.Tag{102, pack.VarintType}, pack.Varint(0xff),
832 pack.Tag{103, pack.Fixed32Type}, pack.Uint32(47),
833 pack.Tag{104, pack.Fixed64Type}, pack.Int64(0xdeadbeef),
Joe Tsai28216c72019-06-22 13:20:09 -0700834 }.Marshal())
835 return m
836 }(),
Herbie Ong20a1d312018-12-11 21:08:58 -0800837 want: `opt_string: "this message contains unknown fields"
838101: 1
839102: 255
840103: 47
841104: 3735928559
842`,
843 }, {
844 desc: "unknown length-delimited",
Joe Tsai28216c72019-06-22 13:20:09 -0700845 input: func() proto.Message {
846 m := new(pb2.Scalars)
847 m.ProtoReflect().SetUnknown(pack.Message{
Herbie Ong20a1d312018-12-11 21:08:58 -0800848 pack.Tag{101, pack.BytesType}, pack.LengthPrefix{pack.Bool(true), pack.Bool(false)},
849 pack.Tag{102, pack.BytesType}, pack.String("hello world"),
850 pack.Tag{103, pack.BytesType}, pack.Bytes("\xe4\xb8\x96\xe7\x95\x8c"),
Joe Tsai28216c72019-06-22 13:20:09 -0700851 }.Marshal())
852 return m
853 }(),
Herbie Ong20a1d312018-12-11 21:08:58 -0800854 want: `101: "\x01\x00"
855102: "hello world"
856103: "世界"
857`,
858 }, {
859 desc: "unknown group type",
Joe Tsai28216c72019-06-22 13:20:09 -0700860 input: func() proto.Message {
861 m := new(pb2.Scalars)
862 m.ProtoReflect().SetUnknown(pack.Message{
Herbie Ong20a1d312018-12-11 21:08:58 -0800863 pack.Tag{101, pack.StartGroupType}, pack.Tag{101, pack.EndGroupType},
864 pack.Tag{102, pack.StartGroupType},
865 pack.Tag{101, pack.VarintType}, pack.Bool(false),
866 pack.Tag{102, pack.BytesType}, pack.String("inside a group"),
867 pack.Tag{102, pack.EndGroupType},
Joe Tsai28216c72019-06-22 13:20:09 -0700868 }.Marshal())
869 return m
870 }(),
Herbie Ong20a1d312018-12-11 21:08:58 -0800871 want: `101: {}
872102: {
873 101: 0
874 102: "inside a group"
875}
876`,
877 }, {
878 desc: "unknown unpack repeated field",
Joe Tsai28216c72019-06-22 13:20:09 -0700879 input: func() proto.Message {
880 m := new(pb2.Scalars)
881 m.ProtoReflect().SetUnknown(pack.Message{
Herbie Ong20a1d312018-12-11 21:08:58 -0800882 pack.Tag{101, pack.BytesType}, pack.LengthPrefix{pack.Bool(true), pack.Bool(false), pack.Bool(true)},
883 pack.Tag{102, pack.BytesType}, pack.String("hello"),
884 pack.Tag{101, pack.VarintType}, pack.Bool(true),
885 pack.Tag{102, pack.BytesType}, pack.String("世界"),
Joe Tsai28216c72019-06-22 13:20:09 -0700886 }.Marshal())
887 return m
888 }(),
Herbie Ong20a1d312018-12-11 21:08:58 -0800889 want: `101: "\x01\x00\x01"
Herbie Ong20a1d312018-12-11 21:08:58 -0800890102: "hello"
Joe Tsai378c1322019-04-25 23:48:08 -0700891101: 1
Herbie Ong20a1d312018-12-11 21:08:58 -0800892102: "世界"
893`,
Herbie Ongcf253082018-12-17 17:13:07 -0800894 }, {
895 desc: "extensions of non-repeated fields",
896 input: func() proto.Message {
897 m := &pb2.Extensions{
Damien Neila8a2cea2019-07-10 16:17:16 -0700898 OptString: proto.String("non-extension field"),
899 OptBool: proto.Bool(true),
900 OptInt32: proto.Int32(42),
Herbie Ongcf253082018-12-17 17:13:07 -0800901 }
Damien Neil92f76182019-08-02 16:58:08 -0700902 proto.SetExtension(m, pb2.E_OptExtBool, true)
903 proto.SetExtension(m, pb2.E_OptExtString, "extension field")
904 proto.SetExtension(m, pb2.E_OptExtEnum, pb2.Enum_TEN)
905 proto.SetExtension(m, pb2.E_OptExtNested, &pb2.Nested{
Damien Neila8a2cea2019-07-10 16:17:16 -0700906 OptString: proto.String("nested in an extension"),
Herbie Ongcf253082018-12-17 17:13:07 -0800907 OptNested: &pb2.Nested{
Damien Neila8a2cea2019-07-10 16:17:16 -0700908 OptString: proto.String("another nested in an extension"),
Herbie Ongcf253082018-12-17 17:13:07 -0800909 },
910 })
911 return m
912 }(),
913 want: `opt_string: "non-extension field"
914opt_bool: true
915opt_int32: 42
916[pb2.opt_ext_bool]: true
Herbie Ong8170d692019-02-13 14:13:21 -0800917[pb2.opt_ext_enum]: TEN
Herbie Ongcf253082018-12-17 17:13:07 -0800918[pb2.opt_ext_nested]: {
919 opt_string: "nested in an extension"
920 opt_nested: {
921 opt_string: "another nested in an extension"
922 }
923}
924[pb2.opt_ext_string]: "extension field"
925`,
926 }, {
Herbie Ong21a39742019-04-08 17:32:44 -0700927 desc: "extension field contains invalid UTF-8",
928 input: func() proto.Message {
929 m := &pb2.Extensions{}
Damien Neil92f76182019-08-02 16:58:08 -0700930 proto.SetExtension(m, pb2.E_OptExtString, "abc\xff")
Herbie Ong21a39742019-04-08 17:32:44 -0700931 return m
932 }(),
Herbie Ong21a39742019-04-08 17:32:44 -0700933 wantErr: true,
934 }, {
Herbie Ong09b28a92019-04-03 15:42:41 -0700935 desc: "extension partial returns error",
936 input: func() proto.Message {
937 m := &pb2.Extensions{}
Damien Neil92f76182019-08-02 16:58:08 -0700938 proto.SetExtension(m, pb2.E_OptExtPartial, &pb2.PartialRequired{
Damien Neila8a2cea2019-07-10 16:17:16 -0700939 OptString: proto.String("partial1"),
Herbie Ong09b28a92019-04-03 15:42:41 -0700940 })
Damien Neil92f76182019-08-02 16:58:08 -0700941 proto.SetExtension(m, pb2.E_ExtensionsContainer_OptExtPartial, &pb2.PartialRequired{
Damien Neila8a2cea2019-07-10 16:17:16 -0700942 OptString: proto.String("partial2"),
Herbie Ong09b28a92019-04-03 15:42:41 -0700943 })
944 return m
945 }(),
946 want: `[pb2.ExtensionsContainer.opt_ext_partial]: {
947 opt_string: "partial2"
948}
949[pb2.opt_ext_partial]: {
950 opt_string: "partial1"
951}
952`,
953 wantErr: true,
954 }, {
955 desc: "extension partial with AllowPartial",
Damien Neil5c5b5312019-05-14 12:44:37 -0700956 mo: prototext.MarshalOptions{AllowPartial: true},
Herbie Ong09b28a92019-04-03 15:42:41 -0700957 input: func() proto.Message {
958 m := &pb2.Extensions{}
Damien Neil92f76182019-08-02 16:58:08 -0700959 proto.SetExtension(m, pb2.E_OptExtPartial, &pb2.PartialRequired{
Damien Neila8a2cea2019-07-10 16:17:16 -0700960 OptString: proto.String("partial1"),
Herbie Ong09b28a92019-04-03 15:42:41 -0700961 })
962 return m
963 }(),
964 want: `[pb2.opt_ext_partial]: {
965 opt_string: "partial1"
966}
967`,
968 }, {
Herbie Ongcf253082018-12-17 17:13:07 -0800969 desc: "extensions of repeated fields",
970 input: func() proto.Message {
971 m := &pb2.Extensions{}
Damien Neil92f76182019-08-02 16:58:08 -0700972 proto.SetExtension(m, pb2.E_RptExtEnum, &[]pb2.Enum{pb2.Enum_TEN, 101, pb2.Enum_ONE})
973 proto.SetExtension(m, pb2.E_RptExtFixed32, &[]uint32{42, 47})
974 proto.SetExtension(m, pb2.E_RptExtNested, &[]*pb2.Nested{
Damien Neila8a2cea2019-07-10 16:17:16 -0700975 &pb2.Nested{OptString: proto.String("one")},
976 &pb2.Nested{OptString: proto.String("two")},
977 &pb2.Nested{OptString: proto.String("three")},
Herbie Ongcf253082018-12-17 17:13:07 -0800978 })
979 return m
980 }(),
Herbie Ong8170d692019-02-13 14:13:21 -0800981 want: `[pb2.rpt_ext_enum]: TEN
Herbie Ongcf253082018-12-17 17:13:07 -0800982[pb2.rpt_ext_enum]: 101
Herbie Ong8170d692019-02-13 14:13:21 -0800983[pb2.rpt_ext_enum]: ONE
Herbie Ongcf253082018-12-17 17:13:07 -0800984[pb2.rpt_ext_fixed32]: 42
985[pb2.rpt_ext_fixed32]: 47
986[pb2.rpt_ext_nested]: {
987 opt_string: "one"
988}
989[pb2.rpt_ext_nested]: {
990 opt_string: "two"
991}
992[pb2.rpt_ext_nested]: {
993 opt_string: "three"
994}
995`,
996 }, {
997 desc: "extensions of non-repeated fields in another message",
998 input: func() proto.Message {
999 m := &pb2.Extensions{}
Damien Neil92f76182019-08-02 16:58:08 -07001000 proto.SetExtension(m, pb2.E_ExtensionsContainer_OptExtBool, true)
1001 proto.SetExtension(m, pb2.E_ExtensionsContainer_OptExtString, "extension field")
1002 proto.SetExtension(m, pb2.E_ExtensionsContainer_OptExtEnum, pb2.Enum_TEN)
1003 proto.SetExtension(m, pb2.E_ExtensionsContainer_OptExtNested, &pb2.Nested{
Damien Neila8a2cea2019-07-10 16:17:16 -07001004 OptString: proto.String("nested in an extension"),
Herbie Ongcf253082018-12-17 17:13:07 -08001005 OptNested: &pb2.Nested{
Damien Neila8a2cea2019-07-10 16:17:16 -07001006 OptString: proto.String("another nested in an extension"),
Herbie Ongcf253082018-12-17 17:13:07 -08001007 },
1008 })
1009 return m
1010 }(),
1011 want: `[pb2.ExtensionsContainer.opt_ext_bool]: true
Herbie Ong8170d692019-02-13 14:13:21 -08001012[pb2.ExtensionsContainer.opt_ext_enum]: TEN
Herbie Ongcf253082018-12-17 17:13:07 -08001013[pb2.ExtensionsContainer.opt_ext_nested]: {
1014 opt_string: "nested in an extension"
1015 opt_nested: {
1016 opt_string: "another nested in an extension"
1017 }
1018}
1019[pb2.ExtensionsContainer.opt_ext_string]: "extension field"
1020`,
1021 }, {
1022 desc: "extensions of repeated fields in another message",
1023 input: func() proto.Message {
1024 m := &pb2.Extensions{
Damien Neila8a2cea2019-07-10 16:17:16 -07001025 OptString: proto.String("non-extension field"),
1026 OptBool: proto.Bool(true),
1027 OptInt32: proto.Int32(42),
Herbie Ongcf253082018-12-17 17:13:07 -08001028 }
Damien Neil92f76182019-08-02 16:58:08 -07001029 proto.SetExtension(m, pb2.E_ExtensionsContainer_RptExtEnum, &[]pb2.Enum{pb2.Enum_TEN, 101, pb2.Enum_ONE})
1030 proto.SetExtension(m, pb2.E_ExtensionsContainer_RptExtString, &[]string{"hello", "world"})
1031 proto.SetExtension(m, pb2.E_ExtensionsContainer_RptExtNested, &[]*pb2.Nested{
Damien Neila8a2cea2019-07-10 16:17:16 -07001032 &pb2.Nested{OptString: proto.String("one")},
1033 &pb2.Nested{OptString: proto.String("two")},
1034 &pb2.Nested{OptString: proto.String("three")},
Herbie Ongcf253082018-12-17 17:13:07 -08001035 })
1036 return m
1037 }(),
1038 want: `opt_string: "non-extension field"
1039opt_bool: true
1040opt_int32: 42
Herbie Ong8170d692019-02-13 14:13:21 -08001041[pb2.ExtensionsContainer.rpt_ext_enum]: TEN
Herbie Ongcf253082018-12-17 17:13:07 -08001042[pb2.ExtensionsContainer.rpt_ext_enum]: 101
Herbie Ong8170d692019-02-13 14:13:21 -08001043[pb2.ExtensionsContainer.rpt_ext_enum]: ONE
Herbie Ongcf253082018-12-17 17:13:07 -08001044[pb2.ExtensionsContainer.rpt_ext_nested]: {
1045 opt_string: "one"
1046}
1047[pb2.ExtensionsContainer.rpt_ext_nested]: {
1048 opt_string: "two"
1049}
1050[pb2.ExtensionsContainer.rpt_ext_nested]: {
1051 opt_string: "three"
1052}
1053[pb2.ExtensionsContainer.rpt_ext_string]: "hello"
1054[pb2.ExtensionsContainer.rpt_ext_string]: "world"
1055`,
Herbie Ong6470ea62019-01-07 18:56:57 -08001056 }, {
1057 desc: "MessageSet",
1058 input: func() proto.Message {
1059 m := &pb2.MessageSet{}
Damien Neil92f76182019-08-02 16:58:08 -07001060 proto.SetExtension(m, pb2.E_MessageSetExtension_MessageSetExtension, &pb2.MessageSetExtension{
Damien Neila8a2cea2019-07-10 16:17:16 -07001061 OptString: proto.String("a messageset extension"),
Herbie Ong6470ea62019-01-07 18:56:57 -08001062 })
Damien Neil92f76182019-08-02 16:58:08 -07001063 proto.SetExtension(m, pb2.E_MessageSetExtension_NotMessageSetExtension, &pb2.MessageSetExtension{
Damien Neila8a2cea2019-07-10 16:17:16 -07001064 OptString: proto.String("not a messageset extension"),
Herbie Ong6470ea62019-01-07 18:56:57 -08001065 })
Damien Neil92f76182019-08-02 16:58:08 -07001066 proto.SetExtension(m, pb2.E_MessageSetExtension_ExtNested, &pb2.Nested{
Damien Neila8a2cea2019-07-10 16:17:16 -07001067 OptString: proto.String("just a regular extension"),
Herbie Ong6470ea62019-01-07 18:56:57 -08001068 })
1069 return m
1070 }(),
1071 want: `[pb2.MessageSetExtension]: {
1072 opt_string: "a messageset extension"
1073}
1074[pb2.MessageSetExtension.ext_nested]: {
1075 opt_string: "just a regular extension"
1076}
1077[pb2.MessageSetExtension.not_message_set_extension]: {
1078 opt_string: "not a messageset extension"
1079}
1080`,
Joe Tsai5ae10aa2019-07-11 18:23:08 -07001081 skip: !flags.Proto1Legacy,
Herbie Ong6470ea62019-01-07 18:56:57 -08001082 }, {
1083 desc: "not real MessageSet 1",
1084 input: func() proto.Message {
1085 m := &pb2.FakeMessageSet{}
Damien Neil92f76182019-08-02 16:58:08 -07001086 proto.SetExtension(m, pb2.E_FakeMessageSetExtension_MessageSetExtension, &pb2.FakeMessageSetExtension{
Damien Neila8a2cea2019-07-10 16:17:16 -07001087 OptString: proto.String("not a messageset extension"),
Herbie Ong6470ea62019-01-07 18:56:57 -08001088 })
1089 return m
1090 }(),
1091 want: `[pb2.FakeMessageSetExtension.message_set_extension]: {
1092 opt_string: "not a messageset extension"
1093}
1094`,
Joe Tsai5ae10aa2019-07-11 18:23:08 -07001095 skip: !flags.Proto1Legacy,
Herbie Ong6470ea62019-01-07 18:56:57 -08001096 }, {
1097 desc: "not real MessageSet 2",
1098 input: func() proto.Message {
1099 m := &pb2.MessageSet{}
Damien Neil92f76182019-08-02 16:58:08 -07001100 proto.SetExtension(m, pb2.E_MessageSetExtension, &pb2.FakeMessageSetExtension{
Damien Neila8a2cea2019-07-10 16:17:16 -07001101 OptString: proto.String("another not a messageset extension"),
Herbie Ong6470ea62019-01-07 18:56:57 -08001102 })
1103 return m
1104 }(),
1105 want: `[pb2.message_set_extension]: {
1106 opt_string: "another not a messageset extension"
1107}
1108`,
Joe Tsai5ae10aa2019-07-11 18:23:08 -07001109 skip: !flags.Proto1Legacy,
Herbie Ongf42b55f2019-01-02 15:46:07 -08001110 }, {
Herbie Ong8170d692019-02-13 14:13:21 -08001111 desc: "Any not expanded",
Damien Neil5c5b5312019-05-14 12:44:37 -07001112 mo: prototext.MarshalOptions{
Herbie Ong66c365c2019-01-04 14:08:41 -08001113 Resolver: preg.NewTypes(),
1114 },
Herbie Ongf42b55f2019-01-02 15:46:07 -08001115 input: func() proto.Message {
1116 m := &pb2.Nested{
Damien Neila8a2cea2019-07-10 16:17:16 -07001117 OptString: proto.String("embedded inside Any"),
Herbie Ongf42b55f2019-01-02 15:46:07 -08001118 OptNested: &pb2.Nested{
Damien Neila8a2cea2019-07-10 16:17:16 -07001119 OptString: proto.String("inception"),
Herbie Ongf42b55f2019-01-02 15:46:07 -08001120 },
1121 }
Herbie Ong4d1c3be2019-03-15 18:22:36 -07001122 b, err := proto.MarshalOptions{Deterministic: true}.Marshal(m)
Herbie Ongf42b55f2019-01-02 15:46:07 -08001123 if err != nil {
1124 t.Fatalf("error in binary marshaling message for Any.value: %v", err)
1125 }
Joe Tsaia95b29f2019-05-16 12:47:20 -07001126 return &anypb.Any{
Herbie Ong66c365c2019-01-04 14:08:41 -08001127 TypeUrl: "pb2.Nested",
Herbie Ongf42b55f2019-01-02 15:46:07 -08001128 Value: b,
Herbie Ong300cff02019-03-20 18:05:16 -07001129 }
Herbie Ongf42b55f2019-01-02 15:46:07 -08001130 }(),
1131 want: `type_url: "pb2.Nested"
1132value: "\n\x13embedded inside Any\x12\x0b\n\tinception"
1133`,
1134 }, {
Herbie Ong8170d692019-02-13 14:13:21 -08001135 desc: "Any expanded",
Damien Neil5c5b5312019-05-14 12:44:37 -07001136 mo: prototext.MarshalOptions{
Joe Tsai0fc49f82019-05-01 12:29:25 -07001137 Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&pb2.Nested{})),
Herbie Ong66c365c2019-01-04 14:08:41 -08001138 },
Herbie Ongf42b55f2019-01-02 15:46:07 -08001139 input: func() proto.Message {
1140 m := &pb2.Nested{
Damien Neila8a2cea2019-07-10 16:17:16 -07001141 OptString: proto.String("embedded inside Any"),
Herbie Ongf42b55f2019-01-02 15:46:07 -08001142 OptNested: &pb2.Nested{
Damien Neila8a2cea2019-07-10 16:17:16 -07001143 OptString: proto.String("inception"),
Herbie Ongf42b55f2019-01-02 15:46:07 -08001144 },
1145 }
Herbie Ong4d1c3be2019-03-15 18:22:36 -07001146 b, err := proto.MarshalOptions{Deterministic: true}.Marshal(m)
Herbie Ongf42b55f2019-01-02 15:46:07 -08001147 if err != nil {
1148 t.Fatalf("error in binary marshaling message for Any.value: %v", err)
1149 }
Joe Tsaia95b29f2019-05-16 12:47:20 -07001150 return &anypb.Any{
Herbie Ong66c365c2019-01-04 14:08:41 -08001151 TypeUrl: "foo/pb2.Nested",
Herbie Ongf42b55f2019-01-02 15:46:07 -08001152 Value: b,
Herbie Ong300cff02019-03-20 18:05:16 -07001153 }
Herbie Ongf42b55f2019-01-02 15:46:07 -08001154 }(),
Herbie Ong66c365c2019-01-04 14:08:41 -08001155 want: `[foo/pb2.Nested]: {
Herbie Ongf42b55f2019-01-02 15:46:07 -08001156 opt_string: "embedded inside Any"
1157 opt_nested: {
1158 opt_string: "inception"
1159 }
1160}
1161`,
1162 }, {
Damien Neil0c9f0a92019-06-19 10:41:09 -07001163 desc: "Any expanded with missing required",
Damien Neil5c5b5312019-05-14 12:44:37 -07001164 mo: prototext.MarshalOptions{
Joe Tsai0fc49f82019-05-01 12:29:25 -07001165 Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&pb2.PartialRequired{})),
Herbie Ong66c365c2019-01-04 14:08:41 -08001166 },
Herbie Ongf42b55f2019-01-02 15:46:07 -08001167 input: func() proto.Message {
1168 m := &pb2.PartialRequired{
Damien Neila8a2cea2019-07-10 16:17:16 -07001169 OptString: proto.String("embedded inside Any"),
Herbie Ongf42b55f2019-01-02 15:46:07 -08001170 }
Damien Neil96c229a2019-04-03 12:17:24 -07001171 b, err := proto.MarshalOptions{
1172 AllowPartial: true,
1173 Deterministic: true,
1174 }.Marshal(m)
Herbie Ong300cff02019-03-20 18:05:16 -07001175 if err != nil {
Herbie Ongf42b55f2019-01-02 15:46:07 -08001176 t.Fatalf("error in binary marshaling message for Any.value: %v", err)
1177 }
Joe Tsaia95b29f2019-05-16 12:47:20 -07001178 return &anypb.Any{
Joe Tsai0fc49f82019-05-01 12:29:25 -07001179 TypeUrl: string(m.ProtoReflect().Descriptor().FullName()),
Herbie Ongf42b55f2019-01-02 15:46:07 -08001180 Value: b,
Herbie Ong300cff02019-03-20 18:05:16 -07001181 }
Herbie Ongf42b55f2019-01-02 15:46:07 -08001182 }(),
1183 want: `[pb2.PartialRequired]: {
1184 opt_string: "embedded inside Any"
1185}
1186`,
Herbie Ongf42b55f2019-01-02 15:46:07 -08001187 }, {
Herbie Ong8170d692019-02-13 14:13:21 -08001188 desc: "Any with invalid value",
Damien Neil5c5b5312019-05-14 12:44:37 -07001189 mo: prototext.MarshalOptions{
Joe Tsai0fc49f82019-05-01 12:29:25 -07001190 Resolver: preg.NewTypes(pimpl.Export{}.MessageTypeOf(&pb2.Nested{})),
Herbie Ong66c365c2019-01-04 14:08:41 -08001191 },
Joe Tsaia95b29f2019-05-16 12:47:20 -07001192 input: &anypb.Any{
Herbie Ong66c365c2019-01-04 14:08:41 -08001193 TypeUrl: "foo/pb2.Nested",
Joe Tsai6dc168e2019-07-09 23:11:13 -07001194 Value: []byte("\x80"),
Herbie Ong300cff02019-03-20 18:05:16 -07001195 },
Herbie Ong66c365c2019-01-04 14:08:41 -08001196 want: `type_url: "foo/pb2.Nested"
Herbie Onga94f78c2019-01-03 15:39:58 -08001197value: "\x80"
1198`,
Herbie Ongcddf8192018-11-28 18:25:20 -08001199 }}
1200
1201 for _, tt := range tests {
1202 tt := tt
Joe Tsai5ae10aa2019-07-11 18:23:08 -07001203 if tt.skip {
1204 continue
1205 }
Herbie Ongcddf8192018-11-28 18:25:20 -08001206 t.Run(tt.desc, func(t *testing.T) {
Herbie Ong3a385912019-03-20 14:04:24 -07001207 // Use 2-space indentation on all MarshalOptions.
1208 tt.mo.Indent = " "
Herbie Ongf42b55f2019-01-02 15:46:07 -08001209 b, err := tt.mo.Marshal(tt.input)
Herbie Ongcddf8192018-11-28 18:25:20 -08001210 if err != nil && !tt.wantErr {
Herbie Ongf42b55f2019-01-02 15:46:07 -08001211 t.Errorf("Marshal() returned error: %v\n", err)
Herbie Ongcddf8192018-11-28 18:25:20 -08001212 }
Herbie Ong800c9902018-12-06 15:28:53 -08001213 if err == nil && tt.wantErr {
Herbie Ongf42b55f2019-01-02 15:46:07 -08001214 t.Error("Marshal() got nil error, want error\n")
Herbie Ongcddf8192018-11-28 18:25:20 -08001215 }
Herbie Ong800c9902018-12-06 15:28:53 -08001216 got := string(b)
1217 if tt.want != "" && got != tt.want {
1218 t.Errorf("Marshal()\n<got>\n%v\n<want>\n%v\n", got, tt.want)
Joe Tsai378c1322019-04-25 23:48:08 -07001219 if diff := cmp.Diff(tt.want, got); diff != "" {
Herbie Ongcddf8192018-11-28 18:25:20 -08001220 t.Errorf("Marshal() diff -want +got\n%v\n", diff)
1221 }
1222 }
1223 })
1224 }
1225}