internal/lsp/cache: validate the range for critical errors in go files

This avoids the panic reported in golang/go#54395.

Fixes golang/go#54395

Change-Id: Ief35985a503d3cc13971499dc6f4e9c1d1d63ea3
Reviewed-on: https://go-review.googlesource.com/c/tools/+/422894
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Suzy Mueller <suzmue@golang.org>
gopls-CI: kokoro <noreply+kokoro@google.com>
Run-TryBot: Robert Findley <rfindley@google.com>
diff --git a/gopls/internal/regtest/workspace/broken_test.go b/gopls/internal/regtest/workspace/broken_test.go
index fbc41de..b06c155 100644
--- a/gopls/internal/regtest/workspace/broken_test.go
+++ b/gopls/internal/regtest/workspace/broken_test.go
@@ -186,6 +186,8 @@
 go 1.12
 -- a/a.go --
 package a
+-- a/empty.go --
+// an empty file
 -- b/go.mod --
 module b.com
 
@@ -202,6 +204,7 @@
 				ver := env.GoVersion()
 				msg := msgForVersion(ver)
 				env.OpenFile("a/a.go")
+				env.OpenFile("a/empty.go")
 				env.OpenFile("b/go.mod")
 				env.Await(
 					env.DiagnosticAtRegexp("a/a.go", "package a"),
diff --git a/internal/lsp/cache/load.go b/internal/lsp/cache/load.go
index 7f30939..b15c537 100644
--- a/internal/lsp/cache/load.go
+++ b/internal/lsp/cache/load.go
@@ -380,9 +380,12 @@
 		switch s.view.FileKind(fh) {
 		case source.Go:
 			if pgf, err := s.ParseGo(ctx, fh, source.ParseHeader); err == nil {
-				pkgDecl := span.NewRange(pgf.Tok, pgf.File.Package, pgf.File.Name.End())
-				if spn, err := pkgDecl.Span(); err == nil {
-					rng, _ = pgf.Mapper.Range(spn)
+				// Check that we have a valid `package foo` range to use for positioning the error.
+				if pgf.File.Package.IsValid() && pgf.File.Name != nil && pgf.File.Name.End().IsValid() {
+					pkgDecl := span.NewRange(pgf.Tok, pgf.File.Package, pgf.File.Name.End())
+					if spn, err := pkgDecl.Span(); err == nil {
+						rng, _ = pgf.Mapper.Range(spn)
+					}
 				}
 			}
 		case source.Mod: