diff options
author | Vladimir Glavnyy <31897320+vglavnyy@users.noreply.github.com> | 2020-09-19 02:51:17 +0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-09-18 12:51:17 -0700 |
commit | 8c67b5b129f445c6bf5dbcbf2a18fec4c6334f16 (patch) | |
tree | d66e068636de0b57a475f0f942c5ccfae2b6ef2c /src/idl_parser.cpp | |
parent | 6228b66d3d1f0e5d2f79e59834c8931d84cccaaf (diff) | |
download | flatbuffers-8c67b5b129f445c6bf5dbcbf2a18fec4c6334f16.tar.gz flatbuffers-8c67b5b129f445c6bf5dbcbf2a18fec4c6334f16.tar.bz2 flatbuffers-8c67b5b129f445c6bf5dbcbf2a18fec4c6334f16.zip |
Add support of Optional<T> scalars to C++ code generator (#6092)
Diffstat (limited to 'src/idl_parser.cpp')
-rw-r--r-- | src/idl_parser.cpp | 53 |
1 files changed, 39 insertions, 14 deletions
diff --git a/src/idl_parser.cpp b/src/idl_parser.cpp index 05b1b194..088246fc 100644 --- a/src/idl_parser.cpp +++ b/src/idl_parser.cpp @@ -743,6 +743,34 @@ CheckedError Parser::ParseField(StructDef &struct_def) { return Error( "default values currently only supported for scalars in tables"); } + + // Mark the optional scalars. Note that a side effect of ParseSingleValue is + // fixing field->value.constant to null. + if (IsScalar(type.base_type)) { + field->optional = (field->value.constant == "null"); + if (field->optional) { + if (type.enum_def && type.enum_def->Lookup("null")) { + FLATBUFFERS_ASSERT(IsInteger(type.base_type)); + return Error( + "the default 'null' is reserved for declaring optional scalar " + "fields, it conflicts with declaration of enum '" + + type.enum_def->name + "'."); + } + if (field->attributes.Lookup("key")) { + return Error("only a non-optional scalar field can be used as a 'key' field"); + } + if (!SupportsOptionalScalars()) { + return Error( + "Optional scalars are not yet supported in at least one the of " + "the specified programming languages."); + } + } + } else { + // For nonscalars, only required fields are non-optional. + // At least until https://github.com/google/flatbuffers/issues/6053 + field->optional = !field->required; + } + // Append .0 if the value has not it (skip hex and scientific floats). // This suffix needed for generated C++ code. if (IsFloat(type.base_type)) { @@ -772,6 +800,7 @@ CheckedError Parser::ParseField(StructDef &struct_def) { } else { // All unions should have the NONE ("0") enum value. auto in_enum = type.enum_def->attributes.Lookup("bit_flags") || + field->IsScalarOptional() || type.enum_def->FindByValue(field->value.constant); if (false == in_enum) return Error("default value of " + field->value.constant + @@ -833,17 +862,7 @@ CheckedError Parser::ParseField(StructDef &struct_def) { if (field->required && (struct_def.fixed || IsScalar(type.base_type))) return Error("only non-scalar fields in tables may be 'required'"); - // Mark the optional scalars. Note that a side effect of ParseSingleValue is - // fixing field->value.constant to null. - if (IsScalar(type.base_type)) { - field->optional = (field->value.constant == "null"); - if (field->optional && !SupportsOptionalScalars()) { - return Error( - "Optional scalars are not yet supported in at least one the of " - "the specified programming languages." - ); - } - } else { + if(!IsScalar(type.base_type)) { // For nonscalars, only required fields are non-optional. // At least until https://github.com/google/flatbuffers/issues/6053 field->optional = !field->required; @@ -2260,11 +2279,17 @@ CheckedError Parser::CheckClash(std::vector<FieldDef *> &fields, return NoError(); } +bool Parser::SupportsOptionalScalars(const flatbuffers::IDLOptions &opts){ + static FLATBUFFERS_CONSTEXPR unsigned long supported_langs = + IDLOptions::kRust | IDLOptions::kSwift | IDLOptions::kLobster | + IDLOptions::kKotlin | IDLOptions::kCpp; + unsigned long langs = opts.lang_to_generate; + return (langs > 0 && langs < IDLOptions::kMAX) && !(langs & ~supported_langs); +} bool Parser::SupportsOptionalScalars() const { - return !(opts.lang_to_generate & - ~(IDLOptions::kRust | IDLOptions::kSwift | IDLOptions::kLobster | - IDLOptions::kKotlin)); + // Check in general if a language isn't specified. + return opts.lang_to_generate == 0 || SupportsOptionalScalars(opts); } bool Parser::SupportsAdvancedUnionFeatures() const { |