Fix nullability of generated Kotlin ByteBuffer accessors (#8844)
* fixes #8691
diff --git a/src/idl_gen_kotlin.cpp b/src/idl_gen_kotlin.cpp
index 2ed89d4..9101a91 100644
--- a/src/idl_gen_kotlin.cpp
+++ b/src/idl_gen_kotlin.cpp
@@ -1201,11 +1201,12 @@
: 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 @@
// 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}})";
});
diff --git a/tests/KotlinTest.kt b/tests/KotlinTest.kt
index b9ee393..94e7496 100644
--- a/tests/KotlinTest.kt
+++ b/tests/KotlinTest.kt
@@ -80,6 +80,7 @@
TestSharedStringPool()
TestScalarOptional()
TestDictionaryLookup()
+ TestNullFields()
println("FlatBuffers test: completed successfully")
}
@@ -142,7 +143,7 @@
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 @@
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)
+ }
}
}
diff --git a/tests/MyGame/Example/Monster.kt b/tests/MyGame/Example/Monster.kt
index 9dfdc30..4e10a8a 100644
--- a/tests/MyGame/Example/Monster.kt
+++ b/tests/MyGame/Example/Monster.kt
@@ -91,8 +91,8 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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)
diff --git a/tests/MyGame/Example/Stat.kt b/tests/MyGame/Example/Stat.kt
index 26ee253..d7bc296 100644
--- a/tests/MyGame/Example/Stat.kt
+++ b/tests/MyGame/Example/Stat.kt
@@ -37,8 +37,8 @@
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)
diff --git a/tests/MyGame/Example/TypeAliases.kt b/tests/MyGame/Example/TypeAliases.kt
index d73f78b..b00eb54 100644
--- a/tests/MyGame/Example/TypeAliases.kt
+++ b/tests/MyGame/Example/TypeAliases.kt
@@ -180,8 +180,8 @@
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 @@
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) {
diff --git a/tests/MyGame/MonsterExtra.kt b/tests/MyGame/MonsterExtra.kt
index d8c8d15..e38abc2 100644
--- a/tests/MyGame/MonsterExtra.kt
+++ b/tests/MyGame/MonsterExtra.kt
@@ -152,8 +152,8 @@
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 @@
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) {
diff --git a/tests/union_vector/Movie.kt b/tests/union_vector/Movie.kt
index 0e8645d..aa04ad5 100644
--- a/tests/union_vector/Movie.kt
+++ b/tests/union_vector/Movie.kt
@@ -55,8 +55,8 @@
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) {