internal/lsp/cache: parse files with ParseFull mode to check if metadata reload is required

ParseHeader mode is used to parse only the package and import declarations.
However, change of go:embed directive should also invalidate metadata.
So, we must use ParseFull mode to get all file comments to compare
old and new go:embed directives.

Fixes golang/go#47436

Change-Id: If7cdb6741e895315bb6a6de2f207b404e15b269a
GitHub-Last-Rev: 64d606cead064ed5996eb7d55c3664940e7a1deb
GitHub-Pull-Request: golang/tools#333
Reviewed-on: https://go-review.googlesource.com/c/tools/+/339469
Reviewed-by: Rebecca Stambler <rstambler@golang.org>
Trust: Rebecca Stambler <rstambler@golang.org>
Trust: Robert Findley <rfindley@google.com>
Run-TryBot: Rebecca Stambler <rstambler@golang.org>
gopls-CI: kokoro <noreply+kokoro@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
diff --git a/gopls/internal/regtest/misc/embed_test.go b/gopls/internal/regtest/misc/embed_test.go
index 8fb654b..2e66d78 100644
--- a/gopls/internal/regtest/misc/embed_test.go
+++ b/gopls/internal/regtest/misc/embed_test.go
@@ -22,6 +22,9 @@
 	_ "embed"
 )
 
+// Issue 47436
+func F() {}
+
 //go:embed NONEXISTENT
 var foo string
 `
diff --git a/internal/lsp/cache/snapshot.go b/internal/lsp/cache/snapshot.go
index 4f1bf19..6ea3aa5 100644
--- a/internal/lsp/cache/snapshot.go
+++ b/internal/lsp/cache/snapshot.go
@@ -2042,8 +2042,8 @@
 	return !o.saved && c.saved
 }
 
-// shouldInvalidateMetadata reparses a file's package and import declarations to
-// determine if the file requires a metadata reload.
+// shouldInvalidateMetadata reparses the full file's AST to determine
+// if the file requires a metadata reload.
 func (s *snapshot) shouldInvalidateMetadata(ctx context.Context, newSnapshot *snapshot, originalFH, currentFH source.FileHandle) (invalidate, pkgNameChanged, importDeleted bool) {
 	if originalFH == nil {
 		return true, false, false
@@ -2055,8 +2055,8 @@
 	// Get the original and current parsed files in order to check package name
 	// and imports. Use the new snapshot to parse to avoid modifying the
 	// current snapshot.
-	original, originalErr := newSnapshot.ParseGo(ctx, originalFH, source.ParseHeader)
-	current, currentErr := newSnapshot.ParseGo(ctx, currentFH, source.ParseHeader)
+	original, originalErr := newSnapshot.ParseGo(ctx, originalFH, source.ParseFull)
+	current, currentErr := newSnapshot.ParseGo(ctx, currentFH, source.ParseFull)
 	if originalErr != nil || currentErr != nil {
 		return (originalErr == nil) != (currentErr == nil), false, (currentErr != nil) // we don't know if an import was deleted
 	}