github.com/aclisp/heapster@v0.19.2-0.20160613100040-51756f899a96/Godeps/_workspace/src/k8s.io/kubernetes/pkg/conversion/converter.go (about)

     1  /*
     2  Copyright 2014 The Kubernetes Authors All rights reserved.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package conversion
    18  
    19  import (
    20  	"fmt"
    21  	"reflect"
    22  )
    23  
    24  type typePair struct {
    25  	source reflect.Type
    26  	dest   reflect.Type
    27  }
    28  
    29  type typeNamePair struct {
    30  	fieldType reflect.Type
    31  	fieldName string
    32  }
    33  
    34  // DebugLogger allows you to get debugging messages if necessary.
    35  type DebugLogger interface {
    36  	Logf(format string, args ...interface{})
    37  }
    38  
    39  type NameFunc func(t reflect.Type) string
    40  
    41  var DefaultNameFunc = func(t reflect.Type) string { return t.Name() }
    42  
    43  type GenericConversionFunc func(a, b interface{}, scope Scope) (bool, error)
    44  
    45  // Converter knows how to convert one type to another.
    46  type Converter struct {
    47  	// Map from the conversion pair to a function which can
    48  	// do the conversion.
    49  	conversionFuncs          ConversionFuncs
    50  	generatedConversionFuncs ConversionFuncs
    51  
    52  	// genericConversions are called during normal conversion to offer a "fast-path"
    53  	// that avoids all reflection. These methods are not called outside of the .Convert()
    54  	// method.
    55  	genericConversions []GenericConversionFunc
    56  
    57  	// Set of conversions that should be treated as a no-op
    58  	ignoredConversions map[typePair]struct{}
    59  
    60  	// This is a map from a source field type and name, to a list of destination
    61  	// field type and name.
    62  	structFieldDests map[typeNamePair][]typeNamePair
    63  
    64  	// Allows for the opposite lookup of structFieldDests. So that SourceFromDest
    65  	// copy flag also works. So this is a map of destination field name, to potential
    66  	// source field name and type to look for.
    67  	structFieldSources map[typeNamePair][]typeNamePair
    68  
    69  	// Map from a type to a function which applies defaults.
    70  	defaultingFuncs map[reflect.Type]reflect.Value
    71  
    72  	// Similar to above, but function is stored as interface{}.
    73  	defaultingInterfaces map[reflect.Type]interface{}
    74  
    75  	// Map from an input type to a function which can apply a key name mapping
    76  	inputFieldMappingFuncs map[reflect.Type]FieldMappingFunc
    77  
    78  	// Map from an input type to a set of default conversion flags.
    79  	inputDefaultFlags map[reflect.Type]FieldMatchingFlags
    80  
    81  	// If non-nil, will be called to print helpful debugging info. Quite verbose.
    82  	Debug DebugLogger
    83  
    84  	// nameFunc is called to retrieve the name of a type; this name is used for the
    85  	// purpose of deciding whether two types match or not (i.e., will we attempt to
    86  	// do a conversion). The default returns the go type name.
    87  	nameFunc func(t reflect.Type) string
    88  }
    89  
    90  // NewConverter creates a new Converter object.
    91  func NewConverter(nameFn NameFunc) *Converter {
    92  	c := &Converter{
    93  		conversionFuncs:          NewConversionFuncs(),
    94  		generatedConversionFuncs: NewConversionFuncs(),
    95  		ignoredConversions:       make(map[typePair]struct{}),
    96  		defaultingFuncs:          make(map[reflect.Type]reflect.Value),
    97  		defaultingInterfaces:     make(map[reflect.Type]interface{}),
    98  		nameFunc:                 nameFn,
    99  		structFieldDests:         make(map[typeNamePair][]typeNamePair),
   100  		structFieldSources:       make(map[typeNamePair][]typeNamePair),
   101  
   102  		inputFieldMappingFuncs: make(map[reflect.Type]FieldMappingFunc),
   103  		inputDefaultFlags:      make(map[reflect.Type]FieldMatchingFlags),
   104  	}
   105  	c.RegisterConversionFunc(Convert_Slice_byte_To_Slice_byte)
   106  	return c
   107  }
   108  
   109  // AddGenericConversionFunc adds a function that accepts the ConversionFunc call pattern
   110  // (for two conversion types) to the converter. These functions are checked first during
   111  // a normal conversion, but are otherwise not called. Use AddConversionFuncs when registering
   112  // typed conversions.
   113  func (c *Converter) AddGenericConversionFunc(fn GenericConversionFunc) {
   114  	c.genericConversions = append(c.genericConversions, fn)
   115  }
   116  
   117  // WithConversions returns a Converter that is a copy of c but with the additional
   118  // fns merged on top.
   119  func (c *Converter) WithConversions(fns ConversionFuncs) *Converter {
   120  	copied := *c
   121  	copied.conversionFuncs = c.conversionFuncs.Merge(fns)
   122  	return &copied
   123  }
   124  
   125  // DefaultMeta returns the conversion FieldMappingFunc and meta for a given type.
   126  func (c *Converter) DefaultMeta(t reflect.Type) (FieldMatchingFlags, *Meta) {
   127  	return c.inputDefaultFlags[t], &Meta{
   128  		KeyNameMapping: c.inputFieldMappingFuncs[t],
   129  	}
   130  }
   131  
   132  // Convert_Slice_byte_To_Slice_byte prevents recursing into every byte
   133  func Convert_Slice_byte_To_Slice_byte(in *[]byte, out *[]byte, s Scope) error {
   134  	if *in == nil {
   135  		*out = nil
   136  		return nil
   137  	}
   138  	*out = make([]byte, len(*in))
   139  	copy(*out, *in)
   140  	return nil
   141  }
   142  
   143  // Scope is passed to conversion funcs to allow them to continue an ongoing conversion.
   144  // If multiple converters exist in the system, Scope will allow you to use the correct one
   145  // from a conversion function--that is, the one your conversion function was called by.
   146  type Scope interface {
   147  	// Call Convert to convert sub-objects. Note that if you call it with your own exact
   148  	// parameters, you'll run out of stack space before anything useful happens.
   149  	Convert(src, dest interface{}, flags FieldMatchingFlags) error
   150  
   151  	// DefaultConvert performs the default conversion, without calling a conversion func
   152  	// on the current stack frame. This makes it safe to call from a conversion func.
   153  	DefaultConvert(src, dest interface{}, flags FieldMatchingFlags) error
   154  
   155  	// If registered, returns a function applying defaults for objects of a given type.
   156  	// Used for automatically generating conversion functions.
   157  	DefaultingInterface(inType reflect.Type) (interface{}, bool)
   158  
   159  	// SrcTags and DestTags contain the struct tags that src and dest had, respectively.
   160  	// If the enclosing object was not a struct, then these will contain no tags, of course.
   161  	SrcTag() reflect.StructTag
   162  	DestTag() reflect.StructTag
   163  
   164  	// Flags returns the flags with which the conversion was started.
   165  	Flags() FieldMatchingFlags
   166  
   167  	// Meta returns any information originally passed to Convert.
   168  	Meta() *Meta
   169  }
   170  
   171  // FieldMappingFunc can convert an input field value into different values, depending on
   172  // the value of the source or destination struct tags.
   173  type FieldMappingFunc func(key string, sourceTag, destTag reflect.StructTag) (source string, dest string)
   174  
   175  func NewConversionFuncs() ConversionFuncs {
   176  	return ConversionFuncs{fns: make(map[typePair]reflect.Value)}
   177  }
   178  
   179  type ConversionFuncs struct {
   180  	fns map[typePair]reflect.Value
   181  }
   182  
   183  // Add adds the provided conversion functions to the lookup table - they must have the signature
   184  // `func(type1, type2, Scope) error`. Functions are added in the order passed and will override
   185  // previously registered pairs.
   186  func (c ConversionFuncs) Add(fns ...interface{}) error {
   187  	for _, fn := range fns {
   188  		fv := reflect.ValueOf(fn)
   189  		ft := fv.Type()
   190  		if err := verifyConversionFunctionSignature(ft); err != nil {
   191  			return err
   192  		}
   193  		c.fns[typePair{ft.In(0).Elem(), ft.In(1).Elem()}] = fv
   194  	}
   195  	return nil
   196  }
   197  
   198  // Merge returns a new ConversionFuncs that contains all conversions from
   199  // both other and c, with other conversions taking precedence.
   200  func (c ConversionFuncs) Merge(other ConversionFuncs) ConversionFuncs {
   201  	merged := NewConversionFuncs()
   202  	for k, v := range c.fns {
   203  		merged.fns[k] = v
   204  	}
   205  	for k, v := range other.fns {
   206  		merged.fns[k] = v
   207  	}
   208  	return merged
   209  }
   210  
   211  // Meta is supplied by Scheme, when it calls Convert.
   212  type Meta struct {
   213  	// KeyNameMapping is an optional function which may map the listed key (field name)
   214  	// into a source and destination value.
   215  	KeyNameMapping FieldMappingFunc
   216  }
   217  
   218  // scope contains information about an ongoing conversion.
   219  type scope struct {
   220  	converter *Converter
   221  	meta      *Meta
   222  	flags     FieldMatchingFlags
   223  
   224  	// srcStack & destStack are separate because they may not have a 1:1
   225  	// relationship.
   226  	srcStack  scopeStack
   227  	destStack scopeStack
   228  }
   229  
   230  type scopeStackElem struct {
   231  	tag   reflect.StructTag
   232  	value reflect.Value
   233  	key   string
   234  }
   235  
   236  type scopeStack []scopeStackElem
   237  
   238  func (s *scopeStack) pop() {
   239  	n := len(*s)
   240  	*s = (*s)[:n-1]
   241  }
   242  
   243  func (s *scopeStack) push(e scopeStackElem) {
   244  	*s = append(*s, e)
   245  }
   246  
   247  func (s *scopeStack) top() *scopeStackElem {
   248  	return &(*s)[len(*s)-1]
   249  }
   250  
   251  func (s scopeStack) describe() string {
   252  	desc := ""
   253  	if len(s) > 1 {
   254  		desc = "(" + s[1].value.Type().String() + ")"
   255  	}
   256  	for i, v := range s {
   257  		if i < 2 {
   258  			// First layer on stack is not real; second is handled specially above.
   259  			continue
   260  		}
   261  		if v.key == "" {
   262  			desc += fmt.Sprintf(".%v", v.value.Type())
   263  		} else {
   264  			desc += fmt.Sprintf(".%v", v.key)
   265  		}
   266  	}
   267  	return desc
   268  }
   269  
   270  func (s *scope) DefaultingInterface(inType reflect.Type) (interface{}, bool) {
   271  	value, found := s.converter.defaultingInterfaces[inType]
   272  	return value, found
   273  }
   274  
   275  // Formats src & dest as indices for printing.
   276  func (s *scope) setIndices(src, dest int) {
   277  	s.srcStack.top().key = fmt.Sprintf("[%v]", src)
   278  	s.destStack.top().key = fmt.Sprintf("[%v]", dest)
   279  }
   280  
   281  // Formats src & dest as map keys for printing.
   282  func (s *scope) setKeys(src, dest interface{}) {
   283  	s.srcStack.top().key = fmt.Sprintf(`["%v"]`, src)
   284  	s.destStack.top().key = fmt.Sprintf(`["%v"]`, dest)
   285  }
   286  
   287  // Convert continues a conversion.
   288  func (s *scope) Convert(src, dest interface{}, flags FieldMatchingFlags) error {
   289  	return s.converter.Convert(src, dest, flags, s.meta)
   290  }
   291  
   292  // DefaultConvert continues a conversion, performing a default conversion (no conversion func)
   293  // for the current stack frame.
   294  func (s *scope) DefaultConvert(src, dest interface{}, flags FieldMatchingFlags) error {
   295  	return s.converter.DefaultConvert(src, dest, flags, s.meta)
   296  }
   297  
   298  // SrcTag returns the tag of the struct containing the current source item, if any.
   299  func (s *scope) SrcTag() reflect.StructTag {
   300  	return s.srcStack.top().tag
   301  }
   302  
   303  // DestTag returns the tag of the struct containing the current dest item, if any.
   304  func (s *scope) DestTag() reflect.StructTag {
   305  	return s.destStack.top().tag
   306  }
   307  
   308  // Flags returns the flags with which the current conversion was started.
   309  func (s *scope) Flags() FieldMatchingFlags {
   310  	return s.flags
   311  }
   312  
   313  // Meta returns the meta object that was originally passed to Convert.
   314  func (s *scope) Meta() *Meta {
   315  	return s.meta
   316  }
   317  
   318  // describe prints the path to get to the current (source, dest) values.
   319  func (s *scope) describe() (src, dest string) {
   320  	return s.srcStack.describe(), s.destStack.describe()
   321  }
   322  
   323  // error makes an error that includes information about where we were in the objects
   324  // we were asked to convert.
   325  func (s *scope) errorf(message string, args ...interface{}) error {
   326  	srcPath, destPath := s.describe()
   327  	where := fmt.Sprintf("converting %v to %v: ", srcPath, destPath)
   328  	return fmt.Errorf(where+message, args...)
   329  }
   330  
   331  // Verifies whether a conversion function has a correct signature.
   332  func verifyConversionFunctionSignature(ft reflect.Type) error {
   333  	if ft.Kind() != reflect.Func {
   334  		return fmt.Errorf("expected func, got: %v", ft)
   335  	}
   336  	if ft.NumIn() != 3 {
   337  		return fmt.Errorf("expected three 'in' params, got: %v", ft)
   338  	}
   339  	if ft.NumOut() != 1 {
   340  		return fmt.Errorf("expected one 'out' param, got: %v", ft)
   341  	}
   342  	if ft.In(0).Kind() != reflect.Ptr {
   343  		return fmt.Errorf("expected pointer arg for 'in' param 0, got: %v", ft)
   344  	}
   345  	if ft.In(1).Kind() != reflect.Ptr {
   346  		return fmt.Errorf("expected pointer arg for 'in' param 1, got: %v", ft)
   347  	}
   348  	scopeType := Scope(nil)
   349  	if e, a := reflect.TypeOf(&scopeType).Elem(), ft.In(2); e != a {
   350  		return fmt.Errorf("expected '%v' arg for 'in' param 2, got '%v' (%v)", e, a, ft)
   351  	}
   352  	var forErrorType error
   353  	// This convolution is necessary, otherwise TypeOf picks up on the fact
   354  	// that forErrorType is nil.
   355  	errorType := reflect.TypeOf(&forErrorType).Elem()
   356  	if ft.Out(0) != errorType {
   357  		return fmt.Errorf("expected error return, got: %v", ft)
   358  	}
   359  	return nil
   360  }
   361  
   362  // RegisterConversionFunc registers a conversion func with the
   363  // Converter. conversionFunc must take three parameters: a pointer to the input
   364  // type, a pointer to the output type, and a conversion.Scope (which should be
   365  // used if recursive conversion calls are desired).  It must return an error.
   366  //
   367  // Example:
   368  // c.RegisterConversionFunc(
   369  //         func(in *Pod, out *v1.Pod, s Scope) error {
   370  //                 // conversion logic...
   371  //                 return nil
   372  //          })
   373  func (c *Converter) RegisterConversionFunc(conversionFunc interface{}) error {
   374  	return c.conversionFuncs.Add(conversionFunc)
   375  }
   376  
   377  // Similar to RegisterConversionFunc, but registers conversion function that were
   378  // automatically generated.
   379  func (c *Converter) RegisterGeneratedConversionFunc(conversionFunc interface{}) error {
   380  	return c.generatedConversionFuncs.Add(conversionFunc)
   381  }
   382  
   383  // RegisterIgnoredConversion registers a "no-op" for conversion, where any requested
   384  // conversion between from and to is ignored.
   385  func (c *Converter) RegisterIgnoredConversion(from, to interface{}) error {
   386  	typeFrom := reflect.TypeOf(from)
   387  	typeTo := reflect.TypeOf(to)
   388  	if reflect.TypeOf(from).Kind() != reflect.Ptr {
   389  		return fmt.Errorf("expected pointer arg for 'from' param 0, got: %v", typeFrom)
   390  	}
   391  	if typeTo.Kind() != reflect.Ptr {
   392  		return fmt.Errorf("expected pointer arg for 'to' param 1, got: %v", typeTo)
   393  	}
   394  	c.ignoredConversions[typePair{typeFrom.Elem(), typeTo.Elem()}] = struct{}{}
   395  	return nil
   396  }
   397  
   398  // IsConversionIgnored returns true if the specified objects should be dropped during
   399  // conversion.
   400  func (c *Converter) IsConversionIgnored(inType, outType reflect.Type) bool {
   401  	_, found := c.ignoredConversions[typePair{inType, outType}]
   402  	return found
   403  }
   404  
   405  func (c *Converter) HasConversionFunc(inType, outType reflect.Type) bool {
   406  	_, found := c.conversionFuncs.fns[typePair{inType, outType}]
   407  	return found
   408  }
   409  
   410  func (c *Converter) ConversionFuncValue(inType, outType reflect.Type) (reflect.Value, bool) {
   411  	value, found := c.conversionFuncs.fns[typePair{inType, outType}]
   412  	return value, found
   413  }
   414  
   415  // SetStructFieldCopy registers a correspondence. Whenever a struct field is encountered
   416  // which has a type and name matching srcFieldType and srcFieldName, it wil be copied
   417  // into the field in the destination struct matching destFieldType & Name, if such a
   418  // field exists.
   419  // May be called multiple times, even for the same source field & type--all applicable
   420  // copies will be performed.
   421  func (c *Converter) SetStructFieldCopy(srcFieldType interface{}, srcFieldName string, destFieldType interface{}, destFieldName string) error {
   422  	st := reflect.TypeOf(srcFieldType)
   423  	dt := reflect.TypeOf(destFieldType)
   424  	srcKey := typeNamePair{st, srcFieldName}
   425  	destKey := typeNamePair{dt, destFieldName}
   426  	c.structFieldDests[srcKey] = append(c.structFieldDests[srcKey], destKey)
   427  	c.structFieldSources[destKey] = append(c.structFieldSources[destKey], srcKey)
   428  	return nil
   429  }
   430  
   431  // RegisterDefaultingFunc registers a value-defaulting func with the Converter.
   432  // defaultingFunc must take one parameters: a pointer to the input type.
   433  //
   434  // Example:
   435  // c.RegisteDefaultingFunc(
   436  //         func(in *v1.Pod) {
   437  //                 // defaulting logic...
   438  //          })
   439  func (c *Converter) RegisterDefaultingFunc(defaultingFunc interface{}) error {
   440  	fv := reflect.ValueOf(defaultingFunc)
   441  	ft := fv.Type()
   442  	if ft.Kind() != reflect.Func {
   443  		return fmt.Errorf("expected func, got: %v", ft)
   444  	}
   445  	if ft.NumIn() != 1 {
   446  		return fmt.Errorf("expected one 'in' param, got: %v", ft)
   447  	}
   448  	if ft.NumOut() != 0 {
   449  		return fmt.Errorf("expected zero 'out' params, got: %v", ft)
   450  	}
   451  	if ft.In(0).Kind() != reflect.Ptr {
   452  		return fmt.Errorf("expected pointer arg for 'in' param 0, got: %v", ft)
   453  	}
   454  	inType := ft.In(0).Elem()
   455  	c.defaultingFuncs[inType] = fv
   456  	c.defaultingInterfaces[inType] = defaultingFunc
   457  	return nil
   458  }
   459  
   460  // RegisterInputDefaults registers a field name mapping function, used when converting
   461  // from maps to structs. Inputs to the conversion methods are checked for this type and a mapping
   462  // applied automatically if the input matches in. A set of default flags for the input conversion
   463  // may also be provided, which will be used when no explicit flags are requested.
   464  func (c *Converter) RegisterInputDefaults(in interface{}, fn FieldMappingFunc, defaultFlags FieldMatchingFlags) error {
   465  	fv := reflect.ValueOf(in)
   466  	ft := fv.Type()
   467  	if ft.Kind() != reflect.Ptr {
   468  		return fmt.Errorf("expected pointer 'in' argument, got: %v", ft)
   469  	}
   470  	c.inputFieldMappingFuncs[ft] = fn
   471  	c.inputDefaultFlags[ft] = defaultFlags
   472  	return nil
   473  }
   474  
   475  // FieldMatchingFlags contains a list of ways in which struct fields could be
   476  // copied. These constants may be | combined.
   477  type FieldMatchingFlags int
   478  
   479  const (
   480  	// Loop through destination fields, search for matching source
   481  	// field to copy it from. Source fields with no corresponding
   482  	// destination field will be ignored. If SourceToDest is
   483  	// specified, this flag is ignored. If neither is specified,
   484  	// or no flags are passed, this flag is the default.
   485  	DestFromSource FieldMatchingFlags = 0
   486  	// Loop through source fields, search for matching dest field
   487  	// to copy it into. Destination fields with no corresponding
   488  	// source field will be ignored.
   489  	SourceToDest FieldMatchingFlags = 1 << iota
   490  	// Don't treat it as an error if the corresponding source or
   491  	// dest field can't be found.
   492  	IgnoreMissingFields
   493  	// Don't require type names to match.
   494  	AllowDifferentFieldTypeNames
   495  )
   496  
   497  // IsSet returns true if the given flag or combination of flags is set.
   498  func (f FieldMatchingFlags) IsSet(flag FieldMatchingFlags) bool {
   499  	if flag == DestFromSource {
   500  		// The bit logic doesn't work on the default value.
   501  		return f&SourceToDest != SourceToDest
   502  	}
   503  	return f&flag == flag
   504  }
   505  
   506  // Convert will translate src to dest if it knows how. Both must be pointers.
   507  // If no conversion func is registered and the default copying mechanism
   508  // doesn't work on this type pair, an error will be returned.
   509  // Read the comments on the various FieldMatchingFlags constants to understand
   510  // what the 'flags' parameter does.
   511  // 'meta' is given to allow you to pass information to conversion functions,
   512  // it is not used by Convert() other than storing it in the scope.
   513  // Not safe for objects with cyclic references!
   514  func (c *Converter) Convert(src, dest interface{}, flags FieldMatchingFlags, meta *Meta) error {
   515  	if len(c.genericConversions) > 0 {
   516  		// TODO: avoid scope allocation
   517  		s := &scope{converter: c, flags: flags, meta: meta}
   518  		for _, fn := range c.genericConversions {
   519  			if ok, err := fn(src, dest, s); ok {
   520  				return err
   521  			}
   522  		}
   523  	}
   524  	return c.doConversion(src, dest, flags, meta, c.convert)
   525  }
   526  
   527  // DefaultConvert will translate src to dest if it knows how. Both must be pointers.
   528  // No conversion func is used. If the default copying mechanism
   529  // doesn't work on this type pair, an error will be returned.
   530  // Read the comments on the various FieldMatchingFlags constants to understand
   531  // what the 'flags' parameter does.
   532  // 'meta' is given to allow you to pass information to conversion functions,
   533  // it is not used by DefaultConvert() other than storing it in the scope.
   534  // Not safe for objects with cyclic references!
   535  func (c *Converter) DefaultConvert(src, dest interface{}, flags FieldMatchingFlags, meta *Meta) error {
   536  	return c.doConversion(src, dest, flags, meta, c.defaultConvert)
   537  }
   538  
   539  type conversionFunc func(sv, dv reflect.Value, scope *scope) error
   540  
   541  func (c *Converter) doConversion(src, dest interface{}, flags FieldMatchingFlags, meta *Meta, f conversionFunc) error {
   542  	dv, err := EnforcePtr(dest)
   543  	if err != nil {
   544  		return err
   545  	}
   546  	if !dv.CanAddr() && !dv.CanSet() {
   547  		return fmt.Errorf("can't write to dest")
   548  	}
   549  	sv, err := EnforcePtr(src)
   550  	if err != nil {
   551  		return err
   552  	}
   553  	s := &scope{
   554  		converter: c,
   555  		flags:     flags,
   556  		meta:      meta,
   557  	}
   558  	// Leave something on the stack, so that calls to struct tag getters never fail.
   559  	s.srcStack.push(scopeStackElem{})
   560  	s.destStack.push(scopeStackElem{})
   561  	return f(sv, dv, s)
   562  }
   563  
   564  // callCustom calls 'custom' with sv & dv. custom must be a conversion function.
   565  func (c *Converter) callCustom(sv, dv, custom reflect.Value, scope *scope) error {
   566  	if !sv.CanAddr() {
   567  		sv2 := reflect.New(sv.Type())
   568  		sv2.Elem().Set(sv)
   569  		sv = sv2
   570  	} else {
   571  		sv = sv.Addr()
   572  	}
   573  	if !dv.CanAddr() {
   574  		if !dv.CanSet() {
   575  			return scope.errorf("can't addr or set dest.")
   576  		}
   577  		dvOrig := dv
   578  		dv := reflect.New(dvOrig.Type())
   579  		defer func() { dvOrig.Set(dv) }()
   580  	} else {
   581  		dv = dv.Addr()
   582  	}
   583  	args := []reflect.Value{sv, dv, reflect.ValueOf(scope)}
   584  	ret := custom.Call(args)[0].Interface()
   585  	// This convolution is necessary because nil interfaces won't convert
   586  	// to errors.
   587  	if ret == nil {
   588  		return nil
   589  	}
   590  	return ret.(error)
   591  }
   592  
   593  // convert recursively copies sv into dv, calling an appropriate conversion function if
   594  // one is registered.
   595  func (c *Converter) convert(sv, dv reflect.Value, scope *scope) error {
   596  	dt, st := dv.Type(), sv.Type()
   597  	// Apply default values.
   598  	if fv, ok := c.defaultingFuncs[st]; ok {
   599  		if c.Debug != nil {
   600  			c.Debug.Logf("Applying defaults for '%v'", st)
   601  		}
   602  		args := []reflect.Value{sv.Addr()}
   603  		fv.Call(args)
   604  	}
   605  
   606  	pair := typePair{st, dt}
   607  
   608  	// ignore conversions of this type
   609  	if _, ok := c.ignoredConversions[pair]; ok {
   610  		if c.Debug != nil {
   611  			c.Debug.Logf("Ignoring conversion of '%v' to '%v'", st, dt)
   612  		}
   613  		return nil
   614  	}
   615  
   616  	// Convert sv to dv.
   617  	if fv, ok := c.conversionFuncs.fns[pair]; ok {
   618  		if c.Debug != nil {
   619  			c.Debug.Logf("Calling custom conversion of '%v' to '%v'", st, dt)
   620  		}
   621  		return c.callCustom(sv, dv, fv, scope)
   622  	}
   623  	if fv, ok := c.generatedConversionFuncs.fns[pair]; ok {
   624  		if c.Debug != nil {
   625  			c.Debug.Logf("Calling generated conversion of '%v' to '%v'", st, dt)
   626  		}
   627  		return c.callCustom(sv, dv, fv, scope)
   628  	}
   629  
   630  	return c.defaultConvert(sv, dv, scope)
   631  }
   632  
   633  // defaultConvert recursively copies sv into dv. no conversion function is called
   634  // for the current stack frame (but conversion functions may be called for nested objects)
   635  func (c *Converter) defaultConvert(sv, dv reflect.Value, scope *scope) error {
   636  	dt, st := dv.Type(), sv.Type()
   637  
   638  	if !dv.CanSet() {
   639  		return scope.errorf("Cannot set dest. (Tried to deep copy something with unexported fields?)")
   640  	}
   641  
   642  	if !scope.flags.IsSet(AllowDifferentFieldTypeNames) && c.nameFunc(dt) != c.nameFunc(st) {
   643  		return scope.errorf(
   644  			"type names don't match (%v, %v), and no conversion 'func (%v, %v) error' registered.",
   645  			c.nameFunc(st), c.nameFunc(dt), st, dt)
   646  	}
   647  
   648  	switch st.Kind() {
   649  	case reflect.Map, reflect.Ptr, reflect.Slice, reflect.Interface, reflect.Struct:
   650  		// Don't copy these via assignment/conversion!
   651  	default:
   652  		// This should handle all simple types.
   653  		if st.AssignableTo(dt) {
   654  			dv.Set(sv)
   655  			return nil
   656  		}
   657  		if st.ConvertibleTo(dt) {
   658  			dv.Set(sv.Convert(dt))
   659  			return nil
   660  		}
   661  	}
   662  
   663  	if c.Debug != nil {
   664  		c.Debug.Logf("Trying to convert '%v' to '%v'", st, dt)
   665  	}
   666  
   667  	scope.srcStack.push(scopeStackElem{value: sv})
   668  	scope.destStack.push(scopeStackElem{value: dv})
   669  	defer scope.srcStack.pop()
   670  	defer scope.destStack.pop()
   671  
   672  	switch dv.Kind() {
   673  	case reflect.Struct:
   674  		return c.convertKV(toKVValue(sv), toKVValue(dv), scope)
   675  	case reflect.Slice:
   676  		if sv.IsNil() {
   677  			// Don't make a zero-length slice.
   678  			dv.Set(reflect.Zero(dt))
   679  			return nil
   680  		}
   681  		dv.Set(reflect.MakeSlice(dt, sv.Len(), sv.Cap()))
   682  		for i := 0; i < sv.Len(); i++ {
   683  			scope.setIndices(i, i)
   684  			if err := c.convert(sv.Index(i), dv.Index(i), scope); err != nil {
   685  				return err
   686  			}
   687  		}
   688  	case reflect.Ptr:
   689  		if sv.IsNil() {
   690  			// Don't copy a nil ptr!
   691  			dv.Set(reflect.Zero(dt))
   692  			return nil
   693  		}
   694  		dv.Set(reflect.New(dt.Elem()))
   695  		switch st.Kind() {
   696  		case reflect.Ptr, reflect.Interface:
   697  			return c.convert(sv.Elem(), dv.Elem(), scope)
   698  		default:
   699  			return c.convert(sv, dv.Elem(), scope)
   700  		}
   701  	case reflect.Map:
   702  		if sv.IsNil() {
   703  			// Don't copy a nil ptr!
   704  			dv.Set(reflect.Zero(dt))
   705  			return nil
   706  		}
   707  		dv.Set(reflect.MakeMap(dt))
   708  		for _, sk := range sv.MapKeys() {
   709  			dk := reflect.New(dt.Key()).Elem()
   710  			if err := c.convert(sk, dk, scope); err != nil {
   711  				return err
   712  			}
   713  			dkv := reflect.New(dt.Elem()).Elem()
   714  			scope.setKeys(sk.Interface(), dk.Interface())
   715  			// TODO:  sv.MapIndex(sk) may return a value with CanAddr() == false,
   716  			// because a map[string]struct{} does not allow a pointer reference.
   717  			// Calling a custom conversion function defined for the map value
   718  			// will panic. Example is PodInfo map[string]ContainerStatus.
   719  			if err := c.convert(sv.MapIndex(sk), dkv, scope); err != nil {
   720  				return err
   721  			}
   722  			dv.SetMapIndex(dk, dkv)
   723  		}
   724  	case reflect.Interface:
   725  		if sv.IsNil() {
   726  			// Don't copy a nil interface!
   727  			dv.Set(reflect.Zero(dt))
   728  			return nil
   729  		}
   730  		tmpdv := reflect.New(sv.Elem().Type()).Elem()
   731  		if err := c.convert(sv.Elem(), tmpdv, scope); err != nil {
   732  			return err
   733  		}
   734  		dv.Set(reflect.ValueOf(tmpdv.Interface()))
   735  		return nil
   736  	default:
   737  		return scope.errorf("couldn't copy '%v' into '%v'; didn't understand types", st, dt)
   738  	}
   739  	return nil
   740  }
   741  
   742  var stringType = reflect.TypeOf("")
   743  
   744  func toKVValue(v reflect.Value) kvValue {
   745  	switch v.Kind() {
   746  	case reflect.Struct:
   747  		return structAdaptor(v)
   748  	case reflect.Map:
   749  		if v.Type().Key().AssignableTo(stringType) {
   750  			return stringMapAdaptor(v)
   751  		}
   752  	}
   753  
   754  	return nil
   755  }
   756  
   757  // kvValue lets us write the same conversion logic to work with both maps
   758  // and structs. Only maps with string keys make sense for this.
   759  type kvValue interface {
   760  	// returns all keys, as a []string.
   761  	keys() []string
   762  	// Will just return "" for maps.
   763  	tagOf(key string) reflect.StructTag
   764  	// Will return the zero Value if the key doesn't exist.
   765  	value(key string) reflect.Value
   766  	// Maps require explicit setting-- will do nothing for structs.
   767  	// Returns false on failure.
   768  	confirmSet(key string, v reflect.Value) bool
   769  }
   770  
   771  type stringMapAdaptor reflect.Value
   772  
   773  func (a stringMapAdaptor) len() int {
   774  	return reflect.Value(a).Len()
   775  }
   776  
   777  func (a stringMapAdaptor) keys() []string {
   778  	v := reflect.Value(a)
   779  	keys := make([]string, v.Len())
   780  	for i, v := range v.MapKeys() {
   781  		if v.IsNil() {
   782  			continue
   783  		}
   784  		switch t := v.Interface().(type) {
   785  		case string:
   786  			keys[i] = t
   787  		}
   788  	}
   789  	return keys
   790  }
   791  
   792  func (a stringMapAdaptor) tagOf(key string) reflect.StructTag {
   793  	return ""
   794  }
   795  
   796  func (a stringMapAdaptor) value(key string) reflect.Value {
   797  	return reflect.Value(a).MapIndex(reflect.ValueOf(key))
   798  }
   799  
   800  func (a stringMapAdaptor) confirmSet(key string, v reflect.Value) bool {
   801  	return true
   802  }
   803  
   804  type structAdaptor reflect.Value
   805  
   806  func (a structAdaptor) len() int {
   807  	v := reflect.Value(a)
   808  	return v.Type().NumField()
   809  }
   810  
   811  func (a structAdaptor) keys() []string {
   812  	v := reflect.Value(a)
   813  	t := v.Type()
   814  	keys := make([]string, t.NumField())
   815  	for i := range keys {
   816  		keys[i] = t.Field(i).Name
   817  	}
   818  	return keys
   819  }
   820  
   821  func (a structAdaptor) tagOf(key string) reflect.StructTag {
   822  	v := reflect.Value(a)
   823  	field, ok := v.Type().FieldByName(key)
   824  	if ok {
   825  		return field.Tag
   826  	}
   827  	return ""
   828  }
   829  
   830  func (a structAdaptor) value(key string) reflect.Value {
   831  	v := reflect.Value(a)
   832  	return v.FieldByName(key)
   833  }
   834  
   835  func (a structAdaptor) confirmSet(key string, v reflect.Value) bool {
   836  	return true
   837  }
   838  
   839  // convertKV can convert things that consist of key/value pairs, like structs
   840  // and some maps.
   841  func (c *Converter) convertKV(skv, dkv kvValue, scope *scope) error {
   842  	if skv == nil || dkv == nil {
   843  		// TODO: add keys to stack to support really understandable error messages.
   844  		return fmt.Errorf("Unable to convert %#v to %#v", skv, dkv)
   845  	}
   846  
   847  	lister := dkv
   848  	if scope.flags.IsSet(SourceToDest) {
   849  		lister = skv
   850  	}
   851  
   852  	var mapping FieldMappingFunc
   853  	if scope.meta != nil && scope.meta.KeyNameMapping != nil {
   854  		mapping = scope.meta.KeyNameMapping
   855  	}
   856  
   857  	for _, key := range lister.keys() {
   858  		if found, err := c.checkField(key, skv, dkv, scope); found {
   859  			if err != nil {
   860  				return err
   861  			}
   862  			continue
   863  		}
   864  		stag := skv.tagOf(key)
   865  		dtag := dkv.tagOf(key)
   866  		skey := key
   867  		dkey := key
   868  		if mapping != nil {
   869  			skey, dkey = scope.meta.KeyNameMapping(key, stag, dtag)
   870  		}
   871  
   872  		df := dkv.value(dkey)
   873  		sf := skv.value(skey)
   874  		if !df.IsValid() || !sf.IsValid() {
   875  			switch {
   876  			case scope.flags.IsSet(IgnoreMissingFields):
   877  				// No error.
   878  			case scope.flags.IsSet(SourceToDest):
   879  				return scope.errorf("%v not present in dest", dkey)
   880  			default:
   881  				return scope.errorf("%v not present in src", skey)
   882  			}
   883  			continue
   884  		}
   885  		scope.srcStack.top().key = skey
   886  		scope.srcStack.top().tag = stag
   887  		scope.destStack.top().key = dkey
   888  		scope.destStack.top().tag = dtag
   889  		if err := c.convert(sf, df, scope); err != nil {
   890  			return err
   891  		}
   892  	}
   893  	return nil
   894  }
   895  
   896  // checkField returns true if the field name matches any of the struct
   897  // field copying rules. The error should be ignored if it returns false.
   898  func (c *Converter) checkField(fieldName string, skv, dkv kvValue, scope *scope) (bool, error) {
   899  	replacementMade := false
   900  	if scope.flags.IsSet(DestFromSource) {
   901  		df := dkv.value(fieldName)
   902  		if !df.IsValid() {
   903  			return false, nil
   904  		}
   905  		destKey := typeNamePair{df.Type(), fieldName}
   906  		// Check each of the potential source (type, name) pairs to see if they're
   907  		// present in sv.
   908  		for _, potentialSourceKey := range c.structFieldSources[destKey] {
   909  			sf := skv.value(potentialSourceKey.fieldName)
   910  			if !sf.IsValid() {
   911  				continue
   912  			}
   913  			if sf.Type() == potentialSourceKey.fieldType {
   914  				// Both the source's name and type matched, so copy.
   915  				scope.srcStack.top().key = potentialSourceKey.fieldName
   916  				scope.destStack.top().key = fieldName
   917  				if err := c.convert(sf, df, scope); err != nil {
   918  					return true, err
   919  				}
   920  				dkv.confirmSet(fieldName, df)
   921  				replacementMade = true
   922  			}
   923  		}
   924  		return replacementMade, nil
   925  	}
   926  
   927  	sf := skv.value(fieldName)
   928  	if !sf.IsValid() {
   929  		return false, nil
   930  	}
   931  	srcKey := typeNamePair{sf.Type(), fieldName}
   932  	// Check each of the potential dest (type, name) pairs to see if they're
   933  	// present in dv.
   934  	for _, potentialDestKey := range c.structFieldDests[srcKey] {
   935  		df := dkv.value(potentialDestKey.fieldName)
   936  		if !df.IsValid() {
   937  			continue
   938  		}
   939  		if df.Type() == potentialDestKey.fieldType {
   940  			// Both the dest's name and type matched, so copy.
   941  			scope.srcStack.top().key = fieldName
   942  			scope.destStack.top().key = potentialDestKey.fieldName
   943  			if err := c.convert(sf, df, scope); err != nil {
   944  				return true, err
   945  			}
   946  			dkv.confirmSet(potentialDestKey.fieldName, df)
   947  			replacementMade = true
   948  		}
   949  	}
   950  	return replacementMade, nil
   951  }