...
1
2
3 package reflect2
4
5 import (
6 "reflect"
7 "sync"
8 "unsafe"
9 )
10
11
12
13 func typelinks2() (sections []unsafe.Pointer, offset [][]int32)
14
15
16 var initOnce sync.Once
17
18 var types map[string]reflect.Type
19 var packages map[string]map[string]reflect.Type
20
21
22 func discoverTypes() {
23 types = make(map[string]reflect.Type)
24 packages = make(map[string]map[string]reflect.Type)
25
26 loadGoTypes()
27 }
28
29 func loadGoTypes() {
30 var obj interface{} = reflect.TypeOf(0)
31 sections, offset := typelinks2()
32 for i, offs := range offset {
33 rodata := sections[i]
34 for _, off := range offs {
35 (*emptyInterface)(unsafe.Pointer(&obj)).word = resolveTypeOff(unsafe.Pointer(rodata), off)
36 typ := obj.(reflect.Type)
37 if typ.Kind() == reflect.Ptr && typ.Elem().Kind() == reflect.Struct {
38 loadedType := typ.Elem()
39 pkgTypes := packages[loadedType.PkgPath()]
40 if pkgTypes == nil {
41 pkgTypes = map[string]reflect.Type{}
42 packages[loadedType.PkgPath()] = pkgTypes
43 }
44 types[loadedType.String()] = loadedType
45 pkgTypes[loadedType.Name()] = loadedType
46 }
47 }
48 }
49 }
50
51 type emptyInterface struct {
52 typ unsafe.Pointer
53 word unsafe.Pointer
54 }
55
56
57 func TypeByName(typeName string) Type {
58 initOnce.Do(discoverTypes)
59 return Type2(types[typeName])
60 }
61
62
63 func TypeByPackageName(pkgPath string, name string) Type {
64 initOnce.Do(discoverTypes)
65 pkgTypes := packages[pkgPath]
66 if pkgTypes == nil {
67 return nil
68 }
69 return Type2(pkgTypes[name])
70 }
71
View as plain text