// Copyright 2016 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.

// This file implements the encoding of source positions.

package src

import (
	"bytes"
	"fmt"
	"io"
)

// A Pos encodes a source position consisting of a (line, column) number pair
// and a position base. A zero Pos is a ready to use "unknown" position (nil
// position base and zero line number).
//
// The (line, column) values refer to a position in a file independent of any
// position base ("absolute" file position).
//
// The position base is used to determine the "relative" position, that is the
// filename and line number relative to the position base. If the base refers
// to the current file, there is no difference between absolute and relative
// positions. If it refers to a //line directive, a relative position is relative
// to that directive. A position base in turn contains the position at which it
// was introduced in the current file.
type Pos struct {
	base *PosBase
	lico
}

// NoPos is a valid unknown position.
var NoPos Pos

// MakePos creates a new Pos value with the given base, and (file-absolute)
// line and column.
func MakePos(base *PosBase, line, col uint) Pos {
	return Pos{base, makeLico(line, col)}
}

// IsKnown reports whether the position p is known.
// A position is known if it either has a non-nil
// position base, or a non-zero line number.
func (p Pos) IsKnown() bool {
	return p.base != nil || p.Line() != 0
}

// Before reports whether the position p comes before q in the source.
// For positions in different files, ordering is by filename.
func (p Pos) Before(q Pos) bool {
	n, m := p.Filename(), q.Filename()
	return n < m || n == m && p.lico < q.lico
}

// After reports whether the position p comes after q in the source.
// For positions in different files, ordering is by filename.
func (p Pos) After(q Pos) bool {
	n, m := p.Filename(), q.Filename()
	return n > m || n == m && p.lico > q.lico
}

func (p Pos) LineNumber() string {
	if !p.IsKnown() {
		return "?"
	}
	return p.lico.lineNumber()
}

func (p Pos) LineNumberHTML() string {
	if !p.IsKnown() {
		return "?"
	}
	return p.lico.lineNumberHTML()
}

// Filename returns the name of the actual file containing this position.
func (p Pos) Filename() string { return p.base.Pos().RelFilename() }

// Base returns the position base.
func (p Pos) Base() *PosBase { return p.base }

// SetBase sets the position base.
func (p *Pos) SetBase(base *PosBase) { p.base = base }

// RelFilename returns the filename recorded with the position's base.
func (p Pos) RelFilename() string { return p.base.Filename() }

// RelLine returns the line number relative to the position's base.
func (p Pos) RelLine() uint {
	b := p.base
	if b.Line() == 0 {
		// base line is unknown => relative line is unknown
		return 0
	}
	return b.Line() + (p.Line() - b.Pos().Line())
}

// RelCol returns the column number relative to the position's base.
func (p Pos) RelCol() uint {
	b := p.base
	if b.Col() == 0 {
		// base column is unknown => relative column is unknown
		// (the current specification for line directives requires
		// this to apply until the next PosBase/line directive,
		// not just until the new newline)
		return 0
	}
	if p.Line() == b.Pos().Line() {
		// p on same line as p's base => column is relative to p's base
		return b.Col() + (p.Col() - b.Pos().Col())
	}
	return p.Col()
}

// AbsFilename() returns the absolute filename recorded with the position's base.
func (p Pos) AbsFilename() string { return p.base.AbsFilename() }

// SymFilename() returns the absolute filename recorded with the position's base,
// prefixed by FileSymPrefix to make it appropriate for use as a linker symbol.
func (p Pos) SymFilename() string { return p.base.SymFilename() }

func (p Pos) String() string {
	return p.Format(true, true)
}

// Format formats a position as "filename:line" or "filename:line:column",
// controlled by the showCol flag and if the column is known (!= 0).
// For positions relative to line directives, the original position is
// shown as well, as in "filename:line[origfile:origline:origcolumn] if
// showOrig is set.
func (p Pos) Format(showCol, showOrig bool) string {
	buf := new(bytes.Buffer)
	p.WriteTo(buf, showCol, showOrig)
	return buf.String()
}

