func (f *featureGate) KnownFeatures() []string {
	var known []string
	for k, v := range f.known.Load().(map[Feature]FeatureSpec) {
		pre := ""
		if v.PreRelease != GA {
			pre = fmt.Sprintf("%s - ", v.PreRelease)
		}
		known = append(known, fmt.Sprintf("%s=true|false (%sdefault=%t)", k, pre, v.Default))
	}
	sort.Strings(known)
	return known
}
KnownFeatures returns a slice of strings describing the FeatureGate's known features.
package feature
import (
	"fmt"
	"sort"
	"strconv"
	"strings"
	"sync"
	"sync/atomic"
	"github.com/golang/glog"
	"github.com/spf13/pflag"
)
type Feature string
const (
	flagName = "feature-gates"
	allAlphaGate Feature = "AllAlpha"
)
var (
	defaultFeatures = map[Feature]FeatureSpec{
		allAlphaGate: {Default: false, PreRelease: Alpha},
	}
	specialFeatures = map[Feature]func(known map[Feature]FeatureSpec, enabled map[Feature]bool, val bool){
		allAlphaGate: setUnsetAlphaGates,
	}
	DefaultFeatureGate FeatureGate = NewFeatureGate()
)
type FeatureSpec struct {
	Default    bool
	PreRelease prerelease
}
type prerelease string
const (
	Alpha = prerelease("ALPHA")
	Beta  = prerelease("BETA")
	GA    = prerelease("")
	Deprecated = prerelease("DEPRECATED")
)
type FeatureGate interface {
	AddFlag(fs *pflag.FlagSet)
	Set(value string) error
	SetFromMap(m map[string]bool) error
	Enabled(key Feature) bool
	Add(features map[Feature]FeatureSpec) error
	KnownFeatures() []string
}
type featureGate struct {
	special map[Feature]func(map[Feature]FeatureSpec, map[Feature]bool, bool)
	lock sync.Mutex
	known *atomic.Value
	enabled *atomic.Value
	closed bool
}
func setUnsetAlphaGates(known map[Feature]FeatureSpec, enabled map[Feature]bool, val bool) {
	for k, v := range known {
		if v.PreRelease == Alpha {
			if _, found := enabled[k]; !found {
				enabled[k] = val
			}
		}
	}
}
var _ pflag.Value = &featureGate{}
func NewFeatureGate() *featureGate {
	known := map[Feature]FeatureSpec{}
	for k, v := range defaultFeatures {
		known[k] = v
	}
	knownValue := &atomic.Value{}
	knownValue.Store(known)
	enabled := map[Feature]bool{}
	enabledValue := &atomic.Value{}
	enabledValue.Store(enabled)
	f := &featureGate{
		known:   knownValue,
		special: specialFeatures,
		enabled: enabledValue,
	}
	return f
}
func (f *featureGate) Set(value string) error {
	f.lock.Lock()
	defer f.lock.Unlock()
	known := map[Feature]FeatureSpec{}
	for k, v := range f.known.Load().(map[Feature]FeatureSpec) {
		known[k] = v
	}
	enabled := map[Feature]bool{}
	for k, v := range f.enabled.Load().(map[Feature]bool) {
		enabled[k] = v
	}
	for _, s := range strings.Split(value, ",") {
		if len(s) == 0 {
			continue
		}
		arr := strings.SplitN(s, "=", 2)
		k := Feature(strings.TrimSpace(arr[0]))
		featureSpec, ok := known[k]
		if !ok {
			return fmt.Errorf("unrecognized key: %s", k)
		}
		if len(arr) != 2 {
			return fmt.Errorf("missing bool value for %s", k)
		}
		v := strings.TrimSpace(arr[1])
		boolValue, err := strconv.ParseBool(v)
		if err != nil {
			return fmt.Errorf("invalid value of %s: %s, err: %v", k, v, err)
		}
		enabled[k] = boolValue
		if boolValue && featureSpec.PreRelease == Deprecated {
			glog.Warningf("enabling deprecated feature gate %s", k)
		}
		if fn, found := f.special[k]; found {
			fn(known, enabled, boolValue)
		}
	}
	f.known.Store(known)
	f.enabled.Store(enabled)
	glog.Infof("feature gates: %v", enabled)
	return nil
}
func (f *featureGate) SetFromMap(m map[string]bool) error {
	f.lock.Lock()
	defer f.lock.Unlock()
	known := map[Feature]FeatureSpec{}
	for k, v := range f.known.Load().(map[Feature]FeatureSpec) {
		known[k] = v
	}
	enabled := map[Feature]bool{}
	for k, v := range f.enabled.Load().(map[Feature]bool) {
		enabled[k] = v
	}
	for k, v := range m {
		k := Feature(k)
		_, ok := known[k]
		if !ok {
			return fmt.Errorf("unrecognized key: %s", k)
		}
		enabled[k] = v
		if fn, found := f.special[k]; found {
			fn(known, enabled, v)
		}
	}
	f.known.Store(known)
	f.enabled.Store(enabled)
	glog.Infof("feature gates: %v", f.enabled)
	return nil
}
func (f *featureGate) String() string {
	pairs := []string{}
	for k, v := range f.enabled.Load().(map[Feature]bool) {
		pairs = append(pairs, fmt.Sprintf("%s=%t", k, v))
	}
	sort.Strings(pairs)
	return strings.Join(pairs, ",")
}
func (f *featureGate) Type() string {
	return "mapStringBool"
}
func (f *featureGate) Add(features map[Feature]FeatureSpec) error {
	f.lock.Lock()
	defer f.lock.Unlock()
	if f.closed {
		return fmt.Errorf("cannot add a feature gate after adding it to the flag set")
	}
	known := map[Feature]FeatureSpec{}
	for k, v := range f.known.Load().(map[Feature]FeatureSpec) {
		known[k] = v
	}
	for name, spec := range features {
		if existingSpec, found := known[name]; found {
			if existingSpec == spec {
				continue
			}
			return fmt.Errorf("feature gate %q with different spec already exists: %v", name, existingSpec)
		}
		known[name] = spec
	}
	f.known.Store(known)
	return nil
}
func (f *featureGate) Enabled(key Feature) bool {
	if v, ok := f.enabled.Load().(map[Feature]bool)[key]; ok {
		return v
	}
	return f.known.Load().(map[Feature]FeatureSpec)[key].Default
}
func (f *featureGate) AddFlag(fs *pflag.FlagSet) {
	f.lock.Lock()
	f.closed = true
	f.lock.Unlock()
	known := f.KnownFeatures()
	fs.Var(f, flagName, ""+
		"A set of key=value pairs that describe feature gates for alpha/experimental features. "+
		"Options are:\n"+strings.Join(known, "\n"))
}