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

View File

@@ -80,6 +80,7 @@ class KotlinTest {
TestSharedStringPool() TestSharedStringPool()
TestScalarOptional() TestScalarOptional()
TestDictionaryLookup() TestDictionaryLookup()
TestNullFields()
println("FlatBuffers test: completed successfully") println("FlatBuffers test: completed successfully")
} }
@@ -142,7 +143,7 @@ class KotlinTest {
assert(invsum == 10u) assert(invsum == 10u)
// Alternative way of accessing a vector: // Alternative way of accessing a vector:
val ibb = monster.inventoryAsByteBuffer val ibb = monster.inventoryAsByteBuffer!!
invsum = 0u invsum = 0u
while (ibb.position() < ibb.limit()) invsum += ibb.get().toUInt() while (ibb.position() < ibb.limit()) invsum += ibb.get().toUInt()
assert(invsum == 10u) assert(invsum == 10u)
@@ -615,5 +616,37 @@ class KotlinTest {
assert(scalarStuff.maybeEnum == OptionalByte.Two) assert(scalarStuff.maybeEnum == OptionalByte.Two)
assert(scalarStuff.defaultEnum == 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() { get() {
val o = __offset(14); return if (o != 0) __vector_len(o) else 0 val o = __offset(14); return if (o != 0) __vector_len(o) else 0
} }
val inventoryAsByteBuffer : ByteBuffer get() = __vector_as_bytebuffer(14, 1) val inventoryAsByteBuffer : ByteBuffer? get() = __vector_as_bytebuffer(14, 1)
fun inventoryInByteBuffer(_bb: ByteBuffer) : ByteBuffer = __vector_in_bytebuffer(_bb, 14, 1) fun inventoryInByteBuffer(_bb: ByteBuffer) : ByteBuffer? = __vector_in_bytebuffer(_bb, 14, 1)
fun mutateInventory(j: Int, inventory: UByte) : Boolean { fun mutateInventory(j: Int, inventory: UByte) : Boolean {
val o = __offset(14) val o = __offset(14)
return if (o != 0) { return if (o != 0) {
@@ -212,8 +212,8 @@ class Monster : Table() {
get() { get() {
val o = __offset(30); return if (o != 0) __vector_len(o) else 0 val o = __offset(30); return if (o != 0) __vector_len(o) else 0
} }
val testnestedflatbufferAsByteBuffer : ByteBuffer get() = __vector_as_bytebuffer(30, 1) val testnestedflatbufferAsByteBuffer : ByteBuffer? get() = __vector_as_bytebuffer(30, 1)
fun testnestedflatbufferInByteBuffer(_bb: ByteBuffer) : ByteBuffer = __vector_in_bytebuffer(_bb, 30, 1) fun testnestedflatbufferInByteBuffer(_bb: ByteBuffer) : ByteBuffer? = __vector_in_bytebuffer(_bb, 30, 1)
val testnestedflatbufferAsMonster : MyGame.Example.Monster? get() = testnestedflatbufferAsMonster(MyGame.Example.Monster()) val testnestedflatbufferAsMonster : MyGame.Example.Monster? get() = testnestedflatbufferAsMonster(MyGame.Example.Monster())
fun testnestedflatbufferAsMonster(obj: MyGame.Example.Monster) : MyGame.Example.Monster? { fun testnestedflatbufferAsMonster(obj: MyGame.Example.Monster) : MyGame.Example.Monster? {
val o = __offset(30) val o = __offset(30)
@@ -379,8 +379,8 @@ class Monster : Table() {
get() { get() {
val o = __offset(52); return if (o != 0) __vector_len(o) else 0 val o = __offset(52); return if (o != 0) __vector_len(o) else 0
} }
val testarrayofboolsAsByteBuffer : ByteBuffer get() = __vector_as_bytebuffer(52, 1) val testarrayofboolsAsByteBuffer : ByteBuffer? get() = __vector_as_bytebuffer(52, 1)
fun testarrayofboolsInByteBuffer(_bb: ByteBuffer) : ByteBuffer = __vector_in_bytebuffer(_bb, 52, 1) fun testarrayofboolsInByteBuffer(_bb: ByteBuffer) : ByteBuffer? = __vector_in_bytebuffer(_bb, 52, 1)
fun mutateTestarrayofbools(j: Int, testarrayofbools: Boolean) : Boolean { fun mutateTestarrayofbools(j: Int, testarrayofbools: Boolean) : Boolean {
val o = __offset(52) val o = __offset(52)
return if (o != 0) { return if (o != 0) {
@@ -469,8 +469,8 @@ class Monster : Table() {
get() { get() {
val o = __offset(64); return if (o != 0) __vector_len(o) else 0 val o = __offset(64); return if (o != 0) __vector_len(o) else 0
} }
val flexAsByteBuffer : ByteBuffer get() = __vector_as_bytebuffer(64, 1) val flexAsByteBuffer : ByteBuffer? get() = __vector_as_bytebuffer(64, 1)
fun flexInByteBuffer(_bb: ByteBuffer) : ByteBuffer = __vector_in_bytebuffer(_bb, 64, 1) fun flexInByteBuffer(_bb: ByteBuffer) : ByteBuffer? = __vector_in_bytebuffer(_bb, 64, 1)
fun mutateFlex(j: Int, flex: UByte) : Boolean { fun mutateFlex(j: Int, flex: UByte) : Boolean {
val o = __offset(64) val o = __offset(64)
return if (o != 0) { return if (o != 0) {
@@ -505,8 +505,8 @@ class Monster : Table() {
get() { get() {
val o = __offset(68); return if (o != 0) __vector_len(o) else 0 val o = __offset(68); return if (o != 0) __vector_len(o) else 0
} }
val vectorOfLongsAsByteBuffer : ByteBuffer get() = __vector_as_bytebuffer(68, 8) val vectorOfLongsAsByteBuffer : ByteBuffer? get() = __vector_as_bytebuffer(68, 8)
fun vectorOfLongsInByteBuffer(_bb: ByteBuffer) : ByteBuffer = __vector_in_bytebuffer(_bb, 68, 8) fun vectorOfLongsInByteBuffer(_bb: ByteBuffer) : ByteBuffer? = __vector_in_bytebuffer(_bb, 68, 8)
fun mutateVectorOfLongs(j: Int, vectorOfLongs: Long) : Boolean { fun mutateVectorOfLongs(j: Int, vectorOfLongs: Long) : Boolean {
val o = __offset(68) val o = __offset(68)
return if (o != 0) { return if (o != 0) {
@@ -528,8 +528,8 @@ class Monster : Table() {
get() { get() {
val o = __offset(70); return if (o != 0) __vector_len(o) else 0 val o = __offset(70); return if (o != 0) __vector_len(o) else 0
} }
val vectorOfDoublesAsByteBuffer : ByteBuffer get() = __vector_as_bytebuffer(70, 8) val vectorOfDoublesAsByteBuffer : ByteBuffer? get() = __vector_as_bytebuffer(70, 8)
fun vectorOfDoublesInByteBuffer(_bb: ByteBuffer) : ByteBuffer = __vector_in_bytebuffer(_bb, 70, 8) fun vectorOfDoublesInByteBuffer(_bb: ByteBuffer) : ByteBuffer? = __vector_in_bytebuffer(_bb, 70, 8)
fun mutateVectorOfDoubles(j: Int, vectorOfDoubles: Double) : Boolean { fun mutateVectorOfDoubles(j: Int, vectorOfDoubles: Double) : Boolean {
val o = __offset(70) val o = __offset(70)
return if (o != 0) { return if (o != 0) {
@@ -603,8 +603,8 @@ class Monster : Table() {
get() { get() {
val o = __offset(78); return if (o != 0) __vector_len(o) else 0 val o = __offset(78); return if (o != 0) __vector_len(o) else 0
} }
val vectorOfWeakReferencesAsByteBuffer : ByteBuffer get() = __vector_as_bytebuffer(78, 8) val vectorOfWeakReferencesAsByteBuffer : ByteBuffer? get() = __vector_as_bytebuffer(78, 8)
fun vectorOfWeakReferencesInByteBuffer(_bb: ByteBuffer) : ByteBuffer = __vector_in_bytebuffer(_bb, 78, 8) fun vectorOfWeakReferencesInByteBuffer(_bb: ByteBuffer) : ByteBuffer? = __vector_in_bytebuffer(_bb, 78, 8)
fun mutateVectorOfWeakReferences(j: Int, vectorOfWeakReferences: ULong) : Boolean { fun mutateVectorOfWeakReferences(j: Int, vectorOfWeakReferences: ULong) : Boolean {
val o = __offset(78) val o = __offset(78)
return if (o != 0) { return if (o != 0) {
@@ -669,8 +669,8 @@ class Monster : Table() {
get() { get() {
val o = __offset(84); return if (o != 0) __vector_len(o) else 0 val o = __offset(84); return if (o != 0) __vector_len(o) else 0
} }
val vectorOfCoOwningReferencesAsByteBuffer : ByteBuffer get() = __vector_as_bytebuffer(84, 8) val vectorOfCoOwningReferencesAsByteBuffer : ByteBuffer? get() = __vector_as_bytebuffer(84, 8)
fun vectorOfCoOwningReferencesInByteBuffer(_bb: ByteBuffer) : ByteBuffer = __vector_in_bytebuffer(_bb, 84, 8) fun vectorOfCoOwningReferencesInByteBuffer(_bb: ByteBuffer) : ByteBuffer? = __vector_in_bytebuffer(_bb, 84, 8)
fun mutateVectorOfCoOwningReferences(j: Int, vectorOfCoOwningReferences: ULong) : Boolean { fun mutateVectorOfCoOwningReferences(j: Int, vectorOfCoOwningReferences: ULong) : Boolean {
val o = __offset(84) val o = __offset(84)
return if (o != 0) { return if (o != 0) {
@@ -706,8 +706,8 @@ class Monster : Table() {
get() { get() {
val o = __offset(88); return if (o != 0) __vector_len(o) else 0 val o = __offset(88); return if (o != 0) __vector_len(o) else 0
} }
val vectorOfNonOwningReferencesAsByteBuffer : ByteBuffer get() = __vector_as_bytebuffer(88, 8) val vectorOfNonOwningReferencesAsByteBuffer : ByteBuffer? get() = __vector_as_bytebuffer(88, 8)
fun vectorOfNonOwningReferencesInByteBuffer(_bb: ByteBuffer) : ByteBuffer = __vector_in_bytebuffer(_bb, 88, 8) fun vectorOfNonOwningReferencesInByteBuffer(_bb: ByteBuffer) : ByteBuffer? = __vector_in_bytebuffer(_bb, 88, 8)
fun mutateVectorOfNonOwningReferences(j: Int, vectorOfNonOwningReferences: ULong) : Boolean { fun mutateVectorOfNonOwningReferences(j: Int, vectorOfNonOwningReferences: ULong) : Boolean {
val o = __offset(88) val o = __offset(88)
return if (o != 0) { return if (o != 0) {
@@ -763,8 +763,8 @@ class Monster : Table() {
get() { get() {
val o = __offset(98); return if (o != 0) __vector_len(o) else 0 val o = __offset(98); return if (o != 0) __vector_len(o) else 0
} }
val vectorOfEnumsAsByteBuffer : ByteBuffer get() = __vector_as_bytebuffer(98, 1) val vectorOfEnumsAsByteBuffer : ByteBuffer? get() = __vector_as_bytebuffer(98, 1)
fun vectorOfEnumsInByteBuffer(_bb: ByteBuffer) : ByteBuffer = __vector_in_bytebuffer(_bb, 98, 1) fun vectorOfEnumsInByteBuffer(_bb: ByteBuffer) : ByteBuffer? = __vector_in_bytebuffer(_bb, 98, 1)
fun mutateVectorOfEnums(j: Int, vectorOfEnums: UByte) : Boolean { fun mutateVectorOfEnums(j: Int, vectorOfEnums: UByte) : Boolean {
val o = __offset(98) val o = __offset(98)
return if (o != 0) { return if (o != 0) {
@@ -800,8 +800,8 @@ class Monster : Table() {
get() { get() {
val o = __offset(102); return if (o != 0) __vector_len(o) else 0 val o = __offset(102); return if (o != 0) __vector_len(o) else 0
} }
val testrequirednestedflatbufferAsByteBuffer : ByteBuffer get() = __vector_as_bytebuffer(102, 1) val testrequirednestedflatbufferAsByteBuffer : ByteBuffer? get() = __vector_as_bytebuffer(102, 1)
fun testrequirednestedflatbufferInByteBuffer(_bb: ByteBuffer) : ByteBuffer = __vector_in_bytebuffer(_bb, 102, 1) fun testrequirednestedflatbufferInByteBuffer(_bb: ByteBuffer) : ByteBuffer? = __vector_in_bytebuffer(_bb, 102, 1)
val testrequirednestedflatbufferAsMonster : MyGame.Example.Monster? get() = testrequirednestedflatbufferAsMonster(MyGame.Example.Monster()) val testrequirednestedflatbufferAsMonster : MyGame.Example.Monster? get() = testrequirednestedflatbufferAsMonster(MyGame.Example.Monster())
fun testrequirednestedflatbufferAsMonster(obj: MyGame.Example.Monster) : MyGame.Example.Monster? { fun testrequirednestedflatbufferAsMonster(obj: MyGame.Example.Monster) : MyGame.Example.Monster? {
val o = __offset(102) val o = __offset(102)

View File

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

View File

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

View File

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

View File

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