// Copyright 2023 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 marker

// This file defines the marker test framework.
// See doc.go for extensive documentation.

import (
	"bytes"
	"context"
	"encoding/json"
	"flag"
	"fmt"
	"go/token"
	"go/types"
	"io/fs"
	"log"
	"os"
	"path"
	"path/filepath"
	"reflect"
	"regexp"
	"runtime"
	"sort"
	"strings"
	"testing"

	"github.com/google/go-cmp/cmp"

	"golang.org/x/tools/go/expect"
	"golang.org/x/tools/gopls/internal/cache"
	"golang.org/x/tools/gopls/internal/debug"
	"golang.org/x/tools/gopls/internal/hooks"
	"golang.org/x/tools/gopls/internal/lsprpc"
	"golang.org/x/tools/gopls/internal/protocol"
	"golang.org/x/tools/gopls/internal/test/compare"
	"golang.org/x/tools/gopls/internal/test/integration"
	"golang.org/x/tools/gopls/internal/test/integration/fake"
	"golang.org/x/tools/gopls/internal/util/bug"
	"golang.org/x/tools/gopls/internal/util/safetoken"
	"golang.org/x/tools/internal/diff"
	"golang.org/x/tools/internal/diff/myers"
	"golang.org/x/tools/internal/jsonrpc2"
	"golang.org/x/tools/internal/jsonrpc2/servertest"
	"golang.org/x/tools/internal/testenv"
	"golang.org/x/tools/txtar"
)

var update = flag.Bool("update", false, "if set, update test data during marker tests")

func TestMain(m *testing.M) {
	bug.PanicOnBugs = true
	testenv.ExitIfSmallMachine()
	// Disable GOPACKAGESDRIVER, as it can cause spurious test failures.
	os.Setenv("GOPACKAGESDRIVER", "off")
	os.Exit(m.Run())
}

// Test runs the marker tests from the testdata directory.
//
// See package documentation for details on how marker tests work.
//
// These tests were inspired by (and in many places copied from) a previous
// iteration of the marker tests built on top of the packagestest framework.
// Key design decisions motivating this reimplementation are as follows:
//   - The old tests had a single global session, causing interaction at a
//     distance and several awkward workarounds.
//   - The old tests could not be safely parallelized, because certain tests
//     manipulated the server options
//   - Relatedly, the old tests did not have a logic grouping of assertions into
//     a single unit, resulting in clusters of files serving clusters of
//     entangled assertions.
//   - The old tests used locations in the source as test names and as the
//     identity of golden content, meaning that a single edit could change the
//     name of an arbitrary number of subtests, and making it difficult to
//     manually edit golden content.
//   - The old tests did not hew closely to LSP concepts, resulting in, for
//     example, each marker implementation doing its own position
//     transformations, and inventing its own mechanism for configuration.
//   - The old tests had an ad-hoc session initialization process. The integration
//     test environment has had more time devoted to its initialization, and has a
//     more convenient API.
//   - The old tests lacked documentation, and often had failures that were hard
//     to understand. By starting from scratch, we can revisit these aspects.
func Test(t *testing.T) {
	if testing.Short() {
		builder := os.Getenv("GO_BUILDER_NAME")
		// Note that HasPrefix(builder, "darwin-" only matches legacy builders.
		// LUCI builder names start with x_tools-goN.NN.
		// We want to exclude solaris on both legacy and LUCI builders, as
		// it is timing out.
		if strings.HasPrefix(builder, "darwin-") || strings.Contains(builder, "solaris") {
			t.Skip("golang/go#64473: skipping with -short: this test is too slow on darwin and solaris builders")
		}
	}
	// The marker tests must be able to run go/packages.Load.
	testenv.NeedsGoPackages(t)

	const dir = "testdata"
	tests, err := loadMarkerTests(dir)
	if err != nil {
		t.Fatal(err)
	}

	// Opt: use a shared cache.
	cache := cache.New(nil)

	for _, test := range tests {
		test := test
		t.Run(test.name, func(t *testing.T) {
			t.Parallel()
			if test.skipReason != "" {
				t.Skip(test.skipReason)
			}
			for _, goos := range test.skipGOOS {
				if runtime.GOOS == goos {
					t.Skipf("skipping on %s due to -skip_goos", runtime.GOOS)
				}
			}

			// TODO(rfindley): it may be more useful to have full support for build
			// constraints.
			if test.minGoVersion != "" {
				var go1point int
				if _, err := fmt.Sscanf(test.minGoVersion, "go1.%d", &go1point); err != nil {
					t.Fatalf("parsing -min_go version: %v", err)
				}
				testenv.NeedsGo1Point(t, go1point)
			}
			if test.cgo {
				testenv.NeedsTool(t, "cgo")
			}
			config := fake.EditorConfig{
				Settings:         test.settings,
				CapabilitiesJSON: test.capabilities,
				Env:              test.env,
			}
			if _, ok := config.Settings["diagnosticsDelay"]; !ok {
				if config.Settings == nil {
					config.Settings = make(map[string]any)
				}
				config.Settings["diagnosticsDelay"] = "10ms"
			}
			// inv: config.Settings != nil

			run := &markerTestRun{
				test:       test,
				env:        newEnv(t, cache, test.files, test.proxyFiles, test.writeGoSum, config),
				settings:   config.Settings,
				values:     make(map[expect.Identifier]any),
				diags:      make(map[protocol.Location][]protocol.Diagnostic),
				extraNotes: make(map[protocol.DocumentURI]map[string][]*expect.Note),
			}
			// TODO(rfindley): make it easier to clean up the integration test environment.
			defer run.env.Editor.Shutdown(context.Background()) // ignore error
			defer run.env.Sandbox.Close()                       // ignore error

			// Open all files so that we operate consistently with LSP clients, and
			// (pragmatically) so that we have a Mapper available via the fake
			// editor.
			//
			// This also allows avoiding mutating the editor state in tests.
			for file := range test.files {
				run.env.OpenFile(file)
			}
			// Wait for the didOpen notifications to be processed, then collect
			// diagnostics.
			var diags map[string]*protocol.PublishDiagnosticsParams
			run.env.AfterChange(integration.ReadAllDiagnostics(&diags))
			for path, params := range diags {
				uri := run.env.Sandbox.Workdir.URI(path)
				for _, diag := range params.Diagnostics {
					loc := protocol.Location{
						URI: uri,
						Range: protocol.Range{
							Start: diag.Range.Start,
							End:   diag.Range.Start, // ignore end positions
						},
					}
					run.diags[loc] = append(run.diags[loc], diag)
				}
			}

			var markers []marker
			for _, note := range test.notes {
				mark := marker{run: run, note: note}
				if fn, ok := valueMarkerFuncs[note.Name]; ok {
					fn(mark)
				} else if _, ok := actionMarkerFuncs[note.Name]; ok {
					markers = append(markers, mark) // save for later
				} else {
					uri := mark.uri()
					if run.extraNotes[uri] == nil {
						run.extraNotes[uri] = make(map[string][]*expect.Note)
					}
					run.extraNotes[uri][note.Name] = append(run.extraNotes[uri][note.Name], note)
				}
			}

			// Invoke each remaining marker in the test.
			for _, mark := range markers {
				actionMarkerFuncs[mark.note.Name](mark)
			}

			// Any remaining (un-eliminated) diagnostics are an error.
			if !test.ignoreExtraDiags {
				for loc, diags := range run.diags {
					for _, diag := range diags {
						t.Errorf("%s: unexpected diagnostic: %q", run.fmtLoc(loc), diag.Message)
					}
				}
			}

			// TODO(rfindley): use these for whole-file marker tests.
			for uri, extras := range run.extraNotes {
				for name, extra := range extras {
					if len(extra) > 0 {
						t.Errorf("%s: %d unused %q markers", run.env.Sandbox.Workdir.URIToPath(uri), len(extra), name)
					}
				}
			}

			formatted, err := formatTest(test)
			if err != nil {
				t.Errorf("formatTest: %v", err)
			} else if *update {
				filename := filepath.Join(dir, test.name)
				if err := os.WriteFile(filename, formatted, 0644); err != nil {
					t.Error(err)
				}
			} else {
				// On go 1.19 and later, verify that the testdata has not changed.
				//
				// On earlier Go versions, the golden test data varies due to different
				// markdown escaping.
				//
				// Only check this if the test hasn't already failed, otherwise we'd
				// report duplicate mismatches of golden data.
				if testenv.Go1Point() >= 19 && !t.Failed() {
					// Otherwise, verify that formatted content matches.
					if diff := compare.NamedText("formatted", "on-disk", string(formatted), string(test.content)); diff != "" {
						t.Errorf("formatted test does not match on-disk content:\n%s", diff)
					}
				}
			}
		})
	}

	if abs, err := filepath.Abs(dir); err == nil && t.Failed() {
		t.Logf("(Filenames are relative to %s.)", abs)
	}
}

// A marker holds state for the execution of a single @marker
// annotation in the source.
type marker struct {
	run  *markerTestRun
	note *expect.Note
}

// ctx returns the mark context.
func (m marker) ctx() context.Context { return m.run.env.Ctx }

// T returns the testing.TB for this mark.
func (m marker) T() testing.TB { return m.run.env.T }

// server returns the LSP server for the marker test run.
func (m marker) editor() *fake.Editor { return m.run.env.Editor }

// server returns the LSP server for the marker test run.
func (m marker) server() protocol.Server { return m.run.env.Editor.Server }

// uri returns the URI of the file containing the marker.
func (mark marker) uri() protocol.DocumentURI {
	return mark.run.env.Sandbox.Workdir.URI(mark.run.test.fset.File(mark.note.Pos).Name())
}

// document returns a protocol.TextDocumentIdentifier for the current file.
func (mark marker) document() protocol.TextDocumentIdentifier {
	return protocol.TextDocumentIdentifier{URI: mark.uri()}
}

// path returns the relative path to the file containing the marker.
func (mark marker) path() string {
	return mark.run.env.Sandbox.Workdir.RelPath(mark.run.test.fset.File(mark.note.Pos).Name())
}

// mapper returns a *protocol.Mapper for the current file.
func (mark marker) mapper() *protocol.Mapper {
	mapper, err := mark.editor().Mapper(mark.path())
	if err != nil {
		mark.T().Fatalf("failed to get mapper for current mark: %v", err)
	}
	return mapper
}

