converter.go 28 KB

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