// WriteTo a position to w, formatted as Format does.
func (p Pos) WriteTo(w io.Writer, showCol, showOrig bool) {
	if !p.IsKnown() {
		io.WriteString(w, "<unknown line number>")
		return
	}

	if b := p.base; b == b.Pos().base {
		// base is file base (incl. nil)
		format(w, p.Filename(), p.Line(), p.Col(), showCol)
		return
	}

	// base is relative
	// Print the column only for the original position since the
	// relative position's column information may be bogus (it's
	// typically generated code and we can't say much about the
	// original source at that point but for the file:line info
	// that's provided via a line directive).
	// TODO(gri) This may not be true if we have an inlining base.
	// We may want to differentiate at some point.
	format(w, p.RelFilename(), p.RelLine(), p.RelCol(), showCol)
	if showOrig {
		io.WriteString(w, "[")
		format(w, p.Filename(), p.Line(), p.Col(), showCol)
		io.WriteString(w, "]")
	}
}

// format formats a (filename, line, col) tuple as "filename:line" (showCol
// is false or col == 0) or "filename:line:column" (showCol is true and col != 0).
func format(w io.Writer, filename string, line, col uint, showCol bool) {
	io.WriteString(w, filename)
	io.WriteString(w, ":")
	fmt.Fprint(w, line)
	// col == 0 and col == colMax are interpreted as unknown column values
	if showCol && 0 < col && col < colMax {
		io.WriteString(w, ":")
		fmt.Fprint(w, col)
	}
}

// formatstr wraps format to return a string.
func formatstr(filename string, line, col uint, showCol bool) string {
	buf := new(bytes.Buffer)
	format(buf, filename, line, col, showCol)
	return buf.String()
}

// ----------------------------------------------------------------------------
// PosBase

// A PosBase encodes a filename and base position.
// Typically, each file and line directive introduce a PosBase.
type PosBase struct {
	pos         Pos    // position at which the relative position is (line, col)
	filename    string // file name used to open source file, for error messages
	absFilename string // absolute file name, for PC-Line tables
	symFilename string // cached symbol file name, to avoid repeated string concatenation
	line, col   uint   // relative line, column number at pos
	inl         int    // inlining index (see cmd/internal/obj/inl.go)
}

// NewFileBase returns a new *PosBase for a file with the given (relative and
// absolute) filenames.
func NewFileBase(filename, absFilename string) *PosBase {
	base := &PosBase{
		filename:    filename,
		absFilename: absFilename,
		symFilename: FileSymPrefix + absFilename,
		line:        1,
		col:         1,
		inl:         -1,
	}
	base.pos = MakePos(base, 1, 1)
	return base
}

// NewLinePragmaBase returns a new *PosBase for a line directive of the form
//      //line filename:line:col
//      /*line filename:line:col*/
// at position pos.
func NewLinePragmaBase(pos Pos, filename, absFilename string, line, col uint) *PosBase {
	return &PosBase{pos, filename, absFilename, FileSymPrefix + absFilename, line, col, -1}
}

// NewInliningBase returns a copy of the old PosBase with the given inlining
// index. If old == nil, the resulting PosBase has no filename.
func NewInliningBase(old *PosBase, inlTreeIndex int) *PosBase {
	if old == nil {
		base := &PosBase{line: 1, col: 1, inl: inlTreeIndex}
		base.pos = MakePos(base, 1, 1)
		return base
	}
	copy := *old
	base := &copy
	base.inl = inlTreeIndex
	if old == old.pos.base {
		base.pos.base = base
	}
	return base
}

var noPos Pos

// Pos returns the position at which base is located.
// If b == nil, the result is the zero position.
func (b *PosBase) Pos() *Pos {
	if b != nil {
		return &b.pos
	}
	return &noPos
}

// Filename returns the filename recorded with the base.
// If b == nil, the result is the empty string.
func (b *PosBase) Filename() string {
	if b != nil {
		return b.filename
	}
	return ""
}

