Files
strom/mc/proto_generator/native_compare_to.go
T
OpenCode eb83786f9a fix: resolve parameterized $compareTo types and fix array count type
- VisitNameAndData: return any instead of named struct when mergeCompareTo
  resolves $compareTo, fixing field type mismatches for switch/container types
- ContainerCompareTo: traverse anon/bitfield fields for compareTo resolution,
  fixes entityMetadata 'field not found' errors
- Array.Count: change from string to any to handle numeric count values
- ArrayEncoder: fix nil check to correctly write length prefix for arrays
- ArrayDecoder: use fmt.Sprint for safe Count conversion
2026-08-05 18:33:39 +02:00

149 lines
3.9 KiB
Go

package main
import (
"errors"
"fmt"
"go/ast"
"strings"
"github.com/admin-else/strom/mc/proto_generator/protodef"
util2 "github.com/admin-else/strom/mc/util"
"github.com/go-viper/mapstructure/v2"
)
func (g *Generator) ParseCompareTo(compareTo string) (e ast.Expr, cet CaseExprType, err error) {
if strings.HasPrefix(compareTo, "$") {
err = fmt.Errorf("parameterized type placeholder: %s", compareTo)
return
}
parts := strings.Split(compareTo, "/")
downPrefixCount := 0
for _, part := range parts {
if part == ".." {
downPrefixCount++
}
}
parts = parts[downPrefixCount:]
startingPoint := g.ContainerStack[len(g.ContainerStack)-downPrefixCount-1]
e, cet, err = g.VisitCompareTo(parts, startingPoint.VarToSet, util2.CombineNamAndData("container", startingPoint.Data))
// return ParseCompareToLegacy(compareTo, varToSet)
return
}
func (g *Generator) VisitCompareTo(parts []string, inExpr ast.Expr, data any) (e ast.Expr, cet CaseExprType, err error) {
tName, tData, err := ParseType(data)
if err != nil {
return
}
d, found := g.CompareToNatives[tName]
if found {
return d(g, parts, inExpr, tData)
}
err = fmt.Errorf("native compare to not implemented for %v", tName)
return
}
func ContainerCompareTo(g *Generator, parts []string, inExpr ast.Expr, dataRaw any) (e ast.Expr, cet CaseExprType, err error) {
var data protodef.Container
err = mapstructure.Decode(dataRaw, &data)
if err != nil {
return
}
name, parts, ok := util2.PopFront(parts)
if !ok {
err = errors.New("expected name part")
return
}
for _, field := range data {
if field.Name == name {
return g.VisitCompareTo(parts, SelectorExprAndStr(inExpr, util2.CamelCase(field.Name)), field.Type)
}
if field.Anon {
anonParts := append([]string{name}, parts...)
e, cet, err2 := g.VisitCompareTo(anonParts, SelectorExprAndStr(inExpr, "Anon"), field.Type)
if err2 == nil {
return e, cet, nil
}
}
}
err = errors.New("field not found")
return
}
func ReturnInputCompareTo(_ *Generator, _ []string, inExpr ast.Expr, _ any) (e ast.Expr, cet CaseExprType, err error) {
return inExpr, CaseExprTypeUnset, nil
}
func BitfieldCompareTo(_ *Generator, parts []string, inExpr ast.Expr, dataRaw any) (e ast.Expr, cet CaseExprType, err error) {
var data protodef.BitField
err = mapstructure.Decode(dataRaw, &data)
if err != nil {
return
}
fieldName, parts, found := util2.PopFront(parts)
if !found {
err = errors.New("expected name part")
return
}
var field protodef.BitFieldEntry
for _, f := range data {
if f.Name == fieldName {
field = f
break
}
}
if field.Size == 1 {
cet = CaseExprTypeOnlyBool
} else {
cet = CaseExprTypeOnlyNumber
}
e = SelectorExprAndStr(inExpr, util2.CamelCase(fieldName))
return
}
func BitflagsCompareTo(_ *Generator, parts []string, inExpr ast.Expr, dataRaw any) (e ast.Expr, cet CaseExprType, err error) {
var data protodef.BitFlags
err = mapstructure.Decode(dataRaw, &data)
if err != nil {
return
}
name, parts, ok := util2.PopFront(parts)
if !ok {
err = errors.New("expected name part")
return
}
for i, flag := range data.Flags {
if flag != name {
continue
}
e = NotEquals(BinAnd(inExpr, NumLitHex(1<<i)), NumLit(0))
return
}
err = errors.New("flag not found")
return
}
func (g *Generator) RegisterCompareToNatives() {
g.CompareToNatives = map[string]CompareToGeneratorFunc{
"container": ContainerCompareTo,
"bool": ReturnInputCompareTo,
"mapper": ReturnInputCompareTo,
"varint": ReturnInputCompareTo,
"bitfield": BitfieldCompareTo,
"u8": ReturnInputCompareTo,
"i8": ReturnInputCompareTo,
"i16": ReturnInputCompareTo,
"i32": ReturnInputCompareTo,
"i64": ReturnInputCompareTo,
"u16": ReturnInputCompareTo,
"u32": ReturnInputCompareTo,
"string": ReturnInputCompareTo,
"bitflags": BitflagsCompareTo,
"switch": ReturnInputCompareTo,
"varlong": ReturnInputCompareTo,
}
}