#ifndef FLATBUFFERS_NAMER
#define FLATBUFFERS_NAMER
#include "flatbuffers/util.h"
namespace flatbuffers {
enum class SkipFile {
None = 0,
Suffix = 1,
Extension = 2,
SuffixAndExtension = 3,
};
inline SkipFile operator&(SkipFile a, SkipFile b) {
return static_cast<SkipFile>(static_cast<int>(a) & static_cast<int>(b));
}
enum class SkipDir {
None = 0,
OutputPath = 1,
TrailingPathSeperator = 2,
OutputPathAndTrailingPathSeparator = 3,
};
inline SkipDir operator&(SkipDir a, SkipDir b) {
return static_cast<SkipDir>(static_cast<int>(a) & static_cast<int>(b));
}
class Namer {
public:
struct Config {
Case types;
Case constants;
Case methods;
Case functions;
Case fields;
Case variables;
Case variants;
std::string enum_variant_seperator;
enum class Escape {
BeforeConvertingCase,
AfterConvertingCase,
};
Escape escape_keywords;
Case namespaces;
std::string namespace_seperator;
std::string object_prefix;
std::string object_suffix;
std::string keyword_prefix;
std::string keyword_suffix;
Case filenames;
Case directories;
std::string output_path;
std::string filename_suffix;
std::string filename_extension;
};
Namer(Config config, std::set<std::string> keywords)
: config_(config), keywords_(std::move(keywords)) {}
virtual ~Namer() {}
template<typename T> std::string Method(const T &s) const {
return Method(s.name);
}
virtual std::string Method(const std::string &pre,
const std::string &mid,
const std::string &suf) const {
return Format(pre + "_" + mid + "_" + suf, config_.methods);
}
virtual std::string Method(const std::string &pre,
const std::string &suf) const {
return Format(pre + "_" + suf, config_.methods);
}
virtual std::string Method(const std::string &s) const {
return Format(s, config_.methods);
}
virtual std::string Constant(const std::string &s) const {
return Format(s, config_.constants);
}
virtual std::string Function(const std::string &s) const {
return Format(s, config_.functions);
}
virtual std::string Variable(const std::string &s) const {
return Format(s, config_.variables);
}
template<typename T>
std::string Variable(const std::string &p, const T &s) const {
return Format(p + "_" + s.name, config_.variables);
}
virtual std::string Variable(const std::string &p,
const std::string &s) const {
return Format(p + "_" + s, config_.variables);
}
virtual std::string Namespace(const std::string &s) const {
return Format(s, config_.namespaces);
}
virtual std::string Namespace(const std::vector<std::string> &ns) const {
std::string result;
for (auto it = ns.begin(); it != ns.end(); it++) {
if (it != ns.begin()) result += config_.namespace_seperator;
result += Namespace(*it);
}
return result;
}
virtual std::string NamespacedType(const std::vector<std::string> &ns,
const std::string &s) const {
return (ns.empty() ? "" : (Namespace(ns) + config_.namespace_seperator)) +
Type(s);
}
virtual std::string File(const std::string &filename,
SkipFile skips = SkipFile::None) const {
const bool skip_suffix = (skips & SkipFile::Suffix) != SkipFile::None;
const bool skip_ext = (skips & SkipFile::Extension) != SkipFile::None;
return ConvertCase(filename, config_.filenames, Case::kUpperCamel) +
(skip_suffix ? "" : config_.filename_suffix) +
(skip_ext ? "" : config_.filename_extension);
}
template<typename T>
std::string File(const T &f, SkipFile skips = SkipFile::None) const {
return File(f.name, skips);
}
virtual std::string Directories(const std::vector<std::string> &directories,
SkipDir skips = SkipDir::None,
Case input_case = Case::kUpperCamel) const {
const bool skip_output_path =
(skips & SkipDir::OutputPath) != SkipDir::None;
const bool skip_trailing_seperator =
(skips & SkipDir::TrailingPathSeperator) != SkipDir::None;
std::string result = skip_output_path ? "" : config_.output_path;
for (auto d = directories.begin(); d != directories.end(); d++) {
result += ConvertCase(*d, config_.directories, input_case);
result.push_back(kPathSeparator);
}
if (skip_trailing_seperator && !result.empty()) result.pop_back();
return result;
}
virtual std::string EscapeKeyword(const std::string &name) const {
if (keywords_.find(name) == keywords_.end()) {
return name;
} else {
return config_.keyword_prefix + name + config_.keyword_suffix;
}
}
virtual std::string Type(const std::string &s) const {
return Format(s, config_.types);
}
virtual std::string Type(const std::string &t, const std::string &s) const {
return Format(t + "_" + s, config_.types);
}
virtual std::string ObjectType(const std::string &s) const {
return config_.object_prefix + Type(s) + config_.object_suffix;
}
virtual std::string Field(const std::string &s) const {
return Format(s, config_.fields);
}
virtual std::string Variant(const std::string &s) const {
return Format(s, config_.variants);
}
virtual std::string Format(const std::string &s, Case casing) const {
if (config_.escape_keywords == Config::Escape::BeforeConvertingCase) {
return ConvertCase(EscapeKeyword(s), casing, Case::kLowerCamel);
} else {
return EscapeKeyword(ConvertCase(s, casing, Case::kLowerCamel));
}
}
virtual std::string Denamespace(const std::string &s,
std::string &namespace_prefix,
const char delimiter = '.') const {
const size_t pos = s.find_last_of(delimiter);
if (pos == std::string::npos) {
namespace_prefix = "";
return s;
}
namespace_prefix = s.substr(0, pos);
return s.substr(pos + 1);
}
virtual std::string Denamespace(const std::string &s,
const char delimiter = '.') const {
std::string prefix;
return Denamespace(s, prefix, delimiter);
}
const Config config_;
const std::set<std::string> keywords_;
};
}
#endif