The Object instances are as follows. They are basically in the pkg/apis directory, you can find it yourself.
Unstructured
The scene of Unstructured and Object cooperation is as follows.
The example diagram is as follows.
Scheme
Builder
Scheme
Look at the definition of Scheme, the first four are maintained the relationship between reflect.Type and Schema.GroupVersionKind. The defaulterFuncs is used to build a default object.
typeSchemestruct {// versionMap allows one to figure out the go type of an object with// the given version and name. gvkToType map[schema.GroupVersionKind]reflect.Type// typeToGroupVersion allows one to find metadata for a given go object.// The reflect.Type we index by should *not* be a pointer. typeToGVK map[reflect.Type][]schema.GroupVersionKind// unversionedTypes are transformed without conversion in ConvertToVersion. unversionedTypes map[reflect.Type]schema.GroupVersionKind// unversionedKinds are the names of kinds that can be created in the context of any group// or version// TODO: resolve the status of unversioned types. unversionedKinds map[string]reflect.Type// Map from version and resource to the corresponding func to convert// resource field labels in that version to internal version. fieldLabelConversionFuncs map[schema.GroupVersionKind]FieldLabelConversionFunc// defaulterFuncs is an array of interfaces to be called with an object to provide defaulting// the provided object must be a pointer. defaulterFuncs map[reflect.Type]func(interface{})// converter stores all registered conversion functions. It also has// default converting behavior. converter *conversion.Converter// versionPriority is a map of groups to ordered lists of versions for those groups indicating the// default priorities of these versions as registered in the scheme versionPriority map[string][]string// observedVersions keeps track of the order we've seen versions during type registration observedVersions []schema.GroupVersion// schemeName is the name of this scheme. If you don't specify a name, the stack of the NewScheme caller will be used.// This is useful for error reporting to indicate the origin of the scheme. schemeName string}
typeFieldLabelConversionFuncfunc(label, value string) (internalLabel, internalValue string, err error)
AddKnownTypes
AddKnownTypes only needs to pay attention to one problem, that is, the GroupVersionKind is generated from the incoming GroupVersion through the Name method of reflect.Type as the Kind. Please see the simplified sample Reflect Name Sample. The sample code can be executed under Go Playground.
AddUnversionedTypes
The principle of AddUnversionedTypes is as follows. Unversioned Type can be understood as an Object mounted on a Group, and the Version will never be updated.
nameFunc
The principle of nameFunc is as follows, just pay attention to the return type priority to Internal Type.
The typePair is used to represent the combination of source type and target type, typeNamePair stores the type and type name. DefaultNameFunc is used as the conversion method from the default type to Name. ConversionFunc defines the object conversion method.
Core Function Definitions
The DefaultNameFunc implementation is as follows.
var DefaultNameFunc =func(t reflect.Type) string { return t.Name() }
The ConversionFunc declaration is as follows.
typeConversionFuncfunc(a, b interface{}, scope Scope) error
FieldMappingFunc converts the key to Field in the source structure and the target structure.
typeFieldMappingFuncfunc(key string, sourceTag, destTag reflect.StructTag) (source string, dest string)
When Converter executes object conversion methods, such as Convert and DefaultConvert, it is allowed to pass in a Meta object and execute the doConversion method to construct the scope object in this method.
Scope
defaultConvert
The defaultConvert handles the default type conversion, the incoming sv, dv have been ensured to be addressable through EnforcePtr. This part of the code is a nearly perfect application of the reflect package in Go.
First, deal with the conversion of basic types, which can be converted by AssignableTo or ConvertibleTo.
switch st.Kind() {case reflect.Map, reflect.Ptr, reflect.Slice, reflect.Interface, reflect.Struct:// 这些类型后续处理default:// This should handle all simple types.if st.AssignableTo(dt) { dv.Set(sv)returnnil }if st.ConvertibleTo(dt) { dv.Set(sv.Convert(dt))returnnil }}
Then process them separately according to dv.Kind().
dv.Kind() -> reflect.Struct
Return the result of the convertKV method directly. However, you need to pay attention to first convert sv and dv into the form of Key/Value respectively. Please study the toKVValue method by yourself.