]> git.immae.eu Git - github/fretlink/terraform-provider-statuscake.git/blame - vendor/github.com/hashicorp/hcl2/hcl/diagnostic.go
Upgrade to 0.12
[github/fretlink/terraform-provider-statuscake.git] / vendor / github.com / hashicorp / hcl2 / hcl / diagnostic.go
CommitLineData
15c0b25d
AP
1package hcl
2
3import (
4 "fmt"
5)
6
7// DiagnosticSeverity represents the severity of a diagnostic.
8type DiagnosticSeverity int
9
10const (
11 // DiagInvalid is the invalid zero value of DiagnosticSeverity
12 DiagInvalid DiagnosticSeverity = iota
13
14 // DiagError indicates that the problem reported by a diagnostic prevents
15 // further progress in parsing and/or evaluating the subject.
16 DiagError
17
18 // DiagWarning indicates that the problem reported by a diagnostic warrants
19 // user attention but does not prevent further progress. It is most
20 // commonly used for showing deprecation notices.
21 DiagWarning
22)
23
24// Diagnostic represents information to be presented to a user about an
25// error or anomoly in parsing or evaluating configuration.
26type Diagnostic struct {
27 Severity DiagnosticSeverity
28
107c1cdb 29 // Summary and Detail contain the English-language description of the
15c0b25d
AP
30 // problem. Summary is a terse description of the general problem and
31 // detail is a more elaborate, often-multi-sentence description of
32 // the probem and what might be done to solve it.
33 Summary string
34 Detail string
107c1cdb
ND
35
36 // Subject and Context are both source ranges relating to the diagnostic.
37 //
38 // Subject is a tight range referring to exactly the construct that
39 // is problematic, while Context is an optional broader range (which should
40 // fully contain Subject) that ought to be shown around Subject when
41 // generating isolated source-code snippets in diagnostic messages.
42 // If Context is nil, the Subject is also the Context.
43 //
44 // Some diagnostics have no source ranges at all. If Context is set then
45 // Subject should always also be set.
15c0b25d
AP
46 Subject *Range
47 Context *Range
107c1cdb
ND
48
49 // For diagnostics that occur when evaluating an expression, Expression
50 // may refer to that expression and EvalContext may point to the
51 // EvalContext that was active when evaluating it. This may allow for the
52 // inclusion of additional useful information when rendering a diagnostic
53 // message to the user.
54 //
55 // It is not always possible to select a single EvalContext for a
56 // diagnostic, and so in some cases this field may be nil even when an
57 // expression causes a problem.
58 //
59 // EvalContexts form a tree, so the given EvalContext may refer to a parent
60 // which in turn refers to another parent, etc. For a full picture of all
61 // of the active variables and functions the caller must walk up this
62 // chain, preferring definitions that are "closer" to the expression in
63 // case of colliding names.
64 Expression Expression
65 EvalContext *EvalContext
15c0b25d
AP
66}
67
68// Diagnostics is a list of Diagnostic instances.
69type Diagnostics []*Diagnostic
70
71// error implementation, so that diagnostics can be returned via APIs
72// that normally deal in vanilla Go errors.
73//
74// This presents only minimal context about the error, for compatibility
75// with usual expectations about how errors will present as strings.
76func (d *Diagnostic) Error() string {
77 return fmt.Sprintf("%s: %s; %s", d.Subject, d.Summary, d.Detail)
78}
79
80// error implementation, so that sets of diagnostics can be returned via
81// APIs that normally deal in vanilla Go errors.
82func (d Diagnostics) Error() string {
83 count := len(d)
84 switch {
85 case count == 0:
86 return "no diagnostics"
87 case count == 1:
88 return d[0].Error()
89 default:
90 return fmt.Sprintf("%s, and %d other diagnostic(s)", d[0].Error(), count-1)
91 }
92}
93
94// Append appends a new error to a Diagnostics and return the whole Diagnostics.
95//
96// This is provided as a convenience for returning from a function that
97// collects and then returns a set of diagnostics:
98//
99// return nil, diags.Append(&hcl.Diagnostic{ ... })
100//
101// Note that this modifies the array underlying the diagnostics slice, so
102// must be used carefully within a single codepath. It is incorrect (and rude)
103// to extend a diagnostics created by a different subsystem.
104func (d Diagnostics) Append(diag *Diagnostic) Diagnostics {
105 return append(d, diag)
106}
107
108// Extend concatenates the given Diagnostics with the receiver and returns
109// the whole new Diagnostics.
110//
111// This is similar to Append but accepts multiple diagnostics to add. It has
112// all the same caveats and constraints.
113func (d Diagnostics) Extend(diags Diagnostics) Diagnostics {
114 return append(d, diags...)
115}
116
117// HasErrors returns true if the receiver contains any diagnostics of
118// severity DiagError.
119func (d Diagnostics) HasErrors() bool {
120 for _, diag := range d {
121 if diag.Severity == DiagError {
122 return true
123 }
124 }
125 return false
126}
127
107c1cdb
ND
128func (d Diagnostics) Errs() []error {
129 var errs []error
130 for _, diag := range d {
131 if diag.Severity == DiagError {
132 errs = append(errs, diag)
133 }
134 }
135
136 return errs
137}
138
15c0b25d
AP
139// A DiagnosticWriter emits diagnostics somehow.
140type DiagnosticWriter interface {
141 WriteDiagnostic(*Diagnostic) error
142 WriteDiagnostics(Diagnostics) error
143}