internal/lsp: support build flags on processConfig

Add 'buildFlags' config to processConfig and pass that value to packages.Config.
We can avoid incorrect diagnostics such as if current source codes require any build tags.

Change-Id: Id191469ec75eedaa82b75ec4fdec084fa78c2c5d
Reviewed-on: https://go-review.googlesource.com/c/tools/+/178782
Reviewed-by: Rebecca Stambler <rstambler@golang.org>
Run-TryBot: Rebecca Stambler <rstambler@golang.org>
diff --git a/internal/lsp/cache/view.go b/internal/lsp/cache/view.go
index 2aef223..e18db6b 100644
--- a/internal/lsp/cache/view.go
+++ b/internal/lsp/cache/view.go
@@ -48,6 +48,9 @@
 	// env is the environment to use when invoking underlying tools.
 	env []string
 
+	// buildFlags is the build flags to use when invoking underlying tools.
+	buildFlags []string
+
 	// keep track of files by uri and by basename, a single file may be mapped
 	// to multiple uris, and the same basename may map to multiple files
 	filesByURI  map[span.URI]viewFile
@@ -119,9 +122,10 @@
 		folderPath = ""
 	}
 	return &packages.Config{
-		Context: v.backgroundCtx,
-		Dir:     folderPath,
-		Env:     v.env,
+		Context:    v.backgroundCtx,
+		Dir:        folderPath,
+		Env:        v.env,
+		BuildFlags: v.buildFlags,
 		Mode: packages.NeedName |
 			packages.NeedFiles |
 			packages.NeedCompiledGoFiles |
@@ -148,6 +152,12 @@
 	v.env = env
 }
 
+func (v *view) SetBuildFlags(buildFlags []string) {
+	v.mu.Lock()
+	defer v.mu.Unlock()
+	v.buildFlags = buildFlags
+}
+
 func (v *view) Shutdown(ctx context.Context) {
 	v.session.removeView(ctx, v)
 }
diff --git a/internal/lsp/general.go b/internal/lsp/general.go
index 8ddbe59..0964de7 100644
--- a/internal/lsp/general.go
+++ b/internal/lsp/general.go
@@ -167,6 +167,18 @@
 		}
 		view.SetEnv(env)
 	}
+	// Get the build flags for the go/packages config.
+	if buildFlags := c["buildFlags"]; buildFlags != nil {
+		iflags, ok := buildFlags.([]interface{})
+		if !ok {
+			return fmt.Errorf("invalid config gopls.buildFlags type %T", buildFlags)
+		}
+		flags := make([]string, 0, len(iflags))
+		for _, flag := range iflags {
+			flags = append(flags, fmt.Sprintf("%s", flag))
+		}
+		view.SetBuildFlags(flags)
+	}
 	// Check if placeholders are enabled.
 	if usePlaceholders, ok := c["usePlaceholders"].(bool); ok {
 		s.usePlaceholders = usePlaceholders
diff --git a/internal/lsp/source/view.go b/internal/lsp/source/view.go
index 9091646..8f7ce8c 100644
--- a/internal/lsp/source/view.go
+++ b/internal/lsp/source/view.go
@@ -129,6 +129,9 @@
 	// SetEnv is used to adjust the environment applied to the view.
 	SetEnv([]string)
 
+	// SetBuildFlags is used to adjust the build flags applied to the view.
+	SetBuildFlags([]string)
+
 	// Shutdown closes this view, and detaches it from it's session.
 	Shutdown(ctx context.Context)