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 }