func (s *snapshot) buildPackageHandle(ctx context.Context, id PackageID, mode source.ParseMode) (*packageHandle, error) {
	if ph := s.getPackage(id, mode); ph != nil {
		return ph, nil
	}
	ph, deps, err := s.buildKey(ctx, id, mode)
	if err != nil {
		return nil, err
	}
	m := ph.m
	key := ph.key
	h := s.generation.Bind(key, func(ctx context.Context, arg memoize.Arg) interface{} {
		snapshot := arg.(*snapshot)
		var wg sync.WaitGroup
		for _, dep := range deps {
			wg.Add(1)
			go func(dep *packageHandle) {
				dep.check(ctx, snapshot)
				wg.Done()
			}(dep)
		}
		data := &packageData{}
		data.pkg, data.err = typeCheck(ctx, snapshot, m.Metadata, mode, deps)
		wg.Wait()
		return data
	}, nil)
	ph.handle = h
	ph = s.addPackageHandle(ph)
	return ph, nil
}
buildPackageHandle returns a packageHandle for a given package and mode.
It assumes that the given ID already has metadata available, so it does not
attempt to reload missing or invalid metadata. The caller must reload
metadata if needed.
package cache
import (
	"bytes"
	"context"
	"fmt"
	"go/ast"
	"go/types"
	"path"
	"path/filepath"
	"sort"
	"strings"
	"sync"
	"golang.org/x/mod/module"
	"golang.org/x/tools/go/ast/astutil"
	"golang.org/x/tools/go/packages"
	"github.com/govim/govim/cmd/govim/internal/golang_org_x_tools/event"
	"github.com/govim/govim/cmd/govim/internal/golang_org_x_tools/lsp/debug/tag"
	"github.com/govim/govim/cmd/govim/internal/golang_org_x_tools/lsp/protocol"
	"github.com/govim/govim/cmd/govim/internal/golang_org_x_tools/lsp/source"
	"github.com/govim/govim/cmd/govim/internal/golang_org_x_tools/memoize"
	"github.com/govim/govim/cmd/govim/internal/golang_org_x_tools/packagesinternal"
	"github.com/govim/govim/cmd/govim/internal/golang_org_x_tools/span"
	"github.com/govim/govim/cmd/govim/internal/golang_org_x_tools/typeparams"
	"github.com/govim/govim/cmd/govim/internal/golang_org_x_tools/typesinternal"
	errors "golang.org/x/xerrors"
)
type packageHandleKey string
type packageHandle struct {
	handle *memoize.Handle
	goFiles, compiledGoFiles []*parseGoHandle
	mode source.ParseMode
	m *KnownMetadata
	key packageHandleKey
}
func (ph *packageHandle) packageKey() packageKey {
	return packageKey{
		id:   ph.m.ID,
		mode: ph.mode,
	}
}
func (ph *packageHandle) imports(ctx context.Context, s source.Snapshot) (result []string) {
	for _, pgh := range ph.goFiles {
		f, err := s.ParseGo(ctx, pgh.file, source.ParseHeader)
		if err != nil {
			continue
		}
		seen := map[string]struct{}{}
		for _, impSpec := range f.File.Imports {
			imp := strings.Trim(impSpec.Path.Value, `"`)
			if _, ok := seen[imp]; !ok {
				seen[imp] = struct{}{}
				result = append(result, imp)
			}
		}
	}
	sort.Strings(result)
	return result
}
type packageData struct {
	pkg *pkg
	err error
}