aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/libs/flatbuffers/src/idl_gen_kotlin.cpp
diff options
context:
space:
mode:
authorreshilkin <reshilkin@yandex-team.com>2023-08-11 12:01:29 +0300
committerreshilkin <reshilkin@yandex-team.com>2023-08-11 13:00:03 +0300
commit5894c3ce50a49a9f9bc1c0316e2ef0708e3a7ef8 (patch)
tree624e56690fe689e569d05612fa0e92f2c5bdb75b /contrib/libs/flatbuffers/src/idl_gen_kotlin.cpp
parent1eb895279c52b0d2505a31b79ad326b56d0b2681 (diff)
downloadydb-5894c3ce50a49a9f9bc1c0316e2ef0708e3a7ef8.tar.gz
Update contrib/libs/flatbuffers to 23.5.9
Diffstat (limited to 'contrib/libs/flatbuffers/src/idl_gen_kotlin.cpp')
-rw-r--r--contrib/libs/flatbuffers/src/idl_gen_kotlin.cpp351
1 files changed, 241 insertions, 110 deletions
diff --git a/contrib/libs/flatbuffers/src/idl_gen_kotlin.cpp b/contrib/libs/flatbuffers/src/idl_gen_kotlin.cpp
index fb4ce87a67..eeaca94854 100644
--- a/contrib/libs/flatbuffers/src/idl_gen_kotlin.cpp
+++ b/contrib/libs/flatbuffers/src/idl_gen_kotlin.cpp
@@ -16,6 +16,8 @@
// independent from idl_parser, since this code is not needed for most clients
+#include "idl_gen_kotlin.h"
+
#include <functional>
#include <unordered_set>
@@ -23,14 +25,14 @@
#include "flatbuffers/flatbuffers.h"
#include "flatbuffers/idl.h"
#include "flatbuffers/util.h"
-#if defined(FLATBUFFERS_CPP98_STL)
-# include <cctype>
-#endif // defined(FLATBUFFERS_CPP98_STL)
+#include "idl_namer.h"
namespace flatbuffers {
namespace kotlin {
+namespace {
+
typedef std::map<std::string, std::pair<std::string, std::string> > FbbParamMap;
static TypedFloatConstantGenerator KotlinFloatGen("Double.", "Float.", "NaN",
"POSITIVE_INFINITY",
@@ -38,40 +40,54 @@ static TypedFloatConstantGenerator KotlinFloatGen("Double.", "Float.", "NaN",
static const CommentConfig comment_config = { "/**", " *", " */" };
static const std::string ident_pad = " ";
-static const char *keywords[] = {
- "package", "as", "typealias", "class", "this", "super",
- "val", "var", "fun", "for", "null", "true",
- "false", "is", "in", "throw", "return", "break",
- "continue", "object", "if", "try", "else", "while",
- "do", "when", "interface", "typeof", "Any", "Character"
-};
-
-// Escape Keywords
-static std::string Esc(const std::string &name) {
- for (size_t i = 0; i < sizeof(keywords) / sizeof(keywords[0]); i++) {
- if (name == keywords[i]) { return MakeCamel(name + "_", false); }
- }
+static std::set<std::string> KotlinKeywords() {
+ return { "package", "as", "typealias", "class", "this", "super",
+ "val", "var", "fun", "for", "null", "true",
+ "false", "is", "in", "throw", "return", "break",
+ "continue", "object", "if", "try", "else", "while",
+ "do", "when", "interface", "typeof", "Any", "Character" };
+}
- return MakeCamel(name, false);
+static Namer::Config KotlinDefaultConfig() {
+ return { /*types=*/Case::kKeep,
+ /*constants=*/Case::kKeep,
+ /*methods=*/Case::kLowerCamel,
+ /*functions=*/Case::kKeep,
+ /*fields=*/Case::kLowerCamel,
+ /*variables=*/Case::kLowerCamel,
+ /*variants=*/Case::kKeep,
+ /*enum_variant_seperator=*/"", // I.e. Concatenate.
+ /*escape_keywords=*/Namer::Config::Escape::BeforeConvertingCase,
+ /*namespaces=*/Case::kKeep,
+ /*namespace_seperator=*/"__",
+ /*object_prefix=*/"",
+ /*object_suffix=*/"T",
+ /*keyword_prefix=*/"",
+ /*keyword_suffix=*/"_",
+ /*filenames=*/Case::kKeep,
+ /*directories=*/Case::kKeep,
+ /*output_path=*/"",
+ /*filename_suffix=*/"",
+ /*filename_extension=*/".kt" };
}
+} // namespace
class KotlinGenerator : public BaseGenerator {
public:
KotlinGenerator(const Parser &parser, const std::string &path,
const std::string &file_name)
: BaseGenerator(parser, path, file_name, "", ".", "kt"),
- cur_name_space_(nullptr) {}
+ namer_(WithFlagOptions(KotlinDefaultConfig(), parser.opts, path),
+ KotlinKeywords()) {}
KotlinGenerator &operator=(const KotlinGenerator &);
bool generate() FLATBUFFERS_OVERRIDE {
std::string one_file_code;
- cur_name_space_ = parser_.current_namespace_;
for (auto it = parser_.enums_.vec.begin(); it != parser_.enums_.vec.end();
++it) {
CodeWriter enumWriter(ident_pad);
auto &enum_def = **it;
- if (!parser_.opts.one_file) cur_name_space_ = enum_def.defined_namespace;
GenEnum(enum_def, enumWriter);
if (parser_.opts.one_file) {
one_file_code += enumWriter.ToString();
@@ -86,8 +102,6 @@ class KotlinGenerator : public BaseGenerator {
it != parser_.structs_.vec.end(); ++it) {
CodeWriter structWriter(ident_pad);
auto &struct_def = **it;
- if (!parser_.opts.one_file)
- cur_name_space_ = struct_def.defined_namespace;
GenStruct(struct_def, structWriter, parser_.opts);
if (parser_.opts.one_file) {
one_file_code += structWriter.ToString();
@@ -120,19 +134,31 @@ class KotlinGenerator : public BaseGenerator {
code += "\n\n";
}
if (needs_includes) {
- code += "import java.nio.*\n";
- code += "import kotlin.math.sign\n";
- code += "import com.google.flatbuffers.*\n\n";
+ code +=
+ "import com.google.flatbuffers.BaseVector\n"
+ "import com.google.flatbuffers.BooleanVector\n"
+ "import com.google.flatbuffers.ByteVector\n"
+ "import com.google.flatbuffers.Constants\n"
+ "import com.google.flatbuffers.DoubleVector\n"
+ "import com.google.flatbuffers.FlatBufferBuilder\n"
+ "import com.google.flatbuffers.FloatVector\n"
+ "import com.google.flatbuffers.LongVector\n"
+ "import com.google.flatbuffers.StringVector\n"
+ "import com.google.flatbuffers.Struct\n"
+ "import com.google.flatbuffers.Table\n"
+ "import com.google.flatbuffers.UnionVector\n"
+ "import java.nio.ByteBuffer\n"
+ "import java.nio.ByteOrder\n"
+ "import kotlin.math.sign\n\n";
}
code += classcode;
- auto filename = NamespaceDir(ns) + defname + ".kt";
+ const std::string dirs = namer_.Directories(ns);
+ EnsureDirExists(dirs);
+ const std::string filename =
+ dirs + namer_.File(defname, /*skips=*/SkipFile::Suffix);
return SaveFile(filename.c_str(), code, false);
}
- const Namespace *CurrentNameSpace() const FLATBUFFERS_OVERRIDE {
- return cur_name_space_;
- }
-
static bool IsEnum(const Type &type) {
return type.enum_def != nullptr && IsInteger(type.base_type);
}
@@ -167,10 +193,11 @@ class KotlinGenerator : public BaseGenerator {
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) ||
+ (!field.IsRequired() &&
+ (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 &&
+ (base_type == BASE_TYPE_VECTOR && !field.IsRequired() &&
!IsScalar(field.value.type.VectorType().base_type))) {
r_type += "?";
}
@@ -262,8 +289,7 @@ class KotlinGenerator : public BaseGenerator {
GenerateComment(enum_def.doc_comment, writer, &comment_config);
writer += "@Suppress(\"unused\")";
- writer += "@ExperimentalUnsignedTypes";
- writer += "class " + Esc(enum_def.name) + " private constructor() {";
+ writer += "class " + namer_.Type(enum_def) + " private constructor() {";
writer.IncrementIdentLevel();
GenerateCompanionObject(writer, [&]() {
@@ -274,7 +300,7 @@ class KotlinGenerator : public BaseGenerator {
auto field_type = GenTypeBasic(enum_def.underlying_type.base_type);
auto val = enum_def.ToString(ev);
auto suffix = LiteralSuffix(enum_def.underlying_type.base_type);
- writer.SetValue("name", Esc(ev.name));
+ writer.SetValue("name", namer_.Variant(ev.name));
writer.SetValue("type", field_type);
writer.SetValue("val", val + suffix);
GenerateComment(ev.doc_comment, writer, &comment_config);
@@ -289,7 +315,10 @@ class KotlinGenerator : public BaseGenerator {
// Average distance between values above which we consider a table
// "too sparse". Change at will.
static const uint64_t kMaxSparseness = 5;
- if (range / static_cast<uint64_t>(enum_def.size()) < kMaxSparseness) {
+ bool generate_names =
+ range / static_cast<uint64_t>(enum_def.size()) < kMaxSparseness &&
+ parser_.opts.mini_reflect == IDLOptions::kTypesAndNames;
+ if (generate_names) {
GeneratePropertyOneLine(writer, "names", "Array<String>", [&]() {
writer += "arrayOf(\\";
auto val = enum_def.Vals().front();
@@ -341,7 +370,8 @@ class KotlinGenerator : public BaseGenerator {
case BASE_TYPE_UTYPE: return bb_var_name + ".get";
case BASE_TYPE_BOOL: return "0.toByte() != " + bb_var_name + ".get";
default:
- return bb_var_name + ".get" + MakeCamel(GenTypeBasic(type.base_type));
+ return bb_var_name + "." +
+ namer_.Method("get", GenTypeBasic(type.base_type));
}
}
@@ -361,7 +391,8 @@ class KotlinGenerator : public BaseGenerator {
case BASE_TYPE_BOOL:
case BASE_TYPE_NONE:
case BASE_TYPE_UTYPE: return "bb.put";
- default: return "bb.put" + MakeCamel(GenTypeBasic(type.base_type));
+ default:
+ return "bb." + namer_.Method("put", GenTypeBasic(type.base_type));
}
}
return "";
@@ -384,8 +415,8 @@ class KotlinGenerator : public BaseGenerator {
// Recursively generate arguments for a constructor, to deal with nested
// structs.
- static void GenStructArgs(const StructDef &struct_def, CodeWriter &writer,
- const char *nameprefix) {
+ void GenStructArgs(const StructDef &struct_def, CodeWriter &writer,
+ const char *nameprefix) const {
for (auto it = struct_def.fields.vec.begin();
it != struct_def.fields.vec.end(); ++it) {
auto &field = **it;
@@ -398,7 +429,7 @@ class KotlinGenerator : public BaseGenerator {
(nameprefix + (field.name + "_")).c_str());
} else {
writer += std::string(", ") + nameprefix + "\\";
- writer += MakeCamel(field.name) + ": \\";
+ writer += namer_.Field(field) + ": \\";
writer += GenTypeBasic(field.value.type.base_type) + "\\";
}
}
@@ -407,8 +438,8 @@ class KotlinGenerator : public BaseGenerator {
// Recusively generate struct construction statements of the form:
// builder.putType(name);
// and insert manual padding.
- static void GenStructBody(const StructDef &struct_def, CodeWriter &writer,
- const char *nameprefix) {
+ void GenStructBody(const StructDef &struct_def, CodeWriter &writer,
+ const char *nameprefix) const {
writer.SetValue("align", NumToString(struct_def.minalign));
writer.SetValue("size", NumToString(struct_def.bytesize));
writer += "builder.prep({{align}}, {{size}})";
@@ -425,7 +456,7 @@ class KotlinGenerator : public BaseGenerator {
(nameprefix + (field.name + "_")).c_str());
} else {
writer.SetValue("type", GenMethod(field.value.type));
- writer.SetValue("argname", nameprefix + MakeCamel(field.name, false));
+ writer.SetValue("argname", nameprefix + namer_.Variable(field));
writer.SetValue("cast", CastToSigned(field.value.type));
writer += "builder.put{{type}}({{argname}}{{cast}})";
}
@@ -459,11 +490,10 @@ class KotlinGenerator : public BaseGenerator {
GenerateComment(struct_def.doc_comment, writer, &comment_config);
auto fixed = struct_def.fixed;
- writer.SetValue("struct_name", Esc(struct_def.name));
+ writer.SetValue("struct_name", namer_.Type(struct_def));
writer.SetValue("superclass", fixed ? "Struct" : "Table");
writer += "@Suppress(\"unused\")";
- writer += "@ExperimentalUnsignedTypes";
writer += "class {{struct_name}} : {{superclass}}() {\n";
writer.IncrementIdentLevel();
@@ -476,7 +506,7 @@ class KotlinGenerator : public BaseGenerator {
// Generate assign method
GenerateFun(writer, "__assign", "_i: Int, _bb: ByteBuffer",
- Esc(struct_def.name), [&]() {
+ namer_.Type(struct_def), [&]() {
writer += "__init(_i, _bb)";
writer += "return this";
});
@@ -489,15 +519,15 @@ class KotlinGenerator : public BaseGenerator {
if (!struct_def.fixed) {
FieldDef *key_field = nullptr;
- // Generate verson check method.
+ // Generate version check method.
// Force compile time error if not using the same version
// runtime.
GenerateFunOneLine(
writer, "validateVersion", "", "",
- [&]() { writer += "Constants.FLATBUFFERS_2_0_0()"; },
+ [&]() { writer += "Constants.FLATBUFFERS_23_5_9()"; },
options.gen_jvmstatic);
- GenerateGetRootAsAccessors(Esc(struct_def.name), writer, options);
+ GenerateGetRootAsAccessors(namer_.Type(struct_def), writer, options);
GenerateBufferHasIdentifier(struct_def, writer, options);
GenerateTableCreator(struct_def, writer, options);
@@ -549,7 +579,7 @@ class KotlinGenerator : public BaseGenerator {
void GenerateLookupByKey(FieldDef *key_field, StructDef &struct_def,
CodeWriter &writer, const IDLOptions options) const {
std::stringstream params;
- params << "obj: " << Esc(struct_def.name) << "?"
+ params << "obj: " << namer_.Type(struct_def) << "?"
<< ", ";
params << "vectorLocation: Int, ";
params << "key: " << GenTypeGet(key_field->value.type) << ", ";
@@ -557,7 +587,7 @@ class KotlinGenerator : public BaseGenerator {
auto statements = [&]() {
auto base_type = key_field->value.type.base_type;
- writer.SetValue("struct_name", Esc(struct_def.name));
+ writer.SetValue("struct_name", namer_.Type(struct_def));
if (base_type == BASE_TYPE_STRING) {
writer +=
"val byteKey = key."
@@ -603,7 +633,8 @@ class KotlinGenerator : public BaseGenerator {
writer += "return null";
};
GenerateFun(writer, "__lookup_by_key", params.str(),
- Esc(struct_def.name) + "?", statements, options.gen_jvmstatic);
+ namer_.Type(struct_def) + "?", statements,
+ options.gen_jvmstatic);
}
void GenerateFinishSizePrefixed(StructDef &struct_def,
@@ -612,7 +643,8 @@ class KotlinGenerator : public BaseGenerator {
const IDLOptions options) const {
auto id = identifier.length() > 0 ? ", \"" + identifier + "\"" : "";
auto params = "builder: FlatBufferBuilder, offset: Int";
- auto method_name = "finishSizePrefixed" + Esc(struct_def.name) + "Buffer";
+ auto method_name =
+ namer_.LegacyJavaMethod2("finishSizePrefixed", struct_def, "Buffer");
GenerateFunOneLine(
writer, method_name, params, "",
[&]() { writer += "builder.finishSizePrefixed(offset" + id + ")"; },
@@ -624,7 +656,8 @@ class KotlinGenerator : public BaseGenerator {
const IDLOptions options) const {
auto id = identifier.length() > 0 ? ", \"" + identifier + "\"" : "";
auto params = "builder: FlatBufferBuilder, offset: Int";
- auto method_name = "finish" + Esc(struct_def.name) + "Buffer";
+ auto method_name =
+ namer_.LegacyKotlinMethod("finish", struct_def, "Buffer");
GenerateFunOneLine(
writer, method_name, params, "",
[&]() { writer += "builder.finish(offset" + id + ")"; },
@@ -634,7 +667,7 @@ class KotlinGenerator : public BaseGenerator {
void GenerateEndStructMethod(StructDef &struct_def, CodeWriter &writer,
const IDLOptions options) const {
// Generate end{{TableName}}(builder: FlatBufferBuilder) method
- auto name = "end" + Esc(struct_def.name);
+ auto name = namer_.LegacyJavaMethod2("end", struct_def, "");
auto params = "builder: FlatBufferBuilder";
auto returns = "Int";
auto field_vec = struct_def.fields.vec;
@@ -660,7 +693,7 @@ class KotlinGenerator : public BaseGenerator {
void GenerateCreateVectorField(FieldDef &field, CodeWriter &writer,
const IDLOptions options) const {
auto vector_type = field.value.type.VectorType();
- auto method_name = "create" + MakeCamel(Esc(field.name)) + "Vector";
+ auto method_name = namer_.Method("create", field, "vector");
auto params = "builder: FlatBufferBuilder, data: " +
GenTypeBasic(vector_type.base_type) + "Array";
writer.SetValue("size", NumToString(InlineSize(vector_type)));
@@ -668,6 +701,9 @@ class KotlinGenerator : public BaseGenerator {
writer.SetValue("root", GenMethod(vector_type));
writer.SetValue("cast", CastToSigned(vector_type));
+ if (IsUnsigned(vector_type.base_type)) {
+ writer += "@kotlin.ExperimentalUnsignedTypes";
+ }
GenerateFun(
writer, method_name, params, "Int",
[&]() {
@@ -692,8 +728,7 @@ class KotlinGenerator : public BaseGenerator {
writer.SetValue("align", NumToString(InlineAlignment(vector_type)));
GenerateFunOneLine(
- writer, "start" + MakeCamel(Esc(field.name) + "Vector", true), params,
- "",
+ writer, namer_.Method("start", field, "Vector"), params, "",
[&]() {
writer += "builder.startVector({{size}}, numElems, {{align}})";
},
@@ -703,23 +738,36 @@ class KotlinGenerator : public BaseGenerator {
void GenerateAddField(std::string field_pos, FieldDef &field,
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);
+ auto secondArg = namer_.Variable(field.name) + ": " + field_type;
+
+ auto content = [&]() {
+ auto method = GenMethod(field.value.type);
+ writer.SetValue("field_name", namer_.Field(field));
+ writer.SetValue("method_name", method);
+ writer.SetValue("pos", field_pos);
+ writer.SetValue("default", GenFBBDefaultValue(field));
+ writer.SetValue("cast", GenFBBValueCast(field));
+ if (field.key) {
+ // field has key attribute, so always need to exist
+ // even if its value is equal to default.
+ // Generated code will bypass default checking
+ // resulting in { builder.addShort(name); slot(id); }
+ writer += "builder.add{{method_name}}({{field_name}}{{cast}})";
+ writer += "builder.slot({{pos}})";
+ } else {
+ writer += "builder.add{{method_name}}({{pos}}, \\";
+ writer += "{{field_name}}{{cast}}, {{default}})";
+ }
+ };
+ auto signature = namer_.LegacyKotlinMethod("add", field, "");
+ auto params = "builder: FlatBufferBuilder, " + secondArg;
+ if (field.key) {
+ GenerateFun(writer, signature, params, "", content,
+ options.gen_jvmstatic);
+ } else {
+ GenerateFunOneLine(writer, signature, params, "", content,
+ options.gen_jvmstatic);
+ }
}
static std::string ToSignedType(const Type &type) {
@@ -763,7 +811,8 @@ class KotlinGenerator : public BaseGenerator {
void GenerateStartStructMethod(StructDef &struct_def, CodeWriter &code,
const IDLOptions options) const {
GenerateFunOneLine(
- code, "start" + Esc(struct_def.name), "builder: FlatBufferBuilder", "",
+ code, namer_.LegacyJavaMethod2("start", struct_def, ""),
+ "builder: FlatBufferBuilder", "",
[&]() {
code += "builder.startTable(" +
NumToString(struct_def.fields.vec.size()) + ")";
@@ -795,13 +844,13 @@ class KotlinGenerator : public BaseGenerator {
// Generate a table constructor of the form:
// public static int createName(FlatBufferBuilder builder, args...)
- auto name = "create" + Esc(struct_def.name);
+ auto name = namer_.LegacyJavaMethod2("create", struct_def, "");
std::stringstream params;
params << "builder: FlatBufferBuilder";
for (auto it = fields_vec.begin(); it != fields_vec.end(); ++it) {
auto &field = **it;
if (field.deprecated) continue;
- params << ", " << MakeCamel(Esc(field.name), false);
+ params << ", " << namer_.Variable(field);
if (!IsScalar(field.value.type.base_type)) {
params << "Offset: ";
} else {
@@ -827,17 +876,15 @@ class KotlinGenerator : public BaseGenerator {
auto base_type_size = SizeOf(field.value.type.base_type);
if (!field.deprecated &&
(!sortbysize || size == base_type_size)) {
- writer.SetValue("camel_field_name",
- MakeCamel(Esc(field.name), true));
- writer.SetValue("field_name",
- MakeCamel(Esc(field.name), false));
+ writer.SetValue("field_name", namer_.Field(field));
// we wrap on null check for scalar optionals
writer += field.IsScalarOptional()
? "{{field_name}}?.run { \\"
: "\\";
- writer += "add{{camel_field_name}}(builder, {{field_name}}\\";
+ writer += namer_.LegacyKotlinMethod("add", field, "") +
+ "(builder, {{field_name}}\\";
if (!IsScalar(field.value.type.base_type)) {
writer += "Offset\\";
}
@@ -857,7 +904,7 @@ class KotlinGenerator : public BaseGenerator {
// Check if a buffer has the identifier.
if (parser_.root_struct_def_ != &struct_def || !file_identifier.length())
return;
- auto name = MakeCamel(Esc(struct_def.name), false);
+ auto name = namer_.Function(struct_def);
GenerateFunOneLine(
writer, name + "BufferHasIdentifier", "_bb: ByteBuffer", "Boolean",
[&]() {
@@ -876,7 +923,7 @@ class KotlinGenerator : public BaseGenerator {
GenerateComment(field.doc_comment, writer, &comment_config);
- auto field_name = MakeCamel(Esc(field.name), false);
+ auto field_name = namer_.Field(field);
auto field_type = GenTypeGet(field.value.type);
auto field_default_value = GenDefaultValue(field);
auto return_type = GetterReturnType(field);
@@ -960,7 +1007,15 @@ class KotlinGenerator : public BaseGenerator {
OffsetWrapper(
writer, offset_val,
[&]() { writer += "obj.__assign({{seek}}, bb)"; },
- [&]() { writer += "null"; });
+ [&]() {
+ if (field.IsRequired()) {
+ writer +=
+ "throw AssertionError(\"No value for "
+ "(required) field {{field_name}}\")";
+ } else {
+ writer += "null";
+ }
+ });
});
}
break;
@@ -970,12 +1025,30 @@ class KotlinGenerator : public BaseGenerator {
// val Name : String?
// get() = {
// val o = __offset(10)
- // return if (o != 0) __string(o + bb_pos) else null
+ // return if (o != 0) {
+ // __string(o + bb_pos)
+ // } else {
+ // null
+ // }
// }
// ? adds nullability annotation
GenerateGetter(writer, field_name, return_type, [&]() {
writer += "val o = __offset({{offset}})";
- writer += "return if (o != 0) __string(o + bb_pos) else null";
+ writer += "return if (o != 0) {";
+ writer.IncrementIdentLevel();
+ writer += "__string(o + bb_pos)";
+ writer.DecrementIdentLevel();
+ writer += "} else {";
+ writer.IncrementIdentLevel();
+ if (field.IsRequired()) {
+ writer +=
+ "throw AssertionError(\"No value for (required) field "
+ "{{field_name}}\")";
+ } else {
+ writer += "null";
+ }
+ writer.DecrementIdentLevel();
+ writer += "}";
});
break;
case BASE_TYPE_VECTOR: {
@@ -1000,7 +1073,11 @@ class KotlinGenerator : public BaseGenerator {
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);
+ auto not_found =
+ field.IsRequired()
+ ? "throw IndexOutOfBoundsException(\"Index out of range: "
+ "$j, vector {{field_name}} is empty\")"
+ : NotFoundReturn(field.value.type.element);
auto found = "";
writer.SetValue("index", index);
switch (vectortype.base_type) {
@@ -1047,7 +1124,7 @@ class KotlinGenerator : public BaseGenerator {
auto &kfield = **kit;
if (kfield.key) {
auto qualified_name = WrapInNameSpace(sd);
- auto name = MakeCamel(Esc(field.name), false) + "ByKey";
+ auto name = namer_.Method(field, "ByKey");
auto params = "key: " + GenTypeGet(kfield.value.type);
auto rtype = qualified_name + "?";
GenerateFun(writer, name, params, rtype, [&]() {
@@ -1140,9 +1217,9 @@ class KotlinGenerator : public BaseGenerator {
auto underlying_type = value_base_type == BASE_TYPE_VECTOR
? value_type.VectorType()
: value_type;
- auto name = "mutate" + MakeCamel(Esc(field.name), true);
+ auto name = namer_.LegacyKotlinMethod("mutate", field, "");
auto size = NumToString(InlineSize(underlying_type));
- auto params = Esc(field.name) + ": " + GenTypeGet(underlying_type);
+ auto params = namer_.Field(field) + ": " + GenTypeGet(underlying_type);
// A vector mutator also needs the index of the vector element it should
// mutate.
if (value_base_type == BASE_TYPE_VECTOR) params.insert(0, "j: Int, ");
@@ -1151,8 +1228,8 @@ class KotlinGenerator : public BaseGenerator {
// representation.
auto setter_parameter =
underlying_type.base_type == BASE_TYPE_BOOL
- ? "(if(" + Esc(field.name) + ") 1 else 0).toByte()"
- : Esc(field.name);
+ ? "(if(" + namer_.Field(field) + ") 1 else 0).toByte()"
+ : namer_.Field(field);
auto setter_index =
value_base_type == BASE_TYPE_VECTOR
@@ -1285,9 +1362,9 @@ class KotlinGenerator : public BaseGenerator {
}
}
- static void GenerateGetRootAsAccessors(const std::string &struct_name,
- CodeWriter &writer,
- IDLOptions options) {
+ void GenerateGetRootAsAccessors(const std::string &struct_name,
+ CodeWriter &writer,
+ IDLOptions options) const {
// Generate a special accessor for the table that when used as the root
// ex: fun getRootAsMonster(_bb: ByteBuffer): Monster {...}
writer.SetValue("gr_name", struct_name);
@@ -1313,13 +1390,12 @@ class KotlinGenerator : public BaseGenerator {
writer += "}";
}
- static void GenerateStaticConstructor(const StructDef &struct_def,
- CodeWriter &code,
- const IDLOptions options) {
+ void GenerateStaticConstructor(const StructDef &struct_def, CodeWriter &code,
+ const IDLOptions options) const {
// create a struct constructor function
auto params = StructConstructorParams(struct_def);
GenerateFun(
- code, "create" + Esc(struct_def.name), params, "Int",
+ code, namer_.LegacyJavaMethod2("create", struct_def, ""), params, "Int",
[&]() {
GenStructBody(struct_def, code, "");
code += "return builder.offset()";
@@ -1327,8 +1403,8 @@ class KotlinGenerator : public BaseGenerator {
options.gen_jvmstatic);
}
- static std::string StructConstructorParams(const StructDef &struct_def,
- const std::string &prefix = "") {
+ std::string StructConstructorParams(const StructDef &struct_def,
+ const std::string &prefix = "") const {
// builder: FlatBufferBuilder
std::stringstream out;
auto field_vec = struct_def.fields.vec;
@@ -1341,9 +1417,9 @@ class KotlinGenerator : public BaseGenerator {
// constructing a nested struct, prefix the name with the field
// name.
out << StructConstructorParams(*field.value.type.struct_def,
- prefix + (Esc(field.name) + "_"));
+ prefix + (namer_.Variable(field) + "_"));
} else {
- out << ", " << prefix << MakeCamel(Esc(field.name), false) << ": "
+ out << ", " << prefix << namer_.Variable(field) << ": "
<< GenTypeBasic(field.value.type.base_type);
}
}
@@ -1513,9 +1589,7 @@ class KotlinGenerator : public BaseGenerator {
if (gen_jvmstatic) { code += "@JvmStatic"; }
}
- // This tracks the current namespace used to determine if a type need to be
- // prefixed by its namespace
- const Namespace *cur_name_space_;
+ const IdlNamer namer_;
};
} // namespace kotlin
@@ -1524,4 +1598,61 @@ bool GenerateKotlin(const Parser &parser, const std::string &path,
kotlin::KotlinGenerator generator(parser, path, file_name);
return generator.generate();
}
+
+namespace {
+
+class KotlinCodeGenerator : public CodeGenerator {
+ public:
+ Status GenerateCode(const Parser &parser, const std::string &path,
+ const std::string &filename) override {
+ if (!GenerateKotlin(parser, path, filename)) { return Status::ERROR; }
+ return Status::OK;
+ }
+
+ Status GenerateCode(const uint8_t *buffer, int64_t length) override {
+ (void)buffer;
+ (void)length;
+ return Status::NOT_IMPLEMENTED;
+ }
+
+ Status GenerateMakeRule(const Parser &parser, const std::string &path,
+ const std::string &filename,
+ std::string &output) override {
+ (void)parser;
+ (void)path;
+ (void)filename;
+ (void)output;
+ return Status::NOT_IMPLEMENTED;
+ }
+
+ Status GenerateGrpcCode(const Parser &parser, const std::string &path,
+ const std::string &filename) override {
+ (void)parser;
+ (void)path;
+ (void)filename;
+ return Status::NOT_IMPLEMENTED;
+ }
+
+ Status GenerateRootFile(const Parser &parser,
+ const std::string &path) override {
+ (void)parser;
+ (void)path;
+ return Status::NOT_IMPLEMENTED;
+ }
+ bool IsSchemaOnly() const override { return true; }
+
+ bool SupportsBfbsGeneration() const override { return false; }
+
+ bool SupportsRootFileGeneration() const override { return false; }
+
+ IDLOptions::Language Language() const override { return IDLOptions::kKotlin; }
+
+ std::string LanguageName() const override { return "Kotlin"; }
+};
+} // namespace
+
+std::unique_ptr<CodeGenerator> NewKotlinCodeGenerator() {
+ return std::unique_ptr<KotlinCodeGenerator>(new KotlinCodeGenerator());
+}
+
} // namespace flatbuffers