Skip to content
Snippets Groups Projects
idl_gen_general.cpp 43 KiB
Newer Older
// 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 += ".";
    if (!onefile) {
      namespace_dir += *it + kPathSeparator;
    }


  std::string code = "// automatically generated, do not modify\n\n";
Amol Deshpande's avatar
Amol Deshpande committed
  if (!namespace_general.empty()) {
	code += lang.namespace_ident + namespace_general + lang.namespace_begin;
	code += "\n\n";
  }
  if (needs_includes) code += lang.includes;
Amol Deshpande's avatar
Amol Deshpande committed
  if (!namespace_general.empty()) code += lang.namespace_end;
  auto filename = namespace_dir + defname + lang.file_extension;
  return SaveFile(filename.c_str(), code, false);
}

bool GenerateGeneral(const Parser &parser,
                     const std::string &path,
                     const std::string & file_name,
                     const GeneratorOptions &opts) {
  assert(opts.lang <= GeneratorOptions::kMAX);
  auto lang = language_parameters[opts.lang];
  std::string one_file_code;

  for (auto it = parser.enums_.vec.begin();
       it != parser.enums_.vec.end(); ++it) {
    std::string enumcode;
    GenEnum(lang, **it, &enumcode);
    if (opts.one_file) {
    }
    else {
      if (!SaveClass(lang, parser, (**it).name, enumcode, path, false, false))
        return false;
    }
  }

  for (auto it = parser.structs_.vec.begin();
       it != parser.structs_.vec.end(); ++it) {
    std::string declcode;
    GenStruct(lang, parser, **it, opts, &declcode);
    if (opts.one_file) {
      one_file_code += declcode;
    }
    else {
      if (!SaveClass(lang, parser, (**it).name, declcode, path, true, false))
        return false;
    }
  if (opts.one_file) {
    return SaveClass(lang, parser, file_name, one_file_code,path, true, true);
  }
static std::string ClassFileName(const LanguageParameters &lang,
                                 const Parser &parser, const Definition &def,
                                 const std::string &path) {
  std::string namespace_general;
  std::string namespace_dir = path;
  auto &namespaces = parser.namespaces_.back()->components;
  for (auto it = namespaces.begin(); it != namespaces.end(); ++it) {
    if (namespace_general.length()) {
      namespace_general += ".";
      namespace_dir += kPathSeparator;
    }
    namespace_general += *it;
    namespace_dir += *it;
  }

  return namespace_dir + kPathSeparator + def.name + lang.file_extension;
}

std::string GeneralMakeRule(const Parser &parser,
                            const std::string &path,
                            const std::string &file_name,
                            const GeneratorOptions &opts) {
  assert(opts.lang <= GeneratorOptions::kMAX);
  auto lang = language_parameters[opts.lang];

  std::string make_rule;

  for (auto it = parser.enums_.vec.begin();
       it != parser.enums_.vec.end(); ++it) {
    if (make_rule != "")
      make_rule += " ";
    make_rule += ClassFileName(lang, parser, **it, path);
  }

  for (auto it = parser.structs_.vec.begin();
       it != parser.structs_.vec.end(); ++it) {
    if (make_rule != "")
      make_rule += " ";
    make_rule += ClassFileName(lang, parser, **it, path);
  }

  make_rule += ": ";
  auto included_files = parser.GetIncludedFilesRecursive(file_name);
  for (auto it = included_files.begin();
       it != included_files.end(); ++it) {
    make_rule += " " + *it;
  }
  return make_rule;
}

std::string BinaryFileName(const Parser &parser,
                           const std::string &path,
                           const std::string &file_name) {
  auto ext = parser.file_extension_.length() ? parser.file_extension_ : "bin";
  return path + file_name + "." + ext;
}

bool GenerateBinary(const Parser &parser,
                    const std::string &path,
                    const std::string &file_name,
                    const GeneratorOptions & /*opts*/) {
  return !parser.builder_.GetSize() ||
         flatbuffers::SaveFile(
           BinaryFileName(parser, path, file_name).c_str(),
           reinterpret_cast<char *>(parser.builder_.GetBufferPointer()),
           parser.builder_.GetSize(),
           true);
}

std::string BinaryMakeRule(const Parser &parser,
                           const std::string &path,
                           const std::string &file_name,
                           const GeneratorOptions & /*opts*/) {
  if (!parser.builder_.GetSize()) return "";
  std::string filebase = flatbuffers::StripPath(
      flatbuffers::StripExtension(file_name));
  std::string make_rule = BinaryFileName(parser, path, filebase) + ": " +
      file_name;
  auto included_files = parser.GetIncludedFilesRecursive(
Amol Deshpande's avatar
Amol Deshpande committed
      parser.root_struct_def_->file);
  for (auto it = included_files.begin();
       it != included_files.end(); ++it) {
    make_rule += " " + *it;
  }
  return make_rule;
}

}  // namespace flatbuffers