class Reference {
public:
+ Reference()
+ : data_(nullptr),
+ parent_width_(0),
+ byte_width_(BIT_WIDTH_8),
+ type_(FBT_NULL) {}
+
Reference(const uint8_t *data, uint8_t parent_width, uint8_t byte_width,
Type type)
: data_(data),
// Container of options that may apply to any of the source/text generators.
struct IDLOptions {
+ // Use flexbuffers instead for binary and text generation
+ bool use_flexbuffers;
bool strict_json;
bool skip_js_exports;
bool use_goog_js_export_format;
bool set_empty_to_null;
IDLOptions()
- : strict_json(false),
+ : use_flexbuffers(false),
+ strict_json(false),
skip_js_exports(false),
use_goog_js_export_format(false),
use_ES6_js_export_format(false),
explicit Parser(const IDLOptions &options = IDLOptions())
: current_namespace_(nullptr),
empty_namespace_(nullptr),
+ flex_builder_(256, flexbuffers::BUILDER_FLAG_SHARE_ALL),
root_struct_def_(nullptr),
opts(options),
uses_flexbuffers_(false),
std::string error_; // User readable error_ if Parse() == false
FlatBufferBuilder builder_; // any data contained in the file
+ flexbuffers::Builder flex_builder_;
+ flexbuffers::Reference flex_root_;
StructDef *root_struct_def_;
std::string file_identifier_;
std::string file_extension_;
" --force-defaults Emit default values in binary output from JSON\n"
" --force-empty When serializing from object API representation,\n"
" force strings and vectors to empty rather than null.\n"
+ " --flexbuffers Used with \"binary\" and \"json\" options, it generates\n"
+ " data using schema-less FlexBuffers.\n"
"FILEs may be schemas (must end in .fbs), binary schemas (must end in .bfbs),\n"
"or JSON files (conforming to preceding schema). FILEs after the -- must be\n"
"binary flatbuffer format files.\n"
opts.set_empty_to_null = false;
} else if (arg == "--java-primitive-has-method") {
opts.java_primitive_has_method = true;
+ } else if (arg == "--flexbuffers") {
+ opts.use_flexbuffers = true;
} else {
for (size_t i = 0; i < params_.num_generators; ++i) {
if (arg == params_.generators[i].generator_opt_long ||
}
} else {
// Check if file contains 0 bytes.
- if (!is_binary_schema && contents.length() != strlen(contents.c_str())) {
+ if (!opts.use_flexbuffers && !is_binary_schema &&
+ contents.length() != strlen(contents.c_str())) {
Error("input file appears to be binary: " + filename, true);
}
if (is_schema) {
}
if (is_binary_schema) {
LoadBinarySchema(*parser.get(), filename, contents);
+ }
+ if (opts.use_flexbuffers) {
+ if (opts.lang_to_generate == IDLOptions::kJson) {
+ parser->flex_root_ = flexbuffers::GetRoot(
+ reinterpret_cast<const uint8_t *>(contents.c_str()),
+ contents.size());
+ } else {
+ parser->flex_builder_.Clear();
+ ParseFile(*parser.get(), filename, contents, include_directories);
+ }
} else {
ParseFile(*parser.get(), filename, contents, include_directories);
- if (!is_schema && !parser->builder_.GetSize()) {
+ if (!opts.use_flexbuffers && !is_schema &&
+ !parser->builder_.GetSize()) {
// If a file doesn't end in .fbs, it must be json/binary. Ensure we
// didn't just parse a schema with a different extension.
Error("input file is neither json nor a .fbs (schema) file: " +
bool GenerateBinary(const Parser &parser, const std::string &path,
const std::string &file_name) {
+ if (parser.opts.use_flexbuffers) {
+ auto data_vec = parser.flex_builder_.GetBuffer();
+ auto data_ptr = reinterpret_cast<char *>(data_vec.data());
+ return !parser.flex_builder_.GetSize() ||
+ flatbuffers::SaveFile(
+ BinaryFileName(parser, path, file_name).c_str(), data_ptr,
+ parser.flex_builder_.GetSize(), true);
+ }
return !parser.builder_.GetSize() ||
flatbuffers::SaveFile(
BinaryFileName(parser, path, file_name).c_str(),
bool GenerateTextFile(const Parser &parser, const std::string &path,
const std::string &file_name) {
+ if (parser.opts.use_flexbuffers) {
+ std::string json;
+ parser.flex_root_.ToString(true, parser.opts.strict_json, json);
+ return flatbuffers::SaveFile(TextFileName(path, file_name).c_str(),
+ json.c_str(), json.size(), true);
+ }
if (!parser.builder_.GetSize() || !parser.root_struct_def_) return true;
std::string text;
if (!GenerateText(parser, parser.builder_.GetBufferPointer(), &text)) {
bool Parser::Parse(const char *source, const char **include_paths,
const char *source_filename) {
FLATBUFFERS_ASSERT(0 == recurse_protection_counter);
- auto r = !ParseRoot(source, include_paths, source_filename).Check();
+ bool r;
+
+ if (opts.use_flexbuffers) {
+ r = ParseFlexBuffer(source, source_filename, &flex_builder_);
+ } else {
+ r = !ParseRoot(source, include_paths, source_filename).Check();
+ }
FLATBUFFERS_ASSERT(0 == recurse_protection_counter);
return r;
}