Files
masonry/interpreter/proto_interpreter.go

66 lines
1.6 KiB
Go

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
}