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 }