blob: 935b9f88fbaf44ea503f6b06061fa822641e9cbe [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"
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"
Joe Tsai08e00302018-11-26 22:32:06 -080014 pimpl "github.com/golang/protobuf/v2/internal/impl"
Joe Tsai009e0672018-11-27 18:45:07 -080015 scalar "github.com/golang/protobuf/v2/internal/scalar"
Joe Tsai08e00302018-11-26 22:32:06 -080016 pvalue "github.com/golang/protobuf/v2/internal/value"
Joe Tsai01ab2962018-09-21 17:44:00 -070017 pref "github.com/golang/protobuf/v2/reflect/protoreflect"
18 ptype "github.com/golang/protobuf/v2/reflect/prototype"
Joe Tsai87b955b2018-11-14 21:59:49 -080019 cmp "github.com/google/go-cmp/cmp"
20 cmpopts "github.com/google/go-cmp/cmp/cmpopts"
Joe Tsaifa02f4e2018-09-12 16:20:37 -070021
Joe Tsai08e00302018-11-26 22:32:06 -080022 // The legacy package must be imported prior to use of any legacy messages.
23 // TODO: Remove this when protoV1 registers these hooks for you.
24 _ "github.com/golang/protobuf/v2/internal/legacy"
25
Joe Tsai87b955b2018-11-14 21:59:49 -080026 proto2_20180125 "github.com/golang/protobuf/v2/internal/testprotos/legacy/proto2.v1.0.0-20180125-92554152"
Joe Tsaie1f8d502018-11-26 18:55:29 -080027 descriptorpb "github.com/golang/protobuf/v2/types/descriptor"
Joe Tsaifa02f4e2018-09-12 16:20:37 -070028)
29
Joe Tsai4b7aff62018-11-14 14:05:19 -080030// List of test operations to perform on messages, lists, or maps.
Joe Tsai91e14662018-09-13 13:24:35 -070031type (
Joe Tsai87b955b2018-11-14 21:59:49 -080032 messageOp interface{ isMessageOp() }
Joe Tsai91e14662018-09-13 13:24:35 -070033 messageOps []messageOp
Joe Tsaifa02f4e2018-09-12 16:20:37 -070034
Joe Tsai87b955b2018-11-14 21:59:49 -080035 listOp interface{ isListOp() }
Joe Tsai4b7aff62018-11-14 14:05:19 -080036 listOps []listOp
Joe Tsai91e14662018-09-13 13:24:35 -070037
Joe Tsai87b955b2018-11-14 21:59:49 -080038 mapOp interface{ isMapOp() }
Joe Tsaibbfaeb72018-10-17 00:27:21 +000039 mapOps []mapOp
Joe Tsai91e14662018-09-13 13:24:35 -070040)
41
42// Test operations performed on a message.
43type (
Joe Tsai87b955b2018-11-14 21:59:49 -080044 // check that the message contents match
45 equalMessage struct{ pref.Message }
46 // check presence for specific fields in the message
47 hasFields map[pref.FieldNumber]bool
48 // check that specific message fields match
49 getFields map[pref.FieldNumber]pref.Value
50 // set specific message fields
51 setFields map[pref.FieldNumber]pref.Value
52 // clear specific fields in the message
53 clearFields []pref.FieldNumber
54 // apply messageOps on each specified message field
Joe Tsai91e14662018-09-13 13:24:35 -070055 messageFields map[pref.FieldNumber]messageOps
Joe Tsai87b955b2018-11-14 21:59:49 -080056 // apply listOps on each specified list field
57 listFields map[pref.FieldNumber]listOps
58 // apply mapOps on each specified map fields
59 mapFields map[pref.FieldNumber]mapOps
60 // range through all fields and check that they match
61 rangeFields map[pref.FieldNumber]pref.Value
Joe Tsai91e14662018-09-13 13:24:35 -070062)
63
Joe Tsai87b955b2018-11-14 21:59:49 -080064func (equalMessage) isMessageOp() {}
65func (hasFields) isMessageOp() {}
66func (getFields) isMessageOp() {}
67func (setFields) isMessageOp() {}
68func (clearFields) isMessageOp() {}
69func (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
Joe Tsai08e00302018-11-26 22:32:06 -0800192var scalarProto2Type = pimpl.MessageType{Type: 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 }),
222 func(pref.MessageType) pref.ProtoMessage {
223 return new(ScalarProto2)
224 },
225)}
Joe Tsai91e14662018-09-13 13:24:35 -0700226
Joe Tsaif0c01e42018-11-06 13:05:20 -0800227func (m *ScalarProto2) Type() pref.MessageType { return scalarProto2Type.Type }
228func (m *ScalarProto2) KnownFields() pref.KnownFields { return scalarProto2Type.KnownFieldsOf(m) }
229func (m *ScalarProto2) UnknownFields() pref.UnknownFields { return scalarProto2Type.UnknownFieldsOf(m) }
230func (m *ScalarProto2) Interface() pref.ProtoMessage { return m }
231func (m *ScalarProto2) ProtoReflect() pref.Message { return m }
232func (m *ScalarProto2) ProtoMutable() {}
233
234func TestScalarProto2(t *testing.T) {
235 testMessage(t, nil, &ScalarProto2{}, messageOps{
Joe Tsai91e14662018-09-13 13:24:35 -0700236 hasFields{
237 1: false, 2: false, 3: false, 4: false, 5: false, 6: false, 7: false, 8: false, 9: false, 10: false, 11: false,
238 12: false, 13: false, 14: false, 15: false, 16: false, 17: false, 18: false, 19: false, 20: false, 21: false, 22: false,
239 },
240 getFields{
241 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")),
242 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")),
243 },
244 setFields{
245 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)),
246 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)),
247 },
248 hasFields{
249 1: true, 2: true, 3: true, 4: true, 5: true, 6: true, 7: true, 8: true, 9: true, 10: true, 11: true,
250 12: true, 13: true, 14: true, 15: true, 16: true, 17: true, 18: true, 19: true, 20: true, 21: true, 22: true,
251 },
Joe Tsai87b955b2018-11-14 21:59:49 -0800252 equalMessage{&ScalarProto2{
Joe Tsai91e14662018-09-13 13:24:35 -0700253 new(bool), new(int32), new(int64), new(uint32), new(uint64), new(float32), new(float64), new(string), []byte{}, []byte{}, new(string),
254 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 -0800255 }},
256 clearFields{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22},
257 equalMessage{&ScalarProto2{}},
Joe Tsai91e14662018-09-13 13:24:35 -0700258 })
Joe Tsai6cf80c42018-12-01 04:57:09 -0800259
260 // Test read-only operations on nil message.
261 testMessage(t, nil, (*ScalarProto2)(nil), messageOps{
262 hasFields{
263 1: false, 2: false, 3: false, 4: false, 5: false, 6: false, 7: false, 8: false, 9: false, 10: false, 11: false,
264 12: false, 13: false, 14: false, 15: false, 16: false, 17: false, 18: false, 19: false, 20: false, 21: false, 22: false,
265 },
266 getFields{
267 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")),
268 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")),
269 },
270 })
Joe Tsaifa02f4e2018-09-12 16:20:37 -0700271}
272
Joe Tsaice6edd32018-10-19 16:27:46 -0700273type ScalarProto3 struct {
274 Bool bool `protobuf:"1"`
275 Int32 int32 `protobuf:"2"`
276 Int64 int64 `protobuf:"3"`
277 Uint32 uint32 `protobuf:"4"`
278 Uint64 uint64 `protobuf:"5"`
279 Float32 float32 `protobuf:"6"`
280 Float64 float64 `protobuf:"7"`
281 String string `protobuf:"8"`
282 StringA []byte `protobuf:"9"`
283 Bytes []byte `protobuf:"10"`
284 BytesA string `protobuf:"11"`
285
286 MyBool MyBool `protobuf:"12"`
287 MyInt32 MyInt32 `protobuf:"13"`
288 MyInt64 MyInt64 `protobuf:"14"`
289 MyUint32 MyUint32 `protobuf:"15"`
290 MyUint64 MyUint64 `protobuf:"16"`
291 MyFloat32 MyFloat32 `protobuf:"17"`
292 MyFloat64 MyFloat64 `protobuf:"18"`
293 MyString MyString `protobuf:"19"`
294 MyStringA MyBytes `protobuf:"20"`
295 MyBytes MyBytes `protobuf:"21"`
296 MyBytesA MyString `protobuf:"22"`
297}
298
Joe Tsai08e00302018-11-26 22:32:06 -0800299var scalarProto3Type = pimpl.MessageType{Type: ptype.GoMessage(
Joe Tsaif0c01e42018-11-06 13:05:20 -0800300 mustMakeMessageDesc(ptype.StandaloneMessage{
Joe Tsai91e14662018-09-13 13:24:35 -0700301 Syntax: pref.Proto3,
302 FullName: "ScalarProto3",
303 Fields: []ptype.Field{
304 {Name: "f1", Number: 1, Cardinality: pref.Optional, Kind: pref.BoolKind},
305 {Name: "f2", Number: 2, Cardinality: pref.Optional, Kind: pref.Int32Kind},
306 {Name: "f3", Number: 3, Cardinality: pref.Optional, Kind: pref.Int64Kind},
307 {Name: "f4", Number: 4, Cardinality: pref.Optional, Kind: pref.Uint32Kind},
308 {Name: "f5", Number: 5, Cardinality: pref.Optional, Kind: pref.Uint64Kind},
309 {Name: "f6", Number: 6, Cardinality: pref.Optional, Kind: pref.FloatKind},
310 {Name: "f7", Number: 7, Cardinality: pref.Optional, Kind: pref.DoubleKind},
311 {Name: "f8", Number: 8, Cardinality: pref.Optional, Kind: pref.StringKind},
312 {Name: "f9", Number: 9, Cardinality: pref.Optional, Kind: pref.StringKind},
313 {Name: "f10", Number: 10, Cardinality: pref.Optional, Kind: pref.BytesKind},
314 {Name: "f11", Number: 11, Cardinality: pref.Optional, Kind: pref.BytesKind},
Joe Tsaifa02f4e2018-09-12 16:20:37 -0700315
Joe Tsai91e14662018-09-13 13:24:35 -0700316 {Name: "f12", Number: 12, Cardinality: pref.Optional, Kind: pref.BoolKind},
317 {Name: "f13", Number: 13, Cardinality: pref.Optional, Kind: pref.Int32Kind},
318 {Name: "f14", Number: 14, Cardinality: pref.Optional, Kind: pref.Int64Kind},
319 {Name: "f15", Number: 15, Cardinality: pref.Optional, Kind: pref.Uint32Kind},
320 {Name: "f16", Number: 16, Cardinality: pref.Optional, Kind: pref.Uint64Kind},
321 {Name: "f17", Number: 17, Cardinality: pref.Optional, Kind: pref.FloatKind},
322 {Name: "f18", Number: 18, Cardinality: pref.Optional, Kind: pref.DoubleKind},
323 {Name: "f19", Number: 19, Cardinality: pref.Optional, Kind: pref.StringKind},
324 {Name: "f20", Number: 20, Cardinality: pref.Optional, Kind: pref.StringKind},
325 {Name: "f21", Number: 21, Cardinality: pref.Optional, Kind: pref.BytesKind},
326 {Name: "f22", Number: 22, Cardinality: pref.Optional, Kind: pref.BytesKind},
327 },
Joe Tsaif0c01e42018-11-06 13:05:20 -0800328 }),
329 func(pref.MessageType) pref.ProtoMessage {
330 return new(ScalarProto3)
331 },
332)}
Joe Tsai91e14662018-09-13 13:24:35 -0700333
Joe Tsaif0c01e42018-11-06 13:05:20 -0800334func (m *ScalarProto3) Type() pref.MessageType { return scalarProto3Type.Type }
335func (m *ScalarProto3) KnownFields() pref.KnownFields { return scalarProto3Type.KnownFieldsOf(m) }
336func (m *ScalarProto3) UnknownFields() pref.UnknownFields { return scalarProto3Type.UnknownFieldsOf(m) }
337func (m *ScalarProto3) Interface() pref.ProtoMessage { return m }
338func (m *ScalarProto3) ProtoReflect() pref.Message { return m }
339func (m *ScalarProto3) ProtoMutable() {}
340
341func TestScalarProto3(t *testing.T) {
342 testMessage(t, nil, &ScalarProto3{}, messageOps{
Joe Tsai91e14662018-09-13 13:24:35 -0700343 hasFields{
344 1: false, 2: false, 3: false, 4: false, 5: false, 6: false, 7: false, 8: false, 9: false, 10: false, 11: false,
345 12: false, 13: false, 14: false, 15: false, 16: false, 17: false, 18: false, 19: false, 20: false, 21: false, 22: false,
346 },
347 getFields{
348 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)),
349 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)),
350 },
351 setFields{
352 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)),
353 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)),
354 },
355 hasFields{
356 1: false, 2: false, 3: false, 4: false, 5: false, 6: false, 7: false, 8: false, 9: false, 10: false, 11: false,
357 12: false, 13: false, 14: false, 15: false, 16: false, 17: false, 18: false, 19: false, 20: false, 21: false, 22: false,
358 },
Joe Tsai87b955b2018-11-14 21:59:49 -0800359 equalMessage{&ScalarProto3{}},
Joe Tsai91e14662018-09-13 13:24:35 -0700360 setFields{
361 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")),
362 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")),
363 },
364 hasFields{
365 1: true, 2: true, 3: true, 4: true, 5: true, 6: true, 7: true, 8: true, 9: true, 10: true, 11: true,
366 12: true, 13: true, 14: true, 15: true, 16: true, 17: true, 18: true, 19: true, 20: true, 21: true, 22: true,
367 },
Joe Tsai87b955b2018-11-14 21:59:49 -0800368 equalMessage{&ScalarProto3{
Joe Tsai91e14662018-09-13 13:24:35 -0700369 true, 2, 3, 4, 5, 6, 7, "8", []byte("9"), []byte("10"), "11",
370 true, 13, 14, 15, 16, 17, 18, "19", []byte("20"), []byte("21"), "22",
Joe Tsai87b955b2018-11-14 21:59:49 -0800371 }},
Joe Tsai44e389c2018-11-19 15:27:09 -0800372 setFields{
373 2: V(int32(-2)), 3: V(int64(-3)), 6: V(float32(math.Inf(-1))), 7: V(float64(math.NaN())),
374 },
375 hasFields{
376 2: true, 3: true, 6: true, 7: true,
377 },
Joe Tsai87b955b2018-11-14 21:59:49 -0800378 clearFields{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22},
379 equalMessage{&ScalarProto3{}},
Joe Tsai91e14662018-09-13 13:24:35 -0700380 })
Joe Tsai6cf80c42018-12-01 04:57:09 -0800381
382 // Test read-only operations on nil message.
383 testMessage(t, nil, (*ScalarProto3)(nil), messageOps{
384 hasFields{
385 1: false, 2: false, 3: false, 4: false, 5: false, 6: false, 7: false, 8: false, 9: false, 10: false, 11: false,
386 12: false, 13: false, 14: false, 15: false, 16: false, 17: false, 18: false, 19: false, 20: false, 21: false, 22: false,
387 },
388 getFields{
389 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)),
390 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)),
391 },
392 })
Joe Tsaifa02f4e2018-09-12 16:20:37 -0700393}
394
Joe Tsaif0c01e42018-11-06 13:05:20 -0800395type ListScalars struct {
Joe Tsaice6edd32018-10-19 16:27:46 -0700396 Bools []bool `protobuf:"1"`
397 Int32s []int32 `protobuf:"2"`
398 Int64s []int64 `protobuf:"3"`
399 Uint32s []uint32 `protobuf:"4"`
400 Uint64s []uint64 `protobuf:"5"`
401 Float32s []float32 `protobuf:"6"`
402 Float64s []float64 `protobuf:"7"`
403 Strings []string `protobuf:"8"`
404 StringsA [][]byte `protobuf:"9"`
405 Bytes [][]byte `protobuf:"10"`
406 BytesA []string `protobuf:"11"`
407
408 MyStrings1 []MyString `protobuf:"12"`
409 MyStrings2 []MyBytes `protobuf:"13"`
410 MyBytes1 []MyBytes `protobuf:"14"`
411 MyBytes2 []MyString `protobuf:"15"`
412
Joe Tsai4b7aff62018-11-14 14:05:19 -0800413 MyStrings3 ListStrings `protobuf:"16"`
414 MyStrings4 ListBytes `protobuf:"17"`
415 MyBytes3 ListBytes `protobuf:"18"`
416 MyBytes4 ListStrings `protobuf:"19"`
Joe Tsaice6edd32018-10-19 16:27:46 -0700417}
418
Joe Tsai08e00302018-11-26 22:32:06 -0800419var listScalarsType = pimpl.MessageType{Type: ptype.GoMessage(
Joe Tsaif0c01e42018-11-06 13:05:20 -0800420 mustMakeMessageDesc(ptype.StandaloneMessage{
Joe Tsai91e14662018-09-13 13:24:35 -0700421 Syntax: pref.Proto2,
Joe Tsaif0c01e42018-11-06 13:05:20 -0800422 FullName: "ListScalars",
Joe Tsai91e14662018-09-13 13:24:35 -0700423 Fields: []ptype.Field{
424 {Name: "f1", Number: 1, Cardinality: pref.Repeated, Kind: pref.BoolKind},
425 {Name: "f2", Number: 2, Cardinality: pref.Repeated, Kind: pref.Int32Kind},
426 {Name: "f3", Number: 3, Cardinality: pref.Repeated, Kind: pref.Int64Kind},
427 {Name: "f4", Number: 4, Cardinality: pref.Repeated, Kind: pref.Uint32Kind},
428 {Name: "f5", Number: 5, Cardinality: pref.Repeated, Kind: pref.Uint64Kind},
429 {Name: "f6", Number: 6, Cardinality: pref.Repeated, Kind: pref.FloatKind},
430 {Name: "f7", Number: 7, Cardinality: pref.Repeated, Kind: pref.DoubleKind},
431 {Name: "f8", Number: 8, Cardinality: pref.Repeated, Kind: pref.StringKind},
432 {Name: "f9", Number: 9, Cardinality: pref.Repeated, Kind: pref.StringKind},
433 {Name: "f10", Number: 10, Cardinality: pref.Repeated, Kind: pref.BytesKind},
434 {Name: "f11", Number: 11, Cardinality: pref.Repeated, Kind: pref.BytesKind},
Joe Tsaifa02f4e2018-09-12 16:20:37 -0700435
Joe Tsai91e14662018-09-13 13:24:35 -0700436 {Name: "f12", Number: 12, Cardinality: pref.Repeated, Kind: pref.StringKind},
437 {Name: "f13", Number: 13, Cardinality: pref.Repeated, Kind: pref.StringKind},
438 {Name: "f14", Number: 14, Cardinality: pref.Repeated, Kind: pref.BytesKind},
439 {Name: "f15", Number: 15, Cardinality: pref.Repeated, Kind: pref.BytesKind},
440
441 {Name: "f16", Number: 16, Cardinality: pref.Repeated, Kind: pref.StringKind},
442 {Name: "f17", Number: 17, Cardinality: pref.Repeated, Kind: pref.StringKind},
443 {Name: "f18", Number: 18, Cardinality: pref.Repeated, Kind: pref.BytesKind},
444 {Name: "f19", Number: 19, Cardinality: pref.Repeated, Kind: pref.BytesKind},
Joe Tsaifa02f4e2018-09-12 16:20:37 -0700445 },
Joe Tsaif0c01e42018-11-06 13:05:20 -0800446 }),
447 func(pref.MessageType) pref.ProtoMessage {
448 return new(ListScalars)
449 },
450)}
Joe Tsai91e14662018-09-13 13:24:35 -0700451
Joe Tsaif0c01e42018-11-06 13:05:20 -0800452func (m *ListScalars) Type() pref.MessageType { return listScalarsType.Type }
453func (m *ListScalars) KnownFields() pref.KnownFields { return listScalarsType.KnownFieldsOf(m) }
454func (m *ListScalars) UnknownFields() pref.UnknownFields { return listScalarsType.UnknownFieldsOf(m) }
455func (m *ListScalars) Interface() pref.ProtoMessage { return m }
456func (m *ListScalars) ProtoReflect() pref.Message { return m }
457func (m *ListScalars) ProtoMutable() {}
458
459func TestListScalars(t *testing.T) {
460 empty := &ListScalars{}
Joe Tsai91e14662018-09-13 13:24:35 -0700461 emptyFS := empty.KnownFields()
462
Joe Tsaif0c01e42018-11-06 13:05:20 -0800463 want := &ListScalars{
Joe Tsai91e14662018-09-13 13:24:35 -0700464 Bools: []bool{true, false, true},
465 Int32s: []int32{2, math.MinInt32, math.MaxInt32},
466 Int64s: []int64{3, math.MinInt64, math.MaxInt64},
467 Uint32s: []uint32{4, math.MaxUint32 / 2, math.MaxUint32},
468 Uint64s: []uint64{5, math.MaxUint64 / 2, math.MaxUint64},
469 Float32s: []float32{6, math.SmallestNonzeroFloat32, float32(math.NaN()), math.MaxFloat32},
470 Float64s: []float64{7, math.SmallestNonzeroFloat64, float64(math.NaN()), math.MaxFloat64},
471 Strings: []string{"8", "", "eight"},
472 StringsA: [][]byte{[]byte("9"), nil, []byte("nine")},
473 Bytes: [][]byte{[]byte("10"), nil, []byte("ten")},
474 BytesA: []string{"11", "", "eleven"},
475
476 MyStrings1: []MyString{"12", "", "twelve"},
477 MyStrings2: []MyBytes{[]byte("13"), nil, []byte("thirteen")},
478 MyBytes1: []MyBytes{[]byte("14"), nil, []byte("fourteen")},
479 MyBytes2: []MyString{"15", "", "fifteen"},
480
Joe Tsai4b7aff62018-11-14 14:05:19 -0800481 MyStrings3: ListStrings{"16", "", "sixteen"},
482 MyStrings4: ListBytes{[]byte("17"), nil, []byte("seventeen")},
483 MyBytes3: ListBytes{[]byte("18"), nil, []byte("eighteen")},
484 MyBytes4: ListStrings{"19", "", "nineteen"},
Joe Tsaif0c01e42018-11-06 13:05:20 -0800485 }
Joe Tsai91e14662018-09-13 13:24:35 -0700486 wantFS := want.KnownFields()
487
Joe Tsaif0c01e42018-11-06 13:05:20 -0800488 testMessage(t, nil, &ListScalars{}, messageOps{
Joe Tsai91e14662018-09-13 13:24:35 -0700489 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},
490 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)},
491 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 -0800492 listFields{
Joe Tsai91e14662018-09-13 13:24:35 -0700493 2: {
Joe Tsai4b7aff62018-11-14 14:05:19 -0800494 lenList(0),
495 appendList{V(int32(2)), V(int32(math.MinInt32)), V(int32(math.MaxInt32))},
496 getList{0: V(int32(2)), 1: V(int32(math.MinInt32)), 2: V(int32(math.MaxInt32))},
Joe Tsai87b955b2018-11-14 21:59:49 -0800497 equalList{wantFS.Get(2).List()},
Joe Tsai91e14662018-09-13 13:24:35 -0700498 },
499 4: {
Joe Tsai4b7aff62018-11-14 14:05:19 -0800500 appendList{V(uint32(0)), V(uint32(0)), V(uint32(0))},
501 setList{0: V(uint32(4)), 1: V(uint32(math.MaxUint32 / 2)), 2: V(uint32(math.MaxUint32))},
502 lenList(3),
Joe Tsai91e14662018-09-13 13:24:35 -0700503 },
504 6: {
Joe Tsai4b7aff62018-11-14 14:05:19 -0800505 appendList{V(float32(6)), V(float32(math.SmallestNonzeroFloat32)), V(float32(math.NaN())), V(float32(math.MaxFloat32))},
Joe Tsai87b955b2018-11-14 21:59:49 -0800506 equalList{wantFS.Get(6).List()},
Joe Tsai91e14662018-09-13 13:24:35 -0700507 },
508 8: {
Joe Tsai4b7aff62018-11-14 14:05:19 -0800509 appendList{V(""), V(""), V(""), V(""), V(""), V("")},
510 lenList(6),
511 setList{0: V("8"), 2: V("eight")},
512 truncList(3),
Joe Tsai87b955b2018-11-14 21:59:49 -0800513 equalList{wantFS.Get(8).List()},
Joe Tsai91e14662018-09-13 13:24:35 -0700514 },
515 10: {
Joe Tsai4b7aff62018-11-14 14:05:19 -0800516 appendList{V([]byte(nil)), V([]byte(nil))},
517 setList{0: V([]byte("10"))},
518 appendList{V([]byte("wrong"))},
519 setList{2: V([]byte("ten"))},
Joe Tsai87b955b2018-11-14 21:59:49 -0800520 equalList{wantFS.Get(10).List()},
Joe Tsai91e14662018-09-13 13:24:35 -0700521 },
522 12: {
Joe Tsai4b7aff62018-11-14 14:05:19 -0800523 appendList{V("12"), V("wrong"), V("twelve")},
524 setList{1: V("")},
Joe Tsai87b955b2018-11-14 21:59:49 -0800525 equalList{wantFS.Get(12).List()},
Joe Tsai91e14662018-09-13 13:24:35 -0700526 },
527 14: {
Joe Tsai4b7aff62018-11-14 14:05:19 -0800528 appendList{V([]byte("14")), V([]byte(nil)), V([]byte("fourteen"))},
Joe Tsai87b955b2018-11-14 21:59:49 -0800529 equalList{wantFS.Get(14).List()},
Joe Tsai91e14662018-09-13 13:24:35 -0700530 },
531 16: {
Joe Tsai4b7aff62018-11-14 14:05:19 -0800532 appendList{V("16"), V(""), V("sixteen"), V("extra")},
533 truncList(3),
Joe Tsai87b955b2018-11-14 21:59:49 -0800534 equalList{wantFS.Get(16).List()},
Joe Tsai91e14662018-09-13 13:24:35 -0700535 },
536 18: {
Joe Tsai4b7aff62018-11-14 14:05:19 -0800537 appendList{V([]byte("18")), V([]byte(nil)), V([]byte("eighteen"))},
Joe Tsai87b955b2018-11-14 21:59:49 -0800538 equalList{wantFS.Get(18).List()},
Joe Tsai91e14662018-09-13 13:24:35 -0700539 },
Joe Tsaifa02f4e2018-09-12 16:20:37 -0700540 },
Joe Tsai91e14662018-09-13 13:24:35 -0700541 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 -0800542 equalMessage{want},
543 clearFields{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19},
544 equalMessage{empty},
Joe Tsaibbfaeb72018-10-17 00:27:21 +0000545 })
Joe Tsai6cf80c42018-12-01 04:57:09 -0800546
547 // Test read-only operations on nil message.
548 testMessage(t, nil, (*ListScalars)(nil), messageOps{
549 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},
550 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)}},
551 })
Joe Tsaibbfaeb72018-10-17 00:27:21 +0000552}
553
Joe Tsaice6edd32018-10-19 16:27:46 -0700554type MapScalars struct {
555 KeyBools map[bool]string `protobuf:"1"`
556 KeyInt32s map[int32]string `protobuf:"2"`
557 KeyInt64s map[int64]string `protobuf:"3"`
558 KeyUint32s map[uint32]string `protobuf:"4"`
559 KeyUint64s map[uint64]string `protobuf:"5"`
560 KeyStrings map[string]string `protobuf:"6"`
561
562 ValBools map[string]bool `protobuf:"7"`
563 ValInt32s map[string]int32 `protobuf:"8"`
564 ValInt64s map[string]int64 `protobuf:"9"`
565 ValUint32s map[string]uint32 `protobuf:"10"`
566 ValUint64s map[string]uint64 `protobuf:"11"`
567 ValFloat32s map[string]float32 `protobuf:"12"`
568 ValFloat64s map[string]float64 `protobuf:"13"`
569 ValStrings map[string]string `protobuf:"14"`
570 ValStringsA map[string][]byte `protobuf:"15"`
571 ValBytes map[string][]byte `protobuf:"16"`
572 ValBytesA map[string]string `protobuf:"17"`
573
574 MyStrings1 map[MyString]MyString `protobuf:"18"`
575 MyStrings2 map[MyString]MyBytes `protobuf:"19"`
576 MyBytes1 map[MyString]MyBytes `protobuf:"20"`
577 MyBytes2 map[MyString]MyString `protobuf:"21"`
578
579 MyStrings3 MapStrings `protobuf:"22"`
580 MyStrings4 MapBytes `protobuf:"23"`
581 MyBytes3 MapBytes `protobuf:"24"`
582 MyBytes4 MapStrings `protobuf:"25"`
583}
584
Joe Tsaif0c01e42018-11-06 13:05:20 -0800585func mustMakeMapEntry(n pref.FieldNumber, keyKind, valKind pref.Kind) ptype.Field {
586 return ptype.Field{
587 Name: pref.Name(fmt.Sprintf("f%d", n)),
588 Number: n,
589 Cardinality: pref.Repeated,
590 Kind: pref.MessageKind,
591 MessageType: mustMakeMessageDesc(ptype.StandaloneMessage{
592 Syntax: pref.Proto2,
593 FullName: pref.FullName(fmt.Sprintf("MapScalars.F%dEntry", n)),
594 Fields: []ptype.Field{
595 {Name: "key", Number: 1, Cardinality: pref.Optional, Kind: keyKind},
596 {Name: "value", Number: 2, Cardinality: pref.Optional, Kind: valKind},
597 },
Joe Tsai6cf80c42018-12-01 04:57:09 -0800598 Options: &descriptorpb.MessageOptions{MapEntry: scalar.Bool(true)},
Joe Tsaif0c01e42018-11-06 13:05:20 -0800599 }),
Joe Tsaibbfaeb72018-10-17 00:27:21 +0000600 }
Joe Tsaif0c01e42018-11-06 13:05:20 -0800601}
602
Joe Tsai08e00302018-11-26 22:32:06 -0800603var mapScalarsType = pimpl.MessageType{Type: ptype.GoMessage(
Joe Tsaif0c01e42018-11-06 13:05:20 -0800604 mustMakeMessageDesc(ptype.StandaloneMessage{
Joe Tsaibbfaeb72018-10-17 00:27:21 +0000605 Syntax: pref.Proto2,
606 FullName: "MapScalars",
607 Fields: []ptype.Field{
608 mustMakeMapEntry(1, pref.BoolKind, pref.StringKind),
609 mustMakeMapEntry(2, pref.Int32Kind, pref.StringKind),
610 mustMakeMapEntry(3, pref.Int64Kind, pref.StringKind),
611 mustMakeMapEntry(4, pref.Uint32Kind, pref.StringKind),
612 mustMakeMapEntry(5, pref.Uint64Kind, pref.StringKind),
613 mustMakeMapEntry(6, pref.StringKind, pref.StringKind),
614
615 mustMakeMapEntry(7, pref.StringKind, pref.BoolKind),
616 mustMakeMapEntry(8, pref.StringKind, pref.Int32Kind),
617 mustMakeMapEntry(9, pref.StringKind, pref.Int64Kind),
618 mustMakeMapEntry(10, pref.StringKind, pref.Uint32Kind),
619 mustMakeMapEntry(11, pref.StringKind, pref.Uint64Kind),
620 mustMakeMapEntry(12, pref.StringKind, pref.FloatKind),
621 mustMakeMapEntry(13, pref.StringKind, pref.DoubleKind),
622 mustMakeMapEntry(14, pref.StringKind, pref.StringKind),
623 mustMakeMapEntry(15, pref.StringKind, pref.StringKind),
624 mustMakeMapEntry(16, pref.StringKind, pref.BytesKind),
625 mustMakeMapEntry(17, pref.StringKind, pref.BytesKind),
626
627 mustMakeMapEntry(18, pref.StringKind, pref.StringKind),
628 mustMakeMapEntry(19, pref.StringKind, pref.StringKind),
629 mustMakeMapEntry(20, pref.StringKind, pref.BytesKind),
630 mustMakeMapEntry(21, pref.StringKind, pref.BytesKind),
631
632 mustMakeMapEntry(22, pref.StringKind, pref.StringKind),
633 mustMakeMapEntry(23, pref.StringKind, pref.StringKind),
634 mustMakeMapEntry(24, pref.StringKind, pref.BytesKind),
635 mustMakeMapEntry(25, pref.StringKind, pref.BytesKind),
636 },
Joe Tsaif0c01e42018-11-06 13:05:20 -0800637 }),
638 func(pref.MessageType) pref.ProtoMessage {
639 return new(MapScalars)
640 },
641)}
Joe Tsaibbfaeb72018-10-17 00:27:21 +0000642
Joe Tsaif0c01e42018-11-06 13:05:20 -0800643func (m *MapScalars) Type() pref.MessageType { return mapScalarsType.Type }
644func (m *MapScalars) KnownFields() pref.KnownFields { return mapScalarsType.KnownFieldsOf(m) }
645func (m *MapScalars) UnknownFields() pref.UnknownFields { return mapScalarsType.UnknownFieldsOf(m) }
646func (m *MapScalars) Interface() pref.ProtoMessage { return m }
647func (m *MapScalars) ProtoReflect() pref.Message { return m }
648func (m *MapScalars) ProtoMutable() {}
649
650func TestMapScalars(t *testing.T) {
651 empty := &MapScalars{}
Joe Tsaibbfaeb72018-10-17 00:27:21 +0000652 emptyFS := empty.KnownFields()
653
Joe Tsaif0c01e42018-11-06 13:05:20 -0800654 want := &MapScalars{
Joe Tsaibbfaeb72018-10-17 00:27:21 +0000655 KeyBools: map[bool]string{true: "true", false: "false"},
656 KeyInt32s: map[int32]string{0: "zero", -1: "one", 2: "two"},
657 KeyInt64s: map[int64]string{0: "zero", -10: "ten", 20: "twenty"},
658 KeyUint32s: map[uint32]string{0: "zero", 1: "one", 2: "two"},
659 KeyUint64s: map[uint64]string{0: "zero", 10: "ten", 20: "twenty"},
660 KeyStrings: map[string]string{"": "", "foo": "bar"},
661
662 ValBools: map[string]bool{"true": true, "false": false},
663 ValInt32s: map[string]int32{"one": 1, "two": 2, "three": 3},
664 ValInt64s: map[string]int64{"ten": 10, "twenty": -20, "thirty": 30},
665 ValUint32s: map[string]uint32{"0x00": 0x00, "0xff": 0xff, "0xdead": 0xdead},
666 ValUint64s: map[string]uint64{"0x00": 0x00, "0xff": 0xff, "0xdead": 0xdead},
667 ValFloat32s: map[string]float32{"nan": float32(math.NaN()), "pi": float32(math.Pi)},
668 ValFloat64s: map[string]float64{"nan": float64(math.NaN()), "pi": float64(math.Pi)},
669 ValStrings: map[string]string{"s1": "s1", "s2": "s2"},
670 ValStringsA: map[string][]byte{"s1": []byte("s1"), "s2": []byte("s2")},
671 ValBytes: map[string][]byte{"s1": []byte("s1"), "s2": []byte("s2")},
672 ValBytesA: map[string]string{"s1": "s1", "s2": "s2"},
673
674 MyStrings1: map[MyString]MyString{"s1": "s1", "s2": "s2"},
675 MyStrings2: map[MyString]MyBytes{"s1": []byte("s1"), "s2": []byte("s2")},
676 MyBytes1: map[MyString]MyBytes{"s1": []byte("s1"), "s2": []byte("s2")},
677 MyBytes2: map[MyString]MyString{"s1": "s1", "s2": "s2"},
678
679 MyStrings3: MapStrings{"s1": "s1", "s2": "s2"},
680 MyStrings4: MapBytes{"s1": []byte("s1"), "s2": []byte("s2")},
681 MyBytes3: MapBytes{"s1": []byte("s1"), "s2": []byte("s2")},
682 MyBytes4: MapStrings{"s1": "s1", "s2": "s2"},
Joe Tsaif0c01e42018-11-06 13:05:20 -0800683 }
Joe Tsaibbfaeb72018-10-17 00:27:21 +0000684 wantFS := want.KnownFields()
685
Joe Tsaif0c01e42018-11-06 13:05:20 -0800686 testMessage(t, nil, &MapScalars{}, messageOps{
Joe Tsaibbfaeb72018-10-17 00:27:21 +0000687 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},
688 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)},
689 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)},
690 mapFields{
691 2: {
692 lenMap(0),
693 hasMap{int32(0): false, int32(-1): false, int32(2): false},
694 setMap{int32(0): V("zero")},
695 lenMap(1),
696 hasMap{int32(0): true, int32(-1): false, int32(2): false},
697 setMap{int32(-1): V("one")},
698 lenMap(2),
699 hasMap{int32(0): true, int32(-1): true, int32(2): false},
700 setMap{int32(2): V("two")},
701 lenMap(3),
702 hasMap{int32(0): true, int32(-1): true, int32(2): true},
703 },
704 4: {
705 setMap{uint32(0): V("zero"), uint32(1): V("one"), uint32(2): V("two")},
Joe Tsai87b955b2018-11-14 21:59:49 -0800706 equalMap{wantFS.Get(4).Map()},
Joe Tsaibbfaeb72018-10-17 00:27:21 +0000707 },
708 6: {
Joe Tsai87b955b2018-11-14 21:59:49 -0800709 clearMap{"noexist"},
Joe Tsaibbfaeb72018-10-17 00:27:21 +0000710 setMap{"foo": V("bar")},
711 setMap{"": V("empty")},
712 getMap{"": V("empty"), "foo": V("bar"), "noexist": V(nil)},
713 setMap{"": V(""), "extra": V("extra")},
Joe Tsai87b955b2018-11-14 21:59:49 -0800714 clearMap{"extra", "noexist"},
Joe Tsaibbfaeb72018-10-17 00:27:21 +0000715 },
716 8: {
Joe Tsai87b955b2018-11-14 21:59:49 -0800717 equalMap{emptyFS.Get(8).Map()},
Joe Tsaibbfaeb72018-10-17 00:27:21 +0000718 setMap{"one": V(int32(1)), "two": V(int32(2)), "three": V(int32(3))},
719 },
720 10: {
721 setMap{"0x00": V(uint32(0x00)), "0xff": V(uint32(0xff)), "0xdead": V(uint32(0xdead))},
722 lenMap(3),
Joe Tsai87b955b2018-11-14 21:59:49 -0800723 equalMap{wantFS.Get(10).Map()},
Joe Tsaibbfaeb72018-10-17 00:27:21 +0000724 getMap{"0x00": V(uint32(0x00)), "0xff": V(uint32(0xff)), "0xdead": V(uint32(0xdead)), "0xdeadbeef": V(nil)},
725 },
726 12: {
727 setMap{"nan": V(float32(math.NaN())), "pi": V(float32(math.Pi)), "e": V(float32(math.E))},
Joe Tsai87b955b2018-11-14 21:59:49 -0800728 clearMap{"e", "phi"},
Joe Tsaibbfaeb72018-10-17 00:27:21 +0000729 rangeMap{"nan": V(float32(math.NaN())), "pi": V(float32(math.Pi))},
730 },
731 14: {
Joe Tsai87b955b2018-11-14 21:59:49 -0800732 equalMap{emptyFS.Get(14).Map()},
Joe Tsaibbfaeb72018-10-17 00:27:21 +0000733 setMap{"s1": V("s1"), "s2": V("s2")},
734 },
735 16: {
736 setMap{"s1": V([]byte("s1")), "s2": V([]byte("s2"))},
Joe Tsai87b955b2018-11-14 21:59:49 -0800737 equalMap{wantFS.Get(16).Map()},
Joe Tsaibbfaeb72018-10-17 00:27:21 +0000738 },
739 18: {
740 hasMap{"s1": false, "s2": false, "s3": false},
741 setMap{"s1": V("s1"), "s2": V("s2")},
742 hasMap{"s1": true, "s2": true, "s3": false},
743 },
744 20: {
Joe Tsai87b955b2018-11-14 21:59:49 -0800745 equalMap{emptyFS.Get(20).Map()},
Joe Tsaibbfaeb72018-10-17 00:27:21 +0000746 setMap{"s1": V([]byte("s1")), "s2": V([]byte("s2"))},
747 },
748 22: {
749 rangeMap{},
750 setMap{"s1": V("s1"), "s2": V("s2")},
751 rangeMap{"s1": V("s1"), "s2": V("s2")},
752 lenMap(2),
753 },
754 24: {
755 setMap{"s1": V([]byte("s1")), "s2": V([]byte("s2"))},
Joe Tsai87b955b2018-11-14 21:59:49 -0800756 equalMap{wantFS.Get(24).Map()},
Joe Tsaibbfaeb72018-10-17 00:27:21 +0000757 },
758 },
759 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 -0800760 equalMessage{want},
761 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},
762 equalMessage{empty},
Joe Tsai91e14662018-09-13 13:24:35 -0700763 })
Joe Tsai6cf80c42018-12-01 04:57:09 -0800764
765 // Test read-only operations on nil message.
766 testMessage(t, nil, (*MapScalars)(nil), messageOps{
767 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},
768 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)}},
769 })
Joe Tsai91e14662018-09-13 13:24:35 -0700770}
Joe Tsaifa02f4e2018-09-12 16:20:37 -0700771
Joe Tsai87b955b2018-11-14 21:59:49 -0800772type OneofScalars struct {
773 Union isOneofScalars_Union `protobuf_oneof:"union"`
774}
Joe Tsai2c870bb2018-10-17 11:46:52 -0700775
Joe Tsai08e00302018-11-26 22:32:06 -0800776var oneofScalarsType = pimpl.MessageType{Type: ptype.GoMessage(
Joe Tsaif0c01e42018-11-06 13:05:20 -0800777 mustMakeMessageDesc(ptype.StandaloneMessage{
778 Syntax: pref.Proto2,
Joe Tsai87b955b2018-11-14 21:59:49 -0800779 FullName: "OneofScalars",
Joe Tsaif0c01e42018-11-06 13:05:20 -0800780 Fields: []ptype.Field{
781 {Name: "f1", Number: 1, Cardinality: pref.Optional, Kind: pref.BoolKind, Default: V(bool(true)), OneofName: "union"},
782 {Name: "f2", Number: 2, Cardinality: pref.Optional, Kind: pref.Int32Kind, Default: V(int32(2)), OneofName: "union"},
783 {Name: "f3", Number: 3, Cardinality: pref.Optional, Kind: pref.Int64Kind, Default: V(int64(3)), OneofName: "union"},
784 {Name: "f4", Number: 4, Cardinality: pref.Optional, Kind: pref.Uint32Kind, Default: V(uint32(4)), OneofName: "union"},
785 {Name: "f5", Number: 5, Cardinality: pref.Optional, Kind: pref.Uint64Kind, Default: V(uint64(5)), OneofName: "union"},
786 {Name: "f6", Number: 6, Cardinality: pref.Optional, Kind: pref.FloatKind, Default: V(float32(6)), OneofName: "union"},
787 {Name: "f7", Number: 7, Cardinality: pref.Optional, Kind: pref.DoubleKind, Default: V(float64(7)), OneofName: "union"},
788 {Name: "f8", Number: 8, Cardinality: pref.Optional, Kind: pref.StringKind, Default: V(string("8")), OneofName: "union"},
789 {Name: "f9", Number: 9, Cardinality: pref.Optional, Kind: pref.StringKind, Default: V(string("9")), OneofName: "union"},
790 {Name: "f10", Number: 10, Cardinality: pref.Optional, Kind: pref.StringKind, Default: V(string("10")), OneofName: "union"},
791 {Name: "f11", Number: 11, Cardinality: pref.Optional, Kind: pref.BytesKind, Default: V([]byte("11")), OneofName: "union"},
792 {Name: "f12", Number: 12, Cardinality: pref.Optional, Kind: pref.BytesKind, Default: V([]byte("12")), OneofName: "union"},
793 {Name: "f13", Number: 13, Cardinality: pref.Optional, Kind: pref.BytesKind, Default: V([]byte("13")), OneofName: "union"},
794 },
795 Oneofs: []ptype.Oneof{{Name: "union"}},
796 }),
797 func(pref.MessageType) pref.ProtoMessage {
798 return new(OneofScalars)
799 },
800)}
801
802func (m *OneofScalars) Type() pref.MessageType { return oneofScalarsType.Type }
803func (m *OneofScalars) KnownFields() pref.KnownFields { return oneofScalarsType.KnownFieldsOf(m) }
804func (m *OneofScalars) UnknownFields() pref.UnknownFields { return oneofScalarsType.UnknownFieldsOf(m) }
805func (m *OneofScalars) Interface() pref.ProtoMessage { return m }
806func (m *OneofScalars) ProtoReflect() pref.Message { return m }
807func (m *OneofScalars) ProtoMutable() {}
808
Joe Tsaif18ab532018-11-27 17:25:04 -0800809func (*OneofScalars) XXX_OneofWrappers() []interface{} {
810 return []interface{}{
Joe Tsai2c870bb2018-10-17 11:46:52 -0700811 (*OneofScalars_Bool)(nil),
812 (*OneofScalars_Int32)(nil),
813 (*OneofScalars_Int64)(nil),
814 (*OneofScalars_Uint32)(nil),
815 (*OneofScalars_Uint64)(nil),
816 (*OneofScalars_Float32)(nil),
817 (*OneofScalars_Float64)(nil),
818 (*OneofScalars_String)(nil),
819 (*OneofScalars_StringA)(nil),
820 (*OneofScalars_StringB)(nil),
821 (*OneofScalars_Bytes)(nil),
822 (*OneofScalars_BytesA)(nil),
823 (*OneofScalars_BytesB)(nil),
824 }
825}
826
Joe Tsai87b955b2018-11-14 21:59:49 -0800827type (
828 isOneofScalars_Union interface {
829 isOneofScalars_Union()
830 }
831 OneofScalars_Bool struct {
832 Bool bool `protobuf:"1"`
833 }
834 OneofScalars_Int32 struct {
835 Int32 MyInt32 `protobuf:"2"`
836 }
837 OneofScalars_Int64 struct {
838 Int64 int64 `protobuf:"3"`
839 }
840 OneofScalars_Uint32 struct {
841 Uint32 MyUint32 `protobuf:"4"`
842 }
843 OneofScalars_Uint64 struct {
844 Uint64 uint64 `protobuf:"5"`
845 }
846 OneofScalars_Float32 struct {
847 Float32 MyFloat32 `protobuf:"6"`
848 }
849 OneofScalars_Float64 struct {
850 Float64 float64 `protobuf:"7"`
851 }
852 OneofScalars_String struct {
853 String string `protobuf:"8"`
854 }
855 OneofScalars_StringA struct {
856 StringA []byte `protobuf:"9"`
857 }
858 OneofScalars_StringB struct {
859 StringB MyString `protobuf:"10"`
860 }
861 OneofScalars_Bytes struct {
862 Bytes []byte `protobuf:"11"`
863 }
864 OneofScalars_BytesA struct {
865 BytesA string `protobuf:"12"`
866 }
867 OneofScalars_BytesB struct {
868 BytesB MyBytes `protobuf:"13"`
869 }
870)
871
Joe Tsai2c870bb2018-10-17 11:46:52 -0700872func (*OneofScalars_Bool) isOneofScalars_Union() {}
873func (*OneofScalars_Int32) isOneofScalars_Union() {}
874func (*OneofScalars_Int64) isOneofScalars_Union() {}
875func (*OneofScalars_Uint32) isOneofScalars_Union() {}
876func (*OneofScalars_Uint64) isOneofScalars_Union() {}
877func (*OneofScalars_Float32) isOneofScalars_Union() {}
878func (*OneofScalars_Float64) isOneofScalars_Union() {}
879func (*OneofScalars_String) isOneofScalars_Union() {}
880func (*OneofScalars_StringA) isOneofScalars_Union() {}
881func (*OneofScalars_StringB) isOneofScalars_Union() {}
882func (*OneofScalars_Bytes) isOneofScalars_Union() {}
883func (*OneofScalars_BytesA) isOneofScalars_Union() {}
884func (*OneofScalars_BytesB) isOneofScalars_Union() {}
885
886func TestOneofs(t *testing.T) {
Joe Tsaif0c01e42018-11-06 13:05:20 -0800887 empty := &OneofScalars{}
888 want1 := &OneofScalars{Union: &OneofScalars_Bool{true}}
889 want2 := &OneofScalars{Union: &OneofScalars_Int32{20}}
890 want3 := &OneofScalars{Union: &OneofScalars_Int64{30}}
891 want4 := &OneofScalars{Union: &OneofScalars_Uint32{40}}
892 want5 := &OneofScalars{Union: &OneofScalars_Uint64{50}}
893 want6 := &OneofScalars{Union: &OneofScalars_Float32{60}}
894 want7 := &OneofScalars{Union: &OneofScalars_Float64{70}}
895 want8 := &OneofScalars{Union: &OneofScalars_String{string("80")}}
896 want9 := &OneofScalars{Union: &OneofScalars_StringA{[]byte("90")}}
897 want10 := &OneofScalars{Union: &OneofScalars_StringB{MyString("100")}}
898 want11 := &OneofScalars{Union: &OneofScalars_Bytes{[]byte("110")}}
899 want12 := &OneofScalars{Union: &OneofScalars_BytesA{string("120")}}
900 want13 := &OneofScalars{Union: &OneofScalars_BytesB{MyBytes("130")}}
Joe Tsai2c870bb2018-10-17 11:46:52 -0700901
Joe Tsaif0c01e42018-11-06 13:05:20 -0800902 testMessage(t, nil, &OneofScalars{}, messageOps{
Joe Tsai2c870bb2018-10-17 11:46:52 -0700903 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},
904 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"))},
905
Joe Tsai87b955b2018-11-14 21:59:49 -0800906 setFields{1: V(bool(true))}, hasFields{1: true}, equalMessage{want1},
907 setFields{2: V(int32(20))}, hasFields{2: true}, equalMessage{want2},
908 setFields{3: V(int64(30))}, hasFields{3: true}, equalMessage{want3},
909 setFields{4: V(uint32(40))}, hasFields{4: true}, equalMessage{want4},
910 setFields{5: V(uint64(50))}, hasFields{5: true}, equalMessage{want5},
911 setFields{6: V(float32(60))}, hasFields{6: true}, equalMessage{want6},
912 setFields{7: V(float64(70))}, hasFields{7: true}, equalMessage{want7},
913 setFields{8: V(string("80"))}, hasFields{8: true}, equalMessage{want8},
914 setFields{9: V(string("90"))}, hasFields{9: true}, equalMessage{want9},
915 setFields{10: V(string("100"))}, hasFields{10: true}, equalMessage{want10},
916 setFields{11: V([]byte("110"))}, hasFields{11: true}, equalMessage{want11},
917 setFields{12: V([]byte("120"))}, hasFields{12: true}, equalMessage{want12},
918 setFields{13: V([]byte("130"))}, hasFields{13: true}, equalMessage{want13},
Joe Tsai2c870bb2018-10-17 11:46:52 -0700919
920 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},
921 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 -0800922 clearFields{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12},
923 equalMessage{want13},
924 clearFields{13},
925 equalMessage{empty},
Joe Tsai2c870bb2018-10-17 11:46:52 -0700926 })
Joe Tsai6cf80c42018-12-01 04:57:09 -0800927
928 // Test read-only operations on nil message.
929 testMessage(t, nil, (*OneofScalars)(nil), messageOps{
930 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},
931 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"))},
932 })
Joe Tsai2c870bb2018-10-17 11:46:52 -0700933}
934
Joe Tsai87b955b2018-11-14 21:59:49 -0800935type EnumProto2 int32
936
937var enumProto2Type = ptype.GoEnum(
938 mustMakeEnumDesc(ptype.StandaloneEnum{
939 Syntax: pref.Proto2,
940 FullName: "EnumProto2",
941 Values: []ptype.EnumValue{{Name: "DEAD", Number: 0xdead}, {Name: "BEEF", Number: 0xbeef}},
942 }),
943 func(_ pref.EnumType, n pref.EnumNumber) pref.ProtoEnum {
944 return EnumProto2(n)
945 },
946)
947
948func (e EnumProto2) Enum() *EnumProto2 { return &e }
949func (e EnumProto2) Type() pref.EnumType { return enumProto2Type }
950func (e EnumProto2) Number() pref.EnumNumber { return pref.EnumNumber(e) }
951func (e EnumProto2) ProtoReflect() pref.Enum { return e }
952
953type EnumProto3 int32
954
955var enumProto3Type = ptype.GoEnum(
956 mustMakeEnumDesc(ptype.StandaloneEnum{
957 Syntax: pref.Proto3,
958 FullName: "EnumProto3",
959 Values: []ptype.EnumValue{{Name: "ALPHA", Number: 0}, {Name: "BRAVO", Number: 1}},
960 }),
961 func(_ pref.EnumType, n pref.EnumNumber) pref.ProtoEnum {
962 return EnumProto3(n)
963 },
964)
965
966func (e EnumProto3) Enum() *EnumProto3 { return &e }
967func (e EnumProto3) Type() pref.EnumType { return enumProto3Type }
968func (e EnumProto3) Number() pref.EnumNumber { return pref.EnumNumber(e) }
969func (e EnumProto3) ProtoReflect() pref.Enum { return e }
970
971type EnumMessages struct {
972 EnumP2 *EnumProto2 `protobuf:"1"`
973 EnumP3 *EnumProto3 `protobuf:"2"`
974 MessageLegacy *proto2_20180125.Message `protobuf:"3"`
975 MessageCycle *EnumMessages `protobuf:"4"`
976 EnumList []EnumProto2 `protobuf:"5"`
977 MessageList []*ScalarProto2 `protobuf:"6"`
978 EnumMap map[string]EnumProto3 `protobuf:"7"`
979 MessageMap map[string]*ScalarProto3 `protobuf:"8"`
980 Union isEnumMessages_Union `protobuf_oneof:"union"`
981}
982
Joe Tsai08e00302018-11-26 22:32:06 -0800983var enumMessagesType = pimpl.MessageType{Type: ptype.GoMessage(
Joe Tsai87b955b2018-11-14 21:59:49 -0800984 mustMakeMessageDesc(ptype.StandaloneMessage{
985 Syntax: pref.Proto2,
986 FullName: "EnumMessages",
987 Fields: []ptype.Field{
988 {Name: "f1", Number: 1, Cardinality: pref.Optional, Kind: pref.EnumKind, Default: V("BEEF"), EnumType: enumProto2Type},
989 {Name: "f2", Number: 2, Cardinality: pref.Optional, Kind: pref.EnumKind, Default: V("BRAVO"), EnumType: enumProto3Type},
Joe Tsai08e00302018-11-26 22:32:06 -0800990 {Name: "f3", Number: 3, Cardinality: pref.Optional, Kind: pref.MessageKind, MessageType: pimpl.Export{}.MessageOf(new(proto2_20180125.Message)).Type()},
Joe Tsai87b955b2018-11-14 21:59:49 -0800991 {Name: "f4", Number: 4, Cardinality: pref.Optional, Kind: pref.MessageKind, MessageType: ptype.PlaceholderMessage("EnumMessages")},
992 {Name: "f5", Number: 5, Cardinality: pref.Repeated, Kind: pref.EnumKind, EnumType: enumProto2Type},
993 {Name: "f6", Number: 6, Cardinality: pref.Repeated, Kind: pref.MessageKind, MessageType: scalarProto2Type.Type},
994 {Name: "f7", Number: 7, Cardinality: pref.Repeated, Kind: pref.MessageKind, MessageType: enumMapDesc},
995 {Name: "f8", Number: 8, Cardinality: pref.Repeated, Kind: pref.MessageKind, MessageType: messageMapDesc},
996 {Name: "f9", Number: 9, Cardinality: pref.Optional, Kind: pref.EnumKind, Default: V("BEEF"), OneofName: "union", EnumType: enumProto2Type},
997 {Name: "f10", Number: 10, Cardinality: pref.Optional, Kind: pref.EnumKind, Default: V("BRAVO"), OneofName: "union", EnumType: enumProto3Type},
998 {Name: "f11", Number: 11, Cardinality: pref.Optional, Kind: pref.MessageKind, OneofName: "union", MessageType: scalarProto2Type.Type},
999 {Name: "f12", Number: 12, Cardinality: pref.Optional, Kind: pref.MessageKind, OneofName: "union", MessageType: scalarProto3Type.Type},
1000 },
1001 Oneofs: []ptype.Oneof{{Name: "union"}},
1002 }),
1003 func(pref.MessageType) pref.ProtoMessage {
1004 return new(EnumMessages)
1005 },
1006)}
1007
1008var enumMapDesc = mustMakeMessageDesc(ptype.StandaloneMessage{
1009 Syntax: pref.Proto2,
1010 FullName: "EnumMessages.F7Entry",
1011 Fields: []ptype.Field{
1012 {Name: "key", Number: 1, Cardinality: pref.Optional, Kind: pref.StringKind},
1013 {Name: "value", Number: 2, Cardinality: pref.Optional, Kind: pref.EnumKind, EnumType: enumProto3Type},
1014 },
Joe Tsai6cf80c42018-12-01 04:57:09 -08001015 Options: &descriptorpb.MessageOptions{MapEntry: scalar.Bool(true)},
Joe Tsai87b955b2018-11-14 21:59:49 -08001016})
1017
1018var messageMapDesc = mustMakeMessageDesc(ptype.StandaloneMessage{
1019 Syntax: pref.Proto2,
1020 FullName: "EnumMessages.F8Entry",
1021 Fields: []ptype.Field{
1022 {Name: "key", Number: 1, Cardinality: pref.Optional, Kind: pref.StringKind},
1023 {Name: "value", Number: 2, Cardinality: pref.Optional, Kind: pref.MessageKind, MessageType: scalarProto3Type.Type},
1024 },
Joe Tsai6cf80c42018-12-01 04:57:09 -08001025 Options: &descriptorpb.MessageOptions{MapEntry: scalar.Bool(true)},
Joe Tsai87b955b2018-11-14 21:59:49 -08001026})
1027
1028func (m *EnumMessages) Type() pref.MessageType { return enumMessagesType.Type }
1029func (m *EnumMessages) KnownFields() pref.KnownFields { return enumMessagesType.KnownFieldsOf(m) }
1030func (m *EnumMessages) UnknownFields() pref.UnknownFields { return enumMessagesType.UnknownFieldsOf(m) }
1031func (m *EnumMessages) Interface() pref.ProtoMessage { return m }
1032func (m *EnumMessages) ProtoReflect() pref.Message { return m }
1033func (m *EnumMessages) ProtoMutable() {}
1034
Joe Tsaif18ab532018-11-27 17:25:04 -08001035func (*EnumMessages) XXX_OneofWrappers() []interface{} {
1036 return []interface{}{
Joe Tsai87b955b2018-11-14 21:59:49 -08001037 (*EnumMessages_OneofE2)(nil),
1038 (*EnumMessages_OneofE3)(nil),
1039 (*EnumMessages_OneofM2)(nil),
1040 (*EnumMessages_OneofM3)(nil),
1041 }
1042}
1043
1044type (
1045 isEnumMessages_Union interface {
1046 isEnumMessages_Union()
1047 }
1048 EnumMessages_OneofE2 struct {
1049 OneofE2 EnumProto2 `protobuf:"9"`
1050 }
1051 EnumMessages_OneofE3 struct {
1052 OneofE3 EnumProto3 `protobuf:"10"`
1053 }
1054 EnumMessages_OneofM2 struct {
1055 OneofM2 *ScalarProto2 `protobuf:"11"`
1056 }
1057 EnumMessages_OneofM3 struct {
1058 OneofM3 *ScalarProto3 `protobuf:"12"`
1059 }
1060)
1061
1062func (*EnumMessages_OneofE2) isEnumMessages_Union() {}
1063func (*EnumMessages_OneofE3) isEnumMessages_Union() {}
1064func (*EnumMessages_OneofM2) isEnumMessages_Union() {}
1065func (*EnumMessages_OneofM3) isEnumMessages_Union() {}
1066
1067func TestEnumMessages(t *testing.T) {
Joe Tsai08e00302018-11-26 22:32:06 -08001068 wantL := pimpl.Export{}.MessageOf(&proto2_20180125.Message{OptionalFloat: scalar.Float32(math.E)})
Joe Tsai87b955b2018-11-14 21:59:49 -08001069 wantM := &EnumMessages{EnumP2: EnumProto2(1234).Enum()}
Joe Tsai009e0672018-11-27 18:45:07 -08001070 wantM2a := &ScalarProto2{Float32: scalar.Float32(math.Pi)}
1071 wantM2b := &ScalarProto2{Float32: scalar.Float32(math.Phi)}
Joe Tsai87b955b2018-11-14 21:59:49 -08001072 wantM3a := &ScalarProto3{Float32: math.Pi}
1073 wantM3b := &ScalarProto3{Float32: math.Ln2}
1074
1075 wantList5 := (&EnumMessages{EnumList: []EnumProto2{333, 222}}).KnownFields().Get(5)
1076 wantList6 := (&EnumMessages{MessageList: []*ScalarProto2{wantM2a, wantM2b}}).KnownFields().Get(6)
1077
1078 wantMap7 := (&EnumMessages{EnumMap: map[string]EnumProto3{"one": 1, "two": 2}}).KnownFields().Get(7)
1079 wantMap8 := (&EnumMessages{MessageMap: map[string]*ScalarProto3{"pi": wantM3a, "ln2": wantM3b}}).KnownFields().Get(8)
1080
1081 testMessage(t, nil, &EnumMessages{}, messageOps{
1082 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 -08001083 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 -08001084
1085 // Test singular enums.
1086 setFields{1: VE(0xdead), 2: VE(0)},
1087 getFields{1: VE(0xdead), 2: VE(0)},
1088 hasFields{1: true, 2: true},
1089
1090 // Test singular messages.
1091 messageFields{3: messageOps{setFields{109: V(float32(math.E))}}},
1092 messageFields{4: messageOps{setFields{1: VE(1234)}}},
1093 getFields{3: V(wantL), 4: V(wantM)},
1094 clearFields{3, 4},
1095 hasFields{3: false, 4: false},
1096 setFields{3: V(wantL), 4: V(wantM)},
1097 hasFields{3: true, 4: true},
1098
1099 // Test list of enums and messages.
1100 listFields{
1101 5: listOps{
1102 appendList{VE(111), VE(222)},
1103 setList{0: VE(333)},
1104 getList{0: VE(333), 1: VE(222)},
1105 lenList(2),
1106 },
1107 6: listOps{
1108 appendMessageList{setFields{4: V(uint32(1e6))}},
1109 appendMessageList{setFields{6: V(float32(math.Phi))}},
1110 setList{0: V(wantM2a)},
1111 getList{0: V(wantM2a), 1: V(wantM2b)},
1112 },
1113 },
1114 getFields{5: wantList5, 6: wantList6},
1115 hasFields{5: true, 6: true},
1116 listFields{5: listOps{truncList(0)}},
1117 hasFields{5: false, 6: true},
1118
1119 // Test maps of enums and messages.
1120 mapFields{
1121 7: mapOps{
1122 setMap{"one": VE(1), "two": VE(2)},
1123 hasMap{"one": true, "two": true, "three": false},
1124 lenMap(2),
1125 },
1126 8: mapOps{
1127 messageMap{"pi": messageOps{setFields{6: V(float32(math.Pi))}}},
1128 setMap{"ln2": V(wantM3b)},
1129 getMap{"pi": V(wantM3a), "ln2": V(wantM3b), "none": V(nil)},
1130 lenMap(2),
1131 },
1132 },
1133 getFields{7: wantMap7, 8: wantMap8},
1134 hasFields{7: true, 8: true},
1135 mapFields{8: mapOps{clearMap{"pi", "ln2", "none"}}},
1136 hasFields{7: true, 8: false},
1137
1138 // Test oneofs of enums and messages.
1139 setFields{9: VE(0xdead)},
1140 hasFields{1: true, 2: true, 9: true, 10: false, 11: false, 12: false},
1141 setFields{10: VE(0)},
1142 hasFields{1: true, 2: true, 9: false, 10: true, 11: false, 12: false},
1143 messageFields{11: messageOps{setFields{6: V(float32(math.Pi))}}},
1144 getFields{11: V(wantM2a)},
1145 hasFields{1: true, 2: true, 9: false, 10: false, 11: true, 12: false},
1146 messageFields{12: messageOps{setFields{6: V(float32(math.Pi))}}},
1147 getFields{12: V(wantM3a)},
1148 hasFields{1: true, 2: true, 9: false, 10: false, 11: false, 12: true},
1149
1150 // Check entire message.
1151 rangeFields{1: VE(0xdead), 2: VE(0), 3: V(wantL), 4: V(wantM), 6: wantList6, 7: wantMap7, 12: V(wantM3a)},
1152 equalMessage{&EnumMessages{
1153 EnumP2: EnumProto2(0xdead).Enum(),
1154 EnumP3: EnumProto3(0).Enum(),
Joe Tsai009e0672018-11-27 18:45:07 -08001155 MessageLegacy: &proto2_20180125.Message{OptionalFloat: scalar.Float32(math.E)},
Joe Tsai87b955b2018-11-14 21:59:49 -08001156 MessageCycle: wantM,
1157 MessageList: []*ScalarProto2{wantM2a, wantM2b},
1158 EnumMap: map[string]EnumProto3{"one": 1, "two": 2},
1159 Union: &EnumMessages_OneofM3{wantM3a},
1160 }},
1161 clearFields{1, 2, 3, 4, 6, 7, 12},
1162 equalMessage{&EnumMessages{}},
1163 })
Joe Tsai6cf80c42018-12-01 04:57:09 -08001164
1165 // Test read-only operations on nil message.
1166 testMessage(t, nil, (*EnumMessages)(nil), messageOps{
1167 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},
1168 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)},
1169 listFields{5: {lenList(0)}, 6: {lenList(0)}},
1170 mapFields{7: {lenMap(0)}, 8: {lenMap(0)}},
1171 })
Joe Tsai87b955b2018-11-14 21:59:49 -08001172}
Joe Tsaifa02f4e2018-09-12 16:20:37 -07001173
Joe Tsai91e14662018-09-13 13:24:35 -07001174var cmpOpts = cmp.Options{
Joe Tsai87b955b2018-11-14 21:59:49 -08001175 cmp.Comparer(func(x, y *proto2_20180125.Message) bool {
1176 return protoV1.Equal(x, y)
Joe Tsai91e14662018-09-13 13:24:35 -07001177 }),
Joe Tsai87b955b2018-11-14 21:59:49 -08001178 cmp.Transformer("UnwrapValue", func(pv pref.Value) interface{} {
1179 return pv.Interface()
Joe Tsai91e14662018-09-13 13:24:35 -07001180 }),
Joe Tsai87b955b2018-11-14 21:59:49 -08001181 cmp.Transformer("UnwrapGeneric", func(x pvalue.Unwrapper) interface{} {
Joe Tsaiba0ef9a2018-11-29 14:54:05 -08001182 return x.ProtoUnwrap()
Joe Tsai91e14662018-09-13 13:24:35 -07001183 }),
1184 cmpopts.EquateNaNs(),
Joe Tsai87b955b2018-11-14 21:59:49 -08001185 cmpopts.EquateEmpty(),
Joe Tsai91e14662018-09-13 13:24:35 -07001186}
1187
1188func testMessage(t *testing.T, p path, m pref.Message, tt messageOps) {
1189 fs := m.KnownFields()
1190 for i, op := range tt {
1191 p.Push(i)
1192 switch op := op.(type) {
1193 case equalMessage:
Joe Tsai87b955b2018-11-14 21:59:49 -08001194 if diff := cmp.Diff(op.Message, m, cmpOpts); diff != "" {
Joe Tsai91e14662018-09-13 13:24:35 -07001195 t.Errorf("operation %v, message mismatch (-want, +got):\n%s", p, diff)
1196 }
1197 case hasFields:
1198 got := map[pref.FieldNumber]bool{}
1199 want := map[pref.FieldNumber]bool(op)
1200 for n := range want {
1201 got[n] = fs.Has(n)
1202 }
1203 if diff := cmp.Diff(want, got); diff != "" {
1204 t.Errorf("operation %v, KnownFields.Has mismatch (-want, +got):\n%s", p, diff)
1205 }
1206 case getFields:
1207 got := map[pref.FieldNumber]pref.Value{}
1208 want := map[pref.FieldNumber]pref.Value(op)
1209 for n := range want {
1210 got[n] = fs.Get(n)
1211 }
1212 if diff := cmp.Diff(want, got, cmpOpts); diff != "" {
1213 t.Errorf("operation %v, KnownFields.Get mismatch (-want, +got):\n%s", p, diff)
1214 }
1215 case setFields:
1216 for n, v := range op {
1217 fs.Set(n, v)
1218 }
1219 case clearFields:
Joe Tsai87b955b2018-11-14 21:59:49 -08001220 for _, n := range op {
1221 fs.Clear(n)
1222 }
1223 case messageFields:
1224 for n, tt := range op {
1225 p.Push(int(n))
1226 testMessage(t, p, fs.Mutable(n).(pref.Message), tt)
1227 p.Pop()
Joe Tsaifa02f4e2018-09-12 16:20:37 -07001228 }
Joe Tsai4b7aff62018-11-14 14:05:19 -08001229 case listFields:
Joe Tsai91e14662018-09-13 13:24:35 -07001230 for n, tt := range op {
1231 p.Push(int(n))
Joe Tsai6cf80c42018-12-01 04:57:09 -08001232 testLists(t, p, fs.Get(n).List(), tt)
Joe Tsai91e14662018-09-13 13:24:35 -07001233 p.Pop()
1234 }
Joe Tsaibbfaeb72018-10-17 00:27:21 +00001235 case mapFields:
1236 for n, tt := range op {
1237 p.Push(int(n))
Joe Tsai6cf80c42018-12-01 04:57:09 -08001238 testMaps(t, p, fs.Get(n).Map(), tt)
Joe Tsaibbfaeb72018-10-17 00:27:21 +00001239 p.Pop()
1240 }
Joe Tsai87b955b2018-11-14 21:59:49 -08001241 case rangeFields:
1242 got := map[pref.FieldNumber]pref.Value{}
1243 want := map[pref.FieldNumber]pref.Value(op)
1244 fs.Range(func(n pref.FieldNumber, v pref.Value) bool {
1245 got[n] = v
1246 return true
1247 })
1248 if diff := cmp.Diff(want, got, cmpOpts); diff != "" {
1249 t.Errorf("operation %v, KnownFields.Range mismatch (-want, +got):\n%s", p, diff)
1250 }
Joe Tsai91e14662018-09-13 13:24:35 -07001251 default:
1252 t.Fatalf("operation %v, invalid operation: %T", p, op)
1253 }
1254 p.Pop()
Joe Tsaifa02f4e2018-09-12 16:20:37 -07001255 }
1256}
Joe Tsai91e14662018-09-13 13:24:35 -07001257
Joe Tsai4b7aff62018-11-14 14:05:19 -08001258func testLists(t *testing.T, p path, v pref.List, tt listOps) {
Joe Tsai91e14662018-09-13 13:24:35 -07001259 for i, op := range tt {
1260 p.Push(i)
1261 switch op := op.(type) {
Joe Tsai4b7aff62018-11-14 14:05:19 -08001262 case equalList:
Joe Tsai87b955b2018-11-14 21:59:49 -08001263 if diff := cmp.Diff(op.List, v, cmpOpts); diff != "" {
Joe Tsai4b7aff62018-11-14 14:05:19 -08001264 t.Errorf("operation %v, list mismatch (-want, +got):\n%s", p, diff)
Joe Tsai91e14662018-09-13 13:24:35 -07001265 }
Joe Tsai4b7aff62018-11-14 14:05:19 -08001266 case lenList:
Joe Tsai91e14662018-09-13 13:24:35 -07001267 if got, want := v.Len(), int(op); got != want {
Joe Tsai4b7aff62018-11-14 14:05:19 -08001268 t.Errorf("operation %v, List.Len = %d, want %d", p, got, want)
Joe Tsai91e14662018-09-13 13:24:35 -07001269 }
Joe Tsai4b7aff62018-11-14 14:05:19 -08001270 case getList:
Joe Tsai91e14662018-09-13 13:24:35 -07001271 got := map[int]pref.Value{}
1272 want := map[int]pref.Value(op)
1273 for n := range want {
1274 got[n] = v.Get(n)
1275 }
1276 if diff := cmp.Diff(want, got, cmpOpts); diff != "" {
Joe Tsai4b7aff62018-11-14 14:05:19 -08001277 t.Errorf("operation %v, List.Get mismatch (-want, +got):\n%s", p, diff)
Joe Tsai91e14662018-09-13 13:24:35 -07001278 }
Joe Tsai4b7aff62018-11-14 14:05:19 -08001279 case setList:
Joe Tsai91e14662018-09-13 13:24:35 -07001280 for n, e := range op {
1281 v.Set(n, e)
1282 }
Joe Tsai4b7aff62018-11-14 14:05:19 -08001283 case appendList:
Joe Tsai91e14662018-09-13 13:24:35 -07001284 for _, e := range op {
1285 v.Append(e)
1286 }
Joe Tsai87b955b2018-11-14 21:59:49 -08001287 case appendMessageList:
1288 testMessage(t, p, v.MutableAppend().(pref.Message), messageOps(op))
Joe Tsai4b7aff62018-11-14 14:05:19 -08001289 case truncList:
Joe Tsai91e14662018-09-13 13:24:35 -07001290 v.Truncate(int(op))
1291 default:
1292 t.Fatalf("operation %v, invalid operation: %T", p, op)
1293 }
1294 p.Pop()
1295 }
1296}
1297
Joe Tsaibbfaeb72018-10-17 00:27:21 +00001298func testMaps(t *testing.T, p path, m pref.Map, tt mapOps) {
1299 for i, op := range tt {
1300 p.Push(i)
1301 switch op := op.(type) {
1302 case equalMap:
Joe Tsai87b955b2018-11-14 21:59:49 -08001303 if diff := cmp.Diff(op.Map, m, cmpOpts); diff != "" {
Joe Tsaibbfaeb72018-10-17 00:27:21 +00001304 t.Errorf("operation %v, map mismatch (-want, +got):\n%s", p, diff)
1305 }
1306 case lenMap:
1307 if got, want := m.Len(), int(op); got != want {
1308 t.Errorf("operation %v, Map.Len = %d, want %d", p, got, want)
1309 }
1310 case hasMap:
1311 got := map[interface{}]bool{}
1312 want := map[interface{}]bool(op)
1313 for k := range want {
1314 got[k] = m.Has(V(k).MapKey())
1315 }
1316 if diff := cmp.Diff(want, got, cmpOpts); diff != "" {
1317 t.Errorf("operation %v, Map.Has mismatch (-want, +got):\n%s", p, diff)
1318 }
1319 case getMap:
1320 got := map[interface{}]pref.Value{}
1321 want := map[interface{}]pref.Value(op)
1322 for k := range want {
1323 got[k] = m.Get(V(k).MapKey())
1324 }
1325 if diff := cmp.Diff(want, got, cmpOpts); diff != "" {
1326 t.Errorf("operation %v, Map.Get mismatch (-want, +got):\n%s", p, diff)
1327 }
1328 case setMap:
1329 for k, v := range op {
1330 m.Set(V(k).MapKey(), v)
1331 }
1332 case clearMap:
Joe Tsai87b955b2018-11-14 21:59:49 -08001333 for _, k := range op {
1334 m.Clear(V(k).MapKey())
1335 }
1336 case messageMap:
1337 for k, tt := range op {
1338 testMessage(t, p, m.Mutable(V(k).MapKey()).(pref.Message), tt)
Joe Tsaibbfaeb72018-10-17 00:27:21 +00001339 }
1340 case rangeMap:
1341 got := map[interface{}]pref.Value{}
1342 want := map[interface{}]pref.Value(op)
1343 m.Range(func(k pref.MapKey, v pref.Value) bool {
1344 got[k.Interface()] = v
1345 return true
1346 })
1347 if diff := cmp.Diff(want, got, cmpOpts); diff != "" {
1348 t.Errorf("operation %v, Map.Range mismatch (-want, +got):\n%s", p, diff)
1349 }
1350 default:
1351 t.Fatalf("operation %v, invalid operation: %T", p, op)
1352 }
1353 p.Pop()
1354 }
1355}
1356
Joe Tsai91e14662018-09-13 13:24:35 -07001357type path []int
1358
1359func (p *path) Push(i int) { *p = append(*p, i) }
1360func (p *path) Pop() { *p = (*p)[:len(*p)-1] }
1361func (p path) String() string {
1362 var ss []string
1363 for _, i := range p {
1364 ss = append(ss, fmt.Sprint(i))
1365 }
1366 return strings.Join(ss, ".")
1367}