cloner.go 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249
  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. // Cloner knows how to copy one type to another.
  19. type Cloner struct {
  20. // Map from the type to a function which can do the deep copy.
  21. deepCopyFuncs map[reflect.Type]reflect.Value
  22. generatedDeepCopyFuncs map[reflect.Type]func(in interface{}, out interface{}, c *Cloner) error
  23. }
  24. // NewCloner creates a new Cloner object.
  25. func NewCloner() *Cloner {
  26. c := &Cloner{
  27. deepCopyFuncs: map[reflect.Type]reflect.Value{},
  28. generatedDeepCopyFuncs: map[reflect.Type]func(in interface{}, out interface{}, c *Cloner) error{},
  29. }
  30. if err := c.RegisterDeepCopyFunc(byteSliceDeepCopy); err != nil {
  31. // If one of the deep-copy functions is malformed, detect it immediately.
  32. panic(err)
  33. }
  34. return c
  35. }
  36. // Prevent recursing into every byte...
  37. func byteSliceDeepCopy(in *[]byte, out *[]byte, c *Cloner) error {
  38. if *in != nil {
  39. *out = make([]byte, len(*in))
  40. copy(*out, *in)
  41. } else {
  42. *out = nil
  43. }
  44. return nil
  45. }
  46. // Verifies whether a deep-copy function has a correct signature.
  47. func verifyDeepCopyFunctionSignature(ft reflect.Type) error {
  48. if ft.Kind() != reflect.Func {
  49. return fmt.Errorf("expected func, got: %v", ft)
  50. }
  51. if ft.NumIn() != 3 {
  52. return fmt.Errorf("expected three 'in' params, got %v", ft)
  53. }
  54. if ft.NumOut() != 1 {
  55. return fmt.Errorf("expected one 'out' param, got %v", ft)
  56. }
  57. if ft.In(0).Kind() != reflect.Ptr {
  58. return fmt.Errorf("expected pointer arg for 'in' param 0, got: %v", ft)
  59. }
  60. if ft.In(1) != ft.In(0) {
  61. return fmt.Errorf("expected 'in' param 0 the same as param 1, got: %v", ft)
  62. }
  63. var forClonerType Cloner
  64. if expected := reflect.TypeOf(&forClonerType); ft.In(2) != expected {
  65. return fmt.Errorf("expected '%v' arg for 'in' param 2, got: '%v'", expected, ft.In(2))
  66. }
  67. var forErrorType error
  68. // This convolution is necessary, otherwise TypeOf picks up on the fact
  69. // that forErrorType is nil
  70. errorType := reflect.TypeOf(&forErrorType).Elem()
  71. if ft.Out(0) != errorType {
  72. return fmt.Errorf("expected error return, got: %v", ft)
  73. }
  74. return nil
  75. }
  76. // RegisterGeneratedDeepCopyFunc registers a copying func with the Cloner.
  77. // deepCopyFunc must take three parameters: a type input, a pointer to a
  78. // type output, and a pointer to Cloner. It should return an error.
  79. //
  80. // Example:
  81. // c.RegisterGeneratedDeepCopyFunc(
  82. // func(in Pod, out *Pod, c *Cloner) error {
  83. // // deep copy logic...
  84. // return nil
  85. // })
  86. func (c *Cloner) RegisterDeepCopyFunc(deepCopyFunc interface{}) error {
  87. fv := reflect.ValueOf(deepCopyFunc)
  88. ft := fv.Type()
  89. if err := verifyDeepCopyFunctionSignature(ft); err != nil {
  90. return err
  91. }
  92. c.deepCopyFuncs[ft.In(0)] = fv
  93. return nil
  94. }
  95. // GeneratedDeepCopyFunc bundles an untyped generated deep-copy function of a type
  96. // with a reflection type object used as a key to lookup the deep-copy function.
  97. type GeneratedDeepCopyFunc struct {
  98. Fn func(in interface{}, out interface{}, c *Cloner) error
  99. InType reflect.Type
  100. }
  101. // Similar to RegisterDeepCopyFunc, but registers deep copy function that were
  102. // automatically generated.
  103. func (c *Cloner) RegisterGeneratedDeepCopyFunc(fn GeneratedDeepCopyFunc) error {
  104. c.generatedDeepCopyFuncs[fn.InType] = fn.Fn
  105. return nil
  106. }
  107. // DeepCopy will perform a deep copy of a given object.
  108. func (c *Cloner) DeepCopy(in interface{}) (interface{}, error) {
  109. // Can be invalid if we run DeepCopy(X) where X is a nil interface type.
  110. // For example, we get an invalid value when someone tries to deep-copy
  111. // a nil labels.Selector.
  112. // This does not occur if X is nil and is a pointer to a concrete type.
  113. if in == nil {
  114. return nil, nil
  115. }
  116. inValue := reflect.ValueOf(in)
  117. outValue, err := c.deepCopy(inValue)
  118. if err != nil {
  119. return nil, err
  120. }
  121. return outValue.Interface(), nil
  122. }
  123. func (c *Cloner) deepCopy(src reflect.Value) (reflect.Value, error) {
  124. inType := src.Type()
  125. switch src.Kind() {
  126. case reflect.Interface, reflect.Ptr, reflect.Map, reflect.Slice:
  127. if src.IsNil() {
  128. return src, nil
  129. }
  130. }
  131. if fv, ok := c.deepCopyFuncs[inType]; ok {
  132. return c.customDeepCopy(src, fv)
  133. }
  134. if fv, ok := c.generatedDeepCopyFuncs[inType]; ok {
  135. var outValue reflect.Value
  136. outValue = reflect.New(inType.Elem())
  137. err := fv(src.Interface(), outValue.Interface(), c)
  138. return outValue, err
  139. }
  140. return c.defaultDeepCopy(src)
  141. }
  142. func (c *Cloner) customDeepCopy(src, fv reflect.Value) (reflect.Value, error) {
  143. outValue := reflect.New(src.Type().Elem())
  144. args := []reflect.Value{src, outValue, reflect.ValueOf(c)}
  145. result := fv.Call(args)[0].Interface()
  146. // This convolution is necessary because nil interfaces won't convert
  147. // to error.
  148. if result == nil {
  149. return outValue, nil
  150. }
  151. return outValue, result.(error)
  152. }
  153. func (c *Cloner) defaultDeepCopy(src reflect.Value) (reflect.Value, error) {
  154. switch src.Kind() {
  155. case reflect.Chan, reflect.Func, reflect.UnsafePointer, reflect.Uintptr:
  156. return src, fmt.Errorf("cannot deep copy kind: %s", src.Kind())
  157. case reflect.Array:
  158. dst := reflect.New(src.Type())
  159. for i := 0; i < src.Len(); i++ {
  160. copyVal, err := c.deepCopy(src.Index(i))
  161. if err != nil {
  162. return src, err
  163. }
  164. dst.Elem().Index(i).Set(copyVal)
  165. }
  166. return dst.Elem(), nil
  167. case reflect.Interface:
  168. if src.IsNil() {
  169. return src, nil
  170. }
  171. return c.deepCopy(src.Elem())
  172. case reflect.Map:
  173. if src.IsNil() {
  174. return src, nil
  175. }
  176. dst := reflect.MakeMap(src.Type())
  177. for _, k := range src.MapKeys() {
  178. copyVal, err := c.deepCopy(src.MapIndex(k))
  179. if err != nil {
  180. return src, err
  181. }
  182. dst.SetMapIndex(k, copyVal)
  183. }
  184. return dst, nil
  185. case reflect.Ptr:
  186. if src.IsNil() {
  187. return src, nil
  188. }
  189. dst := reflect.New(src.Type().Elem())
  190. copyVal, err := c.deepCopy(src.Elem())
  191. if err != nil {
  192. return src, err
  193. }
  194. dst.Elem().Set(copyVal)
  195. return dst, nil
  196. case reflect.Slice:
  197. if src.IsNil() {
  198. return src, nil
  199. }
  200. dst := reflect.MakeSlice(src.Type(), 0, src.Len())
  201. for i := 0; i < src.Len(); i++ {
  202. copyVal, err := c.deepCopy(src.Index(i))
  203. if err != nil {
  204. return src, err
  205. }
  206. dst = reflect.Append(dst, copyVal)
  207. }
  208. return dst, nil
  209. case reflect.Struct:
  210. dst := reflect.New(src.Type())
  211. for i := 0; i < src.NumField(); i++ {
  212. if !dst.Elem().Field(i).CanSet() {
  213. // Can't set private fields. At this point, the
  214. // best we can do is a shallow copy. For
  215. // example, time.Time is a value type with
  216. // private members that can be shallow copied.
  217. return src, nil
  218. }
  219. copyVal, err := c.deepCopy(src.Field(i))
  220. if err != nil {
  221. return src, err
  222. }
  223. dst.Elem().Field(i).Set(copyVal)
  224. }
  225. return dst.Elem(), nil
  226. default:
  227. // Value types like numbers, booleans, and strings.
  228. return src, nil
  229. }
  230. }