1/*
2Copyright 2015 The Kubernetes Authors.
3
4Licensed under the Apache License, Version 2.0 (the "License");
5you may not use this file except in compliance with the License.
6You may obtain a copy of the License at
7
8    http://www.apache.org/licenses/LICENSE-2.0
9
10Unless required by applicable law or agreed to in writing, software
11distributed under the License is distributed on an "AS IS" BASIS,
12WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13See the License for the specific language governing permissions and
14limitations under the License.
15*/
16
17package jsonpath
18
19import "fmt"
20
21// NodeType identifies the type of a parse tree node.
22type NodeType int
23
24// Type returns itself and provides an easy default implementation
25func (t NodeType) Type() NodeType {
26	return t
27}
28
29func (t NodeType) String() string {
30	return NodeTypeName[t]
31}
32
33const (
34	NodeText NodeType = iota
35	NodeArray
36	NodeList
37	NodeField
38	NodeIdentifier
39	NodeFilter
40	NodeInt
41	NodeFloat
42	NodeWildcard
43	NodeRecursive
44	NodeUnion
45	NodeBool
46)
47
48var NodeTypeName = map[NodeType]string{
49	NodeText:       "NodeText",
50	NodeArray:      "NodeArray",
51	NodeList:       "NodeList",
52	NodeField:      "NodeField",
53	NodeIdentifier: "NodeIdentifier",
54	NodeFilter:     "NodeFilter",
55	NodeInt:        "NodeInt",
56	NodeFloat:      "NodeFloat",
57	NodeWildcard:   "NodeWildcard",
58	NodeRecursive:  "NodeRecursive",
59	NodeUnion:      "NodeUnion",
60	NodeBool:       "NodeBool",
61}
62
63type Node interface {
64	Type() NodeType
65	String() string
66}
67
68// ListNode holds a sequence of nodes.
69type ListNode struct {
70	NodeType
71	Nodes []Node // The element nodes in lexical order.
72}
73
74func newList() *ListNode {
75	return &ListNode{NodeType: NodeList}
76}
77
78func (l *ListNode) append(n Node) {
79	l.Nodes = append(l.Nodes, n)
80}
81
82func (l *ListNode) String() string {
83	return l.Type().String()
84}
85
86// TextNode holds plain text.
87type TextNode struct {
88	NodeType
89	Text string // The text; may span newlines.
90}
91
92func newText(text string) *TextNode {
93	return &TextNode{NodeType: NodeText, Text: text}
94}
95
96func (t *TextNode) String() string {
97	return fmt.Sprintf("%s: %s", t.Type(), t.Text)
98}
99
100// FieldNode holds field of struct
101type FieldNode struct {
102	NodeType
103	Value string
104}
105
106func newField(value string) *FieldNode {
107	return &FieldNode{NodeType: NodeField, Value: value}
108}
109
110func (f *FieldNode) String() string {
111	return fmt.Sprintf("%s: %s", f.Type(), f.Value)
112}
113
114// IdentifierNode holds an identifier
115type IdentifierNode struct {
116	NodeType
117	Name string
118}
119
120func newIdentifier(value string) *IdentifierNode {
121	return &IdentifierNode{
122		NodeType: NodeIdentifier,
123		Name:     value,
124	}
125}
126
127func (f *IdentifierNode) String() string {
128	return fmt.Sprintf("%s: %s", f.Type(), f.Name)
129}
130
131// ParamsEntry holds param information for ArrayNode
132type ParamsEntry struct {
133	Value   int
134	Known   bool // whether the value is known when parse it
135	Derived bool
136}
137
138// ArrayNode holds start, end, step information for array index selection
139type ArrayNode struct {
140	NodeType
141	Params [3]ParamsEntry // start, end, step
142}
143
144func newArray(params [3]ParamsEntry) *ArrayNode {
145	return &ArrayNode{
146		NodeType: NodeArray,
147		Params:   params,
148	}
149}
150
151func (a *ArrayNode) String() string {
152	return fmt.Sprintf("%s: %v", a.Type(), a.Params)
153}
154
155// FilterNode holds operand and operator information for filter
156type FilterNode struct {
157	NodeType
158	Left     *ListNode
159	Right    *ListNode
160	Operator string
161}
162
163func newFilter(left, right *ListNode, operator string) *FilterNode {
164	return &FilterNode{
165		NodeType: NodeFilter,
166		Left:     left,
167		Right:    right,
168		Operator: operator,
169	}
170}
171
172func (f *FilterNode) String() string {
173	return fmt.Sprintf("%s: %s %s %s", f.Type(), f.Left, f.Operator, f.Right)
174}
175
176// IntNode holds integer value
177type IntNode struct {
178	NodeType
179	Value int
180}
181
182func newInt(num int) *IntNode {
183	return &IntNode{NodeType: NodeInt, Value: num}
184}
185
186func (i *IntNode) String() string {
187	return fmt.Sprintf("%s: %d", i.Type(), i.Value)
188}
189
190// FloatNode holds float value
191type FloatNode struct {
192	NodeType
193	Value float64
194}
195
196func newFloat(num float64) *FloatNode {
197	return &FloatNode{NodeType: NodeFloat, Value: num}
198}
199
200func (i *FloatNode) String() string {
201	return fmt.Sprintf("%s: %f", i.Type(), i.Value)
202}
203
204// WildcardNode means a wildcard
205type WildcardNode struct {
206	NodeType
207}
208
209func newWildcard() *WildcardNode {
210	return &WildcardNode{NodeType: NodeWildcard}
211}
212
213func (i *WildcardNode) String() string {
214	return i.Type().String()
215}
216
217// RecursiveNode means a recursive descent operator
218type RecursiveNode struct {
219	NodeType
220}
221
222func newRecursive() *RecursiveNode {
223	return &RecursiveNode{NodeType: NodeRecursive}
224}
225
226func (r *RecursiveNode) String() string {
227	return r.Type().String()
228}
229
230// UnionNode is union of ListNode
231type UnionNode struct {
232	NodeType
233	Nodes []*ListNode
234}
235
236func newUnion(nodes []*ListNode) *UnionNode {
237	return &UnionNode{NodeType: NodeUnion, Nodes: nodes}
238}
239
240func (u *UnionNode) String() string {
241	return u.Type().String()
242}
243
244// BoolNode holds bool value
245type BoolNode struct {
246	NodeType
247	Value bool
248}
249
250func newBool(value bool) *BoolNode {
251	return &BoolNode{NodeType: NodeBool, Value: value}
252}
253
254func (b *BoolNode) String() string {
255	return fmt.Sprintf("%s: %t", b.Type(), b.Value)
256}
257