// Copyright 2022 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Package safetoken provides wrappers around methods in go/token,
// that return errors rather than panicking.
//
// It also provides a central place for workarounds in the underlying
// packages. The use of this package's functions instead of methods of
// token.File (such as Offset, Position, and PositionFor) is mandatory
// throughout the gopls codebase and enforced by a static check.
package safetoken

import (
	"fmt"
	"go/token"
)

// Offset returns f.Offset(pos), but first checks that the file
// contains the pos.
//
// The definition of "contains" here differs from that of token.File
// in order to work around a bug in the parser (issue #57490): during
// error recovery, the parser may create syntax nodes whose computed
// End position is 1 byte beyond EOF, which would cause
// token.File.Offset to panic. The workaround is that this function
// accepts a Pos that is exactly 1 byte beyond EOF and maps it to the
// EOF offset.
func Offset(f *token.File, pos token.Pos) (int, error) {
	if !inRange(f, pos) {
		// Accept a Pos that is 1 byte beyond EOF,
		// and map it to the EOF offset.
		// (Workaround for #57490.)
		if int(pos) == f.Base()+f.Size()+1 {
			return f.Size(), nil
		}

		return -1, fmt.Errorf("pos %d is not in range [%d:%d] of file %s",
			pos, f.Base(), f.Base()+f.Size(), f.Name())
	}
	return int(pos) - f.Base(), nil
}

// Offsets returns Offset(start) and Offset(end).
func Offsets(f *token.File, start, end token.Pos) (int, int, error) {
	startOffset, err := Offset(f, start)
	if err != nil {
		return 0, 0, fmt.Errorf("start: %v", err)
	}
	endOffset, err := Offset(f, end)
	if err != nil {
		return 0, 0, fmt.Errorf("end: %v", err)
	}
	return startOffset, endOffset, nil
}

// Pos returns f.Pos(offset), but first checks that the offset is
// non-negative and not larger than the size of the file.
func Pos(f *token.File, offset int) (token.Pos, error) {
	if !(0 <= offset && offset <= f.Size()) {
		return token.NoPos, fmt.Errorf("offset %d is not in range for file %s of size %d", offset, f.Name(), f.Size())
	}
	return token.Pos(f.Base() + offset), nil
}

// inRange reports whether file f contains position pos,
// according to the invariants of token.File.
//
// This function is not public because of the ambiguity it would
// create w.r.t. the definition of "contains". Use Offset instead.
func inRange(f *token.File, pos token.Pos) bool {
	return token.Pos(f.Base()) <= pos && pos <= token.Pos(f.Base()+f.Size())
}

// Position returns the Position for the pos value in the given file.
//
// p must be NoPos, a valid Pos in the range of f, or exactly 1 byte
// beyond the end of f. (See [Offset] for explanation.)
// Any other value causes a panic.
//
// Line directives (//line comments) are ignored.
func Position(f *token.File, pos token.Pos) token.Position {
	// Work around issue #57490.
	if int(pos) == f.Base()+f.Size()+1 {
		pos--
	}

	// TODO(adonovan): centralize the workaround for
	// golang/go#41029 (newline at EOF) here too.

	return f.PositionFor(pos, false)
}

// StartPosition converts a start Pos in the FileSet into a Position.
//
// Call this function only if start represents the start of a token or
// parse tree, such as the result of Node.Pos().  If start is the end of
// an interval, such as Node.End(), call EndPosition instead, as it
// may need the correction described at [Position].
func StartPosition(fset *token.FileSet, start token.Pos) (_ token.Position) {
	if f := fset.File(start); f != nil {
		return Position(f, start)
	}
	return
}

// EndPosition converts an end Pos in the FileSet into a Position.
//
// Call this function only if pos represents the end of
// a non-empty interval, such as the result of Node.End().
func EndPosition(fset *token.FileSet, end token.Pos) (_ token.Position) {
	if f := fset.File(end); f != nil && int(end) > f.Base() {
		return Position(f, end)
	}

	// Work around issue #57490.
	if f := fset.File(end - 1); f != nil {
		return Position(f, end)
	}

	return
}
