func Editor(ctx context.Context, env *envctx.Env) (source []byte, err error) { g := builder.New("main") g.Imports.Anonymous("kego.io/system") g.Imports.Anonymous(env.Path) for _, p := range env.Aliases { g.Imports.Anonymous(p) } /* func main() { if err := client.Start(); err != nil { fmt.Println(err.Error()) } } */ g.Println("func main() {") { clientStart := builder.Reference("kego.io/editor/client", "Start", env.Path, g.Imports.Add) g.Println("if err := ", clientStart, "(); err != nil {") { fmtPrintln := builder.Reference("fmt", "Println", env.Path, g.Imports.Add) g.Println(fmtPrintln, "(err.Error())") } g.Println("}") } g.Println("}") b, err := g.Build() if err != nil { return nil, kerr.Wrap("CBTOLUQOGL", err) } return b, nil }
func printStructDefinition(ctx context.Context, env *envctx.Env, g *builder.Builder, typ *system.Type) error { if typ.Description != "" { g.Println("// ", typ.Description) } g.Println("type ", system.GoName(typ.Id.Name), " struct {") { if !typ.Basic { g.Println("*", g.SprintRef("kego.io/system", system.GoName("object"))) } embedsSortable := system.SortableReferences(typ.Embed) sort.Sort(embedsSortable) embeds := []*system.Reference(embedsSortable) for _, embed := range embeds { g.Println("*", builder.Reference(embed.Package, system.GoName(embed.Name), env.Path, g.Imports.Add)) } for _, nf := range typ.SortedFields() { b := nf.Rule.(system.ObjectInterface).GetObject(nil) if b.Description != "" { g.Println("// ", b.Description) } descriptor, err := builder.FieldTypeDefinition(ctx, nf.Name, nf.Rule, env.Path, g.Imports.Add) if err != nil { return kerr.Wrap("GDSKJDEKQD", err) } g.Println(system.GoName(nf.Name), " ", descriptor) } } g.Println("}") return nil }
func printInterfaceDefinition(ctx context.Context, env *envctx.Env, g *builder.Builder, typ *system.Type) { g.Println("type ", system.GoInterfaceName(typ.Id.Name), " interface {") { g.Println("Get", system.GoName(typ.Id.Name), "(ctx ", builder.Reference("context", "Context", env.Path, g.Imports.Add), ") ", typ.PassedAsPointerString(ctx), system.GoName(typ.Id.Name)) } g.Println("}") }
func printInterfaceImplementation(ctx context.Context, env *envctx.Env, g *builder.Builder, typ *system.Type) { g.Println("func (o ", typ.PassedAsPointerString(ctx), system.GoName(typ.Id.Name), ") Get", system.GoName(typ.Id.Name), "(ctx ", builder.Reference("context", "Context", env.Path, g.Imports.Add), ") ", typ.PassedAsPointerString(ctx), system.GoName(typ.Id.Name), " {") { g.Println("return o") } g.Println("}") }
func printInitFunction(ctx context.Context, env *envctx.Env, g *builder.Builder, types *sysctx.SysTypes) { g.Println("func init() {") { g.Print("pkg := ") g.PrintFunctionCall( "kego.io/context/jsonctx", "InitPackage", strconv.Quote(env.Path), ) g.Println("") g.PrintMethodCall("pkg", "SetHash", env.Hash) g.Println("") for _, name := range types.Keys() { t, ok := types.Get(name) if !ok { // ke: {"block": {"notest": true}} continue } typ := t.Type.(*system.Type) isRule := typ.Id.IsRule() if isRule { continue } interfaceFunc := "nil" isNativeCollection := typ.IsNativeCollection() && typ.Alias == nil if !isNativeCollection { var ifaceName string if typ.Interface { ifaceName = system.GoName(typ.Id.Name) } else { ifaceName = system.GoInterfaceName(typ.Id.Name) } reflectTypeof := g.SprintFunctionCall( "reflect", "TypeOf", fmt.Sprintf("(*%s)(nil)", ifaceName), ) + ".Elem()" reflectType := builder.Reference("reflect", "Type", env.Path, g.Imports.Add) interfaceFunc = "func() " + reflectType + " { return " + reflectTypeof + " }" } newFunc := "nil" derefFunc := "nil" if typ.Interface { newFunc = "func() interface{} { return (*" + system.GoName(typ.Id.Name) + ")(nil) }" } else if !typ.IsNativeCollection() || typ.Alias != nil { newFunc = "func() interface{} { return new(" + system.GoName(typ.Id.Name) + ")}" if !typ.PassedAsPointer(ctx) { derefFunc = "func(in interface{}) interface{} {return *in.(*" + system.GoName(typ.Id.Name) + ")}" } } g.Println("pkg.Init(") { g.Println(strconv.Quote(typ.Id.Name), ",") g.Println(newFunc, ",") g.Println(derefFunc, ",") g.Println("func() interface{} { return new("+system.GoName(typ.Id.ChangeToRule().Name)+")}", ",") g.Println(interfaceFunc, ",") } g.Println(")") g.Println("") } } g.Println("}") }
func printUnpackCode(ctx context.Context, env *envctx.Env, g *builder.Builder, in string, out string, depth int, f system.RuleInterface) error { field := system.WrapRule(ctx, f) fieldType := field.Parent fieldTypeName := builder.Reference(fieldType.Id.Package, system.GoName(fieldType.Id.Name), env.Path, g.Imports.Add) kind, alias := field.Kind(ctx) switch { case kind == system.KindStruct || alias: ptr := fieldType.PassedAsPointerInverseString(ctx) g.Println(out, " := ", ptr, "new(", fieldTypeName, ")") g.Println("if err := ", out, ".Unpack(ctx, ", in, ", false); err != nil {") { g.Println("return err") } g.Println("}") //if store { // g.Println("v.", fieldName, " = ob") //} case kind == system.KindValue: var funcName string switch fieldType.NativeJsonType(ctx) { case system.J_STRING: funcName = "UnpackString" case system.J_NUMBER: funcName = "UnpackNumber" case system.J_BOOL: funcName = "UnpackBool" default: return kerr.New("LSGUACQGHB", "Kind == KindValue but native json type==%s", fieldType.NativeJsonType(ctx)) } funcRef := g.SprintRef("kego.io/system", funcName) g.Println(out, ", err := ", funcRef, "(ctx, ", in, ")") g.Println("if err != nil {") { g.Println("return err") } g.Println("}") //if store { // g.Println("v.", fieldName, " = ob") //} case kind == system.KindInterface: var interfaceName string if fieldType.Interface { interfaceName = system.GoName(fieldType.Id.Name) } else { interfaceName = system.GoInterfaceName(fieldType.Id.Name) } unpackFuncName := builder.Reference(fieldType.Id.Package, "Unpack"+interfaceName, env.Path, g.Imports.Add) g.Println(out, ", err := ", unpackFuncName, "(ctx, ", in, ")") g.Println("if err != nil {") { g.Println("return err") } g.Println("}") //if store { // g.Println("v.", fieldName, " = ob") //} case kind == system.KindArray: fmtPkg := g.Imports.Add("fmt") g.Println("if ", in, ".Type() != ", g.SprintRef("kego.io/system", "J_ARRAY"), " {") { g.Println("return ", fmtPkg, ".Errorf(\"Unsupported json type %s found while unpacking into an array.\", ", in, ".Type())") } g.Println("}") fieldType, err := builder.TypeDefinition(ctx, f, env.Path, g.Imports.Add) if err != nil { return kerr.Wrap("UDPMSSFLTW", err) } g.Println(out, " := ", fieldType, "{}") iVar := fmt.Sprintf("i%d", depth) g.Println("for ", iVar, " := range ", in, ".Array() {") { childRule, err := field.ItemsRule() if err != nil { return kerr.Wrap("PJQBRUEHLD", err) } childDepth := depth + 1 childIn := in + ".Array()[" + iVar + "]" childOut := fmt.Sprintf("ob%d", childDepth) if err := printUnpackCode(ctx, env, g, childIn, childOut, childDepth, childRule.Interface); err != nil { return kerr.Wrap("XCHEJPDJDS", err) } g.Println(out, " = append(", out, ", ", childOut, ")") } g.Println("}") case kind == system.KindMap: fmtPkg := g.Imports.Add("fmt") g.Println("if ", in, ".Type() != ", g.SprintRef("kego.io/system", "J_MAP"), " {") { g.Println("return ", fmtPkg, ".Errorf(\"Unsupported json type %s found while unpacking into a map.\", ", in, ".Type())") } g.Println("}") fieldType, err := builder.TypeDefinition(ctx, f, env.Path, g.Imports.Add) if err != nil { return kerr.Wrap("IHNYODUIKG", err) } g.Println(out, " := ", fieldType, "{}") kVar := fmt.Sprintf("k%d", depth) g.Println("for ", kVar, " := range ", in, ".Map() {") { items, err := field.ItemsRule() if err != nil { return kerr.Wrap("FPOBYGVOPP", err) } childDepth := depth + 1 childIn := in + ".Map()[" + kVar + "]" childOut := fmt.Sprintf("ob%d", childDepth) if err := printUnpackCode(ctx, env, g, childIn, childOut, childDepth, items.Interface); err != nil { return kerr.Wrap("ONUJJGIKJE", err) } g.Println(out, "[", kVar, "] = ", childOut) } g.Println("}") } return nil }
func printUnpacker(ctx context.Context, env *envctx.Env, g *builder.Builder, typ *system.Type) error { name := system.GoName(typ.Id.Name) fmtPkg := g.Imports.Add("fmt") g.Println("func (v *", name, ") Unpack(ctx ", g.SprintRef("context", "Context"), ", in ", g.SprintRef("kego.io/system", "Packed"), ", iface bool) error {") { g.Println("if in == nil || in.Type() == ", g.SprintRef("kego.io/system", "J_NULL"), " {") { g.Println("return nil") } g.Println("}") kind, _ := typ.Kind(ctx) switch kind { case system.KindStruct: structType := typ if typ.Alias != nil { structType = system.WrapRule(ctx, typ.Alias).Parent } for _, embedRef := range structType.AllEmbeds() { embedType, ok := system.GetTypeFromCache(ctx, embedRef.Package, embedRef.Name) if !ok { return kerr.New("IOEEVJCDPU", "Type %s not found", embedRef.String()) } embedName := system.GoName(embedRef.Name) embedTypeName := builder.Reference(embedType.Id.Package, system.GoName(embedType.Id.Name), env.Path, g.Imports.Add) g.Println("if v.", embedName, " == nil {") { g.Println("v.", embedName, " = new(", embedTypeName, ")") } g.Println("}") g.Println("if err := v.", embedName, ".Unpack(ctx, in, false); err != nil {") { g.Println("return err") } g.Println("}") if embedRef.Package == "kego.io/system" && embedRef.Name == "object" { g.Println("if err := v.Object.InitializeType(", strconv.Quote(typ.Id.Package), ", ", strconv.Quote(typ.Id.Name), "); err != nil {") { g.Println("return err") } g.Println("}") } } for _, f := range structType.SortedFields() { g.Println("if field, ok := in.Map()[", strconv.Quote(f.Name), "]; ok && field.Type() != ", g.SprintRef("kego.io/system", "J_NULL"), " {") { in := "field" out := "ob0" depth := 0 if err := printUnpackCode(ctx, env, g, in, out, depth, f.Rule); err != nil { return kerr.Wrap("QLARKEBDBJ", err) } g.Println("v.", system.GoName(f.Name), " = ", out) } if dr, ok := f.Rule.(system.DefaultRule); ok && dr.GetDefault() != nil { g.Println("} else {") { b, err := json.Marshal(dr.GetDefault()) if err != nil { return kerr.Wrap("DLOUEHXVJF", err) } in := g.SprintFunctionCall("kego.io/system", "Pack", string(b)) out := "ob0" depth := 0 if err := printUnpackCode(ctx, env, g, in, out, depth, f.Rule); err != nil { return kerr.Wrap("UOWRFWSTNT", err) } g.Println("v.", system.GoName(f.Name), " = ", out) } g.Println("}") } else { g.Println("}") } } case system.KindValue: g.Println("if in.Type() == ", g.SprintRef("kego.io/system", "J_MAP"), " {") { g.Println("in = in.Map()[\"value\"]") } g.Println("}") switch typ.NativeJsonType(ctx) { case system.J_BOOL: g.Println("if in.Type() != ", g.SprintRef("kego.io/system", "J_BOOL"), " {") { g.Println("return ", fmtPkg, `.Errorf("Invalid type %s while unpacking a bool.", in.Type())`) } g.Println("}") g.Println("*v = ", name, "(in.Bool())") case system.J_STRING: g.Println("if in.Type() != ", g.SprintRef("kego.io/system", "J_STRING"), " {") { g.Println("return ", fmtPkg, `.Errorf("Invalid type %s while unpacking a string.", in.Type())`) } g.Println("}") g.Println("*v = ", name, "(in.String())") case system.J_NUMBER: g.Println("if in.Type() != ", g.SprintRef("kego.io/system", "J_NUMBER"), " {") { g.Println("return ", fmtPkg, `.Errorf("Invalid type %s while unpacking a number.", in.Type())`) } g.Println("}") g.Println("*v = ", name, "(in.Number())") default: panic(fmt.Sprintf("invalid type kind: %s, json native: %s", kind, typ.NativeJsonType(ctx))) } case system.KindArray: g.Println("if in.Type() == ", g.SprintRef("kego.io/system", "J_MAP"), " {") { g.Println("in = in.Map()[\"value\"]") } g.Println("}") g.Println("if in.Type() != ", g.SprintRef("kego.io/system", "J_ARRAY"), " {") { g.Println("return ", fmtPkg, `.Errorf("Invalid type %s while unpacking an array.", in.Type())`) } g.Println("}") in := "in" out := "ob0" depth := 0 if err := printUnpackCode(ctx, env, g, in, out, depth, typ.Alias); err != nil { return kerr.Wrap("VELYRXXGMC", err) } g.Println("*v = ", out) case system.KindMap: g.Println("if iface {") { g.Println("if in.Type() != ", g.SprintRef("kego.io/system", "J_MAP"), " {") { g.Println("return ", fmtPkg, `.Errorf("Invalid type %s while unpacking a map.", in.Type())`) } g.Println("}") g.Println("in = in.Map()[\"value\"]") } g.Println("}") g.Println("if in.Type() != ", g.SprintRef("kego.io/system", "J_MAP"), " {") { g.Println("return ", fmtPkg, `.Errorf("Invalid type %s while unpacking an array.", in.Type())`) } g.Println("}") in := "in" out := "ob0" depth := 0 if err := printUnpackCode(ctx, env, g, in, out, depth, typ.Alias); err != nil { return kerr.Wrap("TNEIUAFUNY", err) } g.Println("*v = ", out) } } g.Println("return nil") g.Println("}") return nil }