Changes in com.intellij.java.syntax.parser

I’ve noticed a pretty big change in 2025.2. It appears all the classes in com.intellij.lang.java.parser have been replaced with classes in the new package com.intellij.java.syntax.parser.

Was this change primarily a transpilation from Java to Kotlin? Or is there more to this change?

My plugin deeply integrates with the parser; it uses reflection to replace the expression, statement, and other parser components so it can augment the language. Knowing the type of changes that have been made in advance of my adapting to this will help set my expectations. Thanks.

That is dangerous and unreliable, we barely will be able to help when it changes. As far as I know Java plugin has been dramatically changed recently to support Remote Development and detach parser from PSI/resolve.

I’m aware of the complications, the plugin has always kept pace with changes. But the recent change that transpiled parser code from Java to Kotlin was dramatic. By the looks of the code it appears to have been simply run through a converter and not much else has changed. I just wanted to verify that. Thanks again for any info you may provide.

This is probably a preparation to make it Kotlin Multiplatform compatible, so not only conversion but also API used

Ok, I see the API changes, but the code looks mostly the same, just a transform; I’ll only need to reintegrate my language enhancements to the Kotlin source. But as you mentioned it appears the PSI/parser detachment is the real problem I’ll be tackling.

For instance, I am replacing the lexer in PsiBuilderFactoryImpl#createBuilder via an com.intellij.lang.PsiBuilderFactory applicationService. But if the parser/lexer is no longer attached to PSI, I suspect the createBuilder method with the Lexer in the signature is no longer called for Java Psi. . . Ah. I think I understand now. Looks like JavaParserUtil.createSyntaxBuilder have replaced PsiBuilderFactoryImpl#createBuilder.

Also, it appears the new JavaParser class is no longer a singleton, but is instead created anew directly by constructor calls everywhere it is used (!) That seems like a good place for an extension point for parser creation, which would be beneficial for IJ internals as well I would think. Otherwise the current architecture invalidates my existing reflection-based mods to JavaParser. And since there isn’t an extension point for creation, my only viable option is to use class loader shenanigans to replace JavaParser with my own class. I’d rather not do that.

I have noticed most of the changes involving PSI / parser separation have resulted in much less flexibility. For instance, my plugin relies on using the PsiBuilderFactory application service to override it. That is no longer possible with PsiSyntaxBuilderFactory, which is not pluggable at all, it is accessed directly as PsiSyntaxBuilderFactory.getInstance()from internal util code with no way to override it.

Because of this and similar changes, my plugin is in last resort mode right now.

It was built on unstable and reliable grounds from the very beginning, right? And it is rather unfair to blame the platform for that. Have you considered contributing proper extensions to intellij-community with the collaboration with our Java team?

I wouldn’t say my plugin was built entirely on “unstable and unreliable grounds.” While I do have some deep integrations, most of the plugin is based on long-standing, public, pluggable services and extension points. For example, PsiBuilderFactory, which allowed me to integrate more cleanly with the parser.

The issue now is that some of these services have been replaced by hardwired, non-pluggable components such as PsiSyntaxBuilderFactory.getInstance(), and without notice. That removes the possibility of extending or overriding behavior in a supported way. Without those hooks, the only viable option left is to go deeper into internals, like classloader substitutions, which I’d much rather avoid.

So the concern isn’t that the platform is changing, I fully expect it to evolve, but that the changes in this case reduce flexibility and force more deep integration, not less. That seems like a step backward for both plugin authors and the platform itself.

I’d be very happy to contribute changes to intellij-community that reintroduce pluggable points in these areas, whether that’s through restoring service-based factories or introducing parser creation extension points. That would let me (and potentially others) stay on more stable ground and reduce dependence on internals going forward.

If the Java team is open to that, I’d like to discuss what would be an acceptable and maintainable approach.

You did say that you do not use proper API, this is exactly it, unreliable grounds we didn’t commit to support. Not something super bad but unsustainable unfortunately.

I’m only asking that you commit to upholding prior services that were removed without notice, like with PsiBuilderFactory v. PsiSyntaxBuildetFactory. I’m also offering to reimplement these APIs myself if JB is unwilling to. Otherwise, if you aren’t interested, I will be forced to use more deep integrations. But I would prefer a healthier path forward.

1 Like

I think all possible improvements in that area are worthwhile including eliminating reflection usage. We also struggle a lot when plugins break even if we didn’t have communication with authors and they use hacks, users don’t care how something is implemented

You may consider submitting a pull request to IntelliJ community adding the extension points you need. We’ll review it.

Thank you, Tagir and Yuriy.

All of the reflection and similar integrations in my plugin are focused on Java language extensions. These account for maybe ~10% of my IntelliJ integration surface, but they naturally require more adjustments with each new release supporting a major new JDK. But keeping these current has been trivial until now.

I fully understand why the core lexer and parser aren’t designed for open extension, I’d be surprised if they were, but if JetBrains is open to it, I’d like to explore loosening parts of the API just enough to make targeted Java language augmentation easier and more maintainable for my use case.

My immediate concern, though, deals with changes related to services surrounding the new parser like PsiBuilderFactory v. PsiSyntaxBuildetFactory. My plan is to reintroduce these and then map my existing parser mods to the new parser (StatementParser, PrattExpressionParser, etc.), which should restore compatibility with 2025.2.

If service restoration changes like this are acceptable as PRs, I’m happy to proceed, and if there’s interest, I can follow up with broader contributions aimed at making Java more adaptable to extensions.

If you’d like more context, the plugin is part of the Manifold project. Hopefully that helps clarify the goals and why this type of integration matters to my project.

1 Like