gtsocial-umbx

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

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 }