// errorf reports an error with a prefix indicating the position of the marker note.
//
// It formats the error message using mark.sprintf.
func (mark marker) errorf(format string, args ...any) {
	msg := mark.sprintf(format, args...)
	// TODO(adonovan): consider using fmt.Fprintf(os.Stderr)+t.Fail instead of
	// t.Errorf to avoid reporting uninteresting positions in the Go source of
	// the driver. However, this loses the order of stderr wrt "FAIL: TestFoo"
	// subtest dividers.
	mark.T().Errorf("%s: %s", mark.run.fmtPos(mark.note.Pos), msg)
}

// valueMarkerFunc returns a wrapper around a function that allows it to be
// called during the processing of value markers (e.g. @value(v, 123)) with marker
// arguments converted to function parameters. The provided function's first
// parameter must be of type 'marker', and it must return a value.
//
// Unlike action markers, which are executed for actions such as test
// assertions, value markers are all evaluated first, and each computes
// a value that is recorded by its identifier, which is the marker's first
// argument. These values may be referred to from an action marker by
// this identifier, e.g. @action(... , v, ...).
//
// For example, given a fn with signature
//
//	func(mark marker, label, details, kind string) CompletionItem
//
// The result of valueMarkerFunc can associated with @item notes, and invoked
// as follows:
//
//	//@item(FooCompletion, "Foo", "func() int", "func")
//
// The provided fn should not mutate the test environment.
func valueMarkerFunc(fn any) func(marker) {
	ftype := reflect.TypeOf(fn)
	if ftype.NumIn() == 0 || ftype.In(0) != markerType {
		panic(fmt.Sprintf("value marker function %#v must accept marker as its first argument", ftype))
	}
	if ftype.NumOut() != 1 {
		panic(fmt.Sprintf("value marker function %#v must have exactly 1 result", ftype))
	}

	return func(mark marker) {
		if len(mark.note.Args) == 0 || !is[expect.Identifier](mark.note.Args[0]) {
			mark.errorf("first argument to a value marker function must be an identifier")
			return
		}
		id := mark.note.Args[0].(expect.Identifier)
		if alt, ok := mark.run.values[id]; ok {
			mark.errorf("%s already declared as %T", id, alt)
			return
		}
		args := append([]any{mark}, mark.note.Args[1:]...)
		argValues, err := convertArgs(mark, ftype, args)
		if err != nil {
			mark.errorf("converting args: %v", err)
			return
		}
		results := reflect.ValueOf(fn).Call(argValues)
		mark.run.values[id] = results[0].Interface()
	}
}

// actionMarkerFunc returns a wrapper around a function that allows it to be
// called during the processing of action markers (e.g. @action("abc", 123))
// with marker arguments converted to function parameters. The provided
// function's first parameter must be of type 'marker', and it must not return
// any values.
//
// The provided fn should not mutate the test environment.
func actionMarkerFunc(fn any) func(marker) {
	ftype := reflect.TypeOf(fn)
	if ftype.NumIn() == 0 || ftype.In(0) != markerType {
		panic(fmt.Sprintf("action marker function %#v must accept marker as its first argument", ftype))
	}
	if ftype.NumOut() != 0 {
		panic(fmt.Sprintf("action marker function %#v cannot have results", ftype))
	}

	return func(mark marker) {
		args := append([]any{mark}, mark.note.Args...)
		argValues, err := convertArgs(mark, ftype, args)
		if err != nil {
			mark.errorf("converting args: %v", err)
			return
		}
		reflect.ValueOf(fn).Call(argValues)
	}
}

func convertArgs(mark marker, ftype reflect.Type, args []any) ([]reflect.Value, error) {
	var (
		argValues []reflect.Value
		pnext     int          // next param index
		p         reflect.Type // current param
	)
	for i, arg := range args {
		if i < ftype.NumIn() {
			p = ftype.In(pnext)
			pnext++
		} else if p == nil || !ftype.IsVariadic() {
			// The actual number of arguments expected by the mark varies, depending
			// on whether this is a value marker or an action marker.
			//
			// Since this error indicates a bug, probably OK to have an imprecise
			// error message here.
			return nil, fmt.Errorf("too many arguments to %s", mark.note.Name)
		}
		elemType := p
		if ftype.IsVariadic() && pnext == ftype.NumIn() {
			elemType = p.Elem()
		}
		var v reflect.Value
		if id, ok := arg.(expect.Identifier); ok && id == "_" {
			v = reflect.Zero(elemType)
		} else {
			a, err := convert(mark, arg, elemType)
			if err != nil {
				return nil, err
			}
			v = reflect.ValueOf(a)
		}
		argValues = append(argValues, v)
	}
	// Check that we have sufficient arguments. If the function is variadic, we
	// do not need arguments for the final parameter.
	if pnext < ftype.NumIn()-1 || pnext == ftype.NumIn()-1 && !ftype.IsVariadic() {
		// Same comment as above: OK to be vague here.
		return nil, fmt.Errorf("not enough arguments to %s", mark.note.Name)
	}
	return argValues, nil
}

// is reports whether arg is a T.
func is[T any](arg any) bool {
	_, ok := arg.(T)
	return ok
}

// Supported value marker functions. See [valueMarkerFunc] for more details.
var valueMarkerFuncs = map[string]func(marker){
	"loc":  valueMarkerFunc(locMarker),
	"item": valueMarkerFunc(completionItemMarker),
}

// Supported action marker functions. See [actionMarkerFunc] for more details.
var actionMarkerFuncs = map[string]func(marker){
	"acceptcompletion": actionMarkerFunc(acceptCompletionMarker),
	"codeaction":       actionMarkerFunc(codeActionMarker),
	"codeactionedit":   actionMarkerFunc(codeActionEditMarker),
	"codeactionerr":    actionMarkerFunc(codeActionErrMarker),
	"codelenses":       actionMarkerFunc(codeLensesMarker),
	"complete":         actionMarkerFunc(completeMarker),
	"def":              actionMarkerFunc(defMarker),
	"diag":             actionMarkerFunc(diagMarker),
	"documentlink":     actionMarkerFunc(documentLinkMarker),
	"foldingrange":     actionMarkerFunc(foldingRangeMarker),
	"format":           actionMarkerFunc(formatMarker),
	"highlight":        actionMarkerFunc(highlightMarker),
	"hover":            actionMarkerFunc(hoverMarker),
	"hovererr":         actionMarkerFunc(hoverErrMarker),
	"implementation":   actionMarkerFunc(implementationMarker),
	"incomingcalls":    actionMarkerFunc(incomingCallsMarker),
	"inlayhints":       actionMarkerFunc(inlayhintsMarker),
	"outgoingcalls":    actionMarkerFunc(outgoingCallsMarker),
	"preparerename":    actionMarkerFunc(prepareRenameMarker),
	"rank":             actionMarkerFunc(rankMarker),
	"rankl":            actionMarkerFunc(ranklMarker),
	"refs":             actionMarkerFunc(refsMarker),
	"rename":           actionMarkerFunc(renameMarker),
	"renameerr":        actionMarkerFunc(renameErrMarker),
	"selectionrange":   actionMarkerFunc(selectionRangeMarker),
	"signature":        actionMarkerFunc(signatureMarker),
	"snippet":          actionMarkerFunc(snippetMarker),
	"suggestedfix":     actionMarkerFunc(suggestedfixMarker),
	"suggestedfixerr":  actionMarkerFunc(suggestedfixErrMarker),
	"symbol":           actionMarkerFunc(symbolMarker),
	"token":            actionMarkerFunc(tokenMarker),
	"typedef":          actionMarkerFunc(typedefMarker),
	"workspacesymbol":  actionMarkerFunc(workspaceSymbolMarker),
}

// markerTest holds all the test data extracted from a test txtar archive.
//
// See the documentation for RunMarkerTests for more information on the archive
// format.
type markerTest struct {
	name         string                        // relative path to the txtar file in the testdata dir
	fset         *token.FileSet                // fileset used for parsing notes
	content      []byte                        // raw test content
	archive      *txtar.Archive                // original test archive
	settings     map[string]any                // gopls settings
	capabilities []byte                        // content of capabilities.json file
	env          map[string]string             // editor environment
	proxyFiles   map[string][]byte             // proxy content
	files        map[string][]byte             // data files from the archive (excluding special files)
	notes        []*expect.Note                // extracted notes from data files
	golden       map[expect.Identifier]*Golden // extracted golden content, by identifier name

	skipReason string   // the skip reason extracted from the "skip" archive file
	flags      []string // flags extracted from the special "flags" archive file.

	// Parsed flags values.
	minGoVersion     string
	cgo              bool
	writeGoSum       []string // comma separated dirs to write go sum for
	skipGOOS         []string // comma separated GOOS values to skip
	ignoreExtraDiags bool
	filterBuiltins   bool
	filterKeywords   bool
}

// flagSet returns the flagset used for parsing the special "flags" file in the
// test archive.
func (t *markerTest) flagSet() *flag.FlagSet {
	flags := flag.NewFlagSet(t.name, flag.ContinueOnError)
	flags.StringVar(&t.minGoVersion, "min_go", "", "if set, the minimum go1.X version required for this test")
	flags.BoolVar(&t.cgo, "cgo", false, "if set, requires cgo (both the cgo tool and CGO_ENABLED=1)")
	flags.Var((*stringListValue)(&t.writeGoSum), "write_sumfile", "if set, write the sumfile for these directories")
	flags.Var((*stringListValue)(&t.skipGOOS), "skip_goos", "if set, skip this test on these GOOS values")
	flags.BoolVar(&t.ignoreExtraDiags, "ignore_extra_diags", false, "if set, suppress errors for unmatched diagnostics")
	flags.BoolVar(&t.filterBuiltins, "filter_builtins", true, "if set, filter builtins from completion results")
	flags.BoolVar(&t.filterKeywords, "filter_keywords", true, "if set, filter keywords from completion results")
	return flags
}

// stringListValue implements flag.Value.
type stringListValue []string

func (l *stringListValue) Set(s string) error {
	if s != "" {
		for _, d := range strings.Split(s, ",") {
			*l = append(*l, strings.TrimSpace(d))
		}
	}
	return nil
}

func (l stringListValue) String() string {
	return strings.Join([]string(l), ",")
}