// AbsFilename returns the absolute filename recorded with the base.
// If b == nil, the result is the empty string.
func (b *PosBase) AbsFilename() string {
	if b != nil {
		return b.absFilename
	}
	return ""
}

const FileSymPrefix = "gofile.."

// SymFilename returns the absolute filename recorded with the base,
// prefixed by FileSymPrefix to make it appropriate for use as a linker symbol.
// If b is nil, SymFilename returns FileSymPrefix + "??".
func (b *PosBase) SymFilename() string {
	if b != nil {
		return b.symFilename
	}
	return FileSymPrefix + "??"
}

// Line returns the line number recorded with the base.
// If b == nil, the result is 0.
func (b *PosBase) Line() uint {
	if b != nil {
		return b.line
	}
	return 0
}

// Col returns the column number recorded with the base.
// If b == nil, the result is 0.
func (b *PosBase) Col() uint {
	if b != nil {
		return b.col
	}
	return 0
}

// InliningIndex returns the index into the global inlining
// tree recorded with the base. If b == nil or the base has
// not been inlined, the result is < 0.
func (b *PosBase) InliningIndex() int {
	if b != nil {
		return b.inl
	}
	return -1
}

// ----------------------------------------------------------------------------
// lico

// A lico is a compact encoding of a LIne and COlumn number.
type lico uint32

// Layout constants: 20 bits for line, 8 bits for column, 2 for isStmt, 2 for pro/epilogue
// (If this is too tight, we can either make lico 64b wide,
// or we can introduce a tiered encoding where we remove column
// information as line numbers grow bigger; similar to what gcc
// does.)
// The bitfield order is chosen to make IsStmt be the least significant
// part of a position; its use is to communicate statement edges through
// instruction scrambling in code generation, not to impose an order.
// TODO: Prologue and epilogue are perhaps better handled as pseudo-ops for the assembler,
// because they have almost no interaction with other uses of the position.
const (
	lineBits, lineMax     = 20, 1<<lineBits - 2
	bogusLine             = 1 // Used to disrupt infinite loops to prevent debugger looping
	isStmtBits, isStmtMax = 2, 1<<isStmtBits - 1
	xlogueBits, xlogueMax = 2, 1<<xlogueBits - 1
	colBits, colMax       = 32 - lineBits - xlogueBits - isStmtBits, 1<<colBits - 1

	isStmtShift = 0
	isStmtMask  = isStmtMax << isStmtShift
	xlogueShift = isStmtBits + isStmtShift
	xlogueMask  = xlogueMax << xlogueShift
	colShift    = xlogueBits + xlogueShift
	lineShift   = colBits + colShift
)
const (
	// It is expected that the front end or a phase in SSA will usually generate positions tagged with
	// PosDefaultStmt, but note statement boundaries with PosIsStmt.  Simple statements will have a single
	// boundary; for loops with initialization may have one for their entry and one for their back edge
	// (this depends on exactly how the loop is compiled; the intent is to provide a good experience to a
	// user debugging a program; the goal is that a breakpoint set on the loop line fires both on entry
	// and on iteration).  Proper treatment of non-gofmt input with multiple simple statements on a single
	// line is TBD.
	//
	// Optimizing compilation will move instructions around, and some of these will become known-bad as
	// step targets for debugging purposes (examples: register spills and reloads; code generated into
	// the entry block; invariant code hoisted out of loops) but those instructions will still have interesting
	// positions for profiling purposes. To reflect this these positions will be changed to PosNotStmt.
	//
	// When the optimizer removes an instruction marked PosIsStmt; it should attempt to find a nearby
	// instruction with the same line marked PosDefaultStmt to be the new statement boundary.  I.e., the
	// optimizer should make a best-effort to conserve statement boundary positions, and might be enhanced
	// to note when a statement boundary is not conserved.
	//
	// Code cloning, e.g. loop unrolling or loop unswitching, is an exception to the conservation rule
	// because a user running a debugger would expect to see breakpoints active in the copies of the code.
	//
	// In non-optimizing compilation there is still a role for PosNotStmt because of code generation
	// into the entry block.  PosIsStmt statement positions should be conserved.
	//
	// When code generation occurs any remaining default-marked positions are replaced with not-statement
	// positions.
	//
	PosDefaultStmt uint = iota // Default; position is not a statement boundary, but might be if optimization removes the designated statement boundary
	PosIsStmt                  // Position is a statement boundary; if optimization removes the corresponding instruction, it should attempt to find a new instruction to be the boundary.
	PosNotStmt                 // Position should not be a statement boundary, but line should be preserved for profiling and low-level debugging purposes.
)

