1// Copyright 2019 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
5// Package dynamicpb creates protocol buffer messages using runtime type information.
6package dynamicpb
7
8import (
9	"math"
10
11	"google.golang.org/protobuf/internal/errors"
12	pref "google.golang.org/protobuf/reflect/protoreflect"
13	"google.golang.org/protobuf/runtime/protoiface"
14	"google.golang.org/protobuf/runtime/protoimpl"
15)
16
17// enum is a dynamic protoreflect.Enum.
18type enum struct {
19	num pref.EnumNumber
20	typ pref.EnumType
21}
22
23func (e enum) Descriptor() pref.EnumDescriptor { return e.typ.Descriptor() }
24func (e enum) Type() pref.EnumType             { return e.typ }
25func (e enum) Number() pref.EnumNumber         { return e.num }
26
27// enumType is a dynamic protoreflect.EnumType.
28type enumType struct {
29	desc pref.EnumDescriptor
30}
31
32// NewEnumType creates a new EnumType with the provided descriptor.
33//
34// EnumTypes created by this package are equal if their descriptors are equal.
35// That is, if ed1 == ed2, then NewEnumType(ed1) == NewEnumType(ed2).
36//
37// Enum values created by the EnumType are equal if their numbers are equal.
38func NewEnumType(desc pref.EnumDescriptor) pref.EnumType {
39	return enumType{desc}
40}
41
42func (et enumType) New(n pref.EnumNumber) pref.Enum { return enum{n, et} }
43func (et enumType) Descriptor() pref.EnumDescriptor { return et.desc }
44
45// extensionType is a dynamic protoreflect.ExtensionType.
46type extensionType struct {
47	desc extensionTypeDescriptor
48}
49
50// A Message is a dynamically constructed protocol buffer message.
51//
52// Message implements the proto.Message interface, and may be used with all
53// standard proto package functions such as Marshal, Unmarshal, and so forth.
54//
55// Message also implements the protoreflect.Message interface. See the protoreflect
56// package documentation for that interface for how to get and set fields and
57// otherwise interact with the contents of a Message.
58//
59// Reflection API functions which construct messages, such as NewField,
60// return new dynamic messages of the appropriate type. Functions which take
61// messages, such as Set for a message-value field, will accept any message
62// with a compatible type.
63//
64// Operations which modify a Message are not safe for concurrent use.
65type Message struct {
66	typ     messageType
67	known   map[pref.FieldNumber]pref.Value
68	ext     map[pref.FieldNumber]pref.FieldDescriptor
69	unknown pref.RawFields
70}
71
72var (
73	_ pref.Message         = (*Message)(nil)
74	_ pref.ProtoMessage    = (*Message)(nil)
75	_ protoiface.MessageV1 = (*Message)(nil)
76)
77
78// NewMessage creates a new message with the provided descriptor.
79func NewMessage(desc pref.MessageDescriptor) *Message {
80	return &Message{
81		typ:   messageType{desc},
82		known: make(map[pref.FieldNumber]pref.Value),
83		ext:   make(map[pref.FieldNumber]pref.FieldDescriptor),
84	}
85}
86
87// ProtoMessage implements the legacy message interface.
88func (m *Message) ProtoMessage() {}
89
90// ProtoReflect implements the protoreflect.ProtoMessage interface.
91func (m *Message) ProtoReflect() pref.Message {
92	return m
93}
94
95// String returns a string representation of a message.
96func (m *Message) String() string {
97	return protoimpl.X.MessageStringOf(m)
98}
99
100// Reset clears the message to be empty, but preserves the dynamic message type.
101func (m *Message) Reset() {
102	m.known = make(map[pref.FieldNumber]pref.Value)
103	m.ext = make(map[pref.FieldNumber]pref.FieldDescriptor)
104	m.unknown = nil
105}
106
107// Descriptor returns the message descriptor.
108func (m *Message) Descriptor() pref.MessageDescriptor {
109	return m.typ.desc
110}
111
112// Type returns the message type.
113func (m *Message) Type() pref.MessageType {
114	return m.typ
115}
116
117// New returns a newly allocated empty message with the same descriptor.
118// See protoreflect.Message for details.
119func (m *Message) New() pref.Message {
120	return m.Type().New()
121}
122
123// Interface returns the message.
124// See protoreflect.Message for details.
125func (m *Message) Interface() pref.ProtoMessage {
126	return m
127}
128
129// ProtoMethods is an internal detail of the protoreflect.Message interface.
130// Users should never call this directly.
131func (m *Message) ProtoMethods() *protoiface.Methods {
132	return nil
133}
134
135// Range visits every populated field in undefined order.
136// See protoreflect.Message for details.
137func (m *Message) Range(f func(pref.FieldDescriptor, pref.Value) bool) {
138	for num, v := range m.known {
139		fd := m.ext[num]
140		if fd == nil {
141			fd = m.Descriptor().Fields().ByNumber(num)
142		}
143		if !isSet(fd, v) {
144			continue
145		}
146		if !f(fd, v) {
147			return
148		}
149	}
150}
151
152// Has reports whether a field is populated.
153// See protoreflect.Message for details.
154func (m *Message) Has(fd pref.FieldDescriptor) bool {
155	m.checkField(fd)
156	if fd.IsExtension() && m.ext[fd.Number()] != fd {
157		return false
158	}
159	v, ok := m.known[fd.Number()]
160	if !ok {
161		return false
162	}
163	return isSet(fd, v)
164}
165
166// Clear clears a field.
167// See protoreflect.Message for details.
168func (m *Message) Clear(fd pref.FieldDescriptor) {
169	m.checkField(fd)
170	num := fd.Number()
171	delete(m.known, num)
172	delete(m.ext, num)
173}
174
175// Get returns the value of a field.
176// See protoreflect.Message for details.
177func (m *Message) Get(fd pref.FieldDescriptor) pref.Value {
178	m.checkField(fd)
179	num := fd.Number()
180	if fd.IsExtension() {
181		if fd != m.ext[num] {
182			return fd.(pref.ExtensionTypeDescriptor).Type().Zero()
183		}
184		return m.known[num]
185	}
186	if v, ok := m.known[num]; ok {
187		switch {
188		case fd.IsMap():
189			if v.Map().Len() > 0 {
190				return v
191			}
192		case fd.IsList():
193			if v.List().Len() > 0 {
194				return v
195			}
196		default:
197			return v
198		}
199	}
200	switch {
201	case fd.IsMap():
202		return pref.ValueOfMap(&dynamicMap{desc: fd})
203	case fd.IsList():
204		return pref.ValueOfList(emptyList{desc: fd})
205	case fd.Message() != nil:
206		return pref.ValueOfMessage(&Message{typ: messageType{fd.Message()}})
207	case fd.Kind() == pref.BytesKind:
208		return pref.ValueOfBytes(append([]byte(nil), fd.Default().Bytes()...))
209	default:
210		return fd.Default()
211	}
212}
213
214// Mutable returns a mutable reference to a repeated, map, or message field.
215// See protoreflect.Message for details.
216func (m *Message) Mutable(fd pref.FieldDescriptor) pref.Value {
217	m.checkField(fd)
218	if !fd.IsMap() && !fd.IsList() && fd.Message() == nil {
219		panic(errors.New("%v: getting mutable reference to non-composite type", fd.FullName()))
220	}
221	if m.known == nil {
222		panic(errors.New("%v: modification of read-only message", fd.FullName()))
223	}
224	num := fd.Number()
225	if fd.IsExtension() {
226		if fd != m.ext[num] {
227			m.ext[num] = fd
228			m.known[num] = fd.(pref.ExtensionTypeDescriptor).Type().New()
229		}
230		return m.known[num]
231	}
232	if v, ok := m.known[num]; ok {
233		return v
234	}
235	m.clearOtherOneofFields(fd)
236	m.known[num] = m.NewField(fd)
237	if fd.IsExtension() {
238		m.ext[num] = fd
239	}
240	return m.known[num]
241}
242
243// Set stores a value in a field.
244// See protoreflect.Message for details.
245func (m *Message) Set(fd pref.FieldDescriptor, v pref.Value) {
246	m.checkField(fd)
247	if m.known == nil {
248		panic(errors.New("%v: modification of read-only message", fd.FullName()))
249	}
250	if fd.IsExtension() {
251		isValid := true
252		switch {
253		case !fd.(pref.ExtensionTypeDescriptor).Type().IsValidValue(v):
254			isValid = false
255		case fd.IsList():
256			isValid = v.List().IsValid()
257		case fd.IsMap():
258			isValid = v.Map().IsValid()
259		case fd.Message() != nil:
260			isValid = v.Message().IsValid()
261		}
262		if !isValid {
263			panic(errors.New("%v: assigning invalid type %T", fd.FullName(), v.Interface()))
264		}
265		m.ext[fd.Number()] = fd
266	} else {
267		typecheck(fd, v)
268	}
269	m.clearOtherOneofFields(fd)
270	m.known[fd.Number()] = v
271}
272
273func (m *Message) clearOtherOneofFields(fd pref.FieldDescriptor) {
274	od := fd.ContainingOneof()
275	if od == nil {
276		return
277	}
278	num := fd.Number()
279	for i := 0; i < od.Fields().Len(); i++ {
280		if n := od.Fields().Get(i).Number(); n != num {
281			delete(m.known, n)
282		}
283	}
284}
285
286// NewField returns a new value for assignable to the field of a given descriptor.
287// See protoreflect.Message for details.
288func (m *Message) NewField(fd pref.FieldDescriptor) pref.Value {
289	m.checkField(fd)
290	switch {
291	case fd.IsExtension():
292		return fd.(pref.ExtensionTypeDescriptor).Type().New()
293	case fd.IsMap():
294		return pref.ValueOfMap(&dynamicMap{
295			desc: fd,
296			mapv: make(map[interface{}]pref.Value),
297		})
298	case fd.IsList():
299		return pref.ValueOfList(&dynamicList{desc: fd})
300	case fd.Message() != nil:
301		return pref.ValueOfMessage(NewMessage(fd.Message()).ProtoReflect())
302	default:
303		return fd.Default()
304	}
305}
306
307// WhichOneof reports which field in a oneof is populated, returning nil if none are populated.
308// See protoreflect.Message for details.
309func (m *Message) WhichOneof(od pref.OneofDescriptor) pref.FieldDescriptor {
310	for i := 0; i < od.Fields().Len(); i++ {
311		fd := od.Fields().Get(i)
312		if m.Has(fd) {
313			return fd
314		}
315	}
316	return nil
317}
318
319// GetUnknown returns the raw unknown fields.
320// See protoreflect.Message for details.
321func (m *Message) GetUnknown() pref.RawFields {
322	return m.unknown
323}
324
325// SetUnknown sets the raw unknown fields.
326// See protoreflect.Message for details.
327func (m *Message) SetUnknown(r pref.RawFields) {
328	if m.known == nil {
329		panic(errors.New("%v: modification of read-only message", m.typ.desc.FullName()))
330	}
331	m.unknown = r
332}
333
334// IsValid reports whether the message is valid.
335// See protoreflect.Message for details.
336func (m *Message) IsValid() bool {
337	return m.known != nil
338}
339
340func (m *Message) checkField(fd pref.FieldDescriptor) {
341	if fd.IsExtension() && fd.ContainingMessage().FullName() == m.Descriptor().FullName() {
342		if _, ok := fd.(pref.ExtensionTypeDescriptor); !ok {
343			panic(errors.New("%v: extension field descriptor does not implement ExtensionTypeDescriptor", fd.FullName()))
344		}
345		return
346	}
347	if fd.Parent() == m.Descriptor() {
348		return
349	}
350	fields := m.Descriptor().Fields()
351	index := fd.Index()
352	if index >= fields.Len() || fields.Get(index) != fd {
353		panic(errors.New("%v: field descriptor does not belong to this message", fd.FullName()))
354	}
355}
356
357type messageType struct {
358	desc pref.MessageDescriptor
359}
360
361// NewMessageType creates a new MessageType with the provided descriptor.
362//
363// MessageTypes created by this package are equal if their descriptors are equal.
364// That is, if md1 == md2, then NewMessageType(md1) == NewMessageType(md2).
365func NewMessageType(desc pref.MessageDescriptor) pref.MessageType {
366	return messageType{desc}
367}
368
369func (mt messageType) New() pref.Message                  { return NewMessage(mt.desc) }
370func (mt messageType) Zero() pref.Message                 { return &Message{typ: messageType{mt.desc}} }
371func (mt messageType) Descriptor() pref.MessageDescriptor { return mt.desc }
372func (mt messageType) Enum(i int) pref.EnumType {
373	if ed := mt.desc.Fields().Get(i).Enum(); ed != nil {
374		return NewEnumType(ed)
375	}
376	return nil
377}
378func (mt messageType) Message(i int) pref.MessageType {
379	if md := mt.desc.Fields().Get(i).Message(); md != nil {
380		return NewMessageType(md)
381	}
382	return nil
383}
384
385type emptyList struct {
386	desc pref.FieldDescriptor
387}
388
389func (x emptyList) Len() int                  { return 0 }
390func (x emptyList) Get(n int) pref.Value      { panic(errors.New("out of range")) }
391func (x emptyList) Set(n int, v pref.Value)   { panic(errors.New("modification of immutable list")) }
392func (x emptyList) Append(v pref.Value)       { panic(errors.New("modification of immutable list")) }
393func (x emptyList) AppendMutable() pref.Value { panic(errors.New("modification of immutable list")) }
394func (x emptyList) Truncate(n int)            { panic(errors.New("modification of immutable list")) }
395func (x emptyList) NewElement() pref.Value    { return newListEntry(x.desc) }
396func (x emptyList) IsValid() bool             { return false }
397
398type dynamicList struct {
399	desc pref.FieldDescriptor
400	list []pref.Value
401}
402
403func (x *dynamicList) Len() int {
404	return len(x.list)
405}
406
407func (x *dynamicList) Get(n int) pref.Value {
408	return x.list[n]
409}
410
411func (x *dynamicList) Set(n int, v pref.Value) {
412	typecheckSingular(x.desc, v)
413	x.list[n] = v
414}
415
416func (x *dynamicList) Append(v pref.Value) {
417	typecheckSingular(x.desc, v)
418	x.list = append(x.list, v)
419}
420
421func (x *dynamicList) AppendMutable() pref.Value {
422	if x.desc.Message() == nil {
423		panic(errors.New("%v: invalid AppendMutable on list with non-message type", x.desc.FullName()))
424	}
425	v := x.NewElement()
426	x.Append(v)
427	return v
428}
429
430func (x *dynamicList) Truncate(n int) {
431	// Zero truncated elements to avoid keeping data live.
432	for i := n; i < len(x.list); i++ {
433		x.list[i] = pref.Value{}
434	}
435	x.list = x.list[:n]
436}
437
438func (x *dynamicList) NewElement() pref.Value {
439	return newListEntry(x.desc)
440}
441
442func (x *dynamicList) IsValid() bool {
443	return true
444}
445
446type dynamicMap struct {
447	desc pref.FieldDescriptor
448	mapv map[interface{}]pref.Value
449}
450
451func (x *dynamicMap) Get(k pref.MapKey) pref.Value { return x.mapv[k.Interface()] }
452func (x *dynamicMap) Set(k pref.MapKey, v pref.Value) {
453	typecheckSingular(x.desc.MapKey(), k.Value())
454	typecheckSingular(x.desc.MapValue(), v)
455	x.mapv[k.Interface()] = v
456}
457func (x *dynamicMap) Has(k pref.MapKey) bool { return x.Get(k).IsValid() }
458func (x *dynamicMap) Clear(k pref.MapKey)    { delete(x.mapv, k.Interface()) }
459func (x *dynamicMap) Mutable(k pref.MapKey) pref.Value {
460	if x.desc.MapValue().Message() == nil {
461		panic(errors.New("%v: invalid Mutable on map with non-message value type", x.desc.FullName()))
462	}
463	v := x.Get(k)
464	if !v.IsValid() {
465		v = x.NewValue()
466		x.Set(k, v)
467	}
468	return v
469}
470func (x *dynamicMap) Len() int { return len(x.mapv) }
471func (x *dynamicMap) NewValue() pref.Value {
472	if md := x.desc.MapValue().Message(); md != nil {
473		return pref.ValueOfMessage(NewMessage(md).ProtoReflect())
474	}
475	return x.desc.MapValue().Default()
476}
477func (x *dynamicMap) IsValid() bool {
478	return x.mapv != nil
479}
480
481func (x *dynamicMap) Range(f func(pref.MapKey, pref.Value) bool) {
482	for k, v := range x.mapv {
483		if !f(pref.ValueOf(k).MapKey(), v) {
484			return
485		}
486	}
487}
488
489func isSet(fd pref.FieldDescriptor, v pref.Value) bool {
490	switch {
491	case fd.IsMap():
492		return v.Map().Len() > 0
493	case fd.IsList():
494		return v.List().Len() > 0
495	case fd.ContainingOneof() != nil:
496		return true
497	case fd.Syntax() == pref.Proto3 && !fd.IsExtension():
498		switch fd.Kind() {
499		case pref.BoolKind:
500			return v.Bool()
501		case pref.EnumKind:
502			return v.Enum() != 0
503		case pref.Int32Kind, pref.Sint32Kind, pref.Int64Kind, pref.Sint64Kind, pref.Sfixed32Kind, pref.Sfixed64Kind:
504			return v.Int() != 0
505		case pref.Uint32Kind, pref.Uint64Kind, pref.Fixed32Kind, pref.Fixed64Kind:
506			return v.Uint() != 0
507		case pref.FloatKind, pref.DoubleKind:
508			return v.Float() != 0 || math.Signbit(v.Float())
509		case pref.StringKind:
510			return v.String() != ""
511		case pref.BytesKind:
512			return len(v.Bytes()) > 0
513		}
514	}
515	return true
516}
517
518func typecheck(fd pref.FieldDescriptor, v pref.Value) {
519	if err := typeIsValid(fd, v); err != nil {
520		panic(err)
521	}
522}
523
524func typeIsValid(fd pref.FieldDescriptor, v pref.Value) error {
525	switch {
526	case !v.IsValid():
527		return errors.New("%v: assigning invalid value", fd.FullName())
528	case fd.IsMap():
529		if mapv, ok := v.Interface().(*dynamicMap); !ok || mapv.desc != fd || !mapv.IsValid() {
530			return errors.New("%v: assigning invalid type %T", fd.FullName(), v.Interface())
531		}
532		return nil
533	case fd.IsList():
534		switch list := v.Interface().(type) {
535		case *dynamicList:
536			if list.desc == fd && list.IsValid() {
537				return nil
538			}
539		case emptyList:
540			if list.desc == fd && list.IsValid() {
541				return nil
542			}
543		}
544		return errors.New("%v: assigning invalid type %T", fd.FullName(), v.Interface())
545	default:
546		return singularTypeIsValid(fd, v)
547	}
548}
549
550func typecheckSingular(fd pref.FieldDescriptor, v pref.Value) {
551	if err := singularTypeIsValid(fd, v); err != nil {
552		panic(err)
553	}
554}
555
556func singularTypeIsValid(fd pref.FieldDescriptor, v pref.Value) error {
557	vi := v.Interface()
558	var ok bool
559	switch fd.Kind() {
560	case pref.BoolKind:
561		_, ok = vi.(bool)
562	case pref.EnumKind:
563		// We could check against the valid set of enum values, but do not.
564		_, ok = vi.(pref.EnumNumber)
565	case pref.Int32Kind, pref.Sint32Kind, pref.Sfixed32Kind:
566		_, ok = vi.(int32)
567	case pref.Uint32Kind, pref.Fixed32Kind:
568		_, ok = vi.(uint32)
569	case pref.Int64Kind, pref.Sint64Kind, pref.Sfixed64Kind:
570		_, ok = vi.(int64)
571	case pref.Uint64Kind, pref.Fixed64Kind:
572		_, ok = vi.(uint64)
573	case pref.FloatKind:
574		_, ok = vi.(float32)
575	case pref.DoubleKind:
576		_, ok = vi.(float64)
577	case pref.StringKind:
578		_, ok = vi.(string)
579	case pref.BytesKind:
580		_, ok = vi.([]byte)
581	case pref.MessageKind, pref.GroupKind:
582		var m pref.Message
583		m, ok = vi.(pref.Message)
584		if ok && m.Descriptor().FullName() != fd.Message().FullName() {
585			return errors.New("%v: assigning invalid message type %v", fd.FullName(), m.Descriptor().FullName())
586		}
587		if dm, ok := vi.(*Message); ok && dm.known == nil {
588			return errors.New("%v: assigning invalid zero-value message", fd.FullName())
589		}
590	}
591	if !ok {
592		return errors.New("%v: assigning invalid type %T", fd.FullName(), v.Interface())
593	}
594	return nil
595}
596
597func newListEntry(fd pref.FieldDescriptor) pref.Value {
598	switch fd.Kind() {
599	case pref.BoolKind:
600		return pref.ValueOfBool(false)
601	case pref.EnumKind:
602		return pref.ValueOfEnum(fd.Enum().Values().Get(0).Number())
603	case pref.Int32Kind, pref.Sint32Kind, pref.Sfixed32Kind:
604		return pref.ValueOfInt32(0)
605	case pref.Uint32Kind, pref.Fixed32Kind:
606		return pref.ValueOfUint32(0)
607	case pref.Int64Kind, pref.Sint64Kind, pref.Sfixed64Kind:
608		return pref.ValueOfInt64(0)
609	case pref.Uint64Kind, pref.Fixed64Kind:
610		return pref.ValueOfUint64(0)
611	case pref.FloatKind:
612		return pref.ValueOfFloat32(0)
613	case pref.DoubleKind:
614		return pref.ValueOfFloat64(0)
615	case pref.StringKind:
616		return pref.ValueOfString("")
617	case pref.BytesKind:
618		return pref.ValueOfBytes(nil)
619	case pref.MessageKind, pref.GroupKind:
620		return pref.ValueOfMessage(NewMessage(fd.Message()).ProtoReflect())
621	}
622	panic(errors.New("%v: unknown kind %v", fd.FullName(), fd.Kind()))
623}
624
625// NewExtensionType creates a new ExtensionType with the provided descriptor.
626//
627// Dynamic ExtensionTypes with the same descriptor compare as equal. That is,
628// if xd1 == xd2, then NewExtensionType(xd1) == NewExtensionType(xd2).
629//
630// The InterfaceOf and ValueOf methods of the extension type are defined as:
631//
632//	func (xt extensionType) ValueOf(iv interface{}) protoreflect.Value {
633//		return protoreflect.ValueOf(iv)
634//	}
635//
636//	func (xt extensionType) InterfaceOf(v protoreflect.Value) interface{} {
637//		return v.Interface()
638//	}
639//
640// The Go type used by the proto.GetExtension and proto.SetExtension functions
641// is determined by these methods, and is therefore equivalent to the Go type
642// used to represent a protoreflect.Value. See the protoreflect.Value
643// documentation for more details.
644func NewExtensionType(desc pref.ExtensionDescriptor) pref.ExtensionType {
645	if xt, ok := desc.(pref.ExtensionTypeDescriptor); ok {
646		desc = xt.Descriptor()
647	}
648	return extensionType{extensionTypeDescriptor{desc}}
649}
650
651func (xt extensionType) New() pref.Value {
652	switch {
653	case xt.desc.IsMap():
654		return pref.ValueOfMap(&dynamicMap{
655			desc: xt.desc,
656			mapv: make(map[interface{}]pref.Value),
657		})
658	case xt.desc.IsList():
659		return pref.ValueOfList(&dynamicList{desc: xt.desc})
660	case xt.desc.Message() != nil:
661		return pref.ValueOfMessage(NewMessage(xt.desc.Message()))
662	default:
663		return xt.desc.Default()
664	}
665}
666
667func (xt extensionType) Zero() pref.Value {
668	switch {
669	case xt.desc.IsMap():
670		return pref.ValueOfMap(&dynamicMap{desc: xt.desc})
671	case xt.desc.Cardinality() == pref.Repeated:
672		return pref.ValueOfList(emptyList{desc: xt.desc})
673	case xt.desc.Message() != nil:
674		return pref.ValueOfMessage(&Message{typ: messageType{xt.desc.Message()}})
675	default:
676		return xt.desc.Default()
677	}
678}
679
680func (xt extensionType) TypeDescriptor() pref.ExtensionTypeDescriptor {
681	return xt.desc
682}
683
684func (xt extensionType) ValueOf(iv interface{}) pref.Value {
685	v := pref.ValueOf(iv)
686	typecheck(xt.desc, v)
687	return v
688}
689
690func (xt extensionType) InterfaceOf(v pref.Value) interface{} {
691	typecheck(xt.desc, v)
692	return v.Interface()
693}
694
695func (xt extensionType) IsValidInterface(iv interface{}) bool {
696	return typeIsValid(xt.desc, pref.ValueOf(iv)) == nil
697}
698
699func (xt extensionType) IsValidValue(v pref.Value) bool {
700	return typeIsValid(xt.desc, v) == nil
701}
702
703type extensionTypeDescriptor struct {
704	pref.ExtensionDescriptor
705}
706
707func (xt extensionTypeDescriptor) Type() pref.ExtensionType {
708	return extensionType{xt}
709}
710
711func (xt extensionTypeDescriptor) Descriptor() pref.ExtensionDescriptor {
712	return xt.ExtensionDescriptor
713}
714