github.com/bytedance/go-tagexpr@v2.7.5-0.20210114074101-de5b8743ad85+incompatible/tagexpr.go (about)

     1  // Package tagexpr is an interesting go struct tag expression syntax for field validation, etc.
     2  //
     3  // Copyright 2019 Bytedance Inc. All Rights Reserved.
     4  //
     5  // Licensed under the Apache License, Version 2.0 (the "License");
     6  // you may not use this file except in compliance with the License.
     7  // You may obtain a copy of the License at
     8  //
     9  //      http://www.apache.org/licenses/LICENSE-2.0
    10  //
    11  // Unless required by applicable law or agreed to in writing, software
    12  // distributed under the License is distributed on an "AS IS" BASIS,
    13  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    14  // See the License for the specific language governing permissions and
    15  // limitations under the License.
    16  package tagexpr
    17  
    18  import (
    19  	"errors"
    20  	"fmt"
    21  	"reflect"
    22  	"strconv"
    23  	"strings"
    24  	"sync"
    25  	"unsafe"
    26  
    27  	"github.com/henrylee2cn/goutil"
    28  	"github.com/henrylee2cn/goutil/tpack"
    29  )
    30  
    31  // Internally unified data types
    32  type (
    33  	Number  = float64
    34  	Null    = interface{}
    35  	Boolean = bool
    36  	String  = string
    37  )
    38  
    39  // VM struct tag expression interpreter
    40  type VM struct {
    41  	tagName   string
    42  	structJar map[uintptr]*structVM
    43  	rw        sync.RWMutex
    44  }
    45  
    46  // structVM tag expression set of struct
    47  type structVM struct {
    48  	vm                         *VM
    49  	name                       string
    50  	fields                     map[string]*fieldVM
    51  	fieldSelectorList          []string
    52  	fieldsWithIndirectStructVM []*fieldVM
    53  	exprs                      map[string]*Expr
    54  	exprSelectorList           []string
    55  	ifaceTagExprGetters        []func(unsafe.Pointer, string, func(*TagExpr, error) error) error
    56  }
    57  
    58  // fieldVM tag expression set of struct field
    59  type fieldVM struct {
    60  	structField            reflect.StructField
    61  	ptrDeep                int
    62  	getPtr                 func(unsafe.Pointer) unsafe.Pointer
    63  	elemType               reflect.Type
    64  	elemKind               reflect.Kind
    65  	valueGetter            func(unsafe.Pointer) interface{}
    66  	reflectValueGetter     func(unsafe.Pointer, bool) reflect.Value
    67  	exprs                  map[string]*Expr
    68  	origin                 *structVM
    69  	mapKeyStructVM         *structVM
    70  	mapOrSliceElemStructVM *structVM
    71  	mapOrSliceIfaceKinds   [2]bool // [value, key/index]
    72  	fieldSelector          string
    73  	tagOp                  string
    74  }
    75  
    76  // New creates a tag expression interpreter that uses tagName as the tag name.
    77  // NOTE:
    78  //  If no tagName is specified, no tag expression will be interpreted,
    79  //  but still can operate the various fields.
    80  func New(tagName ...string) *VM {
    81  	if len(tagName) == 0 {
    82  		tagName = append(tagName, "")
    83  	}
    84  	return &VM{
    85  		tagName:   tagName[0],
    86  		structJar: make(map[uintptr]*structVM, 256),
    87  	}
    88  }
    89  
    90  // MustRun is similar to Run, but panic when error.
    91  func (vm *VM) MustRun(structOrStructPtrOrReflectValue interface{}) *TagExpr {
    92  	te, err := vm.Run(structOrStructPtrOrReflectValue)
    93  	if err != nil {
    94  		panic(err)
    95  	}
    96  	return te
    97  }
    98  
    99  var unsupportNil = errors.New("unsupport data: nil")
   100  
   101  // Run returns the tag expression handler of the @structOrStructPtrOrReflectValue.
   102  // NOTE:
   103  //  If the structure type has not been warmed up,
   104  //  it will be slower when it is first called.
   105  // Disable new -d=checkptr behaviour for Go 1.14
   106  //go:nocheckptr
   107  func (vm *VM) Run(structOrStructPtrOrReflectValue interface{}) (*TagExpr, error) {
   108  	var u tpack.U
   109  	v, isReflectValue := structOrStructPtrOrReflectValue.(reflect.Value)
   110  	if isReflectValue {
   111  		u = tpack.From(v)
   112  	} else {
   113  		u = tpack.Unpack(structOrStructPtrOrReflectValue)
   114  	}
   115  	ptr := unsafe.Pointer(u.Pointer())
   116  	if ptr == nil {
   117  		return nil, unsupportNil
   118  	}
   119  	u = u.UnderlyingElem()
   120  	tid := u.RuntimeTypeID()
   121  	var err error
   122  	vm.rw.RLock()
   123  	s, ok := vm.structJar[tid]
   124  	vm.rw.RUnlock()
   125  	if !ok {
   126  		vm.rw.Lock()
   127  		s, ok = vm.structJar[tid]
   128  		if !ok {
   129  			if isReflectValue {
   130  				s, err = vm.registerStructLocked(v.Type())
   131  			} else {
   132  				s, err = vm.registerStructLocked(reflect.TypeOf(structOrStructPtrOrReflectValue))
   133  			}
   134  			if err != nil {
   135  				vm.rw.Unlock()
   136  				return nil, err
   137  			}
   138  		}
   139  		vm.rw.Unlock()
   140  	}
   141  	return s.newTagExpr(ptr, ""), nil
   142  }
   143  
   144  // RunAny returns the tag expression handler for the @v.
   145  // NOTE:
   146  //  The @v can be structured data such as struct, map, slice, array, interface, reflcet.Value, etc.
   147  //  If the structure type has not been warmed up,
   148  //  it will be slower when it is first called.
   149  func (vm *VM) RunAny(v interface{}, fn func(*TagExpr, error) error) error {
   150  	vv, isReflectValue := v.(reflect.Value)
   151  	if !isReflectValue {
   152  		vv = reflect.ValueOf(v)
   153  	}
   154  	return vm.subRunAll(false, "", vv, fn)
   155  }
   156  
   157  func (vm *VM) subRunAll(omitNil bool, tePath string, value reflect.Value, fn func(*TagExpr, error) error) error {
   158  	rv := goutil.DereferenceIfaceValue(value)
   159  	if !rv.IsValid() {
   160  		return nil
   161  	}
   162  	rt := goutil.DereferenceType(rv.Type())
   163  	rv = goutil.DereferenceValue(rv)
   164  	switch rt.Kind() {
   165  	case reflect.Struct:
   166  		ptr := unsafe.Pointer(tpack.From(rv).Pointer())
   167  		if ptr == nil {
   168  			if omitNil {
   169  				return nil
   170  			}
   171  			return fn(nil, unsupportNil)
   172  		}
   173  		return fn(vm.subRun(tePath, rt, tpack.RuntimeTypeID(rt), ptr))
   174  
   175  	case reflect.Slice, reflect.Array:
   176  		count := rv.Len()
   177  		if count == 0 {
   178  			return nil
   179  		}
   180  		switch goutil.DereferenceType(rv.Type().Elem()).Kind() {
   181  		case reflect.Struct, reflect.Interface, reflect.Slice, reflect.Array, reflect.Map:
   182  			for i := count - 1; i >= 0; i-- {
   183  				err := vm.subRunAll(omitNil, tePath+"["+strconv.Itoa(i)+"]", rv.Index(i), fn)
   184  				if err != nil {
   185  					return err
   186  				}
   187  			}
   188  		default:
   189  			return nil
   190  		}
   191  
   192  	case reflect.Map:
   193  		if rv.Len() == 0 {
   194  			return nil
   195  		}
   196  		var canKey, canValue bool
   197  		rt := rv.Type()
   198  		switch goutil.DereferenceType(rt.Key()).Kind() {
   199  		case reflect.Struct, reflect.Interface, reflect.Slice, reflect.Array, reflect.Map:
   200  			canKey = true
   201  		}
   202  		switch goutil.DereferenceType(rt.Elem()).Kind() {
   203  		case reflect.Struct, reflect.Interface, reflect.Slice, reflect.Array, reflect.Map:
   204  			canValue = true
   205  		}
   206  		if !canKey && !canValue {
   207  			return nil
   208  		}
   209  		for _, key := range rv.MapKeys() {
   210  			if canKey {
   211  				err := vm.subRunAll(omitNil, tePath+"{}", key, fn)
   212  				if err != nil {
   213  					return err
   214  				}
   215  			}
   216  			if canValue {
   217  				err := vm.subRunAll(omitNil, tePath+"{K:"+key.String()+"}", rv.MapIndex(key), fn)
   218  				if err != nil {
   219  					return err
   220  				}
   221  			}
   222  		}
   223  	}
   224  	return nil
   225  }
   226  
   227  func (vm *VM) subRun(path string, t reflect.Type, tid uintptr, ptr unsafe.Pointer) (*TagExpr, error) {
   228  	var err error
   229  	vm.rw.RLock()
   230  	s, ok := vm.structJar[tid]
   231  	vm.rw.RUnlock()
   232  	if !ok {
   233  		vm.rw.Lock()
   234  		s, ok = vm.structJar[tid]
   235  		if !ok {
   236  			s, err = vm.registerStructLocked(t)
   237  			if err != nil {
   238  				vm.rw.Unlock()
   239  				return nil, err
   240  			}
   241  		}
   242  		vm.rw.Unlock()
   243  	}
   244  	return s.newTagExpr(ptr, path), nil
   245  }
   246  
   247  func (vm *VM) registerStructLocked(structType reflect.Type) (*structVM, error) {
   248  	structType, err := vm.getStructType(structType)
   249  	if err != nil {
   250  		return nil, err
   251  	}
   252  	tid := tpack.RuntimeTypeID(structType)
   253  	s, had := vm.structJar[tid]
   254  	if had {
   255  		return s, nil
   256  	}
   257  	s = vm.newStructVM()
   258  	s.name = structType.String()
   259  	vm.structJar[tid] = s
   260  	var numField = structType.NumField()
   261  	var structField reflect.StructField
   262  	var sub *structVM
   263  	for i := 0; i < numField; i++ {
   264  		structField = structType.Field(i)
   265  		field, err := s.newFieldVM(structField)
   266  		if err != nil {
   267  			return nil, err
   268  		}
   269  		switch field.elemKind {
   270  		default:
   271  			field.setUnsupportGetter()
   272  			switch field.elemKind {
   273  			case reflect.Struct:
   274  				sub, err = vm.registerStructLocked(field.structField.Type)
   275  				if err != nil {
   276  					return nil, err
   277  				}
   278  				s.mergeSubStructVM(field, sub)
   279  			case reflect.Interface:
   280  				s.setIfaceTagExprGetter(field)
   281  			}
   282  		case reflect.Float32, reflect.Float64,
   283  			reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,
   284  			reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
   285  			field.setFloatGetter()
   286  		case reflect.String:
   287  			field.setStringGetter()
   288  		case reflect.Bool:
   289  			field.setBoolGetter()
   290  		case reflect.Array, reflect.Slice, reflect.Map:
   291  			err = vm.registerIndirectStructLocked(field)
   292  			if err != nil {
   293  				return nil, err
   294  			}
   295  		}
   296  	}
   297  	return s, nil
   298  }
   299  
   300  func (vm *VM) registerIndirectStructLocked(field *fieldVM) error {
   301  	field.setLengthGetter()
   302  	if field.tagOp == tagOmit {
   303  		return nil
   304  	}
   305  	a := make([]reflect.Type, 1, 2)
   306  	a[0] = derefType(field.elemType.Elem())
   307  	if field.elemKind == reflect.Map {
   308  		a = append(a, derefType(field.elemType.Key()))
   309  	}
   310  	for i, t := range a {
   311  		kind := t.Kind()
   312  		if kind != reflect.Struct {
   313  			if kind == reflect.Interface {
   314  				field.mapOrSliceIfaceKinds[i] = true
   315  				field.origin.fieldsWithIndirectStructVM = append(field.origin.fieldsWithIndirectStructVM, field)
   316  			}
   317  			continue
   318  		}
   319  		s, err := vm.registerStructLocked(t)
   320  		if err != nil {
   321  			return err
   322  		}
   323  		if len(s.exprSelectorList) > 0 ||
   324  			len(s.ifaceTagExprGetters) > 0 ||
   325  			len(s.fieldsWithIndirectStructVM) > 0 {
   326  			if i == 0 {
   327  				field.mapOrSliceElemStructVM = s
   328  			} else {
   329  				field.mapKeyStructVM = s
   330  			}
   331  			field.origin.fieldsWithIndirectStructVM = append(field.origin.fieldsWithIndirectStructVM, field)
   332  		}
   333  	}
   334  	return nil
   335  }
   336  
   337  func (vm *VM) newStructVM() *structVM {
   338  	return &structVM{
   339  		vm:                         vm,
   340  		fields:                     make(map[string]*fieldVM, 32),
   341  		fieldSelectorList:          make([]string, 0, 32),
   342  		fieldsWithIndirectStructVM: make([]*fieldVM, 0, 32),
   343  		exprs:                      make(map[string]*Expr, 64),
   344  		exprSelectorList:           make([]string, 0, 64),
   345  	}
   346  }
   347  
   348  func (s *structVM) newFieldVM(structField reflect.StructField) (*fieldVM, error) {
   349  	f := &fieldVM{
   350  		structField:   structField,
   351  		exprs:         make(map[string]*Expr, 8),
   352  		origin:        s,
   353  		fieldSelector: structField.Name,
   354  	}
   355  	err := f.parseExprs(structField.Tag.Get(s.vm.tagName))
   356  	if err != nil {
   357  		return nil, err
   358  	}
   359  	s.fields[f.fieldSelector] = f
   360  	s.fieldSelectorList = append(s.fieldSelectorList, f.fieldSelector)
   361  
   362  	var t = structField.Type
   363  	var ptrDeep int
   364  	for t.Kind() == reflect.Ptr {
   365  		t = t.Elem()
   366  		ptrDeep++
   367  	}
   368  	f.ptrDeep = ptrDeep
   369  
   370  	var offset = structField.Offset
   371  	f.getPtr = func(ptr unsafe.Pointer) unsafe.Pointer {
   372  		if ptr == nil {
   373  			return nil
   374  		}
   375  		return unsafe.Pointer(uintptr(ptr) + offset)
   376  	}
   377  
   378  	f.elemType = t
   379  	f.elemKind = t.Kind()
   380  	f.reflectValueGetter = func(ptr unsafe.Pointer, initZero bool) reflect.Value {
   381  		v := f.packRawFrom(ptr)
   382  		if initZero {
   383  			f.ensureInit(v)
   384  		}
   385  		return v
   386  	}
   387  
   388  	return f, nil
   389  }
   390  
   391  func (f *fieldVM) ensureInit(v reflect.Value) {
   392  	if safeIsNil(v) && v.CanSet() {
   393  		newField := reflect.New(f.elemType).Elem()
   394  		for i := 0; i < f.ptrDeep; i++ {
   395  			if newField.CanAddr() {
   396  				newField = newField.Addr()
   397  			} else {
   398  				newField2 := reflect.New(newField.Type())
   399  				newField2.Elem().Set(newField)
   400  				newField = newField2
   401  			}
   402  		}
   403  		v.Set(newField)
   404  	}
   405  }
   406  
   407  func (s *structVM) mergeSubStructVM(field *fieldVM, sub *structVM) {
   408  	field.origin = sub
   409  	fieldsWithIndirectStructVM := make(map[*fieldVM]struct{}, len(sub.fieldsWithIndirectStructVM))
   410  	for _, subField := range sub.fieldsWithIndirectStructVM {
   411  		fieldsWithIndirectStructVM[subField] = struct{}{}
   412  	}
   413  	for _, k := range sub.fieldSelectorList {
   414  		v := sub.fields[k]
   415  		f := s.newChildField(field, v, true)
   416  		if _, ok := fieldsWithIndirectStructVM[v]; ok {
   417  			s.fieldsWithIndirectStructVM = append(s.fieldsWithIndirectStructVM, f)
   418  			// TODO: maybe needed?
   419  			// delete(fieldsWithIndirectStructVM, v)
   420  		}
   421  	}
   422  	// TODO: maybe needed?
   423  	// for v := range fieldsWithIndirectStructVM {
   424  	// 	f := s.newChildField(field, v, false)
   425  	// 	s.fieldsWithIndirectStructVM = append(s.fieldsWithIndirectStructVM, f)
   426  	// }
   427  
   428  	for _, _subFn := range sub.ifaceTagExprGetters {
   429  		subFn := _subFn
   430  		s.ifaceTagExprGetters = append(s.ifaceTagExprGetters, func(ptr unsafe.Pointer, pathPrefix string, fn func(*TagExpr, error) error) error {
   431  			ptr = field.getElemPtr(ptr)
   432  			if ptr == nil {
   433  				return nil
   434  			}
   435  			var path string
   436  			if pathPrefix == "" {
   437  				path = field.fieldSelector
   438  			} else {
   439  				path = pathPrefix + FieldSeparator + field.fieldSelector
   440  			}
   441  			return subFn(ptr, path, fn)
   442  		})
   443  	}
   444  }
   445  
   446  func (s *structVM) newChildField(parent *fieldVM, child *fieldVM, toBind bool) *fieldVM {
   447  	f := &fieldVM{
   448  		structField:            child.structField,
   449  		exprs:                  make(map[string]*Expr, len(child.exprs)),
   450  		ptrDeep:                child.ptrDeep,
   451  		elemType:               child.elemType,
   452  		elemKind:               child.elemKind,
   453  		origin:                 child.origin,
   454  		mapKeyStructVM:         child.mapKeyStructVM,
   455  		mapOrSliceElemStructVM: child.mapOrSliceElemStructVM,
   456  		mapOrSliceIfaceKinds:   child.mapOrSliceIfaceKinds,
   457  		fieldSelector:          parent.fieldSelector + FieldSeparator + child.fieldSelector,
   458  	}
   459  	if parent.tagOp != tagOmit {
   460  		f.tagOp = child.tagOp
   461  	} else {
   462  		f.tagOp = parent.tagOp
   463  	}
   464  	f.getPtr = func(ptr unsafe.Pointer) unsafe.Pointer {
   465  		ptr = parent.getElemPtr(ptr)
   466  		if ptr == nil {
   467  			return nil
   468  		}
   469  		return child.getPtr(ptr)
   470  	}
   471  	if child.valueGetter != nil {
   472  		if parent.ptrDeep == 0 {
   473  			f.valueGetter = func(ptr unsafe.Pointer) interface{} {
   474  				return child.valueGetter(parent.getPtr(ptr))
   475  			}
   476  			f.reflectValueGetter = func(ptr unsafe.Pointer, initZero bool) reflect.Value {
   477  				return child.reflectValueGetter(parent.getPtr(ptr), initZero)
   478  			}
   479  		} else {
   480  			f.valueGetter = func(ptr unsafe.Pointer) interface{} {
   481  				newField := reflect.NewAt(parent.structField.Type, parent.getPtr(ptr))
   482  				for i := 0; i < parent.ptrDeep; i++ {
   483  					newField = newField.Elem()
   484  				}
   485  				if newField.IsNil() {
   486  					return nil
   487  				}
   488  				return child.valueGetter(unsafe.Pointer(newField.Pointer()))
   489  			}
   490  			f.reflectValueGetter = func(ptr unsafe.Pointer, initZero bool) reflect.Value {
   491  				newField := reflect.NewAt(parent.structField.Type, parent.getPtr(ptr))
   492  				if initZero {
   493  					parent.ensureInit(newField.Elem())
   494  				}
   495  				for i := 0; i < parent.ptrDeep; i++ {
   496  					newField = newField.Elem()
   497  				}
   498  				if (newField == reflect.Value{}) || (!initZero && newField.IsNil()) {
   499  					return reflect.Value{}
   500  				}
   501  				return child.reflectValueGetter(unsafe.Pointer(newField.Pointer()), initZero)
   502  			}
   503  		}
   504  	}
   505  
   506  	if toBind {
   507  		s.fields[f.fieldSelector] = f
   508  		s.fieldSelectorList = append(s.fieldSelectorList, f.fieldSelector)
   509  		if parent.tagOp != tagOmit {
   510  			for k, v := range child.exprs {
   511  				selector := parent.fieldSelector + FieldSeparator + k
   512  				f.exprs[selector] = v
   513  				s.exprs[selector] = v
   514  				s.exprSelectorList = append(s.exprSelectorList, selector)
   515  			}
   516  		}
   517  	}
   518  	return f
   519  }
   520  
   521  func (f *fieldVM) getElemPtr(ptr unsafe.Pointer) unsafe.Pointer {
   522  	ptr = f.getPtr(ptr)
   523  	for i := f.ptrDeep; ptr != nil && i > 0; i-- {
   524  		ptr = ptrElem(ptr)
   525  	}
   526  	return ptr
   527  }
   528  
   529  func (f *fieldVM) packRawFrom(ptr unsafe.Pointer) reflect.Value {
   530  	return reflect.NewAt(f.structField.Type, f.getPtr(ptr)).Elem()
   531  }
   532  
   533  func (f *fieldVM) packElemFrom(ptr unsafe.Pointer) reflect.Value {
   534  	return reflect.NewAt(f.elemType, f.getElemPtr(ptr)).Elem()
   535  }
   536  
   537  func (s *structVM) setIfaceTagExprGetter(f *fieldVM) {
   538  	if f.tagOp == tagOmit {
   539  		return
   540  	}
   541  	s.ifaceTagExprGetters = append(s.ifaceTagExprGetters, func(ptr unsafe.Pointer, pathPrefix string, fn func(*TagExpr, error) error) error {
   542  		v := f.packElemFrom(ptr)
   543  		if !v.IsValid() || v.IsNil() {
   544  			return nil
   545  		}
   546  		var path string
   547  		if pathPrefix == "" {
   548  			path = f.fieldSelector
   549  		} else {
   550  			path = pathPrefix + FieldSeparator + f.fieldSelector
   551  		}
   552  		return s.vm.subRunAll(f.tagOp == tagOmitNil, path, v, fn)
   553  	})
   554  }
   555  
   556  func (f *fieldVM) setFloatGetter() {
   557  	if f.ptrDeep == 0 {
   558  		f.valueGetter = func(ptr unsafe.Pointer) interface{} {
   559  			ptr = f.getPtr(ptr)
   560  			if ptr == nil {
   561  				return nil
   562  			}
   563  			return getFloat64(f.elemKind, ptr)
   564  		}
   565  	} else {
   566  		f.valueGetter = func(ptr unsafe.Pointer) interface{} {
   567  			v := f.packElemFrom(ptr)
   568  			if v.CanAddr() {
   569  				return getFloat64(f.elemKind, unsafe.Pointer(v.UnsafeAddr()))
   570  			}
   571  			return nil
   572  		}
   573  	}
   574  }
   575  
   576  func (f *fieldVM) setBoolGetter() {
   577  	if f.ptrDeep == 0 {
   578  		f.valueGetter = func(ptr unsafe.Pointer) interface{} {
   579  			ptr = f.getPtr(ptr)
   580  			if ptr == nil {
   581  				return nil
   582  			}
   583  			return *(*bool)(ptr)
   584  		}
   585  	} else {
   586  		f.valueGetter = func(ptr unsafe.Pointer) interface{} {
   587  			v := f.packElemFrom(ptr)
   588  			if v.IsValid() {
   589  				return v.Bool()
   590  			}
   591  			return nil
   592  		}
   593  	}
   594  }
   595  
   596  func (f *fieldVM) setStringGetter() {
   597  	if f.ptrDeep == 0 {
   598  		f.valueGetter = func(ptr unsafe.Pointer) interface{} {
   599  			ptr = f.getPtr(ptr)
   600  			if ptr == nil {
   601  				return nil
   602  			}
   603  			return *(*string)(ptr)
   604  		}
   605  	} else {
   606  		f.valueGetter = func(ptr unsafe.Pointer) interface{} {
   607  			v := f.packElemFrom(ptr)
   608  			if v.IsValid() {
   609  				return v.String()
   610  			}
   611  			return nil
   612  		}
   613  	}
   614  }
   615  
   616  func (f *fieldVM) setLengthGetter() {
   617  	f.valueGetter = func(ptr unsafe.Pointer) interface{} {
   618  		v := f.packElemFrom(ptr)
   619  		if v.IsValid() {
   620  			return v.Interface()
   621  		}
   622  		return nil
   623  	}
   624  }
   625  
   626  func (f *fieldVM) setUnsupportGetter() {
   627  	f.valueGetter = func(ptr unsafe.Pointer) interface{} {
   628  		raw := f.packRawFrom(ptr)
   629  		if safeIsNil(raw) {
   630  			return nil
   631  		}
   632  		v := raw
   633  		for i := 0; i < f.ptrDeep; i++ {
   634  			v = v.Elem()
   635  		}
   636  		for v.Kind() == reflect.Interface {
   637  			v = v.Elem()
   638  		}
   639  		return anyValueGetter(raw, v)
   640  	}
   641  }
   642  
   643  func (vm *VM) getStructType(t reflect.Type) (reflect.Type, error) {
   644  	structType := t
   645  	for structType.Kind() == reflect.Ptr {
   646  		structType = structType.Elem()
   647  	}
   648  	if structType.Kind() != reflect.Struct {
   649  		return nil, fmt.Errorf("unsupport type: %s", t.String())
   650  	}
   651  	return structType, nil
   652  }
   653  
   654  func (s *structVM) newTagExpr(ptr unsafe.Pointer, path string) *TagExpr {
   655  	te := &TagExpr{
   656  		s:    s,
   657  		ptr:  ptr,
   658  		sub:  make(map[string]*TagExpr, 8),
   659  		path: strings.TrimPrefix(path, "."),
   660  	}
   661  	return te
   662  }
   663  
   664  // TagExpr struct tag expression evaluator
   665  type TagExpr struct {
   666  	s    *structVM
   667  	ptr  unsafe.Pointer
   668  	sub  map[string]*TagExpr
   669  	path string
   670  }
   671  
   672  // EvalFloat evaluates the value of the struct tag expression by the selector expression.
   673  // NOTE:
   674  //  If the expression value type is not float64, return 0.
   675  func (t *TagExpr) EvalFloat(exprSelector string) float64 {
   676  	r, _ := t.Eval(exprSelector).(float64)
   677  	return r
   678  }
   679  
   680  // EvalString evaluates the value of the struct tag expression by the selector expression.
   681  // NOTE:
   682  //  If the expression value type is not string, return "".
   683  func (t *TagExpr) EvalString(exprSelector string) string {
   684  	r, _ := t.Eval(exprSelector).(string)
   685  	return r
   686  }
   687  
   688  // EvalBool evaluates the value of the struct tag expression by the selector expression.
   689  // NOTE:
   690  //  If the expression value is not 0, '' or nil, return true.
   691  func (t *TagExpr) EvalBool(exprSelector string) bool {
   692  	return FakeBool(t.Eval(exprSelector))
   693  }
   694  
   695  // FakeBool fakes any type as a boolean.
   696  func FakeBool(v interface{}) bool {
   697  	switch r := v.(type) {
   698  	case float64:
   699  		return r != 0
   700  	case string:
   701  		return r != ""
   702  	case bool:
   703  		return r
   704  	case nil:
   705  		return false
   706  	default:
   707  		return true
   708  	}
   709  }
   710  
   711  // Field returns the field handler specified by the selector.
   712  func (t *TagExpr) Field(fieldSelector string) (fh *FieldHandler, found bool) {
   713  	f, ok := t.s.fields[fieldSelector]
   714  	if !ok {
   715  		return nil, false
   716  	}
   717  	return newFieldHandler(t, fieldSelector, f), true
   718  }
   719  
   720  // RangeFields loop through each field.
   721  // When fn returns false, interrupt traversal and return false.
   722  func (t *TagExpr) RangeFields(fn func(*FieldHandler) bool) bool {
   723  	if list := t.s.fieldSelectorList; len(list) > 0 {
   724  		fields := t.s.fields
   725  		for _, fieldSelector := range list {
   726  			if !fn(newFieldHandler(t, fieldSelector, fields[fieldSelector])) {
   727  				return false
   728  			}
   729  		}
   730  	}
   731  	return true
   732  }
   733  
   734  // Eval evaluates the value of the struct tag expression by the selector expression.
   735  // NOTE:
   736  //  format: fieldName, fieldName.exprName, fieldName1.fieldName2.exprName1
   737  //  result types: float64, string, bool, nil
   738  func (t *TagExpr) Eval(exprSelector string) interface{} {
   739  	expr, ok := t.s.exprs[exprSelector]
   740  	if !ok {
   741  		// Compatible with single mode or the expression with the name @
   742  		if strings.HasSuffix(exprSelector, ExprNameSeparator) {
   743  			exprSelector = exprSelector[:len(exprSelector)-1]
   744  			if strings.HasSuffix(exprSelector, ExprNameSeparator) {
   745  				exprSelector = exprSelector[:len(exprSelector)-1]
   746  			}
   747  			expr, ok = t.s.exprs[exprSelector]
   748  		}
   749  		if !ok {
   750  			return nil
   751  		}
   752  	}
   753  	dir, base := splitFieldSelector(exprSelector)
   754  	targetTagExpr, err := t.checkout(dir)
   755  	if err != nil {
   756  		return nil
   757  	}
   758  	return expr.run(base, targetTagExpr)
   759  }
   760  
   761  // Range loop through each tag expression.
   762  // When fn returns false, interrupt traversal and return false.
   763  // NOTE:
   764  //  eval result types: float64, string, bool, nil
   765  func (t *TagExpr) Range(fn func(*ExprHandler) error) error {
   766  	var err error
   767  	if list := t.s.exprSelectorList; len(list) > 0 {
   768  		for _, es := range list {
   769  			dir, base := splitFieldSelector(es)
   770  			targetTagExpr, err := t.checkout(dir)
   771  			if err != nil {
   772  				continue
   773  			}
   774  			err = fn(newExprHandler(t, targetTagExpr, base, es))
   775  			if err != nil {
   776  				return err
   777  			}
   778  		}
   779  	}
   780  
   781  	ptr := t.ptr
   782  
   783  	if list := t.s.fieldsWithIndirectStructVM; len(list) > 0 {
   784  		for _, f := range list {
   785  			v := f.packElemFrom(ptr)
   786  			if !v.IsValid() {
   787  				continue
   788  			}
   789  			omitNil := f.tagOp == tagOmitNil
   790  			mapKeyStructVM := f.mapKeyStructVM
   791  			mapOrSliceElemStructVM := f.mapOrSliceElemStructVM
   792  			valueIface := f.mapOrSliceIfaceKinds[0]
   793  			keyIface := f.mapOrSliceIfaceKinds[1]
   794  
   795  			if f.elemKind == reflect.Map &&
   796  				(mapOrSliceElemStructVM != nil || mapKeyStructVM != nil || valueIface || keyIface) {
   797  				keyPath := f.fieldSelector + FieldSeparator + "{}"
   798  				for _, key := range v.MapKeys() {
   799  					if mapKeyStructVM != nil {
   800  						p := unsafe.Pointer(tpack.From(derefValue(key)).Pointer())
   801  						if omitNil && p == nil {
   802  							continue
   803  						}
   804  						err = mapKeyStructVM.newTagExpr(p, keyPath).Range(fn)
   805  						if err != nil {
   806  							return err
   807  						}
   808  					} else if keyIface {
   809  						err = t.subRange(omitNil, keyPath, key, fn)
   810  						if err != nil {
   811  							return err
   812  						}
   813  					}
   814  					if mapOrSliceElemStructVM != nil {
   815  						p := unsafe.Pointer(tpack.From(derefValue(v.MapIndex(key))).Pointer())
   816  						if omitNil && p == nil {
   817  							continue
   818  						}
   819  						err = mapOrSliceElemStructVM.newTagExpr(p, f.fieldSelector+"{"+key.String()+"}").Range(fn)
   820  						if err != nil {
   821  							return err
   822  						}
   823  					} else if valueIface {
   824  						err = t.subRange(omitNil, f.fieldSelector+"{"+key.String()+"}", v.MapIndex(key), fn)
   825  						if err != nil {
   826  							return err
   827  						}
   828  					}
   829  				}
   830  
   831  			} else if mapOrSliceElemStructVM != nil || valueIface {
   832  				// slice or array
   833  				for i := v.Len() - 1; i >= 0; i-- {
   834  					if mapOrSliceElemStructVM != nil {
   835  						p := unsafe.Pointer(tpack.From(derefValue(v.Index(i))).Pointer())
   836  						if omitNil && p == nil {
   837  							continue
   838  						}
   839  						err = mapOrSliceElemStructVM.newTagExpr(p, f.fieldSelector+"["+strconv.Itoa(i)+"]").Range(fn)
   840  						if err != nil {
   841  							return err
   842  						}
   843  					} else if valueIface {
   844  						err = t.subRange(omitNil, f.fieldSelector+"["+strconv.Itoa(i)+"]", v.Index(i), fn)
   845  						if err != nil {
   846  							return err
   847  						}
   848  					}
   849  				}
   850  			}
   851  		}
   852  	}
   853  
   854  	if list := t.s.ifaceTagExprGetters; len(list) > 0 {
   855  		for _, getter := range list {
   856  			err = getter(ptr, "", func(te *TagExpr, err error) error {
   857  				if err != nil {
   858  					return err
   859  				}
   860  				return te.Range(fn)
   861  			})
   862  			if err != nil {
   863  				return err
   864  			}
   865  		}
   866  	}
   867  	return nil
   868  }
   869  
   870  func (t *TagExpr) subRange(omitNil bool, path string, value reflect.Value, fn func(*ExprHandler) error) error {
   871  	return t.s.vm.subRunAll(omitNil, path, value, func(te *TagExpr, err error) error {
   872  		if err != nil {
   873  			return err
   874  		}
   875  		return te.Range(fn)
   876  	})
   877  }
   878  
   879  var (
   880  	errFieldSelector = errors.New("field selector does not exist")
   881  	errOmitNil       = errors.New("omit nil")
   882  )
   883  
   884  func (t *TagExpr) checkout(fs string) (*TagExpr, error) {
   885  	if fs == "" {
   886  		return t, nil
   887  	}
   888  	subTagExpr, ok := t.sub[fs]
   889  	if ok {
   890  		if subTagExpr == nil {
   891  			return nil, errOmitNil
   892  		}
   893  		return subTagExpr, nil
   894  	}
   895  	f, ok := t.s.fields[fs]
   896  	if !ok {
   897  		return nil, errFieldSelector
   898  	}
   899  	ptr := f.getElemPtr(t.ptr)
   900  	if f.tagOp == tagOmitNil && unsafe.Pointer(ptr) == nil {
   901  		t.sub[fs] = nil
   902  		return nil, errOmitNil
   903  	}
   904  	subTagExpr = f.origin.newTagExpr(ptr, t.path)
   905  	t.sub[fs] = subTagExpr
   906  	return subTagExpr, nil
   907  }
   908  
   909  func (t *TagExpr) getValue(fieldSelector string, subFields []interface{}) (v interface{}) {
   910  	f := t.s.fields[fieldSelector]
   911  	if f == nil {
   912  		return nil
   913  	}
   914  	if f.valueGetter == nil {
   915  		return nil
   916  	}
   917  	v = f.valueGetter(t.ptr)
   918  	if v == nil {
   919  		return nil
   920  	}
   921  	if len(subFields) == 0 {
   922  		return v
   923  	}
   924  	vv := reflect.ValueOf(v)
   925  	var kind reflect.Kind
   926  	for i, k := range subFields {
   927  		kind = vv.Kind()
   928  		for kind == reflect.Ptr || kind == reflect.Interface {
   929  			vv = vv.Elem()
   930  			kind = vv.Kind()
   931  		}
   932  		switch kind {
   933  		case reflect.Slice, reflect.Array, reflect.String:
   934  			if float, ok := k.(float64); ok {
   935  				idx := int(float)
   936  				if idx >= vv.Len() {
   937  					return nil
   938  				}
   939  				vv = vv.Index(idx)
   940  			} else {
   941  				return nil
   942  			}
   943  		case reflect.Map:
   944  			k := safeConvert(reflect.ValueOf(k), vv.Type().Key())
   945  			if !k.IsValid() {
   946  				return nil
   947  			}
   948  			vv = vv.MapIndex(k)
   949  		case reflect.Struct:
   950  			if float, ok := k.(float64); ok {
   951  				idx := int(float)
   952  				if idx < 0 || idx >= vv.NumField() {
   953  					return nil
   954  				}
   955  				vv = vv.Field(idx)
   956  			} else if str, ok := k.(string); ok {
   957  				vv = vv.FieldByName(str)
   958  			} else {
   959  				return nil
   960  			}
   961  		default:
   962  			if i < len(subFields)-1 {
   963  				return nil
   964  			}
   965  		}
   966  		if !vv.IsValid() {
   967  			return nil
   968  		}
   969  	}
   970  	raw := vv
   971  	for vv.Kind() == reflect.Ptr || vv.Kind() == reflect.Interface {
   972  		vv = vv.Elem()
   973  	}
   974  	return anyValueGetter(raw, vv)
   975  }
   976  
   977  func safeConvert(v reflect.Value, t reflect.Type) reflect.Value {
   978  	defer func() { recover() }()
   979  	return v.Convert(t)
   980  }
   981  
   982  var float64Type = reflect.TypeOf(float64(0))
   983  
   984  func splitFieldSelector(selector string) (dir, base string) {
   985  	idx := strings.LastIndex(selector, ExprNameSeparator)
   986  	if idx != -1 {
   987  		selector = selector[:idx]
   988  	}
   989  	idx = strings.LastIndex(selector, FieldSeparator)
   990  	if idx != -1 {
   991  		return selector[:idx], selector[idx+1:]
   992  	}
   993  	return "", selector
   994  }
   995  
   996  func getFloat64(kind reflect.Kind, p unsafe.Pointer) interface{} {
   997  	switch kind {
   998  	case reflect.Float32:
   999  		return float64(*(*float32)(p))
  1000  	case reflect.Float64:
  1001  		return *(*float64)(p)
  1002  	case reflect.Int:
  1003  		return float64(*(*int)(p))
  1004  	case reflect.Int8:
  1005  		return float64(*(*int8)(p))
  1006  	case reflect.Int16:
  1007  		return float64(*(*int16)(p))
  1008  	case reflect.Int32:
  1009  		return float64(*(*int32)(p))
  1010  	case reflect.Int64:
  1011  		return float64(*(*int64)(p))
  1012  	case reflect.Uint:
  1013  		return float64(*(*uint)(p))
  1014  	case reflect.Uint8:
  1015  		return float64(*(*uint8)(p))
  1016  	case reflect.Uint16:
  1017  		return float64(*(*uint16)(p))
  1018  	case reflect.Uint32:
  1019  		return float64(*(*uint32)(p))
  1020  	case reflect.Uint64:
  1021  		return float64(*(*uint64)(p))
  1022  	case reflect.Uintptr:
  1023  		return float64(*(*uintptr)(p))
  1024  	}
  1025  	return nil
  1026  }
  1027  
  1028  func anyValueGetter(raw, elem reflect.Value) interface{} {
  1029  	if !elem.IsValid() || !raw.IsValid() {
  1030  		return nil
  1031  	}
  1032  	kind := elem.Kind()
  1033  	switch kind {
  1034  	case reflect.Float32, reflect.Float64,
  1035  		reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,
  1036  		reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
  1037  		if elem.CanAddr() {
  1038  			return getFloat64(kind, unsafe.Pointer(elem.UnsafeAddr()))
  1039  		}
  1040  		switch kind {
  1041  		case reflect.Float32, reflect.Float64:
  1042  			return elem.Float()
  1043  		case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
  1044  			return float64(elem.Int())
  1045  		case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
  1046  			return float64(elem.Uint())
  1047  		}
  1048  	case reflect.String:
  1049  		return elem.String()
  1050  	case reflect.Bool:
  1051  		return elem.Bool()
  1052  	}
  1053  	if raw.CanInterface() {
  1054  		return raw.Interface()
  1055  	}
  1056  	return nil
  1057  }
  1058  
  1059  func safeIsNil(v reflect.Value) bool {
  1060  	if !v.IsValid() {
  1061  		return true
  1062  	}
  1063  	switch v.Kind() {
  1064  	case reflect.Chan, reflect.Func, reflect.Map, reflect.Ptr,
  1065  		reflect.UnsafePointer, reflect.Interface, reflect.Slice:
  1066  		return v.IsNil()
  1067  	}
  1068  	return false
  1069  }
  1070  
  1071  //go:nocheckptr
  1072  func ptrElem(ptr unsafe.Pointer) unsafe.Pointer {
  1073  	return unsafe.Pointer(*(*uintptr)(ptr))
  1074  }
  1075  
  1076  func derefType(t reflect.Type) reflect.Type {
  1077  	for t.Kind() == reflect.Ptr {
  1078  		t = t.Elem()
  1079  	}
  1080  	return t
  1081  }
  1082  
  1083  func derefValue(v reflect.Value) reflect.Value {
  1084  	for v.Kind() == reflect.Ptr {
  1085  		v = v.Elem()
  1086  	}
  1087  	return v
  1088  }