github.com/hashicorp/hcl/v2@v2.20.0/cmd/hclspecsuite/diagnostics.go (about)

     1  // Copyright (c) HashiCorp, Inc.
     2  // SPDX-License-Identifier: MPL-2.0
     3  
     4  package main
     5  
     6  import (
     7  	"encoding/json"
     8  	"fmt"
     9  
    10  	"github.com/hashicorp/hcl/v2"
    11  )
    12  
    13  func decodeJSONDiagnostics(src []byte) hcl.Diagnostics {
    14  	type PosJSON struct {
    15  		Line   int `json:"line"`
    16  		Column int `json:"column"`
    17  		Byte   int `json:"byte"`
    18  	}
    19  	type RangeJSON struct {
    20  		Filename string  `json:"filename"`
    21  		Start    PosJSON `json:"start"`
    22  		End      PosJSON `json:"end"`
    23  	}
    24  	type DiagnosticJSON struct {
    25  		Severity string     `json:"severity"`
    26  		Summary  string     `json:"summary"`
    27  		Detail   string     `json:"detail,omitempty"`
    28  		Subject  *RangeJSON `json:"subject,omitempty"`
    29  	}
    30  	type DiagnosticsJSON struct {
    31  		Diagnostics []DiagnosticJSON `json:"diagnostics"`
    32  	}
    33  
    34  	var raw DiagnosticsJSON
    35  	var diags hcl.Diagnostics
    36  	err := json.Unmarshal(src, &raw)
    37  	if err != nil {
    38  		diags = append(diags, &hcl.Diagnostic{
    39  			Severity: hcl.DiagError,
    40  			Summary:  "Failed to parse hcldec diagnostics result",
    41  			Detail:   fmt.Sprintf("Sub-program hcldec produced invalid diagnostics: %s.", err),
    42  		})
    43  		return diags
    44  	}
    45  
    46  	if len(raw.Diagnostics) == 0 {
    47  		return nil
    48  	}
    49  
    50  	diags = make(hcl.Diagnostics, 0, len(raw.Diagnostics))
    51  	for _, rawDiag := range raw.Diagnostics {
    52  		var severity hcl.DiagnosticSeverity
    53  		switch rawDiag.Severity {
    54  		case "error":
    55  			severity = hcl.DiagError
    56  		case "warning":
    57  			severity = hcl.DiagWarning
    58  		default:
    59  			diags = append(diags, &hcl.Diagnostic{
    60  				Severity: hcl.DiagError,
    61  				Summary:  "Failed to parse hcldec diagnostics result",
    62  				Detail:   fmt.Sprintf("Diagnostic has unsupported severity %q.", rawDiag.Severity),
    63  			})
    64  			continue
    65  		}
    66  
    67  		diag := &hcl.Diagnostic{
    68  			Severity: severity,
    69  			Summary:  rawDiag.Summary,
    70  			Detail:   rawDiag.Detail,
    71  		}
    72  		if rawDiag.Subject != nil {
    73  			rawRange := rawDiag.Subject
    74  			diag.Subject = &hcl.Range{
    75  				Filename: rawRange.Filename,
    76  				Start: hcl.Pos{
    77  					Line:   rawRange.Start.Line,
    78  					Column: rawRange.Start.Column,
    79  					Byte:   rawRange.Start.Byte,
    80  				},
    81  				End: hcl.Pos{
    82  					Line:   rawRange.End.Line,
    83  					Column: rawRange.End.Column,
    84  					Byte:   rawRange.End.Byte,
    85  				},
    86  			}
    87  		}
    88  		diags = append(diags, diag)
    89  	}
    90  
    91  	return diags
    92  }
    93  
    94  func severityString(severity hcl.DiagnosticSeverity) string {
    95  	switch severity {
    96  	case hcl.DiagError:
    97  		return "error"
    98  	case hcl.DiagWarning:
    99  		return "warning"
   100  	default:
   101  		return "unsupported-severity"
   102  	}
   103  }
   104  
   105  func rangeString(rng hcl.Range) string {
   106  	return fmt.Sprintf(
   107  		"from line %d column %d byte %d to line %d column %d byte %d",
   108  		rng.Start.Line, rng.Start.Column, rng.Start.Byte,
   109  		rng.End.Line, rng.End.Column, rng.End.Byte,
   110  	)
   111  }