// Copyright 2019 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 cache

import (
	"context"
	"errors"
	"fmt"
	"maps"
	"os"
	"path/filepath"
	"slices"
	"strconv"
	"strings"
	"sync"
	"sync/atomic"
	"time"

	"golang.org/x/tools/gopls/internal/cache/metadata"
	"golang.org/x/tools/gopls/internal/cache/typerefs"
	"golang.org/x/tools/gopls/internal/file"
	"golang.org/x/tools/gopls/internal/label"
	"golang.org/x/tools/gopls/internal/protocol"
	"golang.org/x/tools/gopls/internal/settings"
	"golang.org/x/tools/gopls/internal/util/bug"
	"golang.org/x/tools/gopls/internal/util/memoize"
	"golang.org/x/tools/gopls/internal/util/persistent"
	"golang.org/x/tools/gopls/internal/vulncheck"
	"golang.org/x/tools/internal/event"
	"golang.org/x/tools/internal/event/keys"
	"golang.org/x/tools/internal/gocommand"
	"golang.org/x/tools/internal/imports"
	"golang.org/x/tools/internal/xcontext"
)

// NewSession creates a new gopls session with the given cache.
func NewSession(ctx context.Context, c *Cache) *Session {
	index := atomic.AddInt64(&sessionIndex, 1)
	s := &Session{
		id:          strconv.FormatInt(index, 10),
		cache:       c,
		gocmdRunner: &gocommand.Runner{},
		overlayFS:   newOverlayFS(c),
		parseCache:  newParseCache(1 * time.Minute), // keep recently parsed files for a minute, to optimize typing CPU
		viewMap:     make(map[protocol.DocumentURI]*View),
	}
	event.Log(ctx, "New session", KeyCreateSession.Of(s))
	return s
}

// A Session holds the state (views, file contents, parse cache,
// memoized computations) of a gopls server process.
//
// It implements the file.Source interface.
type Session struct {
	// Unique identifier for this session.
	id string

	// Immutable attributes shared across views.
	cache       *Cache            // shared cache
	gocmdRunner *gocommand.Runner // limits go command concurrency

	viewMu  sync.Mutex
	views   []*View
	viewMap map[protocol.DocumentURI]*View // file->best view or nil; nil after shutdown; the key must be a clean uri.

	// snapshots is a counting semaphore that records the number
	// of unreleased snapshots associated with this session.
	// Shutdown waits for it to fall to zero.
	snapshotWG sync.WaitGroup

	parseCache *parseCache

	*overlayFS
}

// ID returns the unique identifier for this session on this server.
func (s *Session) ID() string     { return s.id }
func (s *Session) String() string { return s.id }

// GoCommandRunner returns the gocommand Runner for this session.
func (s *Session) GoCommandRunner() *gocommand.Runner {
	return s.gocmdRunner
}

// Shutdown the session and all views it has created.
func (s *Session) Shutdown(ctx context.Context) {
	var views []*View
	s.viewMu.Lock()
	views = append(views, s.views...)
	s.views = nil
	s.viewMap = nil
	s.viewMu.Unlock()
	for _, view := range views {
		view.shutdown()
	}
	s.parseCache.stop()
	s.snapshotWG.Wait() // wait for all work on associated snapshots to finish
	event.Log(ctx, "Shutdown session", KeyShutdownSession.Of(s))
}

// Cache returns the cache that created this session, for debugging only.
func (s *Session) Cache() *Cache {
	return s.cache
}

// TODO(rfindley): is the logic surrounding this error actually necessary?
var ErrViewExists = errors.New("view already exists for session")

// NewView creates a new View, returning it and its first snapshot. If a
// non-empty tempWorkspace directory is provided, the View will record a copy
// of its gopls workspace module in that directory, so that client tooling
// can execute in the same main module.  On success it also returns a release
// function that must be called when the Snapshot is no longer needed.
func (s *Session) NewView(ctx context.Context, folder *Folder) (*View, *Snapshot, func(), error) {
	s.viewMu.Lock()
	defer s.viewMu.Unlock()

	if s.viewMap == nil {
		return nil, nil, nil, fmt.Errorf("session is shut down")
	}

	// Querying the file system to check whether
	// two folders denote the same existing directory.
	if inode1, err := os.Stat(filepath.FromSlash(folder.Dir.Path())); err == nil {
		for _, view := range s.views {
			inode2, err := os.Stat(filepath.FromSlash(view.folder.Dir.Path()))
			if err == nil && os.SameFile(inode1, inode2) {
				return nil, nil, nil, ErrViewExists
			}
		}
	}

	def, err := defineView(ctx, s, folder, nil)
	if err != nil {
		return nil, nil, nil, err
	}
	view, snapshot, release := s.createView(ctx, def)
	s.views = append(s.views, view)
	s.viewMap[folder.Dir.Clean()] = view
	return view, snapshot, release, nil
}

// HasView checks whether the uri's view exists.
func (s *Session) HasView(uri protocol.DocumentURI) bool {
	uri = uri.Clean()
	s.viewMu.Lock()
	defer s.viewMu.Unlock()
	_, ok := s.viewMap[uri]
	return ok
}

