Merge pull request #30738 from caesarxuchao/copy-keep-vendor
Automatic merge from submit-queue Keep vendor/ and Godep/ when creating the staging client, add a readme In copy.sh, instead of removing the vendor/, moving it to _vendor. vendor/ is needed when we publish the staging client to its own repository.
This commit is contained in:
@@ -260,6 +260,7 @@ kube::util::gen-analytics() {
|
|||||||
mdfiles=($( find "${dir}" -name "*.md" -type f \
|
mdfiles=($( find "${dir}" -name "*.md" -type f \
|
||||||
-not -path '*/\.*' \
|
-not -path '*/\.*' \
|
||||||
-not -path "${path}/vendor/*" \
|
-not -path "${path}/vendor/*" \
|
||||||
|
-not -path "${path}/staging/*" \
|
||||||
-not -path "${path}/third_party/*" \
|
-not -path "${path}/third_party/*" \
|
||||||
-not -path "${path}/_gopath/*" \
|
-not -path "${path}/_gopath/*" \
|
||||||
-not -path "${path}/_output/*" \
|
-not -path "${path}/_output/*" \
|
||||||
|
|||||||
@@ -55,6 +55,8 @@ def get_all_files(rootdir):
|
|||||||
# don't visit certain dirs
|
# don't visit certain dirs
|
||||||
if 'vendor' in dirs:
|
if 'vendor' in dirs:
|
||||||
dirs.remove('vendor')
|
dirs.remove('vendor')
|
||||||
|
if 'staging' in dirs:
|
||||||
|
dirs.remove('staging')
|
||||||
if '_output' in dirs:
|
if '_output' in dirs:
|
||||||
dirs.remove('_output')
|
dirs.remove('_output')
|
||||||
if '_gopath' in dirs:
|
if '_gopath' in dirs:
|
||||||
|
|||||||
@@ -37,6 +37,7 @@ find_files() {
|
|||||||
-o -wholename './target' \
|
-o -wholename './target' \
|
||||||
-o -wholename '*/third_party/*' \
|
-o -wholename '*/third_party/*' \
|
||||||
-o -wholename '*/vendor/*' \
|
-o -wholename '*/vendor/*' \
|
||||||
|
-o -wholename './staging' \
|
||||||
\) -prune \
|
\) -prune \
|
||||||
\) -name '*.go'
|
\) -name '*.go'
|
||||||
}
|
}
|
||||||
|
|||||||
3
staging/README.md
Normal file
3
staging/README.md
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
This _staging/src/k8s.io/client-go directory is the staging area of the client repo. It contains a versioned client, tools built around the client like the reflector, and all the client dependencies. The content will be periodically published to k8s.io/client-go repo.
|
||||||
|
The staged content is copied from the main repo, i.e., k8s.io/kubernetes, with directory rearrangement and necessary rewritings. To sync the content with the latest code in your local k8s.io/kubernetes, you need to run `godep restore` in k8s root directory, then run _staging/src/k8s.io/client-go/copy.sh.
|
||||||
|
vendor/k8s.io/client-go is a symlink pointing to this staging area, so to use the packages in the staging area, you can import it as "vendor/client-go/<package-name>", as if the client were vendored. The client will be vendored from k8s.io/client-go for real after the test matrix is converted to vendor k8s components.
|
||||||
5
staging/src/k8s.io/client-go/1.4/Godeps/Readme
generated
Normal file
5
staging/src/k8s.io/client-go/1.4/Godeps/Readme
generated
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
This directory tree is generated automatically by godep.
|
||||||
|
|
||||||
|
Please do not edit.
|
||||||
|
|
||||||
|
See https://github.com/tools/godep for more information.
|
||||||
13
staging/src/k8s.io/client-go/1.4/_vendor/bitbucket.org/ww/goautoneg/Makefile
generated
Normal file
13
staging/src/k8s.io/client-go/1.4/_vendor/bitbucket.org/ww/goautoneg/Makefile
generated
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
include $(GOROOT)/src/Make.inc
|
||||||
|
|
||||||
|
TARG=bitbucket.org/ww/goautoneg
|
||||||
|
GOFILES=autoneg.go
|
||||||
|
|
||||||
|
include $(GOROOT)/src/Make.pkg
|
||||||
|
|
||||||
|
format:
|
||||||
|
gofmt -w *.go
|
||||||
|
|
||||||
|
docs:
|
||||||
|
gomake clean
|
||||||
|
godoc ${TARG} > README.txt
|
||||||
67
staging/src/k8s.io/client-go/1.4/_vendor/bitbucket.org/ww/goautoneg/README.txt
generated
Normal file
67
staging/src/k8s.io/client-go/1.4/_vendor/bitbucket.org/ww/goautoneg/README.txt
generated
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
PACKAGE
|
||||||
|
|
||||||
|
package goautoneg
|
||||||
|
import "bitbucket.org/ww/goautoneg"
|
||||||
|
|
||||||
|
HTTP Content-Type Autonegotiation.
|
||||||
|
|
||||||
|
The functions in this package implement the behaviour specified in
|
||||||
|
http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html
|
||||||
|
|
||||||
|
Copyright (c) 2011, Open Knowledge Foundation Ltd.
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are
|
||||||
|
met:
|
||||||
|
|
||||||
|
Redistributions of source code must retain the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
|
||||||
|
Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in
|
||||||
|
the documentation and/or other materials provided with the
|
||||||
|
distribution.
|
||||||
|
|
||||||
|
Neither the name of the Open Knowledge Foundation Ltd. nor the
|
||||||
|
names of its contributors may be used to endorse or promote
|
||||||
|
products derived from this software without specific prior written
|
||||||
|
permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
|
||||||
|
FUNCTIONS
|
||||||
|
|
||||||
|
func Negotiate(header string, alternatives []string) (content_type string)
|
||||||
|
Negotiate the most appropriate content_type given the accept header
|
||||||
|
and a list of alternatives.
|
||||||
|
|
||||||
|
func ParseAccept(header string) (accept []Accept)
|
||||||
|
Parse an Accept Header string returning a sorted list
|
||||||
|
of clauses
|
||||||
|
|
||||||
|
|
||||||
|
TYPES
|
||||||
|
|
||||||
|
type Accept struct {
|
||||||
|
Type, SubType string
|
||||||
|
Q float32
|
||||||
|
Params map[string]string
|
||||||
|
}
|
||||||
|
Structure to represent a clause in an HTTP Accept Header
|
||||||
|
|
||||||
|
|
||||||
|
SUBDIRECTORIES
|
||||||
|
|
||||||
|
.hg
|
||||||
162
staging/src/k8s.io/client-go/1.4/_vendor/bitbucket.org/ww/goautoneg/autoneg.go
generated
Normal file
162
staging/src/k8s.io/client-go/1.4/_vendor/bitbucket.org/ww/goautoneg/autoneg.go
generated
Normal file
@@ -0,0 +1,162 @@
|
|||||||
|
/*
|
||||||
|
HTTP Content-Type Autonegotiation.
|
||||||
|
|
||||||
|
The functions in this package implement the behaviour specified in
|
||||||
|
http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html
|
||||||
|
|
||||||
|
Copyright (c) 2011, Open Knowledge Foundation Ltd.
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are
|
||||||
|
met:
|
||||||
|
|
||||||
|
Redistributions of source code must retain the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
|
||||||
|
Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in
|
||||||
|
the documentation and/or other materials provided with the
|
||||||
|
distribution.
|
||||||
|
|
||||||
|
Neither the name of the Open Knowledge Foundation Ltd. nor the
|
||||||
|
names of its contributors may be used to endorse or promote
|
||||||
|
products derived from this software without specific prior written
|
||||||
|
permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
|
||||||
|
*/
|
||||||
|
package goautoneg
|
||||||
|
|
||||||
|
import (
|
||||||
|
"sort"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Structure to represent a clause in an HTTP Accept Header
|
||||||
|
type Accept struct {
|
||||||
|
Type, SubType string
|
||||||
|
Q float64
|
||||||
|
Params map[string]string
|
||||||
|
}
|
||||||
|
|
||||||
|
// For internal use, so that we can use the sort interface
|
||||||
|
type accept_slice []Accept
|
||||||
|
|
||||||
|
func (accept accept_slice) Len() int {
|
||||||
|
slice := []Accept(accept)
|
||||||
|
return len(slice)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (accept accept_slice) Less(i, j int) bool {
|
||||||
|
slice := []Accept(accept)
|
||||||
|
ai, aj := slice[i], slice[j]
|
||||||
|
if ai.Q > aj.Q {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
if ai.Type != "*" && aj.Type == "*" {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
if ai.SubType != "*" && aj.SubType == "*" {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func (accept accept_slice) Swap(i, j int) {
|
||||||
|
slice := []Accept(accept)
|
||||||
|
slice[i], slice[j] = slice[j], slice[i]
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parse an Accept Header string returning a sorted list
|
||||||
|
// of clauses
|
||||||
|
func ParseAccept(header string) (accept []Accept) {
|
||||||
|
parts := strings.Split(header, ",")
|
||||||
|
accept = make([]Accept, 0, len(parts))
|
||||||
|
for _, part := range parts {
|
||||||
|
part := strings.Trim(part, " ")
|
||||||
|
|
||||||
|
a := Accept{}
|
||||||
|
a.Params = make(map[string]string)
|
||||||
|
a.Q = 1.0
|
||||||
|
|
||||||
|
mrp := strings.Split(part, ";")
|
||||||
|
|
||||||
|
media_range := mrp[0]
|
||||||
|
sp := strings.Split(media_range, "/")
|
||||||
|
a.Type = strings.Trim(sp[0], " ")
|
||||||
|
|
||||||
|
switch {
|
||||||
|
case len(sp) == 1 && a.Type == "*":
|
||||||
|
a.SubType = "*"
|
||||||
|
case len(sp) == 2:
|
||||||
|
a.SubType = strings.Trim(sp[1], " ")
|
||||||
|
default:
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(mrp) == 1 {
|
||||||
|
accept = append(accept, a)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, param := range mrp[1:] {
|
||||||
|
sp := strings.SplitN(param, "=", 2)
|
||||||
|
if len(sp) != 2 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
token := strings.Trim(sp[0], " ")
|
||||||
|
if token == "q" {
|
||||||
|
a.Q, _ = strconv.ParseFloat(sp[1], 32)
|
||||||
|
} else {
|
||||||
|
a.Params[token] = strings.Trim(sp[1], " ")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
accept = append(accept, a)
|
||||||
|
}
|
||||||
|
|
||||||
|
slice := accept_slice(accept)
|
||||||
|
sort.Sort(slice)
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Negotiate the most appropriate content_type given the accept header
|
||||||
|
// and a list of alternatives.
|
||||||
|
func Negotiate(header string, alternatives []string) (content_type string) {
|
||||||
|
asp := make([][]string, 0, len(alternatives))
|
||||||
|
for _, ctype := range alternatives {
|
||||||
|
asp = append(asp, strings.SplitN(ctype, "/", 2))
|
||||||
|
}
|
||||||
|
for _, clause := range ParseAccept(header) {
|
||||||
|
for i, ctsp := range asp {
|
||||||
|
if clause.Type == ctsp[0] && clause.SubType == ctsp[1] {
|
||||||
|
content_type = alternatives[i]
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if clause.Type == ctsp[0] && clause.SubType == "*" {
|
||||||
|
content_type = alternatives[i]
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if clause.Type == "*" && clause.SubType == "*" {
|
||||||
|
content_type = alternatives[i]
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
20
staging/src/k8s.io/client-go/1.4/_vendor/github.com/beorn7/perks/LICENSE
generated
Normal file
20
staging/src/k8s.io/client-go/1.4/_vendor/github.com/beorn7/perks/LICENSE
generated
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
Copyright (C) 2013 Blake Mizerany
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining
|
||||||
|
a copy of this software and associated documentation files (the
|
||||||
|
"Software"), to deal in the Software without restriction, including
|
||||||
|
without limitation the rights to use, copy, modify, merge, publish,
|
||||||
|
distribute, sublicense, and/or sell copies of the Software, and to
|
||||||
|
permit persons to whom the Software is furnished to do so, subject to
|
||||||
|
the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be
|
||||||
|
included in all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||||
|
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||||
|
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||||
|
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
2388
staging/src/k8s.io/client-go/1.4/_vendor/github.com/beorn7/perks/quantile/exampledata.txt
generated
Normal file
2388
staging/src/k8s.io/client-go/1.4/_vendor/github.com/beorn7/perks/quantile/exampledata.txt
generated
Normal file
File diff suppressed because it is too large
Load Diff
292
staging/src/k8s.io/client-go/1.4/_vendor/github.com/beorn7/perks/quantile/stream.go
generated
Normal file
292
staging/src/k8s.io/client-go/1.4/_vendor/github.com/beorn7/perks/quantile/stream.go
generated
Normal file
@@ -0,0 +1,292 @@
|
|||||||
|
// Package quantile computes approximate quantiles over an unbounded data
|
||||||
|
// stream within low memory and CPU bounds.
|
||||||
|
//
|
||||||
|
// A small amount of accuracy is traded to achieve the above properties.
|
||||||
|
//
|
||||||
|
// Multiple streams can be merged before calling Query to generate a single set
|
||||||
|
// of results. This is meaningful when the streams represent the same type of
|
||||||
|
// data. See Merge and Samples.
|
||||||
|
//
|
||||||
|
// For more detailed information about the algorithm used, see:
|
||||||
|
//
|
||||||
|
// Effective Computation of Biased Quantiles over Data Streams
|
||||||
|
//
|
||||||
|
// http://www.cs.rutgers.edu/~muthu/bquant.pdf
|
||||||
|
package quantile
|
||||||
|
|
||||||
|
import (
|
||||||
|
"math"
|
||||||
|
"sort"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Sample holds an observed value and meta information for compression. JSON
|
||||||
|
// tags have been added for convenience.
|
||||||
|
type Sample struct {
|
||||||
|
Value float64 `json:",string"`
|
||||||
|
Width float64 `json:",string"`
|
||||||
|
Delta float64 `json:",string"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Samples represents a slice of samples. It implements sort.Interface.
|
||||||
|
type Samples []Sample
|
||||||
|
|
||||||
|
func (a Samples) Len() int { return len(a) }
|
||||||
|
func (a Samples) Less(i, j int) bool { return a[i].Value < a[j].Value }
|
||||||
|
func (a Samples) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
|
||||||
|
|
||||||
|
type invariant func(s *stream, r float64) float64
|
||||||
|
|
||||||
|
// NewLowBiased returns an initialized Stream for low-biased quantiles
|
||||||
|
// (e.g. 0.01, 0.1, 0.5) where the needed quantiles are not known a priori, but
|
||||||
|
// error guarantees can still be given even for the lower ranks of the data
|
||||||
|
// distribution.
|
||||||
|
//
|
||||||
|
// The provided epsilon is a relative error, i.e. the true quantile of a value
|
||||||
|
// returned by a query is guaranteed to be within (1±Epsilon)*Quantile.
|
||||||
|
//
|
||||||
|
// See http://www.cs.rutgers.edu/~muthu/bquant.pdf for time, space, and error
|
||||||
|
// properties.
|
||||||
|
func NewLowBiased(epsilon float64) *Stream {
|
||||||
|
ƒ := func(s *stream, r float64) float64 {
|
||||||
|
return 2 * epsilon * r
|
||||||
|
}
|
||||||
|
return newStream(ƒ)
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewHighBiased returns an initialized Stream for high-biased quantiles
|
||||||
|
// (e.g. 0.01, 0.1, 0.5) where the needed quantiles are not known a priori, but
|
||||||
|
// error guarantees can still be given even for the higher ranks of the data
|
||||||
|
// distribution.
|
||||||
|
//
|
||||||
|
// The provided epsilon is a relative error, i.e. the true quantile of a value
|
||||||
|
// returned by a query is guaranteed to be within 1-(1±Epsilon)*(1-Quantile).
|
||||||
|
//
|
||||||
|
// See http://www.cs.rutgers.edu/~muthu/bquant.pdf for time, space, and error
|
||||||
|
// properties.
|
||||||
|
func NewHighBiased(epsilon float64) *Stream {
|
||||||
|
ƒ := func(s *stream, r float64) float64 {
|
||||||
|
return 2 * epsilon * (s.n - r)
|
||||||
|
}
|
||||||
|
return newStream(ƒ)
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewTargeted returns an initialized Stream concerned with a particular set of
|
||||||
|
// quantile values that are supplied a priori. Knowing these a priori reduces
|
||||||
|
// space and computation time. The targets map maps the desired quantiles to
|
||||||
|
// their absolute errors, i.e. the true quantile of a value returned by a query
|
||||||
|
// is guaranteed to be within (Quantile±Epsilon).
|
||||||
|
//
|
||||||
|
// See http://www.cs.rutgers.edu/~muthu/bquant.pdf for time, space, and error properties.
|
||||||
|
func NewTargeted(targets map[float64]float64) *Stream {
|
||||||
|
ƒ := func(s *stream, r float64) float64 {
|
||||||
|
var m = math.MaxFloat64
|
||||||
|
var f float64
|
||||||
|
for quantile, epsilon := range targets {
|
||||||
|
if quantile*s.n <= r {
|
||||||
|
f = (2 * epsilon * r) / quantile
|
||||||
|
} else {
|
||||||
|
f = (2 * epsilon * (s.n - r)) / (1 - quantile)
|
||||||
|
}
|
||||||
|
if f < m {
|
||||||
|
m = f
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return m
|
||||||
|
}
|
||||||
|
return newStream(ƒ)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Stream computes quantiles for a stream of float64s. It is not thread-safe by
|
||||||
|
// design. Take care when using across multiple goroutines.
|
||||||
|
type Stream struct {
|
||||||
|
*stream
|
||||||
|
b Samples
|
||||||
|
sorted bool
|
||||||
|
}
|
||||||
|
|
||||||
|
func newStream(ƒ invariant) *Stream {
|
||||||
|
x := &stream{ƒ: ƒ}
|
||||||
|
return &Stream{x, make(Samples, 0, 500), true}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Insert inserts v into the stream.
|
||||||
|
func (s *Stream) Insert(v float64) {
|
||||||
|
s.insert(Sample{Value: v, Width: 1})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Stream) insert(sample Sample) {
|
||||||
|
s.b = append(s.b, sample)
|
||||||
|
s.sorted = false
|
||||||
|
if len(s.b) == cap(s.b) {
|
||||||
|
s.flush()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Query returns the computed qth percentiles value. If s was created with
|
||||||
|
// NewTargeted, and q is not in the set of quantiles provided a priori, Query
|
||||||
|
// will return an unspecified result.
|
||||||
|
func (s *Stream) Query(q float64) float64 {
|
||||||
|
if !s.flushed() {
|
||||||
|
// Fast path when there hasn't been enough data for a flush;
|
||||||
|
// this also yields better accuracy for small sets of data.
|
||||||
|
l := len(s.b)
|
||||||
|
if l == 0 {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
i := int(float64(l) * q)
|
||||||
|
if i > 0 {
|
||||||
|
i -= 1
|
||||||
|
}
|
||||||
|
s.maybeSort()
|
||||||
|
return s.b[i].Value
|
||||||
|
}
|
||||||
|
s.flush()
|
||||||
|
return s.stream.query(q)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Merge merges samples into the underlying streams samples. This is handy when
|
||||||
|
// merging multiple streams from separate threads, database shards, etc.
|
||||||
|
//
|
||||||
|
// ATTENTION: This method is broken and does not yield correct results. The
|
||||||
|
// underlying algorithm is not capable of merging streams correctly.
|
||||||
|
func (s *Stream) Merge(samples Samples) {
|
||||||
|
sort.Sort(samples)
|
||||||
|
s.stream.merge(samples)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reset reinitializes and clears the list reusing the samples buffer memory.
|
||||||
|
func (s *Stream) Reset() {
|
||||||
|
s.stream.reset()
|
||||||
|
s.b = s.b[:0]
|
||||||
|
}
|
||||||
|
|
||||||
|
// Samples returns stream samples held by s.
|
||||||
|
func (s *Stream) Samples() Samples {
|
||||||
|
if !s.flushed() {
|
||||||
|
return s.b
|
||||||
|
}
|
||||||
|
s.flush()
|
||||||
|
return s.stream.samples()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Count returns the total number of samples observed in the stream
|
||||||
|
// since initialization.
|
||||||
|
func (s *Stream) Count() int {
|
||||||
|
return len(s.b) + s.stream.count()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Stream) flush() {
|
||||||
|
s.maybeSort()
|
||||||
|
s.stream.merge(s.b)
|
||||||
|
s.b = s.b[:0]
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Stream) maybeSort() {
|
||||||
|
if !s.sorted {
|
||||||
|
s.sorted = true
|
||||||
|
sort.Sort(s.b)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Stream) flushed() bool {
|
||||||
|
return len(s.stream.l) > 0
|
||||||
|
}
|
||||||
|
|
||||||
|
type stream struct {
|
||||||
|
n float64
|
||||||
|
l []Sample
|
||||||
|
ƒ invariant
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *stream) reset() {
|
||||||
|
s.l = s.l[:0]
|
||||||
|
s.n = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *stream) insert(v float64) {
|
||||||
|
s.merge(Samples{{v, 1, 0}})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *stream) merge(samples Samples) {
|
||||||
|
// TODO(beorn7): This tries to merge not only individual samples, but
|
||||||
|
// whole summaries. The paper doesn't mention merging summaries at
|
||||||
|
// all. Unittests show that the merging is inaccurate. Find out how to
|
||||||
|
// do merges properly.
|
||||||
|
var r float64
|
||||||
|
i := 0
|
||||||
|
for _, sample := range samples {
|
||||||
|
for ; i < len(s.l); i++ {
|
||||||
|
c := s.l[i]
|
||||||
|
if c.Value > sample.Value {
|
||||||
|
// Insert at position i.
|
||||||
|
s.l = append(s.l, Sample{})
|
||||||
|
copy(s.l[i+1:], s.l[i:])
|
||||||
|
s.l[i] = Sample{
|
||||||
|
sample.Value,
|
||||||
|
sample.Width,
|
||||||
|
math.Max(sample.Delta, math.Floor(s.ƒ(s, r))-1),
|
||||||
|
// TODO(beorn7): How to calculate delta correctly?
|
||||||
|
}
|
||||||
|
i++
|
||||||
|
goto inserted
|
||||||
|
}
|
||||||
|
r += c.Width
|
||||||
|
}
|
||||||
|
s.l = append(s.l, Sample{sample.Value, sample.Width, 0})
|
||||||
|
i++
|
||||||
|
inserted:
|
||||||
|
s.n += sample.Width
|
||||||
|
r += sample.Width
|
||||||
|
}
|
||||||
|
s.compress()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *stream) count() int {
|
||||||
|
return int(s.n)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *stream) query(q float64) float64 {
|
||||||
|
t := math.Ceil(q * s.n)
|
||||||
|
t += math.Ceil(s.ƒ(s, t) / 2)
|
||||||
|
p := s.l[0]
|
||||||
|
var r float64
|
||||||
|
for _, c := range s.l[1:] {
|
||||||
|
r += p.Width
|
||||||
|
if r+c.Width+c.Delta > t {
|
||||||
|
return p.Value
|
||||||
|
}
|
||||||
|
p = c
|
||||||
|
}
|
||||||
|
return p.Value
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *stream) compress() {
|
||||||
|
if len(s.l) < 2 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
x := s.l[len(s.l)-1]
|
||||||
|
xi := len(s.l) - 1
|
||||||
|
r := s.n - 1 - x.Width
|
||||||
|
|
||||||
|
for i := len(s.l) - 2; i >= 0; i-- {
|
||||||
|
c := s.l[i]
|
||||||
|
if c.Width+x.Width+x.Delta <= s.ƒ(s, r) {
|
||||||
|
x.Width += c.Width
|
||||||
|
s.l[xi] = x
|
||||||
|
// Remove element at i.
|
||||||
|
copy(s.l[i:], s.l[i+1:])
|
||||||
|
s.l = s.l[:len(s.l)-1]
|
||||||
|
xi -= 1
|
||||||
|
} else {
|
||||||
|
x = c
|
||||||
|
xi = i
|
||||||
|
}
|
||||||
|
r -= c.Width
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *stream) samples() Samples {
|
||||||
|
samples := make(Samples, len(s.l))
|
||||||
|
copy(samples, s.l)
|
||||||
|
return samples
|
||||||
|
}
|
||||||
22
staging/src/k8s.io/client-go/1.4/_vendor/github.com/blang/semver/LICENSE
generated
Normal file
22
staging/src/k8s.io/client-go/1.4/_vendor/github.com/blang/semver/LICENSE
generated
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
The MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2014 Benedikt Lang <github at benediktlang.de>
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
THE SOFTWARE.
|
||||||
|
|
||||||
23
staging/src/k8s.io/client-go/1.4/_vendor/github.com/blang/semver/json.go
generated
Normal file
23
staging/src/k8s.io/client-go/1.4/_vendor/github.com/blang/semver/json.go
generated
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
package semver
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
)
|
||||||
|
|
||||||
|
// MarshalJSON implements the encoding/json.Marshaler interface.
|
||||||
|
func (v Version) MarshalJSON() ([]byte, error) {
|
||||||
|
return json.Marshal(v.String())
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalJSON implements the encoding/json.Unmarshaler interface.
|
||||||
|
func (v *Version) UnmarshalJSON(data []byte) (err error) {
|
||||||
|
var versionString string
|
||||||
|
|
||||||
|
if err = json.Unmarshal(data, &versionString); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
*v, err = Parse(versionString)
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
395
staging/src/k8s.io/client-go/1.4/_vendor/github.com/blang/semver/semver.go
generated
Normal file
395
staging/src/k8s.io/client-go/1.4/_vendor/github.com/blang/semver/semver.go
generated
Normal file
@@ -0,0 +1,395 @@
|
|||||||
|
package semver
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
numbers string = "0123456789"
|
||||||
|
alphas = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-"
|
||||||
|
alphanum = alphas + numbers
|
||||||
|
)
|
||||||
|
|
||||||
|
// SpecVersion is the latest fully supported spec version of semver
|
||||||
|
var SpecVersion = Version{
|
||||||
|
Major: 2,
|
||||||
|
Minor: 0,
|
||||||
|
Patch: 0,
|
||||||
|
}
|
||||||
|
|
||||||
|
// Version represents a semver compatible version
|
||||||
|
type Version struct {
|
||||||
|
Major uint64
|
||||||
|
Minor uint64
|
||||||
|
Patch uint64
|
||||||
|
Pre []PRVersion
|
||||||
|
Build []string //No Precendence
|
||||||
|
}
|
||||||
|
|
||||||
|
// Version to string
|
||||||
|
func (v Version) String() string {
|
||||||
|
b := make([]byte, 0, 5)
|
||||||
|
b = strconv.AppendUint(b, v.Major, 10)
|
||||||
|
b = append(b, '.')
|
||||||
|
b = strconv.AppendUint(b, v.Minor, 10)
|
||||||
|
b = append(b, '.')
|
||||||
|
b = strconv.AppendUint(b, v.Patch, 10)
|
||||||
|
|
||||||
|
if len(v.Pre) > 0 {
|
||||||
|
b = append(b, '-')
|
||||||
|
b = append(b, v.Pre[0].String()...)
|
||||||
|
|
||||||
|
for _, pre := range v.Pre[1:] {
|
||||||
|
b = append(b, '.')
|
||||||
|
b = append(b, pre.String()...)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(v.Build) > 0 {
|
||||||
|
b = append(b, '+')
|
||||||
|
b = append(b, v.Build[0]...)
|
||||||
|
|
||||||
|
for _, build := range v.Build[1:] {
|
||||||
|
b = append(b, '.')
|
||||||
|
b = append(b, build...)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return string(b)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Equals checks if v is equal to o.
|
||||||
|
func (v Version) Equals(o Version) bool {
|
||||||
|
return (v.Compare(o) == 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
// EQ checks if v is equal to o.
|
||||||
|
func (v Version) EQ(o Version) bool {
|
||||||
|
return (v.Compare(o) == 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
// NE checks if v is not equal to o.
|
||||||
|
func (v Version) NE(o Version) bool {
|
||||||
|
return (v.Compare(o) != 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GT checks if v is greater than o.
|
||||||
|
func (v Version) GT(o Version) bool {
|
||||||
|
return (v.Compare(o) == 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GTE checks if v is greater than or equal to o.
|
||||||
|
func (v Version) GTE(o Version) bool {
|
||||||
|
return (v.Compare(o) >= 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GE checks if v is greater than or equal to o.
|
||||||
|
func (v Version) GE(o Version) bool {
|
||||||
|
return (v.Compare(o) >= 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
// LT checks if v is less than o.
|
||||||
|
func (v Version) LT(o Version) bool {
|
||||||
|
return (v.Compare(o) == -1)
|
||||||
|
}
|
||||||
|
|
||||||
|
// LTE checks if v is less than or equal to o.
|
||||||
|
func (v Version) LTE(o Version) bool {
|
||||||
|
return (v.Compare(o) <= 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
// LE checks if v is less than or equal to o.
|
||||||
|
func (v Version) LE(o Version) bool {
|
||||||
|
return (v.Compare(o) <= 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Compare compares Versions v to o:
|
||||||
|
// -1 == v is less than o
|
||||||
|
// 0 == v is equal to o
|
||||||
|
// 1 == v is greater than o
|
||||||
|
func (v Version) Compare(o Version) int {
|
||||||
|
if v.Major != o.Major {
|
||||||
|
if v.Major > o.Major {
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
if v.Minor != o.Minor {
|
||||||
|
if v.Minor > o.Minor {
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
if v.Patch != o.Patch {
|
||||||
|
if v.Patch > o.Patch {
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
|
||||||
|
// Quick comparison if a version has no prerelease versions
|
||||||
|
if len(v.Pre) == 0 && len(o.Pre) == 0 {
|
||||||
|
return 0
|
||||||
|
} else if len(v.Pre) == 0 && len(o.Pre) > 0 {
|
||||||
|
return 1
|
||||||
|
} else if len(v.Pre) > 0 && len(o.Pre) == 0 {
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
|
||||||
|
i := 0
|
||||||
|
for ; i < len(v.Pre) && i < len(o.Pre); i++ {
|
||||||
|
if comp := v.Pre[i].Compare(o.Pre[i]); comp == 0 {
|
||||||
|
continue
|
||||||
|
} else if comp == 1 {
|
||||||
|
return 1
|
||||||
|
} else {
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If all pr versions are the equal but one has further prversion, this one greater
|
||||||
|
if i == len(v.Pre) && i == len(o.Pre) {
|
||||||
|
return 0
|
||||||
|
} else if i == len(v.Pre) && i < len(o.Pre) {
|
||||||
|
return -1
|
||||||
|
} else {
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate validates v and returns error in case
|
||||||
|
func (v Version) Validate() error {
|
||||||
|
// Major, Minor, Patch already validated using uint64
|
||||||
|
|
||||||
|
for _, pre := range v.Pre {
|
||||||
|
if !pre.IsNum { //Numeric prerelease versions already uint64
|
||||||
|
if len(pre.VersionStr) == 0 {
|
||||||
|
return fmt.Errorf("Prerelease can not be empty %q", pre.VersionStr)
|
||||||
|
}
|
||||||
|
if !containsOnly(pre.VersionStr, alphanum) {
|
||||||
|
return fmt.Errorf("Invalid character(s) found in prerelease %q", pre.VersionStr)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, build := range v.Build {
|
||||||
|
if len(build) == 0 {
|
||||||
|
return fmt.Errorf("Build meta data can not be empty %q", build)
|
||||||
|
}
|
||||||
|
if !containsOnly(build, alphanum) {
|
||||||
|
return fmt.Errorf("Invalid character(s) found in build meta data %q", build)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// New is an alias for Parse and returns a pointer, parses version string and returns a validated Version or error
|
||||||
|
func New(s string) (vp *Version, err error) {
|
||||||
|
v, err := Parse(s)
|
||||||
|
vp = &v
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make is an alias for Parse, parses version string and returns a validated Version or error
|
||||||
|
func Make(s string) (Version, error) {
|
||||||
|
return Parse(s)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parse parses version string and returns a validated Version or error
|
||||||
|
func Parse(s string) (Version, error) {
|
||||||
|
if len(s) == 0 {
|
||||||
|
return Version{}, errors.New("Version string empty")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Split into major.minor.(patch+pr+meta)
|
||||||
|
parts := strings.SplitN(s, ".", 3)
|
||||||
|
if len(parts) != 3 {
|
||||||
|
return Version{}, errors.New("No Major.Minor.Patch elements found")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Major
|
||||||
|
if !containsOnly(parts[0], numbers) {
|
||||||
|
return Version{}, fmt.Errorf("Invalid character(s) found in major number %q", parts[0])
|
||||||
|
}
|
||||||
|
if hasLeadingZeroes(parts[0]) {
|
||||||
|
return Version{}, fmt.Errorf("Major number must not contain leading zeroes %q", parts[0])
|
||||||
|
}
|
||||||
|
major, err := strconv.ParseUint(parts[0], 10, 64)
|
||||||
|
if err != nil {
|
||||||
|
return Version{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Minor
|
||||||
|
if !containsOnly(parts[1], numbers) {
|
||||||
|
return Version{}, fmt.Errorf("Invalid character(s) found in minor number %q", parts[1])
|
||||||
|
}
|
||||||
|
if hasLeadingZeroes(parts[1]) {
|
||||||
|
return Version{}, fmt.Errorf("Minor number must not contain leading zeroes %q", parts[1])
|
||||||
|
}
|
||||||
|
minor, err := strconv.ParseUint(parts[1], 10, 64)
|
||||||
|
if err != nil {
|
||||||
|
return Version{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
v := Version{}
|
||||||
|
v.Major = major
|
||||||
|
v.Minor = minor
|
||||||
|
|
||||||
|
var build, prerelease []string
|
||||||
|
patchStr := parts[2]
|
||||||
|
|
||||||
|
if buildIndex := strings.IndexRune(patchStr, '+'); buildIndex != -1 {
|
||||||
|
build = strings.Split(patchStr[buildIndex+1:], ".")
|
||||||
|
patchStr = patchStr[:buildIndex]
|
||||||
|
}
|
||||||
|
|
||||||
|
if preIndex := strings.IndexRune(patchStr, '-'); preIndex != -1 {
|
||||||
|
prerelease = strings.Split(patchStr[preIndex+1:], ".")
|
||||||
|
patchStr = patchStr[:preIndex]
|
||||||
|
}
|
||||||
|
|
||||||
|
if !containsOnly(patchStr, numbers) {
|
||||||
|
return Version{}, fmt.Errorf("Invalid character(s) found in patch number %q", patchStr)
|
||||||
|
}
|
||||||
|
if hasLeadingZeroes(patchStr) {
|
||||||
|
return Version{}, fmt.Errorf("Patch number must not contain leading zeroes %q", patchStr)
|
||||||
|
}
|
||||||
|
patch, err := strconv.ParseUint(patchStr, 10, 64)
|
||||||
|
if err != nil {
|
||||||
|
return Version{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
v.Patch = patch
|
||||||
|
|
||||||
|
// Prerelease
|
||||||
|
for _, prstr := range prerelease {
|
||||||
|
parsedPR, err := NewPRVersion(prstr)
|
||||||
|
if err != nil {
|
||||||
|
return Version{}, err
|
||||||
|
}
|
||||||
|
v.Pre = append(v.Pre, parsedPR)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Build meta data
|
||||||
|
for _, str := range build {
|
||||||
|
if len(str) == 0 {
|
||||||
|
return Version{}, errors.New("Build meta data is empty")
|
||||||
|
}
|
||||||
|
if !containsOnly(str, alphanum) {
|
||||||
|
return Version{}, fmt.Errorf("Invalid character(s) found in build meta data %q", str)
|
||||||
|
}
|
||||||
|
v.Build = append(v.Build, str)
|
||||||
|
}
|
||||||
|
|
||||||
|
return v, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// MustParse is like Parse but panics if the version cannot be parsed.
|
||||||
|
func MustParse(s string) Version {
|
||||||
|
v, err := Parse(s)
|
||||||
|
if err != nil {
|
||||||
|
panic(`semver: Parse(` + s + `): ` + err.Error())
|
||||||
|
}
|
||||||
|
return v
|
||||||
|
}
|
||||||
|
|
||||||
|
// PRVersion represents a PreRelease Version
|
||||||
|
type PRVersion struct {
|
||||||
|
VersionStr string
|
||||||
|
VersionNum uint64
|
||||||
|
IsNum bool
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewPRVersion creates a new valid prerelease version
|
||||||
|
func NewPRVersion(s string) (PRVersion, error) {
|
||||||
|
if len(s) == 0 {
|
||||||
|
return PRVersion{}, errors.New("Prerelease is empty")
|
||||||
|
}
|
||||||
|
v := PRVersion{}
|
||||||
|
if containsOnly(s, numbers) {
|
||||||
|
if hasLeadingZeroes(s) {
|
||||||
|
return PRVersion{}, fmt.Errorf("Numeric PreRelease version must not contain leading zeroes %q", s)
|
||||||
|
}
|
||||||
|
num, err := strconv.ParseUint(s, 10, 64)
|
||||||
|
|
||||||
|
// Might never be hit, but just in case
|
||||||
|
if err != nil {
|
||||||
|
return PRVersion{}, err
|
||||||
|
}
|
||||||
|
v.VersionNum = num
|
||||||
|
v.IsNum = true
|
||||||
|
} else if containsOnly(s, alphanum) {
|
||||||
|
v.VersionStr = s
|
||||||
|
v.IsNum = false
|
||||||
|
} else {
|
||||||
|
return PRVersion{}, fmt.Errorf("Invalid character(s) found in prerelease %q", s)
|
||||||
|
}
|
||||||
|
return v, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsNumeric checks if prerelease-version is numeric
|
||||||
|
func (v PRVersion) IsNumeric() bool {
|
||||||
|
return v.IsNum
|
||||||
|
}
|
||||||
|
|
||||||
|
// Compare compares two PreRelease Versions v and o:
|
||||||
|
// -1 == v is less than o
|
||||||
|
// 0 == v is equal to o
|
||||||
|
// 1 == v is greater than o
|
||||||
|
func (v PRVersion) Compare(o PRVersion) int {
|
||||||
|
if v.IsNum && !o.IsNum {
|
||||||
|
return -1
|
||||||
|
} else if !v.IsNum && o.IsNum {
|
||||||
|
return 1
|
||||||
|
} else if v.IsNum && o.IsNum {
|
||||||
|
if v.VersionNum == o.VersionNum {
|
||||||
|
return 0
|
||||||
|
} else if v.VersionNum > o.VersionNum {
|
||||||
|
return 1
|
||||||
|
} else {
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
} else { // both are Alphas
|
||||||
|
if v.VersionStr == o.VersionStr {
|
||||||
|
return 0
|
||||||
|
} else if v.VersionStr > o.VersionStr {
|
||||||
|
return 1
|
||||||
|
} else {
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// PreRelease version to string
|
||||||
|
func (v PRVersion) String() string {
|
||||||
|
if v.IsNum {
|
||||||
|
return strconv.FormatUint(v.VersionNum, 10)
|
||||||
|
}
|
||||||
|
return v.VersionStr
|
||||||
|
}
|
||||||
|
|
||||||
|
func containsOnly(s string, set string) bool {
|
||||||
|
return strings.IndexFunc(s, func(r rune) bool {
|
||||||
|
return !strings.ContainsRune(set, r)
|
||||||
|
}) == -1
|
||||||
|
}
|
||||||
|
|
||||||
|
func hasLeadingZeroes(s string) bool {
|
||||||
|
return len(s) > 1 && s[0] == '0'
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewBuildVersion creates a new valid build version
|
||||||
|
func NewBuildVersion(s string) (string, error) {
|
||||||
|
if len(s) == 0 {
|
||||||
|
return "", errors.New("Buildversion is empty")
|
||||||
|
}
|
||||||
|
if !containsOnly(s, alphanum) {
|
||||||
|
return "", fmt.Errorf("Invalid character(s) found in build meta data %q", s)
|
||||||
|
}
|
||||||
|
return s, nil
|
||||||
|
}
|
||||||
28
staging/src/k8s.io/client-go/1.4/_vendor/github.com/blang/semver/sort.go
generated
Normal file
28
staging/src/k8s.io/client-go/1.4/_vendor/github.com/blang/semver/sort.go
generated
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
package semver
|
||||||
|
|
||||||
|
import (
|
||||||
|
"sort"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Versions represents multiple versions.
|
||||||
|
type Versions []Version
|
||||||
|
|
||||||
|
// Len returns length of version collection
|
||||||
|
func (s Versions) Len() int {
|
||||||
|
return len(s)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Swap swaps two versions inside the collection by its indices
|
||||||
|
func (s Versions) Swap(i, j int) {
|
||||||
|
s[i], s[j] = s[j], s[i]
|
||||||
|
}
|
||||||
|
|
||||||
|
// Less checks if version at index i is less than version at index j
|
||||||
|
func (s Versions) Less(i, j int) bool {
|
||||||
|
return s[i].LT(s[j])
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sort sorts a slice of versions
|
||||||
|
func Sort(versions []Version) {
|
||||||
|
sort.Sort(Versions(versions))
|
||||||
|
}
|
||||||
30
staging/src/k8s.io/client-go/1.4/_vendor/github.com/blang/semver/sql.go
generated
Normal file
30
staging/src/k8s.io/client-go/1.4/_vendor/github.com/blang/semver/sql.go
generated
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
package semver
|
||||||
|
|
||||||
|
import (
|
||||||
|
"database/sql/driver"
|
||||||
|
"fmt"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Scan implements the database/sql.Scanner interface.
|
||||||
|
func (v *Version) Scan(src interface{}) (err error) {
|
||||||
|
var str string
|
||||||
|
switch src := src.(type) {
|
||||||
|
case string:
|
||||||
|
str = src
|
||||||
|
case []byte:
|
||||||
|
str = string(src)
|
||||||
|
default:
|
||||||
|
return fmt.Errorf("Version.Scan: cannot convert %T to string.", src)
|
||||||
|
}
|
||||||
|
|
||||||
|
if t, err := Parse(str); err == nil {
|
||||||
|
*v = t
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Value implements the database/sql/driver.Valuer interface.
|
||||||
|
func (v Version) Value() (driver.Value, error) {
|
||||||
|
return v.String(), nil
|
||||||
|
}
|
||||||
13
staging/src/k8s.io/client-go/1.4/_vendor/github.com/davecgh/go-spew/LICENSE
generated
Normal file
13
staging/src/k8s.io/client-go/1.4/_vendor/github.com/davecgh/go-spew/LICENSE
generated
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
Copyright (c) 2012-2013 Dave Collins <dave@davec.name>
|
||||||
|
|
||||||
|
Permission to use, copy, modify, and distribute this software for any
|
||||||
|
purpose with or without fee is hereby granted, provided that the above
|
||||||
|
copyright notice and this permission notice appear in all copies.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
|
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
151
staging/src/k8s.io/client-go/1.4/_vendor/github.com/davecgh/go-spew/spew/bypass.go
generated
Normal file
151
staging/src/k8s.io/client-go/1.4/_vendor/github.com/davecgh/go-spew/spew/bypass.go
generated
Normal file
@@ -0,0 +1,151 @@
|
|||||||
|
// Copyright (c) 2015 Dave Collins <dave@davec.name>
|
||||||
|
//
|
||||||
|
// Permission to use, copy, modify, and distribute this software for any
|
||||||
|
// purpose with or without fee is hereby granted, provided that the above
|
||||||
|
// copyright notice and this permission notice appear in all copies.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
|
// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
|
||||||
|
// NOTE: Due to the following build constraints, this file will only be compiled
|
||||||
|
// when the code is not running on Google App Engine and "-tags disableunsafe"
|
||||||
|
// is not added to the go build command line.
|
||||||
|
// +build !appengine,!disableunsafe
|
||||||
|
|
||||||
|
package spew
|
||||||
|
|
||||||
|
import (
|
||||||
|
"reflect"
|
||||||
|
"unsafe"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
// UnsafeDisabled is a build-time constant which specifies whether or
|
||||||
|
// not access to the unsafe package is available.
|
||||||
|
UnsafeDisabled = false
|
||||||
|
|
||||||
|
// ptrSize is the size of a pointer on the current arch.
|
||||||
|
ptrSize = unsafe.Sizeof((*byte)(nil))
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
// offsetPtr, offsetScalar, and offsetFlag are the offsets for the
|
||||||
|
// internal reflect.Value fields. These values are valid before golang
|
||||||
|
// commit ecccf07e7f9d which changed the format. The are also valid
|
||||||
|
// after commit 82f48826c6c7 which changed the format again to mirror
|
||||||
|
// the original format. Code in the init function updates these offsets
|
||||||
|
// as necessary.
|
||||||
|
offsetPtr = uintptr(ptrSize)
|
||||||
|
offsetScalar = uintptr(0)
|
||||||
|
offsetFlag = uintptr(ptrSize * 2)
|
||||||
|
|
||||||
|
// flagKindWidth and flagKindShift indicate various bits that the
|
||||||
|
// reflect package uses internally to track kind information.
|
||||||
|
//
|
||||||
|
// flagRO indicates whether or not the value field of a reflect.Value is
|
||||||
|
// read-only.
|
||||||
|
//
|
||||||
|
// flagIndir indicates whether the value field of a reflect.Value is
|
||||||
|
// the actual data or a pointer to the data.
|
||||||
|
//
|
||||||
|
// These values are valid before golang commit 90a7c3c86944 which
|
||||||
|
// changed their positions. Code in the init function updates these
|
||||||
|
// flags as necessary.
|
||||||
|
flagKindWidth = uintptr(5)
|
||||||
|
flagKindShift = uintptr(flagKindWidth - 1)
|
||||||
|
flagRO = uintptr(1 << 0)
|
||||||
|
flagIndir = uintptr(1 << 1)
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
// Older versions of reflect.Value stored small integers directly in the
|
||||||
|
// ptr field (which is named val in the older versions). Versions
|
||||||
|
// between commits ecccf07e7f9d and 82f48826c6c7 added a new field named
|
||||||
|
// scalar for this purpose which unfortunately came before the flag
|
||||||
|
// field, so the offset of the flag field is different for those
|
||||||
|
// versions.
|
||||||
|
//
|
||||||
|
// This code constructs a new reflect.Value from a known small integer
|
||||||
|
// and checks if the size of the reflect.Value struct indicates it has
|
||||||
|
// the scalar field. When it does, the offsets are updated accordingly.
|
||||||
|
vv := reflect.ValueOf(0xf00)
|
||||||
|
if unsafe.Sizeof(vv) == (ptrSize * 4) {
|
||||||
|
offsetScalar = ptrSize * 2
|
||||||
|
offsetFlag = ptrSize * 3
|
||||||
|
}
|
||||||
|
|
||||||
|
// Commit 90a7c3c86944 changed the flag positions such that the low
|
||||||
|
// order bits are the kind. This code extracts the kind from the flags
|
||||||
|
// field and ensures it's the correct type. When it's not, the flag
|
||||||
|
// order has been changed to the newer format, so the flags are updated
|
||||||
|
// accordingly.
|
||||||
|
upf := unsafe.Pointer(uintptr(unsafe.Pointer(&vv)) + offsetFlag)
|
||||||
|
upfv := *(*uintptr)(upf)
|
||||||
|
flagKindMask := uintptr((1<<flagKindWidth - 1) << flagKindShift)
|
||||||
|
if (upfv&flagKindMask)>>flagKindShift != uintptr(reflect.Int) {
|
||||||
|
flagKindShift = 0
|
||||||
|
flagRO = 1 << 5
|
||||||
|
flagIndir = 1 << 6
|
||||||
|
|
||||||
|
// Commit adf9b30e5594 modified the flags to separate the
|
||||||
|
// flagRO flag into two bits which specifies whether or not the
|
||||||
|
// field is embedded. This causes flagIndir to move over a bit
|
||||||
|
// and means that flagRO is the combination of either of the
|
||||||
|
// original flagRO bit and the new bit.
|
||||||
|
//
|
||||||
|
// This code detects the change by extracting what used to be
|
||||||
|
// the indirect bit to ensure it's set. When it's not, the flag
|
||||||
|
// order has been changed to the newer format, so the flags are
|
||||||
|
// updated accordingly.
|
||||||
|
if upfv&flagIndir == 0 {
|
||||||
|
flagRO = 3 << 5
|
||||||
|
flagIndir = 1 << 7
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// unsafeReflectValue converts the passed reflect.Value into a one that bypasses
|
||||||
|
// the typical safety restrictions preventing access to unaddressable and
|
||||||
|
// unexported data. It works by digging the raw pointer to the underlying
|
||||||
|
// value out of the protected value and generating a new unprotected (unsafe)
|
||||||
|
// reflect.Value to it.
|
||||||
|
//
|
||||||
|
// This allows us to check for implementations of the Stringer and error
|
||||||
|
// interfaces to be used for pretty printing ordinarily unaddressable and
|
||||||
|
// inaccessible values such as unexported struct fields.
|
||||||
|
func unsafeReflectValue(v reflect.Value) (rv reflect.Value) {
|
||||||
|
indirects := 1
|
||||||
|
vt := v.Type()
|
||||||
|
upv := unsafe.Pointer(uintptr(unsafe.Pointer(&v)) + offsetPtr)
|
||||||
|
rvf := *(*uintptr)(unsafe.Pointer(uintptr(unsafe.Pointer(&v)) + offsetFlag))
|
||||||
|
if rvf&flagIndir != 0 {
|
||||||
|
vt = reflect.PtrTo(v.Type())
|
||||||
|
indirects++
|
||||||
|
} else if offsetScalar != 0 {
|
||||||
|
// The value is in the scalar field when it's not one of the
|
||||||
|
// reference types.
|
||||||
|
switch vt.Kind() {
|
||||||
|
case reflect.Uintptr:
|
||||||
|
case reflect.Chan:
|
||||||
|
case reflect.Func:
|
||||||
|
case reflect.Map:
|
||||||
|
case reflect.Ptr:
|
||||||
|
case reflect.UnsafePointer:
|
||||||
|
default:
|
||||||
|
upv = unsafe.Pointer(uintptr(unsafe.Pointer(&v)) +
|
||||||
|
offsetScalar)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pv := reflect.NewAt(vt, upv)
|
||||||
|
rv = pv
|
||||||
|
for i := 0; i < indirects; i++ {
|
||||||
|
rv = rv.Elem()
|
||||||
|
}
|
||||||
|
return rv
|
||||||
|
}
|
||||||
37
staging/src/k8s.io/client-go/1.4/_vendor/github.com/davecgh/go-spew/spew/bypasssafe.go
generated
Normal file
37
staging/src/k8s.io/client-go/1.4/_vendor/github.com/davecgh/go-spew/spew/bypasssafe.go
generated
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
// Copyright (c) 2015 Dave Collins <dave@davec.name>
|
||||||
|
//
|
||||||
|
// Permission to use, copy, modify, and distribute this software for any
|
||||||
|
// purpose with or without fee is hereby granted, provided that the above
|
||||||
|
// copyright notice and this permission notice appear in all copies.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
|
// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
|
||||||
|
// NOTE: Due to the following build constraints, this file will only be compiled
|
||||||
|
// when either the code is running on Google App Engine or "-tags disableunsafe"
|
||||||
|
// is added to the go build command line.
|
||||||
|
// +build appengine disableunsafe
|
||||||
|
|
||||||
|
package spew
|
||||||
|
|
||||||
|
import "reflect"
|
||||||
|
|
||||||
|
const (
|
||||||
|
// UnsafeDisabled is a build-time constant which specifies whether or
|
||||||
|
// not access to the unsafe package is available.
|
||||||
|
UnsafeDisabled = true
|
||||||
|
)
|
||||||
|
|
||||||
|
// unsafeReflectValue typically converts the passed reflect.Value into a one
|
||||||
|
// that bypasses the typical safety restrictions preventing access to
|
||||||
|
// unaddressable and unexported data. However, doing this relies on access to
|
||||||
|
// the unsafe package. This is a stub version which simply returns the passed
|
||||||
|
// reflect.Value when the unsafe package is not available.
|
||||||
|
func unsafeReflectValue(v reflect.Value) reflect.Value {
|
||||||
|
return v
|
||||||
|
}
|
||||||
341
staging/src/k8s.io/client-go/1.4/_vendor/github.com/davecgh/go-spew/spew/common.go
generated
Normal file
341
staging/src/k8s.io/client-go/1.4/_vendor/github.com/davecgh/go-spew/spew/common.go
generated
Normal file
@@ -0,0 +1,341 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2013 Dave Collins <dave@davec.name>
|
||||||
|
*
|
||||||
|
* Permission to use, copy, modify, and distribute this software for any
|
||||||
|
* purpose with or without fee is hereby granted, provided that the above
|
||||||
|
* copyright notice and this permission notice appear in all copies.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
|
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package spew
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"reflect"
|
||||||
|
"sort"
|
||||||
|
"strconv"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Some constants in the form of bytes to avoid string overhead. This mirrors
|
||||||
|
// the technique used in the fmt package.
|
||||||
|
var (
|
||||||
|
panicBytes = []byte("(PANIC=")
|
||||||
|
plusBytes = []byte("+")
|
||||||
|
iBytes = []byte("i")
|
||||||
|
trueBytes = []byte("true")
|
||||||
|
falseBytes = []byte("false")
|
||||||
|
interfaceBytes = []byte("(interface {})")
|
||||||
|
commaNewlineBytes = []byte(",\n")
|
||||||
|
newlineBytes = []byte("\n")
|
||||||
|
openBraceBytes = []byte("{")
|
||||||
|
openBraceNewlineBytes = []byte("{\n")
|
||||||
|
closeBraceBytes = []byte("}")
|
||||||
|
asteriskBytes = []byte("*")
|
||||||
|
colonBytes = []byte(":")
|
||||||
|
colonSpaceBytes = []byte(": ")
|
||||||
|
openParenBytes = []byte("(")
|
||||||
|
closeParenBytes = []byte(")")
|
||||||
|
spaceBytes = []byte(" ")
|
||||||
|
pointerChainBytes = []byte("->")
|
||||||
|
nilAngleBytes = []byte("<nil>")
|
||||||
|
maxNewlineBytes = []byte("<max depth reached>\n")
|
||||||
|
maxShortBytes = []byte("<max>")
|
||||||
|
circularBytes = []byte("<already shown>")
|
||||||
|
circularShortBytes = []byte("<shown>")
|
||||||
|
invalidAngleBytes = []byte("<invalid>")
|
||||||
|
openBracketBytes = []byte("[")
|
||||||
|
closeBracketBytes = []byte("]")
|
||||||
|
percentBytes = []byte("%")
|
||||||
|
precisionBytes = []byte(".")
|
||||||
|
openAngleBytes = []byte("<")
|
||||||
|
closeAngleBytes = []byte(">")
|
||||||
|
openMapBytes = []byte("map[")
|
||||||
|
closeMapBytes = []byte("]")
|
||||||
|
lenEqualsBytes = []byte("len=")
|
||||||
|
capEqualsBytes = []byte("cap=")
|
||||||
|
)
|
||||||
|
|
||||||
|
// hexDigits is used to map a decimal value to a hex digit.
|
||||||
|
var hexDigits = "0123456789abcdef"
|
||||||
|
|
||||||
|
// catchPanic handles any panics that might occur during the handleMethods
|
||||||
|
// calls.
|
||||||
|
func catchPanic(w io.Writer, v reflect.Value) {
|
||||||
|
if err := recover(); err != nil {
|
||||||
|
w.Write(panicBytes)
|
||||||
|
fmt.Fprintf(w, "%v", err)
|
||||||
|
w.Write(closeParenBytes)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// handleMethods attempts to call the Error and String methods on the underlying
|
||||||
|
// type the passed reflect.Value represents and outputes the result to Writer w.
|
||||||
|
//
|
||||||
|
// It handles panics in any called methods by catching and displaying the error
|
||||||
|
// as the formatted value.
|
||||||
|
func handleMethods(cs *ConfigState, w io.Writer, v reflect.Value) (handled bool) {
|
||||||
|
// We need an interface to check if the type implements the error or
|
||||||
|
// Stringer interface. However, the reflect package won't give us an
|
||||||
|
// interface on certain things like unexported struct fields in order
|
||||||
|
// to enforce visibility rules. We use unsafe, when it's available,
|
||||||
|
// to bypass these restrictions since this package does not mutate the
|
||||||
|
// values.
|
||||||
|
if !v.CanInterface() {
|
||||||
|
if UnsafeDisabled {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
v = unsafeReflectValue(v)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Choose whether or not to do error and Stringer interface lookups against
|
||||||
|
// the base type or a pointer to the base type depending on settings.
|
||||||
|
// Technically calling one of these methods with a pointer receiver can
|
||||||
|
// mutate the value, however, types which choose to satisify an error or
|
||||||
|
// Stringer interface with a pointer receiver should not be mutating their
|
||||||
|
// state inside these interface methods.
|
||||||
|
if !cs.DisablePointerMethods && !UnsafeDisabled && !v.CanAddr() {
|
||||||
|
v = unsafeReflectValue(v)
|
||||||
|
}
|
||||||
|
if v.CanAddr() {
|
||||||
|
v = v.Addr()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Is it an error or Stringer?
|
||||||
|
switch iface := v.Interface().(type) {
|
||||||
|
case error:
|
||||||
|
defer catchPanic(w, v)
|
||||||
|
if cs.ContinueOnMethod {
|
||||||
|
w.Write(openParenBytes)
|
||||||
|
w.Write([]byte(iface.Error()))
|
||||||
|
w.Write(closeParenBytes)
|
||||||
|
w.Write(spaceBytes)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
w.Write([]byte(iface.Error()))
|
||||||
|
return true
|
||||||
|
|
||||||
|
case fmt.Stringer:
|
||||||
|
defer catchPanic(w, v)
|
||||||
|
if cs.ContinueOnMethod {
|
||||||
|
w.Write(openParenBytes)
|
||||||
|
w.Write([]byte(iface.String()))
|
||||||
|
w.Write(closeParenBytes)
|
||||||
|
w.Write(spaceBytes)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
w.Write([]byte(iface.String()))
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// printBool outputs a boolean value as true or false to Writer w.
|
||||||
|
func printBool(w io.Writer, val bool) {
|
||||||
|
if val {
|
||||||
|
w.Write(trueBytes)
|
||||||
|
} else {
|
||||||
|
w.Write(falseBytes)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// printInt outputs a signed integer value to Writer w.
|
||||||
|
func printInt(w io.Writer, val int64, base int) {
|
||||||
|
w.Write([]byte(strconv.FormatInt(val, base)))
|
||||||
|
}
|
||||||
|
|
||||||
|
// printUint outputs an unsigned integer value to Writer w.
|
||||||
|
func printUint(w io.Writer, val uint64, base int) {
|
||||||
|
w.Write([]byte(strconv.FormatUint(val, base)))
|
||||||
|
}
|
||||||
|
|
||||||
|
// printFloat outputs a floating point value using the specified precision,
|
||||||
|
// which is expected to be 32 or 64bit, to Writer w.
|
||||||
|
func printFloat(w io.Writer, val float64, precision int) {
|
||||||
|
w.Write([]byte(strconv.FormatFloat(val, 'g', -1, precision)))
|
||||||
|
}
|
||||||
|
|
||||||
|
// printComplex outputs a complex value using the specified float precision
|
||||||
|
// for the real and imaginary parts to Writer w.
|
||||||
|
func printComplex(w io.Writer, c complex128, floatPrecision int) {
|
||||||
|
r := real(c)
|
||||||
|
w.Write(openParenBytes)
|
||||||
|
w.Write([]byte(strconv.FormatFloat(r, 'g', -1, floatPrecision)))
|
||||||
|
i := imag(c)
|
||||||
|
if i >= 0 {
|
||||||
|
w.Write(plusBytes)
|
||||||
|
}
|
||||||
|
w.Write([]byte(strconv.FormatFloat(i, 'g', -1, floatPrecision)))
|
||||||
|
w.Write(iBytes)
|
||||||
|
w.Write(closeParenBytes)
|
||||||
|
}
|
||||||
|
|
||||||
|
// printHexPtr outputs a uintptr formatted as hexidecimal with a leading '0x'
|
||||||
|
// prefix to Writer w.
|
||||||
|
func printHexPtr(w io.Writer, p uintptr) {
|
||||||
|
// Null pointer.
|
||||||
|
num := uint64(p)
|
||||||
|
if num == 0 {
|
||||||
|
w.Write(nilAngleBytes)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Max uint64 is 16 bytes in hex + 2 bytes for '0x' prefix
|
||||||
|
buf := make([]byte, 18)
|
||||||
|
|
||||||
|
// It's simpler to construct the hex string right to left.
|
||||||
|
base := uint64(16)
|
||||||
|
i := len(buf) - 1
|
||||||
|
for num >= base {
|
||||||
|
buf[i] = hexDigits[num%base]
|
||||||
|
num /= base
|
||||||
|
i--
|
||||||
|
}
|
||||||
|
buf[i] = hexDigits[num]
|
||||||
|
|
||||||
|
// Add '0x' prefix.
|
||||||
|
i--
|
||||||
|
buf[i] = 'x'
|
||||||
|
i--
|
||||||
|
buf[i] = '0'
|
||||||
|
|
||||||
|
// Strip unused leading bytes.
|
||||||
|
buf = buf[i:]
|
||||||
|
w.Write(buf)
|
||||||
|
}
|
||||||
|
|
||||||
|
// valuesSorter implements sort.Interface to allow a slice of reflect.Value
|
||||||
|
// elements to be sorted.
|
||||||
|
type valuesSorter struct {
|
||||||
|
values []reflect.Value
|
||||||
|
strings []string // either nil or same len and values
|
||||||
|
cs *ConfigState
|
||||||
|
}
|
||||||
|
|
||||||
|
// newValuesSorter initializes a valuesSorter instance, which holds a set of
|
||||||
|
// surrogate keys on which the data should be sorted. It uses flags in
|
||||||
|
// ConfigState to decide if and how to populate those surrogate keys.
|
||||||
|
func newValuesSorter(values []reflect.Value, cs *ConfigState) sort.Interface {
|
||||||
|
vs := &valuesSorter{values: values, cs: cs}
|
||||||
|
if canSortSimply(vs.values[0].Kind()) {
|
||||||
|
return vs
|
||||||
|
}
|
||||||
|
if !cs.DisableMethods {
|
||||||
|
vs.strings = make([]string, len(values))
|
||||||
|
for i := range vs.values {
|
||||||
|
b := bytes.Buffer{}
|
||||||
|
if !handleMethods(cs, &b, vs.values[i]) {
|
||||||
|
vs.strings = nil
|
||||||
|
break
|
||||||
|
}
|
||||||
|
vs.strings[i] = b.String()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if vs.strings == nil && cs.SpewKeys {
|
||||||
|
vs.strings = make([]string, len(values))
|
||||||
|
for i := range vs.values {
|
||||||
|
vs.strings[i] = Sprintf("%#v", vs.values[i].Interface())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return vs
|
||||||
|
}
|
||||||
|
|
||||||
|
// canSortSimply tests whether a reflect.Kind is a primitive that can be sorted
|
||||||
|
// directly, or whether it should be considered for sorting by surrogate keys
|
||||||
|
// (if the ConfigState allows it).
|
||||||
|
func canSortSimply(kind reflect.Kind) bool {
|
||||||
|
// This switch parallels valueSortLess, except for the default case.
|
||||||
|
switch kind {
|
||||||
|
case reflect.Bool:
|
||||||
|
return true
|
||||||
|
case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int:
|
||||||
|
return true
|
||||||
|
case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint:
|
||||||
|
return true
|
||||||
|
case reflect.Float32, reflect.Float64:
|
||||||
|
return true
|
||||||
|
case reflect.String:
|
||||||
|
return true
|
||||||
|
case reflect.Uintptr:
|
||||||
|
return true
|
||||||
|
case reflect.Array:
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// Len returns the number of values in the slice. It is part of the
|
||||||
|
// sort.Interface implementation.
|
||||||
|
func (s *valuesSorter) Len() int {
|
||||||
|
return len(s.values)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Swap swaps the values at the passed indices. It is part of the
|
||||||
|
// sort.Interface implementation.
|
||||||
|
func (s *valuesSorter) Swap(i, j int) {
|
||||||
|
s.values[i], s.values[j] = s.values[j], s.values[i]
|
||||||
|
if s.strings != nil {
|
||||||
|
s.strings[i], s.strings[j] = s.strings[j], s.strings[i]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// valueSortLess returns whether the first value should sort before the second
|
||||||
|
// value. It is used by valueSorter.Less as part of the sort.Interface
|
||||||
|
// implementation.
|
||||||
|
func valueSortLess(a, b reflect.Value) bool {
|
||||||
|
switch a.Kind() {
|
||||||
|
case reflect.Bool:
|
||||||
|
return !a.Bool() && b.Bool()
|
||||||
|
case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int:
|
||||||
|
return a.Int() < b.Int()
|
||||||
|
case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint:
|
||||||
|
return a.Uint() < b.Uint()
|
||||||
|
case reflect.Float32, reflect.Float64:
|
||||||
|
return a.Float() < b.Float()
|
||||||
|
case reflect.String:
|
||||||
|
return a.String() < b.String()
|
||||||
|
case reflect.Uintptr:
|
||||||
|
return a.Uint() < b.Uint()
|
||||||
|
case reflect.Array:
|
||||||
|
// Compare the contents of both arrays.
|
||||||
|
l := a.Len()
|
||||||
|
for i := 0; i < l; i++ {
|
||||||
|
av := a.Index(i)
|
||||||
|
bv := b.Index(i)
|
||||||
|
if av.Interface() == bv.Interface() {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
return valueSortLess(av, bv)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return a.String() < b.String()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Less returns whether the value at index i should sort before the
|
||||||
|
// value at index j. It is part of the sort.Interface implementation.
|
||||||
|
func (s *valuesSorter) Less(i, j int) bool {
|
||||||
|
if s.strings == nil {
|
||||||
|
return valueSortLess(s.values[i], s.values[j])
|
||||||
|
}
|
||||||
|
return s.strings[i] < s.strings[j]
|
||||||
|
}
|
||||||
|
|
||||||
|
// sortValues is a sort function that handles both native types and any type that
|
||||||
|
// can be converted to error or Stringer. Other inputs are sorted according to
|
||||||
|
// their Value.String() value to ensure display stability.
|
||||||
|
func sortValues(values []reflect.Value, cs *ConfigState) {
|
||||||
|
if len(values) == 0 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
sort.Sort(newValuesSorter(values, cs))
|
||||||
|
}
|
||||||
297
staging/src/k8s.io/client-go/1.4/_vendor/github.com/davecgh/go-spew/spew/config.go
generated
Normal file
297
staging/src/k8s.io/client-go/1.4/_vendor/github.com/davecgh/go-spew/spew/config.go
generated
Normal file
@@ -0,0 +1,297 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2013 Dave Collins <dave@davec.name>
|
||||||
|
*
|
||||||
|
* Permission to use, copy, modify, and distribute this software for any
|
||||||
|
* purpose with or without fee is hereby granted, provided that the above
|
||||||
|
* copyright notice and this permission notice appear in all copies.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
|
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package spew
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"os"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ConfigState houses the configuration options used by spew to format and
|
||||||
|
// display values. There is a global instance, Config, that is used to control
|
||||||
|
// all top-level Formatter and Dump functionality. Each ConfigState instance
|
||||||
|
// provides methods equivalent to the top-level functions.
|
||||||
|
//
|
||||||
|
// The zero value for ConfigState provides no indentation. You would typically
|
||||||
|
// want to set it to a space or a tab.
|
||||||
|
//
|
||||||
|
// Alternatively, you can use NewDefaultConfig to get a ConfigState instance
|
||||||
|
// with default settings. See the documentation of NewDefaultConfig for default
|
||||||
|
// values.
|
||||||
|
type ConfigState struct {
|
||||||
|
// Indent specifies the string to use for each indentation level. The
|
||||||
|
// global config instance that all top-level functions use set this to a
|
||||||
|
// single space by default. If you would like more indentation, you might
|
||||||
|
// set this to a tab with "\t" or perhaps two spaces with " ".
|
||||||
|
Indent string
|
||||||
|
|
||||||
|
// MaxDepth controls the maximum number of levels to descend into nested
|
||||||
|
// data structures. The default, 0, means there is no limit.
|
||||||
|
//
|
||||||
|
// NOTE: Circular data structures are properly detected, so it is not
|
||||||
|
// necessary to set this value unless you specifically want to limit deeply
|
||||||
|
// nested data structures.
|
||||||
|
MaxDepth int
|
||||||
|
|
||||||
|
// DisableMethods specifies whether or not error and Stringer interfaces are
|
||||||
|
// invoked for types that implement them.
|
||||||
|
DisableMethods bool
|
||||||
|
|
||||||
|
// DisablePointerMethods specifies whether or not to check for and invoke
|
||||||
|
// error and Stringer interfaces on types which only accept a pointer
|
||||||
|
// receiver when the current type is not a pointer.
|
||||||
|
//
|
||||||
|
// NOTE: This might be an unsafe action since calling one of these methods
|
||||||
|
// with a pointer receiver could technically mutate the value, however,
|
||||||
|
// in practice, types which choose to satisify an error or Stringer
|
||||||
|
// interface with a pointer receiver should not be mutating their state
|
||||||
|
// inside these interface methods. As a result, this option relies on
|
||||||
|
// access to the unsafe package, so it will not have any effect when
|
||||||
|
// running in environments without access to the unsafe package such as
|
||||||
|
// Google App Engine or with the "disableunsafe" build tag specified.
|
||||||
|
DisablePointerMethods bool
|
||||||
|
|
||||||
|
// ContinueOnMethod specifies whether or not recursion should continue once
|
||||||
|
// a custom error or Stringer interface is invoked. The default, false,
|
||||||
|
// means it will print the results of invoking the custom error or Stringer
|
||||||
|
// interface and return immediately instead of continuing to recurse into
|
||||||
|
// the internals of the data type.
|
||||||
|
//
|
||||||
|
// NOTE: This flag does not have any effect if method invocation is disabled
|
||||||
|
// via the DisableMethods or DisablePointerMethods options.
|
||||||
|
ContinueOnMethod bool
|
||||||
|
|
||||||
|
// SortKeys specifies map keys should be sorted before being printed. Use
|
||||||
|
// this to have a more deterministic, diffable output. Note that only
|
||||||
|
// native types (bool, int, uint, floats, uintptr and string) and types
|
||||||
|
// that support the error or Stringer interfaces (if methods are
|
||||||
|
// enabled) are supported, with other types sorted according to the
|
||||||
|
// reflect.Value.String() output which guarantees display stability.
|
||||||
|
SortKeys bool
|
||||||
|
|
||||||
|
// SpewKeys specifies that, as a last resort attempt, map keys should
|
||||||
|
// be spewed to strings and sorted by those strings. This is only
|
||||||
|
// considered if SortKeys is true.
|
||||||
|
SpewKeys bool
|
||||||
|
}
|
||||||
|
|
||||||
|
// Config is the active configuration of the top-level functions.
|
||||||
|
// The configuration can be changed by modifying the contents of spew.Config.
|
||||||
|
var Config = ConfigState{Indent: " "}
|
||||||
|
|
||||||
|
// Errorf is a wrapper for fmt.Errorf that treats each argument as if it were
|
||||||
|
// passed with a Formatter interface returned by c.NewFormatter. It returns
|
||||||
|
// the formatted string as a value that satisfies error. See NewFormatter
|
||||||
|
// for formatting details.
|
||||||
|
//
|
||||||
|
// This function is shorthand for the following syntax:
|
||||||
|
//
|
||||||
|
// fmt.Errorf(format, c.NewFormatter(a), c.NewFormatter(b))
|
||||||
|
func (c *ConfigState) Errorf(format string, a ...interface{}) (err error) {
|
||||||
|
return fmt.Errorf(format, c.convertArgs(a)...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fprint is a wrapper for fmt.Fprint that treats each argument as if it were
|
||||||
|
// passed with a Formatter interface returned by c.NewFormatter. It returns
|
||||||
|
// the number of bytes written and any write error encountered. See
|
||||||
|
// NewFormatter for formatting details.
|
||||||
|
//
|
||||||
|
// This function is shorthand for the following syntax:
|
||||||
|
//
|
||||||
|
// fmt.Fprint(w, c.NewFormatter(a), c.NewFormatter(b))
|
||||||
|
func (c *ConfigState) Fprint(w io.Writer, a ...interface{}) (n int, err error) {
|
||||||
|
return fmt.Fprint(w, c.convertArgs(a)...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fprintf is a wrapper for fmt.Fprintf that treats each argument as if it were
|
||||||
|
// passed with a Formatter interface returned by c.NewFormatter. It returns
|
||||||
|
// the number of bytes written and any write error encountered. See
|
||||||
|
// NewFormatter for formatting details.
|
||||||
|
//
|
||||||
|
// This function is shorthand for the following syntax:
|
||||||
|
//
|
||||||
|
// fmt.Fprintf(w, format, c.NewFormatter(a), c.NewFormatter(b))
|
||||||
|
func (c *ConfigState) Fprintf(w io.Writer, format string, a ...interface{}) (n int, err error) {
|
||||||
|
return fmt.Fprintf(w, format, c.convertArgs(a)...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fprintln is a wrapper for fmt.Fprintln that treats each argument as if it
|
||||||
|
// passed with a Formatter interface returned by c.NewFormatter. See
|
||||||
|
// NewFormatter for formatting details.
|
||||||
|
//
|
||||||
|
// This function is shorthand for the following syntax:
|
||||||
|
//
|
||||||
|
// fmt.Fprintln(w, c.NewFormatter(a), c.NewFormatter(b))
|
||||||
|
func (c *ConfigState) Fprintln(w io.Writer, a ...interface{}) (n int, err error) {
|
||||||
|
return fmt.Fprintln(w, c.convertArgs(a)...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Print is a wrapper for fmt.Print that treats each argument as if it were
|
||||||
|
// passed with a Formatter interface returned by c.NewFormatter. It returns
|
||||||
|
// the number of bytes written and any write error encountered. See
|
||||||
|
// NewFormatter for formatting details.
|
||||||
|
//
|
||||||
|
// This function is shorthand for the following syntax:
|
||||||
|
//
|
||||||
|
// fmt.Print(c.NewFormatter(a), c.NewFormatter(b))
|
||||||
|
func (c *ConfigState) Print(a ...interface{}) (n int, err error) {
|
||||||
|
return fmt.Print(c.convertArgs(a)...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Printf is a wrapper for fmt.Printf that treats each argument as if it were
|
||||||
|
// passed with a Formatter interface returned by c.NewFormatter. It returns
|
||||||
|
// the number of bytes written and any write error encountered. See
|
||||||
|
// NewFormatter for formatting details.
|
||||||
|
//
|
||||||
|
// This function is shorthand for the following syntax:
|
||||||
|
//
|
||||||
|
// fmt.Printf(format, c.NewFormatter(a), c.NewFormatter(b))
|
||||||
|
func (c *ConfigState) Printf(format string, a ...interface{}) (n int, err error) {
|
||||||
|
return fmt.Printf(format, c.convertArgs(a)...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Println is a wrapper for fmt.Println that treats each argument as if it were
|
||||||
|
// passed with a Formatter interface returned by c.NewFormatter. It returns
|
||||||
|
// the number of bytes written and any write error encountered. See
|
||||||
|
// NewFormatter for formatting details.
|
||||||
|
//
|
||||||
|
// This function is shorthand for the following syntax:
|
||||||
|
//
|
||||||
|
// fmt.Println(c.NewFormatter(a), c.NewFormatter(b))
|
||||||
|
func (c *ConfigState) Println(a ...interface{}) (n int, err error) {
|
||||||
|
return fmt.Println(c.convertArgs(a)...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sprint is a wrapper for fmt.Sprint that treats each argument as if it were
|
||||||
|
// passed with a Formatter interface returned by c.NewFormatter. It returns
|
||||||
|
// the resulting string. See NewFormatter for formatting details.
|
||||||
|
//
|
||||||
|
// This function is shorthand for the following syntax:
|
||||||
|
//
|
||||||
|
// fmt.Sprint(c.NewFormatter(a), c.NewFormatter(b))
|
||||||
|
func (c *ConfigState) Sprint(a ...interface{}) string {
|
||||||
|
return fmt.Sprint(c.convertArgs(a)...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sprintf is a wrapper for fmt.Sprintf that treats each argument as if it were
|
||||||
|
// passed with a Formatter interface returned by c.NewFormatter. It returns
|
||||||
|
// the resulting string. See NewFormatter for formatting details.
|
||||||
|
//
|
||||||
|
// This function is shorthand for the following syntax:
|
||||||
|
//
|
||||||
|
// fmt.Sprintf(format, c.NewFormatter(a), c.NewFormatter(b))
|
||||||
|
func (c *ConfigState) Sprintf(format string, a ...interface{}) string {
|
||||||
|
return fmt.Sprintf(format, c.convertArgs(a)...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sprintln is a wrapper for fmt.Sprintln that treats each argument as if it
|
||||||
|
// were passed with a Formatter interface returned by c.NewFormatter. It
|
||||||
|
// returns the resulting string. See NewFormatter for formatting details.
|
||||||
|
//
|
||||||
|
// This function is shorthand for the following syntax:
|
||||||
|
//
|
||||||
|
// fmt.Sprintln(c.NewFormatter(a), c.NewFormatter(b))
|
||||||
|
func (c *ConfigState) Sprintln(a ...interface{}) string {
|
||||||
|
return fmt.Sprintln(c.convertArgs(a)...)
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
NewFormatter returns a custom formatter that satisfies the fmt.Formatter
|
||||||
|
interface. As a result, it integrates cleanly with standard fmt package
|
||||||
|
printing functions. The formatter is useful for inline printing of smaller data
|
||||||
|
types similar to the standard %v format specifier.
|
||||||
|
|
||||||
|
The custom formatter only responds to the %v (most compact), %+v (adds pointer
|
||||||
|
addresses), %#v (adds types), and %#+v (adds types and pointer addresses) verb
|
||||||
|
combinations. Any other verbs such as %x and %q will be sent to the the
|
||||||
|
standard fmt package for formatting. In addition, the custom formatter ignores
|
||||||
|
the width and precision arguments (however they will still work on the format
|
||||||
|
specifiers not handled by the custom formatter).
|
||||||
|
|
||||||
|
Typically this function shouldn't be called directly. It is much easier to make
|
||||||
|
use of the custom formatter by calling one of the convenience functions such as
|
||||||
|
c.Printf, c.Println, or c.Printf.
|
||||||
|
*/
|
||||||
|
func (c *ConfigState) NewFormatter(v interface{}) fmt.Formatter {
|
||||||
|
return newFormatter(c, v)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fdump formats and displays the passed arguments to io.Writer w. It formats
|
||||||
|
// exactly the same as Dump.
|
||||||
|
func (c *ConfigState) Fdump(w io.Writer, a ...interface{}) {
|
||||||
|
fdump(c, w, a...)
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Dump displays the passed parameters to standard out with newlines, customizable
|
||||||
|
indentation, and additional debug information such as complete types and all
|
||||||
|
pointer addresses used to indirect to the final value. It provides the
|
||||||
|
following features over the built-in printing facilities provided by the fmt
|
||||||
|
package:
|
||||||
|
|
||||||
|
* Pointers are dereferenced and followed
|
||||||
|
* Circular data structures are detected and handled properly
|
||||||
|
* Custom Stringer/error interfaces are optionally invoked, including
|
||||||
|
on unexported types
|
||||||
|
* Custom types which only implement the Stringer/error interfaces via
|
||||||
|
a pointer receiver are optionally invoked when passing non-pointer
|
||||||
|
variables
|
||||||
|
* Byte arrays and slices are dumped like the hexdump -C command which
|
||||||
|
includes offsets, byte values in hex, and ASCII output
|
||||||
|
|
||||||
|
The configuration options are controlled by modifying the public members
|
||||||
|
of c. See ConfigState for options documentation.
|
||||||
|
|
||||||
|
See Fdump if you would prefer dumping to an arbitrary io.Writer or Sdump to
|
||||||
|
get the formatted result as a string.
|
||||||
|
*/
|
||||||
|
func (c *ConfigState) Dump(a ...interface{}) {
|
||||||
|
fdump(c, os.Stdout, a...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sdump returns a string with the passed arguments formatted exactly the same
|
||||||
|
// as Dump.
|
||||||
|
func (c *ConfigState) Sdump(a ...interface{}) string {
|
||||||
|
var buf bytes.Buffer
|
||||||
|
fdump(c, &buf, a...)
|
||||||
|
return buf.String()
|
||||||
|
}
|
||||||
|
|
||||||
|
// convertArgs accepts a slice of arguments and returns a slice of the same
|
||||||
|
// length with each argument converted to a spew Formatter interface using
|
||||||
|
// the ConfigState associated with s.
|
||||||
|
func (c *ConfigState) convertArgs(args []interface{}) (formatters []interface{}) {
|
||||||
|
formatters = make([]interface{}, len(args))
|
||||||
|
for index, arg := range args {
|
||||||
|
formatters[index] = newFormatter(c, arg)
|
||||||
|
}
|
||||||
|
return formatters
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewDefaultConfig returns a ConfigState with the following default settings.
|
||||||
|
//
|
||||||
|
// Indent: " "
|
||||||
|
// MaxDepth: 0
|
||||||
|
// DisableMethods: false
|
||||||
|
// DisablePointerMethods: false
|
||||||
|
// ContinueOnMethod: false
|
||||||
|
// SortKeys: false
|
||||||
|
func NewDefaultConfig() *ConfigState {
|
||||||
|
return &ConfigState{Indent: " "}
|
||||||
|
}
|
||||||
202
staging/src/k8s.io/client-go/1.4/_vendor/github.com/davecgh/go-spew/spew/doc.go
generated
Normal file
202
staging/src/k8s.io/client-go/1.4/_vendor/github.com/davecgh/go-spew/spew/doc.go
generated
Normal file
@@ -0,0 +1,202 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2013 Dave Collins <dave@davec.name>
|
||||||
|
*
|
||||||
|
* Permission to use, copy, modify, and distribute this software for any
|
||||||
|
* purpose with or without fee is hereby granted, provided that the above
|
||||||
|
* copyright notice and this permission notice appear in all copies.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
|
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
Package spew implements a deep pretty printer for Go data structures to aid in
|
||||||
|
debugging.
|
||||||
|
|
||||||
|
A quick overview of the additional features spew provides over the built-in
|
||||||
|
printing facilities for Go data types are as follows:
|
||||||
|
|
||||||
|
* Pointers are dereferenced and followed
|
||||||
|
* Circular data structures are detected and handled properly
|
||||||
|
* Custom Stringer/error interfaces are optionally invoked, including
|
||||||
|
on unexported types
|
||||||
|
* Custom types which only implement the Stringer/error interfaces via
|
||||||
|
a pointer receiver are optionally invoked when passing non-pointer
|
||||||
|
variables
|
||||||
|
* Byte arrays and slices are dumped like the hexdump -C command which
|
||||||
|
includes offsets, byte values in hex, and ASCII output (only when using
|
||||||
|
Dump style)
|
||||||
|
|
||||||
|
There are two different approaches spew allows for dumping Go data structures:
|
||||||
|
|
||||||
|
* Dump style which prints with newlines, customizable indentation,
|
||||||
|
and additional debug information such as types and all pointer addresses
|
||||||
|
used to indirect to the final value
|
||||||
|
* A custom Formatter interface that integrates cleanly with the standard fmt
|
||||||
|
package and replaces %v, %+v, %#v, and %#+v to provide inline printing
|
||||||
|
similar to the default %v while providing the additional functionality
|
||||||
|
outlined above and passing unsupported format verbs such as %x and %q
|
||||||
|
along to fmt
|
||||||
|
|
||||||
|
Quick Start
|
||||||
|
|
||||||
|
This section demonstrates how to quickly get started with spew. See the
|
||||||
|
sections below for further details on formatting and configuration options.
|
||||||
|
|
||||||
|
To dump a variable with full newlines, indentation, type, and pointer
|
||||||
|
information use Dump, Fdump, or Sdump:
|
||||||
|
spew.Dump(myVar1, myVar2, ...)
|
||||||
|
spew.Fdump(someWriter, myVar1, myVar2, ...)
|
||||||
|
str := spew.Sdump(myVar1, myVar2, ...)
|
||||||
|
|
||||||
|
Alternatively, if you would prefer to use format strings with a compacted inline
|
||||||
|
printing style, use the convenience wrappers Printf, Fprintf, etc with
|
||||||
|
%v (most compact), %+v (adds pointer addresses), %#v (adds types), or
|
||||||
|
%#+v (adds types and pointer addresses):
|
||||||
|
spew.Printf("myVar1: %v -- myVar2: %+v", myVar1, myVar2)
|
||||||
|
spew.Printf("myVar3: %#v -- myVar4: %#+v", myVar3, myVar4)
|
||||||
|
spew.Fprintf(someWriter, "myVar1: %v -- myVar2: %+v", myVar1, myVar2)
|
||||||
|
spew.Fprintf(someWriter, "myVar3: %#v -- myVar4: %#+v", myVar3, myVar4)
|
||||||
|
|
||||||
|
Configuration Options
|
||||||
|
|
||||||
|
Configuration of spew is handled by fields in the ConfigState type. For
|
||||||
|
convenience, all of the top-level functions use a global state available
|
||||||
|
via the spew.Config global.
|
||||||
|
|
||||||
|
It is also possible to create a ConfigState instance that provides methods
|
||||||
|
equivalent to the top-level functions. This allows concurrent configuration
|
||||||
|
options. See the ConfigState documentation for more details.
|
||||||
|
|
||||||
|
The following configuration options are available:
|
||||||
|
* Indent
|
||||||
|
String to use for each indentation level for Dump functions.
|
||||||
|
It is a single space by default. A popular alternative is "\t".
|
||||||
|
|
||||||
|
* MaxDepth
|
||||||
|
Maximum number of levels to descend into nested data structures.
|
||||||
|
There is no limit by default.
|
||||||
|
|
||||||
|
* DisableMethods
|
||||||
|
Disables invocation of error and Stringer interface methods.
|
||||||
|
Method invocation is enabled by default.
|
||||||
|
|
||||||
|
* DisablePointerMethods
|
||||||
|
Disables invocation of error and Stringer interface methods on types
|
||||||
|
which only accept pointer receivers from non-pointer variables.
|
||||||
|
Pointer method invocation is enabled by default.
|
||||||
|
|
||||||
|
* ContinueOnMethod
|
||||||
|
Enables recursion into types after invoking error and Stringer interface
|
||||||
|
methods. Recursion after method invocation is disabled by default.
|
||||||
|
|
||||||
|
* SortKeys
|
||||||
|
Specifies map keys should be sorted before being printed. Use
|
||||||
|
this to have a more deterministic, diffable output. Note that
|
||||||
|
only native types (bool, int, uint, floats, uintptr and string)
|
||||||
|
and types which implement error or Stringer interfaces are
|
||||||
|
supported with other types sorted according to the
|
||||||
|
reflect.Value.String() output which guarantees display
|
||||||
|
stability. Natural map order is used by default.
|
||||||
|
|
||||||
|
* SpewKeys
|
||||||
|
Specifies that, as a last resort attempt, map keys should be
|
||||||
|
spewed to strings and sorted by those strings. This is only
|
||||||
|
considered if SortKeys is true.
|
||||||
|
|
||||||
|
Dump Usage
|
||||||
|
|
||||||
|
Simply call spew.Dump with a list of variables you want to dump:
|
||||||
|
|
||||||
|
spew.Dump(myVar1, myVar2, ...)
|
||||||
|
|
||||||
|
You may also call spew.Fdump if you would prefer to output to an arbitrary
|
||||||
|
io.Writer. For example, to dump to standard error:
|
||||||
|
|
||||||
|
spew.Fdump(os.Stderr, myVar1, myVar2, ...)
|
||||||
|
|
||||||
|
A third option is to call spew.Sdump to get the formatted output as a string:
|
||||||
|
|
||||||
|
str := spew.Sdump(myVar1, myVar2, ...)
|
||||||
|
|
||||||
|
Sample Dump Output
|
||||||
|
|
||||||
|
See the Dump example for details on the setup of the types and variables being
|
||||||
|
shown here.
|
||||||
|
|
||||||
|
(main.Foo) {
|
||||||
|
unexportedField: (*main.Bar)(0xf84002e210)({
|
||||||
|
flag: (main.Flag) flagTwo,
|
||||||
|
data: (uintptr) <nil>
|
||||||
|
}),
|
||||||
|
ExportedField: (map[interface {}]interface {}) (len=1) {
|
||||||
|
(string) (len=3) "one": (bool) true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Byte (and uint8) arrays and slices are displayed uniquely like the hexdump -C
|
||||||
|
command as shown.
|
||||||
|
([]uint8) (len=32 cap=32) {
|
||||||
|
00000000 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 |............... |
|
||||||
|
00000010 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f 30 |!"#$%&'()*+,-./0|
|
||||||
|
00000020 31 32 |12|
|
||||||
|
}
|
||||||
|
|
||||||
|
Custom Formatter
|
||||||
|
|
||||||
|
Spew provides a custom formatter that implements the fmt.Formatter interface
|
||||||
|
so that it integrates cleanly with standard fmt package printing functions. The
|
||||||
|
formatter is useful for inline printing of smaller data types similar to the
|
||||||
|
standard %v format specifier.
|
||||||
|
|
||||||
|
The custom formatter only responds to the %v (most compact), %+v (adds pointer
|
||||||
|
addresses), %#v (adds types), or %#+v (adds types and pointer addresses) verb
|
||||||
|
combinations. Any other verbs such as %x and %q will be sent to the the
|
||||||
|
standard fmt package for formatting. In addition, the custom formatter ignores
|
||||||
|
the width and precision arguments (however they will still work on the format
|
||||||
|
specifiers not handled by the custom formatter).
|
||||||
|
|
||||||
|
Custom Formatter Usage
|
||||||
|
|
||||||
|
The simplest way to make use of the spew custom formatter is to call one of the
|
||||||
|
convenience functions such as spew.Printf, spew.Println, or spew.Printf. The
|
||||||
|
functions have syntax you are most likely already familiar with:
|
||||||
|
|
||||||
|
spew.Printf("myVar1: %v -- myVar2: %+v", myVar1, myVar2)
|
||||||
|
spew.Printf("myVar3: %#v -- myVar4: %#+v", myVar3, myVar4)
|
||||||
|
spew.Println(myVar, myVar2)
|
||||||
|
spew.Fprintf(os.Stderr, "myVar1: %v -- myVar2: %+v", myVar1, myVar2)
|
||||||
|
spew.Fprintf(os.Stderr, "myVar3: %#v -- myVar4: %#+v", myVar3, myVar4)
|
||||||
|
|
||||||
|
See the Index for the full list convenience functions.
|
||||||
|
|
||||||
|
Sample Formatter Output
|
||||||
|
|
||||||
|
Double pointer to a uint8:
|
||||||
|
%v: <**>5
|
||||||
|
%+v: <**>(0xf8400420d0->0xf8400420c8)5
|
||||||
|
%#v: (**uint8)5
|
||||||
|
%#+v: (**uint8)(0xf8400420d0->0xf8400420c8)5
|
||||||
|
|
||||||
|
Pointer to circular struct with a uint8 field and a pointer to itself:
|
||||||
|
%v: <*>{1 <*><shown>}
|
||||||
|
%+v: <*>(0xf84003e260){ui8:1 c:<*>(0xf84003e260)<shown>}
|
||||||
|
%#v: (*main.circular){ui8:(uint8)1 c:(*main.circular)<shown>}
|
||||||
|
%#+v: (*main.circular)(0xf84003e260){ui8:(uint8)1 c:(*main.circular)(0xf84003e260)<shown>}
|
||||||
|
|
||||||
|
See the Printf example for details on the setup of variables being shown
|
||||||
|
here.
|
||||||
|
|
||||||
|
Errors
|
||||||
|
|
||||||
|
Since it is possible for custom Stringer/error interfaces to panic, spew
|
||||||
|
detects them and handles them internally by printing the panic information
|
||||||
|
inline with the output. Since spew is intended to provide deep pretty printing
|
||||||
|
capabilities on structures, it intentionally does not return any errors.
|
||||||
|
*/
|
||||||
|
package spew
|
||||||
509
staging/src/k8s.io/client-go/1.4/_vendor/github.com/davecgh/go-spew/spew/dump.go
generated
Normal file
509
staging/src/k8s.io/client-go/1.4/_vendor/github.com/davecgh/go-spew/spew/dump.go
generated
Normal file
@@ -0,0 +1,509 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2013 Dave Collins <dave@davec.name>
|
||||||
|
*
|
||||||
|
* Permission to use, copy, modify, and distribute this software for any
|
||||||
|
* purpose with or without fee is hereby granted, provided that the above
|
||||||
|
* copyright notice and this permission notice appear in all copies.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
|
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package spew
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/hex"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"os"
|
||||||
|
"reflect"
|
||||||
|
"regexp"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
// uint8Type is a reflect.Type representing a uint8. It is used to
|
||||||
|
// convert cgo types to uint8 slices for hexdumping.
|
||||||
|
uint8Type = reflect.TypeOf(uint8(0))
|
||||||
|
|
||||||
|
// cCharRE is a regular expression that matches a cgo char.
|
||||||
|
// It is used to detect character arrays to hexdump them.
|
||||||
|
cCharRE = regexp.MustCompile("^.*\\._Ctype_char$")
|
||||||
|
|
||||||
|
// cUnsignedCharRE is a regular expression that matches a cgo unsigned
|
||||||
|
// char. It is used to detect unsigned character arrays to hexdump
|
||||||
|
// them.
|
||||||
|
cUnsignedCharRE = regexp.MustCompile("^.*\\._Ctype_unsignedchar$")
|
||||||
|
|
||||||
|
// cUint8tCharRE is a regular expression that matches a cgo uint8_t.
|
||||||
|
// It is used to detect uint8_t arrays to hexdump them.
|
||||||
|
cUint8tCharRE = regexp.MustCompile("^.*\\._Ctype_uint8_t$")
|
||||||
|
)
|
||||||
|
|
||||||
|
// dumpState contains information about the state of a dump operation.
|
||||||
|
type dumpState struct {
|
||||||
|
w io.Writer
|
||||||
|
depth int
|
||||||
|
pointers map[uintptr]int
|
||||||
|
ignoreNextType bool
|
||||||
|
ignoreNextIndent bool
|
||||||
|
cs *ConfigState
|
||||||
|
}
|
||||||
|
|
||||||
|
// indent performs indentation according to the depth level and cs.Indent
|
||||||
|
// option.
|
||||||
|
func (d *dumpState) indent() {
|
||||||
|
if d.ignoreNextIndent {
|
||||||
|
d.ignoreNextIndent = false
|
||||||
|
return
|
||||||
|
}
|
||||||
|
d.w.Write(bytes.Repeat([]byte(d.cs.Indent), d.depth))
|
||||||
|
}
|
||||||
|
|
||||||
|
// unpackValue returns values inside of non-nil interfaces when possible.
|
||||||
|
// This is useful for data types like structs, arrays, slices, and maps which
|
||||||
|
// can contain varying types packed inside an interface.
|
||||||
|
func (d *dumpState) unpackValue(v reflect.Value) reflect.Value {
|
||||||
|
if v.Kind() == reflect.Interface && !v.IsNil() {
|
||||||
|
v = v.Elem()
|
||||||
|
}
|
||||||
|
return v
|
||||||
|
}
|
||||||
|
|
||||||
|
// dumpPtr handles formatting of pointers by indirecting them as necessary.
|
||||||
|
func (d *dumpState) dumpPtr(v reflect.Value) {
|
||||||
|
// Remove pointers at or below the current depth from map used to detect
|
||||||
|
// circular refs.
|
||||||
|
for k, depth := range d.pointers {
|
||||||
|
if depth >= d.depth {
|
||||||
|
delete(d.pointers, k)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Keep list of all dereferenced pointers to show later.
|
||||||
|
pointerChain := make([]uintptr, 0)
|
||||||
|
|
||||||
|
// Figure out how many levels of indirection there are by dereferencing
|
||||||
|
// pointers and unpacking interfaces down the chain while detecting circular
|
||||||
|
// references.
|
||||||
|
nilFound := false
|
||||||
|
cycleFound := false
|
||||||
|
indirects := 0
|
||||||
|
ve := v
|
||||||
|
for ve.Kind() == reflect.Ptr {
|
||||||
|
if ve.IsNil() {
|
||||||
|
nilFound = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
indirects++
|
||||||
|
addr := ve.Pointer()
|
||||||
|
pointerChain = append(pointerChain, addr)
|
||||||
|
if pd, ok := d.pointers[addr]; ok && pd < d.depth {
|
||||||
|
cycleFound = true
|
||||||
|
indirects--
|
||||||
|
break
|
||||||
|
}
|
||||||
|
d.pointers[addr] = d.depth
|
||||||
|
|
||||||
|
ve = ve.Elem()
|
||||||
|
if ve.Kind() == reflect.Interface {
|
||||||
|
if ve.IsNil() {
|
||||||
|
nilFound = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
ve = ve.Elem()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Display type information.
|
||||||
|
d.w.Write(openParenBytes)
|
||||||
|
d.w.Write(bytes.Repeat(asteriskBytes, indirects))
|
||||||
|
d.w.Write([]byte(ve.Type().String()))
|
||||||
|
d.w.Write(closeParenBytes)
|
||||||
|
|
||||||
|
// Display pointer information.
|
||||||
|
if len(pointerChain) > 0 {
|
||||||
|
d.w.Write(openParenBytes)
|
||||||
|
for i, addr := range pointerChain {
|
||||||
|
if i > 0 {
|
||||||
|
d.w.Write(pointerChainBytes)
|
||||||
|
}
|
||||||
|
printHexPtr(d.w, addr)
|
||||||
|
}
|
||||||
|
d.w.Write(closeParenBytes)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Display dereferenced value.
|
||||||
|
d.w.Write(openParenBytes)
|
||||||
|
switch {
|
||||||
|
case nilFound == true:
|
||||||
|
d.w.Write(nilAngleBytes)
|
||||||
|
|
||||||
|
case cycleFound == true:
|
||||||
|
d.w.Write(circularBytes)
|
||||||
|
|
||||||
|
default:
|
||||||
|
d.ignoreNextType = true
|
||||||
|
d.dump(ve)
|
||||||
|
}
|
||||||
|
d.w.Write(closeParenBytes)
|
||||||
|
}
|
||||||
|
|
||||||
|
// dumpSlice handles formatting of arrays and slices. Byte (uint8 under
|
||||||
|
// reflection) arrays and slices are dumped in hexdump -C fashion.
|
||||||
|
func (d *dumpState) dumpSlice(v reflect.Value) {
|
||||||
|
// Determine whether this type should be hex dumped or not. Also,
|
||||||
|
// for types which should be hexdumped, try to use the underlying data
|
||||||
|
// first, then fall back to trying to convert them to a uint8 slice.
|
||||||
|
var buf []uint8
|
||||||
|
doConvert := false
|
||||||
|
doHexDump := false
|
||||||
|
numEntries := v.Len()
|
||||||
|
if numEntries > 0 {
|
||||||
|
vt := v.Index(0).Type()
|
||||||
|
vts := vt.String()
|
||||||
|
switch {
|
||||||
|
// C types that need to be converted.
|
||||||
|
case cCharRE.MatchString(vts):
|
||||||
|
fallthrough
|
||||||
|
case cUnsignedCharRE.MatchString(vts):
|
||||||
|
fallthrough
|
||||||
|
case cUint8tCharRE.MatchString(vts):
|
||||||
|
doConvert = true
|
||||||
|
|
||||||
|
// Try to use existing uint8 slices and fall back to converting
|
||||||
|
// and copying if that fails.
|
||||||
|
case vt.Kind() == reflect.Uint8:
|
||||||
|
// We need an addressable interface to convert the type
|
||||||
|
// to a byte slice. However, the reflect package won't
|
||||||
|
// give us an interface on certain things like
|
||||||
|
// unexported struct fields in order to enforce
|
||||||
|
// visibility rules. We use unsafe, when available, to
|
||||||
|
// bypass these restrictions since this package does not
|
||||||
|
// mutate the values.
|
||||||
|
vs := v
|
||||||
|
if !vs.CanInterface() || !vs.CanAddr() {
|
||||||
|
vs = unsafeReflectValue(vs)
|
||||||
|
}
|
||||||
|
if !UnsafeDisabled {
|
||||||
|
vs = vs.Slice(0, numEntries)
|
||||||
|
|
||||||
|
// Use the existing uint8 slice if it can be
|
||||||
|
// type asserted.
|
||||||
|
iface := vs.Interface()
|
||||||
|
if slice, ok := iface.([]uint8); ok {
|
||||||
|
buf = slice
|
||||||
|
doHexDump = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// The underlying data needs to be converted if it can't
|
||||||
|
// be type asserted to a uint8 slice.
|
||||||
|
doConvert = true
|
||||||
|
}
|
||||||
|
|
||||||
|
// Copy and convert the underlying type if needed.
|
||||||
|
if doConvert && vt.ConvertibleTo(uint8Type) {
|
||||||
|
// Convert and copy each element into a uint8 byte
|
||||||
|
// slice.
|
||||||
|
buf = make([]uint8, numEntries)
|
||||||
|
for i := 0; i < numEntries; i++ {
|
||||||
|
vv := v.Index(i)
|
||||||
|
buf[i] = uint8(vv.Convert(uint8Type).Uint())
|
||||||
|
}
|
||||||
|
doHexDump = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Hexdump the entire slice as needed.
|
||||||
|
if doHexDump {
|
||||||
|
indent := strings.Repeat(d.cs.Indent, d.depth)
|
||||||
|
str := indent + hex.Dump(buf)
|
||||||
|
str = strings.Replace(str, "\n", "\n"+indent, -1)
|
||||||
|
str = strings.TrimRight(str, d.cs.Indent)
|
||||||
|
d.w.Write([]byte(str))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Recursively call dump for each item.
|
||||||
|
for i := 0; i < numEntries; i++ {
|
||||||
|
d.dump(d.unpackValue(v.Index(i)))
|
||||||
|
if i < (numEntries - 1) {
|
||||||
|
d.w.Write(commaNewlineBytes)
|
||||||
|
} else {
|
||||||
|
d.w.Write(newlineBytes)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// dump is the main workhorse for dumping a value. It uses the passed reflect
|
||||||
|
// value to figure out what kind of object we are dealing with and formats it
|
||||||
|
// appropriately. It is a recursive function, however circular data structures
|
||||||
|
// are detected and handled properly.
|
||||||
|
func (d *dumpState) dump(v reflect.Value) {
|
||||||
|
// Handle invalid reflect values immediately.
|
||||||
|
kind := v.Kind()
|
||||||
|
if kind == reflect.Invalid {
|
||||||
|
d.w.Write(invalidAngleBytes)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle pointers specially.
|
||||||
|
if kind == reflect.Ptr {
|
||||||
|
d.indent()
|
||||||
|
d.dumpPtr(v)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Print type information unless already handled elsewhere.
|
||||||
|
if !d.ignoreNextType {
|
||||||
|
d.indent()
|
||||||
|
d.w.Write(openParenBytes)
|
||||||
|
d.w.Write([]byte(v.Type().String()))
|
||||||
|
d.w.Write(closeParenBytes)
|
||||||
|
d.w.Write(spaceBytes)
|
||||||
|
}
|
||||||
|
d.ignoreNextType = false
|
||||||
|
|
||||||
|
// Display length and capacity if the built-in len and cap functions
|
||||||
|
// work with the value's kind and the len/cap itself is non-zero.
|
||||||
|
valueLen, valueCap := 0, 0
|
||||||
|
switch v.Kind() {
|
||||||
|
case reflect.Array, reflect.Slice, reflect.Chan:
|
||||||
|
valueLen, valueCap = v.Len(), v.Cap()
|
||||||
|
case reflect.Map, reflect.String:
|
||||||
|
valueLen = v.Len()
|
||||||
|
}
|
||||||
|
if valueLen != 0 || valueCap != 0 {
|
||||||
|
d.w.Write(openParenBytes)
|
||||||
|
if valueLen != 0 {
|
||||||
|
d.w.Write(lenEqualsBytes)
|
||||||
|
printInt(d.w, int64(valueLen), 10)
|
||||||
|
}
|
||||||
|
if valueCap != 0 {
|
||||||
|
if valueLen != 0 {
|
||||||
|
d.w.Write(spaceBytes)
|
||||||
|
}
|
||||||
|
d.w.Write(capEqualsBytes)
|
||||||
|
printInt(d.w, int64(valueCap), 10)
|
||||||
|
}
|
||||||
|
d.w.Write(closeParenBytes)
|
||||||
|
d.w.Write(spaceBytes)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Call Stringer/error interfaces if they exist and the handle methods flag
|
||||||
|
// is enabled
|
||||||
|
if !d.cs.DisableMethods {
|
||||||
|
if (kind != reflect.Invalid) && (kind != reflect.Interface) {
|
||||||
|
if handled := handleMethods(d.cs, d.w, v); handled {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
switch kind {
|
||||||
|
case reflect.Invalid:
|
||||||
|
// Do nothing. We should never get here since invalid has already
|
||||||
|
// been handled above.
|
||||||
|
|
||||||
|
case reflect.Bool:
|
||||||
|
printBool(d.w, v.Bool())
|
||||||
|
|
||||||
|
case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int:
|
||||||
|
printInt(d.w, v.Int(), 10)
|
||||||
|
|
||||||
|
case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint:
|
||||||
|
printUint(d.w, v.Uint(), 10)
|
||||||
|
|
||||||
|
case reflect.Float32:
|
||||||
|
printFloat(d.w, v.Float(), 32)
|
||||||
|
|
||||||
|
case reflect.Float64:
|
||||||
|
printFloat(d.w, v.Float(), 64)
|
||||||
|
|
||||||
|
case reflect.Complex64:
|
||||||
|
printComplex(d.w, v.Complex(), 32)
|
||||||
|
|
||||||
|
case reflect.Complex128:
|
||||||
|
printComplex(d.w, v.Complex(), 64)
|
||||||
|
|
||||||
|
case reflect.Slice:
|
||||||
|
if v.IsNil() {
|
||||||
|
d.w.Write(nilAngleBytes)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
fallthrough
|
||||||
|
|
||||||
|
case reflect.Array:
|
||||||
|
d.w.Write(openBraceNewlineBytes)
|
||||||
|
d.depth++
|
||||||
|
if (d.cs.MaxDepth != 0) && (d.depth > d.cs.MaxDepth) {
|
||||||
|
d.indent()
|
||||||
|
d.w.Write(maxNewlineBytes)
|
||||||
|
} else {
|
||||||
|
d.dumpSlice(v)
|
||||||
|
}
|
||||||
|
d.depth--
|
||||||
|
d.indent()
|
||||||
|
d.w.Write(closeBraceBytes)
|
||||||
|
|
||||||
|
case reflect.String:
|
||||||
|
d.w.Write([]byte(strconv.Quote(v.String())))
|
||||||
|
|
||||||
|
case reflect.Interface:
|
||||||
|
// The only time we should get here is for nil interfaces due to
|
||||||
|
// unpackValue calls.
|
||||||
|
if v.IsNil() {
|
||||||
|
d.w.Write(nilAngleBytes)
|
||||||
|
}
|
||||||
|
|
||||||
|
case reflect.Ptr:
|
||||||
|
// Do nothing. We should never get here since pointers have already
|
||||||
|
// been handled above.
|
||||||
|
|
||||||
|
case reflect.Map:
|
||||||
|
// nil maps should be indicated as different than empty maps
|
||||||
|
if v.IsNil() {
|
||||||
|
d.w.Write(nilAngleBytes)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
d.w.Write(openBraceNewlineBytes)
|
||||||
|
d.depth++
|
||||||
|
if (d.cs.MaxDepth != 0) && (d.depth > d.cs.MaxDepth) {
|
||||||
|
d.indent()
|
||||||
|
d.w.Write(maxNewlineBytes)
|
||||||
|
} else {
|
||||||
|
numEntries := v.Len()
|
||||||
|
keys := v.MapKeys()
|
||||||
|
if d.cs.SortKeys {
|
||||||
|
sortValues(keys, d.cs)
|
||||||
|
}
|
||||||
|
for i, key := range keys {
|
||||||
|
d.dump(d.unpackValue(key))
|
||||||
|
d.w.Write(colonSpaceBytes)
|
||||||
|
d.ignoreNextIndent = true
|
||||||
|
d.dump(d.unpackValue(v.MapIndex(key)))
|
||||||
|
if i < (numEntries - 1) {
|
||||||
|
d.w.Write(commaNewlineBytes)
|
||||||
|
} else {
|
||||||
|
d.w.Write(newlineBytes)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
d.depth--
|
||||||
|
d.indent()
|
||||||
|
d.w.Write(closeBraceBytes)
|
||||||
|
|
||||||
|
case reflect.Struct:
|
||||||
|
d.w.Write(openBraceNewlineBytes)
|
||||||
|
d.depth++
|
||||||
|
if (d.cs.MaxDepth != 0) && (d.depth > d.cs.MaxDepth) {
|
||||||
|
d.indent()
|
||||||
|
d.w.Write(maxNewlineBytes)
|
||||||
|
} else {
|
||||||
|
vt := v.Type()
|
||||||
|
numFields := v.NumField()
|
||||||
|
for i := 0; i < numFields; i++ {
|
||||||
|
d.indent()
|
||||||
|
vtf := vt.Field(i)
|
||||||
|
d.w.Write([]byte(vtf.Name))
|
||||||
|
d.w.Write(colonSpaceBytes)
|
||||||
|
d.ignoreNextIndent = true
|
||||||
|
d.dump(d.unpackValue(v.Field(i)))
|
||||||
|
if i < (numFields - 1) {
|
||||||
|
d.w.Write(commaNewlineBytes)
|
||||||
|
} else {
|
||||||
|
d.w.Write(newlineBytes)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
d.depth--
|
||||||
|
d.indent()
|
||||||
|
d.w.Write(closeBraceBytes)
|
||||||
|
|
||||||
|
case reflect.Uintptr:
|
||||||
|
printHexPtr(d.w, uintptr(v.Uint()))
|
||||||
|
|
||||||
|
case reflect.UnsafePointer, reflect.Chan, reflect.Func:
|
||||||
|
printHexPtr(d.w, v.Pointer())
|
||||||
|
|
||||||
|
// There were not any other types at the time this code was written, but
|
||||||
|
// fall back to letting the default fmt package handle it in case any new
|
||||||
|
// types are added.
|
||||||
|
default:
|
||||||
|
if v.CanInterface() {
|
||||||
|
fmt.Fprintf(d.w, "%v", v.Interface())
|
||||||
|
} else {
|
||||||
|
fmt.Fprintf(d.w, "%v", v.String())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// fdump is a helper function to consolidate the logic from the various public
|
||||||
|
// methods which take varying writers and config states.
|
||||||
|
func fdump(cs *ConfigState, w io.Writer, a ...interface{}) {
|
||||||
|
for _, arg := range a {
|
||||||
|
if arg == nil {
|
||||||
|
w.Write(interfaceBytes)
|
||||||
|
w.Write(spaceBytes)
|
||||||
|
w.Write(nilAngleBytes)
|
||||||
|
w.Write(newlineBytes)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
d := dumpState{w: w, cs: cs}
|
||||||
|
d.pointers = make(map[uintptr]int)
|
||||||
|
d.dump(reflect.ValueOf(arg))
|
||||||
|
d.w.Write(newlineBytes)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fdump formats and displays the passed arguments to io.Writer w. It formats
|
||||||
|
// exactly the same as Dump.
|
||||||
|
func Fdump(w io.Writer, a ...interface{}) {
|
||||||
|
fdump(&Config, w, a...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sdump returns a string with the passed arguments formatted exactly the same
|
||||||
|
// as Dump.
|
||||||
|
func Sdump(a ...interface{}) string {
|
||||||
|
var buf bytes.Buffer
|
||||||
|
fdump(&Config, &buf, a...)
|
||||||
|
return buf.String()
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Dump displays the passed parameters to standard out with newlines, customizable
|
||||||
|
indentation, and additional debug information such as complete types and all
|
||||||
|
pointer addresses used to indirect to the final value. It provides the
|
||||||
|
following features over the built-in printing facilities provided by the fmt
|
||||||
|
package:
|
||||||
|
|
||||||
|
* Pointers are dereferenced and followed
|
||||||
|
* Circular data structures are detected and handled properly
|
||||||
|
* Custom Stringer/error interfaces are optionally invoked, including
|
||||||
|
on unexported types
|
||||||
|
* Custom types which only implement the Stringer/error interfaces via
|
||||||
|
a pointer receiver are optionally invoked when passing non-pointer
|
||||||
|
variables
|
||||||
|
* Byte arrays and slices are dumped like the hexdump -C command which
|
||||||
|
includes offsets, byte values in hex, and ASCII output
|
||||||
|
|
||||||
|
The configuration options are controlled by an exported package global,
|
||||||
|
spew.Config. See ConfigState for options documentation.
|
||||||
|
|
||||||
|
See Fdump if you would prefer dumping to an arbitrary io.Writer or Sdump to
|
||||||
|
get the formatted result as a string.
|
||||||
|
*/
|
||||||
|
func Dump(a ...interface{}) {
|
||||||
|
fdump(&Config, os.Stdout, a...)
|
||||||
|
}
|
||||||
419
staging/src/k8s.io/client-go/1.4/_vendor/github.com/davecgh/go-spew/spew/format.go
generated
Normal file
419
staging/src/k8s.io/client-go/1.4/_vendor/github.com/davecgh/go-spew/spew/format.go
generated
Normal file
@@ -0,0 +1,419 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2013 Dave Collins <dave@davec.name>
|
||||||
|
*
|
||||||
|
* Permission to use, copy, modify, and distribute this software for any
|
||||||
|
* purpose with or without fee is hereby granted, provided that the above
|
||||||
|
* copyright notice and this permission notice appear in all copies.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
|
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package spew
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"fmt"
|
||||||
|
"reflect"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
// supportedFlags is a list of all the character flags supported by fmt package.
|
||||||
|
const supportedFlags = "0-+# "
|
||||||
|
|
||||||
|
// formatState implements the fmt.Formatter interface and contains information
|
||||||
|
// about the state of a formatting operation. The NewFormatter function can
|
||||||
|
// be used to get a new Formatter which can be used directly as arguments
|
||||||
|
// in standard fmt package printing calls.
|
||||||
|
type formatState struct {
|
||||||
|
value interface{}
|
||||||
|
fs fmt.State
|
||||||
|
depth int
|
||||||
|
pointers map[uintptr]int
|
||||||
|
ignoreNextType bool
|
||||||
|
cs *ConfigState
|
||||||
|
}
|
||||||
|
|
||||||
|
// buildDefaultFormat recreates the original format string without precision
|
||||||
|
// and width information to pass in to fmt.Sprintf in the case of an
|
||||||
|
// unrecognized type. Unless new types are added to the language, this
|
||||||
|
// function won't ever be called.
|
||||||
|
func (f *formatState) buildDefaultFormat() (format string) {
|
||||||
|
buf := bytes.NewBuffer(percentBytes)
|
||||||
|
|
||||||
|
for _, flag := range supportedFlags {
|
||||||
|
if f.fs.Flag(int(flag)) {
|
||||||
|
buf.WriteRune(flag)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
buf.WriteRune('v')
|
||||||
|
|
||||||
|
format = buf.String()
|
||||||
|
return format
|
||||||
|
}
|
||||||
|
|
||||||
|
// constructOrigFormat recreates the original format string including precision
|
||||||
|
// and width information to pass along to the standard fmt package. This allows
|
||||||
|
// automatic deferral of all format strings this package doesn't support.
|
||||||
|
func (f *formatState) constructOrigFormat(verb rune) (format string) {
|
||||||
|
buf := bytes.NewBuffer(percentBytes)
|
||||||
|
|
||||||
|
for _, flag := range supportedFlags {
|
||||||
|
if f.fs.Flag(int(flag)) {
|
||||||
|
buf.WriteRune(flag)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if width, ok := f.fs.Width(); ok {
|
||||||
|
buf.WriteString(strconv.Itoa(width))
|
||||||
|
}
|
||||||
|
|
||||||
|
if precision, ok := f.fs.Precision(); ok {
|
||||||
|
buf.Write(precisionBytes)
|
||||||
|
buf.WriteString(strconv.Itoa(precision))
|
||||||
|
}
|
||||||
|
|
||||||
|
buf.WriteRune(verb)
|
||||||
|
|
||||||
|
format = buf.String()
|
||||||
|
return format
|
||||||
|
}
|
||||||
|
|
||||||
|
// unpackValue returns values inside of non-nil interfaces when possible and
|
||||||
|
// ensures that types for values which have been unpacked from an interface
|
||||||
|
// are displayed when the show types flag is also set.
|
||||||
|
// This is useful for data types like structs, arrays, slices, and maps which
|
||||||
|
// can contain varying types packed inside an interface.
|
||||||
|
func (f *formatState) unpackValue(v reflect.Value) reflect.Value {
|
||||||
|
if v.Kind() == reflect.Interface {
|
||||||
|
f.ignoreNextType = false
|
||||||
|
if !v.IsNil() {
|
||||||
|
v = v.Elem()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return v
|
||||||
|
}
|
||||||
|
|
||||||
|
// formatPtr handles formatting of pointers by indirecting them as necessary.
|
||||||
|
func (f *formatState) formatPtr(v reflect.Value) {
|
||||||
|
// Display nil if top level pointer is nil.
|
||||||
|
showTypes := f.fs.Flag('#')
|
||||||
|
if v.IsNil() && (!showTypes || f.ignoreNextType) {
|
||||||
|
f.fs.Write(nilAngleBytes)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove pointers at or below the current depth from map used to detect
|
||||||
|
// circular refs.
|
||||||
|
for k, depth := range f.pointers {
|
||||||
|
if depth >= f.depth {
|
||||||
|
delete(f.pointers, k)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Keep list of all dereferenced pointers to possibly show later.
|
||||||
|
pointerChain := make([]uintptr, 0)
|
||||||
|
|
||||||
|
// Figure out how many levels of indirection there are by derferencing
|
||||||
|
// pointers and unpacking interfaces down the chain while detecting circular
|
||||||
|
// references.
|
||||||
|
nilFound := false
|
||||||
|
cycleFound := false
|
||||||
|
indirects := 0
|
||||||
|
ve := v
|
||||||
|
for ve.Kind() == reflect.Ptr {
|
||||||
|
if ve.IsNil() {
|
||||||
|
nilFound = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
indirects++
|
||||||
|
addr := ve.Pointer()
|
||||||
|
pointerChain = append(pointerChain, addr)
|
||||||
|
if pd, ok := f.pointers[addr]; ok && pd < f.depth {
|
||||||
|
cycleFound = true
|
||||||
|
indirects--
|
||||||
|
break
|
||||||
|
}
|
||||||
|
f.pointers[addr] = f.depth
|
||||||
|
|
||||||
|
ve = ve.Elem()
|
||||||
|
if ve.Kind() == reflect.Interface {
|
||||||
|
if ve.IsNil() {
|
||||||
|
nilFound = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
ve = ve.Elem()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Display type or indirection level depending on flags.
|
||||||
|
if showTypes && !f.ignoreNextType {
|
||||||
|
f.fs.Write(openParenBytes)
|
||||||
|
f.fs.Write(bytes.Repeat(asteriskBytes, indirects))
|
||||||
|
f.fs.Write([]byte(ve.Type().String()))
|
||||||
|
f.fs.Write(closeParenBytes)
|
||||||
|
} else {
|
||||||
|
if nilFound || cycleFound {
|
||||||
|
indirects += strings.Count(ve.Type().String(), "*")
|
||||||
|
}
|
||||||
|
f.fs.Write(openAngleBytes)
|
||||||
|
f.fs.Write([]byte(strings.Repeat("*", indirects)))
|
||||||
|
f.fs.Write(closeAngleBytes)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Display pointer information depending on flags.
|
||||||
|
if f.fs.Flag('+') && (len(pointerChain) > 0) {
|
||||||
|
f.fs.Write(openParenBytes)
|
||||||
|
for i, addr := range pointerChain {
|
||||||
|
if i > 0 {
|
||||||
|
f.fs.Write(pointerChainBytes)
|
||||||
|
}
|
||||||
|
printHexPtr(f.fs, addr)
|
||||||
|
}
|
||||||
|
f.fs.Write(closeParenBytes)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Display dereferenced value.
|
||||||
|
switch {
|
||||||
|
case nilFound == true:
|
||||||
|
f.fs.Write(nilAngleBytes)
|
||||||
|
|
||||||
|
case cycleFound == true:
|
||||||
|
f.fs.Write(circularShortBytes)
|
||||||
|
|
||||||
|
default:
|
||||||
|
f.ignoreNextType = true
|
||||||
|
f.format(ve)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// format is the main workhorse for providing the Formatter interface. It
|
||||||
|
// uses the passed reflect value to figure out what kind of object we are
|
||||||
|
// dealing with and formats it appropriately. It is a recursive function,
|
||||||
|
// however circular data structures are detected and handled properly.
|
||||||
|
func (f *formatState) format(v reflect.Value) {
|
||||||
|
// Handle invalid reflect values immediately.
|
||||||
|
kind := v.Kind()
|
||||||
|
if kind == reflect.Invalid {
|
||||||
|
f.fs.Write(invalidAngleBytes)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle pointers specially.
|
||||||
|
if kind == reflect.Ptr {
|
||||||
|
f.formatPtr(v)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Print type information unless already handled elsewhere.
|
||||||
|
if !f.ignoreNextType && f.fs.Flag('#') {
|
||||||
|
f.fs.Write(openParenBytes)
|
||||||
|
f.fs.Write([]byte(v.Type().String()))
|
||||||
|
f.fs.Write(closeParenBytes)
|
||||||
|
}
|
||||||
|
f.ignoreNextType = false
|
||||||
|
|
||||||
|
// Call Stringer/error interfaces if they exist and the handle methods
|
||||||
|
// flag is enabled.
|
||||||
|
if !f.cs.DisableMethods {
|
||||||
|
if (kind != reflect.Invalid) && (kind != reflect.Interface) {
|
||||||
|
if handled := handleMethods(f.cs, f.fs, v); handled {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
switch kind {
|
||||||
|
case reflect.Invalid:
|
||||||
|
// Do nothing. We should never get here since invalid has already
|
||||||
|
// been handled above.
|
||||||
|
|
||||||
|
case reflect.Bool:
|
||||||
|
printBool(f.fs, v.Bool())
|
||||||
|
|
||||||
|
case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int:
|
||||||
|
printInt(f.fs, v.Int(), 10)
|
||||||
|
|
||||||
|
case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint:
|
||||||
|
printUint(f.fs, v.Uint(), 10)
|
||||||
|
|
||||||
|
case reflect.Float32:
|
||||||
|
printFloat(f.fs, v.Float(), 32)
|
||||||
|
|
||||||
|
case reflect.Float64:
|
||||||
|
printFloat(f.fs, v.Float(), 64)
|
||||||
|
|
||||||
|
case reflect.Complex64:
|
||||||
|
printComplex(f.fs, v.Complex(), 32)
|
||||||
|
|
||||||
|
case reflect.Complex128:
|
||||||
|
printComplex(f.fs, v.Complex(), 64)
|
||||||
|
|
||||||
|
case reflect.Slice:
|
||||||
|
if v.IsNil() {
|
||||||
|
f.fs.Write(nilAngleBytes)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
fallthrough
|
||||||
|
|
||||||
|
case reflect.Array:
|
||||||
|
f.fs.Write(openBracketBytes)
|
||||||
|
f.depth++
|
||||||
|
if (f.cs.MaxDepth != 0) && (f.depth > f.cs.MaxDepth) {
|
||||||
|
f.fs.Write(maxShortBytes)
|
||||||
|
} else {
|
||||||
|
numEntries := v.Len()
|
||||||
|
for i := 0; i < numEntries; i++ {
|
||||||
|
if i > 0 {
|
||||||
|
f.fs.Write(spaceBytes)
|
||||||
|
}
|
||||||
|
f.ignoreNextType = true
|
||||||
|
f.format(f.unpackValue(v.Index(i)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
f.depth--
|
||||||
|
f.fs.Write(closeBracketBytes)
|
||||||
|
|
||||||
|
case reflect.String:
|
||||||
|
f.fs.Write([]byte(v.String()))
|
||||||
|
|
||||||
|
case reflect.Interface:
|
||||||
|
// The only time we should get here is for nil interfaces due to
|
||||||
|
// unpackValue calls.
|
||||||
|
if v.IsNil() {
|
||||||
|
f.fs.Write(nilAngleBytes)
|
||||||
|
}
|
||||||
|
|
||||||
|
case reflect.Ptr:
|
||||||
|
// Do nothing. We should never get here since pointers have already
|
||||||
|
// been handled above.
|
||||||
|
|
||||||
|
case reflect.Map:
|
||||||
|
// nil maps should be indicated as different than empty maps
|
||||||
|
if v.IsNil() {
|
||||||
|
f.fs.Write(nilAngleBytes)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
f.fs.Write(openMapBytes)
|
||||||
|
f.depth++
|
||||||
|
if (f.cs.MaxDepth != 0) && (f.depth > f.cs.MaxDepth) {
|
||||||
|
f.fs.Write(maxShortBytes)
|
||||||
|
} else {
|
||||||
|
keys := v.MapKeys()
|
||||||
|
if f.cs.SortKeys {
|
||||||
|
sortValues(keys, f.cs)
|
||||||
|
}
|
||||||
|
for i, key := range keys {
|
||||||
|
if i > 0 {
|
||||||
|
f.fs.Write(spaceBytes)
|
||||||
|
}
|
||||||
|
f.ignoreNextType = true
|
||||||
|
f.format(f.unpackValue(key))
|
||||||
|
f.fs.Write(colonBytes)
|
||||||
|
f.ignoreNextType = true
|
||||||
|
f.format(f.unpackValue(v.MapIndex(key)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
f.depth--
|
||||||
|
f.fs.Write(closeMapBytes)
|
||||||
|
|
||||||
|
case reflect.Struct:
|
||||||
|
numFields := v.NumField()
|
||||||
|
f.fs.Write(openBraceBytes)
|
||||||
|
f.depth++
|
||||||
|
if (f.cs.MaxDepth != 0) && (f.depth > f.cs.MaxDepth) {
|
||||||
|
f.fs.Write(maxShortBytes)
|
||||||
|
} else {
|
||||||
|
vt := v.Type()
|
||||||
|
for i := 0; i < numFields; i++ {
|
||||||
|
if i > 0 {
|
||||||
|
f.fs.Write(spaceBytes)
|
||||||
|
}
|
||||||
|
vtf := vt.Field(i)
|
||||||
|
if f.fs.Flag('+') || f.fs.Flag('#') {
|
||||||
|
f.fs.Write([]byte(vtf.Name))
|
||||||
|
f.fs.Write(colonBytes)
|
||||||
|
}
|
||||||
|
f.format(f.unpackValue(v.Field(i)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
f.depth--
|
||||||
|
f.fs.Write(closeBraceBytes)
|
||||||
|
|
||||||
|
case reflect.Uintptr:
|
||||||
|
printHexPtr(f.fs, uintptr(v.Uint()))
|
||||||
|
|
||||||
|
case reflect.UnsafePointer, reflect.Chan, reflect.Func:
|
||||||
|
printHexPtr(f.fs, v.Pointer())
|
||||||
|
|
||||||
|
// There were not any other types at the time this code was written, but
|
||||||
|
// fall back to letting the default fmt package handle it if any get added.
|
||||||
|
default:
|
||||||
|
format := f.buildDefaultFormat()
|
||||||
|
if v.CanInterface() {
|
||||||
|
fmt.Fprintf(f.fs, format, v.Interface())
|
||||||
|
} else {
|
||||||
|
fmt.Fprintf(f.fs, format, v.String())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Format satisfies the fmt.Formatter interface. See NewFormatter for usage
|
||||||
|
// details.
|
||||||
|
func (f *formatState) Format(fs fmt.State, verb rune) {
|
||||||
|
f.fs = fs
|
||||||
|
|
||||||
|
// Use standard formatting for verbs that are not v.
|
||||||
|
if verb != 'v' {
|
||||||
|
format := f.constructOrigFormat(verb)
|
||||||
|
fmt.Fprintf(fs, format, f.value)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if f.value == nil {
|
||||||
|
if fs.Flag('#') {
|
||||||
|
fs.Write(interfaceBytes)
|
||||||
|
}
|
||||||
|
fs.Write(nilAngleBytes)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
f.format(reflect.ValueOf(f.value))
|
||||||
|
}
|
||||||
|
|
||||||
|
// newFormatter is a helper function to consolidate the logic from the various
|
||||||
|
// public methods which take varying config states.
|
||||||
|
func newFormatter(cs *ConfigState, v interface{}) fmt.Formatter {
|
||||||
|
fs := &formatState{value: v, cs: cs}
|
||||||
|
fs.pointers = make(map[uintptr]int)
|
||||||
|
return fs
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
NewFormatter returns a custom formatter that satisfies the fmt.Formatter
|
||||||
|
interface. As a result, it integrates cleanly with standard fmt package
|
||||||
|
printing functions. The formatter is useful for inline printing of smaller data
|
||||||
|
types similar to the standard %v format specifier.
|
||||||
|
|
||||||
|
The custom formatter only responds to the %v (most compact), %+v (adds pointer
|
||||||
|
addresses), %#v (adds types), or %#+v (adds types and pointer addresses) verb
|
||||||
|
combinations. Any other verbs such as %x and %q will be sent to the the
|
||||||
|
standard fmt package for formatting. In addition, the custom formatter ignores
|
||||||
|
the width and precision arguments (however they will still work on the format
|
||||||
|
specifiers not handled by the custom formatter).
|
||||||
|
|
||||||
|
Typically this function shouldn't be called directly. It is much easier to make
|
||||||
|
use of the custom formatter by calling one of the convenience functions such as
|
||||||
|
Printf, Println, or Fprintf.
|
||||||
|
*/
|
||||||
|
func NewFormatter(v interface{}) fmt.Formatter {
|
||||||
|
return newFormatter(&Config, v)
|
||||||
|
}
|
||||||
148
staging/src/k8s.io/client-go/1.4/_vendor/github.com/davecgh/go-spew/spew/spew.go
generated
Normal file
148
staging/src/k8s.io/client-go/1.4/_vendor/github.com/davecgh/go-spew/spew/spew.go
generated
Normal file
@@ -0,0 +1,148 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2013 Dave Collins <dave@davec.name>
|
||||||
|
*
|
||||||
|
* Permission to use, copy, modify, and distribute this software for any
|
||||||
|
* purpose with or without fee is hereby granted, provided that the above
|
||||||
|
* copyright notice and this permission notice appear in all copies.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
|
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package spew
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Errorf is a wrapper for fmt.Errorf that treats each argument as if it were
|
||||||
|
// passed with a default Formatter interface returned by NewFormatter. It
|
||||||
|
// returns the formatted string as a value that satisfies error. See
|
||||||
|
// NewFormatter for formatting details.
|
||||||
|
//
|
||||||
|
// This function is shorthand for the following syntax:
|
||||||
|
//
|
||||||
|
// fmt.Errorf(format, spew.NewFormatter(a), spew.NewFormatter(b))
|
||||||
|
func Errorf(format string, a ...interface{}) (err error) {
|
||||||
|
return fmt.Errorf(format, convertArgs(a)...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fprint is a wrapper for fmt.Fprint that treats each argument as if it were
|
||||||
|
// passed with a default Formatter interface returned by NewFormatter. It
|
||||||
|
// returns the number of bytes written and any write error encountered. See
|
||||||
|
// NewFormatter for formatting details.
|
||||||
|
//
|
||||||
|
// This function is shorthand for the following syntax:
|
||||||
|
//
|
||||||
|
// fmt.Fprint(w, spew.NewFormatter(a), spew.NewFormatter(b))
|
||||||
|
func Fprint(w io.Writer, a ...interface{}) (n int, err error) {
|
||||||
|
return fmt.Fprint(w, convertArgs(a)...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fprintf is a wrapper for fmt.Fprintf that treats each argument as if it were
|
||||||
|
// passed with a default Formatter interface returned by NewFormatter. It
|
||||||
|
// returns the number of bytes written and any write error encountered. See
|
||||||
|
// NewFormatter for formatting details.
|
||||||
|
//
|
||||||
|
// This function is shorthand for the following syntax:
|
||||||
|
//
|
||||||
|
// fmt.Fprintf(w, format, spew.NewFormatter(a), spew.NewFormatter(b))
|
||||||
|
func Fprintf(w io.Writer, format string, a ...interface{}) (n int, err error) {
|
||||||
|
return fmt.Fprintf(w, format, convertArgs(a)...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fprintln is a wrapper for fmt.Fprintln that treats each argument as if it
|
||||||
|
// passed with a default Formatter interface returned by NewFormatter. See
|
||||||
|
// NewFormatter for formatting details.
|
||||||
|
//
|
||||||
|
// This function is shorthand for the following syntax:
|
||||||
|
//
|
||||||
|
// fmt.Fprintln(w, spew.NewFormatter(a), spew.NewFormatter(b))
|
||||||
|
func Fprintln(w io.Writer, a ...interface{}) (n int, err error) {
|
||||||
|
return fmt.Fprintln(w, convertArgs(a)...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Print is a wrapper for fmt.Print that treats each argument as if it were
|
||||||
|
// passed with a default Formatter interface returned by NewFormatter. It
|
||||||
|
// returns the number of bytes written and any write error encountered. See
|
||||||
|
// NewFormatter for formatting details.
|
||||||
|
//
|
||||||
|
// This function is shorthand for the following syntax:
|
||||||
|
//
|
||||||
|
// fmt.Print(spew.NewFormatter(a), spew.NewFormatter(b))
|
||||||
|
func Print(a ...interface{}) (n int, err error) {
|
||||||
|
return fmt.Print(convertArgs(a)...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Printf is a wrapper for fmt.Printf that treats each argument as if it were
|
||||||
|
// passed with a default Formatter interface returned by NewFormatter. It
|
||||||
|
// returns the number of bytes written and any write error encountered. See
|
||||||
|
// NewFormatter for formatting details.
|
||||||
|
//
|
||||||
|
// This function is shorthand for the following syntax:
|
||||||
|
//
|
||||||
|
// fmt.Printf(format, spew.NewFormatter(a), spew.NewFormatter(b))
|
||||||
|
func Printf(format string, a ...interface{}) (n int, err error) {
|
||||||
|
return fmt.Printf(format, convertArgs(a)...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Println is a wrapper for fmt.Println that treats each argument as if it were
|
||||||
|
// passed with a default Formatter interface returned by NewFormatter. It
|
||||||
|
// returns the number of bytes written and any write error encountered. See
|
||||||
|
// NewFormatter for formatting details.
|
||||||
|
//
|
||||||
|
// This function is shorthand for the following syntax:
|
||||||
|
//
|
||||||
|
// fmt.Println(spew.NewFormatter(a), spew.NewFormatter(b))
|
||||||
|
func Println(a ...interface{}) (n int, err error) {
|
||||||
|
return fmt.Println(convertArgs(a)...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sprint is a wrapper for fmt.Sprint that treats each argument as if it were
|
||||||
|
// passed with a default Formatter interface returned by NewFormatter. It
|
||||||
|
// returns the resulting string. See NewFormatter for formatting details.
|
||||||
|
//
|
||||||
|
// This function is shorthand for the following syntax:
|
||||||
|
//
|
||||||
|
// fmt.Sprint(spew.NewFormatter(a), spew.NewFormatter(b))
|
||||||
|
func Sprint(a ...interface{}) string {
|
||||||
|
return fmt.Sprint(convertArgs(a)...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sprintf is a wrapper for fmt.Sprintf that treats each argument as if it were
|
||||||
|
// passed with a default Formatter interface returned by NewFormatter. It
|
||||||
|
// returns the resulting string. See NewFormatter for formatting details.
|
||||||
|
//
|
||||||
|
// This function is shorthand for the following syntax:
|
||||||
|
//
|
||||||
|
// fmt.Sprintf(format, spew.NewFormatter(a), spew.NewFormatter(b))
|
||||||
|
func Sprintf(format string, a ...interface{}) string {
|
||||||
|
return fmt.Sprintf(format, convertArgs(a)...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sprintln is a wrapper for fmt.Sprintln that treats each argument as if it
|
||||||
|
// were passed with a default Formatter interface returned by NewFormatter. It
|
||||||
|
// returns the resulting string. See NewFormatter for formatting details.
|
||||||
|
//
|
||||||
|
// This function is shorthand for the following syntax:
|
||||||
|
//
|
||||||
|
// fmt.Sprintln(spew.NewFormatter(a), spew.NewFormatter(b))
|
||||||
|
func Sprintln(a ...interface{}) string {
|
||||||
|
return fmt.Sprintln(convertArgs(a)...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// convertArgs accepts a slice of arguments and returns a slice of the same
|
||||||
|
// length with each argument converted to a default spew Formatter interface.
|
||||||
|
func convertArgs(args []interface{}) (formatters []interface{}) {
|
||||||
|
formatters = make([]interface{}, len(args))
|
||||||
|
for index, arg := range args {
|
||||||
|
formatters[index] = NewFormatter(arg)
|
||||||
|
}
|
||||||
|
return formatters
|
||||||
|
}
|
||||||
202
staging/src/k8s.io/client-go/1.4/_vendor/github.com/docker/distribution/LICENSE
generated
Normal file
202
staging/src/k8s.io/client-go/1.4/_vendor/github.com/docker/distribution/LICENSE
generated
Normal file
@@ -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 {yyyy} {name of copyright owner}
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
139
staging/src/k8s.io/client-go/1.4/_vendor/github.com/docker/distribution/digest/digest.go
generated
Normal file
139
staging/src/k8s.io/client-go/1.4/_vendor/github.com/docker/distribution/digest/digest.go
generated
Normal file
@@ -0,0 +1,139 @@
|
|||||||
|
package digest
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"hash"
|
||||||
|
"io"
|
||||||
|
"regexp"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
// DigestSha256EmptyTar is the canonical sha256 digest of empty data
|
||||||
|
DigestSha256EmptyTar = "sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Digest allows simple protection of hex formatted digest strings, prefixed
|
||||||
|
// by their algorithm. Strings of type Digest have some guarantee of being in
|
||||||
|
// the correct format and it provides quick access to the components of a
|
||||||
|
// digest string.
|
||||||
|
//
|
||||||
|
// The following is an example of the contents of Digest types:
|
||||||
|
//
|
||||||
|
// sha256:7173b809ca12ec5dee4506cd86be934c4596dd234ee82c0662eac04a8c2c71dc
|
||||||
|
//
|
||||||
|
// This allows to abstract the digest behind this type and work only in those
|
||||||
|
// terms.
|
||||||
|
type Digest string
|
||||||
|
|
||||||
|
// NewDigest returns a Digest from alg and a hash.Hash object.
|
||||||
|
func NewDigest(alg Algorithm, h hash.Hash) Digest {
|
||||||
|
return NewDigestFromBytes(alg, h.Sum(nil))
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewDigestFromBytes returns a new digest from the byte contents of p.
|
||||||
|
// Typically, this can come from hash.Hash.Sum(...) or xxx.SumXXX(...)
|
||||||
|
// functions. This is also useful for rebuilding digests from binary
|
||||||
|
// serializations.
|
||||||
|
func NewDigestFromBytes(alg Algorithm, p []byte) Digest {
|
||||||
|
return Digest(fmt.Sprintf("%s:%x", alg, p))
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewDigestFromHex returns a Digest from alg and a the hex encoded digest.
|
||||||
|
func NewDigestFromHex(alg, hex string) Digest {
|
||||||
|
return Digest(fmt.Sprintf("%s:%s", alg, hex))
|
||||||
|
}
|
||||||
|
|
||||||
|
// DigestRegexp matches valid digest types.
|
||||||
|
var DigestRegexp = regexp.MustCompile(`[a-zA-Z0-9-_+.]+:[a-fA-F0-9]+`)
|
||||||
|
|
||||||
|
// DigestRegexpAnchored matches valid digest types, anchored to the start and end of the match.
|
||||||
|
var DigestRegexpAnchored = regexp.MustCompile(`^` + DigestRegexp.String() + `$`)
|
||||||
|
|
||||||
|
var (
|
||||||
|
// ErrDigestInvalidFormat returned when digest format invalid.
|
||||||
|
ErrDigestInvalidFormat = fmt.Errorf("invalid checksum digest format")
|
||||||
|
|
||||||
|
// ErrDigestInvalidLength returned when digest has invalid length.
|
||||||
|
ErrDigestInvalidLength = fmt.Errorf("invalid checksum digest length")
|
||||||
|
|
||||||
|
// ErrDigestUnsupported returned when the digest algorithm is unsupported.
|
||||||
|
ErrDigestUnsupported = fmt.Errorf("unsupported digest algorithm")
|
||||||
|
)
|
||||||
|
|
||||||
|
// ParseDigest parses s and returns the validated digest object. An error will
|
||||||
|
// be returned if the format is invalid.
|
||||||
|
func ParseDigest(s string) (Digest, error) {
|
||||||
|
d := Digest(s)
|
||||||
|
|
||||||
|
return d, d.Validate()
|
||||||
|
}
|
||||||
|
|
||||||
|
// FromReader returns the most valid digest for the underlying content using
|
||||||
|
// the canonical digest algorithm.
|
||||||
|
func FromReader(rd io.Reader) (Digest, error) {
|
||||||
|
return Canonical.FromReader(rd)
|
||||||
|
}
|
||||||
|
|
||||||
|
// FromBytes digests the input and returns a Digest.
|
||||||
|
func FromBytes(p []byte) Digest {
|
||||||
|
return Canonical.FromBytes(p)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate checks that the contents of d is a valid digest, returning an
|
||||||
|
// error if not.
|
||||||
|
func (d Digest) Validate() error {
|
||||||
|
s := string(d)
|
||||||
|
|
||||||
|
if !DigestRegexpAnchored.MatchString(s) {
|
||||||
|
return ErrDigestInvalidFormat
|
||||||
|
}
|
||||||
|
|
||||||
|
i := strings.Index(s, ":")
|
||||||
|
if i < 0 {
|
||||||
|
return ErrDigestInvalidFormat
|
||||||
|
}
|
||||||
|
|
||||||
|
// case: "sha256:" with no hex.
|
||||||
|
if i+1 == len(s) {
|
||||||
|
return ErrDigestInvalidFormat
|
||||||
|
}
|
||||||
|
|
||||||
|
switch algorithm := Algorithm(s[:i]); algorithm {
|
||||||
|
case SHA256, SHA384, SHA512:
|
||||||
|
if algorithm.Size()*2 != len(s[i+1:]) {
|
||||||
|
return ErrDigestInvalidLength
|
||||||
|
}
|
||||||
|
break
|
||||||
|
default:
|
||||||
|
return ErrDigestUnsupported
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Algorithm returns the algorithm portion of the digest. This will panic if
|
||||||
|
// the underlying digest is not in a valid format.
|
||||||
|
func (d Digest) Algorithm() Algorithm {
|
||||||
|
return Algorithm(d[:d.sepIndex()])
|
||||||
|
}
|
||||||
|
|
||||||
|
// Hex returns the hex digest portion of the digest. This will panic if the
|
||||||
|
// underlying digest is not in a valid format.
|
||||||
|
func (d Digest) Hex() string {
|
||||||
|
return string(d[d.sepIndex()+1:])
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d Digest) String() string {
|
||||||
|
return string(d)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d Digest) sepIndex() int {
|
||||||
|
i := strings.Index(string(d), ":")
|
||||||
|
|
||||||
|
if i < 0 {
|
||||||
|
panic("could not find ':' in digest: " + d)
|
||||||
|
}
|
||||||
|
|
||||||
|
return i
|
||||||
|
}
|
||||||
155
staging/src/k8s.io/client-go/1.4/_vendor/github.com/docker/distribution/digest/digester.go
generated
Normal file
155
staging/src/k8s.io/client-go/1.4/_vendor/github.com/docker/distribution/digest/digester.go
generated
Normal file
@@ -0,0 +1,155 @@
|
|||||||
|
package digest
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto"
|
||||||
|
"fmt"
|
||||||
|
"hash"
|
||||||
|
"io"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Algorithm identifies and implementation of a digester by an identifier.
|
||||||
|
// Note the that this defines both the hash algorithm used and the string
|
||||||
|
// encoding.
|
||||||
|
type Algorithm string
|
||||||
|
|
||||||
|
// supported digest types
|
||||||
|
const (
|
||||||
|
SHA256 Algorithm = "sha256" // sha256 with hex encoding
|
||||||
|
SHA384 Algorithm = "sha384" // sha384 with hex encoding
|
||||||
|
SHA512 Algorithm = "sha512" // sha512 with hex encoding
|
||||||
|
|
||||||
|
// Canonical is the primary digest algorithm used with the distribution
|
||||||
|
// project. Other digests may be used but this one is the primary storage
|
||||||
|
// digest.
|
||||||
|
Canonical = SHA256
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
// TODO(stevvooe): Follow the pattern of the standard crypto package for
|
||||||
|
// registration of digests. Effectively, we are a registerable set and
|
||||||
|
// common symbol access.
|
||||||
|
|
||||||
|
// algorithms maps values to hash.Hash implementations. Other algorithms
|
||||||
|
// may be available but they cannot be calculated by the digest package.
|
||||||
|
algorithms = map[Algorithm]crypto.Hash{
|
||||||
|
SHA256: crypto.SHA256,
|
||||||
|
SHA384: crypto.SHA384,
|
||||||
|
SHA512: crypto.SHA512,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
// Available returns true if the digest type is available for use. If this
|
||||||
|
// returns false, New and Hash will return nil.
|
||||||
|
func (a Algorithm) Available() bool {
|
||||||
|
h, ok := algorithms[a]
|
||||||
|
if !ok {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// check availability of the hash, as well
|
||||||
|
return h.Available()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a Algorithm) String() string {
|
||||||
|
return string(a)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Size returns number of bytes returned by the hash.
|
||||||
|
func (a Algorithm) Size() int {
|
||||||
|
h, ok := algorithms[a]
|
||||||
|
if !ok {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
return h.Size()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set implemented to allow use of Algorithm as a command line flag.
|
||||||
|
func (a *Algorithm) Set(value string) error {
|
||||||
|
if value == "" {
|
||||||
|
*a = Canonical
|
||||||
|
} else {
|
||||||
|
// just do a type conversion, support is queried with Available.
|
||||||
|
*a = Algorithm(value)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// New returns a new digester for the specified algorithm. If the algorithm
|
||||||
|
// does not have a digester implementation, nil will be returned. This can be
|
||||||
|
// checked by calling Available before calling New.
|
||||||
|
func (a Algorithm) New() Digester {
|
||||||
|
return &digester{
|
||||||
|
alg: a,
|
||||||
|
hash: a.Hash(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Hash returns a new hash as used by the algorithm. If not available, the
|
||||||
|
// method will panic. Check Algorithm.Available() before calling.
|
||||||
|
func (a Algorithm) Hash() hash.Hash {
|
||||||
|
if !a.Available() {
|
||||||
|
// NOTE(stevvooe): A missing hash is usually a programming error that
|
||||||
|
// must be resolved at compile time. We don't import in the digest
|
||||||
|
// package to allow users to choose their hash implementation (such as
|
||||||
|
// when using stevvooe/resumable or a hardware accelerated package).
|
||||||
|
//
|
||||||
|
// Applications that may want to resolve the hash at runtime should
|
||||||
|
// call Algorithm.Available before call Algorithm.Hash().
|
||||||
|
panic(fmt.Sprintf("%v not available (make sure it is imported)", a))
|
||||||
|
}
|
||||||
|
|
||||||
|
return algorithms[a].New()
|
||||||
|
}
|
||||||
|
|
||||||
|
// FromReader returns the digest of the reader using the algorithm.
|
||||||
|
func (a Algorithm) FromReader(rd io.Reader) (Digest, error) {
|
||||||
|
digester := a.New()
|
||||||
|
|
||||||
|
if _, err := io.Copy(digester.Hash(), rd); err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
return digester.Digest(), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// FromBytes digests the input and returns a Digest.
|
||||||
|
func (a Algorithm) FromBytes(p []byte) Digest {
|
||||||
|
digester := a.New()
|
||||||
|
|
||||||
|
if _, err := digester.Hash().Write(p); err != nil {
|
||||||
|
// Writes to a Hash should never fail. None of the existing
|
||||||
|
// hash implementations in the stdlib or hashes vendored
|
||||||
|
// here can return errors from Write. Having a panic in this
|
||||||
|
// condition instead of having FromBytes return an error value
|
||||||
|
// avoids unnecessary error handling paths in all callers.
|
||||||
|
panic("write to hash function returned error: " + err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
return digester.Digest()
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO(stevvooe): Allow resolution of verifiers using the digest type and
|
||||||
|
// this registration system.
|
||||||
|
|
||||||
|
// Digester calculates the digest of written data. Writes should go directly
|
||||||
|
// to the return value of Hash, while calling Digest will return the current
|
||||||
|
// value of the digest.
|
||||||
|
type Digester interface {
|
||||||
|
Hash() hash.Hash // provides direct access to underlying hash instance.
|
||||||
|
Digest() Digest
|
||||||
|
}
|
||||||
|
|
||||||
|
// digester provides a simple digester definition that embeds a hasher.
|
||||||
|
type digester struct {
|
||||||
|
alg Algorithm
|
||||||
|
hash hash.Hash
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *digester) Hash() hash.Hash {
|
||||||
|
return d.hash
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *digester) Digest() Digest {
|
||||||
|
return NewDigest(d.alg, d.hash)
|
||||||
|
}
|
||||||
42
staging/src/k8s.io/client-go/1.4/_vendor/github.com/docker/distribution/digest/doc.go
generated
Normal file
42
staging/src/k8s.io/client-go/1.4/_vendor/github.com/docker/distribution/digest/doc.go
generated
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
// Package digest provides a generalized type to opaquely represent message
|
||||||
|
// digests and their operations within the registry. The Digest type is
|
||||||
|
// designed to serve as a flexible identifier in a content-addressable system.
|
||||||
|
// More importantly, it provides tools and wrappers to work with
|
||||||
|
// hash.Hash-based digests with little effort.
|
||||||
|
//
|
||||||
|
// Basics
|
||||||
|
//
|
||||||
|
// The format of a digest is simply a string with two parts, dubbed the
|
||||||
|
// "algorithm" and the "digest", separated by a colon:
|
||||||
|
//
|
||||||
|
// <algorithm>:<digest>
|
||||||
|
//
|
||||||
|
// An example of a sha256 digest representation follows:
|
||||||
|
//
|
||||||
|
// sha256:7173b809ca12ec5dee4506cd86be934c4596dd234ee82c0662eac04a8c2c71dc
|
||||||
|
//
|
||||||
|
// In this case, the string "sha256" is the algorithm and the hex bytes are
|
||||||
|
// the "digest".
|
||||||
|
//
|
||||||
|
// Because the Digest type is simply a string, once a valid Digest is
|
||||||
|
// obtained, comparisons are cheap, quick and simple to express with the
|
||||||
|
// standard equality operator.
|
||||||
|
//
|
||||||
|
// Verification
|
||||||
|
//
|
||||||
|
// The main benefit of using the Digest type is simple verification against a
|
||||||
|
// given digest. The Verifier interface, modeled after the stdlib hash.Hash
|
||||||
|
// interface, provides a common write sink for digest verification. After
|
||||||
|
// writing is complete, calling the Verifier.Verified method will indicate
|
||||||
|
// whether or not the stream of bytes matches the target digest.
|
||||||
|
//
|
||||||
|
// Missing Features
|
||||||
|
//
|
||||||
|
// In addition to the above, we intend to add the following features to this
|
||||||
|
// package:
|
||||||
|
//
|
||||||
|
// 1. A Digester type that supports write sink digest calculation.
|
||||||
|
//
|
||||||
|
// 2. Suspend and resume of ongoing digest calculations to support efficient digest verification in the registry.
|
||||||
|
//
|
||||||
|
package digest
|
||||||
245
staging/src/k8s.io/client-go/1.4/_vendor/github.com/docker/distribution/digest/set.go
generated
Normal file
245
staging/src/k8s.io/client-go/1.4/_vendor/github.com/docker/distribution/digest/set.go
generated
Normal file
@@ -0,0 +1,245 @@
|
|||||||
|
package digest
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"sort"
|
||||||
|
"strings"
|
||||||
|
"sync"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
// ErrDigestNotFound is used when a matching digest
|
||||||
|
// could not be found in a set.
|
||||||
|
ErrDigestNotFound = errors.New("digest not found")
|
||||||
|
|
||||||
|
// ErrDigestAmbiguous is used when multiple digests
|
||||||
|
// are found in a set. None of the matching digests
|
||||||
|
// should be considered valid matches.
|
||||||
|
ErrDigestAmbiguous = errors.New("ambiguous digest string")
|
||||||
|
)
|
||||||
|
|
||||||
|
// Set is used to hold a unique set of digests which
|
||||||
|
// may be easily referenced by easily referenced by a string
|
||||||
|
// representation of the digest as well as short representation.
|
||||||
|
// The uniqueness of the short representation is based on other
|
||||||
|
// digests in the set. If digests are omitted from this set,
|
||||||
|
// collisions in a larger set may not be detected, therefore it
|
||||||
|
// is important to always do short representation lookups on
|
||||||
|
// the complete set of digests. To mitigate collisions, an
|
||||||
|
// appropriately long short code should be used.
|
||||||
|
type Set struct {
|
||||||
|
mutex sync.RWMutex
|
||||||
|
entries digestEntries
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewSet creates an empty set of digests
|
||||||
|
// which may have digests added.
|
||||||
|
func NewSet() *Set {
|
||||||
|
return &Set{
|
||||||
|
entries: digestEntries{},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// checkShortMatch checks whether two digests match as either whole
|
||||||
|
// values or short values. This function does not test equality,
|
||||||
|
// rather whether the second value could match against the first
|
||||||
|
// value.
|
||||||
|
func checkShortMatch(alg Algorithm, hex, shortAlg, shortHex string) bool {
|
||||||
|
if len(hex) == len(shortHex) {
|
||||||
|
if hex != shortHex {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if len(shortAlg) > 0 && string(alg) != shortAlg {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
} else if !strings.HasPrefix(hex, shortHex) {
|
||||||
|
return false
|
||||||
|
} else if len(shortAlg) > 0 && string(alg) != shortAlg {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// Lookup looks for a digest matching the given string representation.
|
||||||
|
// If no digests could be found ErrDigestNotFound will be returned
|
||||||
|
// with an empty digest value. If multiple matches are found
|
||||||
|
// ErrDigestAmbiguous will be returned with an empty digest value.
|
||||||
|
func (dst *Set) Lookup(d string) (Digest, error) {
|
||||||
|
dst.mutex.RLock()
|
||||||
|
defer dst.mutex.RUnlock()
|
||||||
|
if len(dst.entries) == 0 {
|
||||||
|
return "", ErrDigestNotFound
|
||||||
|
}
|
||||||
|
var (
|
||||||
|
searchFunc func(int) bool
|
||||||
|
alg Algorithm
|
||||||
|
hex string
|
||||||
|
)
|
||||||
|
dgst, err := ParseDigest(d)
|
||||||
|
if err == ErrDigestInvalidFormat {
|
||||||
|
hex = d
|
||||||
|
searchFunc = func(i int) bool {
|
||||||
|
return dst.entries[i].val >= d
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
hex = dgst.Hex()
|
||||||
|
alg = dgst.Algorithm()
|
||||||
|
searchFunc = func(i int) bool {
|
||||||
|
if dst.entries[i].val == hex {
|
||||||
|
return dst.entries[i].alg >= alg
|
||||||
|
}
|
||||||
|
return dst.entries[i].val >= hex
|
||||||
|
}
|
||||||
|
}
|
||||||
|
idx := sort.Search(len(dst.entries), searchFunc)
|
||||||
|
if idx == len(dst.entries) || !checkShortMatch(dst.entries[idx].alg, dst.entries[idx].val, string(alg), hex) {
|
||||||
|
return "", ErrDigestNotFound
|
||||||
|
}
|
||||||
|
if dst.entries[idx].alg == alg && dst.entries[idx].val == hex {
|
||||||
|
return dst.entries[idx].digest, nil
|
||||||
|
}
|
||||||
|
if idx+1 < len(dst.entries) && checkShortMatch(dst.entries[idx+1].alg, dst.entries[idx+1].val, string(alg), hex) {
|
||||||
|
return "", ErrDigestAmbiguous
|
||||||
|
}
|
||||||
|
|
||||||
|
return dst.entries[idx].digest, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add adds the given digest to the set. An error will be returned
|
||||||
|
// if the given digest is invalid. If the digest already exists in the
|
||||||
|
// set, this operation will be a no-op.
|
||||||
|
func (dst *Set) Add(d Digest) error {
|
||||||
|
if err := d.Validate(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
dst.mutex.Lock()
|
||||||
|
defer dst.mutex.Unlock()
|
||||||
|
entry := &digestEntry{alg: d.Algorithm(), val: d.Hex(), digest: d}
|
||||||
|
searchFunc := func(i int) bool {
|
||||||
|
if dst.entries[i].val == entry.val {
|
||||||
|
return dst.entries[i].alg >= entry.alg
|
||||||
|
}
|
||||||
|
return dst.entries[i].val >= entry.val
|
||||||
|
}
|
||||||
|
idx := sort.Search(len(dst.entries), searchFunc)
|
||||||
|
if idx == len(dst.entries) {
|
||||||
|
dst.entries = append(dst.entries, entry)
|
||||||
|
return nil
|
||||||
|
} else if dst.entries[idx].digest == d {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
entries := append(dst.entries, nil)
|
||||||
|
copy(entries[idx+1:], entries[idx:len(entries)-1])
|
||||||
|
entries[idx] = entry
|
||||||
|
dst.entries = entries
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove removes the given digest from the set. An err will be
|
||||||
|
// returned if the given digest is invalid. If the digest does
|
||||||
|
// not exist in the set, this operation will be a no-op.
|
||||||
|
func (dst *Set) Remove(d Digest) error {
|
||||||
|
if err := d.Validate(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
dst.mutex.Lock()
|
||||||
|
defer dst.mutex.Unlock()
|
||||||
|
entry := &digestEntry{alg: d.Algorithm(), val: d.Hex(), digest: d}
|
||||||
|
searchFunc := func(i int) bool {
|
||||||
|
if dst.entries[i].val == entry.val {
|
||||||
|
return dst.entries[i].alg >= entry.alg
|
||||||
|
}
|
||||||
|
return dst.entries[i].val >= entry.val
|
||||||
|
}
|
||||||
|
idx := sort.Search(len(dst.entries), searchFunc)
|
||||||
|
// Not found if idx is after or value at idx is not digest
|
||||||
|
if idx == len(dst.entries) || dst.entries[idx].digest != d {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
entries := dst.entries
|
||||||
|
copy(entries[idx:], entries[idx+1:])
|
||||||
|
entries = entries[:len(entries)-1]
|
||||||
|
dst.entries = entries
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// All returns all the digests in the set
|
||||||
|
func (dst *Set) All() []Digest {
|
||||||
|
dst.mutex.RLock()
|
||||||
|
defer dst.mutex.RUnlock()
|
||||||
|
retValues := make([]Digest, len(dst.entries))
|
||||||
|
for i := range dst.entries {
|
||||||
|
retValues[i] = dst.entries[i].digest
|
||||||
|
}
|
||||||
|
|
||||||
|
return retValues
|
||||||
|
}
|
||||||
|
|
||||||
|
// ShortCodeTable returns a map of Digest to unique short codes. The
|
||||||
|
// length represents the minimum value, the maximum length may be the
|
||||||
|
// entire value of digest if uniqueness cannot be achieved without the
|
||||||
|
// full value. This function will attempt to make short codes as short
|
||||||
|
// as possible to be unique.
|
||||||
|
func ShortCodeTable(dst *Set, length int) map[Digest]string {
|
||||||
|
dst.mutex.RLock()
|
||||||
|
defer dst.mutex.RUnlock()
|
||||||
|
m := make(map[Digest]string, len(dst.entries))
|
||||||
|
l := length
|
||||||
|
resetIdx := 0
|
||||||
|
for i := 0; i < len(dst.entries); i++ {
|
||||||
|
var short string
|
||||||
|
extended := true
|
||||||
|
for extended {
|
||||||
|
extended = false
|
||||||
|
if len(dst.entries[i].val) <= l {
|
||||||
|
short = dst.entries[i].digest.String()
|
||||||
|
} else {
|
||||||
|
short = dst.entries[i].val[:l]
|
||||||
|
for j := i + 1; j < len(dst.entries); j++ {
|
||||||
|
if checkShortMatch(dst.entries[j].alg, dst.entries[j].val, "", short) {
|
||||||
|
if j > resetIdx {
|
||||||
|
resetIdx = j
|
||||||
|
}
|
||||||
|
extended = true
|
||||||
|
} else {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if extended {
|
||||||
|
l++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
m[dst.entries[i].digest] = short
|
||||||
|
if i >= resetIdx {
|
||||||
|
l = length
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return m
|
||||||
|
}
|
||||||
|
|
||||||
|
type digestEntry struct {
|
||||||
|
alg Algorithm
|
||||||
|
val string
|
||||||
|
digest Digest
|
||||||
|
}
|
||||||
|
|
||||||
|
type digestEntries []*digestEntry
|
||||||
|
|
||||||
|
func (d digestEntries) Len() int {
|
||||||
|
return len(d)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d digestEntries) Less(i, j int) bool {
|
||||||
|
if d[i].val != d[j].val {
|
||||||
|
return d[i].val < d[j].val
|
||||||
|
}
|
||||||
|
return d[i].alg < d[j].alg
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d digestEntries) Swap(i, j int) {
|
||||||
|
d[i], d[j] = d[j], d[i]
|
||||||
|
}
|
||||||
44
staging/src/k8s.io/client-go/1.4/_vendor/github.com/docker/distribution/digest/verifiers.go
generated
Normal file
44
staging/src/k8s.io/client-go/1.4/_vendor/github.com/docker/distribution/digest/verifiers.go
generated
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
package digest
|
||||||
|
|
||||||
|
import (
|
||||||
|
"hash"
|
||||||
|
"io"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Verifier presents a general verification interface to be used with message
|
||||||
|
// digests and other byte stream verifications. Users instantiate a Verifier
|
||||||
|
// from one of the various methods, write the data under test to it then check
|
||||||
|
// the result with the Verified method.
|
||||||
|
type Verifier interface {
|
||||||
|
io.Writer
|
||||||
|
|
||||||
|
// Verified will return true if the content written to Verifier matches
|
||||||
|
// the digest.
|
||||||
|
Verified() bool
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewDigestVerifier returns a verifier that compares the written bytes
|
||||||
|
// against a passed in digest.
|
||||||
|
func NewDigestVerifier(d Digest) (Verifier, error) {
|
||||||
|
if err := d.Validate(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return hashVerifier{
|
||||||
|
hash: d.Algorithm().Hash(),
|
||||||
|
digest: d,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type hashVerifier struct {
|
||||||
|
digest Digest
|
||||||
|
hash hash.Hash
|
||||||
|
}
|
||||||
|
|
||||||
|
func (hv hashVerifier) Write(p []byte) (n int, err error) {
|
||||||
|
return hv.hash.Write(p)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (hv hashVerifier) Verified() bool {
|
||||||
|
return hv.digest == NewDigest(hv.digest.Algorithm(), hv.hash)
|
||||||
|
}
|
||||||
334
staging/src/k8s.io/client-go/1.4/_vendor/github.com/docker/distribution/reference/reference.go
generated
Normal file
334
staging/src/k8s.io/client-go/1.4/_vendor/github.com/docker/distribution/reference/reference.go
generated
Normal file
@@ -0,0 +1,334 @@
|
|||||||
|
// Package reference provides a general type to represent any way of referencing images within the registry.
|
||||||
|
// Its main purpose is to abstract tags and digests (content-addressable hash).
|
||||||
|
//
|
||||||
|
// Grammar
|
||||||
|
//
|
||||||
|
// reference := name [ ":" tag ] [ "@" digest ]
|
||||||
|
// name := [hostname '/'] component ['/' component]*
|
||||||
|
// hostname := hostcomponent ['.' hostcomponent]* [':' port-number]
|
||||||
|
// hostcomponent := /([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9])/
|
||||||
|
// port-number := /[0-9]+/
|
||||||
|
// component := alpha-numeric [separator alpha-numeric]*
|
||||||
|
// alpha-numeric := /[a-z0-9]+/
|
||||||
|
// separator := /[_.]|__|[-]*/
|
||||||
|
//
|
||||||
|
// tag := /[\w][\w.-]{0,127}/
|
||||||
|
//
|
||||||
|
// digest := digest-algorithm ":" digest-hex
|
||||||
|
// digest-algorithm := digest-algorithm-component [ digest-algorithm-separator digest-algorithm-component ]
|
||||||
|
// digest-algorithm-separator := /[+.-_]/
|
||||||
|
// digest-algorithm-component := /[A-Za-z][A-Za-z0-9]*/
|
||||||
|
// digest-hex := /[0-9a-fA-F]{32,}/ ; At least 128 bit digest value
|
||||||
|
package reference
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/docker/distribution/digest"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
// NameTotalLengthMax is the maximum total number of characters in a repository name.
|
||||||
|
NameTotalLengthMax = 255
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
// ErrReferenceInvalidFormat represents an error while trying to parse a string as a reference.
|
||||||
|
ErrReferenceInvalidFormat = errors.New("invalid reference format")
|
||||||
|
|
||||||
|
// ErrTagInvalidFormat represents an error while trying to parse a string as a tag.
|
||||||
|
ErrTagInvalidFormat = errors.New("invalid tag format")
|
||||||
|
|
||||||
|
// ErrDigestInvalidFormat represents an error while trying to parse a string as a tag.
|
||||||
|
ErrDigestInvalidFormat = errors.New("invalid digest format")
|
||||||
|
|
||||||
|
// ErrNameEmpty is returned for empty, invalid repository names.
|
||||||
|
ErrNameEmpty = errors.New("repository name must have at least one component")
|
||||||
|
|
||||||
|
// ErrNameTooLong is returned when a repository name is longer than NameTotalLengthMax.
|
||||||
|
ErrNameTooLong = fmt.Errorf("repository name must not be more than %v characters", NameTotalLengthMax)
|
||||||
|
)
|
||||||
|
|
||||||
|
// Reference is an opaque object reference identifier that may include
|
||||||
|
// modifiers such as a hostname, name, tag, and digest.
|
||||||
|
type Reference interface {
|
||||||
|
// String returns the full reference
|
||||||
|
String() string
|
||||||
|
}
|
||||||
|
|
||||||
|
// Field provides a wrapper type for resolving correct reference types when
|
||||||
|
// working with encoding.
|
||||||
|
type Field struct {
|
||||||
|
reference Reference
|
||||||
|
}
|
||||||
|
|
||||||
|
// AsField wraps a reference in a Field for encoding.
|
||||||
|
func AsField(reference Reference) Field {
|
||||||
|
return Field{reference}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reference unwraps the reference type from the field to
|
||||||
|
// return the Reference object. This object should be
|
||||||
|
// of the appropriate type to further check for different
|
||||||
|
// reference types.
|
||||||
|
func (f Field) Reference() Reference {
|
||||||
|
return f.reference
|
||||||
|
}
|
||||||
|
|
||||||
|
// MarshalText serializes the field to byte text which
|
||||||
|
// is the string of the reference.
|
||||||
|
func (f Field) MarshalText() (p []byte, err error) {
|
||||||
|
return []byte(f.reference.String()), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalText parses text bytes by invoking the
|
||||||
|
// reference parser to ensure the appropriately
|
||||||
|
// typed reference object is wrapped by field.
|
||||||
|
func (f *Field) UnmarshalText(p []byte) error {
|
||||||
|
r, err := Parse(string(p))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
f.reference = r
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Named is an object with a full name
|
||||||
|
type Named interface {
|
||||||
|
Reference
|
||||||
|
Name() string
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tagged is an object which has a tag
|
||||||
|
type Tagged interface {
|
||||||
|
Reference
|
||||||
|
Tag() string
|
||||||
|
}
|
||||||
|
|
||||||
|
// NamedTagged is an object including a name and tag.
|
||||||
|
type NamedTagged interface {
|
||||||
|
Named
|
||||||
|
Tag() string
|
||||||
|
}
|
||||||
|
|
||||||
|
// Digested is an object which has a digest
|
||||||
|
// in which it can be referenced by
|
||||||
|
type Digested interface {
|
||||||
|
Reference
|
||||||
|
Digest() digest.Digest
|
||||||
|
}
|
||||||
|
|
||||||
|
// Canonical reference is an object with a fully unique
|
||||||
|
// name including a name with hostname and digest
|
||||||
|
type Canonical interface {
|
||||||
|
Named
|
||||||
|
Digest() digest.Digest
|
||||||
|
}
|
||||||
|
|
||||||
|
// SplitHostname splits a named reference into a
|
||||||
|
// hostname and name string. If no valid hostname is
|
||||||
|
// found, the hostname is empty and the full value
|
||||||
|
// is returned as name
|
||||||
|
func SplitHostname(named Named) (string, string) {
|
||||||
|
name := named.Name()
|
||||||
|
match := anchoredNameRegexp.FindStringSubmatch(name)
|
||||||
|
if match == nil || len(match) != 3 {
|
||||||
|
return "", name
|
||||||
|
}
|
||||||
|
return match[1], match[2]
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parse parses s and returns a syntactically valid Reference.
|
||||||
|
// If an error was encountered it is returned, along with a nil Reference.
|
||||||
|
// NOTE: Parse will not handle short digests.
|
||||||
|
func Parse(s string) (Reference, error) {
|
||||||
|
matches := ReferenceRegexp.FindStringSubmatch(s)
|
||||||
|
if matches == nil {
|
||||||
|
if s == "" {
|
||||||
|
return nil, ErrNameEmpty
|
||||||
|
}
|
||||||
|
// TODO(dmcgowan): Provide more specific and helpful error
|
||||||
|
return nil, ErrReferenceInvalidFormat
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(matches[1]) > NameTotalLengthMax {
|
||||||
|
return nil, ErrNameTooLong
|
||||||
|
}
|
||||||
|
|
||||||
|
ref := reference{
|
||||||
|
name: matches[1],
|
||||||
|
tag: matches[2],
|
||||||
|
}
|
||||||
|
if matches[3] != "" {
|
||||||
|
var err error
|
||||||
|
ref.digest, err = digest.ParseDigest(matches[3])
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
r := getBestReferenceType(ref)
|
||||||
|
if r == nil {
|
||||||
|
return nil, ErrNameEmpty
|
||||||
|
}
|
||||||
|
|
||||||
|
return r, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ParseNamed parses s and returns a syntactically valid reference implementing
|
||||||
|
// the Named interface. The reference must have a name, otherwise an error is
|
||||||
|
// returned.
|
||||||
|
// If an error was encountered it is returned, along with a nil Reference.
|
||||||
|
// NOTE: ParseNamed will not handle short digests.
|
||||||
|
func ParseNamed(s string) (Named, error) {
|
||||||
|
ref, err := Parse(s)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
named, isNamed := ref.(Named)
|
||||||
|
if !isNamed {
|
||||||
|
return nil, fmt.Errorf("reference %s has no name", ref.String())
|
||||||
|
}
|
||||||
|
return named, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithName returns a named object representing the given string. If the input
|
||||||
|
// is invalid ErrReferenceInvalidFormat will be returned.
|
||||||
|
func WithName(name string) (Named, error) {
|
||||||
|
if len(name) > NameTotalLengthMax {
|
||||||
|
return nil, ErrNameTooLong
|
||||||
|
}
|
||||||
|
if !anchoredNameRegexp.MatchString(name) {
|
||||||
|
return nil, ErrReferenceInvalidFormat
|
||||||
|
}
|
||||||
|
return repository(name), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithTag combines the name from "name" and the tag from "tag" to form a
|
||||||
|
// reference incorporating both the name and the tag.
|
||||||
|
func WithTag(name Named, tag string) (NamedTagged, error) {
|
||||||
|
if !anchoredTagRegexp.MatchString(tag) {
|
||||||
|
return nil, ErrTagInvalidFormat
|
||||||
|
}
|
||||||
|
return taggedReference{
|
||||||
|
name: name.Name(),
|
||||||
|
tag: tag,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithDigest combines the name from "name" and the digest from "digest" to form
|
||||||
|
// a reference incorporating both the name and the digest.
|
||||||
|
func WithDigest(name Named, digest digest.Digest) (Canonical, error) {
|
||||||
|
if !anchoredDigestRegexp.MatchString(digest.String()) {
|
||||||
|
return nil, ErrDigestInvalidFormat
|
||||||
|
}
|
||||||
|
return canonicalReference{
|
||||||
|
name: name.Name(),
|
||||||
|
digest: digest,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func getBestReferenceType(ref reference) Reference {
|
||||||
|
if ref.name == "" {
|
||||||
|
// Allow digest only references
|
||||||
|
if ref.digest != "" {
|
||||||
|
return digestReference(ref.digest)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
if ref.tag == "" {
|
||||||
|
if ref.digest != "" {
|
||||||
|
return canonicalReference{
|
||||||
|
name: ref.name,
|
||||||
|
digest: ref.digest,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return repository(ref.name)
|
||||||
|
}
|
||||||
|
if ref.digest == "" {
|
||||||
|
return taggedReference{
|
||||||
|
name: ref.name,
|
||||||
|
tag: ref.tag,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ref
|
||||||
|
}
|
||||||
|
|
||||||
|
type reference struct {
|
||||||
|
name string
|
||||||
|
tag string
|
||||||
|
digest digest.Digest
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r reference) String() string {
|
||||||
|
return r.name + ":" + r.tag + "@" + r.digest.String()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r reference) Name() string {
|
||||||
|
return r.name
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r reference) Tag() string {
|
||||||
|
return r.tag
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r reference) Digest() digest.Digest {
|
||||||
|
return r.digest
|
||||||
|
}
|
||||||
|
|
||||||
|
type repository string
|
||||||
|
|
||||||
|
func (r repository) String() string {
|
||||||
|
return string(r)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r repository) Name() string {
|
||||||
|
return string(r)
|
||||||
|
}
|
||||||
|
|
||||||
|
type digestReference digest.Digest
|
||||||
|
|
||||||
|
func (d digestReference) String() string {
|
||||||
|
return d.String()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d digestReference) Digest() digest.Digest {
|
||||||
|
return digest.Digest(d)
|
||||||
|
}
|
||||||
|
|
||||||
|
type taggedReference struct {
|
||||||
|
name string
|
||||||
|
tag string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t taggedReference) String() string {
|
||||||
|
return t.name + ":" + t.tag
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t taggedReference) Name() string {
|
||||||
|
return t.name
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t taggedReference) Tag() string {
|
||||||
|
return t.tag
|
||||||
|
}
|
||||||
|
|
||||||
|
type canonicalReference struct {
|
||||||
|
name string
|
||||||
|
digest digest.Digest
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c canonicalReference) String() string {
|
||||||
|
return c.name + "@" + c.digest.String()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c canonicalReference) Name() string {
|
||||||
|
return c.name
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c canonicalReference) Digest() digest.Digest {
|
||||||
|
return c.digest
|
||||||
|
}
|
||||||
124
staging/src/k8s.io/client-go/1.4/_vendor/github.com/docker/distribution/reference/regexp.go
generated
Normal file
124
staging/src/k8s.io/client-go/1.4/_vendor/github.com/docker/distribution/reference/regexp.go
generated
Normal file
@@ -0,0 +1,124 @@
|
|||||||
|
package reference
|
||||||
|
|
||||||
|
import "regexp"
|
||||||
|
|
||||||
|
var (
|
||||||
|
// alphaNumericRegexp defines the alpha numeric atom, typically a
|
||||||
|
// component of names. This only allows lower case characters and digits.
|
||||||
|
alphaNumericRegexp = match(`[a-z0-9]+`)
|
||||||
|
|
||||||
|
// separatorRegexp defines the separators allowed to be embedded in name
|
||||||
|
// components. This allow one period, one or two underscore and multiple
|
||||||
|
// dashes.
|
||||||
|
separatorRegexp = match(`(?:[._]|__|[-]*)`)
|
||||||
|
|
||||||
|
// nameComponentRegexp restricts registry path component names to start
|
||||||
|
// with at least one letter or number, with following parts able to be
|
||||||
|
// separated by one period, one or two underscore and multiple dashes.
|
||||||
|
nameComponentRegexp = expression(
|
||||||
|
alphaNumericRegexp,
|
||||||
|
optional(repeated(separatorRegexp, alphaNumericRegexp)))
|
||||||
|
|
||||||
|
// hostnameComponentRegexp restricts the registry hostname component of a
|
||||||
|
// repository name to start with a component as defined by hostnameRegexp
|
||||||
|
// and followed by an optional port.
|
||||||
|
hostnameComponentRegexp = match(`(?:[a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9])`)
|
||||||
|
|
||||||
|
// hostnameRegexp defines the structure of potential hostname components
|
||||||
|
// that may be part of image names. This is purposely a subset of what is
|
||||||
|
// allowed by DNS to ensure backwards compatibility with Docker image
|
||||||
|
// names.
|
||||||
|
hostnameRegexp = expression(
|
||||||
|
hostnameComponentRegexp,
|
||||||
|
optional(repeated(literal(`.`), hostnameComponentRegexp)),
|
||||||
|
optional(literal(`:`), match(`[0-9]+`)))
|
||||||
|
|
||||||
|
// TagRegexp matches valid tag names. From docker/docker:graph/tags.go.
|
||||||
|
TagRegexp = match(`[\w][\w.-]{0,127}`)
|
||||||
|
|
||||||
|
// anchoredTagRegexp matches valid tag names, anchored at the start and
|
||||||
|
// end of the matched string.
|
||||||
|
anchoredTagRegexp = anchored(TagRegexp)
|
||||||
|
|
||||||
|
// DigestRegexp matches valid digests.
|
||||||
|
DigestRegexp = match(`[A-Za-z][A-Za-z0-9]*(?:[-_+.][A-Za-z][A-Za-z0-9]*)*[:][[:xdigit:]]{32,}`)
|
||||||
|
|
||||||
|
// anchoredDigestRegexp matches valid digests, anchored at the start and
|
||||||
|
// end of the matched string.
|
||||||
|
anchoredDigestRegexp = anchored(DigestRegexp)
|
||||||
|
|
||||||
|
// NameRegexp is the format for the name component of references. The
|
||||||
|
// regexp has capturing groups for the hostname and name part omitting
|
||||||
|
// the separating forward slash from either.
|
||||||
|
NameRegexp = expression(
|
||||||
|
optional(hostnameRegexp, literal(`/`)),
|
||||||
|
nameComponentRegexp,
|
||||||
|
optional(repeated(literal(`/`), nameComponentRegexp)))
|
||||||
|
|
||||||
|
// anchoredNameRegexp is used to parse a name value, capturing the
|
||||||
|
// hostname and trailing components.
|
||||||
|
anchoredNameRegexp = anchored(
|
||||||
|
optional(capture(hostnameRegexp), literal(`/`)),
|
||||||
|
capture(nameComponentRegexp,
|
||||||
|
optional(repeated(literal(`/`), nameComponentRegexp))))
|
||||||
|
|
||||||
|
// ReferenceRegexp is the full supported format of a reference. The regexp
|
||||||
|
// is anchored and has capturing groups for name, tag, and digest
|
||||||
|
// components.
|
||||||
|
ReferenceRegexp = anchored(capture(NameRegexp),
|
||||||
|
optional(literal(":"), capture(TagRegexp)),
|
||||||
|
optional(literal("@"), capture(DigestRegexp)))
|
||||||
|
)
|
||||||
|
|
||||||
|
// match compiles the string to a regular expression.
|
||||||
|
var match = regexp.MustCompile
|
||||||
|
|
||||||
|
// literal compiles s into a literal regular expression, escaping any regexp
|
||||||
|
// reserved characters.
|
||||||
|
func literal(s string) *regexp.Regexp {
|
||||||
|
re := match(regexp.QuoteMeta(s))
|
||||||
|
|
||||||
|
if _, complete := re.LiteralPrefix(); !complete {
|
||||||
|
panic("must be a literal")
|
||||||
|
}
|
||||||
|
|
||||||
|
return re
|
||||||
|
}
|
||||||
|
|
||||||
|
// expression defines a full expression, where each regular expression must
|
||||||
|
// follow the previous.
|
||||||
|
func expression(res ...*regexp.Regexp) *regexp.Regexp {
|
||||||
|
var s string
|
||||||
|
for _, re := range res {
|
||||||
|
s += re.String()
|
||||||
|
}
|
||||||
|
|
||||||
|
return match(s)
|
||||||
|
}
|
||||||
|
|
||||||
|
// optional wraps the expression in a non-capturing group and makes the
|
||||||
|
// production optional.
|
||||||
|
func optional(res ...*regexp.Regexp) *regexp.Regexp {
|
||||||
|
return match(group(expression(res...)).String() + `?`)
|
||||||
|
}
|
||||||
|
|
||||||
|
// repeated wraps the regexp in a non-capturing group to get one or more
|
||||||
|
// matches.
|
||||||
|
func repeated(res ...*regexp.Regexp) *regexp.Regexp {
|
||||||
|
return match(group(expression(res...)).String() + `+`)
|
||||||
|
}
|
||||||
|
|
||||||
|
// group wraps the regexp in a non-capturing group.
|
||||||
|
func group(res ...*regexp.Regexp) *regexp.Regexp {
|
||||||
|
return match(`(?:` + expression(res...).String() + `)`)
|
||||||
|
}
|
||||||
|
|
||||||
|
// capture wraps the expression in a capturing group.
|
||||||
|
func capture(res ...*regexp.Regexp) *regexp.Regexp {
|
||||||
|
return match(`(` + expression(res...).String() + `)`)
|
||||||
|
}
|
||||||
|
|
||||||
|
// anchored anchors the regular expression by adding start and end delimiters.
|
||||||
|
func anchored(res ...*regexp.Regexp) *regexp.Regexp {
|
||||||
|
return match(`^` + expression(res...).String() + `$`)
|
||||||
|
}
|
||||||
70
staging/src/k8s.io/client-go/1.4/_vendor/github.com/emicklei/go-restful/.gitignore
generated
vendored
Normal file
70
staging/src/k8s.io/client-go/1.4/_vendor/github.com/emicklei/go-restful/.gitignore
generated
vendored
Normal file
@@ -0,0 +1,70 @@
|
|||||||
|
# Compiled Object files, Static and Dynamic libs (Shared Objects)
|
||||||
|
*.o
|
||||||
|
*.a
|
||||||
|
*.so
|
||||||
|
|
||||||
|
# Folders
|
||||||
|
_obj
|
||||||
|
_test
|
||||||
|
|
||||||
|
# Architecture specific extensions/prefixes
|
||||||
|
*.[568vq]
|
||||||
|
[568vq].out
|
||||||
|
|
||||||
|
*.cgo1.go
|
||||||
|
*.cgo2.c
|
||||||
|
_cgo_defun.c
|
||||||
|
_cgo_gotypes.go
|
||||||
|
_cgo_export.*
|
||||||
|
|
||||||
|
_testmain.go
|
||||||
|
|
||||||
|
*.exe
|
||||||
|
|
||||||
|
restful.html
|
||||||
|
|
||||||
|
*.out
|
||||||
|
|
||||||
|
tmp.prof
|
||||||
|
|
||||||
|
go-restful.test
|
||||||
|
|
||||||
|
examples/restful-basic-authentication
|
||||||
|
|
||||||
|
examples/restful-encoding-filter
|
||||||
|
|
||||||
|
examples/restful-filters
|
||||||
|
|
||||||
|
examples/restful-hello-world
|
||||||
|
|
||||||
|
examples/restful-resource-functions
|
||||||
|
|
||||||
|
examples/restful-serve-static
|
||||||
|
|
||||||
|
examples/restful-user-service
|
||||||
|
|
||||||
|
*.DS_Store
|
||||||
|
examples/restful-user-resource
|
||||||
|
|
||||||
|
examples/restful-multi-containers
|
||||||
|
|
||||||
|
examples/restful-form-handling
|
||||||
|
|
||||||
|
examples/restful-CORS-filter
|
||||||
|
|
||||||
|
examples/restful-options-filter
|
||||||
|
|
||||||
|
examples/restful-curly-router
|
||||||
|
|
||||||
|
examples/restful-cpuprofiler-service
|
||||||
|
|
||||||
|
examples/restful-pre-post-filters
|
||||||
|
|
||||||
|
curly.prof
|
||||||
|
|
||||||
|
examples/restful-NCSA-logging
|
||||||
|
|
||||||
|
examples/restful-html-template
|
||||||
|
|
||||||
|
s.html
|
||||||
|
restful-path-tail
|
||||||
163
staging/src/k8s.io/client-go/1.4/_vendor/github.com/emicklei/go-restful/CHANGES.md
generated
Normal file
163
staging/src/k8s.io/client-go/1.4/_vendor/github.com/emicklei/go-restful/CHANGES.md
generated
Normal file
@@ -0,0 +1,163 @@
|
|||||||
|
Change history of go-restful
|
||||||
|
=
|
||||||
|
2016-02-14
|
||||||
|
- take the qualify factor of the Accept header mediatype into account when deciding the contentype of the response
|
||||||
|
- add constructors for custom entity accessors for xml and json
|
||||||
|
|
||||||
|
2015-09-27
|
||||||
|
- rename new WriteStatusAnd... to WriteHeaderAnd... for consistency
|
||||||
|
|
||||||
|
2015-09-25
|
||||||
|
- fixed problem with changing Header after WriteHeader (issue 235)
|
||||||
|
|
||||||
|
2015-09-14
|
||||||
|
- changed behavior of WriteHeader (immediate write) and WriteEntity (no status write)
|
||||||
|
- added support for custom EntityReaderWriters.
|
||||||
|
|
||||||
|
2015-08-06
|
||||||
|
- add support for reading entities from compressed request content
|
||||||
|
- use sync.Pool for compressors of http response and request body
|
||||||
|
- add Description to Parameter for documentation in Swagger UI
|
||||||
|
|
||||||
|
2015-03-20
|
||||||
|
- add configurable logging
|
||||||
|
|
||||||
|
2015-03-18
|
||||||
|
- if not specified, the Operation is derived from the Route function
|
||||||
|
|
||||||
|
2015-03-17
|
||||||
|
- expose Parameter creation functions
|
||||||
|
- make trace logger an interface
|
||||||
|
- fix OPTIONSFilter
|
||||||
|
- customize rendering of ServiceError
|
||||||
|
- JSR311 router now handles wildcards
|
||||||
|
- add Notes to Route
|
||||||
|
|
||||||
|
2014-11-27
|
||||||
|
- (api add) PrettyPrint per response. (as proposed in #167)
|
||||||
|
|
||||||
|
2014-11-12
|
||||||
|
- (api add) ApiVersion(.) for documentation in Swagger UI
|
||||||
|
|
||||||
|
2014-11-10
|
||||||
|
- (api change) struct fields tagged with "description" show up in Swagger UI
|
||||||
|
|
||||||
|
2014-10-31
|
||||||
|
- (api change) ReturnsError -> Returns
|
||||||
|
- (api add) RouteBuilder.Do(aBuilder) for DRY use of RouteBuilder
|
||||||
|
- fix swagger nested structs
|
||||||
|
- sort Swagger response messages by code
|
||||||
|
|
||||||
|
2014-10-23
|
||||||
|
- (api add) ReturnsError allows you to document Http codes in swagger
|
||||||
|
- fixed problem with greedy CurlyRouter
|
||||||
|
- (api add) Access-Control-Max-Age in CORS
|
||||||
|
- add tracing functionality (injectable) for debugging purposes
|
||||||
|
- support JSON parse 64bit int
|
||||||
|
- fix empty parameters for swagger
|
||||||
|
- WebServicesUrl is now optional for swagger
|
||||||
|
- fixed duplicate AccessControlAllowOrigin in CORS
|
||||||
|
- (api change) expose ServeMux in container
|
||||||
|
- (api add) added AllowedDomains in CORS
|
||||||
|
- (api add) ParameterNamed for detailed documentation
|
||||||
|
|
||||||
|
2014-04-16
|
||||||
|
- (api add) expose constructor of Request for testing.
|
||||||
|
|
||||||
|
2014-06-27
|
||||||
|
- (api add) ParameterNamed gives access to a Parameter definition and its data (for further specification).
|
||||||
|
- (api add) SetCacheReadEntity allow scontrol over whether or not the request body is being cached (default true for compatibility reasons).
|
||||||
|
|
||||||
|
2014-07-03
|
||||||
|
- (api add) CORS can be configured with a list of allowed domains
|
||||||
|
|
||||||
|
2014-03-12
|
||||||
|
- (api add) Route path parameters can use wildcard or regular expressions. (requires CurlyRouter)
|
||||||
|
|
||||||
|
2014-02-26
|
||||||
|
- (api add) Request now provides information about the matched Route, see method SelectedRoutePath
|
||||||
|
|
||||||
|
2014-02-17
|
||||||
|
- (api change) renamed parameter constants (go-lint checks)
|
||||||
|
|
||||||
|
2014-01-10
|
||||||
|
- (api add) support for CloseNotify, see http://golang.org/pkg/net/http/#CloseNotifier
|
||||||
|
|
||||||
|
2014-01-07
|
||||||
|
- (api change) Write* methods in Response now return the error or nil.
|
||||||
|
- added example of serving HTML from a Go template.
|
||||||
|
- fixed comparing Allowed headers in CORS (is now case-insensitive)
|
||||||
|
|
||||||
|
2013-11-13
|
||||||
|
- (api add) Response knows how many bytes are written to the response body.
|
||||||
|
|
||||||
|
2013-10-29
|
||||||
|
- (api add) RecoverHandler(handler RecoverHandleFunction) to change how panic recovery is handled. Default behavior is to log and return a stacktrace. This may be a security issue as it exposes sourcecode information.
|
||||||
|
|
||||||
|
2013-10-04
|
||||||
|
- (api add) Response knows what HTTP status has been written
|
||||||
|
- (api add) Request can have attributes (map of string->interface, also called request-scoped variables
|
||||||
|
|
||||||
|
2013-09-12
|
||||||
|
- (api change) Router interface simplified
|
||||||
|
- Implemented CurlyRouter, a Router that does not use|allow regular expressions in paths
|
||||||
|
|
||||||
|
2013-08-05
|
||||||
|
- add OPTIONS support
|
||||||
|
- add CORS support
|
||||||
|
|
||||||
|
2013-08-27
|
||||||
|
- fixed some reported issues (see github)
|
||||||
|
- (api change) deprecated use of WriteError; use WriteErrorString instead
|
||||||
|
|
||||||
|
2014-04-15
|
||||||
|
- (fix) v1.0.1 tag: fix Issue 111: WriteErrorString
|
||||||
|
|
||||||
|
2013-08-08
|
||||||
|
- (api add) Added implementation Container: a WebServices collection with its own http.ServeMux allowing multiple endpoints per program. Existing uses of go-restful will register their services to the DefaultContainer.
|
||||||
|
- (api add) the swagger package has be extended to have a UI per container.
|
||||||
|
- if panic is detected then a small stack trace is printed (thanks to runner-mei)
|
||||||
|
- (api add) WriteErrorString to Response
|
||||||
|
|
||||||
|
Important API changes:
|
||||||
|
|
||||||
|
- (api remove) package variable DoNotRecover no longer works ; use restful.DefaultContainer.DoNotRecover(true) instead.
|
||||||
|
- (api remove) package variable EnableContentEncoding no longer works ; use restful.DefaultContainer.EnableContentEncoding(true) instead.
|
||||||
|
|
||||||
|
|
||||||
|
2013-07-06
|
||||||
|
|
||||||
|
- (api add) Added support for response encoding (gzip and deflate(zlib)). This feature is disabled on default (for backwards compatibility). Use restful.EnableContentEncoding = true in your initialization to enable this feature.
|
||||||
|
|
||||||
|
2013-06-19
|
||||||
|
|
||||||
|
- (improve) DoNotRecover option, moved request body closer, improved ReadEntity
|
||||||
|
|
||||||
|
2013-06-03
|
||||||
|
|
||||||
|
- (api change) removed Dispatcher interface, hide PathExpression
|
||||||
|
- changed receiver names of type functions to be more idiomatic Go
|
||||||
|
|
||||||
|
2013-06-02
|
||||||
|
|
||||||
|
- (optimize) Cache the RegExp compilation of Paths.
|
||||||
|
|
||||||
|
2013-05-22
|
||||||
|
|
||||||
|
- (api add) Added support for request/response filter functions
|
||||||
|
|
||||||
|
2013-05-18
|
||||||
|
|
||||||
|
|
||||||
|
- (api add) Added feature to change the default Http Request Dispatch function (travis cline)
|
||||||
|
- (api change) Moved Swagger Webservice to swagger package (see example restful-user)
|
||||||
|
|
||||||
|
[2012-11-14 .. 2013-05-18>
|
||||||
|
|
||||||
|
- See https://github.com/emicklei/go-restful/commits
|
||||||
|
|
||||||
|
2012-11-14
|
||||||
|
|
||||||
|
- Initial commit
|
||||||
|
|
||||||
|
|
||||||
22
staging/src/k8s.io/client-go/1.4/_vendor/github.com/emicklei/go-restful/LICENSE
generated
Normal file
22
staging/src/k8s.io/client-go/1.4/_vendor/github.com/emicklei/go-restful/LICENSE
generated
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
Copyright (c) 2012,2013 Ernest Micklei
|
||||||
|
|
||||||
|
MIT License
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining
|
||||||
|
a copy of this software and associated documentation files (the
|
||||||
|
"Software"), to deal in the Software without restriction, including
|
||||||
|
without limitation the rights to use, copy, modify, merge, publish,
|
||||||
|
distribute, sublicense, and/or sell copies of the Software, and to
|
||||||
|
permit persons to whom the Software is furnished to do so, subject to
|
||||||
|
the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be
|
||||||
|
included in all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||||
|
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||||
|
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||||
|
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
1
staging/src/k8s.io/client-go/1.4/_vendor/github.com/emicklei/go-restful/Srcfile
generated
Normal file
1
staging/src/k8s.io/client-go/1.4/_vendor/github.com/emicklei/go-restful/Srcfile
generated
Normal file
@@ -0,0 +1 @@
|
|||||||
|
{"SkipDirs": ["examples"]}
|
||||||
123
staging/src/k8s.io/client-go/1.4/_vendor/github.com/emicklei/go-restful/compress.go
generated
Normal file
123
staging/src/k8s.io/client-go/1.4/_vendor/github.com/emicklei/go-restful/compress.go
generated
Normal file
@@ -0,0 +1,123 @@
|
|||||||
|
package restful
|
||||||
|
|
||||||
|
// Copyright 2013 Ernest Micklei. All rights reserved.
|
||||||
|
// Use of this source code is governed by a license
|
||||||
|
// that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bufio"
|
||||||
|
"compress/gzip"
|
||||||
|
"compress/zlib"
|
||||||
|
"errors"
|
||||||
|
"io"
|
||||||
|
"net"
|
||||||
|
"net/http"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
// OBSOLETE : use restful.DefaultContainer.EnableContentEncoding(true) to change this setting.
|
||||||
|
var EnableContentEncoding = false
|
||||||
|
|
||||||
|
// CompressingResponseWriter is a http.ResponseWriter that can perform content encoding (gzip and zlib)
|
||||||
|
type CompressingResponseWriter struct {
|
||||||
|
writer http.ResponseWriter
|
||||||
|
compressor io.WriteCloser
|
||||||
|
encoding string
|
||||||
|
}
|
||||||
|
|
||||||
|
// Header is part of http.ResponseWriter interface
|
||||||
|
func (c *CompressingResponseWriter) Header() http.Header {
|
||||||
|
return c.writer.Header()
|
||||||
|
}
|
||||||
|
|
||||||
|
// WriteHeader is part of http.ResponseWriter interface
|
||||||
|
func (c *CompressingResponseWriter) WriteHeader(status int) {
|
||||||
|
c.writer.WriteHeader(status)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write is part of http.ResponseWriter interface
|
||||||
|
// It is passed through the compressor
|
||||||
|
func (c *CompressingResponseWriter) Write(bytes []byte) (int, error) {
|
||||||
|
if c.isCompressorClosed() {
|
||||||
|
return -1, errors.New("Compressing error: tried to write data using closed compressor")
|
||||||
|
}
|
||||||
|
return c.compressor.Write(bytes)
|
||||||
|
}
|
||||||
|
|
||||||
|
// CloseNotify is part of http.CloseNotifier interface
|
||||||
|
func (c *CompressingResponseWriter) CloseNotify() <-chan bool {
|
||||||
|
return c.writer.(http.CloseNotifier).CloseNotify()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Close the underlying compressor
|
||||||
|
func (c *CompressingResponseWriter) Close() error {
|
||||||
|
if c.isCompressorClosed() {
|
||||||
|
return errors.New("Compressing error: tried to close already closed compressor")
|
||||||
|
}
|
||||||
|
|
||||||
|
c.compressor.Close()
|
||||||
|
if ENCODING_GZIP == c.encoding {
|
||||||
|
currentCompressorProvider.ReleaseGzipWriter(c.compressor.(*gzip.Writer))
|
||||||
|
}
|
||||||
|
if ENCODING_DEFLATE == c.encoding {
|
||||||
|
currentCompressorProvider.ReleaseZlibWriter(c.compressor.(*zlib.Writer))
|
||||||
|
}
|
||||||
|
// gc hint needed?
|
||||||
|
c.compressor = nil
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *CompressingResponseWriter) isCompressorClosed() bool {
|
||||||
|
return nil == c.compressor
|
||||||
|
}
|
||||||
|
|
||||||
|
// Hijack implements the Hijacker interface
|
||||||
|
// This is especially useful when combining Container.EnabledContentEncoding
|
||||||
|
// in combination with websockets (for instance gorilla/websocket)
|
||||||
|
func (c *CompressingResponseWriter) Hijack() (net.Conn, *bufio.ReadWriter, error) {
|
||||||
|
hijacker, ok := c.writer.(http.Hijacker)
|
||||||
|
if !ok {
|
||||||
|
return nil, nil, errors.New("ResponseWriter doesn't support Hijacker interface")
|
||||||
|
}
|
||||||
|
return hijacker.Hijack()
|
||||||
|
}
|
||||||
|
|
||||||
|
// WantsCompressedResponse reads the Accept-Encoding header to see if and which encoding is requested.
|
||||||
|
func wantsCompressedResponse(httpRequest *http.Request) (bool, string) {
|
||||||
|
header := httpRequest.Header.Get(HEADER_AcceptEncoding)
|
||||||
|
gi := strings.Index(header, ENCODING_GZIP)
|
||||||
|
zi := strings.Index(header, ENCODING_DEFLATE)
|
||||||
|
// use in order of appearance
|
||||||
|
if gi == -1 {
|
||||||
|
return zi != -1, ENCODING_DEFLATE
|
||||||
|
} else if zi == -1 {
|
||||||
|
return gi != -1, ENCODING_GZIP
|
||||||
|
} else {
|
||||||
|
if gi < zi {
|
||||||
|
return true, ENCODING_GZIP
|
||||||
|
}
|
||||||
|
return true, ENCODING_DEFLATE
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewCompressingResponseWriter create a CompressingResponseWriter for a known encoding = {gzip,deflate}
|
||||||
|
func NewCompressingResponseWriter(httpWriter http.ResponseWriter, encoding string) (*CompressingResponseWriter, error) {
|
||||||
|
httpWriter.Header().Set(HEADER_ContentEncoding, encoding)
|
||||||
|
c := new(CompressingResponseWriter)
|
||||||
|
c.writer = httpWriter
|
||||||
|
var err error
|
||||||
|
if ENCODING_GZIP == encoding {
|
||||||
|
w := currentCompressorProvider.AcquireGzipWriter()
|
||||||
|
w.Reset(httpWriter)
|
||||||
|
c.compressor = w
|
||||||
|
c.encoding = ENCODING_GZIP
|
||||||
|
} else if ENCODING_DEFLATE == encoding {
|
||||||
|
w := currentCompressorProvider.AcquireZlibWriter()
|
||||||
|
w.Reset(httpWriter)
|
||||||
|
c.compressor = w
|
||||||
|
c.encoding = ENCODING_DEFLATE
|
||||||
|
} else {
|
||||||
|
return nil, errors.New("Unknown encoding:" + encoding)
|
||||||
|
}
|
||||||
|
return c, err
|
||||||
|
}
|
||||||
103
staging/src/k8s.io/client-go/1.4/_vendor/github.com/emicklei/go-restful/compressor_cache.go
generated
Normal file
103
staging/src/k8s.io/client-go/1.4/_vendor/github.com/emicklei/go-restful/compressor_cache.go
generated
Normal file
@@ -0,0 +1,103 @@
|
|||||||
|
package restful
|
||||||
|
|
||||||
|
// Copyright 2015 Ernest Micklei. All rights reserved.
|
||||||
|
// Use of this source code is governed by a license
|
||||||
|
// that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
import (
|
||||||
|
"compress/gzip"
|
||||||
|
"compress/zlib"
|
||||||
|
)
|
||||||
|
|
||||||
|
// BoundedCachedCompressors is a CompressorProvider that uses a cache with a fixed amount
|
||||||
|
// of writers and readers (resources).
|
||||||
|
// If a new resource is acquired and all are in use, it will return a new unmanaged resource.
|
||||||
|
type BoundedCachedCompressors struct {
|
||||||
|
gzipWriters chan *gzip.Writer
|
||||||
|
gzipReaders chan *gzip.Reader
|
||||||
|
zlibWriters chan *zlib.Writer
|
||||||
|
writersCapacity int
|
||||||
|
readersCapacity int
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewBoundedCachedCompressors returns a new, with filled cache, BoundedCachedCompressors.
|
||||||
|
func NewBoundedCachedCompressors(writersCapacity, readersCapacity int) *BoundedCachedCompressors {
|
||||||
|
b := &BoundedCachedCompressors{
|
||||||
|
gzipWriters: make(chan *gzip.Writer, writersCapacity),
|
||||||
|
gzipReaders: make(chan *gzip.Reader, readersCapacity),
|
||||||
|
zlibWriters: make(chan *zlib.Writer, writersCapacity),
|
||||||
|
writersCapacity: writersCapacity,
|
||||||
|
readersCapacity: readersCapacity,
|
||||||
|
}
|
||||||
|
for ix := 0; ix < writersCapacity; ix++ {
|
||||||
|
b.gzipWriters <- newGzipWriter()
|
||||||
|
b.zlibWriters <- newZlibWriter()
|
||||||
|
}
|
||||||
|
for ix := 0; ix < readersCapacity; ix++ {
|
||||||
|
b.gzipReaders <- newGzipReader()
|
||||||
|
}
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
|
||||||
|
// AcquireGzipWriter returns an resettable *gzip.Writer. Needs to be released.
|
||||||
|
func (b *BoundedCachedCompressors) AcquireGzipWriter() *gzip.Writer {
|
||||||
|
var writer *gzip.Writer
|
||||||
|
select {
|
||||||
|
case writer, _ = <-b.gzipWriters:
|
||||||
|
default:
|
||||||
|
// return a new unmanaged one
|
||||||
|
writer = newGzipWriter()
|
||||||
|
}
|
||||||
|
return writer
|
||||||
|
}
|
||||||
|
|
||||||
|
// ReleaseGzipWriter accepts a writer (does not have to be one that was cached)
|
||||||
|
// only when the cache has room for it. It will ignore it otherwise.
|
||||||
|
func (b *BoundedCachedCompressors) ReleaseGzipWriter(w *gzip.Writer) {
|
||||||
|
// forget the unmanaged ones
|
||||||
|
if len(b.gzipWriters) < b.writersCapacity {
|
||||||
|
b.gzipWriters <- w
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// AcquireGzipReader returns a *gzip.Reader. Needs to be released.
|
||||||
|
func (b *BoundedCachedCompressors) AcquireGzipReader() *gzip.Reader {
|
||||||
|
var reader *gzip.Reader
|
||||||
|
select {
|
||||||
|
case reader, _ = <-b.gzipReaders:
|
||||||
|
default:
|
||||||
|
// return a new unmanaged one
|
||||||
|
reader = newGzipReader()
|
||||||
|
}
|
||||||
|
return reader
|
||||||
|
}
|
||||||
|
|
||||||
|
// ReleaseGzipReader accepts a reader (does not have to be one that was cached)
|
||||||
|
// only when the cache has room for it. It will ignore it otherwise.
|
||||||
|
func (b *BoundedCachedCompressors) ReleaseGzipReader(r *gzip.Reader) {
|
||||||
|
// forget the unmanaged ones
|
||||||
|
if len(b.gzipReaders) < b.readersCapacity {
|
||||||
|
b.gzipReaders <- r
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// AcquireZlibWriter returns an resettable *zlib.Writer. Needs to be released.
|
||||||
|
func (b *BoundedCachedCompressors) AcquireZlibWriter() *zlib.Writer {
|
||||||
|
var writer *zlib.Writer
|
||||||
|
select {
|
||||||
|
case writer, _ = <-b.zlibWriters:
|
||||||
|
default:
|
||||||
|
// return a new unmanaged one
|
||||||
|
writer = newZlibWriter()
|
||||||
|
}
|
||||||
|
return writer
|
||||||
|
}
|
||||||
|
|
||||||
|
// ReleaseZlibWriter accepts a writer (does not have to be one that was cached)
|
||||||
|
// only when the cache has room for it. It will ignore it otherwise.
|
||||||
|
func (b *BoundedCachedCompressors) ReleaseZlibWriter(w *zlib.Writer) {
|
||||||
|
// forget the unmanaged ones
|
||||||
|
if len(b.zlibWriters) < b.writersCapacity {
|
||||||
|
b.zlibWriters <- w
|
||||||
|
}
|
||||||
|
}
|
||||||
91
staging/src/k8s.io/client-go/1.4/_vendor/github.com/emicklei/go-restful/compressor_pools.go
generated
Normal file
91
staging/src/k8s.io/client-go/1.4/_vendor/github.com/emicklei/go-restful/compressor_pools.go
generated
Normal file
@@ -0,0 +1,91 @@
|
|||||||
|
package restful
|
||||||
|
|
||||||
|
// Copyright 2015 Ernest Micklei. All rights reserved.
|
||||||
|
// Use of this source code is governed by a license
|
||||||
|
// that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"compress/gzip"
|
||||||
|
"compress/zlib"
|
||||||
|
"sync"
|
||||||
|
)
|
||||||
|
|
||||||
|
// SyncPoolCompessors is a CompressorProvider that use the standard sync.Pool.
|
||||||
|
type SyncPoolCompessors struct {
|
||||||
|
GzipWriterPool *sync.Pool
|
||||||
|
GzipReaderPool *sync.Pool
|
||||||
|
ZlibWriterPool *sync.Pool
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewSyncPoolCompessors returns a new ("empty") SyncPoolCompessors.
|
||||||
|
func NewSyncPoolCompessors() *SyncPoolCompessors {
|
||||||
|
return &SyncPoolCompessors{
|
||||||
|
GzipWriterPool: &sync.Pool{
|
||||||
|
New: func() interface{} { return newGzipWriter() },
|
||||||
|
},
|
||||||
|
GzipReaderPool: &sync.Pool{
|
||||||
|
New: func() interface{} { return newGzipReader() },
|
||||||
|
},
|
||||||
|
ZlibWriterPool: &sync.Pool{
|
||||||
|
New: func() interface{} { return newZlibWriter() },
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *SyncPoolCompessors) AcquireGzipWriter() *gzip.Writer {
|
||||||
|
return s.GzipWriterPool.Get().(*gzip.Writer)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *SyncPoolCompessors) ReleaseGzipWriter(w *gzip.Writer) {
|
||||||
|
s.GzipWriterPool.Put(w)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *SyncPoolCompessors) AcquireGzipReader() *gzip.Reader {
|
||||||
|
return s.GzipReaderPool.Get().(*gzip.Reader)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *SyncPoolCompessors) ReleaseGzipReader(r *gzip.Reader) {
|
||||||
|
s.GzipReaderPool.Put(r)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *SyncPoolCompessors) AcquireZlibWriter() *zlib.Writer {
|
||||||
|
return s.ZlibWriterPool.Get().(*zlib.Writer)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *SyncPoolCompessors) ReleaseZlibWriter(w *zlib.Writer) {
|
||||||
|
s.ZlibWriterPool.Put(w)
|
||||||
|
}
|
||||||
|
|
||||||
|
func newGzipWriter() *gzip.Writer {
|
||||||
|
// create with an empty bytes writer; it will be replaced before using the gzipWriter
|
||||||
|
writer, err := gzip.NewWriterLevel(new(bytes.Buffer), gzip.BestSpeed)
|
||||||
|
if err != nil {
|
||||||
|
panic(err.Error())
|
||||||
|
}
|
||||||
|
return writer
|
||||||
|
}
|
||||||
|
|
||||||
|
func newGzipReader() *gzip.Reader {
|
||||||
|
// create with an empty reader (but with GZIP header); it will be replaced before using the gzipReader
|
||||||
|
// we can safely use currentCompressProvider because it is set on package initialization.
|
||||||
|
w := currentCompressorProvider.AcquireGzipWriter()
|
||||||
|
defer currentCompressorProvider.ReleaseGzipWriter(w)
|
||||||
|
b := new(bytes.Buffer)
|
||||||
|
w.Reset(b)
|
||||||
|
w.Flush()
|
||||||
|
w.Close()
|
||||||
|
reader, err := gzip.NewReader(bytes.NewReader(b.Bytes()))
|
||||||
|
if err != nil {
|
||||||
|
panic(err.Error())
|
||||||
|
}
|
||||||
|
return reader
|
||||||
|
}
|
||||||
|
|
||||||
|
func newZlibWriter() *zlib.Writer {
|
||||||
|
writer, err := zlib.NewWriterLevel(new(bytes.Buffer), gzip.BestSpeed)
|
||||||
|
if err != nil {
|
||||||
|
panic(err.Error())
|
||||||
|
}
|
||||||
|
return writer
|
||||||
|
}
|
||||||
53
staging/src/k8s.io/client-go/1.4/_vendor/github.com/emicklei/go-restful/compressors.go
generated
Normal file
53
staging/src/k8s.io/client-go/1.4/_vendor/github.com/emicklei/go-restful/compressors.go
generated
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
package restful
|
||||||
|
|
||||||
|
// Copyright 2015 Ernest Micklei. All rights reserved.
|
||||||
|
// Use of this source code is governed by a license
|
||||||
|
// that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
import (
|
||||||
|
"compress/gzip"
|
||||||
|
"compress/zlib"
|
||||||
|
)
|
||||||
|
|
||||||
|
type CompressorProvider interface {
|
||||||
|
// Returns a *gzip.Writer which needs to be released later.
|
||||||
|
// Before using it, call Reset().
|
||||||
|
AcquireGzipWriter() *gzip.Writer
|
||||||
|
|
||||||
|
// Releases an aqcuired *gzip.Writer.
|
||||||
|
ReleaseGzipWriter(w *gzip.Writer)
|
||||||
|
|
||||||
|
// Returns a *gzip.Reader which needs to be released later.
|
||||||
|
AcquireGzipReader() *gzip.Reader
|
||||||
|
|
||||||
|
// Releases an aqcuired *gzip.Reader.
|
||||||
|
ReleaseGzipReader(w *gzip.Reader)
|
||||||
|
|
||||||
|
// Returns a *zlib.Writer which needs to be released later.
|
||||||
|
// Before using it, call Reset().
|
||||||
|
AcquireZlibWriter() *zlib.Writer
|
||||||
|
|
||||||
|
// Releases an aqcuired *zlib.Writer.
|
||||||
|
ReleaseZlibWriter(w *zlib.Writer)
|
||||||
|
}
|
||||||
|
|
||||||
|
// DefaultCompressorProvider is the actual provider of compressors (zlib or gzip).
|
||||||
|
var currentCompressorProvider CompressorProvider
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
currentCompressorProvider = NewSyncPoolCompessors()
|
||||||
|
}
|
||||||
|
|
||||||
|
// CurrentCompressorProvider returns the current CompressorProvider.
|
||||||
|
// It is initialized using a SyncPoolCompessors.
|
||||||
|
func CurrentCompressorProvider() CompressorProvider {
|
||||||
|
return currentCompressorProvider
|
||||||
|
}
|
||||||
|
|
||||||
|
// CompressorProvider sets the actual provider of compressors (zlib or gzip).
|
||||||
|
func SetCompressorProvider(p CompressorProvider) {
|
||||||
|
if p == nil {
|
||||||
|
panic("cannot set compressor provider to nil")
|
||||||
|
}
|
||||||
|
currentCompressorProvider = p
|
||||||
|
}
|
||||||
30
staging/src/k8s.io/client-go/1.4/_vendor/github.com/emicklei/go-restful/constants.go
generated
Normal file
30
staging/src/k8s.io/client-go/1.4/_vendor/github.com/emicklei/go-restful/constants.go
generated
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
package restful
|
||||||
|
|
||||||
|
// Copyright 2013 Ernest Micklei. All rights reserved.
|
||||||
|
// Use of this source code is governed by a license
|
||||||
|
// that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
const (
|
||||||
|
MIME_XML = "application/xml" // Accept or Content-Type used in Consumes() and/or Produces()
|
||||||
|
MIME_JSON = "application/json" // Accept or Content-Type used in Consumes() and/or Produces()
|
||||||
|
MIME_OCTET = "application/octet-stream" // If Content-Type is not present in request, use the default
|
||||||
|
|
||||||
|
HEADER_Allow = "Allow"
|
||||||
|
HEADER_Accept = "Accept"
|
||||||
|
HEADER_Origin = "Origin"
|
||||||
|
HEADER_ContentType = "Content-Type"
|
||||||
|
HEADER_LastModified = "Last-Modified"
|
||||||
|
HEADER_AcceptEncoding = "Accept-Encoding"
|
||||||
|
HEADER_ContentEncoding = "Content-Encoding"
|
||||||
|
HEADER_AccessControlExposeHeaders = "Access-Control-Expose-Headers"
|
||||||
|
HEADER_AccessControlRequestMethod = "Access-Control-Request-Method"
|
||||||
|
HEADER_AccessControlRequestHeaders = "Access-Control-Request-Headers"
|
||||||
|
HEADER_AccessControlAllowMethods = "Access-Control-Allow-Methods"
|
||||||
|
HEADER_AccessControlAllowOrigin = "Access-Control-Allow-Origin"
|
||||||
|
HEADER_AccessControlAllowCredentials = "Access-Control-Allow-Credentials"
|
||||||
|
HEADER_AccessControlAllowHeaders = "Access-Control-Allow-Headers"
|
||||||
|
HEADER_AccessControlMaxAge = "Access-Control-Max-Age"
|
||||||
|
|
||||||
|
ENCODING_GZIP = "gzip"
|
||||||
|
ENCODING_DEFLATE = "deflate"
|
||||||
|
)
|
||||||
361
staging/src/k8s.io/client-go/1.4/_vendor/github.com/emicklei/go-restful/container.go
generated
Normal file
361
staging/src/k8s.io/client-go/1.4/_vendor/github.com/emicklei/go-restful/container.go
generated
Normal file
@@ -0,0 +1,361 @@
|
|||||||
|
package restful
|
||||||
|
|
||||||
|
// Copyright 2013 Ernest Micklei. All rights reserved.
|
||||||
|
// Use of this source code is governed by a license
|
||||||
|
// that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
"os"
|
||||||
|
"runtime"
|
||||||
|
"strings"
|
||||||
|
"sync"
|
||||||
|
|
||||||
|
"github.com/emicklei/go-restful/log"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Container holds a collection of WebServices and a http.ServeMux to dispatch http requests.
|
||||||
|
// The requests are further dispatched to routes of WebServices using a RouteSelector
|
||||||
|
type Container struct {
|
||||||
|
webServicesLock sync.RWMutex
|
||||||
|
webServices []*WebService
|
||||||
|
ServeMux *http.ServeMux
|
||||||
|
isRegisteredOnRoot bool
|
||||||
|
containerFilters []FilterFunction
|
||||||
|
doNotRecover bool // default is false
|
||||||
|
recoverHandleFunc RecoverHandleFunction
|
||||||
|
serviceErrorHandleFunc ServiceErrorHandleFunction
|
||||||
|
router RouteSelector // default is a RouterJSR311, CurlyRouter is the faster alternative
|
||||||
|
contentEncodingEnabled bool // default is false
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewContainer creates a new Container using a new ServeMux and default router (RouterJSR311)
|
||||||
|
func NewContainer() *Container {
|
||||||
|
return &Container{
|
||||||
|
webServices: []*WebService{},
|
||||||
|
ServeMux: http.NewServeMux(),
|
||||||
|
isRegisteredOnRoot: false,
|
||||||
|
containerFilters: []FilterFunction{},
|
||||||
|
doNotRecover: false,
|
||||||
|
recoverHandleFunc: logStackOnRecover,
|
||||||
|
serviceErrorHandleFunc: writeServiceError,
|
||||||
|
router: RouterJSR311{},
|
||||||
|
contentEncodingEnabled: false}
|
||||||
|
}
|
||||||
|
|
||||||
|
// RecoverHandleFunction declares functions that can be used to handle a panic situation.
|
||||||
|
// The first argument is what recover() returns. The second must be used to communicate an error response.
|
||||||
|
type RecoverHandleFunction func(interface{}, http.ResponseWriter)
|
||||||
|
|
||||||
|
// RecoverHandler changes the default function (logStackOnRecover) to be called
|
||||||
|
// when a panic is detected. DoNotRecover must be have its default value (=false).
|
||||||
|
func (c *Container) RecoverHandler(handler RecoverHandleFunction) {
|
||||||
|
c.recoverHandleFunc = handler
|
||||||
|
}
|
||||||
|
|
||||||
|
// ServiceErrorHandleFunction declares functions that can be used to handle a service error situation.
|
||||||
|
// The first argument is the service error, the second is the request that resulted in the error and
|
||||||
|
// the third must be used to communicate an error response.
|
||||||
|
type ServiceErrorHandleFunction func(ServiceError, *Request, *Response)
|
||||||
|
|
||||||
|
// ServiceErrorHandler changes the default function (writeServiceError) to be called
|
||||||
|
// when a ServiceError is detected.
|
||||||
|
func (c *Container) ServiceErrorHandler(handler ServiceErrorHandleFunction) {
|
||||||
|
c.serviceErrorHandleFunc = handler
|
||||||
|
}
|
||||||
|
|
||||||
|
// DoNotRecover controls whether panics will be caught to return HTTP 500.
|
||||||
|
// If set to true, Route functions are responsible for handling any error situation.
|
||||||
|
// Default value is false = recover from panics. This has performance implications.
|
||||||
|
func (c *Container) DoNotRecover(doNot bool) {
|
||||||
|
c.doNotRecover = doNot
|
||||||
|
}
|
||||||
|
|
||||||
|
// Router changes the default Router (currently RouterJSR311)
|
||||||
|
func (c *Container) Router(aRouter RouteSelector) {
|
||||||
|
c.router = aRouter
|
||||||
|
}
|
||||||
|
|
||||||
|
// EnableContentEncoding (default=false) allows for GZIP or DEFLATE encoding of responses.
|
||||||
|
func (c *Container) EnableContentEncoding(enabled bool) {
|
||||||
|
c.contentEncodingEnabled = enabled
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add a WebService to the Container. It will detect duplicate root paths and exit in that case.
|
||||||
|
func (c *Container) Add(service *WebService) *Container {
|
||||||
|
c.webServicesLock.Lock()
|
||||||
|
defer c.webServicesLock.Unlock()
|
||||||
|
|
||||||
|
// if rootPath was not set then lazy initialize it
|
||||||
|
if len(service.rootPath) == 0 {
|
||||||
|
service.Path("/")
|
||||||
|
}
|
||||||
|
|
||||||
|
// cannot have duplicate root paths
|
||||||
|
for _, each := range c.webServices {
|
||||||
|
if each.RootPath() == service.RootPath() {
|
||||||
|
log.Printf("[restful] WebService with duplicate root path detected:['%v']", each)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If not registered on root then add specific mapping
|
||||||
|
if !c.isRegisteredOnRoot {
|
||||||
|
c.isRegisteredOnRoot = c.addHandler(service, c.ServeMux)
|
||||||
|
}
|
||||||
|
c.webServices = append(c.webServices, service)
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
|
||||||
|
// addHandler may set a new HandleFunc for the serveMux
|
||||||
|
// this function must run inside the critical region protected by the webServicesLock.
|
||||||
|
// returns true if the function was registered on root ("/")
|
||||||
|
func (c *Container) addHandler(service *WebService, serveMux *http.ServeMux) bool {
|
||||||
|
pattern := fixedPrefixPath(service.RootPath())
|
||||||
|
// check if root path registration is needed
|
||||||
|
if "/" == pattern || "" == pattern {
|
||||||
|
serveMux.HandleFunc("/", c.dispatch)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
// detect if registration already exists
|
||||||
|
alreadyMapped := false
|
||||||
|
for _, each := range c.webServices {
|
||||||
|
if each.RootPath() == service.RootPath() {
|
||||||
|
alreadyMapped = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !alreadyMapped {
|
||||||
|
serveMux.HandleFunc(pattern, c.dispatch)
|
||||||
|
if !strings.HasSuffix(pattern, "/") {
|
||||||
|
serveMux.HandleFunc(pattern+"/", c.dispatch)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Container) Remove(ws *WebService) error {
|
||||||
|
if c.ServeMux == http.DefaultServeMux {
|
||||||
|
errMsg := fmt.Sprintf("[restful] cannot remove a WebService from a Container using the DefaultServeMux: ['%v']", ws)
|
||||||
|
log.Printf(errMsg)
|
||||||
|
return errors.New(errMsg)
|
||||||
|
}
|
||||||
|
c.webServicesLock.Lock()
|
||||||
|
defer c.webServicesLock.Unlock()
|
||||||
|
// build a new ServeMux and re-register all WebServices
|
||||||
|
newServeMux := http.NewServeMux()
|
||||||
|
newServices := []*WebService{}
|
||||||
|
newIsRegisteredOnRoot := false
|
||||||
|
for _, each := range c.webServices {
|
||||||
|
if each.rootPath != ws.rootPath {
|
||||||
|
// If not registered on root then add specific mapping
|
||||||
|
if !newIsRegisteredOnRoot {
|
||||||
|
newIsRegisteredOnRoot = c.addHandler(each, newServeMux)
|
||||||
|
}
|
||||||
|
newServices = append(newServices, each)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
c.webServices, c.ServeMux, c.isRegisteredOnRoot = newServices, newServeMux, newIsRegisteredOnRoot
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// logStackOnRecover is the default RecoverHandleFunction and is called
|
||||||
|
// when DoNotRecover is false and the recoverHandleFunc is not set for the container.
|
||||||
|
// Default implementation logs the stacktrace and writes the stacktrace on the response.
|
||||||
|
// This may be a security issue as it exposes sourcecode information.
|
||||||
|
func logStackOnRecover(panicReason interface{}, httpWriter http.ResponseWriter) {
|
||||||
|
var buffer bytes.Buffer
|
||||||
|
buffer.WriteString(fmt.Sprintf("[restful] recover from panic situation: - %v\r\n", panicReason))
|
||||||
|
for i := 2; ; i += 1 {
|
||||||
|
_, file, line, ok := runtime.Caller(i)
|
||||||
|
if !ok {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
buffer.WriteString(fmt.Sprintf(" %s:%d\r\n", file, line))
|
||||||
|
}
|
||||||
|
log.Print(buffer.String())
|
||||||
|
httpWriter.WriteHeader(http.StatusInternalServerError)
|
||||||
|
httpWriter.Write(buffer.Bytes())
|
||||||
|
}
|
||||||
|
|
||||||
|
// writeServiceError is the default ServiceErrorHandleFunction and is called
|
||||||
|
// when a ServiceError is returned during route selection. Default implementation
|
||||||
|
// calls resp.WriteErrorString(err.Code, err.Message)
|
||||||
|
func writeServiceError(err ServiceError, req *Request, resp *Response) {
|
||||||
|
resp.WriteErrorString(err.Code, err.Message)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Dispatch the incoming Http Request to a matching WebService.
|
||||||
|
func (c *Container) dispatch(httpWriter http.ResponseWriter, httpRequest *http.Request) {
|
||||||
|
writer := httpWriter
|
||||||
|
|
||||||
|
// CompressingResponseWriter should be closed after all operations are done
|
||||||
|
defer func() {
|
||||||
|
if compressWriter, ok := writer.(*CompressingResponseWriter); ok {
|
||||||
|
compressWriter.Close()
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
// Instal panic recovery unless told otherwise
|
||||||
|
if !c.doNotRecover { // catch all for 500 response
|
||||||
|
defer func() {
|
||||||
|
if r := recover(); r != nil {
|
||||||
|
c.recoverHandleFunc(r, writer)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
// Install closing the request body (if any)
|
||||||
|
defer func() {
|
||||||
|
if nil != httpRequest.Body {
|
||||||
|
httpRequest.Body.Close()
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
// Detect if compression is needed
|
||||||
|
// assume without compression, test for override
|
||||||
|
if c.contentEncodingEnabled {
|
||||||
|
doCompress, encoding := wantsCompressedResponse(httpRequest)
|
||||||
|
if doCompress {
|
||||||
|
var err error
|
||||||
|
writer, err = NewCompressingResponseWriter(httpWriter, encoding)
|
||||||
|
if err != nil {
|
||||||
|
log.Print("[restful] unable to install compressor: ", err)
|
||||||
|
httpWriter.WriteHeader(http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Find best match Route ; err is non nil if no match was found
|
||||||
|
var webService *WebService
|
||||||
|
var route *Route
|
||||||
|
var err error
|
||||||
|
func() {
|
||||||
|
c.webServicesLock.RLock()
|
||||||
|
defer c.webServicesLock.RUnlock()
|
||||||
|
webService, route, err = c.router.SelectRoute(
|
||||||
|
c.webServices,
|
||||||
|
httpRequest)
|
||||||
|
}()
|
||||||
|
if err != nil {
|
||||||
|
// a non-200 response has already been written
|
||||||
|
// run container filters anyway ; they should not touch the response...
|
||||||
|
chain := FilterChain{Filters: c.containerFilters, Target: func(req *Request, resp *Response) {
|
||||||
|
switch err.(type) {
|
||||||
|
case ServiceError:
|
||||||
|
ser := err.(ServiceError)
|
||||||
|
c.serviceErrorHandleFunc(ser, req, resp)
|
||||||
|
}
|
||||||
|
// TODO
|
||||||
|
}}
|
||||||
|
chain.ProcessFilter(NewRequest(httpRequest), NewResponse(writer))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
wrappedRequest, wrappedResponse := route.wrapRequestResponse(writer, httpRequest)
|
||||||
|
// pass through filters (if any)
|
||||||
|
if len(c.containerFilters)+len(webService.filters)+len(route.Filters) > 0 {
|
||||||
|
// compose filter chain
|
||||||
|
allFilters := []FilterFunction{}
|
||||||
|
allFilters = append(allFilters, c.containerFilters...)
|
||||||
|
allFilters = append(allFilters, webService.filters...)
|
||||||
|
allFilters = append(allFilters, route.Filters...)
|
||||||
|
chain := FilterChain{Filters: allFilters, Target: func(req *Request, resp *Response) {
|
||||||
|
// handle request by route after passing all filters
|
||||||
|
route.Function(wrappedRequest, wrappedResponse)
|
||||||
|
}}
|
||||||
|
chain.ProcessFilter(wrappedRequest, wrappedResponse)
|
||||||
|
} else {
|
||||||
|
// no filters, handle request by route
|
||||||
|
route.Function(wrappedRequest, wrappedResponse)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// fixedPrefixPath returns the fixed part of the partspec ; it may include template vars {}
|
||||||
|
func fixedPrefixPath(pathspec string) string {
|
||||||
|
varBegin := strings.Index(pathspec, "{")
|
||||||
|
if -1 == varBegin {
|
||||||
|
return pathspec
|
||||||
|
}
|
||||||
|
return pathspec[:varBegin]
|
||||||
|
}
|
||||||
|
|
||||||
|
// ServeHTTP implements net/http.Handler therefore a Container can be a Handler in a http.Server
|
||||||
|
func (c Container) ServeHTTP(httpwriter http.ResponseWriter, httpRequest *http.Request) {
|
||||||
|
c.ServeMux.ServeHTTP(httpwriter, httpRequest)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle registers the handler for the given pattern. If a handler already exists for pattern, Handle panics.
|
||||||
|
func (c Container) Handle(pattern string, handler http.Handler) {
|
||||||
|
c.ServeMux.Handle(pattern, handler)
|
||||||
|
}
|
||||||
|
|
||||||
|
// HandleWithFilter registers the handler for the given pattern.
|
||||||
|
// Container's filter chain is applied for handler.
|
||||||
|
// If a handler already exists for pattern, HandleWithFilter panics.
|
||||||
|
func (c *Container) HandleWithFilter(pattern string, handler http.Handler) {
|
||||||
|
f := func(httpResponse http.ResponseWriter, httpRequest *http.Request) {
|
||||||
|
if len(c.containerFilters) == 0 {
|
||||||
|
handler.ServeHTTP(httpResponse, httpRequest)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
chain := FilterChain{Filters: c.containerFilters, Target: func(req *Request, resp *Response) {
|
||||||
|
handler.ServeHTTP(httpResponse, httpRequest)
|
||||||
|
}}
|
||||||
|
chain.ProcessFilter(NewRequest(httpRequest), NewResponse(httpResponse))
|
||||||
|
}
|
||||||
|
|
||||||
|
c.Handle(pattern, http.HandlerFunc(f))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Filter appends a container FilterFunction. These are called before dispatching
|
||||||
|
// a http.Request to a WebService from the container
|
||||||
|
func (c *Container) Filter(filter FilterFunction) {
|
||||||
|
c.containerFilters = append(c.containerFilters, filter)
|
||||||
|
}
|
||||||
|
|
||||||
|
// RegisteredWebServices returns the collections of added WebServices
|
||||||
|
func (c Container) RegisteredWebServices() []*WebService {
|
||||||
|
c.webServicesLock.RLock()
|
||||||
|
defer c.webServicesLock.RUnlock()
|
||||||
|
result := make([]*WebService, len(c.webServices))
|
||||||
|
for ix := range c.webServices {
|
||||||
|
result[ix] = c.webServices[ix]
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
// computeAllowedMethods returns a list of HTTP methods that are valid for a Request
|
||||||
|
func (c Container) computeAllowedMethods(req *Request) []string {
|
||||||
|
// Go through all RegisteredWebServices() and all its Routes to collect the options
|
||||||
|
methods := []string{}
|
||||||
|
requestPath := req.Request.URL.Path
|
||||||
|
for _, ws := range c.RegisteredWebServices() {
|
||||||
|
matches := ws.pathExpr.Matcher.FindStringSubmatch(requestPath)
|
||||||
|
if matches != nil {
|
||||||
|
finalMatch := matches[len(matches)-1]
|
||||||
|
for _, rt := range ws.Routes() {
|
||||||
|
matches := rt.pathExpr.Matcher.FindStringSubmatch(finalMatch)
|
||||||
|
if matches != nil {
|
||||||
|
lastMatch := matches[len(matches)-1]
|
||||||
|
if lastMatch == "" || lastMatch == "/" { // do not include if value is neither empty nor ‘/’.
|
||||||
|
methods = append(methods, rt.Method)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// methods = append(methods, "OPTIONS") not sure about this
|
||||||
|
return methods
|
||||||
|
}
|
||||||
|
|
||||||
|
// newBasicRequestResponse creates a pair of Request,Response from its http versions.
|
||||||
|
// It is basic because no parameter or (produces) content-type information is given.
|
||||||
|
func newBasicRequestResponse(httpWriter http.ResponseWriter, httpRequest *http.Request) (*Request, *Response) {
|
||||||
|
resp := NewResponse(httpWriter)
|
||||||
|
resp.requestAccept = httpRequest.Header.Get(HEADER_Accept)
|
||||||
|
return NewRequest(httpRequest), resp
|
||||||
|
}
|
||||||
202
staging/src/k8s.io/client-go/1.4/_vendor/github.com/emicklei/go-restful/cors_filter.go
generated
Normal file
202
staging/src/k8s.io/client-go/1.4/_vendor/github.com/emicklei/go-restful/cors_filter.go
generated
Normal file
@@ -0,0 +1,202 @@
|
|||||||
|
package restful
|
||||||
|
|
||||||
|
// Copyright 2013 Ernest Micklei. All rights reserved.
|
||||||
|
// Use of this source code is governed by a license
|
||||||
|
// that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
import (
|
||||||
|
"regexp"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
// CrossOriginResourceSharing is used to create a Container Filter that implements CORS.
|
||||||
|
// Cross-origin resource sharing (CORS) is a mechanism that allows JavaScript on a web page
|
||||||
|
// to make XMLHttpRequests to another domain, not the domain the JavaScript originated from.
|
||||||
|
//
|
||||||
|
// http://en.wikipedia.org/wiki/Cross-origin_resource_sharing
|
||||||
|
// http://enable-cors.org/server.html
|
||||||
|
// http://www.html5rocks.com/en/tutorials/cors/#toc-handling-a-not-so-simple-request
|
||||||
|
type CrossOriginResourceSharing struct {
|
||||||
|
ExposeHeaders []string // list of Header names
|
||||||
|
AllowedHeaders []string // list of Header names
|
||||||
|
AllowedDomains []string // list of allowed values for Http Origin. An allowed value can be a regular expression to support subdomain matching. If empty all are allowed.
|
||||||
|
AllowedMethods []string
|
||||||
|
MaxAge int // number of seconds before requiring new Options request
|
||||||
|
CookiesAllowed bool
|
||||||
|
Container *Container
|
||||||
|
|
||||||
|
allowedOriginPatterns []*regexp.Regexp // internal field for origin regexp check.
|
||||||
|
}
|
||||||
|
|
||||||
|
// Filter is a filter function that implements the CORS flow as documented on http://enable-cors.org/server.html
|
||||||
|
// and http://www.html5rocks.com/static/images/cors_server_flowchart.png
|
||||||
|
func (c CrossOriginResourceSharing) Filter(req *Request, resp *Response, chain *FilterChain) {
|
||||||
|
origin := req.Request.Header.Get(HEADER_Origin)
|
||||||
|
if len(origin) == 0 {
|
||||||
|
if trace {
|
||||||
|
traceLogger.Print("no Http header Origin set")
|
||||||
|
}
|
||||||
|
chain.ProcessFilter(req, resp)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if !c.isOriginAllowed(origin) { // check whether this origin is allowed
|
||||||
|
if trace {
|
||||||
|
traceLogger.Printf("HTTP Origin:%s is not part of %v, neither matches any part of %v", origin, c.AllowedDomains, c.allowedOriginPatterns)
|
||||||
|
}
|
||||||
|
chain.ProcessFilter(req, resp)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if req.Request.Method != "OPTIONS" {
|
||||||
|
c.doActualRequest(req, resp)
|
||||||
|
chain.ProcessFilter(req, resp)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if acrm := req.Request.Header.Get(HEADER_AccessControlRequestMethod); acrm != "" {
|
||||||
|
c.doPreflightRequest(req, resp)
|
||||||
|
} else {
|
||||||
|
c.doActualRequest(req, resp)
|
||||||
|
chain.ProcessFilter(req, resp)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c CrossOriginResourceSharing) doActualRequest(req *Request, resp *Response) {
|
||||||
|
c.setOptionsHeaders(req, resp)
|
||||||
|
// continue processing the response
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *CrossOriginResourceSharing) doPreflightRequest(req *Request, resp *Response) {
|
||||||
|
if len(c.AllowedMethods) == 0 {
|
||||||
|
if c.Container == nil {
|
||||||
|
c.AllowedMethods = DefaultContainer.computeAllowedMethods(req)
|
||||||
|
} else {
|
||||||
|
c.AllowedMethods = c.Container.computeAllowedMethods(req)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
acrm := req.Request.Header.Get(HEADER_AccessControlRequestMethod)
|
||||||
|
if !c.isValidAccessControlRequestMethod(acrm, c.AllowedMethods) {
|
||||||
|
if trace {
|
||||||
|
traceLogger.Printf("Http header %s:%s is not in %v",
|
||||||
|
HEADER_AccessControlRequestMethod,
|
||||||
|
acrm,
|
||||||
|
c.AllowedMethods)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
acrhs := req.Request.Header.Get(HEADER_AccessControlRequestHeaders)
|
||||||
|
if len(acrhs) > 0 {
|
||||||
|
for _, each := range strings.Split(acrhs, ",") {
|
||||||
|
if !c.isValidAccessControlRequestHeader(strings.Trim(each, " ")) {
|
||||||
|
if trace {
|
||||||
|
traceLogger.Printf("Http header %s:%s is not in %v",
|
||||||
|
HEADER_AccessControlRequestHeaders,
|
||||||
|
acrhs,
|
||||||
|
c.AllowedHeaders)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
resp.AddHeader(HEADER_AccessControlAllowMethods, strings.Join(c.AllowedMethods, ","))
|
||||||
|
resp.AddHeader(HEADER_AccessControlAllowHeaders, acrhs)
|
||||||
|
c.setOptionsHeaders(req, resp)
|
||||||
|
|
||||||
|
// return http 200 response, no body
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c CrossOriginResourceSharing) setOptionsHeaders(req *Request, resp *Response) {
|
||||||
|
c.checkAndSetExposeHeaders(resp)
|
||||||
|
c.setAllowOriginHeader(req, resp)
|
||||||
|
c.checkAndSetAllowCredentials(resp)
|
||||||
|
if c.MaxAge > 0 {
|
||||||
|
resp.AddHeader(HEADER_AccessControlMaxAge, strconv.Itoa(c.MaxAge))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c CrossOriginResourceSharing) isOriginAllowed(origin string) bool {
|
||||||
|
if len(origin) == 0 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if len(c.AllowedDomains) == 0 {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
allowed := false
|
||||||
|
for _, domain := range c.AllowedDomains {
|
||||||
|
if domain == origin {
|
||||||
|
allowed = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if !allowed {
|
||||||
|
if len(c.allowedOriginPatterns) == 0 {
|
||||||
|
// compile allowed domains to allowed origin patterns
|
||||||
|
allowedOriginRegexps, err := compileRegexps(c.AllowedDomains)
|
||||||
|
if err != nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
c.allowedOriginPatterns = allowedOriginRegexps
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, pattern := range c.allowedOriginPatterns {
|
||||||
|
if allowed = pattern.MatchString(origin); allowed {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return allowed
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c CrossOriginResourceSharing) setAllowOriginHeader(req *Request, resp *Response) {
|
||||||
|
origin := req.Request.Header.Get(HEADER_Origin)
|
||||||
|
if c.isOriginAllowed(origin) {
|
||||||
|
resp.AddHeader(HEADER_AccessControlAllowOrigin, origin)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c CrossOriginResourceSharing) checkAndSetExposeHeaders(resp *Response) {
|
||||||
|
if len(c.ExposeHeaders) > 0 {
|
||||||
|
resp.AddHeader(HEADER_AccessControlExposeHeaders, strings.Join(c.ExposeHeaders, ","))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c CrossOriginResourceSharing) checkAndSetAllowCredentials(resp *Response) {
|
||||||
|
if c.CookiesAllowed {
|
||||||
|
resp.AddHeader(HEADER_AccessControlAllowCredentials, "true")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c CrossOriginResourceSharing) isValidAccessControlRequestMethod(method string, allowedMethods []string) bool {
|
||||||
|
for _, each := range allowedMethods {
|
||||||
|
if each == method {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c CrossOriginResourceSharing) isValidAccessControlRequestHeader(header string) bool {
|
||||||
|
for _, each := range c.AllowedHeaders {
|
||||||
|
if strings.ToLower(each) == strings.ToLower(header) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// Take a list of strings and compile them into a list of regular expressions.
|
||||||
|
func compileRegexps(regexpStrings []string) ([]*regexp.Regexp, error) {
|
||||||
|
regexps := []*regexp.Regexp{}
|
||||||
|
for _, regexpStr := range regexpStrings {
|
||||||
|
r, err := regexp.Compile(regexpStr)
|
||||||
|
if err != nil {
|
||||||
|
return regexps, err
|
||||||
|
}
|
||||||
|
regexps = append(regexps, r)
|
||||||
|
}
|
||||||
|
return regexps, nil
|
||||||
|
}
|
||||||
162
staging/src/k8s.io/client-go/1.4/_vendor/github.com/emicklei/go-restful/curly.go
generated
Normal file
162
staging/src/k8s.io/client-go/1.4/_vendor/github.com/emicklei/go-restful/curly.go
generated
Normal file
@@ -0,0 +1,162 @@
|
|||||||
|
package restful
|
||||||
|
|
||||||
|
// Copyright 2013 Ernest Micklei. All rights reserved.
|
||||||
|
// Use of this source code is governed by a license
|
||||||
|
// that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
"regexp"
|
||||||
|
"sort"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
// CurlyRouter expects Routes with paths that contain zero or more parameters in curly brackets.
|
||||||
|
type CurlyRouter struct{}
|
||||||
|
|
||||||
|
// SelectRoute is part of the Router interface and returns the best match
|
||||||
|
// for the WebService and its Route for the given Request.
|
||||||
|
func (c CurlyRouter) SelectRoute(
|
||||||
|
webServices []*WebService,
|
||||||
|
httpRequest *http.Request) (selectedService *WebService, selected *Route, err error) {
|
||||||
|
|
||||||
|
requestTokens := tokenizePath(httpRequest.URL.Path)
|
||||||
|
|
||||||
|
detectedService := c.detectWebService(requestTokens, webServices)
|
||||||
|
if detectedService == nil {
|
||||||
|
if trace {
|
||||||
|
traceLogger.Printf("no WebService was found to match URL path:%s\n", httpRequest.URL.Path)
|
||||||
|
}
|
||||||
|
return nil, nil, NewError(http.StatusNotFound, "404: Page Not Found")
|
||||||
|
}
|
||||||
|
candidateRoutes := c.selectRoutes(detectedService, requestTokens)
|
||||||
|
if len(candidateRoutes) == 0 {
|
||||||
|
if trace {
|
||||||
|
traceLogger.Printf("no Route in WebService with path %s was found to match URL path:%s\n", detectedService.rootPath, httpRequest.URL.Path)
|
||||||
|
}
|
||||||
|
return detectedService, nil, NewError(http.StatusNotFound, "404: Page Not Found")
|
||||||
|
}
|
||||||
|
selectedRoute, err := c.detectRoute(candidateRoutes, httpRequest)
|
||||||
|
if selectedRoute == nil {
|
||||||
|
return detectedService, nil, err
|
||||||
|
}
|
||||||
|
return detectedService, selectedRoute, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// selectRoutes return a collection of Route from a WebService that matches the path tokens from the request.
|
||||||
|
func (c CurlyRouter) selectRoutes(ws *WebService, requestTokens []string) sortableCurlyRoutes {
|
||||||
|
candidates := sortableCurlyRoutes{}
|
||||||
|
for _, each := range ws.routes {
|
||||||
|
matches, paramCount, staticCount := c.matchesRouteByPathTokens(each.pathParts, requestTokens)
|
||||||
|
if matches {
|
||||||
|
candidates.add(curlyRoute{each, paramCount, staticCount}) // TODO make sure Routes() return pointers?
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sort.Sort(sort.Reverse(candidates))
|
||||||
|
return candidates
|
||||||
|
}
|
||||||
|
|
||||||
|
// matchesRouteByPathTokens computes whether it matches, howmany parameters do match and what the number of static path elements are.
|
||||||
|
func (c CurlyRouter) matchesRouteByPathTokens(routeTokens, requestTokens []string) (matches bool, paramCount int, staticCount int) {
|
||||||
|
if len(routeTokens) < len(requestTokens) {
|
||||||
|
// proceed in matching only if last routeToken is wildcard
|
||||||
|
count := len(routeTokens)
|
||||||
|
if count == 0 || !strings.HasSuffix(routeTokens[count-1], "*}") {
|
||||||
|
return false, 0, 0
|
||||||
|
}
|
||||||
|
// proceed
|
||||||
|
}
|
||||||
|
for i, routeToken := range routeTokens {
|
||||||
|
if i == len(requestTokens) {
|
||||||
|
// reached end of request path
|
||||||
|
return false, 0, 0
|
||||||
|
}
|
||||||
|
requestToken := requestTokens[i]
|
||||||
|
if strings.HasPrefix(routeToken, "{") {
|
||||||
|
paramCount++
|
||||||
|
if colon := strings.Index(routeToken, ":"); colon != -1 {
|
||||||
|
// match by regex
|
||||||
|
matchesToken, matchesRemainder := c.regularMatchesPathToken(routeToken, colon, requestToken)
|
||||||
|
if !matchesToken {
|
||||||
|
return false, 0, 0
|
||||||
|
}
|
||||||
|
if matchesRemainder {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else { // no { prefix
|
||||||
|
if requestToken != routeToken {
|
||||||
|
return false, 0, 0
|
||||||
|
}
|
||||||
|
staticCount++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true, paramCount, staticCount
|
||||||
|
}
|
||||||
|
|
||||||
|
// regularMatchesPathToken tests whether the regular expression part of routeToken matches the requestToken or all remaining tokens
|
||||||
|
// format routeToken is {someVar:someExpression}, e.g. {zipcode:[\d][\d][\d][\d][A-Z][A-Z]}
|
||||||
|
func (c CurlyRouter) regularMatchesPathToken(routeToken string, colon int, requestToken string) (matchesToken bool, matchesRemainder bool) {
|
||||||
|
regPart := routeToken[colon+1 : len(routeToken)-1]
|
||||||
|
if regPart == "*" {
|
||||||
|
if trace {
|
||||||
|
traceLogger.Printf("wildcard parameter detected in route token %s that matches %s\n", routeToken, requestToken)
|
||||||
|
}
|
||||||
|
return true, true
|
||||||
|
}
|
||||||
|
matched, err := regexp.MatchString(regPart, requestToken)
|
||||||
|
return (matched && err == nil), false
|
||||||
|
}
|
||||||
|
|
||||||
|
// detectRoute selectes from a list of Route the first match by inspecting both the Accept and Content-Type
|
||||||
|
// headers of the Request. See also RouterJSR311 in jsr311.go
|
||||||
|
func (c CurlyRouter) detectRoute(candidateRoutes sortableCurlyRoutes, httpRequest *http.Request) (*Route, error) {
|
||||||
|
// tracing is done inside detectRoute
|
||||||
|
return RouterJSR311{}.detectRoute(candidateRoutes.routes(), httpRequest)
|
||||||
|
}
|
||||||
|
|
||||||
|
// detectWebService returns the best matching webService given the list of path tokens.
|
||||||
|
// see also computeWebserviceScore
|
||||||
|
func (c CurlyRouter) detectWebService(requestTokens []string, webServices []*WebService) *WebService {
|
||||||
|
var best *WebService
|
||||||
|
score := -1
|
||||||
|
for _, each := range webServices {
|
||||||
|
matches, eachScore := c.computeWebserviceScore(requestTokens, each.pathExpr.tokens)
|
||||||
|
if matches && (eachScore > score) {
|
||||||
|
best = each
|
||||||
|
score = eachScore
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return best
|
||||||
|
}
|
||||||
|
|
||||||
|
// computeWebserviceScore returns whether tokens match and
|
||||||
|
// the weighted score of the longest matching consecutive tokens from the beginning.
|
||||||
|
func (c CurlyRouter) computeWebserviceScore(requestTokens []string, tokens []string) (bool, int) {
|
||||||
|
if len(tokens) > len(requestTokens) {
|
||||||
|
return false, 0
|
||||||
|
}
|
||||||
|
score := 0
|
||||||
|
for i := 0; i < len(tokens); i++ {
|
||||||
|
each := requestTokens[i]
|
||||||
|
other := tokens[i]
|
||||||
|
if len(each) == 0 && len(other) == 0 {
|
||||||
|
score++
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if len(other) > 0 && strings.HasPrefix(other, "{") {
|
||||||
|
// no empty match
|
||||||
|
if len(each) == 0 {
|
||||||
|
return false, score
|
||||||
|
}
|
||||||
|
score += 1
|
||||||
|
} else {
|
||||||
|
// not a parameter
|
||||||
|
if each != other {
|
||||||
|
return false, score
|
||||||
|
}
|
||||||
|
score += (len(tokens) - i) * 10 //fuzzy
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true, score
|
||||||
|
}
|
||||||
52
staging/src/k8s.io/client-go/1.4/_vendor/github.com/emicklei/go-restful/curly_route.go
generated
Normal file
52
staging/src/k8s.io/client-go/1.4/_vendor/github.com/emicklei/go-restful/curly_route.go
generated
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
package restful
|
||||||
|
|
||||||
|
// Copyright 2013 Ernest Micklei. All rights reserved.
|
||||||
|
// Use of this source code is governed by a license
|
||||||
|
// that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// curlyRoute exits for sorting Routes by the CurlyRouter based on number of parameters and number of static path elements.
|
||||||
|
type curlyRoute struct {
|
||||||
|
route Route
|
||||||
|
paramCount int
|
||||||
|
staticCount int
|
||||||
|
}
|
||||||
|
|
||||||
|
type sortableCurlyRoutes []curlyRoute
|
||||||
|
|
||||||
|
func (s *sortableCurlyRoutes) add(route curlyRoute) {
|
||||||
|
*s = append(*s, route)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s sortableCurlyRoutes) routes() (routes []Route) {
|
||||||
|
for _, each := range s {
|
||||||
|
routes = append(routes, each.route) // TODO change return type
|
||||||
|
}
|
||||||
|
return routes
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s sortableCurlyRoutes) Len() int {
|
||||||
|
return len(s)
|
||||||
|
}
|
||||||
|
func (s sortableCurlyRoutes) Swap(i, j int) {
|
||||||
|
s[i], s[j] = s[j], s[i]
|
||||||
|
}
|
||||||
|
func (s sortableCurlyRoutes) Less(i, j int) bool {
|
||||||
|
ci := s[i]
|
||||||
|
cj := s[j]
|
||||||
|
|
||||||
|
// primary key
|
||||||
|
if ci.staticCount < cj.staticCount {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
if ci.staticCount > cj.staticCount {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
// secundary key
|
||||||
|
if ci.paramCount < cj.paramCount {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
if ci.paramCount > cj.paramCount {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return ci.route.Path < cj.route.Path
|
||||||
|
}
|
||||||
196
staging/src/k8s.io/client-go/1.4/_vendor/github.com/emicklei/go-restful/doc.go
generated
Normal file
196
staging/src/k8s.io/client-go/1.4/_vendor/github.com/emicklei/go-restful/doc.go
generated
Normal file
@@ -0,0 +1,196 @@
|
|||||||
|
/*
|
||||||
|
Package restful, a lean package for creating REST-style WebServices without magic.
|
||||||
|
|
||||||
|
WebServices and Routes
|
||||||
|
|
||||||
|
A WebService has a collection of Route objects that dispatch incoming Http Requests to a function calls.
|
||||||
|
Typically, a WebService has a root path (e.g. /users) and defines common MIME types for its routes.
|
||||||
|
WebServices must be added to a container (see below) in order to handler Http requests from a server.
|
||||||
|
|
||||||
|
A Route is defined by a HTTP method, an URL path and (optionally) the MIME types it consumes (Content-Type) and produces (Accept).
|
||||||
|
This package has the logic to find the best matching Route and if found, call its Function.
|
||||||
|
|
||||||
|
ws := new(restful.WebService)
|
||||||
|
ws.
|
||||||
|
Path("/users").
|
||||||
|
Consumes(restful.MIME_JSON, restful.MIME_XML).
|
||||||
|
Produces(restful.MIME_JSON, restful.MIME_XML)
|
||||||
|
|
||||||
|
ws.Route(ws.GET("/{user-id}").To(u.findUser)) // u is a UserResource
|
||||||
|
|
||||||
|
...
|
||||||
|
|
||||||
|
// GET http://localhost:8080/users/1
|
||||||
|
func (u UserResource) findUser(request *restful.Request, response *restful.Response) {
|
||||||
|
id := request.PathParameter("user-id")
|
||||||
|
...
|
||||||
|
}
|
||||||
|
|
||||||
|
The (*Request, *Response) arguments provide functions for reading information from the request and writing information back to the response.
|
||||||
|
|
||||||
|
See the example https://github.com/emicklei/go-restful/blob/master/examples/restful-user-resource.go with a full implementation.
|
||||||
|
|
||||||
|
Regular expression matching Routes
|
||||||
|
|
||||||
|
A Route parameter can be specified using the format "uri/{var[:regexp]}" or the special version "uri/{var:*}" for matching the tail of the path.
|
||||||
|
For example, /persons/{name:[A-Z][A-Z]} can be used to restrict values for the parameter "name" to only contain capital alphabetic characters.
|
||||||
|
Regular expressions must use the standard Go syntax as described in the regexp package. (https://code.google.com/p/re2/wiki/Syntax)
|
||||||
|
This feature requires the use of a CurlyRouter.
|
||||||
|
|
||||||
|
Containers
|
||||||
|
|
||||||
|
A Container holds a collection of WebServices, Filters and a http.ServeMux for multiplexing http requests.
|
||||||
|
Using the statements "restful.Add(...) and restful.Filter(...)" will register WebServices and Filters to the Default Container.
|
||||||
|
The Default container of go-restful uses the http.DefaultServeMux.
|
||||||
|
You can create your own Container and create a new http.Server for that particular container.
|
||||||
|
|
||||||
|
container := restful.NewContainer()
|
||||||
|
server := &http.Server{Addr: ":8081", Handler: container}
|
||||||
|
|
||||||
|
Filters
|
||||||
|
|
||||||
|
A filter dynamically intercepts requests and responses to transform or use the information contained in the requests or responses.
|
||||||
|
You can use filters to perform generic logging, measurement, authentication, redirect, set response headers etc.
|
||||||
|
In the restful package there are three hooks into the request,response flow where filters can be added.
|
||||||
|
Each filter must define a FilterFunction:
|
||||||
|
|
||||||
|
func (req *restful.Request, resp *restful.Response, chain *restful.FilterChain)
|
||||||
|
|
||||||
|
Use the following statement to pass the request,response pair to the next filter or RouteFunction
|
||||||
|
|
||||||
|
chain.ProcessFilter(req, resp)
|
||||||
|
|
||||||
|
Container Filters
|
||||||
|
|
||||||
|
These are processed before any registered WebService.
|
||||||
|
|
||||||
|
// install a (global) filter for the default container (processed before any webservice)
|
||||||
|
restful.Filter(globalLogging)
|
||||||
|
|
||||||
|
WebService Filters
|
||||||
|
|
||||||
|
These are processed before any Route of a WebService.
|
||||||
|
|
||||||
|
// install a webservice filter (processed before any route)
|
||||||
|
ws.Filter(webserviceLogging).Filter(measureTime)
|
||||||
|
|
||||||
|
|
||||||
|
Route Filters
|
||||||
|
|
||||||
|
These are processed before calling the function associated with the Route.
|
||||||
|
|
||||||
|
// install 2 chained route filters (processed before calling findUser)
|
||||||
|
ws.Route(ws.GET("/{user-id}").Filter(routeLogging).Filter(NewCountFilter().routeCounter).To(findUser))
|
||||||
|
|
||||||
|
See the example https://github.com/emicklei/go-restful/blob/master/examples/restful-filters.go with full implementations.
|
||||||
|
|
||||||
|
Response Encoding
|
||||||
|
|
||||||
|
Two encodings are supported: gzip and deflate. To enable this for all responses:
|
||||||
|
|
||||||
|
restful.DefaultContainer.EnableContentEncoding(true)
|
||||||
|
|
||||||
|
If a Http request includes the Accept-Encoding header then the response content will be compressed using the specified encoding.
|
||||||
|
Alternatively, you can create a Filter that performs the encoding and install it per WebService or Route.
|
||||||
|
|
||||||
|
See the example https://github.com/emicklei/go-restful/blob/master/examples/restful-encoding-filter.go
|
||||||
|
|
||||||
|
OPTIONS support
|
||||||
|
|
||||||
|
By installing a pre-defined container filter, your Webservice(s) can respond to the OPTIONS Http request.
|
||||||
|
|
||||||
|
Filter(OPTIONSFilter())
|
||||||
|
|
||||||
|
CORS
|
||||||
|
|
||||||
|
By installing the filter of a CrossOriginResourceSharing (CORS), your WebService(s) can handle CORS requests.
|
||||||
|
|
||||||
|
cors := CrossOriginResourceSharing{ExposeHeaders: []string{"X-My-Header"}, CookiesAllowed: false, Container: DefaultContainer}
|
||||||
|
Filter(cors.Filter)
|
||||||
|
|
||||||
|
Error Handling
|
||||||
|
|
||||||
|
Unexpected things happen. If a request cannot be processed because of a failure, your service needs to tell via the response what happened and why.
|
||||||
|
For this reason HTTP status codes exist and it is important to use the correct code in every exceptional situation.
|
||||||
|
|
||||||
|
400: Bad Request
|
||||||
|
|
||||||
|
If path or query parameters are not valid (content or type) then use http.StatusBadRequest.
|
||||||
|
|
||||||
|
404: Not Found
|
||||||
|
|
||||||
|
Despite a valid URI, the resource requested may not be available
|
||||||
|
|
||||||
|
500: Internal Server Error
|
||||||
|
|
||||||
|
If the application logic could not process the request (or write the response) then use http.StatusInternalServerError.
|
||||||
|
|
||||||
|
405: Method Not Allowed
|
||||||
|
|
||||||
|
The request has a valid URL but the method (GET,PUT,POST,...) is not allowed.
|
||||||
|
|
||||||
|
406: Not Acceptable
|
||||||
|
|
||||||
|
The request does not have or has an unknown Accept Header set for this operation.
|
||||||
|
|
||||||
|
415: Unsupported Media Type
|
||||||
|
|
||||||
|
The request does not have or has an unknown Content-Type Header set for this operation.
|
||||||
|
|
||||||
|
ServiceError
|
||||||
|
|
||||||
|
In addition to setting the correct (error) Http status code, you can choose to write a ServiceError message on the response.
|
||||||
|
|
||||||
|
Performance options
|
||||||
|
|
||||||
|
This package has several options that affect the performance of your service. It is important to understand them and how you can change it.
|
||||||
|
|
||||||
|
restful.DefaultContainer.Router(CurlyRouter{})
|
||||||
|
|
||||||
|
The default router is the RouterJSR311 which is an implementation of its spec (http://jsr311.java.net/nonav/releases/1.1/spec/spec.html).
|
||||||
|
However, it uses regular expressions for all its routes which, depending on your usecase, may consume a significant amount of time.
|
||||||
|
The CurlyRouter implementation is more lightweight that also allows you to use wildcards and expressions, but only if needed.
|
||||||
|
|
||||||
|
restful.DefaultContainer.DoNotRecover(true)
|
||||||
|
|
||||||
|
DoNotRecover controls whether panics will be caught to return HTTP 500.
|
||||||
|
If set to true, Route functions are responsible for handling any error situation.
|
||||||
|
Default value is false; it will recover from panics. This has performance implications.
|
||||||
|
|
||||||
|
restful.SetCacheReadEntity(false)
|
||||||
|
|
||||||
|
SetCacheReadEntity controls whether the response data ([]byte) is cached such that ReadEntity is repeatable.
|
||||||
|
If you expect to read large amounts of payload data, and you do not use this feature, you should set it to false.
|
||||||
|
|
||||||
|
restful.SetCompressorProvider(NewBoundedCachedCompressors(20, 20))
|
||||||
|
|
||||||
|
If content encoding is enabled then the default strategy for getting new gzip/zlib writers and readers is to use a sync.Pool.
|
||||||
|
Because writers are expensive structures, performance is even more improved when using a preloaded cache. You can also inject your own implementation.
|
||||||
|
|
||||||
|
Trouble shooting
|
||||||
|
|
||||||
|
This package has the means to produce detail logging of the complete Http request matching process and filter invocation.
|
||||||
|
Enabling this feature requires you to set an implementation of restful.StdLogger (e.g. log.Logger) instance such as:
|
||||||
|
|
||||||
|
restful.TraceLogger(log.New(os.Stdout, "[restful] ", log.LstdFlags|log.Lshortfile))
|
||||||
|
|
||||||
|
Logging
|
||||||
|
|
||||||
|
The restful.SetLogger() method allows you to override the logger used by the package. By default restful
|
||||||
|
uses the standard library `log` package and logs to stdout. Different logging packages are supported as
|
||||||
|
long as they conform to `StdLogger` interface defined in the `log` sub-package, writing an adapter for your
|
||||||
|
preferred package is simple.
|
||||||
|
|
||||||
|
Resources
|
||||||
|
|
||||||
|
[project]: https://github.com/emicklei/go-restful
|
||||||
|
|
||||||
|
[examples]: https://github.com/emicklei/go-restful/blob/master/examples
|
||||||
|
|
||||||
|
[design]: http://ernestmicklei.com/2012/11/11/go-restful-api-design/
|
||||||
|
|
||||||
|
[showcases]: https://github.com/emicklei/mora, https://github.com/emicklei/landskape
|
||||||
|
|
||||||
|
(c) 2012-2015, http://ernestmicklei.com. MIT License
|
||||||
|
*/
|
||||||
|
package restful
|
||||||
163
staging/src/k8s.io/client-go/1.4/_vendor/github.com/emicklei/go-restful/entity_accessors.go
generated
Normal file
163
staging/src/k8s.io/client-go/1.4/_vendor/github.com/emicklei/go-restful/entity_accessors.go
generated
Normal file
@@ -0,0 +1,163 @@
|
|||||||
|
package restful
|
||||||
|
|
||||||
|
// Copyright 2015 Ernest Micklei. All rights reserved.
|
||||||
|
// Use of this source code is governed by a license
|
||||||
|
// that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"encoding/xml"
|
||||||
|
"strings"
|
||||||
|
"sync"
|
||||||
|
)
|
||||||
|
|
||||||
|
// EntityReaderWriter can read and write values using an encoding such as JSON,XML.
|
||||||
|
type EntityReaderWriter interface {
|
||||||
|
// Read a serialized version of the value from the request.
|
||||||
|
// The Request may have a decompressing reader. Depends on Content-Encoding.
|
||||||
|
Read(req *Request, v interface{}) error
|
||||||
|
|
||||||
|
// Write a serialized version of the value on the response.
|
||||||
|
// The Response may have a compressing writer. Depends on Accept-Encoding.
|
||||||
|
// status should be a valid Http Status code
|
||||||
|
Write(resp *Response, status int, v interface{}) error
|
||||||
|
}
|
||||||
|
|
||||||
|
// entityAccessRegistry is a singleton
|
||||||
|
var entityAccessRegistry = &entityReaderWriters{
|
||||||
|
protection: new(sync.RWMutex),
|
||||||
|
accessors: map[string]EntityReaderWriter{},
|
||||||
|
}
|
||||||
|
|
||||||
|
// entityReaderWriters associates MIME to an EntityReaderWriter
|
||||||
|
type entityReaderWriters struct {
|
||||||
|
protection *sync.RWMutex
|
||||||
|
accessors map[string]EntityReaderWriter
|
||||||
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
RegisterEntityAccessor(MIME_JSON, NewEntityAccessorJSON(MIME_JSON))
|
||||||
|
RegisterEntityAccessor(MIME_XML, NewEntityAccessorXML(MIME_XML))
|
||||||
|
}
|
||||||
|
|
||||||
|
// RegisterEntityAccessor add/overrides the ReaderWriter for encoding content with this MIME type.
|
||||||
|
func RegisterEntityAccessor(mime string, erw EntityReaderWriter) {
|
||||||
|
entityAccessRegistry.protection.Lock()
|
||||||
|
defer entityAccessRegistry.protection.Unlock()
|
||||||
|
entityAccessRegistry.accessors[mime] = erw
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewEntityAccessorJSON returns a new EntityReaderWriter for accessing JSON content.
|
||||||
|
// This package is already initialized with such an accessor using the MIME_JSON contentType.
|
||||||
|
func NewEntityAccessorJSON(contentType string) EntityReaderWriter {
|
||||||
|
return entityJSONAccess{ContentType: contentType}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewEntityAccessorXML returns a new EntityReaderWriter for accessing XML content.
|
||||||
|
// This package is already initialized with such an accessor using the MIME_XML contentType.
|
||||||
|
func NewEntityAccessorXML(contentType string) EntityReaderWriter {
|
||||||
|
return entityXMLAccess{ContentType: contentType}
|
||||||
|
}
|
||||||
|
|
||||||
|
// accessorAt returns the registered ReaderWriter for this MIME type.
|
||||||
|
func (r *entityReaderWriters) accessorAt(mime string) (EntityReaderWriter, bool) {
|
||||||
|
r.protection.RLock()
|
||||||
|
defer r.protection.RUnlock()
|
||||||
|
er, ok := r.accessors[mime]
|
||||||
|
if !ok {
|
||||||
|
// retry with reverse lookup
|
||||||
|
// more expensive but we are in an exceptional situation anyway
|
||||||
|
for k, v := range r.accessors {
|
||||||
|
if strings.Contains(mime, k) {
|
||||||
|
return v, true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return er, ok
|
||||||
|
}
|
||||||
|
|
||||||
|
// entityXMLAccess is a EntityReaderWriter for XML encoding
|
||||||
|
type entityXMLAccess struct {
|
||||||
|
// This is used for setting the Content-Type header when writing
|
||||||
|
ContentType string
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read unmarshalls the value from XML
|
||||||
|
func (e entityXMLAccess) Read(req *Request, v interface{}) error {
|
||||||
|
return xml.NewDecoder(req.Request.Body).Decode(v)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write marshalls the value to JSON and set the Content-Type Header.
|
||||||
|
func (e entityXMLAccess) Write(resp *Response, status int, v interface{}) error {
|
||||||
|
return writeXML(resp, status, e.ContentType, v)
|
||||||
|
}
|
||||||
|
|
||||||
|
// writeXML marshalls the value to JSON and set the Content-Type Header.
|
||||||
|
func writeXML(resp *Response, status int, contentType string, v interface{}) error {
|
||||||
|
if v == nil {
|
||||||
|
resp.WriteHeader(status)
|
||||||
|
// do not write a nil representation
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
if resp.prettyPrint {
|
||||||
|
// pretty output must be created and written explicitly
|
||||||
|
output, err := xml.MarshalIndent(v, " ", " ")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
resp.Header().Set(HEADER_ContentType, contentType)
|
||||||
|
resp.WriteHeader(status)
|
||||||
|
_, err = resp.Write([]byte(xml.Header))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
_, err = resp.Write(output)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
// not-so-pretty
|
||||||
|
resp.Header().Set(HEADER_ContentType, contentType)
|
||||||
|
resp.WriteHeader(status)
|
||||||
|
return xml.NewEncoder(resp).Encode(v)
|
||||||
|
}
|
||||||
|
|
||||||
|
// entityJSONAccess is a EntityReaderWriter for JSON encoding
|
||||||
|
type entityJSONAccess struct {
|
||||||
|
// This is used for setting the Content-Type header when writing
|
||||||
|
ContentType string
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read unmarshalls the value from JSON
|
||||||
|
func (e entityJSONAccess) Read(req *Request, v interface{}) error {
|
||||||
|
decoder := json.NewDecoder(req.Request.Body)
|
||||||
|
decoder.UseNumber()
|
||||||
|
return decoder.Decode(v)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write marshalls the value to JSON and set the Content-Type Header.
|
||||||
|
func (e entityJSONAccess) Write(resp *Response, status int, v interface{}) error {
|
||||||
|
return writeJSON(resp, status, e.ContentType, v)
|
||||||
|
}
|
||||||
|
|
||||||
|
// write marshalls the value to JSON and set the Content-Type Header.
|
||||||
|
func writeJSON(resp *Response, status int, contentType string, v interface{}) error {
|
||||||
|
if v == nil {
|
||||||
|
resp.WriteHeader(status)
|
||||||
|
// do not write a nil representation
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
if resp.prettyPrint {
|
||||||
|
// pretty output must be created and written explicitly
|
||||||
|
output, err := json.MarshalIndent(v, " ", " ")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
resp.Header().Set(HEADER_ContentType, contentType)
|
||||||
|
resp.WriteHeader(status)
|
||||||
|
_, err = resp.Write(output)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
// not-so-pretty
|
||||||
|
resp.Header().Set(HEADER_ContentType, contentType)
|
||||||
|
resp.WriteHeader(status)
|
||||||
|
return json.NewEncoder(resp).Encode(v)
|
||||||
|
}
|
||||||
26
staging/src/k8s.io/client-go/1.4/_vendor/github.com/emicklei/go-restful/filter.go
generated
Normal file
26
staging/src/k8s.io/client-go/1.4/_vendor/github.com/emicklei/go-restful/filter.go
generated
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
package restful
|
||||||
|
|
||||||
|
// Copyright 2013 Ernest Micklei. All rights reserved.
|
||||||
|
// Use of this source code is governed by a license
|
||||||
|
// that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// FilterChain is a request scoped object to process one or more filters before calling the target RouteFunction.
|
||||||
|
type FilterChain struct {
|
||||||
|
Filters []FilterFunction // ordered list of FilterFunction
|
||||||
|
Index int // index into filters that is currently in progress
|
||||||
|
Target RouteFunction // function to call after passing all filters
|
||||||
|
}
|
||||||
|
|
||||||
|
// ProcessFilter passes the request,response pair through the next of Filters.
|
||||||
|
// Each filter can decide to proceed to the next Filter or handle the Response itself.
|
||||||
|
func (f *FilterChain) ProcessFilter(request *Request, response *Response) {
|
||||||
|
if f.Index < len(f.Filters) {
|
||||||
|
f.Index++
|
||||||
|
f.Filters[f.Index-1](request, response, f)
|
||||||
|
} else {
|
||||||
|
f.Target(request, response)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// FilterFunction definitions must call ProcessFilter on the FilterChain to pass on the control and eventually call the RouteFunction
|
||||||
|
type FilterFunction func(*Request, *Response, *FilterChain)
|
||||||
248
staging/src/k8s.io/client-go/1.4/_vendor/github.com/emicklei/go-restful/jsr311.go
generated
Normal file
248
staging/src/k8s.io/client-go/1.4/_vendor/github.com/emicklei/go-restful/jsr311.go
generated
Normal file
@@ -0,0 +1,248 @@
|
|||||||
|
package restful
|
||||||
|
|
||||||
|
// Copyright 2013 Ernest Micklei. All rights reserved.
|
||||||
|
// Use of this source code is governed by a license
|
||||||
|
// that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
"sort"
|
||||||
|
)
|
||||||
|
|
||||||
|
// RouterJSR311 implements the flow for matching Requests to Routes (and consequently Resource Functions)
|
||||||
|
// as specified by the JSR311 http://jsr311.java.net/nonav/releases/1.1/spec/spec.html.
|
||||||
|
// RouterJSR311 implements the Router interface.
|
||||||
|
// Concept of locators is not implemented.
|
||||||
|
type RouterJSR311 struct{}
|
||||||
|
|
||||||
|
// SelectRoute is part of the Router interface and returns the best match
|
||||||
|
// for the WebService and its Route for the given Request.
|
||||||
|
func (r RouterJSR311) SelectRoute(
|
||||||
|
webServices []*WebService,
|
||||||
|
httpRequest *http.Request) (selectedService *WebService, selectedRoute *Route, err error) {
|
||||||
|
|
||||||
|
// Identify the root resource class (WebService)
|
||||||
|
dispatcher, finalMatch, err := r.detectDispatcher(httpRequest.URL.Path, webServices)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, NewError(http.StatusNotFound, "")
|
||||||
|
}
|
||||||
|
// Obtain the set of candidate methods (Routes)
|
||||||
|
routes := r.selectRoutes(dispatcher, finalMatch)
|
||||||
|
if len(routes) == 0 {
|
||||||
|
return dispatcher, nil, NewError(http.StatusNotFound, "404: Page Not Found")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Identify the method (Route) that will handle the request
|
||||||
|
route, ok := r.detectRoute(routes, httpRequest)
|
||||||
|
return dispatcher, route, ok
|
||||||
|
}
|
||||||
|
|
||||||
|
// http://jsr311.java.net/nonav/releases/1.1/spec/spec3.html#x3-360003.7.2
|
||||||
|
func (r RouterJSR311) detectRoute(routes []Route, httpRequest *http.Request) (*Route, error) {
|
||||||
|
// http method
|
||||||
|
methodOk := []Route{}
|
||||||
|
for _, each := range routes {
|
||||||
|
if httpRequest.Method == each.Method {
|
||||||
|
methodOk = append(methodOk, each)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if len(methodOk) == 0 {
|
||||||
|
if trace {
|
||||||
|
traceLogger.Printf("no Route found (in %d routes) that matches HTTP method %s\n", len(routes), httpRequest.Method)
|
||||||
|
}
|
||||||
|
return nil, NewError(http.StatusMethodNotAllowed, "405: Method Not Allowed")
|
||||||
|
}
|
||||||
|
inputMediaOk := methodOk
|
||||||
|
|
||||||
|
// content-type
|
||||||
|
contentType := httpRequest.Header.Get(HEADER_ContentType)
|
||||||
|
inputMediaOk = []Route{}
|
||||||
|
for _, each := range methodOk {
|
||||||
|
if each.matchesContentType(contentType) {
|
||||||
|
inputMediaOk = append(inputMediaOk, each)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if len(inputMediaOk) == 0 {
|
||||||
|
if trace {
|
||||||
|
traceLogger.Printf("no Route found (from %d) that matches HTTP Content-Type: %s\n", len(methodOk), contentType)
|
||||||
|
}
|
||||||
|
return nil, NewError(http.StatusUnsupportedMediaType, "415: Unsupported Media Type")
|
||||||
|
}
|
||||||
|
|
||||||
|
// accept
|
||||||
|
outputMediaOk := []Route{}
|
||||||
|
accept := httpRequest.Header.Get(HEADER_Accept)
|
||||||
|
if len(accept) == 0 {
|
||||||
|
accept = "*/*"
|
||||||
|
}
|
||||||
|
for _, each := range inputMediaOk {
|
||||||
|
if each.matchesAccept(accept) {
|
||||||
|
outputMediaOk = append(outputMediaOk, each)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if len(outputMediaOk) == 0 {
|
||||||
|
if trace {
|
||||||
|
traceLogger.Printf("no Route found (from %d) that matches HTTP Accept: %s\n", len(inputMediaOk), accept)
|
||||||
|
}
|
||||||
|
return nil, NewError(http.StatusNotAcceptable, "406: Not Acceptable")
|
||||||
|
}
|
||||||
|
// return r.bestMatchByMedia(outputMediaOk, contentType, accept), nil
|
||||||
|
return &outputMediaOk[0], nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// http://jsr311.java.net/nonav/releases/1.1/spec/spec3.html#x3-360003.7.2
|
||||||
|
// n/m > n/* > */*
|
||||||
|
func (r RouterJSR311) bestMatchByMedia(routes []Route, contentType string, accept string) *Route {
|
||||||
|
// TODO
|
||||||
|
return &routes[0]
|
||||||
|
}
|
||||||
|
|
||||||
|
// http://jsr311.java.net/nonav/releases/1.1/spec/spec3.html#x3-360003.7.2 (step 2)
|
||||||
|
func (r RouterJSR311) selectRoutes(dispatcher *WebService, pathRemainder string) []Route {
|
||||||
|
filtered := &sortableRouteCandidates{}
|
||||||
|
for _, each := range dispatcher.Routes() {
|
||||||
|
pathExpr := each.pathExpr
|
||||||
|
matches := pathExpr.Matcher.FindStringSubmatch(pathRemainder)
|
||||||
|
if matches != nil {
|
||||||
|
lastMatch := matches[len(matches)-1]
|
||||||
|
if len(lastMatch) == 0 || lastMatch == "/" { // do not include if value is neither empty nor ‘/’.
|
||||||
|
filtered.candidates = append(filtered.candidates,
|
||||||
|
routeCandidate{each, len(matches) - 1, pathExpr.LiteralCount, pathExpr.VarCount})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if len(filtered.candidates) == 0 {
|
||||||
|
if trace {
|
||||||
|
traceLogger.Printf("WebService on path %s has no routes that match URL path remainder:%s\n", dispatcher.rootPath, pathRemainder)
|
||||||
|
}
|
||||||
|
return []Route{}
|
||||||
|
}
|
||||||
|
sort.Sort(sort.Reverse(filtered))
|
||||||
|
|
||||||
|
// select other routes from candidates whoes expression matches rmatch
|
||||||
|
matchingRoutes := []Route{filtered.candidates[0].route}
|
||||||
|
for c := 1; c < len(filtered.candidates); c++ {
|
||||||
|
each := filtered.candidates[c]
|
||||||
|
if each.route.pathExpr.Matcher.MatchString(pathRemainder) {
|
||||||
|
matchingRoutes = append(matchingRoutes, each.route)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return matchingRoutes
|
||||||
|
}
|
||||||
|
|
||||||
|
// http://jsr311.java.net/nonav/releases/1.1/spec/spec3.html#x3-360003.7.2 (step 1)
|
||||||
|
func (r RouterJSR311) detectDispatcher(requestPath string, dispatchers []*WebService) (*WebService, string, error) {
|
||||||
|
filtered := &sortableDispatcherCandidates{}
|
||||||
|
for _, each := range dispatchers {
|
||||||
|
matches := each.pathExpr.Matcher.FindStringSubmatch(requestPath)
|
||||||
|
if matches != nil {
|
||||||
|
filtered.candidates = append(filtered.candidates,
|
||||||
|
dispatcherCandidate{each, matches[len(matches)-1], len(matches), each.pathExpr.LiteralCount, each.pathExpr.VarCount})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if len(filtered.candidates) == 0 {
|
||||||
|
if trace {
|
||||||
|
traceLogger.Printf("no WebService was found to match URL path:%s\n", requestPath)
|
||||||
|
}
|
||||||
|
return nil, "", errors.New("not found")
|
||||||
|
}
|
||||||
|
sort.Sort(sort.Reverse(filtered))
|
||||||
|
return filtered.candidates[0].dispatcher, filtered.candidates[0].finalMatch, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Types and functions to support the sorting of Routes
|
||||||
|
|
||||||
|
type routeCandidate struct {
|
||||||
|
route Route
|
||||||
|
matchesCount int // the number of capturing groups
|
||||||
|
literalCount int // the number of literal characters (means those not resulting from template variable substitution)
|
||||||
|
nonDefaultCount int // the number of capturing groups with non-default regular expressions (i.e. not ‘([^ /]+?)’)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r routeCandidate) expressionToMatch() string {
|
||||||
|
return r.route.pathExpr.Source
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r routeCandidate) String() string {
|
||||||
|
return fmt.Sprintf("(m=%d,l=%d,n=%d)", r.matchesCount, r.literalCount, r.nonDefaultCount)
|
||||||
|
}
|
||||||
|
|
||||||
|
type sortableRouteCandidates struct {
|
||||||
|
candidates []routeCandidate
|
||||||
|
}
|
||||||
|
|
||||||
|
func (rcs *sortableRouteCandidates) Len() int {
|
||||||
|
return len(rcs.candidates)
|
||||||
|
}
|
||||||
|
func (rcs *sortableRouteCandidates) Swap(i, j int) {
|
||||||
|
rcs.candidates[i], rcs.candidates[j] = rcs.candidates[j], rcs.candidates[i]
|
||||||
|
}
|
||||||
|
func (rcs *sortableRouteCandidates) Less(i, j int) bool {
|
||||||
|
ci := rcs.candidates[i]
|
||||||
|
cj := rcs.candidates[j]
|
||||||
|
// primary key
|
||||||
|
if ci.literalCount < cj.literalCount {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
if ci.literalCount > cj.literalCount {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
// secundary key
|
||||||
|
if ci.matchesCount < cj.matchesCount {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
if ci.matchesCount > cj.matchesCount {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
// tertiary key
|
||||||
|
if ci.nonDefaultCount < cj.nonDefaultCount {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
if ci.nonDefaultCount > cj.nonDefaultCount {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
// quaternary key ("source" is interpreted as Path)
|
||||||
|
return ci.route.Path < cj.route.Path
|
||||||
|
}
|
||||||
|
|
||||||
|
// Types and functions to support the sorting of Dispatchers
|
||||||
|
|
||||||
|
type dispatcherCandidate struct {
|
||||||
|
dispatcher *WebService
|
||||||
|
finalMatch string
|
||||||
|
matchesCount int // the number of capturing groups
|
||||||
|
literalCount int // the number of literal characters (means those not resulting from template variable substitution)
|
||||||
|
nonDefaultCount int // the number of capturing groups with non-default regular expressions (i.e. not ‘([^ /]+?)’)
|
||||||
|
}
|
||||||
|
type sortableDispatcherCandidates struct {
|
||||||
|
candidates []dispatcherCandidate
|
||||||
|
}
|
||||||
|
|
||||||
|
func (dc *sortableDispatcherCandidates) Len() int {
|
||||||
|
return len(dc.candidates)
|
||||||
|
}
|
||||||
|
func (dc *sortableDispatcherCandidates) Swap(i, j int) {
|
||||||
|
dc.candidates[i], dc.candidates[j] = dc.candidates[j], dc.candidates[i]
|
||||||
|
}
|
||||||
|
func (dc *sortableDispatcherCandidates) Less(i, j int) bool {
|
||||||
|
ci := dc.candidates[i]
|
||||||
|
cj := dc.candidates[j]
|
||||||
|
// primary key
|
||||||
|
if ci.matchesCount < cj.matchesCount {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
if ci.matchesCount > cj.matchesCount {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
// secundary key
|
||||||
|
if ci.literalCount < cj.literalCount {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
if ci.literalCount > cj.literalCount {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
// tertiary key
|
||||||
|
return ci.nonDefaultCount < cj.nonDefaultCount
|
||||||
|
}
|
||||||
31
staging/src/k8s.io/client-go/1.4/_vendor/github.com/emicklei/go-restful/log/log.go
generated
Normal file
31
staging/src/k8s.io/client-go/1.4/_vendor/github.com/emicklei/go-restful/log/log.go
generated
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
package log
|
||||||
|
|
||||||
|
import (
|
||||||
|
stdlog "log"
|
||||||
|
"os"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Logger corresponds to a minimal subset of the interface satisfied by stdlib log.Logger
|
||||||
|
type StdLogger interface {
|
||||||
|
Print(v ...interface{})
|
||||||
|
Printf(format string, v ...interface{})
|
||||||
|
}
|
||||||
|
|
||||||
|
var Logger StdLogger
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
// default Logger
|
||||||
|
SetLogger(stdlog.New(os.Stderr, "[restful] ", stdlog.LstdFlags|stdlog.Lshortfile))
|
||||||
|
}
|
||||||
|
|
||||||
|
func SetLogger(customLogger StdLogger) {
|
||||||
|
Logger = customLogger
|
||||||
|
}
|
||||||
|
|
||||||
|
func Print(v ...interface{}) {
|
||||||
|
Logger.Print(v...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Printf(format string, v ...interface{}) {
|
||||||
|
Logger.Printf(format, v...)
|
||||||
|
}
|
||||||
32
staging/src/k8s.io/client-go/1.4/_vendor/github.com/emicklei/go-restful/logger.go
generated
Normal file
32
staging/src/k8s.io/client-go/1.4/_vendor/github.com/emicklei/go-restful/logger.go
generated
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
package restful
|
||||||
|
|
||||||
|
// Copyright 2014 Ernest Micklei. All rights reserved.
|
||||||
|
// Use of this source code is governed by a license
|
||||||
|
// that can be found in the LICENSE file.
|
||||||
|
import (
|
||||||
|
"github.com/emicklei/go-restful/log"
|
||||||
|
)
|
||||||
|
|
||||||
|
var trace bool = false
|
||||||
|
var traceLogger log.StdLogger
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
traceLogger = log.Logger // use the package logger by default
|
||||||
|
}
|
||||||
|
|
||||||
|
// TraceLogger enables detailed logging of Http request matching and filter invocation. Default no logger is set.
|
||||||
|
// You may call EnableTracing() directly to enable trace logging to the package-wide logger.
|
||||||
|
func TraceLogger(logger log.StdLogger) {
|
||||||
|
traceLogger = logger
|
||||||
|
EnableTracing(logger != nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
// expose the setter for the global logger on the top-level package
|
||||||
|
func SetLogger(customLogger log.StdLogger) {
|
||||||
|
log.SetLogger(customLogger)
|
||||||
|
}
|
||||||
|
|
||||||
|
// EnableTracing can be used to Trace logging on and off.
|
||||||
|
func EnableTracing(enabled bool) {
|
||||||
|
trace = enabled
|
||||||
|
}
|
||||||
45
staging/src/k8s.io/client-go/1.4/_vendor/github.com/emicklei/go-restful/mime.go
generated
Normal file
45
staging/src/k8s.io/client-go/1.4/_vendor/github.com/emicklei/go-restful/mime.go
generated
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
package restful
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
type mime struct {
|
||||||
|
media string
|
||||||
|
quality float64
|
||||||
|
}
|
||||||
|
|
||||||
|
// insertMime adds a mime to a list and keeps it sorted by quality.
|
||||||
|
func insertMime(l []mime, e mime) []mime {
|
||||||
|
for i, each := range l {
|
||||||
|
// if current mime has lower quality then insert before
|
||||||
|
if e.quality > each.quality {
|
||||||
|
left := append([]mime{}, l[0:i]...)
|
||||||
|
return append(append(left, e), l[i:]...)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return append(l, e)
|
||||||
|
}
|
||||||
|
|
||||||
|
// sortedMimes returns a list of mime sorted (desc) by its specified quality.
|
||||||
|
func sortedMimes(accept string) (sorted []mime) {
|
||||||
|
for _, each := range strings.Split(accept, ",") {
|
||||||
|
typeAndQuality := strings.Split(strings.Trim(each, " "), ";")
|
||||||
|
if len(typeAndQuality) == 1 {
|
||||||
|
sorted = insertMime(sorted, mime{typeAndQuality[0], 1.0})
|
||||||
|
} else {
|
||||||
|
// take factor
|
||||||
|
parts := strings.Split(typeAndQuality[1], "=")
|
||||||
|
if len(parts) == 2 {
|
||||||
|
f, err := strconv.ParseFloat(parts[1], 64)
|
||||||
|
if err != nil {
|
||||||
|
traceLogger.Printf("unable to parse quality in %s, %v", each, err)
|
||||||
|
} else {
|
||||||
|
sorted = insertMime(sorted, mime{typeAndQuality[0], f})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
26
staging/src/k8s.io/client-go/1.4/_vendor/github.com/emicklei/go-restful/options_filter.go
generated
Normal file
26
staging/src/k8s.io/client-go/1.4/_vendor/github.com/emicklei/go-restful/options_filter.go
generated
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
package restful
|
||||||
|
|
||||||
|
import "strings"
|
||||||
|
|
||||||
|
// Copyright 2013 Ernest Micklei. All rights reserved.
|
||||||
|
// Use of this source code is governed by a license
|
||||||
|
// that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// OPTIONSFilter is a filter function that inspects the Http Request for the OPTIONS method
|
||||||
|
// and provides the response with a set of allowed methods for the request URL Path.
|
||||||
|
// As for any filter, you can also install it for a particular WebService within a Container.
|
||||||
|
// Note: this filter is not needed when using CrossOriginResourceSharing (for CORS).
|
||||||
|
func (c *Container) OPTIONSFilter(req *Request, resp *Response, chain *FilterChain) {
|
||||||
|
if "OPTIONS" != req.Request.Method {
|
||||||
|
chain.ProcessFilter(req, resp)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
resp.AddHeader(HEADER_Allow, strings.Join(c.computeAllowedMethods(req), ","))
|
||||||
|
}
|
||||||
|
|
||||||
|
// OPTIONSFilter is a filter function that inspects the Http Request for the OPTIONS method
|
||||||
|
// and provides the response with a set of allowed methods for the request URL Path.
|
||||||
|
// Note: this filter is not needed when using CrossOriginResourceSharing (for CORS).
|
||||||
|
func OPTIONSFilter() FilterFunction {
|
||||||
|
return DefaultContainer.OPTIONSFilter
|
||||||
|
}
|
||||||
114
staging/src/k8s.io/client-go/1.4/_vendor/github.com/emicklei/go-restful/parameter.go
generated
Normal file
114
staging/src/k8s.io/client-go/1.4/_vendor/github.com/emicklei/go-restful/parameter.go
generated
Normal file
@@ -0,0 +1,114 @@
|
|||||||
|
package restful
|
||||||
|
|
||||||
|
// Copyright 2013 Ernest Micklei. All rights reserved.
|
||||||
|
// Use of this source code is governed by a license
|
||||||
|
// that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
const (
|
||||||
|
// PathParameterKind = indicator of Request parameter type "path"
|
||||||
|
PathParameterKind = iota
|
||||||
|
|
||||||
|
// QueryParameterKind = indicator of Request parameter type "query"
|
||||||
|
QueryParameterKind
|
||||||
|
|
||||||
|
// BodyParameterKind = indicator of Request parameter type "body"
|
||||||
|
BodyParameterKind
|
||||||
|
|
||||||
|
// HeaderParameterKind = indicator of Request parameter type "header"
|
||||||
|
HeaderParameterKind
|
||||||
|
|
||||||
|
// FormParameterKind = indicator of Request parameter type "form"
|
||||||
|
FormParameterKind
|
||||||
|
)
|
||||||
|
|
||||||
|
// Parameter is for documententing the parameter used in a Http Request
|
||||||
|
// ParameterData kinds are Path,Query and Body
|
||||||
|
type Parameter struct {
|
||||||
|
data *ParameterData
|
||||||
|
}
|
||||||
|
|
||||||
|
// ParameterData represents the state of a Parameter.
|
||||||
|
// It is made public to make it accessible to e.g. the Swagger package.
|
||||||
|
type ParameterData struct {
|
||||||
|
Name, Description, DataType, DataFormat string
|
||||||
|
Kind int
|
||||||
|
Required bool
|
||||||
|
AllowableValues map[string]string
|
||||||
|
AllowMultiple bool
|
||||||
|
DefaultValue string
|
||||||
|
}
|
||||||
|
|
||||||
|
// Data returns the state of the Parameter
|
||||||
|
func (p *Parameter) Data() ParameterData {
|
||||||
|
return *p.data
|
||||||
|
}
|
||||||
|
|
||||||
|
// Kind returns the parameter type indicator (see const for valid values)
|
||||||
|
func (p *Parameter) Kind() int {
|
||||||
|
return p.data.Kind
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Parameter) bePath() *Parameter {
|
||||||
|
p.data.Kind = PathParameterKind
|
||||||
|
return p
|
||||||
|
}
|
||||||
|
func (p *Parameter) beQuery() *Parameter {
|
||||||
|
p.data.Kind = QueryParameterKind
|
||||||
|
return p
|
||||||
|
}
|
||||||
|
func (p *Parameter) beBody() *Parameter {
|
||||||
|
p.data.Kind = BodyParameterKind
|
||||||
|
return p
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Parameter) beHeader() *Parameter {
|
||||||
|
p.data.Kind = HeaderParameterKind
|
||||||
|
return p
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Parameter) beForm() *Parameter {
|
||||||
|
p.data.Kind = FormParameterKind
|
||||||
|
return p
|
||||||
|
}
|
||||||
|
|
||||||
|
// Required sets the required field and returns the receiver
|
||||||
|
func (p *Parameter) Required(required bool) *Parameter {
|
||||||
|
p.data.Required = required
|
||||||
|
return p
|
||||||
|
}
|
||||||
|
|
||||||
|
// AllowMultiple sets the allowMultiple field and returns the receiver
|
||||||
|
func (p *Parameter) AllowMultiple(multiple bool) *Parameter {
|
||||||
|
p.data.AllowMultiple = multiple
|
||||||
|
return p
|
||||||
|
}
|
||||||
|
|
||||||
|
// AllowableValues sets the allowableValues field and returns the receiver
|
||||||
|
func (p *Parameter) AllowableValues(values map[string]string) *Parameter {
|
||||||
|
p.data.AllowableValues = values
|
||||||
|
return p
|
||||||
|
}
|
||||||
|
|
||||||
|
// DataType sets the dataType field and returns the receiver
|
||||||
|
func (p *Parameter) DataType(typeName string) *Parameter {
|
||||||
|
p.data.DataType = typeName
|
||||||
|
return p
|
||||||
|
}
|
||||||
|
|
||||||
|
// DataFormat sets the dataFormat field for Swagger UI
|
||||||
|
func (p *Parameter) DataFormat(formatName string) *Parameter {
|
||||||
|
p.data.DataFormat = formatName
|
||||||
|
return p
|
||||||
|
}
|
||||||
|
|
||||||
|
// DefaultValue sets the default value field and returns the receiver
|
||||||
|
func (p *Parameter) DefaultValue(stringRepresentation string) *Parameter {
|
||||||
|
p.data.DefaultValue = stringRepresentation
|
||||||
|
return p
|
||||||
|
}
|
||||||
|
|
||||||
|
// Description sets the description value field and returns the receiver
|
||||||
|
func (p *Parameter) Description(doc string) *Parameter {
|
||||||
|
p.data.Description = doc
|
||||||
|
return p
|
||||||
|
}
|
||||||
69
staging/src/k8s.io/client-go/1.4/_vendor/github.com/emicklei/go-restful/path_expression.go
generated
Normal file
69
staging/src/k8s.io/client-go/1.4/_vendor/github.com/emicklei/go-restful/path_expression.go
generated
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
package restful
|
||||||
|
|
||||||
|
// Copyright 2013 Ernest Micklei. All rights reserved.
|
||||||
|
// Use of this source code is governed by a license
|
||||||
|
// that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"fmt"
|
||||||
|
"regexp"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
// PathExpression holds a compiled path expression (RegExp) needed to match against
|
||||||
|
// Http request paths and to extract path parameter values.
|
||||||
|
type pathExpression struct {
|
||||||
|
LiteralCount int // the number of literal characters (means those not resulting from template variable substitution)
|
||||||
|
VarCount int // the number of named parameters (enclosed by {}) in the path
|
||||||
|
Matcher *regexp.Regexp
|
||||||
|
Source string // Path as defined by the RouteBuilder
|
||||||
|
tokens []string
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewPathExpression creates a PathExpression from the input URL path.
|
||||||
|
// Returns an error if the path is invalid.
|
||||||
|
func newPathExpression(path string) (*pathExpression, error) {
|
||||||
|
expression, literalCount, varCount, tokens := templateToRegularExpression(path)
|
||||||
|
compiled, err := regexp.Compile(expression)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &pathExpression{literalCount, varCount, compiled, expression, tokens}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// http://jsr311.java.net/nonav/releases/1.1/spec/spec3.html#x3-370003.7.3
|
||||||
|
func templateToRegularExpression(template string) (expression string, literalCount int, varCount int, tokens []string) {
|
||||||
|
var buffer bytes.Buffer
|
||||||
|
buffer.WriteString("^")
|
||||||
|
//tokens = strings.Split(template, "/")
|
||||||
|
tokens = tokenizePath(template)
|
||||||
|
for _, each := range tokens {
|
||||||
|
if each == "" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
buffer.WriteString("/")
|
||||||
|
if strings.HasPrefix(each, "{") {
|
||||||
|
// check for regular expression in variable
|
||||||
|
colon := strings.Index(each, ":")
|
||||||
|
if colon != -1 {
|
||||||
|
// extract expression
|
||||||
|
paramExpr := strings.TrimSpace(each[colon+1 : len(each)-1])
|
||||||
|
if paramExpr == "*" { // special case
|
||||||
|
buffer.WriteString("(.*)")
|
||||||
|
} else {
|
||||||
|
buffer.WriteString(fmt.Sprintf("(%s)", paramExpr)) // between colon and closing moustache
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// plain var
|
||||||
|
buffer.WriteString("([^/]+?)")
|
||||||
|
}
|
||||||
|
varCount += 1
|
||||||
|
} else {
|
||||||
|
literalCount += len(each)
|
||||||
|
encoded := each // TODO URI encode
|
||||||
|
buffer.WriteString(regexp.QuoteMeta(encoded))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return strings.TrimRight(buffer.String(), "/") + "(/.*)?$", literalCount, varCount, tokens
|
||||||
|
}
|
||||||
131
staging/src/k8s.io/client-go/1.4/_vendor/github.com/emicklei/go-restful/request.go
generated
Normal file
131
staging/src/k8s.io/client-go/1.4/_vendor/github.com/emicklei/go-restful/request.go
generated
Normal file
@@ -0,0 +1,131 @@
|
|||||||
|
package restful
|
||||||
|
|
||||||
|
// Copyright 2013 Ernest Micklei. All rights reserved.
|
||||||
|
// Use of this source code is governed by a license
|
||||||
|
// that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"compress/zlib"
|
||||||
|
"io/ioutil"
|
||||||
|
"net/http"
|
||||||
|
)
|
||||||
|
|
||||||
|
var defaultRequestContentType string
|
||||||
|
|
||||||
|
var doCacheReadEntityBytes = true
|
||||||
|
|
||||||
|
// Request is a wrapper for a http Request that provides convenience methods
|
||||||
|
type Request struct {
|
||||||
|
Request *http.Request
|
||||||
|
bodyContent *[]byte // to cache the request body for multiple reads of ReadEntity
|
||||||
|
pathParameters map[string]string
|
||||||
|
attributes map[string]interface{} // for storing request-scoped values
|
||||||
|
selectedRoutePath string // root path + route path that matched the request, e.g. /meetings/{id}/attendees
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewRequest(httpRequest *http.Request) *Request {
|
||||||
|
return &Request{
|
||||||
|
Request: httpRequest,
|
||||||
|
pathParameters: map[string]string{},
|
||||||
|
attributes: map[string]interface{}{},
|
||||||
|
} // empty parameters, attributes
|
||||||
|
}
|
||||||
|
|
||||||
|
// If ContentType is missing or */* is given then fall back to this type, otherwise
|
||||||
|
// a "Unable to unmarshal content of type:" response is returned.
|
||||||
|
// Valid values are restful.MIME_JSON and restful.MIME_XML
|
||||||
|
// Example:
|
||||||
|
// restful.DefaultRequestContentType(restful.MIME_JSON)
|
||||||
|
func DefaultRequestContentType(mime string) {
|
||||||
|
defaultRequestContentType = mime
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetCacheReadEntity controls whether the response data ([]byte) is cached such that ReadEntity is repeatable.
|
||||||
|
// Default is true (due to backwardcompatibility). For better performance, you should set it to false if you don't need it.
|
||||||
|
func SetCacheReadEntity(doCache bool) {
|
||||||
|
doCacheReadEntityBytes = doCache
|
||||||
|
}
|
||||||
|
|
||||||
|
// PathParameter accesses the Path parameter value by its name
|
||||||
|
func (r *Request) PathParameter(name string) string {
|
||||||
|
return r.pathParameters[name]
|
||||||
|
}
|
||||||
|
|
||||||
|
// PathParameters accesses the Path parameter values
|
||||||
|
func (r *Request) PathParameters() map[string]string {
|
||||||
|
return r.pathParameters
|
||||||
|
}
|
||||||
|
|
||||||
|
// QueryParameter returns the (first) Query parameter value by its name
|
||||||
|
func (r *Request) QueryParameter(name string) string {
|
||||||
|
return r.Request.FormValue(name)
|
||||||
|
}
|
||||||
|
|
||||||
|
// BodyParameter parses the body of the request (once for typically a POST or a PUT) and returns the value of the given name or an error.
|
||||||
|
func (r *Request) BodyParameter(name string) (string, error) {
|
||||||
|
err := r.Request.ParseForm()
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
return r.Request.PostFormValue(name), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// HeaderParameter returns the HTTP Header value of a Header name or empty if missing
|
||||||
|
func (r *Request) HeaderParameter(name string) string {
|
||||||
|
return r.Request.Header.Get(name)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ReadEntity checks the Accept header and reads the content into the entityPointer.
|
||||||
|
func (r *Request) ReadEntity(entityPointer interface{}) (err error) {
|
||||||
|
contentType := r.Request.Header.Get(HEADER_ContentType)
|
||||||
|
contentEncoding := r.Request.Header.Get(HEADER_ContentEncoding)
|
||||||
|
|
||||||
|
// OLD feature, cache the body for reads
|
||||||
|
if doCacheReadEntityBytes {
|
||||||
|
if r.bodyContent == nil {
|
||||||
|
data, err := ioutil.ReadAll(r.Request.Body)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
r.bodyContent = &data
|
||||||
|
}
|
||||||
|
r.Request.Body = ioutil.NopCloser(bytes.NewReader(*r.bodyContent))
|
||||||
|
}
|
||||||
|
|
||||||
|
// check if the request body needs decompression
|
||||||
|
if ENCODING_GZIP == contentEncoding {
|
||||||
|
gzipReader := currentCompressorProvider.AcquireGzipReader()
|
||||||
|
defer currentCompressorProvider.ReleaseGzipReader(gzipReader)
|
||||||
|
gzipReader.Reset(r.Request.Body)
|
||||||
|
r.Request.Body = gzipReader
|
||||||
|
} else if ENCODING_DEFLATE == contentEncoding {
|
||||||
|
zlibReader, err := zlib.NewReader(r.Request.Body)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
r.Request.Body = zlibReader
|
||||||
|
}
|
||||||
|
|
||||||
|
// lookup the EntityReader
|
||||||
|
entityReader, ok := entityAccessRegistry.accessorAt(contentType)
|
||||||
|
if !ok {
|
||||||
|
return NewError(http.StatusBadRequest, "Unable to unmarshal content of type:"+contentType)
|
||||||
|
}
|
||||||
|
return entityReader.Read(r, entityPointer)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetAttribute adds or replaces the attribute with the given value.
|
||||||
|
func (r *Request) SetAttribute(name string, value interface{}) {
|
||||||
|
r.attributes[name] = value
|
||||||
|
}
|
||||||
|
|
||||||
|
// Attribute returns the value associated to the given name. Returns nil if absent.
|
||||||
|
func (r Request) Attribute(name string) interface{} {
|
||||||
|
return r.attributes[name]
|
||||||
|
}
|
||||||
|
|
||||||
|
// SelectedRoutePath root path + route path that matched the request, e.g. /meetings/{id}/attendees
|
||||||
|
func (r Request) SelectedRoutePath() string {
|
||||||
|
return r.selectedRoutePath
|
||||||
|
}
|
||||||
235
staging/src/k8s.io/client-go/1.4/_vendor/github.com/emicklei/go-restful/response.go
generated
Normal file
235
staging/src/k8s.io/client-go/1.4/_vendor/github.com/emicklei/go-restful/response.go
generated
Normal file
@@ -0,0 +1,235 @@
|
|||||||
|
package restful
|
||||||
|
|
||||||
|
// Copyright 2013 Ernest Micklei. All rights reserved.
|
||||||
|
// Use of this source code is governed by a license
|
||||||
|
// that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"net/http"
|
||||||
|
)
|
||||||
|
|
||||||
|
// DEPRECATED, use DefaultResponseContentType(mime)
|
||||||
|
var DefaultResponseMimeType string
|
||||||
|
|
||||||
|
//PrettyPrintResponses controls the indentation feature of XML and JSON serialization
|
||||||
|
var PrettyPrintResponses = true
|
||||||
|
|
||||||
|
// Response is a wrapper on the actual http ResponseWriter
|
||||||
|
// It provides several convenience methods to prepare and write response content.
|
||||||
|
type Response struct {
|
||||||
|
http.ResponseWriter
|
||||||
|
requestAccept string // mime-type what the Http Request says it wants to receive
|
||||||
|
routeProduces []string // mime-types what the Route says it can produce
|
||||||
|
statusCode int // HTTP status code that has been written explicity (if zero then net/http has written 200)
|
||||||
|
contentLength int // number of bytes written for the response body
|
||||||
|
prettyPrint bool // controls the indentation feature of XML and JSON serialization. It is initialized using var PrettyPrintResponses.
|
||||||
|
err error // err property is kept when WriteError is called
|
||||||
|
}
|
||||||
|
|
||||||
|
// Creates a new response based on a http ResponseWriter.
|
||||||
|
func NewResponse(httpWriter http.ResponseWriter) *Response {
|
||||||
|
return &Response{httpWriter, "", []string{}, http.StatusOK, 0, PrettyPrintResponses, nil} // empty content-types
|
||||||
|
}
|
||||||
|
|
||||||
|
// If Accept header matching fails, fall back to this type.
|
||||||
|
// Valid values are restful.MIME_JSON and restful.MIME_XML
|
||||||
|
// Example:
|
||||||
|
// restful.DefaultResponseContentType(restful.MIME_JSON)
|
||||||
|
func DefaultResponseContentType(mime string) {
|
||||||
|
DefaultResponseMimeType = mime
|
||||||
|
}
|
||||||
|
|
||||||
|
// InternalServerError writes the StatusInternalServerError header.
|
||||||
|
// DEPRECATED, use WriteErrorString(http.StatusInternalServerError,reason)
|
||||||
|
func (r Response) InternalServerError() Response {
|
||||||
|
r.WriteHeader(http.StatusInternalServerError)
|
||||||
|
return r
|
||||||
|
}
|
||||||
|
|
||||||
|
// PrettyPrint changes whether this response must produce pretty (line-by-line, indented) JSON or XML output.
|
||||||
|
func (r *Response) PrettyPrint(bePretty bool) {
|
||||||
|
r.prettyPrint = bePretty
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddHeader is a shortcut for .Header().Add(header,value)
|
||||||
|
func (r Response) AddHeader(header string, value string) Response {
|
||||||
|
r.Header().Add(header, value)
|
||||||
|
return r
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetRequestAccepts tells the response what Mime-type(s) the HTTP request said it wants to accept. Exposed for testing.
|
||||||
|
func (r *Response) SetRequestAccepts(mime string) {
|
||||||
|
r.requestAccept = mime
|
||||||
|
}
|
||||||
|
|
||||||
|
// EntityWriter returns the registered EntityWriter that the entity (requested resource)
|
||||||
|
// can write according to what the request wants (Accept) and what the Route can produce or what the restful defaults say.
|
||||||
|
// If called before WriteEntity and WriteHeader then a false return value can be used to write a 406: Not Acceptable.
|
||||||
|
func (r *Response) EntityWriter() (EntityReaderWriter, bool) {
|
||||||
|
sorted := sortedMimes(r.requestAccept)
|
||||||
|
for _, eachAccept := range sorted {
|
||||||
|
for _, eachProduce := range r.routeProduces {
|
||||||
|
if eachProduce == eachAccept.media {
|
||||||
|
if w, ok := entityAccessRegistry.accessorAt(eachAccept.media); ok {
|
||||||
|
return w, true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if eachAccept.media == "*/*" {
|
||||||
|
for _, each := range r.routeProduces {
|
||||||
|
if w, ok := entityAccessRegistry.accessorAt(each); ok {
|
||||||
|
return w, true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// if requestAccept is empty
|
||||||
|
writer, ok := entityAccessRegistry.accessorAt(r.requestAccept)
|
||||||
|
if !ok {
|
||||||
|
// if not registered then fallback to the defaults (if set)
|
||||||
|
if DefaultResponseMimeType == MIME_JSON {
|
||||||
|
return entityAccessRegistry.accessorAt(MIME_JSON)
|
||||||
|
}
|
||||||
|
if DefaultResponseMimeType == MIME_XML {
|
||||||
|
return entityAccessRegistry.accessorAt(MIME_XML)
|
||||||
|
}
|
||||||
|
// Fallback to whatever the route says it can produce.
|
||||||
|
// https://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html
|
||||||
|
for _, each := range r.routeProduces {
|
||||||
|
if w, ok := entityAccessRegistry.accessorAt(each); ok {
|
||||||
|
return w, true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if trace {
|
||||||
|
traceLogger.Printf("no registered EntityReaderWriter found for %s", r.requestAccept)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return writer, ok
|
||||||
|
}
|
||||||
|
|
||||||
|
// WriteEntity calls WriteHeaderAndEntity with Http Status OK (200)
|
||||||
|
func (r *Response) WriteEntity(value interface{}) error {
|
||||||
|
return r.WriteHeaderAndEntity(http.StatusOK, value)
|
||||||
|
}
|
||||||
|
|
||||||
|
// WriteHeaderAndEntity marshals the value using the representation denoted by the Accept Header and the registered EntityWriters.
|
||||||
|
// If no Accept header is specified (or */*) then respond with the Content-Type as specified by the first in the Route.Produces.
|
||||||
|
// If an Accept header is specified then respond with the Content-Type as specified by the first in the Route.Produces that is matched with the Accept header.
|
||||||
|
// If the value is nil then no response is send except for the Http status. You may want to call WriteHeader(http.StatusNotFound) instead.
|
||||||
|
// If there is no writer available that can represent the value in the requested MIME type then Http Status NotAcceptable is written.
|
||||||
|
// Current implementation ignores any q-parameters in the Accept Header.
|
||||||
|
// Returns an error if the value could not be written on the response.
|
||||||
|
func (r *Response) WriteHeaderAndEntity(status int, value interface{}) error {
|
||||||
|
writer, ok := r.EntityWriter()
|
||||||
|
if !ok {
|
||||||
|
r.WriteHeader(http.StatusNotAcceptable)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return writer.Write(r, status, value)
|
||||||
|
}
|
||||||
|
|
||||||
|
// WriteAsXml is a convenience method for writing a value in xml (requires Xml tags on the value)
|
||||||
|
// It uses the standard encoding/xml package for marshalling the value ; not using a registered EntityReaderWriter.
|
||||||
|
func (r *Response) WriteAsXml(value interface{}) error {
|
||||||
|
return writeXML(r, http.StatusOK, MIME_XML, value)
|
||||||
|
}
|
||||||
|
|
||||||
|
// WriteHeaderAndXml is a convenience method for writing a status and value in xml (requires Xml tags on the value)
|
||||||
|
// It uses the standard encoding/xml package for marshalling the value ; not using a registered EntityReaderWriter.
|
||||||
|
func (r *Response) WriteHeaderAndXml(status int, value interface{}) error {
|
||||||
|
return writeXML(r, status, MIME_XML, value)
|
||||||
|
}
|
||||||
|
|
||||||
|
// WriteAsJson is a convenience method for writing a value in json.
|
||||||
|
// It uses the standard encoding/json package for marshalling the value ; not using a registered EntityReaderWriter.
|
||||||
|
func (r *Response) WriteAsJson(value interface{}) error {
|
||||||
|
return writeJSON(r, http.StatusOK, MIME_JSON, value)
|
||||||
|
}
|
||||||
|
|
||||||
|
// WriteJson is a convenience method for writing a value in Json with a given Content-Type.
|
||||||
|
// It uses the standard encoding/json package for marshalling the value ; not using a registered EntityReaderWriter.
|
||||||
|
func (r *Response) WriteJson(value interface{}, contentType string) error {
|
||||||
|
return writeJSON(r, http.StatusOK, contentType, value)
|
||||||
|
}
|
||||||
|
|
||||||
|
// WriteHeaderAndJson is a convenience method for writing the status and a value in Json with a given Content-Type.
|
||||||
|
// It uses the standard encoding/json package for marshalling the value ; not using a registered EntityReaderWriter.
|
||||||
|
func (r *Response) WriteHeaderAndJson(status int, value interface{}, contentType string) error {
|
||||||
|
return writeJSON(r, status, contentType, value)
|
||||||
|
}
|
||||||
|
|
||||||
|
// WriteError write the http status and the error string on the response.
|
||||||
|
func (r *Response) WriteError(httpStatus int, err error) error {
|
||||||
|
r.err = err
|
||||||
|
return r.WriteErrorString(httpStatus, err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
// WriteServiceError is a convenience method for a responding with a status and a ServiceError
|
||||||
|
func (r *Response) WriteServiceError(httpStatus int, err ServiceError) error {
|
||||||
|
r.err = err
|
||||||
|
return r.WriteHeaderAndEntity(httpStatus, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// WriteErrorString is a convenience method for an error status with the actual error
|
||||||
|
func (r *Response) WriteErrorString(httpStatus int, errorReason string) error {
|
||||||
|
if r.err == nil {
|
||||||
|
// if not called from WriteError
|
||||||
|
r.err = errors.New(errorReason)
|
||||||
|
}
|
||||||
|
r.WriteHeader(httpStatus)
|
||||||
|
if _, err := r.Write([]byte(errorReason)); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Flush implements http.Flusher interface, which sends any buffered data to the client.
|
||||||
|
func (r *Response) Flush() {
|
||||||
|
if f, ok := r.ResponseWriter.(http.Flusher); ok {
|
||||||
|
f.Flush()
|
||||||
|
} else if trace {
|
||||||
|
traceLogger.Printf("ResponseWriter %v doesn't support Flush", r)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// WriteHeader is overridden to remember the Status Code that has been written.
|
||||||
|
// Changes to the Header of the response have no effect after this.
|
||||||
|
func (r *Response) WriteHeader(httpStatus int) {
|
||||||
|
r.statusCode = httpStatus
|
||||||
|
r.ResponseWriter.WriteHeader(httpStatus)
|
||||||
|
}
|
||||||
|
|
||||||
|
// StatusCode returns the code that has been written using WriteHeader.
|
||||||
|
func (r Response) StatusCode() int {
|
||||||
|
if 0 == r.statusCode {
|
||||||
|
// no status code has been written yet; assume OK
|
||||||
|
return http.StatusOK
|
||||||
|
}
|
||||||
|
return r.statusCode
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write writes the data to the connection as part of an HTTP reply.
|
||||||
|
// Write is part of http.ResponseWriter interface.
|
||||||
|
func (r *Response) Write(bytes []byte) (int, error) {
|
||||||
|
written, err := r.ResponseWriter.Write(bytes)
|
||||||
|
r.contentLength += written
|
||||||
|
return written, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// ContentLength returns the number of bytes written for the response content.
|
||||||
|
// Note that this value is only correct if all data is written through the Response using its Write* methods.
|
||||||
|
// Data written directly using the underlying http.ResponseWriter is not accounted for.
|
||||||
|
func (r Response) ContentLength() int {
|
||||||
|
return r.contentLength
|
||||||
|
}
|
||||||
|
|
||||||
|
// CloseNotify is part of http.CloseNotifier interface
|
||||||
|
func (r Response) CloseNotify() <-chan bool {
|
||||||
|
return r.ResponseWriter.(http.CloseNotifier).CloseNotify()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Error returns the err created by WriteError
|
||||||
|
func (r Response) Error() error {
|
||||||
|
return r.err
|
||||||
|
}
|
||||||
183
staging/src/k8s.io/client-go/1.4/_vendor/github.com/emicklei/go-restful/route.go
generated
Normal file
183
staging/src/k8s.io/client-go/1.4/_vendor/github.com/emicklei/go-restful/route.go
generated
Normal file
@@ -0,0 +1,183 @@
|
|||||||
|
package restful
|
||||||
|
|
||||||
|
// Copyright 2013 Ernest Micklei. All rights reserved.
|
||||||
|
// Use of this source code is governed by a license
|
||||||
|
// that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"net/http"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
// RouteFunction declares the signature of a function that can be bound to a Route.
|
||||||
|
type RouteFunction func(*Request, *Response)
|
||||||
|
|
||||||
|
// Route binds a HTTP Method,Path,Consumes combination to a RouteFunction.
|
||||||
|
type Route struct {
|
||||||
|
Method string
|
||||||
|
Produces []string
|
||||||
|
Consumes []string
|
||||||
|
Path string // webservice root path + described path
|
||||||
|
Function RouteFunction
|
||||||
|
Filters []FilterFunction
|
||||||
|
|
||||||
|
// cached values for dispatching
|
||||||
|
relativePath string
|
||||||
|
pathParts []string
|
||||||
|
pathExpr *pathExpression // cached compilation of relativePath as RegExp
|
||||||
|
|
||||||
|
// documentation
|
||||||
|
Doc string
|
||||||
|
Notes string
|
||||||
|
Operation string
|
||||||
|
ParameterDocs []*Parameter
|
||||||
|
ResponseErrors map[int]ResponseError
|
||||||
|
ReadSample, WriteSample interface{} // structs that model an example request or response payload
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initialize for Route
|
||||||
|
func (r *Route) postBuild() {
|
||||||
|
r.pathParts = tokenizePath(r.Path)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create Request and Response from their http versions
|
||||||
|
func (r *Route) wrapRequestResponse(httpWriter http.ResponseWriter, httpRequest *http.Request) (*Request, *Response) {
|
||||||
|
params := r.extractParameters(httpRequest.URL.Path)
|
||||||
|
wrappedRequest := NewRequest(httpRequest)
|
||||||
|
wrappedRequest.pathParameters = params
|
||||||
|
wrappedRequest.selectedRoutePath = r.Path
|
||||||
|
wrappedResponse := NewResponse(httpWriter)
|
||||||
|
wrappedResponse.requestAccept = httpRequest.Header.Get(HEADER_Accept)
|
||||||
|
wrappedResponse.routeProduces = r.Produces
|
||||||
|
return wrappedRequest, wrappedResponse
|
||||||
|
}
|
||||||
|
|
||||||
|
// dispatchWithFilters call the function after passing through its own filters
|
||||||
|
func (r *Route) dispatchWithFilters(wrappedRequest *Request, wrappedResponse *Response) {
|
||||||
|
if len(r.Filters) > 0 {
|
||||||
|
chain := FilterChain{Filters: r.Filters, Target: r.Function}
|
||||||
|
chain.ProcessFilter(wrappedRequest, wrappedResponse)
|
||||||
|
} else {
|
||||||
|
// unfiltered
|
||||||
|
r.Function(wrappedRequest, wrappedResponse)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return whether the mimeType matches to what this Route can produce.
|
||||||
|
func (r Route) matchesAccept(mimeTypesWithQuality string) bool {
|
||||||
|
parts := strings.Split(mimeTypesWithQuality, ",")
|
||||||
|
for _, each := range parts {
|
||||||
|
var withoutQuality string
|
||||||
|
if strings.Contains(each, ";") {
|
||||||
|
withoutQuality = strings.Split(each, ";")[0]
|
||||||
|
} else {
|
||||||
|
withoutQuality = each
|
||||||
|
}
|
||||||
|
// trim before compare
|
||||||
|
withoutQuality = strings.Trim(withoutQuality, " ")
|
||||||
|
if withoutQuality == "*/*" {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
for _, producibleType := range r.Produces {
|
||||||
|
if producibleType == "*/*" || producibleType == withoutQuality {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return whether this Route can consume content with a type specified by mimeTypes (can be empty).
|
||||||
|
func (r Route) matchesContentType(mimeTypes string) bool {
|
||||||
|
|
||||||
|
if len(r.Consumes) == 0 {
|
||||||
|
// did not specify what it can consume ; any media type (“*/*”) is assumed
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(mimeTypes) == 0 {
|
||||||
|
// idempotent methods with (most-likely or garanteed) empty content match missing Content-Type
|
||||||
|
m := r.Method
|
||||||
|
if m == "GET" || m == "HEAD" || m == "OPTIONS" || m == "DELETE" || m == "TRACE" {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
// proceed with default
|
||||||
|
mimeTypes = MIME_OCTET
|
||||||
|
}
|
||||||
|
|
||||||
|
parts := strings.Split(mimeTypes, ",")
|
||||||
|
for _, each := range parts {
|
||||||
|
var contentType string
|
||||||
|
if strings.Contains(each, ";") {
|
||||||
|
contentType = strings.Split(each, ";")[0]
|
||||||
|
} else {
|
||||||
|
contentType = each
|
||||||
|
}
|
||||||
|
// trim before compare
|
||||||
|
contentType = strings.Trim(contentType, " ")
|
||||||
|
for _, consumeableType := range r.Consumes {
|
||||||
|
if consumeableType == "*/*" || consumeableType == contentType {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// Extract the parameters from the request url path
|
||||||
|
func (r Route) extractParameters(urlPath string) map[string]string {
|
||||||
|
urlParts := tokenizePath(urlPath)
|
||||||
|
pathParameters := map[string]string{}
|
||||||
|
for i, key := range r.pathParts {
|
||||||
|
var value string
|
||||||
|
if i >= len(urlParts) {
|
||||||
|
value = ""
|
||||||
|
} else {
|
||||||
|
value = urlParts[i]
|
||||||
|
}
|
||||||
|
if strings.HasPrefix(key, "{") { // path-parameter
|
||||||
|
if colon := strings.Index(key, ":"); colon != -1 {
|
||||||
|
// extract by regex
|
||||||
|
regPart := key[colon+1 : len(key)-1]
|
||||||
|
keyPart := key[1:colon]
|
||||||
|
if regPart == "*" {
|
||||||
|
pathParameters[keyPart] = untokenizePath(i, urlParts)
|
||||||
|
break
|
||||||
|
} else {
|
||||||
|
pathParameters[keyPart] = value
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// without enclosing {}
|
||||||
|
pathParameters[key[1:len(key)-1]] = value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return pathParameters
|
||||||
|
}
|
||||||
|
|
||||||
|
// Untokenize back into an URL path using the slash separator
|
||||||
|
func untokenizePath(offset int, parts []string) string {
|
||||||
|
var buffer bytes.Buffer
|
||||||
|
for p := offset; p < len(parts); p++ {
|
||||||
|
buffer.WriteString(parts[p])
|
||||||
|
// do not end
|
||||||
|
if p < len(parts)-1 {
|
||||||
|
buffer.WriteString("/")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return buffer.String()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tokenize an URL path using the slash separator ; the result does not have empty tokens
|
||||||
|
func tokenizePath(path string) []string {
|
||||||
|
if "/" == path {
|
||||||
|
return []string{}
|
||||||
|
}
|
||||||
|
return strings.Split(strings.Trim(path, "/"), "/")
|
||||||
|
}
|
||||||
|
|
||||||
|
// for debugging
|
||||||
|
func (r Route) String() string {
|
||||||
|
return r.Method + " " + r.Path
|
||||||
|
}
|
||||||
240
staging/src/k8s.io/client-go/1.4/_vendor/github.com/emicklei/go-restful/route_builder.go
generated
Normal file
240
staging/src/k8s.io/client-go/1.4/_vendor/github.com/emicklei/go-restful/route_builder.go
generated
Normal file
@@ -0,0 +1,240 @@
|
|||||||
|
package restful
|
||||||
|
|
||||||
|
// Copyright 2013 Ernest Micklei. All rights reserved.
|
||||||
|
// Use of this source code is governed by a license
|
||||||
|
// that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
"reflect"
|
||||||
|
"runtime"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/emicklei/go-restful/log"
|
||||||
|
)
|
||||||
|
|
||||||
|
// RouteBuilder is a helper to construct Routes.
|
||||||
|
type RouteBuilder struct {
|
||||||
|
rootPath string
|
||||||
|
currentPath string
|
||||||
|
produces []string
|
||||||
|
consumes []string
|
||||||
|
httpMethod string // required
|
||||||
|
function RouteFunction // required
|
||||||
|
filters []FilterFunction
|
||||||
|
// documentation
|
||||||
|
doc string
|
||||||
|
notes string
|
||||||
|
operation string
|
||||||
|
readSample, writeSample interface{}
|
||||||
|
parameters []*Parameter
|
||||||
|
errorMap map[int]ResponseError
|
||||||
|
}
|
||||||
|
|
||||||
|
// Do evaluates each argument with the RouteBuilder itself.
|
||||||
|
// This allows you to follow DRY principles without breaking the fluent programming style.
|
||||||
|
// Example:
|
||||||
|
// ws.Route(ws.DELETE("/{name}").To(t.deletePerson).Do(Returns200, Returns500))
|
||||||
|
//
|
||||||
|
// func Returns500(b *RouteBuilder) {
|
||||||
|
// b.Returns(500, "Internal Server Error", restful.ServiceError{})
|
||||||
|
// }
|
||||||
|
func (b *RouteBuilder) Do(oneArgBlocks ...func(*RouteBuilder)) *RouteBuilder {
|
||||||
|
for _, each := range oneArgBlocks {
|
||||||
|
each(b)
|
||||||
|
}
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
|
||||||
|
// To bind the route to a function.
|
||||||
|
// If this route is matched with the incoming Http Request then call this function with the *Request,*Response pair. Required.
|
||||||
|
func (b *RouteBuilder) To(function RouteFunction) *RouteBuilder {
|
||||||
|
b.function = function
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
|
||||||
|
// Method specifies what HTTP method to match. Required.
|
||||||
|
func (b *RouteBuilder) Method(method string) *RouteBuilder {
|
||||||
|
b.httpMethod = method
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
|
||||||
|
// Produces specifies what MIME types can be produced ; the matched one will appear in the Content-Type Http header.
|
||||||
|
func (b *RouteBuilder) Produces(mimeTypes ...string) *RouteBuilder {
|
||||||
|
b.produces = mimeTypes
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
|
||||||
|
// Consumes specifies what MIME types can be consumes ; the Accept Http header must matched any of these
|
||||||
|
func (b *RouteBuilder) Consumes(mimeTypes ...string) *RouteBuilder {
|
||||||
|
b.consumes = mimeTypes
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
|
||||||
|
// Path specifies the relative (w.r.t WebService root path) URL path to match. Default is "/".
|
||||||
|
func (b *RouteBuilder) Path(subPath string) *RouteBuilder {
|
||||||
|
b.currentPath = subPath
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
|
||||||
|
// Doc tells what this route is all about. Optional.
|
||||||
|
func (b *RouteBuilder) Doc(documentation string) *RouteBuilder {
|
||||||
|
b.doc = documentation
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
|
||||||
|
// A verbose explanation of the operation behavior. Optional.
|
||||||
|
func (b *RouteBuilder) Notes(notes string) *RouteBuilder {
|
||||||
|
b.notes = notes
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reads tells what resource type will be read from the request payload. Optional.
|
||||||
|
// A parameter of type "body" is added ,required is set to true and the dataType is set to the qualified name of the sample's type.
|
||||||
|
func (b *RouteBuilder) Reads(sample interface{}) *RouteBuilder {
|
||||||
|
b.readSample = sample
|
||||||
|
typeAsName := reflect.TypeOf(sample).String()
|
||||||
|
bodyParameter := &Parameter{&ParameterData{Name: "body"}}
|
||||||
|
bodyParameter.beBody()
|
||||||
|
bodyParameter.Required(true)
|
||||||
|
bodyParameter.DataType(typeAsName)
|
||||||
|
b.Param(bodyParameter)
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
|
||||||
|
// ParameterNamed returns a Parameter already known to the RouteBuilder. Returns nil if not.
|
||||||
|
// Use this to modify or extend information for the Parameter (through its Data()).
|
||||||
|
func (b RouteBuilder) ParameterNamed(name string) (p *Parameter) {
|
||||||
|
for _, each := range b.parameters {
|
||||||
|
if each.Data().Name == name {
|
||||||
|
return each
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return p
|
||||||
|
}
|
||||||
|
|
||||||
|
// Writes tells what resource type will be written as the response payload. Optional.
|
||||||
|
func (b *RouteBuilder) Writes(sample interface{}) *RouteBuilder {
|
||||||
|
b.writeSample = sample
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
|
||||||
|
// Param allows you to document the parameters of the Route. It adds a new Parameter (does not check for duplicates).
|
||||||
|
func (b *RouteBuilder) Param(parameter *Parameter) *RouteBuilder {
|
||||||
|
if b.parameters == nil {
|
||||||
|
b.parameters = []*Parameter{}
|
||||||
|
}
|
||||||
|
b.parameters = append(b.parameters, parameter)
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
|
||||||
|
// Operation allows you to document what the actual method/function call is of the Route.
|
||||||
|
// Unless called, the operation name is derived from the RouteFunction set using To(..).
|
||||||
|
func (b *RouteBuilder) Operation(name string) *RouteBuilder {
|
||||||
|
b.operation = name
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
|
||||||
|
// ReturnsError is deprecated, use Returns instead.
|
||||||
|
func (b *RouteBuilder) ReturnsError(code int, message string, model interface{}) *RouteBuilder {
|
||||||
|
log.Print("ReturnsError is deprecated, use Returns instead.")
|
||||||
|
return b.Returns(code, message, model)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns allows you to document what responses (errors or regular) can be expected.
|
||||||
|
// The model parameter is optional ; either pass a struct instance or use nil if not applicable.
|
||||||
|
func (b *RouteBuilder) Returns(code int, message string, model interface{}) *RouteBuilder {
|
||||||
|
err := ResponseError{
|
||||||
|
Code: code,
|
||||||
|
Message: message,
|
||||||
|
Model: model,
|
||||||
|
}
|
||||||
|
// lazy init because there is no NewRouteBuilder (yet)
|
||||||
|
if b.errorMap == nil {
|
||||||
|
b.errorMap = map[int]ResponseError{}
|
||||||
|
}
|
||||||
|
b.errorMap[code] = err
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
|
||||||
|
type ResponseError struct {
|
||||||
|
Code int
|
||||||
|
Message string
|
||||||
|
Model interface{}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *RouteBuilder) servicePath(path string) *RouteBuilder {
|
||||||
|
b.rootPath = path
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
|
||||||
|
// Filter appends a FilterFunction to the end of filters for this Route to build.
|
||||||
|
func (b *RouteBuilder) Filter(filter FilterFunction) *RouteBuilder {
|
||||||
|
b.filters = append(b.filters, filter)
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
|
||||||
|
// If no specific Route path then set to rootPath
|
||||||
|
// If no specific Produces then set to rootProduces
|
||||||
|
// If no specific Consumes then set to rootConsumes
|
||||||
|
func (b *RouteBuilder) copyDefaults(rootProduces, rootConsumes []string) {
|
||||||
|
if len(b.produces) == 0 {
|
||||||
|
b.produces = rootProduces
|
||||||
|
}
|
||||||
|
if len(b.consumes) == 0 {
|
||||||
|
b.consumes = rootConsumes
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Build creates a new Route using the specification details collected by the RouteBuilder
|
||||||
|
func (b *RouteBuilder) Build() Route {
|
||||||
|
pathExpr, err := newPathExpression(b.currentPath)
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("[restful] Invalid path:%s because:%v", b.currentPath, err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
if b.function == nil {
|
||||||
|
log.Printf("[restful] No function specified for route:" + b.currentPath)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
operationName := b.operation
|
||||||
|
if len(operationName) == 0 && b.function != nil {
|
||||||
|
// extract from definition
|
||||||
|
operationName = nameOfFunction(b.function)
|
||||||
|
}
|
||||||
|
route := Route{
|
||||||
|
Method: b.httpMethod,
|
||||||
|
Path: concatPath(b.rootPath, b.currentPath),
|
||||||
|
Produces: b.produces,
|
||||||
|
Consumes: b.consumes,
|
||||||
|
Function: b.function,
|
||||||
|
Filters: b.filters,
|
||||||
|
relativePath: b.currentPath,
|
||||||
|
pathExpr: pathExpr,
|
||||||
|
Doc: b.doc,
|
||||||
|
Notes: b.notes,
|
||||||
|
Operation: operationName,
|
||||||
|
ParameterDocs: b.parameters,
|
||||||
|
ResponseErrors: b.errorMap,
|
||||||
|
ReadSample: b.readSample,
|
||||||
|
WriteSample: b.writeSample}
|
||||||
|
route.postBuild()
|
||||||
|
return route
|
||||||
|
}
|
||||||
|
|
||||||
|
func concatPath(path1, path2 string) string {
|
||||||
|
return strings.TrimRight(path1, "/") + "/" + strings.TrimLeft(path2, "/")
|
||||||
|
}
|
||||||
|
|
||||||
|
// nameOfFunction returns the short name of the function f for documentation.
|
||||||
|
// It uses a runtime feature for debugging ; its value may change for later Go versions.
|
||||||
|
func nameOfFunction(f interface{}) string {
|
||||||
|
fun := runtime.FuncForPC(reflect.ValueOf(f).Pointer())
|
||||||
|
tokenized := strings.Split(fun.Name(), ".")
|
||||||
|
last := tokenized[len(tokenized)-1]
|
||||||
|
last = strings.TrimSuffix(last, ")·fm") // < Go 1.5
|
||||||
|
last = strings.TrimSuffix(last, ")-fm") // Go 1.5
|
||||||
|
last = strings.TrimSuffix(last, "·fm") // < Go 1.5
|
||||||
|
last = strings.TrimSuffix(last, "-fm") // Go 1.5
|
||||||
|
return last
|
||||||
|
}
|
||||||
18
staging/src/k8s.io/client-go/1.4/_vendor/github.com/emicklei/go-restful/router.go
generated
Normal file
18
staging/src/k8s.io/client-go/1.4/_vendor/github.com/emicklei/go-restful/router.go
generated
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
package restful
|
||||||
|
|
||||||
|
// Copyright 2013 Ernest Micklei. All rights reserved.
|
||||||
|
// Use of this source code is governed by a license
|
||||||
|
// that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
import "net/http"
|
||||||
|
|
||||||
|
// A RouteSelector finds the best matching Route given the input HTTP Request
|
||||||
|
type RouteSelector interface {
|
||||||
|
|
||||||
|
// SelectRoute finds a Route given the input HTTP Request and a list of WebServices.
|
||||||
|
// It returns a selected Route and its containing WebService or an error indicating
|
||||||
|
// a problem.
|
||||||
|
SelectRoute(
|
||||||
|
webServices []*WebService,
|
||||||
|
httpRequest *http.Request) (selectedService *WebService, selected *Route, err error)
|
||||||
|
}
|
||||||
23
staging/src/k8s.io/client-go/1.4/_vendor/github.com/emicklei/go-restful/service_error.go
generated
Normal file
23
staging/src/k8s.io/client-go/1.4/_vendor/github.com/emicklei/go-restful/service_error.go
generated
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
package restful
|
||||||
|
|
||||||
|
// Copyright 2013 Ernest Micklei. All rights reserved.
|
||||||
|
// Use of this source code is governed by a license
|
||||||
|
// that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
import "fmt"
|
||||||
|
|
||||||
|
// ServiceError is a transport object to pass information about a non-Http error occurred in a WebService while processing a request.
|
||||||
|
type ServiceError struct {
|
||||||
|
Code int
|
||||||
|
Message string
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewError returns a ServiceError using the code and reason
|
||||||
|
func NewError(code int, message string) ServiceError {
|
||||||
|
return ServiceError{Code: code, Message: message}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Error returns a text representation of the service error
|
||||||
|
func (s ServiceError) Error() string {
|
||||||
|
return fmt.Sprintf("[ServiceError:%v] %v", s.Code, s.Message)
|
||||||
|
}
|
||||||
43
staging/src/k8s.io/client-go/1.4/_vendor/github.com/emicklei/go-restful/swagger/CHANGES.md
generated
Normal file
43
staging/src/k8s.io/client-go/1.4/_vendor/github.com/emicklei/go-restful/swagger/CHANGES.md
generated
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
Change history of swagger
|
||||||
|
=
|
||||||
|
2015-10-16
|
||||||
|
- add type override mechanism for swagger models (MR 254, nathanejohnson)
|
||||||
|
- replace uses of wildcard in generated apidocs (issue 251)
|
||||||
|
|
||||||
|
2015-05-25
|
||||||
|
- (api break) changed the type of Properties in Model
|
||||||
|
- (api break) changed the type of Models in ApiDeclaration
|
||||||
|
- (api break) changed the parameter type of PostBuildDeclarationMapFunc
|
||||||
|
|
||||||
|
2015-04-09
|
||||||
|
- add ModelBuildable interface for customization of Model
|
||||||
|
|
||||||
|
2015-03-17
|
||||||
|
- preserve order of Routes per WebService in Swagger listing
|
||||||
|
- fix use of $ref and type in Swagger models
|
||||||
|
- add api version to listing
|
||||||
|
|
||||||
|
2014-11-14
|
||||||
|
- operation parameters are now sorted using ordering path,query,form,header,body
|
||||||
|
|
||||||
|
2014-11-12
|
||||||
|
- respect omitempty tag value for embedded structs
|
||||||
|
- expose ApiVersion of WebService to Swagger ApiDeclaration
|
||||||
|
|
||||||
|
2014-05-29
|
||||||
|
- (api add) Ability to define custom http.Handler to serve swagger-ui static files
|
||||||
|
|
||||||
|
2014-05-04
|
||||||
|
- (fix) include model for array element type of response
|
||||||
|
|
||||||
|
2014-01-03
|
||||||
|
- (fix) do not add primitive type to the Api models
|
||||||
|
|
||||||
|
2013-11-27
|
||||||
|
- (fix) make Swagger work for WebServices with root ("/" or "") paths
|
||||||
|
|
||||||
|
2013-10-29
|
||||||
|
- (api add) package variable LogInfo to customize logging function
|
||||||
|
|
||||||
|
2013-10-15
|
||||||
|
- upgraded to spec version 1.2 (https://github.com/wordnik/swagger-core/wiki/1.2-transition)
|
||||||
@@ -0,0 +1,64 @@
|
|||||||
|
package swagger
|
||||||
|
|
||||||
|
// Copyright 2015 Ernest Micklei. All rights reserved.
|
||||||
|
// Use of this source code is governed by a license
|
||||||
|
// that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/json"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ApiDeclarationList maintains an ordered list of ApiDeclaration.
|
||||||
|
type ApiDeclarationList struct {
|
||||||
|
List []ApiDeclaration
|
||||||
|
}
|
||||||
|
|
||||||
|
// At returns the ApiDeclaration by its path unless absent, then ok is false
|
||||||
|
func (l *ApiDeclarationList) At(path string) (a ApiDeclaration, ok bool) {
|
||||||
|
for _, each := range l.List {
|
||||||
|
if each.ResourcePath == path {
|
||||||
|
return each, true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return a, false
|
||||||
|
}
|
||||||
|
|
||||||
|
// Put adds or replaces a ApiDeclaration with this name
|
||||||
|
func (l *ApiDeclarationList) Put(path string, a ApiDeclaration) {
|
||||||
|
// maybe replace existing
|
||||||
|
for i, each := range l.List {
|
||||||
|
if each.ResourcePath == path {
|
||||||
|
// replace
|
||||||
|
l.List[i] = a
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// add
|
||||||
|
l.List = append(l.List, a)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Do enumerates all the properties, each with its assigned name
|
||||||
|
func (l *ApiDeclarationList) Do(block func(path string, decl ApiDeclaration)) {
|
||||||
|
for _, each := range l.List {
|
||||||
|
block(each.ResourcePath, each)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// MarshalJSON writes the ModelPropertyList as if it was a map[string]ModelProperty
|
||||||
|
func (l ApiDeclarationList) MarshalJSON() ([]byte, error) {
|
||||||
|
var buf bytes.Buffer
|
||||||
|
encoder := json.NewEncoder(&buf)
|
||||||
|
buf.WriteString("{\n")
|
||||||
|
for i, each := range l.List {
|
||||||
|
buf.WriteString("\"")
|
||||||
|
buf.WriteString(each.ResourcePath)
|
||||||
|
buf.WriteString("\": ")
|
||||||
|
encoder.Encode(each)
|
||||||
|
if i < len(l.List)-1 {
|
||||||
|
buf.WriteString(",\n")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
buf.WriteString("}")
|
||||||
|
return buf.Bytes(), nil
|
||||||
|
}
|
||||||
38
staging/src/k8s.io/client-go/1.4/_vendor/github.com/emicklei/go-restful/swagger/config.go
generated
Normal file
38
staging/src/k8s.io/client-go/1.4/_vendor/github.com/emicklei/go-restful/swagger/config.go
generated
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
package swagger
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/emicklei/go-restful"
|
||||||
|
)
|
||||||
|
|
||||||
|
// PostBuildDeclarationMapFunc can be used to modify the api declaration map.
|
||||||
|
type PostBuildDeclarationMapFunc func(apiDeclarationMap *ApiDeclarationList)
|
||||||
|
|
||||||
|
type MapSchemaFormatFunc func(typeName string) string
|
||||||
|
|
||||||
|
type Config struct {
|
||||||
|
// url where the services are available, e.g. http://localhost:8080
|
||||||
|
// if left empty then the basePath of Swagger is taken from the actual request
|
||||||
|
WebServicesUrl string
|
||||||
|
// path where the JSON api is avaiable , e.g. /apidocs
|
||||||
|
ApiPath string
|
||||||
|
// [optional] path where the swagger UI will be served, e.g. /swagger
|
||||||
|
SwaggerPath string
|
||||||
|
// [optional] location of folder containing Swagger HTML5 application index.html
|
||||||
|
SwaggerFilePath string
|
||||||
|
// api listing is constructed from this list of restful WebServices.
|
||||||
|
WebServices []*restful.WebService
|
||||||
|
// will serve all static content (scripts,pages,images)
|
||||||
|
StaticHandler http.Handler
|
||||||
|
// [optional] on default CORS (Cross-Origin-Resource-Sharing) is enabled.
|
||||||
|
DisableCORS bool
|
||||||
|
// Top-level API version. Is reflected in the resource listing.
|
||||||
|
ApiVersion string
|
||||||
|
// If set then call this handler after building the complete ApiDeclaration Map
|
||||||
|
PostBuildHandler PostBuildDeclarationMapFunc
|
||||||
|
// Swagger global info struct
|
||||||
|
Info Info
|
||||||
|
// [optional] If set, model builder should call this handler to get addition typename-to-swagger-format-field convertion.
|
||||||
|
SchemaFormatHandler MapSchemaFormatFunc
|
||||||
|
}
|
||||||
436
staging/src/k8s.io/client-go/1.4/_vendor/github.com/emicklei/go-restful/swagger/model_builder.go
generated
Normal file
436
staging/src/k8s.io/client-go/1.4/_vendor/github.com/emicklei/go-restful/swagger/model_builder.go
generated
Normal file
@@ -0,0 +1,436 @@
|
|||||||
|
package swagger
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"reflect"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ModelBuildable is used for extending Structs that need more control over
|
||||||
|
// how the Model appears in the Swagger api declaration.
|
||||||
|
type ModelBuildable interface {
|
||||||
|
PostBuildModel(m *Model) *Model
|
||||||
|
}
|
||||||
|
|
||||||
|
type modelBuilder struct {
|
||||||
|
Models *ModelList
|
||||||
|
Config *Config
|
||||||
|
}
|
||||||
|
|
||||||
|
type documentable interface {
|
||||||
|
SwaggerDoc() map[string]string
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if this structure has a method with signature func (<theModel>) SwaggerDoc() map[string]string
|
||||||
|
// If it exists, retrive the documentation and overwrite all struct tag descriptions
|
||||||
|
func getDocFromMethodSwaggerDoc2(model reflect.Type) map[string]string {
|
||||||
|
if docable, ok := reflect.New(model).Elem().Interface().(documentable); ok {
|
||||||
|
return docable.SwaggerDoc()
|
||||||
|
}
|
||||||
|
return make(map[string]string)
|
||||||
|
}
|
||||||
|
|
||||||
|
// addModelFrom creates and adds a Model to the builder and detects and calls
|
||||||
|
// the post build hook for customizations
|
||||||
|
func (b modelBuilder) addModelFrom(sample interface{}) {
|
||||||
|
if modelOrNil := b.addModel(reflect.TypeOf(sample), ""); modelOrNil != nil {
|
||||||
|
// allow customizations
|
||||||
|
if buildable, ok := sample.(ModelBuildable); ok {
|
||||||
|
modelOrNil = buildable.PostBuildModel(modelOrNil)
|
||||||
|
b.Models.Put(modelOrNil.Id, *modelOrNil)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b modelBuilder) addModel(st reflect.Type, nameOverride string) *Model {
|
||||||
|
modelName := b.keyFrom(st)
|
||||||
|
if nameOverride != "" {
|
||||||
|
modelName = nameOverride
|
||||||
|
}
|
||||||
|
// no models needed for primitive types
|
||||||
|
if b.isPrimitiveType(modelName) {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
// see if we already have visited this model
|
||||||
|
if _, ok := b.Models.At(modelName); ok {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
sm := Model{
|
||||||
|
Id: modelName,
|
||||||
|
Required: []string{},
|
||||||
|
Properties: ModelPropertyList{}}
|
||||||
|
|
||||||
|
// reference the model before further initializing (enables recursive structs)
|
||||||
|
b.Models.Put(modelName, sm)
|
||||||
|
|
||||||
|
// check for slice or array
|
||||||
|
if st.Kind() == reflect.Slice || st.Kind() == reflect.Array {
|
||||||
|
b.addModel(st.Elem(), "")
|
||||||
|
return &sm
|
||||||
|
}
|
||||||
|
// check for structure or primitive type
|
||||||
|
if st.Kind() != reflect.Struct {
|
||||||
|
return &sm
|
||||||
|
}
|
||||||
|
|
||||||
|
fullDoc := getDocFromMethodSwaggerDoc2(st)
|
||||||
|
modelDescriptions := []string{}
|
||||||
|
|
||||||
|
for i := 0; i < st.NumField(); i++ {
|
||||||
|
field := st.Field(i)
|
||||||
|
jsonName, modelDescription, prop := b.buildProperty(field, &sm, modelName)
|
||||||
|
if len(modelDescription) > 0 {
|
||||||
|
modelDescriptions = append(modelDescriptions, modelDescription)
|
||||||
|
}
|
||||||
|
|
||||||
|
// add if not omitted
|
||||||
|
if len(jsonName) != 0 {
|
||||||
|
// update description
|
||||||
|
if fieldDoc, ok := fullDoc[jsonName]; ok {
|
||||||
|
prop.Description = fieldDoc
|
||||||
|
}
|
||||||
|
// update Required
|
||||||
|
if b.isPropertyRequired(field) {
|
||||||
|
sm.Required = append(sm.Required, jsonName)
|
||||||
|
}
|
||||||
|
sm.Properties.Put(jsonName, prop)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// We always overwrite documentation if SwaggerDoc method exists
|
||||||
|
// "" is special for documenting the struct itself
|
||||||
|
if modelDoc, ok := fullDoc[""]; ok {
|
||||||
|
sm.Description = modelDoc
|
||||||
|
} else if len(modelDescriptions) != 0 {
|
||||||
|
sm.Description = strings.Join(modelDescriptions, "\n")
|
||||||
|
}
|
||||||
|
|
||||||
|
// update model builder with completed model
|
||||||
|
b.Models.Put(modelName, sm)
|
||||||
|
|
||||||
|
return &sm
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b modelBuilder) isPropertyRequired(field reflect.StructField) bool {
|
||||||
|
required := true
|
||||||
|
if jsonTag := field.Tag.Get("json"); jsonTag != "" {
|
||||||
|
s := strings.Split(jsonTag, ",")
|
||||||
|
if len(s) > 1 && s[1] == "omitempty" {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return required
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b modelBuilder) buildProperty(field reflect.StructField, model *Model, modelName string) (jsonName, modelDescription string, prop ModelProperty) {
|
||||||
|
jsonName = b.jsonNameOfField(field)
|
||||||
|
if len(jsonName) == 0 {
|
||||||
|
// empty name signals skip property
|
||||||
|
return "", "", prop
|
||||||
|
}
|
||||||
|
|
||||||
|
if tag := field.Tag.Get("modelDescription"); tag != "" {
|
||||||
|
modelDescription = tag
|
||||||
|
}
|
||||||
|
|
||||||
|
prop.setPropertyMetadata(field)
|
||||||
|
if prop.Type != nil {
|
||||||
|
return jsonName, modelDescription, prop
|
||||||
|
}
|
||||||
|
fieldType := field.Type
|
||||||
|
|
||||||
|
// check if type is doing its own marshalling
|
||||||
|
marshalerType := reflect.TypeOf((*json.Marshaler)(nil)).Elem()
|
||||||
|
if fieldType.Implements(marshalerType) {
|
||||||
|
var pType = "string"
|
||||||
|
if prop.Type == nil {
|
||||||
|
prop.Type = &pType
|
||||||
|
}
|
||||||
|
if prop.Format == "" {
|
||||||
|
prop.Format = b.jsonSchemaFormat(fieldType.String())
|
||||||
|
}
|
||||||
|
return jsonName, modelDescription, prop
|
||||||
|
}
|
||||||
|
|
||||||
|
// check if annotation says it is a string
|
||||||
|
if jsonTag := field.Tag.Get("json"); jsonTag != "" {
|
||||||
|
s := strings.Split(jsonTag, ",")
|
||||||
|
if len(s) > 1 && s[1] == "string" {
|
||||||
|
stringt := "string"
|
||||||
|
prop.Type = &stringt
|
||||||
|
return jsonName, modelDescription, prop
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fieldKind := fieldType.Kind()
|
||||||
|
switch {
|
||||||
|
case fieldKind == reflect.Struct:
|
||||||
|
jsonName, prop := b.buildStructTypeProperty(field, jsonName, model)
|
||||||
|
return jsonName, modelDescription, prop
|
||||||
|
case fieldKind == reflect.Slice || fieldKind == reflect.Array:
|
||||||
|
jsonName, prop := b.buildArrayTypeProperty(field, jsonName, modelName)
|
||||||
|
return jsonName, modelDescription, prop
|
||||||
|
case fieldKind == reflect.Ptr:
|
||||||
|
jsonName, prop := b.buildPointerTypeProperty(field, jsonName, modelName)
|
||||||
|
return jsonName, modelDescription, prop
|
||||||
|
case fieldKind == reflect.String:
|
||||||
|
stringt := "string"
|
||||||
|
prop.Type = &stringt
|
||||||
|
return jsonName, modelDescription, prop
|
||||||
|
case fieldKind == reflect.Map:
|
||||||
|
// if it's a map, it's unstructured, and swagger 1.2 can't handle it
|
||||||
|
objectType := "object"
|
||||||
|
prop.Type = &objectType
|
||||||
|
return jsonName, modelDescription, prop
|
||||||
|
}
|
||||||
|
|
||||||
|
if b.isPrimitiveType(fieldType.String()) {
|
||||||
|
mapped := b.jsonSchemaType(fieldType.String())
|
||||||
|
prop.Type = &mapped
|
||||||
|
prop.Format = b.jsonSchemaFormat(fieldType.String())
|
||||||
|
return jsonName, modelDescription, prop
|
||||||
|
}
|
||||||
|
modelType := fieldType.String()
|
||||||
|
prop.Ref = &modelType
|
||||||
|
|
||||||
|
if fieldType.Name() == "" { // override type of anonymous structs
|
||||||
|
nestedTypeName := modelName + "." + jsonName
|
||||||
|
prop.Ref = &nestedTypeName
|
||||||
|
b.addModel(fieldType, nestedTypeName)
|
||||||
|
}
|
||||||
|
return jsonName, modelDescription, prop
|
||||||
|
}
|
||||||
|
|
||||||
|
func hasNamedJSONTag(field reflect.StructField) bool {
|
||||||
|
parts := strings.Split(field.Tag.Get("json"), ",")
|
||||||
|
if len(parts) == 0 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
for _, s := range parts[1:] {
|
||||||
|
if s == "inline" {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return len(parts[0]) > 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b modelBuilder) buildStructTypeProperty(field reflect.StructField, jsonName string, model *Model) (nameJson string, prop ModelProperty) {
|
||||||
|
prop.setPropertyMetadata(field)
|
||||||
|
// Check for type override in tag
|
||||||
|
if prop.Type != nil {
|
||||||
|
return jsonName, prop
|
||||||
|
}
|
||||||
|
fieldType := field.Type
|
||||||
|
// check for anonymous
|
||||||
|
if len(fieldType.Name()) == 0 {
|
||||||
|
// anonymous
|
||||||
|
anonType := model.Id + "." + jsonName
|
||||||
|
b.addModel(fieldType, anonType)
|
||||||
|
prop.Ref = &anonType
|
||||||
|
return jsonName, prop
|
||||||
|
}
|
||||||
|
|
||||||
|
if field.Name == fieldType.Name() && field.Anonymous && !hasNamedJSONTag(field) {
|
||||||
|
// embedded struct
|
||||||
|
sub := modelBuilder{new(ModelList), b.Config}
|
||||||
|
sub.addModel(fieldType, "")
|
||||||
|
subKey := sub.keyFrom(fieldType)
|
||||||
|
// merge properties from sub
|
||||||
|
subModel, _ := sub.Models.At(subKey)
|
||||||
|
subModel.Properties.Do(func(k string, v ModelProperty) {
|
||||||
|
model.Properties.Put(k, v)
|
||||||
|
// if subModel says this property is required then include it
|
||||||
|
required := false
|
||||||
|
for _, each := range subModel.Required {
|
||||||
|
if k == each {
|
||||||
|
required = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if required {
|
||||||
|
model.Required = append(model.Required, k)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
// add all new referenced models
|
||||||
|
sub.Models.Do(func(key string, sub Model) {
|
||||||
|
if key != subKey {
|
||||||
|
if _, ok := b.Models.At(key); !ok {
|
||||||
|
b.Models.Put(key, sub)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
// empty name signals skip property
|
||||||
|
return "", prop
|
||||||
|
}
|
||||||
|
// simple struct
|
||||||
|
b.addModel(fieldType, "")
|
||||||
|
var pType = fieldType.String()
|
||||||
|
prop.Ref = &pType
|
||||||
|
return jsonName, prop
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b modelBuilder) buildArrayTypeProperty(field reflect.StructField, jsonName, modelName string) (nameJson string, prop ModelProperty) {
|
||||||
|
// check for type override in tags
|
||||||
|
prop.setPropertyMetadata(field)
|
||||||
|
if prop.Type != nil {
|
||||||
|
return jsonName, prop
|
||||||
|
}
|
||||||
|
fieldType := field.Type
|
||||||
|
var pType = "array"
|
||||||
|
prop.Type = &pType
|
||||||
|
isPrimitive := b.isPrimitiveType(fieldType.Elem().Name())
|
||||||
|
elemTypeName := b.getElementTypeName(modelName, jsonName, fieldType.Elem())
|
||||||
|
prop.Items = new(Item)
|
||||||
|
if isPrimitive {
|
||||||
|
mapped := b.jsonSchemaType(elemTypeName)
|
||||||
|
prop.Items.Type = &mapped
|
||||||
|
} else {
|
||||||
|
prop.Items.Ref = &elemTypeName
|
||||||
|
}
|
||||||
|
// add|overwrite model for element type
|
||||||
|
if fieldType.Elem().Kind() == reflect.Ptr {
|
||||||
|
fieldType = fieldType.Elem()
|
||||||
|
}
|
||||||
|
if !isPrimitive {
|
||||||
|
b.addModel(fieldType.Elem(), elemTypeName)
|
||||||
|
}
|
||||||
|
return jsonName, prop
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b modelBuilder) buildPointerTypeProperty(field reflect.StructField, jsonName, modelName string) (nameJson string, prop ModelProperty) {
|
||||||
|
prop.setPropertyMetadata(field)
|
||||||
|
// Check for type override in tags
|
||||||
|
if prop.Type != nil {
|
||||||
|
return jsonName, prop
|
||||||
|
}
|
||||||
|
fieldType := field.Type
|
||||||
|
|
||||||
|
// override type of pointer to list-likes
|
||||||
|
if fieldType.Elem().Kind() == reflect.Slice || fieldType.Elem().Kind() == reflect.Array {
|
||||||
|
var pType = "array"
|
||||||
|
prop.Type = &pType
|
||||||
|
isPrimitive := b.isPrimitiveType(fieldType.Elem().Elem().Name())
|
||||||
|
elemName := b.getElementTypeName(modelName, jsonName, fieldType.Elem().Elem())
|
||||||
|
if isPrimitive {
|
||||||
|
primName := b.jsonSchemaType(elemName)
|
||||||
|
prop.Items = &Item{Ref: &primName}
|
||||||
|
} else {
|
||||||
|
prop.Items = &Item{Ref: &elemName}
|
||||||
|
}
|
||||||
|
if !isPrimitive {
|
||||||
|
// add|overwrite model for element type
|
||||||
|
b.addModel(fieldType.Elem().Elem(), elemName)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// non-array, pointer type
|
||||||
|
var pType = b.jsonSchemaType(fieldType.String()[1:]) // no star, include pkg path
|
||||||
|
if b.isPrimitiveType(fieldType.String()[1:]) {
|
||||||
|
prop.Type = &pType
|
||||||
|
prop.Format = b.jsonSchemaFormat(fieldType.String()[1:])
|
||||||
|
return jsonName, prop
|
||||||
|
}
|
||||||
|
prop.Ref = &pType
|
||||||
|
elemName := ""
|
||||||
|
if fieldType.Elem().Name() == "" {
|
||||||
|
elemName = modelName + "." + jsonName
|
||||||
|
prop.Ref = &elemName
|
||||||
|
}
|
||||||
|
b.addModel(fieldType.Elem(), elemName)
|
||||||
|
}
|
||||||
|
return jsonName, prop
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b modelBuilder) getElementTypeName(modelName, jsonName string, t reflect.Type) string {
|
||||||
|
if t.Kind() == reflect.Ptr {
|
||||||
|
return t.String()[1:]
|
||||||
|
}
|
||||||
|
if t.Name() == "" {
|
||||||
|
return modelName + "." + jsonName
|
||||||
|
}
|
||||||
|
return b.keyFrom(t)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b modelBuilder) keyFrom(st reflect.Type) string {
|
||||||
|
key := st.String()
|
||||||
|
if len(st.Name()) == 0 { // unnamed type
|
||||||
|
// Swagger UI has special meaning for [
|
||||||
|
key = strings.Replace(key, "[]", "||", -1)
|
||||||
|
}
|
||||||
|
return key
|
||||||
|
}
|
||||||
|
|
||||||
|
// see also https://golang.org/ref/spec#Numeric_types
|
||||||
|
func (b modelBuilder) isPrimitiveType(modelName string) bool {
|
||||||
|
if len(modelName) == 0 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return strings.Contains("uint uint8 uint16 uint32 uint64 int int8 int16 int32 int64 float32 float64 bool string byte rune time.Time", modelName)
|
||||||
|
}
|
||||||
|
|
||||||
|
// jsonNameOfField returns the name of the field as it should appear in JSON format
|
||||||
|
// An empty string indicates that this field is not part of the JSON representation
|
||||||
|
func (b modelBuilder) jsonNameOfField(field reflect.StructField) string {
|
||||||
|
if jsonTag := field.Tag.Get("json"); jsonTag != "" {
|
||||||
|
s := strings.Split(jsonTag, ",")
|
||||||
|
if s[0] == "-" {
|
||||||
|
// empty name signals skip property
|
||||||
|
return ""
|
||||||
|
} else if s[0] != "" {
|
||||||
|
return s[0]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return field.Name
|
||||||
|
}
|
||||||
|
|
||||||
|
// see also http://json-schema.org/latest/json-schema-testing.html#anchor8
|
||||||
|
func (b modelBuilder) jsonSchemaType(modelName string) string {
|
||||||
|
schemaMap := map[string]string{
|
||||||
|
"uint": "integer",
|
||||||
|
"uint8": "integer",
|
||||||
|
"uint16": "integer",
|
||||||
|
"uint32": "integer",
|
||||||
|
"uint64": "integer",
|
||||||
|
|
||||||
|
"int": "integer",
|
||||||
|
"int8": "integer",
|
||||||
|
"int16": "integer",
|
||||||
|
"int32": "integer",
|
||||||
|
"int64": "integer",
|
||||||
|
|
||||||
|
"byte": "integer",
|
||||||
|
"float64": "number",
|
||||||
|
"float32": "number",
|
||||||
|
"bool": "boolean",
|
||||||
|
"time.Time": "string",
|
||||||
|
}
|
||||||
|
mapped, ok := schemaMap[modelName]
|
||||||
|
if !ok {
|
||||||
|
return modelName // use as is (custom or struct)
|
||||||
|
}
|
||||||
|
return mapped
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b modelBuilder) jsonSchemaFormat(modelName string) string {
|
||||||
|
if b.Config != nil && b.Config.SchemaFormatHandler != nil {
|
||||||
|
if mapped := b.Config.SchemaFormatHandler(modelName); mapped != "" {
|
||||||
|
return mapped
|
||||||
|
}
|
||||||
|
}
|
||||||
|
schemaMap := map[string]string{
|
||||||
|
"int": "int32",
|
||||||
|
"int32": "int32",
|
||||||
|
"int64": "int64",
|
||||||
|
"byte": "byte",
|
||||||
|
"uint": "integer",
|
||||||
|
"uint8": "byte",
|
||||||
|
"float64": "double",
|
||||||
|
"float32": "float",
|
||||||
|
"time.Time": "date-time",
|
||||||
|
"*time.Time": "date-time",
|
||||||
|
}
|
||||||
|
mapped, ok := schemaMap[modelName]
|
||||||
|
if !ok {
|
||||||
|
return "" // no format
|
||||||
|
}
|
||||||
|
return mapped
|
||||||
|
}
|
||||||
86
staging/src/k8s.io/client-go/1.4/_vendor/github.com/emicklei/go-restful/swagger/model_list.go
generated
Normal file
86
staging/src/k8s.io/client-go/1.4/_vendor/github.com/emicklei/go-restful/swagger/model_list.go
generated
Normal file
@@ -0,0 +1,86 @@
|
|||||||
|
package swagger
|
||||||
|
|
||||||
|
// Copyright 2015 Ernest Micklei. All rights reserved.
|
||||||
|
// Use of this source code is governed by a license
|
||||||
|
// that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/json"
|
||||||
|
)
|
||||||
|
|
||||||
|
// NamedModel associates a name with a Model (not using its Id)
|
||||||
|
type NamedModel struct {
|
||||||
|
Name string
|
||||||
|
Model Model
|
||||||
|
}
|
||||||
|
|
||||||
|
// ModelList encapsulates a list of NamedModel (association)
|
||||||
|
type ModelList struct {
|
||||||
|
List []NamedModel
|
||||||
|
}
|
||||||
|
|
||||||
|
// Put adds or replaces a Model by its name
|
||||||
|
func (l *ModelList) Put(name string, model Model) {
|
||||||
|
for i, each := range l.List {
|
||||||
|
if each.Name == name {
|
||||||
|
// replace
|
||||||
|
l.List[i] = NamedModel{name, model}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// add
|
||||||
|
l.List = append(l.List, NamedModel{name, model})
|
||||||
|
}
|
||||||
|
|
||||||
|
// At returns a Model by its name, ok is false if absent
|
||||||
|
func (l *ModelList) At(name string) (m Model, ok bool) {
|
||||||
|
for _, each := range l.List {
|
||||||
|
if each.Name == name {
|
||||||
|
return each.Model, true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return m, false
|
||||||
|
}
|
||||||
|
|
||||||
|
// Do enumerates all the models, each with its assigned name
|
||||||
|
func (l *ModelList) Do(block func(name string, value Model)) {
|
||||||
|
for _, each := range l.List {
|
||||||
|
block(each.Name, each.Model)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// MarshalJSON writes the ModelList as if it was a map[string]Model
|
||||||
|
func (l ModelList) MarshalJSON() ([]byte, error) {
|
||||||
|
var buf bytes.Buffer
|
||||||
|
encoder := json.NewEncoder(&buf)
|
||||||
|
buf.WriteString("{\n")
|
||||||
|
for i, each := range l.List {
|
||||||
|
buf.WriteString("\"")
|
||||||
|
buf.WriteString(each.Name)
|
||||||
|
buf.WriteString("\": ")
|
||||||
|
encoder.Encode(each.Model)
|
||||||
|
if i < len(l.List)-1 {
|
||||||
|
buf.WriteString(",\n")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
buf.WriteString("}")
|
||||||
|
return buf.Bytes(), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalJSON reads back a ModelList. This is an expensive operation.
|
||||||
|
func (l *ModelList) UnmarshalJSON(data []byte) error {
|
||||||
|
raw := map[string]interface{}{}
|
||||||
|
json.NewDecoder(bytes.NewReader(data)).Decode(&raw)
|
||||||
|
for k, v := range raw {
|
||||||
|
// produces JSON bytes for each value
|
||||||
|
data, err := json.Marshal(v)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
var m Model
|
||||||
|
json.NewDecoder(bytes.NewReader(data)).Decode(&m)
|
||||||
|
l.Put(k, m)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
@@ -0,0 +1,66 @@
|
|||||||
|
package swagger
|
||||||
|
|
||||||
|
import (
|
||||||
|
"reflect"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (prop *ModelProperty) setDescription(field reflect.StructField) {
|
||||||
|
if tag := field.Tag.Get("description"); tag != "" {
|
||||||
|
prop.Description = tag
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (prop *ModelProperty) setDefaultValue(field reflect.StructField) {
|
||||||
|
if tag := field.Tag.Get("default"); tag != "" {
|
||||||
|
prop.DefaultValue = Special(tag)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (prop *ModelProperty) setEnumValues(field reflect.StructField) {
|
||||||
|
// We use | to separate the enum values. This value is chosen
|
||||||
|
// since its unlikely to be useful in actual enumeration values.
|
||||||
|
if tag := field.Tag.Get("enum"); tag != "" {
|
||||||
|
prop.Enum = strings.Split(tag, "|")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (prop *ModelProperty) setMaximum(field reflect.StructField) {
|
||||||
|
if tag := field.Tag.Get("maximum"); tag != "" {
|
||||||
|
prop.Maximum = tag
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (prop *ModelProperty) setType(field reflect.StructField) {
|
||||||
|
if tag := field.Tag.Get("type"); tag != "" {
|
||||||
|
prop.Type = &tag
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (prop *ModelProperty) setMinimum(field reflect.StructField) {
|
||||||
|
if tag := field.Tag.Get("minimum"); tag != "" {
|
||||||
|
prop.Minimum = tag
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (prop *ModelProperty) setUniqueItems(field reflect.StructField) {
|
||||||
|
tag := field.Tag.Get("unique")
|
||||||
|
switch tag {
|
||||||
|
case "true":
|
||||||
|
v := true
|
||||||
|
prop.UniqueItems = &v
|
||||||
|
case "false":
|
||||||
|
v := false
|
||||||
|
prop.UniqueItems = &v
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (prop *ModelProperty) setPropertyMetadata(field reflect.StructField) {
|
||||||
|
prop.setDescription(field)
|
||||||
|
prop.setEnumValues(field)
|
||||||
|
prop.setMinimum(field)
|
||||||
|
prop.setMaximum(field)
|
||||||
|
prop.setUniqueItems(field)
|
||||||
|
prop.setDefaultValue(field)
|
||||||
|
prop.setType(field)
|
||||||
|
}
|
||||||
@@ -0,0 +1,87 @@
|
|||||||
|
package swagger
|
||||||
|
|
||||||
|
// Copyright 2015 Ernest Micklei. All rights reserved.
|
||||||
|
// Use of this source code is governed by a license
|
||||||
|
// that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/json"
|
||||||
|
)
|
||||||
|
|
||||||
|
// NamedModelProperty associates a name to a ModelProperty
|
||||||
|
type NamedModelProperty struct {
|
||||||
|
Name string
|
||||||
|
Property ModelProperty
|
||||||
|
}
|
||||||
|
|
||||||
|
// ModelPropertyList encapsulates a list of NamedModelProperty (association)
|
||||||
|
type ModelPropertyList struct {
|
||||||
|
List []NamedModelProperty
|
||||||
|
}
|
||||||
|
|
||||||
|
// At returns the ModelPropety by its name unless absent, then ok is false
|
||||||
|
func (l *ModelPropertyList) At(name string) (p ModelProperty, ok bool) {
|
||||||
|
for _, each := range l.List {
|
||||||
|
if each.Name == name {
|
||||||
|
return each.Property, true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return p, false
|
||||||
|
}
|
||||||
|
|
||||||
|
// Put adds or replaces a ModelProperty with this name
|
||||||
|
func (l *ModelPropertyList) Put(name string, prop ModelProperty) {
|
||||||
|
// maybe replace existing
|
||||||
|
for i, each := range l.List {
|
||||||
|
if each.Name == name {
|
||||||
|
// replace
|
||||||
|
l.List[i] = NamedModelProperty{Name: name, Property: prop}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// add
|
||||||
|
l.List = append(l.List, NamedModelProperty{Name: name, Property: prop})
|
||||||
|
}
|
||||||
|
|
||||||
|
// Do enumerates all the properties, each with its assigned name
|
||||||
|
func (l *ModelPropertyList) Do(block func(name string, value ModelProperty)) {
|
||||||
|
for _, each := range l.List {
|
||||||
|
block(each.Name, each.Property)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// MarshalJSON writes the ModelPropertyList as if it was a map[string]ModelProperty
|
||||||
|
func (l ModelPropertyList) MarshalJSON() ([]byte, error) {
|
||||||
|
var buf bytes.Buffer
|
||||||
|
encoder := json.NewEncoder(&buf)
|
||||||
|
buf.WriteString("{\n")
|
||||||
|
for i, each := range l.List {
|
||||||
|
buf.WriteString("\"")
|
||||||
|
buf.WriteString(each.Name)
|
||||||
|
buf.WriteString("\": ")
|
||||||
|
encoder.Encode(each.Property)
|
||||||
|
if i < len(l.List)-1 {
|
||||||
|
buf.WriteString(",\n")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
buf.WriteString("}")
|
||||||
|
return buf.Bytes(), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalJSON reads back a ModelPropertyList. This is an expensive operation.
|
||||||
|
func (l *ModelPropertyList) UnmarshalJSON(data []byte) error {
|
||||||
|
raw := map[string]interface{}{}
|
||||||
|
json.NewDecoder(bytes.NewReader(data)).Decode(&raw)
|
||||||
|
for k, v := range raw {
|
||||||
|
// produces JSON bytes for each value
|
||||||
|
data, err := json.Marshal(v)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
var m ModelProperty
|
||||||
|
json.NewDecoder(bytes.NewReader(data)).Decode(&m)
|
||||||
|
l.Put(k, m)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
36
staging/src/k8s.io/client-go/1.4/_vendor/github.com/emicklei/go-restful/swagger/ordered_route_map.go
generated
Normal file
36
staging/src/k8s.io/client-go/1.4/_vendor/github.com/emicklei/go-restful/swagger/ordered_route_map.go
generated
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
package swagger
|
||||||
|
|
||||||
|
// Copyright 2015 Ernest Micklei. All rights reserved.
|
||||||
|
// Use of this source code is governed by a license
|
||||||
|
// that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
import "github.com/emicklei/go-restful"
|
||||||
|
|
||||||
|
type orderedRouteMap struct {
|
||||||
|
elements map[string][]restful.Route
|
||||||
|
keys []string
|
||||||
|
}
|
||||||
|
|
||||||
|
func newOrderedRouteMap() *orderedRouteMap {
|
||||||
|
return &orderedRouteMap{
|
||||||
|
elements: map[string][]restful.Route{},
|
||||||
|
keys: []string{},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *orderedRouteMap) Add(key string, route restful.Route) {
|
||||||
|
routes, ok := o.elements[key]
|
||||||
|
if ok {
|
||||||
|
routes = append(routes, route)
|
||||||
|
o.elements[key] = routes
|
||||||
|
return
|
||||||
|
}
|
||||||
|
o.elements[key] = []restful.Route{route}
|
||||||
|
o.keys = append(o.keys, key)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *orderedRouteMap) Do(block func(key string, routes []restful.Route)) {
|
||||||
|
for _, k := range o.keys {
|
||||||
|
block(k, o.elements[k])
|
||||||
|
}
|
||||||
|
}
|
||||||
184
staging/src/k8s.io/client-go/1.4/_vendor/github.com/emicklei/go-restful/swagger/swagger.go
generated
Normal file
184
staging/src/k8s.io/client-go/1.4/_vendor/github.com/emicklei/go-restful/swagger/swagger.go
generated
Normal file
@@ -0,0 +1,184 @@
|
|||||||
|
// Package swagger implements the structures of the Swagger
|
||||||
|
// https://github.com/wordnik/swagger-spec/blob/master/versions/1.2.md
|
||||||
|
package swagger
|
||||||
|
|
||||||
|
const swaggerVersion = "1.2"
|
||||||
|
|
||||||
|
// 4.3.3 Data Type Fields
|
||||||
|
type DataTypeFields struct {
|
||||||
|
Type *string `json:"type,omitempty"` // if Ref not used
|
||||||
|
Ref *string `json:"$ref,omitempty"` // if Type not used
|
||||||
|
Format string `json:"format,omitempty"`
|
||||||
|
DefaultValue Special `json:"defaultValue,omitempty"`
|
||||||
|
Enum []string `json:"enum,omitempty"`
|
||||||
|
Minimum string `json:"minimum,omitempty"`
|
||||||
|
Maximum string `json:"maximum,omitempty"`
|
||||||
|
Items *Item `json:"items,omitempty"`
|
||||||
|
UniqueItems *bool `json:"uniqueItems,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type Special string
|
||||||
|
|
||||||
|
// 4.3.4 Items Object
|
||||||
|
type Item struct {
|
||||||
|
Type *string `json:"type,omitempty"`
|
||||||
|
Ref *string `json:"$ref,omitempty"`
|
||||||
|
Format string `json:"format,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// 5.1 Resource Listing
|
||||||
|
type ResourceListing struct {
|
||||||
|
SwaggerVersion string `json:"swaggerVersion"` // e.g 1.2
|
||||||
|
Apis []Resource `json:"apis"`
|
||||||
|
ApiVersion string `json:"apiVersion"`
|
||||||
|
Info Info `json:"info"`
|
||||||
|
Authorizations []Authorization `json:"authorizations,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// 5.1.2 Resource Object
|
||||||
|
type Resource struct {
|
||||||
|
Path string `json:"path"` // relative or absolute, must start with /
|
||||||
|
Description string `json:"description"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// 5.1.3 Info Object
|
||||||
|
type Info struct {
|
||||||
|
Title string `json:"title"`
|
||||||
|
Description string `json:"description"`
|
||||||
|
TermsOfServiceUrl string `json:"termsOfServiceUrl,omitempty"`
|
||||||
|
Contact string `json:"contact,omitempty"`
|
||||||
|
License string `json:"license,omitempty"`
|
||||||
|
LicenseUrl string `json:"licenseUrl,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// 5.1.5
|
||||||
|
type Authorization struct {
|
||||||
|
Type string `json:"type"`
|
||||||
|
PassAs string `json:"passAs"`
|
||||||
|
Keyname string `json:"keyname"`
|
||||||
|
Scopes []Scope `json:"scopes"`
|
||||||
|
GrantTypes []GrantType `json:"grandTypes"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// 5.1.6, 5.2.11
|
||||||
|
type Scope struct {
|
||||||
|
// Required. The name of the scope.
|
||||||
|
Scope string `json:"scope"`
|
||||||
|
// Recommended. A short description of the scope.
|
||||||
|
Description string `json:"description"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// 5.1.7
|
||||||
|
type GrantType struct {
|
||||||
|
Implicit Implicit `json:"implicit"`
|
||||||
|
AuthorizationCode AuthorizationCode `json:"authorization_code"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// 5.1.8 Implicit Object
|
||||||
|
type Implicit struct {
|
||||||
|
// Required. The login endpoint definition.
|
||||||
|
loginEndpoint LoginEndpoint `json:"loginEndpoint"`
|
||||||
|
// An optional alternative name to standard "access_token" OAuth2 parameter.
|
||||||
|
TokenName string `json:"tokenName"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// 5.1.9 Authorization Code Object
|
||||||
|
type AuthorizationCode struct {
|
||||||
|
TokenRequestEndpoint TokenRequestEndpoint `json:"tokenRequestEndpoint"`
|
||||||
|
TokenEndpoint TokenEndpoint `json:"tokenEndpoint"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// 5.1.10 Login Endpoint Object
|
||||||
|
type LoginEndpoint struct {
|
||||||
|
// Required. The URL of the authorization endpoint for the implicit grant flow. The value SHOULD be in a URL format.
|
||||||
|
Url string `json:"url"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// 5.1.11 Token Request Endpoint Object
|
||||||
|
type TokenRequestEndpoint struct {
|
||||||
|
// Required. The URL of the authorization endpoint for the authentication code grant flow. The value SHOULD be in a URL format.
|
||||||
|
Url string `json:"url"`
|
||||||
|
// An optional alternative name to standard "client_id" OAuth2 parameter.
|
||||||
|
ClientIdName string `json:"clientIdName"`
|
||||||
|
// An optional alternative name to the standard "client_secret" OAuth2 parameter.
|
||||||
|
ClientSecretName string `json:"clientSecretName"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// 5.1.12 Token Endpoint Object
|
||||||
|
type TokenEndpoint struct {
|
||||||
|
// Required. The URL of the token endpoint for the authentication code grant flow. The value SHOULD be in a URL format.
|
||||||
|
Url string `json:"url"`
|
||||||
|
// An optional alternative name to standard "access_token" OAuth2 parameter.
|
||||||
|
TokenName string `json:"tokenName"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// 5.2 API Declaration
|
||||||
|
type ApiDeclaration struct {
|
||||||
|
SwaggerVersion string `json:"swaggerVersion"`
|
||||||
|
ApiVersion string `json:"apiVersion"`
|
||||||
|
BasePath string `json:"basePath"`
|
||||||
|
ResourcePath string `json:"resourcePath"` // must start with /
|
||||||
|
Apis []Api `json:"apis,omitempty"`
|
||||||
|
Models ModelList `json:"models,omitempty"`
|
||||||
|
Produces []string `json:"produces,omitempty"`
|
||||||
|
Consumes []string `json:"consumes,omitempty"`
|
||||||
|
Authorizations []Authorization `json:"authorizations,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// 5.2.2 API Object
|
||||||
|
type Api struct {
|
||||||
|
Path string `json:"path"` // relative or absolute, must start with /
|
||||||
|
Description string `json:"description"`
|
||||||
|
Operations []Operation `json:"operations,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// 5.2.3 Operation Object
|
||||||
|
type Operation struct {
|
||||||
|
DataTypeFields
|
||||||
|
Method string `json:"method"`
|
||||||
|
Summary string `json:"summary,omitempty"`
|
||||||
|
Notes string `json:"notes,omitempty"`
|
||||||
|
Nickname string `json:"nickname"`
|
||||||
|
Authorizations []Authorization `json:"authorizations,omitempty"`
|
||||||
|
Parameters []Parameter `json:"parameters"`
|
||||||
|
ResponseMessages []ResponseMessage `json:"responseMessages,omitempty"` // optional
|
||||||
|
Produces []string `json:"produces,omitempty"`
|
||||||
|
Consumes []string `json:"consumes,omitempty"`
|
||||||
|
Deprecated string `json:"deprecated,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// 5.2.4 Parameter Object
|
||||||
|
type Parameter struct {
|
||||||
|
DataTypeFields
|
||||||
|
ParamType string `json:"paramType"` // path,query,body,header,form
|
||||||
|
Name string `json:"name"`
|
||||||
|
Description string `json:"description"`
|
||||||
|
Required bool `json:"required"`
|
||||||
|
AllowMultiple bool `json:"allowMultiple"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// 5.2.5 Response Message Object
|
||||||
|
type ResponseMessage struct {
|
||||||
|
Code int `json:"code"`
|
||||||
|
Message string `json:"message"`
|
||||||
|
ResponseModel string `json:"responseModel,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// 5.2.6, 5.2.7 Models Object
|
||||||
|
type Model struct {
|
||||||
|
Id string `json:"id"`
|
||||||
|
Description string `json:"description,omitempty"`
|
||||||
|
Required []string `json:"required,omitempty"`
|
||||||
|
Properties ModelPropertyList `json:"properties"`
|
||||||
|
SubTypes []string `json:"subTypes,omitempty"`
|
||||||
|
Discriminator string `json:"discriminator,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// 5.2.8 Properties Object
|
||||||
|
type ModelProperty struct {
|
||||||
|
DataTypeFields
|
||||||
|
Description string `json:"description,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// 5.2.10
|
||||||
|
type Authorizations map[string]Authorization
|
||||||
21
staging/src/k8s.io/client-go/1.4/_vendor/github.com/emicklei/go-restful/swagger/swagger_builder.go
generated
Normal file
21
staging/src/k8s.io/client-go/1.4/_vendor/github.com/emicklei/go-restful/swagger/swagger_builder.go
generated
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
package swagger
|
||||||
|
|
||||||
|
type SwaggerBuilder struct {
|
||||||
|
SwaggerService
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewSwaggerBuilder(config Config) *SwaggerBuilder {
|
||||||
|
return &SwaggerBuilder{*newSwaggerService(config)}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (sb SwaggerBuilder) ProduceListing() ResourceListing {
|
||||||
|
return sb.SwaggerService.produceListing()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (sb SwaggerBuilder) ProduceAllDeclarations() map[string]ApiDeclaration {
|
||||||
|
return sb.SwaggerService.produceAllDeclarations()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (sb SwaggerBuilder) ProduceDeclarations(route string) (*ApiDeclaration, bool) {
|
||||||
|
return sb.SwaggerService.produceDeclarations(route)
|
||||||
|
}
|
||||||
440
staging/src/k8s.io/client-go/1.4/_vendor/github.com/emicklei/go-restful/swagger/swagger_webservice.go
generated
Normal file
440
staging/src/k8s.io/client-go/1.4/_vendor/github.com/emicklei/go-restful/swagger/swagger_webservice.go
generated
Normal file
@@ -0,0 +1,440 @@
|
|||||||
|
package swagger
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/emicklei/go-restful"
|
||||||
|
// "github.com/emicklei/hopwatch"
|
||||||
|
"net/http"
|
||||||
|
"reflect"
|
||||||
|
"sort"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/emicklei/go-restful/log"
|
||||||
|
)
|
||||||
|
|
||||||
|
type SwaggerService struct {
|
||||||
|
config Config
|
||||||
|
apiDeclarationMap *ApiDeclarationList
|
||||||
|
}
|
||||||
|
|
||||||
|
func newSwaggerService(config Config) *SwaggerService {
|
||||||
|
sws := &SwaggerService{
|
||||||
|
config: config,
|
||||||
|
apiDeclarationMap: new(ApiDeclarationList)}
|
||||||
|
|
||||||
|
// Build all ApiDeclarations
|
||||||
|
for _, each := range config.WebServices {
|
||||||
|
rootPath := each.RootPath()
|
||||||
|
// skip the api service itself
|
||||||
|
if rootPath != config.ApiPath {
|
||||||
|
if rootPath == "" || rootPath == "/" {
|
||||||
|
// use routes
|
||||||
|
for _, route := range each.Routes() {
|
||||||
|
entry := staticPathFromRoute(route)
|
||||||
|
_, exists := sws.apiDeclarationMap.At(entry)
|
||||||
|
if !exists {
|
||||||
|
sws.apiDeclarationMap.Put(entry, sws.composeDeclaration(each, entry))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else { // use root path
|
||||||
|
sws.apiDeclarationMap.Put(each.RootPath(), sws.composeDeclaration(each, each.RootPath()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// if specified then call the PostBuilderHandler
|
||||||
|
if config.PostBuildHandler != nil {
|
||||||
|
config.PostBuildHandler(sws.apiDeclarationMap)
|
||||||
|
}
|
||||||
|
return sws
|
||||||
|
}
|
||||||
|
|
||||||
|
// LogInfo is the function that is called when this package needs to log. It defaults to log.Printf
|
||||||
|
var LogInfo = func(format string, v ...interface{}) {
|
||||||
|
// use the restful package-wide logger
|
||||||
|
log.Printf(format, v...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// InstallSwaggerService add the WebService that provides the API documentation of all services
|
||||||
|
// conform the Swagger documentation specifcation. (https://github.com/wordnik/swagger-core/wiki).
|
||||||
|
func InstallSwaggerService(aSwaggerConfig Config) {
|
||||||
|
RegisterSwaggerService(aSwaggerConfig, restful.DefaultContainer)
|
||||||
|
}
|
||||||
|
|
||||||
|
// RegisterSwaggerService add the WebService that provides the API documentation of all services
|
||||||
|
// conform the Swagger documentation specifcation. (https://github.com/wordnik/swagger-core/wiki).
|
||||||
|
func RegisterSwaggerService(config Config, wsContainer *restful.Container) {
|
||||||
|
sws := newSwaggerService(config)
|
||||||
|
ws := new(restful.WebService)
|
||||||
|
ws.Path(config.ApiPath)
|
||||||
|
ws.Produces(restful.MIME_JSON)
|
||||||
|
if config.DisableCORS {
|
||||||
|
ws.Filter(enableCORS)
|
||||||
|
}
|
||||||
|
ws.Route(ws.GET("/").To(sws.getListing))
|
||||||
|
ws.Route(ws.GET("/{a}").To(sws.getDeclarations))
|
||||||
|
ws.Route(ws.GET("/{a}/{b}").To(sws.getDeclarations))
|
||||||
|
ws.Route(ws.GET("/{a}/{b}/{c}").To(sws.getDeclarations))
|
||||||
|
ws.Route(ws.GET("/{a}/{b}/{c}/{d}").To(sws.getDeclarations))
|
||||||
|
ws.Route(ws.GET("/{a}/{b}/{c}/{d}/{e}").To(sws.getDeclarations))
|
||||||
|
ws.Route(ws.GET("/{a}/{b}/{c}/{d}/{e}/{f}").To(sws.getDeclarations))
|
||||||
|
ws.Route(ws.GET("/{a}/{b}/{c}/{d}/{e}/{f}/{g}").To(sws.getDeclarations))
|
||||||
|
LogInfo("[restful/swagger] listing is available at %v%v", config.WebServicesUrl, config.ApiPath)
|
||||||
|
wsContainer.Add(ws)
|
||||||
|
|
||||||
|
// Check paths for UI serving
|
||||||
|
if config.StaticHandler == nil && config.SwaggerFilePath != "" && config.SwaggerPath != "" {
|
||||||
|
swaggerPathSlash := config.SwaggerPath
|
||||||
|
// path must end with slash /
|
||||||
|
if "/" != config.SwaggerPath[len(config.SwaggerPath)-1:] {
|
||||||
|
LogInfo("[restful/swagger] use corrected SwaggerPath ; must end with slash (/)")
|
||||||
|
swaggerPathSlash += "/"
|
||||||
|
}
|
||||||
|
|
||||||
|
LogInfo("[restful/swagger] %v%v is mapped to folder %v", config.WebServicesUrl, swaggerPathSlash, config.SwaggerFilePath)
|
||||||
|
wsContainer.Handle(swaggerPathSlash, http.StripPrefix(swaggerPathSlash, http.FileServer(http.Dir(config.SwaggerFilePath))))
|
||||||
|
|
||||||
|
//if we define a custom static handler use it
|
||||||
|
} else if config.StaticHandler != nil && config.SwaggerPath != "" {
|
||||||
|
swaggerPathSlash := config.SwaggerPath
|
||||||
|
// path must end with slash /
|
||||||
|
if "/" != config.SwaggerPath[len(config.SwaggerPath)-1:] {
|
||||||
|
LogInfo("[restful/swagger] use corrected SwaggerFilePath ; must end with slash (/)")
|
||||||
|
swaggerPathSlash += "/"
|
||||||
|
|
||||||
|
}
|
||||||
|
LogInfo("[restful/swagger] %v%v is mapped to custom Handler %T", config.WebServicesUrl, swaggerPathSlash, config.StaticHandler)
|
||||||
|
wsContainer.Handle(swaggerPathSlash, config.StaticHandler)
|
||||||
|
|
||||||
|
} else {
|
||||||
|
LogInfo("[restful/swagger] Swagger(File)Path is empty ; no UI is served")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func staticPathFromRoute(r restful.Route) string {
|
||||||
|
static := r.Path
|
||||||
|
bracket := strings.Index(static, "{")
|
||||||
|
if bracket <= 1 { // result cannot be empty
|
||||||
|
return static
|
||||||
|
}
|
||||||
|
if bracket != -1 {
|
||||||
|
static = r.Path[:bracket]
|
||||||
|
}
|
||||||
|
if strings.HasSuffix(static, "/") {
|
||||||
|
return static[:len(static)-1]
|
||||||
|
} else {
|
||||||
|
return static
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func enableCORS(req *restful.Request, resp *restful.Response, chain *restful.FilterChain) {
|
||||||
|
if origin := req.HeaderParameter(restful.HEADER_Origin); origin != "" {
|
||||||
|
// prevent duplicate header
|
||||||
|
if len(resp.Header().Get(restful.HEADER_AccessControlAllowOrigin)) == 0 {
|
||||||
|
resp.AddHeader(restful.HEADER_AccessControlAllowOrigin, origin)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
chain.ProcessFilter(req, resp)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (sws SwaggerService) getListing(req *restful.Request, resp *restful.Response) {
|
||||||
|
listing := sws.produceListing()
|
||||||
|
resp.WriteAsJson(listing)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (sws SwaggerService) produceListing() ResourceListing {
|
||||||
|
listing := ResourceListing{SwaggerVersion: swaggerVersion, ApiVersion: sws.config.ApiVersion, Info: sws.config.Info}
|
||||||
|
sws.apiDeclarationMap.Do(func(k string, v ApiDeclaration) {
|
||||||
|
ref := Resource{Path: k}
|
||||||
|
if len(v.Apis) > 0 { // use description of first (could still be empty)
|
||||||
|
ref.Description = v.Apis[0].Description
|
||||||
|
}
|
||||||
|
listing.Apis = append(listing.Apis, ref)
|
||||||
|
})
|
||||||
|
return listing
|
||||||
|
}
|
||||||
|
|
||||||
|
func (sws SwaggerService) getDeclarations(req *restful.Request, resp *restful.Response) {
|
||||||
|
decl, ok := sws.produceDeclarations(composeRootPath(req))
|
||||||
|
if !ok {
|
||||||
|
resp.WriteErrorString(http.StatusNotFound, "ApiDeclaration not found")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// unless WebServicesUrl is given
|
||||||
|
if len(sws.config.WebServicesUrl) == 0 {
|
||||||
|
// update base path from the actual request
|
||||||
|
// TODO how to detect https? assume http for now
|
||||||
|
var host string
|
||||||
|
// X-Forwarded-Host or Host or Request.Host
|
||||||
|
hostvalues, ok := req.Request.Header["X-Forwarded-Host"] // apache specific?
|
||||||
|
if !ok || len(hostvalues) == 0 {
|
||||||
|
forwarded, ok := req.Request.Header["Host"] // without reverse-proxy
|
||||||
|
if !ok || len(forwarded) == 0 {
|
||||||
|
// fallback to Host field
|
||||||
|
host = req.Request.Host
|
||||||
|
} else {
|
||||||
|
host = forwarded[0]
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
host = hostvalues[0]
|
||||||
|
}
|
||||||
|
// inspect Referer for the scheme (http vs https)
|
||||||
|
scheme := "http"
|
||||||
|
if referer := req.Request.Header["Referer"]; len(referer) > 0 {
|
||||||
|
if strings.HasPrefix(referer[0], "https") {
|
||||||
|
scheme = "https"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
decl.BasePath = fmt.Sprintf("%s://%s", scheme, host)
|
||||||
|
}
|
||||||
|
resp.WriteAsJson(decl)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (sws SwaggerService) produceAllDeclarations() map[string]ApiDeclaration {
|
||||||
|
decls := map[string]ApiDeclaration{}
|
||||||
|
sws.apiDeclarationMap.Do(func(k string, v ApiDeclaration) {
|
||||||
|
decls[k] = v
|
||||||
|
})
|
||||||
|
return decls
|
||||||
|
}
|
||||||
|
|
||||||
|
func (sws SwaggerService) produceDeclarations(route string) (*ApiDeclaration, bool) {
|
||||||
|
decl, ok := sws.apiDeclarationMap.At(route)
|
||||||
|
if !ok {
|
||||||
|
return nil, false
|
||||||
|
}
|
||||||
|
decl.BasePath = sws.config.WebServicesUrl
|
||||||
|
return &decl, true
|
||||||
|
}
|
||||||
|
|
||||||
|
// composeDeclaration uses all routes and parameters to create a ApiDeclaration
|
||||||
|
func (sws SwaggerService) composeDeclaration(ws *restful.WebService, pathPrefix string) ApiDeclaration {
|
||||||
|
decl := ApiDeclaration{
|
||||||
|
SwaggerVersion: swaggerVersion,
|
||||||
|
BasePath: sws.config.WebServicesUrl,
|
||||||
|
ResourcePath: pathPrefix,
|
||||||
|
Models: ModelList{},
|
||||||
|
ApiVersion: ws.Version()}
|
||||||
|
|
||||||
|
// collect any path parameters
|
||||||
|
rootParams := []Parameter{}
|
||||||
|
for _, param := range ws.PathParameters() {
|
||||||
|
rootParams = append(rootParams, asSwaggerParameter(param.Data()))
|
||||||
|
}
|
||||||
|
// aggregate by path
|
||||||
|
pathToRoutes := newOrderedRouteMap()
|
||||||
|
for _, other := range ws.Routes() {
|
||||||
|
if strings.HasPrefix(other.Path, pathPrefix) {
|
||||||
|
pathToRoutes.Add(other.Path, other)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pathToRoutes.Do(func(path string, routes []restful.Route) {
|
||||||
|
api := Api{Path: strings.TrimSuffix(withoutWildcard(path), "/"), Description: ws.Documentation()}
|
||||||
|
voidString := "void"
|
||||||
|
for _, route := range routes {
|
||||||
|
operation := Operation{
|
||||||
|
Method: route.Method,
|
||||||
|
Summary: route.Doc,
|
||||||
|
Notes: route.Notes,
|
||||||
|
// Type gets overwritten if there is a write sample
|
||||||
|
DataTypeFields: DataTypeFields{Type: &voidString},
|
||||||
|
Parameters: []Parameter{},
|
||||||
|
Nickname: route.Operation,
|
||||||
|
ResponseMessages: composeResponseMessages(route, &decl, &sws.config)}
|
||||||
|
|
||||||
|
operation.Consumes = route.Consumes
|
||||||
|
operation.Produces = route.Produces
|
||||||
|
|
||||||
|
// share root params if any
|
||||||
|
for _, swparam := range rootParams {
|
||||||
|
operation.Parameters = append(operation.Parameters, swparam)
|
||||||
|
}
|
||||||
|
// route specific params
|
||||||
|
for _, param := range route.ParameterDocs {
|
||||||
|
operation.Parameters = append(operation.Parameters, asSwaggerParameter(param.Data()))
|
||||||
|
}
|
||||||
|
|
||||||
|
sws.addModelsFromRouteTo(&operation, route, &decl)
|
||||||
|
api.Operations = append(api.Operations, operation)
|
||||||
|
}
|
||||||
|
decl.Apis = append(decl.Apis, api)
|
||||||
|
})
|
||||||
|
return decl
|
||||||
|
}
|
||||||
|
|
||||||
|
func withoutWildcard(path string) string {
|
||||||
|
if strings.HasSuffix(path, ":*}") {
|
||||||
|
return path[0:len(path)-3] + "}"
|
||||||
|
}
|
||||||
|
return path
|
||||||
|
}
|
||||||
|
|
||||||
|
// composeResponseMessages takes the ResponseErrors (if any) and creates ResponseMessages from them.
|
||||||
|
func composeResponseMessages(route restful.Route, decl *ApiDeclaration, config *Config) (messages []ResponseMessage) {
|
||||||
|
if route.ResponseErrors == nil {
|
||||||
|
return messages
|
||||||
|
}
|
||||||
|
// sort by code
|
||||||
|
codes := sort.IntSlice{}
|
||||||
|
for code, _ := range route.ResponseErrors {
|
||||||
|
codes = append(codes, code)
|
||||||
|
}
|
||||||
|
codes.Sort()
|
||||||
|
for _, code := range codes {
|
||||||
|
each := route.ResponseErrors[code]
|
||||||
|
message := ResponseMessage{
|
||||||
|
Code: code,
|
||||||
|
Message: each.Message,
|
||||||
|
}
|
||||||
|
if each.Model != nil {
|
||||||
|
st := reflect.TypeOf(each.Model)
|
||||||
|
isCollection, st := detectCollectionType(st)
|
||||||
|
modelName := modelBuilder{}.keyFrom(st)
|
||||||
|
if isCollection {
|
||||||
|
modelName = "array[" + modelName + "]"
|
||||||
|
}
|
||||||
|
modelBuilder{Models: &decl.Models, Config: config}.addModel(st, "")
|
||||||
|
// reference the model
|
||||||
|
message.ResponseModel = modelName
|
||||||
|
}
|
||||||
|
messages = append(messages, message)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// addModelsFromRoute takes any read or write sample from the Route and creates a Swagger model from it.
|
||||||
|
func (sws SwaggerService) addModelsFromRouteTo(operation *Operation, route restful.Route, decl *ApiDeclaration) {
|
||||||
|
if route.ReadSample != nil {
|
||||||
|
sws.addModelFromSampleTo(operation, false, route.ReadSample, &decl.Models)
|
||||||
|
}
|
||||||
|
if route.WriteSample != nil {
|
||||||
|
sws.addModelFromSampleTo(operation, true, route.WriteSample, &decl.Models)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func detectCollectionType(st reflect.Type) (bool, reflect.Type) {
|
||||||
|
isCollection := false
|
||||||
|
if st.Kind() == reflect.Slice || st.Kind() == reflect.Array {
|
||||||
|
st = st.Elem()
|
||||||
|
isCollection = true
|
||||||
|
} else {
|
||||||
|
if st.Kind() == reflect.Ptr {
|
||||||
|
if st.Elem().Kind() == reflect.Slice || st.Elem().Kind() == reflect.Array {
|
||||||
|
st = st.Elem().Elem()
|
||||||
|
isCollection = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return isCollection, st
|
||||||
|
}
|
||||||
|
|
||||||
|
// addModelFromSample creates and adds (or overwrites) a Model from a sample resource
|
||||||
|
func (sws SwaggerService) addModelFromSampleTo(operation *Operation, isResponse bool, sample interface{}, models *ModelList) {
|
||||||
|
if isResponse {
|
||||||
|
type_, items := asDataType(sample, &sws.config)
|
||||||
|
operation.Type = type_
|
||||||
|
operation.Items = items
|
||||||
|
}
|
||||||
|
modelBuilder{Models: models, Config: &sws.config}.addModelFrom(sample)
|
||||||
|
}
|
||||||
|
|
||||||
|
func asSwaggerParameter(param restful.ParameterData) Parameter {
|
||||||
|
return Parameter{
|
||||||
|
DataTypeFields: DataTypeFields{
|
||||||
|
Type: ¶m.DataType,
|
||||||
|
Format: asFormat(param.DataType, param.DataFormat),
|
||||||
|
DefaultValue: Special(param.DefaultValue),
|
||||||
|
},
|
||||||
|
Name: param.Name,
|
||||||
|
Description: param.Description,
|
||||||
|
ParamType: asParamType(param.Kind),
|
||||||
|
|
||||||
|
Required: param.Required}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Between 1..7 path parameters is supported
|
||||||
|
func composeRootPath(req *restful.Request) string {
|
||||||
|
path := "/" + req.PathParameter("a")
|
||||||
|
b := req.PathParameter("b")
|
||||||
|
if b == "" {
|
||||||
|
return path
|
||||||
|
}
|
||||||
|
path = path + "/" + b
|
||||||
|
c := req.PathParameter("c")
|
||||||
|
if c == "" {
|
||||||
|
return path
|
||||||
|
}
|
||||||
|
path = path + "/" + c
|
||||||
|
d := req.PathParameter("d")
|
||||||
|
if d == "" {
|
||||||
|
return path
|
||||||
|
}
|
||||||
|
path = path + "/" + d
|
||||||
|
e := req.PathParameter("e")
|
||||||
|
if e == "" {
|
||||||
|
return path
|
||||||
|
}
|
||||||
|
path = path + "/" + e
|
||||||
|
f := req.PathParameter("f")
|
||||||
|
if f == "" {
|
||||||
|
return path
|
||||||
|
}
|
||||||
|
path = path + "/" + f
|
||||||
|
g := req.PathParameter("g")
|
||||||
|
if g == "" {
|
||||||
|
return path
|
||||||
|
}
|
||||||
|
return path + "/" + g
|
||||||
|
}
|
||||||
|
|
||||||
|
func asFormat(dataType string, dataFormat string) string {
|
||||||
|
if dataFormat != "" {
|
||||||
|
return dataFormat
|
||||||
|
}
|
||||||
|
return "" // TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
func asParamType(kind int) string {
|
||||||
|
switch {
|
||||||
|
case kind == restful.PathParameterKind:
|
||||||
|
return "path"
|
||||||
|
case kind == restful.QueryParameterKind:
|
||||||
|
return "query"
|
||||||
|
case kind == restful.BodyParameterKind:
|
||||||
|
return "body"
|
||||||
|
case kind == restful.HeaderParameterKind:
|
||||||
|
return "header"
|
||||||
|
case kind == restful.FormParameterKind:
|
||||||
|
return "form"
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func asDataType(any interface{}, config *Config) (*string, *Item) {
|
||||||
|
// If it's not a collection, return the suggested model name
|
||||||
|
st := reflect.TypeOf(any)
|
||||||
|
isCollection, st := detectCollectionType(st)
|
||||||
|
modelName := modelBuilder{}.keyFrom(st)
|
||||||
|
// if it's not a collection we are done
|
||||||
|
if !isCollection {
|
||||||
|
return &modelName, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// XXX: This is not very elegant
|
||||||
|
// We create an Item object referring to the given model
|
||||||
|
models := ModelList{}
|
||||||
|
mb := modelBuilder{Models: &models, Config: config}
|
||||||
|
mb.addModelFrom(any)
|
||||||
|
|
||||||
|
elemTypeName := mb.getElementTypeName(modelName, "", st)
|
||||||
|
item := new(Item)
|
||||||
|
if mb.isPrimitiveType(elemTypeName) {
|
||||||
|
mapped := mb.jsonSchemaType(elemTypeName)
|
||||||
|
item.Type = &mapped
|
||||||
|
} else {
|
||||||
|
item.Ref = &elemTypeName
|
||||||
|
}
|
||||||
|
tmp := "array"
|
||||||
|
return &tmp, item
|
||||||
|
}
|
||||||
268
staging/src/k8s.io/client-go/1.4/_vendor/github.com/emicklei/go-restful/web_service.go
generated
Normal file
268
staging/src/k8s.io/client-go/1.4/_vendor/github.com/emicklei/go-restful/web_service.go
generated
Normal file
@@ -0,0 +1,268 @@
|
|||||||
|
package restful
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"sync"
|
||||||
|
|
||||||
|
"github.com/emicklei/go-restful/log"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Copyright 2013 Ernest Micklei. All rights reserved.
|
||||||
|
// Use of this source code is governed by a license
|
||||||
|
// that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// WebService holds a collection of Route values that bind a Http Method + URL Path to a function.
|
||||||
|
type WebService struct {
|
||||||
|
rootPath string
|
||||||
|
pathExpr *pathExpression // cached compilation of rootPath as RegExp
|
||||||
|
routes []Route
|
||||||
|
produces []string
|
||||||
|
consumes []string
|
||||||
|
pathParameters []*Parameter
|
||||||
|
filters []FilterFunction
|
||||||
|
documentation string
|
||||||
|
apiVersion string
|
||||||
|
|
||||||
|
dynamicRoutes bool
|
||||||
|
|
||||||
|
// protects 'routes' if dynamic routes are enabled
|
||||||
|
routesLock sync.RWMutex
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *WebService) SetDynamicRoutes(enable bool) {
|
||||||
|
w.dynamicRoutes = enable
|
||||||
|
}
|
||||||
|
|
||||||
|
// compilePathExpression ensures that the path is compiled into a RegEx for those routers that need it.
|
||||||
|
func (w *WebService) compilePathExpression() {
|
||||||
|
compiled, err := newPathExpression(w.rootPath)
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("[restful] invalid path:%s because:%v", w.rootPath, err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
w.pathExpr = compiled
|
||||||
|
}
|
||||||
|
|
||||||
|
// ApiVersion sets the API version for documentation purposes.
|
||||||
|
func (w *WebService) ApiVersion(apiVersion string) *WebService {
|
||||||
|
w.apiVersion = apiVersion
|
||||||
|
return w
|
||||||
|
}
|
||||||
|
|
||||||
|
// Version returns the API version for documentation purposes.
|
||||||
|
func (w WebService) Version() string { return w.apiVersion }
|
||||||
|
|
||||||
|
// Path specifies the root URL template path of the WebService.
|
||||||
|
// All Routes will be relative to this path.
|
||||||
|
func (w *WebService) Path(root string) *WebService {
|
||||||
|
w.rootPath = root
|
||||||
|
if len(w.rootPath) == 0 {
|
||||||
|
w.rootPath = "/"
|
||||||
|
}
|
||||||
|
w.compilePathExpression()
|
||||||
|
return w
|
||||||
|
}
|
||||||
|
|
||||||
|
// Param adds a PathParameter to document parameters used in the root path.
|
||||||
|
func (w *WebService) Param(parameter *Parameter) *WebService {
|
||||||
|
if w.pathParameters == nil {
|
||||||
|
w.pathParameters = []*Parameter{}
|
||||||
|
}
|
||||||
|
w.pathParameters = append(w.pathParameters, parameter)
|
||||||
|
return w
|
||||||
|
}
|
||||||
|
|
||||||
|
// PathParameter creates a new Parameter of kind Path for documentation purposes.
|
||||||
|
// It is initialized as required with string as its DataType.
|
||||||
|
func (w *WebService) PathParameter(name, description string) *Parameter {
|
||||||
|
return PathParameter(name, description)
|
||||||
|
}
|
||||||
|
|
||||||
|
// PathParameter creates a new Parameter of kind Path for documentation purposes.
|
||||||
|
// It is initialized as required with string as its DataType.
|
||||||
|
func PathParameter(name, description string) *Parameter {
|
||||||
|
p := &Parameter{&ParameterData{Name: name, Description: description, Required: true, DataType: "string"}}
|
||||||
|
p.bePath()
|
||||||
|
return p
|
||||||
|
}
|
||||||
|
|
||||||
|
// QueryParameter creates a new Parameter of kind Query for documentation purposes.
|
||||||
|
// It is initialized as not required with string as its DataType.
|
||||||
|
func (w *WebService) QueryParameter(name, description string) *Parameter {
|
||||||
|
return QueryParameter(name, description)
|
||||||
|
}
|
||||||
|
|
||||||
|
// QueryParameter creates a new Parameter of kind Query for documentation purposes.
|
||||||
|
// It is initialized as not required with string as its DataType.
|
||||||
|
func QueryParameter(name, description string) *Parameter {
|
||||||
|
p := &Parameter{&ParameterData{Name: name, Description: description, Required: false, DataType: "string"}}
|
||||||
|
p.beQuery()
|
||||||
|
return p
|
||||||
|
}
|
||||||
|
|
||||||
|
// BodyParameter creates a new Parameter of kind Body for documentation purposes.
|
||||||
|
// It is initialized as required without a DataType.
|
||||||
|
func (w *WebService) BodyParameter(name, description string) *Parameter {
|
||||||
|
return BodyParameter(name, description)
|
||||||
|
}
|
||||||
|
|
||||||
|
// BodyParameter creates a new Parameter of kind Body for documentation purposes.
|
||||||
|
// It is initialized as required without a DataType.
|
||||||
|
func BodyParameter(name, description string) *Parameter {
|
||||||
|
p := &Parameter{&ParameterData{Name: name, Description: description, Required: true}}
|
||||||
|
p.beBody()
|
||||||
|
return p
|
||||||
|
}
|
||||||
|
|
||||||
|
// HeaderParameter creates a new Parameter of kind (Http) Header for documentation purposes.
|
||||||
|
// It is initialized as not required with string as its DataType.
|
||||||
|
func (w *WebService) HeaderParameter(name, description string) *Parameter {
|
||||||
|
return HeaderParameter(name, description)
|
||||||
|
}
|
||||||
|
|
||||||
|
// HeaderParameter creates a new Parameter of kind (Http) Header for documentation purposes.
|
||||||
|
// It is initialized as not required with string as its DataType.
|
||||||
|
func HeaderParameter(name, description string) *Parameter {
|
||||||
|
p := &Parameter{&ParameterData{Name: name, Description: description, Required: false, DataType: "string"}}
|
||||||
|
p.beHeader()
|
||||||
|
return p
|
||||||
|
}
|
||||||
|
|
||||||
|
// FormParameter creates a new Parameter of kind Form (using application/x-www-form-urlencoded) for documentation purposes.
|
||||||
|
// It is initialized as required with string as its DataType.
|
||||||
|
func (w *WebService) FormParameter(name, description string) *Parameter {
|
||||||
|
return FormParameter(name, description)
|
||||||
|
}
|
||||||
|
|
||||||
|
// FormParameter creates a new Parameter of kind Form (using application/x-www-form-urlencoded) for documentation purposes.
|
||||||
|
// It is initialized as required with string as its DataType.
|
||||||
|
func FormParameter(name, description string) *Parameter {
|
||||||
|
p := &Parameter{&ParameterData{Name: name, Description: description, Required: false, DataType: "string"}}
|
||||||
|
p.beForm()
|
||||||
|
return p
|
||||||
|
}
|
||||||
|
|
||||||
|
// Route creates a new Route using the RouteBuilder and add to the ordered list of Routes.
|
||||||
|
func (w *WebService) Route(builder *RouteBuilder) *WebService {
|
||||||
|
w.routesLock.Lock()
|
||||||
|
defer w.routesLock.Unlock()
|
||||||
|
builder.copyDefaults(w.produces, w.consumes)
|
||||||
|
w.routes = append(w.routes, builder.Build())
|
||||||
|
return w
|
||||||
|
}
|
||||||
|
|
||||||
|
// RemoveRoute removes the specified route, looks for something that matches 'path' and 'method'
|
||||||
|
func (w *WebService) RemoveRoute(path, method string) error {
|
||||||
|
if !w.dynamicRoutes {
|
||||||
|
return fmt.Errorf("dynamic routes are not enabled.")
|
||||||
|
}
|
||||||
|
w.routesLock.Lock()
|
||||||
|
defer w.routesLock.Unlock()
|
||||||
|
newRoutes := make([]Route, (len(w.routes) - 1))
|
||||||
|
current := 0
|
||||||
|
for ix := range w.routes {
|
||||||
|
if w.routes[ix].Method == method && w.routes[ix].Path == path {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
newRoutes[current] = w.routes[ix]
|
||||||
|
current = current + 1
|
||||||
|
}
|
||||||
|
w.routes = newRoutes
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Method creates a new RouteBuilder and initialize its http method
|
||||||
|
func (w *WebService) Method(httpMethod string) *RouteBuilder {
|
||||||
|
return new(RouteBuilder).servicePath(w.rootPath).Method(httpMethod)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Produces specifies that this WebService can produce one or more MIME types.
|
||||||
|
// Http requests must have one of these values set for the Accept header.
|
||||||
|
func (w *WebService) Produces(contentTypes ...string) *WebService {
|
||||||
|
w.produces = contentTypes
|
||||||
|
return w
|
||||||
|
}
|
||||||
|
|
||||||
|
// Consumes specifies that this WebService can consume one or more MIME types.
|
||||||
|
// Http requests must have one of these values set for the Content-Type header.
|
||||||
|
func (w *WebService) Consumes(accepts ...string) *WebService {
|
||||||
|
w.consumes = accepts
|
||||||
|
return w
|
||||||
|
}
|
||||||
|
|
||||||
|
// Routes returns the Routes associated with this WebService
|
||||||
|
func (w WebService) Routes() []Route {
|
||||||
|
if !w.dynamicRoutes {
|
||||||
|
return w.routes
|
||||||
|
}
|
||||||
|
// Make a copy of the array to prevent concurrency problems
|
||||||
|
w.routesLock.RLock()
|
||||||
|
defer w.routesLock.RUnlock()
|
||||||
|
result := make([]Route, len(w.routes))
|
||||||
|
for ix := range w.routes {
|
||||||
|
result[ix] = w.routes[ix]
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
// RootPath returns the RootPath associated with this WebService. Default "/"
|
||||||
|
func (w WebService) RootPath() string {
|
||||||
|
return w.rootPath
|
||||||
|
}
|
||||||
|
|
||||||
|
// PathParameters return the path parameter names for (shared amoung its Routes)
|
||||||
|
func (w WebService) PathParameters() []*Parameter {
|
||||||
|
return w.pathParameters
|
||||||
|
}
|
||||||
|
|
||||||
|
// Filter adds a filter function to the chain of filters applicable to all its Routes
|
||||||
|
func (w *WebService) Filter(filter FilterFunction) *WebService {
|
||||||
|
w.filters = append(w.filters, filter)
|
||||||
|
return w
|
||||||
|
}
|
||||||
|
|
||||||
|
// Doc is used to set the documentation of this service.
|
||||||
|
func (w *WebService) Doc(plainText string) *WebService {
|
||||||
|
w.documentation = plainText
|
||||||
|
return w
|
||||||
|
}
|
||||||
|
|
||||||
|
// Documentation returns it.
|
||||||
|
func (w WebService) Documentation() string {
|
||||||
|
return w.documentation
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Convenience methods
|
||||||
|
*/
|
||||||
|
|
||||||
|
// HEAD is a shortcut for .Method("HEAD").Path(subPath)
|
||||||
|
func (w *WebService) HEAD(subPath string) *RouteBuilder {
|
||||||
|
return new(RouteBuilder).servicePath(w.rootPath).Method("HEAD").Path(subPath)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GET is a shortcut for .Method("GET").Path(subPath)
|
||||||
|
func (w *WebService) GET(subPath string) *RouteBuilder {
|
||||||
|
return new(RouteBuilder).servicePath(w.rootPath).Method("GET").Path(subPath)
|
||||||
|
}
|
||||||
|
|
||||||
|
// POST is a shortcut for .Method("POST").Path(subPath)
|
||||||
|
func (w *WebService) POST(subPath string) *RouteBuilder {
|
||||||
|
return new(RouteBuilder).servicePath(w.rootPath).Method("POST").Path(subPath)
|
||||||
|
}
|
||||||
|
|
||||||
|
// PUT is a shortcut for .Method("PUT").Path(subPath)
|
||||||
|
func (w *WebService) PUT(subPath string) *RouteBuilder {
|
||||||
|
return new(RouteBuilder).servicePath(w.rootPath).Method("PUT").Path(subPath)
|
||||||
|
}
|
||||||
|
|
||||||
|
// PATCH is a shortcut for .Method("PATCH").Path(subPath)
|
||||||
|
func (w *WebService) PATCH(subPath string) *RouteBuilder {
|
||||||
|
return new(RouteBuilder).servicePath(w.rootPath).Method("PATCH").Path(subPath)
|
||||||
|
}
|
||||||
|
|
||||||
|
// DELETE is a shortcut for .Method("DELETE").Path(subPath)
|
||||||
|
func (w *WebService) DELETE(subPath string) *RouteBuilder {
|
||||||
|
return new(RouteBuilder).servicePath(w.rootPath).Method("DELETE").Path(subPath)
|
||||||
|
}
|
||||||
39
staging/src/k8s.io/client-go/1.4/_vendor/github.com/emicklei/go-restful/web_service_container.go
generated
Normal file
39
staging/src/k8s.io/client-go/1.4/_vendor/github.com/emicklei/go-restful/web_service_container.go
generated
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
package restful
|
||||||
|
|
||||||
|
// Copyright 2013 Ernest Micklei. All rights reserved.
|
||||||
|
// Use of this source code is governed by a license
|
||||||
|
// that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
)
|
||||||
|
|
||||||
|
// DefaultContainer is a restful.Container that uses http.DefaultServeMux
|
||||||
|
var DefaultContainer *Container
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
DefaultContainer = NewContainer()
|
||||||
|
DefaultContainer.ServeMux = http.DefaultServeMux
|
||||||
|
}
|
||||||
|
|
||||||
|
// If set the true then panics will not be caught to return HTTP 500.
|
||||||
|
// In that case, Route functions are responsible for handling any error situation.
|
||||||
|
// Default value is false = recover from panics. This has performance implications.
|
||||||
|
// OBSOLETE ; use restful.DefaultContainer.DoNotRecover(true)
|
||||||
|
var DoNotRecover = false
|
||||||
|
|
||||||
|
// Add registers a new WebService add it to the DefaultContainer.
|
||||||
|
func Add(service *WebService) {
|
||||||
|
DefaultContainer.Add(service)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Filter appends a container FilterFunction from the DefaultContainer.
|
||||||
|
// These are called before dispatching a http.Request to a WebService.
|
||||||
|
func Filter(filter FilterFunction) {
|
||||||
|
DefaultContainer.Filter(filter)
|
||||||
|
}
|
||||||
|
|
||||||
|
// RegisteredWebServices returns the collections of WebServices from the DefaultContainer
|
||||||
|
func RegisteredWebServices() []*WebService {
|
||||||
|
return DefaultContainer.RegisteredWebServices()
|
||||||
|
}
|
||||||
20
staging/src/k8s.io/client-go/1.4/_vendor/github.com/ghodss/yaml/.gitignore
generated
vendored
Normal file
20
staging/src/k8s.io/client-go/1.4/_vendor/github.com/ghodss/yaml/.gitignore
generated
vendored
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
# OSX leaves these everywhere on SMB shares
|
||||||
|
._*
|
||||||
|
|
||||||
|
# Eclipse files
|
||||||
|
.classpath
|
||||||
|
.project
|
||||||
|
.settings/**
|
||||||
|
|
||||||
|
# Emacs save files
|
||||||
|
*~
|
||||||
|
|
||||||
|
# Vim-related files
|
||||||
|
[._]*.s[a-w][a-z]
|
||||||
|
[._]s[a-w][a-z]
|
||||||
|
*.un~
|
||||||
|
Session.vim
|
||||||
|
.netrwhist
|
||||||
|
|
||||||
|
# Go test binaries
|
||||||
|
*.test
|
||||||
50
staging/src/k8s.io/client-go/1.4/_vendor/github.com/ghodss/yaml/LICENSE
generated
Normal file
50
staging/src/k8s.io/client-go/1.4/_vendor/github.com/ghodss/yaml/LICENSE
generated
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
The MIT License (MIT)
|
||||||
|
|
||||||
|
Copyright (c) 2014 Sam Ghods
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
|
|
||||||
|
|
||||||
|
Copyright (c) 2012 The Go Authors. All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are
|
||||||
|
met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
* Redistributions in binary form must reproduce the above
|
||||||
|
copyright notice, this list of conditions and the following disclaimer
|
||||||
|
in the documentation and/or other materials provided with the
|
||||||
|
distribution.
|
||||||
|
* Neither the name of Google Inc. nor the names of its
|
||||||
|
contributors may be used to endorse or promote products derived from
|
||||||
|
this software without specific prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
497
staging/src/k8s.io/client-go/1.4/_vendor/github.com/ghodss/yaml/fields.go
generated
Normal file
497
staging/src/k8s.io/client-go/1.4/_vendor/github.com/ghodss/yaml/fields.go
generated
Normal file
@@ -0,0 +1,497 @@
|
|||||||
|
// Copyright 2013 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
package yaml
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding"
|
||||||
|
"encoding/json"
|
||||||
|
"reflect"
|
||||||
|
"sort"
|
||||||
|
"strings"
|
||||||
|
"sync"
|
||||||
|
"unicode"
|
||||||
|
"unicode/utf8"
|
||||||
|
)
|
||||||
|
|
||||||
|
// indirect walks down v allocating pointers as needed,
|
||||||
|
// until it gets to a non-pointer.
|
||||||
|
// if it encounters an Unmarshaler, indirect stops and returns that.
|
||||||
|
// if decodingNull is true, indirect stops at the last pointer so it can be set to nil.
|
||||||
|
func indirect(v reflect.Value, decodingNull bool) (json.Unmarshaler, encoding.TextUnmarshaler, reflect.Value) {
|
||||||
|
// If v is a named type and is addressable,
|
||||||
|
// start with its address, so that if the type has pointer methods,
|
||||||
|
// we find them.
|
||||||
|
if v.Kind() != reflect.Ptr && v.Type().Name() != "" && v.CanAddr() {
|
||||||
|
v = v.Addr()
|
||||||
|
}
|
||||||
|
for {
|
||||||
|
// Load value from interface, but only if the result will be
|
||||||
|
// usefully addressable.
|
||||||
|
if v.Kind() == reflect.Interface && !v.IsNil() {
|
||||||
|
e := v.Elem()
|
||||||
|
if e.Kind() == reflect.Ptr && !e.IsNil() && (!decodingNull || e.Elem().Kind() == reflect.Ptr) {
|
||||||
|
v = e
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if v.Kind() != reflect.Ptr {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
if v.Elem().Kind() != reflect.Ptr && decodingNull && v.CanSet() {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if v.IsNil() {
|
||||||
|
v.Set(reflect.New(v.Type().Elem()))
|
||||||
|
}
|
||||||
|
if v.Type().NumMethod() > 0 {
|
||||||
|
if u, ok := v.Interface().(json.Unmarshaler); ok {
|
||||||
|
return u, nil, reflect.Value{}
|
||||||
|
}
|
||||||
|
if u, ok := v.Interface().(encoding.TextUnmarshaler); ok {
|
||||||
|
return nil, u, reflect.Value{}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
v = v.Elem()
|
||||||
|
}
|
||||||
|
return nil, nil, v
|
||||||
|
}
|
||||||
|
|
||||||
|
// A field represents a single field found in a struct.
|
||||||
|
type field struct {
|
||||||
|
name string
|
||||||
|
nameBytes []byte // []byte(name)
|
||||||
|
equalFold func(s, t []byte) bool // bytes.EqualFold or equivalent
|
||||||
|
|
||||||
|
tag bool
|
||||||
|
index []int
|
||||||
|
typ reflect.Type
|
||||||
|
omitEmpty bool
|
||||||
|
quoted bool
|
||||||
|
}
|
||||||
|
|
||||||
|
func fillField(f field) field {
|
||||||
|
f.nameBytes = []byte(f.name)
|
||||||
|
f.equalFold = foldFunc(f.nameBytes)
|
||||||
|
return f
|
||||||
|
}
|
||||||
|
|
||||||
|
// byName sorts field by name, breaking ties with depth,
|
||||||
|
// then breaking ties with "name came from json tag", then
|
||||||
|
// breaking ties with index sequence.
|
||||||
|
type byName []field
|
||||||
|
|
||||||
|
func (x byName) Len() int { return len(x) }
|
||||||
|
|
||||||
|
func (x byName) Swap(i, j int) { x[i], x[j] = x[j], x[i] }
|
||||||
|
|
||||||
|
func (x byName) Less(i, j int) bool {
|
||||||
|
if x[i].name != x[j].name {
|
||||||
|
return x[i].name < x[j].name
|
||||||
|
}
|
||||||
|
if len(x[i].index) != len(x[j].index) {
|
||||||
|
return len(x[i].index) < len(x[j].index)
|
||||||
|
}
|
||||||
|
if x[i].tag != x[j].tag {
|
||||||
|
return x[i].tag
|
||||||
|
}
|
||||||
|
return byIndex(x).Less(i, j)
|
||||||
|
}
|
||||||
|
|
||||||
|
// byIndex sorts field by index sequence.
|
||||||
|
type byIndex []field
|
||||||
|
|
||||||
|
func (x byIndex) Len() int { return len(x) }
|
||||||
|
|
||||||
|
func (x byIndex) Swap(i, j int) { x[i], x[j] = x[j], x[i] }
|
||||||
|
|
||||||
|
func (x byIndex) Less(i, j int) bool {
|
||||||
|
for k, xik := range x[i].index {
|
||||||
|
if k >= len(x[j].index) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if xik != x[j].index[k] {
|
||||||
|
return xik < x[j].index[k]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return len(x[i].index) < len(x[j].index)
|
||||||
|
}
|
||||||
|
|
||||||
|
// typeFields returns a list of fields that JSON should recognize for the given type.
|
||||||
|
// The algorithm is breadth-first search over the set of structs to include - the top struct
|
||||||
|
// and then any reachable anonymous structs.
|
||||||
|
func typeFields(t reflect.Type) []field {
|
||||||
|
// Anonymous fields to explore at the current level and the next.
|
||||||
|
current := []field{}
|
||||||
|
next := []field{{typ: t}}
|
||||||
|
|
||||||
|
// Count of queued names for current level and the next.
|
||||||
|
count := map[reflect.Type]int{}
|
||||||
|
nextCount := map[reflect.Type]int{}
|
||||||
|
|
||||||
|
// Types already visited at an earlier level.
|
||||||
|
visited := map[reflect.Type]bool{}
|
||||||
|
|
||||||
|
// Fields found.
|
||||||
|
var fields []field
|
||||||
|
|
||||||
|
for len(next) > 0 {
|
||||||
|
current, next = next, current[:0]
|
||||||
|
count, nextCount = nextCount, map[reflect.Type]int{}
|
||||||
|
|
||||||
|
for _, f := range current {
|
||||||
|
if visited[f.typ] {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
visited[f.typ] = true
|
||||||
|
|
||||||
|
// Scan f.typ for fields to include.
|
||||||
|
for i := 0; i < f.typ.NumField(); i++ {
|
||||||
|
sf := f.typ.Field(i)
|
||||||
|
if sf.PkgPath != "" { // unexported
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
tag := sf.Tag.Get("json")
|
||||||
|
if tag == "-" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
name, opts := parseTag(tag)
|
||||||
|
if !isValidTag(name) {
|
||||||
|
name = ""
|
||||||
|
}
|
||||||
|
index := make([]int, len(f.index)+1)
|
||||||
|
copy(index, f.index)
|
||||||
|
index[len(f.index)] = i
|
||||||
|
|
||||||
|
ft := sf.Type
|
||||||
|
if ft.Name() == "" && ft.Kind() == reflect.Ptr {
|
||||||
|
// Follow pointer.
|
||||||
|
ft = ft.Elem()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Record found field and index sequence.
|
||||||
|
if name != "" || !sf.Anonymous || ft.Kind() != reflect.Struct {
|
||||||
|
tagged := name != ""
|
||||||
|
if name == "" {
|
||||||
|
name = sf.Name
|
||||||
|
}
|
||||||
|
fields = append(fields, fillField(field{
|
||||||
|
name: name,
|
||||||
|
tag: tagged,
|
||||||
|
index: index,
|
||||||
|
typ: ft,
|
||||||
|
omitEmpty: opts.Contains("omitempty"),
|
||||||
|
quoted: opts.Contains("string"),
|
||||||
|
}))
|
||||||
|
if count[f.typ] > 1 {
|
||||||
|
// If there were multiple instances, add a second,
|
||||||
|
// so that the annihilation code will see a duplicate.
|
||||||
|
// It only cares about the distinction between 1 or 2,
|
||||||
|
// so don't bother generating any more copies.
|
||||||
|
fields = append(fields, fields[len(fields)-1])
|
||||||
|
}
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// Record new anonymous struct to explore in next round.
|
||||||
|
nextCount[ft]++
|
||||||
|
if nextCount[ft] == 1 {
|
||||||
|
next = append(next, fillField(field{name: ft.Name(), index: index, typ: ft}))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sort.Sort(byName(fields))
|
||||||
|
|
||||||
|
// Delete all fields that are hidden by the Go rules for embedded fields,
|
||||||
|
// except that fields with JSON tags are promoted.
|
||||||
|
|
||||||
|
// The fields are sorted in primary order of name, secondary order
|
||||||
|
// of field index length. Loop over names; for each name, delete
|
||||||
|
// hidden fields by choosing the one dominant field that survives.
|
||||||
|
out := fields[:0]
|
||||||
|
for advance, i := 0, 0; i < len(fields); i += advance {
|
||||||
|
// One iteration per name.
|
||||||
|
// Find the sequence of fields with the name of this first field.
|
||||||
|
fi := fields[i]
|
||||||
|
name := fi.name
|
||||||
|
for advance = 1; i+advance < len(fields); advance++ {
|
||||||
|
fj := fields[i+advance]
|
||||||
|
if fj.name != name {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if advance == 1 { // Only one field with this name
|
||||||
|
out = append(out, fi)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
dominant, ok := dominantField(fields[i : i+advance])
|
||||||
|
if ok {
|
||||||
|
out = append(out, dominant)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fields = out
|
||||||
|
sort.Sort(byIndex(fields))
|
||||||
|
|
||||||
|
return fields
|
||||||
|
}
|
||||||
|
|
||||||
|
// dominantField looks through the fields, all of which are known to
|
||||||
|
// have the same name, to find the single field that dominates the
|
||||||
|
// others using Go's embedding rules, modified by the presence of
|
||||||
|
// JSON tags. If there are multiple top-level fields, the boolean
|
||||||
|
// will be false: This condition is an error in Go and we skip all
|
||||||
|
// the fields.
|
||||||
|
func dominantField(fields []field) (field, bool) {
|
||||||
|
// The fields are sorted in increasing index-length order. The winner
|
||||||
|
// must therefore be one with the shortest index length. Drop all
|
||||||
|
// longer entries, which is easy: just truncate the slice.
|
||||||
|
length := len(fields[0].index)
|
||||||
|
tagged := -1 // Index of first tagged field.
|
||||||
|
for i, f := range fields {
|
||||||
|
if len(f.index) > length {
|
||||||
|
fields = fields[:i]
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if f.tag {
|
||||||
|
if tagged >= 0 {
|
||||||
|
// Multiple tagged fields at the same level: conflict.
|
||||||
|
// Return no field.
|
||||||
|
return field{}, false
|
||||||
|
}
|
||||||
|
tagged = i
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if tagged >= 0 {
|
||||||
|
return fields[tagged], true
|
||||||
|
}
|
||||||
|
// All remaining fields have the same length. If there's more than one,
|
||||||
|
// we have a conflict (two fields named "X" at the same level) and we
|
||||||
|
// return no field.
|
||||||
|
if len(fields) > 1 {
|
||||||
|
return field{}, false
|
||||||
|
}
|
||||||
|
return fields[0], true
|
||||||
|
}
|
||||||
|
|
||||||
|
var fieldCache struct {
|
||||||
|
sync.RWMutex
|
||||||
|
m map[reflect.Type][]field
|
||||||
|
}
|
||||||
|
|
||||||
|
// cachedTypeFields is like typeFields but uses a cache to avoid repeated work.
|
||||||
|
func cachedTypeFields(t reflect.Type) []field {
|
||||||
|
fieldCache.RLock()
|
||||||
|
f := fieldCache.m[t]
|
||||||
|
fieldCache.RUnlock()
|
||||||
|
if f != nil {
|
||||||
|
return f
|
||||||
|
}
|
||||||
|
|
||||||
|
// Compute fields without lock.
|
||||||
|
// Might duplicate effort but won't hold other computations back.
|
||||||
|
f = typeFields(t)
|
||||||
|
if f == nil {
|
||||||
|
f = []field{}
|
||||||
|
}
|
||||||
|
|
||||||
|
fieldCache.Lock()
|
||||||
|
if fieldCache.m == nil {
|
||||||
|
fieldCache.m = map[reflect.Type][]field{}
|
||||||
|
}
|
||||||
|
fieldCache.m[t] = f
|
||||||
|
fieldCache.Unlock()
|
||||||
|
return f
|
||||||
|
}
|
||||||
|
|
||||||
|
func isValidTag(s string) bool {
|
||||||
|
if s == "" {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
for _, c := range s {
|
||||||
|
switch {
|
||||||
|
case strings.ContainsRune("!#$%&()*+-./:<=>?@[]^_{|}~ ", c):
|
||||||
|
// Backslash and quote chars are reserved, but
|
||||||
|
// otherwise any punctuation chars are allowed
|
||||||
|
// in a tag name.
|
||||||
|
default:
|
||||||
|
if !unicode.IsLetter(c) && !unicode.IsDigit(c) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
const (
|
||||||
|
caseMask = ^byte(0x20) // Mask to ignore case in ASCII.
|
||||||
|
kelvin = '\u212a'
|
||||||
|
smallLongEss = '\u017f'
|
||||||
|
)
|
||||||
|
|
||||||
|
// foldFunc returns one of four different case folding equivalence
|
||||||
|
// functions, from most general (and slow) to fastest:
|
||||||
|
//
|
||||||
|
// 1) bytes.EqualFold, if the key s contains any non-ASCII UTF-8
|
||||||
|
// 2) equalFoldRight, if s contains special folding ASCII ('k', 'K', 's', 'S')
|
||||||
|
// 3) asciiEqualFold, no special, but includes non-letters (including _)
|
||||||
|
// 4) simpleLetterEqualFold, no specials, no non-letters.
|
||||||
|
//
|
||||||
|
// The letters S and K are special because they map to 3 runes, not just 2:
|
||||||
|
// * S maps to s and to U+017F 'ſ' Latin small letter long s
|
||||||
|
// * k maps to K and to U+212A 'K' Kelvin sign
|
||||||
|
// See http://play.golang.org/p/tTxjOc0OGo
|
||||||
|
//
|
||||||
|
// The returned function is specialized for matching against s and
|
||||||
|
// should only be given s. It's not curried for performance reasons.
|
||||||
|
func foldFunc(s []byte) func(s, t []byte) bool {
|
||||||
|
nonLetter := false
|
||||||
|
special := false // special letter
|
||||||
|
for _, b := range s {
|
||||||
|
if b >= utf8.RuneSelf {
|
||||||
|
return bytes.EqualFold
|
||||||
|
}
|
||||||
|
upper := b & caseMask
|
||||||
|
if upper < 'A' || upper > 'Z' {
|
||||||
|
nonLetter = true
|
||||||
|
} else if upper == 'K' || upper == 'S' {
|
||||||
|
// See above for why these letters are special.
|
||||||
|
special = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if special {
|
||||||
|
return equalFoldRight
|
||||||
|
}
|
||||||
|
if nonLetter {
|
||||||
|
return asciiEqualFold
|
||||||
|
}
|
||||||
|
return simpleLetterEqualFold
|
||||||
|
}
|
||||||
|
|
||||||
|
// equalFoldRight is a specialization of bytes.EqualFold when s is
|
||||||
|
// known to be all ASCII (including punctuation), but contains an 's',
|
||||||
|
// 'S', 'k', or 'K', requiring a Unicode fold on the bytes in t.
|
||||||
|
// See comments on foldFunc.
|
||||||
|
func equalFoldRight(s, t []byte) bool {
|
||||||
|
for _, sb := range s {
|
||||||
|
if len(t) == 0 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
tb := t[0]
|
||||||
|
if tb < utf8.RuneSelf {
|
||||||
|
if sb != tb {
|
||||||
|
sbUpper := sb & caseMask
|
||||||
|
if 'A' <= sbUpper && sbUpper <= 'Z' {
|
||||||
|
if sbUpper != tb&caseMask {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
t = t[1:]
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
// sb is ASCII and t is not. t must be either kelvin
|
||||||
|
// sign or long s; sb must be s, S, k, or K.
|
||||||
|
tr, size := utf8.DecodeRune(t)
|
||||||
|
switch sb {
|
||||||
|
case 's', 'S':
|
||||||
|
if tr != smallLongEss {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
case 'k', 'K':
|
||||||
|
if tr != kelvin {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
t = t[size:]
|
||||||
|
|
||||||
|
}
|
||||||
|
if len(t) > 0 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// asciiEqualFold is a specialization of bytes.EqualFold for use when
|
||||||
|
// s is all ASCII (but may contain non-letters) and contains no
|
||||||
|
// special-folding letters.
|
||||||
|
// See comments on foldFunc.
|
||||||
|
func asciiEqualFold(s, t []byte) bool {
|
||||||
|
if len(s) != len(t) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
for i, sb := range s {
|
||||||
|
tb := t[i]
|
||||||
|
if sb == tb {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if ('a' <= sb && sb <= 'z') || ('A' <= sb && sb <= 'Z') {
|
||||||
|
if sb&caseMask != tb&caseMask {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// simpleLetterEqualFold is a specialization of bytes.EqualFold for
|
||||||
|
// use when s is all ASCII letters (no underscores, etc) and also
|
||||||
|
// doesn't contain 'k', 'K', 's', or 'S'.
|
||||||
|
// See comments on foldFunc.
|
||||||
|
func simpleLetterEqualFold(s, t []byte) bool {
|
||||||
|
if len(s) != len(t) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
for i, b := range s {
|
||||||
|
if b&caseMask != t[i]&caseMask {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// tagOptions is the string following a comma in a struct field's "json"
|
||||||
|
// tag, or the empty string. It does not include the leading comma.
|
||||||
|
type tagOptions string
|
||||||
|
|
||||||
|
// parseTag splits a struct field's json tag into its name and
|
||||||
|
// comma-separated options.
|
||||||
|
func parseTag(tag string) (string, tagOptions) {
|
||||||
|
if idx := strings.Index(tag, ","); idx != -1 {
|
||||||
|
return tag[:idx], tagOptions(tag[idx+1:])
|
||||||
|
}
|
||||||
|
return tag, tagOptions("")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Contains reports whether a comma-separated list of options
|
||||||
|
// contains a particular substr flag. substr must be surrounded by a
|
||||||
|
// string boundary or commas.
|
||||||
|
func (o tagOptions) Contains(optionName string) bool {
|
||||||
|
if len(o) == 0 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
s := string(o)
|
||||||
|
for s != "" {
|
||||||
|
var next string
|
||||||
|
i := strings.Index(s, ",")
|
||||||
|
if i >= 0 {
|
||||||
|
s, next = s[:i], s[i+1:]
|
||||||
|
}
|
||||||
|
if s == optionName {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
s = next
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
277
staging/src/k8s.io/client-go/1.4/_vendor/github.com/ghodss/yaml/yaml.go
generated
Normal file
277
staging/src/k8s.io/client-go/1.4/_vendor/github.com/ghodss/yaml/yaml.go
generated
Normal file
@@ -0,0 +1,277 @@
|
|||||||
|
package yaml
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"reflect"
|
||||||
|
"strconv"
|
||||||
|
|
||||||
|
"gopkg.in/yaml.v2"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Marshals the object into JSON then converts JSON to YAML and returns the
|
||||||
|
// YAML.
|
||||||
|
func Marshal(o interface{}) ([]byte, error) {
|
||||||
|
j, err := json.Marshal(o)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("error marshaling into JSON: ", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
y, err := JSONToYAML(j)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("error converting JSON to YAML: ", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return y, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Converts YAML to JSON then uses JSON to unmarshal into an object.
|
||||||
|
func Unmarshal(y []byte, o interface{}) error {
|
||||||
|
vo := reflect.ValueOf(o)
|
||||||
|
j, err := yamlToJSON(y, &vo)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("error converting YAML to JSON: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = json.Unmarshal(j, o)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("error unmarshaling JSON: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert JSON to YAML.
|
||||||
|
func JSONToYAML(j []byte) ([]byte, error) {
|
||||||
|
// Convert the JSON to an object.
|
||||||
|
var jsonObj interface{}
|
||||||
|
// We are using yaml.Unmarshal here (instead of json.Unmarshal) because the
|
||||||
|
// Go JSON library doesn't try to pick the right number type (int, float,
|
||||||
|
// etc.) when unmarshling to interface{}, it just picks float64
|
||||||
|
// universally. go-yaml does go through the effort of picking the right
|
||||||
|
// number type, so we can preserve number type throughout this process.
|
||||||
|
err := yaml.Unmarshal(j, &jsonObj)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Marshal this object into YAML.
|
||||||
|
return yaml.Marshal(jsonObj)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert YAML to JSON. Since JSON is a subset of YAML, passing JSON through
|
||||||
|
// this method should be a no-op.
|
||||||
|
//
|
||||||
|
// Things YAML can do that are not supported by JSON:
|
||||||
|
// * In YAML you can have binary and null keys in your maps. These are invalid
|
||||||
|
// in JSON. (int and float keys are converted to strings.)
|
||||||
|
// * Binary data in YAML with the !!binary tag is not supported. If you want to
|
||||||
|
// use binary data with this library, encode the data as base64 as usual but do
|
||||||
|
// not use the !!binary tag in your YAML. This will ensure the original base64
|
||||||
|
// encoded data makes it all the way through to the JSON.
|
||||||
|
func YAMLToJSON(y []byte) ([]byte, error) {
|
||||||
|
return yamlToJSON(y, nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
func yamlToJSON(y []byte, jsonTarget *reflect.Value) ([]byte, error) {
|
||||||
|
// Convert the YAML to an object.
|
||||||
|
var yamlObj interface{}
|
||||||
|
err := yaml.Unmarshal(y, &yamlObj)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// YAML objects are not completely compatible with JSON objects (e.g. you
|
||||||
|
// can have non-string keys in YAML). So, convert the YAML-compatible object
|
||||||
|
// to a JSON-compatible object, failing with an error if irrecoverable
|
||||||
|
// incompatibilties happen along the way.
|
||||||
|
jsonObj, err := convertToJSONableObject(yamlObj, jsonTarget)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert this object to JSON and return the data.
|
||||||
|
return json.Marshal(jsonObj)
|
||||||
|
}
|
||||||
|
|
||||||
|
func convertToJSONableObject(yamlObj interface{}, jsonTarget *reflect.Value) (interface{}, error) {
|
||||||
|
var err error
|
||||||
|
|
||||||
|
// Resolve jsonTarget to a concrete value (i.e. not a pointer or an
|
||||||
|
// interface). We pass decodingNull as false because we're not actually
|
||||||
|
// decoding into the value, we're just checking if the ultimate target is a
|
||||||
|
// string.
|
||||||
|
if jsonTarget != nil {
|
||||||
|
ju, tu, pv := indirect(*jsonTarget, false)
|
||||||
|
// We have a JSON or Text Umarshaler at this level, so we can't be trying
|
||||||
|
// to decode into a string.
|
||||||
|
if ju != nil || tu != nil {
|
||||||
|
jsonTarget = nil
|
||||||
|
} else {
|
||||||
|
jsonTarget = &pv
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If yamlObj is a number or a boolean, check if jsonTarget is a string -
|
||||||
|
// if so, coerce. Else return normal.
|
||||||
|
// If yamlObj is a map or array, find the field that each key is
|
||||||
|
// unmarshaling to, and when you recurse pass the reflect.Value for that
|
||||||
|
// field back into this function.
|
||||||
|
switch typedYAMLObj := yamlObj.(type) {
|
||||||
|
case map[interface{}]interface{}:
|
||||||
|
// JSON does not support arbitrary keys in a map, so we must convert
|
||||||
|
// these keys to strings.
|
||||||
|
//
|
||||||
|
// From my reading of go-yaml v2 (specifically the resolve function),
|
||||||
|
// keys can only have the types string, int, int64, float64, binary
|
||||||
|
// (unsupported), or null (unsupported).
|
||||||
|
strMap := make(map[string]interface{})
|
||||||
|
for k, v := range typedYAMLObj {
|
||||||
|
// Resolve the key to a string first.
|
||||||
|
var keyString string
|
||||||
|
switch typedKey := k.(type) {
|
||||||
|
case string:
|
||||||
|
keyString = typedKey
|
||||||
|
case int:
|
||||||
|
keyString = strconv.Itoa(typedKey)
|
||||||
|
case int64:
|
||||||
|
// go-yaml will only return an int64 as a key if the system
|
||||||
|
// architecture is 32-bit and the key's value is between 32-bit
|
||||||
|
// and 64-bit. Otherwise the key type will simply be int.
|
||||||
|
keyString = strconv.FormatInt(typedKey, 10)
|
||||||
|
case float64:
|
||||||
|
// Stolen from go-yaml to use the same conversion to string as
|
||||||
|
// the go-yaml library uses to convert float to string when
|
||||||
|
// Marshaling.
|
||||||
|
s := strconv.FormatFloat(typedKey, 'g', -1, 32)
|
||||||
|
switch s {
|
||||||
|
case "+Inf":
|
||||||
|
s = ".inf"
|
||||||
|
case "-Inf":
|
||||||
|
s = "-.inf"
|
||||||
|
case "NaN":
|
||||||
|
s = ".nan"
|
||||||
|
}
|
||||||
|
keyString = s
|
||||||
|
case bool:
|
||||||
|
if typedKey {
|
||||||
|
keyString = "true"
|
||||||
|
} else {
|
||||||
|
keyString = "false"
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return nil, fmt.Errorf("Unsupported map key of type: %s, key: %+#v, value: %+#v",
|
||||||
|
reflect.TypeOf(k), k, v)
|
||||||
|
}
|
||||||
|
|
||||||
|
// jsonTarget should be a struct or a map. If it's a struct, find
|
||||||
|
// the field it's going to map to and pass its reflect.Value. If
|
||||||
|
// it's a map, find the element type of the map and pass the
|
||||||
|
// reflect.Value created from that type. If it's neither, just pass
|
||||||
|
// nil - JSON conversion will error for us if it's a real issue.
|
||||||
|
if jsonTarget != nil {
|
||||||
|
t := *jsonTarget
|
||||||
|
if t.Kind() == reflect.Struct {
|
||||||
|
keyBytes := []byte(keyString)
|
||||||
|
// Find the field that the JSON library would use.
|
||||||
|
var f *field
|
||||||
|
fields := cachedTypeFields(t.Type())
|
||||||
|
for i := range fields {
|
||||||
|
ff := &fields[i]
|
||||||
|
if bytes.Equal(ff.nameBytes, keyBytes) {
|
||||||
|
f = ff
|
||||||
|
break
|
||||||
|
}
|
||||||
|
// Do case-insensitive comparison.
|
||||||
|
if f == nil && ff.equalFold(ff.nameBytes, keyBytes) {
|
||||||
|
f = ff
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if f != nil {
|
||||||
|
// Find the reflect.Value of the most preferential
|
||||||
|
// struct field.
|
||||||
|
jtf := t.Field(f.index[0])
|
||||||
|
strMap[keyString], err = convertToJSONableObject(v, &jtf)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
} else if t.Kind() == reflect.Map {
|
||||||
|
// Create a zero value of the map's element type to use as
|
||||||
|
// the JSON target.
|
||||||
|
jtv := reflect.Zero(t.Type().Elem())
|
||||||
|
strMap[keyString], err = convertToJSONableObject(v, &jtv)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
strMap[keyString], err = convertToJSONableObject(v, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return strMap, nil
|
||||||
|
case []interface{}:
|
||||||
|
// We need to recurse into arrays in case there are any
|
||||||
|
// map[interface{}]interface{}'s inside and to convert any
|
||||||
|
// numbers to strings.
|
||||||
|
|
||||||
|
// If jsonTarget is a slice (which it really should be), find the
|
||||||
|
// thing it's going to map to. If it's not a slice, just pass nil
|
||||||
|
// - JSON conversion will error for us if it's a real issue.
|
||||||
|
var jsonSliceElemValue *reflect.Value
|
||||||
|
if jsonTarget != nil {
|
||||||
|
t := *jsonTarget
|
||||||
|
if t.Kind() == reflect.Slice {
|
||||||
|
// By default slices point to nil, but we need a reflect.Value
|
||||||
|
// pointing to a value of the slice type, so we create one here.
|
||||||
|
ev := reflect.Indirect(reflect.New(t.Type().Elem()))
|
||||||
|
jsonSliceElemValue = &ev
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make and use a new array.
|
||||||
|
arr := make([]interface{}, len(typedYAMLObj))
|
||||||
|
for i, v := range typedYAMLObj {
|
||||||
|
arr[i], err = convertToJSONableObject(v, jsonSliceElemValue)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return arr, nil
|
||||||
|
default:
|
||||||
|
// If the target type is a string and the YAML type is a number,
|
||||||
|
// convert the YAML type to a string.
|
||||||
|
if jsonTarget != nil && (*jsonTarget).Kind() == reflect.String {
|
||||||
|
// Based on my reading of go-yaml, it may return int, int64,
|
||||||
|
// float64, or uint64.
|
||||||
|
var s string
|
||||||
|
switch typedVal := typedYAMLObj.(type) {
|
||||||
|
case int:
|
||||||
|
s = strconv.FormatInt(int64(typedVal), 10)
|
||||||
|
case int64:
|
||||||
|
s = strconv.FormatInt(typedVal, 10)
|
||||||
|
case float64:
|
||||||
|
s = strconv.FormatFloat(typedVal, 'g', -1, 32)
|
||||||
|
case uint64:
|
||||||
|
s = strconv.FormatUint(typedVal, 10)
|
||||||
|
case bool:
|
||||||
|
if typedVal {
|
||||||
|
s = "true"
|
||||||
|
} else {
|
||||||
|
s = "false"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if len(s) > 0 {
|
||||||
|
yamlObj = interface{}(s)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return yamlObj, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
36
staging/src/k8s.io/client-go/1.4/_vendor/github.com/gogo/protobuf/LICENSE
generated
Normal file
36
staging/src/k8s.io/client-go/1.4/_vendor/github.com/gogo/protobuf/LICENSE
generated
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
Extensions for Protocol Buffers to create more go like structures.
|
||||||
|
|
||||||
|
Copyright (c) 2013, Vastech SA (PTY) LTD. All rights reserved.
|
||||||
|
http://github.com/gogo/protobuf/gogoproto
|
||||||
|
|
||||||
|
Go support for Protocol Buffers - Google's data interchange format
|
||||||
|
|
||||||
|
Copyright 2010 The Go Authors. All rights reserved.
|
||||||
|
https://github.com/golang/protobuf
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are
|
||||||
|
met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
* Redistributions in binary form must reproduce the above
|
||||||
|
copyright notice, this list of conditions and the following disclaimer
|
||||||
|
in the documentation and/or other materials provided with the
|
||||||
|
distribution.
|
||||||
|
* Neither the name of Google Inc. nor the names of its
|
||||||
|
contributors may be used to endorse or promote products derived from
|
||||||
|
this software without specific prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
43
staging/src/k8s.io/client-go/1.4/_vendor/github.com/gogo/protobuf/proto/Makefile
generated
Normal file
43
staging/src/k8s.io/client-go/1.4/_vendor/github.com/gogo/protobuf/proto/Makefile
generated
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
# Go support for Protocol Buffers - Google's data interchange format
|
||||||
|
#
|
||||||
|
# Copyright 2010 The Go Authors. All rights reserved.
|
||||||
|
# https://github.com/golang/protobuf
|
||||||
|
#
|
||||||
|
# Redistribution and use in source and binary forms, with or without
|
||||||
|
# modification, are permitted provided that the following conditions are
|
||||||
|
# met:
|
||||||
|
#
|
||||||
|
# * Redistributions of source code must retain the above copyright
|
||||||
|
# notice, this list of conditions and the following disclaimer.
|
||||||
|
# * Redistributions in binary form must reproduce the above
|
||||||
|
# copyright notice, this list of conditions and the following disclaimer
|
||||||
|
# in the documentation and/or other materials provided with the
|
||||||
|
# distribution.
|
||||||
|
# * Neither the name of Google Inc. nor the names of its
|
||||||
|
# contributors may be used to endorse or promote products derived from
|
||||||
|
# this software without specific prior written permission.
|
||||||
|
#
|
||||||
|
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
install:
|
||||||
|
go install
|
||||||
|
|
||||||
|
test: install generate-test-pbs
|
||||||
|
go test
|
||||||
|
|
||||||
|
|
||||||
|
generate-test-pbs:
|
||||||
|
make install
|
||||||
|
make -C testdata
|
||||||
|
protoc-min-version --version="3.0.0" --proto_path=.:../../../../ --gogo_out=. proto3_proto/proto3.proto
|
||||||
|
make
|
||||||
228
staging/src/k8s.io/client-go/1.4/_vendor/github.com/gogo/protobuf/proto/clone.go
generated
Normal file
228
staging/src/k8s.io/client-go/1.4/_vendor/github.com/gogo/protobuf/proto/clone.go
generated
Normal file
@@ -0,0 +1,228 @@
|
|||||||
|
// Go support for Protocol Buffers - Google's data interchange format
|
||||||
|
//
|
||||||
|
// Copyright 2011 The Go Authors. All rights reserved.
|
||||||
|
// https://github.com/golang/protobuf
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions are
|
||||||
|
// met:
|
||||||
|
//
|
||||||
|
// * Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
// * Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following disclaimer
|
||||||
|
// in the documentation and/or other materials provided with the
|
||||||
|
// distribution.
|
||||||
|
// * Neither the name of Google Inc. nor the names of its
|
||||||
|
// contributors may be used to endorse or promote products derived from
|
||||||
|
// this software without specific prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
// Protocol buffer deep copy and merge.
|
||||||
|
// TODO: RawMessage.
|
||||||
|
|
||||||
|
package proto
|
||||||
|
|
||||||
|
import (
|
||||||
|
"log"
|
||||||
|
"reflect"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Clone returns a deep copy of a protocol buffer.
|
||||||
|
func Clone(pb Message) Message {
|
||||||
|
in := reflect.ValueOf(pb)
|
||||||
|
if in.IsNil() {
|
||||||
|
return pb
|
||||||
|
}
|
||||||
|
|
||||||
|
out := reflect.New(in.Type().Elem())
|
||||||
|
// out is empty so a merge is a deep copy.
|
||||||
|
mergeStruct(out.Elem(), in.Elem())
|
||||||
|
return out.Interface().(Message)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Merge merges src into dst.
|
||||||
|
// Required and optional fields that are set in src will be set to that value in dst.
|
||||||
|
// Elements of repeated fields will be appended.
|
||||||
|
// Merge panics if src and dst are not the same type, or if dst is nil.
|
||||||
|
func Merge(dst, src Message) {
|
||||||
|
in := reflect.ValueOf(src)
|
||||||
|
out := reflect.ValueOf(dst)
|
||||||
|
if out.IsNil() {
|
||||||
|
panic("proto: nil destination")
|
||||||
|
}
|
||||||
|
if in.Type() != out.Type() {
|
||||||
|
// Explicit test prior to mergeStruct so that mistyped nils will fail
|
||||||
|
panic("proto: type mismatch")
|
||||||
|
}
|
||||||
|
if in.IsNil() {
|
||||||
|
// Merging nil into non-nil is a quiet no-op
|
||||||
|
return
|
||||||
|
}
|
||||||
|
mergeStruct(out.Elem(), in.Elem())
|
||||||
|
}
|
||||||
|
|
||||||
|
func mergeStruct(out, in reflect.Value) {
|
||||||
|
sprop := GetProperties(in.Type())
|
||||||
|
for i := 0; i < in.NumField(); i++ {
|
||||||
|
f := in.Type().Field(i)
|
||||||
|
if strings.HasPrefix(f.Name, "XXX_") {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
mergeAny(out.Field(i), in.Field(i), false, sprop.Prop[i])
|
||||||
|
}
|
||||||
|
|
||||||
|
if emIn, ok := in.Addr().Interface().(extensionsMap); ok {
|
||||||
|
emOut := out.Addr().Interface().(extensionsMap)
|
||||||
|
mergeExtension(emOut.ExtensionMap(), emIn.ExtensionMap())
|
||||||
|
} else if emIn, ok := in.Addr().Interface().(extensionsBytes); ok {
|
||||||
|
emOut := out.Addr().Interface().(extensionsBytes)
|
||||||
|
bIn := emIn.GetExtensions()
|
||||||
|
bOut := emOut.GetExtensions()
|
||||||
|
*bOut = append(*bOut, *bIn...)
|
||||||
|
}
|
||||||
|
|
||||||
|
uf := in.FieldByName("XXX_unrecognized")
|
||||||
|
if !uf.IsValid() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
uin := uf.Bytes()
|
||||||
|
if len(uin) > 0 {
|
||||||
|
out.FieldByName("XXX_unrecognized").SetBytes(append([]byte(nil), uin...))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// mergeAny performs a merge between two values of the same type.
|
||||||
|
// viaPtr indicates whether the values were indirected through a pointer (implying proto2).
|
||||||
|
// prop is set if this is a struct field (it may be nil).
|
||||||
|
func mergeAny(out, in reflect.Value, viaPtr bool, prop *Properties) {
|
||||||
|
if in.Type() == protoMessageType {
|
||||||
|
if !in.IsNil() {
|
||||||
|
if out.IsNil() {
|
||||||
|
out.Set(reflect.ValueOf(Clone(in.Interface().(Message))))
|
||||||
|
} else {
|
||||||
|
Merge(out.Interface().(Message), in.Interface().(Message))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
switch in.Kind() {
|
||||||
|
case reflect.Bool, reflect.Float32, reflect.Float64, reflect.Int32, reflect.Int64,
|
||||||
|
reflect.String, reflect.Uint32, reflect.Uint64:
|
||||||
|
if !viaPtr && isProto3Zero(in) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
out.Set(in)
|
||||||
|
case reflect.Interface:
|
||||||
|
// Probably a oneof field; copy non-nil values.
|
||||||
|
if in.IsNil() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// Allocate destination if it is not set, or set to a different type.
|
||||||
|
// Otherwise we will merge as normal.
|
||||||
|
if out.IsNil() || out.Elem().Type() != in.Elem().Type() {
|
||||||
|
out.Set(reflect.New(in.Elem().Elem().Type())) // interface -> *T -> T -> new(T)
|
||||||
|
}
|
||||||
|
mergeAny(out.Elem(), in.Elem(), false, nil)
|
||||||
|
case reflect.Map:
|
||||||
|
if in.Len() == 0 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if out.IsNil() {
|
||||||
|
out.Set(reflect.MakeMap(in.Type()))
|
||||||
|
}
|
||||||
|
// For maps with value types of *T or []byte we need to deep copy each value.
|
||||||
|
elemKind := in.Type().Elem().Kind()
|
||||||
|
for _, key := range in.MapKeys() {
|
||||||
|
var val reflect.Value
|
||||||
|
switch elemKind {
|
||||||
|
case reflect.Ptr:
|
||||||
|
val = reflect.New(in.Type().Elem().Elem())
|
||||||
|
mergeAny(val, in.MapIndex(key), false, nil)
|
||||||
|
case reflect.Slice:
|
||||||
|
val = in.MapIndex(key)
|
||||||
|
val = reflect.ValueOf(append([]byte{}, val.Bytes()...))
|
||||||
|
default:
|
||||||
|
val = in.MapIndex(key)
|
||||||
|
}
|
||||||
|
out.SetMapIndex(key, val)
|
||||||
|
}
|
||||||
|
case reflect.Ptr:
|
||||||
|
if in.IsNil() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if out.IsNil() {
|
||||||
|
out.Set(reflect.New(in.Elem().Type()))
|
||||||
|
}
|
||||||
|
mergeAny(out.Elem(), in.Elem(), true, nil)
|
||||||
|
case reflect.Slice:
|
||||||
|
if in.IsNil() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if in.Type().Elem().Kind() == reflect.Uint8 {
|
||||||
|
// []byte is a scalar bytes field, not a repeated field.
|
||||||
|
|
||||||
|
// Edge case: if this is in a proto3 message, a zero length
|
||||||
|
// bytes field is considered the zero value, and should not
|
||||||
|
// be merged.
|
||||||
|
if prop != nil && prop.proto3 && in.Len() == 0 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make a deep copy.
|
||||||
|
// Append to []byte{} instead of []byte(nil) so that we never end up
|
||||||
|
// with a nil result.
|
||||||
|
out.SetBytes(append([]byte{}, in.Bytes()...))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
n := in.Len()
|
||||||
|
if out.IsNil() {
|
||||||
|
out.Set(reflect.MakeSlice(in.Type(), 0, n))
|
||||||
|
}
|
||||||
|
switch in.Type().Elem().Kind() {
|
||||||
|
case reflect.Bool, reflect.Float32, reflect.Float64, reflect.Int32, reflect.Int64,
|
||||||
|
reflect.String, reflect.Uint32, reflect.Uint64:
|
||||||
|
out.Set(reflect.AppendSlice(out, in))
|
||||||
|
default:
|
||||||
|
for i := 0; i < n; i++ {
|
||||||
|
x := reflect.Indirect(reflect.New(in.Type().Elem()))
|
||||||
|
mergeAny(x, in.Index(i), false, nil)
|
||||||
|
out.Set(reflect.Append(out, x))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case reflect.Struct:
|
||||||
|
mergeStruct(out, in)
|
||||||
|
default:
|
||||||
|
// unknown type, so not a protocol buffer
|
||||||
|
log.Printf("proto: don't know how to copy %v", in)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func mergeExtension(out, in map[int32]Extension) {
|
||||||
|
for extNum, eIn := range in {
|
||||||
|
eOut := Extension{desc: eIn.desc}
|
||||||
|
if eIn.value != nil {
|
||||||
|
v := reflect.New(reflect.TypeOf(eIn.value)).Elem()
|
||||||
|
mergeAny(v, reflect.ValueOf(eIn.value), false, nil)
|
||||||
|
eOut.value = v.Interface()
|
||||||
|
}
|
||||||
|
if eIn.enc != nil {
|
||||||
|
eOut.enc = make([]byte, len(eIn.enc))
|
||||||
|
copy(eOut.enc, eIn.enc)
|
||||||
|
}
|
||||||
|
|
||||||
|
out[extNum] = eOut
|
||||||
|
}
|
||||||
|
}
|
||||||
873
staging/src/k8s.io/client-go/1.4/_vendor/github.com/gogo/protobuf/proto/decode.go
generated
Normal file
873
staging/src/k8s.io/client-go/1.4/_vendor/github.com/gogo/protobuf/proto/decode.go
generated
Normal file
@@ -0,0 +1,873 @@
|
|||||||
|
// Go support for Protocol Buffers - Google's data interchange format
|
||||||
|
//
|
||||||
|
// Copyright 2010 The Go Authors. All rights reserved.
|
||||||
|
// https://github.com/golang/protobuf
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions are
|
||||||
|
// met:
|
||||||
|
//
|
||||||
|
// * Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
// * Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following disclaimer
|
||||||
|
// in the documentation and/or other materials provided with the
|
||||||
|
// distribution.
|
||||||
|
// * Neither the name of Google Inc. nor the names of its
|
||||||
|
// contributors may be used to endorse or promote products derived from
|
||||||
|
// this software without specific prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
package proto
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Routines for decoding protocol buffer data to construct in-memory representations.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"os"
|
||||||
|
"reflect"
|
||||||
|
)
|
||||||
|
|
||||||
|
// errOverflow is returned when an integer is too large to be represented.
|
||||||
|
var errOverflow = errors.New("proto: integer overflow")
|
||||||
|
|
||||||
|
// ErrInternalBadWireType is returned by generated code when an incorrect
|
||||||
|
// wire type is encountered. It does not get returned to user code.
|
||||||
|
var ErrInternalBadWireType = errors.New("proto: internal error: bad wiretype for oneof")
|
||||||
|
|
||||||
|
// The fundamental decoders that interpret bytes on the wire.
|
||||||
|
// Those that take integer types all return uint64 and are
|
||||||
|
// therefore of type valueDecoder.
|
||||||
|
|
||||||
|
// DecodeVarint reads a varint-encoded integer from the slice.
|
||||||
|
// It returns the integer and the number of bytes consumed, or
|
||||||
|
// zero if there is not enough.
|
||||||
|
// This is the format for the
|
||||||
|
// int32, int64, uint32, uint64, bool, and enum
|
||||||
|
// protocol buffer types.
|
||||||
|
func DecodeVarint(buf []byte) (x uint64, n int) {
|
||||||
|
// x, n already 0
|
||||||
|
for shift := uint(0); shift < 64; shift += 7 {
|
||||||
|
if n >= len(buf) {
|
||||||
|
return 0, 0
|
||||||
|
}
|
||||||
|
b := uint64(buf[n])
|
||||||
|
n++
|
||||||
|
x |= (b & 0x7F) << shift
|
||||||
|
if (b & 0x80) == 0 {
|
||||||
|
return x, n
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// The number is too large to represent in a 64-bit value.
|
||||||
|
return 0, 0
|
||||||
|
}
|
||||||
|
|
||||||
|
// DecodeVarint reads a varint-encoded integer from the Buffer.
|
||||||
|
// This is the format for the
|
||||||
|
// int32, int64, uint32, uint64, bool, and enum
|
||||||
|
// protocol buffer types.
|
||||||
|
func (p *Buffer) DecodeVarint() (x uint64, err error) {
|
||||||
|
// x, err already 0
|
||||||
|
|
||||||
|
i := p.index
|
||||||
|
l := len(p.buf)
|
||||||
|
|
||||||
|
for shift := uint(0); shift < 64; shift += 7 {
|
||||||
|
if i >= l {
|
||||||
|
err = io.ErrUnexpectedEOF
|
||||||
|
return
|
||||||
|
}
|
||||||
|
b := p.buf[i]
|
||||||
|
i++
|
||||||
|
x |= (uint64(b) & 0x7F) << shift
|
||||||
|
if b < 0x80 {
|
||||||
|
p.index = i
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// The number is too large to represent in a 64-bit value.
|
||||||
|
err = errOverflow
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// DecodeFixed64 reads a 64-bit integer from the Buffer.
|
||||||
|
// This is the format for the
|
||||||
|
// fixed64, sfixed64, and double protocol buffer types.
|
||||||
|
func (p *Buffer) DecodeFixed64() (x uint64, err error) {
|
||||||
|
// x, err already 0
|
||||||
|
i := p.index + 8
|
||||||
|
if i < 0 || i > len(p.buf) {
|
||||||
|
err = io.ErrUnexpectedEOF
|
||||||
|
return
|
||||||
|
}
|
||||||
|
p.index = i
|
||||||
|
|
||||||
|
x = uint64(p.buf[i-8])
|
||||||
|
x |= uint64(p.buf[i-7]) << 8
|
||||||
|
x |= uint64(p.buf[i-6]) << 16
|
||||||
|
x |= uint64(p.buf[i-5]) << 24
|
||||||
|
x |= uint64(p.buf[i-4]) << 32
|
||||||
|
x |= uint64(p.buf[i-3]) << 40
|
||||||
|
x |= uint64(p.buf[i-2]) << 48
|
||||||
|
x |= uint64(p.buf[i-1]) << 56
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// DecodeFixed32 reads a 32-bit integer from the Buffer.
|
||||||
|
// This is the format for the
|
||||||
|
// fixed32, sfixed32, and float protocol buffer types.
|
||||||
|
func (p *Buffer) DecodeFixed32() (x uint64, err error) {
|
||||||
|
// x, err already 0
|
||||||
|
i := p.index + 4
|
||||||
|
if i < 0 || i > len(p.buf) {
|
||||||
|
err = io.ErrUnexpectedEOF
|
||||||
|
return
|
||||||
|
}
|
||||||
|
p.index = i
|
||||||
|
|
||||||
|
x = uint64(p.buf[i-4])
|
||||||
|
x |= uint64(p.buf[i-3]) << 8
|
||||||
|
x |= uint64(p.buf[i-2]) << 16
|
||||||
|
x |= uint64(p.buf[i-1]) << 24
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// DecodeZigzag64 reads a zigzag-encoded 64-bit integer
|
||||||
|
// from the Buffer.
|
||||||
|
// This is the format used for the sint64 protocol buffer type.
|
||||||
|
func (p *Buffer) DecodeZigzag64() (x uint64, err error) {
|
||||||
|
x, err = p.DecodeVarint()
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
x = (x >> 1) ^ uint64((int64(x&1)<<63)>>63)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// DecodeZigzag32 reads a zigzag-encoded 32-bit integer
|
||||||
|
// from the Buffer.
|
||||||
|
// This is the format used for the sint32 protocol buffer type.
|
||||||
|
func (p *Buffer) DecodeZigzag32() (x uint64, err error) {
|
||||||
|
x, err = p.DecodeVarint()
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
x = uint64((uint32(x) >> 1) ^ uint32((int32(x&1)<<31)>>31))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// These are not ValueDecoders: they produce an array of bytes or a string.
|
||||||
|
// bytes, embedded messages
|
||||||
|
|
||||||
|
// DecodeRawBytes reads a count-delimited byte buffer from the Buffer.
|
||||||
|
// This is the format used for the bytes protocol buffer
|
||||||
|
// type and for embedded messages.
|
||||||
|
func (p *Buffer) DecodeRawBytes(alloc bool) (buf []byte, err error) {
|
||||||
|
n, err := p.DecodeVarint()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
nb := int(n)
|
||||||
|
if nb < 0 {
|
||||||
|
return nil, fmt.Errorf("proto: bad byte length %d", nb)
|
||||||
|
}
|
||||||
|
end := p.index + nb
|
||||||
|
if end < p.index || end > len(p.buf) {
|
||||||
|
return nil, io.ErrUnexpectedEOF
|
||||||
|
}
|
||||||
|
|
||||||
|
if !alloc {
|
||||||
|
// todo: check if can get more uses of alloc=false
|
||||||
|
buf = p.buf[p.index:end]
|
||||||
|
p.index += nb
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
buf = make([]byte, nb)
|
||||||
|
copy(buf, p.buf[p.index:])
|
||||||
|
p.index += nb
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// DecodeStringBytes reads an encoded string from the Buffer.
|
||||||
|
// This is the format used for the proto2 string type.
|
||||||
|
func (p *Buffer) DecodeStringBytes() (s string, err error) {
|
||||||
|
buf, err := p.DecodeRawBytes(false)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
return string(buf), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Skip the next item in the buffer. Its wire type is decoded and presented as an argument.
|
||||||
|
// If the protocol buffer has extensions, and the field matches, add it as an extension.
|
||||||
|
// Otherwise, if the XXX_unrecognized field exists, append the skipped data there.
|
||||||
|
func (o *Buffer) skipAndSave(t reflect.Type, tag, wire int, base structPointer, unrecField field) error {
|
||||||
|
oi := o.index
|
||||||
|
|
||||||
|
err := o.skip(t, tag, wire)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if !unrecField.IsValid() {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
ptr := structPointer_Bytes(base, unrecField)
|
||||||
|
|
||||||
|
// Add the skipped field to struct field
|
||||||
|
obuf := o.buf
|
||||||
|
|
||||||
|
o.buf = *ptr
|
||||||
|
o.EncodeVarint(uint64(tag<<3 | wire))
|
||||||
|
*ptr = append(o.buf, obuf[oi:o.index]...)
|
||||||
|
|
||||||
|
o.buf = obuf
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Skip the next item in the buffer. Its wire type is decoded and presented as an argument.
|
||||||
|
func (o *Buffer) skip(t reflect.Type, tag, wire int) error {
|
||||||
|
|
||||||
|
var u uint64
|
||||||
|
var err error
|
||||||
|
|
||||||
|
switch wire {
|
||||||
|
case WireVarint:
|
||||||
|
_, err = o.DecodeVarint()
|
||||||
|
case WireFixed64:
|
||||||
|
_, err = o.DecodeFixed64()
|
||||||
|
case WireBytes:
|
||||||
|
_, err = o.DecodeRawBytes(false)
|
||||||
|
case WireFixed32:
|
||||||
|
_, err = o.DecodeFixed32()
|
||||||
|
case WireStartGroup:
|
||||||
|
for {
|
||||||
|
u, err = o.DecodeVarint()
|
||||||
|
if err != nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
fwire := int(u & 0x7)
|
||||||
|
if fwire == WireEndGroup {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
ftag := int(u >> 3)
|
||||||
|
err = o.skip(t, ftag, fwire)
|
||||||
|
if err != nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
err = fmt.Errorf("proto: can't skip unknown wire type %d for %s", wire, t)
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unmarshaler is the interface representing objects that can
|
||||||
|
// unmarshal themselves. The method should reset the receiver before
|
||||||
|
// decoding starts. The argument points to data that may be
|
||||||
|
// overwritten, so implementations should not keep references to the
|
||||||
|
// buffer.
|
||||||
|
type Unmarshaler interface {
|
||||||
|
Unmarshal([]byte) error
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unmarshal parses the protocol buffer representation in buf and places the
|
||||||
|
// decoded result in pb. If the struct underlying pb does not match
|
||||||
|
// the data in buf, the results can be unpredictable.
|
||||||
|
//
|
||||||
|
// Unmarshal resets pb before starting to unmarshal, so any
|
||||||
|
// existing data in pb is always removed. Use UnmarshalMerge
|
||||||
|
// to preserve and append to existing data.
|
||||||
|
func Unmarshal(buf []byte, pb Message) error {
|
||||||
|
pb.Reset()
|
||||||
|
return UnmarshalMerge(buf, pb)
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalMerge parses the protocol buffer representation in buf and
|
||||||
|
// writes the decoded result to pb. If the struct underlying pb does not match
|
||||||
|
// the data in buf, the results can be unpredictable.
|
||||||
|
//
|
||||||
|
// UnmarshalMerge merges into existing data in pb.
|
||||||
|
// Most code should use Unmarshal instead.
|
||||||
|
func UnmarshalMerge(buf []byte, pb Message) error {
|
||||||
|
// If the object can unmarshal itself, let it.
|
||||||
|
if u, ok := pb.(Unmarshaler); ok {
|
||||||
|
return u.Unmarshal(buf)
|
||||||
|
}
|
||||||
|
return NewBuffer(buf).Unmarshal(pb)
|
||||||
|
}
|
||||||
|
|
||||||
|
// DecodeMessage reads a count-delimited message from the Buffer.
|
||||||
|
func (p *Buffer) DecodeMessage(pb Message) error {
|
||||||
|
enc, err := p.DecodeRawBytes(false)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return NewBuffer(enc).Unmarshal(pb)
|
||||||
|
}
|
||||||
|
|
||||||
|
// DecodeGroup reads a tag-delimited group from the Buffer.
|
||||||
|
func (p *Buffer) DecodeGroup(pb Message) error {
|
||||||
|
typ, base, err := getbase(pb)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return p.unmarshalType(typ.Elem(), GetProperties(typ.Elem()), true, base)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unmarshal parses the protocol buffer representation in the
|
||||||
|
// Buffer and places the decoded result in pb. If the struct
|
||||||
|
// underlying pb does not match the data in the buffer, the results can be
|
||||||
|
// unpredictable.
|
||||||
|
func (p *Buffer) Unmarshal(pb Message) error {
|
||||||
|
// If the object can unmarshal itself, let it.
|
||||||
|
if u, ok := pb.(Unmarshaler); ok {
|
||||||
|
err := u.Unmarshal(p.buf[p.index:])
|
||||||
|
p.index = len(p.buf)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
typ, base, err := getbase(pb)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = p.unmarshalType(typ.Elem(), GetProperties(typ.Elem()), false, base)
|
||||||
|
|
||||||
|
if collectStats {
|
||||||
|
stats.Decode++
|
||||||
|
}
|
||||||
|
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// unmarshalType does the work of unmarshaling a structure.
|
||||||
|
func (o *Buffer) unmarshalType(st reflect.Type, prop *StructProperties, is_group bool, base structPointer) error {
|
||||||
|
var state errorState
|
||||||
|
required, reqFields := prop.reqCount, uint64(0)
|
||||||
|
|
||||||
|
var err error
|
||||||
|
for err == nil && o.index < len(o.buf) {
|
||||||
|
oi := o.index
|
||||||
|
var u uint64
|
||||||
|
u, err = o.DecodeVarint()
|
||||||
|
if err != nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
wire := int(u & 0x7)
|
||||||
|
if wire == WireEndGroup {
|
||||||
|
if is_group {
|
||||||
|
return nil // input is satisfied
|
||||||
|
}
|
||||||
|
return fmt.Errorf("proto: %s: wiretype end group for non-group", st)
|
||||||
|
}
|
||||||
|
tag := int(u >> 3)
|
||||||
|
if tag <= 0 {
|
||||||
|
return fmt.Errorf("proto: %s: illegal tag %d (wire type %d)", st, tag, wire)
|
||||||
|
}
|
||||||
|
fieldnum, ok := prop.decoderTags.get(tag)
|
||||||
|
if !ok {
|
||||||
|
// Maybe it's an extension?
|
||||||
|
if prop.extendable {
|
||||||
|
if e := structPointer_Interface(base, st).(extendableProto); isExtensionField(e, int32(tag)) {
|
||||||
|
if err = o.skip(st, tag, wire); err == nil {
|
||||||
|
if ee, eok := e.(extensionsMap); eok {
|
||||||
|
ext := ee.ExtensionMap()[int32(tag)] // may be missing
|
||||||
|
ext.enc = append(ext.enc, o.buf[oi:o.index]...)
|
||||||
|
ee.ExtensionMap()[int32(tag)] = ext
|
||||||
|
} else if ee, eok := e.(extensionsBytes); eok {
|
||||||
|
ext := ee.GetExtensions()
|
||||||
|
*ext = append(*ext, o.buf[oi:o.index]...)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Maybe it's a oneof?
|
||||||
|
if prop.oneofUnmarshaler != nil {
|
||||||
|
m := structPointer_Interface(base, st).(Message)
|
||||||
|
// First return value indicates whether tag is a oneof field.
|
||||||
|
ok, err = prop.oneofUnmarshaler(m, tag, wire, o)
|
||||||
|
if err == ErrInternalBadWireType {
|
||||||
|
// Map the error to something more descriptive.
|
||||||
|
// Do the formatting here to save generated code space.
|
||||||
|
err = fmt.Errorf("bad wiretype for oneof field in %T", m)
|
||||||
|
}
|
||||||
|
if ok {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
err = o.skipAndSave(st, tag, wire, base, prop.unrecField)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
p := prop.Prop[fieldnum]
|
||||||
|
|
||||||
|
if p.dec == nil {
|
||||||
|
fmt.Fprintf(os.Stderr, "proto: no protobuf decoder for %s.%s\n", st, st.Field(fieldnum).Name)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
dec := p.dec
|
||||||
|
if wire != WireStartGroup && wire != p.WireType {
|
||||||
|
if wire == WireBytes && p.packedDec != nil {
|
||||||
|
// a packable field
|
||||||
|
dec = p.packedDec
|
||||||
|
} else {
|
||||||
|
err = fmt.Errorf("proto: bad wiretype for field %s.%s: got wiretype %d, want %d", st, st.Field(fieldnum).Name, wire, p.WireType)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
decErr := dec(o, p, base)
|
||||||
|
if decErr != nil && !state.shouldContinue(decErr, p) {
|
||||||
|
err = decErr
|
||||||
|
}
|
||||||
|
if err == nil && p.Required {
|
||||||
|
// Successfully decoded a required field.
|
||||||
|
if tag <= 64 {
|
||||||
|
// use bitmap for fields 1-64 to catch field reuse.
|
||||||
|
var mask uint64 = 1 << uint64(tag-1)
|
||||||
|
if reqFields&mask == 0 {
|
||||||
|
// new required field
|
||||||
|
reqFields |= mask
|
||||||
|
required--
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// This is imprecise. It can be fooled by a required field
|
||||||
|
// with a tag > 64 that is encoded twice; that's very rare.
|
||||||
|
// A fully correct implementation would require allocating
|
||||||
|
// a data structure, which we would like to avoid.
|
||||||
|
required--
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if err == nil {
|
||||||
|
if is_group {
|
||||||
|
return io.ErrUnexpectedEOF
|
||||||
|
}
|
||||||
|
if state.err != nil {
|
||||||
|
return state.err
|
||||||
|
}
|
||||||
|
if required > 0 {
|
||||||
|
// Not enough information to determine the exact field. If we use extra
|
||||||
|
// CPU, we could determine the field only if the missing required field
|
||||||
|
// has a tag <= 64 and we check reqFields.
|
||||||
|
return &RequiredNotSetError{"{Unknown}"}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Individual type decoders
|
||||||
|
// For each,
|
||||||
|
// u is the decoded value,
|
||||||
|
// v is a pointer to the field (pointer) in the struct
|
||||||
|
|
||||||
|
// Sizes of the pools to allocate inside the Buffer.
|
||||||
|
// The goal is modest amortization and allocation
|
||||||
|
// on at least 16-byte boundaries.
|
||||||
|
const (
|
||||||
|
boolPoolSize = 16
|
||||||
|
uint32PoolSize = 8
|
||||||
|
uint64PoolSize = 4
|
||||||
|
)
|
||||||
|
|
||||||
|
// Decode a bool.
|
||||||
|
func (o *Buffer) dec_bool(p *Properties, base structPointer) error {
|
||||||
|
u, err := p.valDec(o)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if len(o.bools) == 0 {
|
||||||
|
o.bools = make([]bool, boolPoolSize)
|
||||||
|
}
|
||||||
|
o.bools[0] = u != 0
|
||||||
|
*structPointer_Bool(base, p.field) = &o.bools[0]
|
||||||
|
o.bools = o.bools[1:]
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *Buffer) dec_proto3_bool(p *Properties, base structPointer) error {
|
||||||
|
u, err := p.valDec(o)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
*structPointer_BoolVal(base, p.field) = u != 0
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Decode an int32.
|
||||||
|
func (o *Buffer) dec_int32(p *Properties, base structPointer) error {
|
||||||
|
u, err := p.valDec(o)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
word32_Set(structPointer_Word32(base, p.field), o, uint32(u))
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *Buffer) dec_proto3_int32(p *Properties, base structPointer) error {
|
||||||
|
u, err := p.valDec(o)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
word32Val_Set(structPointer_Word32Val(base, p.field), uint32(u))
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Decode an int64.
|
||||||
|
func (o *Buffer) dec_int64(p *Properties, base structPointer) error {
|
||||||
|
u, err := p.valDec(o)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
word64_Set(structPointer_Word64(base, p.field), o, u)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *Buffer) dec_proto3_int64(p *Properties, base structPointer) error {
|
||||||
|
u, err := p.valDec(o)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
word64Val_Set(structPointer_Word64Val(base, p.field), o, u)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Decode a string.
|
||||||
|
func (o *Buffer) dec_string(p *Properties, base structPointer) error {
|
||||||
|
s, err := o.DecodeStringBytes()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
*structPointer_String(base, p.field) = &s
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *Buffer) dec_proto3_string(p *Properties, base structPointer) error {
|
||||||
|
s, err := o.DecodeStringBytes()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
*structPointer_StringVal(base, p.field) = s
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Decode a slice of bytes ([]byte).
|
||||||
|
func (o *Buffer) dec_slice_byte(p *Properties, base structPointer) error {
|
||||||
|
b, err := o.DecodeRawBytes(true)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
*structPointer_Bytes(base, p.field) = b
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Decode a slice of bools ([]bool).
|
||||||
|
func (o *Buffer) dec_slice_bool(p *Properties, base structPointer) error {
|
||||||
|
u, err := p.valDec(o)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
v := structPointer_BoolSlice(base, p.field)
|
||||||
|
*v = append(*v, u != 0)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Decode a slice of bools ([]bool) in packed format.
|
||||||
|
func (o *Buffer) dec_slice_packed_bool(p *Properties, base structPointer) error {
|
||||||
|
v := structPointer_BoolSlice(base, p.field)
|
||||||
|
|
||||||
|
nn, err := o.DecodeVarint()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
nb := int(nn) // number of bytes of encoded bools
|
||||||
|
fin := o.index + nb
|
||||||
|
if fin < o.index {
|
||||||
|
return errOverflow
|
||||||
|
}
|
||||||
|
|
||||||
|
y := *v
|
||||||
|
for o.index < fin {
|
||||||
|
u, err := p.valDec(o)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
y = append(y, u != 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
*v = y
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Decode a slice of int32s ([]int32).
|
||||||
|
func (o *Buffer) dec_slice_int32(p *Properties, base structPointer) error {
|
||||||
|
u, err := p.valDec(o)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
structPointer_Word32Slice(base, p.field).Append(uint32(u))
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Decode a slice of int32s ([]int32) in packed format.
|
||||||
|
func (o *Buffer) dec_slice_packed_int32(p *Properties, base structPointer) error {
|
||||||
|
v := structPointer_Word32Slice(base, p.field)
|
||||||
|
|
||||||
|
nn, err := o.DecodeVarint()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
nb := int(nn) // number of bytes of encoded int32s
|
||||||
|
|
||||||
|
fin := o.index + nb
|
||||||
|
if fin < o.index {
|
||||||
|
return errOverflow
|
||||||
|
}
|
||||||
|
for o.index < fin {
|
||||||
|
u, err := p.valDec(o)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
v.Append(uint32(u))
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Decode a slice of int64s ([]int64).
|
||||||
|
func (o *Buffer) dec_slice_int64(p *Properties, base structPointer) error {
|
||||||
|
u, err := p.valDec(o)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
structPointer_Word64Slice(base, p.field).Append(u)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Decode a slice of int64s ([]int64) in packed format.
|
||||||
|
func (o *Buffer) dec_slice_packed_int64(p *Properties, base structPointer) error {
|
||||||
|
v := structPointer_Word64Slice(base, p.field)
|
||||||
|
|
||||||
|
nn, err := o.DecodeVarint()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
nb := int(nn) // number of bytes of encoded int64s
|
||||||
|
|
||||||
|
fin := o.index + nb
|
||||||
|
if fin < o.index {
|
||||||
|
return errOverflow
|
||||||
|
}
|
||||||
|
for o.index < fin {
|
||||||
|
u, err := p.valDec(o)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
v.Append(u)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Decode a slice of strings ([]string).
|
||||||
|
func (o *Buffer) dec_slice_string(p *Properties, base structPointer) error {
|
||||||
|
s, err := o.DecodeStringBytes()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
v := structPointer_StringSlice(base, p.field)
|
||||||
|
*v = append(*v, s)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Decode a slice of slice of bytes ([][]byte).
|
||||||
|
func (o *Buffer) dec_slice_slice_byte(p *Properties, base structPointer) error {
|
||||||
|
b, err := o.DecodeRawBytes(true)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
v := structPointer_BytesSlice(base, p.field)
|
||||||
|
*v = append(*v, b)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Decode a map field.
|
||||||
|
func (o *Buffer) dec_new_map(p *Properties, base structPointer) error {
|
||||||
|
raw, err := o.DecodeRawBytes(false)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
oi := o.index // index at the end of this map entry
|
||||||
|
o.index -= len(raw) // move buffer back to start of map entry
|
||||||
|
|
||||||
|
mptr := structPointer_NewAt(base, p.field, p.mtype) // *map[K]V
|
||||||
|
if mptr.Elem().IsNil() {
|
||||||
|
mptr.Elem().Set(reflect.MakeMap(mptr.Type().Elem()))
|
||||||
|
}
|
||||||
|
v := mptr.Elem() // map[K]V
|
||||||
|
|
||||||
|
// Prepare addressable doubly-indirect placeholders for the key and value types.
|
||||||
|
// See enc_new_map for why.
|
||||||
|
keyptr := reflect.New(reflect.PtrTo(p.mtype.Key())).Elem() // addressable *K
|
||||||
|
keybase := toStructPointer(keyptr.Addr()) // **K
|
||||||
|
|
||||||
|
var valbase structPointer
|
||||||
|
var valptr reflect.Value
|
||||||
|
switch p.mtype.Elem().Kind() {
|
||||||
|
case reflect.Slice:
|
||||||
|
// []byte
|
||||||
|
var dummy []byte
|
||||||
|
valptr = reflect.ValueOf(&dummy) // *[]byte
|
||||||
|
valbase = toStructPointer(valptr) // *[]byte
|
||||||
|
case reflect.Ptr:
|
||||||
|
// message; valptr is **Msg; need to allocate the intermediate pointer
|
||||||
|
valptr = reflect.New(reflect.PtrTo(p.mtype.Elem())).Elem() // addressable *V
|
||||||
|
valptr.Set(reflect.New(valptr.Type().Elem()))
|
||||||
|
valbase = toStructPointer(valptr)
|
||||||
|
default:
|
||||||
|
// everything else
|
||||||
|
valptr = reflect.New(reflect.PtrTo(p.mtype.Elem())).Elem() // addressable *V
|
||||||
|
valbase = toStructPointer(valptr.Addr()) // **V
|
||||||
|
}
|
||||||
|
|
||||||
|
// Decode.
|
||||||
|
// This parses a restricted wire format, namely the encoding of a message
|
||||||
|
// with two fields. See enc_new_map for the format.
|
||||||
|
for o.index < oi {
|
||||||
|
// tagcode for key and value properties are always a single byte
|
||||||
|
// because they have tags 1 and 2.
|
||||||
|
tagcode := o.buf[o.index]
|
||||||
|
o.index++
|
||||||
|
switch tagcode {
|
||||||
|
case p.mkeyprop.tagcode[0]:
|
||||||
|
if err := p.mkeyprop.dec(o, p.mkeyprop, keybase); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
case p.mvalprop.tagcode[0]:
|
||||||
|
if err := p.mvalprop.dec(o, p.mvalprop, valbase); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
// TODO: Should we silently skip this instead?
|
||||||
|
return fmt.Errorf("proto: bad map data tag %d", raw[0])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
keyelem, valelem := keyptr.Elem(), valptr.Elem()
|
||||||
|
if !keyelem.IsValid() {
|
||||||
|
keyelem = reflect.Zero(p.mtype.Key())
|
||||||
|
}
|
||||||
|
if !valelem.IsValid() {
|
||||||
|
valelem = reflect.Zero(p.mtype.Elem())
|
||||||
|
}
|
||||||
|
|
||||||
|
v.SetMapIndex(keyelem, valelem)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Decode a group.
|
||||||
|
func (o *Buffer) dec_struct_group(p *Properties, base structPointer) error {
|
||||||
|
bas := structPointer_GetStructPointer(base, p.field)
|
||||||
|
if structPointer_IsNil(bas) {
|
||||||
|
// allocate new nested message
|
||||||
|
bas = toStructPointer(reflect.New(p.stype))
|
||||||
|
structPointer_SetStructPointer(base, p.field, bas)
|
||||||
|
}
|
||||||
|
return o.unmarshalType(p.stype, p.sprop, true, bas)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Decode an embedded message.
|
||||||
|
func (o *Buffer) dec_struct_message(p *Properties, base structPointer) (err error) {
|
||||||
|
raw, e := o.DecodeRawBytes(false)
|
||||||
|
if e != nil {
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
|
||||||
|
bas := structPointer_GetStructPointer(base, p.field)
|
||||||
|
if structPointer_IsNil(bas) {
|
||||||
|
// allocate new nested message
|
||||||
|
bas = toStructPointer(reflect.New(p.stype))
|
||||||
|
structPointer_SetStructPointer(base, p.field, bas)
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the object can unmarshal itself, let it.
|
||||||
|
if p.isUnmarshaler {
|
||||||
|
iv := structPointer_Interface(bas, p.stype)
|
||||||
|
return iv.(Unmarshaler).Unmarshal(raw)
|
||||||
|
}
|
||||||
|
|
||||||
|
obuf := o.buf
|
||||||
|
oi := o.index
|
||||||
|
o.buf = raw
|
||||||
|
o.index = 0
|
||||||
|
|
||||||
|
err = o.unmarshalType(p.stype, p.sprop, false, bas)
|
||||||
|
o.buf = obuf
|
||||||
|
o.index = oi
|
||||||
|
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Decode a slice of embedded messages.
|
||||||
|
func (o *Buffer) dec_slice_struct_message(p *Properties, base structPointer) error {
|
||||||
|
return o.dec_slice_struct(p, false, base)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Decode a slice of embedded groups.
|
||||||
|
func (o *Buffer) dec_slice_struct_group(p *Properties, base structPointer) error {
|
||||||
|
return o.dec_slice_struct(p, true, base)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Decode a slice of structs ([]*struct).
|
||||||
|
func (o *Buffer) dec_slice_struct(p *Properties, is_group bool, base structPointer) error {
|
||||||
|
v := reflect.New(p.stype)
|
||||||
|
bas := toStructPointer(v)
|
||||||
|
structPointer_StructPointerSlice(base, p.field).Append(bas)
|
||||||
|
|
||||||
|
if is_group {
|
||||||
|
err := o.unmarshalType(p.stype, p.sprop, is_group, bas)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
raw, err := o.DecodeRawBytes(false)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the object can unmarshal itself, let it.
|
||||||
|
if p.isUnmarshaler {
|
||||||
|
iv := v.Interface()
|
||||||
|
return iv.(Unmarshaler).Unmarshal(raw)
|
||||||
|
}
|
||||||
|
|
||||||
|
obuf := o.buf
|
||||||
|
oi := o.index
|
||||||
|
o.buf = raw
|
||||||
|
o.index = 0
|
||||||
|
|
||||||
|
err = o.unmarshalType(p.stype, p.sprop, is_group, bas)
|
||||||
|
|
||||||
|
o.buf = obuf
|
||||||
|
o.index = oi
|
||||||
|
|
||||||
|
return err
|
||||||
|
}
|
||||||
169
staging/src/k8s.io/client-go/1.4/_vendor/github.com/gogo/protobuf/proto/decode_gogo.go
generated
Normal file
169
staging/src/k8s.io/client-go/1.4/_vendor/github.com/gogo/protobuf/proto/decode_gogo.go
generated
Normal file
@@ -0,0 +1,169 @@
|
|||||||
|
// Copyright (c) 2013, Vastech SA (PTY) LTD. All rights reserved.
|
||||||
|
// http://github.com/gogo/protobuf/gogoproto
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions are
|
||||||
|
// met:
|
||||||
|
//
|
||||||
|
// * Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
// * Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following disclaimer
|
||||||
|
// in the documentation and/or other materials provided with the
|
||||||
|
// distribution.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
package proto
|
||||||
|
|
||||||
|
import (
|
||||||
|
"reflect"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Decode a reference to a struct pointer.
|
||||||
|
func (o *Buffer) dec_ref_struct_message(p *Properties, base structPointer) (err error) {
|
||||||
|
raw, e := o.DecodeRawBytes(false)
|
||||||
|
if e != nil {
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the object can unmarshal itself, let it.
|
||||||
|
if p.isUnmarshaler {
|
||||||
|
panic("not supported, since this is a pointer receiver")
|
||||||
|
}
|
||||||
|
|
||||||
|
obuf := o.buf
|
||||||
|
oi := o.index
|
||||||
|
o.buf = raw
|
||||||
|
o.index = 0
|
||||||
|
|
||||||
|
bas := structPointer_FieldPointer(base, p.field)
|
||||||
|
|
||||||
|
err = o.unmarshalType(p.stype, p.sprop, false, bas)
|
||||||
|
o.buf = obuf
|
||||||
|
o.index = oi
|
||||||
|
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Decode a slice of references to struct pointers ([]struct).
|
||||||
|
func (o *Buffer) dec_slice_ref_struct(p *Properties, is_group bool, base structPointer) error {
|
||||||
|
newBas := appendStructPointer(base, p.field, p.sstype)
|
||||||
|
|
||||||
|
if is_group {
|
||||||
|
panic("not supported, maybe in future, if requested.")
|
||||||
|
}
|
||||||
|
|
||||||
|
raw, err := o.DecodeRawBytes(false)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the object can unmarshal itself, let it.
|
||||||
|
if p.isUnmarshaler {
|
||||||
|
panic("not supported, since this is not a pointer receiver.")
|
||||||
|
}
|
||||||
|
|
||||||
|
obuf := o.buf
|
||||||
|
oi := o.index
|
||||||
|
o.buf = raw
|
||||||
|
o.index = 0
|
||||||
|
|
||||||
|
err = o.unmarshalType(p.stype, p.sprop, is_group, newBas)
|
||||||
|
|
||||||
|
o.buf = obuf
|
||||||
|
o.index = oi
|
||||||
|
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Decode a slice of references to struct pointers.
|
||||||
|
func (o *Buffer) dec_slice_ref_struct_message(p *Properties, base structPointer) error {
|
||||||
|
return o.dec_slice_ref_struct(p, false, base)
|
||||||
|
}
|
||||||
|
|
||||||
|
func setPtrCustomType(base structPointer, f field, v interface{}) {
|
||||||
|
if v == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
structPointer_SetStructPointer(base, f, structPointer(reflect.ValueOf(v).Pointer()))
|
||||||
|
}
|
||||||
|
|
||||||
|
func setCustomType(base structPointer, f field, value interface{}) {
|
||||||
|
if value == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
v := reflect.ValueOf(value).Elem()
|
||||||
|
t := reflect.TypeOf(value).Elem()
|
||||||
|
kind := t.Kind()
|
||||||
|
switch kind {
|
||||||
|
case reflect.Slice:
|
||||||
|
slice := reflect.MakeSlice(t, v.Len(), v.Cap())
|
||||||
|
reflect.Copy(slice, v)
|
||||||
|
oldHeader := structPointer_GetSliceHeader(base, f)
|
||||||
|
oldHeader.Data = slice.Pointer()
|
||||||
|
oldHeader.Len = v.Len()
|
||||||
|
oldHeader.Cap = v.Cap()
|
||||||
|
default:
|
||||||
|
size := reflect.TypeOf(value).Elem().Size()
|
||||||
|
structPointer_Copy(toStructPointer(reflect.ValueOf(value)), structPointer_Add(base, f), int(size))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *Buffer) dec_custom_bytes(p *Properties, base structPointer) error {
|
||||||
|
b, err := o.DecodeRawBytes(true)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
i := reflect.New(p.ctype.Elem()).Interface()
|
||||||
|
custom := (i).(Unmarshaler)
|
||||||
|
if err := custom.Unmarshal(b); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
setPtrCustomType(base, p.field, custom)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *Buffer) dec_custom_ref_bytes(p *Properties, base structPointer) error {
|
||||||
|
b, err := o.DecodeRawBytes(true)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
i := reflect.New(p.ctype).Interface()
|
||||||
|
custom := (i).(Unmarshaler)
|
||||||
|
if err := custom.Unmarshal(b); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if custom != nil {
|
||||||
|
setCustomType(base, p.field, custom)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Decode a slice of bytes ([]byte) into a slice of custom types.
|
||||||
|
func (o *Buffer) dec_custom_slice_bytes(p *Properties, base structPointer) error {
|
||||||
|
b, err := o.DecodeRawBytes(true)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
i := reflect.New(p.ctype.Elem()).Interface()
|
||||||
|
custom := (i).(Unmarshaler)
|
||||||
|
if err := custom.Unmarshal(b); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
newBas := appendStructPointer(base, p.field, p.ctype)
|
||||||
|
|
||||||
|
setCustomType(newBas, 0, custom)
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
1331
staging/src/k8s.io/client-go/1.4/_vendor/github.com/gogo/protobuf/proto/encode.go
generated
Normal file
1331
staging/src/k8s.io/client-go/1.4/_vendor/github.com/gogo/protobuf/proto/encode.go
generated
Normal file
File diff suppressed because it is too large
Load Diff
354
staging/src/k8s.io/client-go/1.4/_vendor/github.com/gogo/protobuf/proto/encode_gogo.go
generated
Normal file
354
staging/src/k8s.io/client-go/1.4/_vendor/github.com/gogo/protobuf/proto/encode_gogo.go
generated
Normal file
@@ -0,0 +1,354 @@
|
|||||||
|
// Extensions for Protocol Buffers to create more go like structures.
|
||||||
|
//
|
||||||
|
// Copyright (c) 2013, Vastech SA (PTY) LTD. All rights reserved.
|
||||||
|
// http://github.com/gogo/protobuf/gogoproto
|
||||||
|
//
|
||||||
|
// Go support for Protocol Buffers - Google's data interchange format
|
||||||
|
//
|
||||||
|
// Copyright 2010 The Go Authors. All rights reserved.
|
||||||
|
// http://github.com/golang/protobuf/
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions are
|
||||||
|
// met:
|
||||||
|
//
|
||||||
|
// * Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
// * Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following disclaimer
|
||||||
|
// in the documentation and/or other materials provided with the
|
||||||
|
// distribution.
|
||||||
|
// * Neither the name of Google Inc. nor the names of its
|
||||||
|
// contributors may be used to endorse or promote products derived from
|
||||||
|
// this software without specific prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
package proto
|
||||||
|
|
||||||
|
import (
|
||||||
|
"reflect"
|
||||||
|
)
|
||||||
|
|
||||||
|
func NewRequiredNotSetError(field string) *RequiredNotSetError {
|
||||||
|
return &RequiredNotSetError{field}
|
||||||
|
}
|
||||||
|
|
||||||
|
type Sizer interface {
|
||||||
|
Size() int
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *Buffer) enc_ext_slice_byte(p *Properties, base structPointer) error {
|
||||||
|
s := *structPointer_Bytes(base, p.field)
|
||||||
|
if s == nil {
|
||||||
|
return ErrNil
|
||||||
|
}
|
||||||
|
o.buf = append(o.buf, s...)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func size_ext_slice_byte(p *Properties, base structPointer) (n int) {
|
||||||
|
s := *structPointer_Bytes(base, p.field)
|
||||||
|
if s == nil {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
n += len(s)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Encode a reference to bool pointer.
|
||||||
|
func (o *Buffer) enc_ref_bool(p *Properties, base structPointer) error {
|
||||||
|
v := *structPointer_BoolVal(base, p.field)
|
||||||
|
x := 0
|
||||||
|
if v {
|
||||||
|
x = 1
|
||||||
|
}
|
||||||
|
o.buf = append(o.buf, p.tagcode...)
|
||||||
|
p.valEnc(o, uint64(x))
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func size_ref_bool(p *Properties, base structPointer) int {
|
||||||
|
return len(p.tagcode) + 1 // each bool takes exactly one byte
|
||||||
|
}
|
||||||
|
|
||||||
|
// Encode a reference to int32 pointer.
|
||||||
|
func (o *Buffer) enc_ref_int32(p *Properties, base structPointer) error {
|
||||||
|
v := structPointer_Word32Val(base, p.field)
|
||||||
|
x := int32(word32Val_Get(v))
|
||||||
|
o.buf = append(o.buf, p.tagcode...)
|
||||||
|
p.valEnc(o, uint64(x))
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func size_ref_int32(p *Properties, base structPointer) (n int) {
|
||||||
|
v := structPointer_Word32Val(base, p.field)
|
||||||
|
x := int32(word32Val_Get(v))
|
||||||
|
n += len(p.tagcode)
|
||||||
|
n += p.valSize(uint64(x))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *Buffer) enc_ref_uint32(p *Properties, base structPointer) error {
|
||||||
|
v := structPointer_Word32Val(base, p.field)
|
||||||
|
x := word32Val_Get(v)
|
||||||
|
o.buf = append(o.buf, p.tagcode...)
|
||||||
|
p.valEnc(o, uint64(x))
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func size_ref_uint32(p *Properties, base structPointer) (n int) {
|
||||||
|
v := structPointer_Word32Val(base, p.field)
|
||||||
|
x := word32Val_Get(v)
|
||||||
|
n += len(p.tagcode)
|
||||||
|
n += p.valSize(uint64(x))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Encode a reference to an int64 pointer.
|
||||||
|
func (o *Buffer) enc_ref_int64(p *Properties, base structPointer) error {
|
||||||
|
v := structPointer_Word64Val(base, p.field)
|
||||||
|
x := word64Val_Get(v)
|
||||||
|
o.buf = append(o.buf, p.tagcode...)
|
||||||
|
p.valEnc(o, x)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func size_ref_int64(p *Properties, base structPointer) (n int) {
|
||||||
|
v := structPointer_Word64Val(base, p.field)
|
||||||
|
x := word64Val_Get(v)
|
||||||
|
n += len(p.tagcode)
|
||||||
|
n += p.valSize(x)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Encode a reference to a string pointer.
|
||||||
|
func (o *Buffer) enc_ref_string(p *Properties, base structPointer) error {
|
||||||
|
v := *structPointer_StringVal(base, p.field)
|
||||||
|
o.buf = append(o.buf, p.tagcode...)
|
||||||
|
o.EncodeStringBytes(v)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func size_ref_string(p *Properties, base structPointer) (n int) {
|
||||||
|
v := *structPointer_StringVal(base, p.field)
|
||||||
|
n += len(p.tagcode)
|
||||||
|
n += sizeStringBytes(v)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Encode a reference to a message struct.
|
||||||
|
func (o *Buffer) enc_ref_struct_message(p *Properties, base structPointer) error {
|
||||||
|
var state errorState
|
||||||
|
structp := structPointer_GetRefStructPointer(base, p.field)
|
||||||
|
if structPointer_IsNil(structp) {
|
||||||
|
return ErrNil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Can the object marshal itself?
|
||||||
|
if p.isMarshaler {
|
||||||
|
m := structPointer_Interface(structp, p.stype).(Marshaler)
|
||||||
|
data, err := m.Marshal()
|
||||||
|
if err != nil && !state.shouldContinue(err, nil) {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
o.buf = append(o.buf, p.tagcode...)
|
||||||
|
o.EncodeRawBytes(data)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
o.buf = append(o.buf, p.tagcode...)
|
||||||
|
return o.enc_len_struct(p.sprop, structp, &state)
|
||||||
|
}
|
||||||
|
|
||||||
|
//TODO this is only copied, please fix this
|
||||||
|
func size_ref_struct_message(p *Properties, base structPointer) int {
|
||||||
|
structp := structPointer_GetRefStructPointer(base, p.field)
|
||||||
|
if structPointer_IsNil(structp) {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
// Can the object marshal itself?
|
||||||
|
if p.isMarshaler {
|
||||||
|
m := structPointer_Interface(structp, p.stype).(Marshaler)
|
||||||
|
data, _ := m.Marshal()
|
||||||
|
n0 := len(p.tagcode)
|
||||||
|
n1 := sizeRawBytes(data)
|
||||||
|
return n0 + n1
|
||||||
|
}
|
||||||
|
|
||||||
|
n0 := len(p.tagcode)
|
||||||
|
n1 := size_struct(p.sprop, structp)
|
||||||
|
n2 := sizeVarint(uint64(n1)) // size of encoded length
|
||||||
|
return n0 + n1 + n2
|
||||||
|
}
|
||||||
|
|
||||||
|
// Encode a slice of references to message struct pointers ([]struct).
|
||||||
|
func (o *Buffer) enc_slice_ref_struct_message(p *Properties, base structPointer) error {
|
||||||
|
var state errorState
|
||||||
|
ss := structPointer_GetStructPointer(base, p.field)
|
||||||
|
ss1 := structPointer_GetRefStructPointer(ss, field(0))
|
||||||
|
size := p.stype.Size()
|
||||||
|
l := structPointer_Len(base, p.field)
|
||||||
|
for i := 0; i < l; i++ {
|
||||||
|
structp := structPointer_Add(ss1, field(uintptr(i)*size))
|
||||||
|
if structPointer_IsNil(structp) {
|
||||||
|
return errRepeatedHasNil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Can the object marshal itself?
|
||||||
|
if p.isMarshaler {
|
||||||
|
m := structPointer_Interface(structp, p.stype).(Marshaler)
|
||||||
|
data, err := m.Marshal()
|
||||||
|
if err != nil && !state.shouldContinue(err, nil) {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
o.buf = append(o.buf, p.tagcode...)
|
||||||
|
o.EncodeRawBytes(data)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
o.buf = append(o.buf, p.tagcode...)
|
||||||
|
err := o.enc_len_struct(p.sprop, structp, &state)
|
||||||
|
if err != nil && !state.shouldContinue(err, nil) {
|
||||||
|
if err == ErrNil {
|
||||||
|
return errRepeatedHasNil
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
return state.err
|
||||||
|
}
|
||||||
|
|
||||||
|
//TODO this is only copied, please fix this
|
||||||
|
func size_slice_ref_struct_message(p *Properties, base structPointer) (n int) {
|
||||||
|
ss := structPointer_GetStructPointer(base, p.field)
|
||||||
|
ss1 := structPointer_GetRefStructPointer(ss, field(0))
|
||||||
|
size := p.stype.Size()
|
||||||
|
l := structPointer_Len(base, p.field)
|
||||||
|
n += l * len(p.tagcode)
|
||||||
|
for i := 0; i < l; i++ {
|
||||||
|
structp := structPointer_Add(ss1, field(uintptr(i)*size))
|
||||||
|
if structPointer_IsNil(structp) {
|
||||||
|
return // return the size up to this point
|
||||||
|
}
|
||||||
|
|
||||||
|
// Can the object marshal itself?
|
||||||
|
if p.isMarshaler {
|
||||||
|
m := structPointer_Interface(structp, p.stype).(Marshaler)
|
||||||
|
data, _ := m.Marshal()
|
||||||
|
n += len(p.tagcode)
|
||||||
|
n += sizeRawBytes(data)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
n0 := size_struct(p.sprop, structp)
|
||||||
|
n1 := sizeVarint(uint64(n0)) // size of encoded length
|
||||||
|
n += n0 + n1
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *Buffer) enc_custom_bytes(p *Properties, base structPointer) error {
|
||||||
|
i := structPointer_InterfaceRef(base, p.field, p.ctype)
|
||||||
|
if i == nil {
|
||||||
|
return ErrNil
|
||||||
|
}
|
||||||
|
custom := i.(Marshaler)
|
||||||
|
data, err := custom.Marshal()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if data == nil {
|
||||||
|
return ErrNil
|
||||||
|
}
|
||||||
|
o.buf = append(o.buf, p.tagcode...)
|
||||||
|
o.EncodeRawBytes(data)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func size_custom_bytes(p *Properties, base structPointer) (n int) {
|
||||||
|
n += len(p.tagcode)
|
||||||
|
i := structPointer_InterfaceRef(base, p.field, p.ctype)
|
||||||
|
if i == nil {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
custom := i.(Marshaler)
|
||||||
|
data, _ := custom.Marshal()
|
||||||
|
n += sizeRawBytes(data)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *Buffer) enc_custom_ref_bytes(p *Properties, base structPointer) error {
|
||||||
|
custom := structPointer_InterfaceAt(base, p.field, p.ctype).(Marshaler)
|
||||||
|
data, err := custom.Marshal()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if data == nil {
|
||||||
|
return ErrNil
|
||||||
|
}
|
||||||
|
o.buf = append(o.buf, p.tagcode...)
|
||||||
|
o.EncodeRawBytes(data)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func size_custom_ref_bytes(p *Properties, base structPointer) (n int) {
|
||||||
|
n += len(p.tagcode)
|
||||||
|
i := structPointer_InterfaceAt(base, p.field, p.ctype)
|
||||||
|
if i == nil {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
custom := i.(Marshaler)
|
||||||
|
data, _ := custom.Marshal()
|
||||||
|
n += sizeRawBytes(data)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *Buffer) enc_custom_slice_bytes(p *Properties, base structPointer) error {
|
||||||
|
inter := structPointer_InterfaceRef(base, p.field, p.ctype)
|
||||||
|
if inter == nil {
|
||||||
|
return ErrNil
|
||||||
|
}
|
||||||
|
slice := reflect.ValueOf(inter)
|
||||||
|
l := slice.Len()
|
||||||
|
for i := 0; i < l; i++ {
|
||||||
|
v := slice.Index(i)
|
||||||
|
custom := v.Interface().(Marshaler)
|
||||||
|
data, err := custom.Marshal()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
o.buf = append(o.buf, p.tagcode...)
|
||||||
|
o.EncodeRawBytes(data)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func size_custom_slice_bytes(p *Properties, base structPointer) (n int) {
|
||||||
|
inter := structPointer_InterfaceRef(base, p.field, p.ctype)
|
||||||
|
if inter == nil {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
slice := reflect.ValueOf(inter)
|
||||||
|
l := slice.Len()
|
||||||
|
n += l * len(p.tagcode)
|
||||||
|
for i := 0; i < l; i++ {
|
||||||
|
v := slice.Index(i)
|
||||||
|
custom := v.Interface().(Marshaler)
|
||||||
|
data, _ := custom.Marshal()
|
||||||
|
n += sizeRawBytes(data)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
276
staging/src/k8s.io/client-go/1.4/_vendor/github.com/gogo/protobuf/proto/equal.go
generated
Normal file
276
staging/src/k8s.io/client-go/1.4/_vendor/github.com/gogo/protobuf/proto/equal.go
generated
Normal file
@@ -0,0 +1,276 @@
|
|||||||
|
// Go support for Protocol Buffers - Google's data interchange format
|
||||||
|
//
|
||||||
|
// Copyright 2011 The Go Authors. All rights reserved.
|
||||||
|
// https://github.com/golang/protobuf
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions are
|
||||||
|
// met:
|
||||||
|
//
|
||||||
|
// * Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
// * Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following disclaimer
|
||||||
|
// in the documentation and/or other materials provided with the
|
||||||
|
// distribution.
|
||||||
|
// * Neither the name of Google Inc. nor the names of its
|
||||||
|
// contributors may be used to endorse or promote products derived from
|
||||||
|
// this software without specific prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
// Protocol buffer comparison.
|
||||||
|
|
||||||
|
package proto
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"log"
|
||||||
|
"reflect"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
/*
|
||||||
|
Equal returns true iff protocol buffers a and b are equal.
|
||||||
|
The arguments must both be pointers to protocol buffer structs.
|
||||||
|
|
||||||
|
Equality is defined in this way:
|
||||||
|
- Two messages are equal iff they are the same type,
|
||||||
|
corresponding fields are equal, unknown field sets
|
||||||
|
are equal, and extensions sets are equal.
|
||||||
|
- Two set scalar fields are equal iff their values are equal.
|
||||||
|
If the fields are of a floating-point type, remember that
|
||||||
|
NaN != x for all x, including NaN. If the message is defined
|
||||||
|
in a proto3 .proto file, fields are not "set"; specifically,
|
||||||
|
zero length proto3 "bytes" fields are equal (nil == {}).
|
||||||
|
- Two repeated fields are equal iff their lengths are the same,
|
||||||
|
and their corresponding elements are equal (a "bytes" field,
|
||||||
|
although represented by []byte, is not a repeated field)
|
||||||
|
- Two unset fields are equal.
|
||||||
|
- Two unknown field sets are equal if their current
|
||||||
|
encoded state is equal.
|
||||||
|
- Two extension sets are equal iff they have corresponding
|
||||||
|
elements that are pairwise equal.
|
||||||
|
- Every other combination of things are not equal.
|
||||||
|
|
||||||
|
The return value is undefined if a and b are not protocol buffers.
|
||||||
|
*/
|
||||||
|
func Equal(a, b Message) bool {
|
||||||
|
if a == nil || b == nil {
|
||||||
|
return a == b
|
||||||
|
}
|
||||||
|
v1, v2 := reflect.ValueOf(a), reflect.ValueOf(b)
|
||||||
|
if v1.Type() != v2.Type() {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if v1.Kind() == reflect.Ptr {
|
||||||
|
if v1.IsNil() {
|
||||||
|
return v2.IsNil()
|
||||||
|
}
|
||||||
|
if v2.IsNil() {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
v1, v2 = v1.Elem(), v2.Elem()
|
||||||
|
}
|
||||||
|
if v1.Kind() != reflect.Struct {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return equalStruct(v1, v2)
|
||||||
|
}
|
||||||
|
|
||||||
|
// v1 and v2 are known to have the same type.
|
||||||
|
func equalStruct(v1, v2 reflect.Value) bool {
|
||||||
|
sprop := GetProperties(v1.Type())
|
||||||
|
for i := 0; i < v1.NumField(); i++ {
|
||||||
|
f := v1.Type().Field(i)
|
||||||
|
if strings.HasPrefix(f.Name, "XXX_") {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
f1, f2 := v1.Field(i), v2.Field(i)
|
||||||
|
if f.Type.Kind() == reflect.Ptr {
|
||||||
|
if n1, n2 := f1.IsNil(), f2.IsNil(); n1 && n2 {
|
||||||
|
// both unset
|
||||||
|
continue
|
||||||
|
} else if n1 != n2 {
|
||||||
|
// set/unset mismatch
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
b1, ok := f1.Interface().(raw)
|
||||||
|
if ok {
|
||||||
|
b2 := f2.Interface().(raw)
|
||||||
|
// RawMessage
|
||||||
|
if !bytes.Equal(b1.Bytes(), b2.Bytes()) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
f1, f2 = f1.Elem(), f2.Elem()
|
||||||
|
}
|
||||||
|
if !equalAny(f1, f2, sprop.Prop[i]) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if em1 := v1.FieldByName("XXX_extensions"); em1.IsValid() {
|
||||||
|
em2 := v2.FieldByName("XXX_extensions")
|
||||||
|
if !equalExtensions(v1.Type(), em1.Interface().(map[int32]Extension), em2.Interface().(map[int32]Extension)) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uf := v1.FieldByName("XXX_unrecognized")
|
||||||
|
if !uf.IsValid() {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
u1 := uf.Bytes()
|
||||||
|
u2 := v2.FieldByName("XXX_unrecognized").Bytes()
|
||||||
|
if !bytes.Equal(u1, u2) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// v1 and v2 are known to have the same type.
|
||||||
|
// prop may be nil.
|
||||||
|
func equalAny(v1, v2 reflect.Value, prop *Properties) bool {
|
||||||
|
if v1.Type() == protoMessageType {
|
||||||
|
m1, _ := v1.Interface().(Message)
|
||||||
|
m2, _ := v2.Interface().(Message)
|
||||||
|
return Equal(m1, m2)
|
||||||
|
}
|
||||||
|
switch v1.Kind() {
|
||||||
|
case reflect.Bool:
|
||||||
|
return v1.Bool() == v2.Bool()
|
||||||
|
case reflect.Float32, reflect.Float64:
|
||||||
|
return v1.Float() == v2.Float()
|
||||||
|
case reflect.Int32, reflect.Int64:
|
||||||
|
return v1.Int() == v2.Int()
|
||||||
|
case reflect.Interface:
|
||||||
|
// Probably a oneof field; compare the inner values.
|
||||||
|
n1, n2 := v1.IsNil(), v2.IsNil()
|
||||||
|
if n1 || n2 {
|
||||||
|
return n1 == n2
|
||||||
|
}
|
||||||
|
e1, e2 := v1.Elem(), v2.Elem()
|
||||||
|
if e1.Type() != e2.Type() {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return equalAny(e1, e2, nil)
|
||||||
|
case reflect.Map:
|
||||||
|
if v1.Len() != v2.Len() {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
for _, key := range v1.MapKeys() {
|
||||||
|
val2 := v2.MapIndex(key)
|
||||||
|
if !val2.IsValid() {
|
||||||
|
// This key was not found in the second map.
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if !equalAny(v1.MapIndex(key), val2, nil) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
case reflect.Ptr:
|
||||||
|
return equalAny(v1.Elem(), v2.Elem(), prop)
|
||||||
|
case reflect.Slice:
|
||||||
|
if v1.Type().Elem().Kind() == reflect.Uint8 {
|
||||||
|
// short circuit: []byte
|
||||||
|
|
||||||
|
// Edge case: if this is in a proto3 message, a zero length
|
||||||
|
// bytes field is considered the zero value.
|
||||||
|
if prop != nil && prop.proto3 && v1.Len() == 0 && v2.Len() == 0 {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
if v1.IsNil() != v2.IsNil() {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return bytes.Equal(v1.Interface().([]byte), v2.Interface().([]byte))
|
||||||
|
}
|
||||||
|
|
||||||
|
if v1.Len() != v2.Len() {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
for i := 0; i < v1.Len(); i++ {
|
||||||
|
if !equalAny(v1.Index(i), v2.Index(i), prop) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
case reflect.String:
|
||||||
|
return v1.Interface().(string) == v2.Interface().(string)
|
||||||
|
case reflect.Struct:
|
||||||
|
return equalStruct(v1, v2)
|
||||||
|
case reflect.Uint32, reflect.Uint64:
|
||||||
|
return v1.Uint() == v2.Uint()
|
||||||
|
}
|
||||||
|
|
||||||
|
// unknown type, so not a protocol buffer
|
||||||
|
log.Printf("proto: don't know how to compare %v", v1)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// base is the struct type that the extensions are based on.
|
||||||
|
// em1 and em2 are extension maps.
|
||||||
|
func equalExtensions(base reflect.Type, em1, em2 map[int32]Extension) bool {
|
||||||
|
if len(em1) != len(em2) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
for extNum, e1 := range em1 {
|
||||||
|
e2, ok := em2[extNum]
|
||||||
|
if !ok {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
m1, m2 := e1.value, e2.value
|
||||||
|
|
||||||
|
if m1 != nil && m2 != nil {
|
||||||
|
// Both are unencoded.
|
||||||
|
if !equalAny(reflect.ValueOf(m1), reflect.ValueOf(m2), nil) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// At least one is encoded. To do a semantically correct comparison
|
||||||
|
// we need to unmarshal them first.
|
||||||
|
var desc *ExtensionDesc
|
||||||
|
if m := extensionMaps[base]; m != nil {
|
||||||
|
desc = m[extNum]
|
||||||
|
}
|
||||||
|
if desc == nil {
|
||||||
|
log.Printf("proto: don't know how to compare extension %d of %v", extNum, base)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
var err error
|
||||||
|
if m1 == nil {
|
||||||
|
m1, err = decodeExtension(e1.enc, desc)
|
||||||
|
}
|
||||||
|
if m2 == nil && err == nil {
|
||||||
|
m2, err = decodeExtension(e2.enc, desc)
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
// The encoded form is invalid.
|
||||||
|
log.Printf("proto: badly encoded extension %d of %v: %v", extNum, base, err)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if !equalAny(reflect.ValueOf(m1), reflect.ValueOf(m2), nil) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
518
staging/src/k8s.io/client-go/1.4/_vendor/github.com/gogo/protobuf/proto/extensions.go
generated
Normal file
518
staging/src/k8s.io/client-go/1.4/_vendor/github.com/gogo/protobuf/proto/extensions.go
generated
Normal file
@@ -0,0 +1,518 @@
|
|||||||
|
// Go support for Protocol Buffers - Google's data interchange format
|
||||||
|
//
|
||||||
|
// Copyright 2010 The Go Authors. All rights reserved.
|
||||||
|
// https://github.com/golang/protobuf
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions are
|
||||||
|
// met:
|
||||||
|
//
|
||||||
|
// * Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
// * Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following disclaimer
|
||||||
|
// in the documentation and/or other materials provided with the
|
||||||
|
// distribution.
|
||||||
|
// * Neither the name of Google Inc. nor the names of its
|
||||||
|
// contributors may be used to endorse or promote products derived from
|
||||||
|
// this software without specific prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
package proto
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Types and routines for supporting protocol buffer extensions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"reflect"
|
||||||
|
"strconv"
|
||||||
|
"sync"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ErrMissingExtension is the error returned by GetExtension if the named extension is not in the message.
|
||||||
|
var ErrMissingExtension = errors.New("proto: missing extension")
|
||||||
|
|
||||||
|
// ExtensionRange represents a range of message extensions for a protocol buffer.
|
||||||
|
// Used in code generated by the protocol compiler.
|
||||||
|
type ExtensionRange struct {
|
||||||
|
Start, End int32 // both inclusive
|
||||||
|
}
|
||||||
|
|
||||||
|
// extendableProto is an interface implemented by any protocol buffer that may be extended.
|
||||||
|
type extendableProto interface {
|
||||||
|
Message
|
||||||
|
ExtensionRangeArray() []ExtensionRange
|
||||||
|
}
|
||||||
|
|
||||||
|
type extensionsMap interface {
|
||||||
|
extendableProto
|
||||||
|
ExtensionMap() map[int32]Extension
|
||||||
|
}
|
||||||
|
|
||||||
|
type extensionsBytes interface {
|
||||||
|
extendableProto
|
||||||
|
GetExtensions() *[]byte
|
||||||
|
}
|
||||||
|
|
||||||
|
var extendableProtoType = reflect.TypeOf((*extendableProto)(nil)).Elem()
|
||||||
|
|
||||||
|
// ExtensionDesc represents an extension specification.
|
||||||
|
// Used in generated code from the protocol compiler.
|
||||||
|
type ExtensionDesc struct {
|
||||||
|
ExtendedType Message // nil pointer to the type that is being extended
|
||||||
|
ExtensionType interface{} // nil pointer to the extension type
|
||||||
|
Field int32 // field number
|
||||||
|
Name string // fully-qualified name of extension, for text formatting
|
||||||
|
Tag string // protobuf tag style
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ed *ExtensionDesc) repeated() bool {
|
||||||
|
t := reflect.TypeOf(ed.ExtensionType)
|
||||||
|
return t.Kind() == reflect.Slice && t.Elem().Kind() != reflect.Uint8
|
||||||
|
}
|
||||||
|
|
||||||
|
// Extension represents an extension in a message.
|
||||||
|
type Extension struct {
|
||||||
|
// When an extension is stored in a message using SetExtension
|
||||||
|
// only desc and value are set. When the message is marshaled
|
||||||
|
// enc will be set to the encoded form of the message.
|
||||||
|
//
|
||||||
|
// When a message is unmarshaled and contains extensions, each
|
||||||
|
// extension will have only enc set. When such an extension is
|
||||||
|
// accessed using GetExtension (or GetExtensions) desc and value
|
||||||
|
// will be set.
|
||||||
|
desc *ExtensionDesc
|
||||||
|
value interface{}
|
||||||
|
enc []byte
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetRawExtension is for testing only.
|
||||||
|
func SetRawExtension(base extendableProto, id int32, b []byte) {
|
||||||
|
if ebase, ok := base.(extensionsMap); ok {
|
||||||
|
ebase.ExtensionMap()[id] = Extension{enc: b}
|
||||||
|
} else if ebase, ok := base.(extensionsBytes); ok {
|
||||||
|
clearExtension(base, id)
|
||||||
|
ext := ebase.GetExtensions()
|
||||||
|
*ext = append(*ext, b...)
|
||||||
|
} else {
|
||||||
|
panic("unreachable")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// isExtensionField returns true iff the given field number is in an extension range.
|
||||||
|
func isExtensionField(pb extendableProto, field int32) bool {
|
||||||
|
for _, er := range pb.ExtensionRangeArray() {
|
||||||
|
if er.Start <= field && field <= er.End {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// checkExtensionTypes checks that the given extension is valid for pb.
|
||||||
|
func checkExtensionTypes(pb extendableProto, extension *ExtensionDesc) error {
|
||||||
|
// Check the extended type.
|
||||||
|
if a, b := reflect.TypeOf(pb), reflect.TypeOf(extension.ExtendedType); a != b {
|
||||||
|
return errors.New("proto: bad extended type; " + b.String() + " does not extend " + a.String())
|
||||||
|
}
|
||||||
|
// Check the range.
|
||||||
|
if !isExtensionField(pb, extension.Field) {
|
||||||
|
return errors.New("proto: bad extension number; not in declared ranges")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// extPropKey is sufficient to uniquely identify an extension.
|
||||||
|
type extPropKey struct {
|
||||||
|
base reflect.Type
|
||||||
|
field int32
|
||||||
|
}
|
||||||
|
|
||||||
|
var extProp = struct {
|
||||||
|
sync.RWMutex
|
||||||
|
m map[extPropKey]*Properties
|
||||||
|
}{
|
||||||
|
m: make(map[extPropKey]*Properties),
|
||||||
|
}
|
||||||
|
|
||||||
|
func extensionProperties(ed *ExtensionDesc) *Properties {
|
||||||
|
key := extPropKey{base: reflect.TypeOf(ed.ExtendedType), field: ed.Field}
|
||||||
|
|
||||||
|
extProp.RLock()
|
||||||
|
if prop, ok := extProp.m[key]; ok {
|
||||||
|
extProp.RUnlock()
|
||||||
|
return prop
|
||||||
|
}
|
||||||
|
extProp.RUnlock()
|
||||||
|
|
||||||
|
extProp.Lock()
|
||||||
|
defer extProp.Unlock()
|
||||||
|
// Check again.
|
||||||
|
if prop, ok := extProp.m[key]; ok {
|
||||||
|
return prop
|
||||||
|
}
|
||||||
|
|
||||||
|
prop := new(Properties)
|
||||||
|
prop.Init(reflect.TypeOf(ed.ExtensionType), "unknown_name", ed.Tag, nil)
|
||||||
|
extProp.m[key] = prop
|
||||||
|
return prop
|
||||||
|
}
|
||||||
|
|
||||||
|
// encodeExtensionMap encodes any unmarshaled (unencoded) extensions in m.
|
||||||
|
func encodeExtensionMap(m map[int32]Extension) error {
|
||||||
|
for k, e := range m {
|
||||||
|
err := encodeExtension(&e)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
m[k] = e
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func encodeExtension(e *Extension) error {
|
||||||
|
if e.value == nil || e.desc == nil {
|
||||||
|
// Extension is only in its encoded form.
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
// We don't skip extensions that have an encoded form set,
|
||||||
|
// because the extension value may have been mutated after
|
||||||
|
// the last time this function was called.
|
||||||
|
|
||||||
|
et := reflect.TypeOf(e.desc.ExtensionType)
|
||||||
|
props := extensionProperties(e.desc)
|
||||||
|
|
||||||
|
p := NewBuffer(nil)
|
||||||
|
// If e.value has type T, the encoder expects a *struct{ X T }.
|
||||||
|
// Pass a *T with a zero field and hope it all works out.
|
||||||
|
x := reflect.New(et)
|
||||||
|
x.Elem().Set(reflect.ValueOf(e.value))
|
||||||
|
if err := props.enc(p, props, toStructPointer(x)); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
e.enc = p.buf
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func sizeExtensionMap(m map[int32]Extension) (n int) {
|
||||||
|
for _, e := range m {
|
||||||
|
if e.value == nil || e.desc == nil {
|
||||||
|
// Extension is only in its encoded form.
|
||||||
|
n += len(e.enc)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// We don't skip extensions that have an encoded form set,
|
||||||
|
// because the extension value may have been mutated after
|
||||||
|
// the last time this function was called.
|
||||||
|
|
||||||
|
et := reflect.TypeOf(e.desc.ExtensionType)
|
||||||
|
props := extensionProperties(e.desc)
|
||||||
|
|
||||||
|
// If e.value has type T, the encoder expects a *struct{ X T }.
|
||||||
|
// Pass a *T with a zero field and hope it all works out.
|
||||||
|
x := reflect.New(et)
|
||||||
|
x.Elem().Set(reflect.ValueOf(e.value))
|
||||||
|
n += props.size(props, toStructPointer(x))
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// HasExtension returns whether the given extension is present in pb.
|
||||||
|
func HasExtension(pb extendableProto, extension *ExtensionDesc) bool {
|
||||||
|
// TODO: Check types, field numbers, etc.?
|
||||||
|
if epb, doki := pb.(extensionsMap); doki {
|
||||||
|
_, ok := epb.ExtensionMap()[extension.Field]
|
||||||
|
return ok
|
||||||
|
} else if epb, doki := pb.(extensionsBytes); doki {
|
||||||
|
ext := epb.GetExtensions()
|
||||||
|
buf := *ext
|
||||||
|
o := 0
|
||||||
|
for o < len(buf) {
|
||||||
|
tag, n := DecodeVarint(buf[o:])
|
||||||
|
fieldNum := int32(tag >> 3)
|
||||||
|
if int32(fieldNum) == extension.Field {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
wireType := int(tag & 0x7)
|
||||||
|
o += n
|
||||||
|
l, err := size(buf[o:], wireType)
|
||||||
|
if err != nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
o += l
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
panic("unreachable")
|
||||||
|
}
|
||||||
|
|
||||||
|
func deleteExtension(pb extensionsBytes, theFieldNum int32, offset int) int {
|
||||||
|
ext := pb.GetExtensions()
|
||||||
|
for offset < len(*ext) {
|
||||||
|
tag, n1 := DecodeVarint((*ext)[offset:])
|
||||||
|
fieldNum := int32(tag >> 3)
|
||||||
|
wireType := int(tag & 0x7)
|
||||||
|
n2, err := size((*ext)[offset+n1:], wireType)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
newOffset := offset + n1 + n2
|
||||||
|
if fieldNum == theFieldNum {
|
||||||
|
*ext = append((*ext)[:offset], (*ext)[newOffset:]...)
|
||||||
|
return offset
|
||||||
|
}
|
||||||
|
offset = newOffset
|
||||||
|
}
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
|
||||||
|
func clearExtension(pb extendableProto, fieldNum int32) {
|
||||||
|
if epb, doki := pb.(extensionsMap); doki {
|
||||||
|
delete(epb.ExtensionMap(), fieldNum)
|
||||||
|
} else if epb, doki := pb.(extensionsBytes); doki {
|
||||||
|
offset := 0
|
||||||
|
for offset != -1 {
|
||||||
|
offset = deleteExtension(epb, fieldNum, offset)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
panic("unreachable")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ClearExtension removes the given extension from pb.
|
||||||
|
func ClearExtension(pb extendableProto, extension *ExtensionDesc) {
|
||||||
|
// TODO: Check types, field numbers, etc.?
|
||||||
|
clearExtension(pb, extension.Field)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetExtension parses and returns the given extension of pb.
|
||||||
|
// If the extension is not present it returns ErrMissingExtension.
|
||||||
|
func GetExtension(pb extendableProto, extension *ExtensionDesc) (interface{}, error) {
|
||||||
|
if err := checkExtensionTypes(pb, extension); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if epb, doki := pb.(extensionsMap); doki {
|
||||||
|
emap := epb.ExtensionMap()
|
||||||
|
e, ok := emap[extension.Field]
|
||||||
|
if !ok {
|
||||||
|
// defaultExtensionValue returns the default value or
|
||||||
|
// ErrMissingExtension if there is no default.
|
||||||
|
return defaultExtensionValue(extension)
|
||||||
|
}
|
||||||
|
if e.value != nil {
|
||||||
|
// Already decoded. Check the descriptor, though.
|
||||||
|
if e.desc != extension {
|
||||||
|
// This shouldn't happen. If it does, it means that
|
||||||
|
// GetExtension was called twice with two different
|
||||||
|
// descriptors with the same field number.
|
||||||
|
return nil, errors.New("proto: descriptor conflict")
|
||||||
|
}
|
||||||
|
return e.value, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
v, err := decodeExtension(e.enc, extension)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remember the decoded version and drop the encoded version.
|
||||||
|
// That way it is safe to mutate what we return.
|
||||||
|
e.value = v
|
||||||
|
e.desc = extension
|
||||||
|
e.enc = nil
|
||||||
|
emap[extension.Field] = e
|
||||||
|
return e.value, nil
|
||||||
|
} else if epb, doki := pb.(extensionsBytes); doki {
|
||||||
|
ext := epb.GetExtensions()
|
||||||
|
o := 0
|
||||||
|
for o < len(*ext) {
|
||||||
|
tag, n := DecodeVarint((*ext)[o:])
|
||||||
|
fieldNum := int32(tag >> 3)
|
||||||
|
wireType := int(tag & 0x7)
|
||||||
|
l, err := size((*ext)[o+n:], wireType)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if int32(fieldNum) == extension.Field {
|
||||||
|
v, err := decodeExtension((*ext)[o:o+n+l], extension)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return v, nil
|
||||||
|
}
|
||||||
|
o += n + l
|
||||||
|
}
|
||||||
|
return defaultExtensionValue(extension)
|
||||||
|
}
|
||||||
|
panic("unreachable")
|
||||||
|
}
|
||||||
|
|
||||||
|
// defaultExtensionValue returns the default value for extension.
|
||||||
|
// If no default for an extension is defined ErrMissingExtension is returned.
|
||||||
|
func defaultExtensionValue(extension *ExtensionDesc) (interface{}, error) {
|
||||||
|
t := reflect.TypeOf(extension.ExtensionType)
|
||||||
|
props := extensionProperties(extension)
|
||||||
|
|
||||||
|
sf, _, err := fieldDefault(t, props)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if sf == nil || sf.value == nil {
|
||||||
|
// There is no default value.
|
||||||
|
return nil, ErrMissingExtension
|
||||||
|
}
|
||||||
|
|
||||||
|
if t.Kind() != reflect.Ptr {
|
||||||
|
// We do not need to return a Ptr, we can directly return sf.value.
|
||||||
|
return sf.value, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// We need to return an interface{} that is a pointer to sf.value.
|
||||||
|
value := reflect.New(t).Elem()
|
||||||
|
value.Set(reflect.New(value.Type().Elem()))
|
||||||
|
if sf.kind == reflect.Int32 {
|
||||||
|
// We may have an int32 or an enum, but the underlying data is int32.
|
||||||
|
// Since we can't set an int32 into a non int32 reflect.value directly
|
||||||
|
// set it as a int32.
|
||||||
|
value.Elem().SetInt(int64(sf.value.(int32)))
|
||||||
|
} else {
|
||||||
|
value.Elem().Set(reflect.ValueOf(sf.value))
|
||||||
|
}
|
||||||
|
return value.Interface(), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// decodeExtension decodes an extension encoded in b.
|
||||||
|
func decodeExtension(b []byte, extension *ExtensionDesc) (interface{}, error) {
|
||||||
|
o := NewBuffer(b)
|
||||||
|
|
||||||
|
t := reflect.TypeOf(extension.ExtensionType)
|
||||||
|
|
||||||
|
props := extensionProperties(extension)
|
||||||
|
|
||||||
|
// t is a pointer to a struct, pointer to basic type or a slice.
|
||||||
|
// Allocate a "field" to store the pointer/slice itself; the
|
||||||
|
// pointer/slice will be stored here. We pass
|
||||||
|
// the address of this field to props.dec.
|
||||||
|
// This passes a zero field and a *t and lets props.dec
|
||||||
|
// interpret it as a *struct{ x t }.
|
||||||
|
value := reflect.New(t).Elem()
|
||||||
|
|
||||||
|
for {
|
||||||
|
// Discard wire type and field number varint. It isn't needed.
|
||||||
|
if _, err := o.DecodeVarint(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := props.dec(o, props, toStructPointer(value.Addr())); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if o.index >= len(o.buf) {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return value.Interface(), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetExtensions returns a slice of the extensions present in pb that are also listed in es.
|
||||||
|
// The returned slice has the same length as es; missing extensions will appear as nil elements.
|
||||||
|
func GetExtensions(pb Message, es []*ExtensionDesc) (extensions []interface{}, err error) {
|
||||||
|
epb, ok := pb.(extendableProto)
|
||||||
|
if !ok {
|
||||||
|
err = errors.New("proto: not an extendable proto")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
extensions = make([]interface{}, len(es))
|
||||||
|
for i, e := range es {
|
||||||
|
extensions[i], err = GetExtension(epb, e)
|
||||||
|
if err == ErrMissingExtension {
|
||||||
|
err = nil
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetExtension sets the specified extension of pb to the specified value.
|
||||||
|
func SetExtension(pb extendableProto, extension *ExtensionDesc, value interface{}) error {
|
||||||
|
if err := checkExtensionTypes(pb, extension); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
typ := reflect.TypeOf(extension.ExtensionType)
|
||||||
|
if typ != reflect.TypeOf(value) {
|
||||||
|
return errors.New("proto: bad extension value type")
|
||||||
|
}
|
||||||
|
// nil extension values need to be caught early, because the
|
||||||
|
// encoder can't distinguish an ErrNil due to a nil extension
|
||||||
|
// from an ErrNil due to a missing field. Extensions are
|
||||||
|
// always optional, so the encoder would just swallow the error
|
||||||
|
// and drop all the extensions from the encoded message.
|
||||||
|
if reflect.ValueOf(value).IsNil() {
|
||||||
|
return fmt.Errorf("proto: SetExtension called with nil value of type %T", value)
|
||||||
|
}
|
||||||
|
return setExtension(pb, extension, value)
|
||||||
|
}
|
||||||
|
|
||||||
|
func setExtension(pb extendableProto, extension *ExtensionDesc, value interface{}) error {
|
||||||
|
if epb, doki := pb.(extensionsMap); doki {
|
||||||
|
epb.ExtensionMap()[extension.Field] = Extension{desc: extension, value: value}
|
||||||
|
} else if epb, doki := pb.(extensionsBytes); doki {
|
||||||
|
ClearExtension(pb, extension)
|
||||||
|
ext := epb.GetExtensions()
|
||||||
|
et := reflect.TypeOf(extension.ExtensionType)
|
||||||
|
props := extensionProperties(extension)
|
||||||
|
p := NewBuffer(nil)
|
||||||
|
x := reflect.New(et)
|
||||||
|
x.Elem().Set(reflect.ValueOf(value))
|
||||||
|
if err := props.enc(p, props, toStructPointer(x)); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
*ext = append(*ext, p.buf...)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// A global registry of extensions.
|
||||||
|
// The generated code will register the generated descriptors by calling RegisterExtension.
|
||||||
|
|
||||||
|
var extensionMaps = make(map[reflect.Type]map[int32]*ExtensionDesc)
|
||||||
|
|
||||||
|
// RegisterExtension is called from the generated code.
|
||||||
|
func RegisterExtension(desc *ExtensionDesc) {
|
||||||
|
st := reflect.TypeOf(desc.ExtendedType).Elem()
|
||||||
|
m := extensionMaps[st]
|
||||||
|
if m == nil {
|
||||||
|
m = make(map[int32]*ExtensionDesc)
|
||||||
|
extensionMaps[st] = m
|
||||||
|
}
|
||||||
|
if _, ok := m[desc.Field]; ok {
|
||||||
|
panic("proto: duplicate extension registered: " + st.String() + " " + strconv.Itoa(int(desc.Field)))
|
||||||
|
}
|
||||||
|
m[desc.Field] = desc
|
||||||
|
}
|
||||||
|
|
||||||
|
// RegisteredExtensions returns a map of the registered extensions of a
|
||||||
|
// protocol buffer struct, indexed by the extension number.
|
||||||
|
// The argument pb should be a nil pointer to the struct type.
|
||||||
|
func RegisteredExtensions(pb Message) map[int32]*ExtensionDesc {
|
||||||
|
return extensionMaps[reflect.TypeOf(pb).Elem()]
|
||||||
|
}
|
||||||
236
staging/src/k8s.io/client-go/1.4/_vendor/github.com/gogo/protobuf/proto/extensions_gogo.go
generated
Normal file
236
staging/src/k8s.io/client-go/1.4/_vendor/github.com/gogo/protobuf/proto/extensions_gogo.go
generated
Normal file
@@ -0,0 +1,236 @@
|
|||||||
|
// Copyright (c) 2013, Vastech SA (PTY) LTD. All rights reserved.
|
||||||
|
// http://github.com/gogo/protobuf/gogoproto
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions are
|
||||||
|
// met:
|
||||||
|
//
|
||||||
|
// * Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
// * Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following disclaimer
|
||||||
|
// in the documentation and/or other materials provided with the
|
||||||
|
// distribution.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
package proto
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"reflect"
|
||||||
|
"sort"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
func GetBoolExtension(pb extendableProto, extension *ExtensionDesc, ifnotset bool) bool {
|
||||||
|
if reflect.ValueOf(pb).IsNil() {
|
||||||
|
return ifnotset
|
||||||
|
}
|
||||||
|
value, err := GetExtension(pb, extension)
|
||||||
|
if err != nil {
|
||||||
|
return ifnotset
|
||||||
|
}
|
||||||
|
if value == nil {
|
||||||
|
return ifnotset
|
||||||
|
}
|
||||||
|
if value.(*bool) == nil {
|
||||||
|
return ifnotset
|
||||||
|
}
|
||||||
|
return *(value.(*bool))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *Extension) Equal(that *Extension) bool {
|
||||||
|
return bytes.Equal(this.enc, that.enc)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *Extension) Compare(that *Extension) int {
|
||||||
|
return bytes.Compare(this.enc, that.enc)
|
||||||
|
}
|
||||||
|
|
||||||
|
func SizeOfExtensionMap(m map[int32]Extension) (n int) {
|
||||||
|
return sizeExtensionMap(m)
|
||||||
|
}
|
||||||
|
|
||||||
|
type sortableMapElem struct {
|
||||||
|
field int32
|
||||||
|
ext Extension
|
||||||
|
}
|
||||||
|
|
||||||
|
func newSortableExtensionsFromMap(m map[int32]Extension) sortableExtensions {
|
||||||
|
s := make(sortableExtensions, 0, len(m))
|
||||||
|
for k, v := range m {
|
||||||
|
s = append(s, &sortableMapElem{field: k, ext: v})
|
||||||
|
}
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
|
||||||
|
type sortableExtensions []*sortableMapElem
|
||||||
|
|
||||||
|
func (this sortableExtensions) Len() int { return len(this) }
|
||||||
|
|
||||||
|
func (this sortableExtensions) Swap(i, j int) { this[i], this[j] = this[j], this[i] }
|
||||||
|
|
||||||
|
func (this sortableExtensions) Less(i, j int) bool { return this[i].field < this[j].field }
|
||||||
|
|
||||||
|
func (this sortableExtensions) String() string {
|
||||||
|
sort.Sort(this)
|
||||||
|
ss := make([]string, len(this))
|
||||||
|
for i := range this {
|
||||||
|
ss[i] = fmt.Sprintf("%d: %v", this[i].field, this[i].ext)
|
||||||
|
}
|
||||||
|
return "map[" + strings.Join(ss, ",") + "]"
|
||||||
|
}
|
||||||
|
|
||||||
|
func StringFromExtensionsMap(m map[int32]Extension) string {
|
||||||
|
return newSortableExtensionsFromMap(m).String()
|
||||||
|
}
|
||||||
|
|
||||||
|
func StringFromExtensionsBytes(ext []byte) string {
|
||||||
|
m, err := BytesToExtensionsMap(ext)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
return StringFromExtensionsMap(m)
|
||||||
|
}
|
||||||
|
|
||||||
|
func EncodeExtensionMap(m map[int32]Extension, data []byte) (n int, err error) {
|
||||||
|
if err := encodeExtensionMap(m); err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
keys := make([]int, 0, len(m))
|
||||||
|
for k := range m {
|
||||||
|
keys = append(keys, int(k))
|
||||||
|
}
|
||||||
|
sort.Ints(keys)
|
||||||
|
for _, k := range keys {
|
||||||
|
n += copy(data[n:], m[int32(k)].enc)
|
||||||
|
}
|
||||||
|
return n, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetRawExtension(m map[int32]Extension, id int32) ([]byte, error) {
|
||||||
|
if m[id].value == nil || m[id].desc == nil {
|
||||||
|
return m[id].enc, nil
|
||||||
|
}
|
||||||
|
if err := encodeExtensionMap(m); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return m[id].enc, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func size(buf []byte, wire int) (int, error) {
|
||||||
|
switch wire {
|
||||||
|
case WireVarint:
|
||||||
|
_, n := DecodeVarint(buf)
|
||||||
|
return n, nil
|
||||||
|
case WireFixed64:
|
||||||
|
return 8, nil
|
||||||
|
case WireBytes:
|
||||||
|
v, n := DecodeVarint(buf)
|
||||||
|
return int(v) + n, nil
|
||||||
|
case WireFixed32:
|
||||||
|
return 4, nil
|
||||||
|
case WireStartGroup:
|
||||||
|
offset := 0
|
||||||
|
for {
|
||||||
|
u, n := DecodeVarint(buf[offset:])
|
||||||
|
fwire := int(u & 0x7)
|
||||||
|
offset += n
|
||||||
|
if fwire == WireEndGroup {
|
||||||
|
return offset, nil
|
||||||
|
}
|
||||||
|
s, err := size(buf[offset:], wire)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
offset += s
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0, fmt.Errorf("proto: can't get size for unknown wire type %d", wire)
|
||||||
|
}
|
||||||
|
|
||||||
|
func BytesToExtensionsMap(buf []byte) (map[int32]Extension, error) {
|
||||||
|
m := make(map[int32]Extension)
|
||||||
|
i := 0
|
||||||
|
for i < len(buf) {
|
||||||
|
tag, n := DecodeVarint(buf[i:])
|
||||||
|
if n <= 0 {
|
||||||
|
return nil, fmt.Errorf("unable to decode varint")
|
||||||
|
}
|
||||||
|
fieldNum := int32(tag >> 3)
|
||||||
|
wireType := int(tag & 0x7)
|
||||||
|
l, err := size(buf[i+n:], wireType)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
end := i + int(l) + n
|
||||||
|
m[int32(fieldNum)] = Extension{enc: buf[i:end]}
|
||||||
|
i = end
|
||||||
|
}
|
||||||
|
return m, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewExtension(e []byte) Extension {
|
||||||
|
ee := Extension{enc: make([]byte, len(e))}
|
||||||
|
copy(ee.enc, e)
|
||||||
|
return ee
|
||||||
|
}
|
||||||
|
|
||||||
|
func AppendExtension(e extendableProto, tag int32, buf []byte) {
|
||||||
|
if ee, eok := e.(extensionsMap); eok {
|
||||||
|
ext := ee.ExtensionMap()[int32(tag)] // may be missing
|
||||||
|
ext.enc = append(ext.enc, buf...)
|
||||||
|
ee.ExtensionMap()[int32(tag)] = ext
|
||||||
|
} else if ee, eok := e.(extensionsBytes); eok {
|
||||||
|
ext := ee.GetExtensions()
|
||||||
|
*ext = append(*ext, buf...)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this Extension) GoString() string {
|
||||||
|
if this.enc == nil {
|
||||||
|
if err := encodeExtension(&this); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return fmt.Sprintf("proto.NewExtension(%#v)", this.enc)
|
||||||
|
}
|
||||||
|
|
||||||
|
func SetUnsafeExtension(pb extendableProto, fieldNum int32, value interface{}) error {
|
||||||
|
typ := reflect.TypeOf(pb).Elem()
|
||||||
|
ext, ok := extensionMaps[typ]
|
||||||
|
if !ok {
|
||||||
|
return fmt.Errorf("proto: bad extended type; %s is not extendable", typ.String())
|
||||||
|
}
|
||||||
|
desc, ok := ext[fieldNum]
|
||||||
|
if !ok {
|
||||||
|
return errors.New("proto: bad extension number; not in declared ranges")
|
||||||
|
}
|
||||||
|
return setExtension(pb, desc, value)
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetUnsafeExtension(pb extendableProto, fieldNum int32) (interface{}, error) {
|
||||||
|
typ := reflect.TypeOf(pb).Elem()
|
||||||
|
ext, ok := extensionMaps[typ]
|
||||||
|
if !ok {
|
||||||
|
return nil, fmt.Errorf("proto: bad extended type; %s is not extendable", typ.String())
|
||||||
|
}
|
||||||
|
desc, ok := ext[fieldNum]
|
||||||
|
if !ok {
|
||||||
|
return nil, fmt.Errorf("unregistered field number %d", fieldNum)
|
||||||
|
}
|
||||||
|
return GetExtension(pb, desc)
|
||||||
|
}
|
||||||
894
staging/src/k8s.io/client-go/1.4/_vendor/github.com/gogo/protobuf/proto/lib.go
generated
Normal file
894
staging/src/k8s.io/client-go/1.4/_vendor/github.com/gogo/protobuf/proto/lib.go
generated
Normal file
@@ -0,0 +1,894 @@
|
|||||||
|
// Go support for Protocol Buffers - Google's data interchange format
|
||||||
|
//
|
||||||
|
// Copyright 2010 The Go Authors. All rights reserved.
|
||||||
|
// https://github.com/golang/protobuf
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions are
|
||||||
|
// met:
|
||||||
|
//
|
||||||
|
// * Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
// * Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following disclaimer
|
||||||
|
// in the documentation and/or other materials provided with the
|
||||||
|
// distribution.
|
||||||
|
// * Neither the name of Google Inc. nor the names of its
|
||||||
|
// contributors may be used to endorse or promote products derived from
|
||||||
|
// this software without specific prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
/*
|
||||||
|
Package proto converts data structures to and from the wire format of
|
||||||
|
protocol buffers. It works in concert with the Go source code generated
|
||||||
|
for .proto files by the protocol compiler.
|
||||||
|
|
||||||
|
A summary of the properties of the protocol buffer interface
|
||||||
|
for a protocol buffer variable v:
|
||||||
|
|
||||||
|
- Names are turned from camel_case to CamelCase for export.
|
||||||
|
- There are no methods on v to set fields; just treat
|
||||||
|
them as structure fields.
|
||||||
|
- There are getters that return a field's value if set,
|
||||||
|
and return the field's default value if unset.
|
||||||
|
The getters work even if the receiver is a nil message.
|
||||||
|
- The zero value for a struct is its correct initialization state.
|
||||||
|
All desired fields must be set before marshaling.
|
||||||
|
- A Reset() method will restore a protobuf struct to its zero state.
|
||||||
|
- Non-repeated fields are pointers to the values; nil means unset.
|
||||||
|
That is, optional or required field int32 f becomes F *int32.
|
||||||
|
- Repeated fields are slices.
|
||||||
|
- Helper functions are available to aid the setting of fields.
|
||||||
|
msg.Foo = proto.String("hello") // set field
|
||||||
|
- Constants are defined to hold the default values of all fields that
|
||||||
|
have them. They have the form Default_StructName_FieldName.
|
||||||
|
Because the getter methods handle defaulted values,
|
||||||
|
direct use of these constants should be rare.
|
||||||
|
- Enums are given type names and maps from names to values.
|
||||||
|
Enum values are prefixed by the enclosing message's name, or by the
|
||||||
|
enum's type name if it is a top-level enum. Enum types have a String
|
||||||
|
method, and a Enum method to assist in message construction.
|
||||||
|
- Nested messages, groups and enums have type names prefixed with the name of
|
||||||
|
the surrounding message type.
|
||||||
|
- Extensions are given descriptor names that start with E_,
|
||||||
|
followed by an underscore-delimited list of the nested messages
|
||||||
|
that contain it (if any) followed by the CamelCased name of the
|
||||||
|
extension field itself. HasExtension, ClearExtension, GetExtension
|
||||||
|
and SetExtension are functions for manipulating extensions.
|
||||||
|
- Oneof field sets are given a single field in their message,
|
||||||
|
with distinguished wrapper types for each possible field value.
|
||||||
|
- Marshal and Unmarshal are functions to encode and decode the wire format.
|
||||||
|
|
||||||
|
When the .proto file specifies `syntax="proto3"`, there are some differences:
|
||||||
|
|
||||||
|
- Non-repeated fields of non-message type are values instead of pointers.
|
||||||
|
- Getters are only generated for message and oneof fields.
|
||||||
|
- Enum types do not get an Enum method.
|
||||||
|
|
||||||
|
The simplest way to describe this is to see an example.
|
||||||
|
Given file test.proto, containing
|
||||||
|
|
||||||
|
package example;
|
||||||
|
|
||||||
|
enum FOO { X = 17; }
|
||||||
|
|
||||||
|
message Test {
|
||||||
|
required string label = 1;
|
||||||
|
optional int32 type = 2 [default=77];
|
||||||
|
repeated int64 reps = 3;
|
||||||
|
optional group OptionalGroup = 4 {
|
||||||
|
required string RequiredField = 5;
|
||||||
|
}
|
||||||
|
oneof union {
|
||||||
|
int32 number = 6;
|
||||||
|
string name = 7;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
The resulting file, test.pb.go, is:
|
||||||
|
|
||||||
|
package example
|
||||||
|
|
||||||
|
import proto "github.com/gogo/protobuf/proto"
|
||||||
|
import math "math"
|
||||||
|
|
||||||
|
type FOO int32
|
||||||
|
const (
|
||||||
|
FOO_X FOO = 17
|
||||||
|
)
|
||||||
|
var FOO_name = map[int32]string{
|
||||||
|
17: "X",
|
||||||
|
}
|
||||||
|
var FOO_value = map[string]int32{
|
||||||
|
"X": 17,
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x FOO) Enum() *FOO {
|
||||||
|
p := new(FOO)
|
||||||
|
*p = x
|
||||||
|
return p
|
||||||
|
}
|
||||||
|
func (x FOO) String() string {
|
||||||
|
return proto.EnumName(FOO_name, int32(x))
|
||||||
|
}
|
||||||
|
func (x *FOO) UnmarshalJSON(data []byte) error {
|
||||||
|
value, err := proto.UnmarshalJSONEnum(FOO_value, data)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
*x = FOO(value)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type Test struct {
|
||||||
|
Label *string `protobuf:"bytes,1,req,name=label" json:"label,omitempty"`
|
||||||
|
Type *int32 `protobuf:"varint,2,opt,name=type,def=77" json:"type,omitempty"`
|
||||||
|
Reps []int64 `protobuf:"varint,3,rep,name=reps" json:"reps,omitempty"`
|
||||||
|
Optionalgroup *Test_OptionalGroup `protobuf:"group,4,opt,name=OptionalGroup" json:"optionalgroup,omitempty"`
|
||||||
|
// Types that are valid to be assigned to Union:
|
||||||
|
// *Test_Number
|
||||||
|
// *Test_Name
|
||||||
|
Union isTest_Union `protobuf_oneof:"union"`
|
||||||
|
XXX_unrecognized []byte `json:"-"`
|
||||||
|
}
|
||||||
|
func (m *Test) Reset() { *m = Test{} }
|
||||||
|
func (m *Test) String() string { return proto.CompactTextString(m) }
|
||||||
|
func (*Test) ProtoMessage() {}
|
||||||
|
|
||||||
|
type isTest_Union interface {
|
||||||
|
isTest_Union()
|
||||||
|
}
|
||||||
|
|
||||||
|
type Test_Number struct {
|
||||||
|
Number int32 `protobuf:"varint,6,opt,name=number"`
|
||||||
|
}
|
||||||
|
type Test_Name struct {
|
||||||
|
Name string `protobuf:"bytes,7,opt,name=name"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*Test_Number) isTest_Union() {}
|
||||||
|
func (*Test_Name) isTest_Union() {}
|
||||||
|
|
||||||
|
func (m *Test) GetUnion() isTest_Union {
|
||||||
|
if m != nil {
|
||||||
|
return m.Union
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
const Default_Test_Type int32 = 77
|
||||||
|
|
||||||
|
func (m *Test) GetLabel() string {
|
||||||
|
if m != nil && m.Label != nil {
|
||||||
|
return *m.Label
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Test) GetType() int32 {
|
||||||
|
if m != nil && m.Type != nil {
|
||||||
|
return *m.Type
|
||||||
|
}
|
||||||
|
return Default_Test_Type
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Test) GetOptionalgroup() *Test_OptionalGroup {
|
||||||
|
if m != nil {
|
||||||
|
return m.Optionalgroup
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type Test_OptionalGroup struct {
|
||||||
|
RequiredField *string `protobuf:"bytes,5,req" json:"RequiredField,omitempty"`
|
||||||
|
}
|
||||||
|
func (m *Test_OptionalGroup) Reset() { *m = Test_OptionalGroup{} }
|
||||||
|
func (m *Test_OptionalGroup) String() string { return proto.CompactTextString(m) }
|
||||||
|
|
||||||
|
func (m *Test_OptionalGroup) GetRequiredField() string {
|
||||||
|
if m != nil && m.RequiredField != nil {
|
||||||
|
return *m.RequiredField
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Test) GetNumber() int32 {
|
||||||
|
if x, ok := m.GetUnion().(*Test_Number); ok {
|
||||||
|
return x.Number
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Test) GetName() string {
|
||||||
|
if x, ok := m.GetUnion().(*Test_Name); ok {
|
||||||
|
return x.Name
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
proto.RegisterEnum("example.FOO", FOO_name, FOO_value)
|
||||||
|
}
|
||||||
|
|
||||||
|
To create and play with a Test object:
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"log"
|
||||||
|
|
||||||
|
"github.com/gogo/protobuf/proto"
|
||||||
|
pb "./example.pb"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
test := &pb.Test{
|
||||||
|
Label: proto.String("hello"),
|
||||||
|
Type: proto.Int32(17),
|
||||||
|
Reps: []int64{1, 2, 3},
|
||||||
|
Optionalgroup: &pb.Test_OptionalGroup{
|
||||||
|
RequiredField: proto.String("good bye"),
|
||||||
|
},
|
||||||
|
Union: &pb.Test_Name{"fred"},
|
||||||
|
}
|
||||||
|
data, err := proto.Marshal(test)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal("marshaling error: ", err)
|
||||||
|
}
|
||||||
|
newTest := &pb.Test{}
|
||||||
|
err = proto.Unmarshal(data, newTest)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal("unmarshaling error: ", err)
|
||||||
|
}
|
||||||
|
// Now test and newTest contain the same data.
|
||||||
|
if test.GetLabel() != newTest.GetLabel() {
|
||||||
|
log.Fatalf("data mismatch %q != %q", test.GetLabel(), newTest.GetLabel())
|
||||||
|
}
|
||||||
|
// Use a type switch to determine which oneof was set.
|
||||||
|
switch u := test.Union.(type) {
|
||||||
|
case *pb.Test_Number: // u.Number contains the number.
|
||||||
|
case *pb.Test_Name: // u.Name contains the string.
|
||||||
|
}
|
||||||
|
// etc.
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
package proto
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"log"
|
||||||
|
"reflect"
|
||||||
|
"sort"
|
||||||
|
"strconv"
|
||||||
|
"sync"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Message is implemented by generated protocol buffer messages.
|
||||||
|
type Message interface {
|
||||||
|
Reset()
|
||||||
|
String() string
|
||||||
|
ProtoMessage()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Stats records allocation details about the protocol buffer encoders
|
||||||
|
// and decoders. Useful for tuning the library itself.
|
||||||
|
type Stats struct {
|
||||||
|
Emalloc uint64 // mallocs in encode
|
||||||
|
Dmalloc uint64 // mallocs in decode
|
||||||
|
Encode uint64 // number of encodes
|
||||||
|
Decode uint64 // number of decodes
|
||||||
|
Chit uint64 // number of cache hits
|
||||||
|
Cmiss uint64 // number of cache misses
|
||||||
|
Size uint64 // number of sizes
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set to true to enable stats collection.
|
||||||
|
const collectStats = false
|
||||||
|
|
||||||
|
var stats Stats
|
||||||
|
|
||||||
|
// GetStats returns a copy of the global Stats structure.
|
||||||
|
func GetStats() Stats { return stats }
|
||||||
|
|
||||||
|
// A Buffer is a buffer manager for marshaling and unmarshaling
|
||||||
|
// protocol buffers. It may be reused between invocations to
|
||||||
|
// reduce memory usage. It is not necessary to use a Buffer;
|
||||||
|
// the global functions Marshal and Unmarshal create a
|
||||||
|
// temporary Buffer and are fine for most applications.
|
||||||
|
type Buffer struct {
|
||||||
|
buf []byte // encode/decode byte stream
|
||||||
|
index int // write point
|
||||||
|
|
||||||
|
// pools of basic types to amortize allocation.
|
||||||
|
bools []bool
|
||||||
|
uint32s []uint32
|
||||||
|
uint64s []uint64
|
||||||
|
|
||||||
|
// extra pools, only used with pointer_reflect.go
|
||||||
|
int32s []int32
|
||||||
|
int64s []int64
|
||||||
|
float32s []float32
|
||||||
|
float64s []float64
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewBuffer allocates a new Buffer and initializes its internal data to
|
||||||
|
// the contents of the argument slice.
|
||||||
|
func NewBuffer(e []byte) *Buffer {
|
||||||
|
return &Buffer{buf: e}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reset resets the Buffer, ready for marshaling a new protocol buffer.
|
||||||
|
func (p *Buffer) Reset() {
|
||||||
|
p.buf = p.buf[0:0] // for reading/writing
|
||||||
|
p.index = 0 // for reading
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetBuf replaces the internal buffer with the slice,
|
||||||
|
// ready for unmarshaling the contents of the slice.
|
||||||
|
func (p *Buffer) SetBuf(s []byte) {
|
||||||
|
p.buf = s
|
||||||
|
p.index = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
// Bytes returns the contents of the Buffer.
|
||||||
|
func (p *Buffer) Bytes() []byte { return p.buf }
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Helper routines for simplifying the creation of optional fields of basic type.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Bool is a helper routine that allocates a new bool value
|
||||||
|
// to store v and returns a pointer to it.
|
||||||
|
func Bool(v bool) *bool {
|
||||||
|
return &v
|
||||||
|
}
|
||||||
|
|
||||||
|
// Int32 is a helper routine that allocates a new int32 value
|
||||||
|
// to store v and returns a pointer to it.
|
||||||
|
func Int32(v int32) *int32 {
|
||||||
|
return &v
|
||||||
|
}
|
||||||
|
|
||||||
|
// Int is a helper routine that allocates a new int32 value
|
||||||
|
// to store v and returns a pointer to it, but unlike Int32
|
||||||
|
// its argument value is an int.
|
||||||
|
func Int(v int) *int32 {
|
||||||
|
p := new(int32)
|
||||||
|
*p = int32(v)
|
||||||
|
return p
|
||||||
|
}
|
||||||
|
|
||||||
|
// Int64 is a helper routine that allocates a new int64 value
|
||||||
|
// to store v and returns a pointer to it.
|
||||||
|
func Int64(v int64) *int64 {
|
||||||
|
return &v
|
||||||
|
}
|
||||||
|
|
||||||
|
// Float32 is a helper routine that allocates a new float32 value
|
||||||
|
// to store v and returns a pointer to it.
|
||||||
|
func Float32(v float32) *float32 {
|
||||||
|
return &v
|
||||||
|
}
|
||||||
|
|
||||||
|
// Float64 is a helper routine that allocates a new float64 value
|
||||||
|
// to store v and returns a pointer to it.
|
||||||
|
func Float64(v float64) *float64 {
|
||||||
|
return &v
|
||||||
|
}
|
||||||
|
|
||||||
|
// Uint32 is a helper routine that allocates a new uint32 value
|
||||||
|
// to store v and returns a pointer to it.
|
||||||
|
func Uint32(v uint32) *uint32 {
|
||||||
|
return &v
|
||||||
|
}
|
||||||
|
|
||||||
|
// Uint64 is a helper routine that allocates a new uint64 value
|
||||||
|
// to store v and returns a pointer to it.
|
||||||
|
func Uint64(v uint64) *uint64 {
|
||||||
|
return &v
|
||||||
|
}
|
||||||
|
|
||||||
|
// String is a helper routine that allocates a new string value
|
||||||
|
// to store v and returns a pointer to it.
|
||||||
|
func String(v string) *string {
|
||||||
|
return &v
|
||||||
|
}
|
||||||
|
|
||||||
|
// EnumName is a helper function to simplify printing protocol buffer enums
|
||||||
|
// by name. Given an enum map and a value, it returns a useful string.
|
||||||
|
func EnumName(m map[int32]string, v int32) string {
|
||||||
|
s, ok := m[v]
|
||||||
|
if ok {
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
return strconv.Itoa(int(v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalJSONEnum is a helper function to simplify recovering enum int values
|
||||||
|
// from their JSON-encoded representation. Given a map from the enum's symbolic
|
||||||
|
// names to its int values, and a byte buffer containing the JSON-encoded
|
||||||
|
// value, it returns an int32 that can be cast to the enum type by the caller.
|
||||||
|
//
|
||||||
|
// The function can deal with both JSON representations, numeric and symbolic.
|
||||||
|
func UnmarshalJSONEnum(m map[string]int32, data []byte, enumName string) (int32, error) {
|
||||||
|
if data[0] == '"' {
|
||||||
|
// New style: enums are strings.
|
||||||
|
var repr string
|
||||||
|
if err := json.Unmarshal(data, &repr); err != nil {
|
||||||
|
return -1, err
|
||||||
|
}
|
||||||
|
val, ok := m[repr]
|
||||||
|
if !ok {
|
||||||
|
return 0, fmt.Errorf("unrecognized enum %s value %q", enumName, repr)
|
||||||
|
}
|
||||||
|
return val, nil
|
||||||
|
}
|
||||||
|
// Old style: enums are ints.
|
||||||
|
var val int32
|
||||||
|
if err := json.Unmarshal(data, &val); err != nil {
|
||||||
|
return 0, fmt.Errorf("cannot unmarshal %#q into enum %s", data, enumName)
|
||||||
|
}
|
||||||
|
return val, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// DebugPrint dumps the encoded data in b in a debugging format with a header
|
||||||
|
// including the string s. Used in testing but made available for general debugging.
|
||||||
|
func (p *Buffer) DebugPrint(s string, b []byte) {
|
||||||
|
var u uint64
|
||||||
|
|
||||||
|
obuf := p.buf
|
||||||
|
sindex := p.index
|
||||||
|
p.buf = b
|
||||||
|
p.index = 0
|
||||||
|
depth := 0
|
||||||
|
|
||||||
|
fmt.Printf("\n--- %s ---\n", s)
|
||||||
|
|
||||||
|
out:
|
||||||
|
for {
|
||||||
|
for i := 0; i < depth; i++ {
|
||||||
|
fmt.Print(" ")
|
||||||
|
}
|
||||||
|
|
||||||
|
index := p.index
|
||||||
|
if index == len(p.buf) {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
op, err := p.DecodeVarint()
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("%3d: fetching op err %v\n", index, err)
|
||||||
|
break out
|
||||||
|
}
|
||||||
|
tag := op >> 3
|
||||||
|
wire := op & 7
|
||||||
|
|
||||||
|
switch wire {
|
||||||
|
default:
|
||||||
|
fmt.Printf("%3d: t=%3d unknown wire=%d\n",
|
||||||
|
index, tag, wire)
|
||||||
|
break out
|
||||||
|
|
||||||
|
case WireBytes:
|
||||||
|
var r []byte
|
||||||
|
|
||||||
|
r, err = p.DecodeRawBytes(false)
|
||||||
|
if err != nil {
|
||||||
|
break out
|
||||||
|
}
|
||||||
|
fmt.Printf("%3d: t=%3d bytes [%d]", index, tag, len(r))
|
||||||
|
if len(r) <= 6 {
|
||||||
|
for i := 0; i < len(r); i++ {
|
||||||
|
fmt.Printf(" %.2x", r[i])
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for i := 0; i < 3; i++ {
|
||||||
|
fmt.Printf(" %.2x", r[i])
|
||||||
|
}
|
||||||
|
fmt.Printf(" ..")
|
||||||
|
for i := len(r) - 3; i < len(r); i++ {
|
||||||
|
fmt.Printf(" %.2x", r[i])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fmt.Printf("\n")
|
||||||
|
|
||||||
|
case WireFixed32:
|
||||||
|
u, err = p.DecodeFixed32()
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("%3d: t=%3d fix32 err %v\n", index, tag, err)
|
||||||
|
break out
|
||||||
|
}
|
||||||
|
fmt.Printf("%3d: t=%3d fix32 %d\n", index, tag, u)
|
||||||
|
|
||||||
|
case WireFixed64:
|
||||||
|
u, err = p.DecodeFixed64()
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("%3d: t=%3d fix64 err %v\n", index, tag, err)
|
||||||
|
break out
|
||||||
|
}
|
||||||
|
fmt.Printf("%3d: t=%3d fix64 %d\n", index, tag, u)
|
||||||
|
|
||||||
|
case WireVarint:
|
||||||
|
u, err = p.DecodeVarint()
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("%3d: t=%3d varint err %v\n", index, tag, err)
|
||||||
|
break out
|
||||||
|
}
|
||||||
|
fmt.Printf("%3d: t=%3d varint %d\n", index, tag, u)
|
||||||
|
|
||||||
|
case WireStartGroup:
|
||||||
|
fmt.Printf("%3d: t=%3d start\n", index, tag)
|
||||||
|
depth++
|
||||||
|
|
||||||
|
case WireEndGroup:
|
||||||
|
depth--
|
||||||
|
fmt.Printf("%3d: t=%3d end\n", index, tag)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if depth != 0 {
|
||||||
|
fmt.Printf("%3d: start-end not balanced %d\n", p.index, depth)
|
||||||
|
}
|
||||||
|
fmt.Printf("\n")
|
||||||
|
|
||||||
|
p.buf = obuf
|
||||||
|
p.index = sindex
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetDefaults sets unset protocol buffer fields to their default values.
|
||||||
|
// It only modifies fields that are both unset and have defined defaults.
|
||||||
|
// It recursively sets default values in any non-nil sub-messages.
|
||||||
|
func SetDefaults(pb Message) {
|
||||||
|
setDefaults(reflect.ValueOf(pb), true, false)
|
||||||
|
}
|
||||||
|
|
||||||
|
// v is a pointer to a struct.
|
||||||
|
func setDefaults(v reflect.Value, recur, zeros bool) {
|
||||||
|
v = v.Elem()
|
||||||
|
|
||||||
|
defaultMu.RLock()
|
||||||
|
dm, ok := defaults[v.Type()]
|
||||||
|
defaultMu.RUnlock()
|
||||||
|
if !ok {
|
||||||
|
dm = buildDefaultMessage(v.Type())
|
||||||
|
defaultMu.Lock()
|
||||||
|
defaults[v.Type()] = dm
|
||||||
|
defaultMu.Unlock()
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, sf := range dm.scalars {
|
||||||
|
f := v.Field(sf.index)
|
||||||
|
if !f.IsNil() {
|
||||||
|
// field already set
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
dv := sf.value
|
||||||
|
if dv == nil && !zeros {
|
||||||
|
// no explicit default, and don't want to set zeros
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
fptr := f.Addr().Interface() // **T
|
||||||
|
// TODO: Consider batching the allocations we do here.
|
||||||
|
switch sf.kind {
|
||||||
|
case reflect.Bool:
|
||||||
|
b := new(bool)
|
||||||
|
if dv != nil {
|
||||||
|
*b = dv.(bool)
|
||||||
|
}
|
||||||
|
*(fptr.(**bool)) = b
|
||||||
|
case reflect.Float32:
|
||||||
|
f := new(float32)
|
||||||
|
if dv != nil {
|
||||||
|
*f = dv.(float32)
|
||||||
|
}
|
||||||
|
*(fptr.(**float32)) = f
|
||||||
|
case reflect.Float64:
|
||||||
|
f := new(float64)
|
||||||
|
if dv != nil {
|
||||||
|
*f = dv.(float64)
|
||||||
|
}
|
||||||
|
*(fptr.(**float64)) = f
|
||||||
|
case reflect.Int32:
|
||||||
|
// might be an enum
|
||||||
|
if ft := f.Type(); ft != int32PtrType {
|
||||||
|
// enum
|
||||||
|
f.Set(reflect.New(ft.Elem()))
|
||||||
|
if dv != nil {
|
||||||
|
f.Elem().SetInt(int64(dv.(int32)))
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// int32 field
|
||||||
|
i := new(int32)
|
||||||
|
if dv != nil {
|
||||||
|
*i = dv.(int32)
|
||||||
|
}
|
||||||
|
*(fptr.(**int32)) = i
|
||||||
|
}
|
||||||
|
case reflect.Int64:
|
||||||
|
i := new(int64)
|
||||||
|
if dv != nil {
|
||||||
|
*i = dv.(int64)
|
||||||
|
}
|
||||||
|
*(fptr.(**int64)) = i
|
||||||
|
case reflect.String:
|
||||||
|
s := new(string)
|
||||||
|
if dv != nil {
|
||||||
|
*s = dv.(string)
|
||||||
|
}
|
||||||
|
*(fptr.(**string)) = s
|
||||||
|
case reflect.Uint8:
|
||||||
|
// exceptional case: []byte
|
||||||
|
var b []byte
|
||||||
|
if dv != nil {
|
||||||
|
db := dv.([]byte)
|
||||||
|
b = make([]byte, len(db))
|
||||||
|
copy(b, db)
|
||||||
|
} else {
|
||||||
|
b = []byte{}
|
||||||
|
}
|
||||||
|
*(fptr.(*[]byte)) = b
|
||||||
|
case reflect.Uint32:
|
||||||
|
u := new(uint32)
|
||||||
|
if dv != nil {
|
||||||
|
*u = dv.(uint32)
|
||||||
|
}
|
||||||
|
*(fptr.(**uint32)) = u
|
||||||
|
case reflect.Uint64:
|
||||||
|
u := new(uint64)
|
||||||
|
if dv != nil {
|
||||||
|
*u = dv.(uint64)
|
||||||
|
}
|
||||||
|
*(fptr.(**uint64)) = u
|
||||||
|
default:
|
||||||
|
log.Printf("proto: can't set default for field %v (sf.kind=%v)", f, sf.kind)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, ni := range dm.nested {
|
||||||
|
f := v.Field(ni)
|
||||||
|
// f is *T or []*T or map[T]*T
|
||||||
|
switch f.Kind() {
|
||||||
|
case reflect.Ptr:
|
||||||
|
if f.IsNil() {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
setDefaults(f, recur, zeros)
|
||||||
|
|
||||||
|
case reflect.Slice:
|
||||||
|
for i := 0; i < f.Len(); i++ {
|
||||||
|
e := f.Index(i)
|
||||||
|
if e.IsNil() {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
setDefaults(e, recur, zeros)
|
||||||
|
}
|
||||||
|
|
||||||
|
case reflect.Map:
|
||||||
|
for _, k := range f.MapKeys() {
|
||||||
|
e := f.MapIndex(k)
|
||||||
|
if e.IsNil() {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
setDefaults(e, recur, zeros)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
// defaults maps a protocol buffer struct type to a slice of the fields,
|
||||||
|
// with its scalar fields set to their proto-declared non-zero default values.
|
||||||
|
defaultMu sync.RWMutex
|
||||||
|
defaults = make(map[reflect.Type]defaultMessage)
|
||||||
|
|
||||||
|
int32PtrType = reflect.TypeOf((*int32)(nil))
|
||||||
|
)
|
||||||
|
|
||||||
|
// defaultMessage represents information about the default values of a message.
|
||||||
|
type defaultMessage struct {
|
||||||
|
scalars []scalarField
|
||||||
|
nested []int // struct field index of nested messages
|
||||||
|
}
|
||||||
|
|
||||||
|
type scalarField struct {
|
||||||
|
index int // struct field index
|
||||||
|
kind reflect.Kind // element type (the T in *T or []T)
|
||||||
|
value interface{} // the proto-declared default value, or nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// t is a struct type.
|
||||||
|
func buildDefaultMessage(t reflect.Type) (dm defaultMessage) {
|
||||||
|
sprop := GetProperties(t)
|
||||||
|
for _, prop := range sprop.Prop {
|
||||||
|
fi, ok := sprop.decoderTags.get(prop.Tag)
|
||||||
|
if !ok {
|
||||||
|
// XXX_unrecognized
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
ft := t.Field(fi).Type
|
||||||
|
|
||||||
|
sf, nested, err := fieldDefault(ft, prop)
|
||||||
|
switch {
|
||||||
|
case err != nil:
|
||||||
|
log.Print(err)
|
||||||
|
case nested:
|
||||||
|
dm.nested = append(dm.nested, fi)
|
||||||
|
case sf != nil:
|
||||||
|
sf.index = fi
|
||||||
|
dm.scalars = append(dm.scalars, *sf)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return dm
|
||||||
|
}
|
||||||
|
|
||||||
|
// fieldDefault returns the scalarField for field type ft.
|
||||||
|
// sf will be nil if the field can not have a default.
|
||||||
|
// nestedMessage will be true if this is a nested message.
|
||||||
|
// Note that sf.index is not set on return.
|
||||||
|
func fieldDefault(ft reflect.Type, prop *Properties) (sf *scalarField, nestedMessage bool, err error) {
|
||||||
|
var canHaveDefault bool
|
||||||
|
switch ft.Kind() {
|
||||||
|
case reflect.Ptr:
|
||||||
|
if ft.Elem().Kind() == reflect.Struct {
|
||||||
|
nestedMessage = true
|
||||||
|
} else {
|
||||||
|
canHaveDefault = true // proto2 scalar field
|
||||||
|
}
|
||||||
|
|
||||||
|
case reflect.Slice:
|
||||||
|
switch ft.Elem().Kind() {
|
||||||
|
case reflect.Ptr:
|
||||||
|
nestedMessage = true // repeated message
|
||||||
|
case reflect.Uint8:
|
||||||
|
canHaveDefault = true // bytes field
|
||||||
|
}
|
||||||
|
|
||||||
|
case reflect.Map:
|
||||||
|
if ft.Elem().Kind() == reflect.Ptr {
|
||||||
|
nestedMessage = true // map with message values
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if !canHaveDefault {
|
||||||
|
if nestedMessage {
|
||||||
|
return nil, true, nil
|
||||||
|
}
|
||||||
|
return nil, false, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// We now know that ft is a pointer or slice.
|
||||||
|
sf = &scalarField{kind: ft.Elem().Kind()}
|
||||||
|
|
||||||
|
// scalar fields without defaults
|
||||||
|
if !prop.HasDefault {
|
||||||
|
return sf, false, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// a scalar field: either *T or []byte
|
||||||
|
switch ft.Elem().Kind() {
|
||||||
|
case reflect.Bool:
|
||||||
|
x, err := strconv.ParseBool(prop.Default)
|
||||||
|
if err != nil {
|
||||||
|
return nil, false, fmt.Errorf("proto: bad default bool %q: %v", prop.Default, err)
|
||||||
|
}
|
||||||
|
sf.value = x
|
||||||
|
case reflect.Float32:
|
||||||
|
x, err := strconv.ParseFloat(prop.Default, 32)
|
||||||
|
if err != nil {
|
||||||
|
return nil, false, fmt.Errorf("proto: bad default float32 %q: %v", prop.Default, err)
|
||||||
|
}
|
||||||
|
sf.value = float32(x)
|
||||||
|
case reflect.Float64:
|
||||||
|
x, err := strconv.ParseFloat(prop.Default, 64)
|
||||||
|
if err != nil {
|
||||||
|
return nil, false, fmt.Errorf("proto: bad default float64 %q: %v", prop.Default, err)
|
||||||
|
}
|
||||||
|
sf.value = x
|
||||||
|
case reflect.Int32:
|
||||||
|
x, err := strconv.ParseInt(prop.Default, 10, 32)
|
||||||
|
if err != nil {
|
||||||
|
return nil, false, fmt.Errorf("proto: bad default int32 %q: %v", prop.Default, err)
|
||||||
|
}
|
||||||
|
sf.value = int32(x)
|
||||||
|
case reflect.Int64:
|
||||||
|
x, err := strconv.ParseInt(prop.Default, 10, 64)
|
||||||
|
if err != nil {
|
||||||
|
return nil, false, fmt.Errorf("proto: bad default int64 %q: %v", prop.Default, err)
|
||||||
|
}
|
||||||
|
sf.value = x
|
||||||
|
case reflect.String:
|
||||||
|
sf.value = prop.Default
|
||||||
|
case reflect.Uint8:
|
||||||
|
// []byte (not *uint8)
|
||||||
|
sf.value = []byte(prop.Default)
|
||||||
|
case reflect.Uint32:
|
||||||
|
x, err := strconv.ParseUint(prop.Default, 10, 32)
|
||||||
|
if err != nil {
|
||||||
|
return nil, false, fmt.Errorf("proto: bad default uint32 %q: %v", prop.Default, err)
|
||||||
|
}
|
||||||
|
sf.value = uint32(x)
|
||||||
|
case reflect.Uint64:
|
||||||
|
x, err := strconv.ParseUint(prop.Default, 10, 64)
|
||||||
|
if err != nil {
|
||||||
|
return nil, false, fmt.Errorf("proto: bad default uint64 %q: %v", prop.Default, err)
|
||||||
|
}
|
||||||
|
sf.value = x
|
||||||
|
default:
|
||||||
|
return nil, false, fmt.Errorf("proto: unhandled def kind %v", ft.Elem().Kind())
|
||||||
|
}
|
||||||
|
|
||||||
|
return sf, false, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Map fields may have key types of non-float scalars, strings and enums.
|
||||||
|
// The easiest way to sort them in some deterministic order is to use fmt.
|
||||||
|
// If this turns out to be inefficient we can always consider other options,
|
||||||
|
// such as doing a Schwartzian transform.
|
||||||
|
|
||||||
|
func mapKeys(vs []reflect.Value) sort.Interface {
|
||||||
|
s := mapKeySorter{
|
||||||
|
vs: vs,
|
||||||
|
// default Less function: textual comparison
|
||||||
|
less: func(a, b reflect.Value) bool {
|
||||||
|
return fmt.Sprint(a.Interface()) < fmt.Sprint(b.Interface())
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
// Type specialization per https://developers.google.com/protocol-buffers/docs/proto#maps;
|
||||||
|
// numeric keys are sorted numerically.
|
||||||
|
if len(vs) == 0 {
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
switch vs[0].Kind() {
|
||||||
|
case reflect.Int32, reflect.Int64:
|
||||||
|
s.less = func(a, b reflect.Value) bool { return a.Int() < b.Int() }
|
||||||
|
case reflect.Uint32, reflect.Uint64:
|
||||||
|
s.less = func(a, b reflect.Value) bool { return a.Uint() < b.Uint() }
|
||||||
|
}
|
||||||
|
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
|
||||||
|
type mapKeySorter struct {
|
||||||
|
vs []reflect.Value
|
||||||
|
less func(a, b reflect.Value) bool
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s mapKeySorter) Len() int { return len(s.vs) }
|
||||||
|
func (s mapKeySorter) Swap(i, j int) { s.vs[i], s.vs[j] = s.vs[j], s.vs[i] }
|
||||||
|
func (s mapKeySorter) Less(i, j int) bool {
|
||||||
|
return s.less(s.vs[i], s.vs[j])
|
||||||
|
}
|
||||||
|
|
||||||
|
// isProto3Zero reports whether v is a zero proto3 value.
|
||||||
|
func isProto3Zero(v reflect.Value) bool {
|
||||||
|
switch v.Kind() {
|
||||||
|
case reflect.Bool:
|
||||||
|
return !v.Bool()
|
||||||
|
case reflect.Int32, reflect.Int64:
|
||||||
|
return v.Int() == 0
|
||||||
|
case reflect.Uint32, reflect.Uint64:
|
||||||
|
return v.Uint() == 0
|
||||||
|
case reflect.Float32, reflect.Float64:
|
||||||
|
return v.Float() == 0
|
||||||
|
case reflect.String:
|
||||||
|
return v.String() == ""
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// ProtoPackageIsVersion1 is referenced from generated protocol buffer files
|
||||||
|
// to assert that that code is compatible with this version of the proto package.
|
||||||
|
const GoGoProtoPackageIsVersion1 = true
|
||||||
40
staging/src/k8s.io/client-go/1.4/_vendor/github.com/gogo/protobuf/proto/lib_gogo.go
generated
Normal file
40
staging/src/k8s.io/client-go/1.4/_vendor/github.com/gogo/protobuf/proto/lib_gogo.go
generated
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
// Copyright (c) 2013, Vastech SA (PTY) LTD. All rights reserved.
|
||||||
|
// http://github.com/gogo/protobuf/gogoproto
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions are
|
||||||
|
// met:
|
||||||
|
//
|
||||||
|
// * Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
// * Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following disclaimer
|
||||||
|
// in the documentation and/or other materials provided with the
|
||||||
|
// distribution.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
package proto
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"strconv"
|
||||||
|
)
|
||||||
|
|
||||||
|
func MarshalJSONEnum(m map[int32]string, value int32) ([]byte, error) {
|
||||||
|
s, ok := m[value]
|
||||||
|
if !ok {
|
||||||
|
s = strconv.Itoa(int(value))
|
||||||
|
}
|
||||||
|
return json.Marshal(s)
|
||||||
|
}
|
||||||
280
staging/src/k8s.io/client-go/1.4/_vendor/github.com/gogo/protobuf/proto/message_set.go
generated
Normal file
280
staging/src/k8s.io/client-go/1.4/_vendor/github.com/gogo/protobuf/proto/message_set.go
generated
Normal file
@@ -0,0 +1,280 @@
|
|||||||
|
// Go support for Protocol Buffers - Google's data interchange format
|
||||||
|
//
|
||||||
|
// Copyright 2010 The Go Authors. All rights reserved.
|
||||||
|
// https://github.com/golang/protobuf
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions are
|
||||||
|
// met:
|
||||||
|
//
|
||||||
|
// * Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
// * Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following disclaimer
|
||||||
|
// in the documentation and/or other materials provided with the
|
||||||
|
// distribution.
|
||||||
|
// * Neither the name of Google Inc. nor the names of its
|
||||||
|
// contributors may be used to endorse or promote products derived from
|
||||||
|
// this software without specific prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
package proto
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Support for message sets.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"reflect"
|
||||||
|
"sort"
|
||||||
|
)
|
||||||
|
|
||||||
|
// errNoMessageTypeID occurs when a protocol buffer does not have a message type ID.
|
||||||
|
// A message type ID is required for storing a protocol buffer in a message set.
|
||||||
|
var errNoMessageTypeID = errors.New("proto does not have a message type ID")
|
||||||
|
|
||||||
|
// The first two types (_MessageSet_Item and messageSet)
|
||||||
|
// model what the protocol compiler produces for the following protocol message:
|
||||||
|
// message MessageSet {
|
||||||
|
// repeated group Item = 1 {
|
||||||
|
// required int32 type_id = 2;
|
||||||
|
// required string message = 3;
|
||||||
|
// };
|
||||||
|
// }
|
||||||
|
// That is the MessageSet wire format. We can't use a proto to generate these
|
||||||
|
// because that would introduce a circular dependency between it and this package.
|
||||||
|
|
||||||
|
type _MessageSet_Item struct {
|
||||||
|
TypeId *int32 `protobuf:"varint,2,req,name=type_id"`
|
||||||
|
Message []byte `protobuf:"bytes,3,req,name=message"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type messageSet struct {
|
||||||
|
Item []*_MessageSet_Item `protobuf:"group,1,rep"`
|
||||||
|
XXX_unrecognized []byte
|
||||||
|
// TODO: caching?
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make sure messageSet is a Message.
|
||||||
|
var _ Message = (*messageSet)(nil)
|
||||||
|
|
||||||
|
// messageTypeIder is an interface satisfied by a protocol buffer type
|
||||||
|
// that may be stored in a MessageSet.
|
||||||
|
type messageTypeIder interface {
|
||||||
|
MessageTypeId() int32
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ms *messageSet) find(pb Message) *_MessageSet_Item {
|
||||||
|
mti, ok := pb.(messageTypeIder)
|
||||||
|
if !ok {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
id := mti.MessageTypeId()
|
||||||
|
for _, item := range ms.Item {
|
||||||
|
if *item.TypeId == id {
|
||||||
|
return item
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ms *messageSet) Has(pb Message) bool {
|
||||||
|
if ms.find(pb) != nil {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ms *messageSet) Unmarshal(pb Message) error {
|
||||||
|
if item := ms.find(pb); item != nil {
|
||||||
|
return Unmarshal(item.Message, pb)
|
||||||
|
}
|
||||||
|
if _, ok := pb.(messageTypeIder); !ok {
|
||||||
|
return errNoMessageTypeID
|
||||||
|
}
|
||||||
|
return nil // TODO: return error instead?
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ms *messageSet) Marshal(pb Message) error {
|
||||||
|
msg, err := Marshal(pb)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if item := ms.find(pb); item != nil {
|
||||||
|
// reuse existing item
|
||||||
|
item.Message = msg
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
mti, ok := pb.(messageTypeIder)
|
||||||
|
if !ok {
|
||||||
|
return errNoMessageTypeID
|
||||||
|
}
|
||||||
|
|
||||||
|
mtid := mti.MessageTypeId()
|
||||||
|
ms.Item = append(ms.Item, &_MessageSet_Item{
|
||||||
|
TypeId: &mtid,
|
||||||
|
Message: msg,
|
||||||
|
})
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ms *messageSet) Reset() { *ms = messageSet{} }
|
||||||
|
func (ms *messageSet) String() string { return CompactTextString(ms) }
|
||||||
|
func (*messageSet) ProtoMessage() {}
|
||||||
|
|
||||||
|
// Support for the message_set_wire_format message option.
|
||||||
|
|
||||||
|
func skipVarint(buf []byte) []byte {
|
||||||
|
i := 0
|
||||||
|
for ; buf[i]&0x80 != 0; i++ {
|
||||||
|
}
|
||||||
|
return buf[i+1:]
|
||||||
|
}
|
||||||
|
|
||||||
|
// MarshalMessageSet encodes the extension map represented by m in the message set wire format.
|
||||||
|
// It is called by generated Marshal methods on protocol buffer messages with the message_set_wire_format option.
|
||||||
|
func MarshalMessageSet(m map[int32]Extension) ([]byte, error) {
|
||||||
|
if err := encodeExtensionMap(m); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sort extension IDs to provide a deterministic encoding.
|
||||||
|
// See also enc_map in encode.go.
|
||||||
|
ids := make([]int, 0, len(m))
|
||||||
|
for id := range m {
|
||||||
|
ids = append(ids, int(id))
|
||||||
|
}
|
||||||
|
sort.Ints(ids)
|
||||||
|
|
||||||
|
ms := &messageSet{Item: make([]*_MessageSet_Item, 0, len(m))}
|
||||||
|
for _, id := range ids {
|
||||||
|
e := m[int32(id)]
|
||||||
|
// Remove the wire type and field number varint, as well as the length varint.
|
||||||
|
msg := skipVarint(skipVarint(e.enc))
|
||||||
|
|
||||||
|
ms.Item = append(ms.Item, &_MessageSet_Item{
|
||||||
|
TypeId: Int32(int32(id)),
|
||||||
|
Message: msg,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return Marshal(ms)
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalMessageSet decodes the extension map encoded in buf in the message set wire format.
|
||||||
|
// It is called by generated Unmarshal methods on protocol buffer messages with the message_set_wire_format option.
|
||||||
|
func UnmarshalMessageSet(buf []byte, m map[int32]Extension) error {
|
||||||
|
ms := new(messageSet)
|
||||||
|
if err := Unmarshal(buf, ms); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
for _, item := range ms.Item {
|
||||||
|
id := *item.TypeId
|
||||||
|
msg := item.Message
|
||||||
|
|
||||||
|
// Restore wire type and field number varint, plus length varint.
|
||||||
|
// Be careful to preserve duplicate items.
|
||||||
|
b := EncodeVarint(uint64(id)<<3 | WireBytes)
|
||||||
|
if ext, ok := m[id]; ok {
|
||||||
|
// Existing data; rip off the tag and length varint
|
||||||
|
// so we join the new data correctly.
|
||||||
|
// We can assume that ext.enc is set because we are unmarshaling.
|
||||||
|
o := ext.enc[len(b):] // skip wire type and field number
|
||||||
|
_, n := DecodeVarint(o) // calculate length of length varint
|
||||||
|
o = o[n:] // skip length varint
|
||||||
|
msg = append(o, msg...) // join old data and new data
|
||||||
|
}
|
||||||
|
b = append(b, EncodeVarint(uint64(len(msg)))...)
|
||||||
|
b = append(b, msg...)
|
||||||
|
|
||||||
|
m[id] = Extension{enc: b}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// MarshalMessageSetJSON encodes the extension map represented by m in JSON format.
|
||||||
|
// It is called by generated MarshalJSON methods on protocol buffer messages with the message_set_wire_format option.
|
||||||
|
func MarshalMessageSetJSON(m map[int32]Extension) ([]byte, error) {
|
||||||
|
var b bytes.Buffer
|
||||||
|
b.WriteByte('{')
|
||||||
|
|
||||||
|
// Process the map in key order for deterministic output.
|
||||||
|
ids := make([]int32, 0, len(m))
|
||||||
|
for id := range m {
|
||||||
|
ids = append(ids, id)
|
||||||
|
}
|
||||||
|
sort.Sort(int32Slice(ids)) // int32Slice defined in text.go
|
||||||
|
|
||||||
|
for i, id := range ids {
|
||||||
|
ext := m[id]
|
||||||
|
if i > 0 {
|
||||||
|
b.WriteByte(',')
|
||||||
|
}
|
||||||
|
|
||||||
|
msd, ok := messageSetMap[id]
|
||||||
|
if !ok {
|
||||||
|
// Unknown type; we can't render it, so skip it.
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
fmt.Fprintf(&b, `"[%s]":`, msd.name)
|
||||||
|
|
||||||
|
x := ext.value
|
||||||
|
if x == nil {
|
||||||
|
x = reflect.New(msd.t.Elem()).Interface()
|
||||||
|
if err := Unmarshal(ext.enc, x.(Message)); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
d, err := json.Marshal(x)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
b.Write(d)
|
||||||
|
}
|
||||||
|
b.WriteByte('}')
|
||||||
|
return b.Bytes(), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalMessageSetJSON decodes the extension map encoded in buf in JSON format.
|
||||||
|
// It is called by generated UnmarshalJSON methods on protocol buffer messages with the message_set_wire_format option.
|
||||||
|
func UnmarshalMessageSetJSON(buf []byte, m map[int32]Extension) error {
|
||||||
|
// Common-case fast path.
|
||||||
|
if len(buf) == 0 || bytes.Equal(buf, []byte("{}")) {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// This is fairly tricky, and it's not clear that it is needed.
|
||||||
|
return errors.New("TODO: UnmarshalMessageSetJSON not yet implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
// A global registry of types that can be used in a MessageSet.
|
||||||
|
|
||||||
|
var messageSetMap = make(map[int32]messageSetDesc)
|
||||||
|
|
||||||
|
type messageSetDesc struct {
|
||||||
|
t reflect.Type // pointer to struct
|
||||||
|
name string
|
||||||
|
}
|
||||||
|
|
||||||
|
// RegisterMessageSetType is called from the generated code.
|
||||||
|
func RegisterMessageSetType(m Message, fieldNum int32, name string) {
|
||||||
|
messageSetMap[fieldNum] = messageSetDesc{
|
||||||
|
t: reflect.TypeOf(m),
|
||||||
|
name: name,
|
||||||
|
}
|
||||||
|
}
|
||||||
479
staging/src/k8s.io/client-go/1.4/_vendor/github.com/gogo/protobuf/proto/pointer_reflect.go
generated
Normal file
479
staging/src/k8s.io/client-go/1.4/_vendor/github.com/gogo/protobuf/proto/pointer_reflect.go
generated
Normal file
@@ -0,0 +1,479 @@
|
|||||||
|
// Go support for Protocol Buffers - Google's data interchange format
|
||||||
|
//
|
||||||
|
// Copyright 2012 The Go Authors. All rights reserved.
|
||||||
|
// https://github.com/golang/protobuf
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions are
|
||||||
|
// met:
|
||||||
|
//
|
||||||
|
// * Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
// * Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following disclaimer
|
||||||
|
// in the documentation and/or other materials provided with the
|
||||||
|
// distribution.
|
||||||
|
// * Neither the name of Google Inc. nor the names of its
|
||||||
|
// contributors may be used to endorse or promote products derived from
|
||||||
|
// this software without specific prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
// +build appengine
|
||||||
|
|
||||||
|
// This file contains an implementation of proto field accesses using package reflect.
|
||||||
|
// It is slower than the code in pointer_unsafe.go but it avoids package unsafe and can
|
||||||
|
// be used on App Engine.
|
||||||
|
|
||||||
|
package proto
|
||||||
|
|
||||||
|
import (
|
||||||
|
"math"
|
||||||
|
"reflect"
|
||||||
|
)
|
||||||
|
|
||||||
|
// A structPointer is a pointer to a struct.
|
||||||
|
type structPointer struct {
|
||||||
|
v reflect.Value
|
||||||
|
}
|
||||||
|
|
||||||
|
// toStructPointer returns a structPointer equivalent to the given reflect value.
|
||||||
|
// The reflect value must itself be a pointer to a struct.
|
||||||
|
func toStructPointer(v reflect.Value) structPointer {
|
||||||
|
return structPointer{v}
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsNil reports whether p is nil.
|
||||||
|
func structPointer_IsNil(p structPointer) bool {
|
||||||
|
return p.v.IsNil()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Interface returns the struct pointer as an interface value.
|
||||||
|
func structPointer_Interface(p structPointer, _ reflect.Type) interface{} {
|
||||||
|
return p.v.Interface()
|
||||||
|
}
|
||||||
|
|
||||||
|
// A field identifies a field in a struct, accessible from a structPointer.
|
||||||
|
// In this implementation, a field is identified by the sequence of field indices
|
||||||
|
// passed to reflect's FieldByIndex.
|
||||||
|
type field []int
|
||||||
|
|
||||||
|
// toField returns a field equivalent to the given reflect field.
|
||||||
|
func toField(f *reflect.StructField) field {
|
||||||
|
return f.Index
|
||||||
|
}
|
||||||
|
|
||||||
|
// invalidField is an invalid field identifier.
|
||||||
|
var invalidField = field(nil)
|
||||||
|
|
||||||
|
// IsValid reports whether the field identifier is valid.
|
||||||
|
func (f field) IsValid() bool { return f != nil }
|
||||||
|
|
||||||
|
// field returns the given field in the struct as a reflect value.
|
||||||
|
func structPointer_field(p structPointer, f field) reflect.Value {
|
||||||
|
// Special case: an extension map entry with a value of type T
|
||||||
|
// passes a *T to the struct-handling code with a zero field,
|
||||||
|
// expecting that it will be treated as equivalent to *struct{ X T },
|
||||||
|
// which has the same memory layout. We have to handle that case
|
||||||
|
// specially, because reflect will panic if we call FieldByIndex on a
|
||||||
|
// non-struct.
|
||||||
|
if f == nil {
|
||||||
|
return p.v.Elem()
|
||||||
|
}
|
||||||
|
|
||||||
|
return p.v.Elem().FieldByIndex(f)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ifield returns the given field in the struct as an interface value.
|
||||||
|
func structPointer_ifield(p structPointer, f field) interface{} {
|
||||||
|
return structPointer_field(p, f).Addr().Interface()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Bytes returns the address of a []byte field in the struct.
|
||||||
|
func structPointer_Bytes(p structPointer, f field) *[]byte {
|
||||||
|
return structPointer_ifield(p, f).(*[]byte)
|
||||||
|
}
|
||||||
|
|
||||||
|
// BytesSlice returns the address of a [][]byte field in the struct.
|
||||||
|
func structPointer_BytesSlice(p structPointer, f field) *[][]byte {
|
||||||
|
return structPointer_ifield(p, f).(*[][]byte)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Bool returns the address of a *bool field in the struct.
|
||||||
|
func structPointer_Bool(p structPointer, f field) **bool {
|
||||||
|
return structPointer_ifield(p, f).(**bool)
|
||||||
|
}
|
||||||
|
|
||||||
|
// BoolVal returns the address of a bool field in the struct.
|
||||||
|
func structPointer_BoolVal(p structPointer, f field) *bool {
|
||||||
|
return structPointer_ifield(p, f).(*bool)
|
||||||
|
}
|
||||||
|
|
||||||
|
// BoolSlice returns the address of a []bool field in the struct.
|
||||||
|
func structPointer_BoolSlice(p structPointer, f field) *[]bool {
|
||||||
|
return structPointer_ifield(p, f).(*[]bool)
|
||||||
|
}
|
||||||
|
|
||||||
|
// String returns the address of a *string field in the struct.
|
||||||
|
func structPointer_String(p structPointer, f field) **string {
|
||||||
|
return structPointer_ifield(p, f).(**string)
|
||||||
|
}
|
||||||
|
|
||||||
|
// StringVal returns the address of a string field in the struct.
|
||||||
|
func structPointer_StringVal(p structPointer, f field) *string {
|
||||||
|
return structPointer_ifield(p, f).(*string)
|
||||||
|
}
|
||||||
|
|
||||||
|
// StringSlice returns the address of a []string field in the struct.
|
||||||
|
func structPointer_StringSlice(p structPointer, f field) *[]string {
|
||||||
|
return structPointer_ifield(p, f).(*[]string)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ExtMap returns the address of an extension map field in the struct.
|
||||||
|
func structPointer_ExtMap(p structPointer, f field) *map[int32]Extension {
|
||||||
|
return structPointer_ifield(p, f).(*map[int32]Extension)
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewAt returns the reflect.Value for a pointer to a field in the struct.
|
||||||
|
func structPointer_NewAt(p structPointer, f field, typ reflect.Type) reflect.Value {
|
||||||
|
return structPointer_field(p, f).Addr()
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetStructPointer writes a *struct field in the struct.
|
||||||
|
func structPointer_SetStructPointer(p structPointer, f field, q structPointer) {
|
||||||
|
structPointer_field(p, f).Set(q.v)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetStructPointer reads a *struct field in the struct.
|
||||||
|
func structPointer_GetStructPointer(p structPointer, f field) structPointer {
|
||||||
|
return structPointer{structPointer_field(p, f)}
|
||||||
|
}
|
||||||
|
|
||||||
|
// StructPointerSlice the address of a []*struct field in the struct.
|
||||||
|
func structPointer_StructPointerSlice(p structPointer, f field) structPointerSlice {
|
||||||
|
return structPointerSlice{structPointer_field(p, f)}
|
||||||
|
}
|
||||||
|
|
||||||
|
// A structPointerSlice represents the address of a slice of pointers to structs
|
||||||
|
// (themselves messages or groups). That is, v.Type() is *[]*struct{...}.
|
||||||
|
type structPointerSlice struct {
|
||||||
|
v reflect.Value
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p structPointerSlice) Len() int { return p.v.Len() }
|
||||||
|
func (p structPointerSlice) Index(i int) structPointer { return structPointer{p.v.Index(i)} }
|
||||||
|
func (p structPointerSlice) Append(q structPointer) {
|
||||||
|
p.v.Set(reflect.Append(p.v, q.v))
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
int32Type = reflect.TypeOf(int32(0))
|
||||||
|
uint32Type = reflect.TypeOf(uint32(0))
|
||||||
|
float32Type = reflect.TypeOf(float32(0))
|
||||||
|
int64Type = reflect.TypeOf(int64(0))
|
||||||
|
uint64Type = reflect.TypeOf(uint64(0))
|
||||||
|
float64Type = reflect.TypeOf(float64(0))
|
||||||
|
)
|
||||||
|
|
||||||
|
// A word32 represents a field of type *int32, *uint32, *float32, or *enum.
|
||||||
|
// That is, v.Type() is *int32, *uint32, *float32, or *enum and v is assignable.
|
||||||
|
type word32 struct {
|
||||||
|
v reflect.Value
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsNil reports whether p is nil.
|
||||||
|
func word32_IsNil(p word32) bool {
|
||||||
|
return p.v.IsNil()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set sets p to point at a newly allocated word with bits set to x.
|
||||||
|
func word32_Set(p word32, o *Buffer, x uint32) {
|
||||||
|
t := p.v.Type().Elem()
|
||||||
|
switch t {
|
||||||
|
case int32Type:
|
||||||
|
if len(o.int32s) == 0 {
|
||||||
|
o.int32s = make([]int32, uint32PoolSize)
|
||||||
|
}
|
||||||
|
o.int32s[0] = int32(x)
|
||||||
|
p.v.Set(reflect.ValueOf(&o.int32s[0]))
|
||||||
|
o.int32s = o.int32s[1:]
|
||||||
|
return
|
||||||
|
case uint32Type:
|
||||||
|
if len(o.uint32s) == 0 {
|
||||||
|
o.uint32s = make([]uint32, uint32PoolSize)
|
||||||
|
}
|
||||||
|
o.uint32s[0] = x
|
||||||
|
p.v.Set(reflect.ValueOf(&o.uint32s[0]))
|
||||||
|
o.uint32s = o.uint32s[1:]
|
||||||
|
return
|
||||||
|
case float32Type:
|
||||||
|
if len(o.float32s) == 0 {
|
||||||
|
o.float32s = make([]float32, uint32PoolSize)
|
||||||
|
}
|
||||||
|
o.float32s[0] = math.Float32frombits(x)
|
||||||
|
p.v.Set(reflect.ValueOf(&o.float32s[0]))
|
||||||
|
o.float32s = o.float32s[1:]
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// must be enum
|
||||||
|
p.v.Set(reflect.New(t))
|
||||||
|
p.v.Elem().SetInt(int64(int32(x)))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get gets the bits pointed at by p, as a uint32.
|
||||||
|
func word32_Get(p word32) uint32 {
|
||||||
|
elem := p.v.Elem()
|
||||||
|
switch elem.Kind() {
|
||||||
|
case reflect.Int32:
|
||||||
|
return uint32(elem.Int())
|
||||||
|
case reflect.Uint32:
|
||||||
|
return uint32(elem.Uint())
|
||||||
|
case reflect.Float32:
|
||||||
|
return math.Float32bits(float32(elem.Float()))
|
||||||
|
}
|
||||||
|
panic("unreachable")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Word32 returns a reference to a *int32, *uint32, *float32, or *enum field in the struct.
|
||||||
|
func structPointer_Word32(p structPointer, f field) word32 {
|
||||||
|
return word32{structPointer_field(p, f)}
|
||||||
|
}
|
||||||
|
|
||||||
|
// A word32Val represents a field of type int32, uint32, float32, or enum.
|
||||||
|
// That is, v.Type() is int32, uint32, float32, or enum and v is assignable.
|
||||||
|
type word32Val struct {
|
||||||
|
v reflect.Value
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set sets *p to x.
|
||||||
|
func word32Val_Set(p word32Val, x uint32) {
|
||||||
|
switch p.v.Type() {
|
||||||
|
case int32Type:
|
||||||
|
p.v.SetInt(int64(x))
|
||||||
|
return
|
||||||
|
case uint32Type:
|
||||||
|
p.v.SetUint(uint64(x))
|
||||||
|
return
|
||||||
|
case float32Type:
|
||||||
|
p.v.SetFloat(float64(math.Float32frombits(x)))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// must be enum
|
||||||
|
p.v.SetInt(int64(int32(x)))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get gets the bits pointed at by p, as a uint32.
|
||||||
|
func word32Val_Get(p word32Val) uint32 {
|
||||||
|
elem := p.v
|
||||||
|
switch elem.Kind() {
|
||||||
|
case reflect.Int32:
|
||||||
|
return uint32(elem.Int())
|
||||||
|
case reflect.Uint32:
|
||||||
|
return uint32(elem.Uint())
|
||||||
|
case reflect.Float32:
|
||||||
|
return math.Float32bits(float32(elem.Float()))
|
||||||
|
}
|
||||||
|
panic("unreachable")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Word32Val returns a reference to a int32, uint32, float32, or enum field in the struct.
|
||||||
|
func structPointer_Word32Val(p structPointer, f field) word32Val {
|
||||||
|
return word32Val{structPointer_field(p, f)}
|
||||||
|
}
|
||||||
|
|
||||||
|
// A word32Slice is a slice of 32-bit values.
|
||||||
|
// That is, v.Type() is []int32, []uint32, []float32, or []enum.
|
||||||
|
type word32Slice struct {
|
||||||
|
v reflect.Value
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p word32Slice) Append(x uint32) {
|
||||||
|
n, m := p.v.Len(), p.v.Cap()
|
||||||
|
if n < m {
|
||||||
|
p.v.SetLen(n + 1)
|
||||||
|
} else {
|
||||||
|
t := p.v.Type().Elem()
|
||||||
|
p.v.Set(reflect.Append(p.v, reflect.Zero(t)))
|
||||||
|
}
|
||||||
|
elem := p.v.Index(n)
|
||||||
|
switch elem.Kind() {
|
||||||
|
case reflect.Int32:
|
||||||
|
elem.SetInt(int64(int32(x)))
|
||||||
|
case reflect.Uint32:
|
||||||
|
elem.SetUint(uint64(x))
|
||||||
|
case reflect.Float32:
|
||||||
|
elem.SetFloat(float64(math.Float32frombits(x)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p word32Slice) Len() int {
|
||||||
|
return p.v.Len()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p word32Slice) Index(i int) uint32 {
|
||||||
|
elem := p.v.Index(i)
|
||||||
|
switch elem.Kind() {
|
||||||
|
case reflect.Int32:
|
||||||
|
return uint32(elem.Int())
|
||||||
|
case reflect.Uint32:
|
||||||
|
return uint32(elem.Uint())
|
||||||
|
case reflect.Float32:
|
||||||
|
return math.Float32bits(float32(elem.Float()))
|
||||||
|
}
|
||||||
|
panic("unreachable")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Word32Slice returns a reference to a []int32, []uint32, []float32, or []enum field in the struct.
|
||||||
|
func structPointer_Word32Slice(p structPointer, f field) word32Slice {
|
||||||
|
return word32Slice{structPointer_field(p, f)}
|
||||||
|
}
|
||||||
|
|
||||||
|
// word64 is like word32 but for 64-bit values.
|
||||||
|
type word64 struct {
|
||||||
|
v reflect.Value
|
||||||
|
}
|
||||||
|
|
||||||
|
func word64_Set(p word64, o *Buffer, x uint64) {
|
||||||
|
t := p.v.Type().Elem()
|
||||||
|
switch t {
|
||||||
|
case int64Type:
|
||||||
|
if len(o.int64s) == 0 {
|
||||||
|
o.int64s = make([]int64, uint64PoolSize)
|
||||||
|
}
|
||||||
|
o.int64s[0] = int64(x)
|
||||||
|
p.v.Set(reflect.ValueOf(&o.int64s[0]))
|
||||||
|
o.int64s = o.int64s[1:]
|
||||||
|
return
|
||||||
|
case uint64Type:
|
||||||
|
if len(o.uint64s) == 0 {
|
||||||
|
o.uint64s = make([]uint64, uint64PoolSize)
|
||||||
|
}
|
||||||
|
o.uint64s[0] = x
|
||||||
|
p.v.Set(reflect.ValueOf(&o.uint64s[0]))
|
||||||
|
o.uint64s = o.uint64s[1:]
|
||||||
|
return
|
||||||
|
case float64Type:
|
||||||
|
if len(o.float64s) == 0 {
|
||||||
|
o.float64s = make([]float64, uint64PoolSize)
|
||||||
|
}
|
||||||
|
o.float64s[0] = math.Float64frombits(x)
|
||||||
|
p.v.Set(reflect.ValueOf(&o.float64s[0]))
|
||||||
|
o.float64s = o.float64s[1:]
|
||||||
|
return
|
||||||
|
}
|
||||||
|
panic("unreachable")
|
||||||
|
}
|
||||||
|
|
||||||
|
func word64_IsNil(p word64) bool {
|
||||||
|
return p.v.IsNil()
|
||||||
|
}
|
||||||
|
|
||||||
|
func word64_Get(p word64) uint64 {
|
||||||
|
elem := p.v.Elem()
|
||||||
|
switch elem.Kind() {
|
||||||
|
case reflect.Int64:
|
||||||
|
return uint64(elem.Int())
|
||||||
|
case reflect.Uint64:
|
||||||
|
return elem.Uint()
|
||||||
|
case reflect.Float64:
|
||||||
|
return math.Float64bits(elem.Float())
|
||||||
|
}
|
||||||
|
panic("unreachable")
|
||||||
|
}
|
||||||
|
|
||||||
|
func structPointer_Word64(p structPointer, f field) word64 {
|
||||||
|
return word64{structPointer_field(p, f)}
|
||||||
|
}
|
||||||
|
|
||||||
|
// word64Val is like word32Val but for 64-bit values.
|
||||||
|
type word64Val struct {
|
||||||
|
v reflect.Value
|
||||||
|
}
|
||||||
|
|
||||||
|
func word64Val_Set(p word64Val, o *Buffer, x uint64) {
|
||||||
|
switch p.v.Type() {
|
||||||
|
case int64Type:
|
||||||
|
p.v.SetInt(int64(x))
|
||||||
|
return
|
||||||
|
case uint64Type:
|
||||||
|
p.v.SetUint(x)
|
||||||
|
return
|
||||||
|
case float64Type:
|
||||||
|
p.v.SetFloat(math.Float64frombits(x))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
panic("unreachable")
|
||||||
|
}
|
||||||
|
|
||||||
|
func word64Val_Get(p word64Val) uint64 {
|
||||||
|
elem := p.v
|
||||||
|
switch elem.Kind() {
|
||||||
|
case reflect.Int64:
|
||||||
|
return uint64(elem.Int())
|
||||||
|
case reflect.Uint64:
|
||||||
|
return elem.Uint()
|
||||||
|
case reflect.Float64:
|
||||||
|
return math.Float64bits(elem.Float())
|
||||||
|
}
|
||||||
|
panic("unreachable")
|
||||||
|
}
|
||||||
|
|
||||||
|
func structPointer_Word64Val(p structPointer, f field) word64Val {
|
||||||
|
return word64Val{structPointer_field(p, f)}
|
||||||
|
}
|
||||||
|
|
||||||
|
type word64Slice struct {
|
||||||
|
v reflect.Value
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p word64Slice) Append(x uint64) {
|
||||||
|
n, m := p.v.Len(), p.v.Cap()
|
||||||
|
if n < m {
|
||||||
|
p.v.SetLen(n + 1)
|
||||||
|
} else {
|
||||||
|
t := p.v.Type().Elem()
|
||||||
|
p.v.Set(reflect.Append(p.v, reflect.Zero(t)))
|
||||||
|
}
|
||||||
|
elem := p.v.Index(n)
|
||||||
|
switch elem.Kind() {
|
||||||
|
case reflect.Int64:
|
||||||
|
elem.SetInt(int64(int64(x)))
|
||||||
|
case reflect.Uint64:
|
||||||
|
elem.SetUint(uint64(x))
|
||||||
|
case reflect.Float64:
|
||||||
|
elem.SetFloat(float64(math.Float64frombits(x)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p word64Slice) Len() int {
|
||||||
|
return p.v.Len()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p word64Slice) Index(i int) uint64 {
|
||||||
|
elem := p.v.Index(i)
|
||||||
|
switch elem.Kind() {
|
||||||
|
case reflect.Int64:
|
||||||
|
return uint64(elem.Int())
|
||||||
|
case reflect.Uint64:
|
||||||
|
return uint64(elem.Uint())
|
||||||
|
case reflect.Float64:
|
||||||
|
return math.Float64bits(float64(elem.Float()))
|
||||||
|
}
|
||||||
|
panic("unreachable")
|
||||||
|
}
|
||||||
|
|
||||||
|
func structPointer_Word64Slice(p structPointer, f field) word64Slice {
|
||||||
|
return word64Slice{structPointer_field(p, f)}
|
||||||
|
}
|
||||||
266
staging/src/k8s.io/client-go/1.4/_vendor/github.com/gogo/protobuf/proto/pointer_unsafe.go
generated
Normal file
266
staging/src/k8s.io/client-go/1.4/_vendor/github.com/gogo/protobuf/proto/pointer_unsafe.go
generated
Normal file
@@ -0,0 +1,266 @@
|
|||||||
|
// Go support for Protocol Buffers - Google's data interchange format
|
||||||
|
//
|
||||||
|
// Copyright 2012 The Go Authors. All rights reserved.
|
||||||
|
// https://github.com/golang/protobuf
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions are
|
||||||
|
// met:
|
||||||
|
//
|
||||||
|
// * Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
// * Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following disclaimer
|
||||||
|
// in the documentation and/or other materials provided with the
|
||||||
|
// distribution.
|
||||||
|
// * Neither the name of Google Inc. nor the names of its
|
||||||
|
// contributors may be used to endorse or promote products derived from
|
||||||
|
// this software without specific prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
// +build !appengine
|
||||||
|
|
||||||
|
// This file contains the implementation of the proto field accesses using package unsafe.
|
||||||
|
|
||||||
|
package proto
|
||||||
|
|
||||||
|
import (
|
||||||
|
"reflect"
|
||||||
|
"unsafe"
|
||||||
|
)
|
||||||
|
|
||||||
|
// NOTE: These type_Foo functions would more idiomatically be methods,
|
||||||
|
// but Go does not allow methods on pointer types, and we must preserve
|
||||||
|
// some pointer type for the garbage collector. We use these
|
||||||
|
// funcs with clunky names as our poor approximation to methods.
|
||||||
|
//
|
||||||
|
// An alternative would be
|
||||||
|
// type structPointer struct { p unsafe.Pointer }
|
||||||
|
// but that does not registerize as well.
|
||||||
|
|
||||||
|
// A structPointer is a pointer to a struct.
|
||||||
|
type structPointer unsafe.Pointer
|
||||||
|
|
||||||
|
// toStructPointer returns a structPointer equivalent to the given reflect value.
|
||||||
|
func toStructPointer(v reflect.Value) structPointer {
|
||||||
|
return structPointer(unsafe.Pointer(v.Pointer()))
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsNil reports whether p is nil.
|
||||||
|
func structPointer_IsNil(p structPointer) bool {
|
||||||
|
return p == nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Interface returns the struct pointer, assumed to have element type t,
|
||||||
|
// as an interface value.
|
||||||
|
func structPointer_Interface(p structPointer, t reflect.Type) interface{} {
|
||||||
|
return reflect.NewAt(t, unsafe.Pointer(p)).Interface()
|
||||||
|
}
|
||||||
|
|
||||||
|
// A field identifies a field in a struct, accessible from a structPointer.
|
||||||
|
// In this implementation, a field is identified by its byte offset from the start of the struct.
|
||||||
|
type field uintptr
|
||||||
|
|
||||||
|
// toField returns a field equivalent to the given reflect field.
|
||||||
|
func toField(f *reflect.StructField) field {
|
||||||
|
return field(f.Offset)
|
||||||
|
}
|
||||||
|
|
||||||
|
// invalidField is an invalid field identifier.
|
||||||
|
const invalidField = ^field(0)
|
||||||
|
|
||||||
|
// IsValid reports whether the field identifier is valid.
|
||||||
|
func (f field) IsValid() bool {
|
||||||
|
return f != ^field(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Bytes returns the address of a []byte field in the struct.
|
||||||
|
func structPointer_Bytes(p structPointer, f field) *[]byte {
|
||||||
|
return (*[]byte)(unsafe.Pointer(uintptr(p) + uintptr(f)))
|
||||||
|
}
|
||||||
|
|
||||||
|
// BytesSlice returns the address of a [][]byte field in the struct.
|
||||||
|
func structPointer_BytesSlice(p structPointer, f field) *[][]byte {
|
||||||
|
return (*[][]byte)(unsafe.Pointer(uintptr(p) + uintptr(f)))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Bool returns the address of a *bool field in the struct.
|
||||||
|
func structPointer_Bool(p structPointer, f field) **bool {
|
||||||
|
return (**bool)(unsafe.Pointer(uintptr(p) + uintptr(f)))
|
||||||
|
}
|
||||||
|
|
||||||
|
// BoolVal returns the address of a bool field in the struct.
|
||||||
|
func structPointer_BoolVal(p structPointer, f field) *bool {
|
||||||
|
return (*bool)(unsafe.Pointer(uintptr(p) + uintptr(f)))
|
||||||
|
}
|
||||||
|
|
||||||
|
// BoolSlice returns the address of a []bool field in the struct.
|
||||||
|
func structPointer_BoolSlice(p structPointer, f field) *[]bool {
|
||||||
|
return (*[]bool)(unsafe.Pointer(uintptr(p) + uintptr(f)))
|
||||||
|
}
|
||||||
|
|
||||||
|
// String returns the address of a *string field in the struct.
|
||||||
|
func structPointer_String(p structPointer, f field) **string {
|
||||||
|
return (**string)(unsafe.Pointer(uintptr(p) + uintptr(f)))
|
||||||
|
}
|
||||||
|
|
||||||
|
// StringVal returns the address of a string field in the struct.
|
||||||
|
func structPointer_StringVal(p structPointer, f field) *string {
|
||||||
|
return (*string)(unsafe.Pointer(uintptr(p) + uintptr(f)))
|
||||||
|
}
|
||||||
|
|
||||||
|
// StringSlice returns the address of a []string field in the struct.
|
||||||
|
func structPointer_StringSlice(p structPointer, f field) *[]string {
|
||||||
|
return (*[]string)(unsafe.Pointer(uintptr(p) + uintptr(f)))
|
||||||
|
}
|
||||||
|
|
||||||
|
// ExtMap returns the address of an extension map field in the struct.
|
||||||
|
func structPointer_ExtMap(p structPointer, f field) *map[int32]Extension {
|
||||||
|
return (*map[int32]Extension)(unsafe.Pointer(uintptr(p) + uintptr(f)))
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewAt returns the reflect.Value for a pointer to a field in the struct.
|
||||||
|
func structPointer_NewAt(p structPointer, f field, typ reflect.Type) reflect.Value {
|
||||||
|
return reflect.NewAt(typ, unsafe.Pointer(uintptr(p)+uintptr(f)))
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetStructPointer writes a *struct field in the struct.
|
||||||
|
func structPointer_SetStructPointer(p structPointer, f field, q structPointer) {
|
||||||
|
*(*structPointer)(unsafe.Pointer(uintptr(p) + uintptr(f))) = q
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetStructPointer reads a *struct field in the struct.
|
||||||
|
func structPointer_GetStructPointer(p structPointer, f field) structPointer {
|
||||||
|
return *(*structPointer)(unsafe.Pointer(uintptr(p) + uintptr(f)))
|
||||||
|
}
|
||||||
|
|
||||||
|
// StructPointerSlice the address of a []*struct field in the struct.
|
||||||
|
func structPointer_StructPointerSlice(p structPointer, f field) *structPointerSlice {
|
||||||
|
return (*structPointerSlice)(unsafe.Pointer(uintptr(p) + uintptr(f)))
|
||||||
|
}
|
||||||
|
|
||||||
|
// A structPointerSlice represents a slice of pointers to structs (themselves submessages or groups).
|
||||||
|
type structPointerSlice []structPointer
|
||||||
|
|
||||||
|
func (v *structPointerSlice) Len() int { return len(*v) }
|
||||||
|
func (v *structPointerSlice) Index(i int) structPointer { return (*v)[i] }
|
||||||
|
func (v *structPointerSlice) Append(p structPointer) { *v = append(*v, p) }
|
||||||
|
|
||||||
|
// A word32 is the address of a "pointer to 32-bit value" field.
|
||||||
|
type word32 **uint32
|
||||||
|
|
||||||
|
// IsNil reports whether *v is nil.
|
||||||
|
func word32_IsNil(p word32) bool {
|
||||||
|
return *p == nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set sets *v to point at a newly allocated word set to x.
|
||||||
|
func word32_Set(p word32, o *Buffer, x uint32) {
|
||||||
|
if len(o.uint32s) == 0 {
|
||||||
|
o.uint32s = make([]uint32, uint32PoolSize)
|
||||||
|
}
|
||||||
|
o.uint32s[0] = x
|
||||||
|
*p = &o.uint32s[0]
|
||||||
|
o.uint32s = o.uint32s[1:]
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get gets the value pointed at by *v.
|
||||||
|
func word32_Get(p word32) uint32 {
|
||||||
|
return **p
|
||||||
|
}
|
||||||
|
|
||||||
|
// Word32 returns the address of a *int32, *uint32, *float32, or *enum field in the struct.
|
||||||
|
func structPointer_Word32(p structPointer, f field) word32 {
|
||||||
|
return word32((**uint32)(unsafe.Pointer(uintptr(p) + uintptr(f))))
|
||||||
|
}
|
||||||
|
|
||||||
|
// A word32Val is the address of a 32-bit value field.
|
||||||
|
type word32Val *uint32
|
||||||
|
|
||||||
|
// Set sets *p to x.
|
||||||
|
func word32Val_Set(p word32Val, x uint32) {
|
||||||
|
*p = x
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get gets the value pointed at by p.
|
||||||
|
func word32Val_Get(p word32Val) uint32 {
|
||||||
|
return *p
|
||||||
|
}
|
||||||
|
|
||||||
|
// Word32Val returns the address of a *int32, *uint32, *float32, or *enum field in the struct.
|
||||||
|
func structPointer_Word32Val(p structPointer, f field) word32Val {
|
||||||
|
return word32Val((*uint32)(unsafe.Pointer(uintptr(p) + uintptr(f))))
|
||||||
|
}
|
||||||
|
|
||||||
|
// A word32Slice is a slice of 32-bit values.
|
||||||
|
type word32Slice []uint32
|
||||||
|
|
||||||
|
func (v *word32Slice) Append(x uint32) { *v = append(*v, x) }
|
||||||
|
func (v *word32Slice) Len() int { return len(*v) }
|
||||||
|
func (v *word32Slice) Index(i int) uint32 { return (*v)[i] }
|
||||||
|
|
||||||
|
// Word32Slice returns the address of a []int32, []uint32, []float32, or []enum field in the struct.
|
||||||
|
func structPointer_Word32Slice(p structPointer, f field) *word32Slice {
|
||||||
|
return (*word32Slice)(unsafe.Pointer(uintptr(p) + uintptr(f)))
|
||||||
|
}
|
||||||
|
|
||||||
|
// word64 is like word32 but for 64-bit values.
|
||||||
|
type word64 **uint64
|
||||||
|
|
||||||
|
func word64_Set(p word64, o *Buffer, x uint64) {
|
||||||
|
if len(o.uint64s) == 0 {
|
||||||
|
o.uint64s = make([]uint64, uint64PoolSize)
|
||||||
|
}
|
||||||
|
o.uint64s[0] = x
|
||||||
|
*p = &o.uint64s[0]
|
||||||
|
o.uint64s = o.uint64s[1:]
|
||||||
|
}
|
||||||
|
|
||||||
|
func word64_IsNil(p word64) bool {
|
||||||
|
return *p == nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func word64_Get(p word64) uint64 {
|
||||||
|
return **p
|
||||||
|
}
|
||||||
|
|
||||||
|
func structPointer_Word64(p structPointer, f field) word64 {
|
||||||
|
return word64((**uint64)(unsafe.Pointer(uintptr(p) + uintptr(f))))
|
||||||
|
}
|
||||||
|
|
||||||
|
// word64Val is like word32Val but for 64-bit values.
|
||||||
|
type word64Val *uint64
|
||||||
|
|
||||||
|
func word64Val_Set(p word64Val, o *Buffer, x uint64) {
|
||||||
|
*p = x
|
||||||
|
}
|
||||||
|
|
||||||
|
func word64Val_Get(p word64Val) uint64 {
|
||||||
|
return *p
|
||||||
|
}
|
||||||
|
|
||||||
|
func structPointer_Word64Val(p structPointer, f field) word64Val {
|
||||||
|
return word64Val((*uint64)(unsafe.Pointer(uintptr(p) + uintptr(f))))
|
||||||
|
}
|
||||||
|
|
||||||
|
// word64Slice is like word32Slice but for 64-bit values.
|
||||||
|
type word64Slice []uint64
|
||||||
|
|
||||||
|
func (v *word64Slice) Append(x uint64) { *v = append(*v, x) }
|
||||||
|
func (v *word64Slice) Len() int { return len(*v) }
|
||||||
|
func (v *word64Slice) Index(i int) uint64 { return (*v)[i] }
|
||||||
|
|
||||||
|
func structPointer_Word64Slice(p structPointer, f field) *word64Slice {
|
||||||
|
return (*word64Slice)(unsafe.Pointer(uintptr(p) + uintptr(f)))
|
||||||
|
}
|
||||||
108
staging/src/k8s.io/client-go/1.4/_vendor/github.com/gogo/protobuf/proto/pointer_unsafe_gogo.go
generated
Normal file
108
staging/src/k8s.io/client-go/1.4/_vendor/github.com/gogo/protobuf/proto/pointer_unsafe_gogo.go
generated
Normal file
@@ -0,0 +1,108 @@
|
|||||||
|
// Copyright (c) 2013, Vastech SA (PTY) LTD. All rights reserved.
|
||||||
|
// http://github.com/gogo/protobuf/gogoproto
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions are
|
||||||
|
// met:
|
||||||
|
//
|
||||||
|
// * Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
// * Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following disclaimer
|
||||||
|
// in the documentation and/or other materials provided with the
|
||||||
|
// distribution.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
// +build !appengine
|
||||||
|
|
||||||
|
// This file contains the implementation of the proto field accesses using package unsafe.
|
||||||
|
|
||||||
|
package proto
|
||||||
|
|
||||||
|
import (
|
||||||
|
"reflect"
|
||||||
|
"unsafe"
|
||||||
|
)
|
||||||
|
|
||||||
|
func structPointer_InterfaceAt(p structPointer, f field, t reflect.Type) interface{} {
|
||||||
|
point := unsafe.Pointer(uintptr(p) + uintptr(f))
|
||||||
|
r := reflect.NewAt(t, point)
|
||||||
|
return r.Interface()
|
||||||
|
}
|
||||||
|
|
||||||
|
func structPointer_InterfaceRef(p structPointer, f field, t reflect.Type) interface{} {
|
||||||
|
point := unsafe.Pointer(uintptr(p) + uintptr(f))
|
||||||
|
r := reflect.NewAt(t, point)
|
||||||
|
if r.Elem().IsNil() {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return r.Elem().Interface()
|
||||||
|
}
|
||||||
|
|
||||||
|
func copyUintPtr(oldptr, newptr uintptr, size int) {
|
||||||
|
oldbytes := make([]byte, 0)
|
||||||
|
oldslice := (*reflect.SliceHeader)(unsafe.Pointer(&oldbytes))
|
||||||
|
oldslice.Data = oldptr
|
||||||
|
oldslice.Len = size
|
||||||
|
oldslice.Cap = size
|
||||||
|
newbytes := make([]byte, 0)
|
||||||
|
newslice := (*reflect.SliceHeader)(unsafe.Pointer(&newbytes))
|
||||||
|
newslice.Data = newptr
|
||||||
|
newslice.Len = size
|
||||||
|
newslice.Cap = size
|
||||||
|
copy(newbytes, oldbytes)
|
||||||
|
}
|
||||||
|
|
||||||
|
func structPointer_Copy(oldptr structPointer, newptr structPointer, size int) {
|
||||||
|
copyUintPtr(uintptr(oldptr), uintptr(newptr), size)
|
||||||
|
}
|
||||||
|
|
||||||
|
func appendStructPointer(base structPointer, f field, typ reflect.Type) structPointer {
|
||||||
|
size := typ.Elem().Size()
|
||||||
|
oldHeader := structPointer_GetSliceHeader(base, f)
|
||||||
|
newLen := oldHeader.Len + 1
|
||||||
|
slice := reflect.MakeSlice(typ, newLen, newLen)
|
||||||
|
bas := toStructPointer(slice)
|
||||||
|
for i := 0; i < oldHeader.Len; i++ {
|
||||||
|
newElemptr := uintptr(bas) + uintptr(i)*size
|
||||||
|
oldElemptr := oldHeader.Data + uintptr(i)*size
|
||||||
|
copyUintPtr(oldElemptr, newElemptr, int(size))
|
||||||
|
}
|
||||||
|
|
||||||
|
oldHeader.Data = uintptr(bas)
|
||||||
|
oldHeader.Len = newLen
|
||||||
|
oldHeader.Cap = newLen
|
||||||
|
|
||||||
|
return structPointer(unsafe.Pointer(uintptr(unsafe.Pointer(bas)) + uintptr(uintptr(newLen-1)*size)))
|
||||||
|
}
|
||||||
|
|
||||||
|
func structPointer_FieldPointer(p structPointer, f field) structPointer {
|
||||||
|
return structPointer(unsafe.Pointer(uintptr(p) + uintptr(f)))
|
||||||
|
}
|
||||||
|
|
||||||
|
func structPointer_GetRefStructPointer(p structPointer, f field) structPointer {
|
||||||
|
return structPointer((*structPointer)(unsafe.Pointer(uintptr(p) + uintptr(f))))
|
||||||
|
}
|
||||||
|
|
||||||
|
func structPointer_GetSliceHeader(p structPointer, f field) *reflect.SliceHeader {
|
||||||
|
return (*reflect.SliceHeader)(unsafe.Pointer(uintptr(p) + uintptr(f)))
|
||||||
|
}
|
||||||
|
|
||||||
|
func structPointer_Add(p structPointer, size field) structPointer {
|
||||||
|
return structPointer(unsafe.Pointer(uintptr(p) + uintptr(size)))
|
||||||
|
}
|
||||||
|
|
||||||
|
func structPointer_Len(p structPointer, f field) int {
|
||||||
|
return len(*(*[]interface{})(unsafe.Pointer(structPointer_GetRefStructPointer(p, f))))
|
||||||
|
}
|
||||||
923
staging/src/k8s.io/client-go/1.4/_vendor/github.com/gogo/protobuf/proto/properties.go
generated
Normal file
923
staging/src/k8s.io/client-go/1.4/_vendor/github.com/gogo/protobuf/proto/properties.go
generated
Normal file
@@ -0,0 +1,923 @@
|
|||||||
|
// Extensions for Protocol Buffers to create more go like structures.
|
||||||
|
//
|
||||||
|
// Copyright (c) 2013, Vastech SA (PTY) LTD. All rights reserved.
|
||||||
|
// http://github.com/gogo/protobuf/gogoproto
|
||||||
|
//
|
||||||
|
// Go support for Protocol Buffers - Google's data interchange format
|
||||||
|
//
|
||||||
|
// Copyright 2010 The Go Authors. All rights reserved.
|
||||||
|
// https://github.com/golang/protobuf
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions are
|
||||||
|
// met:
|
||||||
|
//
|
||||||
|
// * Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
// * Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following disclaimer
|
||||||
|
// in the documentation and/or other materials provided with the
|
||||||
|
// distribution.
|
||||||
|
// * Neither the name of Google Inc. nor the names of its
|
||||||
|
// contributors may be used to endorse or promote products derived from
|
||||||
|
// this software without specific prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
package proto
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Routines for encoding data into the wire format for protocol buffers.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"log"
|
||||||
|
"os"
|
||||||
|
"reflect"
|
||||||
|
"sort"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
"sync"
|
||||||
|
)
|
||||||
|
|
||||||
|
const debug bool = false
|
||||||
|
|
||||||
|
// Constants that identify the encoding of a value on the wire.
|
||||||
|
const (
|
||||||
|
WireVarint = 0
|
||||||
|
WireFixed64 = 1
|
||||||
|
WireBytes = 2
|
||||||
|
WireStartGroup = 3
|
||||||
|
WireEndGroup = 4
|
||||||
|
WireFixed32 = 5
|
||||||
|
)
|
||||||
|
|
||||||
|
const startSize = 10 // initial slice/string sizes
|
||||||
|
|
||||||
|
// Encoders are defined in encode.go
|
||||||
|
// An encoder outputs the full representation of a field, including its
|
||||||
|
// tag and encoder type.
|
||||||
|
type encoder func(p *Buffer, prop *Properties, base structPointer) error
|
||||||
|
|
||||||
|
// A valueEncoder encodes a single integer in a particular encoding.
|
||||||
|
type valueEncoder func(o *Buffer, x uint64) error
|
||||||
|
|
||||||
|
// Sizers are defined in encode.go
|
||||||
|
// A sizer returns the encoded size of a field, including its tag and encoder
|
||||||
|
// type.
|
||||||
|
type sizer func(prop *Properties, base structPointer) int
|
||||||
|
|
||||||
|
// A valueSizer returns the encoded size of a single integer in a particular
|
||||||
|
// encoding.
|
||||||
|
type valueSizer func(x uint64) int
|
||||||
|
|
||||||
|
// Decoders are defined in decode.go
|
||||||
|
// A decoder creates a value from its wire representation.
|
||||||
|
// Unrecognized subelements are saved in unrec.
|
||||||
|
type decoder func(p *Buffer, prop *Properties, base structPointer) error
|
||||||
|
|
||||||
|
// A valueDecoder decodes a single integer in a particular encoding.
|
||||||
|
type valueDecoder func(o *Buffer) (x uint64, err error)
|
||||||
|
|
||||||
|
// A oneofMarshaler does the marshaling for all oneof fields in a message.
|
||||||
|
type oneofMarshaler func(Message, *Buffer) error
|
||||||
|
|
||||||
|
// A oneofUnmarshaler does the unmarshaling for a oneof field in a message.
|
||||||
|
type oneofUnmarshaler func(Message, int, int, *Buffer) (bool, error)
|
||||||
|
|
||||||
|
// A oneofSizer does the sizing for all oneof fields in a message.
|
||||||
|
type oneofSizer func(Message) int
|
||||||
|
|
||||||
|
// tagMap is an optimization over map[int]int for typical protocol buffer
|
||||||
|
// use-cases. Encoded protocol buffers are often in tag order with small tag
|
||||||
|
// numbers.
|
||||||
|
type tagMap struct {
|
||||||
|
fastTags []int
|
||||||
|
slowTags map[int]int
|
||||||
|
}
|
||||||
|
|
||||||
|
// tagMapFastLimit is the upper bound on the tag number that will be stored in
|
||||||
|
// the tagMap slice rather than its map.
|
||||||
|
const tagMapFastLimit = 1024
|
||||||
|
|
||||||
|
func (p *tagMap) get(t int) (int, bool) {
|
||||||
|
if t > 0 && t < tagMapFastLimit {
|
||||||
|
if t >= len(p.fastTags) {
|
||||||
|
return 0, false
|
||||||
|
}
|
||||||
|
fi := p.fastTags[t]
|
||||||
|
return fi, fi >= 0
|
||||||
|
}
|
||||||
|
fi, ok := p.slowTags[t]
|
||||||
|
return fi, ok
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *tagMap) put(t int, fi int) {
|
||||||
|
if t > 0 && t < tagMapFastLimit {
|
||||||
|
for len(p.fastTags) < t+1 {
|
||||||
|
p.fastTags = append(p.fastTags, -1)
|
||||||
|
}
|
||||||
|
p.fastTags[t] = fi
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if p.slowTags == nil {
|
||||||
|
p.slowTags = make(map[int]int)
|
||||||
|
}
|
||||||
|
p.slowTags[t] = fi
|
||||||
|
}
|
||||||
|
|
||||||
|
// StructProperties represents properties for all the fields of a struct.
|
||||||
|
// decoderTags and decoderOrigNames should only be used by the decoder.
|
||||||
|
type StructProperties struct {
|
||||||
|
Prop []*Properties // properties for each field
|
||||||
|
reqCount int // required count
|
||||||
|
decoderTags tagMap // map from proto tag to struct field number
|
||||||
|
decoderOrigNames map[string]int // map from original name to struct field number
|
||||||
|
order []int // list of struct field numbers in tag order
|
||||||
|
unrecField field // field id of the XXX_unrecognized []byte field
|
||||||
|
extendable bool // is this an extendable proto
|
||||||
|
|
||||||
|
oneofMarshaler oneofMarshaler
|
||||||
|
oneofUnmarshaler oneofUnmarshaler
|
||||||
|
oneofSizer oneofSizer
|
||||||
|
stype reflect.Type
|
||||||
|
|
||||||
|
// OneofTypes contains information about the oneof fields in this message.
|
||||||
|
// It is keyed by the original name of a field.
|
||||||
|
OneofTypes map[string]*OneofProperties
|
||||||
|
}
|
||||||
|
|
||||||
|
// OneofProperties represents information about a specific field in a oneof.
|
||||||
|
type OneofProperties struct {
|
||||||
|
Type reflect.Type // pointer to generated struct type for this oneof field
|
||||||
|
Field int // struct field number of the containing oneof in the message
|
||||||
|
Prop *Properties
|
||||||
|
}
|
||||||
|
|
||||||
|
// Implement the sorting interface so we can sort the fields in tag order, as recommended by the spec.
|
||||||
|
// See encode.go, (*Buffer).enc_struct.
|
||||||
|
|
||||||
|
func (sp *StructProperties) Len() int { return len(sp.order) }
|
||||||
|
func (sp *StructProperties) Less(i, j int) bool {
|
||||||
|
return sp.Prop[sp.order[i]].Tag < sp.Prop[sp.order[j]].Tag
|
||||||
|
}
|
||||||
|
func (sp *StructProperties) Swap(i, j int) { sp.order[i], sp.order[j] = sp.order[j], sp.order[i] }
|
||||||
|
|
||||||
|
// Properties represents the protocol-specific behavior of a single struct field.
|
||||||
|
type Properties struct {
|
||||||
|
Name string // name of the field, for error messages
|
||||||
|
OrigName string // original name before protocol compiler (always set)
|
||||||
|
JSONName string // name to use for JSON; determined by protoc
|
||||||
|
Wire string
|
||||||
|
WireType int
|
||||||
|
Tag int
|
||||||
|
Required bool
|
||||||
|
Optional bool
|
||||||
|
Repeated bool
|
||||||
|
Packed bool // relevant for repeated primitives only
|
||||||
|
Enum string // set for enum types only
|
||||||
|
proto3 bool // whether this is known to be a proto3 field; set for []byte only
|
||||||
|
oneof bool // whether this is a oneof field
|
||||||
|
|
||||||
|
Default string // default value
|
||||||
|
HasDefault bool // whether an explicit default was provided
|
||||||
|
CustomType string
|
||||||
|
def_uint64 uint64
|
||||||
|
|
||||||
|
enc encoder
|
||||||
|
valEnc valueEncoder // set for bool and numeric types only
|
||||||
|
field field
|
||||||
|
tagcode []byte // encoding of EncodeVarint((Tag<<3)|WireType)
|
||||||
|
tagbuf [8]byte
|
||||||
|
stype reflect.Type // set for struct types only
|
||||||
|
sstype reflect.Type // set for slices of structs types only
|
||||||
|
ctype reflect.Type // set for custom types only
|
||||||
|
sprop *StructProperties // set for struct types only
|
||||||
|
isMarshaler bool
|
||||||
|
isUnmarshaler bool
|
||||||
|
|
||||||
|
mtype reflect.Type // set for map types only
|
||||||
|
mkeyprop *Properties // set for map types only
|
||||||
|
mvalprop *Properties // set for map types only
|
||||||
|
|
||||||
|
size sizer
|
||||||
|
valSize valueSizer // set for bool and numeric types only
|
||||||
|
|
||||||
|
dec decoder
|
||||||
|
valDec valueDecoder // set for bool and numeric types only
|
||||||
|
|
||||||
|
// If this is a packable field, this will be the decoder for the packed version of the field.
|
||||||
|
packedDec decoder
|
||||||
|
}
|
||||||
|
|
||||||
|
// String formats the properties in the protobuf struct field tag style.
|
||||||
|
func (p *Properties) String() string {
|
||||||
|
s := p.Wire
|
||||||
|
s = ","
|
||||||
|
s += strconv.Itoa(p.Tag)
|
||||||
|
if p.Required {
|
||||||
|
s += ",req"
|
||||||
|
}
|
||||||
|
if p.Optional {
|
||||||
|
s += ",opt"
|
||||||
|
}
|
||||||
|
if p.Repeated {
|
||||||
|
s += ",rep"
|
||||||
|
}
|
||||||
|
if p.Packed {
|
||||||
|
s += ",packed"
|
||||||
|
}
|
||||||
|
s += ",name=" + p.OrigName
|
||||||
|
if p.JSONName != p.OrigName {
|
||||||
|
s += ",json=" + p.JSONName
|
||||||
|
}
|
||||||
|
if p.proto3 {
|
||||||
|
s += ",proto3"
|
||||||
|
}
|
||||||
|
if p.oneof {
|
||||||
|
s += ",oneof"
|
||||||
|
}
|
||||||
|
if len(p.Enum) > 0 {
|
||||||
|
s += ",enum=" + p.Enum
|
||||||
|
}
|
||||||
|
if p.HasDefault {
|
||||||
|
s += ",def=" + p.Default
|
||||||
|
}
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parse populates p by parsing a string in the protobuf struct field tag style.
|
||||||
|
func (p *Properties) Parse(s string) {
|
||||||
|
// "bytes,49,opt,name=foo,def=hello!"
|
||||||
|
fields := strings.Split(s, ",") // breaks def=, but handled below.
|
||||||
|
if len(fields) < 2 {
|
||||||
|
fmt.Fprintf(os.Stderr, "proto: tag has too few fields: %q\n", s)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
p.Wire = fields[0]
|
||||||
|
switch p.Wire {
|
||||||
|
case "varint":
|
||||||
|
p.WireType = WireVarint
|
||||||
|
p.valEnc = (*Buffer).EncodeVarint
|
||||||
|
p.valDec = (*Buffer).DecodeVarint
|
||||||
|
p.valSize = sizeVarint
|
||||||
|
case "fixed32":
|
||||||
|
p.WireType = WireFixed32
|
||||||
|
p.valEnc = (*Buffer).EncodeFixed32
|
||||||
|
p.valDec = (*Buffer).DecodeFixed32
|
||||||
|
p.valSize = sizeFixed32
|
||||||
|
case "fixed64":
|
||||||
|
p.WireType = WireFixed64
|
||||||
|
p.valEnc = (*Buffer).EncodeFixed64
|
||||||
|
p.valDec = (*Buffer).DecodeFixed64
|
||||||
|
p.valSize = sizeFixed64
|
||||||
|
case "zigzag32":
|
||||||
|
p.WireType = WireVarint
|
||||||
|
p.valEnc = (*Buffer).EncodeZigzag32
|
||||||
|
p.valDec = (*Buffer).DecodeZigzag32
|
||||||
|
p.valSize = sizeZigzag32
|
||||||
|
case "zigzag64":
|
||||||
|
p.WireType = WireVarint
|
||||||
|
p.valEnc = (*Buffer).EncodeZigzag64
|
||||||
|
p.valDec = (*Buffer).DecodeZigzag64
|
||||||
|
p.valSize = sizeZigzag64
|
||||||
|
case "bytes", "group":
|
||||||
|
p.WireType = WireBytes
|
||||||
|
// no numeric converter for non-numeric types
|
||||||
|
default:
|
||||||
|
fmt.Fprintf(os.Stderr, "proto: tag has unknown wire type: %q\n", s)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var err error
|
||||||
|
p.Tag, err = strconv.Atoi(fields[1])
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := 2; i < len(fields); i++ {
|
||||||
|
f := fields[i]
|
||||||
|
switch {
|
||||||
|
case f == "req":
|
||||||
|
p.Required = true
|
||||||
|
case f == "opt":
|
||||||
|
p.Optional = true
|
||||||
|
case f == "rep":
|
||||||
|
p.Repeated = true
|
||||||
|
case f == "packed":
|
||||||
|
p.Packed = true
|
||||||
|
case strings.HasPrefix(f, "name="):
|
||||||
|
p.OrigName = f[5:]
|
||||||
|
case strings.HasPrefix(f, "json="):
|
||||||
|
p.JSONName = f[5:]
|
||||||
|
case strings.HasPrefix(f, "enum="):
|
||||||
|
p.Enum = f[5:]
|
||||||
|
case f == "proto3":
|
||||||
|
p.proto3 = true
|
||||||
|
case f == "oneof":
|
||||||
|
p.oneof = true
|
||||||
|
case strings.HasPrefix(f, "def="):
|
||||||
|
p.HasDefault = true
|
||||||
|
p.Default = f[4:] // rest of string
|
||||||
|
if i+1 < len(fields) {
|
||||||
|
// Commas aren't escaped, and def is always last.
|
||||||
|
p.Default += "," + strings.Join(fields[i+1:], ",")
|
||||||
|
break
|
||||||
|
}
|
||||||
|
case strings.HasPrefix(f, "embedded="):
|
||||||
|
p.OrigName = strings.Split(f, "=")[1]
|
||||||
|
case strings.HasPrefix(f, "customtype="):
|
||||||
|
p.CustomType = strings.Split(f, "=")[1]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func logNoSliceEnc(t1, t2 reflect.Type) {
|
||||||
|
fmt.Fprintf(os.Stderr, "proto: no slice oenc for %T = []%T\n", t1, t2)
|
||||||
|
}
|
||||||
|
|
||||||
|
var protoMessageType = reflect.TypeOf((*Message)(nil)).Elem()
|
||||||
|
|
||||||
|
// Initialize the fields for encoding and decoding.
|
||||||
|
func (p *Properties) setEncAndDec(typ reflect.Type, f *reflect.StructField, lockGetProp bool) {
|
||||||
|
p.enc = nil
|
||||||
|
p.dec = nil
|
||||||
|
p.size = nil
|
||||||
|
if len(p.CustomType) > 0 {
|
||||||
|
p.setCustomEncAndDec(typ)
|
||||||
|
p.setTag(lockGetProp)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
switch t1 := typ; t1.Kind() {
|
||||||
|
default:
|
||||||
|
fmt.Fprintf(os.Stderr, "proto: no coders for %v\n", t1)
|
||||||
|
|
||||||
|
// proto3 scalar types
|
||||||
|
|
||||||
|
case reflect.Bool:
|
||||||
|
if p.proto3 {
|
||||||
|
p.enc = (*Buffer).enc_proto3_bool
|
||||||
|
p.dec = (*Buffer).dec_proto3_bool
|
||||||
|
p.size = size_proto3_bool
|
||||||
|
} else {
|
||||||
|
p.enc = (*Buffer).enc_ref_bool
|
||||||
|
p.dec = (*Buffer).dec_proto3_bool
|
||||||
|
p.size = size_ref_bool
|
||||||
|
}
|
||||||
|
case reflect.Int32:
|
||||||
|
if p.proto3 {
|
||||||
|
p.enc = (*Buffer).enc_proto3_int32
|
||||||
|
p.dec = (*Buffer).dec_proto3_int32
|
||||||
|
p.size = size_proto3_int32
|
||||||
|
} else {
|
||||||
|
p.enc = (*Buffer).enc_ref_int32
|
||||||
|
p.dec = (*Buffer).dec_proto3_int32
|
||||||
|
p.size = size_ref_int32
|
||||||
|
}
|
||||||
|
case reflect.Uint32:
|
||||||
|
if p.proto3 {
|
||||||
|
p.enc = (*Buffer).enc_proto3_uint32
|
||||||
|
p.dec = (*Buffer).dec_proto3_int32 // can reuse
|
||||||
|
p.size = size_proto3_uint32
|
||||||
|
} else {
|
||||||
|
p.enc = (*Buffer).enc_ref_uint32
|
||||||
|
p.dec = (*Buffer).dec_proto3_int32 // can reuse
|
||||||
|
p.size = size_ref_uint32
|
||||||
|
}
|
||||||
|
case reflect.Int64, reflect.Uint64:
|
||||||
|
if p.proto3 {
|
||||||
|
p.enc = (*Buffer).enc_proto3_int64
|
||||||
|
p.dec = (*Buffer).dec_proto3_int64
|
||||||
|
p.size = size_proto3_int64
|
||||||
|
} else {
|
||||||
|
p.enc = (*Buffer).enc_ref_int64
|
||||||
|
p.dec = (*Buffer).dec_proto3_int64
|
||||||
|
p.size = size_ref_int64
|
||||||
|
}
|
||||||
|
case reflect.Float32:
|
||||||
|
if p.proto3 {
|
||||||
|
p.enc = (*Buffer).enc_proto3_uint32 // can just treat them as bits
|
||||||
|
p.dec = (*Buffer).dec_proto3_int32
|
||||||
|
p.size = size_proto3_uint32
|
||||||
|
} else {
|
||||||
|
p.enc = (*Buffer).enc_ref_uint32 // can just treat them as bits
|
||||||
|
p.dec = (*Buffer).dec_proto3_int32
|
||||||
|
p.size = size_ref_uint32
|
||||||
|
}
|
||||||
|
case reflect.Float64:
|
||||||
|
if p.proto3 {
|
||||||
|
p.enc = (*Buffer).enc_proto3_int64 // can just treat them as bits
|
||||||
|
p.dec = (*Buffer).dec_proto3_int64
|
||||||
|
p.size = size_proto3_int64
|
||||||
|
} else {
|
||||||
|
p.enc = (*Buffer).enc_ref_int64 // can just treat them as bits
|
||||||
|
p.dec = (*Buffer).dec_proto3_int64
|
||||||
|
p.size = size_ref_int64
|
||||||
|
}
|
||||||
|
case reflect.String:
|
||||||
|
if p.proto3 {
|
||||||
|
p.enc = (*Buffer).enc_proto3_string
|
||||||
|
p.dec = (*Buffer).dec_proto3_string
|
||||||
|
p.size = size_proto3_string
|
||||||
|
} else {
|
||||||
|
p.enc = (*Buffer).enc_ref_string
|
||||||
|
p.dec = (*Buffer).dec_proto3_string
|
||||||
|
p.size = size_ref_string
|
||||||
|
}
|
||||||
|
case reflect.Struct:
|
||||||
|
p.stype = typ
|
||||||
|
p.isMarshaler = isMarshaler(typ)
|
||||||
|
p.isUnmarshaler = isUnmarshaler(typ)
|
||||||
|
if p.Wire == "bytes" {
|
||||||
|
p.enc = (*Buffer).enc_ref_struct_message
|
||||||
|
p.dec = (*Buffer).dec_ref_struct_message
|
||||||
|
p.size = size_ref_struct_message
|
||||||
|
} else {
|
||||||
|
fmt.Fprintf(os.Stderr, "proto: no coders for struct %T\n", typ)
|
||||||
|
}
|
||||||
|
|
||||||
|
case reflect.Ptr:
|
||||||
|
switch t2 := t1.Elem(); t2.Kind() {
|
||||||
|
default:
|
||||||
|
fmt.Fprintf(os.Stderr, "proto: no encoder function for %v -> %v\n", t1, t2)
|
||||||
|
break
|
||||||
|
case reflect.Bool:
|
||||||
|
p.enc = (*Buffer).enc_bool
|
||||||
|
p.dec = (*Buffer).dec_bool
|
||||||
|
p.size = size_bool
|
||||||
|
case reflect.Int32:
|
||||||
|
p.enc = (*Buffer).enc_int32
|
||||||
|
p.dec = (*Buffer).dec_int32
|
||||||
|
p.size = size_int32
|
||||||
|
case reflect.Uint32:
|
||||||
|
p.enc = (*Buffer).enc_uint32
|
||||||
|
p.dec = (*Buffer).dec_int32 // can reuse
|
||||||
|
p.size = size_uint32
|
||||||
|
case reflect.Int64, reflect.Uint64:
|
||||||
|
p.enc = (*Buffer).enc_int64
|
||||||
|
p.dec = (*Buffer).dec_int64
|
||||||
|
p.size = size_int64
|
||||||
|
case reflect.Float32:
|
||||||
|
p.enc = (*Buffer).enc_uint32 // can just treat them as bits
|
||||||
|
p.dec = (*Buffer).dec_int32
|
||||||
|
p.size = size_uint32
|
||||||
|
case reflect.Float64:
|
||||||
|
p.enc = (*Buffer).enc_int64 // can just treat them as bits
|
||||||
|
p.dec = (*Buffer).dec_int64
|
||||||
|
p.size = size_int64
|
||||||
|
case reflect.String:
|
||||||
|
p.enc = (*Buffer).enc_string
|
||||||
|
p.dec = (*Buffer).dec_string
|
||||||
|
p.size = size_string
|
||||||
|
case reflect.Struct:
|
||||||
|
p.stype = t1.Elem()
|
||||||
|
p.isMarshaler = isMarshaler(t1)
|
||||||
|
p.isUnmarshaler = isUnmarshaler(t1)
|
||||||
|
if p.Wire == "bytes" {
|
||||||
|
p.enc = (*Buffer).enc_struct_message
|
||||||
|
p.dec = (*Buffer).dec_struct_message
|
||||||
|
p.size = size_struct_message
|
||||||
|
} else {
|
||||||
|
p.enc = (*Buffer).enc_struct_group
|
||||||
|
p.dec = (*Buffer).dec_struct_group
|
||||||
|
p.size = size_struct_group
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
case reflect.Slice:
|
||||||
|
switch t2 := t1.Elem(); t2.Kind() {
|
||||||
|
default:
|
||||||
|
logNoSliceEnc(t1, t2)
|
||||||
|
break
|
||||||
|
case reflect.Bool:
|
||||||
|
if p.Packed {
|
||||||
|
p.enc = (*Buffer).enc_slice_packed_bool
|
||||||
|
p.size = size_slice_packed_bool
|
||||||
|
} else {
|
||||||
|
p.enc = (*Buffer).enc_slice_bool
|
||||||
|
p.size = size_slice_bool
|
||||||
|
}
|
||||||
|
p.dec = (*Buffer).dec_slice_bool
|
||||||
|
p.packedDec = (*Buffer).dec_slice_packed_bool
|
||||||
|
case reflect.Int32:
|
||||||
|
if p.Packed {
|
||||||
|
p.enc = (*Buffer).enc_slice_packed_int32
|
||||||
|
p.size = size_slice_packed_int32
|
||||||
|
} else {
|
||||||
|
p.enc = (*Buffer).enc_slice_int32
|
||||||
|
p.size = size_slice_int32
|
||||||
|
}
|
||||||
|
p.dec = (*Buffer).dec_slice_int32
|
||||||
|
p.packedDec = (*Buffer).dec_slice_packed_int32
|
||||||
|
case reflect.Uint32:
|
||||||
|
if p.Packed {
|
||||||
|
p.enc = (*Buffer).enc_slice_packed_uint32
|
||||||
|
p.size = size_slice_packed_uint32
|
||||||
|
} else {
|
||||||
|
p.enc = (*Buffer).enc_slice_uint32
|
||||||
|
p.size = size_slice_uint32
|
||||||
|
}
|
||||||
|
p.dec = (*Buffer).dec_slice_int32
|
||||||
|
p.packedDec = (*Buffer).dec_slice_packed_int32
|
||||||
|
case reflect.Int64, reflect.Uint64:
|
||||||
|
if p.Packed {
|
||||||
|
p.enc = (*Buffer).enc_slice_packed_int64
|
||||||
|
p.size = size_slice_packed_int64
|
||||||
|
} else {
|
||||||
|
p.enc = (*Buffer).enc_slice_int64
|
||||||
|
p.size = size_slice_int64
|
||||||
|
}
|
||||||
|
p.dec = (*Buffer).dec_slice_int64
|
||||||
|
p.packedDec = (*Buffer).dec_slice_packed_int64
|
||||||
|
case reflect.Uint8:
|
||||||
|
p.enc = (*Buffer).enc_slice_byte
|
||||||
|
p.dec = (*Buffer).dec_slice_byte
|
||||||
|
p.size = size_slice_byte
|
||||||
|
// This is a []byte, which is either a bytes field,
|
||||||
|
// or the value of a map field. In the latter case,
|
||||||
|
// we always encode an empty []byte, so we should not
|
||||||
|
// use the proto3 enc/size funcs.
|
||||||
|
// f == nil iff this is the key/value of a map field.
|
||||||
|
if p.proto3 && f != nil {
|
||||||
|
p.enc = (*Buffer).enc_proto3_slice_byte
|
||||||
|
p.size = size_proto3_slice_byte
|
||||||
|
}
|
||||||
|
case reflect.Float32, reflect.Float64:
|
||||||
|
switch t2.Bits() {
|
||||||
|
case 32:
|
||||||
|
// can just treat them as bits
|
||||||
|
if p.Packed {
|
||||||
|
p.enc = (*Buffer).enc_slice_packed_uint32
|
||||||
|
p.size = size_slice_packed_uint32
|
||||||
|
} else {
|
||||||
|
p.enc = (*Buffer).enc_slice_uint32
|
||||||
|
p.size = size_slice_uint32
|
||||||
|
}
|
||||||
|
p.dec = (*Buffer).dec_slice_int32
|
||||||
|
p.packedDec = (*Buffer).dec_slice_packed_int32
|
||||||
|
case 64:
|
||||||
|
// can just treat them as bits
|
||||||
|
if p.Packed {
|
||||||
|
p.enc = (*Buffer).enc_slice_packed_int64
|
||||||
|
p.size = size_slice_packed_int64
|
||||||
|
} else {
|
||||||
|
p.enc = (*Buffer).enc_slice_int64
|
||||||
|
p.size = size_slice_int64
|
||||||
|
}
|
||||||
|
p.dec = (*Buffer).dec_slice_int64
|
||||||
|
p.packedDec = (*Buffer).dec_slice_packed_int64
|
||||||
|
default:
|
||||||
|
logNoSliceEnc(t1, t2)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
case reflect.String:
|
||||||
|
p.enc = (*Buffer).enc_slice_string
|
||||||
|
p.dec = (*Buffer).dec_slice_string
|
||||||
|
p.size = size_slice_string
|
||||||
|
case reflect.Ptr:
|
||||||
|
switch t3 := t2.Elem(); t3.Kind() {
|
||||||
|
default:
|
||||||
|
fmt.Fprintf(os.Stderr, "proto: no ptr oenc for %T -> %T -> %T\n", t1, t2, t3)
|
||||||
|
break
|
||||||
|
case reflect.Struct:
|
||||||
|
p.stype = t2.Elem()
|
||||||
|
p.isMarshaler = isMarshaler(t2)
|
||||||
|
p.isUnmarshaler = isUnmarshaler(t2)
|
||||||
|
if p.Wire == "bytes" {
|
||||||
|
p.enc = (*Buffer).enc_slice_struct_message
|
||||||
|
p.dec = (*Buffer).dec_slice_struct_message
|
||||||
|
p.size = size_slice_struct_message
|
||||||
|
} else {
|
||||||
|
p.enc = (*Buffer).enc_slice_struct_group
|
||||||
|
p.dec = (*Buffer).dec_slice_struct_group
|
||||||
|
p.size = size_slice_struct_group
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case reflect.Slice:
|
||||||
|
switch t2.Elem().Kind() {
|
||||||
|
default:
|
||||||
|
fmt.Fprintf(os.Stderr, "proto: no slice elem oenc for %T -> %T -> %T\n", t1, t2, t2.Elem())
|
||||||
|
break
|
||||||
|
case reflect.Uint8:
|
||||||
|
p.enc = (*Buffer).enc_slice_slice_byte
|
||||||
|
p.dec = (*Buffer).dec_slice_slice_byte
|
||||||
|
p.size = size_slice_slice_byte
|
||||||
|
}
|
||||||
|
case reflect.Struct:
|
||||||
|
p.setSliceOfNonPointerStructs(t1)
|
||||||
|
}
|
||||||
|
|
||||||
|
case reflect.Map:
|
||||||
|
p.enc = (*Buffer).enc_new_map
|
||||||
|
p.dec = (*Buffer).dec_new_map
|
||||||
|
p.size = size_new_map
|
||||||
|
|
||||||
|
p.mtype = t1
|
||||||
|
p.mkeyprop = &Properties{}
|
||||||
|
p.mkeyprop.init(reflect.PtrTo(p.mtype.Key()), "Key", f.Tag.Get("protobuf_key"), nil, lockGetProp)
|
||||||
|
p.mvalprop = &Properties{}
|
||||||
|
vtype := p.mtype.Elem()
|
||||||
|
if vtype.Kind() != reflect.Ptr && vtype.Kind() != reflect.Slice {
|
||||||
|
// The value type is not a message (*T) or bytes ([]byte),
|
||||||
|
// so we need encoders for the pointer to this type.
|
||||||
|
vtype = reflect.PtrTo(vtype)
|
||||||
|
}
|
||||||
|
p.mvalprop.init(vtype, "Value", f.Tag.Get("protobuf_val"), nil, lockGetProp)
|
||||||
|
}
|
||||||
|
p.setTag(lockGetProp)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Properties) setTag(lockGetProp bool) {
|
||||||
|
// precalculate tag code
|
||||||
|
wire := p.WireType
|
||||||
|
if p.Packed {
|
||||||
|
wire = WireBytes
|
||||||
|
}
|
||||||
|
x := uint32(p.Tag)<<3 | uint32(wire)
|
||||||
|
i := 0
|
||||||
|
for i = 0; x > 127; i++ {
|
||||||
|
p.tagbuf[i] = 0x80 | uint8(x&0x7F)
|
||||||
|
x >>= 7
|
||||||
|
}
|
||||||
|
p.tagbuf[i] = uint8(x)
|
||||||
|
p.tagcode = p.tagbuf[0 : i+1]
|
||||||
|
|
||||||
|
if p.stype != nil {
|
||||||
|
if lockGetProp {
|
||||||
|
p.sprop = GetProperties(p.stype)
|
||||||
|
} else {
|
||||||
|
p.sprop = getPropertiesLocked(p.stype)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
marshalerType = reflect.TypeOf((*Marshaler)(nil)).Elem()
|
||||||
|
unmarshalerType = reflect.TypeOf((*Unmarshaler)(nil)).Elem()
|
||||||
|
)
|
||||||
|
|
||||||
|
// isMarshaler reports whether type t implements Marshaler.
|
||||||
|
func isMarshaler(t reflect.Type) bool {
|
||||||
|
return t.Implements(marshalerType)
|
||||||
|
}
|
||||||
|
|
||||||
|
// isUnmarshaler reports whether type t implements Unmarshaler.
|
||||||
|
func isUnmarshaler(t reflect.Type) bool {
|
||||||
|
return t.Implements(unmarshalerType)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Init populates the properties from a protocol buffer struct tag.
|
||||||
|
func (p *Properties) Init(typ reflect.Type, name, tag string, f *reflect.StructField) {
|
||||||
|
p.init(typ, name, tag, f, true)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Properties) init(typ reflect.Type, name, tag string, f *reflect.StructField, lockGetProp bool) {
|
||||||
|
// "bytes,49,opt,def=hello!"
|
||||||
|
p.Name = name
|
||||||
|
p.OrigName = name
|
||||||
|
if f != nil {
|
||||||
|
p.field = toField(f)
|
||||||
|
}
|
||||||
|
if tag == "" {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
p.Parse(tag)
|
||||||
|
p.setEncAndDec(typ, f, lockGetProp)
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
propertiesMu sync.RWMutex
|
||||||
|
propertiesMap = make(map[reflect.Type]*StructProperties)
|
||||||
|
)
|
||||||
|
|
||||||
|
// GetProperties returns the list of properties for the type represented by t.
|
||||||
|
// t must represent a generated struct type of a protocol message.
|
||||||
|
func GetProperties(t reflect.Type) *StructProperties {
|
||||||
|
if t.Kind() != reflect.Struct {
|
||||||
|
panic("proto: type must have kind struct")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Most calls to GetProperties in a long-running program will be
|
||||||
|
// retrieving details for types we have seen before.
|
||||||
|
propertiesMu.RLock()
|
||||||
|
sprop, ok := propertiesMap[t]
|
||||||
|
propertiesMu.RUnlock()
|
||||||
|
if ok {
|
||||||
|
if collectStats {
|
||||||
|
stats.Chit++
|
||||||
|
}
|
||||||
|
return sprop
|
||||||
|
}
|
||||||
|
|
||||||
|
propertiesMu.Lock()
|
||||||
|
sprop = getPropertiesLocked(t)
|
||||||
|
propertiesMu.Unlock()
|
||||||
|
return sprop
|
||||||
|
}
|
||||||
|
|
||||||
|
// getPropertiesLocked requires that propertiesMu is held.
|
||||||
|
func getPropertiesLocked(t reflect.Type) *StructProperties {
|
||||||
|
if prop, ok := propertiesMap[t]; ok {
|
||||||
|
if collectStats {
|
||||||
|
stats.Chit++
|
||||||
|
}
|
||||||
|
return prop
|
||||||
|
}
|
||||||
|
if collectStats {
|
||||||
|
stats.Cmiss++
|
||||||
|
}
|
||||||
|
|
||||||
|
prop := new(StructProperties)
|
||||||
|
// in case of recursive protos, fill this in now.
|
||||||
|
propertiesMap[t] = prop
|
||||||
|
|
||||||
|
// build properties
|
||||||
|
prop.extendable = reflect.PtrTo(t).Implements(extendableProtoType)
|
||||||
|
prop.unrecField = invalidField
|
||||||
|
prop.Prop = make([]*Properties, t.NumField())
|
||||||
|
prop.order = make([]int, t.NumField())
|
||||||
|
|
||||||
|
isOneofMessage := false
|
||||||
|
for i := 0; i < t.NumField(); i++ {
|
||||||
|
f := t.Field(i)
|
||||||
|
p := new(Properties)
|
||||||
|
name := f.Name
|
||||||
|
p.init(f.Type, name, f.Tag.Get("protobuf"), &f, false)
|
||||||
|
|
||||||
|
if f.Name == "XXX_extensions" { // special case
|
||||||
|
if len(f.Tag.Get("protobuf")) > 0 {
|
||||||
|
p.enc = (*Buffer).enc_ext_slice_byte
|
||||||
|
p.dec = nil // not needed
|
||||||
|
p.size = size_ext_slice_byte
|
||||||
|
} else {
|
||||||
|
p.enc = (*Buffer).enc_map
|
||||||
|
p.dec = nil // not needed
|
||||||
|
p.size = size_map
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if f.Name == "XXX_unrecognized" { // special case
|
||||||
|
prop.unrecField = toField(&f)
|
||||||
|
}
|
||||||
|
oneof := f.Tag.Get("protobuf_oneof") != "" // special case
|
||||||
|
if oneof {
|
||||||
|
isOneofMessage = true
|
||||||
|
}
|
||||||
|
prop.Prop[i] = p
|
||||||
|
prop.order[i] = i
|
||||||
|
if debug {
|
||||||
|
print(i, " ", f.Name, " ", t.String(), " ")
|
||||||
|
if p.Tag > 0 {
|
||||||
|
print(p.String())
|
||||||
|
}
|
||||||
|
print("\n")
|
||||||
|
}
|
||||||
|
if p.enc == nil && !strings.HasPrefix(f.Name, "XXX_") && !oneof {
|
||||||
|
fmt.Fprintln(os.Stderr, "proto: no encoder for", f.Name, f.Type.String(), "[GetProperties]")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Re-order prop.order.
|
||||||
|
sort.Sort(prop)
|
||||||
|
|
||||||
|
type oneofMessage interface {
|
||||||
|
XXX_OneofFuncs() (func(Message, *Buffer) error, func(Message, int, int, *Buffer) (bool, error), func(Message) int, []interface{})
|
||||||
|
}
|
||||||
|
if om, ok := reflect.Zero(reflect.PtrTo(t)).Interface().(oneofMessage); isOneofMessage && ok {
|
||||||
|
var oots []interface{}
|
||||||
|
prop.oneofMarshaler, prop.oneofUnmarshaler, prop.oneofSizer, oots = om.XXX_OneofFuncs()
|
||||||
|
prop.stype = t
|
||||||
|
|
||||||
|
// Interpret oneof metadata.
|
||||||
|
prop.OneofTypes = make(map[string]*OneofProperties)
|
||||||
|
for _, oot := range oots {
|
||||||
|
oop := &OneofProperties{
|
||||||
|
Type: reflect.ValueOf(oot).Type(), // *T
|
||||||
|
Prop: new(Properties),
|
||||||
|
}
|
||||||
|
sft := oop.Type.Elem().Field(0)
|
||||||
|
oop.Prop.Name = sft.Name
|
||||||
|
oop.Prop.Parse(sft.Tag.Get("protobuf"))
|
||||||
|
// There will be exactly one interface field that
|
||||||
|
// this new value is assignable to.
|
||||||
|
for i := 0; i < t.NumField(); i++ {
|
||||||
|
f := t.Field(i)
|
||||||
|
if f.Type.Kind() != reflect.Interface {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if !oop.Type.AssignableTo(f.Type) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
oop.Field = i
|
||||||
|
break
|
||||||
|
}
|
||||||
|
prop.OneofTypes[oop.Prop.OrigName] = oop
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// build required counts
|
||||||
|
// build tags
|
||||||
|
reqCount := 0
|
||||||
|
prop.decoderOrigNames = make(map[string]int)
|
||||||
|
for i, p := range prop.Prop {
|
||||||
|
if strings.HasPrefix(p.Name, "XXX_") {
|
||||||
|
// Internal fields should not appear in tags/origNames maps.
|
||||||
|
// They are handled specially when encoding and decoding.
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if p.Required {
|
||||||
|
reqCount++
|
||||||
|
}
|
||||||
|
prop.decoderTags.put(p.Tag, i)
|
||||||
|
prop.decoderOrigNames[p.OrigName] = i
|
||||||
|
}
|
||||||
|
prop.reqCount = reqCount
|
||||||
|
|
||||||
|
return prop
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return the Properties object for the x[0]'th field of the structure.
|
||||||
|
func propByIndex(t reflect.Type, x []int) *Properties {
|
||||||
|
if len(x) != 1 {
|
||||||
|
fmt.Fprintf(os.Stderr, "proto: field index dimension %d (not 1) for type %s\n", len(x), t)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
prop := GetProperties(t)
|
||||||
|
return prop.Prop[x[0]]
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the address and type of a pointer to a struct from an interface.
|
||||||
|
func getbase(pb Message) (t reflect.Type, b structPointer, err error) {
|
||||||
|
if pb == nil {
|
||||||
|
err = ErrNil
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// get the reflect type of the pointer to the struct.
|
||||||
|
t = reflect.TypeOf(pb)
|
||||||
|
// get the address of the struct.
|
||||||
|
value := reflect.ValueOf(pb)
|
||||||
|
b = toStructPointer(value)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// A global registry of enum types.
|
||||||
|
// The generated code will register the generated maps by calling RegisterEnum.
|
||||||
|
|
||||||
|
var enumValueMaps = make(map[string]map[string]int32)
|
||||||
|
var enumStringMaps = make(map[string]map[int32]string)
|
||||||
|
|
||||||
|
// RegisterEnum is called from the generated code to install the enum descriptor
|
||||||
|
// maps into the global table to aid parsing text format protocol buffers.
|
||||||
|
func RegisterEnum(typeName string, unusedNameMap map[int32]string, valueMap map[string]int32) {
|
||||||
|
if _, ok := enumValueMaps[typeName]; ok {
|
||||||
|
panic("proto: duplicate enum registered: " + typeName)
|
||||||
|
}
|
||||||
|
enumValueMaps[typeName] = valueMap
|
||||||
|
if _, ok := enumStringMaps[typeName]; ok {
|
||||||
|
panic("proto: duplicate enum registered: " + typeName)
|
||||||
|
}
|
||||||
|
enumStringMaps[typeName] = unusedNameMap
|
||||||
|
}
|
||||||
|
|
||||||
|
// EnumValueMap returns the mapping from names to integers of the
|
||||||
|
// enum type enumType, or a nil if not found.
|
||||||
|
func EnumValueMap(enumType string) map[string]int32 {
|
||||||
|
return enumValueMaps[enumType]
|
||||||
|
}
|
||||||
|
|
||||||
|
// A registry of all linked message types.
|
||||||
|
// The string is a fully-qualified proto name ("pkg.Message").
|
||||||
|
var (
|
||||||
|
protoTypes = make(map[string]reflect.Type)
|
||||||
|
revProtoTypes = make(map[reflect.Type]string)
|
||||||
|
)
|
||||||
|
|
||||||
|
// RegisterType is called from generated code and maps from the fully qualified
|
||||||
|
// proto name to the type (pointer to struct) of the protocol buffer.
|
||||||
|
func RegisterType(x Message, name string) {
|
||||||
|
if _, ok := protoTypes[name]; ok {
|
||||||
|
// TODO: Some day, make this a panic.
|
||||||
|
log.Printf("proto: duplicate proto type registered: %s", name)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
t := reflect.TypeOf(x)
|
||||||
|
protoTypes[name] = t
|
||||||
|
revProtoTypes[t] = name
|
||||||
|
}
|
||||||
|
|
||||||
|
// MessageName returns the fully-qualified proto name for the given message type.
|
||||||
|
func MessageName(x Message) string { return revProtoTypes[reflect.TypeOf(x)] }
|
||||||
|
|
||||||
|
// MessageType returns the message type (pointer to struct) for a named message.
|
||||||
|
func MessageType(name string) reflect.Type { return protoTypes[name] }
|
||||||
64
staging/src/k8s.io/client-go/1.4/_vendor/github.com/gogo/protobuf/proto/properties_gogo.go
generated
Normal file
64
staging/src/k8s.io/client-go/1.4/_vendor/github.com/gogo/protobuf/proto/properties_gogo.go
generated
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
// Copyright (c) 2013, Vastech SA (PTY) LTD. All rights reserved.
|
||||||
|
// http://github.com/gogo/protobuf/gogoproto
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions are
|
||||||
|
// met:
|
||||||
|
//
|
||||||
|
// * Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
// * Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following disclaimer
|
||||||
|
// in the documentation and/or other materials provided with the
|
||||||
|
// distribution.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
package proto
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"reflect"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (p *Properties) setCustomEncAndDec(typ reflect.Type) {
|
||||||
|
p.ctype = typ
|
||||||
|
if p.Repeated {
|
||||||
|
p.enc = (*Buffer).enc_custom_slice_bytes
|
||||||
|
p.dec = (*Buffer).dec_custom_slice_bytes
|
||||||
|
p.size = size_custom_slice_bytes
|
||||||
|
} else if typ.Kind() == reflect.Ptr {
|
||||||
|
p.enc = (*Buffer).enc_custom_bytes
|
||||||
|
p.dec = (*Buffer).dec_custom_bytes
|
||||||
|
p.size = size_custom_bytes
|
||||||
|
} else {
|
||||||
|
p.enc = (*Buffer).enc_custom_ref_bytes
|
||||||
|
p.dec = (*Buffer).dec_custom_ref_bytes
|
||||||
|
p.size = size_custom_ref_bytes
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Properties) setSliceOfNonPointerStructs(typ reflect.Type) {
|
||||||
|
t2 := typ.Elem()
|
||||||
|
p.sstype = typ
|
||||||
|
p.stype = t2
|
||||||
|
p.isMarshaler = isMarshaler(t2)
|
||||||
|
p.isUnmarshaler = isUnmarshaler(t2)
|
||||||
|
p.enc = (*Buffer).enc_slice_ref_struct_message
|
||||||
|
p.dec = (*Buffer).dec_slice_ref_struct_message
|
||||||
|
p.size = size_slice_ref_struct_message
|
||||||
|
if p.Wire != "bytes" {
|
||||||
|
fmt.Fprintf(os.Stderr, "proto: no ptr oenc for %T -> %T \n", typ, t2)
|
||||||
|
}
|
||||||
|
}
|
||||||
117
staging/src/k8s.io/client-go/1.4/_vendor/github.com/gogo/protobuf/proto/skip_gogo.go
generated
Normal file
117
staging/src/k8s.io/client-go/1.4/_vendor/github.com/gogo/protobuf/proto/skip_gogo.go
generated
Normal file
@@ -0,0 +1,117 @@
|
|||||||
|
// Copyright (c) 2013, Vastech SA (PTY) LTD. All rights reserved.
|
||||||
|
// http://github.com/gogo/protobuf/gogoproto
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions are
|
||||||
|
// met:
|
||||||
|
//
|
||||||
|
// * Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
// * Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following disclaimer
|
||||||
|
// in the documentation and/or other materials provided with the
|
||||||
|
// distribution.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
package proto
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Skip(data []byte) (n int, err error) {
|
||||||
|
l := len(data)
|
||||||
|
index := 0
|
||||||
|
for index < l {
|
||||||
|
var wire uint64
|
||||||
|
for shift := uint(0); ; shift += 7 {
|
||||||
|
if index >= l {
|
||||||
|
return 0, io.ErrUnexpectedEOF
|
||||||
|
}
|
||||||
|
b := data[index]
|
||||||
|
index++
|
||||||
|
wire |= (uint64(b) & 0x7F) << shift
|
||||||
|
if b < 0x80 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
wireType := int(wire & 0x7)
|
||||||
|
switch wireType {
|
||||||
|
case 0:
|
||||||
|
for {
|
||||||
|
if index >= l {
|
||||||
|
return 0, io.ErrUnexpectedEOF
|
||||||
|
}
|
||||||
|
index++
|
||||||
|
if data[index-1] < 0x80 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return index, nil
|
||||||
|
case 1:
|
||||||
|
index += 8
|
||||||
|
return index, nil
|
||||||
|
case 2:
|
||||||
|
var length int
|
||||||
|
for shift := uint(0); ; shift += 7 {
|
||||||
|
if index >= l {
|
||||||
|
return 0, io.ErrUnexpectedEOF
|
||||||
|
}
|
||||||
|
b := data[index]
|
||||||
|
index++
|
||||||
|
length |= (int(b) & 0x7F) << shift
|
||||||
|
if b < 0x80 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
index += length
|
||||||
|
return index, nil
|
||||||
|
case 3:
|
||||||
|
for {
|
||||||
|
var innerWire uint64
|
||||||
|
var start int = index
|
||||||
|
for shift := uint(0); ; shift += 7 {
|
||||||
|
if index >= l {
|
||||||
|
return 0, io.ErrUnexpectedEOF
|
||||||
|
}
|
||||||
|
b := data[index]
|
||||||
|
index++
|
||||||
|
innerWire |= (uint64(b) & 0x7F) << shift
|
||||||
|
if b < 0x80 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
innerWireType := int(innerWire & 0x7)
|
||||||
|
if innerWireType == 4 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
next, err := Skip(data[start:])
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
index = start + next
|
||||||
|
}
|
||||||
|
return index, nil
|
||||||
|
case 4:
|
||||||
|
return index, nil
|
||||||
|
case 5:
|
||||||
|
index += 4
|
||||||
|
return index, nil
|
||||||
|
default:
|
||||||
|
return 0, fmt.Errorf("proto: illegal wireType %d", wireType)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
panic("unreachable")
|
||||||
|
}
|
||||||
805
staging/src/k8s.io/client-go/1.4/_vendor/github.com/gogo/protobuf/proto/text.go
generated
Normal file
805
staging/src/k8s.io/client-go/1.4/_vendor/github.com/gogo/protobuf/proto/text.go
generated
Normal file
@@ -0,0 +1,805 @@
|
|||||||
|
// Extensions for Protocol Buffers to create more go like structures.
|
||||||
|
//
|
||||||
|
// Copyright (c) 2013, Vastech SA (PTY) LTD. All rights reserved.
|
||||||
|
// http://github.com/gogo/protobuf/gogoproto
|
||||||
|
//
|
||||||
|
// Go support for Protocol Buffers - Google's data interchange format
|
||||||
|
//
|
||||||
|
// Copyright 2010 The Go Authors. All rights reserved.
|
||||||
|
// https://github.com/golang/protobuf
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions are
|
||||||
|
// met:
|
||||||
|
//
|
||||||
|
// * Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
// * Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following disclaimer
|
||||||
|
// in the documentation and/or other materials provided with the
|
||||||
|
// distribution.
|
||||||
|
// * Neither the name of Google Inc. nor the names of its
|
||||||
|
// contributors may be used to endorse or promote products derived from
|
||||||
|
// this software without specific prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
package proto
|
||||||
|
|
||||||
|
// Functions for writing the text protocol buffer format.
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bufio"
|
||||||
|
"bytes"
|
||||||
|
"encoding"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"log"
|
||||||
|
"math"
|
||||||
|
"reflect"
|
||||||
|
"sort"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
newline = []byte("\n")
|
||||||
|
spaces = []byte(" ")
|
||||||
|
gtNewline = []byte(">\n")
|
||||||
|
endBraceNewline = []byte("}\n")
|
||||||
|
backslashN = []byte{'\\', 'n'}
|
||||||
|
backslashR = []byte{'\\', 'r'}
|
||||||
|
backslashT = []byte{'\\', 't'}
|
||||||
|
backslashDQ = []byte{'\\', '"'}
|
||||||
|
backslashBS = []byte{'\\', '\\'}
|
||||||
|
posInf = []byte("inf")
|
||||||
|
negInf = []byte("-inf")
|
||||||
|
nan = []byte("nan")
|
||||||
|
)
|
||||||
|
|
||||||
|
type writer interface {
|
||||||
|
io.Writer
|
||||||
|
WriteByte(byte) error
|
||||||
|
}
|
||||||
|
|
||||||
|
// textWriter is an io.Writer that tracks its indentation level.
|
||||||
|
type textWriter struct {
|
||||||
|
ind int
|
||||||
|
complete bool // if the current position is a complete line
|
||||||
|
compact bool // whether to write out as a one-liner
|
||||||
|
w writer
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *textWriter) WriteString(s string) (n int, err error) {
|
||||||
|
if !strings.Contains(s, "\n") {
|
||||||
|
if !w.compact && w.complete {
|
||||||
|
w.writeIndent()
|
||||||
|
}
|
||||||
|
w.complete = false
|
||||||
|
return io.WriteString(w.w, s)
|
||||||
|
}
|
||||||
|
// WriteString is typically called without newlines, so this
|
||||||
|
// codepath and its copy are rare. We copy to avoid
|
||||||
|
// duplicating all of Write's logic here.
|
||||||
|
return w.Write([]byte(s))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *textWriter) Write(p []byte) (n int, err error) {
|
||||||
|
newlines := bytes.Count(p, newline)
|
||||||
|
if newlines == 0 {
|
||||||
|
if !w.compact && w.complete {
|
||||||
|
w.writeIndent()
|
||||||
|
}
|
||||||
|
n, err = w.w.Write(p)
|
||||||
|
w.complete = false
|
||||||
|
return n, err
|
||||||
|
}
|
||||||
|
|
||||||
|
frags := bytes.SplitN(p, newline, newlines+1)
|
||||||
|
if w.compact {
|
||||||
|
for i, frag := range frags {
|
||||||
|
if i > 0 {
|
||||||
|
if err := w.w.WriteByte(' '); err != nil {
|
||||||
|
return n, err
|
||||||
|
}
|
||||||
|
n++
|
||||||
|
}
|
||||||
|
nn, err := w.w.Write(frag)
|
||||||
|
n += nn
|
||||||
|
if err != nil {
|
||||||
|
return n, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return n, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
for i, frag := range frags {
|
||||||
|
if w.complete {
|
||||||
|
w.writeIndent()
|
||||||
|
}
|
||||||
|
nn, err := w.w.Write(frag)
|
||||||
|
n += nn
|
||||||
|
if err != nil {
|
||||||
|
return n, err
|
||||||
|
}
|
||||||
|
if i+1 < len(frags) {
|
||||||
|
if err := w.w.WriteByte('\n'); err != nil {
|
||||||
|
return n, err
|
||||||
|
}
|
||||||
|
n++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
w.complete = len(frags[len(frags)-1]) == 0
|
||||||
|
return n, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *textWriter) WriteByte(c byte) error {
|
||||||
|
if w.compact && c == '\n' {
|
||||||
|
c = ' '
|
||||||
|
}
|
||||||
|
if !w.compact && w.complete {
|
||||||
|
w.writeIndent()
|
||||||
|
}
|
||||||
|
err := w.w.WriteByte(c)
|
||||||
|
w.complete = c == '\n'
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *textWriter) indent() { w.ind++ }
|
||||||
|
|
||||||
|
func (w *textWriter) unindent() {
|
||||||
|
if w.ind == 0 {
|
||||||
|
log.Printf("proto: textWriter unindented too far")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
w.ind--
|
||||||
|
}
|
||||||
|
|
||||||
|
func writeName(w *textWriter, props *Properties) error {
|
||||||
|
if _, err := w.WriteString(props.OrigName); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if props.Wire != "group" {
|
||||||
|
return w.WriteByte(':')
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// raw is the interface satisfied by RawMessage.
|
||||||
|
type raw interface {
|
||||||
|
Bytes() []byte
|
||||||
|
}
|
||||||
|
|
||||||
|
func writeStruct(w *textWriter, sv reflect.Value) error {
|
||||||
|
st := sv.Type()
|
||||||
|
sprops := GetProperties(st)
|
||||||
|
for i := 0; i < sv.NumField(); i++ {
|
||||||
|
fv := sv.Field(i)
|
||||||
|
props := sprops.Prop[i]
|
||||||
|
name := st.Field(i).Name
|
||||||
|
|
||||||
|
if strings.HasPrefix(name, "XXX_") {
|
||||||
|
// There are two XXX_ fields:
|
||||||
|
// XXX_unrecognized []byte
|
||||||
|
// XXX_extensions map[int32]proto.Extension
|
||||||
|
// The first is handled here;
|
||||||
|
// the second is handled at the bottom of this function.
|
||||||
|
if name == "XXX_unrecognized" && !fv.IsNil() {
|
||||||
|
if err := writeUnknownStruct(w, fv.Interface().([]byte)); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if fv.Kind() == reflect.Ptr && fv.IsNil() {
|
||||||
|
// Field not filled in. This could be an optional field or
|
||||||
|
// a required field that wasn't filled in. Either way, there
|
||||||
|
// isn't anything we can show for it.
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if fv.Kind() == reflect.Slice && fv.IsNil() {
|
||||||
|
// Repeated field that is empty, or a bytes field that is unused.
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if props.Repeated && fv.Kind() == reflect.Slice {
|
||||||
|
// Repeated field.
|
||||||
|
for j := 0; j < fv.Len(); j++ {
|
||||||
|
if err := writeName(w, props); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if !w.compact {
|
||||||
|
if err := w.WriteByte(' '); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
v := fv.Index(j)
|
||||||
|
if v.Kind() == reflect.Ptr && v.IsNil() {
|
||||||
|
// A nil message in a repeated field is not valid,
|
||||||
|
// but we can handle that more gracefully than panicking.
|
||||||
|
if _, err := w.Write([]byte("<nil>\n")); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if len(props.Enum) > 0 {
|
||||||
|
if err := writeEnum(w, v, props); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
} else if err := writeAny(w, v, props); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err := w.WriteByte('\n'); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if fv.Kind() == reflect.Map {
|
||||||
|
// Map fields are rendered as a repeated struct with key/value fields.
|
||||||
|
keys := fv.MapKeys()
|
||||||
|
sort.Sort(mapKeys(keys))
|
||||||
|
for _, key := range keys {
|
||||||
|
val := fv.MapIndex(key)
|
||||||
|
if err := writeName(w, props); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if !w.compact {
|
||||||
|
if err := w.WriteByte(' '); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// open struct
|
||||||
|
if err := w.WriteByte('<'); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if !w.compact {
|
||||||
|
if err := w.WriteByte('\n'); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
w.indent()
|
||||||
|
// key
|
||||||
|
if _, err := w.WriteString("key:"); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if !w.compact {
|
||||||
|
if err := w.WriteByte(' '); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if err := writeAny(w, key, props.mkeyprop); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err := w.WriteByte('\n'); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
// nil values aren't legal, but we can avoid panicking because of them.
|
||||||
|
if val.Kind() != reflect.Ptr || !val.IsNil() {
|
||||||
|
// value
|
||||||
|
if _, err := w.WriteString("value:"); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if !w.compact {
|
||||||
|
if err := w.WriteByte(' '); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if err := writeAny(w, val, props.mvalprop); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err := w.WriteByte('\n'); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// close struct
|
||||||
|
w.unindent()
|
||||||
|
if err := w.WriteByte('>'); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err := w.WriteByte('\n'); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if props.proto3 && fv.Kind() == reflect.Slice && fv.Len() == 0 {
|
||||||
|
// empty bytes field
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if props.proto3 && fv.Kind() != reflect.Ptr && fv.Kind() != reflect.Slice {
|
||||||
|
// proto3 non-repeated scalar field; skip if zero value
|
||||||
|
if isProto3Zero(fv) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if fv.Kind() == reflect.Interface {
|
||||||
|
// Check if it is a oneof.
|
||||||
|
if st.Field(i).Tag.Get("protobuf_oneof") != "" {
|
||||||
|
// fv is nil, or holds a pointer to generated struct.
|
||||||
|
// That generated struct has exactly one field,
|
||||||
|
// which has a protobuf struct tag.
|
||||||
|
if fv.IsNil() {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
inner := fv.Elem().Elem() // interface -> *T -> T
|
||||||
|
tag := inner.Type().Field(0).Tag.Get("protobuf")
|
||||||
|
props = new(Properties) // Overwrite the outer props var, but not its pointee.
|
||||||
|
props.Parse(tag)
|
||||||
|
// Write the value in the oneof, not the oneof itself.
|
||||||
|
fv = inner.Field(0)
|
||||||
|
|
||||||
|
// Special case to cope with malformed messages gracefully:
|
||||||
|
// If the value in the oneof is a nil pointer, don't panic
|
||||||
|
// in writeAny.
|
||||||
|
if fv.Kind() == reflect.Ptr && fv.IsNil() {
|
||||||
|
// Use errors.New so writeAny won't render quotes.
|
||||||
|
msg := errors.New("/* nil */")
|
||||||
|
fv = reflect.ValueOf(&msg).Elem()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := writeName(w, props); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if !w.compact {
|
||||||
|
if err := w.WriteByte(' '); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if b, ok := fv.Interface().(raw); ok {
|
||||||
|
if err := writeRaw(w, b.Bytes()); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(props.Enum) > 0 {
|
||||||
|
if err := writeEnum(w, fv, props); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
} else if err := writeAny(w, fv, props); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := w.WriteByte('\n'); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Extensions (the XXX_extensions field).
|
||||||
|
pv := sv
|
||||||
|
if pv.CanAddr() {
|
||||||
|
pv = sv.Addr()
|
||||||
|
} else {
|
||||||
|
pv = reflect.New(sv.Type())
|
||||||
|
pv.Elem().Set(sv)
|
||||||
|
}
|
||||||
|
if pv.Type().Implements(extendableProtoType) {
|
||||||
|
if err := writeExtensions(w, pv); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// writeRaw writes an uninterpreted raw message.
|
||||||
|
func writeRaw(w *textWriter, b []byte) error {
|
||||||
|
if err := w.WriteByte('<'); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if !w.compact {
|
||||||
|
if err := w.WriteByte('\n'); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
w.indent()
|
||||||
|
if err := writeUnknownStruct(w, b); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
w.unindent()
|
||||||
|
if err := w.WriteByte('>'); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// writeAny writes an arbitrary field.
|
||||||
|
func writeAny(w *textWriter, v reflect.Value, props *Properties) error {
|
||||||
|
v = reflect.Indirect(v)
|
||||||
|
|
||||||
|
if props != nil && len(props.CustomType) > 0 {
|
||||||
|
custom, ok := v.Interface().(Marshaler)
|
||||||
|
if ok {
|
||||||
|
data, err := custom.Marshal()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err := writeString(w, string(data)); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Floats have special cases.
|
||||||
|
if v.Kind() == reflect.Float32 || v.Kind() == reflect.Float64 {
|
||||||
|
x := v.Float()
|
||||||
|
var b []byte
|
||||||
|
switch {
|
||||||
|
case math.IsInf(x, 1):
|
||||||
|
b = posInf
|
||||||
|
case math.IsInf(x, -1):
|
||||||
|
b = negInf
|
||||||
|
case math.IsNaN(x):
|
||||||
|
b = nan
|
||||||
|
}
|
||||||
|
if b != nil {
|
||||||
|
_, err := w.Write(b)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
// Other values are handled below.
|
||||||
|
}
|
||||||
|
|
||||||
|
// We don't attempt to serialise every possible value type; only those
|
||||||
|
// that can occur in protocol buffers.
|
||||||
|
switch v.Kind() {
|
||||||
|
case reflect.Slice:
|
||||||
|
// Should only be a []byte; repeated fields are handled in writeStruct.
|
||||||
|
if err := writeString(w, string(v.Bytes())); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
case reflect.String:
|
||||||
|
if err := writeString(w, v.String()); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
case reflect.Struct:
|
||||||
|
// Required/optional group/message.
|
||||||
|
var bra, ket byte = '<', '>'
|
||||||
|
if props != nil && props.Wire == "group" {
|
||||||
|
bra, ket = '{', '}'
|
||||||
|
}
|
||||||
|
if err := w.WriteByte(bra); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if !w.compact {
|
||||||
|
if err := w.WriteByte('\n'); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
w.indent()
|
||||||
|
if tm, ok := v.Interface().(encoding.TextMarshaler); ok {
|
||||||
|
text, err := tm.MarshalText()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if _, err = w.Write(text); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
} else if err := writeStruct(w, v); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
w.unindent()
|
||||||
|
if err := w.WriteByte(ket); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
_, err := fmt.Fprint(w, v.Interface())
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// equivalent to C's isprint.
|
||||||
|
func isprint(c byte) bool {
|
||||||
|
return c >= 0x20 && c < 0x7f
|
||||||
|
}
|
||||||
|
|
||||||
|
// writeString writes a string in the protocol buffer text format.
|
||||||
|
// It is similar to strconv.Quote except we don't use Go escape sequences,
|
||||||
|
// we treat the string as a byte sequence, and we use octal escapes.
|
||||||
|
// These differences are to maintain interoperability with the other
|
||||||
|
// languages' implementations of the text format.
|
||||||
|
func writeString(w *textWriter, s string) error {
|
||||||
|
// use WriteByte here to get any needed indent
|
||||||
|
if err := w.WriteByte('"'); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
// Loop over the bytes, not the runes.
|
||||||
|
for i := 0; i < len(s); i++ {
|
||||||
|
var err error
|
||||||
|
// Divergence from C++: we don't escape apostrophes.
|
||||||
|
// There's no need to escape them, and the C++ parser
|
||||||
|
// copes with a naked apostrophe.
|
||||||
|
switch c := s[i]; c {
|
||||||
|
case '\n':
|
||||||
|
_, err = w.w.Write(backslashN)
|
||||||
|
case '\r':
|
||||||
|
_, err = w.w.Write(backslashR)
|
||||||
|
case '\t':
|
||||||
|
_, err = w.w.Write(backslashT)
|
||||||
|
case '"':
|
||||||
|
_, err = w.w.Write(backslashDQ)
|
||||||
|
case '\\':
|
||||||
|
_, err = w.w.Write(backslashBS)
|
||||||
|
default:
|
||||||
|
if isprint(c) {
|
||||||
|
err = w.w.WriteByte(c)
|
||||||
|
} else {
|
||||||
|
_, err = fmt.Fprintf(w.w, "\\%03o", c)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return w.WriteByte('"')
|
||||||
|
}
|
||||||
|
|
||||||
|
func writeUnknownStruct(w *textWriter, data []byte) (err error) {
|
||||||
|
if !w.compact {
|
||||||
|
if _, err := fmt.Fprintf(w, "/* %d unknown bytes */\n", len(data)); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
b := NewBuffer(data)
|
||||||
|
for b.index < len(b.buf) {
|
||||||
|
x, err := b.DecodeVarint()
|
||||||
|
if err != nil {
|
||||||
|
_, ferr := fmt.Fprintf(w, "/* %v */\n", err)
|
||||||
|
return ferr
|
||||||
|
}
|
||||||
|
wire, tag := x&7, x>>3
|
||||||
|
if wire == WireEndGroup {
|
||||||
|
w.unindent()
|
||||||
|
if _, werr := w.Write(endBraceNewline); werr != nil {
|
||||||
|
return werr
|
||||||
|
}
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if _, ferr := fmt.Fprint(w, tag); ferr != nil {
|
||||||
|
return ferr
|
||||||
|
}
|
||||||
|
if wire != WireStartGroup {
|
||||||
|
if err = w.WriteByte(':'); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !w.compact || wire == WireStartGroup {
|
||||||
|
if err = w.WriteByte(' '); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
switch wire {
|
||||||
|
case WireBytes:
|
||||||
|
buf, e := b.DecodeRawBytes(false)
|
||||||
|
if e == nil {
|
||||||
|
_, err = fmt.Fprintf(w, "%q", buf)
|
||||||
|
} else {
|
||||||
|
_, err = fmt.Fprintf(w, "/* %v */", e)
|
||||||
|
}
|
||||||
|
case WireFixed32:
|
||||||
|
x, err = b.DecodeFixed32()
|
||||||
|
err = writeUnknownInt(w, x, err)
|
||||||
|
case WireFixed64:
|
||||||
|
x, err = b.DecodeFixed64()
|
||||||
|
err = writeUnknownInt(w, x, err)
|
||||||
|
case WireStartGroup:
|
||||||
|
err = w.WriteByte('{')
|
||||||
|
w.indent()
|
||||||
|
case WireVarint:
|
||||||
|
x, err = b.DecodeVarint()
|
||||||
|
err = writeUnknownInt(w, x, err)
|
||||||
|
default:
|
||||||
|
_, err = fmt.Fprintf(w, "/* unknown wire type %d */", wire)
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err := w.WriteByte('\n'); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func writeUnknownInt(w *textWriter, x uint64, err error) error {
|
||||||
|
if err == nil {
|
||||||
|
_, err = fmt.Fprint(w, x)
|
||||||
|
} else {
|
||||||
|
_, err = fmt.Fprintf(w, "/* %v */", err)
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
type int32Slice []int32
|
||||||
|
|
||||||
|
func (s int32Slice) Len() int { return len(s) }
|
||||||
|
func (s int32Slice) Less(i, j int) bool { return s[i] < s[j] }
|
||||||
|
func (s int32Slice) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
|
||||||
|
|
||||||
|
// writeExtensions writes all the extensions in pv.
|
||||||
|
// pv is assumed to be a pointer to a protocol message struct that is extendable.
|
||||||
|
func writeExtensions(w *textWriter, pv reflect.Value) error {
|
||||||
|
emap := extensionMaps[pv.Type().Elem()]
|
||||||
|
ep := pv.Interface().(extendableProto)
|
||||||
|
|
||||||
|
// Order the extensions by ID.
|
||||||
|
// This isn't strictly necessary, but it will give us
|
||||||
|
// canonical output, which will also make testing easier.
|
||||||
|
var m map[int32]Extension
|
||||||
|
if em, ok := ep.(extensionsMap); ok {
|
||||||
|
m = em.ExtensionMap()
|
||||||
|
} else if em, ok := ep.(extensionsBytes); ok {
|
||||||
|
eb := em.GetExtensions()
|
||||||
|
var err error
|
||||||
|
m, err = BytesToExtensionsMap(*eb)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ids := make([]int32, 0, len(m))
|
||||||
|
for id := range m {
|
||||||
|
ids = append(ids, id)
|
||||||
|
}
|
||||||
|
sort.Sort(int32Slice(ids))
|
||||||
|
|
||||||
|
for _, extNum := range ids {
|
||||||
|
ext := m[extNum]
|
||||||
|
var desc *ExtensionDesc
|
||||||
|
if emap != nil {
|
||||||
|
desc = emap[extNum]
|
||||||
|
}
|
||||||
|
if desc == nil {
|
||||||
|
// Unknown extension.
|
||||||
|
if err := writeUnknownStruct(w, ext.enc); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
pb, err := GetExtension(ep, desc)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed getting extension: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Repeated extensions will appear as a slice.
|
||||||
|
if !desc.repeated() {
|
||||||
|
if err := writeExtension(w, desc.Name, pb); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
v := reflect.ValueOf(pb)
|
||||||
|
for i := 0; i < v.Len(); i++ {
|
||||||
|
if err := writeExtension(w, desc.Name, v.Index(i).Interface()); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func writeExtension(w *textWriter, name string, pb interface{}) error {
|
||||||
|
if _, err := fmt.Fprintf(w, "[%s]:", name); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if !w.compact {
|
||||||
|
if err := w.WriteByte(' '); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if err := writeAny(w, reflect.ValueOf(pb), nil); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err := w.WriteByte('\n'); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *textWriter) writeIndent() {
|
||||||
|
if !w.complete {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
remain := w.ind * 2
|
||||||
|
for remain > 0 {
|
||||||
|
n := remain
|
||||||
|
if n > len(spaces) {
|
||||||
|
n = len(spaces)
|
||||||
|
}
|
||||||
|
w.w.Write(spaces[:n])
|
||||||
|
remain -= n
|
||||||
|
}
|
||||||
|
w.complete = false
|
||||||
|
}
|
||||||
|
|
||||||
|
// TextMarshaler is a configurable text format marshaler.
|
||||||
|
type TextMarshaler struct {
|
||||||
|
Compact bool // use compact text format (one line).
|
||||||
|
}
|
||||||
|
|
||||||
|
// Marshal writes a given protocol buffer in text format.
|
||||||
|
// The only errors returned are from w.
|
||||||
|
func (m *TextMarshaler) Marshal(w io.Writer, pb Message) error {
|
||||||
|
val := reflect.ValueOf(pb)
|
||||||
|
if pb == nil || val.IsNil() {
|
||||||
|
w.Write([]byte("<nil>"))
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
var bw *bufio.Writer
|
||||||
|
ww, ok := w.(writer)
|
||||||
|
if !ok {
|
||||||
|
bw = bufio.NewWriter(w)
|
||||||
|
ww = bw
|
||||||
|
}
|
||||||
|
aw := &textWriter{
|
||||||
|
w: ww,
|
||||||
|
complete: true,
|
||||||
|
compact: m.Compact,
|
||||||
|
}
|
||||||
|
|
||||||
|
if tm, ok := pb.(encoding.TextMarshaler); ok {
|
||||||
|
text, err := tm.MarshalText()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if _, err = aw.Write(text); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if bw != nil {
|
||||||
|
return bw.Flush()
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
// Dereference the received pointer so we don't have outer < and >.
|
||||||
|
v := reflect.Indirect(val)
|
||||||
|
if err := writeStruct(aw, v); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if bw != nil {
|
||||||
|
return bw.Flush()
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Text is the same as Marshal, but returns the string directly.
|
||||||
|
func (m *TextMarshaler) Text(pb Message) string {
|
||||||
|
var buf bytes.Buffer
|
||||||
|
m.Marshal(&buf, pb)
|
||||||
|
return buf.String()
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
defaultTextMarshaler = TextMarshaler{}
|
||||||
|
compactTextMarshaler = TextMarshaler{Compact: true}
|
||||||
|
)
|
||||||
|
|
||||||
|
// TODO: consider removing some of the Marshal functions below.
|
||||||
|
|
||||||
|
// MarshalText writes a given protocol buffer in text format.
|
||||||
|
// The only errors returned are from w.
|
||||||
|
func MarshalText(w io.Writer, pb Message) error { return defaultTextMarshaler.Marshal(w, pb) }
|
||||||
|
|
||||||
|
// MarshalTextString is the same as MarshalText, but returns the string directly.
|
||||||
|
func MarshalTextString(pb Message) string { return defaultTextMarshaler.Text(pb) }
|
||||||
|
|
||||||
|
// CompactText writes a given protocol buffer in compact text format (one line).
|
||||||
|
func CompactText(w io.Writer, pb Message) error { return compactTextMarshaler.Marshal(w, pb) }
|
||||||
|
|
||||||
|
// CompactTextString is the same as CompactText, but returns the string directly.
|
||||||
|
func CompactTextString(pb Message) string { return compactTextMarshaler.Text(pb) }
|
||||||
55
staging/src/k8s.io/client-go/1.4/_vendor/github.com/gogo/protobuf/proto/text_gogo.go
generated
Normal file
55
staging/src/k8s.io/client-go/1.4/_vendor/github.com/gogo/protobuf/proto/text_gogo.go
generated
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
// Copyright (c) 2013, Vastech SA (PTY) LTD. All rights reserved.
|
||||||
|
// http://github.com/gogo/protobuf/gogoproto
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions are
|
||||||
|
// met:
|
||||||
|
//
|
||||||
|
// * Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
// * Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following disclaimer
|
||||||
|
// in the documentation and/or other materials provided with the
|
||||||
|
// distribution.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
package proto
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"reflect"
|
||||||
|
)
|
||||||
|
|
||||||
|
func writeEnum(w *textWriter, v reflect.Value, props *Properties) error {
|
||||||
|
m, ok := enumStringMaps[props.Enum]
|
||||||
|
if !ok {
|
||||||
|
if err := writeAny(w, v, props); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
key := int32(0)
|
||||||
|
if v.Kind() == reflect.Ptr {
|
||||||
|
key = int32(v.Elem().Int())
|
||||||
|
} else {
|
||||||
|
key = int32(v.Int())
|
||||||
|
}
|
||||||
|
s, ok := m[key]
|
||||||
|
if !ok {
|
||||||
|
if err := writeAny(w, v, props); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_, err := fmt.Fprint(w, s)
|
||||||
|
return err
|
||||||
|
}
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user