Files
go-toml/strict.go
T
Cursor Agent 96ac48eb74 Remove optional offset and fallback, guarantee offset by construction
ParserError.Offset is now a plain exported int field, always set:
- The parser sets it via setErrOffset() when capturing parse errors
- strict.go sets it from the key's Raw range at construction
- wrapDecodeError computes it inline from cap(document) - cap(highlight)

This eliminates:
- The SetOffset/Offset() accessor methods and offsetValid flag
- The subsliceOffset fallback function in errors.go
- Any conditional logic around whether the offset is present

The offset is guaranteed by construction at every path that creates
or consumes a ParserError.

Co-authored-by: Thomas Pelletier <thomas@pelletier.dev>
2026-04-12 17:25:32 +00:00

117 lines
2.0 KiB
Go

package toml
import (
"github.com/pelletier/go-toml/v2/internal/tracker"
"github.com/pelletier/go-toml/v2/unstable"
)
type strict struct {
Enabled bool
// Tracks the current key being processed.
key tracker.KeyTracker
missing []unstable.ParserError
// Reference to the document for computing key ranges.
doc []byte
}
func (s *strict) EnterTable(node *unstable.Node) {
if !s.Enabled {
return
}
s.key.UpdateTable(node)
}
func (s *strict) EnterArrayTable(node *unstable.Node) {
if !s.Enabled {
return
}
s.key.UpdateArrayTable(node)
}
func (s *strict) EnterKeyValue(node *unstable.Node) {
if !s.Enabled {
return
}
s.key.Push(node)
}
func (s *strict) ExitKeyValue(node *unstable.Node) {
if !s.Enabled {
return
}
s.key.Pop(node)
}
func (s *strict) MissingTable(node *unstable.Node) {
if !s.Enabled {
return
}
highlight, offset := s.keyLocation(node)
s.missing = append(s.missing, unstable.ParserError{
Highlight: highlight,
Message: "missing table",
Key: s.key.Key(),
Offset: offset,
})
}
func (s *strict) MissingField(node *unstable.Node) {
if !s.Enabled {
return
}
highlight, offset := s.keyLocation(node)
s.missing = append(s.missing, unstable.ParserError{
Highlight: highlight,
Message: "missing field",
Key: s.key.Key(),
Offset: offset,
})
}
func (s *strict) Error(doc []byte) error {
if !s.Enabled || len(s.missing) == 0 {
return nil
}
err := &StrictMissingError{
Errors: make([]DecodeError, 0, len(s.missing)),
}
for _, derr := range s.missing {
derr := derr
err.Errors = append(err.Errors, *wrapDecodeError(doc, &derr))
}
return err
}
func (s *strict) keyLocation(node *unstable.Node) ([]byte, int) {
k := node.Key()
hasOne := k.Next()
if !hasOne {
panic("should not be called with empty key")
}
firstRaw := k.Node().Raw
lastRaw := firstRaw
for k.Next() {
lastRaw = k.Node().Raw
}
start := firstRaw.Offset
end := lastRaw.Offset + lastRaw.Length
return s.doc[start:end], int(start)
}