| package main |
| |
| import ( |
| "encoding/json" |
| "io" |
| |
| "github.com/hashicorp/hcl/v2" |
| ) |
| |
| type jsonDiagWriter struct { |
| w io.Writer |
| diags hcl.Diagnostics |
| } |
| |
| var _ hcl.DiagnosticWriter = &jsonDiagWriter{} |
| |
| func (wr *jsonDiagWriter) WriteDiagnostic(diag *hcl.Diagnostic) error { |
| wr.diags = append(wr.diags, diag) |
| return nil |
| } |
| |
| func (wr *jsonDiagWriter) WriteDiagnostics(diags hcl.Diagnostics) error { |
| wr.diags = append(wr.diags, diags...) |
| return nil |
| } |
| |
| func (wr *jsonDiagWriter) Flush() error { |
| if len(wr.diags) == 0 { |
| return nil |
| } |
| |
| 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"` |
| } |
| |
| diagsJSON := make([]DiagnosticJSON, 0, len(wr.diags)) |
| for _, diag := range wr.diags { |
| var diagJSON DiagnosticJSON |
| |
| switch diag.Severity { |
| case hcl.DiagError: |
| diagJSON.Severity = "error" |
| case hcl.DiagWarning: |
| diagJSON.Severity = "warning" |
| default: |
| diagJSON.Severity = "(unknown)" // should never happen |
| } |
| |
| diagJSON.Summary = diag.Summary |
| diagJSON.Detail = diag.Detail |
| if diag.Subject != nil { |
| diagJSON.Subject = &RangeJSON{} |
| sJSON := diagJSON.Subject |
| rng := diag.Subject |
| sJSON.Filename = rng.Filename |
| sJSON.Start.Line = rng.Start.Line |
| sJSON.Start.Column = rng.Start.Column |
| sJSON.Start.Byte = rng.Start.Byte |
| sJSON.End.Line = rng.End.Line |
| sJSON.End.Column = rng.End.Column |
| sJSON.End.Byte = rng.End.Byte |
| } |
| |
| diagsJSON = append(diagsJSON, diagJSON) |
| } |
| |
| src, err := json.MarshalIndent(DiagnosticsJSON{diagsJSON}, "", " ") |
| if err != nil { |
| return err |
| } |
| _, err = wr.w.Write(src) |
| wr.w.Write([]byte{'\n'}) |
| return err |
| } |
| |
| type flusher interface { |
| Flush() error |
| } |
| |
| func flush(maybeFlusher interface{}) error { |
| if f, ok := maybeFlusher.(flusher); ok { |
| return f.Flush() |
| } |
| return nil |
| } |