blob: 2a69e8862d56483a9e5659c23463ce796351fcaa [file] [log] [blame]
Matthias Andreas Benkard832a54e2019-01-29 09:27:38 +01001// 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 CastType string
197 StdTime bool
198 StdDuration bool
199
200 enc encoder
201 valEnc valueEncoder // set for bool and numeric types only
202 field field
203 tagcode []byte // encoding of EncodeVarint((Tag<<3)|WireType)
204 tagbuf [8]byte
205 stype reflect.Type // set for struct types only
206 sstype reflect.Type // set for slices of structs types only
207 ctype reflect.Type // set for custom types only
208 sprop *StructProperties // set for struct types only
209 isMarshaler bool
210 isUnmarshaler bool
211
212 mtype reflect.Type // set for map types only
213 mkeyprop *Properties // set for map types only
214 mvalprop *Properties // set for map types only
215
216 size sizer
217 valSize valueSizer // set for bool and numeric types only
218
219 dec decoder
220 valDec valueDecoder // set for bool and numeric types only
221
222 // If this is a packable field, this will be the decoder for the packed version of the field.
223 packedDec decoder
224}
225
226// String formats the properties in the protobuf struct field tag style.
227func (p *Properties) String() string {
228 s := p.Wire
229 s = ","
230 s += strconv.Itoa(p.Tag)
231 if p.Required {
232 s += ",req"
233 }
234 if p.Optional {
235 s += ",opt"
236 }
237 if p.Repeated {
238 s += ",rep"
239 }
240 if p.Packed {
241 s += ",packed"
242 }
243 s += ",name=" + p.OrigName
244 if p.JSONName != p.OrigName {
245 s += ",json=" + p.JSONName
246 }
247 if p.proto3 {
248 s += ",proto3"
249 }
250 if p.oneof {
251 s += ",oneof"
252 }
253 if len(p.Enum) > 0 {
254 s += ",enum=" + p.Enum
255 }
256 if p.HasDefault {
257 s += ",def=" + p.Default
258 }
259 return s
260}
261
262// Parse populates p by parsing a string in the protobuf struct field tag style.
263func (p *Properties) Parse(s string) {
264 // "bytes,49,opt,name=foo,def=hello!"
265 fields := strings.Split(s, ",") // breaks def=, but handled below.
266 if len(fields) < 2 {
267 fmt.Fprintf(os.Stderr, "proto: tag has too few fields: %q\n", s)
268 return
269 }
270
271 p.Wire = fields[0]
272 switch p.Wire {
273 case "varint":
274 p.WireType = WireVarint
275 p.valEnc = (*Buffer).EncodeVarint
276 p.valDec = (*Buffer).DecodeVarint
277 p.valSize = sizeVarint
278 case "fixed32":
279 p.WireType = WireFixed32
280 p.valEnc = (*Buffer).EncodeFixed32
281 p.valDec = (*Buffer).DecodeFixed32
282 p.valSize = sizeFixed32
283 case "fixed64":
284 p.WireType = WireFixed64
285 p.valEnc = (*Buffer).EncodeFixed64
286 p.valDec = (*Buffer).DecodeFixed64
287 p.valSize = sizeFixed64
288 case "zigzag32":
289 p.WireType = WireVarint
290 p.valEnc = (*Buffer).EncodeZigzag32
291 p.valDec = (*Buffer).DecodeZigzag32
292 p.valSize = sizeZigzag32
293 case "zigzag64":
294 p.WireType = WireVarint
295 p.valEnc = (*Buffer).EncodeZigzag64
296 p.valDec = (*Buffer).DecodeZigzag64
297 p.valSize = sizeZigzag64
298 case "bytes", "group":
299 p.WireType = WireBytes
300 // no numeric converter for non-numeric types
301 default:
302 fmt.Fprintf(os.Stderr, "proto: tag has unknown wire type: %q\n", s)
303 return
304 }
305
306 var err error
307 p.Tag, err = strconv.Atoi(fields[1])
308 if err != nil {
309 return
310 }
311
312 for i := 2; i < len(fields); i++ {
313 f := fields[i]
314 switch {
315 case f == "req":
316 p.Required = true
317 case f == "opt":
318 p.Optional = true
319 case f == "rep":
320 p.Repeated = true
321 case f == "packed":
322 p.Packed = true
323 case strings.HasPrefix(f, "name="):
324 p.OrigName = f[5:]
325 case strings.HasPrefix(f, "json="):
326 p.JSONName = f[5:]
327 case strings.HasPrefix(f, "enum="):
328 p.Enum = f[5:]
329 case f == "proto3":
330 p.proto3 = true
331 case f == "oneof":
332 p.oneof = true
333 case strings.HasPrefix(f, "def="):
334 p.HasDefault = true
335 p.Default = f[4:] // rest of string
336 if i+1 < len(fields) {
337 // Commas aren't escaped, and def is always last.
338 p.Default += "," + strings.Join(fields[i+1:], ",")
339 break
340 }
341 case strings.HasPrefix(f, "embedded="):
342 p.OrigName = strings.Split(f, "=")[1]
343 case strings.HasPrefix(f, "customtype="):
344 p.CustomType = strings.Split(f, "=")[1]
345 case strings.HasPrefix(f, "casttype="):
346 p.CastType = strings.Split(f, "=")[1]
347 case f == "stdtime":
348 p.StdTime = true
349 case f == "stdduration":
350 p.StdDuration = true
351 }
352 }
353}
354
355func logNoSliceEnc(t1, t2 reflect.Type) {
356 fmt.Fprintf(os.Stderr, "proto: no slice oenc for %T = []%T\n", t1, t2)
357}
358
359var protoMessageType = reflect.TypeOf((*Message)(nil)).Elem()
360
361// Initialize the fields for encoding and decoding.
362func (p *Properties) setEncAndDec(typ reflect.Type, f *reflect.StructField, lockGetProp bool) {
363 p.enc = nil
364 p.dec = nil
365 p.size = nil
366 isMap := typ.Kind() == reflect.Map
367 if len(p.CustomType) > 0 && !isMap {
368 p.setCustomEncAndDec(typ)
369 p.setTag(lockGetProp)
370 return
371 }
372 if p.StdTime && !isMap {
373 p.setTimeEncAndDec(typ)
374 p.setTag(lockGetProp)
375 return
376 }
377 if p.StdDuration && !isMap {
378 p.setDurationEncAndDec(typ)
379 p.setTag(lockGetProp)
380 return
381 }
382 switch t1 := typ; t1.Kind() {
383 default:
384 fmt.Fprintf(os.Stderr, "proto: no coders for %v\n", t1)
385
386 // proto3 scalar types
387
388 case reflect.Bool:
389 if p.proto3 {
390 p.enc = (*Buffer).enc_proto3_bool
391 p.dec = (*Buffer).dec_proto3_bool
392 p.size = size_proto3_bool
393 } else {
394 p.enc = (*Buffer).enc_ref_bool
395 p.dec = (*Buffer).dec_proto3_bool
396 p.size = size_ref_bool
397 }
398 case reflect.Int32:
399 if p.proto3 {
400 p.enc = (*Buffer).enc_proto3_int32
401 p.dec = (*Buffer).dec_proto3_int32
402 p.size = size_proto3_int32
403 } else {
404 p.enc = (*Buffer).enc_ref_int32
405 p.dec = (*Buffer).dec_proto3_int32
406 p.size = size_ref_int32
407 }
408 case reflect.Uint32:
409 if p.proto3 {
410 p.enc = (*Buffer).enc_proto3_uint32
411 p.dec = (*Buffer).dec_proto3_int32 // can reuse
412 p.size = size_proto3_uint32
413 } else {
414 p.enc = (*Buffer).enc_ref_uint32
415 p.dec = (*Buffer).dec_proto3_int32 // can reuse
416 p.size = size_ref_uint32
417 }
418 case reflect.Int64, reflect.Uint64:
419 if p.proto3 {
420 p.enc = (*Buffer).enc_proto3_int64
421 p.dec = (*Buffer).dec_proto3_int64
422 p.size = size_proto3_int64
423 } else {
424 p.enc = (*Buffer).enc_ref_int64
425 p.dec = (*Buffer).dec_proto3_int64
426 p.size = size_ref_int64
427 }
428 case reflect.Float32:
429 if p.proto3 {
430 p.enc = (*Buffer).enc_proto3_uint32 // can just treat them as bits
431 p.dec = (*Buffer).dec_proto3_int32
432 p.size = size_proto3_uint32
433 } else {
434 p.enc = (*Buffer).enc_ref_uint32 // can just treat them as bits
435 p.dec = (*Buffer).dec_proto3_int32
436 p.size = size_ref_uint32
437 }
438 case reflect.Float64:
439 if p.proto3 {
440 p.enc = (*Buffer).enc_proto3_int64 // can just treat them as bits
441 p.dec = (*Buffer).dec_proto3_int64
442 p.size = size_proto3_int64
443 } else {
444 p.enc = (*Buffer).enc_ref_int64 // can just treat them as bits
445 p.dec = (*Buffer).dec_proto3_int64
446 p.size = size_ref_int64
447 }
448 case reflect.String:
449 if p.proto3 {
450 p.enc = (*Buffer).enc_proto3_string
451 p.dec = (*Buffer).dec_proto3_string
452 p.size = size_proto3_string
453 } else {
454 p.enc = (*Buffer).enc_ref_string
455 p.dec = (*Buffer).dec_proto3_string
456 p.size = size_ref_string
457 }
458 case reflect.Struct:
459 p.stype = typ
460 p.isMarshaler = isMarshaler(typ)
461 p.isUnmarshaler = isUnmarshaler(typ)
462 if p.Wire == "bytes" {
463 p.enc = (*Buffer).enc_ref_struct_message
464 p.dec = (*Buffer).dec_ref_struct_message
465 p.size = size_ref_struct_message
466 } else {
467 fmt.Fprintf(os.Stderr, "proto: no coders for struct %T\n", typ)
468 }
469
470 case reflect.Ptr:
471 switch t2 := t1.Elem(); t2.Kind() {
472 default:
473 fmt.Fprintf(os.Stderr, "proto: no encoder function for %v -> %v\n", t1, t2)
474 break
475 case reflect.Bool:
476 p.enc = (*Buffer).enc_bool
477 p.dec = (*Buffer).dec_bool
478 p.size = size_bool
479 case reflect.Int32:
480 p.enc = (*Buffer).enc_int32
481 p.dec = (*Buffer).dec_int32
482 p.size = size_int32
483 case reflect.Uint32:
484 p.enc = (*Buffer).enc_uint32
485 p.dec = (*Buffer).dec_int32 // can reuse
486 p.size = size_uint32
487 case reflect.Int64, reflect.Uint64:
488 p.enc = (*Buffer).enc_int64
489 p.dec = (*Buffer).dec_int64
490 p.size = size_int64
491 case reflect.Float32:
492 p.enc = (*Buffer).enc_uint32 // can just treat them as bits
493 p.dec = (*Buffer).dec_int32
494 p.size = size_uint32
495 case reflect.Float64:
496 p.enc = (*Buffer).enc_int64 // can just treat them as bits
497 p.dec = (*Buffer).dec_int64
498 p.size = size_int64
499 case reflect.String:
500 p.enc = (*Buffer).enc_string
501 p.dec = (*Buffer).dec_string
502 p.size = size_string
503 case reflect.Struct:
504 p.stype = t1.Elem()
505 p.isMarshaler = isMarshaler(t1)
506 p.isUnmarshaler = isUnmarshaler(t1)
507 if p.Wire == "bytes" {
508 p.enc = (*Buffer).enc_struct_message
509 p.dec = (*Buffer).dec_struct_message
510 p.size = size_struct_message
511 } else {
512 p.enc = (*Buffer).enc_struct_group
513 p.dec = (*Buffer).dec_struct_group
514 p.size = size_struct_group
515 }
516 }
517
518 case reflect.Slice:
519 switch t2 := t1.Elem(); t2.Kind() {
520 default:
521 logNoSliceEnc(t1, t2)
522 break
523 case reflect.Bool:
524 if p.Packed {
525 p.enc = (*Buffer).enc_slice_packed_bool
526 p.size = size_slice_packed_bool
527 } else {
528 p.enc = (*Buffer).enc_slice_bool
529 p.size = size_slice_bool
530 }
531 p.dec = (*Buffer).dec_slice_bool
532 p.packedDec = (*Buffer).dec_slice_packed_bool
533 case reflect.Int32:
534 if p.Packed {
535 p.enc = (*Buffer).enc_slice_packed_int32
536 p.size = size_slice_packed_int32
537 } else {
538 p.enc = (*Buffer).enc_slice_int32
539 p.size = size_slice_int32
540 }
541 p.dec = (*Buffer).dec_slice_int32
542 p.packedDec = (*Buffer).dec_slice_packed_int32
543 case reflect.Uint32:
544 if p.Packed {
545 p.enc = (*Buffer).enc_slice_packed_uint32
546 p.size = size_slice_packed_uint32
547 } else {
548 p.enc = (*Buffer).enc_slice_uint32
549 p.size = size_slice_uint32
550 }
551 p.dec = (*Buffer).dec_slice_int32
552 p.packedDec = (*Buffer).dec_slice_packed_int32
553 case reflect.Int64, reflect.Uint64:
554 if p.Packed {
555 p.enc = (*Buffer).enc_slice_packed_int64
556 p.size = size_slice_packed_int64
557 } else {
558 p.enc = (*Buffer).enc_slice_int64
559 p.size = size_slice_int64
560 }
561 p.dec = (*Buffer).dec_slice_int64
562 p.packedDec = (*Buffer).dec_slice_packed_int64
563 case reflect.Uint8:
564 p.dec = (*Buffer).dec_slice_byte
565 if p.proto3 {
566 p.enc = (*Buffer).enc_proto3_slice_byte
567 p.size = size_proto3_slice_byte
568 } else {
569 p.enc = (*Buffer).enc_slice_byte
570 p.size = size_slice_byte
571 }
572 case reflect.Float32, reflect.Float64:
573 switch t2.Bits() {
574 case 32:
575 // can just treat them as bits
576 if p.Packed {
577 p.enc = (*Buffer).enc_slice_packed_uint32
578 p.size = size_slice_packed_uint32
579 } else {
580 p.enc = (*Buffer).enc_slice_uint32
581 p.size = size_slice_uint32
582 }
583 p.dec = (*Buffer).dec_slice_int32
584 p.packedDec = (*Buffer).dec_slice_packed_int32
585 case 64:
586 // can just treat them as bits
587 if p.Packed {
588 p.enc = (*Buffer).enc_slice_packed_int64
589 p.size = size_slice_packed_int64
590 } else {
591 p.enc = (*Buffer).enc_slice_int64
592 p.size = size_slice_int64
593 }
594 p.dec = (*Buffer).dec_slice_int64
595 p.packedDec = (*Buffer).dec_slice_packed_int64
596 default:
597 logNoSliceEnc(t1, t2)
598 break
599 }
600 case reflect.String:
601 p.enc = (*Buffer).enc_slice_string
602 p.dec = (*Buffer).dec_slice_string
603 p.size = size_slice_string
604 case reflect.Ptr:
605 switch t3 := t2.Elem(); t3.Kind() {
606 default:
607 fmt.Fprintf(os.Stderr, "proto: no ptr oenc for %T -> %T -> %T\n", t1, t2, t3)
608 break
609 case reflect.Struct:
610 p.stype = t2.Elem()
611 p.isMarshaler = isMarshaler(t2)
612 p.isUnmarshaler = isUnmarshaler(t2)
613 if p.Wire == "bytes" {
614 p.enc = (*Buffer).enc_slice_struct_message
615 p.dec = (*Buffer).dec_slice_struct_message
616 p.size = size_slice_struct_message
617 } else {
618 p.enc = (*Buffer).enc_slice_struct_group
619 p.dec = (*Buffer).dec_slice_struct_group
620 p.size = size_slice_struct_group
621 }
622 }
623 case reflect.Slice:
624 switch t2.Elem().Kind() {
625 default:
626 fmt.Fprintf(os.Stderr, "proto: no slice elem oenc for %T -> %T -> %T\n", t1, t2, t2.Elem())
627 break
628 case reflect.Uint8:
629 p.enc = (*Buffer).enc_slice_slice_byte
630 p.dec = (*Buffer).dec_slice_slice_byte
631 p.size = size_slice_slice_byte
632 }
633 case reflect.Struct:
634 p.setSliceOfNonPointerStructs(t1)
635 }
636
637 case reflect.Map:
638 p.enc = (*Buffer).enc_new_map
639 p.dec = (*Buffer).dec_new_map
640 p.size = size_new_map
641
642 p.mtype = t1
643 p.mkeyprop = &Properties{}
644 p.mkeyprop.init(reflect.PtrTo(p.mtype.Key()), "Key", f.Tag.Get("protobuf_key"), nil, lockGetProp)
645 p.mvalprop = &Properties{}
646 vtype := p.mtype.Elem()
647 if vtype.Kind() != reflect.Ptr && vtype.Kind() != reflect.Slice {
648 // The value type is not a message (*T) or bytes ([]byte),
649 // so we need encoders for the pointer to this type.
650 vtype = reflect.PtrTo(vtype)
651 }
652
653 p.mvalprop.CustomType = p.CustomType
654 p.mvalprop.StdDuration = p.StdDuration
655 p.mvalprop.StdTime = p.StdTime
656 p.mvalprop.init(vtype, "Value", f.Tag.Get("protobuf_val"), nil, lockGetProp)
657 }
658 p.setTag(lockGetProp)
659}
660
661func (p *Properties) setTag(lockGetProp bool) {
662 // precalculate tag code
663 wire := p.WireType
664 if p.Packed {
665 wire = WireBytes
666 }
667 x := uint32(p.Tag)<<3 | uint32(wire)
668 i := 0
669 for i = 0; x > 127; i++ {
670 p.tagbuf[i] = 0x80 | uint8(x&0x7F)
671 x >>= 7
672 }
673 p.tagbuf[i] = uint8(x)
674 p.tagcode = p.tagbuf[0 : i+1]
675
676 if p.stype != nil {
677 if lockGetProp {
678 p.sprop = GetProperties(p.stype)
679 } else {
680 p.sprop = getPropertiesLocked(p.stype)
681 }
682 }
683}
684
685var (
686 marshalerType = reflect.TypeOf((*Marshaler)(nil)).Elem()
687 unmarshalerType = reflect.TypeOf((*Unmarshaler)(nil)).Elem()
688)
689
690// isMarshaler reports whether type t implements Marshaler.
691func isMarshaler(t reflect.Type) bool {
692 return t.Implements(marshalerType)
693}
694
695// isUnmarshaler reports whether type t implements Unmarshaler.
696func isUnmarshaler(t reflect.Type) bool {
697 return t.Implements(unmarshalerType)
698}
699
700// Init populates the properties from a protocol buffer struct tag.
701func (p *Properties) Init(typ reflect.Type, name, tag string, f *reflect.StructField) {
702 p.init(typ, name, tag, f, true)
703}
704
705func (p *Properties) init(typ reflect.Type, name, tag string, f *reflect.StructField, lockGetProp bool) {
706 // "bytes,49,opt,def=hello!"
707 p.Name = name
708 p.OrigName = name
709 if f != nil {
710 p.field = toField(f)
711 }
712 if tag == "" {
713 return
714 }
715 p.Parse(tag)
716 p.setEncAndDec(typ, f, lockGetProp)
717}
718
719var (
720 propertiesMu sync.RWMutex
721 propertiesMap = make(map[reflect.Type]*StructProperties)
722)
723
724// GetProperties returns the list of properties for the type represented by t.
725// t must represent a generated struct type of a protocol message.
726func GetProperties(t reflect.Type) *StructProperties {
727 if t.Kind() != reflect.Struct {
728 panic("proto: type must have kind struct")
729 }
730
731 // Most calls to GetProperties in a long-running program will be
732 // retrieving details for types we have seen before.
733 propertiesMu.RLock()
734 sprop, ok := propertiesMap[t]
735 propertiesMu.RUnlock()
736 if ok {
737 if collectStats {
738 stats.Chit++
739 }
740 return sprop
741 }
742
743 propertiesMu.Lock()
744 sprop = getPropertiesLocked(t)
745 propertiesMu.Unlock()
746 return sprop
747}
748
749// getPropertiesLocked requires that propertiesMu is held.
750func getPropertiesLocked(t reflect.Type) *StructProperties {
751 if prop, ok := propertiesMap[t]; ok {
752 if collectStats {
753 stats.Chit++
754 }
755 return prop
756 }
757 if collectStats {
758 stats.Cmiss++
759 }
760
761 prop := new(StructProperties)
762 // in case of recursive protos, fill this in now.
763 propertiesMap[t] = prop
764
765 // build properties
766 prop.extendable = reflect.PtrTo(t).Implements(extendableProtoType) ||
767 reflect.PtrTo(t).Implements(extendableProtoV1Type) ||
768 reflect.PtrTo(t).Implements(extendableBytesType)
769 prop.unrecField = invalidField
770 prop.Prop = make([]*Properties, t.NumField())
771 prop.order = make([]int, t.NumField())
772
773 isOneofMessage := false
774 for i := 0; i < t.NumField(); i++ {
775 f := t.Field(i)
776 p := new(Properties)
777 name := f.Name
778 p.init(f.Type, name, f.Tag.Get("protobuf"), &f, false)
779
780 if f.Name == "XXX_InternalExtensions" { // special case
781 p.enc = (*Buffer).enc_exts
782 p.dec = nil // not needed
783 p.size = size_exts
784 } else if f.Name == "XXX_extensions" { // special case
785 if len(f.Tag.Get("protobuf")) > 0 {
786 p.enc = (*Buffer).enc_ext_slice_byte
787 p.dec = nil // not needed
788 p.size = size_ext_slice_byte
789 } else {
790 p.enc = (*Buffer).enc_map
791 p.dec = nil // not needed
792 p.size = size_map
793 }
794 } else if f.Name == "XXX_unrecognized" { // special case
795 prop.unrecField = toField(&f)
796 }
797 oneof := f.Tag.Get("protobuf_oneof") // special case
798 if oneof != "" {
799 isOneofMessage = true
800 // Oneof fields don't use the traditional protobuf tag.
801 p.OrigName = oneof
802 }
803 prop.Prop[i] = p
804 prop.order[i] = i
805 if debug {
806 print(i, " ", f.Name, " ", t.String(), " ")
807 if p.Tag > 0 {
808 print(p.String())
809 }
810 print("\n")
811 }
812 if p.enc == nil && !strings.HasPrefix(f.Name, "XXX_") && oneof == "" {
813 fmt.Fprintln(os.Stderr, "proto: no encoder for", f.Name, f.Type.String(), "[GetProperties]")
814 }
815 }
816
817 // Re-order prop.order.
818 sort.Sort(prop)
819
820 type oneofMessage interface {
821 XXX_OneofFuncs() (func(Message, *Buffer) error, func(Message, int, int, *Buffer) (bool, error), func(Message) int, []interface{})
822 }
823 if om, ok := reflect.Zero(reflect.PtrTo(t)).Interface().(oneofMessage); isOneofMessage && ok {
824 var oots []interface{}
825 prop.oneofMarshaler, prop.oneofUnmarshaler, prop.oneofSizer, oots = om.XXX_OneofFuncs()
826 prop.stype = t
827
828 // Interpret oneof metadata.
829 prop.OneofTypes = make(map[string]*OneofProperties)
830 for _, oot := range oots {
831 oop := &OneofProperties{
832 Type: reflect.ValueOf(oot).Type(), // *T
833 Prop: new(Properties),
834 }
835 sft := oop.Type.Elem().Field(0)
836 oop.Prop.Name = sft.Name
837 oop.Prop.Parse(sft.Tag.Get("protobuf"))
838 // There will be exactly one interface field that
839 // this new value is assignable to.
840 for i := 0; i < t.NumField(); i++ {
841 f := t.Field(i)
842 if f.Type.Kind() != reflect.Interface {
843 continue
844 }
845 if !oop.Type.AssignableTo(f.Type) {
846 continue
847 }
848 oop.Field = i
849 break
850 }
851 prop.OneofTypes[oop.Prop.OrigName] = oop
852 }
853 }
854
855 // build required counts
856 // build tags
857 reqCount := 0
858 prop.decoderOrigNames = make(map[string]int)
859 for i, p := range prop.Prop {
860 if strings.HasPrefix(p.Name, "XXX_") {
861 // Internal fields should not appear in tags/origNames maps.
862 // They are handled specially when encoding and decoding.
863 continue
864 }
865 if p.Required {
866 reqCount++
867 }
868 prop.decoderTags.put(p.Tag, i)
869 prop.decoderOrigNames[p.OrigName] = i
870 }
871 prop.reqCount = reqCount
872
873 return prop
874}
875
876// Return the Properties object for the x[0]'th field of the structure.
877func propByIndex(t reflect.Type, x []int) *Properties {
878 if len(x) != 1 {
879 fmt.Fprintf(os.Stderr, "proto: field index dimension %d (not 1) for type %s\n", len(x), t)
880 return nil
881 }
882 prop := GetProperties(t)
883 return prop.Prop[x[0]]
884}
885
886// Get the address and type of a pointer to a struct from an interface.
887func getbase(pb Message) (t reflect.Type, b structPointer, err error) {
888 if pb == nil {
889 err = ErrNil
890 return
891 }
892 // get the reflect type of the pointer to the struct.
893 t = reflect.TypeOf(pb)
894 // get the address of the struct.
895 value := reflect.ValueOf(pb)
896 b = toStructPointer(value)
897 return
898}
899
900// A global registry of enum types.
901// The generated code will register the generated maps by calling RegisterEnum.
902
903var enumValueMaps = make(map[string]map[string]int32)
904var enumStringMaps = make(map[string]map[int32]string)
905
906// RegisterEnum is called from the generated code to install the enum descriptor
907// maps into the global table to aid parsing text format protocol buffers.
908func RegisterEnum(typeName string, unusedNameMap map[int32]string, valueMap map[string]int32) {
909 if _, ok := enumValueMaps[typeName]; ok {
910 panic("proto: duplicate enum registered: " + typeName)
911 }
912 enumValueMaps[typeName] = valueMap
913 if _, ok := enumStringMaps[typeName]; ok {
914 panic("proto: duplicate enum registered: " + typeName)
915 }
916 enumStringMaps[typeName] = unusedNameMap
917}
918
919// EnumValueMap returns the mapping from names to integers of the
920// enum type enumType, or a nil if not found.
921func EnumValueMap(enumType string) map[string]int32 {
922 return enumValueMaps[enumType]
923}
924
925// A registry of all linked message types.
926// The string is a fully-qualified proto name ("pkg.Message").
927var (
928 protoTypes = make(map[string]reflect.Type)
929 revProtoTypes = make(map[reflect.Type]string)
930)
931
932// RegisterType is called from generated code and maps from the fully qualified
933// proto name to the type (pointer to struct) of the protocol buffer.
934func RegisterType(x Message, name string) {
935 if _, ok := protoTypes[name]; ok {
936 // TODO: Some day, make this a panic.
937 log.Printf("proto: duplicate proto type registered: %s", name)
938 return
939 }
940 t := reflect.TypeOf(x)
941 protoTypes[name] = t
942 revProtoTypes[t] = name
943}
944
945// MessageName returns the fully-qualified proto name for the given message type.
946func MessageName(x Message) string {
947 type xname interface {
948 XXX_MessageName() string
949 }
950 if m, ok := x.(xname); ok {
951 return m.XXX_MessageName()
952 }
953 return revProtoTypes[reflect.TypeOf(x)]
954}
955
956// MessageType returns the message type (pointer to struct) for a named message.
957func MessageType(name string) reflect.Type { return protoTypes[name] }
958
959// A registry of all linked proto files.
960var (
961 protoFiles = make(map[string][]byte) // file name => fileDescriptor
962)
963
964// RegisterFile is called from generated code and maps from the
965// full file name of a .proto file to its compressed FileDescriptorProto.
966func RegisterFile(filename string, fileDescriptor []byte) {
967 protoFiles[filename] = fileDescriptor
968}
969
970// FileDescriptor returns the compressed FileDescriptorProto for a .proto file.
971func FileDescriptor(filename string) []byte { return protoFiles[filename] }