OSDN Git Service

Merge pull request #31 from Bytom/dev_ipfs_transaction
[bytom/vapor.git] / vendor / github.com / gogo / protobuf / proto / properties.go
1 // 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
37 package proto
38
39 /*
40  * Routines for encoding data into the wire format for protocol buffers.
41  */
42
43 import (
44         "fmt"
45         "log"
46         "os"
47         "reflect"
48         "sort"
49         "strconv"
50         "strings"
51         "sync"
52 )
53
54 const debug bool = false
55
56 // Constants that identify the encoding of a value on the wire.
57 const (
58         WireVarint     = 0
59         WireFixed64    = 1
60         WireBytes      = 2
61         WireStartGroup = 3
62         WireEndGroup   = 4
63         WireFixed32    = 5
64 )
65
66 // tagMap is an optimization over map[int]int for typical protocol buffer
67 // use-cases. Encoded protocol buffers are often in tag order with small tag
68 // numbers.
69 type tagMap struct {
70         fastTags []int
71         slowTags map[int]int
72 }
73
74 // tagMapFastLimit is the upper bound on the tag number that will be stored in
75 // the tagMap slice rather than its map.
76 const tagMapFastLimit = 1024
77
78 func (p *tagMap) get(t int) (int, bool) {
79         if t > 0 && t < tagMapFastLimit {
80                 if t >= len(p.fastTags) {
81                         return 0, false
82                 }
83                 fi := p.fastTags[t]
84                 return fi, fi >= 0
85         }
86         fi, ok := p.slowTags[t]
87         return fi, ok
88 }
89
90 func (p *tagMap) put(t int, fi int) {
91         if t > 0 && t < tagMapFastLimit {
92                 for len(p.fastTags) < t+1 {
93                         p.fastTags = append(p.fastTags, -1)
94                 }
95                 p.fastTags[t] = fi
96                 return
97         }
98         if p.slowTags == nil {
99                 p.slowTags = make(map[int]int)
100         }
101         p.slowTags[t] = fi
102 }
103
104 // StructProperties represents properties for all the fields of a struct.
105 // decoderTags and decoderOrigNames should only be used by the decoder.
106 type StructProperties struct {
107         Prop             []*Properties  // properties for each field
108         reqCount         int            // required count
109         decoderTags      tagMap         // map from proto tag to struct field number
110         decoderOrigNames map[string]int // map from original name to struct field number
111         order            []int          // list of struct field numbers in tag order
112
113         // OneofTypes contains information about the oneof fields in this message.
114         // It is keyed by the original name of a field.
115         OneofTypes map[string]*OneofProperties
116 }
117
118 // OneofProperties represents information about a specific field in a oneof.
119 type OneofProperties struct {
120         Type  reflect.Type // pointer to generated struct type for this oneof field
121         Field int          // struct field number of the containing oneof in the message
122         Prop  *Properties
123 }
124
125 // Implement the sorting interface so we can sort the fields in tag order, as recommended by the spec.
126 // See encode.go, (*Buffer).enc_struct.
127
128 func (sp *StructProperties) Len() int { return len(sp.order) }
129 func (sp *StructProperties) Less(i, j int) bool {
130         return sp.Prop[sp.order[i]].Tag < sp.Prop[sp.order[j]].Tag
131 }
132 func (sp *StructProperties) Swap(i, j int) { sp.order[i], sp.order[j] = sp.order[j], sp.order[i] }
133
134 // Properties represents the protocol-specific behavior of a single struct field.
135 type Properties struct {
136         Name     string // name of the field, for error messages
137         OrigName string // original name before protocol compiler (always set)
138         JSONName string // name to use for JSON; determined by protoc
139         Wire     string
140         WireType int
141         Tag      int
142         Required bool
143         Optional bool
144         Repeated bool
145         Packed   bool   // relevant for repeated primitives only
146         Enum     string // set for enum types only
147         proto3   bool   // whether this is known to be a proto3 field
148         oneof    bool   // whether this is a oneof field
149
150         Default     string // default value
151         HasDefault  bool   // whether an explicit default was provided
152         CustomType  string
153         CastType    string
154         StdTime     bool
155         StdDuration bool
156         WktPointer  bool
157
158         stype reflect.Type      // set for struct types only
159         ctype reflect.Type      // set for custom types only
160         sprop *StructProperties // set for struct types only
161
162         mtype      reflect.Type // set for map types only
163         MapKeyProp *Properties  // set for map types only
164         MapValProp *Properties  // set for map types only
165 }
166
167 // String formats the properties in the protobuf struct field tag style.
168 func (p *Properties) String() string {
169         s := p.Wire
170         s += ","
171         s += strconv.Itoa(p.Tag)
172         if p.Required {
173                 s += ",req"
174         }
175         if p.Optional {
176                 s += ",opt"
177         }
178         if p.Repeated {
179                 s += ",rep"
180         }
181         if p.Packed {
182                 s += ",packed"
183         }
184         s += ",name=" + p.OrigName
185         if p.JSONName != p.OrigName {
186                 s += ",json=" + p.JSONName
187         }
188         if p.proto3 {
189                 s += ",proto3"
190         }
191         if p.oneof {
192                 s += ",oneof"
193         }
194         if len(p.Enum) > 0 {
195                 s += ",enum=" + p.Enum
196         }
197         if p.HasDefault {
198                 s += ",def=" + p.Default
199         }
200         return s
201 }
202
203 // Parse populates p by parsing a string in the protobuf struct field tag style.
204 func (p *Properties) Parse(s string) {
205         // "bytes,49,opt,name=foo,def=hello!"
206         fields := strings.Split(s, ",") // breaks def=, but handled below.
207         if len(fields) < 2 {
208                 fmt.Fprintf(os.Stderr, "proto: tag has too few fields: %q\n", s)
209                 return
210         }
211
212         p.Wire = fields[0]
213         switch p.Wire {
214         case "varint":
215                 p.WireType = WireVarint
216         case "fixed32":
217                 p.WireType = WireFixed32
218         case "fixed64":
219                 p.WireType = WireFixed64
220         case "zigzag32":
221                 p.WireType = WireVarint
222         case "zigzag64":
223                 p.WireType = WireVarint
224         case "bytes", "group":
225                 p.WireType = WireBytes
226                 // no numeric converter for non-numeric types
227         default:
228                 fmt.Fprintf(os.Stderr, "proto: tag has unknown wire type: %q\n", s)
229                 return
230         }
231
232         var err error
233         p.Tag, err = strconv.Atoi(fields[1])
234         if err != nil {
235                 return
236         }
237
238 outer:
239         for i := 2; i < len(fields); i++ {
240                 f := fields[i]
241                 switch {
242                 case f == "req":
243                         p.Required = true
244                 case f == "opt":
245                         p.Optional = true
246                 case f == "rep":
247                         p.Repeated = true
248                 case f == "packed":
249                         p.Packed = true
250                 case strings.HasPrefix(f, "name="):
251                         p.OrigName = f[5:]
252                 case strings.HasPrefix(f, "json="):
253                         p.JSONName = f[5:]
254                 case strings.HasPrefix(f, "enum="):
255                         p.Enum = f[5:]
256                 case f == "proto3":
257                         p.proto3 = true
258                 case f == "oneof":
259                         p.oneof = true
260                 case strings.HasPrefix(f, "def="):
261                         p.HasDefault = true
262                         p.Default = f[4:] // rest of string
263                         if i+1 < len(fields) {
264                                 // Commas aren't escaped, and def is always last.
265                                 p.Default += "," + strings.Join(fields[i+1:], ",")
266                                 break outer
267                         }
268                 case strings.HasPrefix(f, "embedded="):
269                         p.OrigName = strings.Split(f, "=")[1]
270                 case strings.HasPrefix(f, "customtype="):
271                         p.CustomType = strings.Split(f, "=")[1]
272                 case strings.HasPrefix(f, "casttype="):
273                         p.CastType = strings.Split(f, "=")[1]
274                 case f == "stdtime":
275                         p.StdTime = true
276                 case f == "stdduration":
277                         p.StdDuration = true
278                 case f == "wktptr":
279                         p.WktPointer = true
280                 }
281         }
282 }
283
284 var protoMessageType = reflect.TypeOf((*Message)(nil)).Elem()
285
286 // setFieldProps initializes the field properties for submessages and maps.
287 func (p *Properties) setFieldProps(typ reflect.Type, f *reflect.StructField, lockGetProp bool) {
288         isMap := typ.Kind() == reflect.Map
289         if len(p.CustomType) > 0 && !isMap {
290                 p.ctype = typ
291                 p.setTag(lockGetProp)
292                 return
293         }
294         if p.StdTime && !isMap {
295                 p.setTag(lockGetProp)
296                 return
297         }
298         if p.StdDuration && !isMap {
299                 p.setTag(lockGetProp)
300                 return
301         }
302         if p.WktPointer && !isMap {
303                 p.setTag(lockGetProp)
304                 return
305         }
306         switch t1 := typ; t1.Kind() {
307         case reflect.Struct:
308                 p.stype = typ
309         case reflect.Ptr:
310                 if t1.Elem().Kind() == reflect.Struct {
311                         p.stype = t1.Elem()
312                 }
313         case reflect.Slice:
314                 switch t2 := t1.Elem(); t2.Kind() {
315                 case reflect.Ptr:
316                         switch t3 := t2.Elem(); t3.Kind() {
317                         case reflect.Struct:
318                                 p.stype = t3
319                         }
320                 case reflect.Struct:
321                         p.stype = t2
322                 }
323
324         case reflect.Map:
325
326                 p.mtype = t1
327                 p.MapKeyProp = &Properties{}
328                 p.MapKeyProp.init(reflect.PtrTo(p.mtype.Key()), "Key", f.Tag.Get("protobuf_key"), nil, lockGetProp)
329                 p.MapValProp = &Properties{}
330                 vtype := p.mtype.Elem()
331                 if vtype.Kind() != reflect.Ptr && vtype.Kind() != reflect.Slice {
332                         // The value type is not a message (*T) or bytes ([]byte),
333                         // so we need encoders for the pointer to this type.
334                         vtype = reflect.PtrTo(vtype)
335                 }
336
337                 p.MapValProp.CustomType = p.CustomType
338                 p.MapValProp.StdDuration = p.StdDuration
339                 p.MapValProp.StdTime = p.StdTime
340                 p.MapValProp.WktPointer = p.WktPointer
341                 p.MapValProp.init(vtype, "Value", f.Tag.Get("protobuf_val"), nil, lockGetProp)
342         }
343         p.setTag(lockGetProp)
344 }
345
346 func (p *Properties) setTag(lockGetProp bool) {
347         if p.stype != nil {
348                 if lockGetProp {
349                         p.sprop = GetProperties(p.stype)
350                 } else {
351                         p.sprop = getPropertiesLocked(p.stype)
352                 }
353         }
354 }
355
356 var (
357         marshalerType = reflect.TypeOf((*Marshaler)(nil)).Elem()
358 )
359
360 // Init populates the properties from a protocol buffer struct tag.
361 func (p *Properties) Init(typ reflect.Type, name, tag string, f *reflect.StructField) {
362         p.init(typ, name, tag, f, true)
363 }
364
365 func (p *Properties) init(typ reflect.Type, name, tag string, f *reflect.StructField, lockGetProp bool) {
366         // "bytes,49,opt,def=hello!"
367         p.Name = name
368         p.OrigName = name
369         if tag == "" {
370                 return
371         }
372         p.Parse(tag)
373         p.setFieldProps(typ, f, lockGetProp)
374 }
375
376 var (
377         propertiesMu  sync.RWMutex
378         propertiesMap = make(map[reflect.Type]*StructProperties)
379 )
380
381 // GetProperties returns the list of properties for the type represented by t.
382 // t must represent a generated struct type of a protocol message.
383 func GetProperties(t reflect.Type) *StructProperties {
384         if t.Kind() != reflect.Struct {
385                 panic("proto: type must have kind struct")
386         }
387
388         // Most calls to GetProperties in a long-running program will be
389         // retrieving details for types we have seen before.
390         propertiesMu.RLock()
391         sprop, ok := propertiesMap[t]
392         propertiesMu.RUnlock()
393         if ok {
394                 return sprop
395         }
396
397         propertiesMu.Lock()
398         sprop = getPropertiesLocked(t)
399         propertiesMu.Unlock()
400         return sprop
401 }
402
403 // getPropertiesLocked requires that propertiesMu is held.
404 func getPropertiesLocked(t reflect.Type) *StructProperties {
405         if prop, ok := propertiesMap[t]; ok {
406                 return prop
407         }
408
409         prop := new(StructProperties)
410         // in case of recursive protos, fill this in now.
411         propertiesMap[t] = prop
412
413         // build properties
414         prop.Prop = make([]*Properties, t.NumField())
415         prop.order = make([]int, t.NumField())
416
417         isOneofMessage := false
418         for i := 0; i < t.NumField(); i++ {
419                 f := t.Field(i)
420                 p := new(Properties)
421                 name := f.Name
422                 p.init(f.Type, name, f.Tag.Get("protobuf"), &f, false)
423
424                 oneof := f.Tag.Get("protobuf_oneof") // special case
425                 if oneof != "" {
426                         isOneofMessage = true
427                         // Oneof fields don't use the traditional protobuf tag.
428                         p.OrigName = oneof
429                 }
430                 prop.Prop[i] = p
431                 prop.order[i] = i
432                 if debug {
433                         print(i, " ", f.Name, " ", t.String(), " ")
434                         if p.Tag > 0 {
435                                 print(p.String())
436                         }
437                         print("\n")
438                 }
439         }
440
441         // Re-order prop.order.
442         sort.Sort(prop)
443
444         type oneofMessage interface {
445                 XXX_OneofFuncs() (func(Message, *Buffer) error, func(Message, int, int, *Buffer) (bool, error), func(Message) int, []interface{})
446         }
447         if om, ok := reflect.Zero(reflect.PtrTo(t)).Interface().(oneofMessage); isOneofMessage && ok {
448                 var oots []interface{}
449                 _, _, _, oots = om.XXX_OneofFuncs()
450
451                 // Interpret oneof metadata.
452                 prop.OneofTypes = make(map[string]*OneofProperties)
453                 for _, oot := range oots {
454                         oop := &OneofProperties{
455                                 Type: reflect.ValueOf(oot).Type(), // *T
456                                 Prop: new(Properties),
457                         }
458                         sft := oop.Type.Elem().Field(0)
459                         oop.Prop.Name = sft.Name
460                         oop.Prop.Parse(sft.Tag.Get("protobuf"))
461                         // There will be exactly one interface field that
462                         // this new value is assignable to.
463                         for i := 0; i < t.NumField(); i++ {
464                                 f := t.Field(i)
465                                 if f.Type.Kind() != reflect.Interface {
466                                         continue
467                                 }
468                                 if !oop.Type.AssignableTo(f.Type) {
469                                         continue
470                                 }
471                                 oop.Field = i
472                                 break
473                         }
474                         prop.OneofTypes[oop.Prop.OrigName] = oop
475                 }
476         }
477
478         // build required counts
479         // build tags
480         reqCount := 0
481         prop.decoderOrigNames = make(map[string]int)
482         for i, p := range prop.Prop {
483                 if strings.HasPrefix(p.Name, "XXX_") {
484                         // Internal fields should not appear in tags/origNames maps.
485                         // They are handled specially when encoding and decoding.
486                         continue
487                 }
488                 if p.Required {
489                         reqCount++
490                 }
491                 prop.decoderTags.put(p.Tag, i)
492                 prop.decoderOrigNames[p.OrigName] = i
493         }
494         prop.reqCount = reqCount
495
496         return prop
497 }
498
499 // A global registry of enum types.
500 // The generated code will register the generated maps by calling RegisterEnum.
501
502 var enumValueMaps = make(map[string]map[string]int32)
503 var enumStringMaps = make(map[string]map[int32]string)
504
505 // RegisterEnum is called from the generated code to install the enum descriptor
506 // maps into the global table to aid parsing text format protocol buffers.
507 func RegisterEnum(typeName string, unusedNameMap map[int32]string, valueMap map[string]int32) {
508         if _, ok := enumValueMaps[typeName]; ok {
509                 panic("proto: duplicate enum registered: " + typeName)
510         }
511         enumValueMaps[typeName] = valueMap
512         if _, ok := enumStringMaps[typeName]; ok {
513                 panic("proto: duplicate enum registered: " + typeName)
514         }
515         enumStringMaps[typeName] = unusedNameMap
516 }
517
518 // EnumValueMap returns the mapping from names to integers of the
519 // enum type enumType, or a nil if not found.
520 func EnumValueMap(enumType string) map[string]int32 {
521         return enumValueMaps[enumType]
522 }
523
524 // A registry of all linked message types.
525 // The string is a fully-qualified proto name ("pkg.Message").
526 var (
527         protoTypedNils = make(map[string]Message)      // a map from proto names to typed nil pointers
528         protoMapTypes  = make(map[string]reflect.Type) // a map from proto names to map types
529         revProtoTypes  = make(map[reflect.Type]string)
530 )
531
532 // RegisterType is called from generated code and maps from the fully qualified
533 // proto name to the type (pointer to struct) of the protocol buffer.
534 func RegisterType(x Message, name string) {
535         if _, ok := protoTypedNils[name]; ok {
536                 // TODO: Some day, make this a panic.
537                 log.Printf("proto: duplicate proto type registered: %s", name)
538                 return
539         }
540         t := reflect.TypeOf(x)
541         if v := reflect.ValueOf(x); v.Kind() == reflect.Ptr && v.Pointer() == 0 {
542                 // Generated code always calls RegisterType with nil x.
543                 // This check is just for extra safety.
544                 protoTypedNils[name] = x
545         } else {
546                 protoTypedNils[name] = reflect.Zero(t).Interface().(Message)
547         }
548         revProtoTypes[t] = name
549 }
550
551 // RegisterMapType is called from generated code and maps from the fully qualified
552 // proto name to the native map type of the proto map definition.
553 func RegisterMapType(x interface{}, name string) {
554         if reflect.TypeOf(x).Kind() != reflect.Map {
555                 panic(fmt.Sprintf("RegisterMapType(%T, %q); want map", x, name))
556         }
557         if _, ok := protoMapTypes[name]; ok {
558                 log.Printf("proto: duplicate proto type registered: %s", name)
559                 return
560         }
561         t := reflect.TypeOf(x)
562         protoMapTypes[name] = t
563         revProtoTypes[t] = name
564 }
565
566 // MessageName returns the fully-qualified proto name for the given message type.
567 func MessageName(x Message) string {
568         type xname interface {
569                 XXX_MessageName() string
570         }
571         if m, ok := x.(xname); ok {
572                 return m.XXX_MessageName()
573         }
574         return revProtoTypes[reflect.TypeOf(x)]
575 }
576
577 // MessageType returns the message type (pointer to struct) for a named message.
578 // The type is not guaranteed to implement proto.Message if the name refers to a
579 // map entry.
580 func MessageType(name string) reflect.Type {
581         if t, ok := protoTypedNils[name]; ok {
582                 return reflect.TypeOf(t)
583         }
584         return protoMapTypes[name]
585 }
586
587 // A registry of all linked proto files.
588 var (
589         protoFiles = make(map[string][]byte) // file name => fileDescriptor
590 )
591
592 // RegisterFile is called from generated code and maps from the
593 // full file name of a .proto file to its compressed FileDescriptorProto.
594 func RegisterFile(filename string, fileDescriptor []byte) {
595         protoFiles[filename] = fileDescriptor
596 }
597
598 // FileDescriptor returns the compressed FileDescriptorProto for a .proto file.
599 func FileDescriptor(filename string) []byte { return protoFiles[filename] }