func (t *markerTest) getGolden(id expect.Identifier) *Golden {
	golden, ok := t.golden[id]
	// If there was no golden content for this identifier, we must create one
	// to handle the case where -update is set: we need a place to store
	// the updated content.
	if !ok {
		golden = &Golden{id: id}

		// TODO(adonovan): the separation of markerTest (the
		// static aspects) from markerTestRun (the dynamic
		// ones) is evidently bogus because here we modify
		// markerTest during execution. Let's merge the two.
		t.golden[id] = golden
	}
	return golden
}

// Golden holds extracted golden content for a single @<name> prefix.
//
// When -update is set, golden captures the updated golden contents for later
// writing.
type Golden struct {
	id      expect.Identifier
	data    map[string][]byte // key "" => @id itself
	updated map[string][]byte
}

// Get returns golden content for the given name, which corresponds to the
// relative path following the golden prefix @<name>/. For example, to access
// the content of @foo/path/to/result.json from the Golden associated with
// @foo, name should be "path/to/result.json".
//
// If -update is set, the given update function will be called to get the
// updated golden content that should be written back to testdata.
//
// Marker functions must use this method instead of accessing data entries
// directly otherwise the -update operation will delete those entries.
//
// TODO(rfindley): rethink the logic here. We may want to separate Get and Set,
// and not delete golden content that isn't set.
func (g *Golden) Get(t testing.TB, name string, updated []byte) ([]byte, bool) {
	if existing, ok := g.updated[name]; ok {
		// Multiple tests may reference the same golden data, but if they do they
		// must agree about its expected content.
		if diff := compare.NamedText("existing", "updated", string(existing), string(updated)); diff != "" {
			t.Errorf("conflicting updates for golden data %s/%s:\n%s", g.id, name, diff)
		}
	}
	if g.updated == nil {
		g.updated = make(map[string][]byte)
	}
	g.updated[name] = updated
	if *update {
		return updated, true
	}

	res, ok := g.data[name]
	return res, ok
}

// loadMarkerTests walks the given dir looking for .txt files, which it
// interprets as a txtar archive.
//
// See the documentation for RunMarkerTests for more details on the test data
// archive.
func loadMarkerTests(dir string) ([]*markerTest, error) {
	var tests []*markerTest
	err := filepath.WalkDir(dir, func(path string, _ fs.DirEntry, err error) error {
		if strings.HasSuffix(path, ".txt") {
			content, err := os.ReadFile(path)
			if err != nil {
				return err
			}

			name := strings.TrimPrefix(path, dir+string(filepath.Separator))
			test, err := loadMarkerTest(name, content)
			if err != nil {
				return fmt.Errorf("%s: %v", path, err)
			}
			tests = append(tests, test)
		}
		return err
	})
	return tests, err
}

func loadMarkerTest(name string, content []byte) (*markerTest, error) {
	archive := txtar.Parse(content)
	if len(archive.Files) == 0 {
		return nil, fmt.Errorf("txtar file has no '-- filename --' sections")
	}
	if bytes.Contains(archive.Comment, []byte("\n-- ")) {
		// This check is conservative, but the comment is only a comment.
		return nil, fmt.Errorf("ill-formed '-- filename --' header in comment")
	}
	test := &markerTest{
		name:    name,
		fset:    token.NewFileSet(),
		content: content,
		archive: archive,
		files:   make(map[string][]byte),
		golden:  make(map[expect.Identifier]*Golden),
	}
	for _, file := range archive.Files {
		switch {
		case file.Name == "skip":
			reason := strings.ReplaceAll(string(file.Data), "\n", " ")
			reason = strings.TrimSpace(reason)
			test.skipReason = reason

		case file.Name == "flags":
			test.flags = strings.Fields(string(file.Data))

		case file.Name == "settings.json":
			if err := json.Unmarshal(file.Data, &test.settings); err != nil {
				return nil, err
			}

		case file.Name == "capabilities.json":
			test.capabilities = file.Data // lazily unmarshalled by the editor

		case file.Name == "env":
			test.env = make(map[string]string)
			fields := strings.Fields(string(file.Data))
			for _, field := range fields {
				key, value, ok := strings.Cut(field, "=")
				if !ok {
					return nil, fmt.Errorf("env vars must be formatted as var=value, got %q", field)
				}
				test.env[key] = value
			}

		case strings.HasPrefix(file.Name, "@"): // golden content
			idstring, name, _ := strings.Cut(file.Name[len("@"):], "/")
			id := expect.Identifier(idstring)
			// Note that a file.Name of just "@id" gives (id, name) = ("id", "").
			if _, ok := test.golden[id]; !ok {
				test.golden[id] = &Golden{
					id:   id,
					data: make(map[string][]byte),
				}
			}
			test.golden[id].data[name] = file.Data

		case strings.HasPrefix(file.Name, "proxy/"):
			name := file.Name[len("proxy/"):]
			if test.proxyFiles == nil {
				test.proxyFiles = make(map[string][]byte)
			}
			test.proxyFiles[name] = file.Data

		default: // ordinary file content
			notes, err := expect.Parse(test.fset, file.Name, file.Data)
			if err != nil {
				return nil, fmt.Errorf("parsing notes in %q: %v", file.Name, err)
			}

			// Reject common misspelling: "// @mark".
			// TODO(adonovan): permit "// @" within a string. Detect multiple spaces.
			if i := bytes.Index(file.Data, []byte("// @")); i >= 0 {
				line := 1 + bytes.Count(file.Data[:i], []byte("\n"))
				return nil, fmt.Errorf("%s:%d: unwanted space before marker (// @)", file.Name, line)
			}

			// The 'go list' command doesn't work correct with modules named
			// testdata", so don't allow it as a module name (golang/go#65406).
			// (Otherwise files within it will end up in an ad hoc
			// package, "command-line-arguments/$TMPDIR/...".)
			if filepath.Base(file.Name) == "go.mod" &&
				bytes.Contains(file.Data, []byte("module testdata")) {
				return nil, fmt.Errorf("'testdata' is not a valid module name")
			}

			test.notes = append(test.notes, notes...)
			test.files[file.Name] = file.Data
		}

		// Print a warning if we see what looks like "-- filename --"
		// without the second "--". It's not necessarily wrong,
		// but it should almost never appear in our test inputs.
		if bytes.Contains(file.Data, []byte("\n-- ")) {
			log.Printf("ill-formed '-- filename --' header in %s?", file.Name)
		}
	}

	// Parse flags after loading files, as they may have been set by the "flags"
	// file.
	if err := test.flagSet().Parse(test.flags); err != nil {
		return nil, fmt.Errorf("parsing flags: %v", err)
	}

	return test, nil
}

// formatTest formats the test as a txtar archive.
func formatTest(test *markerTest) ([]byte, error) {
	arch := &txtar.Archive{
		Comment: test.archive.Comment,
	}

	updatedGolden := make(map[string][]byte)
	for id, g := range test.golden {
		for name, data := range g.updated {
			filename := "@" + path.Join(string(id), name) // name may be ""
			updatedGolden[filename] = data
		}
	}

	// Preserve the original ordering of archive files.
	for _, file := range test.archive.Files {
		switch file.Name {
		// Preserve configuration files exactly as they were. They must have parsed
		// if we got this far.
		case "skip", "flags", "settings.json", "capabilities.json", "env":
			arch.Files = append(arch.Files, file)
		default:
			if _, ok := test.files[file.Name]; ok { // ordinary file
				arch.Files = append(arch.Files, file)
			} else if strings.HasPrefix(file.Name, "proxy/") { // proxy file
				arch.Files = append(arch.Files, file)
			} else if data, ok := updatedGolden[file.Name]; ok { // golden file
				arch.Files = append(arch.Files, txtar.File{Name: file.Name, Data: data})
				delete(updatedGolden, file.Name)
			}
		}
	}

	// ...followed by any new golden files.
	var newGoldenFiles []txtar.File
	for filename, data := range updatedGolden {
		// TODO(rfindley): it looks like this implicitly removes trailing newlines
		// from golden content. Is there any way to fix that? Perhaps we should
		// just make the diff tolerant of missing newlines?
		newGoldenFiles = append(newGoldenFiles, txtar.File{Name: filename, Data: data})
	}
	// Sort new golden files lexically.
	sort.Slice(newGoldenFiles, func(i, j int) bool {
		return newGoldenFiles[i].Name < newGoldenFiles[j].Name
	})
	arch.Files = append(arch.Files, newGoldenFiles...)

	return txtar.Format(arch), nil
}

// newEnv creates a new environment for a marker test.
//
// TODO(rfindley): simplify and refactor the construction of testing
// environments across integration tests, marker tests, and benchmarks.
func newEnv(t *testing.T, cache *cache.Cache, files, proxyFiles map[string][]byte, writeGoSum []string, config fake.EditorConfig) *integration.Env {
	sandbox, err := fake.NewSandbox(&fake.SandboxConfig{
		RootDir:    t.TempDir(),
		Files:      files,
		ProxyFiles: proxyFiles,
	})
	if err != nil {
		t.Fatal(err)
	}

	for _, dir := range writeGoSum {
		if err := sandbox.RunGoCommand(context.Background(), dir, "list", []string{"-mod=mod", "..."}, []string{"GOWORK=off"}, true); err != nil {
			t.Fatal(err)
		}
	}

	// Put a debug instance in the context to prevent logging to stderr.
	// See associated TODO in runner.go: we should revisit this pattern.
	ctx := context.Background()
	ctx = debug.WithInstance(ctx, "off")

	awaiter := integration.NewAwaiter(sandbox.Workdir)
	ss := lsprpc.NewStreamServer(cache, false, hooks.Options)
	server := servertest.NewPipeServer(ss, jsonrpc2.NewRawStream)
	const skipApplyEdits = true // capture edits but don't apply them
	editor, err := fake.NewEditor(sandbox, config).Connect(ctx, server, awaiter.Hooks(), skipApplyEdits)
	if err != nil {
		sandbox.Close() // ignore error
		t.Fatal(err)
	}
	if err := awaiter.Await(ctx, integration.InitialWorkspaceLoad); err != nil {
		sandbox.Close() // ignore error
		t.Fatal(err)
	}
	return &integration.Env{
		T:       t,
		Ctx:     ctx,
		Editor:  editor,
		Sandbox: sandbox,
		Awaiter: awaiter,
	}
}

