func (t *TagExpr) Field(fieldSelector string) (fh *FieldHandler, found bool) {
	f, ok := t.s.fields[fieldSelector]
	if !ok {
		return nil, false
	}
	return newFieldHandler(t, fieldSelector, f), true
}
Field returns the field handler specified by the selector.
package tagexpr
import (
	"errors"
	"fmt"
	"reflect"
	"strconv"
	"strings"
	"sync"
	"unsafe"
	"github.com/henrylee2cn/ameda"
)
type (
	Number  = float64
	Null    = interface{}
	Boolean = bool
	String  = string
)
type VM struct {
	tagName   string
	structJar map[uintptr]*structVM
	rw        sync.RWMutex
}
type structVM struct {
	vm                         *VM
	name                       string
	fields                     map[string]*fieldVM
	fieldSelectorList          []string
	fieldsWithIndirectStructVM []*fieldVM
	exprs                      map[string]*Expr
	exprSelectorList           []string
	ifaceTagExprGetters        []func(unsafe.Pointer, string, func(*TagExpr, error) error) error
}
type fieldVM struct {
	structField            reflect.StructField
	ptrDeep                int
	getPtr                 func(unsafe.Pointer) unsafe.Pointer
	elemType               reflect.Type
	elemKind               reflect.Kind
	valueGetter            func(unsafe.Pointer) interface{}
	reflectValueGetter     func(unsafe.Pointer, bool) reflect.Value
	exprs                  map[string]*Expr
	origin                 *structVM
	mapKeyStructVM         *structVM
	mapOrSliceElemStructVM *structVM
	mapOrSliceIfaceKinds   [2]bool  
	fieldSelector          string
	tagOp                  string
}
func New(tagName ...string) *VM {
	if len(tagName) == 0 {
		tagName = append(tagName, "")
	}
	return &VM{
		tagName:   tagName[0],
		structJar: make(map[uintptr]*structVM, 256),
	}
}
func (vm *VM) MustRun(structOrStructPtrOrReflectValue interface{}) *TagExpr {
	te, err := vm.Run(structOrStructPtrOrReflectValue)
	if err != nil {
		panic(err)
	}
	return te
}
var (
	unsupportNil        = errors.New("unsupport data: nil")
	unsupportCannotAddr = errors.New("unsupport data: can not addr")
)
func (vm *VM) Run(structPtrOrReflectValue interface{}) (*TagExpr, error) {
	var v reflect.Value
	switch t := structPtrOrReflectValue.(type) {
	case reflect.Value:
		v = ameda.DereferenceValue(t)
	default:
		v = ameda.DereferenceValue(reflect.ValueOf(t))
	}
	if err := checkStructMapAddr(v); err != nil {
		return nil, err
	}
	u := ameda.ValueFrom2(&v)
	ptr := unsafe.Pointer(u.Pointer())
	if ptr == nil {
		return nil, unsupportNil
	}
	tid := u.RuntimeTypeID()
	var err error
	vm.rw.RLock()
	s, ok := vm.structJar[tid]
	vm.rw.RUnlock()
	if !ok {
		vm.rw.Lock()
		s, ok = vm.structJar[tid]
		if !ok {
			s, err = vm.registerStructLocked(v.Type())
			if err != nil {
				vm.rw.Unlock()
				return nil, err
			}
		}
		vm.rw.Unlock()
	}
	return s.newTagExpr(ptr, ""), nil
}
func (vm *VM) RunAny(v interface{}, fn func(*TagExpr, error) error) error {
	vv, isReflectValue := v.(reflect.Value)
	if !isReflectValue {
		vv = reflect.ValueOf(v)
	}
	return vm.subRunAll(false, "", vv, fn)
}
func checkStructMapAddr(v reflect.Value) error {
	if !v.IsValid() || v.CanAddr() || v.NumField() != 1 || v.Field(0).Kind() != reflect.Map {
		return nil
	}
	return unsupportCannotAddr
}
func (vm *VM) subRunAll(omitNil bool, tePath string, value reflect.Value, fn func(*TagExpr, error) error) error {
	rv := ameda.DereferenceInterfaceValue(value)
	if !rv.IsValid() {
		return nil
	}
	rt := ameda.DereferenceType(rv.Type())
	rv = ameda.DereferenceValue(rv)
	switch rt.Kind() {
	case reflect.Struct:
		if len(tePath) == 0 {
			if err := checkStructMapAddr(rv); err != nil {
				return err
			}
		}
		u := ameda.ValueFrom2(&rv)
		ptr := unsafe.Pointer(u.Pointer())
		if ptr == nil {
			if omitNil {
				return nil
			}
			return fn(nil, unsupportNil)
		}
		return fn(vm.subRun(tePath, rt, u.RuntimeTypeID(), ptr))
	case reflect.Slice, reflect.Array:
		count := rv.Len()
		if count == 0 {
			return nil
		}
		switch ameda.DereferenceType(rv.Type().Elem()).Kind() {
		case reflect.Struct, reflect.Interface, reflect.Slice, reflect.Array, reflect.Map:
			for i := count - 1; i >= 0; i-- {
				err := vm.subRunAll(omitNil, tePath+"["+strconv.Itoa(i)+"]", rv.Index(i), fn)
				if err != nil {
					return err
				}
			}
		default:
			return nil
		}
	case reflect.Map:
		if rv.Len() == 0 {
			return nil
		}
		var canKey, canValue bool
		rt := rv.Type()
		switch ameda.DereferenceType(rt.Key()).Kind() {
		case reflect.Struct, reflect.Interface, reflect.Slice, reflect.Array, reflect.Map:
			canKey = true
		}
		switch ameda.DereferenceType(rt.Elem()).Kind() {
		case reflect.Struct, reflect.Interface, reflect.Slice, reflect.Array, reflect.Map:
			canValue = true
		}
		if !canKey && !canValue {
			return nil
		}
		for _, key := range rv.MapKeys() {
			if canKey {
				err := vm.subRunAll(omitNil, tePath+"{k}", key, fn)
				if err != nil {
					return err
				}
			}
			if canValue {
				err := vm.subRunAll(omitNil, tePath+"{v for k="+key.String()+"}", rv.MapIndex(key), fn)
				if err != nil {
					return err
				}
			}
		}
	}
	return nil
}
func (vm *VM) subRun(path string, t reflect.Type, tid uintptr, ptr unsafe.Pointer) (*TagExpr, error) {
	var err error
	vm.rw.RLock()
	s, ok := vm.structJar[tid]
	vm.rw.RUnlock()
	if !ok {
		vm.rw.Lock()
		s, ok = vm.structJar[tid]
		if !ok {
			s, err = vm.registerStructLocked(t)
			if err != nil {
				vm.rw.Unlock()
				return nil, err
			}
		}
		vm.rw.Unlock()
	}
	return s.newTagExpr(ptr, path), nil
}
func (vm *VM) registerStructLocked(structType reflect.Type) (*structVM, error) {
	structType, err := vm.getStructType(structType)
	if err != nil {
		return nil, err
	}
	tid := ameda.RuntimeTypeID(structType)
	s, had := vm.structJar[tid]
	if had {
		return s, nil
	}
	s = vm.newStructVM()
	s.name = structType.String()
	vm.structJar[tid] = s
	var numField = structType.NumField()
	var structField reflect.StructField
	var sub *structVM
	for i := 0; i < numField; i++ {
		structField = structType.Field(i)
		field, err := s.newFieldVM(structField)
		if err != nil {
			return nil, err
		}
		switch field.elemKind {
		default:
			field.setUnsupportGetter()
			switch field.elemKind {
			case reflect.Struct:
				sub, err = vm.registerStructLocked(field.structField.Type)
				if err != nil {
					return nil, err
				}
				s.mergeSubStructVM(field, sub)
			case reflect.Interface:
				s.setIfaceTagExprGetter(field)
			}
		case reflect.Float32, reflect.Float64,
			reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,
			reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
			field.setFloatGetter()
		case reflect.String:
			field.setStringGetter()
		case reflect.Bool:
			field.setBoolGetter()
		case reflect.Array, reflect.Slice, reflect.Map:
			err = vm.registerIndirectStructLocked(field)
			if err != nil {
				return nil, err
			}
		}
	}
	return s, nil
}
func (vm *VM) registerIndirectStructLocked(field *fieldVM) error {
	field.setLengthGetter()
	if field.tagOp == tagOmit {
		return nil
	}
	a := make([]reflect.Type, 1, 2)
	a[0] = derefType(field.elemType.Elem())
	if field.elemKind == reflect.Map {
		a = append(a, derefType(field.elemType.Key()))
	}
	for i, t := range a {
		kind := t.Kind()
		switch kind {
		case reflect.Interface:
			field.mapOrSliceIfaceKinds[i] = true
			field.origin.fieldsWithIndirectStructVM = appendDistinct(field.origin.fieldsWithIndirectStructVM, field)
		case reflect.Slice, reflect.Array, reflect.Map:
			tt := t.Elem()
			checkMap := kind == reflect.Map
		F2:
			for {
				switch tt.Kind() {
				case reflect.Slice, reflect.Array, reflect.Map, reflect.Ptr:
					tt = tt.Elem()
				case reflect.Struct:
					_, err := vm.registerStructLocked(tt)
					if err != nil {
						return err
					}
					field.mapOrSliceIfaceKinds[i] = true
					field.origin.fieldsWithIndirectStructVM = appendDistinct(field.origin.fieldsWithIndirectStructVM, field)
					break F2
				default:
					break F2
				}
			}
			if checkMap {
				tt = t.Key()
				checkMap = false
				goto F2
			}
		case reflect.Struct:
			s, err := vm.registerStructLocked(t)
			if err != nil {
				return err
			}
			if len(s.exprSelectorList) > 0 ||
				len(s.ifaceTagExprGetters) > 0 ||
				len(s.fieldsWithIndirectStructVM) > 0 {
				if i == 0 {
					field.mapOrSliceElemStructVM = s
				} else {
					field.mapKeyStructVM = s
				}
				field.origin.fieldsWithIndirectStructVM = appendDistinct(field.origin.fieldsWithIndirectStructVM, field)
			}
		}
	}
	return nil
}
func appendDistinct(a []*fieldVM, i *fieldVM) []*fieldVM {
	has := false
	for _, e := range a {
		if e == i {
			has = true
			break
		}
	}
	if !has {
		return append(a, i)
	}
	return a
}
func (vm *VM) newStructVM() *structVM {
	return &structVM{
		vm:                         vm,
		fields:                     make(map[string]*fieldVM, 32),
		fieldSelectorList:          make([]string, 0, 32),
		fieldsWithIndirectStructVM: make([]*fieldVM, 0, 32),
		exprs:                      make(map[string]*Expr, 64),
		exprSelectorList:           make([]string, 0, 64),
	}
}
func (s *structVM) newFieldVM(structField reflect.StructField) (*fieldVM, error) {
	f := &fieldVM{
		structField:   structField,
		exprs:         make(map[string]*Expr, 8),
		origin:        s,
		fieldSelector: structField.Name,
	}
	err := f.parseExprs(structField.Tag.Get(s.vm.tagName))
	if err != nil {
		return nil, err
	}
	s.fields[f.fieldSelector] = f
	s.fieldSelectorList = append(s.fieldSelectorList, f.fieldSelector)
	var t = structField.Type
	var ptrDeep int
	for t.Kind() == reflect.Ptr {
		t = t.Elem()
		ptrDeep++
	}
	f.ptrDeep = ptrDeep
	var offset = structField.Offset
	f.getPtr = func(ptr unsafe.Pointer) unsafe.Pointer {
		if ptr == nil {
			return nil
		}
		return unsafe.Pointer(uintptr(ptr) + offset)
	}
	f.elemType = t
	f.elemKind = t.Kind()
	f.reflectValueGetter = func(ptr unsafe.Pointer, initZero bool) reflect.Value {
		v := f.packRawFrom(ptr)
		if initZero {
			f.ensureInit(v)
		}
		return v
	}
	return f, nil
}
func (f *fieldVM) ensureInit(v reflect.Value) {
	if safeIsNil(v) && v.CanSet() {
		newField := reflect.New(f.elemType).Elem()
		for i := 0; i < f.ptrDeep; i++ {
			if newField.CanAddr() {
				newField = newField.Addr()
			} else {
				newField2 := reflect.New(newField.Type())
				newField2.Elem().Set(newField)
				newField = newField2
			}
		}
		v.Set(newField)
	}
}
func (s *structVM) mergeSubStructVM(field *fieldVM, sub *structVM) {
	field.origin = sub
	fieldsWithIndirectStructVM := make(map[*fieldVM]struct{}, len(sub.fieldsWithIndirectStructVM))
	for _, subField := range sub.fieldsWithIndirectStructVM {
		fieldsWithIndirectStructVM[subField] = struct{}{}
	}
	for _, k := range sub.fieldSelectorList {
		v := sub.fields[k]
		f := s.newChildField(field, v, true)
		if _, ok := fieldsWithIndirectStructVM[v]; ok {
			s.fieldsWithIndirectStructVM = append(s.fieldsWithIndirectStructVM, f)
		}
	}
	for _, _subFn := range sub.ifaceTagExprGetters {
		subFn := _subFn
		s.ifaceTagExprGetters = append(s.ifaceTagExprGetters, func(ptr unsafe.Pointer, pathPrefix string, fn func(*TagExpr, error) error) error {
			ptr = field.getElemPtr(ptr)
			if ptr == nil {
				return nil
			}
			var path string
			if pathPrefix == "" {
				path = field.fieldSelector
			} else {
				path = pathPrefix + FieldSeparator + field.fieldSelector
			}
			return subFn(ptr, path, fn)
		})
	}
}
func (s *structVM) newChildField(parent *fieldVM, child *fieldVM, toBind bool) *fieldVM {
	f := &fieldVM{
		structField:            child.structField,
		exprs:                  make(map[string]*Expr, len(child.exprs)),
		ptrDeep:                child.ptrDeep,
		elemType:               child.elemType,
		elemKind:               child.elemKind,
		origin:                 child.origin,
		mapKeyStructVM:         child.mapKeyStructVM,
		mapOrSliceElemStructVM: child.mapOrSliceElemStructVM,
		mapOrSliceIfaceKinds:   child.mapOrSliceIfaceKinds,
		fieldSelector:          parent.fieldSelector + FieldSeparator + child.fieldSelector,
	}
	if parent.tagOp != tagOmit {
		f.tagOp = child.tagOp
	} else {
		f.tagOp = parent.tagOp
	}
	f.getPtr = func(ptr unsafe.Pointer) unsafe.Pointer {
		ptr = parent.getElemPtr(ptr)
		if ptr == nil {
			return nil
		}
		return child.getPtr(ptr)
	}
	if child.valueGetter != nil {
		if parent.ptrDeep == 0 {
			f.valueGetter = func(ptr unsafe.Pointer) interface{} {
				return child.valueGetter(parent.getPtr(ptr))
			}
			f.reflectValueGetter = func(ptr unsafe.Pointer, initZero bool) reflect.Value {
				return child.reflectValueGetter(parent.getPtr(ptr), initZero)
			}
		} else {
			f.valueGetter = func(ptr unsafe.Pointer) interface{} {
				newField := reflect.NewAt(parent.structField.Type, parent.getPtr(ptr))
				for i := 0; i < parent.ptrDeep; i++ {
					newField = newField.Elem()
				}
				if newField.IsNil() {
					return nil
				}
				return child.valueGetter(unsafe.Pointer(newField.Pointer()))
			}
			f.reflectValueGetter = func(ptr unsafe.Pointer, initZero bool) reflect.Value {
				newField := reflect.NewAt(parent.structField.Type, parent.getPtr(ptr))
				if initZero {
					parent.ensureInit(newField.Elem())
				}
				for i := 0; i < parent.ptrDeep; i++ {
					newField = newField.Elem()
				}
				if (newField == reflect.Value{}) || (!initZero && newField.IsNil()) {
					return reflect.Value{}
				}
				return child.reflectValueGetter(unsafe.Pointer(newField.Pointer()), initZero)
			}
		}
	}
	if toBind {
		s.fields[f.fieldSelector] = f
		s.fieldSelectorList = append(s.fieldSelectorList, f.fieldSelector)
		if parent.tagOp != tagOmit {
			for k, v := range child.exprs {
				selector := parent.fieldSelector + FieldSeparator + k
				f.exprs[selector] = v
				s.exprs[selector] = v
				s.exprSelectorList = append(s.exprSelectorList, selector)
			}
		}
	}
	return f
}
func (f *fieldVM) getElemPtr(ptr unsafe.Pointer) unsafe.Pointer {
	ptr = f.getPtr(ptr)
	for i := f.ptrDeep; ptr != nil && i > 0; i-- {
		ptr = ptrElem(ptr)
	}
	return ptr
}
func (f *fieldVM) packRawFrom(ptr unsafe.Pointer) reflect.Value {
	return reflect.NewAt(f.structField.Type, f.getPtr(ptr)).Elem()
}
func (f *fieldVM) packElemFrom(ptr unsafe.Pointer) reflect.Value {
	return reflect.NewAt(f.elemType, f.getElemPtr(ptr)).Elem()
}
func (s *structVM) setIfaceTagExprGetter(f *fieldVM) {
	if f.tagOp == tagOmit {
		return
	}
	s.ifaceTagExprGetters = append(s.ifaceTagExprGetters, func(ptr unsafe.Pointer, pathPrefix string, fn func(*TagExpr, error) error) error {
		v := f.packElemFrom(ptr)
		if !v.IsValid() || v.IsNil() {
			return nil
		}
		var path string
		if pathPrefix == "" {
			path = f.fieldSelector
		} else {
			path = pathPrefix + FieldSeparator + f.fieldSelector
		}
		return s.vm.subRunAll(f.tagOp == tagOmitNil, path, v, fn)
	})
}
func (f *fieldVM) setFloatGetter() {
	if f.ptrDeep == 0 {
		f.valueGetter = func(ptr unsafe.Pointer) interface{} {
			ptr = f.getPtr(ptr)
			if ptr == nil {
				return nil
			}
			return getFloat64(f.elemKind, ptr)
		}
	} else {
		f.valueGetter = func(ptr unsafe.Pointer) interface{} {
			v := f.packElemFrom(ptr)
			if v.CanAddr() {
				return getFloat64(f.elemKind, unsafe.Pointer(v.UnsafeAddr()))
			}
			return nil
		}
	}
}
func (f *fieldVM) setBoolGetter() {
	if f.ptrDeep == 0 {
		f.valueGetter = func(ptr unsafe.Pointer) interface{} {
			ptr = f.getPtr(ptr)
			if ptr == nil {
				return nil
			}
			return *(*bool)(ptr)
		}
	} else {
		f.valueGetter = func(ptr unsafe.Pointer) interface{} {
			v := f.packElemFrom(ptr)
			if v.IsValid() {
				return v.Bool()
			}
			return nil
		}
	}
}
func (f *fieldVM) setStringGetter() {
	if f.ptrDeep == 0 {
		f.valueGetter = func(ptr unsafe.Pointer) interface{} {
			ptr = f.getPtr(ptr)
			if ptr == nil {
				return nil
			}
			return *(*string)(ptr)
		}
	} else {
		f.valueGetter = func(ptr unsafe.Pointer) interface{} {
			v := f.packElemFrom(ptr)
			if v.IsValid() {
				return v.String()
			}
			return nil
		}
	}
}
func (f *fieldVM) setLengthGetter() {
	f.valueGetter = func(ptr unsafe.Pointer) interface{} {
		v := f.packElemFrom(ptr)
		if v.IsValid() {
			return v.Interface()
		}
		return nil
	}
}
func (f *fieldVM) setUnsupportGetter() {
	f.valueGetter = func(ptr unsafe.Pointer) interface{} {
		raw := f.packRawFrom(ptr)
		if safeIsNil(raw) {
			return nil
		}
		v := raw
		for i := 0; i < f.ptrDeep; i++ {
			v = v.Elem()
		}
		for v.Kind() == reflect.Interface {
			v = v.Elem()
		}
		return anyValueGetter(raw, v)
	}
}
func (vm *VM) getStructType(t reflect.Type) (reflect.Type, error) {
	structType := t
	for structType.Kind() == reflect.Ptr {
		structType = structType.Elem()
	}
	if structType.Kind() != reflect.Struct {
		return nil, fmt.Errorf("unsupport type: %s", t.String())
	}
	return structType, nil
}
func (s *structVM) newTagExpr(ptr unsafe.Pointer, path string) *TagExpr {
	te := &TagExpr{
		s:    s,
		ptr:  ptr,
		sub:  make(map[string]*TagExpr, 8),
		path: strings.TrimPrefix(path, "."),
	}
	return te
}
type TagExpr struct {
	s    *structVM
	ptr  unsafe.Pointer
	sub  map[string]*TagExpr
	path string
}
func (t *TagExpr) EvalFloat(exprSelector string) float64 {
	r, _ := t.Eval(exprSelector).(float64)
	return r
}
func (t *TagExpr) EvalString(exprSelector string) string {
	r, _ := t.Eval(exprSelector).(string)
	return r
}
func (t *TagExpr) EvalBool(exprSelector string) bool {
	return FakeBool(t.Eval(exprSelector))
}
func FakeBool(v interface{}) bool {
	switch r := v.(type) {
	case float64:
		return r != 0
	case float32:
		return r != 0
	case int:
		return r != 0
	case int8:
		return r != 0
	case int16:
		return r != 0
	case int32:
		return r != 0
	case int64:
		return r != 0
	case uint:
		return r != 0
	case uint8:
		return r != 0
	case uint16:
		return r != 0
	case uint32:
		return r != 0
	case uint64:
		return r != 0
	case string:
		return r != ""
	case bool:
		return r
	case nil, error:
		return false
	case []interface{}:
		var bol = true
		for _, v := range r {
			bol = bol && FakeBool(v)
		}
		return bol
	default:
		vv := ameda.DereferenceValue(reflect.ValueOf(v))
		if vv.IsValid() || vv.IsZero() {
			return false
		}
		return true
	}
}