// createView creates a new view, with an initial snapshot that retains the
// supplied context, detached from events and cancellation.
//
// The caller is responsible for calling the release function once.
func (s *Session) createView(ctx context.Context, def *viewDefinition) (*View, *Snapshot, func()) {
	index := atomic.AddInt64(&viewIndex, 1)

	// We want a true background context and not a detached context here
	// the spans need to be unrelated and no tag values should pollute it.
	baseCtx := event.Detach(xcontext.Detach(ctx))
	backgroundCtx, cancel := context.WithCancel(baseCtx)

	// Compute a skip function to use for module cache scanning.
	//
	// Note that unlike other filtering operations, we definitely don't want to
	// exclude the gomodcache here, even if it is contained in the workspace
	// folder.
	//
	// TODO(rfindley): consolidate with relPathExcludedByFilter(Func), Filterer,
	// View.filterFunc.
	var skipPath func(string) bool
	{
		// Compute a prefix match, respecting segment boundaries, by ensuring
		// the pattern (dir) has a trailing slash.
		dirPrefix := strings.TrimSuffix(string(def.folder.Dir), "/") + "/"
		pathIncluded := PathIncludeFunc(def.folder.Options.DirectoryFilters)
		skipPath = func(dir string) bool {
			uri := strings.TrimSuffix(string(protocol.URIFromPath(dir)), "/")
			// Note that the logic below doesn't handle the case where uri ==
			// v.folder.Dir, because there is no point in excluding the entire
			// workspace folder!
			if rel, ok := strings.CutPrefix(uri, dirPrefix); ok {
				return !pathIncluded(rel)
			}
			return false
		}
	}

	var ignoreFilter *ignoreFilter
	{
		var dirs []string
		if len(def.workspaceModFiles) == 0 {
			for _, entry := range filepath.SplitList(def.folder.Env.GOPATH) {
				dirs = append(dirs, filepath.Join(entry, "src"))
			}
		} else {
			dirs = append(dirs, def.folder.Env.GOMODCACHE)
			for m := range def.workspaceModFiles {
				dirs = append(dirs, m.DirPath())
			}
		}
		ignoreFilter = newIgnoreFilter(dirs)
	}

	var pe *imports.ProcessEnv
	{
		env := make(map[string]string)
		envSlice := slices.Concat(os.Environ(), def.folder.Options.EnvSlice(), []string{"GO111MODULE=" + def.adjustedGO111MODULE()})
		for _, kv := range envSlice {
			if k, v, ok := strings.Cut(kv, "="); ok {
				env[k] = v
			}
		}
		pe = &imports.ProcessEnv{
			GocmdRunner: s.gocmdRunner,
			BuildFlags:  slices.Clone(def.folder.Options.BuildFlags),
			// TODO(rfindley): an old comment said "processEnv operations should not mutate the modfile"
			// But shouldn't we honor the default behavior of mod vendoring?
			ModFlag:        "readonly",
			SkipPathInScan: skipPath,
			Env:            env,
			WorkingDir:     def.root.Path(),
			ModCache:       s.cache.modCache.dirCache(def.folder.Env.GOMODCACHE),
		}
		if def.folder.Options.VerboseOutput {
			pe.Logf = func(format string, args ...any) {
				event.Log(ctx, fmt.Sprintf(format, args...))
			}
		}
	}

	v := &View{
		id:                   strconv.FormatInt(index, 10),
		gocmdRunner:          s.gocmdRunner,
		initialWorkspaceLoad: make(chan struct{}),
		initializationSema:   make(chan struct{}, 1),
		baseCtx:              baseCtx,
		pkgIndex:             typerefs.NewPackageIndex(),
		parseCache:           s.parseCache,
		ignoreFilter:         ignoreFilter,
		fs:                   s.overlayFS,
		viewDefinition:       def,
		importsState:         newImportsState(backgroundCtx, s.cache.modCache, pe),
	}

	// Keep this in sync with golang.computeImportEdits.
	//
	// TODO(rfindley): encapsulate the imports state logic so that the handling
	// for Options.ImportsSource is in a single location.
	if def.folder.Options.ImportsSource == settings.ImportsSourceGopls {
		v.modcacheState = newModcacheState(def.folder.Env.GOMODCACHE)
	}

	s.snapshotWG.Add(1)
	v.snapshot = &Snapshot{
		view:              v,
		backgroundCtx:     backgroundCtx,
		cancel:            cancel,
		store:             s.cache.store,
		refcount:          1, // Snapshots are born referenced.
		done:              s.snapshotWG.Done,
		packages:          new(persistent.Map[PackageID, *packageHandle]),
		fullAnalysisKeys:  new(persistent.Map[PackageID, file.Hash]),
		factyAnalysisKeys: new(persistent.Map[PackageID, file.Hash]),
		meta:              new(metadata.Graph),
		files:             newFileMap(),
		shouldLoad:        new(persistent.Map[PackageID, []PackagePath]),
		unloadableFiles:   new(persistent.Set[protocol.DocumentURI]),
		parseModHandles:   new(persistent.Map[protocol.DocumentURI, *memoize.Promise]),
		parseWorkHandles:  new(persistent.Map[protocol.DocumentURI, *memoize.Promise]),
		modTidyHandles:    new(persistent.Map[protocol.DocumentURI, *memoize.Promise]),
		modVulnHandles:    new(persistent.Map[protocol.DocumentURI, *memoize.Promise]),
		modWhyHandles:     new(persistent.Map[protocol.DocumentURI, *memoize.Promise]),
		moduleUpgrades:    new(persistent.Map[protocol.DocumentURI, map[string]string]),
		vulns:             new(persistent.Map[protocol.DocumentURI, *vulncheck.Result]),
	}

	// Snapshots must observe all open files, as there are some caching
	// heuristics that change behavior depending on open files.
	for _, o := range s.overlayFS.Overlays() {
		_, _ = v.snapshot.ReadFile(ctx, o.URI())
	}

	// Record the environment of the newly created view in the log.
	event.Log(ctx, fmt.Sprintf("Created View (#%s)", v.id),
		label.Directory.Of(v.folder.Dir.Path()),
		viewTypeKey.Of(v.typ.String()),
		rootDirKey.Of(string(v.root)),
		goVersionKey.Of(strings.TrimRight(v.folder.Env.GoVersionOutput, "\n")),
		buildFlagsKey.Of(fmt.Sprint(v.folder.Options.BuildFlags)),
		envKey.Of(fmt.Sprintf("%+v", v.folder.Env)),
		envOverlayKey.Of(v.EnvOverlay()),
	)

	// Initialize the view without blocking.
	initCtx, initCancel := context.WithCancel(xcontext.Detach(ctx))
	v.cancelInitialWorkspaceLoad = initCancel
	snapshot := v.snapshot

	// Pass a second reference to the background goroutine.
	bgRelease := snapshot.Acquire()
	go func() {
		defer bgRelease()
		snapshot.initialize(initCtx, true)
	}()

	// Return a third reference to the caller.
	return v, snapshot, snapshot.Acquire()
}

