blob: f49e5c1388c5dc9e6b85b784d6ae4d4e596cf3f9 [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 }
Joe Tsaif0c01e42018-11-06 13:05:20 -0800232
233func TestScalarProto2(t *testing.T) {
234 testMessage(t, nil, &ScalarProto2{}, messageOps{
Joe Tsai91e14662018-09-13 13:24:35 -0700235 hasFields{
236 1: false, 2: false, 3: false, 4: false, 5: false, 6: false, 7: false, 8: false, 9: false, 10: false, 11: false,
237 12: false, 13: false, 14: false, 15: false, 16: false, 17: false, 18: false, 19: false, 20: false, 21: false, 22: false,
238 },
239 getFields{
240 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")),
241 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")),
242 },
243 setFields{
244 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)),
245 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)),
246 },
247 hasFields{
248 1: true, 2: true, 3: true, 4: true, 5: true, 6: true, 7: true, 8: true, 9: true, 10: true, 11: true,
249 12: true, 13: true, 14: true, 15: true, 16: true, 17: true, 18: true, 19: true, 20: true, 21: true, 22: true,
250 },
Joe Tsai87b955b2018-11-14 21:59:49 -0800251 equalMessage{&ScalarProto2{
Joe Tsai91e14662018-09-13 13:24:35 -0700252 new(bool), new(int32), new(int64), new(uint32), new(uint64), new(float32), new(float64), new(string), []byte{}, []byte{}, new(string),
253 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 -0800254 }},
255 clearFields{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22},
256 equalMessage{&ScalarProto2{}},
Joe Tsai91e14662018-09-13 13:24:35 -0700257 })
Joe Tsai6cf80c42018-12-01 04:57:09 -0800258
259 // Test read-only operations on nil message.
260 testMessage(t, nil, (*ScalarProto2)(nil), messageOps{
261 hasFields{
262 1: false, 2: false, 3: false, 4: false, 5: false, 6: false, 7: false, 8: false, 9: false, 10: false, 11: false,
263 12: false, 13: false, 14: false, 15: false, 16: false, 17: false, 18: false, 19: false, 20: false, 21: false, 22: false,
264 },
265 getFields{
266 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")),
267 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")),
268 },
269 })
Joe Tsaifa02f4e2018-09-12 16:20:37 -0700270}
271
Joe Tsaice6edd32018-10-19 16:27:46 -0700272type ScalarProto3 struct {
273 Bool bool `protobuf:"1"`
274 Int32 int32 `protobuf:"2"`
275 Int64 int64 `protobuf:"3"`
276 Uint32 uint32 `protobuf:"4"`
277 Uint64 uint64 `protobuf:"5"`
278 Float32 float32 `protobuf:"6"`
279 Float64 float64 `protobuf:"7"`
280 String string `protobuf:"8"`
281 StringA []byte `protobuf:"9"`
282 Bytes []byte `protobuf:"10"`
283 BytesA string `protobuf:"11"`
284
285 MyBool MyBool `protobuf:"12"`
286 MyInt32 MyInt32 `protobuf:"13"`
287 MyInt64 MyInt64 `protobuf:"14"`
288 MyUint32 MyUint32 `protobuf:"15"`
289 MyUint64 MyUint64 `protobuf:"16"`
290 MyFloat32 MyFloat32 `protobuf:"17"`
291 MyFloat64 MyFloat64 `protobuf:"18"`
292 MyString MyString `protobuf:"19"`
293 MyStringA MyBytes `protobuf:"20"`
294 MyBytes MyBytes `protobuf:"21"`
295 MyBytesA MyString `protobuf:"22"`
296}
297
Joe Tsai08e00302018-11-26 22:32:06 -0800298var scalarProto3Type = pimpl.MessageType{Type: ptype.GoMessage(
Joe Tsaif0c01e42018-11-06 13:05:20 -0800299 mustMakeMessageDesc(ptype.StandaloneMessage{
Joe Tsai91e14662018-09-13 13:24:35 -0700300 Syntax: pref.Proto3,
301 FullName: "ScalarProto3",
302 Fields: []ptype.Field{
303 {Name: "f1", Number: 1, Cardinality: pref.Optional, Kind: pref.BoolKind},
304 {Name: "f2", Number: 2, Cardinality: pref.Optional, Kind: pref.Int32Kind},
305 {Name: "f3", Number: 3, Cardinality: pref.Optional, Kind: pref.Int64Kind},
306 {Name: "f4", Number: 4, Cardinality: pref.Optional, Kind: pref.Uint32Kind},
307 {Name: "f5", Number: 5, Cardinality: pref.Optional, Kind: pref.Uint64Kind},
308 {Name: "f6", Number: 6, Cardinality: pref.Optional, Kind: pref.FloatKind},
309 {Name: "f7", Number: 7, Cardinality: pref.Optional, Kind: pref.DoubleKind},
310 {Name: "f8", Number: 8, Cardinality: pref.Optional, Kind: pref.StringKind},
311 {Name: "f9", Number: 9, Cardinality: pref.Optional, Kind: pref.StringKind},
312 {Name: "f10", Number: 10, Cardinality: pref.Optional, Kind: pref.BytesKind},
313 {Name: "f11", Number: 11, Cardinality: pref.Optional, Kind: pref.BytesKind},
Joe Tsaifa02f4e2018-09-12 16:20:37 -0700314
Joe Tsai91e14662018-09-13 13:24:35 -0700315 {Name: "f12", Number: 12, Cardinality: pref.Optional, Kind: pref.BoolKind},
316 {Name: "f13", Number: 13, Cardinality: pref.Optional, Kind: pref.Int32Kind},
317 {Name: "f14", Number: 14, Cardinality: pref.Optional, Kind: pref.Int64Kind},
318 {Name: "f15", Number: 15, Cardinality: pref.Optional, Kind: pref.Uint32Kind},
319 {Name: "f16", Number: 16, Cardinality: pref.Optional, Kind: pref.Uint64Kind},
320 {Name: "f17", Number: 17, Cardinality: pref.Optional, Kind: pref.FloatKind},
321 {Name: "f18", Number: 18, Cardinality: pref.Optional, Kind: pref.DoubleKind},
322 {Name: "f19", Number: 19, Cardinality: pref.Optional, Kind: pref.StringKind},
323 {Name: "f20", Number: 20, Cardinality: pref.Optional, Kind: pref.StringKind},
324 {Name: "f21", Number: 21, Cardinality: pref.Optional, Kind: pref.BytesKind},
325 {Name: "f22", Number: 22, Cardinality: pref.Optional, Kind: pref.BytesKind},
326 },
Joe Tsaif0c01e42018-11-06 13:05:20 -0800327 }),
328 func(pref.MessageType) pref.ProtoMessage {
329 return new(ScalarProto3)
330 },
331)}
Joe Tsai91e14662018-09-13 13:24:35 -0700332
Joe Tsaif0c01e42018-11-06 13:05:20 -0800333func (m *ScalarProto3) Type() pref.MessageType { return scalarProto3Type.Type }
334func (m *ScalarProto3) KnownFields() pref.KnownFields { return scalarProto3Type.KnownFieldsOf(m) }
335func (m *ScalarProto3) UnknownFields() pref.UnknownFields { return scalarProto3Type.UnknownFieldsOf(m) }
336func (m *ScalarProto3) Interface() pref.ProtoMessage { return m }
337func (m *ScalarProto3) ProtoReflect() pref.Message { return m }
Joe Tsaif0c01e42018-11-06 13:05:20 -0800338
339func TestScalarProto3(t *testing.T) {
340 testMessage(t, nil, &ScalarProto3{}, messageOps{
Joe Tsai91e14662018-09-13 13:24:35 -0700341 hasFields{
342 1: false, 2: false, 3: false, 4: false, 5: false, 6: false, 7: false, 8: false, 9: false, 10: false, 11: false,
343 12: false, 13: false, 14: false, 15: false, 16: false, 17: false, 18: false, 19: false, 20: false, 21: false, 22: false,
344 },
345 getFields{
346 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)),
347 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)),
348 },
349 setFields{
350 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)),
351 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)),
352 },
353 hasFields{
354 1: false, 2: false, 3: false, 4: false, 5: false, 6: false, 7: false, 8: false, 9: false, 10: false, 11: false,
355 12: false, 13: false, 14: false, 15: false, 16: false, 17: false, 18: false, 19: false, 20: false, 21: false, 22: false,
356 },
Joe Tsai87b955b2018-11-14 21:59:49 -0800357 equalMessage{&ScalarProto3{}},
Joe Tsai91e14662018-09-13 13:24:35 -0700358 setFields{
359 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")),
360 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")),
361 },
362 hasFields{
363 1: true, 2: true, 3: true, 4: true, 5: true, 6: true, 7: true, 8: true, 9: true, 10: true, 11: true,
364 12: true, 13: true, 14: true, 15: true, 16: true, 17: true, 18: true, 19: true, 20: true, 21: true, 22: true,
365 },
Joe Tsai87b955b2018-11-14 21:59:49 -0800366 equalMessage{&ScalarProto3{
Joe Tsai91e14662018-09-13 13:24:35 -0700367 true, 2, 3, 4, 5, 6, 7, "8", []byte("9"), []byte("10"), "11",
368 true, 13, 14, 15, 16, 17, 18, "19", []byte("20"), []byte("21"), "22",
Joe Tsai87b955b2018-11-14 21:59:49 -0800369 }},
Joe Tsai44e389c2018-11-19 15:27:09 -0800370 setFields{
371 2: V(int32(-2)), 3: V(int64(-3)), 6: V(float32(math.Inf(-1))), 7: V(float64(math.NaN())),
372 },
373 hasFields{
374 2: true, 3: true, 6: true, 7: true,
375 },
Joe Tsai87b955b2018-11-14 21:59:49 -0800376 clearFields{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22},
377 equalMessage{&ScalarProto3{}},
Joe Tsai91e14662018-09-13 13:24:35 -0700378 })
Joe Tsai6cf80c42018-12-01 04:57:09 -0800379
380 // Test read-only operations on nil message.
381 testMessage(t, nil, (*ScalarProto3)(nil), messageOps{
382 hasFields{
383 1: false, 2: false, 3: false, 4: false, 5: false, 6: false, 7: false, 8: false, 9: false, 10: false, 11: false,
384 12: false, 13: false, 14: false, 15: false, 16: false, 17: false, 18: false, 19: false, 20: false, 21: false, 22: false,
385 },
386 getFields{
387 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)),
388 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)),
389 },
390 })
Joe Tsaifa02f4e2018-09-12 16:20:37 -0700391}
392
Joe Tsaif0c01e42018-11-06 13:05:20 -0800393type ListScalars struct {
Joe Tsaice6edd32018-10-19 16:27:46 -0700394 Bools []bool `protobuf:"1"`
395 Int32s []int32 `protobuf:"2"`
396 Int64s []int64 `protobuf:"3"`
397 Uint32s []uint32 `protobuf:"4"`
398 Uint64s []uint64 `protobuf:"5"`
399 Float32s []float32 `protobuf:"6"`
400 Float64s []float64 `protobuf:"7"`
401 Strings []string `protobuf:"8"`
402 StringsA [][]byte `protobuf:"9"`
403 Bytes [][]byte `protobuf:"10"`
404 BytesA []string `protobuf:"11"`
405
406 MyStrings1 []MyString `protobuf:"12"`
407 MyStrings2 []MyBytes `protobuf:"13"`
408 MyBytes1 []MyBytes `protobuf:"14"`
409 MyBytes2 []MyString `protobuf:"15"`
410
Joe Tsai4b7aff62018-11-14 14:05:19 -0800411 MyStrings3 ListStrings `protobuf:"16"`
412 MyStrings4 ListBytes `protobuf:"17"`
413 MyBytes3 ListBytes `protobuf:"18"`
414 MyBytes4 ListStrings `protobuf:"19"`
Joe Tsaice6edd32018-10-19 16:27:46 -0700415}
416
Joe Tsai08e00302018-11-26 22:32:06 -0800417var listScalarsType = pimpl.MessageType{Type: ptype.GoMessage(
Joe Tsaif0c01e42018-11-06 13:05:20 -0800418 mustMakeMessageDesc(ptype.StandaloneMessage{
Joe Tsai91e14662018-09-13 13:24:35 -0700419 Syntax: pref.Proto2,
Joe Tsaif0c01e42018-11-06 13:05:20 -0800420 FullName: "ListScalars",
Joe Tsai91e14662018-09-13 13:24:35 -0700421 Fields: []ptype.Field{
422 {Name: "f1", Number: 1, Cardinality: pref.Repeated, Kind: pref.BoolKind},
423 {Name: "f2", Number: 2, Cardinality: pref.Repeated, Kind: pref.Int32Kind},
424 {Name: "f3", Number: 3, Cardinality: pref.Repeated, Kind: pref.Int64Kind},
425 {Name: "f4", Number: 4, Cardinality: pref.Repeated, Kind: pref.Uint32Kind},
426 {Name: "f5", Number: 5, Cardinality: pref.Repeated, Kind: pref.Uint64Kind},
427 {Name: "f6", Number: 6, Cardinality: pref.Repeated, Kind: pref.FloatKind},
428 {Name: "f7", Number: 7, Cardinality: pref.Repeated, Kind: pref.DoubleKind},
429 {Name: "f8", Number: 8, Cardinality: pref.Repeated, Kind: pref.StringKind},
430 {Name: "f9", Number: 9, Cardinality: pref.Repeated, Kind: pref.StringKind},
431 {Name: "f10", Number: 10, Cardinality: pref.Repeated, Kind: pref.BytesKind},
432 {Name: "f11", Number: 11, Cardinality: pref.Repeated, Kind: pref.BytesKind},
Joe Tsaifa02f4e2018-09-12 16:20:37 -0700433
Joe Tsai91e14662018-09-13 13:24:35 -0700434 {Name: "f12", Number: 12, Cardinality: pref.Repeated, Kind: pref.StringKind},
435 {Name: "f13", Number: 13, Cardinality: pref.Repeated, Kind: pref.StringKind},
436 {Name: "f14", Number: 14, Cardinality: pref.Repeated, Kind: pref.BytesKind},
437 {Name: "f15", Number: 15, Cardinality: pref.Repeated, Kind: pref.BytesKind},
438
439 {Name: "f16", Number: 16, Cardinality: pref.Repeated, Kind: pref.StringKind},
440 {Name: "f17", Number: 17, Cardinality: pref.Repeated, Kind: pref.StringKind},
441 {Name: "f18", Number: 18, Cardinality: pref.Repeated, Kind: pref.BytesKind},
442 {Name: "f19", Number: 19, Cardinality: pref.Repeated, Kind: pref.BytesKind},
Joe Tsaifa02f4e2018-09-12 16:20:37 -0700443 },
Joe Tsaif0c01e42018-11-06 13:05:20 -0800444 }),
445 func(pref.MessageType) pref.ProtoMessage {
446 return new(ListScalars)
447 },
448)}
Joe Tsai91e14662018-09-13 13:24:35 -0700449
Joe Tsaif0c01e42018-11-06 13:05:20 -0800450func (m *ListScalars) Type() pref.MessageType { return listScalarsType.Type }
451func (m *ListScalars) KnownFields() pref.KnownFields { return listScalarsType.KnownFieldsOf(m) }
452func (m *ListScalars) UnknownFields() pref.UnknownFields { return listScalarsType.UnknownFieldsOf(m) }
453func (m *ListScalars) Interface() pref.ProtoMessage { return m }
454func (m *ListScalars) ProtoReflect() pref.Message { return m }
Joe Tsaif0c01e42018-11-06 13:05:20 -0800455
456func TestListScalars(t *testing.T) {
457 empty := &ListScalars{}
Joe Tsai91e14662018-09-13 13:24:35 -0700458 emptyFS := empty.KnownFields()
459
Joe Tsaif0c01e42018-11-06 13:05:20 -0800460 want := &ListScalars{
Joe Tsai91e14662018-09-13 13:24:35 -0700461 Bools: []bool{true, false, true},
462 Int32s: []int32{2, math.MinInt32, math.MaxInt32},
463 Int64s: []int64{3, math.MinInt64, math.MaxInt64},
464 Uint32s: []uint32{4, math.MaxUint32 / 2, math.MaxUint32},
465 Uint64s: []uint64{5, math.MaxUint64 / 2, math.MaxUint64},
466 Float32s: []float32{6, math.SmallestNonzeroFloat32, float32(math.NaN()), math.MaxFloat32},
467 Float64s: []float64{7, math.SmallestNonzeroFloat64, float64(math.NaN()), math.MaxFloat64},
468 Strings: []string{"8", "", "eight"},
469 StringsA: [][]byte{[]byte("9"), nil, []byte("nine")},
470 Bytes: [][]byte{[]byte("10"), nil, []byte("ten")},
471 BytesA: []string{"11", "", "eleven"},
472
473 MyStrings1: []MyString{"12", "", "twelve"},
474 MyStrings2: []MyBytes{[]byte("13"), nil, []byte("thirteen")},
475 MyBytes1: []MyBytes{[]byte("14"), nil, []byte("fourteen")},
476 MyBytes2: []MyString{"15", "", "fifteen"},
477
Joe Tsai4b7aff62018-11-14 14:05:19 -0800478 MyStrings3: ListStrings{"16", "", "sixteen"},
479 MyStrings4: ListBytes{[]byte("17"), nil, []byte("seventeen")},
480 MyBytes3: ListBytes{[]byte("18"), nil, []byte("eighteen")},
481 MyBytes4: ListStrings{"19", "", "nineteen"},
Joe Tsaif0c01e42018-11-06 13:05:20 -0800482 }
Joe Tsai91e14662018-09-13 13:24:35 -0700483 wantFS := want.KnownFields()
484
Joe Tsaif0c01e42018-11-06 13:05:20 -0800485 testMessage(t, nil, &ListScalars{}, messageOps{
Joe Tsai91e14662018-09-13 13:24:35 -0700486 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},
487 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)},
488 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 -0800489 listFields{
Joe Tsai91e14662018-09-13 13:24:35 -0700490 2: {
Joe Tsai4b7aff62018-11-14 14:05:19 -0800491 lenList(0),
492 appendList{V(int32(2)), V(int32(math.MinInt32)), V(int32(math.MaxInt32))},
493 getList{0: V(int32(2)), 1: V(int32(math.MinInt32)), 2: V(int32(math.MaxInt32))},
Joe Tsai87b955b2018-11-14 21:59:49 -0800494 equalList{wantFS.Get(2).List()},
Joe Tsai91e14662018-09-13 13:24:35 -0700495 },
496 4: {
Joe Tsai4b7aff62018-11-14 14:05:19 -0800497 appendList{V(uint32(0)), V(uint32(0)), V(uint32(0))},
498 setList{0: V(uint32(4)), 1: V(uint32(math.MaxUint32 / 2)), 2: V(uint32(math.MaxUint32))},
499 lenList(3),
Joe Tsai91e14662018-09-13 13:24:35 -0700500 },
501 6: {
Joe Tsai4b7aff62018-11-14 14:05:19 -0800502 appendList{V(float32(6)), V(float32(math.SmallestNonzeroFloat32)), V(float32(math.NaN())), V(float32(math.MaxFloat32))},
Joe Tsai87b955b2018-11-14 21:59:49 -0800503 equalList{wantFS.Get(6).List()},
Joe Tsai91e14662018-09-13 13:24:35 -0700504 },
505 8: {
Joe Tsai4b7aff62018-11-14 14:05:19 -0800506 appendList{V(""), V(""), V(""), V(""), V(""), V("")},
507 lenList(6),
508 setList{0: V("8"), 2: V("eight")},
509 truncList(3),
Joe Tsai87b955b2018-11-14 21:59:49 -0800510 equalList{wantFS.Get(8).List()},
Joe Tsai91e14662018-09-13 13:24:35 -0700511 },
512 10: {
Joe Tsai4b7aff62018-11-14 14:05:19 -0800513 appendList{V([]byte(nil)), V([]byte(nil))},
514 setList{0: V([]byte("10"))},
515 appendList{V([]byte("wrong"))},
516 setList{2: V([]byte("ten"))},
Joe Tsai87b955b2018-11-14 21:59:49 -0800517 equalList{wantFS.Get(10).List()},
Joe Tsai91e14662018-09-13 13:24:35 -0700518 },
519 12: {
Joe Tsai4b7aff62018-11-14 14:05:19 -0800520 appendList{V("12"), V("wrong"), V("twelve")},
521 setList{1: V("")},
Joe Tsai87b955b2018-11-14 21:59:49 -0800522 equalList{wantFS.Get(12).List()},
Joe Tsai91e14662018-09-13 13:24:35 -0700523 },
524 14: {
Joe Tsai4b7aff62018-11-14 14:05:19 -0800525 appendList{V([]byte("14")), V([]byte(nil)), V([]byte("fourteen"))},
Joe Tsai87b955b2018-11-14 21:59:49 -0800526 equalList{wantFS.Get(14).List()},
Joe Tsai91e14662018-09-13 13:24:35 -0700527 },
528 16: {
Joe Tsai4b7aff62018-11-14 14:05:19 -0800529 appendList{V("16"), V(""), V("sixteen"), V("extra")},
530 truncList(3),
Joe Tsai87b955b2018-11-14 21:59:49 -0800531 equalList{wantFS.Get(16).List()},
Joe Tsai91e14662018-09-13 13:24:35 -0700532 },
533 18: {
Joe Tsai4b7aff62018-11-14 14:05:19 -0800534 appendList{V([]byte("18")), V([]byte(nil)), V([]byte("eighteen"))},
Joe Tsai87b955b2018-11-14 21:59:49 -0800535 equalList{wantFS.Get(18).List()},
Joe Tsai91e14662018-09-13 13:24:35 -0700536 },
Joe Tsaifa02f4e2018-09-12 16:20:37 -0700537 },
Joe Tsai91e14662018-09-13 13:24:35 -0700538 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 -0800539 equalMessage{want},
540 clearFields{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19},
541 equalMessage{empty},
Joe Tsaibbfaeb72018-10-17 00:27:21 +0000542 })
Joe Tsai6cf80c42018-12-01 04:57:09 -0800543
544 // Test read-only operations on nil message.
545 testMessage(t, nil, (*ListScalars)(nil), messageOps{
546 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},
547 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)}},
548 })
Joe Tsaibbfaeb72018-10-17 00:27:21 +0000549}
550
Joe Tsaice6edd32018-10-19 16:27:46 -0700551type MapScalars struct {
552 KeyBools map[bool]string `protobuf:"1"`
553 KeyInt32s map[int32]string `protobuf:"2"`
554 KeyInt64s map[int64]string `protobuf:"3"`
555 KeyUint32s map[uint32]string `protobuf:"4"`
556 KeyUint64s map[uint64]string `protobuf:"5"`
557 KeyStrings map[string]string `protobuf:"6"`
558
559 ValBools map[string]bool `protobuf:"7"`
560 ValInt32s map[string]int32 `protobuf:"8"`
561 ValInt64s map[string]int64 `protobuf:"9"`
562 ValUint32s map[string]uint32 `protobuf:"10"`
563 ValUint64s map[string]uint64 `protobuf:"11"`
564 ValFloat32s map[string]float32 `protobuf:"12"`
565 ValFloat64s map[string]float64 `protobuf:"13"`
566 ValStrings map[string]string `protobuf:"14"`
567 ValStringsA map[string][]byte `protobuf:"15"`
568 ValBytes map[string][]byte `protobuf:"16"`
569 ValBytesA map[string]string `protobuf:"17"`
570
571 MyStrings1 map[MyString]MyString `protobuf:"18"`
572 MyStrings2 map[MyString]MyBytes `protobuf:"19"`
573 MyBytes1 map[MyString]MyBytes `protobuf:"20"`
574 MyBytes2 map[MyString]MyString `protobuf:"21"`
575
576 MyStrings3 MapStrings `protobuf:"22"`
577 MyStrings4 MapBytes `protobuf:"23"`
578 MyBytes3 MapBytes `protobuf:"24"`
579 MyBytes4 MapStrings `protobuf:"25"`
580}
581
Joe Tsaif0c01e42018-11-06 13:05:20 -0800582func mustMakeMapEntry(n pref.FieldNumber, keyKind, valKind pref.Kind) ptype.Field {
583 return ptype.Field{
584 Name: pref.Name(fmt.Sprintf("f%d", n)),
585 Number: n,
586 Cardinality: pref.Repeated,
587 Kind: pref.MessageKind,
588 MessageType: mustMakeMessageDesc(ptype.StandaloneMessage{
589 Syntax: pref.Proto2,
590 FullName: pref.FullName(fmt.Sprintf("MapScalars.F%dEntry", n)),
591 Fields: []ptype.Field{
592 {Name: "key", Number: 1, Cardinality: pref.Optional, Kind: keyKind},
593 {Name: "value", Number: 2, Cardinality: pref.Optional, Kind: valKind},
594 },
Joe Tsai6cf80c42018-12-01 04:57:09 -0800595 Options: &descriptorpb.MessageOptions{MapEntry: scalar.Bool(true)},
Joe Tsaif0c01e42018-11-06 13:05:20 -0800596 }),
Joe Tsaibbfaeb72018-10-17 00:27:21 +0000597 }
Joe Tsaif0c01e42018-11-06 13:05:20 -0800598}
599
Joe Tsai08e00302018-11-26 22:32:06 -0800600var mapScalarsType = pimpl.MessageType{Type: ptype.GoMessage(
Joe Tsaif0c01e42018-11-06 13:05:20 -0800601 mustMakeMessageDesc(ptype.StandaloneMessage{
Joe Tsaibbfaeb72018-10-17 00:27:21 +0000602 Syntax: pref.Proto2,
603 FullName: "MapScalars",
604 Fields: []ptype.Field{
605 mustMakeMapEntry(1, pref.BoolKind, pref.StringKind),
606 mustMakeMapEntry(2, pref.Int32Kind, pref.StringKind),
607 mustMakeMapEntry(3, pref.Int64Kind, pref.StringKind),
608 mustMakeMapEntry(4, pref.Uint32Kind, pref.StringKind),
609 mustMakeMapEntry(5, pref.Uint64Kind, pref.StringKind),
610 mustMakeMapEntry(6, pref.StringKind, pref.StringKind),
611
612 mustMakeMapEntry(7, pref.StringKind, pref.BoolKind),
613 mustMakeMapEntry(8, pref.StringKind, pref.Int32Kind),
614 mustMakeMapEntry(9, pref.StringKind, pref.Int64Kind),
615 mustMakeMapEntry(10, pref.StringKind, pref.Uint32Kind),
616 mustMakeMapEntry(11, pref.StringKind, pref.Uint64Kind),
617 mustMakeMapEntry(12, pref.StringKind, pref.FloatKind),
618 mustMakeMapEntry(13, pref.StringKind, pref.DoubleKind),
619 mustMakeMapEntry(14, pref.StringKind, pref.StringKind),
620 mustMakeMapEntry(15, pref.StringKind, pref.StringKind),
621 mustMakeMapEntry(16, pref.StringKind, pref.BytesKind),
622 mustMakeMapEntry(17, pref.StringKind, pref.BytesKind),
623
624 mustMakeMapEntry(18, pref.StringKind, pref.StringKind),
625 mustMakeMapEntry(19, pref.StringKind, pref.StringKind),
626 mustMakeMapEntry(20, pref.StringKind, pref.BytesKind),
627 mustMakeMapEntry(21, pref.StringKind, pref.BytesKind),
628
629 mustMakeMapEntry(22, pref.StringKind, pref.StringKind),
630 mustMakeMapEntry(23, pref.StringKind, pref.StringKind),
631 mustMakeMapEntry(24, pref.StringKind, pref.BytesKind),
632 mustMakeMapEntry(25, pref.StringKind, pref.BytesKind),
633 },
Joe Tsaif0c01e42018-11-06 13:05:20 -0800634 }),
635 func(pref.MessageType) pref.ProtoMessage {
636 return new(MapScalars)
637 },
638)}
Joe Tsaibbfaeb72018-10-17 00:27:21 +0000639
Joe Tsaif0c01e42018-11-06 13:05:20 -0800640func (m *MapScalars) Type() pref.MessageType { return mapScalarsType.Type }
641func (m *MapScalars) KnownFields() pref.KnownFields { return mapScalarsType.KnownFieldsOf(m) }
642func (m *MapScalars) UnknownFields() pref.UnknownFields { return mapScalarsType.UnknownFieldsOf(m) }
643func (m *MapScalars) Interface() pref.ProtoMessage { return m }
644func (m *MapScalars) ProtoReflect() pref.Message { return m }
Joe Tsaif0c01e42018-11-06 13:05:20 -0800645
646func TestMapScalars(t *testing.T) {
647 empty := &MapScalars{}
Joe Tsaibbfaeb72018-10-17 00:27:21 +0000648 emptyFS := empty.KnownFields()
649
Joe Tsaif0c01e42018-11-06 13:05:20 -0800650 want := &MapScalars{
Joe Tsaibbfaeb72018-10-17 00:27:21 +0000651 KeyBools: map[bool]string{true: "true", false: "false"},
652 KeyInt32s: map[int32]string{0: "zero", -1: "one", 2: "two"},
653 KeyInt64s: map[int64]string{0: "zero", -10: "ten", 20: "twenty"},
654 KeyUint32s: map[uint32]string{0: "zero", 1: "one", 2: "two"},
655 KeyUint64s: map[uint64]string{0: "zero", 10: "ten", 20: "twenty"},
656 KeyStrings: map[string]string{"": "", "foo": "bar"},
657
658 ValBools: map[string]bool{"true": true, "false": false},
659 ValInt32s: map[string]int32{"one": 1, "two": 2, "three": 3},
660 ValInt64s: map[string]int64{"ten": 10, "twenty": -20, "thirty": 30},
661 ValUint32s: map[string]uint32{"0x00": 0x00, "0xff": 0xff, "0xdead": 0xdead},
662 ValUint64s: map[string]uint64{"0x00": 0x00, "0xff": 0xff, "0xdead": 0xdead},
663 ValFloat32s: map[string]float32{"nan": float32(math.NaN()), "pi": float32(math.Pi)},
664 ValFloat64s: map[string]float64{"nan": float64(math.NaN()), "pi": float64(math.Pi)},
665 ValStrings: map[string]string{"s1": "s1", "s2": "s2"},
666 ValStringsA: map[string][]byte{"s1": []byte("s1"), "s2": []byte("s2")},
667 ValBytes: map[string][]byte{"s1": []byte("s1"), "s2": []byte("s2")},
668 ValBytesA: map[string]string{"s1": "s1", "s2": "s2"},
669
670 MyStrings1: map[MyString]MyString{"s1": "s1", "s2": "s2"},
671 MyStrings2: map[MyString]MyBytes{"s1": []byte("s1"), "s2": []byte("s2")},
672 MyBytes1: map[MyString]MyBytes{"s1": []byte("s1"), "s2": []byte("s2")},
673 MyBytes2: map[MyString]MyString{"s1": "s1", "s2": "s2"},
674
675 MyStrings3: MapStrings{"s1": "s1", "s2": "s2"},
676 MyStrings4: MapBytes{"s1": []byte("s1"), "s2": []byte("s2")},
677 MyBytes3: MapBytes{"s1": []byte("s1"), "s2": []byte("s2")},
678 MyBytes4: MapStrings{"s1": "s1", "s2": "s2"},
Joe Tsaif0c01e42018-11-06 13:05:20 -0800679 }
Joe Tsaibbfaeb72018-10-17 00:27:21 +0000680 wantFS := want.KnownFields()
681
Joe Tsaif0c01e42018-11-06 13:05:20 -0800682 testMessage(t, nil, &MapScalars{}, messageOps{
Joe Tsaibbfaeb72018-10-17 00:27:21 +0000683 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},
684 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)},
685 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)},
686 mapFields{
687 2: {
688 lenMap(0),
689 hasMap{int32(0): false, int32(-1): false, int32(2): false},
690 setMap{int32(0): V("zero")},
691 lenMap(1),
692 hasMap{int32(0): true, int32(-1): false, int32(2): false},
693 setMap{int32(-1): V("one")},
694 lenMap(2),
695 hasMap{int32(0): true, int32(-1): true, int32(2): false},
696 setMap{int32(2): V("two")},
697 lenMap(3),
698 hasMap{int32(0): true, int32(-1): true, int32(2): true},
699 },
700 4: {
701 setMap{uint32(0): V("zero"), uint32(1): V("one"), uint32(2): V("two")},
Joe Tsai87b955b2018-11-14 21:59:49 -0800702 equalMap{wantFS.Get(4).Map()},
Joe Tsaibbfaeb72018-10-17 00:27:21 +0000703 },
704 6: {
Joe Tsai87b955b2018-11-14 21:59:49 -0800705 clearMap{"noexist"},
Joe Tsaibbfaeb72018-10-17 00:27:21 +0000706 setMap{"foo": V("bar")},
707 setMap{"": V("empty")},
708 getMap{"": V("empty"), "foo": V("bar"), "noexist": V(nil)},
709 setMap{"": V(""), "extra": V("extra")},
Joe Tsai87b955b2018-11-14 21:59:49 -0800710 clearMap{"extra", "noexist"},
Joe Tsaibbfaeb72018-10-17 00:27:21 +0000711 },
712 8: {
Joe Tsai87b955b2018-11-14 21:59:49 -0800713 equalMap{emptyFS.Get(8).Map()},
Joe Tsaibbfaeb72018-10-17 00:27:21 +0000714 setMap{"one": V(int32(1)), "two": V(int32(2)), "three": V(int32(3))},
715 },
716 10: {
717 setMap{"0x00": V(uint32(0x00)), "0xff": V(uint32(0xff)), "0xdead": V(uint32(0xdead))},
718 lenMap(3),
Joe Tsai87b955b2018-11-14 21:59:49 -0800719 equalMap{wantFS.Get(10).Map()},
Joe Tsaibbfaeb72018-10-17 00:27:21 +0000720 getMap{"0x00": V(uint32(0x00)), "0xff": V(uint32(0xff)), "0xdead": V(uint32(0xdead)), "0xdeadbeef": V(nil)},
721 },
722 12: {
723 setMap{"nan": V(float32(math.NaN())), "pi": V(float32(math.Pi)), "e": V(float32(math.E))},
Joe Tsai87b955b2018-11-14 21:59:49 -0800724 clearMap{"e", "phi"},
Joe Tsaibbfaeb72018-10-17 00:27:21 +0000725 rangeMap{"nan": V(float32(math.NaN())), "pi": V(float32(math.Pi))},
726 },
727 14: {
Joe Tsai87b955b2018-11-14 21:59:49 -0800728 equalMap{emptyFS.Get(14).Map()},
Joe Tsaibbfaeb72018-10-17 00:27:21 +0000729 setMap{"s1": V("s1"), "s2": V("s2")},
730 },
731 16: {
732 setMap{"s1": V([]byte("s1")), "s2": V([]byte("s2"))},
Joe Tsai87b955b2018-11-14 21:59:49 -0800733 equalMap{wantFS.Get(16).Map()},
Joe Tsaibbfaeb72018-10-17 00:27:21 +0000734 },
735 18: {
736 hasMap{"s1": false, "s2": false, "s3": false},
737 setMap{"s1": V("s1"), "s2": V("s2")},
738 hasMap{"s1": true, "s2": true, "s3": false},
739 },
740 20: {
Joe Tsai87b955b2018-11-14 21:59:49 -0800741 equalMap{emptyFS.Get(20).Map()},
Joe Tsaibbfaeb72018-10-17 00:27:21 +0000742 setMap{"s1": V([]byte("s1")), "s2": V([]byte("s2"))},
743 },
744 22: {
745 rangeMap{},
746 setMap{"s1": V("s1"), "s2": V("s2")},
747 rangeMap{"s1": V("s1"), "s2": V("s2")},
748 lenMap(2),
749 },
750 24: {
751 setMap{"s1": V([]byte("s1")), "s2": V([]byte("s2"))},
Joe Tsai87b955b2018-11-14 21:59:49 -0800752 equalMap{wantFS.Get(24).Map()},
Joe Tsaibbfaeb72018-10-17 00:27:21 +0000753 },
754 },
755 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 -0800756 equalMessage{want},
757 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},
758 equalMessage{empty},
Joe Tsai91e14662018-09-13 13:24:35 -0700759 })
Joe Tsai6cf80c42018-12-01 04:57:09 -0800760
761 // Test read-only operations on nil message.
762 testMessage(t, nil, (*MapScalars)(nil), messageOps{
763 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},
764 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)}},
765 })
Joe Tsai91e14662018-09-13 13:24:35 -0700766}
Joe Tsaifa02f4e2018-09-12 16:20:37 -0700767
Joe Tsai87b955b2018-11-14 21:59:49 -0800768type OneofScalars struct {
769 Union isOneofScalars_Union `protobuf_oneof:"union"`
770}
Joe Tsai2c870bb2018-10-17 11:46:52 -0700771
Joe Tsai08e00302018-11-26 22:32:06 -0800772var oneofScalarsType = pimpl.MessageType{Type: ptype.GoMessage(
Joe Tsaif0c01e42018-11-06 13:05:20 -0800773 mustMakeMessageDesc(ptype.StandaloneMessage{
774 Syntax: pref.Proto2,
Joe Tsai87b955b2018-11-14 21:59:49 -0800775 FullName: "OneofScalars",
Joe Tsaif0c01e42018-11-06 13:05:20 -0800776 Fields: []ptype.Field{
777 {Name: "f1", Number: 1, Cardinality: pref.Optional, Kind: pref.BoolKind, Default: V(bool(true)), OneofName: "union"},
778 {Name: "f2", Number: 2, Cardinality: pref.Optional, Kind: pref.Int32Kind, Default: V(int32(2)), OneofName: "union"},
779 {Name: "f3", Number: 3, Cardinality: pref.Optional, Kind: pref.Int64Kind, Default: V(int64(3)), OneofName: "union"},
780 {Name: "f4", Number: 4, Cardinality: pref.Optional, Kind: pref.Uint32Kind, Default: V(uint32(4)), OneofName: "union"},
781 {Name: "f5", Number: 5, Cardinality: pref.Optional, Kind: pref.Uint64Kind, Default: V(uint64(5)), OneofName: "union"},
782 {Name: "f6", Number: 6, Cardinality: pref.Optional, Kind: pref.FloatKind, Default: V(float32(6)), OneofName: "union"},
783 {Name: "f7", Number: 7, Cardinality: pref.Optional, Kind: pref.DoubleKind, Default: V(float64(7)), OneofName: "union"},
784 {Name: "f8", Number: 8, Cardinality: pref.Optional, Kind: pref.StringKind, Default: V(string("8")), OneofName: "union"},
785 {Name: "f9", Number: 9, Cardinality: pref.Optional, Kind: pref.StringKind, Default: V(string("9")), OneofName: "union"},
786 {Name: "f10", Number: 10, Cardinality: pref.Optional, Kind: pref.StringKind, Default: V(string("10")), OneofName: "union"},
787 {Name: "f11", Number: 11, Cardinality: pref.Optional, Kind: pref.BytesKind, Default: V([]byte("11")), OneofName: "union"},
788 {Name: "f12", Number: 12, Cardinality: pref.Optional, Kind: pref.BytesKind, Default: V([]byte("12")), OneofName: "union"},
789 {Name: "f13", Number: 13, Cardinality: pref.Optional, Kind: pref.BytesKind, Default: V([]byte("13")), OneofName: "union"},
790 },
791 Oneofs: []ptype.Oneof{{Name: "union"}},
792 }),
793 func(pref.MessageType) pref.ProtoMessage {
794 return new(OneofScalars)
795 },
796)}
797
798func (m *OneofScalars) Type() pref.MessageType { return oneofScalarsType.Type }
799func (m *OneofScalars) KnownFields() pref.KnownFields { return oneofScalarsType.KnownFieldsOf(m) }
800func (m *OneofScalars) UnknownFields() pref.UnknownFields { return oneofScalarsType.UnknownFieldsOf(m) }
801func (m *OneofScalars) Interface() pref.ProtoMessage { return m }
802func (m *OneofScalars) ProtoReflect() pref.Message { return m }
Joe Tsaif0c01e42018-11-06 13:05:20 -0800803
Joe Tsaif18ab532018-11-27 17:25:04 -0800804func (*OneofScalars) XXX_OneofWrappers() []interface{} {
805 return []interface{}{
Joe Tsai2c870bb2018-10-17 11:46:52 -0700806 (*OneofScalars_Bool)(nil),
807 (*OneofScalars_Int32)(nil),
808 (*OneofScalars_Int64)(nil),
809 (*OneofScalars_Uint32)(nil),
810 (*OneofScalars_Uint64)(nil),
811 (*OneofScalars_Float32)(nil),
812 (*OneofScalars_Float64)(nil),
813 (*OneofScalars_String)(nil),
814 (*OneofScalars_StringA)(nil),
815 (*OneofScalars_StringB)(nil),
816 (*OneofScalars_Bytes)(nil),
817 (*OneofScalars_BytesA)(nil),
818 (*OneofScalars_BytesB)(nil),
819 }
820}
821
Joe Tsai87b955b2018-11-14 21:59:49 -0800822type (
823 isOneofScalars_Union interface {
824 isOneofScalars_Union()
825 }
826 OneofScalars_Bool struct {
827 Bool bool `protobuf:"1"`
828 }
829 OneofScalars_Int32 struct {
830 Int32 MyInt32 `protobuf:"2"`
831 }
832 OneofScalars_Int64 struct {
833 Int64 int64 `protobuf:"3"`
834 }
835 OneofScalars_Uint32 struct {
836 Uint32 MyUint32 `protobuf:"4"`
837 }
838 OneofScalars_Uint64 struct {
839 Uint64 uint64 `protobuf:"5"`
840 }
841 OneofScalars_Float32 struct {
842 Float32 MyFloat32 `protobuf:"6"`
843 }
844 OneofScalars_Float64 struct {
845 Float64 float64 `protobuf:"7"`
846 }
847 OneofScalars_String struct {
848 String string `protobuf:"8"`
849 }
850 OneofScalars_StringA struct {
851 StringA []byte `protobuf:"9"`
852 }
853 OneofScalars_StringB struct {
854 StringB MyString `protobuf:"10"`
855 }
856 OneofScalars_Bytes struct {
857 Bytes []byte `protobuf:"11"`
858 }
859 OneofScalars_BytesA struct {
860 BytesA string `protobuf:"12"`
861 }
862 OneofScalars_BytesB struct {
863 BytesB MyBytes `protobuf:"13"`
864 }
865)
866
Joe Tsai2c870bb2018-10-17 11:46:52 -0700867func (*OneofScalars_Bool) isOneofScalars_Union() {}
868func (*OneofScalars_Int32) isOneofScalars_Union() {}
869func (*OneofScalars_Int64) isOneofScalars_Union() {}
870func (*OneofScalars_Uint32) isOneofScalars_Union() {}
871func (*OneofScalars_Uint64) isOneofScalars_Union() {}
872func (*OneofScalars_Float32) isOneofScalars_Union() {}
873func (*OneofScalars_Float64) isOneofScalars_Union() {}
874func (*OneofScalars_String) isOneofScalars_Union() {}
875func (*OneofScalars_StringA) isOneofScalars_Union() {}
876func (*OneofScalars_StringB) isOneofScalars_Union() {}
877func (*OneofScalars_Bytes) isOneofScalars_Union() {}
878func (*OneofScalars_BytesA) isOneofScalars_Union() {}
879func (*OneofScalars_BytesB) isOneofScalars_Union() {}
880
881func TestOneofs(t *testing.T) {
Joe Tsaif0c01e42018-11-06 13:05:20 -0800882 empty := &OneofScalars{}
883 want1 := &OneofScalars{Union: &OneofScalars_Bool{true}}
884 want2 := &OneofScalars{Union: &OneofScalars_Int32{20}}
885 want3 := &OneofScalars{Union: &OneofScalars_Int64{30}}
886 want4 := &OneofScalars{Union: &OneofScalars_Uint32{40}}
887 want5 := &OneofScalars{Union: &OneofScalars_Uint64{50}}
888 want6 := &OneofScalars{Union: &OneofScalars_Float32{60}}
889 want7 := &OneofScalars{Union: &OneofScalars_Float64{70}}
890 want8 := &OneofScalars{Union: &OneofScalars_String{string("80")}}
891 want9 := &OneofScalars{Union: &OneofScalars_StringA{[]byte("90")}}
892 want10 := &OneofScalars{Union: &OneofScalars_StringB{MyString("100")}}
893 want11 := &OneofScalars{Union: &OneofScalars_Bytes{[]byte("110")}}
894 want12 := &OneofScalars{Union: &OneofScalars_BytesA{string("120")}}
895 want13 := &OneofScalars{Union: &OneofScalars_BytesB{MyBytes("130")}}
Joe Tsai2c870bb2018-10-17 11:46:52 -0700896
Joe Tsaif0c01e42018-11-06 13:05:20 -0800897 testMessage(t, nil, &OneofScalars{}, messageOps{
Joe Tsai2c870bb2018-10-17 11:46:52 -0700898 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},
899 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"))},
900
Joe Tsai87b955b2018-11-14 21:59:49 -0800901 setFields{1: V(bool(true))}, hasFields{1: true}, equalMessage{want1},
902 setFields{2: V(int32(20))}, hasFields{2: true}, equalMessage{want2},
903 setFields{3: V(int64(30))}, hasFields{3: true}, equalMessage{want3},
904 setFields{4: V(uint32(40))}, hasFields{4: true}, equalMessage{want4},
905 setFields{5: V(uint64(50))}, hasFields{5: true}, equalMessage{want5},
906 setFields{6: V(float32(60))}, hasFields{6: true}, equalMessage{want6},
907 setFields{7: V(float64(70))}, hasFields{7: true}, equalMessage{want7},
908 setFields{8: V(string("80"))}, hasFields{8: true}, equalMessage{want8},
909 setFields{9: V(string("90"))}, hasFields{9: true}, equalMessage{want9},
910 setFields{10: V(string("100"))}, hasFields{10: true}, equalMessage{want10},
911 setFields{11: V([]byte("110"))}, hasFields{11: true}, equalMessage{want11},
912 setFields{12: V([]byte("120"))}, hasFields{12: true}, equalMessage{want12},
913 setFields{13: V([]byte("130"))}, hasFields{13: true}, equalMessage{want13},
Joe Tsai2c870bb2018-10-17 11:46:52 -0700914
915 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},
916 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 -0800917 clearFields{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12},
918 equalMessage{want13},
919 clearFields{13},
920 equalMessage{empty},
Joe Tsai2c870bb2018-10-17 11:46:52 -0700921 })
Joe Tsai6cf80c42018-12-01 04:57:09 -0800922
923 // Test read-only operations on nil message.
924 testMessage(t, nil, (*OneofScalars)(nil), messageOps{
925 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},
926 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"))},
927 })
Joe Tsai2c870bb2018-10-17 11:46:52 -0700928}
929
Joe Tsai87b955b2018-11-14 21:59:49 -0800930type EnumProto2 int32
931
932var enumProto2Type = ptype.GoEnum(
933 mustMakeEnumDesc(ptype.StandaloneEnum{
934 Syntax: pref.Proto2,
935 FullName: "EnumProto2",
936 Values: []ptype.EnumValue{{Name: "DEAD", Number: 0xdead}, {Name: "BEEF", Number: 0xbeef}},
937 }),
938 func(_ pref.EnumType, n pref.EnumNumber) pref.ProtoEnum {
939 return EnumProto2(n)
940 },
941)
942
943func (e EnumProto2) Enum() *EnumProto2 { return &e }
944func (e EnumProto2) Type() pref.EnumType { return enumProto2Type }
945func (e EnumProto2) Number() pref.EnumNumber { return pref.EnumNumber(e) }
946func (e EnumProto2) ProtoReflect() pref.Enum { return e }
947
948type EnumProto3 int32
949
950var enumProto3Type = ptype.GoEnum(
951 mustMakeEnumDesc(ptype.StandaloneEnum{
952 Syntax: pref.Proto3,
953 FullName: "EnumProto3",
954 Values: []ptype.EnumValue{{Name: "ALPHA", Number: 0}, {Name: "BRAVO", Number: 1}},
955 }),
956 func(_ pref.EnumType, n pref.EnumNumber) pref.ProtoEnum {
957 return EnumProto3(n)
958 },
959)
960
961func (e EnumProto3) Enum() *EnumProto3 { return &e }
962func (e EnumProto3) Type() pref.EnumType { return enumProto3Type }
963func (e EnumProto3) Number() pref.EnumNumber { return pref.EnumNumber(e) }
964func (e EnumProto3) ProtoReflect() pref.Enum { return e }
965
966type EnumMessages struct {
967 EnumP2 *EnumProto2 `protobuf:"1"`
968 EnumP3 *EnumProto3 `protobuf:"2"`
969 MessageLegacy *proto2_20180125.Message `protobuf:"3"`
970 MessageCycle *EnumMessages `protobuf:"4"`
971 EnumList []EnumProto2 `protobuf:"5"`
972 MessageList []*ScalarProto2 `protobuf:"6"`
973 EnumMap map[string]EnumProto3 `protobuf:"7"`
974 MessageMap map[string]*ScalarProto3 `protobuf:"8"`
975 Union isEnumMessages_Union `protobuf_oneof:"union"`
976}
977
Joe Tsai08e00302018-11-26 22:32:06 -0800978var enumMessagesType = pimpl.MessageType{Type: ptype.GoMessage(
Joe Tsai87b955b2018-11-14 21:59:49 -0800979 mustMakeMessageDesc(ptype.StandaloneMessage{
980 Syntax: pref.Proto2,
981 FullName: "EnumMessages",
982 Fields: []ptype.Field{
983 {Name: "f1", Number: 1, Cardinality: pref.Optional, Kind: pref.EnumKind, Default: V("BEEF"), EnumType: enumProto2Type},
984 {Name: "f2", Number: 2, Cardinality: pref.Optional, Kind: pref.EnumKind, Default: V("BRAVO"), EnumType: enumProto3Type},
Joe Tsai08e00302018-11-26 22:32:06 -0800985 {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 -0800986 {Name: "f4", Number: 4, Cardinality: pref.Optional, Kind: pref.MessageKind, MessageType: ptype.PlaceholderMessage("EnumMessages")},
987 {Name: "f5", Number: 5, Cardinality: pref.Repeated, Kind: pref.EnumKind, EnumType: enumProto2Type},
988 {Name: "f6", Number: 6, Cardinality: pref.Repeated, Kind: pref.MessageKind, MessageType: scalarProto2Type.Type},
989 {Name: "f7", Number: 7, Cardinality: pref.Repeated, Kind: pref.MessageKind, MessageType: enumMapDesc},
990 {Name: "f8", Number: 8, Cardinality: pref.Repeated, Kind: pref.MessageKind, MessageType: messageMapDesc},
991 {Name: "f9", Number: 9, Cardinality: pref.Optional, Kind: pref.EnumKind, Default: V("BEEF"), OneofName: "union", EnumType: enumProto2Type},
992 {Name: "f10", Number: 10, Cardinality: pref.Optional, Kind: pref.EnumKind, Default: V("BRAVO"), OneofName: "union", EnumType: enumProto3Type},
993 {Name: "f11", Number: 11, Cardinality: pref.Optional, Kind: pref.MessageKind, OneofName: "union", MessageType: scalarProto2Type.Type},
994 {Name: "f12", Number: 12, Cardinality: pref.Optional, Kind: pref.MessageKind, OneofName: "union", MessageType: scalarProto3Type.Type},
995 },
996 Oneofs: []ptype.Oneof{{Name: "union"}},
997 }),
998 func(pref.MessageType) pref.ProtoMessage {
999 return new(EnumMessages)
1000 },
1001)}
1002
1003var enumMapDesc = mustMakeMessageDesc(ptype.StandaloneMessage{
1004 Syntax: pref.Proto2,
1005 FullName: "EnumMessages.F7Entry",
1006 Fields: []ptype.Field{
1007 {Name: "key", Number: 1, Cardinality: pref.Optional, Kind: pref.StringKind},
1008 {Name: "value", Number: 2, Cardinality: pref.Optional, Kind: pref.EnumKind, EnumType: enumProto3Type},
1009 },
Joe Tsai6cf80c42018-12-01 04:57:09 -08001010 Options: &descriptorpb.MessageOptions{MapEntry: scalar.Bool(true)},
Joe Tsai87b955b2018-11-14 21:59:49 -08001011})
1012
1013var messageMapDesc = mustMakeMessageDesc(ptype.StandaloneMessage{
1014 Syntax: pref.Proto2,
1015 FullName: "EnumMessages.F8Entry",
1016 Fields: []ptype.Field{
1017 {Name: "key", Number: 1, Cardinality: pref.Optional, Kind: pref.StringKind},
1018 {Name: "value", Number: 2, Cardinality: pref.Optional, Kind: pref.MessageKind, MessageType: scalarProto3Type.Type},
1019 },
Joe Tsai6cf80c42018-12-01 04:57:09 -08001020 Options: &descriptorpb.MessageOptions{MapEntry: scalar.Bool(true)},
Joe Tsai87b955b2018-11-14 21:59:49 -08001021})
1022
1023func (m *EnumMessages) Type() pref.MessageType { return enumMessagesType.Type }
1024func (m *EnumMessages) KnownFields() pref.KnownFields { return enumMessagesType.KnownFieldsOf(m) }
1025func (m *EnumMessages) UnknownFields() pref.UnknownFields { return enumMessagesType.UnknownFieldsOf(m) }
1026func (m *EnumMessages) Interface() pref.ProtoMessage { return m }
1027func (m *EnumMessages) ProtoReflect() pref.Message { return m }
Joe Tsai87b955b2018-11-14 21:59:49 -08001028
Joe Tsaif18ab532018-11-27 17:25:04 -08001029func (*EnumMessages) XXX_OneofWrappers() []interface{} {
1030 return []interface{}{
Joe Tsai87b955b2018-11-14 21:59:49 -08001031 (*EnumMessages_OneofE2)(nil),
1032 (*EnumMessages_OneofE3)(nil),
1033 (*EnumMessages_OneofM2)(nil),
1034 (*EnumMessages_OneofM3)(nil),
1035 }
1036}
1037
1038type (
1039 isEnumMessages_Union interface {
1040 isEnumMessages_Union()
1041 }
1042 EnumMessages_OneofE2 struct {
1043 OneofE2 EnumProto2 `protobuf:"9"`
1044 }
1045 EnumMessages_OneofE3 struct {
1046 OneofE3 EnumProto3 `protobuf:"10"`
1047 }
1048 EnumMessages_OneofM2 struct {
1049 OneofM2 *ScalarProto2 `protobuf:"11"`
1050 }
1051 EnumMessages_OneofM3 struct {
1052 OneofM3 *ScalarProto3 `protobuf:"12"`
1053 }
1054)
1055
1056func (*EnumMessages_OneofE2) isEnumMessages_Union() {}
1057func (*EnumMessages_OneofE3) isEnumMessages_Union() {}
1058func (*EnumMessages_OneofM2) isEnumMessages_Union() {}
1059func (*EnumMessages_OneofM3) isEnumMessages_Union() {}
1060
1061func TestEnumMessages(t *testing.T) {
Joe Tsai08e00302018-11-26 22:32:06 -08001062 wantL := pimpl.Export{}.MessageOf(&proto2_20180125.Message{OptionalFloat: scalar.Float32(math.E)})
Joe Tsai87b955b2018-11-14 21:59:49 -08001063 wantM := &EnumMessages{EnumP2: EnumProto2(1234).Enum()}
Joe Tsai009e0672018-11-27 18:45:07 -08001064 wantM2a := &ScalarProto2{Float32: scalar.Float32(math.Pi)}
1065 wantM2b := &ScalarProto2{Float32: scalar.Float32(math.Phi)}
Joe Tsai87b955b2018-11-14 21:59:49 -08001066 wantM3a := &ScalarProto3{Float32: math.Pi}
1067 wantM3b := &ScalarProto3{Float32: math.Ln2}
1068
1069 wantList5 := (&EnumMessages{EnumList: []EnumProto2{333, 222}}).KnownFields().Get(5)
1070 wantList6 := (&EnumMessages{MessageList: []*ScalarProto2{wantM2a, wantM2b}}).KnownFields().Get(6)
1071
1072 wantMap7 := (&EnumMessages{EnumMap: map[string]EnumProto3{"one": 1, "two": 2}}).KnownFields().Get(7)
1073 wantMap8 := (&EnumMessages{MessageMap: map[string]*ScalarProto3{"pi": wantM3a, "ln2": wantM3b}}).KnownFields().Get(8)
1074
1075 testMessage(t, nil, &EnumMessages{}, messageOps{
1076 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 -08001077 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 -08001078
1079 // Test singular enums.
1080 setFields{1: VE(0xdead), 2: VE(0)},
1081 getFields{1: VE(0xdead), 2: VE(0)},
1082 hasFields{1: true, 2: true},
1083
1084 // Test singular messages.
1085 messageFields{3: messageOps{setFields{109: V(float32(math.E))}}},
1086 messageFields{4: messageOps{setFields{1: VE(1234)}}},
1087 getFields{3: V(wantL), 4: V(wantM)},
1088 clearFields{3, 4},
1089 hasFields{3: false, 4: false},
1090 setFields{3: V(wantL), 4: V(wantM)},
1091 hasFields{3: true, 4: true},
1092
1093 // Test list of enums and messages.
1094 listFields{
1095 5: listOps{
1096 appendList{VE(111), VE(222)},
1097 setList{0: VE(333)},
1098 getList{0: VE(333), 1: VE(222)},
1099 lenList(2),
1100 },
1101 6: listOps{
1102 appendMessageList{setFields{4: V(uint32(1e6))}},
1103 appendMessageList{setFields{6: V(float32(math.Phi))}},
1104 setList{0: V(wantM2a)},
1105 getList{0: V(wantM2a), 1: V(wantM2b)},
1106 },
1107 },
1108 getFields{5: wantList5, 6: wantList6},
1109 hasFields{5: true, 6: true},
1110 listFields{5: listOps{truncList(0)}},
1111 hasFields{5: false, 6: true},
1112
1113 // Test maps of enums and messages.
1114 mapFields{
1115 7: mapOps{
1116 setMap{"one": VE(1), "two": VE(2)},
1117 hasMap{"one": true, "two": true, "three": false},
1118 lenMap(2),
1119 },
1120 8: mapOps{
1121 messageMap{"pi": messageOps{setFields{6: V(float32(math.Pi))}}},
1122 setMap{"ln2": V(wantM3b)},
1123 getMap{"pi": V(wantM3a), "ln2": V(wantM3b), "none": V(nil)},
1124 lenMap(2),
1125 },
1126 },
1127 getFields{7: wantMap7, 8: wantMap8},
1128 hasFields{7: true, 8: true},
1129 mapFields{8: mapOps{clearMap{"pi", "ln2", "none"}}},
1130 hasFields{7: true, 8: false},
1131
1132 // Test oneofs of enums and messages.
1133 setFields{9: VE(0xdead)},
1134 hasFields{1: true, 2: true, 9: true, 10: false, 11: false, 12: false},
1135 setFields{10: VE(0)},
1136 hasFields{1: true, 2: true, 9: false, 10: true, 11: false, 12: false},
1137 messageFields{11: messageOps{setFields{6: V(float32(math.Pi))}}},
1138 getFields{11: V(wantM2a)},
1139 hasFields{1: true, 2: true, 9: false, 10: false, 11: true, 12: false},
1140 messageFields{12: messageOps{setFields{6: V(float32(math.Pi))}}},
1141 getFields{12: V(wantM3a)},
1142 hasFields{1: true, 2: true, 9: false, 10: false, 11: false, 12: true},
1143
1144 // Check entire message.
1145 rangeFields{1: VE(0xdead), 2: VE(0), 3: V(wantL), 4: V(wantM), 6: wantList6, 7: wantMap7, 12: V(wantM3a)},
1146 equalMessage{&EnumMessages{
1147 EnumP2: EnumProto2(0xdead).Enum(),
1148 EnumP3: EnumProto3(0).Enum(),
Joe Tsai009e0672018-11-27 18:45:07 -08001149 MessageLegacy: &proto2_20180125.Message{OptionalFloat: scalar.Float32(math.E)},
Joe Tsai87b955b2018-11-14 21:59:49 -08001150 MessageCycle: wantM,
1151 MessageList: []*ScalarProto2{wantM2a, wantM2b},
1152 EnumMap: map[string]EnumProto3{"one": 1, "two": 2},
1153 Union: &EnumMessages_OneofM3{wantM3a},
1154 }},
1155 clearFields{1, 2, 3, 4, 6, 7, 12},
1156 equalMessage{&EnumMessages{}},
1157 })
Joe Tsai6cf80c42018-12-01 04:57:09 -08001158
1159 // Test read-only operations on nil message.
1160 testMessage(t, nil, (*EnumMessages)(nil), messageOps{
1161 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},
1162 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)},
1163 listFields{5: {lenList(0)}, 6: {lenList(0)}},
1164 mapFields{7: {lenMap(0)}, 8: {lenMap(0)}},
1165 })
Joe Tsai87b955b2018-11-14 21:59:49 -08001166}
Joe Tsaifa02f4e2018-09-12 16:20:37 -07001167
Joe Tsai91e14662018-09-13 13:24:35 -07001168var cmpOpts = cmp.Options{
Joe Tsai87b955b2018-11-14 21:59:49 -08001169 cmp.Comparer(func(x, y *proto2_20180125.Message) bool {
1170 return protoV1.Equal(x, y)
Joe Tsai91e14662018-09-13 13:24:35 -07001171 }),
Joe Tsai87b955b2018-11-14 21:59:49 -08001172 cmp.Transformer("UnwrapValue", func(pv pref.Value) interface{} {
1173 return pv.Interface()
Joe Tsai91e14662018-09-13 13:24:35 -07001174 }),
Joe Tsai87b955b2018-11-14 21:59:49 -08001175 cmp.Transformer("UnwrapGeneric", func(x pvalue.Unwrapper) interface{} {
Joe Tsaiba0ef9a2018-11-29 14:54:05 -08001176 return x.ProtoUnwrap()
Joe Tsai91e14662018-09-13 13:24:35 -07001177 }),
1178 cmpopts.EquateNaNs(),
Joe Tsai87b955b2018-11-14 21:59:49 -08001179 cmpopts.EquateEmpty(),
Joe Tsai91e14662018-09-13 13:24:35 -07001180}
1181
1182func testMessage(t *testing.T, p path, m pref.Message, tt messageOps) {
1183 fs := m.KnownFields()
1184 for i, op := range tt {
1185 p.Push(i)
1186 switch op := op.(type) {
1187 case equalMessage:
Joe Tsai87b955b2018-11-14 21:59:49 -08001188 if diff := cmp.Diff(op.Message, m, cmpOpts); diff != "" {
Joe Tsai91e14662018-09-13 13:24:35 -07001189 t.Errorf("operation %v, message mismatch (-want, +got):\n%s", p, diff)
1190 }
1191 case hasFields:
1192 got := map[pref.FieldNumber]bool{}
1193 want := map[pref.FieldNumber]bool(op)
1194 for n := range want {
1195 got[n] = fs.Has(n)
1196 }
1197 if diff := cmp.Diff(want, got); diff != "" {
1198 t.Errorf("operation %v, KnownFields.Has mismatch (-want, +got):\n%s", p, diff)
1199 }
1200 case getFields:
1201 got := map[pref.FieldNumber]pref.Value{}
1202 want := map[pref.FieldNumber]pref.Value(op)
1203 for n := range want {
1204 got[n] = fs.Get(n)
1205 }
1206 if diff := cmp.Diff(want, got, cmpOpts); diff != "" {
1207 t.Errorf("operation %v, KnownFields.Get mismatch (-want, +got):\n%s", p, diff)
1208 }
1209 case setFields:
1210 for n, v := range op {
1211 fs.Set(n, v)
1212 }
1213 case clearFields:
Joe Tsai87b955b2018-11-14 21:59:49 -08001214 for _, n := range op {
1215 fs.Clear(n)
1216 }
1217 case messageFields:
1218 for n, tt := range op {
1219 p.Push(int(n))
Damien Neil97e7f572018-12-07 14:28:33 -08001220 if !fs.Has(n) {
1221 fs.Set(n, V(fs.NewMessage(n)))
1222 }
1223 testMessage(t, p, fs.Get(n).Message(), tt)
Joe Tsai87b955b2018-11-14 21:59:49 -08001224 p.Pop()
Joe Tsaifa02f4e2018-09-12 16:20:37 -07001225 }
Joe Tsai4b7aff62018-11-14 14:05:19 -08001226 case listFields:
Joe Tsai91e14662018-09-13 13:24:35 -07001227 for n, tt := range op {
1228 p.Push(int(n))
Joe Tsai6cf80c42018-12-01 04:57:09 -08001229 testLists(t, p, fs.Get(n).List(), tt)
Joe Tsai91e14662018-09-13 13:24:35 -07001230 p.Pop()
1231 }
Joe Tsaibbfaeb72018-10-17 00:27:21 +00001232 case mapFields:
1233 for n, tt := range op {
1234 p.Push(int(n))
Joe Tsai6cf80c42018-12-01 04:57:09 -08001235 testMaps(t, p, fs.Get(n).Map(), tt)
Joe Tsaibbfaeb72018-10-17 00:27:21 +00001236 p.Pop()
1237 }
Joe Tsai87b955b2018-11-14 21:59:49 -08001238 case rangeFields:
1239 got := map[pref.FieldNumber]pref.Value{}
1240 want := map[pref.FieldNumber]pref.Value(op)
1241 fs.Range(func(n pref.FieldNumber, v pref.Value) bool {
1242 got[n] = v
1243 return true
1244 })
1245 if diff := cmp.Diff(want, got, cmpOpts); diff != "" {
1246 t.Errorf("operation %v, KnownFields.Range mismatch (-want, +got):\n%s", p, diff)
1247 }
Joe Tsai91e14662018-09-13 13:24:35 -07001248 default:
1249 t.Fatalf("operation %v, invalid operation: %T", p, op)
1250 }
1251 p.Pop()
Joe Tsaifa02f4e2018-09-12 16:20:37 -07001252 }
1253}
Joe Tsai91e14662018-09-13 13:24:35 -07001254
Joe Tsai4b7aff62018-11-14 14:05:19 -08001255func testLists(t *testing.T, p path, v pref.List, tt listOps) {
Joe Tsai91e14662018-09-13 13:24:35 -07001256 for i, op := range tt {
1257 p.Push(i)
1258 switch op := op.(type) {
Joe Tsai4b7aff62018-11-14 14:05:19 -08001259 case equalList:
Joe Tsai87b955b2018-11-14 21:59:49 -08001260 if diff := cmp.Diff(op.List, v, cmpOpts); diff != "" {
Joe Tsai4b7aff62018-11-14 14:05:19 -08001261 t.Errorf("operation %v, list mismatch (-want, +got):\n%s", p, diff)
Joe Tsai91e14662018-09-13 13:24:35 -07001262 }
Joe Tsai4b7aff62018-11-14 14:05:19 -08001263 case lenList:
Joe Tsai91e14662018-09-13 13:24:35 -07001264 if got, want := v.Len(), int(op); got != want {
Joe Tsai4b7aff62018-11-14 14:05:19 -08001265 t.Errorf("operation %v, List.Len = %d, want %d", p, got, want)
Joe Tsai91e14662018-09-13 13:24:35 -07001266 }
Joe Tsai4b7aff62018-11-14 14:05:19 -08001267 case getList:
Joe Tsai91e14662018-09-13 13:24:35 -07001268 got := map[int]pref.Value{}
1269 want := map[int]pref.Value(op)
1270 for n := range want {
1271 got[n] = v.Get(n)
1272 }
1273 if diff := cmp.Diff(want, got, cmpOpts); diff != "" {
Joe Tsai4b7aff62018-11-14 14:05:19 -08001274 t.Errorf("operation %v, List.Get mismatch (-want, +got):\n%s", p, diff)
Joe Tsai91e14662018-09-13 13:24:35 -07001275 }
Joe Tsai4b7aff62018-11-14 14:05:19 -08001276 case setList:
Joe Tsai91e14662018-09-13 13:24:35 -07001277 for n, e := range op {
1278 v.Set(n, e)
1279 }
Joe Tsai4b7aff62018-11-14 14:05:19 -08001280 case appendList:
Joe Tsai91e14662018-09-13 13:24:35 -07001281 for _, e := range op {
1282 v.Append(e)
1283 }
Joe Tsai87b955b2018-11-14 21:59:49 -08001284 case appendMessageList:
Damien Neil97e7f572018-12-07 14:28:33 -08001285 m := v.NewMessage().ProtoReflect()
1286 v.Append(V(m))
1287 testMessage(t, p, m, messageOps(op))
Joe Tsai4b7aff62018-11-14 14:05:19 -08001288 case truncList:
Joe Tsai91e14662018-09-13 13:24:35 -07001289 v.Truncate(int(op))
1290 default:
1291 t.Fatalf("operation %v, invalid operation: %T", p, op)
1292 }
1293 p.Pop()
1294 }
1295}
1296
Joe Tsaibbfaeb72018-10-17 00:27:21 +00001297func testMaps(t *testing.T, p path, m pref.Map, tt mapOps) {
1298 for i, op := range tt {
1299 p.Push(i)
1300 switch op := op.(type) {
1301 case equalMap:
Joe Tsai87b955b2018-11-14 21:59:49 -08001302 if diff := cmp.Diff(op.Map, m, cmpOpts); diff != "" {
Joe Tsaibbfaeb72018-10-17 00:27:21 +00001303 t.Errorf("operation %v, map mismatch (-want, +got):\n%s", p, diff)
1304 }
1305 case lenMap:
1306 if got, want := m.Len(), int(op); got != want {
1307 t.Errorf("operation %v, Map.Len = %d, want %d", p, got, want)
1308 }
1309 case hasMap:
1310 got := map[interface{}]bool{}
1311 want := map[interface{}]bool(op)
1312 for k := range want {
1313 got[k] = m.Has(V(k).MapKey())
1314 }
1315 if diff := cmp.Diff(want, got, cmpOpts); diff != "" {
1316 t.Errorf("operation %v, Map.Has mismatch (-want, +got):\n%s", p, diff)
1317 }
1318 case getMap:
1319 got := map[interface{}]pref.Value{}
1320 want := map[interface{}]pref.Value(op)
1321 for k := range want {
1322 got[k] = m.Get(V(k).MapKey())
1323 }
1324 if diff := cmp.Diff(want, got, cmpOpts); diff != "" {
1325 t.Errorf("operation %v, Map.Get mismatch (-want, +got):\n%s", p, diff)
1326 }
1327 case setMap:
1328 for k, v := range op {
1329 m.Set(V(k).MapKey(), v)
1330 }
1331 case clearMap:
Joe Tsai87b955b2018-11-14 21:59:49 -08001332 for _, k := range op {
1333 m.Clear(V(k).MapKey())
1334 }
1335 case messageMap:
1336 for k, tt := range op {
Damien Neil97e7f572018-12-07 14:28:33 -08001337 mk := V(k).MapKey()
1338 if !m.Has(mk) {
1339 m.Set(mk, V(m.NewMessage()))
1340 }
1341 testMessage(t, p, m.Get(mk).Message(), tt)
Joe Tsaibbfaeb72018-10-17 00:27:21 +00001342 }
1343 case rangeMap:
1344 got := map[interface{}]pref.Value{}
1345 want := map[interface{}]pref.Value(op)
1346 m.Range(func(k pref.MapKey, v pref.Value) bool {
1347 got[k.Interface()] = v
1348 return true
1349 })
1350 if diff := cmp.Diff(want, got, cmpOpts); diff != "" {
1351 t.Errorf("operation %v, Map.Range mismatch (-want, +got):\n%s", p, diff)
1352 }
1353 default:
1354 t.Fatalf("operation %v, invalid operation: %T", p, op)
1355 }
1356 p.Pop()
1357 }
1358}
1359
Joe Tsai91e14662018-09-13 13:24:35 -07001360type path []int
1361
1362func (p *path) Push(i int) { *p = append(*p, i) }
1363func (p *path) Pop() { *p = (*p)[:len(*p)-1] }
1364func (p path) String() string {
1365 var ss []string
1366 for _, i := range p {
1367 ss = append(ss, fmt.Sprint(i))
1368 }
1369 return strings.Join(ss, ".")
1370}