Path: blob/main/vendor/github.com/pelletier/go-toml/v2/unstable/ast.go
2893 views
package unstable12import (3"fmt"4"unsafe"56"github.com/pelletier/go-toml/v2/internal/danger"7)89// Iterator over a sequence of nodes.10//11// Starts uninitialized, you need to call Next() first.12//13// For example:14//15// it := n.Children()16// for it.Next() {17// n := it.Node()18// // do something with n19// }20type Iterator struct {21started bool22node *Node23}2425// Next moves the iterator forward and returns true if points to a26// node, false otherwise.27func (c *Iterator) Next() bool {28if !c.started {29c.started = true30} else if c.node.Valid() {31c.node = c.node.Next()32}33return c.node.Valid()34}3536// IsLast returns true if the current node of the iterator is the last37// one. Subsequent calls to Next() will return false.38func (c *Iterator) IsLast() bool {39return c.node.next == 040}4142// Node returns a pointer to the node pointed at by the iterator.43func (c *Iterator) Node() *Node {44return c.node45}4647// Node in a TOML expression AST.48//49// Depending on Kind, its sequence of children should be interpreted50// differently.51//52// - Array have one child per element in the array.53// - InlineTable have one child per key-value in the table (each of kind54// InlineTable).55// - KeyValue have at least two children. The first one is the value. The rest56// make a potentially dotted key.57// - Table and ArrayTable's children represent a dotted key (same as58// KeyValue, but without the first node being the value).59//60// When relevant, Raw describes the range of bytes this node is referring to in61// the input document. Use Parser.Raw() to retrieve the actual bytes.62type Node struct {63Kind Kind64Raw Range // Raw bytes from the input.65Data []byte // Node value (either allocated or referencing the input).6667// References to other nodes, as offsets in the backing array68// from this node. References can go backward, so those can be69// negative.70next int // 0 if last element71child int // 0 if no child72}7374// Range of bytes in the document.75type Range struct {76Offset uint3277Length uint3278}7980// Next returns a pointer to the next node, or nil if there is no next node.81func (n *Node) Next() *Node {82if n.next == 0 {83return nil84}85ptr := unsafe.Pointer(n)86size := unsafe.Sizeof(Node{})87return (*Node)(danger.Stride(ptr, size, n.next))88}8990// Child returns a pointer to the first child node of this node. Other children91// can be accessed calling Next on the first child. Returns an nil if this Node92// has no child.93func (n *Node) Child() *Node {94if n.child == 0 {95return nil96}97ptr := unsafe.Pointer(n)98size := unsafe.Sizeof(Node{})99return (*Node)(danger.Stride(ptr, size, n.child))100}101102// Valid returns true if the node's kind is set (not to Invalid).103func (n *Node) Valid() bool {104return n != nil105}106107// Key returns the children nodes making the Key on a supported node. Panics108// otherwise. They are guaranteed to be all be of the Kind Key. A simple key109// would return just one element.110func (n *Node) Key() Iterator {111switch n.Kind {112case KeyValue:113value := n.Child()114if !value.Valid() {115panic(fmt.Errorf("KeyValue should have at least two children"))116}117return Iterator{node: value.Next()}118case Table, ArrayTable:119return Iterator{node: n.Child()}120default:121panic(fmt.Errorf("Key() is not supported on a %s", n.Kind))122}123}124125// Value returns a pointer to the value node of a KeyValue.126// Guaranteed to be non-nil. Panics if not called on a KeyValue node,127// or if the Children are malformed.128func (n *Node) Value() *Node {129return n.Child()130}131132// Children returns an iterator over a node's children.133func (n *Node) Children() Iterator {134return Iterator{node: n.Child()}135}136137138