66 lines
1.6 KiB
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
|
|
}
|