blob: 44b332052ef514d38a66857594c29bb95a8e7165 [file] [log] [blame]
David K. Bainbridge215e0242017-09-05 23:18:24 -07001// Protocol Buffers for Go with Gadgets
2//
3// Copyright (c) 2013, The GoGo Authors. All rights reserved.
4// http://github.com/gogo/protobuf
5//
6// Go support for Protocol Buffers - Google's data interchange format
7//
8// Copyright 2010 The Go Authors. All rights reserved.
9// https://github.com/golang/protobuf
10//
11// Redistribution and use in source and binary forms, with or without
12// modification, are permitted provided that the following conditions are
13// met:
14//
15// * Redistributions of source code must retain the above copyright
16// notice, this list of conditions and the following disclaimer.
17// * Redistributions in binary form must reproduce the above
18// copyright notice, this list of conditions and the following disclaimer
19// in the documentation and/or other materials provided with the
20// distribution.
21// * Neither the name of Google Inc. nor the names of its
22// contributors may be used to endorse or promote products derived from
23// this software without specific prior written permission.
24//
25// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
26// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
27// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
28// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
29// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
30// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
31// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
32// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
33// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
35// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36
37package proto
38
39/*
40 * Routines for encoding data into the wire format for protocol buffers.
41 */
42
43import (
44 "fmt"
45 "log"
46 "os"
47 "reflect"
48 "sort"
49 "strconv"
50 "strings"
51 "sync"
52)
53
54const debug bool = false
55
56// Constants that identify the encoding of a value on the wire.
57const (
58 WireVarint = 0
59 WireFixed64 = 1
60 WireBytes = 2
61 WireStartGroup = 3
62 WireEndGroup = 4
63 WireFixed32 = 5
64)
65
66const startSize = 10 // initial slice/string sizes
67
68// Encoders are defined in encode.go
69// An encoder outputs the full representation of a field, including its
70// tag and encoder type.
71type encoder func(p *Buffer, prop *Properties, base structPointer) error
72
73// A valueEncoder encodes a single integer in a particular encoding.
74type valueEncoder func(o *Buffer, x uint64) error
75
76// Sizers are defined in encode.go
77// A sizer returns the encoded size of a field, including its tag and encoder
78// type.
79type sizer func(prop *Properties, base structPointer) int
80
81// A valueSizer returns the encoded size of a single integer in a particular
82// encoding.
83type valueSizer func(x uint64) int
84
85// Decoders are defined in decode.go
86// A decoder creates a value from its wire representation.
87// Unrecognized subelements are saved in unrec.
88type decoder func(p *Buffer, prop *Properties, base structPointer) error
89
90// A valueDecoder decodes a single integer in a particular encoding.
91type valueDecoder func(o *Buffer) (x uint64, err error)
92
93// A oneofMarshaler does the marshaling for all oneof fields in a message.
94type oneofMarshaler func(Message, *Buffer) error
95
96// A oneofUnmarshaler does the unmarshaling for a oneof field in a message.
97type oneofUnmarshaler func(Message, int, int, *Buffer) (bool, error)
98
99// A oneofSizer does the sizing for all oneof fields in a message.
100type oneofSizer func(Message) int
101
102// tagMap is an optimization over map[int]int for typical protocol buffer
103// use-cases. Encoded protocol buffers are often in tag order with small tag
104// numbers.
105type tagMap struct {
106 fastTags []int
107 slowTags map[int]int
108}
109
110// tagMapFastLimit is the upper bound on the tag number that will be stored in
111// the tagMap slice rather than its map.
112const tagMapFastLimit = 1024
113
114func (p *tagMap) get(t int) (int, bool) {
115 if t > 0 && t < tagMapFastLimit {
116 if t >= len(p.fastTags) {
117 return 0, false
118 }
119 fi := p.fastTags[t]
120 return fi, fi >= 0
121 }
122 fi, ok := p.slowTags[t]
123 return fi, ok
124}
125
126func (p *tagMap) put(t int, fi int) {
127 if t > 0 && t < tagMapFastLimit {
128 for len(p.fastTags) < t+1 {
129 p.fastTags = append(p.fastTags, -1)
130 }
131 p.fastTags[t] = fi
132 return
133 }
134 if p.slowTags == nil {
135 p.slowTags = make(map[int]int)
136 }
137 p.slowTags[t] = fi
138}
139
140// StructProperties represents properties for all the fields of a struct.
141// decoderTags and decoderOrigNames should only be used by the decoder.
142type StructProperties struct {
143 Prop []*Properties // properties for each field
144 reqCount int // required count
145 decoderTags tagMap // map from proto tag to struct field number
146 decoderOrigNames map[string]int // map from original name to struct field number
147 order []int // list of struct field numbers in tag order
148 unrecField field // field id of the XXX_unrecognized []byte field
149 extendable bool // is this an extendable proto
150
151 oneofMarshaler oneofMarshaler
152 oneofUnmarshaler oneofUnmarshaler
153 oneofSizer oneofSizer
154 stype reflect.Type
155
156 // OneofTypes contains information about the oneof fields in this message.
157 // It is keyed by the original name of a field.
158 OneofTypes map[string]*OneofProperties
159}
160
161// OneofProperties represents information about a specific field in a oneof.
162type OneofProperties struct {
163 Type reflect.Type // pointer to generated struct type for this oneof field
164 Field int // struct field number of the containing oneof in the message
165 Prop *Properties
166}
167
168// Implement the sorting interface so we can sort the fields in tag order, as recommended by the spec.
169// See encode.go, (*Buffer).enc_struct.
170
171func (sp *StructProperties) Len() int { return len(sp.order) }
172func (sp *StructProperties) Less(i, j int) bool {
173 return sp.Prop[sp.order[i]].Tag < sp.Prop[sp.order[j]].Tag
174}
175func (sp *StructProperties) Swap(i, j int) { sp.order[i], sp.order[j] = sp.order[j], sp.order[i] }
176
177// Properties represents the protocol-specific behavior of a single struct field.
178type Properties struct {
179 Name string // name of the field, for error messages
180 OrigName string // original name before protocol compiler (always set)
181 JSONName string // name to use for JSON; determined by protoc
182 Wire string
183 WireType int
184 Tag int
185 Required bool
186 Optional bool
187 Repeated bool
188 Packed bool // relevant for repeated primitives only
189 Enum string // set for enum types only
190 proto3 bool // whether this is known to be a proto3 field; set for []byte only
191 oneof bool // whether this is a oneof field
192
193 Default string // default value
194 HasDefault bool // whether an explicit default was provided
195 CustomType string
196 StdTime bool
197 StdDuration bool
198
199 enc encoder
200 valEnc valueEncoder // set for bool and numeric types only
201 field field
202 tagcode []byte // encoding of EncodeVarint((Tag<<3)|WireType)
203 tagbuf [8]byte
204 stype reflect.Type // set for struct types only
205 sstype reflect.Type // set for slices of structs types only
206 ctype reflect.Type // set for custom types only
207 sprop *StructProperties // set for struct types only
208 isMarshaler bool
209 isUnmarshaler bool
210
211 mtype reflect.Type // set for map types only
212 mkeyprop *Properties // set for map types only
213 mvalprop *Properties // set for map types only
214
215 size sizer
216 valSize valueSizer // set for bool and numeric types only
217
218 dec decoder
219 valDec valueDecoder // set for bool and numeric types only
220
221 // If this is a packable field, this will be the decoder for the packed version of the field.
222 packedDec decoder
223}
224
225// String formats the properties in the protobuf struct field tag style.
226func (p *Properties) String() string {
227 s := p.Wire
228 s = ","
229 s += strconv.Itoa(p.Tag)
230 if p.Required {
231 s += ",req"
232 }
233 if p.Optional {
234 s += ",opt"
235 }
236 if p.Repeated {
237 s += ",rep"
238 }
239 if p.Packed {
240 s += ",packed"
241 }
242 s += ",name=" + p.OrigName
243 if p.JSONName != p.OrigName {
244 s += ",json=" + p.JSONName
245 }
246 if p.proto3 {
247 s += ",proto3"
248 }
249 if p.oneof {
250 s += ",oneof"
251 }
252 if len(p.Enum) > 0 {
253 s += ",enum=" + p.Enum
254 }
255 if p.HasDefault {
256 s += ",def=" + p.Default
257 }
258 return s
259}
260
261// Parse populates p by parsing a string in the protobuf struct field tag style.
262func (p *Properties) Parse(s string) {
263 // "bytes,49,opt,name=foo,def=hello!"
264 fields := strings.Split(s, ",") // breaks def=, but handled below.
265 if len(fields) < 2 {
266 fmt.Fprintf(os.Stderr, "proto: tag has too few fields: %q\n", s)
267 return
268 }
269
270 p.Wire = fields[0]
271 switch p.Wire {
272 case "varint":
273 p.WireType = WireVarint
274 p.valEnc = (*Buffer).EncodeVarint
275 p.valDec = (*Buffer).DecodeVarint
276 p.valSize = sizeVarint
277 case "fixed32":
278 p.WireType = WireFixed32
279 p.valEnc = (*Buffer).EncodeFixed32
280 p.valDec = (*Buffer).DecodeFixed32
281 p.valSize = sizeFixed32
282 case "fixed64":
283 p.WireType = WireFixed64
284 p.valEnc = (*Buffer).EncodeFixed64
285 p.valDec = (*Buffer).DecodeFixed64
286 p.valSize = sizeFixed64
287 case "zigzag32":
288 p.WireType = WireVarint
289 p.valEnc = (*Buffer).EncodeZigzag32
290 p.valDec = (*Buffer).DecodeZigzag32
291 p.valSize = sizeZigzag32
292 case "zigzag64":
293 p.WireType = WireVarint
294 p.valEnc = (*Buffer).EncodeZigzag64
295 p.valDec = (*Buffer).DecodeZigzag64
296 p.valSize = sizeZigzag64
297 case "bytes", "group":
298 p.WireType = WireBytes
299 // no numeric converter for non-numeric types
300 default:
301 fmt.Fprintf(os.Stderr, "proto: tag has unknown wire type: %q\n", s)
302 return
303 }
304
305 var err error
306 p.Tag, err = strconv.Atoi(fields[1])
307 if err != nil {
308 return
309 }
310
311 for i := 2; i < len(fields); i++ {
312 f := fields[i]
313 switch {
314 case f == "req":
315 p.Required = true
316 case f == "opt":
317 p.Optional = true
318 case f == "rep":
319 p.Repeated = true
320 case f == "packed":
321 p.Packed = true
322 case strings.HasPrefix(f, "name="):
323 p.OrigName = f[5:]
324 case strings.HasPrefix(f, "json="):
325 p.JSONName = f[5:]
326 case strings.HasPrefix(f, "enum="):
327 p.Enum = f[5:]
328 case f == "proto3":
329 p.proto3 = true
330 case f == "oneof":
331 p.oneof = true
332 case strings.HasPrefix(f, "def="):
333 p.HasDefault = true
334 p.Default = f[4:] // rest of string
335 if i+1 < len(fields) {
336 // Commas aren't escaped, and def is always last.
337 p.Default += "," + strings.Join(fields[i+1:], ",")
338 break
339 }
340 case strings.HasPrefix(f, "embedded="):
341 p.OrigName = strings.Split(f, "=")[1]
342 case strings.HasPrefix(f, "customtype="):
343 p.CustomType = strings.Split(f, "=")[1]
344 case f == "stdtime":
345 p.StdTime = true
346 case f == "stdduration":
347 p.StdDuration = true
348 }
349 }
350}
351
352func logNoSliceEnc(t1, t2 reflect.Type) {
353 fmt.Fprintf(os.Stderr, "proto: no slice oenc for %T = []%T\n", t1, t2)
354}
355
356var protoMessageType = reflect.TypeOf((*Message)(nil)).Elem()
357
358// Initialize the fields for encoding and decoding.
359func (p *Properties) setEncAndDec(typ reflect.Type, f *reflect.StructField, lockGetProp bool) {
360 p.enc = nil
361 p.dec = nil
362 p.size = nil
363 isMap := typ.Kind() == reflect.Map
364 if len(p.CustomType) > 0 && !isMap {
365 p.setCustomEncAndDec(typ)
366 p.setTag(lockGetProp)
367 return
368 }
369 if p.StdTime && !isMap {
370 p.setTimeEncAndDec(typ)
371 p.setTag(lockGetProp)
372 return
373 }
374 if p.StdDuration && !isMap {
375 p.setDurationEncAndDec(typ)
376 p.setTag(lockGetProp)
377 return
378 }
379 switch t1 := typ; t1.Kind() {
380 default:
381 fmt.Fprintf(os.Stderr, "proto: no coders for %v\n", t1)
382
383 // proto3 scalar types
384
385 case reflect.Bool:
386 if p.proto3 {
387 p.enc = (*Buffer).enc_proto3_bool
388 p.dec = (*Buffer).dec_proto3_bool
389 p.size = size_proto3_bool
390 } else {
391 p.enc = (*Buffer).enc_ref_bool
392 p.dec = (*Buffer).dec_proto3_bool
393 p.size = size_ref_bool
394 }
395 case reflect.Int32:
396 if p.proto3 {
397 p.enc = (*Buffer).enc_proto3_int32
398 p.dec = (*Buffer).dec_proto3_int32
399 p.size = size_proto3_int32
400 } else {
401 p.enc = (*Buffer).enc_ref_int32
402 p.dec = (*Buffer).dec_proto3_int32
403 p.size = size_ref_int32
404 }
405 case reflect.Uint32:
406 if p.proto3 {
407 p.enc = (*Buffer).enc_proto3_uint32
408 p.dec = (*Buffer).dec_proto3_int32 // can reuse
409 p.size = size_proto3_uint32
410 } else {
411 p.enc = (*Buffer).enc_ref_uint32
412 p.dec = (*Buffer).dec_proto3_int32 // can reuse
413 p.size = size_ref_uint32
414 }
415 case reflect.Int64, reflect.Uint64:
416 if p.proto3 {
417 p.enc = (*Buffer).enc_proto3_int64
418 p.dec = (*Buffer).dec_proto3_int64
419 p.size = size_proto3_int64
420 } else {
421 p.enc = (*Buffer).enc_ref_int64
422 p.dec = (*Buffer).dec_proto3_int64
423 p.size = size_ref_int64
424 }
425 case reflect.Float32:
426 if p.proto3 {
427 p.enc = (*Buffer).enc_proto3_uint32 // can just treat them as bits
428 p.dec = (*Buffer).dec_proto3_int32
429 p.size = size_proto3_uint32
430 } else {
431 p.enc = (*Buffer).enc_ref_uint32 // can just treat them as bits
432 p.dec = (*Buffer).dec_proto3_int32
433 p.size = size_ref_uint32
434 }
435 case reflect.Float64:
436 if p.proto3 {
437 p.enc = (*Buffer).enc_proto3_int64 // can just treat them as bits
438 p.dec = (*Buffer).dec_proto3_int64
439 p.size = size_proto3_int64
440 } else {
441 p.enc = (*Buffer).enc_ref_int64 // can just treat them as bits
442 p.dec = (*Buffer).dec_proto3_int64
443 p.size = size_ref_int64
444 }
445 case reflect.String:
446 if p.proto3 {
447 p.enc = (*Buffer).enc_proto3_string
448 p.dec = (*Buffer).dec_proto3_string
449 p.size = size_proto3_string
450 } else {
451 p.enc = (*Buffer).enc_ref_string
452 p.dec = (*Buffer).dec_proto3_string
453 p.size = size_ref_string
454 }
455 case reflect.Struct:
456 p.stype = typ
457 p.isMarshaler = isMarshaler(typ)
458 p.isUnmarshaler = isUnmarshaler(typ)
459 if p.Wire == "bytes" {
460 p.enc = (*Buffer).enc_ref_struct_message
461 p.dec = (*Buffer).dec_ref_struct_message
462 p.size = size_ref_struct_message
463 } else {
464 fmt.Fprintf(os.Stderr, "proto: no coders for struct %T\n", typ)
465 }
466
467 case reflect.Ptr:
468 switch t2 := t1.Elem(); t2.Kind() {
469 default:
470 fmt.Fprintf(os.Stderr, "proto: no encoder function for %v -> %v\n", t1, t2)
471 break
472 case reflect.Bool:
473 p.enc = (*Buffer).enc_bool
474 p.dec = (*Buffer).dec_bool
475 p.size = size_bool
476 case reflect.Int32:
477 p.enc = (*Buffer).enc_int32
478 p.dec = (*Buffer).dec_int32
479 p.size = size_int32
480 case reflect.Uint32:
481 p.enc = (*Buffer).enc_uint32
482 p.dec = (*Buffer).dec_int32 // can reuse
483 p.size = size_uint32
484 case reflect.Int64, reflect.Uint64:
485 p.enc = (*Buffer).enc_int64
486 p.dec = (*Buffer).dec_int64
487 p.size = size_int64
488 case reflect.Float32:
489 p.enc = (*Buffer).enc_uint32 // can just treat them as bits
490 p.dec = (*Buffer).dec_int32
491 p.size = size_uint32
492 case reflect.Float64:
493 p.enc = (*Buffer).enc_int64 // can just treat them as bits
494 p.dec = (*Buffer).dec_int64
495 p.size = size_int64
496 case reflect.String:
497 p.enc = (*Buffer).enc_string
498 p.dec = (*Buffer).dec_string
499 p.size = size_string
500 case reflect.Struct:
501 p.stype = t1.Elem()
502 p.isMarshaler = isMarshaler(t1)
503 p.isUnmarshaler = isUnmarshaler(t1)
504 if p.Wire == "bytes" {
505 p.enc = (*Buffer).enc_struct_message
506 p.dec = (*Buffer).dec_struct_message
507 p.size = size_struct_message
508 } else {
509 p.enc = (*Buffer).enc_struct_group
510 p.dec = (*Buffer).dec_struct_group
511 p.size = size_struct_group
512 }
513 }
514
515 case reflect.Slice:
516 switch t2 := t1.Elem(); t2.Kind() {
517 default:
518 logNoSliceEnc(t1, t2)
519 break
520 case reflect.Bool:
521 if p.Packed {
522 p.enc = (*Buffer).enc_slice_packed_bool
523 p.size = size_slice_packed_bool
524 } else {
525 p.enc = (*Buffer).enc_slice_bool
526 p.size = size_slice_bool
527 }
528 p.dec = (*Buffer).dec_slice_bool
529 p.packedDec = (*Buffer).dec_slice_packed_bool
530 case reflect.Int32:
531 if p.Packed {
532 p.enc = (*Buffer).enc_slice_packed_int32
533 p.size = size_slice_packed_int32
534 } else {
535 p.enc = (*Buffer).enc_slice_int32
536 p.size = size_slice_int32
537 }
538 p.dec = (*Buffer).dec_slice_int32
539 p.packedDec = (*Buffer).dec_slice_packed_int32
540 case reflect.Uint32:
541 if p.Packed {
542 p.enc = (*Buffer).enc_slice_packed_uint32
543 p.size = size_slice_packed_uint32
544 } else {
545 p.enc = (*Buffer).enc_slice_uint32
546 p.size = size_slice_uint32
547 }
548 p.dec = (*Buffer).dec_slice_int32
549 p.packedDec = (*Buffer).dec_slice_packed_int32
550 case reflect.Int64, reflect.Uint64:
551 if p.Packed {
552 p.enc = (*Buffer).enc_slice_packed_int64
553 p.size = size_slice_packed_int64
554 } else {
555 p.enc = (*Buffer).enc_slice_int64
556 p.size = size_slice_int64
557 }
558 p.dec = (*Buffer).dec_slice_int64
559 p.packedDec = (*Buffer).dec_slice_packed_int64
560 case reflect.Uint8:
561 p.dec = (*Buffer).dec_slice_byte
562 if p.proto3 {
563 p.enc = (*Buffer).enc_proto3_slice_byte
564 p.size = size_proto3_slice_byte
565 } else {
566 p.enc = (*Buffer).enc_slice_byte
567 p.size = size_slice_byte
568 }
569 case reflect.Float32, reflect.Float64:
570 switch t2.Bits() {
571 case 32:
572 // can just treat them as bits
573 if p.Packed {
574 p.enc = (*Buffer).enc_slice_packed_uint32
575 p.size = size_slice_packed_uint32
576 } else {
577 p.enc = (*Buffer).enc_slice_uint32
578 p.size = size_slice_uint32
579 }
580 p.dec = (*Buffer).dec_slice_int32
581 p.packedDec = (*Buffer).dec_slice_packed_int32
582 case 64:
583 // can just treat them as bits
584 if p.Packed {
585 p.enc = (*Buffer).enc_slice_packed_int64
586 p.size = size_slice_packed_int64
587 } else {
588 p.enc = (*Buffer).enc_slice_int64
589 p.size = size_slice_int64
590 }
591 p.dec = (*Buffer).dec_slice_int64
592 p.packedDec = (*Buffer).dec_slice_packed_int64
593 default:
594 logNoSliceEnc(t1, t2)
595 break
596 }
597 case reflect.String:
598 p.enc = (*Buffer).enc_slice_string
599 p.dec = (*Buffer).dec_slice_string
600 p.size = size_slice_string
601 case reflect.Ptr:
602 switch t3 := t2.Elem(); t3.Kind() {
603 default:
604 fmt.Fprintf(os.Stderr, "proto: no ptr oenc for %T -> %T -> %T\n", t1, t2, t3)
605 break
606 case reflect.Struct:
607 p.stype = t2.Elem()
608 p.isMarshaler = isMarshaler(t2)
609 p.isUnmarshaler = isUnmarshaler(t2)
610 if p.Wire == "bytes" {
611 p.enc = (*Buffer).enc_slice_struct_message
612 p.dec = (*Buffer).dec_slice_struct_message
613 p.size = size_slice_struct_message
614 } else {
615 p.enc = (*Buffer).enc_slice_struct_group
616 p.dec = (*Buffer).dec_slice_struct_group
617 p.size = size_slice_struct_group
618 }
619 }
620 case reflect.Slice:
621 switch t2.Elem().Kind() {
622 default:
623 fmt.Fprintf(os.Stderr, "proto: no slice elem oenc for %T -> %T -> %T\n", t1, t2, t2.Elem())
624 break
625 case reflect.Uint8:
626 p.enc = (*Buffer).enc_slice_slice_byte
627 p.dec = (*Buffer).dec_slice_slice_byte
628 p.size = size_slice_slice_byte
629 }
630 case reflect.Struct:
631 p.setSliceOfNonPointerStructs(t1)
632 }
633
634 case reflect.Map:
635 p.enc = (*Buffer).enc_new_map
636 p.dec = (*Buffer).dec_new_map
637 p.size = size_new_map
638
639 p.mtype = t1
640 p.mkeyprop = &Properties{}
641 p.mkeyprop.init(reflect.PtrTo(p.mtype.Key()), "Key", f.Tag.Get("protobuf_key"), nil, lockGetProp)
642 p.mvalprop = &Properties{}
643 vtype := p.mtype.Elem()
644 if vtype.Kind() != reflect.Ptr && vtype.Kind() != reflect.Slice {
645 // The value type is not a message (*T) or bytes ([]byte),
646 // so we need encoders for the pointer to this type.
647 vtype = reflect.PtrTo(vtype)
648 }
649
650 p.mvalprop.CustomType = p.CustomType
651 p.mvalprop.StdDuration = p.StdDuration
652 p.mvalprop.StdTime = p.StdTime
653 p.mvalprop.init(vtype, "Value", f.Tag.Get("protobuf_val"), nil, lockGetProp)
654 }
655 p.setTag(lockGetProp)
656}
657
658func (p *Properties) setTag(lockGetProp bool) {
659 // precalculate tag code
660 wire := p.WireType
661 if p.Packed {
662 wire = WireBytes
663 }
664 x := uint32(p.Tag)<<3 | uint32(wire)
665 i := 0
666 for i = 0; x > 127; i++ {
667 p.tagbuf[i] = 0x80 | uint8(x&0x7F)
668 x >>= 7
669 }
670 p.tagbuf[i] = uint8(x)
671 p.tagcode = p.tagbuf[0 : i+1]
672
673 if p.stype != nil {
674 if lockGetProp {
675 p.sprop = GetProperties(p.stype)
676 } else {
677 p.sprop = getPropertiesLocked(p.stype)
678 }
679 }
680}
681
682var (
683 marshalerType = reflect.TypeOf((*Marshaler)(nil)).Elem()
684 unmarshalerType = reflect.TypeOf((*Unmarshaler)(nil)).Elem()
685)
686
687// isMarshaler reports whether type t implements Marshaler.
688func isMarshaler(t reflect.Type) bool {
689 return t.Implements(marshalerType)
690}
691
692// isUnmarshaler reports whether type t implements Unmarshaler.
693func isUnmarshaler(t reflect.Type) bool {
694 return t.Implements(unmarshalerType)
695}
696
697// Init populates the properties from a protocol buffer struct tag.
698func (p *Properties) Init(typ reflect.Type, name, tag string, f *reflect.StructField) {
699 p.init(typ, name, tag, f, true)
700}
701
702func (p *Properties) init(typ reflect.Type, name, tag string, f *reflect.StructField, lockGetProp bool) {
703 // "bytes,49,opt,def=hello!"
704 p.Name = name
705 p.OrigName = name
706 if f != nil {
707 p.field = toField(f)
708 }
709 if tag == "" {
710 return
711 }
712 p.Parse(tag)
713 p.setEncAndDec(typ, f, lockGetProp)
714}
715
716var (
717 propertiesMu sync.RWMutex
718 propertiesMap = make(map[reflect.Type]*StructProperties)
719)
720
721// GetProperties returns the list of properties for the type represented by t.
722// t must represent a generated struct type of a protocol message.
723func GetProperties(t reflect.Type) *StructProperties {
724 if t.Kind() != reflect.Struct {
725 panic("proto: type must have kind struct")
726 }
727
728 // Most calls to GetProperties in a long-running program will be
729 // retrieving details for types we have seen before.
730 propertiesMu.RLock()
731 sprop, ok := propertiesMap[t]
732 propertiesMu.RUnlock()
733 if ok {
734 if collectStats {
735 stats.Chit++
736 }
737 return sprop
738 }
739
740 propertiesMu.Lock()
741 sprop = getPropertiesLocked(t)
742 propertiesMu.Unlock()
743 return sprop
744}
745
746// getPropertiesLocked requires that propertiesMu is held.
747func getPropertiesLocked(t reflect.Type) *StructProperties {
748 if prop, ok := propertiesMap[t]; ok {
749 if collectStats {
750 stats.Chit++
751 }
752 return prop
753 }
754 if collectStats {
755 stats.Cmiss++
756 }
757
758 prop := new(StructProperties)
759 // in case of recursive protos, fill this in now.
760 propertiesMap[t] = prop
761
762 // build properties
763 prop.extendable = reflect.PtrTo(t).Implements(extendableProtoType) ||
764 reflect.PtrTo(t).Implements(extendableProtoV1Type) ||
765 reflect.PtrTo(t).Implements(extendableBytesType)
766 prop.unrecField = invalidField
767 prop.Prop = make([]*Properties, t.NumField())
768 prop.order = make([]int, t.NumField())
769
770 isOneofMessage := false
771 for i := 0; i < t.NumField(); i++ {
772 f := t.Field(i)
773 p := new(Properties)
774 name := f.Name
775 p.init(f.Type, name, f.Tag.Get("protobuf"), &f, false)
776
777 if f.Name == "XXX_InternalExtensions" { // special case
778 p.enc = (*Buffer).enc_exts
779 p.dec = nil // not needed
780 p.size = size_exts
781 } else if f.Name == "XXX_extensions" { // special case
782 if len(f.Tag.Get("protobuf")) > 0 {
783 p.enc = (*Buffer).enc_ext_slice_byte
784 p.dec = nil // not needed
785 p.size = size_ext_slice_byte
786 } else {
787 p.enc = (*Buffer).enc_map
788 p.dec = nil // not needed
789 p.size = size_map
790 }
791 } else if f.Name == "XXX_unrecognized" { // special case
792 prop.unrecField = toField(&f)
793 }
794 oneof := f.Tag.Get("protobuf_oneof") // special case
795 if oneof != "" {
796 isOneofMessage = true
797 // Oneof fields don't use the traditional protobuf tag.
798 p.OrigName = oneof
799 }
800 prop.Prop[i] = p
801 prop.order[i] = i
802 if debug {
803 print(i, " ", f.Name, " ", t.String(), " ")
804 if p.Tag > 0 {
805 print(p.String())
806 }
807 print("\n")
808 }
809 if p.enc == nil && !strings.HasPrefix(f.Name, "XXX_") && oneof == "" {
810 fmt.Fprintln(os.Stderr, "proto: no encoder for", f.Name, f.Type.String(), "[GetProperties]")
811 }
812 }
813
814 // Re-order prop.order.
815 sort.Sort(prop)
816
817 type oneofMessage interface {
818 XXX_OneofFuncs() (func(Message, *Buffer) error, func(Message, int, int, *Buffer) (bool, error), func(Message) int, []interface{})
819 }
820 if om, ok := reflect.Zero(reflect.PtrTo(t)).Interface().(oneofMessage); isOneofMessage && ok {
821 var oots []interface{}
822 prop.oneofMarshaler, prop.oneofUnmarshaler, prop.oneofSizer, oots = om.XXX_OneofFuncs()
823 prop.stype = t
824
825 // Interpret oneof metadata.
826 prop.OneofTypes = make(map[string]*OneofProperties)
827 for _, oot := range oots {
828 oop := &OneofProperties{
829 Type: reflect.ValueOf(oot).Type(), // *T
830 Prop: new(Properties),
831 }
832 sft := oop.Type.Elem().Field(0)
833 oop.Prop.Name = sft.Name
834 oop.Prop.Parse(sft.Tag.Get("protobuf"))
835 // There will be exactly one interface field that
836 // this new value is assignable to.
837 for i := 0; i < t.NumField(); i++ {
838 f := t.Field(i)
839 if f.Type.Kind() != reflect.Interface {
840 continue
841 }
842 if !oop.Type.AssignableTo(f.Type) {
843 continue
844 }
845 oop.Field = i
846 break
847 }
848 prop.OneofTypes[oop.Prop.OrigName] = oop
849 }
850 }
851
852 // build required counts
853 // build tags
854 reqCount := 0
855 prop.decoderOrigNames = make(map[string]int)
856 for i, p := range prop.Prop {
857 if strings.HasPrefix(p.Name, "XXX_") {
858 // Internal fields should not appear in tags/origNames maps.
859 // They are handled specially when encoding and decoding.
860 continue
861 }
862 if p.Required {
863 reqCount++
864 }
865 prop.decoderTags.put(p.Tag, i)
866 prop.decoderOrigNames[p.OrigName] = i
867 }
868 prop.reqCount = reqCount
869
870 return prop
871}
872
873// Return the Properties object for the x[0]'th field of the structure.
874func propByIndex(t reflect.Type, x []int) *Properties {
875 if len(x) != 1 {
876 fmt.Fprintf(os.Stderr, "proto: field index dimension %d (not 1) for type %s\n", len(x), t)
877 return nil
878 }
879 prop := GetProperties(t)
880 return prop.Prop[x[0]]
881}
882
883// Get the address and type of a pointer to a struct from an interface.
884func getbase(pb Message) (t reflect.Type, b structPointer, err error) {
885 if pb == nil {
886 err = ErrNil
887 return
888 }
889 // get the reflect type of the pointer to the struct.
890 t = reflect.TypeOf(pb)
891 // get the address of the struct.
892 value := reflect.ValueOf(pb)
893 b = toStructPointer(value)
894 return
895}
896
897// A global registry of enum types.
898// The generated code will register the generated maps by calling RegisterEnum.
899
900var enumValueMaps = make(map[string]map[string]int32)
901var enumStringMaps = make(map[string]map[int32]string)
902
903// RegisterEnum is called from the generated code to install the enum descriptor
904// maps into the global table to aid parsing text format protocol buffers.
905func RegisterEnum(typeName string, unusedNameMap map[int32]string, valueMap map[string]int32) {
906 if _, ok := enumValueMaps[typeName]; ok {
907 panic("proto: duplicate enum registered: " + typeName)
908 }
909 enumValueMaps[typeName] = valueMap
910 if _, ok := enumStringMaps[typeName]; ok {
911 panic("proto: duplicate enum registered: " + typeName)
912 }
913 enumStringMaps[typeName] = unusedNameMap
914}
915
916// EnumValueMap returns the mapping from names to integers of the
917// enum type enumType, or a nil if not found.
918func EnumValueMap(enumType string) map[string]int32 {
919 return enumValueMaps[enumType]
920}
921
922// A registry of all linked message types.
923// The string is a fully-qualified proto name ("pkg.Message").
924var (
925 protoTypes = make(map[string]reflect.Type)
926 revProtoTypes = make(map[reflect.Type]string)
927)
928
929// RegisterType is called from generated code and maps from the fully qualified
930// proto name to the type (pointer to struct) of the protocol buffer.
931func RegisterType(x Message, name string) {
932 if _, ok := protoTypes[name]; ok {
933 // TODO: Some day, make this a panic.
934 log.Printf("proto: duplicate proto type registered: %s", name)
935 return
936 }
937 t := reflect.TypeOf(x)
938 protoTypes[name] = t
939 revProtoTypes[t] = name
940}
941
942// MessageName returns the fully-qualified proto name for the given message type.
943func MessageName(x Message) string {
944 type xname interface {
945 XXX_MessageName() string
946 }
947 if m, ok := x.(xname); ok {
948 return m.XXX_MessageName()
949 }
950 return revProtoTypes[reflect.TypeOf(x)]
951}
952
953// MessageType returns the message type (pointer to struct) for a named message.
954func MessageType(name string) reflect.Type { return protoTypes[name] }
955
956// A registry of all linked proto files.
957var (
958 protoFiles = make(map[string][]byte) // file name => fileDescriptor
959)
960
961// RegisterFile is called from generated code and maps from the
962// full file name of a .proto file to its compressed FileDescriptorProto.
963func RegisterFile(filename string, fileDescriptor []byte) {
964 protoFiles[filename] = fileDescriptor
965}
966
967// FileDescriptor returns the compressed FileDescriptorProto for a .proto file.
968func FileDescriptor(filename string) []byte { return protoFiles[filename] }