// A markerTestRun holds the state of one run of a marker test archive.
type markerTestRun struct {
	test     *markerTest
	env      *integration.Env
	settings map[string]any

	// Collected information.
	// Each @diag/@suggestedfix marker eliminates an entry from diags.
	values map[expect.Identifier]any
	diags  map[protocol.Location][]protocol.Diagnostic // diagnostics by position; location end == start

	// Notes that weren't associated with a top-level marker func. They may be
	// consumed by another marker (e.g. @codelenses collects @codelens markers).
	// Any notes that aren't consumed are flagged as an error.
	extraNotes map[protocol.DocumentURI]map[string][]*expect.Note
}

// sprintf returns a formatted string after applying pre-processing to
// arguments of the following types:
//   - token.Pos: formatted using (*markerTestRun).fmtPos
//   - protocol.Location: formatted using (*markerTestRun).fmtLoc
func (c *marker) sprintf(format string, args ...any) string {
	if false {
		_ = fmt.Sprintf(format, args...) // enable vet printf checker
	}
	var args2 []any
	for _, arg := range args {
		switch arg := arg.(type) {
		case token.Pos:
			args2 = append(args2, c.run.fmtPos(arg))
		case protocol.Location:
			args2 = append(args2, c.run.fmtLoc(arg))
		default:
			args2 = append(args2, arg)
		}
	}
	return fmt.Sprintf(format, args2...)
}

// fmtLoc formats the given pos in the context of the test, using
// archive-relative paths for files and including the line number in the full
// archive file.
func (run *markerTestRun) fmtPos(pos token.Pos) string {
	file := run.test.fset.File(pos)
	if file == nil {
		run.env.T.Errorf("position %d not in test fileset", pos)
		return "<invalid location>"
	}
	m, err := run.env.Editor.Mapper(file.Name())
	if err != nil {
		run.env.T.Errorf("%s", err)
		return "<invalid location>"
	}
	loc, err := m.PosLocation(file, pos, pos)
	if err != nil {
		run.env.T.Errorf("Mapper(%s).PosLocation failed: %v", file.Name(), err)
	}
	return run.fmtLoc(loc)
}

// fmtLoc formats the given location in the context of the test, using
// archive-relative paths for files and including the line number in the full
// archive file.
func (run *markerTestRun) fmtLoc(loc protocol.Location) string {
	formatted := run.fmtLocDetails(loc, true)
	if formatted == "" {
		run.env.T.Errorf("unable to find %s in test archive", loc)
		return "<invalid location>"
	}
	return formatted
}

// See fmtLoc. If includeTxtPos is not set, the position in the full archive
// file is omitted.
//
// If the location cannot be found within the archive, fmtLocDetails returns "".
func (run *markerTestRun) fmtLocDetails(loc protocol.Location, includeTxtPos bool) string {
	if loc == (protocol.Location{}) {
		return ""
	}
	lines := bytes.Count(run.test.archive.Comment, []byte("\n"))
	var name string
	for _, f := range run.test.archive.Files {
		lines++ // -- separator --
		uri := run.env.Sandbox.Workdir.URI(f.Name)
		if uri == loc.URI {
			name = f.Name
			break
		}
		lines += bytes.Count(f.Data, []byte("\n"))
	}
	if name == "" {
		return ""
	}
	m, err := run.env.Editor.Mapper(name)
	if err != nil {
		run.env.T.Errorf("internal error: %v", err)
		return "<invalid location>"
	}
	start, end, err := m.RangeOffsets(loc.Range)
	if err != nil {
		run.env.T.Errorf("error formatting location %s: %v", loc, err)
		return "<invalid location>"
	}
	var (
		startLine, startCol8 = m.OffsetLineCol8(start)
		endLine, endCol8     = m.OffsetLineCol8(end)
	)
	innerSpan := fmt.Sprintf("%d:%d", startLine, startCol8)       // relative to the embedded file
	outerSpan := fmt.Sprintf("%d:%d", lines+startLine, startCol8) // relative to the archive file
	if start != end {
		if endLine == startLine {
			innerSpan += fmt.Sprintf("-%d", endCol8)
			outerSpan += fmt.Sprintf("-%d", endCol8)
		} else {
			innerSpan += fmt.Sprintf("-%d:%d", endLine, endCol8)
			outerSpan += fmt.Sprintf("-%d:%d", lines+endLine, endCol8)
		}
	}

	if includeTxtPos {
		return fmt.Sprintf("%s:%s (%s:%s)", name, innerSpan, run.test.name, outerSpan)
	} else {
		return fmt.Sprintf("%s:%s", name, innerSpan)
	}
}

// ---- converters ----

// converter is the signature of argument converters.
// A converter should return an error rather than calling marker.errorf().
//
// type converter func(marker, any) (any, error)

// Types with special conversions.
var (
	goldenType        = reflect.TypeOf(&Golden{})
	locationType      = reflect.TypeOf(protocol.Location{})
	markerType        = reflect.TypeOf(marker{})
	stringMatcherType = reflect.TypeOf(stringMatcher{})
)

func convert(mark marker, arg any, paramType reflect.Type) (any, error) {
	// Handle stringMatcher and golden parameters before resolving identifiers,
	// because golden content lives in a separate namespace from other
	// identifiers.
	switch paramType {
	case stringMatcherType:
		return convertStringMatcher(mark, arg)
	case goldenType:
		id, ok := arg.(expect.Identifier)
		if !ok {
			return nil, fmt.Errorf("invalid input type %T: golden key must be an identifier", arg)
		}
		return mark.run.test.getGolden(id), nil
	}
	if id, ok := arg.(expect.Identifier); ok {
		if arg, ok := mark.run.values[id]; ok {
			if !reflect.TypeOf(arg).AssignableTo(paramType) {
				return nil, fmt.Errorf("cannot convert %v (%T) to %s", arg, arg, paramType)
			}
			return arg, nil
		}
	}
	if paramType == locationType {
		return convertLocation(mark, arg)
	}
	if reflect.TypeOf(arg).AssignableTo(paramType) {
		return arg, nil // no conversion required
	}
	return nil, fmt.Errorf("cannot convert %v (%T) to %s", arg, arg, paramType)
}

// convertLocation converts a string or regexp argument into the protocol
// location corresponding to the first position of the string (or first match
// of the regexp) in the line preceding the note.
func convertLocation(mark marker, arg any) (protocol.Location, error) {
	switch arg := arg.(type) {
	case string:
		startOff, preceding, m, err := linePreceding(mark.run, mark.note.Pos)
		if err != nil {
			return protocol.Location{}, err
		}
		idx := bytes.Index(preceding, []byte(arg))
		if idx < 0 {
			return protocol.Location{}, fmt.Errorf("substring %q not found in %q", arg, preceding)
		}
		off := startOff + idx
		return m.OffsetLocation(off, off+len(arg))
	case *regexp.Regexp:
		return findRegexpInLine(mark.run, mark.note.Pos, arg)
	default:
		return protocol.Location{}, fmt.Errorf("cannot convert argument type %T to location (must be a string to match the preceding line)", arg)
	}
}

// findRegexpInLine searches the partial line preceding pos for a match for the
// regular expression re, returning a location spanning the first match. If re
// contains exactly one subgroup, the position of this subgroup match is
// returned rather than the position of the full match.
func findRegexpInLine(run *markerTestRun, pos token.Pos, re *regexp.Regexp) (protocol.Location, error) {
	startOff, preceding, m, err := linePreceding(run, pos)
	if err != nil {
		return protocol.Location{}, err
	}

	matches := re.FindSubmatchIndex(preceding)
	if len(matches) == 0 {
		return protocol.Location{}, fmt.Errorf("no match for regexp %q found in %q", re, string(preceding))
	}
	var start, end int
	switch len(matches) {
	case 2:
		// no subgroups: return the range of the regexp expression
		start, end = matches[0], matches[1]
	case 4:
		// one subgroup: return its range
		start, end = matches[2], matches[3]
	default:
		return protocol.Location{}, fmt.Errorf("invalid location regexp %q: expect either 0 or 1 subgroups, got %d", re, len(matches)/2-1)
	}

	return m.OffsetLocation(start+startOff, end+startOff)
}

func linePreceding(run *markerTestRun, pos token.Pos) (int, []byte, *protocol.Mapper, error) {
	file := run.test.fset.File(pos)
	posn := safetoken.Position(file, pos)
	lineStart := file.LineStart(posn.Line)
	startOff, endOff, err := safetoken.Offsets(file, lineStart, pos)
	if err != nil {
		return 0, nil, nil, err
	}
	m, err := run.env.Editor.Mapper(file.Name())
	if err != nil {
		return 0, nil, nil, err
	}
	return startOff, m.Content[startOff:endOff], m, nil
}

// convertStringMatcher converts a string, regexp, or identifier
// argument into a stringMatcher. The string is a substring of the
// expected error, the regexp is a pattern than matches the expected
// error, and the identifier is a golden file containing the expected
// error.
func convertStringMatcher(mark marker, arg any) (stringMatcher, error) {
	switch arg := arg.(type) {
	case string:
		return stringMatcher{substr: arg}, nil
	case *regexp.Regexp:
		return stringMatcher{pattern: arg}, nil
	case expect.Identifier:
		golden := mark.run.test.getGolden(arg)
		return stringMatcher{golden: golden}, nil
	default:
		return stringMatcher{}, fmt.Errorf("cannot convert %T to wantError (want: string, regexp, or identifier)", arg)
	}
}

// A stringMatcher represents an expectation of a specific string value.
//
// It may be indicated in one of three ways, in 'expect' notation:
//   - an identifier 'foo', to compare (exactly) with the contents of the golden
//     section @foo;
//   - a pattern expression re"ab.*c", to match against a regular expression;
//   - a string literal "abc", to check for a substring.
type stringMatcher struct {
	golden  *Golden
	pattern *regexp.Regexp
	substr  string
}

func (sc stringMatcher) String() string {
	if sc.golden != nil {
		return fmt.Sprintf("content from @%s entry", sc.golden.id)
	} else if sc.pattern != nil {
		return fmt.Sprintf("content matching %#q", sc.pattern)
	} else {
		return fmt.Sprintf("content with substring %q", sc.substr)
	}
}

