podman

Форк
0
973 строки · 26.4 Кб
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

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.