github.com/graywolf-at-work-2/terraform-vendor@v1.4.5/internal/lang/globalref/analyzer.go (about)

     1  package globalref
     2  
     3  import (
     4  	"fmt"
     5  
     6  	"github.com/hashicorp/terraform/internal/addrs"
     7  	"github.com/hashicorp/terraform/internal/configs"
     8  	"github.com/hashicorp/terraform/internal/providers"
     9  )
    10  
    11  // Analyzer is the main component of this package, serving as a container for
    12  // various state that the analysis algorithms depend on either for their core
    13  // functionality or for producing results more quickly.
    14  //
    15  // Global reference analysis is currently intended only for "best effort"
    16  // use-cases related to giving hints to the user or tailoring UI output.
    17  // Avoid using it for anything that would cause changes to the analyzer being
    18  // considered a breaking change under the v1 compatibility promises, because
    19  // we expect to continue to refine and evolve these rules over time in ways
    20  // that may cause us to detect either more or fewer references than today.
    21  // Typically we will conservatively return more references than would be
    22  // necessary dynamically, but that isn't guaranteed for all situations.
    23  //
    24  // In particular, we currently typically don't distinguish between multiple
    25  // instances of the same module, and so we overgeneralize references from
    26  // one instance of a module as references from the same location in all
    27  // instances of that module. We may make this more precise in future, which
    28  // would then remove various detected references from the analysis results.
    29  //
    30  // Each Analyzer works with a particular configs.Config object which it assumes
    31  // represents the root module of a configuration. Config objects are typically
    32  // immutable by convention anyway, but it's particularly important not to
    33  // modify a configuration while it's attached to a live Analyzer, because
    34  // the Analyzer contains caches derived from data in the configuration tree.
    35  type Analyzer struct {
    36  	cfg             *configs.Config
    37  	providerSchemas map[addrs.Provider]*providers.Schemas
    38  }
    39  
    40  // NewAnalyzer constructs a new analyzer bound to the given configuration and
    41  // provider schemas.
    42  //
    43  // The given object must represent a root module, or this function will panic.
    44  //
    45  // The given provider schemas must cover at least all of the providers used
    46  // in the given configuration. If not then analysis results will be silently
    47  // incomplete for any decision that requires checking schema.
    48  func NewAnalyzer(cfg *configs.Config, providerSchemas map[addrs.Provider]*providers.Schemas) *Analyzer {
    49  	if !cfg.Path.IsRoot() {
    50  		panic(fmt.Sprintf("constructing an Analyzer with non-root module %s", cfg.Path))
    51  	}
    52  
    53  	ret := &Analyzer{
    54  		cfg:             cfg,
    55  		providerSchemas: providerSchemas,
    56  	}
    57  	return ret
    58  }
    59  
    60  // ModuleConfig retrieves a module configuration from the configuration the
    61  // analyzer belongs to, or nil if there is no module with the given address.
    62  func (a *Analyzer) ModuleConfig(addr addrs.ModuleInstance) *configs.Module {
    63  	modCfg := a.cfg.DescendentForInstance(addr)
    64  	if modCfg == nil {
    65  		return nil
    66  	}
    67  	return modCfg.Module
    68  }