github.com/hashicorp/hcl/v2@v2.20.0/cmd/hcldec/diags_json.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 "io" 9 10 "github.com/hashicorp/hcl/v2" 11 ) 12 13 type jsonDiagWriter struct { 14 w io.Writer 15 diags hcl.Diagnostics 16 } 17 18 var _ hcl.DiagnosticWriter = &jsonDiagWriter{} 19 20 func (wr *jsonDiagWriter) WriteDiagnostic(diag *hcl.Diagnostic) error { 21 wr.diags = append(wr.diags, diag) 22 return nil 23 } 24 25 func (wr *jsonDiagWriter) WriteDiagnostics(diags hcl.Diagnostics) error { 26 wr.diags = append(wr.diags, diags...) 27 return nil 28 } 29 30 func (wr *jsonDiagWriter) Flush() error { 31 if len(wr.diags) == 0 { 32 return nil 33 } 34 35 type PosJSON struct { 36 Line int `json:"line"` 37 Column int `json:"column"` 38 Byte int `json:"byte"` 39 } 40 type RangeJSON struct { 41 Filename string `json:"filename"` 42 Start PosJSON `json:"start"` 43 End PosJSON `json:"end"` 44 } 45 type DiagnosticJSON struct { 46 Severity string `json:"severity"` 47 Summary string `json:"summary"` 48 Detail string `json:"detail,omitempty"` 49 Subject *RangeJSON `json:"subject,omitempty"` 50 } 51 type DiagnosticsJSON struct { 52 Diagnostics []DiagnosticJSON `json:"diagnostics"` 53 } 54 55 diagsJSON := make([]DiagnosticJSON, 0, len(wr.diags)) 56 for _, diag := range wr.diags { 57 var diagJSON DiagnosticJSON 58 59 switch diag.Severity { 60 case hcl.DiagError: 61 diagJSON.Severity = "error" 62 case hcl.DiagWarning: 63 diagJSON.Severity = "warning" 64 default: 65 diagJSON.Severity = "(unknown)" // should never happen 66 } 67 68 diagJSON.Summary = diag.Summary 69 diagJSON.Detail = diag.Detail 70 if diag.Subject != nil { 71 diagJSON.Subject = &RangeJSON{} 72 sJSON := diagJSON.Subject 73 rng := diag.Subject 74 sJSON.Filename = rng.Filename 75 sJSON.Start.Line = rng.Start.Line 76 sJSON.Start.Column = rng.Start.Column 77 sJSON.Start.Byte = rng.Start.Byte 78 sJSON.End.Line = rng.End.Line 79 sJSON.End.Column = rng.End.Column 80 sJSON.End.Byte = rng.End.Byte 81 } 82 83 diagsJSON = append(diagsJSON, diagJSON) 84 } 85 86 src, err := json.MarshalIndent(DiagnosticsJSON{diagsJSON}, "", " ") 87 if err != nil { 88 return err 89 } 90 _, err = wr.w.Write(src) 91 wr.w.Write([]byte{'\n'}) 92 return err 93 } 94 95 type flusher interface { 96 Flush() error 97 } 98 99 func flush(maybeFlusher interface{}) error { 100 if f, ok := maybeFlusher.(flusher); ok { 101 return f.Flush() 102 } 103 return nil 104 }