| package main |
| |
| import ( |
| "encoding/json" |
| "fmt" |
| |
| "github.com/hashicorp/hcl/v2" |
| ) |
| |
| func decodeJSONDiagnostics(src []byte) hcl.Diagnostics { |
| type PosJSON struct { |
| Line int `json:"line"` |
| Column int `json:"column"` |
| Byte int `json:"byte"` |
| } |
| type RangeJSON struct { |
| Filename string `json:"filename"` |
| Start PosJSON `json:"start"` |
| End PosJSON `json:"end"` |
| } |
| type DiagnosticJSON struct { |
| Severity string `json:"severity"` |
| Summary string `json:"summary"` |
| Detail string `json:"detail,omitempty"` |
| Subject *RangeJSON `json:"subject,omitempty"` |
| } |
| type DiagnosticsJSON struct { |
| Diagnostics []DiagnosticJSON `json:"diagnostics"` |
| } |
| |
| var raw DiagnosticsJSON |
| var diags hcl.Diagnostics |
| err := json.Unmarshal(src, &raw) |
| if err != nil { |
| diags = append(diags, &hcl.Diagnostic{ |
| Severity: hcl.DiagError, |
| Summary: "Failed to parse hcldec diagnostics result", |
| Detail: fmt.Sprintf("Sub-program hcldec produced invalid diagnostics: %s.", err), |
| }) |
| return diags |
| } |
| |
| if len(raw.Diagnostics) == 0 { |
| return nil |
| } |
| |
| diags = make(hcl.Diagnostics, 0, len(raw.Diagnostics)) |
| for _, rawDiag := range raw.Diagnostics { |
| var severity hcl.DiagnosticSeverity |
| switch rawDiag.Severity { |
| case "error": |
| severity = hcl.DiagError |
| case "warning": |
| severity = hcl.DiagWarning |
| default: |
| diags = append(diags, &hcl.Diagnostic{ |
| Severity: hcl.DiagError, |
| Summary: "Failed to parse hcldec diagnostics result", |
| Detail: fmt.Sprintf("Diagnostic has unsupported severity %q.", rawDiag.Severity), |
| }) |
| continue |
| } |
| |
| diag := &hcl.Diagnostic{ |
| Severity: severity, |
| Summary: rawDiag.Summary, |
| Detail: rawDiag.Detail, |
| } |
| if rawDiag.Subject != nil { |
| rawRange := rawDiag.Subject |
| diag.Subject = &hcl.Range{ |
| Filename: rawRange.Filename, |
| Start: hcl.Pos{ |
| Line: rawRange.Start.Line, |
| Column: rawRange.Start.Column, |
| Byte: rawRange.Start.Byte, |
| }, |
| End: hcl.Pos{ |
| Line: rawRange.End.Line, |
| Column: rawRange.End.Column, |
| Byte: rawRange.End.Byte, |
| }, |
| } |
| } |
| diags = append(diags, diag) |
| } |
| |
| return diags |
| } |
| |
| func severityString(severity hcl.DiagnosticSeverity) string { |
| switch severity { |
| case hcl.DiagError: |
| return "error" |
| case hcl.DiagWarning: |
| return "warning" |
| default: |
| return "unsupported-severity" |
| } |
| } |
| |
| func rangeString(rng hcl.Range) string { |
| return fmt.Sprintf( |
| "from line %d column %d byte %d to line %d column %d byte %d", |
| rng.Start.Line, rng.Start.Column, rng.Start.Byte, |
| rng.End.Line, rng.End.Column, rng.End.Byte, |
| ) |
| } |