package main import ( "go/ast" "go/token" "slices" "strconv" "github.com/admin-else/strom/mc/proto_generator/protodef" util2 "github.com/admin-else/strom/mc/util" "github.com/go-viper/mapstructure/v2" ) func DefaultEncoder(_ *Generator, varToSet ast.Expr, _ any, name string) (s []ast.Stmt, err error) { tmpName := name + "EncTmp" s = Stmts( Define121(Ident(tmpName), varToSet), Assign121( Ident("err"), Call(SelectorExprAndStr(Ident(tmpName), "Encode"), Ident("w")), ), IfErrNil(), ) return } func ContainerEncoder(g *Generator, varToSet ast.Expr, dataRaw any, name string) (s []ast.Stmt, err error) { var data protodef.Container err = mapstructure.Decode(dataRaw, &data) if err != nil { return } g.ContainerStack = append(g.ContainerStack, ContainerStackEntry{ Data: data, VarToSet: varToSet, }) defer func() { g.ContainerStack = g.ContainerStack[:len(g.ContainerStack)-1] }() for _, field := range data { var statements []ast.Stmt cName := util2.CamelCase(field.Name) if field.Anon { cName = "Anon" } statements, err = g.VisitEncoder(SelectorExprAndStr(varToSet, cName), field.Type, name+util2.CamelCase(cName)) if err != nil { return } s = append(s, statements...) } return } func SimpleTypeEncoder(_ *Generator, data ast.Expr, _ any, _ string) (s []ast.Stmt, err error) { s = Stmts( Assign121( Ident("err"), Call(Selector("binary", "Write"), Ident("w"), Selector("binary", "BigEndian"), data), ), IfErrNil(), ) return } func ArrayEncoder(g *Generator, varToSet ast.Expr, dataRaw any, name string) (s []ast.Stmt, err error) { var data protodef.Array err = mapstructure.Decode(dataRaw, &data) if err != nil { return } if data.CountType == nil { data.CountType = "varint" } ct, err := g.VisitType(data.CountType) if err != nil { return } iName := "i" + name //s, err = g.VisitEncoder(varToSet, data.Type, name) var s1 []ast.Stmt if data.Count == nil { s1, err = g.VisitEncoder(Call(ct, Call(Ident("len"), varToSet)), data.CountType, name) if err != nil { return } } s2, err := g.VisitEncoder(Index(varToSet, Ident(iName)), data.Type, name+"Inner") if err != nil { return } s2 = Stmts(ForRange(Ident(iName), Call(Ident("len"), varToSet), NewBlock(s2))) s = append(s1, s2...) return } func ToDoEncoder(_ *Generator, _ ast.Expr, _ any, _ string) (s []ast.Stmt, err error) { err = ToDoError return } func OptionEncoder(g *Generator, data ast.Expr, dataRaw any, name string) (s []ast.Stmt, err error) { cond := NotEquals(data, Nil()) s1, err := g.VisitEncoder(cond, "bool", name) if err != nil { return } s2, err := g.VisitEncoder(DeRef(data), dataRaw, name) if err != nil { return } s = append(s1, If(cond, NewBlock(s2))) return } func BufferEncoder(g *Generator, varToSet ast.Expr, dataRaw any, name string) (s []ast.Stmt, err error) { var data protodef.Buffer err = mapstructure.Decode(dataRaw, &data) if err != nil { return } if data.CountType != nil { var countType ast.Expr countType, err = g.VisitType(data.CountType) if err != nil { return } var s2 []ast.Stmt s2, err = g.VisitEncoder(Call(countType, Call(Ident("len"), varToSet)), data.CountType, name) if err != nil { return } s = append(s, s2...) } else { s = append(s, Define121(Ident("arr"), varToSet)) varToSet = MultiIndex(Ident("arr"), nil, nil, nil) } s = append(s, Assign(Exprs(Ident("_"), Ident("err")), Exprs(Call(Selector("w", "Write"), varToSet)))) s = append(s, IfErrNil()) return } func BitFieldEncoder(g *Generator, varToSet ast.Expr, dataRaw any, name string) (s []ast.Stmt, err error) { var data protodef.BitField err = mapstructure.Decode(dataRaw, &data) if err != nil { return } totalSize := 0 for _, field := range data { totalSize += field.Size } packedVarName := name + "Packed" packedExpr := Ident(packedVarName) packedTypeStr := "uint" + strconv.Itoa(totalSize) s = append(s, VarStmt(packedVarName, Ident(packedTypeStr))) slices.Reverse(data) shiftBy := 0 for _, field := range data { boolFix := packedTypeStr if field.Size == 1 { boolFix = "proto_base.Bool2" + boolFix } s = append(s, OrAssign( // lisp ahh packedExpr, LeftShift( Grouping( BinAnd( Call( Ident(boolFix), SelectorExprAndStr( varToSet, util2.CamelCase(field.Name), ), ), NumLitHex((1<