Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-08-27 09:30:27

0001 /*
0002  * Copyright 2014 Google Inc. All rights reserved.
0003  *
0004  * Licensed under the Apache License, Version 2.0 (the "License");
0005  * you may not use this file except in compliance with the License.
0006  * You may obtain a copy of the License at
0007  *
0008  *     http://www.apache.org/licenses/LICENSE-2.0
0009  *
0010  * Unless required by applicable law or agreed to in writing, software
0011  * distributed under the License is distributed on an "AS IS" BASIS,
0012  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0013  * See the License for the specific language governing permissions and
0014  * limitations under the License.
0015  */
0016 
0017 #ifndef FLATBUFFERS_IDL_H_
0018 #define FLATBUFFERS_IDL_H_
0019 
0020 #include <algorithm>
0021 #include <functional>
0022 #include <map>
0023 #include <memory>
0024 #include <stack>
0025 #include <vector>
0026 
0027 #include "flatbuffers/base.h"
0028 #include "flatbuffers/flatbuffers.h"
0029 #include "flatbuffers/flexbuffers.h"
0030 #include "flatbuffers/hash.h"
0031 #include "flatbuffers/reflection.h"
0032 
0033 // This file defines the data types representing a parsed IDL (Interface
0034 // Definition Language) / schema file.
0035 
0036 // Limits maximum depth of nested objects.
0037 // Prevents stack overflow while parse scheme, or json, or flexbuffer.
0038 #if !defined(FLATBUFFERS_MAX_PARSING_DEPTH)
0039 #  define FLATBUFFERS_MAX_PARSING_DEPTH 64
0040 #endif
0041 
0042 namespace flatbuffers {
0043 
0044 // The order of these matters for Is*() functions below.
0045 // Additionally, Parser::ParseType assumes bool..string is a contiguous range
0046 // of type tokens.
0047 // clang-format off
0048 #define FLATBUFFERS_GEN_TYPES_SCALAR(TD) \
0049   TD(NONE,     "",       uint8_t,  byte,   byte,    byte,   uint8,   u8,   UByte, UInt8, 0) \
0050   TD(UTYPE,    "",       uint8_t,  byte,   byte,    byte,   uint8,   u8,   UByte, UInt8, 1) /* begin scalar/int */ \
0051   TD(BOOL,     "bool",   uint8_t,  boolean,bool,    bool,   bool,    bool, Boolean, Bool, 2) \
0052   TD(CHAR,     "byte",   int8_t,   byte,   int8,    sbyte,  int8,    i8,   Byte, Int8, 3) \
0053   TD(UCHAR,    "ubyte",  uint8_t,  byte,   byte,    byte,   uint8,   u8,   UByte, UInt8, 4) \
0054   TD(SHORT,    "short",  int16_t,  short,  int16,   short,  int16,   i16,  Short, Int16, 5) \
0055   TD(USHORT,   "ushort", uint16_t, short,  uint16,  ushort, uint16,  u16,  UShort, UInt16, 6) \
0056   TD(INT,      "int",    int32_t,  int,    int32,   int,    int32,   i32,  Int, Int32, 7) \
0057   TD(UINT,     "uint",   uint32_t, int,    uint32,  uint,   uint32,  u32,  UInt, UInt32, 8) \
0058   TD(LONG,     "long",   int64_t,  long,   int64,   long,   int64,   i64,  Long, Int64, 9) \
0059   TD(ULONG,    "ulong",  uint64_t, long,   uint64,  ulong,  uint64,  u64,  ULong, UInt64, 10) /* end int */ \
0060   TD(FLOAT,    "float",  float,    float,  float32, float,  float32, f32,  Float, Float32, 11) /* begin float */ \
0061   TD(DOUBLE,   "double", double,   double, float64, double, float64, f64,  Double, Double, 12) /* end float/scalar */
0062 #define FLATBUFFERS_GEN_TYPES_POINTER(TD) \
0063   TD(STRING,   "string", Offset<void>,   int, int, StringOffset, int, unused, Int, Offset<String>, 13) \
0064   TD(VECTOR,   "",       Offset<void>,   int, int, VectorOffset, int, unused, Int, Offset<UOffset>, 14) \
0065   TD(VECTOR64, "",       Offset64<void>, int, int, VectorOffset, int, unused, Int, Offset<UOffset>, 18) \
0066   TD(STRUCT,   "",       Offset<void>,   int, int, int,          int, unused, Int, Offset<UOffset>, 15) \
0067   TD(UNION,    "",       Offset<void>,   int, int, int,          int, unused, Int, Offset<UOffset>, 16)
0068 #define FLATBUFFERS_GEN_TYPE_ARRAY(TD) \
0069   TD(ARRAY,    "",       int,            int, int, int,          int, unused, Int, Offset<UOffset>, 17)
0070 // The fields are:
0071 // - enum
0072 // - FlatBuffers schema type.
0073 // - C++ type.
0074 // - Java type.
0075 // - Go type.
0076 // - C# / .Net type.
0077 // - Python type.
0078 // - Kotlin type.
0079 // - Rust type.
0080 // - Swift type.
0081 // - enum value (matches the reflected values)
0082 
0083 // using these macros, we can now write code dealing with types just once, e.g.
0084 
0085 /*
0086 switch (type) {
0087   #define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE, JTYPE, GTYPE, NTYPE, PTYPE, \
0088                          RTYPE, KTYPE, STYPE, ...) \
0089     case BASE_TYPE_ ## ENUM: \
0090       // do something specific to CTYPE here
0091     FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD)
0092   #undef FLATBUFFERS_TD
0093 }
0094 */
0095 
0096 // If not all FLATBUFFERS_GEN_() arguments are necessary for implementation
0097 // of FLATBUFFERS_TD, you can use a variadic macro (with __VA_ARGS__ if needed).
0098 // In the above example, only CTYPE is used to generate the code, it can be rewritten:
0099 
0100 /*
0101 switch (type) {
0102   #define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE, ...) \
0103     case BASE_TYPE_ ## ENUM: \
0104       // do something specific to CTYPE here
0105     FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD)
0106   #undef FLATBUFFERS_TD
0107 }
0108 */
0109 
0110 #define FLATBUFFERS_GEN_TYPES(TD) \
0111         FLATBUFFERS_GEN_TYPES_SCALAR(TD) \
0112         FLATBUFFERS_GEN_TYPES_POINTER(TD) \
0113         FLATBUFFERS_GEN_TYPE_ARRAY(TD)
0114 
0115 // Create an enum for all the types above.
0116 #ifdef __GNUC__
0117 __extension__  // Stop GCC complaining about trailing comma with -Wpendantic.
0118 #endif
0119 enum BaseType {
0120   #define FLATBUFFERS_TD(ENUM, IDLTYPE, \
0121               CTYPE, JTYPE, GTYPE, NTYPE, PTYPE, RTYPE, KTYPE, STYPE, ENUM_VALUE) \
0122     BASE_TYPE_ ## ENUM = ENUM_VALUE,
0123     FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD)
0124   #undef FLATBUFFERS_TD
0125 };
0126 
0127 #define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE, ...) \
0128   static_assert(sizeof(CTYPE) <= sizeof(largest_scalar_t), \
0129                 "define largest_scalar_t as " #CTYPE);
0130   FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD)
0131 #undef FLATBUFFERS_TD
0132 
0133 inline bool IsScalar (BaseType t) { return t >= BASE_TYPE_UTYPE &&
0134                                            t <= BASE_TYPE_DOUBLE; }
0135 inline bool IsInteger(BaseType t) { return t >= BASE_TYPE_UTYPE &&
0136                                            t <= BASE_TYPE_ULONG; }
0137 inline bool IsFloat  (BaseType t) { return t == BASE_TYPE_FLOAT ||
0138                                            t == BASE_TYPE_DOUBLE; }
0139 inline bool IsLong   (BaseType t) { return t == BASE_TYPE_LONG ||
0140                                            t == BASE_TYPE_ULONG; }
0141 inline bool IsBool   (BaseType t) { return t == BASE_TYPE_BOOL; }
0142 inline bool IsOneByte(BaseType t) { return t >= BASE_TYPE_UTYPE &&
0143                                            t <= BASE_TYPE_UCHAR; }
0144 inline bool IsVector (BaseType t) { return t == BASE_TYPE_VECTOR ||
0145                                            t == BASE_TYPE_VECTOR64; }
0146 
0147 inline bool IsUnsigned(BaseType t) {
0148   return (t == BASE_TYPE_UTYPE)  || (t == BASE_TYPE_UCHAR) ||
0149          (t == BASE_TYPE_USHORT) || (t == BASE_TYPE_UINT)  ||
0150          (t == BASE_TYPE_ULONG);
0151 }
0152 
0153 inline size_t SizeOf(const BaseType t) {
0154   switch (t) {
0155   #define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE, ...) \
0156     case BASE_TYPE_##ENUM: return sizeof(CTYPE);
0157       FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD)
0158   #undef FLATBUFFERS_TD
0159     default: FLATBUFFERS_ASSERT(0);
0160   }
0161   return 0;
0162 }
0163 
0164 inline const char* TypeName(const BaseType t) {
0165   switch (t) {
0166   #define FLATBUFFERS_TD(ENUM, IDLTYPE, ...) \
0167     case BASE_TYPE_##ENUM: return IDLTYPE;
0168       FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD)
0169   #undef FLATBUFFERS_TD
0170     default: FLATBUFFERS_ASSERT(0);
0171   }
0172   return nullptr;
0173 }
0174 
0175 inline const char* StringOf(const BaseType t) {
0176   switch (t) {
0177   #define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE, ...) \
0178     case BASE_TYPE_##ENUM: return #CTYPE;
0179       FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD)
0180   #undef FLATBUFFERS_TD
0181     default: FLATBUFFERS_ASSERT(0);
0182   }
0183   return "";
0184 }
0185 
0186 // clang-format on
0187 
0188 struct StructDef;
0189 struct EnumDef;
0190 class Parser;
0191 
0192 // Represents any type in the IDL, which is a combination of the BaseType
0193 // and additional information for vectors/structs_.
0194 struct Type {
0195   explicit Type(BaseType _base_type = BASE_TYPE_NONE, StructDef *_sd = nullptr,
0196                 EnumDef *_ed = nullptr, uint16_t _fixed_length = 0)
0197       : base_type(_base_type),
0198         element(BASE_TYPE_NONE),
0199         struct_def(_sd),
0200         enum_def(_ed),
0201         fixed_length(_fixed_length) {}
0202 
0203   bool operator==(const Type &o) const {
0204     return base_type == o.base_type && element == o.element &&
0205            struct_def == o.struct_def && enum_def == o.enum_def;
0206   }
0207 
0208   Type VectorType() const {
0209     return Type(element, struct_def, enum_def, fixed_length);
0210   }
0211 
0212   Offset<reflection::Type> Serialize(FlatBufferBuilder *builder) const;
0213 
0214   bool Deserialize(const Parser &parser, const reflection::Type *type);
0215 
0216   BaseType base_type;
0217   BaseType element;       // only set if t == BASE_TYPE_VECTOR or
0218                           // BASE_TYPE_VECTOR64
0219   StructDef *struct_def;  // only set if t or element == BASE_TYPE_STRUCT
0220   EnumDef *enum_def;      // set if t == BASE_TYPE_UNION / BASE_TYPE_UTYPE,
0221                           // or for an integral type derived from an enum.
0222   uint16_t fixed_length;  // only set if t == BASE_TYPE_ARRAY
0223 };
0224 
0225 // Represents a parsed scalar value, it's type, and field offset.
0226 struct Value {
0227   Value()
0228       : constant("0"),
0229         offset(static_cast<voffset_t>(~(static_cast<voffset_t>(0U)))) {}
0230   Type type;
0231   std::string constant;
0232   voffset_t offset;
0233 };
0234 
0235 // Helper class that retains the original order of a set of identifiers and
0236 // also provides quick lookup.
0237 template<typename T> class SymbolTable {
0238  public:
0239   ~SymbolTable() {
0240     for (auto it = vec.begin(); it != vec.end(); ++it) { delete *it; }
0241   }
0242 
0243   bool Add(const std::string &name, T *e) {
0244     vec.emplace_back(e);
0245     auto it = dict.find(name);
0246     if (it != dict.end()) return true;
0247     dict[name] = e;
0248     return false;
0249   }
0250 
0251   void Move(const std::string &oldname, const std::string &newname) {
0252     auto it = dict.find(oldname);
0253     if (it != dict.end()) {
0254       auto obj = it->second;
0255       dict.erase(it);
0256       dict[newname] = obj;
0257     } else {
0258       FLATBUFFERS_ASSERT(false);
0259     }
0260   }
0261 
0262   T *Lookup(const std::string &name) const {
0263     auto it = dict.find(name);
0264     return it == dict.end() ? nullptr : it->second;
0265   }
0266 
0267  public:
0268   std::map<std::string, T *> dict;  // quick lookup
0269   std::vector<T *> vec;             // Used to iterate in order of insertion
0270 };
0271 
0272 // A name space, as set in the schema.
0273 struct Namespace {
0274   Namespace() : from_table(0) {}
0275 
0276   // Given a (potentially unqualified) name, return the "fully qualified" name
0277   // which has a full namespaced descriptor.
0278   // With max_components you can request less than the number of components
0279   // the current namespace has.
0280   std::string GetFullyQualifiedName(const std::string &name,
0281                                     size_t max_components = 1000) const;
0282 
0283   std::vector<std::string> components;
0284   size_t from_table;  // Part of the namespace corresponds to a message/table.
0285 };
0286 
0287 inline bool operator<(const Namespace &a, const Namespace &b) {
0288   size_t min_size = std::min(a.components.size(), b.components.size());
0289   for (size_t i = 0; i < min_size; ++i) {
0290     if (a.components[i] != b.components[i])
0291       return a.components[i] < b.components[i];
0292   }
0293   return a.components.size() < b.components.size();
0294 }
0295 
0296 // Base class for all definition types (fields, structs_, enums_).
0297 struct Definition {
0298   Definition()
0299       : generated(false),
0300         defined_namespace(nullptr),
0301         serialized_location(0),
0302         index(-1),
0303         refcount(1),
0304         declaration_file(nullptr) {}
0305 
0306   flatbuffers::Offset<
0307       flatbuffers::Vector<flatbuffers::Offset<reflection::KeyValue>>>
0308   SerializeAttributes(FlatBufferBuilder *builder, const Parser &parser) const;
0309 
0310   bool DeserializeAttributes(Parser &parser,
0311                              const Vector<Offset<reflection::KeyValue>> *attrs);
0312 
0313   std::string name;
0314   std::string file;
0315   std::vector<std::string> doc_comment;
0316   SymbolTable<Value> attributes;
0317   bool generated;  // did we already output code for this definition?
0318   Namespace *defined_namespace;  // Where it was defined.
0319 
0320   // For use with Serialize()
0321   uoffset_t serialized_location;
0322   int index;  // Inside the vector it is stored.
0323   int refcount;
0324   const std::string *declaration_file;
0325 };
0326 
0327 struct FieldDef : public Definition {
0328   FieldDef()
0329       : deprecated(false),
0330         key(false),
0331         shared(false),
0332         native_inline(false),
0333         flexbuffer(false),
0334         offset64(false),
0335         presence(kDefault),
0336         nested_flatbuffer(nullptr),
0337         padding(0),
0338         sibling_union_field(nullptr) {}
0339 
0340   Offset<reflection::Field> Serialize(FlatBufferBuilder *builder, uint16_t id,
0341                                       const Parser &parser) const;
0342 
0343   bool Deserialize(Parser &parser, const reflection::Field *field);
0344 
0345   bool IsScalarOptional() const {
0346     return IsScalar() && IsOptional();
0347   }
0348   bool IsScalar() const {
0349       return ::flatbuffers::IsScalar(value.type.base_type);
0350   }
0351   bool IsOptional() const { return presence == kOptional; }
0352   bool IsRequired() const { return presence == kRequired; }
0353   bool IsDefault() const { return presence == kDefault; }
0354 
0355   Value value;
0356   bool deprecated;  // Field is allowed to be present in old data, but can't be.
0357                     // written in new data nor accessed in new code.
0358   bool key;         // Field functions as a key for creating sorted vectors.
0359   bool shared;  // Field will be using string pooling (i.e. CreateSharedString)
0360                 // as default serialization behavior if field is a string.
0361   bool native_inline;  // Field will be defined inline (instead of as a pointer)
0362                        // for native tables if field is a struct.
0363   bool flexbuffer;     // This field contains FlexBuffer data.
0364   bool offset64;       // If the field uses 64-bit offsets.
0365 
0366   enum Presence {
0367     // Field must always be present.
0368     kRequired,
0369     // Non-presence should be signalled to and controlled by users.
0370     kOptional,
0371     // Non-presence is hidden from users.
0372     // Implementations may omit writing default values.
0373     kDefault,
0374   };
0375   Presence static MakeFieldPresence(bool optional, bool required) {
0376     FLATBUFFERS_ASSERT(!(required && optional));
0377     // clang-format off
0378     return required ? FieldDef::kRequired
0379          : optional ? FieldDef::kOptional
0380                     : FieldDef::kDefault;
0381     // clang-format on
0382   }
0383   Presence presence;
0384 
0385   StructDef *nested_flatbuffer;  // This field contains nested FlatBuffer data.
0386   size_t padding;                // Bytes to always pad after this field.
0387 
0388   // sibling_union_field is always set to nullptr. The only exception is
0389   // when FieldDef is a union field or an union type field. Therefore,
0390   // sibling_union_field on a union field points to the union type field
0391   // and vice-versa.
0392   FieldDef *sibling_union_field;
0393 };
0394 
0395 struct StructDef : public Definition {
0396   StructDef()
0397       : fixed(false),
0398         predecl(true),
0399         sortbysize(true),
0400         has_key(false),
0401         minalign(1),
0402         bytesize(0) {}
0403 
0404   void PadLastField(size_t min_align) {
0405     auto padding = PaddingBytes(bytesize, min_align);
0406     bytesize += padding;
0407     if (fields.vec.size()) fields.vec.back()->padding = padding;
0408   }
0409 
0410   Offset<reflection::Object> Serialize(FlatBufferBuilder *builder,
0411                                        const Parser &parser) const;
0412 
0413   bool Deserialize(Parser &parser, const reflection::Object *object);
0414 
0415   SymbolTable<FieldDef> fields;
0416 
0417   bool fixed;       // If it's struct, not a table.
0418   bool predecl;     // If it's used before it was defined.
0419   bool sortbysize;  // Whether fields come in the declaration or size order.
0420   bool has_key;     // It has a key field.
0421   size_t minalign;  // What the whole object needs to be aligned to.
0422   size_t bytesize;  // Size if fixed.
0423 
0424   flatbuffers::unique_ptr<std::string> original_location;
0425   std::vector<voffset_t> reserved_ids;
0426 };
0427 
0428 struct EnumDef;
0429 struct EnumValBuilder;
0430 
0431 struct EnumVal {
0432   Offset<reflection::EnumVal> Serialize(FlatBufferBuilder *builder,
0433                                         const Parser &parser) const;
0434 
0435   bool Deserialize(Parser &parser, const reflection::EnumVal *val);
0436 
0437   flatbuffers::Offset<
0438       flatbuffers::Vector<flatbuffers::Offset<reflection::KeyValue>>>
0439   SerializeAttributes(FlatBufferBuilder *builder, const Parser &parser) const;
0440 
0441   bool DeserializeAttributes(Parser &parser,
0442                              const Vector<Offset<reflection::KeyValue>> *attrs);
0443 
0444   uint64_t GetAsUInt64() const { return static_cast<uint64_t>(value); }
0445   int64_t GetAsInt64() const { return value; }
0446   bool IsZero() const { return 0 == value; }
0447   bool IsNonZero() const { return !IsZero(); }
0448 
0449   std::string name;
0450   std::vector<std::string> doc_comment;
0451   Type union_type;
0452   SymbolTable<Value> attributes;
0453 
0454  private:
0455   friend EnumDef;
0456   friend EnumValBuilder;
0457   friend bool operator==(const EnumVal &lhs, const EnumVal &rhs);
0458 
0459   EnumVal(const std::string &_name, int64_t _val) : name(_name), value(_val) {}
0460   EnumVal() : value(0) {}
0461 
0462   int64_t value;
0463 };
0464 
0465 struct EnumDef : public Definition {
0466   EnumDef() : is_union(false), uses_multiple_type_instances(false) {}
0467 
0468   Offset<reflection::Enum> Serialize(FlatBufferBuilder *builder,
0469                                      const Parser &parser) const;
0470 
0471   bool Deserialize(Parser &parser, const reflection::Enum *values);
0472 
0473   template<typename T> void ChangeEnumValue(EnumVal *ev, T new_val);
0474   void SortByValue();
0475   void RemoveDuplicates();
0476 
0477   std::string AllFlags() const;
0478   const EnumVal *MinValue() const;
0479   const EnumVal *MaxValue() const;
0480   // Returns the number of integer steps from v1 to v2.
0481   uint64_t Distance(const EnumVal *v1, const EnumVal *v2) const;
0482   // Returns the number of integer steps from Min to Max.
0483   uint64_t Distance() const { return Distance(MinValue(), MaxValue()); }
0484 
0485   EnumVal *ReverseLookup(int64_t enum_idx,
0486                          bool skip_union_default = false) const;
0487   EnumVal *FindByValue(const std::string &constant) const;
0488 
0489   std::string ToString(const EnumVal &ev) const {
0490     return IsUInt64() ? NumToString(ev.GetAsUInt64())
0491                       : NumToString(ev.GetAsInt64());
0492   }
0493 
0494   size_t size() const { return vals.vec.size(); }
0495 
0496   const std::vector<EnumVal *> &Vals() const { return vals.vec; }
0497 
0498   const EnumVal *Lookup(const std::string &enum_name) const {
0499     return vals.Lookup(enum_name);
0500   }
0501 
0502   bool is_union;
0503   // Type is a union which uses type aliases where at least one type is
0504   // available under two different names.
0505   bool uses_multiple_type_instances;
0506   Type underlying_type;
0507 
0508  private:
0509   bool IsUInt64() const {
0510     return (BASE_TYPE_ULONG == underlying_type.base_type);
0511   }
0512 
0513   friend EnumValBuilder;
0514   SymbolTable<EnumVal> vals;
0515 };
0516 
0517 inline bool IsString(const Type &type) {
0518   return type.base_type == BASE_TYPE_STRING;
0519 }
0520 
0521 inline bool IsStruct(const Type &type) {
0522   return type.base_type == BASE_TYPE_STRUCT && type.struct_def->fixed;
0523 }
0524 
0525 inline bool IsIncompleteStruct(const Type &type) {
0526   return type.base_type == BASE_TYPE_STRUCT && type.struct_def->predecl;
0527 }
0528 
0529 inline bool IsTable(const Type &type) {
0530   return type.base_type == BASE_TYPE_STRUCT && !type.struct_def->fixed;
0531 }
0532 
0533 inline bool IsUnion(const Type &type) {
0534   return type.enum_def != nullptr && type.enum_def->is_union;
0535 }
0536 
0537 inline bool IsUnionType(const Type &type) {
0538   return IsUnion(type) && IsInteger(type.base_type);
0539 }
0540 
0541 inline bool IsVector(const Type &type) { return IsVector(type.base_type); }
0542 
0543 inline bool IsVectorOfStruct(const Type &type) {
0544   return IsVector(type) && IsStruct(type.VectorType());
0545 }
0546 
0547 inline bool IsVectorOfTable(const Type &type) {
0548   return IsVector(type) && IsTable(type.VectorType());
0549 }
0550 
0551 inline bool IsArray(const Type &type) {
0552   return type.base_type == BASE_TYPE_ARRAY;
0553 }
0554 
0555 inline bool IsSeries(const Type &type) {
0556   return IsVector(type) || IsArray(type);
0557 }
0558 
0559 inline bool IsEnum(const Type &type) {
0560   return type.enum_def != nullptr && IsInteger(type.base_type);
0561 }
0562 
0563 inline size_t InlineSize(const Type &type) {
0564   return IsStruct(type)
0565              ? type.struct_def->bytesize
0566              : (IsArray(type)
0567                     ? InlineSize(type.VectorType()) * type.fixed_length
0568                     : SizeOf(type.base_type));
0569 }
0570 
0571 inline size_t InlineAlignment(const Type &type) {
0572   if (IsStruct(type)) {
0573     return type.struct_def->minalign;
0574   } else if (IsArray(type)) {
0575     return IsStruct(type.VectorType()) ? type.struct_def->minalign
0576                                        : SizeOf(type.element);
0577   } else {
0578     return SizeOf(type.base_type);
0579   }
0580 }
0581 inline bool operator==(const EnumVal &lhs, const EnumVal &rhs) {
0582   return lhs.value == rhs.value;
0583 }
0584 inline bool operator!=(const EnumVal &lhs, const EnumVal &rhs) {
0585   return !(lhs == rhs);
0586 }
0587 
0588 inline bool EqualByName(const Type &a, const Type &b) {
0589   return a.base_type == b.base_type && a.element == b.element &&
0590          (a.struct_def == b.struct_def ||
0591           (a.struct_def != nullptr && b.struct_def != nullptr &&
0592            a.struct_def->name == b.struct_def->name)) &&
0593          (a.enum_def == b.enum_def ||
0594           (a.enum_def != nullptr && b.enum_def != nullptr &&
0595            a.enum_def->name == b.enum_def->name));
0596 }
0597 
0598 struct RPCCall : public Definition {
0599   Offset<reflection::RPCCall> Serialize(FlatBufferBuilder *builder,
0600                                         const Parser &parser) const;
0601 
0602   bool Deserialize(Parser &parser, const reflection::RPCCall *call);
0603 
0604   StructDef *request, *response;
0605 };
0606 
0607 struct ServiceDef : public Definition {
0608   Offset<reflection::Service> Serialize(FlatBufferBuilder *builder,
0609                                         const Parser &parser) const;
0610   bool Deserialize(Parser &parser, const reflection::Service *service);
0611 
0612   SymbolTable<RPCCall> calls;
0613 };
0614 
0615 struct IncludedFile {
0616   // The name of the schema file being included, as defined in the .fbs file.
0617   // This includes the prefix (e.g., include "foo/bar/baz.fbs" would mean this
0618   // value is "foo/bar/baz.fbs").
0619   std::string schema_name;
0620 
0621   // The filename of where the included file was found, after searching the
0622   // relative paths plus any other paths included with `flatc -I ...`. Note,
0623   // while this is sometimes the same as schema_name, it is not always, since it
0624   // can be defined relative to where flatc was invoked.
0625   std::string filename;
0626 };
0627 
0628 // Since IncludedFile is contained within a std::set, need to provide ordering.
0629 inline bool operator<(const IncludedFile &a, const IncludedFile &b) {
0630   return a.filename < b.filename;
0631 }
0632 
0633 // Container of options that may apply to any of the source/text generators.
0634 struct IDLOptions {
0635   // field case style options for C++
0636   enum CaseStyle { CaseStyle_Unchanged = 0, CaseStyle_Upper, CaseStyle_Lower };
0637   enum class ProtoIdGapAction { NO_OP, WARNING, ERROR };
0638   bool gen_jvmstatic;
0639   // Use flexbuffers instead for binary and text generation
0640   bool use_flexbuffers;
0641   bool strict_json;
0642   bool output_default_scalars_in_json;
0643   int indent_step;
0644   bool cpp_minify_enums;
0645   bool output_enum_identifiers;
0646   bool prefixed_enums;
0647   bool scoped_enums;
0648   bool emit_min_max_enum_values;
0649   bool swift_implementation_only;
0650   bool include_dependence_headers;
0651   bool mutable_buffer;
0652   bool one_file;
0653   bool proto_mode;
0654   bool proto_oneof_union;
0655   bool generate_all;
0656   bool skip_unexpected_fields_in_json;
0657   bool generate_name_strings;
0658   bool generate_object_based_api;
0659   bool gen_compare;
0660   std::string cpp_object_api_pointer_type;
0661   std::string cpp_object_api_string_type;
0662   bool cpp_object_api_string_flexible_constructor;
0663   CaseStyle cpp_object_api_field_case_style;
0664   bool cpp_direct_copy;
0665   bool gen_nullable;
0666   std::string java_package_prefix;
0667   bool java_checkerframework;
0668   bool gen_generated;
0669   bool gen_json_coders;
0670   std::string object_prefix;
0671   std::string object_suffix;
0672   bool union_value_namespacing;
0673   bool allow_non_utf8;
0674   bool natural_utf8;
0675   std::string include_prefix;
0676   bool keep_prefix;
0677   bool binary_schema_comments;
0678   bool binary_schema_builtins;
0679   bool binary_schema_gen_embed;
0680   bool binary_schema_absolute_paths;
0681   std::string go_import;
0682   std::string go_namespace;
0683   std::string go_module_name;
0684   bool protobuf_ascii_alike;
0685   bool size_prefixed;
0686   std::string root_type;
0687   bool force_defaults;
0688   bool java_primitive_has_method;
0689   bool cs_gen_json_serializer;
0690   std::vector<std::string> cpp_includes;
0691   std::string cpp_std;
0692   bool cpp_static_reflection;
0693   std::string proto_namespace_suffix;
0694   std::string filename_suffix;
0695   std::string filename_extension;
0696   bool no_warnings;
0697   bool warnings_as_errors;
0698   std::string project_root;
0699   bool cs_global_alias;
0700   bool json_nested_flatbuffers;
0701   bool json_nested_flexbuffers;
0702   bool json_nested_legacy_flatbuffers;
0703   bool ts_flat_files;
0704   bool ts_entry_points;
0705   bool ts_no_import_ext;
0706   bool no_leak_private_annotations;
0707   bool require_json_eof;
0708   bool keep_proto_id;
0709 
0710   /********************************** Python **********************************/
0711   bool python_no_type_prefix_suffix;
0712   bool python_typing;
0713 
0714   // The target Python version. Can be one of the following:
0715   // -  "0"
0716   // -  "2"
0717   // -  "3"
0718   // -  "2.<minor>"
0719   // -  "3.<minor>"
0720   // -  "2.<minor>.<micro>"
0721   // -  "3.<minor>.<micro>"
0722   //
0723   // https://docs.python.org/3/faq/general.html#how-does-the-python-version-numbering-scheme-work
0724   std::string python_version;
0725 
0726   // Whether to generate numpy helpers.
0727   bool python_gen_numpy;
0728 
0729   bool ts_omit_entrypoint;
0730   ProtoIdGapAction proto_id_gap_action;
0731 
0732   // Possible options for the more general generator below.
0733   enum Language {
0734     kJava = 1 << 0,
0735     kCSharp = 1 << 1,
0736     kGo = 1 << 2,
0737     kCpp = 1 << 3,
0738     kPython = 1 << 5,
0739     kPhp = 1 << 6,
0740     kJson = 1 << 7,
0741     kBinary = 1 << 8,
0742     kTs = 1 << 9,
0743     kJsonSchema = 1 << 10,
0744     kDart = 1 << 11,
0745     kLua = 1 << 12,
0746     kLobster = 1 << 13,
0747     kRust = 1 << 14,
0748     kKotlin = 1 << 15,
0749     kSwift = 1 << 16,
0750     kNim = 1 << 17,
0751     kProto = 1 << 18,
0752     kKotlinKmp = 1 << 19,
0753     kMAX
0754   };
0755 
0756   enum MiniReflect { kNone, kTypes, kTypesAndNames };
0757 
0758   MiniReflect mini_reflect;
0759 
0760   // If set, require all fields in a table to be explicitly numbered.
0761   bool require_explicit_ids;
0762 
0763   // If set, implement serde::Serialize for generated Rust types
0764   bool rust_serialize;
0765 
0766   // If set, generate rust types in individual files with a root module file.
0767   bool rust_module_root_file;
0768 
0769   // The corresponding language bit will be set if a language is included
0770   // for code generation.
0771   unsigned long lang_to_generate;
0772 
0773   // If set (default behavior), empty string fields will be set to nullptr to
0774   // make the flatbuffer more compact.
0775   bool set_empty_strings_to_null;
0776 
0777   // If set (default behavior), empty vector fields will be set to nullptr to
0778   // make the flatbuffer more compact.
0779   bool set_empty_vectors_to_null;
0780 
0781   /*********************************** gRPC ***********************************/
0782   std::string grpc_filename_suffix;
0783   bool grpc_use_system_headers;
0784   std::string grpc_search_path;
0785   std::vector<std::string> grpc_additional_headers;
0786 
0787   /******************************* Python gRPC ********************************/
0788   bool grpc_python_typed_handlers;
0789 
0790   IDLOptions()
0791       : gen_jvmstatic(false),
0792         use_flexbuffers(false),
0793         strict_json(false),
0794         output_default_scalars_in_json(false),
0795         indent_step(2),
0796         cpp_minify_enums(false),
0797         output_enum_identifiers(true),
0798         prefixed_enums(true),
0799         scoped_enums(false),
0800         emit_min_max_enum_values(true),
0801         swift_implementation_only(false),
0802         include_dependence_headers(true),
0803         mutable_buffer(false),
0804         one_file(false),
0805         proto_mode(false),
0806         proto_oneof_union(false),
0807         generate_all(false),
0808         skip_unexpected_fields_in_json(false),
0809         generate_name_strings(false),
0810         generate_object_based_api(false),
0811         gen_compare(false),
0812         cpp_object_api_pointer_type("std::unique_ptr"),
0813         cpp_object_api_string_flexible_constructor(false),
0814         cpp_object_api_field_case_style(CaseStyle_Unchanged),
0815         cpp_direct_copy(true),
0816         gen_nullable(false),
0817         java_checkerframework(false),
0818         gen_generated(false),
0819         gen_json_coders(false),
0820         object_suffix("T"),
0821         union_value_namespacing(true),
0822         allow_non_utf8(false),
0823         natural_utf8(false),
0824         keep_prefix(false),
0825         binary_schema_comments(false),
0826         binary_schema_builtins(false),
0827         binary_schema_gen_embed(false),
0828         binary_schema_absolute_paths(false),
0829         protobuf_ascii_alike(false),
0830         size_prefixed(false),
0831         force_defaults(false),
0832         java_primitive_has_method(false),
0833         cs_gen_json_serializer(false),
0834         cpp_static_reflection(false),
0835         filename_suffix("_generated"),
0836         filename_extension(),
0837         no_warnings(false),
0838         warnings_as_errors(false),
0839         project_root(""),
0840         cs_global_alias(false),
0841         json_nested_flatbuffers(true),
0842         json_nested_flexbuffers(true),
0843         json_nested_legacy_flatbuffers(false),
0844         ts_flat_files(false),
0845         ts_entry_points(false),
0846         ts_no_import_ext(false),
0847         no_leak_private_annotations(false),
0848         require_json_eof(true),
0849         keep_proto_id(false),
0850         python_no_type_prefix_suffix(false),
0851         python_typing(false),
0852         python_gen_numpy(true),
0853         ts_omit_entrypoint(false),
0854         proto_id_gap_action(ProtoIdGapAction::WARNING),
0855         mini_reflect(IDLOptions::kNone),
0856         require_explicit_ids(false),
0857         rust_serialize(false),
0858         rust_module_root_file(false),
0859         lang_to_generate(0),
0860         set_empty_strings_to_null(true),
0861         set_empty_vectors_to_null(true),
0862         grpc_filename_suffix(".fb"),
0863         grpc_use_system_headers(true),
0864         grpc_python_typed_handlers(false) {}
0865 };
0866 
0867 // This encapsulates where the parser is in the current source file.
0868 struct ParserState {
0869   ParserState()
0870       : prev_cursor_(nullptr),
0871         cursor_(nullptr),
0872         line_start_(nullptr),
0873         line_(0),
0874         token_(-1),
0875         attr_is_trivial_ascii_string_(true) {}
0876 
0877  protected:
0878   void ResetState(const char *source) {
0879     prev_cursor_ = source;
0880     cursor_ = source;
0881     line_ = 0;
0882     MarkNewLine();
0883   }
0884 
0885   void MarkNewLine() {
0886     line_start_ = cursor_;
0887     line_ += 1;
0888   }
0889 
0890   int64_t CursorPosition() const {
0891     FLATBUFFERS_ASSERT(cursor_ && line_start_ && cursor_ >= line_start_);
0892     return static_cast<int64_t>(cursor_ - line_start_);
0893   }
0894 
0895   const char *prev_cursor_;
0896   const char *cursor_;
0897   const char *line_start_;
0898   int line_;  // the current line being parsed
0899   int token_;
0900 
0901   // Flag: text in attribute_ is true ASCII string without escape
0902   // sequences. Only printable ASCII (without [\t\r\n]).
0903   // Used for number-in-string (and base64 string in future).
0904   bool attr_is_trivial_ascii_string_;
0905   std::string attribute_;
0906   std::vector<std::string> doc_comment_;
0907 };
0908 
0909 // A way to make error propagation less error prone by requiring values to be
0910 // checked.
0911 // Once you create a value of this type you must either:
0912 // - Call Check() on it.
0913 // - Copy or assign it to another value.
0914 // Failure to do so leads to an assert.
0915 // This guarantees that this as return value cannot be ignored.
0916 class CheckedError {
0917  public:
0918   explicit CheckedError(bool error)
0919       : is_error_(error), has_been_checked_(false) {}
0920 
0921   CheckedError &operator=(const CheckedError &other) {
0922     is_error_ = other.is_error_;
0923     has_been_checked_ = false;
0924     other.has_been_checked_ = true;
0925     return *this;
0926   }
0927 
0928   CheckedError(const CheckedError &other) {
0929     *this = other;  // Use assignment operator.
0930   }
0931 
0932   ~CheckedError() { FLATBUFFERS_ASSERT(has_been_checked_); }
0933 
0934   bool Check() {
0935     has_been_checked_ = true;
0936     return is_error_;
0937   }
0938 
0939  private:
0940   bool is_error_;
0941   mutable bool has_been_checked_;
0942 };
0943 
0944 // Additionally, in GCC we can get these errors statically, for additional
0945 // assurance:
0946 // clang-format off
0947 #ifdef __GNUC__
0948 #define FLATBUFFERS_CHECKED_ERROR CheckedError \
0949           __attribute__((warn_unused_result))
0950 #else
0951 #define FLATBUFFERS_CHECKED_ERROR CheckedError
0952 #endif
0953 // clang-format on
0954 
0955 class Parser : public ParserState {
0956  public:
0957   explicit Parser(const IDLOptions &options = IDLOptions())
0958       : current_namespace_(nullptr),
0959         empty_namespace_(nullptr),
0960         flex_builder_(256, flexbuffers::BUILDER_FLAG_SHARE_ALL),
0961         root_struct_def_(nullptr),
0962         opts(options),
0963         uses_flexbuffers_(false),
0964         has_warning_(false),
0965         advanced_features_(0),
0966         source_(nullptr),
0967         anonymous_counter_(0),
0968         parse_depth_counter_(0) {
0969     if (opts.force_defaults) { builder_.ForceDefaults(true); }
0970     // Start out with the empty namespace being current.
0971     empty_namespace_ = new Namespace();
0972     namespaces_.push_back(empty_namespace_);
0973     current_namespace_ = empty_namespace_;
0974     known_attributes_["deprecated"] = true;
0975     known_attributes_["required"] = true;
0976     known_attributes_["key"] = true;
0977     known_attributes_["shared"] = true;
0978     known_attributes_["hash"] = true;
0979     known_attributes_["id"] = true;
0980     known_attributes_["force_align"] = true;
0981     known_attributes_["bit_flags"] = true;
0982     known_attributes_["original_order"] = true;
0983     known_attributes_["nested_flatbuffer"] = true;
0984     known_attributes_["csharp_partial"] = true;
0985     known_attributes_["streaming"] = true;
0986     known_attributes_["idempotent"] = true;
0987     known_attributes_["cpp_type"] = true;
0988     known_attributes_["cpp_ptr_type"] = true;
0989     known_attributes_["cpp_ptr_type_get"] = true;
0990     known_attributes_["cpp_str_type"] = true;
0991     known_attributes_["cpp_str_flex_ctor"] = true;
0992     known_attributes_["native_inline"] = true;
0993     known_attributes_["native_custom_alloc"] = true;
0994     known_attributes_["native_type"] = true;
0995     known_attributes_["native_type_pack_name"] = true;
0996     known_attributes_["native_default"] = true;
0997     known_attributes_["flexbuffer"] = true;
0998     known_attributes_["private"] = true;
0999 
1000     // An attribute added to a field to indicate that is uses 64-bit addressing.
1001     known_attributes_["offset64"] = true;
1002 
1003     // An attribute added to a vector field to indicate that it uses 64-bit
1004     // addressing and it has a 64-bit length.
1005     known_attributes_["vector64"] = true;
1006   }
1007 
1008   // Copying is not allowed
1009   Parser(const Parser &) = delete;
1010   Parser &operator=(const Parser &) = delete;
1011 
1012   Parser(Parser &&) = default;
1013   Parser &operator=(Parser &&) = default;
1014 
1015   ~Parser() {
1016     for (auto it = namespaces_.begin(); it != namespaces_.end(); ++it) {
1017       delete *it;
1018     }
1019   }
1020 
1021   // Parse the string containing either schema or JSON data, which will
1022   // populate the SymbolTable's or the FlatBufferBuilder above.
1023   // include_paths is used to resolve any include statements, and typically
1024   // should at least include the project path (where you loaded source_ from).
1025   // include_paths must be nullptr terminated if specified.
1026   // If include_paths is nullptr, it will attempt to load from the current
1027   // directory.
1028   // If the source was loaded from a file and isn't an include file,
1029   // supply its name in source_filename.
1030   // All paths specified in this call must be in posix format, if you accept
1031   // paths from user input, please call PosixPath on them first.
1032   bool Parse(const char *_source, const char **include_paths = nullptr,
1033              const char *source_filename = nullptr);
1034 
1035   bool ParseJson(const char *json, const char *json_filename = nullptr);
1036 
1037   // Returns the number of characters were consumed when parsing a JSON string.
1038   std::ptrdiff_t BytesConsumed() const;
1039 
1040   // Set the root type. May override the one set in the schema.
1041   bool SetRootType(const char *name);
1042 
1043   // Mark all definitions as already having code generated.
1044   void MarkGenerated();
1045 
1046   // Get the files recursively included by the given file. The returned
1047   // container will have at least the given file.
1048   std::set<std::string> GetIncludedFilesRecursive(
1049       const std::string &file_name) const;
1050 
1051   // Fills builder_ with a binary version of the schema parsed.
1052   // See reflection/reflection.fbs
1053   void Serialize();
1054 
1055   // Deserialize a schema buffer
1056   bool Deserialize(const uint8_t *buf, const size_t size);
1057 
1058   // Fills internal structure as if the schema passed had been loaded by parsing
1059   // with Parse except that included filenames will not be populated.
1060   bool Deserialize(const reflection::Schema *schema);
1061 
1062   Type *DeserializeType(const reflection::Type *type);
1063 
1064   // Checks that the schema represented by this parser is a safe evolution
1065   // of the schema provided. Returns non-empty error on any problems.
1066   std::string ConformTo(const Parser &base);
1067 
1068   // Similar to Parse(), but now only accepts JSON to be parsed into a
1069   // FlexBuffer.
1070   bool ParseFlexBuffer(const char *source, const char *source_filename,
1071                        flexbuffers::Builder *builder);
1072 
1073   StructDef *LookupStruct(const std::string &id) const;
1074   StructDef *LookupStructThruParentNamespaces(const std::string &id) const;
1075 
1076   std::string UnqualifiedName(const std::string &fullQualifiedName);
1077 
1078   FLATBUFFERS_CHECKED_ERROR Error(const std::string &msg);
1079 
1080   // @brief Verify that any of 'opts.lang_to_generate' supports Optional scalars
1081   // in a schema.
1082   // @param opts Options used to parce a schema and generate code.
1083   static bool SupportsOptionalScalars(const flatbuffers::IDLOptions &opts);
1084 
1085   // Get the set of included files that are directly referenced by the file
1086   // being parsed. This does not include files that are transitively included by
1087   // others includes.
1088   std::vector<IncludedFile> GetIncludedFiles() const;
1089 
1090  private:
1091   class ParseDepthGuard;
1092 
1093   void Message(const std::string &msg);
1094   void Warning(const std::string &msg);
1095   FLATBUFFERS_CHECKED_ERROR ParseHexNum(int nibbles, uint64_t *val);
1096   FLATBUFFERS_CHECKED_ERROR Next();
1097   FLATBUFFERS_CHECKED_ERROR SkipByteOrderMark();
1098   bool Is(int t) const;
1099   bool IsIdent(const char *id) const;
1100   FLATBUFFERS_CHECKED_ERROR Expect(int t);
1101   std::string TokenToStringId(int t) const;
1102   EnumDef *LookupEnum(const std::string &id);
1103   FLATBUFFERS_CHECKED_ERROR ParseNamespacing(std::string *id,
1104                                              std::string *last);
1105   FLATBUFFERS_CHECKED_ERROR ParseTypeIdent(Type &type);
1106   FLATBUFFERS_CHECKED_ERROR ParseType(Type &type);
1107   FLATBUFFERS_CHECKED_ERROR AddField(StructDef &struct_def,
1108                                      const std::string &name, const Type &type,
1109                                      FieldDef **dest);
1110   FLATBUFFERS_CHECKED_ERROR ParseField(StructDef &struct_def);
1111   FLATBUFFERS_CHECKED_ERROR ParseString(Value &val, bool use_string_pooling);
1112   FLATBUFFERS_CHECKED_ERROR ParseComma();
1113   FLATBUFFERS_CHECKED_ERROR ParseAnyValue(Value &val, FieldDef *field,
1114                                           size_t parent_fieldn,
1115                                           const StructDef *parent_struct_def,
1116                                           size_t count,
1117                                           bool inside_vector = false);
1118   template<typename F>
1119   FLATBUFFERS_CHECKED_ERROR ParseTableDelimiters(size_t &fieldn,
1120                                                  const StructDef *struct_def,
1121                                                  F body);
1122   FLATBUFFERS_CHECKED_ERROR ParseTable(const StructDef &struct_def,
1123                                        std::string *value, uoffset_t *ovalue);
1124   void SerializeStruct(const StructDef &struct_def, const Value &val);
1125   void SerializeStruct(FlatBufferBuilder &builder, const StructDef &struct_def,
1126                        const Value &val);
1127   template<typename F>
1128   FLATBUFFERS_CHECKED_ERROR ParseVectorDelimiters(size_t &count, F body);
1129   FLATBUFFERS_CHECKED_ERROR ParseVector(const Type &type, uoffset_t *ovalue,
1130                                         FieldDef *field, size_t fieldn);
1131   FLATBUFFERS_CHECKED_ERROR ParseArray(Value &array);
1132   FLATBUFFERS_CHECKED_ERROR ParseNestedFlatbuffer(
1133       Value &val, FieldDef *field, size_t fieldn,
1134       const StructDef *parent_struct_def);
1135   FLATBUFFERS_CHECKED_ERROR ParseMetaData(SymbolTable<Value> *attributes);
1136   FLATBUFFERS_CHECKED_ERROR TryTypedValue(const std::string *name, int dtoken,
1137                                           bool check, Value &e, BaseType req,
1138                                           bool *destmatch);
1139   FLATBUFFERS_CHECKED_ERROR ParseHash(Value &e, FieldDef *field);
1140   FLATBUFFERS_CHECKED_ERROR TokenError();
1141   FLATBUFFERS_CHECKED_ERROR ParseSingleValue(const std::string *name, Value &e,
1142                                              bool check_now);
1143   FLATBUFFERS_CHECKED_ERROR ParseFunction(const std::string *name, Value &e);
1144   FLATBUFFERS_CHECKED_ERROR ParseEnumFromString(const Type &type,
1145                                                 std::string *result);
1146   StructDef *LookupCreateStruct(const std::string &name,
1147                                 bool create_if_new = true,
1148                                 bool definition = false);
1149   FLATBUFFERS_CHECKED_ERROR ParseEnum(bool is_union, EnumDef **dest,
1150                                       const char *filename);
1151   FLATBUFFERS_CHECKED_ERROR ParseNamespace();
1152   FLATBUFFERS_CHECKED_ERROR StartStruct(const std::string &name,
1153                                         StructDef **dest);
1154   FLATBUFFERS_CHECKED_ERROR StartEnum(const std::string &name, bool is_union,
1155                                       EnumDef **dest);
1156   FLATBUFFERS_CHECKED_ERROR ParseDecl(const char *filename);
1157   FLATBUFFERS_CHECKED_ERROR ParseService(const char *filename);
1158   FLATBUFFERS_CHECKED_ERROR ParseProtoFields(StructDef *struct_def,
1159                                              bool isextend, bool inside_oneof);
1160   FLATBUFFERS_CHECKED_ERROR ParseProtoMapField(StructDef *struct_def);
1161   FLATBUFFERS_CHECKED_ERROR ParseProtoOption();
1162   FLATBUFFERS_CHECKED_ERROR ParseProtoKey();
1163   FLATBUFFERS_CHECKED_ERROR ParseProtoDecl();
1164   FLATBUFFERS_CHECKED_ERROR ParseProtoCurliesOrIdent();
1165   FLATBUFFERS_CHECKED_ERROR ParseTypeFromProtoType(Type *type);
1166   FLATBUFFERS_CHECKED_ERROR SkipAnyJsonValue();
1167   FLATBUFFERS_CHECKED_ERROR ParseFlexBufferNumericConstant(
1168       flexbuffers::Builder *builder);
1169   FLATBUFFERS_CHECKED_ERROR ParseFlexBufferValue(flexbuffers::Builder *builder);
1170   FLATBUFFERS_CHECKED_ERROR StartParseFile(const char *source,
1171                                            const char *source_filename);
1172   FLATBUFFERS_CHECKED_ERROR ParseRoot(const char *_source,
1173                                       const char **include_paths,
1174                                       const char *source_filename);
1175   FLATBUFFERS_CHECKED_ERROR CheckPrivateLeak();
1176   FLATBUFFERS_CHECKED_ERROR CheckPrivatelyLeakedFields(
1177       const Definition &def, const Definition &value_type);
1178   FLATBUFFERS_CHECKED_ERROR DoParse(const char *_source,
1179                                     const char **include_paths,
1180                                     const char *source_filename,
1181                                     const char *include_filename);
1182   FLATBUFFERS_CHECKED_ERROR DoParseJson();
1183   FLATBUFFERS_CHECKED_ERROR CheckClash(std::vector<FieldDef *> &fields,
1184                                        StructDef *struct_def,
1185                                        const char *suffix, BaseType baseType);
1186   FLATBUFFERS_CHECKED_ERROR ParseAlignAttribute(
1187       const std::string &align_constant, size_t min_align, size_t *align);
1188 
1189   bool SupportsAdvancedUnionFeatures() const;
1190   bool SupportsAdvancedArrayFeatures() const;
1191   bool SupportsOptionalScalars() const;
1192   bool SupportsDefaultVectorsAndStrings() const;
1193   bool Supports64BitOffsets() const;
1194   bool SupportsUnionUnderlyingType() const;
1195   Namespace *UniqueNamespace(Namespace *ns);
1196 
1197   FLATBUFFERS_CHECKED_ERROR RecurseError();
1198   template<typename F> CheckedError Recurse(F f);
1199 
1200   const std::string &GetPooledString(const std::string &s) const;
1201 
1202  public:
1203   SymbolTable<Type> types_;
1204   SymbolTable<StructDef> structs_;
1205   SymbolTable<EnumDef> enums_;
1206   SymbolTable<ServiceDef> services_;
1207   std::vector<Namespace *> namespaces_;
1208   Namespace *current_namespace_;
1209   Namespace *empty_namespace_;
1210   std::string error_;  // User readable error_ if Parse() == false
1211 
1212   FlatBufferBuilder builder_;  // any data contained in the file
1213   flexbuffers::Builder flex_builder_;
1214   flexbuffers::Reference flex_root_;
1215   StructDef *root_struct_def_;
1216   std::string file_identifier_;
1217   std::string file_extension_;
1218 
1219   std::map<uint64_t, std::string> included_files_;
1220   std::map<std::string, std::set<IncludedFile>> files_included_per_file_;
1221   std::vector<std::string> native_included_files_;
1222 
1223   std::map<std::string, bool> known_attributes_;
1224 
1225   IDLOptions opts;
1226   bool uses_flexbuffers_;
1227   bool has_warning_;
1228 
1229   uint64_t advanced_features_;
1230 
1231   std::string file_being_parsed_;
1232 
1233  private:
1234   const char *source_;
1235 
1236   std::vector<std::pair<Value, FieldDef *>> field_stack_;
1237 
1238   // TODO(cneo): Refactor parser to use string_cache more often to save
1239   // on memory usage.
1240   mutable std::set<std::string> string_cache_;
1241 
1242   int anonymous_counter_;
1243   int parse_depth_counter_;  // stack-overflow guard
1244 };
1245 
1246 // Utility functions for multiple generators:
1247 
1248 // Generate text (JSON) from a given FlatBuffer, and a given Parser
1249 // object that has been populated with the corresponding schema.
1250 // If ident_step is 0, no indentation will be generated. Additionally,
1251 // if it is less than 0, no linefeeds will be generated either.
1252 // See idl_gen_text.cpp.
1253 // strict_json adds "quotes" around field names if true.
1254 // These functions return nullptr on success, or an error string,
1255 // which may happen if the flatbuffer cannot be encoded in JSON (e.g.,
1256 // it contains non-UTF-8 byte arrays in String values).
1257 extern bool GenerateTextFromTable(const Parser &parser,
1258                                          const void *table,
1259                                          const std::string &tablename,
1260                                          std::string *text);
1261 extern const char *GenerateText(const Parser &parser, const void *flatbuffer,
1262                                 std::string *text);
1263 extern const char *GenerateTextFile(const Parser &parser,
1264                                     const std::string &path,
1265                                     const std::string &file_name);
1266 
1267 extern const char *GenTextFromTable(const Parser &parser, const void *table,
1268                                     const std::string &tablename,
1269                                     std::string *text);
1270 extern const char *GenText(const Parser &parser, const void *flatbuffer,
1271                            std::string *text);
1272 extern const char *GenTextFile(const Parser &parser, const std::string &path,
1273                                const std::string &file_name);
1274 
1275 // Generate GRPC Cpp interfaces.
1276 // See idl_gen_grpc.cpp.
1277 bool GenerateCppGRPC(const Parser &parser, const std::string &path,
1278                      const std::string &file_name);
1279 
1280 // Generate GRPC Go interfaces.
1281 // See idl_gen_grpc.cpp.
1282 bool GenerateGoGRPC(const Parser &parser, const std::string &path,
1283                     const std::string &file_name);
1284 
1285 // Generate GRPC Java classes.
1286 // See idl_gen_grpc.cpp
1287 bool GenerateJavaGRPC(const Parser &parser, const std::string &path,
1288                       const std::string &file_name);
1289 
1290 // Generate GRPC Python interfaces.
1291 // See idl_gen_grpc.cpp.
1292 bool GeneratePythonGRPC(const Parser &parser, const std::string &path,
1293                         const std::string &file_name);
1294 
1295 // Generate GRPC Swift interfaces.
1296 // See idl_gen_grpc.cpp.
1297 extern bool GenerateSwiftGRPC(const Parser &parser, const std::string &path,
1298                               const std::string &file_name);
1299 
1300 extern bool GenerateTSGRPC(const Parser &parser, const std::string &path,
1301                            const std::string &file_name);
1302 }  // namespace flatbuffers
1303 
1304 #endif  // FLATBUFFERS_IDL_H_