github.com/bingoohuang/gg@v0.0.0-20240325092523-45da7dee9335/pkg/goo/goo.go (about)

     1  package goo
     2  
     3  import (
     4  	"errors"
     5  	"fmt"
     6  	"math"
     7  	"math/bits"
     8  	"reflect"
     9  	"runtime"
    10  	"strconv"
    11  	"strings"
    12  	"unicode"
    13  )
    14  
    15  // https://burakkokenn.medium.com/go-goo-c6921cdac348
    16  // https://github.com/procyon-projects/goo
    17  
    18  type Exportable interface {
    19  	IsExported() bool
    20  }
    21  
    22  type Invokable interface {
    23  	Invoke(obj interface{}, args ...interface{}) []interface{}
    24  }
    25  
    26  type Member interface {
    27  	Exportable
    28  	Name() string
    29  	String() string
    30  }
    31  
    32  type New interface {
    33  	New() interface{}
    34  }
    35  
    36  type Interface interface {
    37  	Type
    38  	Methods() []Method
    39  	MethodNum() int
    40  }
    41  
    42  type intType struct {
    43  	*baseType
    44  }
    45  
    46  func newIntType(baseTyp *baseType) intType { return intType{baseType: baseTyp} }
    47  
    48  func (t intType) Methods() []Method {
    49  	num := t.MethodNum()
    50  	methods := make([]Method, num)
    51  	for i := 0; i < num; i++ {
    52  		methods[i] = ConvertGoMethod(t.typ.Method(i))
    53  	}
    54  	return methods
    55  }
    56  
    57  func (t intType) MethodNum() int { return t.typ.NumMethod() }
    58  
    59  type Bool interface {
    60  	Type
    61  	New
    62  	ToBool(value string) bool
    63  	ToStr(value bool) string
    64  }
    65  
    66  type boolType struct {
    67  	*baseType
    68  }
    69  
    70  func newBoolType(baseTyp *baseType) Bool { return boolType{baseType: baseTyp} }
    71  
    72  func (b boolType) ToBool(value string) bool {
    73  	if value == "true" {
    74  		return true
    75  	} else if value == "false" {
    76  		return false
    77  	}
    78  	panic("Given value is not true or false")
    79  }
    80  
    81  func (b boolType) ToStr(value bool) string {
    82  	if value {
    83  		return "true"
    84  	}
    85  	return "false"
    86  }
    87  
    88  func (b boolType) New() interface{} { return reflect.New(b.GoType()).Interface() }
    89  
    90  type Array interface {
    91  	Type
    92  	New
    93  	ElemType() Type
    94  	Len() int
    95  }
    96  
    97  type arrayType struct {
    98  	*baseType
    99  	elementType Type
   100  	length      int
   101  }
   102  
   103  func newArrayType(baseTyp *baseType) Array {
   104  	return arrayType{
   105  		baseType:    baseTyp,
   106  		elementType: FromGoType(baseTyp.GoType().Elem()),
   107  		length:      baseTyp.GoType().Len(),
   108  	}
   109  }
   110  
   111  func (t arrayType) ElemType() Type   { return t.elementType }
   112  func (t arrayType) Len() int         { return t.length }
   113  func (t arrayType) New() interface{} { return reflect.New(t.GoType()).Interface() }
   114  
   115  type Field interface {
   116  	Member
   117  	Taggable
   118  	IsAnonymous() bool
   119  	Type() Type
   120  	CanSet() bool
   121  	Set(instance interface{}, value interface{})
   122  	Get(instance interface{}) interface{}
   123  }
   124  
   125  type field struct {
   126  	name        string
   127  	typ         Type
   128  	tags        reflect.StructTag
   129  	isAnonymous bool
   130  	isExported  bool
   131  	index       []int
   132  }
   133  
   134  func newField(name string, typ Type, isAnonymous, exported bool, tags reflect.StructTag, index []int) field {
   135  	return field{
   136  		name:        name,
   137  		typ:         typ,
   138  		isAnonymous: isAnonymous,
   139  		tags:        tags,
   140  		isExported:  exported,
   141  		index:       index,
   142  	}
   143  }
   144  
   145  func (f field) Name() string      { return f.name }
   146  func (f field) IsAnonymous() bool { return f.isAnonymous }
   147  func (f field) IsExported() bool  { return f.isExported }
   148  func (f field) CanSet() bool      { return f.isExported }
   149  func (f field) Type() Type        { return f.typ }
   150  func (f field) String() string    { return f.name }
   151  
   152  func (f field) Tags() (fieldTags []Tag) {
   153  	tags := f.tags
   154  	for tags != "" {
   155  		i := 0
   156  		for i < len(tags) && tags[i] == ' ' {
   157  			i++
   158  		}
   159  		tags = tags[i:]
   160  		if tags == "" {
   161  			break
   162  		}
   163  
   164  		i = 0
   165  		for i < len(tags) && tags[i] > ' ' && tags[i] != ':' && tags[i] != '"' && tags[i] != 0x7f {
   166  			i++
   167  		}
   168  		if i == 0 || i+1 >= len(tags) || tags[i] != ':' || tags[i+1] != '"' {
   169  			break
   170  		}
   171  		name := string(tags[:i])
   172  		tags = tags[i+1:]
   173  
   174  		i = 1
   175  		for i < len(tags) && tags[i] != '"' {
   176  			if tags[i] == '\\' {
   177  				i++
   178  			}
   179  			i++
   180  		}
   181  		if i >= len(tags) {
   182  			break
   183  		}
   184  		quotedValue := string(tags[:i+1])
   185  		tags = tags[i+1:]
   186  
   187  		value, err := strconv.Unquote(quotedValue)
   188  		if err != nil {
   189  			break
   190  		}
   191  
   192  		fieldTags = append(fieldTags, Tag{Name: name, Value: value})
   193  	}
   194  	return fieldTags
   195  }
   196  
   197  func (f field) TagByName(name string) (Tag, error) {
   198  	if v, ok := f.tags.Lookup(name); ok {
   199  		return Tag{Name: name, Value: v}, nil
   200  	}
   201  	return Tag{}, fmt.Errorf("Tag named %s not found ", name)
   202  }
   203  
   204  func (f field) Set(instance interface{}, value interface{}) {
   205  	if !f.CanSet() {
   206  		panic("Field cannot be set because of it is an unexported f")
   207  	}
   208  	typ := TypeOf(instance)
   209  	if !typ.IsStruct() {
   210  		panic("Instance must only be a struct")
   211  	}
   212  	if !typ.IsPtr() {
   213  		panic("Instance type must be a pointer")
   214  	}
   215  	v := typ.GoPtrValue().FieldByIndex(f.index)
   216  	v.Set(reflect.ValueOf(value))
   217  }
   218  
   219  func (f field) Get(instance interface{}) interface{} {
   220  	typ := TypeOf(instance)
   221  	if !typ.IsStruct() {
   222  		panic("Instance must only be a struct")
   223  	}
   224  	structType := typ.GoType()
   225  	structValueType := typ.GoValue()
   226  	if typ.IsPtr() {
   227  		structValueType = typ.GoPtrValue()
   228  	}
   229  	fieldType := structType.FieldByIndex(f.index)
   230  	if !IsFieldExported(fieldType) {
   231  		panic("Field is not exported, you cannot get the value : " + f.name)
   232  	}
   233  
   234  	fv := structValueType.FieldByIndex(f.index)
   235  	if fieldType.Type.Kind() != reflect.Ptr {
   236  		return fv.Interface()
   237  	}
   238  
   239  	return fv.Addr().Interface()
   240  }
   241  
   242  type Func interface {
   243  	Type
   244  	InTypes() []Type
   245  	InNum() int
   246  	OutTypes() []Type
   247  	OutNum() int
   248  	Call(args []interface{}) []interface{}
   249  }
   250  
   251  type funcType struct {
   252  	*baseType
   253  }
   254  
   255  func newFuncType(baseTyp *baseType) funcType { return funcType{baseType: baseTyp} }
   256  
   257  func (t funcType) InTypes() []Type {
   258  	num := t.InNum()
   259  	parameterTypes := make([]Type, num)
   260  	for i := 0; i < num; i++ {
   261  		parameterTypes[i] = FromGoType(t.typ.In(i))
   262  	}
   263  	return parameterTypes
   264  }
   265  
   266  func (t funcType) InNum() int  { return t.typ.NumIn() }
   267  func (t funcType) OutNum() int { return t.typ.NumOut() }
   268  
   269  func (t funcType) OutTypes() []Type {
   270  	num := t.OutNum()
   271  	outTypes := make([]Type, num)
   272  	for i := 0; i < num; i++ {
   273  		outTypes[i] = FromGoType(t.typ.Out(i))
   274  	}
   275  	return outTypes
   276  }
   277  
   278  func (t funcType) Call(args []interface{}) []interface{} {
   279  	num := t.InNum()
   280  	if len(args) != num {
   281  		panic("Parameter counts don't match argument counts")
   282  	}
   283  
   284  	in := make([]reflect.Value, num)
   285  	inTypes := t.InTypes()
   286  	for i, arg := range args {
   287  		if arg != nil {
   288  			in[i] = reflect.ValueOf(arg)
   289  		} else if t := inTypes[i]; t.IsPtr() {
   290  			in[i] = reflect.New(t.PtrType()).Elem()
   291  		} else {
   292  			in[i] = reflect.New(t.GoType()).Elem()
   293  		}
   294  	}
   295  	results := t.val.Call(in)
   296  	out := make([]interface{}, len(results))
   297  	for i, outputParam := range results {
   298  		out[i] = outputParam.Interface()
   299  	}
   300  	return out
   301  }
   302  
   303  type Map interface {
   304  	Type
   305  	New
   306  	KeyType() Type
   307  	ValueType() Type
   308  }
   309  
   310  type mapType struct {
   311  	*baseType
   312  	keyType   Type
   313  	valueType Type
   314  }
   315  
   316  func newMapType(baseTyp *baseType) Map {
   317  	return mapType{
   318  		baseType:  baseTyp,
   319  		keyType:   FromGoType(baseTyp.GoType().Key()),
   320  		valueType: FromGoType(baseTyp.GoType().Elem()),
   321  	}
   322  }
   323  
   324  func (m mapType) KeyType() Type   { return m.keyType }
   325  func (m mapType) ValueType() Type { return m.valueType }
   326  
   327  func (m mapType) New() interface{} {
   328  	return reflect.MakeMapWithSize(reflect.MapOf(m.keyType.GoType(), m.valueType.GoType()), 0).Interface()
   329  }
   330  
   331  type Method interface {
   332  	Member
   333  	Invokable
   334  	OutNum() int
   335  	OutTypes() []Type
   336  	InNum() int
   337  	InTypes() []Type
   338  }
   339  
   340  type method struct {
   341  	typ        reflect.Type
   342  	name       string
   343  	isExported bool
   344  	fn         reflect.Value
   345  	index      int
   346  }
   347  
   348  func newMethod(methodType reflect.Type, name string, exported bool, fn reflect.Value, index int) method {
   349  	return method{
   350  		typ:        methodType,
   351  		name:       name,
   352  		isExported: exported,
   353  		fn:         fn,
   354  		index:      index,
   355  	}
   356  }
   357  
   358  func (m method) Name() string     { return m.name }
   359  func (m method) IsExported() bool { return m.isExported }
   360  func (m method) String() string   { return m.name }
   361  func (m method) OutNum() int      { return m.typ.NumOut() }
   362  func (m method) InNum() int       { return m.typ.NumIn() }
   363  
   364  func (m method) Invoke(obj interface{}, args ...interface{}) []interface{} {
   365  	typ := TypeOf(obj)
   366  	if !typ.IsStruct() {
   367  		panic("obj must be a struct instance")
   368  	}
   369  
   370  	if num := m.InNum(); len(args) != num-1 {
   371  		panic("Parameter counts don't match argument counts")
   372  	}
   373  
   374  	args = append([]interface{}{obj}, args[:]...)
   375  	in := make([]reflect.Value, len(args))
   376  	inTypes := m.InTypes()
   377  	for i, arg := range args {
   378  		if arg != nil {
   379  			in[i] = reflect.ValueOf(arg)
   380  		} else if t := inTypes[i]; t.IsPtr() {
   381  			in[i] = reflect.New(t.PtrType()).Elem()
   382  		} else {
   383  			in[i] = reflect.New(t.GoType()).Elem()
   384  		}
   385  	}
   386  
   387  	results := typ.GoType().Method(m.index).Func.Call(in)
   388  	out := make([]interface{}, len(results))
   389  	for i, outputParam := range results {
   390  		out[i] = outputParam.Interface()
   391  	}
   392  	return out
   393  }
   394  
   395  func (m method) OutTypes() []Type {
   396  	num := m.OutNum()
   397  	types := make([]Type, num)
   398  	for i := 0; i < num; i++ {
   399  		types[i] = FromGoType(m.typ.Out(i))
   400  	}
   401  	return types
   402  }
   403  
   404  func (m method) InTypes() []Type {
   405  	num := m.InNum()
   406  	types := make([]Type, num)
   407  	for i := 0; i < num; i++ {
   408  		types[i] = FromGoType(m.typ.In(i))
   409  	}
   410  	return types
   411  }
   412  
   413  type NumberType int
   414  
   415  const (
   416  	IntType NumberType = iota
   417  	FloatType
   418  	ComplexType
   419  )
   420  
   421  type BitSize int
   422  
   423  const (
   424  	Bit8   BitSize = 8
   425  	Bit16  BitSize = 16
   426  	Bit32  BitSize = 32
   427  	Bit64  BitSize = 64
   428  	Bit128 BitSize = 128
   429  )
   430  
   431  type Number interface {
   432  	Type
   433  	New
   434  	Type() NumberType
   435  	BitSize() BitSize
   436  	Overflow(val interface{}) bool
   437  	ToString(val interface{}) string
   438  }
   439  
   440  type Integer interface {
   441  	Number
   442  	IsSigned() bool
   443  }
   444  
   445  type signedType struct {
   446  	*baseType
   447  }
   448  
   449  func newSignedType(baseTyp *baseType) signedType { return signedType{baseType: baseTyp} }
   450  func (t signedType) Type() NumberType            { return IntType }
   451  func (t signedType) IsSigned() bool              { return true }
   452  func (t signedType) New() interface{}            { return reflect.New(t.GoType()).Interface() }
   453  
   454  func (t signedType) BitSize() BitSize {
   455  	switch t.kind {
   456  	case reflect.Int64:
   457  		return Bit64
   458  	case reflect.Int8:
   459  		return Bit8
   460  	case reflect.Int16:
   461  		return Bit16
   462  	case reflect.Int32:
   463  		return Bit32
   464  	default:
   465  		if bits.UintSize == 32 {
   466  			return Bit32
   467  		}
   468  		return Bit64
   469  	}
   470  }
   471  
   472  func (t signedType) Overflow(val interface{}) bool {
   473  	valType := TypeOf(val)
   474  	if !valType.IsNumber() || IntType != valType.(Number).Type() || !valType.(Integer).IsSigned() {
   475  		panic("Given type is not compatible with signed t")
   476  	}
   477  	iv, err := strconv.ParseInt(fmt.Sprintf("%d", val), 10, 64)
   478  	PanicIf(err)
   479  
   480  	s := t.BitSize()
   481  	return Bit8 == s && (math.MinInt8 > iv || math.MaxInt8 < iv) ||
   482  		Bit16 == s && (math.MinInt16 > iv || math.MaxInt16 < iv) ||
   483  		Bit32 == s && (math.MinInt32 > iv || math.MaxInt32 < iv)
   484  }
   485  
   486  func (t signedType) ToString(val interface{}) string {
   487  	valType := TypeOf(val)
   488  	if !valType.IsNumber() || IntType != valType.(Number).Type() || !valType.(Integer).IsSigned() {
   489  		panic("Incompatible type : " + valType.Name())
   490  	}
   491  	return fmt.Sprintf("%d", val)
   492  }
   493  
   494  type unsignedType struct {
   495  	*baseType
   496  }
   497  
   498  func newUnsignedType(baseTyp *baseType) unsignedType { return unsignedType{baseType: baseTyp} }
   499  func (t unsignedType) Type() NumberType              { return IntType }
   500  func (t unsignedType) IsSigned() bool                { return false }
   501  func (t unsignedType) New() interface{}              { return reflect.New(t.GoType()).Interface() }
   502  
   503  func (t unsignedType) BitSize() BitSize {
   504  	switch t.kind {
   505  	case reflect.Uint64:
   506  		return Bit64
   507  	case reflect.Uint8:
   508  		return Bit8
   509  	case reflect.Uint16:
   510  		return Bit16
   511  	case reflect.Uint32:
   512  		return Bit32
   513  	default:
   514  		if bits.UintSize == 32 {
   515  			return Bit32
   516  		}
   517  		return Bit64
   518  	}
   519  }
   520  
   521  func (t unsignedType) Overflow(val interface{}) bool {
   522  	valType := TypeOf(val)
   523  	if !valType.IsNumber() || IntType != valType.(Number).Type() || valType.(Integer).IsSigned() {
   524  		panic("Given type is not compatible with unsigned t")
   525  	}
   526  	v, err := strconv.ParseUint(fmt.Sprintf("%d", val), 10, 64)
   527  	PanicIf(err)
   528  
   529  	size := t.BitSize()
   530  	return Bit8 == size && math.MaxUint8 < v ||
   531  		Bit16 == size && math.MaxUint16 < v ||
   532  		Bit32 == size && math.MaxUint32 < v
   533  }
   534  
   535  func (t unsignedType) ToString(val interface{}) string {
   536  	typ := TypeOf(val)
   537  	if !typ.IsNumber() || IntType != typ.(Number).Type() || typ.(Integer).IsSigned() {
   538  		panic("Incompatible type : " + typ.Name())
   539  	}
   540  	return fmt.Sprintf("%d", val)
   541  }
   542  
   543  type Float interface {
   544  	Number
   545  }
   546  
   547  type floatType struct {
   548  	*baseType
   549  }
   550  
   551  func newFloatType(baseTyp *baseType) Float { return floatType{baseType: baseTyp} }
   552  
   553  func (t floatType) New() interface{} { return reflect.New(t.GoType()).Interface() }
   554  func (t floatType) Type() NumberType { return FloatType }
   555  func (t floatType) BitSize() BitSize { return BitSizeIf(t.kind, reflect.Float32, Bit32, Bit64) }
   556  
   557  func (t floatType) Overflow(val interface{}) bool {
   558  	if typ := TypeOf(val); !typ.IsNumber() || FloatType != typ.(Number).Type() {
   559  		panic("Given type is not compatible with t")
   560  	}
   561  	v, err := strconv.ParseFloat(fmt.Sprintf("%f", val), 64)
   562  	PanicIf(err)
   563  
   564  	size := t.BitSize()
   565  	return Bit32 == size && math.MaxFloat32 < v || Bit64 == size && math.MaxFloat64 < v
   566  }
   567  
   568  func (t floatType) ToString(val interface{}) string {
   569  	valType := TypeOf(val)
   570  	if !valType.IsNumber() || FloatType != valType.(Number).Type() {
   571  		panic("Incompatible type : " + valType.Name())
   572  	}
   573  	return fmt.Sprintf("%f", val)
   574  }
   575  
   576  type Complex interface {
   577  	Number
   578  	ImaginaryData(val interface{}) interface{}
   579  	RealData(val interface{}) interface{}
   580  }
   581  
   582  type complexType struct {
   583  	*baseType
   584  }
   585  
   586  func newComplexType(baseTyp *baseType) Complex    { return complexType{baseType: baseTyp} }
   587  func (t complexType) Type() NumberType            { return ComplexType }
   588  func (t complexType) Overflow(v interface{}) bool { panic("It does not support Overflow for now") }
   589  func (t complexType) BitSize() BitSize            { return BitSizeIf(t.kind, reflect.Complex64, Bit64, Bit128) }
   590  
   591  func BitSizeIf(k, ifv reflect.Kind, a, b BitSize) BitSize {
   592  	if k == ifv {
   593  		return a
   594  	}
   595  
   596  	return b
   597  }
   598  
   599  func (t complexType) ImaginaryData(val interface{}) interface{} {
   600  	typ := TypeOf(val)
   601  	if !typ.IsNumber() || ComplexType != typ.(Number).Type() {
   602  		panic("Given type is not compatible with t")
   603  	}
   604  
   605  	if t.BitSize() == Bit64 {
   606  		return imag(val.(complex64))
   607  	}
   608  	return imag(val.(complex128))
   609  }
   610  
   611  func (t complexType) RealData(val interface{}) interface{} {
   612  	typ := TypeOf(val)
   613  	if !typ.IsNumber() || ComplexType != typ.(Number).Type() {
   614  		panic("Given type is not compatible with t")
   615  	}
   616  
   617  	if t.BitSize() == Bit64 {
   618  		return real(val.(complex64))
   619  	}
   620  	return real(val.(complex128))
   621  }
   622  
   623  func (t complexType) New() interface{} { return reflect.New(t.GoType()).Interface() }
   624  
   625  func (t complexType) ToString(val interface{}) string {
   626  	if typ := TypeOf(val); !typ.IsNumber() || ComplexType != typ.(Number).Type() {
   627  		panic("Incompatible type : " + typ.Name())
   628  	}
   629  	return fmt.Sprintf("%f", val)
   630  }
   631  
   632  type Slice interface {
   633  	Type
   634  	New
   635  	GetElementType() Type
   636  }
   637  
   638  type sliceType struct {
   639  	*baseType
   640  	elementType Type
   641  }
   642  
   643  func newSliceType(baseTyp *baseType) Slice {
   644  	return sliceType{
   645  		baseType:    baseTyp,
   646  		elementType: FromGoType(baseTyp.GoType().Elem()),
   647  	}
   648  }
   649  
   650  func (t sliceType) GetElementType() Type { return t.elementType }
   651  
   652  func (t sliceType) New() interface{} {
   653  	return reflect.MakeSlice(t.GoType(), t.val.Len(), t.val.Cap()).Interface()
   654  }
   655  
   656  type String interface {
   657  	Type
   658  	New
   659  	ToNumber(val string, number Number) (interface{}, error)
   660  	ToInt(val string) int
   661  	ToInt8(val string) int8
   662  	ToInt16(val string) int16
   663  	ToInt32(val string) int32
   664  	ToInt64(val string) int64
   665  	ToUint(val string) uint
   666  	ToUint8(val string) uint8
   667  	ToUint16(val string) uint16
   668  	ToUint32(val string) uint32
   669  	ToUint64(val string) uint64
   670  	ToFloat32(val string) float32
   671  	ToFloat64(val string) float64
   672  }
   673  
   674  type stringType struct {
   675  	*baseType
   676  }
   677  
   678  func newStringType(baseTyp *baseType) stringType {
   679  	return stringType{
   680  		baseType: baseTyp,
   681  	}
   682  }
   683  
   684  func (t stringType) ToNumber(val string, number Number) (interface{}, error) {
   685  	if number == nil {
   686  		panic("Number must not be null")
   687  	}
   688  
   689  	if numberType := number.Type(); IntType == numberType {
   690  		return ParseInt(val, number.(Integer))
   691  	} else if FloatType == numberType {
   692  		return getFloatValue(val, number.(Float))
   693  	}
   694  	return nil, errors.New("complex numbers does not support for now")
   695  }
   696  
   697  func (t stringType) ToInt(val string) int {
   698  	var result interface{}
   699  	if bits.UintSize == 32 {
   700  		result = parseInt(val, Bit32, true)
   701  	} else {
   702  		result = parseInt(val, Bit64, true)
   703  	}
   704  
   705  	if bits.UintSize == 32 {
   706  		return result.(int)
   707  	}
   708  	return int(result.(int64))
   709  }
   710  
   711  func (t stringType) ToInt8(val string) int8   { return parseInt(val, Bit8, true).(int8) }
   712  func (t stringType) ToInt16(val string) int16 { return parseInt(val, Bit16, true).(int16) }
   713  func (t stringType) ToInt32(val string) int32 { return parseInt(val, Bit32, true).(int32) }
   714  func (t stringType) ToInt64(val string) int64 { return parseInt(val, Bit64, true).(int64) }
   715  
   716  func PanicIf(err error) {
   717  	if err != nil {
   718  		panic(err)
   719  	}
   720  }
   721  
   722  func (t stringType) ToUint(val string) uint {
   723  	var result interface{}
   724  	if bits.UintSize == 32 {
   725  		result = parseInt(val, Bit32, false)
   726  	} else {
   727  		result = parseInt(val, Bit64, false)
   728  	}
   729  
   730  	if bits.UintSize == 32 {
   731  		return result.(uint)
   732  	}
   733  	lastValue := result.(uint64)
   734  	return uint(lastValue)
   735  }
   736  
   737  func (t stringType) ToUint8(val string) uint8     { return parseInt(val, Bit8, false).(uint8) }
   738  func (t stringType) ToUint16(val string) uint16   { return parseInt(val, Bit16, false).(uint16) }
   739  func (t stringType) ToUint32(val string) uint32   { return parseInt(val, Bit32, false).(uint32) }
   740  func (t stringType) ToUint64(val string) uint64   { return parseInt(val, Bit64, false).(uint64) }
   741  func (t stringType) ToFloat32(val string) float32 { return float32(ParseFloat(val, int(Bit32))) }
   742  func (t stringType) ToFloat64(val string) float64 { return ParseFloat(val, int(Bit64)) }
   743  
   744  func ParseFloat(val string, bitSize int) float64 {
   745  	v, err := strconv.ParseFloat(val, bitSize)
   746  	PanicIf(err)
   747  	return v
   748  }
   749  
   750  func ParseInt(s string, typ Integer) (resultValue interface{}, err error) {
   751  	var value interface{}
   752  	var signedValue int64
   753  	var unsignedValue uint64
   754  	if typ.IsSigned() {
   755  		signedValue, err = strconv.ParseInt(s, 10, 64)
   756  		value = signedValue
   757  	} else {
   758  		unsignedValue, err = strconv.ParseUint(s, 10, 64)
   759  		value = unsignedValue
   760  	}
   761  
   762  	if err != nil {
   763  		return nil, err
   764  	}
   765  
   766  	if typ.Overflow(value) {
   767  		return nil, errors.New("The given value is out of range of the typ type : " + typ.String())
   768  	}
   769  
   770  	intVal := reflect.New(typ.GoType()).Elem()
   771  	if typ.IsSigned() {
   772  		intVal.SetInt(signedValue)
   773  	} else {
   774  		intVal.SetUint(unsignedValue)
   775  	}
   776  	resultValue = intVal.Interface()
   777  	return
   778  }
   779  
   780  func parseInt(s string, bitSize BitSize, isSigned bool) (result interface{}) {
   781  	if Bit128 == bitSize {
   782  		panic("BitSize does not support 128")
   783  	}
   784  
   785  	var signedValue int64
   786  	var unsignedValue uint64
   787  	var err error
   788  	if isSigned {
   789  		signedValue, err = strconv.ParseInt(s, 10, 64)
   790  	} else {
   791  		unsignedValue, err = strconv.ParseUint(s, 10, 64)
   792  	}
   793  	PanicIf(err)
   794  
   795  	overflow := false
   796  	if isSigned {
   797  		overflow = Bit8 == bitSize && (math.MinInt8 > signedValue || math.MaxInt8 < signedValue) ||
   798  			Bit16 == bitSize && (math.MinInt16 > signedValue || math.MaxInt16 < signedValue) ||
   799  			Bit32 == bitSize && (math.MinInt32 > signedValue || math.MaxInt32 < signedValue)
   800  	} else {
   801  		overflow = Bit8 == bitSize && math.MaxUint8 < unsignedValue ||
   802  			Bit16 == bitSize && math.MaxUint16 < unsignedValue ||
   803  			Bit32 == bitSize && math.MaxUint32 < unsignedValue
   804  	}
   805  
   806  	if overflow {
   807  		panic("the given value is out of range of the integer type")
   808  	}
   809  
   810  	if isSigned {
   811  		if Bit8 == bitSize {
   812  			return int8(signedValue)
   813  		} else if Bit16 == bitSize {
   814  			return int16(signedValue)
   815  		} else if Bit32 == bitSize {
   816  			return int32(signedValue)
   817  		}
   818  		return signedValue
   819  	}
   820  
   821  	if Bit8 == bitSize {
   822  		return uint8(unsignedValue)
   823  	} else if Bit16 == bitSize {
   824  		return uint16(unsignedValue)
   825  	} else if Bit32 == bitSize {
   826  		return uint32(unsignedValue)
   827  	}
   828  	return unsignedValue
   829  }
   830  
   831  func getFloatValue(strValue string, float Float) (resultValue interface{}, err error) {
   832  	var value float64
   833  	value, err = strconv.ParseFloat(strValue, 64)
   834  	if err != nil {
   835  		return nil, err
   836  	}
   837  
   838  	if float.Overflow(value) {
   839  		return nil, errors.New("The given value is out of range of the float type : " + float.String())
   840  	}
   841  	floatValue := reflect.New(float.GoType()).Elem()
   842  	floatValue.SetFloat(value)
   843  	resultValue = floatValue.Interface()
   844  	return
   845  }
   846  
   847  func (t stringType) New() interface{} { return reflect.New(t.GoType()).Interface() }
   848  
   849  type Struct interface {
   850  	Type
   851  	New
   852  	Fields() []Field
   853  	FieldNum() int
   854  	FieldsExported() []Field
   855  	FieldExportedNum() int
   856  	FieldsUnexported() []Field
   857  	FieldUnexportedNum() int
   858  	FieldsAnonymous() []Field
   859  	FieldAnonymousNum() int
   860  	Methods() []Method
   861  	MethodNum() int
   862  	Implements(i Interface) bool
   863  	IsEmbedded(candidate Struct) bool
   864  }
   865  
   866  type structType struct {
   867  	*baseType
   868  }
   869  
   870  func newStructType(baseTyp *baseType) structType {
   871  	return structType{
   872  		baseType: baseTyp,
   873  	}
   874  }
   875  
   876  func (t structType) Fields() []Field {
   877  	num := t.FieldNum()
   878  	fields := make([]Field, num)
   879  	for i := 0; i < num; i++ {
   880  		fields[i] = ConvertGoField(t.typ.Field(i))
   881  	}
   882  	return fields
   883  }
   884  
   885  func (t structType) FieldNum() int { return t.typ.NumField() }
   886  
   887  func (t structType) FieldsExported() []Field {
   888  	return t.FieldsIf(func(f Field) bool { return f.IsExported() })
   889  }
   890  
   891  func (t structType) FieldExportedNum() int {
   892  	return t.NumIf(func(f Field) bool { return f.IsExported() })
   893  }
   894  
   895  func (t structType) FieldsUnexported() []Field {
   896  	return t.FieldsIf(func(f Field) bool { return !f.IsExported() })
   897  }
   898  
   899  func (t structType) FieldUnexportedNum() int {
   900  	return t.NumIf(func(f Field) bool { return !f.IsExported() })
   901  }
   902  
   903  func (t structType) FieldsAnonymous() []Field {
   904  	return t.FieldsIf(func(f Field) bool { return f.IsAnonymous() })
   905  }
   906  
   907  func (t structType) FieldAnonymousNum() int {
   908  	return t.NumIf(func(f Field) bool { return f.IsAnonymous() })
   909  }
   910  
   911  func (t structType) FieldsIf(predicate func(Field) bool) (fields []Field) {
   912  	for _, field := range t.Fields() {
   913  		if predicate(field) {
   914  			fields = append(fields, field)
   915  		}
   916  	}
   917  	return fields
   918  }
   919  
   920  func (t structType) NumIf(predicate func(Field) bool) (n int) {
   921  	for _, field := range t.Fields() {
   922  		if predicate(field) {
   923  			n++
   924  		}
   925  	}
   926  	return n
   927  }
   928  
   929  func (t structType) Methods() (methods []Method) {
   930  	for i := 0; i < t.MethodNum(); i++ {
   931  		var method reflect.Method
   932  		if t.isPtr {
   933  			method = t.ptrType.Method(i)
   934  		} else {
   935  			method = t.typ.Method(i)
   936  		}
   937  		methods = append(methods, ConvertGoMethod(method))
   938  	}
   939  	return methods
   940  }
   941  
   942  func (t structType) MethodNum() int {
   943  	if t.isPtr {
   944  		return t.ptrType.NumMethod()
   945  	}
   946  	return t.typ.NumMethod()
   947  }
   948  
   949  func (t structType) Implements(i Interface) bool {
   950  	if t.isPtr {
   951  		return t.PtrType().Implements(i.GoType())
   952  	}
   953  	return t.GoType().Implements(i.GoType())
   954  }
   955  
   956  func (t structType) New() interface{} { return reflect.New(t.GoType()).Interface() }
   957  
   958  func (t structType) IsEmbedded(candidate Struct) bool {
   959  	if candidate == nil {
   960  		panic("candidate must not be null")
   961  	}
   962  	return t.embeddedStruct(t, candidate)
   963  }
   964  
   965  func (t structType) embeddedStruct(parent Struct, candidate Struct) bool {
   966  	for _, f := range parent.Fields() {
   967  		if f.IsAnonymous() && f.Type().IsStruct() {
   968  			if candidate.Equals(f.Type()) {
   969  				return true
   970  			}
   971  			if f.Type().(Struct).FieldNum() > 0 {
   972  				return t.embeddedStruct(f.Type().(Struct), candidate)
   973  			}
   974  		}
   975  	}
   976  	return false
   977  }
   978  
   979  type Tag struct {
   980  	Name  string
   981  	Value string
   982  }
   983  
   984  func (t Tag) String() string { return t.Name + "->" + t.Value }
   985  
   986  type Taggable interface {
   987  	Tags() []Tag
   988  	TagByName(name string) (Tag, error)
   989  }
   990  
   991  type TypeConverter interface {
   992  	IsBool() bool
   993  	ToBoolType() Bool
   994  	IsNumber() bool
   995  	ToNumberType() Number
   996  	IsFunc() bool
   997  	ToFuncType() Func
   998  	IsStruct() bool
   999  	ToStructType() Struct
  1000  	IsInterface() bool
  1001  	ToInterfaceType() Interface
  1002  	IsString() bool
  1003  	ToStringType() String
  1004  	IsMap() bool
  1005  	ToMapType() Map
  1006  	IsArray() bool
  1007  	ToArrayType() Array
  1008  	IsSlice() bool
  1009  	ToSliceType() Slice
  1010  }
  1011  
  1012  type Type interface {
  1013  	TypeConverter
  1014  	Name() string
  1015  	NameFull() string
  1016  	PkgName() string
  1017  	PkgNameFull() string
  1018  	PtrType() reflect.Type
  1019  	GoPtrValue() reflect.Value
  1020  	GoType() reflect.Type
  1021  	GoValue() reflect.Value
  1022  	IsPtr() bool
  1023  	IsInstantiable() bool
  1024  	String() string
  1025  	Equals(anotherType Type) bool
  1026  }
  1027  
  1028  type baseType struct {
  1029  	parentType  interface{}
  1030  	name        string
  1031  	pkgName     string
  1032  	pkgFullName string
  1033  	typ         reflect.Type
  1034  	val         reflect.Value
  1035  	ptrType     reflect.Type
  1036  	ptrVal      reflect.Value
  1037  	kind        reflect.Kind
  1038  	isNumber    bool
  1039  	isPtr       bool
  1040  }
  1041  
  1042  func newBaseType(typ reflect.Type, val reflect.Value) *baseType {
  1043  	return &baseType{
  1044  		name:        getTypeName(typ, val),
  1045  		pkgName:     getPkgName(typ, val),
  1046  		pkgFullName: getPkgFullName(typ, val),
  1047  		typ:         typ,
  1048  		val:         val,
  1049  		kind:        typ.Kind(),
  1050  		isNumber:    IsNumber(typ),
  1051  	}
  1052  }
  1053  
  1054  func (t baseType) NameFull() string {
  1055  	if t.pkgFullName == "" {
  1056  		return t.name
  1057  	}
  1058  	return t.pkgFullName + "." + t.name
  1059  }
  1060  func (t baseType) Name() string               { return t.name }
  1061  func (t baseType) PkgName() string            { return t.pkgName }
  1062  func (t baseType) PkgNameFull() string        { return t.pkgFullName }
  1063  func (t baseType) PtrType() reflect.Type      { return t.ptrType }
  1064  func (t baseType) GoPtrValue() reflect.Value  { return t.ptrVal }
  1065  func (t baseType) GoType() reflect.Type       { return t.typ }
  1066  func (t baseType) GoValue() reflect.Value     { return t.val }
  1067  func (t baseType) IsBool() bool               { return reflect.Bool == t.kind }
  1068  func (t baseType) IsNumber() bool             { return t.isNumber }
  1069  func (t baseType) IsFunc() bool               { return reflect.Func == t.kind }
  1070  func (t baseType) IsStruct() bool             { return reflect.Struct == t.kind }
  1071  func (t baseType) IsInterface() bool          { return reflect.Interface == t.kind }
  1072  func (t baseType) IsString() bool             { return reflect.String == t.kind }
  1073  func (t baseType) IsMap() bool                { return reflect.Map == t.kind }
  1074  func (t baseType) IsArray() bool              { return reflect.Array == t.kind }
  1075  func (t baseType) IsSlice() bool              { return reflect.Slice == t.kind }
  1076  func (t baseType) IsPtr() bool                { return t.isPtr }
  1077  func (t baseType) IsInstantiable() bool       { return !(t.IsInterface() || t.IsFunc()) }
  1078  func (t baseType) ToBoolType() Bool           { return t.parentType.(Bool) }
  1079  func (t baseType) ToNumberType() Number       { return t.parentType.(Number) }
  1080  func (t baseType) ToFuncType() Func           { return t.parentType.(Func) }
  1081  func (t baseType) ToInterfaceType() Interface { return t.parentType.(Interface) }
  1082  func (t baseType) ToStringType() String       { return t.parentType.(String) }
  1083  func (t baseType) ToMapType() Map             { return t.parentType.(Map) }
  1084  func (t baseType) ToArrayType() Array         { return t.parentType.(Array) }
  1085  func (t baseType) ToSliceType() Slice         { return t.parentType.(Slice) }
  1086  func (t baseType) ToStructType() Struct       { return t.parentType.(Struct) }
  1087  func (t baseType) String() string             { return t.name }
  1088  func (t baseType) Equals(that Type) bool      { return that != nil && t.typ == that.GoType() }
  1089  
  1090  func TypeOf(obj interface{}) Type {
  1091  	typ, val, isPtr := GoTypeAndValue(obj)
  1092  	baseTyp := newBaseType(typ, val)
  1093  	populatePtrInfo(obj, baseTyp, isPtr)
  1094  	actualType := getActualTypeFromBaseType(baseTyp)
  1095  	baseTyp.parentType = actualType
  1096  	return actualType
  1097  }
  1098  
  1099  func populatePtrInfo(obj interface{}, baseType *baseType, isPtr bool) {
  1100  	if isPtr {
  1101  		typ, val := GoPtrTypeAndValue(obj)
  1102  		baseType.isPtr = true
  1103  		baseType.ptrType = typ
  1104  		baseType.ptrVal = val
  1105  	}
  1106  }
  1107  
  1108  func FromGoType(typ reflect.Type) Type {
  1109  	if typ == nil {
  1110  		panic("Type cannot be nil")
  1111  	}
  1112  	var ptrType reflect.Type
  1113  	isPtr := typ.Kind() == reflect.Ptr
  1114  	if isPtr {
  1115  		ptrType = typ
  1116  		typ = typ.Elem()
  1117  	}
  1118  	baseTyp := newBaseType(typ, reflect.Value{})
  1119  	actualType := getActualTypeFromBaseType(baseTyp)
  1120  	baseTyp.parentType = actualType
  1121  	if isPtr {
  1122  		baseTyp.ptrType = ptrType
  1123  		baseTyp.isPtr = true
  1124  	}
  1125  	return actualType
  1126  }
  1127  
  1128  func sanitizedName(str string) string {
  1129  	n := strings.ReplaceAll(str, "/", ".")
  1130  	n = strings.ReplaceAll(n, "-", ".")
  1131  	return strings.ReplaceAll(n, "_", ".")
  1132  }
  1133  
  1134  func getActualTypeFromBaseType(b *baseType) Type {
  1135  	switch {
  1136  	case b.IsFunc():
  1137  		return newFuncType(b)
  1138  	case b.IsInterface():
  1139  		return newIntType(b)
  1140  	case b.IsStruct():
  1141  		return newStructType(b)
  1142  	case b.IsNumber():
  1143  		switch {
  1144  		case IsSigned(b.typ):
  1145  			return newSignedType(b)
  1146  		case IsUnsigned(b.typ):
  1147  			return newUnsignedType(b)
  1148  		case IsFloat(b.typ):
  1149  			return newFloatType(b)
  1150  		case IsComplex(b.typ):
  1151  			return newComplexType(b)
  1152  		}
  1153  	case b.IsString():
  1154  		return newStringType(b)
  1155  	case b.IsBool():
  1156  		return newBoolType(b)
  1157  	case b.IsMap():
  1158  		return newMapType(b)
  1159  	case b.IsArray():
  1160  		return newArrayType(b)
  1161  	case b.IsSlice():
  1162  		return newSliceType(b)
  1163  	}
  1164  	panic(b.Name() + " isn't supported for now")
  1165  }
  1166  
  1167  func getTypeName(typ reflect.Type, val reflect.Value) string {
  1168  	defer func() { recover() }()
  1169  	switch typ.Kind() {
  1170  	case reflect.Struct, reflect.Interface:
  1171  		return GoTypeName(typ)
  1172  	case reflect.Func:
  1173  		return GoFuncName(val)
  1174  	}
  1175  	return typ.Name()
  1176  }
  1177  
  1178  func GoTypeAndValue(obj interface{}) (reflect.Type, reflect.Value, bool) {
  1179  	typ := reflect.TypeOf(obj)
  1180  	if typ == nil {
  1181  		panic("Type cannot be determined as the given object is nil")
  1182  	}
  1183  	isPtr := typ.Kind() == reflect.Ptr
  1184  	if isPtr {
  1185  		typ = typ.Elem()
  1186  	}
  1187  	val := reflect.ValueOf(obj)
  1188  	if val.Kind() == reflect.Ptr {
  1189  		val = val.Elem()
  1190  	}
  1191  
  1192  	return typ, val, isPtr
  1193  }
  1194  
  1195  func GoPtrTypeAndValue(obj interface{}) (reflect.Type, reflect.Value) {
  1196  	typ := reflect.TypeOf(obj)
  1197  	if typ == nil {
  1198  		panic("Type cannot be determined as the given object is nil")
  1199  	}
  1200  
  1201  	var ptrType reflect.Type
  1202  	var ptrVal reflect.Value
  1203  	if typ.Kind() == reflect.Ptr {
  1204  		ptrType = typ
  1205  		ptrVal = reflect.ValueOf(obj).Elem()
  1206  	}
  1207  
  1208  	return ptrType, ptrVal
  1209  }
  1210  
  1211  func GoTypeName(typ reflect.Type) string {
  1212  	name := typ.Name()
  1213  	if name != "" {
  1214  		return name
  1215  	}
  1216  	return typ.String()
  1217  }
  1218  
  1219  func getPkgName(typ reflect.Type, val reflect.Value) string {
  1220  	defer func() { recover() }()
  1221  
  1222  	if reflect.Func == typ.Kind() {
  1223  		return FuncPkgName(val)
  1224  	}
  1225  	if i := strings.LastIndex(typ.String(), "."); i >= 0 {
  1226  		return typ.String()[:i]
  1227  	}
  1228  	return ""
  1229  }
  1230  
  1231  func getPkgFullName(typ reflect.Type, val reflect.Value) string {
  1232  	defer func() { recover() }()
  1233  
  1234  	if reflect.Func == typ.Kind() {
  1235  		return FuncPkgFullName(val)
  1236  	}
  1237  	return sanitizedName(typ.PkgPath())
  1238  }
  1239  
  1240  func GoFuncName(val reflect.Value) string {
  1241  	fullName := runtime.FuncForPC(val.Pointer()).Name()
  1242  	if pos := strings.LastIndex(fullName, "."); pos < 0 {
  1243  		return fullName[pos+1:]
  1244  	}
  1245  	return fullName
  1246  }
  1247  
  1248  func FuncPkgFullName(val reflect.Value) string {
  1249  	fullName := runtime.FuncForPC(val.Pointer()).Name()
  1250  	if pos := strings.LastIndex(fullName, "."); pos < 0 {
  1251  		return fullName[:pos]
  1252  	}
  1253  	return sanitizedName(fullName)
  1254  }
  1255  
  1256  func FuncPkgName(val reflect.Value) string {
  1257  	fullName := FuncPkgFullName(val)
  1258  	if pos := strings.LastIndex(fullName, "."); pos < 0 {
  1259  		return fullName[pos+1:]
  1260  	}
  1261  	return fullName
  1262  }
  1263  
  1264  func ConvertGoField(f reflect.StructField) Field {
  1265  	return newField(f.Name, FromGoType(f.Type), f.Anonymous, IsFieldExported(f), f.Tag, f.Index)
  1266  }
  1267  
  1268  func IsFieldExported(f reflect.StructField) bool { return unicode.IsUpper(rune(f.Name[0])) }
  1269  func IsMethodExported(m reflect.Method) bool     { return unicode.IsUpper(rune(m.Name[0])) }
  1270  
  1271  func ConvertGoMethod(m reflect.Method) Method {
  1272  	return newMethod(m.Type, m.Name, IsMethodExported(m), m.Func, m.Index)
  1273  }
  1274  
  1275  func IsNumber(typ reflect.Type) bool {
  1276  	return IsAnyKind(typ, reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,
  1277  		reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64,
  1278  		reflect.Float32, reflect.Float64, reflect.Complex64, reflect.Complex128)
  1279  }
  1280  
  1281  func IsSigned(typ reflect.Type) bool {
  1282  	return IsAnyKind(typ, reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64)
  1283  }
  1284  
  1285  func IsUnsigned(typ reflect.Type) bool {
  1286  	return IsAnyKind(typ, reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64)
  1287  }
  1288  func IsFloat(typ reflect.Type) bool   { return IsAnyKind(typ, reflect.Float32, reflect.Float64) }
  1289  func IsComplex(typ reflect.Type) bool { return IsAnyKind(typ, reflect.Complex64, reflect.Complex128) }
  1290  
  1291  func IsAnyKind(typ reflect.Type, kinds ...reflect.Kind) bool {
  1292  	kind := typ.Kind()
  1293  	for _, k := range kinds {
  1294  		if kind == k {
  1295  			return true
  1296  		}
  1297  	}
  1298  
  1299  	return false
  1300  }