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/* 33Package proto converts data structures to and from the wire format of 34protocol buffers. It works in concert with the Go source code generated 35for .proto files by the protocol compiler. 36 37A summary of the properties of the protocol buffer interface 38for 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 73When 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 79The simplest way to describe this is to see an example. 80Given 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 99The resulting file, test.pb.go, is: 100 101 package example 102 103 import proto "github.com/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 223To create and play with a Test object: 224 225 package main 226 227 import ( 228 "log" 229 230 "github.com/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*/ 265package proto 266 267import ( 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. 278type 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. 286type 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. 297const collectStats = false 298 299var stats Stats 300 301// GetStats returns a copy of the global Stats structure. 302func 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. 309type 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. 327func NewBuffer(e []byte) *Buffer { 328 return &Buffer{buf: e} 329} 330 331// Reset resets the Buffer, ready for marshaling a new protocol buffer. 332func (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. 339func (p *Buffer) SetBuf(s []byte) { 340 p.buf = s 341 p.index = 0 342} 343 344// Bytes returns the contents of the Buffer. 345func (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. 353func 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. 359func 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. 366func 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. 374func 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. 380func 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. 386func 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. 392func 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. 398func 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. 404func 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. 410func 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. 424func 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. 447func (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 458out: 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. 552func SetDefaults(pb Message) { 553 setDefaults(reflect.ValueOf(pb), true, false) 554} 555 556// v is a pointer to a struct. 557func 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 689var ( 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. 699type defaultMessage struct { 700 scalars []scalarField 701 nested []int // struct field index of nested messages 702} 703 704type 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. 711func 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. 740func 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 840func 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 864type mapKeySorter struct { 865 vs []reflect.Value 866 less func(a, b reflect.Value) bool 867} 868 869func (s mapKeySorter) Len() int { return len(s.vs) } 870func (s mapKeySorter) Swap(i, j int) { s.vs[i], s.vs[j] = s.vs[j], s.vs[i] } 871func (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. 876func 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. 894const ProtoPackageIsVersion1 = true 895