aboutsummaryrefslogtreecommitdiffstats
path: root/vendor/github.com/aws/smithy-go/encoding
diff options
context:
space:
mode:
authorvitalyisaev <vitalyisaev@ydb.tech>2023-12-12 21:55:07 +0300
committervitalyisaev <vitalyisaev@ydb.tech>2023-12-12 22:25:10 +0300
commit4967f99474a4040ba150eb04995de06342252718 (patch)
treec9c118836513a8fab6e9fcfb25be5d404338bca7 /vendor/github.com/aws/smithy-go/encoding
parent2ce9cccb9b0bdd4cd7a3491dc5cbf8687cda51de (diff)
downloadydb-4967f99474a4040ba150eb04995de06342252718.tar.gz
YQ Connector: prepare code base for S3 integration
1. Кодовая база Коннектора переписана с помощью Go дженериков так, чтобы добавление нового источника данных (в частности S3 + csv) максимально переиспользовало имеющийся код (чтобы сохранялась логика нарезания на блоки данных, учёт трафика и пр.) 2. API Connector расширено для работы с S3, но ещё пока не протестировано.
Diffstat (limited to 'vendor/github.com/aws/smithy-go/encoding')
-rw-r--r--vendor/github.com/aws/smithy-go/encoding/doc.go4
-rw-r--r--vendor/github.com/aws/smithy-go/encoding/encoding.go40
-rw-r--r--vendor/github.com/aws/smithy-go/encoding/httpbinding/encode.go123
-rw-r--r--vendor/github.com/aws/smithy-go/encoding/httpbinding/encode_test.go146
-rw-r--r--vendor/github.com/aws/smithy-go/encoding/httpbinding/gotest/ya.make5
-rw-r--r--vendor/github.com/aws/smithy-go/encoding/httpbinding/header.go122
-rw-r--r--vendor/github.com/aws/smithy-go/encoding/httpbinding/header_test.go295
-rw-r--r--vendor/github.com/aws/smithy-go/encoding/httpbinding/path_replace.go108
-rw-r--r--vendor/github.com/aws/smithy-go/encoding/httpbinding/path_replace_test.go67
-rw-r--r--vendor/github.com/aws/smithy-go/encoding/httpbinding/query.go107
-rw-r--r--vendor/github.com/aws/smithy-go/encoding/httpbinding/query_test.go234
-rw-r--r--vendor/github.com/aws/smithy-go/encoding/httpbinding/shared_test.go36
-rw-r--r--vendor/github.com/aws/smithy-go/encoding/httpbinding/uri.go111
-rw-r--r--vendor/github.com/aws/smithy-go/encoding/httpbinding/uri_test.go198
-rw-r--r--vendor/github.com/aws/smithy-go/encoding/httpbinding/ya.make26
-rw-r--r--vendor/github.com/aws/smithy-go/encoding/json/array.go35
-rw-r--r--vendor/github.com/aws/smithy-go/encoding/json/array_test.go21
-rw-r--r--vendor/github.com/aws/smithy-go/encoding/json/constants.go15
-rw-r--r--vendor/github.com/aws/smithy-go/encoding/json/decoder_util.go139
-rw-r--r--vendor/github.com/aws/smithy-go/encoding/json/decoder_util_test.go65
-rw-r--r--vendor/github.com/aws/smithy-go/encoding/json/encoder.go30
-rw-r--r--vendor/github.com/aws/smithy-go/encoding/json/encoder_test.go34
-rw-r--r--vendor/github.com/aws/smithy-go/encoding/json/escape.go198
-rw-r--r--vendor/github.com/aws/smithy-go/encoding/json/escape_test.go49
-rw-r--r--vendor/github.com/aws/smithy-go/encoding/json/gotest/ya.make5
-rw-r--r--vendor/github.com/aws/smithy-go/encoding/json/object.go40
-rw-r--r--vendor/github.com/aws/smithy-go/encoding/json/object_test.go34
-rw-r--r--vendor/github.com/aws/smithy-go/encoding/json/value.go149
-rw-r--r--vendor/github.com/aws/smithy-go/encoding/json/value_test.go156
-rw-r--r--vendor/github.com/aws/smithy-go/encoding/json/ya.make29
-rw-r--r--vendor/github.com/aws/smithy-go/encoding/xml/array.go49
-rw-r--r--vendor/github.com/aws/smithy-go/encoding/xml/array_test.go52
-rw-r--r--vendor/github.com/aws/smithy-go/encoding/xml/constants.go10
-rw-r--r--vendor/github.com/aws/smithy-go/encoding/xml/doc.go49
-rw-r--r--vendor/github.com/aws/smithy-go/encoding/xml/element.go91
-rw-r--r--vendor/github.com/aws/smithy-go/encoding/xml/encoder.go51
-rw-r--r--vendor/github.com/aws/smithy-go/encoding/xml/encoder_test.go560
-rw-r--r--vendor/github.com/aws/smithy-go/encoding/xml/error_utils.go51
-rw-r--r--vendor/github.com/aws/smithy-go/encoding/xml/error_utils_test.go62
-rw-r--r--vendor/github.com/aws/smithy-go/encoding/xml/escape.go137
-rw-r--r--vendor/github.com/aws/smithy-go/encoding/xml/gotest/ya.make5
-rw-r--r--vendor/github.com/aws/smithy-go/encoding/xml/map.go53
-rw-r--r--vendor/github.com/aws/smithy-go/encoding/xml/map_test.go77
-rw-r--r--vendor/github.com/aws/smithy-go/encoding/xml/value.go302
-rw-r--r--vendor/github.com/aws/smithy-go/encoding/xml/value_test.go212
-rw-r--r--vendor/github.com/aws/smithy-go/encoding/xml/xml_decoder.go154
-rw-r--r--vendor/github.com/aws/smithy-go/encoding/xml/xml_decoder_test.go329
-rw-r--r--vendor/github.com/aws/smithy-go/encoding/xml/ya.make32
-rw-r--r--vendor/github.com/aws/smithy-go/encoding/ya.make16
49 files changed, 4913 insertions, 0 deletions
diff --git a/vendor/github.com/aws/smithy-go/encoding/doc.go b/vendor/github.com/aws/smithy-go/encoding/doc.go
new file mode 100644
index 0000000000..792fdfa08b
--- /dev/null
+++ b/vendor/github.com/aws/smithy-go/encoding/doc.go
@@ -0,0 +1,4 @@
+// Package encoding provides utilities for encoding values for specific
+// document encodings.
+
+package encoding
diff --git a/vendor/github.com/aws/smithy-go/encoding/encoding.go b/vendor/github.com/aws/smithy-go/encoding/encoding.go
new file mode 100644
index 0000000000..2fdfb52250
--- /dev/null
+++ b/vendor/github.com/aws/smithy-go/encoding/encoding.go
@@ -0,0 +1,40 @@
+package encoding
+
+import (
+ "fmt"
+ "math"
+ "strconv"
+)
+
+// EncodeFloat encodes a float value as per the stdlib encoder for json and xml protocol
+// This encodes a float value into dst while attempting to conform to ES6 ToString for Numbers
+//
+// Based on encoding/json floatEncoder from the Go Standard Library
+// https://golang.org/src/encoding/json/encode.go
+func EncodeFloat(dst []byte, v float64, bits int) []byte {
+ if math.IsInf(v, 0) || math.IsNaN(v) {
+ panic(fmt.Sprintf("invalid float value: %s", strconv.FormatFloat(v, 'g', -1, bits)))
+ }
+
+ abs := math.Abs(v)
+ fmt := byte('f')
+
+ if abs != 0 {
+ if bits == 64 && (abs < 1e-6 || abs >= 1e21) || bits == 32 && (float32(abs) < 1e-6 || float32(abs) >= 1e21) {
+ fmt = 'e'
+ }
+ }
+
+ dst = strconv.AppendFloat(dst, v, fmt, -1, bits)
+
+ if fmt == 'e' {
+ // clean up e-09 to e-9
+ n := len(dst)
+ if n >= 4 && dst[n-4] == 'e' && dst[n-3] == '-' && dst[n-2] == '0' {
+ dst[n-2] = dst[n-1]
+ dst = dst[:n-1]
+ }
+ }
+
+ return dst
+}
diff --git a/vendor/github.com/aws/smithy-go/encoding/httpbinding/encode.go b/vendor/github.com/aws/smithy-go/encoding/httpbinding/encode.go
new file mode 100644
index 0000000000..543e7cf038
--- /dev/null
+++ b/vendor/github.com/aws/smithy-go/encoding/httpbinding/encode.go
@@ -0,0 +1,123 @@
+package httpbinding
+
+import (
+ "fmt"
+ "net/http"
+ "net/url"
+ "strconv"
+ "strings"
+)
+
+const (
+ contentLengthHeader = "Content-Length"
+ floatNaN = "NaN"
+ floatInfinity = "Infinity"
+ floatNegInfinity = "-Infinity"
+)
+
+// An Encoder provides encoding of REST URI path, query, and header components
+// of an HTTP request. Can also encode a stream as the payload.
+//
+// Does not support SetFields.
+type Encoder struct {
+ path, rawPath, pathBuffer []byte
+
+ query url.Values
+ header http.Header
+}
+
+// NewEncoder creates a new encoder from the passed in request. It assumes that
+// raw path contains no valuable information at this point, so it passes in path
+// as path and raw path for subsequent trans
+func NewEncoder(path, query string, headers http.Header) (*Encoder, error) {
+ return NewEncoderWithRawPath(path, path, query, headers)
+}
+
+// NewHTTPBindingEncoder creates a new encoder from the passed in request. All query and
+// header values will be added on top of the request's existing values. Overwriting
+// duplicate values.
+func NewEncoderWithRawPath(path, rawPath, query string, headers http.Header) (*Encoder, error) {
+ parseQuery, err := url.ParseQuery(query)
+ if err != nil {
+ return nil, fmt.Errorf("failed to parse query string: %w", err)
+ }
+
+ e := &Encoder{
+ path: []byte(path),
+ rawPath: []byte(rawPath),
+ query: parseQuery,
+ header: headers.Clone(),
+ }
+
+ return e, nil
+}
+
+// Encode returns a REST protocol encoder for encoding HTTP bindings.
+//
+// Due net/http requiring `Content-Length` to be specified on the http.Request#ContentLength directly. Encode
+// will look for whether the header is present, and if so will remove it and set the respective value on http.Request.
+//
+// Returns any error occurring during encoding.
+func (e *Encoder) Encode(req *http.Request) (*http.Request, error) {
+ req.URL.Path, req.URL.RawPath = string(e.path), string(e.rawPath)
+ req.URL.RawQuery = e.query.Encode()
+
+ // net/http ignores Content-Length header and requires it to be set on http.Request
+ if v := e.header.Get(contentLengthHeader); len(v) > 0 {
+ iv, err := strconv.ParseInt(v, 10, 64)
+ if err != nil {
+ return nil, err
+ }
+ req.ContentLength = iv
+ e.header.Del(contentLengthHeader)
+ }
+
+ req.Header = e.header
+
+ return req, nil
+}
+
+// AddHeader returns a HeaderValue for appending to the given header name
+func (e *Encoder) AddHeader(key string) HeaderValue {
+ return newHeaderValue(e.header, key, true)
+}
+
+// SetHeader returns a HeaderValue for setting the given header name
+func (e *Encoder) SetHeader(key string) HeaderValue {
+ return newHeaderValue(e.header, key, false)
+}
+
+// Headers returns a Header used for encoding headers with the given prefix
+func (e *Encoder) Headers(prefix string) Headers {
+ return Headers{
+ header: e.header,
+ prefix: strings.TrimSpace(prefix),
+ }
+}
+
+// HasHeader returns if a header with the key specified exists with one or
+// more value.
+func (e Encoder) HasHeader(key string) bool {
+ return len(e.header[key]) != 0
+}
+
+// SetURI returns a URIValue used for setting the given path key
+func (e *Encoder) SetURI(key string) URIValue {
+ return newURIValue(&e.path, &e.rawPath, &e.pathBuffer, key)
+}
+
+// SetQuery returns a QueryValue used for setting the given query key
+func (e *Encoder) SetQuery(key string) QueryValue {
+ return NewQueryValue(e.query, key, false)
+}
+
+// AddQuery returns a QueryValue used for appending the given query key
+func (e *Encoder) AddQuery(key string) QueryValue {
+ return NewQueryValue(e.query, key, true)
+}
+
+// HasQuery returns if a query with the key specified exists with one or
+// more values.
+func (e *Encoder) HasQuery(key string) bool {
+ return len(e.query.Get(key)) != 0
+}
diff --git a/vendor/github.com/aws/smithy-go/encoding/httpbinding/encode_test.go b/vendor/github.com/aws/smithy-go/encoding/httpbinding/encode_test.go
new file mode 100644
index 0000000000..6d972ae508
--- /dev/null
+++ b/vendor/github.com/aws/smithy-go/encoding/httpbinding/encode_test.go
@@ -0,0 +1,146 @@
+package httpbinding
+
+import (
+ "net/http"
+ "net/url"
+ "reflect"
+ "testing"
+)
+
+func TestEncoder(t *testing.T) {
+ actual := &http.Request{
+ Header: http.Header{
+ "custom-user-header": {"someValue"},
+ },
+ URL: &url.URL{
+ Path: "/some/{pathKeyOne}/{pathKeyTwo}",
+ RawQuery: "someExistingKeys=foobar",
+ },
+ }
+
+ expected := &http.Request{
+ Header: map[string][]string{
+ "custom-user-header": {"someValue"},
+ "x-amzn-header-foo": {"someValue"},
+ "x-amzn-meta-foo": {"someValue"},
+ },
+ URL: &url.URL{
+ Path: "/some/someValue/path",
+ RawPath: "/some/someValue/path",
+ RawQuery: "someExistingKeys=foobar&someKey=someValue&someKey=otherValue",
+ },
+ }
+
+ encoder, err := NewEncoder(actual.URL.Path, actual.URL.RawQuery, actual.Header)
+ if err != nil {
+ t.Fatalf("expected no error, got %v", err)
+ }
+
+ // Headers
+ encoder.AddHeader("x-amzn-header-foo").String("someValue")
+ encoder.Headers("x-amzn-meta-").AddHeader("foo").String("someValue")
+
+ // Query
+ encoder.SetQuery("someKey").String("someValue")
+ encoder.AddQuery("someKey").String("otherValue")
+
+ // URI
+ if err := encoder.SetURI("pathKeyOne").String("someValue"); err != nil {
+ t.Errorf("expected no err, but got %v", err)
+ }
+
+ // URI
+ if err := encoder.SetURI("pathKeyTwo").String("path"); err != nil {
+ t.Errorf("expected no err, but got %v", err)
+ }
+
+ if actual, err = encoder.Encode(actual); err != nil {
+ t.Errorf("expected no err, but got %v", err)
+ }
+
+ if !reflect.DeepEqual(expected, actual) {
+ t.Errorf("expected %v, but got %v", expected, actual)
+ }
+}
+
+func TestEncoderHasHeader(t *testing.T) {
+ encoder, err := NewEncoder("/", "", http.Header{})
+ if err != nil {
+ t.Fatalf("expected no error, got %v", err)
+ }
+
+ if h := "i-dont-exist"; encoder.HasHeader(h) {
+ t.Errorf("expect %v not to be set", h)
+ }
+
+ encoder.AddHeader("I-do-exist").String("some value")
+
+ if h := "I-do-exist"; !encoder.HasHeader(h) {
+ t.Errorf("expect %v to be set", h)
+ }
+
+}
+
+func TestEncoderHasQuery(t *testing.T) {
+ encoder, err := NewEncoder("/", "", http.Header{})
+ if err != nil {
+ t.Fatalf("expected no error, got %v", err)
+ }
+
+ if q := "i-dont-exist"; encoder.HasQuery(q) {
+ t.Errorf("expect %v not to be set", q)
+ }
+
+ encoder.AddQuery("I-do-exist").String("some value")
+
+ if q := "I-do-exist"; !encoder.HasQuery(q) {
+ t.Errorf("expect %v to be set", q)
+ }
+
+}
+
+func TestEncodeContentLength(t *testing.T) {
+ cases := map[string]struct {
+ headerValue string
+ expected int64
+ wantErr bool
+ }{
+ "valid number": {
+ headerValue: "1024",
+ expected: 1024,
+ },
+ "invalid number": {
+ headerValue: "1024.5",
+ wantErr: true,
+ },
+ "not a number": {
+ headerValue: "NaN",
+ wantErr: true,
+ },
+ }
+
+ for name, tt := range cases {
+ t.Run(name, func(t *testing.T) {
+ encoder, err := NewEncoder("/", "", http.Header{})
+ if err != nil {
+ t.Fatalf("expect no error, got %v", err)
+ }
+
+ encoder.SetHeader("Content-Length").String(tt.headerValue)
+
+ req := &http.Request{URL: &url.URL{}}
+ req, err = encoder.Encode(req)
+ if (err != nil) != tt.wantErr {
+ t.Fatalf("unexpected error value wantErr=%v", tt.wantErr)
+ } else if tt.wantErr {
+ return
+ }
+ if e, a := tt.expected, req.ContentLength; e != a {
+ t.Errorf("expect %v, got %v", e, a)
+ }
+ if v := req.Header.Get("Content-Length"); len(v) > 0 {
+ t.Errorf("expect header not to be set")
+ }
+ })
+ }
+}
diff --git a/vendor/github.com/aws/smithy-go/encoding/httpbinding/gotest/ya.make b/vendor/github.com/aws/smithy-go/encoding/httpbinding/gotest/ya.make
new file mode 100644
index 0000000000..c8a86501ea
--- /dev/null
+++ b/vendor/github.com/aws/smithy-go/encoding/httpbinding/gotest/ya.make
@@ -0,0 +1,5 @@
+GO_TEST_FOR(vendor/github.com/aws/smithy-go/encoding/httpbinding)
+
+LICENSE(Apache-2.0)
+
+END()
diff --git a/vendor/github.com/aws/smithy-go/encoding/httpbinding/header.go b/vendor/github.com/aws/smithy-go/encoding/httpbinding/header.go
new file mode 100644
index 0000000000..f9256e175f
--- /dev/null
+++ b/vendor/github.com/aws/smithy-go/encoding/httpbinding/header.go
@@ -0,0 +1,122 @@
+package httpbinding
+
+import (
+ "encoding/base64"
+ "math"
+ "math/big"
+ "net/http"
+ "strconv"
+ "strings"
+)
+
+// Headers is used to encode header keys using a provided prefix
+type Headers struct {
+ header http.Header
+ prefix string
+}
+
+// AddHeader returns a HeaderValue used to append values to prefix+key
+func (h Headers) AddHeader(key string) HeaderValue {
+ return h.newHeaderValue(key, true)
+}
+
+// SetHeader returns a HeaderValue used to set the value of prefix+key
+func (h Headers) SetHeader(key string) HeaderValue {
+ return h.newHeaderValue(key, false)
+}
+
+func (h Headers) newHeaderValue(key string, append bool) HeaderValue {
+ return newHeaderValue(h.header, h.prefix+strings.TrimSpace(key), append)
+}
+
+// HeaderValue is used to encode values to an HTTP header
+type HeaderValue struct {
+ header http.Header
+ key string
+ append bool
+}
+
+func newHeaderValue(header http.Header, key string, append bool) HeaderValue {
+ return HeaderValue{header: header, key: strings.TrimSpace(key), append: append}
+}
+
+func (h HeaderValue) modifyHeader(value string) {
+ if h.append {
+ h.header[h.key] = append(h.header[h.key], value)
+ } else {
+ h.header[h.key] = append(h.header[h.key][:0], value)
+ }
+}
+
+// String encodes the value v as the header string value
+func (h HeaderValue) String(v string) {
+ h.modifyHeader(v)
+}
+
+// Byte encodes the value v as a query string value
+func (h HeaderValue) Byte(v int8) {
+ h.Long(int64(v))
+}
+
+// Short encodes the value v as a query string value
+func (h HeaderValue) Short(v int16) {
+ h.Long(int64(v))
+}
+
+// Integer encodes the value v as the header string value
+func (h HeaderValue) Integer(v int32) {
+ h.Long(int64(v))
+}
+
+// Long encodes the value v as the header string value
+func (h HeaderValue) Long(v int64) {
+ h.modifyHeader(strconv.FormatInt(v, 10))
+}
+
+// Boolean encodes the value v as a query string value
+func (h HeaderValue) Boolean(v bool) {
+ h.modifyHeader(strconv.FormatBool(v))
+}
+
+// Float encodes the value v as a query string value
+func (h HeaderValue) Float(v float32) {
+ h.float(float64(v), 32)
+}
+
+// Double encodes the value v as a query string value
+func (h HeaderValue) Double(v float64) {
+ h.float(v, 64)
+}
+
+func (h HeaderValue) float(v float64, bitSize int) {
+ switch {
+ case math.IsNaN(v):
+ h.String(floatNaN)
+ case math.IsInf(v, 1):
+ h.String(floatInfinity)
+ case math.IsInf(v, -1):
+ h.String(floatNegInfinity)
+ default:
+ h.modifyHeader(strconv.FormatFloat(v, 'f', -1, bitSize))
+ }
+}
+
+// BigInteger encodes the value v as a query string value
+func (h HeaderValue) BigInteger(v *big.Int) {
+ h.modifyHeader(v.String())
+}
+
+// BigDecimal encodes the value v as a query string value
+func (h HeaderValue) BigDecimal(v *big.Float) {
+ if i, accuracy := v.Int64(); accuracy == big.Exact {
+ h.Long(i)
+ return
+ }
+ h.modifyHeader(v.Text('e', -1))
+}
+
+// Blob encodes the value v as a base64 header string value
+func (h HeaderValue) Blob(v []byte) {
+ encodeToString := base64.StdEncoding.EncodeToString(v)
+ h.modifyHeader(encodeToString)
+}
diff --git a/vendor/github.com/aws/smithy-go/encoding/httpbinding/header_test.go b/vendor/github.com/aws/smithy-go/encoding/httpbinding/header_test.go
new file mode 100644
index 0000000000..64e555c32b
--- /dev/null
+++ b/vendor/github.com/aws/smithy-go/encoding/httpbinding/header_test.go
@@ -0,0 +1,295 @@
+package httpbinding
+
+import (
+ "fmt"
+ "math/big"
+ "net/http"
+ "reflect"
+ "testing"
+)
+
+func TestHeaderValue(t *testing.T) {
+ const keyName = "test-key"
+ const expectedKeyName = "test-key"
+
+ cases := map[string]struct {
+ header http.Header
+ args []interface{}
+ append bool
+ expected http.Header
+ }{
+ "set blob": {
+ header: http.Header{expectedKeyName: []string{"foobar"}},
+ args: []interface{}{[]byte("baz")},
+ expected: map[string][]string{
+ expectedKeyName: {"YmF6"},
+ },
+ },
+ "set boolean": {
+ header: http.Header{expectedKeyName: []string{"foobar"}},
+ args: []interface{}{true},
+ expected: map[string][]string{
+ expectedKeyName: {"true"},
+ },
+ },
+ "set string": {
+ header: http.Header{expectedKeyName: []string{"foobar"}},
+ args: []interface{}{"string value"},
+ expected: map[string][]string{
+ expectedKeyName: {"string value"},
+ },
+ },
+ "set byte": {
+ header: http.Header{expectedKeyName: []string{"127"}},
+ args: []interface{}{int8(127)},
+ expected: map[string][]string{
+ expectedKeyName: {"127"},
+ },
+ },
+ "set short": {
+ header: http.Header{expectedKeyName: []string{"foobar"}},
+ args: []interface{}{int16(32767)},
+ expected: map[string][]string{
+ expectedKeyName: {"32767"},
+ },
+ },
+ "set integer": {
+ header: http.Header{expectedKeyName: []string{"foobar"}},
+ args: []interface{}{int32(2147483647)},
+ expected: map[string][]string{
+ expectedKeyName: {"2147483647"},
+ },
+ },
+ "set long": {
+ header: http.Header{expectedKeyName: []string{"foobar"}},
+ args: []interface{}{int64(9223372036854775807)},
+ expected: map[string][]string{
+ expectedKeyName: {"9223372036854775807"},
+ },
+ },
+ "set float": {
+ header: http.Header{expectedKeyName: []string{"foobar"}},
+ args: []interface{}{float32(3.14159)},
+ expected: map[string][]string{
+ expectedKeyName: {"3.14159"},
+ },
+ },
+ "set double": {
+ header: http.Header{expectedKeyName: []string{"foobar"}},
+ args: []interface{}{float64(3.14159)},
+ expected: map[string][]string{
+ expectedKeyName: {"3.14159"},
+ },
+ },
+ "set bigInteger": {
+ header: http.Header{expectedKeyName: []string{"foobar"}},
+ args: []interface{}{new(big.Int).SetInt64(42)},
+ expected: map[string][]string{
+ expectedKeyName: {"42"},
+ },
+ },
+ "set bigDecimal": {
+ header: http.Header{expectedKeyName: []string{"foobar"}},
+ args: []interface{}{new(big.Float).SetFloat64(1024.10241024)},
+ expected: map[string][]string{
+ expectedKeyName: {"1.02410241024e+03"},
+ },
+ },
+ "add blob": {
+ header: http.Header{expectedKeyName: []string{"foobar"}},
+ args: []interface{}{[]byte("baz")},
+ append: true,
+ expected: map[string][]string{
+ expectedKeyName: {"foobar", "YmF6"},
+ },
+ },
+ "add bool": {
+ header: http.Header{expectedKeyName: []string{"foobar"}},
+ args: []interface{}{true},
+ append: true,
+ expected: map[string][]string{
+ expectedKeyName: {"foobar", "true"},
+ },
+ },
+ "add string": {
+ header: http.Header{expectedKeyName: []string{"foobar"}},
+ args: []interface{}{"string value"},
+ append: true,
+ expected: map[string][]string{
+ expectedKeyName: {"foobar", "string value"},
+ },
+ },
+ "add byte": {
+ header: http.Header{expectedKeyName: []string{"foobar"}},
+ args: []interface{}{int8(127)},
+ append: true,
+ expected: map[string][]string{
+ expectedKeyName: {"foobar", "127"},
+ },
+ },
+ "add short": {
+ header: http.Header{expectedKeyName: []string{"foobar"}},
+ args: []interface{}{int16(32767)},
+ append: true,
+ expected: map[string][]string{
+ expectedKeyName: {"foobar", "32767"},
+ },
+ },
+ "add integer": {
+ header: http.Header{expectedKeyName: []string{"foobar"}},
+ args: []interface{}{int32(2147483647)},
+ append: true,
+ expected: map[string][]string{
+ expectedKeyName: {"foobar", "2147483647"},
+ },
+ },
+ "add long": {
+ header: http.Header{expectedKeyName: []string{"foobar"}},
+ args: []interface{}{int64(9223372036854775807)},
+ append: true,
+ expected: map[string][]string{
+ expectedKeyName: {"foobar", "9223372036854775807"},
+ },
+ },
+ "add float": {
+ header: http.Header{expectedKeyName: []string{"1.61803"}},
+ args: []interface{}{float32(3.14159)},
+ append: true,
+ expected: map[string][]string{
+ expectedKeyName: {"1.61803", "3.14159"},
+ },
+ },
+ "add double": {
+ header: http.Header{expectedKeyName: []string{"foobar"}},
+ args: []interface{}{float64(3.14159)},
+ append: true,
+ expected: map[string][]string{
+ expectedKeyName: {"foobar", "3.14159"},
+ },
+ },
+ "add bigInteger": {
+ header: http.Header{expectedKeyName: []string{"foobar"}},
+ args: []interface{}{new(big.Int).SetInt64(42)},
+ append: true,
+ expected: map[string][]string{
+ expectedKeyName: {"foobar", "42"},
+ },
+ },
+ "add bigDecimal": {
+ header: http.Header{expectedKeyName: []string{"foobar"}},
+ args: []interface{}{new(big.Float).SetFloat64(1024.10241024)},
+ append: true,
+ expected: map[string][]string{
+ expectedKeyName: {"foobar", "1.02410241024e+03"},
+ },
+ },
+ }
+
+ for name, tt := range cases {
+ t.Run(name, func(t *testing.T) {
+ if tt.header == nil {
+ tt.header = http.Header{}
+ }
+
+ hv := newHeaderValue(tt.header, keyName, tt.append)
+
+ if err := setHeader(hv, tt.args); err != nil {
+ t.Fatalf("expected no error, got %v", err)
+ }
+
+ if e, a := tt.expected, hv.header; !reflect.DeepEqual(e, a) {
+ t.Errorf("expected %v, got %v", e, a)
+ }
+ })
+ }
+}
+
+func TestHeaders(t *testing.T) {
+ const prefix = "X-Amzn-Meta-"
+ cases := map[string]struct {
+ headers http.Header
+ values map[string]string
+ append bool
+ expected http.Header
+ }{
+ "set": {
+ headers: http.Header{
+ "X-Amzn-Meta-Foo": {"bazValue"},
+ },
+ values: map[string]string{
+ "Foo": "fooValue",
+ " Bar ": "barValue",
+ },
+ expected: http.Header{
+ "X-Amzn-Meta-Foo": {"fooValue"},
+ "X-Amzn-Meta-Bar": {"barValue"},
+ },
+ },
+ "add": {
+ headers: http.Header{
+ "X-Amzn-Meta-Foo": {"bazValue"},
+ },
+ values: map[string]string{
+ "Foo": "fooValue",
+ " Bar ": "barValue",
+ },
+ append: true,
+ expected: http.Header{
+ "X-Amzn-Meta-Foo": {"bazValue", "fooValue"},
+ "X-Amzn-Meta-Bar": {"barValue"},
+ },
+ },
+ }
+
+ for name, tt := range cases {
+ t.Run(name, func(t *testing.T) {
+ headers := Headers{header: tt.headers, prefix: prefix}
+
+ var f func(key string) HeaderValue
+ if tt.append {
+ f = headers.AddHeader
+ } else {
+ f = headers.SetHeader
+ }
+
+ for key, value := range tt.values {
+ f(key).String(value)
+ }
+
+ if e, a := tt.expected, tt.headers; !reflect.DeepEqual(e, a) {
+ t.Errorf("expected %v, but got %v", e, a)
+ }
+ })
+ }
+}
+
+func setHeader(hv HeaderValue, args []interface{}) error {
+ value := args[0]
+
+ switch value.(type) {
+ case []byte:
+ return reflectCall(reflect.ValueOf(hv.Blob), args)
+ case bool:
+ return reflectCall(reflect.ValueOf(hv.Boolean), args)
+ case string:
+ return reflectCall(reflect.ValueOf(hv.String), args)
+ case int8:
+ return reflectCall(reflect.ValueOf(hv.Byte), args)
+ case int16:
+ return reflectCall(reflect.ValueOf(hv.Short), args)
+ case int32:
+ return reflectCall(reflect.ValueOf(hv.Integer), args)
+ case int64:
+ return reflectCall(reflect.ValueOf(hv.Long), args)
+ case float32:
+ return reflectCall(reflect.ValueOf(hv.Float), args)
+ case float64:
+ return reflectCall(reflect.ValueOf(hv.Double), args)
+ case *big.Int:
+ return reflectCall(reflect.ValueOf(hv.BigInteger), args)
+ case *big.Float:
+ return reflectCall(reflect.ValueOf(hv.BigDecimal), args)
+ default:
+ return fmt.Errorf("unhandled header value type")
+ }
+}
diff --git a/vendor/github.com/aws/smithy-go/encoding/httpbinding/path_replace.go b/vendor/github.com/aws/smithy-go/encoding/httpbinding/path_replace.go
new file mode 100644
index 0000000000..e78926c9a5
--- /dev/null
+++ b/vendor/github.com/aws/smithy-go/encoding/httpbinding/path_replace.go
@@ -0,0 +1,108 @@
+package httpbinding
+
+import (
+ "bytes"
+ "fmt"
+)
+
+const (
+ uriTokenStart = '{'
+ uriTokenStop = '}'
+ uriTokenSkip = '+'
+)
+
+func bufCap(b []byte, n int) []byte {
+ if cap(b) < n {
+ return make([]byte, 0, n)
+ }
+
+ return b[0:0]
+}
+
+// replacePathElement replaces a single element in the path []byte.
+// Escape is used to control whether the value will be escaped using Amazon path escape style.
+func replacePathElement(path, fieldBuf []byte, key, val string, escape bool) ([]byte, []byte, error) {
+ fieldBuf = bufCap(fieldBuf, len(key)+3) // { <key> [+] }
+ fieldBuf = append(fieldBuf, uriTokenStart)
+ fieldBuf = append(fieldBuf, key...)
+
+ start := bytes.Index(path, fieldBuf)
+ end := start + len(fieldBuf)
+ if start < 0 || len(path[end:]) == 0 {
+ // TODO what to do about error?
+ return path, fieldBuf, fmt.Errorf("invalid path index, start=%d,end=%d. %s", start, end, path)
+ }
+
+ encodeSep := true
+ if path[end] == uriTokenSkip {
+ // '+' token means do not escape slashes
+ encodeSep = false
+ end++
+ }
+
+ if escape {
+ val = EscapePath(val, encodeSep)
+ }
+
+ if path[end] != uriTokenStop {
+ return path, fieldBuf, fmt.Errorf("invalid path element, does not contain token stop, %s", path)
+ }
+ end++
+
+ fieldBuf = bufCap(fieldBuf, len(val))
+ fieldBuf = append(fieldBuf, val...)
+
+ keyLen := end - start
+ valLen := len(fieldBuf)
+
+ if keyLen == valLen {
+ copy(path[start:], fieldBuf)
+ return path, fieldBuf, nil
+ }
+
+ newLen := len(path) + (valLen - keyLen)
+ if len(path) < newLen {
+ path = path[:cap(path)]
+ }
+ if cap(path) < newLen {
+ newURI := make([]byte, newLen)
+ copy(newURI, path)
+ path = newURI
+ }
+
+ // shift
+ copy(path[start+valLen:], path[end:])
+ path = path[:newLen]
+ copy(path[start:], fieldBuf)
+
+ return path, fieldBuf, nil
+}
+
+// EscapePath escapes part of a URL path in Amazon style.
+func EscapePath(path string, encodeSep bool) string {
+ var buf bytes.Buffer
+ for i := 0; i < len(path); i++ {
+ c := path[i]
+ if noEscape[c] || (c == '/' && !encodeSep) {
+ buf.WriteByte(c)
+ } else {
+ fmt.Fprintf(&buf, "%%%02X", c)
+ }
+ }
+ return buf.String()
+}
+
+var noEscape [256]bool
+
+func init() {
+ for i := 0; i < len(noEscape); i++ {
+ // AWS expects every character except these to be escaped
+ noEscape[i] = (i >= 'A' && i <= 'Z') ||
+ (i >= 'a' && i <= 'z') ||
+ (i >= '0' && i <= '9') ||
+ i == '-' ||
+ i == '.' ||
+ i == '_' ||
+ i == '~'
+ }
+}
diff --git a/vendor/github.com/aws/smithy-go/encoding/httpbinding/path_replace_test.go b/vendor/github.com/aws/smithy-go/encoding/httpbinding/path_replace_test.go
new file mode 100644
index 0000000000..689733ca00
--- /dev/null
+++ b/vendor/github.com/aws/smithy-go/encoding/httpbinding/path_replace_test.go
@@ -0,0 +1,67 @@
+package httpbinding
+
+import (
+ "bytes"
+ "testing"
+)
+
+func TestPathReplace(t *testing.T) {
+ cases := []struct {
+ Orig, ExpPath, ExpRawPath []byte
+ Key, Val string
+ }{
+ {
+ Orig: []byte("/{bucket}/{key+}"),
+ ExpPath: []byte("/123/{key+}"),
+ ExpRawPath: []byte("/123/{key+}"),
+ Key: "bucket", Val: "123",
+ },
+ {
+ Orig: []byte("/{bucket}/{key+}"),
+ ExpPath: []byte("/{bucket}/abc"),
+ ExpRawPath: []byte("/{bucket}/abc"),
+ Key: "key", Val: "abc",
+ },
+ {
+ Orig: []byte("/{bucket}/{key+}"),
+ ExpPath: []byte("/{bucket}/a/b/c"),
+ ExpRawPath: []byte("/{bucket}/a/b/c"),
+ Key: "key", Val: "a/b/c",
+ },
+ {
+ Orig: []byte("/{bucket}/{key+}"),
+ ExpPath: []byte("/1/2/3/{key+}"),
+ ExpRawPath: []byte("/1%2F2%2F3/{key+}"),
+ Key: "bucket", Val: "1/2/3",
+ },
+ {
+ Orig: []byte("/{bucket}/{key+}"),
+ ExpPath: []byte("/reallylongvaluegoesheregrowingarray/{key+}"),
+ ExpRawPath: []byte("/reallylongvaluegoesheregrowingarray/{key+}"),
+ Key: "bucket", Val: "reallylongvaluegoesheregrowingarray",
+ },
+ }
+
+ var buffer [64]byte
+
+ for i, c := range cases {
+ origRaw := make([]byte, len(c.Orig))
+ copy(origRaw, c.Orig)
+
+ path, _, err := replacePathElement(c.Orig, buffer[:0], c.Key, c.Val, false)
+ if err != nil {
+ t.Fatalf("expected no error, got %v", err)
+ }
+ rawPath, _, err := replacePathElement(origRaw, buffer[:0], c.Key, c.Val, true)
+ if err != nil {
+ t.Fatalf("expected no error, got %v", err)
+ }
+
+ if e, a := c.ExpPath, path; bytes.Compare(e, a) != 0 {
+ t.Errorf("%d, expect uri path to be %q got %q", i, e, a)
+ }
+ if e, a := c.ExpRawPath, rawPath; bytes.Compare(e, a) != 0 {
+ t.Errorf("%d, expect uri raw path to be %q got %q", i, e, a)
+ }
+ }
+}
diff --git a/vendor/github.com/aws/smithy-go/encoding/httpbinding/query.go b/vendor/github.com/aws/smithy-go/encoding/httpbinding/query.go
new file mode 100644
index 0000000000..c2e7d0a20f
--- /dev/null
+++ b/vendor/github.com/aws/smithy-go/encoding/httpbinding/query.go
@@ -0,0 +1,107 @@
+package httpbinding
+
+import (
+ "encoding/base64"
+ "math"
+ "math/big"
+ "net/url"
+ "strconv"
+)
+
+// QueryValue is used to encode query key values
+type QueryValue struct {
+ query url.Values
+ key string
+ append bool
+}
+
+// NewQueryValue creates a new QueryValue which enables encoding
+// a query value into the given url.Values.
+func NewQueryValue(query url.Values, key string, append bool) QueryValue {
+ return QueryValue{
+ query: query,
+ key: key,
+ append: append,
+ }
+}
+
+func (qv QueryValue) updateKey(value string) {
+ if qv.append {
+ qv.query.Add(qv.key, value)
+ } else {
+ qv.query.Set(qv.key, value)
+ }
+}
+
+// Blob encodes v as a base64 query string value
+func (qv QueryValue) Blob(v []byte) {
+ encodeToString := base64.StdEncoding.EncodeToString(v)
+ qv.updateKey(encodeToString)
+}
+
+// Boolean encodes v as a query string value
+func (qv QueryValue) Boolean(v bool) {
+ qv.updateKey(strconv.FormatBool(v))
+}
+
+// String encodes v as a query string value
+func (qv QueryValue) String(v string) {
+ qv.updateKey(v)
+}
+
+// Byte encodes v as a query string value
+func (qv QueryValue) Byte(v int8) {
+ qv.Long(int64(v))
+}
+
+// Short encodes v as a query string value
+func (qv QueryValue) Short(v int16) {
+ qv.Long(int64(v))
+}
+
+// Integer encodes v as a query string value
+func (qv QueryValue) Integer(v int32) {
+ qv.Long(int64(v))
+}
+
+// Long encodes v as a query string value
+func (qv QueryValue) Long(v int64) {
+ qv.updateKey(strconv.FormatInt(v, 10))
+}
+
+// Float encodes v as a query string value
+func (qv QueryValue) Float(v float32) {
+ qv.float(float64(v), 32)
+}
+
+// Double encodes v as a query string value
+func (qv QueryValue) Double(v float64) {
+ qv.float(v, 64)
+}
+
+func (qv QueryValue) float(v float64, bitSize int) {
+ switch {
+ case math.IsNaN(v):
+ qv.String(floatNaN)
+ case math.IsInf(v, 1):
+ qv.String(floatInfinity)
+ case math.IsInf(v, -1):
+ qv.String(floatNegInfinity)
+ default:
+ qv.updateKey(strconv.FormatFloat(v, 'f', -1, bitSize))
+ }
+}
+
+// BigInteger encodes v as a query string value
+func (qv QueryValue) BigInteger(v *big.Int) {
+ qv.updateKey(v.String())
+}
+
+// BigDecimal encodes v as a query string value
+func (qv QueryValue) BigDecimal(v *big.Float) {
+ if i, accuracy := v.Int64(); accuracy == big.Exact {
+ qv.Long(i)
+ return
+ }
+ qv.updateKey(v.Text('e', -1))
+}
diff --git a/vendor/github.com/aws/smithy-go/encoding/httpbinding/query_test.go b/vendor/github.com/aws/smithy-go/encoding/httpbinding/query_test.go
new file mode 100644
index 0000000000..62cf25cd67
--- /dev/null
+++ b/vendor/github.com/aws/smithy-go/encoding/httpbinding/query_test.go
@@ -0,0 +1,234 @@
+package httpbinding
+
+import (
+ "fmt"
+ "math/big"
+ "net/url"
+ "reflect"
+ "testing"
+)
+
+func TestQueryValue(t *testing.T) {
+ const queryKey = "someKey"
+
+ cases := map[string]struct {
+ values url.Values
+ args []interface{}
+ append bool
+ expected url.Values
+ }{
+ "set blob": {
+ values: url.Values{queryKey: []string{"foobar"}},
+ args: []interface{}{[]byte("baz")},
+ expected: map[string][]string{
+ queryKey: {"YmF6"},
+ },
+ },
+ "set bool": {
+ values: url.Values{queryKey: []string{"foobar"}},
+ args: []interface{}{true},
+ expected: map[string][]string{
+ queryKey: {"true"},
+ },
+ },
+ "set string": {
+ values: url.Values{queryKey: []string{"foobar"}},
+ args: []interface{}{"string value"},
+ expected: map[string][]string{
+ queryKey: {"string value"},
+ },
+ },
+ "set byte": {
+ values: url.Values{queryKey: []string{"foobar"}},
+ args: []interface{}{int8(127)},
+ expected: map[string][]string{
+ queryKey: {"127"},
+ },
+ },
+ "set short": {
+ values: url.Values{queryKey: []string{"foobar"}},
+ args: []interface{}{int16(32767)},
+ expected: map[string][]string{
+ queryKey: {"32767"},
+ },
+ },
+ "set integer": {
+ values: url.Values{queryKey: []string{"foobar"}},
+ args: []interface{}{int32(2147483647)},
+ expected: map[string][]string{
+ queryKey: {"2147483647"},
+ },
+ },
+ "set long": {
+ values: url.Values{queryKey: []string{"foobar"}},
+ args: []interface{}{int64(9223372036854775807)},
+ expected: map[string][]string{
+ queryKey: {"9223372036854775807"},
+ },
+ },
+ "set float": {
+ values: url.Values{queryKey: []string{"foobar"}},
+ args: []interface{}{float32(3.14159)},
+ expected: map[string][]string{
+ queryKey: {"3.14159"},
+ },
+ },
+ "set double": {
+ values: url.Values{queryKey: []string{"foobar"}},
+ args: []interface{}{float64(3.14159)},
+ expected: map[string][]string{
+ queryKey: {"3.14159"},
+ },
+ },
+ "set bigInteger": {
+ values: url.Values{queryKey: []string{"foobar"}},
+ args: []interface{}{new(big.Int).SetInt64(1)},
+ expected: map[string][]string{
+ queryKey: {"1"},
+ },
+ },
+ "set bigDecimal": {
+ values: url.Values{queryKey: []string{"foobar"}},
+ args: []interface{}{new(big.Float).SetFloat64(1024.10241024)},
+ expected: map[string][]string{
+ queryKey: {"1.02410241024e+03"},
+ },
+ },
+ "add blob": {
+ values: url.Values{queryKey: []string{"foobar"}},
+ args: []interface{}{[]byte("baz")},
+ append: true,
+ expected: map[string][]string{
+ queryKey: {"foobar", "YmF6"},
+ },
+ },
+ "add bool": {
+ values: url.Values{queryKey: []string{"foobar"}},
+ args: []interface{}{true},
+ append: true,
+ expected: map[string][]string{
+ queryKey: {"foobar", "true"},
+ },
+ },
+ "add string": {
+ values: url.Values{queryKey: []string{"foobar"}},
+ args: []interface{}{"string value"},
+ append: true,
+ expected: map[string][]string{
+ queryKey: {"foobar", "string value"},
+ },
+ },
+ "add byte": {
+ values: url.Values{queryKey: []string{"foobar"}},
+ args: []interface{}{int8(127)},
+ append: true,
+ expected: map[string][]string{
+ queryKey: {"foobar", "127"},
+ },
+ },
+ "add short": {
+ values: url.Values{queryKey: []string{"foobar"}},
+ args: []interface{}{int16(32767)},
+ append: true,
+ expected: map[string][]string{
+ queryKey: {"foobar", "32767"},
+ },
+ },
+ "add integer": {
+ values: url.Values{queryKey: []string{"foobar"}},
+ args: []interface{}{int32(2147483647)},
+ expected: map[string][]string{
+ queryKey: {"2147483647"},
+ },
+ },
+ "add long": {
+ values: url.Values{queryKey: []string{"foobar"}},
+ args: []interface{}{int64(9223372036854775807)},
+ append: true,
+ expected: map[string][]string{
+ queryKey: {"foobar", "9223372036854775807"},
+ },
+ },
+ "add float": {
+ values: url.Values{queryKey: []string{"foobar"}},
+ args: []interface{}{float32(3.14159)},
+ append: true,
+ expected: map[string][]string{
+ queryKey: {"foobar", "3.14159"},
+ },
+ },
+ "add double": {
+ values: url.Values{queryKey: []string{"foobar"}},
+ args: []interface{}{float64(3.14159)},
+ append: true,
+ expected: map[string][]string{
+ queryKey: {"foobar", "3.14159"},
+ },
+ },
+ "add bigInteger": {
+ values: url.Values{queryKey: []string{"foobar"}},
+ args: []interface{}{new(big.Int).SetInt64(1)},
+ append: true,
+ expected: map[string][]string{
+ queryKey: {"foobar", "1"},
+ },
+ },
+ "add bigDecimal": {
+ values: url.Values{queryKey: []string{"foobar"}},
+ args: []interface{}{new(big.Float).SetFloat64(1024.10241024)},
+ append: true,
+ expected: map[string][]string{
+ queryKey: {"foobar", "1.02410241024e+03"},
+ },
+ },
+ }
+
+ for name, tt := range cases {
+ t.Run(name, func(t *testing.T) {
+ if tt.values == nil {
+ tt.values = url.Values{}
+ }
+
+ qv := NewQueryValue(tt.values, queryKey, tt.append)
+
+ if err := setQueryValue(qv, tt.args); err != nil {
+ t.Fatalf("expected no error, got %v", err)
+ }
+
+ if e, a := tt.expected, qv.query; !reflect.DeepEqual(e, a) {
+ t.Errorf("expected %v, got %v", e, a)
+ }
+ })
+ }
+}
+
+func setQueryValue(qv QueryValue, args []interface{}) error {
+ value := args[0]
+
+ switch value.(type) {
+ case []byte:
+ return reflectCall(reflect.ValueOf(qv.Blob), args)
+ case bool:
+ return reflectCall(reflect.ValueOf(qv.Boolean), args)
+ case string:
+ return reflectCall(reflect.ValueOf(qv.String), args)
+ case int8:
+ return reflectCall(reflect.ValueOf(qv.Byte), args)
+ case int16:
+ return reflectCall(reflect.ValueOf(qv.Short), args)
+ case int32:
+ return reflectCall(reflect.ValueOf(qv.Integer), args)
+ case int64:
+ return reflectCall(reflect.ValueOf(qv.Long), args)
+ case float32:
+ return reflectCall(reflect.ValueOf(qv.Float), args)
+ case float64:
+ return reflectCall(reflect.ValueOf(qv.Double), args)
+ case *big.Int:
+ return reflectCall(reflect.ValueOf(qv.BigInteger), args)
+ case *big.Float:
+ return reflectCall(reflect.ValueOf(qv.BigDecimal), args)
+ default:
+ return fmt.Errorf("unhandled query value type")
+ }
+}
diff --git a/vendor/github.com/aws/smithy-go/encoding/httpbinding/shared_test.go b/vendor/github.com/aws/smithy-go/encoding/httpbinding/shared_test.go
new file mode 100644
index 0000000000..2b7518e1c7
--- /dev/null
+++ b/vendor/github.com/aws/smithy-go/encoding/httpbinding/shared_test.go
@@ -0,0 +1,36 @@
+package httpbinding
+
+import (
+ "fmt"
+ "reflect"
+)
+
+func reflectCall(funcValue reflect.Value, args []interface{}) error {
+ argValues := make([]reflect.Value, len(args))
+
+ for i, v := range args {
+ value := reflect.ValueOf(v)
+ argValues[i] = value
+ }
+
+ retValues := funcValue.Call(argValues)
+ if len(retValues) > 0 {
+ errValue := retValues[0]
+
+ if typeName := errValue.Type().Name(); typeName != "error" {
+ panic(fmt.Sprintf("expected first return argument to be error but got %v", typeName))
+ }
+
+ if errValue.IsNil() {
+ return nil
+ }
+
+ if err, ok := errValue.Interface().(error); ok {
+ return err
+ }
+
+ panic(fmt.Sprintf("expected %v to return error type, but got %v", funcValue.Type().String(), retValues[0].Type().String()))
+ }
+
+ return nil
+}
diff --git a/vendor/github.com/aws/smithy-go/encoding/httpbinding/uri.go b/vendor/github.com/aws/smithy-go/encoding/httpbinding/uri.go
new file mode 100644
index 0000000000..f04e11984a
--- /dev/null
+++ b/vendor/github.com/aws/smithy-go/encoding/httpbinding/uri.go
@@ -0,0 +1,111 @@
+package httpbinding
+
+import (
+ "math"
+ "math/big"
+ "strconv"
+ "strings"
+)
+
+// URIValue is used to encode named URI parameters
+type URIValue struct {
+ path, rawPath, buffer *[]byte
+
+ key string
+}
+
+func newURIValue(path *[]byte, rawPath *[]byte, buffer *[]byte, key string) URIValue {
+ return URIValue{path: path, rawPath: rawPath, buffer: buffer, key: key}
+}
+
+func (u URIValue) modifyURI(value string) (err error) {
+ *u.path, *u.buffer, err = replacePathElement(*u.path, *u.buffer, u.key, value, false)
+ if err != nil {
+ return err
+ }
+ *u.rawPath, *u.buffer, err = replacePathElement(*u.rawPath, *u.buffer, u.key, value, true)
+ return err
+}
+
+// Boolean encodes v as a URI string value
+func (u URIValue) Boolean(v bool) error {
+ return u.modifyURI(strconv.FormatBool(v))
+}
+
+// String encodes v as a URI string value
+func (u URIValue) String(v string) error {
+ return u.modifyURI(v)
+}
+
+// Byte encodes v as a URI string value
+func (u URIValue) Byte(v int8) error {
+ return u.Long(int64(v))
+}
+
+// Short encodes v as a URI string value
+func (u URIValue) Short(v int16) error {
+ return u.Long(int64(v))
+}
+
+// Integer encodes v as a URI string value
+func (u URIValue) Integer(v int32) error {
+ return u.Long(int64(v))
+}
+
+// Long encodes v as a URI string value
+func (u URIValue) Long(v int64) error {
+ return u.modifyURI(strconv.FormatInt(v, 10))
+}
+
+// Float encodes v as a query string value
+func (u URIValue) Float(v float32) error {
+ return u.float(float64(v), 32)
+}
+
+// Double encodes v as a query string value
+func (u URIValue) Double(v float64) error {
+ return u.float(v, 64)
+}
+
+func (u URIValue) float(v float64, bitSize int) error {
+ switch {
+ case math.IsNaN(v):
+ return u.String(floatNaN)
+ case math.IsInf(v, 1):
+ return u.String(floatInfinity)
+ case math.IsInf(v, -1):
+ return u.String(floatNegInfinity)
+ default:
+ return u.modifyURI(strconv.FormatFloat(v, 'f', -1, bitSize))
+ }
+}
+
+// BigInteger encodes v as a query string value
+func (u URIValue) BigInteger(v *big.Int) error {
+ return u.modifyURI(v.String())
+}
+
+// BigDecimal encodes v as a query string value
+func (u URIValue) BigDecimal(v *big.Float) error {
+ if i, accuracy := v.Int64(); accuracy == big.Exact {
+ return u.Long(i)
+ }
+ return u.modifyURI(v.Text('e', -1))
+}
+
+// SplitURI parses a Smithy HTTP binding trait URI
+func SplitURI(uri string) (path, query string) {
+ queryStart := strings.IndexRune(uri, '?')
+ if queryStart == -1 {
+ path = uri
+ return path, query
+ }
+
+ path = uri[:queryStart]
+ if queryStart+1 >= len(uri) {
+ return path, query
+ }
+ query = uri[queryStart+1:]
+
+ return path, query
+}
diff --git a/vendor/github.com/aws/smithy-go/encoding/httpbinding/uri_test.go b/vendor/github.com/aws/smithy-go/encoding/httpbinding/uri_test.go
new file mode 100644
index 0000000000..039e1e5baa
--- /dev/null
+++ b/vendor/github.com/aws/smithy-go/encoding/httpbinding/uri_test.go
@@ -0,0 +1,198 @@
+package httpbinding
+
+import (
+ "fmt"
+ "math/big"
+ "reflect"
+ "strconv"
+ "testing"
+)
+
+func TestURIValue(t *testing.T) {
+ const uriKey = "someKey"
+ const path = "/some/{someKey}/{path+}"
+
+ type expected struct {
+ path string
+ raw string
+ }
+
+ cases := map[string]struct {
+ path string
+ args []interface{}
+ expected expected
+ }{
+ "bool": {
+ path: path,
+ args: []interface{}{true},
+ expected: expected{
+ path: "/some/true/{path+}",
+ raw: "/some/true/{path+}",
+ },
+ },
+ "string": {
+ path: path,
+ args: []interface{}{"someValue"},
+ expected: expected{
+ path: "/some/someValue/{path+}",
+ raw: "/some/someValue/{path+}",
+ },
+ },
+ "byte": {
+ path: path,
+ args: []interface{}{int8(127)},
+ expected: expected{
+ path: "/some/127/{path+}",
+ raw: "/some/127/{path+}",
+ },
+ },
+ "short": {
+ path: path,
+ args: []interface{}{int16(32767)},
+ expected: expected{
+ path: "/some/32767/{path+}",
+ raw: "/some/32767/{path+}",
+ },
+ },
+ "integer": {
+ path: path,
+ args: []interface{}{int32(2147483647)},
+ expected: expected{
+ path: "/some/2147483647/{path+}",
+ raw: "/some/2147483647/{path+}",
+ },
+ },
+ "long": {
+ path: path,
+ args: []interface{}{int64(9223372036854775807)},
+ expected: expected{
+ path: "/some/9223372036854775807/{path+}",
+ raw: "/some/9223372036854775807/{path+}",
+ },
+ },
+ "float32": {
+ path: path,
+ args: []interface{}{float32(3.14159)},
+ expected: expected{
+ path: "/some/3.14159/{path+}",
+ raw: "/some/3.14159/{path+}",
+ },
+ },
+ "float64": {
+ path: path,
+ args: []interface{}{float64(3.14159)},
+ expected: expected{
+ path: "/some/3.14159/{path+}",
+ raw: "/some/3.14159/{path+}",
+ },
+ },
+ "bigInteger": {
+ path: path,
+ args: []interface{}{new(big.Int).SetInt64(1)},
+ expected: expected{
+ path: "/some/1/{path+}",
+ raw: "/some/1/{path+}",
+ },
+ },
+ "bigDecimal": {
+ path: path,
+ args: []interface{}{new(big.Float).SetFloat64(1024.10241024)},
+ expected: expected{
+ path: "/some/1.02410241024e+03/{path+}",
+ raw: "/some/1.02410241024e%2B03/{path+}",
+ },
+ },
+ }
+
+ buffer := make([]byte, 1024)
+
+ for name, tt := range cases {
+ t.Run(name, func(t *testing.T) {
+ pBytes, rBytes := []byte(tt.path), []byte(tt.path)
+
+ uv := newURIValue(&pBytes, &rBytes, &buffer, uriKey)
+
+ if err := setURI(uv, tt.args); err != nil {
+ t.Fatalf("expected no error, %v", err)
+ }
+
+ if e, a := tt.expected.path, string(pBytes); e != a {
+ t.Errorf("expected %v, got %v", e, a)
+ }
+
+ if e, a := tt.expected.raw, string(rBytes); e != a {
+ t.Errorf("expected %v, got %v", e, a)
+ }
+ })
+ }
+}
+
+func setURI(uv URIValue, args []interface{}) error {
+ value := args[0]
+
+ switch value.(type) {
+ case bool:
+ return reflectCall(reflect.ValueOf(uv.Boolean), args)
+ case string:
+ return reflectCall(reflect.ValueOf(uv.String), args)
+ case int8:
+ return reflectCall(reflect.ValueOf(uv.Byte), args)
+ case int16:
+ return reflectCall(reflect.ValueOf(uv.Short), args)
+ case int32:
+ return reflectCall(reflect.ValueOf(uv.Integer), args)
+ case int64:
+ return reflectCall(reflect.ValueOf(uv.Long), args)
+ case float32:
+ return reflectCall(reflect.ValueOf(uv.Float), args)
+ case float64:
+ return reflectCall(reflect.ValueOf(uv.Double), args)
+ case *big.Int:
+ return reflectCall(reflect.ValueOf(uv.BigInteger), args)
+ case *big.Float:
+ return reflectCall(reflect.ValueOf(uv.BigDecimal), args)
+ default:
+ return fmt.Errorf("unhandled value type")
+ }
+}
+
+func TestParseURI(t *testing.T) {
+ cases := []struct {
+ Value string
+ Path string
+ Query string
+ }{
+ {
+ Value: "/my/uri/foo/bar/baz",
+ Path: "/my/uri/foo/bar/baz",
+ Query: "",
+ },
+ {
+ Value: "/path?requiredKey",
+ Path: "/path",
+ Query: "requiredKey",
+ },
+ {
+ Value: "/path?",
+ Path: "/path",
+ Query: "",
+ },
+ {
+ Value: "?",
+ Path: "",
+ Query: "",
+ },
+ }
+
+ for i, tt := range cases {
+ t.Run(strconv.Itoa(i), func(t *testing.T) {
+ path, query := SplitURI(tt.Value)
+ if e, a := tt.Path, path; e != a {
+ t.Errorf("expected %v, got %v", e, a)
+ }
+ if e, a := tt.Query, query; e != a {
+ t.Errorf("expected %v, got %v", e, a)
+ }
+ })
+ }
+}
diff --git a/vendor/github.com/aws/smithy-go/encoding/httpbinding/ya.make b/vendor/github.com/aws/smithy-go/encoding/httpbinding/ya.make
new file mode 100644
index 0000000000..f1f0698636
--- /dev/null
+++ b/vendor/github.com/aws/smithy-go/encoding/httpbinding/ya.make
@@ -0,0 +1,26 @@
+GO_LIBRARY()
+
+LICENSE(Apache-2.0)
+
+SRCS(
+ encode.go
+ header.go
+ path_replace.go
+ query.go
+ uri.go
+)
+
+GO_TEST_SRCS(
+ encode_test.go
+ header_test.go
+ path_replace_test.go
+ query_test.go
+ shared_test.go
+ uri_test.go
+)
+
+END()
+
+RECURSE(
+ gotest
+)
diff --git a/vendor/github.com/aws/smithy-go/encoding/json/array.go b/vendor/github.com/aws/smithy-go/encoding/json/array.go
new file mode 100644
index 0000000000..7a232f660f
--- /dev/null
+++ b/vendor/github.com/aws/smithy-go/encoding/json/array.go
@@ -0,0 +1,35 @@
+package json
+
+import (
+ "bytes"
+)
+
+// Array represents the encoding of a JSON Array
+type Array struct {
+ w *bytes.Buffer
+ writeComma bool
+ scratch *[]byte
+}
+
+func newArray(w *bytes.Buffer, scratch *[]byte) *Array {
+ w.WriteRune(leftBracket)
+ return &Array{w: w, scratch: scratch}
+}
+
+// Value adds a new element to the JSON Array.
+// Returns a Value type that is used to encode
+// the array element.
+func (a *Array) Value() Value {
+ if a.writeComma {
+ a.w.WriteRune(comma)
+ } else {
+ a.writeComma = true
+ }
+
+ return newValue(a.w, a.scratch)
+}
+
+// Close encodes the end of the JSON Array
+func (a *Array) Close() {
+ a.w.WriteRune(rightBracket)
+}
diff --git a/vendor/github.com/aws/smithy-go/encoding/json/array_test.go b/vendor/github.com/aws/smithy-go/encoding/json/array_test.go
new file mode 100644
index 0000000000..072a424129
--- /dev/null
+++ b/vendor/github.com/aws/smithy-go/encoding/json/array_test.go
@@ -0,0 +1,21 @@
+package json
+
+import (
+ "bytes"
+ "testing"
+)
+
+func TestArray(t *testing.T) {
+ buffer := bytes.NewBuffer(nil)
+ scratch := make([]byte, 64)
+
+ array := newArray(buffer, &scratch)
+ array.Value().String("bar")
+ array.Value().String("baz")
+ array.Close()
+
+ e := []byte(`["bar","baz"]`)
+ if a := buffer.Bytes(); bytes.Compare(e, a) != 0 {
+ t.Errorf("expected %+q, but got %+q", e, a)
+ }
+}
diff --git a/vendor/github.com/aws/smithy-go/encoding/json/constants.go b/vendor/github.com/aws/smithy-go/encoding/json/constants.go
new file mode 100644
index 0000000000..91044092ae
--- /dev/null
+++ b/vendor/github.com/aws/smithy-go/encoding/json/constants.go
@@ -0,0 +1,15 @@
+package json
+
+const (
+ leftBrace = '{'
+ rightBrace = '}'
+
+ leftBracket = '['
+ rightBracket = ']'
+
+ comma = ','
+ quote = '"'
+ colon = ':'
+
+ null = "null"
+)
diff --git a/vendor/github.com/aws/smithy-go/encoding/json/decoder_util.go b/vendor/github.com/aws/smithy-go/encoding/json/decoder_util.go
new file mode 100644
index 0000000000..7050c85b3c
--- /dev/null
+++ b/vendor/github.com/aws/smithy-go/encoding/json/decoder_util.go
@@ -0,0 +1,139 @@
+package json
+
+import (
+ "bytes"
+ "encoding/json"
+ "fmt"
+ "io"
+)
+
+// DiscardUnknownField discards unknown fields from a decoder body.
+// This function is useful while deserializing a JSON body with additional
+// unknown information that should be discarded.
+func DiscardUnknownField(decoder *json.Decoder) error {
+ // This deliberately does not share logic with CollectUnknownField, even
+ // though it could, because if we were to delegate to that then we'd incur
+ // extra allocations and general memory usage.
+ v, err := decoder.Token()
+ if err == io.EOF {
+ return nil
+ }
+ if err != nil {
+ return err
+ }
+
+ if _, ok := v.(json.Delim); ok {
+ for decoder.More() {
+ err = DiscardUnknownField(decoder)
+ }
+ endToken, err := decoder.Token()
+ if err != nil {
+ return err
+ }
+ if _, ok := endToken.(json.Delim); !ok {
+ return fmt.Errorf("invalid JSON : expected json delimiter, found %T %v",
+ endToken, endToken)
+ }
+ }
+
+ return nil
+}
+
+// CollectUnknownField grabs the contents of unknown fields from the decoder body
+// and returns them as a byte slice. This is useful for skipping unknown fields without
+// completely discarding them.
+func CollectUnknownField(decoder *json.Decoder) ([]byte, error) {
+ result, err := collectUnknownField(decoder)
+ if err != nil {
+ return nil, err
+ }
+
+ buff := bytes.NewBuffer(nil)
+ encoder := json.NewEncoder(buff)
+
+ if err := encoder.Encode(result); err != nil {
+ return nil, err
+ }
+
+ return buff.Bytes(), nil
+}
+
+func collectUnknownField(decoder *json.Decoder) (interface{}, error) {
+ // Grab the initial value. This could either be a concrete value like a string or a a
+ // delimiter.
+ token, err := decoder.Token()
+ if err == io.EOF {
+ return nil, nil
+ }
+ if err != nil {
+ return nil, err
+ }
+
+ // If it's an array or object, we'll need to recurse.
+ delim, ok := token.(json.Delim)
+ if ok {
+ var result interface{}
+ if delim == '{' {
+ result, err = collectUnknownObject(decoder)
+ if err != nil {
+ return nil, err
+ }
+ } else {
+ result, err = collectUnknownArray(decoder)
+ if err != nil {
+ return nil, err
+ }
+ }
+
+ // Discard the closing token. decoder.Token handles checking for matching delimiters
+ if _, err := decoder.Token(); err != nil {
+ return nil, err
+ }
+ return result, nil
+ }
+
+ return token, nil
+}
+
+func collectUnknownArray(decoder *json.Decoder) ([]interface{}, error) {
+ // We need to create an empty array here instead of a nil array, since by getting
+ // into this function at all we necessarily have seen a non-nil list.
+ array := []interface{}{}
+
+ for decoder.More() {
+ value, err := collectUnknownField(decoder)
+ if err != nil {
+ return nil, err
+ }
+ array = append(array, value)
+ }
+
+ return array, nil
+}
+
+func collectUnknownObject(decoder *json.Decoder) (map[string]interface{}, error) {
+ object := make(map[string]interface{})
+
+ for decoder.More() {
+ key, err := collectUnknownField(decoder)
+ if err != nil {
+ return nil, err
+ }
+
+ // Keys have to be strings, which is particularly important as the encoder
+ // won't except a map with interface{} keys
+ stringKey, ok := key.(string)
+ if !ok {
+ return nil, fmt.Errorf("expected string key, found %T", key)
+ }
+
+ value, err := collectUnknownField(decoder)
+ if err != nil {
+ return nil, err
+ }
+
+ object[stringKey] = value
+ }
+
+ return object, nil
+}
diff --git a/vendor/github.com/aws/smithy-go/encoding/json/decoder_util_test.go b/vendor/github.com/aws/smithy-go/encoding/json/decoder_util_test.go
new file mode 100644
index 0000000000..e4cb38e8b7
--- /dev/null
+++ b/vendor/github.com/aws/smithy-go/encoding/json/decoder_util_test.go
@@ -0,0 +1,65 @@
+package json
+
+import (
+ "bytes"
+ "encoding/json"
+ "testing"
+
+ smithytesting "github.com/aws/smithy-go/testing"
+)
+
+func TestDiscardUnknownField(t *testing.T) {
+ cases := map[string][]byte{
+ "empty object": []byte(`{}`),
+ "simple object": []byte(`{"foo": "bar"}`),
+ "nested object": []byte(`{"foo": {"bar": "baz"}}`),
+ "empty list": []byte(`[]`),
+ "simple list": []byte(`["foo", "bar", "baz"]`),
+ "nested list": []byte(`["foo", ["bar", ["baz"]]]`),
+ "number": []byte(`1`),
+ "boolean": []byte(`true`),
+ "null": []byte(`null`),
+ "string": []byte(`"foo"`),
+ }
+
+ for name, c := range cases {
+ t.Run(name, func(t *testing.T) {
+ buff := bytes.NewBuffer(c)
+ decoder := json.NewDecoder(buff)
+ err := DiscardUnknownField(decoder)
+ if err != nil {
+ t.Fatalf("failed to discard, %v", err)
+ }
+ if decoder.More() {
+ t.Fatalf("failed to discard entire contents")
+ }
+ })
+ }
+}
+
+func TestCollectUnknownField(t *testing.T) {
+ cases := map[string][]byte{
+ "empty object": []byte(`{}`),
+ "simple object": []byte(`{"foo": "bar"}`),
+ "nested object": []byte(`{"foo": {"bar": "baz"}}`),
+ "empty list": []byte(`[]`),
+ "simple list": []byte(`["foo", "bar", "baz"]`),
+ "nested list": []byte(`["foo", ["bar", ["baz"]]]`),
+ "number": []byte(`1`),
+ "boolean": []byte(`true`),
+ "null": []byte(`null`),
+ "string": []byte(`"foo"`),
+ }
+
+ for name, c := range cases {
+ t.Run(name, func(t *testing.T) {
+ buff := bytes.NewBuffer(c)
+ decoder := json.NewDecoder(buff)
+ actual, err := CollectUnknownField(decoder)
+ if err != nil {
+ t.Fatalf("failed to collect, %v", err)
+ }
+ smithytesting.AssertJSONEqual(t, c, actual)
+ })
+ }
+}
diff --git a/vendor/github.com/aws/smithy-go/encoding/json/encoder.go b/vendor/github.com/aws/smithy-go/encoding/json/encoder.go
new file mode 100644
index 0000000000..8772953f1e
--- /dev/null
+++ b/vendor/github.com/aws/smithy-go/encoding/json/encoder.go
@@ -0,0 +1,30 @@
+package json
+
+import (
+ "bytes"
+)
+
+// Encoder is JSON encoder that supports construction of JSON values
+// using methods.
+type Encoder struct {
+ w *bytes.Buffer
+ Value
+}
+
+// NewEncoder returns a new JSON encoder
+func NewEncoder() *Encoder {
+ writer := bytes.NewBuffer(nil)
+ scratch := make([]byte, 64)
+
+ return &Encoder{w: writer, Value: newValue(writer, &scratch)}
+}
+
+// String returns the String output of the JSON encoder
+func (e Encoder) String() string {
+ return e.w.String()
+}
+
+// Bytes returns the []byte slice of the JSON encoder
+func (e Encoder) Bytes() []byte {
+ return e.w.Bytes()
+}
diff --git a/vendor/github.com/aws/smithy-go/encoding/json/encoder_test.go b/vendor/github.com/aws/smithy-go/encoding/json/encoder_test.go
new file mode 100644
index 0000000000..d9fbd4ba82
--- /dev/null
+++ b/vendor/github.com/aws/smithy-go/encoding/json/encoder_test.go
@@ -0,0 +1,34 @@
+package json_test
+
+import (
+ "bytes"
+ "testing"
+
+ "github.com/aws/smithy-go/encoding/json"
+)
+
+func TestEncoder(t *testing.T) {
+ encoder := json.NewEncoder()
+
+ object := encoder.Object()
+
+ object.Key("stringKey").String("stringValue")
+ object.Key("integerKey").Long(1024)
+ object.Key("floatKey").Double(3.14)
+
+ subObj := object.Key("foo").Object()
+
+ subObj.Key("byteSlice").Base64EncodeBytes([]byte("foo bar"))
+ subObj.Close()
+
+ object.Close()
+
+ e := []byte(`{"stringKey":"stringValue","integerKey":1024,"floatKey":3.14,"foo":{"byteSlice":"Zm9vIGJhcg=="}}`)
+ if a := encoder.Bytes(); bytes.Compare(e, a) != 0 {
+ t.Errorf("expected %+q, but got %+q", e, a)
+ }
+
+ if a := encoder.String(); string(e) != a {
+ t.Errorf("expected %s, but got %s", e, a)
+ }
+}
diff --git a/vendor/github.com/aws/smithy-go/encoding/json/escape.go b/vendor/github.com/aws/smithy-go/encoding/json/escape.go
new file mode 100644
index 0000000000..d984d0cdca
--- /dev/null
+++ b/vendor/github.com/aws/smithy-go/encoding/json/escape.go
@@ -0,0 +1,198 @@
+// Copyright 2016 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.
+
+// Copied and modified from Go 1.8 stdlib's encoding/json/#safeSet
+
+package json
+
+import (
+ "bytes"
+ "unicode/utf8"
+)
+
+// safeSet holds the value true if the ASCII character with the given array
+// position can be represented inside a JSON string without any further
+// escaping.
+//
+// All values are true except for the ASCII control characters (0-31), the
+// double quote ("), and the backslash character ("\").
+var safeSet = [utf8.RuneSelf]bool{
+ ' ': true,
+ '!': true,
+ '"': false,
+ '#': true,
+ '$': true,
+ '%': true,
+ '&': true,
+ '\'': true,
+ '(': true,
+ ')': true,
+ '*': true,
+ '+': true,
+ ',': true,
+ '-': true,
+ '.': true,
+ '/': true,
+ '0': true,
+ '1': true,
+ '2': true,
+ '3': true,
+ '4': true,
+ '5': true,
+ '6': true,
+ '7': true,
+ '8': true,
+ '9': true,
+ ':': true,
+ ';': true,
+ '<': true,
+ '=': true,
+ '>': true,
+ '?': true,
+ '@': true,
+ 'A': true,
+ 'B': true,
+ 'C': true,
+ 'D': true,
+ 'E': true,
+ 'F': true,
+ 'G': true,
+ 'H': true,
+ 'I': true,
+ 'J': true,
+ 'K': true,
+ 'L': true,
+ 'M': true,
+ 'N': true,
+ 'O': true,
+ 'P': true,
+ 'Q': true,
+ 'R': true,
+ 'S': true,
+ 'T': true,
+ 'U': true,
+ 'V': true,
+ 'W': true,
+ 'X': true,
+ 'Y': true,
+ 'Z': true,
+ '[': true,
+ '\\': false,
+ ']': true,
+ '^': true,
+ '_': true,
+ '`': true,
+ 'a': true,
+ 'b': true,
+ 'c': true,
+ 'd': true,
+ 'e': true,
+ 'f': true,
+ 'g': true,
+ 'h': true,
+ 'i': true,
+ 'j': true,
+ 'k': true,
+ 'l': true,
+ 'm': true,
+ 'n': true,
+ 'o': true,
+ 'p': true,
+ 'q': true,
+ 'r': true,
+ 's': true,
+ 't': true,
+ 'u': true,
+ 'v': true,
+ 'w': true,
+ 'x': true,
+ 'y': true,
+ 'z': true,
+ '{': true,
+ '|': true,
+ '}': true,
+ '~': true,
+ '\u007f': true,
+}
+
+// copied from Go 1.8 stdlib's encoding/json/#hex
+var hex = "0123456789abcdef"
+
+// escapeStringBytes escapes and writes the passed in string bytes to the dst
+// buffer
+//
+// Copied and modifed from Go 1.8 stdlib's encodeing/json/#encodeState.stringBytes
+func escapeStringBytes(e *bytes.Buffer, s []byte) {
+ e.WriteByte('"')
+ start := 0
+ for i := 0; i < len(s); {
+ if b := s[i]; b < utf8.RuneSelf {
+ if safeSet[b] {
+ i++
+ continue
+ }
+ if start < i {
+ e.Write(s[start:i])
+ }
+ switch b {
+ case '\\', '"':
+ e.WriteByte('\\')
+ e.WriteByte(b)
+ case '\n':
+ e.WriteByte('\\')
+ e.WriteByte('n')
+ case '\r':
+ e.WriteByte('\\')
+ e.WriteByte('r')
+ case '\t':
+ e.WriteByte('\\')
+ e.WriteByte('t')
+ default:
+ // This encodes bytes < 0x20 except for \t, \n and \r.
+ // If escapeHTML is set, it also escapes <, >, and &
+ // because they can lead to security holes when
+ // user-controlled strings are rendered into JSON
+ // and served to some browsers.
+ e.WriteString(`\u00`)
+ e.WriteByte(hex[b>>4])
+ e.WriteByte(hex[b&0xF])
+ }
+ i++
+ start = i
+ continue
+ }
+ c, size := utf8.DecodeRune(s[i:])
+ if c == utf8.RuneError && size == 1 {
+ if start < i {
+ e.Write(s[start:i])
+ }
+ e.WriteString(`\ufffd`)
+ i += size
+ start = i
+ continue
+ }
+ // U+2028 is LINE SEPARATOR.
+ // U+2029 is PARAGRAPH SEPARATOR.
+ // They are both technically valid characters in JSON strings,
+ // but don't work in JSONP, which has to be evaluated as JavaScript,
+ // and can lead to security holes there. It is valid JSON to
+ // escape them, so we do so unconditionally.
+ // See http://timelessrepo.com/json-isnt-a-javascript-subset for discussion.
+ if c == '\u2028' || c == '\u2029' {
+ if start < i {
+ e.Write(s[start:i])
+ }
+ e.WriteString(`\u202`)
+ e.WriteByte(hex[c&0xF])
+ i += size
+ start = i
+ continue
+ }
+ i += size
+ }
+ if start < len(s) {
+ e.Write(s[start:])
+ }
+ e.WriteByte('"')
+}
diff --git a/vendor/github.com/aws/smithy-go/encoding/json/escape_test.go b/vendor/github.com/aws/smithy-go/encoding/json/escape_test.go
new file mode 100644
index 0000000000..c3a07a1260
--- /dev/null
+++ b/vendor/github.com/aws/smithy-go/encoding/json/escape_test.go
@@ -0,0 +1,49 @@
+package json
+
+import (
+ "bytes"
+ "testing"
+)
+
+func TestEscapeStringBytes(t *testing.T) {
+ cases := map[string]struct {
+ expected string
+ input []byte
+ }{
+ "safeSet only": {
+ expected: `"mountainPotato"`,
+ input: []byte("mountainPotato"),
+ },
+ "parenthesis": {
+ expected: `"foo\""`,
+ input: []byte(`foo"`),
+ },
+ "double escape": {
+ expected: `"hello\\\\world"`,
+ input: []byte(`hello\\world`),
+ },
+ "new line": {
+ expected: `"foo\nbar"`,
+ input: []byte("foo\nbar"),
+ },
+ "carriage return": {
+ expected: `"foo\rbar"`,
+ input: []byte("foo\rbar"),
+ },
+ "tab": {
+ expected: `"foo\tbar"`,
+ input: []byte("foo\tbar"),
+ },
+ }
+ for name, c := range cases {
+ t.Run(name, func(t *testing.T) {
+ var buffer bytes.Buffer
+ escapeStringBytes(&buffer, c.input)
+ expected := c.expected
+ actual := buffer.String()
+ if expected != actual {
+ t.Errorf("\nexpected %v \nactual %v", expected, actual)
+ }
+ })
+ }
+}
diff --git a/vendor/github.com/aws/smithy-go/encoding/json/gotest/ya.make b/vendor/github.com/aws/smithy-go/encoding/json/gotest/ya.make
new file mode 100644
index 0000000000..8ae1b85797
--- /dev/null
+++ b/vendor/github.com/aws/smithy-go/encoding/json/gotest/ya.make
@@ -0,0 +1,5 @@
+GO_TEST_FOR(vendor/github.com/aws/smithy-go/encoding/json)
+
+LICENSE(Apache-2.0)
+
+END()
diff --git a/vendor/github.com/aws/smithy-go/encoding/json/object.go b/vendor/github.com/aws/smithy-go/encoding/json/object.go
new file mode 100644
index 0000000000..722346d035
--- /dev/null
+++ b/vendor/github.com/aws/smithy-go/encoding/json/object.go
@@ -0,0 +1,40 @@
+package json
+
+import (
+ "bytes"
+)
+
+// Object represents the encoding of a JSON Object type
+type Object struct {
+ w *bytes.Buffer
+ writeComma bool
+ scratch *[]byte
+}
+
+func newObject(w *bytes.Buffer, scratch *[]byte) *Object {
+ w.WriteRune(leftBrace)
+ return &Object{w: w, scratch: scratch}
+}
+
+func (o *Object) writeKey(key string) {
+ escapeStringBytes(o.w, []byte(key))
+ o.w.WriteRune(colon)
+}
+
+// Key adds the given named key to the JSON object.
+// Returns a Value encoder that should be used to encode
+// a JSON value type.
+func (o *Object) Key(name string) Value {
+ if o.writeComma {
+ o.w.WriteRune(comma)
+ } else {
+ o.writeComma = true
+ }
+ o.writeKey(name)
+ return newValue(o.w, o.scratch)
+}
+
+// Close encodes the end of the JSON Object
+func (o *Object) Close() {
+ o.w.WriteRune(rightBrace)
+}
diff --git a/vendor/github.com/aws/smithy-go/encoding/json/object_test.go b/vendor/github.com/aws/smithy-go/encoding/json/object_test.go
new file mode 100644
index 0000000000..1e0830e052
--- /dev/null
+++ b/vendor/github.com/aws/smithy-go/encoding/json/object_test.go
@@ -0,0 +1,34 @@
+package json
+
+import (
+ "bytes"
+ "testing"
+)
+
+func TestObject(t *testing.T) {
+ buffer := bytes.NewBuffer(nil)
+ scratch := make([]byte, 64)
+
+ object := newObject(buffer, &scratch)
+ object.Key("foo").String("bar")
+ object.Key("faz").String("baz")
+ object.Close()
+
+ e := []byte(`{"foo":"bar","faz":"baz"}`)
+ if a := buffer.Bytes(); bytes.Compare(e, a) != 0 {
+ t.Errorf("expected %+q, but got %+q", e, a)
+ }
+}
+
+func TestObjectKey_escaped(t *testing.T) {
+ jsonEncoder := NewEncoder()
+ object := jsonEncoder.Object()
+ object.Key("foo\"").String("bar")
+ object.Key("faz").String("baz")
+ object.Close()
+
+ e := []byte(`{"foo\"":"bar","faz":"baz"}`)
+ if a := object.w.Bytes(); bytes.Compare(e, a) != 0 {
+ t.Errorf("expected %+q, but got %+q", e, a)
+ }
+}
diff --git a/vendor/github.com/aws/smithy-go/encoding/json/value.go b/vendor/github.com/aws/smithy-go/encoding/json/value.go
new file mode 100644
index 0000000000..b41ff1e15c
--- /dev/null
+++ b/vendor/github.com/aws/smithy-go/encoding/json/value.go
@@ -0,0 +1,149 @@
+package json
+
+import (
+ "bytes"
+ "encoding/base64"
+ "math/big"
+ "strconv"
+
+ "github.com/aws/smithy-go/encoding"
+)
+
+// Value represents a JSON Value type
+// JSON Value types: Object, Array, String, Number, Boolean, and Null
+type Value struct {
+ w *bytes.Buffer
+ scratch *[]byte
+}
+
+// newValue returns a new Value encoder
+func newValue(w *bytes.Buffer, scratch *[]byte) Value {
+ return Value{w: w, scratch: scratch}
+}
+
+// String encodes v as a JSON string
+func (jv Value) String(v string) {
+ escapeStringBytes(jv.w, []byte(v))
+}
+
+// Byte encodes v as a JSON number
+func (jv Value) Byte(v int8) {
+ jv.Long(int64(v))
+}
+
+// Short encodes v as a JSON number
+func (jv Value) Short(v int16) {
+ jv.Long(int64(v))
+}
+
+// Integer encodes v as a JSON number
+func (jv Value) Integer(v int32) {
+ jv.Long(int64(v))
+}
+
+// Long encodes v as a JSON number
+func (jv Value) Long(v int64) {
+ *jv.scratch = strconv.AppendInt((*jv.scratch)[:0], v, 10)
+ jv.w.Write(*jv.scratch)
+}
+
+// ULong encodes v as a JSON number
+func (jv Value) ULong(v uint64) {
+ *jv.scratch = strconv.AppendUint((*jv.scratch)[:0], v, 10)
+ jv.w.Write(*jv.scratch)
+}
+
+// Float encodes v as a JSON number
+func (jv Value) Float(v float32) {
+ jv.float(float64(v), 32)
+}
+
+// Double encodes v as a JSON number
+func (jv Value) Double(v float64) {
+ jv.float(v, 64)
+}
+
+func (jv Value) float(v float64, bits int) {
+ *jv.scratch = encoding.EncodeFloat((*jv.scratch)[:0], v, bits)
+ jv.w.Write(*jv.scratch)
+}
+
+// Boolean encodes v as a JSON boolean
+func (jv Value) Boolean(v bool) {
+ *jv.scratch = strconv.AppendBool((*jv.scratch)[:0], v)
+ jv.w.Write(*jv.scratch)
+}
+
+// Base64EncodeBytes writes v as a base64 value in JSON string
+func (jv Value) Base64EncodeBytes(v []byte) {
+ encodeByteSlice(jv.w, (*jv.scratch)[:0], v)
+}
+
+// Write writes v directly to the JSON document
+func (jv Value) Write(v []byte) {
+ jv.w.Write(v)
+}
+
+// Array returns a new Array encoder
+func (jv Value) Array() *Array {
+ return newArray(jv.w, jv.scratch)
+}
+
+// Object returns a new Object encoder
+func (jv Value) Object() *Object {
+ return newObject(jv.w, jv.scratch)
+}
+
+// Null encodes a null JSON value
+func (jv Value) Null() {
+ jv.w.WriteString(null)
+}
+
+// BigInteger encodes v as JSON value
+func (jv Value) BigInteger(v *big.Int) {
+ jv.w.Write([]byte(v.Text(10)))
+}
+
+// BigDecimal encodes v as JSON value
+func (jv Value) BigDecimal(v *big.Float) {
+ if i, accuracy := v.Int64(); accuracy == big.Exact {
+ jv.Long(i)
+ return
+ }
+ // TODO: Should this try to match ES6 ToString similar to stdlib JSON?
+ jv.w.Write([]byte(v.Text('e', -1)))
+}
+
+// Based on encoding/json encodeByteSlice from the Go Standard Library
+// https://golang.org/src/encoding/json/encode.go
+func encodeByteSlice(w *bytes.Buffer, scratch []byte, v []byte) {
+ if v == nil {
+ w.WriteString(null)
+ return
+ }
+
+ w.WriteRune(quote)
+
+ encodedLen := base64.StdEncoding.EncodedLen(len(v))
+ if encodedLen <= len(scratch) {
+ // If the encoded bytes fit in e.scratch, avoid an extra
+ // allocation and use the cheaper Encoding.Encode.
+ dst := scratch[:encodedLen]
+ base64.StdEncoding.Encode(dst, v)
+ w.Write(dst)
+ } else if encodedLen <= 1024 {
+ // The encoded bytes are short enough to allocate for, and
+ // Encoding.Encode is still cheaper.
+ dst := make([]byte, encodedLen)
+ base64.StdEncoding.Encode(dst, v)
+ w.Write(dst)
+ } else {
+ // The encoded bytes are too long to cheaply allocate, and
+ // Encoding.Encode is no longer noticeably cheaper.
+ enc := base64.NewEncoder(base64.StdEncoding, w)
+ enc.Write(v)
+ enc.Close()
+ }
+
+ w.WriteRune(quote)
+}
diff --git a/vendor/github.com/aws/smithy-go/encoding/json/value_test.go b/vendor/github.com/aws/smithy-go/encoding/json/value_test.go
new file mode 100644
index 0000000000..29f0cc562c
--- /dev/null
+++ b/vendor/github.com/aws/smithy-go/encoding/json/value_test.go
@@ -0,0 +1,156 @@
+package json
+
+import (
+ "bytes"
+ "math"
+ "math/big"
+ "strconv"
+ "testing"
+)
+
+var (
+ oneInt = new(big.Int).SetInt64(1)
+ oneFloat = new(big.Float).SetFloat64(1.0)
+)
+
+func TestValue(t *testing.T) {
+ cases := map[string]struct {
+ setter func(Value)
+ expected string
+ }{
+ "string value": {
+ setter: func(value Value) {
+ value.String("foo")
+ },
+ expected: `"foo"`,
+ },
+ "string escaped": {
+ setter: func(value Value) {
+ value.String(`{"foo":"bar"}`)
+ },
+ expected: `"{\"foo\":\"bar\"}"`,
+ },
+ "integer": {
+ setter: func(value Value) {
+ value.Long(1024)
+ },
+ expected: `1024`,
+ },
+ "float": {
+ setter: func(value Value) {
+ value.Double(1e20)
+ },
+ expected: `100000000000000000000`,
+ },
+ "float exponent component": {
+ setter: func(value Value) {
+ value.Double(3e22)
+ },
+ expected: `3e+22`,
+ },
+ "boolean true": {
+ setter: func(value Value) {
+ value.Boolean(true)
+ },
+ expected: `true`,
+ },
+ "boolean false": {
+ setter: func(value Value) {
+ value.Boolean(false)
+ },
+ expected: `false`,
+ },
+ "encode bytes": {
+ setter: func(value Value) {
+ value.Base64EncodeBytes([]byte("foo bar"))
+ },
+ expected: `"Zm9vIGJhcg=="`,
+ },
+ "encode bytes nil": {
+ setter: func(value Value) {
+ value.Base64EncodeBytes(nil)
+ },
+ expected: `null`,
+ },
+ "object": {
+ setter: func(value Value) {
+ o := value.Object()
+ defer o.Close()
+ o.Key("key").String("value")
+ },
+ expected: `{"key":"value"}`,
+ },
+ "array": {
+ setter: func(value Value) {
+ o := value.Array()
+ defer o.Close()
+ o.Value().String("value1")
+ o.Value().String("value2")
+ },
+ expected: `["value1","value2"]`,
+ },
+ "null": {
+ setter: func(value Value) {
+ value.Null()
+ },
+ expected: `null`,
+ },
+ "write bytes": {
+ setter: func(value Value) {
+ o := value.Object()
+ o.Key("inline").Write([]byte(`{"nested":"value"}`))
+ defer o.Close()
+ },
+ expected: `{"inline":{"nested":"value"}}`,
+ },
+ "bigInteger": {
+ setter: func(value Value) {
+ v := new(big.Int).SetInt64(math.MaxInt64)
+ value.BigInteger(v.Sub(v, oneInt))
+ },
+ expected: strconv.FormatInt(math.MaxInt64-1, 10),
+ },
+ "bigInteger > int64": {
+ setter: func(value Value) {
+ v := new(big.Int).SetInt64(math.MaxInt64)
+ value.BigInteger(v.Add(v, oneInt))
+ },
+ expected: "9223372036854775808",
+ },
+ "bigInteger < int64": {
+ setter: func(value Value) {
+ v := new(big.Int).SetInt64(math.MinInt64)
+ value.BigInteger(v.Sub(v, oneInt))
+ },
+ expected: "-9223372036854775809",
+ },
+ "bigFloat": {
+ setter: func(value Value) {
+ v := new(big.Float).SetFloat64(math.MaxFloat64)
+ value.BigDecimal(v.Sub(v, oneFloat))
+ },
+ expected: strconv.FormatFloat(math.MaxFloat64-1, 'e', -1, 64),
+ },
+ "bigFloat fits in int64": {
+ setter: func(value Value) {
+ v := new(big.Float).SetInt64(math.MaxInt64)
+ value.BigDecimal(v)
+ },
+ expected: "9223372036854775807",
+ },
+ }
+ scratch := make([]byte, 64)
+
+ for name, tt := range cases {
+ t.Run(name, func(t *testing.T) {
+ var b bytes.Buffer
+ value := newValue(&b, &scratch)
+
+ tt.setter(value)
+
+ if e, a := []byte(tt.expected), b.Bytes(); bytes.Compare(e, a) != 0 {
+ t.Errorf("expected %+q, but got %+q", e, a)
+ }
+ })
+ }
+}
diff --git a/vendor/github.com/aws/smithy-go/encoding/json/ya.make b/vendor/github.com/aws/smithy-go/encoding/json/ya.make
new file mode 100644
index 0000000000..f43773b0d8
--- /dev/null
+++ b/vendor/github.com/aws/smithy-go/encoding/json/ya.make
@@ -0,0 +1,29 @@
+GO_LIBRARY()
+
+LICENSE(Apache-2.0)
+
+SRCS(
+ array.go
+ constants.go
+ decoder_util.go
+ encoder.go
+ escape.go
+ object.go
+ value.go
+)
+
+GO_TEST_SRCS(
+ array_test.go
+ decoder_util_test.go
+ escape_test.go
+ object_test.go
+ value_test.go
+)
+
+GO_XTEST_SRCS(encoder_test.go)
+
+END()
+
+RECURSE(
+ gotest
+)
diff --git a/vendor/github.com/aws/smithy-go/encoding/xml/array.go b/vendor/github.com/aws/smithy-go/encoding/xml/array.go
new file mode 100644
index 0000000000..508f3c997e
--- /dev/null
+++ b/vendor/github.com/aws/smithy-go/encoding/xml/array.go
@@ -0,0 +1,49 @@
+package xml
+
+// arrayMemberWrapper is the default member wrapper tag name for XML Array type
+var arrayMemberWrapper = StartElement{
+ Name: Name{Local: "member"},
+}
+
+// Array represents the encoding of a XML array type
+type Array struct {
+ w writer
+ scratch *[]byte
+
+ // member start element is the array member wrapper start element
+ memberStartElement StartElement
+
+ // isFlattened indicates if the array is a flattened array.
+ isFlattened bool
+}
+
+// newArray returns an array encoder.
+// It also takes in the member start element, array start element.
+// It takes in a isFlattened bool, indicating that an array is flattened array.
+//
+// A wrapped array ["value1", "value2"] is represented as
+// `<List><member>value1</member><member>value2</member></List>`.
+
+// A flattened array `someList: ["value1", "value2"]` is represented as
+// `<someList>value1</someList><someList>value2</someList>`.
+func newArray(w writer, scratch *[]byte, memberStartElement StartElement, arrayStartElement StartElement, isFlattened bool) *Array {
+ var memberWrapper = memberStartElement
+ if isFlattened {
+ memberWrapper = arrayStartElement
+ }
+
+ return &Array{
+ w: w,
+ scratch: scratch,
+ memberStartElement: memberWrapper,
+ isFlattened: isFlattened,
+ }
+}
+
+// Member adds a new member to the XML array.
+// It returns a Value encoder.
+func (a *Array) Member() Value {
+ v := newValue(a.w, a.scratch, a.memberStartElement)
+ v.isFlattened = a.isFlattened
+ return v
+}
diff --git a/vendor/github.com/aws/smithy-go/encoding/xml/array_test.go b/vendor/github.com/aws/smithy-go/encoding/xml/array_test.go
new file mode 100644
index 0000000000..b0fbbde561
--- /dev/null
+++ b/vendor/github.com/aws/smithy-go/encoding/xml/array_test.go
@@ -0,0 +1,52 @@
+package xml
+
+import (
+ "bytes"
+ "testing"
+)
+
+func TestWrappedArray(t *testing.T) {
+ buffer := bytes.NewBuffer(nil)
+ scratch := make([]byte, 64)
+
+ root := StartElement{Name: Name{Local: "array"}}
+ a := newArray(buffer, &scratch, arrayMemberWrapper, root, false)
+ a.Member().String("bar")
+ a.Member().String("baz")
+
+ e := []byte(`<member>bar</member><member>baz</member>`)
+ if a := buffer.Bytes(); bytes.Compare(e, a) != 0 {
+ t.Errorf("expected %+q, but got %+q", e, a)
+ }
+}
+
+func TestWrappedArrayWithCustomName(t *testing.T) {
+ buffer := bytes.NewBuffer(nil)
+ scratch := make([]byte, 64)
+
+ root := StartElement{Name: Name{Local: "array"}}
+ item := StartElement{Name: Name{Local: "item"}}
+ a := newArray(buffer, &scratch, item, root, false)
+ a.Member().String("bar")
+ a.Member().String("baz")
+
+ e := []byte(`<item>bar</item><item>baz</item>`)
+ if a := buffer.Bytes(); bytes.Compare(e, a) != 0 {
+ t.Errorf("expected %+q, but got %+q", e, a)
+ }
+}
+
+func TestFlattenedArray(t *testing.T) {
+ buffer := bytes.NewBuffer(nil)
+ scratch := make([]byte, 64)
+
+ root := StartElement{Name: Name{Local: "array"}}
+ a := newArray(buffer, &scratch, arrayMemberWrapper, root, true)
+ a.Member().String("bar")
+ a.Member().String("bix")
+
+ e := []byte(`<array>bar</array><array>bix</array>`)
+ if a := buffer.Bytes(); bytes.Compare(e, a) != 0 {
+ t.Errorf("expected %+q, but got %+q", e, a)
+ }
+}
diff --git a/vendor/github.com/aws/smithy-go/encoding/xml/constants.go b/vendor/github.com/aws/smithy-go/encoding/xml/constants.go
new file mode 100644
index 0000000000..ccee90a636
--- /dev/null
+++ b/vendor/github.com/aws/smithy-go/encoding/xml/constants.go
@@ -0,0 +1,10 @@
+package xml
+
+const (
+ leftAngleBracket = '<'
+ rightAngleBracket = '>'
+ forwardSlash = '/'
+ colon = ':'
+ equals = '='
+ quote = '"'
+)
diff --git a/vendor/github.com/aws/smithy-go/encoding/xml/doc.go b/vendor/github.com/aws/smithy-go/encoding/xml/doc.go
new file mode 100644
index 0000000000..f9200093e8
--- /dev/null
+++ b/vendor/github.com/aws/smithy-go/encoding/xml/doc.go
@@ -0,0 +1,49 @@
+/*
+Package xml holds the XMl encoder utility. This utility is written in accordance to our design to delegate to
+shape serializer function in which a xml.Value will be passed around.
+
+Resources followed: https://smithy.io/2.0/spec/protocol-traits.html#xml-bindings
+
+Member Element
+
+Member element should be used to encode xml shapes into xml elements except for flattened xml shapes. Member element
+write their own element start tag. These elements should always be closed.
+
+Flattened Element
+
+Flattened element should be used to encode shapes marked with flattened trait into xml elements. Flattened element
+do not write a start tag, and thus should not be closed.
+
+Simple types encoding
+
+All simple type methods on value such as String(), Long() etc; auto close the associated member element.
+
+Array
+
+Array returns the collection encoder. It has two modes, wrapped and flattened encoding.
+
+Wrapped arrays have two methods Array() and ArrayWithCustomName() which facilitate array member wrapping.
+By default, a wrapped array members are wrapped with `member` named start element.
+
+ <wrappedArray><member>apple</member><member>tree</member></wrappedArray>
+
+Flattened arrays rely on Value being marked as flattened.
+If a shape is marked as flattened, Array() will use the shape element name as wrapper for array elements.
+
+ <flattenedAarray>apple</flattenedArray><flattenedArray>tree</flattenedArray>
+
+Map
+
+Map is the map encoder. It has two modes, wrapped and flattened encoding.
+
+Wrapped map has Array() method, which facilitate map member wrapping.
+By default, a wrapped map members are wrapped with `entry` named start element.
+
+ <wrappedMap><entry><Key>apple</Key><Value>tree</Value></entry><entry><Key>snow</Key><Value>ice</Value></entry></wrappedMap>
+
+Flattened map rely on Value being marked as flattened.
+If a shape is marked as flattened, Map() will use the shape element name as wrapper for map entry elements.
+
+ <flattenedMap><Key>apple</Key><Value>tree</Value></flattenedMap><flattenedMap><Key>snow</Key><Value>ice</Value></flattenedMap>
+*/
+package xml
diff --git a/vendor/github.com/aws/smithy-go/encoding/xml/element.go b/vendor/github.com/aws/smithy-go/encoding/xml/element.go
new file mode 100644
index 0000000000..ae84e7999e
--- /dev/null
+++ b/vendor/github.com/aws/smithy-go/encoding/xml/element.go
@@ -0,0 +1,91 @@
+// Copyright 2009 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.
+
+// Copied and modified from Go 1.14 stdlib's encoding/xml
+
+package xml
+
+// A Name represents an XML name (Local) annotated
+// with a name space identifier (Space).
+// In tokens returned by Decoder.Token, the Space identifier
+// is given as a canonical URL, not the short prefix used
+// in the document being parsed.
+type Name struct {
+ Space, Local string
+}
+
+// An Attr represents an attribute in an XML element (Name=Value).
+type Attr struct {
+ Name Name
+ Value string
+}
+
+/*
+NewAttribute returns a pointer to an attribute.
+It takes in a local name aka attribute name, and value
+representing the attribute value.
+*/
+func NewAttribute(local, value string) Attr {
+ return Attr{
+ Name: Name{
+ Local: local,
+ },
+ Value: value,
+ }
+}
+
+/*
+NewNamespaceAttribute returns a pointer to an attribute.
+It takes in a local name aka attribute name, and value
+representing the attribute value.
+
+NewNamespaceAttribute appends `xmlns:` in front of namespace
+prefix.
+
+For creating a name space attribute representing
+`xmlns:prefix="http://example.com`, the breakdown would be:
+local = "prefix"
+value = "http://example.com"
+*/
+func NewNamespaceAttribute(local, value string) Attr {
+ attr := NewAttribute(local, value)
+
+ // default name space identifier
+ attr.Name.Space = "xmlns"
+ return attr
+}
+
+// A StartElement represents an XML start element.
+type StartElement struct {
+ Name Name
+ Attr []Attr
+}
+
+// Copy creates a new copy of StartElement.
+func (e StartElement) Copy() StartElement {
+ attrs := make([]Attr, len(e.Attr))
+ copy(attrs, e.Attr)
+ e.Attr = attrs
+ return e
+}
+
+// End returns the corresponding XML end element.
+func (e StartElement) End() EndElement {
+ return EndElement{e.Name}
+}
+
+// returns true if start element local name is empty
+func (e StartElement) isZero() bool {
+ return len(e.Name.Local) == 0
+}
+
+// An EndElement represents an XML end element.
+type EndElement struct {
+ Name Name
+}
+
+// returns true if end element local name is empty
+func (e EndElement) isZero() bool {
+ return len(e.Name.Local) == 0
+}
diff --git a/vendor/github.com/aws/smithy-go/encoding/xml/encoder.go b/vendor/github.com/aws/smithy-go/encoding/xml/encoder.go
new file mode 100644
index 0000000000..16fb3dddb0
--- /dev/null
+++ b/vendor/github.com/aws/smithy-go/encoding/xml/encoder.go
@@ -0,0 +1,51 @@
+package xml
+
+// writer interface used by the xml encoder to write an encoded xml
+// document in a writer.
+type writer interface {
+
+ // Write takes in a byte slice and returns number of bytes written and error
+ Write(p []byte) (n int, err error)
+
+ // WriteRune takes in a rune and returns number of bytes written and error
+ WriteRune(r rune) (n int, err error)
+
+ // WriteString takes in a string and returns number of bytes written and error
+ WriteString(s string) (n int, err error)
+
+ // String method returns a string
+ String() string
+
+ // Bytes return a byte slice.
+ Bytes() []byte
+}
+
+// Encoder is an XML encoder that supports construction of XML values
+// using methods. The encoder takes in a writer and maintains a scratch buffer.
+type Encoder struct {
+ w writer
+ scratch *[]byte
+}
+
+// NewEncoder returns an XML encoder
+func NewEncoder(w writer) *Encoder {
+ scratch := make([]byte, 64)
+
+ return &Encoder{w: w, scratch: &scratch}
+}
+
+// String returns the string output of the XML encoder
+func (e Encoder) String() string {
+ return e.w.String()
+}
+
+// Bytes returns the []byte slice of the XML encoder
+func (e Encoder) Bytes() []byte {
+ return e.w.Bytes()
+}
+
+// RootElement builds a root element encoding
+// It writes it's start element tag. The value should be closed.
+func (e Encoder) RootElement(element StartElement) Value {
+ return newValue(e.w, e.scratch, element)
+}
diff --git a/vendor/github.com/aws/smithy-go/encoding/xml/encoder_test.go b/vendor/github.com/aws/smithy-go/encoding/xml/encoder_test.go
new file mode 100644
index 0000000000..c8e31e1bde
--- /dev/null
+++ b/vendor/github.com/aws/smithy-go/encoding/xml/encoder_test.go
@@ -0,0 +1,560 @@
+package xml_test
+
+import (
+ "bytes"
+ "log"
+ "sort"
+ "testing"
+
+ "github.com/aws/smithy-go/encoding/xml"
+)
+
+var root = xml.StartElement{Name: xml.Name{Local: "root"}}
+
+func TestEncoder(t *testing.T) {
+ b := bytes.NewBuffer(nil)
+ encoder := xml.NewEncoder(b)
+
+ func() {
+ root := encoder.RootElement(root)
+ defer root.Close()
+
+ stringKey := xml.StartElement{Name: xml.Name{Local: "stringKey"}}
+ integerKey := xml.StartElement{Name: xml.Name{Local: "integerKey"}}
+ floatKey := xml.StartElement{Name: xml.Name{Local: "floatKey"}}
+ foo := xml.StartElement{Name: xml.Name{Local: "foo"}}
+ byteSlice := xml.StartElement{Name: xml.Name{Local: "byteSlice"}}
+
+ root.MemberElement(stringKey).String("stringValue")
+ root.MemberElement(integerKey).Integer(1024)
+ root.MemberElement(floatKey).Float(3.14)
+
+ ns := root.MemberElement(foo)
+ defer ns.Close()
+ ns.MemberElement(byteSlice).String("Zm9vIGJhcg==")
+ }()
+
+ e := []byte(`<root><stringKey>stringValue</stringKey><integerKey>1024</integerKey><floatKey>3.14</floatKey><foo><byteSlice>Zm9vIGJhcg==</byteSlice></foo></root>`)
+ verify(t, encoder, e)
+}
+
+func TestEncodeAttribute(t *testing.T) {
+ b := bytes.NewBuffer(nil)
+ encoder := xml.NewEncoder(b)
+
+ func() {
+ r := xml.StartElement{
+ Name: xml.Name{Local: "payload", Space: "baz"},
+ Attr: []xml.Attr{
+ xml.NewAttribute("attrkey", "value"),
+ },
+ }
+
+ obj := encoder.RootElement(r)
+ obj.String("")
+ }()
+
+ expect := `<baz:payload attrkey="value"></baz:payload>`
+
+ verify(t, encoder, []byte(expect))
+}
+
+func TestEncodeNamespace(t *testing.T) {
+ b := bytes.NewBuffer(nil)
+ encoder := xml.NewEncoder(b)
+
+ func() {
+ root := encoder.RootElement(root)
+ defer root.Close()
+
+ key := xml.StartElement{
+ Name: xml.Name{Local: "namespace"},
+ Attr: []xml.Attr{
+ xml.NewNamespaceAttribute("prefix", "https://example.com"),
+ },
+ }
+
+ n := root.MemberElement(key)
+ defer n.Close()
+
+ prefix := xml.StartElement{Name: xml.Name{Local: "user"}}
+ n.MemberElement(prefix).String("abc")
+ }()
+
+ e := []byte(`<root><namespace xmlns:prefix="https://example.com"><user>abc</user></namespace></root>`)
+ verify(t, encoder, e)
+}
+
+func TestEncodeEmptyNamespacePrefix(t *testing.T) {
+ b := bytes.NewBuffer(nil)
+ encoder := xml.NewEncoder(b)
+ func() {
+ root := encoder.RootElement(root)
+ defer root.Close()
+
+ key := xml.StartElement{
+ Name: xml.Name{Local: "namespace"},
+ Attr: []xml.Attr{
+ xml.NewNamespaceAttribute("", "https://example.com"),
+ },
+ }
+
+ n := root.MemberElement(key)
+ defer n.Close()
+
+ prefix := xml.StartElement{Name: xml.Name{Local: "user"}}
+ n.MemberElement(prefix).String("abc")
+ }()
+
+ e := []byte(`<root><namespace xmlns="https://example.com"><user>abc</user></namespace></root>`)
+ verify(t, encoder, e)
+}
+
+func verify(t *testing.T, encoder *xml.Encoder, e []byte) {
+ if a := encoder.Bytes(); bytes.Compare(e, a) != 0 {
+ t.Errorf("expected %+q, but got %+q", e, a)
+ }
+
+ if a := encoder.String(); string(encoder.Bytes()) != a {
+ t.Errorf("expected %s, but got %s", e, a)
+ }
+}
+
+func TestEncodeNestedShape(t *testing.T) {
+ b := bytes.NewBuffer(nil)
+ encoder := xml.NewEncoder(b)
+
+ func() {
+ r := encoder.RootElement(root)
+ defer r.Close()
+
+ // nested `nested` shape
+ nested := xml.StartElement{Name: xml.Name{Local: "nested"}}
+ n1 := r.MemberElement(nested)
+ defer n1.Close()
+
+ // nested `value` shape
+ value := xml.StartElement{Name: xml.Name{Local: "value"}}
+ n1.MemberElement(value).String("expected value")
+ }()
+
+ e := []byte(`<root><nested><value>expected value</value></nested></root>`)
+ defer verify(t, encoder, e)
+}
+
+func TestEncodeMapString(t *testing.T) {
+ b := bytes.NewBuffer(nil)
+ encoder := xml.NewEncoder(b)
+ func() {
+ r := encoder.RootElement(root)
+ defer r.Close()
+
+ // nested `mapStr` shape
+ mapstr := xml.StartElement{Name: xml.Name{Local: "mapstr"}}
+ mapElement := r.MemberElement(mapstr)
+ defer mapElement.Close()
+
+ m := mapElement.Map()
+
+ key := xml.StartElement{Name: xml.Name{Local: "key"}}
+ value := xml.StartElement{Name: xml.Name{Local: "value"}}
+
+ e := m.Entry()
+ defer e.Close()
+ e.MemberElement(key).String("abc")
+ e.MemberElement(value).Integer(123)
+ }()
+
+ ex := []byte(`<root><mapstr><entry><key>abc</key><value>123</value></entry></mapstr></root>`)
+ verify(t, encoder, ex)
+}
+
+func TestEncodeMapFlatten(t *testing.T) {
+ b := bytes.NewBuffer(nil)
+ encoder := xml.NewEncoder(b)
+
+ func() {
+ r := encoder.RootElement(root)
+ defer r.Close()
+ // nested `mapStr` shape
+ mapstr := xml.StartElement{Name: xml.Name{Local: "mapstr"}}
+ flatElement := r.FlattenedElement(mapstr)
+
+ m := flatElement.Map()
+ e := m.Entry()
+ defer e.Close()
+
+ key := xml.StartElement{Name: xml.Name{Local: "key"}}
+ e.MemberElement(key).String("abc")
+
+ value := xml.StartElement{Name: xml.Name{Local: "value"}}
+ e.MemberElement(value).Integer(123)
+ }()
+
+ ex := []byte(`<root><mapstr><key>abc</key><value>123</value></mapstr></root>`)
+ verify(t, encoder, ex)
+}
+
+func TestEncodeMapNamed(t *testing.T) {
+ b := bytes.NewBuffer(nil)
+ encoder := xml.NewEncoder(b)
+
+ func() {
+ r := encoder.RootElement(root)
+ defer r.Close()
+ // nested `mapStr` shape
+ mapstr := xml.StartElement{Name: xml.Name{Local: "mapNamed"}}
+ mapElement := r.MemberElement(mapstr)
+ defer mapElement.Close()
+
+ m := mapElement.Map()
+ e := m.Entry()
+ defer e.Close()
+
+ key := xml.StartElement{Name: xml.Name{Local: "namedKey"}}
+ e.MemberElement(key).String("abc")
+
+ value := xml.StartElement{Name: xml.Name{Local: "namedValue"}}
+ e.MemberElement(value).Integer(123)
+ }()
+
+ ex := []byte(`<root><mapNamed><entry><namedKey>abc</namedKey><namedValue>123</namedValue></entry></mapNamed></root>`)
+ verify(t, encoder, ex)
+}
+
+func TestEncodeMapShape(t *testing.T) {
+ b := bytes.NewBuffer(nil)
+ encoder := xml.NewEncoder(b)
+
+ func() {
+ r := encoder.RootElement(root)
+ defer r.Close()
+
+ // nested `mapStr` shape
+ mapstr := xml.StartElement{Name: xml.Name{Local: "mapShape"}}
+ mapElement := r.MemberElement(mapstr)
+ defer mapElement.Close()
+
+ m := mapElement.Map()
+
+ e := m.Entry()
+ defer e.Close()
+
+ key := xml.StartElement{Name: xml.Name{Local: "key"}}
+ e.MemberElement(key).String("abc")
+
+ value := xml.StartElement{Name: xml.Name{Local: "value"}}
+ n1 := e.MemberElement(value)
+ defer n1.Close()
+
+ shapeVal := xml.StartElement{Name: xml.Name{Local: "shapeVal"}}
+ n1.MemberElement(shapeVal).Integer(1)
+ }()
+
+ ex := []byte(`<root><mapShape><entry><key>abc</key><value><shapeVal>1</shapeVal></value></entry></mapShape></root>`)
+ verify(t, encoder, ex)
+}
+
+func TestEncodeMapFlattenShape(t *testing.T) {
+ b := bytes.NewBuffer(nil)
+ encoder := xml.NewEncoder(b)
+
+ func() {
+ r := encoder.RootElement(root)
+ defer r.Close()
+ // nested `mapStr` shape
+ mapstr := xml.StartElement{Name: xml.Name{Local: "mapShape"}}
+ flatElement := r.FlattenedElement(mapstr)
+ m := flatElement.Map()
+
+ e := m.Entry()
+ defer e.Close()
+
+ key := xml.StartElement{Name: xml.Name{Local: "key"}}
+ e.MemberElement(key).String("abc")
+
+ value := xml.StartElement{Name: xml.Name{Local: "value"}}
+ n1 := e.MemberElement(value)
+ defer n1.Close()
+
+ shapeVal := xml.StartElement{Name: xml.Name{Local: "shapeVal"}}
+ n1.MemberElement(shapeVal).Integer(1)
+ }()
+ ex := []byte(`<root><mapShape><key>abc</key><value><shapeVal>1</shapeVal></value></mapShape></root>`)
+ verify(t, encoder, ex)
+}
+
+func TestEncodeMapNamedShape(t *testing.T) {
+ b := bytes.NewBuffer(nil)
+ encoder := xml.NewEncoder(b)
+
+ func() {
+ r := encoder.RootElement(root)
+ defer r.Close()
+
+ // nested `mapStr` shape
+ mapstr := xml.StartElement{Name: xml.Name{Local: "mapNamedShape"}}
+ mapElement := r.MemberElement(mapstr)
+ defer mapElement.Close()
+
+ m := mapElement.Map()
+ e := m.Entry()
+ defer e.Close()
+
+ key := xml.StartElement{Name: xml.Name{Local: "namedKey"}}
+ e.MemberElement(key).String("abc")
+
+ value := xml.StartElement{Name: xml.Name{Local: "namedValue"}}
+ n1 := e.MemberElement(value)
+ defer n1.Close()
+
+ shapeVal := xml.StartElement{Name: xml.Name{Local: "shapeVal"}}
+ n1.MemberElement(shapeVal).Integer(1)
+ }()
+
+ ex := []byte(`<root><mapNamedShape><entry><namedKey>abc</namedKey><namedValue><shapeVal>1</shapeVal></namedValue></entry></mapNamedShape></root>`)
+ verify(t, encoder, ex)
+}
+
+func TestEncodeListString(t *testing.T) {
+ b := bytes.NewBuffer(nil)
+ encoder := xml.NewEncoder(b)
+
+ func() {
+ r := encoder.RootElement(root)
+ defer r.Close()
+
+ // Object key `liststr`
+ liststr := xml.StartElement{Name: xml.Name{Local: "liststr"}}
+ m := r.MemberElement(liststr)
+ defer m.Close()
+
+ a := m.Array()
+ a.Member().String("abc")
+ a.Member().Integer(123)
+ }()
+
+ ex := []byte(`<root><liststr><member>abc</member><member>123</member></liststr></root>`)
+ verify(t, encoder, ex)
+}
+
+func TestEncodeListFlatten(t *testing.T) {
+ b := bytes.NewBuffer(nil)
+ encoder := xml.NewEncoder(b)
+
+ func() {
+ r := encoder.RootElement(root)
+ defer r.Close()
+
+ // Object key `liststr`
+ liststr := xml.StartElement{Name: xml.Name{Local: "liststr"}}
+ m := r.FlattenedElement(liststr)
+
+ a := m.Array()
+ a.Member().String("abc")
+ a.Member().Integer(123)
+ }()
+
+ ex := []byte(`<root><liststr>abc</liststr><liststr>123</liststr></root>`)
+ verify(t, encoder, ex)
+}
+
+func TestEncodeListNamed(t *testing.T) {
+ b := bytes.NewBuffer(nil)
+ encoder := xml.NewEncoder(b)
+
+ func() {
+ r := encoder.RootElement(root)
+ defer r.Close()
+
+ // Object key `liststr`
+ liststr := xml.StartElement{Name: xml.Name{Local: "liststr"}}
+
+ namedMember := xml.StartElement{Name: xml.Name{Local: "namedMember"}}
+ m := r.MemberElement(liststr)
+ defer m.Close()
+
+ a := m.ArrayWithCustomName(namedMember)
+ a.Member().String("abc")
+ a.Member().Integer(123)
+ }()
+
+ ex := []byte(`<root><liststr><namedMember>abc</namedMember><namedMember>123</namedMember></liststr></root>`)
+ verify(t, encoder, ex)
+}
+
+//
+func TestEncodeListShape(t *testing.T) {
+ b := bytes.NewBuffer(nil)
+ encoder := xml.NewEncoder(b)
+
+ func() {
+ r := encoder.RootElement(root)
+ defer r.Close()
+
+ // Object key `liststr`
+ liststr := xml.StartElement{Name: xml.Name{Local: "liststr"}}
+
+ m := r.MemberElement(liststr)
+ defer m.Close()
+
+ a := m.Array()
+
+ value := xml.StartElement{Name: xml.Name{Local: "value"}}
+
+ m1 := a.Member()
+ m1.MemberElement(value).String("abc")
+ m1.Close()
+
+ m2 := a.Member()
+ m2.MemberElement(value).Integer(123)
+ m2.Close()
+ }()
+
+ ex := []byte(`<root><liststr><member><value>abc</value></member><member><value>123</value></member></liststr></root>`)
+ verify(t, encoder, ex)
+}
+
+//
+func TestEncodeListFlattenShape(t *testing.T) {
+ b := bytes.NewBuffer(nil)
+ encoder := xml.NewEncoder(b)
+
+ func() {
+ r := encoder.RootElement(root)
+ defer r.Close()
+
+ // Object key `liststr`
+ liststr := xml.StartElement{Name: xml.Name{Local: "liststr"}}
+
+ m := r.FlattenedElement(liststr)
+
+ a := m.Array()
+ value := xml.StartElement{Name: xml.Name{Local: "value"}}
+
+ m1 := a.Member()
+ m1.MemberElement(value).String("abc")
+ m1.Close()
+
+ m2 := a.Member()
+ m2.MemberElement(value).Integer(123)
+ m2.Close()
+ }()
+
+ ex := []byte(`<root><liststr><value>abc</value></liststr><liststr><value>123</value></liststr></root>`)
+ verify(t, encoder, ex)
+}
+
+//
+func TestEncodeListNamedShape(t *testing.T) {
+ b := bytes.NewBuffer(nil)
+ encoder := xml.NewEncoder(b)
+
+ func() {
+ r := encoder.RootElement(root)
+ defer r.Close()
+
+ // Object key `liststr`
+ liststr := xml.StartElement{Name: xml.Name{Local: "liststr"}}
+ namedMember := xml.StartElement{Name: xml.Name{Local: "namedMember"}}
+
+ // member element
+ m := r.MemberElement(liststr)
+ defer m.Close()
+
+ // Build array
+ a := m.ArrayWithCustomName(namedMember)
+
+ value := xml.StartElement{Name: xml.Name{Local: "value"}}
+ m1 := a.Member()
+ m1.MemberElement(value).String("abc")
+ m1.Close()
+
+ m2 := a.Member()
+ m2.MemberElement(value).Integer(123)
+ m2.Close()
+ }()
+
+ ex := []byte(`<root><liststr><namedMember><value>abc</value></namedMember><namedMember><value>123</value></namedMember></liststr></root>`)
+ verify(t, encoder, ex)
+}
+
+func TestEncodeEscaping(t *testing.T) {
+ b := bytes.NewBuffer(nil)
+ encoder := xml.NewEncoder(b)
+
+ func() {
+ r := encoder.RootElement(root)
+ defer r.Close()
+
+ cases := map[string]rune{
+ "quote": '"',
+ "apos": '\'',
+ "amp": '&',
+ "lt": '<',
+ "gt": '>',
+ "tab": '\t',
+ "newLine": '\n',
+ "carriageReturn": '\r',
+ "nextLine": '\u0085',
+ "lineSeparator": '\u2028',
+ }
+
+ var sortedKeys []string
+ for name := range cases {
+ sortedKeys = append(sortedKeys, name)
+ }
+
+ sort.Strings(sortedKeys)
+
+ for _, name := range sortedKeys {
+ rr := cases[name]
+
+ st := xml.StartElement{Name: xml.Name{Local: name}}
+ st.Attr = append(st.Attr, xml.Attr{
+ Name: xml.Name{
+ Local: "key",
+ },
+ Value: name + string(rr) + name,
+ })
+ value := r.MemberElement(st)
+ value.String(name + string(rr) + name)
+ }
+ }()
+
+ ex := []byte(`<root><amp key="amp&amp;amp">amp&amp;amp</amp><apos key="apos&#39;apos">apos&#39;apos</apos><carriageReturn key="carriageReturn&#xD;carriageReturn">carriageReturn&#xD;carriageReturn</carriageReturn><gt key="gt&gt;gt">gt&gt;gt</gt><lineSeparator key="lineSeparator&#x2028;lineSeparator">lineSeparator&#x2028;lineSeparator</lineSeparator><lt key="lt&lt;lt">lt&lt;lt</lt><newLine key="newLine&#xA;newLine">newLine&#xA;newLine</newLine><nextLine key="nextLine&#x85;nextLine">nextLine&#x85;nextLine</nextLine><quote key="quote&#34;quote">quote&#34;quote</quote><tab key="tab&#x9;tab">tab&#x9;tab</tab></root>`)
+ verify(t, encoder, ex)
+}
+
+// ExampleEncoder is the example function on how to use an encoder
+func ExampleEncoder() {
+ b := bytes.NewBuffer(nil)
+ encoder := xml.NewEncoder(b)
+
+ // expected encoded xml document is :
+ // `<root><liststr><namedMember><value>abc</value></namedMember><namedMember><value>123</value></namedMember></liststr></root>`
+ defer log.Printf("Encoded xml document: %v", encoder.String())
+
+ r := encoder.RootElement(root)
+ defer r.Close()
+
+ // Object key `liststr`
+ liststr := xml.StartElement{Name: xml.Name{Local: "liststr"}}
+ namedMember := xml.StartElement{Name: xml.Name{Local: "namedMember"}}
+
+ // member element
+ m := r.MemberElement(liststr)
+ defer m.Close()
+
+ // Build array
+ a := m.ArrayWithCustomName(namedMember)
+
+ value := xml.StartElement{Name: xml.Name{Local: "value"}}
+ m1 := a.Member()
+ m1.MemberElement(value).String("abc")
+ m1.Close()
+
+ m2 := a.Member()
+ m2.MemberElement(value).Integer(123)
+ m2.Close()
+}
diff --git a/vendor/github.com/aws/smithy-go/encoding/xml/error_utils.go b/vendor/github.com/aws/smithy-go/encoding/xml/error_utils.go
new file mode 100644
index 0000000000..f3db6ccca8
--- /dev/null
+++ b/vendor/github.com/aws/smithy-go/encoding/xml/error_utils.go
@@ -0,0 +1,51 @@
+package xml
+
+import (
+ "encoding/xml"
+ "fmt"
+ "io"
+)
+
+// ErrorComponents represents the error response fields
+// that will be deserialized from an xml error response body
+type ErrorComponents struct {
+ Code string
+ Message string
+}
+
+// GetErrorResponseComponents returns the error fields from an xml error response body
+func GetErrorResponseComponents(r io.Reader, noErrorWrapping bool) (ErrorComponents, error) {
+ if noErrorWrapping {
+ var errResponse noWrappedErrorResponse
+ if err := xml.NewDecoder(r).Decode(&errResponse); err != nil && err != io.EOF {
+ return ErrorComponents{}, fmt.Errorf("error while deserializing xml error response: %w", err)
+ }
+ return ErrorComponents{
+ Code: errResponse.Code,
+ Message: errResponse.Message,
+ }, nil
+ }
+
+ var errResponse wrappedErrorResponse
+ if err := xml.NewDecoder(r).Decode(&errResponse); err != nil && err != io.EOF {
+ return ErrorComponents{}, fmt.Errorf("error while deserializing xml error response: %w", err)
+ }
+ return ErrorComponents{
+ Code: errResponse.Code,
+ Message: errResponse.Message,
+ }, nil
+}
+
+// noWrappedErrorResponse represents the error response body with
+// no internal <Error></Error wrapping
+type noWrappedErrorResponse struct {
+ Code string `xml:"Code"`
+ Message string `xml:"Message"`
+}
+
+// wrappedErrorResponse represents the error response body
+// wrapped within <Error>...</Error>
+type wrappedErrorResponse struct {
+ Code string `xml:"Error>Code"`
+ Message string `xml:"Error>Message"`
+}
diff --git a/vendor/github.com/aws/smithy-go/encoding/xml/error_utils_test.go b/vendor/github.com/aws/smithy-go/encoding/xml/error_utils_test.go
new file mode 100644
index 0000000000..0077d166d0
--- /dev/null
+++ b/vendor/github.com/aws/smithy-go/encoding/xml/error_utils_test.go
@@ -0,0 +1,62 @@
+package xml
+
+import (
+ "bytes"
+ "io"
+ "strings"
+ "testing"
+)
+
+func TestGetResponseErrorCode(t *testing.T) {
+ cases := map[string]struct {
+ errorResponse io.Reader
+ noErrorWrappingEnabled bool
+ expectedErrorCode string
+ expectedErrorMessage string
+ }{
+ "no error wrapping enabled": {
+ errorResponse: bytes.NewReader([]byte(`<ErrorResponse>
+ <Error>
+ <Type>Sender</Type>
+ <Code>InvalidGreeting</Code>
+ <Message>Hi</Message>
+ <AnotherSetting>setting</AnotherSetting>
+ </Error>
+ <RequestId>foo-id</RequestId>
+</ErrorResponse>`)),
+ expectedErrorCode: "InvalidGreeting",
+ expectedErrorMessage: "Hi",
+ },
+ "no error wrapping disabled": {
+ errorResponse: bytes.NewReader([]byte(`<ErrorResponse>
+ <Type>Sender</Type>
+ <Code>InvalidGreeting</Code>
+ <Message>Hi</Message>
+ <AnotherSetting>setting</AnotherSetting>
+ <RequestId>foo-id</RequestId>
+</ErrorResponse>`)),
+ noErrorWrappingEnabled: true,
+ expectedErrorCode: "InvalidGreeting",
+ expectedErrorMessage: "Hi",
+ },
+ "no response body": {
+ errorResponse: bytes.NewReader([]byte(``)),
+ },
+ }
+
+ for name, c := range cases {
+ t.Run(name, func(t *testing.T) {
+ ec, err := GetErrorResponseComponents(c.errorResponse, c.noErrorWrappingEnabled)
+ if err != nil {
+ t.Fatalf("expected no error, got %v", err)
+ }
+
+ if e, a := c.expectedErrorCode, ec.Code; !strings.EqualFold(e, a) {
+ t.Fatalf("expected %v, got %v", e, a)
+ }
+ if e, a := c.expectedErrorMessage, ec.Message; !strings.EqualFold(e, a) {
+ t.Fatalf("expected %v, got %v", e, a)
+ }
+ })
+ }
+}
diff --git a/vendor/github.com/aws/smithy-go/encoding/xml/escape.go b/vendor/github.com/aws/smithy-go/encoding/xml/escape.go
new file mode 100644
index 0000000000..1c5479af67
--- /dev/null
+++ b/vendor/github.com/aws/smithy-go/encoding/xml/escape.go
@@ -0,0 +1,137 @@
+// Copyright 2009 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.
+
+// Copied and modified from Go 1.14 stdlib's encoding/xml
+
+package xml
+
+import (
+ "unicode/utf8"
+)
+
+// Copied from Go 1.14 stdlib's encoding/xml
+var (
+ escQuot = []byte("&#34;") // shorter than "&quot;"
+ escApos = []byte("&#39;") // shorter than "&apos;"
+ escAmp = []byte("&amp;")
+ escLT = []byte("&lt;")
+ escGT = []byte("&gt;")
+ escTab = []byte("&#x9;")
+ escNL = []byte("&#xA;")
+ escCR = []byte("&#xD;")
+ escFFFD = []byte("\uFFFD") // Unicode replacement character
+
+ // Additional Escapes
+ escNextLine = []byte("&#x85;")
+ escLS = []byte("&#x2028;")
+)
+
+// Decide whether the given rune is in the XML Character Range, per
+// the Char production of https://www.xml.com/axml/testaxml.htm,
+// Section 2.2 Characters.
+func isInCharacterRange(r rune) (inrange bool) {
+ return r == 0x09 ||
+ r == 0x0A ||
+ r == 0x0D ||
+ r >= 0x20 && r <= 0xD7FF ||
+ r >= 0xE000 && r <= 0xFFFD ||
+ r >= 0x10000 && r <= 0x10FFFF
+}
+
+// TODO: When do we need to escape the string?
+// Based on encoding/xml escapeString from the Go Standard Library.
+// https://golang.org/src/encoding/xml/xml.go
+func escapeString(e writer, s string) {
+ var esc []byte
+ last := 0
+ for i := 0; i < len(s); {
+ r, width := utf8.DecodeRuneInString(s[i:])
+ i += width
+ switch r {
+ case '"':
+ esc = escQuot
+ case '\'':
+ esc = escApos
+ case '&':
+ esc = escAmp
+ case '<':
+ esc = escLT
+ case '>':
+ esc = escGT
+ case '\t':
+ esc = escTab
+ case '\n':
+ esc = escNL
+ case '\r':
+ esc = escCR
+ case '\u0085':
+ // Not escaped by stdlib
+ esc = escNextLine
+ case '\u2028':
+ // Not escaped by stdlib
+ esc = escLS
+ default:
+ if !isInCharacterRange(r) || (r == 0xFFFD && width == 1) {
+ esc = escFFFD
+ break
+ }
+ continue
+ }
+ e.WriteString(s[last : i-width])
+ e.Write(esc)
+ last = i
+ }
+ e.WriteString(s[last:])
+}
+
+// escapeText writes to w the properly escaped XML equivalent
+// of the plain text data s. If escapeNewline is true, newline
+// characters will be escaped.
+//
+// Based on encoding/xml escapeText from the Go Standard Library.
+// https://golang.org/src/encoding/xml/xml.go
+func escapeText(e writer, s []byte) {
+ var esc []byte
+ last := 0
+ for i := 0; i < len(s); {
+ r, width := utf8.DecodeRune(s[i:])
+ i += width
+ switch r {
+ case '"':
+ esc = escQuot
+ case '\'':
+ esc = escApos
+ case '&':
+ esc = escAmp
+ case '<':
+ esc = escLT
+ case '>':
+ esc = escGT
+ case '\t':
+ esc = escTab
+ case '\n':
+ // This always escapes newline, which is different than stdlib's optional
+ // escape of new line.
+ esc = escNL
+ case '\r':
+ esc = escCR
+ case '\u0085':
+ // Not escaped by stdlib
+ esc = escNextLine
+ case '\u2028':
+ // Not escaped by stdlib
+ esc = escLS
+ default:
+ if !isInCharacterRange(r) || (r == 0xFFFD && width == 1) {
+ esc = escFFFD
+ break
+ }
+ continue
+ }
+ e.Write(s[last : i-width])
+ e.Write(esc)
+ last = i
+ }
+ e.Write(s[last:])
+}
diff --git a/vendor/github.com/aws/smithy-go/encoding/xml/gotest/ya.make b/vendor/github.com/aws/smithy-go/encoding/xml/gotest/ya.make
new file mode 100644
index 0000000000..a47e23603b
--- /dev/null
+++ b/vendor/github.com/aws/smithy-go/encoding/xml/gotest/ya.make
@@ -0,0 +1,5 @@
+GO_TEST_FOR(vendor/github.com/aws/smithy-go/encoding/xml)
+
+LICENSE(Apache-2.0)
+
+END()
diff --git a/vendor/github.com/aws/smithy-go/encoding/xml/map.go b/vendor/github.com/aws/smithy-go/encoding/xml/map.go
new file mode 100644
index 0000000000..e42858965c
--- /dev/null
+++ b/vendor/github.com/aws/smithy-go/encoding/xml/map.go
@@ -0,0 +1,53 @@
+package xml
+
+// mapEntryWrapper is the default member wrapper start element for XML Map entry
+var mapEntryWrapper = StartElement{
+ Name: Name{Local: "entry"},
+}
+
+// Map represents the encoding of a XML map type
+type Map struct {
+ w writer
+ scratch *[]byte
+
+ // member start element is the map entry wrapper start element
+ memberStartElement StartElement
+
+ // isFlattened returns true if the map is a flattened map
+ isFlattened bool
+}
+
+// newMap returns a map encoder which sets the default map
+// entry wrapper to `entry`.
+//
+// A map `someMap : {{key:"abc", value:"123"}}` is represented as
+// `<someMap><entry><key>abc<key><value>123</value></entry></someMap>`.
+func newMap(w writer, scratch *[]byte) *Map {
+ return &Map{
+ w: w,
+ scratch: scratch,
+ memberStartElement: mapEntryWrapper,
+ }
+}
+
+// newFlattenedMap returns a map encoder which sets the map
+// entry wrapper to the passed in memberWrapper`.
+//
+// A flattened map `someMap : {{key:"abc", value:"123"}}` is represented as
+// `<someMap><key>abc<key><value>123</value></someMap>`.
+func newFlattenedMap(w writer, scratch *[]byte, memberWrapper StartElement) *Map {
+ return &Map{
+ w: w,
+ scratch: scratch,
+ memberStartElement: memberWrapper,
+ isFlattened: true,
+ }
+}
+
+// Entry returns a Value encoder with map's element.
+// It writes the member wrapper start tag for each entry.
+func (m *Map) Entry() Value {
+ v := newValue(m.w, m.scratch, m.memberStartElement)
+ v.isFlattened = m.isFlattened
+ return v
+}
diff --git a/vendor/github.com/aws/smithy-go/encoding/xml/map_test.go b/vendor/github.com/aws/smithy-go/encoding/xml/map_test.go
new file mode 100644
index 0000000000..022165bd6d
--- /dev/null
+++ b/vendor/github.com/aws/smithy-go/encoding/xml/map_test.go
@@ -0,0 +1,77 @@
+package xml
+
+import (
+ "bytes"
+ "testing"
+)
+
+func TestWrappedMap(t *testing.T) {
+ buffer := bytes.NewBuffer(nil)
+ scratch := make([]byte, 64)
+
+ func() {
+ m := newMap(buffer, &scratch)
+
+ key := StartElement{Name: Name{Local: "key"}}
+ value := StartElement{Name: Name{Local: "value"}}
+
+ // map entry
+ e := m.Entry()
+ e.MemberElement(key).String("example-key1")
+ e.MemberElement(value).String("example1")
+ e.Close()
+
+ // map entry
+ e = m.Entry()
+ e.MemberElement(key).String("example-key2")
+ e.MemberElement(value).String("example2")
+ e.Close()
+
+ // map entry
+ e = m.Entry()
+ e.MemberElement(key).String("example-key3")
+ e.MemberElement(value).String("example3")
+ e.Close()
+ }()
+
+ ex := []byte(`<entry><key>example-key1</key><value>example1</value></entry><entry><key>example-key2</key><value>example2</value></entry><entry><key>example-key3</key><value>example3</value></entry>`)
+ if a := buffer.Bytes(); bytes.Compare(ex, a) != 0 {
+ t.Errorf("expected %+q, but got %+q", ex, a)
+ }
+}
+
+func TestFlattenedMapWithCustomName(t *testing.T) {
+ buffer := bytes.NewBuffer(nil)
+ scratch := make([]byte, 64)
+
+ func() {
+ root := StartElement{Name: Name{Local: "flatMap"}}
+ m := newFlattenedMap(buffer, &scratch, root)
+
+ key := StartElement{Name: Name{Local: "key"}}
+ value := StartElement{Name: Name{Local: "value"}}
+
+ // map entry
+ e := m.Entry()
+ e.MemberElement(key).String("example-key1")
+ e.MemberElement(value).String("example1")
+ e.Close()
+
+ // map entry
+ e = m.Entry()
+ e.MemberElement(key).String("example-key2")
+ e.MemberElement(value).String("example2")
+ e.Close()
+
+ // map entry
+ e = m.Entry()
+ e.MemberElement(key).String("example-key3")
+ e.MemberElement(value).String("example3")
+ e.Close()
+ }()
+
+ ex := []byte(`<flatMap><key>example-key1</key><value>example1</value></flatMap><flatMap><key>example-key2</key><value>example2</value></flatMap><flatMap><key>example-key3</key><value>example3</value></flatMap>`)
+ if a := buffer.Bytes(); bytes.Compare(ex, a) != 0 {
+ t.Errorf("expected %+q, but got %+q", ex, a)
+ }
+}
diff --git a/vendor/github.com/aws/smithy-go/encoding/xml/value.go b/vendor/github.com/aws/smithy-go/encoding/xml/value.go
new file mode 100644
index 0000000000..09434b2c0b
--- /dev/null
+++ b/vendor/github.com/aws/smithy-go/encoding/xml/value.go
@@ -0,0 +1,302 @@
+package xml
+
+import (
+ "encoding/base64"
+ "fmt"
+ "math/big"
+ "strconv"
+
+ "github.com/aws/smithy-go/encoding"
+)
+
+// Value represents an XML Value type
+// XML Value types: Object, Array, Map, String, Number, Boolean.
+type Value struct {
+ w writer
+ scratch *[]byte
+
+ // xml start element is the associated start element for the Value
+ startElement StartElement
+
+ // indicates if the Value represents a flattened shape
+ isFlattened bool
+}
+
+// newFlattenedValue returns a Value encoder. newFlattenedValue does NOT write the start element tag
+func newFlattenedValue(w writer, scratch *[]byte, startElement StartElement) Value {
+ return Value{
+ w: w,
+ scratch: scratch,
+ startElement: startElement,
+ }
+}
+
+// newValue writes the start element xml tag and returns a Value
+func newValue(w writer, scratch *[]byte, startElement StartElement) Value {
+ writeStartElement(w, startElement)
+ return Value{w: w, scratch: scratch, startElement: startElement}
+}
+
+// writeStartElement takes in a start element and writes it.
+// It handles namespace, attributes in start element.
+func writeStartElement(w writer, el StartElement) error {
+ if el.isZero() {
+ return fmt.Errorf("xml start element cannot be nil")
+ }
+
+ w.WriteRune(leftAngleBracket)
+
+ if len(el.Name.Space) != 0 {
+ escapeString(w, el.Name.Space)
+ w.WriteRune(colon)
+ }
+ escapeString(w, el.Name.Local)
+ for _, attr := range el.Attr {
+ w.WriteRune(' ')
+ writeAttribute(w, &attr)
+ }
+
+ w.WriteRune(rightAngleBracket)
+ return nil
+}
+
+// writeAttribute writes an attribute from a provided Attribute
+// For a namespace attribute, the attr.Name.Space must be defined as "xmlns".
+// https://www.w3.org/TR/REC-xml-names/#NT-DefaultAttName
+func writeAttribute(w writer, attr *Attr) {
+ // if local, space both are not empty
+ if len(attr.Name.Space) != 0 && len(attr.Name.Local) != 0 {
+ escapeString(w, attr.Name.Space)
+ w.WriteRune(colon)
+ }
+
+ // if prefix is empty, the default `xmlns` space should be used as prefix.
+ if len(attr.Name.Local) == 0 {
+ attr.Name.Local = attr.Name.Space
+ }
+
+ escapeString(w, attr.Name.Local)
+ w.WriteRune(equals)
+ w.WriteRune(quote)
+ escapeString(w, attr.Value)
+ w.WriteRune(quote)
+}
+
+// writeEndElement takes in a end element and writes it.
+func writeEndElement(w writer, el EndElement) error {
+ if el.isZero() {
+ return fmt.Errorf("xml end element cannot be nil")
+ }
+
+ w.WriteRune(leftAngleBracket)
+ w.WriteRune(forwardSlash)
+
+ if len(el.Name.Space) != 0 {
+ escapeString(w, el.Name.Space)
+ w.WriteRune(colon)
+ }
+ escapeString(w, el.Name.Local)
+ w.WriteRune(rightAngleBracket)
+
+ return nil
+}
+
+// String encodes v as a XML string.
+// It will auto close the parent xml element tag.
+func (xv Value) String(v string) {
+ escapeString(xv.w, v)
+ xv.Close()
+}
+
+// Byte encodes v as a XML number.
+// It will auto close the parent xml element tag.
+func (xv Value) Byte(v int8) {
+ xv.Long(int64(v))
+}
+
+// Short encodes v as a XML number.
+// It will auto close the parent xml element tag.
+func (xv Value) Short(v int16) {
+ xv.Long(int64(v))
+}
+
+// Integer encodes v as a XML number.
+// It will auto close the parent xml element tag.
+func (xv Value) Integer(v int32) {
+ xv.Long(int64(v))
+}
+
+// Long encodes v as a XML number.
+// It will auto close the parent xml element tag.
+func (xv Value) Long(v int64) {
+ *xv.scratch = strconv.AppendInt((*xv.scratch)[:0], v, 10)
+ xv.w.Write(*xv.scratch)
+
+ xv.Close()
+}
+
+// Float encodes v as a XML number.
+// It will auto close the parent xml element tag.
+func (xv Value) Float(v float32) {
+ xv.float(float64(v), 32)
+ xv.Close()
+}
+
+// Double encodes v as a XML number.
+// It will auto close the parent xml element tag.
+func (xv Value) Double(v float64) {
+ xv.float(v, 64)
+ xv.Close()
+}
+
+func (xv Value) float(v float64, bits int) {
+ *xv.scratch = encoding.EncodeFloat((*xv.scratch)[:0], v, bits)
+ xv.w.Write(*xv.scratch)
+}
+
+// Boolean encodes v as a XML boolean.
+// It will auto close the parent xml element tag.
+func (xv Value) Boolean(v bool) {
+ *xv.scratch = strconv.AppendBool((*xv.scratch)[:0], v)
+ xv.w.Write(*xv.scratch)
+
+ xv.Close()
+}
+
+// Base64EncodeBytes writes v as a base64 value in XML string.
+// It will auto close the parent xml element tag.
+func (xv Value) Base64EncodeBytes(v []byte) {
+ encodeByteSlice(xv.w, (*xv.scratch)[:0], v)
+ xv.Close()
+}
+
+// BigInteger encodes v big.Int as XML value.
+// It will auto close the parent xml element tag.
+func (xv Value) BigInteger(v *big.Int) {
+ xv.w.Write([]byte(v.Text(10)))
+ xv.Close()
+}
+
+// BigDecimal encodes v big.Float as XML value.
+// It will auto close the parent xml element tag.
+func (xv Value) BigDecimal(v *big.Float) {
+ if i, accuracy := v.Int64(); accuracy == big.Exact {
+ xv.Long(i)
+ return
+ }
+
+ xv.w.Write([]byte(v.Text('e', -1)))
+ xv.Close()
+}
+
+// Write writes v directly to the xml document
+// if escapeXMLText is set to true, write will escape text.
+// It will auto close the parent xml element tag.
+func (xv Value) Write(v []byte, escapeXMLText bool) {
+ // escape and write xml text
+ if escapeXMLText {
+ escapeText(xv.w, v)
+ } else {
+ // write xml directly
+ xv.w.Write(v)
+ }
+
+ xv.Close()
+}
+
+// MemberElement does member element encoding. It returns a Value.
+// Member Element method should be used for all shapes except flattened shapes.
+//
+// A call to MemberElement will write nested element tags directly using the
+// provided start element. The value returned by MemberElement should be closed.
+func (xv Value) MemberElement(element StartElement) Value {
+ return newValue(xv.w, xv.scratch, element)
+}
+
+// FlattenedElement returns flattened element encoding. It returns a Value.
+// This method should be used for flattened shapes.
+//
+// Unlike MemberElement, flattened element will NOT write element tags
+// directly for the associated start element.
+//
+// The value returned by the FlattenedElement does not need to be closed.
+func (xv Value) FlattenedElement(element StartElement) Value {
+ v := newFlattenedValue(xv.w, xv.scratch, element)
+ v.isFlattened = true
+ return v
+}
+
+// Array returns an array encoder. By default, the members of array are
+// wrapped with `<member>` element tag.
+// If value is marked as flattened, the start element is used to wrap the members instead of
+// the `<member>` element.
+func (xv Value) Array() *Array {
+ return newArray(xv.w, xv.scratch, arrayMemberWrapper, xv.startElement, xv.isFlattened)
+}
+
+/*
+ArrayWithCustomName returns an array encoder.
+
+It takes named start element as an argument, the named start element will used to wrap xml array entries.
+for eg, `<someList><customName>entry1</customName></someList>`
+Here `customName` named start element will be wrapped on each array member.
+*/
+func (xv Value) ArrayWithCustomName(element StartElement) *Array {
+ return newArray(xv.w, xv.scratch, element, xv.startElement, xv.isFlattened)
+}
+
+/*
+Map returns a map encoder. By default, the map entries are
+wrapped with `<entry>` element tag.
+
+If value is marked as flattened, the start element is used to wrap the entry instead of
+the `<member>` element.
+*/
+func (xv Value) Map() *Map {
+ // flattened map
+ if xv.isFlattened {
+ return newFlattenedMap(xv.w, xv.scratch, xv.startElement)
+ }
+
+ // un-flattened map
+ return newMap(xv.w, xv.scratch)
+}
+
+// encodeByteSlice is modified copy of json encoder's encodeByteSlice.
+// It is used to base64 encode a byte slice.
+func encodeByteSlice(w writer, scratch []byte, v []byte) {
+ if v == nil {
+ return
+ }
+
+ encodedLen := base64.StdEncoding.EncodedLen(len(v))
+ if encodedLen <= len(scratch) {
+ // If the encoded bytes fit in e.scratch, avoid an extra
+ // allocation and use the cheaper Encoding.Encode.
+ dst := scratch[:encodedLen]
+ base64.StdEncoding.Encode(dst, v)
+ w.Write(dst)
+ } else if encodedLen <= 1024 {
+ // The encoded bytes are short enough to allocate for, and
+ // Encoding.Encode is still cheaper.
+ dst := make([]byte, encodedLen)
+ base64.StdEncoding.Encode(dst, v)
+ w.Write(dst)
+ } else {
+ // The encoded bytes are too long to cheaply allocate, and
+ // Encoding.Encode is no longer noticeably cheaper.
+ enc := base64.NewEncoder(base64.StdEncoding, w)
+ enc.Write(v)
+ enc.Close()
+ }
+}
+
+// IsFlattened returns true if value is for flattened shape.
+func (xv Value) IsFlattened() bool {
+ return xv.isFlattened
+}
+
+// Close closes the value.
+func (xv Value) Close() {
+ writeEndElement(xv.w, xv.startElement.End())
+}
diff --git a/vendor/github.com/aws/smithy-go/encoding/xml/value_test.go b/vendor/github.com/aws/smithy-go/encoding/xml/value_test.go
new file mode 100644
index 0000000000..cbce967bd9
--- /dev/null
+++ b/vendor/github.com/aws/smithy-go/encoding/xml/value_test.go
@@ -0,0 +1,212 @@
+package xml
+
+import (
+ "bytes"
+ "fmt"
+ "math"
+ "math/big"
+ "strconv"
+ "testing"
+)
+
+var (
+ oneInt = new(big.Int).SetInt64(1)
+ oneFloat = new(big.Float).SetFloat64(1.0)
+)
+
+func TestValue(t *testing.T) {
+ nested := StartElement{Name: Name{Local: "nested"}}
+
+ cases := map[string]struct {
+ setter func(Value)
+ expected string
+ }{
+ "string value": {
+ setter: func(value Value) {
+ value.String("foo")
+ },
+ expected: `foo`,
+ },
+ "string escaped": {
+ setter: func(value Value) {
+ value.String("{\"foo\":\"bar\"}")
+ },
+ expected: fmt.Sprintf("{%sfoo%s:%sbar%s}", escQuot, escQuot, escQuot, escQuot),
+ },
+ "integer": {
+ setter: func(value Value) {
+ value.Long(1024)
+ },
+ expected: `1024`,
+ },
+ "float": {
+ setter: func(value Value) {
+ value.Double(1e20)
+ },
+ expected: `100000000000000000000`,
+ },
+ "float exponent component": {
+ setter: func(value Value) {
+ value.Double(3e22)
+ },
+ expected: `3e+22`,
+ },
+ "boolean true": {
+ setter: func(value Value) {
+ value.Boolean(true)
+ },
+ expected: `true`,
+ },
+ "boolean false": {
+ setter: func(value Value) {
+ value.Boolean(false)
+ },
+ expected: `false`,
+ },
+ "encode bytes": {
+ setter: func(value Value) {
+ value.Base64EncodeBytes([]byte("foo bar"))
+ },
+ expected: `Zm9vIGJhcg==`,
+ },
+ "encode bytes nil": {
+ setter: func(value Value) {
+ value.Base64EncodeBytes(nil)
+ },
+ expected: ``,
+ },
+ "object": {
+ setter: func(value Value) {
+ defer value.Close()
+ value.MemberElement(nested).String("value")
+ },
+ expected: `<nested>value</nested>`,
+ },
+ "null": {
+ setter: func(value Value) {
+ value.Close()
+ },
+ expected: ``,
+ },
+ "nullWithRoot": {
+ setter: func(value Value) {
+ defer value.Close()
+ o := value.MemberElement(nested)
+ defer o.Close()
+ },
+ expected: `<nested></nested>`,
+ },
+ "write text": {
+ setter: func(value Value) {
+ defer value.Close()
+ o := value.MemberElement(nested)
+ o.Write([]byte(`{"nested":"value"}`), false)
+ },
+ expected: `<nested>{"nested":"value"}</nested>`,
+ },
+ "write escaped text": {
+ setter: func(value Value) {
+ defer value.Close()
+ o := value.MemberElement(nested)
+ o.Write([]byte(`{"nested":"value"}`), true)
+ },
+ expected: fmt.Sprintf("<nested>{%snested%s:%svalue%s}</nested>", escQuot, escQuot, escQuot, escQuot),
+ },
+ "bigInteger": {
+ setter: func(value Value) {
+ v := new(big.Int).SetInt64(math.MaxInt64)
+ value.BigInteger(v.Sub(v, oneInt))
+ },
+ expected: strconv.FormatInt(math.MaxInt64-1, 10),
+ },
+ "bigInteger > int64": {
+ setter: func(value Value) {
+ v := new(big.Int).SetInt64(math.MaxInt64)
+ value.BigInteger(v.Add(v, oneInt))
+ },
+ expected: "9223372036854775808",
+ },
+ "bigInteger < int64": {
+ setter: func(value Value) {
+ v := new(big.Int).SetInt64(math.MinInt64)
+ value.BigInteger(v.Sub(v, oneInt))
+ },
+ expected: "-9223372036854775809",
+ },
+ "bigFloat": {
+ setter: func(value Value) {
+ v := new(big.Float).SetFloat64(math.MaxFloat64)
+ value.BigDecimal(v.Sub(v, oneFloat))
+ },
+ expected: strconv.FormatFloat(math.MaxFloat64-1, 'e', -1, 64),
+ },
+ "bigFloat fits in int64": {
+ setter: func(value Value) {
+ v := new(big.Float).SetInt64(math.MaxInt64)
+ value.BigDecimal(v)
+ },
+ expected: "9223372036854775807",
+ },
+ }
+ scratch := make([]byte, 64)
+
+ for name, tt := range cases {
+ t.Run(name, func(t *testing.T) {
+ b := bytes.NewBuffer(nil)
+ root := StartElement{Name: Name{Local: "root"}}
+ value := newValue(b, &scratch, root)
+ tt.setter(value)
+
+ if e, a := []byte("<root>"+tt.expected+"</root>"), b.Bytes(); bytes.Compare(e, a) != 0 {
+ t.Errorf("expected %+q, but got %+q", e, a)
+ }
+ })
+ }
+}
+
+func TestWrappedValue(t *testing.T) {
+ buffer := bytes.NewBuffer(nil)
+ scratch := make([]byte, 64)
+
+ func() {
+ root := StartElement{Name: Name{Local: "root"}}
+ object := newValue(buffer, &scratch, root)
+ defer object.Close()
+
+ foo := StartElement{Name: Name{Local: "foo"}}
+ faz := StartElement{Name: Name{Local: "faz"}}
+
+ object.MemberElement(foo).String("bar")
+ object.MemberElement(faz).String("baz")
+ }()
+
+ e := []byte(`<root><foo>bar</foo><faz>baz</faz></root>`)
+ if a := buffer.Bytes(); bytes.Compare(e, a) != 0 {
+ t.Errorf("expected %+q, but got %+q", e, a)
+ }
+}
+
+func TestWrappedValueWithNameSpaceAndAttributes(t *testing.T) {
+ buffer := bytes.NewBuffer(nil)
+ scratch := make([]byte, 64)
+
+ func() {
+ root := StartElement{Name: Name{Local: "root"}}
+ object := newValue(buffer, &scratch, root)
+ defer object.Close()
+
+ foo := StartElement{Name: Name{Local: "foo"}, Attr: []Attr{
+ NewNamespaceAttribute("newspace", "https://endpoint.com"),
+ NewAttribute("attrName", "attrValue"),
+ }}
+ faz := StartElement{Name: Name{Local: "faz"}}
+
+ object.MemberElement(foo).String("bar")
+ object.MemberElement(faz).String("baz")
+ }()
+
+ e := []byte(`<root><foo xmlns:newspace="https://endpoint.com" attrName="attrValue">bar</foo><faz>baz</faz></root>`)
+ if a := buffer.Bytes(); bytes.Compare(e, a) != 0 {
+ t.Errorf("expected %+q, but got %+q", e, a)
+ }
+}
diff --git a/vendor/github.com/aws/smithy-go/encoding/xml/xml_decoder.go b/vendor/github.com/aws/smithy-go/encoding/xml/xml_decoder.go
new file mode 100644
index 0000000000..dc4eebdffa
--- /dev/null
+++ b/vendor/github.com/aws/smithy-go/encoding/xml/xml_decoder.go
@@ -0,0 +1,154 @@
+package xml
+
+import (
+ "encoding/xml"
+ "fmt"
+ "strings"
+)
+
+// NodeDecoder is a XML decoder wrapper that is responsible to decoding
+// a single XML Node element and it's nested member elements. This wrapper decoder
+// takes in the start element of the top level node being decoded.
+type NodeDecoder struct {
+ Decoder *xml.Decoder
+ StartEl xml.StartElement
+}
+
+// WrapNodeDecoder returns an initialized XMLNodeDecoder
+func WrapNodeDecoder(decoder *xml.Decoder, startEl xml.StartElement) NodeDecoder {
+ return NodeDecoder{
+ Decoder: decoder,
+ StartEl: startEl,
+ }
+}
+
+// Token on a Node Decoder returns a xml StartElement. It returns a boolean that indicates the
+// a token is the node decoder's end node token; and an error which indicates any error
+// that occurred while retrieving the start element
+func (d NodeDecoder) Token() (t xml.StartElement, done bool, err error) {
+ for {
+ token, e := d.Decoder.Token()
+ if e != nil {
+ return t, done, e
+ }
+
+ // check if we reach end of the node being decoded
+ if el, ok := token.(xml.EndElement); ok {
+ return t, el == d.StartEl.End(), err
+ }
+
+ if t, ok := token.(xml.StartElement); ok {
+ return restoreAttrNamespaces(t), false, err
+ }
+
+ // skip token if it is a comment or preamble or empty space value due to indentation
+ // or if it's a value and is not expected
+ }
+}
+
+// restoreAttrNamespaces update XML attributes to restore the short namespaces found within
+// the raw XML document.
+func restoreAttrNamespaces(node xml.StartElement) xml.StartElement {
+ if len(node.Attr) == 0 {
+ return node
+ }
+
+ // Generate a mapping of XML namespace values to their short names.
+ ns := map[string]string{}
+ for _, a := range node.Attr {
+ if a.Name.Space == "xmlns" {
+ ns[a.Value] = a.Name.Local
+ break
+ }
+ }
+
+ for i, a := range node.Attr {
+ if a.Name.Space == "xmlns" {
+ continue
+ }
+ // By default, xml.Decoder will fully resolve these namespaces. So if you had <foo xmlns:bar=baz bar:bin=hi/>
+ // then by default the second attribute would have the `Name.Space` resolved to `baz`. But we need it to
+ // continue to resolve as `bar` so we can easily identify it later on.
+ if v, ok := ns[node.Attr[i].Name.Space]; ok {
+ node.Attr[i].Name.Space = v
+ }
+ }
+ return node
+}
+
+// GetElement looks for the given tag name at the current level, and returns the element if found, and
+// skipping over non-matching elements. Returns an error if the node is not found, or if an error occurs while walking
+// the document.
+func (d NodeDecoder) GetElement(name string) (t xml.StartElement, err error) {
+ for {
+ token, done, err := d.Token()
+ if err != nil {
+ return t, err
+ }
+ if done {
+ return t, fmt.Errorf("%s node not found", name)
+ }
+ switch {
+ case strings.EqualFold(name, token.Name.Local):
+ return token, nil
+ default:
+ err = d.Decoder.Skip()
+ if err != nil {
+ return t, err
+ }
+ }
+ }
+}
+
+// Value provides an abstraction to retrieve char data value within an xml element.
+// The method will return an error if it encounters a nested xml element instead of char data.
+// This method should only be used to retrieve simple type or blob shape values as []byte.
+func (d NodeDecoder) Value() (c []byte, err error) {
+ t, e := d.Decoder.Token()
+ if e != nil {
+ return c, e
+ }
+
+ endElement := d.StartEl.End()
+
+ switch ev := t.(type) {
+ case xml.CharData:
+ c = ev.Copy()
+ case xml.EndElement: // end tag or self-closing
+ if ev == endElement {
+ return []byte{}, err
+ }
+ return c, fmt.Errorf("expected value for %v element, got %T type %v instead", d.StartEl.Name.Local, t, t)
+ default:
+ return c, fmt.Errorf("expected value for %v element, got %T type %v instead", d.StartEl.Name.Local, t, t)
+ }
+
+ t, e = d.Decoder.Token()
+ if e != nil {
+ return c, e
+ }
+
+ if ev, ok := t.(xml.EndElement); ok {
+ if ev == endElement {
+ return c, err
+ }
+ }
+
+ return c, fmt.Errorf("expected end element %v, got %T type %v instead", endElement, t, t)
+}
+
+// FetchRootElement takes in a decoder and returns the first start element within the xml body.
+// This function is useful in fetching the start element of an XML response and ignore the
+// comments and preamble
+func FetchRootElement(decoder *xml.Decoder) (startElement xml.StartElement, err error) {
+ for {
+ t, e := decoder.Token()
+ if e != nil {
+ return startElement, e
+ }
+
+ if startElement, ok := t.(xml.StartElement); ok {
+ return startElement, err
+ }
+ }
+}
diff --git a/vendor/github.com/aws/smithy-go/encoding/xml/xml_decoder_test.go b/vendor/github.com/aws/smithy-go/encoding/xml/xml_decoder_test.go
new file mode 100644
index 0000000000..4c48fd218f
--- /dev/null
+++ b/vendor/github.com/aws/smithy-go/encoding/xml/xml_decoder_test.go
@@ -0,0 +1,329 @@
+package xml
+
+import (
+ "bytes"
+ "encoding/xml"
+ "io"
+ "strings"
+ "testing"
+
+ "github.com/google/go-cmp/cmp"
+)
+
+func TestXMLNodeDecoder_Token(t *testing.T) {
+ cases := map[string]struct {
+ responseBody io.Reader
+ expectedStartElement xml.StartElement
+ expectedDone bool
+ expectedError string
+ }{
+ "simple success case": {
+ responseBody: bytes.NewReader([]byte(`<Response>abc</Response>`)),
+ expectedStartElement: xml.StartElement{
+ Name: xml.Name{
+ Local: "",
+ },
+ },
+ expectedDone: true,
+ },
+ "no value": {
+ responseBody: bytes.NewReader([]byte(`<Response></Response>`)),
+ expectedDone: true,
+ },
+ "empty body": {
+ responseBody: bytes.NewReader([]byte(``)),
+ expectedError: "EOF",
+ },
+ "with indentation": {
+ responseBody: bytes.NewReader([]byte(` <Response><Struct>abc</Struct></Response>`)),
+ expectedStartElement: xml.StartElement{
+ Name: xml.Name{
+ Local: "Struct",
+ },
+ Attr: []xml.Attr{},
+ },
+ },
+ "with comment and indentation": {
+ responseBody: bytes.NewReader([]byte(`<!--comment--> <Response><Struct>abc</Struct></Response>`)),
+ expectedStartElement: xml.StartElement{
+ Name: xml.Name{
+ Local: "Struct",
+ },
+ Attr: []xml.Attr{},
+ },
+ },
+ "attr with namespace": {
+ responseBody: bytes.NewReader([]byte(`<Response><Grantee xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="CanonicalUser"></Grantee></Response>`)),
+ expectedStartElement: xml.StartElement{
+ Name: xml.Name{
+ Local: "Grantee",
+ },
+ Attr: []xml.Attr{
+ {
+ Name: xml.Name{
+ Space: "xmlns",
+ Local: "xsi",
+ },
+ Value: "http://www.w3.org/2001/XMLSchema-instance",
+ },
+ {
+ Name: xml.Name{
+ Space: "xsi",
+ Local: "type",
+ },
+ Value: "CanonicalUser",
+ },
+ },
+ },
+ },
+ }
+
+ for name, c := range cases {
+ t.Run(name, func(t *testing.T) {
+ xmlDecoder := xml.NewDecoder(c.responseBody)
+ st, err := FetchRootElement(xmlDecoder)
+ if err != nil {
+ if len(c.expectedError) == 0 {
+ t.Fatalf("Expected no error, got %v", err)
+ }
+
+ if e, a := c.expectedError, err; !strings.Contains(err.Error(), c.expectedError) {
+ t.Fatalf("expected error to contain %v, found %v", e, a.Error())
+ }
+ }
+ nodeDecoder := WrapNodeDecoder(xmlDecoder, st)
+ token, done, err := nodeDecoder.Token()
+ if err != nil {
+ if len(c.expectedError) == 0 {
+ t.Fatalf("Expected no error, got %v", err)
+ }
+
+ if e, a := c.expectedError, err; !strings.Contains(err.Error(), c.expectedError) {
+ t.Fatalf("expected error to contain %v, found %v", e, a.Error())
+ }
+ }
+
+ if e, a := c.expectedDone, done; e != a {
+ t.Fatalf("expected a valid end element token for the xml document, got none")
+ }
+
+ if diff := cmp.Diff(c.expectedStartElement, token); len(diff) != 0 {
+ t.Fatalf("Found diff : (-expected,+actual), \n %v", diff)
+ }
+ })
+ }
+}
+
+func TestXMLNodeDecoder_TokenExample(t *testing.T) {
+ responseBody := bytes.NewReader([]byte(`<Struct><Response>abc</Response></Struct>`))
+
+ xmlDecoder := xml.NewDecoder(responseBody)
+ // Fetches <Struct> tag as start element.
+ st, err := FetchRootElement(xmlDecoder)
+ if err != nil {
+ t.Fatalf("Expected no error, got %v", err)
+ }
+
+ // nodeDecoder will track <Struct> tag as root node of the document
+ nodeDecoder := WrapNodeDecoder(xmlDecoder, st)
+
+ // Retrieves <Response> tag
+ token, done, err := nodeDecoder.Token()
+ if err != nil {
+ t.Fatalf("Expected no error, got %v", err)
+
+ }
+ if diff := cmp.Diff(token, xml.StartElement{Name: xml.Name{Local: "Response"}, Attr: []xml.Attr{}}); len(diff) != 0 {
+ t.Fatalf("Found diff : (-expected,+actual), \n %v", diff)
+ }
+ if done {
+ t.Fatalf("expected decoding to not be done yet")
+ }
+
+ // Skips the value and gets </Response> that is the end token of previously retrieved <Response> tag.
+ // The way node decoder works it only keeps track of the root start tag using which it was initialized.
+ // Here <Struct> is used to initialize, while</Response> is end element corresponding to already read
+ // <Response> tag. We won't be done until we receive </Struct>
+ token, done, err = nodeDecoder.Token()
+ if err != nil {
+ t.Fatalf("Expected no error, got %v", err)
+
+ }
+ if diff := cmp.Diff(token, xml.StartElement{Name: xml.Name{Local: ""}, Attr: nil}); len(diff) != 0 {
+ t.Fatalf("Found diff : (-expected,+actual), \n %v", diff)
+ }
+ if done {
+ t.Fatalf("expected decoding to not be done yet")
+ }
+
+ // Retrieves </Struct> end element tag corresponding to <Struct> tag.
+ // Since we got the end element that corresponds to the start element being track, we are done decoding.
+ token, done, err = nodeDecoder.Token()
+ if err != nil {
+ t.Fatalf("Expected no error, got %v", err)
+
+ }
+ if diff := cmp.Diff(token, xml.StartElement{Name: xml.Name{Local: ""}, Attr: nil}); len(diff) != 0 {
+ t.Fatalf("Found diff : (-expected,+actual), \n %v", diff)
+ }
+ if !done {
+ t.Fatalf("expected decoding to be done as we fetched the end element </Struct>")
+ }
+}
+
+func TestXMLNodeDecoder_Value(t *testing.T) {
+ cases := map[string]struct {
+ responseBody io.Reader
+ expectedValue []byte
+ expectedDone bool
+ expectedError string
+ }{
+ "simple success case": {
+ responseBody: bytes.NewReader([]byte(`<Response>abc</Response>`)),
+ expectedValue: []byte(`abc`),
+ },
+ "no value": {
+ responseBody: bytes.NewReader([]byte(`<Response></Response>`)),
+ expectedValue: []byte{},
+ },
+ "self-closing": {
+ responseBody: bytes.NewReader([]byte(`<Response />`)),
+ expectedValue: []byte{},
+ },
+ "empty body": {
+ responseBody: bytes.NewReader([]byte(``)),
+ expectedError: "EOF",
+ },
+ "start element retrieved": {
+ responseBody: bytes.NewReader([]byte(`<Response><Struct>abc</Struct></Response>`)),
+ expectedError: "expected value for Response element, got xml.StartElement type",
+ },
+ }
+
+ for name, c := range cases {
+ t.Run(name, func(t *testing.T) {
+ xmlDecoder := xml.NewDecoder(c.responseBody)
+ st, err := FetchRootElement(xmlDecoder)
+ if err != nil {
+ if len(c.expectedError) == 0 {
+ t.Fatalf("Expected no error, got %v", err)
+ }
+
+ if e, a := c.expectedError, err; !strings.Contains(err.Error(), c.expectedError) {
+ t.Fatalf("expected error to contain %v, found %v", e, a.Error())
+ }
+ }
+ nodeDecoder := WrapNodeDecoder(xmlDecoder, st)
+ token, err := nodeDecoder.Value()
+ if err != nil {
+ if len(c.expectedError) == 0 {
+ t.Fatalf("Expected no error, got %v", err)
+ }
+
+ if e, a := c.expectedError, err; !strings.Contains(err.Error(), c.expectedError) {
+ t.Fatalf("expected error to contain %v, found %v", e, a.Error())
+ }
+ }
+
+ if diff := cmp.Diff(c.expectedValue, token); len(diff) != 0 {
+ t.Fatalf("Found diff : (-expected,+actual), \n %v", diff)
+ }
+ })
+ }
+}
+
+func Test_FetchXMLRootElement(t *testing.T) {
+ cases := map[string]struct {
+ responseBody io.Reader
+ expectedStartElement xml.StartElement
+ expectedError string
+ }{
+ "simple success case": {
+ responseBody: bytes.NewReader([]byte(`<Response><Struct>abc</Struct></Response>`)),
+ expectedStartElement: xml.StartElement{
+ Name: xml.Name{
+ Local: "Response",
+ },
+ Attr: []xml.Attr{},
+ },
+ },
+ "empty body": {
+ responseBody: bytes.NewReader([]byte(``)),
+ expectedError: "EOF",
+ },
+ "with indentation": {
+ responseBody: bytes.NewReader([]byte(` <ErrorResponse>
+ <Error>
+ <Type>Sender</Type>
+ <Code>InvalidGreeting</Code>
+ <Message>Hi</Message>
+ <AnotherSetting>setting</AnotherSetting>
+ </Error>
+ <RequestId>foo-id</RequestId>
+</ErrorResponse>`)),
+ expectedStartElement: xml.StartElement{
+ Name: xml.Name{
+ Local: "ErrorResponse",
+ },
+ Attr: []xml.Attr{},
+ },
+ },
+ "with preamble": {
+ responseBody: bytes.NewReader([]byte(`<?xml version = "1.0" encoding = "UTF-8" standalone = "no" ?>
+<ErrorResponse>
+ <Error>
+ <Type>Sender</Type>
+ <Code>InvalidGreeting</Code>
+ <Message>Hi</Message>
+ <AnotherSetting>setting</AnotherSetting>
+ </Error>
+ <RequestId>foo-id</RequestId>
+</ErrorResponse>`)),
+ expectedStartElement: xml.StartElement{
+ Name: xml.Name{
+ Local: "ErrorResponse",
+ },
+ Attr: []xml.Attr{},
+ },
+ },
+ "with comments": {
+ responseBody: bytes.NewReader([]byte(`<!--Sample comment for testing-->
+<?xml version = "1.0" encoding = "UTF-8" standalone = "no" ?>
+<ErrorResponse>
+ <Error>
+ <Type>Sender</Type>
+ <Code>InvalidGreeting</Code>
+ <Message>Hi</Message>
+ <AnotherSetting>setting</AnotherSetting>
+ </Error>
+ <RequestId>foo-id</RequestId>
+</ErrorResponse>`)),
+ expectedStartElement: xml.StartElement{
+ Name: xml.Name{
+ Local: "ErrorResponse",
+ },
+ Attr: []xml.Attr{},
+ },
+ },
+ }
+
+ for name, c := range cases {
+ t.Run(name, func(t *testing.T) {
+ decoder := xml.NewDecoder(c.responseBody)
+ st, err := FetchRootElement(decoder)
+ if err != nil {
+ if len(c.expectedError) == 0 {
+ t.Fatalf("Expected no error, got %v", err)
+ }
+
+ if e, a := c.expectedError, err; !strings.Contains(err.Error(), c.expectedError) {
+ t.Fatalf("expected error to contain %v, found %v", e, a.Error())
+ }
+ }
+
+ if diff := cmp.Diff(c.expectedStartElement, st); len(diff) != 0 {
+ t.Fatalf("Found diff : (-expected,+actual), \n %v", diff)
+ }
+ })
+ }
+}
diff --git a/vendor/github.com/aws/smithy-go/encoding/xml/ya.make b/vendor/github.com/aws/smithy-go/encoding/xml/ya.make
new file mode 100644
index 0000000000..8345e974fe
--- /dev/null
+++ b/vendor/github.com/aws/smithy-go/encoding/xml/ya.make
@@ -0,0 +1,32 @@
+GO_LIBRARY()
+
+LICENSE(Apache-2.0)
+
+SRCS(
+ array.go
+ constants.go
+ doc.go
+ element.go
+ encoder.go
+ error_utils.go
+ escape.go
+ map.go
+ value.go
+ xml_decoder.go
+)
+
+GO_TEST_SRCS(
+ array_test.go
+ error_utils_test.go
+ map_test.go
+ value_test.go
+ xml_decoder_test.go
+)
+
+GO_XTEST_SRCS(encoder_test.go)
+
+END()
+
+RECURSE(
+ gotest
+)
diff --git a/vendor/github.com/aws/smithy-go/encoding/ya.make b/vendor/github.com/aws/smithy-go/encoding/ya.make
new file mode 100644
index 0000000000..6212adb3bd
--- /dev/null
+++ b/vendor/github.com/aws/smithy-go/encoding/ya.make
@@ -0,0 +1,16 @@
+GO_LIBRARY()
+
+LICENSE(Apache-2.0)
+
+SRCS(
+ doc.go
+ encoding.go
+)
+
+END()
+
+RECURSE(
+ httpbinding
+ json
+ xml
+)