github.com/matm/etcd@v0.3.1-0.20140328024009-5b4a473f1453/third_party/code.google.com/p/goprotobuf/proto/properties.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 * Routines for encoding data into the wire format for protocol buffers. 36 */ 37 38 import ( 39 "fmt" 40 "os" 41 "reflect" 42 "sort" 43 "strconv" 44 "strings" 45 "sync" 46 ) 47 48 const debug bool = false 49 50 // Constants that identify the encoding of a value on the wire. 51 const ( 52 WireVarint = 0 53 WireFixed64 = 1 54 WireBytes = 2 55 WireStartGroup = 3 56 WireEndGroup = 4 57 WireFixed32 = 5 58 ) 59 60 const startSize = 10 // initial slice/string sizes 61 62 // Encoders are defined in encode.go 63 // An encoder outputs the full representation of a field, including its 64 // tag and encoder type. 65 type encoder func(p *Buffer, prop *Properties, base structPointer) error 66 67 // A valueEncoder encodes a single integer in a particular encoding. 68 type valueEncoder func(o *Buffer, x uint64) error 69 70 // Sizers are defined in encode.go 71 // A sizer returns the encoded size of a field, including its tag and encoder 72 // type. 73 type sizer func(prop *Properties, base structPointer) int 74 75 // A valueSizer returns the encoded size of a single integer in a particular 76 // encoding. 77 type valueSizer func(x uint64) int 78 79 // Decoders are defined in decode.go 80 // A decoder creates a value from its wire representation. 81 // Unrecognized subelements are saved in unrec. 82 type decoder func(p *Buffer, prop *Properties, base structPointer) error 83 84 // A valueDecoder decodes a single integer in a particular encoding. 85 type valueDecoder func(o *Buffer) (x uint64, err error) 86 87 // tagMap is an optimization over map[int]int for typical protocol buffer 88 // use-cases. Encoded protocol buffers are often in tag order with small tag 89 // numbers. 90 type tagMap struct { 91 fastTags []int 92 slowTags map[int]int 93 } 94 95 // tagMapFastLimit is the upper bound on the tag number that will be stored in 96 // the tagMap slice rather than its map. 97 const tagMapFastLimit = 1024 98 99 func (p *tagMap) get(t int) (int, bool) { 100 if t > 0 && t < tagMapFastLimit { 101 if t >= len(p.fastTags) { 102 return 0, false 103 } 104 fi := p.fastTags[t] 105 return fi, fi >= 0 106 } 107 fi, ok := p.slowTags[t] 108 return fi, ok 109 } 110 111 func (p *tagMap) put(t int, fi int) { 112 if t > 0 && t < tagMapFastLimit { 113 for len(p.fastTags) < t+1 { 114 p.fastTags = append(p.fastTags, -1) 115 } 116 p.fastTags[t] = fi 117 return 118 } 119 if p.slowTags == nil { 120 p.slowTags = make(map[int]int) 121 } 122 p.slowTags[t] = fi 123 } 124 125 // StructProperties represents properties for all the fields of a struct. 126 // decoderTags and decoderOrigNames should only be used by the decoder. 127 type StructProperties struct { 128 Prop []*Properties // properties for each field 129 reqCount int // required count 130 decoderTags tagMap // map from proto tag to struct field number 131 decoderOrigNames map[string]int // map from original name to struct field number 132 order []int // list of struct field numbers in tag order 133 unrecField field // field id of the XXX_unrecognized []byte field 134 extendable bool // is this an extendable proto 135 } 136 137 // Implement the sorting interface so we can sort the fields in tag order, as recommended by the spec. 138 // See encode.go, (*Buffer).enc_struct. 139 140 func (sp *StructProperties) Len() int { return len(sp.order) } 141 func (sp *StructProperties) Less(i, j int) bool { 142 return sp.Prop[sp.order[i]].Tag < sp.Prop[sp.order[j]].Tag 143 } 144 func (sp *StructProperties) Swap(i, j int) { sp.order[i], sp.order[j] = sp.order[j], sp.order[i] } 145 146 // Properties represents the protocol-specific behavior of a single struct field. 147 type Properties struct { 148 Name string // name of the field, for error messages 149 OrigName string // original name before protocol compiler (always set) 150 Wire string 151 WireType int 152 Tag int 153 Required bool 154 Optional bool 155 Repeated bool 156 Packed bool // relevant for repeated primitives only 157 Enum string // set for enum types only 158 Default string // default value 159 def_uint64 uint64 160 161 enc encoder 162 valEnc valueEncoder // set for bool and numeric types only 163 field field 164 tagcode []byte // encoding of EncodeVarint((Tag<<3)|WireType) 165 tagbuf [8]byte 166 stype reflect.Type // set for struct types only 167 sprop *StructProperties // set for struct types only 168 isMarshaler bool 169 isUnmarshaler bool 170 171 size sizer 172 valSize valueSizer // set for bool and numeric types only 173 174 dec decoder 175 valDec valueDecoder // set for bool and numeric types only 176 177 // If this is a packable field, this will be the decoder for the packed version of the field. 178 packedDec decoder 179 } 180 181 // String formats the properties in the protobuf struct field tag style. 182 func (p *Properties) String() string { 183 s := p.Wire 184 s = "," 185 s += strconv.Itoa(p.Tag) 186 if p.Required { 187 s += ",req" 188 } 189 if p.Optional { 190 s += ",opt" 191 } 192 if p.Repeated { 193 s += ",rep" 194 } 195 if p.Packed { 196 s += ",packed" 197 } 198 if p.OrigName != p.Name { 199 s += ",name=" + p.OrigName 200 } 201 if len(p.Enum) > 0 { 202 s += ",enum=" + p.Enum 203 } 204 if len(p.Default) > 0 { 205 s += ",def=" + p.Default 206 } 207 return s 208 } 209 210 // Parse populates p by parsing a string in the protobuf struct field tag style. 211 func (p *Properties) Parse(s string) { 212 // "bytes,49,opt,name=foo,def=hello!" 213 fields := strings.Split(s, ",") // breaks def=, but handled below. 214 if len(fields) < 2 { 215 fmt.Fprintf(os.Stderr, "proto: tag has too few fields: %q\n", s) 216 return 217 } 218 219 p.Wire = fields[0] 220 switch p.Wire { 221 case "varint": 222 p.WireType = WireVarint 223 p.valEnc = (*Buffer).EncodeVarint 224 p.valDec = (*Buffer).DecodeVarint 225 p.valSize = sizeVarint 226 case "fixed32": 227 p.WireType = WireFixed32 228 p.valEnc = (*Buffer).EncodeFixed32 229 p.valDec = (*Buffer).DecodeFixed32 230 p.valSize = sizeFixed32 231 case "fixed64": 232 p.WireType = WireFixed64 233 p.valEnc = (*Buffer).EncodeFixed64 234 p.valDec = (*Buffer).DecodeFixed64 235 p.valSize = sizeFixed64 236 case "zigzag32": 237 p.WireType = WireVarint 238 p.valEnc = (*Buffer).EncodeZigzag32 239 p.valDec = (*Buffer).DecodeZigzag32 240 p.valSize = sizeZigzag32 241 case "zigzag64": 242 p.WireType = WireVarint 243 p.valEnc = (*Buffer).EncodeZigzag64 244 p.valDec = (*Buffer).DecodeZigzag64 245 p.valSize = sizeZigzag64 246 case "bytes", "group": 247 p.WireType = WireBytes 248 // no numeric converter for non-numeric types 249 default: 250 fmt.Fprintf(os.Stderr, "proto: tag has unknown wire type: %q\n", s) 251 return 252 } 253 254 var err error 255 p.Tag, err = strconv.Atoi(fields[1]) 256 if err != nil { 257 return 258 } 259 260 for i := 2; i < len(fields); i++ { 261 f := fields[i] 262 switch { 263 case f == "req": 264 p.Required = true 265 case f == "opt": 266 p.Optional = true 267 case f == "rep": 268 p.Repeated = true 269 case f == "packed": 270 p.Packed = true 271 case strings.HasPrefix(f, "name="): 272 p.OrigName = f[5:] 273 case strings.HasPrefix(f, "enum="): 274 p.Enum = f[5:] 275 case strings.HasPrefix(f, "def="): 276 p.Default = f[4:] // rest of string 277 if i+1 < len(fields) { 278 // Commas aren't escaped, and def is always last. 279 p.Default += "," + strings.Join(fields[i+1:], ",") 280 break 281 } 282 } 283 } 284 } 285 286 func logNoSliceEnc(t1, t2 reflect.Type) { 287 fmt.Fprintf(os.Stderr, "proto: no slice oenc for %T = []%T\n", t1, t2) 288 } 289 290 var protoMessageType = reflect.TypeOf((*Message)(nil)).Elem() 291 292 // Initialize the fields for encoding and decoding. 293 func (p *Properties) setEncAndDec(typ reflect.Type, lockGetProp bool) { 294 p.enc = nil 295 p.dec = nil 296 p.size = nil 297 298 switch t1 := typ; t1.Kind() { 299 default: 300 fmt.Fprintf(os.Stderr, "proto: no coders for %T\n", t1) 301 302 case reflect.Ptr: 303 switch t2 := t1.Elem(); t2.Kind() { 304 default: 305 fmt.Fprintf(os.Stderr, "proto: no encoder function for %T -> %T\n", t1, t2) 306 break 307 case reflect.Bool: 308 p.enc = (*Buffer).enc_bool 309 p.dec = (*Buffer).dec_bool 310 p.size = size_bool 311 case reflect.Int32, reflect.Uint32: 312 p.enc = (*Buffer).enc_int32 313 p.dec = (*Buffer).dec_int32 314 p.size = size_int32 315 case reflect.Int64, reflect.Uint64: 316 p.enc = (*Buffer).enc_int64 317 p.dec = (*Buffer).dec_int64 318 p.size = size_int64 319 case reflect.Float32: 320 p.enc = (*Buffer).enc_int32 // can just treat them as bits 321 p.dec = (*Buffer).dec_int32 322 p.size = size_int32 323 case reflect.Float64: 324 p.enc = (*Buffer).enc_int64 // can just treat them as bits 325 p.dec = (*Buffer).dec_int64 326 p.size = size_int64 327 case reflect.String: 328 p.enc = (*Buffer).enc_string 329 p.dec = (*Buffer).dec_string 330 p.size = size_string 331 case reflect.Struct: 332 p.stype = t1.Elem() 333 p.isMarshaler = isMarshaler(t1) 334 p.isUnmarshaler = isUnmarshaler(t1) 335 if p.Wire == "bytes" { 336 p.enc = (*Buffer).enc_struct_message 337 p.dec = (*Buffer).dec_struct_message 338 p.size = size_struct_message 339 } else { 340 p.enc = (*Buffer).enc_struct_group 341 p.dec = (*Buffer).dec_struct_group 342 p.size = size_struct_group 343 } 344 } 345 346 case reflect.Slice: 347 switch t2 := t1.Elem(); t2.Kind() { 348 default: 349 logNoSliceEnc(t1, t2) 350 break 351 case reflect.Bool: 352 if p.Packed { 353 p.enc = (*Buffer).enc_slice_packed_bool 354 p.size = size_slice_packed_bool 355 } else { 356 p.enc = (*Buffer).enc_slice_bool 357 p.size = size_slice_bool 358 } 359 p.dec = (*Buffer).dec_slice_bool 360 p.packedDec = (*Buffer).dec_slice_packed_bool 361 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: 362 switch t2.Bits() { 363 case 32: 364 if p.Packed { 365 p.enc = (*Buffer).enc_slice_packed_int32 366 p.size = size_slice_packed_int32 367 } else { 368 p.enc = (*Buffer).enc_slice_int32 369 p.size = size_slice_int32 370 } 371 p.dec = (*Buffer).dec_slice_int32 372 p.packedDec = (*Buffer).dec_slice_packed_int32 373 case 64: 374 if p.Packed { 375 p.enc = (*Buffer).enc_slice_packed_int64 376 p.size = size_slice_packed_int64 377 } else { 378 p.enc = (*Buffer).enc_slice_int64 379 p.size = size_slice_int64 380 } 381 p.dec = (*Buffer).dec_slice_int64 382 p.packedDec = (*Buffer).dec_slice_packed_int64 383 case 8: 384 if t2.Kind() == reflect.Uint8 { 385 p.enc = (*Buffer).enc_slice_byte 386 p.dec = (*Buffer).dec_slice_byte 387 p.size = size_slice_byte 388 } 389 default: 390 logNoSliceEnc(t1, t2) 391 break 392 } 393 case reflect.Float32, reflect.Float64: 394 switch t2.Bits() { 395 case 32: 396 // can just treat them as bits 397 if p.Packed { 398 p.enc = (*Buffer).enc_slice_packed_int32 399 p.size = size_slice_packed_int32 400 } else { 401 p.enc = (*Buffer).enc_slice_int32 402 p.size = size_slice_int32 403 } 404 p.dec = (*Buffer).dec_slice_int32 405 p.packedDec = (*Buffer).dec_slice_packed_int32 406 case 64: 407 // can just treat them as bits 408 if p.Packed { 409 p.enc = (*Buffer).enc_slice_packed_int64 410 p.size = size_slice_packed_int64 411 } else { 412 p.enc = (*Buffer).enc_slice_int64 413 p.size = size_slice_int64 414 } 415 p.dec = (*Buffer).dec_slice_int64 416 p.packedDec = (*Buffer).dec_slice_packed_int64 417 default: 418 logNoSliceEnc(t1, t2) 419 break 420 } 421 case reflect.String: 422 p.enc = (*Buffer).enc_slice_string 423 p.dec = (*Buffer).dec_slice_string 424 p.size = size_slice_string 425 case reflect.Ptr: 426 switch t3 := t2.Elem(); t3.Kind() { 427 default: 428 fmt.Fprintf(os.Stderr, "proto: no ptr oenc for %T -> %T -> %T\n", t1, t2, t3) 429 break 430 case reflect.Struct: 431 p.stype = t2.Elem() 432 p.isMarshaler = isMarshaler(t2) 433 p.isUnmarshaler = isUnmarshaler(t2) 434 if p.Wire == "bytes" { 435 p.enc = (*Buffer).enc_slice_struct_message 436 p.dec = (*Buffer).dec_slice_struct_message 437 p.size = size_slice_struct_message 438 } else { 439 p.enc = (*Buffer).enc_slice_struct_group 440 p.dec = (*Buffer).dec_slice_struct_group 441 p.size = size_slice_struct_group 442 } 443 } 444 case reflect.Slice: 445 switch t2.Elem().Kind() { 446 default: 447 fmt.Fprintf(os.Stderr, "proto: no slice elem oenc for %T -> %T -> %T\n", t1, t2, t2.Elem()) 448 break 449 case reflect.Uint8: 450 p.enc = (*Buffer).enc_slice_slice_byte 451 p.dec = (*Buffer).dec_slice_slice_byte 452 p.size = size_slice_slice_byte 453 } 454 } 455 } 456 457 // precalculate tag code 458 wire := p.WireType 459 if p.Packed { 460 wire = WireBytes 461 } 462 x := uint32(p.Tag)<<3 | uint32(wire) 463 i := 0 464 for i = 0; x > 127; i++ { 465 p.tagbuf[i] = 0x80 | uint8(x&0x7F) 466 x >>= 7 467 } 468 p.tagbuf[i] = uint8(x) 469 p.tagcode = p.tagbuf[0 : i+1] 470 471 if p.stype != nil { 472 if lockGetProp { 473 p.sprop = GetProperties(p.stype) 474 } else { 475 p.sprop = getPropertiesLocked(p.stype) 476 } 477 } 478 } 479 480 var ( 481 marshalerType = reflect.TypeOf((*Marshaler)(nil)).Elem() 482 unmarshalerType = reflect.TypeOf((*Unmarshaler)(nil)).Elem() 483 ) 484 485 // isMarshaler reports whether type t implements Marshaler. 486 func isMarshaler(t reflect.Type) bool { 487 // We're checking for (likely) pointer-receiver methods 488 // so if t is not a pointer, something is very wrong. 489 // The calls above only invoke isMarshaler on pointer types. 490 if t.Kind() != reflect.Ptr { 491 panic("proto: misuse of isMarshaler") 492 } 493 return t.Implements(marshalerType) 494 } 495 496 // isUnmarshaler reports whether type t implements Unmarshaler. 497 func isUnmarshaler(t reflect.Type) bool { 498 // We're checking for (likely) pointer-receiver methods 499 // so if t is not a pointer, something is very wrong. 500 // The calls above only invoke isUnmarshaler on pointer types. 501 if t.Kind() != reflect.Ptr { 502 panic("proto: misuse of isUnmarshaler") 503 } 504 return t.Implements(unmarshalerType) 505 } 506 507 // Init populates the properties from a protocol buffer struct tag. 508 func (p *Properties) Init(typ reflect.Type, name, tag string, f *reflect.StructField) { 509 p.init(typ, name, tag, f, true) 510 } 511 512 func (p *Properties) init(typ reflect.Type, name, tag string, f *reflect.StructField, lockGetProp bool) { 513 // "bytes,49,opt,def=hello!" 514 p.Name = name 515 p.OrigName = name 516 if f != nil { 517 p.field = toField(f) 518 } 519 if tag == "" { 520 return 521 } 522 p.Parse(tag) 523 p.setEncAndDec(typ, lockGetProp) 524 } 525 526 var ( 527 mutex sync.Mutex 528 propertiesMap = make(map[reflect.Type]*StructProperties) 529 ) 530 531 // GetProperties returns the list of properties for the type represented by t. 532 func GetProperties(t reflect.Type) *StructProperties { 533 mutex.Lock() 534 sprop := getPropertiesLocked(t) 535 mutex.Unlock() 536 return sprop 537 } 538 539 // getPropertiesLocked requires that mutex is held. 540 func getPropertiesLocked(t reflect.Type) *StructProperties { 541 if prop, ok := propertiesMap[t]; ok { 542 if collectStats { 543 stats.Chit++ 544 } 545 return prop 546 } 547 if collectStats { 548 stats.Cmiss++ 549 } 550 551 prop := new(StructProperties) 552 // in case of recursive protos, fill this in now. 553 propertiesMap[t] = prop 554 555 // build properties 556 prop.extendable = reflect.PtrTo(t).Implements(extendableProtoType) 557 prop.unrecField = invalidField 558 prop.Prop = make([]*Properties, t.NumField()) 559 prop.order = make([]int, t.NumField()) 560 561 for i := 0; i < t.NumField(); i++ { 562 f := t.Field(i) 563 p := new(Properties) 564 name := f.Name 565 p.init(f.Type, name, f.Tag.Get("protobuf"), &f, false) 566 567 if f.Name == "XXX_extensions" { // special case 568 p.enc = (*Buffer).enc_map 569 p.dec = nil // not needed 570 p.size = size_map 571 } 572 if f.Name == "XXX_unrecognized" { // special case 573 prop.unrecField = toField(&f) 574 } 575 prop.Prop[i] = p 576 prop.order[i] = i 577 if debug { 578 print(i, " ", f.Name, " ", t.String(), " ") 579 if p.Tag > 0 { 580 print(p.String()) 581 } 582 print("\n") 583 } 584 if p.enc == nil && !strings.HasPrefix(f.Name, "XXX_") { 585 fmt.Fprintln(os.Stderr, "proto: no encoder for", f.Name, f.Type.String(), "[GetProperties]") 586 } 587 } 588 589 // Re-order prop.order. 590 sort.Sort(prop) 591 592 // build required counts 593 // build tags 594 reqCount := 0 595 prop.decoderOrigNames = make(map[string]int) 596 for i, p := range prop.Prop { 597 if strings.HasPrefix(p.Name, "XXX_") { 598 // Internal fields should not appear in tags/origNames maps. 599 // They are handled specially when encoding and decoding. 600 continue 601 } 602 if p.Required { 603 reqCount++ 604 } 605 prop.decoderTags.put(p.Tag, i) 606 prop.decoderOrigNames[p.OrigName] = i 607 } 608 prop.reqCount = reqCount 609 610 return prop 611 } 612 613 // Return the Properties object for the x[0]'th field of the structure. 614 func propByIndex(t reflect.Type, x []int) *Properties { 615 if len(x) != 1 { 616 fmt.Fprintf(os.Stderr, "proto: field index dimension %d (not 1) for type %s\n", len(x), t) 617 return nil 618 } 619 prop := GetProperties(t) 620 return prop.Prop[x[0]] 621 } 622 623 // Get the address and type of a pointer to a struct from an interface. 624 func getbase(pb Message) (t reflect.Type, b structPointer, err error) { 625 if pb == nil { 626 err = ErrNil 627 return 628 } 629 // get the reflect type of the pointer to the struct. 630 t = reflect.TypeOf(pb) 631 // get the address of the struct. 632 value := reflect.ValueOf(pb) 633 b = toStructPointer(value) 634 return 635 } 636 637 // A global registry of enum types. 638 // The generated code will register the generated maps by calling RegisterEnum. 639 640 var enumValueMaps = make(map[string]map[string]int32) 641 642 // RegisterEnum is called from the generated code to install the enum descriptor 643 // maps into the global table to aid parsing text format protocol buffers. 644 func RegisterEnum(typeName string, unusedNameMap map[int32]string, valueMap map[string]int32) { 645 if _, ok := enumValueMaps[typeName]; ok { 646 panic("proto: duplicate enum registered: " + typeName) 647 } 648 enumValueMaps[typeName] = valueMap 649 }