[JS/TS] Size prefix support (#5326)

* WIP size prefix support

* Consider size prefix in overloaded variant

* Work on code gen

* Disabled helper functions in code gen

* Enabled helper functions in code gen

* Fix size prefixed test

* Fix bad function call

* Add SIZE_PREFIX_LENGTH

* Fix review comments
This commit is contained in:
Björn Harrtell
2019-05-16 20:43:31 +02:00
committed by Wouter van Oortmerssen
parent b56d60f058
commit 0bb3ce6935
11 changed files with 370 additions and 61 deletions

View File

@@ -604,6 +604,62 @@ class JsTsGenerator : public BaseGenerator {
}
}
void GenerateRootAccessor(StructDef &struct_def, std::string *code_ptr,
std::string &code, std::string &object_name, bool size_prefixed) {
if (!struct_def.fixed) {
GenDocComment(code_ptr,
GenTypeAnnotation(kParam, "flatbuffers.ByteBuffer", "bb") +
GenTypeAnnotation(kParam, object_name + "=", "obj") +
GenTypeAnnotation(kReturns, object_name, "", false));
std::string sizePrefixed("SizePrefixed");
if (lang_.language == IDLOptions::kTs) {
code += "static get" + (size_prefixed ? sizePrefixed : "") + "Root" + Verbose(struct_def, "As");
code += "(bb:flatbuffers.ByteBuffer, obj?:" + object_name +
"):" + object_name + " {\n";
} else {
code += object_name + ".get" + (size_prefixed ? sizePrefixed : "") + "Root" + Verbose(struct_def, "As");
code += " = function(bb, obj) {\n";
}
code += " return (obj || new " + object_name;
code += ").__init(bb.readInt32(bb.position()) + bb.position(), bb);\n";
code += "};\n\n";
}
}
void GenerateFinisher(StructDef &struct_def, std::string *code_ptr,
std::string &code, std::string &object_name, bool size_prefixed) {
if (parser_.root_struct_def_ == &struct_def) {
std::string sizePrefixed("SizePrefixed");
GenDocComment(
code_ptr,
GenTypeAnnotation(kParam, "flatbuffers.Builder", "builder") +
GenTypeAnnotation(kParam, "flatbuffers.Offset", "offset",
false));
if (lang_.language == IDLOptions::kTs) {
code += "static finish" + (size_prefixed ? sizePrefixed : "") + Verbose(struct_def) + "Buffer";
code +=
"(builder:flatbuffers.Builder, offset:flatbuffers.Offset) {\n";
} else {
code += object_name + ".finish" + (size_prefixed ? sizePrefixed : "") + Verbose(struct_def) + "Buffer";
code += " = function(builder, offset) {\n";
}
code += " builder.finish(offset";
if (!parser_.file_identifier_.empty()) {
code += ", '" + parser_.file_identifier_ + "'";
}
if (size_prefixed) {
if (parser_.file_identifier_.empty()) {
code += ", undefined";
}
code += ", true";
}
code += ");\n";
code += "};\n\n";
}
}
// Generate an accessor struct with constructor for a flatbuffers struct.
void GenStruct(const Parser &parser, StructDef &struct_def,
std::string *code_ptr, std::string *exports_ptr,
@@ -688,43 +744,28 @@ class JsTsGenerator : public BaseGenerator {
code += " return this;\n";
code += "};\n\n";
// Generate a special accessor for the table that when used as the root of a
// Generate special accessors for the table that when used as the root of a
// FlatBuffer
if (!struct_def.fixed) {
GenDocComment(code_ptr,
GenTypeAnnotation(kParam, "flatbuffers.ByteBuffer", "bb") +
GenTypeAnnotation(kParam, object_name + "=", "obj") +
GenTypeAnnotation(kReturns, object_name, "", false));
GenerateRootAccessor(struct_def, code_ptr, code, object_name, false);
GenerateRootAccessor(struct_def, code_ptr, code, object_name, true);
// Generate the identifier check method
if (!struct_def.fixed && parser_.root_struct_def_ == &struct_def &&
!parser_.file_identifier_.empty()) {
GenDocComment(
code_ptr,
GenTypeAnnotation(kParam, "flatbuffers.ByteBuffer", "bb") +
GenTypeAnnotation(kReturns, "boolean", "", false));
if (lang_.language == IDLOptions::kTs) {
code += "static getRoot" + Verbose(struct_def, "As");
code += "(bb:flatbuffers.ByteBuffer, obj?:" + object_name +
"):" + object_name + " {\n";
code +=
"static bufferHasIdentifier(bb:flatbuffers.ByteBuffer):boolean "
"{\n";
} else {
code += object_name + ".getRoot" + Verbose(struct_def, "As");
code += " = function(bb, obj) {\n";
code += object_name + ".bufferHasIdentifier = function(bb) {\n";
}
code += " return (obj || new " + object_name;
code += ").__init(bb.readInt32(bb.position()) + bb.position(), bb);\n";
code += "};\n\n";
// Generate the identifier check method
if (parser_.root_struct_def_ == &struct_def &&
!parser_.file_identifier_.empty()) {
GenDocComment(
code_ptr,
GenTypeAnnotation(kParam, "flatbuffers.ByteBuffer", "bb") +
GenTypeAnnotation(kReturns, "boolean", "", false));
if (lang_.language == IDLOptions::kTs) {
code +=
"static bufferHasIdentifier(bb:flatbuffers.ByteBuffer):boolean "
"{\n";
} else {
code += object_name + ".bufferHasIdentifier = function(bb) {\n";
}
code += " return bb.__has_identifier('" + parser_.file_identifier_;
code += "');\n};\n\n";
}
code += " return bb.__has_identifier('" + parser_.file_identifier_;
code += "');\n};\n\n";
}
// Emit field accessors
@@ -1238,30 +1279,9 @@ class JsTsGenerator : public BaseGenerator {
code += " return offset;\n";
code += "};\n\n";
// Generate the method to complete buffer construction
if (parser_.root_struct_def_ == &struct_def) {
GenDocComment(
code_ptr,
GenTypeAnnotation(kParam, "flatbuffers.Builder", "builder") +
GenTypeAnnotation(kParam, "flatbuffers.Offset", "offset",
false));
if (lang_.language == IDLOptions::kTs) {
code += "static finish" + Verbose(struct_def) + "Buffer";
code +=
"(builder:flatbuffers.Builder, offset:flatbuffers.Offset) {\n";
} else {
code += object_name + ".finish" + Verbose(struct_def) + "Buffer";
code += " = function(builder, offset) {\n";
}
code += " builder.finish(offset";
if (!parser_.file_identifier_.empty()) {
code += ", '" + parser_.file_identifier_ + "'";
}
code += ");\n";
code += "};\n\n";
}
// Generate the methods to complete buffer construction
GenerateFinisher(struct_def, code_ptr, code, object_name, false);
GenerateFinisher(struct_def, code_ptr, code, object_name, true);
// Generate a convenient CreateX function
if (lang_.language == IDLOptions::kJs) {