// These keys are used to log view metadata in createView.
var (
	viewTypeKey   = keys.NewString("view_type", "")
	rootDirKey    = keys.NewString("root_dir", "")
	goVersionKey  = keys.NewString("go_version", "")
	buildFlagsKey = keys.New("build_flags", "")
	envKey        = keys.New("env", "")
	envOverlayKey = keys.New("env_overlay", "")
)

// RemoveView removes from the session the view rooted at the specified directory.
// It reports whether a view of that directory was removed.
func (s *Session) RemoveView(ctx context.Context, dir protocol.DocumentURI) bool {
	s.viewMu.Lock()
	defer s.viewMu.Unlock()

	if s.viewMap == nil {
		return false // Session is shutdown.
	}
	s.viewMap = make(map[protocol.DocumentURI]*View) // reset view associations

	var newViews []*View
	for _, view := range s.views {
		if view.folder.Dir == dir {
			view.shutdown()
		} else {
			newViews = append(newViews, view)
		}
	}
	removed := len(s.views) - len(newViews)
	if removed != 1 {
		// This isn't a bug report, because it could be a client-side bug.
		event.Error(ctx, "removing view", fmt.Errorf("removed %d views, want exactly 1", removed))
	}
	s.views = newViews
	return removed > 0
}

// View returns the view with a matching id, if present.
func (s *Session) View(id string) (*View, error) {
	s.viewMu.Lock()
	defer s.viewMu.Unlock()
	for _, view := range s.views {
		if view.ID() == id {
			return view, nil
		}
	}
	return nil, fmt.Errorf("no view with ID %q", id)
}

// SnapshotOf returns a Snapshot corresponding to the given URI.
//
// In the case where the file can be  can be associated with a View by
// [RelevantViews] (based on directory information alone, without package
// metadata), SnapshotOf returns the current Snapshot for that View. Otherwise,
// it awaits loading package metadata and returns a Snapshot for the first View
// containing a real (=not command-line-arguments) package for the file.
//
// If that also fails to find a View, SnapshotOf returns a Snapshot for the
// first view in s.views that is not shut down (i.e. s.views[0] unless we lose
// a race), for determinism in tests and so that we tend to aggregate the
// resulting command-line-arguments packages into a single view.
//
// SnapshotOf returns an error if a failure occurs along the way (most likely due
// to context cancellation), or if there are no Views in the Session.
//
// On success, the caller must call the returned function to release the snapshot.
func (s *Session) SnapshotOf(ctx context.Context, uri protocol.DocumentURI) (*Snapshot, func(), error) {
	uri = uri.Clean()
	// Fast path: if the uri has a static association with a view, return it.
	s.viewMu.Lock()
	v, err := s.viewOfLocked(ctx, uri)
	s.viewMu.Unlock()

	if err != nil {
		return nil, nil, err
	}

	if v != nil {
		snapshot, release, err := v.Snapshot()
		if err == nil {
			return snapshot, release, nil
		}
		// View is shut down. Forget this association.
		s.viewMu.Lock()
		if s.viewMap[uri] == v {
			delete(s.viewMap, uri)
		}
		s.viewMu.Unlock()
	}

	// Fall-back: none of the views could be associated with uri based on
	// directory information alone.
	//
	// Don't memoize the view association in viewMap, as it is not static: Views
	// may change as metadata changes.
	//
	// TODO(rfindley): we could perhaps optimize this case by peeking at existing
	// metadata before awaiting the load (after all, a load only adds metadata).
	// But that seems potentially tricky, when in the common case no loading
	// should be required.
	views := s.Views()
	for _, v := range views {
		snapshot, release, err := v.Snapshot()
		if err != nil {
			continue // view was shut down
		}
		// We don't check the error from awaitLoaded, because a load failure (that
		// doesn't result from context cancellation) should not prevent us from
		// continuing to search for the best view.
		_ = snapshot.awaitLoaded(ctx)
		g := snapshot.MetadataGraph()
		if ctx.Err() != nil {
			release()
			return nil, nil, ctx.Err()
		}
		// Special handling for the builtin file, since it doesn't have packages.
		if snapshot.IsBuiltin(uri) {
			return snapshot, release, nil
		}
		// Only match this view if it loaded a real package for the file.
		//
		// Any view can load a command-line-arguments package; aggregate those into
		// views[0] below.
		for _, pkg := range g.ForFile[uri] {
			if !metadata.IsCommandLineArguments(pkg.ID) || pkg.Standalone {
				return snapshot, release, nil
			}
		}
		release()
	}

	for _, v := range views {
		snapshot, release, err := v.Snapshot()
		if err == nil {
			return snapshot, release, nil // first valid snapshot
		}
	}
	return nil, nil, errNoViews
}

