Skip to content

Conversation

pxwanglu
Copy link

@pxwanglu pxwanglu commented Aug 25, 2025

Description

try to use better api reflect.TypeFor instead of reflect.TypeOf when we have known the type.

Closes: #XXXX

Summary by CodeRabbit

  • New Features
    • No user-facing changes.
  • Refactor
    • Modernized internal protobuf type detection using updated reflection, with no impact on public APIs or behavior.
  • Tests
    • Updated tests to align with the new reflection approach.
  • Stability
    • No functional changes expected; existing behavior remains the same.

Signed-off-by: pxwanglu <[email protected]>
Copy link
Contributor

coderabbitai bot commented Aug 25, 2025

📝 Walkthrough

Walkthrough

Replaced several reflect.TypeOf initializations with reflect.TypeFor generics across multiple packages. In protocompat, both gogo and proto v2 type references now point to the same proto.Message type, impacting the isProtov2 decision path. Tests and internal registries updated accordingly. No public APIs changed.

Changes

Cohort / File(s) Summary
Protocompat gogo/protoV2 type check unification
baseapp/internal/protocompat/protocompat.go
Switched gogoType and protov2Type to use reflect.TypeForproto.Message, making both references identical and altering isProtov2 branching behavior.
Proto reflection type retrieval modernization
codec/proto_codec_test.go, codec/types/interface_registry.go, contrib/x/group/internal/orm/iterator.go
Replaced reflect.TypeOf((*T)(nil)).Elem() with reflect.TypeForT for proto-related interface types; no functional changes intended in these sites.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor Caller
  participant Protocompat
  participant Reflect

  Caller->>Protocompat: Handle message (detect proto impl)
  Protocompat->>Reflect: Get type for proto.Message (TypeFor)
  Note over Protocompat,Reflect: Both gogoType and protov2Type now resolve to the same proto.Message type
  alt Detected as proto v2 (isProtov2)
    Protocompat-->>Caller: Use proto v2 path
  else Detected as gogo (legacy)
    Protocompat-->>Caller: Use gogo path
  end

  Note over Protocompat: Branching may shift since both checks test the same interface
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Tip

🔌 Remote MCP (Model Context Protocol) integration is now available!

Pro plan users can now connect to remote MCP servers from the Integrations page. Connect with popular remote MCPs such as Notion and Linear to add more context to your reviews and chats.

✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

‼️ IMPORTANT
Auto-reply has been disabled for this repository in the CodeRabbit settings. The CodeRabbit bot will not respond to your replies unless it is explicitly tagged.

  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

CodeRabbit Commands (Invoked using PR/Issue comments)

Type @coderabbitai help to get the list of available commands.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Status, Documentation and Community

  • Visit our Status Page to check the current availability of CodeRabbit.
  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

Knowledge Base: Disabled due to Reviews > Disable Knowledge Base setting

📥 Commits

Reviewing files that changed from the base of the PR and between 79fcc30 and a668d01.