// checkErr asserts that the given error matches the stringMatcher's expectations.
func (sc stringMatcher) checkErr(mark marker, err error) {
	if err == nil {
		mark.errorf("@%s succeeded unexpectedly, want %v", mark.note.Name, sc)
		return
	}
	sc.check(mark, err.Error())
}

// check asserts that the given content matches the stringMatcher's expectations.
func (sc stringMatcher) check(mark marker, got string) {
	if sc.golden != nil {
		compareGolden(mark, []byte(got), sc.golden)
	} else if sc.pattern != nil {
		// Content must match the regular expression pattern.
		if !sc.pattern.MatchString(got) {
			mark.errorf("got %q, does not match pattern %#q", got, sc.pattern)
		}

	} else if !strings.Contains(got, sc.substr) {
		// Content must contain the expected substring.
		mark.errorf("got %q, want substring %q", got, sc.substr)
	}
}

// checkChangedFiles compares the files changed by an operation with their expected (golden) state.
func checkChangedFiles(mark marker, changed map[string][]byte, golden *Golden) {
	// Check changed files match expectations.
	for filename, got := range changed {
		if want, ok := golden.Get(mark.T(), filename, got); !ok {
			mark.errorf("%s: unexpected change to file %s; got:\n%s",
				mark.note.Name, filename, got)

		} else if string(got) != string(want) {
			mark.errorf("%s: wrong file content for %s: got:\n%s\nwant:\n%s\ndiff:\n%s",
				mark.note.Name, filename, got, want,
				compare.Bytes(want, got))
		}
	}

	// Report unmet expectations.
	for filename := range golden.data {
		if _, ok := changed[filename]; !ok {
			want, _ := golden.Get(mark.T(), filename, nil)
			mark.errorf("%s: missing change to file %s; want:\n%s",
				mark.note.Name, filename, want)
		}
	}
}

// checkDiffs computes unified diffs for each changed file, and compares with
// the diff content stored in the given golden directory.
func checkDiffs(mark marker, changed map[string][]byte, golden *Golden) {
	diffs := make(map[string]string)
	for name, after := range changed {
		before := mark.run.env.FileContent(name)
		// TODO(golang/go#64023): switch back to diff.Strings.
		// The attached issue is only one obstacle to switching.
		// Another is that different diff algorithms produce
		// different results, so if we commit diffs in test
		// expectations, then we need to either (1) state
		// which diff implementation they use and never change
		// it, or (2) don't compare diffs, but instead apply
		// the "want" diff and check that it produces the
		// "got" output. Option 2 is more robust, as it allows
		// the test expectation to use any valid diff.
		edits := myers.ComputeEdits(before, string(after))
		d, err := diff.ToUnified("before", "after", before, edits, 0)
		if err != nil {
			// Can't happen: edits are consistent.
			log.Fatalf("internal error in diff.ToUnified: %v", err)
		}
		// Trim the unified header from diffs, as it is unnecessary and repetitive.
		difflines := strings.Split(d, "\n")
		if len(difflines) >= 2 && strings.HasPrefix(difflines[1], "+++") {
			diffs[name] = strings.Join(difflines[2:], "\n")
		} else {
			diffs[name] = d
		}
	}
	// Check changed files match expectations.
	for filename, got := range diffs {
		if want, ok := golden.Get(mark.T(), filename, []byte(got)); !ok {
			mark.errorf("%s: unexpected change to file %s; got diff:\n%s",
				mark.note.Name, filename, got)

		} else if got != string(want) {
			mark.errorf("%s: wrong diff for %s:\n\ngot:\n%s\n\nwant:\n%s\n",
				mark.note.Name, filename, got, want)
		}
	}
	// Report unmet expectations.
	for filename := range golden.data {
		if _, ok := changed[filename]; !ok {
			want, _ := golden.Get(mark.T(), filename, nil)
			mark.errorf("%s: missing change to file %s; want:\n%s",
				mark.note.Name, filename, want)
		}
	}
}

// ---- marker functions ----

// TODO(rfindley): consolidate documentation of these markers. They are already
// documented above, so much of the documentation here is redundant.

// completionItem is a simplified summary of a completion item.
type completionItem struct {
	Label, Detail, Kind, Documentation string
}

func completionItemMarker(mark marker, label string, other ...string) completionItem {
	if len(other) > 3 {
		mark.errorf("too many arguments to @item: expect at most 4")
	}
	item := completionItem{
		Label: label,
	}
	if len(other) > 0 {
		item.Detail = other[0]
	}
	if len(other) > 1 {
		item.Kind = other[1]
	}
	if len(other) > 2 {
		item.Documentation = other[2]
	}
	return item
}

func rankMarker(mark marker, src protocol.Location, items ...completionItem) {
	list := mark.run.env.Completion(src)
	var got []string
	// Collect results that are present in items, preserving their order.
	for _, g := range list.Items {
		for _, w := range items {
			if g.Label == w.Label {
				got = append(got, g.Label)
				break
			}
		}
	}
	var want []string
	for _, w := range items {
		want = append(want, w.Label)
	}
	if diff := cmp.Diff(want, got); diff != "" {
		mark.errorf("completion rankings do not match (-want +got):\n%s", diff)
	}
}

func ranklMarker(mark marker, src protocol.Location, labels ...string) {
	list := mark.run.env.Completion(src)
	var got []string
	// Collect results that are present in items, preserving their order.
	for _, g := range list.Items {
		for _, label := range labels {
			if g.Label == label {
				got = append(got, g.Label)
				break
			}
		}
	}
	if diff := cmp.Diff(labels, got); diff != "" {
		mark.errorf("completion rankings do not match (-want +got):\n%s", diff)
	}
}

func snippetMarker(mark marker, src protocol.Location, item completionItem, want string) {
	list := mark.run.env.Completion(src)
	var (
		found bool
		got   string
		all   []string // for errors
	)
	items := filterBuiltinsAndKeywords(mark, list.Items)
	for _, i := range items {
		all = append(all, i.Label)
		if i.Label == item.Label {
			found = true
			if i.TextEdit != nil {
				got = i.TextEdit.NewText
			}
			break
		}
	}
	if !found {
		mark.errorf("no completion item found matching %s (got: %v)", item.Label, all)
		return
	}
	if got != want {
		mark.errorf("snippets do not match: got %q, want %q", got, want)
	}
}

// completeMarker implements the @complete marker, running
// textDocument/completion at the given src location and asserting that the
// results match the expected results.
func completeMarker(mark marker, src protocol.Location, want ...completionItem) {
	list := mark.run.env.Completion(src)
	items := filterBuiltinsAndKeywords(mark, list.Items)
	var got []completionItem
	for i, item := range items {
		simplified := completionItem{
			Label:  item.Label,
			Detail: item.Detail,
			Kind:   fmt.Sprint(item.Kind),
		}
		if item.Documentation != nil {
			switch v := item.Documentation.Value.(type) {
			case string:
				simplified.Documentation = v
			case protocol.MarkupContent:
				simplified.Documentation = strings.TrimSpace(v.Value) // trim newlines
			}
		}
		// Support short-hand notation: if Detail, Kind, or Documentation are omitted from the
		// item, don't match them.
		if i < len(want) {
			if want[i].Detail == "" {
				simplified.Detail = ""
			}
			if want[i].Kind == "" {
				simplified.Kind = ""
			}
			if want[i].Documentation == "" {
				simplified.Documentation = ""
			}
		}
		got = append(got, simplified)
	}
	if len(want) == 0 {
		want = nil // got is nil if empty
	}
	if diff := cmp.Diff(want, got); diff != "" {
		mark.errorf("Completion(...) returned unexpect results (-want +got):\n%s", diff)
	}
}

// filterBuiltinsAndKeywords filters out builtins and keywords from completion
// results.
//
// It over-approximates, and does not detect if builtins are shadowed.
func filterBuiltinsAndKeywords(mark marker, items []protocol.CompletionItem) []protocol.CompletionItem {
	keep := 0
	for _, item := range items {
		if mark.run.test.filterKeywords && item.Kind == protocol.KeywordCompletion {
			continue
		}
		if mark.run.test.filterBuiltins && types.Universe.Lookup(item.Label) != nil {
			continue
		}
		items[keep] = item
		keep++
	}
	return items[:keep]
}

// acceptCompletionMarker implements the @acceptCompletion marker, running
// textDocument/completion at the given src location and accepting the
// candidate with the given label. The resulting source must match the provided
// golden content.
func acceptCompletionMarker(mark marker, src protocol.Location, label string, golden *Golden) {
	list := mark.run.env.Completion(src)
	var selected *protocol.CompletionItem
	for _, item := range list.Items {
		if item.Label == label {
			selected = &item
			break
		}
	}
	if selected == nil {
		mark.errorf("Completion(...) did not return an item labeled %q", label)
		return
	}
	filename := mark.path()
	mapper := mark.mapper()
	patched, _, err := protocol.ApplyEdits(mapper, append([]protocol.TextEdit{*selected.TextEdit}, selected.AdditionalTextEdits...))

	if err != nil {
		mark.errorf("ApplyProtocolEdits failed: %v", err)
		return
	}
	changes := map[string][]byte{filename: patched}
	// Check the file state.
	checkChangedFiles(mark, changes, golden)
}

// defMarker implements the @def marker, running textDocument/definition at
// the given src location and asserting that there is exactly one resulting
// location, matching dst.
//
// TODO(rfindley): support a variadic destination set.
func defMarker(mark marker, src, dst protocol.Location) {
	got := mark.run.env.GoToDefinition(src)
	if got != dst {
		mark.errorf("definition location does not match:\n\tgot: %s\n\twant %s",
			mark.run.fmtLoc(got), mark.run.fmtLoc(dst))
	}
}

func typedefMarker(mark marker, src, dst protocol.Location) {
	got := mark.run.env.TypeDefinition(src)
	if got != dst {
		mark.errorf("type definition location does not match:\n\tgot: %s\n\twant %s",
			mark.run.fmtLoc(got), mark.run.fmtLoc(dst))
	}
}

