code: func (c *Context) Validate() tfdiags.Diagnostics {
  	defer c.acquireRun("validate")()
  
  	var diags tfdiags.Diagnostics
  
  	// Validate input variables. We do this only for the values supplied
  	// by the root module, since child module calls are validated when we
  	// visit their graph nodes.
  	if c.config != nil {
  		varDiags := checkInputVariables(c.config.Module.Variables, c.variables)
  		diags = diags.Append(varDiags)
  	}
  
  	// If we have errors at this point then we probably won't be able to
  	// construct a graph without producing redundant errors, so we'll halt early.
  	if diags.HasErrors() {
  		return diags
  	}
  
  	// Build the graph so we can walk it and run Validate on nodes.
  	// We also validate the graph generated here, but this graph doesn't
  	// necessarily match the graph that Plan will generate, so we'll validate the
  	// graph again later after Planning.
  	graph, graphDiags := c.Graph(GraphTypeValidate, nil)
  	diags = diags.Append(graphDiags)
  	if graphDiags.HasErrors() {
  		return diags
  	}
  
  	// Walk
  	walker, walkDiags := c.walk(graph, walkValidate)
  	diags = diags.Append(walker.NonFatalDiagnostics)
  	diags = diags.Append(walkDiags)
  	if walkDiags.HasErrors() {
  		return diags
  	}
  
  	return diags
  }
docs: // Validate performs semantic validation of the configuration, and returning
  // any warnings or errors.
  //
  // Syntax and structural checks are performed by the configuration loader,
  // and so are not repeated here.