Skip to content

Commit 60910fb

Browse files
authored
Fix nullability of generated Kotlin ByteBuffer accessors (google#8844)
* fixes google#8691
1 parent 7bfaabc commit 60910fb

File tree

7 files changed

+73
-39
lines changed

7 files changed

+73
-39
lines changed

src/idl_gen_kotlin.cpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1201,22 +1201,23 @@ class KotlinGenerator : public BaseGenerator {
12011201
: InlineSize(field.value.type.VectorType()));
12021202
// Generate a ByteBuffer accessor for strings & vectors of scalars.
12031203
// e.g.
1204-
// val inventoryByteBuffer: ByteBuffer
1204+
// val inventoryByteBuffer: ByteBuffer?
12051205
// get = __vector_as_bytebuffer(14, 1)
12061206

1207+
auto buffer_type = field.IsRequired() ? "ByteBuffer" : "ByteBuffer?";
12071208
GenerateGetterOneLine(
1208-
writer, field_name + "AsByteBuffer", "ByteBuffer", [&]() {
1209+
writer, field_name + "AsByteBuffer", buffer_type, [&]() {
12091210
writer.SetValue("end", end_idx);
12101211
writer += "__vector_as_bytebuffer({{offset}}, {{end}})";
12111212
});
12121213

12131214
// Generate a ByteBuffer accessor for strings & vectors of scalars.
12141215
// e.g.
12151216
// fun inventoryInByteBuffer(_bb: Bytebuffer):
1216-
// ByteBuffer = __vector_as_bytebuffer(_bb, 14, 1)
1217+
// ByteBuffer? = __vector_as_bytebuffer(_bb, 14, 1)
12171218
GenerateFunOneLine(
12181219
writer, field_name + "InByteBuffer", "_bb: ByteBuffer",
1219-
"ByteBuffer", [&]() {
1220+
buffer_type, [&]() {
12201221
writer.SetValue("end", end_idx);
12211222
writer += "__vector_in_bytebuffer(_bb, {{offset}}, {{end}})";
12221223
});

tests/KotlinTest.kt

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ class KotlinTest {
8080
TestSharedStringPool()
8181
TestScalarOptional()
8282
TestDictionaryLookup()
83+
TestNullFields()
8384
println("FlatBuffers test: completed successfully")
8485
}
8586

@@ -142,7 +143,7 @@ class KotlinTest {
142143
assert(invsum == 10u)
143144

144145
// Alternative way of accessing a vector:
145-
val ibb = monster.inventoryAsByteBuffer
146+
val ibb = monster.inventoryAsByteBuffer!!
146147
invsum = 0u
147148
while (ibb.position() < ibb.limit()) invsum += ibb.get().toUInt()
148149
assert(invsum == 10u)
@@ -615,5 +616,37 @@ class KotlinTest {
615616
assert(scalarStuff.maybeEnum == OptionalByte.Two)
616617
assert(scalarStuff.defaultEnum == OptionalByte.Two)
617618
}
619+
620+
fun TestNullFields() {
621+
val fbb = FlatBufferBuilder(1)
622+
val nameOffset = fbb.createString("name")
623+
Monster.startMonster(fbb)
624+
Monster.addName(fbb, nameOffset)
625+
Monster.finishMonsterBuffer(fbb, Monster.endMonster(fbb))
626+
627+
val monsterBb = fbb.dataBuffer()
628+
val monster = Monster.getRootAsMonster(monsterBb.duplicate())
629+
assert(monster.pos == null) // struct
630+
assert(monster.enemy == null) // table
631+
assert(monster.test(Monster()) == null) // union
632+
assert(monster.testType == Any_.NONE)
633+
assert(monster.inventoryLength == 0) // vector of scalars
634+
assert(monster.inventoryAsByteBuffer == null)
635+
assert(monster.inventoryInByteBuffer(monsterBb) == null)
636+
assert(monster.testarrayofsortedstructLength == 0) // vector of structs
637+
assert(monster.testarrayofstringLength == 0) // vector of strings
638+
assert(monster.testarrayoftablesLength == 0) // vector of tables
639+
640+
641+
val fbb2 = FlatBufferBuilder(1)
642+
val offset = Stat.createStat(fbb2, 0, 10, 10.toUShort())
643+
fbb2.finish(offset)
644+
645+
val statBb = fbb2.dataBuffer()
646+
val stat = Stat.getRootAsStat(statBb.duplicate())
647+
assert(stat.id == null) // string
648+
assert(stat.idAsByteBuffer == null)
649+
assert(stat.idInByteBuffer(statBb) == null)
650+
}
618651
}
619652
}

tests/MyGame/Example/Monster.kt

Lines changed: 22 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -91,8 +91,8 @@ class Monster : Table() {
9191
get() {
9292
val o = __offset(14); return if (o != 0) __vector_len(o) else 0
9393
}
94-
val inventoryAsByteBuffer : ByteBuffer get() = __vector_as_bytebuffer(14, 1)
95-
fun inventoryInByteBuffer(_bb: ByteBuffer) : ByteBuffer = __vector_in_bytebuffer(_bb, 14, 1)
94+
val inventoryAsByteBuffer : ByteBuffer? get() = __vector_as_bytebuffer(14, 1)
95+
fun inventoryInByteBuffer(_bb: ByteBuffer) : ByteBuffer? = __vector_in_bytebuffer(_bb, 14, 1)
9696
fun mutateInventory(j: Int, inventory: UByte) : Boolean {
9797
val o = __offset(14)
9898
return if (o != 0) {
@@ -212,8 +212,8 @@ class Monster : Table() {
212212
get() {
213213
val o = __offset(30); return if (o != 0) __vector_len(o) else 0
214214
}
215-
val testnestedflatbufferAsByteBuffer : ByteBuffer get() = __vector_as_bytebuffer(30, 1)
216-
fun testnestedflatbufferInByteBuffer(_bb: ByteBuffer) : ByteBuffer = __vector_in_bytebuffer(_bb, 30, 1)
215+
val testnestedflatbufferAsByteBuffer : ByteBuffer? get() = __vector_as_bytebuffer(30, 1)
216+
fun testnestedflatbufferInByteBuffer(_bb: ByteBuffer) : ByteBuffer? = __vector_in_bytebuffer(_bb, 30, 1)
217217
val testnestedflatbufferAsMonster : MyGame.Example.Monster? get() = testnestedflatbufferAsMonster(MyGame.Example.Monster())
218218
fun testnestedflatbufferAsMonster(obj: MyGame.Example.Monster) : MyGame.Example.Monster? {
219219
val o = __offset(30)
@@ -379,8 +379,8 @@ class Monster : Table() {
379379
get() {
380380
val o = __offset(52); return if (o != 0) __vector_len(o) else 0
381381
}
382-
val testarrayofboolsAsByteBuffer : ByteBuffer get() = __vector_as_bytebuffer(52, 1)
383-
fun testarrayofboolsInByteBuffer(_bb: ByteBuffer) : ByteBuffer = __vector_in_bytebuffer(_bb, 52, 1)
382+
val testarrayofboolsAsByteBuffer : ByteBuffer? get() = __vector_as_bytebuffer(52, 1)
383+
fun testarrayofboolsInByteBuffer(_bb: ByteBuffer) : ByteBuffer? = __vector_in_bytebuffer(_bb, 52, 1)
384384
fun mutateTestarrayofbools(j: Int, testarrayofbools: Boolean) : Boolean {
385385
val o = __offset(52)
386386
return if (o != 0) {
@@ -469,8 +469,8 @@ class Monster : Table() {
469469
get() {
470470
val o = __offset(64); return if (o != 0) __vector_len(o) else 0
471471
}
472-
val flexAsByteBuffer : ByteBuffer get() = __vector_as_bytebuffer(64, 1)
473-
fun flexInByteBuffer(_bb: ByteBuffer) : ByteBuffer = __vector_in_bytebuffer(_bb, 64, 1)
472+
val flexAsByteBuffer : ByteBuffer? get() = __vector_as_bytebuffer(64, 1)
473+
fun flexInByteBuffer(_bb: ByteBuffer) : ByteBuffer? = __vector_in_bytebuffer(_bb, 64, 1)
474474
fun mutateFlex(j: Int, flex: UByte) : Boolean {
475475
val o = __offset(64)
476476
return if (o != 0) {
@@ -505,8 +505,8 @@ class Monster : Table() {
505505
get() {
506506
val o = __offset(68); return if (o != 0) __vector_len(o) else 0
507507
}
508-
val vectorOfLongsAsByteBuffer : ByteBuffer get() = __vector_as_bytebuffer(68, 8)
509-
fun vectorOfLongsInByteBuffer(_bb: ByteBuffer) : ByteBuffer = __vector_in_bytebuffer(_bb, 68, 8)
508+
val vectorOfLongsAsByteBuffer : ByteBuffer? get() = __vector_as_bytebuffer(68, 8)
509+
fun vectorOfLongsInByteBuffer(_bb: ByteBuffer) : ByteBuffer? = __vector_in_bytebuffer(_bb, 68, 8)
510510
fun mutateVectorOfLongs(j: Int, vectorOfLongs: Long) : Boolean {
511511
val o = __offset(68)
512512
return if (o != 0) {
@@ -528,8 +528,8 @@ class Monster : Table() {
528528
get() {
529529
val o = __offset(70); return if (o != 0) __vector_len(o) else 0
530530
}
531-
val vectorOfDoublesAsByteBuffer : ByteBuffer get() = __vector_as_bytebuffer(70, 8)
532-
fun vectorOfDoublesInByteBuffer(_bb: ByteBuffer) : ByteBuffer = __vector_in_bytebuffer(_bb, 70, 8)
531+
val vectorOfDoublesAsByteBuffer : ByteBuffer? get() = __vector_as_bytebuffer(70, 8)
532+
fun vectorOfDoublesInByteBuffer(_bb: ByteBuffer) : ByteBuffer? = __vector_in_bytebuffer(_bb, 70, 8)
533533
fun mutateVectorOfDoubles(j: Int, vectorOfDoubles: Double) : Boolean {
534534
val o = __offset(70)
535535
return if (o != 0) {
@@ -603,8 +603,8 @@ class Monster : Table() {
603603
get() {
604604
val o = __offset(78); return if (o != 0) __vector_len(o) else 0
605605
}
606-
val vectorOfWeakReferencesAsByteBuffer : ByteBuffer get() = __vector_as_bytebuffer(78, 8)
607-
fun vectorOfWeakReferencesInByteBuffer(_bb: ByteBuffer) : ByteBuffer = __vector_in_bytebuffer(_bb, 78, 8)
606+
val vectorOfWeakReferencesAsByteBuffer : ByteBuffer? get() = __vector_as_bytebuffer(78, 8)
607+
fun vectorOfWeakReferencesInByteBuffer(_bb: ByteBuffer) : ByteBuffer? = __vector_in_bytebuffer(_bb, 78, 8)
608608
fun mutateVectorOfWeakReferences(j: Int, vectorOfWeakReferences: ULong) : Boolean {
609609
val o = __offset(78)
610610
return if (o != 0) {
@@ -669,8 +669,8 @@ class Monster : Table() {
669669
get() {
670670
val o = __offset(84); return if (o != 0) __vector_len(o) else 0
671671
}
672-
val vectorOfCoOwningReferencesAsByteBuffer : ByteBuffer get() = __vector_as_bytebuffer(84, 8)
673-
fun vectorOfCoOwningReferencesInByteBuffer(_bb: ByteBuffer) : ByteBuffer = __vector_in_bytebuffer(_bb, 84, 8)
672+
val vectorOfCoOwningReferencesAsByteBuffer : ByteBuffer? get() = __vector_as_bytebuffer(84, 8)
673+
fun vectorOfCoOwningReferencesInByteBuffer(_bb: ByteBuffer) : ByteBuffer? = __vector_in_bytebuffer(_bb, 84, 8)
674674
fun mutateVectorOfCoOwningReferences(j: Int, vectorOfCoOwningReferences: ULong) : Boolean {
675675
val o = __offset(84)
676676
return if (o != 0) {
@@ -706,8 +706,8 @@ class Monster : Table() {
706706
get() {
707707
val o = __offset(88); return if (o != 0) __vector_len(o) else 0
708708
}
709-
val vectorOfNonOwningReferencesAsByteBuffer : ByteBuffer get() = __vector_as_bytebuffer(88, 8)
710-
fun vectorOfNonOwningReferencesInByteBuffer(_bb: ByteBuffer) : ByteBuffer = __vector_in_bytebuffer(_bb, 88, 8)
709+
val vectorOfNonOwningReferencesAsByteBuffer : ByteBuffer? get() = __vector_as_bytebuffer(88, 8)
710+
fun vectorOfNonOwningReferencesInByteBuffer(_bb: ByteBuffer) : ByteBuffer? = __vector_in_bytebuffer(_bb, 88, 8)
711711
fun mutateVectorOfNonOwningReferences(j: Int, vectorOfNonOwningReferences: ULong) : Boolean {
712712
val o = __offset(88)
713713
return if (o != 0) {
@@ -763,8 +763,8 @@ class Monster : Table() {
763763
get() {
764764
val o = __offset(98); return if (o != 0) __vector_len(o) else 0
765765
}
766-
val vectorOfEnumsAsByteBuffer : ByteBuffer get() = __vector_as_bytebuffer(98, 1)
767-
fun vectorOfEnumsInByteBuffer(_bb: ByteBuffer) : ByteBuffer = __vector_in_bytebuffer(_bb, 98, 1)
766+
val vectorOfEnumsAsByteBuffer : ByteBuffer? get() = __vector_as_bytebuffer(98, 1)
767+
fun vectorOfEnumsInByteBuffer(_bb: ByteBuffer) : ByteBuffer? = __vector_in_bytebuffer(_bb, 98, 1)
768768
fun mutateVectorOfEnums(j: Int, vectorOfEnums: UByte) : Boolean {
769769
val o = __offset(98)
770770
return if (o != 0) {
@@ -800,8 +800,8 @@ class Monster : Table() {
800800
get() {
801801
val o = __offset(102); return if (o != 0) __vector_len(o) else 0
802802
}
803-
val testrequirednestedflatbufferAsByteBuffer : ByteBuffer get() = __vector_as_bytebuffer(102, 1)
804-
fun testrequirednestedflatbufferInByteBuffer(_bb: ByteBuffer) : ByteBuffer = __vector_in_bytebuffer(_bb, 102, 1)
803+
val testrequirednestedflatbufferAsByteBuffer : ByteBuffer? get() = __vector_as_bytebuffer(102, 1)
804+
fun testrequirednestedflatbufferInByteBuffer(_bb: ByteBuffer) : ByteBuffer? = __vector_in_bytebuffer(_bb, 102, 1)
805805
val testrequirednestedflatbufferAsMonster : MyGame.Example.Monster? get() = testrequirednestedflatbufferAsMonster(MyGame.Example.Monster())
806806
fun testrequirednestedflatbufferAsMonster(obj: MyGame.Example.Monster) : MyGame.Example.Monster? {
807807
val o = __offset(102)

tests/MyGame/Example/Stat.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,8 @@ class Stat : Table() {
3737
null
3838
}
3939
}
40-
val idAsByteBuffer : ByteBuffer get() = __vector_as_bytebuffer(4, 1)
41-
fun idInByteBuffer(_bb: ByteBuffer) : ByteBuffer = __vector_in_bytebuffer(_bb, 4, 1)
40+
val idAsByteBuffer : ByteBuffer? get() = __vector_as_bytebuffer(4, 1)
41+
fun idInByteBuffer(_bb: ByteBuffer) : ByteBuffer? = __vector_in_bytebuffer(_bb, 4, 1)
4242
val val_ : Long
4343
get() {
4444
val o = __offset(6)

tests/MyGame/Example/TypeAliases.kt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -180,8 +180,8 @@ class TypeAliases : Table() {
180180
get() {
181181
val o = __offset(24); return if (o != 0) __vector_len(o) else 0
182182
}
183-
val v8AsByteBuffer : ByteBuffer get() = __vector_as_bytebuffer(24, 1)
184-
fun v8InByteBuffer(_bb: ByteBuffer) : ByteBuffer = __vector_in_bytebuffer(_bb, 24, 1)
183+
val v8AsByteBuffer : ByteBuffer? get() = __vector_as_bytebuffer(24, 1)
184+
fun v8InByteBuffer(_bb: ByteBuffer) : ByteBuffer? = __vector_in_bytebuffer(_bb, 24, 1)
185185
fun mutateV8(j: Int, v8: Byte) : Boolean {
186186
val o = __offset(24)
187187
return if (o != 0) {
@@ -203,8 +203,8 @@ class TypeAliases : Table() {
203203
get() {
204204
val o = __offset(26); return if (o != 0) __vector_len(o) else 0
205205
}
206-
val vf64AsByteBuffer : ByteBuffer get() = __vector_as_bytebuffer(26, 8)
207-
fun vf64InByteBuffer(_bb: ByteBuffer) : ByteBuffer = __vector_in_bytebuffer(_bb, 26, 8)
206+
val vf64AsByteBuffer : ByteBuffer? get() = __vector_as_bytebuffer(26, 8)
207+
fun vf64InByteBuffer(_bb: ByteBuffer) : ByteBuffer? = __vector_in_bytebuffer(_bb, 26, 8)
208208
fun mutateVf64(j: Int, vf64: Double) : Boolean {
209209
val o = __offset(26)
210210
return if (o != 0) {

tests/MyGame/MonsterExtra.kt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -152,8 +152,8 @@ class MonsterExtra : Table() {
152152
get() {
153153
val o = __offset(20); return if (o != 0) __vector_len(o) else 0
154154
}
155-
val dvecAsByteBuffer : ByteBuffer get() = __vector_as_bytebuffer(20, 8)
156-
fun dvecInByteBuffer(_bb: ByteBuffer) : ByteBuffer = __vector_in_bytebuffer(_bb, 20, 8)
155+
val dvecAsByteBuffer : ByteBuffer? get() = __vector_as_bytebuffer(20, 8)
156+
fun dvecInByteBuffer(_bb: ByteBuffer) : ByteBuffer? = __vector_in_bytebuffer(_bb, 20, 8)
157157
fun mutateDvec(j: Int, dvec: Double) : Boolean {
158158
val o = __offset(20)
159159
return if (o != 0) {
@@ -175,8 +175,8 @@ class MonsterExtra : Table() {
175175
get() {
176176
val o = __offset(22); return if (o != 0) __vector_len(o) else 0
177177
}
178-
val fvecAsByteBuffer : ByteBuffer get() = __vector_as_bytebuffer(22, 4)
179-
fun fvecInByteBuffer(_bb: ByteBuffer) : ByteBuffer = __vector_in_bytebuffer(_bb, 22, 4)
178+
val fvecAsByteBuffer : ByteBuffer? get() = __vector_as_bytebuffer(22, 4)
179+
fun fvecInByteBuffer(_bb: ByteBuffer) : ByteBuffer? = __vector_in_bytebuffer(_bb, 22, 4)
180180
fun mutateFvec(j: Int, fvec: Float) : Boolean {
181181
val o = __offset(22)
182182
return if (o != 0) {

tests/union_vector/Movie.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,8 +55,8 @@ class Movie : Table() {
5555
get() {
5656
val o = __offset(8); return if (o != 0) __vector_len(o) else 0
5757
}
58-
val charactersTypeAsByteBuffer : ByteBuffer get() = __vector_as_bytebuffer(8, 1)
59-
fun charactersTypeInByteBuffer(_bb: ByteBuffer) : ByteBuffer = __vector_in_bytebuffer(_bb, 8, 1)
58+
val charactersTypeAsByteBuffer : ByteBuffer? get() = __vector_as_bytebuffer(8, 1)
59+
fun charactersTypeInByteBuffer(_bb: ByteBuffer) : ByteBuffer? = __vector_in_bytebuffer(_bb, 8, 1)
6060
fun mutateCharactersType(j: Int, charactersType: UByte) : Boolean {
6161
val o = __offset(8)
6262
return if (o != 0) {

0 commit comments

Comments
 (0)