Skip to content

Conversation

@jmesnil
Copy link
Collaborator

@jmesnil jmesnil commented Dec 4, 2025

Refactored the domain classes in the spec module from a final class to a Java record to reduce boilerplate code and leverage modern Java features.

Key changes:

  • Converted Task, Part and its subtypes to record with compact canonical constructor
  • Preserved validation and defensive copying logic
  • Added deprecated getter methods for backward compatibility
  • Updated Builder to use record accessor methods

Benefits:

  • Automatic equals(), hashCode(), and toString() implementations
  • Improved code readability and maintainability
  • Zero breaking changes (deprecated getters maintain API compatibility)

Breaking change note: This is marked as breaking because while we maintain backward compatibility through deprecated methods, the underlying class structure has changed from a class to a record.

See ADR 0002 (docs/adr/0002-refactor-domain-classes-to-java-records.md) for detailed architectural decision and rationale.

🤖 Generated with Claude Code

  • Follow the CONTRIBUTING Guide.
  • Make your Pull Request title in the https://www.conventionalcommits.org/ specification.
    • Important Prefixes for release-please:
      • fix: which represents bug fixes, and correlates to a SemVer patch.
      • feat: represents a new feature, and correlates to a SemVer minor.
      • feat!:, or fix!:, refactor!:, etc., which represent a breaking change (indicated by the !) and will result in a SemVer major.
  • Ensure the tests pass
  • Appropriate READMEs were updated (if necessary)

Fixes #507 🦕

@jmesnil
Copy link
Collaborator Author

jmesnil commented Dec 4, 2025

/gemini review

@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello @jmesnil, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request modernizes the core Task data structure by converting it to a Java record. This change streamlines the class definition, making it more readable and maintainable, while carefully preserving API compatibility for consumers. The refactoring leverages Java's built-in features for data carriers, such as automatic equals(), hashCode(), and toString() implementations, without introducing breaking changes to the public API.

Highlights

  • Task Class Refactoring: The Task class has been refactored from a traditional final class to a Java record, significantly reducing boilerplate code and improving conciseness.
  • Backward Compatibility: Deprecated getter methods (e.g., getId(), getContextId()) have been added to the Task record, ensuring existing code bases remain compatible without immediate modifications.
  • Builder Pattern Update: The Task.Builder class has been updated to utilize the new record accessor methods (e.g., task.id() instead of task.getId()) and now uses a static factory method Task.builder().
  • Architectural Decision Record: A new ADR (0002) has been added, documenting the detailed rationale, implementation, and consequences of converting the Task class to a Java record.
  • Codebase-Wide Adaption: All internal usages of the Task class across the codebase have been updated to use the new record accessor methods, promoting consistency and leveraging the new structure.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request is a well-executed refactoring of the Task class into a Java record, which modernizes the code and reduces boilerplate. The changes have been applied consistently across the codebase, replacing old getter methods with new record-style accessors. The inclusion of an Architecture Decision Record (ADR) is a great practice and clearly explains the rationale behind this change.

I've identified a couple of minor improvements for the new Task record to fully enforce its immutability and to handle deprecation warnings more cleanly. Overall, this is a high-quality refactoring that improves the maintainability of the code.

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request is a great refactoring of the Task class into a Java record, which significantly reduces boilerplate and improves code clarity. The changes are applied consistently across the codebase. I've found a few issues: one critical bug that could lead to a runtime exception, one high-severity issue related to the immutability of the new record, and a couple of medium-severity suggestions for code simplification by removing redundant null checks that are no longer necessary with the new record implementation. I've also added a suggestion to update the ADR to reflect the changes for metadata.

@jmesnil jmesnil force-pushed the 507_feat_domain_records branch from db2fff9 to ca0eb30 Compare December 4, 2025 11:29
@jmesnil
Copy link
Collaborator Author

jmesnil commented Dec 4, 2025

/gemini review

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request is a great initiative to modernize the codebase by refactoring the Task class into a Java record, which significantly reduces boilerplate. The changes are consistently applied across the project, and the inclusion of an Architecture Decision Record (ADR) is commendable. However, I've identified a critical runtime bug stemming from an attempt to modify an immutable list returned by the new record. Additionally, there are several opportunities to simplify the code by removing now-redundant null checks, and a suggestion to enhance the ADR to better guide future development. Addressing these points will solidify this valuable refactoring.

@jmesnil
Copy link
Collaborator Author

jmesnil commented Dec 4, 2025

/gemini review

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request is a well-executed refactoring of the Task class into a Java record. The change effectively reduces boilerplate code and modernizes the codebase by leveraging Java records. The attention to backward compatibility by including deprecated getter methods is a thoughtful touch. The updates across the entire codebase to use the new record accessors and builder factory methods are consistent and correct. I have one suggestion to suppress a compiler warning that this change introduces, which will help maintain a clean build.

@jmesnil
Copy link
Collaborator Author

jmesnil commented Dec 4, 2025

@gemini-code-assist what's the compiler warning suggestion that you mentioned?

@gemini-code-assist
Copy link
Contributor

Thanks for the follow-up, @jmesnil! The "compiler warning suggestion" I mentioned refers to the deprecation warnings that code using the old getter methods (like getId() or getContextId()) will now see.

The suggestion is to migrate to the new record accessor methods (e.g., task.id() instead of task.getId()) to remove these warnings and fully leverage the benefits of Java records. This is detailed in the ADR 0002 under "Negative Consequences" and "Implementation Details" regarding deprecation.

@jmesnil jmesnil changed the title refactor!: Convert Task class to Java record refactor!: Convert domain classes to Java records Dec 4, 2025
@jmesnil
Copy link
Collaborator Author

