1
// Go support for Protocol Buffers - Google's data interchange format
3
// Copyright 2010 The Go Authors. All rights reserved.
4
// https://github.com/golang/protobuf
6
// Redistribution and use in source and binary forms, with or without
7
// modification, are permitted provided that the following conditions are
10
// * Redistributions of source code must retain the above copyright
11
// notice, this list of conditions and the following disclaimer.
12
// * Redistributions in binary form must reproduce the above
13
// copyright notice, this list of conditions and the following disclaimer
14
// in the documentation and/or other materials provided with the
16
// * Neither the name of Google Inc. nor the names of its
17
// contributors may be used to endorse or promote products derived from
18
// this software without specific prior written permission.
20
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35
* Types and routines for supporting protocol buffer extensions.
47
// ErrMissingExtension is the error returned by GetExtension if the named extension is not in the message.
48
var ErrMissingExtension = errors.New("proto: missing extension")
50
// ExtensionRange represents a range of message extensions for a protocol buffer.
51
// Used in code generated by the protocol compiler.
52
type ExtensionRange struct {
53
Start, End int32 // both inclusive
56
// extendableProto is an interface implemented by any protocol buffer generated by the current
57
// proto compiler that may be extended.
58
type extendableProto interface {
60
ExtensionRangeArray() []ExtensionRange
61
extensionsWrite() map[int32]Extension
62
extensionsRead() (map[int32]Extension, sync.Locker)
65
// extendableProtoV1 is an interface implemented by a protocol buffer generated by the previous
66
// version of the proto compiler that may be extended.
67
type extendableProtoV1 interface {
69
ExtensionRangeArray() []ExtensionRange
70
ExtensionMap() map[int32]Extension
73
// extensionAdapter is a wrapper around extendableProtoV1 that implements extendableProto.
74
type extensionAdapter struct {
78
func (e extensionAdapter) extensionsWrite() map[int32]Extension {
79
return e.ExtensionMap()
82
func (e extensionAdapter) extensionsRead() (map[int32]Extension, sync.Locker) {
83
return e.ExtensionMap(), notLocker{}
86
// notLocker is a sync.Locker whose Lock and Unlock methods are nops.
87
type notLocker struct{}
89
func (n notLocker) Lock() {}
90
func (n notLocker) Unlock() {}
92
// extendable returns the extendableProto interface for the given generated proto message.
93
// If the proto message has the old extension format, it returns a wrapper that implements
94
// the extendableProto interface.
95
func extendable(p interface{}) (extendableProto, error) {
96
switch p := p.(type) {
99
return nil, fmt.Errorf("proto: nil %T is not extendable", p)
102
case extendableProtoV1:
104
return nil, fmt.Errorf("proto: nil %T is not extendable", p)
106
return extensionAdapter{p}, nil
107
case extensionsBytes:
108
return slowExtensionAdapter{p}, nil
110
// Don't allocate a specific error containing %T:
111
// this is the hot path for Clone and MarshalText.
112
return nil, errNotExtendable
115
var errNotExtendable = errors.New("proto: not an extendable proto.Message")
117
func isNilPtr(x interface{}) bool {
118
v := reflect.ValueOf(x)
119
return v.Kind() == reflect.Ptr && v.IsNil()
122
// XXX_InternalExtensions is an internal representation of proto extensions.
124
// Each generated message struct type embeds an anonymous XXX_InternalExtensions field,
125
// thus gaining the unexported 'extensions' method, which can be called only from the proto package.
127
// The methods of XXX_InternalExtensions are not concurrency safe in general,
128
// but calls to logically read-only methods such as has and get may be executed concurrently.
129
type XXX_InternalExtensions struct {
130
// The struct must be indirect so that if a user inadvertently copies a
131
// generated message and its embedded XXX_InternalExtensions, they
132
// avoid the mayhem of a copied mutex.
134
// The mutex serializes all logically read-only operations to p.extensionMap.
135
// It is up to the client to ensure that write operations to p.extensionMap are
136
// mutually exclusive with other accesses.
139
extensionMap map[int32]Extension
143
// extensionsWrite returns the extension map, creating it on first use.
144
func (e *XXX_InternalExtensions) extensionsWrite() map[int32]Extension {
148
extensionMap map[int32]Extension
150
e.p.extensionMap = make(map[int32]Extension)
152
return e.p.extensionMap
155
// extensionsRead returns the extensions map for read-only use. It may be nil.
156
// The caller must hold the returned mutex's lock when accessing Elements within the map.
157
func (e *XXX_InternalExtensions) extensionsRead() (map[int32]Extension, sync.Locker) {
161
return e.p.extensionMap, &e.p.mu
164
// ExtensionDesc represents an extension specification.
165
// Used in generated code from the protocol compiler.
166
type ExtensionDesc struct {
167
ExtendedType Message // nil pointer to the type that is being extended
168
ExtensionType interface{} // nil pointer to the extension type
169
Field int32 // field number
170
Name string // fully-qualified name of extension, for text formatting
171
Tag string // protobuf tag style
172
Filename string // name of the file in which the extension is defined
175
func (ed *ExtensionDesc) repeated() bool {
176
t := reflect.TypeOf(ed.ExtensionType)
177
return t.Kind() == reflect.Slice && t.Elem().Kind() != reflect.Uint8
180
// Extension represents an extension in a message.
181
type Extension struct {
182
// When an extension is stored in a message using SetExtension
183
// only desc and value are set. When the message is marshaled
184
// enc will be set to the encoded form of the message.
186
// When a message is unmarshaled and contains extensions, each
187
// extension will have only enc set. When such an extension is
188
// accessed using GetExtension (or GetExtensions) desc and value
195
// SetRawExtension is for testing only.
196
func SetRawExtension(base Message, id int32, b []byte) {
197
if ebase, ok := base.(extensionsBytes); ok {
198
clearExtension(base, id)
199
ext := ebase.GetExtensions()
200
*ext = append(*ext, b...)
203
epb, err := extendable(base)
207
extmap := epb.extensionsWrite()
208
extmap[id] = Extension{enc: b}
211
// isExtensionField returns true iff the given field number is in an extension range.
212
func isExtensionField(pb extendableProto, field int32) bool {
213
for _, er := range pb.ExtensionRangeArray() {
214
if er.Start <= field && field <= er.End {
221
// checkExtensionTypes checks that the given extension is valid for pb.
222
func checkExtensionTypes(pb extendableProto, extension *ExtensionDesc) error {
223
var pbi interface{} = pb
224
// Check the extended type.
225
if ea, ok := pbi.(extensionAdapter); ok {
226
pbi = ea.extendableProtoV1
228
if ea, ok := pbi.(slowExtensionAdapter); ok {
229
pbi = ea.extensionsBytes
231
if a, b := reflect.TypeOf(pbi), reflect.TypeOf(extension.ExtendedType); a != b {
232
return fmt.Errorf("proto: bad extended type; %v does not extend %v", b, a)
235
if !isExtensionField(pb, extension.Field) {
236
return errors.New("proto: bad extension number; not in declared ranges")
241
// extPropKey is sufficient to uniquely identify an extension.
242
type extPropKey struct {
247
var extProp = struct {
249
m map[extPropKey]*Properties
251
m: make(map[extPropKey]*Properties),
254
func extensionProperties(ed *ExtensionDesc) *Properties {
255
key := extPropKey{base: reflect.TypeOf(ed.ExtendedType), field: ed.Field}
258
if prop, ok := extProp.m[key]; ok {
265
defer extProp.Unlock()
267
if prop, ok := extProp.m[key]; ok {
271
prop := new(Properties)
272
prop.Init(reflect.TypeOf(ed.ExtensionType), "unknown_name", ed.Tag, nil)
273
extProp.m[key] = prop
277
// HasExtension returns whether the given extension is present in pb.
278
func HasExtension(pb Message, extension *ExtensionDesc) bool {
279
if epb, doki := pb.(extensionsBytes); doki {
280
ext := epb.GetExtensions()
284
tag, n := DecodeVarint(buf[o:])
285
fieldNum := int32(tag >> 3)
286
if int32(fieldNum) == extension.Field {
289
wireType := int(tag & 0x7)
291
l, err := size(buf[o:], wireType)
299
// TODO: Check types, field numbers, etc.?
300
epb, err := extendable(pb)
304
extmap, mu := epb.extensionsRead()
309
_, ok := extmap[extension.Field]
314
// ClearExtension removes the given extension from pb.
315
func ClearExtension(pb Message, extension *ExtensionDesc) {
316
clearExtension(pb, extension.Field)
319
func clearExtension(pb Message, fieldNum int32) {
320
if epb, ok := pb.(extensionsBytes); ok {
323
offset = deleteExtension(epb, fieldNum, offset)
327
epb, err := extendable(pb)
331
// TODO: Check types, field numbers, etc.?
332
extmap := epb.extensionsWrite()
333
delete(extmap, fieldNum)
336
// GetExtension retrieves a proto2 extended field from pb.
338
// If the descriptor is type complete (i.e., ExtensionDesc.ExtensionType is non-nil),
339
// then GetExtension parses the encoded field and returns a Go value of the specified type.
340
// If the field is not present, then the default value is returned (if one is specified),
341
// otherwise ErrMissingExtension is reported.
343
// If the descriptor is not type complete (i.e., ExtensionDesc.ExtensionType is nil),
344
// then GetExtension returns the raw encoded bytes of the field extension.
345
func GetExtension(pb Message, extension *ExtensionDesc) (interface{}, error) {
346
if epb, doki := pb.(extensionsBytes); doki {
347
ext := epb.GetExtensions()
348
return decodeExtensionFromBytes(extension, *ext)
351
epb, err := extendable(pb)
356
if extension.ExtendedType != nil {
357
// can only check type if this is a complete descriptor
358
if cerr := checkExtensionTypes(epb, extension); cerr != nil {
363
emap, mu := epb.extensionsRead()
365
return defaultExtensionValue(extension)
369
e, ok := emap[extension.Field]
371
// defaultExtensionValue returns the default value or
372
// ErrMissingExtension if there is no default.
373
return defaultExtensionValue(extension)
377
// Already decoded. Check the descriptor, though.
378
if e.desc != extension {
379
// This shouldn't happen. If it does, it means that
380
// GetExtension was called twice with two different
381
// descriptors with the same field number.
382
return nil, errors.New("proto: descriptor conflict")
387
if extension.ExtensionType == nil {
388
// incomplete descriptor
392
v, err := decodeExtension(e.enc, extension)
397
// Remember the decoded version and drop the encoded version.
398
// That way it is safe to mutate what we return.
402
emap[extension.Field] = e
406
// defaultExtensionValue returns the default value for extension.
407
// If no default for an extension is defined ErrMissingExtension is returned.
408
func defaultExtensionValue(extension *ExtensionDesc) (interface{}, error) {
409
if extension.ExtensionType == nil {
410
// incomplete descriptor, so no default
411
return nil, ErrMissingExtension
414
t := reflect.TypeOf(extension.ExtensionType)
415
props := extensionProperties(extension)
417
sf, _, err := fieldDefault(t, props)
422
if sf == nil || sf.value == nil {
423
// There is no default value.
424
return nil, ErrMissingExtension
427
if t.Kind() != reflect.Ptr {
428
// We do not need to return a Ptr, we can directly return sf.value.
432
// We need to return an interface{} that is a pointer to sf.value.
433
value := reflect.New(t).Elem()
434
value.Set(reflect.New(value.Type().Elem()))
435
if sf.kind == reflect.Int32 {
436
// We may have an int32 or an enum, but the underlying data is int32.
437
// Since we can't set an int32 into a non int32 reflect.value directly
438
// set it as a int32.
439
value.Elem().SetInt(int64(sf.value.(int32)))
441
value.Elem().Set(reflect.ValueOf(sf.value))
443
return value.Interface(), nil
446
// decodeExtension decodes an extension encoded in b.
447
func decodeExtension(b []byte, extension *ExtensionDesc) (interface{}, error) {
448
t := reflect.TypeOf(extension.ExtensionType)
449
unmarshal := typeUnmarshaler(t, extension.Tag)
451
// t is a pointer to a struct, pointer to basic type or a slice.
452
// Allocate space to store the pointer/slice.
453
value := reflect.New(t).Elem()
457
x, n := decodeVarint(b)
459
return nil, io.ErrUnexpectedEOF
464
b, err = unmarshal(b, valToPointer(value.Addr()), wire)
473
return value.Interface(), nil
476
// GetExtensions returns a slice of the extensions present in pb that are also listed in es.
477
// The returned slice has the same length as es; missing extensions will appear as nil elements.
478
func GetExtensions(pb Message, es []*ExtensionDesc) (extensions []interface{}, err error) {
479
epb, err := extendable(pb)
483
extensions = make([]interface{}, len(es))
484
for i, e := range es {
485
extensions[i], err = GetExtension(epb, e)
486
if err == ErrMissingExtension {
496
// ExtensionDescs returns a new slice containing pb's extension descriptors, in undefined order.
497
// For non-registered extensions, ExtensionDescs returns an incomplete descriptor containing
498
// just the Field field, which defines the extension's field number.
499
func ExtensionDescs(pb Message) ([]*ExtensionDesc, error) {
500
epb, err := extendable(pb)
504
registeredExtensions := RegisteredExtensions(pb)
506
emap, mu := epb.extensionsRead()
512
extensions := make([]*ExtensionDesc, 0, len(emap))
513
for extid, e := range emap {
516
desc = registeredExtensions[extid]
518
desc = &ExtensionDesc{Field: extid}
522
extensions = append(extensions, desc)
524
return extensions, nil
527
// SetExtension sets the specified extension of pb to the specified value.
528
func SetExtension(pb Message, extension *ExtensionDesc, value interface{}) error {
529
if epb, ok := pb.(extensionsBytes); ok {
530
ClearExtension(pb, extension)
531
newb, err := encodeExtension(extension, value)
535
bb := epb.GetExtensions()
536
*bb = append(*bb, newb...)
539
epb, err := extendable(pb)
543
if err := checkExtensionTypes(epb, extension); err != nil {
546
typ := reflect.TypeOf(extension.ExtensionType)
547
if typ != reflect.TypeOf(value) {
548
return fmt.Errorf("proto: bad extension value type. got: %T, want: %T", value, extension.ExtensionType)
550
// nil extension values need to be caught early, because the
551
// encoder can't distinguish an ErrNil due to a nil extension
552
// from an ErrNil due to a missing field. Extensions are
553
// always optional, so the encoder would just swallow the error
554
// and drop all the extensions from the encoded message.
555
if reflect.ValueOf(value).IsNil() {
556
return fmt.Errorf("proto: SetExtension called with nil value of type %T", value)
559
extmap := epb.extensionsWrite()
560
extmap[extension.Field] = Extension{desc: extension, value: value}
564
// ClearAllExtensions clears all extensions from pb.
565
func ClearAllExtensions(pb Message) {
566
if epb, doki := pb.(extensionsBytes); doki {
567
ext := epb.GetExtensions()
571
epb, err := extendable(pb)
575
m := epb.extensionsWrite()
581
// A global registry of extensions.
582
// The generated code will register the generated descriptors by calling RegisterExtension.
584
var extensionMaps = make(map[reflect.Type]map[int32]*ExtensionDesc)
586
// RegisterExtension is called from the generated code.
587
func RegisterExtension(desc *ExtensionDesc) {
588
st := reflect.TypeOf(desc.ExtendedType).Elem()
589
m := extensionMaps[st]
591
m = make(map[int32]*ExtensionDesc)
592
extensionMaps[st] = m
594
if _, ok := m[desc.Field]; ok {
595
panic("proto: duplicate extension registered: " + st.String() + " " + strconv.Itoa(int(desc.Field)))
600
// RegisteredExtensions returns a map of the registered extensions of a
601
// protocol buffer struct, indexed by the extension number.
602
// The argument pb should be a nil pointer to the struct type.
603
func RegisteredExtensions(pb Message) map[int32]*ExtensionDesc {
604
return extensionMaps[reflect.TypeOf(pb).Elem()]