RFR: Generate Java enums
Maurizio Cimadamore
mcimadamore at openjdk.org
Thu Jul 3 09:40:55 UTC 2025
On Fri, 20 Jun 2025 17:09:19 GMT, Vivek Narang <duke 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.
In general we have not used the translation to Java enum because it's not 100% semantics preserving. In C enum constants are more of loose constants -- given:
enum Color
{
Red,
Green,
Blue,
}
C code can do things like `Red | Blue` -- which are not possible with Java enums.
Moreover, C enum constants live in the same namespace as global variables. So it seemed again honest to allow clients to access enum constants directly after having imported (statically) the main generated header class.
While in some ways using Java enums to model C enums look more natural, it also represents a significant departure from C. I can imagine that some simple uses of C enums would be quite happy with the approach you propose -- but this approach would not scale for more complex uses.
The philosophy of jextract has, so far, been to generate a set of bindings that was as close as possible to the semantics of the extracted header. That has been the main guiding principle. There's a lot of "creativity" jextract could provide on top (and enums is a good example), but adding creativity almost always results in binding that work better in some cases and worse in others. For these reasons, I don't think this PR fits well with the design principles of jextract.
One less radical move could be to give up to the "single namespace" property, and at least group related enum constants together, under a separate generated class. That would mean the Java code would require more "qualifiers" than the associated C code, but with some better separation. Would something like that be enough? Or do you really need these constants to be enum constants (e.g. because you use them in exhaustive switches etc.) ?
-------------
PR Comment: https://git.openjdk.org/jextract/pull/284#issuecomment-3031589143
More information about the jextract-dev
mailing list