vendor/github.com/pelletier/go-toml/v2/internal/ast/ast.go
author Mikael Berthe <mikael@lilotux.net>
Tue, 23 Aug 2022 22:39:43 +0200
changeset 260 445e01aede7e
permissions -rw-r--r--
Update vendor directory
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
260
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
     1
package ast
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
     2
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
     3
import (
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
     4
	"fmt"
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
     5
	"unsafe"
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
     6
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
     7
	"github.com/pelletier/go-toml/v2/internal/danger"
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
     8
)
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
     9
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    10
// Iterator starts uninitialized, you need to call Next() first.
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    11
//
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    12
// For example:
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    13
//
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    14
//	it := n.Children()
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    15
//	for it.Next() {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    16
//			it.Node()
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    17
//	}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    18
type Iterator struct {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    19
	started bool
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    20
	node    *Node
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    21
}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    22
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    23
// Next moves the iterator forward and returns true if points to a
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    24
// node, false otherwise.
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    25
func (c *Iterator) Next() bool {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    26
	if !c.started {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    27
		c.started = true
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    28
	} else if c.node.Valid() {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    29
		c.node = c.node.Next()
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    30
	}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    31
	return c.node.Valid()
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    32
}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    33
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    34
// IsLast returns true if the current node of the iterator is the last
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    35
// one.  Subsequent call to Next() will return false.
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    36
func (c *Iterator) IsLast() bool {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    37
	return c.node.next == 0
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    38
}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    39
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    40
// Node returns a copy of the node pointed at by the iterator.
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    41
func (c *Iterator) Node() *Node {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    42
	return c.node
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    43
}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    44
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    45
// Root contains a full AST.
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    46
//
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    47
// It is immutable once constructed with Builder.
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    48
type Root struct {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    49
	nodes []Node
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    50
}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    51
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    52
// Iterator over the top level nodes.
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    53
func (r *Root) Iterator() Iterator {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    54
	it := Iterator{}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    55
	if len(r.nodes) > 0 {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    56
		it.node = &r.nodes[0]
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    57
	}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    58
	return it
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    59
}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    60
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    61
func (r *Root) at(idx Reference) *Node {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    62
	return &r.nodes[idx]
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    63
}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    64
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    65
// Arrays have one child per element in the array.  InlineTables have
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    66
// one child per key-value pair in the table.  KeyValues have at least
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    67
// two children. The first one is the value. The rest make a
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    68
// potentially dotted key.  Table and Array table have one child per
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    69
// element of the key they represent (same as KeyValue, but without
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    70
// the last node being the value).
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    71
type Node struct {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    72
	Kind Kind
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    73
	Raw  Range  // Raw bytes from the input.
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    74
	Data []byte // Node value (either allocated or referencing the input).
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    75
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    76
	// References to other nodes, as offsets in the backing array
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    77
	// from this node. References can go backward, so those can be
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    78
	// negative.
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    79
	next  int // 0 if last element
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    80
	child int // 0 if no child
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    81
}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    82
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    83
type Range struct {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    84
	Offset uint32
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    85
	Length uint32
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    86
}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    87
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    88
// Next returns a copy of the next node, or an invalid Node if there
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    89
// is no next node.
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    90
func (n *Node) Next() *Node {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    91
	if n.next == 0 {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    92
		return nil
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    93
	}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    94
	ptr := unsafe.Pointer(n)
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    95
	size := unsafe.Sizeof(Node{})
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    96
	return (*Node)(danger.Stride(ptr, size, n.next))
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    97
}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    98
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    99
// Child returns a copy of the first child node of this node. Other
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   100
// children can be accessed calling Next on the first child.  Returns
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   101
// an invalid Node if there is none.
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   102
func (n *Node) Child() *Node {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   103
	if n.child == 0 {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   104
		return nil
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   105
	}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   106
	ptr := unsafe.Pointer(n)
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   107
	size := unsafe.Sizeof(Node{})
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   108
	return (*Node)(danger.Stride(ptr, size, n.child))
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   109
}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   110
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   111
// Valid returns true if the node's kind is set (not to Invalid).
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   112
func (n *Node) Valid() bool {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   113
	return n != nil
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   114
}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   115
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   116
// Key returns the child nodes making the Key on a supported
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   117
// node. Panics otherwise.  They are guaranteed to be all be of the
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   118
// Kind Key. A simple key would return just one element.
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   119
func (n *Node) Key() Iterator {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   120
	switch n.Kind {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   121
	case KeyValue:
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   122
		value := n.Child()
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   123
		if !value.Valid() {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   124
			panic(fmt.Errorf("KeyValue should have at least two children"))
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   125
		}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   126
		return Iterator{node: value.Next()}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   127
	case Table, ArrayTable:
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   128
		return Iterator{node: n.Child()}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   129
	default:
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   130
		panic(fmt.Errorf("Key() is not supported on a %s", n.Kind))
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   131
	}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   132
}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   133
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   134
// Value returns a pointer to the value node of a KeyValue.
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   135
// Guaranteed to be non-nil.  Panics if not called on a KeyValue node,
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   136
// or if the Children are malformed.
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   137
func (n *Node) Value() *Node {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   138
	return n.Child()
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   139
}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   140
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   141
// Children returns an iterator over a node's children.
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   142
func (n *Node) Children() Iterator {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   143
	return Iterator{node: n.Child()}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   144
}