blob: 7580bb45c61764aa66a8a6df4fb99aa512211464 [file] [log] [blame]
David K. Bainbridge215e0242017-09-05 23:18:24 -07001// 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/gogo/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/gogo/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 // read 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 sindex := 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 = sindex
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// ProtoPackageIsVersion2 is referenced from generated protocol buffer files
893// to assert that that code is compatible with this version of the proto package.
894const GoGoProtoPackageIsVersion2 = true
895
896// ProtoPackageIsVersion1 is referenced from generated protocol buffer files
897// to assert that that code is compatible with this version of the proto package.
898const GoGoProtoPackageIsVersion1 = true