blob: 33daea098a5d79be3d042f74d73bd1109bde03e6 [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 "google.golang.org/protobuf/proto"
17 preg "google.golang.org/protobuf/reflect/protoregistry"
Herbie Ongcddf8192018-11-28 18:25:20 -080018
Joe Tsai94e730b2020-01-10 23:31:25 -080019 pb2 "google.golang.org/protobuf/internal/testprotos/textpb2"
20 pb3 "google.golang.org/protobuf/internal/testprotos/textpb3"
Joe Tsaia95b29f2019-05-16 12:47:20 -070021 "google.golang.org/protobuf/types/known/anypb"
Herbie Ongcddf8192018-11-28 18:25:20 -080022)
23
24func init() {
25 // Disable detrand to enable direct comparisons on outputs.
26 detrand.Disable()
27}
28
Herbie Ongcddf8192018-11-28 18:25:20 -080029func TestMarshal(t *testing.T) {
30 tests := []struct {
31 desc string
Damien Neil5c5b5312019-05-14 12:44:37 -070032 mo prototext.MarshalOptions
Herbie Ong70651952018-12-13 14:19:50 -080033 input proto.Message
Herbie Ongcddf8192018-11-28 18:25:20 -080034 want string
Herbie Ong300cff02019-03-20 18:05:16 -070035 wantErr bool // TODO: Verify error message content.
Joe Tsai5ae10aa2019-07-11 18:23:08 -070036 skip bool
Herbie Ongcddf8192018-11-28 18:25:20 -080037 }{{
Herbie Ong8170d692019-02-13 14:13:21 -080038 desc: "proto2 optional scalars not set",
Herbie Ong800c9902018-12-06 15:28:53 -080039 input: &pb2.Scalars{},
Joe Tsai3c4ab8c2019-09-11 15:31:45 -070040 want: "",
Herbie Ongcddf8192018-11-28 18:25:20 -080041 }, {
Herbie Ong8170d692019-02-13 14:13:21 -080042 desc: "proto3 scalars not set",
Herbie Ong800c9902018-12-06 15:28:53 -080043 input: &pb3.Scalars{},
Joe Tsai3c4ab8c2019-09-11 15:31:45 -070044 want: "",
Herbie Ongcddf8192018-11-28 18:25:20 -080045 }, {
Herbie Ong8170d692019-02-13 14:13:21 -080046 desc: "proto2 optional scalars set to zero values",
Herbie Ong800c9902018-12-06 15:28:53 -080047 input: &pb2.Scalars{
Damien Neila8a2cea2019-07-10 16:17:16 -070048 OptBool: proto.Bool(false),
49 OptInt32: proto.Int32(0),
50 OptInt64: proto.Int64(0),
51 OptUint32: proto.Uint32(0),
52 OptUint64: proto.Uint64(0),
53 OptSint32: proto.Int32(0),
54 OptSint64: proto.Int64(0),
55 OptFixed32: proto.Uint32(0),
56 OptFixed64: proto.Uint64(0),
57 OptSfixed32: proto.Int32(0),
58 OptSfixed64: proto.Int64(0),
59 OptFloat: proto.Float32(0),
60 OptDouble: proto.Float64(0),
Herbie Ongcddf8192018-11-28 18:25:20 -080061 OptBytes: []byte{},
Damien Neila8a2cea2019-07-10 16:17:16 -070062 OptString: proto.String(""),
Herbie Ong800c9902018-12-06 15:28:53 -080063 },
Herbie Ongcddf8192018-11-28 18:25:20 -080064 want: `opt_bool: false
65opt_int32: 0
66opt_int64: 0
67opt_uint32: 0
68opt_uint64: 0
69opt_sint32: 0
70opt_sint64: 0
71opt_fixed32: 0
72opt_fixed64: 0
73opt_sfixed32: 0
74opt_sfixed64: 0
75opt_float: 0
76opt_double: 0
77opt_bytes: ""
78opt_string: ""
79`,
80 }, {
Herbie Ong8170d692019-02-13 14:13:21 -080081 desc: "proto3 scalars set to zero values",
Herbie Ong800c9902018-12-06 15:28:53 -080082 input: &pb3.Scalars{
Herbie Ongcddf8192018-11-28 18:25:20 -080083 SBool: false,
84 SInt32: 0,
85 SInt64: 0,
86 SUint32: 0,
87 SUint64: 0,
88 SSint32: 0,
89 SSint64: 0,
90 SFixed32: 0,
91 SFixed64: 0,
92 SSfixed32: 0,
93 SSfixed64: 0,
94 SFloat: 0,
95 SDouble: 0,
96 SBytes: []byte{},
97 SString: "",
Herbie Ong800c9902018-12-06 15:28:53 -080098 },
Joe Tsai3c4ab8c2019-09-11 15:31:45 -070099 want: "",
Herbie Ongcddf8192018-11-28 18:25:20 -0800100 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800101 desc: "proto2 optional scalars set to some values",
Herbie Ong800c9902018-12-06 15:28:53 -0800102 input: &pb2.Scalars{
Damien Neila8a2cea2019-07-10 16:17:16 -0700103 OptBool: proto.Bool(true),
104 OptInt32: proto.Int32(0xff),
105 OptInt64: proto.Int64(0xdeadbeef),
106 OptUint32: proto.Uint32(47),
107 OptUint64: proto.Uint64(0xdeadbeef),
108 OptSint32: proto.Int32(-1001),
109 OptSint64: proto.Int64(-0xffff),
110 OptFixed64: proto.Uint64(64),
111 OptSfixed32: proto.Int32(-32),
112 OptFloat: proto.Float32(1.02),
113 OptDouble: proto.Float64(1.0199999809265137),
Herbie Ong8170d692019-02-13 14:13:21 -0800114 OptBytes: []byte("\xe8\xb0\xb7\xe6\xad\x8c"),
Damien Neila8a2cea2019-07-10 16:17:16 -0700115 OptString: proto.String("谷歌"),
Herbie Ong800c9902018-12-06 15:28:53 -0800116 },
Herbie Ongcddf8192018-11-28 18:25:20 -0800117 want: `opt_bool: true
118opt_int32: 255
119opt_int64: 3735928559
120opt_uint32: 47
121opt_uint64: 3735928559
122opt_sint32: -1001
123opt_sint64: -65535
124opt_fixed64: 64
125opt_sfixed32: -32
Herbie Ong84f09602019-01-17 19:31:47 -0800126opt_float: 1.02
127opt_double: 1.0199999809265137
Herbie Ongcddf8192018-11-28 18:25:20 -0800128opt_bytes: "谷歌"
129opt_string: "谷歌"
130`,
131 }, {
Herbie Ong21a39742019-04-08 17:32:44 -0700132 desc: "string with invalid UTF-8",
133 input: &pb3.Scalars{
134 SString: "abc\xff",
135 },
Herbie Ong21a39742019-04-08 17:32:44 -0700136 wantErr: true,
137 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800138 desc: "float nan",
Herbie Ong800c9902018-12-06 15:28:53 -0800139 input: &pb3.Scalars{
Herbie Ongcddf8192018-11-28 18:25:20 -0800140 SFloat: float32(math.NaN()),
Herbie Ong800c9902018-12-06 15:28:53 -0800141 },
Herbie Ongcddf8192018-11-28 18:25:20 -0800142 want: "s_float: nan\n",
143 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800144 desc: "float positive infinity",
Herbie Ong800c9902018-12-06 15:28:53 -0800145 input: &pb3.Scalars{
Herbie Ongcddf8192018-11-28 18:25:20 -0800146 SFloat: float32(math.Inf(1)),
Herbie Ong800c9902018-12-06 15:28:53 -0800147 },
Herbie Ongcddf8192018-11-28 18:25:20 -0800148 want: "s_float: inf\n",
149 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800150 desc: "float negative infinity",
Herbie Ong800c9902018-12-06 15:28:53 -0800151 input: &pb3.Scalars{
Herbie Ongcddf8192018-11-28 18:25:20 -0800152 SFloat: float32(math.Inf(-1)),
Herbie Ong800c9902018-12-06 15:28:53 -0800153 },
Herbie Ongcddf8192018-11-28 18:25:20 -0800154 want: "s_float: -inf\n",
155 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800156 desc: "double nan",
Herbie Ong800c9902018-12-06 15:28:53 -0800157 input: &pb3.Scalars{
Herbie Ongcddf8192018-11-28 18:25:20 -0800158 SDouble: math.NaN(),
Herbie Ong800c9902018-12-06 15:28:53 -0800159 },
Herbie Ongcddf8192018-11-28 18:25:20 -0800160 want: "s_double: nan\n",
161 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800162 desc: "double positive infinity",
Herbie Ong800c9902018-12-06 15:28:53 -0800163 input: &pb3.Scalars{
Herbie Ongcddf8192018-11-28 18:25:20 -0800164 SDouble: math.Inf(1),
Herbie Ong800c9902018-12-06 15:28:53 -0800165 },
Herbie Ongcddf8192018-11-28 18:25:20 -0800166 want: "s_double: inf\n",
167 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800168 desc: "double negative infinity",
Herbie Ong800c9902018-12-06 15:28:53 -0800169 input: &pb3.Scalars{
Herbie Ongcddf8192018-11-28 18:25:20 -0800170 SDouble: math.Inf(-1),
Herbie Ong800c9902018-12-06 15:28:53 -0800171 },
Herbie Ongcddf8192018-11-28 18:25:20 -0800172 want: "s_double: -inf\n",
173 }, {
Herbie Ong800c9902018-12-06 15:28:53 -0800174 desc: "proto2 enum not set",
175 input: &pb2.Enums{},
Joe Tsai3c4ab8c2019-09-11 15:31:45 -0700176 want: "",
Herbie Ongcddf8192018-11-28 18:25:20 -0800177 }, {
Herbie Ong800c9902018-12-06 15:28:53 -0800178 desc: "proto2 enum set to zero value",
179 input: &pb2.Enums{
Joe Tsai6dc168e2019-07-09 23:11:13 -0700180 OptEnum: pb2.Enum(0).Enum(),
181 OptNestedEnum: pb2.Enums_NestedEnum(0).Enum(),
Herbie Ong800c9902018-12-06 15:28:53 -0800182 },
Herbie Ong8170d692019-02-13 14:13:21 -0800183 want: `opt_enum: 0
Herbie Ong800c9902018-12-06 15:28:53 -0800184opt_nested_enum: 0
185`,
186 }, {
187 desc: "proto2 enum",
188 input: &pb2.Enums{
Herbie Ong8170d692019-02-13 14:13:21 -0800189 OptEnum: pb2.Enum_ONE.Enum(),
Herbie Ong800c9902018-12-06 15:28:53 -0800190 OptNestedEnum: pb2.Enums_UNO.Enum(),
191 },
Herbie Ong8170d692019-02-13 14:13:21 -0800192 want: `opt_enum: ONE
Herbie Ong800c9902018-12-06 15:28:53 -0800193opt_nested_enum: UNO
194`,
195 }, {
196 desc: "proto2 enum set to numeric values",
197 input: &pb2.Enums{
Joe Tsai6dc168e2019-07-09 23:11:13 -0700198 OptEnum: pb2.Enum(2).Enum(),
199 OptNestedEnum: pb2.Enums_NestedEnum(2).Enum(),
Herbie Ong800c9902018-12-06 15:28:53 -0800200 },
Herbie Ong8170d692019-02-13 14:13:21 -0800201 want: `opt_enum: TWO
Herbie Ong800c9902018-12-06 15:28:53 -0800202opt_nested_enum: DOS
203`,
204 }, {
205 desc: "proto2 enum set to unnamed numeric values",
206 input: &pb2.Enums{
Joe Tsai6dc168e2019-07-09 23:11:13 -0700207 OptEnum: pb2.Enum(101).Enum(),
208 OptNestedEnum: pb2.Enums_NestedEnum(-101).Enum(),
Herbie Ong800c9902018-12-06 15:28:53 -0800209 },
210 want: `opt_enum: 101
211opt_nested_enum: -101
212`,
213 }, {
214 desc: "proto3 enum not set",
215 input: &pb3.Enums{},
Joe Tsai3c4ab8c2019-09-11 15:31:45 -0700216 want: "",
Herbie Ong800c9902018-12-06 15:28:53 -0800217 }, {
218 desc: "proto3 enum set to zero value",
219 input: &pb3.Enums{
220 SEnum: pb3.Enum_ZERO,
221 SNestedEnum: pb3.Enums_CERO,
222 },
Joe Tsai3c4ab8c2019-09-11 15:31:45 -0700223 want: "",
Herbie Ong800c9902018-12-06 15:28:53 -0800224 }, {
225 desc: "proto3 enum",
226 input: &pb3.Enums{
227 SEnum: pb3.Enum_ONE,
Herbie Ong8170d692019-02-13 14:13:21 -0800228 SNestedEnum: pb3.Enums_UNO,
Herbie Ong800c9902018-12-06 15:28:53 -0800229 },
230 want: `s_enum: ONE
Herbie Ong8170d692019-02-13 14:13:21 -0800231s_nested_enum: UNO
Herbie Ong800c9902018-12-06 15:28:53 -0800232`,
233 }, {
234 desc: "proto3 enum set to numeric values",
235 input: &pb3.Enums{
236 SEnum: 2,
Herbie Ong8170d692019-02-13 14:13:21 -0800237 SNestedEnum: 2,
Herbie Ong800c9902018-12-06 15:28:53 -0800238 },
239 want: `s_enum: TWO
Herbie Ong8170d692019-02-13 14:13:21 -0800240s_nested_enum: DOS
Herbie Ong800c9902018-12-06 15:28:53 -0800241`,
242 }, {
243 desc: "proto3 enum set to unnamed numeric values",
244 input: &pb3.Enums{
245 SEnum: -47,
246 SNestedEnum: 47,
247 },
248 want: `s_enum: -47
249s_nested_enum: 47
250`,
251 }, {
252 desc: "proto2 nested message not set",
253 input: &pb2.Nests{},
Joe Tsai3c4ab8c2019-09-11 15:31:45 -0700254 want: "",
Herbie Ong800c9902018-12-06 15:28:53 -0800255 }, {
256 desc: "proto2 nested message set to empty",
257 input: &pb2.Nests{
258 OptNested: &pb2.Nested{},
259 Optgroup: &pb2.Nests_OptGroup{},
260 },
261 want: `opt_nested: {}
Herbie Ong0dcfb9a2019-01-14 15:32:26 -0800262OptGroup: {}
Herbie Ong800c9902018-12-06 15:28:53 -0800263`,
264 }, {
265 desc: "proto2 nested messages",
266 input: &pb2.Nests{
267 OptNested: &pb2.Nested{
Damien Neila8a2cea2019-07-10 16:17:16 -0700268 OptString: proto.String("nested message"),
Herbie Ong800c9902018-12-06 15:28:53 -0800269 OptNested: &pb2.Nested{
Damien Neila8a2cea2019-07-10 16:17:16 -0700270 OptString: proto.String("another nested message"),
Herbie Ong800c9902018-12-06 15:28:53 -0800271 },
272 },
273 },
274 want: `opt_nested: {
275 opt_string: "nested message"
276 opt_nested: {
277 opt_string: "another nested message"
278 }
279}
280`,
281 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800282 desc: "proto2 groups",
Herbie Ong800c9902018-12-06 15:28:53 -0800283 input: &pb2.Nests{
284 Optgroup: &pb2.Nests_OptGroup{
Damien Neila8a2cea2019-07-10 16:17:16 -0700285 OptString: proto.String("inside a group"),
Herbie Ong800c9902018-12-06 15:28:53 -0800286 OptNested: &pb2.Nested{
Damien Neila8a2cea2019-07-10 16:17:16 -0700287 OptString: proto.String("nested message inside a group"),
Herbie Ong800c9902018-12-06 15:28:53 -0800288 },
289 Optnestedgroup: &pb2.Nests_OptGroup_OptNestedGroup{
Damien Neila8a2cea2019-07-10 16:17:16 -0700290 OptFixed32: proto.Uint32(47),
Herbie Ong800c9902018-12-06 15:28:53 -0800291 },
292 },
293 },
Herbie Ong0dcfb9a2019-01-14 15:32:26 -0800294 want: `OptGroup: {
Herbie Ong800c9902018-12-06 15:28:53 -0800295 opt_string: "inside a group"
296 opt_nested: {
297 opt_string: "nested message inside a group"
298 }
Herbie Ong0dcfb9a2019-01-14 15:32:26 -0800299 OptNestedGroup: {
Herbie Ong8170d692019-02-13 14:13:21 -0800300 opt_fixed32: 47
Herbie Ong800c9902018-12-06 15:28:53 -0800301 }
302}
303`,
304 }, {
305 desc: "proto3 nested message not set",
306 input: &pb3.Nests{},
Joe Tsai3c4ab8c2019-09-11 15:31:45 -0700307 want: "",
Herbie Ong800c9902018-12-06 15:28:53 -0800308 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800309 desc: "proto3 nested message set to empty",
310 input: &pb3.Nests{
311 SNested: &pb3.Nested{},
312 },
313 want: "s_nested: {}\n",
314 }, {
Herbie Ong800c9902018-12-06 15:28:53 -0800315 desc: "proto3 nested message",
316 input: &pb3.Nests{
317 SNested: &pb3.Nested{
318 SString: "nested message",
319 SNested: &pb3.Nested{
320 SString: "another nested message",
321 },
322 },
323 },
324 want: `s_nested: {
325 s_string: "nested message"
326 s_nested: {
327 s_string: "another nested message"
328 }
329}
330`,
331 }, {
Herbie Ong21a39742019-04-08 17:32:44 -0700332 desc: "proto3 nested message contains invalid UTF-8",
333 input: &pb3.Nests{
334 SNested: &pb3.Nested{
335 SString: "abc\xff",
336 },
337 },
Herbie Ong21a39742019-04-08 17:32:44 -0700338 wantErr: true,
339 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800340 desc: "oneof not set",
341 input: &pb3.Oneofs{},
Joe Tsai3c4ab8c2019-09-11 15:31:45 -0700342 want: "",
Herbie Ong800c9902018-12-06 15:28:53 -0800343 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800344 desc: "oneof set to empty string",
345 input: &pb3.Oneofs{
346 Union: &pb3.Oneofs_OneofString{},
Herbie Ong800c9902018-12-06 15:28:53 -0800347 },
Herbie Ong8170d692019-02-13 14:13:21 -0800348 want: `oneof_string: ""
349`,
Herbie Ong800c9902018-12-06 15:28:53 -0800350 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800351 desc: "oneof set to string",
352 input: &pb3.Oneofs{
353 Union: &pb3.Oneofs_OneofString{
354 OneofString: "hello",
Herbie Ong800c9902018-12-06 15:28:53 -0800355 },
356 },
Herbie Ong8170d692019-02-13 14:13:21 -0800357 want: `oneof_string: "hello"
358`,
Herbie Ong800c9902018-12-06 15:28:53 -0800359 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800360 desc: "oneof set to enum",
361 input: &pb3.Oneofs{
362 Union: &pb3.Oneofs_OneofEnum{
363 OneofEnum: pb3.Enum_ZERO,
Herbie Ong800c9902018-12-06 15:28:53 -0800364 },
365 },
Herbie Ong8170d692019-02-13 14:13:21 -0800366 want: `oneof_enum: ZERO
367`,
Herbie Ong800c9902018-12-06 15:28:53 -0800368 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800369 desc: "oneof set to empty message",
370 input: &pb3.Oneofs{
371 Union: &pb3.Oneofs_OneofNested{
372 OneofNested: &pb3.Nested{},
373 },
374 },
375 want: "oneof_nested: {}\n",
376 }, {
377 desc: "oneof set to message",
378 input: &pb3.Oneofs{
379 Union: &pb3.Oneofs_OneofNested{
380 OneofNested: &pb3.Nested{
381 SString: "nested message",
Herbie Ong800c9902018-12-06 15:28:53 -0800382 },
383 },
384 },
Herbie Ong8170d692019-02-13 14:13:21 -0800385 want: `oneof_nested: {
386 s_string: "nested message"
Herbie Ong800c9902018-12-06 15:28:53 -0800387}
388`,
389 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800390 desc: "repeated fields not set",
Herbie Ong800c9902018-12-06 15:28:53 -0800391 input: &pb2.Repeats{},
Joe Tsai3c4ab8c2019-09-11 15:31:45 -0700392 want: "",
Herbie Ong800c9902018-12-06 15:28:53 -0800393 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800394 desc: "repeated fields set to empty slices",
Herbie Ong800c9902018-12-06 15:28:53 -0800395 input: &pb2.Repeats{
Herbie Ongcddf8192018-11-28 18:25:20 -0800396 RptBool: []bool{},
397 RptInt32: []int32{},
398 RptInt64: []int64{},
399 RptUint32: []uint32{},
400 RptUint64: []uint64{},
401 RptFloat: []float32{},
402 RptDouble: []float64{},
403 RptBytes: [][]byte{},
Herbie Ong800c9902018-12-06 15:28:53 -0800404 },
Joe Tsai3c4ab8c2019-09-11 15:31:45 -0700405 want: "",
Herbie Ongcddf8192018-11-28 18:25:20 -0800406 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800407 desc: "repeated fields set to some values",
Herbie Ong800c9902018-12-06 15:28:53 -0800408 input: &pb2.Repeats{
Herbie Ongcddf8192018-11-28 18:25:20 -0800409 RptBool: []bool{true, false, true, true},
410 RptInt32: []int32{1, 6, 0, 0},
411 RptInt64: []int64{-64, 47},
412 RptUint32: []uint32{0xff, 0xffff},
413 RptUint64: []uint64{0xdeadbeef},
Herbie Ong84f09602019-01-17 19:31:47 -0800414 RptFloat: []float32{float32(math.NaN()), float32(math.Inf(1)), float32(math.Inf(-1)), 1.034},
Herbie Ongcddf8192018-11-28 18:25:20 -0800415 RptDouble: []float64{math.NaN(), math.Inf(1), math.Inf(-1), 1.23e-308},
416 RptString: []string{"hello", "世界"},
417 RptBytes: [][]byte{
418 []byte("hello"),
419 []byte("\xe4\xb8\x96\xe7\x95\x8c"),
420 },
Herbie Ong800c9902018-12-06 15:28:53 -0800421 },
Herbie Ongcddf8192018-11-28 18:25:20 -0800422 want: `rpt_bool: true
423rpt_bool: false
424rpt_bool: true
425rpt_bool: true
426rpt_int32: 1
427rpt_int32: 6
428rpt_int32: 0
429rpt_int32: 0
430rpt_int64: -64
431rpt_int64: 47
432rpt_uint32: 255
433rpt_uint32: 65535
434rpt_uint64: 3735928559
Herbie Ong84f09602019-01-17 19:31:47 -0800435rpt_float: nan
436rpt_float: inf
437rpt_float: -inf
438rpt_float: 1.034
Herbie Ongcddf8192018-11-28 18:25:20 -0800439rpt_double: nan
440rpt_double: inf
441rpt_double: -inf
442rpt_double: 1.23e-308
443rpt_string: "hello"
444rpt_string: "世界"
445rpt_bytes: "hello"
446rpt_bytes: "世界"
447`,
448 }, {
Herbie Ong21a39742019-04-08 17:32:44 -0700449 desc: "repeated contains invalid UTF-8",
450 input: &pb2.Repeats{
451 RptString: []string{"abc\xff"},
452 },
Herbie Ong21a39742019-04-08 17:32:44 -0700453 wantErr: true,
454 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800455 desc: "repeated enums",
Herbie Ong800c9902018-12-06 15:28:53 -0800456 input: &pb2.Enums{
Herbie Ong8170d692019-02-13 14:13:21 -0800457 RptEnum: []pb2.Enum{pb2.Enum_ONE, 2, pb2.Enum_TEN, 42},
Herbie Ongcddf8192018-11-28 18:25:20 -0800458 RptNestedEnum: []pb2.Enums_NestedEnum{2, 47, 10},
Herbie Ong800c9902018-12-06 15:28:53 -0800459 },
Herbie Ong8170d692019-02-13 14:13:21 -0800460 want: `rpt_enum: ONE
461rpt_enum: TWO
462rpt_enum: TEN
Herbie Ongcddf8192018-11-28 18:25:20 -0800463rpt_enum: 42
Herbie Ongcddf8192018-11-28 18:25:20 -0800464rpt_nested_enum: DOS
465rpt_nested_enum: 47
466rpt_nested_enum: DIEZ
467`,
468 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800469 desc: "repeated messages set to empty",
Herbie Ong800c9902018-12-06 15:28:53 -0800470 input: &pb2.Nests{
Herbie Ongcddf8192018-11-28 18:25:20 -0800471 RptNested: []*pb2.Nested{},
472 Rptgroup: []*pb2.Nests_RptGroup{},
Herbie Ong800c9902018-12-06 15:28:53 -0800473 },
Joe Tsai3c4ab8c2019-09-11 15:31:45 -0700474 want: "",
Herbie Ongcddf8192018-11-28 18:25:20 -0800475 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800476 desc: "repeated messages",
Herbie Ong800c9902018-12-06 15:28:53 -0800477 input: &pb2.Nests{
Herbie Ongcddf8192018-11-28 18:25:20 -0800478 RptNested: []*pb2.Nested{
479 {
Damien Neila8a2cea2019-07-10 16:17:16 -0700480 OptString: proto.String("repeat nested one"),
Herbie Ongcddf8192018-11-28 18:25:20 -0800481 },
482 {
Damien Neila8a2cea2019-07-10 16:17:16 -0700483 OptString: proto.String("repeat nested two"),
Herbie Ongcddf8192018-11-28 18:25:20 -0800484 OptNested: &pb2.Nested{
Damien Neila8a2cea2019-07-10 16:17:16 -0700485 OptString: proto.String("inside repeat nested two"),
Herbie Ongcddf8192018-11-28 18:25:20 -0800486 },
487 },
488 {},
489 },
Herbie Ong800c9902018-12-06 15:28:53 -0800490 },
491 want: `rpt_nested: {
Herbie Ongcddf8192018-11-28 18:25:20 -0800492 opt_string: "repeat nested one"
493}
494rpt_nested: {
495 opt_string: "repeat nested two"
496 opt_nested: {
497 opt_string: "inside repeat nested two"
498 }
499}
500rpt_nested: {}
501`,
502 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800503 desc: "repeated messages contains nil value",
Herbie Ongf5db2df2019-02-07 20:17:45 -0800504 input: &pb2.Nests{
505 RptNested: []*pb2.Nested{nil, {}},
506 },
507 want: `rpt_nested: {}
508rpt_nested: {}
509`,
510 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800511 desc: "repeated groups",
Herbie Ong800c9902018-12-06 15:28:53 -0800512 input: &pb2.Nests{
Herbie Ongcddf8192018-11-28 18:25:20 -0800513 Rptgroup: []*pb2.Nests_RptGroup{
514 {
Herbie Ong8170d692019-02-13 14:13:21 -0800515 RptString: []string{"hello", "world"},
Herbie Ongcddf8192018-11-28 18:25:20 -0800516 },
517 {},
Herbie Ong8170d692019-02-13 14:13:21 -0800518 nil,
Herbie Ongcddf8192018-11-28 18:25:20 -0800519 },
Herbie Ong800c9902018-12-06 15:28:53 -0800520 },
Herbie Ongde7313b2019-01-14 19:26:50 -0800521 want: `RptGroup: {
Herbie Ong8170d692019-02-13 14:13:21 -0800522 rpt_string: "hello"
523 rpt_string: "world"
Herbie Ongcddf8192018-11-28 18:25:20 -0800524}
Herbie Ongde7313b2019-01-14 19:26:50 -0800525RptGroup: {}
Herbie Ong8170d692019-02-13 14:13:21 -0800526RptGroup: {}
Herbie Ongcddf8192018-11-28 18:25:20 -0800527`,
528 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800529 desc: "map fields not set",
530 input: &pb3.Maps{},
Joe Tsai3c4ab8c2019-09-11 15:31:45 -0700531 want: "",
Herbie Ongcddf8192018-11-28 18:25:20 -0800532 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800533 desc: "map fields set to empty",
534 input: &pb3.Maps{
535 Int32ToStr: map[int32]string{},
536 BoolToUint32: map[bool]uint32{},
537 Uint64ToEnum: map[uint64]pb3.Enum{},
538 StrToNested: map[string]*pb3.Nested{},
539 StrToOneofs: map[string]*pb3.Oneofs{},
Herbie Ong800c9902018-12-06 15:28:53 -0800540 },
Joe Tsai3c4ab8c2019-09-11 15:31:45 -0700541 want: "",
Herbie Ongcddf8192018-11-28 18:25:20 -0800542 }, {
543 desc: "map fields 1",
Herbie Ong8170d692019-02-13 14:13:21 -0800544 input: &pb3.Maps{
Herbie Ongcddf8192018-11-28 18:25:20 -0800545 Int32ToStr: map[int32]string{
546 -101: "-101",
547 0xff: "0xff",
548 0: "zero",
549 },
Herbie Ongcddf8192018-11-28 18:25:20 -0800550 BoolToUint32: map[bool]uint32{
551 true: 42,
552 false: 101,
553 },
Herbie Ong800c9902018-12-06 15:28:53 -0800554 },
Herbie Ongcddf8192018-11-28 18:25:20 -0800555 want: `int32_to_str: {
556 key: -101
557 value: "-101"
558}
559int32_to_str: {
560 key: 0
561 value: "zero"
562}
563int32_to_str: {
564 key: 255
565 value: "0xff"
566}
Herbie Ongcddf8192018-11-28 18:25:20 -0800567bool_to_uint32: {
568 key: false
569 value: 101
570}
571bool_to_uint32: {
572 key: true
573 value: 42
574}
575`,
576 }, {
577 desc: "map fields 2",
Herbie Ong8170d692019-02-13 14:13:21 -0800578 input: &pb3.Maps{
579 Uint64ToEnum: map[uint64]pb3.Enum{
580 1: pb3.Enum_ONE,
581 2: pb3.Enum_TWO,
582 10: pb3.Enum_TEN,
583 47: 47,
Herbie Ongcddf8192018-11-28 18:25:20 -0800584 },
Herbie Ong800c9902018-12-06 15:28:53 -0800585 },
Herbie Ongcddf8192018-11-28 18:25:20 -0800586 want: `uint64_to_enum: {
587 key: 1
Herbie Ong8170d692019-02-13 14:13:21 -0800588 value: ONE
Herbie Ongcddf8192018-11-28 18:25:20 -0800589}
590uint64_to_enum: {
591 key: 2
Herbie Ong8170d692019-02-13 14:13:21 -0800592 value: TWO
Herbie Ongcddf8192018-11-28 18:25:20 -0800593}
594uint64_to_enum: {
595 key: 10
Herbie Ong8170d692019-02-13 14:13:21 -0800596 value: TEN
597}
598uint64_to_enum: {
599 key: 47
600 value: 47
Herbie Ongcddf8192018-11-28 18:25:20 -0800601}
602`,
603 }, {
604 desc: "map fields 3",
Herbie Ong8170d692019-02-13 14:13:21 -0800605 input: &pb3.Maps{
606 StrToNested: map[string]*pb3.Nested{
607 "nested": &pb3.Nested{
608 SString: "nested in a map",
Herbie Ongcddf8192018-11-28 18:25:20 -0800609 },
610 },
Herbie Ong800c9902018-12-06 15:28:53 -0800611 },
Herbie Ongcddf8192018-11-28 18:25:20 -0800612 want: `str_to_nested: {
Herbie Ong8170d692019-02-13 14:13:21 -0800613 key: "nested"
Herbie Ongcddf8192018-11-28 18:25:20 -0800614 value: {
Herbie Ong8170d692019-02-13 14:13:21 -0800615 s_string: "nested in a map"
Herbie Ongcddf8192018-11-28 18:25:20 -0800616 }
617}
618`,
619 }, {
620 desc: "map fields 4",
Herbie Ong8170d692019-02-13 14:13:21 -0800621 input: &pb3.Maps{
622 StrToOneofs: map[string]*pb3.Oneofs{
623 "string": &pb3.Oneofs{
624 Union: &pb3.Oneofs_OneofString{
625 OneofString: "hello",
Herbie Ongcddf8192018-11-28 18:25:20 -0800626 },
627 },
Herbie Ong8170d692019-02-13 14:13:21 -0800628 "nested": &pb3.Oneofs{
629 Union: &pb3.Oneofs_OneofNested{
630 OneofNested: &pb3.Nested{
631 SString: "nested oneof in map field value",
Herbie Ongcddf8192018-11-28 18:25:20 -0800632 },
633 },
634 },
635 },
Herbie Ong800c9902018-12-06 15:28:53 -0800636 },
Herbie Ongcddf8192018-11-28 18:25:20 -0800637 want: `str_to_oneofs: {
638 key: "nested"
639 value: {
Herbie Ong8170d692019-02-13 14:13:21 -0800640 oneof_nested: {
641 s_string: "nested oneof in map field value"
Herbie Ongcddf8192018-11-28 18:25:20 -0800642 }
643 }
644}
645str_to_oneofs: {
646 key: "string"
647 value: {
Herbie Ong8170d692019-02-13 14:13:21 -0800648 oneof_string: "hello"
Herbie Ongcddf8192018-11-28 18:25:20 -0800649 }
650}
651`,
652 }, {
Herbie Ong21a39742019-04-08 17:32:44 -0700653 desc: "map field value contains invalid UTF-8",
654 input: &pb3.Maps{
655 Int32ToStr: map[int32]string{
656 101: "abc\xff",
657 },
658 },
Herbie Ong21a39742019-04-08 17:32:44 -0700659 wantErr: true,
660 }, {
661 desc: "map field key contains invalid UTF-8",
662 input: &pb3.Maps{
663 StrToNested: map[string]*pb3.Nested{
664 "abc\xff": {},
665 },
666 },
Herbie Ong21a39742019-04-08 17:32:44 -0700667 wantErr: true,
668 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800669 desc: "map field contains nil value",
670 input: &pb3.Maps{
671 StrToNested: map[string]*pb3.Nested{
Herbie Ongf5db2df2019-02-07 20:17:45 -0800672 "nil": nil,
673 },
674 },
675 want: `str_to_nested: {
676 key: "nil"
677 value: {}
678}
679`,
680 }, {
Herbie Ong42577ea2019-03-26 16:26:22 -0700681 desc: "required fields not set",
Herbie Ong800c9902018-12-06 15:28:53 -0800682 input: &pb2.Requireds{},
Joe Tsai3c4ab8c2019-09-11 15:31:45 -0700683 want: "",
Herbie Ong800c9902018-12-06 15:28:53 -0800684 wantErr: true,
Herbie Ongcddf8192018-11-28 18:25:20 -0800685 }, {
Herbie Ong42577ea2019-03-26 16:26:22 -0700686 desc: "required fields partially set",
Herbie Ong800c9902018-12-06 15:28:53 -0800687 input: &pb2.Requireds{
Damien Neila8a2cea2019-07-10 16:17:16 -0700688 ReqBool: proto.Bool(false),
689 ReqSfixed64: proto.Int64(0xbeefcafe),
690 ReqDouble: proto.Float64(math.NaN()),
691 ReqString: proto.String("hello"),
Herbie Ong8170d692019-02-13 14:13:21 -0800692 ReqEnum: pb2.Enum_ONE.Enum(),
Herbie Ong800c9902018-12-06 15:28:53 -0800693 },
694 want: `req_bool: false
Herbie Ong800c9902018-12-06 15:28:53 -0800695req_sfixed64: 3203386110
696req_double: nan
697req_string: "hello"
Herbie Ong8170d692019-02-13 14:13:21 -0800698req_enum: ONE
Herbie Ong800c9902018-12-06 15:28:53 -0800699`,
700 wantErr: true,
701 }, {
Herbie Ong42577ea2019-03-26 16:26:22 -0700702 desc: "required fields not set with AllowPartial",
Damien Neil5c5b5312019-05-14 12:44:37 -0700703 mo: prototext.MarshalOptions{AllowPartial: true},
Herbie Ong42577ea2019-03-26 16:26:22 -0700704 input: &pb2.Requireds{
Damien Neila8a2cea2019-07-10 16:17:16 -0700705 ReqBool: proto.Bool(false),
706 ReqSfixed64: proto.Int64(0xbeefcafe),
707 ReqDouble: proto.Float64(math.NaN()),
708 ReqString: proto.String("hello"),
Herbie Ong42577ea2019-03-26 16:26:22 -0700709 ReqEnum: pb2.Enum_ONE.Enum(),
710 },
711 want: `req_bool: false
712req_sfixed64: 3203386110
713req_double: nan
714req_string: "hello"
715req_enum: ONE
716`,
717 }, {
718 desc: "required fields all set",
Herbie Ong800c9902018-12-06 15:28:53 -0800719 input: &pb2.Requireds{
Damien Neila8a2cea2019-07-10 16:17:16 -0700720 ReqBool: proto.Bool(false),
721 ReqSfixed64: proto.Int64(0),
722 ReqDouble: proto.Float64(1.23),
723 ReqString: proto.String(""),
Herbie Ong8170d692019-02-13 14:13:21 -0800724 ReqEnum: pb2.Enum_ONE.Enum(),
Herbie Ong800c9902018-12-06 15:28:53 -0800725 ReqNested: &pb2.Nested{},
726 },
727 want: `req_bool: false
Herbie Ong800c9902018-12-06 15:28:53 -0800728req_sfixed64: 0
Herbie Ong8170d692019-02-13 14:13:21 -0800729req_double: 1.23
Herbie Ong800c9902018-12-06 15:28:53 -0800730req_string: ""
Herbie Ong8170d692019-02-13 14:13:21 -0800731req_enum: ONE
Herbie Ong800c9902018-12-06 15:28:53 -0800732req_nested: {}
Herbie Ongcddf8192018-11-28 18:25:20 -0800733`,
734 }, {
Herbie Ong800c9902018-12-06 15:28:53 -0800735 desc: "indirect required field",
736 input: &pb2.IndirectRequired{
737 OptNested: &pb2.NestedWithRequired{},
738 },
739 want: "opt_nested: {}\n",
740 wantErr: true,
Herbie Ongcddf8192018-11-28 18:25:20 -0800741 }, {
Herbie Ong42577ea2019-03-26 16:26:22 -0700742 desc: "indirect required field with AllowPartial",
Damien Neil5c5b5312019-05-14 12:44:37 -0700743 mo: prototext.MarshalOptions{AllowPartial: true},
Herbie Ong42577ea2019-03-26 16:26:22 -0700744 input: &pb2.IndirectRequired{
745 OptNested: &pb2.NestedWithRequired{},
746 },
747 want: "opt_nested: {}\n",
748 }, {
Herbie Ong800c9902018-12-06 15:28:53 -0800749 desc: "indirect required field in empty repeated",
750 input: &pb2.IndirectRequired{
751 RptNested: []*pb2.NestedWithRequired{},
752 },
Joe Tsai3c4ab8c2019-09-11 15:31:45 -0700753 want: "",
Herbie Ongcddf8192018-11-28 18:25:20 -0800754 }, {
Herbie Ong800c9902018-12-06 15:28:53 -0800755 desc: "indirect required field in repeated",
756 input: &pb2.IndirectRequired{
757 RptNested: []*pb2.NestedWithRequired{
758 &pb2.NestedWithRequired{},
Herbie Ongcddf8192018-11-28 18:25:20 -0800759 },
Herbie Ong800c9902018-12-06 15:28:53 -0800760 },
761 want: "rpt_nested: {}\n",
762 wantErr: true,
763 }, {
Herbie Ong42577ea2019-03-26 16:26:22 -0700764 desc: "indirect required field in repeated with AllowPartial",
Damien Neil5c5b5312019-05-14 12:44:37 -0700765 mo: prototext.MarshalOptions{AllowPartial: true},
Herbie Ong42577ea2019-03-26 16:26:22 -0700766 input: &pb2.IndirectRequired{
767 RptNested: []*pb2.NestedWithRequired{
768 &pb2.NestedWithRequired{},
769 },
770 },
771 want: "rpt_nested: {}\n",
772 }, {
Herbie Ong800c9902018-12-06 15:28:53 -0800773 desc: "indirect required field in empty map",
774 input: &pb2.IndirectRequired{
775 StrToNested: map[string]*pb2.NestedWithRequired{},
776 },
Joe Tsai3c4ab8c2019-09-11 15:31:45 -0700777 want: "",
Herbie Ong800c9902018-12-06 15:28:53 -0800778 }, {
779 desc: "indirect required field in map",
780 input: &pb2.IndirectRequired{
781 StrToNested: map[string]*pb2.NestedWithRequired{
782 "fail": &pb2.NestedWithRequired{},
783 },
784 },
785 want: `str_to_nested: {
786 key: "fail"
787 value: {}
Herbie Ongcddf8192018-11-28 18:25:20 -0800788}
789`,
Herbie Ong800c9902018-12-06 15:28:53 -0800790 wantErr: true,
Herbie Ong20a1d312018-12-11 21:08:58 -0800791 }, {
Herbie Ong42577ea2019-03-26 16:26:22 -0700792 desc: "indirect required field in map with AllowPartial",
Damien Neil5c5b5312019-05-14 12:44:37 -0700793 mo: prototext.MarshalOptions{AllowPartial: true},
Herbie Ong42577ea2019-03-26 16:26:22 -0700794 input: &pb2.IndirectRequired{
795 StrToNested: map[string]*pb2.NestedWithRequired{
796 "fail": &pb2.NestedWithRequired{},
797 },
798 },
799 want: `str_to_nested: {
800 key: "fail"
801 value: {}
802}
803`,
804 }, {
Herbie Ong8170d692019-02-13 14:13:21 -0800805 desc: "indirect required field in oneof",
806 input: &pb2.IndirectRequired{
807 Union: &pb2.IndirectRequired_OneofNested{
808 OneofNested: &pb2.NestedWithRequired{},
809 },
810 },
811 want: "oneof_nested: {}\n",
812 wantErr: true,
813 }, {
Herbie Ong42577ea2019-03-26 16:26:22 -0700814 desc: "indirect required field in oneof with AllowPartial",
Damien Neil5c5b5312019-05-14 12:44:37 -0700815 mo: prototext.MarshalOptions{AllowPartial: true},
Herbie Ong42577ea2019-03-26 16:26:22 -0700816 input: &pb2.IndirectRequired{
817 Union: &pb2.IndirectRequired_OneofNested{
818 OneofNested: &pb2.NestedWithRequired{},
819 },
820 },
821 want: "oneof_nested: {}\n",
822 }, {
Joe Tsaicd4a31e2019-09-14 19:14:24 -0700823 desc: "unknown fields not printed",
824 input: func() proto.Message {
825 m := &pb2.Scalars{
826 OptString: proto.String("this message contains unknown fields"),
827 }
828 m.ProtoReflect().SetUnknown(pack.Message{
829 pack.Tag{101, pack.VarintType}, pack.Bool(true),
830 pack.Tag{102, pack.VarintType}, pack.Varint(0xff),
831 pack.Tag{103, pack.Fixed32Type}, pack.Uint32(47),
832 pack.Tag{104, pack.Fixed64Type}, pack.Int64(0xdeadbeef),
833 }.Marshal())
834 return m
835 }(),
836 want: `opt_string: "this message contains unknown fields"
837`,
838 }, {
Herbie Ong20a1d312018-12-11 21:08:58 -0800839 desc: "unknown varint and fixed types",
Joe Tsaicd4a31e2019-09-14 19:14:24 -0700840 mo: prototext.MarshalOptions{EmitUnknown: true},
Joe Tsai28216c72019-06-22 13:20:09 -0700841 input: func() proto.Message {
842 m := &pb2.Scalars{
Damien Neila8a2cea2019-07-10 16:17:16 -0700843 OptString: proto.String("this message contains unknown fields"),
Joe Tsai28216c72019-06-22 13:20:09 -0700844 }
845 m.ProtoReflect().SetUnknown(pack.Message{
Herbie Ong20a1d312018-12-11 21:08:58 -0800846 pack.Tag{101, pack.VarintType}, pack.Bool(true),
847 pack.Tag{102, pack.VarintType}, pack.Varint(0xff),
848 pack.Tag{103, pack.Fixed32Type}, pack.Uint32(47),
849 pack.Tag{104, pack.Fixed64Type}, pack.Int64(0xdeadbeef),
Joe Tsai28216c72019-06-22 13:20:09 -0700850 }.Marshal())
851 return m
852 }(),
Herbie Ong20a1d312018-12-11 21:08:58 -0800853 want: `opt_string: "this message contains unknown fields"
854101: 1
855102: 255
856103: 47
857104: 3735928559
858`,
859 }, {
860 desc: "unknown length-delimited",
Joe Tsaicd4a31e2019-09-14 19:14:24 -0700861 mo: prototext.MarshalOptions{EmitUnknown: true},
Joe Tsai28216c72019-06-22 13:20:09 -0700862 input: func() proto.Message {
863 m := new(pb2.Scalars)
864 m.ProtoReflect().SetUnknown(pack.Message{
Herbie Ong20a1d312018-12-11 21:08:58 -0800865 pack.Tag{101, pack.BytesType}, pack.LengthPrefix{pack.Bool(true), pack.Bool(false)},
866 pack.Tag{102, pack.BytesType}, pack.String("hello world"),
867 pack.Tag{103, pack.BytesType}, pack.Bytes("\xe4\xb8\x96\xe7\x95\x8c"),
Joe Tsai28216c72019-06-22 13:20:09 -0700868 }.Marshal())
869 return m
870 }(),
Herbie Ong20a1d312018-12-11 21:08:58 -0800871 want: `101: "\x01\x00"
872102: "hello world"
873103: "世界"
874`,
875 }, {
876 desc: "unknown group type",
Joe Tsaicd4a31e2019-09-14 19:14:24 -0700877 mo: prototext.MarshalOptions{EmitUnknown: true},
Joe Tsai28216c72019-06-22 13:20:09 -0700878 input: func() proto.Message {
879 m := new(pb2.Scalars)
880 m.ProtoReflect().SetUnknown(pack.Message{
Herbie Ong20a1d312018-12-11 21:08:58 -0800881 pack.Tag{101, pack.StartGroupType}, pack.Tag{101, pack.EndGroupType},
882 pack.Tag{102, pack.StartGroupType},
883 pack.Tag{101, pack.VarintType}, pack.Bool(false),
884 pack.Tag{102, pack.BytesType}, pack.String("inside a group"),
885 pack.Tag{102, pack.EndGroupType},
Joe Tsai28216c72019-06-22 13:20:09 -0700886 }.Marshal())
887 return m
888 }(),
Herbie Ong20a1d312018-12-11 21:08:58 -0800889 want: `101: {}
890102: {
891 101: 0
892 102: "inside a group"
893}
894`,
895 }, {
896 desc: "unknown unpack repeated field",
Joe Tsaicd4a31e2019-09-14 19:14:24 -0700897 mo: prototext.MarshalOptions{EmitUnknown: true},
Joe Tsai28216c72019-06-22 13:20:09 -0700898 input: func() proto.Message {
899 m := new(pb2.Scalars)
900 m.ProtoReflect().SetUnknown(pack.Message{
Herbie Ong20a1d312018-12-11 21:08:58 -0800901 pack.Tag{101, pack.BytesType}, pack.LengthPrefix{pack.Bool(true), pack.Bool(false), pack.Bool(true)},
902 pack.Tag{102, pack.BytesType}, pack.String("hello"),
903 pack.Tag{101, pack.VarintType}, pack.Bool(true),
904 pack.Tag{102, pack.BytesType}, pack.String("世界"),
Joe Tsai28216c72019-06-22 13:20:09 -0700905 }.Marshal())
906 return m
907 }(),
Herbie Ong20a1d312018-12-11 21:08:58 -0800908 want: `101: "\x01\x00\x01"
Herbie Ong20a1d312018-12-11 21:08:58 -0800909102: "hello"
Joe Tsai378c1322019-04-25 23:48:08 -0700910101: 1
Herbie Ong20a1d312018-12-11 21:08:58 -0800911102: "世界"
912`,
Herbie Ongcf253082018-12-17 17:13:07 -0800913 }, {
914 desc: "extensions of non-repeated fields",
915 input: func() proto.Message {
916 m := &pb2.Extensions{
Damien Neila8a2cea2019-07-10 16:17:16 -0700917 OptString: proto.String("non-extension field"),
918 OptBool: proto.Bool(true),
919 OptInt32: proto.Int32(42),
Herbie Ongcf253082018-12-17 17:13:07 -0800920 }
Damien Neil92f76182019-08-02 16:58:08 -0700921 proto.SetExtension(m, pb2.E_OptExtBool, true)
922 proto.SetExtension(m, pb2.E_OptExtString, "extension field")
923 proto.SetExtension(m, pb2.E_OptExtEnum, pb2.Enum_TEN)
924 proto.SetExtension(m, pb2.E_OptExtNested, &pb2.Nested{
Damien Neila8a2cea2019-07-10 16:17:16 -0700925 OptString: proto.String("nested in an extension"),
Herbie Ongcf253082018-12-17 17:13:07 -0800926 OptNested: &pb2.Nested{
Damien Neila8a2cea2019-07-10 16:17:16 -0700927 OptString: proto.String("another nested in an extension"),
Herbie Ongcf253082018-12-17 17:13:07 -0800928 },
929 })
930 return m
931 }(),
932 want: `opt_string: "non-extension field"
933opt_bool: true
934opt_int32: 42
935[pb2.opt_ext_bool]: true
Herbie Ong8170d692019-02-13 14:13:21 -0800936[pb2.opt_ext_enum]: TEN
Herbie Ongcf253082018-12-17 17:13:07 -0800937[pb2.opt_ext_nested]: {
938 opt_string: "nested in an extension"
939 opt_nested: {
940 opt_string: "another nested in an extension"
941 }
942}
943[pb2.opt_ext_string]: "extension field"
944`,
945 }, {
Herbie Ong21a39742019-04-08 17:32:44 -0700946 desc: "extension field contains invalid UTF-8",
947 input: func() proto.Message {
948 m := &pb2.Extensions{}
Damien Neil92f76182019-08-02 16:58:08 -0700949 proto.SetExtension(m, pb2.E_OptExtString, "abc\xff")
Herbie Ong21a39742019-04-08 17:32:44 -0700950 return m
951 }(),
Herbie Ong21a39742019-04-08 17:32:44 -0700952 wantErr: true,
953 }, {
Herbie Ong09b28a92019-04-03 15:42:41 -0700954 desc: "extension partial returns error",
955 input: func() proto.Message {
956 m := &pb2.Extensions{}
Damien Neil92f76182019-08-02 16:58:08 -0700957 proto.SetExtension(m, pb2.E_OptExtPartial, &pb2.PartialRequired{
Damien Neila8a2cea2019-07-10 16:17:16 -0700958 OptString: proto.String("partial1"),
Herbie Ong09b28a92019-04-03 15:42:41 -0700959 })
Damien Neil92f76182019-08-02 16:58:08 -0700960 proto.SetExtension(m, pb2.E_ExtensionsContainer_OptExtPartial, &pb2.PartialRequired{
Damien Neila8a2cea2019-07-10 16:17:16 -0700961 OptString: proto.String("partial2"),
Herbie Ong09b28a92019-04-03 15:42:41 -0700962 })
963 return m
964 }(),
965 want: `[pb2.ExtensionsContainer.opt_ext_partial]: {
966 opt_string: "partial2"
967}
968[pb2.opt_ext_partial]: {
969 opt_string: "partial1"
970}
971`,
972 wantErr: true,
973 }, {
974 desc: "extension partial with AllowPartial",
Damien Neil5c5b5312019-05-14 12:44:37 -0700975 mo: prototext.MarshalOptions{AllowPartial: true},
Herbie Ong09b28a92019-04-03 15:42:41 -0700976 input: func() proto.Message {
977 m := &pb2.Extensions{}
Damien Neil92f76182019-08-02 16:58:08 -0700978 proto.SetExtension(m, pb2.E_OptExtPartial, &pb2.PartialRequired{
Damien Neila8a2cea2019-07-10 16:17:16 -0700979 OptString: proto.String("partial1"),
Herbie Ong09b28a92019-04-03 15:42:41 -0700980 })
981 return m
982 }(),
983 want: `[pb2.opt_ext_partial]: {
984 opt_string: "partial1"
985}
986`,
987 }, {
Herbie Ongcf253082018-12-17 17:13:07 -0800988 desc: "extensions of repeated fields",
989 input: func() proto.Message {
990 m := &pb2.Extensions{}
Damien Neil293dc762019-08-29 11:42:57 -0700991 proto.SetExtension(m, pb2.E_RptExtEnum, []pb2.Enum{pb2.Enum_TEN, 101, pb2.Enum_ONE})
992 proto.SetExtension(m, pb2.E_RptExtFixed32, []uint32{42, 47})
993 proto.SetExtension(m, pb2.E_RptExtNested, []*pb2.Nested{
Damien Neila8a2cea2019-07-10 16:17:16 -0700994 &pb2.Nested{OptString: proto.String("one")},
995 &pb2.Nested{OptString: proto.String("two")},
996 &pb2.Nested{OptString: proto.String("three")},
Herbie Ongcf253082018-12-17 17:13:07 -0800997 })
998 return m
999 }(),
Herbie Ong8170d692019-02-13 14:13:21 -08001000 want: `[pb2.rpt_ext_enum]: TEN
Herbie Ongcf253082018-12-17 17:13:07 -08001001[pb2.rpt_ext_enum]: 101
Herbie Ong8170d692019-02-13 14:13:21 -08001002[pb2.rpt_ext_enum]: ONE
Herbie Ongcf253082018-12-17 17:13:07 -08001003[pb2.rpt_ext_fixed32]: 42
1004[pb2.rpt_ext_fixed32]: 47
1005[pb2.rpt_ext_nested]: {
1006 opt_string: "one"
1007}
1008[pb2.rpt_ext_nested]: {
1009 opt_string: "two"
1010}
1011[pb2.rpt_ext_nested]: {
1012 opt_string: "three"
1013}
1014`,
1015 }, {
1016 desc: "extensions of non-repeated fields in another message",
1017 input: func() proto.Message {
1018 m := &pb2.Extensions{}
Damien Neil92f76182019-08-02 16:58:08 -07001019 proto.SetExtension(m, pb2.E_ExtensionsContainer_OptExtBool, true)
1020 proto.SetExtension(m, pb2.E_ExtensionsContainer_OptExtString, "extension field")
1021 proto.SetExtension(m, pb2.E_ExtensionsContainer_OptExtEnum, pb2.Enum_TEN)
1022 proto.SetExtension(m, pb2.E_ExtensionsContainer_OptExtNested, &pb2.Nested{
Damien Neila8a2cea2019-07-10 16:17:16 -07001023 OptString: proto.String("nested in an extension"),
Herbie Ongcf253082018-12-17 17:13:07 -08001024 OptNested: &pb2.Nested{
Damien Neila8a2cea2019-07-10 16:17:16 -07001025 OptString: proto.String("another nested in an extension"),
Herbie Ongcf253082018-12-17 17:13:07 -08001026 },
1027 })
1028 return m
1029 }(),
1030 want: `[pb2.ExtensionsContainer.opt_ext_bool]: true
Herbie Ong8170d692019-02-13 14:13:21 -08001031[pb2.ExtensionsContainer.opt_ext_enum]: TEN
Herbie Ongcf253082018-12-17 17:13:07 -08001032[pb2.ExtensionsContainer.opt_ext_nested]: {
1033 opt_string: "nested in an extension"
1034 opt_nested: {
1035 opt_string: "another nested in an extension"
1036 }
1037}
1038[pb2.ExtensionsContainer.opt_ext_string]: "extension field"
1039`,
1040 }, {
1041 desc: "extensions of repeated fields in another message",
1042 input: func() proto.Message {
1043 m := &pb2.Extensions{
Damien Neila8a2cea2019-07-10 16:17:16 -07001044 OptString: proto.String("non-extension field"),
1045 OptBool: proto.Bool(true),
1046 OptInt32: proto.Int32(42),
Herbie Ongcf253082018-12-17 17:13:07 -08001047 }
Damien Neil293dc762019-08-29 11:42:57 -07001048 proto.SetExtension(m, pb2.E_ExtensionsContainer_RptExtEnum, []pb2.Enum{pb2.Enum_TEN, 101, pb2.Enum_ONE})
1049 proto.SetExtension(m, pb2.E_ExtensionsContainer_RptExtString, []string{"hello", "world"})
1050 proto.SetExtension(m, pb2.E_ExtensionsContainer_RptExtNested, []*pb2.Nested{
Damien Neila8a2cea2019-07-10 16:17:16 -07001051 &pb2.Nested{OptString: proto.String("one")},
1052 &pb2.Nested{OptString: proto.String("two")},
1053 &pb2.Nested{OptString: proto.String("three")},
Herbie Ongcf253082018-12-17 17:13:07 -08001054 })
1055 return m
1056 }(),
1057 want: `opt_string: "non-extension field"
1058opt_bool: true
1059opt_int32: 42
Herbie Ong8170d692019-02-13 14:13:21 -08001060[pb2.ExtensionsContainer.rpt_ext_enum]: TEN
Herbie Ongcf253082018-12-17 17:13:07 -08001061[pb2.ExtensionsContainer.rpt_ext_enum]: 101
Herbie Ong8170d692019-02-13 14:13:21 -08001062[pb2.ExtensionsContainer.rpt_ext_enum]: ONE
Herbie Ongcf253082018-12-17 17:13:07 -08001063[pb2.ExtensionsContainer.rpt_ext_nested]: {
1064 opt_string: "one"
1065}
1066[pb2.ExtensionsContainer.rpt_ext_nested]: {
1067 opt_string: "two"
1068}
1069[pb2.ExtensionsContainer.rpt_ext_nested]: {
1070 opt_string: "three"
1071}
1072[pb2.ExtensionsContainer.rpt_ext_string]: "hello"
1073[pb2.ExtensionsContainer.rpt_ext_string]: "world"
1074`,
Herbie Ong6470ea62019-01-07 18:56:57 -08001075 }, {
1076 desc: "MessageSet",
1077 input: func() proto.Message {
1078 m := &pb2.MessageSet{}
Damien Neil92f76182019-08-02 16:58:08 -07001079 proto.SetExtension(m, pb2.E_MessageSetExtension_MessageSetExtension, &pb2.MessageSetExtension{
Damien Neila8a2cea2019-07-10 16:17:16 -07001080 OptString: proto.String("a messageset extension"),
Herbie Ong6470ea62019-01-07 18:56:57 -08001081 })
Damien Neil92f76182019-08-02 16:58:08 -07001082 proto.SetExtension(m, pb2.E_MessageSetExtension_NotMessageSetExtension, &pb2.MessageSetExtension{
Damien Neila8a2cea2019-07-10 16:17:16 -07001083 OptString: proto.String("not a messageset extension"),
Herbie Ong6470ea62019-01-07 18:56:57 -08001084 })
Damien Neil92f76182019-08-02 16:58:08 -07001085 proto.SetExtension(m, pb2.E_MessageSetExtension_ExtNested, &pb2.Nested{
Damien Neila8a2cea2019-07-10 16:17:16 -07001086 OptString: proto.String("just a regular extension"),
Herbie Ong6470ea62019-01-07 18:56:57 -08001087 })
1088 return m
1089 }(),
1090 want: `[pb2.MessageSetExtension]: {
1091 opt_string: "a messageset extension"
1092}
1093[pb2.MessageSetExtension.ext_nested]: {
1094 opt_string: "just a regular extension"
1095}
1096[pb2.MessageSetExtension.not_message_set_extension]: {
1097 opt_string: "not a messageset extension"
1098}
1099`,
Joe Tsai1799d112019-08-08 13:31:59 -07001100 skip: !flags.ProtoLegacy,
Herbie Ong6470ea62019-01-07 18:56:57 -08001101 }, {
1102 desc: "not real MessageSet 1",
1103 input: func() proto.Message {
1104 m := &pb2.FakeMessageSet{}
Damien Neil92f76182019-08-02 16:58:08 -07001105 proto.SetExtension(m, pb2.E_FakeMessageSetExtension_MessageSetExtension, &pb2.FakeMessageSetExtension{
Damien Neila8a2cea2019-07-10 16:17:16 -07001106 OptString: proto.String("not a messageset extension"),
Herbie Ong6470ea62019-01-07 18:56:57 -08001107 })
1108 return m
1109 }(),
1110 want: `[pb2.FakeMessageSetExtension.message_set_extension]: {
1111 opt_string: "not a messageset extension"
1112}
1113`,
Joe Tsai1799d112019-08-08 13:31:59 -07001114 skip: !flags.ProtoLegacy,
Herbie Ong6470ea62019-01-07 18:56:57 -08001115 }, {
1116 desc: "not real MessageSet 2",
1117 input: func() proto.Message {
1118 m := &pb2.MessageSet{}
Damien Neil92f76182019-08-02 16:58:08 -07001119 proto.SetExtension(m, pb2.E_MessageSetExtension, &pb2.FakeMessageSetExtension{
Damien Neila8a2cea2019-07-10 16:17:16 -07001120 OptString: proto.String("another not a messageset extension"),
Herbie Ong6470ea62019-01-07 18:56:57 -08001121 })
1122 return m
1123 }(),
1124 want: `[pb2.message_set_extension]: {
1125 opt_string: "another not a messageset extension"
1126}
1127`,
Joe Tsai1799d112019-08-08 13:31:59 -07001128 skip: !flags.ProtoLegacy,
Herbie Ongf42b55f2019-01-02 15:46:07 -08001129 }, {
Herbie Ong8170d692019-02-13 14:13:21 -08001130 desc: "Any not expanded",
Damien Neil5c5b5312019-05-14 12:44:37 -07001131 mo: prototext.MarshalOptions{
Damien Neilc1507ac2019-10-08 13:24:16 -07001132 Resolver: new(preg.Types),
Herbie Ong66c365c2019-01-04 14:08:41 -08001133 },
Herbie Ongf42b55f2019-01-02 15:46:07 -08001134 input: func() proto.Message {
1135 m := &pb2.Nested{
Damien Neila8a2cea2019-07-10 16:17:16 -07001136 OptString: proto.String("embedded inside Any"),
Herbie Ongf42b55f2019-01-02 15:46:07 -08001137 OptNested: &pb2.Nested{
Damien Neila8a2cea2019-07-10 16:17:16 -07001138 OptString: proto.String("inception"),
Herbie Ongf42b55f2019-01-02 15:46:07 -08001139 },
1140 }
Herbie Ong4d1c3be2019-03-15 18:22:36 -07001141 b, err := proto.MarshalOptions{Deterministic: true}.Marshal(m)
Herbie Ongf42b55f2019-01-02 15:46:07 -08001142 if err != nil {
1143 t.Fatalf("error in binary marshaling message for Any.value: %v", err)
1144 }
Joe Tsaia95b29f2019-05-16 12:47:20 -07001145 return &anypb.Any{
Herbie Ong66c365c2019-01-04 14:08:41 -08001146 TypeUrl: "pb2.Nested",
Herbie Ongf42b55f2019-01-02 15:46:07 -08001147 Value: b,
Herbie Ong300cff02019-03-20 18:05:16 -07001148 }
Herbie Ongf42b55f2019-01-02 15:46:07 -08001149 }(),
1150 want: `type_url: "pb2.Nested"
1151value: "\n\x13embedded inside Any\x12\x0b\n\tinception"
1152`,
1153 }, {
Herbie Ong8170d692019-02-13 14:13:21 -08001154 desc: "Any expanded",
Herbie Ongf42b55f2019-01-02 15:46:07 -08001155 input: func() proto.Message {
1156 m := &pb2.Nested{
Damien Neila8a2cea2019-07-10 16:17:16 -07001157 OptString: proto.String("embedded inside Any"),
Herbie Ongf42b55f2019-01-02 15:46:07 -08001158 OptNested: &pb2.Nested{
Damien Neila8a2cea2019-07-10 16:17:16 -07001159 OptString: proto.String("inception"),
Herbie Ongf42b55f2019-01-02 15:46:07 -08001160 },
1161 }
Herbie Ong4d1c3be2019-03-15 18:22:36 -07001162 b, err := proto.MarshalOptions{Deterministic: true}.Marshal(m)
Herbie Ongf42b55f2019-01-02 15:46:07 -08001163 if err != nil {
1164 t.Fatalf("error in binary marshaling message for Any.value: %v", err)
1165 }
Joe Tsaia95b29f2019-05-16 12:47:20 -07001166 return &anypb.Any{
Herbie Ong66c365c2019-01-04 14:08:41 -08001167 TypeUrl: "foo/pb2.Nested",
Herbie Ongf42b55f2019-01-02 15:46:07 -08001168 Value: b,
Herbie Ong300cff02019-03-20 18:05:16 -07001169 }
Herbie Ongf42b55f2019-01-02 15:46:07 -08001170 }(),
Herbie Ong66c365c2019-01-04 14:08:41 -08001171 want: `[foo/pb2.Nested]: {
Herbie Ongf42b55f2019-01-02 15:46:07 -08001172 opt_string: "embedded inside Any"
1173 opt_nested: {
1174 opt_string: "inception"
1175 }
1176}
1177`,
1178 }, {
Damien Neil0c9f0a92019-06-19 10:41:09 -07001179 desc: "Any expanded with missing required",
Herbie Ongf42b55f2019-01-02 15:46:07 -08001180 input: func() proto.Message {
1181 m := &pb2.PartialRequired{
Damien Neila8a2cea2019-07-10 16:17:16 -07001182 OptString: proto.String("embedded inside Any"),
Herbie Ongf42b55f2019-01-02 15:46:07 -08001183 }
Damien Neil96c229a2019-04-03 12:17:24 -07001184 b, err := proto.MarshalOptions{
1185 AllowPartial: true,
1186 Deterministic: true,
1187 }.Marshal(m)
Herbie Ong300cff02019-03-20 18:05:16 -07001188 if err != nil {
Herbie Ongf42b55f2019-01-02 15:46:07 -08001189 t.Fatalf("error in binary marshaling message for Any.value: %v", err)
1190 }
Joe Tsaia95b29f2019-05-16 12:47:20 -07001191 return &anypb.Any{
Joe Tsai0fc49f82019-05-01 12:29:25 -07001192 TypeUrl: string(m.ProtoReflect().Descriptor().FullName()),
Herbie Ongf42b55f2019-01-02 15:46:07 -08001193 Value: b,
Herbie Ong300cff02019-03-20 18:05:16 -07001194 }
Herbie Ongf42b55f2019-01-02 15:46:07 -08001195 }(),
1196 want: `[pb2.PartialRequired]: {
1197 opt_string: "embedded inside Any"
1198}
1199`,
Herbie Ongf42b55f2019-01-02 15:46:07 -08001200 }, {
Herbie Ong8170d692019-02-13 14:13:21 -08001201 desc: "Any with invalid value",
Joe Tsaia95b29f2019-05-16 12:47:20 -07001202 input: &anypb.Any{
Herbie Ong66c365c2019-01-04 14:08:41 -08001203 TypeUrl: "foo/pb2.Nested",
Joe Tsai6dc168e2019-07-09 23:11:13 -07001204 Value: []byte("\x80"),
Herbie Ong300cff02019-03-20 18:05:16 -07001205 },
Herbie Ong66c365c2019-01-04 14:08:41 -08001206 want: `type_url: "foo/pb2.Nested"
Herbie Onga94f78c2019-01-03 15:39:58 -08001207value: "\x80"
1208`,
Herbie Ongcddf8192018-11-28 18:25:20 -08001209 }}
1210
1211 for _, tt := range tests {
1212 tt := tt
Joe Tsai5ae10aa2019-07-11 18:23:08 -07001213 if tt.skip {
1214 continue
1215 }
Herbie Ongcddf8192018-11-28 18:25:20 -08001216 t.Run(tt.desc, func(t *testing.T) {
Herbie Ong3a385912019-03-20 14:04:24 -07001217 // Use 2-space indentation on all MarshalOptions.
1218 tt.mo.Indent = " "
Herbie Ongf42b55f2019-01-02 15:46:07 -08001219 b, err := tt.mo.Marshal(tt.input)
Herbie Ongcddf8192018-11-28 18:25:20 -08001220 if err != nil && !tt.wantErr {
Herbie Ongf42b55f2019-01-02 15:46:07 -08001221 t.Errorf("Marshal() returned error: %v\n", err)
Herbie Ongcddf8192018-11-28 18:25:20 -08001222 }
Herbie Ong800c9902018-12-06 15:28:53 -08001223 if err == nil && tt.wantErr {
Herbie Ongf42b55f2019-01-02 15:46:07 -08001224 t.Error("Marshal() got nil error, want error\n")
Herbie Ongcddf8192018-11-28 18:25:20 -08001225 }
Herbie Ong800c9902018-12-06 15:28:53 -08001226 got := string(b)
1227 if tt.want != "" && got != tt.want {
1228 t.Errorf("Marshal()\n<got>\n%v\n<want>\n%v\n", got, tt.want)
Joe Tsai378c1322019-04-25 23:48:08 -07001229 if diff := cmp.Diff(tt.want, got); diff != "" {
Herbie Ongcddf8192018-11-28 18:25:20 -08001230 t.Errorf("Marshal() diff -want +got\n%v\n", diff)
1231 }
1232 }
1233 })
1234 }
1235}