<!-- 
RSS generated by JIRA (9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66) at Thu Feb 08 09:03:22 UTC 2024

It is possible to restrict the fields that are returned in this document by specifying the 'field' parameter in your request.
For example, to request only the issue key and summary append 'field=key&field=summary' to the URL of your request.
-->
<rss version="0.92" >
<channel>
    <title>MongoDB Jira</title>
    <link>https://jira.mongodb.org</link>
    <description>This file is an XML representation of an issue</description>
    <language>en-us</language>    <build-info>
        <version>9.7.1</version>
        <build-number>970001</build-number>
        <build-date>13-04-2023</build-date>
    </build-info>


<item>
            <title>[JAVA-4954] Refactor PojoCodec to leverage CodecProvider.get(clazz, typeArguments, registry)</title>
                <link>https://jira.mongodb.org/browse/JAVA-4954</link>
                <project id="10006" key="JAVA">Java Driver</project>
                    <description>&lt;p&gt;&lt;b&gt;Update&lt;/b&gt;: the &lt;tt&gt;Parameterizable&lt;/tt&gt; interface &lt;a href=&quot;https://jira.mongodb.org/browse/JAVA-4967&quot; class=&quot;external-link&quot; rel=&quot;nofollow&quot;&gt;was replaced&lt;/a&gt; with &lt;tt&gt;CodecProvider.get(Class&amp;lt;T&amp;gt; clazz, List&amp;lt;Type&amp;gt; typeArguments, CodecRegistry registry)&lt;/tt&gt;.&lt;/p&gt;

&lt;p&gt;The &lt;tt&gt;Parameterizable&lt;/tt&gt; interface was introduced along with &lt;tt&gt;RecordCodec&lt;/tt&gt; to allow it to be deeply immutable even in the face of type parameters. We can make &lt;tt&gt;PojoCodec&lt;/tt&gt; similarly immutable by having it make use of this interface.  There are a few aspects to this&lt;/p&gt;

