Home | History | Annotate | Download | only in proto
      1 // Go support for Protocol Buffers - Google's data interchange format
      2 //
      3 // Copyright 2010 The Go Authors.  All rights reserved.
      4 // https://github.com/golang/protobuf
      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 	"log"
     41 	"os"
     42 	"reflect"
     43 	"sort"
     44 	"strconv"
     45 	"strings"
     46 	"sync"
     47 )
     48 
     49 const debug bool = false
     50 
     51 // Constants that identify the encoding of a value on the wire.
     52 const (
     53 	WireVarint     = 0
     54 	WireFixed64    = 1
     55 	WireBytes      = 2
     56 	WireStartGroup = 3
     57 	WireEndGroup   = 4
     58 	WireFixed32    = 5
     59 )
     60 
     61 const startSize = 10 // initial slice/string sizes
     62 
     63 // Encoders are defined in encode.go
     64 // An encoder outputs the full representation of a field, including its
     65 // tag and encoder type.
     66 type encoder func(p *Buffer, prop *Properties, base structPointer) error
     67 
     68 // A valueEncoder encodes a single integer in a particular encoding.
     69 type valueEncoder func(o *Buffer, x uint64) error
     70 
     71 // Sizers are defined in encode.go
     72 // A sizer returns the encoded size of a field, including its tag and encoder
     73 // type.
     74 type sizer func(prop *Properties, base structPointer) int
     75 
     76 // A valueSizer returns the encoded size of a single integer in a particular
     77 // encoding.
     78 type valueSizer func(x uint64) int
     79 
     80 // Decoders are defined in decode.go
     81 // A decoder creates a value from its wire representation.
     82 // Unrecognized subelements are saved in unrec.
     83 type decoder func(p *Buffer, prop *Properties, base structPointer) error
     84 
     85 // A valueDecoder decodes a single integer in a particular encoding.
     86 type valueDecoder func(o *Buffer) (x uint64, err error)
     87 
     88 // A oneofMarshaler does the marshaling for all oneof fields in a message.
     89 type oneofMarshaler func(Message, *Buffer) error
     90 
     91 // A oneofUnmarshaler does the unmarshaling for a oneof field in a message.
     92 type oneofUnmarshaler func(Message, int, int, *Buffer) (bool, error)
     93 
     94 // A oneofSizer does the sizing for all oneof fields in a message.
     95 type oneofSizer func(Message) int
     96 
     97 // tagMap is an optimization over map[int]int for typical protocol buffer
     98 // use-cases. Encoded protocol buffers are often in tag order with small tag
     99 // numbers.
    100 type tagMap struct {
    101 	fastTags []int
    102 	slowTags map[int]int
    103 }
    104 
    105 // tagMapFastLimit is the upper bound on the tag number that will be stored in
    106 // the tagMap slice rather than its map.
    107 const tagMapFastLimit = 1024
    108 
    109 func (p *tagMap) get(t int) (int, bool) {
    110 	if t > 0 && t < tagMapFastLimit {
    111 		if t >= len(p.fastTags) {
    112 			return 0, false
    113 		}
    114 		fi := p.fastTags[t]
    115 		return fi, fi >= 0
    116 	}
    117 	fi, ok := p.slowTags[t]
    118 	return fi, ok
    119 }
    120 
    121 func (p *tagMap) put(t int, fi int) {
    122 	if t > 0 && t < tagMapFastLimit {
    123 		for len(p.fastTags) < t+1 {
    124 			p.fastTags = append(p.fastTags, -1)
    125 		}
    126 		p.fastTags[t] = fi
    127 		return
    128 	}
    129 	if p.slowTags == nil {
    130 		p.slowTags = make(map[int]int)
    131 	}
    132 	p.slowTags[t] = fi
    133 }
    134 
    135 // StructProperties represents properties for all the fields of a struct.
    136 // decoderTags and decoderOrigNames should only be used by the decoder.
    137 type StructProperties struct {
    138 	Prop             []*Properties  // properties for each field
    139 	reqCount         int            // required count
    140 	decoderTags      tagMap         // map from proto tag to struct field number
    141 	decoderOrigNames map[string]int // map from original name to struct field number
    142 	order            []int          // list of struct field numbers in tag order
    143 	unrecField       field          // field id of the XXX_unrecognized []byte field
    144 	extendable       bool           // is this an extendable proto
    145 
    146 	oneofMarshaler   oneofMarshaler
    147 	oneofUnmarshaler oneofUnmarshaler
    148 	oneofSizer       oneofSizer
    149 	stype            reflect.Type
    150 
    151 	// OneofTypes contains information about the oneof fields in this message.
    152 	// It is keyed by the original name of a field.
    153 	OneofTypes map[string]*OneofProperties
    154 }
    155 
    156 // OneofProperties represents information about a specific field in a oneof.
    157 type OneofProperties struct {
    158 	Type  reflect.Type // pointer to generated struct type for this oneof field
    159 	Field int          // struct field number of the containing oneof in the message
    160 	Prop  *Properties
    161 }
    162 
    163 // Implement the sorting interface so we can sort the fields in tag order, as recommended by the spec.
    164 // See encode.go, (*Buffer).enc_struct.
    165 
    166 func (sp *StructProperties) Len() int { return len(sp.order) }
    167 func (sp *StructProperties) Less(i, j int) bool {
    168 	return sp.Prop[sp.order[i]].Tag < sp.Prop[sp.order[j]].Tag
    169 }
    170 func (sp *StructProperties) Swap(i, j int) { sp.order[i], sp.order[j] = sp.order[j], sp.order[i] }
    171 
    172 // Properties represents the protocol-specific behavior of a single struct field.
    173 type Properties struct {
    174 	Name     string // name of the field, for error messages
    175 	OrigName string // original name before protocol compiler (always set)
    176 	JSONName string // name to use for JSON; determined by protoc
    177 	Wire     string
    178 	WireType int
    179 	Tag      int
    180 	Required bool
    181 	Optional bool
    182 	Repeated bool
    183 	Packed   bool   // relevant for repeated primitives only
    184 	Enum     string // set for enum types only
    185 	proto3   bool   // whether this is known to be a proto3 field; set for []byte only
    186 	oneof    bool   // whether this is a oneof field
    187 
    188 	Default    string // default value
    189 	HasDefault bool   // whether an explicit default was provided
    190 	def_uint64 uint64
    191 
    192 	enc           encoder
    193 	valEnc        valueEncoder // set for bool and numeric types only
    194 	field         field
    195 	tagcode       []byte // encoding of EncodeVarint((Tag<<3)|WireType)
    196 	tagbuf        [8]byte
    197 	stype         reflect.Type      // set for struct types only
    198 	sprop         *StructProperties // set for struct types only
    199 	isMarshaler   bool
    200 	isUnmarshaler bool
    201 
    202 	mtype    reflect.Type // set for map types only
    203 	mkeyprop *Properties  // set for map types only
    204 	mvalprop *Properties  // set for map types only
    205 
    206 	size    sizer
    207 	valSize valueSizer // set for bool and numeric types only
    208 
    209 	dec    decoder
    210 	valDec valueDecoder // set for bool and numeric types only
    211 
    212 	// If this is a packable field, this will be the decoder for the packed version of the field.
    213 	packedDec decoder
    214 }
    215 
    216 // String formats the properties in the protobuf struct field tag style.
    217 func (p *Properties) String() string {
    218 	s := p.Wire
    219 	s = ","
    220 	s += strconv.Itoa(p.Tag)
    221 	if p.Required {
    222 		s += ",req"
    223 	}
    224 	if p.Optional {
    225 		s += ",opt"
    226 	}
    227 	if p.Repeated {
    228 		s += ",rep"
    229 	}
    230 	if p.Packed {
    231 		s += ",packed"
    232 	}
    233 	s += ",name=" + p.OrigName
    234 	if p.JSONName != p.OrigName {
    235 		s += ",json=" + p.JSONName
    236 	}
    237 	if p.proto3 {
    238 		s += ",proto3"
    239 	}
    240 	if p.oneof {
    241 		s += ",oneof"
    242 	}
    243 	if len(p.Enum) > 0 {
    244 		s += ",enum=" + p.Enum
    245 	}
    246 	if p.HasDefault {
    247 		s += ",def=" + p.Default
    248 	}
    249 	return s
    250 }
    251 
    252 // Parse populates p by parsing a string in the protobuf struct field tag style.
    253 func (p *Properties) Parse(s string) {
    254 	// "bytes,49,opt,name=foo,def=hello!"
    255 	fields := strings.Split(s, ",") // breaks def=, but handled below.
    256 	if len(fields) < 2 {
    257 		fmt.Fprintf(os.Stderr, "proto: tag has too few fields: %q\n", s)
    258 		return
    259 	}
    260 
    261 	p.Wire = fields[0]
    262 	switch p.Wire {
    263 	case "varint":
    264 		p.WireType = WireVarint
    265 		p.valEnc = (*Buffer).EncodeVarint
    266 		p.valDec = (*Buffer).DecodeVarint
    267 		p.valSize = sizeVarint
    268 	case "fixed32":
    269 		p.WireType = WireFixed32
    270 		p.valEnc = (*Buffer).EncodeFixed32
    271 		p.valDec = (*Buffer).DecodeFixed32
    272 		p.valSize = sizeFixed32
    273 	case "fixed64":
    274 		p.WireType = WireFixed64
    275 		p.valEnc = (*Buffer).EncodeFixed64
    276 		p.valDec = (*Buffer).DecodeFixed64
    277 		p.valSize = sizeFixed64
    278 	case "zigzag32":
    279 		p.WireType = WireVarint
    280 		p.valEnc = (*Buffer).EncodeZigzag32
    281 		p.valDec = (*Buffer).DecodeZigzag32
    282 		p.valSize = sizeZigzag32
    283 	case "zigzag64":
    284 		p.WireType = WireVarint
    285 		p.valEnc = (*Buffer).EncodeZigzag64
    286 		p.valDec = (*Buffer).DecodeZigzag64
    287 		p.valSize = sizeZigzag64
    288 	case "bytes", "group":
    289 		p.WireType = WireBytes
    290 		// no numeric converter for non-numeric types
    291 	default:
    292 		fmt.Fprintf(os.Stderr, "proto: tag has unknown wire type: %q\n", s)
    293 		return
    294 	}
    295 
    296 	var err error
    297 	p.Tag, err = strconv.Atoi(fields[1])
    298 	if err != nil {
    299 		return
    300 	}
    301 
    302 	for i := 2; i < len(fields); i++ {
    303 		f := fields[i]
    304 		switch {
    305 		case f == "req":
    306 			p.Required = true
    307 		case f == "opt":
    308 			p.Optional = true
    309 		case f == "rep":
    310 			p.Repeated = true
    311 		case f == "packed":
    312 			p.Packed = true
    313 		case strings.HasPrefix(f, "name="):
    314 			p.OrigName = f[5:]
    315 		case strings.HasPrefix(f, "json="):
    316 			p.JSONName = f[5:]
    317 		case strings.HasPrefix(f, "enum="):
    318 			p.Enum = f[5:]
    319 		case f == "proto3":
    320 			p.proto3 = true
    321 		case f == "oneof":
    322 			p.oneof = true
    323 		case strings.HasPrefix(f, "def="):
    324 			p.HasDefault = true
    325 			p.Default = f[4:] // rest of string
    326 			if i+1 < len(fields) {
    327 				// Commas aren't escaped, and def is always last.
    328 				p.Default += "," + strings.Join(fields[i+1:], ",")
    329 				break
    330 			}
    331 		}
    332 	}
    333 }
    334 
    335 func logNoSliceEnc(t1, t2 reflect.Type) {
    336 	fmt.Fprintf(os.Stderr, "proto: no slice oenc for %T = []%T\n", t1, t2)
    337 }
    338 
    339 var protoMessageType = reflect.TypeOf((*Message)(nil)).Elem()
    340 
    341 // Initialize the fields for encoding and decoding.
    342 func (p *Properties) setEncAndDec(typ reflect.Type, f *reflect.StructField, lockGetProp bool) {
    343 	p.enc = nil
    344 	p.dec = nil
    345 	p.size = nil
    346 
    347 	switch t1 := typ; t1.Kind() {
    348 	default:
    349 		fmt.Fprintf(os.Stderr, "proto: no coders for %v\n", t1)
    350 
    351 	// proto3 scalar types
    352 
    353 	case reflect.Bool:
    354 		p.enc = (*Buffer).enc_proto3_bool
    355 		p.dec = (*Buffer).dec_proto3_bool
    356 		p.size = size_proto3_bool
    357 	case reflect.Int32:
    358 		p.enc = (*Buffer).enc_proto3_int32
    359 		p.dec = (*Buffer).dec_proto3_int32
    360 		p.size = size_proto3_int32
    361 	case reflect.Uint32:
    362 		p.enc = (*Buffer).enc_proto3_uint32
    363 		p.dec = (*Buffer).dec_proto3_int32 // can reuse
    364 		p.size = size_proto3_uint32
    365 	case reflect.Int64, reflect.Uint64:
    366 		p.enc = (*Buffer).enc_proto3_int64
    367 		p.dec = (*Buffer).dec_proto3_int64
    368 		p.size = size_proto3_int64
    369 	case reflect.Float32:
    370 		p.enc = (*Buffer).enc_proto3_uint32 // can just treat them as bits
    371 		p.dec = (*Buffer).dec_proto3_int32
    372 		p.size = size_proto3_uint32
    373 	case reflect.Float64:
    374 		p.enc = (*Buffer).enc_proto3_int64 // can just treat them as bits
    375 		p.dec = (*Buffer).dec_proto3_int64
    376 		p.size = size_proto3_int64
    377 	case reflect.String:
    378 		p.enc = (*Buffer).enc_proto3_string
    379 		p.dec = (*Buffer).dec_proto3_string
    380 		p.size = size_proto3_string
    381 
    382 	case reflect.Ptr:
    383 		switch t2 := t1.Elem(); t2.Kind() {
    384 		default:
    385 			fmt.Fprintf(os.Stderr, "proto: no encoder function for %v -> %v\n", t1, t2)
    386 			break
    387 		case reflect.Bool:
    388 			p.enc = (*Buffer).enc_bool
    389 			p.dec = (*Buffer).dec_bool
    390 			p.size = size_bool
    391 		case reflect.Int32:
    392 			p.enc = (*Buffer).enc_int32
    393 			p.dec = (*Buffer).dec_int32
    394 			p.size = size_int32
    395 		case reflect.Uint32:
    396 			p.enc = (*Buffer).enc_uint32
    397 			p.dec = (*Buffer).dec_int32 // can reuse
    398 			p.size = size_uint32
    399 		case reflect.Int64, reflect.Uint64:
    400 			p.enc = (*Buffer).enc_int64
    401 			p.dec = (*Buffer).dec_int64
    402 			p.size = size_int64
    403 		case reflect.Float32:
    404 			p.enc = (*Buffer).enc_uint32 // can just treat them as bits
    405 			p.dec = (*Buffer).dec_int32
    406 			p.size = size_uint32
    407 		case reflect.Float64:
    408 			p.enc = (*Buffer).enc_int64 // can just treat them as bits
    409 			p.dec = (*Buffer).dec_int64
    410 			p.size = size_int64
    411 		case reflect.String:
    412 			p.enc = (*Buffer).enc_string
    413 			p.dec = (*Buffer).dec_string
    414 			p.size = size_string
    415 		case reflect.Struct:
    416 			p.stype = t1.Elem()
    417 			p.isMarshaler = isMarshaler(t1)
    418 			p.isUnmarshaler = isUnmarshaler(t1)
    419 			if p.Wire == "bytes" {
    420 				p.enc = (*Buffer).enc_struct_message
    421 				p.dec = (*Buffer).dec_struct_message
    422 				p.size = size_struct_message
    423 			} else {
    424 				p.enc = (*Buffer).enc_struct_group
    425 				p.dec = (*Buffer).dec_struct_group
    426 				p.size = size_struct_group
    427 			}
    428 		}
    429 
    430 	case reflect.Slice:
    431 		switch t2 := t1.Elem(); t2.Kind() {
    432 		default:
    433 			logNoSliceEnc(t1, t2)
    434 			break
    435 		case reflect.Bool:
    436 			if p.Packed {
    437 				p.enc = (*Buffer).enc_slice_packed_bool
    438 				p.size = size_slice_packed_bool
    439 			} else {
    440 				p.enc = (*Buffer).enc_slice_bool
    441 				p.size = size_slice_bool
    442 			}
    443 			p.dec = (*Buffer).dec_slice_bool
    444 			p.packedDec = (*Buffer).dec_slice_packed_bool
    445 		case reflect.Int32:
    446 			if p.Packed {
    447 				p.enc = (*Buffer).enc_slice_packed_int32
    448 				p.size = size_slice_packed_int32
    449 			} else {
    450 				p.enc = (*Buffer).enc_slice_int32
    451 				p.size = size_slice_int32
    452 			}
    453 			p.dec = (*Buffer).dec_slice_int32
    454 			p.packedDec = (*Buffer).dec_slice_packed_int32
    455 		case reflect.Uint32:
    456 			if p.Packed {
    457 				p.enc = (*Buffer).enc_slice_packed_uint32
    458 				p.size = size_slice_packed_uint32
    459 			} else {
    460 				p.enc = (*Buffer).enc_slice_uint32
    461 				p.size = size_slice_uint32
    462 			}
    463 			p.dec = (*Buffer).dec_slice_int32
    464 			p.packedDec = (*Buffer).dec_slice_packed_int32
    465 		case reflect.Int64, reflect.Uint64:
    466 			if p.Packed {
    467 				p.enc = (*Buffer).enc_slice_packed_int64
    468 				p.size = size_slice_packed_int64
    469 			} else {
    470 				p.enc = (*Buffer).enc_slice_int64
    471 				p.size = size_slice_int64
    472 			}
    473 			p.dec = (*Buffer).dec_slice_int64
    474 			p.packedDec = (*Buffer).dec_slice_packed_int64
    475 		case reflect.Uint8:
    476 			p.dec = (*Buffer).dec_slice_byte
    477 			if p.proto3 {
    478 				p.enc = (*Buffer).enc_proto3_slice_byte
    479 				p.size = size_proto3_slice_byte
    480 			} else {
    481 				p.enc = (*Buffer).enc_slice_byte
    482 				p.size = size_slice_byte
    483 			}
    484 		case reflect.Float32, reflect.Float64:
    485 			switch t2.Bits() {
    486 			case 32:
    487 				// can just treat them as bits
    488 				if p.Packed {
    489 					p.enc = (*Buffer).enc_slice_packed_uint32
    490 					p.size = size_slice_packed_uint32
    491 				} else {
    492 					p.enc = (*Buffer).enc_slice_uint32
    493 					p.size = size_slice_uint32
    494 				}
    495 				p.dec = (*Buffer).dec_slice_int32
    496 				p.packedDec = (*Buffer).dec_slice_packed_int32
    497 			case 64:
    498 				// can just treat them as bits
    499 				if p.Packed {
    500 					p.enc = (*Buffer).enc_slice_packed_int64
    501 					p.size = size_slice_packed_int64
    502 				} else {
    503 					p.enc = (*Buffer).enc_slice_int64
    504 					p.size = size_slice_int64
    505 				}
    506 				p.dec = (*Buffer).dec_slice_int64
    507 				p.packedDec = (*Buffer).dec_slice_packed_int64
    508 			default:
    509 				logNoSliceEnc(t1, t2)
    510 				break
    511 			}
    512 		case reflect.String:
    513 			p.enc = (*Buffer).enc_slice_string
    514 			p.dec = (*Buffer).dec_slice_string
    515 			p.size = size_slice_string
    516 		case reflect.Ptr:
    517 			switch t3 := t2.Elem(); t3.Kind() {
    518 			default:
    519 				fmt.Fprintf(os.Stderr, "proto: no ptr oenc for %T -> %T -> %T\n", t1, t2, t3)
    520 				break
    521 			case reflect.Struct:
    522 				p.stype = t2.Elem()
    523 				p.isMarshaler = isMarshaler(t2)
    524 				p.isUnmarshaler = isUnmarshaler(t2)
    525 				if p.Wire == "bytes" {
    526 					p.enc = (*Buffer).enc_slice_struct_message
    527 					p.dec = (*Buffer).dec_slice_struct_message
    528 					p.size = size_slice_struct_message
    529 				} else {
    530 					p.enc = (*Buffer).enc_slice_struct_group
    531 					p.dec = (*Buffer).dec_slice_struct_group
    532 					p.size = size_slice_struct_group
    533 				}
    534 			}
    535 		case reflect.Slice:
    536 			switch t2.Elem().Kind() {
    537 			default:
    538 				fmt.Fprintf(os.Stderr, "proto: no slice elem oenc for %T -> %T -> %T\n", t1, t2, t2.Elem())
    539 				break
    540 			case reflect.Uint8:
    541 				p.enc = (*Buffer).enc_slice_slice_byte
    542 				p.dec = (*Buffer).dec_slice_slice_byte
    543 				p.size = size_slice_slice_byte
    544 			}
    545 		}
    546 
    547 	case reflect.Map:
    548 		p.enc = (*Buffer).enc_new_map
    549 		p.dec = (*Buffer).dec_new_map
    550 		p.size = size_new_map
    551 
    552 		p.mtype = t1
    553 		p.mkeyprop = &Properties{}
    554 		p.mkeyprop.init(reflect.PtrTo(p.mtype.Key()), "Key", f.Tag.Get("protobuf_key"), nil, lockGetProp)
    555 		p.mvalprop = &Properties{}
    556 		vtype := p.mtype.Elem()
    557 		if vtype.Kind() != reflect.Ptr && vtype.Kind() != reflect.Slice {
    558 			// The value type is not a message (*T) or bytes ([]byte),
    559 			// so we need encoders for the pointer to this type.
    560 			vtype = reflect.PtrTo(vtype)
    561 		}
    562 		p.mvalprop.init(vtype, "Value", f.Tag.Get("protobuf_val"), nil, lockGetProp)
    563 	}
    564 
    565 	// precalculate tag code
    566 	wire := p.WireType
    567 	if p.Packed {
    568 		wire = WireBytes
    569 	}
    570 	x := uint32(p.Tag)<<3 | uint32(wire)
    571 	i := 0
    572 	for i = 0; x > 127; i++ {
    573 		p.tagbuf[i] = 0x80 | uint8(x&0x7F)
    574 		x >>= 7
    575 	}
    576 	p.tagbuf[i] = uint8(x)
    577 	p.tagcode = p.tagbuf[0 : i+1]
    578 
    579 	if p.stype != nil {
    580 		if lockGetProp {
    581 			p.sprop = GetProperties(p.stype)
    582 		} else {
    583 			p.sprop = getPropertiesLocked(p.stype)
    584 		}
    585 	}
    586 }
    587 
    588 var (
    589 	marshalerType   = reflect.TypeOf((*Marshaler)(nil)).Elem()
    590 	unmarshalerType = reflect.TypeOf((*Unmarshaler)(nil)).Elem()
    591 )
    592 
    593 // isMarshaler reports whether type t implements Marshaler.
    594 func isMarshaler(t reflect.Type) bool {
    595 	// We're checking for (likely) pointer-receiver methods
    596 	// so if t is not a pointer, something is very wrong.
    597 	// The calls above only invoke isMarshaler on pointer types.
    598 	if t.Kind() != reflect.Ptr {
    599 		panic("proto: misuse of isMarshaler")
    600 	}
    601 	return t.Implements(marshalerType)
    602 }
    603 
    604 // isUnmarshaler reports whether type t implements Unmarshaler.
    605 func isUnmarshaler(t reflect.Type) bool {
    606 	// We're checking for (likely) pointer-receiver methods
    607 	// so if t is not a pointer, something is very wrong.
    608 	// The calls above only invoke isUnmarshaler on pointer types.
    609 	if t.Kind() != reflect.Ptr {
    610 		panic("proto: misuse of isUnmarshaler")
    611 	}
    612 	return t.Implements(unmarshalerType)
    613 }
    614 
    615 // Init populates the properties from a protocol buffer struct tag.
    616 func (p *Properties) Init(typ reflect.Type, name, tag string, f *reflect.StructField) {
    617 	p.init(typ, name, tag, f, true)
    618 }
    619 
    620 func (p *Properties) init(typ reflect.Type, name, tag string, f *reflect.StructField, lockGetProp bool) {
    621 	// "bytes,49,opt,def=hello!"
    622 	p.Name = name
    623 	p.OrigName = name
    624 	if f != nil {
    625 		p.field = toField(f)
    626 	}
    627 	if tag == "" {
    628 		return
    629 	}
    630 	p.Parse(tag)
    631 	p.setEncAndDec(typ, f, lockGetProp)
    632 }
    633 
    634 var (
    635 	propertiesMu  sync.RWMutex
    636 	propertiesMap = make(map[reflect.Type]*StructProperties)
    637 )
    638 
    639 // GetProperties returns the list of properties for the type represented by t.
    640 // t must represent a generated struct type of a protocol message.
    641 func GetProperties(t reflect.Type) *StructProperties {
    642 	if t.Kind() != reflect.Struct {
    643 		panic("proto: type must have kind struct")
    644 	}
    645 
    646 	// Most calls to GetProperties in a long-running program will be
    647 	// retrieving details for types we have seen before.
    648 	propertiesMu.RLock()
    649 	sprop, ok := propertiesMap[t]
    650 	propertiesMu.RUnlock()
    651 	if ok {
    652 		if collectStats {
    653 			stats.Chit++
    654 		}
    655 		return sprop
    656 	}
    657 
    658 	propertiesMu.Lock()
    659 	sprop = getPropertiesLocked(t)
    660 	propertiesMu.Unlock()
    661 	return sprop
    662 }
    663 
    664 // getPropertiesLocked requires that propertiesMu is held.
    665 func getPropertiesLocked(t reflect.Type) *StructProperties {
    666 	if prop, ok := propertiesMap[t]; ok {
    667 		if collectStats {
    668 			stats.Chit++
    669 		}
    670 		return prop
    671 	}
    672 	if collectStats {
    673 		stats.Cmiss++
    674 	}
    675 
    676 	prop := new(StructProperties)
    677 	// in case of recursive protos, fill this in now.
    678 	propertiesMap[t] = prop
    679 
    680 	// build properties
    681 	prop.extendable = reflect.PtrTo(t).Implements(extendableProtoType) ||
    682 		reflect.PtrTo(t).Implements(extendableProtoV1Type)
    683 	prop.unrecField = invalidField
    684 	prop.Prop = make([]*Properties, t.NumField())
    685 	prop.order = make([]int, t.NumField())
    686 
    687 	for i := 0; i < t.NumField(); i++ {
    688 		f := t.Field(i)
    689 		p := new(Properties)
    690 		name := f.Name
    691 		p.init(f.Type, name, f.Tag.Get("protobuf"), &f, false)
    692 
    693 		if f.Name == "XXX_InternalExtensions" { // special case
    694 			p.enc = (*Buffer).enc_exts
    695 			p.dec = nil // not needed
    696 			p.size = size_exts
    697 		} else if f.Name == "XXX_extensions" { // special case
    698 			p.enc = (*Buffer).enc_map
    699 			p.dec = nil // not needed
    700 			p.size = size_map
    701 		} else if f.Name == "XXX_unrecognized" { // special case
    702 			prop.unrecField = toField(&f)
    703 		}
    704 		oneof := f.Tag.Get("protobuf_oneof") // special case
    705 		if oneof != "" {
    706 			// Oneof fields don't use the traditional protobuf tag.
    707 			p.OrigName = oneof
    708 		}
    709 		prop.Prop[i] = p
    710 		prop.order[i] = i
    711 		if debug {
    712 			print(i, " ", f.Name, " ", t.String(), " ")
    713 			if p.Tag > 0 {
    714 				print(p.String())
    715 			}
    716 			print("\n")
    717 		}
    718 		if p.enc == nil && !strings.HasPrefix(f.Name, "XXX_") && oneof == "" {
    719 			fmt.Fprintln(os.Stderr, "proto: no encoder for", f.Name, f.Type.String(), "[GetProperties]")
    720 		}
    721 	}
    722 
    723 	// Re-order prop.order.
    724 	sort.Sort(prop)
    725 
    726 	type oneofMessage interface {
    727 		XXX_OneofFuncs() (func(Message, *Buffer) error, func(Message, int, int, *Buffer) (bool, error), func(Message) int, []interface{})
    728 	}
    729 	if om, ok := reflect.Zero(reflect.PtrTo(t)).Interface().(oneofMessage); ok {
    730 		var oots []interface{}
    731 		prop.oneofMarshaler, prop.oneofUnmarshaler, prop.oneofSizer, oots = om.XXX_OneofFuncs()
    732 		prop.stype = t
    733 
    734 		// Interpret oneof metadata.
    735 		prop.OneofTypes = make(map[string]*OneofProperties)
    736 		for _, oot := range oots {
    737 			oop := &OneofProperties{
    738 				Type: reflect.ValueOf(oot).Type(), // *T
    739 				Prop: new(Properties),
    740 			}
    741 			sft := oop.Type.Elem().Field(0)
    742 			oop.Prop.Name = sft.Name
    743 			oop.Prop.Parse(sft.Tag.Get("protobuf"))
    744 			// There will be exactly one interface field that
    745 			// this new value is assignable to.
    746 			for i := 0; i < t.NumField(); i++ {
    747 				f := t.Field(i)
    748 				if f.Type.Kind() != reflect.Interface {
    749 					continue
    750 				}
    751 				if !oop.Type.AssignableTo(f.Type) {
    752 					continue
    753 				}
    754 				oop.Field = i
    755 				break
    756 			}
    757 			prop.OneofTypes[oop.Prop.OrigName] = oop
    758 		}
    759 	}
    760 
    761 	// build required counts
    762 	// build tags
    763 	reqCount := 0
    764 	prop.decoderOrigNames = make(map[string]int)
    765 	for i, p := range prop.Prop {
    766 		if strings.HasPrefix(p.Name, "XXX_") {
    767 			// Internal fields should not appear in tags/origNames maps.
    768 			// They are handled specially when encoding and decoding.
    769 			continue
    770 		}
    771 		if p.Required {
    772 			reqCount++
    773 		}
    774 		prop.decoderTags.put(p.Tag, i)
    775 		prop.decoderOrigNames[p.OrigName] = i
    776 	}
    777 	prop.reqCount = reqCount
    778 
    779 	return prop
    780 }
    781 
    782 // Return the Properties object for the x[0]'th field of the structure.
    783 func propByIndex(t reflect.Type, x []int) *Properties {
    784 	if len(x) != 1 {
    785 		fmt.Fprintf(os.Stderr, "proto: field index dimension %d (not 1) for type %s\n", len(x), t)
    786 		return nil
    787 	}
    788 	prop := GetProperties(t)
    789 	return prop.Prop[x[0]]
    790 }
    791 
    792 // Get the address and type of a pointer to a struct from an interface.
    793 func getbase(pb Message) (t reflect.Type, b structPointer, err error) {
    794 	if pb == nil {
    795 		err = ErrNil
    796 		return
    797 	}
    798 	// get the reflect type of the pointer to the struct.
    799 	t = reflect.TypeOf(pb)
    800 	// get the address of the struct.
    801 	value := reflect.ValueOf(pb)
    802 	b = toStructPointer(value)
    803 	return
    804 }
    805 
    806 // A global registry of enum types.
    807 // The generated code will register the generated maps by calling RegisterEnum.
    808 
    809 var enumValueMaps = make(map[string]map[string]int32)
    810 
    811 // RegisterEnum is called from the generated code to install the enum descriptor
    812 // maps into the global table to aid parsing text format protocol buffers.
    813 func RegisterEnum(typeName string, unusedNameMap map[int32]string, valueMap map[string]int32) {
    814 	if _, ok := enumValueMaps[typeName]; ok {
    815 		panic("proto: duplicate enum registered: " + typeName)
    816 	}
    817 	enumValueMaps[typeName] = valueMap
    818 }
    819 
    820 // EnumValueMap returns the mapping from names to integers of the
    821 // enum type enumType, or a nil if not found.
    822 func EnumValueMap(enumType string) map[string]int32 {
    823 	return enumValueMaps[enumType]
    824 }
    825 
    826 // A registry of all linked message types.
    827 // The string is a fully-qualified proto name ("pkg.Message").
    828 var (
    829 	protoTypes    = make(map[string]reflect.Type)
    830 	revProtoTypes = make(map[reflect.Type]string)
    831 )
    832 
    833 // RegisterType is called from generated code and maps from the fully qualified
    834 // proto name to the type (pointer to struct) of the protocol buffer.
    835 func RegisterType(x Message, name string) {
    836 	if _, ok := protoTypes[name]; ok {
    837 		// TODO: Some day, make this a panic.
    838 		log.Printf("proto: duplicate proto type registered: %s", name)
    839 		return
    840 	}
    841 	t := reflect.TypeOf(x)
    842 	protoTypes[name] = t
    843 	revProtoTypes[t] = name
    844 }
    845 
    846 // MessageName returns the fully-qualified proto name for the given message type.
    847 func MessageName(x Message) string {
    848 	type xname interface {
    849 		XXX_MessageName() string
    850 	}
    851 	if m, ok := x.(xname); ok {
    852 		return m.XXX_MessageName()
    853 	}
    854 	return revProtoTypes[reflect.TypeOf(x)]
    855 }
    856 
    857 // MessageType returns the message type (pointer to struct) for a named message.
    858 func MessageType(name string) reflect.Type { return protoTypes[name] }
    859 
    860 // A registry of all linked proto files.
    861 var (
    862 	protoFiles = make(map[string][]byte) // file name => fileDescriptor
    863 )
    864 
    865 // RegisterFile is called from generated code and maps from the
    866 // full file name of a .proto file to its compressed FileDescriptorProto.
    867 func RegisterFile(filename string, fileDescriptor []byte) {
    868 	protoFiles[filename] = fileDescriptor
    869 }
    870 
    871 // FileDescriptor returns the compressed FileDescriptorProto for a .proto file.
    872 func FileDescriptor(filename string) []byte { return protoFiles[filename] }
    873