internal/lsp: await the initial workspace load in ModHandle

ModHandle races with the initial workspace load if the go.mod file does
not yet exist. We should await for the initial workspace load to
complete before proceeding with update codelenses, etc.

Part of trying to figure out the flakes in golang/go#39504.
Also a few staticcheck fixes, and fix the Windows line endings in
fill_struct.go, because `git gofmt` complains.

Change-Id: Ide21a47137390792d1afb924740cff0bb6f0b764
Reviewed-on: https://go-review.googlesource.com/c/tools/+/237419
Run-TryBot: Rebecca Stambler <rstambler@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Heschi Kreinick <heschi@google.com>
diff --git a/internal/lsp/cache/mod.go b/internal/lsp/cache/mod.go
index 1fb4413..abbd98b 100644
--- a/internal/lsp/cache/mod.go
+++ b/internal/lsp/cache/mod.go
@@ -128,12 +128,14 @@
 	return data.origParsedFile, data.origMapper, data.why, data.err
 }
 
-func (s *snapshot) ModHandle(ctx context.Context, fh source.FileHandle) source.ModHandle {
+func (s *snapshot) ModHandle(ctx context.Context, fh source.FileHandle) (source.ModHandle, error) {
+	if err := s.awaitLoaded(ctx); err != nil {
+		return nil, err
+	}
 	uri := fh.URI()
 	if handle := s.getModHandle(uri); handle != nil {
-		return handle
+		return handle, nil
 	}
-
 	realURI, tempURI := s.view.ModFiles()
 	folder := s.View().Folder().Filename()
 	cfg := s.Config(ctx)
@@ -202,7 +204,7 @@
 		file:   fh,
 		cfg:    cfg,
 	}
-	return s.modHandles[uri]
+	return s.modHandles[uri], nil
 }
 
 func goModWhy(ctx context.Context, cfg *packages.Config, folder string, data *modData) error {
diff --git a/internal/lsp/link.go b/internal/lsp/link.go
index 73865bd..ea09d76 100644
--- a/internal/lsp/link.go
+++ b/internal/lsp/link.go
@@ -46,7 +46,11 @@
 func modLinks(ctx context.Context, snapshot source.Snapshot, fh source.FileHandle) ([]protocol.DocumentLink, error) {
 	view := snapshot.View()
 
-	file, m, err := snapshot.ModHandle(ctx, fh).Parse(ctx)
+	mh, err := snapshot.ModHandle(ctx, fh)
+	if err != nil {
+		return nil, err
+	}
+	file, m, err := mh.Parse(ctx)
 	if err != nil {
 		return nil, err
 	}
diff --git a/internal/lsp/mod/code_lens.go b/internal/lsp/mod/code_lens.go
index 8f117dc..9948882 100644
--- a/internal/lsp/mod/code_lens.go
+++ b/internal/lsp/mod/code_lens.go
@@ -33,7 +33,11 @@
 	if err != nil {
 		return nil, err
 	}
-	f, m, upgrades, err := snapshot.ModHandle(ctx, fh).Upgrades(ctx)
+	mh, err := snapshot.ModHandle(ctx, fh)
+	if err != nil {
+		return nil, err
+	}
+	f, m, upgrades, err := mh.Upgrades(ctx)
 	if err != nil {
 		return nil, err
 	}
diff --git a/internal/lsp/mod/format.go b/internal/lsp/mod/format.go
index a635cb8..4aaf8ae 100644
--- a/internal/lsp/mod/format.go
+++ b/internal/lsp/mod/format.go
@@ -12,7 +12,11 @@
 	ctx, done := event.Start(ctx, "mod.Format")
 	defer done()
 
-	file, m, err := snapshot.ModHandle(ctx, fh).Parse(ctx)
+	mh, err := snapshot.ModHandle(ctx, fh)
+	if err != nil {
+		return nil, err
+	}
+	file, m, err := mh.Parse(ctx)
 	if err != nil {
 		return nil, err
 	}
diff --git a/internal/lsp/mod/hover.go b/internal/lsp/mod/hover.go
index 97d3dd3..f437c7c 100644
--- a/internal/lsp/mod/hover.go
+++ b/internal/lsp/mod/hover.go
@@ -23,7 +23,11 @@
 	ctx, done := event.Start(ctx, "mod.Hover")
 	defer done()
 
-	file, m, why, err := snapshot.ModHandle(ctx, fh).Why(ctx)
+	mh, err := snapshot.ModHandle(ctx, fh)
+	if err != nil {
+		return nil, err
+	}
+	file, m, why, err := mh.Why(ctx)
 	if err != nil {
 		return nil, err
 	}
diff --git a/internal/lsp/source/fill_struct.go b/internal/lsp/source/fill_struct.go
index e44c53b..f7fa001 100644
--- a/internal/lsp/source/fill_struct.go
+++ b/internal/lsp/source/fill_struct.go
@@ -17,7 +17,6 @@
 
 // FillStruct completes all of targeted struct's fields with their default values.
 func FillStruct(ctx context.Context, snapshot Snapshot, fh FileHandle, protoRng protocol.Range) ([]protocol.CodeAction, error) {
-
 	pkg, pgh, err := getParsedFile(ctx, snapshot, fh, NarrowestPackageHandle)
 	if err != nil {
 		return nil, fmt.Errorf("getting file for struct fill code action: %v", err)
diff --git a/internal/lsp/source/view.go b/internal/lsp/source/view.go
index d60e37c..f1649e5 100644
--- a/internal/lsp/source/view.go
+++ b/internal/lsp/source/view.go
@@ -54,7 +54,7 @@
 
 	// ModHandle returns a ModHandle for the passed in go.mod file handle.
 	// This function can have no data if there is no modfile detected.
-	ModHandle(ctx context.Context, fh FileHandle) ModHandle
+	ModHandle(ctx context.Context, fh FileHandle) (ModHandle, error)
 
 	// PackageHandles returns the PackageHandles for the packages that this file
 	// belongs to.