// FileOf returns the file for a given URI and its snapshot.
// On success, the returned function must be called to release the snapshot.
func (s *Session) FileOf(ctx context.Context, uri protocol.DocumentURI) (file.Handle, *Snapshot, func(), error) {
	snapshot, release, err := s.SnapshotOf(ctx, uri)
	if err != nil {
		return nil, nil, nil, err
	}
	fh, err := snapshot.ReadFile(ctx, uri)
	if err != nil {
		release()
		return nil, nil, nil, err
	}
	return fh, snapshot, release, nil
}

// errNoViews is sought by orphaned file diagnostics, to detect the case where
// we have no view containing a file.
var errNoViews = errors.New("no views")

// viewOfLocked evaluates the best view for uri, memoizing its result in
// s.viewMap.
//
// Precondition: caller holds s.viewMu lock; uri must be clean.
//
// May return (nil, nil) if no best view can be determined.
func (s *Session) viewOfLocked(ctx context.Context, uri protocol.DocumentURI) (*View, error) {
	if s.viewMap == nil {
		return nil, errors.New("session is shut down")
	}
	v, hit := s.viewMap[uri]
	if !hit {
		// Cache miss: compute (and memoize) the best view.
		fh, err := s.ReadFile(ctx, uri)
		if err != nil {
			return nil, err
		}
		relevantViews, err := RelevantViews(ctx, s, fh.URI(), s.views)
		if err != nil {
			return nil, err
		}
		v = matchingView(fh, relevantViews)
		if v == nil && len(relevantViews) > 0 {
			// If we have relevant views, but none of them matched the file's build
			// constraints, then we are still better off using one of them here.
			// Otherwise, logic may fall back to an inferior view, which lacks
			// relevant module information, leading to misleading diagnostics.
			// (as in golang/go#60776).
			v = relevantViews[0]
		}
		s.viewMap[uri] = v // may be nil
	}
	return v, nil
}

func (s *Session) Views() []*View {
	s.viewMu.Lock()
	defer s.viewMu.Unlock()
	result := make([]*View, len(s.views))
	copy(result, s.views)
	return result
}

// selectViewDefs constructs the best set of views covering the provided workspace
// folders and open files.
//
// This implements the zero-config algorithm of golang/go#57979.
func selectViewDefs(ctx context.Context, fs file.Source, folders []*Folder, openFiles []protocol.DocumentURI) ([]*viewDefinition, error) {
	var defs []*viewDefinition

	// First, compute a default view for each workspace folder.
	// TODO(golang/go#57979): technically, this is path dependent, since
	// DidChangeWorkspaceFolders could introduce a path-dependent ordering on
	// folders. We should keep folders sorted, or sort them here.
	for _, folder := range folders {
		def, err := defineView(ctx, fs, folder, nil)
		if err != nil {
			return nil, err
		}
		defs = append(defs, def)
	}

	// Next, ensure that the set of views covers all open files contained in a
	// workspace folder.
	//
	// We only do this for files contained in a workspace folder, because other
	// open files are most likely the result of jumping to a definition from a
	// workspace file; we don't want to create additional views in those cases:
	// they should be resolved after initialization.

	folderForFile := func(uri protocol.DocumentURI) *Folder {
		var longest *Folder
		for _, folder := range folders {
			// Check that this is a better match than longest, but not through a
			// vendor directory. Count occurrences of "/vendor/" as a quick check
			// that the vendor directory is between the folder and the file. Note the
			// addition of a trailing "/" to handle the odd case where the folder is named
			// vendor (which I hope is exceedingly rare in any case).
			//
			// Vendored packages are, by definition, part of an existing view.
			if (longest == nil || len(folder.Dir) > len(longest.Dir)) &&
				folder.Dir.Encloses(uri) &&
				strings.Count(string(uri), "/vendor/") == strings.Count(string(folder.Dir)+"/", "/vendor/") {

				longest = folder
			}
		}
		return longest
	}

checkFiles:
	for _, uri := range openFiles {
		folder := folderForFile(uri)
		if folder == nil || !folder.Options.ZeroConfig {
			continue // only guess views for open files
		}
		fh, err := fs.ReadFile(ctx, uri)
		if err != nil {
			return nil, err
		}
		relevantViews, err := RelevantViews(ctx, fs, fh.URI(), defs)
		if err != nil {
			// We should never call selectViewDefs with a cancellable context, so
			// this should never fail.
			return nil, bug.Errorf("failed to find best view for open file: %v", err)
		}
		def := matchingView(fh, relevantViews)
		if def != nil {
			continue // file covered by an existing view
		}
		def, err = defineView(ctx, fs, folder, fh)
		if err != nil {
			// e.g. folder path is invalid?
			return nil, fmt.Errorf("failed to define view for open file: %v", err)
		}
		// It need not strictly be the case that the best view for a file is
		// distinct from other views, as the logic of getViewDefinition and
		// [RelevantViews] does not align perfectly. This is not necessarily a bug:
		// there may be files for which we can't construct a valid view.
		//
		// Nevertheless, we should not create redundant views.
		for _, alt := range defs {
			if viewDefinitionsEqual(alt, def) {
				continue checkFiles
			}
		}
		defs = append(defs, def)
	}

	return defs, nil
}

