blob: 66c25361fa6c174fdfbba78f3e36fb7bf0ff62ee [file] [log] [blame]
Joe Tsaifa02f4e2018-09-12 16:20:37 -07001// Copyright 2018 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
Joe Tsai08e00302018-11-26 22:32:06 -08005package impl_test
Joe Tsaifa02f4e2018-09-12 16:20:37 -07006
7import (
Joe Tsai91e14662018-09-13 13:24:35 -07008 "fmt"
9 "math"
Damien Neil8012b442019-01-18 09:32:24 -080010 "reflect"
Joe Tsai82760ce2019-06-20 03:09:57 -070011 "runtime"
Joe Tsai91e14662018-09-13 13:24:35 -070012 "strings"
Joe Tsai82760ce2019-06-20 03:09:57 -070013 "sync"
Joe Tsaifa02f4e2018-09-12 16:20:37 -070014 "testing"
15
Joe Tsai87b955b2018-11-14 21:59:49 -080016 cmp "github.com/google/go-cmp/cmp"
17 cmpopts "github.com/google/go-cmp/cmp/cmpopts"
Joe Tsaie0daf312020-02-25 12:51:10 -080018
Joe Tsaid8881392019-06-06 13:01:53 -070019 "google.golang.org/protobuf/encoding/prototext"
Damien Neile89e6242019-05-13 23:55:40 -070020 pimpl "google.golang.org/protobuf/internal/impl"
Joe Tsaid8881392019-06-06 13:01:53 -070021 "google.golang.org/protobuf/proto"
22 pdesc "google.golang.org/protobuf/reflect/protodesc"
Damien Neile89e6242019-05-13 23:55:40 -070023 pref "google.golang.org/protobuf/reflect/protoreflect"
Joe Tsaid8881392019-06-06 13:01:53 -070024 "google.golang.org/protobuf/reflect/protoregistry"
Joe Tsaifa02f4e2018-09-12 16:20:37 -070025
Joe Tsai55f18252020-01-11 00:25:01 -080026 proto2_20180125 "google.golang.org/protobuf/internal/testprotos/legacy/proto2_20180125_92554152"
Joe Tsai82760ce2019-06-20 03:09:57 -070027 testpb "google.golang.org/protobuf/internal/testprotos/test"
Joe Tsaia95b29f2019-05-16 12:47:20 -070028 "google.golang.org/protobuf/types/descriptorpb"
Joe Tsaifa02f4e2018-09-12 16:20:37 -070029)
30
Joe Tsai4b7aff62018-11-14 14:05:19 -080031// List of test operations to perform on messages, lists, or maps.
Joe Tsai91e14662018-09-13 13:24:35 -070032type (
Joe Tsai87b955b2018-11-14 21:59:49 -080033 messageOp interface{ isMessageOp() }
Joe Tsai91e14662018-09-13 13:24:35 -070034 messageOps []messageOp
Joe Tsaifa02f4e2018-09-12 16:20:37 -070035
Joe Tsai87b955b2018-11-14 21:59:49 -080036 listOp interface{ isListOp() }
Joe Tsai4b7aff62018-11-14 14:05:19 -080037 listOps []listOp
Joe Tsai91e14662018-09-13 13:24:35 -070038
Joe Tsai87b955b2018-11-14 21:59:49 -080039 mapOp interface{ isMapOp() }
Joe Tsaibbfaeb72018-10-17 00:27:21 +000040 mapOps []mapOp
Joe Tsai91e14662018-09-13 13:24:35 -070041)
42
43// Test operations performed on a message.
44type (
Joe Tsai87b955b2018-11-14 21:59:49 -080045 // check that the message contents match
46 equalMessage struct{ pref.Message }
47 // check presence for specific fields in the message
48 hasFields map[pref.FieldNumber]bool
49 // check that specific message fields match
50 getFields map[pref.FieldNumber]pref.Value
51 // set specific message fields
52 setFields map[pref.FieldNumber]pref.Value
53 // clear specific fields in the message
54 clearFields []pref.FieldNumber
Joe Tsai4ec39c72019-04-03 13:40:53 -070055 // check for the presence of specific oneof member fields.
56 whichOneofs map[pref.Name]pref.FieldNumber
Joe Tsai87b955b2018-11-14 21:59:49 -080057 // apply messageOps on each specified message field
Joe Tsai378c1322019-04-25 23:48:08 -070058 messageFields map[pref.FieldNumber]messageOps
59 messageFieldsMutable map[pref.FieldNumber]messageOps
Joe Tsai87b955b2018-11-14 21:59:49 -080060 // apply listOps on each specified list field
Joe Tsai378c1322019-04-25 23:48:08 -070061 listFields map[pref.FieldNumber]listOps
62 listFieldsMutable map[pref.FieldNumber]listOps
Joe Tsai87b955b2018-11-14 21:59:49 -080063 // apply mapOps on each specified map fields
Joe Tsai378c1322019-04-25 23:48:08 -070064 mapFields map[pref.FieldNumber]mapOps
65 mapFieldsMutable map[pref.FieldNumber]mapOps
Joe Tsai87b955b2018-11-14 21:59:49 -080066 // range through all fields and check that they match
67 rangeFields map[pref.FieldNumber]pref.Value
Joe Tsai91e14662018-09-13 13:24:35 -070068)
69
Joe Tsai378c1322019-04-25 23:48:08 -070070func (equalMessage) isMessageOp() {}
71func (hasFields) isMessageOp() {}
72func (getFields) isMessageOp() {}
73func (setFields) isMessageOp() {}
74func (clearFields) isMessageOp() {}
75func (whichOneofs) isMessageOp() {}
76func (messageFields) isMessageOp() {}
77func (messageFieldsMutable) isMessageOp() {}
78func (listFields) isMessageOp() {}
79func (listFieldsMutable) isMessageOp() {}
80func (mapFields) isMessageOp() {}
81func (mapFieldsMutable) isMessageOp() {}
82func (rangeFields) isMessageOp() {}
Joe Tsai87b955b2018-11-14 21:59:49 -080083
Joe Tsai4b7aff62018-11-14 14:05:19 -080084// Test operations performed on a list.
Joe Tsai91e14662018-09-13 13:24:35 -070085type (
Joe Tsai87b955b2018-11-14 21:59:49 -080086 // check that the list contents match
87 equalList struct{ pref.List }
88 // check that list length matches
89 lenList int
90 // check that specific list entries match
91 getList map[int]pref.Value
92 // set specific list entries
93 setList map[int]pref.Value
94 // append entries to the list
Joe Tsai4b7aff62018-11-14 14:05:19 -080095 appendList []pref.Value
Joe Tsai87b955b2018-11-14 21:59:49 -080096 // apply messageOps on a newly appended message
97 appendMessageList messageOps
98 // truncate the list to the specified length
99 truncList int
Joe Tsai91e14662018-09-13 13:24:35 -0700100)
101
Joe Tsai87b955b2018-11-14 21:59:49 -0800102func (equalList) isListOp() {}
103func (lenList) isListOp() {}
104func (getList) isListOp() {}
105func (setList) isListOp() {}
106func (appendList) isListOp() {}
107func (appendMessageList) isListOp() {}
108func (truncList) isListOp() {}
109
Joe Tsaibbfaeb72018-10-17 00:27:21 +0000110// Test operations performed on a map.
111type (
Joe Tsai87b955b2018-11-14 21:59:49 -0800112 // check that the map contents match
113 equalMap struct{ pref.Map }
114 // check that map length matches
115 lenMap int
116 // check presence for specific entries in the map
117 hasMap map[interface{}]bool
118 // check that specific map entries match
119 getMap map[interface{}]pref.Value
120 // set specific map entries
121 setMap map[interface{}]pref.Value
122 // clear specific entries in the map
123 clearMap []interface{}
124 // apply messageOps on each specified message entry
125 messageMap map[interface{}]messageOps
126 // range through all entries and check that they match
Joe Tsaibbfaeb72018-10-17 00:27:21 +0000127 rangeMap map[interface{}]pref.Value
Joe Tsaibbfaeb72018-10-17 00:27:21 +0000128)
129
Joe Tsai87b955b2018-11-14 21:59:49 -0800130func (equalMap) isMapOp() {}
131func (lenMap) isMapOp() {}
132func (hasMap) isMapOp() {}
133func (getMap) isMapOp() {}
134func (setMap) isMapOp() {}
135func (clearMap) isMapOp() {}
136func (messageMap) isMapOp() {}
137func (rangeMap) isMapOp() {}
138
Joe Tsaice6edd32018-10-19 16:27:46 -0700139type ScalarProto2 struct {
140 Bool *bool `protobuf:"1"`
141 Int32 *int32 `protobuf:"2"`
142 Int64 *int64 `protobuf:"3"`
143 Uint32 *uint32 `protobuf:"4"`
144 Uint64 *uint64 `protobuf:"5"`
145 Float32 *float32 `protobuf:"6"`
146 Float64 *float64 `protobuf:"7"`
147 String *string `protobuf:"8"`
148 StringA []byte `protobuf:"9"`
149 Bytes []byte `protobuf:"10"`
150 BytesA *string `protobuf:"11"`
151
152 MyBool *MyBool `protobuf:"12"`
153 MyInt32 *MyInt32 `protobuf:"13"`
154 MyInt64 *MyInt64 `protobuf:"14"`
155 MyUint32 *MyUint32 `protobuf:"15"`
156 MyUint64 *MyUint64 `protobuf:"16"`
157 MyFloat32 *MyFloat32 `protobuf:"17"`
158 MyFloat64 *MyFloat64 `protobuf:"18"`
159 MyString *MyString `protobuf:"19"`
160 MyStringA MyBytes `protobuf:"20"`
161 MyBytes MyBytes `protobuf:"21"`
162 MyBytesA *MyString `protobuf:"22"`
163}
164
Joe Tsaid8881392019-06-06 13:01:53 -0700165func mustMakeEnumDesc(path string, syntax pref.Syntax, enumDesc string) pref.EnumDescriptor {
166 s := fmt.Sprintf(`name:%q syntax:%q enum_type:[{%s}]`, path, syntax, enumDesc)
167 pb := new(descriptorpb.FileDescriptorProto)
168 if err := prototext.Unmarshal([]byte(s), pb); err != nil {
169 panic(err)
170 }
171 fd, err := pdesc.NewFile(pb, nil)
Joe Tsai87b955b2018-11-14 21:59:49 -0800172 if err != nil {
173 panic(err)
174 }
Joe Tsaid8881392019-06-06 13:01:53 -0700175 return fd.Enums().Get(0)
Joe Tsai87b955b2018-11-14 21:59:49 -0800176}
177
Joe Tsaid8881392019-06-06 13:01:53 -0700178func mustMakeMessageDesc(path string, syntax pref.Syntax, fileDesc, msgDesc string, r pdesc.Resolver) pref.MessageDescriptor {
179 s := fmt.Sprintf(`name:%q syntax:%q %s message_type:[{%s}]`, path, syntax, fileDesc, msgDesc)
180 pb := new(descriptorpb.FileDescriptorProto)
181 if err := prototext.Unmarshal([]byte(s), pb); err != nil {
182 panic(err)
183 }
184 fd, err := pdesc.NewFile(pb, r)
Joe Tsai87b955b2018-11-14 21:59:49 -0800185 if err != nil {
186 panic(err)
187 }
Joe Tsaid8881392019-06-06 13:01:53 -0700188 return fd.Messages().Get(0)
Joe Tsai87b955b2018-11-14 21:59:49 -0800189}
190
191var V = pref.ValueOf
192var VE = func(n pref.EnumNumber) pref.Value { return V(n) }
193
194type (
195 MyBool bool
196 MyInt32 int32
197 MyInt64 int64
198 MyUint32 uint32
199 MyUint64 uint64
200 MyFloat32 float32
201 MyFloat64 float64
202 MyString string
203 MyBytes []byte
204
205 ListStrings []MyString
206 ListBytes []MyBytes
207
208 MapStrings map[MyString]MyString
209 MapBytes map[MyString]MyBytes
210)
211
Damien Neil16163b42019-08-06 15:43:25 -0700212var scalarProto2Type = pimpl.MessageInfo{GoReflectType: reflect.TypeOf(new(ScalarProto2)), Desc: mustMakeMessageDesc("scalar2.proto", pref.Proto2, "", `
Joe Tsaid8881392019-06-06 13:01:53 -0700213 name: "ScalarProto2"
214 field: [
215 {name:"f1" number:1 label:LABEL_OPTIONAL type:TYPE_BOOL default_value:"true"},
216 {name:"f2" number:2 label:LABEL_OPTIONAL type:TYPE_INT32 default_value:"2"},
217 {name:"f3" number:3 label:LABEL_OPTIONAL type:TYPE_INT64 default_value:"3"},
218 {name:"f4" number:4 label:LABEL_OPTIONAL type:TYPE_UINT32 default_value:"4"},
219 {name:"f5" number:5 label:LABEL_OPTIONAL type:TYPE_UINT64 default_value:"5"},
220 {name:"f6" number:6 label:LABEL_OPTIONAL type:TYPE_FLOAT default_value:"6"},
221 {name:"f7" number:7 label:LABEL_OPTIONAL type:TYPE_DOUBLE default_value:"7"},
222 {name:"f8" number:8 label:LABEL_OPTIONAL type:TYPE_STRING default_value:"8"},
223 {name:"f9" number:9 label:LABEL_OPTIONAL type:TYPE_STRING default_value:"9"},
224 {name:"f10" number:10 label:LABEL_OPTIONAL type:TYPE_BYTES default_value:"10"},
225 {name:"f11" number:11 label:LABEL_OPTIONAL type:TYPE_BYTES default_value:"11"},
Joe Tsai91e14662018-09-13 13:24:35 -0700226
Joe Tsaid8881392019-06-06 13:01:53 -0700227 {name:"f12" number:12 label:LABEL_OPTIONAL type:TYPE_BOOL default_value:"true"},
228 {name:"f13" number:13 label:LABEL_OPTIONAL type:TYPE_INT32 default_value:"13"},
229 {name:"f14" number:14 label:LABEL_OPTIONAL type:TYPE_INT64 default_value:"14"},
230 {name:"f15" number:15 label:LABEL_OPTIONAL type:TYPE_UINT32 default_value:"15"},
231 {name:"f16" number:16 label:LABEL_OPTIONAL type:TYPE_UINT64 default_value:"16"},
232 {name:"f17" number:17 label:LABEL_OPTIONAL type:TYPE_FLOAT default_value:"17"},
233 {name:"f18" number:18 label:LABEL_OPTIONAL type:TYPE_DOUBLE default_value:"18"},
234 {name:"f19" number:19 label:LABEL_OPTIONAL type:TYPE_STRING default_value:"19"},
235 {name:"f20" number:20 label:LABEL_OPTIONAL type:TYPE_STRING default_value:"20"},
236 {name:"f21" number:21 label:LABEL_OPTIONAL type:TYPE_BYTES default_value:"21"},
237 {name:"f22" number:22 label:LABEL_OPTIONAL type:TYPE_BYTES default_value:"22"}
238 ]
239 `, nil),
Damien Neil16163b42019-08-06 15:43:25 -0700240}
Joe Tsai91e14662018-09-13 13:24:35 -0700241
Joe Tsai378c1322019-04-25 23:48:08 -0700242func (m *ScalarProto2) ProtoReflect() pref.Message { return scalarProto2Type.MessageOf(m) }
Joe Tsaif0c01e42018-11-06 13:05:20 -0800243
244func TestScalarProto2(t *testing.T) {
Joe Tsai378c1322019-04-25 23:48:08 -0700245 testMessage(t, nil, new(ScalarProto2).ProtoReflect(), messageOps{
Joe Tsai91e14662018-09-13 13:24:35 -0700246 hasFields{
247 1: false, 2: false, 3: false, 4: false, 5: false, 6: false, 7: false, 8: false, 9: false, 10: false, 11: false,
248 12: false, 13: false, 14: false, 15: false, 16: false, 17: false, 18: false, 19: false, 20: false, 21: false, 22: false,
249 },
250 getFields{
251 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")),
252 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")),
253 },
254 setFields{
255 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)),
256 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)),
257 },
258 hasFields{
259 1: true, 2: true, 3: true, 4: true, 5: true, 6: true, 7: true, 8: true, 9: true, 10: true, 11: true,
260 12: true, 13: true, 14: true, 15: true, 16: true, 17: true, 18: true, 19: true, 20: true, 21: true, 22: true,
261 },
Joe Tsai378c1322019-04-25 23:48:08 -0700262 equalMessage{(&ScalarProto2{
Joe Tsai91e14662018-09-13 13:24:35 -0700263 new(bool), new(int32), new(int64), new(uint32), new(uint64), new(float32), new(float64), new(string), []byte{}, []byte{}, new(string),
264 new(MyBool), new(MyInt32), new(MyInt64), new(MyUint32), new(MyUint64), new(MyFloat32), new(MyFloat64), new(MyString), MyBytes{}, MyBytes{}, new(MyString),
Joe Tsai378c1322019-04-25 23:48:08 -0700265 }).ProtoReflect()},
Joe Tsai87b955b2018-11-14 21:59:49 -0800266 clearFields{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22},
Joe Tsai378c1322019-04-25 23:48:08 -0700267 equalMessage{new(ScalarProto2).ProtoReflect()},
Joe Tsai3e6a39b2019-07-10 10:21:12 -0700268
269 // Setting a bytes field nil empty bytes should preserve presence.
270 setFields{10: V([]byte(nil)), 11: V([]byte(nil)), 21: V([]byte(nil)), 22: V([]byte(nil))},
271 getFields{10: V([]byte{}), 11: V([]byte(nil)), 21: V([]byte{}), 22: V([]byte(nil))},
272 hasFields{10: true, 11: true, 21: true, 22: true},
Joe Tsai91e14662018-09-13 13:24:35 -0700273 })
Joe Tsai6cf80c42018-12-01 04:57:09 -0800274
275 // Test read-only operations on nil message.
Joe Tsai378c1322019-04-25 23:48:08 -0700276 testMessage(t, nil, (*ScalarProto2)(nil).ProtoReflect(), messageOps{
Joe Tsai6cf80c42018-12-01 04:57:09 -0800277 hasFields{
278 1: false, 2: false, 3: false, 4: false, 5: false, 6: false, 7: false, 8: false, 9: false, 10: false, 11: false,
279 12: false, 13: false, 14: false, 15: false, 16: false, 17: false, 18: false, 19: false, 20: false, 21: false, 22: false,
280 },
281 getFields{
282 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")),
283 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")),
284 },
285 })
Joe Tsaifa02f4e2018-09-12 16:20:37 -0700286}
287
Joe Tsaice6edd32018-10-19 16:27:46 -0700288type ScalarProto3 struct {
289 Bool bool `protobuf:"1"`
290 Int32 int32 `protobuf:"2"`
291 Int64 int64 `protobuf:"3"`
292 Uint32 uint32 `protobuf:"4"`
293 Uint64 uint64 `protobuf:"5"`
294 Float32 float32 `protobuf:"6"`
295 Float64 float64 `protobuf:"7"`
296 String string `protobuf:"8"`
297 StringA []byte `protobuf:"9"`
298 Bytes []byte `protobuf:"10"`
299 BytesA string `protobuf:"11"`
300
301 MyBool MyBool `protobuf:"12"`
302 MyInt32 MyInt32 `protobuf:"13"`
303 MyInt64 MyInt64 `protobuf:"14"`
304 MyUint32 MyUint32 `protobuf:"15"`
305 MyUint64 MyUint64 `protobuf:"16"`
306 MyFloat32 MyFloat32 `protobuf:"17"`
307 MyFloat64 MyFloat64 `protobuf:"18"`
308 MyString MyString `protobuf:"19"`
309 MyStringA MyBytes `protobuf:"20"`
310 MyBytes MyBytes `protobuf:"21"`
311 MyBytesA MyString `protobuf:"22"`
312}
313
Damien Neil16163b42019-08-06 15:43:25 -0700314var scalarProto3Type = pimpl.MessageInfo{GoReflectType: reflect.TypeOf(new(ScalarProto3)), Desc: mustMakeMessageDesc("scalar3.proto", pref.Proto3, "", `
Joe Tsaid8881392019-06-06 13:01:53 -0700315 name: "ScalarProto3"
316 field: [
317 {name:"f1" number:1 label:LABEL_OPTIONAL type:TYPE_BOOL},
318 {name:"f2" number:2 label:LABEL_OPTIONAL type:TYPE_INT32},
319 {name:"f3" number:3 label:LABEL_OPTIONAL type:TYPE_INT64},
320 {name:"f4" number:4 label:LABEL_OPTIONAL type:TYPE_UINT32},
321 {name:"f5" number:5 label:LABEL_OPTIONAL type:TYPE_UINT64},
322 {name:"f6" number:6 label:LABEL_OPTIONAL type:TYPE_FLOAT},
323 {name:"f7" number:7 label:LABEL_OPTIONAL type:TYPE_DOUBLE},
324 {name:"f8" number:8 label:LABEL_OPTIONAL type:TYPE_STRING},
325 {name:"f9" number:9 label:LABEL_OPTIONAL type:TYPE_STRING},
326 {name:"f10" number:10 label:LABEL_OPTIONAL type:TYPE_BYTES},
327 {name:"f11" number:11 label:LABEL_OPTIONAL type:TYPE_BYTES},
Joe Tsaifa02f4e2018-09-12 16:20:37 -0700328
Joe Tsaid8881392019-06-06 13:01:53 -0700329 {name:"f12" number:12 label:LABEL_OPTIONAL type:TYPE_BOOL},
330 {name:"f13" number:13 label:LABEL_OPTIONAL type:TYPE_INT32},
331 {name:"f14" number:14 label:LABEL_OPTIONAL type:TYPE_INT64},
332 {name:"f15" number:15 label:LABEL_OPTIONAL type:TYPE_UINT32},
333 {name:"f16" number:16 label:LABEL_OPTIONAL type:TYPE_UINT64},
334 {name:"f17" number:17 label:LABEL_OPTIONAL type:TYPE_FLOAT},
335 {name:"f18" number:18 label:LABEL_OPTIONAL type:TYPE_DOUBLE},
336 {name:"f19" number:19 label:LABEL_OPTIONAL type:TYPE_STRING},
337 {name:"f20" number:20 label:LABEL_OPTIONAL type:TYPE_STRING},
338 {name:"f21" number:21 label:LABEL_OPTIONAL type:TYPE_BYTES},
339 {name:"f22" number:22 label:LABEL_OPTIONAL type:TYPE_BYTES}
340 ]
341 `, nil),
Damien Neil16163b42019-08-06 15:43:25 -0700342}
Joe Tsai91e14662018-09-13 13:24:35 -0700343
Joe Tsai378c1322019-04-25 23:48:08 -0700344func (m *ScalarProto3) ProtoReflect() pref.Message { return scalarProto3Type.MessageOf(m) }
Joe Tsaif0c01e42018-11-06 13:05:20 -0800345
346func TestScalarProto3(t *testing.T) {
Joe Tsai378c1322019-04-25 23:48:08 -0700347 testMessage(t, nil, new(ScalarProto3).ProtoReflect(), messageOps{
Joe Tsai91e14662018-09-13 13:24:35 -0700348 hasFields{
349 1: false, 2: false, 3: false, 4: false, 5: false, 6: false, 7: false, 8: false, 9: false, 10: false, 11: false,
350 12: false, 13: false, 14: false, 15: false, 16: false, 17: false, 18: false, 19: false, 20: false, 21: false, 22: false,
351 },
352 getFields{
353 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)),
354 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)),
355 },
356 setFields{
357 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)),
358 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)),
359 },
360 hasFields{
361 1: false, 2: false, 3: false, 4: false, 5: false, 6: false, 7: false, 8: false, 9: false, 10: false, 11: false,
362 12: false, 13: false, 14: false, 15: false, 16: false, 17: false, 18: false, 19: false, 20: false, 21: false, 22: false,
363 },
Joe Tsai378c1322019-04-25 23:48:08 -0700364 equalMessage{new(ScalarProto3).ProtoReflect()},
Joe Tsai91e14662018-09-13 13:24:35 -0700365 setFields{
366 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")),
367 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")),
368 },
369 hasFields{
370 1: true, 2: true, 3: true, 4: true, 5: true, 6: true, 7: true, 8: true, 9: true, 10: true, 11: true,
371 12: true, 13: true, 14: true, 15: true, 16: true, 17: true, 18: true, 19: true, 20: true, 21: true, 22: true,
372 },
Joe Tsai378c1322019-04-25 23:48:08 -0700373 equalMessage{(&ScalarProto3{
Joe Tsai91e14662018-09-13 13:24:35 -0700374 true, 2, 3, 4, 5, 6, 7, "8", []byte("9"), []byte("10"), "11",
375 true, 13, 14, 15, 16, 17, 18, "19", []byte("20"), []byte("21"), "22",
Joe Tsai378c1322019-04-25 23:48:08 -0700376 }).ProtoReflect()},
Joe Tsai44e389c2018-11-19 15:27:09 -0800377 setFields{
378 2: V(int32(-2)), 3: V(int64(-3)), 6: V(float32(math.Inf(-1))), 7: V(float64(math.NaN())),
379 },
380 hasFields{
381 2: true, 3: true, 6: true, 7: true,
382 },
Joe Tsai87b955b2018-11-14 21:59:49 -0800383 clearFields{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22},
Joe Tsai378c1322019-04-25 23:48:08 -0700384 equalMessage{new(ScalarProto3).ProtoReflect()},
Joe Tsai060cdac2019-04-22 11:44:49 -0700385
386 // Verify that -0 triggers proper Has behavior.
387 hasFields{6: false, 7: false},
388 setFields{6: V(float32(math.Copysign(0, -1))), 7: V(float64(math.Copysign(0, -1)))},
389 hasFields{6: true, 7: true},
Joe Tsai3e6a39b2019-07-10 10:21:12 -0700390
391 // Setting a bytes field to non-nil empty bytes should not preserve presence.
392 setFields{10: V([]byte{}), 11: V([]byte{}), 21: V([]byte{}), 22: V([]byte{})},
393 getFields{10: V([]byte(nil)), 11: V([]byte(nil)), 21: V([]byte(nil)), 22: V([]byte(nil))},
394 hasFields{10: false, 11: false, 21: false, 22: false},
Joe Tsai91e14662018-09-13 13:24:35 -0700395 })
Joe Tsai6cf80c42018-12-01 04:57:09 -0800396
397 // Test read-only operations on nil message.
Joe Tsai378c1322019-04-25 23:48:08 -0700398 testMessage(t, nil, (*ScalarProto3)(nil).ProtoReflect(), messageOps{
Joe Tsai6cf80c42018-12-01 04:57:09 -0800399 hasFields{
400 1: false, 2: false, 3: false, 4: false, 5: false, 6: false, 7: false, 8: false, 9: false, 10: false, 11: false,
401 12: false, 13: false, 14: false, 15: false, 16: false, 17: false, 18: false, 19: false, 20: false, 21: false, 22: false,
402 },
403 getFields{
404 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)),
405 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)),
406 },
407 })
Joe Tsaifa02f4e2018-09-12 16:20:37 -0700408}
409
Joe Tsaif0c01e42018-11-06 13:05:20 -0800410type ListScalars struct {
Joe Tsaice6edd32018-10-19 16:27:46 -0700411 Bools []bool `protobuf:"1"`
412 Int32s []int32 `protobuf:"2"`
413 Int64s []int64 `protobuf:"3"`
414 Uint32s []uint32 `protobuf:"4"`
415 Uint64s []uint64 `protobuf:"5"`
416 Float32s []float32 `protobuf:"6"`
417 Float64s []float64 `protobuf:"7"`
418 Strings []string `protobuf:"8"`
419 StringsA [][]byte `protobuf:"9"`
420 Bytes [][]byte `protobuf:"10"`
421 BytesA []string `protobuf:"11"`
422
423 MyStrings1 []MyString `protobuf:"12"`
424 MyStrings2 []MyBytes `protobuf:"13"`
425 MyBytes1 []MyBytes `protobuf:"14"`
426 MyBytes2 []MyString `protobuf:"15"`
427
Joe Tsai4b7aff62018-11-14 14:05:19 -0800428 MyStrings3 ListStrings `protobuf:"16"`
429 MyStrings4 ListBytes `protobuf:"17"`
430 MyBytes3 ListBytes `protobuf:"18"`
431 MyBytes4 ListStrings `protobuf:"19"`
Joe Tsaice6edd32018-10-19 16:27:46 -0700432}
433
Damien Neil16163b42019-08-06 15:43:25 -0700434var listScalarsType = pimpl.MessageInfo{GoReflectType: reflect.TypeOf(new(ListScalars)), Desc: mustMakeMessageDesc("list-scalars.proto", pref.Proto2, "", `
Joe Tsaid8881392019-06-06 13:01:53 -0700435 name: "ListScalars"
436 field: [
437 {name:"f1" number:1 label:LABEL_REPEATED type:TYPE_BOOL},
438 {name:"f2" number:2 label:LABEL_REPEATED type:TYPE_INT32},
439 {name:"f3" number:3 label:LABEL_REPEATED type:TYPE_INT64},
440 {name:"f4" number:4 label:LABEL_REPEATED type:TYPE_UINT32},
441 {name:"f5" number:5 label:LABEL_REPEATED type:TYPE_UINT64},
442 {name:"f6" number:6 label:LABEL_REPEATED type:TYPE_FLOAT},
443 {name:"f7" number:7 label:LABEL_REPEATED type:TYPE_DOUBLE},
444 {name:"f8" number:8 label:LABEL_REPEATED type:TYPE_STRING},
445 {name:"f9" number:9 label:LABEL_REPEATED type:TYPE_STRING},
446 {name:"f10" number:10 label:LABEL_REPEATED type:TYPE_BYTES},
447 {name:"f11" number:11 label:LABEL_REPEATED type:TYPE_BYTES},
Joe Tsaifa02f4e2018-09-12 16:20:37 -0700448
Joe Tsaid8881392019-06-06 13:01:53 -0700449 {name:"f12" number:12 label:LABEL_REPEATED type:TYPE_STRING},
450 {name:"f13" number:13 label:LABEL_REPEATED type:TYPE_STRING},
451 {name:"f14" number:14 label:LABEL_REPEATED type:TYPE_BYTES},
452 {name:"f15" number:15 label:LABEL_REPEATED type:TYPE_BYTES},
Joe Tsai91e14662018-09-13 13:24:35 -0700453
Joe Tsaid8881392019-06-06 13:01:53 -0700454 {name:"f16" number:16 label:LABEL_REPEATED type:TYPE_STRING},
455 {name:"f17" number:17 label:LABEL_REPEATED type:TYPE_STRING},
456 {name:"f18" number:18 label:LABEL_REPEATED type:TYPE_BYTES},
457 {name:"f19" number:19 label:LABEL_REPEATED type:TYPE_BYTES}
458 ]
459 `, nil),
Damien Neil16163b42019-08-06 15:43:25 -0700460}
Joe Tsai91e14662018-09-13 13:24:35 -0700461
Joe Tsai378c1322019-04-25 23:48:08 -0700462func (m *ListScalars) ProtoReflect() pref.Message { return listScalarsType.MessageOf(m) }
Joe Tsaif0c01e42018-11-06 13:05:20 -0800463
464func TestListScalars(t *testing.T) {
Joe Tsai378c1322019-04-25 23:48:08 -0700465 empty := new(ListScalars).ProtoReflect()
466 want := (&ListScalars{
Joe Tsai91e14662018-09-13 13:24:35 -0700467 Bools: []bool{true, false, true},
468 Int32s: []int32{2, math.MinInt32, math.MaxInt32},
469 Int64s: []int64{3, math.MinInt64, math.MaxInt64},
470 Uint32s: []uint32{4, math.MaxUint32 / 2, math.MaxUint32},
471 Uint64s: []uint64{5, math.MaxUint64 / 2, math.MaxUint64},
472 Float32s: []float32{6, math.SmallestNonzeroFloat32, float32(math.NaN()), math.MaxFloat32},
473 Float64s: []float64{7, math.SmallestNonzeroFloat64, float64(math.NaN()), math.MaxFloat64},
474 Strings: []string{"8", "", "eight"},
475 StringsA: [][]byte{[]byte("9"), nil, []byte("nine")},
476 Bytes: [][]byte{[]byte("10"), nil, []byte("ten")},
477 BytesA: []string{"11", "", "eleven"},
478
479 MyStrings1: []MyString{"12", "", "twelve"},
480 MyStrings2: []MyBytes{[]byte("13"), nil, []byte("thirteen")},
481 MyBytes1: []MyBytes{[]byte("14"), nil, []byte("fourteen")},
482 MyBytes2: []MyString{"15", "", "fifteen"},
483
Joe Tsai4b7aff62018-11-14 14:05:19 -0800484 MyStrings3: ListStrings{"16", "", "sixteen"},
485 MyStrings4: ListBytes{[]byte("17"), nil, []byte("seventeen")},
486 MyBytes3: ListBytes{[]byte("18"), nil, []byte("eighteen")},
487 MyBytes4: ListStrings{"19", "", "nineteen"},
Joe Tsai378c1322019-04-25 23:48:08 -0700488 }).ProtoReflect()
Joe Tsai91e14662018-09-13 13:24:35 -0700489
Joe Tsai378c1322019-04-25 23:48:08 -0700490 testMessage(t, nil, new(ListScalars).ProtoReflect(), messageOps{
Joe Tsai91e14662018-09-13 13:24:35 -0700491 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},
Joe Tsai378c1322019-04-25 23:48:08 -0700492 getFields{1: getField(empty, 1), 3: getField(empty, 3), 5: getField(empty, 5), 7: getField(empty, 7), 9: getField(empty, 9), 11: getField(empty, 11), 13: getField(empty, 13), 15: getField(empty, 15), 17: getField(empty, 17), 19: getField(empty, 19)},
493 setFields{1: getField(want, 1), 3: getField(want, 3), 5: getField(want, 5), 7: getField(want, 7), 9: getField(want, 9), 11: getField(want, 11), 13: getField(want, 13), 15: getField(want, 15), 17: getField(want, 17), 19: getField(want, 19)},
494 listFieldsMutable{
Joe Tsai91e14662018-09-13 13:24:35 -0700495 2: {
Joe Tsai4b7aff62018-11-14 14:05:19 -0800496 lenList(0),
497 appendList{V(int32(2)), V(int32(math.MinInt32)), V(int32(math.MaxInt32))},
498 getList{0: V(int32(2)), 1: V(int32(math.MinInt32)), 2: V(int32(math.MaxInt32))},
Joe Tsai378c1322019-04-25 23:48:08 -0700499 equalList{getField(want, 2).List()},
Joe Tsai91e14662018-09-13 13:24:35 -0700500 },
501 4: {
Joe Tsai4b7aff62018-11-14 14:05:19 -0800502 appendList{V(uint32(0)), V(uint32(0)), V(uint32(0))},
503 setList{0: V(uint32(4)), 1: V(uint32(math.MaxUint32 / 2)), 2: V(uint32(math.MaxUint32))},
504 lenList(3),
Joe Tsai91e14662018-09-13 13:24:35 -0700505 },
506 6: {
Joe Tsai4b7aff62018-11-14 14:05:19 -0800507 appendList{V(float32(6)), V(float32(math.SmallestNonzeroFloat32)), V(float32(math.NaN())), V(float32(math.MaxFloat32))},
Joe Tsai378c1322019-04-25 23:48:08 -0700508 equalList{getField(want, 6).List()},
Joe Tsai91e14662018-09-13 13:24:35 -0700509 },
510 8: {
Joe Tsai4b7aff62018-11-14 14:05:19 -0800511 appendList{V(""), V(""), V(""), V(""), V(""), V("")},
512 lenList(6),
513 setList{0: V("8"), 2: V("eight")},
514 truncList(3),
Joe Tsai378c1322019-04-25 23:48:08 -0700515 equalList{getField(want, 8).List()},
Joe Tsai91e14662018-09-13 13:24:35 -0700516 },
517 10: {
Joe Tsai4b7aff62018-11-14 14:05:19 -0800518 appendList{V([]byte(nil)), V([]byte(nil))},
519 setList{0: V([]byte("10"))},
520 appendList{V([]byte("wrong"))},
521 setList{2: V([]byte("ten"))},
Joe Tsai378c1322019-04-25 23:48:08 -0700522 equalList{getField(want, 10).List()},
Joe Tsai91e14662018-09-13 13:24:35 -0700523 },
524 12: {
Joe Tsai4b7aff62018-11-14 14:05:19 -0800525 appendList{V("12"), V("wrong"), V("twelve")},
526 setList{1: V("")},
Joe Tsai378c1322019-04-25 23:48:08 -0700527 equalList{getField(want, 12).List()},
Joe Tsai91e14662018-09-13 13:24:35 -0700528 },
529 14: {
Joe Tsai4b7aff62018-11-14 14:05:19 -0800530 appendList{V([]byte("14")), V([]byte(nil)), V([]byte("fourteen"))},
Joe Tsai378c1322019-04-25 23:48:08 -0700531 equalList{getField(want, 14).List()},
Joe Tsai91e14662018-09-13 13:24:35 -0700532 },
533 16: {
Joe Tsai4b7aff62018-11-14 14:05:19 -0800534 appendList{V("16"), V(""), V("sixteen"), V("extra")},
535 truncList(3),
Joe Tsai378c1322019-04-25 23:48:08 -0700536 equalList{getField(want, 16).List()},
Joe Tsai91e14662018-09-13 13:24:35 -0700537 },
538 18: {
Joe Tsai4b7aff62018-11-14 14:05:19 -0800539 appendList{V([]byte("18")), V([]byte(nil)), V([]byte("eighteen"))},
Joe Tsai378c1322019-04-25 23:48:08 -0700540 equalList{getField(want, 18).List()},
Joe Tsai91e14662018-09-13 13:24:35 -0700541 },
Joe Tsaifa02f4e2018-09-12 16:20:37 -0700542 },
Joe Tsai91e14662018-09-13 13:24:35 -0700543 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 -0800544 equalMessage{want},
545 clearFields{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19},
546 equalMessage{empty},
Joe Tsaibbfaeb72018-10-17 00:27:21 +0000547 })
Joe Tsai6cf80c42018-12-01 04:57:09 -0800548
549 // Test read-only operations on nil message.
Joe Tsai378c1322019-04-25 23:48:08 -0700550 testMessage(t, nil, (*ListScalars)(nil).ProtoReflect(), messageOps{
Joe Tsai6cf80c42018-12-01 04:57:09 -0800551 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},
552 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)}},
553 })
Joe Tsaibbfaeb72018-10-17 00:27:21 +0000554}
555
Joe Tsaice6edd32018-10-19 16:27:46 -0700556type MapScalars struct {
557 KeyBools map[bool]string `protobuf:"1"`
558 KeyInt32s map[int32]string `protobuf:"2"`
559 KeyInt64s map[int64]string `protobuf:"3"`
560 KeyUint32s map[uint32]string `protobuf:"4"`
561 KeyUint64s map[uint64]string `protobuf:"5"`
562 KeyStrings map[string]string `protobuf:"6"`
563
564 ValBools map[string]bool `protobuf:"7"`
565 ValInt32s map[string]int32 `protobuf:"8"`
566 ValInt64s map[string]int64 `protobuf:"9"`
567 ValUint32s map[string]uint32 `protobuf:"10"`
568 ValUint64s map[string]uint64 `protobuf:"11"`
569 ValFloat32s map[string]float32 `protobuf:"12"`
570 ValFloat64s map[string]float64 `protobuf:"13"`
571 ValStrings map[string]string `protobuf:"14"`
572 ValStringsA map[string][]byte `protobuf:"15"`
573 ValBytes map[string][]byte `protobuf:"16"`
574 ValBytesA map[string]string `protobuf:"17"`
575
576 MyStrings1 map[MyString]MyString `protobuf:"18"`
577 MyStrings2 map[MyString]MyBytes `protobuf:"19"`
578 MyBytes1 map[MyString]MyBytes `protobuf:"20"`
579 MyBytes2 map[MyString]MyString `protobuf:"21"`
580
581 MyStrings3 MapStrings `protobuf:"22"`
582 MyStrings4 MapBytes `protobuf:"23"`
583 MyBytes3 MapBytes `protobuf:"24"`
584 MyBytes4 MapStrings `protobuf:"25"`
585}
586
Damien Neil16163b42019-08-06 15:43:25 -0700587var mapScalarsType = pimpl.MessageInfo{GoReflectType: reflect.TypeOf(new(MapScalars)), Desc: mustMakeMessageDesc("map-scalars.proto", pref.Proto2, "", `
Joe Tsaid8881392019-06-06 13:01:53 -0700588 name: "MapScalars"
589 field: [
590 {name:"f1" number:1 label:LABEL_REPEATED type:TYPE_MESSAGE type_name:".MapScalars.F1Entry"},
591 {name:"f2" number:2 label:LABEL_REPEATED type:TYPE_MESSAGE type_name:".MapScalars.F2Entry"},
592 {name:"f3" number:3 label:LABEL_REPEATED type:TYPE_MESSAGE type_name:".MapScalars.F3Entry"},
593 {name:"f4" number:4 label:LABEL_REPEATED type:TYPE_MESSAGE type_name:".MapScalars.F4Entry"},
594 {name:"f5" number:5 label:LABEL_REPEATED type:TYPE_MESSAGE type_name:".MapScalars.F5Entry"},
595 {name:"f6" number:6 label:LABEL_REPEATED type:TYPE_MESSAGE type_name:".MapScalars.F6Entry"},
Joe Tsaibbfaeb72018-10-17 00:27:21 +0000596
Joe Tsaid8881392019-06-06 13:01:53 -0700597 {name:"f7" number:7 label:LABEL_REPEATED type:TYPE_MESSAGE type_name:".MapScalars.F7Entry"},
598 {name:"f8" number:8 label:LABEL_REPEATED type:TYPE_MESSAGE type_name:".MapScalars.F8Entry"},
599 {name:"f9" number:9 label:LABEL_REPEATED type:TYPE_MESSAGE type_name:".MapScalars.F9Entry"},
600 {name:"f10" number:10 label:LABEL_REPEATED type:TYPE_MESSAGE type_name:".MapScalars.F10Entry"},
601 {name:"f11" number:11 label:LABEL_REPEATED type:TYPE_MESSAGE type_name:".MapScalars.F11Entry"},
602 {name:"f12" number:12 label:LABEL_REPEATED type:TYPE_MESSAGE type_name:".MapScalars.F12Entry"},
603 {name:"f13" number:13 label:LABEL_REPEATED type:TYPE_MESSAGE type_name:".MapScalars.F13Entry"},
604 {name:"f14" number:14 label:LABEL_REPEATED type:TYPE_MESSAGE type_name:".MapScalars.F14Entry"},
605 {name:"f15" number:15 label:LABEL_REPEATED type:TYPE_MESSAGE type_name:".MapScalars.F15Entry"},
606 {name:"f16" number:16 label:LABEL_REPEATED type:TYPE_MESSAGE type_name:".MapScalars.F16Entry"},
607 {name:"f17" number:17 label:LABEL_REPEATED type:TYPE_MESSAGE type_name:".MapScalars.F17Entry"},
Joe Tsaibbfaeb72018-10-17 00:27:21 +0000608
Joe Tsaid8881392019-06-06 13:01:53 -0700609 {name:"f18" number:18 label:LABEL_REPEATED type:TYPE_MESSAGE type_name:".MapScalars.F18Entry"},
610 {name:"f19" number:19 label:LABEL_REPEATED type:TYPE_MESSAGE type_name:".MapScalars.F19Entry"},
611 {name:"f20" number:20 label:LABEL_REPEATED type:TYPE_MESSAGE type_name:".MapScalars.F20Entry"},
612 {name:"f21" number:21 label:LABEL_REPEATED type:TYPE_MESSAGE type_name:".MapScalars.F21Entry"},
Joe Tsaibbfaeb72018-10-17 00:27:21 +0000613
Joe Tsaid8881392019-06-06 13:01:53 -0700614 {name:"f22" number:22 label:LABEL_REPEATED type:TYPE_MESSAGE type_name:".MapScalars.F22Entry"},
615 {name:"f23" number:23 label:LABEL_REPEATED type:TYPE_MESSAGE type_name:".MapScalars.F23Entry"},
616 {name:"f24" number:24 label:LABEL_REPEATED type:TYPE_MESSAGE type_name:".MapScalars.F24Entry"},
617 {name:"f25" number:25 label:LABEL_REPEATED type:TYPE_MESSAGE type_name:".MapScalars.F25Entry"}
618 ]
619 nested_type: [
620 {name:"F1Entry" field:[{name:"key" number:1 label:LABEL_OPTIONAL type:TYPE_BOOL}, {name:"value" number:2 label:LABEL_OPTIONAL type:TYPE_STRING}] options:{map_entry:true}},
621 {name:"F2Entry" field:[{name:"key" number:1 label:LABEL_OPTIONAL type:TYPE_INT32}, {name:"value" number:2 label:LABEL_OPTIONAL type:TYPE_STRING}] options:{map_entry:true}},
622 {name:"F3Entry" field:[{name:"key" number:1 label:LABEL_OPTIONAL type:TYPE_INT64}, {name:"value" number:2 label:LABEL_OPTIONAL type:TYPE_STRING}] options:{map_entry:true}},
623 {name:"F4Entry" field:[{name:"key" number:1 label:LABEL_OPTIONAL type:TYPE_UINT32}, {name:"value" number:2 label:LABEL_OPTIONAL type:TYPE_STRING}] options:{map_entry:true}},
624 {name:"F5Entry" field:[{name:"key" number:1 label:LABEL_OPTIONAL type:TYPE_UINT64}, {name:"value" number:2 label:LABEL_OPTIONAL type:TYPE_STRING}] options:{map_entry:true}},
625 {name:"F6Entry" field:[{name:"key" number:1 label:LABEL_OPTIONAL type:TYPE_STRING}, {name:"value" number:2 label:LABEL_OPTIONAL type:TYPE_STRING}] options:{map_entry:true}},
626
627 {name:"F7Entry" field:[{name:"key" number:1 label:LABEL_OPTIONAL type:TYPE_STRING}, {name:"value" number:2 label:LABEL_OPTIONAL type:TYPE_BOOL}] options:{map_entry:true}},
628 {name:"F8Entry" field:[{name:"key" number:1 label:LABEL_OPTIONAL type:TYPE_STRING}, {name:"value" number:2 label:LABEL_OPTIONAL type:TYPE_INT32}] options:{map_entry:true}},
629 {name:"F9Entry" field:[{name:"key" number:1 label:LABEL_OPTIONAL type:TYPE_STRING}, {name:"value" number:2 label:LABEL_OPTIONAL type:TYPE_INT64}] options:{map_entry:true}},
630 {name:"F10Entry" field:[{name:"key" number:1 label:LABEL_OPTIONAL type:TYPE_STRING}, {name:"value" number:2 label:LABEL_OPTIONAL type:TYPE_UINT32}] options:{map_entry:true}},
631 {name:"F11Entry" field:[{name:"key" number:1 label:LABEL_OPTIONAL type:TYPE_STRING}, {name:"value" number:2 label:LABEL_OPTIONAL type:TYPE_UINT64}] options:{map_entry:true}},
632 {name:"F12Entry" field:[{name:"key" number:1 label:LABEL_OPTIONAL type:TYPE_STRING}, {name:"value" number:2 label:LABEL_OPTIONAL type:TYPE_FLOAT}] options:{map_entry:true}},
633 {name:"F13Entry" field:[{name:"key" number:1 label:LABEL_OPTIONAL type:TYPE_STRING}, {name:"value" number:2 label:LABEL_OPTIONAL type:TYPE_DOUBLE}] options:{map_entry:true}},
634 {name:"F14Entry" field:[{name:"key" number:1 label:LABEL_OPTIONAL type:TYPE_STRING}, {name:"value" number:2 label:LABEL_OPTIONAL type:TYPE_STRING}] options:{map_entry:true}},
635 {name:"F15Entry" field:[{name:"key" number:1 label:LABEL_OPTIONAL type:TYPE_STRING}, {name:"value" number:2 label:LABEL_OPTIONAL type:TYPE_STRING}] options:{map_entry:true}},
636 {name:"F16Entry" field:[{name:"key" number:1 label:LABEL_OPTIONAL type:TYPE_STRING}, {name:"value" number:2 label:LABEL_OPTIONAL type:TYPE_BYTES}] options:{map_entry:true}},
637 {name:"F17Entry" field:[{name:"key" number:1 label:LABEL_OPTIONAL type:TYPE_STRING}, {name:"value" number:2 label:LABEL_OPTIONAL type:TYPE_BYTES}] options:{map_entry:true}},
638
639 {name:"F18Entry" field:[{name:"key" number:1 label:LABEL_OPTIONAL type:TYPE_STRING}, {name:"value" number:2 label:LABEL_OPTIONAL type:TYPE_STRING}] options:{map_entry:true}},
640 {name:"F19Entry" field:[{name:"key" number:1 label:LABEL_OPTIONAL type:TYPE_STRING}, {name:"value" number:2 label:LABEL_OPTIONAL type:TYPE_STRING}] options:{map_entry:true}},
641 {name:"F20Entry" field:[{name:"key" number:1 label:LABEL_OPTIONAL type:TYPE_STRING}, {name:"value" number:2 label:LABEL_OPTIONAL type:TYPE_BYTES}] options:{map_entry:true}},
642 {name:"F21Entry" field:[{name:"key" number:1 label:LABEL_OPTIONAL type:TYPE_STRING}, {name:"value" number:2 label:LABEL_OPTIONAL type:TYPE_BYTES}] options:{map_entry:true}},
643
644 {name:"F22Entry" field:[{name:"key" number:1 label:LABEL_OPTIONAL type:TYPE_STRING}, {name:"value" number:2 label:LABEL_OPTIONAL type:TYPE_STRING}] options:{map_entry:true}},
645 {name:"F23Entry" field:[{name:"key" number:1 label:LABEL_OPTIONAL type:TYPE_STRING}, {name:"value" number:2 label:LABEL_OPTIONAL type:TYPE_STRING}] options:{map_entry:true}},
646 {name:"F24Entry" field:[{name:"key" number:1 label:LABEL_OPTIONAL type:TYPE_STRING}, {name:"value" number:2 label:LABEL_OPTIONAL type:TYPE_BYTES}] options:{map_entry:true}},
647 {name:"F25Entry" field:[{name:"key" number:1 label:LABEL_OPTIONAL type:TYPE_STRING}, {name:"value" number:2 label:LABEL_OPTIONAL type:TYPE_BYTES}] options:{map_entry:true}}
648 ]
649 `, nil),
Damien Neil16163b42019-08-06 15:43:25 -0700650}
Joe Tsaibbfaeb72018-10-17 00:27:21 +0000651
Joe Tsai378c1322019-04-25 23:48:08 -0700652func (m *MapScalars) ProtoReflect() pref.Message { return mapScalarsType.MessageOf(m) }
Joe Tsaif0c01e42018-11-06 13:05:20 -0800653
654func TestMapScalars(t *testing.T) {
Joe Tsai378c1322019-04-25 23:48:08 -0700655 empty := new(MapScalars).ProtoReflect()
656 want := (&MapScalars{
Joe Tsaibbfaeb72018-10-17 00:27:21 +0000657 KeyBools: map[bool]string{true: "true", false: "false"},
658 KeyInt32s: map[int32]string{0: "zero", -1: "one", 2: "two"},
659 KeyInt64s: map[int64]string{0: "zero", -10: "ten", 20: "twenty"},
660 KeyUint32s: map[uint32]string{0: "zero", 1: "one", 2: "two"},
661 KeyUint64s: map[uint64]string{0: "zero", 10: "ten", 20: "twenty"},
662 KeyStrings: map[string]string{"": "", "foo": "bar"},
663
664 ValBools: map[string]bool{"true": true, "false": false},
665 ValInt32s: map[string]int32{"one": 1, "two": 2, "three": 3},
666 ValInt64s: map[string]int64{"ten": 10, "twenty": -20, "thirty": 30},
667 ValUint32s: map[string]uint32{"0x00": 0x00, "0xff": 0xff, "0xdead": 0xdead},
668 ValUint64s: map[string]uint64{"0x00": 0x00, "0xff": 0xff, "0xdead": 0xdead},
669 ValFloat32s: map[string]float32{"nan": float32(math.NaN()), "pi": float32(math.Pi)},
670 ValFloat64s: map[string]float64{"nan": float64(math.NaN()), "pi": float64(math.Pi)},
671 ValStrings: map[string]string{"s1": "s1", "s2": "s2"},
672 ValStringsA: map[string][]byte{"s1": []byte("s1"), "s2": []byte("s2")},
673 ValBytes: map[string][]byte{"s1": []byte("s1"), "s2": []byte("s2")},
674 ValBytesA: map[string]string{"s1": "s1", "s2": "s2"},
675
676 MyStrings1: map[MyString]MyString{"s1": "s1", "s2": "s2"},
677 MyStrings2: map[MyString]MyBytes{"s1": []byte("s1"), "s2": []byte("s2")},
678 MyBytes1: map[MyString]MyBytes{"s1": []byte("s1"), "s2": []byte("s2")},
679 MyBytes2: map[MyString]MyString{"s1": "s1", "s2": "s2"},
680
681 MyStrings3: MapStrings{"s1": "s1", "s2": "s2"},
682 MyStrings4: MapBytes{"s1": []byte("s1"), "s2": []byte("s2")},
683 MyBytes3: MapBytes{"s1": []byte("s1"), "s2": []byte("s2")},
684 MyBytes4: MapStrings{"s1": "s1", "s2": "s2"},
Joe Tsai378c1322019-04-25 23:48:08 -0700685 }).ProtoReflect()
Joe Tsaibbfaeb72018-10-17 00:27:21 +0000686
Joe Tsai378c1322019-04-25 23:48:08 -0700687 testMessage(t, nil, new(MapScalars).ProtoReflect(), messageOps{
Joe Tsaibbfaeb72018-10-17 00:27:21 +0000688 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},
Joe Tsai378c1322019-04-25 23:48:08 -0700689 getFields{1: getField(empty, 1), 3: getField(empty, 3), 5: getField(empty, 5), 7: getField(empty, 7), 9: getField(empty, 9), 11: getField(empty, 11), 13: getField(empty, 13), 15: getField(empty, 15), 17: getField(empty, 17), 19: getField(empty, 19), 21: getField(empty, 21), 23: getField(empty, 23), 25: getField(empty, 25)},
690 setFields{1: getField(want, 1), 3: getField(want, 3), 5: getField(want, 5), 7: getField(want, 7), 9: getField(want, 9), 11: getField(want, 11), 13: getField(want, 13), 15: getField(want, 15), 17: getField(want, 17), 19: getField(want, 19), 21: getField(want, 21), 23: getField(want, 23), 25: getField(want, 25)},
691 mapFieldsMutable{
Joe Tsaibbfaeb72018-10-17 00:27:21 +0000692 2: {
693 lenMap(0),
694 hasMap{int32(0): false, int32(-1): false, int32(2): false},
695 setMap{int32(0): V("zero")},
696 lenMap(1),
697 hasMap{int32(0): true, int32(-1): false, int32(2): false},
698 setMap{int32(-1): V("one")},
699 lenMap(2),
700 hasMap{int32(0): true, int32(-1): true, int32(2): false},
701 setMap{int32(2): V("two")},
702 lenMap(3),
703 hasMap{int32(0): true, int32(-1): true, int32(2): true},
704 },
705 4: {
706 setMap{uint32(0): V("zero"), uint32(1): V("one"), uint32(2): V("two")},
Joe Tsai378c1322019-04-25 23:48:08 -0700707 equalMap{getField(want, 4).Map()},
Joe Tsaibbfaeb72018-10-17 00:27:21 +0000708 },
709 6: {
Joe Tsai87b955b2018-11-14 21:59:49 -0800710 clearMap{"noexist"},
Joe Tsaibbfaeb72018-10-17 00:27:21 +0000711 setMap{"foo": V("bar")},
712 setMap{"": V("empty")},
713 getMap{"": V("empty"), "foo": V("bar"), "noexist": V(nil)},
714 setMap{"": V(""), "extra": V("extra")},
Joe Tsai87b955b2018-11-14 21:59:49 -0800715 clearMap{"extra", "noexist"},
Joe Tsaibbfaeb72018-10-17 00:27:21 +0000716 },
717 8: {
Joe Tsai378c1322019-04-25 23:48:08 -0700718 equalMap{getField(empty, 8).Map()},
Joe Tsaibbfaeb72018-10-17 00:27:21 +0000719 setMap{"one": V(int32(1)), "two": V(int32(2)), "three": V(int32(3))},
720 },
721 10: {
722 setMap{"0x00": V(uint32(0x00)), "0xff": V(uint32(0xff)), "0xdead": V(uint32(0xdead))},
723 lenMap(3),
Joe Tsai378c1322019-04-25 23:48:08 -0700724 equalMap{getField(want, 10).Map()},
Joe Tsaibbfaeb72018-10-17 00:27:21 +0000725 getMap{"0x00": V(uint32(0x00)), "0xff": V(uint32(0xff)), "0xdead": V(uint32(0xdead)), "0xdeadbeef": V(nil)},
726 },
727 12: {
728 setMap{"nan": V(float32(math.NaN())), "pi": V(float32(math.Pi)), "e": V(float32(math.E))},
Joe Tsai87b955b2018-11-14 21:59:49 -0800729 clearMap{"e", "phi"},
Joe Tsaibbfaeb72018-10-17 00:27:21 +0000730 rangeMap{"nan": V(float32(math.NaN())), "pi": V(float32(math.Pi))},
731 },
732 14: {
Joe Tsai378c1322019-04-25 23:48:08 -0700733 equalMap{getField(empty, 14).Map()},
Joe Tsaibbfaeb72018-10-17 00:27:21 +0000734 setMap{"s1": V("s1"), "s2": V("s2")},
735 },
736 16: {
737 setMap{"s1": V([]byte("s1")), "s2": V([]byte("s2"))},
Joe Tsai378c1322019-04-25 23:48:08 -0700738 equalMap{getField(want, 16).Map()},
Joe Tsaibbfaeb72018-10-17 00:27:21 +0000739 },
740 18: {
741 hasMap{"s1": false, "s2": false, "s3": false},
742 setMap{"s1": V("s1"), "s2": V("s2")},
743 hasMap{"s1": true, "s2": true, "s3": false},
744 },
745 20: {
Joe Tsai378c1322019-04-25 23:48:08 -0700746 equalMap{getField(empty, 20).Map()},
Joe Tsaibbfaeb72018-10-17 00:27:21 +0000747 setMap{"s1": V([]byte("s1")), "s2": V([]byte("s2"))},
748 },
749 22: {
750 rangeMap{},
751 setMap{"s1": V("s1"), "s2": V("s2")},
752 rangeMap{"s1": V("s1"), "s2": V("s2")},
753 lenMap(2),
754 },
755 24: {
756 setMap{"s1": V([]byte("s1")), "s2": V([]byte("s2"))},
Joe Tsai378c1322019-04-25 23:48:08 -0700757 equalMap{getField(want, 24).Map()},
Joe Tsaibbfaeb72018-10-17 00:27:21 +0000758 },
759 },
760 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 -0800761 equalMessage{want},
762 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},
763 equalMessage{empty},
Joe Tsai91e14662018-09-13 13:24:35 -0700764 })
Joe Tsai6cf80c42018-12-01 04:57:09 -0800765
766 // Test read-only operations on nil message.
Joe Tsai378c1322019-04-25 23:48:08 -0700767 testMessage(t, nil, (*MapScalars)(nil).ProtoReflect(), messageOps{
Joe Tsai6cf80c42018-12-01 04:57:09 -0800768 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},
769 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)}},
770 })
Joe Tsai91e14662018-09-13 13:24:35 -0700771}
Joe Tsaifa02f4e2018-09-12 16:20:37 -0700772
Joe Tsai87b955b2018-11-14 21:59:49 -0800773type OneofScalars struct {
774 Union isOneofScalars_Union `protobuf_oneof:"union"`
775}
Joe Tsai2c870bb2018-10-17 11:46:52 -0700776
Damien Neil16163b42019-08-06 15:43:25 -0700777var oneofScalarsType = pimpl.MessageInfo{GoReflectType: reflect.TypeOf(new(OneofScalars)), Desc: mustMakeMessageDesc("oneof-scalars.proto", pref.Proto2, "", `
Joe Tsaid8881392019-06-06 13:01:53 -0700778 name: "OneofScalars"
779 field: [
780 {name:"f1" number:1 label:LABEL_OPTIONAL type:TYPE_BOOL default_value:"true" oneof_index:0},
781 {name:"f2" number:2 label:LABEL_OPTIONAL type:TYPE_INT32 default_value:"2" oneof_index:0},
782 {name:"f3" number:3 label:LABEL_OPTIONAL type:TYPE_INT64 default_value:"3" oneof_index:0},
783 {name:"f4" number:4 label:LABEL_OPTIONAL type:TYPE_UINT32 default_value:"4" oneof_index:0},
784 {name:"f5" number:5 label:LABEL_OPTIONAL type:TYPE_UINT64 default_value:"5" oneof_index:0},
785 {name:"f6" number:6 label:LABEL_OPTIONAL type:TYPE_FLOAT default_value:"6" oneof_index:0},
786 {name:"f7" number:7 label:LABEL_OPTIONAL type:TYPE_DOUBLE default_value:"7" oneof_index:0},
787 {name:"f8" number:8 label:LABEL_OPTIONAL type:TYPE_STRING default_value:"8" oneof_index:0},
788 {name:"f9" number:9 label:LABEL_OPTIONAL type:TYPE_STRING default_value:"9" oneof_index:0},
789 {name:"f10" number:10 label:LABEL_OPTIONAL type:TYPE_STRING default_value:"10" oneof_index:0},
790 {name:"f11" number:11 label:LABEL_OPTIONAL type:TYPE_BYTES default_value:"11" oneof_index:0},
791 {name:"f12" number:12 label:LABEL_OPTIONAL type:TYPE_BYTES default_value:"12" oneof_index:0},
792 {name:"f13" number:13 label:LABEL_OPTIONAL type:TYPE_BYTES default_value:"13" oneof_index:0}
793 ]
794 oneof_decl: [{name:"union"}]
795 `, nil),
Damien Neil16163b42019-08-06 15:43:25 -0700796}
Joe Tsaif0c01e42018-11-06 13:05:20 -0800797
Joe Tsai378c1322019-04-25 23:48:08 -0700798func (m *OneofScalars) ProtoReflect() pref.Message { return oneofScalarsType.MessageOf(m) }
Joe Tsaif0c01e42018-11-06 13:05:20 -0800799
Joe Tsaif18ab532018-11-27 17:25:04 -0800800func (*OneofScalars) XXX_OneofWrappers() []interface{} {
801 return []interface{}{
Joe Tsai2c870bb2018-10-17 11:46:52 -0700802 (*OneofScalars_Bool)(nil),
803 (*OneofScalars_Int32)(nil),
804 (*OneofScalars_Int64)(nil),
805 (*OneofScalars_Uint32)(nil),
806 (*OneofScalars_Uint64)(nil),
807 (*OneofScalars_Float32)(nil),
808 (*OneofScalars_Float64)(nil),
809 (*OneofScalars_String)(nil),
810 (*OneofScalars_StringA)(nil),
811 (*OneofScalars_StringB)(nil),
812 (*OneofScalars_Bytes)(nil),
813 (*OneofScalars_BytesA)(nil),
814 (*OneofScalars_BytesB)(nil),
815 }
816}
817
Joe Tsai87b955b2018-11-14 21:59:49 -0800818type (
819 isOneofScalars_Union interface {
820 isOneofScalars_Union()
821 }
822 OneofScalars_Bool struct {
823 Bool bool `protobuf:"1"`
824 }
825 OneofScalars_Int32 struct {
826 Int32 MyInt32 `protobuf:"2"`
827 }
828 OneofScalars_Int64 struct {
829 Int64 int64 `protobuf:"3"`
830 }
831 OneofScalars_Uint32 struct {
832 Uint32 MyUint32 `protobuf:"4"`
833 }
834 OneofScalars_Uint64 struct {
835 Uint64 uint64 `protobuf:"5"`
836 }
837 OneofScalars_Float32 struct {
838 Float32 MyFloat32 `protobuf:"6"`
839 }
840 OneofScalars_Float64 struct {
841 Float64 float64 `protobuf:"7"`
842 }
843 OneofScalars_String struct {
844 String string `protobuf:"8"`
845 }
846 OneofScalars_StringA struct {
847 StringA []byte `protobuf:"9"`
848 }
849 OneofScalars_StringB struct {
850 StringB MyString `protobuf:"10"`
851 }
852 OneofScalars_Bytes struct {
853 Bytes []byte `protobuf:"11"`
854 }
855 OneofScalars_BytesA struct {
856 BytesA string `protobuf:"12"`
857 }
858 OneofScalars_BytesB struct {
859 BytesB MyBytes `protobuf:"13"`
860 }
861)
862
Joe Tsai2c870bb2018-10-17 11:46:52 -0700863func (*OneofScalars_Bool) isOneofScalars_Union() {}
864func (*OneofScalars_Int32) isOneofScalars_Union() {}
865func (*OneofScalars_Int64) isOneofScalars_Union() {}
866func (*OneofScalars_Uint32) isOneofScalars_Union() {}
867func (*OneofScalars_Uint64) isOneofScalars_Union() {}
868func (*OneofScalars_Float32) isOneofScalars_Union() {}
869func (*OneofScalars_Float64) isOneofScalars_Union() {}
870func (*OneofScalars_String) isOneofScalars_Union() {}
871func (*OneofScalars_StringA) isOneofScalars_Union() {}
872func (*OneofScalars_StringB) isOneofScalars_Union() {}
873func (*OneofScalars_Bytes) isOneofScalars_Union() {}
874func (*OneofScalars_BytesA) isOneofScalars_Union() {}
875func (*OneofScalars_BytesB) isOneofScalars_Union() {}
876
877func TestOneofs(t *testing.T) {
Joe Tsaif0c01e42018-11-06 13:05:20 -0800878 empty := &OneofScalars{}
879 want1 := &OneofScalars{Union: &OneofScalars_Bool{true}}
880 want2 := &OneofScalars{Union: &OneofScalars_Int32{20}}
881 want3 := &OneofScalars{Union: &OneofScalars_Int64{30}}
882 want4 := &OneofScalars{Union: &OneofScalars_Uint32{40}}
883 want5 := &OneofScalars{Union: &OneofScalars_Uint64{50}}
884 want6 := &OneofScalars{Union: &OneofScalars_Float32{60}}
885 want7 := &OneofScalars{Union: &OneofScalars_Float64{70}}
886 want8 := &OneofScalars{Union: &OneofScalars_String{string("80")}}
887 want9 := &OneofScalars{Union: &OneofScalars_StringA{[]byte("90")}}
888 want10 := &OneofScalars{Union: &OneofScalars_StringB{MyString("100")}}
889 want11 := &OneofScalars{Union: &OneofScalars_Bytes{[]byte("110")}}
890 want12 := &OneofScalars{Union: &OneofScalars_BytesA{string("120")}}
891 want13 := &OneofScalars{Union: &OneofScalars_BytesB{MyBytes("130")}}
Joe Tsai2c870bb2018-10-17 11:46:52 -0700892
Joe Tsai378c1322019-04-25 23:48:08 -0700893 testMessage(t, nil, new(OneofScalars).ProtoReflect(), messageOps{
Joe Tsai2c870bb2018-10-17 11:46:52 -0700894 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},
895 getFields{1: V(bool(true)), 2: V(int32(2)), 3: V(int64(3)), 4: V(uint32(4)), 5: V(uint64(5)), 6: V(float32(6)), 7: V(float64(7)), 8: V(string("8")), 9: V(string("9")), 10: V(string("10")), 11: V([]byte("11")), 12: V([]byte("12")), 13: V([]byte("13"))},
Joe Tsai378c1322019-04-25 23:48:08 -0700896 whichOneofs{"union": 0},
Joe Tsai2c870bb2018-10-17 11:46:52 -0700897
Joe Tsai378c1322019-04-25 23:48:08 -0700898 setFields{1: V(bool(true))}, hasFields{1: true}, equalMessage{want1.ProtoReflect()},
899 setFields{2: V(int32(20))}, hasFields{2: true}, equalMessage{want2.ProtoReflect()},
900 setFields{3: V(int64(30))}, hasFields{3: true}, equalMessage{want3.ProtoReflect()},
901 setFields{4: V(uint32(40))}, hasFields{4: true}, equalMessage{want4.ProtoReflect()},
902 setFields{5: V(uint64(50))}, hasFields{5: true}, equalMessage{want5.ProtoReflect()},
903 setFields{6: V(float32(60))}, hasFields{6: true}, equalMessage{want6.ProtoReflect()},
904 setFields{7: V(float64(70))}, hasFields{7: true}, equalMessage{want7.ProtoReflect()},
Joe Tsai4ec39c72019-04-03 13:40:53 -0700905
906 hasFields{1: false, 2: false, 3: false, 4: false, 5: false, 6: false, 7: true, 8: false, 9: false, 10: false, 11: false, 12: false, 13: false},
Joe Tsai378c1322019-04-25 23:48:08 -0700907 whichOneofs{"union": 7},
Joe Tsai4ec39c72019-04-03 13:40:53 -0700908
Joe Tsai378c1322019-04-25 23:48:08 -0700909 setFields{8: V(string("80"))}, hasFields{8: true}, equalMessage{want8.ProtoReflect()},
910 setFields{9: V(string("90"))}, hasFields{9: true}, equalMessage{want9.ProtoReflect()},
911 setFields{10: V(string("100"))}, hasFields{10: true}, equalMessage{want10.ProtoReflect()},
912 setFields{11: V([]byte("110"))}, hasFields{11: true}, equalMessage{want11.ProtoReflect()},
913 setFields{12: V([]byte("120"))}, hasFields{12: true}, equalMessage{want12.ProtoReflect()},
914 setFields{13: V([]byte("130"))}, hasFields{13: true}, equalMessage{want13.ProtoReflect()},
Joe Tsai2c870bb2018-10-17 11:46:52 -0700915
916 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},
917 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 -0800918 clearFields{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12},
Joe Tsai378c1322019-04-25 23:48:08 -0700919 whichOneofs{"union": 13},
920 equalMessage{want13.ProtoReflect()},
Joe Tsai87b955b2018-11-14 21:59:49 -0800921 clearFields{13},
Joe Tsai378c1322019-04-25 23:48:08 -0700922 whichOneofs{"union": 0},
923 equalMessage{empty.ProtoReflect()},
Joe Tsai2c870bb2018-10-17 11:46:52 -0700924 })
Joe Tsai6cf80c42018-12-01 04:57:09 -0800925
926 // Test read-only operations on nil message.
Joe Tsai378c1322019-04-25 23:48:08 -0700927 testMessage(t, nil, (*OneofScalars)(nil).ProtoReflect(), messageOps{
Joe Tsai6cf80c42018-12-01 04:57:09 -0800928 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},
929 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"))},
930 })
Joe Tsai2c870bb2018-10-17 11:46:52 -0700931}
932
Joe Tsai87b955b2018-11-14 21:59:49 -0800933type EnumProto2 int32
934
Damien Neil16163b42019-08-06 15:43:25 -0700935var enumProto2Desc = mustMakeEnumDesc("enum2.proto", pref.Proto2, `
936 name: "EnumProto2"
937 value: [{name:"DEAD" number:0xdead}, {name:"BEEF" number:0xbeef}]
938`)
Joe Tsai87b955b2018-11-14 21:59:49 -0800939
Damien Neil16163b42019-08-06 15:43:25 -0700940func (e EnumProto2) Descriptor() pref.EnumDescriptor { return enumProto2Desc }
941func (e EnumProto2) Type() pref.EnumType { return e }
Joe Tsai0fc49f82019-05-01 12:29:25 -0700942func (e EnumProto2) Enum() *EnumProto2 { return &e }
943func (e EnumProto2) Number() pref.EnumNumber { return pref.EnumNumber(e) }
Damien Neil16163b42019-08-06 15:43:25 -0700944func (t EnumProto2) New(n pref.EnumNumber) pref.Enum { return EnumProto2(n) }
Joe Tsai87b955b2018-11-14 21:59:49 -0800945
946type EnumProto3 int32
947
Damien Neil16163b42019-08-06 15:43:25 -0700948var enumProto3Desc = mustMakeEnumDesc("enum3.proto", pref.Proto3, `
949 name: "EnumProto3",
950 value: [{name:"ALPHA" number:0}, {name:"BRAVO" number:1}]
951`)
Joe Tsai87b955b2018-11-14 21:59:49 -0800952
Damien Neil16163b42019-08-06 15:43:25 -0700953func (e EnumProto3) Descriptor() pref.EnumDescriptor { return enumProto3Desc }
954func (e EnumProto3) Type() pref.EnumType { return e }
Joe Tsai0fc49f82019-05-01 12:29:25 -0700955func (e EnumProto3) Enum() *EnumProto3 { return &e }
956func (e EnumProto3) Number() pref.EnumNumber { return pref.EnumNumber(e) }
Damien Neil16163b42019-08-06 15:43:25 -0700957func (t EnumProto3) New(n pref.EnumNumber) pref.Enum { return EnumProto3(n) }
Joe Tsai87b955b2018-11-14 21:59:49 -0800958
959type EnumMessages struct {
960 EnumP2 *EnumProto2 `protobuf:"1"`
961 EnumP3 *EnumProto3 `protobuf:"2"`
962 MessageLegacy *proto2_20180125.Message `protobuf:"3"`
963 MessageCycle *EnumMessages `protobuf:"4"`
964 EnumList []EnumProto2 `protobuf:"5"`
965 MessageList []*ScalarProto2 `protobuf:"6"`
966 EnumMap map[string]EnumProto3 `protobuf:"7"`
967 MessageMap map[string]*ScalarProto3 `protobuf:"8"`
968 Union isEnumMessages_Union `protobuf_oneof:"union"`
969}
970
Damien Neil16163b42019-08-06 15:43:25 -0700971var enumMessagesType = pimpl.MessageInfo{GoReflectType: reflect.TypeOf(new(EnumMessages)), Desc: mustMakeMessageDesc("enum-messages.proto", pref.Proto2, `
Joe Tsai55f18252020-01-11 00:25:01 -0800972 dependency: ["enum2.proto", "enum3.proto", "scalar2.proto", "scalar3.proto", "proto2_20180125_92554152/test.proto"]
Joe Tsaid8881392019-06-06 13:01:53 -0700973 `, `
974 name: "EnumMessages"
975 field: [
976 {name:"f1" number:1 label:LABEL_OPTIONAL type:TYPE_ENUM type_name:".EnumProto2" default_value:"BEEF"},
977 {name:"f2" number:2 label:LABEL_OPTIONAL type:TYPE_ENUM type_name:".EnumProto3" default_value:"BRAVO"},
Herbie Ong20aefe92019-06-24 19:21:46 -0700978 {name:"f3" number:3 label:LABEL_OPTIONAL type:TYPE_MESSAGE type_name:".google.golang.org.proto2_20180125.Message"},
979 {name:"f4" number:4 label:LABEL_OPTIONAL type:TYPE_MESSAGE type_name:".EnumMessages"},
Joe Tsaid8881392019-06-06 13:01:53 -0700980 {name:"f5" number:5 label:LABEL_REPEATED type:TYPE_ENUM type_name:".EnumProto2"},
981 {name:"f6" number:6 label:LABEL_REPEATED type:TYPE_MESSAGE type_name:".ScalarProto2"},
982 {name:"f7" number:7 label:LABEL_REPEATED type:TYPE_MESSAGE type_name:".EnumMessages.F7Entry"},
983 {name:"f8" number:8 label:LABEL_REPEATED type:TYPE_MESSAGE type_name:".EnumMessages.F8Entry"},
984 {name:"f9" number:9 label:LABEL_OPTIONAL type:TYPE_ENUM type_name:".EnumProto2" oneof_index:0 default_value:"BEEF"},
985 {name:"f10" number:10 label:LABEL_OPTIONAL type:TYPE_ENUM type_name:".EnumProto3" oneof_index:0 default_value:"BRAVO"},
986 {name:"f11" number:11 label:LABEL_OPTIONAL type:TYPE_MESSAGE type_name:".ScalarProto2" oneof_index:0},
987 {name:"f12" number:12 label:LABEL_OPTIONAL type:TYPE_MESSAGE type_name:".ScalarProto3" oneof_index:0}
988 ]
989 oneof_decl: [{name:"union"}]
990 nested_type: [
991 {name:"F7Entry" field:[{name:"key" number:1 label:LABEL_OPTIONAL type:TYPE_STRING}, {name:"value" number:2 label:LABEL_OPTIONAL type:TYPE_ENUM type_name:".EnumProto3"}] options:{map_entry:true}},
992 {name:"F8Entry" field:[{name:"key" number:1 label:LABEL_OPTIONAL type:TYPE_STRING}, {name:"value" number:2 label:LABEL_OPTIONAL type:TYPE_MESSAGE type_name:".ScalarProto3"}] options:{map_entry:true}}
993 ]
Damien Neilc8268852019-10-08 13:28:53 -0700994 `, newFileRegistry(
Damien Neil16163b42019-08-06 15:43:25 -0700995 EnumProto2(0).Descriptor().ParentFile(),
996 EnumProto3(0).Descriptor().ParentFile(),
997 ((*ScalarProto2)(nil)).ProtoReflect().Descriptor().ParentFile(),
998 ((*ScalarProto3)(nil)).ProtoReflect().Descriptor().ParentFile(),
999 pimpl.Export{}.MessageDescriptorOf((*proto2_20180125.Message)(nil)).ParentFile(),
1000)),
1001}
Joe Tsai87b955b2018-11-14 21:59:49 -08001002
Damien Neilc8268852019-10-08 13:28:53 -07001003func newFileRegistry(files ...pref.FileDescriptor) *protoregistry.Files {
1004 r := new(protoregistry.Files)
1005 for _, file := range files {
1006 r.RegisterFile(file)
1007 }
1008 return r
1009}
1010
Joe Tsai378c1322019-04-25 23:48:08 -07001011func (m *EnumMessages) ProtoReflect() pref.Message { return enumMessagesType.MessageOf(m) }
Joe Tsai87b955b2018-11-14 21:59:49 -08001012
Joe Tsaif18ab532018-11-27 17:25:04 -08001013func (*EnumMessages) XXX_OneofWrappers() []interface{} {
1014 return []interface{}{
Joe Tsai87b955b2018-11-14 21:59:49 -08001015 (*EnumMessages_OneofE2)(nil),
1016 (*EnumMessages_OneofE3)(nil),
1017 (*EnumMessages_OneofM2)(nil),
1018 (*EnumMessages_OneofM3)(nil),
1019 }
1020}
1021
1022type (
1023 isEnumMessages_Union interface {
1024 isEnumMessages_Union()
1025 }
1026 EnumMessages_OneofE2 struct {
1027 OneofE2 EnumProto2 `protobuf:"9"`
1028 }
1029 EnumMessages_OneofE3 struct {
1030 OneofE3 EnumProto3 `protobuf:"10"`
1031 }
1032 EnumMessages_OneofM2 struct {
1033 OneofM2 *ScalarProto2 `protobuf:"11"`
1034 }
1035 EnumMessages_OneofM3 struct {
1036 OneofM3 *ScalarProto3 `protobuf:"12"`
1037 }
1038)
1039
1040func (*EnumMessages_OneofE2) isEnumMessages_Union() {}
1041func (*EnumMessages_OneofE3) isEnumMessages_Union() {}
1042func (*EnumMessages_OneofM2) isEnumMessages_Union() {}
1043func (*EnumMessages_OneofM3) isEnumMessages_Union() {}
1044
1045func TestEnumMessages(t *testing.T) {
Joe Tsai378c1322019-04-25 23:48:08 -07001046 emptyL := pimpl.Export{}.MessageOf(new(proto2_20180125.Message))
1047 emptyM := new(EnumMessages).ProtoReflect()
1048 emptyM2 := new(ScalarProto2).ProtoReflect()
1049 emptyM3 := new(ScalarProto3).ProtoReflect()
1050
Damien Neila8a2cea2019-07-10 16:17:16 -07001051 wantL := pimpl.Export{}.MessageOf(&proto2_20180125.Message{OptionalFloat: proto.Float32(math.E)})
Joe Tsai378c1322019-04-25 23:48:08 -07001052 wantM := (&EnumMessages{EnumP2: EnumProto2(1234).Enum()}).ProtoReflect()
Damien Neila8a2cea2019-07-10 16:17:16 -07001053 wantM2a := &ScalarProto2{Float32: proto.Float32(math.Pi)}
1054 wantM2b := &ScalarProto2{Float32: proto.Float32(math.Phi)}
Joe Tsai87b955b2018-11-14 21:59:49 -08001055 wantM3a := &ScalarProto3{Float32: math.Pi}
1056 wantM3b := &ScalarProto3{Float32: math.Ln2}
1057
Joe Tsai378c1322019-04-25 23:48:08 -07001058 wantList5 := getField((&EnumMessages{EnumList: []EnumProto2{333, 222}}).ProtoReflect(), 5)
1059 wantList6 := getField((&EnumMessages{MessageList: []*ScalarProto2{wantM2a, wantM2b}}).ProtoReflect(), 6)
Joe Tsai87b955b2018-11-14 21:59:49 -08001060
Joe Tsai378c1322019-04-25 23:48:08 -07001061 wantMap7 := getField((&EnumMessages{EnumMap: map[string]EnumProto3{"one": 1, "two": 2}}).ProtoReflect(), 7)
1062 wantMap8 := getField((&EnumMessages{MessageMap: map[string]*ScalarProto3{"pi": wantM3a, "ln2": wantM3b}}).ProtoReflect(), 8)
Joe Tsai87b955b2018-11-14 21:59:49 -08001063
Joe Tsai378c1322019-04-25 23:48:08 -07001064 testMessage(t, nil, new(EnumMessages).ProtoReflect(), messageOps{
Joe Tsai87b955b2018-11-14 21:59:49 -08001065 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 Tsai378c1322019-04-25 23:48:08 -07001066 getFields{1: VE(0xbeef), 2: VE(1), 3: V(emptyL), 4: V(emptyM), 9: VE(0xbeef), 10: VE(1)},
Joe Tsai87b955b2018-11-14 21:59:49 -08001067
1068 // Test singular enums.
1069 setFields{1: VE(0xdead), 2: VE(0)},
1070 getFields{1: VE(0xdead), 2: VE(0)},
1071 hasFields{1: true, 2: true},
1072
1073 // Test singular messages.
Joe Tsai378c1322019-04-25 23:48:08 -07001074 messageFieldsMutable{3: messageOps{setFields{109: V(float32(math.E))}}},
1075 messageFieldsMutable{4: messageOps{setFields{1: VE(1234)}}},
Joe Tsai87b955b2018-11-14 21:59:49 -08001076 getFields{3: V(wantL), 4: V(wantM)},
1077 clearFields{3, 4},
1078 hasFields{3: false, 4: false},
1079 setFields{3: V(wantL), 4: V(wantM)},
1080 hasFields{3: true, 4: true},
1081
1082 // Test list of enums and messages.
Joe Tsai378c1322019-04-25 23:48:08 -07001083 listFieldsMutable{
Joe Tsai87b955b2018-11-14 21:59:49 -08001084 5: listOps{
1085 appendList{VE(111), VE(222)},
1086 setList{0: VE(333)},
1087 getList{0: VE(333), 1: VE(222)},
1088 lenList(2),
1089 },
1090 6: listOps{
1091 appendMessageList{setFields{4: V(uint32(1e6))}},
1092 appendMessageList{setFields{6: V(float32(math.Phi))}},
Joe Tsai378c1322019-04-25 23:48:08 -07001093 setList{0: V(wantM2a.ProtoReflect())},
1094 getList{0: V(wantM2a.ProtoReflect()), 1: V(wantM2b.ProtoReflect())},
Joe Tsai87b955b2018-11-14 21:59:49 -08001095 },
1096 },
1097 getFields{5: wantList5, 6: wantList6},
1098 hasFields{5: true, 6: true},
1099 listFields{5: listOps{truncList(0)}},
1100 hasFields{5: false, 6: true},
1101
1102 // Test maps of enums and messages.
Joe Tsai378c1322019-04-25 23:48:08 -07001103 mapFieldsMutable{
Joe Tsai87b955b2018-11-14 21:59:49 -08001104 7: mapOps{
1105 setMap{"one": VE(1), "two": VE(2)},
1106 hasMap{"one": true, "two": true, "three": false},
1107 lenMap(2),
1108 },
1109 8: mapOps{
1110 messageMap{"pi": messageOps{setFields{6: V(float32(math.Pi))}}},
Joe Tsai378c1322019-04-25 23:48:08 -07001111 setMap{"ln2": V(wantM3b.ProtoReflect())},
1112 getMap{"pi": V(wantM3a.ProtoReflect()), "ln2": V(wantM3b.ProtoReflect()), "none": V(nil)},
Joe Tsai87b955b2018-11-14 21:59:49 -08001113 lenMap(2),
1114 },
1115 },
1116 getFields{7: wantMap7, 8: wantMap8},
1117 hasFields{7: true, 8: true},
1118 mapFields{8: mapOps{clearMap{"pi", "ln2", "none"}}},
1119 hasFields{7: true, 8: false},
1120
1121 // Test oneofs of enums and messages.
1122 setFields{9: VE(0xdead)},
1123 hasFields{1: true, 2: true, 9: true, 10: false, 11: false, 12: false},
1124 setFields{10: VE(0)},
1125 hasFields{1: true, 2: true, 9: false, 10: true, 11: false, 12: false},
Joe Tsai378c1322019-04-25 23:48:08 -07001126 messageFieldsMutable{11: messageOps{setFields{6: V(float32(math.Pi))}}},
1127 getFields{11: V(wantM2a.ProtoReflect())},
Joe Tsai87b955b2018-11-14 21:59:49 -08001128 hasFields{1: true, 2: true, 9: false, 10: false, 11: true, 12: false},
Joe Tsai378c1322019-04-25 23:48:08 -07001129 messageFieldsMutable{12: messageOps{setFields{6: V(float32(math.Pi))}}},
1130 getFields{12: V(wantM3a.ProtoReflect())},
Joe Tsai87b955b2018-11-14 21:59:49 -08001131 hasFields{1: true, 2: true, 9: false, 10: false, 11: false, 12: true},
1132
1133 // Check entire message.
Joe Tsai378c1322019-04-25 23:48:08 -07001134 rangeFields{1: VE(0xdead), 2: VE(0), 3: V(wantL), 4: V(wantM), 6: wantList6, 7: wantMap7, 12: V(wantM3a.ProtoReflect())},
1135 equalMessage{(&EnumMessages{
Joe Tsai87b955b2018-11-14 21:59:49 -08001136 EnumP2: EnumProto2(0xdead).Enum(),
1137 EnumP3: EnumProto3(0).Enum(),
Damien Neila8a2cea2019-07-10 16:17:16 -07001138 MessageLegacy: &proto2_20180125.Message{OptionalFloat: proto.Float32(math.E)},
Joe Tsai378c1322019-04-25 23:48:08 -07001139 MessageCycle: wantM.Interface().(*EnumMessages),
Joe Tsai87b955b2018-11-14 21:59:49 -08001140 MessageList: []*ScalarProto2{wantM2a, wantM2b},
1141 EnumMap: map[string]EnumProto3{"one": 1, "two": 2},
1142 Union: &EnumMessages_OneofM3{wantM3a},
Joe Tsai378c1322019-04-25 23:48:08 -07001143 }).ProtoReflect()},
Joe Tsai87b955b2018-11-14 21:59:49 -08001144 clearFields{1, 2, 3, 4, 6, 7, 12},
Joe Tsai378c1322019-04-25 23:48:08 -07001145 equalMessage{new(EnumMessages).ProtoReflect()},
Joe Tsai87b955b2018-11-14 21:59:49 -08001146 })
Joe Tsai6cf80c42018-12-01 04:57:09 -08001147
1148 // Test read-only operations on nil message.
Joe Tsai378c1322019-04-25 23:48:08 -07001149 testMessage(t, nil, (*EnumMessages)(nil).ProtoReflect(), messageOps{
Joe Tsai6cf80c42018-12-01 04:57:09 -08001150 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 Tsai378c1322019-04-25 23:48:08 -07001151 getFields{1: VE(0xbeef), 2: VE(1), 3: V(emptyL), 4: V(emptyM), 9: VE(0xbeef), 10: VE(1), 11: V(emptyM2), 12: V(emptyM3)},
Joe Tsai6cf80c42018-12-01 04:57:09 -08001152 listFields{5: {lenList(0)}, 6: {lenList(0)}},
1153 mapFields{7: {lenMap(0)}, 8: {lenMap(0)}},
1154 })
Joe Tsai87b955b2018-11-14 21:59:49 -08001155}
Joe Tsaifa02f4e2018-09-12 16:20:37 -07001156
Joe Tsai91e14662018-09-13 13:24:35 -07001157var cmpOpts = cmp.Options{
Joe Tsai87b955b2018-11-14 21:59:49 -08001158 cmp.Comparer(func(x, y *proto2_20180125.Message) bool {
Joe Tsaid8881392019-06-06 13:01:53 -07001159 mx := pimpl.Export{}.MessageOf(x).Interface()
1160 my := pimpl.Export{}.MessageOf(y).Interface()
1161 return proto.Equal(mx, my)
Joe Tsai91e14662018-09-13 13:24:35 -07001162 }),
Joe Tsai87b955b2018-11-14 21:59:49 -08001163 cmp.Transformer("UnwrapValue", func(pv pref.Value) interface{} {
Joe Tsai378c1322019-04-25 23:48:08 -07001164 switch v := pv.Interface().(type) {
1165 case pref.Message:
1166 out := make(map[pref.FieldNumber]pref.Value)
1167 v.Range(func(fd pref.FieldDescriptor, v pref.Value) bool {
1168 out[fd.Number()] = v
1169 return true
1170 })
1171 return out
1172 case pref.List:
1173 var out []pref.Value
1174 for i := 0; i < v.Len(); i++ {
1175 out = append(out, v.Get(i))
1176 }
1177 return out
1178 case pref.Map:
1179 out := make(map[interface{}]pref.Value)
1180 v.Range(func(k pref.MapKey, v pref.Value) bool {
1181 out[k.Interface()] = v
1182 return true
1183 })
1184 return out
1185 default:
1186 return v
1187 }
Joe Tsai91e14662018-09-13 13:24:35 -07001188 }),
1189 cmpopts.EquateNaNs(),
1190}
1191
1192func testMessage(t *testing.T, p path, m pref.Message, tt messageOps) {
Joe Tsai378c1322019-04-25 23:48:08 -07001193 fieldDescs := m.Descriptor().Fields()
1194 oneofDescs := m.Descriptor().Oneofs()
Joe Tsai91e14662018-09-13 13:24:35 -07001195 for i, op := range tt {
1196 p.Push(i)
1197 switch op := op.(type) {
1198 case equalMessage:
Joe Tsai378c1322019-04-25 23:48:08 -07001199 if diff := cmp.Diff(V(op.Message), V(m), cmpOpts); diff != "" {
Joe Tsai91e14662018-09-13 13:24:35 -07001200 t.Errorf("operation %v, message mismatch (-want, +got):\n%s", p, diff)
1201 }
1202 case hasFields:
1203 got := map[pref.FieldNumber]bool{}
1204 want := map[pref.FieldNumber]bool(op)
1205 for n := range want {
Joe Tsai378c1322019-04-25 23:48:08 -07001206 fd := fieldDescs.ByNumber(n)
1207 got[n] = m.Has(fd)
Joe Tsai91e14662018-09-13 13:24:35 -07001208 }
1209 if diff := cmp.Diff(want, got); diff != "" {
Joe Tsai378c1322019-04-25 23:48:08 -07001210 t.Errorf("operation %v, Message.Has mismatch (-want, +got):\n%s", p, diff)
Joe Tsai91e14662018-09-13 13:24:35 -07001211 }
1212 case getFields:
1213 got := map[pref.FieldNumber]pref.Value{}
1214 want := map[pref.FieldNumber]pref.Value(op)
1215 for n := range want {
Joe Tsai378c1322019-04-25 23:48:08 -07001216 fd := fieldDescs.ByNumber(n)
1217 got[n] = m.Get(fd)
Joe Tsai91e14662018-09-13 13:24:35 -07001218 }
1219 if diff := cmp.Diff(want, got, cmpOpts); diff != "" {
Joe Tsai378c1322019-04-25 23:48:08 -07001220 t.Errorf("operation %v, Message.Get mismatch (-want, +got):\n%s", p, diff)
Joe Tsai91e14662018-09-13 13:24:35 -07001221 }
1222 case setFields:
1223 for n, v := range op {
Joe Tsai378c1322019-04-25 23:48:08 -07001224 fd := fieldDescs.ByNumber(n)
1225 m.Set(fd, v)
Joe Tsai91e14662018-09-13 13:24:35 -07001226 }
1227 case clearFields:
Joe Tsai87b955b2018-11-14 21:59:49 -08001228 for _, n := range op {
Joe Tsai378c1322019-04-25 23:48:08 -07001229 fd := fieldDescs.ByNumber(n)
1230 m.Clear(fd)
Joe Tsai87b955b2018-11-14 21:59:49 -08001231 }
Joe Tsai4ec39c72019-04-03 13:40:53 -07001232 case whichOneofs:
1233 got := map[pref.Name]pref.FieldNumber{}
1234 want := map[pref.Name]pref.FieldNumber(op)
1235 for s := range want {
Joe Tsai378c1322019-04-25 23:48:08 -07001236 od := oneofDescs.ByName(s)
1237 fd := m.WhichOneof(od)
1238 if fd == nil {
1239 got[s] = 0
1240 } else {
1241 got[s] = fd.Number()
1242 }
Joe Tsai4ec39c72019-04-03 13:40:53 -07001243 }
1244 if diff := cmp.Diff(want, got); diff != "" {
Joe Tsai378c1322019-04-25 23:48:08 -07001245 t.Errorf("operation %v, Message.WhichOneof mismatch (-want, +got):\n%s", p, diff)
Joe Tsai4ec39c72019-04-03 13:40:53 -07001246 }
Joe Tsai87b955b2018-11-14 21:59:49 -08001247 case messageFields:
1248 for n, tt := range op {
1249 p.Push(int(n))
Joe Tsai378c1322019-04-25 23:48:08 -07001250 fd := fieldDescs.ByNumber(n)
1251 testMessage(t, p, m.Get(fd).Message(), tt)
1252 p.Pop()
1253 }
1254 case messageFieldsMutable:
1255 for n, tt := range op {
1256 p.Push(int(n))
1257 fd := fieldDescs.ByNumber(n)
1258 testMessage(t, p, m.Mutable(fd).Message(), tt)
Joe Tsai87b955b2018-11-14 21:59:49 -08001259 p.Pop()
Joe Tsaifa02f4e2018-09-12 16:20:37 -07001260 }
Joe Tsai4b7aff62018-11-14 14:05:19 -08001261 case listFields:
Joe Tsai91e14662018-09-13 13:24:35 -07001262 for n, tt := range op {
1263 p.Push(int(n))
Joe Tsai378c1322019-04-25 23:48:08 -07001264 fd := fieldDescs.ByNumber(n)
1265 testLists(t, p, m.Get(fd).List(), tt)
1266 p.Pop()
1267 }
1268 case listFieldsMutable:
1269 for n, tt := range op {
1270 p.Push(int(n))
1271 fd := fieldDescs.ByNumber(n)
1272 testLists(t, p, m.Mutable(fd).List(), tt)
Joe Tsai91e14662018-09-13 13:24:35 -07001273 p.Pop()
1274 }
Joe Tsaibbfaeb72018-10-17 00:27:21 +00001275 case mapFields:
1276 for n, tt := range op {
1277 p.Push(int(n))
Joe Tsai378c1322019-04-25 23:48:08 -07001278 fd := fieldDescs.ByNumber(n)
1279 testMaps(t, p, m.Get(fd).Map(), tt)
1280 p.Pop()
1281 }
1282 case mapFieldsMutable:
1283 for n, tt := range op {
1284 p.Push(int(n))
1285 fd := fieldDescs.ByNumber(n)
1286 testMaps(t, p, m.Mutable(fd).Map(), tt)
Joe Tsaibbfaeb72018-10-17 00:27:21 +00001287 p.Pop()
1288 }
Joe Tsai87b955b2018-11-14 21:59:49 -08001289 case rangeFields:
1290 got := map[pref.FieldNumber]pref.Value{}
1291 want := map[pref.FieldNumber]pref.Value(op)
Joe Tsai378c1322019-04-25 23:48:08 -07001292 m.Range(func(fd pref.FieldDescriptor, v pref.Value) bool {
1293 got[fd.Number()] = v
Joe Tsai87b955b2018-11-14 21:59:49 -08001294 return true
1295 })
1296 if diff := cmp.Diff(want, got, cmpOpts); diff != "" {
Joe Tsai378c1322019-04-25 23:48:08 -07001297 t.Errorf("operation %v, Message.Range mismatch (-want, +got):\n%s", p, diff)
Joe Tsai87b955b2018-11-14 21:59:49 -08001298 }
Joe Tsai91e14662018-09-13 13:24:35 -07001299 default:
1300 t.Fatalf("operation %v, invalid operation: %T", p, op)
1301 }
1302 p.Pop()
Joe Tsaifa02f4e2018-09-12 16:20:37 -07001303 }
1304}
Joe Tsai91e14662018-09-13 13:24:35 -07001305
Joe Tsai4b7aff62018-11-14 14:05:19 -08001306func testLists(t *testing.T, p path, v pref.List, tt listOps) {
Joe Tsai91e14662018-09-13 13:24:35 -07001307 for i, op := range tt {
1308 p.Push(i)
1309 switch op := op.(type) {
Joe Tsai4b7aff62018-11-14 14:05:19 -08001310 case equalList:
Joe Tsai378c1322019-04-25 23:48:08 -07001311 if diff := cmp.Diff(V(op.List), V(v), cmpOpts); diff != "" {
Joe Tsai4b7aff62018-11-14 14:05:19 -08001312 t.Errorf("operation %v, list mismatch (-want, +got):\n%s", p, diff)
Joe Tsai91e14662018-09-13 13:24:35 -07001313 }
Joe Tsai4b7aff62018-11-14 14:05:19 -08001314 case lenList:
Joe Tsai91e14662018-09-13 13:24:35 -07001315 if got, want := v.Len(), int(op); got != want {
Joe Tsai4b7aff62018-11-14 14:05:19 -08001316 t.Errorf("operation %v, List.Len = %d, want %d", p, got, want)
Joe Tsai91e14662018-09-13 13:24:35 -07001317 }
Joe Tsai4b7aff62018-11-14 14:05:19 -08001318 case getList:
Joe Tsai91e14662018-09-13 13:24:35 -07001319 got := map[int]pref.Value{}
1320 want := map[int]pref.Value(op)
1321 for n := range want {
1322 got[n] = v.Get(n)
1323 }
1324 if diff := cmp.Diff(want, got, cmpOpts); diff != "" {
Joe Tsai4b7aff62018-11-14 14:05:19 -08001325 t.Errorf("operation %v, List.Get mismatch (-want, +got):\n%s", p, diff)
Joe Tsai91e14662018-09-13 13:24:35 -07001326 }
Joe Tsai4b7aff62018-11-14 14:05:19 -08001327 case setList:
Joe Tsai91e14662018-09-13 13:24:35 -07001328 for n, e := range op {
1329 v.Set(n, e)
1330 }
Joe Tsai4b7aff62018-11-14 14:05:19 -08001331 case appendList:
Joe Tsai91e14662018-09-13 13:24:35 -07001332 for _, e := range op {
1333 v.Append(e)
1334 }
Joe Tsai87b955b2018-11-14 21:59:49 -08001335 case appendMessageList:
Damien Neild91c4222019-09-04 10:46:00 -07001336 e := v.NewElement()
1337 v.Append(e)
1338 testMessage(t, p, e.Message(), messageOps(op))
Joe Tsai4b7aff62018-11-14 14:05:19 -08001339 case truncList:
Joe Tsai91e14662018-09-13 13:24:35 -07001340 v.Truncate(int(op))
1341 default:
1342 t.Fatalf("operation %v, invalid operation: %T", p, op)
1343 }
1344 p.Pop()
1345 }
1346}
1347
Joe Tsaibbfaeb72018-10-17 00:27:21 +00001348func testMaps(t *testing.T, p path, m pref.Map, tt mapOps) {
1349 for i, op := range tt {
1350 p.Push(i)
1351 switch op := op.(type) {
1352 case equalMap:
Joe Tsai378c1322019-04-25 23:48:08 -07001353 if diff := cmp.Diff(V(op.Map), V(m), cmpOpts); diff != "" {
Joe Tsaibbfaeb72018-10-17 00:27:21 +00001354 t.Errorf("operation %v, map mismatch (-want, +got):\n%s", p, diff)
1355 }
1356 case lenMap:
1357 if got, want := m.Len(), int(op); got != want {
1358 t.Errorf("operation %v, Map.Len = %d, want %d", p, got, want)
1359 }
1360 case hasMap:
1361 got := map[interface{}]bool{}
1362 want := map[interface{}]bool(op)
1363 for k := range want {
1364 got[k] = m.Has(V(k).MapKey())
1365 }
1366 if diff := cmp.Diff(want, got, cmpOpts); diff != "" {
1367 t.Errorf("operation %v, Map.Has mismatch (-want, +got):\n%s", p, diff)
1368 }
1369 case getMap:
1370 got := map[interface{}]pref.Value{}
1371 want := map[interface{}]pref.Value(op)
1372 for k := range want {
1373 got[k] = m.Get(V(k).MapKey())
1374 }
1375 if diff := cmp.Diff(want, got, cmpOpts); diff != "" {
1376 t.Errorf("operation %v, Map.Get mismatch (-want, +got):\n%s", p, diff)
1377 }
1378 case setMap:
1379 for k, v := range op {
1380 m.Set(V(k).MapKey(), v)
1381 }
1382 case clearMap:
Joe Tsai87b955b2018-11-14 21:59:49 -08001383 for _, k := range op {
1384 m.Clear(V(k).MapKey())
1385 }
1386 case messageMap:
1387 for k, tt := range op {
Damien Neil97e7f572018-12-07 14:28:33 -08001388 mk := V(k).MapKey()
1389 if !m.Has(mk) {
Damien Neild91c4222019-09-04 10:46:00 -07001390 m.Set(mk, m.NewValue())
Damien Neil97e7f572018-12-07 14:28:33 -08001391 }
1392 testMessage(t, p, m.Get(mk).Message(), tt)
Joe Tsaibbfaeb72018-10-17 00:27:21 +00001393 }
1394 case rangeMap:
1395 got := map[interface{}]pref.Value{}
1396 want := map[interface{}]pref.Value(op)
1397 m.Range(func(k pref.MapKey, v pref.Value) bool {
1398 got[k.Interface()] = v
1399 return true
1400 })
1401 if diff := cmp.Diff(want, got, cmpOpts); diff != "" {
1402 t.Errorf("operation %v, Map.Range mismatch (-want, +got):\n%s", p, diff)
1403 }
1404 default:
1405 t.Fatalf("operation %v, invalid operation: %T", p, op)
1406 }
1407 p.Pop()
1408 }
1409}
1410
Joe Tsai378c1322019-04-25 23:48:08 -07001411func getField(m pref.Message, n pref.FieldNumber) pref.Value {
1412 fd := m.Descriptor().Fields().ByNumber(n)
1413 return m.Get(fd)
1414}
1415
Joe Tsai91e14662018-09-13 13:24:35 -07001416type path []int
1417
1418func (p *path) Push(i int) { *p = append(*p, i) }
1419func (p *path) Pop() { *p = (*p)[:len(*p)-1] }
1420func (p path) String() string {
1421 var ss []string
1422 for _, i := range p {
1423 ss = append(ss, fmt.Sprint(i))
1424 }
1425 return strings.Join(ss, ".")
1426}
Joe Tsai82760ce2019-06-20 03:09:57 -07001427
Joe Tsaiae313d42019-10-16 10:25:54 -07001428func TestReset(t *testing.T) {
1429 mi := new(testpb.TestAllTypes)
1430
1431 // ProtoReflect is implemented using a messageState cache.
1432 m := mi.ProtoReflect()
1433
1434 // Reset must not clear the messageState cache.
1435 mi.Reset()
1436
1437 // If Reset accidentally cleared the messageState cache, this panics.
1438 m.Descriptor()
1439}
1440
Damien Neilb120a232019-12-16 13:23:25 -08001441func TestIsValid(t *testing.T) {
1442 var m *testpb.TestAllTypes
1443 if got, want := m.ProtoReflect().IsValid(), false; got != want {
1444 t.Errorf("((*M)(nil)).ProtoReflect().IsValid() = %v, want %v", got, want)
1445 }
1446 m = &testpb.TestAllTypes{}
1447 if got, want := m.ProtoReflect().IsValid(), true; got != want {
1448 t.Errorf("(&M{}).ProtoReflect().IsValid() = %v, want %v", got, want)
1449 }
1450}
1451
Joe Tsai82760ce2019-06-20 03:09:57 -07001452// The MessageState implementation makes the assumption that when a
1453// concrete message is unsafe casted as a *MessageState, the Go GC does
1454// not reclaim the memory for the remainder of the concrete message.
1455func TestUnsafeAssumptions(t *testing.T) {
1456 if !pimpl.UnsafeEnabled {
1457 t.Skip()
1458 }
1459
1460 var wg sync.WaitGroup
1461 for i := 0; i < 10; i++ {
1462 wg.Add(1)
1463 go func() {
1464 var ms [10]pref.Message
1465
1466 // Store the message only in its reflective form.
1467 // Trigger the GC after each iteration.
1468 for j := 0; j < 10; j++ {
1469 ms[j] = (&testpb.TestAllTypes{
Damien Neila8a2cea2019-07-10 16:17:16 -07001470 OptionalInt32: proto.Int32(int32(j)),
1471 OptionalFloat: proto.Float32(float32(j)),
Joe Tsai82760ce2019-06-20 03:09:57 -07001472 RepeatedInt32: []int32{int32(j)},
1473 RepeatedFloat: []float32{float32(j)},
Damien Neila8a2cea2019-07-10 16:17:16 -07001474 DefaultInt32: proto.Int32(int32(j)),
1475 DefaultFloat: proto.Float32(float32(j)),
Joe Tsai82760ce2019-06-20 03:09:57 -07001476 }).ProtoReflect()
1477 runtime.GC()
1478 }
1479
1480 // Convert the reflective form back into a concrete form.
1481 // Verify that the values written previously are still the same.
1482 for j := 0; j < 10; j++ {
1483 switch m := ms[j].Interface().(*testpb.TestAllTypes); {
1484 case m.GetOptionalInt32() != int32(j):
1485 case m.GetOptionalFloat() != float32(j):
1486 case m.GetRepeatedInt32()[0] != int32(j):
1487 case m.GetRepeatedFloat()[0] != float32(j):
1488 case m.GetDefaultInt32() != int32(j):
1489 case m.GetDefaultFloat() != float32(j):
1490 default:
1491 continue
1492 }
1493 t.Error("memory corrupted detected")
1494 }
1495 defer wg.Done()
1496 }()
1497 }
1498 wg.Wait()
1499}
1500
1501func BenchmarkName(b *testing.B) {
1502 var sink pref.FullName
1503 b.Run("Value", func(b *testing.B) {
1504 b.ReportAllocs()
1505 m := new(descriptorpb.FileDescriptorProto)
1506 for i := 0; i < b.N; i++ {
1507 sink = m.ProtoReflect().Descriptor().FullName()
1508 }
1509 })
1510 b.Run("Nil", func(b *testing.B) {
1511 b.ReportAllocs()
1512 m := (*descriptorpb.FileDescriptorProto)(nil)
1513 for i := 0; i < b.N; i++ {
1514 sink = m.ProtoReflect().Descriptor().FullName()
1515 }
1516 })
1517 runtime.KeepAlive(sink)
1518}
Joe Tsai9d637ca2019-09-18 18:08:52 -07001519
1520func BenchmarkReflect(b *testing.B) {
1521 m := new(testpb.TestAllTypes).ProtoReflect()
1522 fds := m.Descriptor().Fields()
1523 vs := make([]pref.Value, fds.Len())
1524 for i := range vs {
1525 vs[i] = m.NewField(fds.Get(i))
1526 }
1527
1528 b.Run("Has", func(b *testing.B) {
1529 b.ReportAllocs()
1530 for i := 0; i < b.N; i++ {
1531 for j := 0; j < fds.Len(); j++ {
1532 m.Has(fds.Get(j))
1533 }
1534 }
1535 })
1536 b.Run("Get", func(b *testing.B) {
1537 b.ReportAllocs()
1538 for i := 0; i < b.N; i++ {
1539 for j := 0; j < fds.Len(); j++ {
1540 m.Get(fds.Get(j))
1541 }
1542 }
1543 })
1544 b.Run("Set", func(b *testing.B) {
1545 b.ReportAllocs()
1546 for i := 0; i < b.N; i++ {
1547 for j := 0; j < fds.Len(); j++ {
1548 m.Set(fds.Get(j), vs[j])
1549 }
1550 }
1551 })
1552 b.Run("Clear", func(b *testing.B) {
1553 b.ReportAllocs()
1554 for i := 0; i < b.N; i++ {
1555 for j := 0; j < fds.Len(); j++ {
1556 m.Clear(fds.Get(j))
1557 }
1558 }
1559 })
1560 b.Run("Range", func(b *testing.B) {
1561 b.ReportAllocs()
1562 for i := 0; i < b.N; i++ {
1563 m.Range(func(pref.FieldDescriptor, pref.Value) bool {
1564 return true
1565 })
1566 }
1567 })
1568}