github.com/opentofu/opentofu@v1.7.1/internal/configs/configschema/path.go (about)

     1  // Copyright (c) The OpenTofu Authors
     2  // SPDX-License-Identifier: MPL-2.0
     3  // Copyright (c) 2023 HashiCorp, Inc.
     4  // SPDX-License-Identifier: MPL-2.0
     5  
     6  package configschema
     7  
     8  import (
     9  	"github.com/zclconf/go-cty/cty"
    10  )
    11  
    12  // AttributeByPath looks up the Attribute schema which corresponds to the given
    13  // cty.Path. A nil value is returned if the given path does not correspond to a
    14  // specific attribute.
    15  func (b *Block) AttributeByPath(path cty.Path) *Attribute {
    16  	block := b
    17  	for i, step := range path {
    18  		switch step := step.(type) {
    19  		case cty.GetAttrStep:
    20  			if attr := block.Attributes[step.Name]; attr != nil {
    21  				// If the Attribute is defined with a NestedType and there's
    22  				// more to the path, descend into the NestedType
    23  				if attr.NestedType != nil && i < len(path)-1 {
    24  					return attr.NestedType.AttributeByPath(path[i+1:])
    25  				} else if i < len(path)-1 { // There's more to the path, but not more to this Attribute.
    26  					return nil
    27  				}
    28  				return attr
    29  			}
    30  
    31  			if nestedBlock := block.BlockTypes[step.Name]; nestedBlock != nil {
    32  				block = &nestedBlock.Block
    33  				continue
    34  			}
    35  
    36  			return nil
    37  		}
    38  	}
    39  	return nil
    40  }
    41  
    42  // AttributeByPath recurses through a NestedType to look up the Attribute scheme
    43  // which corresponds to the given cty.Path. A nil value is returned if the given
    44  // path does not correspond to a specific attribute.
    45  func (o *Object) AttributeByPath(path cty.Path) *Attribute {
    46  	for i, step := range path {
    47  		switch step := step.(type) {
    48  		case cty.GetAttrStep:
    49  			if attr := o.Attributes[step.Name]; attr != nil {
    50  				if attr.NestedType != nil && i < len(path)-1 {
    51  					return attr.NestedType.AttributeByPath(path[i+1:])
    52  				} else if i < len(path)-1 { // There's more to the path, but not more to this Attribute.
    53  					return nil
    54  				}
    55  				return attr
    56  			}
    57  		}
    58  	}
    59  	return nil
    60  }