From 53560fdc6ff391c34cd43bc66235d52546847789 Mon Sep 17 00:00:00 2001 From: steadytao Date: Fri, 3 Apr 2026 16:59:02 +1000 Subject: [PATCH] Fix Java ulong enum literal generation Emit Java ulong enum constants as signed long bit-equivalents so values above Long.MAX_VALUE compile correctly. Add a focused Java ulong enum schema and regression test covering constants that previously failed with integer number too large. --- java/src/test/java/JavaTest.java | 17 +++++++++++++++++ scripts/generate_code.py | 3 +++ src/idl_gen_java.cpp | 11 ++++++++++- tests/MyGame/Example/Condition.java | 16 ++++++++++++++++ tests/java_ulong_enum_test.fbs | 11 +++++++++++ 5 files changed, 57 insertions(+), 1 deletion(-) create mode 100644 tests/MyGame/Example/Condition.java create mode 100644 tests/java_ulong_enum_test.fbs diff --git a/java/src/test/java/JavaTest.java b/java/src/test/java/JavaTest.java index 4e12db82f9..1c502f7cfd 100644 --- a/java/src/test/java/JavaTest.java +++ b/java/src/test/java/JavaTest.java @@ -87,6 +87,23 @@ public void TestEnums() { assertThat(Any.name(Any.Monster)).isEqualTo("Monster"); } + @org.junit.Test + public void TestUlongEnums() { + assertThat(Condition.Empty).isEqualTo(0L); + assertThat(Condition.GreaterThanEqual) + .isEqualTo(Long.parseUnsignedLong("34F605C97C571896", 16)); + assertThat(Condition.LessThanEqual) + .isEqualTo(Long.parseUnsignedLong("488B1F9FBC949365", 16)); + assertThat(Condition.NotEqual) + .isEqualTo(Long.parseUnsignedLong("88C99E99F1FC6C55", 16)); + assertThat(Condition.Equal) + .isEqualTo(Long.parseUnsignedLong("B763CBE88B6F844F", 16)); + assertThat(Condition.None) + .isEqualTo(Long.parseUnsignedLong("CBF29CE484222645", 16)); + assertThat(Condition.Between) + .isEqualTo(Long.parseUnsignedLong("E5E34D77DC75E2EF", 16)); + } + static void TestBuffer(ByteBuffer bb) { assertThat(Monster.MonsterBufferHasIdentifier(bb)).isEqualTo(true); diff --git a/scripts/generate_code.py b/scripts/generate_code.py index b754ec58f6..9926a8f73e 100755 --- a/scripts/generate_code.py +++ b/scripts/generate_code.py @@ -481,6 +481,9 @@ def glob(path, pattern): dictionary_lookup_schema = "dictionary_lookup.fbs" flatc(["--java", "--kotlin"], schema=dictionary_lookup_schema) +# Java ulong enum generation test +flatc(["--java"], schema="java_ulong_enum_test.fbs") + # Swift Tests swift_prefix = "swift/Tests/Flatbuffers" flatc( diff --git a/src/idl_gen_java.cpp b/src/idl_gen_java.cpp index 130751a749..06bad169fb 100644 --- a/src/idl_gen_java.cpp +++ b/src/idl_gen_java.cpp @@ -419,6 +419,15 @@ class JavaGenerator : public BaseGenerator { return GenDefaultValue(field); } + std::string GenEnumValue(const EnumDef& enum_def, const EnumVal& enum_val) const { + auto value = enum_def.ToString(enum_val); + if (enum_def.underlying_type.base_type == BASE_TYPE_ULONG) { + const uint64_t unsigned_value = StringToUInt(value.c_str()); + return NumToString(static_cast(unsigned_value)); + } + return value; + } + void GenEnum(EnumDef& enum_def, std::string& code) const { if (enum_def.generated) return; @@ -445,7 +454,7 @@ class JavaGenerator : public BaseGenerator { code += GenTypeBasic(DestinationType(enum_def.underlying_type, false)); code += " "; code += namer_.Variant(ev) + " = "; - code += enum_def.ToString(ev); + code += GenEnumValue(enum_def, ev); if (enum_def.underlying_type.base_type == BASE_TYPE_UINT || enum_def.underlying_type.base_type == BASE_TYPE_LONG || enum_def.underlying_type.base_type == BASE_TYPE_ULONG) { diff --git a/tests/MyGame/Example/Condition.java b/tests/MyGame/Example/Condition.java new file mode 100644 index 0000000000..d4fd6016be --- /dev/null +++ b/tests/MyGame/Example/Condition.java @@ -0,0 +1,16 @@ +// automatically generated by the FlatBuffers compiler, do not modify + +package MyGame.Example; + +@SuppressWarnings("unused") +public final class Condition { + private Condition() { } + public static final long Empty = 0L; + public static final long GreaterThanEqual = 3816244097175722134L; + public static final long LessThanEqual = 5227306563417707365L; + public static final long NotEqual = -8590160430205473707L; + public static final long Equal = -5232114142442191793L; + public static final long None = -3750763034362894779L; + public static final long Between = -1881575042115575057L; +} + diff --git a/tests/java_ulong_enum_test.fbs b/tests/java_ulong_enum_test.fbs new file mode 100644 index 0000000000..1153d2e1b6 --- /dev/null +++ b/tests/java_ulong_enum_test.fbs @@ -0,0 +1,11 @@ +namespace MyGame.Example; + +enum Condition : ulong { + Empty = 0, + GreaterThanEqual = 0x34F605C97C571896, + LessThanEqual = 0x488B1F9FBC949365, + NotEqual = 0x88C99E99F1FC6C55, + Equal = 0xB763CBE88B6F844F, + None = 0xCBF29CE484222645, + Between = 0xE5E34D77DC75E2EF +}