// The viewDefiner interface allows the [RelevantViews] algorithm to operate on both
// Views and viewDefinitions.
type viewDefiner interface{ definition() *viewDefinition }

// RelevantViews returns the views that may contain the given URI, or nil if
// none exist. A view is "relevant" if, ignoring build constraints, it may have
// a workspace package containing uri. Therefore, the definition of relevance
// depends on the view type.
func RelevantViews[V viewDefiner](ctx context.Context, fs file.Source, uri protocol.DocumentURI, views []V) ([]V, error) {
	if len(views) == 0 {
		return nil, nil // avoid the call to findRootPattern
	}
	dir := uri.Dir()
	modURI, err := findRootPattern(ctx, dir, "go.mod", fs)
	if err != nil {
		return nil, err
	}

	// Prefer GoWork > GoMod > GOPATH > GoPackages > AdHoc.
	var (
		goPackagesViews []V // prefer longest
		workViews       []V // prefer longest
		modViews        []V // exact match
		gopathViews     []V // prefer longest
		adHocViews      []V // exact match
	)

	// pushView updates the views slice with the matching view v, using the
	// heuristic that views with a longer root are preferable. Accordingly,
	// pushView may be a no op if v's root is shorter than the roots in the views
	// slice.
	//
	// Invariant: the length of all roots in views is the same.
	pushView := func(views *[]V, v V) {
		if len(*views) == 0 {
			*views = []V{v}
			return
		}
		better := func(l, r V) bool {
			return len(l.definition().root) > len(r.definition().root)
		}
		existing := (*views)[0]
		switch {
		case better(existing, v):
		case better(v, existing):
			*views = []V{v}
		default:
			*views = append(*views, v)
		}
	}

	for _, view := range views {
		switch def := view.definition(); def.Type() {
		case GoPackagesDriverView:
			if def.root.Encloses(dir) {
				pushView(&goPackagesViews, view)
			}
		case GoWorkView:
			if _, ok := def.workspaceModFiles[modURI]; ok || uri == def.gowork {
				pushView(&workViews, view)
			}
		case GoModView:
			if _, ok := def.workspaceModFiles[modURI]; ok {
				modViews = append(modViews, view)
			}
		case GOPATHView:
			if def.root.Encloses(dir) {
				pushView(&gopathViews, view)
			}
		case AdHocView:
			if def.root == dir {
				adHocViews = append(adHocViews, view)
			}
		}
	}

	// Now that we've collected matching views, choose the best match,
	// considering ports.
	//
	// We only consider one type of view, since the matching view created by
	// defineView should be of the best type.
	var relevantViews []V
	switch {
	case len(workViews) > 0:
		relevantViews = workViews
	case len(modViews) > 0:
		relevantViews = modViews
	case len(gopathViews) > 0:
		relevantViews = gopathViews
	case len(goPackagesViews) > 0:
		relevantViews = goPackagesViews
	case len(adHocViews) > 0:
		relevantViews = adHocViews
	}

	return relevantViews, nil
}

// matchingView returns the View or viewDefinition out of relevantViews that
// matches the given file's build constraints, or nil if no match is found.
//
// Making this function generic is convenient so that we can avoid mapping view
// definitions back to views inside Session.DidModifyFiles, where performance
// matters. It is, however, not the cleanest application of generics.
//
// Note: keep this function in sync with defineView.
func matchingView[V viewDefiner](fh file.Handle, relevantViews []V) V {
	var zero V

	if len(relevantViews) == 0 {
		return zero
	}

	content, err := fh.Content()

	// Port matching doesn't apply to non-go files, or files that no longer exist.
	// Note that the behavior here on non-existent files shouldn't matter much,
	// since there will be a subsequent failure.
	if fileKind(fh) != file.Go || err != nil {
		return relevantViews[0]
	}

	// Find the first view that matches constraints.
	// Content trimming is nontrivial, so do this outside of the loop below.
	path := fh.URI().Path()
	content = trimContentForPortMatch(content)
	for _, v := range relevantViews {
		def := v.definition()
		viewPort := port{def.GOOS(), def.GOARCH()}
		if viewPort.matches(path, content) {
			return v
		}
	}

	return zero // no view found
}

// ResetView resets the best view for the given URI.
func (s *Session) ResetView(ctx context.Context, uri protocol.DocumentURI) (*View, error) {
	s.viewMu.Lock()
	defer s.viewMu.Unlock()

	if s.viewMap == nil {
		return nil, fmt.Errorf("session is shut down")
	}

	view, err := s.viewOfLocked(ctx, uri.Clean())
	if err != nil {
		return nil, err
	}
	if view == nil {
		return nil, fmt.Errorf("no view for %s", uri)
	}

	s.viewMap = make(map[protocol.DocumentURI]*View)
	for i, v := range s.views {
		if v == view {
			v2, _, release := s.createView(ctx, view.viewDefinition)
			release() // don't need the snapshot
			v.shutdown()
			s.views[i] = v2
			return v2, nil
		}
	}

	return nil, bug.Errorf("missing view") // can't happen...
}

