mirror of
https://github.com/google/flatbuffers.git
synced 2026-06-15 00:38:52 +00:00
[TS] GRPC Implementation (#6141)
* GRPC implementation for Typescript * Fixes a couple of issues * Finished implementing the typescript support for grpc * Updated generated code * Fixes CI
This commit is contained in:
@@ -71,5 +71,6 @@ cc_library(
|
||||
"//grpc/src/compiler:java_generator",
|
||||
"//grpc/src/compiler:python_generator",
|
||||
"//grpc/src/compiler:swift_generator",
|
||||
"//grpc/src/compiler:ts_generator",
|
||||
],
|
||||
)
|
||||
|
||||
@@ -78,8 +78,8 @@ int main(int argc, const char *argv[]) {
|
||||
{ flatbuffers::GenerateDart, "-d", "--dart", "Dart", true, nullptr,
|
||||
flatbuffers::IDLOptions::kDart,
|
||||
"Generate Dart classes for tables/structs", flatbuffers::DartMakeRule },
|
||||
{ flatbuffers::GenerateJSTS, "-T", "--ts", "TypeScript", true, nullptr,
|
||||
flatbuffers::IDLOptions::kTs,
|
||||
{ flatbuffers::GenerateJSTS, "-T", "--ts", "TypeScript", true,
|
||||
flatbuffers::GenerateTSGRPC, flatbuffers::IDLOptions::kTs,
|
||||
"Generate TypeScript code for tables/structs",
|
||||
flatbuffers::JSTSMakeRule },
|
||||
{ flatbuffers::GenerateCSharp, "-n", "--csharp", "C#", true, nullptr,
|
||||
|
||||
@@ -1714,9 +1714,7 @@ class CppGenerator : public BaseGenerator {
|
||||
auto native_default = field.attributes.Lookup("native_default");
|
||||
// Scalar types get parsed defaults, raw pointers get nullptrs.
|
||||
if (IsScalar(field.value.type.base_type)) {
|
||||
if (!initializer_list.empty()) {
|
||||
initializer_list += ",\n ";
|
||||
}
|
||||
if (!initializer_list.empty()) { initializer_list += ",\n "; }
|
||||
initializer_list += Name(field);
|
||||
initializer_list +=
|
||||
"(" +
|
||||
@@ -1992,8 +1990,7 @@ class CppGenerator : public BaseGenerator {
|
||||
code_ += " {{FIELD_TYPE}}{{FIELD_NAME}}() const {";
|
||||
code_ += " return {{FIELD_VALUE}};";
|
||||
code_ += " }";
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
auto wire_type = GenTypeBasic(type, false);
|
||||
auto face_type = GenTypeBasic(type, true);
|
||||
auto opt_value = "GetOptional<" + wire_type + ", " + face_type + ">(" +
|
||||
@@ -2011,7 +2008,7 @@ class CppGenerator : public BaseGenerator {
|
||||
const auto &type = field.value.type;
|
||||
const bool is_scalar = IsScalar(type.base_type);
|
||||
if (is_scalar && IsUnion(type))
|
||||
return; // changing of a union's type is forbidden
|
||||
return; // changing of a union's type is forbidden
|
||||
|
||||
auto offset_str = GenFieldOffsetName(field);
|
||||
if (is_scalar) {
|
||||
@@ -2109,9 +2106,7 @@ class CppGenerator : public BaseGenerator {
|
||||
|
||||
code_.SetValue("FIELD_NAME", Name(field));
|
||||
GenTableFieldGetter(field);
|
||||
if (opts_.mutable_buffer) {
|
||||
GenTableFieldSetter(field);
|
||||
}
|
||||
if (opts_.mutable_buffer) { GenTableFieldSetter(field); }
|
||||
|
||||
auto nested = field.attributes.Lookup("nested_flatbuffer");
|
||||
if (nested) {
|
||||
@@ -2252,8 +2247,7 @@ class CppGenerator : public BaseGenerator {
|
||||
for (auto it = struct_def.fields.vec.begin();
|
||||
it != struct_def.fields.vec.end(); ++it) {
|
||||
const auto &field = **it;
|
||||
if (field.deprecated)
|
||||
continue;
|
||||
if (field.deprecated) continue;
|
||||
const bool is_scalar = IsScalar(field.value.type.base_type);
|
||||
const bool is_default_scalar = is_scalar && !field.IsScalarOptional();
|
||||
const bool is_string = field.value.type.base_type == BASE_TYPE_STRING;
|
||||
@@ -2813,15 +2807,17 @@ class CppGenerator : public BaseGenerator {
|
||||
code_ +=
|
||||
"inline " + TableUnPackSignature(struct_def, false, opts_) + " {";
|
||||
|
||||
if(opts_.g_cpp_std == cpp::CPP_STD_X0) {
|
||||
if (opts_.g_cpp_std == cpp::CPP_STD_X0) {
|
||||
auto native_name =
|
||||
NativeName(WrapInNameSpace(struct_def), &struct_def, parser_.opts);
|
||||
code_.SetValue("POINTER_TYPE",
|
||||
GenTypeNativePtr(native_name, nullptr, false));
|
||||
code_ +=
|
||||
" {{POINTER_TYPE}} _o = {{POINTER_TYPE}}(new {{NATIVE_NAME}}());";
|
||||
} else if(opts_.g_cpp_std == cpp::CPP_STD_11) {
|
||||
code_ += " auto _o = std::unique_ptr<{{NATIVE_NAME}}>(new {{NATIVE_NAME}}());";
|
||||
} else if (opts_.g_cpp_std == cpp::CPP_STD_11) {
|
||||
code_ +=
|
||||
" auto _o = std::unique_ptr<{{NATIVE_NAME}}>(new "
|
||||
"{{NATIVE_NAME}}());";
|
||||
} else {
|
||||
code_ += " auto _o = std::make_unique<{{NATIVE_NAME}}>();";
|
||||
}
|
||||
@@ -2958,8 +2954,7 @@ class CppGenerator : public BaseGenerator {
|
||||
int padding_initializer_id = 0;
|
||||
int padding_body_id = 0;
|
||||
for (auto it = struct_def.fields.vec.begin();
|
||||
it != struct_def.fields.vec.end();
|
||||
++it) {
|
||||
it != struct_def.fields.vec.end(); ++it) {
|
||||
const auto field = *it;
|
||||
const auto field_name = field->name + "_";
|
||||
|
||||
|
||||
@@ -486,8 +486,7 @@ class DartGenerator : public BaseGenerator {
|
||||
auto &part = *it;
|
||||
|
||||
for (size_t i = 0; i < part.length(); i++) {
|
||||
if (i && !isdigit(part[i]) &&
|
||||
part[i] == CharToUpper(part[i])) {
|
||||
if (i && !isdigit(part[i]) && part[i] == CharToUpper(part[i])) {
|
||||
ns += "_";
|
||||
ns += CharToLower(part[i]);
|
||||
} else {
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#include "src/compiler/python_generator.h"
|
||||
#include "src/compiler/python_private_generator.h"
|
||||
#include "src/compiler/swift_generator.h"
|
||||
#include "src/compiler/ts_generator.h"
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
# pragma warning(push)
|
||||
@@ -206,7 +207,8 @@ class FlatBufFile : public grpc_generator::File {
|
||||
kLanguageCpp,
|
||||
kLanguageJava,
|
||||
kLanguagePython,
|
||||
kLanguageSwift
|
||||
kLanguageSwift,
|
||||
kLanguageTS
|
||||
};
|
||||
|
||||
FlatBufFile(const Parser &parser, const std::string &file_name,
|
||||
@@ -258,6 +260,9 @@ class FlatBufFile : public grpc_generator::File {
|
||||
case kLanguageSwift: {
|
||||
return "";
|
||||
}
|
||||
case kLanguageTS: {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
@@ -467,6 +472,54 @@ bool GenerateSwiftGRPC(const Parser &parser, const std::string &path,
|
||||
return SwiftGRPCGenerator(parser, path, file_name).generate();
|
||||
}
|
||||
|
||||
class TSGRPCGenerator : public flatbuffers::BaseGenerator {
|
||||
private:
|
||||
CodeWriter code_;
|
||||
|
||||
public:
|
||||
TSGRPCGenerator(const Parser &parser, const std::string &path,
|
||||
const std::string &filename)
|
||||
: BaseGenerator(parser, path, filename, "", "" /*Unused*/, "ts") {}
|
||||
|
||||
bool generate() {
|
||||
code_.Clear();
|
||||
FlatBufFile file(parser_, file_name_, FlatBufFile::kLanguageTS);
|
||||
|
||||
for (int i = 0; i < file.service_count(); i++) {
|
||||
auto service = file.service(i);
|
||||
code_ += grpc_ts_generator::Generate(&file, service.get(), file_name_);
|
||||
const auto ts_name = GeneratedFileName(path_, file_name_);
|
||||
if (!SaveFile(ts_name.c_str(), code_.ToString(), false)) return false;
|
||||
|
||||
code_.Clear();
|
||||
code_ += grpc_ts_generator::GenerateInterface(&file, service.get(),
|
||||
file_name_);
|
||||
const auto ts_interface_name = GeneratedFileName(path_, file_name_, true);
|
||||
if (!SaveFile(ts_interface_name.c_str(), code_.ToString(), false))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static std::string GeneratedFileName(const std::string &path,
|
||||
const std::string &file_name,
|
||||
const bool is_interface = false) {
|
||||
if (is_interface) return path + file_name + "_grpc.d.ts";
|
||||
return path + file_name + "_grpc.js";
|
||||
}
|
||||
};
|
||||
|
||||
bool GenerateTSGRPC(const Parser &parser, const std::string &path,
|
||||
const std::string &file_name) {
|
||||
int nservices = 0;
|
||||
for (auto it = parser.services_.vec.begin(); it != parser.services_.vec.end();
|
||||
++it) {
|
||||
if (!(*it)->generated) nservices++;
|
||||
}
|
||||
if (!nservices) return true;
|
||||
return TSGRPCGenerator(parser, path, file_name).generate();
|
||||
}
|
||||
|
||||
} // namespace flatbuffers
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
|
||||
@@ -141,7 +141,8 @@ class JsTsGenerator : public BaseGenerator {
|
||||
const auto &file = *it;
|
||||
const auto basename =
|
||||
flatbuffers::StripPath(flatbuffers::StripExtension(file.first));
|
||||
if (basename != file_name_ && imported.find(file.second.symbol) == imported.end()) {
|
||||
if (basename != file_name_ &&
|
||||
imported.find(file.second.symbol) == imported.end()) {
|
||||
if (imported_files.find(file.first) == imported_files.end()) {
|
||||
code += GenPrefixedImport(file.first, basename);
|
||||
imported_files.emplace(file.first);
|
||||
@@ -225,9 +226,7 @@ class JsTsGenerator : public BaseGenerator {
|
||||
for (auto it = sorted_namespaces.begin(); it != sorted_namespaces.end();
|
||||
++it) {
|
||||
if (lang_.language == IDLOptions::kTs) {
|
||||
if (it->find('.') == std::string::npos) {
|
||||
break;
|
||||
}
|
||||
if (it->find('.') == std::string::npos) { break; }
|
||||
} else {
|
||||
code += "/**\n * @const\n * @namespace\n */\n";
|
||||
if (it->find('.') == std::string::npos) {
|
||||
@@ -992,8 +991,8 @@ class JsTsGenerator : public BaseGenerator {
|
||||
std::string constructor_func = "constructor(";
|
||||
constructor_func += (struct_def.fields.vec.empty() ? "" : "\n");
|
||||
|
||||
|
||||
const auto has_create = struct_def.fixed || CanCreateFactoryMethod(struct_def);
|
||||
const auto has_create =
|
||||
struct_def.fixed || CanCreateFactoryMethod(struct_def);
|
||||
|
||||
std::string pack_func_prototype =
|
||||
"/**\n * " +
|
||||
@@ -1004,14 +1003,13 @@ class JsTsGenerator : public BaseGenerator {
|
||||
std::string pack_func_offset_decl;
|
||||
std::string pack_func_create_call;
|
||||
|
||||
const auto struct_name = GenPrefixedTypeName(WrapInNameSpace(struct_def), struct_def.file);
|
||||
const auto struct_name =
|
||||
GenPrefixedTypeName(WrapInNameSpace(struct_def), struct_def.file);
|
||||
|
||||
if (has_create) {
|
||||
pack_func_create_call =
|
||||
" return " +
|
||||
struct_name +
|
||||
".create" + Verbose(struct_def) + "(builder" +
|
||||
(struct_def.fields.vec.empty() ? "" : ",\n ");
|
||||
pack_func_create_call = " return " + struct_name + ".create" +
|
||||
Verbose(struct_def) + "(builder" +
|
||||
(struct_def.fields.vec.empty() ? "" : ",\n ");
|
||||
} else {
|
||||
pack_func_create_call = " " + struct_name + ".start(builder);\n";
|
||||
}
|
||||
@@ -1231,7 +1229,9 @@ class JsTsGenerator : public BaseGenerator {
|
||||
if (has_create) {
|
||||
pack_func_create_call += field_offset_val;
|
||||
} else {
|
||||
pack_func_create_call += " " + struct_name + ".add" + MakeCamel(field.name) + "(builder, " + field_offset_val + ");\n";
|
||||
pack_func_create_call += " " + struct_name + ".add" +
|
||||
MakeCamel(field.name) + "(builder, " +
|
||||
field_offset_val + ");\n";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1239,7 +1239,9 @@ class JsTsGenerator : public BaseGenerator {
|
||||
constructor_annotation += "\n";
|
||||
constructor_func += ",\n";
|
||||
|
||||
if (!struct_def.fixed && has_create) { pack_func_create_call += ",\n "; }
|
||||
if (!struct_def.fixed && has_create) {
|
||||
pack_func_create_call += ",\n ";
|
||||
}
|
||||
|
||||
unpack_func += ",\n";
|
||||
unpack_to_func += "\n";
|
||||
@@ -1698,11 +1700,12 @@ class JsTsGenerator : public BaseGenerator {
|
||||
|
||||
if (struct_def.fixed) {
|
||||
code += " " + GenBBAccess() + ".write" +
|
||||
MakeCamel(GenType(field.value.type)) +
|
||||
"(this.bb_pos + " + NumToString(field.value.offset) + ", ";
|
||||
MakeCamel(GenType(field.value.type)) + "(this.bb_pos + " +
|
||||
NumToString(field.value.offset) + ", ";
|
||||
} else {
|
||||
code += " var offset = " + GenBBAccess() + ".__offset(this.bb_pos, " +
|
||||
NumToString(field.value.offset) + ");\n\n";
|
||||
code += " var offset = " + GenBBAccess() +
|
||||
".__offset(this.bb_pos, " + NumToString(field.value.offset) +
|
||||
");\n\n";
|
||||
code += " if (offset === 0) {\n";
|
||||
code += " return false;\n";
|
||||
code += " }\n\n";
|
||||
@@ -2063,6 +2066,21 @@ class JsTsGenerator : public BaseGenerator {
|
||||
}
|
||||
}
|
||||
|
||||
if (!struct_def.fixed && parser_.services_.vec.size() != 0 &&
|
||||
lang_.language == IDLOptions::kTs) {
|
||||
auto name = Verbose(struct_def, "");
|
||||
code += "\n";
|
||||
code += "serialize():Uint8Array {\n";
|
||||
code += " return this.bb!.bytes();\n";
|
||||
code += "}\n";
|
||||
|
||||
code += "\n";
|
||||
code += "static deserialize(buffer: Uint8Array):"+ name +" {\n";
|
||||
code += " return " + name + ".getRootAs" + name +
|
||||
"(new flatbuffers.ByteBuffer(buffer))\n";
|
||||
code += "}\n";
|
||||
}
|
||||
|
||||
if (lang_.language == IDLOptions::kTs) {
|
||||
if (parser_.opts.generate_object_based_api) {
|
||||
std::string obj_api_class;
|
||||
|
||||
@@ -303,12 +303,15 @@ class KotlinGenerator : public BaseGenerator {
|
||||
}
|
||||
writer += ")";
|
||||
});
|
||||
GenerateFunOneLine(writer, "name", "e: Int", "String", [&]() {
|
||||
writer += "names[e\\";
|
||||
if (enum_def.MinValue()->IsNonZero())
|
||||
writer += " - " + enum_def.MinValue()->name + ".toInt()\\";
|
||||
writer += "]";
|
||||
}, parser_.opts.gen_jvmstatic);
|
||||
GenerateFunOneLine(
|
||||
writer, "name", "e: Int", "String",
|
||||
[&]() {
|
||||
writer += "names[e\\";
|
||||
if (enum_def.MinValue()->IsNonZero())
|
||||
writer += " - " + enum_def.MinValue()->name + ".toInt()\\";
|
||||
writer += "]";
|
||||
},
|
||||
parser_.opts.gen_jvmstatic);
|
||||
}
|
||||
});
|
||||
writer.DecrementIdentLevel();
|
||||
@@ -449,7 +452,8 @@ class KotlinGenerator : public BaseGenerator {
|
||||
return key_offset;
|
||||
}
|
||||
|
||||
void GenStruct(StructDef &struct_def, CodeWriter &writer, IDLOptions options) const {
|
||||
void GenStruct(StructDef &struct_def, CodeWriter &writer,
|
||||
IDLOptions options) const {
|
||||
if (struct_def.generated) return;
|
||||
|
||||
GenerateComment(struct_def.doc_comment, writer, &comment_config);
|
||||
@@ -488,9 +492,10 @@ class KotlinGenerator : public BaseGenerator {
|
||||
// Generate verson check method.
|
||||
// Force compile time error if not using the same version
|
||||
// runtime.
|
||||
GenerateFunOneLine(writer, "validateVersion", "", "", [&]() {
|
||||
writer += "Constants.FLATBUFFERS_1_12_0()";
|
||||
}, options.gen_jvmstatic);
|
||||
GenerateFunOneLine(
|
||||
writer, "validateVersion", "", "",
|
||||
[&]() { writer += "Constants.FLATBUFFERS_1_12_0()"; },
|
||||
options.gen_jvmstatic);
|
||||
|
||||
GenerateGetRootAsAccessors(Esc(struct_def.name), writer, options);
|
||||
GenerateBufferHasIdentifier(struct_def, writer, options);
|
||||
@@ -520,8 +525,10 @@ class KotlinGenerator : public BaseGenerator {
|
||||
GenerateEndStructMethod(struct_def, writer, options);
|
||||
auto file_identifier = parser_.file_identifier_;
|
||||
if (parser_.root_struct_def_ == &struct_def) {
|
||||
GenerateFinishStructBuffer(struct_def, file_identifier, writer, options);
|
||||
GenerateFinishSizePrefixed(struct_def, file_identifier, writer, options);
|
||||
GenerateFinishStructBuffer(struct_def, file_identifier, writer,
|
||||
options);
|
||||
GenerateFinishSizePrefixed(struct_def, file_identifier, writer,
|
||||
options);
|
||||
}
|
||||
|
||||
if (struct_def.has_key) {
|
||||
@@ -606,9 +613,10 @@ class KotlinGenerator : public BaseGenerator {
|
||||
auto id = identifier.length() > 0 ? ", \"" + identifier + "\"" : "";
|
||||
auto params = "builder: FlatBufferBuilder, offset: Int";
|
||||
auto method_name = "finishSizePrefixed" + Esc(struct_def.name) + "Buffer";
|
||||
GenerateFunOneLine(writer, method_name, params, "", [&]() {
|
||||
writer += "builder.finishSizePrefixed(offset" + id + ")";
|
||||
}, options.gen_jvmstatic);
|
||||
GenerateFunOneLine(
|
||||
writer, method_name, params, "",
|
||||
[&]() { writer += "builder.finishSizePrefixed(offset" + id + ")"; },
|
||||
options.gen_jvmstatic);
|
||||
}
|
||||
void GenerateFinishStructBuffer(StructDef &struct_def,
|
||||
const std::string &identifier,
|
||||
@@ -617,9 +625,10 @@ class KotlinGenerator : public BaseGenerator {
|
||||
auto id = identifier.length() > 0 ? ", \"" + identifier + "\"" : "";
|
||||
auto params = "builder: FlatBufferBuilder, offset: Int";
|
||||
auto method_name = "finish" + Esc(struct_def.name) + "Buffer";
|
||||
GenerateFunOneLine(writer, method_name, params, "",
|
||||
[&]() { writer += "builder.finish(offset" + id + ")"; },
|
||||
options.gen_jvmstatic);
|
||||
GenerateFunOneLine(
|
||||
writer, method_name, params, "",
|
||||
[&]() { writer += "builder.finish(offset" + id + ")"; },
|
||||
options.gen_jvmstatic);
|
||||
}
|
||||
|
||||
void GenerateEndStructMethod(StructDef &struct_def, CodeWriter &writer,
|
||||
@@ -630,18 +639,21 @@ class KotlinGenerator : public BaseGenerator {
|
||||
auto returns = "Int";
|
||||
auto field_vec = struct_def.fields.vec;
|
||||
|
||||
GenerateFun(writer, name, params, returns, [&]() {
|
||||
writer += "val o = builder.endTable()";
|
||||
writer.IncrementIdentLevel();
|
||||
for (auto it = field_vec.begin(); it != field_vec.end(); ++it) {
|
||||
auto &field = **it;
|
||||
if (field.deprecated || !field.required) { continue; }
|
||||
writer.SetValue("offset", NumToString(field.value.offset));
|
||||
writer += "builder.required(o, {{offset}})";
|
||||
}
|
||||
writer.DecrementIdentLevel();
|
||||
writer += "return o";
|
||||
}, options.gen_jvmstatic);
|
||||
GenerateFun(
|
||||
writer, name, params, returns,
|
||||
[&]() {
|
||||
writer += "val o = builder.endTable()";
|
||||
writer.IncrementIdentLevel();
|
||||
for (auto it = field_vec.begin(); it != field_vec.end(); ++it) {
|
||||
auto &field = **it;
|
||||
if (field.deprecated || !field.required) { continue; }
|
||||
writer.SetValue("offset", NumToString(field.value.offset));
|
||||
writer += "builder.required(o, {{offset}})";
|
||||
}
|
||||
writer.DecrementIdentLevel();
|
||||
writer += "return o";
|
||||
},
|
||||
options.gen_jvmstatic);
|
||||
}
|
||||
|
||||
// Generate a method to create a vector from a Kotlin array.
|
||||
@@ -656,15 +668,18 @@ class KotlinGenerator : public BaseGenerator {
|
||||
writer.SetValue("root", GenMethod(vector_type));
|
||||
writer.SetValue("cast", CastToSigned(vector_type));
|
||||
|
||||
GenerateFun(writer, method_name, params, "Int", [&]() {
|
||||
writer += "builder.startVector({{size}}, data.size, {{align}})";
|
||||
writer += "for (i in data.size - 1 downTo 0) {";
|
||||
writer.IncrementIdentLevel();
|
||||
writer += "builder.add{{root}}(data[i]{{cast}})";
|
||||
writer.DecrementIdentLevel();
|
||||
writer += "}";
|
||||
writer += "return builder.endVector()";
|
||||
}, options.gen_jvmstatic);
|
||||
GenerateFun(
|
||||
writer, method_name, params, "Int",
|
||||
[&]() {
|
||||
writer += "builder.startVector({{size}}, data.size, {{align}})";
|
||||
writer += "for (i in data.size - 1 downTo 0) {";
|
||||
writer.IncrementIdentLevel();
|
||||
writer += "builder.add{{root}}(data[i]{{cast}})";
|
||||
writer.DecrementIdentLevel();
|
||||
writer += "}";
|
||||
writer += "return builder.endVector()";
|
||||
},
|
||||
options.gen_jvmstatic);
|
||||
}
|
||||
|
||||
void GenerateStartVectorField(FieldDef &field, CodeWriter &writer,
|
||||
@@ -678,9 +693,11 @@ class KotlinGenerator : public BaseGenerator {
|
||||
|
||||
GenerateFunOneLine(
|
||||
writer, "start" + MakeCamel(Esc(field.name) + "Vector", true), params,
|
||||
"", [&]() {
|
||||
"",
|
||||
[&]() {
|
||||
writer += "builder.startVector({{size}}, numElems, {{align}})";
|
||||
}, options.gen_jvmstatic);
|
||||
},
|
||||
options.gen_jvmstatic);
|
||||
}
|
||||
|
||||
void GenerateAddField(std::string field_pos, FieldDef &field,
|
||||
@@ -745,12 +762,13 @@ class KotlinGenerator : public BaseGenerator {
|
||||
// fun startMonster(builder: FlatBufferBuilder) = builder.startTable(11)
|
||||
void GenerateStartStructMethod(StructDef &struct_def, CodeWriter &code,
|
||||
const IDLOptions options) const {
|
||||
GenerateFunOneLine(code, "start" + Esc(struct_def.name),
|
||||
"builder: FlatBufferBuilder", "", [&]() {
|
||||
code += "builder.startTable(" +
|
||||
NumToString(struct_def.fields.vec.size()) +
|
||||
")";
|
||||
}, options.gen_jvmstatic);
|
||||
GenerateFunOneLine(
|
||||
code, "start" + Esc(struct_def.name), "builder: FlatBufferBuilder", "",
|
||||
[&]() {
|
||||
code += "builder.startTable(" +
|
||||
NumToString(struct_def.fields.vec.size()) + ")";
|
||||
},
|
||||
options.gen_jvmstatic);
|
||||
}
|
||||
|
||||
void GenerateTableCreator(StructDef &struct_def, CodeWriter &writer,
|
||||
@@ -793,51 +811,59 @@ class KotlinGenerator : public BaseGenerator {
|
||||
params << GenTypeBasic(field.value.type.base_type) << optional;
|
||||
}
|
||||
|
||||
GenerateFun(writer, name, params.str(), "Int", [&]() {
|
||||
writer.SetValue("vec_size", NumToString(fields_vec.size()));
|
||||
GenerateFun(
|
||||
writer, name, params.str(), "Int",
|
||||
[&]() {
|
||||
writer.SetValue("vec_size", NumToString(fields_vec.size()));
|
||||
|
||||
writer += "builder.startTable({{vec_size}})";
|
||||
writer += "builder.startTable({{vec_size}})";
|
||||
|
||||
auto sortbysize = struct_def.sortbysize;
|
||||
auto largest = sortbysize ? sizeof(largest_scalar_t) : 1;
|
||||
for (size_t size = largest; size; size /= 2) {
|
||||
for (auto it = fields_vec.rbegin(); it != fields_vec.rend(); ++it) {
|
||||
auto &field = **it;
|
||||
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));
|
||||
auto sortbysize = struct_def.sortbysize;
|
||||
auto largest = sortbysize ? sizeof(largest_scalar_t) : 1;
|
||||
for (size_t size = largest; size; size /= 2) {
|
||||
for (auto it = fields_vec.rbegin(); it != fields_vec.rend();
|
||||
++it) {
|
||||
auto &field = **it;
|
||||
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));
|
||||
|
||||
// we wrap on null check for scalar optionals
|
||||
writer +=
|
||||
field.IsScalarOptional() ? "{{field_name}}?.run { \\" : "\\";
|
||||
// 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 += "add{{camel_field_name}}(builder, {{field_name}}\\";
|
||||
if (!IsScalar(field.value.type.base_type)) {
|
||||
writer += "Offset\\";
|
||||
}
|
||||
// we wrap on null check for scalar optionals
|
||||
writer += field.IsScalarOptional() ? ") }" : ")";
|
||||
}
|
||||
}
|
||||
// we wrap on null check for scalar optionals
|
||||
writer += field.IsScalarOptional() ? ") }" : ")";
|
||||
}
|
||||
}
|
||||
}
|
||||
writer += "return end{{struct_name}}(builder)";
|
||||
}, options.gen_jvmstatic);
|
||||
writer += "return end{{struct_name}}(builder)";
|
||||
},
|
||||
options.gen_jvmstatic);
|
||||
}
|
||||
}
|
||||
void GenerateBufferHasIdentifier(StructDef &struct_def,
|
||||
CodeWriter &writer, IDLOptions options) const {
|
||||
void GenerateBufferHasIdentifier(StructDef &struct_def, CodeWriter &writer,
|
||||
IDLOptions options) const {
|
||||
auto file_identifier = parser_.file_identifier_;
|
||||
// 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);
|
||||
GenerateFunOneLine(writer, name + "BufferHasIdentifier", "_bb: ByteBuffer",
|
||||
"Boolean", [&]() {
|
||||
writer += "__has_identifier(_bb, \"" +
|
||||
file_identifier + "\")";
|
||||
}, options.gen_jvmstatic);
|
||||
GenerateFunOneLine(
|
||||
writer, name + "BufferHasIdentifier", "_bb: ByteBuffer", "Boolean",
|
||||
[&]() {
|
||||
writer += "__has_identifier(_bb, \"" + file_identifier + "\")";
|
||||
},
|
||||
options.gen_jvmstatic);
|
||||
}
|
||||
|
||||
void GenerateStructGetters(StructDef &struct_def, CodeWriter &writer) const {
|
||||
@@ -996,12 +1022,11 @@ class KotlinGenerator : public BaseGenerator {
|
||||
break;
|
||||
}
|
||||
case BASE_TYPE_UNION:
|
||||
GenerateFun(writer, field_name, "obj: " + field_type, return_type,
|
||||
[&]() {
|
||||
writer += OffsetWrapperOneLine(
|
||||
offset_val, bbgetter + "(obj, o + bb_pos)",
|
||||
"null");
|
||||
});
|
||||
GenerateFun(
|
||||
writer, field_name, "obj: " + field_type, return_type, [&]() {
|
||||
writer += OffsetWrapperOneLine(
|
||||
offset_val, bbgetter + "(obj, o + bb_pos)", "null");
|
||||
});
|
||||
break;
|
||||
default: FLATBUFFERS_ASSERT(0);
|
||||
}
|
||||
@@ -1293,10 +1318,13 @@ class KotlinGenerator : public BaseGenerator {
|
||||
const IDLOptions options) {
|
||||
// create a struct constructor function
|
||||
auto params = StructConstructorParams(struct_def);
|
||||
GenerateFun(code, "create" + Esc(struct_def.name), params, "Int", [&]() {
|
||||
GenStructBody(struct_def, code, "");
|
||||
code += "return builder.offset()";
|
||||
}, options.gen_jvmstatic);
|
||||
GenerateFun(
|
||||
code, "create" + Esc(struct_def.name), params, "Int",
|
||||
[&]() {
|
||||
GenStructBody(struct_def, code, "");
|
||||
code += "return builder.offset()";
|
||||
},
|
||||
options.gen_jvmstatic);
|
||||
}
|
||||
|
||||
static std::string StructConstructorParams(const StructDef &struct_def,
|
||||
@@ -1482,9 +1510,7 @@ class KotlinGenerator : public BaseGenerator {
|
||||
// Prepend @JvmStatic to methods in companion object.
|
||||
static void GenerateJvmStaticAnnotation(CodeWriter &code,
|
||||
bool gen_jvmstatic) {
|
||||
if (gen_jvmstatic) {
|
||||
code += "@JvmStatic";
|
||||
}
|
||||
if (gen_jvmstatic) { code += "@JvmStatic"; }
|
||||
}
|
||||
|
||||
// This tracks the current namespace used to determine if a type need to be
|
||||
|
||||
@@ -47,9 +47,7 @@ std::string MakeSnakeCase(const std::string &in) {
|
||||
// Convert a string to all uppercase.
|
||||
std::string MakeUpper(const std::string &in) {
|
||||
std::string s;
|
||||
for (size_t i = 0; i < in.length(); i++) {
|
||||
s += CharToUpper(in[i]);
|
||||
}
|
||||
for (size_t i = 0; i < in.length(); i++) { s += CharToUpper(in[i]); }
|
||||
return s;
|
||||
}
|
||||
|
||||
@@ -668,8 +666,8 @@ class RustGenerator : public BaseGenerator {
|
||||
return field.optional ? "None" : field.value.constant;
|
||||
}
|
||||
case ftBool: {
|
||||
return field.optional ? "None" :
|
||||
field.value.constant == "0" ? "false" : "true";
|
||||
return field.optional ? "None"
|
||||
: field.value.constant == "0" ? "false" : "true";
|
||||
}
|
||||
case ftUnionKey:
|
||||
case ftEnumKey: {
|
||||
@@ -868,9 +866,9 @@ class RustGenerator : public BaseGenerator {
|
||||
case ftBool:
|
||||
case ftFloat: {
|
||||
const auto typname = GetTypeBasic(field.value.type);
|
||||
return (field.optional ?
|
||||
"self.fbb_.push_slot_always::<" :
|
||||
"self.fbb_.push_slot::<") + typname + ">";
|
||||
return (field.optional ? "self.fbb_.push_slot_always::<"
|
||||
: "self.fbb_.push_slot::<") +
|
||||
typname + ">";
|
||||
}
|
||||
case ftEnumKey:
|
||||
case ftUnionKey: {
|
||||
@@ -1005,7 +1003,7 @@ class RustGenerator : public BaseGenerator {
|
||||
const auto default_value = GetDefaultScalarValue(field);
|
||||
return "self._tab.get::<" + typname + ">(" + offset_name + ", Some(" +
|
||||
default_value + ")).unwrap()";
|
||||
}
|
||||
}
|
||||
}
|
||||
case ftStruct: {
|
||||
const auto typname = WrapInNameSpace(*type.struct_def);
|
||||
|
||||
@@ -757,7 +757,8 @@ CheckedError Parser::ParseField(StructDef &struct_def) {
|
||||
type.enum_def->name + "'.");
|
||||
}
|
||||
if (field->attributes.Lookup("key")) {
|
||||
return Error("only a non-optional scalar field can be used as a 'key' field");
|
||||
return Error(
|
||||
"only a non-optional scalar field can be used as a 'key' field");
|
||||
}
|
||||
if (!SupportsOptionalScalars()) {
|
||||
return Error(
|
||||
@@ -862,7 +863,7 @@ CheckedError Parser::ParseField(StructDef &struct_def) {
|
||||
if (field->required && (struct_def.fixed || IsScalar(type.base_type)))
|
||||
return Error("only non-scalar fields in tables may be 'required'");
|
||||
|
||||
if(!IsScalar(type.base_type)) {
|
||||
if (!IsScalar(type.base_type)) {
|
||||
// For nonscalars, only required fields are non-optional.
|
||||
// At least until https://github.com/google/flatbuffers/issues/6053
|
||||
field->optional = !field->required;
|
||||
@@ -1230,7 +1231,7 @@ CheckedError Parser::ParseTable(const StructDef &struct_def, std::string *value,
|
||||
if (!struct_def.sortbysize ||
|
||||
size == SizeOf(field_value.type.base_type)) {
|
||||
switch (field_value.type.base_type) {
|
||||
// clang-format off
|
||||
// clang-format off
|
||||
#define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE, ...) \
|
||||
case BASE_TYPE_ ## ENUM: \
|
||||
builder_.Pad(field->padding); \
|
||||
@@ -1369,7 +1370,7 @@ CheckedError Parser::ParseVector(const Type &type, uoffset_t *ovalue,
|
||||
// start at the back, since we're building the data backwards.
|
||||
auto &val = field_stack_.back().first;
|
||||
switch (val.type.base_type) {
|
||||
// clang-format off
|
||||
// clang-format off
|
||||
#define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE,...) \
|
||||
case BASE_TYPE_ ## ENUM: \
|
||||
if (IsStruct(val.type)) SerializeStruct(*val.type.struct_def, val); \
|
||||
@@ -2279,7 +2280,7 @@ CheckedError Parser::CheckClash(std::vector<FieldDef *> &fields,
|
||||
return NoError();
|
||||
}
|
||||
|
||||
bool Parser::SupportsOptionalScalars(const flatbuffers::IDLOptions &opts){
|
||||
bool Parser::SupportsOptionalScalars(const flatbuffers::IDLOptions &opts) {
|
||||
static FLATBUFFERS_CONSTEXPR unsigned long supported_langs =
|
||||
IDLOptions::kRust | IDLOptions::kSwift | IDLOptions::kLobster |
|
||||
IDLOptions::kKotlin | IDLOptions::kCpp;
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
namespace flatbuffers {
|
||||
|
||||
int64_t GetAnyValueI(reflection::BaseType type, const uint8_t *data) {
|
||||
// clang-format off
|
||||
// clang-format off
|
||||
#define FLATBUFFERS_GET(T) static_cast<int64_t>(ReadScalar<T>(data))
|
||||
switch (type) {
|
||||
case reflection::UType:
|
||||
@@ -121,7 +121,7 @@ std::string GetAnyValueS(reflection::BaseType type, const uint8_t *data,
|
||||
}
|
||||
|
||||
void SetAnyValueI(reflection::BaseType type, uint8_t *data, int64_t val) {
|
||||
// clang-format off
|
||||
// clang-format off
|
||||
#define FLATBUFFERS_SET(T) WriteScalar(data, static_cast<T>(val))
|
||||
switch (type) {
|
||||
case reflection::UType:
|
||||
|
||||
Reference in New Issue
Block a user