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 }
func printRepacker(ctx context.Context, env *envctx.Env, g *builder.Builder, typ *system.Type) error { name := system.GoName(typ.Id.Name) context_Context := g.SprintRef("context", "Context") system_JsonType := g.SprintRef("kego.io/system", "JsonType") ptr := typ.PassedAsPointerString(ctx) v := "v" if typ.PassedAsPointer(ctx) { v = "(*v)" } g.Println("func (v ", ptr, name, ") Repack(ctx ", context_Context, ") (data interface{}, typePackage string, typeName string, jsonType ", system_JsonType, ", err error) {") { g.Println("if v == nil {") { system_J_NULL := g.SprintRef("kego.io/system", "J_NULL") g.Println("return nil, ", strconv.Quote(typ.Id.Package), ", ", strconv.Quote(typ.Id.Name), ", ", system_J_NULL, ", nil") } g.Println("}") jtype := typ.NativeJsonType(ctx) var jsonType string switch jtype { case system.J_NUMBER: jsonType = g.SprintRef("kego.io/system", "J_NUMBER") case system.J_STRING: jsonType = g.SprintRef("kego.io/system", "J_STRING") case system.J_BOOL: jsonType = g.SprintRef("kego.io/system", "J_BOOL") case system.J_MAP: jsonType = g.SprintRef("kego.io/system", "J_MAP") case system.J_OBJECT: jsonType = g.SprintRef("kego.io/system", "J_OBJECT") case system.J_ARRAY: jsonType = g.SprintRef("kego.io/system", "J_ARRAY") case system.J_NULL: jsonType = g.SprintRef("kego.io/system", "J_NULL") } kind, _ := typ.Kind(ctx) switch kind { case system.KindStruct: g.Println("m := map[string]interface{}{}") structType := typ if typ.Alias != nil { structType = system.WrapRule(ctx, typ.Alias).Parent } for _, embedRef := range structType.AllEmbeds() { embedName := system.GoName(embedRef.Name) g.Println("if v.", embedName, " != nil {") { g.Println("ob, _, _, _, err := v.", embedName, ".Repack(ctx)") g.Println("if err != nil {") { g.Println(`return nil, "", "", "", err`) } g.Println("}") g.Println("for key, val := range ob.(map[string]interface{}) {") { g.Println("m[key] = val") } g.Println("}") } g.Println("}") } for _, f := range structType.SortedFields() { fieldRule := system.WrapRule(ctx, f.Rule) fieldName := system.GoName(f.Name) fieldType := fieldRule.Parent kind, alias := fieldRule.Kind(ctx) switch { case kind == system.KindStruct || alias: g.Println("if v.", fieldName, " != nil {") { if err := printRepackCode(ctx, env, g, "v."+fieldName, "ob0", 0, f.Rule, true); err != nil { return kerr.Wrap("WSARHJIFHS", err) } g.Println("m[", strconv.Quote(f.Name), "] = ", "ob0") } g.Println("}") case kind == system.KindValue: switch fieldType.NativeJsonType(ctx) { case system.J_STRING: g.Println("if v.", fieldName, " != \"\" {") case system.J_NUMBER: g.Println("if v.", fieldName, " != 0.0 {") case system.J_BOOL: g.Println("if v.", fieldName, " != false {") } { if err := printRepackCode(ctx, env, g, "v."+fieldName, "ob0", 0, f.Rule, true); err != nil { return kerr.Wrap("YYDYVIMXPM", err) } g.Println("m[", strconv.Quote(f.Name), "] = ", "ob0") } g.Println("}") case kind == system.KindArray || kind == system.KindMap || kind == system.KindInterface: g.Println("if v.", fieldName, " != nil {") { if err := printRepackCode(ctx, env, g, "v."+fieldName, "ob0", 0, f.Rule, true); err != nil { return kerr.Wrap("YSFPHQTBNA", err) } g.Println("m[", strconv.Quote(f.Name), "] = ", "ob0") } g.Println("}") } } g.Println("return m, ", strconv.Quote(typ.Id.Package), ", ", strconv.Quote(typ.Id.Name), ", ", jsonType, ", nil") case system.KindValue: outer := typ inner := typ if typ.Alias != nil { inner = system.WrapRule(ctx, typ.Alias).Parent } switch inner.NativeJsonType(ctx) { case system.J_STRING: g.Println("if v != nil {") { g.Println("return string(", ptr, "v), ", strconv.Quote(outer.Id.Package), ", ", strconv.Quote(outer.Id.Name), ", ", jsonType, ", nil") } g.Println("}") g.Println("return nil, ", strconv.Quote(outer.Id.Package), ", ", strconv.Quote(outer.Id.Name), ", ", jsonType, ", nil") case system.J_NUMBER: g.Println("if v != nil {") { g.Println("return float64(", ptr, "v), ", strconv.Quote(outer.Id.Package), ", ", strconv.Quote(outer.Id.Name), ", ", jsonType, ", nil") } g.Println("}") g.Println("return nil, ", strconv.Quote(outer.Id.Package), ", ", strconv.Quote(outer.Id.Name), ", ", jsonType, ", nil") case system.J_BOOL: g.Println("if v != nil {") { g.Println("return bool(", ptr, "v), ", strconv.Quote(outer.Id.Package), ", ", strconv.Quote(outer.Id.Name), ", ", jsonType, ", nil") } g.Println("}") g.Println("return nil, ", strconv.Quote(outer.Id.Package), ", ", strconv.Quote(outer.Id.Name), ", ", jsonType, ", nil") } case system.KindArray: if err := printRepackCode(ctx, env, g, v, "ob0", 0, typ.Alias, false); err != nil { return kerr.Wrap("SYKLQKLCEO", err) } g.Println("return ob0, ", strconv.Quote(typ.Id.Package), ", ", strconv.Quote(typ.Id.Name), ", ", jsonType, ", nil") case system.KindMap: if err := printRepackCode(ctx, env, g, v, "ob0", 0, typ.Alias, false); err != nil { return kerr.Wrap("HBSGXLGKCD", err) } g.Println("return ob0, ", strconv.Quote(typ.Id.Package), ", ", strconv.Quote(typ.Id.Name), ", ", jsonType, ", nil") } } g.Println("}") return nil }