blob: ba4aa51bebff4a7036500c9cd4a70be116b8dd2b [file] [log] [blame]
Joe Tsaifa02f4e2018-09-12 16:20:37 -07001// 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
Joe Tsai08e00302018-11-26 22:32:06 -08005package impl_test
Joe Tsaifa02f4e2018-09-12 16:20:37 -07006
7import (
Joe Tsai91e14662018-09-13 13:24:35 -07008 "fmt"
9 "math"
Damien Neil8012b442019-01-18 09:32:24 -080010 "reflect"
Joe Tsai91e14662018-09-13 13:24:35 -070011 "strings"
Joe Tsaifa02f4e2018-09-12 16:20:37 -070012 "testing"
13
Damien Neil204f1c02018-10-23 15:03:38 -070014 protoV1 "github.com/golang/protobuf/proto"
Joe Tsai87b955b2018-11-14 21:59:49 -080015 cmp "github.com/google/go-cmp/cmp"
16 cmpopts "github.com/google/go-cmp/cmp/cmpopts"
Damien Neile89e6242019-05-13 23:55:40 -070017 pimpl "google.golang.org/protobuf/internal/impl"
18 ptype "google.golang.org/protobuf/internal/prototype"
19 scalar "google.golang.org/protobuf/internal/scalar"
20 pvalue "google.golang.org/protobuf/internal/value"
21 pref "google.golang.org/protobuf/reflect/protoreflect"
Joe Tsaifa02f4e2018-09-12 16:20:37 -070022
Damien Neile89e6242019-05-13 23:55:40 -070023 proto2_20180125 "google.golang.org/protobuf/internal/testprotos/legacy/proto2.v1.0.0-20180125-92554152"
Joe Tsaia95b29f2019-05-16 12:47:20 -070024 "google.golang.org/protobuf/types/descriptorpb"
Joe Tsaifa02f4e2018-09-12 16:20:37 -070025)
26
Joe Tsai4b7aff62018-11-14 14:05:19 -080027// List of test operations to perform on messages, lists, or maps.
Joe Tsai91e14662018-09-13 13:24:35 -070028type (
Joe Tsai87b955b2018-11-14 21:59:49 -080029 messageOp interface{ isMessageOp() }
Joe Tsai91e14662018-09-13 13:24:35 -070030 messageOps []messageOp
Joe Tsaifa02f4e2018-09-12 16:20:37 -070031
Joe Tsai87b955b2018-11-14 21:59:49 -080032 listOp interface{ isListOp() }
Joe Tsai4b7aff62018-11-14 14:05:19 -080033 listOps []listOp
Joe Tsai91e14662018-09-13 13:24:35 -070034
Joe Tsai87b955b2018-11-14 21:59:49 -080035 mapOp interface{ isMapOp() }
Joe Tsaibbfaeb72018-10-17 00:27:21 +000036 mapOps []mapOp
Joe Tsai91e14662018-09-13 13:24:35 -070037)
38
39// Test operations performed on a message.
40type (
Joe Tsai87b955b2018-11-14 21:59:49 -080041 // check that the message contents match
42 equalMessage struct{ pref.Message }
43 // check presence for specific fields in the message
44 hasFields map[pref.FieldNumber]bool
45 // check that specific message fields match
46 getFields map[pref.FieldNumber]pref.Value
47 // set specific message fields
48 setFields map[pref.FieldNumber]pref.Value
49 // clear specific fields in the message
50 clearFields []pref.FieldNumber
Joe Tsai4ec39c72019-04-03 13:40:53 -070051 // check for the presence of specific oneof member fields.
52 whichOneofs map[pref.Name]pref.FieldNumber
Joe Tsai87b955b2018-11-14 21:59:49 -080053 // apply messageOps on each specified message field
Joe Tsai91e14662018-09-13 13:24:35 -070054 messageFields map[pref.FieldNumber]messageOps
Joe Tsai87b955b2018-11-14 21:59:49 -080055 // apply listOps on each specified list field
56 listFields map[pref.FieldNumber]listOps
57 // apply mapOps on each specified map fields
58 mapFields map[pref.FieldNumber]mapOps
59 // range through all fields and check that they match
60 rangeFields map[pref.FieldNumber]pref.Value
Joe Tsai91e14662018-09-13 13:24:35 -070061)
62
Joe Tsai87b955b2018-11-14 21:59:49 -080063func (equalMessage) isMessageOp() {}
64func (hasFields) isMessageOp() {}
65func (getFields) isMessageOp() {}
66func (setFields) isMessageOp() {}
67func (clearFields) isMessageOp() {}
Joe Tsai4ec39c72019-04-03 13:40:53 -070068func (whichOneofs) isMessageOp() {}
Joe Tsai87b955b2018-11-14 21:59:49 -080069func (messageFields) isMessageOp() {}
70func (listFields) isMessageOp() {}
71func (mapFields) isMessageOp() {}
72func (rangeFields) isMessageOp() {}
73
Joe Tsai4b7aff62018-11-14 14:05:19 -080074// Test operations performed on a list.
Joe Tsai91e14662018-09-13 13:24:35 -070075type (
Joe Tsai87b955b2018-11-14 21:59:49 -080076 // check that the list contents match
77 equalList struct{ pref.List }
78 // check that list length matches
79 lenList int
80 // check that specific list entries match
81 getList map[int]pref.Value
82 // set specific list entries
83 setList map[int]pref.Value
84 // append entries to the list
Joe Tsai4b7aff62018-11-14 14:05:19 -080085 appendList []pref.Value
Joe Tsai87b955b2018-11-14 21:59:49 -080086 // apply messageOps on a newly appended message
87 appendMessageList messageOps
88 // truncate the list to the specified length
89 truncList int
Joe Tsai91e14662018-09-13 13:24:35 -070090)
91
Joe Tsai87b955b2018-11-14 21:59:49 -080092func (equalList) isListOp() {}
93func (lenList) isListOp() {}
94func (getList) isListOp() {}
95func (setList) isListOp() {}
96func (appendList) isListOp() {}
97func (appendMessageList) isListOp() {}
98func (truncList) isListOp() {}
99
Joe Tsaibbfaeb72018-10-17 00:27:21 +0000100// Test operations performed on a map.
101type (
Joe Tsai87b955b2018-11-14 21:59:49 -0800102 // check that the map contents match
103 equalMap struct{ pref.Map }
104 // check that map length matches
105 lenMap int
106 // check presence for specific entries in the map
107 hasMap map[interface{}]bool
108 // check that specific map entries match
109 getMap map[interface{}]pref.Value
110 // set specific map entries
111 setMap map[interface{}]pref.Value
112 // clear specific entries in the map
113 clearMap []interface{}
114 // apply messageOps on each specified message entry
115 messageMap map[interface{}]messageOps
116 // range through all entries and check that they match
Joe Tsaibbfaeb72018-10-17 00:27:21 +0000117 rangeMap map[interface{}]pref.Value
Joe Tsaibbfaeb72018-10-17 00:27:21 +0000118)
119
Joe Tsai87b955b2018-11-14 21:59:49 -0800120func (equalMap) isMapOp() {}
121func (lenMap) isMapOp() {}
122func (hasMap) isMapOp() {}
123func (getMap) isMapOp() {}
124func (setMap) isMapOp() {}
125func (clearMap) isMapOp() {}
126func (messageMap) isMapOp() {}
127func (rangeMap) isMapOp() {}
128
Joe Tsaice6edd32018-10-19 16:27:46 -0700129type ScalarProto2 struct {
130 Bool *bool `protobuf:"1"`
131 Int32 *int32 `protobuf:"2"`
132 Int64 *int64 `protobuf:"3"`
133 Uint32 *uint32 `protobuf:"4"`
134 Uint64 *uint64 `protobuf:"5"`
135 Float32 *float32 `protobuf:"6"`
136 Float64 *float64 `protobuf:"7"`
137 String *string `protobuf:"8"`
138 StringA []byte `protobuf:"9"`
139 Bytes []byte `protobuf:"10"`
140 BytesA *string `protobuf:"11"`
141
142 MyBool *MyBool `protobuf:"12"`
143 MyInt32 *MyInt32 `protobuf:"13"`
144 MyInt64 *MyInt64 `protobuf:"14"`
145 MyUint32 *MyUint32 `protobuf:"15"`
146 MyUint64 *MyUint64 `protobuf:"16"`
147 MyFloat32 *MyFloat32 `protobuf:"17"`
148 MyFloat64 *MyFloat64 `protobuf:"18"`
149 MyString *MyString `protobuf:"19"`
150 MyStringA MyBytes `protobuf:"20"`
151 MyBytes MyBytes `protobuf:"21"`
152 MyBytesA *MyString `protobuf:"22"`
153}
154
Joe Tsai87b955b2018-11-14 21:59:49 -0800155func mustMakeEnumDesc(t ptype.StandaloneEnum) pref.EnumDescriptor {
156 ed, err := ptype.NewEnum(&t)
157 if err != nil {
158 panic(err)
159 }
160 return ed
161}
162
163func mustMakeMessageDesc(t ptype.StandaloneMessage) pref.MessageDescriptor {
164 md, err := ptype.NewMessage(&t)
165 if err != nil {
166 panic(err)
167 }
168 return md
169}
170
171var V = pref.ValueOf
172var VE = func(n pref.EnumNumber) pref.Value { return V(n) }
173
174type (
175 MyBool bool
176 MyInt32 int32
177 MyInt64 int64
178 MyUint32 uint32
179 MyUint64 uint64
180 MyFloat32 float32
181 MyFloat64 float64
182 MyString string
183 MyBytes []byte
184
185 ListStrings []MyString
186 ListBytes []MyBytes
187
188 MapStrings map[MyString]MyString
189 MapBytes map[MyString]MyBytes
190)
191
Damien Neil8012b442019-01-18 09:32:24 -0800192var scalarProto2Type = pimpl.MessageType{GoType: reflect.TypeOf(new(ScalarProto2)), PBType: ptype.GoMessage(
Joe Tsaif0c01e42018-11-06 13:05:20 -0800193 mustMakeMessageDesc(ptype.StandaloneMessage{
Joe Tsai91e14662018-09-13 13:24:35 -0700194 Syntax: pref.Proto2,
195 FullName: "ScalarProto2",
196 Fields: []ptype.Field{
197 {Name: "f1", Number: 1, Cardinality: pref.Optional, Kind: pref.BoolKind, Default: V(bool(true))},
198 {Name: "f2", Number: 2, Cardinality: pref.Optional, Kind: pref.Int32Kind, Default: V(int32(2))},
199 {Name: "f3", Number: 3, Cardinality: pref.Optional, Kind: pref.Int64Kind, Default: V(int64(3))},
200 {Name: "f4", Number: 4, Cardinality: pref.Optional, Kind: pref.Uint32Kind, Default: V(uint32(4))},
201 {Name: "f5", Number: 5, Cardinality: pref.Optional, Kind: pref.Uint64Kind, Default: V(uint64(5))},
202 {Name: "f6", Number: 6, Cardinality: pref.Optional, Kind: pref.FloatKind, Default: V(float32(6))},
203 {Name: "f7", Number: 7, Cardinality: pref.Optional, Kind: pref.DoubleKind, Default: V(float64(7))},
204 {Name: "f8", Number: 8, Cardinality: pref.Optional, Kind: pref.StringKind, Default: V(string("8"))},
205 {Name: "f9", Number: 9, Cardinality: pref.Optional, Kind: pref.StringKind, Default: V(string("9"))},
206 {Name: "f10", Number: 10, Cardinality: pref.Optional, Kind: pref.BytesKind, Default: V([]byte("10"))},
207 {Name: "f11", Number: 11, Cardinality: pref.Optional, Kind: pref.BytesKind, Default: V([]byte("11"))},
208
209 {Name: "f12", Number: 12, Cardinality: pref.Optional, Kind: pref.BoolKind, Default: V(bool(true))},
210 {Name: "f13", Number: 13, Cardinality: pref.Optional, Kind: pref.Int32Kind, Default: V(int32(13))},
211 {Name: "f14", Number: 14, Cardinality: pref.Optional, Kind: pref.Int64Kind, Default: V(int64(14))},
212 {Name: "f15", Number: 15, Cardinality: pref.Optional, Kind: pref.Uint32Kind, Default: V(uint32(15))},
213 {Name: "f16", Number: 16, Cardinality: pref.Optional, Kind: pref.Uint64Kind, Default: V(uint64(16))},
214 {Name: "f17", Number: 17, Cardinality: pref.Optional, Kind: pref.FloatKind, Default: V(float32(17))},
215 {Name: "f18", Number: 18, Cardinality: pref.Optional, Kind: pref.DoubleKind, Default: V(float64(18))},
216 {Name: "f19", Number: 19, Cardinality: pref.Optional, Kind: pref.StringKind, Default: V(string("19"))},
217 {Name: "f20", Number: 20, Cardinality: pref.Optional, Kind: pref.StringKind, Default: V(string("20"))},
218 {Name: "f21", Number: 21, Cardinality: pref.Optional, Kind: pref.BytesKind, Default: V([]byte("21"))},
219 {Name: "f22", Number: 22, Cardinality: pref.Optional, Kind: pref.BytesKind, Default: V([]byte("22"))},
220 },
Joe Tsaif0c01e42018-11-06 13:05:20 -0800221 }),
Joe Tsai3bc7d6f2019-01-09 02:57:13 -0800222 func(pref.MessageType) pref.Message {
Joe Tsaif0c01e42018-11-06 13:05:20 -0800223 return new(ScalarProto2)
224 },
225)}
Joe Tsai91e14662018-09-13 13:24:35 -0700226
Joe Tsai0fc49f82019-05-01 12:29:25 -0700227// TODO: Remove this.
Damien Neil374cdb82019-01-29 16:45:30 -0800228func (m *ScalarProto2) Type() pref.MessageType { return scalarProto2Type.PBType }
Joe Tsai0fc49f82019-05-01 12:29:25 -0700229func (m *ScalarProto2) Descriptor() pref.MessageDescriptor {
230 return scalarProto2Type.PBType.Descriptor()
231}
Damien Neil374cdb82019-01-29 16:45:30 -0800232func (m *ScalarProto2) KnownFields() pref.KnownFields {
233 return scalarProto2Type.MessageOf(m).KnownFields()
234}
235func (m *ScalarProto2) UnknownFields() pref.UnknownFields {
236 return scalarProto2Type.MessageOf(m).UnknownFields()
237}
Joe Tsai0fc49f82019-05-01 12:29:25 -0700238func (m *ScalarProto2) New() pref.Message { return new(ScalarProto2) }
Damien Neil374cdb82019-01-29 16:45:30 -0800239func (m *ScalarProto2) Interface() pref.ProtoMessage { return m }
240func (m *ScalarProto2) ProtoReflect() pref.Message { return m }
Joe Tsaif0c01e42018-11-06 13:05:20 -0800241
242func TestScalarProto2(t *testing.T) {
243 testMessage(t, nil, &ScalarProto2{}, messageOps{
Joe Tsai91e14662018-09-13 13:24:35 -0700244 hasFields{
245 1: false, 2: false, 3: false, 4: false, 5: false, 6: false, 7: false, 8: false, 9: false, 10: false, 11: false,
246 12: false, 13: false, 14: false, 15: false, 16: false, 17: false, 18: false, 19: false, 20: false, 21: false, 22: false,
247 },
248 getFields{
249 1: V(bool(true)), 2: V(int32(2)), 3: V(int64(3)), 4: V(uint32(4)), 5: V(uint64(5)), 6: V(float32(6)), 7: V(float64(7)), 8: V(string("8")), 9: V(string("9")), 10: V([]byte("10")), 11: V([]byte("11")),
250 12: V(bool(true)), 13: V(int32(13)), 14: V(int64(14)), 15: V(uint32(15)), 16: V(uint64(16)), 17: V(float32(17)), 18: V(float64(18)), 19: V(string("19")), 20: V(string("20")), 21: V([]byte("21")), 22: V([]byte("22")),
251 },
252 setFields{
253 1: V(bool(false)), 2: V(int32(0)), 3: V(int64(0)), 4: V(uint32(0)), 5: V(uint64(0)), 6: V(float32(0)), 7: V(float64(0)), 8: V(string("")), 9: V(string("")), 10: V([]byte(nil)), 11: V([]byte(nil)),
254 12: V(bool(false)), 13: V(int32(0)), 14: V(int64(0)), 15: V(uint32(0)), 16: V(uint64(0)), 17: V(float32(0)), 18: V(float64(0)), 19: V(string("")), 20: V(string("")), 21: V([]byte(nil)), 22: V([]byte(nil)),
255 },
256 hasFields{
257 1: true, 2: true, 3: true, 4: true, 5: true, 6: true, 7: true, 8: true, 9: true, 10: true, 11: true,
258 12: true, 13: true, 14: true, 15: true, 16: true, 17: true, 18: true, 19: true, 20: true, 21: true, 22: true,
259 },
Joe Tsai87b955b2018-11-14 21:59:49 -0800260 equalMessage{&ScalarProto2{
Joe Tsai91e14662018-09-13 13:24:35 -0700261 new(bool), new(int32), new(int64), new(uint32), new(uint64), new(float32), new(float64), new(string), []byte{}, []byte{}, new(string),
262 new(MyBool), new(MyInt32), new(MyInt64), new(MyUint32), new(MyUint64), new(MyFloat32), new(MyFloat64), new(MyString), MyBytes{}, MyBytes{}, new(MyString),
Joe Tsai87b955b2018-11-14 21:59:49 -0800263 }},
264 clearFields{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22},
265 equalMessage{&ScalarProto2{}},
Joe Tsai91e14662018-09-13 13:24:35 -0700266 })
Joe Tsai6cf80c42018-12-01 04:57:09 -0800267
268 // Test read-only operations on nil message.
269 testMessage(t, nil, (*ScalarProto2)(nil), messageOps{
270 hasFields{
271 1: false, 2: false, 3: false, 4: false, 5: false, 6: false, 7: false, 8: false, 9: false, 10: false, 11: false,
272 12: false, 13: false, 14: false, 15: false, 16: false, 17: false, 18: false, 19: false, 20: false, 21: false, 22: false,
273 },
274 getFields{
275 1: V(bool(true)), 2: V(int32(2)), 3: V(int64(3)), 4: V(uint32(4)), 5: V(uint64(5)), 6: V(float32(6)), 7: V(float64(7)), 8: V(string("8")), 9: V(string("9")), 10: V([]byte("10")), 11: V([]byte("11")),
276 12: V(bool(true)), 13: V(int32(13)), 14: V(int64(14)), 15: V(uint32(15)), 16: V(uint64(16)), 17: V(float32(17)), 18: V(float64(18)), 19: V(string("19")), 20: V(string("20")), 21: V([]byte("21")), 22: V([]byte("22")),
277 },
278 })
Joe Tsaifa02f4e2018-09-12 16:20:37 -0700279}
280
Joe Tsaice6edd32018-10-19 16:27:46 -0700281type ScalarProto3 struct {
282 Bool bool `protobuf:"1"`
283 Int32 int32 `protobuf:"2"`
284 Int64 int64 `protobuf:"3"`
285 Uint32 uint32 `protobuf:"4"`
286 Uint64 uint64 `protobuf:"5"`
287 Float32 float32 `protobuf:"6"`
288 Float64 float64 `protobuf:"7"`
289 String string `protobuf:"8"`
290 StringA []byte `protobuf:"9"`
291 Bytes []byte `protobuf:"10"`
292 BytesA string `protobuf:"11"`
293
294 MyBool MyBool `protobuf:"12"`
295 MyInt32 MyInt32 `protobuf:"13"`
296 MyInt64 MyInt64 `protobuf:"14"`
297 MyUint32 MyUint32 `protobuf:"15"`
298 MyUint64 MyUint64 `protobuf:"16"`
299 MyFloat32 MyFloat32 `protobuf:"17"`
300 MyFloat64 MyFloat64 `protobuf:"18"`
301 MyString MyString `protobuf:"19"`
302 MyStringA MyBytes `protobuf:"20"`
303 MyBytes MyBytes `protobuf:"21"`
304 MyBytesA MyString `protobuf:"22"`
305}
306
Damien Neil8012b442019-01-18 09:32:24 -0800307var scalarProto3Type = pimpl.MessageType{GoType: reflect.TypeOf(new(ScalarProto3)), PBType: ptype.GoMessage(
Joe Tsaif0c01e42018-11-06 13:05:20 -0800308 mustMakeMessageDesc(ptype.StandaloneMessage{
Joe Tsai91e14662018-09-13 13:24:35 -0700309 Syntax: pref.Proto3,
310 FullName: "ScalarProto3",
311 Fields: []ptype.Field{
312 {Name: "f1", Number: 1, Cardinality: pref.Optional, Kind: pref.BoolKind},
313 {Name: "f2", Number: 2, Cardinality: pref.Optional, Kind: pref.Int32Kind},
314 {Name: "f3", Number: 3, Cardinality: pref.Optional, Kind: pref.Int64Kind},
315 {Name: "f4", Number: 4, Cardinality: pref.Optional, Kind: pref.Uint32Kind},
316 {Name: "f5", Number: 5, Cardinality: pref.Optional, Kind: pref.Uint64Kind},
317 {Name: "f6", Number: 6, Cardinality: pref.Optional, Kind: pref.FloatKind},
318 {Name: "f7", Number: 7, Cardinality: pref.Optional, Kind: pref.DoubleKind},
319 {Name: "f8", Number: 8, Cardinality: pref.Optional, Kind: pref.StringKind},
320 {Name: "f9", Number: 9, Cardinality: pref.Optional, Kind: pref.StringKind},
321 {Name: "f10", Number: 10, Cardinality: pref.Optional, Kind: pref.BytesKind},
322 {Name: "f11", Number: 11, Cardinality: pref.Optional, Kind: pref.BytesKind},
Joe Tsaifa02f4e2018-09-12 16:20:37 -0700323
Joe Tsai91e14662018-09-13 13:24:35 -0700324 {Name: "f12", Number: 12, Cardinality: pref.Optional, Kind: pref.BoolKind},
325 {Name: "f13", Number: 13, Cardinality: pref.Optional, Kind: pref.Int32Kind},
326 {Name: "f14", Number: 14, Cardinality: pref.Optional, Kind: pref.Int64Kind},
327 {Name: "f15", Number: 15, Cardinality: pref.Optional, Kind: pref.Uint32Kind},
328 {Name: "f16", Number: 16, Cardinality: pref.Optional, Kind: pref.Uint64Kind},
329 {Name: "f17", Number: 17, Cardinality: pref.Optional, Kind: pref.FloatKind},
330 {Name: "f18", Number: 18, Cardinality: pref.Optional, Kind: pref.DoubleKind},
331 {Name: "f19", Number: 19, Cardinality: pref.Optional, Kind: pref.StringKind},
332 {Name: "f20", Number: 20, Cardinality: pref.Optional, Kind: pref.StringKind},
333 {Name: "f21", Number: 21, Cardinality: pref.Optional, Kind: pref.BytesKind},
334 {Name: "f22", Number: 22, Cardinality: pref.Optional, Kind: pref.BytesKind},
335 },
Joe Tsaif0c01e42018-11-06 13:05:20 -0800336 }),
Joe Tsai3bc7d6f2019-01-09 02:57:13 -0800337 func(pref.MessageType) pref.Message {
Joe Tsaif0c01e42018-11-06 13:05:20 -0800338 return new(ScalarProto3)
339 },
340)}
Joe Tsai91e14662018-09-13 13:24:35 -0700341
Joe Tsai0fc49f82019-05-01 12:29:25 -0700342// TODO: Remove this.
Damien Neil374cdb82019-01-29 16:45:30 -0800343func (m *ScalarProto3) Type() pref.MessageType { return scalarProto3Type.PBType }
Joe Tsai0fc49f82019-05-01 12:29:25 -0700344func (m *ScalarProto3) Descriptor() pref.MessageDescriptor {
345 return scalarProto3Type.PBType.Descriptor()
346}
Damien Neil374cdb82019-01-29 16:45:30 -0800347func (m *ScalarProto3) KnownFields() pref.KnownFields {
348 return scalarProto3Type.MessageOf(m).KnownFields()
349}
350func (m *ScalarProto3) UnknownFields() pref.UnknownFields {
351 return scalarProto3Type.MessageOf(m).UnknownFields()
352}
Joe Tsai0fc49f82019-05-01 12:29:25 -0700353func (m *ScalarProto3) New() pref.Message { return new(ScalarProto3) }
Damien Neil374cdb82019-01-29 16:45:30 -0800354func (m *ScalarProto3) Interface() pref.ProtoMessage { return m }
355func (m *ScalarProto3) ProtoReflect() pref.Message { return m }
Joe Tsaif0c01e42018-11-06 13:05:20 -0800356
357func TestScalarProto3(t *testing.T) {
358 testMessage(t, nil, &ScalarProto3{}, messageOps{
Joe Tsai91e14662018-09-13 13:24:35 -0700359 hasFields{
360 1: false, 2: false, 3: false, 4: false, 5: false, 6: false, 7: false, 8: false, 9: false, 10: false, 11: false,
361 12: false, 13: false, 14: false, 15: false, 16: false, 17: false, 18: false, 19: false, 20: false, 21: false, 22: false,
362 },
363 getFields{
364 1: V(bool(false)), 2: V(int32(0)), 3: V(int64(0)), 4: V(uint32(0)), 5: V(uint64(0)), 6: V(float32(0)), 7: V(float64(0)), 8: V(string("")), 9: V(string("")), 10: V([]byte(nil)), 11: V([]byte(nil)),
365 12: V(bool(false)), 13: V(int32(0)), 14: V(int64(0)), 15: V(uint32(0)), 16: V(uint64(0)), 17: V(float32(0)), 18: V(float64(0)), 19: V(string("")), 20: V(string("")), 21: V([]byte(nil)), 22: V([]byte(nil)),
366 },
367 setFields{
368 1: V(bool(false)), 2: V(int32(0)), 3: V(int64(0)), 4: V(uint32(0)), 5: V(uint64(0)), 6: V(float32(0)), 7: V(float64(0)), 8: V(string("")), 9: V(string("")), 10: V([]byte(nil)), 11: V([]byte(nil)),
369 12: V(bool(false)), 13: V(int32(0)), 14: V(int64(0)), 15: V(uint32(0)), 16: V(uint64(0)), 17: V(float32(0)), 18: V(float64(0)), 19: V(string("")), 20: V(string("")), 21: V([]byte(nil)), 22: V([]byte(nil)),
370 },
371 hasFields{
372 1: false, 2: false, 3: false, 4: false, 5: false, 6: false, 7: false, 8: false, 9: false, 10: false, 11: false,
373 12: false, 13: false, 14: false, 15: false, 16: false, 17: false, 18: false, 19: false, 20: false, 21: false, 22: false,
374 },
Joe Tsai87b955b2018-11-14 21:59:49 -0800375 equalMessage{&ScalarProto3{}},
Joe Tsai91e14662018-09-13 13:24:35 -0700376 setFields{
377 1: V(bool(true)), 2: V(int32(2)), 3: V(int64(3)), 4: V(uint32(4)), 5: V(uint64(5)), 6: V(float32(6)), 7: V(float64(7)), 8: V(string("8")), 9: V(string("9")), 10: V([]byte("10")), 11: V([]byte("11")),
378 12: V(bool(true)), 13: V(int32(13)), 14: V(int64(14)), 15: V(uint32(15)), 16: V(uint64(16)), 17: V(float32(17)), 18: V(float64(18)), 19: V(string("19")), 20: V(string("20")), 21: V([]byte("21")), 22: V([]byte("22")),
379 },
380 hasFields{
381 1: true, 2: true, 3: true, 4: true, 5: true, 6: true, 7: true, 8: true, 9: true, 10: true, 11: true,
382 12: true, 13: true, 14: true, 15: true, 16: true, 17: true, 18: true, 19: true, 20: true, 21: true, 22: true,
383 },
Joe Tsai87b955b2018-11-14 21:59:49 -0800384 equalMessage{&ScalarProto3{
Joe Tsai91e14662018-09-13 13:24:35 -0700385 true, 2, 3, 4, 5, 6, 7, "8", []byte("9"), []byte("10"), "11",
386 true, 13, 14, 15, 16, 17, 18, "19", []byte("20"), []byte("21"), "22",
Joe Tsai87b955b2018-11-14 21:59:49 -0800387 }},
Joe Tsai44e389c2018-11-19 15:27:09 -0800388 setFields{
389 2: V(int32(-2)), 3: V(int64(-3)), 6: V(float32(math.Inf(-1))), 7: V(float64(math.NaN())),
390 },
391 hasFields{
392 2: true, 3: true, 6: true, 7: true,
393 },
Joe Tsai87b955b2018-11-14 21:59:49 -0800394 clearFields{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22},
395 equalMessage{&ScalarProto3{}},
Joe Tsai060cdac2019-04-22 11:44:49 -0700396
397 // Verify that -0 triggers proper Has behavior.
398 hasFields{6: false, 7: false},
399 setFields{6: V(float32(math.Copysign(0, -1))), 7: V(float64(math.Copysign(0, -1)))},
400 hasFields{6: true, 7: true},
Joe Tsai91e14662018-09-13 13:24:35 -0700401 })
Joe Tsai6cf80c42018-12-01 04:57:09 -0800402
403 // Test read-only operations on nil message.
404 testMessage(t, nil, (*ScalarProto3)(nil), messageOps{
405 hasFields{
406 1: false, 2: false, 3: false, 4: false, 5: false, 6: false, 7: false, 8: false, 9: false, 10: false, 11: false,
407 12: false, 13: false, 14: false, 15: false, 16: false, 17: false, 18: false, 19: false, 20: false, 21: false, 22: false,
408 },
409 getFields{
410 1: V(bool(false)), 2: V(int32(0)), 3: V(int64(0)), 4: V(uint32(0)), 5: V(uint64(0)), 6: V(float32(0)), 7: V(float64(0)), 8: V(string("")), 9: V(string("")), 10: V([]byte(nil)), 11: V([]byte(nil)),
411 12: V(bool(false)), 13: V(int32(0)), 14: V(int64(0)), 15: V(uint32(0)), 16: V(uint64(0)), 17: V(float32(0)), 18: V(float64(0)), 19: V(string("")), 20: V(string("")), 21: V([]byte(nil)), 22: V([]byte(nil)),
412 },
413 })
Joe Tsaifa02f4e2018-09-12 16:20:37 -0700414}
415
Joe Tsaif0c01e42018-11-06 13:05:20 -0800416type ListScalars struct {
Joe Tsaice6edd32018-10-19 16:27:46 -0700417 Bools []bool `protobuf:"1"`
418 Int32s []int32 `protobuf:"2"`
419 Int64s []int64 `protobuf:"3"`
420 Uint32s []uint32 `protobuf:"4"`
421 Uint64s []uint64 `protobuf:"5"`
422 Float32s []float32 `protobuf:"6"`
423 Float64s []float64 `protobuf:"7"`
424 Strings []string `protobuf:"8"`
425 StringsA [][]byte `protobuf:"9"`
426 Bytes [][]byte `protobuf:"10"`
427 BytesA []string `protobuf:"11"`
428
429 MyStrings1 []MyString `protobuf:"12"`
430 MyStrings2 []MyBytes `protobuf:"13"`
431 MyBytes1 []MyBytes `protobuf:"14"`
432 MyBytes2 []MyString `protobuf:"15"`
433
Joe Tsai4b7aff62018-11-14 14:05:19 -0800434 MyStrings3 ListStrings `protobuf:"16"`
435 MyStrings4 ListBytes `protobuf:"17"`
436 MyBytes3 ListBytes `protobuf:"18"`
437 MyBytes4 ListStrings `protobuf:"19"`
Joe Tsaice6edd32018-10-19 16:27:46 -0700438}
439
Damien Neil8012b442019-01-18 09:32:24 -0800440var listScalarsType = pimpl.MessageType{GoType: reflect.TypeOf(new(ListScalars)), PBType: ptype.GoMessage(
Joe Tsaif0c01e42018-11-06 13:05:20 -0800441 mustMakeMessageDesc(ptype.StandaloneMessage{
Joe Tsai91e14662018-09-13 13:24:35 -0700442 Syntax: pref.Proto2,
Joe Tsaif0c01e42018-11-06 13:05:20 -0800443 FullName: "ListScalars",
Joe Tsai91e14662018-09-13 13:24:35 -0700444 Fields: []ptype.Field{
445 {Name: "f1", Number: 1, Cardinality: pref.Repeated, Kind: pref.BoolKind},
446 {Name: "f2", Number: 2, Cardinality: pref.Repeated, Kind: pref.Int32Kind},
447 {Name: "f3", Number: 3, Cardinality: pref.Repeated, Kind: pref.Int64Kind},
448 {Name: "f4", Number: 4, Cardinality: pref.Repeated, Kind: pref.Uint32Kind},
449 {Name: "f5", Number: 5, Cardinality: pref.Repeated, Kind: pref.Uint64Kind},
450 {Name: "f6", Number: 6, Cardinality: pref.Repeated, Kind: pref.FloatKind},
451 {Name: "f7", Number: 7, Cardinality: pref.Repeated, Kind: pref.DoubleKind},
452 {Name: "f8", Number: 8, Cardinality: pref.Repeated, Kind: pref.StringKind},
453 {Name: "f9", Number: 9, Cardinality: pref.Repeated, Kind: pref.StringKind},
454 {Name: "f10", Number: 10, Cardinality: pref.Repeated, Kind: pref.BytesKind},
455 {Name: "f11", Number: 11, Cardinality: pref.Repeated, Kind: pref.BytesKind},
Joe Tsaifa02f4e2018-09-12 16:20:37 -0700456
Joe Tsai91e14662018-09-13 13:24:35 -0700457 {Name: "f12", Number: 12, Cardinality: pref.Repeated, Kind: pref.StringKind},
458 {Name: "f13", Number: 13, Cardinality: pref.Repeated, Kind: pref.StringKind},
459 {Name: "f14", Number: 14, Cardinality: pref.Repeated, Kind: pref.BytesKind},
460 {Name: "f15", Number: 15, Cardinality: pref.Repeated, Kind: pref.BytesKind},
461
462 {Name: "f16", Number: 16, Cardinality: pref.Repeated, Kind: pref.StringKind},
463 {Name: "f17", Number: 17, Cardinality: pref.Repeated, Kind: pref.StringKind},
464 {Name: "f18", Number: 18, Cardinality: pref.Repeated, Kind: pref.BytesKind},
465 {Name: "f19", Number: 19, Cardinality: pref.Repeated, Kind: pref.BytesKind},
Joe Tsaifa02f4e2018-09-12 16:20:37 -0700466 },
Joe Tsaif0c01e42018-11-06 13:05:20 -0800467 }),
Joe Tsai3bc7d6f2019-01-09 02:57:13 -0800468 func(pref.MessageType) pref.Message {
Joe Tsaif0c01e42018-11-06 13:05:20 -0800469 return new(ListScalars)
470 },
471)}
Joe Tsai91e14662018-09-13 13:24:35 -0700472
Joe Tsai0fc49f82019-05-01 12:29:25 -0700473// TODO: Remove this.
474func (m *ListScalars) Type() pref.MessageType { return listScalarsType.PBType }
475func (m *ListScalars) Descriptor() pref.MessageDescriptor { return listScalarsType.PBType.Descriptor() }
Damien Neil374cdb82019-01-29 16:45:30 -0800476func (m *ListScalars) KnownFields() pref.KnownFields {
477 return listScalarsType.MessageOf(m).KnownFields()
478}
479func (m *ListScalars) UnknownFields() pref.UnknownFields {
480 return listScalarsType.MessageOf(m).UnknownFields()
481}
Joe Tsai0fc49f82019-05-01 12:29:25 -0700482func (m *ListScalars) New() pref.Message { return new(ListScalars) }
Damien Neil374cdb82019-01-29 16:45:30 -0800483func (m *ListScalars) Interface() pref.ProtoMessage { return m }
484func (m *ListScalars) ProtoReflect() pref.Message { return m }
Joe Tsaif0c01e42018-11-06 13:05:20 -0800485
486func TestListScalars(t *testing.T) {
487 empty := &ListScalars{}
Joe Tsai91e14662018-09-13 13:24:35 -0700488 emptyFS := empty.KnownFields()
489
Joe Tsaif0c01e42018-11-06 13:05:20 -0800490 want := &ListScalars{
Joe Tsai91e14662018-09-13 13:24:35 -0700491 Bools: []bool{true, false, true},
492 Int32s: []int32{2, math.MinInt32, math.MaxInt32},
493 Int64s: []int64{3, math.MinInt64, math.MaxInt64},
494 Uint32s: []uint32{4, math.MaxUint32 / 2, math.MaxUint32},
495 Uint64s: []uint64{5, math.MaxUint64 / 2, math.MaxUint64},
496 Float32s: []float32{6, math.SmallestNonzeroFloat32, float32(math.NaN()), math.MaxFloat32},
497 Float64s: []float64{7, math.SmallestNonzeroFloat64, float64(math.NaN()), math.MaxFloat64},
498 Strings: []string{"8", "", "eight"},
499 StringsA: [][]byte{[]byte("9"), nil, []byte("nine")},
500 Bytes: [][]byte{[]byte("10"), nil, []byte("ten")},
501 BytesA: []string{"11", "", "eleven"},
502
503 MyStrings1: []MyString{"12", "", "twelve"},
504 MyStrings2: []MyBytes{[]byte("13"), nil, []byte("thirteen")},
505 MyBytes1: []MyBytes{[]byte("14"), nil, []byte("fourteen")},
506 MyBytes2: []MyString{"15", "", "fifteen"},
507
Joe Tsai4b7aff62018-11-14 14:05:19 -0800508 MyStrings3: ListStrings{"16", "", "sixteen"},
509 MyStrings4: ListBytes{[]byte("17"), nil, []byte("seventeen")},
510 MyBytes3: ListBytes{[]byte("18"), nil, []byte("eighteen")},
511 MyBytes4: ListStrings{"19", "", "nineteen"},
Joe Tsaif0c01e42018-11-06 13:05:20 -0800512 }
Joe Tsai91e14662018-09-13 13:24:35 -0700513 wantFS := want.KnownFields()
514
Joe Tsaif0c01e42018-11-06 13:05:20 -0800515 testMessage(t, nil, &ListScalars{}, messageOps{
Joe Tsai91e14662018-09-13 13:24:35 -0700516 hasFields{1: false, 2: false, 3: false, 4: false, 5: false, 6: false, 7: false, 8: false, 9: false, 10: false, 11: false, 12: false, 13: false, 14: false, 15: false, 16: false, 17: false, 18: false, 19: false},
517 getFields{1: emptyFS.Get(1), 3: emptyFS.Get(3), 5: emptyFS.Get(5), 7: emptyFS.Get(7), 9: emptyFS.Get(9), 11: emptyFS.Get(11), 13: emptyFS.Get(13), 15: emptyFS.Get(15), 17: emptyFS.Get(17), 19: emptyFS.Get(19)},
518 setFields{1: wantFS.Get(1), 3: wantFS.Get(3), 5: wantFS.Get(5), 7: wantFS.Get(7), 9: wantFS.Get(9), 11: wantFS.Get(11), 13: wantFS.Get(13), 15: wantFS.Get(15), 17: wantFS.Get(17), 19: wantFS.Get(19)},
Joe Tsai4b7aff62018-11-14 14:05:19 -0800519 listFields{
Joe Tsai91e14662018-09-13 13:24:35 -0700520 2: {
Joe Tsai4b7aff62018-11-14 14:05:19 -0800521 lenList(0),
522 appendList{V(int32(2)), V(int32(math.MinInt32)), V(int32(math.MaxInt32))},
523 getList{0: V(int32(2)), 1: V(int32(math.MinInt32)), 2: V(int32(math.MaxInt32))},
Joe Tsai87b955b2018-11-14 21:59:49 -0800524 equalList{wantFS.Get(2).List()},
Joe Tsai91e14662018-09-13 13:24:35 -0700525 },
526 4: {
Joe Tsai4b7aff62018-11-14 14:05:19 -0800527 appendList{V(uint32(0)), V(uint32(0)), V(uint32(0))},
528 setList{0: V(uint32(4)), 1: V(uint32(math.MaxUint32 / 2)), 2: V(uint32(math.MaxUint32))},
529 lenList(3),
Joe Tsai91e14662018-09-13 13:24:35 -0700530 },
531 6: {
Joe Tsai4b7aff62018-11-14 14:05:19 -0800532 appendList{V(float32(6)), V(float32(math.SmallestNonzeroFloat32)), V(float32(math.NaN())), V(float32(math.MaxFloat32))},
Joe Tsai87b955b2018-11-14 21:59:49 -0800533 equalList{wantFS.Get(6).List()},
Joe Tsai91e14662018-09-13 13:24:35 -0700534 },
535 8: {
Joe Tsai4b7aff62018-11-14 14:05:19 -0800536 appendList{V(""), V(""), V(""), V(""), V(""), V("")},
537 lenList(6),
538 setList{0: V("8"), 2: V("eight")},
539 truncList(3),
Joe Tsai87b955b2018-11-14 21:59:49 -0800540 equalList{wantFS.Get(8).List()},
Joe Tsai91e14662018-09-13 13:24:35 -0700541 },
542 10: {
Joe Tsai4b7aff62018-11-14 14:05:19 -0800543 appendList{V([]byte(nil)), V([]byte(nil))},
544 setList{0: V([]byte("10"))},
545 appendList{V([]byte("wrong"))},
546 setList{2: V([]byte("ten"))},
Joe Tsai87b955b2018-11-14 21:59:49 -0800547 equalList{wantFS.Get(10).List()},
Joe Tsai91e14662018-09-13 13:24:35 -0700548 },
549 12: {
Joe Tsai4b7aff62018-11-14 14:05:19 -0800550 appendList{V("12"), V("wrong"), V("twelve")},
551 setList{1: V("")},
Joe Tsai87b955b2018-11-14 21:59:49 -0800552 equalList{wantFS.Get(12).List()},
Joe Tsai91e14662018-09-13 13:24:35 -0700553 },
554 14: {
Joe Tsai4b7aff62018-11-14 14:05:19 -0800555 appendList{V([]byte("14")), V([]byte(nil)), V([]byte("fourteen"))},
Joe Tsai87b955b2018-11-14 21:59:49 -0800556 equalList{wantFS.Get(14).List()},
Joe Tsai91e14662018-09-13 13:24:35 -0700557 },
558 16: {
Joe Tsai4b7aff62018-11-14 14:05:19 -0800559 appendList{V("16"), V(""), V("sixteen"), V("extra")},
560 truncList(3),
Joe Tsai87b955b2018-11-14 21:59:49 -0800561 equalList{wantFS.Get(16).List()},
Joe Tsai91e14662018-09-13 13:24:35 -0700562 },
563 18: {
Joe Tsai4b7aff62018-11-14 14:05:19 -0800564 appendList{V([]byte("18")), V([]byte(nil)), V([]byte("eighteen"))},
Joe Tsai87b955b2018-11-14 21:59:49 -0800565 equalList{wantFS.Get(18).List()},
Joe Tsai91e14662018-09-13 13:24:35 -0700566 },
Joe Tsaifa02f4e2018-09-12 16:20:37 -0700567 },
Joe Tsai91e14662018-09-13 13:24:35 -0700568 hasFields{1: true, 2: true, 3: true, 4: true, 5: true, 6: true, 7: true, 8: true, 9: true, 10: true, 11: true, 12: true, 13: true, 14: true, 15: true, 16: true, 17: true, 18: true, 19: true},
Joe Tsai87b955b2018-11-14 21:59:49 -0800569 equalMessage{want},
570 clearFields{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19},
571 equalMessage{empty},
Joe Tsaibbfaeb72018-10-17 00:27:21 +0000572 })
Joe Tsai6cf80c42018-12-01 04:57:09 -0800573
574 // Test read-only operations on nil message.
575 testMessage(t, nil, (*ListScalars)(nil), messageOps{
576 hasFields{1: false, 2: false, 3: false, 4: false, 5: false, 6: false, 7: false, 8: false, 9: false, 10: false, 11: false, 12: false, 13: false, 14: false, 15: false, 16: false, 17: false, 18: false, 19: false},
577 listFields{2: {lenList(0)}, 4: {lenList(0)}, 6: {lenList(0)}, 8: {lenList(0)}, 10: {lenList(0)}, 12: {lenList(0)}, 14: {lenList(0)}, 16: {lenList(0)}, 18: {lenList(0)}},
578 })
Joe Tsaibbfaeb72018-10-17 00:27:21 +0000579}
580
Joe Tsaice6edd32018-10-19 16:27:46 -0700581type MapScalars struct {
582 KeyBools map[bool]string `protobuf:"1"`
583 KeyInt32s map[int32]string `protobuf:"2"`
584 KeyInt64s map[int64]string `protobuf:"3"`
585 KeyUint32s map[uint32]string `protobuf:"4"`
586 KeyUint64s map[uint64]string `protobuf:"5"`
587 KeyStrings map[string]string `protobuf:"6"`
588
589 ValBools map[string]bool `protobuf:"7"`
590 ValInt32s map[string]int32 `protobuf:"8"`
591 ValInt64s map[string]int64 `protobuf:"9"`
592 ValUint32s map[string]uint32 `protobuf:"10"`
593 ValUint64s map[string]uint64 `protobuf:"11"`
594 ValFloat32s map[string]float32 `protobuf:"12"`
595 ValFloat64s map[string]float64 `protobuf:"13"`
596 ValStrings map[string]string `protobuf:"14"`
597 ValStringsA map[string][]byte `protobuf:"15"`
598 ValBytes map[string][]byte `protobuf:"16"`
599 ValBytesA map[string]string `protobuf:"17"`
600
601 MyStrings1 map[MyString]MyString `protobuf:"18"`
602 MyStrings2 map[MyString]MyBytes `protobuf:"19"`
603 MyBytes1 map[MyString]MyBytes `protobuf:"20"`
604 MyBytes2 map[MyString]MyString `protobuf:"21"`
605
606 MyStrings3 MapStrings `protobuf:"22"`
607 MyStrings4 MapBytes `protobuf:"23"`
608 MyBytes3 MapBytes `protobuf:"24"`
609 MyBytes4 MapStrings `protobuf:"25"`
610}
611
Joe Tsaif0c01e42018-11-06 13:05:20 -0800612func mustMakeMapEntry(n pref.FieldNumber, keyKind, valKind pref.Kind) ptype.Field {
613 return ptype.Field{
614 Name: pref.Name(fmt.Sprintf("f%d", n)),
615 Number: n,
616 Cardinality: pref.Repeated,
617 Kind: pref.MessageKind,
618 MessageType: mustMakeMessageDesc(ptype.StandaloneMessage{
619 Syntax: pref.Proto2,
620 FullName: pref.FullName(fmt.Sprintf("MapScalars.F%dEntry", n)),
621 Fields: []ptype.Field{
622 {Name: "key", Number: 1, Cardinality: pref.Optional, Kind: keyKind},
623 {Name: "value", Number: 2, Cardinality: pref.Optional, Kind: valKind},
624 },
Damien Neil232ea152018-12-10 15:14:36 -0800625 Options: &descriptorpb.MessageOptions{MapEntry: scalar.Bool(true)},
626 IsMapEntry: true,
Joe Tsaif0c01e42018-11-06 13:05:20 -0800627 }),
Joe Tsaibbfaeb72018-10-17 00:27:21 +0000628 }
Joe Tsaif0c01e42018-11-06 13:05:20 -0800629}
630
Damien Neil8012b442019-01-18 09:32:24 -0800631var mapScalarsType = pimpl.MessageType{GoType: reflect.TypeOf(new(MapScalars)), PBType: ptype.GoMessage(
Joe Tsaif0c01e42018-11-06 13:05:20 -0800632 mustMakeMessageDesc(ptype.StandaloneMessage{
Joe Tsaibbfaeb72018-10-17 00:27:21 +0000633 Syntax: pref.Proto2,
634 FullName: "MapScalars",
635 Fields: []ptype.Field{
636 mustMakeMapEntry(1, pref.BoolKind, pref.StringKind),
637 mustMakeMapEntry(2, pref.Int32Kind, pref.StringKind),
638 mustMakeMapEntry(3, pref.Int64Kind, pref.StringKind),
639 mustMakeMapEntry(4, pref.Uint32Kind, pref.StringKind),
640 mustMakeMapEntry(5, pref.Uint64Kind, pref.StringKind),
641 mustMakeMapEntry(6, pref.StringKind, pref.StringKind),
642
643 mustMakeMapEntry(7, pref.StringKind, pref.BoolKind),
644 mustMakeMapEntry(8, pref.StringKind, pref.Int32Kind),
645 mustMakeMapEntry(9, pref.StringKind, pref.Int64Kind),
646 mustMakeMapEntry(10, pref.StringKind, pref.Uint32Kind),
647 mustMakeMapEntry(11, pref.StringKind, pref.Uint64Kind),
648 mustMakeMapEntry(12, pref.StringKind, pref.FloatKind),
649 mustMakeMapEntry(13, pref.StringKind, pref.DoubleKind),
650 mustMakeMapEntry(14, pref.StringKind, pref.StringKind),
651 mustMakeMapEntry(15, pref.StringKind, pref.StringKind),
652 mustMakeMapEntry(16, pref.StringKind, pref.BytesKind),
653 mustMakeMapEntry(17, pref.StringKind, pref.BytesKind),
654
655 mustMakeMapEntry(18, pref.StringKind, pref.StringKind),
656 mustMakeMapEntry(19, pref.StringKind, pref.StringKind),
657 mustMakeMapEntry(20, pref.StringKind, pref.BytesKind),
658 mustMakeMapEntry(21, pref.StringKind, pref.BytesKind),
659
660 mustMakeMapEntry(22, pref.StringKind, pref.StringKind),
661 mustMakeMapEntry(23, pref.StringKind, pref.StringKind),
662 mustMakeMapEntry(24, pref.StringKind, pref.BytesKind),
663 mustMakeMapEntry(25, pref.StringKind, pref.BytesKind),
664 },
Joe Tsaif0c01e42018-11-06 13:05:20 -0800665 }),
Joe Tsai3bc7d6f2019-01-09 02:57:13 -0800666 func(pref.MessageType) pref.Message {
Joe Tsaif0c01e42018-11-06 13:05:20 -0800667 return new(MapScalars)
668 },
669)}
Joe Tsaibbfaeb72018-10-17 00:27:21 +0000670
Joe Tsai0fc49f82019-05-01 12:29:25 -0700671// TODO: Remove this.
672func (m *MapScalars) Type() pref.MessageType { return mapScalarsType.PBType }
673func (m *MapScalars) Descriptor() pref.MessageDescriptor { return mapScalarsType.PBType.Descriptor() }
Damien Neil374cdb82019-01-29 16:45:30 -0800674func (m *MapScalars) KnownFields() pref.KnownFields {
675 return mapScalarsType.MessageOf(m).KnownFields()
676}
677func (m *MapScalars) UnknownFields() pref.UnknownFields {
678 return mapScalarsType.MessageOf(m).UnknownFields()
679}
Joe Tsai0fc49f82019-05-01 12:29:25 -0700680func (m *MapScalars) New() pref.Message { return new(MapScalars) }
Damien Neil374cdb82019-01-29 16:45:30 -0800681func (m *MapScalars) Interface() pref.ProtoMessage { return m }
682func (m *MapScalars) ProtoReflect() pref.Message { return m }
Joe Tsaif0c01e42018-11-06 13:05:20 -0800683
684func TestMapScalars(t *testing.T) {
685 empty := &MapScalars{}
Joe Tsaibbfaeb72018-10-17 00:27:21 +0000686 emptyFS := empty.KnownFields()
687
Joe Tsaif0c01e42018-11-06 13:05:20 -0800688 want := &MapScalars{
Joe Tsaibbfaeb72018-10-17 00:27:21 +0000689 KeyBools: map[bool]string{true: "true", false: "false"},
690 KeyInt32s: map[int32]string{0: "zero", -1: "one", 2: "two"},
691 KeyInt64s: map[int64]string{0: "zero", -10: "ten", 20: "twenty"},
692 KeyUint32s: map[uint32]string{0: "zero", 1: "one", 2: "two"},
693 KeyUint64s: map[uint64]string{0: "zero", 10: "ten", 20: "twenty"},
694 KeyStrings: map[string]string{"": "", "foo": "bar"},
695
696 ValBools: map[string]bool{"true": true, "false": false},
697 ValInt32s: map[string]int32{"one": 1, "two": 2, "three": 3},
698 ValInt64s: map[string]int64{"ten": 10, "twenty": -20, "thirty": 30},
699 ValUint32s: map[string]uint32{"0x00": 0x00, "0xff": 0xff, "0xdead": 0xdead},
700 ValUint64s: map[string]uint64{"0x00": 0x00, "0xff": 0xff, "0xdead": 0xdead},
701 ValFloat32s: map[string]float32{"nan": float32(math.NaN()), "pi": float32(math.Pi)},
702 ValFloat64s: map[string]float64{"nan": float64(math.NaN()), "pi": float64(math.Pi)},
703 ValStrings: map[string]string{"s1": "s1", "s2": "s2"},
704 ValStringsA: map[string][]byte{"s1": []byte("s1"), "s2": []byte("s2")},
705 ValBytes: map[string][]byte{"s1": []byte("s1"), "s2": []byte("s2")},
706 ValBytesA: map[string]string{"s1": "s1", "s2": "s2"},
707
708 MyStrings1: map[MyString]MyString{"s1": "s1", "s2": "s2"},
709 MyStrings2: map[MyString]MyBytes{"s1": []byte("s1"), "s2": []byte("s2")},
710 MyBytes1: map[MyString]MyBytes{"s1": []byte("s1"), "s2": []byte("s2")},
711 MyBytes2: map[MyString]MyString{"s1": "s1", "s2": "s2"},
712
713 MyStrings3: MapStrings{"s1": "s1", "s2": "s2"},
714 MyStrings4: MapBytes{"s1": []byte("s1"), "s2": []byte("s2")},
715 MyBytes3: MapBytes{"s1": []byte("s1"), "s2": []byte("s2")},
716 MyBytes4: MapStrings{"s1": "s1", "s2": "s2"},
Joe Tsaif0c01e42018-11-06 13:05:20 -0800717 }
Joe Tsaibbfaeb72018-10-17 00:27:21 +0000718 wantFS := want.KnownFields()
719
Joe Tsaif0c01e42018-11-06 13:05:20 -0800720 testMessage(t, nil, &MapScalars{}, messageOps{
Joe Tsaibbfaeb72018-10-17 00:27:21 +0000721 hasFields{1: false, 2: false, 3: false, 4: false, 5: false, 6: false, 7: false, 8: false, 9: false, 10: false, 11: false, 12: false, 13: false, 14: false, 15: false, 16: false, 17: false, 18: false, 19: false, 20: false, 21: false, 22: false, 23: false, 24: false, 25: false},
722 getFields{1: emptyFS.Get(1), 3: emptyFS.Get(3), 5: emptyFS.Get(5), 7: emptyFS.Get(7), 9: emptyFS.Get(9), 11: emptyFS.Get(11), 13: emptyFS.Get(13), 15: emptyFS.Get(15), 17: emptyFS.Get(17), 19: emptyFS.Get(19), 21: emptyFS.Get(21), 23: emptyFS.Get(23), 25: emptyFS.Get(25)},
723 setFields{1: wantFS.Get(1), 3: wantFS.Get(3), 5: wantFS.Get(5), 7: wantFS.Get(7), 9: wantFS.Get(9), 11: wantFS.Get(11), 13: wantFS.Get(13), 15: wantFS.Get(15), 17: wantFS.Get(17), 19: wantFS.Get(19), 21: wantFS.Get(21), 23: wantFS.Get(23), 25: wantFS.Get(25)},
724 mapFields{
725 2: {
726 lenMap(0),
727 hasMap{int32(0): false, int32(-1): false, int32(2): false},
728 setMap{int32(0): V("zero")},
729 lenMap(1),
730 hasMap{int32(0): true, int32(-1): false, int32(2): false},
731 setMap{int32(-1): V("one")},
732 lenMap(2),
733 hasMap{int32(0): true, int32(-1): true, int32(2): false},
734 setMap{int32(2): V("two")},
735 lenMap(3),
736 hasMap{int32(0): true, int32(-1): true, int32(2): true},
737 },
738 4: {
739 setMap{uint32(0): V("zero"), uint32(1): V("one"), uint32(2): V("two")},
Joe Tsai87b955b2018-11-14 21:59:49 -0800740 equalMap{wantFS.Get(4).Map()},
Joe Tsaibbfaeb72018-10-17 00:27:21 +0000741 },
742 6: {
Joe Tsai87b955b2018-11-14 21:59:49 -0800743 clearMap{"noexist"},
Joe Tsaibbfaeb72018-10-17 00:27:21 +0000744 setMap{"foo": V("bar")},
745 setMap{"": V("empty")},
746 getMap{"": V("empty"), "foo": V("bar"), "noexist": V(nil)},
747 setMap{"": V(""), "extra": V("extra")},
Joe Tsai87b955b2018-11-14 21:59:49 -0800748 clearMap{"extra", "noexist"},
Joe Tsaibbfaeb72018-10-17 00:27:21 +0000749 },
750 8: {
Joe Tsai87b955b2018-11-14 21:59:49 -0800751 equalMap{emptyFS.Get(8).Map()},
Joe Tsaibbfaeb72018-10-17 00:27:21 +0000752 setMap{"one": V(int32(1)), "two": V(int32(2)), "three": V(int32(3))},
753 },
754 10: {
755 setMap{"0x00": V(uint32(0x00)), "0xff": V(uint32(0xff)), "0xdead": V(uint32(0xdead))},
756 lenMap(3),
Joe Tsai87b955b2018-11-14 21:59:49 -0800757 equalMap{wantFS.Get(10).Map()},
Joe Tsaibbfaeb72018-10-17 00:27:21 +0000758 getMap{"0x00": V(uint32(0x00)), "0xff": V(uint32(0xff)), "0xdead": V(uint32(0xdead)), "0xdeadbeef": V(nil)},
759 },
760 12: {
761 setMap{"nan": V(float32(math.NaN())), "pi": V(float32(math.Pi)), "e": V(float32(math.E))},
Joe Tsai87b955b2018-11-14 21:59:49 -0800762 clearMap{"e", "phi"},
Joe Tsaibbfaeb72018-10-17 00:27:21 +0000763 rangeMap{"nan": V(float32(math.NaN())), "pi": V(float32(math.Pi))},
764 },
765 14: {
Joe Tsai87b955b2018-11-14 21:59:49 -0800766 equalMap{emptyFS.Get(14).Map()},
Joe Tsaibbfaeb72018-10-17 00:27:21 +0000767 setMap{"s1": V("s1"), "s2": V("s2")},
768 },
769 16: {
770 setMap{"s1": V([]byte("s1")), "s2": V([]byte("s2"))},
Joe Tsai87b955b2018-11-14 21:59:49 -0800771 equalMap{wantFS.Get(16).Map()},
Joe Tsaibbfaeb72018-10-17 00:27:21 +0000772 },
773 18: {
774 hasMap{"s1": false, "s2": false, "s3": false},
775 setMap{"s1": V("s1"), "s2": V("s2")},
776 hasMap{"s1": true, "s2": true, "s3": false},
777 },
778 20: {
Joe Tsai87b955b2018-11-14 21:59:49 -0800779 equalMap{emptyFS.Get(20).Map()},
Joe Tsaibbfaeb72018-10-17 00:27:21 +0000780 setMap{"s1": V([]byte("s1")), "s2": V([]byte("s2"))},
781 },
782 22: {
783 rangeMap{},
784 setMap{"s1": V("s1"), "s2": V("s2")},
785 rangeMap{"s1": V("s1"), "s2": V("s2")},
786 lenMap(2),
787 },
788 24: {
789 setMap{"s1": V([]byte("s1")), "s2": V([]byte("s2"))},
Joe Tsai87b955b2018-11-14 21:59:49 -0800790 equalMap{wantFS.Get(24).Map()},
Joe Tsaibbfaeb72018-10-17 00:27:21 +0000791 },
792 },
793 hasFields{1: true, 2: true, 3: true, 4: true, 5: true, 6: true, 7: true, 8: true, 9: true, 10: true, 11: true, 12: true, 13: true, 14: true, 15: true, 16: true, 17: true, 18: true, 19: true, 20: true, 21: true, 22: true, 23: true, 24: true, 25: true},
Joe Tsai87b955b2018-11-14 21:59:49 -0800794 equalMessage{want},
795 clearFields{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25},
796 equalMessage{empty},
Joe Tsai91e14662018-09-13 13:24:35 -0700797 })
Joe Tsai6cf80c42018-12-01 04:57:09 -0800798
799 // Test read-only operations on nil message.
800 testMessage(t, nil, (*MapScalars)(nil), messageOps{
801 hasFields{1: false, 2: false, 3: false, 4: false, 5: false, 6: false, 7: false, 8: false, 9: false, 10: false, 11: false, 12: false, 13: false, 14: false, 15: false, 16: false, 17: false, 18: false, 19: false, 20: false, 21: false, 22: false, 23: false, 24: false, 25: false},
802 mapFields{2: {lenMap(0)}, 4: {lenMap(0)}, 6: {lenMap(0)}, 8: {lenMap(0)}, 10: {lenMap(0)}, 12: {lenMap(0)}, 14: {lenMap(0)}, 16: {lenMap(0)}, 18: {lenMap(0)}, 20: {lenMap(0)}, 22: {lenMap(0)}, 24: {lenMap(0)}},
803 })
Joe Tsai91e14662018-09-13 13:24:35 -0700804}
Joe Tsaifa02f4e2018-09-12 16:20:37 -0700805
Joe Tsai87b955b2018-11-14 21:59:49 -0800806type OneofScalars struct {
807 Union isOneofScalars_Union `protobuf_oneof:"union"`
808}
Joe Tsai2c870bb2018-10-17 11:46:52 -0700809
Damien Neil8012b442019-01-18 09:32:24 -0800810var oneofScalarsType = pimpl.MessageType{GoType: reflect.TypeOf(new(OneofScalars)), PBType: ptype.GoMessage(
Joe Tsaif0c01e42018-11-06 13:05:20 -0800811 mustMakeMessageDesc(ptype.StandaloneMessage{
812 Syntax: pref.Proto2,
Joe Tsai87b955b2018-11-14 21:59:49 -0800813 FullName: "OneofScalars",
Joe Tsaif0c01e42018-11-06 13:05:20 -0800814 Fields: []ptype.Field{
815 {Name: "f1", Number: 1, Cardinality: pref.Optional, Kind: pref.BoolKind, Default: V(bool(true)), OneofName: "union"},
816 {Name: "f2", Number: 2, Cardinality: pref.Optional, Kind: pref.Int32Kind, Default: V(int32(2)), OneofName: "union"},
817 {Name: "f3", Number: 3, Cardinality: pref.Optional, Kind: pref.Int64Kind, Default: V(int64(3)), OneofName: "union"},
818 {Name: "f4", Number: 4, Cardinality: pref.Optional, Kind: pref.Uint32Kind, Default: V(uint32(4)), OneofName: "union"},
819 {Name: "f5", Number: 5, Cardinality: pref.Optional, Kind: pref.Uint64Kind, Default: V(uint64(5)), OneofName: "union"},
820 {Name: "f6", Number: 6, Cardinality: pref.Optional, Kind: pref.FloatKind, Default: V(float32(6)), OneofName: "union"},
821 {Name: "f7", Number: 7, Cardinality: pref.Optional, Kind: pref.DoubleKind, Default: V(float64(7)), OneofName: "union"},
822 {Name: "f8", Number: 8, Cardinality: pref.Optional, Kind: pref.StringKind, Default: V(string("8")), OneofName: "union"},
823 {Name: "f9", Number: 9, Cardinality: pref.Optional, Kind: pref.StringKind, Default: V(string("9")), OneofName: "union"},
824 {Name: "f10", Number: 10, Cardinality: pref.Optional, Kind: pref.StringKind, Default: V(string("10")), OneofName: "union"},
825 {Name: "f11", Number: 11, Cardinality: pref.Optional, Kind: pref.BytesKind, Default: V([]byte("11")), OneofName: "union"},
826 {Name: "f12", Number: 12, Cardinality: pref.Optional, Kind: pref.BytesKind, Default: V([]byte("12")), OneofName: "union"},
827 {Name: "f13", Number: 13, Cardinality: pref.Optional, Kind: pref.BytesKind, Default: V([]byte("13")), OneofName: "union"},
828 },
829 Oneofs: []ptype.Oneof{{Name: "union"}},
830 }),
Joe Tsai3bc7d6f2019-01-09 02:57:13 -0800831 func(pref.MessageType) pref.Message {
Joe Tsaif0c01e42018-11-06 13:05:20 -0800832 return new(OneofScalars)
833 },
834)}
835
Joe Tsai0fc49f82019-05-01 12:29:25 -0700836// TODO: Remove this.
Damien Neil374cdb82019-01-29 16:45:30 -0800837func (m *OneofScalars) Type() pref.MessageType { return oneofScalarsType.PBType }
Joe Tsai0fc49f82019-05-01 12:29:25 -0700838func (m *OneofScalars) Descriptor() pref.MessageDescriptor {
839 return oneofScalarsType.PBType.Descriptor()
840}
Damien Neil374cdb82019-01-29 16:45:30 -0800841func (m *OneofScalars) KnownFields() pref.KnownFields {
842 return oneofScalarsType.MessageOf(m).KnownFields()
843}
844func (m *OneofScalars) UnknownFields() pref.UnknownFields {
845 return oneofScalarsType.MessageOf(m).UnknownFields()
846}
Joe Tsai0fc49f82019-05-01 12:29:25 -0700847func (m *OneofScalars) New() pref.Message { return new(OneofScalars) }
Damien Neil374cdb82019-01-29 16:45:30 -0800848func (m *OneofScalars) Interface() pref.ProtoMessage { return m }
849func (m *OneofScalars) ProtoReflect() pref.Message { return m }
Joe Tsaif0c01e42018-11-06 13:05:20 -0800850
Joe Tsaif18ab532018-11-27 17:25:04 -0800851func (*OneofScalars) XXX_OneofWrappers() []interface{} {
852 return []interface{}{
Joe Tsai2c870bb2018-10-17 11:46:52 -0700853 (*OneofScalars_Bool)(nil),
854 (*OneofScalars_Int32)(nil),
855 (*OneofScalars_Int64)(nil),
856 (*OneofScalars_Uint32)(nil),
857 (*OneofScalars_Uint64)(nil),
858 (*OneofScalars_Float32)(nil),
859 (*OneofScalars_Float64)(nil),
860 (*OneofScalars_String)(nil),
861 (*OneofScalars_StringA)(nil),
862 (*OneofScalars_StringB)(nil),
863 (*OneofScalars_Bytes)(nil),
864 (*OneofScalars_BytesA)(nil),
865 (*OneofScalars_BytesB)(nil),
866 }
867}
868
Joe Tsai87b955b2018-11-14 21:59:49 -0800869type (
870 isOneofScalars_Union interface {
871 isOneofScalars_Union()
872 }
873 OneofScalars_Bool struct {
874 Bool bool `protobuf:"1"`
875 }
876 OneofScalars_Int32 struct {
877 Int32 MyInt32 `protobuf:"2"`
878 }
879 OneofScalars_Int64 struct {
880 Int64 int64 `protobuf:"3"`
881 }
882 OneofScalars_Uint32 struct {
883 Uint32 MyUint32 `protobuf:"4"`
884 }
885 OneofScalars_Uint64 struct {
886 Uint64 uint64 `protobuf:"5"`
887 }
888 OneofScalars_Float32 struct {
889 Float32 MyFloat32 `protobuf:"6"`
890 }
891 OneofScalars_Float64 struct {
892 Float64 float64 `protobuf:"7"`
893 }
894 OneofScalars_String struct {
895 String string `protobuf:"8"`
896 }
897 OneofScalars_StringA struct {
898 StringA []byte `protobuf:"9"`
899 }
900 OneofScalars_StringB struct {
901 StringB MyString `protobuf:"10"`
902 }
903 OneofScalars_Bytes struct {
904 Bytes []byte `protobuf:"11"`
905 }
906 OneofScalars_BytesA struct {
907 BytesA string `protobuf:"12"`
908 }
909 OneofScalars_BytesB struct {
910 BytesB MyBytes `protobuf:"13"`
911 }
912)
913
Joe Tsai2c870bb2018-10-17 11:46:52 -0700914func (*OneofScalars_Bool) isOneofScalars_Union() {}
915func (*OneofScalars_Int32) isOneofScalars_Union() {}
916func (*OneofScalars_Int64) isOneofScalars_Union() {}
917func (*OneofScalars_Uint32) isOneofScalars_Union() {}
918func (*OneofScalars_Uint64) isOneofScalars_Union() {}
919func (*OneofScalars_Float32) isOneofScalars_Union() {}
920func (*OneofScalars_Float64) isOneofScalars_Union() {}
921func (*OneofScalars_String) isOneofScalars_Union() {}
922func (*OneofScalars_StringA) isOneofScalars_Union() {}
923func (*OneofScalars_StringB) isOneofScalars_Union() {}
924func (*OneofScalars_Bytes) isOneofScalars_Union() {}
925func (*OneofScalars_BytesA) isOneofScalars_Union() {}
926func (*OneofScalars_BytesB) isOneofScalars_Union() {}
927
928func TestOneofs(t *testing.T) {
Joe Tsaif0c01e42018-11-06 13:05:20 -0800929 empty := &OneofScalars{}
930 want1 := &OneofScalars{Union: &OneofScalars_Bool{true}}
931 want2 := &OneofScalars{Union: &OneofScalars_Int32{20}}
932 want3 := &OneofScalars{Union: &OneofScalars_Int64{30}}
933 want4 := &OneofScalars{Union: &OneofScalars_Uint32{40}}
934 want5 := &OneofScalars{Union: &OneofScalars_Uint64{50}}
935 want6 := &OneofScalars{Union: &OneofScalars_Float32{60}}
936 want7 := &OneofScalars{Union: &OneofScalars_Float64{70}}
937 want8 := &OneofScalars{Union: &OneofScalars_String{string("80")}}
938 want9 := &OneofScalars{Union: &OneofScalars_StringA{[]byte("90")}}
939 want10 := &OneofScalars{Union: &OneofScalars_StringB{MyString("100")}}
940 want11 := &OneofScalars{Union: &OneofScalars_Bytes{[]byte("110")}}
941 want12 := &OneofScalars{Union: &OneofScalars_BytesA{string("120")}}
942 want13 := &OneofScalars{Union: &OneofScalars_BytesB{MyBytes("130")}}
Joe Tsai2c870bb2018-10-17 11:46:52 -0700943
Joe Tsaif0c01e42018-11-06 13:05:20 -0800944 testMessage(t, nil, &OneofScalars{}, messageOps{
Joe Tsai2c870bb2018-10-17 11:46:52 -0700945 hasFields{1: false, 2: false, 3: false, 4: false, 5: false, 6: false, 7: false, 8: false, 9: false, 10: false, 11: false, 12: false, 13: false},
946 getFields{1: V(bool(true)), 2: V(int32(2)), 3: V(int64(3)), 4: V(uint32(4)), 5: V(uint64(5)), 6: V(float32(6)), 7: V(float64(7)), 8: V(string("8")), 9: V(string("9")), 10: V(string("10")), 11: V([]byte("11")), 12: V([]byte("12")), 13: V([]byte("13"))},
Joe Tsai4ec39c72019-04-03 13:40:53 -0700947 whichOneofs{"union": 0, "Union": 0},
Joe Tsai2c870bb2018-10-17 11:46:52 -0700948
Joe Tsai87b955b2018-11-14 21:59:49 -0800949 setFields{1: V(bool(true))}, hasFields{1: true}, equalMessage{want1},
950 setFields{2: V(int32(20))}, hasFields{2: true}, equalMessage{want2},
951 setFields{3: V(int64(30))}, hasFields{3: true}, equalMessage{want3},
952 setFields{4: V(uint32(40))}, hasFields{4: true}, equalMessage{want4},
953 setFields{5: V(uint64(50))}, hasFields{5: true}, equalMessage{want5},
954 setFields{6: V(float32(60))}, hasFields{6: true}, equalMessage{want6},
955 setFields{7: V(float64(70))}, hasFields{7: true}, equalMessage{want7},
Joe Tsai4ec39c72019-04-03 13:40:53 -0700956
957 hasFields{1: false, 2: false, 3: false, 4: false, 5: false, 6: false, 7: true, 8: false, 9: false, 10: false, 11: false, 12: false, 13: false},
958 whichOneofs{"union": 7, "Union": 0},
959
Joe Tsai87b955b2018-11-14 21:59:49 -0800960 setFields{8: V(string("80"))}, hasFields{8: true}, equalMessage{want8},
961 setFields{9: V(string("90"))}, hasFields{9: true}, equalMessage{want9},
962 setFields{10: V(string("100"))}, hasFields{10: true}, equalMessage{want10},
963 setFields{11: V([]byte("110"))}, hasFields{11: true}, equalMessage{want11},
964 setFields{12: V([]byte("120"))}, hasFields{12: true}, equalMessage{want12},
965 setFields{13: V([]byte("130"))}, hasFields{13: true}, equalMessage{want13},
Joe Tsai2c870bb2018-10-17 11:46:52 -0700966
967 hasFields{1: false, 2: false, 3: false, 4: false, 5: false, 6: false, 7: false, 8: false, 9: false, 10: false, 11: false, 12: false, 13: true},
968 getFields{1: V(bool(true)), 2: V(int32(2)), 3: V(int64(3)), 4: V(uint32(4)), 5: V(uint64(5)), 6: V(float32(6)), 7: V(float64(7)), 8: V(string("8")), 9: V(string("9")), 10: V(string("10")), 11: V([]byte("11")), 12: V([]byte("12")), 13: V([]byte("130"))},
Joe Tsai87b955b2018-11-14 21:59:49 -0800969 clearFields{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12},
Joe Tsai4ec39c72019-04-03 13:40:53 -0700970 whichOneofs{"union": 13, "Union": 0},
Joe Tsai87b955b2018-11-14 21:59:49 -0800971 equalMessage{want13},
972 clearFields{13},
Joe Tsai4ec39c72019-04-03 13:40:53 -0700973 whichOneofs{"union": 0, "Union": 0},
Joe Tsai87b955b2018-11-14 21:59:49 -0800974 equalMessage{empty},
Joe Tsai2c870bb2018-10-17 11:46:52 -0700975 })
Joe Tsai6cf80c42018-12-01 04:57:09 -0800976
977 // Test read-only operations on nil message.
978 testMessage(t, nil, (*OneofScalars)(nil), messageOps{
979 hasFields{1: false, 2: false, 3: false, 4: false, 5: false, 6: false, 7: false, 8: false, 9: false, 10: false, 11: false, 12: false, 13: false},
980 getFields{1: V(bool(true)), 2: V(int32(2)), 3: V(int64(3)), 4: V(uint32(4)), 5: V(uint64(5)), 6: V(float32(6)), 7: V(float64(7)), 8: V(string("8")), 9: V(string("9")), 10: V(string("10")), 11: V([]byte("11")), 12: V([]byte("12")), 13: V([]byte("13"))},
981 })
Joe Tsai2c870bb2018-10-17 11:46:52 -0700982}
983
Joe Tsai87b955b2018-11-14 21:59:49 -0800984type EnumProto2 int32
985
986var enumProto2Type = ptype.GoEnum(
987 mustMakeEnumDesc(ptype.StandaloneEnum{
988 Syntax: pref.Proto2,
989 FullName: "EnumProto2",
990 Values: []ptype.EnumValue{{Name: "DEAD", Number: 0xdead}, {Name: "BEEF", Number: 0xbeef}},
991 }),
Damien Neila8593ba2019-01-08 16:18:07 -0800992 func(_ pref.EnumType, n pref.EnumNumber) pref.Enum {
Joe Tsai87b955b2018-11-14 21:59:49 -0800993 return EnumProto2(n)
994 },
995)
996
Joe Tsai0fc49f82019-05-01 12:29:25 -0700997// TODO: Remove this.
998func (e EnumProto2) Type() pref.EnumType { return enumProto2Type }
999func (e EnumProto2) Descriptor() pref.EnumDescriptor { return enumProto2Type.Descriptor() }
1000func (e EnumProto2) Enum() *EnumProto2 { return &e }
1001func (e EnumProto2) Number() pref.EnumNumber { return pref.EnumNumber(e) }
Joe Tsai87b955b2018-11-14 21:59:49 -08001002
1003type EnumProto3 int32
1004
1005var enumProto3Type = ptype.GoEnum(
1006 mustMakeEnumDesc(ptype.StandaloneEnum{
1007 Syntax: pref.Proto3,
1008 FullName: "EnumProto3",
1009 Values: []ptype.EnumValue{{Name: "ALPHA", Number: 0}, {Name: "BRAVO", Number: 1}},
1010 }),
Damien Neila8593ba2019-01-08 16:18:07 -08001011 func(_ pref.EnumType, n pref.EnumNumber) pref.Enum {
Joe Tsai87b955b2018-11-14 21:59:49 -08001012 return EnumProto3(n)
1013 },
1014)
1015
Joe Tsai0fc49f82019-05-01 12:29:25 -07001016// TODO: Remove this.
1017func (e EnumProto3) Type() pref.EnumType { return enumProto3Type }
1018func (e EnumProto3) Descriptor() pref.EnumDescriptor { return enumProto3Type.Descriptor() }
1019func (e EnumProto3) Enum() *EnumProto3 { return &e }
1020func (e EnumProto3) Number() pref.EnumNumber { return pref.EnumNumber(e) }
Joe Tsai87b955b2018-11-14 21:59:49 -08001021
1022type EnumMessages struct {
1023 EnumP2 *EnumProto2 `protobuf:"1"`
1024 EnumP3 *EnumProto3 `protobuf:"2"`
1025 MessageLegacy *proto2_20180125.Message `protobuf:"3"`
1026 MessageCycle *EnumMessages `protobuf:"4"`
1027 EnumList []EnumProto2 `protobuf:"5"`
1028 MessageList []*ScalarProto2 `protobuf:"6"`
1029 EnumMap map[string]EnumProto3 `protobuf:"7"`
1030 MessageMap map[string]*ScalarProto3 `protobuf:"8"`
1031 Union isEnumMessages_Union `protobuf_oneof:"union"`
1032}
1033
Damien Neil8012b442019-01-18 09:32:24 -08001034var enumMessagesType = pimpl.MessageType{GoType: reflect.TypeOf(new(EnumMessages)), PBType: ptype.GoMessage(
Joe Tsai87b955b2018-11-14 21:59:49 -08001035 mustMakeMessageDesc(ptype.StandaloneMessage{
1036 Syntax: pref.Proto2,
1037 FullName: "EnumMessages",
1038 Fields: []ptype.Field{
Joe Tsai0fc49f82019-05-01 12:29:25 -07001039 {Name: "f1", Number: 1, Cardinality: pref.Optional, Kind: pref.EnumKind, Default: V("BEEF"), EnumType: enumProto2Type.Descriptor()},
1040 {Name: "f2", Number: 2, Cardinality: pref.Optional, Kind: pref.EnumKind, Default: V("BRAVO"), EnumType: enumProto3Type.Descriptor()},
1041 {Name: "f3", Number: 3, Cardinality: pref.Optional, Kind: pref.MessageKind, MessageType: pimpl.Export{}.MessageDescriptorOf(new(proto2_20180125.Message))},
Joe Tsai87b955b2018-11-14 21:59:49 -08001042 {Name: "f4", Number: 4, Cardinality: pref.Optional, Kind: pref.MessageKind, MessageType: ptype.PlaceholderMessage("EnumMessages")},
Joe Tsai0fc49f82019-05-01 12:29:25 -07001043 {Name: "f5", Number: 5, Cardinality: pref.Repeated, Kind: pref.EnumKind, EnumType: enumProto2Type.Descriptor()},
1044 {Name: "f6", Number: 6, Cardinality: pref.Repeated, Kind: pref.MessageKind, MessageType: scalarProto2Type.PBType.Descriptor()},
Joe Tsai87b955b2018-11-14 21:59:49 -08001045 {Name: "f7", Number: 7, Cardinality: pref.Repeated, Kind: pref.MessageKind, MessageType: enumMapDesc},
1046 {Name: "f8", Number: 8, Cardinality: pref.Repeated, Kind: pref.MessageKind, MessageType: messageMapDesc},
Joe Tsai0fc49f82019-05-01 12:29:25 -07001047 {Name: "f9", Number: 9, Cardinality: pref.Optional, Kind: pref.EnumKind, Default: V("BEEF"), OneofName: "union", EnumType: enumProto2Type.Descriptor()},
1048 {Name: "f10", Number: 10, Cardinality: pref.Optional, Kind: pref.EnumKind, Default: V("BRAVO"), OneofName: "union", EnumType: enumProto3Type.Descriptor()},
1049 {Name: "f11", Number: 11, Cardinality: pref.Optional, Kind: pref.MessageKind, OneofName: "union", MessageType: scalarProto2Type.PBType.Descriptor()},
1050 {Name: "f12", Number: 12, Cardinality: pref.Optional, Kind: pref.MessageKind, OneofName: "union", MessageType: scalarProto3Type.PBType.Descriptor()},
Joe Tsai87b955b2018-11-14 21:59:49 -08001051 },
1052 Oneofs: []ptype.Oneof{{Name: "union"}},
1053 }),
Joe Tsai3bc7d6f2019-01-09 02:57:13 -08001054 func(pref.MessageType) pref.Message {
Joe Tsai87b955b2018-11-14 21:59:49 -08001055 return new(EnumMessages)
1056 },
1057)}
1058
1059var enumMapDesc = mustMakeMessageDesc(ptype.StandaloneMessage{
1060 Syntax: pref.Proto2,
1061 FullName: "EnumMessages.F7Entry",
1062 Fields: []ptype.Field{
1063 {Name: "key", Number: 1, Cardinality: pref.Optional, Kind: pref.StringKind},
Joe Tsai0fc49f82019-05-01 12:29:25 -07001064 {Name: "value", Number: 2, Cardinality: pref.Optional, Kind: pref.EnumKind, EnumType: enumProto3Type.Descriptor()},
Joe Tsai87b955b2018-11-14 21:59:49 -08001065 },
Damien Neil232ea152018-12-10 15:14:36 -08001066 Options: &descriptorpb.MessageOptions{MapEntry: scalar.Bool(true)},
1067 IsMapEntry: true,
Joe Tsai87b955b2018-11-14 21:59:49 -08001068})
1069
1070var messageMapDesc = mustMakeMessageDesc(ptype.StandaloneMessage{
1071 Syntax: pref.Proto2,
1072 FullName: "EnumMessages.F8Entry",
1073 Fields: []ptype.Field{
1074 {Name: "key", Number: 1, Cardinality: pref.Optional, Kind: pref.StringKind},
Joe Tsai0fc49f82019-05-01 12:29:25 -07001075 {Name: "value", Number: 2, Cardinality: pref.Optional, Kind: pref.MessageKind, MessageType: scalarProto3Type.PBType.Descriptor()},
Joe Tsai87b955b2018-11-14 21:59:49 -08001076 },
Damien Neil232ea152018-12-10 15:14:36 -08001077 Options: &descriptorpb.MessageOptions{MapEntry: scalar.Bool(true)},
1078 IsMapEntry: true,
Joe Tsai87b955b2018-11-14 21:59:49 -08001079})
1080
Joe Tsai0fc49f82019-05-01 12:29:25 -07001081// TODO: Remove this.
Damien Neil374cdb82019-01-29 16:45:30 -08001082func (m *EnumMessages) Type() pref.MessageType { return enumMessagesType.PBType }
Joe Tsai0fc49f82019-05-01 12:29:25 -07001083func (m *EnumMessages) Descriptor() pref.MessageDescriptor {
1084 return enumMessagesType.PBType.Descriptor()
1085}
Damien Neil374cdb82019-01-29 16:45:30 -08001086func (m *EnumMessages) KnownFields() pref.KnownFields {
1087 return enumMessagesType.MessageOf(m).KnownFields()
1088}
1089func (m *EnumMessages) UnknownFields() pref.UnknownFields {
1090 return enumMessagesType.MessageOf(m).UnknownFields()
1091}
Joe Tsai0fc49f82019-05-01 12:29:25 -07001092func (m *EnumMessages) New() pref.Message { return new(EnumMessages) }
Damien Neil374cdb82019-01-29 16:45:30 -08001093func (m *EnumMessages) Interface() pref.ProtoMessage { return m }
1094func (m *EnumMessages) ProtoReflect() pref.Message { return m }
Joe Tsai87b955b2018-11-14 21:59:49 -08001095
Joe Tsaif18ab532018-11-27 17:25:04 -08001096func (*EnumMessages) XXX_OneofWrappers() []interface{} {
1097 return []interface{}{
Joe Tsai87b955b2018-11-14 21:59:49 -08001098 (*EnumMessages_OneofE2)(nil),
1099 (*EnumMessages_OneofE3)(nil),
1100 (*EnumMessages_OneofM2)(nil),
1101 (*EnumMessages_OneofM3)(nil),
1102 }
1103}
1104
1105type (
1106 isEnumMessages_Union interface {
1107 isEnumMessages_Union()
1108 }
1109 EnumMessages_OneofE2 struct {
1110 OneofE2 EnumProto2 `protobuf:"9"`
1111 }
1112 EnumMessages_OneofE3 struct {
1113 OneofE3 EnumProto3 `protobuf:"10"`
1114 }
1115 EnumMessages_OneofM2 struct {
1116 OneofM2 *ScalarProto2 `protobuf:"11"`
1117 }
1118 EnumMessages_OneofM3 struct {
1119 OneofM3 *ScalarProto3 `protobuf:"12"`
1120 }
1121)
1122
1123func (*EnumMessages_OneofE2) isEnumMessages_Union() {}
1124func (*EnumMessages_OneofE3) isEnumMessages_Union() {}
1125func (*EnumMessages_OneofM2) isEnumMessages_Union() {}
1126func (*EnumMessages_OneofM3) isEnumMessages_Union() {}
1127
1128func TestEnumMessages(t *testing.T) {
Joe Tsai08e00302018-11-26 22:32:06 -08001129 wantL := pimpl.Export{}.MessageOf(&proto2_20180125.Message{OptionalFloat: scalar.Float32(math.E)})
Joe Tsai87b955b2018-11-14 21:59:49 -08001130 wantM := &EnumMessages{EnumP2: EnumProto2(1234).Enum()}
Joe Tsai009e0672018-11-27 18:45:07 -08001131 wantM2a := &ScalarProto2{Float32: scalar.Float32(math.Pi)}
1132 wantM2b := &ScalarProto2{Float32: scalar.Float32(math.Phi)}
Joe Tsai87b955b2018-11-14 21:59:49 -08001133 wantM3a := &ScalarProto3{Float32: math.Pi}
1134 wantM3b := &ScalarProto3{Float32: math.Ln2}
1135
1136 wantList5 := (&EnumMessages{EnumList: []EnumProto2{333, 222}}).KnownFields().Get(5)
1137 wantList6 := (&EnumMessages{MessageList: []*ScalarProto2{wantM2a, wantM2b}}).KnownFields().Get(6)
1138
1139 wantMap7 := (&EnumMessages{EnumMap: map[string]EnumProto3{"one": 1, "two": 2}}).KnownFields().Get(7)
1140 wantMap8 := (&EnumMessages{MessageMap: map[string]*ScalarProto3{"pi": wantM3a, "ln2": wantM3b}}).KnownFields().Get(8)
1141
1142 testMessage(t, nil, &EnumMessages{}, messageOps{
1143 hasFields{1: false, 2: false, 3: false, 4: false, 5: false, 6: false, 7: false, 8: false, 9: false, 10: false, 11: false, 12: false},
Joe Tsaif6d4a422018-11-19 14:26:06 -08001144 getFields{1: VE(0xbeef), 2: VE(1), 3: V(nil), 4: V(nil), 9: VE(0xbeef), 10: VE(1)},
Joe Tsai87b955b2018-11-14 21:59:49 -08001145
1146 // Test singular enums.
1147 setFields{1: VE(0xdead), 2: VE(0)},
1148 getFields{1: VE(0xdead), 2: VE(0)},
1149 hasFields{1: true, 2: true},
1150
1151 // Test singular messages.
1152 messageFields{3: messageOps{setFields{109: V(float32(math.E))}}},
1153 messageFields{4: messageOps{setFields{1: VE(1234)}}},
1154 getFields{3: V(wantL), 4: V(wantM)},
1155 clearFields{3, 4},
1156 hasFields{3: false, 4: false},
1157 setFields{3: V(wantL), 4: V(wantM)},
1158 hasFields{3: true, 4: true},
1159
1160 // Test list of enums and messages.
1161 listFields{
1162 5: listOps{
1163 appendList{VE(111), VE(222)},
1164 setList{0: VE(333)},
1165 getList{0: VE(333), 1: VE(222)},
1166 lenList(2),
1167 },
1168 6: listOps{
1169 appendMessageList{setFields{4: V(uint32(1e6))}},
1170 appendMessageList{setFields{6: V(float32(math.Phi))}},
1171 setList{0: V(wantM2a)},
1172 getList{0: V(wantM2a), 1: V(wantM2b)},
1173 },
1174 },
1175 getFields{5: wantList5, 6: wantList6},
1176 hasFields{5: true, 6: true},
1177 listFields{5: listOps{truncList(0)}},
1178 hasFields{5: false, 6: true},
1179
1180 // Test maps of enums and messages.
1181 mapFields{
1182 7: mapOps{
1183 setMap{"one": VE(1), "two": VE(2)},
1184 hasMap{"one": true, "two": true, "three": false},
1185 lenMap(2),
1186 },
1187 8: mapOps{
1188 messageMap{"pi": messageOps{setFields{6: V(float32(math.Pi))}}},
1189 setMap{"ln2": V(wantM3b)},
1190 getMap{"pi": V(wantM3a), "ln2": V(wantM3b), "none": V(nil)},
1191 lenMap(2),
1192 },
1193 },
1194 getFields{7: wantMap7, 8: wantMap8},
1195 hasFields{7: true, 8: true},
1196 mapFields{8: mapOps{clearMap{"pi", "ln2", "none"}}},
1197 hasFields{7: true, 8: false},
1198
1199 // Test oneofs of enums and messages.
1200 setFields{9: VE(0xdead)},
1201 hasFields{1: true, 2: true, 9: true, 10: false, 11: false, 12: false},
1202 setFields{10: VE(0)},
1203 hasFields{1: true, 2: true, 9: false, 10: true, 11: false, 12: false},
1204 messageFields{11: messageOps{setFields{6: V(float32(math.Pi))}}},
1205 getFields{11: V(wantM2a)},
1206 hasFields{1: true, 2: true, 9: false, 10: false, 11: true, 12: false},
1207 messageFields{12: messageOps{setFields{6: V(float32(math.Pi))}}},
1208 getFields{12: V(wantM3a)},
1209 hasFields{1: true, 2: true, 9: false, 10: false, 11: false, 12: true},
1210
1211 // Check entire message.
1212 rangeFields{1: VE(0xdead), 2: VE(0), 3: V(wantL), 4: V(wantM), 6: wantList6, 7: wantMap7, 12: V(wantM3a)},
1213 equalMessage{&EnumMessages{
1214 EnumP2: EnumProto2(0xdead).Enum(),
1215 EnumP3: EnumProto3(0).Enum(),
Joe Tsai009e0672018-11-27 18:45:07 -08001216 MessageLegacy: &proto2_20180125.Message{OptionalFloat: scalar.Float32(math.E)},
Joe Tsai87b955b2018-11-14 21:59:49 -08001217 MessageCycle: wantM,
1218 MessageList: []*ScalarProto2{wantM2a, wantM2b},
1219 EnumMap: map[string]EnumProto3{"one": 1, "two": 2},
1220 Union: &EnumMessages_OneofM3{wantM3a},
1221 }},
1222 clearFields{1, 2, 3, 4, 6, 7, 12},
1223 equalMessage{&EnumMessages{}},
1224 })
Joe Tsai6cf80c42018-12-01 04:57:09 -08001225
1226 // Test read-only operations on nil message.
1227 testMessage(t, nil, (*EnumMessages)(nil), messageOps{
1228 hasFields{1: false, 2: false, 3: false, 4: false, 5: false, 6: false, 7: false, 8: false, 9: false, 10: false, 11: false, 12: false},
1229 getFields{1: VE(0xbeef), 2: VE(1), 3: V(nil), 4: V(nil), 9: VE(0xbeef), 10: VE(1), 11: V(nil), 12: V(nil)},
1230 listFields{5: {lenList(0)}, 6: {lenList(0)}},
1231 mapFields{7: {lenMap(0)}, 8: {lenMap(0)}},
1232 })
Joe Tsai87b955b2018-11-14 21:59:49 -08001233}
Joe Tsaifa02f4e2018-09-12 16:20:37 -07001234
Joe Tsai91e14662018-09-13 13:24:35 -07001235var cmpOpts = cmp.Options{
Joe Tsai87b955b2018-11-14 21:59:49 -08001236 cmp.Comparer(func(x, y *proto2_20180125.Message) bool {
1237 return protoV1.Equal(x, y)
Joe Tsai91e14662018-09-13 13:24:35 -07001238 }),
Joe Tsai87b955b2018-11-14 21:59:49 -08001239 cmp.Transformer("UnwrapValue", func(pv pref.Value) interface{} {
1240 return pv.Interface()
Joe Tsai91e14662018-09-13 13:24:35 -07001241 }),
Joe Tsai87b955b2018-11-14 21:59:49 -08001242 cmp.Transformer("UnwrapGeneric", func(x pvalue.Unwrapper) interface{} {
Joe Tsaiba0ef9a2018-11-29 14:54:05 -08001243 return x.ProtoUnwrap()
Joe Tsai91e14662018-09-13 13:24:35 -07001244 }),
1245 cmpopts.EquateNaNs(),
Joe Tsai87b955b2018-11-14 21:59:49 -08001246 cmpopts.EquateEmpty(),
Joe Tsai91e14662018-09-13 13:24:35 -07001247}
1248
1249func testMessage(t *testing.T, p path, m pref.Message, tt messageOps) {
1250 fs := m.KnownFields()
1251 for i, op := range tt {
1252 p.Push(i)
1253 switch op := op.(type) {
1254 case equalMessage:
Joe Tsai87b955b2018-11-14 21:59:49 -08001255 if diff := cmp.Diff(op.Message, m, cmpOpts); diff != "" {
Joe Tsai91e14662018-09-13 13:24:35 -07001256 t.Errorf("operation %v, message mismatch (-want, +got):\n%s", p, diff)
1257 }
1258 case hasFields:
1259 got := map[pref.FieldNumber]bool{}
1260 want := map[pref.FieldNumber]bool(op)
1261 for n := range want {
1262 got[n] = fs.Has(n)
1263 }
1264 if diff := cmp.Diff(want, got); diff != "" {
1265 t.Errorf("operation %v, KnownFields.Has mismatch (-want, +got):\n%s", p, diff)
1266 }
1267 case getFields:
1268 got := map[pref.FieldNumber]pref.Value{}
1269 want := map[pref.FieldNumber]pref.Value(op)
1270 for n := range want {
1271 got[n] = fs.Get(n)
1272 }
1273 if diff := cmp.Diff(want, got, cmpOpts); diff != "" {
1274 t.Errorf("operation %v, KnownFields.Get mismatch (-want, +got):\n%s", p, diff)
1275 }
1276 case setFields:
1277 for n, v := range op {
1278 fs.Set(n, v)
1279 }
1280 case clearFields:
Joe Tsai87b955b2018-11-14 21:59:49 -08001281 for _, n := range op {
1282 fs.Clear(n)
1283 }
Joe Tsai4ec39c72019-04-03 13:40:53 -07001284 case whichOneofs:
1285 got := map[pref.Name]pref.FieldNumber{}
1286 want := map[pref.Name]pref.FieldNumber(op)
1287 for s := range want {
1288 got[s] = fs.WhichOneof(s)
1289 }
1290 if diff := cmp.Diff(want, got); diff != "" {
1291 t.Errorf("operation %v, KnownFields.WhichOneof mismatch (-want, +got):\n%s", p, diff)
1292 }
Joe Tsai87b955b2018-11-14 21:59:49 -08001293 case messageFields:
1294 for n, tt := range op {
1295 p.Push(int(n))
Damien Neil97e7f572018-12-07 14:28:33 -08001296 if !fs.Has(n) {
1297 fs.Set(n, V(fs.NewMessage(n)))
1298 }
1299 testMessage(t, p, fs.Get(n).Message(), tt)
Joe Tsai87b955b2018-11-14 21:59:49 -08001300 p.Pop()
Joe Tsaifa02f4e2018-09-12 16:20:37 -07001301 }
Joe Tsai4b7aff62018-11-14 14:05:19 -08001302 case listFields:
Joe Tsai91e14662018-09-13 13:24:35 -07001303 for n, tt := range op {
1304 p.Push(int(n))
Joe Tsai6cf80c42018-12-01 04:57:09 -08001305 testLists(t, p, fs.Get(n).List(), tt)
Joe Tsai91e14662018-09-13 13:24:35 -07001306 p.Pop()
1307 }
Joe Tsaibbfaeb72018-10-17 00:27:21 +00001308 case mapFields:
1309 for n, tt := range op {
1310 p.Push(int(n))
Joe Tsai6cf80c42018-12-01 04:57:09 -08001311 testMaps(t, p, fs.Get(n).Map(), tt)
Joe Tsaibbfaeb72018-10-17 00:27:21 +00001312 p.Pop()
1313 }
Joe Tsai87b955b2018-11-14 21:59:49 -08001314 case rangeFields:
1315 got := map[pref.FieldNumber]pref.Value{}
1316 want := map[pref.FieldNumber]pref.Value(op)
1317 fs.Range(func(n pref.FieldNumber, v pref.Value) bool {
1318 got[n] = v
1319 return true
1320 })
1321 if diff := cmp.Diff(want, got, cmpOpts); diff != "" {
1322 t.Errorf("operation %v, KnownFields.Range mismatch (-want, +got):\n%s", p, diff)
1323 }
Joe Tsai91e14662018-09-13 13:24:35 -07001324 default:
1325 t.Fatalf("operation %v, invalid operation: %T", p, op)
1326 }
1327 p.Pop()
Joe Tsaifa02f4e2018-09-12 16:20:37 -07001328 }
1329}
Joe Tsai91e14662018-09-13 13:24:35 -07001330
Joe Tsai4b7aff62018-11-14 14:05:19 -08001331func testLists(t *testing.T, p path, v pref.List, tt listOps) {
Joe Tsai91e14662018-09-13 13:24:35 -07001332 for i, op := range tt {
1333 p.Push(i)
1334 switch op := op.(type) {
Joe Tsai4b7aff62018-11-14 14:05:19 -08001335 case equalList:
Joe Tsai87b955b2018-11-14 21:59:49 -08001336 if diff := cmp.Diff(op.List, v, cmpOpts); diff != "" {
Joe Tsai4b7aff62018-11-14 14:05:19 -08001337 t.Errorf("operation %v, list mismatch (-want, +got):\n%s", p, diff)
Joe Tsai91e14662018-09-13 13:24:35 -07001338 }
Joe Tsai4b7aff62018-11-14 14:05:19 -08001339 case lenList:
Joe Tsai91e14662018-09-13 13:24:35 -07001340 if got, want := v.Len(), int(op); got != want {
Joe Tsai4b7aff62018-11-14 14:05:19 -08001341 t.Errorf("operation %v, List.Len = %d, want %d", p, got, want)
Joe Tsai91e14662018-09-13 13:24:35 -07001342 }
Joe Tsai4b7aff62018-11-14 14:05:19 -08001343 case getList:
Joe Tsai91e14662018-09-13 13:24:35 -07001344 got := map[int]pref.Value{}
1345 want := map[int]pref.Value(op)
1346 for n := range want {
1347 got[n] = v.Get(n)
1348 }
1349 if diff := cmp.Diff(want, got, cmpOpts); diff != "" {
Joe Tsai4b7aff62018-11-14 14:05:19 -08001350 t.Errorf("operation %v, List.Get mismatch (-want, +got):\n%s", p, diff)
Joe Tsai91e14662018-09-13 13:24:35 -07001351 }
Joe Tsai4b7aff62018-11-14 14:05:19 -08001352 case setList:
Joe Tsai91e14662018-09-13 13:24:35 -07001353 for n, e := range op {
1354 v.Set(n, e)
1355 }
Joe Tsai4b7aff62018-11-14 14:05:19 -08001356 case appendList:
Joe Tsai91e14662018-09-13 13:24:35 -07001357 for _, e := range op {
1358 v.Append(e)
1359 }
Joe Tsai87b955b2018-11-14 21:59:49 -08001360 case appendMessageList:
Joe Tsai3bc7d6f2019-01-09 02:57:13 -08001361 m := v.NewMessage()
Damien Neil97e7f572018-12-07 14:28:33 -08001362 v.Append(V(m))
1363 testMessage(t, p, m, messageOps(op))
Joe Tsai4b7aff62018-11-14 14:05:19 -08001364 case truncList:
Joe Tsai91e14662018-09-13 13:24:35 -07001365 v.Truncate(int(op))
1366 default:
1367 t.Fatalf("operation %v, invalid operation: %T", p, op)
1368 }
1369 p.Pop()
1370 }
1371}
1372
Joe Tsaibbfaeb72018-10-17 00:27:21 +00001373func testMaps(t *testing.T, p path, m pref.Map, tt mapOps) {
1374 for i, op := range tt {
1375 p.Push(i)
1376 switch op := op.(type) {
1377 case equalMap:
Joe Tsai87b955b2018-11-14 21:59:49 -08001378 if diff := cmp.Diff(op.Map, m, cmpOpts); diff != "" {
Joe Tsaibbfaeb72018-10-17 00:27:21 +00001379 t.Errorf("operation %v, map mismatch (-want, +got):\n%s", p, diff)
1380 }
1381 case lenMap:
1382 if got, want := m.Len(), int(op); got != want {
1383 t.Errorf("operation %v, Map.Len = %d, want %d", p, got, want)
1384 }
1385 case hasMap:
1386 got := map[interface{}]bool{}
1387 want := map[interface{}]bool(op)
1388 for k := range want {
1389 got[k] = m.Has(V(k).MapKey())
1390 }
1391 if diff := cmp.Diff(want, got, cmpOpts); diff != "" {
1392 t.Errorf("operation %v, Map.Has mismatch (-want, +got):\n%s", p, diff)
1393 }
1394 case getMap:
1395 got := map[interface{}]pref.Value{}
1396 want := map[interface{}]pref.Value(op)
1397 for k := range want {
1398 got[k] = m.Get(V(k).MapKey())
1399 }
1400 if diff := cmp.Diff(want, got, cmpOpts); diff != "" {
1401 t.Errorf("operation %v, Map.Get mismatch (-want, +got):\n%s", p, diff)
1402 }
1403 case setMap:
1404 for k, v := range op {
1405 m.Set(V(k).MapKey(), v)
1406 }
1407 case clearMap:
Joe Tsai87b955b2018-11-14 21:59:49 -08001408 for _, k := range op {
1409 m.Clear(V(k).MapKey())
1410 }
1411 case messageMap:
1412 for k, tt := range op {
Damien Neil97e7f572018-12-07 14:28:33 -08001413 mk := V(k).MapKey()
1414 if !m.Has(mk) {
1415 m.Set(mk, V(m.NewMessage()))
1416 }
1417 testMessage(t, p, m.Get(mk).Message(), tt)
Joe Tsaibbfaeb72018-10-17 00:27:21 +00001418 }
1419 case rangeMap:
1420 got := map[interface{}]pref.Value{}
1421 want := map[interface{}]pref.Value(op)
1422 m.Range(func(k pref.MapKey, v pref.Value) bool {
1423 got[k.Interface()] = v
1424 return true
1425 })
1426 if diff := cmp.Diff(want, got, cmpOpts); diff != "" {
1427 t.Errorf("operation %v, Map.Range mismatch (-want, +got):\n%s", p, diff)
1428 }
1429 default:
1430 t.Fatalf("operation %v, invalid operation: %T", p, op)
1431 }
1432 p.Pop()
1433 }
1434}
1435
Joe Tsai91e14662018-09-13 13:24:35 -07001436type path []int
1437
1438func (p *path) Push(i int) { *p = append(*p, i) }
1439func (p *path) Pop() { *p = (*p)[:len(*p)-1] }
1440func (p path) String() string {
1441 var ss []string
1442 for _, i := range p {
1443 ss = append(ss, fmt.Sprint(i))
1444 }
1445 return strings.Join(ss, ".")
1446}