converter.go 30 KB

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