96 lines
2.9 KiB
Go
96 lines
2.9 KiB
Go
|
package zcl
|
||
|
|
||
|
import (
|
||
|
"github.com/apparentlymart/go-cty/cty"
|
||
|
)
|
||
|
|
||
|
// File is the top-level node that results from parsing a ZCL file.
|
||
|
type File struct {
|
||
|
Body Body
|
||
|
}
|
||
|
|
||
|
// Element represents a nested block within a Body.
|
||
|
type Element struct {
|
||
|
Type string
|
||
|
Labels []string
|
||
|
Body Body
|
||
|
|
||
|
DefRange Range // Range that can be considered the "definition" for seeking in an editor
|
||
|
TypeRange Range // Range for the element type declaration specifically.
|
||
|
LabelRanges []Range // Ranges for the label values specifically.
|
||
|
}
|
||
|
|
||
|
// Elements is a sequence of Element.
|
||
|
type Elements []*Element
|
||
|
|
||
|
// Body is a container for attributes and elements. It serves as the primary
|
||
|
// unit of heirarchical structure within configuration.
|
||
|
//
|
||
|
// The content of a body cannot be meaningfully intepreted without a schema,
|
||
|
// so Body represents the raw body content and has methods that allow the
|
||
|
// content to be extracted in terms of a given schema.
|
||
|
type Body interface {
|
||
|
// Content verifies that the entire body content conforms to the given
|
||
|
// schema and then returns it, and/or returns diagnostics. The returned
|
||
|
// body content is valid if non-nil, regardless of whether Diagnostics
|
||
|
// are provided, but diagnostics should still be eventually shown to
|
||
|
// the user.
|
||
|
Content(schema *BodySchema) (*BodyContent, Diagnostics)
|
||
|
|
||
|
// PartialContent is like Content except that it permits the configuration
|
||
|
// to contain additional elements or attributes not specified in the
|
||
|
// schema. If any are present, the returned Body is non-nil and contains
|
||
|
// the remaining items from the body that were not selected by the schema.
|
||
|
PartialContent(schema *BodySchema) (*BodyContent, Body, Diagnostics)
|
||
|
}
|
||
|
|
||
|
// BodyContent is the result of applying a BodySchema to a Body.
|
||
|
type BodyContent struct {
|
||
|
Attributes map[string]Attribute
|
||
|
Elements Elements
|
||
|
}
|
||
|
|
||
|
// Attribute represents an attribute from within a body.
|
||
|
type Attribute struct {
|
||
|
Name string
|
||
|
Expr Expression
|
||
|
|
||
|
Range Range
|
||
|
NameRange Range
|
||
|
ExprRange Range
|
||
|
}
|
||
|
|
||
|
// Expression is a literal value or an expression provided in the
|
||
|
// configuration, which can be evaluated within a scope to produce a value.
|
||
|
type Expression interface {
|
||
|
LiteralValue() cty.Value
|
||
|
// TODO: evaluation of non-literal expressions
|
||
|
}
|
||
|
|
||
|
// OfType filters the receiving element sequence by element type name,
|
||
|
// returning a new element sequence including only the elements of the
|
||
|
// requested type.
|
||
|
func (els Elements) OfType(typeName string) Elements {
|
||
|
ret := make(Elements, 0)
|
||
|
for _, el := range els {
|
||
|
if el.Type == typeName {
|
||
|
ret = append(ret, el)
|
||
|
}
|
||
|
}
|
||
|
return ret
|
||
|
}
|
||
|
|
||
|
// ByType transforms the receiving elements sequence into a map from type
|
||
|
// name to element sequences of only that type.
|
||
|
func (els Elements) ByType() map[string]Elements {
|
||
|
ret := make(map[string]Elements)
|
||
|
for _, el := range els {
|
||
|
ty := el.Type
|
||
|
if ret[ty] == nil {
|
||
|
ret[ty] = make(Elements, 0, 1)
|
||
|
}
|
||
|
ret[ty] = append(ret[ty], el)
|
||
|
}
|
||
|
return ret
|
||
|
}
|