func (e TypeReflectCacheEntry) CanConvertToUnstructured() bool {
	return e.isJsonMarshaler || e.ptrIsJsonMarshaler || e.isStringConvertable || e.ptrIsStringConvertable
}
CanConvertToUnstructured returns true if this TypeReflectCacheEntry can convert values of its type to unstructured.
package value
import (
	"bytes"
	"encoding/json"
	"fmt"
	"reflect"
	"sort"
	"sync"
	"sync/atomic"
)
type UnstructuredConverter interface {
	json.Marshaler  
	ToUnstructured() interface{}
}
type TypeReflectCacheEntry struct {
	isJsonMarshaler        bool
	ptrIsJsonMarshaler     bool
	isJsonUnmarshaler      bool
	ptrIsJsonUnmarshaler   bool
	isStringConvertable    bool
	ptrIsStringConvertable bool
	structFields        map[string]*FieldCacheEntry
	orderedStructFields []*FieldCacheEntry
}
type FieldCacheEntry struct {
	JsonName string
	isOmitEmpty bool
	fieldPath [][]int
	fieldType reflect.Type
	TypeEntry *TypeReflectCacheEntry
}
func (f *FieldCacheEntry) CanOmit(fieldVal reflect.Value) bool {
	return f.isOmitEmpty && (safeIsNil(fieldVal) || isZero(fieldVal))
}
func (f *FieldCacheEntry) GetFrom(structVal reflect.Value) reflect.Value {
	for _, elem := range f.fieldPath {
		structVal = dereference(structVal).FieldByIndex(elem)
	}
	return structVal
}
var marshalerType = reflect.TypeOf(new(json.Marshaler)).Elem()
var unmarshalerType = reflect.TypeOf(new(json.Unmarshaler)).Elem()
var unstructuredConvertableType = reflect.TypeOf(new(UnstructuredConverter)).Elem()
var defaultReflectCache = newReflectCache()
func TypeReflectEntryOf(t reflect.Type) *TypeReflectCacheEntry {
	cm := defaultReflectCache.get()
	if record, ok := cm[t]; ok {
		return record
	}
	updates := reflectCacheMap{}
	result := typeReflectEntryOf(cm, t, updates)
	if len(updates) > 0 {
		defaultReflectCache.update(updates)
	}
	return result
}
func typeReflectEntryOf(cm reflectCacheMap, t reflect.Type, updates reflectCacheMap) *TypeReflectCacheEntry {
	if record, ok := cm[t]; ok {
		return record
	}
	if record, ok := updates[t]; ok {
		return record
	}
	typeEntry := &TypeReflectCacheEntry{
		isJsonMarshaler:        t.Implements(marshalerType),
		ptrIsJsonMarshaler:     reflect.PtrTo(t).Implements(marshalerType),
		isJsonUnmarshaler:      reflect.PtrTo(t).Implements(unmarshalerType),
		isStringConvertable:    t.Implements(unstructuredConvertableType),
		ptrIsStringConvertable: reflect.PtrTo(t).Implements(unstructuredConvertableType),
	}
	if t.Kind() == reflect.Struct {
		fieldEntries := map[string]*FieldCacheEntry{}
		buildStructCacheEntry(t, fieldEntries, nil)
		typeEntry.structFields = fieldEntries
		sortedByJsonName := make([]*FieldCacheEntry, len(fieldEntries))
		i := 0
		for _, entry := range fieldEntries {
			sortedByJsonName[i] = entry
			i++
		}
		sort.Slice(sortedByJsonName, func(i, j int) bool {
			return sortedByJsonName[i].JsonName < sortedByJsonName[j].JsonName
		})
		typeEntry.orderedStructFields = sortedByJsonName
	}
	updates[t] = typeEntry
	for _, field := range typeEntry.structFields {
		if field.TypeEntry == nil {
			field.TypeEntry = typeReflectEntryOf(cm, field.fieldType, updates)
		}
	}
	return typeEntry
}
func buildStructCacheEntry(t reflect.Type, infos map[string]*FieldCacheEntry, fieldPath [][]int) {
	for i := 0; i < t.NumField(); i++ {
		field := t.Field(i)
		jsonName, omit, isInline, isOmitempty := lookupJsonTags(field)
		if omit {
			continue
		}
		if isInline {
			e := field.Type
			if field.Type.Kind() == reflect.Ptr {
				e = field.Type.Elem()
			}
			buildStructCacheEntry(e, infos, append(fieldPath, field.Index))
			continue
		}
		info := &FieldCacheEntry{JsonName: jsonName, isOmitEmpty: isOmitempty, fieldPath: append(fieldPath, field.Index), fieldType: field.Type}
		infos[jsonName] = info
	}
}
func (e TypeReflectCacheEntry) Fields() map[string]*FieldCacheEntry {
	return e.structFields
}
func (e TypeReflectCacheEntry) OrderedFields() []*FieldCacheEntry {
	return e.orderedStructFields
}