153 lines
3.9 KiB
Go
153 lines
3.9 KiB
Go
package main
|
|
|
|
import (
|
|
"flag"
|
|
"fmt"
|
|
"log"
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
|
|
"github.com/edmand46/arpack/generator"
|
|
"github.com/edmand46/arpack/parser"
|
|
)
|
|
|
|
func main() {
|
|
in := flag.String("in", "", "input Go file with struct definitions")
|
|
outGo := flag.String("out-go", "", "output directory for generated Go code")
|
|
outCS := flag.String("out-cs", "", "output directory for generated C# code")
|
|
outTS := flag.String("out-ts", "", "output directory for generated TypeScript code")
|
|
outLua := flag.String("out-lua", "", "output directory for generated Lua code")
|
|
namespace := flag.String("cs-namespace", "Arpack.Messages", "C# namespace")
|
|
flag.Parse()
|
|
|
|
if *in == "" {
|
|
log.Fatal("arpack: -in is required")
|
|
}
|
|
|
|
if *outGo == "" && *outCS == "" && *outTS == "" && *outLua == "" {
|
|
log.Fatal("arpack: at least one of -out-go, -out-cs, -out-ts, or -out-lua is required")
|
|
}
|
|
|
|
schema, err := parser.ParseSchemaFile(*in)
|
|
if err != nil {
|
|
log.Fatalf("arpack: parse error: %v", err)
|
|
}
|
|
msgs := schema.Messages
|
|
if len(msgs) == 0 {
|
|
log.Fatalf("arpack: no structs found in %s", *in)
|
|
}
|
|
|
|
baseName := strings.TrimSuffix(filepath.Base(*in), ".go")
|
|
|
|
if *outGo != "" {
|
|
pkgName := filepath.Base(*outGo)
|
|
if pkgName == "." || pkgName == "" {
|
|
pkgName = msgs[0].PackageName
|
|
}
|
|
// Replace hyphens with underscores for valid Go package names
|
|
pkgName = strings.ReplaceAll(pkgName, "-", "_")
|
|
|
|
src, err := generator.GenerateGoSchema(schema, pkgName)
|
|
if err != nil {
|
|
log.Fatalf("arpack: Go generation error: %v", err)
|
|
}
|
|
|
|
outPath := filepath.Join(*outGo, baseName+"_gen.go")
|
|
if err := os.MkdirAll(*outGo, 0755); err != nil {
|
|
log.Fatalf("arpack: mkdir %s: %v", *outGo, err)
|
|
}
|
|
if err := os.WriteFile(outPath, src, 0644); err != nil {
|
|
log.Fatalf("arpack: write %s: %v", outPath, err)
|
|
}
|
|
|
|
fmt.Printf("arpack: wrote %s\n", outPath)
|
|
}
|
|
|
|
if *outCS != "" {
|
|
src, err := generator.GenerateCSharpSchema(schema, *namespace)
|
|
if err != nil {
|
|
log.Fatalf("arpack: C# generation error: %v", err)
|
|
}
|
|
|
|
outPath := filepath.Join(*outCS, toTitle(baseName)+".gen.cs")
|
|
if err := os.MkdirAll(*outCS, 0755); err != nil {
|
|
log.Fatalf("arpack: mkdir %s: %v", *outCS, err)
|
|
}
|
|
if err := os.WriteFile(outPath, src, 0644); err != nil {
|
|
log.Fatalf("arpack: write %s: %v", outPath, err)
|
|
}
|
|
|
|
fmt.Printf("arpack: wrote %s\n", outPath)
|
|
}
|
|
|
|
if *outTS != "" {
|
|
src, err := generator.GenerateTypeScriptSchema(schema, "Arpack.Messages")
|
|
if err != nil {
|
|
log.Fatalf("arpack: TypeScript generation error: %v", err)
|
|
}
|
|
|
|
outPath := filepath.Join(*outTS, toTitle(baseName)+".gen.ts")
|
|
if err := os.MkdirAll(*outTS, 0755); err != nil {
|
|
log.Fatalf("arpack: mkdir %s: %v", *outTS, err)
|
|
}
|
|
if err := os.WriteFile(outPath, src, 0644); err != nil {
|
|
log.Fatalf("arpack: write %s: %v", outPath, err)
|
|
}
|
|
|
|
fmt.Printf("arpack: wrote %s\n", outPath)
|
|
}
|
|
|
|
if *outLua != "" {
|
|
src, err := generator.GenerateLuaSchema(schema, baseName)
|
|
if err != nil {
|
|
log.Fatalf("arpack: Lua generation error: %v", err)
|
|
}
|
|
|
|
// Use snake_case filename for Lua require() compatibility
|
|
outPath := filepath.Join(*outLua, toSnakeCase(baseName)+"_gen.lua")
|
|
if err := os.MkdirAll(*outLua, 0755); err != nil {
|
|
log.Fatalf("arpack: mkdir %s: %v", *outLua, err)
|
|
}
|
|
if err := os.WriteFile(outPath, src, 0644); err != nil {
|
|
log.Fatalf("arpack: write %s: %v", outPath, err)
|
|
}
|
|
|
|
fmt.Printf("arpack: wrote %s\n", outPath)
|
|
}
|
|
}
|
|
|
|
func toTitle(s string) string {
|
|
return strings.ToUpper(s[:1]) + strings.ToLower(s[1:])
|
|
}
|
|
|
|
func toSnakeCase(s string) string {
|
|
if s == "" {
|
|
return ""
|
|
}
|
|
|
|
var b strings.Builder
|
|
var prevUpper bool
|
|
|
|
for i, c := range s {
|
|
isUpper := c >= 'A' && c <= 'Z'
|
|
|
|
if i > 0 && isUpper {
|
|
nextLower := false
|
|
if i+1 < len(s) {
|
|
nextChar := rune(s[i+1])
|
|
nextLower = nextChar >= 'a' && nextChar <= 'z'
|
|
}
|
|
|
|
if !prevUpper || nextLower {
|
|
b.WriteByte('_')
|
|
}
|
|
}
|
|
|
|
b.WriteRune(c)
|
|
prevUpper = isUpper
|
|
}
|
|
|
|
return strings.ToLower(b.String())
|
|
}
|