func foldingRangeMarker(mark marker, g *Golden) {
	env := mark.run.env
	ranges, err := mark.server().FoldingRange(env.Ctx, &protocol.FoldingRangeParams{
		TextDocument: mark.document(),
	})
	if err != nil {
		mark.errorf("foldingRange failed: %v", err)
		return
	}
	var edits []protocol.TextEdit
	insert := func(line, char uint32, text string) {
		pos := protocol.Position{Line: line, Character: char}
		edits = append(edits, protocol.TextEdit{
			Range: protocol.Range{
				Start: pos,
				End:   pos,
			},
			NewText: text,
		})
	}
	for i, rng := range ranges {
		insert(rng.StartLine, rng.StartCharacter, fmt.Sprintf("<%d kind=%q>", i, rng.Kind))
		insert(rng.EndLine, rng.EndCharacter, fmt.Sprintf("</%d>", i))
	}
	filename := mark.path()
	mapper, err := env.Editor.Mapper(filename)
	if err != nil {
		mark.errorf("Editor.Mapper(%s) failed: %v", filename, err)
		return
	}
	got, _, err := protocol.ApplyEdits(mapper, edits)
	if err != nil {
		mark.errorf("ApplyProtocolEdits failed: %v", err)
		return
	}
	want, _ := g.Get(mark.T(), "", got)
	if diff := compare.Bytes(want, got); diff != "" {
		mark.errorf("foldingRange mismatch:\n%s", diff)
	}
}

// formatMarker implements the @format marker.
func formatMarker(mark marker, golden *Golden) {
	edits, err := mark.server().Formatting(mark.ctx(), &protocol.DocumentFormattingParams{
		TextDocument: mark.document(),
	})
	var got []byte
	if err != nil {
		got = []byte(err.Error() + "\n") // all golden content is newline terminated
	} else {
		env := mark.run.env
		filename := mark.path()
		mapper, err := env.Editor.Mapper(filename)
		if err != nil {
			mark.errorf("Editor.Mapper(%s) failed: %v", filename, err)
		}

		got, _, err = protocol.ApplyEdits(mapper, edits)
		if err != nil {
			mark.errorf("ApplyProtocolEdits failed: %v", err)
			return
		}
	}

	compareGolden(mark, got, golden)
}

func highlightMarker(mark marker, src protocol.Location, dsts ...protocol.Location) {
	highlights := mark.run.env.DocumentHighlight(src)
	var got []protocol.Range
	for _, h := range highlights {
		got = append(got, h.Range)
	}

	var want []protocol.Range
	for _, d := range dsts {
		want = append(want, d.Range)
	}

	sortRanges := func(s []protocol.Range) {
		sort.Slice(s, func(i, j int) bool {
			return protocol.CompareRange(s[i], s[j]) < 0
		})
	}

	sortRanges(got)
	sortRanges(want)

	if diff := cmp.Diff(want, got); diff != "" {
		mark.errorf("DocumentHighlight(%v) mismatch (-want +got):\n%s", src, diff)
	}
}

func hoverMarker(mark marker, src, dst protocol.Location, sc stringMatcher) {
	content, gotDst := mark.run.env.Hover(src)
	if gotDst != dst {
		mark.errorf("hover location does not match:\n\tgot: %s\n\twant %s)", mark.run.fmtLoc(gotDst), mark.run.fmtLoc(dst))
	}
	gotMD := ""
	if content != nil {
		gotMD = content.Value
	}
	sc.check(mark, gotMD)
}

func hoverErrMarker(mark marker, src protocol.Location, em stringMatcher) {
	_, _, err := mark.editor().Hover(mark.ctx(), src)
	em.checkErr(mark, err)
}

// locMarker implements the @loc marker. It is executed before other
// markers, so that locations are available.
func locMarker(mark marker, loc protocol.Location) protocol.Location { return loc }

// diagMarker implements the @diag marker. It eliminates diagnostics from
// the observed set in mark.test.
func diagMarker(mark marker, loc protocol.Location, re *regexp.Regexp) {
	if _, ok := removeDiagnostic(mark, loc, re); !ok {
		mark.errorf("no diagnostic at %v matches %q", loc, re)
	}
}

// removeDiagnostic looks for a diagnostic matching loc at the given position.
//
// If found, it returns (diag, true), and eliminates the matched diagnostic
// from the unmatched set.
//
// If not found, it returns (protocol.Diagnostic{}, false).
func removeDiagnostic(mark marker, loc protocol.Location, re *regexp.Regexp) (protocol.Diagnostic, bool) {
	loc.Range.End = loc.Range.Start // diagnostics ignore end position.
	diags := mark.run.diags[loc]
	for i, diag := range diags {
		if re.MatchString(diag.Message) {
			mark.run.diags[loc] = append(diags[:i], diags[i+1:]...)
			return diag, true
		}
	}
	return protocol.Diagnostic{}, false
}

// renameMarker implements the @rename(location, new, golden) marker.
func renameMarker(mark marker, loc protocol.Location, newName string, golden *Golden) {
	changed, err := rename(mark.run.env, loc, newName)
	if err != nil {
		mark.errorf("rename failed: %v. (Use @renameerr for expected errors.)", err)
		return
	}
	checkDiffs(mark, changed, golden)
}

// renameErrMarker implements the @renamererr(location, new, error) marker.
func renameErrMarker(mark marker, loc protocol.Location, newName string, wantErr stringMatcher) {
	_, err := rename(mark.run.env, loc, newName)
	wantErr.checkErr(mark, err)
}

func selectionRangeMarker(mark marker, loc protocol.Location, g *Golden) {
	ranges, err := mark.server().SelectionRange(mark.ctx(), &protocol.SelectionRangeParams{
		TextDocument: mark.document(),
		Positions:    []protocol.Position{loc.Range.Start},
	})
	if err != nil {
		mark.errorf("SelectionRange failed: %v", err)
		return
	}
	var buf bytes.Buffer
	m := mark.mapper()
	for i, path := range ranges {
		fmt.Fprintf(&buf, "Ranges %d:", i)
		rng := path
		for {
			s, e, err := m.RangeOffsets(rng.Range)
			if err != nil {
				mark.errorf("RangeOffsets failed: %v", err)
				return
			}

			var snippet string
			if e-s < 30 {
				snippet = string(m.Content[s:e])
			} else {
				snippet = string(m.Content[s:s+15]) + "..." + string(m.Content[e-15:e])
			}

			fmt.Fprintf(&buf, "\n\t%v %q", rng.Range, strings.ReplaceAll(snippet, "\n", "\\n"))

			if rng.Parent == nil {
				break
			}
			rng = *rng.Parent
		}
		buf.WriteRune('\n')
	}
	compareGolden(mark, buf.Bytes(), g)
}

func tokenMarker(mark marker, loc protocol.Location, tokenType, mod string) {
	tokens := mark.run.env.SemanticTokensRange(loc)
	if len(tokens) != 1 {
		mark.errorf("got %d tokens, want 1", len(tokens))
		return
	}
	tok := tokens[0]
	if tok.TokenType != tokenType {
		mark.errorf("token type = %q, want %q", tok.TokenType, tokenType)
	}
	if tok.Mod != mod {
		mark.errorf("token mod = %q, want %q", tok.Mod, mod)
	}
}

func signatureMarker(mark marker, src protocol.Location, label string, active int64) {
	got := mark.run.env.SignatureHelp(src)
	if label == "" {
		// A null result is expected.
		// (There's no point having a @signatureerr marker
		// because the server handler suppresses all errors.)
		if got != nil && len(got.Signatures) > 0 {
			mark.errorf("signatureHelp = %v, want 0 signatures", got)
		}
		return
	}
	if got == nil || len(got.Signatures) != 1 {
		mark.errorf("signatureHelp = %v, want exactly 1 signature", got)
		return
	}
	if got := got.Signatures[0].Label; got != label {
		mark.errorf("signatureHelp: got label %q, want %q", got, label)
	}
	if got := int64(got.ActiveParameter); got != active {
		mark.errorf("signatureHelp: got active parameter %d, want %d", got, active)
	}
}

// rename returns the new contents of the files that would be modified
// by renaming the identifier at loc to newName.
func rename(env *integration.Env, loc protocol.Location, newName string) (map[string][]byte, error) {
	// We call Server.Rename directly, instead of
	//   env.Editor.Rename(env.Ctx, loc, newName)
	// to isolate Rename from PrepareRename, and because we don't
	// want to modify the file system in a scenario with multiple
	// @rename markers.

	editMap, err := env.Editor.Server.Rename(env.Ctx, &protocol.RenameParams{
		TextDocument: protocol.TextDocumentIdentifier{URI: loc.URI},
		Position:     loc.Range.Start,
		NewName:      newName,
	})
	if err != nil {
		return nil, err
	}

	fileChanges := make(map[string][]byte)
	if err := applyDocumentChanges(env, editMap.DocumentChanges, fileChanges); err != nil {
		return nil, fmt.Errorf("applying document changes: %v", err)
	}
	return fileChanges, nil
}

// applyDocumentChanges applies the given document changes to the editor buffer
// content, recording the resulting contents in the fileChanges map. It is an
// error for a change to an edit a file that is already present in the
// fileChanges map.
func applyDocumentChanges(env *integration.Env, changes []protocol.DocumentChanges, fileChanges map[string][]byte) error {
	getMapper := func(path string) (*protocol.Mapper, error) {
		if _, ok := fileChanges[path]; ok {
			return nil, fmt.Errorf("internal error: %s is already edited", path)
		}
		return env.Editor.Mapper(path)
	}

	for _, change := range changes {
		if change.RenameFile != nil {
			// rename
			oldFile := env.Sandbox.Workdir.URIToPath(change.RenameFile.OldURI)
			mapper, err := getMapper(oldFile)
			if err != nil {
				return err
			}
			newFile := env.Sandbox.Workdir.URIToPath(change.RenameFile.NewURI)
			fileChanges[newFile] = mapper.Content
		} else {
			// edit
			filename := env.Sandbox.Workdir.URIToPath(change.TextDocumentEdit.TextDocument.URI)
			mapper, err := getMapper(filename)
			if err != nil {
				return err
			}
			patched, _, err := protocol.ApplyEdits(mapper, protocol.AsTextEdits(change.TextDocumentEdit.Edits))
			if err != nil {
				return err
			}
			fileChanges[filename] = patched
		}
	}

	return nil
}

