1
// Protocol Buffers for Go with Gadgets
3
// Copyright (c) 2013, The GoGo Authors. All rights reserved.
4
// http://github.com/gogo/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
17
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
42
type extensionsBytes interface {
44
ExtensionRangeArray() []ExtensionRange
45
GetExtensions() *[]byte
48
type slowExtensionAdapter struct {
52
func (s slowExtensionAdapter) extensionsWrite() map[int32]Extension {
53
panic("Please report a bug to github.com/gogo/protobuf if you see this message: Writing extensions is not supported for extensions stored in a byte slice field.")
56
func (s slowExtensionAdapter) extensionsRead() (map[int32]Extension, sync.Locker) {
57
b := s.GetExtensions()
58
m, err := BytesToExtensionsMap(*b)
65
func GetBoolExtension(pb Message, extension *ExtensionDesc, ifnotset bool) bool {
66
if reflect.ValueOf(pb).IsNil() {
69
value, err := GetExtension(pb, extension)
76
if value.(*bool) == nil {
79
return *(value.(*bool))
82
func (this *Extension) Equal(that *Extension) bool {
83
if err := this.Encode(); err != nil {
86
if err := that.Encode(); err != nil {
89
return bytes.Equal(this.enc, that.enc)
92
func (this *Extension) Compare(that *Extension) int {
93
if err := this.Encode(); err != nil {
96
if err := that.Encode(); err != nil {
99
return bytes.Compare(this.enc, that.enc)
102
func SizeOfInternalExtension(m extendableProto) (n int) {
103
info := getMarshalInfo(reflect.TypeOf(m))
104
return info.sizeV1Extensions(m.extensionsWrite())
107
type sortableMapElem struct {
112
func newSortableExtensionsFromMap(m map[int32]Extension) sortableExtensions {
113
s := make(sortableExtensions, 0, len(m))
114
for k, v := range m {
115
s = append(s, &sortableMapElem{field: k, ext: v})
120
type sortableExtensions []*sortableMapElem
122
func (this sortableExtensions) Len() int { return len(this) }
124
func (this sortableExtensions) Swap(i, j int) { this[i], this[j] = this[j], this[i] }
126
func (this sortableExtensions) Less(i, j int) bool { return this[i].field < this[j].field }
128
func (this sortableExtensions) String() string {
130
ss := make([]string, len(this))
131
for i := range this {
132
ss[i] = fmt.Sprintf("%d: %v", this[i].field, this[i].ext)
134
return "map[" + strings.Join(ss, ",") + "]"
137
func StringFromInternalExtension(m extendableProto) string {
138
return StringFromExtensionsMap(m.extensionsWrite())
141
func StringFromExtensionsMap(m map[int32]Extension) string {
142
return newSortableExtensionsFromMap(m).String()
145
func StringFromExtensionsBytes(ext []byte) string {
146
m, err := BytesToExtensionsMap(ext)
150
return StringFromExtensionsMap(m)
153
func EncodeInternalExtension(m extendableProto, data []byte) (n int, err error) {
154
return EncodeExtensionMap(m.extensionsWrite(), data)
157
func EncodeInternalExtensionBackwards(m extendableProto, data []byte) (n int, err error) {
158
return EncodeExtensionMapBackwards(m.extensionsWrite(), data)
161
func EncodeExtensionMap(m map[int32]Extension, data []byte) (n int, err error) {
163
for _, e := range m {
164
if err := e.Encode(); err != nil {
167
n := copy(data[o:], e.enc)
169
return 0, io.ErrShortBuffer
176
func EncodeExtensionMapBackwards(m map[int32]Extension, data []byte) (n int, err error) {
179
for _, e := range m {
180
if err := e.Encode(); err != nil {
183
n := copy(data[end-len(e.enc):], e.enc)
185
return 0, io.ErrShortBuffer
193
func GetRawExtension(m map[int32]Extension, id int32) ([]byte, error) {
195
if err := e.Encode(); err != nil {
201
func size(buf []byte, wire int) (int, error) {
204
_, n := DecodeVarint(buf)
209
v, n := DecodeVarint(buf)
210
return int(v) + n, nil
216
u, n := DecodeVarint(buf[offset:])
217
fwire := int(u & 0x7)
219
if fwire == WireEndGroup {
222
s, err := size(buf[offset:], wire)
229
return 0, fmt.Errorf("proto: can't get size for unknown wire type %d", wire)
232
func BytesToExtensionsMap(buf []byte) (map[int32]Extension, error) {
233
m := make(map[int32]Extension)
236
tag, n := DecodeVarint(buf[i:])
238
return nil, fmt.Errorf("unable to decode varint")
240
fieldNum := int32(tag >> 3)
241
wireType := int(tag & 0x7)
242
l, err := size(buf[i+n:], wireType)
246
end := i + int(l) + n
247
m[int32(fieldNum)] = Extension{enc: buf[i:end]}
253
func NewExtension(e []byte) Extension {
254
ee := Extension{enc: make([]byte, len(e))}
259
func AppendExtension(e Message, tag int32, buf []byte) {
260
if ee, eok := e.(extensionsBytes); eok {
261
ext := ee.GetExtensions()
262
*ext = append(*ext, buf...)
265
if ee, eok := e.(extendableProto); eok {
266
m := ee.extensionsWrite()
267
ext := m[int32(tag)] // may be missing
268
ext.enc = append(ext.enc, buf...)
273
func encodeExtension(extension *ExtensionDesc, value interface{}) ([]byte, error) {
274
u := getMarshalInfo(reflect.TypeOf(extension.ExtendedType))
275
ei := u.getExtElemInfo(extension)
277
p := toAddrPointer(&v, ei.isptr)
278
siz := ei.sizer(p, SizeVarint(ei.wiretag))
279
buf := make([]byte, 0, siz)
280
return ei.marshaler(buf, p, ei.wiretag, false)
283
func decodeExtensionFromBytes(extension *ExtensionDesc, buf []byte) (interface{}, error) {
286
tag, n := DecodeVarint((buf)[o:])
287
fieldNum := int32(tag >> 3)
288
wireType := int(tag & 0x7)
290
return nil, fmt.Errorf("unable to decode extension")
292
l, err := size((buf)[o+n:], wireType)
296
if int32(fieldNum) == extension.Field {
297
if o+n+l > len(buf) {
298
return nil, fmt.Errorf("unable to decode extension")
300
v, err := decodeExtension((buf)[o:o+n+l], extension)
308
return defaultExtensionValue(extension)
311
func (this *Extension) Encode() error {
314
this.enc, err = encodeExtension(this.desc, this.value)
322
func (this Extension) GoString() string {
323
if err := this.Encode(); err != nil {
324
return fmt.Sprintf("error encoding extension: %v", err)
326
return fmt.Sprintf("proto.NewExtension(%#v)", this.enc)
329
func SetUnsafeExtension(pb Message, fieldNum int32, value interface{}) error {
330
typ := reflect.TypeOf(pb).Elem()
331
ext, ok := extensionMaps[typ]
333
return fmt.Errorf("proto: bad extended type; %s is not extendable", typ.String())
335
desc, ok := ext[fieldNum]
337
return errors.New("proto: bad extension number; not in declared ranges")
339
return SetExtension(pb, desc, value)
342
func GetUnsafeExtension(pb Message, fieldNum int32) (interface{}, error) {
343
typ := reflect.TypeOf(pb).Elem()
344
ext, ok := extensionMaps[typ]
346
return nil, fmt.Errorf("proto: bad extended type; %s is not extendable", typ.String())
348
desc, ok := ext[fieldNum]
350
return nil, fmt.Errorf("unregistered field number %d", fieldNum)
352
return GetExtension(pb, desc)
355
func NewUnsafeXXX_InternalExtensions(m map[int32]Extension) XXX_InternalExtensions {
356
x := &XXX_InternalExtensions{
359
extensionMap map[int32]Extension
366
func GetUnsafeExtensionsMap(extendable Message) map[int32]Extension {
367
pb := extendable.(extendableProto)
368
return pb.extensionsWrite()
371
func deleteExtension(pb extensionsBytes, theFieldNum int32, offset int) int {
372
ext := pb.GetExtensions()
373
for offset < len(*ext) {
374
tag, n1 := DecodeVarint((*ext)[offset:])
375
fieldNum := int32(tag >> 3)
376
wireType := int(tag & 0x7)
377
n2, err := size((*ext)[offset+n1:], wireType)
381
newOffset := offset + n1 + n2
382
if fieldNum == theFieldNum {
383
*ext = append((*ext)[:offset], (*ext)[newOffset:]...)