// DidModifyFiles reports a file modification to the session. It returns
// the new snapshots after the modifications have been applied, paired with
// the affected file URIs for those snapshots.
// On success, it returns a release function that
// must be called when the snapshots are no longer needed.
//
// TODO(rfindley): what happens if this function fails? It must leave us in a
// broken state, which we should surface to the user, probably as a request to
// restart gopls.
func (s *Session) DidModifyFiles(ctx context.Context, modifications []file.Modification) (map[*View][]protocol.DocumentURI, error) {
	s.viewMu.Lock()
	defer s.viewMu.Unlock()

	// Short circuit the logic below if s is shut down.
	if s.viewMap == nil {
		return nil, fmt.Errorf("session is shut down")
	}

	// Update overlays.
	//
	// This is done while holding viewMu because the set of open files affects
	// the set of views, and to prevent views from seeing updated file content
	// before they have processed invalidations.
	replaced, err := s.updateOverlays(ctx, modifications)
	if err != nil {
		return nil, err
	}

	// checkViews controls whether the set of views needs to be recomputed, for
	// example because a go.mod file was created or deleted, or a go.work file
	// changed on disk.
	checkViews := false

	// Hack: collect folders from existing views.
	// TODO(golang/go#57979): we really should track folders independent of
	// Views, but since we always have a default View for each folder, this
	// works for now.
	var folders []*Folder // preserve folder order
	workspaceFileGlobsSet := make(map[string]bool)
	seen := make(map[*Folder]unit)
	for _, v := range s.views {
		if _, ok := seen[v.folder]; ok {
			continue
		}
		seen[v.folder] = unit{}
		folders = append(folders, v.folder)
		for _, glob := range v.folder.Options.WorkspaceFiles {
			workspaceFileGlobsSet[glob] = true
		}
	}
	workspaceFileGlobs := slices.Collect(maps.Keys(workspaceFileGlobsSet))

	changed := make(map[protocol.DocumentURI]file.Handle)
	for _, c := range modifications {
		fh := mustReadFile(ctx, s, c.URI)
		changed[c.URI] = fh

		// Any change to the set of open files causes views to be recomputed.
		if c.Action == file.Open || c.Action == file.Close {
			checkViews = true
		}

		// Any on-disk change to a go.work or go.mod file causes recomputing views.
		//
		// TODO(rfindley): go.work files need not be named "go.work" -- we need to
		// check each view's source to handle the case of an explicit GOWORK value.
		// Write a test that fails, and fix this.
		if (isGoWork(c.URI) || isGoMod(c.URI) || isWorkspaceFile(c.URI, workspaceFileGlobs)) && (c.Action == file.Save || c.OnDisk) {
			checkViews = true
		}

		// Any change to the set of supported ports in a file may affect view
		// selection. This is perhaps more subtle than it first seems: since the
		// algorithm for selecting views considers open files in a deterministic
		// order, a change in supported ports may cause a different port to be
		// chosen, even if all open files still match an existing View!
		//
		// We endeavor to avoid that sort of path dependence, so must re-run the
		// view selection algorithm whenever any input changes.
		//
		// However, extracting the build comment is nontrivial, so we don't want to
		// pay this cost when e.g. processing a bunch of on-disk changes due to a
		// branch change. Be careful to only do this if both files are open Go
		// files.
		if old, ok := replaced[c.URI]; ok && !checkViews && fileKind(fh) == file.Go {
			if new, ok := fh.(*overlay); ok {
				if buildComment(old.content) != buildComment(new.content) {
					checkViews = true
				}
			}
		}
	}

	if checkViews {
		var openFiles []protocol.DocumentURI
		for _, o := range s.Overlays() {
			openFiles = append(openFiles, o.URI())
		}
		// Sort for determinism.
		slices.Sort(openFiles)

		// TODO(rfindley): can we avoid running the go command (go env)
		// synchronously to change processing? Can we assume that the env did not
		// change, and derive go.work using a combination of the configured
		// GOWORK value and filesystem?
		defs, err := selectViewDefs(ctx, s, folders, openFiles)
		if err != nil {
			// Catastrophic failure, equivalent to a failure of session
			// initialization and therefore should almost never happen. One
			// scenario where this failure mode could occur is if some file
			// permissions have changed preventing us from reading go.mod
			// files.
			//
			// TODO(rfindley): consider surfacing this error more loudly. We
			// could report a bug, but it's not really a bug.
			event.Error(ctx, "selecting new views", err)
		} else {
			kept := make(map[*View]unit)
			var newViews []*View
			for _, def := range defs {
				var newView *View
				// Reuse existing view?
				for _, v := range s.views {
					if viewDefinitionsEqual(def, v.viewDefinition) {
						newView = v
						kept[v] = unit{}
						break
					}
				}
				if newView == nil {
					v, _, release := s.createView(ctx, def)
					release()
					newView = v
				}
				newViews = append(newViews, newView)
			}
			for _, v := range s.views {
				if _, ok := kept[v]; !ok {
					v.shutdown()
				}
			}
			s.views = newViews
			s.viewMap = make(map[protocol.DocumentURI]*View)
		}
	}

	// We only want to run fast-path diagnostics (i.e. diagnoseChangedFiles) once
	// for each changed file, in its best view.
	viewsToDiagnose := map[*View][]protocol.DocumentURI{}
	for _, mod := range modifications {
		v, err := s.viewOfLocked(ctx, mod.URI)
		if err != nil {
			// viewOfLocked only returns an error in the event of context
			// cancellation, or if the session is shut down. Since state changes
			// should occur on an uncancellable context, and s.viewMap was checked at
			// the top of this function, an error here is a bug.
			bug.Reportf("finding best view for change: %v", err)
			continue
		}
		if v != nil {
			viewsToDiagnose[v] = append(viewsToDiagnose[v], mod.URI)
		}
	}

	// ...but changes may be relevant to other views, for example if they are
	// changes to a shared package.
	for _, v := range s.views {
		_, release, needsDiagnosis := s.invalidateViewLocked(ctx, v, StateChange{Modifications: modifications, Files: changed})
		release()

		if needsDiagnosis || checkViews {
			if _, ok := viewsToDiagnose[v]; !ok {
				viewsToDiagnose[v] = nil
			}
		}
	}

	return viewsToDiagnose, nil
}

