diff --git a/docs/source/Compiler.md b/docs/source/Compiler.md index 9eaabf811..df0378669 100644 --- a/docs/source/Compiler.md +++ b/docs/source/Compiler.md @@ -203,5 +203,8 @@ Additional options: - `--force-empty` : When serializing from object API representation, force strings and vectors to empty rather than null. +- `--force-empty-vectors` : When serializing from object API representation, force + vectors to empty rather than null. + NOTE: short-form options for generators are deprecated, use the long form whenever possible. diff --git a/include/flatbuffers/idl.h b/include/flatbuffers/idl.h index 4e8f71d37..21616210e 100644 --- a/include/flatbuffers/idl.h +++ b/include/flatbuffers/idl.h @@ -588,9 +588,13 @@ struct IDLOptions { // for code generation. unsigned long lang_to_generate; - // If set (default behavior), empty string and vector fields will be set to - // nullptr to make the flatbuffer more compact. - bool set_empty_to_null; + // If set (default behavior), empty string fields will be set to nullptr to make + // the flatbuffer more compact. + bool set_empty_strings_to_null; + + // If set (default behavior), empty vector fields will be set to nullptr to make + // the flatbuffer more compact. + bool set_empty_vectors_to_null; IDLOptions() : use_flexbuffers(false), @@ -635,7 +639,8 @@ struct IDLOptions { lang(IDLOptions::kJava), mini_reflect(IDLOptions::kNone), lang_to_generate(0), - set_empty_to_null(true) {} + set_empty_strings_to_null(true), + set_empty_vectors_to_null(true) {} }; // This encapsulates where the parser is in the current source file. diff --git a/src/flatc.cpp b/src/flatc.cpp index 8cc2d3c94..9c59232f6 100644 --- a/src/flatc.cpp +++ b/src/flatc.cpp @@ -63,7 +63,7 @@ std::string FlatCompiler::GetUsageString(const char *program_name) const { const Generator &g = params_.generators[i]; std::stringstream full_name; - full_name << std::setw(12) << std::left << g.generator_opt_long; + full_name << std::setw(16) << std::left << g.generator_opt_long; const char *name = g.generator_opt_short ? g.generator_opt_short : " "; const char *help = g.generator_help; @@ -71,86 +71,88 @@ std::string FlatCompiler::GetUsageString(const char *program_name) const { } // clang-format off ss << - " -o PATH Prefix PATH to all generated files.\n" - " -I PATH Search for includes in the specified path.\n" - " -M Print make rules for generated files.\n" - " --version Print the version number of flatc and exit.\n" - " --strict-json Strict JSON: field names must be / will be quoted,\n" - " no trailing commas in tables/vectors.\n" - " --allow-non-utf8 Pass non-UTF-8 input through parser and emit nonstandard\n" - " \\x escapes in JSON. (Default is to raise parse error on\n" - " non-UTF-8 input.)\n" - " --natural-utf8 Output strings with UTF-8 as human-readable strings.\n" - " By default, UTF-8 characters are printed as \\uXXXX escapes.\n" - " --defaults-json Output fields whose value is the default when\n" - " writing JSON\n" - " --unknown-json Allow fields in JSON that are not defined in the\n" - " schema. These fields will be discared when generating\n" - " binaries.\n" - " --no-prefix Don\'t prefix enum values with the enum type in C++.\n" - " --scoped-enums Use C++11 style scoped and strongly typed enums.\n" - " also implies --no-prefix.\n" - " --gen-includes (deprecated), this is the default behavior.\n" - " If the original behavior is required (no include\n" - " statements) use --no-includes.\n" - " --no-includes Don\'t generate include statements for included\n" - " schemas the generated file depends on (C++ / Python).\n" - " --gen-mutable Generate accessors that can mutate buffers in-place.\n" - " --gen-onefile Generate single output file for C# and Go.\n" - " --gen-name-strings Generate type name functions for C++.\n" - " --gen-object-api Generate an additional object-based API.\n" - " --gen-compare Generate operator== for object-based API types.\n" - " --gen-nullable Add Clang _Nullable for C++ pointer. or @Nullable for Java\n" - " --java-checkerframework Add @Pure for Java.\n" - " --gen-generated Add @Generated annotation for Java\n" - " --gen-all Generate not just code for the current schema files,\n" - " but for all files it includes as well.\n" - " If the language uses a single file for output (by default\n" - " the case for C++ and JS), all code will end up in this one\n" - " file.\n" - " --cpp-include Adds an #include in generated file.\n" - " --cpp-ptr-type T Set object API pointer type (default std::unique_ptr).\n" - " --cpp-str-type T Set object API string type (default std::string).\n" - " T::c_str(), T::length() and T::empty() must be supported.\n" - " The custom type also needs to be constructible from std::string\n" - " (see the --cpp-str-flex-ctor option to change this behavior).\n" - " --cpp-str-flex-ctor Don't construct custom string types by passing std::string\n" - " from Flatbuffers, but (char* + length).\n" - " --object-prefix Customise class prefix for C++ object-based API.\n" - " --object-suffix Customise class suffix for C++ object-based API.\n" - " Default value is \"T\".\n" - " --no-js-exports Removes Node.js style export lines in JS.\n" - " --goog-js-export Uses goog.exports* for closure compiler exporting in JS.\n" - " --es6-js-export Uses ECMAScript 6 export style lines in JS.\n" - " --go-namespace Generate the overrided namespace in Golang.\n" - " --go-import Generate the overrided import for flatbuffers in Golang\n" - " (default is \"github.com/google/flatbuffers/go\").\n" - " --raw-binary Allow binaries without file_indentifier to be read.\n" - " This may crash flatc given a mismatched schema.\n" - " --size-prefixed Input binaries are size prefixed buffers.\n" - " --proto Input is a .proto, translate to .fbs.\n" - " --oneof-union Translate .proto oneofs to flatbuffer unions.\n" - " --grpc Generate GRPC interfaces for the specified languages.\n" - " --schema Serialize schemas instead of JSON (use with -b).\n" - " --bfbs-comments Add doc comments to the binary schema files.\n" - " --bfbs-builtins Add builtin attributes to the binary schema files.\n" - " --conform FILE Specify a schema the following schemas should be\n" - " an evolution of. Gives errors if not.\n" - " --conform-includes Include path for the schema given with --conform PATH\n" - " --include-prefix Prefix this path to any generated include statements.\n" + " -o PATH Prefix PATH to all generated files.\n" + " -I PATH Search for includes in the specified path.\n" + " -M Print make rules for generated files.\n" + " --version Print the version number of flatc and exit.\n" + " --strict-json Strict JSON: field names must be / will be quoted,\n" + " no trailing commas in tables/vectors.\n" + " --allow-non-utf8 Pass non-UTF-8 input through parser and emit nonstandard\n" + " \\x escapes in JSON. (Default is to raise parse error on\n" + " non-UTF-8 input.)\n" + " --natural-utf8 Output strings with UTF-8 as human-readable strings.\n" + " By default, UTF-8 characters are printed as \\uXXXX escapes.\n" + " --defaults-json Output fields whose value is the default when\n" + " writing JSON\n" + " --unknown-json Allow fields in JSON that are not defined in the\n" + " schema. These fields will be discared when generating\n" + " binaries.\n" + " --no-prefix Don\'t prefix enum values with the enum type in C++.\n" + " --scoped-enums Use C++11 style scoped and strongly typed enums.\n" + " also implies --no-prefix.\n" + " --gen-includes (deprecated), this is the default behavior.\n" + " If the original behavior is required (no include\n" + " statements) use --no-includes.\n" + " --no-includes Don\'t generate include statements for included\n" + " schemas the generated file depends on (C++ / Python).\n" + " --gen-mutable Generate accessors that can mutate buffers in-place.\n" + " --gen-onefile Generate single output file for C# and Go.\n" + " --gen-name-strings Generate type name functions for C++.\n" + " --gen-object-api Generate an additional object-based API.\n" + " --gen-compare Generate operator== for object-based API types.\n" + " --gen-nullable Add Clang _Nullable for C++ pointer. or @Nullable for Java\n" + " --java-checkerframe work Add @Pure for Java.\n" + " --gen-generated Add @Generated annotation for Java\n" + " --gen-all Generate not just code for the current schema files,\n" + " but for all files it includes as well.\n" + " If the language uses a single file for output (by default\n" + " the case for C++ and JS), all code will end up in this one\n" + " file.\n" + " --cpp-include Adds an #include in generated file.\n" + " --cpp-ptr-type T Set object API pointer type (default std::unique_ptr).\n" + " --cpp-str-type T Set object API string type (default std::string).\n" + " T::c_str(), T::length() and T::empty() must be supported.\n" + " The custom type also needs to be constructible from std::string\n" + " (see the --cpp-str-flex-ctor option to change this behavior).\n" + " --cpp-str-flex-ctor Don't construct custom string types by passing std::string\n" + " from Flatbuffers, but (char* + length).\n" + " --object-prefix Customise class prefix for C++ object-based API.\n" + " --object-suffix Customise class suffix for C++ object-based API.\n" + " Default value is \"T\".\n" + " --no-js-exports Removes Node.js style export lines in JS.\n" + " --goog-js-export Uses goog.exports* for closure compiler exporting in JS.\n" + " --es6-js-export Uses ECMAScript 6 export style lines in JS.\n" + " --go-namespace Generate the overrided namespace in Golang.\n" + " --go-import Generate the overrided import for flatbuffers in Golang\n" + " (default is \"github.com/google/flatbuffers/go\").\n" + " --raw-binary Allow binaries without file_indentifier to be read.\n" + " This may crash flatc given a mismatched schema.\n" + " --size-prefixed Input binaries are size prefixed buffers.\n" + " --proto Input is a .proto, translate to .fbs.\n" + " --oneof-union Translate .proto oneofs to flatbuffer unions.\n" + " --grpc Generate GRPC interfaces for the specified languages.\n" + " --schema Serialize schemas instead of JSON (use with -b).\n" + " --bfbs-comments Add doc comments to the binary schema files.\n" + " --bfbs-builtins Add builtin attributes to the binary schema files.\n" + " --conform FILE Specify a schema the following schemas should be\n" + " an evolution of. Gives errors if not.\n" + " --conform-includes Include path for the schema given with --conform PATH\n" + " --include-prefix Prefix this path to any generated include statements.\n" " PATH\n" - " --keep-prefix Keep original prefix of schema include statement.\n" - " --no-fb-import Don't include flatbuffers import statement for TypeScript.\n" - " --no-ts-reexport Don't re-export imported dependencies for TypeScript.\n" - " --short-names Use short function names for JS and TypeScript.\n" - " --reflect-types Add minimal type reflection to code generation.\n" - " --reflect-names Add minimal type/name reflection.\n" - " --root-type T Select or override the default root_type\n" - " --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" + " --keep-prefix Keep original prefix of schema include statement.\n" + " --no-fb-import Don't include flatbuffers import statement for TypeScript.\n" + " --no-ts-reexport Don't re-export imported dependencies for TypeScript.\n" + " --short-names Use short function names for JS and TypeScript.\n" + " --reflect-types Add minimal type reflection to code generation.\n" + " --reflect-names Add minimal type/name reflection.\n" + " --root-type T Select or override the default root_type\n" + " --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" + " --force-empty-vectors When serializing from object API representation,\n" + " force 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" @@ -323,7 +325,10 @@ int FlatCompiler::Compile(int argc, const char **argv) { } else if (arg == "--force-defaults") { opts.force_defaults = true; } else if (arg == "--force-empty") { - opts.set_empty_to_null = false; + opts.set_empty_strings_to_null = false; + opts.set_empty_vectors_to_null = false; + } else if (arg == "--force-empty-vectors") { + opts.set_empty_vectors_to_null = false; } else if (arg == "--java-primitive-has-method") { opts.java_primitive_has_method = true; } else if (arg == "--flexbuffers") { diff --git a/src/idl_gen_cpp.cpp b/src/idl_gen_cpp.cpp index 7a467928d..fd53eceaa 100644 --- a/src/idl_gen_cpp.cpp +++ b/src/idl_gen_cpp.cpp @@ -2452,10 +2452,10 @@ class CppGenerator : public BaseGenerator { // For optional fields, check to see if there actually is any data // in _o->field before attempting to access it. If there isn't, - // depending on set_empty_to_null either set it to 0 or an empty string. + // depending on set_empty_strings_to_null either set it to 0 or an empty string. if (!field.required) { auto empty_value = - opts.set_empty_to_null ? "0" : "_fbb.CreateSharedString(\"\")"; + opts.set_empty_strings_to_null ? "0" : "_fbb.CreateSharedString(\"\")"; code = value + ".empty() ? " + empty_value + " : " + code; } break; @@ -2557,10 +2557,10 @@ class CppGenerator : public BaseGenerator { } } - // If set_empty_to_null option is enabled, for optional fields, check to + // If set_empty_vectors_to_null option is enabled, for optional fields, check to // see if there actually is any data in _o->field before attempting to // access it. - if (opts.set_empty_to_null && !field.required) { + if (opts.set_empty_vectors_to_null && !field.required) { code = value + ".size() ? " + code + " : 0"; } break;