summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaulo Pinheiro <paulovictor.pinheiro@gmail.com>2020-09-18 08:31:51 +0200
committerGitHub <noreply@github.com>2020-09-17 23:31:51 -0700
commit6228b66d3d1f0e5d2f79e59834c8931d84cccaaf (patch)
tree1041ed8d6988029363aedca21be37c1a91bdc2bb
parente1be8aaadd773e9ac608d7ad9b6a2f691699cdb3 (diff)
downloadflatbuffers-6228b66d3d1f0e5d2f79e59834c8931d84cccaaf.tar.gz
flatbuffers-6228b66d3d1f0e5d2f79e59834c8931d84cccaaf.tar.bz2
flatbuffers-6228b66d3d1f0e5d2f79e59834c8931d84cccaaf.zip
[Kotlin] Support for optional scalars. (#6115)
More information on #6014
-rw-r--r--include/flatbuffers/idl.h4
-rw-r--r--src/idl_gen_kotlin.cpp95
-rw-r--r--src/idl_parser.cpp3
-rw-r--r--tests/KotlinTest.kt123
-rwxr-xr-xtests/generate_code.sh2
-rw-r--r--tests/optional_scalars/ScalarStuff.kt268
-rw-r--r--tests/test.cpp1
7 files changed, 464 insertions, 32 deletions
diff --git a/include/flatbuffers/idl.h b/include/flatbuffers/idl.h
index 6b0de14a..a361c653 100644
--- a/include/flatbuffers/idl.h
+++ b/include/flatbuffers/idl.h
@@ -305,6 +305,10 @@ struct FieldDef : public Definition {
bool Deserialize(Parser &parser, const reflection::Field *field);
+ bool IsScalarOptional() const {
+ return IsScalar(value.type.base_type) && optional;
+ }
+
Value value;
bool deprecated; // Field is allowed to be present in old data, but can't be.
// written in new data nor accessed in new code.
diff --git a/src/idl_gen_kotlin.cpp b/src/idl_gen_kotlin.cpp
index 2c0c8d43..79913f54 100644
--- a/src/idl_gen_kotlin.cpp
+++ b/src/idl_gen_kotlin.cpp
@@ -159,6 +159,24 @@ class KotlinGenerator : public BaseGenerator {
}
}
+ // with the addition of optional scalar types,
+ // we are adding the nullable '?' operator to return type of a field.
+ std::string GetterReturnType(const FieldDef &field) const {
+ auto base_type = field.value.type.base_type;
+
+ auto r_type = GenTypeGet(field.value.type);
+ if (field.IsScalarOptional() ||
+ // string, structs and unions
+ (base_type == BASE_TYPE_STRING || base_type == BASE_TYPE_STRUCT ||
+ base_type == BASE_TYPE_UNION) ||
+ // vector of anything not scalar
+ (base_type == BASE_TYPE_VECTOR &&
+ !IsScalar(field.value.type.VectorType().base_type))) {
+ r_type += "?";
+ }
+ return r_type;
+ }
+
std::string GenTypeGet(const Type &type) const {
return IsScalar(type.base_type) ? GenTypeBasic(type.base_type)
: GenTypePointer(type);
@@ -179,6 +197,18 @@ class KotlinGenerator : public BaseGenerator {
// - Floats are upcasted to doubles
// - Unsigned are casted to signed
std::string GenFBBDefaultValue(const FieldDef &field) const {
+ if (field.IsScalarOptional()) {
+ // although default value is null, java API forces us to present a real
+ // default value for scalars, while adding a field to the buffer. This is
+ // not a problem because the default can be representing just by not
+ // calling builder.addMyField()
+ switch (field.value.type.base_type) {
+ case BASE_TYPE_DOUBLE:
+ case BASE_TYPE_FLOAT: return "0.0";
+ case BASE_TYPE_BOOL: return "false";
+ default: return "0";
+ }
+ }
auto out = GenDefaultValue(field, true);
// All FlatBufferBuilder default floating point values are doubles
if (field.value.type.base_type == BASE_TYPE_FLOAT) {
@@ -204,6 +234,8 @@ class KotlinGenerator : public BaseGenerator {
bool force_signed = false) const {
auto &value = field.value;
auto base_type = field.value.type.base_type;
+
+ if (field.IsScalarOptional()) { return "null"; }
if (IsFloat(base_type)) {
auto val = KotlinFloatGen.GenFloatConstant(field);
if (base_type == BASE_TYPE_DOUBLE && val.back() == 'f') {
@@ -655,19 +687,22 @@ class KotlinGenerator : public BaseGenerator {
CodeWriter &writer, const IDLOptions options) const {
auto field_type = GenTypeBasic(field.value.type.base_type);
auto secondArg = MakeCamel(Esc(field.name), false) + ": " + field_type;
- GenerateFunOneLine(writer, "add" + MakeCamel(Esc(field.name), true),
- "builder: FlatBufferBuilder, " + secondArg, "", [&]() {
- auto method = GenMethod(field.value.type);
- writer.SetValue("field_name",
- MakeCamel(Esc(field.name), false));
- writer.SetValue("method_name", method);
- writer.SetValue("pos", field_pos);
- writer.SetValue("default", GenFBBDefaultValue(field));
- writer.SetValue("cast", GenFBBValueCast(field));
-
- writer += "builder.add{{method_name}}({{pos}}, \\";
- writer += "{{field_name}}{{cast}}, {{default}})";
- }, options.gen_jvmstatic);
+
+ GenerateFunOneLine(
+ writer, "add" + MakeCamel(Esc(field.name), true),
+ "builder: FlatBufferBuilder, " + secondArg, "",
+ [&]() {
+ auto method = GenMethod(field.value.type);
+ writer.SetValue("field_name", MakeCamel(Esc(field.name), false));
+ writer.SetValue("method_name", method);
+ writer.SetValue("pos", field_pos);
+ writer.SetValue("default", GenFBBDefaultValue(field));
+ writer.SetValue("cast", GenFBBValueCast(field));
+
+ writer += "builder.add{{method_name}}({{pos}}, \\";
+ writer += "{{field_name}}{{cast}}, {{default}})";
+ },
+ options.gen_jvmstatic);
}
static std::string ToSignedType(const Type &type) {
@@ -754,7 +789,8 @@ class KotlinGenerator : public BaseGenerator {
} else {
params << ": ";
}
- params << GenTypeBasic(field.value.type.base_type);
+ auto optional = field.IsScalarOptional() ? "?" : "";
+ params << GenTypeBasic(field.value.type.base_type) << optional;
}
GenerateFun(writer, name, params.str(), "Int", [&]() {
@@ -773,11 +809,16 @@ class KotlinGenerator : public BaseGenerator {
MakeCamel(Esc(field.name), true));
writer.SetValue("field_name", MakeCamel(Esc(field.name), false));
+ // we wrap on null check for scalar optionals
+ writer +=
+ field.IsScalarOptional() ? "{{field_name}}?.run { \\" : "\\";
+
writer += "add{{camel_field_name}}(builder, {{field_name}}\\";
if (!IsScalar(field.value.type.base_type)) {
writer += "Offset\\";
}
- writer += ")";
+ // we wrap on null check for scalar optionals
+ writer += field.IsScalarOptional() ? ") }" : ")";
}
}
}
@@ -812,7 +853,7 @@ class KotlinGenerator : public BaseGenerator {
auto field_name = MakeCamel(Esc(field.name), false);
auto field_type = GenTypeGet(field.value.type);
auto field_default_value = GenDefaultValue(field);
- auto return_type = GenTypeGet(field.value.type);
+ auto return_type = GetterReturnType(field);
auto bbgetter = ByteBufferGetter(field.value.type, "bb");
auto ucast = CastToUsigned(field);
auto offset_val = NumToString(field.value.offset);
@@ -829,14 +870,13 @@ class KotlinGenerator : public BaseGenerator {
writer.SetValue("bbgetter", bbgetter);
writer.SetValue("ucast", ucast);
- auto opt_ret_type = return_type + "?";
// Generate the accessors that don't do object reuse.
if (value_base_type == BASE_TYPE_STRUCT) {
// Calls the accessor that takes an accessor object with a
// new object.
// val pos
// get() = pos(Vec3())
- GenerateGetterOneLine(writer, field_name, opt_ret_type, [&]() {
+ GenerateGetterOneLine(writer, field_name, return_type, [&]() {
writer += "{{field_name}}({{field_type}}())";
});
} else if (value_base_type == BASE_TYPE_VECTOR &&
@@ -844,8 +884,8 @@ class KotlinGenerator : public BaseGenerator {
// Accessors for vectors of structs also take accessor objects,
// this generates a variant without that argument.
// ex: fun weapons(j: Int) = weapons(Weapon(), j)
- GenerateFunOneLine(writer, field_name, "j: Int", opt_ret_type, [&]() {
- writer += "{{field_name}}({{return_type}}(), j)";
+ GenerateFunOneLine(writer, field_name, "j: Int", return_type, [&]() {
+ writer += "{{field_name}}({{field_type}}(), j)";
});
}
@@ -872,7 +912,7 @@ class KotlinGenerator : public BaseGenerator {
// fun pos(obj: Vec3) : Vec3? = obj.__assign(bb_pos + 4, bb)
// ? adds nullability annotation
GenerateFunOneLine(
- writer, field_name, "obj: " + field_type, return_type + "?",
+ writer, field_name, "obj: " + field_type, return_type,
[&]() { writer += "obj.__assign(bb_pos + {{offset}}, bb)"; });
} else {
// create getter with object reuse
@@ -887,8 +927,7 @@ class KotlinGenerator : public BaseGenerator {
// }
// ? adds nullability annotation
GenerateFun(
- writer, field_name, "obj: " + field_type, return_type + "?",
- [&]() {
+ writer, field_name, "obj: " + field_type, return_type, [&]() {
auto fixed = field.value.type.struct_def->fixed;
writer.SetValue("seek", Indirect("o + bb_pos", fixed));
@@ -908,7 +947,7 @@ class KotlinGenerator : public BaseGenerator {
// return if (o != 0) __string(o + bb_pos) else null
// }
// ? adds nullability annotation
- GenerateGetter(writer, field_name, return_type + "?", [&]() {
+ GenerateGetter(writer, field_name, return_type, [&]() {
writer += "val o = __offset({{offset}})";
writer += "return if (o != 0) __string(o + bb_pos) else null";
});
@@ -926,15 +965,13 @@ class KotlinGenerator : public BaseGenerator {
auto vectortype = field.value.type.VectorType();
std::string params = "j: Int";
- std::string nullable = IsScalar(vectortype.base_type) ? "" : "?";
if (vectortype.base_type == BASE_TYPE_STRUCT ||
vectortype.base_type == BASE_TYPE_UNION) {
params = "obj: " + field_type + ", j: Int";
}
- auto ret_type = return_type + nullable;
- GenerateFun(writer, field_name, params, ret_type, [&]() {
+ GenerateFun(writer, field_name, params, return_type, [&]() {
auto inline_size = NumToString(InlineSize(vectortype));
auto index = "__vector(o) + j * " + inline_size;
auto not_found = NotFoundReturn(field.value.type.element);
@@ -959,8 +996,8 @@ class KotlinGenerator : public BaseGenerator {
break;
}
case BASE_TYPE_UNION:
- GenerateFun(writer, field_name, "obj: " + field_type,
- return_type + "?", [&]() {
+ GenerateFun(writer, field_name, "obj: " + field_type, return_type,
+ [&]() {
writer += OffsetWrapperOneLine(
offset_val, bbgetter + "(obj, o + bb_pos)",
"null");
diff --git a/src/idl_parser.cpp b/src/idl_parser.cpp
index 90e07674..05b1b194 100644
--- a/src/idl_parser.cpp
+++ b/src/idl_parser.cpp
@@ -2263,7 +2263,8 @@ CheckedError Parser::CheckClash(std::vector<FieldDef *> &fields,
bool Parser::SupportsOptionalScalars() const {
return !(opts.lang_to_generate &
- ~(IDLOptions::kRust | IDLOptions::kSwift | IDLOptions::kLobster));
+ ~(IDLOptions::kRust | IDLOptions::kSwift | IDLOptions::kLobster |
+ IDLOptions::kKotlin));
}
bool Parser::SupportsAdvancedUnionFeatures() const {
diff --git a/tests/KotlinTest.kt b/tests/KotlinTest.kt
index 538ab466..cdbd299a 100644
--- a/tests/KotlinTest.kt
+++ b/tests/KotlinTest.kt
@@ -15,6 +15,7 @@
*/
import MyGame.Example.*
+import optional_scalars.*
import com.google.flatbuffers.ByteBufferUtil
import com.google.flatbuffers.FlatBufferBuilder
import NamespaceA.*
@@ -77,7 +78,7 @@ class KotlinTest {
TestVectorOfUnions()
TestSharedStringPool()
-
+ TestScalarOptional()
println("FlatBuffers test: completed successfully")
}
@@ -467,5 +468,125 @@ class KotlinTest {
assert(offset == fb.createSharedString(testString));
}
}
+
+ fun TestScalarOptional() {
+ val fbb = FlatBufferBuilder(1)
+ ScalarStuff.startScalarStuff(fbb)
+ var pos = ScalarStuff.endScalarStuff(fbb)
+ fbb.finish(pos)
+
+ var scalarStuff = ScalarStuff.getRootAsScalarStuff(fbb.dataBuffer())
+
+ assert(scalarStuff.justI8 == 0.toByte())
+ assert(scalarStuff.maybeI8 == null)
+ assert(scalarStuff.defaultI8 == 42.toByte())
+ assert(scalarStuff.justU8 == 0.toUByte())
+ assert(scalarStuff.maybeU8 == null)
+ assert(scalarStuff.defaultU8 == 42.toUByte())
+ assert(scalarStuff.justI16 == 0.toShort())
+ assert(scalarStuff.maybeI16 == null)
+ assert(scalarStuff.defaultI16 == 42.toShort())
+ assert(scalarStuff.justU16 == 0.toUShort())
+ assert(scalarStuff.maybeU16 == null)
+ assert(scalarStuff.defaultU16 == 42.toUShort())
+ assert(scalarStuff.justI32 == 0)
+ assert(scalarStuff.maybeI32 == null)
+ assert(scalarStuff.defaultI32 == 42)
+ assert(scalarStuff.justU32 == 0.toUInt())
+ assert(scalarStuff.maybeU32 == null)
+ assert(scalarStuff.defaultU32 == 42U)
+ assert(scalarStuff.justI64 == 0L)
+ assert(scalarStuff.maybeI64 == null)
+ assert(scalarStuff.defaultI64 == 42L)
+ assert(scalarStuff.justU64 == 0UL)
+ assert(scalarStuff.maybeU64 == null)
+ assert(scalarStuff.defaultU64 == 42UL)
+ assert(scalarStuff.justF32 == 0.0f)
+ assert(scalarStuff.maybeF32 == null)
+ assert(scalarStuff.defaultF32 == 42.0f)
+ assert(scalarStuff.justF64 == 0.0)
+ assert(scalarStuff.maybeF64 == null)
+ assert(scalarStuff.defaultF64 == 42.0)
+ assert(scalarStuff.justBool == false)
+ assert(scalarStuff.maybeBool == null)
+ assert(scalarStuff.defaultBool == true)
+
+ fbb.clear()
+
+ ScalarStuff.startScalarStuff(fbb)
+ ScalarStuff.addJustI8(fbb, 5.toByte())
+ ScalarStuff.addMaybeI8(fbb, 5.toByte())
+ ScalarStuff.addDefaultI8(fbb, 5.toByte())
+ ScalarStuff.addJustU8(fbb, 6.toUByte())
+ ScalarStuff.addMaybeU8(fbb, 6.toUByte())
+ ScalarStuff.addDefaultU8(fbb, 6.toUByte())
+ ScalarStuff.addJustI16(fbb, 7.toShort())
+ ScalarStuff.addMaybeI16(fbb, 7.toShort())
+ ScalarStuff.addDefaultI16(fbb, 7.toShort())
+ ScalarStuff.addJustU16(fbb, 8.toUShort())
+ ScalarStuff.addMaybeU16(fbb, 8.toUShort())
+ ScalarStuff.addDefaultU16(fbb, 8.toUShort())
+ ScalarStuff.addJustI32(fbb, 9)
+ ScalarStuff.addMaybeI32(fbb, 9)
+ ScalarStuff.addDefaultI32(fbb, 9)
+ ScalarStuff.addJustU32(fbb, 10.toUInt())
+ ScalarStuff.addMaybeU32(fbb, 10.toUInt())
+ ScalarStuff.addDefaultU32(fbb, 10.toUInt())
+ ScalarStuff.addJustI64(fbb, 11L)
+ ScalarStuff.addMaybeI64(fbb, 11L)
+ ScalarStuff.addDefaultI64(fbb, 11L)
+ ScalarStuff.addJustU64(fbb, 12UL)
+ ScalarStuff.addMaybeU64(fbb, 12UL)
+ ScalarStuff.addDefaultU64(fbb, 12UL)
+ ScalarStuff.addJustF32(fbb, 13.0f)
+ ScalarStuff.addMaybeF32(fbb, 13.0f)
+ ScalarStuff.addDefaultF32(fbb, 13.0f)
+ ScalarStuff.addJustF64(fbb, 14.0)
+ ScalarStuff.addMaybeF64(fbb, 14.0)
+ ScalarStuff.addDefaultF64(fbb, 14.0)
+ ScalarStuff.addJustBool(fbb, true)
+ ScalarStuff.addMaybeBool(fbb, true)
+ ScalarStuff.addDefaultBool(fbb, true)
+
+ pos = ScalarStuff.endScalarStuff(fbb)
+
+ fbb.finish(pos)
+
+ scalarStuff = ScalarStuff.getRootAsScalarStuff(fbb.dataBuffer())
+
+ assert(scalarStuff.justI8 == 5.toByte())
+ assert(scalarStuff.maybeI8 == 5.toByte())
+ assert(scalarStuff.defaultI8 == 5.toByte())
+ assert(scalarStuff.justU8 == 6.toUByte())
+ assert(scalarStuff.maybeU8 == 6.toUByte())
+ assert(scalarStuff.defaultU8 == 6.toUByte())
+ assert(scalarStuff.justI16 == 7.toShort())
+ assert(scalarStuff.maybeI16 == 7.toShort())
+ assert(scalarStuff.defaultI16 == 7.toShort())
+ assert(scalarStuff.justU16 == 8.toUShort())
+ assert(scalarStuff.maybeU16 == 8.toUShort())
+ assert(scalarStuff.defaultU16 == 8.toUShort())
+ assert(scalarStuff.justI32 == 9)
+ assert(scalarStuff.maybeI32 == 9)
+ assert(scalarStuff.defaultI32 == 9)
+ assert(scalarStuff.justU32 == 10u)
+ assert(scalarStuff.maybeU32 == 10u)
+ assert(scalarStuff.defaultU32 == 10u)
+ assert(scalarStuff.justI64 == 11L)
+ assert(scalarStuff.maybeI64 == 11L)
+ assert(scalarStuff.defaultI64 == 11L)
+ assert(scalarStuff.justU64 == 12UL)
+ assert(scalarStuff.maybeU64 == 12UL)
+ assert(scalarStuff.defaultU64 == 12UL)
+ assert(scalarStuff.justF32 == 13.0f)
+ assert(scalarStuff.maybeF32 == 13.0f)
+ assert(scalarStuff.defaultF32 == 13.0f)
+ assert(scalarStuff.justF64 == 14.0)
+ assert(scalarStuff.maybeF64 == 14.0)
+ assert(scalarStuff.defaultF64 == 14.0)
+ assert(scalarStuff.justBool == true)
+ assert(scalarStuff.maybeBool == true)
+ assert(scalarStuff.defaultBool == true)
+ }
}
}
diff --git a/tests/generate_code.sh b/tests/generate_code.sh
index 56786fa2..c0a08330 100755
--- a/tests/generate_code.sh
+++ b/tests/generate_code.sh
@@ -53,7 +53,7 @@ $TEST_NOINCL_FLAGS $TEST_CPP_FLAGS $TEST_CS_FLAGS $TEST_JS_TS_FLAGS -o namespace
../flatc --dart monster_extra.fbs
# Generate optional scalar code for tests.
-../flatc --rust --lobster optional_scalars.fbs
+../flatc --kotlin --rust --lobster optional_scalars.fbs
# Generate the schema evolution tests
../flatc --cpp --scoped-enums $TEST_CPP_FLAGS -o evolution_test ./evolution_test/evolution_v*.fbs
diff --git a/tests/optional_scalars/ScalarStuff.kt b/tests/optional_scalars/ScalarStuff.kt
new file mode 100644
index 00000000..1d71b232
--- /dev/null
+++ b/tests/optional_scalars/ScalarStuff.kt
@@ -0,0 +1,268 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+package optional_scalars
+
+import java.nio.*
+import kotlin.math.sign
+import com.google.flatbuffers.*
+
+@Suppress("unused")
+@ExperimentalUnsignedTypes
+class ScalarStuff : Table() {
+
+ fun __init(_i: Int, _bb: ByteBuffer) {
+ __reset(_i, _bb)
+ }
+ fun __assign(_i: Int, _bb: ByteBuffer) : ScalarStuff {
+ __init(_i, _bb)
+ return this
+ }
+ val justI8 : Byte
+ get() {
+ val o = __offset(4)
+ return if(o != 0) bb.get(o + bb_pos) else 0
+ }
+ val maybeI8 : Byte?
+ get() {
+ val o = __offset(6)
+ return if(o != 0) bb.get(o + bb_pos) else null
+ }
+ val defaultI8 : Byte
+ get() {
+ val o = __offset(8)
+ return if(o != 0) bb.get(o + bb_pos) else 42
+ }
+ val justU8 : UByte
+ get() {
+ val o = __offset(10)
+ return if(o != 0) bb.get(o + bb_pos).toUByte() else 0u
+ }
+ val maybeU8 : UByte?
+ get() {
+ val o = __offset(12)
+ return if(o != 0) bb.get(o + bb_pos).toUByte() else null
+ }
+ val defaultU8 : UByte
+ get() {
+ val o = __offset(14)
+ return if(o != 0) bb.get(o + bb_pos).toUByte() else 42u
+ }
+ val justI16 : Short
+ get() {
+ val o = __offset(16)
+ return if(o != 0) bb.getShort(o + bb_pos) else 0
+ }
+ val maybeI16 : Short?
+ get() {
+ val o = __offset(18)
+ return if(o != 0) bb.getShort(o + bb_pos) else null
+ }
+ val defaultI16 : Short
+ get() {
+ val o = __offset(20)
+ return if(o != 0) bb.getShort(o + bb_pos) else 42
+ }
+ val justU16 : UShort
+ get() {
+ val o = __offset(22)
+ return if(o != 0) bb.getShort(o + bb_pos).toUShort() else 0u
+ }
+ val maybeU16 : UShort?
+ get() {
+ val o = __offset(24)
+ return if(o != 0) bb.getShort(o + bb_pos).toUShort() else null
+ }
+ val defaultU16 : UShort
+ get() {
+ val o = __offset(26)
+ return if(o != 0) bb.getShort(o + bb_pos).toUShort() else 42u
+ }
+ val justI32 : Int
+ get() {
+ val o = __offset(28)
+ return if(o != 0) bb.getInt(o + bb_pos) else 0
+ }
+ val maybeI32 : Int?
+ get() {
+ val o = __offset(30)
+ return if(o != 0) bb.getInt(o + bb_pos) else null
+ }
+ val defaultI32 : Int
+ get() {
+ val o = __offset(32)
+ return if(o != 0) bb.getInt(o + bb_pos) else 42
+ }
+ val justU32 : UInt
+ get() {
+ val o = __offset(34)
+ return if(o != 0) bb.getInt(o + bb_pos).toUInt() else 0u
+ }
+ val maybeU32 : UInt?
+ get() {
+ val o = __offset(36)
+ return if(o != 0) bb.getInt(o + bb_pos).toUInt() else null
+ }
+ val defaultU32 : UInt
+ get() {
+ val o = __offset(38)
+ return if(o != 0) bb.getInt(o + bb_pos).toUInt() else 42u
+ }
+ val justI64 : Long
+ get() {
+ val o = __offset(40)
+ return if(o != 0) bb.getLong(o + bb_pos) else 0L
+ }
+ val maybeI64 : Long?
+ get() {
+ val o = __offset(42)
+ return if(o != 0) bb.getLong(o + bb_pos) else null
+ }
+ val defaultI64 : Long
+ get() {
+ val o = __offset(44)
+ return if(o != 0) bb.getLong(o + bb_pos) else 42L
+ }
+ val justU64 : ULong
+ get() {
+ val o = __offset(46)
+ return if(o != 0) bb.getLong(o + bb_pos).toULong() else 0UL
+ }
+ val maybeU64 : ULong?
+ get() {
+ val o = __offset(48)
+ return if(o != 0) bb.getLong(o + bb_pos).toULong() else null
+ }
+ val defaultU64 : ULong
+ get() {
+ val o = __offset(50)
+ return if(o != 0) bb.getLong(o + bb_pos).toULong() else 42UL
+ }
+ val justF32 : Float
+ get() {
+ val o = __offset(52)
+ return if(o != 0) bb.getFloat(o + bb_pos) else 0.0f
+ }
+ val maybeF32 : Float?
+ get() {
+ val o = __offset(54)
+ return if(o != 0) bb.getFloat(o + bb_pos) else null
+ }
+ val defaultF32 : Float
+ get() {
+ val o = __offset(56)
+ return if(o != 0) bb.getFloat(o + bb_pos) else 42.0f
+ }
+ val justF64 : Double
+ get() {
+ val o = __offset(58)
+ return if(o != 0) bb.getDouble(o + bb_pos) else 0.0
+ }
+ val maybeF64 : Double?
+ get() {
+ val o = __offset(60)
+ return if(o != 0) bb.getDouble(o + bb_pos) else null
+ }
+ val defaultF64 : Double
+ get() {
+ val o = __offset(62)
+ return if(o != 0) bb.getDouble(o + bb_pos) else 42.0
+ }
+ val justBool : Boolean
+ get() {
+ val o = __offset(64)
+ return if(o != 0) 0.toByte() != bb.get(o + bb_pos) else false
+ }
+ val maybeBool : Boolean?
+ get() {
+ val o = __offset(66)
+ return if(o != 0) 0.toByte() != bb.get(o + bb_pos) else null
+ }
+ val defaultBool : Boolean
+ get() {
+ val o = __offset(68)
+ return if(o != 0) 0.toByte() != bb.get(o + bb_pos) else true
+ }
+ companion object {
+ fun validateVersion() = Constants.FLATBUFFERS_1_12_0()
+ fun getRootAsScalarStuff(_bb: ByteBuffer): ScalarStuff = getRootAsScalarStuff(_bb, ScalarStuff())
+ fun getRootAsScalarStuff(_bb: ByteBuffer, obj: ScalarStuff): ScalarStuff {
+ _bb.order(ByteOrder.LITTLE_ENDIAN)
+ return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb))
+ }
+ fun createScalarStuff(builder: FlatBufferBuilder, justI8: Byte, maybeI8: Byte?, defaultI8: Byte, justU8: UByte, maybeU8: UByte?, defaultU8: UByte, justI16: Short, maybeI16: Short?, defaultI16: Short, justU16: UShort, maybeU16: UShort?, defaultU16: UShort, justI32: Int, maybeI32: Int?, defaultI32: Int, justU32: UInt, maybeU32: UInt?, defaultU32: UInt, justI64: Long, maybeI64: Long?, defaultI64: Long, justU64: ULong, maybeU64: ULong?, defaultU64: ULong, justF32: Float, maybeF32: Float?, defaultF32: Float, justF64: Double, maybeF64: Double?, defaultF64: Double, justBool: Boolean, maybeBool: Boolean?, defaultBool: Boolean) : Int {
+ builder.startTable(33)
+ addDefaultF64(builder, defaultF64)
+ maybeF64?.run { addMaybeF64(builder, maybeF64) }
+ addJustF64(builder, justF64)
+ addDefaultU64(builder, defaultU64)
+ maybeU64?.run { addMaybeU64(builder, maybeU64) }
+ addJustU64(builder, justU64)
+ addDefaultI64(builder, defaultI64)
+ maybeI64?.run { addMaybeI64(builder, maybeI64) }
+ addJustI64(builder, justI64)
+ addDefaultF32(builder, defaultF32)
+ maybeF32?.run { addMaybeF32(builder, maybeF32) }
+ addJustF32(builder, justF32)
+ addDefaultU32(builder, defaultU32)
+ maybeU32?.run { addMaybeU32(builder, maybeU32) }
+ addJustU32(builder, justU32)
+ addDefaultI32(builder, defaultI32)
+ maybeI32?.run { addMaybeI32(builder, maybeI32) }
+ addJustI32(builder, justI32)
+ addDefaultU16(builder, defaultU16)
+ maybeU16?.run { addMaybeU16(builder, maybeU16) }
+ addJustU16(builder, justU16)
+ addDefaultI16(builder, defaultI16)
+ maybeI16?.run { addMaybeI16(builder, maybeI16) }
+ addJustI16(builder, justI16)
+ addDefaultBool(builder, defaultBool)
+ maybeBool?.run { addMaybeBool(builder, maybeBool) }
+ addJustBool(builder, justBool)
+ addDefaultU8(builder, defaultU8)
+ maybeU8?.run { addMaybeU8(builder, maybeU8) }
+ addJustU8(builder, justU8)
+ addDefaultI8(builder, defaultI8)
+ maybeI8?.run { addMaybeI8(builder, maybeI8) }
+ addJustI8(builder, justI8)
+ return endScalarStuff(builder)
+ }
+ fun startScalarStuff(builder: FlatBufferBuilder) = builder.startTable(33)
+ fun addJustI8(builder: FlatBufferBuilder, justI8: Byte) = builder.addByte(0, justI8, 0)
+ fun addMaybeI8(builder: FlatBufferBuilder, maybeI8: Byte) = builder.addByte(1, maybeI8, 0)
+ fun addDefaultI8(builder: FlatBufferBuilder, defaultI8: Byte) = builder.addByte(2, defaultI8, 42)
+ fun addJustU8(builder: FlatBufferBuilder, justU8: UByte) = builder.addByte(3, justU8.toByte(), 0)
+ fun addMaybeU8(builder: FlatBufferBuilder, maybeU8: UByte) = builder.addByte(4, maybeU8.toByte(), 0)
+ fun addDefaultU8(builder: FlatBufferBuilder, defaultU8: UByte) = builder.addByte(5, defaultU8.toByte(), 42)
+ fun addJustI16(builder: FlatBufferBuilder, justI16: Short) = builder.addShort(6, justI16, 0)
+ fun addMaybeI16(builder: FlatBufferBuilder, maybeI16: Short) = builder.addShort(7, maybeI16, 0)
+ fun addDefaultI16(builder: FlatBufferBuilder, defaultI16: Short) = builder.addShort(8, defaultI16, 42)
+ fun addJustU16(builder: FlatBufferBuilder, justU16: UShort) = builder.addShort(9, justU16.toShort(), 0)
+ fun addMaybeU16(builder: FlatBufferBuilder, maybeU16: UShort) = builder.addShort(10, maybeU16.toShort(), 0)
+ fun addDefaultU16(builder: FlatBufferBuilder, defaultU16: UShort) = builder.addShort(11, defaultU16.toShort(), 42)
+ fun addJustI32(builder: FlatBufferBuilder, justI32: Int) = builder.addInt(12, justI32, 0)
+ fun addMaybeI32(builder: FlatBufferBuilder, maybeI32: Int) = builder.addInt(13, maybeI32, 0)
+ fun addDefaultI32(builder: FlatBufferBuilder, defaultI32: Int) = builder.addInt(14, defaultI32, 42)
+ fun addJustU32(builder: FlatBufferBuilder, justU32: UInt) = builder.addInt(15, justU32.toInt(), 0)
+ fun addMaybeU32(builder: FlatBufferBuilder, maybeU32: UInt) = builder.addInt(16, maybeU32.toInt(), 0)
+ fun addDefaultU32(builder: FlatBufferBuilder, defaultU32: UInt) = builder.addInt(17, defaultU32.toInt(), 42)
+ fun addJustI64(builder: FlatBufferBuilder, justI64: Long) = builder.addLong(18, justI64, 0L)
+ fun addMaybeI64(builder: FlatBufferBuilder, maybeI64: Long) = builder.addLong(19, maybeI64, 0)
+ fun addDefaultI64(builder: FlatBufferBuilder, defaultI64: Long) = builder.addLong(20, defaultI64, 42L)
+ fun addJustU64(builder: FlatBufferBuilder, justU64: ULong) = builder.addLong(21, justU64.toLong(), 0)
+ fun addMaybeU64(builder: FlatBufferBuilder, maybeU64: ULong) = builder.addLong(22, maybeU64.toLong(), 0)
+ fun addDefaultU64(builder: FlatBufferBuilder, defaultU64: ULong) = builder.addLong(23, defaultU64.toLong(), 42)
+ fun addJustF32(builder: FlatBufferBuilder, justF32: Float) = builder.addFloat(24, justF32, 0.0)
+ fun addMaybeF32(builder: FlatBufferBuilder, maybeF32: Float) = builder.addFloat(25, maybeF32, 0.0)
+ fun addDefaultF32(builder: FlatBufferBuilder, defaultF32: Float) = builder.addFloat(26, defaultF32, 42.0)
+ fun addJustF64(builder: FlatBufferBuilder, justF64: Double) = builder.addDouble(27, justF64, 0.0)
+ fun addMaybeF64(builder: FlatBufferBuilder, maybeF64: Double) = builder.addDouble(28, maybeF64, 0.0)
+ fun addDefaultF64(builder: FlatBufferBuilder, defaultF64: Double) = builder.addDouble(29, defaultF64, 42.0)
+ fun addJustBool(builder: FlatBufferBuilder, justBool: Boolean) = builder.addBoolean(30, justBool, false)
+ fun addMaybeBool(builder: FlatBufferBuilder, maybeBool: Boolean) = builder.addBoolean(31, maybeBool, false)
+ fun addDefaultBool(builder: FlatBufferBuilder, defaultBool: Boolean) = builder.addBoolean(32, defaultBool, true)
+ fun endScalarStuff(builder: FlatBufferBuilder) : Int {
+ val o = builder.endTable()
+ return o
+ }
+ }
+}
diff --git a/tests/test.cpp b/tests/test.cpp
index 68f982b5..7f3c7d34 100644
--- a/tests/test.cpp
+++ b/tests/test.cpp
@@ -3466,6 +3466,7 @@ void OptionalScalarsTest() {
const int kNumLanguages = 17;
const auto supported = (flatbuffers::IDLOptions::kRust |
flatbuffers::IDLOptions::kSwift |
+ flatbuffers::IDLOptions::kKotlin |
flatbuffers::IDLOptions::kLobster);
for (int lang=0; lang<kNumLanguages; lang++) {
flatbuffers::IDLOptions opts;