// ExpandModificationsToDirectories returns the set of changes with the
// directory changes removed and expanded to include all of the files in
// the directory.
func (s *Session) ExpandModificationsToDirectories(ctx context.Context, changes []file.Modification) []file.Modification {
	var snapshots []*Snapshot
	s.viewMu.Lock()
	for _, v := range s.views {
		snapshot, release, err := v.Snapshot()
		if err != nil {
			continue // view is shut down; continue with others
		}
		defer release()
		snapshots = append(snapshots, snapshot)
	}
	s.viewMu.Unlock()

	// Expand the modification to any file we could care about, which we define
	// to be any file observed by any of the snapshots.
	//
	// There may be other files in the directory, but if we haven't read them yet
	// we don't need to invalidate them.
	var result []file.Modification
	for _, c := range changes {
		expanded := make(map[protocol.DocumentURI]bool)
		for _, snapshot := range snapshots {
			for _, uri := range snapshot.filesInDir(c.URI) {
				expanded[uri] = true
			}
		}
		if len(expanded) == 0 {
			result = append(result, c)
		} else {
			for uri := range expanded {
				result = append(result, file.Modification{
					URI:        uri,
					Action:     c.Action,
					LanguageID: "",
					OnDisk:     c.OnDisk,
					// changes to directories cannot include text or versions
				})
			}
		}
	}
	return result
}

// updateOverlays updates the set of overlays and returns a map of any existing
// overlay values that were replaced.
//
// Precondition: caller holds s.viewMu lock.
// TODO(rfindley): move this to fs_overlay.go.
func (fs *overlayFS) updateOverlays(ctx context.Context, changes []file.Modification) (map[protocol.DocumentURI]*overlay, error) {
	fs.mu.Lock()
	defer fs.mu.Unlock()

	replaced := make(map[protocol.DocumentURI]*overlay)
	for _, c := range changes {
		o, ok := fs.overlays[c.URI]
		if ok {
			replaced[c.URI] = o
		}

		// If the file is not opened in an overlay and the change is on disk,
		// there's no need to update an overlay. If there is an overlay, we
		// may need to update the overlay's saved value.
		if !ok && c.OnDisk {
			continue
		}

		// Determine the file kind on open, otherwise, assume it has been cached.
		var kind file.Kind
		switch c.Action {
		case file.Open:
			kind = file.KindForLang(c.LanguageID)
		default:
			if !ok {
				return nil, fmt.Errorf("updateOverlays: modifying unopened overlay %v", c.URI)
			}
			kind = o.kind
		}

		// Closing a file just deletes its overlay.
		if c.Action == file.Close {
			delete(fs.overlays, c.URI)
			continue
		}

		// If the file is on disk, check if its content is the same as in the
		// overlay. Saves and on-disk file changes don't come with the file's
		// content.
		text := c.Text
		if text == nil && (c.Action == file.Save || c.OnDisk) {
			if !ok {
				return nil, fmt.Errorf("no known content for overlay for %s", c.Action)
			}
			text = o.content
		}
		// On-disk changes don't come with versions.
		version := c.Version
		if c.OnDisk || c.Action == file.Save {
			version = o.version
		}
		hash := file.HashOf(text)
		var sameContentOnDisk bool
		switch c.Action {
		case file.Delete:
			// Do nothing. sameContentOnDisk should be false.
		case file.Save:
			// Make sure the version and content (if present) is the same.
			if false && o.version != version { // Client no longer sends the version
				return nil, fmt.Errorf("updateOverlays: saving %s at version %v, currently at %v", c.URI, c.Version, o.version)
			}
			if c.Text != nil && o.hash != hash {
				return nil, fmt.Errorf("updateOverlays: overlay %s changed on save", c.URI)
			}
			sameContentOnDisk = true
		default:
			fh := mustReadFile(ctx, fs.delegate, c.URI)
			_, readErr := fh.Content()
			sameContentOnDisk = (readErr == nil && fh.Identity().Hash == hash)
		}
		o = &overlay{
			uri:     c.URI,
			version: version,
			content: text,
			modTime: time.Now(),
			kind:    kind,
			hash:    hash,
			saved:   sameContentOnDisk,
		}

		// NOTE: previous versions of this code checked here that the overlay had a
		// view and file kind (but we don't know why).

		fs.overlays[c.URI] = o
	}

	return replaced, nil
}

func mustReadFile(ctx context.Context, fs file.Source, uri protocol.DocumentURI) file.Handle {
	ctx = xcontext.Detach(ctx)
	fh, err := fs.ReadFile(ctx, uri)
	if err != nil {
		// ReadFile cannot fail with an uncancellable context.
		bug.Reportf("reading file failed unexpectedly: %v", err)
		return brokenFile{uri, err}
	}
	return fh
}

