func (t *Type) LoadFields(levels int) error {
	if t.st == nil || levels == 0 {
		return nil
	}
	for i := 0; i < t.st.NumFields(); i++ {
		field, err := newField(t, i)
		if err != nil {
			return err
		}
		switch {
		case field == nil:
		case field.Embedded:
			err := field.Type.LoadFields(-1)
			if err != nil {
				return err
			}
			for _, field := range field.Type.Fields {
				field.AccessName = fmt.Sprintf("%s.%s", field.ParentType.Name, field.Name())
				t.Fields = append(t.Fields, field)
			}
		default:
			t.Fields = append(t.Fields, field)
		}
	}
	for _, field := range t.Fields {
		err := field.Type.LoadFields(levels - 1)
		if err != nil {
			return err
		}
	}
	return nil
}
LoadFields iterate over the type's data structure and load all it's fields
this function might recursively call to the New function
package load
import (
	"fmt"
	"go/types"
	"strings"
)
var basicTypes = map[string]bool{
	"bool":      true,
	"int":       true,
	"int8":      true,
	"int16":     true,
	"int32":     true,
	"int64":     true,
	"uint":      true,
	"uint8":     true,
	"uint16":    true,
	"uint32":    true,
	"uint64":    true,
	"float32":   true,
	"float64":   true,
	"string":    true,
	"[]byte":    true,
	"time.Time": true,
}
type AnnotatedType struct {
	*Type
	Pointer bool
	Slice   bool
}
type Type struct {
	Name string
	Fields      []*Field
	PrimaryKeys []*Field
	st  *types.Struct
	pkg *types.Package
}
func New(fullName string) (*AnnotatedType, error) {
	if fullName == "[]byte" || fullName == "*[]byte" {
		return &AnnotatedType{
			Type:    &Type{Name: strings.TrimLeft(fullName, "*")},
			Pointer: pointer(fullName),
		}, nil
	}
	t := &AnnotatedType{
		Type: &Type{
			Name: typeName(fullName),
		},
		Pointer: pointer(fullName),
		Slice:   slice(fullName),
	}
	if t.IsBasic() {
		return t, nil
	}
	err := t.loadStruct(importPath(fullName))
	if err != nil {
		return nil, err
	}
	return t, nil
}
func (t *Type) ImportPath() string {
	if t.pkg == nil {
		return ""
	}
	return t.pkg.Path()
}