internal/lsp: avoid diagnosing unopened non-workspace packages

This fixes an issue where we were reloading packages in the vendor
directory when they changed on-disk. We should only do this if the
packages are part of the workspace or the files are opened.

Change-Id: Iefbd690ec0c096d9a40c62ce567c18335024ea15
Reviewed-on: https://go-review.googlesource.com/c/tools/+/268038
Trust: Rebecca Stambler <rstambler@golang.org>
Run-TryBot: Rebecca Stambler <rstambler@golang.org>
gopls-CI: kokoro <noreply+kokoro@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Robert Findley <rfindley@google.com>
(cherry picked from commit 169ad6d6ecb228fea640e4aadaa45093069211af)
Reviewed-on: https://go-review.googlesource.com/c/tools/+/268657
diff --git a/internal/lsp/command.go b/internal/lsp/command.go
index a622329..20ae57f 100644
--- a/internal/lsp/command.go
+++ b/internal/lsp/command.go
@@ -235,7 +235,7 @@
 		}
 		snapshot, release := sv.Snapshot(ctx)
 		defer release()
-		s.diagnoseSnapshot(snapshot, nil)
+		s.diagnoseSnapshot(snapshot, nil, false)
 	case source.CommandGenerateGoplsMod:
 		var v source.View
 		if len(args) == 0 {
diff --git a/internal/lsp/diagnostics.go b/internal/lsp/diagnostics.go
index f878108..c54bdaa 100644
--- a/internal/lsp/diagnostics.go
+++ b/internal/lsp/diagnostics.go
@@ -82,7 +82,7 @@
 	s.publishReports(ctx, snapshot, reports, false)
 }
 
-func (s *Server) diagnoseSnapshot(snapshot source.Snapshot, changedURIs []span.URI) {
+func (s *Server) diagnoseSnapshot(snapshot source.Snapshot, changedURIs []span.URI, onDisk bool) {
 	ctx := snapshot.View().BackgroundContext()
 
 	delay := snapshot.View().Options().ExperimentalDiagnosticsDelay
@@ -93,7 +93,7 @@
 		// by file modifications (no analysis).
 		//
 		// The second phase does everything, and is debounced by the configured delay.
-		reports, err := s.diagnoseChangedFiles(ctx, snapshot, changedURIs)
+		reports, err := s.diagnoseChangedFiles(ctx, snapshot, changedURIs, onDisk)
 		if err != nil {
 			if !errors.Is(err, context.Canceled) {
 				event.Error(ctx, "diagnosing changed files", err)
@@ -112,11 +112,16 @@
 	s.publishReports(ctx, snapshot, reports, false)
 }
 
-func (s *Server) diagnoseChangedFiles(ctx context.Context, snapshot source.Snapshot, uris []span.URI) (*reportSet, error) {
+func (s *Server) diagnoseChangedFiles(ctx context.Context, snapshot source.Snapshot, uris []span.URI, onDisk bool) (*reportSet, error) {
 	ctx, done := event.Start(ctx, "Server.diagnoseChangedFiles")
 	defer done()
 	packages := make(map[source.Package]struct{})
 	for _, uri := range uris {
+		// If the change is only on-disk and the file is not open, don't
+		// directly request its package. It may not be a workspace package.
+		if onDisk && !snapshot.IsOpen(uri) {
+			continue
+		}
 		pkgs, err := snapshot.PackagesForFile(ctx, uri, source.TypecheckWorkspace)
 		if err != nil {
 			// TODO (rFindley): we should probably do something with the error here,
diff --git a/internal/lsp/text_synchronization.go b/internal/lsp/text_synchronization.go
index 205331d..fc35ff5 100644
--- a/internal/lsp/text_synchronization.go
+++ b/internal/lsp/text_synchronization.go
@@ -236,7 +236,7 @@
 		diagnosticWG.Add(1)
 		go func(snapshot source.Snapshot, uris []span.URI) {
 			defer diagnosticWG.Done()
-			s.diagnoseSnapshot(snapshot, uris)
+			s.diagnoseSnapshot(snapshot, uris, cause == FromDidChangeWatchedFiles)
 		}(snapshot, uris)
 	}