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 }