github.com/insionng/yougam@v0.0.0-20170714101924-2bc18d833463/libraries/golang/protobuf/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  // https://yougam/libraries/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.enc = (*Buffer).enc_slice_byte
   477  			p.dec = (*Buffer).dec_slice_byte
   478  			p.size = size_slice_byte
   479  			// This is a []byte, which is either a bytes field,
   480  			// or the value of a map field. In the latter case,
   481  			// we always encode an empty []byte, so we should not
   482  			// use the proto3 enc/size funcs.
   483  			// f == nil iff this is the key/value of a map field.
   484  			if p.proto3 && f != nil {
   485  				p.enc = (*Buffer).enc_proto3_slice_byte
   486  				p.size = size_proto3_slice_byte
   487  			}
   488  		case reflect.Float32, reflect.Float64:
   489  			switch t2.Bits() {
   490  			case 32:
   491  				// can just treat them as bits
   492  				if p.Packed {
   493  					p.enc = (*Buffer).enc_slice_packed_uint32
   494  					p.size = size_slice_packed_uint32
   495  				} else {
   496  					p.enc = (*Buffer).enc_slice_uint32
   497  					p.size = size_slice_uint32
   498  				}
   499  				p.dec = (*Buffer).dec_slice_int32
   500  				p.packedDec = (*Buffer).dec_slice_packed_int32
   501  			case 64:
   502  				// can just treat them as bits
   503  				if p.Packed {
   504  					p.enc = (*Buffer).enc_slice_packed_int64
   505  					p.size = size_slice_packed_int64
   506  				} else {
   507  					p.enc = (*Buffer).enc_slice_int64
   508  					p.size = size_slice_int64
   509  				}
   510  				p.dec = (*Buffer).dec_slice_int64
   511  				p.packedDec = (*Buffer).dec_slice_packed_int64
   512  			default:
   513  				logNoSliceEnc(t1, t2)
   514  				break
   515  			}
   516  		case reflect.String:
   517  			p.enc = (*Buffer).enc_slice_string
   518  			p.dec = (*Buffer).dec_slice_string
   519  			p.size = size_slice_string
   520  		case reflect.Ptr:
   521  			switch t3 := t2.Elem(); t3.Kind() {
   522  			default:
   523  				fmt.Fprintf(os.Stderr, "proto: no ptr oenc for %T -> %T -> %T\n", t1, t2, t3)
   524  				break
   525  			case reflect.Struct:
   526  				p.stype = t2.Elem()
   527  				p.isMarshaler = isMarshaler(t2)
   528  				p.isUnmarshaler = isUnmarshaler(t2)
   529  				if p.Wire == "bytes" {
   530  					p.enc = (*Buffer).enc_slice_struct_message
   531  					p.dec = (*Buffer).dec_slice_struct_message
   532  					p.size = size_slice_struct_message
   533  				} else {
   534  					p.enc = (*Buffer).enc_slice_struct_group
   535  					p.dec = (*Buffer).dec_slice_struct_group
   536  					p.size = size_slice_struct_group
   537  				}
   538  			}
   539  		case reflect.Slice:
   540  			switch t2.Elem().Kind() {
   541  			default:
   542  				fmt.Fprintf(os.Stderr, "proto: no slice elem oenc for %T -> %T -> %T\n", t1, t2, t2.Elem())
   543  				break
   544  			case reflect.Uint8:
   545  				p.enc = (*Buffer).enc_slice_slice_byte
   546  				p.dec = (*Buffer).dec_slice_slice_byte
   547  				p.size = size_slice_slice_byte
   548  			}
   549  		}
   550  
   551  	case reflect.Map:
   552  		p.enc = (*Buffer).enc_new_map
   553  		p.dec = (*Buffer).dec_new_map
   554  		p.size = size_new_map
   555  
   556  		p.mtype = t1
   557  		p.mkeyprop = &Properties{}
   558  		p.mkeyprop.init(reflect.PtrTo(p.mtype.Key()), "Key", f.Tag.Get("protobuf_key"), nil, lockGetProp)
   559  		p.mvalprop = &Properties{}
   560  		vtype := p.mtype.Elem()
   561  		if vtype.Kind() != reflect.Ptr && vtype.Kind() != reflect.Slice {
   562  			// The value type is not a message (*T) or bytes ([]byte),
   563  			// so we need encoders for the pointer to this type.
   564  			vtype = reflect.PtrTo(vtype)
   565  		}
   566  		p.mvalprop.init(vtype, "Value", f.Tag.Get("protobuf_val"), nil, lockGetProp)
   567  	}
   568  
   569  	// precalculate tag code
   570  	wire := p.WireType
   571  	if p.Packed {
   572  		wire = WireBytes
   573  	}
   574  	x := uint32(p.Tag)<<3 | uint32(wire)
   575  	i := 0
   576  	for i = 0; x > 127; i++ {
   577  		p.tagbuf[i] = 0x80 | uint8(x&0x7F)
   578  		x >>= 7
   579  	}
   580  	p.tagbuf[i] = uint8(x)
   581  	p.tagcode = p.tagbuf[0 : i+1]
   582  
   583  	if p.stype != nil {
   584  		if lockGetProp {
   585  			p.sprop = GetProperties(p.stype)
   586  		} else {
   587  			p.sprop = getPropertiesLocked(p.stype)
   588  		}
   589  	}
   590  }
   591  
   592  var (
   593  	marshalerType   = reflect.TypeOf((*Marshaler)(nil)).Elem()
   594  	unmarshalerType = reflect.TypeOf((*Unmarshaler)(nil)).Elem()
   595  )
   596  
   597  // isMarshaler reports whether type t implements Marshaler.
   598  func isMarshaler(t reflect.Type) bool {
   599  	// We're checking for (likely) pointer-receiver methods
   600  	// so if t is not a pointer, something is very wrong.
   601  	// The calls above only invoke isMarshaler on pointer types.
   602  	if t.Kind() != reflect.Ptr {
   603  		panic("proto: misuse of isMarshaler")
   604  	}
   605  	return t.Implements(marshalerType)
   606  }
   607  
   608  // isUnmarshaler reports whether type t implements Unmarshaler.
   609  func isUnmarshaler(t reflect.Type) bool {
   610  	// We're checking for (likely) pointer-receiver methods
   611  	// so if t is not a pointer, something is very wrong.
   612  	// The calls above only invoke isUnmarshaler on pointer types.
   613  	if t.Kind() != reflect.Ptr {
   614  		panic("proto: misuse of isUnmarshaler")
   615  	}
   616  	return t.Implements(unmarshalerType)
   617  }
   618  
   619  // Init populates the properties from a protocol buffer struct tag.
   620  func (p *Properties) Init(typ reflect.Type, name, tag string, f *reflect.StructField) {
   621  	p.init(typ, name, tag, f, true)
   622  }
   623  
   624  func (p *Properties) init(typ reflect.Type, name, tag string, f *reflect.StructField, lockGetProp bool) {
   625  	// "bytes,49,opt,def=hello!"
   626  	p.Name = name
   627  	p.OrigName = name
   628  	if f != nil {
   629  		p.field = toField(f)
   630  	}
   631  	if tag == "" {
   632  		return
   633  	}
   634  	p.Parse(tag)
   635  	p.setEncAndDec(typ, f, lockGetProp)
   636  }
   637  
   638  var (
   639  	propertiesMu  sync.RWMutex
   640  	propertiesMap = make(map[reflect.Type]*StructProperties)
   641  )
   642  
   643  // GetProperties returns the list of properties for the type represented by t.
   644  // t must represent a generated struct type of a protocol message.
   645  func GetProperties(t reflect.Type) *StructProperties {
   646  	if t.Kind() != reflect.Struct {
   647  		panic("proto: type must have kind struct")
   648  	}
   649  
   650  	// Most calls to GetProperties in a long-running program will be
   651  	// retrieving details for types we have seen before.
   652  	propertiesMu.RLock()
   653  	sprop, ok := propertiesMap[t]
   654  	propertiesMu.RUnlock()
   655  	if ok {
   656  		if collectStats {
   657  			stats.Chit++
   658  		}
   659  		return sprop
   660  	}
   661  
   662  	propertiesMu.Lock()
   663  	sprop = getPropertiesLocked(t)
   664  	propertiesMu.Unlock()
   665  	return sprop
   666  }
   667  
   668  // getPropertiesLocked requires that propertiesMu is held.
   669  func getPropertiesLocked(t reflect.Type) *StructProperties {
   670  	if prop, ok := propertiesMap[t]; ok {
   671  		if collectStats {
   672  			stats.Chit++
   673  		}
   674  		return prop
   675  	}
   676  	if collectStats {
   677  		stats.Cmiss++
   678  	}
   679  
   680  	prop := new(StructProperties)
   681  	// in case of recursive protos, fill this in now.
   682  	propertiesMap[t] = prop
   683  
   684  	// build properties
   685  	prop.extendable = reflect.PtrTo(t).Implements(extendableProtoType)
   686  	prop.unrecField = invalidField
   687  	prop.Prop = make([]*Properties, t.NumField())
   688  	prop.order = make([]int, t.NumField())
   689  
   690  	for i := 0; i < t.NumField(); i++ {
   691  		f := t.Field(i)
   692  		p := new(Properties)
   693  		name := f.Name
   694  		p.init(f.Type, name, f.Tag.Get("protobuf"), &f, false)
   695  
   696  		if f.Name == "XXX_extensions" { // special case
   697  			p.enc = (*Buffer).enc_map
   698  			p.dec = nil // not needed
   699  			p.size = size_map
   700  		}
   701  		if f.Name == "XXX_unrecognized" { // special case
   702  			prop.unrecField = toField(&f)
   703  		}
   704  		oneof := f.Tag.Get("protobuf_oneof") != "" // special case
   705  		prop.Prop[i] = p
   706  		prop.order[i] = i
   707  		if debug {
   708  			print(i, " ", f.Name, " ", t.String(), " ")
   709  			if p.Tag > 0 {
   710  				print(p.String())
   711  			}
   712  			print("\n")
   713  		}
   714  		if p.enc == nil && !strings.HasPrefix(f.Name, "XXX_") && !oneof {
   715  			fmt.Fprintln(os.Stderr, "proto: no encoder for", f.Name, f.Type.String(), "[GetProperties]")
   716  		}
   717  	}
   718  
   719  	// Re-order prop.order.
   720  	sort.Sort(prop)
   721  
   722  	type oneofMessage interface {
   723  		XXX_OneofFuncs() (func(Message, *Buffer) error, func(Message, int, int, *Buffer) (bool, error), func(Message) int, []interface{})
   724  	}
   725  	if om, ok := reflect.Zero(reflect.PtrTo(t)).Interface().(oneofMessage); ok {
   726  		var oots []interface{}
   727  		prop.oneofMarshaler, prop.oneofUnmarshaler, prop.oneofSizer, oots = om.XXX_OneofFuncs()
   728  		prop.stype = t
   729  
   730  		// Interpret oneof metadata.
   731  		prop.OneofTypes = make(map[string]*OneofProperties)
   732  		for _, oot := range oots {
   733  			oop := &OneofProperties{
   734  				Type: reflect.ValueOf(oot).Type(), // *T
   735  				Prop: new(Properties),
   736  			}
   737  			sft := oop.Type.Elem().Field(0)
   738  			oop.Prop.Name = sft.Name
   739  			oop.Prop.Parse(sft.Tag.Get("protobuf"))
   740  			// There will be exactly one interface field that
   741  			// this new value is assignable to.
   742  			for i := 0; i < t.NumField(); i++ {
   743  				f := t.Field(i)
   744  				if f.Type.Kind() != reflect.Interface {
   745  					continue
   746  				}
   747  				if !oop.Type.AssignableTo(f.Type) {
   748  					continue
   749  				}
   750  				oop.Field = i
   751  				break
   752  			}
   753  			prop.OneofTypes[oop.Prop.OrigName] = oop
   754  		}
   755  	}
   756  
   757  	// build required counts
   758  	// build tags
   759  	reqCount := 0
   760  	prop.decoderOrigNames = make(map[string]int)
   761  	for i, p := range prop.Prop {
   762  		if strings.HasPrefix(p.Name, "XXX_") {
   763  			// Internal fields should not appear in tags/origNames maps.
   764  			// They are handled specially when encoding and decoding.
   765  			continue
   766  		}
   767  		if p.Required {
   768  			reqCount++
   769  		}
   770  		prop.decoderTags.put(p.Tag, i)
   771  		prop.decoderOrigNames[p.OrigName] = i
   772  	}
   773  	prop.reqCount = reqCount
   774  
   775  	return prop
   776  }
   777  
   778  // Return the Properties object for the x[0]'th field of the structure.
   779  func propByIndex(t reflect.Type, x []int) *Properties {
   780  	if len(x) != 1 {
   781  		fmt.Fprintf(os.Stderr, "proto: field index dimension %d (not 1) for type %s\n", len(x), t)
   782  		return nil
   783  	}
   784  	prop := GetProperties(t)
   785  	return prop.Prop[x[0]]
   786  }
   787  
   788  // Get the address and type of a pointer to a struct from an interface.
   789  func getbase(pb Message) (t reflect.Type, b structPointer, err error) {
   790  	if pb == nil {
   791  		err = ErrNil
   792  		return
   793  	}
   794  	// get the reflect type of the pointer to the struct.
   795  	t = reflect.TypeOf(pb)
   796  	// get the address of the struct.
   797  	value := reflect.ValueOf(pb)
   798  	b = toStructPointer(value)
   799  	return
   800  }
   801  
   802  // A global registry of enum types.
   803  // The generated code will register the generated maps by calling RegisterEnum.
   804  
   805  var enumValueMaps = make(map[string]map[string]int32)
   806  
   807  // RegisterEnum is called from the generated code to install the enum descriptor
   808  // maps into the global table to aid parsing text format protocol buffers.
   809  func RegisterEnum(typeName string, unusedNameMap map[int32]string, valueMap map[string]int32) {
   810  	if _, ok := enumValueMaps[typeName]; ok {
   811  		panic("proto: duplicate enum registered: " + typeName)
   812  	}
   813  	enumValueMaps[typeName] = valueMap
   814  }
   815  
   816  // EnumValueMap returns the mapping from names to integers of the
   817  // enum type enumType, or a nil if not found.
   818  func EnumValueMap(enumType string) map[string]int32 {
   819  	return enumValueMaps[enumType]
   820  }
   821  
   822  // A registry of all linked message types.
   823  // The string is a fully-qualified proto name ("pkg.Message").
   824  var (
   825  	protoTypes    = make(map[string]reflect.Type)
   826  	revProtoTypes = make(map[reflect.Type]string)
   827  )
   828  
   829  // RegisterType is called from generated code and maps from the fully qualified
   830  // proto name to the type (pointer to struct) of the protocol buffer.
   831  func RegisterType(x Message, name string) {
   832  	if _, ok := protoTypes[name]; ok {
   833  		// TODO: Some day, make this a panic.
   834  		log.Printf("proto: duplicate proto type registered: %s", name)
   835  		return
   836  	}
   837  	t := reflect.TypeOf(x)
   838  	protoTypes[name] = t
   839  	revProtoTypes[t] = name
   840  }
   841  
   842  // MessageName returns the fully-qualified proto name for the given message type.
   843  func MessageName(x Message) string { return revProtoTypes[reflect.TypeOf(x)] }
   844  
   845  // MessageType returns the message type (pointer to struct) for a named message.
   846  func MessageType(name string) reflect.Type { return protoTypes[name] }