blob: 0de8f8dffd0880ceea9abd8176eaa2adb1e11109 [file] [log] [blame]
Rob Pikeaaa3a622010-03-20 22:32:34 -07001// Go support for Protocol Buffers - Google's data interchange format
2//
David Symondsee6e9c52012-11-29 08:51:07 +11003// Copyright 2010 The Go Authors. All rights reserved.
David Symonds558f13f2014-11-24 10:28:53 +11004// https://github.com/golang/protobuf
Rob Pikeaaa3a622010-03-20 22:32:34 -07005//
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/*
David Symondsb955ee12015-05-02 04:05:00 +100033Package 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.
Rob Pikeaaa3a622010-03-20 22:32:34 -070036
David Symondsb955ee12015-05-02 04:05:00 +100037A summary of the properties of the protocol buffer interface
38for a protocol buffer variable v:
Rob Pikeaaa3a622010-03-20 22:32:34 -070039
David Symondsb955ee12015-05-02 04:05:00 +100040 - 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.
David Symonds59b73b32015-08-24 13:22:02 +100069 - Oneof field sets are given a single field in their message,
70 with distinguished wrapper types for each possible field value.
David Symondsb955ee12015-05-02 04:05:00 +100071 - Marshal and Unmarshal are functions to encode and decode the wire format.
Rob Pikeaaa3a622010-03-20 22:32:34 -070072
David Symonds04eac412016-01-05 11:20:00 +110073When 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
David Symondsb955ee12015-05-02 04:05:00 +100079The simplest way to describe this is to see an example.
80Given file test.proto, containing
Rob Pikeaaa3a622010-03-20 22:32:34 -070081
David Symondsb955ee12015-05-02 04:05:00 +100082 package example;
Rob Pikeaaa3a622010-03-20 22:32:34 -070083
David Symondsb955ee12015-05-02 04:05:00 +100084 enum FOO { X = 17; }
Rob Pikeaaa3a622010-03-20 22:32:34 -070085
David Symondsb955ee12015-05-02 04:05:00 +100086 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 }
Dave Dayef197e12015-09-02 09:30:00 +100093 oneof union {
94 int32 number = 6;
95 string name = 7;
96 }
David Symondsb955ee12015-05-02 04:05:00 +100097 }
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
Rob Pikeaaa3a622010-03-20 22:32:34 -0700129 }
David Symondsb955ee12015-05-02 04:05:00 +1000130 *x = FOO(value)
131 return nil
132 }
Rob Pikeaaa3a622010-03-20 22:32:34 -0700133
David Symondsb955ee12015-05-02 04:05:00 +1000134 type Test struct {
Dave Dayef197e12015-09-02 09:30:00 +1000135 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:"-"`
David Symondsb955ee12015-05-02 04:05:00 +1000144 }
145 func (m *Test) Reset() { *m = Test{} }
146 func (m *Test) String() string { return proto.CompactTextString(m) }
Dave Dayef197e12015-09-02 09:30:00 +1000147 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 }
David Symondsb955ee12015-05-02 04:05:00 +1000169 const Default_Test_Type int32 = 77
Rob Pikeaaa3a622010-03-20 22:32:34 -0700170
David Symondsb955ee12015-05-02 04:05:00 +1000171 func (m *Test) GetLabel() string {
172 if m != nil && m.Label != nil {
173 return *m.Label
Rob Pikeaaa3a622010-03-20 22:32:34 -0700174 }
David Symondsb955ee12015-05-02 04:05:00 +1000175 return ""
176 }
177
178 func (m *Test) GetType() int32 {
179 if m != nil && m.Type != nil {
180 return *m.Type
Rob Pikeaaa3a622010-03-20 22:32:34 -0700181 }
David Symondsb955ee12015-05-02 04:05:00 +1000182 return Default_Test_Type
183 }
David Symondsefeca9a2012-05-08 10:36:04 +1000184
David Symondsb955ee12015-05-02 04:05:00 +1000185 func (m *Test) GetOptionalgroup() *Test_OptionalGroup {
186 if m != nil {
187 return m.Optionalgroup
Rob Pikeaaa3a622010-03-20 22:32:34 -0700188 }
David Symondsb955ee12015-05-02 04:05:00 +1000189 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
David Symonds350c58f2011-08-03 12:09:32 +1000201 }
David Symondsb955ee12015-05-02 04:05:00 +1000202 return ""
203 }
204
Dave Dayef197e12015-09-02 09:30:00 +1000205 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
David Symondsb955ee12015-05-02 04:05:00 +1000219 func init() {
220 proto.RegisterEnum("example.FOO", FOO_name, FOO_value)
221 }
222
223To create and play with a Test object:
224
David Symondse63abb12015-11-04 09:37:32 +1100225 package main
David Symondsb955ee12015-05-02 04:05:00 +1000226
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),
Zac Mullett6aaa8d42016-01-24 20:11:55 +0100238 Reps: []int64{1, 2, 3},
David Symondsb955ee12015-05-02 04:05:00 +1000239 Optionalgroup: &pb.Test_OptionalGroup{
240 RequiredField: proto.String("good bye"),
241 },
Dave Dayef197e12015-09-02 09:30:00 +1000242 Union: &pb.Test_Name{"fred"},
David Symonds1e735162015-02-09 11:05:25 +1100243 }
David Symondsb955ee12015-05-02 04:05:00 +1000244 data, err := proto.Marshal(test)
245 if err != nil {
246 log.Fatal("marshaling error: ", err)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700247 }
David Symondsb955ee12015-05-02 04:05:00 +1000248 newTest := &pb.Test{}
249 err = proto.Unmarshal(data, newTest)
250 if err != nil {
251 log.Fatal("unmarshaling error: ", err)
David Symonds87c9bcc2012-06-28 10:42:01 -0700252 }
David Symondsb955ee12015-05-02 04:05:00 +1000253 // 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())
David Symonds87c9bcc2012-06-28 10:42:01 -0700256 }
Dave Dayef197e12015-09-02 09:30:00 +1000257 // 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 }
David Symondsb955ee12015-05-02 04:05:00 +1000262 // etc.
263 }
Rob Pikeaaa3a622010-03-20 22:32:34 -0700264*/
265package proto
266
267import (
David Symonds62539862012-08-04 10:06:55 +1000268 "encoding/json"
Rob Pikeaaa3a622010-03-20 22:32:34 -0700269 "fmt"
David Symondsb79d99b2011-08-29 16:38:49 +1000270 "log"
271 "reflect"
David Symonds66836542015-07-25 20:00:00 +1000272 "sort"
Rob Pikeaaa3a622010-03-20 22:32:34 -0700273 "strconv"
David Symondsb79d99b2011-08-29 16:38:49 +1000274 "sync"
Rob Pikeaaa3a622010-03-20 22:32:34 -0700275)
276
David Symonds9f60f432012-06-14 09:45:25 +1000277// Message is implemented by generated protocol buffer messages.
278type Message interface {
279 Reset()
280 String() string
281 ProtoMessage()
282}
283
Rob Pikeaaa3a622010-03-20 22:32:34 -0700284// 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
David Symonds0bf1ad52013-10-11 09:07:50 +1100293 Size uint64 // number of sizes
Rob Pikeaaa3a622010-03-20 22:32:34 -0700294}
295
David Symonds9f60f432012-06-14 09:45:25 +1000296// Set to true to enable stats collection.
297const collectStats = false
298
Rob Pikeaaa3a622010-03-20 22:32:34 -0700299var 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 {
David Symonds8b253302014-01-14 16:24:19 +1100310 buf []byte // encode/decode byte stream
311 index int // write point
Russ Coxd4ce3f12012-09-12 10:36:26 +1000312
Rob Pike76f6ee52011-10-20 12:58:28 -0700313 // pools of basic types to amortize allocation.
Russ Coxd4ce3f12012-09-12 10:36:26 +1000314 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
Rob Pikeaaa3a622010-03-20 22:32:34 -0700323}
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 {
David Symonds8b253302014-01-14 16:24:19 +1100328 return &Buffer{buf: e}
Rob Pikeaaa3a622010-03-20 22:32:34 -0700329}
330
331// Reset resets the Buffer, ready for marshaling a new protocol buffer.
332func (p *Buffer) Reset() {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700333 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
Rob Pikeaaa3a622010-03-20 22:32:34 -0700347/*
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 {
David Symondsfff2ec62013-08-08 13:37:09 +1000354 return &v
Rob Pikeaaa3a622010-03-20 22:32:34 -0700355}
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 {
David Symondsfff2ec62013-08-08 13:37:09 +1000360 return &v
Rob Pikeaaa3a622010-03-20 22:32:34 -0700361}
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 {
David Symondsfff2ec62013-08-08 13:37:09 +1000375 return &v
Rob Pikeaaa3a622010-03-20 22:32:34 -0700376}
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 {
David Symondsfff2ec62013-08-08 13:37:09 +1000381 return &v
Rob Pikeaaa3a622010-03-20 22:32:34 -0700382}
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 {
David Symondsfff2ec62013-08-08 13:37:09 +1000387 return &v
Rob Pikeaaa3a622010-03-20 22:32:34 -0700388}
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 {
David Symonds60976d32015-01-06 07:56:48 +1100393 return &v
Rob Pikeaaa3a622010-03-20 22:32:34 -0700394}
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 {
David Symondsfff2ec62013-08-08 13:37:09 +1000399 return &v
Rob Pikeaaa3a622010-03-20 22:32:34 -0700400}
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 {
David Symondsfff2ec62013-08-08 13:37:09 +1000405 return &v
Rob Pikeaaa3a622010-03-20 22:32:34 -0700406}
407
Rob Pikeaaa3a622010-03-20 22:32:34 -0700408// 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 }
David Symondsf8a1fcc2013-05-03 08:51:23 +1000415 return strconv.Itoa(int(v))
Rob Pikeaaa3a622010-03-20 22:32:34 -0700416}
417
David Symonds62539862012-08-04 10:06:55 +1000418// 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//
David Symonds4af5f1f2013-10-11 10:08:35 +1100423// The function can deal with both JSON representations, numeric and symbolic.
David Symonds62539862012-08-04 10:06:55 +1000424func 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
Rob Pikeaaa3a622010-03-20 22:32:34 -0700445// 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.
David Symondsb955ee12015-05-02 04:05:00 +1000447func (p *Buffer) DebugPrint(s string, b []byte) {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700448 var u uint64
449
David Symondsb955ee12015-05-02 04:05:00 +1000450 obuf := p.buf
451 index := p.index
452 p.buf = b
453 p.index = 0
Rob Pikeaaa3a622010-03-20 22:32:34 -0700454 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
David Symondsb955ee12015-05-02 04:05:00 +1000464 index := p.index
465 if index == len(p.buf) {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700466 break
467 }
468
David Symondsb955ee12015-05-02 04:05:00 +1000469 op, err := p.DecodeVarint()
Rob Pikeaaa3a622010-03-20 22:32:34 -0700470 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
David Symondsb955ee12015-05-02 04:05:00 +1000486 r, err = p.DecodeRawBytes(false)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700487 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:
David Symondsb955ee12015-05-02 04:05:00 +1000507 u, err = p.DecodeFixed32()
Rob Pikeaaa3a622010-03-20 22:32:34 -0700508 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:
David Symondsb955ee12015-05-02 04:05:00 +1000515 u, err = p.DecodeFixed64()
Rob Pikeaaa3a622010-03-20 22:32:34 -0700516 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)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700521
522 case WireVarint:
David Symondsb955ee12015-05-02 04:05:00 +1000523 u, err = p.DecodeVarint()
Rob Pikeaaa3a622010-03-20 22:32:34 -0700524 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:
Rob Pikeaaa3a622010-03-20 22:32:34 -0700531 fmt.Printf("%3d: t=%3d start\n", index, tag)
532 depth++
533
534 case WireEndGroup:
535 depth--
Rob Pikeaaa3a622010-03-20 22:32:34 -0700536 fmt.Printf("%3d: t=%3d end\n", index, tag)
537 }
538 }
539
540 if depth != 0 {
David Symondsb955ee12015-05-02 04:05:00 +1000541 fmt.Printf("%3d: start-end not balanced %d\n", p.index, depth)
Rob Pikeaaa3a622010-03-20 22:32:34 -0700542 }
543 fmt.Printf("\n")
544
David Symondsb955ee12015-05-02 04:05:00 +1000545 p.buf = obuf
546 p.index = index
Rob Pikeaaa3a622010-03-20 22:32:34 -0700547}
David Symondsb79d99b2011-08-29 16:38:49 +1000548
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.
David Symonds9f60f432012-06-14 09:45:25 +1000552func SetDefaults(pb Message) {
553 setDefaults(reflect.ValueOf(pb), true, false)
David Symondsb79d99b2011-08-29 16:38:49 +1000554}
555
556// v is a pointer to a struct.
557func setDefaults(v reflect.Value, recur, zeros bool) {
558 v = v.Elem()
559
David Symonds72607582011-11-01 12:52:01 +1100560 defaultMu.RLock()
David Symondsb79d99b2011-08-29 16:38:49 +1000561 dm, ok := defaults[v.Type()]
David Symonds72607582011-11-01 12:52:01 +1100562 defaultMu.RUnlock()
David Symondsb79d99b2011-08-29 16:38:49 +1000563 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 {
David Symonds814b9362011-12-13 09:10:47 +1100659 f := v.Field(ni)
David Symondsde8c5232015-03-20 16:29:30 +1100660 // f is *T or []*T or map[T]*T
661 switch f.Kind() {
662 case reflect.Ptr:
663 if f.IsNil() {
664 continue
665 }
David Symonds472e2592013-07-15 11:10:07 +1000666 setDefaults(f, recur, zeros)
David Symondsde8c5232015-03-20 16:29:30 +1100667
668 case reflect.Slice:
David Symonds472e2592013-07-15 11:10:07 +1000669 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 }
David Symondsde8c5232015-03-20 16:29:30 +1100676
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 }
David Symonds472e2592013-07-15 11:10:07 +1000685 }
David Symondsb79d99b2011-08-29 16:38:49 +1000686 }
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.
David Symonds72607582011-11-01 12:52:01 +1100692 defaultMu sync.RWMutex
David Symondsb79d99b2011-08-29 16:38:49 +1000693 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 {
David Symonds2bba1b22012-09-26 14:53:08 +1000714 fi, ok := sprop.decoderTags.get(prop.Tag)
David Symonds6a6f82c2012-08-22 09:18:54 +1000715 if !ok {
716 // XXX_unrecognized
717 continue
718 }
David Symondsb79d99b2011-08-29 16:38:49 +1000719 ft := t.Field(fi).Type
720
David Symondsc8ba1152015-05-21 01:23:00 +1000721 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)
David Symondsde8c5232015-03-20 16:29:30 +1100730 }
David Symondsb79d99b2011-08-29 16:38:49 +1000731 }
732
733 return dm
734}
David Symonds7f079252015-01-09 11:09:00 +1100735
David Symondsc8ba1152015-05-21 01:23:00 +1000736// 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
David Symonds7f079252015-01-09 11:09:00 +1100835// 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
David Symonds66836542015-07-25 20:00:00 +1000840func 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 }
David Symonds7f079252015-01-09 11:09:00 +1100848
David Symonds66836542015-07-25 20:00:00 +1000849 // 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])
David Symonds7f079252015-01-09 11:09:00 +1100873}
David Symondsab974be2015-07-07 21:13:00 -0600874
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}
David Symonds2402d762016-01-06 12:58:00 +1100891
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