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