mirror of
https://github.com/opentofu/opentofu.git
synced 2025-02-25 18:45:20 -06:00
68 lines
2.6 KiB
Go
68 lines
2.6 KiB
Go
// Copyright (c) The OpenTofu Authors
|
|
// SPDX-License-Identifier: MPL-2.0
|
|
// Copyright (c) 2023 HashiCorp, Inc.
|
|
// SPDX-License-Identifier: MPL-2.0
|
|
|
|
package structured
|
|
|
|
import (
|
|
"github.com/opentofu/opentofu/internal/command/jsonformat/computed"
|
|
)
|
|
|
|
type ProcessUnknown func(current Change) computed.Diff
|
|
type ProcessUnknownWithBefore func(current Change, before Change) computed.Diff
|
|
|
|
func (change Change) IsUnknown() bool {
|
|
if unknown, ok := change.Unknown.(bool); ok {
|
|
return unknown
|
|
}
|
|
return false
|
|
}
|
|
|
|
// CheckForUnknown is a helper function that handles all common functionality
|
|
// for processing an unknown value.
|
|
//
|
|
// It returns the computed unknown diff and true if this value was unknown and
|
|
// needs to be rendered as such, otherwise it returns the second return value as
|
|
// false and the first return value should be discarded.
|
|
//
|
|
// The actual processing of unknown values happens in the ProcessUnknown and
|
|
// ProcessUnknownWithBefore functions. If a value is unknown and is being
|
|
// created, the ProcessUnknown function is called and the caller should decide
|
|
// how to create the unknown value. If a value is being updated the
|
|
// ProcessUnknownWithBefore function is called and the function provides the
|
|
// before value as if it is being deleted for the caller to handle. Note that
|
|
// values being deleted will never be marked as unknown so this case isn't
|
|
// handled.
|
|
//
|
|
// The childUnknown argument is meant to allow callers with extra information
|
|
// about the type being processed to provide a list of known children that might
|
|
// not be present in the before or after values. These values will be propagated
|
|
// as the unknown values in the before value should it be needed.
|
|
func (change Change) CheckForUnknown(childUnknown interface{}, process ProcessUnknown, processBefore ProcessUnknownWithBefore) (computed.Diff, bool) {
|
|
unknown := change.IsUnknown()
|
|
|
|
if !unknown {
|
|
return computed.Diff{}, false
|
|
}
|
|
|
|
// No matter what we do here, we want to treat the after value as explicit.
|
|
// This is because it is going to be null in the value, and we don't want
|
|
// the functions in this package to assume this means it has been deleted.
|
|
change.AfterExplicit = true
|
|
|
|
if change.Before == nil {
|
|
return process(change), true
|
|
}
|
|
|
|
// If we get here, then we have a before value. We're going to model a
|
|
// delete operation and our renderer later can render the overall change
|
|
// accurately.
|
|
before := change.AsDelete()
|
|
|
|
// We also let our callers override the unknown values in any before, this
|
|
// is the renderers can display them as being computed instead of deleted.
|
|
before.Unknown = childUnknown
|
|
return processBefore(change, before), true
|
|
}
|