Fix nullability of generated Kotlin ByteBuffer accessors (#8844)

* fixes #8691
This commit is contained in:
souma987
2025-12-15 08:56:40 +09:00
committed by GitHub
parent 7bfaabc358
commit 60910fb7f5
7 changed files with 73 additions and 39 deletions

View File

@@ -1201,11 +1201,12 @@ class KotlinGenerator : public BaseGenerator {
: InlineSize(field.value.type.VectorType()));
// Generate a ByteBuffer accessor for strings & vectors of scalars.
// e.g.
// val inventoryByteBuffer: ByteBuffer
// val inventoryByteBuffer: ByteBuffer?
// get = __vector_as_bytebuffer(14, 1)
auto buffer_type = field.IsRequired() ? "ByteBuffer" : "ByteBuffer?";
GenerateGetterOneLine(
writer, field_name + "AsByteBuffer", "ByteBuffer", [&]() {
writer, field_name + "AsByteBuffer", buffer_type, [&]() {
writer.SetValue("end", end_idx);
writer += "__vector_as_bytebuffer({{offset}}, {{end}})";
});
@@ -1213,10 +1214,10 @@ class KotlinGenerator : public BaseGenerator {
// Generate a ByteBuffer accessor for strings & vectors of scalars.
// e.g.
// fun inventoryInByteBuffer(_bb: Bytebuffer):
// ByteBuffer = __vector_as_bytebuffer(_bb, 14, 1)
// ByteBuffer? = __vector_as_bytebuffer(_bb, 14, 1)
GenerateFunOneLine(
writer, field_name + "InByteBuffer", "_bb: ByteBuffer",
"ByteBuffer", [&]() {
buffer_type, [&]() {
writer.SetValue("end", end_idx);
writer += "__vector_in_bytebuffer(_bb, {{offset}}, {{end}})";
});

View File

@@ -80,6 +80,7 @@ class KotlinTest {
TestSharedStringPool()
TestScalarOptional()
TestDictionaryLookup()
TestNullFields()
println("FlatBuffers test: completed successfully")
}
@@ -142,7 +143,7 @@ class KotlinTest {
assert(invsum == 10u)
// Alternative way of accessing a vector:
val ibb = monster.inventoryAsByteBuffer
val ibb = monster.inventoryAsByteBuffer!!
invsum = 0u
while (ibb.position() < ibb.limit()) invsum += ibb.get().toUInt()
assert(invsum == 10u)
@@ -615,5 +616,37 @@ class KotlinTest {
assert(scalarStuff.maybeEnum == OptionalByte.Two)
assert(scalarStuff.defaultEnum == OptionalByte.Two)
}
fun TestNullFields() {
val fbb = FlatBufferBuilder(1)
val nameOffset = fbb.createString("name")
Monster.startMonster(fbb)
Monster.addName(fbb, nameOffset)
Monster.finishMonsterBuffer(fbb, Monster.endMonster(fbb))
val monsterBb = fbb.dataBuffer()
val monster = Monster.getRootAsMonster(monsterBb.duplicate())
assert(monster.pos == null) // struct
assert(monster.enemy == null) // table
assert(monster.test(Monster()) == null) // union
assert(monster.testType == Any_.NONE)
assert(monster.inventoryLength == 0) // vector of scalars
assert(monster.inventoryAsByteBuffer == null)
assert(monster.inventoryInByteBuffer(monsterBb) == null)
assert(monster.testarrayofsortedstructLength == 0) // vector of structs
assert(monster.testarrayofstringLength == 0) // vector of strings
assert(monster.testarrayoftablesLength == 0) // vector of tables
val fbb2 = FlatBufferBuilder(1)
val offset = Stat.createStat(fbb2, 0, 10, 10.toUShort())
fbb2.finish(offset)
val statBb = fbb2.dataBuffer()
val stat = Stat.getRootAsStat(statBb.duplicate())
assert(stat.id == null) // string
assert(stat.idAsByteBuffer == null)
assert(stat.idInByteBuffer(statBb) == null)
}
}
}

View File

@@ -91,8 +91,8 @@ class Monster : Table() {
get() {
val o = __offset(14); return if (o != 0) __vector_len(o) else 0
}
val inventoryAsByteBuffer : ByteBuffer get() = __vector_as_bytebuffer(14, 1)
fun inventoryInByteBuffer(_bb: ByteBuffer) : ByteBuffer = __vector_in_bytebuffer(_bb, 14, 1)
val inventoryAsByteBuffer : ByteBuffer? get() = __vector_as_bytebuffer(14, 1)
fun inventoryInByteBuffer(_bb: ByteBuffer) : ByteBuffer? = __vector_in_bytebuffer(_bb, 14, 1)
fun mutateInventory(j: Int, inventory: UByte) : Boolean {
val o = __offset(14)
return if (o != 0) {
@@ -212,8 +212,8 @@ class Monster : Table() {
get() {
val o = __offset(30); return if (o != 0) __vector_len(o) else 0
}
val testnestedflatbufferAsByteBuffer : ByteBuffer get() = __vector_as_bytebuffer(30, 1)
fun testnestedflatbufferInByteBuffer(_bb: ByteBuffer) : ByteBuffer = __vector_in_bytebuffer(_bb, 30, 1)
val testnestedflatbufferAsByteBuffer : ByteBuffer? get() = __vector_as_bytebuffer(30, 1)
fun testnestedflatbufferInByteBuffer(_bb: ByteBuffer) : ByteBuffer? = __vector_in_bytebuffer(_bb, 30, 1)
val testnestedflatbufferAsMonster : MyGame.Example.Monster? get() = testnestedflatbufferAsMonster(MyGame.Example.Monster())
fun testnestedflatbufferAsMonster(obj: MyGame.Example.Monster) : MyGame.Example.Monster? {
val o = __offset(30)
@@ -379,8 +379,8 @@ class Monster : Table() {
get() {
val o = __offset(52); return if (o != 0) __vector_len(o) else 0
}
val testarrayofboolsAsByteBuffer : ByteBuffer get() = __vector_as_bytebuffer(52, 1)
fun testarrayofboolsInByteBuffer(_bb: ByteBuffer) : ByteBuffer = __vector_in_bytebuffer(_bb, 52, 1)
val testarrayofboolsAsByteBuffer : ByteBuffer? get() = __vector_as_bytebuffer(52, 1)
fun testarrayofboolsInByteBuffer(_bb: ByteBuffer) : ByteBuffer? = __vector_in_bytebuffer(_bb, 52, 1)
fun mutateTestarrayofbools(j: Int, testarrayofbools: Boolean) : Boolean {
val o = __offset(52)
return if (o != 0) {
@@ -469,8 +469,8 @@ class Monster : Table() {
get() {
val o = __offset(64); return if (o != 0) __vector_len(o) else 0
}
val flexAsByteBuffer : ByteBuffer get() = __vector_as_bytebuffer(64, 1)
fun flexInByteBuffer(_bb: ByteBuffer) : ByteBuffer = __vector_in_bytebuffer(_bb, 64, 1)
val flexAsByteBuffer : ByteBuffer? get() = __vector_as_bytebuffer(64, 1)
fun flexInByteBuffer(_bb: ByteBuffer) : ByteBuffer? = __vector_in_bytebuffer(_bb, 64, 1)
fun mutateFlex(j: Int, flex: UByte) : Boolean {
val o = __offset(64)
return if (o != 0) {
@@ -505,8 +505,8 @@ class Monster : Table() {
get() {
val o = __offset(68); return if (o != 0) __vector_len(o) else 0
}
val vectorOfLongsAsByteBuffer : ByteBuffer get() = __vector_as_bytebuffer(68, 8)
fun vectorOfLongsInByteBuffer(_bb: ByteBuffer) : ByteBuffer = __vector_in_bytebuffer(_bb, 68, 8)
val vectorOfLongsAsByteBuffer : ByteBuffer? get() = __vector_as_bytebuffer(68, 8)
fun vectorOfLongsInByteBuffer(_bb: ByteBuffer) : ByteBuffer? = __vector_in_bytebuffer(_bb, 68, 8)
fun mutateVectorOfLongs(j: Int, vectorOfLongs: Long) : Boolean {
val o = __offset(68)
return if (o != 0) {
@@ -528,8 +528,8 @@ class Monster : Table() {
get() {
val o = __offset(70); return if (o != 0) __vector_len(o) else 0
}
val vectorOfDoublesAsByteBuffer : ByteBuffer get() = __vector_as_bytebuffer(70, 8)
fun vectorOfDoublesInByteBuffer(_bb: ByteBuffer) : ByteBuffer = __vector_in_bytebuffer(_bb, 70, 8)
val vectorOfDoublesAsByteBuffer : ByteBuffer? get() = __vector_as_bytebuffer(70, 8)
fun vectorOfDoublesInByteBuffer(_bb: ByteBuffer) : ByteBuffer? = __vector_in_bytebuffer(_bb, 70, 8)
fun mutateVectorOfDoubles(j: Int, vectorOfDoubles: Double) : Boolean {
val o = __offset(70)
return if (o != 0) {
@@ -603,8 +603,8 @@ class Monster : Table() {
get() {
val o = __offset(78); return if (o != 0) __vector_len(o) else 0
}
val vectorOfWeakReferencesAsByteBuffer : ByteBuffer get() = __vector_as_bytebuffer(78, 8)
fun vectorOfWeakReferencesInByteBuffer(_bb: ByteBuffer) : ByteBuffer = __vector_in_bytebuffer(_bb, 78, 8)
val vectorOfWeakReferencesAsByteBuffer : ByteBuffer? get() = __vector_as_bytebuffer(78, 8)
fun vectorOfWeakReferencesInByteBuffer(_bb: ByteBuffer) : ByteBuffer? = __vector_in_bytebuffer(_bb, 78, 8)
fun mutateVectorOfWeakReferences(j: Int, vectorOfWeakReferences: ULong) : Boolean {
val o = __offset(78)
return if (o != 0) {
@@ -669,8 +669,8 @@ class Monster : Table() {
get() {
val o = __offset(84); return if (o != 0) __vector_len(o) else 0
}
val vectorOfCoOwningReferencesAsByteBuffer : ByteBuffer get() = __vector_as_bytebuffer(84, 8)
fun vectorOfCoOwningReferencesInByteBuffer(_bb: ByteBuffer) : ByteBuffer = __vector_in_bytebuffer(_bb, 84, 8)
val vectorOfCoOwningReferencesAsByteBuffer : ByteBuffer? get() = __vector_as_bytebuffer(84, 8)
fun vectorOfCoOwningReferencesInByteBuffer(_bb: ByteBuffer) : ByteBuffer? = __vector_in_bytebuffer(_bb, 84, 8)
fun mutateVectorOfCoOwningReferences(j: Int, vectorOfCoOwningReferences: ULong) : Boolean {
val o = __offset(84)
return if (o != 0) {
@@ -706,8 +706,8 @@ class Monster : Table() {
get() {
val o = __offset(88); return if (o != 0) __vector_len(o) else 0
}
val vectorOfNonOwningReferencesAsByteBuffer : ByteBuffer get() = __vector_as_bytebuffer(88, 8)
fun vectorOfNonOwningReferencesInByteBuffer(_bb: ByteBuffer) : ByteBuffer = __vector_in_bytebuffer(_bb, 88, 8)
val vectorOfNonOwningReferencesAsByteBuffer : ByteBuffer? get() = __vector_as_bytebuffer(88, 8)
fun vectorOfNonOwningReferencesInByteBuffer(_bb: ByteBuffer) : ByteBuffer? = __vector_in_bytebuffer(_bb, 88, 8)
fun mutateVectorOfNonOwningReferences(j: Int, vectorOfNonOwningReferences: ULong) : Boolean {
val o = __offset(88)
return if (o != 0) {
@@ -763,8 +763,8 @@ class Monster : Table() {
get() {
val o = __offset(98); return if (o != 0) __vector_len(o) else 0
}
val vectorOfEnumsAsByteBuffer : ByteBuffer get() = __vector_as_bytebuffer(98, 1)
fun vectorOfEnumsInByteBuffer(_bb: ByteBuffer) : ByteBuffer = __vector_in_bytebuffer(_bb, 98, 1)
val vectorOfEnumsAsByteBuffer : ByteBuffer? get() = __vector_as_bytebuffer(98, 1)
fun vectorOfEnumsInByteBuffer(_bb: ByteBuffer) : ByteBuffer? = __vector_in_bytebuffer(_bb, 98, 1)
fun mutateVectorOfEnums(j: Int, vectorOfEnums: UByte) : Boolean {
val o = __offset(98)
return if (o != 0) {
@@ -800,8 +800,8 @@ class Monster : Table() {
get() {
val o = __offset(102); return if (o != 0) __vector_len(o) else 0
}
val testrequirednestedflatbufferAsByteBuffer : ByteBuffer get() = __vector_as_bytebuffer(102, 1)
fun testrequirednestedflatbufferInByteBuffer(_bb: ByteBuffer) : ByteBuffer = __vector_in_bytebuffer(_bb, 102, 1)
val testrequirednestedflatbufferAsByteBuffer : ByteBuffer? get() = __vector_as_bytebuffer(102, 1)
fun testrequirednestedflatbufferInByteBuffer(_bb: ByteBuffer) : ByteBuffer? = __vector_in_bytebuffer(_bb, 102, 1)
val testrequirednestedflatbufferAsMonster : MyGame.Example.Monster? get() = testrequirednestedflatbufferAsMonster(MyGame.Example.Monster())
fun testrequirednestedflatbufferAsMonster(obj: MyGame.Example.Monster) : MyGame.Example.Monster? {
val o = __offset(102)

View File

@@ -37,8 +37,8 @@ class Stat : Table() {
null
}
}
val idAsByteBuffer : ByteBuffer get() = __vector_as_bytebuffer(4, 1)
fun idInByteBuffer(_bb: ByteBuffer) : ByteBuffer = __vector_in_bytebuffer(_bb, 4, 1)
val idAsByteBuffer : ByteBuffer? get() = __vector_as_bytebuffer(4, 1)
fun idInByteBuffer(_bb: ByteBuffer) : ByteBuffer? = __vector_in_bytebuffer(_bb, 4, 1)
val val_ : Long
get() {
val o = __offset(6)

View File

@@ -180,8 +180,8 @@ class TypeAliases : Table() {
get() {
val o = __offset(24); return if (o != 0) __vector_len(o) else 0
}
val v8AsByteBuffer : ByteBuffer get() = __vector_as_bytebuffer(24, 1)
fun v8InByteBuffer(_bb: ByteBuffer) : ByteBuffer = __vector_in_bytebuffer(_bb, 24, 1)
val v8AsByteBuffer : ByteBuffer? get() = __vector_as_bytebuffer(24, 1)
fun v8InByteBuffer(_bb: ByteBuffer) : ByteBuffer? = __vector_in_bytebuffer(_bb, 24, 1)
fun mutateV8(j: Int, v8: Byte) : Boolean {
val o = __offset(24)
return if (o != 0) {
@@ -203,8 +203,8 @@ class TypeAliases : Table() {
get() {
val o = __offset(26); return if (o != 0) __vector_len(o) else 0
}
val vf64AsByteBuffer : ByteBuffer get() = __vector_as_bytebuffer(26, 8)
fun vf64InByteBuffer(_bb: ByteBuffer) : ByteBuffer = __vector_in_bytebuffer(_bb, 26, 8)
val vf64AsByteBuffer : ByteBuffer? get() = __vector_as_bytebuffer(26, 8)
fun vf64InByteBuffer(_bb: ByteBuffer) : ByteBuffer? = __vector_in_bytebuffer(_bb, 26, 8)
fun mutateVf64(j: Int, vf64: Double) : Boolean {
val o = __offset(26)
return if (o != 0) {

View File

@@ -152,8 +152,8 @@ class MonsterExtra : Table() {
get() {
val o = __offset(20); return if (o != 0) __vector_len(o) else 0
}
val dvecAsByteBuffer : ByteBuffer get() = __vector_as_bytebuffer(20, 8)
fun dvecInByteBuffer(_bb: ByteBuffer) : ByteBuffer = __vector_in_bytebuffer(_bb, 20, 8)
val dvecAsByteBuffer : ByteBuffer? get() = __vector_as_bytebuffer(20, 8)
fun dvecInByteBuffer(_bb: ByteBuffer) : ByteBuffer? = __vector_in_bytebuffer(_bb, 20, 8)
fun mutateDvec(j: Int, dvec: Double) : Boolean {
val o = __offset(20)
return if (o != 0) {
@@ -175,8 +175,8 @@ class MonsterExtra : Table() {
get() {
val o = __offset(22); return if (o != 0) __vector_len(o) else 0
}
val fvecAsByteBuffer : ByteBuffer get() = __vector_as_bytebuffer(22, 4)
fun fvecInByteBuffer(_bb: ByteBuffer) : ByteBuffer = __vector_in_bytebuffer(_bb, 22, 4)
val fvecAsByteBuffer : ByteBuffer? get() = __vector_as_bytebuffer(22, 4)
fun fvecInByteBuffer(_bb: ByteBuffer) : ByteBuffer? = __vector_in_bytebuffer(_bb, 22, 4)
fun mutateFvec(j: Int, fvec: Float) : Boolean {
val o = __offset(22)
return if (o != 0) {

View File

@@ -55,8 +55,8 @@ class Movie : Table() {
get() {
val o = __offset(8); return if (o != 0) __vector_len(o) else 0
}
val charactersTypeAsByteBuffer : ByteBuffer get() = __vector_as_bytebuffer(8, 1)
fun charactersTypeInByteBuffer(_bb: ByteBuffer) : ByteBuffer = __vector_in_bytebuffer(_bb, 8, 1)
val charactersTypeAsByteBuffer : ByteBuffer? get() = __vector_as_bytebuffer(8, 1)
fun charactersTypeInByteBuffer(_bb: ByteBuffer) : ByteBuffer? = __vector_in_bytebuffer(_bb, 8, 1)
fun mutateCharactersType(j: Int, charactersType: UByte) : Boolean {
val o = __offset(8)
return if (o != 0) {