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  }