github.com/asifdxtreme/cli@v6.1.3-0.20150123051144-9ead8700b4ae+incompatible/Godeps/_workspace/src/code.google.com/p/gogoprotobuf/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  // http://code.google.com/p/goprotobuf/
     5  //
     6  // Redistribution and use in source and binary forms, with or without
     7  // modification, are permitted provided that the following conditions are
     8  // met:
     9  //
    10  //     * Redistributions of source code must retain the above copyright
    11  // notice, this list of conditions and the following disclaimer.
    12  //     * Redistributions in binary form must reproduce the above
    13  // copyright notice, this list of conditions and the following disclaimer
    14  // in the documentation and/or other materials provided with the
    15  // distribution.
    16  //     * Neither the name of Google Inc. nor the names of its
    17  // contributors may be used to endorse or promote products derived from
    18  // this software without specific prior written permission.
    19  //
    20  // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    21  // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    22  // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    23  // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    24  // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    25  // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    26  // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    27  // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    28  // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    29  // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    30  // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    31  
    32  /*
    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  		Helpers for getting values are superseded by the
    54  		GetFoo methods and their use is deprecated.
    55  			msg.Foo = proto.String("hello") // set field
    56  	  - Constants are defined to hold the default values of all fields that
    57  		have them.  They have the form Default_StructName_FieldName.
    58  		Because the getter methods handle defaulted values,
    59  		direct use of these constants should be rare.
    60  	  - Enums are given type names and maps from names to values.
    61  		Enum values are prefixed with the enum's type name. Enum types have
    62  		a String method, and a Enum method to assist in message construction.
    63  	  - Nested groups and enums have type names prefixed with the name of
    64  	  	the surrounding message type.
    65  	  - Extensions are given descriptor names that start with E_,
    66  		followed by an underscore-delimited list of the nested messages
    67  		that contain it (if any) followed by the CamelCased name of the
    68  		extension field itself.  HasExtension, ClearExtension, GetExtension
    69  		and SetExtension are functions for manipulating extensions.
    70  	  - Marshal and Unmarshal are functions to encode and decode the wire format.
    71  
    72  	The simplest way to describe this is to see an example.
    73  	Given file test.proto, containing
    74  
    75  		package example;
    76  
    77  		enum FOO { X = 17; };
    78  
    79  		message Test {
    80  		  required string label = 1;
    81  		  optional int32 type = 2 [default=77];
    82  		  repeated int64 reps = 3;
    83  		  optional group OptionalGroup = 4 {
    84  		    required string RequiredField = 5;
    85  		  }
    86  		}
    87  
    88  	The resulting file, test.pb.go, is:
    89  
    90  		package example
    91  
    92  		import "code.google.com/p/gogoprotobuf/proto"
    93  
    94  		type FOO int32
    95  		const (
    96  			FOO_X FOO = 17
    97  		)
    98  		var FOO_name = map[int32]string{
    99  			17: "X",
   100  		}
   101  		var FOO_value = map[string]int32{
   102  			"X": 17,
   103  		}
   104  
   105  		func (x FOO) Enum() *FOO {
   106  			p := new(FOO)
   107  			*p = x
   108  			return p
   109  		}
   110  		func (x FOO) String() string {
   111  			return proto.EnumName(FOO_name, int32(x))
   112  		}
   113  
   114  		type Test struct {
   115  			Label            *string             `protobuf:"bytes,1,req,name=label" json:"label,omitempty"`
   116  			Type             *int32              `protobuf:"varint,2,opt,name=type,def=77" json:"type,omitempty"`
   117  			Reps             []int64             `protobuf:"varint,3,rep,name=reps" json:"reps,omitempty"`
   118  			Optionalgroup    *Test_OptionalGroup `protobuf:"group,4,opt,name=OptionalGroup" json:"optionalgroup,omitempty"`
   119  			XXX_unrecognized []byte              `json:"-"`
   120  		}
   121  		func (this *Test) Reset()         { *this = Test{} }
   122  		func (this *Test) String() string { return proto.CompactTextString(this) }
   123  		const Default_Test_Type int32 = 77
   124  
   125  		func (this *Test) GetLabel() string {
   126  			if this != nil && this.Label != nil {
   127  				return *this.Label
   128  			}
   129  			return ""
   130  		}
   131  
   132  		func (this *Test) GetType() int32 {
   133  			if this != nil && this.Type != nil {
   134  				return *this.Type
   135  			}
   136  			return Default_Test_Type
   137  		}
   138  
   139  		func (this *Test) GetOptionalgroup() *Test_OptionalGroup {
   140  			if this != nil {
   141  				return this.Optionalgroup
   142  			}
   143  			return nil
   144  		}
   145  
   146  		type Test_OptionalGroup struct {
   147  			RequiredField    *string `protobuf:"bytes,5,req" json:"RequiredField,omitempty"`
   148  			XXX_unrecognized []byte  `json:"-"`
   149  		}
   150  		func (this *Test_OptionalGroup) Reset()         { *this = Test_OptionalGroup{} }
   151  		func (this *Test_OptionalGroup) String() string { return proto.CompactTextString(this) }
   152  
   153  		func (this *Test_OptionalGroup) GetRequiredField() string {
   154  			if this != nil && this.RequiredField != nil {
   155  				return *this.RequiredField
   156  			}
   157  			return ""
   158  		}
   159  
   160  		func init() {
   161  			proto.RegisterEnum("example.FOO", FOO_name, FOO_value)
   162  		}
   163  
   164  	To create and play with a Test object:
   165  
   166  		package main
   167  
   168  		import (
   169  			"log"
   170  
   171  			"code.google.com/p/gogoprotobuf/proto"
   172  			"./example.pb"
   173  		)
   174  
   175  		func main() {
   176  			test := &example.Test{
   177  				Label: proto.String("hello"),
   178  				Type:  proto.Int32(17),
   179  				Optionalgroup: &example.Test_OptionalGroup{
   180  					RequiredField: proto.String("good bye"),
   181  				},
   182  			}
   183  			data, err := proto.Marshal(test)
   184  			if err != nil {
   185  				log.Fatal("marshaling error: ", err)
   186  			}
   187  			newTest := new(example.Test)
   188  			err = proto.Unmarshal(data, newTest)
   189  			if err != nil {
   190  				log.Fatal("unmarshaling error: ", err)
   191  			}
   192  			// Now test and newTest contain the same data.
   193  			if test.GetLabel() != newTest.GetLabel() {
   194  				log.Fatalf("data mismatch %q != %q", test.GetLabel(), newTest.GetLabel())
   195  			}
   196  			// etc.
   197  		}
   198  */
   199  package proto
   200  
   201  import (
   202  	"encoding/json"
   203  	"fmt"
   204  	"log"
   205  	"reflect"
   206  	"strconv"
   207  	"sync"
   208  )
   209  
   210  // Message is implemented by generated protocol buffer messages.
   211  type Message interface {
   212  	Reset()
   213  	String() string
   214  	ProtoMessage()
   215  }
   216  
   217  // Stats records allocation details about the protocol buffer encoders
   218  // and decoders.  Useful for tuning the library itself.
   219  type Stats struct {
   220  	Emalloc uint64 // mallocs in encode
   221  	Dmalloc uint64 // mallocs in decode
   222  	Encode  uint64 // number of encodes
   223  	Decode  uint64 // number of decodes
   224  	Chit    uint64 // number of cache hits
   225  	Cmiss   uint64 // number of cache misses
   226  	Size    uint64 // number of sizes
   227  }
   228  
   229  // Set to true to enable stats collection.
   230  const collectStats = false
   231  
   232  var stats Stats
   233  
   234  // GetStats returns a copy of the global Stats structure.
   235  func GetStats() Stats { return stats }
   236  
   237  // A Buffer is a buffer manager for marshaling and unmarshaling
   238  // protocol buffers.  It may be reused between invocations to
   239  // reduce memory usage.  It is not necessary to use a Buffer;
   240  // the global functions Marshal and Unmarshal create a
   241  // temporary Buffer and are fine for most applications.
   242  type Buffer struct {
   243  	buf   []byte // encode/decode byte stream
   244  	index int    // write point
   245  
   246  	// pools of basic types to amortize allocation.
   247  	bools   []bool
   248  	uint32s []uint32
   249  	uint64s []uint64
   250  
   251  	// extra pools, only used with pointer_reflect.go
   252  	int32s   []int32
   253  	int64s   []int64
   254  	float32s []float32
   255  	float64s []float64
   256  }
   257  
   258  // NewBuffer allocates a new Buffer and initializes its internal data to
   259  // the contents of the argument slice.
   260  func NewBuffer(e []byte) *Buffer {
   261  	return &Buffer{buf: e}
   262  }
   263  
   264  // Reset resets the Buffer, ready for marshaling a new protocol buffer.
   265  func (p *Buffer) Reset() {
   266  	p.buf = p.buf[0:0] // for reading/writing
   267  	p.index = 0        // for reading
   268  }
   269  
   270  // SetBuf replaces the internal buffer with the slice,
   271  // ready for unmarshaling the contents of the slice.
   272  func (p *Buffer) SetBuf(s []byte) {
   273  	p.buf = s
   274  	p.index = 0
   275  }
   276  
   277  // Bytes returns the contents of the Buffer.
   278  func (p *Buffer) Bytes() []byte { return p.buf }
   279  
   280  /*
   281   * Helper routines for simplifying the creation of optional fields of basic type.
   282   */
   283  
   284  // Bool is a helper routine that allocates a new bool value
   285  // to store v and returns a pointer to it.
   286  func Bool(v bool) *bool {
   287  	return &v
   288  }
   289  
   290  // Int32 is a helper routine that allocates a new int32 value
   291  // to store v and returns a pointer to it.
   292  func Int32(v int32) *int32 {
   293  	return &v
   294  }
   295  
   296  // Int is a helper routine that allocates a new int32 value
   297  // to store v and returns a pointer to it, but unlike Int32
   298  // its argument value is an int.
   299  func Int(v int) *int32 {
   300  	p := new(int32)
   301  	*p = int32(v)
   302  	return p
   303  }
   304  
   305  // Int64 is a helper routine that allocates a new int64 value
   306  // to store v and returns a pointer to it.
   307  func Int64(v int64) *int64 {
   308  	return &v
   309  }
   310  
   311  // Float32 is a helper routine that allocates a new float32 value
   312  // to store v and returns a pointer to it.
   313  func Float32(v float32) *float32 {
   314  	return &v
   315  }
   316  
   317  // Float64 is a helper routine that allocates a new float64 value
   318  // to store v and returns a pointer to it.
   319  func Float64(v float64) *float64 {
   320  	return &v
   321  }
   322  
   323  // Uint32 is a helper routine that allocates a new uint32 value
   324  // to store v and returns a pointer to it.
   325  func Uint32(v uint32) *uint32 {
   326  	p := new(uint32)
   327  	*p = v
   328  	return p
   329  }
   330  
   331  // Uint64 is a helper routine that allocates a new uint64 value
   332  // to store v and returns a pointer to it.
   333  func Uint64(v uint64) *uint64 {
   334  	return &v
   335  }
   336  
   337  // String is a helper routine that allocates a new string value
   338  // to store v and returns a pointer to it.
   339  func String(v string) *string {
   340  	return &v
   341  }
   342  
   343  // EnumName is a helper function to simplify printing protocol buffer enums
   344  // by name.  Given an enum map and a value, it returns a useful string.
   345  func EnumName(m map[int32]string, v int32) string {
   346  	s, ok := m[v]
   347  	if ok {
   348  		return s
   349  	}
   350  	return strconv.Itoa(int(v))
   351  }
   352  
   353  // UnmarshalJSONEnum is a helper function to simplify recovering enum int values
   354  // from their JSON-encoded representation. Given a map from the enum's symbolic
   355  // names to its int values, and a byte buffer containing the JSON-encoded
   356  // value, it returns an int32 that can be cast to the enum type by the caller.
   357  //
   358  // The function can deal with both JSON representations, numeric and symbolic.
   359  func UnmarshalJSONEnum(m map[string]int32, data []byte, enumName string) (int32, error) {
   360  	if data[0] == '"' {
   361  		// New style: enums are strings.
   362  		var repr string
   363  		if err := json.Unmarshal(data, &repr); err != nil {
   364  			return -1, err
   365  		}
   366  		val, ok := m[repr]
   367  		if !ok {
   368  			return 0, fmt.Errorf("unrecognized enum %s value %q", enumName, repr)
   369  		}
   370  		return val, nil
   371  	}
   372  	// Old style: enums are ints.
   373  	var val int32
   374  	if err := json.Unmarshal(data, &val); err != nil {
   375  		return 0, fmt.Errorf("cannot unmarshal %#q into enum %s", data, enumName)
   376  	}
   377  	return val, nil
   378  }
   379  
   380  // DebugPrint dumps the encoded data in b in a debugging format with a header
   381  // including the string s. Used in testing but made available for general debugging.
   382  func (o *Buffer) DebugPrint(s string, b []byte) {
   383  	var u uint64
   384  
   385  	obuf := o.buf
   386  	index := o.index
   387  	o.buf = b
   388  	o.index = 0
   389  	depth := 0
   390  
   391  	fmt.Printf("\n--- %s ---\n", s)
   392  
   393  out:
   394  	for {
   395  		for i := 0; i < depth; i++ {
   396  			fmt.Print("  ")
   397  		}
   398  
   399  		index := o.index
   400  		if index == len(o.buf) {
   401  			break
   402  		}
   403  
   404  		op, err := o.DecodeVarint()
   405  		if err != nil {
   406  			fmt.Printf("%3d: fetching op err %v\n", index, err)
   407  			break out
   408  		}
   409  		tag := op >> 3
   410  		wire := op & 7
   411  
   412  		switch wire {
   413  		default:
   414  			fmt.Printf("%3d: t=%3d unknown wire=%d\n",
   415  				index, tag, wire)
   416  			break out
   417  
   418  		case WireBytes:
   419  			var r []byte
   420  
   421  			r, err = o.DecodeRawBytes(false)
   422  			if err != nil {
   423  				break out
   424  			}
   425  			fmt.Printf("%3d: t=%3d bytes [%d]", index, tag, len(r))
   426  			if len(r) <= 6 {
   427  				for i := 0; i < len(r); i++ {
   428  					fmt.Printf(" %.2x", r[i])
   429  				}
   430  			} else {
   431  				for i := 0; i < 3; i++ {
   432  					fmt.Printf(" %.2x", r[i])
   433  				}
   434  				fmt.Printf(" ..")
   435  				for i := len(r) - 3; i < len(r); i++ {
   436  					fmt.Printf(" %.2x", r[i])
   437  				}
   438  			}
   439  			fmt.Printf("\n")
   440  
   441  		case WireFixed32:
   442  			u, err = o.DecodeFixed32()
   443  			if err != nil {
   444  				fmt.Printf("%3d: t=%3d fix32 err %v\n", index, tag, err)
   445  				break out
   446  			}
   447  			fmt.Printf("%3d: t=%3d fix32 %d\n", index, tag, u)
   448  
   449  		case WireFixed64:
   450  			u, err = o.DecodeFixed64()
   451  			if err != nil {
   452  				fmt.Printf("%3d: t=%3d fix64 err %v\n", index, tag, err)
   453  				break out
   454  			}
   455  			fmt.Printf("%3d: t=%3d fix64 %d\n", index, tag, u)
   456  			break
   457  
   458  		case WireVarint:
   459  			u, err = o.DecodeVarint()
   460  			if err != nil {
   461  				fmt.Printf("%3d: t=%3d varint err %v\n", index, tag, err)
   462  				break out
   463  			}
   464  			fmt.Printf("%3d: t=%3d varint %d\n", index, tag, u)
   465  
   466  		case WireStartGroup:
   467  			if err != nil {
   468  				fmt.Printf("%3d: t=%3d start err %v\n", index, tag, err)
   469  				break out
   470  			}
   471  			fmt.Printf("%3d: t=%3d start\n", index, tag)
   472  			depth++
   473  
   474  		case WireEndGroup:
   475  			depth--
   476  			if err != nil {
   477  				fmt.Printf("%3d: t=%3d end err %v\n", index, tag, err)
   478  				break out
   479  			}
   480  			fmt.Printf("%3d: t=%3d end\n", index, tag)
   481  		}
   482  	}
   483  
   484  	if depth != 0 {
   485  		fmt.Printf("%3d: start-end not balanced %d\n", o.index, depth)
   486  	}
   487  	fmt.Printf("\n")
   488  
   489  	o.buf = obuf
   490  	o.index = index
   491  }
   492  
   493  // SetDefaults sets unset protocol buffer fields to their default values.
   494  // It only modifies fields that are both unset and have defined defaults.
   495  // It recursively sets default values in any non-nil sub-messages.
   496  func SetDefaults(pb Message) {
   497  	setDefaults(reflect.ValueOf(pb), true, false)
   498  }
   499  
   500  // v is a pointer to a struct.
   501  func setDefaults(v reflect.Value, recur, zeros bool) {
   502  	v = v.Elem()
   503  
   504  	defaultMu.RLock()
   505  	dm, ok := defaults[v.Type()]
   506  	defaultMu.RUnlock()
   507  	if !ok {
   508  		dm = buildDefaultMessage(v.Type())
   509  		defaultMu.Lock()
   510  		defaults[v.Type()] = dm
   511  		defaultMu.Unlock()
   512  	}
   513  
   514  	for _, sf := range dm.scalars {
   515  		f := v.Field(sf.index)
   516  		if !f.IsNil() {
   517  			// field already set
   518  			continue
   519  		}
   520  		dv := sf.value
   521  		if dv == nil && !zeros {
   522  			// no explicit default, and don't want to set zeros
   523  			continue
   524  		}
   525  		fptr := f.Addr().Interface() // **T
   526  		// TODO: Consider batching the allocations we do here.
   527  		switch sf.kind {
   528  		case reflect.Bool:
   529  			b := new(bool)
   530  			if dv != nil {
   531  				*b = dv.(bool)
   532  			}
   533  			*(fptr.(**bool)) = b
   534  		case reflect.Float32:
   535  			f := new(float32)
   536  			if dv != nil {
   537  				*f = dv.(float32)
   538  			}
   539  			*(fptr.(**float32)) = f
   540  		case reflect.Float64:
   541  			f := new(float64)
   542  			if dv != nil {
   543  				*f = dv.(float64)
   544  			}
   545  			*(fptr.(**float64)) = f
   546  		case reflect.Int32:
   547  			// might be an enum
   548  			if ft := f.Type(); ft != int32PtrType {
   549  				// enum
   550  				f.Set(reflect.New(ft.Elem()))
   551  				if dv != nil {
   552  					f.Elem().SetInt(int64(dv.(int32)))
   553  				}
   554  			} else {
   555  				// int32 field
   556  				i := new(int32)
   557  				if dv != nil {
   558  					*i = dv.(int32)
   559  				}
   560  				*(fptr.(**int32)) = i
   561  			}
   562  		case reflect.Int64:
   563  			i := new(int64)
   564  			if dv != nil {
   565  				*i = dv.(int64)
   566  			}
   567  			*(fptr.(**int64)) = i
   568  		case reflect.String:
   569  			s := new(string)
   570  			if dv != nil {
   571  				*s = dv.(string)
   572  			}
   573  			*(fptr.(**string)) = s
   574  		case reflect.Uint8:
   575  			// exceptional case: []byte
   576  			var b []byte
   577  			if dv != nil {
   578  				db := dv.([]byte)
   579  				b = make([]byte, len(db))
   580  				copy(b, db)
   581  			} else {
   582  				b = []byte{}
   583  			}
   584  			*(fptr.(*[]byte)) = b
   585  		case reflect.Uint32:
   586  			u := new(uint32)
   587  			if dv != nil {
   588  				*u = dv.(uint32)
   589  			}
   590  			*(fptr.(**uint32)) = u
   591  		case reflect.Uint64:
   592  			u := new(uint64)
   593  			if dv != nil {
   594  				*u = dv.(uint64)
   595  			}
   596  			*(fptr.(**uint64)) = u
   597  		default:
   598  			log.Printf("proto: can't set default for field %v (sf.kind=%v)", f, sf.kind)
   599  		}
   600  	}
   601  
   602  	for _, ni := range dm.nested {
   603  		f := v.Field(ni)
   604  		if f.IsNil() {
   605  			continue
   606  		}
   607  		// f is *T or []*T
   608  		if f.Kind() == reflect.Ptr {
   609  			setDefaults(f, recur, zeros)
   610  		} else {
   611  			for i := 0; i < f.Len(); i++ {
   612  				e := f.Index(i)
   613  				if e.IsNil() {
   614  					continue
   615  				}
   616  				setDefaults(e, recur, zeros)
   617  			}
   618  		}
   619  	}
   620  }
   621  
   622  var (
   623  	// defaults maps a protocol buffer struct type to a slice of the fields,
   624  	// with its scalar fields set to their proto-declared non-zero default values.
   625  	defaultMu sync.RWMutex
   626  	defaults  = make(map[reflect.Type]defaultMessage)
   627  
   628  	int32PtrType = reflect.TypeOf((*int32)(nil))
   629  )
   630  
   631  // defaultMessage represents information about the default values of a message.
   632  type defaultMessage struct {
   633  	scalars []scalarField
   634  	nested  []int // struct field index of nested messages
   635  }
   636  
   637  type scalarField struct {
   638  	index int          // struct field index
   639  	kind  reflect.Kind // element type (the T in *T or []T)
   640  	value interface{}  // the proto-declared default value, or nil
   641  }
   642  
   643  func ptrToStruct(t reflect.Type) bool {
   644  	return t.Kind() == reflect.Ptr && t.Elem().Kind() == reflect.Struct
   645  }
   646  
   647  // t is a struct type.
   648  func buildDefaultMessage(t reflect.Type) (dm defaultMessage) {
   649  	sprop := GetProperties(t)
   650  	for _, prop := range sprop.Prop {
   651  		fi, ok := sprop.decoderTags.get(prop.Tag)
   652  		if !ok {
   653  			// XXX_unrecognized
   654  			continue
   655  		}
   656  		ft := t.Field(fi).Type
   657  
   658  		// nested messages
   659  		if ptrToStruct(ft) || (ft.Kind() == reflect.Slice && ptrToStruct(ft.Elem())) {
   660  			dm.nested = append(dm.nested, fi)
   661  			continue
   662  		}
   663  
   664  		sf := scalarField{
   665  			index: fi,
   666  			kind:  ft.Elem().Kind(),
   667  		}
   668  
   669  		// scalar fields without defaults
   670  		if prop.Default == "" {
   671  			dm.scalars = append(dm.scalars, sf)
   672  			continue
   673  		}
   674  
   675  		// a scalar field: either *T or []byte
   676  		switch ft.Elem().Kind() {
   677  		case reflect.Bool:
   678  			x, err := strconv.ParseBool(prop.Default)
   679  			if err != nil {
   680  				log.Printf("proto: bad default bool %q: %v", prop.Default, err)
   681  				continue
   682  			}
   683  			sf.value = x
   684  		case reflect.Float32:
   685  			x, err := strconv.ParseFloat(prop.Default, 32)
   686  			if err != nil {
   687  				log.Printf("proto: bad default float32 %q: %v", prop.Default, err)
   688  				continue
   689  			}
   690  			sf.value = float32(x)
   691  		case reflect.Float64:
   692  			x, err := strconv.ParseFloat(prop.Default, 64)
   693  			if err != nil {
   694  				log.Printf("proto: bad default float64 %q: %v", prop.Default, err)
   695  				continue
   696  			}
   697  			sf.value = x
   698  		case reflect.Int32:
   699  			x, err := strconv.ParseInt(prop.Default, 10, 32)
   700  			if err != nil {
   701  				log.Printf("proto: bad default int32 %q: %v", prop.Default, err)
   702  				continue
   703  			}
   704  			sf.value = int32(x)
   705  		case reflect.Int64:
   706  			x, err := strconv.ParseInt(prop.Default, 10, 64)
   707  			if err != nil {
   708  				log.Printf("proto: bad default int64 %q: %v", prop.Default, err)
   709  				continue
   710  			}
   711  			sf.value = x
   712  		case reflect.String:
   713  			sf.value = prop.Default
   714  		case reflect.Uint8:
   715  			// []byte (not *uint8)
   716  			sf.value = []byte(prop.Default)
   717  		case reflect.Uint32:
   718  			x, err := strconv.ParseUint(prop.Default, 10, 32)
   719  			if err != nil {
   720  				log.Printf("proto: bad default uint32 %q: %v", prop.Default, err)
   721  				continue
   722  			}
   723  			sf.value = uint32(x)
   724  		case reflect.Uint64:
   725  			x, err := strconv.ParseUint(prop.Default, 10, 64)
   726  			if err != nil {
   727  				log.Printf("proto: bad default uint64 %q: %v", prop.Default, err)
   728  				continue
   729  			}
   730  			sf.value = x
   731  		default:
   732  			log.Printf("proto: unhandled def kind %v", ft.Elem().Kind())
   733  			continue
   734  		}
   735  
   736  		dm.scalars = append(dm.scalars, sf)
   737  	}
   738  
   739  	return dm
   740  }