flatbuffers
flatbuffers copied to clipboard
Java enum name() function source compatibility issue
Affected languages: Java FlatBuffer versions: 24.3.25
When adding new enum constants to an existing FlatBuffers enum, the generated Java code can change in ways that break backwards source compatibility. This is surprising behaviour and is not documented anywhere.
In particular, the name
method and the names
static member in the generated Java class are only generated if the enum type is not too sparse. Adding new enum constants can increase the sparseness, causing name
and names
to no longer be generated. This can break backwards source compatibility with existing source code using name
or names
.
Either this behaviour should be documented, or (better) the name
method should be generated unconditionally, and the names
static member should be deprecated and replaced with a means of iterating over all the enum constants in an enum that can work when the enum is sparse.
The only place that I could find where this behaviour described at all is in the source code for the flatbuffer compiler,
specifically in src/idl_gen_java.cc
, in the GenEnum
function https://github.com/google/flatbuffers/blob/fb9afbafc7dfe226b9db54d4923bfb8839635274/src/idl_gen_java.cpp#L439:
void GenEnum(EnumDef &enum_def, std::string &code) const {
...
// Generate a string table for enum values.
// Problem is, if values are very sparse that could generate really big
// tables. Ideally in that case we generate a map lookup instead, but for
// the moment we simply don't output a table at all.
auto range = enum_def.Distance();
// Average distance between values above which we consider a table
// "too sparse". Change at will.
static const uint64_t kMaxSparseness = 5;
if (range / static_cast<uint64_t>(enum_def.size()) < kMaxSparseness &&
GenTypeBasic(DestinationType(enum_def.underlying_type, false)) !=
"long") {