github.com/asifdxtreme/cli@v6.1.3-0.20150123051144-9ead8700b4ae+incompatible/Godeps/_workspace/src/code.google.com/p/gogoprotobuf/proto/extensions.go (about) 1 // Go support for Protocol Buffers - Google's data interchange format 2 // 3 // Copyright 2010 The Go Authors. All rights reserved. 4 // http://code.google.com/p/goprotobuf/ 5 // 6 // Redistribution and use in source and binary forms, with or without 7 // modification, are permitted provided that the following conditions are 8 // met: 9 // 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 15 // distribution. 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. 19 // 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. 31 32 package proto 33 34 /* 35 * Types and routines for supporting protocol buffer extensions. 36 */ 37 38 import ( 39 "errors" 40 "reflect" 41 "strconv" 42 "sync" 43 ) 44 45 // ErrMissingExtension is the error returned by GetExtension if the named extension is not in the message. 46 var ErrMissingExtension = errors.New("proto: missing extension") 47 48 // ExtensionRange represents a range of message extensions for a protocol buffer. 49 // Used in code generated by the protocol compiler. 50 type ExtensionRange struct { 51 Start, End int32 // both inclusive 52 } 53 54 // extendableProto is an interface implemented by any protocol buffer that may be extended. 55 type extendableProto interface { 56 Message 57 ExtensionRangeArray() []ExtensionRange 58 } 59 60 type extensionsMap interface { 61 extendableProto 62 ExtensionMap() map[int32]Extension 63 } 64 65 type extensionsBytes interface { 66 extendableProto 67 GetExtensions() *[]byte 68 } 69 70 var extendableProtoType = reflect.TypeOf((*extendableProto)(nil)).Elem() 71 72 // ExtensionDesc represents an extension specification. 73 // Used in generated code from the protocol compiler. 74 type ExtensionDesc struct { 75 ExtendedType Message // nil pointer to the type that is being extended 76 ExtensionType interface{} // nil pointer to the extension type 77 Field int32 // field number 78 Name string // fully-qualified name of extension, for text formatting 79 Tag string // protobuf tag style 80 } 81 82 func (ed *ExtensionDesc) repeated() bool { 83 t := reflect.TypeOf(ed.ExtensionType) 84 return t.Kind() == reflect.Slice && t.Elem().Kind() != reflect.Uint8 85 } 86 87 // Extension represents an extension in a message. 88 type Extension struct { 89 // When an extension is stored in a message using SetExtension 90 // only desc and value are set. When the message is marshaled 91 // enc will be set to the encoded form of the message. 92 // 93 // When a message is unmarshaled and contains extensions, each 94 // extension will have only enc set. When such an extension is 95 // accessed using GetExtension (or GetExtensions) desc and value 96 // will be set. 97 desc *ExtensionDesc 98 value interface{} 99 enc []byte 100 } 101 102 // SetRawExtension is for testing only. 103 func SetRawExtension(base extendableProto, id int32, b []byte) { 104 if ebase, ok := base.(extensionsMap); ok { 105 ebase.ExtensionMap()[id] = Extension{enc: b} 106 } else if ebase, ok := base.(extensionsBytes); ok { 107 clearExtension(base, id) 108 ext := ebase.GetExtensions() 109 *ext = append(*ext, b...) 110 } else { 111 panic("unreachable") 112 } 113 } 114 115 // isExtensionField returns true iff the given field number is in an extension range. 116 func isExtensionField(pb extendableProto, field int32) bool { 117 for _, er := range pb.ExtensionRangeArray() { 118 if er.Start <= field && field <= er.End { 119 return true 120 } 121 } 122 return false 123 } 124 125 // checkExtensionTypes checks that the given extension is valid for pb. 126 func checkExtensionTypes(pb extendableProto, extension *ExtensionDesc) error { 127 // Check the extended type. 128 if a, b := reflect.TypeOf(pb), reflect.TypeOf(extension.ExtendedType); a != b { 129 return errors.New("proto: bad extended type; " + b.String() + " does not extend " + a.String()) 130 } 131 // Check the range. 132 if !isExtensionField(pb, extension.Field) { 133 return errors.New("proto: bad extension number; not in declared ranges") 134 } 135 return nil 136 } 137 138 // extPropKey is sufficient to uniquely identify an extension. 139 type extPropKey struct { 140 base reflect.Type 141 field int32 142 } 143 144 var extProp = struct { 145 sync.RWMutex 146 m map[extPropKey]*Properties 147 }{ 148 m: make(map[extPropKey]*Properties), 149 } 150 151 func extensionProperties(ed *ExtensionDesc) *Properties { 152 key := extPropKey{base: reflect.TypeOf(ed.ExtendedType), field: ed.Field} 153 154 extProp.RLock() 155 if prop, ok := extProp.m[key]; ok { 156 extProp.RUnlock() 157 return prop 158 } 159 extProp.RUnlock() 160 161 extProp.Lock() 162 defer extProp.Unlock() 163 // Check again. 164 if prop, ok := extProp.m[key]; ok { 165 return prop 166 } 167 168 prop := new(Properties) 169 prop.Init(reflect.TypeOf(ed.ExtensionType), "unknown_name", ed.Tag, nil) 170 extProp.m[key] = prop 171 return prop 172 } 173 174 // encodeExtensionMap encodes any unmarshaled (unencoded) extensions in m. 175 func encodeExtensionMap(m map[int32]Extension) error { 176 for k, e := range m { 177 if e.value == nil || e.desc == nil { 178 // Extension is only in its encoded form. 179 continue 180 } 181 182 // We don't skip extensions that have an encoded form set, 183 // because the extension value may have been mutated after 184 // the last time this function was called. 185 186 et := reflect.TypeOf(e.desc.ExtensionType) 187 props := extensionProperties(e.desc) 188 189 p := NewBuffer(nil) 190 // If e.value has type T, the encoder expects a *struct{ X T }. 191 // Pass a *T with a zero field and hope it all works out. 192 x := reflect.New(et) 193 x.Elem().Set(reflect.ValueOf(e.value)) 194 if err := props.enc(p, props, toStructPointer(x)); err != nil { 195 return err 196 } 197 e.enc = p.buf 198 m[k] = e 199 } 200 return nil 201 } 202 203 func sizeExtensionMap(m map[int32]Extension) (n int) { 204 for _, e := range m { 205 if e.value == nil || e.desc == nil { 206 // Extension is only in its encoded form. 207 n += len(e.enc) 208 continue 209 } 210 211 // We don't skip extensions that have an encoded form set, 212 // because the extension value may have been mutated after 213 // the last time this function was called. 214 215 et := reflect.TypeOf(e.desc.ExtensionType) 216 props := extensionProperties(e.desc) 217 218 // If e.value has type T, the encoder expects a *struct{ X T }. 219 // Pass a *T with a zero field and hope it all works out. 220 x := reflect.New(et) 221 x.Elem().Set(reflect.ValueOf(e.value)) 222 n += props.size(props, toStructPointer(x)) 223 } 224 return 225 } 226 227 // HasExtension returns whether the given extension is present in pb. 228 func HasExtension(pb extendableProto, extension *ExtensionDesc) bool { 229 // TODO: Check types, field numbers, etc.? 230 if epb, doki := pb.(extensionsMap); doki { 231 _, ok := epb.ExtensionMap()[extension.Field] 232 return ok 233 } else if epb, doki := pb.(extensionsBytes); doki { 234 ext := epb.GetExtensions() 235 buf := *ext 236 o := 0 237 for o < len(buf) { 238 tag, n := DecodeVarint(buf[o:]) 239 fieldNum := int32(tag >> 3) 240 if int32(fieldNum) == extension.Field { 241 return true 242 } 243 wireType := int(tag & 0x7) 244 o += n 245 l, err := size(buf[o:], wireType) 246 if err != nil { 247 return false 248 } 249 o += l 250 } 251 return false 252 } 253 panic("unreachable") 254 } 255 256 func deleteExtension(pb extensionsBytes, theFieldNum int32, offset int) int { 257 ext := pb.GetExtensions() 258 for offset < len(*ext) { 259 tag, n1 := DecodeVarint((*ext)[offset:]) 260 fieldNum := int32(tag >> 3) 261 wireType := int(tag & 0x7) 262 n2, err := size((*ext)[offset+n1:], wireType) 263 if err != nil { 264 panic(err) 265 } 266 newOffset := offset + n1 + n2 267 if fieldNum == theFieldNum { 268 *ext = append((*ext)[:offset], (*ext)[newOffset:]...) 269 return offset 270 } 271 offset = newOffset 272 } 273 return -1 274 } 275 276 func clearExtension(pb extendableProto, fieldNum int32) { 277 if epb, doki := pb.(extensionsMap); doki { 278 delete(epb.ExtensionMap(), fieldNum) 279 } else if epb, doki := pb.(extensionsBytes); doki { 280 offset := 0 281 for offset != -1 { 282 offset = deleteExtension(epb, fieldNum, offset) 283 } 284 } else { 285 panic("unreachable") 286 } 287 } 288 289 // ClearExtension removes the given extension from pb. 290 func ClearExtension(pb extendableProto, extension *ExtensionDesc) { 291 // TODO: Check types, field numbers, etc.? 292 clearExtension(pb, extension.Field) 293 } 294 295 // GetExtension parses and returns the given extension of pb. 296 // If the extension is not present it returns ErrMissingExtension. 297 func GetExtension(pb extendableProto, extension *ExtensionDesc) (interface{}, error) { 298 if err := checkExtensionTypes(pb, extension); err != nil { 299 return nil, err 300 } 301 302 if epb, doki := pb.(extensionsMap); doki { 303 e, ok := epb.ExtensionMap()[extension.Field] 304 if !ok { 305 return nil, ErrMissingExtension 306 } 307 if e.value != nil { 308 // Already decoded. Check the descriptor, though. 309 if e.desc != extension { 310 // This shouldn't happen. If it does, it means that 311 // GetExtension was called twice with two different 312 // descriptors with the same field number. 313 return nil, errors.New("proto: descriptor conflict") 314 } 315 return e.value, nil 316 } 317 318 v, err := decodeExtension(e.enc, extension) 319 if err != nil { 320 return nil, err 321 } 322 323 // Remember the decoded version and drop the encoded version. 324 // That way it is safe to mutate what we return. 325 e.value = v 326 e.desc = extension 327 e.enc = nil 328 return e.value, nil 329 } else if epb, doki := pb.(extensionsBytes); doki { 330 ext := epb.GetExtensions() 331 o := 0 332 for o < len(*ext) { 333 tag, n := DecodeVarint((*ext)[o:]) 334 fieldNum := int32(tag >> 3) 335 wireType := int(tag & 0x7) 336 l, err := size((*ext)[o+n:], wireType) 337 if err != nil { 338 return nil, err 339 } 340 if int32(fieldNum) == extension.Field { 341 v, err := decodeExtension((*ext)[o:o+n+l], extension) 342 if err != nil { 343 return nil, err 344 } 345 return v, nil 346 } 347 o += n + l 348 } 349 } 350 panic("unreachable") 351 } 352 353 // decodeExtension decodes an extension encoded in b. 354 func decodeExtension(b []byte, extension *ExtensionDesc) (interface{}, error) { 355 o := NewBuffer(b) 356 357 t := reflect.TypeOf(extension.ExtensionType) 358 rep := extension.repeated() 359 360 props := extensionProperties(extension) 361 362 // t is a pointer to a struct, pointer to basic type or a slice. 363 // Allocate a "field" to store the pointer/slice itself; the 364 // pointer/slice will be stored here. We pass 365 // the address of this field to props.dec. 366 // This passes a zero field and a *t and lets props.dec 367 // interpret it as a *struct{ x t }. 368 value := reflect.New(t).Elem() 369 370 for { 371 // Discard wire type and field number varint. It isn't needed. 372 if _, err := o.DecodeVarint(); err != nil { 373 return nil, err 374 } 375 376 if err := props.dec(o, props, toStructPointer(value.Addr())); err != nil { 377 return nil, err 378 } 379 380 if !rep || o.index >= len(o.buf) { 381 break 382 } 383 } 384 return value.Interface(), nil 385 } 386 387 // GetExtensions returns a slice of the extensions present in pb that are also listed in es. 388 // The returned slice has the same length as es; missing extensions will appear as nil elements. 389 func GetExtensions(pb Message, es []*ExtensionDesc) (extensions []interface{}, err error) { 390 epb, ok := pb.(extendableProto) 391 if !ok { 392 err = errors.New("proto: not an extendable proto") 393 return 394 } 395 extensions = make([]interface{}, len(es)) 396 for i, e := range es { 397 extensions[i], err = GetExtension(epb, e) 398 if err == ErrMissingExtension { 399 err = nil 400 } 401 if err != nil { 402 return 403 } 404 } 405 return 406 } 407 408 // SetExtension sets the specified extension of pb to the specified value. 409 func SetExtension(pb extendableProto, extension *ExtensionDesc, value interface{}) error { 410 if err := checkExtensionTypes(pb, extension); err != nil { 411 return err 412 } 413 typ := reflect.TypeOf(extension.ExtensionType) 414 if typ != reflect.TypeOf(value) { 415 return errors.New("proto: bad extension value type") 416 } 417 418 if epb, doki := pb.(extensionsMap); doki { 419 epb.ExtensionMap()[extension.Field] = Extension{desc: extension, value: value} 420 } else if epb, doki := pb.(extensionsBytes); doki { 421 ClearExtension(pb, extension) 422 ext := epb.GetExtensions() 423 et := reflect.TypeOf(extension.ExtensionType) 424 props := extensionProperties(extension) 425 p := NewBuffer(nil) 426 x := reflect.New(et) 427 x.Elem().Set(reflect.ValueOf(value)) 428 if err := props.enc(p, props, toStructPointer(x)); err != nil { 429 return err 430 } 431 *ext = append(*ext, p.buf...) 432 } 433 return nil 434 } 435 436 // A global registry of extensions. 437 // The generated code will register the generated descriptors by calling RegisterExtension. 438 439 var extensionMaps = make(map[reflect.Type]map[int32]*ExtensionDesc) 440 441 // RegisterExtension is called from the generated code. 442 func RegisterExtension(desc *ExtensionDesc) { 443 st := reflect.TypeOf(desc.ExtendedType).Elem() 444 m := extensionMaps[st] 445 if m == nil { 446 m = make(map[int32]*ExtensionDesc) 447 extensionMaps[st] = m 448 } 449 if _, ok := m[desc.Field]; ok { 450 panic("proto: duplicate extension registered: " + st.String() + " " + strconv.Itoa(int(desc.Field))) 451 } 452 m[desc.Field] = desc 453 } 454 455 // RegisteredExtensions returns a map of the registered extensions of a 456 // protocol buffer struct, indexed by the extension number. 457 // The argument pb should be a nil pointer to the struct type. 458 func RegisteredExtensions(pb Message) map[int32]*ExtensionDesc { 459 return extensionMaps[reflect.TypeOf(pb).Elem()] 460 }