diff options
author | reshilkin <reshilkin@yandex-team.com> | 2023-08-11 12:01:29 +0300 |
---|---|---|
committer | reshilkin <reshilkin@yandex-team.com> | 2023-08-11 13:00:03 +0300 |
commit | 5894c3ce50a49a9f9bc1c0316e2ef0708e3a7ef8 (patch) | |
tree | 624e56690fe689e569d05612fa0e92f2c5bdb75b /contrib/libs/flatbuffers/src/idl_gen_kotlin.cpp | |
parent | 1eb895279c52b0d2505a31b79ad326b56d0b2681 (diff) | |
download | ydb-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.cpp | 351 |
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 |