github.com/opentofu/opentofu@v1.7.1/internal/addrs/check_rule_diagnostic.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 addrs 7 8 import "github.com/opentofu/opentofu/internal/tfdiags" 9 10 // DiagnosticExtraCheckRule provides an interface for diagnostic ExtraInfo to 11 // retrieve an embedded CheckRule from within a tfdiags.Diagnostic. 12 type DiagnosticExtraCheckRule interface { 13 // DiagnosticOriginatesFromCheckRule returns the CheckRule that the 14 // surrounding diagnostic originated from. 15 DiagnosticOriginatesFromCheckRule() CheckRule 16 } 17 18 // DiagnosticOriginatesFromCheckRule checks if the provided diagnostic contains 19 // a CheckRule as ExtraInfo and returns that CheckRule and true if it does. This 20 // function returns an empty CheckRule and false if the diagnostic does not 21 // contain a CheckRule. 22 func DiagnosticOriginatesFromCheckRule(diag tfdiags.Diagnostic) (CheckRule, bool) { 23 maybe := tfdiags.ExtraInfo[DiagnosticExtraCheckRule](diag) 24 if maybe == nil { 25 return CheckRule{}, false 26 } 27 return maybe.DiagnosticOriginatesFromCheckRule(), true 28 } 29 30 // CheckRuleDiagnosticExtra is an object that can be attached to diagnostics 31 // that originate from check rules. 32 // 33 // It implements the DiagnosticExtraCheckRule interface for retrieving the 34 // concrete CheckRule that spawned the diagnostic. 35 // 36 // It also implements the tfdiags.DiagnosticExtraDoNotConsolidate interface, to 37 // stop diagnostics created by check blocks being consolidated. 38 // 39 // It also implements the tfdiags.DiagnosticExtraUnwrapper interface, as nested 40 // data blocks will attach this struct but do want to lose any extra info 41 // embedded in the original diagnostic. 42 type CheckRuleDiagnosticExtra struct { 43 CheckRule CheckRule 44 45 wrapped interface{} 46 } 47 48 var ( 49 _ DiagnosticExtraCheckRule = (*CheckRuleDiagnosticExtra)(nil) 50 _ tfdiags.DiagnosticExtraDoNotConsolidate = (*CheckRuleDiagnosticExtra)(nil) 51 _ tfdiags.DiagnosticExtraUnwrapper = (*CheckRuleDiagnosticExtra)(nil) 52 _ tfdiags.DiagnosticExtraWrapper = (*CheckRuleDiagnosticExtra)(nil) 53 ) 54 55 func (c *CheckRuleDiagnosticExtra) UnwrapDiagnosticExtra() interface{} { 56 return c.wrapped 57 } 58 59 func (c *CheckRuleDiagnosticExtra) WrapDiagnosticExtra(inner interface{}) { 60 if c.wrapped != nil { 61 // This is a logical inconsistency, the caller should know whether they 62 // have already wrapped an extra or not. 63 panic("Attempted to wrap a diagnostic extra into a CheckRuleDiagnosticExtra that is already wrapping a different extra. This is a bug in OpenTofu, please report it.") 64 } 65 c.wrapped = inner 66 } 67 68 func (c *CheckRuleDiagnosticExtra) DoNotConsolidateDiagnostic() bool { 69 // Do not consolidate warnings from check blocks. 70 return c.CheckRule.Container.CheckableKind() == CheckableCheck 71 } 72 73 func (c *CheckRuleDiagnosticExtra) DiagnosticOriginatesFromCheckRule() CheckRule { 74 return c.CheckRule 75 }