📒 Files selected for processing (4)
  • baseapp/internal/protocompat/protocompat.go (1 hunks)
  • codec/proto_codec_test.go (1 hunks)
  • codec/types/interface_registry.go (1 hunks)
  • contrib/x/group/internal/orm/iterator.go (1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Summary
🔇 Additional comments (3)
codec/types/interface_registry.go (1)

40-40: Good modernization using reflect.TypeFor.

The change from reflect.TypeOf((*proto.Message)(nil)).Elem() to reflect.TypeFor[proto.Message]() is a good use of Go 1.18+ generics, providing better type safety and cleaner code.

contrib/x/group/internal/orm/iterator.go (1)

299-299: Consistent use of reflect.TypeFor for proto.Message type.

Good change that aligns with the overall PR modernization pattern.

codec/proto_codec_test.go (1)

95-95: Good adoption of reflect.TypeFor in tests.

The change to use reflect.TypeFor[testdata.Animal]() in the test is consistent with the broader PR goal and improves code clarity.

Comment on lines +20 to +21
gogoType = reflect.TypeFor[proto.Message]()
protov2Type = reflect.TypeFor[proto.Message]()
Copy link
Contributor

Choose a reason for hiding this comment

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

💡 Verification agent

🧩 Analysis chain

Potential logic issue: both gogoType and protov2Type now reference the same type.

Both variables are now initialized to reflect.TypeFor[proto.Message](), which means they reference the same interface type. This appears to be incorrect since:

  1. The variables have distinct names suggesting they should represent different types
  2. The isProtov2 function at lines 199-204 uses these to distinguish between protov2 and gogo message types
  3. The imports show gogoproto "github.com/cosmos/gogoproto/proto" (line 8) and proto2 "google.golang.org/protobuf/proto" (line 11), suggesting these should map to different proto interfaces

This change will likely break the type discrimination logic in isProtov2.

Apply this diff to correctly use the appropriate types:

-	gogoType           = reflect.TypeFor[proto.Message]()
-	protov2Type        = reflect.TypeFor[proto.Message]()
+	gogoType           = reflect.TypeFor[gogoproto.Message]()
+	protov2Type        = reflect.TypeFor[proto2.Message]()

Let me verify the type usage across the codebase to confirm this issue:


🏁 Script executed:

#!/bin/bash
# Check how gogoType and protov2Type are used in isProtov2 function
rg -A5 -B5 "case typ\.Implements\((gogoType|protov2Type)\)" baseapp/internal/protocompat/

# Check the imports to understand proto vs proto2 usage
rg "^import \(" -A20 baseapp/internal/protocompat/protocompat.go | head -30

# Search for other usages of these variables
rg "gogoType|protov2Type" baseapp/internal/protocompat/

Length of output: 2346


Fix incorrect gogoType and protov2Type initializations

The two variables at lines 20–21 currently both capture the same github.com/golang/protobuf/proto.Message interface, so your isProtov2 discriminator will never distinguish between gogo and protov2 messages. They need to reference their respective interfaces:

• File: baseapp/internal/protocompat/protocompat.go
• Lines: 20–21

Apply this diff:

-   gogoType    = reflect.TypeFor[proto.Message]()
-   protov2Type = reflect.TypeFor[proto.Message]()
+   gogoType    = reflect.TypeFor[gogoproto.Message]()
+   protov2Type = reflect.TypeFor[proto2.Message]()

This change ensures that:

  • typ.Implements(protov2Type) correctly identifies google.golang.org/protobuf/proto.Message implementations
  • typ.Implements(gogoType) correctly identifies github.com/cosmos/gogoproto/proto.Message implementations
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
gogoType = reflect.TypeFor[proto.Message]()
protov2Type = reflect.TypeFor[proto.Message]()
++ b/baseapp/internal/protocompat/protocompat.go
@@ Lines 20-21
- gogoType = reflect.TypeFor[proto.Message]()
gogoType = reflect.TypeFor[gogoproto.Message]()
protov2Type = reflect.TypeFor[proto2.Message]()
🤖 Prompt for AI Agents
In baseapp/internal/protocompat/protocompat.go around lines 20 to 21, the
gogoType and protov2Type variables are both initialized to the same
proto.Message interface; update them so gogoType references
github.com/cosmos/gogoproto/proto.Message and protov2Type references
google.golang.org/protobuf/proto.Message, and add or adjust imports accordingly
so typ.Implements(protov2Type) and typ.Implements(gogoType) correctly
discriminate between protov2 and gogo messages.

@aljo242
Copy link
Contributor

aljo242 commented Aug 29, 2025

@pxwanglu why is this better? what is the benefit of this?

@pxwanglu
Copy link
Author

@pxwanglu why is this better? what is the benefit of this?

Thanks for your review. @aljo242

reflect.TypeOf is one of a few fundamental reflect APIs. It returns the dynamic type of a value. However, golang/go#35427. The correct code is long, awkward, and hard to explain.

Pre-generics, there was no way to write a nice API to get a static reflect.Type. Now there is.

More info golang/go#60088

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.

2 participants