// A brokenFile represents an unexpected failure to read a file.
type brokenFile struct {
	uri protocol.DocumentURI
	err error
}

func (b brokenFile) String() string              { return b.uri.Path() }
func (b brokenFile) URI() protocol.DocumentURI   { return b.uri }
func (b brokenFile) Identity() file.Identity     { return file.Identity{URI: b.uri} }
func (b brokenFile) SameContentsOnDisk() bool    { return false }
func (b brokenFile) Version() int32              { return 0 }
func (b brokenFile) Content() ([]byte, error)    { return nil, b.err }
func (b brokenFile) ModTime() (time.Time, error) { return time.Time{}, b.err }

// FileWatchingGlobPatterns returns a set of glob patterns that the client is
// required to watch for changes, and notify the server of them, in order to
// keep the server's state up to date.
//
// This set includes
//  1. all go.mod and go.work files in the workspace; and
//  2. all files defined by the WorkspaceFiles option in BuildOptions (to support custom GOPACKAGESDRIVERS); and
//  3. for each Snapshot, its modules (or directory for ad-hoc views). In
//     module mode, this is the set of active modules (and for VS Code, all
//     workspace directories within them, due to golang/go#42348).
//
// The watch for workspace files in (1) is sufficient to
// capture changes to the repo structure that may affect the set of views.
// Whenever this set changes, we reload the workspace and invalidate memoized
// files.
//
// The watch for workspace directories in (2) should keep each View up to date,
// as it should capture any newly added/modified/deleted Go files.
//
// Patterns are returned as a set of protocol.RelativePatterns, since they can
// always be later translated to glob patterns (i.e. strings) if the client
// lacks relative pattern support. By convention, any pattern returned with
// empty baseURI should be served as a glob pattern.
//
// In general, we prefer to serve relative patterns, as they work better on
// most clients that support both, and do not have issues with Windows driver
// letter casing:
// https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#relativePattern
//
// TODO(golang/go#57979): we need to reset the memoizedFS when a view changes.
// Consider the case where we incidentally read a file, then it moved outside
// of an active module, and subsequently changed: we would still observe the
// original file state.
func (s *Session) FileWatchingGlobPatterns(ctx context.Context) map[protocol.RelativePattern]unit {
	s.viewMu.Lock()
	defer s.viewMu.Unlock()

	// Always watch files that may change the set of views.
	patterns := map[protocol.RelativePattern]unit{
		{Pattern: "**/*.{mod,work}"}: {},
	}

	for _, view := range s.views {
		snapshot, release, err := view.Snapshot()
		if err != nil {
			continue // view is shut down; continue with others
		}
		maps.Copy(patterns, snapshot.fileWatchingGlobPatterns())
		release()
	}
	return patterns
}

// OrphanedFileDiagnostics reports diagnostics describing why open files have
// no packages or have only command-line-arguments packages.
//
// If the resulting diagnostic is nil, the file is either not orphaned or we
// can't produce a good diagnostic.
//
// The caller must not mutate the result.
func (s *Session) OrphanedFileDiagnostics(ctx context.Context) (map[protocol.DocumentURI][]*Diagnostic, error) {
	if err := ctx.Err(); err != nil {
		// Avoid collecting diagnostics if the context is cancelled.
		// (Previously, it was possible to get all the way to packages.Load on a cancelled context)
		return nil, err
	}
	// Note: diagnostics holds a slice for consistency with other diagnostic
	// funcs.
	diagnostics := make(map[protocol.DocumentURI][]*Diagnostic)

	byView := make(map[*View][]*overlay)
	for _, o := range s.Overlays() {
		uri := o.URI()
		snapshot, release, err := s.SnapshotOf(ctx, uri)
		if err != nil {
			// TODO(golang/go#57979): we have to use the .go suffix as an approximation for
			// file kind here, because we don't have access to Options if no View was
			// matched.
			//
			// But Options are really a property of Folder, not View, and we could
			// match a folder here.
			//
			// Refactor so that Folders are tracked independently of Views, and use
			// the correct options here to get the most accurate file kind.
			//
			// TODO(golang/go#57979): once we switch entirely to the zeroconfig
			// logic, we should use this diagnostic for the fallback case of
			// s.views[0] in the ViewOf logic.
			if errors.Is(err, errNoViews) {
				if strings.HasSuffix(string(uri), ".go") {
					if _, rng, ok := orphanedFileDiagnosticRange(ctx, s.parseCache, o); ok {
						diagnostics[uri] = []*Diagnostic{{
							URI:      uri,
							Range:    rng,
							Severity: protocol.SeverityWarning,
							Source:   ListError,
							Message:  fmt.Sprintf("No active builds contain %s: consider opening a new workspace folder containing it", uri.Path()),
						}}
					}
				}
				continue
			}
			return nil, err
		}
		v := snapshot.View()
		release()
		byView[v] = append(byView[v], o)
	}

	for view, overlays := range byView {
		snapshot, release, err := view.Snapshot()
		if err != nil {
			continue // view is shutting down
		}
		defer release()
		diags, err := snapshot.orphanedFileDiagnostics(ctx, overlays)
		if err != nil {
			return nil, err
		}
		for _, d := range diags {
			diagnostics[d.URI] = append(diagnostics[d.URI], d)
		}
	}
	return diagnostics, nil
}
