Skip to content

Support recursive types in parameterized records #1007

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

Merged
merged 12 commits into from
Oct 15, 2022
Merged

Conversation

jyemin
Copy link
Collaborator

@jyemin jyemin commented Sep 30, 2022

Provide codec support for records whose type declarations contain cycles.

JAVA-4745

Looking for feedback on the general approach. The codec registry changes could use some more unit tests if we want to proceed with this.

@jyemin jyemin self-assigned this Sep 30, 2022
@jyemin jyemin requested review from rozza and katcharov September 30, 2022 16:50
Copy link
Member

@rozza rozza left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Interesting, would an alternative be to keep this within the RecordCodec implementaiton - so no changes to the CodecRegistry?

For example would just adding a LazyRecordCodec be enough to break any cycles eg:

class LazyRecordCodec<T> implements Codec<T> {
    private final Supplier<Codec<T>> supplier;
    private volatile Codec<T> wrapped;

    LazyRecordCodec(final Supplier<Codec<T>> supplier) {
        this.supplier = supplier;
    }

    @Override
    public void encode(final BsonWriter writer, final T value, final EncoderContext encoderContext) {
        getWrapped().encode(writer, value, encoderContext);
    }

    @Override
    public Class<T> getEncoderClass() {
        return  getWrapped().getEncoderClass();
    }

    @Override
    public T decode(final BsonReader reader, final DecoderContext decoderContext) {
        return getWrapped().decode(reader, decoderContext);
    }

    private Codec<T> getWrapped() {
        if (wrapped == null) {
            wrapped = supplier.get();
        }
        return wrapped;
    }
}

Then the codec could be:

this.codec = new LazyRecordCodec<>(() -> computeCodec(typeParameters, component, codecRegistry));

The downside is it makes all records codecs lazy but the upside would be no changes required outside the RecordCodec.

@jyemin jyemin requested a review from stIncMale October 3, 2022 14:30
@jyemin jyemin changed the title Support cyclical types in parameterized records Support recursive types in parameterized records Oct 3, 2022
@jyemin
Copy link
Collaborator Author

jyemin commented Oct 3, 2022

Yes, I think we could handle cycles outside the registry. But it's cleaner if we put it in the registry, and we get the additional benefit of caching parameterized types.

@jyemin jyemin requested a review from stIncMale October 6, 2022 01:41
@jyemin jyemin marked this pull request as ready for review October 6, 2022 01:42
Copy link
Member

@rozza rozza left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One question - but its looking good

@jyemin jyemin requested review from rozza and removed request for katcharov October 11, 2022 14:03
@jyemin jyemin merged commit 7d73eee into mongodb:master Oct 15, 2022
@jyemin jyemin deleted the j4745 branch October 15, 2022 03:01
@stIncMale stIncMale mentioned this pull request Oct 18, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants