Merge branch 'master' into master

This commit is contained in:
Derek Bailey
2023-04-25 22:27:14 -07:00
committed by GitHub
125 changed files with 4479 additions and 910 deletions

View File

@@ -69,6 +69,9 @@ cc_library(
"bfbs_gen_nim.cpp",
"bfbs_gen_nim.h",
"bfbs_namer.h",
"file_binary_writer.cpp",
"file_name_saving_file_manager.cpp",
"file_writer.cpp",
"flatc_main.cpp",
"idl_gen_binary.cpp",
"idl_gen_binary.h",

View File

@@ -0,0 +1,49 @@
/*
* Copyright 2023 Google Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <fstream>
#include <set>
#include <string>
#include "flatbuffers/file_manager.h"
namespace flatbuffers {
class FileBinaryWriter : public FileManager {
public:
bool SaveFile(const std::string &absolute_file_name,
const std::string &content) override {
std::ofstream ofs(absolute_file_name, std::ofstream::binary);
if (!ofs.is_open()) return false;
ofs.write(content.c_str(), content.size());
return !ofs.bad();
}
bool Loadfile(const std::string &absolute_file_name, std::string *output) {
if (DirExists(absolute_file_name.c_str())) return false;
std::ifstream ifs(absolute_file_name, std::ifstream::binary);
if (!ifs.is_open()) return false;
// The fastest way to read a file into a string.
ifs.seekg(0, std::ios::end);
auto size = ifs.tellg();
(*output).resize(static_cast<size_t>(size));
ifs.seekg(0, std::ios::beg);
ifs.read(&(*output)[0], (*output).size());
return !ifs.bad();
}
};
} // namespace flatbuffers

View File

@@ -0,0 +1,49 @@
/*
* Copyright 2023 Google Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <fstream>
#include <set>
#include <string>
#include "flatbuffers/file_manager.h"
namespace flatbuffers {
class FileNameSavingFileManager : public FileManager {
public:
FileNameSavingFileManager(std::set<std::string> file_names)
: file_names_(file_names) {}
bool SaveFile(const std::string &absolute_file_name,
const std::string &content) override {
(void)content;
auto pair = file_names_.insert(absolute_file_name);
// pair.second indicates whether the insertion is
// successful or not.
return pair.second;
}
bool Loadfile(const std::string &absolute_file_name, std::string *content) {
(void) absolute_file_name;
(void) content;
return false;
}
private:
std::set<std::string> file_names_;
};
} // namespace flatbuffers

47
src/file_writer.cpp Normal file
View File

@@ -0,0 +1,47 @@
/*
* Copyright 2023 Google Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <fstream>
#include <set>
#include <string>
#include "flatbuffers/file_manager.h"
namespace flatbuffers {
class FileWriter : public FileManager {
public:
bool SaveFile(const std::string &absolute_file_name,
const std::string &content) override {
std::ofstream ofs(absolute_file_name, std::ofstream::out);
if (!ofs.is_open()) return false;
ofs.write(content.c_str(), content.size());
return !ofs.bad();
}
bool Loadfile(const std::string &absolute_file_name, std::string *output) {
if (DirExists(absolute_file_name.c_str())) return false;
std::ifstream ifs(absolute_file_name, std::ifstream::in);
if (!ifs.is_open()) return false;
// This is slower, but works correctly on all platforms for text files.
std::ostringstream oss;
oss << ifs.rdbuf();
*output = oss.str();
return !ifs.bad();
}
};
} // namespace flatbuffers

View File

@@ -250,6 +250,10 @@ const static FlatCOption flatc_options[] = {
{ "", "no-leak-private-annotation", "",
"Prevents multiple type of annotations within a Fbs SCHEMA file. "
"Currently this is required to generate private types in Rust" },
{ "", "python-no-type-prefix-suffix", "",
"Skip emission of Python functions that are prefixed with typenames" },
{ "", "file-names-only", "",
"Print out generated file names without writing to the files"},
};
auto cmp = [](FlatCOption a, FlatCOption b) { return a.long_opt < b.long_opt; };
@@ -648,11 +652,16 @@ FlatCOptions FlatCompiler::ParseFromCommandLineArguments(int argc,
opts.ts_no_import_ext = true;
} else if (arg == "--no-leak-private-annotation") {
opts.no_leak_private_annotations = true;
} else if (arg == "--annotate-sparse-vectors") {
} else if (arg == "--python-no-type-prefix-suffix") {
opts.python_no_type_prefix_suffix = true;
} else if (arg == "--annotate-sparse-vectors") {
options.annotate_include_vector_contents = false;
} else if (arg == "--annotate") {
if (++argi >= argc) Error("missing path following: " + arg, true);
options.annotate_schema = flatbuffers::PosixPath(argv[argi]);
} else if(arg == "--file-names-only") {
// TODO (khhn): Provide 2 implementation
options.file_names_only = true;
} else {
if (arg == "--proto") { opts.proto_mode = true; }

View File

@@ -169,6 +169,7 @@ class CSharpGenerator : public BaseGenerator {
if (!parser_.opts.one_file)
cur_name_space_ = struct_def.defined_namespace;
GenStruct(struct_def, &declcode, parser_.opts);
GenStructVerifier(struct_def, &declcode);
if (parser_.opts.one_file) {
one_file_code += declcode;
} else {
@@ -623,6 +624,173 @@ class CSharpGenerator : public BaseGenerator {
")";
}
// Get the value of a table verification function start
void GetStartOfTableVerifier(const StructDef &struct_def, std::string *code_ptr) {
std::string &code = *code_ptr;
code += "\n";
code += "static public class " + struct_def.name + "Verify\n";
code += "{\n";
code += " static public bool Verify";
code += "(Google.FlatBuffers.Verifier verifier, uint tablePos)\n";
code += " {\n";
code += " return verifier.VerifyTableStart(tablePos)\n";
}
// Get the value of a table verification function end
void GetEndOfTableVerifier(std::string *code_ptr) {
std::string &code = *code_ptr;
code += " && verifier.VerifyTableEnd(tablePos);\n";
code += " }\n";
code += "}\n";
}
std::string GetNestedFlatBufferName(const FieldDef &field) {
std::string name;
if (field.nested_flatbuffer) {
name = NamespacedName(*field.nested_flatbuffer);
} else {
name = "";
}
return name ;
}
// Generate the code to call the appropriate Verify function(s) for a field.
void GenVerifyCall(CodeWriter &code_, const FieldDef &field, const char *prefix) {
code_.SetValue("PRE", prefix);
code_.SetValue("NAME", ConvertCase(field.name, Case::kUpperCamel));
code_.SetValue("REQUIRED", field.IsRequired() ? "Required" : "");
code_.SetValue("REQUIRED_FLAG", field.IsRequired() ? "true" : "false");
code_.SetValue("TYPE", GenTypeGet(field.value.type));
code_.SetValue("INLINESIZE", NumToString(InlineSize(field.value.type)));
code_.SetValue("OFFSET", NumToString(field.value.offset));
if (IsScalar(field.value.type.base_type) || IsStruct(field.value.type)) {
code_.SetValue("ALIGN", NumToString(InlineAlignment(field.value.type)));
code_ +=
"{{PRE}} && verifier.VerifyField(tablePos, "
"{{OFFSET}} /*{{NAME}}*/, {{INLINESIZE}} /*{{TYPE}}*/, {{ALIGN}}, {{REQUIRED_FLAG}})";
} else {
// TODO - probably code below should go to this 'else' - code_ += "{{PRE}}VerifyOffset{{REQUIRED}}(verifier, {{OFFSET}})\\";
}
switch (field.value.type.base_type) {
case BASE_TYPE_UNION: {
auto union_name = NamespacedName(*field.value.type.enum_def);
code_.SetValue("ENUM_NAME1", field.value.type.enum_def->name);
code_.SetValue("ENUM_NAME", union_name);
code_.SetValue("SUFFIX", UnionTypeFieldSuffix());
// Caution: This construction assumes, that UNION type id element has been created just before union data and
// its offset precedes union. Such assumption is common in flatbuffer implementation
code_.SetValue("TYPE_ID_OFFSET", NumToString(field.value.offset - sizeof(voffset_t)));
code_ += "{{PRE}} && verifier.VerifyUnion(tablePos, {{TYPE_ID_OFFSET}}, "
"{{OFFSET}} /*{{NAME}}*/, {{ENUM_NAME}}Verify.Verify, {{REQUIRED_FLAG}})";
break;
}
case BASE_TYPE_STRUCT: {
if (!field.value.type.struct_def->fixed) {
code_ += "{{PRE}} && verifier.VerifyTable(tablePos, "
"{{OFFSET}} /*{{NAME}}*/, {{TYPE}}Verify.Verify, {{REQUIRED_FLAG}})";
}
break;
}
case BASE_TYPE_STRING: {
code_ += "{{PRE}} && verifier.VerifyString(tablePos, "
"{{OFFSET}} /*{{NAME}}*/, {{REQUIRED_FLAG}})";
break;
}
case BASE_TYPE_VECTOR: {
switch (field.value.type.element) {
case BASE_TYPE_STRING: {
code_ += "{{PRE}} && verifier.VerifyVectorOfStrings(tablePos, "
"{{OFFSET}} /*{{NAME}}*/, {{REQUIRED_FLAG}})";
break;
}
case BASE_TYPE_STRUCT: {
if (!field.value.type.struct_def->fixed) {
code_ += "{{PRE}} && verifier.VerifyVectorOfTables(tablePos, "
"{{OFFSET}} /*{{NAME}}*/, {{TYPE}}Verify.Verify, {{REQUIRED_FLAG}})";
} else {
code_.SetValue(
"VECTOR_ELEM_INLINESIZE",
NumToString(InlineSize(field.value.type.VectorType())));
code_ +=
"{{PRE}} && "
"verifier.VerifyVectorOfData(tablePos, "
"{{OFFSET}} /*{{NAME}}*/, {{VECTOR_ELEM_INLINESIZE}} "
"/*{{TYPE}}*/, {{REQUIRED_FLAG}})";
}
break;
}
case BASE_TYPE_UNION: {
// Vectors of unions are not yet supported for go
break;
}
default:
// Generate verifier for vector of data.
// It may be either nested flatbuffer of just vector of bytes
auto nfn = GetNestedFlatBufferName(field);
if (!nfn.empty()) {
code_.SetValue("CPP_NAME", nfn);
// FIXME: file_identifier.
code_ += "{{PRE}} && verifier.VerifyNestedBuffer(tablePos, "
"{{OFFSET}} /*{{NAME}}*/, {{CPP_NAME}}Verify.Verify, {{REQUIRED_FLAG}})";
} else if (field.flexbuffer) {
code_ += "{{PRE}} && verifier.VerifyNestedBuffer(tablePos, "
"{{OFFSET}} /*{{NAME}}*/, null, {{REQUIRED_FLAG}})";
} else {
code_.SetValue("VECTOR_ELEM_INLINESIZE", NumToString(InlineSize(field.value.type.VectorType())));
code_ +=
"{{PRE}} && verifier.VerifyVectorOfData(tablePos, "
"{{OFFSET}} /*{{NAME}}*/, {{VECTOR_ELEM_INLINESIZE}} /*{{TYPE}}*/, {{REQUIRED_FLAG}})";
}
break;
}
break;
}
default: {
break;
}
}
}
// Generate table constructors, conditioned on its members' types.
void GenTableVerifier(const StructDef &struct_def, std::string *code_ptr) {
CodeWriter code_;
GetStartOfTableVerifier(struct_def, code_ptr);
// Generate struct fields accessors
for (auto it = struct_def.fields.vec.begin();
it != struct_def.fields.vec.end(); ++it) {
auto &field = **it;
if (field.deprecated) continue;
GenVerifyCall(code_, field, "");
}
*code_ptr += code_.ToString();
GetEndOfTableVerifier(code_ptr);
}
// Generate struct or table methods.
void GenStructVerifier(const StructDef &struct_def, std::string *code_ptr) {
if (struct_def.generated) return;
// cur_name_space_ = struct_def.defined_namespace;
// Generate verifiers
if (struct_def.fixed) {
// Fixed size structures do not require table members
// verification - instead structure size is verified using VerifyField
} else {
// Create table verification function
GenTableVerifier(struct_def, code_ptr);
}
}
void GenStruct(StructDef &struct_def, std::string *code_ptr,
const IDLOptions &opts) const {
if (struct_def.generated) return;
@@ -688,8 +856,20 @@ class CSharpGenerator : public BaseGenerator {
code += parser_.file_identifier_;
code += "\"); }\n";
}
// Generate the Verify method that checks if a ByteBuffer is save to
// access
code += " public static ";
code += "bool Verify" + struct_def.name + "(ByteBuffer _bb) {";
code += "Google.FlatBuffers.Verifier verifier = new ";
code += "Google.FlatBuffers.Verifier(_bb); ";
code += "return verifier.VerifyBuffer(\"";
code += parser_.file_identifier_;
code += "\", false, " + struct_def.name + "Verify.Verify);";
code += " }\n";
}
}
// Generate the __init method that sets the field in a pre-existing
// accessor object. This is to allow object reuse.
code += " public void __init(int _i, ByteBuffer _bb) ";
@@ -1418,6 +1598,67 @@ class CSharpGenerator : public BaseGenerator {
code += " }\n";
}
std::string GenUnionVerify(const Type &union_type) const {
if (union_type.enum_def) {
const auto &enum_def = *union_type.enum_def;
auto ret =
"\n\nstatic public class " + enum_def.name + "Verify\n";
ret += "{\n";
ret +=
" static public bool Verify(Google.FlatBuffers.Verifier verifier, "
"byte typeId, uint tablePos)\n";
ret += " {\n";
ret += " bool result = true;\n";
const auto union_enum_loop = [&]() {
ret += " switch((" + enum_def.name + ")typeId)\n";
ret += " {\n";
for (auto it = enum_def.Vals().begin(); it != enum_def.Vals().end(); ++it) {
const auto &ev = **it;
if (ev.IsZero()) { continue; }
ret += " case " + Name(enum_def) + "." + Name(ev) + ":\n";
if (IsString(ev.union_type)) {
ret +=
" result = verifier.VerifyUnionString(tablePos);\n";
ret += " break;";
} else if (ev.union_type.base_type == BASE_TYPE_STRUCT) {
if (! ev.union_type.struct_def->fixed) {
auto type = GenTypeGet(ev.union_type);
ret += " result = " + type + "Verify.Verify(verifier, tablePos);\n";
} else {
ret += " result = verifier.VerifyUnionData(tablePos, " +
NumToString(InlineSize(ev.union_type)) + ", " +
NumToString(InlineAlignment(ev.union_type)) +
");\n";;
}
ret += " break;";
} else {
FLATBUFFERS_ASSERT(false);
}
ret += "\n";
}
ret += " default: result = true;\n";
ret += " break;\n";
ret += " }\n";
ret += " return result;\n";
};
union_enum_loop();
ret += " }\n";
ret += "}\n";
ret += "\n";
return ret;
}
FLATBUFFERS_ASSERT(0);
return "";
}
void GenEnum_ObjectAPI(EnumDef &enum_def, std::string *code_ptr,
const IDLOptions &opts) const {
auto &code = *code_ptr;
@@ -1493,6 +1734,9 @@ class CSharpGenerator : public BaseGenerator {
code += " }\n";
code += " }\n";
code += "}\n\n";
code += GenUnionVerify(enum_def.underlying_type);
// JsonConverter
if (opts.cs_gen_json_serializer) {
if (enum_def.attributes.Lookup("private")) {

View File

@@ -292,6 +292,14 @@ class GoGenerator : public BaseGenerator {
const std::string size_prefix[] = { "", "SizePrefixed" };
const std::string struct_type = namer_.Type(struct_def);
bool has_file_identifier = (parser_.root_struct_def_ == &struct_def) &&
parser_.file_identifier_.length();
if (has_file_identifier) {
code += "const " + struct_type + "Identifier = \"" +
parser_.file_identifier_ + "\"\n\n";
}
for (int i = 0; i < 2; i++) {
code += "func Get" + size_prefix[i] + "RootAs" + struct_type;
code += "(buf []byte, offset flatbuffers.UOffsetT) ";
@@ -312,6 +320,26 @@ class GoGenerator : public BaseGenerator {
}
code += "\treturn x\n";
code += "}\n\n";
code += "func Finish" + size_prefix[i] + struct_type +
"Buffer(builder *flatbuffers.Builder, offset "
"flatbuffers.UOffsetT) {\n";
if (has_file_identifier) {
code += "\tidentifierBytes := []byte(" + struct_type + "Identifier)\n";
code += "\tbuilder.Finish" + size_prefix[i] +
"WithFileIdentifier(offset, identifierBytes)\n";
} else {
code += "\tbuilder.Finish" + size_prefix[i] + "(offset)\n";
}
code += "}\n\n";
if (has_file_identifier) {
code += "func " + size_prefix[i] + struct_type +
"BufferHasIdentifier(buf []byte) bool {\n";
code += "\treturn flatbuffers." + size_prefix[i] +
"BufferHasIdentifier(buf, " + struct_type + "Identifier)\n";
code += "}\n\n";
}
}
}
@@ -513,7 +541,7 @@ class GoGenerator : public BaseGenerator {
GenReceiver(struct_def, code_ptr);
code += " " + namer_.Field(field) + "ByKey";
code += "(obj *" + TypeName(field);
code += ", key " + NativeType(key_field.value.type) + ") bool" +
code += ", key " + NativeType(key_field.value.type) + ") bool " +
OffsetPrefix(field);
code += "\t\tx := rcv._tab.Vector(o)\n";
code += "\t\treturn ";
@@ -892,8 +920,8 @@ class GoGenerator : public BaseGenerator {
code += "o1, o2 flatbuffers.UOffsetT, buf []byte) bool {\n";
code += "\tobj1 := &" + namer_.Type(struct_def) + "{}\n";
code += "\tobj2 := &" + namer_.Type(struct_def) + "{}\n";
code += "\tobj1.Init(buf, flatbuffers.UOffsetT(len(buf)) - o1)\n";
code += "\tobj2.Init(buf, flatbuffers.UOffsetT(len(buf)) - o2)\n";
code += "\tobj1.Init(buf, flatbuffers.UOffsetT(len(buf))-o1)\n";
code += "\tobj2.Init(buf, flatbuffers.UOffsetT(len(buf))-o2)\n";
if (IsString(field.value.type)) {
code += "\treturn string(obj1." + namer_.Function(field.name) + "()) < ";
code += "string(obj2." + namer_.Function(field.name) + "())\n";
@@ -915,13 +943,13 @@ class GoGenerator : public BaseGenerator {
code += "key " + NativeType(field.value.type) + ", ";
code += "vectorLocation flatbuffers.UOffsetT, ";
code += "buf []byte) bool {\n";
code += "\tspan := flatbuffers.GetUOffsetT(buf[vectorLocation - 4:])\n";
code += "\tspan := flatbuffers.GetUOffsetT(buf[vectorLocation-4:])\n";
code += "\tstart := flatbuffers.UOffsetT(0)\n";
if (IsString(field.value.type)) { code += "\tbKey := []byte(key)\n"; }
code += "\tfor span != 0 {\n";
code += "\t\tmiddle := span / 2\n";
code += "\t\ttableOffset := flatbuffers.GetIndirectOffset(buf, ";
code += "vectorLocation+ 4 * (start + middle))\n";
code += "vectorLocation+4*(start+middle))\n";
code += "\t\tobj := &" + namer_.Type(struct_def) + "{}\n";
code += "\t\tobj.Init(buf, tableOffset)\n";
@@ -1032,8 +1060,8 @@ class GoGenerator : public BaseGenerator {
code += "\t\treturn &" +
WrapInNameSpaceAndTrack(&enum_def, NativeName(enum_def)) +
"{ Type: " + namer_.EnumVariant(enum_def, ev) +
", Value: x.UnPack() }\n";
"{Type: " + namer_.EnumVariant(enum_def, ev) +
", Value: x.UnPack()}\n";
}
code += "\t}\n";
code += "\treturn nil\n";
@@ -1046,7 +1074,7 @@ class GoGenerator : public BaseGenerator {
code += "func (t *" + NativeName(struct_def) +
") Pack(builder *flatbuffers.Builder) flatbuffers.UOffsetT {\n";
code += "\tif t == nil { return 0 }\n";
code += "\tif t == nil {\n\t\treturn 0\n\t}\n";
for (auto it = struct_def.fields.vec.begin();
it != struct_def.fields.vec.end(); ++it) {
const FieldDef &field = **it;
@@ -1116,8 +1144,7 @@ class GoGenerator : public BaseGenerator {
if (field.value.type.struct_def->fixed) continue;
code += "\t" + offset + " := t." + field_field + ".Pack(builder)\n";
} else if (field.value.type.base_type == BASE_TYPE_UNION) {
code += "\t" + offset + " := t." + field_field + ".Pack(builder)\n";
code += "\t\n";
code += "\t" + offset + " := t." + field_field + ".Pack(builder)\n\n";
} else {
FLATBUFFERS_ASSERT(0);
}
@@ -1233,7 +1260,7 @@ class GoGenerator : public BaseGenerator {
code += "func (rcv *" + struct_type + ") UnPack() *" +
NativeName(struct_def) + " {\n";
code += "\tif rcv == nil { return nil }\n";
code += "\tif rcv == nil {\n\t\treturn nil\n\t}\n";
code += "\tt := &" + NativeName(struct_def) + "{}\n";
code += "\trcv.UnPackTo(t)\n";
code += "\treturn t\n";
@@ -1245,7 +1272,7 @@ class GoGenerator : public BaseGenerator {
code += "func (t *" + NativeName(struct_def) +
") Pack(builder *flatbuffers.Builder) flatbuffers.UOffsetT {\n";
code += "\tif t == nil { return 0 }\n";
code += "\tif t == nil {\n\t\treturn 0\n\t}\n";
code += "\treturn Create" + namer_.Type(struct_def) + "(builder";
StructPackArgs(struct_def, "", code_ptr);
code += ")\n";
@@ -1289,7 +1316,7 @@ class GoGenerator : public BaseGenerator {
code += "func (rcv *" + namer_.Type(struct_def) + ") UnPack() *" +
NativeName(struct_def) + " {\n";
code += "\tif rcv == nil { return nil }\n";
code += "\tif rcv == nil {\n\t\treturn nil\n\t}\n";
code += "\tt := &" + NativeName(struct_def) + "{}\n";
code += "\trcv.UnPackTo(t)\n";
code += "\treturn t\n";
@@ -1477,15 +1504,17 @@ class GoGenerator : public BaseGenerator {
code += "package " + name_space_name + "\n\n";
if (needs_imports) {
code += "import (\n";
// standard imports, in alphabetical order for go fmt
if (needs_bytes_import_) code += "\t\"bytes\"\n";
// math is needed to support non-finite scalar default values.
if (needs_math_import_) { code += "\t\"math\"\n"; }
if (is_enum) { code += "\t\"strconv\"\n"; }
if (!parser_.opts.go_import.empty()) {
code += "\tflatbuffers \"" + parser_.opts.go_import + "\"\n";
} else {
code += "\tflatbuffers \"github.com/google/flatbuffers/go\"\n";
}
// math is needed to support non-finite scalar default values.
if (needs_math_import_) { code += "\t\"math\"\n"; }
if (is_enum) { code += "\t\"strconv\"\n"; }
if (tracked_imported_namespaces_.size() > 0) {
code += "\n";
for (auto it = tracked_imported_namespaces_.begin();

View File

@@ -139,13 +139,15 @@ class PythonGenerator : public BaseGenerator {
code += Indent + Indent + "return x\n";
code += "\n";
// Add an alias with the old name
code += Indent + "@classmethod\n";
code += Indent + "def GetRootAs" + struct_type + "(cls, buf, offset=0):\n";
code +=
Indent + Indent +
"\"\"\"This method is deprecated. Please switch to GetRootAs.\"\"\"\n";
code += Indent + Indent + "return cls.GetRootAs(buf, offset)\n";
if (!parser_.opts.python_no_type_prefix_suffix) {
// Add an alias with the old name
code += Indent + "@classmethod\n";
code += Indent + "def GetRootAs" + struct_type + "(cls, buf, offset=0):\n";
code +=
Indent + Indent +
"\"\"\"This method is deprecated. Please switch to GetRootAs.\"\"\"\n";
code += Indent + Indent + "return cls.GetRootAs(buf, offset)\n";
}
}
// Initialize an existing object with other data, to avoid an allocation.
@@ -480,7 +482,10 @@ class PythonGenerator : public BaseGenerator {
if (!nested) { return; } // There is no nested flatbuffer.
const std::string unqualified_name = nested->constant;
const std::string qualified_name = NestedFlatbufferType(unqualified_name);
std::string qualified_name = NestedFlatbufferType(unqualified_name);
if (qualified_name.empty()) {
qualified_name = nested->constant;
}
auto &code = *code_ptr;
GenReceiver(struct_def, code_ptr);
@@ -491,7 +496,7 @@ class PythonGenerator : public BaseGenerator {
code += Indent + Indent + Indent;
code += "from " + qualified_name + " import " + unqualified_name + "\n";
code += Indent + Indent + Indent + "return " + unqualified_name;
code += ".GetRootAs" + unqualified_name;
code += ".GetRootAs";
code += "(self._tab.Bytes, self._tab.Vector(o))\n";
code += Indent + Indent + "return 0\n";
code += "\n";
@@ -605,15 +610,18 @@ class PythonGenerator : public BaseGenerator {
auto &code = *code_ptr;
const auto struct_type = namer_.Type(struct_def);
// Generate method with struct name.
code += "def " + struct_type + "Start(builder): ";
code += "builder.StartObject(";
code += NumToString(struct_def.fields.vec.size());
code += ")\n";
if (!parser_.opts.one_file) {
const auto name = parser_.opts.python_no_type_prefix_suffix ? "Start" : struct_type + "Start";
code += "def " + name + "(builder):\n";
code += Indent + "return builder.StartObject(";
code += NumToString(struct_def.fields.vec.size());
code += ")\n\n";
if (!parser_.opts.one_file && !parser_.opts.python_no_type_prefix_suffix) {
// Generate method without struct name.
code += "def Start(builder):\n";
code += Indent + "return " + struct_type + "Start(builder)\n";
code += Indent + "return " + struct_type + "Start(builder)\n\n";
}
}
@@ -624,12 +632,14 @@ class PythonGenerator : public BaseGenerator {
const std::string field_var = namer_.Variable(field);
const std::string field_method = namer_.Method(field);
const auto name = parser_.opts.python_no_type_prefix_suffix ? "Add" + field_method : namer_.Type(struct_def) + "Add" + field_method;
// Generate method with struct name.
code += "def " + namer_.Type(struct_def) + "Add" + field_method;
code += "def " + name;
code += "(builder, ";
code += field_var;
code += "): ";
code += "builder.Prepend";
code += "):\n";
code += Indent + "return builder.Prepend";
code += GenMethod(field) + "Slot(";
code += NumToString(offset) + ", ";
if (!IsScalar(field.value.type.base_type) && (!struct_def.fixed)) {
@@ -646,16 +656,16 @@ class PythonGenerator : public BaseGenerator {
} else {
code += field.value.constant;
}
code += ")\n";
code += ")\n\n";
if (!parser_.opts.one_file) {
if (!parser_.opts.one_file && !parser_.opts.python_no_type_prefix_suffix) {
// Generate method without struct name.
code += "def Add" + field_method + "(builder, " + field_var + "):\n";
code +=
Indent + "return " + namer_.Type(struct_def) + "Add" + field_method;
code += "(builder, ";
code += field_var;
code += ")\n";
code += ")\n\n";
}
}
@@ -667,20 +677,22 @@ class PythonGenerator : public BaseGenerator {
const std::string field_method = namer_.Method(field);
// Generate method with struct name.
code += "def " + struct_type + "Start" + field_method;
code += "Vector(builder, numElems): return builder.StartVector(";
const auto name = parser_.opts.python_no_type_prefix_suffix ? "Start" + field_method : struct_type + "Start" + field_method;
code += "def " + name;
code += "Vector(builder, numElems):\n";
code += Indent + "return builder.StartVector(";
auto vector_type = field.value.type.VectorType();
auto alignment = InlineAlignment(vector_type);
auto elem_size = InlineSize(vector_type);
code += NumToString(elem_size);
code += ", numElems, " + NumToString(alignment);
code += ")\n";
code += ")\n\n";
if (!parser_.opts.one_file) {
if (!parser_.opts.one_file && !parser_.opts.python_no_type_prefix_suffix) {
// Generate method without struct name.
code += "def Start" + field_method + "Vector(builder, numElems):\n";
code += Indent + "return " + struct_type + "Start";
code += field_method + "Vector(builder, numElems)\n";
code += field_method + "Vector(builder, numElems)\n\n";
}
}
@@ -725,15 +737,16 @@ class PythonGenerator : public BaseGenerator {
std::string *code_ptr) const {
auto &code = *code_ptr;
const auto name = parser_.opts.python_no_type_prefix_suffix ? "End" : namer_.Type(struct_def) + "End";
// Generate method with struct name.
code += "def " + namer_.Type(struct_def) + "End";
code += "(builder): ";
code += "return builder.EndObject()\n";
code += "def " + name + "(builder):\n";
code += Indent + "return builder.EndObject()\n\n";
if (!parser_.opts.one_file) {
if (!parser_.opts.one_file && !parser_.opts.python_no_type_prefix_suffix) {
// Generate method without struct name.
code += "def End(builder):\n";
code += Indent + "return " + namer_.Type(struct_def) + "End(builder)";
code += "\n";
}
}

View File

@@ -725,9 +725,9 @@ class SwiftGenerator : public BaseGenerator {
code_.SetValue("CONSTANT", default_value);
code_.SetValue("VALUETYPE", "Bool");
code_ += GenReaderMainBody(optional) + "\\";
code_.SetValue("VALUETYPE", "Byte");
code_ += GenOffset() + "return o == 0 ? {{CONSTANT}} : 0 != " +
GenReader("VALUETYPE", "o") + " }";
code_ += GenOffset() +
"return o == 0 ? {{CONSTANT}} : " + GenReader("VALUETYPE", "o") +
" }";
if (parser_.opts.mutable_buffer) code_ += GenMutate("o", GenOffset());
return;
}

View File

@@ -474,14 +474,13 @@ class TsGenerator : public BaseGenerator {
return "BigInt('" + value.constant + "')";
}
default: {
if (auto val = value.type.enum_def->FindByValue(value.constant)) {
return AddImport(imports, *value.type.enum_def,
*value.type.enum_def)
.name +
"." + namer_.Variant(*val);
} else {
return value.constant;
}
EnumVal *val = value.type.enum_def->FindByValue(value.constant);
if (val == nullptr)
val = const_cast<EnumVal *>(value.type.enum_def->MinValue());
return AddImport(imports, *value.type.enum_def,
*value.type.enum_def)
.name +
"." + namer_.Variant(*val);
}
}
}