[engine] Prohibit forking without locking

Calling the `os/exec.Cmd` functions `Run()` or `Start()` without locking
the R/W mutex used to write the nsjail executable causes test flakiness;
see docstring of the command package for more details.

So extract a library that forks safely, and add a check that no unsafe
forks are done.

Change-Id: I926654d38f66fb614e39db5a7d9c3e1e43ebeb4a
Reviewed-on: https://fuchsia-review.googlesource.com/c/shac-project/shac/+/904660
Fuchsia-Auto-Submit: Oliver Newman <olivernewman@google.com>
Commit-Queue: Oliver Newman <olivernewman@google.com>
Reviewed-by: Marc-Antoine Ruel <maruel@google.com>
diff --git a/checks/go.star b/checks/go.star
index fb1c646..063061a 100644
--- a/checks/go.star
+++ b/checks/go.star
@@ -208,6 +208,47 @@
 shadow = shac.check(_shadow)
 
 
+def no_fork_without_lock(ctx):
+  """Checks that exec.Command Start() and Run() aren't called directly.
+
+  Instead, callers should use the `execsupport` package, which provides appropriate
+  locks to make sure forks are safe.
+
+  Args:
+    ctx: A ctx instance.
+  """
+  output = json.decode(ctx.os.exec(
+    [
+      "go",
+      "run",
+      "./internal/go_checks/fork_check",
+      "-test=false",
+      "-json",
+      "./...",
+    ],
+    env=_go_env(ctx, "no_fork_without_lock")
+  ).wait().stdout)
+
+  # Skip the "execsupport" package since it contains the wrappers around Run()
+  # and Start() that should be used. But if it's not present in the output,
+  # that's a
+  # good sign that the check is broken.
+  if not output.pop("go.fuchsia.dev/shac-project/shac/internal/execsupport", None):
+    fail("execsupport package was not found in the output, fork_check may be buggy")
+
+  for checks in output.values():
+    for findings in checks.values():
+      for finding in findings:
+        match = ctx.re.match(r"^%s/(.+):(\d+):(\d+)$" % ctx.scm.root, finding["posn"])
+        ctx.emit.finding(
+          level="error",
+          filepath=match.groups[1],
+          line=int(match.groups[2]),
+          col=int(match.groups[3]),
+          message=finding["message"],
+        )
+
+
 def _go_install(ctx, pkg, version):
   tool_name = pkg.split("/")[-1]
   env = _go_env(ctx, tool_name)
diff --git a/cmd/fork_check/main.go b/cmd/fork_check/main.go
new file mode 100644
index 0000000..56eb61c
--- /dev/null
+++ b/cmd/fork_check/main.go
@@ -0,0 +1,81 @@
+// Copyright 2023 The Shac Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Package main implements a check that the os/exec.Cmd Start() and Run()
+// functions aren't called directly.
+//
+// Instead, callers should use the execsupport package.
+package main
+
+import (
+	"go/ast"
+
+	"golang.org/x/tools/go/analysis"
+	"golang.org/x/tools/go/analysis/multichecker"
+)
+
+func run(pass *analysis.Pass) (any, error) {
+	for _, f := range pass.Files {
+		ast.Inspect(f, func(n ast.Node) bool {
+			if n == nil {
+				return false
+			}
+			call, ok := n.(*ast.CallExpr)
+			if !ok {
+				return true
+			}
+			selector, ok := call.Fun.(*ast.SelectorExpr)
+			if !ok {
+				return true
+			}
+			funcName := selector.Sel.Name
+			if funcName != "Start" && funcName != "Run" {
+				return true
+			}
+
+			var obj *ast.Ident
+			switch o := selector.X.(type) {
+			case *ast.Ident:
+				obj = o
+			case *ast.SelectorExpr:
+				obj = o.Sel
+			default:
+				return true
+			}
+
+			// Skip function calls that aren't struct methods.
+			if obj == nil {
+				return true
+			}
+
+			typ := pass.TypesInfo.ObjectOf(obj).Type()
+			if typ.String() == "*os/exec.Cmd" {
+				pass.Reportf(n.Pos(), "do not call %s.%s() directly, use execsupport.%s(%s) instead",
+					obj.Name, funcName, funcName, obj.Name)
+			}
+			return false
+		})
+	}
+	return nil, nil
+}
+
+func main() {
+	multichecker.Main(
+		&analysis.Analyzer{
+			Name: "directexec",
+			Doc:  "do not call os/exec.Cmd Start or Run functions directly",
+			Run:  run,
+		},
+	)
+}
diff --git a/go.mod b/go.mod
index 7ecbd43..4e913cc 100644
--- a/go.mod
+++ b/go.mod
@@ -41,6 +41,7 @@
 	golang.org/x/net v0.11.0 // indirect
 	golang.org/x/sys v0.9.0 // indirect
 	golang.org/x/text v0.10.0 // indirect
+	golang.org/x/tools v0.7.0 // indirect
 	google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 // indirect
 	google.golang.org/grpc v1.54.0 // indirect
 	gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect
diff --git a/go.sum b/go.sum
index 5be4015..a7ac2c3 100644
--- a/go.sum
+++ b/go.sum
@@ -153,6 +153,8 @@
 golang.org/x/tools v0.0.0-20190729092621-ff9f1409240a/go.mod h1:jcCCGcm9btYwXyDqrUWc6MKQKKGJCWEQ3AfLSRIbEuI=
 golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
 golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
+golang.org/x/tools v0.7.0 h1:W4OVu8VVOaIO0yzWMNdepAulS7YfoS3Zabrm8DOXXU4=
+golang.org/x/tools v0.7.0/go.mod h1:4pg6aUX35JBAogB10C9AtvVL+qowtN4pT3CGSQex14s=
 golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
diff --git a/internal/engine/runtime_ctx_os.go b/internal/engine/runtime_ctx_os.go
index e8af0fe..95d9392 100644
--- a/internal/engine/runtime_ctx_os.go
+++ b/internal/engine/runtime_ctx_os.go
@@ -28,6 +28,7 @@
 	"slices"
 	"strings"
 
+	"go.fuchsia.dev/shac-project/shac/internal/execsupport"
 	"go.fuchsia.dev/shac-project/shac/internal/sandbox"
 	"go.starlark.net/starlark"
 )
@@ -354,10 +355,7 @@
 	cmd.Stdout = stdout
 	cmd.Stderr = stderr
 
-	// Serialize start given the issue described at sandbox.Mu.
-	sandbox.Mu.RLock()
-	err = cmd.Start()
-	sandbox.Mu.RUnlock()
+	err = execsupport.Start(cmd)
 	if err != nil {
 		return nil, err
 	}
diff --git a/internal/engine/runtime_ctx_scm.go b/internal/engine/runtime_ctx_scm.go
index ff7f778..7f637e0 100644
--- a/internal/engine/runtime_ctx_scm.go
+++ b/internal/engine/runtime_ctx_scm.go
@@ -31,6 +31,7 @@
 	"unsafe"
 
 	"github.com/go-git/go-git/plumbing/format/gitignore"
+	"go.fuchsia.dev/shac-project/shac/internal/execsupport"
 	"go.starlark.net/starlark"
 )
 
@@ -378,7 +379,7 @@
 	b := buffers.get()
 	cmd.Stdout = b
 	cmd.Stderr = b
-	err := cmd.Run()
+	err := execsupport.Run(cmd)
 	// Always make a copy of the output, since it could be persisted. Only reuse
 	// the temporary buffer.
 	out := b.String()
diff --git a/internal/execsupport/execsupport.go b/internal/execsupport/execsupport.go
new file mode 100644
index 0000000..89113fa
--- /dev/null
+++ b/internal/execsupport/execsupport.go
@@ -0,0 +1,64 @@
+// Copyright 2023 The Shac Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Package execsupport implements wrappers around os/exec.Cmd Start() and Wait()
+// functions that acquire a read lock on a R/W mutex to work around fork+exec
+// concurrency issue with open file handle on POSIX.
+// See https://github.com/golang/go/issues/22315 and
+// https://github.com/golang/go/issues/22220 for background.
+//
+// This specifically affects the nsjail executable: if one goroutine of a
+// subprocess has the nsjail file handle open for writing at the time that
+// another goroutine forks a subprocess (any subprocess, whether it be git or a
+// subprocess run by `ctx.os.exec()`), the forked subprocess will inherit the
+// open file handle and it will remain open even after the parent closes it.
+// Then if the parent or any other process tries to run the nsjail executable,
+// it will fail with ETXTBSY due to being open for writing.
+//
+// So the code that writes the nsjail executable must acquire this package's
+// mutex for writing, to prevent any forks while the nsjail file is open for
+// writing, and all shac code must use this package's Start() and Wait()
+// functions instead of calling Cmd.Start() and Cmd.Wait() directly.
+//
+// This is only strictly necessary when running unit tests, because many shac
+// instances are run in parallel in the same process. In normal execution,
+// there are no subprocesses forks run concurrently when the nsjail executable
+// is being written.
+//
+// TODO(olivernewman): This hack will no longer be necessary when we switch from
+// using a prebuilt nsjail to implementing our own sandboxing using cgroups.
+package execsupport
+
+import (
+	"os/exec"
+	"sync"
+)
+
+// Mu enables blocking all exec(), for example while writing an executable that
+// will later be exec()'ed.
+var Mu sync.RWMutex
+
+// Start is a fork-safe wrapper around os/exec.Cmd.Start.
+func Start(cmd *exec.Cmd) error {
+	Mu.RLock()
+	defer Mu.RUnlock()
+	return cmd.Start()
+}
+
+// Run is a fork-safe wrapper around os/exec.Cmd.Run.
+func Run(cmd *exec.Cmd) error {
+	Mu.RLock()
+	defer Mu.RUnlock()
+	return cmd.Run()
+}
diff --git a/internal/go_checks/fork_check/main.go b/internal/go_checks/fork_check/main.go
new file mode 100644
index 0000000..5ed6200
--- /dev/null
+++ b/internal/go_checks/fork_check/main.go
@@ -0,0 +1,81 @@
+// Copyright 2023 The Shac Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Package main implements a check that the os/exec.Cmd Start() and Run()
+// functions aren't called directly.
+//
+// Instead, callers should use
+package main
+
+import (
+	"go/ast"
+
+	"golang.org/x/tools/go/analysis"
+	"golang.org/x/tools/go/analysis/multichecker"
+)
+
+func run(pass *analysis.Pass) (any, error) {
+	for _, f := range pass.Files {
+		ast.Inspect(f, func(n ast.Node) bool {
+			if n == nil {
+				return false
+			}
+			call, ok := n.(*ast.CallExpr)
+			if !ok {
+				return true
+			}
+			selector, ok := call.Fun.(*ast.SelectorExpr)
+			if !ok {
+				return true
+			}
+			funcName := selector.Sel.Name
+			if funcName != "Start" && funcName != "Run" {
+				return true
+			}
+
+			var obj *ast.Ident
+			switch o := selector.X.(type) {
+			case *ast.Ident:
+				obj = o
+			case *ast.SelectorExpr:
+				obj = o.Sel
+			default:
+				return true
+			}
+
+			// Skip function calls that aren't struct methods.
+			if obj == nil {
+				return true
+			}
+
+			typ := pass.TypesInfo.ObjectOf(obj).Type()
+			if typ.String() == "*os/exec.Cmd" {
+				pass.Reportf(n.Pos(), "do not call %s.%s() directly, use execsupport.%s(%s) instead",
+					obj.Name, funcName, funcName, obj.Name)
+			}
+			return false
+		})
+	}
+	return nil, nil
+}
+
+func main() {
+	multichecker.Main(
+		&analysis.Analyzer{
+			Name: "directexec",
+			Doc:  "do not call os/exec.Cmd Start or Run functions directly",
+			Run:  run,
+		},
+	)
+}
diff --git a/internal/sandbox/sandbox.go b/internal/sandbox/sandbox.go
index 33a3a40..af36164 100644
--- a/internal/sandbox/sandbox.go
+++ b/internal/sandbox/sandbox.go
@@ -24,7 +24,8 @@
 	"runtime"
 	"sort"
 	"strings"
-	"sync"
+
+	"go.fuchsia.dev/shac-project/shac/internal/execsupport"
 )
 
 //go:generate go run download_nsjail.go
@@ -59,18 +60,11 @@
 	Command(context.Context, *Config) *exec.Cmd
 }
 
-// Mu works around fork+exec concurrency issue with open file handle on POSIX.
-// See https://github.com/golang/go/issues/22315 and
-// https://github.com/golang/go/issues/22220 for background.
-//
-// This is only needed when running unit tests.
-var Mu sync.RWMutex
-
 // New constructs a platform-appropriate sandbox.
 func New(tempDir string) (Sandbox, error) {
 	if runtime.GOOS == "linux" && (runtime.GOARCH == "amd64" || runtime.GOARCH == "arm64") {
-		Mu.Lock()
-		defer Mu.Unlock()
+		execsupport.Mu.Lock()
+		defer execsupport.Mu.Unlock()
 		nsjailPath := filepath.Join(tempDir, "nsjail")
 		// Executable permissions are ok.
 		//#nosec CWE-276
diff --git a/shac.star b/shac.star
index 7ede0fa..8f97c6d 100644
--- a/shac.star
+++ b/shac.star
@@ -18,7 +18,7 @@
 """
 
 load("//checks/check_doc.star", "check_docs")
-load("//checks/go.star", "gofmt", "gosec", "ineffassign", "shadow", "staticcheck")
+load("//checks/go.star", "gofmt", "gosec", "ineffassign", "no_fork_without_lock", "shadow", "staticcheck")
 load("//checks/licenses.star", "check_license_headers")
 
 
@@ -64,5 +64,6 @@
 shac.register_check(gosec)
 shac.register_check(ineffassign)
 shac.register_check(new_todos)
+shac.register_check(no_fork_without_lock)
 shac.register_check(shadow)
 shac.register_check(staticcheck)
diff --git a/vendor/golang.org/x/mod/semver/semver.go b/vendor/golang.org/x/mod/semver/semver.go
new file mode 100644
index 0000000..a30a22b
--- /dev/null
+++ b/vendor/golang.org/x/mod/semver/semver.go
@@ -0,0 +1,401 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package semver implements comparison of semantic version strings.
+// In this package, semantic version strings must begin with a leading "v",
+// as in "v1.0.0".
+//
+// The general form of a semantic version string accepted by this package is
+//
+//	vMAJOR[.MINOR[.PATCH[-PRERELEASE][+BUILD]]]
+//
+// where square brackets indicate optional parts of the syntax;
+// MAJOR, MINOR, and PATCH are decimal integers without extra leading zeros;
+// PRERELEASE and BUILD are each a series of non-empty dot-separated identifiers
+// using only alphanumeric characters and hyphens; and
+// all-numeric PRERELEASE identifiers must not have leading zeros.
+//
+// This package follows Semantic Versioning 2.0.0 (see semver.org)
+// with two exceptions. First, it requires the "v" prefix. Second, it recognizes
+// vMAJOR and vMAJOR.MINOR (with no prerelease or build suffixes)
+// as shorthands for vMAJOR.0.0 and vMAJOR.MINOR.0.
+package semver
+
+import "sort"
+
+// parsed returns the parsed form of a semantic version string.
+type parsed struct {
+	major      string
+	minor      string
+	patch      string
+	short      string
+	prerelease string
+	build      string
+}
+
+// IsValid reports whether v is a valid semantic version string.
+func IsValid(v string) bool {
+	_, ok := parse(v)
+	return ok
+}
+
+// Canonical returns the canonical formatting of the semantic version v.
+// It fills in any missing .MINOR or .PATCH and discards build metadata.
+// Two semantic versions compare equal only if their canonical formattings
+// are identical strings.
+// The canonical invalid semantic version is the empty string.
+func Canonical(v string) string {
+	p, ok := parse(v)
+	if !ok {
+		return ""
+	}
+	if p.build != "" {
+		return v[:len(v)-len(p.build)]
+	}
+	if p.short != "" {
+		return v + p.short
+	}
+	return v
+}
+
+// Major returns the major version prefix of the semantic version v.
+// For example, Major("v2.1.0") == "v2".
+// If v is an invalid semantic version string, Major returns the empty string.
+func Major(v string) string {
+	pv, ok := parse(v)
+	if !ok {
+		return ""
+	}
+	return v[:1+len(pv.major)]
+}
+
+// MajorMinor returns the major.minor version prefix of the semantic version v.
+// For example, MajorMinor("v2.1.0") == "v2.1".
+// If v is an invalid semantic version string, MajorMinor returns the empty string.
+func MajorMinor(v string) string {
+	pv, ok := parse(v)
+	if !ok {
+		return ""
+	}
+	i := 1 + len(pv.major)
+	if j := i + 1 + len(pv.minor); j <= len(v) && v[i] == '.' && v[i+1:j] == pv.minor {
+		return v[:j]
+	}
+	return v[:i] + "." + pv.minor
+}
+
+// Prerelease returns the prerelease suffix of the semantic version v.
+// For example, Prerelease("v2.1.0-pre+meta") == "-pre".
+// If v is an invalid semantic version string, Prerelease returns the empty string.
+func Prerelease(v string) string {
+	pv, ok := parse(v)
+	if !ok {
+		return ""
+	}
+	return pv.prerelease
+}
+
+// Build returns the build suffix of the semantic version v.
+// For example, Build("v2.1.0+meta") == "+meta".
+// If v is an invalid semantic version string, Build returns the empty string.
+func Build(v string) string {
+	pv, ok := parse(v)
+	if !ok {
+		return ""
+	}
+	return pv.build
+}
+
+// Compare returns an integer comparing two versions according to
+// semantic version precedence.
+// The result will be 0 if v == w, -1 if v < w, or +1 if v > w.
+//
+// An invalid semantic version string is considered less than a valid one.
+// All invalid semantic version strings compare equal to each other.
+func Compare(v, w string) int {
+	pv, ok1 := parse(v)
+	pw, ok2 := parse(w)
+	if !ok1 && !ok2 {
+		return 0
+	}
+	if !ok1 {
+		return -1
+	}
+	if !ok2 {
+		return +1
+	}
+	if c := compareInt(pv.major, pw.major); c != 0 {
+		return c
+	}
+	if c := compareInt(pv.minor, pw.minor); c != 0 {
+		return c
+	}
+	if c := compareInt(pv.patch, pw.patch); c != 0 {
+		return c
+	}
+	return comparePrerelease(pv.prerelease, pw.prerelease)
+}
+
+// Max canonicalizes its arguments and then returns the version string
+// that compares greater.
+//
+// Deprecated: use Compare instead. In most cases, returning a canonicalized
+// version is not expected or desired.
+func Max(v, w string) string {
+	v = Canonical(v)
+	w = Canonical(w)
+	if Compare(v, w) > 0 {
+		return v
+	}
+	return w
+}
+
+// ByVersion implements sort.Interface for sorting semantic version strings.
+type ByVersion []string
+
+func (vs ByVersion) Len() int      { return len(vs) }
+func (vs ByVersion) Swap(i, j int) { vs[i], vs[j] = vs[j], vs[i] }
+func (vs ByVersion) Less(i, j int) bool {
+	cmp := Compare(vs[i], vs[j])
+	if cmp != 0 {
+		return cmp < 0
+	}
+	return vs[i] < vs[j]
+}
+
+// Sort sorts a list of semantic version strings using ByVersion.
+func Sort(list []string) {
+	sort.Sort(ByVersion(list))
+}
+
+func parse(v string) (p parsed, ok bool) {
+	if v == "" || v[0] != 'v' {
+		return
+	}
+	p.major, v, ok = parseInt(v[1:])
+	if !ok {
+		return
+	}
+	if v == "" {
+		p.minor = "0"
+		p.patch = "0"
+		p.short = ".0.0"
+		return
+	}
+	if v[0] != '.' {
+		ok = false
+		return
+	}
+	p.minor, v, ok = parseInt(v[1:])
+	if !ok {
+		return
+	}
+	if v == "" {
+		p.patch = "0"
+		p.short = ".0"
+		return
+	}
+	if v[0] != '.' {
+		ok = false
+		return
+	}
+	p.patch, v, ok = parseInt(v[1:])
+	if !ok {
+		return
+	}
+	if len(v) > 0 && v[0] == '-' {
+		p.prerelease, v, ok = parsePrerelease(v)
+		if !ok {
+			return
+		}
+	}
+	if len(v) > 0 && v[0] == '+' {
+		p.build, v, ok = parseBuild(v)
+		if !ok {
+			return
+		}
+	}
+	if v != "" {
+		ok = false
+		return
+	}
+	ok = true
+	return
+}
+
+func parseInt(v string) (t, rest string, ok bool) {
+	if v == "" {
+		return
+	}
+	if v[0] < '0' || '9' < v[0] {
+		return
+	}
+	i := 1
+	for i < len(v) && '0' <= v[i] && v[i] <= '9' {
+		i++
+	}
+	if v[0] == '0' && i != 1 {
+		return
+	}
+	return v[:i], v[i:], true
+}
+
+func parsePrerelease(v string) (t, rest string, ok bool) {
+	// "A pre-release version MAY be denoted by appending a hyphen and
+	// a series of dot separated identifiers immediately following the patch version.
+	// Identifiers MUST comprise only ASCII alphanumerics and hyphen [0-9A-Za-z-].
+	// Identifiers MUST NOT be empty. Numeric identifiers MUST NOT include leading zeroes."
+	if v == "" || v[0] != '-' {
+		return
+	}
+	i := 1
+	start := 1
+	for i < len(v) && v[i] != '+' {
+		if !isIdentChar(v[i]) && v[i] != '.' {
+			return
+		}
+		if v[i] == '.' {
+			if start == i || isBadNum(v[start:i]) {
+				return
+			}
+			start = i + 1
+		}
+		i++
+	}
+	if start == i || isBadNum(v[start:i]) {
+		return
+	}
+	return v[:i], v[i:], true
+}
+
+func parseBuild(v string) (t, rest string, ok bool) {
+	if v == "" || v[0] != '+' {
+		return
+	}
+	i := 1
+	start := 1
+	for i < len(v) {
+		if !isIdentChar(v[i]) && v[i] != '.' {
+			return
+		}
+		if v[i] == '.' {
+			if start == i {
+				return
+			}
+			start = i + 1
+		}
+		i++
+	}
+	if start == i {
+		return
+	}
+	return v[:i], v[i:], true
+}
+
+func isIdentChar(c byte) bool {
+	return 'A' <= c && c <= 'Z' || 'a' <= c && c <= 'z' || '0' <= c && c <= '9' || c == '-'
+}
+
+func isBadNum(v string) bool {
+	i := 0
+	for i < len(v) && '0' <= v[i] && v[i] <= '9' {
+		i++
+	}
+	return i == len(v) && i > 1 && v[0] == '0'
+}
+
+func isNum(v string) bool {
+	i := 0
+	for i < len(v) && '0' <= v[i] && v[i] <= '9' {
+		i++
+	}
+	return i == len(v)
+}
+
+func compareInt(x, y string) int {
+	if x == y {
+		return 0
+	}
+	if len(x) < len(y) {
+		return -1
+	}
+	if len(x) > len(y) {
+		return +1
+	}
+	if x < y {
+		return -1
+	} else {
+		return +1
+	}
+}
+
+func comparePrerelease(x, y string) int {
+	// "When major, minor, and patch are equal, a pre-release version has
+	// lower precedence than a normal version.
+	// Example: 1.0.0-alpha < 1.0.0.
+	// Precedence for two pre-release versions with the same major, minor,
+	// and patch version MUST be determined by comparing each dot separated
+	// identifier from left to right until a difference is found as follows:
+	// identifiers consisting of only digits are compared numerically and
+	// identifiers with letters or hyphens are compared lexically in ASCII
+	// sort order. Numeric identifiers always have lower precedence than
+	// non-numeric identifiers. A larger set of pre-release fields has a
+	// higher precedence than a smaller set, if all of the preceding
+	// identifiers are equal.
+	// Example: 1.0.0-alpha < 1.0.0-alpha.1 < 1.0.0-alpha.beta <
+	// 1.0.0-beta < 1.0.0-beta.2 < 1.0.0-beta.11 < 1.0.0-rc.1 < 1.0.0."
+	if x == y {
+		return 0
+	}
+	if x == "" {
+		return +1
+	}
+	if y == "" {
+		return -1
+	}
+	for x != "" && y != "" {
+		x = x[1:] // skip - or .
+		y = y[1:] // skip - or .
+		var dx, dy string
+		dx, x = nextIdent(x)
+		dy, y = nextIdent(y)
+		if dx != dy {
+			ix := isNum(dx)
+			iy := isNum(dy)
+			if ix != iy {
+				if ix {
+					return -1
+				} else {
+					return +1
+				}
+			}
+			if ix {
+				if len(dx) < len(dy) {
+					return -1
+				}
+				if len(dx) > len(dy) {
+					return +1
+				}
+			}
+			if dx < dy {
+				return -1
+			} else {
+				return +1
+			}
+		}
+	}
+	if x == "" {
+		return -1
+	} else {
+		return +1
+	}
+}
+
+func nextIdent(x string) (dx, rest string) {
+	i := 0
+	for i < len(x) && x[i] != '.' {
+		i++
+	}
+	return x[:i], x[i:]
+}
diff --git a/vendor/golang.org/x/sys/execabs/execabs.go b/vendor/golang.org/x/sys/execabs/execabs.go
new file mode 100644
index 0000000..3bf40fd
--- /dev/null
+++ b/vendor/golang.org/x/sys/execabs/execabs.go
@@ -0,0 +1,102 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package execabs is a drop-in replacement for os/exec
+// that requires PATH lookups to find absolute paths.
+// That is, execabs.Command("cmd") runs the same PATH lookup
+// as exec.Command("cmd"), but if the result is a path
+// which is relative, the Run and Start methods will report
+// an error instead of running the executable.
+//
+// See https://blog.golang.org/path-security for more information
+// about when it may be necessary or appropriate to use this package.
+package execabs
+
+import (
+	"context"
+	"fmt"
+	"os/exec"
+	"path/filepath"
+	"reflect"
+	"unsafe"
+)
+
+// ErrNotFound is the error resulting if a path search failed to find an executable file.
+// It is an alias for exec.ErrNotFound.
+var ErrNotFound = exec.ErrNotFound
+
+// Cmd represents an external command being prepared or run.
+// It is an alias for exec.Cmd.
+type Cmd = exec.Cmd
+
+// Error is returned by LookPath when it fails to classify a file as an executable.
+// It is an alias for exec.Error.
+type Error = exec.Error
+
+// An ExitError reports an unsuccessful exit by a command.
+// It is an alias for exec.ExitError.
+type ExitError = exec.ExitError
+
+func relError(file, path string) error {
+	return fmt.Errorf("%s resolves to executable in current directory (.%c%s)", file, filepath.Separator, path)
+}
+
+// LookPath searches for an executable named file in the directories
+// named by the PATH environment variable. If file contains a slash,
+// it is tried directly and the PATH is not consulted. The result will be
+// an absolute path.
+//
+// LookPath differs from exec.LookPath in its handling of PATH lookups,
+// which are used for file names without slashes. If exec.LookPath's
+// PATH lookup would have returned an executable from the current directory,
+// LookPath instead returns an error.
+func LookPath(file string) (string, error) {
+	path, err := exec.LookPath(file)
+	if err != nil && !isGo119ErrDot(err) {
+		return "", err
+	}
+	if filepath.Base(file) == file && !filepath.IsAbs(path) {
+		return "", relError(file, path)
+	}
+	return path, nil
+}
+
+func fixCmd(name string, cmd *exec.Cmd) {
+	if filepath.Base(name) == name && !filepath.IsAbs(cmd.Path) && !isGo119ErrFieldSet(cmd) {
+		// exec.Command was called with a bare binary name and
+		// exec.LookPath returned a path which is not absolute.
+		// Set cmd.lookPathErr and clear cmd.Path so that it
+		// cannot be run.
+		lookPathErr := (*error)(unsafe.Pointer(reflect.ValueOf(cmd).Elem().FieldByName("lookPathErr").Addr().Pointer()))
+		if *lookPathErr == nil {
+			*lookPathErr = relError(name, cmd.Path)
+		}
+		cmd.Path = ""
+	}
+}
+
+// CommandContext is like Command but includes a context.
+//
+// The provided context is used to kill the process (by calling os.Process.Kill)
+// if the context becomes done before the command completes on its own.
+func CommandContext(ctx context.Context, name string, arg ...string) *exec.Cmd {
+	cmd := exec.CommandContext(ctx, name, arg...)
+	fixCmd(name, cmd)
+	return cmd
+
+}
+
+// Command returns the Cmd struct to execute the named program with the given arguments.
+// See exec.Command for most details.
+//
+// Command differs from exec.Command in its handling of PATH lookups,
+// which are used when the program name contains no slashes.
+// If exec.Command would have returned an exec.Cmd configured to run an
+// executable from the current directory, Command instead
+// returns an exec.Cmd that will return an error from Start or Run.
+func Command(name string, arg ...string) *exec.Cmd {
+	cmd := exec.Command(name, arg...)
+	fixCmd(name, cmd)
+	return cmd
+}
diff --git a/vendor/golang.org/x/sys/execabs/execabs_go118.go b/vendor/golang.org/x/sys/execabs/execabs_go118.go
new file mode 100644
index 0000000..2000064
--- /dev/null
+++ b/vendor/golang.org/x/sys/execabs/execabs_go118.go
@@ -0,0 +1,18 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build !go1.19
+// +build !go1.19
+
+package execabs
+
+import "os/exec"
+
+func isGo119ErrDot(err error) bool {
+	return false
+}
+
+func isGo119ErrFieldSet(cmd *exec.Cmd) bool {
+	return false
+}
diff --git a/vendor/golang.org/x/sys/execabs/execabs_go119.go b/vendor/golang.org/x/sys/execabs/execabs_go119.go
new file mode 100644
index 0000000..f364b34
--- /dev/null
+++ b/vendor/golang.org/x/sys/execabs/execabs_go119.go
@@ -0,0 +1,21 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build go1.19
+// +build go1.19
+
+package execabs
+
+import (
+	"errors"
+	"os/exec"
+)
+
+func isGo119ErrDot(err error) bool {
+	return errors.Is(err, exec.ErrDot)
+}
+
+func isGo119ErrFieldSet(cmd *exec.Cmd) bool {
+	return cmd.Err != nil
+}
diff --git a/vendor/golang.org/x/tools/LICENSE b/vendor/golang.org/x/tools/LICENSE
new file mode 100644
index 0000000..6a66aea
--- /dev/null
+++ b/vendor/golang.org/x/tools/LICENSE
@@ -0,0 +1,27 @@
+Copyright (c) 2009 The Go Authors. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+   * Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+   * Redistributions in binary form must reproduce the above
+copyright notice, this list of conditions and the following disclaimer
+in the documentation and/or other materials provided with the
+distribution.
+   * Neither the name of Google Inc. nor the names of its
+contributors may be used to endorse or promote products derived from
+this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/vendor/golang.org/x/tools/PATENTS b/vendor/golang.org/x/tools/PATENTS
new file mode 100644
index 0000000..7330990
--- /dev/null
+++ b/vendor/golang.org/x/tools/PATENTS
@@ -0,0 +1,22 @@
+Additional IP Rights Grant (Patents)
+
+"This implementation" means the copyrightable works distributed by
+Google as part of the Go project.
+
+Google hereby grants to You a perpetual, worldwide, non-exclusive,
+no-charge, royalty-free, irrevocable (except as stated in this section)
+patent license to make, have made, use, offer to sell, sell, import,
+transfer and otherwise run, modify and propagate the contents of this
+implementation of Go, where such license applies only to those patent
+claims, both currently owned or controlled by Google and acquired in
+the future, licensable by Google that are necessarily infringed by this
+implementation of Go.  This grant does not include claims that would be
+infringed only as a consequence of further modification of this
+implementation.  If you or your agent or exclusive licensee institute or
+order or agree to the institution of patent litigation against any
+entity (including a cross-claim or counterclaim in a lawsuit) alleging
+that this implementation of Go or any code incorporated within this
+implementation of Go constitutes direct or contributory patent
+infringement, or inducement of patent infringement, then any patent
+rights granted to you under this License for this implementation of Go
+shall terminate as of the date such litigation is filed.
diff --git a/vendor/golang.org/x/tools/go/analysis/analysis.go b/vendor/golang.org/x/tools/go/analysis/analysis.go
new file mode 100644
index 0000000..44ada22
--- /dev/null
+++ b/vendor/golang.org/x/tools/go/analysis/analysis.go
@@ -0,0 +1,231 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package analysis
+
+import (
+	"flag"
+	"fmt"
+	"go/ast"
+	"go/token"
+	"go/types"
+	"reflect"
+)
+
+// An Analyzer describes an analysis function and its options.
+type Analyzer struct {
+	// The Name of the analyzer must be a valid Go identifier
+	// as it may appear in command-line flags, URLs, and so on.
+	Name string
+
+	// Doc is the documentation for the analyzer.
+	// The part before the first "\n\n" is the title
+	// (no capital or period, max ~60 letters).
+	Doc string
+
+	// Flags defines any flags accepted by the analyzer.
+	// The manner in which these flags are exposed to the user
+	// depends on the driver which runs the analyzer.
+	Flags flag.FlagSet
+
+	// Run applies the analyzer to a package.
+	// It returns an error if the analyzer failed.
+	//
+	// On success, the Run function may return a result
+	// computed by the Analyzer; its type must match ResultType.
+	// The driver makes this result available as an input to
+	// another Analyzer that depends directly on this one (see
+	// Requires) when it analyzes the same package.
+	//
+	// To pass analysis results between packages (and thus
+	// potentially between address spaces), use Facts, which are
+	// serializable.
+	Run func(*Pass) (interface{}, error)
+
+	// RunDespiteErrors allows the driver to invoke
+	// the Run method of this analyzer even on a
+	// package that contains parse or type errors.
+	// The Pass.TypeErrors field may consequently be non-empty.
+	RunDespiteErrors bool
+
+	// Requires is a set of analyzers that must run successfully
+	// before this one on a given package. This analyzer may inspect
+	// the outputs produced by each analyzer in Requires.
+	// The graph over analyzers implied by Requires edges must be acyclic.
+	//
+	// Requires establishes a "horizontal" dependency between
+	// analysis passes (different analyzers, same package).
+	Requires []*Analyzer
+
+	// ResultType is the type of the optional result of the Run function.
+	ResultType reflect.Type
+
+	// FactTypes indicates that this analyzer imports and exports
+	// Facts of the specified concrete types.
+	// An analyzer that uses facts may assume that its import
+	// dependencies have been similarly analyzed before it runs.
+	// Facts must be pointers.
+	//
+	// FactTypes establishes a "vertical" dependency between
+	// analysis passes (same analyzer, different packages).
+	FactTypes []Fact
+}
+
+func (a *Analyzer) String() string { return a.Name }
+
+// A Pass provides information to the Run function that
+// applies a specific analyzer to a single Go package.
+//
+// It forms the interface between the analysis logic and the driver
+// program, and has both input and an output components.
+//
+// As in a compiler, one pass may depend on the result computed by another.
+//
+// The Run function should not call any of the Pass functions concurrently.
+type Pass struct {
+	Analyzer *Analyzer // the identity of the current analyzer
+
+	// syntax and type information
+	Fset         *token.FileSet // file position information
+	Files        []*ast.File    // the abstract syntax tree of each file
+	OtherFiles   []string       // names of non-Go files of this package
+	IgnoredFiles []string       // names of ignored source files in this package
+	Pkg          *types.Package // type information about the package
+	TypesInfo    *types.Info    // type information about the syntax trees
+	TypesSizes   types.Sizes    // function for computing sizes of types
+	TypeErrors   []types.Error  // type errors (only if Analyzer.RunDespiteErrors)
+
+	// Report reports a Diagnostic, a finding about a specific location
+	// in the analyzed source code such as a potential mistake.
+	// It may be called by the Run function.
+	Report func(Diagnostic)
+
+	// ResultOf provides the inputs to this analysis pass, which are
+	// the corresponding results of its prerequisite analyzers.
+	// The map keys are the elements of Analysis.Required,
+	// and the type of each corresponding value is the required
+	// analysis's ResultType.
+	ResultOf map[*Analyzer]interface{}
+
+	// -- facts --
+
+	// ImportObjectFact retrieves a fact associated with obj.
+	// Given a value ptr of type *T, where *T satisfies Fact,
+	// ImportObjectFact copies the value to *ptr.
+	//
+	// ImportObjectFact panics if called after the pass is complete.
+	// ImportObjectFact is not concurrency-safe.
+	ImportObjectFact func(obj types.Object, fact Fact) bool
+
+	// ImportPackageFact retrieves a fact associated with package pkg,
+	// which must be this package or one of its dependencies.
+	// See comments for ImportObjectFact.
+	ImportPackageFact func(pkg *types.Package, fact Fact) bool
+
+	// ExportObjectFact associates a fact of type *T with the obj,
+	// replacing any previous fact of that type.
+	//
+	// ExportObjectFact panics if it is called after the pass is
+	// complete, or if obj does not belong to the package being analyzed.
+	// ExportObjectFact is not concurrency-safe.
+	ExportObjectFact func(obj types.Object, fact Fact)
+
+	// ExportPackageFact associates a fact with the current package.
+	// See comments for ExportObjectFact.
+	ExportPackageFact func(fact Fact)
+
+	// AllPackageFacts returns a new slice containing all package facts of the analysis's FactTypes
+	// in unspecified order.
+	// WARNING: This is an experimental API and may change in the future.
+	AllPackageFacts func() []PackageFact
+
+	// AllObjectFacts returns a new slice containing all object facts of the analysis's FactTypes
+	// in unspecified order.
+	// WARNING: This is an experimental API and may change in the future.
+	AllObjectFacts func() []ObjectFact
+
+	// typeErrors contains types.Errors that are associated with the pkg.
+	typeErrors []types.Error
+
+	/* Further fields may be added in future. */
+	// For example, suggested or applied refactorings.
+}
+
+// PackageFact is a package together with an associated fact.
+// WARNING: This is an experimental API and may change in the future.
+type PackageFact struct {
+	Package *types.Package
+	Fact    Fact
+}
+
+// ObjectFact is an object together with an associated fact.
+// WARNING: This is an experimental API and may change in the future.
+type ObjectFact struct {
+	Object types.Object
+	Fact   Fact
+}
+
+// Reportf is a helper function that reports a Diagnostic using the
+// specified position and formatted error message.
+func (pass *Pass) Reportf(pos token.Pos, format string, args ...interface{}) {
+	msg := fmt.Sprintf(format, args...)
+	pass.Report(Diagnostic{Pos: pos, Message: msg})
+}
+
+// The Range interface provides a range. It's equivalent to and satisfied by
+// ast.Node.
+type Range interface {
+	Pos() token.Pos // position of first character belonging to the node
+	End() token.Pos // position of first character immediately after the node
+}
+
+// ReportRangef is a helper function that reports a Diagnostic using the
+// range provided. ast.Node values can be passed in as the range because
+// they satisfy the Range interface.
+func (pass *Pass) ReportRangef(rng Range, format string, args ...interface{}) {
+	msg := fmt.Sprintf(format, args...)
+	pass.Report(Diagnostic{Pos: rng.Pos(), End: rng.End(), Message: msg})
+}
+
+func (pass *Pass) String() string {
+	return fmt.Sprintf("%s@%s", pass.Analyzer.Name, pass.Pkg.Path())
+}
+
+// A Fact is an intermediate fact produced during analysis.
+//
+// Each fact is associated with a named declaration (a types.Object) or
+// with a package as a whole. A single object or package may have
+// multiple associated facts, but only one of any particular fact type.
+//
+// A Fact represents a predicate such as "never returns", but does not
+// represent the subject of the predicate such as "function F" or "package P".
+//
+// Facts may be produced in one analysis pass and consumed by another
+// analysis pass even if these are in different address spaces.
+// If package P imports Q, all facts about Q produced during
+// analysis of that package will be available during later analysis of P.
+// Facts are analogous to type export data in a build system:
+// just as export data enables separate compilation of several passes,
+// facts enable "separate analysis".
+//
+// Each pass (a, p) starts with the set of facts produced by the
+// same analyzer a applied to the packages directly imported by p.
+// The analysis may add facts to the set, and they may be exported in turn.
+// An analysis's Run function may retrieve facts by calling
+// Pass.Import{Object,Package}Fact and update them using
+// Pass.Export{Object,Package}Fact.
+//
+// A fact is logically private to its Analysis. To pass values
+// between different analyzers, use the results mechanism;
+// see Analyzer.Requires, Analyzer.ResultType, and Pass.ResultOf.
+//
+// A Fact type must be a pointer.
+// Facts are encoded and decoded using encoding/gob.
+// A Fact may implement the GobEncoder/GobDecoder interfaces
+// to customize its encoding. Fact encoding should not fail.
+//
+// A Fact should not be modified once exported.
+type Fact interface {
+	AFact() // dummy method to avoid type errors
+}
diff --git a/vendor/golang.org/x/tools/go/analysis/diagnostic.go b/vendor/golang.org/x/tools/go/analysis/diagnostic.go
new file mode 100644
index 0000000..5cdcf46
--- /dev/null
+++ b/vendor/golang.org/x/tools/go/analysis/diagnostic.go
@@ -0,0 +1,65 @@
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package analysis
+
+import "go/token"
+
+// A Diagnostic is a message associated with a source location or range.
+//
+// An Analyzer may return a variety of diagnostics; the optional Category,
+// which should be a constant, may be used to classify them.
+// It is primarily intended to make it easy to look up documentation.
+//
+// If End is provided, the diagnostic is specified to apply to the range between
+// Pos and End.
+type Diagnostic struct {
+	Pos      token.Pos
+	End      token.Pos // optional
+	Category string    // optional
+	Message  string
+
+	// SuggestedFixes contains suggested fixes for a diagnostic which can be used to perform
+	// edits to a file that address the diagnostic.
+	// TODO(matloob): Should multiple SuggestedFixes be allowed for a diagnostic?
+	// Diagnostics should not contain SuggestedFixes that overlap.
+	// Experimental: This API is experimental and may change in the future.
+	SuggestedFixes []SuggestedFix // optional
+
+	// Experimental: This API is experimental and may change in the future.
+	Related []RelatedInformation // optional
+}
+
+// RelatedInformation contains information related to a diagnostic.
+// For example, a diagnostic that flags duplicated declarations of a
+// variable may include one RelatedInformation per existing
+// declaration.
+type RelatedInformation struct {
+	Pos     token.Pos
+	End     token.Pos // optional
+	Message string
+}
+
+// A SuggestedFix is a code change associated with a Diagnostic that a user can choose
+// to apply to their code. Usually the SuggestedFix is meant to fix the issue flagged
+// by the diagnostic.
+// TextEdits for a SuggestedFix should not overlap. TextEdits for a SuggestedFix
+// should not contain edits for other packages.
+// Experimental: This API is experimental and may change in the future.
+type SuggestedFix struct {
+	// A description for this suggested fix to be shown to a user deciding
+	// whether to accept it.
+	Message   string
+	TextEdits []TextEdit
+}
+
+// A TextEdit represents the replacement of the code between Pos and End with the new text.
+// Each TextEdit should apply to a single file. End should not be earlier in the file than Pos.
+// Experimental: This API is experimental and may change in the future.
+type TextEdit struct {
+	// For a pure insertion, End can either be set to Pos or token.NoPos.
+	Pos     token.Pos
+	End     token.Pos
+	NewText []byte
+}
diff --git a/vendor/golang.org/x/tools/go/analysis/doc.go b/vendor/golang.org/x/tools/go/analysis/doc.go
new file mode 100644
index 0000000..c5429c9
--- /dev/null
+++ b/vendor/golang.org/x/tools/go/analysis/doc.go
@@ -0,0 +1,319 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+/*
+Package analysis defines the interface between a modular static
+analysis and an analysis driver program.
+
+# Background
+
+A static analysis is a function that inspects a package of Go code and
+reports a set of diagnostics (typically mistakes in the code), and
+perhaps produces other results as well, such as suggested refactorings
+or other facts. An analysis that reports mistakes is informally called a
+"checker". For example, the printf checker reports mistakes in
+fmt.Printf format strings.
+
+A "modular" analysis is one that inspects one package at a time but can
+save information from a lower-level package and use it when inspecting a
+higher-level package, analogous to separate compilation in a toolchain.
+The printf checker is modular: when it discovers that a function such as
+log.Fatalf delegates to fmt.Printf, it records this fact, and checks
+calls to that function too, including calls made from another package.
+
+By implementing a common interface, checkers from a variety of sources
+can be easily selected, incorporated, and reused in a wide range of
+driver programs including command-line tools (such as vet), text editors and
+IDEs, build and test systems (such as go build, Bazel, or Buck), test
+frameworks, code review tools, code-base indexers (such as SourceGraph),
+documentation viewers (such as godoc), batch pipelines for large code
+bases, and so on.
+
+# Analyzer
+
+The primary type in the API is Analyzer. An Analyzer statically
+describes an analysis function: its name, documentation, flags,
+relationship to other analyzers, and of course, its logic.
+
+To define an analysis, a user declares a (logically constant) variable
+of type Analyzer. Here is a typical example from one of the analyzers in
+the go/analysis/passes/ subdirectory:
+
+	package unusedresult
+
+	var Analyzer = &analysis.Analyzer{
+		Name: "unusedresult",
+		Doc:  "check for unused results of calls to some functions",
+		Run:  run,
+		...
+	}
+
+	func run(pass *analysis.Pass) (interface{}, error) {
+		...
+	}
+
+An analysis driver is a program such as vet that runs a set of
+analyses and prints the diagnostics that they report.
+The driver program must import the list of Analyzers it needs.
+Typically each Analyzer resides in a separate package.
+To add a new Analyzer to an existing driver, add another item to the list:
+
+	import ( "unusedresult"; "nilness"; "printf" )
+
+	var analyses = []*analysis.Analyzer{
+		unusedresult.Analyzer,
+		nilness.Analyzer,
+		printf.Analyzer,
+	}
+
+A driver may use the name, flags, and documentation to provide on-line
+help that describes the analyses it performs.
+The doc comment contains a brief one-line summary,
+optionally followed by paragraphs of explanation.
+
+The Analyzer type has more fields besides those shown above:
+
+	type Analyzer struct {
+		Name             string
+		Doc              string
+		Flags            flag.FlagSet
+		Run              func(*Pass) (interface{}, error)
+		RunDespiteErrors bool
+		ResultType       reflect.Type
+		Requires         []*Analyzer
+		FactTypes        []Fact
+	}
+
+The Flags field declares a set of named (global) flag variables that
+control analysis behavior. Unlike vet, analysis flags are not declared
+directly in the command line FlagSet; it is up to the driver to set the
+flag variables. A driver for a single analysis, a, might expose its flag
+f directly on the command line as -f, whereas a driver for multiple
+analyses might prefix the flag name by the analysis name (-a.f) to avoid
+ambiguity. An IDE might expose the flags through a graphical interface,
+and a batch pipeline might configure them from a config file.
+See the "findcall" analyzer for an example of flags in action.
+
+The RunDespiteErrors flag indicates whether the analysis is equipped to
+handle ill-typed code. If not, the driver will skip the analysis if
+there were parse or type errors.
+The optional ResultType field specifies the type of the result value
+computed by this analysis and made available to other analyses.
+The Requires field specifies a list of analyses upon which
+this one depends and whose results it may access, and it constrains the
+order in which a driver may run analyses.
+The FactTypes field is discussed in the section on Modularity.
+The analysis package provides a Validate function to perform basic
+sanity checks on an Analyzer, such as that its Requires graph is
+acyclic, its fact and result types are unique, and so on.
+
+Finally, the Run field contains a function to be called by the driver to
+execute the analysis on a single package. The driver passes it an
+instance of the Pass type.
+
+# Pass
+
+A Pass describes a single unit of work: the application of a particular
+Analyzer to a particular package of Go code.
+The Pass provides information to the Analyzer's Run function about the
+package being analyzed, and provides operations to the Run function for
+reporting diagnostics and other information back to the driver.
+
+	type Pass struct {
+		Fset         *token.FileSet
+		Files        []*ast.File
+		OtherFiles   []string
+		IgnoredFiles []string
+		Pkg          *types.Package
+		TypesInfo    *types.Info
+		ResultOf     map[*Analyzer]interface{}
+		Report       func(Diagnostic)
+		...
+	}
+
+The Fset, Files, Pkg, and TypesInfo fields provide the syntax trees,
+type information, and source positions for a single package of Go code.
+
+The OtherFiles field provides the names, but not the contents, of non-Go
+files such as assembly that are part of this package. See the "asmdecl"
+or "buildtags" analyzers for examples of loading non-Go files and reporting
+diagnostics against them.
+
+The IgnoredFiles field provides the names, but not the contents,
+of ignored Go and non-Go source files that are not part of this package
+with the current build configuration but may be part of other build
+configurations. See the "buildtags" analyzer for an example of loading
+and checking IgnoredFiles.
+
+The ResultOf field provides the results computed by the analyzers
+required by this one, as expressed in its Analyzer.Requires field. The
+driver runs the required analyzers first and makes their results
+available in this map. Each Analyzer must return a value of the type
+described in its Analyzer.ResultType field.
+For example, the "ctrlflow" analyzer returns a *ctrlflow.CFGs, which
+provides a control-flow graph for each function in the package (see
+golang.org/x/tools/go/cfg); the "inspect" analyzer returns a value that
+enables other Analyzers to traverse the syntax trees of the package more
+efficiently; and the "buildssa" analyzer constructs an SSA-form
+intermediate representation.
+Each of these Analyzers extends the capabilities of later Analyzers
+without adding a dependency to the core API, so an analysis tool pays
+only for the extensions it needs.
+
+The Report function emits a diagnostic, a message associated with a
+source position. For most analyses, diagnostics are their primary
+result.
+For convenience, Pass provides a helper method, Reportf, to report a new
+diagnostic by formatting a string.
+Diagnostic is defined as:
+
+	type Diagnostic struct {
+		Pos      token.Pos
+		Category string // optional
+		Message  string
+	}
+
+The optional Category field is a short identifier that classifies the
+kind of message when an analysis produces several kinds of diagnostic.
+
+The Diagnostic struct does not have a field to indicate its severity
+because opinions about the relative importance of Analyzers and their
+diagnostics vary widely among users. The design of this framework does
+not hold each Analyzer responsible for identifying the severity of its
+diagnostics. Instead, we expect that drivers will allow the user to
+customize the filtering and prioritization of diagnostics based on the
+producing Analyzer and optional Category, according to the user's
+preferences.
+
+Most Analyzers inspect typed Go syntax trees, but a few, such as asmdecl
+and buildtag, inspect the raw text of Go source files or even non-Go
+files such as assembly. To report a diagnostic against a line of a
+raw text file, use the following sequence:
+
+	content, err := ioutil.ReadFile(filename)
+	if err != nil { ... }
+	tf := fset.AddFile(filename, -1, len(content))
+	tf.SetLinesForContent(content)
+	...
+	pass.Reportf(tf.LineStart(line), "oops")
+
+# Modular analysis with Facts
+
+To improve efficiency and scalability, large programs are routinely
+built using separate compilation: units of the program are compiled
+separately, and recompiled only when one of their dependencies changes;
+independent modules may be compiled in parallel. The same technique may
+be applied to static analyses, for the same benefits. Such analyses are
+described as "modular".
+
+A compiler’s type checker is an example of a modular static analysis.
+Many other checkers we would like to apply to Go programs can be
+understood as alternative or non-standard type systems. For example,
+vet's printf checker infers whether a function has the "printf wrapper"
+type, and it applies stricter checks to calls of such functions. In
+addition, it records which functions are printf wrappers for use by
+later analysis passes to identify other printf wrappers by induction.
+A result such as “f is a printf wrapper” that is not interesting by
+itself but serves as a stepping stone to an interesting result (such as
+a diagnostic) is called a "fact".
+
+The analysis API allows an analysis to define new types of facts, to
+associate facts of these types with objects (named entities) declared
+within the current package, or with the package as a whole, and to query
+for an existing fact of a given type associated with an object or
+package.
+
+An Analyzer that uses facts must declare their types:
+
+	var Analyzer = &analysis.Analyzer{
+		Name:      "printf",
+		FactTypes: []analysis.Fact{new(isWrapper)},
+		...
+	}
+
+	type isWrapper struct{} // => *types.Func f “is a printf wrapper”
+
+The driver program ensures that facts for a pass’s dependencies are
+generated before analyzing the package and is responsible for propagating
+facts from one package to another, possibly across address spaces.
+Consequently, Facts must be serializable. The API requires that drivers
+use the gob encoding, an efficient, robust, self-describing binary
+protocol. A fact type may implement the GobEncoder/GobDecoder interfaces
+if the default encoding is unsuitable. Facts should be stateless.
+Because serialized facts may appear within build outputs, the gob encoding
+of a fact must be deterministic, to avoid spurious cache misses in
+build systems that use content-addressable caches.
+The driver makes a single call to the gob encoder for all facts
+exported by a given analysis pass, so that the topology of
+shared data structures referenced by multiple facts is preserved.
+
+The Pass type has functions to import and export facts,
+associated either with an object or with a package:
+
+	type Pass struct {
+		...
+		ExportObjectFact func(types.Object, Fact)
+		ImportObjectFact func(types.Object, Fact) bool
+
+		ExportPackageFact func(fact Fact)
+		ImportPackageFact func(*types.Package, Fact) bool
+	}
+
+An Analyzer may only export facts associated with the current package or
+its objects, though it may import facts from any package or object that
+is an import dependency of the current package.
+
+Conceptually, ExportObjectFact(obj, fact) inserts fact into a hidden map keyed by
+the pair (obj, TypeOf(fact)), and the ImportObjectFact function
+retrieves the entry from this map and copies its value into the variable
+pointed to by fact. This scheme assumes that the concrete type of fact
+is a pointer; this assumption is checked by the Validate function.
+See the "printf" analyzer for an example of object facts in action.
+
+Some driver implementations (such as those based on Bazel and Blaze) do
+not currently apply analyzers to packages of the standard library.
+Therefore, for best results, analyzer authors should not rely on
+analysis facts being available for standard packages.
+For example, although the printf checker is capable of deducing during
+analysis of the log package that log.Printf is a printf wrapper,
+this fact is built in to the analyzer so that it correctly checks
+calls to log.Printf even when run in a driver that does not apply
+it to standard packages. We would like to remove this limitation in future.
+
+# Testing an Analyzer
+
+The analysistest subpackage provides utilities for testing an Analyzer.
+In a few lines of code, it is possible to run an analyzer on a package
+of testdata files and check that it reported all the expected
+diagnostics and facts (and no more). Expectations are expressed using
+"// want ..." comments in the input code.
+
+# Standalone commands
+
+Analyzers are provided in the form of packages that a driver program is
+expected to import. The vet command imports a set of several analyzers,
+but users may wish to define their own analysis commands that perform
+additional checks. To simplify the task of creating an analysis command,
+either for a single analyzer or for a whole suite, we provide the
+singlechecker and multichecker subpackages.
+
+The singlechecker package provides the main function for a command that
+runs one analyzer. By convention, each analyzer such as
+go/analysis/passes/findcall should be accompanied by a singlechecker-based
+command such as go/analysis/passes/findcall/cmd/findcall, defined in its
+entirety as:
+
+	package main
+
+	import (
+		"golang.org/x/tools/go/analysis/passes/findcall"
+		"golang.org/x/tools/go/analysis/singlechecker"
+	)
+
+	func main() { singlechecker.Main(findcall.Analyzer) }
+
+A tool that provides multiple analyzers can use multichecker in a
+similar way, giving it the list of Analyzers.
+*/
+package analysis
diff --git a/vendor/golang.org/x/tools/go/analysis/internal/analysisflags/flags.go b/vendor/golang.org/x/tools/go/analysis/internal/analysisflags/flags.go
new file mode 100644
index 0000000..e127a42
--- /dev/null
+++ b/vendor/golang.org/x/tools/go/analysis/internal/analysisflags/flags.go
@@ -0,0 +1,431 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package analysisflags defines helpers for processing flags of
+// analysis driver tools.
+package analysisflags
+
+import (
+	"crypto/sha256"
+	"encoding/gob"
+	"encoding/json"
+	"flag"
+	"fmt"
+	"go/token"
+	"io"
+	"io/ioutil"
+	"log"
+	"os"
+	"strconv"
+	"strings"
+
+	"golang.org/x/tools/go/analysis"
+)
+
+// flags common to all {single,multi,unit}checkers.
+var (
+	JSON    = false // -json
+	Context = -1    // -c=N: if N>0, display offending line plus N lines of context
+)
+
+// Parse creates a flag for each of the analyzer's flags,
+// including (in multi mode) a flag named after the analyzer,
+// parses the flags, then filters and returns the list of
+// analyzers enabled by flags.
+//
+// The result is intended to be passed to unitchecker.Run or checker.Run.
+// Use in unitchecker.Run will gob.Register all fact types for the returned
+// graph of analyzers but of course not the ones only reachable from
+// dropped analyzers. To avoid inconsistency about which gob types are
+// registered from run to run, Parse itself gob.Registers all the facts
+// only reachable from dropped analyzers.
+// This is not a particularly elegant API, but this is an internal package.
+func Parse(analyzers []*analysis.Analyzer, multi bool) []*analysis.Analyzer {
+	// Connect each analysis flag to the command line as -analysis.flag.
+	enabled := make(map[*analysis.Analyzer]*triState)
+	for _, a := range analyzers {
+		var prefix string
+
+		// Add -NAME flag to enable it.
+		if multi {
+			prefix = a.Name + "."
+
+			enable := new(triState)
+			enableUsage := "enable " + a.Name + " analysis"
+			flag.Var(enable, a.Name, enableUsage)
+			enabled[a] = enable
+		}
+
+		a.Flags.VisitAll(func(f *flag.Flag) {
+			if !multi && flag.Lookup(f.Name) != nil {
+				log.Printf("%s flag -%s would conflict with driver; skipping", a.Name, f.Name)
+				return
+			}
+
+			name := prefix + f.Name
+			flag.Var(f.Value, name, f.Usage)
+		})
+	}
+
+	// standard flags: -flags, -V.
+	printflags := flag.Bool("flags", false, "print analyzer flags in JSON")
+	addVersionFlag()
+
+	// flags common to all checkers
+	flag.BoolVar(&JSON, "json", JSON, "emit JSON output")
+	flag.IntVar(&Context, "c", Context, `display offending line with this many lines of context`)
+
+	// Add shims for legacy vet flags to enable existing
+	// scripts that run vet to continue to work.
+	_ = flag.Bool("source", false, "no effect (deprecated)")
+	_ = flag.Bool("v", false, "no effect (deprecated)")
+	_ = flag.Bool("all", false, "no effect (deprecated)")
+	_ = flag.String("tags", "", "no effect (deprecated)")
+	for old, new := range vetLegacyFlags {
+		newFlag := flag.Lookup(new)
+		if newFlag != nil && flag.Lookup(old) == nil {
+			flag.Var(newFlag.Value, old, "deprecated alias for -"+new)
+		}
+	}
+
+	flag.Parse() // (ExitOnError)
+
+	// -flags: print flags so that go vet knows which ones are legitimate.
+	if *printflags {
+		printFlags()
+		os.Exit(0)
+	}
+
+	everything := expand(analyzers)
+
+	// If any -NAME flag is true,  run only those analyzers. Otherwise,
+	// if any -NAME flag is false, run all but those analyzers.
+	if multi {
+		var hasTrue, hasFalse bool
+		for _, ts := range enabled {
+			switch *ts {
+			case setTrue:
+				hasTrue = true
+			case setFalse:
+				hasFalse = true
+			}
+		}
+
+		var keep []*analysis.Analyzer
+		if hasTrue {
+			for _, a := range analyzers {
+				if *enabled[a] == setTrue {
+					keep = append(keep, a)
+				}
+			}
+			analyzers = keep
+		} else if hasFalse {
+			for _, a := range analyzers {
+				if *enabled[a] != setFalse {
+					keep = append(keep, a)
+				}
+			}
+			analyzers = keep
+		}
+	}
+
+	// Register fact types of skipped analyzers
+	// in case we encounter them in imported files.
+	kept := expand(analyzers)
+	for a := range everything {
+		if !kept[a] {
+			for _, f := range a.FactTypes {
+				gob.Register(f)
+			}
+		}
+	}
+
+	return analyzers
+}
+
+func expand(analyzers []*analysis.Analyzer) map[*analysis.Analyzer]bool {
+	seen := make(map[*analysis.Analyzer]bool)
+	var visitAll func([]*analysis.Analyzer)
+	visitAll = func(analyzers []*analysis.Analyzer) {
+		for _, a := range analyzers {
+			if !seen[a] {
+				seen[a] = true
+				visitAll(a.Requires)
+			}
+		}
+	}
+	visitAll(analyzers)
+	return seen
+}
+
+func printFlags() {
+	type jsonFlag struct {
+		Name  string
+		Bool  bool
+		Usage string
+	}
+	var flags []jsonFlag = nil
+	flag.VisitAll(func(f *flag.Flag) {
+		// Don't report {single,multi}checker debugging
+		// flags or fix as these have no effect on unitchecker
+		// (as invoked by 'go vet').
+		switch f.Name {
+		case "debug", "cpuprofile", "memprofile", "trace", "fix":
+			return
+		}
+
+		b, ok := f.Value.(interface{ IsBoolFlag() bool })
+		isBool := ok && b.IsBoolFlag()
+		flags = append(flags, jsonFlag{f.Name, isBool, f.Usage})
+	})
+	data, err := json.MarshalIndent(flags, "", "\t")
+	if err != nil {
+		log.Fatal(err)
+	}
+	os.Stdout.Write(data)
+}
+
+// addVersionFlag registers a -V flag that, if set,
+// prints the executable version and exits 0.
+//
+// If the -V flag already exists — for example, because it was already
+// registered by a call to cmd/internal/objabi.AddVersionFlag — then
+// addVersionFlag does nothing.
+func addVersionFlag() {
+	if flag.Lookup("V") == nil {
+		flag.Var(versionFlag{}, "V", "print version and exit")
+	}
+}
+
+// versionFlag minimally complies with the -V protocol required by "go vet".
+type versionFlag struct{}
+
+func (versionFlag) IsBoolFlag() bool { return true }
+func (versionFlag) Get() interface{} { return nil }
+func (versionFlag) String() string   { return "" }
+func (versionFlag) Set(s string) error {
+	if s != "full" {
+		log.Fatalf("unsupported flag value: -V=%s (use -V=full)", s)
+	}
+
+	// This replicates the minimal subset of
+	// cmd/internal/objabi.AddVersionFlag, which is private to the
+	// go tool yet forms part of our command-line interface.
+	// TODO(adonovan): clarify the contract.
+
+	// Print the tool version so the build system can track changes.
+	// Formats:
+	//   $progname version devel ... buildID=...
+	//   $progname version go1.9.1
+	progname, err := os.Executable()
+	if err != nil {
+		return err
+	}
+	f, err := os.Open(progname)
+	if err != nil {
+		log.Fatal(err)
+	}
+	h := sha256.New()
+	if _, err := io.Copy(h, f); err != nil {
+		log.Fatal(err)
+	}
+	f.Close()
+	fmt.Printf("%s version devel comments-go-here buildID=%02x\n",
+		progname, string(h.Sum(nil)))
+	os.Exit(0)
+	return nil
+}
+
+// A triState is a boolean that knows whether
+// it has been set to either true or false.
+// It is used to identify whether a flag appears;
+// the standard boolean flag cannot
+// distinguish missing from unset.
+// It also satisfies flag.Value.
+type triState int
+
+const (
+	unset triState = iota
+	setTrue
+	setFalse
+)
+
+func triStateFlag(name string, value triState, usage string) *triState {
+	flag.Var(&value, name, usage)
+	return &value
+}
+
+// triState implements flag.Value, flag.Getter, and flag.boolFlag.
+// They work like boolean flags: we can say vet -printf as well as vet -printf=true
+func (ts *triState) Get() interface{} {
+	return *ts == setTrue
+}
+
+func (ts triState) isTrue() bool {
+	return ts == setTrue
+}
+
+func (ts *triState) Set(value string) error {
+	b, err := strconv.ParseBool(value)
+	if err != nil {
+		// This error message looks poor but package "flag" adds
+		// "invalid boolean value %q for -NAME: %s"
+		return fmt.Errorf("want true or false")
+	}
+	if b {
+		*ts = setTrue
+	} else {
+		*ts = setFalse
+	}
+	return nil
+}
+
+func (ts *triState) String() string {
+	switch *ts {
+	case unset:
+		return "true"
+	case setTrue:
+		return "true"
+	case setFalse:
+		return "false"
+	}
+	panic("not reached")
+}
+
+func (ts triState) IsBoolFlag() bool {
+	return true
+}
+
+// Legacy flag support
+
+// vetLegacyFlags maps flags used by legacy vet to their corresponding
+// new names. The old names will continue to work.
+var vetLegacyFlags = map[string]string{
+	// Analyzer name changes
+	"bool":       "bools",
+	"buildtags":  "buildtag",
+	"methods":    "stdmethods",
+	"rangeloops": "loopclosure",
+
+	// Analyzer flags
+	"compositewhitelist":  "composites.whitelist",
+	"printfuncs":          "printf.funcs",
+	"shadowstrict":        "shadow.strict",
+	"unusedfuncs":         "unusedresult.funcs",
+	"unusedstringmethods": "unusedresult.stringmethods",
+}
+
+// ---- output helpers common to all drivers ----
+
+// PrintPlain prints a diagnostic in plain text form,
+// with context specified by the -c flag.
+func PrintPlain(fset *token.FileSet, diag analysis.Diagnostic) {
+	posn := fset.Position(diag.Pos)
+	fmt.Fprintf(os.Stderr, "%s: %s\n", posn, diag.Message)
+
+	// -c=N: show offending line plus N lines of context.
+	if Context >= 0 {
+		posn := fset.Position(diag.Pos)
+		end := fset.Position(diag.End)
+		if !end.IsValid() {
+			end = posn
+		}
+		data, _ := ioutil.ReadFile(posn.Filename)
+		lines := strings.Split(string(data), "\n")
+		for i := posn.Line - Context; i <= end.Line+Context; i++ {
+			if 1 <= i && i <= len(lines) {
+				fmt.Fprintf(os.Stderr, "%d\t%s\n", i, lines[i-1])
+			}
+		}
+	}
+}
+
+// A JSONTree is a mapping from package ID to analysis name to result.
+// Each result is either a jsonError or a list of JSONDiagnostic.
+type JSONTree map[string]map[string]interface{}
+
+// A TextEdit describes the replacement of a portion of a file.
+// Start and End are zero-based half-open indices into the original byte
+// sequence of the file, and New is the new text.
+type JSONTextEdit struct {
+	Filename string `json:"filename"`
+	Start    int    `json:"start"`
+	End      int    `json:"end"`
+	New      string `json:"new"`
+}
+
+// A JSONSuggestedFix describes an edit that should be applied as a whole or not
+// at all. It might contain multiple TextEdits/text_edits if the SuggestedFix
+// consists of multiple non-contiguous edits.
+type JSONSuggestedFix struct {
+	Message string         `json:"message"`
+	Edits   []JSONTextEdit `json:"edits"`
+}
+
+// A JSONDiagnostic can be used to encode and decode analysis.Diagnostics to and
+// from JSON.
+// TODO(matloob): Should the JSON diagnostics contain ranges?
+// If so, how should they be formatted?
+type JSONDiagnostic struct {
+	Category       string             `json:"category,omitempty"`
+	Posn           string             `json:"posn"`
+	Message        string             `json:"message"`
+	SuggestedFixes []JSONSuggestedFix `json:"suggested_fixes,omitempty"`
+}
+
+// Add adds the result of analysis 'name' on package 'id'.
+// The result is either a list of diagnostics or an error.
+func (tree JSONTree) Add(fset *token.FileSet, id, name string, diags []analysis.Diagnostic, err error) {
+	var v interface{}
+	if err != nil {
+		type jsonError struct {
+			Err string `json:"error"`
+		}
+		v = jsonError{err.Error()}
+	} else if len(diags) > 0 {
+		diagnostics := make([]JSONDiagnostic, 0, len(diags))
+		for _, f := range diags {
+			var fixes []JSONSuggestedFix
+			for _, fix := range f.SuggestedFixes {
+				var edits []JSONTextEdit
+				for _, edit := range fix.TextEdits {
+					edits = append(edits, JSONTextEdit{
+						Filename: fset.Position(edit.Pos).Filename,
+						Start:    fset.Position(edit.Pos).Offset,
+						End:      fset.Position(edit.End).Offset,
+						New:      string(edit.NewText),
+					})
+				}
+				fixes = append(fixes, JSONSuggestedFix{
+					Message: fix.Message,
+					Edits:   edits,
+				})
+			}
+			jdiag := JSONDiagnostic{
+				Category:       f.Category,
+				Posn:           fset.Position(f.Pos).String(),
+				Message:        f.Message,
+				SuggestedFixes: fixes,
+			}
+			diagnostics = append(diagnostics, jdiag)
+		}
+		v = diagnostics
+	}
+	if v != nil {
+		m, ok := tree[id]
+		if !ok {
+			m = make(map[string]interface{})
+			tree[id] = m
+		}
+		m[name] = v
+	}
+}
+
+func (tree JSONTree) Print() {
+	data, err := json.MarshalIndent(tree, "", "\t")
+	if err != nil {
+		log.Panicf("internal error: JSON marshaling failed: %v", err)
+	}
+	fmt.Printf("%s\n", data)
+}
diff --git a/vendor/golang.org/x/tools/go/analysis/internal/analysisflags/help.go b/vendor/golang.org/x/tools/go/analysis/internal/analysisflags/help.go
new file mode 100644
index 0000000..ce92892
--- /dev/null
+++ b/vendor/golang.org/x/tools/go/analysis/internal/analysisflags/help.go
@@ -0,0 +1,96 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package analysisflags
+
+import (
+	"flag"
+	"fmt"
+	"log"
+	"os"
+	"sort"
+	"strings"
+
+	"golang.org/x/tools/go/analysis"
+)
+
+const help = `PROGNAME is a tool for static analysis of Go programs.
+
+PROGNAME examines Go source code and reports suspicious constructs,
+such as Printf calls whose arguments do not align with the format
+string. It uses heuristics that do not guarantee all reports are
+genuine problems, but it can find errors not caught by the compilers.
+`
+
+// Help implements the help subcommand for a multichecker or unitchecker
+// style command. The optional args specify the analyzers to describe.
+// Help calls log.Fatal if no such analyzer exists.
+func Help(progname string, analyzers []*analysis.Analyzer, args []string) {
+	// No args: show summary of all analyzers.
+	if len(args) == 0 {
+		fmt.Println(strings.Replace(help, "PROGNAME", progname, -1))
+		fmt.Println("Registered analyzers:")
+		fmt.Println()
+		sort.Slice(analyzers, func(i, j int) bool {
+			return analyzers[i].Name < analyzers[j].Name
+		})
+		for _, a := range analyzers {
+			title := strings.Split(a.Doc, "\n\n")[0]
+			fmt.Printf("    %-12s %s\n", a.Name, title)
+		}
+		fmt.Println("\nBy default all analyzers are run.")
+		fmt.Println("To select specific analyzers, use the -NAME flag for each one,")
+		fmt.Println(" or -NAME=false to run all analyzers not explicitly disabled.")
+
+		// Show only the core command-line flags.
+		fmt.Println("\nCore flags:")
+		fmt.Println()
+		fs := flag.NewFlagSet("", flag.ExitOnError)
+		flag.VisitAll(func(f *flag.Flag) {
+			if !strings.Contains(f.Name, ".") {
+				fs.Var(f.Value, f.Name, f.Usage)
+			}
+		})
+		fs.SetOutput(os.Stdout)
+		fs.PrintDefaults()
+
+		fmt.Printf("\nTo see details and flags of a specific analyzer, run '%s help name'.\n", progname)
+
+		return
+	}
+
+	// Show help on specific analyzer(s).
+outer:
+	for _, arg := range args {
+		for _, a := range analyzers {
+			if a.Name == arg {
+				paras := strings.Split(a.Doc, "\n\n")
+				title := paras[0]
+				fmt.Printf("%s: %s\n", a.Name, title)
+
+				// Show only the flags relating to this analysis,
+				// properly prefixed.
+				first := true
+				fs := flag.NewFlagSet(a.Name, flag.ExitOnError)
+				a.Flags.VisitAll(func(f *flag.Flag) {
+					if first {
+						first = false
+						fmt.Println("\nAnalyzer flags:")
+						fmt.Println()
+					}
+					fs.Var(f.Value, a.Name+"."+f.Name, f.Usage)
+				})
+				fs.SetOutput(os.Stdout)
+				fs.PrintDefaults()
+
+				if len(paras) > 1 {
+					fmt.Printf("\n%s\n", strings.Join(paras[1:], "\n\n"))
+				}
+
+				continue outer
+			}
+		}
+		log.Fatalf("Analyzer %q not registered", arg)
+	}
+}
diff --git a/vendor/golang.org/x/tools/go/analysis/internal/checker/checker.go b/vendor/golang.org/x/tools/go/analysis/internal/checker/checker.go
new file mode 100644
index 0000000..5346acd
--- /dev/null
+++ b/vendor/golang.org/x/tools/go/analysis/internal/checker/checker.go
@@ -0,0 +1,978 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package checker defines the implementation of the checker commands.
+// The same code drives the multi-analysis driver, the single-analysis
+// driver that is conventionally provided for convenience along with
+// each analysis package, and the test driver.
+package checker
+
+import (
+	"bytes"
+	"encoding/gob"
+	"errors"
+	"flag"
+	"fmt"
+	"go/format"
+	"go/token"
+	"go/types"
+	"io/ioutil"
+	"log"
+	"os"
+	"reflect"
+	"runtime"
+	"runtime/pprof"
+	"runtime/trace"
+	"sort"
+	"strings"
+	"sync"
+	"time"
+
+	"golang.org/x/tools/go/analysis"
+	"golang.org/x/tools/go/analysis/internal/analysisflags"
+	"golang.org/x/tools/go/packages"
+	"golang.org/x/tools/internal/diff"
+	"golang.org/x/tools/internal/robustio"
+)
+
+var (
+	// Debug is a set of single-letter flags:
+	//
+	//	f	show [f]acts as they are created
+	// 	p	disable [p]arallel execution of analyzers
+	//	s	do additional [s]anity checks on fact types and serialization
+	//	t	show [t]iming info (NB: use 'p' flag to avoid GC/scheduler noise)
+	//	v	show [v]erbose logging
+	//
+	Debug = ""
+
+	// Log files for optional performance tracing.
+	CPUProfile, MemProfile, Trace string
+
+	// IncludeTests indicates whether test files should be analyzed too.
+	IncludeTests = true
+
+	// Fix determines whether to apply all suggested fixes.
+	Fix bool
+)
+
+// RegisterFlags registers command-line flags used by the analysis driver.
+func RegisterFlags() {
+	// When adding flags here, remember to update
+	// the list of suppressed flags in analysisflags.
+
+	flag.StringVar(&Debug, "debug", Debug, `debug flags, any subset of "fpstv"`)
+
+	flag.StringVar(&CPUProfile, "cpuprofile", "", "write CPU profile to this file")
+	flag.StringVar(&MemProfile, "memprofile", "", "write memory profile to this file")
+	flag.StringVar(&Trace, "trace", "", "write trace log to this file")
+	flag.BoolVar(&IncludeTests, "test", IncludeTests, "indicates whether test files should be analyzed, too")
+
+	flag.BoolVar(&Fix, "fix", false, "apply all suggested fixes")
+}
+
+// Run loads the packages specified by args using go/packages,
+// then applies the specified analyzers to them.
+// Analysis flags must already have been set.
+// It provides most of the logic for the main functions of both the
+// singlechecker and the multi-analysis commands.
+// It returns the appropriate exit code.
+func Run(args []string, analyzers []*analysis.Analyzer) (exitcode int) {
+	if CPUProfile != "" {
+		f, err := os.Create(CPUProfile)
+		if err != nil {
+			log.Fatal(err)
+		}
+		if err := pprof.StartCPUProfile(f); err != nil {
+			log.Fatal(err)
+		}
+		// NB: profile won't be written in case of error.
+		defer pprof.StopCPUProfile()
+	}
+
+	if Trace != "" {
+		f, err := os.Create(Trace)
+		if err != nil {
+			log.Fatal(err)
+		}
+		if err := trace.Start(f); err != nil {
+			log.Fatal(err)
+		}
+		// NB: trace log won't be written in case of error.
+		defer func() {
+			trace.Stop()
+			log.Printf("To view the trace, run:\n$ go tool trace view %s", Trace)
+		}()
+	}
+
+	if MemProfile != "" {
+		f, err := os.Create(MemProfile)
+		if err != nil {
+			log.Fatal(err)
+		}
+		// NB: memprofile won't be written in case of error.
+		defer func() {
+			runtime.GC() // get up-to-date statistics
+			if err := pprof.WriteHeapProfile(f); err != nil {
+				log.Fatalf("Writing memory profile: %v", err)
+			}
+			f.Close()
+		}()
+	}
+
+	// Load the packages.
+	if dbg('v') {
+		log.SetPrefix("")
+		log.SetFlags(log.Lmicroseconds) // display timing
+		log.Printf("load %s", args)
+	}
+
+	// Optimization: if the selected analyzers don't produce/consume
+	// facts, we need source only for the initial packages.
+	allSyntax := needFacts(analyzers)
+	initial, err := load(args, allSyntax)
+	if err != nil {
+		if _, ok := err.(typeParseError); !ok {
+			// Fail when some of the errors are not
+			// related to parsing nor typing.
+			log.Print(err)
+			return 1
+		}
+		// TODO: filter analyzers based on RunDespiteError?
+	}
+
+	// Print the results.
+	roots := analyze(initial, analyzers)
+
+	if Fix {
+		if err := applyFixes(roots); err != nil {
+			// Fail when applying fixes failed.
+			log.Print(err)
+			return 1
+		}
+	}
+	return printDiagnostics(roots)
+}
+
+// typeParseError represents a package load error
+// that is related to typing and parsing.
+type typeParseError struct {
+	error
+}
+
+// load loads the initial packages. If all loading issues are related to
+// typing and parsing, the returned error is of type typeParseError.
+func load(patterns []string, allSyntax bool) ([]*packages.Package, error) {
+	mode := packages.LoadSyntax
+	if allSyntax {
+		mode = packages.LoadAllSyntax
+	}
+	conf := packages.Config{
+		Mode:  mode,
+		Tests: IncludeTests,
+	}
+	initial, err := packages.Load(&conf, patterns...)
+	if err == nil {
+		if len(initial) == 0 {
+			err = fmt.Errorf("%s matched no packages", strings.Join(patterns, " "))
+		} else {
+			err = loadingError(initial)
+		}
+	}
+	return initial, err
+}
+
+// loadingError checks for issues during the loading of initial
+// packages. Returns nil if there are no issues. Returns error
+// of type typeParseError if all errors, including those in
+// dependencies, are related to typing or parsing. Otherwise,
+// a plain error is returned with an appropriate message.
+func loadingError(initial []*packages.Package) error {
+	var err error
+	if n := packages.PrintErrors(initial); n > 1 {
+		err = fmt.Errorf("%d errors during loading", n)
+	} else if n == 1 {
+		err = errors.New("error during loading")
+	} else {
+		// no errors
+		return nil
+	}
+	all := true
+	packages.Visit(initial, nil, func(pkg *packages.Package) {
+		for _, err := range pkg.Errors {
+			typeOrParse := err.Kind == packages.TypeError || err.Kind == packages.ParseError
+			all = all && typeOrParse
+		}
+	})
+	if all {
+		return typeParseError{err}
+	}
+	return err
+}
+
+// TestAnalyzer applies an analysis to a set of packages (and their
+// dependencies if necessary) and returns the results.
+//
+// Facts about pkg are returned in a map keyed by object; package facts
+// have a nil key.
+//
+// This entry point is used only by analysistest.
+func TestAnalyzer(a *analysis.Analyzer, pkgs []*packages.Package) []*TestAnalyzerResult {
+	var results []*TestAnalyzerResult
+	for _, act := range analyze(pkgs, []*analysis.Analyzer{a}) {
+		facts := make(map[types.Object][]analysis.Fact)
+		for key, fact := range act.objectFacts {
+			if key.obj.Pkg() == act.pass.Pkg {
+				facts[key.obj] = append(facts[key.obj], fact)
+			}
+		}
+		for key, fact := range act.packageFacts {
+			if key.pkg == act.pass.Pkg {
+				facts[nil] = append(facts[nil], fact)
+			}
+		}
+
+		results = append(results, &TestAnalyzerResult{act.pass, act.diagnostics, facts, act.result, act.err})
+	}
+	return results
+}
+
+type TestAnalyzerResult struct {
+	Pass        *analysis.Pass
+	Diagnostics []analysis.Diagnostic
+	Facts       map[types.Object][]analysis.Fact
+	Result      interface{}
+	Err         error
+}
+
+func analyze(pkgs []*packages.Package, analyzers []*analysis.Analyzer) []*action {
+	// Construct the action graph.
+	if dbg('v') {
+		log.Printf("building graph of analysis passes")
+	}
+
+	// Each graph node (action) is one unit of analysis.
+	// Edges express package-to-package (vertical) dependencies,
+	// and analysis-to-analysis (horizontal) dependencies.
+	type key struct {
+		*analysis.Analyzer
+		*packages.Package
+	}
+	actions := make(map[key]*action)
+
+	var mkAction func(a *analysis.Analyzer, pkg *packages.Package) *action
+	mkAction = func(a *analysis.Analyzer, pkg *packages.Package) *action {
+		k := key{a, pkg}
+		act, ok := actions[k]
+		if !ok {
+			act = &action{a: a, pkg: pkg}
+
+			// Add a dependency on each required analyzers.
+			for _, req := range a.Requires {
+				act.deps = append(act.deps, mkAction(req, pkg))
+			}
+
+			// An analysis that consumes/produces facts
+			// must run on the package's dependencies too.
+			if len(a.FactTypes) > 0 {
+				paths := make([]string, 0, len(pkg.Imports))
+				for path := range pkg.Imports {
+					paths = append(paths, path)
+				}
+				sort.Strings(paths) // for determinism
+				for _, path := range paths {
+					dep := mkAction(a, pkg.Imports[path])
+					act.deps = append(act.deps, dep)
+				}
+			}
+
+			actions[k] = act
+		}
+		return act
+	}
+
+	// Build nodes for initial packages.
+	var roots []*action
+	for _, a := range analyzers {
+		for _, pkg := range pkgs {
+			root := mkAction(a, pkg)
+			root.isroot = true
+			roots = append(roots, root)
+		}
+	}
+
+	// Execute the graph in parallel.
+	execAll(roots)
+
+	return roots
+}
+
+func applyFixes(roots []*action) error {
+	// visit all of the actions and accumulate the suggested edits.
+	paths := make(map[robustio.FileID]string)
+	editsByAction := make(map[robustio.FileID]map[*action][]diff.Edit)
+	visited := make(map[*action]bool)
+	var apply func(*action) error
+	var visitAll func(actions []*action) error
+	visitAll = func(actions []*action) error {
+		for _, act := range actions {
+			if !visited[act] {
+				visited[act] = true
+				if err := visitAll(act.deps); err != nil {
+					return err
+				}
+				if err := apply(act); err != nil {
+					return err
+				}
+			}
+		}
+		return nil
+	}
+
+	apply = func(act *action) error {
+		editsForTokenFile := make(map[*token.File][]diff.Edit)
+		for _, diag := range act.diagnostics {
+			for _, sf := range diag.SuggestedFixes {
+				for _, edit := range sf.TextEdits {
+					// Validate the edit.
+					// Any error here indicates a bug in the analyzer.
+					file := act.pkg.Fset.File(edit.Pos)
+					if file == nil {
+						return fmt.Errorf("analysis %q suggests invalid fix: missing file info for pos (%v)",
+							act.a.Name, edit.Pos)
+					}
+					if edit.Pos > edit.End {
+						return fmt.Errorf("analysis %q suggests invalid fix: pos (%v) > end (%v)",
+							act.a.Name, edit.Pos, edit.End)
+					}
+					if eof := token.Pos(file.Base() + file.Size()); edit.End > eof {
+						return fmt.Errorf("analysis %q suggests invalid fix: end (%v) past end of file (%v)",
+							act.a.Name, edit.End, eof)
+					}
+					edit := diff.Edit{Start: file.Offset(edit.Pos), End: file.Offset(edit.End), New: string(edit.NewText)}
+					editsForTokenFile[file] = append(editsForTokenFile[file], edit)
+				}
+			}
+		}
+
+		for f, edits := range editsForTokenFile {
+			id, _, err := robustio.GetFileID(f.Name())
+			if err != nil {
+				return err
+			}
+			if _, hasId := paths[id]; !hasId {
+				paths[id] = f.Name()
+				editsByAction[id] = make(map[*action][]diff.Edit)
+			}
+			editsByAction[id][act] = edits
+		}
+		return nil
+	}
+
+	if err := visitAll(roots); err != nil {
+		return err
+	}
+
+	// Validate and group the edits to each actual file.
+	editsByPath := make(map[string][]diff.Edit)
+	for id, actToEdits := range editsByAction {
+		path := paths[id]
+		actions := make([]*action, 0, len(actToEdits))
+		for act := range actToEdits {
+			actions = append(actions, act)
+		}
+
+		// Does any action create conflicting edits?
+		for _, act := range actions {
+			edits := actToEdits[act]
+			if _, invalid := validateEdits(edits); invalid > 0 {
+				name, x, y := act.a.Name, edits[invalid-1], edits[invalid]
+				return diff3Conflict(path, name, name, []diff.Edit{x}, []diff.Edit{y})
+			}
+		}
+
+		// Does any pair of different actions create edits that conflict?
+		for j := range actions {
+			for k := range actions[:j] {
+				x, y := actions[j], actions[k]
+				if x.a.Name > y.a.Name {
+					x, y = y, x
+				}
+				xedits, yedits := actToEdits[x], actToEdits[y]
+				combined := append(xedits, yedits...)
+				if _, invalid := validateEdits(combined); invalid > 0 {
+					// TODO: consider applying each action's consistent list of edits entirely,
+					// and then using a three-way merge (such as GNU diff3) on the resulting
+					// files to report more precisely the parts that actually conflict.
+					return diff3Conflict(path, x.a.Name, y.a.Name, xedits, yedits)
+				}
+			}
+		}
+
+		var edits []diff.Edit
+		for act := range actToEdits {
+			edits = append(edits, actToEdits[act]...)
+		}
+		editsByPath[path], _ = validateEdits(edits) // remove duplicates. already validated.
+	}
+
+	// Now we've got a set of valid edits for each file. Apply them.
+	for path, edits := range editsByPath {
+		contents, err := ioutil.ReadFile(path)
+		if err != nil {
+			return err
+		}
+
+		out, err := diff.ApplyBytes(contents, edits)
+		if err != nil {
+			return err
+		}
+
+		// Try to format the file.
+		if formatted, err := format.Source(out); err == nil {
+			out = formatted
+		}
+
+		if err := ioutil.WriteFile(path, out, 0644); err != nil {
+			return err
+		}
+	}
+	return nil
+}
+
+// validateEdits returns a list of edits that is sorted and
+// contains no duplicate edits. Returns the index of some
+// overlapping adjacent edits if there is one and <0 if the
+// edits are valid.
+func validateEdits(edits []diff.Edit) ([]diff.Edit, int) {
+	if len(edits) == 0 {
+		return nil, -1
+	}
+	equivalent := func(x, y diff.Edit) bool {
+		return x.Start == y.Start && x.End == y.End && x.New == y.New
+	}
+	diff.SortEdits(edits)
+	unique := []diff.Edit{edits[0]}
+	invalid := -1
+	for i := 1; i < len(edits); i++ {
+		prev, cur := edits[i-1], edits[i]
+		// We skip over equivalent edits without considering them
+		// an error. This handles identical edits coming from the
+		// multiple ways of loading a package into a
+		// *go/packages.Packages for testing, e.g. packages "p" and "p [p.test]".
+		if !equivalent(prev, cur) {
+			unique = append(unique, cur)
+			if prev.End > cur.Start {
+				invalid = i
+			}
+		}
+	}
+	return unique, invalid
+}
+
+// diff3Conflict returns an error describing two conflicting sets of
+// edits on a file at path.
+func diff3Conflict(path string, xlabel, ylabel string, xedits, yedits []diff.Edit) error {
+	contents, err := ioutil.ReadFile(path)
+	if err != nil {
+		return err
+	}
+	oldlabel, old := "base", string(contents)
+
+	xdiff, err := diff.ToUnified(oldlabel, xlabel, old, xedits)
+	if err != nil {
+		return err
+	}
+	ydiff, err := diff.ToUnified(oldlabel, ylabel, old, yedits)
+	if err != nil {
+		return err
+	}
+
+	return fmt.Errorf("conflicting edits from %s and %s on %s\nfirst edits:\n%s\nsecond edits:\n%s",
+		xlabel, ylabel, path, xdiff, ydiff)
+}
+
+// printDiagnostics prints the diagnostics for the root packages in either
+// plain text or JSON format. JSON format also includes errors for any
+// dependencies.
+//
+// It returns the exitcode: in plain mode, 0 for success, 1 for analysis
+// errors, and 3 for diagnostics. We avoid 2 since the flag package uses
+// it. JSON mode always succeeds at printing errors and diagnostics in a
+// structured form to stdout.
+func printDiagnostics(roots []*action) (exitcode int) {
+	// Print the output.
+	//
+	// Print diagnostics only for root packages,
+	// but errors for all packages.
+	printed := make(map[*action]bool)
+	var print func(*action)
+	var visitAll func(actions []*action)
+	visitAll = func(actions []*action) {
+		for _, act := range actions {
+			if !printed[act] {
+				printed[act] = true
+				visitAll(act.deps)
+				print(act)
+			}
+		}
+	}
+
+	if analysisflags.JSON {
+		// JSON output
+		tree := make(analysisflags.JSONTree)
+		print = func(act *action) {
+			var diags []analysis.Diagnostic
+			if act.isroot {
+				diags = act.diagnostics
+			}
+			tree.Add(act.pkg.Fset, act.pkg.ID, act.a.Name, diags, act.err)
+		}
+		visitAll(roots)
+		tree.Print()
+	} else {
+		// plain text output
+
+		// De-duplicate diagnostics by position (not token.Pos) to
+		// avoid double-reporting in source files that belong to
+		// multiple packages, such as foo and foo.test.
+		type key struct {
+			pos token.Position
+			end token.Position
+			*analysis.Analyzer
+			message string
+		}
+		seen := make(map[key]bool)
+
+		print = func(act *action) {
+			if act.err != nil {
+				fmt.Fprintf(os.Stderr, "%s: %v\n", act.a.Name, act.err)
+				exitcode = 1 // analysis failed, at least partially
+				return
+			}
+			if act.isroot {
+				for _, diag := range act.diagnostics {
+					// We don't display a.Name/f.Category
+					// as most users don't care.
+
+					posn := act.pkg.Fset.Position(diag.Pos)
+					end := act.pkg.Fset.Position(diag.End)
+					k := key{posn, end, act.a, diag.Message}
+					if seen[k] {
+						continue // duplicate
+					}
+					seen[k] = true
+
+					analysisflags.PrintPlain(act.pkg.Fset, diag)
+				}
+			}
+		}
+		visitAll(roots)
+
+		if exitcode == 0 && len(seen) > 0 {
+			exitcode = 3 // successfully produced diagnostics
+		}
+	}
+
+	// Print timing info.
+	if dbg('t') {
+		if !dbg('p') {
+			log.Println("Warning: times are mostly GC/scheduler noise; use -debug=tp to disable parallelism")
+		}
+		var all []*action
+		var total time.Duration
+		for act := range printed {
+			all = append(all, act)
+			total += act.duration
+		}
+		sort.Slice(all, func(i, j int) bool {
+			return all[i].duration > all[j].duration
+		})
+
+		// Print actions accounting for 90% of the total.
+		var sum time.Duration
+		for _, act := range all {
+			fmt.Fprintf(os.Stderr, "%s\t%s\n", act.duration, act)
+			sum += act.duration
+			if sum >= total*9/10 {
+				break
+			}
+		}
+	}
+
+	return exitcode
+}
+
+// needFacts reports whether any analysis required by the specified set
+// needs facts.  If so, we must load the entire program from source.
+func needFacts(analyzers []*analysis.Analyzer) bool {
+	seen := make(map[*analysis.Analyzer]bool)
+	var q []*analysis.Analyzer // for BFS
+	q = append(q, analyzers...)
+	for len(q) > 0 {
+		a := q[0]
+		q = q[1:]
+		if !seen[a] {
+			seen[a] = true
+			if len(a.FactTypes) > 0 {
+				return true
+			}
+			q = append(q, a.Requires...)
+		}
+	}
+	return false
+}
+
+// An action represents one unit of analysis work: the application of
+// one analysis to one package. Actions form a DAG, both within a
+// package (as different analyzers are applied, either in sequence or
+// parallel), and across packages (as dependencies are analyzed).
+type action struct {
+	once         sync.Once
+	a            *analysis.Analyzer
+	pkg          *packages.Package
+	pass         *analysis.Pass
+	isroot       bool
+	deps         []*action
+	objectFacts  map[objectFactKey]analysis.Fact
+	packageFacts map[packageFactKey]analysis.Fact
+	result       interface{}
+	diagnostics  []analysis.Diagnostic
+	err          error
+	duration     time.Duration
+}
+
+type objectFactKey struct {
+	obj types.Object
+	typ reflect.Type
+}
+
+type packageFactKey struct {
+	pkg *types.Package
+	typ reflect.Type
+}
+
+func (act *action) String() string {
+	return fmt.Sprintf("%s@%s", act.a, act.pkg)
+}
+
+func execAll(actions []*action) {
+	sequential := dbg('p')
+	var wg sync.WaitGroup
+	for _, act := range actions {
+		wg.Add(1)
+		work := func(act *action) {
+			act.exec()
+			wg.Done()
+		}
+		if sequential {
+			work(act)
+		} else {
+			go work(act)
+		}
+	}
+	wg.Wait()
+}
+
+func (act *action) exec() { act.once.Do(act.execOnce) }
+
+func (act *action) execOnce() {
+	// Analyze dependencies.
+	execAll(act.deps)
+
+	// TODO(adonovan): uncomment this during profiling.
+	// It won't build pre-go1.11 but conditional compilation
+	// using build tags isn't warranted.
+	//
+	// ctx, task := trace.NewTask(context.Background(), "exec")
+	// trace.Log(ctx, "pass", act.String())
+	// defer task.End()
+
+	// Record time spent in this node but not its dependencies.
+	// In parallel mode, due to GC/scheduler contention, the
+	// time is 5x higher than in sequential mode, even with a
+	// semaphore limiting the number of threads here.
+	// So use -debug=tp.
+	if dbg('t') {
+		t0 := time.Now()
+		defer func() { act.duration = time.Since(t0) }()
+	}
+
+	// Report an error if any dependency failed.
+	var failed []string
+	for _, dep := range act.deps {
+		if dep.err != nil {
+			failed = append(failed, dep.String())
+		}
+	}
+	if failed != nil {
+		sort.Strings(failed)
+		act.err = fmt.Errorf("failed prerequisites: %s", strings.Join(failed, ", "))
+		return
+	}
+
+	// Plumb the output values of the dependencies
+	// into the inputs of this action.  Also facts.
+	inputs := make(map[*analysis.Analyzer]interface{})
+	act.objectFacts = make(map[objectFactKey]analysis.Fact)
+	act.packageFacts = make(map[packageFactKey]analysis.Fact)
+	for _, dep := range act.deps {
+		if dep.pkg == act.pkg {
+			// Same package, different analysis (horizontal edge):
+			// in-memory outputs of prerequisite analyzers
+			// become inputs to this analysis pass.
+			inputs[dep.a] = dep.result
+
+		} else if dep.a == act.a { // (always true)
+			// Same analysis, different package (vertical edge):
+			// serialized facts produced by prerequisite analysis
+			// become available to this analysis pass.
+			inheritFacts(act, dep)
+		}
+	}
+
+	// Run the analysis.
+	pass := &analysis.Pass{
+		Analyzer:     act.a,
+		Fset:         act.pkg.Fset,
+		Files:        act.pkg.Syntax,
+		OtherFiles:   act.pkg.OtherFiles,
+		IgnoredFiles: act.pkg.IgnoredFiles,
+		Pkg:          act.pkg.Types,
+		TypesInfo:    act.pkg.TypesInfo,
+		TypesSizes:   act.pkg.TypesSizes,
+		TypeErrors:   act.pkg.TypeErrors,
+
+		ResultOf:          inputs,
+		Report:            func(d analysis.Diagnostic) { act.diagnostics = append(act.diagnostics, d) },
+		ImportObjectFact:  act.importObjectFact,
+		ExportObjectFact:  act.exportObjectFact,
+		ImportPackageFact: act.importPackageFact,
+		ExportPackageFact: act.exportPackageFact,
+		AllObjectFacts:    act.allObjectFacts,
+		AllPackageFacts:   act.allPackageFacts,
+	}
+	act.pass = pass
+
+	var err error
+	if act.pkg.IllTyped && !pass.Analyzer.RunDespiteErrors {
+		err = fmt.Errorf("analysis skipped due to errors in package")
+	} else {
+		act.result, err = pass.Analyzer.Run(pass)
+		if err == nil {
+			if got, want := reflect.TypeOf(act.result), pass.Analyzer.ResultType; got != want {
+				err = fmt.Errorf(
+					"internal error: on package %s, analyzer %s returned a result of type %v, but declared ResultType %v",
+					pass.Pkg.Path(), pass.Analyzer, got, want)
+			}
+		}
+	}
+	act.err = err
+
+	// disallow calls after Run
+	pass.ExportObjectFact = nil
+	pass.ExportPackageFact = nil
+}
+
+// inheritFacts populates act.facts with
+// those it obtains from its dependency, dep.
+func inheritFacts(act, dep *action) {
+	serialize := dbg('s')
+
+	for key, fact := range dep.objectFacts {
+		// Filter out facts related to objects
+		// that are irrelevant downstream
+		// (equivalently: not in the compiler export data).
+		if !exportedFrom(key.obj, dep.pkg.Types) {
+			if false {
+				log.Printf("%v: discarding %T fact from %s for %s: %s", act, fact, dep, key.obj, fact)
+			}
+			continue
+		}
+
+		// Optionally serialize/deserialize fact
+		// to verify that it works across address spaces.
+		if serialize {
+			encodedFact, err := codeFact(fact)
+			if err != nil {
+				log.Panicf("internal error: encoding of %T fact failed in %v: %v", fact, act, err)
+			}
+			fact = encodedFact
+		}
+
+		if false {
+			log.Printf("%v: inherited %T fact for %s: %s", act, fact, key.obj, fact)
+		}
+		act.objectFacts[key] = fact
+	}
+
+	for key, fact := range dep.packageFacts {
+		// TODO: filter out facts that belong to
+		// packages not mentioned in the export data
+		// to prevent side channels.
+
+		// Optionally serialize/deserialize fact
+		// to verify that it works across address spaces
+		// and is deterministic.
+		if serialize {
+			encodedFact, err := codeFact(fact)
+			if err != nil {
+				log.Panicf("internal error: encoding of %T fact failed in %v", fact, act)
+			}
+			fact = encodedFact
+		}
+
+		if false {
+			log.Printf("%v: inherited %T fact for %s: %s", act, fact, key.pkg.Path(), fact)
+		}
+		act.packageFacts[key] = fact
+	}
+}
+
+// codeFact encodes then decodes a fact,
+// just to exercise that logic.
+func codeFact(fact analysis.Fact) (analysis.Fact, error) {
+	// We encode facts one at a time.
+	// A real modular driver would emit all facts
+	// into one encoder to improve gob efficiency.
+	var buf bytes.Buffer
+	if err := gob.NewEncoder(&buf).Encode(fact); err != nil {
+		return nil, err
+	}
+
+	// Encode it twice and assert that we get the same bits.
+	// This helps detect nondeterministic Gob encoding (e.g. of maps).
+	var buf2 bytes.Buffer
+	if err := gob.NewEncoder(&buf2).Encode(fact); err != nil {
+		return nil, err
+	}
+	if !bytes.Equal(buf.Bytes(), buf2.Bytes()) {
+		return nil, fmt.Errorf("encoding of %T fact is nondeterministic", fact)
+	}
+
+	new := reflect.New(reflect.TypeOf(fact).Elem()).Interface().(analysis.Fact)
+	if err := gob.NewDecoder(&buf).Decode(new); err != nil {
+		return nil, err
+	}
+	return new, nil
+}
+
+// exportedFrom reports whether obj may be visible to a package that imports pkg.
+// This includes not just the exported members of pkg, but also unexported
+// constants, types, fields, and methods, perhaps belonging to other packages,
+// that find there way into the API.
+// This is an overapproximation of the more accurate approach used by
+// gc export data, which walks the type graph, but it's much simpler.
+//
+// TODO(adonovan): do more accurate filtering by walking the type graph.
+func exportedFrom(obj types.Object, pkg *types.Package) bool {
+	switch obj := obj.(type) {
+	case *types.Func:
+		return obj.Exported() && obj.Pkg() == pkg ||
+			obj.Type().(*types.Signature).Recv() != nil
+	case *types.Var:
+		if obj.IsField() {
+			return true
+		}
+		// we can't filter more aggressively than this because we need
+		// to consider function parameters exported, but have no way
+		// of telling apart function parameters from local variables.
+		return obj.Pkg() == pkg
+	case *types.TypeName, *types.Const:
+		return true
+	}
+	return false // Nil, Builtin, Label, or PkgName
+}
+
+// importObjectFact implements Pass.ImportObjectFact.
+// Given a non-nil pointer ptr of type *T, where *T satisfies Fact,
+// importObjectFact copies the fact value to *ptr.
+func (act *action) importObjectFact(obj types.Object, ptr analysis.Fact) bool {
+	if obj == nil {
+		panic("nil object")
+	}
+	key := objectFactKey{obj, factType(ptr)}
+	if v, ok := act.objectFacts[key]; ok {
+		reflect.ValueOf(ptr).Elem().Set(reflect.ValueOf(v).Elem())
+		return true
+	}
+	return false
+}
+
+// exportObjectFact implements Pass.ExportObjectFact.
+func (act *action) exportObjectFact(obj types.Object, fact analysis.Fact) {
+	if act.pass.ExportObjectFact == nil {
+		log.Panicf("%s: Pass.ExportObjectFact(%s, %T) called after Run", act, obj, fact)
+	}
+
+	if obj.Pkg() != act.pkg.Types {
+		log.Panicf("internal error: in analysis %s of package %s: Fact.Set(%s, %T): can't set facts on objects belonging another package",
+			act.a, act.pkg, obj, fact)
+	}
+
+	key := objectFactKey{obj, factType(fact)}
+	act.objectFacts[key] = fact // clobber any existing entry
+	if dbg('f') {
+		objstr := types.ObjectString(obj, (*types.Package).Name)
+		fmt.Fprintf(os.Stderr, "%s: object %s has fact %s\n",
+			act.pkg.Fset.Position(obj.Pos()), objstr, fact)
+	}
+}
+
+// allObjectFacts implements Pass.AllObjectFacts.
+func (act *action) allObjectFacts() []analysis.ObjectFact {
+	facts := make([]analysis.ObjectFact, 0, len(act.objectFacts))
+	for k := range act.objectFacts {
+		facts = append(facts, analysis.ObjectFact{Object: k.obj, Fact: act.objectFacts[k]})
+	}
+	return facts
+}
+
+// importPackageFact implements Pass.ImportPackageFact.
+// Given a non-nil pointer ptr of type *T, where *T satisfies Fact,
+// fact copies the fact value to *ptr.
+func (act *action) importPackageFact(pkg *types.Package, ptr analysis.Fact) bool {
+	if pkg == nil {
+		panic("nil package")
+	}
+	key := packageFactKey{pkg, factType(ptr)}
+	if v, ok := act.packageFacts[key]; ok {
+		reflect.ValueOf(ptr).Elem().Set(reflect.ValueOf(v).Elem())
+		return true
+	}
+	return false
+}
+
+// exportPackageFact implements Pass.ExportPackageFact.
+func (act *action) exportPackageFact(fact analysis.Fact) {
+	if act.pass.ExportPackageFact == nil {
+		log.Panicf("%s: Pass.ExportPackageFact(%T) called after Run", act, fact)
+	}
+
+	key := packageFactKey{act.pass.Pkg, factType(fact)}
+	act.packageFacts[key] = fact // clobber any existing entry
+	if dbg('f') {
+		fmt.Fprintf(os.Stderr, "%s: package %s has fact %s\n",
+			act.pkg.Fset.Position(act.pass.Files[0].Pos()), act.pass.Pkg.Path(), fact)
+	}
+}
+
+func factType(fact analysis.Fact) reflect.Type {
+	t := reflect.TypeOf(fact)
+	if t.Kind() != reflect.Ptr {
+		log.Fatalf("invalid Fact type: got %T, want pointer", fact)
+	}
+	return t
+}
+
+// allPackageFacts implements Pass.AllPackageFacts.
+func (act *action) allPackageFacts() []analysis.PackageFact {
+	facts := make([]analysis.PackageFact, 0, len(act.packageFacts))
+	for k := range act.packageFacts {
+		facts = append(facts, analysis.PackageFact{Package: k.pkg, Fact: act.packageFacts[k]})
+	}
+	return facts
+}
+
+func dbg(b byte) bool { return strings.IndexByte(Debug, b) >= 0 }
diff --git a/vendor/golang.org/x/tools/go/analysis/multichecker/multichecker.go b/vendor/golang.org/x/tools/go/analysis/multichecker/multichecker.go
new file mode 100644
index 0000000..3c62be5
--- /dev/null
+++ b/vendor/golang.org/x/tools/go/analysis/multichecker/multichecker.go
@@ -0,0 +1,60 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package multichecker defines the main function for an analysis driver
+// with several analyzers. This package makes it easy for anyone to build
+// an analysis tool containing just the analyzers they need.
+package multichecker
+
+import (
+	"flag"
+	"fmt"
+	"log"
+	"os"
+	"path/filepath"
+	"strings"
+
+	"golang.org/x/tools/go/analysis"
+	"golang.org/x/tools/go/analysis/internal/analysisflags"
+	"golang.org/x/tools/go/analysis/internal/checker"
+	"golang.org/x/tools/go/analysis/unitchecker"
+)
+
+func Main(analyzers ...*analysis.Analyzer) {
+	progname := filepath.Base(os.Args[0])
+	log.SetFlags(0)
+	log.SetPrefix(progname + ": ") // e.g. "vet: "
+
+	if err := analysis.Validate(analyzers); err != nil {
+		log.Fatal(err)
+	}
+
+	checker.RegisterFlags()
+
+	analyzers = analysisflags.Parse(analyzers, true)
+
+	args := flag.Args()
+	if len(args) == 0 {
+		fmt.Fprintf(os.Stderr, `%[1]s is a tool for static analysis of Go programs.
+
+Usage: %[1]s [-flag] [package]
+
+Run '%[1]s help' for more detail,
+ or '%[1]s help name' for details and flags of a specific analyzer.
+`, progname)
+		os.Exit(1)
+	}
+
+	if args[0] == "help" {
+		analysisflags.Help(progname, analyzers, args[1:])
+		os.Exit(0)
+	}
+
+	if len(args) == 1 && strings.HasSuffix(args[0], ".cfg") {
+		unitchecker.Run(args[0], analyzers)
+		panic("unreachable")
+	}
+
+	os.Exit(checker.Run(args, analyzers))
+}
diff --git a/vendor/golang.org/x/tools/go/analysis/unitchecker/unitchecker.go b/vendor/golang.org/x/tools/go/analysis/unitchecker/unitchecker.go
new file mode 100644
index 0000000..3769356
--- /dev/null
+++ b/vendor/golang.org/x/tools/go/analysis/unitchecker/unitchecker.go
@@ -0,0 +1,405 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// The unitchecker package defines the main function for an analysis
+// driver that analyzes a single compilation unit during a build.
+// It is invoked by a build system such as "go vet":
+//
+//	$ go vet -vettool=$(which vet)
+//
+// It supports the following command-line protocol:
+//
+//	-V=full         describe executable               (to the build tool)
+//	-flags          describe flags                    (to the build tool)
+//	foo.cfg         description of compilation unit (from the build tool)
+//
+// This package does not depend on go/packages.
+// If you need a standalone tool, use multichecker,
+// which supports this mode but can also load packages
+// from source using go/packages.
+package unitchecker
+
+// TODO(adonovan):
+// - with gccgo, go build does not build standard library,
+//   so we will not get to analyze it. Yet we must in order
+//   to create base facts for, say, the fmt package for the
+//   printf checker.
+
+import (
+	"encoding/gob"
+	"encoding/json"
+	"flag"
+	"fmt"
+	"go/ast"
+	"go/build"
+	"go/importer"
+	"go/parser"
+	"go/token"
+	"go/types"
+	"io"
+	"io/ioutil"
+	"log"
+	"os"
+	"path/filepath"
+	"reflect"
+	"sort"
+	"strings"
+	"sync"
+	"time"
+
+	"golang.org/x/tools/go/analysis"
+	"golang.org/x/tools/go/analysis/internal/analysisflags"
+	"golang.org/x/tools/internal/facts"
+	"golang.org/x/tools/internal/typeparams"
+)
+
+// A Config describes a compilation unit to be analyzed.
+// It is provided to the tool in a JSON-encoded file
+// whose name ends with ".cfg".
+type Config struct {
+	ID                        string // e.g. "fmt [fmt.test]"
+	Compiler                  string
+	Dir                       string
+	ImportPath                string
+	GoFiles                   []string
+	NonGoFiles                []string
+	IgnoredFiles              []string
+	ImportMap                 map[string]string
+	PackageFile               map[string]string
+	Standard                  map[string]bool
+	PackageVetx               map[string]string
+	VetxOnly                  bool
+	VetxOutput                string
+	SucceedOnTypecheckFailure bool
+}
+
+// Main is the main function of a vet-like analysis tool that must be
+// invoked by a build system to analyze a single package.
+//
+// The protocol required by 'go vet -vettool=...' is that the tool must support:
+//
+//	-flags          describe flags in JSON
+//	-V=full         describe executable for build caching
+//	foo.cfg         perform separate modular analyze on the single
+//	                unit described by a JSON config file foo.cfg.
+func Main(analyzers ...*analysis.Analyzer) {
+	progname := filepath.Base(os.Args[0])
+	log.SetFlags(0)
+	log.SetPrefix(progname + ": ")
+
+	if err := analysis.Validate(analyzers); err != nil {
+		log.Fatal(err)
+	}
+
+	flag.Usage = func() {
+		fmt.Fprintf(os.Stderr, `%[1]s is a tool for static analysis of Go programs.
+
+Usage of %[1]s:
+	%.16[1]s unit.cfg	# execute analysis specified by config file
+	%.16[1]s help    	# general help, including listing analyzers and flags
+	%.16[1]s help name	# help on specific analyzer and its flags
+`, progname)
+		os.Exit(1)
+	}
+
+	analyzers = analysisflags.Parse(analyzers, true)
+
+	args := flag.Args()
+	if len(args) == 0 {
+		flag.Usage()
+	}
+	if args[0] == "help" {
+		analysisflags.Help(progname, analyzers, args[1:])
+		os.Exit(0)
+	}
+	if len(args) != 1 || !strings.HasSuffix(args[0], ".cfg") {
+		log.Fatalf(`invoking "go tool vet" directly is unsupported; use "go vet"`)
+	}
+	Run(args[0], analyzers)
+}
+
+// Run reads the *.cfg file, runs the analysis,
+// and calls os.Exit with an appropriate error code.
+// It assumes flags have already been set.
+func Run(configFile string, analyzers []*analysis.Analyzer) {
+	cfg, err := readConfig(configFile)
+	if err != nil {
+		log.Fatal(err)
+	}
+
+	fset := token.NewFileSet()
+	results, err := run(fset, cfg, analyzers)
+	if err != nil {
+		log.Fatal(err)
+	}
+
+	// In VetxOnly mode, the analysis is run only for facts.
+	if !cfg.VetxOnly {
+		if analysisflags.JSON {
+			// JSON output
+			tree := make(analysisflags.JSONTree)
+			for _, res := range results {
+				tree.Add(fset, cfg.ID, res.a.Name, res.diagnostics, res.err)
+			}
+			tree.Print()
+		} else {
+			// plain text
+			exit := 0
+			for _, res := range results {
+				if res.err != nil {
+					log.Println(res.err)
+					exit = 1
+				}
+			}
+			for _, res := range results {
+				for _, diag := range res.diagnostics {
+					analysisflags.PrintPlain(fset, diag)
+					exit = 1
+				}
+			}
+			os.Exit(exit)
+		}
+	}
+
+	os.Exit(0)
+}
+
+func readConfig(filename string) (*Config, error) {
+	data, err := ioutil.ReadFile(filename)
+	if err != nil {
+		return nil, err
+	}
+	cfg := new(Config)
+	if err := json.Unmarshal(data, cfg); err != nil {
+		return nil, fmt.Errorf("cannot decode JSON config file %s: %v", filename, err)
+	}
+	if len(cfg.GoFiles) == 0 {
+		// The go command disallows packages with no files.
+		// The only exception is unsafe, but the go command
+		// doesn't call vet on it.
+		return nil, fmt.Errorf("package has no files: %s", cfg.ImportPath)
+	}
+	return cfg, nil
+}
+
+var importerForCompiler = func(_ *token.FileSet, compiler string, lookup importer.Lookup) types.Importer {
+	// broken legacy implementation (https://golang.org/issue/28995)
+	return importer.For(compiler, lookup)
+}
+
+func run(fset *token.FileSet, cfg *Config, analyzers []*analysis.Analyzer) ([]result, error) {
+	// Load, parse, typecheck.
+	var files []*ast.File
+	for _, name := range cfg.GoFiles {
+		f, err := parser.ParseFile(fset, name, nil, parser.ParseComments)
+		if err != nil {
+			if cfg.SucceedOnTypecheckFailure {
+				// Silently succeed; let the compiler
+				// report parse errors.
+				err = nil
+			}
+			return nil, err
+		}
+		files = append(files, f)
+	}
+	compilerImporter := importerForCompiler(fset, cfg.Compiler, func(path string) (io.ReadCloser, error) {
+		// path is a resolved package path, not an import path.
+		file, ok := cfg.PackageFile[path]
+		if !ok {
+			if cfg.Compiler == "gccgo" && cfg.Standard[path] {
+				return nil, nil // fall back to default gccgo lookup
+			}
+			return nil, fmt.Errorf("no package file for %q", path)
+		}
+		return os.Open(file)
+	})
+	importer := importerFunc(func(importPath string) (*types.Package, error) {
+		path, ok := cfg.ImportMap[importPath] // resolve vendoring, etc
+		if !ok {
+			return nil, fmt.Errorf("can't resolve import %q", path)
+		}
+		return compilerImporter.Import(path)
+	})
+	tc := &types.Config{
+		Importer: importer,
+		Sizes:    types.SizesFor("gc", build.Default.GOARCH), // assume gccgo ≡ gc?
+	}
+	info := &types.Info{
+		Types:      make(map[ast.Expr]types.TypeAndValue),
+		Defs:       make(map[*ast.Ident]types.Object),
+		Uses:       make(map[*ast.Ident]types.Object),
+		Implicits:  make(map[ast.Node]types.Object),
+		Scopes:     make(map[ast.Node]*types.Scope),
+		Selections: make(map[*ast.SelectorExpr]*types.Selection),
+	}
+	typeparams.InitInstanceInfo(info)
+
+	pkg, err := tc.Check(cfg.ImportPath, fset, files, info)
+	if err != nil {
+		if cfg.SucceedOnTypecheckFailure {
+			// Silently succeed; let the compiler
+			// report type errors.
+			err = nil
+		}
+		return nil, err
+	}
+
+	// Register fact types with gob.
+	// In VetxOnly mode, analyzers are only for their facts,
+	// so we can skip any analysis that neither produces facts
+	// nor depends on any analysis that produces facts.
+	//
+	// TODO(adonovan): fix: the command (and logic!) here are backwards.
+	// It should say "...nor is required by any...". (Issue 443099)
+	//
+	// Also build a map to hold working state and result.
+	type action struct {
+		once        sync.Once
+		result      interface{}
+		err         error
+		usesFacts   bool // (transitively uses)
+		diagnostics []analysis.Diagnostic
+	}
+	actions := make(map[*analysis.Analyzer]*action)
+	var registerFacts func(a *analysis.Analyzer) bool
+	registerFacts = func(a *analysis.Analyzer) bool {
+		act, ok := actions[a]
+		if !ok {
+			act = new(action)
+			var usesFacts bool
+			for _, f := range a.FactTypes {
+				usesFacts = true
+				gob.Register(f)
+			}
+			for _, req := range a.Requires {
+				if registerFacts(req) {
+					usesFacts = true
+				}
+			}
+			act.usesFacts = usesFacts
+			actions[a] = act
+		}
+		return act.usesFacts
+	}
+	var filtered []*analysis.Analyzer
+	for _, a := range analyzers {
+		if registerFacts(a) || !cfg.VetxOnly {
+			filtered = append(filtered, a)
+		}
+	}
+	analyzers = filtered
+
+	// Read facts from imported packages.
+	read := func(imp *types.Package) ([]byte, error) {
+		if vetx, ok := cfg.PackageVetx[imp.Path()]; ok {
+			return ioutil.ReadFile(vetx)
+		}
+		return nil, nil // no .vetx file, no facts
+	}
+	facts, err := facts.NewDecoder(pkg).Decode(read)
+	if err != nil {
+		return nil, err
+	}
+
+	// In parallel, execute the DAG of analyzers.
+	var exec func(a *analysis.Analyzer) *action
+	var execAll func(analyzers []*analysis.Analyzer)
+	exec = func(a *analysis.Analyzer) *action {
+		act := actions[a]
+		act.once.Do(func() {
+			execAll(a.Requires) // prefetch dependencies in parallel
+
+			// The inputs to this analysis are the
+			// results of its prerequisites.
+			inputs := make(map[*analysis.Analyzer]interface{})
+			var failed []string
+			for _, req := range a.Requires {
+				reqact := exec(req)
+				if reqact.err != nil {
+					failed = append(failed, req.String())
+					continue
+				}
+				inputs[req] = reqact.result
+			}
+
+			// Report an error if any dependency failed.
+			if failed != nil {
+				sort.Strings(failed)
+				act.err = fmt.Errorf("failed prerequisites: %s", strings.Join(failed, ", "))
+				return
+			}
+
+			factFilter := make(map[reflect.Type]bool)
+			for _, f := range a.FactTypes {
+				factFilter[reflect.TypeOf(f)] = true
+			}
+
+			pass := &analysis.Pass{
+				Analyzer:          a,
+				Fset:              fset,
+				Files:             files,
+				OtherFiles:        cfg.NonGoFiles,
+				IgnoredFiles:      cfg.IgnoredFiles,
+				Pkg:               pkg,
+				TypesInfo:         info,
+				TypesSizes:        tc.Sizes,
+				TypeErrors:        nil, // unitchecker doesn't RunDespiteErrors
+				ResultOf:          inputs,
+				Report:            func(d analysis.Diagnostic) { act.diagnostics = append(act.diagnostics, d) },
+				ImportObjectFact:  facts.ImportObjectFact,
+				ExportObjectFact:  facts.ExportObjectFact,
+				AllObjectFacts:    func() []analysis.ObjectFact { return facts.AllObjectFacts(factFilter) },
+				ImportPackageFact: facts.ImportPackageFact,
+				ExportPackageFact: facts.ExportPackageFact,
+				AllPackageFacts:   func() []analysis.PackageFact { return facts.AllPackageFacts(factFilter) },
+			}
+
+			t0 := time.Now()
+			act.result, act.err = a.Run(pass)
+			if false {
+				log.Printf("analysis %s = %s", pass, time.Since(t0))
+			}
+		})
+		return act
+	}
+	execAll = func(analyzers []*analysis.Analyzer) {
+		var wg sync.WaitGroup
+		for _, a := range analyzers {
+			wg.Add(1)
+			go func(a *analysis.Analyzer) {
+				_ = exec(a)
+				wg.Done()
+			}(a)
+		}
+		wg.Wait()
+	}
+
+	execAll(analyzers)
+
+	// Return diagnostics and errors from root analyzers.
+	results := make([]result, len(analyzers))
+	for i, a := range analyzers {
+		act := actions[a]
+		results[i].a = a
+		results[i].err = act.err
+		results[i].diagnostics = act.diagnostics
+	}
+
+	data := facts.Encode()
+	if err := ioutil.WriteFile(cfg.VetxOutput, data, 0666); err != nil {
+		return nil, fmt.Errorf("failed to write analysis facts: %v", err)
+	}
+
+	return results, nil
+}
+
+type result struct {
+	a           *analysis.Analyzer
+	diagnostics []analysis.Diagnostic
+	err         error
+}
+
+type importerFunc func(path string) (*types.Package, error)
+
+func (f importerFunc) Import(path string) (*types.Package, error) { return f(path) }
diff --git a/vendor/golang.org/x/tools/go/analysis/unitchecker/unitchecker112.go b/vendor/golang.org/x/tools/go/analysis/unitchecker/unitchecker112.go
new file mode 100644
index 0000000..3180f4a
--- /dev/null
+++ b/vendor/golang.org/x/tools/go/analysis/unitchecker/unitchecker112.go
@@ -0,0 +1,14 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build go1.12
+// +build go1.12
+
+package unitchecker
+
+import "go/importer"
+
+func init() {
+	importerForCompiler = importer.ForCompiler
+}
diff --git a/vendor/golang.org/x/tools/go/analysis/validate.go b/vendor/golang.org/x/tools/go/analysis/validate.go
new file mode 100644
index 0000000..9da5692
--- /dev/null
+++ b/vendor/golang.org/x/tools/go/analysis/validate.go
@@ -0,0 +1,135 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package analysis
+
+import (
+	"fmt"
+	"reflect"
+	"strings"
+	"unicode"
+)
+
+// Validate reports an error if any of the analyzers are misconfigured.
+// Checks include:
+// that the name is a valid identifier;
+// that the Doc is not empty;
+// that the Run is non-nil;
+// that the Requires graph is acyclic;
+// that analyzer fact types are unique;
+// that each fact type is a pointer.
+func Validate(analyzers []*Analyzer) error {
+	// Map each fact type to its sole generating analyzer.
+	factTypes := make(map[reflect.Type]*Analyzer)
+
+	// Traverse the Requires graph, depth first.
+	const (
+		white = iota
+		grey
+		black
+		finished
+	)
+	color := make(map[*Analyzer]uint8)
+	var visit func(a *Analyzer) error
+	visit = func(a *Analyzer) error {
+		if a == nil {
+			return fmt.Errorf("nil *Analyzer")
+		}
+		if color[a] == white {
+			color[a] = grey
+
+			// names
+			if !validIdent(a.Name) {
+				return fmt.Errorf("invalid analyzer name %q", a)
+			}
+
+			if a.Doc == "" {
+				return fmt.Errorf("analyzer %q is undocumented", a)
+			}
+
+			if a.Run == nil {
+				return fmt.Errorf("analyzer %q has nil Run", a)
+			}
+			// fact types
+			for _, f := range a.FactTypes {
+				if f == nil {
+					return fmt.Errorf("analyzer %s has nil FactType", a)
+				}
+				t := reflect.TypeOf(f)
+				if prev := factTypes[t]; prev != nil {
+					return fmt.Errorf("fact type %s registered by two analyzers: %v, %v",
+						t, a, prev)
+				}
+				if t.Kind() != reflect.Ptr {
+					return fmt.Errorf("%s: fact type %s is not a pointer", a, t)
+				}
+				factTypes[t] = a
+			}
+
+			// recursion
+			for _, req := range a.Requires {
+				if err := visit(req); err != nil {
+					return err
+				}
+			}
+			color[a] = black
+		}
+
+		if color[a] == grey {
+			stack := []*Analyzer{a}
+			inCycle := map[string]bool{}
+			for len(stack) > 0 {
+				current := stack[len(stack)-1]
+				stack = stack[:len(stack)-1]
+				if color[current] == grey && !inCycle[current.Name] {
+					inCycle[current.Name] = true
+					stack = append(stack, current.Requires...)
+				}
+			}
+			return &CycleInRequiresGraphError{AnalyzerNames: inCycle}
+		}
+
+		return nil
+	}
+	for _, a := range analyzers {
+		if err := visit(a); err != nil {
+			return err
+		}
+	}
+
+	// Reject duplicates among analyzers.
+	// Precondition:  color[a] == black.
+	// Postcondition: color[a] == finished.
+	for _, a := range analyzers {
+		if color[a] == finished {
+			return fmt.Errorf("duplicate analyzer: %s", a.Name)
+		}
+		color[a] = finished
+	}
+
+	return nil
+}
+
+func validIdent(name string) bool {
+	for i, r := range name {
+		if !(r == '_' || unicode.IsLetter(r) || i > 0 && unicode.IsDigit(r)) {
+			return false
+		}
+	}
+	return name != ""
+}
+
+type CycleInRequiresGraphError struct {
+	AnalyzerNames map[string]bool
+}
+
+func (e *CycleInRequiresGraphError) Error() string {
+	var b strings.Builder
+	b.WriteString("cycle detected involving the following analyzers:")
+	for n := range e.AnalyzerNames {
+		b.WriteByte(' ')
+		b.WriteString(n)
+	}
+	return b.String()
+}
diff --git a/vendor/golang.org/x/tools/go/gcexportdata/gcexportdata.go b/vendor/golang.org/x/tools/go/gcexportdata/gcexportdata.go
new file mode 100644
index 0000000..165ede0
--- /dev/null
+++ b/vendor/golang.org/x/tools/go/gcexportdata/gcexportdata.go
@@ -0,0 +1,187 @@
+// Copyright 2016 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package gcexportdata provides functions for locating, reading, and
+// writing export data files containing type information produced by the
+// gc compiler.  This package supports go1.7 export data format and all
+// later versions.
+//
+// Although it might seem convenient for this package to live alongside
+// go/types in the standard library, this would cause version skew
+// problems for developer tools that use it, since they must be able to
+// consume the outputs of the gc compiler both before and after a Go
+// update such as from Go 1.7 to Go 1.8.  Because this package lives in
+// golang.org/x/tools, sites can update their version of this repo some
+// time before the Go 1.8 release and rebuild and redeploy their
+// developer tools, which will then be able to consume both Go 1.7 and
+// Go 1.8 export data files, so they will work before and after the
+// Go update. (See discussion at https://golang.org/issue/15651.)
+package gcexportdata // import "golang.org/x/tools/go/gcexportdata"
+
+import (
+	"bufio"
+	"bytes"
+	"encoding/json"
+	"fmt"
+	"go/token"
+	"go/types"
+	"io"
+	"os/exec"
+
+	"golang.org/x/tools/internal/gcimporter"
+)
+
+// Find returns the name of an object (.o) or archive (.a) file
+// containing type information for the specified import path,
+// using the go command.
+// If no file was found, an empty filename is returned.
+//
+// A relative srcDir is interpreted relative to the current working directory.
+//
+// Find also returns the package's resolved (canonical) import path,
+// reflecting the effects of srcDir and vendoring on importPath.
+//
+// Deprecated: Use the higher-level API in golang.org/x/tools/go/packages,
+// which is more efficient.
+func Find(importPath, srcDir string) (filename, path string) {
+	cmd := exec.Command("go", "list", "-json", "-export", "--", importPath)
+	cmd.Dir = srcDir
+	out, err := cmd.CombinedOutput()
+	if err != nil {
+		return "", ""
+	}
+	var data struct {
+		ImportPath string
+		Export     string
+	}
+	json.Unmarshal(out, &data)
+	return data.Export, data.ImportPath
+}
+
+// NewReader returns a reader for the export data section of an object
+// (.o) or archive (.a) file read from r.  The new reader may provide
+// additional trailing data beyond the end of the export data.
+func NewReader(r io.Reader) (io.Reader, error) {
+	buf := bufio.NewReader(r)
+	_, size, err := gcimporter.FindExportData(buf)
+	if err != nil {
+		return nil, err
+	}
+
+	if size >= 0 {
+		// We were given an archive and found the __.PKGDEF in it.
+		// This tells us the size of the export data, and we don't
+		// need to return the entire file.
+		return &io.LimitedReader{
+			R: buf,
+			N: size,
+		}, nil
+	} else {
+		// We were given an object file. As such, we don't know how large
+		// the export data is and must return the entire file.
+		return buf, nil
+	}
+}
+
+// readAll works the same way as io.ReadAll, but avoids allocations and copies
+// by preallocating a byte slice of the necessary size if the size is known up
+// front. This is always possible when the input is an archive. In that case,
+// NewReader will return the known size using an io.LimitedReader.
+func readAll(r io.Reader) ([]byte, error) {
+	if lr, ok := r.(*io.LimitedReader); ok {
+		data := make([]byte, lr.N)
+		_, err := io.ReadFull(lr, data)
+		return data, err
+	}
+	return io.ReadAll(r)
+}
+
+// Read reads export data from in, decodes it, and returns type
+// information for the package.
+//
+// The package path (effectively its linker symbol prefix) is
+// specified by path, since unlike the package name, this information
+// may not be recorded in the export data.
+//
+// File position information is added to fset.
+//
+// Read may inspect and add to the imports map to ensure that references
+// within the export data to other packages are consistent.  The caller
+// must ensure that imports[path] does not exist, or exists but is
+// incomplete (see types.Package.Complete), and Read inserts the
+// resulting package into this map entry.
+//
+// On return, the state of the reader is undefined.
+func Read(in io.Reader, fset *token.FileSet, imports map[string]*types.Package, path string) (*types.Package, error) {
+	data, err := readAll(in)
+	if err != nil {
+		return nil, fmt.Errorf("reading export data for %q: %v", path, err)
+	}
+
+	if bytes.HasPrefix(data, []byte("!<arch>")) {
+		return nil, fmt.Errorf("can't read export data for %q directly from an archive file (call gcexportdata.NewReader first to extract export data)", path)
+	}
+
+	// The indexed export format starts with an 'i'; the older
+	// binary export format starts with a 'c', 'd', or 'v'
+	// (from "version"). Select appropriate importer.
+	if len(data) > 0 {
+		switch data[0] {
+		case 'i':
+			_, pkg, err := gcimporter.IImportData(fset, imports, data[1:], path)
+			return pkg, err
+
+		case 'v', 'c', 'd':
+			_, pkg, err := gcimporter.BImportData(fset, imports, data, path)
+			return pkg, err
+
+		case 'u':
+			_, pkg, err := gcimporter.UImportData(fset, imports, data[1:], path)
+			return pkg, err
+
+		default:
+			l := len(data)
+			if l > 10 {
+				l = 10
+			}
+			return nil, fmt.Errorf("unexpected export data with prefix %q for path %s", string(data[:l]), path)
+		}
+	}
+	return nil, fmt.Errorf("empty export data for %s", path)
+}
+
+// Write writes encoded type information for the specified package to out.
+// The FileSet provides file position information for named objects.
+func Write(out io.Writer, fset *token.FileSet, pkg *types.Package) error {
+	if _, err := io.WriteString(out, "i"); err != nil {
+		return err
+	}
+	return gcimporter.IExportData(out, fset, pkg)
+}
+
+// ReadBundle reads an export bundle from in, decodes it, and returns type
+// information for the packages.
+// File position information is added to fset.
+//
+// ReadBundle may inspect and add to the imports map to ensure that references
+// within the export bundle to other packages are consistent.
+//
+// On return, the state of the reader is undefined.
+//
+// Experimental: This API is experimental and may change in the future.
+func ReadBundle(in io.Reader, fset *token.FileSet, imports map[string]*types.Package) ([]*types.Package, error) {
+	data, err := readAll(in)
+	if err != nil {
+		return nil, fmt.Errorf("reading export bundle: %v", err)
+	}
+	return gcimporter.IImportBundle(fset, imports, data)
+}
+
+// WriteBundle writes encoded type information for the specified packages to out.
+// The FileSet provides file position information for named objects.
+//
+// Experimental: This API is experimental and may change in the future.
+func WriteBundle(out io.Writer, fset *token.FileSet, pkgs []*types.Package) error {
+	return gcimporter.IExportBundle(out, fset, pkgs)
+}
diff --git a/vendor/golang.org/x/tools/go/gcexportdata/importer.go b/vendor/golang.org/x/tools/go/gcexportdata/importer.go
new file mode 100644
index 0000000..37a7247
--- /dev/null
+++ b/vendor/golang.org/x/tools/go/gcexportdata/importer.go
@@ -0,0 +1,75 @@
+// Copyright 2016 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package gcexportdata
+
+import (
+	"fmt"
+	"go/token"
+	"go/types"
+	"os"
+)
+
+// NewImporter returns a new instance of the types.Importer interface
+// that reads type information from export data files written by gc.
+// The Importer also satisfies types.ImporterFrom.
+//
+// Export data files are located using "go build" workspace conventions
+// and the build.Default context.
+//
+// Use this importer instead of go/importer.For("gc", ...) to avoid the
+// version-skew problems described in the documentation of this package,
+// or to control the FileSet or access the imports map populated during
+// package loading.
+//
+// Deprecated: Use the higher-level API in golang.org/x/tools/go/packages,
+// which is more efficient.
+func NewImporter(fset *token.FileSet, imports map[string]*types.Package) types.ImporterFrom {
+	return importer{fset, imports}
+}
+
+type importer struct {
+	fset    *token.FileSet
+	imports map[string]*types.Package
+}
+
+func (imp importer) Import(importPath string) (*types.Package, error) {
+	return imp.ImportFrom(importPath, "", 0)
+}
+
+func (imp importer) ImportFrom(importPath, srcDir string, mode types.ImportMode) (_ *types.Package, err error) {
+	filename, path := Find(importPath, srcDir)
+	if filename == "" {
+		if importPath == "unsafe" {
+			// Even for unsafe, call Find first in case
+			// the package was vendored.
+			return types.Unsafe, nil
+		}
+		return nil, fmt.Errorf("can't find import: %s", importPath)
+	}
+
+	if pkg, ok := imp.imports[path]; ok && pkg.Complete() {
+		return pkg, nil // cache hit
+	}
+
+	// open file
+	f, err := os.Open(filename)
+	if err != nil {
+		return nil, err
+	}
+	defer func() {
+		f.Close()
+		if err != nil {
+			// add file name to error
+			err = fmt.Errorf("reading export data: %s: %v", filename, err)
+		}
+	}()
+
+	r, err := NewReader(f)
+	if err != nil {
+		return nil, err
+	}
+
+	return Read(r, imp.fset, imp.imports, path)
+}
diff --git a/vendor/golang.org/x/tools/go/internal/packagesdriver/sizes.go b/vendor/golang.org/x/tools/go/internal/packagesdriver/sizes.go
new file mode 100644
index 0000000..18a002f
--- /dev/null
+++ b/vendor/golang.org/x/tools/go/internal/packagesdriver/sizes.go
@@ -0,0 +1,49 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package packagesdriver fetches type sizes for go/packages and go/analysis.
+package packagesdriver
+
+import (
+	"context"
+	"fmt"
+	"go/types"
+	"strings"
+
+	"golang.org/x/tools/internal/gocommand"
+)
+
+var debug = false
+
+func GetSizesGolist(ctx context.Context, inv gocommand.Invocation, gocmdRunner *gocommand.Runner) (types.Sizes, error) {
+	inv.Verb = "list"
+	inv.Args = []string{"-f", "{{context.GOARCH}} {{context.Compiler}}", "--", "unsafe"}
+	stdout, stderr, friendlyErr, rawErr := gocmdRunner.RunRaw(ctx, inv)
+	var goarch, compiler string
+	if rawErr != nil {
+		if rawErrMsg := rawErr.Error(); strings.Contains(rawErrMsg, "cannot find main module") || strings.Contains(rawErrMsg, "go.mod file not found") {
+			// User's running outside of a module. All bets are off. Get GOARCH and guess compiler is gc.
+			// TODO(matloob): Is this a problem in practice?
+			inv.Verb = "env"
+			inv.Args = []string{"GOARCH"}
+			envout, enverr := gocmdRunner.Run(ctx, inv)
+			if enverr != nil {
+				return nil, enverr
+			}
+			goarch = strings.TrimSpace(envout.String())
+			compiler = "gc"
+		} else {
+			return nil, friendlyErr
+		}
+	} else {
+		fields := strings.Fields(stdout.String())
+		if len(fields) < 2 {
+			return nil, fmt.Errorf("could not parse GOARCH and Go compiler in format \"<GOARCH> <compiler>\":\nstdout: <<%s>>\nstderr: <<%s>>",
+				stdout.String(), stderr.String())
+		}
+		goarch = fields[0]
+		compiler = fields[1]
+	}
+	return types.SizesFor(compiler, goarch), nil
+}
diff --git a/vendor/golang.org/x/tools/go/packages/doc.go b/vendor/golang.org/x/tools/go/packages/doc.go
new file mode 100644
index 0000000..da4ab89
--- /dev/null
+++ b/vendor/golang.org/x/tools/go/packages/doc.go
@@ -0,0 +1,220 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+/*
+Package packages loads Go packages for inspection and analysis.
+
+The Load function takes as input a list of patterns and return a list of Package
+structs describing individual packages matched by those patterns.
+The LoadMode controls the amount of detail in the loaded packages.
+
+Load passes most patterns directly to the underlying build tool,
+but all patterns with the prefix "query=", where query is a
+non-empty string of letters from [a-z], are reserved and may be
+interpreted as query operators.
+
+Two query operators are currently supported: "file" and "pattern".
+
+The query "file=path/to/file.go" matches the package or packages enclosing
+the Go source file path/to/file.go.  For example "file=~/go/src/fmt/print.go"
+might return the packages "fmt" and "fmt [fmt.test]".
+
+The query "pattern=string" causes "string" to be passed directly to
+the underlying build tool. In most cases this is unnecessary,
+but an application can use Load("pattern=" + x) as an escaping mechanism
+to ensure that x is not interpreted as a query operator if it contains '='.
+
+All other query operators are reserved for future use and currently
+cause Load to report an error.
+
+The Package struct provides basic information about the package, including
+
+  - ID, a unique identifier for the package in the returned set;
+  - GoFiles, the names of the package's Go source files;
+  - Imports, a map from source import strings to the Packages they name;
+  - Types, the type information for the package's exported symbols;
+  - Syntax, the parsed syntax trees for the package's source code; and
+  - TypeInfo, the result of a complete type-check of the package syntax trees.
+
+(See the documentation for type Package for the complete list of fields
+and more detailed descriptions.)
+
+For example,
+
+	Load(nil, "bytes", "unicode...")
+
+returns four Package structs describing the standard library packages
+bytes, unicode, unicode/utf16, and unicode/utf8. Note that one pattern
+can match multiple packages and that a package might be matched by
+multiple patterns: in general it is not possible to determine which
+packages correspond to which patterns.
+
+Note that the list returned by Load contains only the packages matched
+by the patterns. Their dependencies can be found by walking the import
+graph using the Imports fields.
+
+The Load function can be configured by passing a pointer to a Config as
+the first argument. A nil Config is equivalent to the zero Config, which
+causes Load to run in LoadFiles mode, collecting minimal information.
+See the documentation for type Config for details.
+
+As noted earlier, the Config.Mode controls the amount of detail
+reported about the loaded packages. See the documentation for type LoadMode
+for details.
+
+Most tools should pass their command-line arguments (after any flags)
+uninterpreted to the loader, so that the loader can interpret them
+according to the conventions of the underlying build system.
+See the Example function for typical usage.
+*/
+package packages // import "golang.org/x/tools/go/packages"
+
+/*
+
+Motivation and design considerations
+
+The new package's design solves problems addressed by two existing
+packages: go/build, which locates and describes packages, and
+golang.org/x/tools/go/loader, which loads, parses and type-checks them.
+The go/build.Package structure encodes too much of the 'go build' way
+of organizing projects, leaving us in need of a data type that describes a
+package of Go source code independent of the underlying build system.
+We wanted something that works equally well with go build and vgo, and
+also other build systems such as Bazel and Blaze, making it possible to
+construct analysis tools that work in all these environments.
+Tools such as errcheck and staticcheck were essentially unavailable to
+the Go community at Google, and some of Google's internal tools for Go
+are unavailable externally.
+This new package provides a uniform way to obtain package metadata by
+querying each of these build systems, optionally supporting their
+preferred command-line notations for packages, so that tools integrate
+neatly with users' build environments. The Metadata query function
+executes an external query tool appropriate to the current workspace.
+
+Loading packages always returns the complete import graph "all the way down",
+even if all you want is information about a single package, because the query
+mechanisms of all the build systems we currently support ({go,vgo} list, and
+blaze/bazel aspect-based query) cannot provide detailed information
+about one package without visiting all its dependencies too, so there is
+no additional asymptotic cost to providing transitive information.
+(This property might not be true of a hypothetical 5th build system.)
+
+In calls to TypeCheck, all initial packages, and any package that
+transitively depends on one of them, must be loaded from source.
+Consider A->B->C->D->E: if A,C are initial, A,B,C must be loaded from
+source; D may be loaded from export data, and E may not be loaded at all
+(though it's possible that D's export data mentions it, so a
+types.Package may be created for it and exposed.)
+
+The old loader had a feature to suppress type-checking of function
+bodies on a per-package basis, primarily intended to reduce the work of
+obtaining type information for imported packages. Now that imports are
+satisfied by export data, the optimization no longer seems necessary.
+
+Despite some early attempts, the old loader did not exploit export data,
+instead always using the equivalent of WholeProgram mode. This was due
+to the complexity of mixing source and export data packages (now
+resolved by the upward traversal mentioned above), and because export data
+files were nearly always missing or stale. Now that 'go build' supports
+caching, all the underlying build systems can guarantee to produce
+export data in a reasonable (amortized) time.
+
+Test "main" packages synthesized by the build system are now reported as
+first-class packages, avoiding the need for clients (such as go/ssa) to
+reinvent this generation logic.
+
+One way in which go/packages is simpler than the old loader is in its
+treatment of in-package tests. In-package tests are packages that
+consist of all the files of the library under test, plus the test files.
+The old loader constructed in-package tests by a two-phase process of
+mutation called "augmentation": first it would construct and type check
+all the ordinary library packages and type-check the packages that
+depend on them; then it would add more (test) files to the package and
+type-check again. This two-phase approach had four major problems:
+1) in processing the tests, the loader modified the library package,
+   leaving no way for a client application to see both the test
+   package and the library package; one would mutate into the other.
+2) because test files can declare additional methods on types defined in
+   the library portion of the package, the dispatch of method calls in
+   the library portion was affected by the presence of the test files.
+   This should have been a clue that the packages were logically
+   different.
+3) this model of "augmentation" assumed at most one in-package test
+   per library package, which is true of projects using 'go build',
+   but not other build systems.
+4) because of the two-phase nature of test processing, all packages that
+   import the library package had to be processed before augmentation,
+   forcing a "one-shot" API and preventing the client from calling Load
+   in several times in sequence as is now possible in WholeProgram mode.
+   (TypeCheck mode has a similar one-shot restriction for a different reason.)
+
+Early drafts of this package supported "multi-shot" operation.
+Although it allowed clients to make a sequence of calls (or concurrent
+calls) to Load, building up the graph of Packages incrementally,
+it was of marginal value: it complicated the API
+(since it allowed some options to vary across calls but not others),
+it complicated the implementation,
+it cannot be made to work in Types mode, as explained above,
+and it was less efficient than making one combined call (when this is possible).
+Among the clients we have inspected, none made multiple calls to load
+but could not be easily and satisfactorily modified to make only a single call.
+However, applications changes may be required.
+For example, the ssadump command loads the user-specified packages
+and in addition the runtime package.  It is tempting to simply append
+"runtime" to the user-provided list, but that does not work if the user
+specified an ad-hoc package such as [a.go b.go].
+Instead, ssadump no longer requests the runtime package,
+but seeks it among the dependencies of the user-specified packages,
+and emits an error if it is not found.
+
+Overlays: The Overlay field in the Config allows providing alternate contents
+for Go source files, by providing a mapping from file path to contents.
+go/packages will pull in new imports added in overlay files when go/packages
+is run in LoadImports mode or greater.
+Overlay support for the go list driver isn't complete yet: if the file doesn't
+exist on disk, it will only be recognized in an overlay if it is a non-test file
+and the package would be reported even without the overlay.
+
+Questions & Tasks
+
+- Add GOARCH/GOOS?
+  They are not portable concepts, but could be made portable.
+  Our goal has been to allow users to express themselves using the conventions
+  of the underlying build system: if the build system honors GOARCH
+  during a build and during a metadata query, then so should
+  applications built atop that query mechanism.
+  Conversely, if the target architecture of the build is determined by
+  command-line flags, the application can pass the relevant
+  flags through to the build system using a command such as:
+    myapp -query_flag="--cpu=amd64" -query_flag="--os=darwin"
+  However, this approach is low-level, unwieldy, and non-portable.
+  GOOS and GOARCH seem important enough to warrant a dedicated option.
+
+- How should we handle partial failures such as a mixture of good and
+  malformed patterns, existing and non-existent packages, successful and
+  failed builds, import failures, import cycles, and so on, in a call to
+  Load?
+
+- Support bazel, blaze, and go1.10 list, not just go1.11 list.
+
+- Handle (and test) various partial success cases, e.g.
+  a mixture of good packages and:
+  invalid patterns
+  nonexistent packages
+  empty packages
+  packages with malformed package or import declarations
+  unreadable files
+  import cycles
+  other parse errors
+  type errors
+  Make sure we record errors at the correct place in the graph.
+
+- Missing packages among initial arguments are not reported.
+  Return bogus packages for them, like golist does.
+
+- "undeclared name" errors (for example) are reported out of source file
+  order. I suspect this is due to the breadth-first resolution now used
+  by go/types. Is that a bug? Discuss with gri.
+
+*/
diff --git a/vendor/golang.org/x/tools/go/packages/external.go b/vendor/golang.org/x/tools/go/packages/external.go
new file mode 100644
index 0000000..7242a0a
--- /dev/null
+++ b/vendor/golang.org/x/tools/go/packages/external.go
@@ -0,0 +1,101 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This file enables an external tool to intercept package requests.
+// If the tool is present then its results are used in preference to
+// the go list command.
+
+package packages
+
+import (
+	"bytes"
+	"encoding/json"
+	"fmt"
+	exec "golang.org/x/sys/execabs"
+	"os"
+	"strings"
+)
+
+// The Driver Protocol
+//
+// The driver, given the inputs to a call to Load, returns metadata about the packages specified.
+// This allows for different build systems to support go/packages by telling go/packages how the
+// packages' source is organized.
+// The driver is a binary, either specified by the GOPACKAGESDRIVER environment variable or in
+// the path as gopackagesdriver. It's given the inputs to load in its argv. See the package
+// documentation in doc.go for the full description of the patterns that need to be supported.
+// A driver receives as a JSON-serialized driverRequest struct in standard input and will
+// produce a JSON-serialized driverResponse (see definition in packages.go) in its standard output.
+
+// driverRequest is used to provide the portion of Load's Config that is needed by a driver.
+type driverRequest struct {
+	Mode LoadMode `json:"mode"`
+	// Env specifies the environment the underlying build system should be run in.
+	Env []string `json:"env"`
+	// BuildFlags are flags that should be passed to the underlying build system.
+	BuildFlags []string `json:"build_flags"`
+	// Tests specifies whether the patterns should also return test packages.
+	Tests bool `json:"tests"`
+	// Overlay maps file paths (relative to the driver's working directory) to the byte contents
+	// of overlay files.
+	Overlay map[string][]byte `json:"overlay"`
+}
+
+// findExternalDriver returns the file path of a tool that supplies
+// the build system package structure, or "" if not found."
+// If GOPACKAGESDRIVER is set in the environment findExternalTool returns its
+// value, otherwise it searches for a binary named gopackagesdriver on the PATH.
+func findExternalDriver(cfg *Config) driver {
+	const toolPrefix = "GOPACKAGESDRIVER="
+	tool := ""
+	for _, env := range cfg.Env {
+		if val := strings.TrimPrefix(env, toolPrefix); val != env {
+			tool = val
+		}
+	}
+	if tool != "" && tool == "off" {
+		return nil
+	}
+	if tool == "" {
+		var err error
+		tool, err = exec.LookPath("gopackagesdriver")
+		if err != nil {
+			return nil
+		}
+	}
+	return func(cfg *Config, words ...string) (*driverResponse, error) {
+		req, err := json.Marshal(driverRequest{
+			Mode:       cfg.Mode,
+			Env:        cfg.Env,
+			BuildFlags: cfg.BuildFlags,
+			Tests:      cfg.Tests,
+			Overlay:    cfg.Overlay,
+		})
+		if err != nil {
+			return nil, fmt.Errorf("failed to encode message to driver tool: %v", err)
+		}
+
+		buf := new(bytes.Buffer)
+		stderr := new(bytes.Buffer)
+		cmd := exec.CommandContext(cfg.Context, tool, words...)
+		cmd.Dir = cfg.Dir
+		cmd.Env = cfg.Env
+		cmd.Stdin = bytes.NewReader(req)
+		cmd.Stdout = buf
+		cmd.Stderr = stderr
+
+		if err := cmd.Run(); err != nil {
+			return nil, fmt.Errorf("%v: %v: %s", tool, err, cmd.Stderr)
+		}
+		if len(stderr.Bytes()) != 0 && os.Getenv("GOPACKAGESPRINTDRIVERERRORS") != "" {
+			fmt.Fprintf(os.Stderr, "%s stderr: <<%s>>\n", cmdDebugStr(cmd), stderr)
+		}
+
+		var response driverResponse
+		if err := json.Unmarshal(buf.Bytes(), &response); err != nil {
+			return nil, err
+		}
+		return &response, nil
+	}
+}
diff --git a/vendor/golang.org/x/tools/go/packages/golist.go b/vendor/golang.org/x/tools/go/packages/golist.go
new file mode 100644
index 0000000..6bb7168
--- /dev/null
+++ b/vendor/golang.org/x/tools/go/packages/golist.go
@@ -0,0 +1,1173 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package packages
+
+import (
+	"bytes"
+	"context"
+	"encoding/json"
+	"fmt"
+	"go/types"
+	"io/ioutil"
+	"log"
+	"os"
+	"path"
+	"path/filepath"
+	"reflect"
+	"sort"
+	"strconv"
+	"strings"
+	"sync"
+	"unicode"
+
+	exec "golang.org/x/sys/execabs"
+	"golang.org/x/tools/go/internal/packagesdriver"
+	"golang.org/x/tools/internal/gocommand"
+	"golang.org/x/tools/internal/packagesinternal"
+)
+
+// debug controls verbose logging.
+var debug, _ = strconv.ParseBool(os.Getenv("GOPACKAGESDEBUG"))
+
+// A goTooOldError reports that the go command
+// found by exec.LookPath is too old to use the new go list behavior.
+type goTooOldError struct {
+	error
+}
+
+// responseDeduper wraps a driverResponse, deduplicating its contents.
+type responseDeduper struct {
+	seenRoots    map[string]bool
+	seenPackages map[string]*Package
+	dr           *driverResponse
+}
+
+func newDeduper() *responseDeduper {
+	return &responseDeduper{
+		dr:           &driverResponse{},
+		seenRoots:    map[string]bool{},
+		seenPackages: map[string]*Package{},
+	}
+}
+
+// addAll fills in r with a driverResponse.
+func (r *responseDeduper) addAll(dr *driverResponse) {
+	for _, pkg := range dr.Packages {
+		r.addPackage(pkg)
+	}
+	for _, root := range dr.Roots {
+		r.addRoot(root)
+	}
+	r.dr.GoVersion = dr.GoVersion
+}
+
+func (r *responseDeduper) addPackage(p *Package) {
+	if r.seenPackages[p.ID] != nil {
+		return
+	}
+	r.seenPackages[p.ID] = p
+	r.dr.Packages = append(r.dr.Packages, p)
+}
+
+func (r *responseDeduper) addRoot(id string) {
+	if r.seenRoots[id] {
+		return
+	}
+	r.seenRoots[id] = true
+	r.dr.Roots = append(r.dr.Roots, id)
+}
+
+type golistState struct {
+	cfg *Config
+	ctx context.Context
+
+	envOnce    sync.Once
+	goEnvError error
+	goEnv      map[string]string
+
+	rootsOnce     sync.Once
+	rootDirsError error
+	rootDirs      map[string]string
+
+	goVersionOnce  sync.Once
+	goVersionError error
+	goVersion      int // The X in Go 1.X.
+
+	// vendorDirs caches the (non)existence of vendor directories.
+	vendorDirs map[string]bool
+}
+
+// getEnv returns Go environment variables. Only specific variables are
+// populated -- computing all of them is slow.
+func (state *golistState) getEnv() (map[string]string, error) {
+	state.envOnce.Do(func() {
+		var b *bytes.Buffer
+		b, state.goEnvError = state.invokeGo("env", "-json", "GOMOD", "GOPATH")
+		if state.goEnvError != nil {
+			return
+		}
+
+		state.goEnv = make(map[string]string)
+		decoder := json.NewDecoder(b)
+		if state.goEnvError = decoder.Decode(&state.goEnv); state.goEnvError != nil {
+			return
+		}
+	})
+	return state.goEnv, state.goEnvError
+}
+
+// mustGetEnv is a convenience function that can be used if getEnv has already succeeded.
+func (state *golistState) mustGetEnv() map[string]string {
+	env, err := state.getEnv()
+	if err != nil {
+		panic(fmt.Sprintf("mustGetEnv: %v", err))
+	}
+	return env
+}
+
+// goListDriver uses the go list command to interpret the patterns and produce
+// the build system package structure.
+// See driver for more details.
+func goListDriver(cfg *Config, patterns ...string) (*driverResponse, error) {
+	// Make sure that any asynchronous go commands are killed when we return.
+	parentCtx := cfg.Context
+	if parentCtx == nil {
+		parentCtx = context.Background()
+	}
+	ctx, cancel := context.WithCancel(parentCtx)
+	defer cancel()
+
+	response := newDeduper()
+
+	state := &golistState{
+		cfg:        cfg,
+		ctx:        ctx,
+		vendorDirs: map[string]bool{},
+	}
+
+	// Fill in response.Sizes asynchronously if necessary.
+	var sizeserr error
+	var sizeswg sync.WaitGroup
+	if cfg.Mode&NeedTypesSizes != 0 || cfg.Mode&NeedTypes != 0 {
+		sizeswg.Add(1)
+		go func() {
+			var sizes types.Sizes
+			sizes, sizeserr = packagesdriver.GetSizesGolist(ctx, state.cfgInvocation(), cfg.gocmdRunner)
+			// types.SizesFor always returns nil or a *types.StdSizes.
+			response.dr.Sizes, _ = sizes.(*types.StdSizes)
+			sizeswg.Done()
+		}()
+	}
+
+	// Determine files requested in contains patterns
+	var containFiles []string
+	restPatterns := make([]string, 0, len(patterns))
+	// Extract file= and other [querytype]= patterns. Report an error if querytype
+	// doesn't exist.
+extractQueries:
+	for _, pattern := range patterns {
+		eqidx := strings.Index(pattern, "=")
+		if eqidx < 0 {
+			restPatterns = append(restPatterns, pattern)
+		} else {
+			query, value := pattern[:eqidx], pattern[eqidx+len("="):]
+			switch query {
+			case "file":
+				containFiles = append(containFiles, value)
+			case "pattern":
+				restPatterns = append(restPatterns, value)
+			case "": // not a reserved query
+				restPatterns = append(restPatterns, pattern)
+			default:
+				for _, rune := range query {
+					if rune < 'a' || rune > 'z' { // not a reserved query
+						restPatterns = append(restPatterns, pattern)
+						continue extractQueries
+					}
+				}
+				// Reject all other patterns containing "="
+				return nil, fmt.Errorf("invalid query type %q in query pattern %q", query, pattern)
+			}
+		}
+	}
+
+	// See if we have any patterns to pass through to go list. Zero initial
+	// patterns also requires a go list call, since it's the equivalent of
+	// ".".
+	if len(restPatterns) > 0 || len(patterns) == 0 {
+		dr, err := state.createDriverResponse(restPatterns...)
+		if err != nil {
+			return nil, err
+		}
+		response.addAll(dr)
+	}
+
+	if len(containFiles) != 0 {
+		if err := state.runContainsQueries(response, containFiles); err != nil {
+			return nil, err
+		}
+	}
+
+	// Only use go/packages' overlay processing if we're using a Go version
+	// below 1.16. Otherwise, go list handles it.
+	if goVersion, err := state.getGoVersion(); err == nil && goVersion < 16 {
+		modifiedPkgs, needPkgs, err := state.processGolistOverlay(response)
+		if err != nil {
+			return nil, err
+		}
+
+		var containsCandidates []string
+		if len(containFiles) > 0 {
+			containsCandidates = append(containsCandidates, modifiedPkgs...)
+			containsCandidates = append(containsCandidates, needPkgs...)
+		}
+		if err := state.addNeededOverlayPackages(response, needPkgs); err != nil {
+			return nil, err
+		}
+		// Check candidate packages for containFiles.
+		if len(containFiles) > 0 {
+			for _, id := range containsCandidates {
+				pkg, ok := response.seenPackages[id]
+				if !ok {
+					response.addPackage(&Package{
+						ID: id,
+						Errors: []Error{{
+							Kind: ListError,
+							Msg:  fmt.Sprintf("package %s expected but not seen", id),
+						}},
+					})
+					continue
+				}
+				for _, f := range containFiles {
+					for _, g := range pkg.GoFiles {
+						if sameFile(f, g) {
+							response.addRoot(id)
+						}
+					}
+				}
+			}
+		}
+		// Add root for any package that matches a pattern. This applies only to
+		// packages that are modified by overlays, since they are not added as
+		// roots automatically.
+		for _, pattern := range restPatterns {
+			match := matchPattern(pattern)
+			for _, pkgID := range modifiedPkgs {
+				pkg, ok := response.seenPackages[pkgID]
+				if !ok {
+					continue
+				}
+				if match(pkg.PkgPath) {
+					response.addRoot(pkg.ID)
+				}
+			}
+		}
+	}
+
+	sizeswg.Wait()
+	if sizeserr != nil {
+		return nil, sizeserr
+	}
+	return response.dr, nil
+}
+
+func (state *golistState) addNeededOverlayPackages(response *responseDeduper, pkgs []string) error {
+	if len(pkgs) == 0 {
+		return nil
+	}
+	dr, err := state.createDriverResponse(pkgs...)
+	if err != nil {
+		return err
+	}
+	for _, pkg := range dr.Packages {
+		response.addPackage(pkg)
+	}
+	_, needPkgs, err := state.processGolistOverlay(response)
+	if err != nil {
+		return err
+	}
+	return state.addNeededOverlayPackages(response, needPkgs)
+}
+
+func (state *golistState) runContainsQueries(response *responseDeduper, queries []string) error {
+	for _, query := range queries {
+		// TODO(matloob): Do only one query per directory.
+		fdir := filepath.Dir(query)
+		// Pass absolute path of directory to go list so that it knows to treat it as a directory,
+		// not a package path.
+		pattern, err := filepath.Abs(fdir)
+		if err != nil {
+			return fmt.Errorf("could not determine absolute path of file= query path %q: %v", query, err)
+		}
+		dirResponse, err := state.createDriverResponse(pattern)
+
+		// If there was an error loading the package, or no packages are returned,
+		// or the package is returned with errors, try to load the file as an
+		// ad-hoc package.
+		// Usually the error will appear in a returned package, but may not if we're
+		// in module mode and the ad-hoc is located outside a module.
+		if err != nil || len(dirResponse.Packages) == 0 || len(dirResponse.Packages) == 1 && len(dirResponse.Packages[0].GoFiles) == 0 &&
+			len(dirResponse.Packages[0].Errors) == 1 {
+			var queryErr error
+			if dirResponse, queryErr = state.adhocPackage(pattern, query); queryErr != nil {
+				return err // return the original error
+			}
+		}
+		isRoot := make(map[string]bool, len(dirResponse.Roots))
+		for _, root := range dirResponse.Roots {
+			isRoot[root] = true
+		}
+		for _, pkg := range dirResponse.Packages {
+			// Add any new packages to the main set
+			// We don't bother to filter packages that will be dropped by the changes of roots,
+			// that will happen anyway during graph construction outside this function.
+			// Over-reporting packages is not a problem.
+			response.addPackage(pkg)
+			// if the package was not a root one, it cannot have the file
+			if !isRoot[pkg.ID] {
+				continue
+			}
+			for _, pkgFile := range pkg.GoFiles {
+				if filepath.Base(query) == filepath.Base(pkgFile) {
+					response.addRoot(pkg.ID)
+					break
+				}
+			}
+		}
+	}
+	return nil
+}
+
+// adhocPackage attempts to load or construct an ad-hoc package for a given
+// query, if the original call to the driver produced inadequate results.
+func (state *golistState) adhocPackage(pattern, query string) (*driverResponse, error) {
+	response, err := state.createDriverResponse(query)
+	if err != nil {
+		return nil, err
+	}
+	// If we get nothing back from `go list`,
+	// try to make this file into its own ad-hoc package.
+	// TODO(rstambler): Should this check against the original response?
+	if len(response.Packages) == 0 {
+		response.Packages = append(response.Packages, &Package{
+			ID:              "command-line-arguments",
+			PkgPath:         query,
+			GoFiles:         []string{query},
+			CompiledGoFiles: []string{query},
+			Imports:         make(map[string]*Package),
+		})
+		response.Roots = append(response.Roots, "command-line-arguments")
+	}
+	// Handle special cases.
+	if len(response.Packages) == 1 {
+		// golang/go#33482: If this is a file= query for ad-hoc packages where
+		// the file only exists on an overlay, and exists outside of a module,
+		// add the file to the package and remove the errors.
+		if response.Packages[0].ID == "command-line-arguments" ||
+			filepath.ToSlash(response.Packages[0].PkgPath) == filepath.ToSlash(query) {
+			if len(response.Packages[0].GoFiles) == 0 {
+				filename := filepath.Join(pattern, filepath.Base(query)) // avoid recomputing abspath
+				// TODO(matloob): check if the file is outside of a root dir?
+				for path := range state.cfg.Overlay {
+					if path == filename {
+						response.Packages[0].Errors = nil
+						response.Packages[0].GoFiles = []string{path}
+						response.Packages[0].CompiledGoFiles = []string{path}
+					}
+				}
+			}
+		}
+	}
+	return response, nil
+}
+
+// Fields must match go list;
+// see $GOROOT/src/cmd/go/internal/load/pkg.go.
+type jsonPackage struct {
+	ImportPath        string
+	Dir               string
+	Name              string
+	Export            string
+	GoFiles           []string
+	CompiledGoFiles   []string
+	IgnoredGoFiles    []string
+	IgnoredOtherFiles []string
+	EmbedPatterns     []string
+	EmbedFiles        []string
+	CFiles            []string
+	CgoFiles          []string
+	CXXFiles          []string
+	MFiles            []string
+	HFiles            []string
+	FFiles            []string
+	SFiles            []string
+	SwigFiles         []string
+	SwigCXXFiles      []string
+	SysoFiles         []string
+	Imports           []string
+	ImportMap         map[string]string
+	Deps              []string
+	Module            *Module
+	TestGoFiles       []string
+	TestImports       []string
+	XTestGoFiles      []string
+	XTestImports      []string
+	ForTest           string // q in a "p [q.test]" package, else ""
+	DepOnly           bool
+
+	Error      *packagesinternal.PackageError
+	DepsErrors []*packagesinternal.PackageError
+}
+
+type jsonPackageError struct {
+	ImportStack []string
+	Pos         string
+	Err         string
+}
+
+func otherFiles(p *jsonPackage) [][]string {
+	return [][]string{p.CFiles, p.CXXFiles, p.MFiles, p.HFiles, p.FFiles, p.SFiles, p.SwigFiles, p.SwigCXXFiles, p.SysoFiles}
+}
+
+// createDriverResponse uses the "go list" command to expand the pattern
+// words and return a response for the specified packages.
+func (state *golistState) createDriverResponse(words ...string) (*driverResponse, error) {
+	// go list uses the following identifiers in ImportPath and Imports:
+	//
+	// 	"p"			-- importable package or main (command)
+	// 	"q.test"		-- q's test executable
+	// 	"p [q.test]"		-- variant of p as built for q's test executable
+	// 	"q_test [q.test]"	-- q's external test package
+	//
+	// The packages p that are built differently for a test q.test
+	// are q itself, plus any helpers used by the external test q_test,
+	// typically including "testing" and all its dependencies.
+
+	// Run "go list" for complete
+	// information on the specified packages.
+	goVersion, err := state.getGoVersion()
+	if err != nil {
+		return nil, err
+	}
+	buf, err := state.invokeGo("list", golistargs(state.cfg, words, goVersion)...)
+	if err != nil {
+		return nil, err
+	}
+
+	seen := make(map[string]*jsonPackage)
+	pkgs := make(map[string]*Package)
+	additionalErrors := make(map[string][]Error)
+	// Decode the JSON and convert it to Package form.
+	response := &driverResponse{
+		GoVersion: goVersion,
+	}
+	for dec := json.NewDecoder(buf); dec.More(); {
+		p := new(jsonPackage)
+		if err := dec.Decode(p); err != nil {
+			return nil, fmt.Errorf("JSON decoding failed: %v", err)
+		}
+
+		if p.ImportPath == "" {
+			// The documentation for go list says that “[e]rroneous packages will have
+			// a non-empty ImportPath”. If for some reason it comes back empty, we
+			// prefer to error out rather than silently discarding data or handing
+			// back a package without any way to refer to it.
+			if p.Error != nil {
+				return nil, Error{
+					Pos: p.Error.Pos,
+					Msg: p.Error.Err,
+				}
+			}
+			return nil, fmt.Errorf("package missing import path: %+v", p)
+		}
+
+		// Work around https://golang.org/issue/33157:
+		// go list -e, when given an absolute path, will find the package contained at
+		// that directory. But when no package exists there, it will return a fake package
+		// with an error and the ImportPath set to the absolute path provided to go list.
+		// Try to convert that absolute path to what its package path would be if it's
+		// contained in a known module or GOPATH entry. This will allow the package to be
+		// properly "reclaimed" when overlays are processed.
+		if filepath.IsAbs(p.ImportPath) && p.Error != nil {
+			pkgPath, ok, err := state.getPkgPath(p.ImportPath)
+			if err != nil {
+				return nil, err
+			}
+			if ok {
+				p.ImportPath = pkgPath
+			}
+		}
+
+		if old, found := seen[p.ImportPath]; found {
+			// If one version of the package has an error, and the other doesn't, assume
+			// that this is a case where go list is reporting a fake dependency variant
+			// of the imported package: When a package tries to invalidly import another
+			// package, go list emits a variant of the imported package (with the same
+			// import path, but with an error on it, and the package will have a
+			// DepError set on it). An example of when this can happen is for imports of
+			// main packages: main packages can not be imported, but they may be
+			// separately matched and listed by another pattern.
+			// See golang.org/issue/36188 for more details.
+
+			// The plan is that eventually, hopefully in Go 1.15, the error will be
+			// reported on the importing package rather than the duplicate "fake"
+			// version of the imported package. Once all supported versions of Go
+			// have the new behavior this logic can be deleted.
+			// TODO(matloob): delete the workaround logic once all supported versions of
+			// Go return the errors on the proper package.
+
+			// There should be exactly one version of a package that doesn't have an
+			// error.
+			if old.Error == nil && p.Error == nil {
+				if !reflect.DeepEqual(p, old) {
+					return nil, fmt.Errorf("internal error: go list gives conflicting information for package %v", p.ImportPath)
+				}
+				continue
+			}
+
+			// Determine if this package's error needs to be bubbled up.
+			// This is a hack, and we expect for go list to eventually set the error
+			// on the package.
+			if old.Error != nil {
+				var errkind string
+				if strings.Contains(old.Error.Err, "not an importable package") {
+					errkind = "not an importable package"
+				} else if strings.Contains(old.Error.Err, "use of internal package") && strings.Contains(old.Error.Err, "not allowed") {
+					errkind = "use of internal package not allowed"
+				}
+				if errkind != "" {
+					if len(old.Error.ImportStack) < 1 {
+						return nil, fmt.Errorf(`internal error: go list gave a %q error with empty import stack`, errkind)
+					}
+					importingPkg := old.Error.ImportStack[len(old.Error.ImportStack)-1]
+					if importingPkg == old.ImportPath {
+						// Using an older version of Go which put this package itself on top of import
+						// stack, instead of the importer. Look for importer in second from top
+						// position.
+						if len(old.Error.ImportStack) < 2 {
+							return nil, fmt.Errorf(`internal error: go list gave a %q error with an import stack without importing package`, errkind)
+						}
+						importingPkg = old.Error.ImportStack[len(old.Error.ImportStack)-2]
+					}
+					additionalErrors[importingPkg] = append(additionalErrors[importingPkg], Error{
+						Pos:  old.Error.Pos,
+						Msg:  old.Error.Err,
+						Kind: ListError,
+					})
+				}
+			}
+
+			// Make sure that if there's a version of the package without an error,
+			// that's the one reported to the user.
+			if old.Error == nil {
+				continue
+			}
+
+			// This package will replace the old one at the end of the loop.
+		}
+		seen[p.ImportPath] = p
+
+		pkg := &Package{
+			Name:            p.Name,
+			ID:              p.ImportPath,
+			GoFiles:         absJoin(p.Dir, p.GoFiles, p.CgoFiles),
+			CompiledGoFiles: absJoin(p.Dir, p.CompiledGoFiles),
+			OtherFiles:      absJoin(p.Dir, otherFiles(p)...),
+			EmbedFiles:      absJoin(p.Dir, p.EmbedFiles),
+			EmbedPatterns:   absJoin(p.Dir, p.EmbedPatterns),
+			IgnoredFiles:    absJoin(p.Dir, p.IgnoredGoFiles, p.IgnoredOtherFiles),
+			forTest:         p.ForTest,
+			depsErrors:      p.DepsErrors,
+			Module:          p.Module,
+		}
+
+		if (state.cfg.Mode&typecheckCgo) != 0 && len(p.CgoFiles) != 0 {
+			if len(p.CompiledGoFiles) > len(p.GoFiles) {
+				// We need the cgo definitions, which are in the first
+				// CompiledGoFile after the non-cgo ones. This is a hack but there
+				// isn't currently a better way to find it. We also need the pure
+				// Go files and unprocessed cgo files, all of which are already
+				// in pkg.GoFiles.
+				cgoTypes := p.CompiledGoFiles[len(p.GoFiles)]
+				pkg.CompiledGoFiles = append([]string{cgoTypes}, pkg.GoFiles...)
+			} else {
+				// golang/go#38990: go list silently fails to do cgo processing
+				pkg.CompiledGoFiles = nil
+				pkg.Errors = append(pkg.Errors, Error{
+					Msg:  "go list failed to return CompiledGoFiles. This may indicate failure to perform cgo processing; try building at the command line. See https://golang.org/issue/38990.",
+					Kind: ListError,
+				})
+			}
+		}
+
+		// Work around https://golang.org/issue/28749:
+		// cmd/go puts assembly, C, and C++ files in CompiledGoFiles.
+		// Remove files from CompiledGoFiles that are non-go files
+		// (or are not files that look like they are from the cache).
+		if len(pkg.CompiledGoFiles) > 0 {
+			out := pkg.CompiledGoFiles[:0]
+			for _, f := range pkg.CompiledGoFiles {
+				if ext := filepath.Ext(f); ext != ".go" && ext != "" { // ext == "" means the file is from the cache, so probably cgo-processed file
+					continue
+				}
+				out = append(out, f)
+			}
+			pkg.CompiledGoFiles = out
+		}
+
+		// Extract the PkgPath from the package's ID.
+		if i := strings.IndexByte(pkg.ID, ' '); i >= 0 {
+			pkg.PkgPath = pkg.ID[:i]
+		} else {
+			pkg.PkgPath = pkg.ID
+		}
+
+		if pkg.PkgPath == "unsafe" {
+			pkg.GoFiles = nil // ignore fake unsafe.go file
+		}
+
+		// Assume go list emits only absolute paths for Dir.
+		if p.Dir != "" && !filepath.IsAbs(p.Dir) {
+			log.Fatalf("internal error: go list returned non-absolute Package.Dir: %s", p.Dir)
+		}
+
+		if p.Export != "" && !filepath.IsAbs(p.Export) {
+			pkg.ExportFile = filepath.Join(p.Dir, p.Export)
+		} else {
+			pkg.ExportFile = p.Export
+		}
+
+		// imports
+		//
+		// Imports contains the IDs of all imported packages.
+		// ImportsMap records (path, ID) only where they differ.
+		ids := make(map[string]bool)
+		for _, id := range p.Imports {
+			ids[id] = true
+		}
+		pkg.Imports = make(map[string]*Package)
+		for path, id := range p.ImportMap {
+			pkg.Imports[path] = &Package{ID: id} // non-identity import
+			delete(ids, id)
+		}
+		for id := range ids {
+			if id == "C" {
+				continue
+			}
+
+			pkg.Imports[id] = &Package{ID: id} // identity import
+		}
+		if !p.DepOnly {
+			response.Roots = append(response.Roots, pkg.ID)
+		}
+
+		// Work around for pre-go.1.11 versions of go list.
+		// TODO(matloob): they should be handled by the fallback.
+		// Can we delete this?
+		if len(pkg.CompiledGoFiles) == 0 {
+			pkg.CompiledGoFiles = pkg.GoFiles
+		}
+
+		// Temporary work-around for golang/go#39986. Parse filenames out of
+		// error messages. This happens if there are unrecoverable syntax
+		// errors in the source, so we can't match on a specific error message.
+		if err := p.Error; err != nil && state.shouldAddFilenameFromError(p) {
+			addFilenameFromPos := func(pos string) bool {
+				split := strings.Split(pos, ":")
+				if len(split) < 1 {
+					return false
+				}
+				filename := strings.TrimSpace(split[0])
+				if filename == "" {
+					return false
+				}
+				if !filepath.IsAbs(filename) {
+					filename = filepath.Join(state.cfg.Dir, filename)
+				}
+				info, _ := os.Stat(filename)
+				if info == nil {
+					return false
+				}
+				pkg.CompiledGoFiles = append(pkg.CompiledGoFiles, filename)
+				pkg.GoFiles = append(pkg.GoFiles, filename)
+				return true
+			}
+			found := addFilenameFromPos(err.Pos)
+			// In some cases, go list only reports the error position in the
+			// error text, not the error position. One such case is when the
+			// file's package name is a keyword (see golang.org/issue/39763).
+			if !found {
+				addFilenameFromPos(err.Err)
+			}
+		}
+
+		if p.Error != nil {
+			msg := strings.TrimSpace(p.Error.Err) // Trim to work around golang.org/issue/32363.
+			// Address golang.org/issue/35964 by appending import stack to error message.
+			if msg == "import cycle not allowed" && len(p.Error.ImportStack) != 0 {
+				msg += fmt.Sprintf(": import stack: %v", p.Error.ImportStack)
+			}
+			pkg.Errors = append(pkg.Errors, Error{
+				Pos:  p.Error.Pos,
+				Msg:  msg,
+				Kind: ListError,
+			})
+		}
+
+		pkgs[pkg.ID] = pkg
+	}
+
+	for id, errs := range additionalErrors {
+		if p, ok := pkgs[id]; ok {
+			p.Errors = append(p.Errors, errs...)
+		}
+	}
+	for _, pkg := range pkgs {
+		response.Packages = append(response.Packages, pkg)
+	}
+	sort.Slice(response.Packages, func(i, j int) bool { return response.Packages[i].ID < response.Packages[j].ID })
+
+	return response, nil
+}
+
+func (state *golistState) shouldAddFilenameFromError(p *jsonPackage) bool {
+	if len(p.GoFiles) > 0 || len(p.CompiledGoFiles) > 0 {
+		return false
+	}
+
+	goV, err := state.getGoVersion()
+	if err != nil {
+		return false
+	}
+
+	// On Go 1.14 and earlier, only add filenames from errors if the import stack is empty.
+	// The import stack behaves differently for these versions than newer Go versions.
+	if goV < 15 {
+		return len(p.Error.ImportStack) == 0
+	}
+
+	// On Go 1.15 and later, only parse filenames out of error if there's no import stack,
+	// or the current package is at the top of the import stack. This is not guaranteed
+	// to work perfectly, but should avoid some cases where files in errors don't belong to this
+	// package.
+	return len(p.Error.ImportStack) == 0 || p.Error.ImportStack[len(p.Error.ImportStack)-1] == p.ImportPath
+}
+
+// getGoVersion returns the effective minor version of the go command.
+func (state *golistState) getGoVersion() (int, error) {
+	state.goVersionOnce.Do(func() {
+		state.goVersion, state.goVersionError = gocommand.GoVersion(state.ctx, state.cfgInvocation(), state.cfg.gocmdRunner)
+	})
+	return state.goVersion, state.goVersionError
+}
+
+// getPkgPath finds the package path of a directory if it's relative to a root
+// directory.
+func (state *golistState) getPkgPath(dir string) (string, bool, error) {
+	absDir, err := filepath.Abs(dir)
+	if err != nil {
+		return "", false, err
+	}
+	roots, err := state.determineRootDirs()
+	if err != nil {
+		return "", false, err
+	}
+
+	for rdir, rpath := range roots {
+		// Make sure that the directory is in the module,
+		// to avoid creating a path relative to another module.
+		if !strings.HasPrefix(absDir, rdir) {
+			continue
+		}
+		// TODO(matloob): This doesn't properly handle symlinks.
+		r, err := filepath.Rel(rdir, dir)
+		if err != nil {
+			continue
+		}
+		if rpath != "" {
+			// We choose only one root even though the directory even it can belong in multiple modules
+			// or GOPATH entries. This is okay because we only need to work with absolute dirs when a
+			// file is missing from disk, for instance when gopls calls go/packages in an overlay.
+			// Once the file is saved, gopls, or the next invocation of the tool will get the correct
+			// result straight from golist.
+			// TODO(matloob): Implement module tiebreaking?
+			return path.Join(rpath, filepath.ToSlash(r)), true, nil
+		}
+		return filepath.ToSlash(r), true, nil
+	}
+	return "", false, nil
+}
+
+// absJoin absolutizes and flattens the lists of files.
+func absJoin(dir string, fileses ...[]string) (res []string) {
+	for _, files := range fileses {
+		for _, file := range files {
+			if !filepath.IsAbs(file) {
+				file = filepath.Join(dir, file)
+			}
+			res = append(res, file)
+		}
+	}
+	return res
+}
+
+func jsonFlag(cfg *Config, goVersion int) string {
+	if goVersion < 19 {
+		return "-json"
+	}
+	var fields []string
+	added := make(map[string]bool)
+	addFields := func(fs ...string) {
+		for _, f := range fs {
+			if !added[f] {
+				added[f] = true
+				fields = append(fields, f)
+			}
+		}
+	}
+	addFields("Name", "ImportPath", "Error") // These fields are always needed
+	if cfg.Mode&NeedFiles != 0 || cfg.Mode&NeedTypes != 0 {
+		addFields("Dir", "GoFiles", "IgnoredGoFiles", "IgnoredOtherFiles", "CFiles",
+			"CgoFiles", "CXXFiles", "MFiles", "HFiles", "FFiles", "SFiles",
+			"SwigFiles", "SwigCXXFiles", "SysoFiles")
+		if cfg.Tests {
+			addFields("TestGoFiles", "XTestGoFiles")
+		}
+	}
+	if cfg.Mode&NeedTypes != 0 {
+		// CompiledGoFiles seems to be required for the test case TestCgoNoSyntax,
+		// even when -compiled isn't passed in.
+		// TODO(#52435): Should we make the test ask for -compiled, or automatically
+		// request CompiledGoFiles in certain circumstances?
+		addFields("Dir", "CompiledGoFiles")
+	}
+	if cfg.Mode&NeedCompiledGoFiles != 0 {
+		addFields("Dir", "CompiledGoFiles", "Export")
+	}
+	if cfg.Mode&NeedImports != 0 {
+		// When imports are requested, DepOnly is used to distinguish between packages
+		// explicitly requested and transitive imports of those packages.
+		addFields("DepOnly", "Imports", "ImportMap")
+		if cfg.Tests {
+			addFields("TestImports", "XTestImports")
+		}
+	}
+	if cfg.Mode&NeedDeps != 0 {
+		addFields("DepOnly")
+	}
+	if usesExportData(cfg) {
+		// Request Dir in the unlikely case Export is not absolute.
+		addFields("Dir", "Export")
+	}
+	if cfg.Mode&needInternalForTest != 0 {
+		addFields("ForTest")
+	}
+	if cfg.Mode&needInternalDepsErrors != 0 {
+		addFields("DepsErrors")
+	}
+	if cfg.Mode&NeedModule != 0 {
+		addFields("Module")
+	}
+	if cfg.Mode&NeedEmbedFiles != 0 {
+		addFields("EmbedFiles")
+	}
+	if cfg.Mode&NeedEmbedPatterns != 0 {
+		addFields("EmbedPatterns")
+	}
+	return "-json=" + strings.Join(fields, ",")
+}
+
+func golistargs(cfg *Config, words []string, goVersion int) []string {
+	const findFlags = NeedImports | NeedTypes | NeedSyntax | NeedTypesInfo
+	fullargs := []string{
+		"-e", jsonFlag(cfg, goVersion),
+		fmt.Sprintf("-compiled=%t", cfg.Mode&(NeedCompiledGoFiles|NeedSyntax|NeedTypes|NeedTypesInfo|NeedTypesSizes) != 0),
+		fmt.Sprintf("-test=%t", cfg.Tests),
+		fmt.Sprintf("-export=%t", usesExportData(cfg)),
+		fmt.Sprintf("-deps=%t", cfg.Mode&NeedImports != 0),
+		// go list doesn't let you pass -test and -find together,
+		// probably because you'd just get the TestMain.
+		fmt.Sprintf("-find=%t", !cfg.Tests && cfg.Mode&findFlags == 0 && !usesExportData(cfg)),
+	}
+	fullargs = append(fullargs, cfg.BuildFlags...)
+	fullargs = append(fullargs, "--")
+	fullargs = append(fullargs, words...)
+	return fullargs
+}
+
+// cfgInvocation returns an Invocation that reflects cfg's settings.
+func (state *golistState) cfgInvocation() gocommand.Invocation {
+	cfg := state.cfg
+	return gocommand.Invocation{
+		BuildFlags: cfg.BuildFlags,
+		ModFile:    cfg.modFile,
+		ModFlag:    cfg.modFlag,
+		CleanEnv:   cfg.Env != nil,
+		Env:        cfg.Env,
+		Logf:       cfg.Logf,
+		WorkingDir: cfg.Dir,
+	}
+}
+
+// invokeGo returns the stdout of a go command invocation.
+func (state *golistState) invokeGo(verb string, args ...string) (*bytes.Buffer, error) {
+	cfg := state.cfg
+
+	inv := state.cfgInvocation()
+
+	// For Go versions 1.16 and above, `go list` accepts overlays directly via
+	// the -overlay flag. Set it, if it's available.
+	//
+	// The check for "list" is not necessarily required, but we should avoid
+	// getting the go version if possible.
+	if verb == "list" {
+		goVersion, err := state.getGoVersion()
+		if err != nil {
+			return nil, err
+		}
+		if goVersion >= 16 {
+			filename, cleanup, err := state.writeOverlays()
+			if err != nil {
+				return nil, err
+			}
+			defer cleanup()
+			inv.Overlay = filename
+		}
+	}
+	inv.Verb = verb
+	inv.Args = args
+	gocmdRunner := cfg.gocmdRunner
+	if gocmdRunner == nil {
+		gocmdRunner = &gocommand.Runner{}
+	}
+	stdout, stderr, friendlyErr, err := gocmdRunner.RunRaw(cfg.Context, inv)
+	if err != nil {
+		// Check for 'go' executable not being found.
+		if ee, ok := err.(*exec.Error); ok && ee.Err == exec.ErrNotFound {
+			return nil, fmt.Errorf("'go list' driver requires 'go', but %s", exec.ErrNotFound)
+		}
+
+		exitErr, ok := err.(*exec.ExitError)
+		if !ok {
+			// Catastrophic error:
+			// - context cancellation
+			return nil, fmt.Errorf("couldn't run 'go': %w", err)
+		}
+
+		// Old go version?
+		if strings.Contains(stderr.String(), "flag provided but not defined") {
+			return nil, goTooOldError{fmt.Errorf("unsupported version of go: %s: %s", exitErr, stderr)}
+		}
+
+		// Related to #24854
+		if len(stderr.String()) > 0 && strings.Contains(stderr.String(), "unexpected directory layout") {
+			return nil, friendlyErr
+		}
+
+		// Is there an error running the C compiler in cgo? This will be reported in the "Error" field
+		// and should be suppressed by go list -e.
+		//
+		// This condition is not perfect yet because the error message can include other error messages than runtime/cgo.
+		isPkgPathRune := func(r rune) bool {
+			// From https://golang.org/ref/spec#Import_declarations:
+			//    Implementation restriction: A compiler may restrict ImportPaths to non-empty strings
+			//    using only characters belonging to Unicode's L, M, N, P, and S general categories
+			//    (the Graphic characters without spaces) and may also exclude the
+			//    characters !"#$%&'()*,:;<=>?[\]^`{|} and the Unicode replacement character U+FFFD.
+			return unicode.IsOneOf([]*unicode.RangeTable{unicode.L, unicode.M, unicode.N, unicode.P, unicode.S}, r) &&
+				!strings.ContainsRune("!\"#$%&'()*,:;<=>?[\\]^`{|}\uFFFD", r)
+		}
+		// golang/go#36770: Handle case where cmd/go prints module download messages before the error.
+		msg := stderr.String()
+		for strings.HasPrefix(msg, "go: downloading") {
+			msg = msg[strings.IndexRune(msg, '\n')+1:]
+		}
+		if len(stderr.String()) > 0 && strings.HasPrefix(stderr.String(), "# ") {
+			msg := msg[len("# "):]
+			if strings.HasPrefix(strings.TrimLeftFunc(msg, isPkgPathRune), "\n") {
+				return stdout, nil
+			}
+			// Treat pkg-config errors as a special case (golang.org/issue/36770).
+			if strings.HasPrefix(msg, "pkg-config") {
+				return stdout, nil
+			}
+		}
+
+		// This error only appears in stderr. See golang.org/cl/166398 for a fix in go list to show
+		// the error in the Err section of stdout in case -e option is provided.
+		// This fix is provided for backwards compatibility.
+		if len(stderr.String()) > 0 && strings.Contains(stderr.String(), "named files must be .go files") {
+			output := fmt.Sprintf(`{"ImportPath": "command-line-arguments","Incomplete": true,"Error": {"Pos": "","Err": %q}}`,
+				strings.Trim(stderr.String(), "\n"))
+			return bytes.NewBufferString(output), nil
+		}
+
+		// Similar to the previous error, but currently lacks a fix in Go.
+		if len(stderr.String()) > 0 && strings.Contains(stderr.String(), "named files must all be in one directory") {
+			output := fmt.Sprintf(`{"ImportPath": "command-line-arguments","Incomplete": true,"Error": {"Pos": "","Err": %q}}`,
+				strings.Trim(stderr.String(), "\n"))
+			return bytes.NewBufferString(output), nil
+		}
+
+		// Backwards compatibility for Go 1.11 because 1.12 and 1.13 put the directory in the ImportPath.
+		// If the package doesn't exist, put the absolute path of the directory into the error message,
+		// as Go 1.13 list does.
+		const noSuchDirectory = "no such directory"
+		if len(stderr.String()) > 0 && strings.Contains(stderr.String(), noSuchDirectory) {
+			errstr := stderr.String()
+			abspath := strings.TrimSpace(errstr[strings.Index(errstr, noSuchDirectory)+len(noSuchDirectory):])
+			output := fmt.Sprintf(`{"ImportPath": %q,"Incomplete": true,"Error": {"Pos": "","Err": %q}}`,
+				abspath, strings.Trim(stderr.String(), "\n"))
+			return bytes.NewBufferString(output), nil
+		}
+
+		// Workaround for #29280: go list -e has incorrect behavior when an ad-hoc package doesn't exist.
+		// Note that the error message we look for in this case is different that the one looked for above.
+		if len(stderr.String()) > 0 && strings.Contains(stderr.String(), "no such file or directory") {
+			output := fmt.Sprintf(`{"ImportPath": "command-line-arguments","Incomplete": true,"Error": {"Pos": "","Err": %q}}`,
+				strings.Trim(stderr.String(), "\n"))
+			return bytes.NewBufferString(output), nil
+		}
+
+		// Workaround for #34273. go list -e with GO111MODULE=on has incorrect behavior when listing a
+		// directory outside any module.
+		if len(stderr.String()) > 0 && strings.Contains(stderr.String(), "outside available modules") {
+			output := fmt.Sprintf(`{"ImportPath": %q,"Incomplete": true,"Error": {"Pos": "","Err": %q}}`,
+				// TODO(matloob): command-line-arguments isn't correct here.
+				"command-line-arguments", strings.Trim(stderr.String(), "\n"))
+			return bytes.NewBufferString(output), nil
+		}
+
+		// Another variation of the previous error
+		if len(stderr.String()) > 0 && strings.Contains(stderr.String(), "outside module root") {
+			output := fmt.Sprintf(`{"ImportPath": %q,"Incomplete": true,"Error": {"Pos": "","Err": %q}}`,
+				// TODO(matloob): command-line-arguments isn't correct here.
+				"command-line-arguments", strings.Trim(stderr.String(), "\n"))
+			return bytes.NewBufferString(output), nil
+		}
+
+		// Workaround for an instance of golang.org/issue/26755: go list -e  will return a non-zero exit
+		// status if there's a dependency on a package that doesn't exist. But it should return
+		// a zero exit status and set an error on that package.
+		if len(stderr.String()) > 0 && strings.Contains(stderr.String(), "no Go files in") {
+			// Don't clobber stdout if `go list` actually returned something.
+			if len(stdout.String()) > 0 {
+				return stdout, nil
+			}
+			// try to extract package name from string
+			stderrStr := stderr.String()
+			var importPath string
+			colon := strings.Index(stderrStr, ":")
+			if colon > 0 && strings.HasPrefix(stderrStr, "go build ") {
+				importPath = stderrStr[len("go build "):colon]
+			}
+			output := fmt.Sprintf(`{"ImportPath": %q,"Incomplete": true,"Error": {"Pos": "","Err": %q}}`,
+				importPath, strings.Trim(stderrStr, "\n"))
+			return bytes.NewBufferString(output), nil
+		}
+
+		// Export mode entails a build.
+		// If that build fails, errors appear on stderr
+		// (despite the -e flag) and the Export field is blank.
+		// Do not fail in that case.
+		// The same is true if an ad-hoc package given to go list doesn't exist.
+		// TODO(matloob): Remove these once we can depend on go list to exit with a zero status with -e even when
+		// packages don't exist or a build fails.
+		if !usesExportData(cfg) && !containsGoFile(args) {
+			return nil, friendlyErr
+		}
+	}
+	return stdout, nil
+}
+
+// OverlayJSON is the format overlay files are expected to be in.
+// The Replace map maps from overlaid paths to replacement paths:
+// the Go command will forward all reads trying to open
+// each overlaid path to its replacement path, or consider the overlaid
+// path not to exist if the replacement path is empty.
+//
+// From golang/go#39958.
+type OverlayJSON struct {
+	Replace map[string]string `json:"replace,omitempty"`
+}
+
+// writeOverlays writes out files for go list's -overlay flag, as described
+// above.
+func (state *golistState) writeOverlays() (filename string, cleanup func(), err error) {
+	// Do nothing if there are no overlays in the config.
+	if len(state.cfg.Overlay) == 0 {
+		return "", func() {}, nil
+	}
+	dir, err := ioutil.TempDir("", "gopackages-*")
+	if err != nil {
+		return "", nil, err
+	}
+	// The caller must clean up this directory, unless this function returns an
+	// error.
+	cleanup = func() {
+		os.RemoveAll(dir)
+	}
+	defer func() {
+		if err != nil {
+			cleanup()
+		}
+	}()
+	overlays := map[string]string{}
+	for k, v := range state.cfg.Overlay {
+		// Create a unique filename for the overlaid files, to avoid
+		// creating nested directories.
+		noSeparator := strings.Join(strings.Split(filepath.ToSlash(k), "/"), "")
+		f, err := ioutil.TempFile(dir, fmt.Sprintf("*-%s", noSeparator))
+		if err != nil {
+			return "", func() {}, err
+		}
+		if _, err := f.Write(v); err != nil {
+			return "", func() {}, err
+		}
+		if err := f.Close(); err != nil {
+			return "", func() {}, err
+		}
+		overlays[k] = f.Name()
+	}
+	b, err := json.Marshal(OverlayJSON{Replace: overlays})
+	if err != nil {
+		return "", func() {}, err
+	}
+	// Write out the overlay file that contains the filepath mappings.
+	filename = filepath.Join(dir, "overlay.json")
+	if err := ioutil.WriteFile(filename, b, 0665); err != nil {
+		return "", func() {}, err
+	}
+	return filename, cleanup, nil
+}
+
+func containsGoFile(s []string) bool {
+	for _, f := range s {
+		if strings.HasSuffix(f, ".go") {
+			return true
+		}
+	}
+	return false
+}
+
+func cmdDebugStr(cmd *exec.Cmd) string {
+	env := make(map[string]string)
+	for _, kv := range cmd.Env {
+		split := strings.SplitN(kv, "=", 2)
+		k, v := split[0], split[1]
+		env[k] = v
+	}
+
+	var args []string
+	for _, arg := range cmd.Args {
+		quoted := strconv.Quote(arg)
+		if quoted[1:len(quoted)-1] != arg || strings.Contains(arg, " ") {
+			args = append(args, quoted)
+		} else {
+			args = append(args, arg)
+		}
+	}
+	return fmt.Sprintf("GOROOT=%v GOPATH=%v GO111MODULE=%v GOPROXY=%v PWD=%v %v", env["GOROOT"], env["GOPATH"], env["GO111MODULE"], env["GOPROXY"], env["PWD"], strings.Join(args, " "))
+}
diff --git a/vendor/golang.org/x/tools/go/packages/golist_overlay.go b/vendor/golang.org/x/tools/go/packages/golist_overlay.go
new file mode 100644
index 0000000..9576b47
--- /dev/null
+++ b/vendor/golang.org/x/tools/go/packages/golist_overlay.go
@@ -0,0 +1,575 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package packages
+
+import (
+	"encoding/json"
+	"fmt"
+	"go/parser"
+	"go/token"
+	"os"
+	"path/filepath"
+	"regexp"
+	"sort"
+	"strconv"
+	"strings"
+
+	"golang.org/x/tools/internal/gocommand"
+)
+
+// processGolistOverlay provides rudimentary support for adding
+// files that don't exist on disk to an overlay. The results can be
+// sometimes incorrect.
+// TODO(matloob): Handle unsupported cases, including the following:
+// - determining the correct package to add given a new import path
+func (state *golistState) processGolistOverlay(response *responseDeduper) (modifiedPkgs, needPkgs []string, err error) {
+	havePkgs := make(map[string]string) // importPath -> non-test package ID
+	needPkgsSet := make(map[string]bool)
+	modifiedPkgsSet := make(map[string]bool)
+
+	pkgOfDir := make(map[string][]*Package)
+	for _, pkg := range response.dr.Packages {
+		// This is an approximation of import path to id. This can be
+		// wrong for tests, vendored packages, and a number of other cases.
+		havePkgs[pkg.PkgPath] = pkg.ID
+		dir, err := commonDir(pkg.GoFiles)
+		if err != nil {
+			return nil, nil, err
+		}
+		if dir != "" {
+			pkgOfDir[dir] = append(pkgOfDir[dir], pkg)
+		}
+	}
+
+	// If no new imports are added, it is safe to avoid loading any needPkgs.
+	// Otherwise, it's hard to tell which package is actually being loaded
+	// (due to vendoring) and whether any modified package will show up
+	// in the transitive set of dependencies (because new imports are added,
+	// potentially modifying the transitive set of dependencies).
+	var overlayAddsImports bool
+
+	// If both a package and its test package are created by the overlay, we
+	// need the real package first. Process all non-test files before test
+	// files, and make the whole process deterministic while we're at it.
+	var overlayFiles []string
+	for opath := range state.cfg.Overlay {
+		overlayFiles = append(overlayFiles, opath)
+	}
+	sort.Slice(overlayFiles, func(i, j int) bool {
+		iTest := strings.HasSuffix(overlayFiles[i], "_test.go")
+		jTest := strings.HasSuffix(overlayFiles[j], "_test.go")
+		if iTest != jTest {
+			return !iTest // non-tests are before tests.
+		}
+		return overlayFiles[i] < overlayFiles[j]
+	})
+	for _, opath := range overlayFiles {
+		contents := state.cfg.Overlay[opath]
+		base := filepath.Base(opath)
+		dir := filepath.Dir(opath)
+		var pkg *Package           // if opath belongs to both a package and its test variant, this will be the test variant
+		var testVariantOf *Package // if opath is a test file, this is the package it is testing
+		var fileExists bool
+		isTestFile := strings.HasSuffix(opath, "_test.go")
+		pkgName, ok := extractPackageName(opath, contents)
+		if !ok {
+			// Don't bother adding a file that doesn't even have a parsable package statement
+			// to the overlay.
+			continue
+		}
+		// If all the overlay files belong to a different package, change the
+		// package name to that package.
+		maybeFixPackageName(pkgName, isTestFile, pkgOfDir[dir])
+	nextPackage:
+		for _, p := range response.dr.Packages {
+			if pkgName != p.Name && p.ID != "command-line-arguments" {
+				continue
+			}
+			for _, f := range p.GoFiles {
+				if !sameFile(filepath.Dir(f), dir) {
+					continue
+				}
+				// Make sure to capture information on the package's test variant, if needed.
+				if isTestFile && !hasTestFiles(p) {
+					// TODO(matloob): Are there packages other than the 'production' variant
+					// of a package that this can match? This shouldn't match the test main package
+					// because the file is generated in another directory.
+					testVariantOf = p
+					continue nextPackage
+				} else if !isTestFile && hasTestFiles(p) {
+					// We're examining a test variant, but the overlaid file is
+					// a non-test file. Because the overlay implementation
+					// (currently) only adds a file to one package, skip this
+					// package, so that we can add the file to the production
+					// variant of the package. (https://golang.org/issue/36857
+					// tracks handling overlays on both the production and test
+					// variant of a package).
+					continue nextPackage
+				}
+				if pkg != nil && p != pkg && pkg.PkgPath == p.PkgPath {
+					// We have already seen the production version of the
+					// for which p is a test variant.
+					if hasTestFiles(p) {
+						testVariantOf = pkg
+					}
+				}
+				pkg = p
+				if filepath.Base(f) == base {
+					fileExists = true
+				}
+			}
+		}
+		// The overlay could have included an entirely new package or an
+		// ad-hoc package. An ad-hoc package is one that we have manually
+		// constructed from inadequate `go list` results for a file= query.
+		// It will have the ID command-line-arguments.
+		if pkg == nil || pkg.ID == "command-line-arguments" {
+			// Try to find the module or gopath dir the file is contained in.
+			// Then for modules, add the module opath to the beginning.
+			pkgPath, ok, err := state.getPkgPath(dir)
+			if err != nil {
+				return nil, nil, err
+			}
+			if !ok {
+				break
+			}
+			var forTest string // only set for x tests
+			isXTest := strings.HasSuffix(pkgName, "_test")
+			if isXTest {
+				forTest = pkgPath
+				pkgPath += "_test"
+			}
+			id := pkgPath
+			if isTestFile {
+				if isXTest {
+					id = fmt.Sprintf("%s [%s.test]", pkgPath, forTest)
+				} else {
+					id = fmt.Sprintf("%s [%s.test]", pkgPath, pkgPath)
+				}
+			}
+			if pkg != nil {
+				// TODO(rstambler): We should change the package's path and ID
+				// here. The only issue is that this messes with the roots.
+			} else {
+				// Try to reclaim a package with the same ID, if it exists in the response.
+				for _, p := range response.dr.Packages {
+					if reclaimPackage(p, id, opath, contents) {
+						pkg = p
+						break
+					}
+				}
+				// Otherwise, create a new package.
+				if pkg == nil {
+					pkg = &Package{
+						PkgPath: pkgPath,
+						ID:      id,
+						Name:    pkgName,
+						Imports: make(map[string]*Package),
+					}
+					response.addPackage(pkg)
+					havePkgs[pkg.PkgPath] = id
+					// Add the production package's sources for a test variant.
+					if isTestFile && !isXTest && testVariantOf != nil {
+						pkg.GoFiles = append(pkg.GoFiles, testVariantOf.GoFiles...)
+						pkg.CompiledGoFiles = append(pkg.CompiledGoFiles, testVariantOf.CompiledGoFiles...)
+						// Add the package under test and its imports to the test variant.
+						pkg.forTest = testVariantOf.PkgPath
+						for k, v := range testVariantOf.Imports {
+							pkg.Imports[k] = &Package{ID: v.ID}
+						}
+					}
+					if isXTest {
+						pkg.forTest = forTest
+					}
+				}
+			}
+		}
+		if !fileExists {
+			pkg.GoFiles = append(pkg.GoFiles, opath)
+			// TODO(matloob): Adding the file to CompiledGoFiles can exhibit the wrong behavior
+			// if the file will be ignored due to its build tags.
+			pkg.CompiledGoFiles = append(pkg.CompiledGoFiles, opath)
+			modifiedPkgsSet[pkg.ID] = true
+		}
+		imports, err := extractImports(opath, contents)
+		if err != nil {
+			// Let the parser or type checker report errors later.
+			continue
+		}
+		for _, imp := range imports {
+			// TODO(rstambler): If the package is an x test and the import has
+			// a test variant, make sure to replace it.
+			if _, found := pkg.Imports[imp]; found {
+				continue
+			}
+			overlayAddsImports = true
+			id, ok := havePkgs[imp]
+			if !ok {
+				var err error
+				id, err = state.resolveImport(dir, imp)
+				if err != nil {
+					return nil, nil, err
+				}
+			}
+			pkg.Imports[imp] = &Package{ID: id}
+			// Add dependencies to the non-test variant version of this package as well.
+			if testVariantOf != nil {
+				testVariantOf.Imports[imp] = &Package{ID: id}
+			}
+		}
+	}
+
+	// toPkgPath guesses the package path given the id.
+	toPkgPath := func(sourceDir, id string) (string, error) {
+		if i := strings.IndexByte(id, ' '); i >= 0 {
+			return state.resolveImport(sourceDir, id[:i])
+		}
+		return state.resolveImport(sourceDir, id)
+	}
+
+	// Now that new packages have been created, do another pass to determine
+	// the new set of missing packages.
+	for _, pkg := range response.dr.Packages {
+		for _, imp := range pkg.Imports {
+			if len(pkg.GoFiles) == 0 {
+				return nil, nil, fmt.Errorf("cannot resolve imports for package %q with no Go files", pkg.PkgPath)
+			}
+			pkgPath, err := toPkgPath(filepath.Dir(pkg.GoFiles[0]), imp.ID)
+			if err != nil {
+				return nil, nil, err
+			}
+			if _, ok := havePkgs[pkgPath]; !ok {
+				needPkgsSet[pkgPath] = true
+			}
+		}
+	}
+
+	if overlayAddsImports {
+		needPkgs = make([]string, 0, len(needPkgsSet))
+		for pkg := range needPkgsSet {
+			needPkgs = append(needPkgs, pkg)
+		}
+	}
+	modifiedPkgs = make([]string, 0, len(modifiedPkgsSet))
+	for pkg := range modifiedPkgsSet {
+		modifiedPkgs = append(modifiedPkgs, pkg)
+	}
+	return modifiedPkgs, needPkgs, err
+}
+
+// resolveImport finds the ID of a package given its import path.
+// In particular, it will find the right vendored copy when in GOPATH mode.
+func (state *golistState) resolveImport(sourceDir, importPath string) (string, error) {
+	env, err := state.getEnv()
+	if err != nil {
+		return "", err
+	}
+	if env["GOMOD"] != "" {
+		return importPath, nil
+	}
+
+	searchDir := sourceDir
+	for {
+		vendorDir := filepath.Join(searchDir, "vendor")
+		exists, ok := state.vendorDirs[vendorDir]
+		if !ok {
+			info, err := os.Stat(vendorDir)
+			exists = err == nil && info.IsDir()
+			state.vendorDirs[vendorDir] = exists
+		}
+
+		if exists {
+			vendoredPath := filepath.Join(vendorDir, importPath)
+			if info, err := os.Stat(vendoredPath); err == nil && info.IsDir() {
+				// We should probably check for .go files here, but shame on anyone who fools us.
+				path, ok, err := state.getPkgPath(vendoredPath)
+				if err != nil {
+					return "", err
+				}
+				if ok {
+					return path, nil
+				}
+			}
+		}
+
+		// We know we've hit the top of the filesystem when we Dir / and get /,
+		// or C:\ and get C:\, etc.
+		next := filepath.Dir(searchDir)
+		if next == searchDir {
+			break
+		}
+		searchDir = next
+	}
+	return importPath, nil
+}
+
+func hasTestFiles(p *Package) bool {
+	for _, f := range p.GoFiles {
+		if strings.HasSuffix(f, "_test.go") {
+			return true
+		}
+	}
+	return false
+}
+
+// determineRootDirs returns a mapping from absolute directories that could
+// contain code to their corresponding import path prefixes.
+func (state *golistState) determineRootDirs() (map[string]string, error) {
+	env, err := state.getEnv()
+	if err != nil {
+		return nil, err
+	}
+	if env["GOMOD"] != "" {
+		state.rootsOnce.Do(func() {
+			state.rootDirs, state.rootDirsError = state.determineRootDirsModules()
+		})
+	} else {
+		state.rootsOnce.Do(func() {
+			state.rootDirs, state.rootDirsError = state.determineRootDirsGOPATH()
+		})
+	}
+	return state.rootDirs, state.rootDirsError
+}
+
+func (state *golistState) determineRootDirsModules() (map[string]string, error) {
+	// List all of the modules--the first will be the directory for the main
+	// module. Any replaced modules will also need to be treated as roots.
+	// Editing files in the module cache isn't a great idea, so we don't
+	// plan to ever support that.
+	out, err := state.invokeGo("list", "-m", "-json", "all")
+	if err != nil {
+		// 'go list all' will fail if we're outside of a module and
+		// GO111MODULE=on. Try falling back without 'all'.
+		var innerErr error
+		out, innerErr = state.invokeGo("list", "-m", "-json")
+		if innerErr != nil {
+			return nil, err
+		}
+	}
+	roots := map[string]string{}
+	modules := map[string]string{}
+	var i int
+	for dec := json.NewDecoder(out); dec.More(); {
+		mod := new(gocommand.ModuleJSON)
+		if err := dec.Decode(mod); err != nil {
+			return nil, err
+		}
+		if mod.Dir != "" && mod.Path != "" {
+			// This is a valid module; add it to the map.
+			absDir, err := filepath.Abs(mod.Dir)
+			if err != nil {
+				return nil, err
+			}
+			modules[absDir] = mod.Path
+			// The first result is the main module.
+			if i == 0 || mod.Replace != nil && mod.Replace.Path != "" {
+				roots[absDir] = mod.Path
+			}
+		}
+		i++
+	}
+	return roots, nil
+}
+
+func (state *golistState) determineRootDirsGOPATH() (map[string]string, error) {
+	m := map[string]string{}
+	for _, dir := range filepath.SplitList(state.mustGetEnv()["GOPATH"]) {
+		absDir, err := filepath.Abs(dir)
+		if err != nil {
+			return nil, err
+		}
+		m[filepath.Join(absDir, "src")] = ""
+	}
+	return m, nil
+}
+
+func extractImports(filename string, contents []byte) ([]string, error) {
+	f, err := parser.ParseFile(token.NewFileSet(), filename, contents, parser.ImportsOnly) // TODO(matloob): reuse fileset?
+	if err != nil {
+		return nil, err
+	}
+	var res []string
+	for _, imp := range f.Imports {
+		quotedPath := imp.Path.Value
+		path, err := strconv.Unquote(quotedPath)
+		if err != nil {
+			return nil, err
+		}
+		res = append(res, path)
+	}
+	return res, nil
+}
+
+// reclaimPackage attempts to reuse a package that failed to load in an overlay.
+//
+// If the package has errors and has no Name, GoFiles, or Imports,
+// then it's possible that it doesn't yet exist on disk.
+func reclaimPackage(pkg *Package, id string, filename string, contents []byte) bool {
+	// TODO(rstambler): Check the message of the actual error?
+	// It differs between $GOPATH and module mode.
+	if pkg.ID != id {
+		return false
+	}
+	if len(pkg.Errors) != 1 {
+		return false
+	}
+	if pkg.Name != "" || pkg.ExportFile != "" {
+		return false
+	}
+	if len(pkg.GoFiles) > 0 || len(pkg.CompiledGoFiles) > 0 || len(pkg.OtherFiles) > 0 {
+		return false
+	}
+	if len(pkg.Imports) > 0 {
+		return false
+	}
+	pkgName, ok := extractPackageName(filename, contents)
+	if !ok {
+		return false
+	}
+	pkg.Name = pkgName
+	pkg.Errors = nil
+	return true
+}
+
+func extractPackageName(filename string, contents []byte) (string, bool) {
+	// TODO(rstambler): Check the message of the actual error?
+	// It differs between $GOPATH and module mode.
+	f, err := parser.ParseFile(token.NewFileSet(), filename, contents, parser.PackageClauseOnly) // TODO(matloob): reuse fileset?
+	if err != nil {
+		return "", false
+	}
+	return f.Name.Name, true
+}
+
+// commonDir returns the directory that all files are in, "" if files is empty,
+// or an error if they aren't in the same directory.
+func commonDir(files []string) (string, error) {
+	seen := make(map[string]bool)
+	for _, f := range files {
+		seen[filepath.Dir(f)] = true
+	}
+	if len(seen) > 1 {
+		return "", fmt.Errorf("files (%v) are in more than one directory: %v", files, seen)
+	}
+	for k := range seen {
+		// seen has only one element; return it.
+		return k, nil
+	}
+	return "", nil // no files
+}
+
+// It is possible that the files in the disk directory dir have a different package
+// name from newName, which is deduced from the overlays. If they all have a different
+// package name, and they all have the same package name, then that name becomes
+// the package name.
+// It returns true if it changes the package name, false otherwise.
+func maybeFixPackageName(newName string, isTestFile bool, pkgsOfDir []*Package) {
+	names := make(map[string]int)
+	for _, p := range pkgsOfDir {
+		names[p.Name]++
+	}
+	if len(names) != 1 {
+		// some files are in different packages
+		return
+	}
+	var oldName string
+	for k := range names {
+		oldName = k
+	}
+	if newName == oldName {
+		return
+	}
+	// We might have a case where all of the package names in the directory are
+	// the same, but the overlay file is for an x test, which belongs to its
+	// own package. If the x test does not yet exist on disk, we may not yet
+	// have its package name on disk, but we should not rename the packages.
+	//
+	// We use a heuristic to determine if this file belongs to an x test:
+	// The test file should have a package name whose package name has a _test
+	// suffix or looks like "newName_test".
+	maybeXTest := strings.HasPrefix(oldName+"_test", newName) || strings.HasSuffix(newName, "_test")
+	if isTestFile && maybeXTest {
+		return
+	}
+	for _, p := range pkgsOfDir {
+		p.Name = newName
+	}
+}
+
+// This function is copy-pasted from
+// https://github.com/golang/go/blob/9706f510a5e2754595d716bd64be8375997311fb/src/cmd/go/internal/search/search.go#L360.
+// It should be deleted when we remove support for overlays from go/packages.
+//
+// NOTE: This does not handle any ./... or ./ style queries, as this function
+// doesn't know the working directory.
+//
+// matchPattern(pattern)(name) reports whether
+// name matches pattern. Pattern is a limited glob
+// pattern in which '...' means 'any string' and there
+// is no other special syntax.
+// Unfortunately, there are two special cases. Quoting "go help packages":
+//
+// First, /... at the end of the pattern can match an empty string,
+// so that net/... matches both net and packages in its subdirectories, like net/http.
+// Second, any slash-separated pattern element containing a wildcard never
+// participates in a match of the "vendor" element in the path of a vendored
+// package, so that ./... does not match packages in subdirectories of
+// ./vendor or ./mycode/vendor, but ./vendor/... and ./mycode/vendor/... do.
+// Note, however, that a directory named vendor that itself contains code
+// is not a vendored package: cmd/vendor would be a command named vendor,
+// and the pattern cmd/... matches it.
+func matchPattern(pattern string) func(name string) bool {
+	// Convert pattern to regular expression.
+	// The strategy for the trailing /... is to nest it in an explicit ? expression.
+	// The strategy for the vendor exclusion is to change the unmatchable
+	// vendor strings to a disallowed code point (vendorChar) and to use
+	// "(anything but that codepoint)*" as the implementation of the ... wildcard.
+	// This is a bit complicated but the obvious alternative,
+	// namely a hand-written search like in most shell glob matchers,
+	// is too easy to make accidentally exponential.
+	// Using package regexp guarantees linear-time matching.
+
+	const vendorChar = "\x00"
+
+	if strings.Contains(pattern, vendorChar) {
+		return func(name string) bool { return false }
+	}
+
+	re := regexp.QuoteMeta(pattern)
+	re = replaceVendor(re, vendorChar)
+	switch {
+	case strings.HasSuffix(re, `/`+vendorChar+`/\.\.\.`):
+		re = strings.TrimSuffix(re, `/`+vendorChar+`/\.\.\.`) + `(/vendor|/` + vendorChar + `/\.\.\.)`
+	case re == vendorChar+`/\.\.\.`:
+		re = `(/vendor|/` + vendorChar + `/\.\.\.)`
+	case strings.HasSuffix(re, `/\.\.\.`):
+		re = strings.TrimSuffix(re, `/\.\.\.`) + `(/\.\.\.)?`
+	}
+	re = strings.ReplaceAll(re, `\.\.\.`, `[^`+vendorChar+`]*`)
+
+	reg := regexp.MustCompile(`^` + re + `$`)
+
+	return func(name string) bool {
+		if strings.Contains(name, vendorChar) {
+			return false
+		}
+		return reg.MatchString(replaceVendor(name, vendorChar))
+	}
+}
+
+// replaceVendor returns the result of replacing
+// non-trailing vendor path elements in x with repl.
+func replaceVendor(x, repl string) string {
+	if !strings.Contains(x, "vendor") {
+		return x
+	}
+	elem := strings.Split(x, "/")
+	for i := 0; i < len(elem)-1; i++ {
+		if elem[i] == "vendor" {
+			elem[i] = repl
+		}
+	}
+	return strings.Join(elem, "/")
+}
diff --git a/vendor/golang.org/x/tools/go/packages/loadmode_string.go b/vendor/golang.org/x/tools/go/packages/loadmode_string.go
new file mode 100644
index 0000000..5c080d2
--- /dev/null
+++ b/vendor/golang.org/x/tools/go/packages/loadmode_string.go
@@ -0,0 +1,57 @@
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package packages
+
+import (
+	"fmt"
+	"strings"
+)
+
+var allModes = []LoadMode{
+	NeedName,
+	NeedFiles,
+	NeedCompiledGoFiles,
+	NeedImports,
+	NeedDeps,
+	NeedExportFile,
+	NeedTypes,
+	NeedSyntax,
+	NeedTypesInfo,
+	NeedTypesSizes,
+}
+
+var modeStrings = []string{
+	"NeedName",
+	"NeedFiles",
+	"NeedCompiledGoFiles",
+	"NeedImports",
+	"NeedDeps",
+	"NeedExportFile",
+	"NeedTypes",
+	"NeedSyntax",
+	"NeedTypesInfo",
+	"NeedTypesSizes",
+}
+
+func (mod LoadMode) String() string {
+	m := mod
+	if m == 0 {
+		return "LoadMode(0)"
+	}
+	var out []string
+	for i, x := range allModes {
+		if x > m {
+			break
+		}
+		if (m & x) != 0 {
+			out = append(out, modeStrings[i])
+			m = m ^ x
+		}
+	}
+	if m != 0 {
+		out = append(out, "Unknown")
+	}
+	return fmt.Sprintf("LoadMode(%s)", strings.Join(out, "|"))
+}
diff --git a/vendor/golang.org/x/tools/go/packages/packages.go b/vendor/golang.org/x/tools/go/packages/packages.go
new file mode 100644
index 0000000..0f1505b
--- /dev/null
+++ b/vendor/golang.org/x/tools/go/packages/packages.go
@@ -0,0 +1,1326 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package packages
+
+// See doc.go for package documentation and implementation notes.
+
+import (
+	"context"
+	"encoding/json"
+	"fmt"
+	"go/ast"
+	"go/parser"
+	"go/scanner"
+	"go/token"
+	"go/types"
+	"io"
+	"io/ioutil"
+	"log"
+	"os"
+	"path/filepath"
+	"runtime"
+	"strings"
+	"sync"
+	"time"
+
+	"golang.org/x/tools/go/gcexportdata"
+	"golang.org/x/tools/internal/gocommand"
+	"golang.org/x/tools/internal/packagesinternal"
+	"golang.org/x/tools/internal/typeparams"
+	"golang.org/x/tools/internal/typesinternal"
+)
+
+// A LoadMode controls the amount of detail to return when loading.
+// The bits below can be combined to specify which fields should be
+// filled in the result packages.
+// The zero value is a special case, equivalent to combining
+// the NeedName, NeedFiles, and NeedCompiledGoFiles bits.
+// ID and Errors (if present) will always be filled.
+// Load may return more information than requested.
+type LoadMode int
+
+const (
+	// NeedName adds Name and PkgPath.
+	NeedName LoadMode = 1 << iota
+
+	// NeedFiles adds GoFiles and OtherFiles.
+	NeedFiles
+
+	// NeedCompiledGoFiles adds CompiledGoFiles.
+	NeedCompiledGoFiles
+
+	// NeedImports adds Imports. If NeedDeps is not set, the Imports field will contain
+	// "placeholder" Packages with only the ID set.
+	NeedImports
+
+	// NeedDeps adds the fields requested by the LoadMode in the packages in Imports.
+	NeedDeps
+
+	// NeedExportFile adds ExportFile.
+	NeedExportFile
+
+	// NeedTypes adds Types, Fset, and IllTyped.
+	NeedTypes
+
+	// NeedSyntax adds Syntax.
+	NeedSyntax
+
+	// NeedTypesInfo adds TypesInfo.
+	NeedTypesInfo
+
+	// NeedTypesSizes adds TypesSizes.
+	NeedTypesSizes
+
+	// needInternalDepsErrors adds the internal deps errors field for use by gopls.
+	needInternalDepsErrors
+
+	// needInternalForTest adds the internal forTest field.
+	// Tests must also be set on the context for this field to be populated.
+	needInternalForTest
+
+	// typecheckCgo enables full support for type checking cgo. Requires Go 1.15+.
+	// Modifies CompiledGoFiles and Types, and has no effect on its own.
+	typecheckCgo
+
+	// NeedModule adds Module.
+	NeedModule
+
+	// NeedEmbedFiles adds EmbedFiles.
+	NeedEmbedFiles
+
+	// NeedEmbedPatterns adds EmbedPatterns.
+	NeedEmbedPatterns
+)
+
+const (
+	// Deprecated: LoadFiles exists for historical compatibility
+	// and should not be used. Please directly specify the needed fields using the Need values.
+	LoadFiles = NeedName | NeedFiles | NeedCompiledGoFiles
+
+	// Deprecated: LoadImports exists for historical compatibility
+	// and should not be used. Please directly specify the needed fields using the Need values.
+	LoadImports = LoadFiles | NeedImports
+
+	// Deprecated: LoadTypes exists for historical compatibility
+	// and should not be used. Please directly specify the needed fields using the Need values.
+	LoadTypes = LoadImports | NeedTypes | NeedTypesSizes
+
+	// Deprecated: LoadSyntax exists for historical compatibility
+	// and should not be used. Please directly specify the needed fields using the Need values.
+	LoadSyntax = LoadTypes | NeedSyntax | NeedTypesInfo
+
+	// Deprecated: LoadAllSyntax exists for historical compatibility
+	// and should not be used. Please directly specify the needed fields using the Need values.
+	LoadAllSyntax = LoadSyntax | NeedDeps
+
+	// Deprecated: NeedExportsFile is a historical misspelling of NeedExportFile.
+	NeedExportsFile = NeedExportFile
+)
+
+// A Config specifies details about how packages should be loaded.
+// The zero value is a valid configuration.
+// Calls to Load do not modify this struct.
+type Config struct {
+	// Mode controls the level of information returned for each package.
+	Mode LoadMode
+
+	// Context specifies the context for the load operation.
+	// If the context is cancelled, the loader may stop early
+	// and return an ErrCancelled error.
+	// If Context is nil, the load cannot be cancelled.
+	Context context.Context
+
+	// Logf is the logger for the config.
+	// If the user provides a logger, debug logging is enabled.
+	// If the GOPACKAGESDEBUG environment variable is set to true,
+	// but the logger is nil, default to log.Printf.
+	Logf func(format string, args ...interface{})
+
+	// Dir is the directory in which to run the build system's query tool
+	// that provides information about the packages.
+	// If Dir is empty, the tool is run in the current directory.
+	Dir string
+
+	// Env is the environment to use when invoking the build system's query tool.
+	// If Env is nil, the current environment is used.
+	// As in os/exec's Cmd, only the last value in the slice for
+	// each environment key is used. To specify the setting of only
+	// a few variables, append to the current environment, as in:
+	//
+	//	opt.Env = append(os.Environ(), "GOOS=plan9", "GOARCH=386")
+	//
+	Env []string
+
+	// gocmdRunner guards go command calls from concurrency errors.
+	gocmdRunner *gocommand.Runner
+
+	// BuildFlags is a list of command-line flags to be passed through to
+	// the build system's query tool.
+	BuildFlags []string
+
+	// modFile will be used for -modfile in go command invocations.
+	modFile string
+
+	// modFlag will be used for -modfile in go command invocations.
+	modFlag string
+
+	// Fset provides source position information for syntax trees and types.
+	// If Fset is nil, Load will use a new fileset, but preserve Fset's value.
+	Fset *token.FileSet
+
+	// ParseFile is called to read and parse each file
+	// when preparing a package's type-checked syntax tree.
+	// It must be safe to call ParseFile simultaneously from multiple goroutines.
+	// If ParseFile is nil, the loader will uses parser.ParseFile.
+	//
+	// ParseFile should parse the source from src and use filename only for
+	// recording position information.
+	//
+	// An application may supply a custom implementation of ParseFile
+	// to change the effective file contents or the behavior of the parser,
+	// or to modify the syntax tree. For example, selectively eliminating
+	// unwanted function bodies can significantly accelerate type checking.
+	ParseFile func(fset *token.FileSet, filename string, src []byte) (*ast.File, error)
+
+	// If Tests is set, the loader includes not just the packages
+	// matching a particular pattern but also any related test packages,
+	// including test-only variants of the package and the test executable.
+	//
+	// For example, when using the go command, loading "fmt" with Tests=true
+	// returns four packages, with IDs "fmt" (the standard package),
+	// "fmt [fmt.test]" (the package as compiled for the test),
+	// "fmt_test" (the test functions from source files in package fmt_test),
+	// and "fmt.test" (the test binary).
+	//
+	// In build systems with explicit names for tests,
+	// setting Tests may have no effect.
+	Tests bool
+
+	// Overlay provides a mapping of absolute file paths to file contents.
+	// If the file with the given path already exists, the parser will use the
+	// alternative file contents provided by the map.
+	//
+	// Overlays provide incomplete support for when a given file doesn't
+	// already exist on disk. See the package doc above for more details.
+	Overlay map[string][]byte
+}
+
+// driver is the type for functions that query the build system for the
+// packages named by the patterns.
+type driver func(cfg *Config, patterns ...string) (*driverResponse, error)
+
+// driverResponse contains the results for a driver query.
+type driverResponse struct {
+	// NotHandled is returned if the request can't be handled by the current
+	// driver. If an external driver returns a response with NotHandled, the
+	// rest of the driverResponse is ignored, and go/packages will fallback
+	// to the next driver. If go/packages is extended in the future to support
+	// lists of multiple drivers, go/packages will fall back to the next driver.
+	NotHandled bool
+
+	// Sizes, if not nil, is the types.Sizes to use when type checking.
+	Sizes *types.StdSizes
+
+	// Roots is the set of package IDs that make up the root packages.
+	// We have to encode this separately because when we encode a single package
+	// we cannot know if it is one of the roots as that requires knowledge of the
+	// graph it is part of.
+	Roots []string `json:",omitempty"`
+
+	// Packages is the full set of packages in the graph.
+	// The packages are not connected into a graph.
+	// The Imports if populated will be stubs that only have their ID set.
+	// Imports will be connected and then type and syntax information added in a
+	// later pass (see refine).
+	Packages []*Package
+
+	// GoVersion is the minor version number used by the driver
+	// (e.g. the go command on the PATH) when selecting .go files.
+	// Zero means unknown.
+	GoVersion int
+}
+
+// Load loads and returns the Go packages named by the given patterns.
+//
+// Config specifies loading options;
+// nil behaves the same as an empty Config.
+//
+// Load returns an error if any of the patterns was invalid
+// as defined by the underlying build system.
+// It may return an empty list of packages without an error,
+// for instance for an empty expansion of a valid wildcard.
+// Errors associated with a particular package are recorded in the
+// corresponding Package's Errors list, and do not cause Load to
+// return an error. Clients may need to handle such errors before
+// proceeding with further analysis. The PrintErrors function is
+// provided for convenient display of all errors.
+func Load(cfg *Config, patterns ...string) ([]*Package, error) {
+	l := newLoader(cfg)
+	response, err := defaultDriver(&l.Config, patterns...)
+	if err != nil {
+		return nil, err
+	}
+	l.sizes = response.Sizes
+	return l.refine(response)
+}
+
+// defaultDriver is a driver that implements go/packages' fallback behavior.
+// It will try to request to an external driver, if one exists. If there's
+// no external driver, or the driver returns a response with NotHandled set,
+// defaultDriver will fall back to the go list driver.
+func defaultDriver(cfg *Config, patterns ...string) (*driverResponse, error) {
+	driver := findExternalDriver(cfg)
+	if driver == nil {
+		driver = goListDriver
+	}
+	response, err := driver(cfg, patterns...)
+	if err != nil {
+		return response, err
+	} else if response.NotHandled {
+		return goListDriver(cfg, patterns...)
+	}
+	return response, nil
+}
+
+// A Package describes a loaded Go package.
+type Package struct {
+	// ID is a unique identifier for a package,
+	// in a syntax provided by the underlying build system.
+	//
+	// Because the syntax varies based on the build system,
+	// clients should treat IDs as opaque and not attempt to
+	// interpret them.
+	ID string
+
+	// Name is the package name as it appears in the package source code.
+	Name string
+
+	// PkgPath is the package path as used by the go/types package.
+	PkgPath string
+
+	// Errors contains any errors encountered querying the metadata
+	// of the package, or while parsing or type-checking its files.
+	Errors []Error
+
+	// TypeErrors contains the subset of errors produced during type checking.
+	TypeErrors []types.Error
+
+	// GoFiles lists the absolute file paths of the package's Go source files.
+	GoFiles []string
+
+	// CompiledGoFiles lists the absolute file paths of the package's source
+	// files that are suitable for type checking.
+	// This may differ from GoFiles if files are processed before compilation.
+	CompiledGoFiles []string
+
+	// OtherFiles lists the absolute file paths of the package's non-Go source files,
+	// including assembly, C, C++, Fortran, Objective-C, SWIG, and so on.
+	OtherFiles []string
+
+	// EmbedFiles lists the absolute file paths of the package's files
+	// embedded with go:embed.
+	EmbedFiles []string
+
+	// EmbedPatterns lists the absolute file patterns of the package's
+	// files embedded with go:embed.
+	EmbedPatterns []string
+
+	// IgnoredFiles lists source files that are not part of the package
+	// using the current build configuration but that might be part of
+	// the package using other build configurations.
+	IgnoredFiles []string
+
+	// ExportFile is the absolute path to a file containing type
+	// information for the package as provided by the build system.
+	ExportFile string
+
+	// Imports maps import paths appearing in the package's Go source files
+	// to corresponding loaded Packages.
+	Imports map[string]*Package
+
+	// Types provides type information for the package.
+	// The NeedTypes LoadMode bit sets this field for packages matching the
+	// patterns; type information for dependencies may be missing or incomplete,
+	// unless NeedDeps and NeedImports are also set.
+	Types *types.Package
+
+	// Fset provides position information for Types, TypesInfo, and Syntax.
+	// It is set only when Types is set.
+	Fset *token.FileSet
+
+	// IllTyped indicates whether the package or any dependency contains errors.
+	// It is set only when Types is set.
+	IllTyped bool
+
+	// Syntax is the package's syntax trees, for the files listed in CompiledGoFiles.
+	//
+	// The NeedSyntax LoadMode bit populates this field for packages matching the patterns.
+	// If NeedDeps and NeedImports are also set, this field will also be populated
+	// for dependencies.
+	//
+	// Syntax is kept in the same order as CompiledGoFiles, with the caveat that nils are
+	// removed.  If parsing returned nil, Syntax may be shorter than CompiledGoFiles.
+	Syntax []*ast.File
+
+	// TypesInfo provides type information about the package's syntax trees.
+	// It is set only when Syntax is set.
+	TypesInfo *types.Info
+
+	// TypesSizes provides the effective size function for types in TypesInfo.
+	TypesSizes types.Sizes
+
+	// forTest is the package under test, if any.
+	forTest string
+
+	// depsErrors is the DepsErrors field from the go list response, if any.
+	depsErrors []*packagesinternal.PackageError
+
+	// module is the module information for the package if it exists.
+	Module *Module
+}
+
+// Module provides module information for a package.
+type Module struct {
+	Path      string       // module path
+	Version   string       // module version
+	Replace   *Module      // replaced by this module
+	Time      *time.Time   // time version was created
+	Main      bool         // is this the main module?
+	Indirect  bool         // is this module only an indirect dependency of main module?
+	Dir       string       // directory holding files for this module, if any
+	GoMod     string       // path to go.mod file used when loading this module, if any
+	GoVersion string       // go version used in module
+	Error     *ModuleError // error loading module
+}
+
+// ModuleError holds errors loading a module.
+type ModuleError struct {
+	Err string // the error itself
+}
+
+func init() {
+	packagesinternal.GetForTest = func(p interface{}) string {
+		return p.(*Package).forTest
+	}
+	packagesinternal.GetDepsErrors = func(p interface{}) []*packagesinternal.PackageError {
+		return p.(*Package).depsErrors
+	}
+	packagesinternal.GetGoCmdRunner = func(config interface{}) *gocommand.Runner {
+		return config.(*Config).gocmdRunner
+	}
+	packagesinternal.SetGoCmdRunner = func(config interface{}, runner *gocommand.Runner) {
+		config.(*Config).gocmdRunner = runner
+	}
+	packagesinternal.SetModFile = func(config interface{}, value string) {
+		config.(*Config).modFile = value
+	}
+	packagesinternal.SetModFlag = func(config interface{}, value string) {
+		config.(*Config).modFlag = value
+	}
+	packagesinternal.TypecheckCgo = int(typecheckCgo)
+	packagesinternal.DepsErrors = int(needInternalDepsErrors)
+	packagesinternal.ForTest = int(needInternalForTest)
+}
+
+// An Error describes a problem with a package's metadata, syntax, or types.
+type Error struct {
+	Pos  string // "file:line:col" or "file:line" or "" or "-"
+	Msg  string
+	Kind ErrorKind
+}
+
+// ErrorKind describes the source of the error, allowing the user to
+// differentiate between errors generated by the driver, the parser, or the
+// type-checker.
+type ErrorKind int
+
+const (
+	UnknownError ErrorKind = iota
+	ListError
+	ParseError
+	TypeError
+)
+
+func (err Error) Error() string {
+	pos := err.Pos
+	if pos == "" {
+		pos = "-" // like token.Position{}.String()
+	}
+	return pos + ": " + err.Msg
+}
+
+// flatPackage is the JSON form of Package
+// It drops all the type and syntax fields, and transforms the Imports
+//
+// TODO(adonovan): identify this struct with Package, effectively
+// publishing the JSON protocol.
+type flatPackage struct {
+	ID              string
+	Name            string            `json:",omitempty"`
+	PkgPath         string            `json:",omitempty"`
+	Errors          []Error           `json:",omitempty"`
+	GoFiles         []string          `json:",omitempty"`
+	CompiledGoFiles []string          `json:",omitempty"`
+	OtherFiles      []string          `json:",omitempty"`
+	EmbedFiles      []string          `json:",omitempty"`
+	EmbedPatterns   []string          `json:",omitempty"`
+	IgnoredFiles    []string          `json:",omitempty"`
+	ExportFile      string            `json:",omitempty"`
+	Imports         map[string]string `json:",omitempty"`
+}
+
+// MarshalJSON returns the Package in its JSON form.
+// For the most part, the structure fields are written out unmodified, and
+// the type and syntax fields are skipped.
+// The imports are written out as just a map of path to package id.
+// The errors are written using a custom type that tries to preserve the
+// structure of error types we know about.
+//
+// This method exists to enable support for additional build systems.  It is
+// not intended for use by clients of the API and we may change the format.
+func (p *Package) MarshalJSON() ([]byte, error) {
+	flat := &flatPackage{
+		ID:              p.ID,
+		Name:            p.Name,
+		PkgPath:         p.PkgPath,
+		Errors:          p.Errors,
+		GoFiles:         p.GoFiles,
+		CompiledGoFiles: p.CompiledGoFiles,
+		OtherFiles:      p.OtherFiles,
+		EmbedFiles:      p.EmbedFiles,
+		EmbedPatterns:   p.EmbedPatterns,
+		IgnoredFiles:    p.IgnoredFiles,
+		ExportFile:      p.ExportFile,
+	}
+	if len(p.Imports) > 0 {
+		flat.Imports = make(map[string]string, len(p.Imports))
+		for path, ipkg := range p.Imports {
+			flat.Imports[path] = ipkg.ID
+		}
+	}
+	return json.Marshal(flat)
+}
+
+// UnmarshalJSON reads in a Package from its JSON format.
+// See MarshalJSON for details about the format accepted.
+func (p *Package) UnmarshalJSON(b []byte) error {
+	flat := &flatPackage{}
+	if err := json.Unmarshal(b, &flat); err != nil {
+		return err
+	}
+	*p = Package{
+		ID:              flat.ID,
+		Name:            flat.Name,
+		PkgPath:         flat.PkgPath,
+		Errors:          flat.Errors,
+		GoFiles:         flat.GoFiles,
+		CompiledGoFiles: flat.CompiledGoFiles,
+		OtherFiles:      flat.OtherFiles,
+		EmbedFiles:      flat.EmbedFiles,
+		EmbedPatterns:   flat.EmbedPatterns,
+		ExportFile:      flat.ExportFile,
+	}
+	if len(flat.Imports) > 0 {
+		p.Imports = make(map[string]*Package, len(flat.Imports))
+		for path, id := range flat.Imports {
+			p.Imports[path] = &Package{ID: id}
+		}
+	}
+	return nil
+}
+
+func (p *Package) String() string { return p.ID }
+
+// loaderPackage augments Package with state used during the loading phase
+type loaderPackage struct {
+	*Package
+	importErrors map[string]error // maps each bad import to its error
+	loadOnce     sync.Once
+	color        uint8 // for cycle detection
+	needsrc      bool  // load from source (Mode >= LoadTypes)
+	needtypes    bool  // type information is either requested or depended on
+	initial      bool  // package was matched by a pattern
+	goVersion    int   // minor version number of go command on PATH
+}
+
+// loader holds the working state of a single call to load.
+type loader struct {
+	pkgs map[string]*loaderPackage
+	Config
+	sizes        types.Sizes
+	parseCache   map[string]*parseValue
+	parseCacheMu sync.Mutex
+	exportMu     sync.Mutex // enforces mutual exclusion of exportdata operations
+
+	// Config.Mode contains the implied mode (see impliedLoadMode).
+	// Implied mode contains all the fields we need the data for.
+	// In requestedMode there are the actually requested fields.
+	// We'll zero them out before returning packages to the user.
+	// This makes it easier for us to get the conditions where
+	// we need certain modes right.
+	requestedMode LoadMode
+}
+
+type parseValue struct {
+	f     *ast.File
+	err   error
+	ready chan struct{}
+}
+
+func newLoader(cfg *Config) *loader {
+	ld := &loader{
+		parseCache: map[string]*parseValue{},
+	}
+	if cfg != nil {
+		ld.Config = *cfg
+		// If the user has provided a logger, use it.
+		ld.Config.Logf = cfg.Logf
+	}
+	if ld.Config.Logf == nil {
+		// If the GOPACKAGESDEBUG environment variable is set to true,
+		// but the user has not provided a logger, default to log.Printf.
+		if debug {
+			ld.Config.Logf = log.Printf
+		} else {
+			ld.Config.Logf = func(format string, args ...interface{}) {}
+		}
+	}
+	if ld.Config.Mode == 0 {
+		ld.Config.Mode = NeedName | NeedFiles | NeedCompiledGoFiles // Preserve zero behavior of Mode for backwards compatibility.
+	}
+	if ld.Config.Env == nil {
+		ld.Config.Env = os.Environ()
+	}
+	if ld.Config.gocmdRunner == nil {
+		ld.Config.gocmdRunner = &gocommand.Runner{}
+	}
+	if ld.Context == nil {
+		ld.Context = context.Background()
+	}
+	if ld.Dir == "" {
+		if dir, err := os.Getwd(); err == nil {
+			ld.Dir = dir
+		}
+	}
+
+	// Save the actually requested fields. We'll zero them out before returning packages to the user.
+	ld.requestedMode = ld.Mode
+	ld.Mode = impliedLoadMode(ld.Mode)
+
+	if ld.Mode&NeedTypes != 0 || ld.Mode&NeedSyntax != 0 {
+		if ld.Fset == nil {
+			ld.Fset = token.NewFileSet()
+		}
+
+		// ParseFile is required even in LoadTypes mode
+		// because we load source if export data is missing.
+		if ld.ParseFile == nil {
+			ld.ParseFile = func(fset *token.FileSet, filename string, src []byte) (*ast.File, error) {
+				const mode = parser.AllErrors | parser.ParseComments
+				return parser.ParseFile(fset, filename, src, mode)
+			}
+		}
+	}
+
+	return ld
+}
+
+// refine connects the supplied packages into a graph and then adds type and
+// and syntax information as requested by the LoadMode.
+func (ld *loader) refine(response *driverResponse) ([]*Package, error) {
+	roots := response.Roots
+	rootMap := make(map[string]int, len(roots))
+	for i, root := range roots {
+		rootMap[root] = i
+	}
+	ld.pkgs = make(map[string]*loaderPackage)
+	// first pass, fixup and build the map and roots
+	var initial = make([]*loaderPackage, len(roots))
+	for _, pkg := range response.Packages {
+		rootIndex := -1
+		if i, found := rootMap[pkg.ID]; found {
+			rootIndex = i
+		}
+
+		// Overlays can invalidate export data.
+		// TODO(matloob): make this check fine-grained based on dependencies on overlaid files
+		exportDataInvalid := len(ld.Overlay) > 0 || pkg.ExportFile == "" && pkg.PkgPath != "unsafe"
+		// This package needs type information if the caller requested types and the package is
+		// either a root, or it's a non-root and the user requested dependencies ...
+		needtypes := (ld.Mode&NeedTypes|NeedTypesInfo != 0 && (rootIndex >= 0 || ld.Mode&NeedDeps != 0))
+		// This package needs source if the call requested source (or types info, which implies source)
+		// and the package is either a root, or itas a non- root and the user requested dependencies...
+		needsrc := ((ld.Mode&(NeedSyntax|NeedTypesInfo) != 0 && (rootIndex >= 0 || ld.Mode&NeedDeps != 0)) ||
+			// ... or if we need types and the exportData is invalid. We fall back to (incompletely)
+			// typechecking packages from source if they fail to compile.
+			(ld.Mode&(NeedTypes|NeedTypesInfo) != 0 && exportDataInvalid)) && pkg.PkgPath != "unsafe"
+		lpkg := &loaderPackage{
+			Package:   pkg,
+			needtypes: needtypes,
+			needsrc:   needsrc,
+			goVersion: response.GoVersion,
+		}
+		ld.pkgs[lpkg.ID] = lpkg
+		if rootIndex >= 0 {
+			initial[rootIndex] = lpkg
+			lpkg.initial = true
+		}
+	}
+	for i, root := range roots {
+		if initial[i] == nil {
+			return nil, fmt.Errorf("root package %v is missing", root)
+		}
+	}
+
+	// Materialize the import graph.
+
+	const (
+		white = 0 // new
+		grey  = 1 // in progress
+		black = 2 // complete
+	)
+
+	// visit traverses the import graph, depth-first,
+	// and materializes the graph as Packages.Imports.
+	//
+	// Valid imports are saved in the Packages.Import map.
+	// Invalid imports (cycles and missing nodes) are saved in the importErrors map.
+	// Thus, even in the presence of both kinds of errors, the Import graph remains a DAG.
+	//
+	// visit returns whether the package needs src or has a transitive
+	// dependency on a package that does. These are the only packages
+	// for which we load source code.
+	var stack []*loaderPackage
+	var visit func(lpkg *loaderPackage) bool
+	var srcPkgs []*loaderPackage
+	visit = func(lpkg *loaderPackage) bool {
+		switch lpkg.color {
+		case black:
+			return lpkg.needsrc
+		case grey:
+			panic("internal error: grey node")
+		}
+		lpkg.color = grey
+		stack = append(stack, lpkg) // push
+		stubs := lpkg.Imports       // the structure form has only stubs with the ID in the Imports
+		// If NeedImports isn't set, the imports fields will all be zeroed out.
+		if ld.Mode&NeedImports != 0 {
+			lpkg.Imports = make(map[string]*Package, len(stubs))
+			for importPath, ipkg := range stubs {
+				var importErr error
+				imp := ld.pkgs[ipkg.ID]
+				if imp == nil {
+					// (includes package "C" when DisableCgo)
+					importErr = fmt.Errorf("missing package: %q", ipkg.ID)
+				} else if imp.color == grey {
+					importErr = fmt.Errorf("import cycle: %s", stack)
+				}
+				if importErr != nil {
+					if lpkg.importErrors == nil {
+						lpkg.importErrors = make(map[string]error)
+					}
+					lpkg.importErrors[importPath] = importErr
+					continue
+				}
+
+				if visit(imp) {
+					lpkg.needsrc = true
+				}
+				lpkg.Imports[importPath] = imp.Package
+			}
+		}
+		if lpkg.needsrc {
+			srcPkgs = append(srcPkgs, lpkg)
+		}
+		if ld.Mode&NeedTypesSizes != 0 {
+			lpkg.TypesSizes = ld.sizes
+		}
+		stack = stack[:len(stack)-1] // pop
+		lpkg.color = black
+
+		return lpkg.needsrc
+	}
+
+	if ld.Mode&NeedImports == 0 {
+		// We do this to drop the stub import packages that we are not even going to try to resolve.
+		for _, lpkg := range initial {
+			lpkg.Imports = nil
+		}
+	} else {
+		// For each initial package, create its import DAG.
+		for _, lpkg := range initial {
+			visit(lpkg)
+		}
+	}
+	if ld.Mode&NeedImports != 0 && ld.Mode&NeedTypes != 0 {
+		for _, lpkg := range srcPkgs {
+			// Complete type information is required for the
+			// immediate dependencies of each source package.
+			for _, ipkg := range lpkg.Imports {
+				imp := ld.pkgs[ipkg.ID]
+				imp.needtypes = true
+			}
+		}
+	}
+	// Load type data and syntax if needed, starting at
+	// the initial packages (roots of the import DAG).
+	if ld.Mode&NeedTypes != 0 || ld.Mode&NeedSyntax != 0 {
+		var wg sync.WaitGroup
+		for _, lpkg := range initial {
+			wg.Add(1)
+			go func(lpkg *loaderPackage) {
+				ld.loadRecursive(lpkg)
+				wg.Done()
+			}(lpkg)
+		}
+		wg.Wait()
+	}
+
+	result := make([]*Package, len(initial))
+	for i, lpkg := range initial {
+		result[i] = lpkg.Package
+	}
+	for i := range ld.pkgs {
+		// Clear all unrequested fields,
+		// to catch programs that use more than they request.
+		if ld.requestedMode&NeedName == 0 {
+			ld.pkgs[i].Name = ""
+			ld.pkgs[i].PkgPath = ""
+		}
+		if ld.requestedMode&NeedFiles == 0 {
+			ld.pkgs[i].GoFiles = nil
+			ld.pkgs[i].OtherFiles = nil
+			ld.pkgs[i].IgnoredFiles = nil
+		}
+		if ld.requestedMode&NeedEmbedFiles == 0 {
+			ld.pkgs[i].EmbedFiles = nil
+		}
+		if ld.requestedMode&NeedEmbedPatterns == 0 {
+			ld.pkgs[i].EmbedPatterns = nil
+		}
+		if ld.requestedMode&NeedCompiledGoFiles == 0 {
+			ld.pkgs[i].CompiledGoFiles = nil
+		}
+		if ld.requestedMode&NeedImports == 0 {
+			ld.pkgs[i].Imports = nil
+		}
+		if ld.requestedMode&NeedExportFile == 0 {
+			ld.pkgs[i].ExportFile = ""
+		}
+		if ld.requestedMode&NeedTypes == 0 {
+			ld.pkgs[i].Types = nil
+			ld.pkgs[i].Fset = nil
+			ld.pkgs[i].IllTyped = false
+		}
+		if ld.requestedMode&NeedSyntax == 0 {
+			ld.pkgs[i].Syntax = nil
+		}
+		if ld.requestedMode&NeedTypesInfo == 0 {
+			ld.pkgs[i].TypesInfo = nil
+		}
+		if ld.requestedMode&NeedTypesSizes == 0 {
+			ld.pkgs[i].TypesSizes = nil
+		}
+		if ld.requestedMode&NeedModule == 0 {
+			ld.pkgs[i].Module = nil
+		}
+	}
+
+	return result, nil
+}
+
+// loadRecursive loads the specified package and its dependencies,
+// recursively, in parallel, in topological order.
+// It is atomic and idempotent.
+// Precondition: ld.Mode&NeedTypes.
+func (ld *loader) loadRecursive(lpkg *loaderPackage) {
+	lpkg.loadOnce.Do(func() {
+		// Load the direct dependencies, in parallel.
+		var wg sync.WaitGroup
+		for _, ipkg := range lpkg.Imports {
+			imp := ld.pkgs[ipkg.ID]
+			wg.Add(1)
+			go func(imp *loaderPackage) {
+				ld.loadRecursive(imp)
+				wg.Done()
+			}(imp)
+		}
+		wg.Wait()
+		ld.loadPackage(lpkg)
+	})
+}
+
+// loadPackage loads the specified package.
+// It must be called only once per Package,
+// after immediate dependencies are loaded.
+// Precondition: ld.Mode & NeedTypes.
+func (ld *loader) loadPackage(lpkg *loaderPackage) {
+	if lpkg.PkgPath == "unsafe" {
+		// Fill in the blanks to avoid surprises.
+		lpkg.Types = types.Unsafe
+		lpkg.Fset = ld.Fset
+		lpkg.Syntax = []*ast.File{}
+		lpkg.TypesInfo = new(types.Info)
+		lpkg.TypesSizes = ld.sizes
+		return
+	}
+
+	// Call NewPackage directly with explicit name.
+	// This avoids skew between golist and go/types when the files'
+	// package declarations are inconsistent.
+	lpkg.Types = types.NewPackage(lpkg.PkgPath, lpkg.Name)
+	lpkg.Fset = ld.Fset
+
+	// Subtle: we populate all Types fields with an empty Package
+	// before loading export data so that export data processing
+	// never has to create a types.Package for an indirect dependency,
+	// which would then require that such created packages be explicitly
+	// inserted back into the Import graph as a final step after export data loading.
+	// (Hence this return is after the Types assignment.)
+	// The Diamond test exercises this case.
+	if !lpkg.needtypes && !lpkg.needsrc {
+		return
+	}
+	if !lpkg.needsrc {
+		if err := ld.loadFromExportData(lpkg); err != nil {
+			lpkg.Errors = append(lpkg.Errors, Error{
+				Pos:  "-",
+				Msg:  err.Error(),
+				Kind: UnknownError, // e.g. can't find/open/parse export data
+			})
+		}
+		return // not a source package, don't get syntax trees
+	}
+
+	appendError := func(err error) {
+		// Convert various error types into the one true Error.
+		var errs []Error
+		switch err := err.(type) {
+		case Error:
+			// from driver
+			errs = append(errs, err)
+
+		case *os.PathError:
+			// from parser
+			errs = append(errs, Error{
+				Pos:  err.Path + ":1",
+				Msg:  err.Err.Error(),
+				Kind: ParseError,
+			})
+
+		case scanner.ErrorList:
+			// from parser
+			for _, err := range err {
+				errs = append(errs, Error{
+					Pos:  err.Pos.String(),
+					Msg:  err.Msg,
+					Kind: ParseError,
+				})
+			}
+
+		case types.Error:
+			// from type checker
+			lpkg.TypeErrors = append(lpkg.TypeErrors, err)
+			errs = append(errs, Error{
+				Pos:  err.Fset.Position(err.Pos).String(),
+				Msg:  err.Msg,
+				Kind: TypeError,
+			})
+
+		default:
+			// unexpected impoverished error from parser?
+			errs = append(errs, Error{
+				Pos:  "-",
+				Msg:  err.Error(),
+				Kind: UnknownError,
+			})
+
+			// If you see this error message, please file a bug.
+			log.Printf("internal error: error %q (%T) without position", err, err)
+		}
+
+		lpkg.Errors = append(lpkg.Errors, errs...)
+	}
+
+	// If the go command on the PATH is newer than the runtime,
+	// then the go/{scanner,ast,parser,types} packages from the
+	// standard library may be unable to process the files
+	// selected by go list.
+	//
+	// There is currently no way to downgrade the effective
+	// version of the go command (see issue 52078), so we proceed
+	// with the newer go command but, in case of parse or type
+	// errors, we emit an additional diagnostic.
+	//
+	// See:
+	// - golang.org/issue/52078 (flag to set release tags)
+	// - golang.org/issue/50825 (gopls legacy version support)
+	// - golang.org/issue/55883 (go/packages confusing error)
+	//
+	// Should we assert a hard minimum of (currently) go1.16 here?
+	var runtimeVersion int
+	if _, err := fmt.Sscanf(runtime.Version(), "go1.%d", &runtimeVersion); err == nil && runtimeVersion < lpkg.goVersion {
+		defer func() {
+			if len(lpkg.Errors) > 0 {
+				appendError(Error{
+					Pos:  "-",
+					Msg:  fmt.Sprintf("This application uses version go1.%d of the source-processing packages but runs version go1.%d of 'go list'. It may fail to process source files that rely on newer language features. If so, rebuild the application using a newer version of Go.", runtimeVersion, lpkg.goVersion),
+					Kind: UnknownError,
+				})
+			}
+		}()
+	}
+
+	if ld.Config.Mode&NeedTypes != 0 && len(lpkg.CompiledGoFiles) == 0 && lpkg.ExportFile != "" {
+		// The config requested loading sources and types, but sources are missing.
+		// Add an error to the package and fall back to loading from export data.
+		appendError(Error{"-", fmt.Sprintf("sources missing for package %s", lpkg.ID), ParseError})
+		_ = ld.loadFromExportData(lpkg) // ignore any secondary errors
+
+		return // can't get syntax trees for this package
+	}
+
+	files, errs := ld.parseFiles(lpkg.CompiledGoFiles)
+	for _, err := range errs {
+		appendError(err)
+	}
+
+	lpkg.Syntax = files
+	if ld.Config.Mode&NeedTypes == 0 {
+		return
+	}
+
+	lpkg.TypesInfo = &types.Info{
+		Types:      make(map[ast.Expr]types.TypeAndValue),
+		Defs:       make(map[*ast.Ident]types.Object),
+		Uses:       make(map[*ast.Ident]types.Object),
+		Implicits:  make(map[ast.Node]types.Object),
+		Scopes:     make(map[ast.Node]*types.Scope),
+		Selections: make(map[*ast.SelectorExpr]*types.Selection),
+	}
+	typeparams.InitInstanceInfo(lpkg.TypesInfo)
+	lpkg.TypesSizes = ld.sizes
+
+	importer := importerFunc(func(path string) (*types.Package, error) {
+		if path == "unsafe" {
+			return types.Unsafe, nil
+		}
+
+		// The imports map is keyed by import path.
+		ipkg := lpkg.Imports[path]
+		if ipkg == nil {
+			if err := lpkg.importErrors[path]; err != nil {
+				return nil, err
+			}
+			// There was skew between the metadata and the
+			// import declarations, likely due to an edit
+			// race, or because the ParseFile feature was
+			// used to supply alternative file contents.
+			return nil, fmt.Errorf("no metadata for %s", path)
+		}
+
+		if ipkg.Types != nil && ipkg.Types.Complete() {
+			return ipkg.Types, nil
+		}
+		log.Fatalf("internal error: package %q without types was imported from %q", path, lpkg)
+		panic("unreachable")
+	})
+
+	// type-check
+	tc := &types.Config{
+		Importer: importer,
+
+		// Type-check bodies of functions only in initial packages.
+		// Example: for import graph A->B->C and initial packages {A,C},
+		// we can ignore function bodies in B.
+		IgnoreFuncBodies: ld.Mode&NeedDeps == 0 && !lpkg.initial,
+
+		Error: appendError,
+		Sizes: ld.sizes,
+	}
+	if (ld.Mode & typecheckCgo) != 0 {
+		if !typesinternal.SetUsesCgo(tc) {
+			appendError(Error{
+				Msg:  "typecheckCgo requires Go 1.15+",
+				Kind: ListError,
+			})
+			return
+		}
+	}
+	types.NewChecker(tc, ld.Fset, lpkg.Types, lpkg.TypesInfo).Files(lpkg.Syntax)
+
+	lpkg.importErrors = nil // no longer needed
+
+	// If !Cgo, the type-checker uses FakeImportC mode, so
+	// it doesn't invoke the importer for import "C",
+	// nor report an error for the import,
+	// or for any undefined C.f reference.
+	// We must detect this explicitly and correctly
+	// mark the package as IllTyped (by reporting an error).
+	// TODO(adonovan): if these errors are annoying,
+	// we could just set IllTyped quietly.
+	if tc.FakeImportC {
+	outer:
+		for _, f := range lpkg.Syntax {
+			for _, imp := range f.Imports {
+				if imp.Path.Value == `"C"` {
+					err := types.Error{Fset: ld.Fset, Pos: imp.Pos(), Msg: `import "C" ignored`}
+					appendError(err)
+					break outer
+				}
+			}
+		}
+	}
+
+	// Record accumulated errors.
+	illTyped := len(lpkg.Errors) > 0
+	if !illTyped {
+		for _, imp := range lpkg.Imports {
+			if imp.IllTyped {
+				illTyped = true
+				break
+			}
+		}
+	}
+	lpkg.IllTyped = illTyped
+}
+
+// An importFunc is an implementation of the single-method
+// types.Importer interface based on a function value.
+type importerFunc func(path string) (*types.Package, error)
+
+func (f importerFunc) Import(path string) (*types.Package, error) { return f(path) }
+
+// We use a counting semaphore to limit
+// the number of parallel I/O calls per process.
+var ioLimit = make(chan bool, 20)
+
+func (ld *loader) parseFile(filename string) (*ast.File, error) {
+	ld.parseCacheMu.Lock()
+	v, ok := ld.parseCache[filename]
+	if ok {
+		// cache hit
+		ld.parseCacheMu.Unlock()
+		<-v.ready
+	} else {
+		// cache miss
+		v = &parseValue{ready: make(chan struct{})}
+		ld.parseCache[filename] = v
+		ld.parseCacheMu.Unlock()
+
+		var src []byte
+		for f, contents := range ld.Config.Overlay {
+			if sameFile(f, filename) {
+				src = contents
+			}
+		}
+		var err error
+		if src == nil {
+			ioLimit <- true // wait
+			src, err = ioutil.ReadFile(filename)
+			<-ioLimit // signal
+		}
+		if err != nil {
+			v.err = err
+		} else {
+			v.f, v.err = ld.ParseFile(ld.Fset, filename, src)
+		}
+
+		close(v.ready)
+	}
+	return v.f, v.err
+}
+
+// parseFiles reads and parses the Go source files and returns the ASTs
+// of the ones that could be at least partially parsed, along with a
+// list of I/O and parse errors encountered.
+//
+// Because files are scanned in parallel, the token.Pos
+// positions of the resulting ast.Files are not ordered.
+func (ld *loader) parseFiles(filenames []string) ([]*ast.File, []error) {
+	var wg sync.WaitGroup
+	n := len(filenames)
+	parsed := make([]*ast.File, n)
+	errors := make([]error, n)
+	for i, file := range filenames {
+		if ld.Config.Context.Err() != nil {
+			parsed[i] = nil
+			errors[i] = ld.Config.Context.Err()
+			continue
+		}
+		wg.Add(1)
+		go func(i int, filename string) {
+			parsed[i], errors[i] = ld.parseFile(filename)
+			wg.Done()
+		}(i, file)
+	}
+	wg.Wait()
+
+	// Eliminate nils, preserving order.
+	var o int
+	for _, f := range parsed {
+		if f != nil {
+			parsed[o] = f
+			o++
+		}
+	}
+	parsed = parsed[:o]
+
+	o = 0
+	for _, err := range errors {
+		if err != nil {
+			errors[o] = err
+			o++
+		}
+	}
+	errors = errors[:o]
+
+	return parsed, errors
+}
+
+// sameFile returns true if x and y have the same basename and denote
+// the same file.
+func sameFile(x, y string) bool {
+	if x == y {
+		// It could be the case that y doesn't exist.
+		// For instance, it may be an overlay file that
+		// hasn't been written to disk. To handle that case
+		// let x == y through. (We added the exact absolute path
+		// string to the CompiledGoFiles list, so the unwritten
+		// overlay case implies x==y.)
+		return true
+	}
+	if strings.EqualFold(filepath.Base(x), filepath.Base(y)) { // (optimisation)
+		if xi, err := os.Stat(x); err == nil {
+			if yi, err := os.Stat(y); err == nil {
+				return os.SameFile(xi, yi)
+			}
+		}
+	}
+	return false
+}
+
+// loadFromExportData ensures that type information is present for the specified
+// package, loading it from an export data file on the first request.
+// On success it sets lpkg.Types to a new Package.
+func (ld *loader) loadFromExportData(lpkg *loaderPackage) error {
+	if lpkg.PkgPath == "" {
+		log.Fatalf("internal error: Package %s has no PkgPath", lpkg)
+	}
+
+	// Because gcexportdata.Read has the potential to create or
+	// modify the types.Package for each node in the transitive
+	// closure of dependencies of lpkg, all exportdata operations
+	// must be sequential. (Finer-grained locking would require
+	// changes to the gcexportdata API.)
+	//
+	// The exportMu lock guards the lpkg.Types field and the
+	// types.Package it points to, for each loaderPackage in the graph.
+	//
+	// Not all accesses to Package.Pkg need to be protected by exportMu:
+	// graph ordering ensures that direct dependencies of source
+	// packages are fully loaded before the importer reads their Pkg field.
+	ld.exportMu.Lock()
+	defer ld.exportMu.Unlock()
+
+	if tpkg := lpkg.Types; tpkg != nil && tpkg.Complete() {
+		return nil // cache hit
+	}
+
+	lpkg.IllTyped = true // fail safe
+
+	if lpkg.ExportFile == "" {
+		// Errors while building export data will have been printed to stderr.
+		return fmt.Errorf("no export data file")
+	}
+	f, err := os.Open(lpkg.ExportFile)
+	if err != nil {
+		return err
+	}
+	defer f.Close()
+
+	// Read gc export data.
+	//
+	// We don't currently support gccgo export data because all
+	// underlying workspaces use the gc toolchain. (Even build
+	// systems that support gccgo don't use it for workspace
+	// queries.)
+	r, err := gcexportdata.NewReader(f)
+	if err != nil {
+		return fmt.Errorf("reading %s: %v", lpkg.ExportFile, err)
+	}
+
+	// Build the view.
+	//
+	// The gcexportdata machinery has no concept of package ID.
+	// It identifies packages by their PkgPath, which although not
+	// globally unique is unique within the scope of one invocation
+	// of the linker, type-checker, or gcexportdata.
+	//
+	// So, we must build a PkgPath-keyed view of the global
+	// (conceptually ID-keyed) cache of packages and pass it to
+	// gcexportdata. The view must contain every existing
+	// package that might possibly be mentioned by the
+	// current package---its transitive closure.
+	//
+	// In loadPackage, we unconditionally create a types.Package for
+	// each dependency so that export data loading does not
+	// create new ones.
+	//
+	// TODO(adonovan): it would be simpler and more efficient
+	// if the export data machinery invoked a callback to
+	// get-or-create a package instead of a map.
+	//
+	view := make(map[string]*types.Package) // view seen by gcexportdata
+	seen := make(map[*loaderPackage]bool)   // all visited packages
+	var visit func(pkgs map[string]*Package)
+	visit = func(pkgs map[string]*Package) {
+		for _, p := range pkgs {
+			lpkg := ld.pkgs[p.ID]
+			if !seen[lpkg] {
+				seen[lpkg] = true
+				view[lpkg.PkgPath] = lpkg.Types
+				visit(lpkg.Imports)
+			}
+		}
+	}
+	visit(lpkg.Imports)
+
+	viewLen := len(view) + 1 // adding the self package
+	// Parse the export data.
+	// (May modify incomplete packages in view but not create new ones.)
+	tpkg, err := gcexportdata.Read(r, ld.Fset, view, lpkg.PkgPath)
+	if err != nil {
+		return fmt.Errorf("reading %s: %v", lpkg.ExportFile, err)
+	}
+	if _, ok := view["go.shape"]; ok {
+		// Account for the pseudopackage "go.shape" that gets
+		// created by generic code.
+		viewLen++
+	}
+	if viewLen != len(view) {
+		log.Panicf("golang.org/x/tools/go/packages: unexpected new packages during load of %s", lpkg.PkgPath)
+	}
+
+	lpkg.Types = tpkg
+	lpkg.IllTyped = false
+	return nil
+}
+
+// impliedLoadMode returns loadMode with its dependencies.
+func impliedLoadMode(loadMode LoadMode) LoadMode {
+	if loadMode&(NeedDeps|NeedTypes|NeedTypesInfo) != 0 {
+		// All these things require knowing the import graph.
+		loadMode |= NeedImports
+	}
+
+	return loadMode
+}
+
+func usesExportData(cfg *Config) bool {
+	return cfg.Mode&NeedExportFile != 0 || cfg.Mode&NeedTypes != 0 && cfg.Mode&NeedDeps == 0
+}
+
+var _ interface{} = io.Discard // assert build toolchain is go1.16 or later
diff --git a/vendor/golang.org/x/tools/go/packages/visit.go b/vendor/golang.org/x/tools/go/packages/visit.go
new file mode 100644
index 0000000..a1dcc40
--- /dev/null
+++ b/vendor/golang.org/x/tools/go/packages/visit.go
@@ -0,0 +1,59 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package packages
+
+import (
+	"fmt"
+	"os"
+	"sort"
+)
+
+// Visit visits all the packages in the import graph whose roots are
+// pkgs, calling the optional pre function the first time each package
+// is encountered (preorder), and the optional post function after a
+// package's dependencies have been visited (postorder).
+// The boolean result of pre(pkg) determines whether
+// the imports of package pkg are visited.
+func Visit(pkgs []*Package, pre func(*Package) bool, post func(*Package)) {
+	seen := make(map[*Package]bool)
+	var visit func(*Package)
+	visit = func(pkg *Package) {
+		if !seen[pkg] {
+			seen[pkg] = true
+
+			if pre == nil || pre(pkg) {
+				paths := make([]string, 0, len(pkg.Imports))
+				for path := range pkg.Imports {
+					paths = append(paths, path)
+				}
+				sort.Strings(paths) // Imports is a map, this makes visit stable
+				for _, path := range paths {
+					visit(pkg.Imports[path])
+				}
+			}
+
+			if post != nil {
+				post(pkg)
+			}
+		}
+	}
+	for _, pkg := range pkgs {
+		visit(pkg)
+	}
+}
+
+// PrintErrors prints to os.Stderr the accumulated errors of all
+// packages in the import graph rooted at pkgs, dependencies first.
+// PrintErrors returns the number of errors printed.
+func PrintErrors(pkgs []*Package) int {
+	var n int
+	Visit(pkgs, nil, func(pkg *Package) {
+		for _, err := range pkg.Errors {
+			fmt.Fprintln(os.Stderr, err)
+			n++
+		}
+	})
+	return n
+}
diff --git a/vendor/golang.org/x/tools/go/types/objectpath/objectpath.go b/vendor/golang.org/x/tools/go/types/objectpath/objectpath.go
new file mode 100644
index 0000000..be8f5a8
--- /dev/null
+++ b/vendor/golang.org/x/tools/go/types/objectpath/objectpath.go
@@ -0,0 +1,762 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package objectpath defines a naming scheme for types.Objects
+// (that is, named entities in Go programs) relative to their enclosing
+// package.
+//
+// Type-checker objects are canonical, so they are usually identified by
+// their address in memory (a pointer), but a pointer has meaning only
+// within one address space. By contrast, objectpath names allow the
+// identity of an object to be sent from one program to another,
+// establishing a correspondence between types.Object variables that are
+// distinct but logically equivalent.
+//
+// A single object may have multiple paths. In this example,
+//
+//	type A struct{ X int }
+//	type B A
+//
+// the field X has two paths due to its membership of both A and B.
+// The For(obj) function always returns one of these paths, arbitrarily
+// but consistently.
+package objectpath
+
+import (
+	"fmt"
+	"go/types"
+	"sort"
+	"strconv"
+	"strings"
+
+	"golang.org/x/tools/internal/typeparams"
+
+	_ "unsafe" // for go:linkname
+)
+
+// A Path is an opaque name that identifies a types.Object
+// relative to its package. Conceptually, the name consists of a
+// sequence of destructuring operations applied to the package scope
+// to obtain the original object.
+// The name does not include the package itself.
+type Path string
+
+// Encoding
+//
+// An object path is a textual and (with training) human-readable encoding
+// of a sequence of destructuring operators, starting from a types.Package.
+// The sequences represent a path through the package/object/type graph.
+// We classify these operators by their type:
+//
+//	PO package->object	Package.Scope.Lookup
+//	OT  object->type 	Object.Type
+//	TT    type->type 	Type.{Elem,Key,Params,Results,Underlying} [EKPRU]
+//	TO   type->object	Type.{At,Field,Method,Obj} [AFMO]
+//
+// All valid paths start with a package and end at an object
+// and thus may be defined by the regular language:
+//
+//	objectpath = PO (OT TT* TO)*
+//
+// The concrete encoding follows directly:
+//   - The only PO operator is Package.Scope.Lookup, which requires an identifier.
+//   - The only OT operator is Object.Type,
+//     which we encode as '.' because dot cannot appear in an identifier.
+//   - The TT operators are encoded as [EKPRUTC];
+//     one of these (TypeParam) requires an integer operand,
+//     which is encoded as a string of decimal digits.
+//   - The TO operators are encoded as [AFMO];
+//     three of these (At,Field,Method) require an integer operand,
+//     which is encoded as a string of decimal digits.
+//     These indices are stable across different representations
+//     of the same package, even source and export data.
+//     The indices used are implementation specific and may not correspond to
+//     the argument to the go/types function.
+//
+// In the example below,
+//
+//	package p
+//
+//	type T interface {
+//		f() (a string, b struct{ X int })
+//	}
+//
+// field X has the path "T.UM0.RA1.F0",
+// representing the following sequence of operations:
+//
+//	p.Lookup("T")					T
+//	.Type().Underlying().Method(0).			f
+//	.Type().Results().At(1)				b
+//	.Type().Field(0)					X
+//
+// The encoding is not maximally compact---every R or P is
+// followed by an A, for example---but this simplifies the
+// encoder and decoder.
+const (
+	// object->type operators
+	opType = '.' // .Type()		  (Object)
+
+	// type->type operators
+	opElem       = 'E' // .Elem()		        (Pointer, Slice, Array, Chan, Map)
+	opKey        = 'K' // .Key()		        (Map)
+	opParams     = 'P' // .Params()		      (Signature)
+	opResults    = 'R' // .Results()	      (Signature)
+	opUnderlying = 'U' // .Underlying()	    (Named)
+	opTypeParam  = 'T' // .TypeParams.At(i) (Named, Signature)
+	opConstraint = 'C' // .Constraint()     (TypeParam)
+
+	// type->object operators
+	opAt     = 'A' // .At(i)		 (Tuple)
+	opField  = 'F' // .Field(i)	 (Struct)
+	opMethod = 'M' // .Method(i) (Named or Interface; not Struct: "promoted" names are ignored)
+	opObj    = 'O' // .Obj()		 (Named, TypeParam)
+)
+
+// For returns the path to an object relative to its package,
+// or an error if the object is not accessible from the package's Scope.
+//
+// The For function guarantees to return a path only for the following objects:
+// - package-level types
+// - exported package-level non-types
+// - methods
+// - parameter and result variables
+// - struct fields
+// These objects are sufficient to define the API of their package.
+// The objects described by a package's export data are drawn from this set.
+//
+// For does not return a path for predeclared names, imported package
+// names, local names, and unexported package-level names (except
+// types).
+//
+// Example: given this definition,
+//
+//	package p
+//
+//	type T interface {
+//		f() (a string, b struct{ X int })
+//	}
+//
+// For(X) would return a path that denotes the following sequence of operations:
+//
+//	p.Scope().Lookup("T")				(TypeName T)
+//	.Type().Underlying().Method(0).			(method Func f)
+//	.Type().Results().At(1)				(field Var b)
+//	.Type().Field(0)					(field Var X)
+//
+// where p is the package (*types.Package) to which X belongs.
+func For(obj types.Object) (Path, error) {
+	return newEncoderFor()(obj)
+}
+
+// An encoder amortizes the cost of encoding the paths of multiple objects.
+// Nonexported pending approval of proposal 58668.
+type encoder struct {
+	scopeNamesMemo   map[*types.Scope][]string      // memoization of Scope.Names()
+	namedMethodsMemo map[*types.Named][]*types.Func // memoization of namedMethods()
+}
+
+// Exposed to gopls via golang.org/x/tools/internal/typesinternal
+// pending approval of proposal 58668.
+//
+//go:linkname newEncoderFor
+func newEncoderFor() func(types.Object) (Path, error) { return new(encoder).For }
+
+func (enc *encoder) For(obj types.Object) (Path, error) {
+	pkg := obj.Pkg()
+
+	// This table lists the cases of interest.
+	//
+	// Object				Action
+	// ------                               ------
+	// nil					reject
+	// builtin				reject
+	// pkgname				reject
+	// label				reject
+	// var
+	//    package-level			accept
+	//    func param/result			accept
+	//    local				reject
+	//    struct field			accept
+	// const
+	//    package-level			accept
+	//    local				reject
+	// func
+	//    package-level			accept
+	//    init functions			reject
+	//    concrete method			accept
+	//    interface method			accept
+	// type
+	//    package-level			accept
+	//    local				reject
+	//
+	// The only accessible package-level objects are members of pkg itself.
+	//
+	// The cases are handled in four steps:
+	//
+	// 1. reject nil and builtin
+	// 2. accept package-level objects
+	// 3. reject obviously invalid objects
+	// 4. search the API for the path to the param/result/field/method.
+
+	// 1. reference to nil or builtin?
+	if pkg == nil {
+		return "", fmt.Errorf("predeclared %s has no path", obj)
+	}
+	scope := pkg.Scope()
+
+	// 2. package-level object?
+	if scope.Lookup(obj.Name()) == obj {
+		// Only exported objects (and non-exported types) have a path.
+		// Non-exported types may be referenced by other objects.
+		if _, ok := obj.(*types.TypeName); !ok && !obj.Exported() {
+			return "", fmt.Errorf("no path for non-exported %v", obj)
+		}
+		return Path(obj.Name()), nil
+	}
+
+	// 3. Not a package-level object.
+	//    Reject obviously non-viable cases.
+	switch obj := obj.(type) {
+	case *types.TypeName:
+		if _, ok := obj.Type().(*typeparams.TypeParam); !ok {
+			// With the exception of type parameters, only package-level type names
+			// have a path.
+			return "", fmt.Errorf("no path for %v", obj)
+		}
+	case *types.Const, // Only package-level constants have a path.
+		*types.Label,   // Labels are function-local.
+		*types.PkgName: // PkgNames are file-local.
+		return "", fmt.Errorf("no path for %v", obj)
+
+	case *types.Var:
+		// Could be:
+		// - a field (obj.IsField())
+		// - a func parameter or result
+		// - a local var.
+		// Sadly there is no way to distinguish
+		// a param/result from a local
+		// so we must proceed to the find.
+
+	case *types.Func:
+		// A func, if not package-level, must be a method.
+		if recv := obj.Type().(*types.Signature).Recv(); recv == nil {
+			return "", fmt.Errorf("func is not a method: %v", obj)
+		}
+
+		if path, ok := enc.concreteMethod(obj); ok {
+			// Fast path for concrete methods that avoids looping over scope.
+			return path, nil
+		}
+
+	default:
+		panic(obj)
+	}
+
+	// 4. Search the API for the path to the var (field/param/result) or method.
+
+	// First inspect package-level named types.
+	// In the presence of path aliases, these give
+	// the best paths because non-types may
+	// refer to types, but not the reverse.
+	empty := make([]byte, 0, 48) // initial space
+	names := enc.scopeNames(scope)
+	for _, name := range names {
+		o := scope.Lookup(name)
+		tname, ok := o.(*types.TypeName)
+		if !ok {
+			continue // handle non-types in second pass
+		}
+
+		path := append(empty, name...)
+		path = append(path, opType)
+
+		T := o.Type()
+
+		if tname.IsAlias() {
+			// type alias
+			if r := find(obj, T, path, nil); r != nil {
+				return Path(r), nil
+			}
+		} else {
+			if named, _ := T.(*types.Named); named != nil {
+				if r := findTypeParam(obj, typeparams.ForNamed(named), path, nil); r != nil {
+					// generic named type
+					return Path(r), nil
+				}
+			}
+			// defined (named) type
+			if r := find(obj, T.Underlying(), append(path, opUnderlying), nil); r != nil {
+				return Path(r), nil
+			}
+		}
+	}
+
+	// Then inspect everything else:
+	// non-types, and declared methods of defined types.
+	for _, name := range names {
+		o := scope.Lookup(name)
+		path := append(empty, name...)
+		if _, ok := o.(*types.TypeName); !ok {
+			if o.Exported() {
+				// exported non-type (const, var, func)
+				if r := find(obj, o.Type(), append(path, opType), nil); r != nil {
+					return Path(r), nil
+				}
+			}
+			continue
+		}
+
+		// Inspect declared methods of defined types.
+		if T, ok := o.Type().(*types.Named); ok {
+			path = append(path, opType)
+			// Note that method index here is always with respect
+			// to canonical ordering of methods, regardless of how
+			// they appear in the underlying type.
+			for i, m := range enc.namedMethods(T) {
+				path2 := appendOpArg(path, opMethod, i)
+				if m == obj {
+					return Path(path2), nil // found declared method
+				}
+				if r := find(obj, m.Type(), append(path2, opType), nil); r != nil {
+					return Path(r), nil
+				}
+			}
+		}
+	}
+
+	return "", fmt.Errorf("can't find path for %v in %s", obj, pkg.Path())
+}
+
+func appendOpArg(path []byte, op byte, arg int) []byte {
+	path = append(path, op)
+	path = strconv.AppendInt(path, int64(arg), 10)
+	return path
+}
+
+// concreteMethod returns the path for meth, which must have a non-nil receiver.
+// The second return value indicates success and may be false if the method is
+// an interface method or if it is an instantiated method.
+//
+// This function is just an optimization that avoids the general scope walking
+// approach. You are expected to fall back to the general approach if this
+// function fails.
+func (enc *encoder) concreteMethod(meth *types.Func) (Path, bool) {
+	// Concrete methods can only be declared on package-scoped named types. For
+	// that reason we can skip the expensive walk over the package scope: the
+	// path will always be package -> named type -> method. We can trivially get
+	// the type name from the receiver, and only have to look over the type's
+	// methods to find the method index.
+	//
+	// Methods on generic types require special consideration, however. Consider
+	// the following package:
+	//
+	// 	L1: type S[T any] struct{}
+	// 	L2: func (recv S[A]) Foo() { recv.Bar() }
+	// 	L3: func (recv S[B]) Bar() { }
+	// 	L4: type Alias = S[int]
+	// 	L5: func _[T any]() { var s S[int]; s.Foo() }
+	//
+	// The receivers of methods on generic types are instantiations. L2 and L3
+	// instantiate S with the type-parameters A and B, which are scoped to the
+	// respective methods. L4 and L5 each instantiate S with int. Each of these
+	// instantiations has its own method set, full of methods (and thus objects)
+	// with receivers whose types are the respective instantiations. In other
+	// words, we have
+	//
+	// S[A].Foo, S[A].Bar
+	// S[B].Foo, S[B].Bar
+	// S[int].Foo, S[int].Bar
+	//
+	// We may thus be trying to produce object paths for any of these objects.
+	//
+	// S[A].Foo and S[B].Bar are the origin methods, and their paths are S.Foo
+	// and S.Bar, which are the paths that this function naturally produces.
+	//
+	// S[A].Bar, S[B].Foo, and both methods on S[int] are instantiations that
+	// don't correspond to the origin methods. For S[int], this is significant.
+	// The most precise object path for S[int].Foo, for example, is Alias.Foo,
+	// not S.Foo. Our function, however, would produce S.Foo, which would
+	// resolve to a different object.
+	//
+	// For S[A].Bar and S[B].Foo it could be argued that S.Bar and S.Foo are
+	// still the correct paths, since only the origin methods have meaningful
+	// paths. But this is likely only true for trivial cases and has edge cases.
+	// Since this function is only an optimization, we err on the side of giving
+	// up, deferring to the slower but definitely correct algorithm. Most users
+	// of objectpath will only be giving us origin methods, anyway, as referring
+	// to instantiated methods is usually not useful.
+
+	if typeparams.OriginMethod(meth) != meth {
+		return "", false
+	}
+
+	recvT := meth.Type().(*types.Signature).Recv().Type()
+	if ptr, ok := recvT.(*types.Pointer); ok {
+		recvT = ptr.Elem()
+	}
+
+	named, ok := recvT.(*types.Named)
+	if !ok {
+		return "", false
+	}
+
+	if types.IsInterface(named) {
+		// Named interfaces don't have to be package-scoped
+		//
+		// TODO(dominikh): opt: if scope.Lookup(name) == named, then we can apply this optimization to interface
+		// methods, too, I think.
+		return "", false
+	}
+
+	// Preallocate space for the name, opType, opMethod, and some digits.
+	name := named.Obj().Name()
+	path := make([]byte, 0, len(name)+8)
+	path = append(path, name...)
+	path = append(path, opType)
+	for i, m := range enc.namedMethods(named) {
+		if m == meth {
+			path = appendOpArg(path, opMethod, i)
+			return Path(path), true
+		}
+	}
+
+	panic(fmt.Sprintf("couldn't find method %s on type %s", meth, named))
+}
+
+// find finds obj within type T, returning the path to it, or nil if not found.
+//
+// The seen map is used to short circuit cycles through type parameters. If
+// nil, it will be allocated as necessary.
+func find(obj types.Object, T types.Type, path []byte, seen map[*types.TypeName]bool) []byte {
+	switch T := T.(type) {
+	case *types.Basic, *types.Named:
+		// Named types belonging to pkg were handled already,
+		// so T must belong to another package. No path.
+		return nil
+	case *types.Pointer:
+		return find(obj, T.Elem(), append(path, opElem), seen)
+	case *types.Slice:
+		return find(obj, T.Elem(), append(path, opElem), seen)
+	case *types.Array:
+		return find(obj, T.Elem(), append(path, opElem), seen)
+	case *types.Chan:
+		return find(obj, T.Elem(), append(path, opElem), seen)
+	case *types.Map:
+		if r := find(obj, T.Key(), append(path, opKey), seen); r != nil {
+			return r
+		}
+		return find(obj, T.Elem(), append(path, opElem), seen)
+	case *types.Signature:
+		if r := findTypeParam(obj, typeparams.ForSignature(T), path, seen); r != nil {
+			return r
+		}
+		if r := find(obj, T.Params(), append(path, opParams), seen); r != nil {
+			return r
+		}
+		return find(obj, T.Results(), append(path, opResults), seen)
+	case *types.Struct:
+		for i := 0; i < T.NumFields(); i++ {
+			fld := T.Field(i)
+			path2 := appendOpArg(path, opField, i)
+			if fld == obj {
+				return path2 // found field var
+			}
+			if r := find(obj, fld.Type(), append(path2, opType), seen); r != nil {
+				return r
+			}
+		}
+		return nil
+	case *types.Tuple:
+		for i := 0; i < T.Len(); i++ {
+			v := T.At(i)
+			path2 := appendOpArg(path, opAt, i)
+			if v == obj {
+				return path2 // found param/result var
+			}
+			if r := find(obj, v.Type(), append(path2, opType), seen); r != nil {
+				return r
+			}
+		}
+		return nil
+	case *types.Interface:
+		for i := 0; i < T.NumMethods(); i++ {
+			m := T.Method(i)
+			path2 := appendOpArg(path, opMethod, i)
+			if m == obj {
+				return path2 // found interface method
+			}
+			if r := find(obj, m.Type(), append(path2, opType), seen); r != nil {
+				return r
+			}
+		}
+		return nil
+	case *typeparams.TypeParam:
+		name := T.Obj()
+		if name == obj {
+			return append(path, opObj)
+		}
+		if seen[name] {
+			return nil
+		}
+		if seen == nil {
+			seen = make(map[*types.TypeName]bool)
+		}
+		seen[name] = true
+		if r := find(obj, T.Constraint(), append(path, opConstraint), seen); r != nil {
+			return r
+		}
+		return nil
+	}
+	panic(T)
+}
+
+func findTypeParam(obj types.Object, list *typeparams.TypeParamList, path []byte, seen map[*types.TypeName]bool) []byte {
+	for i := 0; i < list.Len(); i++ {
+		tparam := list.At(i)
+		path2 := appendOpArg(path, opTypeParam, i)
+		if r := find(obj, tparam, path2, seen); r != nil {
+			return r
+		}
+	}
+	return nil
+}
+
+// Object returns the object denoted by path p within the package pkg.
+func Object(pkg *types.Package, p Path) (types.Object, error) {
+	if p == "" {
+		return nil, fmt.Errorf("empty path")
+	}
+
+	pathstr := string(p)
+	var pkgobj, suffix string
+	if dot := strings.IndexByte(pathstr, opType); dot < 0 {
+		pkgobj = pathstr
+	} else {
+		pkgobj = pathstr[:dot]
+		suffix = pathstr[dot:] // suffix starts with "."
+	}
+
+	obj := pkg.Scope().Lookup(pkgobj)
+	if obj == nil {
+		return nil, fmt.Errorf("package %s does not contain %q", pkg.Path(), pkgobj)
+	}
+
+	// abstraction of *types.{Pointer,Slice,Array,Chan,Map}
+	type hasElem interface {
+		Elem() types.Type
+	}
+	// abstraction of *types.{Named,Signature}
+	type hasTypeParams interface {
+		TypeParams() *typeparams.TypeParamList
+	}
+	// abstraction of *types.{Named,TypeParam}
+	type hasObj interface {
+		Obj() *types.TypeName
+	}
+
+	// The loop state is the pair (t, obj),
+	// exactly one of which is non-nil, initially obj.
+	// All suffixes start with '.' (the only object->type operation),
+	// followed by optional type->type operations,
+	// then a type->object operation.
+	// The cycle then repeats.
+	var t types.Type
+	for suffix != "" {
+		code := suffix[0]
+		suffix = suffix[1:]
+
+		// Codes [AFM] have an integer operand.
+		var index int
+		switch code {
+		case opAt, opField, opMethod, opTypeParam:
+			rest := strings.TrimLeft(suffix, "0123456789")
+			numerals := suffix[:len(suffix)-len(rest)]
+			suffix = rest
+			i, err := strconv.Atoi(numerals)
+			if err != nil {
+				return nil, fmt.Errorf("invalid path: bad numeric operand %q for code %q", numerals, code)
+			}
+			index = int(i)
+		case opObj:
+			// no operand
+		default:
+			// The suffix must end with a type->object operation.
+			if suffix == "" {
+				return nil, fmt.Errorf("invalid path: ends with %q, want [AFMO]", code)
+			}
+		}
+
+		if code == opType {
+			if t != nil {
+				return nil, fmt.Errorf("invalid path: unexpected %q in type context", opType)
+			}
+			t = obj.Type()
+			obj = nil
+			continue
+		}
+
+		if t == nil {
+			return nil, fmt.Errorf("invalid path: code %q in object context", code)
+		}
+
+		// Inv: t != nil, obj == nil
+
+		switch code {
+		case opElem:
+			hasElem, ok := t.(hasElem) // Pointer, Slice, Array, Chan, Map
+			if !ok {
+				return nil, fmt.Errorf("cannot apply %q to %s (got %T, want pointer, slice, array, chan or map)", code, t, t)
+			}
+			t = hasElem.Elem()
+
+		case opKey:
+			mapType, ok := t.(*types.Map)
+			if !ok {
+				return nil, fmt.Errorf("cannot apply %q to %s (got %T, want map)", code, t, t)
+			}
+			t = mapType.Key()
+
+		case opParams:
+			sig, ok := t.(*types.Signature)
+			if !ok {
+				return nil, fmt.Errorf("cannot apply %q to %s (got %T, want signature)", code, t, t)
+			}
+			t = sig.Params()
+
+		case opResults:
+			sig, ok := t.(*types.Signature)
+			if !ok {
+				return nil, fmt.Errorf("cannot apply %q to %s (got %T, want signature)", code, t, t)
+			}
+			t = sig.Results()
+
+		case opUnderlying:
+			named, ok := t.(*types.Named)
+			if !ok {
+				return nil, fmt.Errorf("cannot apply %q to %s (got %T, want named)", code, t, t)
+			}
+			t = named.Underlying()
+
+		case opTypeParam:
+			hasTypeParams, ok := t.(hasTypeParams) // Named, Signature
+			if !ok {
+				return nil, fmt.Errorf("cannot apply %q to %s (got %T, want named or signature)", code, t, t)
+			}
+			tparams := hasTypeParams.TypeParams()
+			if n := tparams.Len(); index >= n {
+				return nil, fmt.Errorf("tuple index %d out of range [0-%d)", index, n)
+			}
+			t = tparams.At(index)
+
+		case opConstraint:
+			tparam, ok := t.(*typeparams.TypeParam)
+			if !ok {
+				return nil, fmt.Errorf("cannot apply %q to %s (got %T, want type parameter)", code, t, t)
+			}
+			t = tparam.Constraint()
+
+		case opAt:
+			tuple, ok := t.(*types.Tuple)
+			if !ok {
+				return nil, fmt.Errorf("cannot apply %q to %s (got %T, want tuple)", code, t, t)
+			}
+			if n := tuple.Len(); index >= n {
+				return nil, fmt.Errorf("tuple index %d out of range [0-%d)", index, n)
+			}
+			obj = tuple.At(index)
+			t = nil
+
+		case opField:
+			structType, ok := t.(*types.Struct)
+			if !ok {
+				return nil, fmt.Errorf("cannot apply %q to %s (got %T, want struct)", code, t, t)
+			}
+			if n := structType.NumFields(); index >= n {
+				return nil, fmt.Errorf("field index %d out of range [0-%d)", index, n)
+			}
+			obj = structType.Field(index)
+			t = nil
+
+		case opMethod:
+			switch t := t.(type) {
+			case *types.Interface:
+				if index >= t.NumMethods() {
+					return nil, fmt.Errorf("method index %d out of range [0-%d)", index, t.NumMethods())
+				}
+				obj = t.Method(index) // Id-ordered
+
+			case *types.Named:
+				methods := namedMethods(t) // (unmemoized)
+				if index >= len(methods) {
+					return nil, fmt.Errorf("method index %d out of range [0-%d)", index, len(methods))
+				}
+				obj = methods[index] // Id-ordered
+
+			default:
+				return nil, fmt.Errorf("cannot apply %q to %s (got %T, want interface or named)", code, t, t)
+			}
+			t = nil
+
+		case opObj:
+			hasObj, ok := t.(hasObj)
+			if !ok {
+				return nil, fmt.Errorf("cannot apply %q to %s (got %T, want named or type param)", code, t, t)
+			}
+			obj = hasObj.Obj()
+			t = nil
+
+		default:
+			return nil, fmt.Errorf("invalid path: unknown code %q", code)
+		}
+	}
+
+	if obj.Pkg() != pkg {
+		return nil, fmt.Errorf("path denotes %s, which belongs to a different package", obj)
+	}
+
+	return obj, nil // success
+}
+
+// namedMethods returns the methods of a Named type in ascending Id order.
+func namedMethods(named *types.Named) []*types.Func {
+	methods := make([]*types.Func, named.NumMethods())
+	for i := range methods {
+		methods[i] = named.Method(i)
+	}
+	sort.Slice(methods, func(i, j int) bool {
+		return methods[i].Id() < methods[j].Id()
+	})
+	return methods
+}
+
+// scopeNames is a memoization of scope.Names. Callers must not modify the result.
+func (enc *encoder) scopeNames(scope *types.Scope) []string {
+	m := enc.scopeNamesMemo
+	if m == nil {
+		m = make(map[*types.Scope][]string)
+		enc.scopeNamesMemo = m
+	}
+	names, ok := m[scope]
+	if !ok {
+		names = scope.Names() // allocates and sorts
+		m[scope] = names
+	}
+	return names
+}
+
+// namedMethods is a memoization of the namedMethods function. Callers must not modify the result.
+func (enc *encoder) namedMethods(named *types.Named) []*types.Func {
+	m := enc.namedMethodsMemo
+	if m == nil {
+		m = make(map[*types.Named][]*types.Func)
+		enc.namedMethodsMemo = m
+	}
+	methods, ok := m[named]
+	if !ok {
+		methods = namedMethods(named) // allocates and sorts
+		m[named] = methods
+	}
+	return methods
+
+}
diff --git a/vendor/golang.org/x/tools/internal/diff/diff.go b/vendor/golang.org/x/tools/internal/diff/diff.go
new file mode 100644
index 0000000..2bc63c2
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/diff/diff.go
@@ -0,0 +1,169 @@
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package diff computes differences between text files or strings.
+package diff
+
+import (
+	"fmt"
+	"sort"
+	"strings"
+)
+
+// An Edit describes the replacement of a portion of a text file.
+type Edit struct {
+	Start, End int    // byte offsets of the region to replace
+	New        string // the replacement
+}
+
+func (e Edit) String() string {
+	return fmt.Sprintf("{Start:%d,End:%d,New:%s}", e.Start, e.End, e.New)
+}
+
+// Apply applies a sequence of edits to the src buffer and returns the
+// result. Edits are applied in order of start offset; edits with the
+// same start offset are applied in they order they were provided.
+//
+// Apply returns an error if any edit is out of bounds,
+// or if any pair of edits is overlapping.
+func Apply(src string, edits []Edit) (string, error) {
+	edits, size, err := validate(src, edits)
+	if err != nil {
+		return "", err
+	}
+
+	// Apply edits.
+	out := make([]byte, 0, size)
+	lastEnd := 0
+	for _, edit := range edits {
+		if lastEnd < edit.Start {
+			out = append(out, src[lastEnd:edit.Start]...)
+		}
+		out = append(out, edit.New...)
+		lastEnd = edit.End
+	}
+	out = append(out, src[lastEnd:]...)
+
+	if len(out) != size {
+		panic("wrong size")
+	}
+
+	return string(out), nil
+}
+
+// ApplyBytes is like Apply, but it accepts a byte slice.
+// The result is always a new array.
+func ApplyBytes(src []byte, edits []Edit) ([]byte, error) {
+	res, err := Apply(string(src), edits)
+	return []byte(res), err
+}
+
+// validate checks that edits are consistent with src,
+// and returns the size of the patched output.
+// It may return a different slice.
+func validate(src string, edits []Edit) ([]Edit, int, error) {
+	if !sort.IsSorted(editsSort(edits)) {
+		edits = append([]Edit(nil), edits...)
+		SortEdits(edits)
+	}
+
+	// Check validity of edits and compute final size.
+	size := len(src)
+	lastEnd := 0
+	for _, edit := range edits {
+		if !(0 <= edit.Start && edit.Start <= edit.End && edit.End <= len(src)) {
+			return nil, 0, fmt.Errorf("diff has out-of-bounds edits")
+		}
+		if edit.Start < lastEnd {
+			return nil, 0, fmt.Errorf("diff has overlapping edits")
+		}
+		size += len(edit.New) + edit.Start - edit.End
+		lastEnd = edit.End
+	}
+
+	return edits, size, nil
+}
+
+// SortEdits orders a slice of Edits by (start, end) offset.
+// This ordering puts insertions (end = start) before deletions
+// (end > start) at the same point, but uses a stable sort to preserve
+// the order of multiple insertions at the same point.
+// (Apply detects multiple deletions at the same point as an error.)
+func SortEdits(edits []Edit) {
+	sort.Stable(editsSort(edits))
+}
+
+type editsSort []Edit
+
+func (a editsSort) Len() int { return len(a) }
+func (a editsSort) Less(i, j int) bool {
+	if cmp := a[i].Start - a[j].Start; cmp != 0 {
+		return cmp < 0
+	}
+	return a[i].End < a[j].End
+}
+func (a editsSort) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
+
+// lineEdits expands and merges a sequence of edits so that each
+// resulting edit replaces one or more complete lines.
+// See ApplyEdits for preconditions.
+func lineEdits(src string, edits []Edit) ([]Edit, error) {
+	edits, _, err := validate(src, edits)
+	if err != nil {
+		return nil, err
+	}
+
+	// Do all edits begin and end at the start of a line?
+	// TODO(adonovan): opt: is this fast path necessary?
+	// (Also, it complicates the result ownership.)
+	for _, edit := range edits {
+		if edit.Start >= len(src) || // insertion at EOF
+			edit.Start > 0 && src[edit.Start-1] != '\n' || // not at line start
+			edit.End > 0 && src[edit.End-1] != '\n' { // not at line start
+			goto expand
+		}
+	}
+	return edits, nil // aligned
+
+expand:
+	expanded := make([]Edit, 0, len(edits)) // a guess
+	prev := edits[0]
+	// TODO(adonovan): opt: start from the first misaligned edit.
+	// TODO(adonovan): opt: avoid quadratic cost of string += string.
+	for _, edit := range edits[1:] {
+		between := src[prev.End:edit.Start]
+		if !strings.Contains(between, "\n") {
+			// overlapping lines: combine with previous edit.
+			prev.New += between + edit.New
+			prev.End = edit.End
+		} else {
+			// non-overlapping lines: flush previous edit.
+			expanded = append(expanded, expandEdit(prev, src))
+			prev = edit
+		}
+	}
+	return append(expanded, expandEdit(prev, src)), nil // flush final edit
+}
+
+// expandEdit returns edit expanded to complete whole lines.
+func expandEdit(edit Edit, src string) Edit {
+	// Expand start left to start of line.
+	// (delta is the zero-based column number of of start.)
+	start := edit.Start
+	if delta := start - 1 - strings.LastIndex(src[:start], "\n"); delta > 0 {
+		edit.Start -= delta
+		edit.New = src[start-delta:start] + edit.New
+	}
+
+	// Expand end right to end of line.
+	end := edit.End
+	if nl := strings.IndexByte(src[end:], '\n'); nl < 0 {
+		edit.End = len(src) // extend to EOF
+	} else {
+		edit.End = end + nl + 1 // extend beyond \n
+	}
+	edit.New += src[end:edit.End]
+
+	return edit
+}
diff --git a/vendor/golang.org/x/tools/internal/diff/lcs/common.go b/vendor/golang.org/x/tools/internal/diff/lcs/common.go
new file mode 100644
index 0000000..c3e82dd
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/diff/lcs/common.go
@@ -0,0 +1,179 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package lcs
+
+import (
+	"log"
+	"sort"
+)
+
+// lcs is a longest common sequence
+type lcs []diag
+
+// A diag is a piece of the edit graph where A[X+i] == B[Y+i], for 0<=i<Len.
+// All computed diagonals are parts of a longest common subsequence.
+type diag struct {
+	X, Y int
+	Len  int
+}
+
+// sort sorts in place, by lowest X, and if tied, inversely by Len
+func (l lcs) sort() lcs {
+	sort.Slice(l, func(i, j int) bool {
+		if l[i].X != l[j].X {
+			return l[i].X < l[j].X
+		}
+		return l[i].Len > l[j].Len
+	})
+	return l
+}
+
+// validate that the elements of the lcs do not overlap
+// (can only happen when the two-sided algorithm ends early)
+// expects the lcs to be sorted
+func (l lcs) valid() bool {
+	for i := 1; i < len(l); i++ {
+		if l[i-1].X+l[i-1].Len > l[i].X {
+			return false
+		}
+		if l[i-1].Y+l[i-1].Len > l[i].Y {
+			return false
+		}
+	}
+	return true
+}
+
+// repair overlapping lcs
+// only called if two-sided stops early
+func (l lcs) fix() lcs {
+	// from the set of diagonals in l, find a maximal non-conflicting set
+	// this problem may be NP-complete, but we use a greedy heuristic,
+	// which is quadratic, but with a better data structure, could be D log D.
+	// indepedent is not enough: {0,3,1} and {3,0,2} can't both occur in an lcs
+	// which has to have monotone x and y
+	if len(l) == 0 {
+		return nil
+	}
+	sort.Slice(l, func(i, j int) bool { return l[i].Len > l[j].Len })
+	tmp := make(lcs, 0, len(l))
+	tmp = append(tmp, l[0])
+	for i := 1; i < len(l); i++ {
+		var dir direction
+		nxt := l[i]
+		for _, in := range tmp {
+			if dir, nxt = overlap(in, nxt); dir == empty || dir == bad {
+				break
+			}
+		}
+		if nxt.Len > 0 && dir != bad {
+			tmp = append(tmp, nxt)
+		}
+	}
+	tmp.sort()
+	if false && !tmp.valid() { // debug checking
+		log.Fatalf("here %d", len(tmp))
+	}
+	return tmp
+}
+
+type direction int
+
+const (
+	empty    direction = iota // diag is empty (so not in lcs)
+	leftdown                  // proposed acceptably to the left and below
+	rightup                   // proposed diag is acceptably to the right and above
+	bad                       // proposed diag is inconsistent with the lcs so far
+)
+
+// overlap trims the proposed diag prop  so it doesn't overlap with
+// the existing diag that has already been added to the lcs.
+func overlap(exist, prop diag) (direction, diag) {
+	if prop.X <= exist.X && exist.X < prop.X+prop.Len {
+		// remove the end of prop where it overlaps with the X end of exist
+		delta := prop.X + prop.Len - exist.X
+		prop.Len -= delta
+		if prop.Len <= 0 {
+			return empty, prop
+		}
+	}
+	if exist.X <= prop.X && prop.X < exist.X+exist.Len {
+		// remove the beginning of prop where overlaps with exist
+		delta := exist.X + exist.Len - prop.X
+		prop.Len -= delta
+		if prop.Len <= 0 {
+			return empty, prop
+		}
+		prop.X += delta
+		prop.Y += delta
+	}
+	if prop.Y <= exist.Y && exist.Y < prop.Y+prop.Len {
+		// remove the end of prop that overlaps (in Y) with exist
+		delta := prop.Y + prop.Len - exist.Y
+		prop.Len -= delta
+		if prop.Len <= 0 {
+			return empty, prop
+		}
+	}
+	if exist.Y <= prop.Y && prop.Y < exist.Y+exist.Len {
+		// remove the beginning of peop that overlaps with exist
+		delta := exist.Y + exist.Len - prop.Y
+		prop.Len -= delta
+		if prop.Len <= 0 {
+			return empty, prop
+		}
+		prop.X += delta // no test reaches this code
+		prop.Y += delta
+	}
+	if prop.X+prop.Len <= exist.X && prop.Y+prop.Len <= exist.Y {
+		return leftdown, prop
+	}
+	if exist.X+exist.Len <= prop.X && exist.Y+exist.Len <= prop.Y {
+		return rightup, prop
+	}
+	// prop can't be in an lcs that contains exist
+	return bad, prop
+}
+
+// manipulating Diag and lcs
+
+// prepend a diagonal (x,y)-(x+1,y+1) segment either to an empty lcs
+// or to its first Diag. prepend is only called to extend diagonals
+// the backward direction.
+func (lcs lcs) prepend(x, y int) lcs {
+	if len(lcs) > 0 {
+		d := &lcs[0]
+		if int(d.X) == x+1 && int(d.Y) == y+1 {
+			// extend the diagonal down and to the left
+			d.X, d.Y = int(x), int(y)
+			d.Len++
+			return lcs
+		}
+	}
+
+	r := diag{X: int(x), Y: int(y), Len: 1}
+	lcs = append([]diag{r}, lcs...)
+	return lcs
+}
+
+// append appends a diagonal, or extends the existing one.
+// by adding the edge (x,y)-(x+1.y+1). append is only called
+// to extend diagonals in the forward direction.
+func (lcs lcs) append(x, y int) lcs {
+	if len(lcs) > 0 {
+		last := &lcs[len(lcs)-1]
+		// Expand last element if adjoining.
+		if last.X+last.Len == x && last.Y+last.Len == y {
+			last.Len++
+			return lcs
+		}
+	}
+
+	return append(lcs, diag{X: x, Y: y, Len: 1})
+}
+
+// enforce constraint on d, k
+func ok(d, k int) bool {
+	return d >= 0 && -d <= k && k <= d
+}
diff --git a/vendor/golang.org/x/tools/internal/diff/lcs/doc.go b/vendor/golang.org/x/tools/internal/diff/lcs/doc.go
new file mode 100644
index 0000000..dc779f3
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/diff/lcs/doc.go
@@ -0,0 +1,156 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// package lcs contains code to find longest-common-subsequences
+// (and diffs)
+package lcs
+
+/*
+Compute longest-common-subsequences of two slices A, B using
+algorithms from Myers' paper. A longest-common-subsequence
+(LCS from now on) of A and B is a maximal set of lexically increasing
+pairs of subscripts (x,y) with A[x]==B[y]. There may be many LCS, but
+they all have the same length. An LCS determines a sequence of edits
+that changes A into B.
+
+The key concept is the edit graph of A and B.
+If A has length N and B has length M, then the edit graph has
+vertices v[i][j] for 0 <= i <= N, 0 <= j <= M. There is a
+horizontal edge from v[i][j] to v[i+1][j] whenever both are in
+the graph, and a vertical edge from v[i][j] to f[i][j+1] similarly.
+When A[i] == B[j] there is a diagonal edge from v[i][j] to v[i+1][j+1].
+
+A path between in the graph between (0,0) and (N,M) determines a sequence
+of edits converting A into B: each horizontal edge corresponds to removing
+an element of A, and each vertical edge corresponds to inserting an
+element of B.
+
+A vertex (x,y) is on (forward) diagonal k if x-y=k. A path in the graph
+is of length D if it has D non-diagonal edges. The algorithms generate
+forward paths (in which at least one of x,y increases at each edge),
+or backward paths (in which at least one of x,y decreases at each edge),
+or a combination. (Note that the orientation is the traditional mathematical one,
+with the origin in the lower-left corner.)
+
+Here is the edit graph for A:"aabbaa", B:"aacaba". (I know the diagonals look weird.)
+          ⊙   -------   ⊙   -------   ⊙   -------   ⊙   -------   ⊙   -------   ⊙   -------   ⊙
+   a      |   ___/‾‾‾   |   ___/‾‾‾   |             |             |   ___/‾‾‾   |   ___/‾‾‾   |
+          ⊙   -------   ⊙   -------   ⊙   -------   ⊙   -------   ⊙   -------   ⊙   -------   ⊙
+   b      |             |             |   ___/‾‾‾   |   ___/‾‾‾   |             |             |
+          ⊙   -------   ⊙   -------   ⊙   -------   ⊙   -------   ⊙   -------   ⊙   -------   ⊙
+   a      |   ___/‾‾‾   |   ___/‾‾‾   |             |             |   ___/‾‾‾   |   ___/‾‾‾   |
+          ⊙   -------   ⊙   -------   ⊙   -------   ⊙   -------   ⊙   -------   ⊙   -------   ⊙
+   c      |             |             |             |             |             |             |
+          ⊙   -------   ⊙   -------   ⊙   -------   ⊙   -------   ⊙   -------   ⊙   -------   ⊙
+   a      |   ___/‾‾‾   |   ___/‾‾‾   |             |             |   ___/‾‾‾   |   ___/‾‾‾   |
+          ⊙   -------   ⊙   -------   ⊙   -------   ⊙   -------   ⊙   -------   ⊙   -------   ⊙
+   a      |   ___/‾‾‾   |   ___/‾‾‾   |             |             |   ___/‾‾‾   |   ___/‾‾‾   |
+          ⊙   -------   ⊙   -------   ⊙   -------   ⊙   -------   ⊙   -------   ⊙   -------   ⊙
+                 a             a             b             b             a             a
+
+
+The algorithm labels a vertex (x,y) with D,k if it is on diagonal k and at
+the end of a maximal path of length D. (Because x-y=k it suffices to remember
+only the x coordinate of the vertex.)
+
+The forward algorithm: Find the longest diagonal starting at (0,0) and
+label its end with D=0,k=0. From that vertex take a vertical step and
+then follow the longest diagonal (up and to the right), and label that vertex
+with D=1,k=-1. From the D=0,k=0 point take a horizontal step and the follow
+the longest diagonal (up and to the right) and label that vertex
+D=1,k=1. In the same way, having labelled all the D vertices,
+from a vertex labelled D,k find two vertices
+tentatively labelled D+1,k-1 and D+1,k+1. There may be two on the same
+diagonal, in which case take the one with the larger x.
+
+Eventually the path gets to (N,M), and the diagonals on it are the LCS.
+
+Here is the edit graph with the ends of D-paths labelled. (So, for instance,
+0/2,2 indicates that x=2,y=2 is labelled with 0, as it should be, since the first
+step is to go up the longest diagonal from (0,0).)
+A:"aabbaa", B:"aacaba"
+          ⊙   -------   ⊙   -------   ⊙   -------(3/3,6)-------   ⊙   -------(3/5,6)-------(4/6,6)
+   a      |   ___/‾‾‾   |   ___/‾‾‾   |             |             |   ___/‾‾‾   |   ___/‾‾‾   |
+          ⊙   -------   ⊙   -------   ⊙   -------(2/3,5)-------   ⊙   -------   ⊙   -------   ⊙
+   b      |             |             |   ___/‾‾‾   |   ___/‾‾‾   |             |             |
+          ⊙   -------   ⊙   -------   ⊙   -------   ⊙   -------   ⊙   -------(3/5,4)-------   ⊙
+   a      |   ___/‾‾‾   |   ___/‾‾‾   |             |             |   ___/‾‾‾   |   ___/‾‾‾   |
+          ⊙   -------   ⊙   -------(1/2,3)-------(2/3,3)-------   ⊙   -------   ⊙   -------   ⊙
+   c      |             |             |             |             |             |             |
+          ⊙   -------   ⊙   -------(0/2,2)-------(1/3,2)-------(2/4,2)-------(3/5,2)-------(4/6,2)
+   a      |   ___/‾‾‾   |   ___/‾‾‾   |             |             |   ___/‾‾‾   |   ___/‾‾‾   |
+          ⊙   -------   ⊙   -------   ⊙   -------   ⊙   -------   ⊙   -------   ⊙   -------   ⊙
+   a      |   ___/‾‾‾   |   ___/‾‾‾   |             |             |   ___/‾‾‾   |   ___/‾‾‾   |
+          ⊙   -------   ⊙   -------   ⊙   -------   ⊙   -------   ⊙   -------   ⊙   -------   ⊙
+                 a             a             b             b             a             a
+
+The 4-path is reconstructed starting at (4/6,6), horizontal to (3/5,6), diagonal to (3,4), vertical
+to (2/3,3), horizontal to (1/2,3), vertical to (0/2,2), and diagonal to (0,0). As expected,
+there are 4 non-diagonal steps, and the diagonals form an LCS.
+
+There is a symmetric backward algorithm, which gives (backwards labels are prefixed with a colon):
+A:"aabbaa", B:"aacaba"
+            ⊙   --------    ⊙   --------    ⊙   --------    ⊙   --------    ⊙   --------    ⊙   --------    ⊙
+    a       |   ____/‾‾‾    |   ____/‾‾‾    |               |               |   ____/‾‾‾    |   ____/‾‾‾    |
+            ⊙   --------    ⊙   --------    ⊙   --------    ⊙   --------    ⊙   --------(:0/5,5)--------    ⊙
+    b       |               |               |   ____/‾‾‾    |   ____/‾‾‾    |               |               |
+            ⊙   --------    ⊙   --------    ⊙   --------(:1/3,4)--------    ⊙   --------    ⊙   --------    ⊙
+    a       |   ____/‾‾‾    |   ____/‾‾‾    |               |               |   ____/‾‾‾    |   ____/‾‾‾    |
+        (:3/0,3)--------(:2/1,3)--------    ⊙   --------(:2/3,3)--------(:1/4,3)--------    ⊙   --------    ⊙
+    c       |               |               |               |               |               |               |
+            ⊙   --------    ⊙   --------    ⊙   --------(:3/3,2)--------(:2/4,2)--------    ⊙   --------    ⊙
+    a       |   ____/‾‾‾    |   ____/‾‾‾    |               |               |   ____/‾‾‾    |   ____/‾‾‾    |
+        (:3/0,1)--------    ⊙   --------    ⊙   --------    ⊙   --------(:3/4,1)--------    ⊙   --------    ⊙
+    a       |   ____/‾‾‾    |   ____/‾‾‾    |               |               |   ____/‾‾‾    |   ____/‾‾‾    |
+        (:4/0,0)--------    ⊙   --------    ⊙   --------    ⊙   --------(:4/4,0)--------    ⊙   --------    ⊙
+                    a               a               b               b               a               a
+
+Neither of these is ideal for use in an editor, where it is undesirable to send very long diffs to the
+front end. It's tricky to decide exactly what 'very long diffs' means, as "replace A by B" is very short.
+We want to control how big D can be, by stopping when it gets too large. The forward algorithm then
+privileges common prefixes, and the backward algorithm privileges common suffixes. Either is an undesirable
+asymmetry.
+
+Fortunately there is a two-sided algorithm, implied by results in Myers' paper. Here's what the labels in
+the edit graph look like.
+A:"aabbaa", B:"aacaba"
+             ⊙    ---------    ⊙    ---------    ⊙    ---------    ⊙    ---------    ⊙    ---------    ⊙    ---------    ⊙
+    a        |    ____/‾‾‾‾    |    ____/‾‾‾‾    |                 |                 |    ____/‾‾‾‾    |    ____/‾‾‾‾    |
+             ⊙    ---------    ⊙    ---------    ⊙    --------- (2/3,5) ---------    ⊙    --------- (:0/5,5)---------    ⊙
+    b        |                 |                 |    ____/‾‾‾‾    |    ____/‾‾‾‾    |                 |                 |
+             ⊙    ---------    ⊙    ---------    ⊙    --------- (:1/3,4)---------    ⊙    ---------    ⊙    ---------    ⊙
+    a        |    ____/‾‾‾‾    |    ____/‾‾‾‾    |                 |                 |    ____/‾‾‾‾    |    ____/‾‾‾‾    |
+             ⊙    --------- (:2/1,3)--------- (1/2,3) ---------(2:2/3,3)--------- (:1/4,3)---------    ⊙    ---------    ⊙
+    c        |                 |                 |                 |                 |                 |                 |
+             ⊙    ---------    ⊙    --------- (0/2,2) --------- (1/3,2) ---------(2:2/4,2)---------    ⊙    ---------    ⊙
+    a        |    ____/‾‾‾‾    |    ____/‾‾‾‾    |                 |                 |    ____/‾‾‾‾    |    ____/‾‾‾‾    |
+             ⊙    ---------    ⊙    ---------    ⊙    ---------    ⊙    ---------    ⊙    ---------    ⊙    ---------    ⊙
+    a        |    ____/‾‾‾‾    |    ____/‾‾‾‾    |                 |                 |    ____/‾‾‾‾    |    ____/‾‾‾‾    |
+             ⊙    ---------    ⊙    ---------    ⊙    ---------    ⊙    ---------    ⊙    ---------    ⊙    ---------    ⊙
+                      a                 a                 b                 b                 a                 a
+
+The algorithm stopped when it saw the backwards 2-path ending at (1,3) and the forwards 2-path ending at (3,5). The criterion
+is a backwards path ending at (u,v) and a forward path ending at (x,y), where u <= x and the two points are on the same
+diagonal. (Here the edgegraph has a diagonal, but the criterion is x-y=u-v.) Myers proves there is a forward
+2-path from (0,0) to (1,3), and that together with the backwards 2-path ending at (1,3) gives the expected 4-path.
+Unfortunately the forward path has to be constructed by another run of the forward algorithm; it can't be found from the
+computed labels. That is the worst case. Had the code noticed (x,y)=(u,v)=(3,3) the whole path could be reconstructed
+from the edgegraph. The implementation looks for a number of special cases to try to avoid computing an extra forward path.
+
+If the two-sided algorithm has stop early (because D has become too large) it will have found a forward LCS and a
+backwards LCS. Ideally these go with disjoint prefixes and suffixes of A and B, but disjointness may fail and the two
+computed LCS may conflict. (An easy example is where A is a suffix of B, and shares a short prefix. The backwards LCS
+is all of A, and the forward LCS is a prefix of A.) The algorithm combines the two
+to form a best-effort LCS. In the worst case the forward partial LCS may have to
+be recomputed.
+*/
+
+/* Eugene Myers paper is titled
+"An O(ND) Difference Algorithm and Its Variations"
+and can be found at
+http://www.xmailserver.org/diff2.pdf
+
+(There is a generic implementation of the algorithm the the repository with git hash
+b9ad7e4ade3a686d608e44475390ad428e60e7fc)
+*/
diff --git a/vendor/golang.org/x/tools/internal/diff/lcs/git.sh b/vendor/golang.org/x/tools/internal/diff/lcs/git.sh
new file mode 100644
index 0000000..6856f84
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/diff/lcs/git.sh
@@ -0,0 +1,33 @@
+#!/bin/bash
+#
+# Copyright 2022 The Go Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style
+# license that can be found in the LICENSE file.
+#
+# Creates a zip file containing all numbered versions
+# of the commit history of a large source file, for use
+# as input data for the tests of the diff algorithm.
+#
+# Run script from root of the x/tools repo.
+
+set -eu
+
+# WARNING: This script will install the latest version of $file
+# The largest real source file in the x/tools repo.
+# file=internal/lsp/source/completion/completion.go
+# file=internal/lsp/source/diagnostics.go
+file=internal/lsp/protocol/tsprotocol.go
+
+tmp=$(mktemp -d)
+git log $file |
+  awk '/^commit / {print $2}' |
+  nl -ba -nrz |
+  while read n hash; do
+    git checkout --quiet $hash $file
+    cp -f $file $tmp/$n
+  done
+(cd $tmp && zip -q - *) > testdata.zip
+rm -fr $tmp
+git restore --staged $file
+git restore $file
+echo "Created testdata.zip"
diff --git a/vendor/golang.org/x/tools/internal/diff/lcs/labels.go b/vendor/golang.org/x/tools/internal/diff/lcs/labels.go
new file mode 100644
index 0000000..0689f1e
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/diff/lcs/labels.go
@@ -0,0 +1,55 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package lcs
+
+import (
+	"fmt"
+)
+
+//  For each D, vec[D] has length D+1,
+// and the label for (D, k) is stored in vec[D][(D+k)/2].
+type label struct {
+	vec [][]int
+}
+
+// Temporary checking DO NOT COMMIT true TO PRODUCTION CODE
+const debug = false
+
+// debugging. check that the (d,k) pair is valid
+// (that is, -d<=k<=d and d+k even)
+func checkDK(D, k int) {
+	if k >= -D && k <= D && (D+k)%2 == 0 {
+		return
+	}
+	panic(fmt.Sprintf("out of range, d=%d,k=%d", D, k))
+}
+
+func (t *label) set(D, k, x int) {
+	if debug {
+		checkDK(D, k)
+	}
+	for len(t.vec) <= D {
+		t.vec = append(t.vec, nil)
+	}
+	if t.vec[D] == nil {
+		t.vec[D] = make([]int, D+1)
+	}
+	t.vec[D][(D+k)/2] = x // known that D+k is even
+}
+
+func (t *label) get(d, k int) int {
+	if debug {
+		checkDK(d, k)
+	}
+	return int(t.vec[d][(d+k)/2])
+}
+
+func newtriang(limit int) label {
+	if limit < 100 {
+		// Preallocate if limit is not large.
+		return label{vec: make([][]int, limit)}
+	}
+	return label{}
+}
diff --git a/vendor/golang.org/x/tools/internal/diff/lcs/old.go b/vendor/golang.org/x/tools/internal/diff/lcs/old.go
new file mode 100644
index 0000000..7af11fc
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/diff/lcs/old.go
@@ -0,0 +1,480 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package lcs
+
+// TODO(adonovan): remove unclear references to "old" in this package.
+
+import (
+	"fmt"
+)
+
+// A Diff is a replacement of a portion of A by a portion of B.
+type Diff struct {
+	Start, End         int // offsets of portion to delete in A
+	ReplStart, ReplEnd int // offset of replacement text in B
+}
+
+// DiffStrings returns the differences between two strings.
+// It does not respect rune boundaries.
+func DiffStrings(a, b string) []Diff { return diff(stringSeqs{a, b}) }
+
+// DiffBytes returns the differences between two byte sequences.
+// It does not respect rune boundaries.
+func DiffBytes(a, b []byte) []Diff { return diff(bytesSeqs{a, b}) }
+
+// DiffRunes returns the differences between two rune sequences.
+func DiffRunes(a, b []rune) []Diff { return diff(runesSeqs{a, b}) }
+
+func diff(seqs sequences) []Diff {
+	// A limit on how deeply the LCS algorithm should search. The value is just a guess.
+	const maxDiffs = 30
+	diff, _ := compute(seqs, twosided, maxDiffs/2)
+	return diff
+}
+
+// compute computes the list of differences between two sequences,
+// along with the LCS. It is exercised directly by tests.
+// The algorithm is one of {forward, backward, twosided}.
+func compute(seqs sequences, algo func(*editGraph) lcs, limit int) ([]Diff, lcs) {
+	if limit <= 0 {
+		limit = 1 << 25 // effectively infinity
+	}
+	alen, blen := seqs.lengths()
+	g := &editGraph{
+		seqs:  seqs,
+		vf:    newtriang(limit),
+		vb:    newtriang(limit),
+		limit: limit,
+		ux:    alen,
+		uy:    blen,
+		delta: alen - blen,
+	}
+	lcs := algo(g)
+	diffs := lcs.toDiffs(alen, blen)
+	return diffs, lcs
+}
+
+// editGraph carries the information for computing the lcs of two sequences.
+type editGraph struct {
+	seqs   sequences
+	vf, vb label // forward and backward labels
+
+	limit int // maximal value of D
+	// the bounding rectangle of the current edit graph
+	lx, ly, ux, uy int
+	delta          int // common subexpression: (ux-lx)-(uy-ly)
+}
+
+// toDiffs converts an LCS to a list of edits.
+func (lcs lcs) toDiffs(alen, blen int) []Diff {
+	var diffs []Diff
+	var pa, pb int // offsets in a, b
+	for _, l := range lcs {
+		if pa < l.X || pb < l.Y {
+			diffs = append(diffs, Diff{pa, l.X, pb, l.Y})
+		}
+		pa = l.X + l.Len
+		pb = l.Y + l.Len
+	}
+	if pa < alen || pb < blen {
+		diffs = append(diffs, Diff{pa, alen, pb, blen})
+	}
+	return diffs
+}
+
+// --- FORWARD ---
+
+// fdone decides if the forwward path has reached the upper right
+// corner of the rectangle. If so, it also returns the computed lcs.
+func (e *editGraph) fdone(D, k int) (bool, lcs) {
+	// x, y, k are relative to the rectangle
+	x := e.vf.get(D, k)
+	y := x - k
+	if x == e.ux && y == e.uy {
+		return true, e.forwardlcs(D, k)
+	}
+	return false, nil
+}
+
+// run the forward algorithm, until success or up to the limit on D.
+func forward(e *editGraph) lcs {
+	e.setForward(0, 0, e.lx)
+	if ok, ans := e.fdone(0, 0); ok {
+		return ans
+	}
+	// from D to D+1
+	for D := 0; D < e.limit; D++ {
+		e.setForward(D+1, -(D + 1), e.getForward(D, -D))
+		if ok, ans := e.fdone(D+1, -(D + 1)); ok {
+			return ans
+		}
+		e.setForward(D+1, D+1, e.getForward(D, D)+1)
+		if ok, ans := e.fdone(D+1, D+1); ok {
+			return ans
+		}
+		for k := -D + 1; k <= D-1; k += 2 {
+			// these are tricky and easy to get backwards
+			lookv := e.lookForward(k, e.getForward(D, k-1)+1)
+			lookh := e.lookForward(k, e.getForward(D, k+1))
+			if lookv > lookh {
+				e.setForward(D+1, k, lookv)
+			} else {
+				e.setForward(D+1, k, lookh)
+			}
+			if ok, ans := e.fdone(D+1, k); ok {
+				return ans
+			}
+		}
+	}
+	// D is too large
+	// find the D path with maximal x+y inside the rectangle and
+	// use that to compute the found part of the lcs
+	kmax := -e.limit - 1
+	diagmax := -1
+	for k := -e.limit; k <= e.limit; k += 2 {
+		x := e.getForward(e.limit, k)
+		y := x - k
+		if x+y > diagmax && x <= e.ux && y <= e.uy {
+			diagmax, kmax = x+y, k
+		}
+	}
+	return e.forwardlcs(e.limit, kmax)
+}
+
+// recover the lcs by backtracking from the farthest point reached
+func (e *editGraph) forwardlcs(D, k int) lcs {
+	var ans lcs
+	for x := e.getForward(D, k); x != 0 || x-k != 0; {
+		if ok(D-1, k-1) && x-1 == e.getForward(D-1, k-1) {
+			// if (x-1,y) is labelled D-1, x--,D--,k--,continue
+			D, k, x = D-1, k-1, x-1
+			continue
+		} else if ok(D-1, k+1) && x == e.getForward(D-1, k+1) {
+			// if (x,y-1) is labelled D-1, x, D--,k++, continue
+			D, k = D-1, k+1
+			continue
+		}
+		// if (x-1,y-1)--(x,y) is a diagonal, prepend,x--,y--, continue
+		y := x - k
+		ans = ans.prepend(x+e.lx-1, y+e.ly-1)
+		x--
+	}
+	return ans
+}
+
+// start at (x,y), go up the diagonal as far as possible,
+// and label the result with d
+func (e *editGraph) lookForward(k, relx int) int {
+	rely := relx - k
+	x, y := relx+e.lx, rely+e.ly
+	if x < e.ux && y < e.uy {
+		x += e.seqs.commonPrefixLen(x, e.ux, y, e.uy)
+	}
+	return x
+}
+
+func (e *editGraph) setForward(d, k, relx int) {
+	x := e.lookForward(k, relx)
+	e.vf.set(d, k, x-e.lx)
+}
+
+func (e *editGraph) getForward(d, k int) int {
+	x := e.vf.get(d, k)
+	return x
+}
+
+// --- BACKWARD ---
+
+// bdone decides if the backward path has reached the lower left corner
+func (e *editGraph) bdone(D, k int) (bool, lcs) {
+	// x, y, k are relative to the rectangle
+	x := e.vb.get(D, k)
+	y := x - (k + e.delta)
+	if x == 0 && y == 0 {
+		return true, e.backwardlcs(D, k)
+	}
+	return false, nil
+}
+
+// run the backward algorithm, until success or up to the limit on D.
+func backward(e *editGraph) lcs {
+	e.setBackward(0, 0, e.ux)
+	if ok, ans := e.bdone(0, 0); ok {
+		return ans
+	}
+	// from D to D+1
+	for D := 0; D < e.limit; D++ {
+		e.setBackward(D+1, -(D + 1), e.getBackward(D, -D)-1)
+		if ok, ans := e.bdone(D+1, -(D + 1)); ok {
+			return ans
+		}
+		e.setBackward(D+1, D+1, e.getBackward(D, D))
+		if ok, ans := e.bdone(D+1, D+1); ok {
+			return ans
+		}
+		for k := -D + 1; k <= D-1; k += 2 {
+			// these are tricky and easy to get wrong
+			lookv := e.lookBackward(k, e.getBackward(D, k-1))
+			lookh := e.lookBackward(k, e.getBackward(D, k+1)-1)
+			if lookv < lookh {
+				e.setBackward(D+1, k, lookv)
+			} else {
+				e.setBackward(D+1, k, lookh)
+			}
+			if ok, ans := e.bdone(D+1, k); ok {
+				return ans
+			}
+		}
+	}
+
+	// D is too large
+	// find the D path with minimal x+y inside the rectangle and
+	// use that to compute the part of the lcs found
+	kmax := -e.limit - 1
+	diagmin := 1 << 25
+	for k := -e.limit; k <= e.limit; k += 2 {
+		x := e.getBackward(e.limit, k)
+		y := x - (k + e.delta)
+		if x+y < diagmin && x >= 0 && y >= 0 {
+			diagmin, kmax = x+y, k
+		}
+	}
+	if kmax < -e.limit {
+		panic(fmt.Sprintf("no paths when limit=%d?", e.limit))
+	}
+	return e.backwardlcs(e.limit, kmax)
+}
+
+// recover the lcs by backtracking
+func (e *editGraph) backwardlcs(D, k int) lcs {
+	var ans lcs
+	for x := e.getBackward(D, k); x != e.ux || x-(k+e.delta) != e.uy; {
+		if ok(D-1, k-1) && x == e.getBackward(D-1, k-1) {
+			// D--, k--, x unchanged
+			D, k = D-1, k-1
+			continue
+		} else if ok(D-1, k+1) && x+1 == e.getBackward(D-1, k+1) {
+			// D--, k++, x++
+			D, k, x = D-1, k+1, x+1
+			continue
+		}
+		y := x - (k + e.delta)
+		ans = ans.append(x+e.lx, y+e.ly)
+		x++
+	}
+	return ans
+}
+
+// start at (x,y), go down the diagonal as far as possible,
+func (e *editGraph) lookBackward(k, relx int) int {
+	rely := relx - (k + e.delta) // forward k = k + e.delta
+	x, y := relx+e.lx, rely+e.ly
+	if x > 0 && y > 0 {
+		x -= e.seqs.commonSuffixLen(0, x, 0, y)
+	}
+	return x
+}
+
+// convert to rectangle, and label the result with d
+func (e *editGraph) setBackward(d, k, relx int) {
+	x := e.lookBackward(k, relx)
+	e.vb.set(d, k, x-e.lx)
+}
+
+func (e *editGraph) getBackward(d, k int) int {
+	x := e.vb.get(d, k)
+	return x
+}
+
+// -- TWOSIDED ---
+
+func twosided(e *editGraph) lcs {
+	// The termination condition could be improved, as either the forward
+	// or backward pass could succeed before Myers' Lemma applies.
+	// Aside from questions of efficiency (is the extra testing cost-effective)
+	// this is more likely to matter when e.limit is reached.
+	e.setForward(0, 0, e.lx)
+	e.setBackward(0, 0, e.ux)
+
+	// from D to D+1
+	for D := 0; D < e.limit; D++ {
+		// just finished a backwards pass, so check
+		if got, ok := e.twoDone(D, D); ok {
+			return e.twolcs(D, D, got)
+		}
+		// do a forwards pass (D to D+1)
+		e.setForward(D+1, -(D + 1), e.getForward(D, -D))
+		e.setForward(D+1, D+1, e.getForward(D, D)+1)
+		for k := -D + 1; k <= D-1; k += 2 {
+			// these are tricky and easy to get backwards
+			lookv := e.lookForward(k, e.getForward(D, k-1)+1)
+			lookh := e.lookForward(k, e.getForward(D, k+1))
+			if lookv > lookh {
+				e.setForward(D+1, k, lookv)
+			} else {
+				e.setForward(D+1, k, lookh)
+			}
+		}
+		// just did a forward pass, so check
+		if got, ok := e.twoDone(D+1, D); ok {
+			return e.twolcs(D+1, D, got)
+		}
+		// do a backward pass, D to D+1
+		e.setBackward(D+1, -(D + 1), e.getBackward(D, -D)-1)
+		e.setBackward(D+1, D+1, e.getBackward(D, D))
+		for k := -D + 1; k <= D-1; k += 2 {
+			// these are tricky and easy to get wrong
+			lookv := e.lookBackward(k, e.getBackward(D, k-1))
+			lookh := e.lookBackward(k, e.getBackward(D, k+1)-1)
+			if lookv < lookh {
+				e.setBackward(D+1, k, lookv)
+			} else {
+				e.setBackward(D+1, k, lookh)
+			}
+		}
+	}
+
+	// D too large. combine a forward and backward partial lcs
+	// first, a forward one
+	kmax := -e.limit - 1
+	diagmax := -1
+	for k := -e.limit; k <= e.limit; k += 2 {
+		x := e.getForward(e.limit, k)
+		y := x - k
+		if x+y > diagmax && x <= e.ux && y <= e.uy {
+			diagmax, kmax = x+y, k
+		}
+	}
+	if kmax < -e.limit {
+		panic(fmt.Sprintf("no forward paths when limit=%d?", e.limit))
+	}
+	lcs := e.forwardlcs(e.limit, kmax)
+	// now a backward one
+	// find the D path with minimal x+y inside the rectangle and
+	// use that to compute the lcs
+	diagmin := 1 << 25 // infinity
+	for k := -e.limit; k <= e.limit; k += 2 {
+		x := e.getBackward(e.limit, k)
+		y := x - (k + e.delta)
+		if x+y < diagmin && x >= 0 && y >= 0 {
+			diagmin, kmax = x+y, k
+		}
+	}
+	if kmax < -e.limit {
+		panic(fmt.Sprintf("no backward paths when limit=%d?", e.limit))
+	}
+	lcs = append(lcs, e.backwardlcs(e.limit, kmax)...)
+	// These may overlap (e.forwardlcs and e.backwardlcs return sorted lcs)
+	ans := lcs.fix()
+	return ans
+}
+
+// Does Myers' Lemma apply?
+func (e *editGraph) twoDone(df, db int) (int, bool) {
+	if (df+db+e.delta)%2 != 0 {
+		return 0, false // diagonals cannot overlap
+	}
+	kmin := -db + e.delta
+	if -df > kmin {
+		kmin = -df
+	}
+	kmax := db + e.delta
+	if df < kmax {
+		kmax = df
+	}
+	for k := kmin; k <= kmax; k += 2 {
+		x := e.vf.get(df, k)
+		u := e.vb.get(db, k-e.delta)
+		if u <= x {
+			// is it worth looking at all the other k?
+			for l := k; l <= kmax; l += 2 {
+				x := e.vf.get(df, l)
+				y := x - l
+				u := e.vb.get(db, l-e.delta)
+				v := u - l
+				if x == u || u == 0 || v == 0 || y == e.uy || x == e.ux {
+					return l, true
+				}
+			}
+			return k, true
+		}
+	}
+	return 0, false
+}
+
+func (e *editGraph) twolcs(df, db, kf int) lcs {
+	// db==df || db+1==df
+	x := e.vf.get(df, kf)
+	y := x - kf
+	kb := kf - e.delta
+	u := e.vb.get(db, kb)
+	v := u - kf
+
+	// Myers proved there is a df-path from (0,0) to (u,v)
+	// and a db-path from (x,y) to (N,M).
+	// In the first case the overall path is the forward path
+	// to (u,v) followed by the backward path to (N,M).
+	// In the second case the path is the backward path to (x,y)
+	// followed by the forward path to (x,y) from (0,0).
+
+	// Look for some special cases to avoid computing either of these paths.
+	if x == u {
+		// "babaab" "cccaba"
+		// already patched together
+		lcs := e.forwardlcs(df, kf)
+		lcs = append(lcs, e.backwardlcs(db, kb)...)
+		return lcs.sort()
+	}
+
+	// is (u-1,v) or (u,v-1) labelled df-1?
+	// if so, that forward df-1-path plus a horizontal or vertical edge
+	// is the df-path to (u,v), then plus the db-path to (N,M)
+	if u > 0 && ok(df-1, u-1-v) && e.vf.get(df-1, u-1-v) == u-1 {
+		//  "aabbab" "cbcabc"
+		lcs := e.forwardlcs(df-1, u-1-v)
+		lcs = append(lcs, e.backwardlcs(db, kb)...)
+		return lcs.sort()
+	}
+	if v > 0 && ok(df-1, (u-(v-1))) && e.vf.get(df-1, u-(v-1)) == u {
+		//  "abaabb" "bcacab"
+		lcs := e.forwardlcs(df-1, u-(v-1))
+		lcs = append(lcs, e.backwardlcs(db, kb)...)
+		return lcs.sort()
+	}
+
+	// The path can't possibly contribute to the lcs because it
+	// is all horizontal or vertical edges
+	if u == 0 || v == 0 || x == e.ux || y == e.uy {
+		// "abaabb" "abaaaa"
+		if u == 0 || v == 0 {
+			return e.backwardlcs(db, kb)
+		}
+		return e.forwardlcs(df, kf)
+	}
+
+	// is (x+1,y) or (x,y+1) labelled db-1?
+	if x+1 <= e.ux && ok(db-1, x+1-y-e.delta) && e.vb.get(db-1, x+1-y-e.delta) == x+1 {
+		// "bababb" "baaabb"
+		lcs := e.backwardlcs(db-1, kb+1)
+		lcs = append(lcs, e.forwardlcs(df, kf)...)
+		return lcs.sort()
+	}
+	if y+1 <= e.uy && ok(db-1, x-(y+1)-e.delta) && e.vb.get(db-1, x-(y+1)-e.delta) == x {
+		// "abbbaa" "cabacc"
+		lcs := e.backwardlcs(db-1, kb-1)
+		lcs = append(lcs, e.forwardlcs(df, kf)...)
+		return lcs.sort()
+	}
+
+	// need to compute another path
+	// "aabbaa" "aacaba"
+	lcs := e.backwardlcs(db, kb)
+	oldx, oldy := e.ux, e.uy
+	e.ux = u
+	e.uy = v
+	lcs = append(lcs, forward(e)...)
+	e.ux, e.uy = oldx, oldy
+	return lcs.sort()
+}
diff --git a/vendor/golang.org/x/tools/internal/diff/lcs/sequence.go b/vendor/golang.org/x/tools/internal/diff/lcs/sequence.go
new file mode 100644
index 0000000..2d72d26
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/diff/lcs/sequence.go
@@ -0,0 +1,113 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package lcs
+
+// This file defines the abstract sequence over which the LCS algorithm operates.
+
+// sequences abstracts a pair of sequences, A and B.
+type sequences interface {
+	lengths() (int, int)                    // len(A), len(B)
+	commonPrefixLen(ai, aj, bi, bj int) int // len(commonPrefix(A[ai:aj], B[bi:bj]))
+	commonSuffixLen(ai, aj, bi, bj int) int // len(commonSuffix(A[ai:aj], B[bi:bj]))
+}
+
+type stringSeqs struct{ a, b string }
+
+func (s stringSeqs) lengths() (int, int) { return len(s.a), len(s.b) }
+func (s stringSeqs) commonPrefixLen(ai, aj, bi, bj int) int {
+	return commonPrefixLenString(s.a[ai:aj], s.b[bi:bj])
+}
+func (s stringSeqs) commonSuffixLen(ai, aj, bi, bj int) int {
+	return commonSuffixLenString(s.a[ai:aj], s.b[bi:bj])
+}
+
+// The explicit capacity in s[i:j:j] leads to more efficient code.
+
+type bytesSeqs struct{ a, b []byte }
+
+func (s bytesSeqs) lengths() (int, int) { return len(s.a), len(s.b) }
+func (s bytesSeqs) commonPrefixLen(ai, aj, bi, bj int) int {
+	return commonPrefixLenBytes(s.a[ai:aj:aj], s.b[bi:bj:bj])
+}
+func (s bytesSeqs) commonSuffixLen(ai, aj, bi, bj int) int {
+	return commonSuffixLenBytes(s.a[ai:aj:aj], s.b[bi:bj:bj])
+}
+
+type runesSeqs struct{ a, b []rune }
+
+func (s runesSeqs) lengths() (int, int) { return len(s.a), len(s.b) }
+func (s runesSeqs) commonPrefixLen(ai, aj, bi, bj int) int {
+	return commonPrefixLenRunes(s.a[ai:aj:aj], s.b[bi:bj:bj])
+}
+func (s runesSeqs) commonSuffixLen(ai, aj, bi, bj int) int {
+	return commonSuffixLenRunes(s.a[ai:aj:aj], s.b[bi:bj:bj])
+}
+
+// TODO(adonovan): optimize these functions using ideas from:
+// - https://go.dev/cl/408116 common.go
+// - https://go.dev/cl/421435 xor_generic.go
+
+// TODO(adonovan): factor using generics when available,
+// but measure performance impact.
+
+// commonPrefixLen* returns the length of the common prefix of a[ai:aj] and b[bi:bj].
+func commonPrefixLenBytes(a, b []byte) int {
+	n := min(len(a), len(b))
+	i := 0
+	for i < n && a[i] == b[i] {
+		i++
+	}
+	return i
+}
+func commonPrefixLenRunes(a, b []rune) int {
+	n := min(len(a), len(b))
+	i := 0
+	for i < n && a[i] == b[i] {
+		i++
+	}
+	return i
+}
+func commonPrefixLenString(a, b string) int {
+	n := min(len(a), len(b))
+	i := 0
+	for i < n && a[i] == b[i] {
+		i++
+	}
+	return i
+}
+
+// commonSuffixLen* returns the length of the common suffix of a[ai:aj] and b[bi:bj].
+func commonSuffixLenBytes(a, b []byte) int {
+	n := min(len(a), len(b))
+	i := 0
+	for i < n && a[len(a)-1-i] == b[len(b)-1-i] {
+		i++
+	}
+	return i
+}
+func commonSuffixLenRunes(a, b []rune) int {
+	n := min(len(a), len(b))
+	i := 0
+	for i < n && a[len(a)-1-i] == b[len(b)-1-i] {
+		i++
+	}
+	return i
+}
+func commonSuffixLenString(a, b string) int {
+	n := min(len(a), len(b))
+	i := 0
+	for i < n && a[len(a)-1-i] == b[len(b)-1-i] {
+		i++
+	}
+	return i
+}
+
+func min(x, y int) int {
+	if x < y {
+		return x
+	} else {
+		return y
+	}
+}
diff --git a/vendor/golang.org/x/tools/internal/diff/ndiff.go b/vendor/golang.org/x/tools/internal/diff/ndiff.go
new file mode 100644
index 0000000..050b08d
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/diff/ndiff.go
@@ -0,0 +1,109 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package diff
+
+import (
+	"bytes"
+	"unicode/utf8"
+
+	"golang.org/x/tools/internal/diff/lcs"
+)
+
+// Strings computes the differences between two strings.
+// The resulting edits respect rune boundaries.
+func Strings(before, after string) []Edit {
+	if before == after {
+		return nil // common case
+	}
+
+	if stringIsASCII(before) && stringIsASCII(after) {
+		// TODO(adonovan): opt: specialize diffASCII for strings.
+		return diffASCII([]byte(before), []byte(after))
+	}
+	return diffRunes([]rune(before), []rune(after))
+}
+
+// Bytes computes the differences between two byte slices.
+// The resulting edits respect rune boundaries.
+func Bytes(before, after []byte) []Edit {
+	if bytes.Equal(before, after) {
+		return nil // common case
+	}
+
+	if bytesIsASCII(before) && bytesIsASCII(after) {
+		return diffASCII(before, after)
+	}
+	return diffRunes(runes(before), runes(after))
+}
+
+func diffASCII(before, after []byte) []Edit {
+	diffs := lcs.DiffBytes(before, after)
+
+	// Convert from LCS diffs.
+	res := make([]Edit, len(diffs))
+	for i, d := range diffs {
+		res[i] = Edit{d.Start, d.End, string(after[d.ReplStart:d.ReplEnd])}
+	}
+	return res
+}
+
+func diffRunes(before, after []rune) []Edit {
+	diffs := lcs.DiffRunes(before, after)
+
+	// The diffs returned by the lcs package use indexes
+	// into whatever slice was passed in.
+	// Convert rune offsets to byte offsets.
+	res := make([]Edit, len(diffs))
+	lastEnd := 0
+	utf8Len := 0
+	for i, d := range diffs {
+		utf8Len += runesLen(before[lastEnd:d.Start]) // text between edits
+		start := utf8Len
+		utf8Len += runesLen(before[d.Start:d.End]) // text deleted by this edit
+		res[i] = Edit{start, utf8Len, string(after[d.ReplStart:d.ReplEnd])}
+		lastEnd = d.End
+	}
+	return res
+}
+
+// runes is like []rune(string(bytes)) without the duplicate allocation.
+func runes(bytes []byte) []rune {
+	n := utf8.RuneCount(bytes)
+	runes := make([]rune, n)
+	for i := 0; i < n; i++ {
+		r, sz := utf8.DecodeRune(bytes)
+		bytes = bytes[sz:]
+		runes[i] = r
+	}
+	return runes
+}
+
+// runesLen returns the length in bytes of the UTF-8 encoding of runes.
+func runesLen(runes []rune) (len int) {
+	for _, r := range runes {
+		len += utf8.RuneLen(r)
+	}
+	return len
+}
+
+// stringIsASCII reports whether s contains only ASCII.
+// TODO(adonovan): combine when x/tools allows generics.
+func stringIsASCII(s string) bool {
+	for i := 0; i < len(s); i++ {
+		if s[i] >= utf8.RuneSelf {
+			return false
+		}
+	}
+	return true
+}
+
+func bytesIsASCII(s []byte) bool {
+	for i := 0; i < len(s); i++ {
+		if s[i] >= utf8.RuneSelf {
+			return false
+		}
+	}
+	return true
+}
diff --git a/vendor/golang.org/x/tools/internal/diff/unified.go b/vendor/golang.org/x/tools/internal/diff/unified.go
new file mode 100644
index 0000000..fa376f1
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/diff/unified.go
@@ -0,0 +1,248 @@
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package diff
+
+import (
+	"fmt"
+	"log"
+	"strings"
+)
+
+// Unified returns a unified diff of the old and new strings.
+// The old and new labels are the names of the old and new files.
+// If the strings are equal, it returns the empty string.
+func Unified(oldLabel, newLabel, old, new string) string {
+	edits := Strings(old, new)
+	unified, err := ToUnified(oldLabel, newLabel, old, edits)
+	if err != nil {
+		// Can't happen: edits are consistent.
+		log.Fatalf("internal error in diff.Unified: %v", err)
+	}
+	return unified
+}
+
+// ToUnified applies the edits to content and returns a unified diff.
+// The old and new labels are the names of the content and result files.
+// It returns an error if the edits are inconsistent; see ApplyEdits.
+func ToUnified(oldLabel, newLabel, content string, edits []Edit) (string, error) {
+	u, err := toUnified(oldLabel, newLabel, content, edits)
+	if err != nil {
+		return "", err
+	}
+	return u.String(), nil
+}
+
+// unified represents a set of edits as a unified diff.
+type unified struct {
+	// From is the name of the original file.
+	From string
+	// To is the name of the modified file.
+	To string
+	// Hunks is the set of edit hunks needed to transform the file content.
+	Hunks []*hunk
+}
+
+// Hunk represents a contiguous set of line edits to apply.
+type hunk struct {
+	// The line in the original source where the hunk starts.
+	FromLine int
+	// The line in the original source where the hunk finishes.
+	ToLine int
+	// The set of line based edits to apply.
+	Lines []line
+}
+
+// Line represents a single line operation to apply as part of a Hunk.
+type line struct {
+	// Kind is the type of line this represents, deletion, insertion or copy.
+	Kind OpKind
+	// Content is the content of this line.
+	// For deletion it is the line being removed, for all others it is the line
+	// to put in the output.
+	Content string
+}
+
+// OpKind is used to denote the type of operation a line represents.
+// TODO(adonovan): hide this once the myers package no longer references it.
+type OpKind int
+
+const (
+	// Delete is the operation kind for a line that is present in the input
+	// but not in the output.
+	Delete OpKind = iota
+	// Insert is the operation kind for a line that is new in the output.
+	Insert
+	// Equal is the operation kind for a line that is the same in the input and
+	// output, often used to provide context around edited lines.
+	Equal
+)
+
+// String returns a human readable representation of an OpKind. It is not
+// intended for machine processing.
+func (k OpKind) String() string {
+	switch k {
+	case Delete:
+		return "delete"
+	case Insert:
+		return "insert"
+	case Equal:
+		return "equal"
+	default:
+		panic("unknown operation kind")
+	}
+}
+
+const (
+	edge = 3
+	gap  = edge * 2
+)
+
+// toUnified takes a file contents and a sequence of edits, and calculates
+// a unified diff that represents those edits.
+func toUnified(fromName, toName string, content string, edits []Edit) (unified, error) {
+	u := unified{
+		From: fromName,
+		To:   toName,
+	}
+	if len(edits) == 0 {
+		return u, nil
+	}
+	var err error
+	edits, err = lineEdits(content, edits) // expand to whole lines
+	if err != nil {
+		return u, err
+	}
+	lines := splitLines(content)
+	var h *hunk
+	last := 0
+	toLine := 0
+	for _, edit := range edits {
+		// Compute the zero-based line numbers of the edit start and end.
+		// TODO(adonovan): opt: compute incrementally, avoid O(n^2).
+		start := strings.Count(content[:edit.Start], "\n")
+		end := strings.Count(content[:edit.End], "\n")
+		if edit.End == len(content) && len(content) > 0 && content[len(content)-1] != '\n' {
+			end++ // EOF counts as an implicit newline
+		}
+
+		switch {
+		case h != nil && start == last:
+			//direct extension
+		case h != nil && start <= last+gap:
+			//within range of previous lines, add the joiners
+			addEqualLines(h, lines, last, start)
+		default:
+			//need to start a new hunk
+			if h != nil {
+				// add the edge to the previous hunk
+				addEqualLines(h, lines, last, last+edge)
+				u.Hunks = append(u.Hunks, h)
+			}
+			toLine += start - last
+			h = &hunk{
+				FromLine: start + 1,
+				ToLine:   toLine + 1,
+			}
+			// add the edge to the new hunk
+			delta := addEqualLines(h, lines, start-edge, start)
+			h.FromLine -= delta
+			h.ToLine -= delta
+		}
+		last = start
+		for i := start; i < end; i++ {
+			h.Lines = append(h.Lines, line{Kind: Delete, Content: lines[i]})
+			last++
+		}
+		if edit.New != "" {
+			for _, content := range splitLines(edit.New) {
+				h.Lines = append(h.Lines, line{Kind: Insert, Content: content})
+				toLine++
+			}
+		}
+	}
+	if h != nil {
+		// add the edge to the final hunk
+		addEqualLines(h, lines, last, last+edge)
+		u.Hunks = append(u.Hunks, h)
+	}
+	return u, nil
+}
+
+func splitLines(text string) []string {
+	lines := strings.SplitAfter(text, "\n")
+	if lines[len(lines)-1] == "" {
+		lines = lines[:len(lines)-1]
+	}
+	return lines
+}
+
+func addEqualLines(h *hunk, lines []string, start, end int) int {
+	delta := 0
+	for i := start; i < end; i++ {
+		if i < 0 {
+			continue
+		}
+		if i >= len(lines) {
+			return delta
+		}
+		h.Lines = append(h.Lines, line{Kind: Equal, Content: lines[i]})
+		delta++
+	}
+	return delta
+}
+
+// String converts a unified diff to the standard textual form for that diff.
+// The output of this function can be passed to tools like patch.
+func (u unified) String() string {
+	if len(u.Hunks) == 0 {
+		return ""
+	}
+	b := new(strings.Builder)
+	fmt.Fprintf(b, "--- %s\n", u.From)
+	fmt.Fprintf(b, "+++ %s\n", u.To)
+	for _, hunk := range u.Hunks {
+		fromCount, toCount := 0, 0
+		for _, l := range hunk.Lines {
+			switch l.Kind {
+			case Delete:
+				fromCount++
+			case Insert:
+				toCount++
+			default:
+				fromCount++
+				toCount++
+			}
+		}
+		fmt.Fprint(b, "@@")
+		if fromCount > 1 {
+			fmt.Fprintf(b, " -%d,%d", hunk.FromLine, fromCount)
+		} else if hunk.FromLine == 1 && fromCount == 0 {
+			// Match odd GNU diff -u behavior adding to empty file.
+			fmt.Fprintf(b, " -0,0")
+		} else {
+			fmt.Fprintf(b, " -%d", hunk.FromLine)
+		}
+		if toCount > 1 {
+			fmt.Fprintf(b, " +%d,%d", hunk.ToLine, toCount)
+		} else {
+			fmt.Fprintf(b, " +%d", hunk.ToLine)
+		}
+		fmt.Fprint(b, " @@\n")
+		for _, l := range hunk.Lines {
+			switch l.Kind {
+			case Delete:
+				fmt.Fprintf(b, "-%s", l.Content)
+			case Insert:
+				fmt.Fprintf(b, "+%s", l.Content)
+			default:
+				fmt.Fprintf(b, " %s", l.Content)
+			}
+			if !strings.HasSuffix(l.Content, "\n") {
+				fmt.Fprintf(b, "\n\\ No newline at end of file\n")
+			}
+		}
+	}
+	return b.String()
+}
diff --git a/vendor/golang.org/x/tools/internal/event/core/event.go b/vendor/golang.org/x/tools/internal/event/core/event.go
new file mode 100644
index 0000000..a6cf0e6
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/event/core/event.go
@@ -0,0 +1,85 @@
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package core provides support for event based telemetry.
+package core
+
+import (
+	"fmt"
+	"time"
+
+	"golang.org/x/tools/internal/event/label"
+)
+
+// Event holds the information about an event of note that occurred.
+type Event struct {
+	at time.Time
+
+	// As events are often on the stack, storing the first few labels directly
+	// in the event can avoid an allocation at all for the very common cases of
+	// simple events.
+	// The length needs to be large enough to cope with the majority of events
+	// but no so large as to cause undue stack pressure.
+	// A log message with two values will use 3 labels (one for each value and
+	// one for the message itself).
+
+	static  [3]label.Label // inline storage for the first few labels
+	dynamic []label.Label  // dynamically sized storage for remaining labels
+}
+
+// eventLabelMap implements label.Map for a the labels of an Event.
+type eventLabelMap struct {
+	event Event
+}
+
+func (ev Event) At() time.Time { return ev.at }
+
+func (ev Event) Format(f fmt.State, r rune) {
+	if !ev.at.IsZero() {
+		fmt.Fprint(f, ev.at.Format("2006/01/02 15:04:05 "))
+	}
+	for index := 0; ev.Valid(index); index++ {
+		if l := ev.Label(index); l.Valid() {
+			fmt.Fprintf(f, "\n\t%v", l)
+		}
+	}
+}
+
+func (ev Event) Valid(index int) bool {
+	return index >= 0 && index < len(ev.static)+len(ev.dynamic)
+}
+
+func (ev Event) Label(index int) label.Label {
+	if index < len(ev.static) {
+		return ev.static[index]
+	}
+	return ev.dynamic[index-len(ev.static)]
+}
+
+func (ev Event) Find(key label.Key) label.Label {
+	for _, l := range ev.static {
+		if l.Key() == key {
+			return l
+		}
+	}
+	for _, l := range ev.dynamic {
+		if l.Key() == key {
+			return l
+		}
+	}
+	return label.Label{}
+}
+
+func MakeEvent(static [3]label.Label, labels []label.Label) Event {
+	return Event{
+		static:  static,
+		dynamic: labels,
+	}
+}
+
+// CloneEvent event returns a copy of the event with the time adjusted to at.
+func CloneEvent(ev Event, at time.Time) Event {
+	ev.at = at
+	return ev
+}
diff --git a/vendor/golang.org/x/tools/internal/event/core/export.go b/vendor/golang.org/x/tools/internal/event/core/export.go
new file mode 100644
index 0000000..05f3a9a
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/event/core/export.go
@@ -0,0 +1,70 @@
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package core
+
+import (
+	"context"
+	"sync/atomic"
+	"time"
+	"unsafe"
+
+	"golang.org/x/tools/internal/event/label"
+)
+
+// Exporter is a function that handles events.
+// It may return a modified context and event.
+type Exporter func(context.Context, Event, label.Map) context.Context
+
+var (
+	exporter unsafe.Pointer
+)
+
+// SetExporter sets the global exporter function that handles all events.
+// The exporter is called synchronously from the event call site, so it should
+// return quickly so as not to hold up user code.
+func SetExporter(e Exporter) {
+	p := unsafe.Pointer(&e)
+	if e == nil {
+		// &e is always valid, and so p is always valid, but for the early abort
+		// of ProcessEvent to be efficient it needs to make the nil check on the
+		// pointer without having to dereference it, so we make the nil function
+		// also a nil pointer
+		p = nil
+	}
+	atomic.StorePointer(&exporter, p)
+}
+
+// deliver is called to deliver an event to the supplied exporter.
+// it will fill in the time.
+func deliver(ctx context.Context, exporter Exporter, ev Event) context.Context {
+	// add the current time to the event
+	ev.at = time.Now()
+	// hand the event off to the current exporter
+	return exporter(ctx, ev, ev)
+}
+
+// Export is called to deliver an event to the global exporter if set.
+func Export(ctx context.Context, ev Event) context.Context {
+	// get the global exporter and abort early if there is not one
+	exporterPtr := (*Exporter)(atomic.LoadPointer(&exporter))
+	if exporterPtr == nil {
+		return ctx
+	}
+	return deliver(ctx, *exporterPtr, ev)
+}
+
+// ExportPair is called to deliver a start event to the supplied exporter.
+// It also returns a function that will deliver the end event to the same
+// exporter.
+// It will fill in the time.
+func ExportPair(ctx context.Context, begin, end Event) (context.Context, func()) {
+	// get the global exporter and abort early if there is not one
+	exporterPtr := (*Exporter)(atomic.LoadPointer(&exporter))
+	if exporterPtr == nil {
+		return ctx, func() {}
+	}
+	ctx = deliver(ctx, *exporterPtr, begin)
+	return ctx, func() { deliver(ctx, *exporterPtr, end) }
+}
diff --git a/vendor/golang.org/x/tools/internal/event/core/fast.go b/vendor/golang.org/x/tools/internal/event/core/fast.go
new file mode 100644
index 0000000..06c1d46
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/event/core/fast.go
@@ -0,0 +1,77 @@
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package core
+
+import (
+	"context"
+
+	"golang.org/x/tools/internal/event/keys"
+	"golang.org/x/tools/internal/event/label"
+)
+
+// Log1 takes a message and one label delivers a log event to the exporter.
+// It is a customized version of Print that is faster and does no allocation.
+func Log1(ctx context.Context, message string, t1 label.Label) {
+	Export(ctx, MakeEvent([3]label.Label{
+		keys.Msg.Of(message),
+		t1,
+	}, nil))
+}
+
+// Log2 takes a message and two labels and delivers a log event to the exporter.
+// It is a customized version of Print that is faster and does no allocation.
+func Log2(ctx context.Context, message string, t1 label.Label, t2 label.Label) {
+	Export(ctx, MakeEvent([3]label.Label{
+		keys.Msg.Of(message),
+		t1,
+		t2,
+	}, nil))
+}
+
+// Metric1 sends a label event to the exporter with the supplied labels.
+func Metric1(ctx context.Context, t1 label.Label) context.Context {
+	return Export(ctx, MakeEvent([3]label.Label{
+		keys.Metric.New(),
+		t1,
+	}, nil))
+}
+
+// Metric2 sends a label event to the exporter with the supplied labels.
+func Metric2(ctx context.Context, t1, t2 label.Label) context.Context {
+	return Export(ctx, MakeEvent([3]label.Label{
+		keys.Metric.New(),
+		t1,
+		t2,
+	}, nil))
+}
+
+// Start1 sends a span start event with the supplied label list to the exporter.
+// It also returns a function that will end the span, which should normally be
+// deferred.
+func Start1(ctx context.Context, name string, t1 label.Label) (context.Context, func()) {
+	return ExportPair(ctx,
+		MakeEvent([3]label.Label{
+			keys.Start.Of(name),
+			t1,
+		}, nil),
+		MakeEvent([3]label.Label{
+			keys.End.New(),
+		}, nil))
+}
+
+// Start2 sends a span start event with the supplied label list to the exporter.
+// It also returns a function that will end the span, which should normally be
+// deferred.
+func Start2(ctx context.Context, name string, t1, t2 label.Label) (context.Context, func()) {
+	return ExportPair(ctx,
+		MakeEvent([3]label.Label{
+			keys.Start.Of(name),
+			t1,
+			t2,
+		}, nil),
+		MakeEvent([3]label.Label{
+			keys.End.New(),
+		}, nil))
+}
diff --git a/vendor/golang.org/x/tools/internal/event/doc.go b/vendor/golang.org/x/tools/internal/event/doc.go
new file mode 100644
index 0000000..5dc6e6b
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/event/doc.go
@@ -0,0 +1,7 @@
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package event provides a set of packages that cover the main
+// concepts of telemetry in an implementation agnostic way.
+package event
diff --git a/vendor/golang.org/x/tools/internal/event/event.go b/vendor/golang.org/x/tools/internal/event/event.go
new file mode 100644
index 0000000..4d55e57
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/event/event.go
@@ -0,0 +1,127 @@
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package event
+
+import (
+	"context"
+
+	"golang.org/x/tools/internal/event/core"
+	"golang.org/x/tools/internal/event/keys"
+	"golang.org/x/tools/internal/event/label"
+)
+
+// Exporter is a function that handles events.
+// It may return a modified context and event.
+type Exporter func(context.Context, core.Event, label.Map) context.Context
+
+// SetExporter sets the global exporter function that handles all events.
+// The exporter is called synchronously from the event call site, so it should
+// return quickly so as not to hold up user code.
+func SetExporter(e Exporter) {
+	core.SetExporter(core.Exporter(e))
+}
+
+// Log takes a message and a label list and combines them into a single event
+// before delivering them to the exporter.
+func Log(ctx context.Context, message string, labels ...label.Label) {
+	core.Export(ctx, core.MakeEvent([3]label.Label{
+		keys.Msg.Of(message),
+	}, labels))
+}
+
+// IsLog returns true if the event was built by the Log function.
+// It is intended to be used in exporters to identify the semantics of the
+// event when deciding what to do with it.
+func IsLog(ev core.Event) bool {
+	return ev.Label(0).Key() == keys.Msg
+}
+
+// Error takes a message and a label list and combines them into a single event
+// before delivering them to the exporter. It captures the error in the
+// delivered event.
+func Error(ctx context.Context, message string, err error, labels ...label.Label) {
+	core.Export(ctx, core.MakeEvent([3]label.Label{
+		keys.Msg.Of(message),
+		keys.Err.Of(err),
+	}, labels))
+}
+
+// IsError returns true if the event was built by the Error function.
+// It is intended to be used in exporters to identify the semantics of the
+// event when deciding what to do with it.
+func IsError(ev core.Event) bool {
+	return ev.Label(0).Key() == keys.Msg &&
+		ev.Label(1).Key() == keys.Err
+}
+
+// Metric sends a label event to the exporter with the supplied labels.
+func Metric(ctx context.Context, labels ...label.Label) {
+	core.Export(ctx, core.MakeEvent([3]label.Label{
+		keys.Metric.New(),
+	}, labels))
+}
+
+// IsMetric returns true if the event was built by the Metric function.
+// It is intended to be used in exporters to identify the semantics of the
+// event when deciding what to do with it.
+func IsMetric(ev core.Event) bool {
+	return ev.Label(0).Key() == keys.Metric
+}
+
+// Label sends a label event to the exporter with the supplied labels.
+func Label(ctx context.Context, labels ...label.Label) context.Context {
+	return core.Export(ctx, core.MakeEvent([3]label.Label{
+		keys.Label.New(),
+	}, labels))
+}
+
+// IsLabel returns true if the event was built by the Label function.
+// It is intended to be used in exporters to identify the semantics of the
+// event when deciding what to do with it.
+func IsLabel(ev core.Event) bool {
+	return ev.Label(0).Key() == keys.Label
+}
+
+// Start sends a span start event with the supplied label list to the exporter.
+// It also returns a function that will end the span, which should normally be
+// deferred.
+func Start(ctx context.Context, name string, labels ...label.Label) (context.Context, func()) {
+	return core.ExportPair(ctx,
+		core.MakeEvent([3]label.Label{
+			keys.Start.Of(name),
+		}, labels),
+		core.MakeEvent([3]label.Label{
+			keys.End.New(),
+		}, nil))
+}
+
+// IsStart returns true if the event was built by the Start function.
+// It is intended to be used in exporters to identify the semantics of the
+// event when deciding what to do with it.
+func IsStart(ev core.Event) bool {
+	return ev.Label(0).Key() == keys.Start
+}
+
+// IsEnd returns true if the event was built by the End function.
+// It is intended to be used in exporters to identify the semantics of the
+// event when deciding what to do with it.
+func IsEnd(ev core.Event) bool {
+	return ev.Label(0).Key() == keys.End
+}
+
+// Detach returns a context without an associated span.
+// This allows the creation of spans that are not children of the current span.
+func Detach(ctx context.Context) context.Context {
+	return core.Export(ctx, core.MakeEvent([3]label.Label{
+		keys.Detach.New(),
+	}, nil))
+}
+
+// IsDetach returns true if the event was built by the Detach function.
+// It is intended to be used in exporters to identify the semantics of the
+// event when deciding what to do with it.
+func IsDetach(ev core.Event) bool {
+	return ev.Label(0).Key() == keys.Detach
+}
diff --git a/vendor/golang.org/x/tools/internal/event/keys/keys.go b/vendor/golang.org/x/tools/internal/event/keys/keys.go
new file mode 100644
index 0000000..a02206e
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/event/keys/keys.go
@@ -0,0 +1,564 @@
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package keys
+
+import (
+	"fmt"
+	"io"
+	"math"
+	"strconv"
+
+	"golang.org/x/tools/internal/event/label"
+)
+
+// Value represents a key for untyped values.
+type Value struct {
+	name        string
+	description string
+}
+
+// New creates a new Key for untyped values.
+func New(name, description string) *Value {
+	return &Value{name: name, description: description}
+}
+
+func (k *Value) Name() string        { return k.name }
+func (k *Value) Description() string { return k.description }
+
+func (k *Value) Format(w io.Writer, buf []byte, l label.Label) {
+	fmt.Fprint(w, k.From(l))
+}
+
+// Get can be used to get a label for the key from a label.Map.
+func (k *Value) Get(lm label.Map) interface{} {
+	if t := lm.Find(k); t.Valid() {
+		return k.From(t)
+	}
+	return nil
+}
+
+// From can be used to get a value from a Label.
+func (k *Value) From(t label.Label) interface{} { return t.UnpackValue() }
+
+// Of creates a new Label with this key and the supplied value.
+func (k *Value) Of(value interface{}) label.Label { return label.OfValue(k, value) }
+
+// Tag represents a key for tagging labels that have no value.
+// These are used when the existence of the label is the entire information it
+// carries, such as marking events to be of a specific kind, or from a specific
+// package.
+type Tag struct {
+	name        string
+	description string
+}
+
+// NewTag creates a new Key for tagging labels.
+func NewTag(name, description string) *Tag {
+	return &Tag{name: name, description: description}
+}
+
+func (k *Tag) Name() string        { return k.name }
+func (k *Tag) Description() string { return k.description }
+
+func (k *Tag) Format(w io.Writer, buf []byte, l label.Label) {}
+
+// New creates a new Label with this key.
+func (k *Tag) New() label.Label { return label.OfValue(k, nil) }
+
+// Int represents a key
+type Int struct {
+	name        string
+	description string
+}
+
+// NewInt creates a new Key for int values.
+func NewInt(name, description string) *Int {
+	return &Int{name: name, description: description}
+}
+
+func (k *Int) Name() string        { return k.name }
+func (k *Int) Description() string { return k.description }
+
+func (k *Int) Format(w io.Writer, buf []byte, l label.Label) {
+	w.Write(strconv.AppendInt(buf, int64(k.From(l)), 10))
+}
+
+// Of creates a new Label with this key and the supplied value.
+func (k *Int) Of(v int) label.Label { return label.Of64(k, uint64(v)) }
+
+// Get can be used to get a label for the key from a label.Map.
+func (k *Int) Get(lm label.Map) int {
+	if t := lm.Find(k); t.Valid() {
+		return k.From(t)
+	}
+	return 0
+}
+
+// From can be used to get a value from a Label.
+func (k *Int) From(t label.Label) int { return int(t.Unpack64()) }
+
+// Int8 represents a key
+type Int8 struct {
+	name        string
+	description string
+}
+
+// NewInt8 creates a new Key for int8 values.
+func NewInt8(name, description string) *Int8 {
+	return &Int8{name: name, description: description}
+}
+
+func (k *Int8) Name() string        { return k.name }
+func (k *Int8) Description() string { return k.description }
+
+func (k *Int8) Format(w io.Writer, buf []byte, l label.Label) {
+	w.Write(strconv.AppendInt(buf, int64(k.From(l)), 10))
+}
+
+// Of creates a new Label with this key and the supplied value.
+func (k *Int8) Of(v int8) label.Label { return label.Of64(k, uint64(v)) }
+
+// Get can be used to get a label for the key from a label.Map.
+func (k *Int8) Get(lm label.Map) int8 {
+	if t := lm.Find(k); t.Valid() {
+		return k.From(t)
+	}
+	return 0
+}
+
+// From can be used to get a value from a Label.
+func (k *Int8) From(t label.Label) int8 { return int8(t.Unpack64()) }
+
+// Int16 represents a key
+type Int16 struct {
+	name        string
+	description string
+}
+
+// NewInt16 creates a new Key for int16 values.
+func NewInt16(name, description string) *Int16 {
+	return &Int16{name: name, description: description}
+}
+
+func (k *Int16) Name() string        { return k.name }
+func (k *Int16) Description() string { return k.description }
+
+func (k *Int16) Format(w io.Writer, buf []byte, l label.Label) {
+	w.Write(strconv.AppendInt(buf, int64(k.From(l)), 10))
+}
+
+// Of creates a new Label with this key and the supplied value.
+func (k *Int16) Of(v int16) label.Label { return label.Of64(k, uint64(v)) }
+
+// Get can be used to get a label for the key from a label.Map.
+func (k *Int16) Get(lm label.Map) int16 {
+	if t := lm.Find(k); t.Valid() {
+		return k.From(t)
+	}
+	return 0
+}
+
+// From can be used to get a value from a Label.
+func (k *Int16) From(t label.Label) int16 { return int16(t.Unpack64()) }
+
+// Int32 represents a key
+type Int32 struct {
+	name        string
+	description string
+}
+
+// NewInt32 creates a new Key for int32 values.
+func NewInt32(name, description string) *Int32 {
+	return &Int32{name: name, description: description}
+}
+
+func (k *Int32) Name() string        { return k.name }
+func (k *Int32) Description() string { return k.description }
+
+func (k *Int32) Format(w io.Writer, buf []byte, l label.Label) {
+	w.Write(strconv.AppendInt(buf, int64(k.From(l)), 10))
+}
+
+// Of creates a new Label with this key and the supplied value.
+func (k *Int32) Of(v int32) label.Label { return label.Of64(k, uint64(v)) }
+
+// Get can be used to get a label for the key from a label.Map.
+func (k *Int32) Get(lm label.Map) int32 {
+	if t := lm.Find(k); t.Valid() {
+		return k.From(t)
+	}
+	return 0
+}
+
+// From can be used to get a value from a Label.
+func (k *Int32) From(t label.Label) int32 { return int32(t.Unpack64()) }
+
+// Int64 represents a key
+type Int64 struct {
+	name        string
+	description string
+}
+
+// NewInt64 creates a new Key for int64 values.
+func NewInt64(name, description string) *Int64 {
+	return &Int64{name: name, description: description}
+}
+
+func (k *Int64) Name() string        { return k.name }
+func (k *Int64) Description() string { return k.description }
+
+func (k *Int64) Format(w io.Writer, buf []byte, l label.Label) {
+	w.Write(strconv.AppendInt(buf, k.From(l), 10))
+}
+
+// Of creates a new Label with this key and the supplied value.
+func (k *Int64) Of(v int64) label.Label { return label.Of64(k, uint64(v)) }
+
+// Get can be used to get a label for the key from a label.Map.
+func (k *Int64) Get(lm label.Map) int64 {
+	if t := lm.Find(k); t.Valid() {
+		return k.From(t)
+	}
+	return 0
+}
+
+// From can be used to get a value from a Label.
+func (k *Int64) From(t label.Label) int64 { return int64(t.Unpack64()) }
+
+// UInt represents a key
+type UInt struct {
+	name        string
+	description string
+}
+
+// NewUInt creates a new Key for uint values.
+func NewUInt(name, description string) *UInt {
+	return &UInt{name: name, description: description}
+}
+
+func (k *UInt) Name() string        { return k.name }
+func (k *UInt) Description() string { return k.description }
+
+func (k *UInt) Format(w io.Writer, buf []byte, l label.Label) {
+	w.Write(strconv.AppendUint(buf, uint64(k.From(l)), 10))
+}
+
+// Of creates a new Label with this key and the supplied value.
+func (k *UInt) Of(v uint) label.Label { return label.Of64(k, uint64(v)) }
+
+// Get can be used to get a label for the key from a label.Map.
+func (k *UInt) Get(lm label.Map) uint {
+	if t := lm.Find(k); t.Valid() {
+		return k.From(t)
+	}
+	return 0
+}
+
+// From can be used to get a value from a Label.
+func (k *UInt) From(t label.Label) uint { return uint(t.Unpack64()) }
+
+// UInt8 represents a key
+type UInt8 struct {
+	name        string
+	description string
+}
+
+// NewUInt8 creates a new Key for uint8 values.
+func NewUInt8(name, description string) *UInt8 {
+	return &UInt8{name: name, description: description}
+}
+
+func (k *UInt8) Name() string        { return k.name }
+func (k *UInt8) Description() string { return k.description }
+
+func (k *UInt8) Format(w io.Writer, buf []byte, l label.Label) {
+	w.Write(strconv.AppendUint(buf, uint64(k.From(l)), 10))
+}
+
+// Of creates a new Label with this key and the supplied value.
+func (k *UInt8) Of(v uint8) label.Label { return label.Of64(k, uint64(v)) }
+
+// Get can be used to get a label for the key from a label.Map.
+func (k *UInt8) Get(lm label.Map) uint8 {
+	if t := lm.Find(k); t.Valid() {
+		return k.From(t)
+	}
+	return 0
+}
+
+// From can be used to get a value from a Label.
+func (k *UInt8) From(t label.Label) uint8 { return uint8(t.Unpack64()) }
+
+// UInt16 represents a key
+type UInt16 struct {
+	name        string
+	description string
+}
+
+// NewUInt16 creates a new Key for uint16 values.
+func NewUInt16(name, description string) *UInt16 {
+	return &UInt16{name: name, description: description}
+}
+
+func (k *UInt16) Name() string        { return k.name }
+func (k *UInt16) Description() string { return k.description }
+
+func (k *UInt16) Format(w io.Writer, buf []byte, l label.Label) {
+	w.Write(strconv.AppendUint(buf, uint64(k.From(l)), 10))
+}
+
+// Of creates a new Label with this key and the supplied value.
+func (k *UInt16) Of(v uint16) label.Label { return label.Of64(k, uint64(v)) }
+
+// Get can be used to get a label for the key from a label.Map.
+func (k *UInt16) Get(lm label.Map) uint16 {
+	if t := lm.Find(k); t.Valid() {
+		return k.From(t)
+	}
+	return 0
+}
+
+// From can be used to get a value from a Label.
+func (k *UInt16) From(t label.Label) uint16 { return uint16(t.Unpack64()) }
+
+// UInt32 represents a key
+type UInt32 struct {
+	name        string
+	description string
+}
+
+// NewUInt32 creates a new Key for uint32 values.
+func NewUInt32(name, description string) *UInt32 {
+	return &UInt32{name: name, description: description}
+}
+
+func (k *UInt32) Name() string        { return k.name }
+func (k *UInt32) Description() string { return k.description }
+
+func (k *UInt32) Format(w io.Writer, buf []byte, l label.Label) {
+	w.Write(strconv.AppendUint(buf, uint64(k.From(l)), 10))
+}
+
+// Of creates a new Label with this key and the supplied value.
+func (k *UInt32) Of(v uint32) label.Label { return label.Of64(k, uint64(v)) }
+
+// Get can be used to get a label for the key from a label.Map.
+func (k *UInt32) Get(lm label.Map) uint32 {
+	if t := lm.Find(k); t.Valid() {
+		return k.From(t)
+	}
+	return 0
+}
+
+// From can be used to get a value from a Label.
+func (k *UInt32) From(t label.Label) uint32 { return uint32(t.Unpack64()) }
+
+// UInt64 represents a key
+type UInt64 struct {
+	name        string
+	description string
+}
+
+// NewUInt64 creates a new Key for uint64 values.
+func NewUInt64(name, description string) *UInt64 {
+	return &UInt64{name: name, description: description}
+}
+
+func (k *UInt64) Name() string        { return k.name }
+func (k *UInt64) Description() string { return k.description }
+
+func (k *UInt64) Format(w io.Writer, buf []byte, l label.Label) {
+	w.Write(strconv.AppendUint(buf, k.From(l), 10))
+}
+
+// Of creates a new Label with this key and the supplied value.
+func (k *UInt64) Of(v uint64) label.Label { return label.Of64(k, v) }
+
+// Get can be used to get a label for the key from a label.Map.
+func (k *UInt64) Get(lm label.Map) uint64 {
+	if t := lm.Find(k); t.Valid() {
+		return k.From(t)
+	}
+	return 0
+}
+
+// From can be used to get a value from a Label.
+func (k *UInt64) From(t label.Label) uint64 { return t.Unpack64() }
+
+// Float32 represents a key
+type Float32 struct {
+	name        string
+	description string
+}
+
+// NewFloat32 creates a new Key for float32 values.
+func NewFloat32(name, description string) *Float32 {
+	return &Float32{name: name, description: description}
+}
+
+func (k *Float32) Name() string        { return k.name }
+func (k *Float32) Description() string { return k.description }
+
+func (k *Float32) Format(w io.Writer, buf []byte, l label.Label) {
+	w.Write(strconv.AppendFloat(buf, float64(k.From(l)), 'E', -1, 32))
+}
+
+// Of creates a new Label with this key and the supplied value.
+func (k *Float32) Of(v float32) label.Label {
+	return label.Of64(k, uint64(math.Float32bits(v)))
+}
+
+// Get can be used to get a label for the key from a label.Map.
+func (k *Float32) Get(lm label.Map) float32 {
+	if t := lm.Find(k); t.Valid() {
+		return k.From(t)
+	}
+	return 0
+}
+
+// From can be used to get a value from a Label.
+func (k *Float32) From(t label.Label) float32 {
+	return math.Float32frombits(uint32(t.Unpack64()))
+}
+
+// Float64 represents a key
+type Float64 struct {
+	name        string
+	description string
+}
+
+// NewFloat64 creates a new Key for int64 values.
+func NewFloat64(name, description string) *Float64 {
+	return &Float64{name: name, description: description}
+}
+
+func (k *Float64) Name() string        { return k.name }
+func (k *Float64) Description() string { return k.description }
+
+func (k *Float64) Format(w io.Writer, buf []byte, l label.Label) {
+	w.Write(strconv.AppendFloat(buf, k.From(l), 'E', -1, 64))
+}
+
+// Of creates a new Label with this key and the supplied value.
+func (k *Float64) Of(v float64) label.Label {
+	return label.Of64(k, math.Float64bits(v))
+}
+
+// Get can be used to get a label for the key from a label.Map.
+func (k *Float64) Get(lm label.Map) float64 {
+	if t := lm.Find(k); t.Valid() {
+		return k.From(t)
+	}
+	return 0
+}
+
+// From can be used to get a value from a Label.
+func (k *Float64) From(t label.Label) float64 {
+	return math.Float64frombits(t.Unpack64())
+}
+
+// String represents a key
+type String struct {
+	name        string
+	description string
+}
+
+// NewString creates a new Key for int64 values.
+func NewString(name, description string) *String {
+	return &String{name: name, description: description}
+}
+
+func (k *String) Name() string        { return k.name }
+func (k *String) Description() string { return k.description }
+
+func (k *String) Format(w io.Writer, buf []byte, l label.Label) {
+	w.Write(strconv.AppendQuote(buf, k.From(l)))
+}
+
+// Of creates a new Label with this key and the supplied value.
+func (k *String) Of(v string) label.Label { return label.OfString(k, v) }
+
+// Get can be used to get a label for the key from a label.Map.
+func (k *String) Get(lm label.Map) string {
+	if t := lm.Find(k); t.Valid() {
+		return k.From(t)
+	}
+	return ""
+}
+
+// From can be used to get a value from a Label.
+func (k *String) From(t label.Label) string { return t.UnpackString() }
+
+// Boolean represents a key
+type Boolean struct {
+	name        string
+	description string
+}
+
+// NewBoolean creates a new Key for bool values.
+func NewBoolean(name, description string) *Boolean {
+	return &Boolean{name: name, description: description}
+}
+
+func (k *Boolean) Name() string        { return k.name }
+func (k *Boolean) Description() string { return k.description }
+
+func (k *Boolean) Format(w io.Writer, buf []byte, l label.Label) {
+	w.Write(strconv.AppendBool(buf, k.From(l)))
+}
+
+// Of creates a new Label with this key and the supplied value.
+func (k *Boolean) Of(v bool) label.Label {
+	if v {
+		return label.Of64(k, 1)
+	}
+	return label.Of64(k, 0)
+}
+
+// Get can be used to get a label for the key from a label.Map.
+func (k *Boolean) Get(lm label.Map) bool {
+	if t := lm.Find(k); t.Valid() {
+		return k.From(t)
+	}
+	return false
+}
+
+// From can be used to get a value from a Label.
+func (k *Boolean) From(t label.Label) bool { return t.Unpack64() > 0 }
+
+// Error represents a key
+type Error struct {
+	name        string
+	description string
+}
+
+// NewError creates a new Key for int64 values.
+func NewError(name, description string) *Error {
+	return &Error{name: name, description: description}
+}
+
+func (k *Error) Name() string        { return k.name }
+func (k *Error) Description() string { return k.description }
+
+func (k *Error) Format(w io.Writer, buf []byte, l label.Label) {
+	io.WriteString(w, k.From(l).Error())
+}
+
+// Of creates a new Label with this key and the supplied value.
+func (k *Error) Of(v error) label.Label { return label.OfValue(k, v) }
+
+// Get can be used to get a label for the key from a label.Map.
+func (k *Error) Get(lm label.Map) error {
+	if t := lm.Find(k); t.Valid() {
+		return k.From(t)
+	}
+	return nil
+}
+
+// From can be used to get a value from a Label.
+func (k *Error) From(t label.Label) error {
+	err, _ := t.UnpackValue().(error)
+	return err
+}
diff --git a/vendor/golang.org/x/tools/internal/event/keys/standard.go b/vendor/golang.org/x/tools/internal/event/keys/standard.go
new file mode 100644
index 0000000..7e95866
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/event/keys/standard.go
@@ -0,0 +1,22 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package keys
+
+var (
+	// Msg is a key used to add message strings to label lists.
+	Msg = NewString("message", "a readable message")
+	// Label is a key used to indicate an event adds labels to the context.
+	Label = NewTag("label", "a label context marker")
+	// Start is used for things like traces that have a name.
+	Start = NewString("start", "span start")
+	// Metric is a key used to indicate an event records metrics.
+	End = NewTag("end", "a span end marker")
+	// Metric is a key used to indicate an event records metrics.
+	Detach = NewTag("detach", "a span detach marker")
+	// Err is a key used to add error values to label lists.
+	Err = NewError("error", "an error that occurred")
+	// Metric is a key used to indicate an event records metrics.
+	Metric = NewTag("metric", "a metric event marker")
+)
diff --git a/vendor/golang.org/x/tools/internal/event/label/label.go b/vendor/golang.org/x/tools/internal/event/label/label.go
new file mode 100644
index 0000000..0f526e1
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/event/label/label.go
@@ -0,0 +1,215 @@
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package label
+
+import (
+	"fmt"
+	"io"
+	"reflect"
+	"unsafe"
+)
+
+// Key is used as the identity of a Label.
+// Keys are intended to be compared by pointer only, the name should be unique
+// for communicating with external systems, but it is not required or enforced.
+type Key interface {
+	// Name returns the key name.
+	Name() string
+	// Description returns a string that can be used to describe the value.
+	Description() string
+
+	// Format is used in formatting to append the value of the label to the
+	// supplied buffer.
+	// The formatter may use the supplied buf as a scratch area to avoid
+	// allocations.
+	Format(w io.Writer, buf []byte, l Label)
+}
+
+// Label holds a key and value pair.
+// It is normally used when passing around lists of labels.
+type Label struct {
+	key     Key
+	packed  uint64
+	untyped interface{}
+}
+
+// Map is the interface to a collection of Labels indexed by key.
+type Map interface {
+	// Find returns the label that matches the supplied key.
+	Find(key Key) Label
+}
+
+// List is the interface to something that provides an iterable
+// list of labels.
+// Iteration should start from 0 and continue until Valid returns false.
+type List interface {
+	// Valid returns true if the index is within range for the list.
+	// It does not imply the label at that index will itself be valid.
+	Valid(index int) bool
+	// Label returns the label at the given index.
+	Label(index int) Label
+}
+
+// list implements LabelList for a list of Labels.
+type list struct {
+	labels []Label
+}
+
+// filter wraps a LabelList filtering out specific labels.
+type filter struct {
+	keys       []Key
+	underlying List
+}
+
+// listMap implements LabelMap for a simple list of labels.
+type listMap struct {
+	labels []Label
+}
+
+// mapChain implements LabelMap for a list of underlying LabelMap.
+type mapChain struct {
+	maps []Map
+}
+
+// OfValue creates a new label from the key and value.
+// This method is for implementing new key types, label creation should
+// normally be done with the Of method of the key.
+func OfValue(k Key, value interface{}) Label { return Label{key: k, untyped: value} }
+
+// UnpackValue assumes the label was built using LabelOfValue and returns the value
+// that was passed to that constructor.
+// This method is for implementing new key types, for type safety normal
+// access should be done with the From method of the key.
+func (t Label) UnpackValue() interface{} { return t.untyped }
+
+// Of64 creates a new label from a key and a uint64. This is often
+// used for non uint64 values that can be packed into a uint64.
+// This method is for implementing new key types, label creation should
+// normally be done with the Of method of the key.
+func Of64(k Key, v uint64) Label { return Label{key: k, packed: v} }
+
+// Unpack64 assumes the label was built using LabelOf64 and returns the value that
+// was passed to that constructor.
+// This method is for implementing new key types, for type safety normal
+// access should be done with the From method of the key.
+func (t Label) Unpack64() uint64 { return t.packed }
+
+type stringptr unsafe.Pointer
+
+// OfString creates a new label from a key and a string.
+// This method is for implementing new key types, label creation should
+// normally be done with the Of method of the key.
+func OfString(k Key, v string) Label {
+	hdr := (*reflect.StringHeader)(unsafe.Pointer(&v))
+	return Label{
+		key:     k,
+		packed:  uint64(hdr.Len),
+		untyped: stringptr(hdr.Data),
+	}
+}
+
+// UnpackString assumes the label was built using LabelOfString and returns the
+// value that was passed to that constructor.
+// This method is for implementing new key types, for type safety normal
+// access should be done with the From method of the key.
+func (t Label) UnpackString() string {
+	var v string
+	hdr := (*reflect.StringHeader)(unsafe.Pointer(&v))
+	hdr.Data = uintptr(t.untyped.(stringptr))
+	hdr.Len = int(t.packed)
+	return v
+}
+
+// Valid returns true if the Label is a valid one (it has a key).
+func (t Label) Valid() bool { return t.key != nil }
+
+// Key returns the key of this Label.
+func (t Label) Key() Key { return t.key }
+
+// Format is used for debug printing of labels.
+func (t Label) Format(f fmt.State, r rune) {
+	if !t.Valid() {
+		io.WriteString(f, `nil`)
+		return
+	}
+	io.WriteString(f, t.Key().Name())
+	io.WriteString(f, "=")
+	var buf [128]byte
+	t.Key().Format(f, buf[:0], t)
+}
+
+func (l *list) Valid(index int) bool {
+	return index >= 0 && index < len(l.labels)
+}
+
+func (l *list) Label(index int) Label {
+	return l.labels[index]
+}
+
+func (f *filter) Valid(index int) bool {
+	return f.underlying.Valid(index)
+}
+
+func (f *filter) Label(index int) Label {
+	l := f.underlying.Label(index)
+	for _, f := range f.keys {
+		if l.Key() == f {
+			return Label{}
+		}
+	}
+	return l
+}
+
+func (lm listMap) Find(key Key) Label {
+	for _, l := range lm.labels {
+		if l.Key() == key {
+			return l
+		}
+	}
+	return Label{}
+}
+
+func (c mapChain) Find(key Key) Label {
+	for _, src := range c.maps {
+		l := src.Find(key)
+		if l.Valid() {
+			return l
+		}
+	}
+	return Label{}
+}
+
+var emptyList = &list{}
+
+func NewList(labels ...Label) List {
+	if len(labels) == 0 {
+		return emptyList
+	}
+	return &list{labels: labels}
+}
+
+func Filter(l List, keys ...Key) List {
+	if len(keys) == 0 {
+		return l
+	}
+	return &filter{keys: keys, underlying: l}
+}
+
+func NewMap(labels ...Label) Map {
+	return listMap{labels: labels}
+}
+
+func MergeMaps(srcs ...Map) Map {
+	var nonNil []Map
+	for _, src := range srcs {
+		if src != nil {
+			nonNil = append(nonNil, src)
+		}
+	}
+	if len(nonNil) == 1 {
+		return nonNil[0]
+	}
+	return mapChain{maps: nonNil}
+}
diff --git a/vendor/golang.org/x/tools/internal/facts/facts.go b/vendor/golang.org/x/tools/internal/facts/facts.go
new file mode 100644
index 0000000..81df451
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/facts/facts.go
@@ -0,0 +1,335 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package facts defines a serializable set of analysis.Fact.
+//
+// It provides a partial implementation of the Fact-related parts of the
+// analysis.Pass interface for use in analysis drivers such as "go vet"
+// and other build systems.
+//
+// The serial format is unspecified and may change, so the same version
+// of this package must be used for reading and writing serialized facts.
+//
+// The handling of facts in the analysis system parallels the handling
+// of type information in the compiler: during compilation of package P,
+// the compiler emits an export data file that describes the type of
+// every object (named thing) defined in package P, plus every object
+// indirectly reachable from one of those objects. Thus the downstream
+// compiler of package Q need only load one export data file per direct
+// import of Q, and it will learn everything about the API of package P
+// and everything it needs to know about the API of P's dependencies.
+//
+// Similarly, analysis of package P emits a fact set containing facts
+// about all objects exported from P, plus additional facts about only
+// those objects of P's dependencies that are reachable from the API of
+// package P; the downstream analysis of Q need only load one fact set
+// per direct import of Q.
+//
+// The notion of "exportedness" that matters here is that of the
+// compiler. According to the language spec, a method pkg.T.f is
+// unexported simply because its name starts with lowercase. But the
+// compiler must nonetheless export f so that downstream compilations can
+// accurately ascertain whether pkg.T implements an interface pkg.I
+// defined as interface{f()}. Exported thus means "described in export
+// data".
+package facts
+
+import (
+	"bytes"
+	"encoding/gob"
+	"fmt"
+	"go/types"
+	"io/ioutil"
+	"log"
+	"reflect"
+	"sort"
+	"sync"
+
+	"golang.org/x/tools/go/analysis"
+	"golang.org/x/tools/go/types/objectpath"
+)
+
+const debug = false
+
+// A Set is a set of analysis.Facts.
+//
+// Decode creates a Set of facts by reading from the imports of a given
+// package, and Encode writes out the set. Between these operation,
+// the Import and Export methods will query and update the set.
+//
+// All of Set's methods except String are safe to call concurrently.
+type Set struct {
+	pkg *types.Package
+	mu  sync.Mutex
+	m   map[key]analysis.Fact
+}
+
+type key struct {
+	pkg *types.Package
+	obj types.Object // (object facts only)
+	t   reflect.Type
+}
+
+// ImportObjectFact implements analysis.Pass.ImportObjectFact.
+func (s *Set) ImportObjectFact(obj types.Object, ptr analysis.Fact) bool {
+	if obj == nil {
+		panic("nil object")
+	}
+	key := key{pkg: obj.Pkg(), obj: obj, t: reflect.TypeOf(ptr)}
+	s.mu.Lock()
+	defer s.mu.Unlock()
+	if v, ok := s.m[key]; ok {
+		reflect.ValueOf(ptr).Elem().Set(reflect.ValueOf(v).Elem())
+		return true
+	}
+	return false
+}
+
+// ExportObjectFact implements analysis.Pass.ExportObjectFact.
+func (s *Set) ExportObjectFact(obj types.Object, fact analysis.Fact) {
+	if obj.Pkg() != s.pkg {
+		log.Panicf("in package %s: ExportObjectFact(%s, %T): can't set fact on object belonging another package",
+			s.pkg, obj, fact)
+	}
+	key := key{pkg: obj.Pkg(), obj: obj, t: reflect.TypeOf(fact)}
+	s.mu.Lock()
+	s.m[key] = fact // clobber any existing entry
+	s.mu.Unlock()
+}
+
+func (s *Set) AllObjectFacts(filter map[reflect.Type]bool) []analysis.ObjectFact {
+	var facts []analysis.ObjectFact
+	s.mu.Lock()
+	for k, v := range s.m {
+		if k.obj != nil && filter[k.t] {
+			facts = append(facts, analysis.ObjectFact{Object: k.obj, Fact: v})
+		}
+	}
+	s.mu.Unlock()
+	return facts
+}
+
+// ImportPackageFact implements analysis.Pass.ImportPackageFact.
+func (s *Set) ImportPackageFact(pkg *types.Package, ptr analysis.Fact) bool {
+	if pkg == nil {
+		panic("nil package")
+	}
+	key := key{pkg: pkg, t: reflect.TypeOf(ptr)}
+	s.mu.Lock()
+	defer s.mu.Unlock()
+	if v, ok := s.m[key]; ok {
+		reflect.ValueOf(ptr).Elem().Set(reflect.ValueOf(v).Elem())
+		return true
+	}
+	return false
+}
+
+// ExportPackageFact implements analysis.Pass.ExportPackageFact.
+func (s *Set) ExportPackageFact(fact analysis.Fact) {
+	key := key{pkg: s.pkg, t: reflect.TypeOf(fact)}
+	s.mu.Lock()
+	s.m[key] = fact // clobber any existing entry
+	s.mu.Unlock()
+}
+
+func (s *Set) AllPackageFacts(filter map[reflect.Type]bool) []analysis.PackageFact {
+	var facts []analysis.PackageFact
+	s.mu.Lock()
+	for k, v := range s.m {
+		if k.obj == nil && filter[k.t] {
+			facts = append(facts, analysis.PackageFact{Package: k.pkg, Fact: v})
+		}
+	}
+	s.mu.Unlock()
+	return facts
+}
+
+// gobFact is the Gob declaration of a serialized fact.
+type gobFact struct {
+	PkgPath string          // path of package
+	Object  objectpath.Path // optional path of object relative to package itself
+	Fact    analysis.Fact   // type and value of user-defined Fact
+}
+
+// A Decoder decodes the facts from the direct imports of the package
+// provided to NewEncoder. A single decoder may be used to decode
+// multiple fact sets (e.g. each for a different set of fact types)
+// for the same package. Each call to Decode returns an independent
+// fact set.
+type Decoder struct {
+	pkg      *types.Package
+	packages map[string]*types.Package
+}
+
+// NewDecoder returns a fact decoder for the specified package.
+func NewDecoder(pkg *types.Package) *Decoder {
+	// Compute the import map for this package.
+	// See the package doc comment.
+	return &Decoder{pkg, importMap(pkg.Imports())}
+}
+
+// Decode decodes all the facts relevant to the analysis of package pkg.
+// The read function reads serialized fact data from an external source
+// for one of of pkg's direct imports. The empty file is a valid
+// encoding of an empty fact set.
+//
+// It is the caller's responsibility to call gob.Register on all
+// necessary fact types.
+func (d *Decoder) Decode(read func(*types.Package) ([]byte, error)) (*Set, error) {
+	// Read facts from imported packages.
+	// Facts may describe indirectly imported packages, or their objects.
+	m := make(map[key]analysis.Fact) // one big bucket
+	for _, imp := range d.pkg.Imports() {
+		logf := func(format string, args ...interface{}) {
+			if debug {
+				prefix := fmt.Sprintf("in %s, importing %s: ",
+					d.pkg.Path(), imp.Path())
+				log.Print(prefix, fmt.Sprintf(format, args...))
+			}
+		}
+
+		// Read the gob-encoded facts.
+		data, err := read(imp)
+		if err != nil {
+			return nil, fmt.Errorf("in %s, can't import facts for package %q: %v",
+				d.pkg.Path(), imp.Path(), err)
+		}
+		if len(data) == 0 {
+			continue // no facts
+		}
+		var gobFacts []gobFact
+		if err := gob.NewDecoder(bytes.NewReader(data)).Decode(&gobFacts); err != nil {
+			return nil, fmt.Errorf("decoding facts for %q: %v", imp.Path(), err)
+		}
+		if debug {
+			logf("decoded %d facts: %v", len(gobFacts), gobFacts)
+		}
+
+		// Parse each one into a key and a Fact.
+		for _, f := range gobFacts {
+			factPkg := d.packages[f.PkgPath]
+			if factPkg == nil {
+				// Fact relates to a dependency that was
+				// unused in this translation unit. Skip.
+				logf("no package %q; discarding %v", f.PkgPath, f.Fact)
+				continue
+			}
+			key := key{pkg: factPkg, t: reflect.TypeOf(f.Fact)}
+			if f.Object != "" {
+				// object fact
+				obj, err := objectpath.Object(factPkg, f.Object)
+				if err != nil {
+					// (most likely due to unexported object)
+					// TODO(adonovan): audit for other possibilities.
+					logf("no object for path: %v; discarding %s", err, f.Fact)
+					continue
+				}
+				key.obj = obj
+				logf("read %T fact %s for %v", f.Fact, f.Fact, key.obj)
+			} else {
+				// package fact
+				logf("read %T fact %s for %v", f.Fact, f.Fact, factPkg)
+			}
+			m[key] = f.Fact
+		}
+	}
+
+	return &Set{pkg: d.pkg, m: m}, nil
+}
+
+// Encode encodes a set of facts to a memory buffer.
+//
+// It may fail if one of the Facts could not be gob-encoded, but this is
+// a sign of a bug in an Analyzer.
+func (s *Set) Encode() []byte {
+
+	// TODO(adonovan): opt: use a more efficient encoding
+	// that avoids repeating PkgPath for each fact.
+
+	// Gather all facts, including those from imported packages.
+	var gobFacts []gobFact
+
+	s.mu.Lock()
+	for k, fact := range s.m {
+		if debug {
+			log.Printf("%v => %s\n", k, fact)
+		}
+		var object objectpath.Path
+		if k.obj != nil {
+			path, err := objectpath.For(k.obj)
+			if err != nil {
+				if debug {
+					log.Printf("discarding fact %s about %s\n", fact, k.obj)
+				}
+				continue // object not accessible from package API; discard fact
+			}
+			object = path
+		}
+		gobFacts = append(gobFacts, gobFact{
+			PkgPath: k.pkg.Path(),
+			Object:  object,
+			Fact:    fact,
+		})
+	}
+	s.mu.Unlock()
+
+	// Sort facts by (package, object, type) for determinism.
+	sort.Slice(gobFacts, func(i, j int) bool {
+		x, y := gobFacts[i], gobFacts[j]
+		if x.PkgPath != y.PkgPath {
+			return x.PkgPath < y.PkgPath
+		}
+		if x.Object != y.Object {
+			return x.Object < y.Object
+		}
+		tx := reflect.TypeOf(x.Fact)
+		ty := reflect.TypeOf(y.Fact)
+		if tx != ty {
+			return tx.String() < ty.String()
+		}
+		return false // equal
+	})
+
+	var buf bytes.Buffer
+	if len(gobFacts) > 0 {
+		if err := gob.NewEncoder(&buf).Encode(gobFacts); err != nil {
+			// Fact encoding should never fail. Identify the culprit.
+			for _, gf := range gobFacts {
+				if err := gob.NewEncoder(ioutil.Discard).Encode(gf); err != nil {
+					fact := gf.Fact
+					pkgpath := reflect.TypeOf(fact).Elem().PkgPath()
+					log.Panicf("internal error: gob encoding of analysis fact %s failed: %v; please report a bug against fact %T in package %q",
+						fact, err, fact, pkgpath)
+				}
+			}
+		}
+	}
+
+	if debug {
+		log.Printf("package %q: encode %d facts, %d bytes\n",
+			s.pkg.Path(), len(gobFacts), buf.Len())
+	}
+
+	return buf.Bytes()
+}
+
+// String is provided only for debugging, and must not be called
+// concurrent with any Import/Export method.
+func (s *Set) String() string {
+	var buf bytes.Buffer
+	buf.WriteString("{")
+	for k, f := range s.m {
+		if buf.Len() > 1 {
+			buf.WriteString(", ")
+		}
+		if k.obj != nil {
+			buf.WriteString(k.obj.String())
+		} else {
+			buf.WriteString(k.pkg.Path())
+		}
+		fmt.Fprintf(&buf, ": %v", f)
+	}
+	buf.WriteString("}")
+	return buf.String()
+}
diff --git a/vendor/golang.org/x/tools/internal/facts/imports.go b/vendor/golang.org/x/tools/internal/facts/imports.go
new file mode 100644
index 0000000..7b21668
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/facts/imports.go
@@ -0,0 +1,130 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package facts
+
+import (
+	"go/types"
+
+	"golang.org/x/tools/internal/typeparams"
+)
+
+// importMap computes the import map for a package by traversing the
+// entire exported API each of its imports.
+//
+// This is a workaround for the fact that we cannot access the map used
+// internally by the types.Importer returned by go/importer. The entries
+// in this map are the packages and objects that may be relevant to the
+// current analysis unit.
+//
+// Packages in the map that are only indirectly imported may be
+// incomplete (!pkg.Complete()).
+//
+// TODO(adonovan): opt: compute this information more efficiently
+// by obtaining it from the internals of the gcexportdata decoder.
+func importMap(imports []*types.Package) map[string]*types.Package {
+	objects := make(map[types.Object]bool)
+	typs := make(map[types.Type]bool) // Named and TypeParam
+	packages := make(map[string]*types.Package)
+
+	var addObj func(obj types.Object)
+	var addType func(T types.Type)
+
+	addObj = func(obj types.Object) {
+		if !objects[obj] {
+			objects[obj] = true
+			addType(obj.Type())
+			if pkg := obj.Pkg(); pkg != nil {
+				packages[pkg.Path()] = pkg
+			}
+		}
+	}
+
+	addType = func(T types.Type) {
+		switch T := T.(type) {
+		case *types.Basic:
+			// nop
+		case *types.Named:
+			// Remove infinite expansions of *types.Named by always looking at the origin.
+			// Some named types with type parameters [that will not type check] have
+			// infinite expansions:
+			//     type N[T any] struct { F *N[N[T]] }
+			// importMap() is called on such types when Analyzer.RunDespiteErrors is true.
+			T = typeparams.NamedTypeOrigin(T).(*types.Named)
+			if !typs[T] {
+				typs[T] = true
+				addObj(T.Obj())
+				addType(T.Underlying())
+				for i := 0; i < T.NumMethods(); i++ {
+					addObj(T.Method(i))
+				}
+				if tparams := typeparams.ForNamed(T); tparams != nil {
+					for i := 0; i < tparams.Len(); i++ {
+						addType(tparams.At(i))
+					}
+				}
+				if targs := typeparams.NamedTypeArgs(T); targs != nil {
+					for i := 0; i < targs.Len(); i++ {
+						addType(targs.At(i))
+					}
+				}
+			}
+		case *types.Pointer:
+			addType(T.Elem())
+		case *types.Slice:
+			addType(T.Elem())
+		case *types.Array:
+			addType(T.Elem())
+		case *types.Chan:
+			addType(T.Elem())
+		case *types.Map:
+			addType(T.Key())
+			addType(T.Elem())
+		case *types.Signature:
+			addType(T.Params())
+			addType(T.Results())
+			if tparams := typeparams.ForSignature(T); tparams != nil {
+				for i := 0; i < tparams.Len(); i++ {
+					addType(tparams.At(i))
+				}
+			}
+		case *types.Struct:
+			for i := 0; i < T.NumFields(); i++ {
+				addObj(T.Field(i))
+			}
+		case *types.Tuple:
+			for i := 0; i < T.Len(); i++ {
+				addObj(T.At(i))
+			}
+		case *types.Interface:
+			for i := 0; i < T.NumMethods(); i++ {
+				addObj(T.Method(i))
+			}
+			for i := 0; i < T.NumEmbeddeds(); i++ {
+				addType(T.EmbeddedType(i)) // walk Embedded for implicits
+			}
+		case *typeparams.Union:
+			for i := 0; i < T.Len(); i++ {
+				addType(T.Term(i).Type())
+			}
+		case *typeparams.TypeParam:
+			if !typs[T] {
+				typs[T] = true
+				addObj(T.Obj())
+				addType(T.Constraint())
+			}
+		}
+	}
+
+	for _, imp := range imports {
+		packages[imp.Path()] = imp
+
+		scope := imp.Scope()
+		for _, name := range scope.Names() {
+			addObj(scope.Lookup(name))
+		}
+	}
+
+	return packages
+}
diff --git a/vendor/golang.org/x/tools/internal/gcimporter/bexport.go b/vendor/golang.org/x/tools/internal/gcimporter/bexport.go
new file mode 100644
index 0000000..30582ed
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/gcimporter/bexport.go
@@ -0,0 +1,852 @@
+// Copyright 2016 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Binary package export.
+// This file was derived from $GOROOT/src/cmd/compile/internal/gc/bexport.go;
+// see that file for specification of the format.
+
+package gcimporter
+
+import (
+	"bytes"
+	"encoding/binary"
+	"fmt"
+	"go/constant"
+	"go/token"
+	"go/types"
+	"math"
+	"math/big"
+	"sort"
+	"strings"
+)
+
+// If debugFormat is set, each integer and string value is preceded by a marker
+// and position information in the encoding. This mechanism permits an importer
+// to recognize immediately when it is out of sync. The importer recognizes this
+// mode automatically (i.e., it can import export data produced with debugging
+// support even if debugFormat is not set at the time of import). This mode will
+// lead to massively larger export data (by a factor of 2 to 3) and should only
+// be enabled during development and debugging.
+//
+// NOTE: This flag is the first flag to enable if importing dies because of
+// (suspected) format errors, and whenever a change is made to the format.
+const debugFormat = false // default: false
+
+// Current export format version. Increase with each format change.
+//
+// Note: The latest binary (non-indexed) export format is at version 6.
+// This exporter is still at level 4, but it doesn't matter since
+// the binary importer can handle older versions just fine.
+//
+//	6: package height (CL 105038) -- NOT IMPLEMENTED HERE
+//	5: improved position encoding efficiency (issue 20080, CL 41619) -- NOT IMPLEMENTED HERE
+//	4: type name objects support type aliases, uses aliasTag
+//	3: Go1.8 encoding (same as version 2, aliasTag defined but never used)
+//	2: removed unused bool in ODCL export (compiler only)
+//	1: header format change (more regular), export package for _ struct fields
+//	0: Go1.7 encoding
+const exportVersion = 4
+
+// trackAllTypes enables cycle tracking for all types, not just named
+// types. The existing compiler invariants assume that unnamed types
+// that are not completely set up are not used, or else there are spurious
+// errors.
+// If disabled, only named types are tracked, possibly leading to slightly
+// less efficient encoding in rare cases. It also prevents the export of
+// some corner-case type declarations (but those are not handled correctly
+// with with the textual export format either).
+// TODO(gri) enable and remove once issues caused by it are fixed
+const trackAllTypes = false
+
+type exporter struct {
+	fset *token.FileSet
+	out  bytes.Buffer
+
+	// object -> index maps, indexed in order of serialization
+	strIndex map[string]int
+	pkgIndex map[*types.Package]int
+	typIndex map[types.Type]int
+
+	// position encoding
+	posInfoFormat bool
+	prevFile      string
+	prevLine      int
+
+	// debugging support
+	written int // bytes written
+	indent  int // for trace
+}
+
+// internalError represents an error generated inside this package.
+type internalError string
+
+func (e internalError) Error() string { return "gcimporter: " + string(e) }
+
+func internalErrorf(format string, args ...interface{}) error {
+	return internalError(fmt.Sprintf(format, args...))
+}
+
+// BExportData returns binary export data for pkg.
+// If no file set is provided, position info will be missing.
+func BExportData(fset *token.FileSet, pkg *types.Package) (b []byte, err error) {
+	if !debug {
+		defer func() {
+			if e := recover(); e != nil {
+				if ierr, ok := e.(internalError); ok {
+					err = ierr
+					return
+				}
+				// Not an internal error; panic again.
+				panic(e)
+			}
+		}()
+	}
+
+	p := exporter{
+		fset:          fset,
+		strIndex:      map[string]int{"": 0}, // empty string is mapped to 0
+		pkgIndex:      make(map[*types.Package]int),
+		typIndex:      make(map[types.Type]int),
+		posInfoFormat: true, // TODO(gri) might become a flag, eventually
+	}
+
+	// write version info
+	// The version string must start with "version %d" where %d is the version
+	// number. Additional debugging information may follow after a blank; that
+	// text is ignored by the importer.
+	p.rawStringln(fmt.Sprintf("version %d", exportVersion))
+	var debug string
+	if debugFormat {
+		debug = "debug"
+	}
+	p.rawStringln(debug) // cannot use p.bool since it's affected by debugFormat; also want to see this clearly
+	p.bool(trackAllTypes)
+	p.bool(p.posInfoFormat)
+
+	// --- generic export data ---
+
+	// populate type map with predeclared "known" types
+	for index, typ := range predeclared() {
+		p.typIndex[typ] = index
+	}
+	if len(p.typIndex) != len(predeclared()) {
+		return nil, internalError("duplicate entries in type map?")
+	}
+
+	// write package data
+	p.pkg(pkg, true)
+	if trace {
+		p.tracef("\n")
+	}
+
+	// write objects
+	objcount := 0
+	scope := pkg.Scope()
+	for _, name := range scope.Names() {
+		if !token.IsExported(name) {
+			continue
+		}
+		if trace {
+			p.tracef("\n")
+		}
+		p.obj(scope.Lookup(name))
+		objcount++
+	}
+
+	// indicate end of list
+	if trace {
+		p.tracef("\n")
+	}
+	p.tag(endTag)
+
+	// for self-verification only (redundant)
+	p.int(objcount)
+
+	if trace {
+		p.tracef("\n")
+	}
+
+	// --- end of export data ---
+
+	return p.out.Bytes(), nil
+}
+
+func (p *exporter) pkg(pkg *types.Package, emptypath bool) {
+	if pkg == nil {
+		panic(internalError("unexpected nil pkg"))
+	}
+
+	// if we saw the package before, write its index (>= 0)
+	if i, ok := p.pkgIndex[pkg]; ok {
+		p.index('P', i)
+		return
+	}
+
+	// otherwise, remember the package, write the package tag (< 0) and package data
+	if trace {
+		p.tracef("P%d = { ", len(p.pkgIndex))
+		defer p.tracef("} ")
+	}
+	p.pkgIndex[pkg] = len(p.pkgIndex)
+
+	p.tag(packageTag)
+	p.string(pkg.Name())
+	if emptypath {
+		p.string("")
+	} else {
+		p.string(pkg.Path())
+	}
+}
+
+func (p *exporter) obj(obj types.Object) {
+	switch obj := obj.(type) {
+	case *types.Const:
+		p.tag(constTag)
+		p.pos(obj)
+		p.qualifiedName(obj)
+		p.typ(obj.Type())
+		p.value(obj.Val())
+
+	case *types.TypeName:
+		if obj.IsAlias() {
+			p.tag(aliasTag)
+			p.pos(obj)
+			p.qualifiedName(obj)
+		} else {
+			p.tag(typeTag)
+		}
+		p.typ(obj.Type())
+
+	case *types.Var:
+		p.tag(varTag)
+		p.pos(obj)
+		p.qualifiedName(obj)
+		p.typ(obj.Type())
+
+	case *types.Func:
+		p.tag(funcTag)
+		p.pos(obj)
+		p.qualifiedName(obj)
+		sig := obj.Type().(*types.Signature)
+		p.paramList(sig.Params(), sig.Variadic())
+		p.paramList(sig.Results(), false)
+
+	default:
+		panic(internalErrorf("unexpected object %v (%T)", obj, obj))
+	}
+}
+
+func (p *exporter) pos(obj types.Object) {
+	if !p.posInfoFormat {
+		return
+	}
+
+	file, line := p.fileLine(obj)
+	if file == p.prevFile {
+		// common case: write line delta
+		// delta == 0 means different file or no line change
+		delta := line - p.prevLine
+		p.int(delta)
+		if delta == 0 {
+			p.int(-1) // -1 means no file change
+		}
+	} else {
+		// different file
+		p.int(0)
+		// Encode filename as length of common prefix with previous
+		// filename, followed by (possibly empty) suffix. Filenames
+		// frequently share path prefixes, so this can save a lot
+		// of space and make export data size less dependent on file
+		// path length. The suffix is unlikely to be empty because
+		// file names tend to end in ".go".
+		n := commonPrefixLen(p.prevFile, file)
+		p.int(n)           // n >= 0
+		p.string(file[n:]) // write suffix only
+		p.prevFile = file
+		p.int(line)
+	}
+	p.prevLine = line
+}
+
+func (p *exporter) fileLine(obj types.Object) (file string, line int) {
+	if p.fset != nil {
+		pos := p.fset.Position(obj.Pos())
+		file = pos.Filename
+		line = pos.Line
+	}
+	return
+}
+
+func commonPrefixLen(a, b string) int {
+	if len(a) > len(b) {
+		a, b = b, a
+	}
+	// len(a) <= len(b)
+	i := 0
+	for i < len(a) && a[i] == b[i] {
+		i++
+	}
+	return i
+}
+
+func (p *exporter) qualifiedName(obj types.Object) {
+	p.string(obj.Name())
+	p.pkg(obj.Pkg(), false)
+}
+
+func (p *exporter) typ(t types.Type) {
+	if t == nil {
+		panic(internalError("nil type"))
+	}
+
+	// Possible optimization: Anonymous pointer types *T where
+	// T is a named type are common. We could canonicalize all
+	// such types *T to a single type PT = *T. This would lead
+	// to at most one *T entry in typIndex, and all future *T's
+	// would be encoded as the respective index directly. Would
+	// save 1 byte (pointerTag) per *T and reduce the typIndex
+	// size (at the cost of a canonicalization map). We can do
+	// this later, without encoding format change.
+
+	// if we saw the type before, write its index (>= 0)
+	if i, ok := p.typIndex[t]; ok {
+		p.index('T', i)
+		return
+	}
+
+	// otherwise, remember the type, write the type tag (< 0) and type data
+	if trackAllTypes {
+		if trace {
+			p.tracef("T%d = {>\n", len(p.typIndex))
+			defer p.tracef("<\n} ")
+		}
+		p.typIndex[t] = len(p.typIndex)
+	}
+
+	switch t := t.(type) {
+	case *types.Named:
+		if !trackAllTypes {
+			// if we don't track all types, track named types now
+			p.typIndex[t] = len(p.typIndex)
+		}
+
+		p.tag(namedTag)
+		p.pos(t.Obj())
+		p.qualifiedName(t.Obj())
+		p.typ(t.Underlying())
+		if !types.IsInterface(t) {
+			p.assocMethods(t)
+		}
+
+	case *types.Array:
+		p.tag(arrayTag)
+		p.int64(t.Len())
+		p.typ(t.Elem())
+
+	case *types.Slice:
+		p.tag(sliceTag)
+		p.typ(t.Elem())
+
+	case *dddSlice:
+		p.tag(dddTag)
+		p.typ(t.elem)
+
+	case *types.Struct:
+		p.tag(structTag)
+		p.fieldList(t)
+
+	case *types.Pointer:
+		p.tag(pointerTag)
+		p.typ(t.Elem())
+
+	case *types.Signature:
+		p.tag(signatureTag)
+		p.paramList(t.Params(), t.Variadic())
+		p.paramList(t.Results(), false)
+
+	case *types.Interface:
+		p.tag(interfaceTag)
+		p.iface(t)
+
+	case *types.Map:
+		p.tag(mapTag)
+		p.typ(t.Key())
+		p.typ(t.Elem())
+
+	case *types.Chan:
+		p.tag(chanTag)
+		p.int(int(3 - t.Dir())) // hack
+		p.typ(t.Elem())
+
+	default:
+		panic(internalErrorf("unexpected type %T: %s", t, t))
+	}
+}
+
+func (p *exporter) assocMethods(named *types.Named) {
+	// Sort methods (for determinism).
+	var methods []*types.Func
+	for i := 0; i < named.NumMethods(); i++ {
+		methods = append(methods, named.Method(i))
+	}
+	sort.Sort(methodsByName(methods))
+
+	p.int(len(methods))
+
+	if trace && methods != nil {
+		p.tracef("associated methods {>\n")
+	}
+
+	for i, m := range methods {
+		if trace && i > 0 {
+			p.tracef("\n")
+		}
+
+		p.pos(m)
+		name := m.Name()
+		p.string(name)
+		if !exported(name) {
+			p.pkg(m.Pkg(), false)
+		}
+
+		sig := m.Type().(*types.Signature)
+		p.paramList(types.NewTuple(sig.Recv()), false)
+		p.paramList(sig.Params(), sig.Variadic())
+		p.paramList(sig.Results(), false)
+		p.int(0) // dummy value for go:nointerface pragma - ignored by importer
+	}
+
+	if trace && methods != nil {
+		p.tracef("<\n} ")
+	}
+}
+
+type methodsByName []*types.Func
+
+func (x methodsByName) Len() int           { return len(x) }
+func (x methodsByName) Swap(i, j int)      { x[i], x[j] = x[j], x[i] }
+func (x methodsByName) Less(i, j int) bool { return x[i].Name() < x[j].Name() }
+
+func (p *exporter) fieldList(t *types.Struct) {
+	if trace && t.NumFields() > 0 {
+		p.tracef("fields {>\n")
+		defer p.tracef("<\n} ")
+	}
+
+	p.int(t.NumFields())
+	for i := 0; i < t.NumFields(); i++ {
+		if trace && i > 0 {
+			p.tracef("\n")
+		}
+		p.field(t.Field(i))
+		p.string(t.Tag(i))
+	}
+}
+
+func (p *exporter) field(f *types.Var) {
+	if !f.IsField() {
+		panic(internalError("field expected"))
+	}
+
+	p.pos(f)
+	p.fieldName(f)
+	p.typ(f.Type())
+}
+
+func (p *exporter) iface(t *types.Interface) {
+	// TODO(gri): enable importer to load embedded interfaces,
+	// then emit Embeddeds and ExplicitMethods separately here.
+	p.int(0)
+
+	n := t.NumMethods()
+	if trace && n > 0 {
+		p.tracef("methods {>\n")
+		defer p.tracef("<\n} ")
+	}
+	p.int(n)
+	for i := 0; i < n; i++ {
+		if trace && i > 0 {
+			p.tracef("\n")
+		}
+		p.method(t.Method(i))
+	}
+}
+
+func (p *exporter) method(m *types.Func) {
+	sig := m.Type().(*types.Signature)
+	if sig.Recv() == nil {
+		panic(internalError("method expected"))
+	}
+
+	p.pos(m)
+	p.string(m.Name())
+	if m.Name() != "_" && !token.IsExported(m.Name()) {
+		p.pkg(m.Pkg(), false)
+	}
+
+	// interface method; no need to encode receiver.
+	p.paramList(sig.Params(), sig.Variadic())
+	p.paramList(sig.Results(), false)
+}
+
+func (p *exporter) fieldName(f *types.Var) {
+	name := f.Name()
+
+	if f.Anonymous() {
+		// anonymous field - we distinguish between 3 cases:
+		// 1) field name matches base type name and is exported
+		// 2) field name matches base type name and is not exported
+		// 3) field name doesn't match base type name (alias name)
+		bname := basetypeName(f.Type())
+		if name == bname {
+			if token.IsExported(name) {
+				name = "" // 1) we don't need to know the field name or package
+			} else {
+				name = "?" // 2) use unexported name "?" to force package export
+			}
+		} else {
+			// 3) indicate alias and export name as is
+			// (this requires an extra "@" but this is a rare case)
+			p.string("@")
+		}
+	}
+
+	p.string(name)
+	if name != "" && !token.IsExported(name) {
+		p.pkg(f.Pkg(), false)
+	}
+}
+
+func basetypeName(typ types.Type) string {
+	switch typ := deref(typ).(type) {
+	case *types.Basic:
+		return typ.Name()
+	case *types.Named:
+		return typ.Obj().Name()
+	default:
+		return "" // unnamed type
+	}
+}
+
+func (p *exporter) paramList(params *types.Tuple, variadic bool) {
+	// use negative length to indicate unnamed parameters
+	// (look at the first parameter only since either all
+	// names are present or all are absent)
+	n := params.Len()
+	if n > 0 && params.At(0).Name() == "" {
+		n = -n
+	}
+	p.int(n)
+	for i := 0; i < params.Len(); i++ {
+		q := params.At(i)
+		t := q.Type()
+		if variadic && i == params.Len()-1 {
+			t = &dddSlice{t.(*types.Slice).Elem()}
+		}
+		p.typ(t)
+		if n > 0 {
+			name := q.Name()
+			p.string(name)
+			if name != "_" {
+				p.pkg(q.Pkg(), false)
+			}
+		}
+		p.string("") // no compiler-specific info
+	}
+}
+
+func (p *exporter) value(x constant.Value) {
+	if trace {
+		p.tracef("= ")
+	}
+
+	switch x.Kind() {
+	case constant.Bool:
+		tag := falseTag
+		if constant.BoolVal(x) {
+			tag = trueTag
+		}
+		p.tag(tag)
+
+	case constant.Int:
+		if v, exact := constant.Int64Val(x); exact {
+			// common case: x fits into an int64 - use compact encoding
+			p.tag(int64Tag)
+			p.int64(v)
+			return
+		}
+		// uncommon case: large x - use float encoding
+		// (powers of 2 will be encoded efficiently with exponent)
+		p.tag(floatTag)
+		p.float(constant.ToFloat(x))
+
+	case constant.Float:
+		p.tag(floatTag)
+		p.float(x)
+
+	case constant.Complex:
+		p.tag(complexTag)
+		p.float(constant.Real(x))
+		p.float(constant.Imag(x))
+
+	case constant.String:
+		p.tag(stringTag)
+		p.string(constant.StringVal(x))
+
+	case constant.Unknown:
+		// package contains type errors
+		p.tag(unknownTag)
+
+	default:
+		panic(internalErrorf("unexpected value %v (%T)", x, x))
+	}
+}
+
+func (p *exporter) float(x constant.Value) {
+	if x.Kind() != constant.Float {
+		panic(internalErrorf("unexpected constant %v, want float", x))
+	}
+	// extract sign (there is no -0)
+	sign := constant.Sign(x)
+	if sign == 0 {
+		// x == 0
+		p.int(0)
+		return
+	}
+	// x != 0
+
+	var f big.Float
+	if v, exact := constant.Float64Val(x); exact {
+		// float64
+		f.SetFloat64(v)
+	} else if num, denom := constant.Num(x), constant.Denom(x); num.Kind() == constant.Int {
+		// TODO(gri): add big.Rat accessor to constant.Value.
+		r := valueToRat(num)
+		f.SetRat(r.Quo(r, valueToRat(denom)))
+	} else {
+		// Value too large to represent as a fraction => inaccessible.
+		// TODO(gri): add big.Float accessor to constant.Value.
+		f.SetFloat64(math.MaxFloat64) // FIXME
+	}
+
+	// extract exponent such that 0.5 <= m < 1.0
+	var m big.Float
+	exp := f.MantExp(&m)
+
+	// extract mantissa as *big.Int
+	// - set exponent large enough so mant satisfies mant.IsInt()
+	// - get *big.Int from mant
+	m.SetMantExp(&m, int(m.MinPrec()))
+	mant, acc := m.Int(nil)
+	if acc != big.Exact {
+		panic(internalError("internal error"))
+	}
+
+	p.int(sign)
+	p.int(exp)
+	p.string(string(mant.Bytes()))
+}
+
+func valueToRat(x constant.Value) *big.Rat {
+	// Convert little-endian to big-endian.
+	// I can't believe this is necessary.
+	bytes := constant.Bytes(x)
+	for i := 0; i < len(bytes)/2; i++ {
+		bytes[i], bytes[len(bytes)-1-i] = bytes[len(bytes)-1-i], bytes[i]
+	}
+	return new(big.Rat).SetInt(new(big.Int).SetBytes(bytes))
+}
+
+func (p *exporter) bool(b bool) bool {
+	if trace {
+		p.tracef("[")
+		defer p.tracef("= %v] ", b)
+	}
+
+	x := 0
+	if b {
+		x = 1
+	}
+	p.int(x)
+	return b
+}
+
+// ----------------------------------------------------------------------------
+// Low-level encoders
+
+func (p *exporter) index(marker byte, index int) {
+	if index < 0 {
+		panic(internalError("invalid index < 0"))
+	}
+	if debugFormat {
+		p.marker('t')
+	}
+	if trace {
+		p.tracef("%c%d ", marker, index)
+	}
+	p.rawInt64(int64(index))
+}
+
+func (p *exporter) tag(tag int) {
+	if tag >= 0 {
+		panic(internalError("invalid tag >= 0"))
+	}
+	if debugFormat {
+		p.marker('t')
+	}
+	if trace {
+		p.tracef("%s ", tagString[-tag])
+	}
+	p.rawInt64(int64(tag))
+}
+
+func (p *exporter) int(x int) {
+	p.int64(int64(x))
+}
+
+func (p *exporter) int64(x int64) {
+	if debugFormat {
+		p.marker('i')
+	}
+	if trace {
+		p.tracef("%d ", x)
+	}
+	p.rawInt64(x)
+}
+
+func (p *exporter) string(s string) {
+	if debugFormat {
+		p.marker('s')
+	}
+	if trace {
+		p.tracef("%q ", s)
+	}
+	// if we saw the string before, write its index (>= 0)
+	// (the empty string is mapped to 0)
+	if i, ok := p.strIndex[s]; ok {
+		p.rawInt64(int64(i))
+		return
+	}
+	// otherwise, remember string and write its negative length and bytes
+	p.strIndex[s] = len(p.strIndex)
+	p.rawInt64(-int64(len(s)))
+	for i := 0; i < len(s); i++ {
+		p.rawByte(s[i])
+	}
+}
+
+// marker emits a marker byte and position information which makes
+// it easy for a reader to detect if it is "out of sync". Used for
+// debugFormat format only.
+func (p *exporter) marker(m byte) {
+	p.rawByte(m)
+	// Enable this for help tracking down the location
+	// of an incorrect marker when running in debugFormat.
+	if false && trace {
+		p.tracef("#%d ", p.written)
+	}
+	p.rawInt64(int64(p.written))
+}
+
+// rawInt64 should only be used by low-level encoders.
+func (p *exporter) rawInt64(x int64) {
+	var tmp [binary.MaxVarintLen64]byte
+	n := binary.PutVarint(tmp[:], x)
+	for i := 0; i < n; i++ {
+		p.rawByte(tmp[i])
+	}
+}
+
+// rawStringln should only be used to emit the initial version string.
+func (p *exporter) rawStringln(s string) {
+	for i := 0; i < len(s); i++ {
+		p.rawByte(s[i])
+	}
+	p.rawByte('\n')
+}
+
+// rawByte is the bottleneck interface to write to p.out.
+// rawByte escapes b as follows (any encoding does that
+// hides '$'):
+//
+//	'$'  => '|' 'S'
+//	'|'  => '|' '|'
+//
+// Necessary so other tools can find the end of the
+// export data by searching for "$$".
+// rawByte should only be used by low-level encoders.
+func (p *exporter) rawByte(b byte) {
+	switch b {
+	case '$':
+		// write '$' as '|' 'S'
+		b = 'S'
+		fallthrough
+	case '|':
+		// write '|' as '|' '|'
+		p.out.WriteByte('|')
+		p.written++
+	}
+	p.out.WriteByte(b)
+	p.written++
+}
+
+// tracef is like fmt.Printf but it rewrites the format string
+// to take care of indentation.
+func (p *exporter) tracef(format string, args ...interface{}) {
+	if strings.ContainsAny(format, "<>\n") {
+		var buf bytes.Buffer
+		for i := 0; i < len(format); i++ {
+			// no need to deal with runes
+			ch := format[i]
+			switch ch {
+			case '>':
+				p.indent++
+				continue
+			case '<':
+				p.indent--
+				continue
+			}
+			buf.WriteByte(ch)
+			if ch == '\n' {
+				for j := p.indent; j > 0; j-- {
+					buf.WriteString(".  ")
+				}
+			}
+		}
+		format = buf.String()
+	}
+	fmt.Printf(format, args...)
+}
+
+// Debugging support.
+// (tagString is only used when tracing is enabled)
+var tagString = [...]string{
+	// Packages
+	-packageTag: "package",
+
+	// Types
+	-namedTag:     "named type",
+	-arrayTag:     "array",
+	-sliceTag:     "slice",
+	-dddTag:       "ddd",
+	-structTag:    "struct",
+	-pointerTag:   "pointer",
+	-signatureTag: "signature",
+	-interfaceTag: "interface",
+	-mapTag:       "map",
+	-chanTag:      "chan",
+
+	// Values
+	-falseTag:    "false",
+	-trueTag:     "true",
+	-int64Tag:    "int64",
+	-floatTag:    "float",
+	-fractionTag: "fraction",
+	-complexTag:  "complex",
+	-stringTag:   "string",
+	-unknownTag:  "unknown",
+
+	// Type aliases
+	-aliasTag: "alias",
+}
diff --git a/vendor/golang.org/x/tools/internal/gcimporter/bimport.go b/vendor/golang.org/x/tools/internal/gcimporter/bimport.go
new file mode 100644
index 0000000..b85de01
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/gcimporter/bimport.go
@@ -0,0 +1,1053 @@
+// Copyright 2015 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This file is a copy of $GOROOT/src/go/internal/gcimporter/bimport.go.
+
+package gcimporter
+
+import (
+	"encoding/binary"
+	"fmt"
+	"go/constant"
+	"go/token"
+	"go/types"
+	"sort"
+	"strconv"
+	"strings"
+	"sync"
+	"unicode"
+	"unicode/utf8"
+)
+
+type importer struct {
+	imports    map[string]*types.Package
+	data       []byte
+	importpath string
+	buf        []byte // for reading strings
+	version    int    // export format version
+
+	// object lists
+	strList       []string           // in order of appearance
+	pathList      []string           // in order of appearance
+	pkgList       []*types.Package   // in order of appearance
+	typList       []types.Type       // in order of appearance
+	interfaceList []*types.Interface // for delayed completion only
+	trackAllTypes bool
+
+	// position encoding
+	posInfoFormat bool
+	prevFile      string
+	prevLine      int
+	fake          fakeFileSet
+
+	// debugging support
+	debugFormat bool
+	read        int // bytes read
+}
+
+// BImportData imports a package from the serialized package data
+// and returns the number of bytes consumed and a reference to the package.
+// If the export data version is not recognized or the format is otherwise
+// compromised, an error is returned.
+func BImportData(fset *token.FileSet, imports map[string]*types.Package, data []byte, path string) (_ int, pkg *types.Package, err error) {
+	// catch panics and return them as errors
+	const currentVersion = 6
+	version := -1 // unknown version
+	defer func() {
+		if e := recover(); e != nil {
+			// Return a (possibly nil or incomplete) package unchanged (see #16088).
+			if version > currentVersion {
+				err = fmt.Errorf("cannot import %q (%v), export data is newer version - update tool", path, e)
+			} else {
+				err = fmt.Errorf("cannot import %q (%v), possibly version skew - reinstall package", path, e)
+			}
+		}
+	}()
+
+	p := importer{
+		imports:    imports,
+		data:       data,
+		importpath: path,
+		version:    version,
+		strList:    []string{""}, // empty string is mapped to 0
+		pathList:   []string{""}, // empty string is mapped to 0
+		fake: fakeFileSet{
+			fset:  fset,
+			files: make(map[string]*fileInfo),
+		},
+	}
+	defer p.fake.setLines() // set lines for files in fset
+
+	// read version info
+	var versionstr string
+	if b := p.rawByte(); b == 'c' || b == 'd' {
+		// Go1.7 encoding; first byte encodes low-level
+		// encoding format (compact vs debug).
+		// For backward-compatibility only (avoid problems with
+		// old installed packages). Newly compiled packages use
+		// the extensible format string.
+		// TODO(gri) Remove this support eventually; after Go1.8.
+		if b == 'd' {
+			p.debugFormat = true
+		}
+		p.trackAllTypes = p.rawByte() == 'a'
+		p.posInfoFormat = p.int() != 0
+		versionstr = p.string()
+		if versionstr == "v1" {
+			version = 0
+		}
+	} else {
+		// Go1.8 extensible encoding
+		// read version string and extract version number (ignore anything after the version number)
+		versionstr = p.rawStringln(b)
+		if s := strings.SplitN(versionstr, " ", 3); len(s) >= 2 && s[0] == "version" {
+			if v, err := strconv.Atoi(s[1]); err == nil && v > 0 {
+				version = v
+			}
+		}
+	}
+	p.version = version
+
+	// read version specific flags - extend as necessary
+	switch p.version {
+	// case currentVersion:
+	// 	...
+	//	fallthrough
+	case currentVersion, 5, 4, 3, 2, 1:
+		p.debugFormat = p.rawStringln(p.rawByte()) == "debug"
+		p.trackAllTypes = p.int() != 0
+		p.posInfoFormat = p.int() != 0
+	case 0:
+		// Go1.7 encoding format - nothing to do here
+	default:
+		errorf("unknown bexport format version %d (%q)", p.version, versionstr)
+	}
+
+	// --- generic export data ---
+
+	// populate typList with predeclared "known" types
+	p.typList = append(p.typList, predeclared()...)
+
+	// read package data
+	pkg = p.pkg()
+
+	// read objects of phase 1 only (see cmd/compile/internal/gc/bexport.go)
+	objcount := 0
+	for {
+		tag := p.tagOrIndex()
+		if tag == endTag {
+			break
+		}
+		p.obj(tag)
+		objcount++
+	}
+
+	// self-verification
+	if count := p.int(); count != objcount {
+		errorf("got %d objects; want %d", objcount, count)
+	}
+
+	// ignore compiler-specific import data
+
+	// complete interfaces
+	// TODO(gri) re-investigate if we still need to do this in a delayed fashion
+	for _, typ := range p.interfaceList {
+		typ.Complete()
+	}
+
+	// record all referenced packages as imports
+	list := append(([]*types.Package)(nil), p.pkgList[1:]...)
+	sort.Sort(byPath(list))
+	pkg.SetImports(list)
+
+	// package was imported completely and without errors
+	pkg.MarkComplete()
+
+	return p.read, pkg, nil
+}
+
+func errorf(format string, args ...interface{}) {
+	panic(fmt.Sprintf(format, args...))
+}
+
+func (p *importer) pkg() *types.Package {
+	// if the package was seen before, i is its index (>= 0)
+	i := p.tagOrIndex()
+	if i >= 0 {
+		return p.pkgList[i]
+	}
+
+	// otherwise, i is the package tag (< 0)
+	if i != packageTag {
+		errorf("unexpected package tag %d version %d", i, p.version)
+	}
+
+	// read package data
+	name := p.string()
+	var path string
+	if p.version >= 5 {
+		path = p.path()
+	} else {
+		path = p.string()
+	}
+	if p.version >= 6 {
+		p.int() // package height; unused by go/types
+	}
+
+	// we should never see an empty package name
+	if name == "" {
+		errorf("empty package name in import")
+	}
+
+	// an empty path denotes the package we are currently importing;
+	// it must be the first package we see
+	if (path == "") != (len(p.pkgList) == 0) {
+		errorf("package path %q for pkg index %d", path, len(p.pkgList))
+	}
+
+	// if the package was imported before, use that one; otherwise create a new one
+	if path == "" {
+		path = p.importpath
+	}
+	pkg := p.imports[path]
+	if pkg == nil {
+		pkg = types.NewPackage(path, name)
+		p.imports[path] = pkg
+	} else if pkg.Name() != name {
+		errorf("conflicting names %s and %s for package %q", pkg.Name(), name, path)
+	}
+	p.pkgList = append(p.pkgList, pkg)
+
+	return pkg
+}
+
+// objTag returns the tag value for each object kind.
+func objTag(obj types.Object) int {
+	switch obj.(type) {
+	case *types.Const:
+		return constTag
+	case *types.TypeName:
+		return typeTag
+	case *types.Var:
+		return varTag
+	case *types.Func:
+		return funcTag
+	default:
+		errorf("unexpected object: %v (%T)", obj, obj) // panics
+		panic("unreachable")
+	}
+}
+
+func sameObj(a, b types.Object) bool {
+	// Because unnamed types are not canonicalized, we cannot simply compare types for
+	// (pointer) identity.
+	// Ideally we'd check equality of constant values as well, but this is good enough.
+	return objTag(a) == objTag(b) && types.Identical(a.Type(), b.Type())
+}
+
+func (p *importer) declare(obj types.Object) {
+	pkg := obj.Pkg()
+	if alt := pkg.Scope().Insert(obj); alt != nil {
+		// This can only trigger if we import a (non-type) object a second time.
+		// Excluding type aliases, this cannot happen because 1) we only import a package
+		// once; and b) we ignore compiler-specific export data which may contain
+		// functions whose inlined function bodies refer to other functions that
+		// were already imported.
+		// However, type aliases require reexporting the original type, so we need
+		// to allow it (see also the comment in cmd/compile/internal/gc/bimport.go,
+		// method importer.obj, switch case importing functions).
+		// TODO(gri) review/update this comment once the gc compiler handles type aliases.
+		if !sameObj(obj, alt) {
+			errorf("inconsistent import:\n\t%v\npreviously imported as:\n\t%v\n", obj, alt)
+		}
+	}
+}
+
+func (p *importer) obj(tag int) {
+	switch tag {
+	case constTag:
+		pos := p.pos()
+		pkg, name := p.qualifiedName()
+		typ := p.typ(nil, nil)
+		val := p.value()
+		p.declare(types.NewConst(pos, pkg, name, typ, val))
+
+	case aliasTag:
+		// TODO(gri) verify type alias hookup is correct
+		pos := p.pos()
+		pkg, name := p.qualifiedName()
+		typ := p.typ(nil, nil)
+		p.declare(types.NewTypeName(pos, pkg, name, typ))
+
+	case typeTag:
+		p.typ(nil, nil)
+
+	case varTag:
+		pos := p.pos()
+		pkg, name := p.qualifiedName()
+		typ := p.typ(nil, nil)
+		p.declare(types.NewVar(pos, pkg, name, typ))
+
+	case funcTag:
+		pos := p.pos()
+		pkg, name := p.qualifiedName()
+		params, isddd := p.paramList()
+		result, _ := p.paramList()
+		sig := types.NewSignature(nil, params, result, isddd)
+		p.declare(types.NewFunc(pos, pkg, name, sig))
+
+	default:
+		errorf("unexpected object tag %d", tag)
+	}
+}
+
+const deltaNewFile = -64 // see cmd/compile/internal/gc/bexport.go
+
+func (p *importer) pos() token.Pos {
+	if !p.posInfoFormat {
+		return token.NoPos
+	}
+
+	file := p.prevFile
+	line := p.prevLine
+	delta := p.int()
+	line += delta
+	if p.version >= 5 {
+		if delta == deltaNewFile {
+			if n := p.int(); n >= 0 {
+				// file changed
+				file = p.path()
+				line = n
+			}
+		}
+	} else {
+		if delta == 0 {
+			if n := p.int(); n >= 0 {
+				// file changed
+				file = p.prevFile[:n] + p.string()
+				line = p.int()
+			}
+		}
+	}
+	p.prevFile = file
+	p.prevLine = line
+
+	return p.fake.pos(file, line, 0)
+}
+
+// Synthesize a token.Pos
+type fakeFileSet struct {
+	fset  *token.FileSet
+	files map[string]*fileInfo
+}
+
+type fileInfo struct {
+	file     *token.File
+	lastline int
+}
+
+const maxlines = 64 * 1024
+
+func (s *fakeFileSet) pos(file string, line, column int) token.Pos {
+	// TODO(mdempsky): Make use of column.
+
+	// Since we don't know the set of needed file positions, we reserve maxlines
+	// positions per file. We delay calling token.File.SetLines until all
+	// positions have been calculated (by way of fakeFileSet.setLines), so that
+	// we can avoid setting unnecessary lines. See also golang/go#46586.
+	f := s.files[file]
+	if f == nil {
+		f = &fileInfo{file: s.fset.AddFile(file, -1, maxlines)}
+		s.files[file] = f
+	}
+	if line > maxlines {
+		line = 1
+	}
+	if line > f.lastline {
+		f.lastline = line
+	}
+
+	// Return a fake position assuming that f.file consists only of newlines.
+	return token.Pos(f.file.Base() + line - 1)
+}
+
+func (s *fakeFileSet) setLines() {
+	fakeLinesOnce.Do(func() {
+		fakeLines = make([]int, maxlines)
+		for i := range fakeLines {
+			fakeLines[i] = i
+		}
+	})
+	for _, f := range s.files {
+		f.file.SetLines(fakeLines[:f.lastline])
+	}
+}
+
+var (
+	fakeLines     []int
+	fakeLinesOnce sync.Once
+)
+
+func (p *importer) qualifiedName() (pkg *types.Package, name string) {
+	name = p.string()
+	pkg = p.pkg()
+	return
+}
+
+func (p *importer) record(t types.Type) {
+	p.typList = append(p.typList, t)
+}
+
+// A dddSlice is a types.Type representing ...T parameters.
+// It only appears for parameter types and does not escape
+// the importer.
+type dddSlice struct {
+	elem types.Type
+}
+
+func (t *dddSlice) Underlying() types.Type { return t }
+func (t *dddSlice) String() string         { return "..." + t.elem.String() }
+
+// parent is the package which declared the type; parent == nil means
+// the package currently imported. The parent package is needed for
+// exported struct fields and interface methods which don't contain
+// explicit package information in the export data.
+//
+// A non-nil tname is used as the "owner" of the result type; i.e.,
+// the result type is the underlying type of tname. tname is used
+// to give interface methods a named receiver type where possible.
+func (p *importer) typ(parent *types.Package, tname *types.Named) types.Type {
+	// if the type was seen before, i is its index (>= 0)
+	i := p.tagOrIndex()
+	if i >= 0 {
+		return p.typList[i]
+	}
+
+	// otherwise, i is the type tag (< 0)
+	switch i {
+	case namedTag:
+		// read type object
+		pos := p.pos()
+		parent, name := p.qualifiedName()
+		scope := parent.Scope()
+		obj := scope.Lookup(name)
+
+		// if the object doesn't exist yet, create and insert it
+		if obj == nil {
+			obj = types.NewTypeName(pos, parent, name, nil)
+			scope.Insert(obj)
+		}
+
+		if _, ok := obj.(*types.TypeName); !ok {
+			errorf("pkg = %s, name = %s => %s", parent, name, obj)
+		}
+
+		// associate new named type with obj if it doesn't exist yet
+		t0 := types.NewNamed(obj.(*types.TypeName), nil, nil)
+
+		// but record the existing type, if any
+		tname := obj.Type().(*types.Named) // tname is either t0 or the existing type
+		p.record(tname)
+
+		// read underlying type
+		t0.SetUnderlying(p.typ(parent, t0))
+
+		// interfaces don't have associated methods
+		if types.IsInterface(t0) {
+			return tname
+		}
+
+		// read associated methods
+		for i := p.int(); i > 0; i-- {
+			// TODO(gri) replace this with something closer to fieldName
+			pos := p.pos()
+			name := p.string()
+			if !exported(name) {
+				p.pkg()
+			}
+
+			recv, _ := p.paramList() // TODO(gri) do we need a full param list for the receiver?
+			params, isddd := p.paramList()
+			result, _ := p.paramList()
+			p.int() // go:nointerface pragma - discarded
+
+			sig := types.NewSignature(recv.At(0), params, result, isddd)
+			t0.AddMethod(types.NewFunc(pos, parent, name, sig))
+		}
+
+		return tname
+
+	case arrayTag:
+		t := new(types.Array)
+		if p.trackAllTypes {
+			p.record(t)
+		}
+
+		n := p.int64()
+		*t = *types.NewArray(p.typ(parent, nil), n)
+		return t
+
+	case sliceTag:
+		t := new(types.Slice)
+		if p.trackAllTypes {
+			p.record(t)
+		}
+
+		*t = *types.NewSlice(p.typ(parent, nil))
+		return t
+
+	case dddTag:
+		t := new(dddSlice)
+		if p.trackAllTypes {
+			p.record(t)
+		}
+
+		t.elem = p.typ(parent, nil)
+		return t
+
+	case structTag:
+		t := new(types.Struct)
+		if p.trackAllTypes {
+			p.record(t)
+		}
+
+		*t = *types.NewStruct(p.fieldList(parent))
+		return t
+
+	case pointerTag:
+		t := new(types.Pointer)
+		if p.trackAllTypes {
+			p.record(t)
+		}
+
+		*t = *types.NewPointer(p.typ(parent, nil))
+		return t
+
+	case signatureTag:
+		t := new(types.Signature)
+		if p.trackAllTypes {
+			p.record(t)
+		}
+
+		params, isddd := p.paramList()
+		result, _ := p.paramList()
+		*t = *types.NewSignature(nil, params, result, isddd)
+		return t
+
+	case interfaceTag:
+		// Create a dummy entry in the type list. This is safe because we
+		// cannot expect the interface type to appear in a cycle, as any
+		// such cycle must contain a named type which would have been
+		// first defined earlier.
+		// TODO(gri) Is this still true now that we have type aliases?
+		// See issue #23225.
+		n := len(p.typList)
+		if p.trackAllTypes {
+			p.record(nil)
+		}
+
+		var embeddeds []types.Type
+		for n := p.int(); n > 0; n-- {
+			p.pos()
+			embeddeds = append(embeddeds, p.typ(parent, nil))
+		}
+
+		t := newInterface(p.methodList(parent, tname), embeddeds)
+		p.interfaceList = append(p.interfaceList, t)
+		if p.trackAllTypes {
+			p.typList[n] = t
+		}
+		return t
+
+	case mapTag:
+		t := new(types.Map)
+		if p.trackAllTypes {
+			p.record(t)
+		}
+
+		key := p.typ(parent, nil)
+		val := p.typ(parent, nil)
+		*t = *types.NewMap(key, val)
+		return t
+
+	case chanTag:
+		t := new(types.Chan)
+		if p.trackAllTypes {
+			p.record(t)
+		}
+
+		dir := chanDir(p.int())
+		val := p.typ(parent, nil)
+		*t = *types.NewChan(dir, val)
+		return t
+
+	default:
+		errorf("unexpected type tag %d", i) // panics
+		panic("unreachable")
+	}
+}
+
+func chanDir(d int) types.ChanDir {
+	// tag values must match the constants in cmd/compile/internal/gc/go.go
+	switch d {
+	case 1 /* Crecv */ :
+		return types.RecvOnly
+	case 2 /* Csend */ :
+		return types.SendOnly
+	case 3 /* Cboth */ :
+		return types.SendRecv
+	default:
+		errorf("unexpected channel dir %d", d)
+		return 0
+	}
+}
+
+func (p *importer) fieldList(parent *types.Package) (fields []*types.Var, tags []string) {
+	if n := p.int(); n > 0 {
+		fields = make([]*types.Var, n)
+		tags = make([]string, n)
+		for i := range fields {
+			fields[i], tags[i] = p.field(parent)
+		}
+	}
+	return
+}
+
+func (p *importer) field(parent *types.Package) (*types.Var, string) {
+	pos := p.pos()
+	pkg, name, alias := p.fieldName(parent)
+	typ := p.typ(parent, nil)
+	tag := p.string()
+
+	anonymous := false
+	if name == "" {
+		// anonymous field - typ must be T or *T and T must be a type name
+		switch typ := deref(typ).(type) {
+		case *types.Basic: // basic types are named types
+			pkg = nil // // objects defined in Universe scope have no package
+			name = typ.Name()
+		case *types.Named:
+			name = typ.Obj().Name()
+		default:
+			errorf("named base type expected")
+		}
+		anonymous = true
+	} else if alias {
+		// anonymous field: we have an explicit name because it's an alias
+		anonymous = true
+	}
+
+	return types.NewField(pos, pkg, name, typ, anonymous), tag
+}
+
+func (p *importer) methodList(parent *types.Package, baseType *types.Named) (methods []*types.Func) {
+	if n := p.int(); n > 0 {
+		methods = make([]*types.Func, n)
+		for i := range methods {
+			methods[i] = p.method(parent, baseType)
+		}
+	}
+	return
+}
+
+func (p *importer) method(parent *types.Package, baseType *types.Named) *types.Func {
+	pos := p.pos()
+	pkg, name, _ := p.fieldName(parent)
+	// If we don't have a baseType, use a nil receiver.
+	// A receiver using the actual interface type (which
+	// we don't know yet) will be filled in when we call
+	// types.Interface.Complete.
+	var recv *types.Var
+	if baseType != nil {
+		recv = types.NewVar(token.NoPos, parent, "", baseType)
+	}
+	params, isddd := p.paramList()
+	result, _ := p.paramList()
+	sig := types.NewSignature(recv, params, result, isddd)
+	return types.NewFunc(pos, pkg, name, sig)
+}
+
+func (p *importer) fieldName(parent *types.Package) (pkg *types.Package, name string, alias bool) {
+	name = p.string()
+	pkg = parent
+	if pkg == nil {
+		// use the imported package instead
+		pkg = p.pkgList[0]
+	}
+	if p.version == 0 && name == "_" {
+		// version 0 didn't export a package for _ fields
+		return
+	}
+	switch name {
+	case "":
+		// 1) field name matches base type name and is exported: nothing to do
+	case "?":
+		// 2) field name matches base type name and is not exported: need package
+		name = ""
+		pkg = p.pkg()
+	case "@":
+		// 3) field name doesn't match type name (alias)
+		name = p.string()
+		alias = true
+		fallthrough
+	default:
+		if !exported(name) {
+			pkg = p.pkg()
+		}
+	}
+	return
+}
+
+func (p *importer) paramList() (*types.Tuple, bool) {
+	n := p.int()
+	if n == 0 {
+		return nil, false
+	}
+	// negative length indicates unnamed parameters
+	named := true
+	if n < 0 {
+		n = -n
+		named = false
+	}
+	// n > 0
+	params := make([]*types.Var, n)
+	isddd := false
+	for i := range params {
+		params[i], isddd = p.param(named)
+	}
+	return types.NewTuple(params...), isddd
+}
+
+func (p *importer) param(named bool) (*types.Var, bool) {
+	t := p.typ(nil, nil)
+	td, isddd := t.(*dddSlice)
+	if isddd {
+		t = types.NewSlice(td.elem)
+	}
+
+	var pkg *types.Package
+	var name string
+	if named {
+		name = p.string()
+		if name == "" {
+			errorf("expected named parameter")
+		}
+		if name != "_" {
+			pkg = p.pkg()
+		}
+		if i := strings.Index(name, "·"); i > 0 {
+			name = name[:i] // cut off gc-specific parameter numbering
+		}
+	}
+
+	// read and discard compiler-specific info
+	p.string()
+
+	return types.NewVar(token.NoPos, pkg, name, t), isddd
+}
+
+func exported(name string) bool {
+	ch, _ := utf8.DecodeRuneInString(name)
+	return unicode.IsUpper(ch)
+}
+
+func (p *importer) value() constant.Value {
+	switch tag := p.tagOrIndex(); tag {
+	case falseTag:
+		return constant.MakeBool(false)
+	case trueTag:
+		return constant.MakeBool(true)
+	case int64Tag:
+		return constant.MakeInt64(p.int64())
+	case floatTag:
+		return p.float()
+	case complexTag:
+		re := p.float()
+		im := p.float()
+		return constant.BinaryOp(re, token.ADD, constant.MakeImag(im))
+	case stringTag:
+		return constant.MakeString(p.string())
+	case unknownTag:
+		return constant.MakeUnknown()
+	default:
+		errorf("unexpected value tag %d", tag) // panics
+		panic("unreachable")
+	}
+}
+
+func (p *importer) float() constant.Value {
+	sign := p.int()
+	if sign == 0 {
+		return constant.MakeInt64(0)
+	}
+
+	exp := p.int()
+	mant := []byte(p.string()) // big endian
+
+	// remove leading 0's if any
+	for len(mant) > 0 && mant[0] == 0 {
+		mant = mant[1:]
+	}
+
+	// convert to little endian
+	// TODO(gri) go/constant should have a more direct conversion function
+	//           (e.g., once it supports a big.Float based implementation)
+	for i, j := 0, len(mant)-1; i < j; i, j = i+1, j-1 {
+		mant[i], mant[j] = mant[j], mant[i]
+	}
+
+	// adjust exponent (constant.MakeFromBytes creates an integer value,
+	// but mant represents the mantissa bits such that 0.5 <= mant < 1.0)
+	exp -= len(mant) << 3
+	if len(mant) > 0 {
+		for msd := mant[len(mant)-1]; msd&0x80 == 0; msd <<= 1 {
+			exp++
+		}
+	}
+
+	x := constant.MakeFromBytes(mant)
+	switch {
+	case exp < 0:
+		d := constant.Shift(constant.MakeInt64(1), token.SHL, uint(-exp))
+		x = constant.BinaryOp(x, token.QUO, d)
+	case exp > 0:
+		x = constant.Shift(x, token.SHL, uint(exp))
+	}
+
+	if sign < 0 {
+		x = constant.UnaryOp(token.SUB, x, 0)
+	}
+	return x
+}
+
+// ----------------------------------------------------------------------------
+// Low-level decoders
+
+func (p *importer) tagOrIndex() int {
+	if p.debugFormat {
+		p.marker('t')
+	}
+
+	return int(p.rawInt64())
+}
+
+func (p *importer) int() int {
+	x := p.int64()
+	if int64(int(x)) != x {
+		errorf("exported integer too large")
+	}
+	return int(x)
+}
+
+func (p *importer) int64() int64 {
+	if p.debugFormat {
+		p.marker('i')
+	}
+
+	return p.rawInt64()
+}
+
+func (p *importer) path() string {
+	if p.debugFormat {
+		p.marker('p')
+	}
+	// if the path was seen before, i is its index (>= 0)
+	// (the empty string is at index 0)
+	i := p.rawInt64()
+	if i >= 0 {
+		return p.pathList[i]
+	}
+	// otherwise, i is the negative path length (< 0)
+	a := make([]string, -i)
+	for n := range a {
+		a[n] = p.string()
+	}
+	s := strings.Join(a, "/")
+	p.pathList = append(p.pathList, s)
+	return s
+}
+
+func (p *importer) string() string {
+	if p.debugFormat {
+		p.marker('s')
+	}
+	// if the string was seen before, i is its index (>= 0)
+	// (the empty string is at index 0)
+	i := p.rawInt64()
+	if i >= 0 {
+		return p.strList[i]
+	}
+	// otherwise, i is the negative string length (< 0)
+	if n := int(-i); n <= cap(p.buf) {
+		p.buf = p.buf[:n]
+	} else {
+		p.buf = make([]byte, n)
+	}
+	for i := range p.buf {
+		p.buf[i] = p.rawByte()
+	}
+	s := string(p.buf)
+	p.strList = append(p.strList, s)
+	return s
+}
+
+func (p *importer) marker(want byte) {
+	if got := p.rawByte(); got != want {
+		errorf("incorrect marker: got %c; want %c (pos = %d)", got, want, p.read)
+	}
+
+	pos := p.read
+	if n := int(p.rawInt64()); n != pos {
+		errorf("incorrect position: got %d; want %d", n, pos)
+	}
+}
+
+// rawInt64 should only be used by low-level decoders.
+func (p *importer) rawInt64() int64 {
+	i, err := binary.ReadVarint(p)
+	if err != nil {
+		errorf("read error: %v", err)
+	}
+	return i
+}
+
+// rawStringln should only be used to read the initial version string.
+func (p *importer) rawStringln(b byte) string {
+	p.buf = p.buf[:0]
+	for b != '\n' {
+		p.buf = append(p.buf, b)
+		b = p.rawByte()
+	}
+	return string(p.buf)
+}
+
+// needed for binary.ReadVarint in rawInt64
+func (p *importer) ReadByte() (byte, error) {
+	return p.rawByte(), nil
+}
+
+// byte is the bottleneck interface for reading p.data.
+// It unescapes '|' 'S' to '$' and '|' '|' to '|'.
+// rawByte should only be used by low-level decoders.
+func (p *importer) rawByte() byte {
+	b := p.data[0]
+	r := 1
+	if b == '|' {
+		b = p.data[1]
+		r = 2
+		switch b {
+		case 'S':
+			b = '$'
+		case '|':
+			// nothing to do
+		default:
+			errorf("unexpected escape sequence in export data")
+		}
+	}
+	p.data = p.data[r:]
+	p.read += r
+	return b
+
+}
+
+// ----------------------------------------------------------------------------
+// Export format
+
+// Tags. Must be < 0.
+const (
+	// Objects
+	packageTag = -(iota + 1)
+	constTag
+	typeTag
+	varTag
+	funcTag
+	endTag
+
+	// Types
+	namedTag
+	arrayTag
+	sliceTag
+	dddTag
+	structTag
+	pointerTag
+	signatureTag
+	interfaceTag
+	mapTag
+	chanTag
+
+	// Values
+	falseTag
+	trueTag
+	int64Tag
+	floatTag
+	fractionTag // not used by gc
+	complexTag
+	stringTag
+	nilTag     // only used by gc (appears in exported inlined function bodies)
+	unknownTag // not used by gc (only appears in packages with errors)
+
+	// Type aliases
+	aliasTag
+)
+
+var predeclOnce sync.Once
+var predecl []types.Type // initialized lazily
+
+func predeclared() []types.Type {
+	predeclOnce.Do(func() {
+		// initialize lazily to be sure that all
+		// elements have been initialized before
+		predecl = []types.Type{ // basic types
+			types.Typ[types.Bool],
+			types.Typ[types.Int],
+			types.Typ[types.Int8],
+			types.Typ[types.Int16],
+			types.Typ[types.Int32],
+			types.Typ[types.Int64],
+			types.Typ[types.Uint],
+			types.Typ[types.Uint8],
+			types.Typ[types.Uint16],
+			types.Typ[types.Uint32],
+			types.Typ[types.Uint64],
+			types.Typ[types.Uintptr],
+			types.Typ[types.Float32],
+			types.Typ[types.Float64],
+			types.Typ[types.Complex64],
+			types.Typ[types.Complex128],
+			types.Typ[types.String],
+
+			// basic type aliases
+			types.Universe.Lookup("byte").Type(),
+			types.Universe.Lookup("rune").Type(),
+
+			// error
+			types.Universe.Lookup("error").Type(),
+
+			// untyped types
+			types.Typ[types.UntypedBool],
+			types.Typ[types.UntypedInt],
+			types.Typ[types.UntypedRune],
+			types.Typ[types.UntypedFloat],
+			types.Typ[types.UntypedComplex],
+			types.Typ[types.UntypedString],
+			types.Typ[types.UntypedNil],
+
+			// package unsafe
+			types.Typ[types.UnsafePointer],
+
+			// invalid type
+			types.Typ[types.Invalid], // only appears in packages with errors
+
+			// used internally by gc; never used by this package or in .a files
+			anyType{},
+		}
+		predecl = append(predecl, additionalPredeclared()...)
+	})
+	return predecl
+}
+
+type anyType struct{}
+
+func (t anyType) Underlying() types.Type { return t }
+func (t anyType) String() string         { return "any" }
diff --git a/vendor/golang.org/x/tools/internal/gcimporter/exportdata.go b/vendor/golang.org/x/tools/internal/gcimporter/exportdata.go
new file mode 100644
index 0000000..f6437fe
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/gcimporter/exportdata.go
@@ -0,0 +1,99 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This file is a copy of $GOROOT/src/go/internal/gcimporter/exportdata.go.
+
+// This file implements FindExportData.
+
+package gcimporter
+
+import (
+	"bufio"
+	"fmt"
+	"io"
+	"strconv"
+	"strings"
+)
+
+func readGopackHeader(r *bufio.Reader) (name string, size int64, err error) {
+	// See $GOROOT/include/ar.h.
+	hdr := make([]byte, 16+12+6+6+8+10+2)
+	_, err = io.ReadFull(r, hdr)
+	if err != nil {
+		return
+	}
+	// leave for debugging
+	if false {
+		fmt.Printf("header: %s", hdr)
+	}
+	s := strings.TrimSpace(string(hdr[16+12+6+6+8:][:10]))
+	length, err := strconv.Atoi(s)
+	size = int64(length)
+	if err != nil || hdr[len(hdr)-2] != '`' || hdr[len(hdr)-1] != '\n' {
+		err = fmt.Errorf("invalid archive header")
+		return
+	}
+	name = strings.TrimSpace(string(hdr[:16]))
+	return
+}
+
+// FindExportData positions the reader r at the beginning of the
+// export data section of an underlying GC-created object/archive
+// file by reading from it. The reader must be positioned at the
+// start of the file before calling this function. The hdr result
+// is the string before the export data, either "$$" or "$$B".
+// The size result is the length of the export data in bytes, or -1 if not known.
+func FindExportData(r *bufio.Reader) (hdr string, size int64, err error) {
+	// Read first line to make sure this is an object file.
+	line, err := r.ReadSlice('\n')
+	if err != nil {
+		err = fmt.Errorf("can't find export data (%v)", err)
+		return
+	}
+
+	if string(line) == "!<arch>\n" {
+		// Archive file. Scan to __.PKGDEF.
+		var name string
+		if name, size, err = readGopackHeader(r); err != nil {
+			return
+		}
+
+		// First entry should be __.PKGDEF.
+		if name != "__.PKGDEF" {
+			err = fmt.Errorf("go archive is missing __.PKGDEF")
+			return
+		}
+
+		// Read first line of __.PKGDEF data, so that line
+		// is once again the first line of the input.
+		if line, err = r.ReadSlice('\n'); err != nil {
+			err = fmt.Errorf("can't find export data (%v)", err)
+			return
+		}
+		size -= int64(len(line))
+	}
+
+	// Now at __.PKGDEF in archive or still at beginning of file.
+	// Either way, line should begin with "go object ".
+	if !strings.HasPrefix(string(line), "go object ") {
+		err = fmt.Errorf("not a Go object file")
+		return
+	}
+
+	// Skip over object header to export data.
+	// Begins after first line starting with $$.
+	for line[0] != '$' {
+		if line, err = r.ReadSlice('\n'); err != nil {
+			err = fmt.Errorf("can't find export data (%v)", err)
+			return
+		}
+		size -= int64(len(line))
+	}
+	hdr = string(line)
+	if size < 0 {
+		size = -1
+	}
+
+	return
+}
diff --git a/vendor/golang.org/x/tools/internal/gcimporter/gcimporter.go b/vendor/golang.org/x/tools/internal/gcimporter/gcimporter.go
new file mode 100644
index 0000000..a973dec
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/gcimporter/gcimporter.go
@@ -0,0 +1,277 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This file is a reduced copy of $GOROOT/src/go/internal/gcimporter/gcimporter.go.
+
+// Package gcimporter provides various functions for reading
+// gc-generated object files that can be used to implement the
+// Importer interface defined by the Go 1.5 standard library package.
+//
+// The encoding is deterministic: if the encoder is applied twice to
+// the same types.Package data structure, both encodings are equal.
+// This property may be important to avoid spurious changes in
+// applications such as build systems.
+//
+// However, the encoder is not necessarily idempotent. Importing an
+// exported package may yield a types.Package that, while it
+// represents the same set of Go types as the original, may differ in
+// the details of its internal representation. Because of these
+// differences, re-encoding the imported package may yield a
+// different, but equally valid, encoding of the package.
+package gcimporter // import "golang.org/x/tools/internal/gcimporter"
+
+import (
+	"bufio"
+	"bytes"
+	"fmt"
+	"go/build"
+	"go/token"
+	"go/types"
+	"io"
+	"io/ioutil"
+	"os"
+	"os/exec"
+	"path/filepath"
+	"strings"
+	"sync"
+)
+
+const (
+	// Enable debug during development: it adds some additional checks, and
+	// prevents errors from being recovered.
+	debug = false
+
+	// If trace is set, debugging output is printed to std out.
+	trace = false
+)
+
+var exportMap sync.Map // package dir → func() (string, bool)
+
+// lookupGorootExport returns the location of the export data
+// (normally found in the build cache, but located in GOROOT/pkg
+// in prior Go releases) for the package located in pkgDir.
+//
+// (We use the package's directory instead of its import path
+// mainly to simplify handling of the packages in src/vendor
+// and cmd/vendor.)
+func lookupGorootExport(pkgDir string) (string, bool) {
+	f, ok := exportMap.Load(pkgDir)
+	if !ok {
+		var (
+			listOnce   sync.Once
+			exportPath string
+		)
+		f, _ = exportMap.LoadOrStore(pkgDir, func() (string, bool) {
+			listOnce.Do(func() {
+				cmd := exec.Command("go", "list", "-export", "-f", "{{.Export}}", pkgDir)
+				cmd.Dir = build.Default.GOROOT
+				var output []byte
+				output, err := cmd.Output()
+				if err != nil {
+					return
+				}
+
+				exports := strings.Split(string(bytes.TrimSpace(output)), "\n")
+				if len(exports) != 1 {
+					return
+				}
+
+				exportPath = exports[0]
+			})
+
+			return exportPath, exportPath != ""
+		})
+	}
+
+	return f.(func() (string, bool))()
+}
+
+var pkgExts = [...]string{".a", ".o"}
+
+// FindPkg returns the filename and unique package id for an import
+// path based on package information provided by build.Import (using
+// the build.Default build.Context). A relative srcDir is interpreted
+// relative to the current working directory.
+// If no file was found, an empty filename is returned.
+func FindPkg(path, srcDir string) (filename, id string) {
+	if path == "" {
+		return
+	}
+
+	var noext string
+	switch {
+	default:
+		// "x" -> "$GOPATH/pkg/$GOOS_$GOARCH/x.ext", "x"
+		// Don't require the source files to be present.
+		if abs, err := filepath.Abs(srcDir); err == nil { // see issue 14282
+			srcDir = abs
+		}
+		bp, _ := build.Import(path, srcDir, build.FindOnly|build.AllowBinary)
+		if bp.PkgObj == "" {
+			var ok bool
+			if bp.Goroot && bp.Dir != "" {
+				filename, ok = lookupGorootExport(bp.Dir)
+			}
+			if !ok {
+				id = path // make sure we have an id to print in error message
+				return
+			}
+		} else {
+			noext = strings.TrimSuffix(bp.PkgObj, ".a")
+			id = bp.ImportPath
+		}
+
+	case build.IsLocalImport(path):
+		// "./x" -> "/this/directory/x.ext", "/this/directory/x"
+		noext = filepath.Join(srcDir, path)
+		id = noext
+
+	case filepath.IsAbs(path):
+		// for completeness only - go/build.Import
+		// does not support absolute imports
+		// "/x" -> "/x.ext", "/x"
+		noext = path
+		id = path
+	}
+
+	if false { // for debugging
+		if path != id {
+			fmt.Printf("%s -> %s\n", path, id)
+		}
+	}
+
+	if filename != "" {
+		if f, err := os.Stat(filename); err == nil && !f.IsDir() {
+			return
+		}
+	}
+
+	// try extensions
+	for _, ext := range pkgExts {
+		filename = noext + ext
+		if f, err := os.Stat(filename); err == nil && !f.IsDir() {
+			return
+		}
+	}
+
+	filename = "" // not found
+	return
+}
+
+// Import imports a gc-generated package given its import path and srcDir, adds
+// the corresponding package object to the packages map, and returns the object.
+// The packages map must contain all packages already imported.
+func Import(packages map[string]*types.Package, path, srcDir string, lookup func(path string) (io.ReadCloser, error)) (pkg *types.Package, err error) {
+	var rc io.ReadCloser
+	var filename, id string
+	if lookup != nil {
+		// With custom lookup specified, assume that caller has
+		// converted path to a canonical import path for use in the map.
+		if path == "unsafe" {
+			return types.Unsafe, nil
+		}
+		id = path
+
+		// No need to re-import if the package was imported completely before.
+		if pkg = packages[id]; pkg != nil && pkg.Complete() {
+			return
+		}
+		f, err := lookup(path)
+		if err != nil {
+			return nil, err
+		}
+		rc = f
+	} else {
+		filename, id = FindPkg(path, srcDir)
+		if filename == "" {
+			if path == "unsafe" {
+				return types.Unsafe, nil
+			}
+			return nil, fmt.Errorf("can't find import: %q", id)
+		}
+
+		// no need to re-import if the package was imported completely before
+		if pkg = packages[id]; pkg != nil && pkg.Complete() {
+			return
+		}
+
+		// open file
+		f, err := os.Open(filename)
+		if err != nil {
+			return nil, err
+		}
+		defer func() {
+			if err != nil {
+				// add file name to error
+				err = fmt.Errorf("%s: %v", filename, err)
+			}
+		}()
+		rc = f
+	}
+	defer rc.Close()
+
+	var hdr string
+	var size int64
+	buf := bufio.NewReader(rc)
+	if hdr, size, err = FindExportData(buf); err != nil {
+		return
+	}
+
+	switch hdr {
+	case "$$B\n":
+		var data []byte
+		data, err = ioutil.ReadAll(buf)
+		if err != nil {
+			break
+		}
+
+		// TODO(gri): allow clients of go/importer to provide a FileSet.
+		// Or, define a new standard go/types/gcexportdata package.
+		fset := token.NewFileSet()
+
+		// The indexed export format starts with an 'i'; the older
+		// binary export format starts with a 'c', 'd', or 'v'
+		// (from "version"). Select appropriate importer.
+		if len(data) > 0 {
+			switch data[0] {
+			case 'i':
+				_, pkg, err := IImportData(fset, packages, data[1:], id)
+				return pkg, err
+
+			case 'v', 'c', 'd':
+				_, pkg, err := BImportData(fset, packages, data, id)
+				return pkg, err
+
+			case 'u':
+				_, pkg, err := UImportData(fset, packages, data[1:size], id)
+				return pkg, err
+
+			default:
+				l := len(data)
+				if l > 10 {
+					l = 10
+				}
+				return nil, fmt.Errorf("unexpected export data with prefix %q for path %s", string(data[:l]), id)
+			}
+		}
+
+	default:
+		err = fmt.Errorf("unknown export data header: %q", hdr)
+	}
+
+	return
+}
+
+func deref(typ types.Type) types.Type {
+	if p, _ := typ.(*types.Pointer); p != nil {
+		return p.Elem()
+	}
+	return typ
+}
+
+type byPath []*types.Package
+
+func (a byPath) Len() int           { return len(a) }
+func (a byPath) Swap(i, j int)      { a[i], a[j] = a[j], a[i] }
+func (a byPath) Less(i, j int) bool { return a[i].Path() < a[j].Path() }
diff --git a/vendor/golang.org/x/tools/internal/gcimporter/iexport.go b/vendor/golang.org/x/tools/internal/gcimporter/iexport.go
new file mode 100644
index 0000000..ba53cdc
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/gcimporter/iexport.go
@@ -0,0 +1,1180 @@
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Indexed binary package export.
+// This file was derived from $GOROOT/src/cmd/compile/internal/gc/iexport.go;
+// see that file for specification of the format.
+
+package gcimporter
+
+import (
+	"bytes"
+	"encoding/binary"
+	"fmt"
+	"go/constant"
+	"go/token"
+	"go/types"
+	"io"
+	"math/big"
+	"reflect"
+	"sort"
+	"strconv"
+	"strings"
+
+	"golang.org/x/tools/internal/tokeninternal"
+	"golang.org/x/tools/internal/typeparams"
+)
+
+// IExportShallow encodes "shallow" export data for the specified package.
+//
+// No promises are made about the encoding other than that it can be
+// decoded by the same version of IIExportShallow. If you plan to save
+// export data in the file system, be sure to include a cryptographic
+// digest of the executable in the key to avoid version skew.
+func IExportShallow(fset *token.FileSet, pkg *types.Package) ([]byte, error) {
+	// In principle this operation can only fail if out.Write fails,
+	// but that's impossible for bytes.Buffer---and as a matter of
+	// fact iexportCommon doesn't even check for I/O errors.
+	// TODO(adonovan): handle I/O errors properly.
+	// TODO(adonovan): use byte slices throughout, avoiding copying.
+	const bundle, shallow = false, true
+	var out bytes.Buffer
+	err := iexportCommon(&out, fset, bundle, shallow, iexportVersion, []*types.Package{pkg})
+	return out.Bytes(), err
+}
+
+// IImportShallow decodes "shallow" types.Package data encoded by IExportShallow
+// in the same executable. This function cannot import data from
+// cmd/compile or gcexportdata.Write.
+func IImportShallow(fset *token.FileSet, imports map[string]*types.Package, data []byte, path string, insert InsertType) (*types.Package, error) {
+	const bundle = false
+	pkgs, err := iimportCommon(fset, imports, data, bundle, path, insert)
+	if err != nil {
+		return nil, err
+	}
+	return pkgs[0], nil
+}
+
+// InsertType is the type of a function that creates a types.TypeName
+// object for a named type and inserts it into the scope of the
+// specified Package.
+type InsertType = func(pkg *types.Package, name string)
+
+// Current bundled export format version. Increase with each format change.
+// 0: initial implementation
+const bundleVersion = 0
+
+// IExportData writes indexed export data for pkg to out.
+//
+// If no file set is provided, position info will be missing.
+// The package path of the top-level package will not be recorded,
+// so that calls to IImportData can override with a provided package path.
+func IExportData(out io.Writer, fset *token.FileSet, pkg *types.Package) error {
+	const bundle, shallow = false, false
+	return iexportCommon(out, fset, bundle, shallow, iexportVersion, []*types.Package{pkg})
+}
+
+// IExportBundle writes an indexed export bundle for pkgs to out.
+func IExportBundle(out io.Writer, fset *token.FileSet, pkgs []*types.Package) error {
+	const bundle, shallow = true, false
+	return iexportCommon(out, fset, bundle, shallow, iexportVersion, pkgs)
+}
+
+func iexportCommon(out io.Writer, fset *token.FileSet, bundle, shallow bool, version int, pkgs []*types.Package) (err error) {
+	if !debug {
+		defer func() {
+			if e := recover(); e != nil {
+				if ierr, ok := e.(internalError); ok {
+					err = ierr
+					return
+				}
+				// Not an internal error; panic again.
+				panic(e)
+			}
+		}()
+	}
+
+	p := iexporter{
+		fset:        fset,
+		version:     version,
+		shallow:     shallow,
+		allPkgs:     map[*types.Package]bool{},
+		stringIndex: map[string]uint64{},
+		declIndex:   map[types.Object]uint64{},
+		tparamNames: map[types.Object]string{},
+		typIndex:    map[types.Type]uint64{},
+	}
+	if !bundle {
+		p.localpkg = pkgs[0]
+	}
+
+	for i, pt := range predeclared() {
+		p.typIndex[pt] = uint64(i)
+	}
+	if len(p.typIndex) > predeclReserved {
+		panic(internalErrorf("too many predeclared types: %d > %d", len(p.typIndex), predeclReserved))
+	}
+
+	// Initialize work queue with exported declarations.
+	for _, pkg := range pkgs {
+		scope := pkg.Scope()
+		for _, name := range scope.Names() {
+			if token.IsExported(name) {
+				p.pushDecl(scope.Lookup(name))
+			}
+		}
+
+		if bundle {
+			// Ensure pkg and its imports are included in the index.
+			p.allPkgs[pkg] = true
+			for _, imp := range pkg.Imports() {
+				p.allPkgs[imp] = true
+			}
+		}
+	}
+
+	// Loop until no more work.
+	for !p.declTodo.empty() {
+		p.doDecl(p.declTodo.popHead())
+	}
+
+	// Produce index of offset of each file record in files.
+	var files intWriter
+	var fileOffset []uint64 // fileOffset[i] is offset in files of file encoded as i
+	if p.shallow {
+		fileOffset = make([]uint64, len(p.fileInfos))
+		for i, info := range p.fileInfos {
+			fileOffset[i] = uint64(files.Len())
+			p.encodeFile(&files, info.file, info.needed)
+		}
+	}
+
+	// Append indices to data0 section.
+	dataLen := uint64(p.data0.Len())
+	w := p.newWriter()
+	w.writeIndex(p.declIndex)
+
+	if bundle {
+		w.uint64(uint64(len(pkgs)))
+		for _, pkg := range pkgs {
+			w.pkg(pkg)
+			imps := pkg.Imports()
+			w.uint64(uint64(len(imps)))
+			for _, imp := range imps {
+				w.pkg(imp)
+			}
+		}
+	}
+	w.flush()
+
+	// Assemble header.
+	var hdr intWriter
+	if bundle {
+		hdr.uint64(bundleVersion)
+	}
+	hdr.uint64(uint64(p.version))
+	hdr.uint64(uint64(p.strings.Len()))
+	if p.shallow {
+		hdr.uint64(uint64(files.Len()))
+		hdr.uint64(uint64(len(fileOffset)))
+		for _, offset := range fileOffset {
+			hdr.uint64(offset)
+		}
+	}
+	hdr.uint64(dataLen)
+
+	// Flush output.
+	io.Copy(out, &hdr)
+	io.Copy(out, &p.strings)
+	if p.shallow {
+		io.Copy(out, &files)
+	}
+	io.Copy(out, &p.data0)
+
+	return nil
+}
+
+// encodeFile writes to w a representation of the file sufficient to
+// faithfully restore position information about all needed offsets.
+// Mutates the needed array.
+func (p *iexporter) encodeFile(w *intWriter, file *token.File, needed []uint64) {
+	_ = needed[0] // precondition: needed is non-empty
+
+	w.uint64(p.stringOff(file.Name()))
+
+	size := uint64(file.Size())
+	w.uint64(size)
+
+	// Sort the set of needed offsets. Duplicates are harmless.
+	sort.Slice(needed, func(i, j int) bool { return needed[i] < needed[j] })
+
+	lines := tokeninternal.GetLines(file) // byte offset of each line start
+	w.uint64(uint64(len(lines)))
+
+	// Rather than record the entire array of line start offsets,
+	// we save only a sparse list of (index, offset) pairs for
+	// the start of each line that contains a needed position.
+	var sparse [][2]int // (index, offset) pairs
+outer:
+	for i, lineStart := range lines {
+		lineEnd := size
+		if i < len(lines)-1 {
+			lineEnd = uint64(lines[i+1])
+		}
+		// Does this line contains a needed offset?
+		if needed[0] < lineEnd {
+			sparse = append(sparse, [2]int{i, lineStart})
+			for needed[0] < lineEnd {
+				needed = needed[1:]
+				if len(needed) == 0 {
+					break outer
+				}
+			}
+		}
+	}
+
+	// Delta-encode the columns.
+	w.uint64(uint64(len(sparse)))
+	var prev [2]int
+	for _, pair := range sparse {
+		w.uint64(uint64(pair[0] - prev[0]))
+		w.uint64(uint64(pair[1] - prev[1]))
+		prev = pair
+	}
+}
+
+// writeIndex writes out an object index. mainIndex indicates whether
+// we're writing out the main index, which is also read by
+// non-compiler tools and includes a complete package description
+// (i.e., name and height).
+func (w *exportWriter) writeIndex(index map[types.Object]uint64) {
+	type pkgObj struct {
+		obj  types.Object
+		name string // qualified name; differs from obj.Name for type params
+	}
+	// Build a map from packages to objects from that package.
+	pkgObjs := map[*types.Package][]pkgObj{}
+
+	// For the main index, make sure to include every package that
+	// we reference, even if we're not exporting (or reexporting)
+	// any symbols from it.
+	if w.p.localpkg != nil {
+		pkgObjs[w.p.localpkg] = nil
+	}
+	for pkg := range w.p.allPkgs {
+		pkgObjs[pkg] = nil
+	}
+
+	for obj := range index {
+		name := w.p.exportName(obj)
+		pkgObjs[obj.Pkg()] = append(pkgObjs[obj.Pkg()], pkgObj{obj, name})
+	}
+
+	var pkgs []*types.Package
+	for pkg, objs := range pkgObjs {
+		pkgs = append(pkgs, pkg)
+
+		sort.Slice(objs, func(i, j int) bool {
+			return objs[i].name < objs[j].name
+		})
+	}
+
+	sort.Slice(pkgs, func(i, j int) bool {
+		return w.exportPath(pkgs[i]) < w.exportPath(pkgs[j])
+	})
+
+	w.uint64(uint64(len(pkgs)))
+	for _, pkg := range pkgs {
+		w.string(w.exportPath(pkg))
+		w.string(pkg.Name())
+		w.uint64(uint64(0)) // package height is not needed for go/types
+
+		objs := pkgObjs[pkg]
+		w.uint64(uint64(len(objs)))
+		for _, obj := range objs {
+			w.string(obj.name)
+			w.uint64(index[obj.obj])
+		}
+	}
+}
+
+// exportName returns the 'exported' name of an object. It differs from
+// obj.Name() only for type parameters (see tparamExportName for details).
+func (p *iexporter) exportName(obj types.Object) (res string) {
+	if name := p.tparamNames[obj]; name != "" {
+		return name
+	}
+	return obj.Name()
+}
+
+type iexporter struct {
+	fset    *token.FileSet
+	out     *bytes.Buffer
+	version int
+
+	shallow  bool           // don't put types from other packages in the index
+	localpkg *types.Package // (nil in bundle mode)
+
+	// allPkgs tracks all packages that have been referenced by
+	// the export data, so we can ensure to include them in the
+	// main index.
+	allPkgs map[*types.Package]bool
+
+	declTodo objQueue
+
+	strings     intWriter
+	stringIndex map[string]uint64
+
+	// In shallow mode, object positions are encoded as (file, offset).
+	// Each file is recorded as a line-number table.
+	// Only the lines of needed positions are saved faithfully.
+	fileInfo  map[*token.File]uint64 // value is index in fileInfos
+	fileInfos []*filePositions
+
+	data0       intWriter
+	declIndex   map[types.Object]uint64
+	tparamNames map[types.Object]string // typeparam->exported name
+	typIndex    map[types.Type]uint64
+
+	indent int // for tracing support
+}
+
+type filePositions struct {
+	file   *token.File
+	needed []uint64 // unordered list of needed file offsets
+}
+
+func (p *iexporter) trace(format string, args ...interface{}) {
+	if !trace {
+		// Call sites should also be guarded, but having this check here allows
+		// easily enabling/disabling debug trace statements.
+		return
+	}
+	fmt.Printf(strings.Repeat("..", p.indent)+format+"\n", args...)
+}
+
+// stringOff returns the offset of s within the string section.
+// If not already present, it's added to the end.
+func (p *iexporter) stringOff(s string) uint64 {
+	off, ok := p.stringIndex[s]
+	if !ok {
+		off = uint64(p.strings.Len())
+		p.stringIndex[s] = off
+
+		p.strings.uint64(uint64(len(s)))
+		p.strings.WriteString(s)
+	}
+	return off
+}
+
+// fileIndexAndOffset returns the index of the token.File and the byte offset of pos within it.
+func (p *iexporter) fileIndexAndOffset(file *token.File, pos token.Pos) (uint64, uint64) {
+	index, ok := p.fileInfo[file]
+	if !ok {
+		index = uint64(len(p.fileInfo))
+		p.fileInfos = append(p.fileInfos, &filePositions{file: file})
+		if p.fileInfo == nil {
+			p.fileInfo = make(map[*token.File]uint64)
+		}
+		p.fileInfo[file] = index
+	}
+	// Record each needed offset.
+	info := p.fileInfos[index]
+	offset := uint64(file.Offset(pos))
+	info.needed = append(info.needed, offset)
+
+	return index, offset
+}
+
+// pushDecl adds n to the declaration work queue, if not already present.
+func (p *iexporter) pushDecl(obj types.Object) {
+	// Package unsafe is known to the compiler and predeclared.
+	// Caller should not ask us to do export it.
+	if obj.Pkg() == types.Unsafe {
+		panic("cannot export package unsafe")
+	}
+
+	// Shallow export data: don't index decls from other packages.
+	if p.shallow && obj.Pkg() != p.localpkg {
+		return
+	}
+
+	if _, ok := p.declIndex[obj]; ok {
+		return
+	}
+
+	p.declIndex[obj] = ^uint64(0) // mark obj present in work queue
+	p.declTodo.pushTail(obj)
+}
+
+// exportWriter handles writing out individual data section chunks.
+type exportWriter struct {
+	p *iexporter
+
+	data       intWriter
+	currPkg    *types.Package
+	prevFile   string
+	prevLine   int64
+	prevColumn int64
+}
+
+func (w *exportWriter) exportPath(pkg *types.Package) string {
+	if pkg == w.p.localpkg {
+		return ""
+	}
+	return pkg.Path()
+}
+
+func (p *iexporter) doDecl(obj types.Object) {
+	if trace {
+		p.trace("exporting decl %v (%T)", obj, obj)
+		p.indent++
+		defer func() {
+			p.indent--
+			p.trace("=> %s", obj)
+		}()
+	}
+	w := p.newWriter()
+	w.setPkg(obj.Pkg(), false)
+
+	switch obj := obj.(type) {
+	case *types.Var:
+		w.tag('V')
+		w.pos(obj.Pos())
+		w.typ(obj.Type(), obj.Pkg())
+
+	case *types.Func:
+		sig, _ := obj.Type().(*types.Signature)
+		if sig.Recv() != nil {
+			// We shouldn't see methods in the package scope,
+			// but the type checker may repair "func () F() {}"
+			// to "func (Invalid) F()" and then treat it like "func F()",
+			// so allow that. See golang/go#57729.
+			if sig.Recv().Type() != types.Typ[types.Invalid] {
+				panic(internalErrorf("unexpected method: %v", sig))
+			}
+		}
+
+		// Function.
+		if typeparams.ForSignature(sig).Len() == 0 {
+			w.tag('F')
+		} else {
+			w.tag('G')
+		}
+		w.pos(obj.Pos())
+		// The tparam list of the function type is the declaration of the type
+		// params. So, write out the type params right now. Then those type params
+		// will be referenced via their type offset (via typOff) in all other
+		// places in the signature and function where they are used.
+		//
+		// While importing the type parameters, tparamList computes and records
+		// their export name, so that it can be later used when writing the index.
+		if tparams := typeparams.ForSignature(sig); tparams.Len() > 0 {
+			w.tparamList(obj.Name(), tparams, obj.Pkg())
+		}
+		w.signature(sig)
+
+	case *types.Const:
+		w.tag('C')
+		w.pos(obj.Pos())
+		w.value(obj.Type(), obj.Val())
+
+	case *types.TypeName:
+		t := obj.Type()
+
+		if tparam, ok := t.(*typeparams.TypeParam); ok {
+			w.tag('P')
+			w.pos(obj.Pos())
+			constraint := tparam.Constraint()
+			if p.version >= iexportVersionGo1_18 {
+				implicit := false
+				if iface, _ := constraint.(*types.Interface); iface != nil {
+					implicit = typeparams.IsImplicit(iface)
+				}
+				w.bool(implicit)
+			}
+			w.typ(constraint, obj.Pkg())
+			break
+		}
+
+		if obj.IsAlias() {
+			w.tag('A')
+			w.pos(obj.Pos())
+			w.typ(t, obj.Pkg())
+			break
+		}
+
+		// Defined type.
+		named, ok := t.(*types.Named)
+		if !ok {
+			panic(internalErrorf("%s is not a defined type", t))
+		}
+
+		if typeparams.ForNamed(named).Len() == 0 {
+			w.tag('T')
+		} else {
+			w.tag('U')
+		}
+		w.pos(obj.Pos())
+
+		if typeparams.ForNamed(named).Len() > 0 {
+			// While importing the type parameters, tparamList computes and records
+			// their export name, so that it can be later used when writing the index.
+			w.tparamList(obj.Name(), typeparams.ForNamed(named), obj.Pkg())
+		}
+
+		underlying := obj.Type().Underlying()
+		w.typ(underlying, obj.Pkg())
+
+		if types.IsInterface(t) {
+			break
+		}
+
+		n := named.NumMethods()
+		w.uint64(uint64(n))
+		for i := 0; i < n; i++ {
+			m := named.Method(i)
+			w.pos(m.Pos())
+			w.string(m.Name())
+			sig, _ := m.Type().(*types.Signature)
+
+			// Receiver type parameters are type arguments of the receiver type, so
+			// their name must be qualified before exporting recv.
+			if rparams := typeparams.RecvTypeParams(sig); rparams.Len() > 0 {
+				prefix := obj.Name() + "." + m.Name()
+				for i := 0; i < rparams.Len(); i++ {
+					rparam := rparams.At(i)
+					name := tparamExportName(prefix, rparam)
+					w.p.tparamNames[rparam.Obj()] = name
+				}
+			}
+			w.param(sig.Recv())
+			w.signature(sig)
+		}
+
+	default:
+		panic(internalErrorf("unexpected object: %v", obj))
+	}
+
+	p.declIndex[obj] = w.flush()
+}
+
+func (w *exportWriter) tag(tag byte) {
+	w.data.WriteByte(tag)
+}
+
+func (w *exportWriter) pos(pos token.Pos) {
+	if w.p.shallow {
+		w.posV2(pos)
+	} else if w.p.version >= iexportVersionPosCol {
+		w.posV1(pos)
+	} else {
+		w.posV0(pos)
+	}
+}
+
+// posV2 encoding (used only in shallow mode) records positions as
+// (file, offset), where file is the index in the token.File table
+// (which records the file name and newline offsets) and offset is a
+// byte offset. It effectively ignores //line directives.
+func (w *exportWriter) posV2(pos token.Pos) {
+	if pos == token.NoPos {
+		w.uint64(0)
+		return
+	}
+	file := w.p.fset.File(pos) // fset must be non-nil
+	index, offset := w.p.fileIndexAndOffset(file, pos)
+	w.uint64(1 + index)
+	w.uint64(offset)
+}
+
+func (w *exportWriter) posV1(pos token.Pos) {
+	if w.p.fset == nil {
+		w.int64(0)
+		return
+	}
+
+	p := w.p.fset.Position(pos)
+	file := p.Filename
+	line := int64(p.Line)
+	column := int64(p.Column)
+
+	deltaColumn := (column - w.prevColumn) << 1
+	deltaLine := (line - w.prevLine) << 1
+
+	if file != w.prevFile {
+		deltaLine |= 1
+	}
+	if deltaLine != 0 {
+		deltaColumn |= 1
+	}
+
+	w.int64(deltaColumn)
+	if deltaColumn&1 != 0 {
+		w.int64(deltaLine)
+		if deltaLine&1 != 0 {
+			w.string(file)
+		}
+	}
+
+	w.prevFile = file
+	w.prevLine = line
+	w.prevColumn = column
+}
+
+func (w *exportWriter) posV0(pos token.Pos) {
+	if w.p.fset == nil {
+		w.int64(0)
+		return
+	}
+
+	p := w.p.fset.Position(pos)
+	file := p.Filename
+	line := int64(p.Line)
+
+	// When file is the same as the last position (common case),
+	// we can save a few bytes by delta encoding just the line
+	// number.
+	//
+	// Note: Because data objects may be read out of order (or not
+	// at all), we can only apply delta encoding within a single
+	// object. This is handled implicitly by tracking prevFile and
+	// prevLine as fields of exportWriter.
+
+	if file == w.prevFile {
+		delta := line - w.prevLine
+		w.int64(delta)
+		if delta == deltaNewFile {
+			w.int64(-1)
+		}
+	} else {
+		w.int64(deltaNewFile)
+		w.int64(line) // line >= 0
+		w.string(file)
+		w.prevFile = file
+	}
+	w.prevLine = line
+}
+
+func (w *exportWriter) pkg(pkg *types.Package) {
+	// Ensure any referenced packages are declared in the main index.
+	w.p.allPkgs[pkg] = true
+
+	w.string(w.exportPath(pkg))
+}
+
+func (w *exportWriter) qualifiedType(obj *types.TypeName) {
+	name := w.p.exportName(obj)
+
+	// Ensure any referenced declarations are written out too.
+	w.p.pushDecl(obj)
+	w.string(name)
+	w.pkg(obj.Pkg())
+}
+
+func (w *exportWriter) typ(t types.Type, pkg *types.Package) {
+	w.data.uint64(w.p.typOff(t, pkg))
+}
+
+func (p *iexporter) newWriter() *exportWriter {
+	return &exportWriter{p: p}
+}
+
+func (w *exportWriter) flush() uint64 {
+	off := uint64(w.p.data0.Len())
+	io.Copy(&w.p.data0, &w.data)
+	return off
+}
+
+func (p *iexporter) typOff(t types.Type, pkg *types.Package) uint64 {
+	off, ok := p.typIndex[t]
+	if !ok {
+		w := p.newWriter()
+		w.doTyp(t, pkg)
+		off = predeclReserved + w.flush()
+		p.typIndex[t] = off
+	}
+	return off
+}
+
+func (w *exportWriter) startType(k itag) {
+	w.data.uint64(uint64(k))
+}
+
+func (w *exportWriter) doTyp(t types.Type, pkg *types.Package) {
+	if trace {
+		w.p.trace("exporting type %s (%T)", t, t)
+		w.p.indent++
+		defer func() {
+			w.p.indent--
+			w.p.trace("=> %s", t)
+		}()
+	}
+	switch t := t.(type) {
+	case *types.Named:
+		if targs := typeparams.NamedTypeArgs(t); targs.Len() > 0 {
+			w.startType(instanceType)
+			// TODO(rfindley): investigate if this position is correct, and if it
+			// matters.
+			w.pos(t.Obj().Pos())
+			w.typeList(targs, pkg)
+			w.typ(typeparams.NamedTypeOrigin(t), pkg)
+			return
+		}
+		w.startType(definedType)
+		w.qualifiedType(t.Obj())
+
+	case *typeparams.TypeParam:
+		w.startType(typeParamType)
+		w.qualifiedType(t.Obj())
+
+	case *types.Pointer:
+		w.startType(pointerType)
+		w.typ(t.Elem(), pkg)
+
+	case *types.Slice:
+		w.startType(sliceType)
+		w.typ(t.Elem(), pkg)
+
+	case *types.Array:
+		w.startType(arrayType)
+		w.uint64(uint64(t.Len()))
+		w.typ(t.Elem(), pkg)
+
+	case *types.Chan:
+		w.startType(chanType)
+		// 1 RecvOnly; 2 SendOnly; 3 SendRecv
+		var dir uint64
+		switch t.Dir() {
+		case types.RecvOnly:
+			dir = 1
+		case types.SendOnly:
+			dir = 2
+		case types.SendRecv:
+			dir = 3
+		}
+		w.uint64(dir)
+		w.typ(t.Elem(), pkg)
+
+	case *types.Map:
+		w.startType(mapType)
+		w.typ(t.Key(), pkg)
+		w.typ(t.Elem(), pkg)
+
+	case *types.Signature:
+		w.startType(signatureType)
+		w.setPkg(pkg, true)
+		w.signature(t)
+
+	case *types.Struct:
+		w.startType(structType)
+		n := t.NumFields()
+		if n > 0 {
+			w.setPkg(t.Field(0).Pkg(), true) // qualifying package for field objects
+		} else {
+			w.setPkg(pkg, true)
+		}
+		w.uint64(uint64(n))
+		for i := 0; i < n; i++ {
+			f := t.Field(i)
+			w.pos(f.Pos())
+			w.string(f.Name()) // unexported fields implicitly qualified by prior setPkg
+			w.typ(f.Type(), pkg)
+			w.bool(f.Anonymous())
+			w.string(t.Tag(i)) // note (or tag)
+		}
+
+	case *types.Interface:
+		w.startType(interfaceType)
+		w.setPkg(pkg, true)
+
+		n := t.NumEmbeddeds()
+		w.uint64(uint64(n))
+		for i := 0; i < n; i++ {
+			ft := t.EmbeddedType(i)
+			tPkg := pkg
+			if named, _ := ft.(*types.Named); named != nil {
+				w.pos(named.Obj().Pos())
+			} else {
+				w.pos(token.NoPos)
+			}
+			w.typ(ft, tPkg)
+		}
+
+		n = t.NumExplicitMethods()
+		w.uint64(uint64(n))
+		for i := 0; i < n; i++ {
+			m := t.ExplicitMethod(i)
+			w.pos(m.Pos())
+			w.string(m.Name())
+			sig, _ := m.Type().(*types.Signature)
+			w.signature(sig)
+		}
+
+	case *typeparams.Union:
+		w.startType(unionType)
+		nt := t.Len()
+		w.uint64(uint64(nt))
+		for i := 0; i < nt; i++ {
+			term := t.Term(i)
+			w.bool(term.Tilde())
+			w.typ(term.Type(), pkg)
+		}
+
+	default:
+		panic(internalErrorf("unexpected type: %v, %v", t, reflect.TypeOf(t)))
+	}
+}
+
+func (w *exportWriter) setPkg(pkg *types.Package, write bool) {
+	if write {
+		w.pkg(pkg)
+	}
+
+	w.currPkg = pkg
+}
+
+func (w *exportWriter) signature(sig *types.Signature) {
+	w.paramList(sig.Params())
+	w.paramList(sig.Results())
+	if sig.Params().Len() > 0 {
+		w.bool(sig.Variadic())
+	}
+}
+
+func (w *exportWriter) typeList(ts *typeparams.TypeList, pkg *types.Package) {
+	w.uint64(uint64(ts.Len()))
+	for i := 0; i < ts.Len(); i++ {
+		w.typ(ts.At(i), pkg)
+	}
+}
+
+func (w *exportWriter) tparamList(prefix string, list *typeparams.TypeParamList, pkg *types.Package) {
+	ll := uint64(list.Len())
+	w.uint64(ll)
+	for i := 0; i < list.Len(); i++ {
+		tparam := list.At(i)
+		// Set the type parameter exportName before exporting its type.
+		exportName := tparamExportName(prefix, tparam)
+		w.p.tparamNames[tparam.Obj()] = exportName
+		w.typ(list.At(i), pkg)
+	}
+}
+
+const blankMarker = "$"
+
+// tparamExportName returns the 'exported' name of a type parameter, which
+// differs from its actual object name: it is prefixed with a qualifier, and
+// blank type parameter names are disambiguated by their index in the type
+// parameter list.
+func tparamExportName(prefix string, tparam *typeparams.TypeParam) string {
+	assert(prefix != "")
+	name := tparam.Obj().Name()
+	if name == "_" {
+		name = blankMarker + strconv.Itoa(tparam.Index())
+	}
+	return prefix + "." + name
+}
+
+// tparamName returns the real name of a type parameter, after stripping its
+// qualifying prefix and reverting blank-name encoding. See tparamExportName
+// for details.
+func tparamName(exportName string) string {
+	// Remove the "path" from the type param name that makes it unique.
+	ix := strings.LastIndex(exportName, ".")
+	if ix < 0 {
+		errorf("malformed type parameter export name %s: missing prefix", exportName)
+	}
+	name := exportName[ix+1:]
+	if strings.HasPrefix(name, blankMarker) {
+		return "_"
+	}
+	return name
+}
+
+func (w *exportWriter) paramList(tup *types.Tuple) {
+	n := tup.Len()
+	w.uint64(uint64(n))
+	for i := 0; i < n; i++ {
+		w.param(tup.At(i))
+	}
+}
+
+func (w *exportWriter) param(obj types.Object) {
+	w.pos(obj.Pos())
+	w.localIdent(obj)
+	w.typ(obj.Type(), obj.Pkg())
+}
+
+func (w *exportWriter) value(typ types.Type, v constant.Value) {
+	w.typ(typ, nil)
+	if w.p.version >= iexportVersionGo1_18 {
+		w.int64(int64(v.Kind()))
+	}
+
+	switch b := typ.Underlying().(*types.Basic); b.Info() & types.IsConstType {
+	case types.IsBoolean:
+		w.bool(constant.BoolVal(v))
+	case types.IsInteger:
+		var i big.Int
+		if i64, exact := constant.Int64Val(v); exact {
+			i.SetInt64(i64)
+		} else if ui64, exact := constant.Uint64Val(v); exact {
+			i.SetUint64(ui64)
+		} else {
+			i.SetString(v.ExactString(), 10)
+		}
+		w.mpint(&i, typ)
+	case types.IsFloat:
+		f := constantToFloat(v)
+		w.mpfloat(f, typ)
+	case types.IsComplex:
+		w.mpfloat(constantToFloat(constant.Real(v)), typ)
+		w.mpfloat(constantToFloat(constant.Imag(v)), typ)
+	case types.IsString:
+		w.string(constant.StringVal(v))
+	default:
+		if b.Kind() == types.Invalid {
+			// package contains type errors
+			break
+		}
+		panic(internalErrorf("unexpected type %v (%v)", typ, typ.Underlying()))
+	}
+}
+
+// constantToFloat converts a constant.Value with kind constant.Float to a
+// big.Float.
+func constantToFloat(x constant.Value) *big.Float {
+	x = constant.ToFloat(x)
+	// Use the same floating-point precision (512) as cmd/compile
+	// (see Mpprec in cmd/compile/internal/gc/mpfloat.go).
+	const mpprec = 512
+	var f big.Float
+	f.SetPrec(mpprec)
+	if v, exact := constant.Float64Val(x); exact {
+		// float64
+		f.SetFloat64(v)
+	} else if num, denom := constant.Num(x), constant.Denom(x); num.Kind() == constant.Int {
+		// TODO(gri): add big.Rat accessor to constant.Value.
+		n := valueToRat(num)
+		d := valueToRat(denom)
+		f.SetRat(n.Quo(n, d))
+	} else {
+		// Value too large to represent as a fraction => inaccessible.
+		// TODO(gri): add big.Float accessor to constant.Value.
+		_, ok := f.SetString(x.ExactString())
+		assert(ok)
+	}
+	return &f
+}
+
+// mpint exports a multi-precision integer.
+//
+// For unsigned types, small values are written out as a single
+// byte. Larger values are written out as a length-prefixed big-endian
+// byte string, where the length prefix is encoded as its complement.
+// For example, bytes 0, 1, and 2 directly represent the integer
+// values 0, 1, and 2; while bytes 255, 254, and 253 indicate a 1-,
+// 2-, and 3-byte big-endian string follow.
+//
+// Encoding for signed types use the same general approach as for
+// unsigned types, except small values use zig-zag encoding and the
+// bottom bit of length prefix byte for large values is reserved as a
+// sign bit.
+//
+// The exact boundary between small and large encodings varies
+// according to the maximum number of bytes needed to encode a value
+// of type typ. As a special case, 8-bit types are always encoded as a
+// single byte.
+//
+// TODO(mdempsky): Is this level of complexity really worthwhile?
+func (w *exportWriter) mpint(x *big.Int, typ types.Type) {
+	basic, ok := typ.Underlying().(*types.Basic)
+	if !ok {
+		panic(internalErrorf("unexpected type %v (%T)", typ.Underlying(), typ.Underlying()))
+	}
+
+	signed, maxBytes := intSize(basic)
+
+	negative := x.Sign() < 0
+	if !signed && negative {
+		panic(internalErrorf("negative unsigned integer; type %v, value %v", typ, x))
+	}
+
+	b := x.Bytes()
+	if len(b) > 0 && b[0] == 0 {
+		panic(internalErrorf("leading zeros"))
+	}
+	if uint(len(b)) > maxBytes {
+		panic(internalErrorf("bad mpint length: %d > %d (type %v, value %v)", len(b), maxBytes, typ, x))
+	}
+
+	maxSmall := 256 - maxBytes
+	if signed {
+		maxSmall = 256 - 2*maxBytes
+	}
+	if maxBytes == 1 {
+		maxSmall = 256
+	}
+
+	// Check if x can use small value encoding.
+	if len(b) <= 1 {
+		var ux uint
+		if len(b) == 1 {
+			ux = uint(b[0])
+		}
+		if signed {
+			ux <<= 1
+			if negative {
+				ux--
+			}
+		}
+		if ux < maxSmall {
+			w.data.WriteByte(byte(ux))
+			return
+		}
+	}
+
+	n := 256 - uint(len(b))
+	if signed {
+		n = 256 - 2*uint(len(b))
+		if negative {
+			n |= 1
+		}
+	}
+	if n < maxSmall || n >= 256 {
+		panic(internalErrorf("encoding mistake: %d, %v, %v => %d", len(b), signed, negative, n))
+	}
+
+	w.data.WriteByte(byte(n))
+	w.data.Write(b)
+}
+
+// mpfloat exports a multi-precision floating point number.
+//
+// The number's value is decomposed into mantissa × 2**exponent, where
+// mantissa is an integer. The value is written out as mantissa (as a
+// multi-precision integer) and then the exponent, except exponent is
+// omitted if mantissa is zero.
+func (w *exportWriter) mpfloat(f *big.Float, typ types.Type) {
+	if f.IsInf() {
+		panic("infinite constant")
+	}
+
+	// Break into f = mant × 2**exp, with 0.5 <= mant < 1.
+	var mant big.Float
+	exp := int64(f.MantExp(&mant))
+
+	// Scale so that mant is an integer.
+	prec := mant.MinPrec()
+	mant.SetMantExp(&mant, int(prec))
+	exp -= int64(prec)
+
+	manti, acc := mant.Int(nil)
+	if acc != big.Exact {
+		panic(internalErrorf("mantissa scaling failed for %f (%s)", f, acc))
+	}
+	w.mpint(manti, typ)
+	if manti.Sign() != 0 {
+		w.int64(exp)
+	}
+}
+
+func (w *exportWriter) bool(b bool) bool {
+	var x uint64
+	if b {
+		x = 1
+	}
+	w.uint64(x)
+	return b
+}
+
+func (w *exportWriter) int64(x int64)   { w.data.int64(x) }
+func (w *exportWriter) uint64(x uint64) { w.data.uint64(x) }
+func (w *exportWriter) string(s string) { w.uint64(w.p.stringOff(s)) }
+
+func (w *exportWriter) localIdent(obj types.Object) {
+	// Anonymous parameters.
+	if obj == nil {
+		w.string("")
+		return
+	}
+
+	name := obj.Name()
+	if name == "_" {
+		w.string("_")
+		return
+	}
+
+	w.string(name)
+}
+
+type intWriter struct {
+	bytes.Buffer
+}
+
+func (w *intWriter) int64(x int64) {
+	var buf [binary.MaxVarintLen64]byte
+	n := binary.PutVarint(buf[:], x)
+	w.Write(buf[:n])
+}
+
+func (w *intWriter) uint64(x uint64) {
+	var buf [binary.MaxVarintLen64]byte
+	n := binary.PutUvarint(buf[:], x)
+	w.Write(buf[:n])
+}
+
+func assert(cond bool) {
+	if !cond {
+		panic("internal error: assertion failed")
+	}
+}
+
+// The below is copied from go/src/cmd/compile/internal/gc/syntax.go.
+
+// objQueue is a FIFO queue of types.Object. The zero value of objQueue is
+// a ready-to-use empty queue.
+type objQueue struct {
+	ring       []types.Object
+	head, tail int
+}
+
+// empty returns true if q contains no Nodes.
+func (q *objQueue) empty() bool {
+	return q.head == q.tail
+}
+
+// pushTail appends n to the tail of the queue.
+func (q *objQueue) pushTail(obj types.Object) {
+	if len(q.ring) == 0 {
+		q.ring = make([]types.Object, 16)
+	} else if q.head+len(q.ring) == q.tail {
+		// Grow the ring.
+		nring := make([]types.Object, len(q.ring)*2)
+		// Copy the old elements.
+		part := q.ring[q.head%len(q.ring):]
+		if q.tail-q.head <= len(part) {
+			part = part[:q.tail-q.head]
+			copy(nring, part)
+		} else {
+			pos := copy(nring, part)
+			copy(nring[pos:], q.ring[:q.tail%len(q.ring)])
+		}
+		q.ring, q.head, q.tail = nring, 0, q.tail-q.head
+	}
+
+	q.ring[q.tail%len(q.ring)] = obj
+	q.tail++
+}
+
+// popHead pops a node from the head of the queue. It panics if q is empty.
+func (q *objQueue) popHead() types.Object {
+	if q.empty() {
+		panic("dequeue empty")
+	}
+	obj := q.ring[q.head%len(q.ring)]
+	q.head++
+	return obj
+}
diff --git a/vendor/golang.org/x/tools/internal/gcimporter/iimport.go b/vendor/golang.org/x/tools/internal/gcimporter/iimport.go
new file mode 100644
index 0000000..448f903
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/gcimporter/iimport.go
@@ -0,0 +1,976 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Indexed package import.
+// See cmd/compile/internal/gc/iexport.go for the export data format.
+
+// This file is a copy of $GOROOT/src/go/internal/gcimporter/iimport.go.
+
+package gcimporter
+
+import (
+	"bytes"
+	"encoding/binary"
+	"fmt"
+	"go/constant"
+	"go/token"
+	"go/types"
+	"io"
+	"math/big"
+	"sort"
+	"strings"
+
+	"golang.org/x/tools/internal/typeparams"
+)
+
+type intReader struct {
+	*bytes.Reader
+	path string
+}
+
+func (r *intReader) int64() int64 {
+	i, err := binary.ReadVarint(r.Reader)
+	if err != nil {
+		errorf("import %q: read varint error: %v", r.path, err)
+	}
+	return i
+}
+
+func (r *intReader) uint64() uint64 {
+	i, err := binary.ReadUvarint(r.Reader)
+	if err != nil {
+		errorf("import %q: read varint error: %v", r.path, err)
+	}
+	return i
+}
+
+// Keep this in sync with constants in iexport.go.
+const (
+	iexportVersionGo1_11   = 0
+	iexportVersionPosCol   = 1
+	iexportVersionGo1_18   = 2
+	iexportVersionGenerics = 2
+
+	iexportVersionCurrent = 2
+)
+
+type ident struct {
+	pkg  *types.Package
+	name string
+}
+
+const predeclReserved = 32
+
+type itag uint64
+
+const (
+	// Types
+	definedType itag = iota
+	pointerType
+	sliceType
+	arrayType
+	chanType
+	mapType
+	signatureType
+	structType
+	interfaceType
+	typeParamType
+	instanceType
+	unionType
+)
+
+// IImportData imports a package from the serialized package data
+// and returns 0 and a reference to the package.
+// If the export data version is not recognized or the format is otherwise
+// compromised, an error is returned.
+func IImportData(fset *token.FileSet, imports map[string]*types.Package, data []byte, path string) (int, *types.Package, error) {
+	pkgs, err := iimportCommon(fset, imports, data, false, path, nil)
+	if err != nil {
+		return 0, nil, err
+	}
+	return 0, pkgs[0], nil
+}
+
+// IImportBundle imports a set of packages from the serialized package bundle.
+func IImportBundle(fset *token.FileSet, imports map[string]*types.Package, data []byte) ([]*types.Package, error) {
+	return iimportCommon(fset, imports, data, true, "", nil)
+}
+
+func iimportCommon(fset *token.FileSet, imports map[string]*types.Package, data []byte, bundle bool, path string, insert InsertType) (pkgs []*types.Package, err error) {
+	const currentVersion = iexportVersionCurrent
+	version := int64(-1)
+	if !debug {
+		defer func() {
+			if e := recover(); e != nil {
+				if bundle {
+					err = fmt.Errorf("%v", e)
+				} else if version > currentVersion {
+					err = fmt.Errorf("cannot import %q (%v), export data is newer version - update tool", path, e)
+				} else {
+					err = fmt.Errorf("cannot import %q (%v), possibly version skew - reinstall package", path, e)
+				}
+			}
+		}()
+	}
+
+	r := &intReader{bytes.NewReader(data), path}
+
+	if bundle {
+		bundleVersion := r.uint64()
+		switch bundleVersion {
+		case bundleVersion:
+		default:
+			errorf("unknown bundle format version %d", bundleVersion)
+		}
+	}
+
+	version = int64(r.uint64())
+	switch version {
+	case iexportVersionGo1_18, iexportVersionPosCol, iexportVersionGo1_11:
+	default:
+		if version > iexportVersionGo1_18 {
+			errorf("unstable iexport format version %d, just rebuild compiler and std library", version)
+		} else {
+			errorf("unknown iexport format version %d", version)
+		}
+	}
+
+	sLen := int64(r.uint64())
+	var fLen int64
+	var fileOffset []uint64
+	if insert != nil {
+		// Shallow mode uses a different position encoding.
+		fLen = int64(r.uint64())
+		fileOffset = make([]uint64, r.uint64())
+		for i := range fileOffset {
+			fileOffset[i] = r.uint64()
+		}
+	}
+	dLen := int64(r.uint64())
+
+	whence, _ := r.Seek(0, io.SeekCurrent)
+	stringData := data[whence : whence+sLen]
+	fileData := data[whence+sLen : whence+sLen+fLen]
+	declData := data[whence+sLen+fLen : whence+sLen+fLen+dLen]
+	r.Seek(sLen+fLen+dLen, io.SeekCurrent)
+
+	p := iimporter{
+		version: int(version),
+		ipath:   path,
+		insert:  insert,
+
+		stringData:  stringData,
+		stringCache: make(map[uint64]string),
+		fileOffset:  fileOffset,
+		fileData:    fileData,
+		fileCache:   make([]*token.File, len(fileOffset)),
+		pkgCache:    make(map[uint64]*types.Package),
+
+		declData: declData,
+		pkgIndex: make(map[*types.Package]map[string]uint64),
+		typCache: make(map[uint64]types.Type),
+		// Separate map for typeparams, keyed by their package and unique
+		// name.
+		tparamIndex: make(map[ident]types.Type),
+
+		fake: fakeFileSet{
+			fset:  fset,
+			files: make(map[string]*fileInfo),
+		},
+	}
+	defer p.fake.setLines() // set lines for files in fset
+
+	for i, pt := range predeclared() {
+		p.typCache[uint64(i)] = pt
+	}
+
+	pkgList := make([]*types.Package, r.uint64())
+	for i := range pkgList {
+		pkgPathOff := r.uint64()
+		pkgPath := p.stringAt(pkgPathOff)
+		pkgName := p.stringAt(r.uint64())
+		_ = r.uint64() // package height; unused by go/types
+
+		if pkgPath == "" {
+			pkgPath = path
+		}
+		pkg := imports[pkgPath]
+		if pkg == nil {
+			pkg = types.NewPackage(pkgPath, pkgName)
+			imports[pkgPath] = pkg
+		} else if pkg.Name() != pkgName {
+			errorf("conflicting names %s and %s for package %q", pkg.Name(), pkgName, path)
+		}
+		if i == 0 && !bundle {
+			p.localpkg = pkg
+		}
+
+		p.pkgCache[pkgPathOff] = pkg
+
+		// Read index for package.
+		nameIndex := make(map[string]uint64)
+		nSyms := r.uint64()
+		// In shallow mode we don't expect an index for other packages.
+		assert(nSyms == 0 || p.localpkg == pkg || p.insert == nil)
+		for ; nSyms > 0; nSyms-- {
+			name := p.stringAt(r.uint64())
+			nameIndex[name] = r.uint64()
+		}
+
+		p.pkgIndex[pkg] = nameIndex
+		pkgList[i] = pkg
+	}
+
+	if bundle {
+		pkgs = make([]*types.Package, r.uint64())
+		for i := range pkgs {
+			pkg := p.pkgAt(r.uint64())
+			imps := make([]*types.Package, r.uint64())
+			for j := range imps {
+				imps[j] = p.pkgAt(r.uint64())
+			}
+			pkg.SetImports(imps)
+			pkgs[i] = pkg
+		}
+	} else {
+		if len(pkgList) == 0 {
+			errorf("no packages found for %s", path)
+			panic("unreachable")
+		}
+		pkgs = pkgList[:1]
+
+		// record all referenced packages as imports
+		list := append(([]*types.Package)(nil), pkgList[1:]...)
+		sort.Sort(byPath(list))
+		pkgs[0].SetImports(list)
+	}
+
+	for _, pkg := range pkgs {
+		if pkg.Complete() {
+			continue
+		}
+
+		names := make([]string, 0, len(p.pkgIndex[pkg]))
+		for name := range p.pkgIndex[pkg] {
+			names = append(names, name)
+		}
+		sort.Strings(names)
+		for _, name := range names {
+			p.doDecl(pkg, name)
+		}
+
+		// package was imported completely and without errors
+		pkg.MarkComplete()
+	}
+
+	// SetConstraint can't be called if the constraint type is not yet complete.
+	// When type params are created in the 'P' case of (*importReader).obj(),
+	// the associated constraint type may not be complete due to recursion.
+	// Therefore, we defer calling SetConstraint there, and call it here instead
+	// after all types are complete.
+	for _, d := range p.later {
+		typeparams.SetTypeParamConstraint(d.t, d.constraint)
+	}
+
+	for _, typ := range p.interfaceList {
+		typ.Complete()
+	}
+
+	return pkgs, nil
+}
+
+type setConstraintArgs struct {
+	t          *typeparams.TypeParam
+	constraint types.Type
+}
+
+type iimporter struct {
+	version int
+	ipath   string
+
+	localpkg *types.Package
+	insert   func(pkg *types.Package, name string) // "shallow" mode only
+
+	stringData  []byte
+	stringCache map[uint64]string
+	fileOffset  []uint64 // fileOffset[i] is offset in fileData for info about file encoded as i
+	fileData    []byte
+	fileCache   []*token.File // memoized decoding of file encoded as i
+	pkgCache    map[uint64]*types.Package
+
+	declData    []byte
+	pkgIndex    map[*types.Package]map[string]uint64
+	typCache    map[uint64]types.Type
+	tparamIndex map[ident]types.Type
+
+	fake          fakeFileSet
+	interfaceList []*types.Interface
+
+	// Arguments for calls to SetConstraint that are deferred due to recursive types
+	later []setConstraintArgs
+
+	indent int // for tracing support
+}
+
+func (p *iimporter) trace(format string, args ...interface{}) {
+	if !trace {
+		// Call sites should also be guarded, but having this check here allows
+		// easily enabling/disabling debug trace statements.
+		return
+	}
+	fmt.Printf(strings.Repeat("..", p.indent)+format+"\n", args...)
+}
+
+func (p *iimporter) doDecl(pkg *types.Package, name string) {
+	if debug {
+		p.trace("import decl %s", name)
+		p.indent++
+		defer func() {
+			p.indent--
+			p.trace("=> %s", name)
+		}()
+	}
+	// See if we've already imported this declaration.
+	if obj := pkg.Scope().Lookup(name); obj != nil {
+		return
+	}
+
+	off, ok := p.pkgIndex[pkg][name]
+	if !ok {
+		// In "shallow" mode, call back to the application to
+		// find the object and insert it into the package scope.
+		if p.insert != nil {
+			assert(pkg != p.localpkg)
+			p.insert(pkg, name) // "can't fail"
+			return
+		}
+		errorf("%v.%v not in index", pkg, name)
+	}
+
+	r := &importReader{p: p, currPkg: pkg}
+	r.declReader.Reset(p.declData[off:])
+
+	r.obj(name)
+}
+
+func (p *iimporter) stringAt(off uint64) string {
+	if s, ok := p.stringCache[off]; ok {
+		return s
+	}
+
+	slen, n := binary.Uvarint(p.stringData[off:])
+	if n <= 0 {
+		errorf("varint failed")
+	}
+	spos := off + uint64(n)
+	s := string(p.stringData[spos : spos+slen])
+	p.stringCache[off] = s
+	return s
+}
+
+func (p *iimporter) fileAt(index uint64) *token.File {
+	file := p.fileCache[index]
+	if file == nil {
+		off := p.fileOffset[index]
+		file = p.decodeFile(intReader{bytes.NewReader(p.fileData[off:]), p.ipath})
+		p.fileCache[index] = file
+	}
+	return file
+}
+
+func (p *iimporter) decodeFile(rd intReader) *token.File {
+	filename := p.stringAt(rd.uint64())
+	size := int(rd.uint64())
+	file := p.fake.fset.AddFile(filename, -1, size)
+
+	// SetLines requires a nondecreasing sequence.
+	// Because it is common for clients to derive the interval
+	// [start, start+len(name)] from a start position, and we
+	// want to ensure that the end offset is on the same line,
+	// we fill in the gaps of the sparse encoding with values
+	// that strictly increase by the largest possible amount.
+	// This allows us to avoid having to record the actual end
+	// offset of each needed line.
+
+	lines := make([]int, int(rd.uint64()))
+	var index, offset int
+	for i, n := 0, int(rd.uint64()); i < n; i++ {
+		index += int(rd.uint64())
+		offset += int(rd.uint64())
+		lines[index] = offset
+
+		// Ensure monotonicity between points.
+		for j := index - 1; j > 0 && lines[j] == 0; j-- {
+			lines[j] = lines[j+1] - 1
+		}
+	}
+
+	// Ensure monotonicity after last point.
+	for j := len(lines) - 1; j > 0 && lines[j] == 0; j-- {
+		size--
+		lines[j] = size
+	}
+
+	if !file.SetLines(lines) {
+		errorf("SetLines failed: %d", lines) // can't happen
+	}
+	return file
+}
+
+func (p *iimporter) pkgAt(off uint64) *types.Package {
+	if pkg, ok := p.pkgCache[off]; ok {
+		return pkg
+	}
+	path := p.stringAt(off)
+	errorf("missing package %q in %q", path, p.ipath)
+	return nil
+}
+
+func (p *iimporter) typAt(off uint64, base *types.Named) types.Type {
+	if t, ok := p.typCache[off]; ok && canReuse(base, t) {
+		return t
+	}
+
+	if off < predeclReserved {
+		errorf("predeclared type missing from cache: %v", off)
+	}
+
+	r := &importReader{p: p}
+	r.declReader.Reset(p.declData[off-predeclReserved:])
+	t := r.doType(base)
+
+	if canReuse(base, t) {
+		p.typCache[off] = t
+	}
+	return t
+}
+
+// canReuse reports whether the type rhs on the RHS of the declaration for def
+// may be re-used.
+//
+// Specifically, if def is non-nil and rhs is an interface type with methods, it
+// may not be re-used because we have a convention of setting the receiver type
+// for interface methods to def.
+func canReuse(def *types.Named, rhs types.Type) bool {
+	if def == nil {
+		return true
+	}
+	iface, _ := rhs.(*types.Interface)
+	if iface == nil {
+		return true
+	}
+	// Don't use iface.Empty() here as iface may not be complete.
+	return iface.NumEmbeddeds() == 0 && iface.NumExplicitMethods() == 0
+}
+
+type importReader struct {
+	p          *iimporter
+	declReader bytes.Reader
+	currPkg    *types.Package
+	prevFile   string
+	prevLine   int64
+	prevColumn int64
+}
+
+func (r *importReader) obj(name string) {
+	tag := r.byte()
+	pos := r.pos()
+
+	switch tag {
+	case 'A':
+		typ := r.typ()
+
+		r.declare(types.NewTypeName(pos, r.currPkg, name, typ))
+
+	case 'C':
+		typ, val := r.value()
+
+		r.declare(types.NewConst(pos, r.currPkg, name, typ, val))
+
+	case 'F', 'G':
+		var tparams []*typeparams.TypeParam
+		if tag == 'G' {
+			tparams = r.tparamList()
+		}
+		sig := r.signature(nil, nil, tparams)
+		r.declare(types.NewFunc(pos, r.currPkg, name, sig))
+
+	case 'T', 'U':
+		// Types can be recursive. We need to setup a stub
+		// declaration before recursing.
+		obj := types.NewTypeName(pos, r.currPkg, name, nil)
+		named := types.NewNamed(obj, nil, nil)
+		// Declare obj before calling r.tparamList, so the new type name is recognized
+		// if used in the constraint of one of its own typeparams (see #48280).
+		r.declare(obj)
+		if tag == 'U' {
+			tparams := r.tparamList()
+			typeparams.SetForNamed(named, tparams)
+		}
+
+		underlying := r.p.typAt(r.uint64(), named).Underlying()
+		named.SetUnderlying(underlying)
+
+		if !isInterface(underlying) {
+			for n := r.uint64(); n > 0; n-- {
+				mpos := r.pos()
+				mname := r.ident()
+				recv := r.param()
+
+				// If the receiver has any targs, set those as the
+				// rparams of the method (since those are the
+				// typeparams being used in the method sig/body).
+				base := baseType(recv.Type())
+				assert(base != nil)
+				targs := typeparams.NamedTypeArgs(base)
+				var rparams []*typeparams.TypeParam
+				if targs.Len() > 0 {
+					rparams = make([]*typeparams.TypeParam, targs.Len())
+					for i := range rparams {
+						rparams[i] = targs.At(i).(*typeparams.TypeParam)
+					}
+				}
+				msig := r.signature(recv, rparams, nil)
+
+				named.AddMethod(types.NewFunc(mpos, r.currPkg, mname, msig))
+			}
+		}
+
+	case 'P':
+		// We need to "declare" a typeparam in order to have a name that
+		// can be referenced recursively (if needed) in the type param's
+		// bound.
+		if r.p.version < iexportVersionGenerics {
+			errorf("unexpected type param type")
+		}
+		name0 := tparamName(name)
+		tn := types.NewTypeName(pos, r.currPkg, name0, nil)
+		t := typeparams.NewTypeParam(tn, nil)
+
+		// To handle recursive references to the typeparam within its
+		// bound, save the partial type in tparamIndex before reading the bounds.
+		id := ident{r.currPkg, name}
+		r.p.tparamIndex[id] = t
+		var implicit bool
+		if r.p.version >= iexportVersionGo1_18 {
+			implicit = r.bool()
+		}
+		constraint := r.typ()
+		if implicit {
+			iface, _ := constraint.(*types.Interface)
+			if iface == nil {
+				errorf("non-interface constraint marked implicit")
+			}
+			typeparams.MarkImplicit(iface)
+		}
+		// The constraint type may not be complete, if we
+		// are in the middle of a type recursion involving type
+		// constraints. So, we defer SetConstraint until we have
+		// completely set up all types in ImportData.
+		r.p.later = append(r.p.later, setConstraintArgs{t: t, constraint: constraint})
+
+	case 'V':
+		typ := r.typ()
+
+		r.declare(types.NewVar(pos, r.currPkg, name, typ))
+
+	default:
+		errorf("unexpected tag: %v", tag)
+	}
+}
+
+func (r *importReader) declare(obj types.Object) {
+	obj.Pkg().Scope().Insert(obj)
+}
+
+func (r *importReader) value() (typ types.Type, val constant.Value) {
+	typ = r.typ()
+	if r.p.version >= iexportVersionGo1_18 {
+		// TODO: add support for using the kind.
+		_ = constant.Kind(r.int64())
+	}
+
+	switch b := typ.Underlying().(*types.Basic); b.Info() & types.IsConstType {
+	case types.IsBoolean:
+		val = constant.MakeBool(r.bool())
+
+	case types.IsString:
+		val = constant.MakeString(r.string())
+
+	case types.IsInteger:
+		var x big.Int
+		r.mpint(&x, b)
+		val = constant.Make(&x)
+
+	case types.IsFloat:
+		val = r.mpfloat(b)
+
+	case types.IsComplex:
+		re := r.mpfloat(b)
+		im := r.mpfloat(b)
+		val = constant.BinaryOp(re, token.ADD, constant.MakeImag(im))
+
+	default:
+		if b.Kind() == types.Invalid {
+			val = constant.MakeUnknown()
+			return
+		}
+		errorf("unexpected type %v", typ) // panics
+		panic("unreachable")
+	}
+
+	return
+}
+
+func intSize(b *types.Basic) (signed bool, maxBytes uint) {
+	if (b.Info() & types.IsUntyped) != 0 {
+		return true, 64
+	}
+
+	switch b.Kind() {
+	case types.Float32, types.Complex64:
+		return true, 3
+	case types.Float64, types.Complex128:
+		return true, 7
+	}
+
+	signed = (b.Info() & types.IsUnsigned) == 0
+	switch b.Kind() {
+	case types.Int8, types.Uint8:
+		maxBytes = 1
+	case types.Int16, types.Uint16:
+		maxBytes = 2
+	case types.Int32, types.Uint32:
+		maxBytes = 4
+	default:
+		maxBytes = 8
+	}
+
+	return
+}
+
+func (r *importReader) mpint(x *big.Int, typ *types.Basic) {
+	signed, maxBytes := intSize(typ)
+
+	maxSmall := 256 - maxBytes
+	if signed {
+		maxSmall = 256 - 2*maxBytes
+	}
+	if maxBytes == 1 {
+		maxSmall = 256
+	}
+
+	n, _ := r.declReader.ReadByte()
+	if uint(n) < maxSmall {
+		v := int64(n)
+		if signed {
+			v >>= 1
+			if n&1 != 0 {
+				v = ^v
+			}
+		}
+		x.SetInt64(v)
+		return
+	}
+
+	v := -n
+	if signed {
+		v = -(n &^ 1) >> 1
+	}
+	if v < 1 || uint(v) > maxBytes {
+		errorf("weird decoding: %v, %v => %v", n, signed, v)
+	}
+	b := make([]byte, v)
+	io.ReadFull(&r.declReader, b)
+	x.SetBytes(b)
+	if signed && n&1 != 0 {
+		x.Neg(x)
+	}
+}
+
+func (r *importReader) mpfloat(typ *types.Basic) constant.Value {
+	var mant big.Int
+	r.mpint(&mant, typ)
+	var f big.Float
+	f.SetInt(&mant)
+	if f.Sign() != 0 {
+		f.SetMantExp(&f, int(r.int64()))
+	}
+	return constant.Make(&f)
+}
+
+func (r *importReader) ident() string {
+	return r.string()
+}
+
+func (r *importReader) qualifiedIdent() (*types.Package, string) {
+	name := r.string()
+	pkg := r.pkg()
+	return pkg, name
+}
+
+func (r *importReader) pos() token.Pos {
+	if r.p.insert != nil { // shallow mode
+		return r.posv2()
+	}
+	if r.p.version >= iexportVersionPosCol {
+		r.posv1()
+	} else {
+		r.posv0()
+	}
+
+	if r.prevFile == "" && r.prevLine == 0 && r.prevColumn == 0 {
+		return token.NoPos
+	}
+	return r.p.fake.pos(r.prevFile, int(r.prevLine), int(r.prevColumn))
+}
+
+func (r *importReader) posv0() {
+	delta := r.int64()
+	if delta != deltaNewFile {
+		r.prevLine += delta
+	} else if l := r.int64(); l == -1 {
+		r.prevLine += deltaNewFile
+	} else {
+		r.prevFile = r.string()
+		r.prevLine = l
+	}
+}
+
+func (r *importReader) posv1() {
+	delta := r.int64()
+	r.prevColumn += delta >> 1
+	if delta&1 != 0 {
+		delta = r.int64()
+		r.prevLine += delta >> 1
+		if delta&1 != 0 {
+			r.prevFile = r.string()
+		}
+	}
+}
+
+func (r *importReader) posv2() token.Pos {
+	file := r.uint64()
+	if file == 0 {
+		return token.NoPos
+	}
+	tf := r.p.fileAt(file - 1)
+	return tf.Pos(int(r.uint64()))
+}
+
+func (r *importReader) typ() types.Type {
+	return r.p.typAt(r.uint64(), nil)
+}
+
+func isInterface(t types.Type) bool {
+	_, ok := t.(*types.Interface)
+	return ok
+}
+
+func (r *importReader) pkg() *types.Package { return r.p.pkgAt(r.uint64()) }
+func (r *importReader) string() string      { return r.p.stringAt(r.uint64()) }
+
+func (r *importReader) doType(base *types.Named) (res types.Type) {
+	k := r.kind()
+	if debug {
+		r.p.trace("importing type %d (base: %s)", k, base)
+		r.p.indent++
+		defer func() {
+			r.p.indent--
+			r.p.trace("=> %s", res)
+		}()
+	}
+	switch k {
+	default:
+		errorf("unexpected kind tag in %q: %v", r.p.ipath, k)
+		return nil
+
+	case definedType:
+		pkg, name := r.qualifiedIdent()
+		r.p.doDecl(pkg, name)
+		return pkg.Scope().Lookup(name).(*types.TypeName).Type()
+	case pointerType:
+		return types.NewPointer(r.typ())
+	case sliceType:
+		return types.NewSlice(r.typ())
+	case arrayType:
+		n := r.uint64()
+		return types.NewArray(r.typ(), int64(n))
+	case chanType:
+		dir := chanDir(int(r.uint64()))
+		return types.NewChan(dir, r.typ())
+	case mapType:
+		return types.NewMap(r.typ(), r.typ())
+	case signatureType:
+		r.currPkg = r.pkg()
+		return r.signature(nil, nil, nil)
+
+	case structType:
+		r.currPkg = r.pkg()
+
+		fields := make([]*types.Var, r.uint64())
+		tags := make([]string, len(fields))
+		for i := range fields {
+			fpos := r.pos()
+			fname := r.ident()
+			ftyp := r.typ()
+			emb := r.bool()
+			tag := r.string()
+
+			fields[i] = types.NewField(fpos, r.currPkg, fname, ftyp, emb)
+			tags[i] = tag
+		}
+		return types.NewStruct(fields, tags)
+
+	case interfaceType:
+		r.currPkg = r.pkg()
+
+		embeddeds := make([]types.Type, r.uint64())
+		for i := range embeddeds {
+			_ = r.pos()
+			embeddeds[i] = r.typ()
+		}
+
+		methods := make([]*types.Func, r.uint64())
+		for i := range methods {
+			mpos := r.pos()
+			mname := r.ident()
+
+			// TODO(mdempsky): Matches bimport.go, but I
+			// don't agree with this.
+			var recv *types.Var
+			if base != nil {
+				recv = types.NewVar(token.NoPos, r.currPkg, "", base)
+			}
+
+			msig := r.signature(recv, nil, nil)
+			methods[i] = types.NewFunc(mpos, r.currPkg, mname, msig)
+		}
+
+		typ := newInterface(methods, embeddeds)
+		r.p.interfaceList = append(r.p.interfaceList, typ)
+		return typ
+
+	case typeParamType:
+		if r.p.version < iexportVersionGenerics {
+			errorf("unexpected type param type")
+		}
+		pkg, name := r.qualifiedIdent()
+		id := ident{pkg, name}
+		if t, ok := r.p.tparamIndex[id]; ok {
+			// We're already in the process of importing this typeparam.
+			return t
+		}
+		// Otherwise, import the definition of the typeparam now.
+		r.p.doDecl(pkg, name)
+		return r.p.tparamIndex[id]
+
+	case instanceType:
+		if r.p.version < iexportVersionGenerics {
+			errorf("unexpected instantiation type")
+		}
+		// pos does not matter for instances: they are positioned on the original
+		// type.
+		_ = r.pos()
+		len := r.uint64()
+		targs := make([]types.Type, len)
+		for i := range targs {
+			targs[i] = r.typ()
+		}
+		baseType := r.typ()
+		// The imported instantiated type doesn't include any methods, so
+		// we must always use the methods of the base (orig) type.
+		// TODO provide a non-nil *Environment
+		t, _ := typeparams.Instantiate(nil, baseType, targs, false)
+		return t
+
+	case unionType:
+		if r.p.version < iexportVersionGenerics {
+			errorf("unexpected instantiation type")
+		}
+		terms := make([]*typeparams.Term, r.uint64())
+		for i := range terms {
+			terms[i] = typeparams.NewTerm(r.bool(), r.typ())
+		}
+		return typeparams.NewUnion(terms)
+	}
+}
+
+func (r *importReader) kind() itag {
+	return itag(r.uint64())
+}
+
+func (r *importReader) signature(recv *types.Var, rparams []*typeparams.TypeParam, tparams []*typeparams.TypeParam) *types.Signature {
+	params := r.paramList()
+	results := r.paramList()
+	variadic := params.Len() > 0 && r.bool()
+	return typeparams.NewSignatureType(recv, rparams, tparams, params, results, variadic)
+}
+
+func (r *importReader) tparamList() []*typeparams.TypeParam {
+	n := r.uint64()
+	if n == 0 {
+		return nil
+	}
+	xs := make([]*typeparams.TypeParam, n)
+	for i := range xs {
+		// Note: the standard library importer is tolerant of nil types here,
+		// though would panic in SetTypeParams.
+		xs[i] = r.typ().(*typeparams.TypeParam)
+	}
+	return xs
+}
+
+func (r *importReader) paramList() *types.Tuple {
+	xs := make([]*types.Var, r.uint64())
+	for i := range xs {
+		xs[i] = r.param()
+	}
+	return types.NewTuple(xs...)
+}
+
+func (r *importReader) param() *types.Var {
+	pos := r.pos()
+	name := r.ident()
+	typ := r.typ()
+	return types.NewParam(pos, r.currPkg, name, typ)
+}
+
+func (r *importReader) bool() bool {
+	return r.uint64() != 0
+}
+
+func (r *importReader) int64() int64 {
+	n, err := binary.ReadVarint(&r.declReader)
+	if err != nil {
+		errorf("readVarint: %v", err)
+	}
+	return n
+}
+
+func (r *importReader) uint64() uint64 {
+	n, err := binary.ReadUvarint(&r.declReader)
+	if err != nil {
+		errorf("readUvarint: %v", err)
+	}
+	return n
+}
+
+func (r *importReader) byte() byte {
+	x, err := r.declReader.ReadByte()
+	if err != nil {
+		errorf("declReader.ReadByte: %v", err)
+	}
+	return x
+}
+
+func baseType(typ types.Type) *types.Named {
+	// pointer receivers are never types.Named types
+	if p, _ := typ.(*types.Pointer); p != nil {
+		typ = p.Elem()
+	}
+	// receiver base types are always (possibly generic) types.Named types
+	n, _ := typ.(*types.Named)
+	return n
+}
diff --git a/vendor/golang.org/x/tools/internal/gcimporter/newInterface10.go b/vendor/golang.org/x/tools/internal/gcimporter/newInterface10.go
new file mode 100644
index 0000000..8b163e3
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/gcimporter/newInterface10.go
@@ -0,0 +1,22 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build !go1.11
+// +build !go1.11
+
+package gcimporter
+
+import "go/types"
+
+func newInterface(methods []*types.Func, embeddeds []types.Type) *types.Interface {
+	named := make([]*types.Named, len(embeddeds))
+	for i, e := range embeddeds {
+		var ok bool
+		named[i], ok = e.(*types.Named)
+		if !ok {
+			panic("embedding of non-defined interfaces in interfaces is not supported before Go 1.11")
+		}
+	}
+	return types.NewInterface(methods, named)
+}
diff --git a/vendor/golang.org/x/tools/internal/gcimporter/newInterface11.go b/vendor/golang.org/x/tools/internal/gcimporter/newInterface11.go
new file mode 100644
index 0000000..49984f4
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/gcimporter/newInterface11.go
@@ -0,0 +1,14 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build go1.11
+// +build go1.11
+
+package gcimporter
+
+import "go/types"
+
+func newInterface(methods []*types.Func, embeddeds []types.Type) *types.Interface {
+	return types.NewInterfaceType(methods, embeddeds)
+}
diff --git a/vendor/golang.org/x/tools/internal/gcimporter/support_go117.go b/vendor/golang.org/x/tools/internal/gcimporter/support_go117.go
new file mode 100644
index 0000000..d892273
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/gcimporter/support_go117.go
@@ -0,0 +1,16 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build !go1.18
+// +build !go1.18
+
+package gcimporter
+
+import "go/types"
+
+const iexportVersion = iexportVersionGo1_11
+
+func additionalPredeclared() []types.Type {
+	return nil
+}
diff --git a/vendor/golang.org/x/tools/internal/gcimporter/support_go118.go b/vendor/golang.org/x/tools/internal/gcimporter/support_go118.go
new file mode 100644
index 0000000..edbe6ea
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/gcimporter/support_go118.go
@@ -0,0 +1,37 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build go1.18
+// +build go1.18
+
+package gcimporter
+
+import "go/types"
+
+const iexportVersion = iexportVersionGenerics
+
+// additionalPredeclared returns additional predeclared types in go.1.18.
+func additionalPredeclared() []types.Type {
+	return []types.Type{
+		// comparable
+		types.Universe.Lookup("comparable").Type(),
+
+		// any
+		types.Universe.Lookup("any").Type(),
+	}
+}
+
+// See cmd/compile/internal/types.SplitVargenSuffix.
+func splitVargenSuffix(name string) (base, suffix string) {
+	i := len(name)
+	for i > 0 && name[i-1] >= '0' && name[i-1] <= '9' {
+		i--
+	}
+	const dot = "·"
+	if i >= len(dot) && name[i-len(dot):i] == dot {
+		i -= len(dot)
+		return name[:i], name[i:]
+	}
+	return name, ""
+}
diff --git a/vendor/golang.org/x/tools/internal/gcimporter/unified_no.go b/vendor/golang.org/x/tools/internal/gcimporter/unified_no.go
new file mode 100644
index 0000000..286bf44
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/gcimporter/unified_no.go
@@ -0,0 +1,10 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build !(go1.18 && goexperiment.unified)
+// +build !go1.18 !goexperiment.unified
+
+package gcimporter
+
+const unifiedIR = false
diff --git a/vendor/golang.org/x/tools/internal/gcimporter/unified_yes.go b/vendor/golang.org/x/tools/internal/gcimporter/unified_yes.go
new file mode 100644
index 0000000..b5d69ff
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/gcimporter/unified_yes.go
@@ -0,0 +1,10 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build go1.18 && goexperiment.unified
+// +build go1.18,goexperiment.unified
+
+package gcimporter
+
+const unifiedIR = true
diff --git a/vendor/golang.org/x/tools/internal/gcimporter/ureader_no.go b/vendor/golang.org/x/tools/internal/gcimporter/ureader_no.go
new file mode 100644
index 0000000..8eb2072
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/gcimporter/ureader_no.go
@@ -0,0 +1,19 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build !go1.18
+// +build !go1.18
+
+package gcimporter
+
+import (
+	"fmt"
+	"go/token"
+	"go/types"
+)
+
+func UImportData(fset *token.FileSet, imports map[string]*types.Package, data []byte, path string) (_ int, pkg *types.Package, err error) {
+	err = fmt.Errorf("go/tools compiled with a Go version earlier than 1.18 cannot read unified IR export data")
+	return
+}
diff --git a/vendor/golang.org/x/tools/internal/gcimporter/ureader_yes.go b/vendor/golang.org/x/tools/internal/gcimporter/ureader_yes.go
new file mode 100644
index 0000000..34fc783
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/gcimporter/ureader_yes.go
@@ -0,0 +1,719 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Derived from go/internal/gcimporter/ureader.go
+
+//go:build go1.18
+// +build go1.18
+
+package gcimporter
+
+import (
+	"go/token"
+	"go/types"
+	"sort"
+	"strings"
+
+	"golang.org/x/tools/internal/pkgbits"
+)
+
+// A pkgReader holds the shared state for reading a unified IR package
+// description.
+type pkgReader struct {
+	pkgbits.PkgDecoder
+
+	fake fakeFileSet
+
+	ctxt    *types.Context
+	imports map[string]*types.Package // previously imported packages, indexed by path
+
+	// lazily initialized arrays corresponding to the unified IR
+	// PosBase, Pkg, and Type sections, respectively.
+	posBases []string // position bases (i.e., file names)
+	pkgs     []*types.Package
+	typs     []types.Type
+
+	// laterFns holds functions that need to be invoked at the end of
+	// import reading.
+	laterFns []func()
+	// laterFors is used in case of 'type A B' to ensure that B is processed before A.
+	laterFors map[types.Type]int
+
+	// ifaces holds a list of constructed Interfaces, which need to have
+	// Complete called after importing is done.
+	ifaces []*types.Interface
+}
+
+// later adds a function to be invoked at the end of import reading.
+func (pr *pkgReader) later(fn func()) {
+	pr.laterFns = append(pr.laterFns, fn)
+}
+
+// See cmd/compile/internal/noder.derivedInfo.
+type derivedInfo struct {
+	idx    pkgbits.Index
+	needed bool
+}
+
+// See cmd/compile/internal/noder.typeInfo.
+type typeInfo struct {
+	idx     pkgbits.Index
+	derived bool
+}
+
+func UImportData(fset *token.FileSet, imports map[string]*types.Package, data []byte, path string) (_ int, pkg *types.Package, err error) {
+	s := string(data)
+	s = s[:strings.LastIndex(s, "\n$$\n")]
+	input := pkgbits.NewPkgDecoder(path, s)
+	pkg = readUnifiedPackage(fset, nil, imports, input)
+	return
+}
+
+// laterFor adds a function to be invoked at the end of import reading, and records the type that function is finishing.
+func (pr *pkgReader) laterFor(t types.Type, fn func()) {
+	if pr.laterFors == nil {
+		pr.laterFors = make(map[types.Type]int)
+	}
+	pr.laterFors[t] = len(pr.laterFns)
+	pr.laterFns = append(pr.laterFns, fn)
+}
+
+// readUnifiedPackage reads a package description from the given
+// unified IR export data decoder.
+func readUnifiedPackage(fset *token.FileSet, ctxt *types.Context, imports map[string]*types.Package, input pkgbits.PkgDecoder) *types.Package {
+	pr := pkgReader{
+		PkgDecoder: input,
+
+		fake: fakeFileSet{
+			fset:  fset,
+			files: make(map[string]*fileInfo),
+		},
+
+		ctxt:    ctxt,
+		imports: imports,
+
+		posBases: make([]string, input.NumElems(pkgbits.RelocPosBase)),
+		pkgs:     make([]*types.Package, input.NumElems(pkgbits.RelocPkg)),
+		typs:     make([]types.Type, input.NumElems(pkgbits.RelocType)),
+	}
+	defer pr.fake.setLines()
+
+	r := pr.newReader(pkgbits.RelocMeta, pkgbits.PublicRootIdx, pkgbits.SyncPublic)
+	pkg := r.pkg()
+	r.Bool() // has init
+
+	for i, n := 0, r.Len(); i < n; i++ {
+		// As if r.obj(), but avoiding the Scope.Lookup call,
+		// to avoid eager loading of imports.
+		r.Sync(pkgbits.SyncObject)
+		assert(!r.Bool())
+		r.p.objIdx(r.Reloc(pkgbits.RelocObj))
+		assert(r.Len() == 0)
+	}
+
+	r.Sync(pkgbits.SyncEOF)
+
+	for _, fn := range pr.laterFns {
+		fn()
+	}
+
+	for _, iface := range pr.ifaces {
+		iface.Complete()
+	}
+
+	// Imports() of pkg are all of the transitive packages that were loaded.
+	var imps []*types.Package
+	for _, imp := range pr.pkgs {
+		if imp != nil && imp != pkg {
+			imps = append(imps, imp)
+		}
+	}
+	sort.Sort(byPath(imps))
+	pkg.SetImports(imps)
+
+	pkg.MarkComplete()
+	return pkg
+}
+
+// A reader holds the state for reading a single unified IR element
+// within a package.
+type reader struct {
+	pkgbits.Decoder
+
+	p *pkgReader
+
+	dict *readerDict
+}
+
+// A readerDict holds the state for type parameters that parameterize
+// the current unified IR element.
+type readerDict struct {
+	// bounds is a slice of typeInfos corresponding to the underlying
+	// bounds of the element's type parameters.
+	bounds []typeInfo
+
+	// tparams is a slice of the constructed TypeParams for the element.
+	tparams []*types.TypeParam
+
+	// devived is a slice of types derived from tparams, which may be
+	// instantiated while reading the current element.
+	derived      []derivedInfo
+	derivedTypes []types.Type // lazily instantiated from derived
+}
+
+func (pr *pkgReader) newReader(k pkgbits.RelocKind, idx pkgbits.Index, marker pkgbits.SyncMarker) *reader {
+	return &reader{
+		Decoder: pr.NewDecoder(k, idx, marker),
+		p:       pr,
+	}
+}
+
+func (pr *pkgReader) tempReader(k pkgbits.RelocKind, idx pkgbits.Index, marker pkgbits.SyncMarker) *reader {
+	return &reader{
+		Decoder: pr.TempDecoder(k, idx, marker),
+		p:       pr,
+	}
+}
+
+func (pr *pkgReader) retireReader(r *reader) {
+	pr.RetireDecoder(&r.Decoder)
+}
+
+// @@@ Positions
+
+func (r *reader) pos() token.Pos {
+	r.Sync(pkgbits.SyncPos)
+	if !r.Bool() {
+		return token.NoPos
+	}
+
+	// TODO(mdempsky): Delta encoding.
+	posBase := r.posBase()
+	line := r.Uint()
+	col := r.Uint()
+	return r.p.fake.pos(posBase, int(line), int(col))
+}
+
+func (r *reader) posBase() string {
+	return r.p.posBaseIdx(r.Reloc(pkgbits.RelocPosBase))
+}
+
+func (pr *pkgReader) posBaseIdx(idx pkgbits.Index) string {
+	if b := pr.posBases[idx]; b != "" {
+		return b
+	}
+
+	var filename string
+	{
+		r := pr.tempReader(pkgbits.RelocPosBase, idx, pkgbits.SyncPosBase)
+
+		// Within types2, position bases have a lot more details (e.g.,
+		// keeping track of where //line directives appeared exactly).
+		//
+		// For go/types, we just track the file name.
+
+		filename = r.String()
+
+		if r.Bool() { // file base
+			// Was: "b = token.NewTrimmedFileBase(filename, true)"
+		} else { // line base
+			pos := r.pos()
+			line := r.Uint()
+			col := r.Uint()
+
+			// Was: "b = token.NewLineBase(pos, filename, true, line, col)"
+			_, _, _ = pos, line, col
+		}
+		pr.retireReader(r)
+	}
+	b := filename
+	pr.posBases[idx] = b
+	return b
+}
+
+// @@@ Packages
+
+func (r *reader) pkg() *types.Package {
+	r.Sync(pkgbits.SyncPkg)
+	return r.p.pkgIdx(r.Reloc(pkgbits.RelocPkg))
+}
+
+func (pr *pkgReader) pkgIdx(idx pkgbits.Index) *types.Package {
+	// TODO(mdempsky): Consider using some non-nil pointer to indicate
+	// the universe scope, so we don't need to keep re-reading it.
+	if pkg := pr.pkgs[idx]; pkg != nil {
+		return pkg
+	}
+
+	pkg := pr.newReader(pkgbits.RelocPkg, idx, pkgbits.SyncPkgDef).doPkg()
+	pr.pkgs[idx] = pkg
+	return pkg
+}
+
+func (r *reader) doPkg() *types.Package {
+	path := r.String()
+	switch path {
+	case "":
+		path = r.p.PkgPath()
+	case "builtin":
+		return nil // universe
+	case "unsafe":
+		return types.Unsafe
+	}
+
+	if pkg := r.p.imports[path]; pkg != nil {
+		return pkg
+	}
+
+	name := r.String()
+
+	pkg := types.NewPackage(path, name)
+	r.p.imports[path] = pkg
+
+	return pkg
+}
+
+// @@@ Types
+
+func (r *reader) typ() types.Type {
+	return r.p.typIdx(r.typInfo(), r.dict)
+}
+
+func (r *reader) typInfo() typeInfo {
+	r.Sync(pkgbits.SyncType)
+	if r.Bool() {
+		return typeInfo{idx: pkgbits.Index(r.Len()), derived: true}
+	}
+	return typeInfo{idx: r.Reloc(pkgbits.RelocType), derived: false}
+}
+
+func (pr *pkgReader) typIdx(info typeInfo, dict *readerDict) types.Type {
+	idx := info.idx
+	var where *types.Type
+	if info.derived {
+		where = &dict.derivedTypes[idx]
+		idx = dict.derived[idx].idx
+	} else {
+		where = &pr.typs[idx]
+	}
+
+	if typ := *where; typ != nil {
+		return typ
+	}
+
+	var typ types.Type
+	{
+		r := pr.tempReader(pkgbits.RelocType, idx, pkgbits.SyncTypeIdx)
+		r.dict = dict
+
+		typ = r.doTyp()
+		assert(typ != nil)
+		pr.retireReader(r)
+	}
+	// See comment in pkgReader.typIdx explaining how this happens.
+	if prev := *where; prev != nil {
+		return prev
+	}
+
+	*where = typ
+	return typ
+}
+
+func (r *reader) doTyp() (res types.Type) {
+	switch tag := pkgbits.CodeType(r.Code(pkgbits.SyncType)); tag {
+	default:
+		errorf("unhandled type tag: %v", tag)
+		panic("unreachable")
+
+	case pkgbits.TypeBasic:
+		return types.Typ[r.Len()]
+
+	case pkgbits.TypeNamed:
+		obj, targs := r.obj()
+		name := obj.(*types.TypeName)
+		if len(targs) != 0 {
+			t, _ := types.Instantiate(r.p.ctxt, name.Type(), targs, false)
+			return t
+		}
+		return name.Type()
+
+	case pkgbits.TypeTypeParam:
+		return r.dict.tparams[r.Len()]
+
+	case pkgbits.TypeArray:
+		len := int64(r.Uint64())
+		return types.NewArray(r.typ(), len)
+	case pkgbits.TypeChan:
+		dir := types.ChanDir(r.Len())
+		return types.NewChan(dir, r.typ())
+	case pkgbits.TypeMap:
+		return types.NewMap(r.typ(), r.typ())
+	case pkgbits.TypePointer:
+		return types.NewPointer(r.typ())
+	case pkgbits.TypeSignature:
+		return r.signature(nil, nil, nil)
+	case pkgbits.TypeSlice:
+		return types.NewSlice(r.typ())
+	case pkgbits.TypeStruct:
+		return r.structType()
+	case pkgbits.TypeInterface:
+		return r.interfaceType()
+	case pkgbits.TypeUnion:
+		return r.unionType()
+	}
+}
+
+func (r *reader) structType() *types.Struct {
+	fields := make([]*types.Var, r.Len())
+	var tags []string
+	for i := range fields {
+		pos := r.pos()
+		pkg, name := r.selector()
+		ftyp := r.typ()
+		tag := r.String()
+		embedded := r.Bool()
+
+		fields[i] = types.NewField(pos, pkg, name, ftyp, embedded)
+		if tag != "" {
+			for len(tags) < i {
+				tags = append(tags, "")
+			}
+			tags = append(tags, tag)
+		}
+	}
+	return types.NewStruct(fields, tags)
+}
+
+func (r *reader) unionType() *types.Union {
+	terms := make([]*types.Term, r.Len())
+	for i := range terms {
+		terms[i] = types.NewTerm(r.Bool(), r.typ())
+	}
+	return types.NewUnion(terms)
+}
+
+func (r *reader) interfaceType() *types.Interface {
+	methods := make([]*types.Func, r.Len())
+	embeddeds := make([]types.Type, r.Len())
+	implicit := len(methods) == 0 && len(embeddeds) == 1 && r.Bool()
+
+	for i := range methods {
+		pos := r.pos()
+		pkg, name := r.selector()
+		mtyp := r.signature(nil, nil, nil)
+		methods[i] = types.NewFunc(pos, pkg, name, mtyp)
+	}
+
+	for i := range embeddeds {
+		embeddeds[i] = r.typ()
+	}
+
+	iface := types.NewInterfaceType(methods, embeddeds)
+	if implicit {
+		iface.MarkImplicit()
+	}
+
+	// We need to call iface.Complete(), but if there are any embedded
+	// defined types, then we may not have set their underlying
+	// interface type yet. So we need to defer calling Complete until
+	// after we've called SetUnderlying everywhere.
+	//
+	// TODO(mdempsky): After CL 424876 lands, it should be safe to call
+	// iface.Complete() immediately.
+	r.p.ifaces = append(r.p.ifaces, iface)
+
+	return iface
+}
+
+func (r *reader) signature(recv *types.Var, rtparams, tparams []*types.TypeParam) *types.Signature {
+	r.Sync(pkgbits.SyncSignature)
+
+	params := r.params()
+	results := r.params()
+	variadic := r.Bool()
+
+	return types.NewSignatureType(recv, rtparams, tparams, params, results, variadic)
+}
+
+func (r *reader) params() *types.Tuple {
+	r.Sync(pkgbits.SyncParams)
+
+	params := make([]*types.Var, r.Len())
+	for i := range params {
+		params[i] = r.param()
+	}
+
+	return types.NewTuple(params...)
+}
+
+func (r *reader) param() *types.Var {
+	r.Sync(pkgbits.SyncParam)
+
+	pos := r.pos()
+	pkg, name := r.localIdent()
+	typ := r.typ()
+
+	return types.NewParam(pos, pkg, name, typ)
+}
+
+// @@@ Objects
+
+func (r *reader) obj() (types.Object, []types.Type) {
+	r.Sync(pkgbits.SyncObject)
+
+	assert(!r.Bool())
+
+	pkg, name := r.p.objIdx(r.Reloc(pkgbits.RelocObj))
+	obj := pkgScope(pkg).Lookup(name)
+
+	targs := make([]types.Type, r.Len())
+	for i := range targs {
+		targs[i] = r.typ()
+	}
+
+	return obj, targs
+}
+
+func (pr *pkgReader) objIdx(idx pkgbits.Index) (*types.Package, string) {
+
+	var objPkg *types.Package
+	var objName string
+	var tag pkgbits.CodeObj
+	{
+		rname := pr.tempReader(pkgbits.RelocName, idx, pkgbits.SyncObject1)
+
+		objPkg, objName = rname.qualifiedIdent()
+		assert(objName != "")
+
+		tag = pkgbits.CodeObj(rname.Code(pkgbits.SyncCodeObj))
+		pr.retireReader(rname)
+	}
+
+	if tag == pkgbits.ObjStub {
+		assert(objPkg == nil || objPkg == types.Unsafe)
+		return objPkg, objName
+	}
+
+	// Ignore local types promoted to global scope (#55110).
+	if _, suffix := splitVargenSuffix(objName); suffix != "" {
+		return objPkg, objName
+	}
+
+	if objPkg.Scope().Lookup(objName) == nil {
+		dict := pr.objDictIdx(idx)
+
+		r := pr.newReader(pkgbits.RelocObj, idx, pkgbits.SyncObject1)
+		r.dict = dict
+
+		declare := func(obj types.Object) {
+			objPkg.Scope().Insert(obj)
+		}
+
+		switch tag {
+		default:
+			panic("weird")
+
+		case pkgbits.ObjAlias:
+			pos := r.pos()
+			typ := r.typ()
+			declare(types.NewTypeName(pos, objPkg, objName, typ))
+
+		case pkgbits.ObjConst:
+			pos := r.pos()
+			typ := r.typ()
+			val := r.Value()
+			declare(types.NewConst(pos, objPkg, objName, typ, val))
+
+		case pkgbits.ObjFunc:
+			pos := r.pos()
+			tparams := r.typeParamNames()
+			sig := r.signature(nil, nil, tparams)
+			declare(types.NewFunc(pos, objPkg, objName, sig))
+
+		case pkgbits.ObjType:
+			pos := r.pos()
+
+			obj := types.NewTypeName(pos, objPkg, objName, nil)
+			named := types.NewNamed(obj, nil, nil)
+			declare(obj)
+
+			named.SetTypeParams(r.typeParamNames())
+
+			setUnderlying := func(underlying types.Type) {
+				// If the underlying type is an interface, we need to
+				// duplicate its methods so we can replace the receiver
+				// parameter's type (#49906).
+				if iface, ok := underlying.(*types.Interface); ok && iface.NumExplicitMethods() != 0 {
+					methods := make([]*types.Func, iface.NumExplicitMethods())
+					for i := range methods {
+						fn := iface.ExplicitMethod(i)
+						sig := fn.Type().(*types.Signature)
+
+						recv := types.NewVar(fn.Pos(), fn.Pkg(), "", named)
+						methods[i] = types.NewFunc(fn.Pos(), fn.Pkg(), fn.Name(), types.NewSignature(recv, sig.Params(), sig.Results(), sig.Variadic()))
+					}
+
+					embeds := make([]types.Type, iface.NumEmbeddeds())
+					for i := range embeds {
+						embeds[i] = iface.EmbeddedType(i)
+					}
+
+					newIface := types.NewInterfaceType(methods, embeds)
+					r.p.ifaces = append(r.p.ifaces, newIface)
+					underlying = newIface
+				}
+
+				named.SetUnderlying(underlying)
+			}
+
+			// Since go.dev/cl/455279, we can assume rhs.Underlying() will
+			// always be non-nil. However, to temporarily support users of
+			// older snapshot releases, we continue to fallback to the old
+			// behavior for now.
+			//
+			// TODO(mdempsky): Remove fallback code and simplify after
+			// allowing time for snapshot users to upgrade.
+			rhs := r.typ()
+			if underlying := rhs.Underlying(); underlying != nil {
+				setUnderlying(underlying)
+			} else {
+				pk := r.p
+				pk.laterFor(named, func() {
+					// First be sure that the rhs is initialized, if it needs to be initialized.
+					delete(pk.laterFors, named) // prevent cycles
+					if i, ok := pk.laterFors[rhs]; ok {
+						f := pk.laterFns[i]
+						pk.laterFns[i] = func() {} // function is running now, so replace it with a no-op
+						f()                        // initialize RHS
+					}
+					setUnderlying(rhs.Underlying())
+				})
+			}
+
+			for i, n := 0, r.Len(); i < n; i++ {
+				named.AddMethod(r.method())
+			}
+
+		case pkgbits.ObjVar:
+			pos := r.pos()
+			typ := r.typ()
+			declare(types.NewVar(pos, objPkg, objName, typ))
+		}
+	}
+
+	return objPkg, objName
+}
+
+func (pr *pkgReader) objDictIdx(idx pkgbits.Index) *readerDict {
+
+	var dict readerDict
+
+	{
+		r := pr.tempReader(pkgbits.RelocObjDict, idx, pkgbits.SyncObject1)
+		if implicits := r.Len(); implicits != 0 {
+			errorf("unexpected object with %v implicit type parameter(s)", implicits)
+		}
+
+		dict.bounds = make([]typeInfo, r.Len())
+		for i := range dict.bounds {
+			dict.bounds[i] = r.typInfo()
+		}
+
+		dict.derived = make([]derivedInfo, r.Len())
+		dict.derivedTypes = make([]types.Type, len(dict.derived))
+		for i := range dict.derived {
+			dict.derived[i] = derivedInfo{r.Reloc(pkgbits.RelocType), r.Bool()}
+		}
+
+		pr.retireReader(r)
+	}
+	// function references follow, but reader doesn't need those
+
+	return &dict
+}
+
+func (r *reader) typeParamNames() []*types.TypeParam {
+	r.Sync(pkgbits.SyncTypeParamNames)
+
+	// Note: This code assumes it only processes objects without
+	// implement type parameters. This is currently fine, because
+	// reader is only used to read in exported declarations, which are
+	// always package scoped.
+
+	if len(r.dict.bounds) == 0 {
+		return nil
+	}
+
+	// Careful: Type parameter lists may have cycles. To allow for this,
+	// we construct the type parameter list in two passes: first we
+	// create all the TypeNames and TypeParams, then we construct and
+	// set the bound type.
+
+	r.dict.tparams = make([]*types.TypeParam, len(r.dict.bounds))
+	for i := range r.dict.bounds {
+		pos := r.pos()
+		pkg, name := r.localIdent()
+
+		tname := types.NewTypeName(pos, pkg, name, nil)
+		r.dict.tparams[i] = types.NewTypeParam(tname, nil)
+	}
+
+	typs := make([]types.Type, len(r.dict.bounds))
+	for i, bound := range r.dict.bounds {
+		typs[i] = r.p.typIdx(bound, r.dict)
+	}
+
+	// TODO(mdempsky): This is subtle, elaborate further.
+	//
+	// We have to save tparams outside of the closure, because
+	// typeParamNames() can be called multiple times with the same
+	// dictionary instance.
+	//
+	// Also, this needs to happen later to make sure SetUnderlying has
+	// been called.
+	//
+	// TODO(mdempsky): Is it safe to have a single "later" slice or do
+	// we need to have multiple passes? See comments on CL 386002 and
+	// go.dev/issue/52104.
+	tparams := r.dict.tparams
+	r.p.later(func() {
+		for i, typ := range typs {
+			tparams[i].SetConstraint(typ)
+		}
+	})
+
+	return r.dict.tparams
+}
+
+func (r *reader) method() *types.Func {
+	r.Sync(pkgbits.SyncMethod)
+	pos := r.pos()
+	pkg, name := r.selector()
+
+	rparams := r.typeParamNames()
+	sig := r.signature(r.param(), rparams, nil)
+
+	_ = r.pos() // TODO(mdempsky): Remove; this is a hacker for linker.go.
+	return types.NewFunc(pos, pkg, name, sig)
+}
+
+func (r *reader) qualifiedIdent() (*types.Package, string) { return r.ident(pkgbits.SyncSym) }
+func (r *reader) localIdent() (*types.Package, string)     { return r.ident(pkgbits.SyncLocalIdent) }
+func (r *reader) selector() (*types.Package, string)       { return r.ident(pkgbits.SyncSelector) }
+
+func (r *reader) ident(marker pkgbits.SyncMarker) (*types.Package, string) {
+	r.Sync(marker)
+	return r.pkg(), r.String()
+}
+
+// pkgScope returns pkg.Scope().
+// If pkg is nil, it returns types.Universe instead.
+//
+// TODO(mdempsky): Remove after x/tools can depend on Go 1.19.
+func pkgScope(pkg *types.Package) *types.Scope {
+	if pkg != nil {
+		return pkg.Scope()
+	}
+	return types.Universe
+}
diff --git a/vendor/golang.org/x/tools/internal/gocommand/invoke.go b/vendor/golang.org/x/tools/internal/gocommand/invoke.go
new file mode 100644
index 0000000..d505516
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/gocommand/invoke.go
@@ -0,0 +1,356 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package gocommand is a helper for calling the go command.
+package gocommand
+
+import (
+	"bytes"
+	"context"
+	"fmt"
+	"io"
+	"log"
+	"os"
+	"regexp"
+	"runtime"
+	"strconv"
+	"strings"
+	"sync"
+	"time"
+
+	exec "golang.org/x/sys/execabs"
+
+	"golang.org/x/tools/internal/event"
+)
+
+// An Runner will run go command invocations and serialize
+// them if it sees a concurrency error.
+type Runner struct {
+	// once guards the runner initialization.
+	once sync.Once
+
+	// inFlight tracks available workers.
+	inFlight chan struct{}
+
+	// serialized guards the ability to run a go command serially,
+	// to avoid deadlocks when claiming workers.
+	serialized chan struct{}
+}
+
+const maxInFlight = 10
+
+func (runner *Runner) initialize() {
+	runner.once.Do(func() {
+		runner.inFlight = make(chan struct{}, maxInFlight)
+		runner.serialized = make(chan struct{}, 1)
+	})
+}
+
+// 1.13: go: updates to go.mod needed, but contents have changed
+// 1.14: go: updating go.mod: existing contents have changed since last read
+var modConcurrencyError = regexp.MustCompile(`go:.*go.mod.*contents have changed`)
+
+// Run is a convenience wrapper around RunRaw.
+// It returns only stdout and a "friendly" error.
+func (runner *Runner) Run(ctx context.Context, inv Invocation) (*bytes.Buffer, error) {
+	stdout, _, friendly, _ := runner.RunRaw(ctx, inv)
+	return stdout, friendly
+}
+
+// RunPiped runs the invocation serially, always waiting for any concurrent
+// invocations to complete first.
+func (runner *Runner) RunPiped(ctx context.Context, inv Invocation, stdout, stderr io.Writer) error {
+	_, err := runner.runPiped(ctx, inv, stdout, stderr)
+	return err
+}
+
+// RunRaw runs the invocation, serializing requests only if they fight over
+// go.mod changes.
+func (runner *Runner) RunRaw(ctx context.Context, inv Invocation) (*bytes.Buffer, *bytes.Buffer, error, error) {
+	// Make sure the runner is always initialized.
+	runner.initialize()
+
+	// First, try to run the go command concurrently.
+	stdout, stderr, friendlyErr, err := runner.runConcurrent(ctx, inv)
+
+	// If we encounter a load concurrency error, we need to retry serially.
+	if friendlyErr == nil || !modConcurrencyError.MatchString(friendlyErr.Error()) {
+		return stdout, stderr, friendlyErr, err
+	}
+	event.Error(ctx, "Load concurrency error, will retry serially", err)
+
+	// Run serially by calling runPiped.
+	stdout.Reset()
+	stderr.Reset()
+	friendlyErr, err = runner.runPiped(ctx, inv, stdout, stderr)
+	return stdout, stderr, friendlyErr, err
+}
+
+func (runner *Runner) runConcurrent(ctx context.Context, inv Invocation) (*bytes.Buffer, *bytes.Buffer, error, error) {
+	// Wait for 1 worker to become available.
+	select {
+	case <-ctx.Done():
+		return nil, nil, nil, ctx.Err()
+	case runner.inFlight <- struct{}{}:
+		defer func() { <-runner.inFlight }()
+	}
+
+	stdout, stderr := &bytes.Buffer{}, &bytes.Buffer{}
+	friendlyErr, err := inv.runWithFriendlyError(ctx, stdout, stderr)
+	return stdout, stderr, friendlyErr, err
+}
+
+func (runner *Runner) runPiped(ctx context.Context, inv Invocation, stdout, stderr io.Writer) (error, error) {
+	// Make sure the runner is always initialized.
+	runner.initialize()
+
+	// Acquire the serialization lock. This avoids deadlocks between two
+	// runPiped commands.
+	select {
+	case <-ctx.Done():
+		return nil, ctx.Err()
+	case runner.serialized <- struct{}{}:
+		defer func() { <-runner.serialized }()
+	}
+
+	// Wait for all in-progress go commands to return before proceeding,
+	// to avoid load concurrency errors.
+	for i := 0; i < maxInFlight; i++ {
+		select {
+		case <-ctx.Done():
+			return nil, ctx.Err()
+		case runner.inFlight <- struct{}{}:
+			// Make sure we always "return" any workers we took.
+			defer func() { <-runner.inFlight }()
+		}
+	}
+
+	return inv.runWithFriendlyError(ctx, stdout, stderr)
+}
+
+// An Invocation represents a call to the go command.
+type Invocation struct {
+	Verb       string
+	Args       []string
+	BuildFlags []string
+
+	// If ModFlag is set, the go command is invoked with -mod=ModFlag.
+	ModFlag string
+
+	// If ModFile is set, the go command is invoked with -modfile=ModFile.
+	ModFile string
+
+	// If Overlay is set, the go command is invoked with -overlay=Overlay.
+	Overlay string
+
+	// If CleanEnv is set, the invocation will run only with the environment
+	// in Env, not starting with os.Environ.
+	CleanEnv   bool
+	Env        []string
+	WorkingDir string
+	Logf       func(format string, args ...interface{})
+}
+
+func (i *Invocation) runWithFriendlyError(ctx context.Context, stdout, stderr io.Writer) (friendlyError error, rawError error) {
+	rawError = i.run(ctx, stdout, stderr)
+	if rawError != nil {
+		friendlyError = rawError
+		// Check for 'go' executable not being found.
+		if ee, ok := rawError.(*exec.Error); ok && ee.Err == exec.ErrNotFound {
+			friendlyError = fmt.Errorf("go command required, not found: %v", ee)
+		}
+		if ctx.Err() != nil {
+			friendlyError = ctx.Err()
+		}
+		friendlyError = fmt.Errorf("err: %v: stderr: %s", friendlyError, stderr)
+	}
+	return
+}
+
+func (i *Invocation) run(ctx context.Context, stdout, stderr io.Writer) error {
+	log := i.Logf
+	if log == nil {
+		log = func(string, ...interface{}) {}
+	}
+
+	goArgs := []string{i.Verb}
+
+	appendModFile := func() {
+		if i.ModFile != "" {
+			goArgs = append(goArgs, "-modfile="+i.ModFile)
+		}
+	}
+	appendModFlag := func() {
+		if i.ModFlag != "" {
+			goArgs = append(goArgs, "-mod="+i.ModFlag)
+		}
+	}
+	appendOverlayFlag := func() {
+		if i.Overlay != "" {
+			goArgs = append(goArgs, "-overlay="+i.Overlay)
+		}
+	}
+
+	switch i.Verb {
+	case "env", "version":
+		goArgs = append(goArgs, i.Args...)
+	case "mod":
+		// mod needs the sub-verb before flags.
+		goArgs = append(goArgs, i.Args[0])
+		appendModFile()
+		goArgs = append(goArgs, i.Args[1:]...)
+	case "get":
+		goArgs = append(goArgs, i.BuildFlags...)
+		appendModFile()
+		goArgs = append(goArgs, i.Args...)
+
+	default: // notably list and build.
+		goArgs = append(goArgs, i.BuildFlags...)
+		appendModFile()
+		appendModFlag()
+		appendOverlayFlag()
+		goArgs = append(goArgs, i.Args...)
+	}
+	cmd := exec.Command("go", goArgs...)
+	cmd.Stdout = stdout
+	cmd.Stderr = stderr
+	// On darwin the cwd gets resolved to the real path, which breaks anything that
+	// expects the working directory to keep the original path, including the
+	// go command when dealing with modules.
+	// The Go stdlib has a special feature where if the cwd and the PWD are the
+	// same node then it trusts the PWD, so by setting it in the env for the child
+	// process we fix up all the paths returned by the go command.
+	if !i.CleanEnv {
+		cmd.Env = os.Environ()
+	}
+	cmd.Env = append(cmd.Env, i.Env...)
+	if i.WorkingDir != "" {
+		cmd.Env = append(cmd.Env, "PWD="+i.WorkingDir)
+		cmd.Dir = i.WorkingDir
+	}
+	defer func(start time.Time) { log("%s for %v", time.Since(start), cmdDebugStr(cmd)) }(time.Now())
+
+	return runCmdContext(ctx, cmd)
+}
+
+// DebugHangingGoCommands may be set by tests to enable additional
+// instrumentation (including panics) for debugging hanging Go commands.
+//
+// See golang/go#54461 for details.
+var DebugHangingGoCommands = false
+
+// runCmdContext is like exec.CommandContext except it sends os.Interrupt
+// before os.Kill.
+func runCmdContext(ctx context.Context, cmd *exec.Cmd) error {
+	if err := cmd.Start(); err != nil {
+		return err
+	}
+	resChan := make(chan error, 1)
+	go func() {
+		resChan <- cmd.Wait()
+	}()
+
+	// If we're interested in debugging hanging Go commands, stop waiting after a
+	// minute and panic with interesting information.
+	if DebugHangingGoCommands {
+		select {
+		case err := <-resChan:
+			return err
+		case <-time.After(1 * time.Minute):
+			HandleHangingGoCommand(cmd.Process)
+		case <-ctx.Done():
+		}
+	} else {
+		select {
+		case err := <-resChan:
+			return err
+		case <-ctx.Done():
+		}
+	}
+
+	// Cancelled. Interrupt and see if it ends voluntarily.
+	cmd.Process.Signal(os.Interrupt)
+	select {
+	case err := <-resChan:
+		return err
+	case <-time.After(time.Second):
+	}
+
+	// Didn't shut down in response to interrupt. Kill it hard.
+	// TODO(rfindley): per advice from bcmills@, it may be better to send SIGQUIT
+	// on certain platforms, such as unix.
+	if err := cmd.Process.Kill(); err != nil && DebugHangingGoCommands {
+		// Don't panic here as this reliably fails on windows with EINVAL.
+		log.Printf("error killing the Go command: %v", err)
+	}
+
+	// See above: don't wait indefinitely if we're debugging hanging Go commands.
+	if DebugHangingGoCommands {
+		select {
+		case err := <-resChan:
+			return err
+		case <-time.After(10 * time.Second): // a shorter wait as resChan should return quickly following Kill
+			HandleHangingGoCommand(cmd.Process)
+		}
+	}
+	return <-resChan
+}
+
+func HandleHangingGoCommand(proc *os.Process) {
+	switch runtime.GOOS {
+	case "linux", "darwin", "freebsd", "netbsd":
+		fmt.Fprintln(os.Stderr, `DETECTED A HANGING GO COMMAND
+
+The gopls test runner has detected a hanging go command. In order to debug
+this, the output of ps and lsof/fstat is printed below.
+
+See golang/go#54461 for more details.`)
+
+		fmt.Fprintln(os.Stderr, "\nps axo ppid,pid,command:")
+		fmt.Fprintln(os.Stderr, "-------------------------")
+		psCmd := exec.Command("ps", "axo", "ppid,pid,command")
+		psCmd.Stdout = os.Stderr
+		psCmd.Stderr = os.Stderr
+		if err := psCmd.Run(); err != nil {
+			panic(fmt.Sprintf("running ps: %v", err))
+		}
+
+		listFiles := "lsof"
+		if runtime.GOOS == "freebsd" || runtime.GOOS == "netbsd" {
+			listFiles = "fstat"
+		}
+
+		fmt.Fprintln(os.Stderr, "\n"+listFiles+":")
+		fmt.Fprintln(os.Stderr, "-----")
+		listFilesCmd := exec.Command(listFiles)
+		listFilesCmd.Stdout = os.Stderr
+		listFilesCmd.Stderr = os.Stderr
+		if err := listFilesCmd.Run(); err != nil {
+			panic(fmt.Sprintf("running %s: %v", listFiles, err))
+		}
+	}
+	panic(fmt.Sprintf("detected hanging go command (pid %d): see golang/go#54461 for more details", proc.Pid))
+}
+
+func cmdDebugStr(cmd *exec.Cmd) string {
+	env := make(map[string]string)
+	for _, kv := range cmd.Env {
+		split := strings.SplitN(kv, "=", 2)
+		if len(split) == 2 {
+			k, v := split[0], split[1]
+			env[k] = v
+		}
+	}
+
+	var args []string
+	for _, arg := range cmd.Args {
+		quoted := strconv.Quote(arg)
+		if quoted[1:len(quoted)-1] != arg || strings.Contains(arg, " ") {
+			args = append(args, quoted)
+		} else {
+			args = append(args, arg)
+		}
+	}
+	return fmt.Sprintf("GOROOT=%v GOPATH=%v GO111MODULE=%v GOPROXY=%v PWD=%v %v", env["GOROOT"], env["GOPATH"], env["GO111MODULE"], env["GOPROXY"], env["PWD"], strings.Join(args, " "))
+}
diff --git a/vendor/golang.org/x/tools/internal/gocommand/vendor.go b/vendor/golang.org/x/tools/internal/gocommand/vendor.go
new file mode 100644
index 0000000..2d3d408
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/gocommand/vendor.go
@@ -0,0 +1,109 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package gocommand
+
+import (
+	"bytes"
+	"context"
+	"fmt"
+	"os"
+	"path/filepath"
+	"regexp"
+	"strings"
+	"time"
+
+	"golang.org/x/mod/semver"
+)
+
+// ModuleJSON holds information about a module.
+type ModuleJSON struct {
+	Path      string      // module path
+	Version   string      // module version
+	Versions  []string    // available module versions (with -versions)
+	Replace   *ModuleJSON // replaced by this module
+	Time      *time.Time  // time version was created
+	Update    *ModuleJSON // available update, if any (with -u)
+	Main      bool        // is this the main module?
+	Indirect  bool        // is this module only an indirect dependency of main module?
+	Dir       string      // directory holding files for this module, if any
+	GoMod     string      // path to go.mod file used when loading this module, if any
+	GoVersion string      // go version used in module
+}
+
+var modFlagRegexp = regexp.MustCompile(`-mod[ =](\w+)`)
+
+// VendorEnabled reports whether vendoring is enabled. It takes a *Runner to execute Go commands
+// with the supplied context.Context and Invocation. The Invocation can contain pre-defined fields,
+// of which only Verb and Args are modified to run the appropriate Go command.
+// Inspired by setDefaultBuildMod in modload/init.go
+func VendorEnabled(ctx context.Context, inv Invocation, r *Runner) (bool, *ModuleJSON, error) {
+	mainMod, go114, err := getMainModuleAnd114(ctx, inv, r)
+	if err != nil {
+		return false, nil, err
+	}
+
+	// We check the GOFLAGS to see if there is anything overridden or not.
+	inv.Verb = "env"
+	inv.Args = []string{"GOFLAGS"}
+	stdout, err := r.Run(ctx, inv)
+	if err != nil {
+		return false, nil, err
+	}
+	goflags := string(bytes.TrimSpace(stdout.Bytes()))
+	matches := modFlagRegexp.FindStringSubmatch(goflags)
+	var modFlag string
+	if len(matches) != 0 {
+		modFlag = matches[1]
+	}
+	// Don't override an explicit '-mod=' argument.
+	if modFlag == "vendor" {
+		return true, mainMod, nil
+	} else if modFlag != "" {
+		return false, nil, nil
+	}
+	if mainMod == nil || !go114 {
+		return false, nil, nil
+	}
+	// Check 1.14's automatic vendor mode.
+	if fi, err := os.Stat(filepath.Join(mainMod.Dir, "vendor")); err == nil && fi.IsDir() {
+		if mainMod.GoVersion != "" && semver.Compare("v"+mainMod.GoVersion, "v1.14") >= 0 {
+			// The Go version is at least 1.14, and a vendor directory exists.
+			// Set -mod=vendor by default.
+			return true, mainMod, nil
+		}
+	}
+	return false, nil, nil
+}
+
+// getMainModuleAnd114 gets one of the main modules' information and whether the
+// go command in use is 1.14+. This is the information needed to figure out
+// if vendoring should be enabled.
+func getMainModuleAnd114(ctx context.Context, inv Invocation, r *Runner) (*ModuleJSON, bool, error) {
+	const format = `{{.Path}}
+{{.Dir}}
+{{.GoMod}}
+{{.GoVersion}}
+{{range context.ReleaseTags}}{{if eq . "go1.14"}}{{.}}{{end}}{{end}}
+`
+	inv.Verb = "list"
+	inv.Args = []string{"-m", "-f", format}
+	stdout, err := r.Run(ctx, inv)
+	if err != nil {
+		return nil, false, err
+	}
+
+	lines := strings.Split(stdout.String(), "\n")
+	if len(lines) < 5 {
+		return nil, false, fmt.Errorf("unexpected stdout: %q", stdout.String())
+	}
+	mod := &ModuleJSON{
+		Path:      lines[0],
+		Dir:       lines[1],
+		GoMod:     lines[2],
+		GoVersion: lines[3],
+		Main:      true,
+	}
+	return mod, lines[4] == "go1.14", nil
+}
diff --git a/vendor/golang.org/x/tools/internal/gocommand/version.go b/vendor/golang.org/x/tools/internal/gocommand/version.go
new file mode 100644
index 0000000..307a76d
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/gocommand/version.go
@@ -0,0 +1,81 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package gocommand
+
+import (
+	"context"
+	"fmt"
+	"regexp"
+	"strings"
+)
+
+// GoVersion reports the minor version number of the highest release
+// tag built into the go command on the PATH.
+//
+// Note that this may be higher than the version of the go tool used
+// to build this application, and thus the versions of the standard
+// go/{scanner,parser,ast,types} packages that are linked into it.
+// In that case, callers should either downgrade to the version of
+// go used to build the application, or report an error that the
+// application is too old to use the go command on the PATH.
+func GoVersion(ctx context.Context, inv Invocation, r *Runner) (int, error) {
+	inv.Verb = "list"
+	inv.Args = []string{"-e", "-f", `{{context.ReleaseTags}}`, `--`, `unsafe`}
+	inv.Env = append(append([]string{}, inv.Env...), "GO111MODULE=off")
+	// Unset any unneeded flags, and remove them from BuildFlags, if they're
+	// present.
+	inv.ModFile = ""
+	inv.ModFlag = ""
+	var buildFlags []string
+	for _, flag := range inv.BuildFlags {
+		// Flags can be prefixed by one or two dashes.
+		f := strings.TrimPrefix(strings.TrimPrefix(flag, "-"), "-")
+		if strings.HasPrefix(f, "mod=") || strings.HasPrefix(f, "modfile=") {
+			continue
+		}
+		buildFlags = append(buildFlags, flag)
+	}
+	inv.BuildFlags = buildFlags
+	stdoutBytes, err := r.Run(ctx, inv)
+	if err != nil {
+		return 0, err
+	}
+	stdout := stdoutBytes.String()
+	if len(stdout) < 3 {
+		return 0, fmt.Errorf("bad ReleaseTags output: %q", stdout)
+	}
+	// Split up "[go1.1 go1.15]" and return highest go1.X value.
+	tags := strings.Fields(stdout[1 : len(stdout)-2])
+	for i := len(tags) - 1; i >= 0; i-- {
+		var version int
+		if _, err := fmt.Sscanf(tags[i], "go1.%d", &version); err != nil {
+			continue
+		}
+		return version, nil
+	}
+	return 0, fmt.Errorf("no parseable ReleaseTags in %v", tags)
+}
+
+// GoVersionOutput returns the complete output of the go version command.
+func GoVersionOutput(ctx context.Context, inv Invocation, r *Runner) (string, error) {
+	inv.Verb = "version"
+	goVersion, err := r.Run(ctx, inv)
+	if err != nil {
+		return "", err
+	}
+	return goVersion.String(), nil
+}
+
+// ParseGoVersionOutput extracts the Go version string
+// from the output of the "go version" command.
+// Given an unrecognized form, it returns an empty string.
+func ParseGoVersionOutput(data string) string {
+	re := regexp.MustCompile(`^go version (go\S+|devel \S+)`)
+	m := re.FindStringSubmatch(data)
+	if len(m) != 2 {
+		return "" // unrecognized version
+	}
+	return m[1]
+}
diff --git a/vendor/golang.org/x/tools/internal/packagesinternal/packages.go b/vendor/golang.org/x/tools/internal/packagesinternal/packages.go
new file mode 100644
index 0000000..d9950b1
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/packagesinternal/packages.go
@@ -0,0 +1,30 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package packagesinternal exposes internal-only fields from go/packages.
+package packagesinternal
+
+import (
+	"golang.org/x/tools/internal/gocommand"
+)
+
+var GetForTest = func(p interface{}) string { return "" }
+var GetDepsErrors = func(p interface{}) []*PackageError { return nil }
+
+type PackageError struct {
+	ImportStack []string // shortest path from package named on command line to this one
+	Pos         string   // position of error (if present, file:line:col)
+	Err         string   // the error itself
+}
+
+var GetGoCmdRunner = func(config interface{}) *gocommand.Runner { return nil }
+
+var SetGoCmdRunner = func(config interface{}, runner *gocommand.Runner) {}
+
+var TypecheckCgo int
+var DepsErrors int // must be set as a LoadMode to call GetDepsErrors
+var ForTest int    // must be set as a LoadMode to call GetForTest
+
+var SetModFlag = func(config interface{}, value string) {}
+var SetModFile = func(config interface{}, value string) {}
diff --git a/vendor/golang.org/x/tools/internal/pkgbits/codes.go b/vendor/golang.org/x/tools/internal/pkgbits/codes.go
new file mode 100644
index 0000000..f0cabde
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/pkgbits/codes.go
@@ -0,0 +1,77 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package pkgbits
+
+// A Code is an enum value that can be encoded into bitstreams.
+//
+// Code types are preferable for enum types, because they allow
+// Decoder to detect desyncs.
+type Code interface {
+	// Marker returns the SyncMarker for the Code's dynamic type.
+	Marker() SyncMarker
+
+	// Value returns the Code's ordinal value.
+	Value() int
+}
+
+// A CodeVal distinguishes among go/constant.Value encodings.
+type CodeVal int
+
+func (c CodeVal) Marker() SyncMarker { return SyncVal }
+func (c CodeVal) Value() int         { return int(c) }
+
+// Note: These values are public and cannot be changed without
+// updating the go/types importers.
+
+const (
+	ValBool CodeVal = iota
+	ValString
+	ValInt64
+	ValBigInt
+	ValBigRat
+	ValBigFloat
+)
+
+// A CodeType distinguishes among go/types.Type encodings.
+type CodeType int
+
+func (c CodeType) Marker() SyncMarker { return SyncType }
+func (c CodeType) Value() int         { return int(c) }
+
+// Note: These values are public and cannot be changed without
+// updating the go/types importers.
+
+const (
+	TypeBasic CodeType = iota
+	TypeNamed
+	TypePointer
+	TypeSlice
+	TypeArray
+	TypeChan
+	TypeMap
+	TypeSignature
+	TypeStruct
+	TypeInterface
+	TypeUnion
+	TypeTypeParam
+)
+
+// A CodeObj distinguishes among go/types.Object encodings.
+type CodeObj int
+
+func (c CodeObj) Marker() SyncMarker { return SyncCodeObj }
+func (c CodeObj) Value() int         { return int(c) }
+
+// Note: These values are public and cannot be changed without
+// updating the go/types importers.
+
+const (
+	ObjAlias CodeObj = iota
+	ObjConst
+	ObjType
+	ObjFunc
+	ObjVar
+	ObjStub
+)
diff --git a/vendor/golang.org/x/tools/internal/pkgbits/decoder.go b/vendor/golang.org/x/tools/internal/pkgbits/decoder.go
new file mode 100644
index 0000000..b92e8e6
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/pkgbits/decoder.go
@@ -0,0 +1,517 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package pkgbits
+
+import (
+	"encoding/binary"
+	"errors"
+	"fmt"
+	"go/constant"
+	"go/token"
+	"io"
+	"math/big"
+	"os"
+	"runtime"
+	"strings"
+)
+
+// A PkgDecoder provides methods for decoding a package's Unified IR
+// export data.
+type PkgDecoder struct {
+	// version is the file format version.
+	version uint32
+
+	// sync indicates whether the file uses sync markers.
+	sync bool
+
+	// pkgPath is the package path for the package to be decoded.
+	//
+	// TODO(mdempsky): Remove; unneeded since CL 391014.
+	pkgPath string
+
+	// elemData is the full data payload of the encoded package.
+	// Elements are densely and contiguously packed together.
+	//
+	// The last 8 bytes of elemData are the package fingerprint.
+	elemData string
+
+	// elemEnds stores the byte-offset end positions of element
+	// bitstreams within elemData.
+	//
+	// For example, element I's bitstream data starts at elemEnds[I-1]
+	// (or 0, if I==0) and ends at elemEnds[I].
+	//
+	// Note: elemEnds is indexed by absolute indices, not
+	// section-relative indices.
+	elemEnds []uint32
+
+	// elemEndsEnds stores the index-offset end positions of relocation
+	// sections within elemEnds.
+	//
+	// For example, section K's end positions start at elemEndsEnds[K-1]
+	// (or 0, if K==0) and end at elemEndsEnds[K].
+	elemEndsEnds [numRelocs]uint32
+
+	scratchRelocEnt []RelocEnt
+}
+
+// PkgPath returns the package path for the package
+//
+// TODO(mdempsky): Remove; unneeded since CL 391014.
+func (pr *PkgDecoder) PkgPath() string { return pr.pkgPath }
+
+// SyncMarkers reports whether pr uses sync markers.
+func (pr *PkgDecoder) SyncMarkers() bool { return pr.sync }
+
+// NewPkgDecoder returns a PkgDecoder initialized to read the Unified
+// IR export data from input. pkgPath is the package path for the
+// compilation unit that produced the export data.
+//
+// TODO(mdempsky): Remove pkgPath parameter; unneeded since CL 391014.
+func NewPkgDecoder(pkgPath, input string) PkgDecoder {
+	pr := PkgDecoder{
+		pkgPath: pkgPath,
+	}
+
+	// TODO(mdempsky): Implement direct indexing of input string to
+	// avoid copying the position information.
+
+	r := strings.NewReader(input)
+
+	assert(binary.Read(r, binary.LittleEndian, &pr.version) == nil)
+
+	switch pr.version {
+	default:
+		panic(fmt.Errorf("unsupported version: %v", pr.version))
+	case 0:
+		// no flags
+	case 1:
+		var flags uint32
+		assert(binary.Read(r, binary.LittleEndian, &flags) == nil)
+		pr.sync = flags&flagSyncMarkers != 0
+	}
+
+	assert(binary.Read(r, binary.LittleEndian, pr.elemEndsEnds[:]) == nil)
+
+	pr.elemEnds = make([]uint32, pr.elemEndsEnds[len(pr.elemEndsEnds)-1])
+	assert(binary.Read(r, binary.LittleEndian, pr.elemEnds[:]) == nil)
+
+	pos, err := r.Seek(0, io.SeekCurrent)
+	assert(err == nil)
+
+	pr.elemData = input[pos:]
+	assert(len(pr.elemData)-8 == int(pr.elemEnds[len(pr.elemEnds)-1]))
+
+	return pr
+}
+
+// NumElems returns the number of elements in section k.
+func (pr *PkgDecoder) NumElems(k RelocKind) int {
+	count := int(pr.elemEndsEnds[k])
+	if k > 0 {
+		count -= int(pr.elemEndsEnds[k-1])
+	}
+	return count
+}
+
+// TotalElems returns the total number of elements across all sections.
+func (pr *PkgDecoder) TotalElems() int {
+	return len(pr.elemEnds)
+}
+
+// Fingerprint returns the package fingerprint.
+func (pr *PkgDecoder) Fingerprint() [8]byte {
+	var fp [8]byte
+	copy(fp[:], pr.elemData[len(pr.elemData)-8:])
+	return fp
+}
+
+// AbsIdx returns the absolute index for the given (section, index)
+// pair.
+func (pr *PkgDecoder) AbsIdx(k RelocKind, idx Index) int {
+	absIdx := int(idx)
+	if k > 0 {
+		absIdx += int(pr.elemEndsEnds[k-1])
+	}
+	if absIdx >= int(pr.elemEndsEnds[k]) {
+		errorf("%v:%v is out of bounds; %v", k, idx, pr.elemEndsEnds)
+	}
+	return absIdx
+}
+
+// DataIdx returns the raw element bitstream for the given (section,
+// index) pair.
+func (pr *PkgDecoder) DataIdx(k RelocKind, idx Index) string {
+	absIdx := pr.AbsIdx(k, idx)
+
+	var start uint32
+	if absIdx > 0 {
+		start = pr.elemEnds[absIdx-1]
+	}
+	end := pr.elemEnds[absIdx]
+
+	return pr.elemData[start:end]
+}
+
+// StringIdx returns the string value for the given string index.
+func (pr *PkgDecoder) StringIdx(idx Index) string {
+	return pr.DataIdx(RelocString, idx)
+}
+
+// NewDecoder returns a Decoder for the given (section, index) pair,
+// and decodes the given SyncMarker from the element bitstream.
+func (pr *PkgDecoder) NewDecoder(k RelocKind, idx Index, marker SyncMarker) Decoder {
+	r := pr.NewDecoderRaw(k, idx)
+	r.Sync(marker)
+	return r
+}
+
+// TempDecoder returns a Decoder for the given (section, index) pair,
+// and decodes the given SyncMarker from the element bitstream.
+// If possible the Decoder should be RetireDecoder'd when it is no longer
+// needed, this will avoid heap allocations.
+func (pr *PkgDecoder) TempDecoder(k RelocKind, idx Index, marker SyncMarker) Decoder {
+	r := pr.TempDecoderRaw(k, idx)
+	r.Sync(marker)
+	return r
+}
+
+func (pr *PkgDecoder) RetireDecoder(d *Decoder) {
+	pr.scratchRelocEnt = d.Relocs
+	d.Relocs = nil
+}
+
+// NewDecoderRaw returns a Decoder for the given (section, index) pair.
+//
+// Most callers should use NewDecoder instead.
+func (pr *PkgDecoder) NewDecoderRaw(k RelocKind, idx Index) Decoder {
+	r := Decoder{
+		common: pr,
+		k:      k,
+		Idx:    idx,
+	}
+
+	// TODO(mdempsky) r.data.Reset(...) after #44505 is resolved.
+	r.Data = *strings.NewReader(pr.DataIdx(k, idx))
+
+	r.Sync(SyncRelocs)
+	r.Relocs = make([]RelocEnt, r.Len())
+	for i := range r.Relocs {
+		r.Sync(SyncReloc)
+		r.Relocs[i] = RelocEnt{RelocKind(r.Len()), Index(r.Len())}
+	}
+
+	return r
+}
+
+func (pr *PkgDecoder) TempDecoderRaw(k RelocKind, idx Index) Decoder {
+	r := Decoder{
+		common: pr,
+		k:      k,
+		Idx:    idx,
+	}
+
+	r.Data.Reset(pr.DataIdx(k, idx))
+	r.Sync(SyncRelocs)
+	l := r.Len()
+	if cap(pr.scratchRelocEnt) >= l {
+		r.Relocs = pr.scratchRelocEnt[:l]
+		pr.scratchRelocEnt = nil
+	} else {
+		r.Relocs = make([]RelocEnt, l)
+	}
+	for i := range r.Relocs {
+		r.Sync(SyncReloc)
+		r.Relocs[i] = RelocEnt{RelocKind(r.Len()), Index(r.Len())}
+	}
+
+	return r
+}
+
+// A Decoder provides methods for decoding an individual element's
+// bitstream data.
+type Decoder struct {
+	common *PkgDecoder
+
+	Relocs []RelocEnt
+	Data   strings.Reader
+
+	k   RelocKind
+	Idx Index
+}
+
+func (r *Decoder) checkErr(err error) {
+	if err != nil {
+		errorf("unexpected decoding error: %w", err)
+	}
+}
+
+func (r *Decoder) rawUvarint() uint64 {
+	x, err := readUvarint(&r.Data)
+	r.checkErr(err)
+	return x
+}
+
+// readUvarint is a type-specialized copy of encoding/binary.ReadUvarint.
+// This avoids the interface conversion and thus has better escape properties,
+// which flows up the stack.
+func readUvarint(r *strings.Reader) (uint64, error) {
+	var x uint64
+	var s uint
+	for i := 0; i < binary.MaxVarintLen64; i++ {
+		b, err := r.ReadByte()
+		if err != nil {
+			if i > 0 && err == io.EOF {
+				err = io.ErrUnexpectedEOF
+			}
+			return x, err
+		}
+		if b < 0x80 {
+			if i == binary.MaxVarintLen64-1 && b > 1 {
+				return x, overflow
+			}
+			return x | uint64(b)<<s, nil
+		}
+		x |= uint64(b&0x7f) << s
+		s += 7
+	}
+	return x, overflow
+}
+
+var overflow = errors.New("pkgbits: readUvarint overflows a 64-bit integer")
+
+func (r *Decoder) rawVarint() int64 {
+	ux := r.rawUvarint()
+
+	// Zig-zag decode.
+	x := int64(ux >> 1)
+	if ux&1 != 0 {
+		x = ^x
+	}
+	return x
+}
+
+func (r *Decoder) rawReloc(k RelocKind, idx int) Index {
+	e := r.Relocs[idx]
+	assert(e.Kind == k)
+	return e.Idx
+}
+
+// Sync decodes a sync marker from the element bitstream and asserts
+// that it matches the expected marker.
+//
+// If r.common.sync is false, then Sync is a no-op.
+func (r *Decoder) Sync(mWant SyncMarker) {
+	if !r.common.sync {
+		return
+	}
+
+	pos, _ := r.Data.Seek(0, io.SeekCurrent)
+	mHave := SyncMarker(r.rawUvarint())
+	writerPCs := make([]int, r.rawUvarint())
+	for i := range writerPCs {
+		writerPCs[i] = int(r.rawUvarint())
+	}
+
+	if mHave == mWant {
+		return
+	}
+
+	// There's some tension here between printing:
+	//
+	// (1) full file paths that tools can recognize (e.g., so emacs
+	//     hyperlinks the "file:line" text for easy navigation), or
+	//
+	// (2) short file paths that are easier for humans to read (e.g., by
+	//     omitting redundant or irrelevant details, so it's easier to
+	//     focus on the useful bits that remain).
+	//
+	// The current formatting favors the former, as it seems more
+	// helpful in practice. But perhaps the formatting could be improved
+	// to better address both concerns. For example, use relative file
+	// paths if they would be shorter, or rewrite file paths to contain
+	// "$GOROOT" (like objabi.AbsFile does) if tools can be taught how
+	// to reliably expand that again.
+
+	fmt.Printf("export data desync: package %q, section %v, index %v, offset %v\n", r.common.pkgPath, r.k, r.Idx, pos)
+
+	fmt.Printf("\nfound %v, written at:\n", mHave)
+	if len(writerPCs) == 0 {
+		fmt.Printf("\t[stack trace unavailable; recompile package %q with -d=syncframes]\n", r.common.pkgPath)
+	}
+	for _, pc := range writerPCs {
+		fmt.Printf("\t%s\n", r.common.StringIdx(r.rawReloc(RelocString, pc)))
+	}
+
+	fmt.Printf("\nexpected %v, reading at:\n", mWant)
+	var readerPCs [32]uintptr // TODO(mdempsky): Dynamically size?
+	n := runtime.Callers(2, readerPCs[:])
+	for _, pc := range fmtFrames(readerPCs[:n]...) {
+		fmt.Printf("\t%s\n", pc)
+	}
+
+	// We already printed a stack trace for the reader, so now we can
+	// simply exit. Printing a second one with panic or base.Fatalf
+	// would just be noise.
+	os.Exit(1)
+}
+
+// Bool decodes and returns a bool value from the element bitstream.
+func (r *Decoder) Bool() bool {
+	r.Sync(SyncBool)
+	x, err := r.Data.ReadByte()
+	r.checkErr(err)
+	assert(x < 2)
+	return x != 0
+}
+
+// Int64 decodes and returns an int64 value from the element bitstream.
+func (r *Decoder) Int64() int64 {
+	r.Sync(SyncInt64)
+	return r.rawVarint()
+}
+
+// Uint64 decodes and returns a uint64 value from the element bitstream.
+func (r *Decoder) Uint64() uint64 {
+	r.Sync(SyncUint64)
+	return r.rawUvarint()
+}
+
+// Len decodes and returns a non-negative int value from the element bitstream.
+func (r *Decoder) Len() int { x := r.Uint64(); v := int(x); assert(uint64(v) == x); return v }
+
+// Int decodes and returns an int value from the element bitstream.
+func (r *Decoder) Int() int { x := r.Int64(); v := int(x); assert(int64(v) == x); return v }
+
+// Uint decodes and returns a uint value from the element bitstream.
+func (r *Decoder) Uint() uint { x := r.Uint64(); v := uint(x); assert(uint64(v) == x); return v }
+
+// Code decodes a Code value from the element bitstream and returns
+// its ordinal value. It's the caller's responsibility to convert the
+// result to an appropriate Code type.
+//
+// TODO(mdempsky): Ideally this method would have signature "Code[T
+// Code] T" instead, but we don't allow generic methods and the
+// compiler can't depend on generics yet anyway.
+func (r *Decoder) Code(mark SyncMarker) int {
+	r.Sync(mark)
+	return r.Len()
+}
+
+// Reloc decodes a relocation of expected section k from the element
+// bitstream and returns an index to the referenced element.
+func (r *Decoder) Reloc(k RelocKind) Index {
+	r.Sync(SyncUseReloc)
+	return r.rawReloc(k, r.Len())
+}
+
+// String decodes and returns a string value from the element
+// bitstream.
+func (r *Decoder) String() string {
+	r.Sync(SyncString)
+	return r.common.StringIdx(r.Reloc(RelocString))
+}
+
+// Strings decodes and returns a variable-length slice of strings from
+// the element bitstream.
+func (r *Decoder) Strings() []string {
+	res := make([]string, r.Len())
+	for i := range res {
+		res[i] = r.String()
+	}
+	return res
+}
+
+// Value decodes and returns a constant.Value from the element
+// bitstream.
+func (r *Decoder) Value() constant.Value {
+	r.Sync(SyncValue)
+	isComplex := r.Bool()
+	val := r.scalar()
+	if isComplex {
+		val = constant.BinaryOp(val, token.ADD, constant.MakeImag(r.scalar()))
+	}
+	return val
+}
+
+func (r *Decoder) scalar() constant.Value {
+	switch tag := CodeVal(r.Code(SyncVal)); tag {
+	default:
+		panic(fmt.Errorf("unexpected scalar tag: %v", tag))
+
+	case ValBool:
+		return constant.MakeBool(r.Bool())
+	case ValString:
+		return constant.MakeString(r.String())
+	case ValInt64:
+		return constant.MakeInt64(r.Int64())
+	case ValBigInt:
+		return constant.Make(r.bigInt())
+	case ValBigRat:
+		num := r.bigInt()
+		denom := r.bigInt()
+		return constant.Make(new(big.Rat).SetFrac(num, denom))
+	case ValBigFloat:
+		return constant.Make(r.bigFloat())
+	}
+}
+
+func (r *Decoder) bigInt() *big.Int {
+	v := new(big.Int).SetBytes([]byte(r.String()))
+	if r.Bool() {
+		v.Neg(v)
+	}
+	return v
+}
+
+func (r *Decoder) bigFloat() *big.Float {
+	v := new(big.Float).SetPrec(512)
+	assert(v.UnmarshalText([]byte(r.String())) == nil)
+	return v
+}
+
+// @@@ Helpers
+
+// TODO(mdempsky): These should probably be removed. I think they're a
+// smell that the export data format is not yet quite right.
+
+// PeekPkgPath returns the package path for the specified package
+// index.
+func (pr *PkgDecoder) PeekPkgPath(idx Index) string {
+	var path string
+	{
+		r := pr.TempDecoder(RelocPkg, idx, SyncPkgDef)
+		path = r.String()
+		pr.RetireDecoder(&r)
+	}
+	if path == "" {
+		path = pr.pkgPath
+	}
+	return path
+}
+
+// PeekObj returns the package path, object name, and CodeObj for the
+// specified object index.
+func (pr *PkgDecoder) PeekObj(idx Index) (string, string, CodeObj) {
+	var ridx Index
+	var name string
+	var rcode int
+	{
+		r := pr.TempDecoder(RelocName, idx, SyncObject1)
+		r.Sync(SyncSym)
+		r.Sync(SyncPkg)
+		ridx = r.Reloc(RelocPkg)
+		name = r.String()
+		rcode = r.Code(SyncCodeObj)
+		pr.RetireDecoder(&r)
+	}
+
+	path := pr.PeekPkgPath(ridx)
+	assert(name != "")
+
+	tag := CodeObj(rcode)
+
+	return path, name, tag
+}
diff --git a/vendor/golang.org/x/tools/internal/pkgbits/doc.go b/vendor/golang.org/x/tools/internal/pkgbits/doc.go
new file mode 100644
index 0000000..c8a2796
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/pkgbits/doc.go
@@ -0,0 +1,32 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package pkgbits implements low-level coding abstractions for
+// Unified IR's export data format.
+//
+// At a low-level, a package is a collection of bitstream elements.
+// Each element has a "kind" and a dense, non-negative index.
+// Elements can be randomly accessed given their kind and index.
+//
+// Individual elements are sequences of variable-length values (e.g.,
+// integers, booleans, strings, go/constant values, cross-references
+// to other elements). Package pkgbits provides APIs for encoding and
+// decoding these low-level values, but the details of mapping
+// higher-level Go constructs into elements is left to higher-level
+// abstractions.
+//
+// Elements may cross-reference each other with "relocations." For
+// example, an element representing a pointer type has a relocation
+// referring to the element type.
+//
+// Go constructs may be composed as a constellation of multiple
+// elements. For example, a declared function may have one element to
+// describe the object (e.g., its name, type, position), and a
+// separate element to describe its function body. This allows readers
+// some flexibility in efficiently seeking or re-reading data (e.g.,
+// inlining requires re-reading the function body for each inlined
+// call, without needing to re-read the object-level details).
+//
+// This is a copy of internal/pkgbits in the Go implementation.
+package pkgbits
diff --git a/vendor/golang.org/x/tools/internal/pkgbits/encoder.go b/vendor/golang.org/x/tools/internal/pkgbits/encoder.go
new file mode 100644
index 0000000..6482617
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/pkgbits/encoder.go
@@ -0,0 +1,383 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package pkgbits
+
+import (
+	"bytes"
+	"crypto/md5"
+	"encoding/binary"
+	"go/constant"
+	"io"
+	"math/big"
+	"runtime"
+)
+
+// currentVersion is the current version number.
+//
+//   - v0: initial prototype
+//
+//   - v1: adds the flags uint32 word
+const currentVersion uint32 = 1
+
+// A PkgEncoder provides methods for encoding a package's Unified IR
+// export data.
+type PkgEncoder struct {
+	// elems holds the bitstream for previously encoded elements.
+	elems [numRelocs][]string
+
+	// stringsIdx maps previously encoded strings to their index within
+	// the RelocString section, to allow deduplication. That is,
+	// elems[RelocString][stringsIdx[s]] == s (if present).
+	stringsIdx map[string]Index
+
+	// syncFrames is the number of frames to write at each sync
+	// marker. A negative value means sync markers are omitted.
+	syncFrames int
+}
+
+// SyncMarkers reports whether pw uses sync markers.
+func (pw *PkgEncoder) SyncMarkers() bool { return pw.syncFrames >= 0 }
+
+// NewPkgEncoder returns an initialized PkgEncoder.
+//
+// syncFrames is the number of caller frames that should be serialized
+// at Sync points. Serializing additional frames results in larger
+// export data files, but can help diagnosing desync errors in
+// higher-level Unified IR reader/writer code. If syncFrames is
+// negative, then sync markers are omitted entirely.
+func NewPkgEncoder(syncFrames int) PkgEncoder {
+	return PkgEncoder{
+		stringsIdx: make(map[string]Index),
+		syncFrames: syncFrames,
+	}
+}
+
+// DumpTo writes the package's encoded data to out0 and returns the
+// package fingerprint.
+func (pw *PkgEncoder) DumpTo(out0 io.Writer) (fingerprint [8]byte) {
+	h := md5.New()
+	out := io.MultiWriter(out0, h)
+
+	writeUint32 := func(x uint32) {
+		assert(binary.Write(out, binary.LittleEndian, x) == nil)
+	}
+
+	writeUint32(currentVersion)
+
+	var flags uint32
+	if pw.SyncMarkers() {
+		flags |= flagSyncMarkers
+	}
+	writeUint32(flags)
+
+	// Write elemEndsEnds.
+	var sum uint32
+	for _, elems := range &pw.elems {
+		sum += uint32(len(elems))
+		writeUint32(sum)
+	}
+
+	// Write elemEnds.
+	sum = 0
+	for _, elems := range &pw.elems {
+		for _, elem := range elems {
+			sum += uint32(len(elem))
+			writeUint32(sum)
+		}
+	}
+
+	// Write elemData.
+	for _, elems := range &pw.elems {
+		for _, elem := range elems {
+			_, err := io.WriteString(out, elem)
+			assert(err == nil)
+		}
+	}
+
+	// Write fingerprint.
+	copy(fingerprint[:], h.Sum(nil))
+	_, err := out0.Write(fingerprint[:])
+	assert(err == nil)
+
+	return
+}
+
+// StringIdx adds a string value to the strings section, if not
+// already present, and returns its index.
+func (pw *PkgEncoder) StringIdx(s string) Index {
+	if idx, ok := pw.stringsIdx[s]; ok {
+		assert(pw.elems[RelocString][idx] == s)
+		return idx
+	}
+
+	idx := Index(len(pw.elems[RelocString]))
+	pw.elems[RelocString] = append(pw.elems[RelocString], s)
+	pw.stringsIdx[s] = idx
+	return idx
+}
+
+// NewEncoder returns an Encoder for a new element within the given
+// section, and encodes the given SyncMarker as the start of the
+// element bitstream.
+func (pw *PkgEncoder) NewEncoder(k RelocKind, marker SyncMarker) Encoder {
+	e := pw.NewEncoderRaw(k)
+	e.Sync(marker)
+	return e
+}
+
+// NewEncoderRaw returns an Encoder for a new element within the given
+// section.
+//
+// Most callers should use NewEncoder instead.
+func (pw *PkgEncoder) NewEncoderRaw(k RelocKind) Encoder {
+	idx := Index(len(pw.elems[k]))
+	pw.elems[k] = append(pw.elems[k], "") // placeholder
+
+	return Encoder{
+		p:   pw,
+		k:   k,
+		Idx: idx,
+	}
+}
+
+// An Encoder provides methods for encoding an individual element's
+// bitstream data.
+type Encoder struct {
+	p *PkgEncoder
+
+	Relocs   []RelocEnt
+	RelocMap map[RelocEnt]uint32
+	Data     bytes.Buffer // accumulated element bitstream data
+
+	encodingRelocHeader bool
+
+	k   RelocKind
+	Idx Index // index within relocation section
+}
+
+// Flush finalizes the element's bitstream and returns its Index.
+func (w *Encoder) Flush() Index {
+	var sb bytes.Buffer // TODO(mdempsky): strings.Builder after #44505 is resolved
+
+	// Backup the data so we write the relocations at the front.
+	var tmp bytes.Buffer
+	io.Copy(&tmp, &w.Data)
+
+	// TODO(mdempsky): Consider writing these out separately so they're
+	// easier to strip, along with function bodies, so that we can prune
+	// down to just the data that's relevant to go/types.
+	if w.encodingRelocHeader {
+		panic("encodingRelocHeader already true; recursive flush?")
+	}
+	w.encodingRelocHeader = true
+	w.Sync(SyncRelocs)
+	w.Len(len(w.Relocs))
+	for _, rEnt := range w.Relocs {
+		w.Sync(SyncReloc)
+		w.Len(int(rEnt.Kind))
+		w.Len(int(rEnt.Idx))
+	}
+
+	io.Copy(&sb, &w.Data)
+	io.Copy(&sb, &tmp)
+	w.p.elems[w.k][w.Idx] = sb.String()
+
+	return w.Idx
+}
+
+func (w *Encoder) checkErr(err error) {
+	if err != nil {
+		errorf("unexpected encoding error: %v", err)
+	}
+}
+
+func (w *Encoder) rawUvarint(x uint64) {
+	var buf [binary.MaxVarintLen64]byte
+	n := binary.PutUvarint(buf[:], x)
+	_, err := w.Data.Write(buf[:n])
+	w.checkErr(err)
+}
+
+func (w *Encoder) rawVarint(x int64) {
+	// Zig-zag encode.
+	ux := uint64(x) << 1
+	if x < 0 {
+		ux = ^ux
+	}
+
+	w.rawUvarint(ux)
+}
+
+func (w *Encoder) rawReloc(r RelocKind, idx Index) int {
+	e := RelocEnt{r, idx}
+	if w.RelocMap != nil {
+		if i, ok := w.RelocMap[e]; ok {
+			return int(i)
+		}
+	} else {
+		w.RelocMap = make(map[RelocEnt]uint32)
+	}
+
+	i := len(w.Relocs)
+	w.RelocMap[e] = uint32(i)
+	w.Relocs = append(w.Relocs, e)
+	return i
+}
+
+func (w *Encoder) Sync(m SyncMarker) {
+	if !w.p.SyncMarkers() {
+		return
+	}
+
+	// Writing out stack frame string references requires working
+	// relocations, but writing out the relocations themselves involves
+	// sync markers. To prevent infinite recursion, we simply trim the
+	// stack frame for sync markers within the relocation header.
+	var frames []string
+	if !w.encodingRelocHeader && w.p.syncFrames > 0 {
+		pcs := make([]uintptr, w.p.syncFrames)
+		n := runtime.Callers(2, pcs)
+		frames = fmtFrames(pcs[:n]...)
+	}
+
+	// TODO(mdempsky): Save space by writing out stack frames as a
+	// linked list so we can share common stack frames.
+	w.rawUvarint(uint64(m))
+	w.rawUvarint(uint64(len(frames)))
+	for _, frame := range frames {
+		w.rawUvarint(uint64(w.rawReloc(RelocString, w.p.StringIdx(frame))))
+	}
+}
+
+// Bool encodes and writes a bool value into the element bitstream,
+// and then returns the bool value.
+//
+// For simple, 2-alternative encodings, the idiomatic way to call Bool
+// is something like:
+//
+//	if w.Bool(x != 0) {
+//		// alternative #1
+//	} else {
+//		// alternative #2
+//	}
+//
+// For multi-alternative encodings, use Code instead.
+func (w *Encoder) Bool(b bool) bool {
+	w.Sync(SyncBool)
+	var x byte
+	if b {
+		x = 1
+	}
+	err := w.Data.WriteByte(x)
+	w.checkErr(err)
+	return b
+}
+
+// Int64 encodes and writes an int64 value into the element bitstream.
+func (w *Encoder) Int64(x int64) {
+	w.Sync(SyncInt64)
+	w.rawVarint(x)
+}
+
+// Uint64 encodes and writes a uint64 value into the element bitstream.
+func (w *Encoder) Uint64(x uint64) {
+	w.Sync(SyncUint64)
+	w.rawUvarint(x)
+}
+
+// Len encodes and writes a non-negative int value into the element bitstream.
+func (w *Encoder) Len(x int) { assert(x >= 0); w.Uint64(uint64(x)) }
+
+// Int encodes and writes an int value into the element bitstream.
+func (w *Encoder) Int(x int) { w.Int64(int64(x)) }
+
+// Uint encodes and writes a uint value into the element bitstream.
+func (w *Encoder) Uint(x uint) { w.Uint64(uint64(x)) }
+
+// Reloc encodes and writes a relocation for the given (section,
+// index) pair into the element bitstream.
+//
+// Note: Only the index is formally written into the element
+// bitstream, so bitstream decoders must know from context which
+// section an encoded relocation refers to.
+func (w *Encoder) Reloc(r RelocKind, idx Index) {
+	w.Sync(SyncUseReloc)
+	w.Len(w.rawReloc(r, idx))
+}
+
+// Code encodes and writes a Code value into the element bitstream.
+func (w *Encoder) Code(c Code) {
+	w.Sync(c.Marker())
+	w.Len(c.Value())
+}
+
+// String encodes and writes a string value into the element
+// bitstream.
+//
+// Internally, strings are deduplicated by adding them to the strings
+// section (if not already present), and then writing a relocation
+// into the element bitstream.
+func (w *Encoder) String(s string) {
+	w.Sync(SyncString)
+	w.Reloc(RelocString, w.p.StringIdx(s))
+}
+
+// Strings encodes and writes a variable-length slice of strings into
+// the element bitstream.
+func (w *Encoder) Strings(ss []string) {
+	w.Len(len(ss))
+	for _, s := range ss {
+		w.String(s)
+	}
+}
+
+// Value encodes and writes a constant.Value into the element
+// bitstream.
+func (w *Encoder) Value(val constant.Value) {
+	w.Sync(SyncValue)
+	if w.Bool(val.Kind() == constant.Complex) {
+		w.scalar(constant.Real(val))
+		w.scalar(constant.Imag(val))
+	} else {
+		w.scalar(val)
+	}
+}
+
+func (w *Encoder) scalar(val constant.Value) {
+	switch v := constant.Val(val).(type) {
+	default:
+		errorf("unhandled %v (%v)", val, val.Kind())
+	case bool:
+		w.Code(ValBool)
+		w.Bool(v)
+	case string:
+		w.Code(ValString)
+		w.String(v)
+	case int64:
+		w.Code(ValInt64)
+		w.Int64(v)
+	case *big.Int:
+		w.Code(ValBigInt)
+		w.bigInt(v)
+	case *big.Rat:
+		w.Code(ValBigRat)
+		w.bigInt(v.Num())
+		w.bigInt(v.Denom())
+	case *big.Float:
+		w.Code(ValBigFloat)
+		w.bigFloat(v)
+	}
+}
+
+func (w *Encoder) bigInt(v *big.Int) {
+	b := v.Bytes()
+	w.String(string(b)) // TODO: More efficient encoding.
+	w.Bool(v.Sign() < 0)
+}
+
+func (w *Encoder) bigFloat(v *big.Float) {
+	b := v.Append(nil, 'p', -1)
+	w.String(string(b)) // TODO: More efficient encoding.
+}
diff --git a/vendor/golang.org/x/tools/internal/pkgbits/flags.go b/vendor/golang.org/x/tools/internal/pkgbits/flags.go
new file mode 100644
index 0000000..6542227
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/pkgbits/flags.go
@@ -0,0 +1,9 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package pkgbits
+
+const (
+	flagSyncMarkers = 1 << iota // file format contains sync markers
+)
diff --git a/vendor/golang.org/x/tools/internal/pkgbits/frames_go1.go b/vendor/golang.org/x/tools/internal/pkgbits/frames_go1.go
new file mode 100644
index 0000000..5294f6a
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/pkgbits/frames_go1.go
@@ -0,0 +1,21 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build !go1.7
+// +build !go1.7
+
+// TODO(mdempsky): Remove after #44505 is resolved
+
+package pkgbits
+
+import "runtime"
+
+func walkFrames(pcs []uintptr, visit frameVisitor) {
+	for _, pc := range pcs {
+		fn := runtime.FuncForPC(pc)
+		file, line := fn.FileLine(pc)
+
+		visit(file, line, fn.Name(), pc-fn.Entry())
+	}
+}
diff --git a/vendor/golang.org/x/tools/internal/pkgbits/frames_go17.go b/vendor/golang.org/x/tools/internal/pkgbits/frames_go17.go
new file mode 100644
index 0000000..2324ae7
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/pkgbits/frames_go17.go
@@ -0,0 +1,28 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build go1.7
+// +build go1.7
+
+package pkgbits
+
+import "runtime"
+
+// walkFrames calls visit for each call frame represented by pcs.
+//
+// pcs should be a slice of PCs, as returned by runtime.Callers.
+func walkFrames(pcs []uintptr, visit frameVisitor) {
+	if len(pcs) == 0 {
+		return
+	}
+
+	frames := runtime.CallersFrames(pcs)
+	for {
+		frame, more := frames.Next()
+		visit(frame.File, frame.Line, frame.Function, frame.PC-frame.Entry)
+		if !more {
+			return
+		}
+	}
+}
diff --git a/vendor/golang.org/x/tools/internal/pkgbits/reloc.go b/vendor/golang.org/x/tools/internal/pkgbits/reloc.go
new file mode 100644
index 0000000..fcdfb97
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/pkgbits/reloc.go
@@ -0,0 +1,42 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package pkgbits
+
+// A RelocKind indicates a particular section within a unified IR export.
+type RelocKind int32
+
+// An Index represents a bitstream element index within a particular
+// section.
+type Index int32
+
+// A relocEnt (relocation entry) is an entry in an element's local
+// reference table.
+//
+// TODO(mdempsky): Rename this too.
+type RelocEnt struct {
+	Kind RelocKind
+	Idx  Index
+}
+
+// Reserved indices within the meta relocation section.
+const (
+	PublicRootIdx  Index = 0
+	PrivateRootIdx Index = 1
+)
+
+const (
+	RelocString RelocKind = iota
+	RelocMeta
+	RelocPosBase
+	RelocPkg
+	RelocName
+	RelocType
+	RelocObj
+	RelocObjExt
+	RelocObjDict
+	RelocBody
+
+	numRelocs = iota
+)
diff --git a/vendor/golang.org/x/tools/internal/pkgbits/support.go b/vendor/golang.org/x/tools/internal/pkgbits/support.go
new file mode 100644
index 0000000..ad26d3b
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/pkgbits/support.go
@@ -0,0 +1,17 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package pkgbits
+
+import "fmt"
+
+func assert(b bool) {
+	if !b {
+		panic("assertion failed")
+	}
+}
+
+func errorf(format string, args ...interface{}) {
+	panic(fmt.Errorf(format, args...))
+}
diff --git a/vendor/golang.org/x/tools/internal/pkgbits/sync.go b/vendor/golang.org/x/tools/internal/pkgbits/sync.go
new file mode 100644
index 0000000..5bd51ef
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/pkgbits/sync.go
@@ -0,0 +1,113 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package pkgbits
+
+import (
+	"fmt"
+	"strings"
+)
+
+// fmtFrames formats a backtrace for reporting reader/writer desyncs.
+func fmtFrames(pcs ...uintptr) []string {
+	res := make([]string, 0, len(pcs))
+	walkFrames(pcs, func(file string, line int, name string, offset uintptr) {
+		// Trim package from function name. It's just redundant noise.
+		name = strings.TrimPrefix(name, "cmd/compile/internal/noder.")
+
+		res = append(res, fmt.Sprintf("%s:%v: %s +0x%v", file, line, name, offset))
+	})
+	return res
+}
+
+type frameVisitor func(file string, line int, name string, offset uintptr)
+
+// SyncMarker is an enum type that represents markers that may be
+// written to export data to ensure the reader and writer stay
+// synchronized.
+type SyncMarker int
+
+//go:generate stringer -type=SyncMarker -trimprefix=Sync
+
+const (
+	_ SyncMarker = iota
+
+	// Public markers (known to go/types importers).
+
+	// Low-level coding markers.
+	SyncEOF
+	SyncBool
+	SyncInt64
+	SyncUint64
+	SyncString
+	SyncValue
+	SyncVal
+	SyncRelocs
+	SyncReloc
+	SyncUseReloc
+
+	// Higher-level object and type markers.
+	SyncPublic
+	SyncPos
+	SyncPosBase
+	SyncObject
+	SyncObject1
+	SyncPkg
+	SyncPkgDef
+	SyncMethod
+	SyncType
+	SyncTypeIdx
+	SyncTypeParamNames
+	SyncSignature
+	SyncParams
+	SyncParam
+	SyncCodeObj
+	SyncSym
+	SyncLocalIdent
+	SyncSelector
+
+	// Private markers (only known to cmd/compile).
+	SyncPrivate
+
+	SyncFuncExt
+	SyncVarExt
+	SyncTypeExt
+	SyncPragma
+
+	SyncExprList
+	SyncExprs
+	SyncExpr
+	SyncExprType
+	SyncAssign
+	SyncOp
+	SyncFuncLit
+	SyncCompLit
+
+	SyncDecl
+	SyncFuncBody
+	SyncOpenScope
+	SyncCloseScope
+	SyncCloseAnotherScope
+	SyncDeclNames
+	SyncDeclName
+
+	SyncStmts
+	SyncBlockStmt
+	SyncIfStmt
+	SyncForStmt
+	SyncSwitchStmt
+	SyncRangeStmt
+	SyncCaseClause
+	SyncCommClause
+	SyncSelectStmt
+	SyncDecls
+	SyncLabeledStmt
+	SyncUseObjLocal
+	SyncAddLocal
+	SyncLinkname
+	SyncStmt1
+	SyncStmtsEnd
+	SyncLabel
+	SyncOptLabel
+)
diff --git a/vendor/golang.org/x/tools/internal/pkgbits/syncmarker_string.go b/vendor/golang.org/x/tools/internal/pkgbits/syncmarker_string.go
new file mode 100644
index 0000000..4a5b0ca
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/pkgbits/syncmarker_string.go
@@ -0,0 +1,89 @@
+// Code generated by "stringer -type=SyncMarker -trimprefix=Sync"; DO NOT EDIT.
+
+package pkgbits
+
+import "strconv"
+
+func _() {
+	// An "invalid array index" compiler error signifies that the constant values have changed.
+	// Re-run the stringer command to generate them again.
+	var x [1]struct{}
+	_ = x[SyncEOF-1]
+	_ = x[SyncBool-2]
+	_ = x[SyncInt64-3]
+	_ = x[SyncUint64-4]
+	_ = x[SyncString-5]
+	_ = x[SyncValue-6]
+	_ = x[SyncVal-7]
+	_ = x[SyncRelocs-8]
+	_ = x[SyncReloc-9]
+	_ = x[SyncUseReloc-10]
+	_ = x[SyncPublic-11]
+	_ = x[SyncPos-12]
+	_ = x[SyncPosBase-13]
+	_ = x[SyncObject-14]
+	_ = x[SyncObject1-15]
+	_ = x[SyncPkg-16]
+	_ = x[SyncPkgDef-17]
+	_ = x[SyncMethod-18]
+	_ = x[SyncType-19]
+	_ = x[SyncTypeIdx-20]
+	_ = x[SyncTypeParamNames-21]
+	_ = x[SyncSignature-22]
+	_ = x[SyncParams-23]
+	_ = x[SyncParam-24]
+	_ = x[SyncCodeObj-25]
+	_ = x[SyncSym-26]
+	_ = x[SyncLocalIdent-27]
+	_ = x[SyncSelector-28]
+	_ = x[SyncPrivate-29]
+	_ = x[SyncFuncExt-30]
+	_ = x[SyncVarExt-31]
+	_ = x[SyncTypeExt-32]
+	_ = x[SyncPragma-33]
+	_ = x[SyncExprList-34]
+	_ = x[SyncExprs-35]
+	_ = x[SyncExpr-36]
+	_ = x[SyncExprType-37]
+	_ = x[SyncAssign-38]
+	_ = x[SyncOp-39]
+	_ = x[SyncFuncLit-40]
+	_ = x[SyncCompLit-41]
+	_ = x[SyncDecl-42]
+	_ = x[SyncFuncBody-43]
+	_ = x[SyncOpenScope-44]
+	_ = x[SyncCloseScope-45]
+	_ = x[SyncCloseAnotherScope-46]
+	_ = x[SyncDeclNames-47]
+	_ = x[SyncDeclName-48]
+	_ = x[SyncStmts-49]
+	_ = x[SyncBlockStmt-50]
+	_ = x[SyncIfStmt-51]
+	_ = x[SyncForStmt-52]
+	_ = x[SyncSwitchStmt-53]
+	_ = x[SyncRangeStmt-54]
+	_ = x[SyncCaseClause-55]
+	_ = x[SyncCommClause-56]
+	_ = x[SyncSelectStmt-57]
+	_ = x[SyncDecls-58]
+	_ = x[SyncLabeledStmt-59]
+	_ = x[SyncUseObjLocal-60]
+	_ = x[SyncAddLocal-61]
+	_ = x[SyncLinkname-62]
+	_ = x[SyncStmt1-63]
+	_ = x[SyncStmtsEnd-64]
+	_ = x[SyncLabel-65]
+	_ = x[SyncOptLabel-66]
+}
+
+const _SyncMarker_name = "EOFBoolInt64Uint64StringValueValRelocsRelocUseRelocPublicPosPosBaseObjectObject1PkgPkgDefMethodTypeTypeIdxTypeParamNamesSignatureParamsParamCodeObjSymLocalIdentSelectorPrivateFuncExtVarExtTypeExtPragmaExprListExprsExprExprTypeAssignOpFuncLitCompLitDeclFuncBodyOpenScopeCloseScopeCloseAnotherScopeDeclNamesDeclNameStmtsBlockStmtIfStmtForStmtSwitchStmtRangeStmtCaseClauseCommClauseSelectStmtDeclsLabeledStmtUseObjLocalAddLocalLinknameStmt1StmtsEndLabelOptLabel"
+
+var _SyncMarker_index = [...]uint16{0, 3, 7, 12, 18, 24, 29, 32, 38, 43, 51, 57, 60, 67, 73, 80, 83, 89, 95, 99, 106, 120, 129, 135, 140, 147, 150, 160, 168, 175, 182, 188, 195, 201, 209, 214, 218, 226, 232, 234, 241, 248, 252, 260, 269, 279, 296, 305, 313, 318, 327, 333, 340, 350, 359, 369, 379, 389, 394, 405, 416, 424, 432, 437, 445, 450, 458}
+
+func (i SyncMarker) String() string {
+	i -= 1
+	if i < 0 || i >= SyncMarker(len(_SyncMarker_index)-1) {
+		return "SyncMarker(" + strconv.FormatInt(int64(i+1), 10) + ")"
+	}
+	return _SyncMarker_name[_SyncMarker_index[i]:_SyncMarker_index[i+1]]
+}
diff --git a/vendor/golang.org/x/tools/internal/robustio/gopls_windows.go b/vendor/golang.org/x/tools/internal/robustio/gopls_windows.go
new file mode 100644
index 0000000..949f278
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/robustio/gopls_windows.go
@@ -0,0 +1,16 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package robustio
+
+import "syscall"
+
+// The robustio package is copied from cmd/go/internal/robustio, a package used
+// by the go command to retry known flaky operations on certain operating systems.
+
+//go:generate go run copyfiles.go
+
+// Since the gopls module cannot access internal/syscall/windows, copy a
+// necessary constant.
+const ERROR_SHARING_VIOLATION syscall.Errno = 32
diff --git a/vendor/golang.org/x/tools/internal/robustio/robustio.go b/vendor/golang.org/x/tools/internal/robustio/robustio.go
new file mode 100644
index 0000000..0a559fc
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/robustio/robustio.go
@@ -0,0 +1,69 @@
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package robustio wraps I/O functions that are prone to failure on Windows,
+// transparently retrying errors up to an arbitrary timeout.
+//
+// Errors are classified heuristically and retries are bounded, so the functions
+// in this package do not completely eliminate spurious errors. However, they do
+// significantly reduce the rate of failure in practice.
+//
+// If so, the error will likely wrap one of:
+// The functions in this package do not completely eliminate spurious errors,
+// but substantially reduce their rate of occurrence in practice.
+package robustio
+
+import "time"
+
+// Rename is like os.Rename, but on Windows retries errors that may occur if the
+// file is concurrently read or overwritten.
+//
+// (See golang.org/issue/31247 and golang.org/issue/32188.)
+func Rename(oldpath, newpath string) error {
+	return rename(oldpath, newpath)
+}
+
+// ReadFile is like os.ReadFile, but on Windows retries errors that may
+// occur if the file is concurrently replaced.
+//
+// (See golang.org/issue/31247 and golang.org/issue/32188.)
+func ReadFile(filename string) ([]byte, error) {
+	return readFile(filename)
+}
+
+// RemoveAll is like os.RemoveAll, but on Windows retries errors that may occur
+// if an executable file in the directory has recently been executed.
+//
+// (See golang.org/issue/19491.)
+func RemoveAll(path string) error {
+	return removeAll(path)
+}
+
+// IsEphemeralError reports whether err is one of the errors that the functions
+// in this package attempt to mitigate.
+//
+// Errors considered ephemeral include:
+//   - syscall.ERROR_ACCESS_DENIED
+//   - syscall.ERROR_FILE_NOT_FOUND
+//   - internal/syscall/windows.ERROR_SHARING_VIOLATION
+//
+// This set may be expanded in the future; programs must not rely on the
+// non-ephemerality of any given error.
+func IsEphemeralError(err error) bool {
+	return isEphemeralError(err)
+}
+
+// A FileID uniquely identifies a file in the file system.
+//
+// If GetFileID(name1) returns the same ID as GetFileID(name2), the two file
+// names denote the same file.
+// A FileID is comparable, and thus suitable for use as a map key.
+type FileID struct {
+	device, inode uint64
+}
+
+// GetFileID returns the file system's identifier for the file, and its
+// modification time.
+// Like os.Stat, it reads through symbolic links.
+func GetFileID(filename string) (FileID, time.Time, error) { return getFileID(filename) }
diff --git a/vendor/golang.org/x/tools/internal/robustio/robustio_darwin.go b/vendor/golang.org/x/tools/internal/robustio/robustio_darwin.go
new file mode 100644
index 0000000..99fd8eb
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/robustio/robustio_darwin.go
@@ -0,0 +1,21 @@
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package robustio
+
+import (
+	"errors"
+	"syscall"
+)
+
+const errFileNotFound = syscall.ENOENT
+
+// isEphemeralError returns true if err may be resolved by waiting.
+func isEphemeralError(err error) bool {
+	var errno syscall.Errno
+	if errors.As(err, &errno) {
+		return errno == errFileNotFound
+	}
+	return false
+}
diff --git a/vendor/golang.org/x/tools/internal/robustio/robustio_flaky.go b/vendor/golang.org/x/tools/internal/robustio/robustio_flaky.go
new file mode 100644
index 0000000..c6f9972
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/robustio/robustio_flaky.go
@@ -0,0 +1,93 @@
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build windows || darwin
+// +build windows darwin
+
+package robustio
+
+import (
+	"errors"
+	"io/ioutil"
+	"math/rand"
+	"os"
+	"syscall"
+	"time"
+)
+
+const arbitraryTimeout = 2000 * time.Millisecond
+
+// retry retries ephemeral errors from f up to an arbitrary timeout
+// to work around filesystem flakiness on Windows and Darwin.
+func retry(f func() (err error, mayRetry bool)) error {
+	var (
+		bestErr     error
+		lowestErrno syscall.Errno
+		start       time.Time
+		nextSleep   time.Duration = 1 * time.Millisecond
+	)
+	for {
+		err, mayRetry := f()
+		if err == nil || !mayRetry {
+			return err
+		}
+
+		var errno syscall.Errno
+		if errors.As(err, &errno) && (lowestErrno == 0 || errno < lowestErrno) {
+			bestErr = err
+			lowestErrno = errno
+		} else if bestErr == nil {
+			bestErr = err
+		}
+
+		if start.IsZero() {
+			start = time.Now()
+		} else if d := time.Since(start) + nextSleep; d >= arbitraryTimeout {
+			break
+		}
+		time.Sleep(nextSleep)
+		nextSleep += time.Duration(rand.Int63n(int64(nextSleep)))
+	}
+
+	return bestErr
+}
+
+// rename is like os.Rename, but retries ephemeral errors.
+//
+// On Windows it wraps os.Rename, which (as of 2019-06-04) uses MoveFileEx with
+// MOVEFILE_REPLACE_EXISTING.
+//
+// Windows also provides a different system call, ReplaceFile,
+// that provides similar semantics, but perhaps preserves more metadata. (The
+// documentation on the differences between the two is very sparse.)
+//
+// Empirical error rates with MoveFileEx are lower under modest concurrency, so
+// for now we're sticking with what the os package already provides.
+func rename(oldpath, newpath string) (err error) {
+	return retry(func() (err error, mayRetry bool) {
+		err = os.Rename(oldpath, newpath)
+		return err, isEphemeralError(err)
+	})
+}
+
+// readFile is like os.ReadFile, but retries ephemeral errors.
+func readFile(filename string) ([]byte, error) {
+	var b []byte
+	err := retry(func() (err error, mayRetry bool) {
+		b, err = ioutil.ReadFile(filename)
+
+		// Unlike in rename, we do not retry errFileNotFound here: it can occur
+		// as a spurious error, but the file may also genuinely not exist, so the
+		// increase in robustness is probably not worth the extra latency.
+		return err, isEphemeralError(err) && !errors.Is(err, errFileNotFound)
+	})
+	return b, err
+}
+
+func removeAll(path string) error {
+	return retry(func() (err error, mayRetry bool) {
+		err = os.RemoveAll(path)
+		return err, isEphemeralError(err)
+	})
+}
diff --git a/vendor/golang.org/x/tools/internal/robustio/robustio_other.go b/vendor/golang.org/x/tools/internal/robustio/robustio_other.go
new file mode 100644
index 0000000..c11dbf9
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/robustio/robustio_other.go
@@ -0,0 +1,29 @@
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build !windows && !darwin
+// +build !windows,!darwin
+
+package robustio
+
+import (
+	"io/ioutil"
+	"os"
+)
+
+func rename(oldpath, newpath string) error {
+	return os.Rename(oldpath, newpath)
+}
+
+func readFile(filename string) ([]byte, error) {
+	return ioutil.ReadFile(filename)
+}
+
+func removeAll(path string) error {
+	return os.RemoveAll(path)
+}
+
+func isEphemeralError(err error) bool {
+	return false
+}
diff --git a/vendor/golang.org/x/tools/internal/robustio/robustio_plan9.go b/vendor/golang.org/x/tools/internal/robustio/robustio_plan9.go
new file mode 100644
index 0000000..9fa4cac
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/robustio/robustio_plan9.go
@@ -0,0 +1,26 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build plan9
+// +build plan9
+
+package robustio
+
+import (
+	"os"
+	"syscall"
+	"time"
+)
+
+func getFileID(filename string) (FileID, time.Time, error) {
+	fi, err := os.Stat(filename)
+	if err != nil {
+		return FileID{}, time.Time{}, err
+	}
+	dir := fi.Sys().(*syscall.Dir)
+	return FileID{
+		device: uint64(dir.Type)<<32 | uint64(dir.Dev),
+		inode:  dir.Qid.Path,
+	}, fi.ModTime(), nil
+}
diff --git a/vendor/golang.org/x/tools/internal/robustio/robustio_posix.go b/vendor/golang.org/x/tools/internal/robustio/robustio_posix.go
new file mode 100644
index 0000000..8aa13d0
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/robustio/robustio_posix.go
@@ -0,0 +1,28 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build !windows && !plan9
+// +build !windows,!plan9
+
+// TODO(adonovan): use 'unix' tag when go1.19 can be assumed.
+
+package robustio
+
+import (
+	"os"
+	"syscall"
+	"time"
+)
+
+func getFileID(filename string) (FileID, time.Time, error) {
+	fi, err := os.Stat(filename)
+	if err != nil {
+		return FileID{}, time.Time{}, err
+	}
+	stat := fi.Sys().(*syscall.Stat_t)
+	return FileID{
+		device: uint64(stat.Dev), // (int32 on darwin, uint64 on linux)
+		inode:  stat.Ino,
+	}, fi.ModTime(), nil
+}
diff --git a/vendor/golang.org/x/tools/internal/robustio/robustio_windows.go b/vendor/golang.org/x/tools/internal/robustio/robustio_windows.go
new file mode 100644
index 0000000..616c328
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/robustio/robustio_windows.go
@@ -0,0 +1,51 @@
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package robustio
+
+import (
+	"errors"
+	"syscall"
+	"time"
+)
+
+const errFileNotFound = syscall.ERROR_FILE_NOT_FOUND
+
+// isEphemeralError returns true if err may be resolved by waiting.
+func isEphemeralError(err error) bool {
+	var errno syscall.Errno
+	if errors.As(err, &errno) {
+		switch errno {
+		case syscall.ERROR_ACCESS_DENIED,
+			syscall.ERROR_FILE_NOT_FOUND,
+			ERROR_SHARING_VIOLATION:
+			return true
+		}
+	}
+	return false
+}
+
+// Note: it may be convenient to have this helper return fs.FileInfo, but
+// implementing this is actually quite involved on Windows. Since we only
+// currently use mtime, keep it simple.
+func getFileID(filename string) (FileID, time.Time, error) {
+	filename16, err := syscall.UTF16PtrFromString(filename)
+	if err != nil {
+		return FileID{}, time.Time{}, err
+	}
+	h, err := syscall.CreateFile(filename16, 0, 0, nil, syscall.OPEN_EXISTING, uint32(syscall.FILE_FLAG_BACKUP_SEMANTICS), 0)
+	if err != nil {
+		return FileID{}, time.Time{}, err
+	}
+	defer syscall.CloseHandle(h)
+	var i syscall.ByHandleFileInformation
+	if err := syscall.GetFileInformationByHandle(h, &i); err != nil {
+		return FileID{}, time.Time{}, err
+	}
+	mtime := time.Unix(0, i.LastWriteTime.Nanoseconds())
+	return FileID{
+		device: uint64(i.VolumeSerialNumber),
+		inode:  uint64(i.FileIndexHigh)<<32 | uint64(i.FileIndexLow),
+	}, mtime, nil
+}
diff --git a/vendor/golang.org/x/tools/internal/tokeninternal/tokeninternal.go b/vendor/golang.org/x/tools/internal/tokeninternal/tokeninternal.go
new file mode 100644
index 0000000..a3fb2d4
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/tokeninternal/tokeninternal.go
@@ -0,0 +1,59 @@
+// Copyright 2023 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// package tokeninternal provides access to some internal features of the token
+// package.
+package tokeninternal
+
+import (
+	"go/token"
+	"sync"
+	"unsafe"
+)
+
+// GetLines returns the table of line-start offsets from a token.File.
+func GetLines(file *token.File) []int {
+	// token.File has a Lines method on Go 1.21 and later.
+	if file, ok := (interface{})(file).(interface{ Lines() []int }); ok {
+		return file.Lines()
+	}
+
+	// This declaration must match that of token.File.
+	// This creates a risk of dependency skew.
+	// For now we check that the size of the two
+	// declarations is the same, on the (fragile) assumption
+	// that future changes would add fields.
+	type tokenFile119 struct {
+		_     string
+		_     int
+		_     int
+		mu    sync.Mutex // we're not complete monsters
+		lines []int
+		_     []struct{}
+	}
+	type tokenFile118 struct {
+		_ *token.FileSet // deleted in go1.19
+		tokenFile119
+	}
+
+	type uP = unsafe.Pointer
+	switch unsafe.Sizeof(*file) {
+	case unsafe.Sizeof(tokenFile118{}):
+		var ptr *tokenFile118
+		*(*uP)(uP(&ptr)) = uP(file)
+		ptr.mu.Lock()
+		defer ptr.mu.Unlock()
+		return ptr.lines
+
+	case unsafe.Sizeof(tokenFile119{}):
+		var ptr *tokenFile119
+		*(*uP)(uP(&ptr)) = uP(file)
+		ptr.mu.Lock()
+		defer ptr.mu.Unlock()
+		return ptr.lines
+
+	default:
+		panic("unexpected token.File size")
+	}
+}
diff --git a/vendor/golang.org/x/tools/internal/typeparams/common.go b/vendor/golang.org/x/tools/internal/typeparams/common.go
new file mode 100644
index 0000000..cfba818
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/typeparams/common.go
@@ -0,0 +1,178 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package typeparams contains common utilities for writing tools that interact
+// with generic Go code, as introduced with Go 1.18.
+//
+// Many of the types and functions in this package are proxies for the new APIs
+// introduced in the standard library with Go 1.18. For example, the
+// typeparams.Union type is an alias for go/types.Union, and the ForTypeSpec
+// function returns the value of the go/ast.TypeSpec.TypeParams field. At Go
+// versions older than 1.18 these helpers are implemented as stubs, allowing
+// users of this package to write code that handles generic constructs inline,
+// even if the Go version being used to compile does not support generics.
+//
+// Additionally, this package contains common utilities for working with the
+// new generic constructs, to supplement the standard library APIs. Notably,
+// the StructuralTerms API computes a minimal representation of the structural
+// restrictions on a type parameter.
+//
+// An external version of these APIs is available in the
+// golang.org/x/exp/typeparams module.
+package typeparams
+
+import (
+	"go/ast"
+	"go/token"
+	"go/types"
+)
+
+// UnpackIndexExpr extracts data from AST nodes that represent index
+// expressions.
+//
+// For an ast.IndexExpr, the resulting indices slice will contain exactly one
+// index expression. For an ast.IndexListExpr (go1.18+), it may have a variable
+// number of index expressions.
+//
+// For nodes that don't represent index expressions, the first return value of
+// UnpackIndexExpr will be nil.
+func UnpackIndexExpr(n ast.Node) (x ast.Expr, lbrack token.Pos, indices []ast.Expr, rbrack token.Pos) {
+	switch e := n.(type) {
+	case *ast.IndexExpr:
+		return e.X, e.Lbrack, []ast.Expr{e.Index}, e.Rbrack
+	case *IndexListExpr:
+		return e.X, e.Lbrack, e.Indices, e.Rbrack
+	}
+	return nil, token.NoPos, nil, token.NoPos
+}
+
+// PackIndexExpr returns an *ast.IndexExpr or *ast.IndexListExpr, depending on
+// the cardinality of indices. Calling PackIndexExpr with len(indices) == 0
+// will panic.
+func PackIndexExpr(x ast.Expr, lbrack token.Pos, indices []ast.Expr, rbrack token.Pos) ast.Expr {
+	switch len(indices) {
+	case 0:
+		panic("empty indices")
+	case 1:
+		return &ast.IndexExpr{
+			X:      x,
+			Lbrack: lbrack,
+			Index:  indices[0],
+			Rbrack: rbrack,
+		}
+	default:
+		return &IndexListExpr{
+			X:       x,
+			Lbrack:  lbrack,
+			Indices: indices,
+			Rbrack:  rbrack,
+		}
+	}
+}
+
+// IsTypeParam reports whether t is a type parameter.
+func IsTypeParam(t types.Type) bool {
+	_, ok := t.(*TypeParam)
+	return ok
+}
+
+// OriginMethod returns the origin method associated with the method fn.
+// For methods on a non-generic receiver base type, this is just
+// fn. However, for methods with a generic receiver, OriginMethod returns the
+// corresponding method in the method set of the origin type.
+//
+// As a special case, if fn is not a method (has no receiver), OriginMethod
+// returns fn.
+func OriginMethod(fn *types.Func) *types.Func {
+	recv := fn.Type().(*types.Signature).Recv()
+	if recv == nil {
+		return fn
+	}
+	base := recv.Type()
+	p, isPtr := base.(*types.Pointer)
+	if isPtr {
+		base = p.Elem()
+	}
+	named, isNamed := base.(*types.Named)
+	if !isNamed {
+		// Receiver is a *types.Interface.
+		return fn
+	}
+	if ForNamed(named).Len() == 0 {
+		// Receiver base has no type parameters, so we can avoid the lookup below.
+		return fn
+	}
+	orig := NamedTypeOrigin(named)
+	gfn, _, _ := types.LookupFieldOrMethod(orig, true, fn.Pkg(), fn.Name())
+	return gfn.(*types.Func)
+}
+
+// GenericAssignableTo is a generalization of types.AssignableTo that
+// implements the following rule for uninstantiated generic types:
+//
+// If V and T are generic named types, then V is considered assignable to T if,
+// for every possible instantation of V[A_1, ..., A_N], the instantiation
+// T[A_1, ..., A_N] is valid and V[A_1, ..., A_N] implements T[A_1, ..., A_N].
+//
+// If T has structural constraints, they must be satisfied by V.
+//
+// For example, consider the following type declarations:
+//
+//	type Interface[T any] interface {
+//		Accept(T)
+//	}
+//
+//	type Container[T any] struct {
+//		Element T
+//	}
+//
+//	func (c Container[T]) Accept(t T) { c.Element = t }
+//
+// In this case, GenericAssignableTo reports that instantiations of Container
+// are assignable to the corresponding instantiation of Interface.
+func GenericAssignableTo(ctxt *Context, V, T types.Type) bool {
+	// If V and T are not both named, or do not have matching non-empty type
+	// parameter lists, fall back on types.AssignableTo.
+
+	VN, Vnamed := V.(*types.Named)
+	TN, Tnamed := T.(*types.Named)
+	if !Vnamed || !Tnamed {
+		return types.AssignableTo(V, T)
+	}
+
+	vtparams := ForNamed(VN)
+	ttparams := ForNamed(TN)
+	if vtparams.Len() == 0 || vtparams.Len() != ttparams.Len() || NamedTypeArgs(VN).Len() != 0 || NamedTypeArgs(TN).Len() != 0 {
+		return types.AssignableTo(V, T)
+	}
+
+	// V and T have the same (non-zero) number of type params. Instantiate both
+	// with the type parameters of V. This must always succeed for V, and will
+	// succeed for T if and only if the type set of each type parameter of V is a
+	// subset of the type set of the corresponding type parameter of T, meaning
+	// that every instantiation of V corresponds to a valid instantiation of T.
+
+	// Minor optimization: ensure we share a context across the two
+	// instantiations below.
+	if ctxt == nil {
+		ctxt = NewContext()
+	}
+
+	var targs []types.Type
+	for i := 0; i < vtparams.Len(); i++ {
+		targs = append(targs, vtparams.At(i))
+	}
+
+	vinst, err := Instantiate(ctxt, V, targs, true)
+	if err != nil {
+		panic("type parameters should satisfy their own constraints")
+	}
+
+	tinst, err := Instantiate(ctxt, T, targs, true)
+	if err != nil {
+		return false
+	}
+
+	return types.AssignableTo(vinst, tinst)
+}
diff --git a/vendor/golang.org/x/tools/internal/typeparams/coretype.go b/vendor/golang.org/x/tools/internal/typeparams/coretype.go
new file mode 100644
index 0000000..993135e
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/typeparams/coretype.go
@@ -0,0 +1,122 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package typeparams
+
+import (
+	"go/types"
+)
+
+// CoreType returns the core type of T or nil if T does not have a core type.
+//
+// See https://go.dev/ref/spec#Core_types for the definition of a core type.
+func CoreType(T types.Type) types.Type {
+	U := T.Underlying()
+	if _, ok := U.(*types.Interface); !ok {
+		return U // for non-interface types,
+	}
+
+	terms, err := _NormalTerms(U)
+	if len(terms) == 0 || err != nil {
+		// len(terms) -> empty type set of interface.
+		// err != nil => U is invalid, exceeds complexity bounds, or has an empty type set.
+		return nil // no core type.
+	}
+
+	U = terms[0].Type().Underlying()
+	var identical int // i in [0,identical) => Identical(U, terms[i].Type().Underlying())
+	for identical = 1; identical < len(terms); identical++ {
+		if !types.Identical(U, terms[identical].Type().Underlying()) {
+			break
+		}
+	}
+
+	if identical == len(terms) {
+		// https://go.dev/ref/spec#Core_types
+		// "There is a single type U which is the underlying type of all types in the type set of T"
+		return U
+	}
+	ch, ok := U.(*types.Chan)
+	if !ok {
+		return nil // no core type as identical < len(terms) and U is not a channel.
+	}
+	// https://go.dev/ref/spec#Core_types
+	// "the type chan E if T contains only bidirectional channels, or the type chan<- E or
+	// <-chan E depending on the direction of the directional channels present."
+	for chans := identical; chans < len(terms); chans++ {
+		curr, ok := terms[chans].Type().Underlying().(*types.Chan)
+		if !ok {
+			return nil
+		}
+		if !types.Identical(ch.Elem(), curr.Elem()) {
+			return nil // channel elements are not identical.
+		}
+		if ch.Dir() == types.SendRecv {
+			// ch is bidirectional. We can safely always use curr's direction.
+			ch = curr
+		} else if curr.Dir() != types.SendRecv && ch.Dir() != curr.Dir() {
+			// ch and curr are not bidirectional and not the same direction.
+			return nil
+		}
+	}
+	return ch
+}
+
+// _NormalTerms returns a slice of terms representing the normalized structural
+// type restrictions of a type, if any.
+//
+// For all types other than *types.TypeParam, *types.Interface, and
+// *types.Union, this is just a single term with Tilde() == false and
+// Type() == typ. For *types.TypeParam, *types.Interface, and *types.Union, see
+// below.
+//
+// Structural type restrictions of a type parameter are created via
+// non-interface types embedded in its constraint interface (directly, or via a
+// chain of interface embeddings). For example, in the declaration type
+// T[P interface{~int; m()}] int the structural restriction of the type
+// parameter P is ~int.
+//
+// With interface embedding and unions, the specification of structural type
+// restrictions may be arbitrarily complex. For example, consider the
+// following:
+//
+//  type A interface{ ~string|~[]byte }
+//
+//  type B interface{ int|string }
+//
+//  type C interface { ~string|~int }
+//
+//  type T[P interface{ A|B; C }] int
+//
+// In this example, the structural type restriction of P is ~string|int: A|B
+// expands to ~string|~[]byte|int|string, which reduces to ~string|~[]byte|int,
+// which when intersected with C (~string|~int) yields ~string|int.
+//
+// _NormalTerms computes these expansions and reductions, producing a
+// "normalized" form of the embeddings. A structural restriction is normalized
+// if it is a single union containing no interface terms, and is minimal in the
+// sense that removing any term changes the set of types satisfying the
+// constraint. It is left as a proof for the reader that, modulo sorting, there
+// is exactly one such normalized form.
+//
+// Because the minimal representation always takes this form, _NormalTerms
+// returns a slice of tilde terms corresponding to the terms of the union in
+// the normalized structural restriction. An error is returned if the type is
+// invalid, exceeds complexity bounds, or has an empty type set. In the latter
+// case, _NormalTerms returns ErrEmptyTypeSet.
+//
+// _NormalTerms makes no guarantees about the order of terms, except that it
+// is deterministic.
+func _NormalTerms(typ types.Type) ([]*Term, error) {
+	switch typ := typ.(type) {
+	case *TypeParam:
+		return StructuralTerms(typ)
+	case *Union:
+		return UnionTermSet(typ)
+	case *types.Interface:
+		return InterfaceTermSet(typ)
+	default:
+		return []*Term{NewTerm(false, typ)}, nil
+	}
+}
diff --git a/vendor/golang.org/x/tools/internal/typeparams/enabled_go117.go b/vendor/golang.org/x/tools/internal/typeparams/enabled_go117.go
new file mode 100644
index 0000000..1821239
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/typeparams/enabled_go117.go
@@ -0,0 +1,12 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build !go1.18
+// +build !go1.18
+
+package typeparams
+
+// Enabled reports whether type parameters are enabled in the current build
+// environment.
+const Enabled = false
diff --git a/vendor/golang.org/x/tools/internal/typeparams/enabled_go118.go b/vendor/golang.org/x/tools/internal/typeparams/enabled_go118.go
new file mode 100644
index 0000000..d671488
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/typeparams/enabled_go118.go
@@ -0,0 +1,15 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build go1.18
+// +build go1.18
+
+package typeparams
+
+// Note: this constant is in a separate file as this is the only acceptable
+// diff between the <1.18 API of this package and the 1.18 API.
+
+// Enabled reports whether type parameters are enabled in the current build
+// environment.
+const Enabled = true
diff --git a/vendor/golang.org/x/tools/internal/typeparams/normalize.go b/vendor/golang.org/x/tools/internal/typeparams/normalize.go
new file mode 100644
index 0000000..9c631b6
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/typeparams/normalize.go
@@ -0,0 +1,218 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package typeparams
+
+import (
+	"errors"
+	"fmt"
+	"go/types"
+	"os"
+	"strings"
+)
+
+//go:generate go run copytermlist.go
+
+const debug = false
+
+var ErrEmptyTypeSet = errors.New("empty type set")
+
+// StructuralTerms returns a slice of terms representing the normalized
+// structural type restrictions of a type parameter, if any.
+//
+// Structural type restrictions of a type parameter are created via
+// non-interface types embedded in its constraint interface (directly, or via a
+// chain of interface embeddings). For example, in the declaration
+//
+//	type T[P interface{~int; m()}] int
+//
+// the structural restriction of the type parameter P is ~int.
+//
+// With interface embedding and unions, the specification of structural type
+// restrictions may be arbitrarily complex. For example, consider the
+// following:
+//
+//	type A interface{ ~string|~[]byte }
+//
+//	type B interface{ int|string }
+//
+//	type C interface { ~string|~int }
+//
+//	type T[P interface{ A|B; C }] int
+//
+// In this example, the structural type restriction of P is ~string|int: A|B
+// expands to ~string|~[]byte|int|string, which reduces to ~string|~[]byte|int,
+// which when intersected with C (~string|~int) yields ~string|int.
+//
+// StructuralTerms computes these expansions and reductions, producing a
+// "normalized" form of the embeddings. A structural restriction is normalized
+// if it is a single union containing no interface terms, and is minimal in the
+// sense that removing any term changes the set of types satisfying the
+// constraint. It is left as a proof for the reader that, modulo sorting, there
+// is exactly one such normalized form.
+//
+// Because the minimal representation always takes this form, StructuralTerms
+// returns a slice of tilde terms corresponding to the terms of the union in
+// the normalized structural restriction. An error is returned if the
+// constraint interface is invalid, exceeds complexity bounds, or has an empty
+// type set. In the latter case, StructuralTerms returns ErrEmptyTypeSet.
+//
+// StructuralTerms makes no guarantees about the order of terms, except that it
+// is deterministic.
+func StructuralTerms(tparam *TypeParam) ([]*Term, error) {
+	constraint := tparam.Constraint()
+	if constraint == nil {
+		return nil, fmt.Errorf("%s has nil constraint", tparam)
+	}
+	iface, _ := constraint.Underlying().(*types.Interface)
+	if iface == nil {
+		return nil, fmt.Errorf("constraint is %T, not *types.Interface", constraint.Underlying())
+	}
+	return InterfaceTermSet(iface)
+}
+
+// InterfaceTermSet computes the normalized terms for a constraint interface,
+// returning an error if the term set cannot be computed or is empty. In the
+// latter case, the error will be ErrEmptyTypeSet.
+//
+// See the documentation of StructuralTerms for more information on
+// normalization.
+func InterfaceTermSet(iface *types.Interface) ([]*Term, error) {
+	return computeTermSet(iface)
+}
+
+// UnionTermSet computes the normalized terms for a union, returning an error
+// if the term set cannot be computed or is empty. In the latter case, the
+// error will be ErrEmptyTypeSet.
+//
+// See the documentation of StructuralTerms for more information on
+// normalization.
+func UnionTermSet(union *Union) ([]*Term, error) {
+	return computeTermSet(union)
+}
+
+func computeTermSet(typ types.Type) ([]*Term, error) {
+	tset, err := computeTermSetInternal(typ, make(map[types.Type]*termSet), 0)
+	if err != nil {
+		return nil, err
+	}
+	if tset.terms.isEmpty() {
+		return nil, ErrEmptyTypeSet
+	}
+	if tset.terms.isAll() {
+		return nil, nil
+	}
+	var terms []*Term
+	for _, term := range tset.terms {
+		terms = append(terms, NewTerm(term.tilde, term.typ))
+	}
+	return terms, nil
+}
+
+// A termSet holds the normalized set of terms for a given type.
+//
+// The name termSet is intentionally distinct from 'type set': a type set is
+// all types that implement a type (and includes method restrictions), whereas
+// a term set just represents the structural restrictions on a type.
+type termSet struct {
+	complete bool
+	terms    termlist
+}
+
+func indentf(depth int, format string, args ...interface{}) {
+	fmt.Fprintf(os.Stderr, strings.Repeat(".", depth)+format+"\n", args...)
+}
+
+func computeTermSetInternal(t types.Type, seen map[types.Type]*termSet, depth int) (res *termSet, err error) {
+	if t == nil {
+		panic("nil type")
+	}
+
+	if debug {
+		indentf(depth, "%s", t.String())
+		defer func() {
+			if err != nil {
+				indentf(depth, "=> %s", err)
+			} else {
+				indentf(depth, "=> %s", res.terms.String())
+			}
+		}()
+	}
+
+	const maxTermCount = 100
+	if tset, ok := seen[t]; ok {
+		if !tset.complete {
+			return nil, fmt.Errorf("cycle detected in the declaration of %s", t)
+		}
+		return tset, nil
+	}
+
+	// Mark the current type as seen to avoid infinite recursion.
+	tset := new(termSet)
+	defer func() {
+		tset.complete = true
+	}()
+	seen[t] = tset
+
+	switch u := t.Underlying().(type) {
+	case *types.Interface:
+		// The term set of an interface is the intersection of the term sets of its
+		// embedded types.
+		tset.terms = allTermlist
+		for i := 0; i < u.NumEmbeddeds(); i++ {
+			embedded := u.EmbeddedType(i)
+			if _, ok := embedded.Underlying().(*TypeParam); ok {
+				return nil, fmt.Errorf("invalid embedded type %T", embedded)
+			}
+			tset2, err := computeTermSetInternal(embedded, seen, depth+1)
+			if err != nil {
+				return nil, err
+			}
+			tset.terms = tset.terms.intersect(tset2.terms)
+		}
+	case *Union:
+		// The term set of a union is the union of term sets of its terms.
+		tset.terms = nil
+		for i := 0; i < u.Len(); i++ {
+			t := u.Term(i)
+			var terms termlist
+			switch t.Type().Underlying().(type) {
+			case *types.Interface:
+				tset2, err := computeTermSetInternal(t.Type(), seen, depth+1)
+				if err != nil {
+					return nil, err
+				}
+				terms = tset2.terms
+			case *TypeParam, *Union:
+				// A stand-alone type parameter or union is not permitted as union
+				// term.
+				return nil, fmt.Errorf("invalid union term %T", t)
+			default:
+				if t.Type() == types.Typ[types.Invalid] {
+					continue
+				}
+				terms = termlist{{t.Tilde(), t.Type()}}
+			}
+			tset.terms = tset.terms.union(terms)
+			if len(tset.terms) > maxTermCount {
+				return nil, fmt.Errorf("exceeded max term count %d", maxTermCount)
+			}
+		}
+	case *TypeParam:
+		panic("unreachable")
+	default:
+		// For all other types, the term set is just a single non-tilde term
+		// holding the type itself.
+		if u != types.Typ[types.Invalid] {
+			tset.terms = termlist{{false, t}}
+		}
+	}
+	return tset, nil
+}
+
+// under is a facade for the go/types internal function of the same name. It is
+// used by typeterm.go.
+func under(t types.Type) types.Type {
+	return t.Underlying()
+}
diff --git a/vendor/golang.org/x/tools/internal/typeparams/termlist.go b/vendor/golang.org/x/tools/internal/typeparams/termlist.go
new file mode 100644
index 0000000..933106a
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/typeparams/termlist.go
@@ -0,0 +1,163 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Code generated by copytermlist.go DO NOT EDIT.
+
+package typeparams
+
+import (
+	"bytes"
+	"go/types"
+)
+
+// A termlist represents the type set represented by the union
+// t1 ∪ y2 ∪ ... tn of the type sets of the terms t1 to tn.
+// A termlist is in normal form if all terms are disjoint.
+// termlist operations don't require the operands to be in
+// normal form.
+type termlist []*term
+
+// allTermlist represents the set of all types.
+// It is in normal form.
+var allTermlist = termlist{new(term)}
+
+// String prints the termlist exactly (without normalization).
+func (xl termlist) String() string {
+	if len(xl) == 0 {
+		return "∅"
+	}
+	var buf bytes.Buffer
+	for i, x := range xl {
+		if i > 0 {
+			buf.WriteString(" ∪ ")
+		}
+		buf.WriteString(x.String())
+	}
+	return buf.String()
+}
+
+// isEmpty reports whether the termlist xl represents the empty set of types.
+func (xl termlist) isEmpty() bool {
+	// If there's a non-nil term, the entire list is not empty.
+	// If the termlist is in normal form, this requires at most
+	// one iteration.
+	for _, x := range xl {
+		if x != nil {
+			return false
+		}
+	}
+	return true
+}
+
+// isAll reports whether the termlist xl represents the set of all types.
+func (xl termlist) isAll() bool {
+	// If there's a 𝓤 term, the entire list is 𝓤.
+	// If the termlist is in normal form, this requires at most
+	// one iteration.
+	for _, x := range xl {
+		if x != nil && x.typ == nil {
+			return true
+		}
+	}
+	return false
+}
+
+// norm returns the normal form of xl.
+func (xl termlist) norm() termlist {
+	// Quadratic algorithm, but good enough for now.
+	// TODO(gri) fix asymptotic performance
+	used := make([]bool, len(xl))
+	var rl termlist
+	for i, xi := range xl {
+		if xi == nil || used[i] {
+			continue
+		}
+		for j := i + 1; j < len(xl); j++ {
+			xj := xl[j]
+			if xj == nil || used[j] {
+				continue
+			}
+			if u1, u2 := xi.union(xj); u2 == nil {
+				// If we encounter a 𝓤 term, the entire list is 𝓤.
+				// Exit early.
+				// (Note that this is not just an optimization;
+				// if we continue, we may end up with a 𝓤 term
+				// and other terms and the result would not be
+				// in normal form.)
+				if u1.typ == nil {
+					return allTermlist
+				}
+				xi = u1
+				used[j] = true // xj is now unioned into xi - ignore it in future iterations
+			}
+		}
+		rl = append(rl, xi)
+	}
+	return rl
+}
+
+// union returns the union xl ∪ yl.
+func (xl termlist) union(yl termlist) termlist {
+	return append(xl, yl...).norm()
+}
+
+// intersect returns the intersection xl ∩ yl.
+func (xl termlist) intersect(yl termlist) termlist {
+	if xl.isEmpty() || yl.isEmpty() {
+		return nil
+	}
+
+	// Quadratic algorithm, but good enough for now.
+	// TODO(gri) fix asymptotic performance
+	var rl termlist
+	for _, x := range xl {
+		for _, y := range yl {
+			if r := x.intersect(y); r != nil {
+				rl = append(rl, r)
+			}
+		}
+	}
+	return rl.norm()
+}
+
+// equal reports whether xl and yl represent the same type set.
+func (xl termlist) equal(yl termlist) bool {
+	// TODO(gri) this should be more efficient
+	return xl.subsetOf(yl) && yl.subsetOf(xl)
+}
+
+// includes reports whether t ∈ xl.
+func (xl termlist) includes(t types.Type) bool {
+	for _, x := range xl {
+		if x.includes(t) {
+			return true
+		}
+	}
+	return false
+}
+
+// supersetOf reports whether y ⊆ xl.
+func (xl termlist) supersetOf(y *term) bool {
+	for _, x := range xl {
+		if y.subsetOf(x) {
+			return true
+		}
+	}
+	return false
+}
+
+// subsetOf reports whether xl ⊆ yl.
+func (xl termlist) subsetOf(yl termlist) bool {
+	if yl.isEmpty() {
+		return xl.isEmpty()
+	}
+
+	// each term x of xl must be a subset of yl
+	for _, x := range xl {
+		if !yl.supersetOf(x) {
+			return false // x is not a subset yl
+		}
+	}
+	return true
+}
diff --git a/vendor/golang.org/x/tools/internal/typeparams/typeparams_go117.go b/vendor/golang.org/x/tools/internal/typeparams/typeparams_go117.go
new file mode 100644
index 0000000..b478897
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/typeparams/typeparams_go117.go
@@ -0,0 +1,197 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build !go1.18
+// +build !go1.18
+
+package typeparams
+
+import (
+	"go/ast"
+	"go/token"
+	"go/types"
+)
+
+func unsupported() {
+	panic("type parameters are unsupported at this go version")
+}
+
+// IndexListExpr is a placeholder type, as type parameters are not supported at
+// this Go version. Its methods panic on use.
+type IndexListExpr struct {
+	ast.Expr
+	X       ast.Expr   // expression
+	Lbrack  token.Pos  // position of "["
+	Indices []ast.Expr // index expressions
+	Rbrack  token.Pos  // position of "]"
+}
+
+// ForTypeSpec returns an empty field list, as type parameters on not supported
+// at this Go version.
+func ForTypeSpec(*ast.TypeSpec) *ast.FieldList {
+	return nil
+}
+
+// ForFuncType returns an empty field list, as type parameters are not
+// supported at this Go version.
+func ForFuncType(*ast.FuncType) *ast.FieldList {
+	return nil
+}
+
+// TypeParam is a placeholder type, as type parameters are not supported at
+// this Go version. Its methods panic on use.
+type TypeParam struct{ types.Type }
+
+func (*TypeParam) Index() int             { unsupported(); return 0 }
+func (*TypeParam) Constraint() types.Type { unsupported(); return nil }
+func (*TypeParam) Obj() *types.TypeName   { unsupported(); return nil }
+
+// TypeParamList is a placeholder for an empty type parameter list.
+type TypeParamList struct{}
+
+func (*TypeParamList) Len() int          { return 0 }
+func (*TypeParamList) At(int) *TypeParam { unsupported(); return nil }
+
+// TypeList is a placeholder for an empty type list.
+type TypeList struct{}
+
+func (*TypeList) Len() int          { return 0 }
+func (*TypeList) At(int) types.Type { unsupported(); return nil }
+
+// NewTypeParam is unsupported at this Go version, and panics.
+func NewTypeParam(name *types.TypeName, constraint types.Type) *TypeParam {
+	unsupported()
+	return nil
+}
+
+// SetTypeParamConstraint is unsupported at this Go version, and panics.
+func SetTypeParamConstraint(tparam *TypeParam, constraint types.Type) {
+	unsupported()
+}
+
+// NewSignatureType calls types.NewSignature, panicking if recvTypeParams or
+// typeParams is non-empty.
+func NewSignatureType(recv *types.Var, recvTypeParams, typeParams []*TypeParam, params, results *types.Tuple, variadic bool) *types.Signature {
+	if len(recvTypeParams) != 0 || len(typeParams) != 0 {
+		panic("signatures cannot have type parameters at this Go version")
+	}
+	return types.NewSignature(recv, params, results, variadic)
+}
+
+// ForSignature returns an empty slice.
+func ForSignature(*types.Signature) *TypeParamList {
+	return nil
+}
+
+// RecvTypeParams returns a nil slice.
+func RecvTypeParams(sig *types.Signature) *TypeParamList {
+	return nil
+}
+
+// IsComparable returns false, as no interfaces are type-restricted at this Go
+// version.
+func IsComparable(*types.Interface) bool {
+	return false
+}
+
+// IsMethodSet returns true, as no interfaces are type-restricted at this Go
+// version.
+func IsMethodSet(*types.Interface) bool {
+	return true
+}
+
+// IsImplicit returns false, as no interfaces are implicit at this Go version.
+func IsImplicit(*types.Interface) bool {
+	return false
+}
+
+// MarkImplicit does nothing, because this Go version does not have implicit
+// interfaces.
+func MarkImplicit(*types.Interface) {}
+
+// ForNamed returns an empty type parameter list, as type parameters are not
+// supported at this Go version.
+func ForNamed(*types.Named) *TypeParamList {
+	return nil
+}
+
+// SetForNamed panics if tparams is non-empty.
+func SetForNamed(_ *types.Named, tparams []*TypeParam) {
+	if len(tparams) > 0 {
+		unsupported()
+	}
+}
+
+// NamedTypeArgs returns nil.
+func NamedTypeArgs(*types.Named) *TypeList {
+	return nil
+}
+
+// NamedTypeOrigin is the identity method at this Go version.
+func NamedTypeOrigin(named *types.Named) types.Type {
+	return named
+}
+
+// Term holds information about a structural type restriction.
+type Term struct {
+	tilde bool
+	typ   types.Type
+}
+
+func (m *Term) Tilde() bool      { return m.tilde }
+func (m *Term) Type() types.Type { return m.typ }
+func (m *Term) String() string {
+	pre := ""
+	if m.tilde {
+		pre = "~"
+	}
+	return pre + m.typ.String()
+}
+
+// NewTerm is unsupported at this Go version, and panics.
+func NewTerm(tilde bool, typ types.Type) *Term {
+	return &Term{tilde, typ}
+}
+
+// Union is a placeholder type, as type parameters are not supported at this Go
+// version. Its methods panic on use.
+type Union struct{ types.Type }
+
+func (*Union) Len() int         { return 0 }
+func (*Union) Term(i int) *Term { unsupported(); return nil }
+
+// NewUnion is unsupported at this Go version, and panics.
+func NewUnion(terms []*Term) *Union {
+	unsupported()
+	return nil
+}
+
+// InitInstanceInfo is a noop at this Go version.
+func InitInstanceInfo(*types.Info) {}
+
+// Instance is a placeholder type, as type parameters are not supported at this
+// Go version.
+type Instance struct {
+	TypeArgs *TypeList
+	Type     types.Type
+}
+
+// GetInstances returns a nil map, as type parameters are not supported at this
+// Go version.
+func GetInstances(info *types.Info) map[*ast.Ident]Instance { return nil }
+
+// Context is a placeholder type, as type parameters are not supported at
+// this Go version.
+type Context struct{}
+
+// NewContext returns a placeholder Context instance.
+func NewContext() *Context {
+	return &Context{}
+}
+
+// Instantiate is unsupported on this Go version, and panics.
+func Instantiate(ctxt *Context, typ types.Type, targs []types.Type, validate bool) (types.Type, error) {
+	unsupported()
+	return nil, nil
+}
diff --git a/vendor/golang.org/x/tools/internal/typeparams/typeparams_go118.go b/vendor/golang.org/x/tools/internal/typeparams/typeparams_go118.go
new file mode 100644
index 0000000..114a36b
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/typeparams/typeparams_go118.go
@@ -0,0 +1,151 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build go1.18
+// +build go1.18
+
+package typeparams
+
+import (
+	"go/ast"
+	"go/types"
+)
+
+// IndexListExpr is an alias for ast.IndexListExpr.
+type IndexListExpr = ast.IndexListExpr
+
+// ForTypeSpec returns n.TypeParams.
+func ForTypeSpec(n *ast.TypeSpec) *ast.FieldList {
+	if n == nil {
+		return nil
+	}
+	return n.TypeParams
+}
+
+// ForFuncType returns n.TypeParams.
+func ForFuncType(n *ast.FuncType) *ast.FieldList {
+	if n == nil {
+		return nil
+	}
+	return n.TypeParams
+}
+
+// TypeParam is an alias for types.TypeParam
+type TypeParam = types.TypeParam
+
+// TypeParamList is an alias for types.TypeParamList
+type TypeParamList = types.TypeParamList
+
+// TypeList is an alias for types.TypeList
+type TypeList = types.TypeList
+
+// NewTypeParam calls types.NewTypeParam.
+func NewTypeParam(name *types.TypeName, constraint types.Type) *TypeParam {
+	return types.NewTypeParam(name, constraint)
+}
+
+// SetTypeParamConstraint calls tparam.SetConstraint(constraint).
+func SetTypeParamConstraint(tparam *TypeParam, constraint types.Type) {
+	tparam.SetConstraint(constraint)
+}
+
+// NewSignatureType calls types.NewSignatureType.
+func NewSignatureType(recv *types.Var, recvTypeParams, typeParams []*TypeParam, params, results *types.Tuple, variadic bool) *types.Signature {
+	return types.NewSignatureType(recv, recvTypeParams, typeParams, params, results, variadic)
+}
+
+// ForSignature returns sig.TypeParams()
+func ForSignature(sig *types.Signature) *TypeParamList {
+	return sig.TypeParams()
+}
+
+// RecvTypeParams returns sig.RecvTypeParams().
+func RecvTypeParams(sig *types.Signature) *TypeParamList {
+	return sig.RecvTypeParams()
+}
+
+// IsComparable calls iface.IsComparable().
+func IsComparable(iface *types.Interface) bool {
+	return iface.IsComparable()
+}
+
+// IsMethodSet calls iface.IsMethodSet().
+func IsMethodSet(iface *types.Interface) bool {
+	return iface.IsMethodSet()
+}
+
+// IsImplicit calls iface.IsImplicit().
+func IsImplicit(iface *types.Interface) bool {
+	return iface.IsImplicit()
+}
+
+// MarkImplicit calls iface.MarkImplicit().
+func MarkImplicit(iface *types.Interface) {
+	iface.MarkImplicit()
+}
+
+// ForNamed extracts the (possibly empty) type parameter object list from
+// named.
+func ForNamed(named *types.Named) *TypeParamList {
+	return named.TypeParams()
+}
+
+// SetForNamed sets the type params tparams on n. Each tparam must be of
+// dynamic type *types.TypeParam.
+func SetForNamed(n *types.Named, tparams []*TypeParam) {
+	n.SetTypeParams(tparams)
+}
+
+// NamedTypeArgs returns named.TypeArgs().
+func NamedTypeArgs(named *types.Named) *TypeList {
+	return named.TypeArgs()
+}
+
+// NamedTypeOrigin returns named.Orig().
+func NamedTypeOrigin(named *types.Named) types.Type {
+	return named.Origin()
+}
+
+// Term is an alias for types.Term.
+type Term = types.Term
+
+// NewTerm calls types.NewTerm.
+func NewTerm(tilde bool, typ types.Type) *Term {
+	return types.NewTerm(tilde, typ)
+}
+
+// Union is an alias for types.Union
+type Union = types.Union
+
+// NewUnion calls types.NewUnion.
+func NewUnion(terms []*Term) *Union {
+	return types.NewUnion(terms)
+}
+
+// InitInstanceInfo initializes info to record information about type and
+// function instances.
+func InitInstanceInfo(info *types.Info) {
+	info.Instances = make(map[*ast.Ident]types.Instance)
+}
+
+// Instance is an alias for types.Instance.
+type Instance = types.Instance
+
+// GetInstances returns info.Instances.
+func GetInstances(info *types.Info) map[*ast.Ident]Instance {
+	return info.Instances
+}
+
+// Context is an alias for types.Context.
+type Context = types.Context
+
+// NewContext calls types.NewContext.
+func NewContext() *Context {
+	return types.NewContext()
+}
+
+// Instantiate calls types.Instantiate.
+func Instantiate(ctxt *Context, typ types.Type, targs []types.Type, validate bool) (types.Type, error) {
+	return types.Instantiate(ctxt, typ, targs, validate)
+}
diff --git a/vendor/golang.org/x/tools/internal/typeparams/typeterm.go b/vendor/golang.org/x/tools/internal/typeparams/typeterm.go
new file mode 100644
index 0000000..7ddee28
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/typeparams/typeterm.go
@@ -0,0 +1,170 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Code generated by copytermlist.go DO NOT EDIT.
+
+package typeparams
+
+import "go/types"
+
+// A term describes elementary type sets:
+//
+//   ∅:  (*term)(nil)     == ∅                      // set of no types (empty set)
+//   𝓤:  &term{}          == 𝓤                      // set of all types (𝓤niverse)
+//   T:  &term{false, T}  == {T}                    // set of type T
+//  ~t:  &term{true, t}   == {t' | under(t') == t}  // set of types with underlying type t
+//
+type term struct {
+	tilde bool // valid if typ != nil
+	typ   types.Type
+}
+
+func (x *term) String() string {
+	switch {
+	case x == nil:
+		return "∅"
+	case x.typ == nil:
+		return "𝓤"
+	case x.tilde:
+		return "~" + x.typ.String()
+	default:
+		return x.typ.String()
+	}
+}
+
+// equal reports whether x and y represent the same type set.
+func (x *term) equal(y *term) bool {
+	// easy cases
+	switch {
+	case x == nil || y == nil:
+		return x == y
+	case x.typ == nil || y.typ == nil:
+		return x.typ == y.typ
+	}
+	// ∅ ⊂ x, y ⊂ 𝓤
+
+	return x.tilde == y.tilde && types.Identical(x.typ, y.typ)
+}
+
+// union returns the union x ∪ y: zero, one, or two non-nil terms.
+func (x *term) union(y *term) (_, _ *term) {
+	// easy cases
+	switch {
+	case x == nil && y == nil:
+		return nil, nil // ∅ ∪ ∅ == ∅
+	case x == nil:
+		return y, nil // ∅ ∪ y == y
+	case y == nil:
+		return x, nil // x ∪ ∅ == x
+	case x.typ == nil:
+		return x, nil // 𝓤 ∪ y == 𝓤
+	case y.typ == nil:
+		return y, nil // x ∪ 𝓤 == 𝓤
+	}
+	// ∅ ⊂ x, y ⊂ 𝓤
+
+	if x.disjoint(y) {
+		return x, y // x ∪ y == (x, y) if x ∩ y == ∅
+	}
+	// x.typ == y.typ
+
+	// ~t ∪ ~t == ~t
+	// ~t ∪  T == ~t
+	//  T ∪ ~t == ~t
+	//  T ∪  T ==  T
+	if x.tilde || !y.tilde {
+		return x, nil
+	}
+	return y, nil
+}
+
+// intersect returns the intersection x ∩ y.
+func (x *term) intersect(y *term) *term {
+	// easy cases
+	switch {
+	case x == nil || y == nil:
+		return nil // ∅ ∩ y == ∅ and ∩ ∅ == ∅
+	case x.typ == nil:
+		return y // 𝓤 ∩ y == y
+	case y.typ == nil:
+		return x // x ∩ 𝓤 == x
+	}
+	// ∅ ⊂ x, y ⊂ 𝓤
+
+	if x.disjoint(y) {
+		return nil // x ∩ y == ∅ if x ∩ y == ∅
+	}
+	// x.typ == y.typ
+
+	// ~t ∩ ~t == ~t
+	// ~t ∩  T ==  T
+	//  T ∩ ~t ==  T
+	//  T ∩  T ==  T
+	if !x.tilde || y.tilde {
+		return x
+	}
+	return y
+}
+
+// includes reports whether t ∈ x.
+func (x *term) includes(t types.Type) bool {
+	// easy cases
+	switch {
+	case x == nil:
+		return false // t ∈ ∅ == false
+	case x.typ == nil:
+		return true // t ∈ 𝓤 == true
+	}
+	// ∅ ⊂ x ⊂ 𝓤
+
+	u := t
+	if x.tilde {
+		u = under(u)
+	}
+	return types.Identical(x.typ, u)
+}
+
+// subsetOf reports whether x ⊆ y.
+func (x *term) subsetOf(y *term) bool {
+	// easy cases
+	switch {
+	case x == nil:
+		return true // ∅ ⊆ y == true
+	case y == nil:
+		return false // x ⊆ ∅ == false since x != ∅
+	case y.typ == nil:
+		return true // x ⊆ 𝓤 == true
+	case x.typ == nil:
+		return false // 𝓤 ⊆ y == false since y != 𝓤
+	}
+	// ∅ ⊂ x, y ⊂ 𝓤
+
+	if x.disjoint(y) {
+		return false // x ⊆ y == false if x ∩ y == ∅
+	}
+	// x.typ == y.typ
+
+	// ~t ⊆ ~t == true
+	// ~t ⊆ T == false
+	//  T ⊆ ~t == true
+	//  T ⊆  T == true
+	return !x.tilde || y.tilde
+}
+
+// disjoint reports whether x ∩ y == ∅.
+// x.typ and y.typ must not be nil.
+func (x *term) disjoint(y *term) bool {
+	if debug && (x.typ == nil || y.typ == nil) {
+		panic("invalid argument(s)")
+	}
+	ux := x.typ
+	if y.tilde {
+		ux = under(ux)
+	}
+	uy := y.typ
+	if x.tilde {
+		uy = under(uy)
+	}
+	return !types.Identical(ux, uy)
+}
diff --git a/vendor/golang.org/x/tools/internal/typesinternal/errorcode.go b/vendor/golang.org/x/tools/internal/typesinternal/errorcode.go
new file mode 100644
index 0000000..0748407
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/typesinternal/errorcode.go
@@ -0,0 +1,1560 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package typesinternal
+
+//go:generate stringer -type=ErrorCode
+
+type ErrorCode int
+
+// This file defines the error codes that can be produced during type-checking.
+// Collectively, these codes provide an identifier that may be used to
+// implement special handling for certain types of errors.
+//
+// Error codes should be fine-grained enough that the exact nature of the error
+// can be easily determined, but coarse enough that they are not an
+// implementation detail of the type checking algorithm. As a rule-of-thumb,
+// errors should be considered equivalent if there is a theoretical refactoring
+// of the type checker in which they are emitted in exactly one place. For
+// example, the type checker emits different error messages for "too many
+// arguments" and "too few arguments", but one can imagine an alternative type
+// checker where this check instead just emits a single "wrong number of
+// arguments", so these errors should have the same code.
+//
+// Error code names should be as brief as possible while retaining accuracy and
+// distinctiveness. In most cases names should start with an adjective
+// describing the nature of the error (e.g. "invalid", "unused", "misplaced"),
+// and end with a noun identifying the relevant language object. For example,
+// "DuplicateDecl" or "InvalidSliceExpr". For brevity, naming follows the
+// convention that "bad" implies a problem with syntax, and "invalid" implies a
+// problem with types.
+
+const (
+	// InvalidSyntaxTree occurs if an invalid syntax tree is provided
+	// to the type checker. It should never happen.
+	InvalidSyntaxTree ErrorCode = -1
+)
+
+const (
+	_ ErrorCode = iota
+
+	// Test is reserved for errors that only apply while in self-test mode.
+	Test
+
+	/* package names */
+
+	// BlankPkgName occurs when a package name is the blank identifier "_".
+	//
+	// Per the spec:
+	//  "The PackageName must not be the blank identifier."
+	BlankPkgName
+
+	// MismatchedPkgName occurs when a file's package name doesn't match the
+	// package name already established by other files.
+	MismatchedPkgName
+
+	// InvalidPkgUse occurs when a package identifier is used outside of a
+	// selector expression.
+	//
+	// Example:
+	//  import "fmt"
+	//
+	//  var _ = fmt
+	InvalidPkgUse
+
+	/* imports */
+
+	// BadImportPath occurs when an import path is not valid.
+	BadImportPath
+
+	// BrokenImport occurs when importing a package fails.
+	//
+	// Example:
+	//  import "amissingpackage"
+	BrokenImport
+
+	// ImportCRenamed occurs when the special import "C" is renamed. "C" is a
+	// pseudo-package, and must not be renamed.
+	//
+	// Example:
+	//  import _ "C"
+	ImportCRenamed
+
+	// UnusedImport occurs when an import is unused.
+	//
+	// Example:
+	//  import "fmt"
+	//
+	//  func main() {}
+	UnusedImport
+
+	/* initialization */
+
+	// InvalidInitCycle occurs when an invalid cycle is detected within the
+	// initialization graph.
+	//
+	// Example:
+	//  var x int = f()
+	//
+	//  func f() int { return x }
+	InvalidInitCycle
+
+	/* decls */
+
+	// DuplicateDecl occurs when an identifier is declared multiple times.
+	//
+	// Example:
+	//  var x = 1
+	//  var x = 2
+	DuplicateDecl
+
+	// InvalidDeclCycle occurs when a declaration cycle is not valid.
+	//
+	// Example:
+	//  import "unsafe"
+	//
+	//  type T struct {
+	//  	a [n]int
+	//  }
+	//
+	//  var n = unsafe.Sizeof(T{})
+	InvalidDeclCycle
+
+	// InvalidTypeCycle occurs when a cycle in type definitions results in a
+	// type that is not well-defined.
+	//
+	// Example:
+	//  import "unsafe"
+	//
+	//  type T [unsafe.Sizeof(T{})]int
+	InvalidTypeCycle
+
+	/* decls > const */
+
+	// InvalidConstInit occurs when a const declaration has a non-constant
+	// initializer.
+	//
+	// Example:
+	//  var x int
+	//  const _ = x
+	InvalidConstInit
+
+	// InvalidConstVal occurs when a const value cannot be converted to its
+	// target type.
+	//
+	// TODO(findleyr): this error code and example are not very clear. Consider
+	// removing it.
+	//
+	// Example:
+	//  const _ = 1 << "hello"
+	InvalidConstVal
+
+	// InvalidConstType occurs when the underlying type in a const declaration
+	// is not a valid constant type.
+	//
+	// Example:
+	//  const c *int = 4
+	InvalidConstType
+
+	/* decls > var (+ other variable assignment codes) */
+
+	// UntypedNilUse occurs when the predeclared (untyped) value nil is used to
+	// initialize a variable declared without an explicit type.
+	//
+	// Example:
+	//  var x = nil
+	UntypedNilUse
+
+	// WrongAssignCount occurs when the number of values on the right-hand side
+	// of an assignment or or initialization expression does not match the number
+	// of variables on the left-hand side.
+	//
+	// Example:
+	//  var x = 1, 2
+	WrongAssignCount
+
+	// UnassignableOperand occurs when the left-hand side of an assignment is
+	// not assignable.
+	//
+	// Example:
+	//  func f() {
+	//  	const c = 1
+	//  	c = 2
+	//  }
+	UnassignableOperand
+
+	// NoNewVar occurs when a short variable declaration (':=') does not declare
+	// new variables.
+	//
+	// Example:
+	//  func f() {
+	//  	x := 1
+	//  	x := 2
+	//  }
+	NoNewVar
+
+	// MultiValAssignOp occurs when an assignment operation (+=, *=, etc) does
+	// not have single-valued left-hand or right-hand side.
+	//
+	// Per the spec:
+	//  "In assignment operations, both the left- and right-hand expression lists
+	//  must contain exactly one single-valued expression"
+	//
+	// Example:
+	//  func f() int {
+	//  	x, y := 1, 2
+	//  	x, y += 1
+	//  	return x + y
+	//  }
+	MultiValAssignOp
+
+	// InvalidIfaceAssign occurs when a value of type T is used as an
+	// interface, but T does not implement a method of the expected interface.
+	//
+	// Example:
+	//  type I interface {
+	//  	f()
+	//  }
+	//
+	//  type T int
+	//
+	//  var x I = T(1)
+	InvalidIfaceAssign
+
+	// InvalidChanAssign occurs when a chan assignment is invalid.
+	//
+	// Per the spec, a value x is assignable to a channel type T if:
+	//  "x is a bidirectional channel value, T is a channel type, x's type V and
+	//  T have identical element types, and at least one of V or T is not a
+	//  defined type."
+	//
+	// Example:
+	//  type T1 chan int
+	//  type T2 chan int
+	//
+	//  var x T1
+	//  // Invalid assignment because both types are named
+	//  var _ T2 = x
+	InvalidChanAssign
+
+	// IncompatibleAssign occurs when the type of the right-hand side expression
+	// in an assignment cannot be assigned to the type of the variable being
+	// assigned.
+	//
+	// Example:
+	//  var x []int
+	//  var _ int = x
+	IncompatibleAssign
+
+	// UnaddressableFieldAssign occurs when trying to assign to a struct field
+	// in a map value.
+	//
+	// Example:
+	//  func f() {
+	//  	m := make(map[string]struct{i int})
+	//  	m["foo"].i = 42
+	//  }
+	UnaddressableFieldAssign
+
+	/* decls > type (+ other type expression codes) */
+
+	// NotAType occurs when the identifier used as the underlying type in a type
+	// declaration or the right-hand side of a type alias does not denote a type.
+	//
+	// Example:
+	//  var S = 2
+	//
+	//  type T S
+	NotAType
+
+	// InvalidArrayLen occurs when an array length is not a constant value.
+	//
+	// Example:
+	//  var n = 3
+	//  var _ = [n]int{}
+	InvalidArrayLen
+
+	// BlankIfaceMethod occurs when a method name is '_'.
+	//
+	// Per the spec:
+	//  "The name of each explicitly specified method must be unique and not
+	//  blank."
+	//
+	// Example:
+	//  type T interface {
+	//  	_(int)
+	//  }
+	BlankIfaceMethod
+
+	// IncomparableMapKey occurs when a map key type does not support the == and
+	// != operators.
+	//
+	// Per the spec:
+	//  "The comparison operators == and != must be fully defined for operands of
+	//  the key type; thus the key type must not be a function, map, or slice."
+	//
+	// Example:
+	//  var x map[T]int
+	//
+	//  type T []int
+	IncomparableMapKey
+
+	// InvalidIfaceEmbed occurs when a non-interface type is embedded in an
+	// interface.
+	//
+	// Example:
+	//  type T struct {}
+	//
+	//  func (T) m()
+	//
+	//  type I interface {
+	//  	T
+	//  }
+	InvalidIfaceEmbed
+
+	// InvalidPtrEmbed occurs when an embedded field is of the pointer form *T,
+	// and T itself is itself a pointer, an unsafe.Pointer, or an interface.
+	//
+	// Per the spec:
+	//  "An embedded field must be specified as a type name T or as a pointer to
+	//  a non-interface type name *T, and T itself may not be a pointer type."
+	//
+	// Example:
+	//  type T *int
+	//
+	//  type S struct {
+	//  	*T
+	//  }
+	InvalidPtrEmbed
+
+	/* decls > func and method */
+
+	// BadRecv occurs when a method declaration does not have exactly one
+	// receiver parameter.
+	//
+	// Example:
+	//  func () _() {}
+	BadRecv
+
+	// InvalidRecv occurs when a receiver type expression is not of the form T
+	// or *T, or T is a pointer type.
+	//
+	// Example:
+	//  type T struct {}
+	//
+	//  func (**T) m() {}
+	InvalidRecv
+
+	// DuplicateFieldAndMethod occurs when an identifier appears as both a field
+	// and method name.
+	//
+	// Example:
+	//  type T struct {
+	//  	m int
+	//  }
+	//
+	//  func (T) m() {}
+	DuplicateFieldAndMethod
+
+	// DuplicateMethod occurs when two methods on the same receiver type have
+	// the same name.
+	//
+	// Example:
+	//  type T struct {}
+	//  func (T) m() {}
+	//  func (T) m(i int) int { return i }
+	DuplicateMethod
+
+	/* decls > special */
+
+	// InvalidBlank occurs when a blank identifier is used as a value or type.
+	//
+	// Per the spec:
+	//  "The blank identifier may appear as an operand only on the left-hand side
+	//  of an assignment."
+	//
+	// Example:
+	//  var x = _
+	InvalidBlank
+
+	// InvalidIota occurs when the predeclared identifier iota is used outside
+	// of a constant declaration.
+	//
+	// Example:
+	//  var x = iota
+	InvalidIota
+
+	// MissingInitBody occurs when an init function is missing its body.
+	//
+	// Example:
+	//  func init()
+	MissingInitBody
+
+	// InvalidInitSig occurs when an init function declares parameters or
+	// results.
+	//
+	// Example:
+	//  func init() int { return 1 }
+	InvalidInitSig
+
+	// InvalidInitDecl occurs when init is declared as anything other than a
+	// function.
+	//
+	// Example:
+	//  var init = 1
+	InvalidInitDecl
+
+	// InvalidMainDecl occurs when main is declared as anything other than a
+	// function, in a main package.
+	InvalidMainDecl
+
+	/* exprs */
+
+	// TooManyValues occurs when a function returns too many values for the
+	// expression context in which it is used.
+	//
+	// Example:
+	//  func ReturnTwo() (int, int) {
+	//  	return 1, 2
+	//  }
+	//
+	//  var x = ReturnTwo()
+	TooManyValues
+
+	// NotAnExpr occurs when a type expression is used where a value expression
+	// is expected.
+	//
+	// Example:
+	//  type T struct {}
+	//
+	//  func f() {
+	//  	T
+	//  }
+	NotAnExpr
+
+	/* exprs > const */
+
+	// TruncatedFloat occurs when a float constant is truncated to an integer
+	// value.
+	//
+	// Example:
+	//  var _ int = 98.6
+	TruncatedFloat
+
+	// NumericOverflow occurs when a numeric constant overflows its target type.
+	//
+	// Example:
+	//  var x int8 = 1000
+	NumericOverflow
+
+	/* exprs > operation */
+
+	// UndefinedOp occurs when an operator is not defined for the type(s) used
+	// in an operation.
+	//
+	// Example:
+	//  var c = "a" - "b"
+	UndefinedOp
+
+	// MismatchedTypes occurs when operand types are incompatible in a binary
+	// operation.
+	//
+	// Example:
+	//  var a = "hello"
+	//  var b = 1
+	//  var c = a - b
+	MismatchedTypes
+
+	// DivByZero occurs when a division operation is provable at compile
+	// time to be a division by zero.
+	//
+	// Example:
+	//  const divisor = 0
+	//  var x int = 1/divisor
+	DivByZero
+
+	// NonNumericIncDec occurs when an increment or decrement operator is
+	// applied to a non-numeric value.
+	//
+	// Example:
+	//  func f() {
+	//  	var c = "c"
+	//  	c++
+	//  }
+	NonNumericIncDec
+
+	/* exprs > ptr */
+
+	// UnaddressableOperand occurs when the & operator is applied to an
+	// unaddressable expression.
+	//
+	// Example:
+	//  var x = &1
+	UnaddressableOperand
+
+	// InvalidIndirection occurs when a non-pointer value is indirected via the
+	// '*' operator.
+	//
+	// Example:
+	//  var x int
+	//  var y = *x
+	InvalidIndirection
+
+	/* exprs > [] */
+
+	// NonIndexableOperand occurs when an index operation is applied to a value
+	// that cannot be indexed.
+	//
+	// Example:
+	//  var x = 1
+	//  var y = x[1]
+	NonIndexableOperand
+
+	// InvalidIndex occurs when an index argument is not of integer type,
+	// negative, or out-of-bounds.
+	//
+	// Example:
+	//  var s = [...]int{1,2,3}
+	//  var x = s[5]
+	//
+	// Example:
+	//  var s = []int{1,2,3}
+	//  var _ = s[-1]
+	//
+	// Example:
+	//  var s = []int{1,2,3}
+	//  var i string
+	//  var _ = s[i]
+	InvalidIndex
+
+	// SwappedSliceIndices occurs when constant indices in a slice expression
+	// are decreasing in value.
+	//
+	// Example:
+	//  var _ = []int{1,2,3}[2:1]
+	SwappedSliceIndices
+
+	/* operators > slice */
+
+	// NonSliceableOperand occurs when a slice operation is applied to a value
+	// whose type is not sliceable, or is unaddressable.
+	//
+	// Example:
+	//  var x = [...]int{1, 2, 3}[:1]
+	//
+	// Example:
+	//  var x = 1
+	//  var y = 1[:1]
+	NonSliceableOperand
+
+	// InvalidSliceExpr occurs when a three-index slice expression (a[x:y:z]) is
+	// applied to a string.
+	//
+	// Example:
+	//  var s = "hello"
+	//  var x = s[1:2:3]
+	InvalidSliceExpr
+
+	/* exprs > shift */
+
+	// InvalidShiftCount occurs when the right-hand side of a shift operation is
+	// either non-integer, negative, or too large.
+	//
+	// Example:
+	//  var (
+	//  	x string
+	//  	y int = 1 << x
+	//  )
+	InvalidShiftCount
+
+	// InvalidShiftOperand occurs when the shifted operand is not an integer.
+	//
+	// Example:
+	//  var s = "hello"
+	//  var x = s << 2
+	InvalidShiftOperand
+
+	/* exprs > chan */
+
+	// InvalidReceive occurs when there is a channel receive from a value that
+	// is either not a channel, or is a send-only channel.
+	//
+	// Example:
+	//  func f() {
+	//  	var x = 1
+	//  	<-x
+	//  }
+	InvalidReceive
+
+	// InvalidSend occurs when there is a channel send to a value that is not a
+	// channel, or is a receive-only channel.
+	//
+	// Example:
+	//  func f() {
+	//  	var x = 1
+	//  	x <- "hello!"
+	//  }
+	InvalidSend
+
+	/* exprs > literal */
+
+	// DuplicateLitKey occurs when an index is duplicated in a slice, array, or
+	// map literal.
+	//
+	// Example:
+	//  var _ = []int{0:1, 0:2}
+	//
+	// Example:
+	//  var _ = map[string]int{"a": 1, "a": 2}
+	DuplicateLitKey
+
+	// MissingLitKey occurs when a map literal is missing a key expression.
+	//
+	// Example:
+	//  var _ = map[string]int{1}
+	MissingLitKey
+
+	// InvalidLitIndex occurs when the key in a key-value element of a slice or
+	// array literal is not an integer constant.
+	//
+	// Example:
+	//  var i = 0
+	//  var x = []string{i: "world"}
+	InvalidLitIndex
+
+	// OversizeArrayLit occurs when an array literal exceeds its length.
+	//
+	// Example:
+	//  var _ = [2]int{1,2,3}
+	OversizeArrayLit
+
+	// MixedStructLit occurs when a struct literal contains a mix of positional
+	// and named elements.
+	//
+	// Example:
+	//  var _ = struct{i, j int}{i: 1, 2}
+	MixedStructLit
+
+	// InvalidStructLit occurs when a positional struct literal has an incorrect
+	// number of values.
+	//
+	// Example:
+	//  var _ = struct{i, j int}{1,2,3}
+	InvalidStructLit
+
+	// MissingLitField occurs when a struct literal refers to a field that does
+	// not exist on the struct type.
+	//
+	// Example:
+	//  var _ = struct{i int}{j: 2}
+	MissingLitField
+
+	// DuplicateLitField occurs when a struct literal contains duplicated
+	// fields.
+	//
+	// Example:
+	//  var _ = struct{i int}{i: 1, i: 2}
+	DuplicateLitField
+
+	// UnexportedLitField occurs when a positional struct literal implicitly
+	// assigns an unexported field of an imported type.
+	UnexportedLitField
+
+	// InvalidLitField occurs when a field name is not a valid identifier.
+	//
+	// Example:
+	//  var _ = struct{i int}{1: 1}
+	InvalidLitField
+
+	// UntypedLit occurs when a composite literal omits a required type
+	// identifier.
+	//
+	// Example:
+	//  type outer struct{
+	//  	inner struct { i int }
+	//  }
+	//
+	//  var _ = outer{inner: {1}}
+	UntypedLit
+
+	// InvalidLit occurs when a composite literal expression does not match its
+	// type.
+	//
+	// Example:
+	//  type P *struct{
+	//  	x int
+	//  }
+	//  var _ = P {}
+	InvalidLit
+
+	/* exprs > selector */
+
+	// AmbiguousSelector occurs when a selector is ambiguous.
+	//
+	// Example:
+	//  type E1 struct { i int }
+	//  type E2 struct { i int }
+	//  type T struct { E1; E2 }
+	//
+	//  var x T
+	//  var _ = x.i
+	AmbiguousSelector
+
+	// UndeclaredImportedName occurs when a package-qualified identifier is
+	// undeclared by the imported package.
+	//
+	// Example:
+	//  import "go/types"
+	//
+	//  var _ = types.NotAnActualIdentifier
+	UndeclaredImportedName
+
+	// UnexportedName occurs when a selector refers to an unexported identifier
+	// of an imported package.
+	//
+	// Example:
+	//  import "reflect"
+	//
+	//  type _ reflect.flag
+	UnexportedName
+
+	// UndeclaredName occurs when an identifier is not declared in the current
+	// scope.
+	//
+	// Example:
+	//  var x T
+	UndeclaredName
+
+	// MissingFieldOrMethod occurs when a selector references a field or method
+	// that does not exist.
+	//
+	// Example:
+	//  type T struct {}
+	//
+	//  var x = T{}.f
+	MissingFieldOrMethod
+
+	/* exprs > ... */
+
+	// BadDotDotDotSyntax occurs when a "..." occurs in a context where it is
+	// not valid.
+	//
+	// Example:
+	//  var _ = map[int][...]int{0: {}}
+	BadDotDotDotSyntax
+
+	// NonVariadicDotDotDot occurs when a "..." is used on the final argument to
+	// a non-variadic function.
+	//
+	// Example:
+	//  func printArgs(s []string) {
+	//  	for _, a := range s {
+	//  		println(a)
+	//  	}
+	//  }
+	//
+	//  func f() {
+	//  	s := []string{"a", "b", "c"}
+	//  	printArgs(s...)
+	//  }
+	NonVariadicDotDotDot
+
+	// MisplacedDotDotDot occurs when a "..." is used somewhere other than the
+	// final argument to a function call.
+	//
+	// Example:
+	//  func printArgs(args ...int) {
+	//  	for _, a := range args {
+	//  		println(a)
+	//  	}
+	//  }
+	//
+	//  func f() {
+	//  	a := []int{1,2,3}
+	//  	printArgs(0, a...)
+	//  }
+	MisplacedDotDotDot
+
+	// InvalidDotDotDotOperand occurs when a "..." operator is applied to a
+	// single-valued operand.
+	//
+	// Example:
+	//  func printArgs(args ...int) {
+	//  	for _, a := range args {
+	//  		println(a)
+	//  	}
+	//  }
+	//
+	//  func f() {
+	//  	a := 1
+	//  	printArgs(a...)
+	//  }
+	//
+	// Example:
+	//  func args() (int, int) {
+	//  	return 1, 2
+	//  }
+	//
+	//  func printArgs(args ...int) {
+	//  	for _, a := range args {
+	//  		println(a)
+	//  	}
+	//  }
+	//
+	//  func g() {
+	//  	printArgs(args()...)
+	//  }
+	InvalidDotDotDotOperand
+
+	// InvalidDotDotDot occurs when a "..." is used in a non-variadic built-in
+	// function.
+	//
+	// Example:
+	//  var s = []int{1, 2, 3}
+	//  var l = len(s...)
+	InvalidDotDotDot
+
+	/* exprs > built-in */
+
+	// UncalledBuiltin occurs when a built-in function is used as a
+	// function-valued expression, instead of being called.
+	//
+	// Per the spec:
+	//  "The built-in functions do not have standard Go types, so they can only
+	//  appear in call expressions; they cannot be used as function values."
+	//
+	// Example:
+	//  var _ = copy
+	UncalledBuiltin
+
+	// InvalidAppend occurs when append is called with a first argument that is
+	// not a slice.
+	//
+	// Example:
+	//  var _ = append(1, 2)
+	InvalidAppend
+
+	// InvalidCap occurs when an argument to the cap built-in function is not of
+	// supported type.
+	//
+	// See https://golang.org/ref/spec#Lengthand_capacity for information on
+	// which underlying types are supported as arguments to cap and len.
+	//
+	// Example:
+	//  var s = 2
+	//  var x = cap(s)
+	InvalidCap
+
+	// InvalidClose occurs when close(...) is called with an argument that is
+	// not of channel type, or that is a receive-only channel.
+	//
+	// Example:
+	//  func f() {
+	//  	var x int
+	//  	close(x)
+	//  }
+	InvalidClose
+
+	// InvalidCopy occurs when the arguments are not of slice type or do not
+	// have compatible type.
+	//
+	// See https://golang.org/ref/spec#Appendingand_copying_slices for more
+	// information on the type requirements for the copy built-in.
+	//
+	// Example:
+	//  func f() {
+	//  	var x []int
+	//  	y := []int64{1,2,3}
+	//  	copy(x, y)
+	//  }
+	InvalidCopy
+
+	// InvalidComplex occurs when the complex built-in function is called with
+	// arguments with incompatible types.
+	//
+	// Example:
+	//  var _ = complex(float32(1), float64(2))
+	InvalidComplex
+
+	// InvalidDelete occurs when the delete built-in function is called with a
+	// first argument that is not a map.
+	//
+	// Example:
+	//  func f() {
+	//  	m := "hello"
+	//  	delete(m, "e")
+	//  }
+	InvalidDelete
+
+	// InvalidImag occurs when the imag built-in function is called with an
+	// argument that does not have complex type.
+	//
+	// Example:
+	//  var _ = imag(int(1))
+	InvalidImag
+
+	// InvalidLen occurs when an argument to the len built-in function is not of
+	// supported type.
+	//
+	// See https://golang.org/ref/spec#Lengthand_capacity for information on
+	// which underlying types are supported as arguments to cap and len.
+	//
+	// Example:
+	//  var s = 2
+	//  var x = len(s)
+	InvalidLen
+
+	// SwappedMakeArgs occurs when make is called with three arguments, and its
+	// length argument is larger than its capacity argument.
+	//
+	// Example:
+	//  var x = make([]int, 3, 2)
+	SwappedMakeArgs
+
+	// InvalidMake occurs when make is called with an unsupported type argument.
+	//
+	// See https://golang.org/ref/spec#Makingslices_maps_and_channels for
+	// information on the types that may be created using make.
+	//
+	// Example:
+	//  var x = make(int)
+	InvalidMake
+
+	// InvalidReal occurs when the real built-in function is called with an
+	// argument that does not have complex type.
+	//
+	// Example:
+	//  var _ = real(int(1))
+	InvalidReal
+
+	/* exprs > assertion */
+
+	// InvalidAssert occurs when a type assertion is applied to a
+	// value that is not of interface type.
+	//
+	// Example:
+	//  var x = 1
+	//  var _ = x.(float64)
+	InvalidAssert
+
+	// ImpossibleAssert occurs for a type assertion x.(T) when the value x of
+	// interface cannot have dynamic type T, due to a missing or mismatching
+	// method on T.
+	//
+	// Example:
+	//  type T int
+	//
+	//  func (t *T) m() int { return int(*t) }
+	//
+	//  type I interface { m() int }
+	//
+	//  var x I
+	//  var _ = x.(T)
+	ImpossibleAssert
+
+	/* exprs > conversion */
+
+	// InvalidConversion occurs when the argument type cannot be converted to the
+	// target.
+	//
+	// See https://golang.org/ref/spec#Conversions for the rules of
+	// convertibility.
+	//
+	// Example:
+	//  var x float64
+	//  var _ = string(x)
+	InvalidConversion
+
+	// InvalidUntypedConversion occurs when an there is no valid implicit
+	// conversion from an untyped value satisfying the type constraints of the
+	// context in which it is used.
+	//
+	// Example:
+	//  var _ = 1 + ""
+	InvalidUntypedConversion
+
+	/* offsetof */
+
+	// BadOffsetofSyntax occurs when unsafe.Offsetof is called with an argument
+	// that is not a selector expression.
+	//
+	// Example:
+	//  import "unsafe"
+	//
+	//  var x int
+	//  var _ = unsafe.Offsetof(x)
+	BadOffsetofSyntax
+
+	// InvalidOffsetof occurs when unsafe.Offsetof is called with a method
+	// selector, rather than a field selector, or when the field is embedded via
+	// a pointer.
+	//
+	// Per the spec:
+	//
+	//  "If f is an embedded field, it must be reachable without pointer
+	//  indirections through fields of the struct. "
+	//
+	// Example:
+	//  import "unsafe"
+	//
+	//  type T struct { f int }
+	//  type S struct { *T }
+	//  var s S
+	//  var _ = unsafe.Offsetof(s.f)
+	//
+	// Example:
+	//  import "unsafe"
+	//
+	//  type S struct{}
+	//
+	//  func (S) m() {}
+	//
+	//  var s S
+	//  var _ = unsafe.Offsetof(s.m)
+	InvalidOffsetof
+
+	/* control flow > scope */
+
+	// UnusedExpr occurs when a side-effect free expression is used as a
+	// statement. Such a statement has no effect.
+	//
+	// Example:
+	//  func f(i int) {
+	//  	i*i
+	//  }
+	UnusedExpr
+
+	// UnusedVar occurs when a variable is declared but unused.
+	//
+	// Example:
+	//  func f() {
+	//  	x := 1
+	//  }
+	UnusedVar
+
+	// MissingReturn occurs when a function with results is missing a return
+	// statement.
+	//
+	// Example:
+	//  func f() int {}
+	MissingReturn
+
+	// WrongResultCount occurs when a return statement returns an incorrect
+	// number of values.
+	//
+	// Example:
+	//  func ReturnOne() int {
+	//  	return 1, 2
+	//  }
+	WrongResultCount
+
+	// OutOfScopeResult occurs when the name of a value implicitly returned by
+	// an empty return statement is shadowed in a nested scope.
+	//
+	// Example:
+	//  func factor(n int) (i int) {
+	//  	for i := 2; i < n; i++ {
+	//  		if n%i == 0 {
+	//  			return
+	//  		}
+	//  	}
+	//  	return 0
+	//  }
+	OutOfScopeResult
+
+	/* control flow > if */
+
+	// InvalidCond occurs when an if condition is not a boolean expression.
+	//
+	// Example:
+	//  func checkReturn(i int) {
+	//  	if i {
+	//  		panic("non-zero return")
+	//  	}
+	//  }
+	InvalidCond
+
+	/* control flow > for */
+
+	// InvalidPostDecl occurs when there is a declaration in a for-loop post
+	// statement.
+	//
+	// Example:
+	//  func f() {
+	//  	for i := 0; i < 10; j := 0 {}
+	//  }
+	InvalidPostDecl
+
+	// InvalidChanRange occurs when a send-only channel used in a range
+	// expression.
+	//
+	// Example:
+	//  func sum(c chan<- int) {
+	//  	s := 0
+	//  	for i := range c {
+	//  		s += i
+	//  	}
+	//  }
+	InvalidChanRange
+
+	// InvalidIterVar occurs when two iteration variables are used while ranging
+	// over a channel.
+	//
+	// Example:
+	//  func f(c chan int) {
+	//  	for k, v := range c {
+	//  		println(k, v)
+	//  	}
+	//  }
+	InvalidIterVar
+
+	// InvalidRangeExpr occurs when the type of a range expression is not array,
+	// slice, string, map, or channel.
+	//
+	// Example:
+	//  func f(i int) {
+	//  	for j := range i {
+	//  		println(j)
+	//  	}
+	//  }
+	InvalidRangeExpr
+
+	/* control flow > switch */
+
+	// MisplacedBreak occurs when a break statement is not within a for, switch,
+	// or select statement of the innermost function definition.
+	//
+	// Example:
+	//  func f() {
+	//  	break
+	//  }
+	MisplacedBreak
+
+	// MisplacedContinue occurs when a continue statement is not within a for
+	// loop of the innermost function definition.
+	//
+	// Example:
+	//  func sumeven(n int) int {
+	//  	proceed := func() {
+	//  		continue
+	//  	}
+	//  	sum := 0
+	//  	for i := 1; i <= n; i++ {
+	//  		if i % 2 != 0 {
+	//  			proceed()
+	//  		}
+	//  		sum += i
+	//  	}
+	//  	return sum
+	//  }
+	MisplacedContinue
+
+	// MisplacedFallthrough occurs when a fallthrough statement is not within an
+	// expression switch.
+	//
+	// Example:
+	//  func typename(i interface{}) string {
+	//  	switch i.(type) {
+	//  	case int64:
+	//  		fallthrough
+	//  	case int:
+	//  		return "int"
+	//  	}
+	//  	return "unsupported"
+	//  }
+	MisplacedFallthrough
+
+	// DuplicateCase occurs when a type or expression switch has duplicate
+	// cases.
+	//
+	// Example:
+	//  func printInt(i int) {
+	//  	switch i {
+	//  	case 1:
+	//  		println("one")
+	//  	case 1:
+	//  		println("One")
+	//  	}
+	//  }
+	DuplicateCase
+
+	// DuplicateDefault occurs when a type or expression switch has multiple
+	// default clauses.
+	//
+	// Example:
+	//  func printInt(i int) {
+	//  	switch i {
+	//  	case 1:
+	//  		println("one")
+	//  	default:
+	//  		println("One")
+	//  	default:
+	//  		println("1")
+	//  	}
+	//  }
+	DuplicateDefault
+
+	// BadTypeKeyword occurs when a .(type) expression is used anywhere other
+	// than a type switch.
+	//
+	// Example:
+	//  type I interface {
+	//  	m()
+	//  }
+	//  var t I
+	//  var _ = t.(type)
+	BadTypeKeyword
+
+	// InvalidTypeSwitch occurs when .(type) is used on an expression that is
+	// not of interface type.
+	//
+	// Example:
+	//  func f(i int) {
+	//  	switch x := i.(type) {}
+	//  }
+	InvalidTypeSwitch
+
+	// InvalidExprSwitch occurs when a switch expression is not comparable.
+	//
+	// Example:
+	//  func _() {
+	//  	var a struct{ _ func() }
+	//  	switch a /* ERROR cannot switch on a */ {
+	//  	}
+	//  }
+	InvalidExprSwitch
+
+	/* control flow > select */
+
+	// InvalidSelectCase occurs when a select case is not a channel send or
+	// receive.
+	//
+	// Example:
+	//  func checkChan(c <-chan int) bool {
+	//  	select {
+	//  	case c:
+	//  		return true
+	//  	default:
+	//  		return false
+	//  	}
+	//  }
+	InvalidSelectCase
+
+	/* control flow > labels and jumps */
+
+	// UndeclaredLabel occurs when an undeclared label is jumped to.
+	//
+	// Example:
+	//  func f() {
+	//  	goto L
+	//  }
+	UndeclaredLabel
+
+	// DuplicateLabel occurs when a label is declared more than once.
+	//
+	// Example:
+	//  func f() int {
+	//  L:
+	//  L:
+	//  	return 1
+	//  }
+	DuplicateLabel
+
+	// MisplacedLabel occurs when a break or continue label is not on a for,
+	// switch, or select statement.
+	//
+	// Example:
+	//  func f() {
+	//  L:
+	//  	a := []int{1,2,3}
+	//  	for _, e := range a {
+	//  		if e > 10 {
+	//  			break L
+	//  		}
+	//  		println(a)
+	//  	}
+	//  }
+	MisplacedLabel
+
+	// UnusedLabel occurs when a label is declared but not used.
+	//
+	// Example:
+	//  func f() {
+	//  L:
+	//  }
+	UnusedLabel
+
+	// JumpOverDecl occurs when a label jumps over a variable declaration.
+	//
+	// Example:
+	//  func f() int {
+	//  	goto L
+	//  	x := 2
+	//  L:
+	//  	x++
+	//  	return x
+	//  }
+	JumpOverDecl
+
+	// JumpIntoBlock occurs when a forward jump goes to a label inside a nested
+	// block.
+	//
+	// Example:
+	//  func f(x int) {
+	//  	goto L
+	//  	if x > 0 {
+	//  	L:
+	//  		print("inside block")
+	//  	}
+	// }
+	JumpIntoBlock
+
+	/* control flow > calls */
+
+	// InvalidMethodExpr occurs when a pointer method is called but the argument
+	// is not addressable.
+	//
+	// Example:
+	//  type T struct {}
+	//
+	//  func (*T) m() int { return 1 }
+	//
+	//  var _ = T.m(T{})
+	InvalidMethodExpr
+
+	// WrongArgCount occurs when too few or too many arguments are passed by a
+	// function call.
+	//
+	// Example:
+	//  func f(i int) {}
+	//  var x = f()
+	WrongArgCount
+
+	// InvalidCall occurs when an expression is called that is not of function
+	// type.
+	//
+	// Example:
+	//  var x = "x"
+	//  var y = x()
+	InvalidCall
+
+	/* control flow > suspended */
+
+	// UnusedResults occurs when a restricted expression-only built-in function
+	// is suspended via go or defer. Such a suspension discards the results of
+	// these side-effect free built-in functions, and therefore is ineffectual.
+	//
+	// Example:
+	//  func f(a []int) int {
+	//  	defer len(a)
+	//  	return i
+	//  }
+	UnusedResults
+
+	// InvalidDefer occurs when a deferred expression is not a function call,
+	// for example if the expression is a type conversion.
+	//
+	// Example:
+	//  func f(i int) int {
+	//  	defer int32(i)
+	//  	return i
+	//  }
+	InvalidDefer
+
+	// InvalidGo occurs when a go expression is not a function call, for example
+	// if the expression is a type conversion.
+	//
+	// Example:
+	//  func f(i int) int {
+	//  	go int32(i)
+	//  	return i
+	//  }
+	InvalidGo
+
+	// All codes below were added in Go 1.17.
+
+	/* decl */
+
+	// BadDecl occurs when a declaration has invalid syntax.
+	BadDecl
+
+	// RepeatedDecl occurs when an identifier occurs more than once on the left
+	// hand side of a short variable declaration.
+	//
+	// Example:
+	//  func _() {
+	//  	x, y, y := 1, 2, 3
+	//  }
+	RepeatedDecl
+
+	/* unsafe */
+
+	// InvalidUnsafeAdd occurs when unsafe.Add is called with a
+	// length argument that is not of integer type.
+	//
+	// Example:
+	//  import "unsafe"
+	//
+	//  var p unsafe.Pointer
+	//  var _ = unsafe.Add(p, float64(1))
+	InvalidUnsafeAdd
+
+	// InvalidUnsafeSlice occurs when unsafe.Slice is called with a
+	// pointer argument that is not of pointer type or a length argument
+	// that is not of integer type, negative, or out of bounds.
+	//
+	// Example:
+	//  import "unsafe"
+	//
+	//  var x int
+	//  var _ = unsafe.Slice(x, 1)
+	//
+	// Example:
+	//  import "unsafe"
+	//
+	//  var x int
+	//  var _ = unsafe.Slice(&x, float64(1))
+	//
+	// Example:
+	//  import "unsafe"
+	//
+	//  var x int
+	//  var _ = unsafe.Slice(&x, -1)
+	//
+	// Example:
+	//  import "unsafe"
+	//
+	//  var x int
+	//  var _ = unsafe.Slice(&x, uint64(1) << 63)
+	InvalidUnsafeSlice
+
+	// All codes below were added in Go 1.18.
+
+	/* features */
+
+	// UnsupportedFeature occurs when a language feature is used that is not
+	// supported at this Go version.
+	UnsupportedFeature
+
+	/* type params */
+
+	// NotAGenericType occurs when a non-generic type is used where a generic
+	// type is expected: in type or function instantiation.
+	//
+	// Example:
+	//  type T int
+	//
+	//  var _ T[int]
+	NotAGenericType
+
+	// WrongTypeArgCount occurs when a type or function is instantiated with an
+	// incorrent number of type arguments, including when a generic type or
+	// function is used without instantiation.
+	//
+	// Errors inolving failed type inference are assigned other error codes.
+	//
+	// Example:
+	//  type T[p any] int
+	//
+	//  var _ T[int, string]
+	//
+	// Example:
+	//  func f[T any]() {}
+	//
+	//  var x = f
+	WrongTypeArgCount
+
+	// CannotInferTypeArgs occurs when type or function type argument inference
+	// fails to infer all type arguments.
+	//
+	// Example:
+	//  func f[T any]() {}
+	//
+	//  func _() {
+	//  	f()
+	//  }
+	//
+	// Example:
+	//   type N[P, Q any] struct{}
+	//
+	//   var _ N[int]
+	CannotInferTypeArgs
+
+	// InvalidTypeArg occurs when a type argument does not satisfy its
+	// corresponding type parameter constraints.
+	//
+	// Example:
+	//  type T[P ~int] struct{}
+	//
+	//  var _ T[string]
+	InvalidTypeArg // arguments? InferenceFailed
+
+	// InvalidInstanceCycle occurs when an invalid cycle is detected
+	// within the instantiation graph.
+	//
+	// Example:
+	//  func f[T any]() { f[*T]() }
+	InvalidInstanceCycle
+
+	// InvalidUnion occurs when an embedded union or approximation element is
+	// not valid.
+	//
+	// Example:
+	//  type _ interface {
+	//   	~int | interface{ m() }
+	//  }
+	InvalidUnion
+
+	// MisplacedConstraintIface occurs when a constraint-type interface is used
+	// outside of constraint position.
+	//
+	// Example:
+	//   type I interface { ~int }
+	//
+	//   var _ I
+	MisplacedConstraintIface
+
+	// InvalidMethodTypeParams occurs when methods have type parameters.
+	//
+	// It cannot be encountered with an AST parsed using go/parser.
+	InvalidMethodTypeParams
+
+	// MisplacedTypeParam occurs when a type parameter is used in a place where
+	// it is not permitted.
+	//
+	// Example:
+	//  type T[P any] P
+	//
+	// Example:
+	//  type T[P any] struct{ *P }
+	MisplacedTypeParam
+
+	// InvalidUnsafeSliceData occurs when unsafe.SliceData is called with
+	// an argument that is not of slice type. It also occurs if it is used
+	// in a package compiled for a language version before go1.20.
+	//
+	// Example:
+	//  import "unsafe"
+	//
+	//  var x int
+	//  var _ = unsafe.SliceData(x)
+	InvalidUnsafeSliceData
+
+	// InvalidUnsafeString occurs when unsafe.String is called with
+	// a length argument that is not of integer type, negative, or
+	// out of bounds. It also occurs if it is used in a package
+	// compiled for a language version before go1.20.
+	//
+	// Example:
+	//  import "unsafe"
+	//
+	//  var b [10]byte
+	//  var _ = unsafe.String(&b[0], -1)
+	InvalidUnsafeString
+
+	// InvalidUnsafeStringData occurs if it is used in a package
+	// compiled for a language version before go1.20.
+	_ // not used anymore
+
+)
diff --git a/vendor/golang.org/x/tools/internal/typesinternal/errorcode_string.go b/vendor/golang.org/x/tools/internal/typesinternal/errorcode_string.go
new file mode 100644
index 0000000..15ecf7c
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/typesinternal/errorcode_string.go
@@ -0,0 +1,179 @@
+// Code generated by "stringer -type=ErrorCode"; DO NOT EDIT.
+
+package typesinternal
+
+import "strconv"
+
+func _() {
+	// An "invalid array index" compiler error signifies that the constant values have changed.
+	// Re-run the stringer command to generate them again.
+	var x [1]struct{}
+	_ = x[InvalidSyntaxTree - -1]
+	_ = x[Test-1]
+	_ = x[BlankPkgName-2]
+	_ = x[MismatchedPkgName-3]
+	_ = x[InvalidPkgUse-4]
+	_ = x[BadImportPath-5]
+	_ = x[BrokenImport-6]
+	_ = x[ImportCRenamed-7]
+	_ = x[UnusedImport-8]
+	_ = x[InvalidInitCycle-9]
+	_ = x[DuplicateDecl-10]
+	_ = x[InvalidDeclCycle-11]
+	_ = x[InvalidTypeCycle-12]
+	_ = x[InvalidConstInit-13]
+	_ = x[InvalidConstVal-14]
+	_ = x[InvalidConstType-15]
+	_ = x[UntypedNilUse-16]
+	_ = x[WrongAssignCount-17]
+	_ = x[UnassignableOperand-18]
+	_ = x[NoNewVar-19]
+	_ = x[MultiValAssignOp-20]
+	_ = x[InvalidIfaceAssign-21]
+	_ = x[InvalidChanAssign-22]
+	_ = x[IncompatibleAssign-23]
+	_ = x[UnaddressableFieldAssign-24]
+	_ = x[NotAType-25]
+	_ = x[InvalidArrayLen-26]
+	_ = x[BlankIfaceMethod-27]
+	_ = x[IncomparableMapKey-28]
+	_ = x[InvalidIfaceEmbed-29]
+	_ = x[InvalidPtrEmbed-30]
+	_ = x[BadRecv-31]
+	_ = x[InvalidRecv-32]
+	_ = x[DuplicateFieldAndMethod-33]
+	_ = x[DuplicateMethod-34]
+	_ = x[InvalidBlank-35]
+	_ = x[InvalidIota-36]
+	_ = x[MissingInitBody-37]
+	_ = x[InvalidInitSig-38]
+	_ = x[InvalidInitDecl-39]
+	_ = x[InvalidMainDecl-40]
+	_ = x[TooManyValues-41]
+	_ = x[NotAnExpr-42]
+	_ = x[TruncatedFloat-43]
+	_ = x[NumericOverflow-44]
+	_ = x[UndefinedOp-45]
+	_ = x[MismatchedTypes-46]
+	_ = x[DivByZero-47]
+	_ = x[NonNumericIncDec-48]
+	_ = x[UnaddressableOperand-49]
+	_ = x[InvalidIndirection-50]
+	_ = x[NonIndexableOperand-51]
+	_ = x[InvalidIndex-52]
+	_ = x[SwappedSliceIndices-53]
+	_ = x[NonSliceableOperand-54]
+	_ = x[InvalidSliceExpr-55]
+	_ = x[InvalidShiftCount-56]
+	_ = x[InvalidShiftOperand-57]
+	_ = x[InvalidReceive-58]
+	_ = x[InvalidSend-59]
+	_ = x[DuplicateLitKey-60]
+	_ = x[MissingLitKey-61]
+	_ = x[InvalidLitIndex-62]
+	_ = x[OversizeArrayLit-63]
+	_ = x[MixedStructLit-64]
+	_ = x[InvalidStructLit-65]
+	_ = x[MissingLitField-66]
+	_ = x[DuplicateLitField-67]
+	_ = x[UnexportedLitField-68]
+	_ = x[InvalidLitField-69]
+	_ = x[UntypedLit-70]
+	_ = x[InvalidLit-71]
+	_ = x[AmbiguousSelector-72]
+	_ = x[UndeclaredImportedName-73]
+	_ = x[UnexportedName-74]
+	_ = x[UndeclaredName-75]
+	_ = x[MissingFieldOrMethod-76]
+	_ = x[BadDotDotDotSyntax-77]
+	_ = x[NonVariadicDotDotDot-78]
+	_ = x[MisplacedDotDotDot-79]
+	_ = x[InvalidDotDotDotOperand-80]
+	_ = x[InvalidDotDotDot-81]
+	_ = x[UncalledBuiltin-82]
+	_ = x[InvalidAppend-83]
+	_ = x[InvalidCap-84]
+	_ = x[InvalidClose-85]
+	_ = x[InvalidCopy-86]
+	_ = x[InvalidComplex-87]
+	_ = x[InvalidDelete-88]
+	_ = x[InvalidImag-89]
+	_ = x[InvalidLen-90]
+	_ = x[SwappedMakeArgs-91]
+	_ = x[InvalidMake-92]
+	_ = x[InvalidReal-93]
+	_ = x[InvalidAssert-94]
+	_ = x[ImpossibleAssert-95]
+	_ = x[InvalidConversion-96]
+	_ = x[InvalidUntypedConversion-97]
+	_ = x[BadOffsetofSyntax-98]
+	_ = x[InvalidOffsetof-99]
+	_ = x[UnusedExpr-100]
+	_ = x[UnusedVar-101]
+	_ = x[MissingReturn-102]
+	_ = x[WrongResultCount-103]
+	_ = x[OutOfScopeResult-104]
+	_ = x[InvalidCond-105]
+	_ = x[InvalidPostDecl-106]
+	_ = x[InvalidChanRange-107]
+	_ = x[InvalidIterVar-108]
+	_ = x[InvalidRangeExpr-109]
+	_ = x[MisplacedBreak-110]
+	_ = x[MisplacedContinue-111]
+	_ = x[MisplacedFallthrough-112]
+	_ = x[DuplicateCase-113]
+	_ = x[DuplicateDefault-114]
+	_ = x[BadTypeKeyword-115]
+	_ = x[InvalidTypeSwitch-116]
+	_ = x[InvalidExprSwitch-117]
+	_ = x[InvalidSelectCase-118]
+	_ = x[UndeclaredLabel-119]
+	_ = x[DuplicateLabel-120]
+	_ = x[MisplacedLabel-121]
+	_ = x[UnusedLabel-122]
+	_ = x[JumpOverDecl-123]
+	_ = x[JumpIntoBlock-124]
+	_ = x[InvalidMethodExpr-125]
+	_ = x[WrongArgCount-126]
+	_ = x[InvalidCall-127]
+	_ = x[UnusedResults-128]
+	_ = x[InvalidDefer-129]
+	_ = x[InvalidGo-130]
+	_ = x[BadDecl-131]
+	_ = x[RepeatedDecl-132]
+	_ = x[InvalidUnsafeAdd-133]
+	_ = x[InvalidUnsafeSlice-134]
+	_ = x[UnsupportedFeature-135]
+	_ = x[NotAGenericType-136]
+	_ = x[WrongTypeArgCount-137]
+	_ = x[CannotInferTypeArgs-138]
+	_ = x[InvalidTypeArg-139]
+	_ = x[InvalidInstanceCycle-140]
+	_ = x[InvalidUnion-141]
+	_ = x[MisplacedConstraintIface-142]
+	_ = x[InvalidMethodTypeParams-143]
+	_ = x[MisplacedTypeParam-144]
+	_ = x[InvalidUnsafeSliceData-145]
+	_ = x[InvalidUnsafeString-146]
+}
+
+const (
+	_ErrorCode_name_0 = "InvalidSyntaxTree"
+	_ErrorCode_name_1 = "TestBlankPkgNameMismatchedPkgNameInvalidPkgUseBadImportPathBrokenImportImportCRenamedUnusedImportInvalidInitCycleDuplicateDeclInvalidDeclCycleInvalidTypeCycleInvalidConstInitInvalidConstValInvalidConstTypeUntypedNilUseWrongAssignCountUnassignableOperandNoNewVarMultiValAssignOpInvalidIfaceAssignInvalidChanAssignIncompatibleAssignUnaddressableFieldAssignNotATypeInvalidArrayLenBlankIfaceMethodIncomparableMapKeyInvalidIfaceEmbedInvalidPtrEmbedBadRecvInvalidRecvDuplicateFieldAndMethodDuplicateMethodInvalidBlankInvalidIotaMissingInitBodyInvalidInitSigInvalidInitDeclInvalidMainDeclTooManyValuesNotAnExprTruncatedFloatNumericOverflowUndefinedOpMismatchedTypesDivByZeroNonNumericIncDecUnaddressableOperandInvalidIndirectionNonIndexableOperandInvalidIndexSwappedSliceIndicesNonSliceableOperandInvalidSliceExprInvalidShiftCountInvalidShiftOperandInvalidReceiveInvalidSendDuplicateLitKeyMissingLitKeyInvalidLitIndexOversizeArrayLitMixedStructLitInvalidStructLitMissingLitFieldDuplicateLitFieldUnexportedLitFieldInvalidLitFieldUntypedLitInvalidLitAmbiguousSelectorUndeclaredImportedNameUnexportedNameUndeclaredNameMissingFieldOrMethodBadDotDotDotSyntaxNonVariadicDotDotDotMisplacedDotDotDotInvalidDotDotDotOperandInvalidDotDotDotUncalledBuiltinInvalidAppendInvalidCapInvalidCloseInvalidCopyInvalidComplexInvalidDeleteInvalidImagInvalidLenSwappedMakeArgsInvalidMakeInvalidRealInvalidAssertImpossibleAssertInvalidConversionInvalidUntypedConversionBadOffsetofSyntaxInvalidOffsetofUnusedExprUnusedVarMissingReturnWrongResultCountOutOfScopeResultInvalidCondInvalidPostDeclInvalidChanRangeInvalidIterVarInvalidRangeExprMisplacedBreakMisplacedContinueMisplacedFallthroughDuplicateCaseDuplicateDefaultBadTypeKeywordInvalidTypeSwitchInvalidExprSwitchInvalidSelectCaseUndeclaredLabelDuplicateLabelMisplacedLabelUnusedLabelJumpOverDeclJumpIntoBlockInvalidMethodExprWrongArgCountInvalidCallUnusedResultsInvalidDeferInvalidGoBadDeclRepeatedDeclInvalidUnsafeAddInvalidUnsafeSliceUnsupportedFeatureNotAGenericTypeWrongTypeArgCountCannotInferTypeArgsInvalidTypeArgInvalidInstanceCycleInvalidUnionMisplacedConstraintIfaceInvalidMethodTypeParamsMisplacedTypeParamInvalidUnsafeSliceDataInvalidUnsafeString"
+)
+
+var (
+	_ErrorCode_index_1 = [...]uint16{0, 4, 16, 33, 46, 59, 71, 85, 97, 113, 126, 142, 158, 174, 189, 205, 218, 234, 253, 261, 277, 295, 312, 330, 354, 362, 377, 393, 411, 428, 443, 450, 461, 484, 499, 511, 522, 537, 551, 566, 581, 594, 603, 617, 632, 643, 658, 667, 683, 703, 721, 740, 752, 771, 790, 806, 823, 842, 856, 867, 882, 895, 910, 926, 940, 956, 971, 988, 1006, 1021, 1031, 1041, 1058, 1080, 1094, 1108, 1128, 1146, 1166, 1184, 1207, 1223, 1238, 1251, 1261, 1273, 1284, 1298, 1311, 1322, 1332, 1347, 1358, 1369, 1382, 1398, 1415, 1439, 1456, 1471, 1481, 1490, 1503, 1519, 1535, 1546, 1561, 1577, 1591, 1607, 1621, 1638, 1658, 1671, 1687, 1701, 1718, 1735, 1752, 1767, 1781, 1795, 1806, 1818, 1831, 1848, 1861, 1872, 1885, 1897, 1906, 1913, 1925, 1941, 1959, 1977, 1992, 2009, 2028, 2042, 2062, 2074, 2098, 2121, 2139, 2161, 2180}
+)
+
+func (i ErrorCode) String() string {
+	switch {
+	case i == -1:
+		return _ErrorCode_name_0
+	case 1 <= i && i <= 146:
+		i -= 1
+		return _ErrorCode_name_1[_ErrorCode_index_1[i]:_ErrorCode_index_1[i+1]]
+	default:
+		return "ErrorCode(" + strconv.FormatInt(int64(i), 10) + ")"
+	}
+}
diff --git a/vendor/golang.org/x/tools/internal/typesinternal/types.go b/vendor/golang.org/x/tools/internal/typesinternal/types.go
new file mode 100644
index 0000000..3c53fbc
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/typesinternal/types.go
@@ -0,0 +1,61 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package typesinternal provides access to internal go/types APIs that are not
+// yet exported.
+package typesinternal
+
+import (
+	"go/token"
+	"go/types"
+	"reflect"
+	"unsafe"
+
+	"golang.org/x/tools/go/types/objectpath"
+)
+
+func SetUsesCgo(conf *types.Config) bool {
+	v := reflect.ValueOf(conf).Elem()
+
+	f := v.FieldByName("go115UsesCgo")
+	if !f.IsValid() {
+		f = v.FieldByName("UsesCgo")
+		if !f.IsValid() {
+			return false
+		}
+	}
+
+	addr := unsafe.Pointer(f.UnsafeAddr())
+	*(*bool)(addr) = true
+
+	return true
+}
+
+// ReadGo116ErrorData extracts additional information from types.Error values
+// generated by Go version 1.16 and later: the error code, start position, and
+// end position. If all positions are valid, start <= err.Pos <= end.
+//
+// If the data could not be read, the final result parameter will be false.
+func ReadGo116ErrorData(err types.Error) (code ErrorCode, start, end token.Pos, ok bool) {
+	var data [3]int
+	// By coincidence all of these fields are ints, which simplifies things.
+	v := reflect.ValueOf(err)
+	for i, name := range []string{"go116code", "go116start", "go116end"} {
+		f := v.FieldByName(name)
+		if !f.IsValid() {
+			return 0, 0, 0, false
+		}
+		data[i] = int(f.Int())
+	}
+	return ErrorCode(data[0]), token.Pos(data[1]), token.Pos(data[2]), true
+}
+
+var SetGoVersion = func(conf *types.Config, version string) bool { return false }
+
+// NewObjectpathEncoder returns a function closure equivalent to
+// objectpath.For but amortized for multiple (sequential) calls.
+// It is a temporary workaround, pending the approval of proposal 58668.
+//
+//go:linkname NewObjectpathFunc golang.org/x/tools/go/types/objectpath.newEncoderFor
+func NewObjectpathFunc() func(types.Object) (objectpath.Path, error)
diff --git a/vendor/golang.org/x/tools/internal/typesinternal/types_118.go b/vendor/golang.org/x/tools/internal/typesinternal/types_118.go
new file mode 100644
index 0000000..a42b072
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/typesinternal/types_118.go
@@ -0,0 +1,19 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build go1.18
+// +build go1.18
+
+package typesinternal
+
+import (
+	"go/types"
+)
+
+func init() {
+	SetGoVersion = func(conf *types.Config, version string) bool {
+		conf.GoVersion = version
+		return true
+	}
+}
diff --git a/vendor/modules.txt b/vendor/modules.txt
index 03214b5..13c165e 100644
--- a/vendor/modules.txt
+++ b/vendor/modules.txt
@@ -84,6 +84,7 @@
 go.starlark.net/syntax
 # golang.org/x/mod v0.11.0
 ## explicit; go 1.17
+golang.org/x/mod/semver
 golang.org/x/mod/sumdb/dirhash
 # golang.org/x/net v0.11.0
 ## explicit; go 1.17
@@ -100,6 +101,7 @@
 golang.org/x/sync/semaphore
 # golang.org/x/sys v0.9.0
 ## explicit; go 1.17
+golang.org/x/sys/execabs
 golang.org/x/sys/unix
 # golang.org/x/text v0.10.0
 ## explicit; go 1.17
@@ -107,6 +109,32 @@
 golang.org/x/text/transform
 golang.org/x/text/unicode/bidi
 golang.org/x/text/unicode/norm
+# golang.org/x/tools v0.7.0
+## explicit; go 1.18
+golang.org/x/tools/go/analysis
+golang.org/x/tools/go/analysis/internal/analysisflags
+golang.org/x/tools/go/analysis/internal/checker
+golang.org/x/tools/go/analysis/multichecker
+golang.org/x/tools/go/analysis/unitchecker
+golang.org/x/tools/go/gcexportdata
+golang.org/x/tools/go/internal/packagesdriver
+golang.org/x/tools/go/packages
+golang.org/x/tools/go/types/objectpath
+golang.org/x/tools/internal/diff
+golang.org/x/tools/internal/diff/lcs
+golang.org/x/tools/internal/event
+golang.org/x/tools/internal/event/core
+golang.org/x/tools/internal/event/keys
+golang.org/x/tools/internal/event/label
+golang.org/x/tools/internal/facts
+golang.org/x/tools/internal/gcimporter
+golang.org/x/tools/internal/gocommand
+golang.org/x/tools/internal/packagesinternal
+golang.org/x/tools/internal/pkgbits
+golang.org/x/tools/internal/robustio
+golang.org/x/tools/internal/tokeninternal
+golang.org/x/tools/internal/typeparams
+golang.org/x/tools/internal/typesinternal
 # google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1
 ## explicit; go 1.19
 google.golang.org/genproto/googleapis/api