@@ -948,11 +948,13 @@ CheckedError Parser::ParseField(StructDef &struct_def) {
948948 // For union fields, add a second auto-generated field to hold the type,
949949 // with a special suffix.
950950
951- // To ensure compatibility with many codes that rely on the BASE_TYPE_UTYPE value to identify union type fields.
951+ // To ensure compatibility with many codes that rely on the BASE_TYPE_UTYPE
952+ // value to identify union type fields.
952953 Type union_type (type.enum_def ->underlying_type );
953954 union_type.base_type = BASE_TYPE_UTYPE;
954- ECHECK (AddField (struct_def, name + UnionTypeFieldSuffix (),union_type, &typefield));
955-
955+ ECHECK (AddField (struct_def, name + UnionTypeFieldSuffix (), union_type,
956+ &typefield));
957+
956958 } else if (IsVector (type) && type.element == BASE_TYPE_UNION) {
957959 advanced_features_ |= reflection::AdvancedUnionFeatures;
958960 // Only cpp, js and ts supports the union vector feature so far.
@@ -1590,7 +1592,7 @@ CheckedError Parser::ParseTable(const StructDef &struct_def, std::string *value,
15901592 if (!struct_def.sortbysize ||
15911593 size == SizeOf (field_value.type .base_type )) {
15921594 switch (field_value.type .base_type ) {
1593- // clang-format off
1595+ // clang-format off
15941596 #define FLATBUFFERS_TD (ENUM, IDLTYPE, CTYPE, ...) \
15951597 case BASE_TYPE_ ## ENUM: \
15961598 builder_.Pad (field->padding ); \
@@ -1733,7 +1735,7 @@ CheckedError Parser::ParseVector(const Type &vector_type, uoffset_t *ovalue,
17331735 // start at the back, since we're building the data backwards.
17341736 auto &val = field_stack_.back ().first ;
17351737 switch (val.type .base_type ) {
1736- // clang-format off
1738+ // clang-format off
17371739 #define FLATBUFFERS_TD (ENUM, IDLTYPE, CTYPE,...) \
17381740 case BASE_TYPE_ ## ENUM: \
17391741 if (IsStruct (val.type )) SerializeStruct (*val.type .struct_def , val); \
@@ -2189,6 +2191,21 @@ CheckedError Parser::ParseSingleValue(const std::string *name, Value &e,
21892191 } else {
21902192 // Try a float number.
21912193 TRY_ECHECK (kTokenFloatConstant , IsFloat (in_type), BASE_TYPE_FLOAT);
2194+
2195+ // Special handling for integer types that might come as floats from JSON
2196+ // This happens when large integers are parsed as doubles by JSON parsers
2197+ // Set the value to 0 to avoid precision issues
2198+ if (!match && token_ == kTokenFloatConstant && IsInteger (in_type) &&
2199+ opts.zero_on_float_to_int ) {
2200+ double float_val = std::stod (attribute_);
2201+ // For integers fields that receive float values, set to 0
2202+ Warning (" Float value " + std::to_string (float_val) + " received for <" +
2203+ std::string (TypeName (in_type)) +
2204+ " > field, setting to 0." );
2205+ attribute_ = " 0" ;
2206+ TRY_ECHECK (kTokenFloatConstant , IsInteger (in_type), BASE_TYPE_INT);
2207+ }
2208+
21922209 // Integer token can init any scalar (integer of float).
21932210 FORCE_ECHECK (kTokenIntegerConstant , IsScalar (in_type), BASE_TYPE_INT);
21942211 }
@@ -2372,12 +2389,8 @@ template<typename T> void EnumDef::ChangeEnumValue(EnumVal *ev, T new_value) {
23722389}
23732390
23742391namespace EnumHelper {
2375- template <BaseType E> struct EnumValType {
2376- typedef int64_t type;
2377- };
2378- template <> struct EnumValType <BASE_TYPE_ULONG> {
2379- typedef uint64_t type;
2380- };
2392+ template <BaseType E> struct EnumValType { typedef int64_t type; };
2393+ template <> struct EnumValType <BASE_TYPE_ULONG> { typedef uint64_t type; };
23812394} // namespace EnumHelper
23822395
23832396struct EnumValBuilder {
@@ -2482,8 +2495,8 @@ CheckedError Parser::ParseEnum(const bool is_union, EnumDef **dest,
24822495 EnumDef *enum_def;
24832496 ECHECK (StartEnum (enum_name, is_union, &enum_def));
24842497 if (filename != nullptr && !opts.project_root .empty ()) {
2485- enum_def->declaration_file =
2486- & GetPooledString ( FilePath ( opts.project_root , filename, opts.binary_schema_absolute_paths ));
2498+ enum_def->declaration_file = & GetPooledString ( FilePath (
2499+ opts.project_root , filename, opts.binary_schema_absolute_paths ));
24872500 }
24882501 enum_def->doc_comment = enum_comment;
24892502 if (!opts.proto_mode ) {
@@ -2511,14 +2524,15 @@ CheckedError Parser::ParseEnum(const bool is_union, EnumDef **dest,
25112524 if (explicit_underlying_type) {
25122525 // Specify the integer type underlying this enum.
25132526 ECHECK (ParseType (enum_def->underlying_type ));
2514- if (!IsInteger (enum_def->underlying_type .base_type ) || IsBool (enum_def->underlying_type .base_type )) {
2515- return Error (" underlying " + std::string (is_union ? " union" : " enum" ) + " type must be integral" );
2527+ if (!IsInteger (enum_def->underlying_type .base_type ) ||
2528+ IsBool (enum_def->underlying_type .base_type )) {
2529+ return Error (" underlying " + std::string (is_union ? " union" : " enum" ) +
2530+ " type must be integral" );
25162531 }
2517-
2532+
25182533 // Make this type refer back to the enum it was derived from.
25192534 enum_def->underlying_type .enum_def = enum_def;
25202535 }
2521-
25222536 }
25232537 ECHECK (ParseMetaData (&enum_def->attributes ));
25242538 const auto underlying_type = enum_def->underlying_type .base_type ;
@@ -2682,8 +2696,7 @@ bool Parser::SupportsOptionalScalars(const flatbuffers::IDLOptions &opts) {
26822696 IDLOptions::kKotlin | IDLOptions::kKotlinKmp | IDLOptions::kCpp |
26832697 IDLOptions::kJava | IDLOptions::kCSharp | IDLOptions::kTs |
26842698 IDLOptions::kBinary | IDLOptions::kGo | IDLOptions::kPython |
2685- IDLOptions::kJson |
2686- IDLOptions::kNim ;
2699+ IDLOptions::kJson | IDLOptions::kNim ;
26872700 unsigned long langs = opts.lang_to_generate ;
26882701 return (langs > 0 && langs < IDLOptions::kMAX ) && !(langs & ~supported_langs);
26892702}
@@ -2719,8 +2732,8 @@ bool Parser::Supports64BitOffsets() const {
27192732}
27202733
27212734bool Parser::SupportsUnionUnderlyingType () const {
2722- return (opts.lang_to_generate & ~(IDLOptions:: kCpp | IDLOptions:: kTs |
2723- IDLOptions::kBinary )) == 0 ;
2735+ return (opts.lang_to_generate &
2736+ ~(IDLOptions:: kCpp | IDLOptions:: kTs | IDLOptions::kBinary )) == 0 ;
27242737}
27252738
27262739Namespace *Parser::UniqueNamespace (Namespace *ns) {
@@ -2761,8 +2774,8 @@ CheckedError Parser::ParseDecl(const char *filename) {
27612774 struct_def->doc_comment = dc;
27622775 struct_def->fixed = fixed;
27632776 if (filename && !opts.project_root .empty ()) {
2764- struct_def->declaration_file =
2765- & GetPooledString ( FilePath ( opts.project_root , filename, opts.binary_schema_absolute_paths ));
2777+ struct_def->declaration_file = & GetPooledString ( FilePath (
2778+ opts.project_root , filename, opts.binary_schema_absolute_paths ));
27662779 }
27672780 ECHECK (ParseMetaData (&struct_def->attributes ));
27682781 struct_def->sortbysize =
@@ -2855,8 +2868,8 @@ CheckedError Parser::ParseService(const char *filename) {
28552868 service_def.doc_comment = service_comment;
28562869 service_def.defined_namespace = current_namespace_;
28572870 if (filename != nullptr && !opts.project_root .empty ()) {
2858- service_def.declaration_file =
2859- & GetPooledString ( FilePath ( opts.project_root , filename, opts.binary_schema_absolute_paths ));
2871+ service_def.declaration_file = & GetPooledString ( FilePath (
2872+ opts.project_root , filename, opts.binary_schema_absolute_paths ));
28602873 }
28612874 if (services_.Add (current_namespace_->GetFullyQualifiedName (service_name),
28622875 &service_def))
@@ -3937,12 +3950,12 @@ void Parser::Serialize() {
39373950 std::vector<Offset<flatbuffers::String>> included_files;
39383951 for (auto f = files_included_per_file_.begin ();
39393952 f != files_included_per_file_.end (); f++) {
3940-
39413953 const auto filename__ = builder_.CreateSharedString (FilePath (
39423954 opts.project_root , f->first , opts.binary_schema_absolute_paths ));
39433955 for (auto i = f->second .begin (); i != f->second .end (); i++) {
39443956 included_files.push_back (builder_.CreateSharedString (
3945- FilePath (opts.project_root , i->filename , opts.binary_schema_absolute_paths )));
3957+ FilePath (opts.project_root , i->filename ,
3958+ opts.binary_schema_absolute_paths )));
39463959 }
39473960 const auto included_files__ = builder_.CreateVector (included_files);
39483961 included_files.clear ();
@@ -4456,8 +4469,11 @@ std::string Parser::ConformTo(const Parser &base) {
44564469 }
44574470 }
44584471 // Check underlying type changes
4459- if (enum_def_base->underlying_type .base_type != enum_def.underlying_type .base_type ) {
4460- return " underlying type differ for " + std::string (enum_def.is_union ? " union: " : " enum: " ) + qualified_name;
4472+ if (enum_def_base->underlying_type .base_type !=
4473+ enum_def.underlying_type .base_type ) {
4474+ return " underlying type differ for " +
4475+ std::string (enum_def.is_union ? " union: " : " enum: " ) +
4476+ qualified_name;
44614477 }
44624478 }
44634479 return " " ;
0 commit comments