4 "github.com/hashicorp/hcl2/hcldec"
5 "github.com/zclconf/go-cty/cty"
8 var mapLabelNames = []string{"key"}
10 // DecoderSpec returns a hcldec.Spec that can be used to decode a HCL Body
11 // using the facilities in the hcldec package.
13 // The returned specification is guaranteed to return a value of the same type
14 // returned by method ImpliedType, but it may contain null or unknown values if
15 // any of the block attributes are defined as optional and/or computed
17 func (b *Block) DecoderSpec() hcldec.Spec {
18 ret := hcldec.ObjectSpec{}
23 for name, attrS := range b.Attributes {
25 case attrS.Computed && attrS.Optional:
26 // In this special case we use an unknown value as a default
27 // to get the intended behavior that the result is computed
28 // unless it has been explicitly set in config.
29 ret[name] = &hcldec.DefaultSpec{
30 Primary: &hcldec.AttrSpec{
34 Default: &hcldec.LiteralSpec{
35 Value: cty.UnknownVal(attrS.Type),
39 ret[name] = &hcldec.LiteralSpec{
40 Value: cty.UnknownVal(attrS.Type),
43 ret[name] = &hcldec.AttrSpec{
46 Required: attrS.Required,
51 for name, blockS := range b.BlockTypes {
52 if _, exists := ret[name]; exists {
53 // This indicates an invalid schema, since it's not valid to
54 // define both an attribute and a block type of the same name.
55 // However, we don't raise this here since it's checked by
60 childSpec := blockS.Block.DecoderSpec()
62 switch blockS.Nesting {
64 ret[name] = &hcldec.BlockSpec{
67 Required: blockS.MinItems == 1 && blockS.MaxItems >= 1,
70 ret[name] = &hcldec.BlockListSpec{
73 MinItems: blockS.MinItems,
74 MaxItems: blockS.MaxItems,
77 ret[name] = &hcldec.BlockSetSpec{
80 MinItems: blockS.MinItems,
81 MaxItems: blockS.MaxItems,
84 ret[name] = &hcldec.BlockMapSpec{
87 LabelNames: mapLabelNames,
90 // Invalid nesting type is just ignored. It's checked by