github.com/insionng/yougam@v0.0.0-20170714101924-2bc18d833463/libraries/golang/protobuf/proto/lib.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  /*
    33  Package proto converts data structures to and from the wire format of
    34  protocol buffers.  It works in concert with the Go source code generated
    35  for .proto files by the protocol compiler.
    36  
    37  A summary of the properties of the protocol buffer interface
    38  for a protocol buffer variable v:
    39  
    40    - Names are turned from camel_case to CamelCase for export.
    41    - There are no methods on v to set fields; just treat
    42  	them as structure fields.
    43    - There are getters that return a field's value if set,
    44  	and return the field's default value if unset.
    45  	The getters work even if the receiver is a nil message.
    46    - The zero value for a struct is its correct initialization state.
    47  	All desired fields must be set before marshaling.
    48    - A Reset() method will restore a protobuf struct to its zero state.
    49    - Non-repeated fields are pointers to the values; nil means unset.
    50  	That is, optional or required field int32 f becomes F *int32.
    51    - Repeated fields are slices.
    52    - Helper functions are available to aid the setting of fields.
    53  	msg.Foo = proto.String("hello") // set field
    54    - Constants are defined to hold the default values of all fields that
    55  	have them.  They have the form Default_StructName_FieldName.
    56  	Because the getter methods handle defaulted values,
    57  	direct use of these constants should be rare.
    58    - Enums are given type names and maps from names to values.
    59  	Enum values are prefixed by the enclosing message's name, or by the
    60  	enum's type name if it is a top-level enum. Enum types have a String
    61  	method, and a Enum method to assist in message construction.
    62    - Nested messages, groups and enums have type names prefixed with the name of
    63  	the surrounding message type.
    64    - Extensions are given descriptor names that start with E_,
    65  	followed by an underscore-delimited list of the nested messages
    66  	that contain it (if any) followed by the CamelCased name of the
    67  	extension field itself.  HasExtension, ClearExtension, GetExtension
    68  	and SetExtension are functions for manipulating extensions.
    69    - Oneof field sets are given a single field in their message,
    70  	with distinguished wrapper types for each possible field value.
    71    - Marshal and Unmarshal are functions to encode and decode the wire format.
    72  
    73  When the .proto file specifies `syntax="proto3"`, there are some differences:
    74  
    75    - Non-repeated fields of non-message type are values instead of pointers.
    76    - Getters are only generated for message and oneof fields.
    77    - Enum types do not get an Enum method.
    78  
    79  The simplest way to describe this is to see an example.
    80  Given file test.proto, containing
    81  
    82  	package example;
    83  
    84  	enum FOO { X = 17; }
    85  
    86  	message Test {
    87  	  required string label = 1;
    88  	  optional int32 type = 2 [default=77];
    89  	  repeated int64 reps = 3;
    90  	  optional group OptionalGroup = 4 {
    91  	    required string RequiredField = 5;
    92  	  }
    93  	  oneof union {
    94  	    int32 number = 6;
    95  	    string name = 7;
    96  	  }
    97  	}
    98  
    99  The resulting file, test.pb.go, is:
   100  
   101  	package example
   102  
   103  	import proto "github.com/insionng/yougam/libraries/golang/protobuf/proto"
   104  	import math "math"
   105  
   106  	type FOO int32
   107  	const (
   108  		FOO_X FOO = 17
   109  	)
   110  	var FOO_name = map[int32]string{
   111  		17: "X",
   112  	}
   113  	var FOO_value = map[string]int32{
   114  		"X": 17,
   115  	}
   116  
   117  	func (x FOO) Enum() *FOO {
   118  		p := new(FOO)
   119  		*p = x
   120  		return p
   121  	}
   122  	func (x FOO) String() string {
   123  		return proto.EnumName(FOO_name, int32(x))
   124  	}
   125  	func (x *FOO) UnmarshalJSON(data []byte) error {
   126  		value, err := proto.UnmarshalJSONEnum(FOO_value, data)
   127  		if err != nil {
   128  			return err
   129  		}
   130  		*x = FOO(value)
   131  		return nil
   132  	}
   133  
   134  	type Test struct {
   135  		Label         *string             `protobuf:"bytes,1,req,name=label" json:"label,omitempty"`
   136  		Type          *int32              `protobuf:"varint,2,opt,name=type,def=77" json:"type,omitempty"`
   137  		Reps          []int64             `protobuf:"varint,3,rep,name=reps" json:"reps,omitempty"`
   138  		Optionalgroup *Test_OptionalGroup `protobuf:"group,4,opt,name=OptionalGroup" json:"optionalgroup,omitempty"`
   139  		// Types that are valid to be assigned to Union:
   140  		//	*Test_Number
   141  		//	*Test_Name
   142  		Union            isTest_Union `protobuf_oneof:"union"`
   143  		XXX_unrecognized []byte       `json:"-"`
   144  	}
   145  	func (m *Test) Reset()         { *m = Test{} }
   146  	func (m *Test) String() string { return proto.CompactTextString(m) }
   147  	func (*Test) ProtoMessage() {}
   148  
   149  	type isTest_Union interface {
   150  		isTest_Union()
   151  	}
   152  
   153  	type Test_Number struct {
   154  		Number int32 `protobuf:"varint,6,opt,name=number"`
   155  	}
   156  	type Test_Name struct {
   157  		Name string `protobuf:"bytes,7,opt,name=name"`
   158  	}
   159  
   160  	func (*Test_Number) isTest_Union() {}
   161  	func (*Test_Name) isTest_Union()   {}
   162  
   163  	func (m *Test) GetUnion() isTest_Union {
   164  		if m != nil {
   165  			return m.Union
   166  		}
   167  		return nil
   168  	}
   169  	const Default_Test_Type int32 = 77
   170  
   171  	func (m *Test) GetLabel() string {
   172  		if m != nil && m.Label != nil {
   173  			return *m.Label
   174  		}
   175  		return ""
   176  	}
   177  
   178  	func (m *Test) GetType() int32 {
   179  		if m != nil && m.Type != nil {
   180  			return *m.Type
   181  		}
   182  		return Default_Test_Type
   183  	}
   184  
   185  	func (m *Test) GetOptionalgroup() *Test_OptionalGroup {
   186  		if m != nil {
   187  			return m.Optionalgroup
   188  		}
   189  		return nil
   190  	}
   191  
   192  	type Test_OptionalGroup struct {
   193  		RequiredField *string `protobuf:"bytes,5,req" json:"RequiredField,omitempty"`
   194  	}
   195  	func (m *Test_OptionalGroup) Reset()         { *m = Test_OptionalGroup{} }
   196  	func (m *Test_OptionalGroup) String() string { return proto.CompactTextString(m) }
   197  
   198  	func (m *Test_OptionalGroup) GetRequiredField() string {
   199  		if m != nil && m.RequiredField != nil {
   200  			return *m.RequiredField
   201  		}
   202  		return ""
   203  	}
   204  
   205  	func (m *Test) GetNumber() int32 {
   206  		if x, ok := m.GetUnion().(*Test_Number); ok {
   207  			return x.Number
   208  		}
   209  		return 0
   210  	}
   211  
   212  	func (m *Test) GetName() string {
   213  		if x, ok := m.GetUnion().(*Test_Name); ok {
   214  			return x.Name
   215  		}
   216  		return ""
   217  	}
   218  
   219  	func init() {
   220  		proto.RegisterEnum("example.FOO", FOO_name, FOO_value)
   221  	}
   222  
   223  To create and play with a Test object:
   224  
   225  	package main
   226  
   227  	import (
   228  		"log"
   229  
   230  		"github.com/insionng/yougam/libraries/golang/protobuf/proto"
   231  		pb "./example.pb"
   232  	)
   233  
   234  	func main() {
   235  		test := &pb.Test{
   236  			Label: proto.String("hello"),
   237  			Type:  proto.Int32(17),
   238  			Reps:  []int64{1, 2, 3},
   239  			Optionalgroup: &pb.Test_OptionalGroup{
   240  				RequiredField: proto.String("good bye"),
   241  			},
   242  			Union: &pb.Test_Name{"fred"},
   243  		}
   244  		data, err := proto.Marshal(test)
   245  		if err != nil {
   246  			log.Fatal("marshaling error: ", err)
   247  		}
   248  		newTest := &pb.Test{}
   249  		err = proto.Unmarshal(data, newTest)
   250  		if err != nil {
   251  			log.Fatal("unmarshaling error: ", err)
   252  		}
   253  		// Now test and newTest contain the same data.
   254  		if test.GetLabel() != newTest.GetLabel() {
   255  			log.Fatalf("data mismatch %q != %q", test.GetLabel(), newTest.GetLabel())
   256  		}
   257  		// Use a type switch to determine which oneof was set.
   258  		switch u := test.Union.(type) {
   259  		case *pb.Test_Number: // u.Number contains the number.
   260  		case *pb.Test_Name: // u.Name contains the string.
   261  		}
   262  		// etc.
   263  	}
   264  */
   265  package proto
   266  
   267  import (
   268  	"encoding/json"
   269  	"fmt"
   270  	"log"
   271  	"reflect"
   272  	"sort"
   273  	"strconv"
   274  	"sync"
   275  )
   276  
   277  // Message is implemented by generated protocol buffer messages.
   278  type Message interface {
   279  	Reset()
   280  	String() string
   281  	ProtoMessage()
   282  }
   283  
   284  // Stats records allocation details about the protocol buffer encoders
   285  // and decoders.  Useful for tuning the library itself.
   286  type Stats struct {
   287  	Emalloc uint64 // mallocs in encode
   288  	Dmalloc uint64 // mallocs in decode
   289  	Encode  uint64 // number of encodes
   290  	Decode  uint64 // number of decodes
   291  	Chit    uint64 // number of cache hits
   292  	Cmiss   uint64 // number of cache misses
   293  	Size    uint64 // number of sizes
   294  }
   295  
   296  // Set to true to enable stats collection.
   297  const collectStats = false
   298  
   299  var stats Stats
   300  
   301  // GetStats returns a copy of the global Stats structure.
   302  func GetStats() Stats { return stats }
   303  
   304  // A Buffer is a buffer manager for marshaling and unmarshaling
   305  // protocol buffers.  It may be reused between invocations to
   306  // reduce memory usage.  It is not necessary to use a Buffer;
   307  // the global functions Marshal and Unmarshal create a
   308  // temporary Buffer and are fine for most applications.
   309  type Buffer struct {
   310  	buf   []byte // encode/decode byte stream
   311  	index int    // write point
   312  
   313  	// pools of basic types to amortize allocation.
   314  	bools   []bool
   315  	uint32s []uint32
   316  	uint64s []uint64
   317  
   318  	// extra pools, only used with pointer_reflect.go
   319  	int32s   []int32
   320  	int64s   []int64
   321  	float32s []float32
   322  	float64s []float64
   323  }
   324  
   325  // NewBuffer allocates a new Buffer and initializes its internal data to
   326  // the contents of the argument slice.
   327  func NewBuffer(e []byte) *Buffer {
   328  	return &Buffer{buf: e}
   329  }
   330  
   331  // Reset resets the Buffer, ready for marshaling a new protocol buffer.
   332  func (p *Buffer) Reset() {
   333  	p.buf = p.buf[0:0] // for reading/writing
   334  	p.index = 0        // for reading
   335  }
   336  
   337  // SetBuf replaces the internal buffer with the slice,
   338  // ready for unmarshaling the contents of the slice.
   339  func (p *Buffer) SetBuf(s []byte) {
   340  	p.buf = s
   341  	p.index = 0
   342  }
   343  
   344  // Bytes returns the contents of the Buffer.
   345  func (p *Buffer) Bytes() []byte { return p.buf }
   346  
   347  /*
   348   * Helper routines for simplifying the creation of optional fields of basic type.
   349   */
   350  
   351  // Bool is a helper routine that allocates a new bool value
   352  // to store v and returns a pointer to it.
   353  func Bool(v bool) *bool {
   354  	return &v
   355  }
   356  
   357  // Int32 is a helper routine that allocates a new int32 value
   358  // to store v and returns a pointer to it.
   359  func Int32(v int32) *int32 {
   360  	return &v
   361  }
   362  
   363  // Int is a helper routine that allocates a new int32 value
   364  // to store v and returns a pointer to it, but unlike Int32
   365  // its argument value is an int.
   366  func Int(v int) *int32 {
   367  	p := new(int32)
   368  	*p = int32(v)
   369  	return p
   370  }
   371  
   372  // Int64 is a helper routine that allocates a new int64 value
   373  // to store v and returns a pointer to it.
   374  func Int64(v int64) *int64 {
   375  	return &v
   376  }
   377  
   378  // Float32 is a helper routine that allocates a new float32 value
   379  // to store v and returns a pointer to it.
   380  func Float32(v float32) *float32 {
   381  	return &v
   382  }
   383  
   384  // Float64 is a helper routine that allocates a new float64 value
   385  // to store v and returns a pointer to it.
   386  func Float64(v float64) *float64 {
   387  	return &v
   388  }
   389  
   390  // Uint32 is a helper routine that allocates a new uint32 value
   391  // to store v and returns a pointer to it.
   392  func Uint32(v uint32) *uint32 {
   393  	return &v
   394  }
   395  
   396  // Uint64 is a helper routine that allocates a new uint64 value
   397  // to store v and returns a pointer to it.
   398  func Uint64(v uint64) *uint64 {
   399  	return &v
   400  }
   401  
   402  // String is a helper routine that allocates a new string value
   403  // to store v and returns a pointer to it.
   404  func String(v string) *string {
   405  	return &v
   406  }
   407  
   408  // EnumName is a helper function to simplify printing protocol buffer enums
   409  // by name.  Given an enum map and a value, it returns a useful string.
   410  func EnumName(m map[int32]string, v int32) string {
   411  	s, ok := m[v]
   412  	if ok {
   413  		return s
   414  	}
   415  	return strconv.Itoa(int(v))
   416  }
   417  
   418  // UnmarshalJSONEnum is a helper function to simplify recovering enum int values
   419  // from their JSON-encoded representation. Given a map from the enum's symbolic
   420  // names to its int values, and a byte buffer containing the JSON-encoded
   421  // value, it returns an int32 that can be cast to the enum type by the caller.
   422  //
   423  // The function can deal with both JSON representations, numeric and symbolic.
   424  func UnmarshalJSONEnum(m map[string]int32, data []byte, enumName string) (int32, error) {
   425  	if data[0] == '"' {
   426  		// New style: enums are strings.
   427  		var repr string
   428  		if err := json.Unmarshal(data, &repr); err != nil {
   429  			return -1, err
   430  		}
   431  		val, ok := m[repr]
   432  		if !ok {
   433  			return 0, fmt.Errorf("unrecognized enum %s value %q", enumName, repr)
   434  		}
   435  		return val, nil
   436  	}
   437  	// Old style: enums are ints.
   438  	var val int32
   439  	if err := json.Unmarshal(data, &val); err != nil {
   440  		return 0, fmt.Errorf("cannot unmarshal %#q into enum %s", data, enumName)
   441  	}
   442  	return val, nil
   443  }
   444  
   445  // DebugPrint dumps the encoded data in b in a debugging format with a header
   446  // including the string s. Used in testing but made available for general debugging.
   447  func (p *Buffer) DebugPrint(s string, b []byte) {
   448  	var u uint64
   449  
   450  	obuf := p.buf
   451  	index := p.index
   452  	p.buf = b
   453  	p.index = 0
   454  	depth := 0
   455  
   456  	fmt.Printf("\n--- %s ---\n", s)
   457  
   458  out:
   459  	for {
   460  		for i := 0; i < depth; i++ {
   461  			fmt.Print("  ")
   462  		}
   463  
   464  		index := p.index
   465  		if index == len(p.buf) {
   466  			break
   467  		}
   468  
   469  		op, err := p.DecodeVarint()
   470  		if err != nil {
   471  			fmt.Printf("%3d: fetching op err %v\n", index, err)
   472  			break out
   473  		}
   474  		tag := op >> 3
   475  		wire := op & 7
   476  
   477  		switch wire {
   478  		default:
   479  			fmt.Printf("%3d: t=%3d unknown wire=%d\n",
   480  				index, tag, wire)
   481  			break out
   482  
   483  		case WireBytes:
   484  			var r []byte
   485  
   486  			r, err = p.DecodeRawBytes(false)
   487  			if err != nil {
   488  				break out
   489  			}
   490  			fmt.Printf("%3d: t=%3d bytes [%d]", index, tag, len(r))
   491  			if len(r) <= 6 {
   492  				for i := 0; i < len(r); i++ {
   493  					fmt.Printf(" %.2x", r[i])
   494  				}
   495  			} else {
   496  				for i := 0; i < 3; i++ {
   497  					fmt.Printf(" %.2x", r[i])
   498  				}
   499  				fmt.Printf(" ..")
   500  				for i := len(r) - 3; i < len(r); i++ {
   501  					fmt.Printf(" %.2x", r[i])
   502  				}
   503  			}
   504  			fmt.Printf("\n")
   505  
   506  		case WireFixed32:
   507  			u, err = p.DecodeFixed32()
   508  			if err != nil {
   509  				fmt.Printf("%3d: t=%3d fix32 err %v\n", index, tag, err)
   510  				break out
   511  			}
   512  			fmt.Printf("%3d: t=%3d fix32 %d\n", index, tag, u)
   513  
   514  		case WireFixed64:
   515  			u, err = p.DecodeFixed64()
   516  			if err != nil {
   517  				fmt.Printf("%3d: t=%3d fix64 err %v\n", index, tag, err)
   518  				break out
   519  			}
   520  			fmt.Printf("%3d: t=%3d fix64 %d\n", index, tag, u)
   521  
   522  		case WireVarint:
   523  			u, err = p.DecodeVarint()
   524  			if err != nil {
   525  				fmt.Printf("%3d: t=%3d varint err %v\n", index, tag, err)
   526  				break out
   527  			}
   528  			fmt.Printf("%3d: t=%3d varint %d\n", index, tag, u)
   529  
   530  		case WireStartGroup:
   531  			fmt.Printf("%3d: t=%3d start\n", index, tag)
   532  			depth++
   533  
   534  		case WireEndGroup:
   535  			depth--
   536  			fmt.Printf("%3d: t=%3d end\n", index, tag)
   537  		}
   538  	}
   539  
   540  	if depth != 0 {
   541  		fmt.Printf("%3d: start-end not balanced %d\n", p.index, depth)
   542  	}
   543  	fmt.Printf("\n")
   544  
   545  	p.buf = obuf
   546  	p.index = index
   547  }
   548  
   549  // SetDefaults sets unset protocol buffer fields to their default values.
   550  // It only modifies fields that are both unset and have defined defaults.
   551  // It recursively sets default values in any non-nil sub-messages.
   552  func SetDefaults(pb Message) {
   553  	setDefaults(reflect.ValueOf(pb), true, false)
   554  }
   555  
   556  // v is a pointer to a struct.
   557  func setDefaults(v reflect.Value, recur, zeros bool) {
   558  	v = v.Elem()
   559  
   560  	defaultMu.RLock()
   561  	dm, ok := defaults[v.Type()]
   562  	defaultMu.RUnlock()
   563  	if !ok {
   564  		dm = buildDefaultMessage(v.Type())
   565  		defaultMu.Lock()
   566  		defaults[v.Type()] = dm
   567  		defaultMu.Unlock()
   568  	}
   569  
   570  	for _, sf := range dm.scalars {
   571  		f := v.Field(sf.index)
   572  		if !f.IsNil() {
   573  			// field already set
   574  			continue
   575  		}
   576  		dv := sf.value
   577  		if dv == nil && !zeros {
   578  			// no explicit default, and don't want to set zeros
   579  			continue
   580  		}
   581  		fptr := f.Addr().Interface() // **T
   582  		// TODO: Consider batching the allocations we do here.
   583  		switch sf.kind {
   584  		case reflect.Bool:
   585  			b := new(bool)
   586  			if dv != nil {
   587  				*b = dv.(bool)
   588  			}
   589  			*(fptr.(**bool)) = b
   590  		case reflect.Float32:
   591  			f := new(float32)
   592  			if dv != nil {
   593  				*f = dv.(float32)
   594  			}
   595  			*(fptr.(**float32)) = f
   596  		case reflect.Float64:
   597  			f := new(float64)
   598  			if dv != nil {
   599  				*f = dv.(float64)
   600  			}
   601  			*(fptr.(**float64)) = f
   602  		case reflect.Int32:
   603  			// might be an enum
   604  			if ft := f.Type(); ft != int32PtrType {
   605  				// enum
   606  				f.Set(reflect.New(ft.Elem()))
   607  				if dv != nil {
   608  					f.Elem().SetInt(int64(dv.(int32)))
   609  				}
   610  			} else {
   611  				// int32 field
   612  				i := new(int32)
   613  				if dv != nil {
   614  					*i = dv.(int32)
   615  				}
   616  				*(fptr.(**int32)) = i
   617  			}
   618  		case reflect.Int64:
   619  			i := new(int64)
   620  			if dv != nil {
   621  				*i = dv.(int64)
   622  			}
   623  			*(fptr.(**int64)) = i
   624  		case reflect.String:
   625  			s := new(string)
   626  			if dv != nil {
   627  				*s = dv.(string)
   628  			}
   629  			*(fptr.(**string)) = s
   630  		case reflect.Uint8:
   631  			// exceptional case: []byte
   632  			var b []byte
   633  			if dv != nil {
   634  				db := dv.([]byte)
   635  				b = make([]byte, len(db))
   636  				copy(b, db)
   637  			} else {
   638  				b = []byte{}
   639  			}
   640  			*(fptr.(*[]byte)) = b
   641  		case reflect.Uint32:
   642  			u := new(uint32)
   643  			if dv != nil {
   644  				*u = dv.(uint32)
   645  			}
   646  			*(fptr.(**uint32)) = u
   647  		case reflect.Uint64:
   648  			u := new(uint64)
   649  			if dv != nil {
   650  				*u = dv.(uint64)
   651  			}
   652  			*(fptr.(**uint64)) = u
   653  		default:
   654  			log.Printf("proto: can't set default for field %v (sf.kind=%v)", f, sf.kind)
   655  		}
   656  	}
   657  
   658  	for _, ni := range dm.nested {
   659  		f := v.Field(ni)
   660  		// f is *T or []*T or map[T]*T
   661  		switch f.Kind() {
   662  		case reflect.Ptr:
   663  			if f.IsNil() {
   664  				continue
   665  			}
   666  			setDefaults(f, recur, zeros)
   667  
   668  		case reflect.Slice:
   669  			for i := 0; i < f.Len(); i++ {
   670  				e := f.Index(i)
   671  				if e.IsNil() {
   672  					continue
   673  				}
   674  				setDefaults(e, recur, zeros)
   675  			}
   676  
   677  		case reflect.Map:
   678  			for _, k := range f.MapKeys() {
   679  				e := f.MapIndex(k)
   680  				if e.IsNil() {
   681  					continue
   682  				}
   683  				setDefaults(e, recur, zeros)
   684  			}
   685  		}
   686  	}
   687  }
   688  
   689  var (
   690  	// defaults maps a protocol buffer struct type to a slice of the fields,
   691  	// with its scalar fields set to their proto-declared non-zero default values.
   692  	defaultMu sync.RWMutex
   693  	defaults  = make(map[reflect.Type]defaultMessage)
   694  
   695  	int32PtrType = reflect.TypeOf((*int32)(nil))
   696  )
   697  
   698  // defaultMessage represents information about the default values of a message.
   699  type defaultMessage struct {
   700  	scalars []scalarField
   701  	nested  []int // struct field index of nested messages
   702  }
   703  
   704  type scalarField struct {
   705  	index int          // struct field index
   706  	kind  reflect.Kind // element type (the T in *T or []T)
   707  	value interface{}  // the proto-declared default value, or nil
   708  }
   709  
   710  // t is a struct type.
   711  func buildDefaultMessage(t reflect.Type) (dm defaultMessage) {
   712  	sprop := GetProperties(t)
   713  	for _, prop := range sprop.Prop {
   714  		fi, ok := sprop.decoderTags.get(prop.Tag)
   715  		if !ok {
   716  			// XXX_unrecognized
   717  			continue
   718  		}
   719  		ft := t.Field(fi).Type
   720  
   721  		sf, nested, err := fieldDefault(ft, prop)
   722  		switch {
   723  		case err != nil:
   724  			log.Print(err)
   725  		case nested:
   726  			dm.nested = append(dm.nested, fi)
   727  		case sf != nil:
   728  			sf.index = fi
   729  			dm.scalars = append(dm.scalars, *sf)
   730  		}
   731  	}
   732  
   733  	return dm
   734  }
   735  
   736  // fieldDefault returns the scalarField for field type ft.
   737  // sf will be nil if the field can not have a default.
   738  // nestedMessage will be true if this is a nested message.
   739  // Note that sf.index is not set on return.
   740  func fieldDefault(ft reflect.Type, prop *Properties) (sf *scalarField, nestedMessage bool, err error) {
   741  	var canHaveDefault bool
   742  	switch ft.Kind() {
   743  	case reflect.Ptr:
   744  		if ft.Elem().Kind() == reflect.Struct {
   745  			nestedMessage = true
   746  		} else {
   747  			canHaveDefault = true // proto2 scalar field
   748  		}
   749  
   750  	case reflect.Slice:
   751  		switch ft.Elem().Kind() {
   752  		case reflect.Ptr:
   753  			nestedMessage = true // repeated message
   754  		case reflect.Uint8:
   755  			canHaveDefault = true // bytes field
   756  		}
   757  
   758  	case reflect.Map:
   759  		if ft.Elem().Kind() == reflect.Ptr {
   760  			nestedMessage = true // map with message values
   761  		}
   762  	}
   763  
   764  	if !canHaveDefault {
   765  		if nestedMessage {
   766  			return nil, true, nil
   767  		}
   768  		return nil, false, nil
   769  	}
   770  
   771  	// We now know that ft is a pointer or slice.
   772  	sf = &scalarField{kind: ft.Elem().Kind()}
   773  
   774  	// scalar fields without defaults
   775  	if !prop.HasDefault {
   776  		return sf, false, nil
   777  	}
   778  
   779  	// a scalar field: either *T or []byte
   780  	switch ft.Elem().Kind() {
   781  	case reflect.Bool:
   782  		x, err := strconv.ParseBool(prop.Default)
   783  		if err != nil {
   784  			return nil, false, fmt.Errorf("proto: bad default bool %q: %v", prop.Default, err)
   785  		}
   786  		sf.value = x
   787  	case reflect.Float32:
   788  		x, err := strconv.ParseFloat(prop.Default, 32)
   789  		if err != nil {
   790  			return nil, false, fmt.Errorf("proto: bad default float32 %q: %v", prop.Default, err)
   791  		}
   792  		sf.value = float32(x)
   793  	case reflect.Float64:
   794  		x, err := strconv.ParseFloat(prop.Default, 64)
   795  		if err != nil {
   796  			return nil, false, fmt.Errorf("proto: bad default float64 %q: %v", prop.Default, err)
   797  		}
   798  		sf.value = x
   799  	case reflect.Int32:
   800  		x, err := strconv.ParseInt(prop.Default, 10, 32)
   801  		if err != nil {
   802  			return nil, false, fmt.Errorf("proto: bad default int32 %q: %v", prop.Default, err)
   803  		}
   804  		sf.value = int32(x)
   805  	case reflect.Int64:
   806  		x, err := strconv.ParseInt(prop.Default, 10, 64)
   807  		if err != nil {
   808  			return nil, false, fmt.Errorf("proto: bad default int64 %q: %v", prop.Default, err)
   809  		}
   810  		sf.value = x
   811  	case reflect.String:
   812  		sf.value = prop.Default
   813  	case reflect.Uint8:
   814  		// []byte (not *uint8)
   815  		sf.value = []byte(prop.Default)
   816  	case reflect.Uint32:
   817  		x, err := strconv.ParseUint(prop.Default, 10, 32)
   818  		if err != nil {
   819  			return nil, false, fmt.Errorf("proto: bad default uint32 %q: %v", prop.Default, err)
   820  		}
   821  		sf.value = uint32(x)
   822  	case reflect.Uint64:
   823  		x, err := strconv.ParseUint(prop.Default, 10, 64)
   824  		if err != nil {
   825  			return nil, false, fmt.Errorf("proto: bad default uint64 %q: %v", prop.Default, err)
   826  		}
   827  		sf.value = x
   828  	default:
   829  		return nil, false, fmt.Errorf("proto: unhandled def kind %v", ft.Elem().Kind())
   830  	}
   831  
   832  	return sf, false, nil
   833  }
   834  
   835  // Map fields may have key types of non-float scalars, strings and enums.
   836  // The easiest way to sort them in some deterministic order is to use fmt.
   837  // If this turns out to be inefficient we can always consider other options,
   838  // such as doing a Schwartzian transform.
   839  
   840  func mapKeys(vs []reflect.Value) sort.Interface {
   841  	s := mapKeySorter{
   842  		vs: vs,
   843  		// default Less function: textual comparison
   844  		less: func(a, b reflect.Value) bool {
   845  			return fmt.Sprint(a.Interface()) < fmt.Sprint(b.Interface())
   846  		},
   847  	}
   848  
   849  	// Type specialization per https://developers.google.com/protocol-buffers/docs/proto#maps;
   850  	// numeric keys are sorted numerically.
   851  	if len(vs) == 0 {
   852  		return s
   853  	}
   854  	switch vs[0].Kind() {
   855  	case reflect.Int32, reflect.Int64:
   856  		s.less = func(a, b reflect.Value) bool { return a.Int() < b.Int() }
   857  	case reflect.Uint32, reflect.Uint64:
   858  		s.less = func(a, b reflect.Value) bool { return a.Uint() < b.Uint() }
   859  	}
   860  
   861  	return s
   862  }
   863  
   864  type mapKeySorter struct {
   865  	vs   []reflect.Value
   866  	less func(a, b reflect.Value) bool
   867  }
   868  
   869  func (s mapKeySorter) Len() int      { return len(s.vs) }
   870  func (s mapKeySorter) Swap(i, j int) { s.vs[i], s.vs[j] = s.vs[j], s.vs[i] }
   871  func (s mapKeySorter) Less(i, j int) bool {
   872  	return s.less(s.vs[i], s.vs[j])
   873  }
   874  
   875  // isProto3Zero reports whether v is a zero proto3 value.
   876  func isProto3Zero(v reflect.Value) bool {
   877  	switch v.Kind() {
   878  	case reflect.Bool:
   879  		return !v.Bool()
   880  	case reflect.Int32, reflect.Int64:
   881  		return v.Int() == 0
   882  	case reflect.Uint32, reflect.Uint64:
   883  		return v.Uint() == 0
   884  	case reflect.Float32, reflect.Float64:
   885  		return v.Float() == 0
   886  	case reflect.String:
   887  		return v.String() == ""
   888  	}
   889  	return false
   890  }
   891  
   892  // ProtoPackageIsVersion1 is referenced from generated protocol buffer files
   893  // to assert that that code is compatible with this version of the proto package.
   894  const ProtoPackageIsVersion1 = true