| /* |
| Copyright 2015 The Kubernetes Authors. |
| |
| Licensed under the Apache License, Version 2.0 (the "License"); |
| you may not use this file except in compliance with the License. |
| You may obtain a copy of the License at |
| |
| http://www.apache.org/licenses/LICENSE-2.0 |
| |
| Unless required by applicable law or agreed to in writing, software |
| distributed under the License is distributed on an "AS IS" BASIS, |
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| See the License for the specific language governing permissions and |
| limitations under the License. |
| */ |
| |
| package jsonpath |
| |
| import "fmt" |
| |
| // NodeType identifies the type of a parse tree node. |
| type NodeType int |
| |
| // Type returns itself and provides an easy default implementation |
| func (t NodeType) Type() NodeType { |
| return t |
| } |
| |
| func (t NodeType) String() string { |
| return NodeTypeName[t] |
| } |
| |
| const ( |
| NodeText NodeType = iota |
| NodeArray |
| NodeList |
| NodeField |
| NodeIdentifier |
| NodeFilter |
| NodeInt |
| NodeFloat |
| NodeWildcard |
| NodeRecursive |
| NodeUnion |
| NodeBool |
| ) |
| |
| var NodeTypeName = map[NodeType]string{ |
| NodeText: "NodeText", |
| NodeArray: "NodeArray", |
| NodeList: "NodeList", |
| NodeField: "NodeField", |
| NodeIdentifier: "NodeIdentifier", |
| NodeFilter: "NodeFilter", |
| NodeInt: "NodeInt", |
| NodeFloat: "NodeFloat", |
| NodeWildcard: "NodeWildcard", |
| NodeRecursive: "NodeRecursive", |
| NodeUnion: "NodeUnion", |
| NodeBool: "NodeBool", |
| } |
| |
| type Node interface { |
| Type() NodeType |
| String() string |
| } |
| |
| // ListNode holds a sequence of nodes. |
| type ListNode struct { |
| NodeType |
| Nodes []Node // The element nodes in lexical order. |
| } |
| |
| func newList() *ListNode { |
| return &ListNode{NodeType: NodeList} |
| } |
| |
| func (l *ListNode) append(n Node) { |
| l.Nodes = append(l.Nodes, n) |
| } |
| |
| func (l *ListNode) String() string { |
| return l.Type().String() |
| } |
| |
| // TextNode holds plain text. |
| type TextNode struct { |
| NodeType |
| Text string // The text; may span newlines. |
| } |
| |
| func newText(text string) *TextNode { |
| return &TextNode{NodeType: NodeText, Text: text} |
| } |
| |
| func (t *TextNode) String() string { |
| return fmt.Sprintf("%s: %s", t.Type(), t.Text) |
| } |
| |
| // FieldNode holds field of struct |
| type FieldNode struct { |
| NodeType |
| Value string |
| } |
| |
| func newField(value string) *FieldNode { |
| return &FieldNode{NodeType: NodeField, Value: value} |
| } |
| |
| func (f *FieldNode) String() string { |
| return fmt.Sprintf("%s: %s", f.Type(), f.Value) |
| } |
| |
| // IdentifierNode holds an identifier |
| type IdentifierNode struct { |
| NodeType |
| Name string |
| } |
| |
| func newIdentifier(value string) *IdentifierNode { |
| return &IdentifierNode{ |
| NodeType: NodeIdentifier, |
| Name: value, |
| } |
| } |
| |
| func (f *IdentifierNode) String() string { |
| return fmt.Sprintf("%s: %s", f.Type(), f.Name) |
| } |
| |
| // ParamsEntry holds param information for ArrayNode |
| type ParamsEntry struct { |
| Value int |
| Known bool // whether the value is known when parse it |
| } |
| |
| // ArrayNode holds start, end, step information for array index selection |
| type ArrayNode struct { |
| NodeType |
| Params [3]ParamsEntry // start, end, step |
| } |
| |
| func newArray(params [3]ParamsEntry) *ArrayNode { |
| return &ArrayNode{ |
| NodeType: NodeArray, |
| Params: params, |
| } |
| } |
| |
| func (a *ArrayNode) String() string { |
| return fmt.Sprintf("%s: %v", a.Type(), a.Params) |
| } |
| |
| // FilterNode holds operand and operator information for filter |
| type FilterNode struct { |
| NodeType |
| Left *ListNode |
| Right *ListNode |
| Operator string |
| } |
| |
| func newFilter(left, right *ListNode, operator string) *FilterNode { |
| return &FilterNode{ |
| NodeType: NodeFilter, |
| Left: left, |
| Right: right, |
| Operator: operator, |
| } |
| } |
| |
| func (f *FilterNode) String() string { |
| return fmt.Sprintf("%s: %s %s %s", f.Type(), f.Left, f.Operator, f.Right) |
| } |
| |
| // IntNode holds integer value |
| type IntNode struct { |
| NodeType |
| Value int |
| } |
| |
| func newInt(num int) *IntNode { |
| return &IntNode{NodeType: NodeInt, Value: num} |
| } |
| |
| func (i *IntNode) String() string { |
| return fmt.Sprintf("%s: %d", i.Type(), i.Value) |
| } |
| |
| // FloatNode holds float value |
| type FloatNode struct { |
| NodeType |
| Value float64 |
| } |
| |
| func newFloat(num float64) *FloatNode { |
| return &FloatNode{NodeType: NodeFloat, Value: num} |
| } |
| |
| func (i *FloatNode) String() string { |
| return fmt.Sprintf("%s: %f", i.Type(), i.Value) |
| } |
| |
| // WildcardNode means a wildcard |
| type WildcardNode struct { |
| NodeType |
| } |
| |
| func newWildcard() *WildcardNode { |
| return &WildcardNode{NodeType: NodeWildcard} |
| } |
| |
| func (i *WildcardNode) String() string { |
| return i.Type().String() |
| } |
| |
| // RecursiveNode means a recursive descent operator |
| type RecursiveNode struct { |
| NodeType |
| } |
| |
| func newRecursive() *RecursiveNode { |
| return &RecursiveNode{NodeType: NodeRecursive} |
| } |
| |
| func (r *RecursiveNode) String() string { |
| return r.Type().String() |
| } |
| |
| // UnionNode is union of ListNode |
| type UnionNode struct { |
| NodeType |
| Nodes []*ListNode |
| } |
| |
| func newUnion(nodes []*ListNode) *UnionNode { |
| return &UnionNode{NodeType: NodeUnion, Nodes: nodes} |
| } |
| |
| func (u *UnionNode) String() string { |
| return u.Type().String() |
| } |
| |
| // BoolNode holds bool value |
| type BoolNode struct { |
| NodeType |
| Value bool |
| } |
| |
| func newBool(value bool) *BoolNode { |
| return &BoolNode{NodeType: NodeBool, Value: value} |
| } |
| |
| func (b *BoolNode) String() string { |
| return fmt.Sprintf("%s: %t", b.Type(), b.Value) |
| } |