260
|
1 |
package ast |
|
2 |
|
|
3 |
import ( |
|
4 |
"fmt" |
|
5 |
"unsafe" |
|
6 |
|
|
7 |
"github.com/pelletier/go-toml/v2/internal/danger" |
|
8 |
) |
|
9 |
|
|
10 |
// Iterator starts uninitialized, you need to call Next() first. |
|
11 |
// |
|
12 |
// For example: |
|
13 |
// |
|
14 |
// it := n.Children() |
|
15 |
// for it.Next() { |
|
16 |
// it.Node() |
|
17 |
// } |
|
18 |
type Iterator struct { |
|
19 |
started bool |
|
20 |
node *Node |
|
21 |
} |
|
22 |
|
|
23 |
// Next moves the iterator forward and returns true if points to a |
|
24 |
// node, false otherwise. |
|
25 |
func (c *Iterator) Next() bool { |
|
26 |
if !c.started { |
|
27 |
c.started = true |
|
28 |
} else if c.node.Valid() { |
|
29 |
c.node = c.node.Next() |
|
30 |
} |
|
31 |
return c.node.Valid() |
|
32 |
} |
|
33 |
|
|
34 |
// IsLast returns true if the current node of the iterator is the last |
|
35 |
// one. Subsequent call to Next() will return false. |
|
36 |
func (c *Iterator) IsLast() bool { |
|
37 |
return c.node.next == 0 |
|
38 |
} |
|
39 |
|
|
40 |
// Node returns a copy of the node pointed at by the iterator. |
|
41 |
func (c *Iterator) Node() *Node { |
|
42 |
return c.node |
|
43 |
} |
|
44 |
|
|
45 |
// Root contains a full AST. |
|
46 |
// |
|
47 |
// It is immutable once constructed with Builder. |
|
48 |
type Root struct { |
|
49 |
nodes []Node |
|
50 |
} |
|
51 |
|
|
52 |
// Iterator over the top level nodes. |
|
53 |
func (r *Root) Iterator() Iterator { |
|
54 |
it := Iterator{} |
|
55 |
if len(r.nodes) > 0 { |
|
56 |
it.node = &r.nodes[0] |
|
57 |
} |
|
58 |
return it |
|
59 |
} |
|
60 |
|
|
61 |
func (r *Root) at(idx Reference) *Node { |
|
62 |
return &r.nodes[idx] |
|
63 |
} |
|
64 |
|
|
65 |
// Arrays have one child per element in the array. InlineTables have |
|
66 |
// one child per key-value pair in the table. KeyValues have at least |
|
67 |
// two children. The first one is the value. The rest make a |
|
68 |
// potentially dotted key. Table and Array table have one child per |
|
69 |
// element of the key they represent (same as KeyValue, but without |
|
70 |
// the last node being the value). |
|
71 |
type Node struct { |
|
72 |
Kind Kind |
|
73 |
Raw Range // Raw bytes from the input. |
|
74 |
Data []byte // Node value (either allocated or referencing the input). |
|
75 |
|
|
76 |
// References to other nodes, as offsets in the backing array |
|
77 |
// from this node. References can go backward, so those can be |
|
78 |
// negative. |
|
79 |
next int // 0 if last element |
|
80 |
child int // 0 if no child |
|
81 |
} |
|
82 |
|
|
83 |
type Range struct { |
|
84 |
Offset uint32 |
|
85 |
Length uint32 |
|
86 |
} |
|
87 |
|
|
88 |
// Next returns a copy of the next node, or an invalid Node if there |
|
89 |
// is no next node. |
|
90 |
func (n *Node) Next() *Node { |
|
91 |
if n.next == 0 { |
|
92 |
return nil |
|
93 |
} |
|
94 |
ptr := unsafe.Pointer(n) |
|
95 |
size := unsafe.Sizeof(Node{}) |
|
96 |
return (*Node)(danger.Stride(ptr, size, n.next)) |
|
97 |
} |
|
98 |
|
|
99 |
// Child returns a copy of the first child node of this node. Other |
|
100 |
// children can be accessed calling Next on the first child. Returns |
|
101 |
// an invalid Node if there is none. |
|
102 |
func (n *Node) Child() *Node { |
|
103 |
if n.child == 0 { |
|
104 |
return nil |
|
105 |
} |
|
106 |
ptr := unsafe.Pointer(n) |
|
107 |
size := unsafe.Sizeof(Node{}) |
|
108 |
return (*Node)(danger.Stride(ptr, size, n.child)) |
|
109 |
} |
|
110 |
|
|
111 |
// Valid returns true if the node's kind is set (not to Invalid). |
|
112 |
func (n *Node) Valid() bool { |
|
113 |
return n != nil |
|
114 |
} |
|
115 |
|
|
116 |
// Key returns the child nodes making the Key on a supported |
|
117 |
// node. Panics otherwise. They are guaranteed to be all be of the |
|
118 |
// Kind Key. A simple key would return just one element. |
|
119 |
func (n *Node) Key() Iterator { |
|
120 |
switch n.Kind { |
|
121 |
case KeyValue: |
|
122 |
value := n.Child() |
|
123 |
if !value.Valid() { |
|
124 |
panic(fmt.Errorf("KeyValue should have at least two children")) |
|
125 |
} |
|
126 |
return Iterator{node: value.Next()} |
|
127 |
case Table, ArrayTable: |
|
128 |
return Iterator{node: n.Child()} |
|
129 |
default: |
|
130 |
panic(fmt.Errorf("Key() is not supported on a %s", n.Kind)) |
|
131 |
} |
|
132 |
} |
|
133 |
|
|
134 |
// Value returns a pointer to the value node of a KeyValue. |
|
135 |
// Guaranteed to be non-nil. Panics if not called on a KeyValue node, |
|
136 |
// or if the Children are malformed. |
|
137 |
func (n *Node) Value() *Node { |
|
138 |
return n.Child() |
|
139 |
} |
|
140 |
|
|
141 |
// Children returns an iterator over a node's children. |
|
142 |
func (n *Node) Children() Iterator { |
|
143 |
return Iterator{node: n.Child()} |
|
144 |
} |