// 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/debug"
	"golang.org/x/tools/gopls/internal/hooks"
	"golang.org/x/tools/gopls/internal/lsp/cache"
	"golang.org/x/tools/gopls/internal/lsp/lsprpc"
	"golang.org/x/tools/gopls/internal/lsp/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()
	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) {
	// 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)
			}

			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{})
	regexpType        = reflect.TypeOf(&regexp.Regexp{})
	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.
		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.
	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)
	}
}
