diff --git a/include/flatbuffers/code_generators.h b/include/flatbuffers/code_generators.h index 5770932cc..6c902a454 100644 --- a/include/flatbuffers/code_generators.h +++ b/include/flatbuffers/code_generators.h @@ -29,6 +29,11 @@ class BaseGenerator { protected: virtual ~BaseGenerator(){}; + const char * FlatBuffersGeneratedWarning() { + return "automatically generated by the FlatBuffers compiler," + " do not modify\n\n"; + } + bool IsEverythingGenerated() { for (auto it = parser_.enums_.vec.begin(); it != parser_.enums_.vec.end(); ++it) { diff --git a/samples/monster_generated.h b/samples/monster_generated.h index cf45bbb91..1a16126a5 100644 --- a/samples/monster_generated.h +++ b/samples/monster_generated.h @@ -5,12 +5,13 @@ #include "flatbuffers/flatbuffers.h" - namespace MyGame { namespace Sample { struct Vec3; + struct Monster; + struct Weapon; enum Color { @@ -55,8 +56,11 @@ MANUALLY_ALIGNED_STRUCT(4) Vec3 FLATBUFFERS_FINAL_CLASS { : x_(flatbuffers::EndianScalar(_x)), y_(flatbuffers::EndianScalar(_y)), z_(flatbuffers::EndianScalar(_z)) { } float x() const { return flatbuffers::EndianScalar(x_); } + void mutate_x(float _x) { flatbuffers::WriteScalar(&x_, _x); } float y() const { return flatbuffers::EndianScalar(y_); } + void mutate_y(float _y) { flatbuffers::WriteScalar(&y_, _y); } float z() const { return flatbuffers::EndianScalar(z_); } + void mutate_z(float _z) { flatbuffers::WriteScalar(&z_, _z); } }; STRUCT_END(Vec3, 12); @@ -73,14 +77,23 @@ struct Monster FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { VT_EQUIPPED = 22 }; const Vec3 *pos() const { return GetStruct(VT_POS); } + Vec3 *mutable_pos() { return GetStruct(VT_POS); } int16_t mana() const { return GetField(VT_MANA, 150); } + bool mutate_mana(int16_t _mana) { return SetField(VT_MANA, _mana); } int16_t hp() const { return GetField(VT_HP, 100); } + bool mutate_hp(int16_t _hp) { return SetField(VT_HP, _hp); } const flatbuffers::String *name() const { return GetPointer(VT_NAME); } + flatbuffers::String *mutable_name() { return GetPointer(VT_NAME); } const flatbuffers::Vector *inventory() const { return GetPointer *>(VT_INVENTORY); } + flatbuffers::Vector *mutable_inventory() { return GetPointer *>(VT_INVENTORY); } Color color() const { return static_cast(GetField(VT_COLOR, 2)); } + bool mutate_color(Color _color) { return SetField(VT_COLOR, static_cast(_color)); } const flatbuffers::Vector> *weapons() const { return GetPointer> *>(VT_WEAPONS); } + flatbuffers::Vector> *mutable_weapons() { return GetPointer> *>(VT_WEAPONS); } Equipment equipped_type() const { return static_cast(GetField(VT_EQUIPPED_TYPE, 0)); } + bool mutate_equipped_type(Equipment _equipped_type) { return SetField(VT_EQUIPPED_TYPE, static_cast(_equipped_type)); } const void *equipped() const { return GetPointer(VT_EQUIPPED); } + void *mutable_equipped() { return GetPointer(VT_EQUIPPED); } bool Verify(flatbuffers::Verifier &verifier) const { return VerifyTableStart(verifier) && VerifyField(verifier, VT_POS) && @@ -150,7 +163,9 @@ struct Weapon FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { VT_DAMAGE = 6 }; const flatbuffers::String *name() const { return GetPointer(VT_NAME); } + flatbuffers::String *mutable_name() { return GetPointer(VT_NAME); } int16_t damage() const { return GetField(VT_DAMAGE, 0); } + bool mutate_damage(int16_t _damage) { return SetField(VT_DAMAGE, _damage); } bool Verify(flatbuffers::Verifier &verifier) const { return VerifyTableStart(verifier) && VerifyField(verifier, VT_NAME) && @@ -192,6 +207,8 @@ inline bool VerifyEquipment(flatbuffers::Verifier &verifier, const void *union_o inline const MyGame::Sample::Monster *GetMonster(const void *buf) { return flatbuffers::GetRoot(buf); } +inline Monster *GetMutableMonster(void *buf) { return flatbuffers::GetMutableRoot(buf); } + inline bool VerifyMonsterBuffer(flatbuffers::Verifier &verifier) { return verifier.VerifyBuffer(); } inline void FinishMonsterBuffer(flatbuffers::FlatBufferBuilder &fbb, flatbuffers::Offset root) { fbb.Finish(root); } diff --git a/src/idl_gen_cpp.cpp b/src/idl_gen_cpp.cpp index 051cd99de..0bec8ca51 100644 --- a/src/idl_gen_cpp.cpp +++ b/src/idl_gen_cpp.cpp @@ -733,9 +733,7 @@ class CppGenerator : public BaseGenerator { if (IsEverythingGenerated()) return true; std::string code; - code = - "// automatically generated by the FlatBuffers compiler," - " do not modify\n\n"; + code = code + "// " + FlatBuffersGeneratedWarning(); // Generate include guard. std::string include_guard_ident = file_name_; diff --git a/src/idl_gen_general.cpp b/src/idl_gen_general.cpp index 4a4e54dc4..71ea19ed1 100644 --- a/src/idl_gen_general.cpp +++ b/src/idl_gen_general.cpp @@ -1115,40 +1115,6 @@ static void GenStruct(const LanguageParameters &lang, const Parser &parser, code += "};\n\n"; } -// Save out the generated code for a single class while adding -// declaration boilerplate. -static bool SaveClass(const LanguageParameters &lang, const Parser &parser, - const std::string &defname, const std::string &classcode, - const std::string &path, bool needs_includes, bool onefile) { - if (!classcode.length()) return true; - - std::string namespace_general; - std::string namespace_dir = path; // Either empty or ends in separator. - auto &namespaces = parser.namespaces_.back()->components; - for (auto it = namespaces.begin(); it != namespaces.end(); ++it) { - if (namespace_general.length()) { - namespace_general += "."; - } - namespace_general += *it; - if (!onefile) { - namespace_dir += *it + kPathSeparator; - } - - } - EnsureDirExists(namespace_dir); - - std::string code = "// automatically generated, do not modify\n\n"; - if (!namespace_general.empty()) { - code += lang.namespace_ident + namespace_general + lang.namespace_begin; - code += "\n\n"; - } - if (needs_includes) code += lang.includes; - code += classcode; - if (!namespace_general.empty()) code += lang.namespace_end; - auto filename = namespace_dir + defname + lang.file_extension; - return SaveFile(filename.c_str(), code, false); -} - namespace general { class GeneralGenerator : public BaseGenerator { public: @@ -1167,9 +1133,7 @@ class GeneralGenerator : public BaseGenerator { if (parser_.opts.one_file) { one_file_code += enumcode; } else { - if (!SaveClass(lang, parser_, (**it).name, enumcode, path_, false, - false)) - return false; + if (!SaveType(lang, (**it).name, enumcode, false, false)) return false; } } @@ -1180,18 +1144,49 @@ class GeneralGenerator : public BaseGenerator { if (parser_.opts.one_file) { one_file_code += declcode; } else { - if (!SaveClass(lang, parser_, (**it).name, declcode, path_, true, - false)) - return false; + if (!SaveType(lang, (**it).name, declcode, true, false)) return false; } } if (parser_.opts.one_file) { - return SaveClass(lang, parser_, file_name_, one_file_code, path_, true, - true); + return SaveType(lang, file_name_, one_file_code, true, true); } return true; } + + // Save out the generated code for a single class while adding + // declaration boilerplate. + bool SaveType(const LanguageParameters &lang, const std::string &defname, + const std::string &classcode, bool needs_includes, + bool onefile) { + if (!classcode.length()) return true; + + std::string namespace_general; + std::string namespace_dir = path_; // Either empty or ends in separator. + auto &namespaces = parser_.namespaces_.back()->components; + for (auto it = namespaces.begin(); it != namespaces.end(); ++it) { + if (namespace_general.length()) { + namespace_general += "."; + } + namespace_general += *it; + if (!onefile) { + namespace_dir += *it + kPathSeparator; + } + } + EnsureDirExists(namespace_dir); + + std::string code; + code = code + "// " + FlatBuffersGeneratedWarning(); + if (!namespace_general.empty()) { + code += lang.namespace_ident + namespace_general + lang.namespace_begin; + code += "\n\n"; + } + if (needs_includes) code += lang.includes; + code += classcode; + if (!namespace_general.empty()) code += lang.namespace_end; + auto filename = namespace_dir + defname + lang.file_extension; + return SaveFile(filename.c_str(), code, false); + } }; } // namespace general diff --git a/src/idl_gen_go.cpp b/src/idl_gen_go.cpp index bce8f95bc..be437c7b0 100644 --- a/src/idl_gen_go.cpp +++ b/src/idl_gen_go.cpp @@ -53,20 +53,6 @@ std::string OffsetPrefix(const FieldDef &field) { "))\n\tif o != 0 {\n"; } -// Begin by declaring namespace and imports. -static void BeginFile(const std::string name_space_name, - const bool needs_imports, - std::string *code_ptr) { - std::string &code = *code_ptr; - code += "// automatically generated, do not modify\n\n"; - code += "package " + name_space_name + "\n\n"; - if (needs_imports) { - code += "import (\n"; - code += "\tflatbuffers \"github.com/google/flatbuffers/go\"\n"; - code += ")\n"; - } -} - // Begin a class declaration. static void BeginClass(const StructDef &struct_def, std::string *code_ptr) { std::string &code = *code_ptr; @@ -589,32 +575,6 @@ static std::string GenMethod(const FieldDef &field) { : (IsStruct(field.value.type) ? "Struct" : "UOffsetT"); } - -// Save out the generated code for a Go Table type. -static bool SaveType(const Parser &parser, const Definition &def, - const std::string &classcode, const std::string &path, - bool needs_imports) { - if (!classcode.length()) return true; - - std::string namespace_name; - std::string namespace_dir = path; // Either empty or ends in separator. - auto &namespaces = parser.namespaces_.back()->components; - for (auto it = namespaces.begin(); it != namespaces.end(); ++it) { - if (namespace_name.length()) { - namespace_name += "."; - } - namespace_name = *it; - namespace_dir += *it + kPathSeparator; - } - EnsureDirExists(namespace_dir); - - std::string code = ""; - BeginFile(namespace_name, needs_imports, &code); - code += classcode; - std::string filename = namespace_dir + def.name + ".go"; - return SaveFile(filename.c_str(), code, false); -} - static std::string GenTypeBasic(const Type &type) { static const char *ctypename[] = { #define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE, JTYPE, GTYPE, NTYPE, PTYPE) \ @@ -671,18 +631,56 @@ class GoGenerator : public BaseGenerator { ++it) { std::string enumcode; go::GenEnum(**it, &enumcode); - if (!go::SaveType(parser_, **it, enumcode, path_, false)) return false; + if (!SaveType(**it, enumcode, false)) return false; } for (auto it = parser_.structs_.vec.begin(); it != parser_.structs_.vec.end(); ++it) { std::string declcode; go::GenStruct(**it, &declcode, parser_.root_struct_def_); - if (!go::SaveType(parser_, **it, declcode, path_, true)) return false; + if (!SaveType(**it, declcode, true)) return false; } return true; } + + private: + // Begin by declaring namespace and imports. + void BeginFile(const std::string name_space_name, const bool needs_imports, + std::string *code_ptr) { + std::string &code = *code_ptr; + code = code + "// " + FlatBuffersGeneratedWarning(); + code += "package " + name_space_name + "\n\n"; + if (needs_imports) { + code += "import (\n"; + code += "\tflatbuffers \"github.com/google/flatbuffers/go\"\n"; + code += ")\n"; + } + } + + // Save out the generated code for a Go Table type. + bool SaveType(const Definition &def, const std::string &classcode, + bool needs_imports) { + if (!classcode.length()) return true; + + std::string namespace_name; + std::string namespace_dir = path_; // Either empty or ends in separator. + auto &namespaces = parser_.namespaces_.back()->components; + for (auto it = namespaces.begin(); it != namespaces.end(); ++it) { + if (namespace_name.length()) { + namespace_name += "."; + } + namespace_name = *it; + namespace_dir += *it + kPathSeparator; + } + EnsureDirExists(namespace_dir); + + std::string code = ""; + BeginFile(namespace_name, needs_imports, &code); + code += classcode; + std::string filename = namespace_dir + def.name + ".go"; + return SaveFile(filename.c_str(), code, false); + } }; } // namespace go diff --git a/src/idl_gen_js.cpp b/src/idl_gen_js.cpp index 0265394ed..d724b80f4 100644 --- a/src/idl_gen_js.cpp +++ b/src/idl_gen_js.cpp @@ -684,9 +684,7 @@ class JsGenerator : public BaseGenerator { generateEnums(&enum_code, &exports_code); generateStructs(&struct_code, &exports_code); - code += - "// automatically generated by the FlatBuffers compiler, do not " - "modify\n\n"; + code = code + "// " + FlatBuffersGeneratedWarning(); // Generate code for all the namespace declarations. GenNamespaces(parser_, &code, &exports_code); diff --git a/src/idl_gen_php.cpp b/src/idl_gen_php.cpp index b43ea6702..5fb412434 100644 --- a/src/idl_gen_php.cpp +++ b/src/idl_gen_php.cpp @@ -54,24 +54,6 @@ namespace php { // Hardcode spaces per indentation. const std::string Indent = " "; - // Begin by declaring namespace and imports. - static void BeginFile(const std::string name_space_name, - const bool needs_imports, - std::string *code_ptr) { - std::string &code = *code_ptr; - code += "components; - for (auto it = namespaces.begin(); it != namespaces.end(); ++it) { - if (namespace_name.length()) { - namespace_name += "\\"; - namespace_dir += kPathSeparator; - } - namespace_name += *it; - namespace_dir += *it; - EnsureDirExists(namespace_dir.c_str()); - } - - std::string code = ""; - BeginFile(namespace_name, needs_imports, &code); - code += classcode; - - std::string filename = namespace_dir + kPathSeparator + def.name + ".php"; - return SaveFile(filename.c_str(), code, false); - } - static std::string GenTypeBasic(const Type &type) { static const char *ctypename[] = { #define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE, JTYPE, GTYPE, NTYPE, PTYPE) \ @@ -993,8 +946,7 @@ namespace php { auto &enum_def = **it; std::string enumcode; GenEnum(enum_def, &enumcode); - if (!SaveType(parser_, enum_def, enumcode, path_, false)) - return false; + if (!SaveType(enum_def, enumcode, false)) return false; } return true; } @@ -1005,11 +957,55 @@ namespace php { auto &struct_def = **it; std::string declcode; GenStruct(parser_, struct_def, &declcode); - if (!SaveType(parser_, struct_def, declcode, path_, true)) - return false; + if (!SaveType(struct_def, declcode, true)) return false; } return true; } + + // Begin by declaring namespace and imports. + void BeginFile(const std::string name_space_name, + const bool needs_imports, std::string *code_ptr) { + std::string &code = *code_ptr; + code += "components; + for (auto it = namespaces.begin(); it != namespaces.end(); ++it) { + if (namespace_name.length()) { + namespace_name += "\\"; + namespace_dir += kPathSeparator; + } + namespace_name += *it; + namespace_dir += *it; + EnsureDirExists(namespace_dir.c_str()); + } + + std::string code = ""; + BeginFile(namespace_name, needs_imports, &code); + code += classcode; + + std::string filename = + namespace_dir + kPathSeparator + def.name + ".php"; + return SaveFile(filename.c_str(), code, false); + } }; } // namespace php diff --git a/src/idl_gen_python.cpp b/src/idl_gen_python.cpp index ee6d16874..291aada0e 100644 --- a/src/idl_gen_python.cpp +++ b/src/idl_gen_python.cpp @@ -49,18 +49,6 @@ std::string OffsetPrefix(const FieldDef &field) { "))\n" + Indent + Indent + "if o != 0:\n"; } -// Begin by declaring namespace and imports. -static void BeginFile(const std::string name_space_name, - const bool needs_imports, - std::string *code_ptr) { - std::string &code = *code_ptr; - code += "# automatically generated, do not modify\n\n"; - code += "# namespace: " + name_space_name + "\n\n"; - if (needs_imports) { - code += "import flatbuffers\n\n"; - } -} - // Begin a class declaration. static void BeginClass(const StructDef &struct_def, std::string *code_ptr) { std::string &code = *code_ptr; @@ -558,37 +546,6 @@ static std::string GenMethod(const FieldDef &field) { : (IsStruct(field.value.type) ? "Struct" : "UOffsetTRelative"); } - -// Save out the generated code for a Python Table type. -static bool SaveType(const Parser &parser, const Definition &def, - const std::string &classcode, const std::string &path, - bool needs_imports) { - if (!classcode.length()) return true; - - std::string namespace_name; - std::string namespace_dir = path; - auto &namespaces = parser.namespaces_.back()->components; - for (auto it = namespaces.begin(); it != namespaces.end(); ++it) { - if (namespace_name.length()) { - namespace_name += "."; - namespace_dir += kPathSeparator; - } - namespace_name = *it; - namespace_dir += *it; - EnsureDirExists(namespace_dir.c_str()); - - std::string init_py_filename = namespace_dir + "/__init__.py"; - SaveFile(init_py_filename.c_str(), "", false); - } - - - std::string code = ""; - BeginFile(namespace_name, needs_imports, &code); - code += classcode; - std::string filename = namespace_dir + kPathSeparator + def.name + ".py"; - return SaveFile(filename.c_str(), code, false); -} - static std::string GenTypeBasic(const Type &type) { static const char *ctypename[] = { #define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE, JTYPE, GTYPE, NTYPE, PTYPE) \ @@ -653,7 +610,7 @@ class PythonGenerator : public BaseGenerator { auto &enum_def = **it; std::string enumcode; GenEnum(enum_def, &enumcode); - if (!SaveType(parser_, enum_def, enumcode, path_, false)) return false; + if (!SaveType(enum_def, enumcode, false)) return false; } return true; } @@ -664,10 +621,49 @@ class PythonGenerator : public BaseGenerator { auto &struct_def = **it; std::string declcode; GenStruct(struct_def, &declcode, parser_.root_struct_def_); - if (!SaveType(parser_, struct_def, declcode, path_, true)) return false; + if (!SaveType(struct_def, declcode, true)) return false; } return true; } + + // Begin by declaring namespace and imports. + void BeginFile(const std::string name_space_name, const bool needs_imports, + std::string *code_ptr) { + std::string &code = *code_ptr; + code = code + "# " + FlatBuffersGeneratedWarning(); + code += "# namespace: " + name_space_name + "\n\n"; + if (needs_imports) { + code += "import flatbuffers\n\n"; + } + } + + // Save out the generated code for a Python Table type. + bool SaveType(const Definition &def, const std::string &classcode, + bool needs_imports) { + if (!classcode.length()) return true; + + std::string namespace_name; + std::string namespace_dir = path_; + auto &namespaces = parser_.namespaces_.back()->components; + for (auto it = namespaces.begin(); it != namespaces.end(); ++it) { + if (namespace_name.length()) { + namespace_name += "."; + namespace_dir += kPathSeparator; + } + namespace_name = *it; + namespace_dir += *it; + EnsureDirExists(namespace_dir.c_str()); + + std::string init_py_filename = namespace_dir + "/__init__.py"; + SaveFile(init_py_filename.c_str(), "", false); + } + + std::string code = ""; + BeginFile(namespace_name, needs_imports, &code); + code += classcode; + std::string filename = namespace_dir + kPathSeparator + def.name + ".py"; + return SaveFile(filename.c_str(), code, false); + } }; } // namespace python diff --git a/tests/MyGame/Example/Any.cs b/tests/MyGame/Example/Any.cs index a05a91851..1f018ad89 100644 --- a/tests/MyGame/Example/Any.cs +++ b/tests/MyGame/Example/Any.cs @@ -1,4 +1,4 @@ -// automatically generated, do not modify +// automatically generated by the FlatBuffers compiler, do not modify namespace MyGame.Example { diff --git a/tests/MyGame/Example/Any.go b/tests/MyGame/Example/Any.go index a23de4cbc..0322364c6 100644 --- a/tests/MyGame/Example/Any.go +++ b/tests/MyGame/Example/Any.go @@ -1,4 +1,4 @@ -// automatically generated, do not modify +// automatically generated by the FlatBuffers compiler, do not modify package Example diff --git a/tests/MyGame/Example/Any.java b/tests/MyGame/Example/Any.java index cdc3ec567..27dc1bcb9 100644 --- a/tests/MyGame/Example/Any.java +++ b/tests/MyGame/Example/Any.java @@ -1,4 +1,4 @@ -// automatically generated, do not modify +// automatically generated by the FlatBuffers compiler, do not modify package MyGame.Example; diff --git a/tests/MyGame/Example/Any.php b/tests/MyGame/Example/Any.php index d35bfd639..f04f4ad3f 100644 --- a/tests/MyGame/Example/Any.php +++ b/tests/MyGame/Example/Any.php @@ -1,5 +1,5 @@