gitee.com/zhongguo168a/gocodes@v0.0.0-20230609140523-e1828349603f/datax/schemax/reflect.go (about)

     1  package schemax
     2  
     3  import (
     4  	"errors"
     5  	"gitee.com/zhongguo168a/gocodes/datax/schemax/basickind"
     6  	"gitee.com/zhongguo168a/gocodes/datax/schemax/fieldkind"
     7  	"reflect"
     8  )
     9  
    10  func CreateDecl(st reflect.Type) IDecl {
    11  	decl := ParseClass(st)
    12  	AddDecl(decl, "")
    13  
    14  	if st.Kind() == reflect.Ptr {
    15  		st = st.Elem()
    16  	}
    17  	for i := 0; i < st.NumField(); i++ {
    18  		field := st.Field(i)
    19  		ftyp := field.Type
    20  		if ftyp.Kind() == reflect.Ptr {
    21  			ftyp = ftyp.Elem()
    22  		}
    23  		if ftyp.Kind() == reflect.Struct {
    24  			CreateDecl(ftyp)
    25  		}
    26  	}
    27  
    28  	return decl
    29  }
    30  
    31  // golang不支持枚举类型,无法在运行时解析
    32  // 如需枚举需求,可通过注解工具创建枚举代码
    33  func ParseEnum(val interface{}) *EnumDecl {
    34  	return nil
    35  }
    36  
    37  func ParseClass(rtyp reflect.Type) *ClassDecl {
    38  	return parseClass(rtyp)
    39  }
    40  
    41  func parseClass(rtyp reflect.Type) *ClassDecl {
    42  	if rtyp.Kind() == reflect.Ptr {
    43  		rtyp = rtyp.Elem()
    44  	}
    45  	decl := &ClassDecl{
    46  		Name: rtyp.String(),
    47  		Parent: func() string {
    48  			for i := 0; i < rtyp.NumField(); i++ {
    49  				ftyp := rtyp.Field(i)
    50  				if ftyp.Anonymous {
    51  					return ftyp.Type.String()
    52  				}
    53  			}
    54  			return ""
    55  
    56  		}(),
    57  		Fields: func() (x []*Field) {
    58  			for i := 0; i < rtyp.NumField(); i++ {
    59  				field := rtyp.Field(i)
    60  				ftyp := field.Type
    61  				if field.Anonymous {
    62  					continue
    63  				}
    64  				f := &Field{
    65  					Name:     field.Name,
    66  					Type:     parseFieldType(ftyp),
    67  					Value:    "",
    68  					Comments: nil,
    69  					Tags:     nil,
    70  					//Unsafe: UnsafeInfo{
    71  					//	Offset: field.Offset,
    72  					//	Kind:   ftyp.Kind(),
    73  					//},
    74  				}
    75  				x = append(x, f)
    76  			}
    77  			return
    78  
    79  		}(),
    80  		Comments: nil,
    81  		Tags:     nil,
    82  	}
    83  
    84  	return decl
    85  }
    86  
    87  func parseFieldType(ftyp reflect.Type) (r IType) {
    88  	switch ftyp.Kind() {
    89  	case reflect.Ptr:
    90  		ftyp = ftyp.Elem()
    91  		switch fieldkind.ReflectToFieldKind(ftyp) {
    92  		case fieldkind.Class:
    93  		default:
    94  			panic(errors.New("not support field type [kind" + ftyp.String() + "]"))
    95  		}
    96  	default:
    97  	}
    98  
    99  	switch fieldkind.ReflectToFieldKind(ftyp) {
   100  	case fieldkind.Class:
   101  		r = &ClassType{
   102  			Decl: ftyp.String(),
   103  		}
   104  	case fieldkind.Map:
   105  		r = &MapType{
   106  			Key:   parseFieldType(ftyp.Key()),
   107  			Value: parseFieldType(ftyp.Elem()),
   108  		}
   109  	case fieldkind.Array:
   110  		r = &ArrayType{
   111  			Elem: parseFieldType(ftyp.Elem()),
   112  		}
   113  	case fieldkind.Enum:
   114  		r = &EnumType{
   115  			Decl: ftyp.String(),
   116  		}
   117  	case fieldkind.Basic:
   118  		r = &BasicType{
   119  			Kind: basickind.ReflectKindToBasicKind(ftyp.Kind()),
   120  		}
   121  	case fieldkind.Any:
   122  		r = &AnyType{}
   123  	default:
   124  		panic(errors.New("not support field type [kind" + ftyp.String() + "]"))
   125  	}
   126  
   127  	return
   128  }