aboutsummaryrefslogtreecommitdiffhomepage
path: root/vendor/github.com/hashicorp/hcl2/hcl/hclsyntax/parser_traversal.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/hashicorp/hcl2/hcl/hclsyntax/parser_traversal.go')
-rw-r--r--vendor/github.com/hashicorp/hcl2/hcl/hclsyntax/parser_traversal.go159
1 files changed, 159 insertions, 0 deletions
diff --git a/vendor/github.com/hashicorp/hcl2/hcl/hclsyntax/parser_traversal.go b/vendor/github.com/hashicorp/hcl2/hcl/hclsyntax/parser_traversal.go
new file mode 100644
index 0000000..2ff3ed6
--- /dev/null
+++ b/vendor/github.com/hashicorp/hcl2/hcl/hclsyntax/parser_traversal.go
@@ -0,0 +1,159 @@
1package hclsyntax
2
3import (
4 "github.com/hashicorp/hcl2/hcl"
5 "github.com/zclconf/go-cty/cty"
6)
7
8// ParseTraversalAbs parses an absolute traversal that is assumed to consume
9// all of the remaining tokens in the peeker. The usual parser recovery
10// behavior is not supported here because traversals are not expected to
11// be parsed as part of a larger program.
12func (p *parser) ParseTraversalAbs() (hcl.Traversal, hcl.Diagnostics) {
13 var ret hcl.Traversal
14 var diags hcl.Diagnostics
15
16 // Absolute traversal must always begin with a variable name
17 varTok := p.Read()
18 if varTok.Type != TokenIdent {
19 diags = append(diags, &hcl.Diagnostic{
20 Severity: hcl.DiagError,
21 Summary: "Variable name required",
22 Detail: "Must begin with a variable name.",
23 Subject: &varTok.Range,
24 })
25 return ret, diags
26 }
27
28 varName := string(varTok.Bytes)
29 ret = append(ret, hcl.TraverseRoot{
30 Name: varName,
31 SrcRange: varTok.Range,
32 })
33
34 for {
35 next := p.Peek()
36
37 if next.Type == TokenEOF {
38 return ret, diags
39 }
40
41 switch next.Type {
42 case TokenDot:
43 // Attribute access
44 dot := p.Read() // eat dot
45 nameTok := p.Read()
46 if nameTok.Type != TokenIdent {
47 if nameTok.Type == TokenStar {
48 diags = append(diags, &hcl.Diagnostic{
49 Severity: hcl.DiagError,
50 Summary: "Attribute name required",
51 Detail: "Splat expressions (.*) may not be used here.",
52 Subject: &nameTok.Range,
53 Context: hcl.RangeBetween(varTok.Range, nameTok.Range).Ptr(),
54 })
55 } else {
56 diags = append(diags, &hcl.Diagnostic{
57 Severity: hcl.DiagError,
58 Summary: "Attribute name required",
59 Detail: "Dot must be followed by attribute name.",
60 Subject: &nameTok.Range,
61 Context: hcl.RangeBetween(varTok.Range, nameTok.Range).Ptr(),
62 })
63 }
64 return ret, diags
65 }
66
67 attrName := string(nameTok.Bytes)
68 ret = append(ret, hcl.TraverseAttr{
69 Name: attrName,
70 SrcRange: hcl.RangeBetween(dot.Range, nameTok.Range),
71 })
72 case TokenOBrack:
73 // Index
74 open := p.Read() // eat open bracket
75 next := p.Peek()
76
77 switch next.Type {
78 case TokenNumberLit:
79 tok := p.Read() // eat number
80 numVal, numDiags := p.numberLitValue(tok)
81 diags = append(diags, numDiags...)
82
83 close := p.Read()
84 if close.Type != TokenCBrack {
85 diags = append(diags, &hcl.Diagnostic{
86 Severity: hcl.DiagError,
87 Summary: "Unclosed index brackets",
88 Detail: "Index key must be followed by a closing bracket.",
89 Subject: &close.Range,
90 Context: hcl.RangeBetween(open.Range, close.Range).Ptr(),
91 })
92 }
93
94 ret = append(ret, hcl.TraverseIndex{
95 Key: numVal,
96 SrcRange: hcl.RangeBetween(open.Range, close.Range),
97 })
98
99 if diags.HasErrors() {
100 return ret, diags
101 }
102
103 case TokenOQuote:
104 str, _, strDiags := p.parseQuotedStringLiteral()
105 diags = append(diags, strDiags...)
106
107 close := p.Read()
108 if close.Type != TokenCBrack {
109 diags = append(diags, &hcl.Diagnostic{
110 Severity: hcl.DiagError,
111 Summary: "Unclosed index brackets",
112 Detail: "Index key must be followed by a closing bracket.",
113 Subject: &close.Range,
114 Context: hcl.RangeBetween(open.Range, close.Range).Ptr(),
115 })
116 }
117
118 ret = append(ret, hcl.TraverseIndex{
119 Key: cty.StringVal(str),
120 SrcRange: hcl.RangeBetween(open.Range, close.Range),
121 })
122
123 if diags.HasErrors() {
124 return ret, diags
125 }
126
127 default:
128 if next.Type == TokenStar {
129 diags = append(diags, &hcl.Diagnostic{
130 Severity: hcl.DiagError,
131 Summary: "Attribute name required",
132 Detail: "Splat expressions ([*]) may not be used here.",
133 Subject: &next.Range,
134 Context: hcl.RangeBetween(varTok.Range, next.Range).Ptr(),
135 })
136 } else {
137 diags = append(diags, &hcl.Diagnostic{
138 Severity: hcl.DiagError,
139 Summary: "Index value required",
140 Detail: "Index brackets must contain either a literal number or a literal string.",
141 Subject: &next.Range,
142 Context: hcl.RangeBetween(varTok.Range, next.Range).Ptr(),
143 })
144 }
145 return ret, diags
146 }
147
148 default:
149 diags = append(diags, &hcl.Diagnostic{
150 Severity: hcl.DiagError,
151 Summary: "Invalid character",
152 Detail: "Expected an attribute access or an index operator.",
153 Subject: &next.Range,
154 Context: hcl.RangeBetween(varTok.Range, next.Range).Ptr(),
155 })
156 return ret, diags
157 }
158 }
159}