forked from glycerine/greenpack
/
toschema.go
114 lines (104 loc) · 2.88 KB
/
toschema.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
package parse
import (
"fmt"
"github.com/glycerine/greenpack/gen"
"github.com/glycerine/greenpack/green"
//"github.com/shurcooL/go-goon"
)
// TranslateToGreenSchema takes the FileSet already in `fs`,
// assumes it was generated by parsing `path` (to Go
// source file), and returns a Greenpack specified schema;
// i.e. a *green.Schema.
// TODO: handled top-level arrays/other types besides structs.
// Currently we only record structs.
func TranslateToGreenSchema(path string, fs *FileSet) (*green.Schema, error) {
structs := make(map[string]*green.Struct)
for _, ele := range fs.Identities {
switch x := ele.(type) {
case *gen.Struct:
tr := green.Struct{
StructName: x.TypeName(),
}
for _, f := range x.Fields {
zc, zp := getCatPrimiType(&f)
//fmt.Printf("\n on f = %#v\n", f)
//goon.Dump(f)
fld := green.Field{
Zid: f.ZebraId,
OmitEmpty: f.OmitEmpty,
Skip: f.Skip,
FieldGoName: f.FieldName,
FieldTagName: f.FieldTag,
FieldCategory: zc,
FieldPrimitive: zp,
Deprecated: f.Deprecated,
ShowZero: f.ShowZero,
}
if !fld.Skip {
zt := f.FieldElem.GetZtype()
fld.FieldFullType = &zt
fld.FieldTypeStr = f.FieldElem.TypeName()
}
//fmt.Printf("\n in %v, on field %#v ... fld='%#v'\n", tr.StructName, f, fld)
tr.Fields = append(tr.Fields, fld)
}
structs[tr.StructName] = &tr
//structs = append(structs, tr)
/*
case *Ptr:
case *Array:
case *Slice:
case *Map:
case *BaseElem:
*/
default:
//fmt.Fprintf(os.Stderr, "\nwarning: ignoring type '%v'; we only support top-level structs in a schema at present.\n", x.TypeName())
//return nil, fmt.Errorf("unhandled type %T", x)
}
}
imports := []string{}
for _, imp := range fs.Imports {
n := ""
if imp.Name != nil {
n = imp.Name.Name // local package name (including "."); or nil
}
p := imp.Path.Value // import path
if len(n) > 0 {
imports = append(imports, fmt.Sprintf("%s %s", n, p))
} else {
imports = append(imports, p)
}
}
sch := &green.Schema{
SourcePath: path,
SourcePackage: fs.Package,
GreenSchemaId: fs.ZebraSchemaId,
Structs: structs,
Imports: imports,
}
//fmt.Printf("total number of structs: %v\n", len(structs))
//fmt.Printf("total number of fields in first struct: %v\n", len(structs[0].Fields))
return sch, nil
}
func getCatPrimiType(f *gen.StructField) (zc green.Zkind, zp green.Zkind) {
switch e := f.FieldElem.(type) {
case *gen.Map:
zc = green.MapCat
case *gen.Struct:
zc = green.StructCat
case *gen.Slice:
zc = green.SliceCat
case *gen.Array:
zc = green.ArrayCat
case *gen.Ptr:
zc = green.PointerCat
case *gen.BaseElem:
zc = green.BaseElemCat
zp = green.Zkind(e.Value)
case nil:
// struct{} or other skippable, default 0, 0 is fine.
default:
panic(fmt.Errorf("bad element type %T", e))
}
return
}