vendor/github.com/pelletier/go-toml/v2/internal/ast/ast.go
changeset 260 445e01aede7e
equal deleted inserted replaced
259:db4911b0c721 260:445e01aede7e
       
     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 }