type PosXlogue uint

const (
	PosDefaultLogue PosXlogue = iota
	PosPrologueEnd
	PosEpilogueBegin
)

func makeLicoRaw(line, col uint) lico {
	return lico(line<<lineShift | col<<colShift)
}

// This is a not-position that will not be elided.
// Depending on the debugger (gdb or delve) it may or may not be displayed.
func makeBogusLico() lico {
	return makeLicoRaw(bogusLine, 0).withIsStmt()
}

func makeLico(line, col uint) lico {
	if line > lineMax {
		// cannot represent line, use max. line so we have some information
		line = lineMax
	}
	if col > colMax {
		// cannot represent column, use max. column so we have some information
		col = colMax
	}
	// default is not-sure-if-statement
	return makeLicoRaw(line, col)
}

func (x lico) Line() uint           { return uint(x) >> lineShift }
func (x lico) SameLine(y lico) bool { return 0 == (x^y)&^lico(1<<lineShift-1) }
func (x lico) Col() uint            { return uint(x) >> colShift & colMax }
func (x lico) IsStmt() uint {
	if x == 0 {
		return PosNotStmt
	}
	return uint(x) >> isStmtShift & isStmtMax
}
func (x lico) Xlogue() PosXlogue {
	return PosXlogue(uint(x) >> xlogueShift & xlogueMax)
}

// withNotStmt returns a lico for the same location, but not a statement
func (x lico) withNotStmt() lico {
	return x.withStmt(PosNotStmt)
}

// withDefaultStmt returns a lico for the same location, with default isStmt
func (x lico) withDefaultStmt() lico {
	return x.withStmt(PosDefaultStmt)
}

// withIsStmt returns a lico for the same location, tagged as definitely a statement
func (x lico) withIsStmt() lico {
	return x.withStmt(PosIsStmt)
}

// withLogue attaches a prologue/epilogue attribute to a lico
func (x lico) withXlogue(xlogue PosXlogue) lico {
	if x == 0 {
		if xlogue == 0 {
			return x
		}
		// Normalize 0 to "not a statement"
		x = lico(PosNotStmt << isStmtShift)
	}
	return lico(uint(x) & ^uint(xlogueMax<<xlogueShift) | (uint(xlogue) << xlogueShift))
}

// withStmt returns a lico for the same location with specified is_stmt attribute
func (x lico) withStmt(stmt uint) lico {
	if x == 0 {
		return lico(0)
	}
	return lico(uint(x) & ^uint(isStmtMax<<isStmtShift) | (stmt << isStmtShift))
}

func (x lico) lineNumber() string {
	return fmt.Sprintf("%d", x.Line())
}

func (x lico) lineNumberHTML() string {
	if x.IsStmt() == PosDefaultStmt {
		return fmt.Sprintf("%d", x.Line())
	}
	style, pfx := "b", "+"
	if x.IsStmt() == PosNotStmt {
		style = "s" // /strike not supported in HTML5
		pfx = ""
	}
	return fmt.Sprintf("<%s>%s%d</%s>", style, pfx, x.Line(), style)
}

func (x lico) atColumn1() lico {
	return makeLico(x.Line(), 1).withIsStmt()
}
