|
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 } |