...

Source file src/github.com/gogo/protobuf/proto/lib.go

Documentation: github.com/gogo/protobuf/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  /*
    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    - Enum types do not get an Enum method.
    77  
    78  The simplest way to describe this is to see an example.
    79  Given file test.proto, containing
    80  
    81  	package example;
    82  
    83  	enum FOO { X = 17; }
    84  
    85  	message Test {
    86  	  required string label = 1;
    87  	  optional int32 type = 2 [default=77];
    88  	  repeated int64 reps = 3;
    89  	  optional group OptionalGroup = 4 {
    90  	    required string RequiredField = 5;
    91  	  }
    92  	  oneof union {
    93  	    int32 number = 6;
    94  	    string name = 7;
    95  	  }
    96  	}
    97  
    98  The resulting file, test.pb.go, is:
    99  
   100  	package example
   101  
   102  	import proto "github.com/gogo/protobuf/proto"
   103  	import math "math"
   104  
   105  	type FOO int32
   106  	const (
   107  		FOO_X FOO = 17
   108  	)
   109  	var FOO_name = map[int32]string{
   110  		17: "X",
   111  	}
   112  	var FOO_value = map[string]int32{
   113  		"X": 17,
   114  	}
   115  
   116  	func (x FOO) Enum() *FOO {
   117  		p := new(FOO)
   118  		*p = x
   119  		return p
   120  	}
   121  	func (x FOO) String() string {
   122  		return proto.EnumName(FOO_name, int32(x))
   123  	}
   124  	func (x *FOO) UnmarshalJSON(data []byte) error {
   125  		value, err := proto.UnmarshalJSONEnum(FOO_value, data)
   126  		if err != nil {
   127  			return err
   128  		}
   129  		*x = FOO(value)
   130  		return nil
   131  	}
   132  
   133  	type Test struct {
   134  		Label         *string             `protobuf:"bytes,1,req,name=label" json:"label,omitempty"`
   135  		Type          *int32              `protobuf:"varint,2,opt,name=type,def=77" json:"type,omitempty"`
   136  		Reps          []int64             `protobuf:"varint,3,rep,name=reps" json:"reps,omitempty"`
   137  		Optionalgroup *Test_OptionalGroup `protobuf:"group,4,opt,name=OptionalGroup" json:"optionalgroup,omitempty"`
   138  		// Types that are valid to be assigned to Union:
   139  		//	*Test_Number
   140  		//	*Test_Name
   141  		Union            isTest_Union `protobuf_oneof:"union"`
   142  		XXX_unrecognized []byte       `json:"-"`
   143  	}
   144  	func (m *Test) Reset()         { *m = Test{} }
   145  	func (m *Test) String() string { return proto.CompactTextString(m) }
   146  	func (*Test) ProtoMessage() {}
   147  
   148  	type isTest_Union interface {
   149  		isTest_Union()
   150  	}
   151  
   152  	type Test_Number struct {
   153  		Number int32 `protobuf:"varint,6,opt,name=number"`
   154  	}
   155  	type Test_Name struct {
   156  		Name string `protobuf:"bytes,7,opt,name=name"`
   157  	}
   158  
   159  	func (*Test_Number) isTest_Union() {}
   160  	func (*Test_Name) isTest_Union()   {}
   161  
   162  	func (m *Test) GetUnion() isTest_Union {
   163  		if m != nil {
   164  			return m.Union
   165  		}
   166  		return nil
   167  	}
   168  	const Default_Test_Type int32 = 77
   169  
   170  	func (m *Test) GetLabel() string {
   171  		if m != nil && m.Label != nil {
   172  			return *m.Label
   173  		}
   174  		return ""
   175  	}
   176  
   177  	func (m *Test) GetType() int32 {
   178  		if m != nil && m.Type != nil {
   179  			return *m.Type
   180  		}
   181  		return Default_Test_Type
   182  	}
   183  
   184  	func (m *Test) GetOptionalgroup() *Test_OptionalGroup {
   185  		if m != nil {
   186  			return m.Optionalgroup
   187  		}
   188  		return nil
   189  	}
   190  
   191  	type Test_OptionalGroup struct {
   192  		RequiredField *string `protobuf:"bytes,5,req" json:"RequiredField,omitempty"`
   193  	}
   194  	func (m *Test_OptionalGroup) Reset()         { *m = Test_OptionalGroup{} }
   195  	func (m *Test_OptionalGroup) String() string { return proto.CompactTextString(m) }
   196  
   197  	func (m *Test_OptionalGroup) GetRequiredField() string {
   198  		if m != nil && m.RequiredField != nil {
   199  			return *m.RequiredField
   200  		}
   201  		return ""
   202  	}
   203  
   204  	func (m *Test) GetNumber() int32 {
   205  		if x, ok := m.GetUnion().(*Test_Number); ok {
   206  			return x.Number
   207  		}
   208  		return 0
   209  	}
   210  
   211  	func (m *Test) GetName() string {
   212  		if x, ok := m.GetUnion().(*Test_Name); ok {
   213  			return x.Name
   214  		}
   215  		return ""
   216  	}
   217  
   218  	func init() {
   219  		proto.RegisterEnum("example.FOO", FOO_name, FOO_value)
   220  	}
   221  
   222  To create and play with a Test object:
   223  
   224  	package main
   225  
   226  	import (
   227  		"log"
   228  
   229  		"github.com/gogo/protobuf/proto"
   230  		pb "./example.pb"
   231  	)
   232  
   233  	func main() {
   234  		test := &pb.Test{
   235  			Label: proto.String("hello"),
   236  			Type:  proto.Int32(17),
   237  			Reps:  []int64{1, 2, 3},
   238  			Optionalgroup: &pb.Test_OptionalGroup{
   239  				RequiredField: proto.String("good bye"),
   240  			},
   241  			Union: &pb.Test_Name{"fred"},
   242  		}
   243  		data, err := proto.Marshal(test)
   244  		if err != nil {
   245  			log.Fatal("marshaling error: ", err)
   246  		}
   247  		newTest := &pb.Test{}
   248  		err = proto.Unmarshal(data, newTest)
   249  		if err != nil {
   250  			log.Fatal("unmarshaling error: ", err)
   251  		}
   252  		// Now test and newTest contain the same data.
   253  		if test.GetLabel() != newTest.GetLabel() {
   254  			log.Fatalf("data mismatch %q != %q", test.GetLabel(), newTest.GetLabel())
   255  		}
   256  		// Use a type switch to determine which oneof was set.
   257  		switch u := test.Union.(type) {
   258  		case *pb.Test_Number: // u.Number contains the number.
   259  		case *pb.Test_Name: // u.Name contains the string.
   260  		}
   261  		// etc.
   262  	}
   263  */
   264  package proto
   265  
   266  import (
   267  	"encoding/json"
   268  	"fmt"
   269  	"log"
   270  	"reflect"
   271  	"sort"
   272  	"strconv"
   273  	"sync"
   274  )
   275  
   276  // RequiredNotSetError is an error type returned by either Marshal or Unmarshal.
   277  // Marshal reports this when a required field is not initialized.
   278  // Unmarshal reports this when a required field is missing from the wire data.
   279  type RequiredNotSetError struct{ field string }
   280  
   281  func (e *RequiredNotSetError) Error() string {
   282  	if e.field == "" {
   283  		return fmt.Sprintf("proto: required field not set")
   284  	}
   285  	return fmt.Sprintf("proto: required field %q not set", e.field)
   286  }
   287  func (e *RequiredNotSetError) RequiredNotSet() bool {
   288  	return true
   289  }
   290  
   291  type invalidUTF8Error struct{ field string }
   292  
   293  func (e *invalidUTF8Error) Error() string {
   294  	if e.field == "" {
   295  		return "proto: invalid UTF-8 detected"
   296  	}
   297  	return fmt.Sprintf("proto: field %q contains invalid UTF-8", e.field)
   298  }
   299  func (e *invalidUTF8Error) InvalidUTF8() bool {
   300  	return true
   301  }
   302  
   303  // errInvalidUTF8 is a sentinel error to identify fields with invalid UTF-8.
   304  // This error should not be exposed to the external API as such errors should
   305  // be recreated with the field information.
   306  var errInvalidUTF8 = &invalidUTF8Error{}
   307  
   308  // isNonFatal reports whether the error is either a RequiredNotSet error
   309  // or a InvalidUTF8 error.
   310  func isNonFatal(err error) bool {
   311  	if re, ok := err.(interface{ RequiredNotSet() bool }); ok && re.RequiredNotSet() {
   312  		return true
   313  	}
   314  	if re, ok := err.(interface{ InvalidUTF8() bool }); ok && re.InvalidUTF8() {
   315  		return true
   316  	}
   317  	return false
   318  }
   319  
   320  type nonFatal struct{ E error }
   321  
   322  // Merge merges err into nf and reports whether it was successful.
   323  // Otherwise it returns false for any fatal non-nil errors.
   324  func (nf *nonFatal) Merge(err error) (ok bool) {
   325  	if err == nil {
   326  		return true // not an error
   327  	}
   328  	if !isNonFatal(err) {
   329  		return false // fatal error
   330  	}
   331  	if nf.E == nil {
   332  		nf.E = err // store first instance of non-fatal error
   333  	}
   334  	return true
   335  }
   336  
   337  // Message is implemented by generated protocol buffer messages.
   338  type Message interface {
   339  	Reset()
   340  	String() string
   341  	ProtoMessage()
   342  }
   343  
   344  // A Buffer is a buffer manager for marshaling and unmarshaling
   345  // protocol buffers.  It may be reused between invocations to
   346  // reduce memory usage.  It is not necessary to use a Buffer;
   347  // the global functions Marshal and Unmarshal create a
   348  // temporary Buffer and are fine for most applications.
   349  type Buffer struct {
   350  	buf   []byte // encode/decode byte stream
   351  	index int    // read point
   352  
   353  	deterministic bool
   354  }
   355  
   356  // NewBuffer allocates a new Buffer and initializes its internal data to
   357  // the contents of the argument slice.
   358  func NewBuffer(e []byte) *Buffer {
   359  	return &Buffer{buf: e}
   360  }
   361  
   362  // Reset resets the Buffer, ready for marshaling a new protocol buffer.
   363  func (p *Buffer) Reset() {
   364  	p.buf = p.buf[0:0] // for reading/writing
   365  	p.index = 0        // for reading
   366  }
   367  
   368  // SetBuf replaces the internal buffer with the slice,
   369  // ready for unmarshaling the contents of the slice.
   370  func (p *Buffer) SetBuf(s []byte) {
   371  	p.buf = s
   372  	p.index = 0
   373  }
   374  
   375  // Bytes returns the contents of the Buffer.
   376  func (p *Buffer) Bytes() []byte { return p.buf }
   377  
   378  // SetDeterministic sets whether to use deterministic serialization.
   379  //
   380  // Deterministic serialization guarantees that for a given binary, equal
   381  // messages will always be serialized to the same bytes. This implies:
   382  //
   383  //   - Repeated serialization of a message will return the same bytes.
   384  //   - Different processes of the same binary (which may be executing on
   385  //     different machines) will serialize equal messages to the same bytes.
   386  //
   387  // Note that the deterministic serialization is NOT canonical across
   388  // languages. It is not guaranteed to remain stable over time. It is unstable
   389  // across different builds with schema changes due to unknown fields.
   390  // Users who need canonical serialization (e.g., persistent storage in a
   391  // canonical form, fingerprinting, etc.) should define their own
   392  // canonicalization specification and implement their own serializer rather
   393  // than relying on this API.
   394  //
   395  // If deterministic serialization is requested, map entries will be sorted
   396  // by keys in lexographical order. This is an implementation detail and
   397  // subject to change.
   398  func (p *Buffer) SetDeterministic(deterministic bool) {
   399  	p.deterministic = deterministic
   400  }
   401  
   402  /*
   403   * Helper routines for simplifying the creation of optional fields of basic type.
   404   */
   405  
   406  // Bool is a helper routine that allocates a new bool value
   407  // to store v and returns a pointer to it.
   408  func Bool(v bool) *bool {
   409  	return &v
   410  }
   411  
   412  // Int32 is a helper routine that allocates a new int32 value
   413  // to store v and returns a pointer to it.
   414  func Int32(v int32) *int32 {
   415  	return &v
   416  }
   417  
   418  // Int is a helper routine that allocates a new int32 value
   419  // to store v and returns a pointer to it, but unlike Int32
   420  // its argument value is an int.
   421  func Int(v int) *int32 {
   422  	p := new(int32)
   423  	*p = int32(v)
   424  	return p
   425  }
   426  
   427  // Int64 is a helper routine that allocates a new int64 value
   428  // to store v and returns a pointer to it.
   429  func Int64(v int64) *int64 {
   430  	return &v
   431  }
   432  
   433  // Float32 is a helper routine that allocates a new float32 value
   434  // to store v and returns a pointer to it.
   435  func Float32(v float32) *float32 {
   436  	return &v
   437  }
   438  
   439  // Float64 is a helper routine that allocates a new float64 value
   440  // to store v and returns a pointer to it.
   441  func Float64(v float64) *float64 {
   442  	return &v
   443  }
   444  
   445  // Uint32 is a helper routine that allocates a new uint32 value
   446  // to store v and returns a pointer to it.
   447  func Uint32(v uint32) *uint32 {
   448  	return &v
   449  }
   450  
   451  // Uint64 is a helper routine that allocates a new uint64 value
   452  // to store v and returns a pointer to it.
   453  func Uint64(v uint64) *uint64 {
   454  	return &v
   455  }
   456  
   457  // String is a helper routine that allocates a new string value
   458  // to store v and returns a pointer to it.
   459  func String(v string) *string {
   460  	return &v
   461  }
   462  
   463  // EnumName is a helper function to simplify printing protocol buffer enums
   464  // by name.  Given an enum map and a value, it returns a useful string.
   465  func EnumName(m map[int32]string, v int32) string {
   466  	s, ok := m[v]
   467  	if ok {
   468  		return s
   469  	}
   470  	return strconv.Itoa(int(v))
   471  }
   472  
   473  // UnmarshalJSONEnum is a helper function to simplify recovering enum int values
   474  // from their JSON-encoded representation. Given a map from the enum's symbolic
   475  // names to its int values, and a byte buffer containing the JSON-encoded
   476  // value, it returns an int32 that can be cast to the enum type by the caller.
   477  //
   478  // The function can deal with both JSON representations, numeric and symbolic.
   479  func UnmarshalJSONEnum(m map[string]int32, data []byte, enumName string) (int32, error) {
   480  	if data[0] == '"' {
   481  		// New style: enums are strings.
   482  		var repr string
   483  		if err := json.Unmarshal(data, &repr); err != nil {
   484  			return -1, err
   485  		}
   486  		val, ok := m[repr]
   487  		if !ok {
   488  			return 0, fmt.Errorf("unrecognized enum %s value %q", enumName, repr)
   489  		}
   490  		return val, nil
   491  	}
   492  	// Old style: enums are ints.
   493  	var val int32
   494  	if err := json.Unmarshal(data, &val); err != nil {
   495  		return 0, fmt.Errorf("cannot unmarshal %#q into enum %s", data, enumName)
   496  	}
   497  	return val, nil
   498  }
   499  
   500  // DebugPrint dumps the encoded data in b in a debugging format with a header
   501  // including the string s. Used in testing but made available for general debugging.
   502  func (p *Buffer) DebugPrint(s string, b []byte) {
   503  	var u uint64
   504  
   505  	obuf := p.buf
   506  	sindex := p.index
   507  	p.buf = b
   508  	p.index = 0
   509  	depth := 0
   510  
   511  	fmt.Printf("\n--- %s ---\n", s)
   512  
   513  out:
   514  	for {
   515  		for i := 0; i < depth; i++ {
   516  			fmt.Print("  ")
   517  		}
   518  
   519  		index := p.index
   520  		if index == len(p.buf) {
   521  			break
   522  		}
   523  
   524  		op, err := p.DecodeVarint()
   525  		if err != nil {
   526  			fmt.Printf("%3d: fetching op err %v\n", index, err)
   527  			break out
   528  		}
   529  		tag := op >> 3
   530  		wire := op & 7
   531  
   532  		switch wire {
   533  		default:
   534  			fmt.Printf("%3d: t=%3d unknown wire=%d\n",
   535  				index, tag, wire)
   536  			break out
   537  
   538  		case WireBytes:
   539  			var r []byte
   540  
   541  			r, err = p.DecodeRawBytes(false)
   542  			if err != nil {
   543  				break out
   544  			}
   545  			fmt.Printf("%3d: t=%3d bytes [%d]", index, tag, len(r))
   546  			if len(r) <= 6 {
   547  				for i := 0; i < len(r); i++ {
   548  					fmt.Printf(" %.2x", r[i])
   549  				}
   550  			} else {
   551  				for i := 0; i < 3; i++ {
   552  					fmt.Printf(" %.2x", r[i])
   553  				}
   554  				fmt.Printf(" ..")
   555  				for i := len(r) - 3; i < len(r); i++ {
   556  					fmt.Printf(" %.2x", r[i])
   557  				}
   558  			}
   559  			fmt.Printf("\n")
   560  
   561  		case WireFixed32:
   562  			u, err = p.DecodeFixed32()
   563  			if err != nil {
   564  				fmt.Printf("%3d: t=%3d fix32 err %v\n", index, tag, err)
   565  				break out
   566  			}
   567  			fmt.Printf("%3d: t=%3d fix32 %d\n", index, tag, u)
   568  
   569  		case WireFixed64:
   570  			u, err = p.DecodeFixed64()
   571  			if err != nil {
   572  				fmt.Printf("%3d: t=%3d fix64 err %v\n", index, tag, err)
   573  				break out
   574  			}
   575  			fmt.Printf("%3d: t=%3d fix64 %d\n", index, tag, u)
   576  
   577  		case WireVarint:
   578  			u, err = p.DecodeVarint()
   579  			if err != nil {
   580  				fmt.Printf("%3d: t=%3d varint err %v\n", index, tag, err)
   581  				break out
   582  			}
   583  			fmt.Printf("%3d: t=%3d varint %d\n", index, tag, u)
   584  
   585  		case WireStartGroup:
   586  			fmt.Printf("%3d: t=%3d start\n", index, tag)
   587  			depth++
   588  
   589  		case WireEndGroup:
   590  			depth--
   591  			fmt.Printf("%3d: t=%3d end\n", index, tag)
   592  		}
   593  	}
   594  
   595  	if depth != 0 {
   596  		fmt.Printf("%3d: start-end not balanced %d\n", p.index, depth)
   597  	}
   598  	fmt.Printf("\n")
   599  
   600  	p.buf = obuf
   601  	p.index = sindex
   602  }
   603  
   604  // SetDefaults sets unset protocol buffer fields to their default values.
   605  // It only modifies fields that are both unset and have defined defaults.
   606  // It recursively sets default values in any non-nil sub-messages.
   607  func SetDefaults(pb Message) {
   608  	setDefaults(reflect.ValueOf(pb), true, false)
   609  }
   610  
   611  // v is a struct.
   612  func setDefaults(v reflect.Value, recur, zeros bool) {
   613  	if v.Kind() == reflect.Ptr {
   614  		v = v.Elem()
   615  	}
   616  
   617  	defaultMu.RLock()
   618  	dm, ok := defaults[v.Type()]
   619  	defaultMu.RUnlock()
   620  	if !ok {
   621  		dm = buildDefaultMessage(v.Type())
   622  		defaultMu.Lock()
   623  		defaults[v.Type()] = dm
   624  		defaultMu.Unlock()
   625  	}
   626  
   627  	for _, sf := range dm.scalars {
   628  		f := v.Field(sf.index)
   629  		if !f.IsNil() {
   630  			// field already set
   631  			continue
   632  		}
   633  		dv := sf.value
   634  		if dv == nil && !zeros {
   635  			// no explicit default, and don't want to set zeros
   636  			continue
   637  		}
   638  		fptr := f.Addr().Interface() // **T
   639  		// TODO: Consider batching the allocations we do here.
   640  		switch sf.kind {
   641  		case reflect.Bool:
   642  			b := new(bool)
   643  			if dv != nil {
   644  				*b = dv.(bool)
   645  			}
   646  			*(fptr.(**bool)) = b
   647  		case reflect.Float32:
   648  			f := new(float32)
   649  			if dv != nil {
   650  				*f = dv.(float32)
   651  			}
   652  			*(fptr.(**float32)) = f
   653  		case reflect.Float64:
   654  			f := new(float64)
   655  			if dv != nil {
   656  				*f = dv.(float64)
   657  			}
   658  			*(fptr.(**float64)) = f
   659  		case reflect.Int32:
   660  			// might be an enum
   661  			if ft := f.Type(); ft != int32PtrType {
   662  				// enum
   663  				f.Set(reflect.New(ft.Elem()))
   664  				if dv != nil {
   665  					f.Elem().SetInt(int64(dv.(int32)))
   666  				}
   667  			} else {
   668  				// int32 field
   669  				i := new(int32)
   670  				if dv != nil {
   671  					*i = dv.(int32)
   672  				}
   673  				*(fptr.(**int32)) = i
   674  			}
   675  		case reflect.Int64:
   676  			i := new(int64)
   677  			if dv != nil {
   678  				*i = dv.(int64)
   679  			}
   680  			*(fptr.(**int64)) = i
   681  		case reflect.String:
   682  			s := new(string)
   683  			if dv != nil {
   684  				*s = dv.(string)
   685  			}
   686  			*(fptr.(**string)) = s
   687  		case reflect.Uint8:
   688  			// exceptional case: []byte
   689  			var b []byte
   690  			if dv != nil {
   691  				db := dv.([]byte)
   692  				b = make([]byte, len(db))
   693  				copy(b, db)
   694  			} else {
   695  				b = []byte{}
   696  			}
   697  			*(fptr.(*[]byte)) = b
   698  		case reflect.Uint32:
   699  			u := new(uint32)
   700  			if dv != nil {
   701  				*u = dv.(uint32)
   702  			}
   703  			*(fptr.(**uint32)) = u
   704  		case reflect.Uint64:
   705  			u := new(uint64)
   706  			if dv != nil {
   707  				*u = dv.(uint64)
   708  			}
   709  			*(fptr.(**uint64)) = u
   710  		default:
   711  			log.Printf("proto: can't set default for field %v (sf.kind=%v)", f, sf.kind)
   712  		}
   713  	}
   714  
   715  	for _, ni := range dm.nested {
   716  		f := v.Field(ni)
   717  		// f is *T or T or []*T or []T
   718  		switch f.Kind() {
   719  		case reflect.Struct:
   720  			setDefaults(f, recur, zeros)
   721  
   722  		case reflect.Ptr:
   723  			if f.IsNil() {
   724  				continue
   725  			}
   726  			setDefaults(f, recur, zeros)
   727  
   728  		case reflect.Slice:
   729  			for i := 0; i < f.Len(); i++ {
   730  				e := f.Index(i)
   731  				if e.Kind() == reflect.Ptr && e.IsNil() {
   732  					continue
   733  				}
   734  				setDefaults(e, recur, zeros)
   735  			}
   736  
   737  		case reflect.Map:
   738  			for _, k := range f.MapKeys() {
   739  				e := f.MapIndex(k)
   740  				if e.IsNil() {
   741  					continue
   742  				}
   743  				setDefaults(e, recur, zeros)
   744  			}
   745  		}
   746  	}
   747  }
   748  
   749  var (
   750  	// defaults maps a protocol buffer struct type to a slice of the fields,
   751  	// with its scalar fields set to their proto-declared non-zero default values.
   752  	defaultMu sync.RWMutex
   753  	defaults  = make(map[reflect.Type]defaultMessage)
   754  
   755  	int32PtrType = reflect.TypeOf((*int32)(nil))
   756  )
   757  
   758  // defaultMessage represents information about the default values of a message.
   759  type defaultMessage struct {
   760  	scalars []scalarField
   761  	nested  []int // struct field index of nested messages
   762  }
   763  
   764  type scalarField struct {
   765  	index int          // struct field index
   766  	kind  reflect.Kind // element type (the T in *T or []T)
   767  	value interface{}  // the proto-declared default value, or nil
   768  }
   769  
   770  // t is a struct type.
   771  func buildDefaultMessage(t reflect.Type) (dm defaultMessage) {
   772  	sprop := GetProperties(t)
   773  	for _, prop := range sprop.Prop {
   774  		fi, ok := sprop.decoderTags.get(prop.Tag)
   775  		if !ok {
   776  			// XXX_unrecognized
   777  			continue
   778  		}
   779  		ft := t.Field(fi).Type
   780  
   781  		sf, nested, err := fieldDefault(ft, prop)
   782  		switch {
   783  		case err != nil:
   784  			log.Print(err)
   785  		case nested:
   786  			dm.nested = append(dm.nested, fi)
   787  		case sf != nil:
   788  			sf.index = fi
   789  			dm.scalars = append(dm.scalars, *sf)
   790  		}
   791  	}
   792  
   793  	return dm
   794  }
   795  
   796  // fieldDefault returns the scalarField for field type ft.
   797  // sf will be nil if the field can not have a default.
   798  // nestedMessage will be true if this is a nested message.
   799  // Note that sf.index is not set on return.
   800  func fieldDefault(ft reflect.Type, prop *Properties) (sf *scalarField, nestedMessage bool, err error) {
   801  	var canHaveDefault bool
   802  	switch ft.Kind() {
   803  	case reflect.Struct:
   804  		nestedMessage = true // non-nullable
   805  
   806  	case reflect.Ptr:
   807  		if ft.Elem().Kind() == reflect.Struct {
   808  			nestedMessage = true
   809  		} else {
   810  			canHaveDefault = true // proto2 scalar field
   811  		}
   812  
   813  	case reflect.Slice:
   814  		switch ft.Elem().Kind() {
   815  		case reflect.Ptr, reflect.Struct:
   816  			nestedMessage = true // repeated message
   817  		case reflect.Uint8:
   818  			canHaveDefault = true // bytes field
   819  		}
   820  
   821  	case reflect.Map:
   822  		if ft.Elem().Kind() == reflect.Ptr {
   823  			nestedMessage = true // map with message values
   824  		}
   825  	}
   826  
   827  	if !canHaveDefault {
   828  		if nestedMessage {
   829  			return nil, true, nil
   830  		}
   831  		return nil, false, nil
   832  	}
   833  
   834  	// We now know that ft is a pointer or slice.
   835  	sf = &scalarField{kind: ft.Elem().Kind()}
   836  
   837  	// scalar fields without defaults
   838  	if !prop.HasDefault {
   839  		return sf, false, nil
   840  	}
   841  
   842  	// a scalar field: either *T or []byte
   843  	switch ft.Elem().Kind() {
   844  	case reflect.Bool:
   845  		x, err := strconv.ParseBool(prop.Default)
   846  		if err != nil {
   847  			return nil, false, fmt.Errorf("proto: bad default bool %q: %v", prop.Default, err)
   848  		}
   849  		sf.value = x
   850  	case reflect.Float32:
   851  		x, err := strconv.ParseFloat(prop.Default, 32)
   852  		if err != nil {
   853  			return nil, false, fmt.Errorf("proto: bad default float32 %q: %v", prop.Default, err)
   854  		}
   855  		sf.value = float32(x)
   856  	case reflect.Float64:
   857  		x, err := strconv.ParseFloat(prop.Default, 64)
   858  		if err != nil {
   859  			return nil, false, fmt.Errorf("proto: bad default float64 %q: %v", prop.Default, err)
   860  		}
   861  		sf.value = x
   862  	case reflect.Int32:
   863  		x, err := strconv.ParseInt(prop.Default, 10, 32)
   864  		if err != nil {
   865  			return nil, false, fmt.Errorf("proto: bad default int32 %q: %v", prop.Default, err)
   866  		}
   867  		sf.value = int32(x)
   868  	case reflect.Int64:
   869  		x, err := strconv.ParseInt(prop.Default, 10, 64)
   870  		if err != nil {
   871  			return nil, false, fmt.Errorf("proto: bad default int64 %q: %v", prop.Default, err)
   872  		}
   873  		sf.value = x
   874  	case reflect.String:
   875  		sf.value = prop.Default
   876  	case reflect.Uint8:
   877  		// []byte (not *uint8)
   878  		sf.value = []byte(prop.Default)
   879  	case reflect.Uint32:
   880  		x, err := strconv.ParseUint(prop.Default, 10, 32)
   881  		if err != nil {
   882  			return nil, false, fmt.Errorf("proto: bad default uint32 %q: %v", prop.Default, err)
   883  		}
   884  		sf.value = uint32(x)
   885  	case reflect.Uint64:
   886  		x, err := strconv.ParseUint(prop.Default, 10, 64)
   887  		if err != nil {
   888  			return nil, false, fmt.Errorf("proto: bad default uint64 %q: %v", prop.Default, err)
   889  		}
   890  		sf.value = x
   891  	default:
   892  		return nil, false, fmt.Errorf("proto: unhandled def kind %v", ft.Elem().Kind())
   893  	}
   894  
   895  	return sf, false, nil
   896  }
   897  
   898  // mapKeys returns a sort.Interface to be used for sorting the map keys.
   899  // Map fields may have key types of non-float scalars, strings and enums.
   900  func mapKeys(vs []reflect.Value) sort.Interface {
   901  	s := mapKeySorter{vs: vs}
   902  
   903  	// Type specialization per https://developers.google.com/protocol-buffers/docs/proto#maps.
   904  	if len(vs) == 0 {
   905  		return s
   906  	}
   907  	switch vs[0].Kind() {
   908  	case reflect.Int32, reflect.Int64:
   909  		s.less = func(a, b reflect.Value) bool { return a.Int() < b.Int() }
   910  	case reflect.Uint32, reflect.Uint64:
   911  		s.less = func(a, b reflect.Value) bool { return a.Uint() < b.Uint() }
   912  	case reflect.Bool:
   913  		s.less = func(a, b reflect.Value) bool { return !a.Bool() && b.Bool() } // false < true
   914  	case reflect.String:
   915  		s.less = func(a, b reflect.Value) bool { return a.String() < b.String() }
   916  	default:
   917  		panic(fmt.Sprintf("unsupported map key type: %v", vs[0].Kind()))
   918  	}
   919  
   920  	return s
   921  }
   922  
   923  type mapKeySorter struct {
   924  	vs   []reflect.Value
   925  	less func(a, b reflect.Value) bool
   926  }
   927  
   928  func (s mapKeySorter) Len() int      { return len(s.vs) }
   929  func (s mapKeySorter) Swap(i, j int) { s.vs[i], s.vs[j] = s.vs[j], s.vs[i] }
   930  func (s mapKeySorter) Less(i, j int) bool {
   931  	return s.less(s.vs[i], s.vs[j])
   932  }
   933  
   934  // isProto3Zero reports whether v is a zero proto3 value.
   935  func isProto3Zero(v reflect.Value) bool {
   936  	switch v.Kind() {
   937  	case reflect.Bool:
   938  		return !v.Bool()
   939  	case reflect.Int32, reflect.Int64:
   940  		return v.Int() == 0
   941  	case reflect.Uint32, reflect.Uint64:
   942  		return v.Uint() == 0
   943  	case reflect.Float32, reflect.Float64:
   944  		return v.Float() == 0
   945  	case reflect.String:
   946  		return v.String() == ""
   947  	}
   948  	return false
   949  }
   950  
   951  const (
   952  	// ProtoPackageIsVersion3 is referenced from generated protocol buffer files
   953  	// to assert that that code is compatible with this version of the proto package.
   954  	GoGoProtoPackageIsVersion3 = true
   955  
   956  	// ProtoPackageIsVersion2 is referenced from generated protocol buffer files
   957  	// to assert that that code is compatible with this version of the proto package.
   958  	GoGoProtoPackageIsVersion2 = true
   959  
   960  	// ProtoPackageIsVersion1 is referenced from generated protocol buffer files
   961  	// to assert that that code is compatible with this version of the proto package.
   962  	GoGoProtoPackageIsVersion1 = true
   963  )
   964  
   965  // InternalMessageInfo is a type used internally by generated .pb.go files.
   966  // This type is not intended to be used by non-generated code.
   967  // This type is not subject to any compatibility guarantee.
   968  type InternalMessageInfo struct {
   969  	marshal   *marshalInfo
   970  	unmarshal *unmarshalInfo
   971  	merge     *mergeInfo
   972  	discard   *discardInfo
   973  }
   974  

View as plain text