-
Notifications
You must be signed in to change notification settings - Fork 1.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Deprecate Parameterizable
, introduce default CodecProvider.get(Class<T>, List<Type>, CodecRegistry)
instead
#1115
Conversation
…rguments, CodecRegistry registry)` Refactor `RecordCodec` and `CollectionCodec`. `MapCodecV2` and `RawDataClassCodec` are still `Parameterizable` and are working. JAVA-4954
JAVA-4954
/** | ||
* Get a {@code Codec} using the given context, which includes, most importantly, the Class for which a {@code Codec} is required. | ||
* | ||
* <p>This method is called only if {@link #get(Class, List, CodecRegistry)} is not properly overridden.</p> | ||
* | ||
* @param clazz the Class for which to get a Codec | ||
* @param registry the registry to use for resolving dependent Codec instances | ||
* @param <T> the type of the class for which a Codec is required | ||
* @return the Codec instance, which may be null, if this source is unable to provide one for the requested Class | ||
*/ | ||
<T> Codec<T> get(Class<T> clazz, CodecRegistry registry); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The driver no longer calls the "old" CodecProvider.get
, i.e., we may even deprecate this method in the future and remove in 5.0, thus going back to having only one method on CodecProvider
.
default <T> Codec<T> get(Class<T> clazz, List<Type> typeArguments, CodecRegistry registry) { | ||
return get(clazz, registry); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We don't have Beta
in bson
, but maybe we should. This will allow us to mark the new method as @Beta(Beta.Reason.CLIENT)
and give ourselves more time to realize whether the signature of the method should be different. @jyemin What do you think?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm happy enough with this signature that I'm willing to go with it as is.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We were mistakenly happy previously more than once about things in this domain. Let's hope, this is the last time)
@@ -47,7 +44,7 @@ | |||
*/ | |||
@SuppressWarnings("rawtypes") | |||
final class CollectionCodec<C extends Collection<Object>> extends AbstractCollectionCodec<Object, C> | |||
implements OverridableUuidRepresentationCodec<C>, Parameterizable { | |||
implements OverridableUuidRepresentationCodec<C> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I noticed that while CollectionCodec
implements OverridableUuidRepresentationCodec
, ParameterizedCollectionCodec
does not. The same goes about MapCodecV2
and ParameterizedMapCodec
. Is this intentional / OK?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's intentional
JAVA-4967
public class DataClassCodecProvider : CodecProvider { | ||
override fun <T : Any> get(clazz: Class<T>, registry: CodecRegistry): Codec<T>? = | ||
DataClassCodec.create(clazz.kotlin, registry) | ||
get(clazz, emptyList(), registry) | ||
|
||
override fun <T : Any> get(clazz: Class<T>, typeArguments: List<Type>, registry: CodecRegistry): Codec<T>? = | ||
DataClassCodec.create(clazz.kotlin, registry, typeArguments) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If this provider is rolled back to the previous implementation, some tests in DataClassCodecTest
(for example, testDataClassWithParameterizedDataClass
), which this PR did not modify, start failing with CodecConfigurationException: Could not find codec for number with type N
. I.e., they do test parameterization and it appear to work when the provider properly overrides the new get
method.
@@ -51,40 +53,55 @@ public <T> Codec<T> get(final Class<T> clazz) { | |||
@Override | |||
public <T> Codec<T> get(final Class<T> clazz, final List<Type> typeArguments) { | |||
notNull("typeArguments", typeArguments); | |||
isTrueArgument("typeArguments is not empty", !typeArguments.isEmpty()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This assertion and the similar assertion in ChildCodecRegistry.get
contradicted the documentation of ChildCodecRegistry.get
, which explicitly allows empty typeArguments
(this PR has not changed that documentation). While all our tests happened to pass despite the assertions existing, users can pass empty typeArguments
and get an unjustified error.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Very nice improvement.
RecordCodec(final Class<T> clazz, final CodecRegistry codecRegistry, final List<Type> types) { | ||
if (types.size() != clazz.getTypeParameters().length || types.isEmpty()) { | ||
RecordCodec(final Class<T> clazz, final List<Type> types, final CodecRegistry codecRegistry) { | ||
if (types.size() != clazz.getTypeParameters().length) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is so much nicer
@@ -47,7 +44,7 @@ | |||
*/ | |||
@SuppressWarnings("rawtypes") | |||
final class CollectionCodec<C extends Collection<Object>> extends AbstractCollectionCodec<Object, C> | |||
implements OverridableUuidRepresentationCodec<C>, Parameterizable { | |||
implements OverridableUuidRepresentationCodec<C> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's intentional
default <T> Codec<T> get(Class<T> clazz, List<Type> typeArguments, CodecRegistry registry) { | ||
return get(clazz, registry); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm happy enough with this signature that I'm willing to go with it as is.
JAVA-4967
JAVA-4967
Turns out, we don't even need to introduce
ParameterizedCodecProvider
to replaceParameterizable
. All we need is a new default method onCodecProvider
. And the cost of still supportingParameterizable
is really small: a singleif
block inProvidersCodecRegistry.getFromCodecProvider
.I also refactored
RecordCodec
,CollectionCodec
,MapCodecV2
,org.bson.codecs.kotlin.DataClassCodec
such that they no longer implementParameterizable
.How is this related to JAVA-4954?
JAVA-4954 is about trying to improve
PojoCodecImpl
to be more likeRecordCodec
. Given that we discovered a better alternative toParameterizable
, which can be implemented without breaking public API, it seems worth making the improvement before trying to refactorPojoCodecImpl
. Otherwise, we will likely have to refactorPojoCodecImpl
again in the future.JAVA-4967