From 23e84c263d0b60e5ba022572c19289c0cc06efe4 Mon Sep 17 00:00:00 2001 From: Mason Payne Date: Mon, 1 Sep 2025 11:09:49 -0600 Subject: [PATCH] WIP: start the proto interpreter --- interpreter/proto_interpreter.go | 65 ++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 interpreter/proto_interpreter.go diff --git a/interpreter/proto_interpreter.go b/interpreter/proto_interpreter.go new file mode 100644 index 0000000..c2c414b --- /dev/null +++ b/interpreter/proto_interpreter.go @@ -0,0 +1,65 @@ +package interpreter + +import ( + "fmt" + "masonry/lang" + "strings" +) + +type ProtoInterpreter struct { + entities map[string]*lang.Entity + endpoints map[string]*lang.Endpoint + server *lang.Server +} + +func NewProtoInterpreter() *ProtoInterpreter { + return &ProtoInterpreter{ + entities: make(map[string]*lang.Entity), + endpoints: make(map[string]*lang.Endpoint), + } +} + +func (pi *ProtoInterpreter) Interpret(ast lang.AST) error { + + for _, def := range ast.Definitions { + if def.Server != nil { + pi.server = def.Server + } else if def.Entity != nil { + pi.entities[def.Entity.Name] = def.Entity + } else if def.Endpoint != nil { + key := fmt.Sprintf("%s_%s", def.Endpoint.Method, strings.ReplaceAll(def.Endpoint.Path, "/", "_")) + pi.endpoints[key] = def.Endpoint + } + } + + // Validate references + for _, endpoint := range pi.endpoints { + if endpoint.Entity != nil { + if _, exists := pi.entities[*endpoint.Entity]; !exists { + return fmt.Errorf("undefined entity referenced in endpoint request: %s", *endpoint.Entity) + } + } + if endpoint.Response != nil { + entity, exists := pi.entities[*endpoint.Entity] + if !exists { + return fmt.Errorf("undefined entity referenced in endpoint response: %s", *endpoint.Entity) + } + // validate the fields of the response + for _, field := range endpoint.Response.Fields { + // check for a field with the same name in the entity + found := false + for _, entityField := range entity.Fields { + if entityField.Name == field { + found = true + break + } + } + if !found { + return fmt.Errorf("undefined field referenced in endpoint response: %s", field) + } + } + } + } + + return nil +}