]> git.immae.eu Git - github/fretlink/terraform-provider-statuscake.git/blob - 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
1 package hcl
2
3 import (
4 "fmt"
5 )
6
7 // DiagnosticSeverity represents the severity of a diagnostic.
8 type DiagnosticSeverity int
9
10 const (
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.
26 type Diagnostic struct {
27 Severity DiagnosticSeverity
28
29 // Summary and Detail contain the English-language description of the
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
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.
46 Subject *Range
47 Context *Range
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
66 }
67
68 // Diagnostics is a list of Diagnostic instances.
69 type 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.
76 func (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.
82 func (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.
104 func (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.
113 func (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.
119 func (d Diagnostics) HasErrors() bool {
120 for _, diag := range d {
121 if diag.Severity == DiagError {
122 return true
123 }
124 }
125 return false
126 }
127
128 func (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
139 // A DiagnosticWriter emits diagnostics somehow.
140 type DiagnosticWriter interface {
141 WriteDiagnostic(*Diagnostic) error
142 WriteDiagnostics(Diagnostics) error
143 }