Add basic Kotlin support (#5409)

* [Kotlin] Add kotlin generate code for tests and add
kotlin test to TestAll.sh

* [Kotlin] Add Kotlin generator

This change adds support for generating Kotlin classes.

The approach of this generator is to keep it as close
as possible to the java generator for now, in order
to keep the change simple.

It uses the already implemented java runtime,
so we don't support cross-platform nor js Kotlin yet.

Kotlin tests are just a copy of the java tests.

* Add optional ident support for CodeWriter

Identation is important for some languages and
different projects have different ways of ident
code, e.g. tabs vs spaces, so we are adding optional
support on CodeWriter for identation.

* [Kotlin] Add Documentation for Kotlin

* [Kotlin] Modify generated code to use experimental Unsigned types.
This commit is contained in:
Paulo Pinheiro
2019-07-22 20:05:15 -03:00
committed by Wouter van Oortmerssen
parent a752d1b88c
commit de9aa0cdee
54 changed files with 4995 additions and 64 deletions

View File

@@ -26,7 +26,7 @@ namespace flatbuffers {
// Utility class to assist in generating code through use of text templates.
//
// Example code:
// CodeWriter code;
// CodeWriter code("\t");
// code.SetValue("NAME", "Foo");
// code += "void {{NAME}}() { printf("%s", "{{NAME}}"); }";
// code.SetValue("NAME", "Bar");
@@ -38,7 +38,8 @@ namespace flatbuffers {
// void Bar() { printf("%s", "Bar"); }
class CodeWriter {
public:
CodeWriter() {}
CodeWriter(std::string pad = std::string())
: pad_(pad), cur_ident_lvl_(0), ignore_ident_(false) {}
// Clears the current "written" code.
void Clear() {
@@ -67,9 +68,22 @@ class CodeWriter {
// Returns the current contents of the CodeWriter as a std::string.
std::string ToString() const { return stream_.str(); }
// Increase ident level for writing code
void IncrementIdentLevel() { cur_ident_lvl_++; }
// Decrease ident level for writing code
void DecrementIdentLevel() {
if (cur_ident_lvl_) cur_ident_lvl_--;
}
private:
std::map<std::string, std::string> value_map_;
std::stringstream stream_;
std::string pad_;
int cur_ident_lvl_;
bool ignore_ident_;
// Add ident padding (tab or space) based on ident level
void AppendIdent(std::stringstream &stream);
};
class BaseGenerator {

View File

@@ -47,26 +47,26 @@ namespace flatbuffers {
// of type tokens.
// clang-format off
#define FLATBUFFERS_GEN_TYPES_SCALAR(TD) \
TD(NONE, "", uint8_t, byte, byte, byte, uint8, u8) \
TD(UTYPE, "", uint8_t, byte, byte, byte, uint8, u8) /* begin scalar/int */ \
TD(BOOL, "bool", uint8_t, boolean,bool, bool, bool, bool) \
TD(CHAR, "byte", int8_t, byte, int8, sbyte, int8, i8) \
TD(UCHAR, "ubyte", uint8_t, byte, byte, byte, uint8, u8) \
TD(SHORT, "short", int16_t, short, int16, short, int16, i16) \
TD(USHORT, "ushort", uint16_t, short, uint16, ushort, uint16, u16) \
TD(INT, "int", int32_t, int, int32, int, int32, i32) \
TD(UINT, "uint", uint32_t, int, uint32, uint, uint32, u32) \
TD(LONG, "long", int64_t, long, int64, long, int64, i64) \
TD(ULONG, "ulong", uint64_t, long, uint64, ulong, uint64, u64) /* end int */ \
TD(FLOAT, "float", float, float, float32, float, float32, f32) /* begin float */ \
TD(DOUBLE, "double", double, double, float64, double, float64, f64) /* end float/scalar */
TD(NONE, "", uint8_t, byte, byte, byte, uint8, u8, UByte) \
TD(UTYPE, "", uint8_t, byte, byte, byte, uint8, u8, UByte) /* begin scalar/int */ \
TD(BOOL, "bool", uint8_t, boolean,bool, bool, bool, bool, Boolean) \
TD(CHAR, "byte", int8_t, byte, int8, sbyte, int8, i8, Byte) \
TD(UCHAR, "ubyte", uint8_t, byte, byte, byte, uint8, u8, UByte) \
TD(SHORT, "short", int16_t, short, int16, short, int16, i16, Short) \
TD(USHORT, "ushort", uint16_t, short, uint16, ushort, uint16, u16, UShort) \
TD(INT, "int", int32_t, int, int32, int, int32, i32, Int) \
TD(UINT, "uint", uint32_t, int, uint32, uint, uint32, u32, UInt) \
TD(LONG, "long", int64_t, long, int64, long, int64, i64, Long) \
TD(ULONG, "ulong", uint64_t, long, uint64, ulong, uint64, u64, ULong) /* end int */ \
TD(FLOAT, "float", float, float, float32, float, float32, f32, Float) /* begin float */ \
TD(DOUBLE, "double", double, double, float64, double, float64, f64, Double) /* end float/scalar */
#define FLATBUFFERS_GEN_TYPES_POINTER(TD) \
TD(STRING, "string", Offset<void>, int, int, StringOffset, int, unused) \
TD(VECTOR, "", Offset<void>, int, int, VectorOffset, int, unused) \
TD(STRUCT, "", Offset<void>, int, int, int, int, unused) \
TD(UNION, "", Offset<void>, int, int, int, int, unused)
TD(STRING, "string", Offset<void>, int, int, StringOffset, int, unused, Int) \
TD(VECTOR, "", Offset<void>, int, int, VectorOffset, int, unused, Int) \
TD(STRUCT, "", Offset<void>, int, int, int, int, unused, Int) \
TD(UNION, "", Offset<void>, int, int, int, int, unused, Int)
#define FLATBUFFERS_GEN_TYPE_ARRAY(TD) \
TD(ARRAY, "", int, int, int, int, int, unused)
TD(ARRAY, "", int, int, int, int, int, unused, Int)
// The fields are:
// - enum
// - FlatBuffers schema type.
@@ -76,13 +76,14 @@ namespace flatbuffers {
// - C# / .Net type.
// - Python type.
// - Rust type.
// - Kotlin type.
// using these macros, we can now write code dealing with types just once, e.g.
/*
switch (type) {
#define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE, JTYPE, GTYPE, NTYPE, PTYPE, \
RTYPE) \
RTYPE, KTYPE) \
case BASE_TYPE_ ## ENUM: \
// do something specific to CTYPE here
FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD)
@@ -101,14 +102,14 @@ __extension__ // Stop GCC complaining about trailing comma with -Wpendantic.
#endif
enum BaseType {
#define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE, JTYPE, GTYPE, NTYPE, PTYPE, \
RTYPE) \
RTYPE, KTYPE) \
BASE_TYPE_ ## ENUM,
FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD)
#undef FLATBUFFERS_TD
};
#define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE, JTYPE, GTYPE, NTYPE, PTYPE, \
RTYPE) \
RTYPE, KTYPE) \
static_assert(sizeof(CTYPE) <= sizeof(largest_scalar_t), \
"define largest_scalar_t as " #CTYPE);
FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD)
@@ -546,6 +547,7 @@ struct IDLOptions {
kLua = 1 << 12,
kLobster = 1 << 13,
kRust = 1 << 14,
kKotlin = 1 << 15,
kMAX
};
@@ -1009,6 +1011,9 @@ extern bool GenerateJsonSchema(const Parser &parser,
const std::string &path,
const std::string &file_name);
extern bool GenerateKotlin(const Parser &parser, const std::string &path,
const std::string &file_name);
// Generate Java/C#/.. files from the definitions in the Parser object.
// See idl_gen_general.cpp.
extern bool GenerateGeneral(const Parser &parser,