github.com/hashicorp/hcl/v2@v2.20.0/ext/dynblock/public.go (about)

     1  // Copyright (c) HashiCorp, Inc.
     2  // SPDX-License-Identifier: MPL-2.0
     3  
     4  // Package dynblock provides an extension to HCL that allows dynamic
     5  // declaration of nested blocks in certain contexts via a special block type
     6  // named "dynamic".
     7  package dynblock
     8  
     9  import (
    10  	"github.com/hashicorp/hcl/v2"
    11  )
    12  
    13  // Expand "dynamic" blocks in the given body, returning a new body that
    14  // has those blocks expanded.
    15  //
    16  // The given EvalContext is used when evaluating "for_each" and "labels"
    17  // attributes within dynamic blocks, allowing those expressions access to
    18  // variables and functions beyond the iterator variable created by the
    19  // iteration.
    20  //
    21  // Expand returns no diagnostics because no blocks are actually expanded
    22  // until a call to Content or PartialContent on the returned body, which
    23  // will then expand only the blocks selected by the schema.
    24  //
    25  // "dynamic" blocks are also expanded automatically within nested blocks
    26  // in the given body, including within other dynamic blocks, thus allowing
    27  // multi-dimensional iteration. However, it is not possible to
    28  // dynamically-generate the "dynamic" blocks themselves except through nesting.
    29  //
    30  //	parent {
    31  //	  dynamic "child" {
    32  //	    for_each = child_objs
    33  //	    content {
    34  //	      dynamic "grandchild" {
    35  //	        for_each = child.value.children
    36  //	        labels   = [grandchild.key]
    37  //	        content {
    38  //	          parent_key = child.key
    39  //	          value      = grandchild.value
    40  //	        }
    41  //	      }
    42  //	    }
    43  //	  }
    44  //	}
    45  func Expand(body hcl.Body, ctx *hcl.EvalContext, opts ...ExpandOption) hcl.Body {
    46  	ret := &expandBody{
    47  		original:   body,
    48  		forEachCtx: ctx,
    49  	}
    50  	for _, opt := range opts {
    51  		opt.applyExpandOption(ret)
    52  	}
    53  	return ret
    54  }