github.com/opentofu/opentofu@v1.7.1/internal/configs/configschema/empty_value.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  // EmptyValue returns the "empty value" for the recieving block, which for
    13  // a block type is a non-null object where all of the attribute values are
    14  // the empty values of the block's attributes and nested block types.
    15  //
    16  // In other words, it returns the value that would be returned if an empty
    17  // block were decoded against the recieving schema, assuming that no required
    18  // attribute or block constraints were honored.
    19  func (b *Block) EmptyValue() cty.Value {
    20  	vals := make(map[string]cty.Value)
    21  	for name, attrS := range b.Attributes {
    22  		vals[name] = attrS.EmptyValue()
    23  	}
    24  	for name, blockS := range b.BlockTypes {
    25  		vals[name] = blockS.EmptyValue()
    26  	}
    27  	return cty.ObjectVal(vals)
    28  }
    29  
    30  // EmptyValue returns the "empty value" for the receiving attribute, which is
    31  // the value that would be returned if there were no definition of the attribute
    32  // at all, ignoring any required constraint.
    33  func (a *Attribute) EmptyValue() cty.Value {
    34  	return cty.NullVal(a.ImpliedType())
    35  }
    36  
    37  // EmptyValue returns the "empty value" for when there are zero nested blocks
    38  // present of the receiving type.
    39  func (b *NestedBlock) EmptyValue() cty.Value {
    40  	switch b.Nesting {
    41  	case NestingSingle:
    42  		return cty.NullVal(b.Block.ImpliedType())
    43  	case NestingGroup:
    44  		return b.Block.EmptyValue()
    45  	case NestingList:
    46  		if ty := b.Block.ImpliedType(); ty.HasDynamicTypes() {
    47  			return cty.EmptyTupleVal
    48  		} else {
    49  			return cty.ListValEmpty(ty)
    50  		}
    51  	case NestingMap:
    52  		if ty := b.Block.ImpliedType(); ty.HasDynamicTypes() {
    53  			return cty.EmptyObjectVal
    54  		} else {
    55  			return cty.MapValEmpty(ty)
    56  		}
    57  	case NestingSet:
    58  		return cty.SetValEmpty(b.Block.ImpliedType())
    59  	default:
    60  		// Should never get here because the above is intended to be exhaustive,
    61  		// but we'll be robust and return a result nonetheless.
    62  		return cty.NullVal(cty.DynamicPseudoType)
    63  	}
    64  }