1package terraform
2
3import (
4	"log"
5
6	"github.com/hashicorp/terraform/internal/dag"
7	"github.com/hashicorp/terraform/internal/logging"
8)
9
10// GraphTransformer is the interface that transformers implement. This
11// interface is only for transforms that need entire graph visibility.
12type GraphTransformer interface {
13	Transform(*Graph) error
14}
15
16// GraphVertexTransformer is an interface that transforms a single
17// Vertex within with graph. This is a specialization of GraphTransformer
18// that makes it easy to do vertex replacement.
19//
20// The GraphTransformer that runs through the GraphVertexTransformers is
21// VertexTransformer.
22type GraphVertexTransformer interface {
23	Transform(dag.Vertex) (dag.Vertex, error)
24}
25
26type graphTransformerMulti struct {
27	Transforms []GraphTransformer
28}
29
30func (t *graphTransformerMulti) Transform(g *Graph) error {
31	var lastStepStr string
32	for _, t := range t.Transforms {
33		log.Printf("[TRACE] (graphTransformerMulti) Executing graph transform %T", t)
34		if err := t.Transform(g); err != nil {
35			return err
36		}
37		if thisStepStr := g.StringWithNodeTypes(); thisStepStr != lastStepStr {
38			log.Printf("[TRACE] (graphTransformerMulti) Completed graph transform %T with new graph:\n%s  ------", t, logging.Indent(thisStepStr))
39			lastStepStr = thisStepStr
40		} else {
41			log.Printf("[TRACE] (graphTransformerMulti) Completed graph transform %T (no changes)", t)
42		}
43	}
44
45	return nil
46}
47
48// GraphTransformMulti combines multiple graph transformers into a single
49// GraphTransformer that runs all the individual graph transformers.
50func GraphTransformMulti(ts ...GraphTransformer) GraphTransformer {
51	return &graphTransformerMulti{Transforms: ts}
52}
53