[VOL-1866] Changed module dependency to v12.0.0 of k8s client-go and v1.15.4 of k8s api/apimachinery in sync with other voltha components

Had to use pseudo-version corresponding to v12.0.0 of k8s client-go
because golang proxy is no longer serving the modules not complying
to Semantic Import Versioning rules including client-go v12.0.0.
Refer to https://github.com/kubernetes/client-go/issues/631 and
https://github.com/golang/go/issues/33558

Change-Id: I2e558bab7f0702f230761319eb5392a7d0532ea3
diff --git a/vendor/k8s.io/apimachinery/pkg/runtime/serializer/codec_factory.go b/vendor/k8s.io/apimachinery/pkg/runtime/serializer/codec_factory.go
index 65f4511..01f56c9 100644
--- a/vendor/k8s.io/apimachinery/pkg/runtime/serializer/codec_factory.go
+++ b/vendor/k8s.io/apimachinery/pkg/runtime/serializer/codec_factory.go
@@ -17,9 +17,13 @@
 package serializer
 
 import (
+	"mime"
+	"strings"
+
 	"k8s.io/apimachinery/pkg/runtime"
 	"k8s.io/apimachinery/pkg/runtime/schema"
 	"k8s.io/apimachinery/pkg/runtime/serializer/json"
+	"k8s.io/apimachinery/pkg/runtime/serializer/protobuf"
 	"k8s.io/apimachinery/pkg/runtime/serializer/recognizer"
 	"k8s.io/apimachinery/pkg/runtime/serializer/versioning"
 )
@@ -48,6 +52,8 @@
 	jsonSerializer := json.NewSerializer(mf, scheme, scheme, false)
 	jsonPrettySerializer := json.NewSerializer(mf, scheme, scheme, true)
 	yamlSerializer := json.NewYAMLSerializer(mf, scheme, scheme)
+	serializer := protobuf.NewSerializer(scheme, scheme)
+	raw := protobuf.NewRawSerializer(scheme, scheme)
 
 	serializers := []serializerType{
 		{
@@ -68,6 +74,15 @@
 			EncodesAsText:      true,
 			Serializer:         yamlSerializer,
 		},
+		{
+			AcceptContentTypes: []string{runtime.ContentTypeProtobuf},
+			ContentType:        runtime.ContentTypeProtobuf,
+			FileExtensions:     []string{"pb"},
+			Serializer:         serializer,
+
+			Framer:           protobuf.LengthDelimitedFramer,
+			StreamSerializer: raw,
+		},
 	}
 
 	for _, fn := range serializerExtensions {
@@ -120,6 +135,15 @@
 				Serializer:       d.Serializer,
 				PrettySerializer: d.PrettySerializer,
 			}
+
+			mediaType, _, err := mime.ParseMediaType(info.MediaType)
+			if err != nil {
+				panic(err)
+			}
+			parts := strings.SplitN(mediaType, "/", 2)
+			info.MediaTypeType = parts[0]
+			info.MediaTypeSubType = parts[1]
+
 			if d.StreamSerializer != nil {
 				info.StreamSerializer = &runtime.StreamSerializerInfo{
 					Serializer:    d.StreamSerializer,
@@ -148,6 +172,12 @@
 	}
 }
 
+// WithoutConversion returns a NegotiatedSerializer that performs no conversion, even if the
+// caller requests it.
+func (f CodecFactory) WithoutConversion() runtime.NegotiatedSerializer {
+	return WithoutConversionCodecFactory{f}
+}
+
 // SupportedMediaTypes returns the RFC2046 media types that this factory has serializers for.
 func (f CodecFactory) SupportedMediaTypes() []runtime.SerializerInfo {
 	return f.accepts
@@ -215,23 +245,30 @@
 	return f.CodecForVersions(encoder, nil, gv, nil)
 }
 
