func sniffCoreVersionRequirements(body hcl.Body) ([]VersionConstraint, hcl.Diagnostics) {
	rootContent, _, diags := body.PartialContent(configFileTerraformBlockSniffRootSchema)
	var constraints []VersionConstraint
	for _, block := range rootContent.Blocks {
		content, _, blockDiags := block.Body.PartialContent(configFileVersionSniffBlockSchema)
		diags = append(diags, blockDiags...)
		attr, exists := content.Attributes["required_version"]
		if !exists {
			continue
		}
		constraint, constraintDiags := decodeVersionConstraint(attr)
		diags = append(diags, constraintDiags...)
		if !constraintDiags.HasErrors() {
			constraints = append(constraints, constraint)
		}
	}
	return constraints, diags
}
sniffCoreVersionRequirements does minimal parsing of the given body for
"terraform" blocks with "required_version" attributes, returning the
requirements found.

This is intended to maximize the chance that we'll be able to read the
requirements (syntax errors notwithstanding) even if the config file contains
constructs that might've been added in future Terraform versions

This is a "best effort" sort of method which will return constraints it is
able to find, but may return no constraints at all if the given body is
so invalid that it cannot be decoded at all.
package configs
import (
	"github.com/hashicorp/hcl/v2"
)
func (p *Parser) LoadConfigFile(path string) (*File, hcl.Diagnostics) {
	return p.loadConfigFile(path, false)
}
func (p *Parser) LoadConfigFileOverride(path string) (*File, hcl.Diagnostics) {
	return p.loadConfigFile(path, true)
}
func (p *Parser) loadConfigFile(path string, override bool) (*File, hcl.Diagnostics) {
	body, diags := p.LoadHCLFile(path)
	if body == nil {
		return nil, diags
	}
	file := &File{}
	var reqDiags hcl.Diagnostics
	file.CoreVersionConstraints, reqDiags = sniffCoreVersionRequirements(body)
	diags = append(diags, reqDiags...)
	var expDiags hcl.Diagnostics
	file.ActiveExperiments, expDiags = sniffActiveExperiments(body)
	diags = append(diags, expDiags...)
	content, contentDiags := body.Content(configFileSchema)
	diags = append(diags, contentDiags...)
	for _, block := range content.Blocks {
		switch block.Type {
		case "terraform":
			content, contentDiags := block.Body.Content(terraformBlockSchema)
			diags = append(diags, contentDiags...)
			for _, innerBlock := range content.Blocks {
				switch innerBlock.Type {
				case "backend":
					backendCfg, cfgDiags := decodeBackendBlock(innerBlock)
					diags = append(diags, cfgDiags...)
					if backendCfg != nil {
						file.Backends = append(file.Backends, backendCfg)
					}
				case "required_providers":
					reqs, reqsDiags := decodeRequiredProvidersBlock(innerBlock)
					diags = append(diags, reqsDiags...)
					file.RequiredProviders = append(file.RequiredProviders, reqs)
				case "provider_meta":
					providerCfg, cfgDiags := decodeProviderMetaBlock(innerBlock)
					diags = append(diags, cfgDiags...)
					if providerCfg != nil {
						file.ProviderMetas = append(file.ProviderMetas, providerCfg)
					}
				default:
					continue
				}
			}
		case "required_providers":
			diags = append(diags, &hcl.Diagnostic{
				Severity: hcl.DiagError,
				Summary:  "Invalid required_providers block",
				Detail:   "A \"required_providers\" block must be nested inside a \"terraform\" block.",
				Subject:  block.TypeRange.Ptr(),
			})
		case "provider":
			cfg, cfgDiags := decodeProviderBlock(block)
			diags = append(diags, cfgDiags...)
			if cfg != nil {
				file.ProviderConfigs = append(file.ProviderConfigs, cfg)
			}
		case "variable":
			cfg, cfgDiags := decodeVariableBlock(block, override)
			diags = append(diags, cfgDiags...)
			if cfg != nil {
				file.Variables = append(file.Variables, cfg)
			}
		case "locals":
			defs, defsDiags := decodeLocalsBlock(block)
			diags = append(diags, defsDiags...)
			file.Locals = append(file.Locals, defs...)
		case "output":
			cfg, cfgDiags := decodeOutputBlock(block, override)
			diags = append(diags, cfgDiags...)
			if cfg != nil {
				file.Outputs = append(file.Outputs, cfg)
			}
		case "module":
			cfg, cfgDiags := decodeModuleBlock(block, override)
			diags = append(diags, cfgDiags...)
			if cfg != nil {
				file.ModuleCalls = append(file.ModuleCalls, cfg)
			}
		case "resource":
			cfg, cfgDiags := decodeResourceBlock(block)
			diags = append(diags, cfgDiags...)
			if cfg != nil {
				file.ManagedResources = append(file.ManagedResources, cfg)
			}
		case "data":
			cfg, cfgDiags := decodeDataBlock(block)
			diags = append(diags, cfgDiags...)
			if cfg != nil {
				file.DataResources = append(file.DataResources, cfg)
			}
		default:
			continue
		}
	}
	return file, diags
}