git subrepo clone (merge) https://github.com/kubernetes-incubator/metrics-server.git metrics-server
subrepo:
subdir: "metrics-server"
merged: "92d8412"
upstream:
origin: "https://github.com/kubernetes-incubator/metrics-server.git"
branch: "master"
commit: "92d8412"
git-subrepo:
version: "0.4.0"
origin: "???"
commit: "???"
diff --git a/metrics-server/vendor/k8s.io/gengo/LICENSE b/metrics-server/vendor/k8s.io/gengo/LICENSE
new file mode 100644
index 0000000..00b2401
--- /dev/null
+++ b/metrics-server/vendor/k8s.io/gengo/LICENSE
@@ -0,0 +1,202 @@
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor 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, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright 2014 The Kubernetes 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.
diff --git a/metrics-server/vendor/k8s.io/gengo/args/args.go b/metrics-server/vendor/k8s.io/gengo/args/args.go
new file mode 100644
index 0000000..2f8680d
--- /dev/null
+++ b/metrics-server/vendor/k8s.io/gengo/args/args.go
@@ -0,0 +1,199 @@
+/*
+Copyright 2015 The Kubernetes 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 args has common command-line flags for generation programs.
+package args
+
+import (
+ "bytes"
+ goflag "flag"
+ "fmt"
+ "io/ioutil"
+ "os"
+ "path"
+ "path/filepath"
+ "strconv"
+ "strings"
+ "time"
+
+ "k8s.io/gengo/generator"
+ "k8s.io/gengo/namer"
+ "k8s.io/gengo/parser"
+ "k8s.io/gengo/types"
+
+ "github.com/spf13/pflag"
+)
+
+// Default returns a defaulted GeneratorArgs. You may change the defaults
+// before calling AddFlags.
+func Default() *GeneratorArgs {
+ return &GeneratorArgs{
+ OutputBase: DefaultSourceTree(),
+ GoHeaderFilePath: filepath.Join(DefaultSourceTree(), "k8s.io/gengo/boilerplate/boilerplate.go.txt"),
+ GeneratedBuildTag: "ignore_autogenerated",
+ GeneratedByCommentTemplate: "// Code generated by GENERATOR_NAME. DO NOT EDIT.",
+ defaultCommandLineFlags: true,
+ }
+}
+
+// GeneratorArgs has arguments that are passed to generators.
+type GeneratorArgs struct {
+ // Which directories to parse.
+ InputDirs []string
+
+ // Source tree to write results to.
+ OutputBase string
+
+ // Package path within the source tree.
+ OutputPackagePath string
+
+ // Output file name.
+ OutputFileBaseName string
+
+ // Where to get copyright header text.
+ GoHeaderFilePath string
+
+ // If GeneratedByCommentTemplate is set, generate a "Code generated by" comment
+ // below the bloilerplate, of the format defined by this string.
+ // Any instances of "GENERATOR_NAME" will be replaced with the name of the code generator.
+ GeneratedByCommentTemplate string
+
+ // If true, only verify, don't write anything.
+ VerifyOnly bool
+
+ // GeneratedBuildTag is the tag used to identify code generated by execution
+ // of this type. Each generator should use a different tag, and different
+ // groups of generators (external API that depends on Kube generations) should
+ // keep tags distinct as well.
+ GeneratedBuildTag string
+
+ // Any custom arguments go here
+ CustomArgs interface{}
+
+ // Whether to use default command line flags
+ defaultCommandLineFlags bool
+}
+
+// WithoutDefaultFlagParsing disables implicit addition of command line flags and parsing.
+func (g *GeneratorArgs) WithoutDefaultFlagParsing() *GeneratorArgs {
+ g.defaultCommandLineFlags = false
+ return g
+}
+
+func (g *GeneratorArgs) AddFlags(fs *pflag.FlagSet) {
+ fs.StringSliceVarP(&g.InputDirs, "input-dirs", "i", g.InputDirs, "Comma-separated list of import paths to get input types from.")
+ fs.StringVarP(&g.OutputBase, "output-base", "o", g.OutputBase, "Output base; defaults to $GOPATH/src/ or ./ if $GOPATH is not set.")
+ fs.StringVarP(&g.OutputPackagePath, "output-package", "p", g.OutputPackagePath, "Base package path.")
+ fs.StringVarP(&g.OutputFileBaseName, "output-file-base", "O", g.OutputFileBaseName, "Base name (without .go suffix) for output files.")
+ fs.StringVarP(&g.GoHeaderFilePath, "go-header-file", "h", g.GoHeaderFilePath, "File containing boilerplate header text. The string YEAR will be replaced with the current 4-digit year.")
+ fs.BoolVar(&g.VerifyOnly, "verify-only", g.VerifyOnly, "If true, only verify existing output, do not write anything.")
+ fs.StringVar(&g.GeneratedBuildTag, "build-tag", g.GeneratedBuildTag, "A Go build tag to use to identify files generated by this command. Should be unique.")
+}
+
+// LoadGoBoilerplate loads the boilerplate file passed to --go-header-file.
+func (g *GeneratorArgs) LoadGoBoilerplate() ([]byte, error) {
+ b, err := ioutil.ReadFile(g.GoHeaderFilePath)
+ if err != nil {
+ return nil, err
+ }
+ b = bytes.Replace(b, []byte("YEAR"), []byte(strconv.Itoa(time.Now().Year())), -1)
+
+ if g.GeneratedByCommentTemplate != "" {
+ if len(b) != 0 {
+ b = append(b, byte('\n'))
+ }
+ generatorName := path.Base(os.Args[0])
+ generatedByComment := strings.Replace(g.GeneratedByCommentTemplate, "GENERATOR_NAME", generatorName, -1)
+ s := fmt.Sprintf("%s\n\n", generatedByComment)
+ b = append(b, []byte(s)...)
+ }
+ return b, nil
+}
+
+// NewBuilder makes a new parser.Builder and populates it with the input
+// directories.
+func (g *GeneratorArgs) NewBuilder() (*parser.Builder, error) {
+ b := parser.New()
+ // Ignore all auto-generated files.
+ b.AddBuildTags(g.GeneratedBuildTag)
+
+ for _, d := range g.InputDirs {
+ var err error
+ if strings.HasSuffix(d, "/...") {
+ err = b.AddDirRecursive(strings.TrimSuffix(d, "/..."))
+ } else {
+ err = b.AddDir(d)
+ }
+ if err != nil {
+ return nil, fmt.Errorf("unable to add directory %q: %v", d, err)
+ }
+ }
+ return b, nil
+}
+
+// InputIncludes returns true if the given package is a (sub) package of one of
+// the InputDirs.
+func (g *GeneratorArgs) InputIncludes(p *types.Package) bool {
+ for _, dir := range g.InputDirs {
+ d := dir
+ if strings.HasSuffix(d, "...") {
+ d = strings.TrimSuffix(d, "...")
+ }
+ if strings.HasPrefix(p.Path, d) {
+ return true
+ }
+ }
+ return false
+}
+
+// DefaultSourceTree returns the /src directory of the first entry in $GOPATH.
+// If $GOPATH is empty, it returns "./". Useful as a default output location.
+func DefaultSourceTree() string {
+ paths := strings.Split(os.Getenv("GOPATH"), string(filepath.ListSeparator))
+ if len(paths) > 0 && len(paths[0]) > 0 {
+ return filepath.Join(paths[0], "src")
+ }
+ return "./"
+}
+
+// Execute implements main().
+// If you don't need any non-default behavior, use as:
+// args.Default().Execute(...)
+func (g *GeneratorArgs) Execute(nameSystems namer.NameSystems, defaultSystem string, pkgs func(*generator.Context, *GeneratorArgs) generator.Packages) error {
+ if g.defaultCommandLineFlags {
+ g.AddFlags(pflag.CommandLine)
+ pflag.CommandLine.AddGoFlagSet(goflag.CommandLine)
+ pflag.Parse()
+ }
+
+ b, err := g.NewBuilder()
+ if err != nil {
+ return fmt.Errorf("Failed making a parser: %v", err)
+ }
+
+ c, err := generator.NewContext(b, nameSystems, defaultSystem)
+ if err != nil {
+ return fmt.Errorf("Failed making a context: %v", err)
+ }
+
+ c.Verify = g.VerifyOnly
+ packages := pkgs(c, g)
+ if err := c.ExecutePackages(g.OutputBase, packages); err != nil {
+ return fmt.Errorf("Failed executing generator: %v", err)
+ }
+
+ return nil
+}
diff --git a/metrics-server/vendor/k8s.io/gengo/examples/set-gen/sets/byte.go b/metrics-server/vendor/k8s.io/gengo/examples/set-gen/sets/byte.go
new file mode 100644
index 0000000..766f450
--- /dev/null
+++ b/metrics-server/vendor/k8s.io/gengo/examples/set-gen/sets/byte.go
@@ -0,0 +1,203 @@
+/*
+Copyright The Kubernetes 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.
+*/
+
+// Code generated by set-gen. DO NOT EDIT.
+
+package sets
+
+import (
+ "reflect"
+ "sort"
+)
+
+// sets.Byte is a set of bytes, implemented via map[byte]struct{} for minimal memory consumption.
+type Byte map[byte]Empty
+
+// NewByte creates a Byte from a list of values.
+func NewByte(items ...byte) Byte {
+ ss := Byte{}
+ ss.Insert(items...)
+ return ss
+}
+
+// ByteKeySet creates a Byte from a keys of a map[byte](? extends interface{}).
+// If the value passed in is not actually a map, this will panic.
+func ByteKeySet(theMap interface{}) Byte {
+ v := reflect.ValueOf(theMap)
+ ret := Byte{}
+
+ for _, keyValue := range v.MapKeys() {
+ ret.Insert(keyValue.Interface().(byte))
+ }
+ return ret
+}
+
+// Insert adds items to the set.
+func (s Byte) Insert(items ...byte) {
+ for _, item := range items {
+ s[item] = Empty{}
+ }
+}
+
+// Delete removes all items from the set.
+func (s Byte) Delete(items ...byte) {
+ for _, item := range items {
+ delete(s, item)
+ }
+}
+
+// Has returns true if and only if item is contained in the set.
+func (s Byte) Has(item byte) bool {
+ _, contained := s[item]
+ return contained
+}
+
+// HasAll returns true if and only if all items are contained in the set.
+func (s Byte) HasAll(items ...byte) bool {
+ for _, item := range items {
+ if !s.Has(item) {
+ return false
+ }
+ }
+ return true
+}
+
+// HasAny returns true if any items are contained in the set.
+func (s Byte) HasAny(items ...byte) bool {
+ for _, item := range items {
+ if s.Has(item) {
+ return true
+ }
+ }
+ return false
+}
+
+// Difference returns a set of objects that are not in s2
+// For example:
+// s1 = {a1, a2, a3}
+// s2 = {a1, a2, a4, a5}
+// s1.Difference(s2) = {a3}
+// s2.Difference(s1) = {a4, a5}
+func (s Byte) Difference(s2 Byte) Byte {
+ result := NewByte()
+ for key := range s {
+ if !s2.Has(key) {
+ result.Insert(key)
+ }
+ }
+ return result
+}
+
+// Union returns a new set which includes items in either s1 or s2.
+// For example:
+// s1 = {a1, a2}
+// s2 = {a3, a4}
+// s1.Union(s2) = {a1, a2, a3, a4}
+// s2.Union(s1) = {a1, a2, a3, a4}
+func (s1 Byte) Union(s2 Byte) Byte {
+ result := NewByte()
+ for key := range s1 {
+ result.Insert(key)
+ }
+ for key := range s2 {
+ result.Insert(key)
+ }
+ return result
+}
+
+// Intersection returns a new set which includes the item in BOTH s1 and s2
+// For example:
+// s1 = {a1, a2}
+// s2 = {a2, a3}
+// s1.Intersection(s2) = {a2}
+func (s1 Byte) Intersection(s2 Byte) Byte {
+ var walk, other Byte
+ result := NewByte()
+ if s1.Len() < s2.Len() {
+ walk = s1
+ other = s2
+ } else {
+ walk = s2
+ other = s1
+ }
+ for key := range walk {
+ if other.Has(key) {
+ result.Insert(key)
+ }
+ }
+ return result
+}
+
+// IsSuperset returns true if and only if s1 is a superset of s2.
+func (s1 Byte) IsSuperset(s2 Byte) bool {
+ for item := range s2 {
+ if !s1.Has(item) {
+ return false
+ }
+ }
+ return true
+}
+
+// Equal returns true if and only if s1 is equal (as a set) to s2.
+// Two sets are equal if their membership is identical.
+// (In practice, this means same elements, order doesn't matter)
+func (s1 Byte) Equal(s2 Byte) bool {
+ return len(s1) == len(s2) && s1.IsSuperset(s2)
+}
+
+type sortableSliceOfByte []byte
+
+func (s sortableSliceOfByte) Len() int { return len(s) }
+func (s sortableSliceOfByte) Less(i, j int) bool { return lessByte(s[i], s[j]) }
+func (s sortableSliceOfByte) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
+
+// List returns the contents as a sorted byte slice.
+func (s Byte) List() []byte {
+ res := make(sortableSliceOfByte, 0, len(s))
+ for key := range s {
+ res = append(res, key)
+ }
+ sort.Sort(res)
+ return []byte(res)
+}
+
+// UnsortedList returns the slice with contents in random order.
+func (s Byte) UnsortedList() []byte {
+ res := make([]byte, 0, len(s))
+ for key := range s {
+ res = append(res, key)
+ }
+ return res
+}
+
+// Returns a single element from the set.
+func (s Byte) PopAny() (byte, bool) {
+ for key := range s {
+ s.Delete(key)
+ return key, true
+ }
+ var zeroValue byte
+ return zeroValue, false
+}
+
+// Len returns the size of the set.
+func (s Byte) Len() int {
+ return len(s)
+}
+
+func lessByte(lhs, rhs byte) bool {
+ return lhs < rhs
+}
diff --git a/metrics-server/vendor/k8s.io/gengo/examples/set-gen/sets/doc.go b/metrics-server/vendor/k8s.io/gengo/examples/set-gen/sets/doc.go
new file mode 100644
index 0000000..b152a0b
--- /dev/null
+++ b/metrics-server/vendor/k8s.io/gengo/examples/set-gen/sets/doc.go
@@ -0,0 +1,20 @@
+/*
+Copyright The Kubernetes 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.
+*/
+
+// Code generated by set-gen. DO NOT EDIT.
+
+// Package sets has auto-generated set types.
+package sets
diff --git a/metrics-server/vendor/k8s.io/gengo/examples/set-gen/sets/empty.go b/metrics-server/vendor/k8s.io/gengo/examples/set-gen/sets/empty.go
new file mode 100644
index 0000000..e11e622
--- /dev/null
+++ b/metrics-server/vendor/k8s.io/gengo/examples/set-gen/sets/empty.go
@@ -0,0 +1,23 @@
+/*
+Copyright The Kubernetes 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.
+*/
+
+// Code generated by set-gen. DO NOT EDIT.
+
+package sets
+
+// Empty is public since it is used by some internal API objects for conversions between external
+// string arrays and internal sets, and conversion logic requires public types today.
+type Empty struct{}
diff --git a/metrics-server/vendor/k8s.io/gengo/examples/set-gen/sets/int.go b/metrics-server/vendor/k8s.io/gengo/examples/set-gen/sets/int.go
new file mode 100644
index 0000000..a0a513c
--- /dev/null
+++ b/metrics-server/vendor/k8s.io/gengo/examples/set-gen/sets/int.go
@@ -0,0 +1,203 @@
+/*
+Copyright The Kubernetes 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.
+*/
+
+// Code generated by set-gen. DO NOT EDIT.
+
+package sets
+
+import (
+ "reflect"
+ "sort"
+)
+
+// sets.Int is a set of ints, implemented via map[int]struct{} for minimal memory consumption.
+type Int map[int]Empty
+
+// NewInt creates a Int from a list of values.
+func NewInt(items ...int) Int {
+ ss := Int{}
+ ss.Insert(items...)
+ return ss
+}
+
+// IntKeySet creates a Int from a keys of a map[int](? extends interface{}).
+// If the value passed in is not actually a map, this will panic.
+func IntKeySet(theMap interface{}) Int {
+ v := reflect.ValueOf(theMap)
+ ret := Int{}
+
+ for _, keyValue := range v.MapKeys() {
+ ret.Insert(keyValue.Interface().(int))
+ }
+ return ret
+}
+
+// Insert adds items to the set.
+func (s Int) Insert(items ...int) {
+ for _, item := range items {
+ s[item] = Empty{}
+ }
+}
+
+// Delete removes all items from the set.
+func (s Int) Delete(items ...int) {
+ for _, item := range items {
+ delete(s, item)
+ }
+}
+
+// Has returns true if and only if item is contained in the set.
+func (s Int) Has(item int) bool {
+ _, contained := s[item]
+ return contained
+}
+
+// HasAll returns true if and only if all items are contained in the set.
+func (s Int) HasAll(items ...int) bool {
+ for _, item := range items {
+ if !s.Has(item) {
+ return false
+ }
+ }
+ return true
+}
+
+// HasAny returns true if any items are contained in the set.
+func (s Int) HasAny(items ...int) bool {
+ for _, item := range items {
+ if s.Has(item) {
+ return true
+ }
+ }
+ return false
+}
+
+// Difference returns a set of objects that are not in s2
+// For example:
+// s1 = {a1, a2, a3}
+// s2 = {a1, a2, a4, a5}
+// s1.Difference(s2) = {a3}
+// s2.Difference(s1) = {a4, a5}
+func (s Int) Difference(s2 Int) Int {
+ result := NewInt()
+ for key := range s {
+ if !s2.Has(key) {
+ result.Insert(key)
+ }
+ }
+ return result
+}
+
+// Union returns a new set which includes items in either s1 or s2.
+// For example:
+// s1 = {a1, a2}
+// s2 = {a3, a4}
+// s1.Union(s2) = {a1, a2, a3, a4}
+// s2.Union(s1) = {a1, a2, a3, a4}
+func (s1 Int) Union(s2 Int) Int {
+ result := NewInt()
+ for key := range s1 {
+ result.Insert(key)
+ }
+ for key := range s2 {
+ result.Insert(key)
+ }
+ return result
+}
+
+// Intersection returns a new set which includes the item in BOTH s1 and s2
+// For example:
+// s1 = {a1, a2}
+// s2 = {a2, a3}
+// s1.Intersection(s2) = {a2}
+func (s1 Int) Intersection(s2 Int) Int {
+ var walk, other Int
+ result := NewInt()
+ if s1.Len() < s2.Len() {
+ walk = s1
+ other = s2
+ } else {
+ walk = s2
+ other = s1
+ }
+ for key := range walk {
+ if other.Has(key) {
+ result.Insert(key)
+ }
+ }
+ return result
+}
+
+// IsSuperset returns true if and only if s1 is a superset of s2.
+func (s1 Int) IsSuperset(s2 Int) bool {
+ for item := range s2 {
+ if !s1.Has(item) {
+ return false
+ }
+ }
+ return true
+}
+
+// Equal returns true if and only if s1 is equal (as a set) to s2.
+// Two sets are equal if their membership is identical.
+// (In practice, this means same elements, order doesn't matter)
+func (s1 Int) Equal(s2 Int) bool {
+ return len(s1) == len(s2) && s1.IsSuperset(s2)
+}
+
+type sortableSliceOfInt []int
+
+func (s sortableSliceOfInt) Len() int { return len(s) }
+func (s sortableSliceOfInt) Less(i, j int) bool { return lessInt(s[i], s[j]) }
+func (s sortableSliceOfInt) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
+
+// List returns the contents as a sorted int slice.
+func (s Int) List() []int {
+ res := make(sortableSliceOfInt, 0, len(s))
+ for key := range s {
+ res = append(res, key)
+ }
+ sort.Sort(res)
+ return []int(res)
+}
+
+// UnsortedList returns the slice with contents in random order.
+func (s Int) UnsortedList() []int {
+ res := make([]int, 0, len(s))
+ for key := range s {
+ res = append(res, key)
+ }
+ return res
+}
+
+// Returns a single element from the set.
+func (s Int) PopAny() (int, bool) {
+ for key := range s {
+ s.Delete(key)
+ return key, true
+ }
+ var zeroValue int
+ return zeroValue, false
+}
+
+// Len returns the size of the set.
+func (s Int) Len() int {
+ return len(s)
+}
+
+func lessInt(lhs, rhs int) bool {
+ return lhs < rhs
+}
diff --git a/metrics-server/vendor/k8s.io/gengo/examples/set-gen/sets/int64.go b/metrics-server/vendor/k8s.io/gengo/examples/set-gen/sets/int64.go
new file mode 100644
index 0000000..9ca9af0
--- /dev/null
+++ b/metrics-server/vendor/k8s.io/gengo/examples/set-gen/sets/int64.go
@@ -0,0 +1,203 @@
+/*
+Copyright The Kubernetes 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.
+*/
+
+// Code generated by set-gen. DO NOT EDIT.
+
+package sets
+
+import (
+ "reflect"
+ "sort"
+)
+
+// sets.Int64 is a set of int64s, implemented via map[int64]struct{} for minimal memory consumption.
+type Int64 map[int64]Empty
+
+// NewInt64 creates a Int64 from a list of values.
+func NewInt64(items ...int64) Int64 {
+ ss := Int64{}
+ ss.Insert(items...)
+ return ss
+}
+
+// Int64KeySet creates a Int64 from a keys of a map[int64](? extends interface{}).
+// If the value passed in is not actually a map, this will panic.
+func Int64KeySet(theMap interface{}) Int64 {
+ v := reflect.ValueOf(theMap)
+ ret := Int64{}
+
+ for _, keyValue := range v.MapKeys() {
+ ret.Insert(keyValue.Interface().(int64))
+ }
+ return ret
+}
+
+// Insert adds items to the set.
+func (s Int64) Insert(items ...int64) {
+ for _, item := range items {
+ s[item] = Empty{}
+ }
+}
+
+// Delete removes all items from the set.
+func (s Int64) Delete(items ...int64) {
+ for _, item := range items {
+ delete(s, item)
+ }
+}
+
+// Has returns true if and only if item is contained in the set.
+func (s Int64) Has(item int64) bool {
+ _, contained := s[item]
+ return contained
+}
+
+// HasAll returns true if and only if all items are contained in the set.
+func (s Int64) HasAll(items ...int64) bool {
+ for _, item := range items {
+ if !s.Has(item) {
+ return false
+ }
+ }
+ return true
+}
+
+// HasAny returns true if any items are contained in the set.
+func (s Int64) HasAny(items ...int64) bool {
+ for _, item := range items {
+ if s.Has(item) {
+ return true
+ }
+ }
+ return false
+}
+
+// Difference returns a set of objects that are not in s2
+// For example:
+// s1 = {a1, a2, a3}
+// s2 = {a1, a2, a4, a5}
+// s1.Difference(s2) = {a3}
+// s2.Difference(s1) = {a4, a5}
+func (s Int64) Difference(s2 Int64) Int64 {
+ result := NewInt64()
+ for key := range s {
+ if !s2.Has(key) {
+ result.Insert(key)
+ }
+ }
+ return result
+}
+
+// Union returns a new set which includes items in either s1 or s2.
+// For example:
+// s1 = {a1, a2}
+// s2 = {a3, a4}
+// s1.Union(s2) = {a1, a2, a3, a4}
+// s2.Union(s1) = {a1, a2, a3, a4}
+func (s1 Int64) Union(s2 Int64) Int64 {
+ result := NewInt64()
+ for key := range s1 {
+ result.Insert(key)
+ }
+ for key := range s2 {
+ result.Insert(key)
+ }
+ return result
+}
+
+// Intersection returns a new set which includes the item in BOTH s1 and s2
+// For example:
+// s1 = {a1, a2}
+// s2 = {a2, a3}
+// s1.Intersection(s2) = {a2}
+func (s1 Int64) Intersection(s2 Int64) Int64 {
+ var walk, other Int64
+ result := NewInt64()
+ if s1.Len() < s2.Len() {
+ walk = s1
+ other = s2
+ } else {
+ walk = s2
+ other = s1
+ }
+ for key := range walk {
+ if other.Has(key) {
+ result.Insert(key)
+ }
+ }
+ return result
+}
+
+// IsSuperset returns true if and only if s1 is a superset of s2.
+func (s1 Int64) IsSuperset(s2 Int64) bool {
+ for item := range s2 {
+ if !s1.Has(item) {
+ return false
+ }
+ }
+ return true
+}
+
+// Equal returns true if and only if s1 is equal (as a set) to s2.
+// Two sets are equal if their membership is identical.
+// (In practice, this means same elements, order doesn't matter)
+func (s1 Int64) Equal(s2 Int64) bool {
+ return len(s1) == len(s2) && s1.IsSuperset(s2)
+}
+
+type sortableSliceOfInt64 []int64
+
+func (s sortableSliceOfInt64) Len() int { return len(s) }
+func (s sortableSliceOfInt64) Less(i, j int) bool { return lessInt64(s[i], s[j]) }
+func (s sortableSliceOfInt64) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
+
+// List returns the contents as a sorted int64 slice.
+func (s Int64) List() []int64 {
+ res := make(sortableSliceOfInt64, 0, len(s))
+ for key := range s {
+ res = append(res, key)
+ }
+ sort.Sort(res)
+ return []int64(res)
+}
+
+// UnsortedList returns the slice with contents in random order.
+func (s Int64) UnsortedList() []int64 {
+ res := make([]int64, 0, len(s))
+ for key := range s {
+ res = append(res, key)
+ }
+ return res
+}
+
+// Returns a single element from the set.
+func (s Int64) PopAny() (int64, bool) {
+ for key := range s {
+ s.Delete(key)
+ return key, true
+ }
+ var zeroValue int64
+ return zeroValue, false
+}
+
+// Len returns the size of the set.
+func (s Int64) Len() int {
+ return len(s)
+}
+
+func lessInt64(lhs, rhs int64) bool {
+ return lhs < rhs
+}
diff --git a/metrics-server/vendor/k8s.io/gengo/examples/set-gen/sets/string.go b/metrics-server/vendor/k8s.io/gengo/examples/set-gen/sets/string.go
new file mode 100644
index 0000000..ba00ad7
--- /dev/null
+++ b/metrics-server/vendor/k8s.io/gengo/examples/set-gen/sets/string.go
@@ -0,0 +1,203 @@
+/*
+Copyright The Kubernetes 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.
+*/
+
+// Code generated by set-gen. DO NOT EDIT.
+
+package sets
+
+import (
+ "reflect"
+ "sort"
+)
+
+// sets.String is a set of strings, implemented via map[string]struct{} for minimal memory consumption.
+type String map[string]Empty
+
+// NewString creates a String from a list of values.
+func NewString(items ...string) String {
+ ss := String{}
+ ss.Insert(items...)
+ return ss
+}
+
+// StringKeySet creates a String from a keys of a map[string](? extends interface{}).
+// If the value passed in is not actually a map, this will panic.
+func StringKeySet(theMap interface{}) String {
+ v := reflect.ValueOf(theMap)
+ ret := String{}
+
+ for _, keyValue := range v.MapKeys() {
+ ret.Insert(keyValue.Interface().(string))
+ }
+ return ret
+}
+
+// Insert adds items to the set.
+func (s String) Insert(items ...string) {
+ for _, item := range items {
+ s[item] = Empty{}
+ }
+}
+
+// Delete removes all items from the set.
+func (s String) Delete(items ...string) {
+ for _, item := range items {
+ delete(s, item)
+ }
+}
+
+// Has returns true if and only if item is contained in the set.
+func (s String) Has(item string) bool {
+ _, contained := s[item]
+ return contained
+}
+
+// HasAll returns true if and only if all items are contained in the set.
+func (s String) HasAll(items ...string) bool {
+ for _, item := range items {
+ if !s.Has(item) {
+ return false
+ }
+ }
+ return true
+}
+
+// HasAny returns true if any items are contained in the set.
+func (s String) HasAny(items ...string) bool {
+ for _, item := range items {
+ if s.Has(item) {
+ return true
+ }
+ }
+ return false
+}
+
+// Difference returns a set of objects that are not in s2
+// For example:
+// s1 = {a1, a2, a3}
+// s2 = {a1, a2, a4, a5}
+// s1.Difference(s2) = {a3}
+// s2.Difference(s1) = {a4, a5}
+func (s String) Difference(s2 String) String {
+ result := NewString()
+ for key := range s {
+ if !s2.Has(key) {
+ result.Insert(key)
+ }
+ }
+ return result
+}
+
+// Union returns a new set which includes items in either s1 or s2.
+// For example:
+// s1 = {a1, a2}
+// s2 = {a3, a4}
+// s1.Union(s2) = {a1, a2, a3, a4}
+// s2.Union(s1) = {a1, a2, a3, a4}
+func (s1 String) Union(s2 String) String {
+ result := NewString()
+ for key := range s1 {
+ result.Insert(key)
+ }
+ for key := range s2 {
+ result.Insert(key)
+ }
+ return result
+}
+
+// Intersection returns a new set which includes the item in BOTH s1 and s2
+// For example:
+// s1 = {a1, a2}
+// s2 = {a2, a3}
+// s1.Intersection(s2) = {a2}
+func (s1 String) Intersection(s2 String) String {
+ var walk, other String
+ result := NewString()
+ if s1.Len() < s2.Len() {
+ walk = s1
+ other = s2
+ } else {
+ walk = s2
+ other = s1
+ }
+ for key := range walk {
+ if other.Has(key) {
+ result.Insert(key)
+ }
+ }
+ return result
+}
+
+// IsSuperset returns true if and only if s1 is a superset of s2.
+func (s1 String) IsSuperset(s2 String) bool {
+ for item := range s2 {
+ if !s1.Has(item) {
+ return false
+ }
+ }
+ return true
+}
+
+// Equal returns true if and only if s1 is equal (as a set) to s2.
+// Two sets are equal if their membership is identical.
+// (In practice, this means same elements, order doesn't matter)
+func (s1 String) Equal(s2 String) bool {
+ return len(s1) == len(s2) && s1.IsSuperset(s2)
+}
+
+type sortableSliceOfString []string
+
+func (s sortableSliceOfString) Len() int { return len(s) }
+func (s sortableSliceOfString) Less(i, j int) bool { return lessString(s[i], s[j]) }
+func (s sortableSliceOfString) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
+
+// List returns the contents as a sorted string slice.
+func (s String) List() []string {
+ res := make(sortableSliceOfString, 0, len(s))
+ for key := range s {
+ res = append(res, key)
+ }
+ sort.Sort(res)
+ return []string(res)
+}
+
+// UnsortedList returns the slice with contents in random order.
+func (s String) UnsortedList() []string {
+ res := make([]string, 0, len(s))
+ for key := range s {
+ res = append(res, key)
+ }
+ return res
+}
+
+// Returns a single element from the set.
+func (s String) PopAny() (string, bool) {
+ for key := range s {
+ s.Delete(key)
+ return key, true
+ }
+ var zeroValue string
+ return zeroValue, false
+}
+
+// Len returns the size of the set.
+func (s String) Len() int {
+ return len(s)
+}
+
+func lessString(lhs, rhs string) bool {
+ return lhs < rhs
+}
diff --git a/metrics-server/vendor/k8s.io/gengo/generator/default_generator.go b/metrics-server/vendor/k8s.io/gengo/generator/default_generator.go
new file mode 100644
index 0000000..f947668
--- /dev/null
+++ b/metrics-server/vendor/k8s.io/gengo/generator/default_generator.go
@@ -0,0 +1,62 @@
+/*
+Copyright 2015 The Kubernetes 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 generator
+
+import (
+ "io"
+
+ "k8s.io/gengo/namer"
+ "k8s.io/gengo/types"
+)
+
+const (
+ GolangFileType = "golang"
+)
+
+// DefaultGen implements a do-nothing Generator.
+//
+// It can be used to implement static content files.
+type DefaultGen struct {
+ // OptionalName, if present, will be used for the generator's name, and
+ // the filename (with ".go" appended).
+ OptionalName string
+
+ // OptionalBody, if present, will be used as the return from the "Init"
+ // method. This causes it to be static content for the entire file if
+ // no other generator touches the file.
+ OptionalBody []byte
+}
+
+func (d DefaultGen) Name() string { return d.OptionalName }
+func (d DefaultGen) Filter(*Context, *types.Type) bool { return true }
+func (d DefaultGen) Namers(*Context) namer.NameSystems { return nil }
+func (d DefaultGen) Imports(*Context) []string { return []string{} }
+func (d DefaultGen) PackageVars(*Context) []string { return []string{} }
+func (d DefaultGen) PackageConsts(*Context) []string { return []string{} }
+func (d DefaultGen) GenerateType(*Context, *types.Type, io.Writer) error { return nil }
+func (d DefaultGen) Filename() string { return d.OptionalName + ".go" }
+func (d DefaultGen) FileType() string { return GolangFileType }
+func (d DefaultGen) Finalize(*Context, io.Writer) error { return nil }
+
+func (d DefaultGen) Init(c *Context, w io.Writer) error {
+ _, err := w.Write(d.OptionalBody)
+ return err
+}
+
+var (
+ _ = Generator(DefaultGen{})
+)
diff --git a/metrics-server/vendor/k8s.io/gengo/generator/default_package.go b/metrics-server/vendor/k8s.io/gengo/generator/default_package.go
new file mode 100644
index 0000000..11517fc
--- /dev/null
+++ b/metrics-server/vendor/k8s.io/gengo/generator/default_package.go
@@ -0,0 +1,72 @@
+/*
+Copyright 2015 The Kubernetes 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 generator
+
+import (
+ "k8s.io/gengo/types"
+)
+
+// DefaultPackage contains a default implementation of Package.
+type DefaultPackage struct {
+ // Short name of package, used in the "package xxxx" line.
+ PackageName string
+ // Import path of the package, and the location on disk of the package.
+ PackagePath string
+
+ // Emitted at the top of every file.
+ HeaderText []byte
+
+ // Emitted only for a "doc.go" file; appended to the HeaderText for
+ // that file.
+ PackageDocumentation []byte
+
+ // If non-nil, will be called on "Generators"; otherwise, the static
+ // list will be used. So you should set only one of these two fields.
+ GeneratorFunc func(*Context) []Generator
+ GeneratorList []Generator
+
+ // Optional; filters the types exposed to the generators.
+ FilterFunc func(*Context, *types.Type) bool
+}
+
+func (d *DefaultPackage) Name() string { return d.PackageName }
+func (d *DefaultPackage) Path() string { return d.PackagePath }
+
+func (d *DefaultPackage) Filter(c *Context, t *types.Type) bool {
+ if d.FilterFunc != nil {
+ return d.FilterFunc(c, t)
+ }
+ return true
+}
+
+func (d *DefaultPackage) Generators(c *Context) []Generator {
+ if d.GeneratorFunc != nil {
+ return d.GeneratorFunc(c)
+ }
+ return d.GeneratorList
+}
+
+func (d *DefaultPackage) Header(filename string) []byte {
+ if filename == "doc.go" {
+ return append(d.HeaderText, d.PackageDocumentation...)
+ }
+ return d.HeaderText
+}
+
+var (
+ _ = Package(&DefaultPackage{})
+)
diff --git a/metrics-server/vendor/k8s.io/gengo/generator/doc.go b/metrics-server/vendor/k8s.io/gengo/generator/doc.go
new file mode 100644
index 0000000..d8e1253
--- /dev/null
+++ b/metrics-server/vendor/k8s.io/gengo/generator/doc.go
@@ -0,0 +1,31 @@
+/*
+Copyright 2015 The Kubernetes 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 generator defines an interface for code generators to implement.
+//
+// To use this package, you'll implement the "Package" and "Generator"
+// interfaces; you'll call NewContext to load up the types you want to work
+// with, and then you'll call one or more of the Execute methods. See the
+// interface definitions for explanations. All output will have gofmt called on
+// it automatically, so you do not need to worry about generating correct
+// indentation.
+//
+// This package also exposes SnippetWriter. SnippetWriter reduces to a minimum
+// the boilerplate involved in setting up a template from go's text/template
+// package. Additionally, all naming systems in the Context will be added as
+// functions to the parsed template, so that they can be called directly from
+// your templates!
+package generator // import "k8s.io/gengo/generator"
diff --git a/metrics-server/vendor/k8s.io/gengo/generator/error_tracker.go b/metrics-server/vendor/k8s.io/gengo/generator/error_tracker.go
new file mode 100644
index 0000000..964dae3
--- /dev/null
+++ b/metrics-server/vendor/k8s.io/gengo/generator/error_tracker.go
@@ -0,0 +1,50 @@
+/*
+Copyright 2015 The Kubernetes 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 generator
+
+import (
+ "io"
+)
+
+// ErrorTracker tracks errors to the underlying writer, so that you can ignore
+// them until you're ready to return.
+type ErrorTracker struct {
+ io.Writer
+ err error
+}
+
+// NewErrorTracker makes a new error tracker; note that it implements io.Writer.
+func NewErrorTracker(w io.Writer) *ErrorTracker {
+ return &ErrorTracker{Writer: w}
+}
+
+// Write intercepts calls to Write.
+func (et *ErrorTracker) Write(p []byte) (n int, err error) {
+ if et.err != nil {
+ return 0, et.err
+ }
+ n, err = et.Writer.Write(p)
+ if err != nil {
+ et.err = err
+ }
+ return n, err
+}
+
+// Error returns nil if no error has occurred, otherwise it returns the error.
+func (et *ErrorTracker) Error() error {
+ return et.err
+}
diff --git a/metrics-server/vendor/k8s.io/gengo/generator/execute.go b/metrics-server/vendor/k8s.io/gengo/generator/execute.go
new file mode 100644
index 0000000..38dffff
--- /dev/null
+++ b/metrics-server/vendor/k8s.io/gengo/generator/execute.go
@@ -0,0 +1,312 @@
+/*
+Copyright 2015 The Kubernetes 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 generator
+
+import (
+ "bytes"
+ "fmt"
+ "io"
+ "io/ioutil"
+ "os"
+ "path/filepath"
+ "strings"
+
+ "golang.org/x/tools/imports"
+ "k8s.io/gengo/namer"
+ "k8s.io/gengo/types"
+
+ "github.com/golang/glog"
+)
+
+func errs2strings(errors []error) []string {
+ strs := make([]string, len(errors))
+ for i := range errors {
+ strs[i] = errors[i].Error()
+ }
+ return strs
+}
+
+// ExecutePackages runs the generators for every package in 'packages'. 'outDir'
+// is the base directory in which to place all the generated packages; it
+// should be a physical path on disk, not an import path. e.g.:
+// /path/to/home/path/to/gopath/src/
+// Each package has its import path already, this will be appended to 'outDir'.
+func (c *Context) ExecutePackages(outDir string, packages Packages) error {
+ var errors []error
+ for _, p := range packages {
+ if err := c.ExecutePackage(outDir, p); err != nil {
+ errors = append(errors, err)
+ }
+ }
+ if len(errors) > 0 {
+ return fmt.Errorf("some packages had errors:\n%v\n", strings.Join(errs2strings(errors), "\n"))
+ }
+ return nil
+}
+
+type DefaultFileType struct {
+ Format func([]byte) ([]byte, error)
+ Assemble func(io.Writer, *File)
+}
+
+func (ft DefaultFileType) AssembleFile(f *File, pathname string) error {
+ glog.V(2).Infof("Assembling file %q", pathname)
+ destFile, err := os.Create(pathname)
+ if err != nil {
+ return err
+ }
+ defer destFile.Close()
+
+ b := &bytes.Buffer{}
+ et := NewErrorTracker(b)
+ ft.Assemble(et, f)
+ if et.Error() != nil {
+ return et.Error()
+ }
+ if formatted, err := ft.Format(b.Bytes()); err != nil {
+ err = fmt.Errorf("unable to format file %q (%v).", pathname, err)
+ // Write the file anyway, so they can see what's going wrong and fix the generator.
+ if _, err2 := destFile.Write(b.Bytes()); err2 != nil {
+ return err2
+ }
+ return err
+ } else {
+ _, err = destFile.Write(formatted)
+ return err
+ }
+}
+
+func (ft DefaultFileType) VerifyFile(f *File, pathname string) error {
+ glog.V(2).Infof("Verifying file %q", pathname)
+ friendlyName := filepath.Join(f.PackageName, f.Name)
+ b := &bytes.Buffer{}
+ et := NewErrorTracker(b)
+ ft.Assemble(et, f)
+ if et.Error() != nil {
+ return et.Error()
+ }
+ formatted, err := ft.Format(b.Bytes())
+ if err != nil {
+ return fmt.Errorf("unable to format the output for %q: %v", friendlyName, err)
+ }
+ existing, err := ioutil.ReadFile(pathname)
+ if err != nil {
+ return fmt.Errorf("unable to read file %q for comparison: %v", friendlyName, err)
+ }
+ if bytes.Compare(formatted, existing) == 0 {
+ return nil
+ }
+ // Be nice and find the first place where they differ
+ i := 0
+ for i < len(formatted) && i < len(existing) && formatted[i] == existing[i] {
+ i++
+ }
+ eDiff, fDiff := existing[i:], formatted[i:]
+ if len(eDiff) > 100 {
+ eDiff = eDiff[:100]
+ }
+ if len(fDiff) > 100 {
+ fDiff = fDiff[:100]
+ }
+ return fmt.Errorf("output for %q differs; first existing/expected diff: \n %q\n %q", friendlyName, string(eDiff), string(fDiff))
+}
+
+func assembleGolangFile(w io.Writer, f *File) {
+ w.Write(f.Header)
+ fmt.Fprintf(w, "package %v\n\n", f.PackageName)
+
+ if len(f.Imports) > 0 {
+ fmt.Fprint(w, "import (\n")
+ for i := range f.Imports {
+ if strings.Contains(i, "\"") {
+ // they included quotes, or are using the
+ // `name "path/to/pkg"` format.
+ fmt.Fprintf(w, "\t%s\n", i)
+ } else {
+ fmt.Fprintf(w, "\t%q\n", i)
+ }
+ }
+ fmt.Fprint(w, ")\n\n")
+ }
+
+ if f.Vars.Len() > 0 {
+ fmt.Fprint(w, "var (\n")
+ w.Write(f.Vars.Bytes())
+ fmt.Fprint(w, ")\n\n")
+ }
+
+ if f.Consts.Len() > 0 {
+ fmt.Fprint(w, "const (\n")
+ w.Write(f.Consts.Bytes())
+ fmt.Fprint(w, ")\n\n")
+ }
+
+ w.Write(f.Body.Bytes())
+}
+
+func importsWrapper(src []byte) ([]byte, error) {
+ return imports.Process("", src, nil)
+}
+
+func NewGolangFile() *DefaultFileType {
+ return &DefaultFileType{
+ Format: importsWrapper,
+ Assemble: assembleGolangFile,
+ }
+}
+
+// format should be one line only, and not end with \n.
+func addIndentHeaderComment(b *bytes.Buffer, format string, args ...interface{}) {
+ if b.Len() > 0 {
+ fmt.Fprintf(b, "\n// "+format+"\n", args...)
+ } else {
+ fmt.Fprintf(b, "// "+format+"\n", args...)
+ }
+}
+
+func (c *Context) filteredBy(f func(*Context, *types.Type) bool) *Context {
+ c2 := *c
+ c2.Order = []*types.Type{}
+ for _, t := range c.Order {
+ if f(c, t) {
+ c2.Order = append(c2.Order, t)
+ }
+ }
+ return &c2
+}
+
+// make a new context; inheret c.Namers, but add on 'namers'. In case of a name
+// collision, the namer in 'namers' wins.
+func (c *Context) addNameSystems(namers namer.NameSystems) *Context {
+ if namers == nil {
+ return c
+ }
+ c2 := *c
+ // Copy the existing name systems so we don't corrupt a parent context
+ c2.Namers = namer.NameSystems{}
+ for k, v := range c.Namers {
+ c2.Namers[k] = v
+ }
+
+ for name, namer := range namers {
+ c2.Namers[name] = namer
+ }
+ return &c2
+}
+
+// ExecutePackage executes a single package. 'outDir' is the base directory in
+// which to place the package; it should be a physical path on disk, not an
+// import path. e.g.: '/path/to/home/path/to/gopath/src/' The package knows its
+// import path already, this will be appended to 'outDir'.
+func (c *Context) ExecutePackage(outDir string, p Package) error {
+ path := filepath.Join(outDir, p.Path())
+ glog.V(2).Infof("Processing package %q, disk location %q", p.Name(), path)
+ // Filter out any types the *package* doesn't care about.
+ packageContext := c.filteredBy(p.Filter)
+ os.MkdirAll(path, 0755)
+ files := map[string]*File{}
+ for _, g := range p.Generators(packageContext) {
+ // Filter out types the *generator* doesn't care about.
+ genContext := packageContext.filteredBy(g.Filter)
+ // Now add any extra name systems defined by this generator
+ genContext = genContext.addNameSystems(g.Namers(genContext))
+
+ fileType := g.FileType()
+ if len(fileType) == 0 {
+ return fmt.Errorf("generator %q must specify a file type", g.Name())
+ }
+ f := files[g.Filename()]
+ if f == nil {
+ // This is the first generator to reference this file, so start it.
+ f = &File{
+ Name: g.Filename(),
+ FileType: fileType,
+ PackageName: p.Name(),
+ Header: p.Header(g.Filename()),
+ Imports: map[string]struct{}{},
+ }
+ files[f.Name] = f
+ } else {
+ if f.FileType != g.FileType() {
+ return fmt.Errorf("file %q already has type %q, but generator %q wants to use type %q", f.Name, f.FileType, g.Name(), g.FileType())
+ }
+ }
+
+ if vars := g.PackageVars(genContext); len(vars) > 0 {
+ addIndentHeaderComment(&f.Vars, "Package-wide variables from generator %q.", g.Name())
+ for _, v := range vars {
+ if _, err := fmt.Fprintf(&f.Vars, "%s\n", v); err != nil {
+ return err
+ }
+ }
+ }
+ if consts := g.PackageConsts(genContext); len(consts) > 0 {
+ addIndentHeaderComment(&f.Consts, "Package-wide consts from generator %q.", g.Name())
+ for _, v := range consts {
+ if _, err := fmt.Fprintf(&f.Consts, "%s\n", v); err != nil {
+ return err
+ }
+ }
+ }
+ if err := genContext.executeBody(&f.Body, g); err != nil {
+ return err
+ }
+ if imports := g.Imports(genContext); len(imports) > 0 {
+ for _, i := range imports {
+ f.Imports[i] = struct{}{}
+ }
+ }
+ }
+
+ var errors []error
+ for _, f := range files {
+ finalPath := filepath.Join(path, f.Name)
+ assembler, ok := c.FileTypes[f.FileType]
+ if !ok {
+ return fmt.Errorf("the file type %q registered for file %q does not exist in the context", f.FileType, f.Name)
+ }
+ var err error
+ if c.Verify {
+ err = assembler.VerifyFile(f, finalPath)
+ } else {
+ err = assembler.AssembleFile(f, finalPath)
+ }
+ if err != nil {
+ errors = append(errors, err)
+ }
+ }
+ if len(errors) > 0 {
+ return fmt.Errorf("errors in package %q:\n%v\n", p.Path(), strings.Join(errs2strings(errors), "\n"))
+ }
+ return nil
+}
+
+func (c *Context) executeBody(w io.Writer, generator Generator) error {
+ et := NewErrorTracker(w)
+ if err := generator.Init(c, et); err != nil {
+ return err
+ }
+ for _, t := range c.Order {
+ if err := generator.GenerateType(c, t, et); err != nil {
+ return err
+ }
+ }
+ if err := generator.Finalize(c, et); err != nil {
+ return err
+ }
+ return et.Error()
+}
diff --git a/metrics-server/vendor/k8s.io/gengo/generator/generator.go b/metrics-server/vendor/k8s.io/gengo/generator/generator.go
new file mode 100644
index 0000000..05a3f65
--- /dev/null
+++ b/metrics-server/vendor/k8s.io/gengo/generator/generator.go
@@ -0,0 +1,219 @@
+/*
+Copyright 2015 The Kubernetes 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 generator
+
+import (
+ "bytes"
+ "io"
+
+ "k8s.io/gengo/namer"
+ "k8s.io/gengo/parser"
+ "k8s.io/gengo/types"
+)
+
+// Package contains the contract for generating a package.
+type Package interface {
+ // Name returns the package short name.
+ Name() string
+ // Path returns the package import path.
+ Path() string
+
+ // Filter should return true if this package cares about this type.
+ // Otherwise, this type will be omitted from the type ordering for
+ // this package.
+ Filter(*Context, *types.Type) bool
+
+ // Header should return a header for the file, including comment markers.
+ // Useful for copyright notices and doc strings. Include an
+ // autogeneration notice! Do not include the "package x" line.
+ Header(filename string) []byte
+
+ // Generators returns the list of generators for this package. It is
+ // allowed for more than one generator to write to the same file.
+ // A Context is passed in case the list of generators depends on the
+ // input types.
+ Generators(*Context) []Generator
+}
+
+type File struct {
+ Name string
+ FileType string
+ PackageName string
+ Header []byte
+ Imports map[string]struct{}
+ Vars bytes.Buffer
+ Consts bytes.Buffer
+ Body bytes.Buffer
+}
+
+type FileType interface {
+ AssembleFile(f *File, path string) error
+ VerifyFile(f *File, path string) error
+}
+
+// Packages is a list of packages to generate.
+type Packages []Package
+
+// Generator is the contract for anything that wants to do auto-generation.
+// It's expected that the io.Writers passed to the below functions will be
+// ErrorTrackers; this allows implementations to not check for io errors,
+// making more readable code.
+//
+// The call order for the functions that take a Context is:
+// 1. Filter() // Subsequent calls see only types that pass this.
+// 2. Namers() // Subsequent calls see the namers provided by this.
+// 3. PackageVars()
+// 4. PackageConsts()
+// 5. Init()
+// 6. GenerateType() // Called N times, once per type in the context's Order.
+// 7. Imports()
+//
+// You may have multiple generators for the same file.
+type Generator interface {
+ // The name of this generator. Will be included in generated comments.
+ Name() string
+
+ // Filter should return true if this generator cares about this type.
+ // (otherwise, GenerateType will not be called.)
+ //
+ // Filter is called before any of the generator's other functions;
+ // subsequent calls will get a context with only the types that passed
+ // this filter.
+ Filter(*Context, *types.Type) bool
+
+ // If this generator needs special namers, return them here. These will
+ // override the original namers in the context if there is a collision.
+ // You may return nil if you don't need special names. These names will
+ // be available in the context passed to the rest of the generator's
+ // functions.
+ //
+ // A use case for this is to return a namer that tracks imports.
+ Namers(*Context) namer.NameSystems
+
+ // Init should write an init function, and any other content that's not
+ // generated per-type. (It's not intended for generator specific
+ // initialization! Do that when your Package constructs the
+ // Generators.)
+ Init(*Context, io.Writer) error
+
+ // Finalize should write finish up functions, and any other content that's not
+ // generated per-type.
+ Finalize(*Context, io.Writer) error
+
+ // PackageVars should emit an array of variable lines. They will be
+ // placed in a var ( ... ) block. There's no need to include a leading
+ // \t or trailing \n.
+ PackageVars(*Context) []string
+
+ // PackageConsts should emit an array of constant lines. They will be
+ // placed in a const ( ... ) block. There's no need to include a leading
+ // \t or trailing \n.
+ PackageConsts(*Context) []string
+
+ // GenerateType should emit the code for a particular type.
+ GenerateType(*Context, *types.Type, io.Writer) error
+
+ // Imports should return a list of necessary imports. They will be
+ // formatted correctly. You do not need to include quotation marks,
+ // return only the package name; alternatively, you can also return
+ // imports in the format `name "path/to/pkg"`. Imports will be called
+ // after Init, PackageVars, PackageConsts, and GenerateType, to allow
+ // you to keep track of what imports you actually need.
+ Imports(*Context) []string
+
+ // Preferred file name of this generator, not including a path. It is
+ // allowed for multiple generators to use the same filename, but it's
+ // up to you to make sure they don't have colliding import names.
+ // TODO: provide per-file import tracking, removing the requirement
+ // that generators coordinate..
+ Filename() string
+
+ // A registered file type in the context to generate this file with. If
+ // the FileType is not found in the context, execution will stop.
+ FileType() string
+}
+
+// Context is global context for individual generators to consume.
+type Context struct {
+ // A map from the naming system to the names for that system. E.g., you
+ // might have public names and several private naming systems.
+ Namers namer.NameSystems
+
+ // All the types, in case you want to look up something.
+ Universe types.Universe
+
+ // All the user-specified packages. This is after recursive expansion.
+ Inputs []string
+
+ // The canonical ordering of the types (will be filtered by both the
+ // Package's and Generator's Filter methods).
+ Order []*types.Type
+
+ // A set of types this context can process. If this is empty or nil,
+ // the default "golang" filetype will be provided.
+ FileTypes map[string]FileType
+
+ // If true, Execute* calls will just verify that the existing output is
+ // correct. (You may set this after calling NewContext.)
+ Verify bool
+
+ // Allows generators to add packages at runtime.
+ builder *parser.Builder
+}
+
+// NewContext generates a context from the given builder, naming systems, and
+// the naming system you wish to construct the canonical ordering from.
+func NewContext(b *parser.Builder, nameSystems namer.NameSystems, canonicalOrderName string) (*Context, error) {
+ universe, err := b.FindTypes()
+ if err != nil {
+ return nil, err
+ }
+
+ c := &Context{
+ Namers: namer.NameSystems{},
+ Universe: universe,
+ Inputs: b.FindPackages(),
+ FileTypes: map[string]FileType{
+ GolangFileType: NewGolangFile(),
+ },
+ builder: b,
+ }
+
+ for name, systemNamer := range nameSystems {
+ c.Namers[name] = systemNamer
+ if name == canonicalOrderName {
+ orderer := namer.Orderer{Namer: systemNamer}
+ c.Order = orderer.OrderUniverse(universe)
+ }
+ }
+ return c, nil
+}
+
+// AddDir adds a Go package to the context. The specified path must be a single
+// go package import path. GOPATH, GOROOT, and the location of your go binary
+// (`which go`) will all be searched, in the normal Go fashion.
+// Deprecated. Please use AddDirectory.
+func (ctxt *Context) AddDir(path string) error {
+ return ctxt.builder.AddDirTo(path, &ctxt.Universe)
+}
+
+// AddDirectory adds a Go package to the context. The specified path must be a
+// single go package import path. GOPATH, GOROOT, and the location of your go
+// binary (`which go`) will all be searched, in the normal Go fashion.
+func (ctxt *Context) AddDirectory(path string) (*types.Package, error) {
+ return ctxt.builder.AddDirectoryTo(path, &ctxt.Universe)
+}
diff --git a/metrics-server/vendor/k8s.io/gengo/generator/import_tracker.go b/metrics-server/vendor/k8s.io/gengo/generator/import_tracker.go
new file mode 100644
index 0000000..d4ba5e9
--- /dev/null
+++ b/metrics-server/vendor/k8s.io/gengo/generator/import_tracker.go
@@ -0,0 +1,64 @@
+/*
+Copyright 2015 The Kubernetes 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 generator
+
+import (
+ "strings"
+
+ "github.com/golang/glog"
+
+ "k8s.io/gengo/namer"
+ "k8s.io/gengo/types"
+)
+
+func NewImportTracker(typesToAdd ...*types.Type) namer.ImportTracker {
+ tracker := namer.NewDefaultImportTracker(types.Name{})
+ tracker.IsInvalidType = func(*types.Type) bool { return false }
+ tracker.LocalName = func(name types.Name) string { return golangTrackerLocalName(&tracker, name) }
+ tracker.PrintImport = func(path, name string) string { return name + " \"" + path + "\"" }
+
+ tracker.AddTypes(typesToAdd...)
+ return &tracker
+
+}
+
+func golangTrackerLocalName(tracker namer.ImportTracker, t types.Name) string {
+ path := t.Package
+
+ // Using backslashes in package names causes gengo to produce Go code which
+ // will not compile with the gc compiler. See the comment on GoSeperator.
+ if strings.ContainsRune(path, '\\') {
+ glog.Warningf("Warning: backslash used in import path '%v', this is unsupported.\n", path)
+ }
+
+ dirs := strings.Split(path, namer.GoSeperator)
+ for n := len(dirs) - 1; n >= 0; n-- {
+ // follow kube convention of not having anything between directory names
+ name := strings.Join(dirs[n:], "")
+ name = strings.Replace(name, "_", "", -1)
+ // These characters commonly appear in import paths for go
+ // packages, but aren't legal go names. So we'll sanitize.
+ name = strings.Replace(name, ".", "", -1)
+ name = strings.Replace(name, "-", "", -1)
+ if _, found := tracker.PathOf(name); found {
+ // This name collides with some other package
+ continue
+ }
+ return name
+ }
+ panic("can't find import for " + path)
+}
diff --git a/metrics-server/vendor/k8s.io/gengo/generator/snippet_writer.go b/metrics-server/vendor/k8s.io/gengo/generator/snippet_writer.go
new file mode 100644
index 0000000..eae917c
--- /dev/null
+++ b/metrics-server/vendor/k8s.io/gengo/generator/snippet_writer.go
@@ -0,0 +1,154 @@
+/*
+Copyright 2015 The Kubernetes 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 generator
+
+import (
+ "fmt"
+ "io"
+ "runtime"
+ "text/template"
+)
+
+// SnippetWriter is an attempt to make the template library usable.
+// Methods are chainable, and you don't have to check Error() until you're all
+// done.
+type SnippetWriter struct {
+ w io.Writer
+ context *Context
+ // Left & right delimiters. text/template defaults to "{{" and "}}"
+ // which is totally unusable for go code based templates.
+ left, right string
+ funcMap template.FuncMap
+ err error
+}
+
+// w is the destination; left and right are the delimiters; @ and $ are both
+// reasonable choices.
+//
+// c is used to make a function for every naming system, to which you can pass
+// a type and get the corresponding name.
+func NewSnippetWriter(w io.Writer, c *Context, left, right string) *SnippetWriter {
+ sw := &SnippetWriter{
+ w: w,
+ context: c,
+ left: left,
+ right: right,
+ funcMap: template.FuncMap{},
+ }
+ for name, namer := range c.Namers {
+ sw.funcMap[name] = namer.Name
+ }
+ return sw
+}
+
+// Do parses format and runs args through it. You can have arbitrary logic in
+// the format (see the text/template documentation), but consider running many
+// short templaces, with ordinary go logic in between--this may be more
+// readable. Do is chainable. Any error causes every other call to do to be
+// ignored, and the error will be returned by Error(). So you can check it just
+// once, at the end of your function.
+//
+// 'args' can be quite literally anything; read the text/template documentation
+// for details. Maps and structs work particularly nicely. Conveniently, the
+// types package is designed to have structs that are easily referencable from
+// the template language.
+//
+// Example:
+//
+// sw := generator.NewSnippetWriter(outBuffer, context, "$", "$")
+// sw.Do(`The public type name is: $.type|public$`, map[string]interface{}{"type": t})
+// return sw.Error()
+//
+// Where:
+// * "$" starts a template directive
+// * "." references the entire thing passed as args
+// * "type" therefore sees a map and looks up the key "type"
+// * "|" means "pass the thing on the left to the thing on the right"
+// * "public" is the name of a naming system, so the SnippetWriter has given
+// the template a function called "public" that takes a *types.Type and
+// returns the naming system's name. E.g., if the type is "string" this might
+// return "String".
+// * the second "$" ends the template directive.
+//
+// The map is actually not necessary. The below does the same thing:
+//
+// sw.Do(`The public type name is: $.|public$`, t)
+//
+// You may or may not find it more readable to use the map with a descriptive
+// key, but if you want to pass more than one arg, the map or a custom struct
+// becomes a requirement. You can do arbitrary logic inside these templates,
+// but you should consider doing the logic in go and stitching them together
+// for the sake of your readers.
+//
+// TODO: Change Do() to optionally take a list of pairs of parameters (key, value)
+// and have it construct a combined map with that and args.
+func (s *SnippetWriter) Do(format string, args interface{}) *SnippetWriter {
+ if s.err != nil {
+ return s
+ }
+ // Name the template by source file:line so it can be found when
+ // there's an error.
+ _, file, line, _ := runtime.Caller(1)
+ tmpl, err := template.
+ New(fmt.Sprintf("%s:%d", file, line)).
+ Delims(s.left, s.right).
+ Funcs(s.funcMap).
+ Parse(format)
+ if err != nil {
+ s.err = err
+ return s
+ }
+ err = tmpl.Execute(s.w, args)
+ if err != nil {
+ s.err = err
+ }
+ return s
+}
+
+// Args exists to make it convenient to construct arguments for
+// SnippetWriter.Do.
+type Args map[interface{}]interface{}
+
+// With makes a copy of a and adds the given key, value pair.
+func (a Args) With(key, value interface{}) Args {
+ a2 := Args{key: value}
+ for k, v := range a {
+ a2[k] = v
+ }
+ return a2
+}
+
+// WithArgs makes a copy of a and adds the given arguments.
+func (a Args) WithArgs(rhs Args) Args {
+ a2 := Args{}
+ for k, v := range rhs {
+ a2[k] = v
+ }
+ for k, v := range a {
+ a2[k] = v
+ }
+ return a2
+}
+
+func (s *SnippetWriter) Out() io.Writer {
+ return s.w
+}
+
+// Error returns any encountered error.
+func (s *SnippetWriter) Error() error {
+ return s.err
+}
diff --git a/metrics-server/vendor/k8s.io/gengo/namer/doc.go b/metrics-server/vendor/k8s.io/gengo/namer/doc.go
new file mode 100644
index 0000000..8a44ea9
--- /dev/null
+++ b/metrics-server/vendor/k8s.io/gengo/namer/doc.go
@@ -0,0 +1,31 @@
+/*
+Copyright 2015 The Kubernetes 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 namer has support for making different type naming systems.
+//
+// This is because sometimes you want to refer to the literal type, sometimes
+// you want to make a name for the thing you're generating, and you want to
+// make the name based on the type. For example, if you have `type foo string`,
+// you want to be able to generate something like `func FooPrinter(f *foo) {
+// Print(string(*f)) }`; that is, you want to refer to a public name, a literal
+// name, and the underlying literal name.
+//
+// This package supports the idea of a "Namer" and a set of "NameSystems" to
+// support these use cases.
+//
+// Additionally, a "RawNamer" can optionally keep track of what needs to be
+// imported.
+package namer // import "k8s.io/gengo/namer"
diff --git a/metrics-server/vendor/k8s.io/gengo/namer/import_tracker.go b/metrics-server/vendor/k8s.io/gengo/namer/import_tracker.go
new file mode 100644
index 0000000..37094b2
--- /dev/null
+++ b/metrics-server/vendor/k8s.io/gengo/namer/import_tracker.go
@@ -0,0 +1,112 @@
+/*
+Copyright 2015 The Kubernetes 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 namer
+
+import (
+ "sort"
+
+ "k8s.io/gengo/types"
+)
+
+// ImportTracker may be passed to a namer.RawNamer, to track the imports needed
+// for the types it names.
+//
+// TODO: pay attention to the package name (instead of renaming every package).
+type DefaultImportTracker struct {
+ pathToName map[string]string
+ // forbidden names are in here. (e.g. "go" is a directory in which
+ // there is code, but "go" is not a legal name for a package, so we put
+ // it here to prevent us from naming any package "go")
+ nameToPath map[string]string
+ local types.Name
+
+ // Returns true if a given types is an invalid type and should be ignored.
+ IsInvalidType func(*types.Type) bool
+ // Returns the final local name for the given name
+ LocalName func(types.Name) string
+ // Returns the "import" line for a given (path, name).
+ PrintImport func(string, string) string
+}
+
+func NewDefaultImportTracker(local types.Name) DefaultImportTracker {
+ return DefaultImportTracker{
+ pathToName: map[string]string{},
+ nameToPath: map[string]string{},
+ local: local,
+ }
+}
+
+func (tracker *DefaultImportTracker) AddTypes(types ...*types.Type) {
+ for _, t := range types {
+ tracker.AddType(t)
+ }
+}
+func (tracker *DefaultImportTracker) AddType(t *types.Type) {
+ if tracker.local.Package == t.Name.Package {
+ return
+ }
+
+ if tracker.IsInvalidType(t) {
+ if t.Kind == types.Builtin {
+ return
+ }
+ if _, ok := tracker.nameToPath[t.Name.Package]; !ok {
+ tracker.nameToPath[t.Name.Package] = ""
+ }
+ return
+ }
+
+ if len(t.Name.Package) == 0 {
+ return
+ }
+ path := t.Name.Path
+ if len(path) == 0 {
+ path = t.Name.Package
+ }
+ if _, ok := tracker.pathToName[path]; ok {
+ return
+ }
+ name := tracker.LocalName(t.Name)
+ tracker.nameToPath[name] = path
+ tracker.pathToName[path] = name
+}
+
+func (tracker *DefaultImportTracker) ImportLines() []string {
+ importPaths := []string{}
+ for path := range tracker.pathToName {
+ importPaths = append(importPaths, path)
+ }
+ sort.Sort(sort.StringSlice(importPaths))
+ out := []string{}
+ for _, path := range importPaths {
+ out = append(out, tracker.PrintImport(path, tracker.pathToName[path]))
+ }
+ return out
+}
+
+// LocalNameOf returns the name you would use to refer to the package at the
+// specified path within the body of a file.
+func (tracker *DefaultImportTracker) LocalNameOf(path string) string {
+ return tracker.pathToName[path]
+}
+
+// PathOf returns the path that a given localName is referring to within the
+// body of a file.
+func (tracker *DefaultImportTracker) PathOf(localName string) (string, bool) {
+ name, ok := tracker.nameToPath[localName]
+ return name, ok
+}
diff --git a/metrics-server/vendor/k8s.io/gengo/namer/namer.go b/metrics-server/vendor/k8s.io/gengo/namer/namer.go
new file mode 100644
index 0000000..d700a00
--- /dev/null
+++ b/metrics-server/vendor/k8s.io/gengo/namer/namer.go
@@ -0,0 +1,383 @@
+/*
+Copyright 2015 The Kubernetes 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 namer
+
+import (
+ "path/filepath"
+ "strings"
+
+ "k8s.io/gengo/types"
+)
+
+const (
+ // GoSeperator is used to split go import paths.
+ // Forward slash is used instead of filepath.Seperator because it is the
+ // only universally-accepted path delimiter and the only delimiter not
+ // potentially forbidden by Go compilers. (In particular gc does not allow
+ // the use of backslashes in import paths.)
+ // See https://golang.org/ref/spec#Import_declarations.
+ // See also https://github.com/kubernetes/gengo/issues/83#issuecomment-367040772.
+ GoSeperator = "/"
+)
+
+// Returns whether a name is a private Go name.
+func IsPrivateGoName(name string) bool {
+ return len(name) == 0 || strings.ToLower(name[:1]) == name[:1]
+}
+
+// NewPublicNamer is a helper function that returns a namer that makes
+// CamelCase names. See the NameStrategy struct for an explanation of the
+// arguments to this constructor.
+func NewPublicNamer(prependPackageNames int, ignoreWords ...string) *NameStrategy {
+ n := &NameStrategy{
+ Join: Joiner(IC, IC),
+ IgnoreWords: map[string]bool{},
+ PrependPackageNames: prependPackageNames,
+ }
+ for _, w := range ignoreWords {
+ n.IgnoreWords[w] = true
+ }
+ return n
+}
+
+// NewPrivateNamer is a helper function that returns a namer that makes
+// camelCase names. See the NameStrategy struct for an explanation of the
+// arguments to this constructor.
+func NewPrivateNamer(prependPackageNames int, ignoreWords ...string) *NameStrategy {
+ n := &NameStrategy{
+ Join: Joiner(IL, IC),
+ IgnoreWords: map[string]bool{},
+ PrependPackageNames: prependPackageNames,
+ }
+ for _, w := range ignoreWords {
+ n.IgnoreWords[w] = true
+ }
+ return n
+}
+
+// NewRawNamer will return a Namer that makes a name by which you would
+// directly refer to a type, optionally keeping track of the import paths
+// necessary to reference the names it provides. Tracker may be nil.
+// The 'pkg' is the full package name, in which the Namer is used - all
+// types from that package will be referenced by just type name without
+// referencing the package.
+//
+// For example, if the type is map[string]int, a raw namer will literally
+// return "map[string]int".
+//
+// Or if the type, in package foo, is "type Bar struct { ... }", then the raw
+// namer will return "foo.Bar" as the name of the type, and if 'tracker' was
+// not nil, will record that package foo needs to be imported.
+func NewRawNamer(pkg string, tracker ImportTracker) *rawNamer {
+ return &rawNamer{pkg: pkg, tracker: tracker}
+}
+
+// Names is a map from Type to name, as defined by some Namer.
+type Names map[*types.Type]string
+
+// Namer takes a type, and assigns a name.
+//
+// The purpose of this complexity is so that you can assign coherent
+// side-by-side systems of names for the types. For example, you might want a
+// public interface, a private implementation struct, and also to reference
+// literally the type name.
+//
+// Note that it is safe to call your own Name() function recursively to find
+// the names of keys, elements, etc. This is because anonymous types can't have
+// cycles in their names, and named types don't require the sort of recursion
+// that would be problematic.
+type Namer interface {
+ Name(*types.Type) string
+}
+
+// NameSystems is a map of a system name to a namer for that system.
+type NameSystems map[string]Namer
+
+// NameStrategy is a general Namer. The easiest way to use it is to copy the
+// Public/PrivateNamer variables, and modify the members you wish to change.
+//
+// The Name method produces a name for the given type, of the forms:
+// Anonymous types: <Prefix><Type description><Suffix>
+// Named types: <Prefix><Optional Prepended Package name(s)><Original name><Suffix>
+//
+// In all cases, every part of the name is run through the capitalization
+// functions.
+//
+// The IgnoreWords map can be set if you have directory names that are
+// semantically meaningless for naming purposes, e.g. "proto".
+//
+// Prefix and Suffix can be used to disambiguate parallel systems of type
+// names. For example, if you want to generate an interface and an
+// implementation, you might want to suffix one with "Interface" and the other
+// with "Implementation". Another common use-- if you want to generate private
+// types, and one of your source types could be "string", you can't use the
+// default lowercase private namer. You'll have to add a suffix or prefix.
+type NameStrategy struct {
+ Prefix, Suffix string
+ Join func(pre string, parts []string, post string) string
+
+ // Add non-meaningful package directory names here (e.g. "proto") and
+ // they will be ignored.
+ IgnoreWords map[string]bool
+
+ // If > 0, prepend exactly that many package directory names (or as
+ // many as there are). Package names listed in "IgnoreWords" will be
+ // ignored.
+ //
+ // For example, if Ignore words lists "proto" and type Foo is in
+ // pkg/server/frobbing/proto, then a value of 1 will give a type name
+ // of FrobbingFoo, 2 gives ServerFrobbingFoo, etc.
+ PrependPackageNames int
+
+ // A cache of names thus far assigned by this namer.
+ Names
+}
+
+// IC ensures the first character is uppercase.
+func IC(in string) string {
+ if in == "" {
+ return in
+ }
+ return strings.ToUpper(in[:1]) + in[1:]
+}
+
+// IL ensures the first character is lowercase.
+func IL(in string) string {
+ if in == "" {
+ return in
+ }
+ return strings.ToLower(in[:1]) + in[1:]
+}
+
+// Joiner lets you specify functions that preprocess the various components of
+// a name before joining them. You can construct e.g. camelCase or CamelCase or
+// any other way of joining words. (See the IC and IL convenience functions.)
+func Joiner(first, others func(string) string) func(pre string, in []string, post string) string {
+ return func(pre string, in []string, post string) string {
+ tmp := []string{others(pre)}
+ for i := range in {
+ tmp = append(tmp, others(in[i]))
+ }
+ tmp = append(tmp, others(post))
+ return first(strings.Join(tmp, ""))
+ }
+}
+
+func (ns *NameStrategy) removePrefixAndSuffix(s string) string {
+ // The join function may have changed capitalization.
+ lowerIn := strings.ToLower(s)
+ lowerP := strings.ToLower(ns.Prefix)
+ lowerS := strings.ToLower(ns.Suffix)
+ b, e := 0, len(s)
+ if strings.HasPrefix(lowerIn, lowerP) {
+ b = len(ns.Prefix)
+ }
+ if strings.HasSuffix(lowerIn, lowerS) {
+ e -= len(ns.Suffix)
+ }
+ return s[b:e]
+}
+
+var (
+ importPathNameSanitizer = strings.NewReplacer("-", "_", ".", "")
+)
+
+// filters out unwanted directory names and sanitizes remaining names.
+func (ns *NameStrategy) filterDirs(path string) []string {
+ allDirs := strings.Split(path, GoSeperator)
+ dirs := make([]string, 0, len(allDirs))
+ for _, p := range allDirs {
+ if ns.IgnoreWords == nil || !ns.IgnoreWords[p] {
+ dirs = append(dirs, importPathNameSanitizer.Replace(p))
+ }
+ }
+ return dirs
+}
+
+// See the comment on NameStrategy.
+func (ns *NameStrategy) Name(t *types.Type) string {
+ if ns.Names == nil {
+ ns.Names = Names{}
+ }
+ if s, ok := ns.Names[t]; ok {
+ return s
+ }
+
+ if t.Name.Package != "" {
+ dirs := append(ns.filterDirs(t.Name.Package), t.Name.Name)
+ i := ns.PrependPackageNames + 1
+ dn := len(dirs)
+ if i > dn {
+ i = dn
+ }
+ name := ns.Join(ns.Prefix, dirs[dn-i:], ns.Suffix)
+ ns.Names[t] = name
+ return name
+ }
+
+ // Only anonymous types remain.
+ var name string
+ switch t.Kind {
+ case types.Builtin:
+ name = ns.Join(ns.Prefix, []string{t.Name.Name}, ns.Suffix)
+ case types.Map:
+ name = ns.Join(ns.Prefix, []string{
+ "Map",
+ ns.removePrefixAndSuffix(ns.Name(t.Key)),
+ "To",
+ ns.removePrefixAndSuffix(ns.Name(t.Elem)),
+ }, ns.Suffix)
+ case types.Slice:
+ name = ns.Join(ns.Prefix, []string{
+ "Slice",
+ ns.removePrefixAndSuffix(ns.Name(t.Elem)),
+ }, ns.Suffix)
+ case types.Pointer:
+ name = ns.Join(ns.Prefix, []string{
+ "Pointer",
+ ns.removePrefixAndSuffix(ns.Name(t.Elem)),
+ }, ns.Suffix)
+ case types.Struct:
+ names := []string{"Struct"}
+ for _, m := range t.Members {
+ names = append(names, ns.removePrefixAndSuffix(ns.Name(m.Type)))
+ }
+ name = ns.Join(ns.Prefix, names, ns.Suffix)
+ case types.Chan:
+ name = ns.Join(ns.Prefix, []string{
+ "Chan",
+ ns.removePrefixAndSuffix(ns.Name(t.Elem)),
+ }, ns.Suffix)
+ case types.Interface:
+ // TODO: add to name test
+ names := []string{"Interface"}
+ for _, m := range t.Methods {
+ // TODO: include function signature
+ names = append(names, m.Name.Name)
+ }
+ name = ns.Join(ns.Prefix, names, ns.Suffix)
+ case types.Func:
+ // TODO: add to name test
+ parts := []string{"Func"}
+ for _, pt := range t.Signature.Parameters {
+ parts = append(parts, ns.removePrefixAndSuffix(ns.Name(pt)))
+ }
+ parts = append(parts, "Returns")
+ for _, rt := range t.Signature.Results {
+ parts = append(parts, ns.removePrefixAndSuffix(ns.Name(rt)))
+ }
+ name = ns.Join(ns.Prefix, parts, ns.Suffix)
+ default:
+ name = "unnameable_" + string(t.Kind)
+ }
+ ns.Names[t] = name
+ return name
+}
+
+// ImportTracker allows a raw namer to keep track of the packages needed for
+// import. You can implement yourself or use the one in the generation package.
+type ImportTracker interface {
+ AddType(*types.Type)
+ LocalNameOf(packagePath string) string
+ PathOf(localName string) (string, bool)
+ ImportLines() []string
+}
+
+type rawNamer struct {
+ pkg string
+ tracker ImportTracker
+ Names
+}
+
+// Name makes a name the way you'd write it to literally refer to type t,
+// making ordinary assumptions about how you've imported t's package (or using
+// r.tracker to specifically track the package imports).
+func (r *rawNamer) Name(t *types.Type) string {
+ if r.Names == nil {
+ r.Names = Names{}
+ }
+ if name, ok := r.Names[t]; ok {
+ return name
+ }
+ if t.Name.Package != "" {
+ var name string
+ if r.tracker != nil {
+ r.tracker.AddType(t)
+ if t.Name.Package == r.pkg {
+ name = t.Name.Name
+ } else {
+ name = r.tracker.LocalNameOf(t.Name.Package) + "." + t.Name.Name
+ }
+ } else {
+ if t.Name.Package == r.pkg {
+ name = t.Name.Name
+ } else {
+ name = filepath.Base(t.Name.Package) + "." + t.Name.Name
+ }
+ }
+ r.Names[t] = name
+ return name
+ }
+ var name string
+ switch t.Kind {
+ case types.Builtin:
+ name = t.Name.Name
+ case types.Map:
+ name = "map[" + r.Name(t.Key) + "]" + r.Name(t.Elem)
+ case types.Slice:
+ name = "[]" + r.Name(t.Elem)
+ case types.Pointer:
+ name = "*" + r.Name(t.Elem)
+ case types.Struct:
+ elems := []string{}
+ for _, m := range t.Members {
+ elems = append(elems, m.Name+" "+r.Name(m.Type))
+ }
+ name = "struct{" + strings.Join(elems, "; ") + "}"
+ case types.Chan:
+ // TODO: include directionality
+ name = "chan " + r.Name(t.Elem)
+ case types.Interface:
+ // TODO: add to name test
+ elems := []string{}
+ for _, m := range t.Methods {
+ // TODO: include function signature
+ elems = append(elems, m.Name.Name)
+ }
+ name = "interface{" + strings.Join(elems, "; ") + "}"
+ case types.Func:
+ // TODO: add to name test
+ params := []string{}
+ for _, pt := range t.Signature.Parameters {
+ params = append(params, r.Name(pt))
+ }
+ results := []string{}
+ for _, rt := range t.Signature.Results {
+ results = append(results, r.Name(rt))
+ }
+ name = "func(" + strings.Join(params, ",") + ")"
+ if len(results) == 1 {
+ name += " " + results[0]
+ } else if len(results) > 1 {
+ name += " (" + strings.Join(results, ",") + ")"
+ }
+ default:
+ name = "unnameable_" + string(t.Kind)
+ }
+ r.Names[t] = name
+ return name
+}
diff --git a/metrics-server/vendor/k8s.io/gengo/namer/order.go b/metrics-server/vendor/k8s.io/gengo/namer/order.go
new file mode 100644
index 0000000..f86282b
--- /dev/null
+++ b/metrics-server/vendor/k8s.io/gengo/namer/order.go
@@ -0,0 +1,69 @@
+/*
+Copyright 2015 The Kubernetes 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 namer
+
+import (
+ "sort"
+
+ "k8s.io/gengo/types"
+)
+
+// Orderer produces an ordering of types given a Namer.
+type Orderer struct {
+ Namer
+}
+
+// OrderUniverse assigns a name to every type in the Universe, including Types,
+// Functions and Variables, and returns a list sorted by those names.
+func (o *Orderer) OrderUniverse(u types.Universe) []*types.Type {
+ list := tList{
+ namer: o.Namer,
+ }
+ for _, p := range u {
+ for _, t := range p.Types {
+ list.types = append(list.types, t)
+ }
+ for _, f := range p.Functions {
+ list.types = append(list.types, f)
+ }
+ for _, v := range p.Variables {
+ list.types = append(list.types, v)
+ }
+ }
+ sort.Sort(list)
+ return list.types
+}
+
+// OrderTypes assigns a name to every type, and returns a list sorted by those
+// names.
+func (o *Orderer) OrderTypes(typeList []*types.Type) []*types.Type {
+ list := tList{
+ namer: o.Namer,
+ types: typeList,
+ }
+ sort.Sort(list)
+ return list.types
+}
+
+type tList struct {
+ namer Namer
+ types []*types.Type
+}
+
+func (t tList) Len() int { return len(t.types) }
+func (t tList) Less(i, j int) bool { return t.namer.Name(t.types[i]) < t.namer.Name(t.types[j]) }
+func (t tList) Swap(i, j int) { t.types[i], t.types[j] = t.types[j], t.types[i] }
diff --git a/metrics-server/vendor/k8s.io/gengo/namer/plural_namer.go b/metrics-server/vendor/k8s.io/gengo/namer/plural_namer.go
new file mode 100644
index 0000000..40bdcc6
--- /dev/null
+++ b/metrics-server/vendor/k8s.io/gengo/namer/plural_namer.go
@@ -0,0 +1,120 @@
+/*
+Copyright 2015 The Kubernetes 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 namer
+
+import (
+ "strings"
+
+ "k8s.io/gengo/types"
+)
+
+var consonants = "bcdfghjklmnpqrsttvwxyz"
+
+type pluralNamer struct {
+ // key is the case-sensitive type name, value is the case-insensitive
+ // intended output.
+ exceptions map[string]string
+ finalize func(string) string
+}
+
+// NewPublicPluralNamer returns a namer that returns the plural form of the input
+// type's name, starting with a uppercase letter.
+func NewPublicPluralNamer(exceptions map[string]string) *pluralNamer {
+ return &pluralNamer{exceptions, IC}
+}
+
+// NewPrivatePluralNamer returns a namer that returns the plural form of the input
+// type's name, starting with a lowercase letter.
+func NewPrivatePluralNamer(exceptions map[string]string) *pluralNamer {
+ return &pluralNamer{exceptions, IL}
+}
+
+// NewAllLowercasePluralNamer returns a namer that returns the plural form of the input
+// type's name, with all letters in lowercase.
+func NewAllLowercasePluralNamer(exceptions map[string]string) *pluralNamer {
+ return &pluralNamer{exceptions, strings.ToLower}
+}
+
+// Name returns the plural form of the type's name. If the type's name is found
+// in the exceptions map, the map value is returned.
+func (r *pluralNamer) Name(t *types.Type) string {
+ singular := t.Name.Name
+ var plural string
+ var ok bool
+ if plural, ok = r.exceptions[singular]; ok {
+ return r.finalize(plural)
+ }
+ if len(singular) < 2 {
+ return r.finalize(plural)
+ }
+
+ switch rune(singular[len(singular)-1]) {
+ case 's', 'x', 'z':
+ plural = esPlural(singular)
+ case 'y':
+ sl := rune(singular[len(singular)-2])
+ if isConsonant(sl) {
+ plural = iesPlural(singular)
+ } else {
+ plural = sPlural(singular)
+ }
+ case 'h':
+ sl := rune(singular[len(singular)-2])
+ if sl == 'c' || sl == 's' {
+ plural = esPlural(singular)
+ } else {
+ plural = sPlural(singular)
+ }
+ case 'e':
+ sl := rune(singular[len(singular)-2])
+ if sl == 'f' {
+ plural = vesPlural(singular[:len(singular)-1])
+ } else {
+ plural = sPlural(singular)
+ }
+ case 'f':
+ plural = vesPlural(singular)
+ default:
+ plural = sPlural(singular)
+ }
+ return r.finalize(plural)
+}
+
+func iesPlural(singular string) string {
+ return singular[:len(singular)-1] + "ies"
+}
+
+func vesPlural(singular string) string {
+ return singular[:len(singular)-1] + "ves"
+}
+
+func esPlural(singular string) string {
+ return singular + "es"
+}
+
+func sPlural(singular string) string {
+ return singular + "s"
+}
+
+func isConsonant(char rune) bool {
+ for _, c := range consonants {
+ if char == c {
+ return true
+ }
+ }
+ return false
+}
diff --git a/metrics-server/vendor/k8s.io/gengo/parser/doc.go b/metrics-server/vendor/k8s.io/gengo/parser/doc.go
new file mode 100644
index 0000000..8231b6d
--- /dev/null
+++ b/metrics-server/vendor/k8s.io/gengo/parser/doc.go
@@ -0,0 +1,19 @@
+/*
+Copyright 2015 The Kubernetes 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 parser provides code to parse go files, type-check them, extract the
+// types.
+package parser // import "k8s.io/gengo/parser"
diff --git a/metrics-server/vendor/k8s.io/gengo/parser/parse.go b/metrics-server/vendor/k8s.io/gengo/parser/parse.go
new file mode 100644
index 0000000..7b043d7
--- /dev/null
+++ b/metrics-server/vendor/k8s.io/gengo/parser/parse.go
@@ -0,0 +1,813 @@
+/*
+Copyright 2015 The Kubernetes 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 parser
+
+import (
+ "fmt"
+ "go/ast"
+ "go/build"
+ "go/parser"
+ "go/token"
+ tc "go/types"
+ "io/ioutil"
+ "os"
+ "os/exec"
+ "path"
+ "path/filepath"
+ "sort"
+ "strings"
+
+ "github.com/golang/glog"
+ "k8s.io/gengo/types"
+)
+
+// This clarifies when a pkg path has been canonicalized.
+type importPathString string
+
+// Builder lets you add all the go files in all the packages that you care
+// about, then constructs the type source data.
+type Builder struct {
+ context *build.Context
+
+ // Map of package names to more canonical information about the package.
+ // This might hold the same value for multiple names, e.g. if someone
+ // referenced ./pkg/name or in the case of vendoring, which canonicalizes
+ // differently that what humans would type.
+ buildPackages map[string]*build.Package
+
+ fset *token.FileSet
+ // map of package path to list of parsed files
+ parsed map[importPathString][]parsedFile
+ // map of package path to absolute path (to prevent overlap)
+ absPaths map[importPathString]string
+
+ // Set by typeCheckPackage(), used by importPackage() and friends.
+ typeCheckedPackages map[importPathString]*tc.Package
+
+ // Map of package path to whether the user requested it or it was from
+ // an import.
+ userRequested map[importPathString]bool
+
+ // All comments from everywhere in every parsed file.
+ endLineToCommentGroup map[fileLine]*ast.CommentGroup
+
+ // map of package to list of packages it imports.
+ importGraph map[importPathString]map[string]struct{}
+}
+
+// parsedFile is for tracking files with name
+type parsedFile struct {
+ name string
+ file *ast.File
+}
+
+// key type for finding comments.
+type fileLine struct {
+ file string
+ line int
+}
+
+// New constructs a new builder.
+func New() *Builder {
+ c := build.Default
+ if c.GOROOT == "" {
+ if p, err := exec.Command("which", "go").CombinedOutput(); err == nil {
+ // The returned string will have some/path/bin/go, so remove the last two elements.
+ c.GOROOT = filepath.Dir(filepath.Dir(strings.Trim(string(p), "\n")))
+ } else {
+ glog.Warningf("Warning: $GOROOT not set, and unable to run `which go` to find it: %v\n", err)
+ }
+ }
+ // Force this to off, since we don't properly parse CGo. All symbols must
+ // have non-CGo equivalents.
+ c.CgoEnabled = false
+ return &Builder{
+ context: &c,
+ buildPackages: map[string]*build.Package{},
+ typeCheckedPackages: map[importPathString]*tc.Package{},
+ fset: token.NewFileSet(),
+ parsed: map[importPathString][]parsedFile{},
+ absPaths: map[importPathString]string{},
+ userRequested: map[importPathString]bool{},
+ endLineToCommentGroup: map[fileLine]*ast.CommentGroup{},
+ importGraph: map[importPathString]map[string]struct{}{},
+ }
+}
+
+// AddBuildTags adds the specified build tags to the parse context.
+func (b *Builder) AddBuildTags(tags ...string) {
+ b.context.BuildTags = append(b.context.BuildTags, tags...)
+}
+
+// Get package information from the go/build package. Automatically excludes
+// e.g. test files and files for other platforms-- there is quite a bit of
+// logic of that nature in the build package.
+func (b *Builder) importBuildPackage(dir string) (*build.Package, error) {
+ if buildPkg, ok := b.buildPackages[dir]; ok {
+ return buildPkg, nil
+ }
+ // This validates the `package foo // github.com/bar/foo` comments.
+ buildPkg, err := b.importWithMode(dir, build.ImportComment)
+ if err != nil {
+ if _, ok := err.(*build.NoGoError); !ok {
+ return nil, fmt.Errorf("unable to import %q: %v", dir, err)
+ }
+ }
+ if buildPkg == nil {
+ // Might be an empty directory. Try to just find the dir.
+ buildPkg, err = b.importWithMode(dir, build.FindOnly)
+ if err != nil {
+ return nil, err
+ }
+ }
+
+ // Remember it under the user-provided name.
+ glog.V(5).Infof("saving buildPackage %s", dir)
+ b.buildPackages[dir] = buildPkg
+ canonicalPackage := canonicalizeImportPath(buildPkg.ImportPath)
+ if dir != string(canonicalPackage) {
+ // Since `dir` is not the canonical name, see if we knew it under another name.
+ if buildPkg, ok := b.buildPackages[string(canonicalPackage)]; ok {
+ return buildPkg, nil
+ }
+ // Must be new, save it under the canonical name, too.
+ glog.V(5).Infof("saving buildPackage %s", canonicalPackage)
+ b.buildPackages[string(canonicalPackage)] = buildPkg
+ }
+
+ return buildPkg, nil
+}
+
+// AddFileForTest adds a file to the set, without verifying that the provided
+// pkg actually exists on disk. The pkg must be of the form "canonical/pkg/path"
+// and the path must be the absolute path to the file. Because this bypasses
+// the normal recursive finding of package dependencies (on disk), test should
+// sort their test files topologically first, so all deps are resolved by the
+// time we need them.
+func (b *Builder) AddFileForTest(pkg string, path string, src []byte) error {
+ if err := b.addFile(importPathString(pkg), path, src, true); err != nil {
+ return err
+ }
+ if _, err := b.typeCheckPackage(importPathString(pkg)); err != nil {
+ return err
+ }
+ return nil
+}
+
+// addFile adds a file to the set. The pkgPath must be of the form
+// "canonical/pkg/path" and the path must be the absolute path to the file. A
+// flag indicates whether this file was user-requested or just from following
+// the import graph.
+func (b *Builder) addFile(pkgPath importPathString, path string, src []byte, userRequested bool) error {
+ for _, p := range b.parsed[pkgPath] {
+ if path == p.name {
+ glog.V(5).Infof("addFile %s %s already parsed, skipping", pkgPath, path)
+ return nil
+ }
+ }
+ glog.V(6).Infof("addFile %s %s", pkgPath, path)
+ p, err := parser.ParseFile(b.fset, path, src, parser.DeclarationErrors|parser.ParseComments)
+ if err != nil {
+ return err
+ }
+
+ // This is redundant with addDir, but some tests call AddFileForTest, which
+ // call into here without calling addDir.
+ b.userRequested[pkgPath] = userRequested || b.userRequested[pkgPath]
+
+ b.parsed[pkgPath] = append(b.parsed[pkgPath], parsedFile{path, p})
+ for _, c := range p.Comments {
+ position := b.fset.Position(c.End())
+ b.endLineToCommentGroup[fileLine{position.Filename, position.Line}] = c
+ }
+
+ // We have to get the packages from this specific file, in case the
+ // user added individual files instead of entire directories.
+ if b.importGraph[pkgPath] == nil {
+ b.importGraph[pkgPath] = map[string]struct{}{}
+ }
+ for _, im := range p.Imports {
+ importedPath := strings.Trim(im.Path.Value, `"`)
+ b.importGraph[pkgPath][importedPath] = struct{}{}
+ }
+ return nil
+}
+
+// AddDir adds an entire directory, scanning it for go files. 'dir' should have
+// a single go package in it. GOPATH, GOROOT, and the location of your go
+// binary (`which go`) will all be searched if dir doesn't literally resolve.
+func (b *Builder) AddDir(dir string) error {
+ _, err := b.importPackage(dir, true)
+ return err
+}
+
+// AddDirRecursive is just like AddDir, but it also recursively adds
+// subdirectories; it returns an error only if the path couldn't be resolved;
+// any directories recursed into without go source are ignored.
+func (b *Builder) AddDirRecursive(dir string) error {
+ // Add the root.
+ if _, err := b.importPackage(dir, true); err != nil {
+ glog.Warningf("Ignoring directory %v: %v", dir, err)
+ }
+
+ // filepath.Walk includes the root dir, but we already did that, so we'll
+ // remove that prefix and rebuild a package import path.
+ prefix := b.buildPackages[dir].Dir
+ fn := func(filePath string, info os.FileInfo, err error) error {
+ if info != nil && info.IsDir() {
+ rel := filepath.ToSlash(strings.TrimPrefix(filePath, prefix))
+ if rel != "" {
+ // Make a pkg path.
+ pkg := path.Join(string(canonicalizeImportPath(b.buildPackages[dir].ImportPath)), rel)
+
+ // Add it.
+ if _, err := b.importPackage(pkg, true); err != nil {
+ glog.Warningf("Ignoring child directory %v: %v", pkg, err)
+ }
+ }
+ }
+ return nil
+ }
+ if err := filepath.Walk(b.buildPackages[dir].Dir, fn); err != nil {
+ return err
+ }
+ return nil
+}
+
+// AddDirTo adds an entire directory to a given Universe. Unlike AddDir, this
+// processes the package immediately, which makes it safe to use from within a
+// generator (rather than just at init time. 'dir' must be a single go package.
+// GOPATH, GOROOT, and the location of your go binary (`which go`) will all be
+// searched if dir doesn't literally resolve.
+// Deprecated. Please use AddDirectoryTo.
+func (b *Builder) AddDirTo(dir string, u *types.Universe) error {
+ // We want all types from this package, as if they were directly added
+ // by the user. They WERE added by the user, in effect.
+ if _, err := b.importPackage(dir, true); err != nil {
+ return err
+ }
+ return b.findTypesIn(canonicalizeImportPath(b.buildPackages[dir].ImportPath), u)
+}
+
+// AddDirectoryTo adds an entire directory to a given Universe. Unlike AddDir,
+// this processes the package immediately, which makes it safe to use from
+// within a generator (rather than just at init time. 'dir' must be a single go
+// package. GOPATH, GOROOT, and the location of your go binary (`which go`)
+// will all be searched if dir doesn't literally resolve.
+func (b *Builder) AddDirectoryTo(dir string, u *types.Universe) (*types.Package, error) {
+ // We want all types from this package, as if they were directly added
+ // by the user. They WERE added by the user, in effect.
+ if _, err := b.importPackage(dir, true); err != nil {
+ return nil, err
+ }
+ path := canonicalizeImportPath(b.buildPackages[dir].ImportPath)
+ if err := b.findTypesIn(path, u); err != nil {
+ return nil, err
+ }
+ return u.Package(string(path)), nil
+}
+
+// The implementation of AddDir. A flag indicates whether this directory was
+// user-requested or just from following the import graph.
+func (b *Builder) addDir(dir string, userRequested bool) error {
+ glog.V(5).Infof("addDir %s", dir)
+ buildPkg, err := b.importBuildPackage(dir)
+ if err != nil {
+ return err
+ }
+ canonicalPackage := canonicalizeImportPath(buildPkg.ImportPath)
+ pkgPath := canonicalPackage
+ if dir != string(canonicalPackage) {
+ glog.V(5).Infof("addDir %s, canonical path is %s", dir, pkgPath)
+ }
+
+ // Sanity check the pkg dir has not changed.
+ if prev, found := b.absPaths[pkgPath]; found {
+ if buildPkg.Dir != prev {
+ return fmt.Errorf("package %q (%s) previously resolved to %s", pkgPath, buildPkg.Dir, prev)
+ }
+ } else {
+ b.absPaths[pkgPath] = buildPkg.Dir
+ }
+
+ for _, n := range buildPkg.GoFiles {
+ if !strings.HasSuffix(n, ".go") {
+ continue
+ }
+ absPath := filepath.Join(buildPkg.Dir, n)
+ data, err := ioutil.ReadFile(absPath)
+ if err != nil {
+ return fmt.Errorf("while loading %q: %v", absPath, err)
+ }
+ err = b.addFile(pkgPath, absPath, data, userRequested)
+ if err != nil {
+ return fmt.Errorf("while parsing %q: %v", absPath, err)
+ }
+ }
+ return nil
+}
+
+// importPackage is a function that will be called by the type check package when it
+// needs to import a go package. 'path' is the import path.
+func (b *Builder) importPackage(dir string, userRequested bool) (*tc.Package, error) {
+ glog.V(5).Infof("importPackage %s", dir)
+ var pkgPath = importPathString(dir)
+
+ // Get the canonical path if we can.
+ if buildPkg := b.buildPackages[dir]; buildPkg != nil {
+ canonicalPackage := canonicalizeImportPath(buildPkg.ImportPath)
+ glog.V(5).Infof("importPackage %s, canonical path is %s", dir, canonicalPackage)
+ pkgPath = canonicalPackage
+ }
+
+ // If we have not seen this before, process it now.
+ ignoreError := false
+ if _, found := b.parsed[pkgPath]; !found {
+ // Ignore errors in paths that we're importing solely because
+ // they're referenced by other packages.
+ ignoreError = true
+
+ // Add it.
+ if err := b.addDir(dir, userRequested); err != nil {
+ return nil, err
+ }
+
+ // Get the canonical path now that it has been added.
+ if buildPkg := b.buildPackages[dir]; buildPkg != nil {
+ canonicalPackage := canonicalizeImportPath(buildPkg.ImportPath)
+ glog.V(5).Infof("importPackage %s, canonical path is %s", dir, canonicalPackage)
+ pkgPath = canonicalPackage
+ }
+ }
+
+ // If it was previously known, just check that the user-requestedness hasn't
+ // changed.
+ b.userRequested[pkgPath] = userRequested || b.userRequested[pkgPath]
+
+ // Run the type checker. We may end up doing this to pkgs that are already
+ // done, or are in the queue to be done later, but it will short-circuit,
+ // and we can't miss pkgs that are only depended on.
+ pkg, err := b.typeCheckPackage(pkgPath)
+ if err != nil {
+ switch {
+ case ignoreError && pkg != nil:
+ glog.V(2).Infof("type checking encountered some issues in %q, but ignoring.\n", pkgPath)
+ case !ignoreError && pkg != nil:
+ glog.V(2).Infof("type checking encountered some errors in %q\n", pkgPath)
+ return nil, err
+ default:
+ return nil, err
+ }
+ }
+
+ return pkg, nil
+}
+
+type importAdapter struct {
+ b *Builder
+}
+
+func (a importAdapter) Import(path string) (*tc.Package, error) {
+ return a.b.importPackage(path, false)
+}
+
+// typeCheckPackage will attempt to return the package even if there are some
+// errors, so you may check whether the package is nil or not even if you get
+// an error.
+func (b *Builder) typeCheckPackage(pkgPath importPathString) (*tc.Package, error) {
+ glog.V(5).Infof("typeCheckPackage %s", pkgPath)
+ if pkg, ok := b.typeCheckedPackages[pkgPath]; ok {
+ if pkg != nil {
+ glog.V(6).Infof("typeCheckPackage %s already done", pkgPath)
+ return pkg, nil
+ }
+ // We store a nil right before starting work on a package. So
+ // if we get here and it's present and nil, that means there's
+ // another invocation of this function on the call stack
+ // already processing this package.
+ return nil, fmt.Errorf("circular dependency for %q", pkgPath)
+ }
+ parsedFiles, ok := b.parsed[pkgPath]
+ if !ok {
+ return nil, fmt.Errorf("No files for pkg %q: %#v", pkgPath, b.parsed)
+ }
+ files := make([]*ast.File, len(parsedFiles))
+ for i := range parsedFiles {
+ files[i] = parsedFiles[i].file
+ }
+ b.typeCheckedPackages[pkgPath] = nil
+ c := tc.Config{
+ IgnoreFuncBodies: true,
+ // Note that importAdapter can call b.importPackage which calls this
+ // method. So there can't be cycles in the import graph.
+ Importer: importAdapter{b},
+ Error: func(err error) {
+ glog.V(2).Infof("type checker: %v\n", err)
+ },
+ }
+ pkg, err := c.Check(string(pkgPath), b.fset, files, nil)
+ b.typeCheckedPackages[pkgPath] = pkg // record the result whether or not there was an error
+ return pkg, err
+}
+
+// FindPackages fetches a list of the user-imported packages.
+// Note that you need to call b.FindTypes() first.
+func (b *Builder) FindPackages() []string {
+ // Iterate packages in a predictable order.
+ pkgPaths := []string{}
+ for k := range b.typeCheckedPackages {
+ pkgPaths = append(pkgPaths, string(k))
+ }
+ sort.Strings(pkgPaths)
+
+ result := []string{}
+ for _, pkgPath := range pkgPaths {
+ if b.userRequested[importPathString(pkgPath)] {
+ // Since walkType is recursive, all types that are in packages that
+ // were directly mentioned will be included. We don't need to
+ // include all types in all transitive packages, though.
+ result = append(result, pkgPath)
+ }
+ }
+ return result
+}
+
+// FindTypes finalizes the package imports, and searches through all the
+// packages for types.
+func (b *Builder) FindTypes() (types.Universe, error) {
+ // Take a snapshot of pkgs to iterate, since this will recursively mutate
+ // b.parsed. Iterate in a predictable order.
+ pkgPaths := []string{}
+ for pkgPath := range b.parsed {
+ pkgPaths = append(pkgPaths, string(pkgPath))
+ }
+ sort.Strings(pkgPaths)
+
+ u := types.Universe{}
+ for _, pkgPath := range pkgPaths {
+ if err := b.findTypesIn(importPathString(pkgPath), &u); err != nil {
+ return nil, err
+ }
+ }
+ return u, nil
+}
+
+// findTypesIn finalizes the package import and searches through the package
+// for types.
+func (b *Builder) findTypesIn(pkgPath importPathString, u *types.Universe) error {
+ glog.V(5).Infof("findTypesIn %s", pkgPath)
+ pkg := b.typeCheckedPackages[pkgPath]
+ if pkg == nil {
+ return fmt.Errorf("findTypesIn(%s): package is not known", pkgPath)
+ }
+ if !b.userRequested[pkgPath] {
+ // Since walkType is recursive, all types that the
+ // packages they asked for depend on will be included.
+ // But we don't need to include all types in all
+ // *packages* they depend on.
+ glog.V(5).Infof("findTypesIn %s: package is not user requested", pkgPath)
+ return nil
+ }
+
+ // We're keeping this package. This call will create the record.
+ u.Package(string(pkgPath)).Name = pkg.Name()
+ u.Package(string(pkgPath)).Path = pkg.Path()
+ u.Package(string(pkgPath)).SourcePath = b.absPaths[pkgPath]
+
+ for _, f := range b.parsed[pkgPath] {
+ if _, fileName := filepath.Split(f.name); fileName == "doc.go" {
+ tp := u.Package(string(pkgPath))
+ // findTypesIn might be called multiple times. Clean up tp.Comments
+ // to avoid repeatedly fill same comments to it.
+ tp.Comments = []string{}
+ for i := range f.file.Comments {
+ tp.Comments = append(tp.Comments, splitLines(f.file.Comments[i].Text())...)
+ }
+ if f.file.Doc != nil {
+ tp.DocComments = splitLines(f.file.Doc.Text())
+ }
+ }
+ }
+
+ s := pkg.Scope()
+ for _, n := range s.Names() {
+ obj := s.Lookup(n)
+ tn, ok := obj.(*tc.TypeName)
+ if ok {
+ t := b.walkType(*u, nil, tn.Type())
+ c1 := b.priorCommentLines(obj.Pos(), 1)
+ // c1.Text() is safe if c1 is nil
+ t.CommentLines = splitLines(c1.Text())
+ if c1 == nil {
+ t.SecondClosestCommentLines = splitLines(b.priorCommentLines(obj.Pos(), 2).Text())
+ } else {
+ t.SecondClosestCommentLines = splitLines(b.priorCommentLines(c1.List[0].Slash, 2).Text())
+ }
+ }
+ tf, ok := obj.(*tc.Func)
+ // We only care about functions, not concrete/abstract methods.
+ if ok && tf.Type() != nil && tf.Type().(*tc.Signature).Recv() == nil {
+ t := b.addFunction(*u, nil, tf)
+ c1 := b.priorCommentLines(obj.Pos(), 1)
+ // c1.Text() is safe if c1 is nil
+ t.CommentLines = splitLines(c1.Text())
+ if c1 == nil {
+ t.SecondClosestCommentLines = splitLines(b.priorCommentLines(obj.Pos(), 2).Text())
+ } else {
+ t.SecondClosestCommentLines = splitLines(b.priorCommentLines(c1.List[0].Slash, 2).Text())
+ }
+ }
+ tv, ok := obj.(*tc.Var)
+ if ok && !tv.IsField() {
+ b.addVariable(*u, nil, tv)
+ }
+ }
+
+ importedPkgs := []string{}
+ for k := range b.importGraph[pkgPath] {
+ importedPkgs = append(importedPkgs, string(k))
+ }
+ sort.Strings(importedPkgs)
+ for _, p := range importedPkgs {
+ u.AddImports(string(pkgPath), p)
+ }
+ return nil
+}
+
+func (b *Builder) importWithMode(dir string, mode build.ImportMode) (*build.Package, error) {
+ // This is a bit of a hack. The srcDir argument to Import() should
+ // properly be the dir of the file which depends on the package to be
+ // imported, so that vendoring can work properly and local paths can
+ // resolve. We assume that there is only one level of vendoring, and that
+ // the CWD is inside the GOPATH, so this should be safe. Nobody should be
+ // using local (relative) paths except on the CLI, so CWD is also
+ // sufficient.
+ cwd, err := os.Getwd()
+ if err != nil {
+ return nil, fmt.Errorf("unable to get current directory: %v", err)
+ }
+ buildPkg, err := b.context.Import(dir, cwd, mode)
+ if err != nil {
+ return nil, err
+ }
+ return buildPkg, nil
+}
+
+// if there's a comment on the line `lines` before pos, return its text, otherwise "".
+func (b *Builder) priorCommentLines(pos token.Pos, lines int) *ast.CommentGroup {
+ position := b.fset.Position(pos)
+ key := fileLine{position.Filename, position.Line - lines}
+ return b.endLineToCommentGroup[key]
+}
+
+func splitLines(str string) []string {
+ return strings.Split(strings.TrimRight(str, "\n"), "\n")
+}
+
+func tcFuncNameToName(in string) types.Name {
+ name := strings.TrimPrefix(in, "func ")
+ nameParts := strings.Split(name, "(")
+ return tcNameToName(nameParts[0])
+}
+
+func tcVarNameToName(in string) types.Name {
+ nameParts := strings.Split(in, " ")
+ // nameParts[0] is "var".
+ // nameParts[2:] is the type of the variable, we ignore it for now.
+ return tcNameToName(nameParts[1])
+}
+
+func tcNameToName(in string) types.Name {
+ // Detect anonymous type names. (These may have '.' characters because
+ // embedded types may have packages, so we detect them specially.)
+ if strings.HasPrefix(in, "struct{") ||
+ strings.HasPrefix(in, "<-chan") ||
+ strings.HasPrefix(in, "chan<-") ||
+ strings.HasPrefix(in, "chan ") ||
+ strings.HasPrefix(in, "func(") ||
+ strings.HasPrefix(in, "*") ||
+ strings.HasPrefix(in, "map[") ||
+ strings.HasPrefix(in, "[") {
+ return types.Name{Name: in}
+ }
+
+ // Otherwise, if there are '.' characters present, the name has a
+ // package path in front.
+ nameParts := strings.Split(in, ".")
+ name := types.Name{Name: in}
+ if n := len(nameParts); n >= 2 {
+ // The final "." is the name of the type--previous ones must
+ // have been in the package path.
+ name.Package, name.Name = strings.Join(nameParts[:n-1], "."), nameParts[n-1]
+ }
+ return name
+}
+
+func (b *Builder) convertSignature(u types.Universe, t *tc.Signature) *types.Signature {
+ signature := &types.Signature{}
+ for i := 0; i < t.Params().Len(); i++ {
+ signature.Parameters = append(signature.Parameters, b.walkType(u, nil, t.Params().At(i).Type()))
+ }
+ for i := 0; i < t.Results().Len(); i++ {
+ signature.Results = append(signature.Results, b.walkType(u, nil, t.Results().At(i).Type()))
+ }
+ if r := t.Recv(); r != nil {
+ signature.Receiver = b.walkType(u, nil, r.Type())
+ }
+ signature.Variadic = t.Variadic()
+ return signature
+}
+
+// walkType adds the type, and any necessary child types.
+func (b *Builder) walkType(u types.Universe, useName *types.Name, in tc.Type) *types.Type {
+ // Most of the cases are underlying types of the named type.
+ name := tcNameToName(in.String())
+ if useName != nil {
+ name = *useName
+ }
+
+ switch t := in.(type) {
+ case *tc.Struct:
+ out := u.Type(name)
+ if out.Kind != types.Unknown {
+ return out
+ }
+ out.Kind = types.Struct
+ for i := 0; i < t.NumFields(); i++ {
+ f := t.Field(i)
+ m := types.Member{
+ Name: f.Name(),
+ Embedded: f.Anonymous(),
+ Tags: t.Tag(i),
+ Type: b.walkType(u, nil, f.Type()),
+ CommentLines: splitLines(b.priorCommentLines(f.Pos(), 1).Text()),
+ }
+ out.Members = append(out.Members, m)
+ }
+ return out
+ case *tc.Map:
+ out := u.Type(name)
+ if out.Kind != types.Unknown {
+ return out
+ }
+ out.Kind = types.Map
+ out.Elem = b.walkType(u, nil, t.Elem())
+ out.Key = b.walkType(u, nil, t.Key())
+ return out
+ case *tc.Pointer:
+ out := u.Type(name)
+ if out.Kind != types.Unknown {
+ return out
+ }
+ out.Kind = types.Pointer
+ out.Elem = b.walkType(u, nil, t.Elem())
+ return out
+ case *tc.Slice:
+ out := u.Type(name)
+ if out.Kind != types.Unknown {
+ return out
+ }
+ out.Kind = types.Slice
+ out.Elem = b.walkType(u, nil, t.Elem())
+ return out
+ case *tc.Array:
+ out := u.Type(name)
+ if out.Kind != types.Unknown {
+ return out
+ }
+ out.Kind = types.Array
+ out.Elem = b.walkType(u, nil, t.Elem())
+ // TODO: need to store array length, otherwise raw type name
+ // cannot be properly written.
+ return out
+ case *tc.Chan:
+ out := u.Type(name)
+ if out.Kind != types.Unknown {
+ return out
+ }
+ out.Kind = types.Chan
+ out.Elem = b.walkType(u, nil, t.Elem())
+ // TODO: need to store direction, otherwise raw type name
+ // cannot be properly written.
+ return out
+ case *tc.Basic:
+ out := u.Type(types.Name{
+ Package: "",
+ Name: t.Name(),
+ })
+ if out.Kind != types.Unknown {
+ return out
+ }
+ out.Kind = types.Unsupported
+ return out
+ case *tc.Signature:
+ out := u.Type(name)
+ if out.Kind != types.Unknown {
+ return out
+ }
+ out.Kind = types.Func
+ out.Signature = b.convertSignature(u, t)
+ return out
+ case *tc.Interface:
+ out := u.Type(name)
+ if out.Kind != types.Unknown {
+ return out
+ }
+ out.Kind = types.Interface
+ t.Complete()
+ for i := 0; i < t.NumMethods(); i++ {
+ if out.Methods == nil {
+ out.Methods = map[string]*types.Type{}
+ }
+ out.Methods[t.Method(i).Name()] = b.walkType(u, nil, t.Method(i).Type())
+ }
+ return out
+ case *tc.Named:
+ var out *types.Type
+ switch t.Underlying().(type) {
+ case *tc.Named, *tc.Basic, *tc.Map, *tc.Slice:
+ name := tcNameToName(t.String())
+ out = u.Type(name)
+ if out.Kind != types.Unknown {
+ return out
+ }
+ out.Kind = types.Alias
+ out.Underlying = b.walkType(u, nil, t.Underlying())
+ default:
+ // tc package makes everything "named" with an
+ // underlying anonymous type--we remove that annoying
+ // "feature" for users. This flattens those types
+ // together.
+ name := tcNameToName(t.String())
+ if out := u.Type(name); out.Kind != types.Unknown {
+ return out // short circuit if we've already made this.
+ }
+ out = b.walkType(u, &name, t.Underlying())
+ }
+ // If the underlying type didn't already add methods, add them.
+ // (Interface types will have already added methods.)
+ if len(out.Methods) == 0 {
+ for i := 0; i < t.NumMethods(); i++ {
+ if out.Methods == nil {
+ out.Methods = map[string]*types.Type{}
+ }
+ out.Methods[t.Method(i).Name()] = b.walkType(u, nil, t.Method(i).Type())
+ }
+ }
+ return out
+ default:
+ out := u.Type(name)
+ if out.Kind != types.Unknown {
+ return out
+ }
+ out.Kind = types.Unsupported
+ glog.Warningf("Making unsupported type entry %q for: %#v\n", out, t)
+ return out
+ }
+}
+
+func (b *Builder) addFunction(u types.Universe, useName *types.Name, in *tc.Func) *types.Type {
+ name := tcFuncNameToName(in.String())
+ if useName != nil {
+ name = *useName
+ }
+ out := u.Function(name)
+ out.Kind = types.DeclarationOf
+ out.Underlying = b.walkType(u, nil, in.Type())
+ return out
+}
+
+func (b *Builder) addVariable(u types.Universe, useName *types.Name, in *tc.Var) *types.Type {
+ name := tcVarNameToName(in.String())
+ if useName != nil {
+ name = *useName
+ }
+ out := u.Variable(name)
+ out.Kind = types.DeclarationOf
+ out.Underlying = b.walkType(u, nil, in.Type())
+ return out
+}
+
+// canonicalizeImportPath takes an import path and returns the actual package.
+// It doesn't support nested vendoring.
+func canonicalizeImportPath(importPath string) importPathString {
+ if !strings.Contains(importPath, "/vendor/") {
+ return importPathString(importPath)
+ }
+
+ return importPathString(importPath[strings.Index(importPath, "/vendor/")+len("/vendor/"):])
+}
diff --git a/metrics-server/vendor/k8s.io/gengo/types/comments.go b/metrics-server/vendor/k8s.io/gengo/types/comments.go
new file mode 100644
index 0000000..8150c38
--- /dev/null
+++ b/metrics-server/vendor/k8s.io/gengo/types/comments.go
@@ -0,0 +1,82 @@
+/*
+Copyright 2015 The Kubernetes 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 types contains go type information, packaged in a way that makes
+// auto-generation convenient, whether by template or straight go functions.
+package types
+
+import (
+ "fmt"
+ "strings"
+)
+
+// ExtractCommentTags parses comments for lines of the form:
+//
+// 'marker' + "key=value".
+//
+// Values are optional; "" is the default. A tag can be specified more than
+// one time and all values are returned. If the resulting map has an entry for
+// a key, the value (a slice) is guaranteed to have at least 1 element.
+//
+// Example: if you pass "+" for 'marker', and the following lines are in
+// the comments:
+// +foo=value1
+// +bar
+// +foo=value2
+// +baz="qux"
+// Then this function will return:
+// map[string][]string{"foo":{"value1, "value2"}, "bar": {""}, "baz": {"qux"}}
+func ExtractCommentTags(marker string, lines []string) map[string][]string {
+ out := map[string][]string{}
+ for _, line := range lines {
+ line = strings.Trim(line, " ")
+ if len(line) == 0 {
+ continue
+ }
+ if !strings.HasPrefix(line, marker) {
+ continue
+ }
+ // TODO: we could support multiple values per key if we split on spaces
+ kv := strings.SplitN(line[len(marker):], "=", 2)
+ if len(kv) == 2 {
+ out[kv[0]] = append(out[kv[0]], kv[1])
+ } else if len(kv) == 1 {
+ out[kv[0]] = append(out[kv[0]], "")
+ }
+ }
+ return out
+}
+
+// ExtractSingleBoolCommentTag parses comments for lines of the form:
+//
+// 'marker' + "key=value1"
+//
+// If the tag is not found, the default value is returned. Values are asserted
+// to be boolean ("true" or "false"), and any other value will cause an error
+// to be returned. If the key has multiple values, the first one will be used.
+func ExtractSingleBoolCommentTag(marker string, key string, defaultVal bool, lines []string) (bool, error) {
+ values := ExtractCommentTags(marker, lines)[key]
+ if values == nil {
+ return defaultVal, nil
+ }
+ if values[0] == "true" {
+ return true, nil
+ }
+ if values[0] == "false" {
+ return false, nil
+ }
+ return false, fmt.Errorf("tag value for %q is not boolean: %q", key, values[0])
+}
diff --git a/metrics-server/vendor/k8s.io/gengo/types/doc.go b/metrics-server/vendor/k8s.io/gengo/types/doc.go
new file mode 100644
index 0000000..74a969a
--- /dev/null
+++ b/metrics-server/vendor/k8s.io/gengo/types/doc.go
@@ -0,0 +1,19 @@
+/*
+Copyright 2015 The Kubernetes 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 types contains go type information, packaged in a way that makes
+// auto-generation convenient, whether by template or straight go functions.
+package types // import "k8s.io/gengo/types"
diff --git a/metrics-server/vendor/k8s.io/gengo/types/flatten.go b/metrics-server/vendor/k8s.io/gengo/types/flatten.go
new file mode 100644
index 0000000..585014e
--- /dev/null
+++ b/metrics-server/vendor/k8s.io/gengo/types/flatten.go
@@ -0,0 +1,57 @@
+/*
+Copyright 2015 The Kubernetes 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 types
+
+// FlattenMembers recursively takes any embedded members and puts them in the
+// top level, correctly hiding them if the top level hides them. There must not
+// be a cycle-- that implies infinite members.
+//
+// This is useful for e.g. computing all the valid keys in a json struct,
+// properly considering any configuration of embedded structs.
+func FlattenMembers(m []Member) []Member {
+ embedded := []Member{}
+ normal := []Member{}
+ type nameInfo struct {
+ top bool
+ i int
+ }
+ names := map[string]nameInfo{}
+ for i := range m {
+ if m[i].Embedded && m[i].Type.Kind == Struct {
+ embedded = append(embedded, m[i])
+ } else {
+ normal = append(normal, m[i])
+ names[m[i].Name] = nameInfo{true, len(normal) - 1}
+ }
+ }
+ for i := range embedded {
+ for _, e := range FlattenMembers(embedded[i].Type.Members) {
+ if info, found := names[e.Name]; found {
+ if info.top {
+ continue
+ }
+ if n := normal[info.i]; n.Name == e.Name && n.Type == e.Type {
+ continue
+ }
+ panic("conflicting members")
+ }
+ normal = append(normal, e)
+ names[e.Name] = nameInfo{false, len(normal) - 1}
+ }
+ }
+ return normal
+}
diff --git a/metrics-server/vendor/k8s.io/gengo/types/types.go b/metrics-server/vendor/k8s.io/gengo/types/types.go
new file mode 100644
index 0000000..aa3b712
--- /dev/null
+++ b/metrics-server/vendor/k8s.io/gengo/types/types.go
@@ -0,0 +1,499 @@
+/*
+Copyright 2015 The Kubernetes 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 types
+
+import "strings"
+
+// Ref makes a reference to the given type. It can only be used for e.g.
+// passing to namers.
+func Ref(packageName, typeName string) *Type {
+ return &Type{Name: Name{
+ Name: typeName,
+ Package: packageName,
+ }}
+}
+
+// A type name may have a package qualifier.
+type Name struct {
+ // Empty if embedded or builtin. This is the package path unless Path is specified.
+ Package string
+ // The type name.
+ Name string
+ // An optional location of the type definition for languages that can have disjoint
+ // packages and paths.
+ Path string
+}
+
+// String returns the name formatted as a string.
+func (n Name) String() string {
+ if n.Package == "" {
+ return n.Name
+ }
+ return n.Package + "." + n.Name
+}
+
+// ParseFullyQualifiedName parses a name like k8s.io/kubernetes/pkg/api.Pod into a Name.
+func ParseFullyQualifiedName(fqn string) Name {
+ cs := strings.Split(fqn, ".")
+ pkg := ""
+ if len(cs) > 1 {
+ pkg = strings.Join(cs[0:len(cs) - 1], ".")
+ }
+ return Name{
+ Name: cs[len(cs) - 1],
+ Package: pkg,
+ }
+}
+
+// The possible classes of types.
+type Kind string
+
+const (
+ // Builtin is a primitive, like bool, string, int.
+ Builtin Kind = "Builtin"
+ Struct Kind = "Struct"
+ Map Kind = "Map"
+ Slice Kind = "Slice"
+ Pointer Kind = "Pointer"
+
+ // Alias is an alias of another type, e.g. in:
+ // type Foo string
+ // type Bar Foo
+ // Bar is an alias of Foo.
+ //
+ // In the real go type system, Foo is a "Named" string; but to simplify
+ // generation, this type system will just say that Foo *is* a builtin.
+ // We then need "Alias" as a way for us to say that Bar *is* a Foo.
+ Alias Kind = "Alias"
+
+ // Interface is any type that could have differing types at run time.
+ Interface Kind = "Interface"
+
+ // The remaining types are included for completeness, but are not well
+ // supported.
+ Array Kind = "Array" // Array is just like slice, but has a fixed length.
+ Chan Kind = "Chan"
+ Func Kind = "Func"
+
+ // DeclarationOf is different from other Kinds; it indicates that instead of
+ // representing an actual Type, the type is a declaration of an instance of
+ // a type. E.g., a top-level function, variable, or constant. See the
+ // comment for Type.Name for more detail.
+ DeclarationOf Kind = "DeclarationOf"
+ Unknown Kind = ""
+ Unsupported Kind = "Unsupported"
+
+ // Protobuf is protobuf type.
+ Protobuf Kind = "Protobuf"
+)
+
+// Package holds package-level information.
+// Fields are public, as everything in this package, to enable consumption by
+// templates (for example). But it is strongly encouraged for code to build by
+// using the provided functions.
+type Package struct {
+ // Canonical name of this package-- its path.
+ Path string
+
+ // The location this package was loaded from
+ SourcePath string
+
+ // Short name of this package; the name that appears in the
+ // 'package x' line.
+ Name string
+
+ // The comment right above the package declaration in doc.go, if any.
+ DocComments []string
+
+ // All comments from doc.go, if any.
+ // TODO: remove Comments and use DocComments everywhere.
+ Comments []string
+
+ // Types within this package, indexed by their name (*not* including
+ // package name).
+ Types map[string]*Type
+
+ // Functions within this package, indexed by their name (*not* including
+ // package name).
+ Functions map[string]*Type
+
+ // Global variables within this package, indexed by their name (*not* including
+ // package name).
+ Variables map[string]*Type
+
+ // Packages imported by this package, indexed by (canonicalized)
+ // package path.
+ Imports map[string]*Package
+}
+
+// Has returns true if the given name references a type known to this package.
+func (p *Package) Has(name string) bool {
+ _, has := p.Types[name]
+ return has
+}
+
+// Type gets the given Type in this Package. If the Type is not already
+// defined, this will add it and return the new Type value. The caller is
+// expected to finish initialization.
+func (p *Package) Type(typeName string) *Type {
+ if t, ok := p.Types[typeName]; ok {
+ return t
+ }
+ if p.Path == "" {
+ // Import the standard builtin types!
+ if t, ok := builtins.Types[typeName]; ok {
+ p.Types[typeName] = t
+ return t
+ }
+ }
+ t := &Type{Name: Name{Package: p.Path, Name: typeName}}
+ p.Types[typeName] = t
+ return t
+}
+
+// Function gets the given function Type in this Package. If the function is
+// not already defined, this will add it. If a function is added, it's the
+// caller's responsibility to finish construction of the function by setting
+// Underlying to the correct type.
+func (p *Package) Function(funcName string) *Type {
+ if t, ok := p.Functions[funcName]; ok {
+ return t
+ }
+ t := &Type{Name: Name{Package: p.Path, Name: funcName}}
+ t.Kind = DeclarationOf
+ p.Functions[funcName] = t
+ return t
+}
+
+// Variable gets the given variable Type in this Package. If the variable is
+// not already defined, this will add it. If a variable is added, it's the caller's
+// responsibility to finish construction of the variable by setting Underlying
+// to the correct type.
+func (p *Package) Variable(varName string) *Type {
+ if t, ok := p.Variables[varName]; ok {
+ return t
+ }
+ t := &Type{Name: Name{Package: p.Path, Name: varName}}
+ t.Kind = DeclarationOf
+ p.Variables[varName] = t
+ return t
+}
+
+// HasImport returns true if p imports packageName. Package names include the
+// package directory.
+func (p *Package) HasImport(packageName string) bool {
+ _, has := p.Imports[packageName]
+ return has
+}
+
+// Universe is a map of all packages. The key is the package name, but you
+// should use Package(), Type(), Function(), or Variable() instead of direct
+// access.
+type Universe map[string]*Package
+
+// Type returns the canonical type for the given fully-qualified name. Builtin
+// types will always be found, even if they haven't been explicitly added to
+// the map. If a non-existing type is requested, this will create (a marker for)
+// it.
+func (u Universe) Type(n Name) *Type {
+ return u.Package(n.Package).Type(n.Name)
+}
+
+// Function returns the canonical function for the given fully-qualified name.
+// If a non-existing function is requested, this will create (a marker for) it.
+// If a marker is created, it's the caller's responsibility to finish
+// construction of the function by setting Underlying to the correct type.
+func (u Universe) Function(n Name) *Type {
+ return u.Package(n.Package).Function(n.Name)
+}
+
+// Variable returns the canonical variable for the given fully-qualified name.
+// If a non-existing variable is requested, this will create (a marker for) it.
+// If a marker is created, it's the caller's responsibility to finish
+// construction of the variable by setting Underlying to the correct type.
+func (u Universe) Variable(n Name) *Type {
+ return u.Package(n.Package).Variable(n.Name)
+}
+
+// AddImports registers import lines for packageName. May be called multiple times.
+// You are responsible for canonicalizing all package paths.
+func (u Universe) AddImports(packagePath string, importPaths ...string) {
+ p := u.Package(packagePath)
+ for _, i := range importPaths {
+ p.Imports[i] = u.Package(i)
+ }
+}
+
+// Package returns the Package for the given path.
+// If a non-existing package is requested, this will create (a marker for) it.
+// If a marker is created, it's the caller's responsibility to finish
+// construction of the package.
+func (u Universe) Package(packagePath string) *Package {
+ if p, ok := u[packagePath]; ok {
+ return p
+ }
+ p := &Package{
+ Path: packagePath,
+ Types: map[string]*Type{},
+ Functions: map[string]*Type{},
+ Variables: map[string]*Type{},
+ Imports: map[string]*Package{},
+ }
+ u[packagePath] = p
+ return p
+}
+
+// Type represents a subset of possible go types.
+type Type struct {
+ // There are two general categories of types, those explicitly named
+ // and those anonymous. Named ones will have a non-empty package in the
+ // name field.
+ //
+ // An exception: If Kind == DeclarationOf, then this name is the name of a
+ // top-level function, variable, or const, and the type can be found in Underlying.
+ // We do this to allow the naming system to work against these objects, even
+ // though they aren't strictly speaking types.
+ Name Name
+
+ // The general kind of this type.
+ Kind Kind
+
+ // If there are comment lines immediately before the type definition,
+ // they will be recorded here.
+ CommentLines []string
+
+ // If there are comment lines preceding the `CommentLines`, they will be
+ // recorded here. There are two cases:
+ // ---
+ // SecondClosestCommentLines
+ // a blank line
+ // CommentLines
+ // type definition
+ // ---
+ //
+ // or
+ // ---
+ // SecondClosestCommentLines
+ // a blank line
+ // type definition
+ // ---
+ SecondClosestCommentLines []string
+
+ // If Kind == Struct
+ Members []Member
+
+ // If Kind == Map, Slice, Pointer, or Chan
+ Elem *Type
+
+ // If Kind == Map, this is the map's key type.
+ Key *Type
+
+ // If Kind == Alias, this is the underlying type.
+ // If Kind == DeclarationOf, this is the type of the declaration.
+ Underlying *Type
+
+ // If Kind == Interface, this is the set of all required functions.
+ // Otherwise, if this is a named type, this is the list of methods that
+ // type has. (All elements will have Kind=="Func")
+ Methods map[string]*Type
+
+ // If Kind == func, this is the signature of the function.
+ Signature *Signature
+
+ // TODO: Add:
+ // * channel direction
+ // * array length
+}
+
+// String returns the name of the type.
+func (t *Type) String() string {
+ return t.Name.String()
+}
+
+// IsPrimitive returns whether the type is a built-in type or is an alias to a
+// built-in type. For example: strings and aliases of strings are primitives,
+// structs are not.
+func (t *Type) IsPrimitive() bool {
+ if t.Kind == Builtin || (t.Kind == Alias && t.Underlying.Kind == Builtin) {
+ return true
+ }
+ return false
+}
+
+// IsAssignable returns whether the type is deep-assignable. For example,
+// slices and maps and pointers are shallow copies, but ints and strings are
+// complete.
+func (t *Type) IsAssignable() bool {
+ if t.IsPrimitive() {
+ return true
+ }
+ if t.Kind == Struct {
+ for _, m := range t.Members {
+ if !m.Type.IsAssignable() {
+ return false
+ }
+ }
+ return true
+ }
+ return false
+}
+
+// IsAnonymousStruct returns true if the type is an anonymous struct or an alias
+// to an anonymous struct.
+func (t *Type) IsAnonymousStruct() bool {
+ return (t.Kind == Struct && t.Name.Name == "struct{}") || (t.Kind == Alias && t.Underlying.IsAnonymousStruct())
+}
+
+// A single struct member
+type Member struct {
+ // The name of the member.
+ Name string
+
+ // If the member is embedded (anonymous) this will be true, and the
+ // Name will be the type name.
+ Embedded bool
+
+ // If there are comment lines immediately before the member in the type
+ // definition, they will be recorded here.
+ CommentLines []string
+
+ // If there are tags along with this member, they will be saved here.
+ Tags string
+
+ // The type of this member.
+ Type *Type
+}
+
+// String returns the name and type of the member.
+func (m Member) String() string {
+ return m.Name + " " + m.Type.String()
+}
+
+// Signature is a function's signature.
+type Signature struct {
+ // TODO: store the parameter names, not just types.
+
+ // If a method of some type, this is the type it's a member of.
+ Receiver *Type
+ Parameters []*Type
+ Results []*Type
+
+ // True if the last in parameter is of the form ...T.
+ Variadic bool
+
+ // If there are comment lines immediately before this
+ // signature/method/function declaration, they will be recorded here.
+ CommentLines []string
+}
+
+// Built in types.
+var (
+ String = &Type{
+ Name: Name{Name: "string"},
+ Kind: Builtin,
+ }
+ Int64 = &Type{
+ Name: Name{Name: "int64"},
+ Kind: Builtin,
+ }
+ Int32 = &Type{
+ Name: Name{Name: "int32"},
+ Kind: Builtin,
+ }
+ Int16 = &Type{
+ Name: Name{Name: "int16"},
+ Kind: Builtin,
+ }
+ Int = &Type{
+ Name: Name{Name: "int"},
+ Kind: Builtin,
+ }
+ Uint64 = &Type{
+ Name: Name{Name: "uint64"},
+ Kind: Builtin,
+ }
+ Uint32 = &Type{
+ Name: Name{Name: "uint32"},
+ Kind: Builtin,
+ }
+ Uint16 = &Type{
+ Name: Name{Name: "uint16"},
+ Kind: Builtin,
+ }
+ Uint = &Type{
+ Name: Name{Name: "uint"},
+ Kind: Builtin,
+ }
+ Uintptr = &Type{
+ Name: Name{Name: "uintptr"},
+ Kind: Builtin,
+ }
+ Float64 = &Type{
+ Name: Name{Name: "float64"},
+ Kind: Builtin,
+ }
+ Float32 = &Type{
+ Name: Name{Name: "float32"},
+ Kind: Builtin,
+ }
+ Float = &Type{
+ Name: Name{Name: "float"},
+ Kind: Builtin,
+ }
+ Bool = &Type{
+ Name: Name{Name: "bool"},
+ Kind: Builtin,
+ }
+ Byte = &Type{
+ Name: Name{Name: "byte"},
+ Kind: Builtin,
+ }
+
+ builtins = &Package{
+ Types: map[string]*Type{
+ "bool": Bool,
+ "string": String,
+ "int": Int,
+ "int64": Int64,
+ "int32": Int32,
+ "int16": Int16,
+ "int8": Byte,
+ "uint": Uint,
+ "uint64": Uint64,
+ "uint32": Uint32,
+ "uint16": Uint16,
+ "uint8": Byte,
+ "uintptr": Uintptr,
+ "byte": Byte,
+ "float": Float,
+ "float64": Float64,
+ "float32": Float32,
+ },
+ Imports: map[string]*Package{},
+ Path: "",
+ Name: "",
+ }
+)
+
+func IsInteger(t *Type) bool {
+ switch t {
+ case Int, Int64, Int32, Int16, Uint, Uint64, Uint32, Uint16, Byte:
+ return true
+ default:
+ return false
+ }
+}