@@ -6,6 +6,43 @@ import (
66 "github.com/hashicorp/hcl/v2"
77)
88
9+ type DiagnosticExtra struct {
10+ Code string `json:"code"`
11+
12+ // If there was a previous extra, store it here for unwrapping.
13+ wrapped any
14+ }
15+
16+ var _ hcl.DiagnosticExtraUnwrapper = DiagnosticExtra {}
17+
18+ func (e DiagnosticExtra ) UnwrapDiagnosticExtra () interface {} {
19+ return e .wrapped
20+ }
21+
22+ func ExtractDiagnosticExtra (diag * hcl.Diagnostic ) DiagnosticExtra {
23+ // Zero values for a missing extra field is fine.
24+ extra , _ := hcl.DiagnosticExtra [DiagnosticExtra ](diag )
25+ return extra
26+ }
27+
28+ func SetDiagnosticExtra (diag * hcl.Diagnostic , extra DiagnosticExtra ) {
29+ existing , ok := hcl.DiagnosticExtra [DiagnosticExtra ](diag )
30+ if ok {
31+ // If an existing extra is present, we will keep the underlying
32+ // wrapped. This is not perfect, as any parents are lost.
33+ // So try to avoid calling 'SetDiagnosticExtra' more than once.
34+ extra .wrapped = existing .wrapped
35+ diag .Extra = extra
36+ return
37+ }
38+
39+ // Maintain any existing extra fields.
40+ if diag .Extra != nil {
41+ extra .wrapped = diag .Extra
42+ }
43+ diag .Extra = extra
44+ }
45+
946// Diagnostics is a JSON friendly form of hcl.Diagnostics.
1047// Data is lost when doing a json marshal.
1148type Diagnostics hcl.Diagnostics
@@ -23,11 +60,15 @@ func (d *Diagnostics) UnmarshalJSON(data []byte) error {
2360 severity = hcl .DiagWarning
2461 }
2562
26- * d = append ( * d , & hcl.Diagnostic {
63+ hclDiag := & hcl.Diagnostic {
2764 Severity : severity ,
2865 Summary : diag .Summary ,
2966 Detail : diag .Detail ,
30- })
67+ }
68+
69+ SetDiagnosticExtra (hclDiag , diag .Extra )
70+
71+ * d = append (* d , hclDiag )
3172 }
3273 return nil
3374}
@@ -40,10 +81,13 @@ func (d Diagnostics) MarshalJSON() ([]byte, error) {
4081 severity = DiagnosticSeverityWarning
4182 }
4283
84+ extra := ExtractDiagnosticExtra (diag )
85+
4386 cpy = append (cpy , FriendlyDiagnostic {
4487 Severity : severity ,
4588 Summary : diag .Summary ,
4689 Detail : diag .Detail ,
90+ Extra : extra ,
4791 })
4892 }
4993 return json .Marshal (cpy )
@@ -60,4 +104,6 @@ type FriendlyDiagnostic struct {
60104 Severity DiagnosticSeverityString `json:"severity"`
61105 Summary string `json:"summary"`
62106 Detail string `json:"detail"`
107+
108+ Extra DiagnosticExtra `json:"extra"`
63109}
0 commit comments