github.com/opentofu/opentofu@v1.7.1/internal/lang/globalref/analyzer_meta_references_shortcuts.go (about)

     1  // Copyright (c) The OpenTofu Authors
     2  // SPDX-License-Identifier: MPL-2.0
     3  // Copyright (c) 2023 HashiCorp, Inc.
     4  // SPDX-License-Identifier: MPL-2.0
     5  
     6  package globalref
     7  
     8  import (
     9  	"fmt"
    10  
    11  	"github.com/opentofu/opentofu/internal/addrs"
    12  	"github.com/opentofu/opentofu/internal/lang"
    13  )
    14  
    15  // ReferencesFromOutputValue returns all of the direct references from the
    16  // value expression of the given output value. It doesn't include any indirect
    17  // references.
    18  func (a *Analyzer) ReferencesFromOutputValue(addr addrs.AbsOutputValue) []Reference {
    19  	mc := a.ModuleConfig(addr.Module)
    20  	if mc == nil {
    21  		return nil
    22  	}
    23  	oc := mc.Outputs[addr.OutputValue.Name]
    24  	if oc == nil {
    25  		return nil
    26  	}
    27  	refs, _ := lang.ReferencesInExpr(addrs.ParseRef, oc.Expr)
    28  	return absoluteRefs(addr.Module, refs)
    29  }
    30  
    31  // ReferencesFromResourceInstance returns all of the direct references from the
    32  // definition of the resource instance at the given address. It doesn't include
    33  // any indirect references.
    34  //
    35  // The result doesn't directly include references from a "count" or "for_each"
    36  // expression belonging to the associated resource, but it will include any
    37  // references to count.index, each.key, or each.value that appear in the
    38  // expressions which you can then, if you wish, resolve indirectly using
    39  // Analyzer.MetaReferences. Alternatively, you can use
    40  // Analyzer.ReferencesFromResourceRepetition to get that same result directly.
    41  func (a *Analyzer) ReferencesFromResourceInstance(addr addrs.AbsResourceInstance) []Reference {
    42  	// Using MetaReferences for this is kinda overkill, since
    43  	// lang.ReferencesInBlock would be sufficient really, but
    44  	// this ensures we keep consistent in how we build the
    45  	// resulting absolute references and otherwise aside from
    46  	// some extra overhead this call boils down to a call to
    47  	// lang.ReferencesInBlock anyway.
    48  	fakeRef := Reference{
    49  		ContainerAddr: addr.Module,
    50  		LocalRef: &addrs.Reference{
    51  			Subject: addr.Resource,
    52  		},
    53  	}
    54  	return a.MetaReferences(fakeRef)
    55  }
    56  
    57  // ReferencesFromResourceRepetition returns the references from the given
    58  // resource's for_each or count expression, or an empty set if the resource
    59  // doesn't use repetition.
    60  //
    61  // This is a special-case sort of helper for use in situations where an
    62  // expression might refer to count.index, each.key, or each.value, and thus
    63  // we say that it depends indirectly on the repetition expression.
    64  func (a *Analyzer) ReferencesFromResourceRepetition(addr addrs.AbsResource) []Reference {
    65  	modCfg := a.ModuleConfig(addr.Module)
    66  	if modCfg == nil {
    67  		return nil
    68  	}
    69  	rc := modCfg.ResourceByAddr(addr.Resource)
    70  	if rc == nil {
    71  		return nil
    72  	}
    73  
    74  	// We're assuming here that resources can either have count or for_each,
    75  	// but never both, because that's a requirement enforced by the language
    76  	// decoder. But we'll assert it just to make sure we catch it if that
    77  	// changes for some reason.
    78  	if rc.ForEach != nil && rc.Count != nil {
    79  		panic(fmt.Sprintf("%s has both for_each and count", addr))
    80  	}
    81  
    82  	switch {
    83  	case rc.ForEach != nil:
    84  		refs, _ := lang.ReferencesInExpr(addrs.ParseRef, rc.ForEach)
    85  		return absoluteRefs(addr.Module, refs)
    86  	case rc.Count != nil:
    87  		refs, _ := lang.ReferencesInExpr(addrs.ParseRef, rc.Count)
    88  		return absoluteRefs(addr.Module, refs)
    89  	default:
    90  		return nil
    91  	}
    92  }