blob: 612845418e297ab5f1f8421b1d422846e51cefb5 [file] [log] [blame]
package builder
import (
"reflect"
"sync"
)
var (
registry = make(map[reflect.Type]reflect.Type)
registryMux sync.RWMutex
)
// RegisterType maps the given builderType to a structType.
// This mapping affects the type of slices returned by Get and is required for
// GetStruct to work.
//
// Returns a Value containing an empty instance of the registered builderType.
//
// RegisterType will panic if builderType's underlying type is not Builder or
// if structType's Kind is not Struct.
func RegisterType(builderType reflect.Type, structType reflect.Type) *reflect.Value {
registryMux.Lock()
defer registryMux.Unlock()
structType.NumField() // Panic if structType is not a struct
registry[builderType] = structType
emptyValue := emptyBuilderValue.Convert(builderType)
return &emptyValue
}
// Register wraps RegisterType, taking instances instead of Types.
//
// Returns an empty instance of the registered builder type which can be used
// as the initial value for builder expressions. See example.
func Register(builderProto, structProto interface{}) interface{} {
empty := RegisterType(
reflect.TypeOf(builderProto),
reflect.TypeOf(structProto),
).Interface()
return empty
}
func getBuilderStructType(builderType reflect.Type) *reflect.Type {
registryMux.RLock()
defer registryMux.RUnlock()
structType, ok := registry[builderType]
if !ok {
return nil
}
return &structType
}
func newBuilderStruct(builderType reflect.Type) *reflect.Value {
structType := getBuilderStructType(builderType)
if structType == nil {
return nil
}
newStruct := reflect.New(*structType).Elem()
return &newStruct
}