func codeActionMarker(mark marker, start, end protocol.Location, actionKind string, g *Golden, titles ...string) {
	// Request the range from start.Start to end.End.
	loc := start
	loc.Range.End = end.Range.End

	// Apply the fix it suggests.
	changed, err := codeAction(mark.run.env, loc.URI, loc.Range, actionKind, nil, titles)
	if err != nil {
		mark.errorf("codeAction failed: %v", err)
		return
	}

	// Check the file state.
	checkChangedFiles(mark, changed, g)
}

func codeActionEditMarker(mark marker, loc protocol.Location, actionKind string, g *Golden, titles ...string) {
	changed, err := codeAction(mark.run.env, loc.URI, loc.Range, actionKind, nil, titles)
	if err != nil {
		mark.errorf("codeAction failed: %v", err)
		return
	}

	checkDiffs(mark, changed, g)
}

func codeActionErrMarker(mark marker, start, end protocol.Location, actionKind string, wantErr stringMatcher) {
	loc := start
	loc.Range.End = end.Range.End
	_, err := codeAction(mark.run.env, loc.URI, loc.Range, actionKind, nil, nil)
	wantErr.checkErr(mark, err)
}

// codeLensesMarker runs the @codelenses() marker, collecting @codelens marks
// in the current file and comparing with the result of the
// textDocument/codeLens RPC.
func codeLensesMarker(mark marker) {
	type codeLens struct {
		Range protocol.Range
		Title string
	}

	lenses := mark.run.env.CodeLens(mark.path())
	var got []codeLens
	for _, lens := range lenses {
		title := ""
		if lens.Command != nil {
			title = lens.Command.Title
		}
		got = append(got, codeLens{lens.Range, title})
	}

	var want []codeLens
	mark.consumeExtraNotes("codelens", actionMarkerFunc(func(_ marker, loc protocol.Location, title string) {
		want = append(want, codeLens{loc.Range, title})
	}))

	for _, s := range [][]codeLens{got, want} {
		sort.Slice(s, func(i, j int) bool {
			li, lj := s[i], s[j]
			if c := protocol.CompareRange(li.Range, lj.Range); c != 0 {
				return c < 0
			}
			return li.Title < lj.Title
		})
	}

	if diff := cmp.Diff(want, got); diff != "" {
		mark.errorf("codelenses: unexpected diff (-want +got):\n%s", diff)
	}
}

func documentLinkMarker(mark marker, g *Golden) {
	var b bytes.Buffer
	links := mark.run.env.DocumentLink(mark.path())
	for _, l := range links {
		if l.Target == nil {
			mark.errorf("%s: nil link target", l.Range)
			continue
		}
		loc := protocol.Location{URI: mark.uri(), Range: l.Range}
		fmt.Fprintln(&b, mark.run.fmtLocDetails(loc, false), *l.Target)
	}

	compareGolden(mark, b.Bytes(), g)
}

// consumeExtraNotes runs the provided func for each extra note with the given
// name, and deletes all matching notes.
func (mark marker) consumeExtraNotes(name string, f func(marker)) {
	uri := mark.uri()
	notes := mark.run.extraNotes[uri][name]
	delete(mark.run.extraNotes[uri], name)

	for _, note := range notes {
		f(marker{run: mark.run, note: note})
	}
}

// suggestedfixMarker implements the @suggestedfix(location, regexp,
// kind, golden) marker. It acts like @diag(location, regexp), to set
// the expectation of a diagnostic, but then it applies the first code
// action of the specified kind suggested by the matched diagnostic.
func suggestedfixMarker(mark marker, loc protocol.Location, re *regexp.Regexp, golden *Golden) {
	loc.Range.End = loc.Range.Start // diagnostics ignore end position.
	// Find and remove the matching diagnostic.
	diag, ok := removeDiagnostic(mark, loc, re)
	if !ok {
		mark.errorf("no diagnostic at %v matches %q", loc, re)
		return
	}

	// Apply the fix it suggests.
	changed, err := codeAction(mark.run.env, loc.URI, diag.Range, "quickfix", &diag, nil)
	if err != nil {
		mark.errorf("suggestedfix failed: %v. (Use @suggestedfixerr for expected errors.)", err)
		return
	}

	// Check the file state.
	checkDiffs(mark, changed, golden)
}

func suggestedfixErrMarker(mark marker, loc protocol.Location, re *regexp.Regexp, wantErr stringMatcher) {
	loc.Range.End = loc.Range.Start // diagnostics ignore end position.
	// Find and remove the matching diagnostic.
	diag, ok := removeDiagnostic(mark, loc, re)
	if !ok {
		mark.errorf("no diagnostic at %v matches %q", loc, re)
		return
	}

	// Apply the fix it suggests.
	_, err := codeAction(mark.run.env, loc.URI, diag.Range, "quickfix", &diag, nil)
	wantErr.checkErr(mark, err)
}

// codeAction executes a textDocument/codeAction request for the specified
// location and kind. If diag is non-nil, it is used as the code action
// context.
//
// The resulting map contains resulting file contents after the code action is
// applied. Currently, this function does not support code actions that return
// edits directly; it only supports code action commands.
func codeAction(env *integration.Env, uri protocol.DocumentURI, rng protocol.Range, actionKind string, diag *protocol.Diagnostic, titles []string) (map[string][]byte, error) {
	changes, err := codeActionChanges(env, uri, rng, actionKind, diag, titles)
	if err != nil {
		return nil, err
	}
	fileChanges := make(map[string][]byte)
	if err := applyDocumentChanges(env, changes, fileChanges); err != nil {
		return nil, fmt.Errorf("applying document changes: %v", err)
	}
	return fileChanges, nil
}

// codeActionChanges executes a textDocument/codeAction request for the
// specified location and kind, and captures the resulting document changes.
// If diag is non-nil, it is used as the code action context.
// If titles is non-empty, the code action title must be present among the provided titles.
func codeActionChanges(env *integration.Env, uri protocol.DocumentURI, rng protocol.Range, actionKind string, diag *protocol.Diagnostic, titles []string) ([]protocol.DocumentChanges, error) {
	// Request all code actions that apply to the diagnostic.
	// (The protocol supports filtering using Context.Only={actionKind}
	// but we can give a better error if we don't filter.)
	params := &protocol.CodeActionParams{
		TextDocument: protocol.TextDocumentIdentifier{URI: uri},
		Range:        rng,
		Context: protocol.CodeActionContext{
			Only: nil, // => all kinds
		},
	}
	if diag != nil {
		params.Context.Diagnostics = []protocol.Diagnostic{*diag}
	}

	actions, err := env.Editor.Server.CodeAction(env.Ctx, params)
	if err != nil {
		return nil, err
	}

	// Find the sole candidates CodeAction of the specified kind (e.g. refactor.rewrite).
	var candidates []protocol.CodeAction
	for _, act := range actions {
		if act.Kind == protocol.CodeActionKind(actionKind) {
			if len(titles) > 0 {
				for _, f := range titles {
					if act.Title == f {
						candidates = append(candidates, act)
						break
					}
				}
			} else {
				candidates = append(candidates, act)
			}
		}
	}
	if len(candidates) != 1 {
		for _, act := range actions {
			env.T.Logf("found CodeAction Kind=%s Title=%q", act.Kind, act.Title)
		}
		return nil, fmt.Errorf("found %d CodeActions of kind %s matching filters %v for this diagnostic, want 1", len(candidates), actionKind, titles)
	}
	action := candidates[0]

	// Apply the codeAction.
	//
	// Spec:
	//  "If a code action provides an edit and a command, first the edit is
	//  executed and then the command."
	// An action may specify an edit and/or a command, to be
	// applied in that order. But since applyDocumentChanges(env,
	// action.Edit.DocumentChanges) doesn't compose, for now we
	// assert that actions return one or the other.

	// Resolve code action edits first if the client has resolve support
	// and the code action has no edits.
	if action.Edit == nil {
		editSupport, err := env.Editor.EditResolveSupport()
		if err != nil {
			return nil, err
		}
		if editSupport {
			resolved, err := env.Editor.Server.ResolveCodeAction(env.Ctx, &action)
			if err != nil {
				return nil, err
			}
			action.Edit = resolved.Edit
		}
	}

	if action.Edit != nil {
		if action.Edit.Changes != nil {
			env.T.Errorf("internal error: discarding unexpected CodeAction{Kind=%s, Title=%q}.Edit.Changes", action.Kind, action.Title)
		}
		if action.Edit.DocumentChanges != nil {
			if action.Command != nil {
				env.T.Errorf("internal error: discarding unexpected CodeAction{Kind=%s, Title=%q}.Command", action.Kind, action.Title)
			}
			return action.Edit.DocumentChanges, nil
		}
	}

	if action.Command != nil {
		// This is a typical CodeAction command:
		//
		//   Title:     "Implement error"
		//   Command:   gopls.apply_fix
		//   Arguments: [{"Fix":"stub_methods","URI":".../a.go","Range":...}}]
		//
		// The client makes an ExecuteCommand RPC to the server,
		// which dispatches it to the ApplyFix handler.
		// ApplyFix dispatches to the "stub_methods" suggestedfix hook (the meat).
		// The server then makes an ApplyEdit RPC to the client,
		// whose Awaiter hook gathers the edits instead of applying them.

		_ = env.Awaiter.TakeDocumentChanges() // reset (assuming Env is confined to this thread)

		if _, err := env.Editor.Server.ExecuteCommand(env.Ctx, &protocol.ExecuteCommandParams{
			Command:   action.Command.Command,
			Arguments: action.Command.Arguments,
		}); err != nil {
			return nil, err
		}
		return env.Awaiter.TakeDocumentChanges(), nil
	}

	return nil, nil
}

// refsMarker implements the @refs marker.
func refsMarker(mark marker, src protocol.Location, want ...protocol.Location) {
	refs := func(includeDeclaration bool, want []protocol.Location) error {
		got, err := mark.server().References(mark.ctx(), &protocol.ReferenceParams{
			TextDocumentPositionParams: protocol.LocationTextDocumentPositionParams(src),
			Context: protocol.ReferenceContext{
				IncludeDeclaration: includeDeclaration,
			},
		})
		if err != nil {
			return err
		}

		return compareLocations(mark, got, want)
	}

	for _, includeDeclaration := range []bool{false, true} {
		// Ignore first 'want' location if we didn't request the declaration.
		// TODO(adonovan): don't assume a single declaration:
		// there may be >1 if corresponding methods are considered.
		want := want
		if !includeDeclaration && len(want) > 0 {
			want = want[1:]
		}
		if err := refs(includeDeclaration, want); err != nil {
			mark.errorf("refs(includeDeclaration=%t) failed: %v",
				includeDeclaration, err)
		}
	}
}