-// DirectCodecFactory provides methods for retrieving "DirectCodec"s, which do not do conversion.
-type DirectCodecFactory struct {
+// WithoutConversionCodecFactory is a CodecFactory that will explicitly ignore requests to perform conversion.
+// This wrapper is used while code migrates away from using conversion (such as external clients) and in the future
+// will be unnecessary when we change the signature of NegotiatedSerializer.
+type WithoutConversionCodecFactory struct {
 	CodecFactory
 }
 
-// EncoderForVersion returns an encoder that does not do conversion.
-func (f DirectCodecFactory) EncoderForVersion(serializer runtime.Encoder, version runtime.GroupVersioner) runtime.Encoder {
-	return versioning.DirectEncoder{
+// EncoderForVersion returns an encoder that does not do conversion, but does set the group version kind of the object
+// when serialized.
+func (f WithoutConversionCodecFactory) EncoderForVersion(serializer runtime.Encoder, version runtime.GroupVersioner) runtime.Encoder {
+	return runtime.WithVersionEncoder{
 		Version:     version,
 		Encoder:     serializer,
 		ObjectTyper: f.CodecFactory.scheme,
 	}
 }
 
-// DecoderToVersion returns an decoder that does not do conversion. gv is ignored.
-func (f DirectCodecFactory) DecoderToVersion(serializer runtime.Decoder, _ runtime.GroupVersioner) runtime.Decoder {
-	return versioning.DirectDecoder{
+// DecoderToVersion returns an decoder that does not do conversion.
+func (f WithoutConversionCodecFactory) DecoderToVersion(serializer runtime.Decoder, _ runtime.GroupVersioner) runtime.Decoder {
+	return runtime.WithoutVersionDecoder{
 		Decoder: serializer,
 	}
 }
+
+// DirectCodecFactory was renamed to WithoutConversionCodecFactory in 1.15.
+// TODO: remove in 1.16.
+type DirectCodecFactory = WithoutConversionCodecFactory
diff --git a/vendor/k8s.io/apimachinery/pkg/runtime/serializer/json/json.go b/vendor/k8s.io/apimachinery/pkg/runtime/serializer/json/json.go
index 8987e74..69ada8e 100644
--- a/vendor/k8s.io/apimachinery/pkg/runtime/serializer/json/json.go
+++ b/vendor/k8s.io/apimachinery/pkg/runtime/serializer/json/json.go
@@ -35,34 +35,56 @@
 
 // NewSerializer creates a JSON serializer that handles encoding versioned objects into the proper JSON form. If typer
 // is not nil, the object has the group, version, and kind fields set.
+// Deprecated: use NewSerializerWithOptions instead.
 func NewSerializer(meta MetaFactory, creater runtime.ObjectCreater, typer runtime.ObjectTyper, pretty bool) *Serializer {
-	return &Serializer{
-		meta:    meta,
-		creater: creater,
-		typer:   typer,
-		yaml:    false,
-		pretty:  pretty,
-	}
+	return NewSerializerWithOptions(meta, creater, typer, SerializerOptions{false, pretty, false})
 }
 
 // NewYAMLSerializer creates a YAML serializer that handles encoding versioned objects into the proper YAML form. If typer
 // is not nil, the object has the group, version, and kind fields set. This serializer supports only the subset of YAML that
 // matches JSON, and will error if constructs are used that do not serialize to JSON.
+// Deprecated: use NewSerializerWithOptions instead.
 func NewYAMLSerializer(meta MetaFactory, creater runtime.ObjectCreater, typer runtime.ObjectTyper) *Serializer {
+	return NewSerializerWithOptions(meta, creater, typer, SerializerOptions{true, false, false})
+}
+
+// NewSerializerWithOptions creates a JSON/YAML serializer that handles encoding versioned objects into the proper JSON/YAML
+// form. If typer is not nil, the object has the group, version, and kind fields set. Options are copied into the Serializer
+// and are immutable.
+func NewSerializerWithOptions(meta MetaFactory, creater runtime.ObjectCreater, typer runtime.ObjectTyper, options SerializerOptions) *Serializer {
 	return &Serializer{
 		meta:    meta,
 		creater: creater,
 		typer:   typer,
-		yaml:    true,
+		options: options,
 	}
 }
 
+// SerializerOptions holds the options which are used to configure a JSON/YAML serializer.
+// example:
+// (1) To configure a JSON serializer, set `Yaml` to `false`.
+// (2) To configure a YAML serializer, set `Yaml` to `true`.
+// (3) To configure a strict serializer that can return strictDecodingError, set `Strict` to `true`.
+type SerializerOptions struct {
+	// Yaml: configures the Serializer to work with JSON(false) or YAML(true).
+	// When `Yaml` is enabled, this serializer only supports the subset of YAML that
+	// matches JSON, and will error if constructs are used that do not serialize to JSON.
+	Yaml bool
+
+	// Pretty: configures a JSON enabled Serializer(`Yaml: false`) to produce human-readable output.
+	// This option is silently ignored when `Yaml` is `true`.
+	Pretty bool
+
+	// Strict: configures the Serializer to return strictDecodingError's when duplicate fields are present decoding JSON or YAML.
+	// Note that enabling this option is not as performant as the non-strict variant, and should not be used in fast paths.
+	Strict bool
+}
+
 type Serializer struct {
 	meta    MetaFactory
+	options SerializerOptions
 	creater runtime.ObjectCreater
 	typer   runtime.ObjectTyper
-	yaml    bool
-	pretty  bool
 }
 
 // Serializer implements Serializer
@@ -119,11 +141,28 @@
 	return config
 }
 
-// Private copy of jsoniter to try to shield against possible mutations
+// StrictCaseSensitiveJsonIterator returns a jsoniterator API that's configured to be
+// case-sensitive, but also disallows unknown fields when unmarshalling. It is compatible with
+// the encoding/json standard library.
+func StrictCaseSensitiveJsonIterator() jsoniter.API {
+	config := jsoniter.Config{
+		EscapeHTML:             true,
+		SortMapKeys:            true,
+		ValidateJsonRawMessage: true,
+		CaseSensitive:          true,
+		DisallowUnknownFields:  true,
+	}.Froze()
+	// Force jsoniter to decode number to interface{} via int64/float64, if possible.
+	config.RegisterExtension(&customNumberExtension{})
+	return config
+}
+
+// Private copies of jsoniter to try to shield against possible mutations
 // from outside. Still does not protect from package level jsoniter.Register*() functions - someone calling them
 // in some other library will mess with every usage of the jsoniter library in the whole program.
 // See https://github.com/json-iterator/go/issues/265
 var caseSensitiveJsonIterator = CaseSensitiveJsonIterator()
+var strictCaseSensitiveJsonIterator = StrictCaseSensitiveJsonIterator()
 
 // gvkWithDefaults returns group kind and version defaulting from provided default
 func gvkWithDefaults(actual, defaultGVK schema.GroupVersionKind) schema.GroupVersionKind {
@@ -160,7 +199,7 @@
 	}
 
 	data := originalData
-	if s.yaml {
+	if s.options.Yaml {
 		altered, err := yaml.YAMLToJSON(data)
 		if err != nil {
 			return nil, nil, err
@@ -216,12 +255,38 @@
 	if err := caseSensitiveJsonIterator.Unmarshal(data, obj); err != nil {
 		return nil, actual, err
 	}
+
+	// If the deserializer is non-strict, return successfully here.
+	if !s.options.Strict {
+		return obj, actual, nil
+	}
+
+	// In strict mode pass the data trough the YAMLToJSONStrict converter.
+	// This is done to catch duplicate fields regardless of encoding (JSON or YAML). For JSON data,
+	// the output would equal the input, unless there is a parsing error such as duplicate fields.
+	// As we know this was successful in the non-strict case, the only error that may be returned here
+	// is because of the newly-added strictness. hence we know we can return the typed strictDecoderError
+	// the actual error is that the object contains duplicate fields.
+	altered, err := yaml.YAMLToJSONStrict(originalData)
+	if err != nil {
+		return nil, actual, runtime.NewStrictDecodingError(err.Error(), string(originalData))
+	}
+	// As performance is not an issue for now for the strict deserializer (one has regardless to do
+	// the unmarshal twice), we take the sanitized, altered data that is guaranteed to have no duplicated
+	// fields, and unmarshal this into a copy of the already-populated obj. Any error that occurs here is
+	// due to that a matching field doesn't exist in the object. hence we can return a typed strictDecoderError,
+	// the actual error is that the object contains unknown field.
+	strictObj := obj.DeepCopyObject()
+	if err := strictCaseSensitiveJsonIterator.Unmarshal(altered, strictObj); err != nil {
+		return nil, actual, runtime.NewStrictDecodingError(err.Error(), string(originalData))
+	}
+	// Always return the same object as the non-strict serializer to avoid any deviations.
 	return obj, actual, nil
 }
 
 // Encode serializes the provided object to the given writer.
 func (s *Serializer) Encode(obj runtime.Object, w io.Writer) error {
-	if s.yaml {
+	if s.options.Yaml {
 		json, err := caseSensitiveJsonIterator.Marshal(obj)
 		if err != nil {
 			return err
@@ -234,7 +299,7 @@
 		return err
 	}
 
-	if s.pretty {
+	if s.options.Pretty {
 		data, err := caseSensitiveJsonIterator.MarshalIndent(obj, "", "  ")
 		if err != nil {
 			return err
@@ -248,7 +313,7 @@
 
 // RecognizesData implements the RecognizingDecoder interface.
 func (s *Serializer) RecognizesData(peek io.Reader) (ok, unknown bool, err error) {
-	if s.yaml {
+	if s.options.Yaml {
 		// we could potentially look for '---'
 		return false, true, nil
 	}
diff --git a/vendor/k8s.io/apimachinery/pkg/runtime/serializer/protobuf/protobuf.go b/vendor/k8s.io/apimachinery/pkg/runtime/serializer/protobuf/protobuf.go
index b99ba25..8af889d 100644
--- a/vendor/k8s.io/apimachinery/pkg/runtime/serializer/protobuf/protobuf.go
+++ b/vendor/k8s.io/apimachinery/pkg/runtime/serializer/protobuf/protobuf.go
@@ -69,22 +69,18 @@
 // NewSerializer creates a Protobuf serializer that handles encoding versioned objects into the proper wire form. If a typer
 // is passed, the encoded object will have group, version, and kind fields set. If typer is nil, the objects will be written
 // as-is (any type info passed with the object will be used).
-//
-// This encoding scheme is experimental, and is subject to change at any time.
-func NewSerializer(creater runtime.ObjectCreater, typer runtime.ObjectTyper, defaultContentType string) *Serializer {
+func NewSerializer(creater runtime.ObjectCreater, typer runtime.ObjectTyper) *Serializer {
 	return &Serializer{
-		prefix:      protoEncodingPrefix,
-		creater:     creater,
-		typer:       typer,
-		contentType: defaultContentType,
+		prefix:  protoEncodingPrefix,
+		creater: creater,
+		typer:   typer,
 	}
 }
 
 type Serializer struct {
-	prefix      []byte
-	creater     runtime.ObjectCreater
-	typer       runtime.ObjectTyper
-	contentType string
+	prefix  []byte
+	creater runtime.ObjectCreater
+	typer   runtime.ObjectTyper
 }
 
 var _ runtime.Serializer = &Serializer{}
@@ -138,7 +134,7 @@
 	if intoUnknown, ok := into.(*runtime.Unknown); ok && intoUnknown != nil {
 		*intoUnknown = unk
 		if ok, _, _ := s.RecognizesData(bytes.NewBuffer(unk.Raw)); ok {
-			intoUnknown.ContentType = s.contentType
+			intoUnknown.ContentType = runtime.ContentTypeProtobuf
 		}
 		return intoUnknown, &actual, nil
 	}
@@ -303,20 +299,18 @@
 // encoded object, and thus is not self describing (callers must know what type is being described in order to decode).
 //
 // This encoding scheme is experimental, and is subject to change at any time.
-func NewRawSerializer(creater runtime.ObjectCreater, typer runtime.ObjectTyper, defaultContentType string) *RawSerializer {
+func NewRawSerializer(creater runtime.ObjectCreater, typer runtime.ObjectTyper) *RawSerializer {
 	return &RawSerializer{
-		creater:     creater,
-		typer:       typer,
-		contentType: defaultContentType,
+		creater: creater,
+		typer:   typer,
 	}
 }
 
 // RawSerializer encodes and decodes objects without adding a runtime.Unknown wrapper (objects are encoded without identifying
 // type).
 type RawSerializer struct {
-	creater     runtime.ObjectCreater
-	typer       runtime.ObjectTyper
-	contentType string
+	creater runtime.ObjectCreater
+	typer   runtime.ObjectTyper
 }
 
 var _ runtime.Serializer = &RawSerializer{}
@@ -358,7 +352,7 @@
 	if intoUnknown, ok := into.(*runtime.Unknown); ok && intoUnknown != nil {
 		intoUnknown.Raw = data
 		intoUnknown.ContentEncoding = ""
-		intoUnknown.ContentType = s.contentType
+		intoUnknown.ContentType = runtime.ContentTypeProtobuf
 		intoUnknown.SetGroupVersionKind(*actual)
 		return intoUnknown, actual, nil
 	}
@@ -411,6 +405,9 @@
 	if err := proto.Unmarshal(data, pb); err != nil {
 		return nil, actual, err
 	}
+	if actual != nil {
+		obj.GetObjectKind().SetGroupVersionKind(*actual)
+	}
 	return obj, actual, nil
 }
 
diff --git a/vendor/k8s.io/apimachinery/pkg/runtime/serializer/protobuf_extension.go b/vendor/k8s.io/apimachinery/pkg/runtime/serializer/protobuf_extension.go
deleted file mode 100644
index 545cf78..0000000
--- a/vendor/k8s.io/apimachinery/pkg/runtime/serializer/protobuf_extension.go
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
-Copyright 2014 The Kubernetes Authors.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-*/
-
-package serializer
-
-import (
-	"k8s.io/apimachinery/pkg/runtime"
-	"k8s.io/apimachinery/pkg/runtime/serializer/protobuf"
-)
-
-const (
-	// contentTypeProtobuf is the protobuf type exposed for Kubernetes. It is private to prevent others from
-	// depending on it unintentionally.
-	// TODO: potentially move to pkg/api (since it's part of the Kube public API) and pass it in to the
-	//   CodecFactory on initialization.
-	contentTypeProtobuf = "application/vnd.kubernetes.protobuf"
-)
-
-func protobufSerializer(scheme *runtime.Scheme) (serializerType, bool) {
-	serializer := protobuf.NewSerializer(scheme, scheme, contentTypeProtobuf)
-	raw := protobuf.NewRawSerializer(scheme, scheme, contentTypeProtobuf)
-	return serializerType{
-		AcceptContentTypes: []string{contentTypeProtobuf},
-		ContentType:        contentTypeProtobuf,
-		FileExtensions:     []string{"pb"},
-		Serializer:         serializer,
-
-		Framer:           protobuf.LengthDelimitedFramer,
-		StreamSerializer: raw,
-	}, true
-}
-
-func init() {
-	serializerExtensions = append(serializerExtensions, protobufSerializer)
-}
diff --git a/vendor/k8s.io/apimachinery/pkg/runtime/serializer/versioning/versioning.go b/vendor/k8s.io/apimachinery/pkg/runtime/serializer/versioning/versioning.go
index 0018471..a04a2e9 100644
--- a/vendor/k8s.io/apimachinery/pkg/runtime/serializer/versioning/versioning.go
+++ b/vendor/k8s.io/apimachinery/pkg/runtime/serializer/versioning/versioning.go
@@ -106,20 +106,13 @@
 	}
 
 	if d, ok := obj.(runtime.NestedObjectDecoder); ok {
-		if err := d.DecodeNestedObjects(DirectDecoder{c.decoder}); err != nil {
+		if err := d.DecodeNestedObjects(runtime.WithoutVersionDecoder{c.decoder}); err != nil {
 			return nil, gvk, err
 		}
 	}
 
 	// if we specify a target, use generic conversion.
 	if into != nil {
-		if into == obj {
-			if isVersioned {
-				return versioned, gvk, nil
-			}
-			return into, gvk, nil
-		}
-
 		// perform defaulting if requested
 		if c.defaulter != nil {
 			// create a copy to ensure defaulting is not applied to the original versioned objects
@@ -133,6 +126,14 @@
 			}
 		}
 
+		// Short-circuit conversion if the into object is same object
+		if into == obj {
+			if isVersioned {
+				return versioned, gvk, nil
+			}
+			return into, gvk, nil
+		}
+
 		if err := c.convertor.Convert(obj, into, c.decodeVersion); err != nil {
 			return nil, gvk, err
 		}
@@ -199,84 +200,41 @@
 		return err
 	}
 
+	objectKind := obj.GetObjectKind()
+	old := objectKind.GroupVersionKind()
+	// restore the old GVK after encoding
+	defer objectKind.SetGroupVersionKind(old)
+
 	if c.encodeVersion == nil || isUnversioned {
 		if e, ok := obj.(runtime.NestedObjectEncoder); ok {
-			if err := e.EncodeNestedObjects(DirectEncoder{Encoder: c.encoder, ObjectTyper: c.typer}); err != nil {
+			if err := e.EncodeNestedObjects(runtime.WithVersionEncoder{Encoder: c.encoder, ObjectTyper: c.typer}); err != nil {
 				return err
 			}
 		}
-		objectKind := obj.GetObjectKind()
-		old := objectKind.GroupVersionKind()
 		objectKind.SetGroupVersionKind(gvks[0])
-		err = c.encoder.Encode(obj, w)
-		objectKind.SetGroupVersionKind(old)
-		return err
+		return c.encoder.Encode(obj, w)
 	}
 
 	// Perform a conversion if necessary
-	objectKind := obj.GetObjectKind()
-	old := objectKind.GroupVersionKind()
 	out, err := c.convertor.ConvertToVersion(obj, c.encodeVersion)
 	if err != nil {
 		return err
 	}
 
 	if e, ok := out.(runtime.NestedObjectEncoder); ok {
-		if err := e.EncodeNestedObjects(DirectEncoder{Version: c.encodeVersion, Encoder: c.encoder, ObjectTyper: c.typer}); err != nil {
+		if err := e.EncodeNestedObjects(runtime.WithVersionEncoder{Version: c.encodeVersion, Encoder: c.encoder, ObjectTyper: c.typer}); err != nil {
 			return err
 		}
 	}
 
 	// Conversion is responsible for setting the proper group, version, and kind onto the outgoing object
-	err = c.encoder.Encode(out, w)
-	// restore the old GVK, in case conversion returned the same object
-	objectKind.SetGroupVersionKind(old)
-	return err
+	return c.encoder.Encode(out, w)
 }
 
-// DirectEncoder serializes an object and ensures the GVK is set.
-type DirectEncoder struct {
-	Version runtime.GroupVersioner
-	runtime.Encoder
-	runtime.ObjectTyper
-}
+// DirectEncoder was moved and renamed to runtime.WithVersionEncoder in 1.15.
+// TODO: remove in 1.16.
+type DirectEncoder = runtime.WithVersionEncoder
 
-// Encode does not do conversion. It sets the gvk during serialization.
-func (e DirectEncoder) Encode(obj runtime.Object, stream io.Writer) error {
-	gvks, _, err := e.ObjectTyper.ObjectKinds(obj)
-	if err != nil {
-		if runtime.IsNotRegisteredError(err) {
-			return e.Encoder.Encode(obj, stream)
-		}
-		return err
-	}
-	kind := obj.GetObjectKind()
-	oldGVK := kind.GroupVersionKind()
-	gvk := gvks[0]
-	if e.Version != nil {
-		preferredGVK, ok := e.Version.KindForGroupVersionKinds(gvks)
-		if ok {
-			gvk = preferredGVK
-		}
-	}
-	kind.SetGroupVersionKind(gvk)
-	err = e.Encoder.Encode(obj, stream)
-	kind.SetGroupVersionKind(oldGVK)
-	return err
-}
-
-// DirectDecoder clears the group version kind of a deserialized object.
-type DirectDecoder struct {
-	runtime.Decoder
-}
-
-// Decode does not do conversion. It removes the gvk during deserialization.
-func (d DirectDecoder) Decode(data []byte, defaults *schema.GroupVersionKind, into runtime.Object) (runtime.Object, *schema.GroupVersionKind, error) {
-	obj, gvk, err := d.Decoder.Decode(data, defaults, into)
-	if obj != nil {
-		kind := obj.GetObjectKind()
-		// clearing the gvk is just a convention of a codec
-		kind.SetGroupVersionKind(schema.GroupVersionKind{})
-	}
-	return obj, gvk, err
-}
+// DirectDecoder was moved and renamed to runtime.WithoutVersionDecoder in 1.15.
+// TODO: remove in 1.16.
+type DirectDecoder = runtime.WithoutVersionDecoder