blob: b3393d42f887bdd73962e0fa15544dc7f99afdb2 [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
5package impl
6
7import (
Joe Tsai91e14662018-09-13 13:24:35 -07008 "fmt"
9 "math"
10 "strings"
Joe Tsaifa02f4e2018-09-12 16:20:37 -070011 "testing"
12
Damien Neil204f1c02018-10-23 15:03:38 -070013 protoV1 "github.com/golang/protobuf/proto"
14 descriptorV1 "github.com/golang/protobuf/protoc-gen-go/descriptor"
Joe Tsai01ab2962018-09-21 17:44:00 -070015 pref "github.com/golang/protobuf/v2/reflect/protoreflect"
16 ptype "github.com/golang/protobuf/v2/reflect/prototype"
Joe Tsai87b955b2018-11-14 21:59:49 -080017 cmp "github.com/google/go-cmp/cmp"
18 cmpopts "github.com/google/go-cmp/cmp/cmpopts"
Joe Tsaifa02f4e2018-09-12 16:20:37 -070019
Joe Tsai87b955b2018-11-14 21:59:49 -080020 proto2_20180125 "github.com/golang/protobuf/v2/internal/testprotos/legacy/proto2.v1.0.0-20180125-92554152"
21 pvalue "github.com/golang/protobuf/v2/internal/value"
Joe Tsaifa02f4e2018-09-12 16:20:37 -070022)
23
Joe Tsai4b7aff62018-11-14 14:05:19 -080024// List of test operations to perform on messages, lists, or maps.
Joe Tsai91e14662018-09-13 13:24:35 -070025type (
Joe Tsai87b955b2018-11-14 21:59:49 -080026 messageOp interface{ isMessageOp() }
Joe Tsai91e14662018-09-13 13:24:35 -070027 messageOps []messageOp
Joe Tsaifa02f4e2018-09-12 16:20:37 -070028
Joe Tsai87b955b2018-11-14 21:59:49 -080029 listOp interface{ isListOp() }
Joe Tsai4b7aff62018-11-14 14:05:19 -080030 listOps []listOp
Joe Tsai91e14662018-09-13 13:24:35 -070031
Joe Tsai87b955b2018-11-14 21:59:49 -080032 mapOp interface{ isMapOp() }
Joe Tsaibbfaeb72018-10-17 00:27:21 +000033 mapOps []mapOp
Joe Tsai91e14662018-09-13 13:24:35 -070034)
35
36// Test operations performed on a message.
37type (
Joe Tsai87b955b2018-11-14 21:59:49 -080038 // check that the message contents match
39 equalMessage struct{ pref.Message }
40 // check presence for specific fields in the message
41 hasFields map[pref.FieldNumber]bool
42 // check that specific message fields match
43 getFields map[pref.FieldNumber]pref.Value
44 // set specific message fields
45 setFields map[pref.FieldNumber]pref.Value
46 // clear specific fields in the message
47 clearFields []pref.FieldNumber
48 // apply messageOps on each specified message field
Joe Tsai91e14662018-09-13 13:24:35 -070049 messageFields map[pref.FieldNumber]messageOps
Joe Tsai87b955b2018-11-14 21:59:49 -080050 // apply listOps on each specified list field
51 listFields map[pref.FieldNumber]listOps
52 // apply mapOps on each specified map fields
53 mapFields map[pref.FieldNumber]mapOps
54 // range through all fields and check that they match
55 rangeFields map[pref.FieldNumber]pref.Value
Joe Tsai91e14662018-09-13 13:24:35 -070056)
57
Joe Tsai87b955b2018-11-14 21:59:49 -080058func (equalMessage) isMessageOp() {}
59func (hasFields) isMessageOp() {}
60func (getFields) isMessageOp() {}
61func (setFields) isMessageOp() {}
62func (clearFields) isMessageOp() {}
63func (messageFields) isMessageOp() {}
64func (listFields) isMessageOp() {}
65func (mapFields) isMessageOp() {}
66func (rangeFields) isMessageOp() {}
67
Joe Tsai4b7aff62018-11-14 14:05:19 -080068// Test operations performed on a list.
Joe Tsai91e14662018-09-13 13:24:35 -070069type (
Joe Tsai87b955b2018-11-14 21:59:49 -080070 // check that the list contents match
71 equalList struct{ pref.List }
72 // check that list length matches
73 lenList int
74 // check that specific list entries match
75 getList map[int]pref.Value
76 // set specific list entries
77 setList map[int]pref.Value
78 // append entries to the list
Joe Tsai4b7aff62018-11-14 14:05:19 -080079 appendList []pref.Value
Joe Tsai87b955b2018-11-14 21:59:49 -080080 // apply messageOps on a newly appended message
81 appendMessageList messageOps
82 // truncate the list to the specified length
83 truncList int
Joe Tsai91e14662018-09-13 13:24:35 -070084)
85
Joe Tsai87b955b2018-11-14 21:59:49 -080086func (equalList) isListOp() {}
87func (lenList) isListOp() {}
88func (getList) isListOp() {}
89func (setList) isListOp() {}
90func (appendList) isListOp() {}
91func (appendMessageList) isListOp() {}
92func (truncList) isListOp() {}
93
Joe Tsaibbfaeb72018-10-17 00:27:21 +000094// Test operations performed on a map.
95type (
Joe Tsai87b955b2018-11-14 21:59:49 -080096 // check that the map contents match
97 equalMap struct{ pref.Map }
98 // check that map length matches
99 lenMap int
100 // check presence for specific entries in the map
101 hasMap map[interface{}]bool
102 // check that specific map entries match
103 getMap map[interface{}]pref.Value
104 // set specific map entries
105 setMap map[interface{}]pref.Value
106 // clear specific entries in the map
107 clearMap []interface{}
108 // apply messageOps on each specified message entry
109 messageMap map[interface{}]messageOps
110 // range through all entries and check that they match
Joe Tsaibbfaeb72018-10-17 00:27:21 +0000111 rangeMap map[interface{}]pref.Value
Joe Tsaibbfaeb72018-10-17 00:27:21 +0000112)
113
Joe Tsai87b955b2018-11-14 21:59:49 -0800114func (equalMap) isMapOp() {}
115func (lenMap) isMapOp() {}
116func (hasMap) isMapOp() {}
117func (getMap) isMapOp() {}
118func (setMap) isMapOp() {}
119func (clearMap) isMapOp() {}
120func (messageMap) isMapOp() {}
121func (rangeMap) isMapOp() {}
122
Joe Tsaice6edd32018-10-19 16:27:46 -0700123type ScalarProto2 struct {
124 Bool *bool `protobuf:"1"`
125 Int32 *int32 `protobuf:"2"`
126 Int64 *int64 `protobuf:"3"`
127 Uint32 *uint32 `protobuf:"4"`
128 Uint64 *uint64 `protobuf:"5"`
129 Float32 *float32 `protobuf:"6"`
130 Float64 *float64 `protobuf:"7"`
131 String *string `protobuf:"8"`
132 StringA []byte `protobuf:"9"`
133 Bytes []byte `protobuf:"10"`
134 BytesA *string `protobuf:"11"`
135
136 MyBool *MyBool `protobuf:"12"`
137 MyInt32 *MyInt32 `protobuf:"13"`
138 MyInt64 *MyInt64 `protobuf:"14"`
139 MyUint32 *MyUint32 `protobuf:"15"`
140 MyUint64 *MyUint64 `protobuf:"16"`
141 MyFloat32 *MyFloat32 `protobuf:"17"`
142 MyFloat64 *MyFloat64 `protobuf:"18"`
143 MyString *MyString `protobuf:"19"`
144 MyStringA MyBytes `protobuf:"20"`
145 MyBytes MyBytes `protobuf:"21"`
146 MyBytesA *MyString `protobuf:"22"`
147}
148
Joe Tsai87b955b2018-11-14 21:59:49 -0800149func mustMakeEnumDesc(t ptype.StandaloneEnum) pref.EnumDescriptor {
150 ed, err := ptype.NewEnum(&t)
151 if err != nil {
152 panic(err)
153 }
154 return ed
155}
156
157func mustMakeMessageDesc(t ptype.StandaloneMessage) pref.MessageDescriptor {
158 md, err := ptype.NewMessage(&t)
159 if err != nil {
160 panic(err)
161 }
162 return md
163}
164
165var V = pref.ValueOf
166var VE = func(n pref.EnumNumber) pref.Value { return V(n) }
167
168type (
169 MyBool bool
170 MyInt32 int32
171 MyInt64 int64
172 MyUint32 uint32
173 MyUint64 uint64
174 MyFloat32 float32
175 MyFloat64 float64
176 MyString string
177 MyBytes []byte
178
179 ListStrings []MyString
180 ListBytes []MyBytes
181
182 MapStrings map[MyString]MyString
183 MapBytes map[MyString]MyBytes
184)
185
Joe Tsaif0c01e42018-11-06 13:05:20 -0800186var scalarProto2Type = MessageType{Type: ptype.GoMessage(
187 mustMakeMessageDesc(ptype.StandaloneMessage{
Joe Tsai91e14662018-09-13 13:24:35 -0700188 Syntax: pref.Proto2,
189 FullName: "ScalarProto2",
190 Fields: []ptype.Field{
191 {Name: "f1", Number: 1, Cardinality: pref.Optional, Kind: pref.BoolKind, Default: V(bool(true))},
192 {Name: "f2", Number: 2, Cardinality: pref.Optional, Kind: pref.Int32Kind, Default: V(int32(2))},
193 {Name: "f3", Number: 3, Cardinality: pref.Optional, Kind: pref.Int64Kind, Default: V(int64(3))},
194 {Name: "f4", Number: 4, Cardinality: pref.Optional, Kind: pref.Uint32Kind, Default: V(uint32(4))},
195 {Name: "f5", Number: 5, Cardinality: pref.Optional, Kind: pref.Uint64Kind, Default: V(uint64(5))},
196 {Name: "f6", Number: 6, Cardinality: pref.Optional, Kind: pref.FloatKind, Default: V(float32(6))},
197 {Name: "f7", Number: 7, Cardinality: pref.Optional, Kind: pref.DoubleKind, Default: V(float64(7))},
198 {Name: "f8", Number: 8, Cardinality: pref.Optional, Kind: pref.StringKind, Default: V(string("8"))},
199 {Name: "f9", Number: 9, Cardinality: pref.Optional, Kind: pref.StringKind, Default: V(string("9"))},
200 {Name: "f10", Number: 10, Cardinality: pref.Optional, Kind: pref.BytesKind, Default: V([]byte("10"))},
201 {Name: "f11", Number: 11, Cardinality: pref.Optional, Kind: pref.BytesKind, Default: V([]byte("11"))},
202
203 {Name: "f12", Number: 12, Cardinality: pref.Optional, Kind: pref.BoolKind, Default: V(bool(true))},
204 {Name: "f13", Number: 13, Cardinality: pref.Optional, Kind: pref.Int32Kind, Default: V(int32(13))},
205 {Name: "f14", Number: 14, Cardinality: pref.Optional, Kind: pref.Int64Kind, Default: V(int64(14))},
206 {Name: "f15", Number: 15, Cardinality: pref.Optional, Kind: pref.Uint32Kind, Default: V(uint32(15))},
207 {Name: "f16", Number: 16, Cardinality: pref.Optional, Kind: pref.Uint64Kind, Default: V(uint64(16))},
208 {Name: "f17", Number: 17, Cardinality: pref.Optional, Kind: pref.FloatKind, Default: V(float32(17))},
209 {Name: "f18", Number: 18, Cardinality: pref.Optional, Kind: pref.DoubleKind, Default: V(float64(18))},
210 {Name: "f19", Number: 19, Cardinality: pref.Optional, Kind: pref.StringKind, Default: V(string("19"))},
211 {Name: "f20", Number: 20, Cardinality: pref.Optional, Kind: pref.StringKind, Default: V(string("20"))},
212 {Name: "f21", Number: 21, Cardinality: pref.Optional, Kind: pref.BytesKind, Default: V([]byte("21"))},
213 {Name: "f22", Number: 22, Cardinality: pref.Optional, Kind: pref.BytesKind, Default: V([]byte("22"))},
214 },
Joe Tsaif0c01e42018-11-06 13:05:20 -0800215 }),
216 func(pref.MessageType) pref.ProtoMessage {
217 return new(ScalarProto2)
218 },
219)}
Joe Tsai91e14662018-09-13 13:24:35 -0700220
Joe Tsaif0c01e42018-11-06 13:05:20 -0800221func (m *ScalarProto2) Type() pref.MessageType { return scalarProto2Type.Type }
222func (m *ScalarProto2) KnownFields() pref.KnownFields { return scalarProto2Type.KnownFieldsOf(m) }
223func (m *ScalarProto2) UnknownFields() pref.UnknownFields { return scalarProto2Type.UnknownFieldsOf(m) }
224func (m *ScalarProto2) Interface() pref.ProtoMessage { return m }
225func (m *ScalarProto2) ProtoReflect() pref.Message { return m }
226func (m *ScalarProto2) ProtoMutable() {}
227
228func TestScalarProto2(t *testing.T) {
229 testMessage(t, nil, &ScalarProto2{}, messageOps{
Joe Tsai91e14662018-09-13 13:24:35 -0700230 hasFields{
231 1: false, 2: false, 3: false, 4: false, 5: false, 6: false, 7: false, 8: false, 9: false, 10: false, 11: false,
232 12: false, 13: false, 14: false, 15: false, 16: false, 17: false, 18: false, 19: false, 20: false, 21: false, 22: false,
233 },
234 getFields{
235 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")),
236 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")),
237 },
238 setFields{
239 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)),
240 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)),
241 },
242 hasFields{
243 1: true, 2: true, 3: true, 4: true, 5: true, 6: true, 7: true, 8: true, 9: true, 10: true, 11: true,
244 12: true, 13: true, 14: true, 15: true, 16: true, 17: true, 18: true, 19: true, 20: true, 21: true, 22: true,
245 },
Joe Tsai87b955b2018-11-14 21:59:49 -0800246 equalMessage{&ScalarProto2{
Joe Tsai91e14662018-09-13 13:24:35 -0700247 new(bool), new(int32), new(int64), new(uint32), new(uint64), new(float32), new(float64), new(string), []byte{}, []byte{}, new(string),
248 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 -0800249 }},
250 clearFields{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22},
251 equalMessage{&ScalarProto2{}},
Joe Tsai91e14662018-09-13 13:24:35 -0700252 })
Joe Tsaifa02f4e2018-09-12 16:20:37 -0700253}
254
Joe Tsaice6edd32018-10-19 16:27:46 -0700255type ScalarProto3 struct {
256 Bool bool `protobuf:"1"`
257 Int32 int32 `protobuf:"2"`
258 Int64 int64 `protobuf:"3"`
259 Uint32 uint32 `protobuf:"4"`
260 Uint64 uint64 `protobuf:"5"`
261 Float32 float32 `protobuf:"6"`
262 Float64 float64 `protobuf:"7"`
263 String string `protobuf:"8"`
264 StringA []byte `protobuf:"9"`
265 Bytes []byte `protobuf:"10"`
266 BytesA string `protobuf:"11"`
267
268 MyBool MyBool `protobuf:"12"`
269 MyInt32 MyInt32 `protobuf:"13"`
270 MyInt64 MyInt64 `protobuf:"14"`
271 MyUint32 MyUint32 `protobuf:"15"`
272 MyUint64 MyUint64 `protobuf:"16"`
273 MyFloat32 MyFloat32 `protobuf:"17"`
274 MyFloat64 MyFloat64 `protobuf:"18"`
275 MyString MyString `protobuf:"19"`
276 MyStringA MyBytes `protobuf:"20"`
277 MyBytes MyBytes `protobuf:"21"`
278 MyBytesA MyString `protobuf:"22"`
279}
280
Joe Tsaif0c01e42018-11-06 13:05:20 -0800281var scalarProto3Type = MessageType{Type: ptype.GoMessage(
282 mustMakeMessageDesc(ptype.StandaloneMessage{
Joe Tsai91e14662018-09-13 13:24:35 -0700283 Syntax: pref.Proto3,
284 FullName: "ScalarProto3",
285 Fields: []ptype.Field{
286 {Name: "f1", Number: 1, Cardinality: pref.Optional, Kind: pref.BoolKind},
287 {Name: "f2", Number: 2, Cardinality: pref.Optional, Kind: pref.Int32Kind},
288 {Name: "f3", Number: 3, Cardinality: pref.Optional, Kind: pref.Int64Kind},
289 {Name: "f4", Number: 4, Cardinality: pref.Optional, Kind: pref.Uint32Kind},
290 {Name: "f5", Number: 5, Cardinality: pref.Optional, Kind: pref.Uint64Kind},
291 {Name: "f6", Number: 6, Cardinality: pref.Optional, Kind: pref.FloatKind},
292 {Name: "f7", Number: 7, Cardinality: pref.Optional, Kind: pref.DoubleKind},
293 {Name: "f8", Number: 8, Cardinality: pref.Optional, Kind: pref.StringKind},
294 {Name: "f9", Number: 9, Cardinality: pref.Optional, Kind: pref.StringKind},
295 {Name: "f10", Number: 10, Cardinality: pref.Optional, Kind: pref.BytesKind},
296 {Name: "f11", Number: 11, Cardinality: pref.Optional, Kind: pref.BytesKind},
Joe Tsaifa02f4e2018-09-12 16:20:37 -0700297
Joe Tsai91e14662018-09-13 13:24:35 -0700298 {Name: "f12", Number: 12, Cardinality: pref.Optional, Kind: pref.BoolKind},
299 {Name: "f13", Number: 13, Cardinality: pref.Optional, Kind: pref.Int32Kind},
300 {Name: "f14", Number: 14, Cardinality: pref.Optional, Kind: pref.Int64Kind},
301 {Name: "f15", Number: 15, Cardinality: pref.Optional, Kind: pref.Uint32Kind},
302 {Name: "f16", Number: 16, Cardinality: pref.Optional, Kind: pref.Uint64Kind},
303 {Name: "f17", Number: 17, Cardinality: pref.Optional, Kind: pref.FloatKind},
304 {Name: "f18", Number: 18, Cardinality: pref.Optional, Kind: pref.DoubleKind},
305 {Name: "f19", Number: 19, Cardinality: pref.Optional, Kind: pref.StringKind},
306 {Name: "f20", Number: 20, Cardinality: pref.Optional, Kind: pref.StringKind},
307 {Name: "f21", Number: 21, Cardinality: pref.Optional, Kind: pref.BytesKind},
308 {Name: "f22", Number: 22, Cardinality: pref.Optional, Kind: pref.BytesKind},
309 },
Joe Tsaif0c01e42018-11-06 13:05:20 -0800310 }),
311 func(pref.MessageType) pref.ProtoMessage {
312 return new(ScalarProto3)
313 },
314)}
Joe Tsai91e14662018-09-13 13:24:35 -0700315
Joe Tsaif0c01e42018-11-06 13:05:20 -0800316func (m *ScalarProto3) Type() pref.MessageType { return scalarProto3Type.Type }
317func (m *ScalarProto3) KnownFields() pref.KnownFields { return scalarProto3Type.KnownFieldsOf(m) }
318func (m *ScalarProto3) UnknownFields() pref.UnknownFields { return scalarProto3Type.UnknownFieldsOf(m) }
319func (m *ScalarProto3) Interface() pref.ProtoMessage { return m }
320func (m *ScalarProto3) ProtoReflect() pref.Message { return m }
321func (m *ScalarProto3) ProtoMutable() {}
322
323func TestScalarProto3(t *testing.T) {
324 testMessage(t, nil, &ScalarProto3{}, messageOps{
Joe Tsai91e14662018-09-13 13:24:35 -0700325 hasFields{
326 1: false, 2: false, 3: false, 4: false, 5: false, 6: false, 7: false, 8: false, 9: false, 10: false, 11: false,
327 12: false, 13: false, 14: false, 15: false, 16: false, 17: false, 18: false, 19: false, 20: false, 21: false, 22: false,
328 },
329 getFields{
330 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)),
331 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)),
332 },
333 setFields{
334 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)),
335 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)),
336 },
337 hasFields{
338 1: false, 2: false, 3: false, 4: false, 5: false, 6: false, 7: false, 8: false, 9: false, 10: false, 11: false,
339 12: false, 13: false, 14: false, 15: false, 16: false, 17: false, 18: false, 19: false, 20: false, 21: false, 22: false,
340 },
Joe Tsai87b955b2018-11-14 21:59:49 -0800341 equalMessage{&ScalarProto3{}},
Joe Tsai91e14662018-09-13 13:24:35 -0700342 setFields{
343 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")),
344 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")),
345 },
346 hasFields{
347 1: true, 2: true, 3: true, 4: true, 5: true, 6: true, 7: true, 8: true, 9: true, 10: true, 11: true,
348 12: true, 13: true, 14: true, 15: true, 16: true, 17: true, 18: true, 19: true, 20: true, 21: true, 22: true,
349 },
Joe Tsai87b955b2018-11-14 21:59:49 -0800350 equalMessage{&ScalarProto3{
Joe Tsai91e14662018-09-13 13:24:35 -0700351 true, 2, 3, 4, 5, 6, 7, "8", []byte("9"), []byte("10"), "11",
352 true, 13, 14, 15, 16, 17, 18, "19", []byte("20"), []byte("21"), "22",
Joe Tsai87b955b2018-11-14 21:59:49 -0800353 }},
Joe Tsai44e389c2018-11-19 15:27:09 -0800354 setFields{
355 2: V(int32(-2)), 3: V(int64(-3)), 6: V(float32(math.Inf(-1))), 7: V(float64(math.NaN())),
356 },
357 hasFields{
358 2: true, 3: true, 6: true, 7: true,
359 },
Joe Tsai87b955b2018-11-14 21:59:49 -0800360 clearFields{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22},
361 equalMessage{&ScalarProto3{}},
Joe Tsai91e14662018-09-13 13:24:35 -0700362 })
Joe Tsaifa02f4e2018-09-12 16:20:37 -0700363}
364
Joe Tsaif0c01e42018-11-06 13:05:20 -0800365type ListScalars struct {
Joe Tsaice6edd32018-10-19 16:27:46 -0700366 Bools []bool `protobuf:"1"`
367 Int32s []int32 `protobuf:"2"`
368 Int64s []int64 `protobuf:"3"`
369 Uint32s []uint32 `protobuf:"4"`
370 Uint64s []uint64 `protobuf:"5"`
371 Float32s []float32 `protobuf:"6"`
372 Float64s []float64 `protobuf:"7"`
373 Strings []string `protobuf:"8"`
374 StringsA [][]byte `protobuf:"9"`
375 Bytes [][]byte `protobuf:"10"`
376 BytesA []string `protobuf:"11"`
377
378 MyStrings1 []MyString `protobuf:"12"`
379 MyStrings2 []MyBytes `protobuf:"13"`
380 MyBytes1 []MyBytes `protobuf:"14"`
381 MyBytes2 []MyString `protobuf:"15"`
382
Joe Tsai4b7aff62018-11-14 14:05:19 -0800383 MyStrings3 ListStrings `protobuf:"16"`
384 MyStrings4 ListBytes `protobuf:"17"`
385 MyBytes3 ListBytes `protobuf:"18"`
386 MyBytes4 ListStrings `protobuf:"19"`
Joe Tsaice6edd32018-10-19 16:27:46 -0700387}
388
Joe Tsaif0c01e42018-11-06 13:05:20 -0800389var listScalarsType = MessageType{Type: ptype.GoMessage(
390 mustMakeMessageDesc(ptype.StandaloneMessage{
Joe Tsai91e14662018-09-13 13:24:35 -0700391 Syntax: pref.Proto2,
Joe Tsaif0c01e42018-11-06 13:05:20 -0800392 FullName: "ListScalars",
Joe Tsai91e14662018-09-13 13:24:35 -0700393 Fields: []ptype.Field{
394 {Name: "f1", Number: 1, Cardinality: pref.Repeated, Kind: pref.BoolKind},
395 {Name: "f2", Number: 2, Cardinality: pref.Repeated, Kind: pref.Int32Kind},
396 {Name: "f3", Number: 3, Cardinality: pref.Repeated, Kind: pref.Int64Kind},
397 {Name: "f4", Number: 4, Cardinality: pref.Repeated, Kind: pref.Uint32Kind},
398 {Name: "f5", Number: 5, Cardinality: pref.Repeated, Kind: pref.Uint64Kind},
399 {Name: "f6", Number: 6, Cardinality: pref.Repeated, Kind: pref.FloatKind},
400 {Name: "f7", Number: 7, Cardinality: pref.Repeated, Kind: pref.DoubleKind},
401 {Name: "f8", Number: 8, Cardinality: pref.Repeated, Kind: pref.StringKind},
402 {Name: "f9", Number: 9, Cardinality: pref.Repeated, Kind: pref.StringKind},
403 {Name: "f10", Number: 10, Cardinality: pref.Repeated, Kind: pref.BytesKind},
404 {Name: "f11", Number: 11, Cardinality: pref.Repeated, Kind: pref.BytesKind},
Joe Tsaifa02f4e2018-09-12 16:20:37 -0700405
Joe Tsai91e14662018-09-13 13:24:35 -0700406 {Name: "f12", Number: 12, Cardinality: pref.Repeated, Kind: pref.StringKind},
407 {Name: "f13", Number: 13, Cardinality: pref.Repeated, Kind: pref.StringKind},
408 {Name: "f14", Number: 14, Cardinality: pref.Repeated, Kind: pref.BytesKind},
409 {Name: "f15", Number: 15, Cardinality: pref.Repeated, Kind: pref.BytesKind},
410
411 {Name: "f16", Number: 16, Cardinality: pref.Repeated, Kind: pref.StringKind},
412 {Name: "f17", Number: 17, Cardinality: pref.Repeated, Kind: pref.StringKind},
413 {Name: "f18", Number: 18, Cardinality: pref.Repeated, Kind: pref.BytesKind},
414 {Name: "f19", Number: 19, Cardinality: pref.Repeated, Kind: pref.BytesKind},
Joe Tsaifa02f4e2018-09-12 16:20:37 -0700415 },
Joe Tsaif0c01e42018-11-06 13:05:20 -0800416 }),
417 func(pref.MessageType) pref.ProtoMessage {
418 return new(ListScalars)
419 },
420)}
Joe Tsai91e14662018-09-13 13:24:35 -0700421
Joe Tsaif0c01e42018-11-06 13:05:20 -0800422func (m *ListScalars) Type() pref.MessageType { return listScalarsType.Type }
423func (m *ListScalars) KnownFields() pref.KnownFields { return listScalarsType.KnownFieldsOf(m) }
424func (m *ListScalars) UnknownFields() pref.UnknownFields { return listScalarsType.UnknownFieldsOf(m) }
425func (m *ListScalars) Interface() pref.ProtoMessage { return m }
426func (m *ListScalars) ProtoReflect() pref.Message { return m }
427func (m *ListScalars) ProtoMutable() {}
428
429func TestListScalars(t *testing.T) {
430 empty := &ListScalars{}
Joe Tsai91e14662018-09-13 13:24:35 -0700431 emptyFS := empty.KnownFields()
432
Joe Tsaif0c01e42018-11-06 13:05:20 -0800433 want := &ListScalars{
Joe Tsai91e14662018-09-13 13:24:35 -0700434 Bools: []bool{true, false, true},
435 Int32s: []int32{2, math.MinInt32, math.MaxInt32},
436 Int64s: []int64{3, math.MinInt64, math.MaxInt64},
437 Uint32s: []uint32{4, math.MaxUint32 / 2, math.MaxUint32},
438 Uint64s: []uint64{5, math.MaxUint64 / 2, math.MaxUint64},
439 Float32s: []float32{6, math.SmallestNonzeroFloat32, float32(math.NaN()), math.MaxFloat32},
440 Float64s: []float64{7, math.SmallestNonzeroFloat64, float64(math.NaN()), math.MaxFloat64},
441 Strings: []string{"8", "", "eight"},
442 StringsA: [][]byte{[]byte("9"), nil, []byte("nine")},
443 Bytes: [][]byte{[]byte("10"), nil, []byte("ten")},
444 BytesA: []string{"11", "", "eleven"},
445
446 MyStrings1: []MyString{"12", "", "twelve"},
447 MyStrings2: []MyBytes{[]byte("13"), nil, []byte("thirteen")},
448 MyBytes1: []MyBytes{[]byte("14"), nil, []byte("fourteen")},
449 MyBytes2: []MyString{"15", "", "fifteen"},
450
Joe Tsai4b7aff62018-11-14 14:05:19 -0800451 MyStrings3: ListStrings{"16", "", "sixteen"},
452 MyStrings4: ListBytes{[]byte("17"), nil, []byte("seventeen")},
453 MyBytes3: ListBytes{[]byte("18"), nil, []byte("eighteen")},
454 MyBytes4: ListStrings{"19", "", "nineteen"},
Joe Tsaif0c01e42018-11-06 13:05:20 -0800455 }
Joe Tsai91e14662018-09-13 13:24:35 -0700456 wantFS := want.KnownFields()
457
Joe Tsaif0c01e42018-11-06 13:05:20 -0800458 testMessage(t, nil, &ListScalars{}, messageOps{
Joe Tsai91e14662018-09-13 13:24:35 -0700459 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},
460 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)},
461 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 -0800462 listFields{
Joe Tsai91e14662018-09-13 13:24:35 -0700463 2: {
Joe Tsai4b7aff62018-11-14 14:05:19 -0800464 lenList(0),
465 appendList{V(int32(2)), V(int32(math.MinInt32)), V(int32(math.MaxInt32))},
466 getList{0: V(int32(2)), 1: V(int32(math.MinInt32)), 2: V(int32(math.MaxInt32))},
Joe Tsai87b955b2018-11-14 21:59:49 -0800467 equalList{wantFS.Get(2).List()},
Joe Tsai91e14662018-09-13 13:24:35 -0700468 },
469 4: {
Joe Tsai4b7aff62018-11-14 14:05:19 -0800470 appendList{V(uint32(0)), V(uint32(0)), V(uint32(0))},
471 setList{0: V(uint32(4)), 1: V(uint32(math.MaxUint32 / 2)), 2: V(uint32(math.MaxUint32))},
472 lenList(3),
Joe Tsai91e14662018-09-13 13:24:35 -0700473 },
474 6: {
Joe Tsai4b7aff62018-11-14 14:05:19 -0800475 appendList{V(float32(6)), V(float32(math.SmallestNonzeroFloat32)), V(float32(math.NaN())), V(float32(math.MaxFloat32))},
Joe Tsai87b955b2018-11-14 21:59:49 -0800476 equalList{wantFS.Get(6).List()},
Joe Tsai91e14662018-09-13 13:24:35 -0700477 },
478 8: {
Joe Tsai4b7aff62018-11-14 14:05:19 -0800479 appendList{V(""), V(""), V(""), V(""), V(""), V("")},
480 lenList(6),
481 setList{0: V("8"), 2: V("eight")},
482 truncList(3),
Joe Tsai87b955b2018-11-14 21:59:49 -0800483 equalList{wantFS.Get(8).List()},
Joe Tsai91e14662018-09-13 13:24:35 -0700484 },
485 10: {
Joe Tsai4b7aff62018-11-14 14:05:19 -0800486 appendList{V([]byte(nil)), V([]byte(nil))},
487 setList{0: V([]byte("10"))},
488 appendList{V([]byte("wrong"))},
489 setList{2: V([]byte("ten"))},
Joe Tsai87b955b2018-11-14 21:59:49 -0800490 equalList{wantFS.Get(10).List()},
Joe Tsai91e14662018-09-13 13:24:35 -0700491 },
492 12: {
Joe Tsai4b7aff62018-11-14 14:05:19 -0800493 appendList{V("12"), V("wrong"), V("twelve")},
494 setList{1: V("")},
Joe Tsai87b955b2018-11-14 21:59:49 -0800495 equalList{wantFS.Get(12).List()},
Joe Tsai91e14662018-09-13 13:24:35 -0700496 },
497 14: {
Joe Tsai4b7aff62018-11-14 14:05:19 -0800498 appendList{V([]byte("14")), V([]byte(nil)), V([]byte("fourteen"))},
Joe Tsai87b955b2018-11-14 21:59:49 -0800499 equalList{wantFS.Get(14).List()},
Joe Tsai91e14662018-09-13 13:24:35 -0700500 },
501 16: {
Joe Tsai4b7aff62018-11-14 14:05:19 -0800502 appendList{V("16"), V(""), V("sixteen"), V("extra")},
503 truncList(3),
Joe Tsai87b955b2018-11-14 21:59:49 -0800504 equalList{wantFS.Get(16).List()},
Joe Tsai91e14662018-09-13 13:24:35 -0700505 },
506 18: {
Joe Tsai4b7aff62018-11-14 14:05:19 -0800507 appendList{V([]byte("18")), V([]byte(nil)), V([]byte("eighteen"))},
Joe Tsai87b955b2018-11-14 21:59:49 -0800508 equalList{wantFS.Get(18).List()},
Joe Tsai91e14662018-09-13 13:24:35 -0700509 },
Joe Tsaifa02f4e2018-09-12 16:20:37 -0700510 },
Joe Tsai91e14662018-09-13 13:24:35 -0700511 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 -0800512 equalMessage{want},
513 clearFields{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19},
514 equalMessage{empty},
Joe Tsaibbfaeb72018-10-17 00:27:21 +0000515 })
516}
517
Joe Tsaice6edd32018-10-19 16:27:46 -0700518type MapScalars struct {
519 KeyBools map[bool]string `protobuf:"1"`
520 KeyInt32s map[int32]string `protobuf:"2"`
521 KeyInt64s map[int64]string `protobuf:"3"`
522 KeyUint32s map[uint32]string `protobuf:"4"`
523 KeyUint64s map[uint64]string `protobuf:"5"`
524 KeyStrings map[string]string `protobuf:"6"`
525
526 ValBools map[string]bool `protobuf:"7"`
527 ValInt32s map[string]int32 `protobuf:"8"`
528 ValInt64s map[string]int64 `protobuf:"9"`
529 ValUint32s map[string]uint32 `protobuf:"10"`
530 ValUint64s map[string]uint64 `protobuf:"11"`
531 ValFloat32s map[string]float32 `protobuf:"12"`
532 ValFloat64s map[string]float64 `protobuf:"13"`
533 ValStrings map[string]string `protobuf:"14"`
534 ValStringsA map[string][]byte `protobuf:"15"`
535 ValBytes map[string][]byte `protobuf:"16"`
536 ValBytesA map[string]string `protobuf:"17"`
537
538 MyStrings1 map[MyString]MyString `protobuf:"18"`
539 MyStrings2 map[MyString]MyBytes `protobuf:"19"`
540 MyBytes1 map[MyString]MyBytes `protobuf:"20"`
541 MyBytes2 map[MyString]MyString `protobuf:"21"`
542
543 MyStrings3 MapStrings `protobuf:"22"`
544 MyStrings4 MapBytes `protobuf:"23"`
545 MyBytes3 MapBytes `protobuf:"24"`
546 MyBytes4 MapStrings `protobuf:"25"`
547}
548
Joe Tsaif0c01e42018-11-06 13:05:20 -0800549func mustMakeMapEntry(n pref.FieldNumber, keyKind, valKind pref.Kind) ptype.Field {
550 return ptype.Field{
551 Name: pref.Name(fmt.Sprintf("f%d", n)),
552 Number: n,
553 Cardinality: pref.Repeated,
554 Kind: pref.MessageKind,
555 MessageType: mustMakeMessageDesc(ptype.StandaloneMessage{
556 Syntax: pref.Proto2,
557 FullName: pref.FullName(fmt.Sprintf("MapScalars.F%dEntry", n)),
558 Fields: []ptype.Field{
559 {Name: "key", Number: 1, Cardinality: pref.Optional, Kind: keyKind},
560 {Name: "value", Number: 2, Cardinality: pref.Optional, Kind: valKind},
561 },
562 Options: &descriptorV1.MessageOptions{MapEntry: protoV1.Bool(true)},
563 }),
Joe Tsaibbfaeb72018-10-17 00:27:21 +0000564 }
Joe Tsaif0c01e42018-11-06 13:05:20 -0800565}
566
567var mapScalarsType = MessageType{Type: ptype.GoMessage(
568 mustMakeMessageDesc(ptype.StandaloneMessage{
Joe Tsaibbfaeb72018-10-17 00:27:21 +0000569 Syntax: pref.Proto2,
570 FullName: "MapScalars",
571 Fields: []ptype.Field{
572 mustMakeMapEntry(1, pref.BoolKind, pref.StringKind),
573 mustMakeMapEntry(2, pref.Int32Kind, pref.StringKind),
574 mustMakeMapEntry(3, pref.Int64Kind, pref.StringKind),
575 mustMakeMapEntry(4, pref.Uint32Kind, pref.StringKind),
576 mustMakeMapEntry(5, pref.Uint64Kind, pref.StringKind),
577 mustMakeMapEntry(6, pref.StringKind, pref.StringKind),
578
579 mustMakeMapEntry(7, pref.StringKind, pref.BoolKind),
580 mustMakeMapEntry(8, pref.StringKind, pref.Int32Kind),
581 mustMakeMapEntry(9, pref.StringKind, pref.Int64Kind),
582 mustMakeMapEntry(10, pref.StringKind, pref.Uint32Kind),
583 mustMakeMapEntry(11, pref.StringKind, pref.Uint64Kind),
584 mustMakeMapEntry(12, pref.StringKind, pref.FloatKind),
585 mustMakeMapEntry(13, pref.StringKind, pref.DoubleKind),
586 mustMakeMapEntry(14, pref.StringKind, pref.StringKind),
587 mustMakeMapEntry(15, pref.StringKind, pref.StringKind),
588 mustMakeMapEntry(16, pref.StringKind, pref.BytesKind),
589 mustMakeMapEntry(17, pref.StringKind, pref.BytesKind),
590
591 mustMakeMapEntry(18, pref.StringKind, pref.StringKind),
592 mustMakeMapEntry(19, pref.StringKind, pref.StringKind),
593 mustMakeMapEntry(20, pref.StringKind, pref.BytesKind),
594 mustMakeMapEntry(21, pref.StringKind, pref.BytesKind),
595
596 mustMakeMapEntry(22, pref.StringKind, pref.StringKind),
597 mustMakeMapEntry(23, pref.StringKind, pref.StringKind),
598 mustMakeMapEntry(24, pref.StringKind, pref.BytesKind),
599 mustMakeMapEntry(25, pref.StringKind, pref.BytesKind),
600 },
Joe Tsaif0c01e42018-11-06 13:05:20 -0800601 }),
602 func(pref.MessageType) pref.ProtoMessage {
603 return new(MapScalars)
604 },
605)}
Joe Tsaibbfaeb72018-10-17 00:27:21 +0000606
Joe Tsaif0c01e42018-11-06 13:05:20 -0800607func (m *MapScalars) Type() pref.MessageType { return mapScalarsType.Type }
608func (m *MapScalars) KnownFields() pref.KnownFields { return mapScalarsType.KnownFieldsOf(m) }
609func (m *MapScalars) UnknownFields() pref.UnknownFields { return mapScalarsType.UnknownFieldsOf(m) }
610func (m *MapScalars) Interface() pref.ProtoMessage { return m }
611func (m *MapScalars) ProtoReflect() pref.Message { return m }
612func (m *MapScalars) ProtoMutable() {}
613
614func TestMapScalars(t *testing.T) {
615 empty := &MapScalars{}
Joe Tsaibbfaeb72018-10-17 00:27:21 +0000616 emptyFS := empty.KnownFields()
617
Joe Tsaif0c01e42018-11-06 13:05:20 -0800618 want := &MapScalars{
Joe Tsaibbfaeb72018-10-17 00:27:21 +0000619 KeyBools: map[bool]string{true: "true", false: "false"},
620 KeyInt32s: map[int32]string{0: "zero", -1: "one", 2: "two"},
621 KeyInt64s: map[int64]string{0: "zero", -10: "ten", 20: "twenty"},
622 KeyUint32s: map[uint32]string{0: "zero", 1: "one", 2: "two"},
623 KeyUint64s: map[uint64]string{0: "zero", 10: "ten", 20: "twenty"},
624 KeyStrings: map[string]string{"": "", "foo": "bar"},
625
626 ValBools: map[string]bool{"true": true, "false": false},
627 ValInt32s: map[string]int32{"one": 1, "two": 2, "three": 3},
628 ValInt64s: map[string]int64{"ten": 10, "twenty": -20, "thirty": 30},
629 ValUint32s: map[string]uint32{"0x00": 0x00, "0xff": 0xff, "0xdead": 0xdead},
630 ValUint64s: map[string]uint64{"0x00": 0x00, "0xff": 0xff, "0xdead": 0xdead},
631 ValFloat32s: map[string]float32{"nan": float32(math.NaN()), "pi": float32(math.Pi)},
632 ValFloat64s: map[string]float64{"nan": float64(math.NaN()), "pi": float64(math.Pi)},
633 ValStrings: map[string]string{"s1": "s1", "s2": "s2"},
634 ValStringsA: map[string][]byte{"s1": []byte("s1"), "s2": []byte("s2")},
635 ValBytes: map[string][]byte{"s1": []byte("s1"), "s2": []byte("s2")},
636 ValBytesA: map[string]string{"s1": "s1", "s2": "s2"},
637
638 MyStrings1: map[MyString]MyString{"s1": "s1", "s2": "s2"},
639 MyStrings2: map[MyString]MyBytes{"s1": []byte("s1"), "s2": []byte("s2")},
640 MyBytes1: map[MyString]MyBytes{"s1": []byte("s1"), "s2": []byte("s2")},
641 MyBytes2: map[MyString]MyString{"s1": "s1", "s2": "s2"},
642
643 MyStrings3: MapStrings{"s1": "s1", "s2": "s2"},
644 MyStrings4: MapBytes{"s1": []byte("s1"), "s2": []byte("s2")},
645 MyBytes3: MapBytes{"s1": []byte("s1"), "s2": []byte("s2")},
646 MyBytes4: MapStrings{"s1": "s1", "s2": "s2"},
Joe Tsaif0c01e42018-11-06 13:05:20 -0800647 }
Joe Tsaibbfaeb72018-10-17 00:27:21 +0000648 wantFS := want.KnownFields()
649
Joe Tsaif0c01e42018-11-06 13:05:20 -0800650 testMessage(t, nil, &MapScalars{}, messageOps{
Joe Tsaibbfaeb72018-10-17 00:27:21 +0000651 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},
652 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)},
653 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)},
654 mapFields{
655 2: {
656 lenMap(0),
657 hasMap{int32(0): false, int32(-1): false, int32(2): false},
658 setMap{int32(0): V("zero")},
659 lenMap(1),
660 hasMap{int32(0): true, int32(-1): false, int32(2): false},
661 setMap{int32(-1): V("one")},
662 lenMap(2),
663 hasMap{int32(0): true, int32(-1): true, int32(2): false},
664 setMap{int32(2): V("two")},
665 lenMap(3),
666 hasMap{int32(0): true, int32(-1): true, int32(2): true},
667 },
668 4: {
669 setMap{uint32(0): V("zero"), uint32(1): V("one"), uint32(2): V("two")},
Joe Tsai87b955b2018-11-14 21:59:49 -0800670 equalMap{wantFS.Get(4).Map()},
Joe Tsaibbfaeb72018-10-17 00:27:21 +0000671 },
672 6: {
Joe Tsai87b955b2018-11-14 21:59:49 -0800673 clearMap{"noexist"},
Joe Tsaibbfaeb72018-10-17 00:27:21 +0000674 setMap{"foo": V("bar")},
675 setMap{"": V("empty")},
676 getMap{"": V("empty"), "foo": V("bar"), "noexist": V(nil)},
677 setMap{"": V(""), "extra": V("extra")},
Joe Tsai87b955b2018-11-14 21:59:49 -0800678 clearMap{"extra", "noexist"},
Joe Tsaibbfaeb72018-10-17 00:27:21 +0000679 },
680 8: {
Joe Tsai87b955b2018-11-14 21:59:49 -0800681 equalMap{emptyFS.Get(8).Map()},
Joe Tsaibbfaeb72018-10-17 00:27:21 +0000682 setMap{"one": V(int32(1)), "two": V(int32(2)), "three": V(int32(3))},
683 },
684 10: {
685 setMap{"0x00": V(uint32(0x00)), "0xff": V(uint32(0xff)), "0xdead": V(uint32(0xdead))},
686 lenMap(3),
Joe Tsai87b955b2018-11-14 21:59:49 -0800687 equalMap{wantFS.Get(10).Map()},
Joe Tsaibbfaeb72018-10-17 00:27:21 +0000688 getMap{"0x00": V(uint32(0x00)), "0xff": V(uint32(0xff)), "0xdead": V(uint32(0xdead)), "0xdeadbeef": V(nil)},
689 },
690 12: {
691 setMap{"nan": V(float32(math.NaN())), "pi": V(float32(math.Pi)), "e": V(float32(math.E))},
Joe Tsai87b955b2018-11-14 21:59:49 -0800692 clearMap{"e", "phi"},
Joe Tsaibbfaeb72018-10-17 00:27:21 +0000693 rangeMap{"nan": V(float32(math.NaN())), "pi": V(float32(math.Pi))},
694 },
695 14: {
Joe Tsai87b955b2018-11-14 21:59:49 -0800696 equalMap{emptyFS.Get(14).Map()},
Joe Tsaibbfaeb72018-10-17 00:27:21 +0000697 setMap{"s1": V("s1"), "s2": V("s2")},
698 },
699 16: {
700 setMap{"s1": V([]byte("s1")), "s2": V([]byte("s2"))},
Joe Tsai87b955b2018-11-14 21:59:49 -0800701 equalMap{wantFS.Get(16).Map()},
Joe Tsaibbfaeb72018-10-17 00:27:21 +0000702 },
703 18: {
704 hasMap{"s1": false, "s2": false, "s3": false},
705 setMap{"s1": V("s1"), "s2": V("s2")},
706 hasMap{"s1": true, "s2": true, "s3": false},
707 },
708 20: {
Joe Tsai87b955b2018-11-14 21:59:49 -0800709 equalMap{emptyFS.Get(20).Map()},
Joe Tsaibbfaeb72018-10-17 00:27:21 +0000710 setMap{"s1": V([]byte("s1")), "s2": V([]byte("s2"))},
711 },
712 22: {
713 rangeMap{},
714 setMap{"s1": V("s1"), "s2": V("s2")},
715 rangeMap{"s1": V("s1"), "s2": V("s2")},
716 lenMap(2),
717 },
718 24: {
719 setMap{"s1": V([]byte("s1")), "s2": V([]byte("s2"))},
Joe Tsai87b955b2018-11-14 21:59:49 -0800720 equalMap{wantFS.Get(24).Map()},
Joe Tsaibbfaeb72018-10-17 00:27:21 +0000721 },
722 },
723 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 -0800724 equalMessage{want},
725 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},
726 equalMessage{empty},
Joe Tsai91e14662018-09-13 13:24:35 -0700727 })
728}
Joe Tsaifa02f4e2018-09-12 16:20:37 -0700729
Joe Tsai87b955b2018-11-14 21:59:49 -0800730type OneofScalars struct {
731 Union isOneofScalars_Union `protobuf_oneof:"union"`
732}
Joe Tsai2c870bb2018-10-17 11:46:52 -0700733
Joe Tsaif0c01e42018-11-06 13:05:20 -0800734var oneofScalarsType = MessageType{Type: ptype.GoMessage(
735 mustMakeMessageDesc(ptype.StandaloneMessage{
736 Syntax: pref.Proto2,
Joe Tsai87b955b2018-11-14 21:59:49 -0800737 FullName: "OneofScalars",
Joe Tsaif0c01e42018-11-06 13:05:20 -0800738 Fields: []ptype.Field{
739 {Name: "f1", Number: 1, Cardinality: pref.Optional, Kind: pref.BoolKind, Default: V(bool(true)), OneofName: "union"},
740 {Name: "f2", Number: 2, Cardinality: pref.Optional, Kind: pref.Int32Kind, Default: V(int32(2)), OneofName: "union"},
741 {Name: "f3", Number: 3, Cardinality: pref.Optional, Kind: pref.Int64Kind, Default: V(int64(3)), OneofName: "union"},
742 {Name: "f4", Number: 4, Cardinality: pref.Optional, Kind: pref.Uint32Kind, Default: V(uint32(4)), OneofName: "union"},
743 {Name: "f5", Number: 5, Cardinality: pref.Optional, Kind: pref.Uint64Kind, Default: V(uint64(5)), OneofName: "union"},
744 {Name: "f6", Number: 6, Cardinality: pref.Optional, Kind: pref.FloatKind, Default: V(float32(6)), OneofName: "union"},
745 {Name: "f7", Number: 7, Cardinality: pref.Optional, Kind: pref.DoubleKind, Default: V(float64(7)), OneofName: "union"},
746 {Name: "f8", Number: 8, Cardinality: pref.Optional, Kind: pref.StringKind, Default: V(string("8")), OneofName: "union"},
747 {Name: "f9", Number: 9, Cardinality: pref.Optional, Kind: pref.StringKind, Default: V(string("9")), OneofName: "union"},
748 {Name: "f10", Number: 10, Cardinality: pref.Optional, Kind: pref.StringKind, Default: V(string("10")), OneofName: "union"},
749 {Name: "f11", Number: 11, Cardinality: pref.Optional, Kind: pref.BytesKind, Default: V([]byte("11")), OneofName: "union"},
750 {Name: "f12", Number: 12, Cardinality: pref.Optional, Kind: pref.BytesKind, Default: V([]byte("12")), OneofName: "union"},
751 {Name: "f13", Number: 13, Cardinality: pref.Optional, Kind: pref.BytesKind, Default: V([]byte("13")), OneofName: "union"},
752 },
753 Oneofs: []ptype.Oneof{{Name: "union"}},
754 }),
755 func(pref.MessageType) pref.ProtoMessage {
756 return new(OneofScalars)
757 },
758)}
759
760func (m *OneofScalars) Type() pref.MessageType { return oneofScalarsType.Type }
761func (m *OneofScalars) KnownFields() pref.KnownFields { return oneofScalarsType.KnownFieldsOf(m) }
762func (m *OneofScalars) UnknownFields() pref.UnknownFields { return oneofScalarsType.UnknownFieldsOf(m) }
763func (m *OneofScalars) Interface() pref.ProtoMessage { return m }
764func (m *OneofScalars) ProtoReflect() pref.Message { return m }
765func (m *OneofScalars) ProtoMutable() {}
766
767func (*OneofScalars) XXX_OneofFuncs() (func(protoV1.Message, *protoV1.Buffer) error, func(protoV1.Message, int, int, *protoV1.Buffer) (bool, error), func(protoV1.Message) int, []interface{}) {
Joe Tsai2c870bb2018-10-17 11:46:52 -0700768 return nil, nil, nil, []interface{}{
769 (*OneofScalars_Bool)(nil),
770 (*OneofScalars_Int32)(nil),
771 (*OneofScalars_Int64)(nil),
772 (*OneofScalars_Uint32)(nil),
773 (*OneofScalars_Uint64)(nil),
774 (*OneofScalars_Float32)(nil),
775 (*OneofScalars_Float64)(nil),
776 (*OneofScalars_String)(nil),
777 (*OneofScalars_StringA)(nil),
778 (*OneofScalars_StringB)(nil),
779 (*OneofScalars_Bytes)(nil),
780 (*OneofScalars_BytesA)(nil),
781 (*OneofScalars_BytesB)(nil),
782 }
783}
784
Joe Tsai87b955b2018-11-14 21:59:49 -0800785type (
786 isOneofScalars_Union interface {
787 isOneofScalars_Union()
788 }
789 OneofScalars_Bool struct {
790 Bool bool `protobuf:"1"`
791 }
792 OneofScalars_Int32 struct {
793 Int32 MyInt32 `protobuf:"2"`
794 }
795 OneofScalars_Int64 struct {
796 Int64 int64 `protobuf:"3"`
797 }
798 OneofScalars_Uint32 struct {
799 Uint32 MyUint32 `protobuf:"4"`
800 }
801 OneofScalars_Uint64 struct {
802 Uint64 uint64 `protobuf:"5"`
803 }
804 OneofScalars_Float32 struct {
805 Float32 MyFloat32 `protobuf:"6"`
806 }
807 OneofScalars_Float64 struct {
808 Float64 float64 `protobuf:"7"`
809 }
810 OneofScalars_String struct {
811 String string `protobuf:"8"`
812 }
813 OneofScalars_StringA struct {
814 StringA []byte `protobuf:"9"`
815 }
816 OneofScalars_StringB struct {
817 StringB MyString `protobuf:"10"`
818 }
819 OneofScalars_Bytes struct {
820 Bytes []byte `protobuf:"11"`
821 }
822 OneofScalars_BytesA struct {
823 BytesA string `protobuf:"12"`
824 }
825 OneofScalars_BytesB struct {
826 BytesB MyBytes `protobuf:"13"`
827 }
828)
829
Joe Tsai2c870bb2018-10-17 11:46:52 -0700830func (*OneofScalars_Bool) isOneofScalars_Union() {}
831func (*OneofScalars_Int32) isOneofScalars_Union() {}
832func (*OneofScalars_Int64) isOneofScalars_Union() {}
833func (*OneofScalars_Uint32) isOneofScalars_Union() {}
834func (*OneofScalars_Uint64) isOneofScalars_Union() {}
835func (*OneofScalars_Float32) isOneofScalars_Union() {}
836func (*OneofScalars_Float64) isOneofScalars_Union() {}
837func (*OneofScalars_String) isOneofScalars_Union() {}
838func (*OneofScalars_StringA) isOneofScalars_Union() {}
839func (*OneofScalars_StringB) isOneofScalars_Union() {}
840func (*OneofScalars_Bytes) isOneofScalars_Union() {}
841func (*OneofScalars_BytesA) isOneofScalars_Union() {}
842func (*OneofScalars_BytesB) isOneofScalars_Union() {}
843
844func TestOneofs(t *testing.T) {
Joe Tsaif0c01e42018-11-06 13:05:20 -0800845 empty := &OneofScalars{}
846 want1 := &OneofScalars{Union: &OneofScalars_Bool{true}}
847 want2 := &OneofScalars{Union: &OneofScalars_Int32{20}}
848 want3 := &OneofScalars{Union: &OneofScalars_Int64{30}}
849 want4 := &OneofScalars{Union: &OneofScalars_Uint32{40}}
850 want5 := &OneofScalars{Union: &OneofScalars_Uint64{50}}
851 want6 := &OneofScalars{Union: &OneofScalars_Float32{60}}
852 want7 := &OneofScalars{Union: &OneofScalars_Float64{70}}
853 want8 := &OneofScalars{Union: &OneofScalars_String{string("80")}}
854 want9 := &OneofScalars{Union: &OneofScalars_StringA{[]byte("90")}}
855 want10 := &OneofScalars{Union: &OneofScalars_StringB{MyString("100")}}
856 want11 := &OneofScalars{Union: &OneofScalars_Bytes{[]byte("110")}}
857 want12 := &OneofScalars{Union: &OneofScalars_BytesA{string("120")}}
858 want13 := &OneofScalars{Union: &OneofScalars_BytesB{MyBytes("130")}}
Joe Tsai2c870bb2018-10-17 11:46:52 -0700859
Joe Tsaif0c01e42018-11-06 13:05:20 -0800860 testMessage(t, nil, &OneofScalars{}, messageOps{
Joe Tsai2c870bb2018-10-17 11:46:52 -0700861 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},
862 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"))},
863
Joe Tsai87b955b2018-11-14 21:59:49 -0800864 setFields{1: V(bool(true))}, hasFields{1: true}, equalMessage{want1},
865 setFields{2: V(int32(20))}, hasFields{2: true}, equalMessage{want2},
866 setFields{3: V(int64(30))}, hasFields{3: true}, equalMessage{want3},
867 setFields{4: V(uint32(40))}, hasFields{4: true}, equalMessage{want4},
868 setFields{5: V(uint64(50))}, hasFields{5: true}, equalMessage{want5},
869 setFields{6: V(float32(60))}, hasFields{6: true}, equalMessage{want6},
870 setFields{7: V(float64(70))}, hasFields{7: true}, equalMessage{want7},
871 setFields{8: V(string("80"))}, hasFields{8: true}, equalMessage{want8},
872 setFields{9: V(string("90"))}, hasFields{9: true}, equalMessage{want9},
873 setFields{10: V(string("100"))}, hasFields{10: true}, equalMessage{want10},
874 setFields{11: V([]byte("110"))}, hasFields{11: true}, equalMessage{want11},
875 setFields{12: V([]byte("120"))}, hasFields{12: true}, equalMessage{want12},
876 setFields{13: V([]byte("130"))}, hasFields{13: true}, equalMessage{want13},
Joe Tsai2c870bb2018-10-17 11:46:52 -0700877
878 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},
879 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 -0800880 clearFields{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12},
881 equalMessage{want13},
882 clearFields{13},
883 equalMessage{empty},
Joe Tsai2c870bb2018-10-17 11:46:52 -0700884 })
885}
886
Joe Tsai87b955b2018-11-14 21:59:49 -0800887type EnumProto2 int32
888
889var enumProto2Type = ptype.GoEnum(
890 mustMakeEnumDesc(ptype.StandaloneEnum{
891 Syntax: pref.Proto2,
892 FullName: "EnumProto2",
893 Values: []ptype.EnumValue{{Name: "DEAD", Number: 0xdead}, {Name: "BEEF", Number: 0xbeef}},
894 }),
895 func(_ pref.EnumType, n pref.EnumNumber) pref.ProtoEnum {
896 return EnumProto2(n)
897 },
898)
899
900func (e EnumProto2) Enum() *EnumProto2 { return &e }
901func (e EnumProto2) Type() pref.EnumType { return enumProto2Type }
902func (e EnumProto2) Number() pref.EnumNumber { return pref.EnumNumber(e) }
903func (e EnumProto2) ProtoReflect() pref.Enum { return e }
904
905type EnumProto3 int32
906
907var enumProto3Type = ptype.GoEnum(
908 mustMakeEnumDesc(ptype.StandaloneEnum{
909 Syntax: pref.Proto3,
910 FullName: "EnumProto3",
911 Values: []ptype.EnumValue{{Name: "ALPHA", Number: 0}, {Name: "BRAVO", Number: 1}},
912 }),
913 func(_ pref.EnumType, n pref.EnumNumber) pref.ProtoEnum {
914 return EnumProto3(n)
915 },
916)
917
918func (e EnumProto3) Enum() *EnumProto3 { return &e }
919func (e EnumProto3) Type() pref.EnumType { return enumProto3Type }
920func (e EnumProto3) Number() pref.EnumNumber { return pref.EnumNumber(e) }
921func (e EnumProto3) ProtoReflect() pref.Enum { return e }
922
923type EnumMessages struct {
924 EnumP2 *EnumProto2 `protobuf:"1"`
925 EnumP3 *EnumProto3 `protobuf:"2"`
926 MessageLegacy *proto2_20180125.Message `protobuf:"3"`
927 MessageCycle *EnumMessages `protobuf:"4"`
928 EnumList []EnumProto2 `protobuf:"5"`
929 MessageList []*ScalarProto2 `protobuf:"6"`
930 EnumMap map[string]EnumProto3 `protobuf:"7"`
931 MessageMap map[string]*ScalarProto3 `protobuf:"8"`
932 Union isEnumMessages_Union `protobuf_oneof:"union"`
933}
934
935var enumMessagesType = MessageType{Type: ptype.GoMessage(
936 mustMakeMessageDesc(ptype.StandaloneMessage{
937 Syntax: pref.Proto2,
938 FullName: "EnumMessages",
939 Fields: []ptype.Field{
940 {Name: "f1", Number: 1, Cardinality: pref.Optional, Kind: pref.EnumKind, Default: V("BEEF"), EnumType: enumProto2Type},
941 {Name: "f2", Number: 2, Cardinality: pref.Optional, Kind: pref.EnumKind, Default: V("BRAVO"), EnumType: enumProto3Type},
942 {Name: "f3", Number: 3, Cardinality: pref.Optional, Kind: pref.MessageKind, MessageType: MessageOf(new(proto2_20180125.Message)).Type()},
943 {Name: "f4", Number: 4, Cardinality: pref.Optional, Kind: pref.MessageKind, MessageType: ptype.PlaceholderMessage("EnumMessages")},
944 {Name: "f5", Number: 5, Cardinality: pref.Repeated, Kind: pref.EnumKind, EnumType: enumProto2Type},
945 {Name: "f6", Number: 6, Cardinality: pref.Repeated, Kind: pref.MessageKind, MessageType: scalarProto2Type.Type},
946 {Name: "f7", Number: 7, Cardinality: pref.Repeated, Kind: pref.MessageKind, MessageType: enumMapDesc},
947 {Name: "f8", Number: 8, Cardinality: pref.Repeated, Kind: pref.MessageKind, MessageType: messageMapDesc},
948 {Name: "f9", Number: 9, Cardinality: pref.Optional, Kind: pref.EnumKind, Default: V("BEEF"), OneofName: "union", EnumType: enumProto2Type},
949 {Name: "f10", Number: 10, Cardinality: pref.Optional, Kind: pref.EnumKind, Default: V("BRAVO"), OneofName: "union", EnumType: enumProto3Type},
950 {Name: "f11", Number: 11, Cardinality: pref.Optional, Kind: pref.MessageKind, OneofName: "union", MessageType: scalarProto2Type.Type},
951 {Name: "f12", Number: 12, Cardinality: pref.Optional, Kind: pref.MessageKind, OneofName: "union", MessageType: scalarProto3Type.Type},
952 },
953 Oneofs: []ptype.Oneof{{Name: "union"}},
954 }),
955 func(pref.MessageType) pref.ProtoMessage {
956 return new(EnumMessages)
957 },
958)}
959
960var enumMapDesc = mustMakeMessageDesc(ptype.StandaloneMessage{
961 Syntax: pref.Proto2,
962 FullName: "EnumMessages.F7Entry",
963 Fields: []ptype.Field{
964 {Name: "key", Number: 1, Cardinality: pref.Optional, Kind: pref.StringKind},
965 {Name: "value", Number: 2, Cardinality: pref.Optional, Kind: pref.EnumKind, EnumType: enumProto3Type},
966 },
967 Options: &descriptorV1.MessageOptions{MapEntry: protoV1.Bool(true)},
968})
969
970var messageMapDesc = mustMakeMessageDesc(ptype.StandaloneMessage{
971 Syntax: pref.Proto2,
972 FullName: "EnumMessages.F8Entry",
973 Fields: []ptype.Field{
974 {Name: "key", Number: 1, Cardinality: pref.Optional, Kind: pref.StringKind},
975 {Name: "value", Number: 2, Cardinality: pref.Optional, Kind: pref.MessageKind, MessageType: scalarProto3Type.Type},
976 },
977 Options: &descriptorV1.MessageOptions{MapEntry: protoV1.Bool(true)},
978})
979
980func (m *EnumMessages) Type() pref.MessageType { return enumMessagesType.Type }
981func (m *EnumMessages) KnownFields() pref.KnownFields { return enumMessagesType.KnownFieldsOf(m) }
982func (m *EnumMessages) UnknownFields() pref.UnknownFields { return enumMessagesType.UnknownFieldsOf(m) }
983func (m *EnumMessages) Interface() pref.ProtoMessage { return m }
984func (m *EnumMessages) ProtoReflect() pref.Message { return m }
985func (m *EnumMessages) ProtoMutable() {}
986
987func (*EnumMessages) XXX_OneofFuncs() (func(protoV1.Message, *protoV1.Buffer) error, func(protoV1.Message, int, int, *protoV1.Buffer) (bool, error), func(protoV1.Message) int, []interface{}) {
988 return nil, nil, nil, []interface{}{
989 (*EnumMessages_OneofE2)(nil),
990 (*EnumMessages_OneofE3)(nil),
991 (*EnumMessages_OneofM2)(nil),
992 (*EnumMessages_OneofM3)(nil),
993 }
994}
995
996type (
997 isEnumMessages_Union interface {
998 isEnumMessages_Union()
999 }
1000 EnumMessages_OneofE2 struct {
1001 OneofE2 EnumProto2 `protobuf:"9"`
1002 }
1003 EnumMessages_OneofE3 struct {
1004 OneofE3 EnumProto3 `protobuf:"10"`
1005 }
1006 EnumMessages_OneofM2 struct {
1007 OneofM2 *ScalarProto2 `protobuf:"11"`
1008 }
1009 EnumMessages_OneofM3 struct {
1010 OneofM3 *ScalarProto3 `protobuf:"12"`
1011 }
1012)
1013
1014func (*EnumMessages_OneofE2) isEnumMessages_Union() {}
1015func (*EnumMessages_OneofE3) isEnumMessages_Union() {}
1016func (*EnumMessages_OneofM2) isEnumMessages_Union() {}
1017func (*EnumMessages_OneofM3) isEnumMessages_Union() {}
1018
1019func TestEnumMessages(t *testing.T) {
1020 // TODO: Test behavior of Get on unpopulated message.
1021 wantL := MessageOf(&proto2_20180125.Message{OptionalFloat: protoV1.Float32(math.E)})
1022 wantM := &EnumMessages{EnumP2: EnumProto2(1234).Enum()}
1023 wantM2a := &ScalarProto2{Float32: protoV1.Float32(math.Pi)}
1024 wantM2b := &ScalarProto2{Float32: protoV1.Float32(math.Phi)}
1025 wantM3a := &ScalarProto3{Float32: math.Pi}
1026 wantM3b := &ScalarProto3{Float32: math.Ln2}
1027
1028 wantList5 := (&EnumMessages{EnumList: []EnumProto2{333, 222}}).KnownFields().Get(5)
1029 wantList6 := (&EnumMessages{MessageList: []*ScalarProto2{wantM2a, wantM2b}}).KnownFields().Get(6)
1030
1031 wantMap7 := (&EnumMessages{EnumMap: map[string]EnumProto3{"one": 1, "two": 2}}).KnownFields().Get(7)
1032 wantMap8 := (&EnumMessages{MessageMap: map[string]*ScalarProto3{"pi": wantM3a, "ln2": wantM3b}}).KnownFields().Get(8)
1033
1034 testMessage(t, nil, &EnumMessages{}, messageOps{
1035 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},
1036 getFields{1: VE(0xbeef), 2: VE(1), 9: VE(0xbeef), 10: VE(1)},
1037
1038 // Test singular enums.
1039 setFields{1: VE(0xdead), 2: VE(0)},
1040 getFields{1: VE(0xdead), 2: VE(0)},
1041 hasFields{1: true, 2: true},
1042
1043 // Test singular messages.
1044 messageFields{3: messageOps{setFields{109: V(float32(math.E))}}},
1045 messageFields{4: messageOps{setFields{1: VE(1234)}}},
1046 getFields{3: V(wantL), 4: V(wantM)},
1047 clearFields{3, 4},
1048 hasFields{3: false, 4: false},
1049 setFields{3: V(wantL), 4: V(wantM)},
1050 hasFields{3: true, 4: true},
1051
1052 // Test list of enums and messages.
1053 listFields{
1054 5: listOps{
1055 appendList{VE(111), VE(222)},
1056 setList{0: VE(333)},
1057 getList{0: VE(333), 1: VE(222)},
1058 lenList(2),
1059 },
1060 6: listOps{
1061 appendMessageList{setFields{4: V(uint32(1e6))}},
1062 appendMessageList{setFields{6: V(float32(math.Phi))}},
1063 setList{0: V(wantM2a)},
1064 getList{0: V(wantM2a), 1: V(wantM2b)},
1065 },
1066 },
1067 getFields{5: wantList5, 6: wantList6},
1068 hasFields{5: true, 6: true},
1069 listFields{5: listOps{truncList(0)}},
1070 hasFields{5: false, 6: true},
1071
1072 // Test maps of enums and messages.
1073 mapFields{
1074 7: mapOps{
1075 setMap{"one": VE(1), "two": VE(2)},
1076 hasMap{"one": true, "two": true, "three": false},
1077 lenMap(2),
1078 },
1079 8: mapOps{
1080 messageMap{"pi": messageOps{setFields{6: V(float32(math.Pi))}}},
1081 setMap{"ln2": V(wantM3b)},
1082 getMap{"pi": V(wantM3a), "ln2": V(wantM3b), "none": V(nil)},
1083 lenMap(2),
1084 },
1085 },
1086 getFields{7: wantMap7, 8: wantMap8},
1087 hasFields{7: true, 8: true},
1088 mapFields{8: mapOps{clearMap{"pi", "ln2", "none"}}},
1089 hasFields{7: true, 8: false},
1090
1091 // Test oneofs of enums and messages.
1092 setFields{9: VE(0xdead)},
1093 hasFields{1: true, 2: true, 9: true, 10: false, 11: false, 12: false},
1094 setFields{10: VE(0)},
1095 hasFields{1: true, 2: true, 9: false, 10: true, 11: false, 12: false},
1096 messageFields{11: messageOps{setFields{6: V(float32(math.Pi))}}},
1097 getFields{11: V(wantM2a)},
1098 hasFields{1: true, 2: true, 9: false, 10: false, 11: true, 12: false},
1099 messageFields{12: messageOps{setFields{6: V(float32(math.Pi))}}},
1100 getFields{12: V(wantM3a)},
1101 hasFields{1: true, 2: true, 9: false, 10: false, 11: false, 12: true},
1102
1103 // Check entire message.
1104 rangeFields{1: VE(0xdead), 2: VE(0), 3: V(wantL), 4: V(wantM), 6: wantList6, 7: wantMap7, 12: V(wantM3a)},
1105 equalMessage{&EnumMessages{
1106 EnumP2: EnumProto2(0xdead).Enum(),
1107 EnumP3: EnumProto3(0).Enum(),
1108 MessageLegacy: &proto2_20180125.Message{OptionalFloat: protoV1.Float32(math.E)},
1109 MessageCycle: wantM,
1110 MessageList: []*ScalarProto2{wantM2a, wantM2b},
1111 EnumMap: map[string]EnumProto3{"one": 1, "two": 2},
1112 Union: &EnumMessages_OneofM3{wantM3a},
1113 }},
1114 clearFields{1, 2, 3, 4, 6, 7, 12},
1115 equalMessage{&EnumMessages{}},
1116 })
1117}
Joe Tsaifa02f4e2018-09-12 16:20:37 -07001118
Joe Tsai91e14662018-09-13 13:24:35 -07001119var cmpOpts = cmp.Options{
Joe Tsai87b955b2018-11-14 21:59:49 -08001120 cmp.Comparer(func(x, y *proto2_20180125.Message) bool {
1121 return protoV1.Equal(x, y)
Joe Tsai91e14662018-09-13 13:24:35 -07001122 }),
Joe Tsai87b955b2018-11-14 21:59:49 -08001123 cmp.Transformer("UnwrapValue", func(pv pref.Value) interface{} {
1124 return pv.Interface()
Joe Tsai91e14662018-09-13 13:24:35 -07001125 }),
Joe Tsai87b955b2018-11-14 21:59:49 -08001126 cmp.Transformer("UnwrapGeneric", func(x pvalue.Unwrapper) interface{} {
1127 return x.Unwrap()
Joe Tsai91e14662018-09-13 13:24:35 -07001128 }),
1129 cmpopts.EquateNaNs(),
Joe Tsai87b955b2018-11-14 21:59:49 -08001130 cmpopts.EquateEmpty(),
Joe Tsai91e14662018-09-13 13:24:35 -07001131}
1132
1133func testMessage(t *testing.T, p path, m pref.Message, tt messageOps) {
1134 fs := m.KnownFields()
1135 for i, op := range tt {
1136 p.Push(i)
1137 switch op := op.(type) {
1138 case equalMessage:
Joe Tsai87b955b2018-11-14 21:59:49 -08001139 if diff := cmp.Diff(op.Message, m, cmpOpts); diff != "" {
Joe Tsai91e14662018-09-13 13:24:35 -07001140 t.Errorf("operation %v, message mismatch (-want, +got):\n%s", p, diff)
1141 }
1142 case hasFields:
1143 got := map[pref.FieldNumber]bool{}
1144 want := map[pref.FieldNumber]bool(op)
1145 for n := range want {
1146 got[n] = fs.Has(n)
1147 }
1148 if diff := cmp.Diff(want, got); diff != "" {
1149 t.Errorf("operation %v, KnownFields.Has mismatch (-want, +got):\n%s", p, diff)
1150 }
1151 case getFields:
1152 got := map[pref.FieldNumber]pref.Value{}
1153 want := map[pref.FieldNumber]pref.Value(op)
1154 for n := range want {
1155 got[n] = fs.Get(n)
1156 }
1157 if diff := cmp.Diff(want, got, cmpOpts); diff != "" {
1158 t.Errorf("operation %v, KnownFields.Get mismatch (-want, +got):\n%s", p, diff)
1159 }
1160 case setFields:
1161 for n, v := range op {
1162 fs.Set(n, v)
1163 }
1164 case clearFields:
Joe Tsai87b955b2018-11-14 21:59:49 -08001165 for _, n := range op {
1166 fs.Clear(n)
1167 }
1168 case messageFields:
1169 for n, tt := range op {
1170 p.Push(int(n))
1171 testMessage(t, p, fs.Mutable(n).(pref.Message), tt)
1172 p.Pop()
Joe Tsaifa02f4e2018-09-12 16:20:37 -07001173 }
Joe Tsai4b7aff62018-11-14 14:05:19 -08001174 case listFields:
Joe Tsai91e14662018-09-13 13:24:35 -07001175 for n, tt := range op {
1176 p.Push(int(n))
Joe Tsai4b7aff62018-11-14 14:05:19 -08001177 testLists(t, p, fs.Mutable(n).(pref.List), tt)
Joe Tsai91e14662018-09-13 13:24:35 -07001178 p.Pop()
1179 }
Joe Tsaibbfaeb72018-10-17 00:27:21 +00001180 case mapFields:
1181 for n, tt := range op {
1182 p.Push(int(n))
1183 testMaps(t, p, fs.Mutable(n).(pref.Map), tt)
1184 p.Pop()
1185 }
Joe Tsai87b955b2018-11-14 21:59:49 -08001186 case rangeFields:
1187 got := map[pref.FieldNumber]pref.Value{}
1188 want := map[pref.FieldNumber]pref.Value(op)
1189 fs.Range(func(n pref.FieldNumber, v pref.Value) bool {
1190 got[n] = v
1191 return true
1192 })
1193 if diff := cmp.Diff(want, got, cmpOpts); diff != "" {
1194 t.Errorf("operation %v, KnownFields.Range mismatch (-want, +got):\n%s", p, diff)
1195 }
Joe Tsai91e14662018-09-13 13:24:35 -07001196 default:
1197 t.Fatalf("operation %v, invalid operation: %T", p, op)
1198 }
1199 p.Pop()
Joe Tsaifa02f4e2018-09-12 16:20:37 -07001200 }
1201}
Joe Tsai91e14662018-09-13 13:24:35 -07001202
Joe Tsai4b7aff62018-11-14 14:05:19 -08001203func testLists(t *testing.T, p path, v pref.List, tt listOps) {
Joe Tsai91e14662018-09-13 13:24:35 -07001204 for i, op := range tt {
1205 p.Push(i)
1206 switch op := op.(type) {
Joe Tsai4b7aff62018-11-14 14:05:19 -08001207 case equalList:
Joe Tsai87b955b2018-11-14 21:59:49 -08001208 if diff := cmp.Diff(op.List, v, cmpOpts); diff != "" {
Joe Tsai4b7aff62018-11-14 14:05:19 -08001209 t.Errorf("operation %v, list mismatch (-want, +got):\n%s", p, diff)
Joe Tsai91e14662018-09-13 13:24:35 -07001210 }
Joe Tsai4b7aff62018-11-14 14:05:19 -08001211 case lenList:
Joe Tsai91e14662018-09-13 13:24:35 -07001212 if got, want := v.Len(), int(op); got != want {
Joe Tsai4b7aff62018-11-14 14:05:19 -08001213 t.Errorf("operation %v, List.Len = %d, want %d", p, got, want)
Joe Tsai91e14662018-09-13 13:24:35 -07001214 }
Joe Tsai4b7aff62018-11-14 14:05:19 -08001215 case getList:
Joe Tsai91e14662018-09-13 13:24:35 -07001216 got := map[int]pref.Value{}
1217 want := map[int]pref.Value(op)
1218 for n := range want {
1219 got[n] = v.Get(n)
1220 }
1221 if diff := cmp.Diff(want, got, cmpOpts); diff != "" {
Joe Tsai4b7aff62018-11-14 14:05:19 -08001222 t.Errorf("operation %v, List.Get mismatch (-want, +got):\n%s", p, diff)
Joe Tsai91e14662018-09-13 13:24:35 -07001223 }
Joe Tsai4b7aff62018-11-14 14:05:19 -08001224 case setList:
Joe Tsai91e14662018-09-13 13:24:35 -07001225 for n, e := range op {
1226 v.Set(n, e)
1227 }
Joe Tsai4b7aff62018-11-14 14:05:19 -08001228 case appendList:
Joe Tsai91e14662018-09-13 13:24:35 -07001229 for _, e := range op {
1230 v.Append(e)
1231 }
Joe Tsai87b955b2018-11-14 21:59:49 -08001232 case appendMessageList:
1233 testMessage(t, p, v.MutableAppend().(pref.Message), messageOps(op))
Joe Tsai4b7aff62018-11-14 14:05:19 -08001234 case truncList:
Joe Tsai91e14662018-09-13 13:24:35 -07001235 v.Truncate(int(op))
1236 default:
1237 t.Fatalf("operation %v, invalid operation: %T", p, op)
1238 }
1239 p.Pop()
1240 }
1241}
1242
Joe Tsaibbfaeb72018-10-17 00:27:21 +00001243func testMaps(t *testing.T, p path, m pref.Map, tt mapOps) {
1244 for i, op := range tt {
1245 p.Push(i)
1246 switch op := op.(type) {
1247 case equalMap:
Joe Tsai87b955b2018-11-14 21:59:49 -08001248 if diff := cmp.Diff(op.Map, m, cmpOpts); diff != "" {
Joe Tsaibbfaeb72018-10-17 00:27:21 +00001249 t.Errorf("operation %v, map mismatch (-want, +got):\n%s", p, diff)
1250 }
1251 case lenMap:
1252 if got, want := m.Len(), int(op); got != want {
1253 t.Errorf("operation %v, Map.Len = %d, want %d", p, got, want)
1254 }
1255 case hasMap:
1256 got := map[interface{}]bool{}
1257 want := map[interface{}]bool(op)
1258 for k := range want {
1259 got[k] = m.Has(V(k).MapKey())
1260 }
1261 if diff := cmp.Diff(want, got, cmpOpts); diff != "" {
1262 t.Errorf("operation %v, Map.Has mismatch (-want, +got):\n%s", p, diff)
1263 }
1264 case getMap:
1265 got := map[interface{}]pref.Value{}
1266 want := map[interface{}]pref.Value(op)
1267 for k := range want {
1268 got[k] = m.Get(V(k).MapKey())
1269 }
1270 if diff := cmp.Diff(want, got, cmpOpts); diff != "" {
1271 t.Errorf("operation %v, Map.Get mismatch (-want, +got):\n%s", p, diff)
1272 }
1273 case setMap:
1274 for k, v := range op {
1275 m.Set(V(k).MapKey(), v)
1276 }
1277 case clearMap:
Joe Tsai87b955b2018-11-14 21:59:49 -08001278 for _, k := range op {
1279 m.Clear(V(k).MapKey())
1280 }
1281 case messageMap:
1282 for k, tt := range op {
1283 testMessage(t, p, m.Mutable(V(k).MapKey()).(pref.Message), tt)
Joe Tsaibbfaeb72018-10-17 00:27:21 +00001284 }
1285 case rangeMap:
1286 got := map[interface{}]pref.Value{}
1287 want := map[interface{}]pref.Value(op)
1288 m.Range(func(k pref.MapKey, v pref.Value) bool {
1289 got[k.Interface()] = v
1290 return true
1291 })
1292 if diff := cmp.Diff(want, got, cmpOpts); diff != "" {
1293 t.Errorf("operation %v, Map.Range mismatch (-want, +got):\n%s", p, diff)
1294 }
1295 default:
1296 t.Fatalf("operation %v, invalid operation: %T", p, op)
1297 }
1298 p.Pop()
1299 }
1300}
1301
Joe Tsai91e14662018-09-13 13:24:35 -07001302type path []int
1303
1304func (p *path) Push(i int) { *p = append(*p, i) }
1305func (p *path) Pop() { *p = (*p)[:len(*p)-1] }
1306func (p path) String() string {
1307 var ss []string
1308 for _, i := range p {
1309 ss = append(ss, fmt.Sprint(i))
1310 }
1311 return strings.Join(ss, ".")
1312}