github.com/eliastor/durgaform@v0.0.0-20220816172711-d0ab2d17673e/internal/tfdiags/hcl.go (about)

     1  package tfdiags
     2  
     3  import (
     4  	"github.com/hashicorp/hcl/v2"
     5  )
     6  
     7  // hclDiagnostic is a Diagnostic implementation that wraps a HCL Diagnostic
     8  type hclDiagnostic struct {
     9  	diag *hcl.Diagnostic
    10  }
    11  
    12  var _ Diagnostic = hclDiagnostic{}
    13  
    14  func (d hclDiagnostic) Severity() Severity {
    15  	switch d.diag.Severity {
    16  	case hcl.DiagWarning:
    17  		return Warning
    18  	default:
    19  		return Error
    20  	}
    21  }
    22  
    23  func (d hclDiagnostic) Description() Description {
    24  	return Description{
    25  		Summary: d.diag.Summary,
    26  		Detail:  d.diag.Detail,
    27  	}
    28  }
    29  
    30  func (d hclDiagnostic) Source() Source {
    31  	var ret Source
    32  	if d.diag.Subject != nil {
    33  		rng := SourceRangeFromHCL(*d.diag.Subject)
    34  		ret.Subject = &rng
    35  	}
    36  	if d.diag.Context != nil {
    37  		rng := SourceRangeFromHCL(*d.diag.Context)
    38  		ret.Context = &rng
    39  	}
    40  	return ret
    41  }
    42  
    43  func (d hclDiagnostic) FromExpr() *FromExpr {
    44  	if d.diag.Expression == nil || d.diag.EvalContext == nil {
    45  		return nil
    46  	}
    47  	return &FromExpr{
    48  		Expression:  d.diag.Expression,
    49  		EvalContext: d.diag.EvalContext,
    50  	}
    51  }
    52  
    53  func (d hclDiagnostic) ExtraInfo() interface{} {
    54  	return d.diag.Extra
    55  }
    56  
    57  // SourceRangeFromHCL constructs a SourceRange from the corresponding range
    58  // type within the HCL package.
    59  func SourceRangeFromHCL(hclRange hcl.Range) SourceRange {
    60  	return SourceRange{
    61  		Filename: hclRange.Filename,
    62  		Start: SourcePos{
    63  			Line:   hclRange.Start.Line,
    64  			Column: hclRange.Start.Column,
    65  			Byte:   hclRange.Start.Byte,
    66  		},
    67  		End: SourcePos{
    68  			Line:   hclRange.End.Line,
    69  			Column: hclRange.End.Column,
    70  			Byte:   hclRange.End.Byte,
    71  		},
    72  	}
    73  }
    74  
    75  // ToHCL constructs a HCL Range from the receiving SourceRange. This is the
    76  // opposite of SourceRangeFromHCL.
    77  func (r SourceRange) ToHCL() hcl.Range {
    78  	return hcl.Range{
    79  		Filename: r.Filename,
    80  		Start: hcl.Pos{
    81  			Line:   r.Start.Line,
    82  			Column: r.Start.Column,
    83  			Byte:   r.Start.Byte,
    84  		},
    85  		End: hcl.Pos{
    86  			Line:   r.End.Line,
    87  			Column: r.End.Column,
    88  			Byte:   r.End.Byte,
    89  		},
    90  	}
    91  }
    92  
    93  // ToHCL constructs a hcl.Diagnostics containing the same diagnostic messages
    94  // as the receiving tfdiags.Diagnostics.
    95  //
    96  // This conversion preserves the data that HCL diagnostics are able to
    97  // preserve but would be lossy in a round trip from tfdiags to HCL and then
    98  // back to tfdiags, because it will lose the specific type information of
    99  // the source diagnostics. In most cases this will not be a significant
   100  // problem, but could produce an awkward result in some special cases such
   101  // as converting the result of ConsolidateWarnings, which will force the
   102  // resulting warning groups to be flattened early.
   103  func (diags Diagnostics) ToHCL() hcl.Diagnostics {
   104  	if len(diags) == 0 {
   105  		return nil
   106  	}
   107  	ret := make(hcl.Diagnostics, len(diags))
   108  	for i, diag := range diags {
   109  		severity := diag.Severity()
   110  		desc := diag.Description()
   111  		source := diag.Source()
   112  		fromExpr := diag.FromExpr()
   113  
   114  		hclDiag := &hcl.Diagnostic{
   115  			Summary:  desc.Summary,
   116  			Detail:   desc.Detail,
   117  			Severity: severity.ToHCL(),
   118  		}
   119  		if source.Subject != nil {
   120  			hclDiag.Subject = source.Subject.ToHCL().Ptr()
   121  		}
   122  		if source.Context != nil {
   123  			hclDiag.Context = source.Context.ToHCL().Ptr()
   124  		}
   125  		if fromExpr != nil {
   126  			hclDiag.Expression = fromExpr.Expression
   127  			hclDiag.EvalContext = fromExpr.EvalContext
   128  		}
   129  
   130  		ret[i] = hclDiag
   131  	}
   132  	return ret
   133  }