vendor/github.com/golang/protobuf/proto/properties.go
changeset 251 1c52a0eeb952
parent 242 2a9ec03fe5a1
child 256 6d9efbef00a9
equal deleted inserted replaced
250:c040f992052f 251:1c52a0eeb952
    36  */
    36  */
    37 
    37 
    38 import (
    38 import (
    39 	"fmt"
    39 	"fmt"
    40 	"log"
    40 	"log"
    41 	"os"
       
    42 	"reflect"
    41 	"reflect"
    43 	"sort"
    42 	"sort"
    44 	"strconv"
    43 	"strconv"
    45 	"strings"
    44 	"strings"
    46 	"sync"
    45 	"sync"
   192 // Parse populates p by parsing a string in the protobuf struct field tag style.
   191 // Parse populates p by parsing a string in the protobuf struct field tag style.
   193 func (p *Properties) Parse(s string) {
   192 func (p *Properties) Parse(s string) {
   194 	// "bytes,49,opt,name=foo,def=hello!"
   193 	// "bytes,49,opt,name=foo,def=hello!"
   195 	fields := strings.Split(s, ",") // breaks def=, but handled below.
   194 	fields := strings.Split(s, ",") // breaks def=, but handled below.
   196 	if len(fields) < 2 {
   195 	if len(fields) < 2 {
   197 		fmt.Fprintf(os.Stderr, "proto: tag has too few fields: %q\n", s)
   196 		log.Printf("proto: tag has too few fields: %q", s)
   198 		return
   197 		return
   199 	}
   198 	}
   200 
   199 
   201 	p.Wire = fields[0]
   200 	p.Wire = fields[0]
   202 	switch p.Wire {
   201 	switch p.Wire {
   212 		p.WireType = WireVarint
   211 		p.WireType = WireVarint
   213 	case "bytes", "group":
   212 	case "bytes", "group":
   214 		p.WireType = WireBytes
   213 		p.WireType = WireBytes
   215 		// no numeric converter for non-numeric types
   214 		// no numeric converter for non-numeric types
   216 	default:
   215 	default:
   217 		fmt.Fprintf(os.Stderr, "proto: tag has unknown wire type: %q\n", s)
   216 		log.Printf("proto: tag has unknown wire type: %q", s)
   218 		return
   217 		return
   219 	}
   218 	}
   220 
   219 
   221 	var err error
   220 	var err error
   222 	p.Tag, err = strconv.Atoi(fields[1])
   221 	p.Tag, err = strconv.Atoi(fields[1])
   332 	// retrieving details for types we have seen before.
   331 	// retrieving details for types we have seen before.
   333 	propertiesMu.RLock()
   332 	propertiesMu.RLock()
   334 	sprop, ok := propertiesMap[t]
   333 	sprop, ok := propertiesMap[t]
   335 	propertiesMu.RUnlock()
   334 	propertiesMu.RUnlock()
   336 	if ok {
   335 	if ok {
   337 		if collectStats {
       
   338 			stats.Chit++
       
   339 		}
       
   340 		return sprop
   336 		return sprop
   341 	}
   337 	}
   342 
   338 
   343 	propertiesMu.Lock()
   339 	propertiesMu.Lock()
   344 	sprop = getPropertiesLocked(t)
   340 	sprop = getPropertiesLocked(t)
   345 	propertiesMu.Unlock()
   341 	propertiesMu.Unlock()
   346 	return sprop
   342 	return sprop
   347 }
   343 }
   348 
   344 
       
   345 type (
       
   346 	oneofFuncsIface interface {
       
   347 		XXX_OneofFuncs() (func(Message, *Buffer) error, func(Message, int, int, *Buffer) (bool, error), func(Message) int, []interface{})
       
   348 	}
       
   349 	oneofWrappersIface interface {
       
   350 		XXX_OneofWrappers() []interface{}
       
   351 	}
       
   352 )
       
   353 
   349 // getPropertiesLocked requires that propertiesMu is held.
   354 // getPropertiesLocked requires that propertiesMu is held.
   350 func getPropertiesLocked(t reflect.Type) *StructProperties {
   355 func getPropertiesLocked(t reflect.Type) *StructProperties {
   351 	if prop, ok := propertiesMap[t]; ok {
   356 	if prop, ok := propertiesMap[t]; ok {
   352 		if collectStats {
       
   353 			stats.Chit++
       
   354 		}
       
   355 		return prop
   357 		return prop
   356 	}
       
   357 	if collectStats {
       
   358 		stats.Cmiss++
       
   359 	}
   358 	}
   360 
   359 
   361 	prop := new(StructProperties)
   360 	prop := new(StructProperties)
   362 	// in case of recursive protos, fill this in now.
   361 	// in case of recursive protos, fill this in now.
   363 	propertiesMap[t] = prop
   362 	propertiesMap[t] = prop
   389 	}
   388 	}
   390 
   389 
   391 	// Re-order prop.order.
   390 	// Re-order prop.order.
   392 	sort.Sort(prop)
   391 	sort.Sort(prop)
   393 
   392 
   394 	type oneofMessage interface {
   393 	var oots []interface{}
   395 		XXX_OneofFuncs() (func(Message, *Buffer) error, func(Message, int, int, *Buffer) (bool, error), func(Message) int, []interface{})
   394 	switch m := reflect.Zero(reflect.PtrTo(t)).Interface().(type) {
   396 	}
   395 	case oneofFuncsIface:
   397 	if om, ok := reflect.Zero(reflect.PtrTo(t)).Interface().(oneofMessage); ok {
   396 		_, _, _, oots = m.XXX_OneofFuncs()
   398 		var oots []interface{}
   397 	case oneofWrappersIface:
   399 		_, _, _, oots = om.XXX_OneofFuncs()
   398 		oots = m.XXX_OneofWrappers()
   400 
   399 	}
       
   400 	if len(oots) > 0 {
   401 		// Interpret oneof metadata.
   401 		// Interpret oneof metadata.
   402 		prop.OneofTypes = make(map[string]*OneofProperties)
   402 		prop.OneofTypes = make(map[string]*OneofProperties)
   403 		for _, oot := range oots {
   403 		for _, oot := range oots {
   404 			oop := &OneofProperties{
   404 			oop := &OneofProperties{
   405 				Type: reflect.ValueOf(oot).Type(), // *T
   405 				Type: reflect.ValueOf(oot).Type(), // *T