// implementationMarker implements the @implementation marker.
func implementationMarker(mark marker, src protocol.Location, want ...protocol.Location) {
	got, err := mark.server().Implementation(mark.ctx(), &protocol.ImplementationParams{
		TextDocumentPositionParams: protocol.LocationTextDocumentPositionParams(src),
	})
	if err != nil {
		mark.errorf("implementation at %s failed: %v", src, err)
		return
	}
	if err := compareLocations(mark, got, want); err != nil {
		mark.errorf("implementation: %v", err)
	}
}

func itemLocation(item protocol.CallHierarchyItem) protocol.Location {
	return protocol.Location{
		URI:   item.URI,
		Range: item.Range,
	}
}

func incomingCallsMarker(mark marker, src protocol.Location, want ...protocol.Location) {
	getCalls := func(item protocol.CallHierarchyItem) ([]protocol.Location, error) {
		calls, err := mark.server().IncomingCalls(mark.ctx(), &protocol.CallHierarchyIncomingCallsParams{Item: item})
		if err != nil {
			return nil, err
		}
		var locs []protocol.Location
		for _, call := range calls {
			locs = append(locs, itemLocation(call.From))
		}
		return locs, nil
	}
	callHierarchy(mark, src, getCalls, want)
}

func outgoingCallsMarker(mark marker, src protocol.Location, want ...protocol.Location) {
	getCalls := func(item protocol.CallHierarchyItem) ([]protocol.Location, error) {
		calls, err := mark.server().OutgoingCalls(mark.ctx(), &protocol.CallHierarchyOutgoingCallsParams{Item: item})
		if err != nil {
			return nil, err
		}
		var locs []protocol.Location
		for _, call := range calls {
			locs = append(locs, itemLocation(call.To))
		}
		return locs, nil
	}
	callHierarchy(mark, src, getCalls, want)
}

type callHierarchyFunc = func(protocol.CallHierarchyItem) ([]protocol.Location, error)

func callHierarchy(mark marker, src protocol.Location, getCalls callHierarchyFunc, want []protocol.Location) {
	items, err := mark.server().PrepareCallHierarchy(mark.ctx(), &protocol.CallHierarchyPrepareParams{
		TextDocumentPositionParams: protocol.LocationTextDocumentPositionParams(src),
	})
	if err != nil {
		mark.errorf("PrepareCallHierarchy failed: %v", err)
		return
	}
	if nitems := len(items); nitems != 1 {
		mark.errorf("PrepareCallHierarchy returned %d items, want exactly 1", nitems)
		return
	}
	if loc := itemLocation(items[0]); loc != src {
		mark.errorf("PrepareCallHierarchy found call %v, want %v", loc, src)
		return
	}
	calls, err := getCalls(items[0])
	if err != nil {
		mark.errorf("call hierarchy failed: %v", err)
		return
	}
	if calls == nil {
		calls = []protocol.Location{}
	}
	// TODO(rfindley): why aren't call hierarchy results stable?
	sortLocs := func(locs []protocol.Location) {
		sort.Slice(locs, func(i, j int) bool {
			return protocol.CompareLocation(locs[i], locs[j]) < 0
		})
	}
	sortLocs(want)
	sortLocs(calls)
	if d := cmp.Diff(want, calls); d != "" {
		mark.errorf("call hierarchy: unexpected results (-want +got):\n%s", d)
	}
}

func inlayhintsMarker(mark marker, g *Golden) {
	hints := mark.run.env.InlayHints(mark.path())

	// Map inlay hints to text edits.
	edits := make([]protocol.TextEdit, len(hints))
	for i, hint := range hints {
		var paddingLeft, paddingRight string
		if hint.PaddingLeft {
			paddingLeft = " "
		}
		if hint.PaddingRight {
			paddingRight = " "
		}
		edits[i] = protocol.TextEdit{
			Range:   protocol.Range{Start: hint.Position, End: hint.Position},
			NewText: fmt.Sprintf("<%s%s%s>", paddingLeft, hint.Label[0].Value, paddingRight),
		}
	}

	m := mark.mapper()
	got, _, err := protocol.ApplyEdits(m, edits)
	if err != nil {
		mark.errorf("ApplyProtocolEdits: %v", err)
		return
	}

	compareGolden(mark, got, g)
}

func prepareRenameMarker(mark marker, src, spn protocol.Location, placeholder string) {
	params := &protocol.PrepareRenameParams{
		TextDocumentPositionParams: protocol.LocationTextDocumentPositionParams(src),
	}
	got, err := mark.server().PrepareRename(mark.ctx(), params)
	if err != nil {
		mark.T().Fatal(err)
	}
	if placeholder == "" {
		if got != nil {
			mark.errorf("PrepareRename(...) = %v, want nil", got)
		}
		return
	}
	want := &protocol.PrepareRenameResult{Range: spn.Range, Placeholder: placeholder}
	if diff := cmp.Diff(want, got); diff != "" {
		mark.errorf("mismatching PrepareRename result:\n%s", diff)
	}
}

// symbolMarker implements the @symbol marker.
func symbolMarker(mark marker, golden *Golden) {
	// Retrieve information about all symbols in this file.
	symbols, err := mark.server().DocumentSymbol(mark.ctx(), &protocol.DocumentSymbolParams{
		TextDocument: protocol.TextDocumentIdentifier{URI: mark.uri()},
	})
	if err != nil {
		mark.errorf("DocumentSymbol request failed: %v", err)
		return
	}

	// Format symbols one per line, sorted (in effect) by first column, a dotted name.
	var lines []string
	for _, symbol := range symbols {
		// Each result element is a union of (legacy)
		// SymbolInformation and (new) DocumentSymbol,
		// so we ascertain which one and then transcode.
		data, err := json.Marshal(symbol)
		if err != nil {
			mark.T().Fatal(err)
		}
		if _, ok := symbol.(map[string]any)["location"]; ok {
			// This case is not reached because Editor initialization
			// enables HierarchicalDocumentSymbolSupport.
			// TODO(adonovan): test this too.
			var sym protocol.SymbolInformation
			if err := json.Unmarshal(data, &sym); err != nil {
				mark.T().Fatal(err)
			}
			mark.errorf("fake Editor doesn't support SymbolInformation")

		} else {
			var sym protocol.DocumentSymbol // new hierarchical hotness
			if err := json.Unmarshal(data, &sym); err != nil {
				mark.T().Fatal(err)
			}

			// Print each symbol in the response tree.
			var visit func(sym protocol.DocumentSymbol, prefix []string)
			visit = func(sym protocol.DocumentSymbol, prefix []string) {
				var out strings.Builder
				out.WriteString(strings.Join(prefix, "."))
				fmt.Fprintf(&out, " %q", sym.Detail)
				if delta := sym.Range.End.Line - sym.Range.Start.Line; delta > 0 {
					fmt.Fprintf(&out, " +%d lines", delta)
				}
				lines = append(lines, out.String())

				for _, child := range sym.Children {
					visit(child, append(prefix, child.Name))
				}
			}
			visit(sym, []string{sym.Name})
		}
	}
	sort.Strings(lines)
	lines = append(lines, "") // match trailing newline in .txtar file
	got := []byte(strings.Join(lines, "\n"))

	// Compare with golden.
	want, ok := golden.Get(mark.T(), "", got)
	if !ok {
		mark.errorf("%s: missing golden file @%s", mark.note.Name, golden.id)
	} else if diff := cmp.Diff(string(got), string(want)); diff != "" {
		mark.errorf("%s: unexpected output: got:\n%s\nwant:\n%s\ndiff:\n%s",
			mark.note.Name, got, want, diff)
	}
}

// compareLocations returns an error message if got and want are not
// the same set of locations. The marker is used only for fmtLoc.
func compareLocations(mark marker, got, want []protocol.Location) error {
	toStrings := func(locs []protocol.Location) []string {
		strs := make([]string, len(locs))
		for i, loc := range locs {
			strs[i] = mark.run.fmtLoc(loc)
		}
		sort.Strings(strs)
		return strs
	}
	if diff := cmp.Diff(toStrings(want), toStrings(got)); diff != "" {
		return fmt.Errorf("incorrect result locations: (got %d, want %d):\n%s",
			len(got), len(want), diff)
	}
	return nil
}

func workspaceSymbolMarker(mark marker, query string, golden *Golden) {
	params := &protocol.WorkspaceSymbolParams{
		Query: query,
	}

	gotSymbols, err := mark.server().Symbol(mark.ctx(), params)
	if err != nil {
		mark.errorf("Symbol(%q) failed: %v", query, err)
		return
	}
	var got bytes.Buffer
	for _, s := range gotSymbols {
		// Omit the txtar position of the symbol location; otherwise edits to the
		// txtar archive lead to unexpected failures.
		loc := mark.run.fmtLocDetails(s.Location, false)
		// TODO(rfindley): can we do better here, by detecting if the location is
		// relative to GOROOT?
		if loc == "" {
			loc = "<unknown>"
		}
		fmt.Fprintf(&got, "%s %s %s\n", loc, s.Name, s.Kind)
	}

	compareGolden(mark, got.Bytes(), golden)
}

// compareGolden compares the content of got with that of g.Get(""), reporting
// errors on any mismatch.
//
// TODO(rfindley): use this helper in more places.
func compareGolden(mark marker, got []byte, g *Golden) {
	want, ok := g.Get(mark.T(), "", got)
	if !ok {
		mark.errorf("missing golden file @%s", g.id)
		return
	}
	// Normalize newline termination: archive files (i.e. Golden content) can't
	// contain non-newline terminated files, except in the special case where the
	// file is completely empty.
	//
	// Note that txtar partitions a contiguous byte slice, so we must copy before
	// appending.
	normalize := func(s []byte) []byte {
		if n := len(s); n > 0 && s[n-1] != '\n' {
			s = append(s[:n:n], '\n') // don't mutate array
		}
		return s
	}
	got = normalize(got)
	want = normalize(want)
	if diff := compare.Bytes(want, got); diff != "" {
		mark.errorf("%s does not match @%s:\n%s", mark.note.Name, g.id, diff)
	}
}
