Remove BPA from Makefile
[icn.git] / cmd / bpa-operator / vendor / github.com / golang / protobuf / proto / properties.go
1 // Go support for Protocol Buffers - Google's data interchange format
2 //
3 // Copyright 2010 The Go Authors.  All rights reserved.
4 // https://github.com/golang/protobuf
5 //
6 // Redistribution and use in source and binary forms, with or without
7 // modification, are permitted provided that the following conditions are
8 // met:
9 //
10 //     * Redistributions of source code must retain the above copyright
11 // notice, this list of conditions and the following disclaimer.
12 //     * Redistributions in binary form must reproduce the above
13 // copyright notice, this list of conditions and the following disclaimer
14 // in the documentation and/or other materials provided with the
15 // distribution.
16 //     * Neither the name of Google Inc. nor the names of its
17 // contributors may be used to endorse or promote products derived from
18 // this software without specific prior written permission.
19 //
20 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31
32 package proto
33
34 /*
35  * Routines for encoding data into the wire format for protocol buffers.
36  */
37
38 import (
39         "fmt"
40         "log"
41         "os"
42         "reflect"
43         "sort"
44         "strconv"
45         "strings"
46         "sync"
47 )
48
49 const debug bool = false
50
51 // Constants that identify the encoding of a value on the wire.
52 const (
53         WireVarint     = 0
54         WireFixed64    = 1
55         WireBytes      = 2
56         WireStartGroup = 3
57         WireEndGroup   = 4
58         WireFixed32    = 5
59 )
60
61 // tagMap is an optimization over map[int]int for typical protocol buffer
62 // use-cases. Encoded protocol buffers are often in tag order with small tag
63 // numbers.
64 type tagMap struct {
65         fastTags []int
66         slowTags map[int]int
67 }
68
69 // tagMapFastLimit is the upper bound on the tag number that will be stored in
70 // the tagMap slice rather than its map.
71 const tagMapFastLimit = 1024
72
73 func (p *tagMap) get(t int) (int, bool) {
74         if t > 0 && t < tagMapFastLimit {
75                 if t >= len(p.fastTags) {
76                         return 0, false
77                 }
78                 fi := p.fastTags[t]
79                 return fi, fi >= 0
80         }
81         fi, ok := p.slowTags[t]
82         return fi, ok
83 }
84
85 func (p *tagMap) put(t int, fi int) {
86         if t > 0 && t < tagMapFastLimit {
87                 for len(p.fastTags) < t+1 {
88                         p.fastTags = append(p.fastTags, -1)
89                 }
90                 p.fastTags[t] = fi
91                 return
92         }
93         if p.slowTags == nil {
94                 p.slowTags = make(map[int]int)
95         }
96         p.slowTags[t] = fi
97 }
98
99 // StructProperties represents properties for all the fields of a struct.
100 // decoderTags and decoderOrigNames should only be used by the decoder.
101 type StructProperties struct {
102         Prop             []*Properties  // properties for each field
103         reqCount         int            // required count
104         decoderTags      tagMap         // map from proto tag to struct field number
105         decoderOrigNames map[string]int // map from original name to struct field number
106         order            []int          // list of struct field numbers in tag order
107
108         // OneofTypes contains information about the oneof fields in this message.
109         // It is keyed by the original name of a field.
110         OneofTypes map[string]*OneofProperties
111 }
112
113 // OneofProperties represents information about a specific field in a oneof.
114 type OneofProperties struct {
115         Type  reflect.Type // pointer to generated struct type for this oneof field
116         Field int          // struct field number of the containing oneof in the message
117         Prop  *Properties
118 }
119
120 // Implement the sorting interface so we can sort the fields in tag order, as recommended by the spec.
121 // See encode.go, (*Buffer).enc_struct.
122
123 func (sp *StructProperties) Len() int { return len(sp.order) }
124 func (sp *StructProperties) Less(i, j int) bool {
125         return sp.Prop[sp.order[i]].Tag < sp.Prop[sp.order[j]].Tag
126 }
127 func (sp *StructProperties) Swap(i, j int) { sp.order[i], sp.order[j] = sp.order[j], sp.order[i] }
128
129 // Properties represents the protocol-specific behavior of a single struct field.
130 type Properties struct {
131         Name     string // name of the field, for error messages
132         OrigName string // original name before protocol compiler (always set)
133         JSONName string // name to use for JSON; determined by protoc
134         Wire     string
135         WireType int
136         Tag      int
137         Required bool
138         Optional bool
139         Repeated bool
140         Packed   bool   // relevant for repeated primitives only
141         Enum     string // set for enum types only
142         proto3   bool   // whether this is known to be a proto3 field
143         oneof    bool   // whether this is a oneof field
144
145         Default    string // default value
146         HasDefault bool   // whether an explicit default was provided
147
148         stype reflect.Type      // set for struct types only
149         sprop *StructProperties // set for struct types only
150
151         mtype      reflect.Type // set for map types only
152         MapKeyProp *Properties  // set for map types only
153         MapValProp *Properties  // set for map types only
154 }
155
156 // String formats the properties in the protobuf struct field tag style.
157 func (p *Properties) String() string {
158         s := p.Wire
159         s += ","
160         s += strconv.Itoa(p.Tag)
161         if p.Required {
162                 s += ",req"
163         }
164         if p.Optional {
165                 s += ",opt"
166         }
167         if p.Repeated {
168                 s += ",rep"
169         }
170         if p.Packed {
171                 s += ",packed"
172         }
173         s += ",name=" + p.OrigName
174         if p.JSONName != p.OrigName {
175                 s += ",json=" + p.JSONName
176         }
177         if p.proto3 {
178                 s += ",proto3"
179         }
180         if p.oneof {
181                 s += ",oneof"
182         }
183         if len(p.Enum) > 0 {
184                 s += ",enum=" + p.Enum
185         }
186         if p.HasDefault {
187                 s += ",def=" + p.Default
188         }
189         return s
190 }
191
192 // Parse populates p by parsing a string in the protobuf struct field tag style.
193 func (p *Properties) Parse(s string) {
194         // "bytes,49,opt,name=foo,def=hello!"
195         fields := strings.Split(s, ",") // breaks def=, but handled below.
196         if len(fields) < 2 {
197                 fmt.Fprintf(os.Stderr, "proto: tag has too few fields: %q\n", s)
198                 return
199         }
200
201         p.Wire = fields[0]
202         switch p.Wire {
203         case "varint":
204                 p.WireType = WireVarint
205         case "fixed32":
206                 p.WireType = WireFixed32
207         case "fixed64":
208                 p.WireType = WireFixed64
209         case "zigzag32":
210                 p.WireType = WireVarint
211         case "zigzag64":
212                 p.WireType = WireVarint
213         case "bytes", "group":
214                 p.WireType = WireBytes
215                 // no numeric converter for non-numeric types
216         default:
217                 fmt.Fprintf(os.Stderr, "proto: tag has unknown wire type: %q\n", s)
218                 return
219         }
220
221         var err error
222         p.Tag, err = strconv.Atoi(fields[1])
223         if err != nil {
224                 return
225         }
226
227 outer:
228         for i := 2; i < len(fields); i++ {
229                 f := fields[i]
230                 switch {
231                 case f == "req":
232                         p.Required = true
233                 case f == "opt":
234                         p.Optional = true
235                 case f == "rep":
236                         p.Repeated = true
237                 case f == "packed":
238                         p.Packed = true
239                 case strings.HasPrefix(f, "name="):
240                         p.OrigName = f[5:]
241                 case strings.HasPrefix(f, "json="):
242                         p.JSONName = f[5:]
243                 case strings.HasPrefix(f, "enum="):
244                         p.Enum = f[5:]
245                 case f == "proto3":
246                         p.proto3 = true
247                 case f == "oneof":
248                         p.oneof = true
249                 case strings.HasPrefix(f, "def="):
250                         p.HasDefault = true
251                         p.Default = f[4:] // rest of string
252                         if i+1 < len(fields) {
253                                 // Commas aren't escaped, and def is always last.
254                                 p.Default += "," + strings.Join(fields[i+1:], ",")
255                                 break outer
256                         }
257                 }
258         }
259 }
260
261 var protoMessageType = reflect.TypeOf((*Message)(nil)).Elem()
262
263 // setFieldProps initializes the field properties for submessages and maps.
264 func (p *Properties) setFieldProps(typ reflect.Type, f *reflect.StructField, lockGetProp bool) {
265         switch t1 := typ; t1.Kind() {
266         case reflect.Ptr:
267                 if t1.Elem().Kind() == reflect.Struct {
268                         p.stype = t1.Elem()
269                 }
270
271         case reflect.Slice:
272                 if t2 := t1.Elem(); t2.Kind() == reflect.Ptr && t2.Elem().Kind() == reflect.Struct {
273                         p.stype = t2.Elem()
274                 }
275
276         case reflect.Map:
277                 p.mtype = t1
278                 p.MapKeyProp = &Properties{}
279                 p.MapKeyProp.init(reflect.PtrTo(p.mtype.Key()), "Key", f.Tag.Get("protobuf_key"), nil, lockGetProp)
280                 p.MapValProp = &Properties{}
281                 vtype := p.mtype.Elem()
282                 if vtype.Kind() != reflect.Ptr && vtype.Kind() != reflect.Slice {
283                         // The value type is not a message (*T) or bytes ([]byte),
284                         // so we need encoders for the pointer to this type.
285                         vtype = reflect.PtrTo(vtype)
286                 }
287                 p.MapValProp.init(vtype, "Value", f.Tag.Get("protobuf_val"), nil, lockGetProp)
288         }
289
290         if p.stype != nil {
291                 if lockGetProp {
292                         p.sprop = GetProperties(p.stype)
293                 } else {
294                         p.sprop = getPropertiesLocked(p.stype)
295                 }
296         }
297 }
298
299 var (
300         marshalerType = reflect.TypeOf((*Marshaler)(nil)).Elem()
301 )
302
303 // Init populates the properties from a protocol buffer struct tag.
304 func (p *Properties) Init(typ reflect.Type, name, tag string, f *reflect.StructField) {
305         p.init(typ, name, tag, f, true)
306 }
307
308 func (p *Properties) init(typ reflect.Type, name, tag string, f *reflect.StructField, lockGetProp bool) {
309         // "bytes,49,opt,def=hello!"
310         p.Name = name
311         p.OrigName = name
312         if tag == "" {
313                 return
314         }
315         p.Parse(tag)
316         p.setFieldProps(typ, f, lockGetProp)
317 }
318
319 var (
320         propertiesMu  sync.RWMutex
321         propertiesMap = make(map[reflect.Type]*StructProperties)
322 )
323
324 // GetProperties returns the list of properties for the type represented by t.
325 // t must represent a generated struct type of a protocol message.
326 func GetProperties(t reflect.Type) *StructProperties {
327         if t.Kind() != reflect.Struct {
328                 panic("proto: type must have kind struct")
329         }
330
331         // Most calls to GetProperties in a long-running program will be
332         // retrieving details for types we have seen before.
333         propertiesMu.RLock()
334         sprop, ok := propertiesMap[t]
335         propertiesMu.RUnlock()
336         if ok {
337                 return sprop
338         }
339
340         propertiesMu.Lock()
341         sprop = getPropertiesLocked(t)
342         propertiesMu.Unlock()
343         return sprop
344 }
345
346 type (
347         oneofFuncsIface interface {
348                 XXX_OneofFuncs() (func(Message, *Buffer) error, func(Message, int, int, *Buffer) (bool, error), func(Message) int, []interface{})
349         }
350         oneofWrappersIface interface {
351                 XXX_OneofWrappers() []interface{}
352         }
353 )
354
355 // getPropertiesLocked requires that propertiesMu is held.
356 func getPropertiesLocked(t reflect.Type) *StructProperties {
357         if prop, ok := propertiesMap[t]; ok {
358                 return prop
359         }
360
361         prop := new(StructProperties)
362         // in case of recursive protos, fill this in now.
363         propertiesMap[t] = prop
364
365         // build properties
366         prop.Prop = make([]*Properties, t.NumField())
367         prop.order = make([]int, t.NumField())
368
369         for i := 0; i < t.NumField(); i++ {
370                 f := t.Field(i)
371                 p := new(Properties)
372                 name := f.Name
373                 p.init(f.Type, name, f.Tag.Get("protobuf"), &f, false)
374
375                 oneof := f.Tag.Get("protobuf_oneof") // special case
376                 if oneof != "" {
377                         // Oneof fields don't use the traditional protobuf tag.
378                         p.OrigName = oneof
379                 }
380                 prop.Prop[i] = p
381                 prop.order[i] = i
382                 if debug {
383                         print(i, " ", f.Name, " ", t.String(), " ")
384                         if p.Tag > 0 {
385                                 print(p.String())
386                         }
387                         print("\n")
388                 }
389         }
390
391         // Re-order prop.order.
392         sort.Sort(prop)
393
394         var oots []interface{}
395         switch m := reflect.Zero(reflect.PtrTo(t)).Interface().(type) {
396         case oneofFuncsIface:
397                 _, _, _, oots = m.XXX_OneofFuncs()
398         case oneofWrappersIface:
399                 oots = m.XXX_OneofWrappers()
400         }
401         if len(oots) > 0 {
402                 // Interpret oneof metadata.
403                 prop.OneofTypes = make(map[string]*OneofProperties)
404                 for _, oot := range oots {
405                         oop := &OneofProperties{
406                                 Type: reflect.ValueOf(oot).Type(), // *T
407                                 Prop: new(Properties),
408                         }
409                         sft := oop.Type.Elem().Field(0)
410                         oop.Prop.Name = sft.Name
411                         oop.Prop.Parse(sft.Tag.Get("protobuf"))
412                         // There will be exactly one interface field that
413                         // this new value is assignable to.
414                         for i := 0; i < t.NumField(); i++ {
415                                 f := t.Field(i)
416                                 if f.Type.Kind() != reflect.Interface {
417                                         continue
418                                 }
419                                 if !oop.Type.AssignableTo(f.Type) {
420                                         continue
421                                 }
422                                 oop.Field = i
423                                 break
424                         }
425                         prop.OneofTypes[oop.Prop.OrigName] = oop
426                 }
427         }
428
429         // build required counts
430         // build tags
431         reqCount := 0
432         prop.decoderOrigNames = make(map[string]int)
433         for i, p := range prop.Prop {
434                 if strings.HasPrefix(p.Name, "XXX_") {
435                         // Internal fields should not appear in tags/origNames maps.
436                         // They are handled specially when encoding and decoding.
437                         continue
438                 }
439                 if p.Required {
440                         reqCount++
441                 }
442                 prop.decoderTags.put(p.Tag, i)
443                 prop.decoderOrigNames[p.OrigName] = i
444         }
445         prop.reqCount = reqCount
446
447         return prop
448 }
449
450 // A global registry of enum types.
451 // The generated code will register the generated maps by calling RegisterEnum.
452
453 var enumValueMaps = make(map[string]map[string]int32)
454
455 // RegisterEnum is called from the generated code to install the enum descriptor
456 // maps into the global table to aid parsing text format protocol buffers.
457 func RegisterEnum(typeName string, unusedNameMap map[int32]string, valueMap map[string]int32) {
458         if _, ok := enumValueMaps[typeName]; ok {
459                 panic("proto: duplicate enum registered: " + typeName)
460         }
461         enumValueMaps[typeName] = valueMap
462 }
463
464 // EnumValueMap returns the mapping from names to integers of the
465 // enum type enumType, or a nil if not found.
466 func EnumValueMap(enumType string) map[string]int32 {
467         return enumValueMaps[enumType]
468 }
469
470 // A registry of all linked message types.
471 // The string is a fully-qualified proto name ("pkg.Message").
472 var (
473         protoTypedNils = make(map[string]Message)      // a map from proto names to typed nil pointers
474         protoMapTypes  = make(map[string]reflect.Type) // a map from proto names to map types
475         revProtoTypes  = make(map[reflect.Type]string)
476 )
477
478 // RegisterType is called from generated code and maps from the fully qualified
479 // proto name to the type (pointer to struct) of the protocol buffer.
480 func RegisterType(x Message, name string) {
481         if _, ok := protoTypedNils[name]; ok {
482                 // TODO: Some day, make this a panic.
483                 log.Printf("proto: duplicate proto type registered: %s", name)
484                 return
485         }
486         t := reflect.TypeOf(x)
487         if v := reflect.ValueOf(x); v.Kind() == reflect.Ptr && v.Pointer() == 0 {
488                 // Generated code always calls RegisterType with nil x.
489                 // This check is just for extra safety.
490                 protoTypedNils[name] = x
491         } else {
492                 protoTypedNils[name] = reflect.Zero(t).Interface().(Message)
493         }
494         revProtoTypes[t] = name
495 }
496
497 // RegisterMapType is called from generated code and maps from the fully qualified
498 // proto name to the native map type of the proto map definition.
499 func RegisterMapType(x interface{}, name string) {
500         if reflect.TypeOf(x).Kind() != reflect.Map {
501                 panic(fmt.Sprintf("RegisterMapType(%T, %q); want map", x, name))
502         }
503         if _, ok := protoMapTypes[name]; ok {
504                 log.Printf("proto: duplicate proto type registered: %s", name)
505                 return
506         }
507         t := reflect.TypeOf(x)
508         protoMapTypes[name] = t
509         revProtoTypes[t] = name
510 }
511
512 // MessageName returns the fully-qualified proto name for the given message type.
513 func MessageName(x Message) string {
514         type xname interface {
515                 XXX_MessageName() string
516         }
517         if m, ok := x.(xname); ok {
518                 return m.XXX_MessageName()
519         }
520         return revProtoTypes[reflect.TypeOf(x)]
521 }
522
523 // MessageType returns the message type (pointer to struct) for a named message.
524 // The type is not guaranteed to implement proto.Message if the name refers to a
525 // map entry.
526 func MessageType(name string) reflect.Type {
527         if t, ok := protoTypedNils[name]; ok {
528                 return reflect.TypeOf(t)
529         }
530         return protoMapTypes[name]
531 }
532
533 // A registry of all linked proto files.
534 var (
535         protoFiles = make(map[string][]byte) // file name => fileDescriptor
536 )
537
538 // RegisterFile is called from generated code and maps from the
539 // full file name of a .proto file to its compressed FileDescriptorProto.
540 func RegisterFile(filename string, fileDescriptor []byte) {
541         protoFiles[filename] = fileDescriptor
542 }
543
544 // FileDescriptor returns the compressed FileDescriptorProto for a .proto file.
545 func FileDescriptor(filename string) []byte { return protoFiles[filename] }