&lt;ul&gt;
	&lt;li&gt;&lt;tt&gt;PojoCodec&lt;/tt&gt; implements &lt;tt&gt;Parameterizable&lt;/tt&gt;&lt;/li&gt;
	&lt;li&gt;PojoCodec uses CodecRegistry#get(java.lang.Class&amp;lt;T&amp;gt;, java.util.List&amp;lt;java.lang.reflect.Type&amp;gt;) to resolve codecs for parameterized POJO types, including nested POJOs and collections.  Doing this for collections may be tricky since a different mechanism was introduced in &lt;a href=&quot;https://jira.mongodb.org/browse/JAVA-2554&quot; title=&quot;Investigate Optional support for the Pojo Codec&quot; class=&quot;issue-link&quot; data-issue-key=&quot;JAVA-2554&quot;&gt;&lt;del&gt;JAVA-2554&lt;/del&gt;&lt;/a&gt; that may conflict with this effort.&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;The end result should be that the full set of parameterized codecs is resolved before the codec is ever used for encoding or decoding.&lt;/p&gt;</description>
                <environment></environment>
        <key id="2328436">JAVA-4954</key>
            <summary>Refactor PojoCodec to leverage CodecProvider.get(clazz, typeArguments, registry)</summary>
                <type id="4" iconUrl="https://jira.mongodb.org/secure/viewavatar?size=xsmall&amp;avatarId=14710&amp;avatarType=issuetype">Improvement</type>
                                            <priority id="3" iconUrl="https://jira.mongodb.org/images/icons/priorities/major.svg">Major - P3</priority>
                        <status id="10038" iconUrl="https://jira.mongodb.org/images/icons/subtask.gif" description="">Backlog</status>
                    <statusCategory id="2" key="new" colorName="default"/>
                                    <resolution id="-1">Unresolved</resolution>
                                        <assignee username="valentin.kovalenko@mongodb.com">Valentin Kavalenka</assignee>
                                    <reporter username="jeff.yemin@mongodb.com">Jeffrey Yemin</reporter>
                        <labels>
                            <label>tech-debt</label>
                    </labels>
                <created>Sat, 29 Apr 2023 20:27:23 +0000</created>
                <updated>Mon, 9 Oct 2023 15:28:23 +0000</updated>
                                                                            <component>POJO</component>
                                        <votes>0</votes>
                                    <watches>2</watches>
                                                                                                                <comments>
                            <comment id="5488209" author="xgen-internal-githook" created="Fri, 9 Jun 2023 14:57:18 +0000"  >&lt;p&gt;Author: &lt;/p&gt;
{&apos;name&apos;: &apos;Valentin Kovalenko&apos;, &apos;email&apos;: &apos;valentin.kovalenko@mongodb.com&apos;, &apos;username&apos;: &apos;stIncMale&apos;}
&lt;p&gt;Message: Remove specialization-related conditional logic from `PojoCodecImpl` by introducing `LazyPropertyModelCodec.NeedsSpecializationCodec` (#1136)&lt;/p&gt;

&lt;p&gt;This commit moves some of the conditional logic from `PojoCodecImpl` under the rug,&lt;br/&gt;
thus allegedly simplifying `PojoCodecImpl`, but not the POJO codec implementation overall.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://jira.mongodb.org/browse/JAVA-4954&quot; title=&quot;Refactor PojoCodec to leverage CodecProvider.get(clazz, typeArguments, registry)&quot; class=&quot;issue-link&quot; data-issue-key=&quot;JAVA-4954&quot;&gt;JAVA-4954&lt;/a&gt;&lt;br/&gt;
Branch: master&lt;br/&gt;
&lt;a href=&quot;https://github.com/mongodb/mongo-java-driver/commit/14cfcdca70e3e4e93e6fecefc35af1eb4da061cf&quot; class=&quot;external-link&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener&quot;&gt;https://github.com/mongodb/mongo-java-driver/commit/14cfcdca70e3e4e93e6fecefc35af1eb4da061cf&lt;/a&gt;&lt;/p&gt;</comment>
                            <comment id="5476915" author="JIRAUSER1258163" created="Tue, 6 Jun 2023 02:27:43 +0000"  >&lt;blockquote&gt;&lt;p&gt;Use get(Class&amp;lt;T&amp;gt; clazz, List&amp;lt;Type&amp;gt; typeArguments, CodecRegistry registry) if PropertyCodecProvider/PropertyCodecRegistry and PropertyModelBuilder.codec are not used&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;I don&apos;t see how we can tell whether those mechanisms are used or not when deciding whether to use the new (not yet existing) implementation of &lt;tt&gt;get&lt;/tt&gt;, given that the way they are used is lazy, while the new &lt;tt&gt;get&lt;/tt&gt; is eager. But even if this is possible (I am not sure I can do that), it will make things much more complex (I still fail to understand the existing code, and have a voice in my head telling me that trying to understand it is not worth it)&lt;/p&gt;

&lt;p&gt;The way out I see that does not introduce a new POJO codec is something you will not like:&lt;/p&gt;
&lt;ol&gt;
	&lt;li&gt;Deprecate &lt;tt&gt;PropertyCodecProvider&lt;/tt&gt;/&lt;tt&gt;PropertyCodecRegistry&lt;/tt&gt; and &lt;tt&gt;PropertyModelBuilder.codec&lt;/tt&gt; for removal without providing an alternative.&lt;/li&gt;
	&lt;li&gt;Remove the aforementioned in a major release and implement a replacement in the form of the new &lt;tt&gt;get&lt;/tt&gt; implementation.&lt;/li&gt;
&lt;/ol&gt;
</comment>
                            <comment id="5476811" author="jeff.yemin" created="Tue, 6 Jun 2023 01:16:56 +0000"  >&lt;p&gt;Is there a longer time horizon that we could take towards simplification, something like:&lt;/p&gt;

&lt;ol&gt;
	&lt;li&gt;Use get(Class&amp;lt;T&amp;gt; clazz, List&amp;lt;Type&amp;gt; typeArguments, CodecRegistry registry) if PropertyCodecProvider/PropertyCodecRegistry and PropertyModelBuilder.codec are not used&lt;/li&gt;
	&lt;li&gt;Deprecate PropertyCodecProvider/PropertyCodecRegistry and PropertyModelBuilder.codec&lt;/li&gt;
	&lt;li&gt;Remove PropertyCodecProvider/PropertyCodecRegistry and PropertyModelBuilder.codec in a major release&lt;/li&gt;
&lt;/ol&gt;
</comment>
                            <comment id="5476795" author="JIRAUSER1258163" created="Tue, 6 Jun 2023 01:04:02 +0000"  >&lt;p&gt;The thoughts below may be used as a starter for a discussion.&lt;/p&gt;

&lt;p&gt;I think it may be impossible to refactor POJO codec such that it benefits from &lt;tt&gt;PojoCodecProvider&lt;/tt&gt; implementing the new &lt;tt&gt;get(Class&amp;lt;T&amp;gt; clazz, List&amp;lt;Type&amp;gt; typeArguments, CodecRegistry registry)&lt;/tt&gt; method introduced in &lt;a href=&quot;https://jira.mongodb.org/browse/JAVA-4967&quot; title=&quot;Deprecate Parameterizable, introduce default CodecProvider.get(Class&amp;lt;T&amp;gt;, List&amp;lt;Type&amp;gt;, CodecRegistry) instead&quot; class=&quot;issue-link&quot; data-issue-key=&quot;JAVA-4967&quot;&gt;&lt;del&gt;JAVA-4967&lt;/del&gt;&lt;/a&gt; (the same goes about &lt;tt&gt;Parameterizable&lt;/tt&gt;, only now its more clear).&lt;/p&gt;

&lt;ol&gt;
	&lt;li&gt;Notice that &lt;tt&gt;PojoCodecProvider&lt;/tt&gt; does not currently implement this method, yet POJO codec handles parameterized types. How does it do that? My understanding is that this happens because of the logic in &lt;tt&gt;LazyPropertyModelCodec&lt;/tt&gt;, which deals with type parameters.&lt;/li&gt;
	&lt;li&gt;If we implement the new &lt;tt&gt;get&lt;/tt&gt; method on &lt;tt&gt;PojoCodecProvider&lt;/tt&gt;, that method must deal with &lt;tt&gt;List&amp;lt;Type&amp;gt; typeArguments&lt;/tt&gt; eagerly, as its done in &lt;tt&gt;RecordCodecProvider&lt;/tt&gt;/&lt;tt&gt;RecordCodec&lt;/tt&gt;, allowing the &lt;tt&gt;ProvidersCodecRegistry&lt;/tt&gt; to &quot;secretly&quot; create &lt;tt&gt;LazyCodec&lt;/tt&gt; (via &lt;tt&gt;ChildCodecRegistry&lt;/tt&gt;) when it deems needed (not that I currently understand any part of that code).&lt;/li&gt;
	&lt;li&gt;Adding that eager logic in addition to the logic in and around &lt;tt&gt;LazyPropertyModelCodec&lt;/tt&gt; will only further complicate the implementation of the POJO codec. In other words, it seems that the POJO codec can only benefit from the new &lt;tt&gt;get&lt;/tt&gt; method if it can get rid of the logic in &lt;tt&gt;LazyPropertyModelCodec&lt;/tt&gt; and around it, which it can&apos;t because it must continue supporting &lt;tt&gt;PropertyCodecProvider&lt;/tt&gt;/&lt;tt&gt;PropertyCodecRegistry&lt;/tt&gt; and &lt;tt&gt;PropertyModelBuilder.codec&lt;/tt&gt;.&lt;/li&gt;
	&lt;li&gt;Furthermore, if the new &lt;tt&gt;get&lt;/tt&gt; is implemented, the implementation can&apos;t even exist separately from the existing code: it must fall back to the existing logic if it fails to produce a codec for a parameterized type. Not only it seems impossible for it to know whether it failed or not (it may produce a codec, but the codec will still fail to either correctly encode or decode), but even if there is a way, the &lt;tt&gt;get&lt;/tt&gt; code will be entangled with the existing code, making things more complex than when having two separate implementations.&lt;/li&gt;
&lt;/ol&gt;
</comment>
                            <comment id="5433230" author="JIRAUSER1258163" created="Wed, 17 May 2023 20:42:25 +0000"  >&lt;p&gt;Yes, that&apos;s how the new &lt;tt&gt;CodecProvider.get&lt;/tt&gt; and the existing &lt;tt&gt;CodecRegistry.get&lt;/tt&gt; are supposed to work together. I understand this part, but it says nothing about how to simplify &lt;tt&gt;PojoCodecImpl&lt;/tt&gt; with its &lt;tt&gt;ClassModel&lt;/tt&gt;/&lt;tt&gt;PropertyModel&lt;/tt&gt;/&lt;tt&gt;PropertyCodecProvider&lt;/tt&gt; public API (&lt;tt&gt;PropertyModel&lt;/tt&gt; allows users to specify the optional &lt;tt&gt;Codec&lt;/tt&gt; for it, which is a mechanism that duplicates / conflicts with the &lt;tt&gt;CodecProvider&lt;/tt&gt;, and with &lt;tt&gt;PropertyCodecProvider&lt;/tt&gt;; i.e., there are three conflicting mechanisms solving the same task, all expressed via public API).&lt;/p&gt;

&lt;p&gt;In order to refactor a piece of code, one at first must understand it. I do not have understanding of the POJO codec code (it is spread across many classes, &lt;tt&gt;PojoCodecImpl&lt;/tt&gt; is just one of them), and the way I am trying to approach it is by understanding it bit by bit. One of such bits I expressed in &lt;a href=&quot;https://jira.mongodb.org/browse/JAVA-4954?focusedCommentId=5432833&amp;amp;page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-5432833&quot; class=&quot;external-link&quot; rel=&quot;nofollow&quot;&gt;https://jira.mongodb.org/browse/JAVA-4954?focusedCommentId=5432833&amp;amp;page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-5432833&lt;/a&gt;. And it seems like I even found the answer to the question I asked there: the broken &lt;tt&gt;PojoCodecImpl&lt;/tt&gt; (one with &lt;tt&gt;specialized&lt;/tt&gt; being &lt;tt&gt;false&lt;/tt&gt;) is replaced after being created by the code in &lt;tt&gt;LazyPropertyModelCodec.createCodec()&lt;/tt&gt;. It appears that at first &lt;tt&gt;LazyPropertyModelCodec.getCodecFromPropertyRegistry()&lt;/tt&gt; creates a broken &lt;tt&gt;PojoCodecImpl&lt;/tt&gt;, and then &lt;tt&gt;LazyPropertyModelCodec.createCodec()&lt;/tt&gt; creates a working &lt;tt&gt;PojoCodecImpl&lt;/tt&gt; based on the data in the broken &lt;tt&gt;PojoCodecImpl&lt;/tt&gt;.&lt;/p&gt;</comment>
                            <comment id="5432889" author="jeff.yemin" created="Wed, 17 May 2023 19:12:51 +0000"  >&lt;p&gt;I was hoping that the following could happen:&lt;/p&gt;
&lt;ol&gt;
	&lt;li&gt;&lt;tt&gt;PojoCodecProvider&lt;/tt&gt; could override the new &lt;tt&gt;CodecProvider#get&lt;/tt&gt; overload you added in the PR in order to look up codecs for parameterized POJOs&lt;/li&gt;
	&lt;li&gt;&lt;tt&gt;PojocCodec&lt;/tt&gt; could use the {{&lt;tt&gt;CodecRegistry#get(java.lang.Class&amp;lt;T&amp;gt;, java.util.List&amp;lt;java.lang.reflect.Type&amp;gt;)&lt;/tt&gt;}} method to look up codecs for its fields whose types are parameterized.&lt;/li&gt;
&lt;/ol&gt;


&lt;p&gt;Let me know your thoughts.&lt;/p&gt;</comment>
                            <comment id="5432833" author="JIRAUSER1258163" created="Wed, 17 May 2023 18:54:22 +0000"  >&lt;p&gt;Got it, thank you &lt;a href=&quot;https://jira.mongodb.org/secure/ViewProfile.jspa?name=jeff.yemin%40mongodb.com&quot; class=&quot;user-hover&quot; rel=&quot;jeff.yemin@mongodb.com&quot;&gt;jeff.yemin@mongodb.com&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Since I fail to develop even a high-level view on how to refactor &lt;tt&gt;PojoCodecImpl&lt;/tt&gt; such that it utilizes &lt;tt&gt;Parameterizable&lt;/tt&gt; / the new &lt;tt&gt;CodecProvider.get&lt;/tt&gt; and becomes simpler, I decided to see if I may have any success trying to do small pieces of refactoring, like simplifying a piece of code that may be written in a convoluted way. &lt;tt&gt;PropertyModel.codec&lt;/tt&gt;/&lt;tt&gt;cachedCodec&lt;/tt&gt; and &lt;tt&gt;PojoCodecImpl.specialized&lt;/tt&gt;/&lt;tt&gt;specialize()&lt;/tt&gt; (they are connected) appeared to be a good start.&lt;/p&gt;

&lt;p&gt;From the inception, &lt;tt&gt;PojoCodec&lt;/tt&gt; (the code was later moved to &lt;tt&gt;PojoCodecImpl&lt;/tt&gt;) had the &lt;tt&gt;specialized&lt;/tt&gt; field and the specialization logic around it, as well as the &lt;tt&gt;specialized&lt;/tt&gt; checks in &lt;tt&gt;encode&lt;/tt&gt;/&lt;tt&gt;decode&lt;/tt&gt; methods that render the codec broken if &lt;tt&gt;specialized&lt;/tt&gt; (it is set only in the constructor of &lt;tt&gt;PojoCodec&lt;/tt&gt;) is not &lt;tt&gt;true&lt;/tt&gt;. I fail to understand this logic: why would we want to create a codec that we know can never encode and can only sometimes decode? At first glance this may look somewhat similar to creating an unusable &lt;tt&gt;Parameterizable&lt;/tt&gt; codec only to later call &lt;tt&gt;Parameterizable.parameterize&lt;/tt&gt; and replace it with the working one created by this method, but nothing like that happens with &lt;tt&gt;PojoCodec&lt;/tt&gt; - once created as not &lt;tt&gt;specialized&lt;/tt&gt;, it stays broken and does not get replaced as far as I can see.&lt;/p&gt;</comment>
                            <comment id="5429660" author="jeff.yemin" created="Tue, 16 May 2023 20:24:46 +0000"  >&lt;p&gt;I believe we did that because those existing codecs are public and the work to make them Parameterizable looked to be a breaking change. PojoCodecImpl, by contrast, is not public, only PojoCodecProvider&lt;/p&gt;</comment>
                            <comment id="5429162" author="JIRAUSER1258163" created="Tue, 16 May 2023 18:11:29 +0000"  >&lt;p&gt;&lt;a href=&quot;https://jira.mongodb.org/secure/ViewProfile.jspa?name=jeff.yemin%40mongodb.com&quot; class=&quot;user-hover&quot; rel=&quot;jeff.yemin@mongodb.com&quot;&gt;jeff.yemin@mongodb.com&lt;/a&gt; If we currently think that &lt;tt&gt;PojoCodecImpl&lt;/tt&gt; may probably be refactored to use &lt;tt&gt;Parameterized&lt;/tt&gt; (or the new &lt;tt&gt;CodecProvider.get(Class&amp;lt;T&amp;gt;, List&amp;lt;Type&amp;gt;, CodecRegistry)&lt;/tt&gt;), why did we have to add &lt;tt&gt;CollectionCodec&lt;/tt&gt;, &lt;tt&gt;MapCodecV2&lt;/tt&gt; and did not refactor &lt;tt&gt;IterableCodec&lt;/tt&gt;, &lt;tt&gt;MapCodec&lt;/tt&gt;? These codecs appear to be much simpler than the POJO codec, yet we had to create new versions of them.&lt;/p&gt;</comment>
                            <comment id="5409973" author="JIRAUSER1258163" created="Mon, 8 May 2023 22:15:02 +0000"  >&lt;p&gt;&lt;tt&gt;PojoCodec&lt;/tt&gt; is implemented by &lt;tt&gt;PojoCodecImpl&lt;/tt&gt; and &lt;tt&gt;AutomaticPojoCodec&lt;/tt&gt;, but the latter is a trivial decorator that changes exception messages, which is why only &lt;tt&gt;PojoCodecImpl&lt;/tt&gt; is relevant in the context of this task.&lt;/p&gt;

&lt;h1&gt;&lt;a name=&quot;Mutabilityof%7B%7BPojoCodecImpl%7D%7D.&quot;&gt;&lt;/a&gt;Mutability of &lt;tt&gt;PojoCodecImpl&lt;/tt&gt;.&lt;/h1&gt;

&lt;p&gt;There are two conceptual sources of mutability of &lt;tt&gt;PojoCodecImpl&lt;/tt&gt;:&lt;/p&gt;

&lt;ul&gt;
	&lt;li&gt;The one related to creating and representing the POJO metadata: &lt;tt&gt;PojoCodecImpl&lt;/tt&gt; contains &lt;tt&gt;DiscriminatorLookup&lt;/tt&gt;, which is mutable. At the moment I am not sure if &lt;tt&gt;ClassModel&lt;/tt&gt; is mutable.&lt;/li&gt;
	&lt;li&gt;And the one related to creating and configuring codecs: &lt;tt&gt;PojoCodecImpl&lt;/tt&gt; contains &lt;tt&gt;CodecRegistry&lt;/tt&gt; and &lt;tt&gt;PropertyCodecRegistry&lt;/tt&gt;, which are mutable.&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;Within the scope of this task, only the mutability related to creating and configuring codecs should be considered. &lt;b&gt;The two sources of mutability are tangled&lt;/b&gt; with each other because &lt;tt&gt;ClassModel&lt;/tt&gt; refers to &lt;tt&gt;Codec&lt;/tt&gt; s via &lt;tt&gt;PropertyModel&lt;/tt&gt; s, which is &lt;font color=&quot;#4C9AFF&quot;&gt;(I am guessing) to avoid looking up codecs in &lt;tt&gt;CodecRegistry&lt;/tt&gt;/&lt;tt&gt;PropertyCodecRegistry&lt;/tt&gt; each time they are needed. &lt;a href=&quot;https://jira.mongodb.org/secure/ViewProfile.jspa?name=jeff.yemin%40mongodb.com&quot; class=&quot;user-hover&quot; rel=&quot;jeff.yemin@mongodb.com&quot;&gt;jeff.yemin@mongodb.com&lt;/a&gt; &lt;b&gt;Is my guess correct here?&lt;/b&gt;&lt;/font&gt; &lt;tt&gt;RecordCodec.ComponentModel&lt;/tt&gt; also refers a &lt;tt&gt;Codec&lt;/tt&gt;, presumably for the same reason. &lt;b&gt;This appears to hamper straightforward reusing the code from &lt;tt&gt;RecordCodec&lt;/tt&gt; in &lt;tt&gt;PojoCodecImpl&lt;/tt&gt;.&lt;/b&gt;&lt;/p&gt;

&lt;h1&gt;&lt;a name=&quot;Representingtypeswiththeirtypearguments&quot;&gt;&lt;/a&gt;Representing types with their type arguments&lt;/h1&gt;

&lt;p&gt;&lt;b&gt;The approaches &lt;tt&gt;PojoCodecImpl&lt;/tt&gt; and &lt;tt&gt;RecordCodec&lt;/tt&gt; take on representing types with their type arguments are similar conceptually, but on the other hand, they are coded differently. This difference is an obstacle when trying to reuse the code from &lt;tt&gt;RecordCodec&lt;/tt&gt; in &lt;tt&gt;PojoCodecImpl&lt;/tt&gt; .&lt;/b&gt; Moreover, the approach taken by &lt;tt&gt;PojoCodecImpl&lt;/tt&gt; seems at the first glance superior to the one taken by &lt;tt&gt;RecordCodec&lt;/tt&gt;. Below I describe what we have for woking with types in the Java SE API, in &lt;tt&gt;PojoCodecImpl&lt;/tt&gt;, in &lt;tt&gt;RecordCodec&lt;/tt&gt;.&lt;/p&gt;

&lt;h2&gt;&lt;a name=&quot;%7B%7Bjava.lang.reflect.Type%7D%7DintheJavaSEAPI&quot;&gt;&lt;/a&gt;&lt;tt&gt;java.lang.reflect.Type&lt;/tt&gt; in the Java SE API&lt;/h2&gt;

&lt;p&gt;The only provided implementation of &lt;a href=&quot;https://docs.oracle.com/javase/8/docs/api/java/lang/reflect/Type.html&quot; class=&quot;external-link&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener&quot;&gt;&lt;tt&gt;Type&lt;/tt&gt;&lt;/a&gt; is &lt;a href=&quot;https://docs.oracle.com/javase/8/docs/api/java/lang/Class.html&quot; class=&quot;external-link&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener&quot;&gt;&lt;tt&gt;Class&lt;/tt&gt;&lt;/a&gt;. Some &lt;tt&gt;Type&lt;/tt&gt; s are &lt;a href=&quot;https://docs.oracle.com/javase/8/docs/api/java/lang/reflect/ParameterizedType.html&quot; class=&quot;external-link&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener&quot;&gt;&lt;tt&gt;ParameterizedType&lt;/tt&gt; s&lt;/a&gt;, which &lt;a href=&quot;https://docs.oracle.com/javase/8/docs/api/java/lang/reflect/ParameterizedType.html#getActualTypeArguments--&quot; class=&quot;external-link&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener&quot;&gt;know about their type arguments (values of the type parameters)&lt;/a&gt;. Note that because a &lt;tt&gt;Type&lt;/tt&gt;, when parameterized, knows of its type arguments, which are also represented as &lt;tt&gt;Type&lt;/tt&gt;, it appears that a &lt;tt&gt;Type&lt;/tt&gt; is essentially a graph of types that includes all the types involved.&lt;/p&gt;

&lt;h2&gt;&lt;a name=&quot;%7B%7Borg.bson.codecs.pojo.TypeWithTypeParameters%7D%7Din%7B%7BPojoCodecImpl%7D%7D&quot;&gt;&lt;/a&gt;&lt;tt&gt;org.bson.codecs.pojo.TypeWithTypeParameters&lt;/tt&gt; in &lt;tt&gt;PojoCodecImpl&lt;/tt&gt;&lt;/h2&gt;

&lt;p&gt;&lt;font color=&quot;#4C9AFF&quot;&gt;Just knowing the &lt;tt&gt;Type&lt;/tt&gt; is not enough when encoding/decoding, as it does not tell us about the fields/properties/components of a class, i.e., we do need &lt;tt&gt;Class&lt;/tt&gt;. This is likely the reason why &lt;tt&gt;TypeWithTypeParameters&lt;/tt&gt; was introduced when writing &lt;tt&gt;PojoCodecImpl&lt;/tt&gt; (&lt;a href=&quot;https://jira.mongodb.org/secure/ViewProfile.jspa?name=jeff.yemin%40mongodb.com&quot; class=&quot;user-hover&quot; rel=&quot;jeff.yemin@mongodb.com&quot;&gt;jeff.yemin@mongodb.com&lt;/a&gt; &lt;b&gt;Was this indeed the reason?&lt;/b&gt;)&lt;/font&gt;:&lt;/p&gt;

&lt;ul&gt;
	&lt;li&gt;just like &lt;tt&gt;Type&lt;/tt&gt;, it &lt;a href=&quot;https://mongodb.github.io/mongo-java-driver/4.9/apidocs/bson/org/bson/codecs/pojo/TypeWithTypeParameters.html#getTypeParameters()&quot; class=&quot;external-link&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener&quot;&gt;knows about its type arguments&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;it also knows about its fields and the fields of each type argument because it uses &lt;tt&gt;Class&lt;/tt&gt; instead of &lt;tt&gt;Type&lt;/tt&gt;.&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;The driver then uses &lt;tt&gt;TypeWithTypeParameters&lt;/tt&gt; in &lt;tt&gt;PropertyCodecRegistry.get(TypeWithTypeParameters)&lt;/tt&gt;.&lt;/p&gt;

&lt;p&gt;Note here that specifically for &lt;tt&gt;PojoCodec&lt;/tt&gt;, &lt;tt&gt;PropertyCodecRegistry&lt;/tt&gt; and &lt;tt&gt;PropertyCodecProvider&lt;/tt&gt; were introduced to the public API (unlike for &lt;tt&gt;CodecRegistry&lt;/tt&gt;, a user has no way to specify his implementation of &lt;tt&gt;PropertyCodecRegistry&lt;/tt&gt;, and can only specify a custom &lt;tt&gt;PropertyCodecProvider&lt;/tt&gt;). &lt;font color=&quot;#4C9AFF&quot;&gt;My guess is that these two interfaces (of which only &lt;tt&gt;PropertyCodecProvider&lt;/tt&gt; should have been made part of the public API, which is the same issue as we have with &lt;tt&gt;CodecRegistry&lt;/tt&gt; and &lt;tt&gt;CodecProvider&lt;/tt&gt;) were introduced as a worse solution to the same problem that the introduction of &lt;tt&gt;CodecRegistry.get(Class&amp;lt;T&amp;gt;, List&amp;lt;Type&amp;gt;)&lt;/tt&gt; solved. &lt;a href=&quot;https://jira.mongodb.org/secure/ViewProfile.jspa?name=jeff.yemin%40mongodb.com&quot; class=&quot;user-hover&quot; rel=&quot;jeff.yemin@mongodb.com&quot;&gt;jeff.yemin@mongodb.com&lt;/a&gt; &lt;b&gt;Am I guessing correctly here?&lt;/b&gt;&lt;/font&gt;&lt;/p&gt;

&lt;h2&gt;&lt;a name=&quot;Apairof%7B%7BClass%7D%7Dand%7B%7BList%3CType%3E%7D%7Din%7B%7BRecordCodec%7D%7D&quot;&gt;&lt;/a&gt;A pair of &lt;tt&gt;Class&lt;/tt&gt; and &lt;tt&gt;List&amp;lt;Type&amp;gt;&lt;/tt&gt; in &lt;tt&gt;RecordCodec&lt;/tt&gt;&lt;/h2&gt;

&lt;p&gt;Instead of using &lt;tt&gt;TypeWithTypeParameters&lt;/tt&gt;, &lt;tt&gt;RecordCodec&lt;/tt&gt; uses two unrelated (from the standpoint of the compiler) objects &lt;tt&gt;Class&lt;/tt&gt; and &lt;tt&gt;List&amp;lt;Type&amp;gt;&lt;/tt&gt; to represent seemingly the same thing as &lt;tt&gt;TypeWithTypeParameters&lt;/tt&gt;, and, consequently, &lt;tt&gt;CodecRegistry.get(Class, List&amp;lt;Type&amp;gt;)&lt;/tt&gt; instead of &lt;tt&gt;CodecRegistry.get(TypeWithTypeParameters)&lt;/tt&gt;.&lt;/p&gt;

&lt;p&gt;&lt;font color=&quot;#4C9AFF&quot;&gt;&lt;a href=&quot;https://jira.mongodb.org/secure/ViewProfile.jspa?name=jeff.yemin%40mongodb.com&quot; class=&quot;user-hover&quot; rel=&quot;jeff.yemin@mongodb.com&quot;&gt;jeff.yemin@mongodb.com&lt;/a&gt; &lt;b&gt;What were the reasons for not using &lt;tt&gt;TypeWithTypeParameters&lt;/tt&gt; (at the first glance, I like this type), and using a pair of &lt;tt&gt;Class&lt;/tt&gt; and &lt;tt&gt;List&amp;lt;Type&amp;gt;&lt;/tt&gt; instead? Also, if you note that something I wrote above is clearly wrong, could you please correct me?&lt;/b&gt;&lt;/font&gt;&lt;/p&gt;</comment>
                    </comments>
                <issuelinks>
                            <issuelinktype id="10620">
                    <name>Issue split</name>
                                            <outwardlinks description="split to">
                                        <issuelink>
            <issuekey id="2342609">JAVA-4967</issuekey>
        </issuelink>
                            </outwardlinks>
                                                        </issuelinktype>
                            <issuelinktype id="10012">
                    <name>Related</name>
                                            <outwardlinks description="related to">
                                        <issuelink>
            <issuekey id="403930">JAVA-2554</issuekey>
        </issuelink>
                            </outwardlinks>
                                                        </issuelinktype>
                    </issuelinks>
                <attachments>
                    </attachments>
                <subtasks>
                    </subtasks>
                <customfields>
                                                                                                                                                                                                                                                                                                                                                                    <customfield id="customfield_15850" key="com.atlassian.jira.plugins.jira-development-integration-plugin:devsummary">
                        <customfieldname>Development</customfieldname>
                        <customfieldvalues>
                            
                        </customfieldvalues>
                    </customfield>
                                                                                            <customfield id="customfield_14266" key="com.atlassian.jira.plugin.system.customfieldtypes:textarea">
                        <customfieldname>Documentation Changes Summary</customfieldname>
                        <customfieldvalues>
                            <customfieldvalue>&lt;p&gt;1.  What would you like to communicate to the user about this feature?&lt;br/&gt;
2.  Would you like the user to see examples of the syntax and/or executable code and its output?&lt;br/&gt;
3.  Which versions of the driver/connector does this apply to?&lt;/p&gt;</customfieldvalue>

                        </customfieldvalues>
                    </customfield>
                                                                                            <customfield id="customfield_10857" key="com.pyxis.greenhopper.jira:gh-epic-link">
                        <customfieldname>Epic Link</customfieldname>
                        <customfieldvalues>
                            <customfieldvalue>JAVA-3853</customfieldvalue>
                        </customfieldvalues>
                    </customfield>
                                                                                                                                                                                                                                                                                                                                                                                                                                            <customfield id="customfield_21553" key="com.atlassian.jira.plugin.system.customfieldtypes:labels">
                        <customfieldname>Quarter</customfieldname>
                        <customfieldvalues>
                                        <label>FY24Q2</label>
            <label>FY24Q4</label>
    
                        </customfieldvalues>
                    </customfield>
                                                                                            <customfield id="customfield_12550" key="com.pyxis.greenhopper.jira:gh-lexo-rank">
                        <customfieldname>Rank</customfieldname>
                        <customfieldvalues>
                            <customfieldvalue>2|hr1d6s:3</customfieldvalue>

                        </customfieldvalues>
                    </customfield>
                                                                <customfield id="customfield_10558" key="com.pyxis.greenhopper.jira:gh-global-rank">
                        <customfieldname>Rank (Obsolete)</customfieldname>
                        <customfieldvalues>
                            <customfieldvalue>9223372036854775807</customfieldvalue>
                        </customfieldvalues>
                    </customfield>
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            </customfields>
    </item>
</channel>
</rss>