Add a recognizer that is capable of sniffing content type from data by
asking each serializer to try to decode - this is for a "universal
decoder/deserializer" which can be used by client logic.
Add codec factory, which provides the core primitives for content type
negotiation. Codec factories depend only on schemes, serializers, and
groupversion pairs.
Break Codec into two general purpose interfaces, Encoder and Decoder,
and move parameter codec responsibilities to ParameterCodec.
Make unversioned types explicit when registering - these types go
through conversion without modification.
Switch to use "__internal" instead of "" to represent the internal
version. Future commits will also add group defaulting (so that "" is
expanded internally into a known group version, and only cleared during
set).
For embedded types like runtime.Object -> runtime.RawExtension, put the
responsibility on the caller of Decode/Encode to handle transformation
into destination serialization. Future commits will expand RawExtension
and Unknown to accept a content encoding as well as bytes.
Make Unknown a bit more powerful and use it to carry unrecognized types.
Replace many of the remaining s.Convert() invocations with direct
execution, and make generated methods public. Removes 10% of the
allocations during decode of a pod and ~20-40% of the total CPU time.
The pending codec -> conversion split changes the signature of
Encode and Decode to be more complicated. Create a stub helper
with the exact semantics of today and do the simple mechanical
refactor here to reduce the cost of that change.
Rather than an "all or nothing" approach to defining a custom conversion
function (which seems destined to cause problems eventually), this is an
attempt to make it possible to call the auto-generated code and then "fix it
up".
Specifically, consider you have a fooBar struct. If you don't define a
conversion for FooBar, you will get a generated function like:
convert_v1_FooBar_To_api_FooBar()
Before this PR, if you define your own conversion function, you get no
generated function. After this PR you get:
autoconvert_v1_FooBar_To_api_FooBar()
...which you can call yourself in your custom function.
A lot of packages use StringSet, but they don't use anything else from
the util package. Moving StringSet into another package will shrink
their dependency trees significantly.
Running reflect.ValueOf(X) where X is a nil interface will return
a zero Value. We cannot get the type (because no concrete type is
known) and cannot check if the Value is nil later on due to the way
reflect.Value works. So we should handle this case by immediately
returning nil. We cannot type-assert a nil interface to another
interface type (as no concrete type is assigned), so we must add
another check to see if the returned interface is nil.
OpenShift uses multiple API packages (types are split) which
Kube will also eventually have as we introduce more plugins.
These changes make the generators able to handle importing different
API object packages into a single generator function.