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

     1  // Copyright (c) HashiCorp, Inc.
     2  // SPDX-License-Identifier: MPL-2.0
     3  
     4  // Package customdecode contains a HCL extension that allows, in certain
     5  // contexts, expression evaluation to be overridden by custom static analysis.
     6  //
     7  // This mechanism is only supported in certain specific contexts where
     8  // expressions are decoded with a specific target type in mind. For more
     9  // information, see the documentation on CustomExpressionDecoder.
    10  package customdecode
    11  
    12  import (
    13  	"github.com/hashicorp/hcl/v2"
    14  	"github.com/zclconf/go-cty/cty"
    15  )
    16  
    17  type customDecoderImpl int
    18  
    19  // CustomExpressionDecoder is a value intended to be used as a cty capsule
    20  // type ExtensionData key for capsule types whose values are to be obtained
    21  // by static analysis of an expression rather than normal evaluation of that
    22  // expression.
    23  //
    24  // When a cooperating capsule type is asked for ExtensionData with this key,
    25  // it must return a non-nil CustomExpressionDecoderFunc value.
    26  //
    27  // This mechanism is not universally supported; instead, it's handled in a few
    28  // specific places where expressions are evaluated with the intent of producing
    29  // a cty.Value of a type given by the calling application.
    30  //
    31  // Specifically, this currently works for type constraints given in
    32  // hcldec.AttrSpec and hcldec.BlockAttrsSpec, and it works for arguments to
    33  // function calls in the HCL native syntax. HCL extensions implemented outside
    34  // of the main HCL module may also implement this; consult their own
    35  // documentation for details.
    36  const CustomExpressionDecoder = customDecoderImpl(1)
    37  
    38  // CustomExpressionDecoderFunc is the type of value that must be returned by
    39  // a capsule type handling the key CustomExpressionDecoder in its ExtensionData
    40  // implementation.
    41  //
    42  // If no error diagnostics are returned, the result value MUST be of the
    43  // capsule type that the decoder function was derived from. If the returned
    44  // error diagnostics prevent producing a value at all, return cty.NilVal.
    45  type CustomExpressionDecoderFunc func(expr hcl.Expression, ctx *hcl.EvalContext) (cty.Value, hcl.Diagnostics)
    46  
    47  // CustomExpressionDecoderForType takes any cty type and returns its
    48  // custom expression decoder implementation if it has one. If it is not a
    49  // capsule type or it does not implement a custom expression decoder, this
    50  // function returns nil.
    51  func CustomExpressionDecoderForType(ty cty.Type) CustomExpressionDecoderFunc {
    52  	if !ty.IsCapsuleType() {
    53  		return nil
    54  	}
    55  	if fn, ok := ty.CapsuleExtensionData(CustomExpressionDecoder).(CustomExpressionDecoderFunc); ok {
    56  		return fn
    57  	}
    58  	return nil
    59  }