1 // Go support for Protocol Buffers - Google's data interchange format
3 // Copyright 2010 The Go Authors. All rights reserved.
4 // https://github.com/golang/protobuf
6 // Redistribution and use in source and binary forms, with or without
7 // modification, are permitted provided that the following conditions are
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
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.
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.
35 * Routines for encoding data into the wire format for protocol buffers.
49 const debug bool = false
51 // Constants that identify the encoding of a value on the wire.
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
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
73 func (p *tagMap) get(t int) (int, bool) {
74 if t > 0 && t < tagMapFastLimit {
75 if t >= len(p.fastTags) {
81 fi, ok := p.slowTags[t]
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)
93 if p.slowTags == nil {
94 p.slowTags = make(map[int]int)
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
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
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
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.
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
127 func (sp *StructProperties) Swap(i, j int) { sp.order[i], sp.order[j] = sp.order[j], sp.order[i] }
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
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
145 Default string // default value
146 HasDefault bool // whether an explicit default was provided
148 stype reflect.Type // set for struct types only
149 sprop *StructProperties // set for struct types only
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
156 // String formats the properties in the protobuf struct field tag style.
157 func (p *Properties) String() string {
160 s += strconv.Itoa(p.Tag)
173 s += ",name=" + p.OrigName
174 if p.JSONName != p.OrigName {
175 s += ",json=" + p.JSONName
184 s += ",enum=" + p.Enum
187 s += ",def=" + p.Default
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.
197 fmt.Fprintf(os.Stderr, "proto: tag has too few fields: %q\n", s)
204 p.WireType = WireVarint
206 p.WireType = WireFixed32
208 p.WireType = WireFixed64
210 p.WireType = WireVarint
212 p.WireType = WireVarint
213 case "bytes", "group":
214 p.WireType = WireBytes
215 // no numeric converter for non-numeric types
217 fmt.Fprintf(os.Stderr, "proto: tag has unknown wire type: %q\n", s)
222 p.Tag, err = strconv.Atoi(fields[1])
228 for i := 2; i < len(fields); i++ {
239 case strings.HasPrefix(f, "name="):
241 case strings.HasPrefix(f, "json="):
243 case strings.HasPrefix(f, "enum="):
249 case strings.HasPrefix(f, "def="):
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:], ",")
261 var protoMessageType = reflect.TypeOf((*Message)(nil)).Elem()
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() {
267 if t1.Elem().Kind() == reflect.Struct {
272 if t2 := t1.Elem(); t2.Kind() == reflect.Ptr && t2.Elem().Kind() == reflect.Struct {
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)
287 p.MapValProp.init(vtype, "Value", f.Tag.Get("protobuf_val"), nil, lockGetProp)
292 p.sprop = GetProperties(p.stype)
294 p.sprop = getPropertiesLocked(p.stype)
300 marshalerType = reflect.TypeOf((*Marshaler)(nil)).Elem()
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)
308 func (p *Properties) init(typ reflect.Type, name, tag string, f *reflect.StructField, lockGetProp bool) {
309 // "bytes,49,opt,def=hello!"
316 p.setFieldProps(typ, f, lockGetProp)
320 propertiesMu sync.RWMutex
321 propertiesMap = make(map[reflect.Type]*StructProperties)
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")
331 // Most calls to GetProperties in a long-running program will be
332 // retrieving details for types we have seen before.
334 sprop, ok := propertiesMap[t]
335 propertiesMu.RUnlock()
341 sprop = getPropertiesLocked(t)
342 propertiesMu.Unlock()
347 oneofFuncsIface interface {
348 XXX_OneofFuncs() (func(Message, *Buffer) error, func(Message, int, int, *Buffer) (bool, error), func(Message) int, []interface{})
350 oneofWrappersIface interface {
351 XXX_OneofWrappers() []interface{}
355 // getPropertiesLocked requires that propertiesMu is held.
356 func getPropertiesLocked(t reflect.Type) *StructProperties {
357 if prop, ok := propertiesMap[t]; ok {
361 prop := new(StructProperties)
362 // in case of recursive protos, fill this in now.
363 propertiesMap[t] = prop
366 prop.Prop = make([]*Properties, t.NumField())
367 prop.order = make([]int, t.NumField())
369 for i := 0; i < t.NumField(); i++ {
373 p.init(f.Type, name, f.Tag.Get("protobuf"), &f, false)
375 oneof := f.Tag.Get("protobuf_oneof") // special case
377 // Oneof fields don't use the traditional protobuf tag.
383 print(i, " ", f.Name, " ", t.String(), " ")
391 // Re-order prop.order.
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()
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),
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++ {
416 if f.Type.Kind() != reflect.Interface {
419 if !oop.Type.AssignableTo(f.Type) {
425 prop.OneofTypes[oop.Prop.OrigName] = oop
429 // build required counts
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.
442 prop.decoderTags.put(p.Tag, i)
443 prop.decoderOrigNames[p.OrigName] = i
445 prop.reqCount = reqCount
450 // A global registry of enum types.
451 // The generated code will register the generated maps by calling RegisterEnum.
453 var enumValueMaps = make(map[string]map[string]int32)
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)
461 enumValueMaps[typeName] = valueMap
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]
470 // A registry of all linked message types.
471 // The string is a fully-qualified proto name ("pkg.Message").
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)
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)
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
492 protoTypedNils[name] = reflect.Zero(t).Interface().(Message)
494 revProtoTypes[t] = name
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))
503 if _, ok := protoMapTypes[name]; ok {
504 log.Printf("proto: duplicate proto type registered: %s", name)
507 t := reflect.TypeOf(x)
508 protoMapTypes[name] = t
509 revProtoTypes[t] = name
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
517 if m, ok := x.(xname); ok {
518 return m.XXX_MessageName()
520 return revProtoTypes[reflect.TypeOf(x)]
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
526 func MessageType(name string) reflect.Type {
527 if t, ok := protoTypedNils[name]; ok {
528 return reflect.TypeOf(t)
530 return protoMapTypes[name]
533 // A registry of all linked proto files.
535 protoFiles = make(map[string][]byte) // file name => fileDescriptor
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
544 // FileDescriptor returns the compressed FileDescriptorProto for a .proto file.
545 func FileDescriptor(filename string) []byte { return protoFiles[filename] }