jmesnil commented Dec 4, 2025

/gemini review

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This is an excellent pull request that modernizes the domain classes by converting them to Java records. The refactoring significantly reduces boilerplate code and improves readability and maintainability, as clearly documented in the new ADR. The careful handling of backward compatibility with deprecated getter methods is also well-executed.

I've found one potential issue regarding the immutability of the DataPart record, which I've commented on.

Also, there's a minor inconsistency in the ADR filename mentioned in the pull request description (.../0002-refactor-task-to-java-record.md) versus the actual filename in the repository (.../0002-refactor-domain-classes-to-java-records.md). The actual filename seems more accurate given the scope of the changes.

Overall, this is a high-quality contribution that brings significant improvements to the codebase.

@jmesnil jmesnil force-pushed the 507_feat_domain_records branch from 2c8decb to d4b902e Compare December 4, 2025 13:26
@jmesnil
Copy link
Collaborator Author

jmesnil commented Dec 4, 2025

/gemini review

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request is an excellent and comprehensive refactoring of the domain classes to use Java records. The changes significantly reduce boilerplate code and improve immutability by leveraging modern Java features like records and sealed interfaces. The backward compatibility is thoughtfully maintained through deprecated getter methods. The implementation, including defensive copying in record constructors and updates to the builder pattern, is solid.

My review includes a few minor suggestions to correct documentation typos in the new ADR file and in Javadoc comments to ensure clarity and accuracy. Overall, this is a high-quality contribution that modernizes the codebase.

Refactored the Task class in the spec module from a final class to a
Java record to reduce boilerplate code and leverage modern Java features.

Key changes:
- Converted Task to record with compact canonical constructor
- Preserved validation and defensive copying logic
- Added deprecated getter methods for backward compatibility
- Updated Builder to use record accessor methods

Benefits:
- Automatic equals(), hashCode(), and toString() implementations
- Improved code readability and maintainability
- Zero breaking changes (deprecated getters maintain API compatibility)

Breaking change note: This is marked as breaking because while we
maintain backward compatibility through deprecated methods, the
underlying class structure has changed from a class to a record.

See ADR 0002 (doc/adr/0002-refactor-task-to-java-record.md) for
detailed architectural decision and rationale.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>
@jmesnil jmesnil force-pushed the 507_feat_domain_records branch from 5143951 to 30fd3fd Compare December 4, 2025 14:27
@jmesnil
Copy link
Collaborator Author

jmesnil commented Dec 4, 2025

/gemini review

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request is an excellent and thorough refactoring of the domain classes to Java records. The changes are extensive, touching many files to update class definitions, builders, and call sites to use modern Java features. The introduction of an ADR to document this significant architectural decision is a great practice.

The conversion to records for Task, Message, and Part subtypes, along with making Part a sealed interface, significantly reduces boilerplate and improves code clarity and immutability, as intended. The careful handling of backward compatibility with deprecated getters is well-executed.

My review found the implementation to be very consistent and correct across the codebase. I have only one minor suggestion regarding a misleading comment in one of the mapper classes.

* Uses CommonFieldMapper for Struct → Map conversion.
* Uses factory method to construct DataPart with single-arg constructor.
* Metadata is ignored (not part of proto definition).
* Reconstructs FileWithBytes or FileWithUri based on oneof field.
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

This comment is incorrect and seems to be a copy-paste error from another mapper, as it mentions FileWithBytes and FileWithUri which are not relevant for DataPart. It should be removed to avoid confusion.

jmesnil and others added 2 commits December 5, 2025 08:41
Refactored the Part type hierarchy in the spec module from classes to
Java records with a sealed interface to reduce boilerplate code and
leverage modern Java features.

Key changes:
- Converted Part from abstract class to sealed interface
- Converted DataPart, FilePart, and TextPart to records
- Preserved validation and defensive copying logic in compact constructors
- Added deprecated getter methods for backward compatibility
- Updated gRPC mappers to use record accessor methods

Benefits:
- Automatic equals(), hashCode(), and toString() implementations
- Improved code readability and maintainability
- Exhaustive pattern matching enabled by sealed interface
- Type safety with compile-time immutability guarantees
- Zero breaking changes (deprecated getters maintain API compatibility)

Breaking change note: This is marked as breaking because while we
maintain backward compatibility through deprecated methods, the
underlying type structure has changed from classes to records and
the Part base type changed from abstract class to sealed interface.

See ADR 0002 (doc/adr/0002-refactor-domain-classes-to-java-records.md) for
detailed architectural decision and rationale.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>
Refactored the Message class in the spec module from a final class to a
Java record to reduce boilerplate code and leverage modern Java features.

Key changes:
- Converted Message to record with compact canonical constructor
- Preserved validation and defensive copying logic
- Added deprecated getter methods for backward compatibility
- Updated Builder to use record accessor methods
- Removed setTaskId() and setContextId() setters (use builder for immutability)

Benefits:
- Automatic equals(), hashCode(), and toString() implementations
- Improved code readability and maintainability
- Zero breaking changes for getter methods (deprecated methods maintain API compatibility)

Breaking change note: This is marked as breaking because:
1. The underlying class structure changed from a class to a record
2. The setTaskId() and setContextId() methods were removed (records are immutable)

See ADR 0002 (doc/adr/0002-refactor-domain-classes-to-java-records.md) for
detailed architectural decision and rationale.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>
@jmesnil jmesnil force-pushed the 507_feat_domain_records branch from b9eee60 to 9a37dc3 Compare December 5, 2025 07:41
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.

[Feat!]: Use records for immutable objects in the spec API

1 participant