Repository: opentofu/opentofu
File: internal/tofu/transform_provider.go (Go)

Code before:
type ProviderUnconfiguredTransformer struct {
	Config *configs.Config
}

func (t *ProviderUnconfiguredTransformer) Transform(_ context.Context, g *Graph) error {
	if t.Config == nil {
		// This is probably a test case, inherited from ProviderTransformer
		log.Printf("[WARN] Skipping provider config and references transformer due to missing config")
		return nil
	}

	// Locate all providerVerts in the graph
	providerVerts := providerVertexMap(g)
	// Iterate through the providers to identify their dependencies (edges). If a provider
	// lacks both references and configuration, use a NodeEvalableProvider.
providerVertsLoop:
	for _, p := range providerVerts {
		applyableProvider, ok := p.(*NodeApplyableProvider)
		// If it's not an NodeApplyableProvider or there's existing configuration, we can skip it.
		if !ok || applyableProvider.Config != nil {
			continue
		}

		for _, edge := range g.EdgesFrom(p) {
			if _, ok := edge.Target().(GraphNodeProviderConsumer); ok {
				continue providerVertsLoop
			}
		}

		pAddr := applyableProvider.ProviderAddr()
		log.Printf("[TRACE] ProviderFunctionTransformer: replacing NodeApplyableProvider with NodeEvalableProvider for %s since it's missing configuration and there are no consumers of it", pAddr)
		unconfiguredProvider := &NodeEvalableProvider{
			&NodeAbstractProvider{
				Addr: pAddr,
			},
		}

		providerVerts[pAddr.String()] = unconfiguredProvider
		g.Replace(applyableProvider, unconfiguredProvider)
	}
	return nil
}

// ProviderFunctionTransformer is a GraphTransformer that maps nodes which reference functions to providers
// within the graph. This will error if there are any provider functions that don't map to known providers.
type ProviderFunctionTransformer struct {
	Config                  *configs.Config
	ProviderFunctionTracker ProviderFunctionMapping
}

func (t *ProviderFunctionTransformer) Transform(_ context.Context, g *Graph) error {

Review comment (suggestion):
I usually prefer to not label loops as it adds confusion.  I'd prefer code that looks like:

```go
found := false
for ... {
   if {
     found = true
     break
   }
}
if found {
  continue
}
```

Code after:
type ProviderUnconfiguredTransformer struct{}

func (t *ProviderUnconfiguredTransformer) Transform(_ context.Context, g *Graph) error {
	// Locate all providerVerts in the graph
	providerVerts := providerVertexMap(g)
	// Iterate through the providers to identify their dependencies (edges). If a provider
	// lacks both references and configuration, use a NodeEvalableProvider.
	for _, p := range providerVerts {
		applyableProvider, ok := p.(*NodeApplyableProvider)
		// There are three conditions to skip the conversion
		// from NodeApplyableProvider to NodeEvalableProvider:
		//   1. The node is not an NodeApplyableProvider
		//   2. The provider has existing configuration
		//   3. The provider node is referenced by another node
		edges := append(g.EdgesFrom(applyableProvider), g.EdgesTo(applyableProvider)...)
		if !ok || applyableProvider.Config != nil || len(edges) > 0 {
			continue
		}

		pAddr := applyableProvider.ProviderAddr()
		log.Printf("[TRACE] ProviderFunctionTransformer: replacing NodeApplyableProvider with NodeEvalableProvider for %s since it's missing configuration and there are no consumers of it", pAddr)
		unconfiguredProvider := &NodeEvalableProvider{
			&NodeAbstractProvider{
				Addr: pAddr,
			},
		}
		g.Replace(applyableProvider, unconfiguredProvider)
	}
	return nil
}

// ProviderFunctionTransformer is a GraphTransformer that maps nodes which reference functions to providers
// within the graph. This will error if there are any provider functions that don't map to known providers.
type ProviderFunctionTransformer struct {
	Config                  *configs.Config
	ProviderFunctionTracker ProviderFunctionMapping
}

func (t *ProviderFunctionTransformer) Transform(_ context.Context, g *Graph) error {
	var diags tfdiags.Diagnostics

	if t.Config == nil {
		// This is probably a test case, inherited from ProviderTransformer
		log.Printf("[WARN] Skipping provider function transformer due to missing config")
		return nil
	}

	// Locate all providerVerts in the graph
	providerVerts := providerVertexMap(g)
	// LuT of provider reference -> provider vertex
	providerReferences := make(map[ProviderFunctionReference]dag.Vertex)