I am writing a HCL-based configuration language where some types of blocks can reference other blocks using expressions, as follows:
source "my_source" {
// some blocks and attributes...
to = destination.my_kafka_topic
}
destination "kafka" "my_kafka_topic" {
// some blocks and attributes...
}
destination "elasticsearch" "my_es_index" {
// some blocks and attributes...
}
(The goal is the model the flow of events in a messaging system, and then materialize the actual system in terms of infrastructure.)
During parsing, I simply perform a partial decoding of the static attributes and blocks and ensure "to" hcl.Attribute
s can be interpreted as hcl.Traversal
s, but don't evaluate them (yet).
type Source struct {
Name string // first HCL tag
/* ... */
To hcl.Traversal
}
type Destination struct {
Type string // first HCL tag
Name string // second HCL tag
/* ... */
}
Later, referenceable blocks (e.g. destination
in the example above) are associated with a certain Go type based on their Type
label, and this Go type always implements an interface called Referenceable
.
type Referenceable interface {
AsReference() *Destination
}
type Destination struct {
// fields that represent the destination in terms of address, protocol, etc.
}
At that stage, I know how to build a map of referenceables map[string]Referenceable
where the key is <block_type>.<block_name>
(e.g. "destination.my_kafka_topic"
), but I am unsure how to leverage that in an hcl.EvalContext
in order to evaluate the variables to Go Referenceable
s.
What I would like to know is: how to express a Go interface in the cty
type system used by hcl.EvalContext
? Is is even possible? If not, is it advised to inject instances of *Destination
in the hcl.EvalContext
instead?