hcl/zcl/structure.go

96 lines
2.9 KiB
Go
Raw Normal View History

2017-05-14 00:44:11 +00:00
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
}