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