RFR: Generate Java enums

Maurizio Cimadamore mcimadamore at openjdk.org
Mon Jul 7 21:28:52 UTC 2025


On Thu, 3 Jul 2025 09:43:59 GMT, Maurizio Cimadamore <mcimadamore at openjdk.org> wrote:

>> We are using jextract in our [cuVS Java](https://github.com/rapidsai/cuvs/tree/branch-25.08/java) project. As of now, jextract generates individual getter functions for the C enums. This results in code where it is difficult to disambiguate which getter functions are logically grouped together for a particular Enum. Additionally, given the lack of this capability, we also have to manually create and maintain Java enums for each enum in the C layer.
>> 
>> In this PR, I wish to introduce an option to additionally generate Java enums by passing an optional flag `--generate-java-enums`. In case a Java user wishes to use bitwise operations on the enums, they can use the enum's `.ordinal()` method for this. The original static getter methods will still be generated as before. 
>> 
>> Example C enum:
>> 
>> enum SIZE {
>>    S,
>>    M,
>>    L
>> };
>> 
>> Produces the following with jextract:
>> 
>> private static final int S = (int)0L;
>> public static int S() {
>>      return S;
>> }
>> 
>> private static final int M = (int)1L;
>> public static int M() {
>>      return M;
>> }
>> 
>> private static final int L = (int)2L;
>> public static int L() {
>>      return L;
>> }
>> 
>> With this feature enabled using the `--generate-java-enums` flag, the following enum is generated (in addition to the above):
>> 
>> public enum Size {
>>     S(0),
>>     M(1),
>>     L(2);
>> 
>>     private final int value;
>> 
>>     private Size(int value) {;
>>         this.value = value;
>>     }
>> 
>>     public int getValue() {
>>         return this.value;
>>     }
>> }
>> 
>> This PR is created against the `jdk22` branch. I will rebase it to `master` branch if needed.
>
> Another thing that came to mind: if we translate C enums as Java enums -- how is a native function accepting a C enum type translated? If we translate it as an int-accepting function (what we do now) then the Java enum constants cannot be used to call into native functions. If we translate it as a Java-enum-accepting function, then we would make these function stricter than their C counterparts.

> Hey @mcimadamore please excuse my gap in understanding here, but won't this operation be possible in Java by doing: `Color.Red.ordinal() | Color.Blue.ordinal()`?

As said in another comment, there's no guarantee that the Java enum ordinal and the value of the C enum constant will be the same. So, no, that would not be a good translation. Also, please consider clients passing enums to native functions -- right now they can just say e.g.


native_func(RED);


It would be sad if they had to do:


native_func(RED.ordinal());


Of course one could imagine generating one extra overload for each enum-accepting function -- but that has issues:

* you can only use the Java enum-accepting overload in some cases, but not other (where you want to use bitwise ops)
* if a function uses N enum types, you need 2^N overloads (at least if you want to generate all possible combinations)

I don't think much joy is to be had by modelling C enums with Java enums. We've been at it several times, and we keep retracing our steps back to the same answers.

-------------

PR Comment: https://git.openjdk.org/jextract/pull/284#issuecomment-3046568103


More information about the jextract-dev mailing list