cloudflare/pint

Public

mirrored from https://github.com/cloudflare/pintAvailable

CodeCommitsIssuesPull requestsActionsInsightsSecurity
764db704502bdd64d8b436fb6830458da0be0ffd

Branches

Tags

  • No tags available.
0Branches0Tags
Go to file
Add file
Code

Clone

HTTPS

Download ZIP

internal/parser/models.go

277lines · modecode

1package parser
2
3import (
4 "strings"
5
6 "gopkg.in/yaml.v3"
7
8 promparser "github.com/prometheus/prometheus/promql/parser"
9)
10
11func appendLine(lines []int, newLines ...int) []int {
12 for _, nl := range newLines {
13 var present bool
14 for _, l := range lines {
15 if l == nl {
16 present = true
17 break
18 }
19 }
20 if !present {
21 lines = append(lines, nl)
22 }
23 }
24
25 return lines
26}
27
28func nodeLines(node *yaml.Node) (lines []int) {
29 lineCount := len(strings.Split(strings.TrimSuffix(node.Value, "\n"), "\n"))
30
31 var firstLine int
32 switch node.Style {
33 case yaml.LiteralStyle, yaml.FoldedStyle:
34 firstLine = node.Line + 1
35 default:
36 firstLine = node.Line
37 }
38
39 for i := 0; i < lineCount; i++ {
40 lines = appendLine(lines, firstLine+i)
41 }
42
43 return lines
44}
45
46func NewFilePosition(l []int) FilePosition {
47 return FilePosition{Lines: l}
48}
49
50type FilePosition struct {
51 Lines []int
52}
53
54func (fp FilePosition) FistLine() (line int) {
55 for _, l := range fp.Lines {
56 if line == 0 || l < line {
57 line = l
58 }
59 }
60 return
61}
62
63func (fp FilePosition) LastLine() (line int) {
64 for _, l := range fp.Lines {
65 if l > line {
66 line = l
67 }
68 }
69 return
70}
71
72type YamlNode struct {
73 Position FilePosition
74 Value string
75}
76
77func newYamlNode(node *yaml.Node) *YamlNode {
78 return &YamlNode{
79 Position: NewFilePosition(nodeLines(node)),
80 Value: node.Value,
81 }
82}
83
84func newYamlNodeWithParent(parent, node *yaml.Node) *YamlNode {
85 return &YamlNode{
86 Position: NewFilePosition(nodeLines(node)),
87 Value: node.Value,
88 }
89}
90
91func newYamlKeyValue(key, val *yaml.Node) *YamlKeyValue {
92 return &YamlKeyValue{
93 Key: newYamlNode(key),
94 Value: newYamlNodeWithParent(key, val),
95 }
96}
97
98type YamlKeyValue struct {
99 Key *YamlNode
100 Value *YamlNode
101}
102
103func (ykv YamlKeyValue) Lines() (lines []int) {
104 lines = appendLine(lines, ykv.Key.Position.Lines...)
105 lines = appendLine(lines, ykv.Value.Position.Lines...)
106 return
107}
108
109type YamlMap struct {
110 Key *YamlNode
111 Items []*YamlKeyValue
112}
113
114func (ym YamlMap) Lines() (lines []int) {
115 lines = appendLine(lines, ym.Key.Position.Lines...)
116 for _, item := range ym.Items {
117 lines = appendLine(lines, item.Lines()...)
118 }
119 return
120}
121
122func (ym YamlMap) GetValue(key string) *YamlNode {
123 for _, child := range ym.Items {
124 if child.Key.Value == key {
125 return child.Value
126 }
127 }
128 return nil
129}
130
131func newYamlMap(key, value *yaml.Node) *YamlMap {
132 ym := YamlMap{
133 Key: newYamlNode(key),
134 }
135
136 var ckey *yaml.Node
137 for _, child := range value.Content {
138 if ckey != nil {
139 kv := YamlKeyValue{
140 Key: newYamlNode(ckey),
141 Value: newYamlNode(child),
142 }
143 ym.Items = append(ym.Items, &kv)
144 ckey = nil
145 } else {
146 ckey = child
147 }
148 }
149
150 return &ym
151}
152
153type PromQLNode struct {
154 Expr string
155 Node promparser.Expr
156 Children []*PromQLNode
157}
158
159type PromQLError struct {
160 node *PromQLNode
161 Err error
162}
163
164func (pqle PromQLError) Error() string {
165 return pqle.Err.Error()
166}
167
168func (pqle *PromQLError) Unwrap() error {
169 return pqle.Err
170}
171
172func (pqle PromQLError) Node() *PromQLNode {
173 return pqle.node
174}
175
176type PromQLExpr struct {
177 Key *YamlNode
178 Value *YamlNode
179 SyntaxError error
180 Query *PromQLNode
181}
182
183func (pqle PromQLExpr) Lines() (lines []int) {
184 lines = appendLine(lines, pqle.Key.Position.Lines...)
185 lines = appendLine(lines, pqle.Value.Position.Lines...)
186 return
187}
188
189func newPromQLExpr(key, val *yaml.Node) *PromQLExpr {
190 expr := PromQLExpr{
191 Key: newYamlNode(key),
192 Value: newYamlNodeWithParent(key, val),
193 }
194
195 qlNode, err := decodeExpr(val.Value)
196 if err != nil {
197 expr.SyntaxError = err
198 return &expr
199
200 }
201 expr.Query = qlNode
202 return &expr
203}
204
205type AlertingRule struct {
206 Alert YamlKeyValue
207 Expr PromQLExpr
208 For *YamlKeyValue
209 Labels *YamlMap
210 Annotations *YamlMap
211}
212
213func (ar AlertingRule) Lines() (lines []int) {
214 lines = appendLine(lines, ar.Alert.Lines()...)
215 lines = appendLine(lines, ar.Expr.Lines()...)
216 if ar.For != nil {
217 lines = appendLine(lines, ar.For.Lines()...)
218 }
219 if ar.Labels != nil {
220 lines = appendLine(lines, ar.Labels.Lines()...)
221 }
222 if ar.Annotations != nil {
223 lines = appendLine(lines, ar.Annotations.Lines()...)
224 }
225 return
226}
227
228type RecordingRule struct {
229 Record YamlKeyValue
230 Expr PromQLExpr
231 Labels *YamlMap
232}
233
234func (rr RecordingRule) Lines() (lines []int) {
235 lines = appendLine(lines, rr.Record.Lines()...)
236 lines = appendLine(lines, rr.Expr.Lines()...)
237 if rr.Labels != nil {
238 lines = appendLine(lines, rr.Labels.Lines()...)
239 }
240 return
241}
242
243type ParseError struct {
244 Fragment string
245 Err error
246 Line int
247}
248
249type Rule struct {
250 AlertingRule *AlertingRule
251 RecordingRule *RecordingRule
252 Error ParseError
253}
254
255func (r Rule) Expr() PromQLExpr {
256 if r.RecordingRule != nil {
257 return r.RecordingRule.Expr
258 }
259 return r.AlertingRule.Expr
260}
261
262func (r Rule) Lines() []int {
263 if r.RecordingRule != nil {
264 return r.RecordingRule.Lines()
265 }
266 if r.AlertingRule != nil {
267 return r.AlertingRule.Lines()
268 }
269 return []int{r.Error.Line}
270}
271
272type Result struct {
273 Path string
274 Error error
275 Content []byte
276 Rules []Rule
277}