func (h *Handle) wait(ctx context.Context) (interface{}, error) {
	h.waiters++
	done := h.done
	h.mu.Unlock()
	select {
	case <-done:
		h.mu.Lock()
		defer h.mu.Unlock()
		if h.state == stateCompleted {
			return h.value, nil
		}
		return nil, nil
	case <-ctx.Done():
		h.mu.Lock()
		defer h.mu.Unlock()
		h.waiters--
		if h.waiters == 0 && h.state == stateRunning {
			h.cancel()
			close(h.done)
			h.state = stateIdle
			h.done = nil
			h.cancel = nil
		}
		return nil, ctx.Err()
	}
}
wait waits for the value to be computed, or ctx to be cancelled. h.mu must be locked.
package memoize
import (
	"context"
	"flag"
	"fmt"
	"reflect"
	"sync"
	"sync/atomic"
	"github.com/govim/govim/cmd/govim/internal/golang_org_x_tools/xcontext"
)
var (
	panicOnDestroyed = flag.Bool("memoize_panic_on_destroyed", false,
		"Panic when a destroyed generation is read rather than returning an error. "+
			"Panicking may make it easier to debug lifetime errors, especially when "+
			"used with GOTRACEBACK=crash to see all running goroutines.")
)
type Store struct {
	mu sync.Mutex
	handles map[interface{}]*Handle
	generations map[*Generation]struct{}
}
func (s *Store) Generation(name string) *Generation {
	s.mu.Lock()
	defer s.mu.Unlock()
	if s.handles == nil {
		s.handles = map[interface{}]*Handle{}
		s.generations = map[*Generation]struct{}{}
	}
	g := &Generation{store: s, name: name}
	s.generations[g] = struct{}{}
	return g
}
type Generation struct {
	destroyed uint32
	store     *Store
	name      string
	wg sync.WaitGroup
}
func (g *Generation) Destroy() {
	g.wg.Wait()
	atomic.StoreUint32(&g.destroyed, 1)
	g.store.mu.Lock()
	defer g.store.mu.Unlock()
	for k, e := range g.store.handles {
		e.mu.Lock()
		if _, ok := e.generations[g]; ok {
			delete(e.generations, g)  
			if len(e.generations) == 0 {
				delete(g.store.handles, k)
				e.state = stateDestroyed
				if e.cleanup != nil && e.value != nil {
					e.cleanup(e.value)
				}
			}
		}
		e.mu.Unlock()
	}
	delete(g.store.generations, g)
}
func (g *Generation) Acquire(ctx context.Context) func() {
	destroyed := atomic.LoadUint32(&g.destroyed)
	if ctx.Err() != nil {
		return func() {}
	}
	if destroyed != 0 {
		panic("acquire on destroyed generation " + g.name)
	}
	g.wg.Add(1)
	return g.wg.Done
}
type Arg interface{ memoizeArg() }
type Function func(ctx context.Context, arg Arg) interface{}
type state int
const (
	stateIdle = iota
	stateRunning
	stateCompleted
	stateDestroyed
)
type Handle struct {
	key interface{}
	mu  sync.Mutex
	generations map[*Generation]struct{}
	state state
	done chan struct{}
	cancel context.CancelFunc
	waiters uint
	function Function
	value interface{}
	cleanup func(interface{})
}
func (g *Generation) Bind(key interface{}, function Function, cleanup func(interface{})) *Handle {
	if function == nil {
		panic("the function passed to bind must not be nil")
	}
	if atomic.LoadUint32(&g.destroyed) != 0 {
		panic("operation on destroyed generation " + g.name)
	}
	g.store.mu.Lock()
	defer g.store.mu.Unlock()
	h, ok := g.store.handles[key]
	if !ok {
		h := &Handle{
			key:         key,
			function:    function,
			generations: map[*Generation]struct{}{g: {}},
			cleanup:     cleanup,
		}
		g.store.handles[key] = h
		return h
	}
	h.mu.Lock()
	defer h.mu.Unlock()
	if _, ok := h.generations[g]; !ok {
		h.generations[g] = struct{}{}
	}
	return h
}
func (s *Store) Stats() map[reflect.Type]int {
	s.mu.Lock()
	defer s.mu.Unlock()
	result := map[reflect.Type]int{}
	for k := range s.handles {
		result[reflect.TypeOf(k)]++
	}
	return result
}
func (s *Store) DebugOnlyIterate(f func(k, v interface{})) {
	s.mu.Lock()
	defer s.mu.Unlock()
	for k, e := range s.handles {
		var v interface{}
		e.mu.Lock()
		if e.state == stateCompleted {
			v = e.value
		}
		e.mu.Unlock()
		if v == nil {
			continue
		}
		f(k, v)
	}
}
func (g *Generation) Inherit(hs ...*Handle) {
	for _, h := range hs {
		if atomic.LoadUint32(&g.destroyed) != 0 {
			panic("inherit on destroyed generation " + g.name)
		}
		h.mu.Lock()
		defer h.mu.Unlock()
		if h.state == stateDestroyed {
			panic(fmt.Sprintf("inheriting destroyed handle %#v (type %T) into generation %v", h.key, h.key, g.name))
		}
		h.generations[g] = struct{}{}
	}
}
func (h *Handle) Cached(g *Generation) interface{} {
	h.mu.Lock()
	defer h.mu.Unlock()
	if _, ok := h.generations[g]; !ok {
		return nil
	}
	if h.state == stateCompleted {
		return h.value
	}
	return nil
}
func (h *Handle) Get(ctx context.Context, g *Generation, arg Arg) (interface{}, error) {
	release := g.Acquire(ctx)
	defer release()
	if ctx.Err() != nil {
		return nil, ctx.Err()
	}
	h.mu.Lock()
	if _, ok := h.generations[g]; !ok {
		h.mu.Unlock()
		err := fmt.Errorf("reading key %#v: generation %v is not known", h.key, g.name)
		if *panicOnDestroyed && ctx.Err() != nil {
			panic(err)
		}
		return nil, err
	}
	switch h.state {
	case stateIdle:
		return h.run(ctx, g, arg)
	case stateRunning:
		return h.wait(ctx)
	case stateCompleted:
		defer h.mu.Unlock()
		return h.value, nil
	case stateDestroyed:
		h.mu.Unlock()
		err := fmt.Errorf("Get on destroyed entry %#v (type %T) in generation %v", h.key, h.key, g.name)
		if *panicOnDestroyed {
			panic(err)
		}
		return nil, err
	default:
		panic("unknown state")
	}
}
func (h *Handle) run(ctx context.Context, g *Generation, arg Arg) (interface{}, error) {
	childCtx, cancel := context.WithCancel(xcontext.Detach(ctx))
	h.cancel = cancel
	h.state = stateRunning
	h.done = make(chan struct{})
	function := h.function  
	release := g.Acquire(ctx)
	go func() {
		defer release()
		if childCtx.Err() != nil {
			return
		}
		v := function(childCtx, arg)
		if childCtx.Err() != nil {
			if h.cleanup != nil && v != nil {
				h.cleanup(v)
			}
			return
		}
		h.mu.Lock()
		defer h.mu.Unlock()
		if h.state != stateRunning {
			if h.cleanup != nil && v != nil {
				h.cleanup(v)
			}
			return
		}
		h.value = v
		h.function = nil
		h.state = stateCompleted
		close(h.done)
	}()
	return h.wait(ctx)
}