blob: 3d0a92118a0609faff93cb0930605a5a509f0906 [file] [log] [blame]
Joe Tsai90fe9962018-10-18 11:06:29 -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 Tsai21ade492019-05-22 13:42:54 -04005package impl
Joe Tsai90fe9962018-10-18 11:06:29 -07006
7import (
8 "fmt"
Joe Tsai90fe9962018-10-18 11:06:29 -07009 "reflect"
Joe Tsai851185d2019-07-01 13:45:52 -070010 "strings"
Joe Tsai90fe9962018-10-18 11:06:29 -070011 "sync"
Joe Tsai90fe9962018-10-18 11:06:29 -070012
Joe Tsai851185d2019-07-01 13:45:52 -070013 "google.golang.org/protobuf/internal/descopts"
14 ptag "google.golang.org/protobuf/internal/encoding/tag"
Damien Neil47d58932019-09-30 15:34:27 -070015 "google.golang.org/protobuf/internal/errors"
Joe Tsai851185d2019-07-01 13:45:52 -070016 "google.golang.org/protobuf/internal/filedesc"
Joe Tsai97a87392019-07-07 01:49:59 -070017 "google.golang.org/protobuf/internal/strs"
Joe Tsaid8881392019-06-06 13:01:53 -070018 "google.golang.org/protobuf/reflect/protoreflect"
Damien Neile89e6242019-05-13 23:55:40 -070019 pref "google.golang.org/protobuf/reflect/protoreflect"
Damien Neil37ef6912019-09-25 16:51:15 -070020 piface "google.golang.org/protobuf/runtime/protoiface"
Joe Tsai90fe9962018-10-18 11:06:29 -070021)
22
Joe Tsai21ade492019-05-22 13:42:54 -040023// legacyWrapMessage wraps v as a protoreflect.ProtoMessage,
Joe Tsaif0c01e42018-11-06 13:05:20 -080024// where v must be a *struct kind and not implement the v2 API already.
Joe Tsai21ade492019-05-22 13:42:54 -040025func legacyWrapMessage(v reflect.Value) pref.ProtoMessage {
Damien Neil47d58932019-09-30 15:34:27 -070026 typ := v.Type()
27 if typ.Kind() != reflect.Ptr || typ.Elem().Kind() != reflect.Struct {
28 return aberrantMessage{v: v}
29 }
30 mt := legacyLoadMessageInfo(typ, "")
Joe Tsai08e00302018-11-26 22:32:06 -080031 return mt.MessageOf(v.Interface()).Interface()
Joe Tsaif0c01e42018-11-06 13:05:20 -080032}
33
Joe Tsai21ade492019-05-22 13:42:54 -040034var legacyMessageTypeCache sync.Map // map[reflect.Type]*MessageInfo
Joe Tsaice6edd32018-10-19 16:27:46 -070035
Joe Tsai21ade492019-05-22 13:42:54 -040036// legacyLoadMessageInfo dynamically loads a *MessageInfo for t,
Joe Tsaif0c01e42018-11-06 13:05:20 -080037// where t must be a *struct kind and not implement the v2 API already.
Joe Tsaiea5ada12019-09-04 22:41:40 -070038// The provided name is used if it cannot be determined from the message.
39func legacyLoadMessageInfo(t reflect.Type, name pref.FullName) *MessageInfo {
Joe Tsai4fe96632019-05-22 05:12:36 -040040 // Fast-path: check if a MessageInfo is cached for this concrete type.
Joe Tsai21ade492019-05-22 13:42:54 -040041 if mt, ok := legacyMessageTypeCache.Load(t); ok {
42 return mt.(*MessageInfo)
Joe Tsaice6edd32018-10-19 16:27:46 -070043 }
44
Joe Tsai4fe96632019-05-22 05:12:36 -040045 // Slow-path: derive message descriptor and initialize MessageInfo.
Damien Neil16163b42019-08-06 15:43:25 -070046 mi := &MessageInfo{
Joe Tsaiea5ada12019-09-04 22:41:40 -070047 Desc: legacyLoadMessageDesc(t, name),
Damien Neil16163b42019-08-06 15:43:25 -070048 GoReflectType: t,
Joe Tsaib2f66be2019-05-22 00:42:45 -040049 }
Damien Neil37ef6912019-09-25 16:51:15 -070050
51 v := reflect.Zero(t).Interface()
Damien Neil47d58932019-09-30 15:34:27 -070052 if _, ok := v.(legacyMarshaler); ok {
53 mi.methods.MarshalAppend = legacyMarshalAppend
54 mi.methods.Size = legacySize
Damien Neilc7f2bee2019-11-06 15:29:05 -080055
56 // We have no way to tell whether the type's Marshal method
57 // supports deterministic serialization or not, but this
58 // preserves the v1 implementation's behavior of always
59 // calling Marshal methods when present.
60 mi.methods.Flags |= piface.SupportMarshalDeterministic
Damien Neil37ef6912019-09-25 16:51:15 -070061 }
Damien Neil47d58932019-09-30 15:34:27 -070062 if _, ok := v.(legacyUnmarshaler); ok {
63 mi.methods.Unmarshal = legacyUnmarshal
Damien Neil37ef6912019-09-25 16:51:15 -070064 }
65
Damien Neil16163b42019-08-06 15:43:25 -070066 if mi, ok := legacyMessageTypeCache.LoadOrStore(t, mi); ok {
67 return mi.(*MessageInfo)
Joe Tsaib9365042019-03-19 14:14:29 -070068 }
Damien Neil16163b42019-08-06 15:43:25 -070069 return mi
Joe Tsaice6edd32018-10-19 16:27:46 -070070}
71
Joe Tsaid8881392019-06-06 13:01:53 -070072var legacyMessageDescCache sync.Map // map[reflect.Type]protoreflect.MessageDescriptor
Joe Tsai90fe9962018-10-18 11:06:29 -070073
Joe Tsai21ade492019-05-22 13:42:54 -040074// LegacyLoadMessageDesc returns an MessageDescriptor derived from the Go type,
Joe Tsaice6edd32018-10-19 16:27:46 -070075// which must be a *struct kind and not implement the v2 API already.
Joe Tsai35ec98f2019-03-25 14:41:32 -070076//
77// This is exported for testing purposes.
Joe Tsai21ade492019-05-22 13:42:54 -040078func LegacyLoadMessageDesc(t reflect.Type) pref.MessageDescriptor {
Joe Tsaiea5ada12019-09-04 22:41:40 -070079 return legacyLoadMessageDesc(t, "")
80}
81func legacyLoadMessageDesc(t reflect.Type, name pref.FullName) pref.MessageDescriptor {
Joe Tsai90fe9962018-10-18 11:06:29 -070082 // Fast-path: check if a MessageDescriptor is cached for this concrete type.
Joe Tsai21ade492019-05-22 13:42:54 -040083 if mi, ok := legacyMessageDescCache.Load(t); ok {
Joe Tsai90fe9962018-10-18 11:06:29 -070084 return mi.(pref.MessageDescriptor)
85 }
86
Joe Tsaid8881392019-06-06 13:01:53 -070087 // Slow-path: initialize MessageDescriptor from the raw descriptor.
Damien Neil47d58932019-09-30 15:34:27 -070088 mv := reflect.Zero(t).Interface()
Joe Tsai90fe9962018-10-18 11:06:29 -070089 if _, ok := mv.(pref.ProtoMessage); ok {
90 panic(fmt.Sprintf("%v already implements proto.Message", t))
91 }
Joe Tsaid8881392019-06-06 13:01:53 -070092 mdV1, ok := mv.(messageV1)
93 if !ok {
Joe Tsaiea5ada12019-09-04 22:41:40 -070094 return aberrantLoadMessageDesc(t, name)
Joe Tsaid8881392019-06-06 13:01:53 -070095 }
Damien Neil16057752019-11-11 16:30:04 -080096
97 // If this is a dynamic message type where there isn't a 1-1 mapping between
98 // Go and protobuf types, calling the Descriptor method on the zero value of
99 // the message type isn't likely to work. If it panics, swallow the panic and
100 // continue as if the Descriptor method wasn't present.
101 b, idxs := func() ([]byte, []int) {
102 defer func() {
103 recover()
104 }()
105 return mdV1.Descriptor()
106 }()
107 if b == nil {
108 return aberrantLoadMessageDesc(t, name)
109 }
Joe Tsai90fe9962018-10-18 11:06:29 -0700110
Joe Tsaid8881392019-06-06 13:01:53 -0700111 md := legacyLoadFileDesc(b).Messages().Get(idxs[0])
112 for _, i := range idxs[1:] {
113 md = md.Messages().Get(i)
Joe Tsai90fe9962018-10-18 11:06:29 -0700114 }
Joe Tsaiea5ada12019-09-04 22:41:40 -0700115 if name != "" && md.FullName() != name {
116 panic(fmt.Sprintf("mismatching message name: got %v, want %v", md.FullName(), name))
117 }
Joe Tsaid8881392019-06-06 13:01:53 -0700118 if md, ok := legacyMessageDescCache.LoadOrStore(t, md); ok {
119 return md.(protoreflect.MessageDescriptor)
Joe Tsai90fe9962018-10-18 11:06:29 -0700120 }
Joe Tsaid8881392019-06-06 13:01:53 -0700121 return md
Joe Tsai90fe9962018-10-18 11:06:29 -0700122}
Joe Tsai851185d2019-07-01 13:45:52 -0700123
Joe Tsai32e8a522019-07-02 10:51:24 -0700124var (
125 aberrantMessageDescLock sync.Mutex
126 aberrantMessageDescCache map[reflect.Type]protoreflect.MessageDescriptor
127)
Joe Tsai851185d2019-07-01 13:45:52 -0700128
Damien Neil47d58932019-09-30 15:34:27 -0700129// aberrantLoadMessageDesc returns an MessageDescriptor derived from the Go type,
Joe Tsai851185d2019-07-01 13:45:52 -0700130// which must not implement protoreflect.ProtoMessage or messageV1.
131//
132// This is a best-effort derivation of the message descriptor using the protobuf
133// tags on the struct fields.
Joe Tsaiea5ada12019-09-04 22:41:40 -0700134func aberrantLoadMessageDesc(t reflect.Type, name pref.FullName) pref.MessageDescriptor {
Joe Tsai32e8a522019-07-02 10:51:24 -0700135 aberrantMessageDescLock.Lock()
136 defer aberrantMessageDescLock.Unlock()
137 if aberrantMessageDescCache == nil {
138 aberrantMessageDescCache = make(map[reflect.Type]protoreflect.MessageDescriptor)
139 }
Joe Tsaiea5ada12019-09-04 22:41:40 -0700140 return aberrantLoadMessageDescReentrant(t, name)
Joe Tsai32e8a522019-07-02 10:51:24 -0700141}
Joe Tsaiea5ada12019-09-04 22:41:40 -0700142func aberrantLoadMessageDescReentrant(t reflect.Type, name pref.FullName) pref.MessageDescriptor {
Joe Tsai851185d2019-07-01 13:45:52 -0700143 // Fast-path: check if an MessageDescriptor is cached for this concrete type.
Joe Tsai32e8a522019-07-02 10:51:24 -0700144 if md, ok := aberrantMessageDescCache[t]; ok {
145 return md
Joe Tsai851185d2019-07-01 13:45:52 -0700146 }
147
Joe Tsai851185d2019-07-01 13:45:52 -0700148 // Slow-path: construct a descriptor from the Go struct type (best-effort).
Joe Tsai32e8a522019-07-02 10:51:24 -0700149 // Cache the MessageDescriptor early on so that we can resolve internal
150 // cyclic references.
151 md := &filedesc.Message{L2: new(filedesc.MessageL2)}
Damien Neil47d58932019-09-30 15:34:27 -0700152 md.L0.FullName = aberrantDeriveMessageName(t, name)
Joe Tsai851185d2019-07-01 13:45:52 -0700153 md.L0.ParentFile = filedesc.SurrogateProto2
Joe Tsai32e8a522019-07-02 10:51:24 -0700154 aberrantMessageDescCache[t] = md
Joe Tsai851185d2019-07-01 13:45:52 -0700155
Damien Neil47d58932019-09-30 15:34:27 -0700156 if t.Kind() != reflect.Ptr || t.Elem().Kind() != reflect.Struct {
157 return md
158 }
159
Joe Tsai851185d2019-07-01 13:45:52 -0700160 // Try to determine if the message is using proto3 by checking scalars.
161 for i := 0; i < t.Elem().NumField(); i++ {
162 f := t.Elem().Field(i)
163 if tag := f.Tag.Get("protobuf"); tag != "" {
164 switch f.Type.Kind() {
165 case reflect.Bool, reflect.Int32, reflect.Int64, reflect.Uint32, reflect.Uint64, reflect.Float32, reflect.Float64, reflect.String:
166 md.L0.ParentFile = filedesc.SurrogateProto3
167 }
168 for _, s := range strings.Split(tag, ",") {
169 if s == "proto3" {
170 md.L0.ParentFile = filedesc.SurrogateProto3
171 }
172 }
173 }
174 }
175
176 // Obtain a list of oneof wrapper types.
177 var oneofWrappers []reflect.Type
178 if fn, ok := t.MethodByName("XXX_OneofFuncs"); ok {
179 vs := fn.Func.Call([]reflect.Value{reflect.Zero(fn.Type.In(0))})[3]
180 for _, v := range vs.Interface().([]interface{}) {
181 oneofWrappers = append(oneofWrappers, reflect.TypeOf(v))
182 }
183 }
184 if fn, ok := t.MethodByName("XXX_OneofWrappers"); ok {
185 vs := fn.Func.Call([]reflect.Value{reflect.Zero(fn.Type.In(0))})[0]
186 for _, v := range vs.Interface().([]interface{}) {
187 oneofWrappers = append(oneofWrappers, reflect.TypeOf(v))
188 }
189 }
190
191 // Obtain a list of the extension ranges.
192 if fn, ok := t.MethodByName("ExtensionRangeArray"); ok {
193 vs := fn.Func.Call([]reflect.Value{reflect.Zero(fn.Type.In(0))})[0]
194 for i := 0; i < vs.Len(); i++ {
195 v := vs.Index(i)
196 md.L2.ExtensionRanges.List = append(md.L2.ExtensionRanges.List, [2]pref.FieldNumber{
197 pref.FieldNumber(v.FieldByName("Start").Int()),
198 pref.FieldNumber(v.FieldByName("End").Int() + 1),
199 })
200 md.L2.ExtensionRangeOptions = append(md.L2.ExtensionRangeOptions, nil)
201 }
202 }
203
204 // Derive the message fields by inspecting the struct fields.
205 for i := 0; i < t.Elem().NumField(); i++ {
206 f := t.Elem().Field(i)
207 if tag := f.Tag.Get("protobuf"); tag != "" {
208 tagKey := f.Tag.Get("protobuf_key")
209 tagVal := f.Tag.Get("protobuf_val")
210 aberrantAppendField(md, f.Type, tag, tagKey, tagVal)
211 }
212 if tag := f.Tag.Get("protobuf_oneof"); tag != "" {
213 n := len(md.L2.Oneofs.List)
214 md.L2.Oneofs.List = append(md.L2.Oneofs.List, filedesc.Oneof{})
215 od := &md.L2.Oneofs.List[n]
216 od.L0.FullName = md.FullName().Append(pref.Name(tag))
217 od.L0.ParentFile = md.L0.ParentFile
218 od.L0.Parent = md
219 od.L0.Index = n
220
221 for _, t := range oneofWrappers {
222 if t.Implements(f.Type) {
223 f := t.Elem().Field(0)
224 if tag := f.Tag.Get("protobuf"); tag != "" {
225 aberrantAppendField(md, f.Type, tag, "", "")
226 fd := &md.L2.Fields.List[len(md.L2.Fields.List)-1]
227 fd.L1.ContainingOneof = od
228 od.L1.Fields.List = append(od.L1.Fields.List, fd)
229 }
230 }
231 }
232 }
233 }
234
Joe Tsai851185d2019-07-01 13:45:52 -0700235 return md
236}
237
Joe Tsaiea5ada12019-09-04 22:41:40 -0700238func aberrantDeriveMessageName(t reflect.Type, name pref.FullName) pref.FullName {
239 if name.IsValid() {
240 return name
241 }
Joe Tsaie87cf532019-09-10 12:20:00 -0700242 func() {
243 defer func() { recover() }() // swallow possible nil panics
Damien Neil47d58932019-09-30 15:34:27 -0700244 if m, ok := reflect.Zero(t).Interface().(interface{ XXX_MessageName() string }); ok {
Joe Tsaie87cf532019-09-10 12:20:00 -0700245 name = pref.FullName(m.XXX_MessageName())
Joe Tsaiea5ada12019-09-04 22:41:40 -0700246 }
Joe Tsaie87cf532019-09-10 12:20:00 -0700247 }()
248 if name.IsValid() {
249 return name
Joe Tsaiea5ada12019-09-04 22:41:40 -0700250 }
Damien Neil47d58932019-09-30 15:34:27 -0700251 if t.Kind() == reflect.Ptr {
252 t = t.Elem()
253 }
Joe Tsaiea5ada12019-09-04 22:41:40 -0700254 return aberrantDeriveFullName(t)
255}
256
Joe Tsai851185d2019-07-01 13:45:52 -0700257func aberrantAppendField(md *filedesc.Message, goType reflect.Type, tag, tagKey, tagVal string) {
258 t := goType
259 isOptional := t.Kind() == reflect.Ptr && t.Elem().Kind() != reflect.Struct
260 isRepeated := t.Kind() == reflect.Slice && t.Elem().Kind() != reflect.Uint8
261 if isOptional || isRepeated {
262 t = t.Elem()
263 }
264 fd := ptag.Unmarshal(tag, t, placeholderEnumValues{}).(*filedesc.Field)
265
266 // Append field descriptor to the message.
267 n := len(md.L2.Fields.List)
268 md.L2.Fields.List = append(md.L2.Fields.List, *fd)
269 fd = &md.L2.Fields.List[n]
270 fd.L0.FullName = md.FullName().Append(fd.Name())
271 fd.L0.ParentFile = md.L0.ParentFile
272 fd.L0.Parent = md
273 fd.L0.Index = n
274
275 if fd.L1.IsWeak || fd.L1.HasPacked {
276 fd.L1.Options = func() pref.ProtoMessage {
277 opts := descopts.Field.ProtoReflect().New()
278 if fd.L1.IsWeak {
Joe Tsai84177c92019-09-17 13:38:48 -0700279 opts.Set(opts.Descriptor().Fields().ByName("weak"), protoreflect.ValueOfBool(true))
Joe Tsai851185d2019-07-01 13:45:52 -0700280 }
281 if fd.L1.HasPacked {
Joe Tsai84177c92019-09-17 13:38:48 -0700282 opts.Set(opts.Descriptor().Fields().ByName("packed"), protoreflect.ValueOfBool(fd.L1.IsPacked))
Joe Tsai851185d2019-07-01 13:45:52 -0700283 }
284 return opts.Interface()
285 }
286 }
287
288 // Populate Enum and Message.
289 if fd.Enum() == nil && fd.Kind() == pref.EnumKind {
290 switch v := reflect.Zero(t).Interface().(type) {
291 case pref.Enum:
292 fd.L1.Enum = v.Descriptor()
293 default:
294 fd.L1.Enum = LegacyLoadEnumDesc(t)
295 }
296 }
297 if fd.Message() == nil && (fd.Kind() == pref.MessageKind || fd.Kind() == pref.GroupKind) {
298 switch v := reflect.Zero(t).Interface().(type) {
299 case pref.ProtoMessage:
300 fd.L1.Message = v.ProtoReflect().Descriptor()
Joe Tsai32e8a522019-07-02 10:51:24 -0700301 case messageV1:
302 fd.L1.Message = LegacyLoadMessageDesc(t)
Joe Tsai851185d2019-07-01 13:45:52 -0700303 default:
304 if t.Kind() == reflect.Map {
305 n := len(md.L1.Messages.List)
306 md.L1.Messages.List = append(md.L1.Messages.List, filedesc.Message{L2: new(filedesc.MessageL2)})
307 md2 := &md.L1.Messages.List[n]
Joe Tsai97a87392019-07-07 01:49:59 -0700308 md2.L0.FullName = md.FullName().Append(pref.Name(strs.MapEntryName(string(fd.Name()))))
Joe Tsai851185d2019-07-01 13:45:52 -0700309 md2.L0.ParentFile = md.L0.ParentFile
310 md2.L0.Parent = md
311 md2.L0.Index = n
312
Damien Neile9187322019-11-07 15:30:44 -0800313 md2.L1.IsMapEntry = true
Joe Tsai851185d2019-07-01 13:45:52 -0700314 md2.L2.Options = func() pref.ProtoMessage {
315 opts := descopts.Message.ProtoReflect().New()
Joe Tsai84177c92019-09-17 13:38:48 -0700316 opts.Set(opts.Descriptor().Fields().ByName("map_entry"), protoreflect.ValueOfBool(true))
Joe Tsai851185d2019-07-01 13:45:52 -0700317 return opts.Interface()
318 }
319
320 aberrantAppendField(md2, t.Key(), tagKey, "", "")
321 aberrantAppendField(md2, t.Elem(), tagVal, "", "")
322
323 fd.L1.Message = md2
324 break
325 }
Joe Tsaiea5ada12019-09-04 22:41:40 -0700326 fd.L1.Message = aberrantLoadMessageDescReentrant(t, "")
Joe Tsai851185d2019-07-01 13:45:52 -0700327 }
328 }
329}
330
331type placeholderEnumValues struct {
332 protoreflect.EnumValueDescriptors
333}
334
335func (placeholderEnumValues) ByNumber(n pref.EnumNumber) pref.EnumValueDescriptor {
336 return filedesc.PlaceholderEnumValue(pref.FullName(fmt.Sprintf("UNKNOWN_%d", n)))
337}
Damien Neil47d58932019-09-30 15:34:27 -0700338
339// legacyMarshaler is the proto.Marshaler interface superseded by protoiface.Methoder.
340type legacyMarshaler interface {
341 Marshal() ([]byte, error)
342}
343
344// legacyUnmarshaler is the proto.Unmarshaler interface superseded by protoiface.Methoder.
345type legacyUnmarshaler interface {
346 Unmarshal([]byte) error
347}
348
349var legacyProtoMethods = &piface.Methods{
350 Size: legacySize,
351 MarshalAppend: legacyMarshalAppend,
352 Unmarshal: legacyUnmarshal,
Damien Neilc7f2bee2019-11-06 15:29:05 -0800353
354 // We have no way to tell whether the type's Marshal method
355 // supports deterministic serialization or not, but this
356 // preserves the v1 implementation's behavior of always
357 // calling Marshal methods when present.
358 Flags: piface.SupportMarshalDeterministic,
Damien Neil47d58932019-09-30 15:34:27 -0700359}
360
361func legacySize(m protoreflect.Message, opts piface.MarshalOptions) int {
362 b, _ := legacyMarshalAppend(nil, m, opts)
363 return len(b)
364}
365
366func legacyMarshalAppend(b []byte, m protoreflect.Message, opts piface.MarshalOptions) ([]byte, error) {
367 v := m.(unwrapper).protoUnwrap()
368 marshaler, ok := v.(legacyMarshaler)
369 if !ok {
370 return nil, errors.New("%T does not implement Marshal", v)
371 }
372 out, err := marshaler.Marshal()
373 if b != nil {
374 out = append(b, out...)
375 }
376 return out, err
377}
378
379func legacyUnmarshal(b []byte, m protoreflect.Message, opts piface.UnmarshalOptions) error {
380 v := m.(unwrapper).protoUnwrap()
381 unmarshaler, ok := v.(legacyUnmarshaler)
382 if !ok {
383 return errors.New("%T does not implement Marshal", v)
384 }
385 return unmarshaler.Unmarshal(b)
386}
387
388// aberrantMessageType implements MessageType for all types other than pointer-to-struct.
389type aberrantMessageType struct {
390 t reflect.Type
391}
392
393func (mt aberrantMessageType) New() pref.Message {
394 return aberrantMessage{reflect.Zero(mt.t)}
395}
396func (mt aberrantMessageType) Zero() pref.Message {
397 return aberrantMessage{reflect.Zero(mt.t)}
398}
399func (mt aberrantMessageType) GoType() reflect.Type {
400 return mt.t
401}
402func (mt aberrantMessageType) Descriptor() pref.MessageDescriptor {
403 return LegacyLoadMessageDesc(mt.t)
404}
405
406// aberrantMessage implements Message for all types other than pointer-to-struct.
407//
408// When the underlying type implements legacyMarshaler or legacyUnmarshaler,
409// the aberrant Message can be marshaled or unmarshaled. Otherwise, there is
410// not much that can be done with values of this type.
411type aberrantMessage struct {
412 v reflect.Value
413}
414
415func (m aberrantMessage) ProtoReflect() pref.Message {
416 return m
417}
418
419func (m aberrantMessage) Descriptor() pref.MessageDescriptor {
420 return LegacyLoadMessageDesc(m.v.Type())
421}
422func (m aberrantMessage) Type() pref.MessageType {
423 return aberrantMessageType{m.v.Type()}
424}
425func (m aberrantMessage) New() pref.Message {
426 return aberrantMessage{reflect.Zero(m.v.Type())}
427}
428func (m aberrantMessage) Interface() pref.ProtoMessage {
429 return m
430}
431func (m aberrantMessage) Range(f func(pref.FieldDescriptor, pref.Value) bool) {
432}
433func (m aberrantMessage) Has(pref.FieldDescriptor) bool {
434 panic("invalid field descriptor")
435}
436func (m aberrantMessage) Clear(pref.FieldDescriptor) {
437 panic("invalid field descriptor")
438}
439func (m aberrantMessage) Get(pref.FieldDescriptor) pref.Value {
440 panic("invalid field descriptor")
441}
442func (m aberrantMessage) Set(pref.FieldDescriptor, pref.Value) {
443 panic("invalid field descriptor")
444}
445func (m aberrantMessage) Mutable(pref.FieldDescriptor) pref.Value {
446 panic("invalid field descriptor")
447}
448func (m aberrantMessage) NewField(pref.FieldDescriptor) pref.Value {
449 panic("invalid field descriptor")
450}
451func (m aberrantMessage) WhichOneof(pref.OneofDescriptor) pref.FieldDescriptor {
452 panic("invalid oneof descriptor")
453}
454func (m aberrantMessage) GetUnknown() pref.RawFields {
455 return nil
456}
457func (m aberrantMessage) SetUnknown(pref.RawFields) {
458 // SetUnknown discards its input on messages which don't support unknown field storage.
459}
460func (m aberrantMessage) ProtoMethods() *piface.Methods {
461 return legacyProtoMethods
462}
463func (m aberrantMessage) protoUnwrap() interface{} {
464 return m.v.Interface()
465}