/*
 * Copyright 2014 Google Inc. All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef FLATBUFFERS_IDL_H_
#define FLATBUFFERS_IDL_H_

#include <algorithm>
#include <functional>
#include <map>
#include <memory>
#include <stack>

#include "flatbuffers/base.h"
#include "flatbuffers/flatbuffers.h"
#include "flatbuffers/flexbuffers.h"
#include "flatbuffers/hash.h"
#include "flatbuffers/reflection.h"

// This file defines the data types representing a parsed IDL (Interface
// Definition Language) / schema file.

// Limits maximum depth of nested objects.
// Prevents stack overflow while parse scheme, or json, or flexbuffer.
#if !defined(FLATBUFFERS_MAX_PARSING_DEPTH)
#  define FLATBUFFERS_MAX_PARSING_DEPTH 64
#endif

namespace flatbuffers {

// The order of these matters for Is*() functions below.
// Additionally, Parser::ParseType assumes bool..string is a contiguous range
// of type tokens.
// clang-format off
#define FLATBUFFERS_GEN_TYPES_SCALAR(TD) \
  TD(NONE,   "",       uint8_t,  byte,   byte,    byte,   uint8,   u8,   UByte, UInt8) \
  TD(UTYPE,  "",       uint8_t,  byte,   byte,    byte,   uint8,   u8,   UByte, UInt8) /* begin scalar/int */ \
  TD(BOOL,   "bool",   uint8_t,  boolean,bool,    bool,   bool,    bool, Boolean, Bool) \
  TD(CHAR,   "byte",   int8_t,   byte,   int8,    sbyte,  int8,    i8,   Byte, Int8) \
  TD(UCHAR,  "ubyte",  uint8_t,  byte,   byte,    byte,   uint8,   u8,   UByte, UInt8) \
  TD(SHORT,  "short",  int16_t,  short,  int16,   short,  int16,   i16,  Short, Int16) \
  TD(USHORT, "ushort", uint16_t, short,  uint16,  ushort, uint16,  u16,  UShort, UInt16) \
  TD(INT,    "int",    int32_t,  int,    int32,   int,    int32,   i32,  Int, Int32) \
  TD(UINT,   "uint",   uint32_t, int,    uint32,  uint,   uint32,  u32,  UInt, UInt32) \
  TD(LONG,   "long",   int64_t,  long,   int64,   long,   int64,   i64,  Long, Int64) \
  TD(ULONG,  "ulong",  uint64_t, long,   uint64,  ulong,  uint64,  u64,  ULong, UInt64) /* end int */ \
  TD(FLOAT,  "float",  float,    float,  float32, float,  float32, f32,  Float, Float32) /* begin float */ \
  TD(DOUBLE, "double", double,   double, float64, double, float64, f64,  Double, Double) /* end float/scalar */
#define FLATBUFFERS_GEN_TYPES_POINTER(TD) \
  TD(STRING, "string", Offset<void>, int, int, StringOffset, int, unused, Int, Offset<String>) \
  TD(VECTOR, "",       Offset<void>, int, int, VectorOffset, int, unused, Int, Offset<UOffset>) \
  TD(STRUCT, "",       Offset<void>, int, int, int,          int, unused, Int, Offset<UOffset>) \
  TD(UNION,  "",       Offset<void>, int, int, int,          int, unused, Int, Offset<UOffset>)
#define FLATBUFFERS_GEN_TYPE_ARRAY(TD) \
  TD(ARRAY,  "",       int,          int, int, int,          int, unused, Int, Offset<UOffset>)
// The fields are:
// - enum
// - FlatBuffers schema type.
// - C++ type.
// - Java type.
// - Go type.
// - C# / .Net type.
// - Python type.
// - Kotlin type.
// - Rust type.

// using these macros, we can now write code dealing with types just once, e.g.

/*
switch (type) {
  #define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE, JTYPE, GTYPE, NTYPE, PTYPE, \
                         RTYPE, KTYPE) \
    case BASE_TYPE_ ## ENUM: \
      // do something specific to CTYPE here
    FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD)
  #undef FLATBUFFERS_TD
}
*/

// If not all FLATBUFFERS_GEN_() arguments are necessary for implementation
// of FLATBUFFERS_TD, you can use a variadic macro (with __VA_ARGS__ if needed).
// In the above example, only CTYPE is used to generate the code, it can be rewritten:

/*
switch (type) {
  #define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE, ...) \
    case BASE_TYPE_ ## ENUM: \
      // do something specific to CTYPE here
    FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD)
  #undef FLATBUFFERS_TD
}
*/

#define FLATBUFFERS_GEN_TYPES(TD) \
        FLATBUFFERS_GEN_TYPES_SCALAR(TD) \
        FLATBUFFERS_GEN_TYPES_POINTER(TD) \
        FLATBUFFERS_GEN_TYPE_ARRAY(TD)

// Create an enum for all the types above.
#ifdef __GNUC__
__extension__  // Stop GCC complaining about trailing comma with -Wpendantic.
#endif
enum BaseType {
  #define FLATBUFFERS_TD(ENUM, ...) \
    BASE_TYPE_ ## ENUM,
    FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD)
  #undef FLATBUFFERS_TD
};

#define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE, ...) \
  static_assert(sizeof(CTYPE) <= sizeof(largest_scalar_t), \
                "define largest_scalar_t as " #CTYPE);
  FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD)
#undef FLATBUFFERS_TD

inline bool IsScalar (BaseType t) { return t >= BASE_TYPE_UTYPE &&
                                           t <= BASE_TYPE_DOUBLE; }
inline bool IsInteger(BaseType t) { return t >= BASE_TYPE_UTYPE &&
                                           t <= BASE_TYPE_ULONG; }
inline bool IsFloat  (BaseType t) { return t == BASE_TYPE_FLOAT ||
                                           t == BASE_TYPE_DOUBLE; }
inline bool IsLong   (BaseType t) { return t == BASE_TYPE_LONG ||
                                           t == BASE_TYPE_ULONG; }
inline bool IsBool   (BaseType t) { return t == BASE_TYPE_BOOL; }
inline bool IsOneByte(BaseType t) { return t >= BASE_TYPE_UTYPE &&
                                           t <= BASE_TYPE_UCHAR; }

inline bool IsUnsigned(BaseType t) {
  return (t == BASE_TYPE_UTYPE)  || (t == BASE_TYPE_UCHAR) ||
         (t == BASE_TYPE_USHORT) || (t == BASE_TYPE_UINT)  ||
         (t == BASE_TYPE_ULONG);
}

// clang-format on

extern const char *const kTypeNames[];
extern const char kTypeSizes[];

inline size_t SizeOf(BaseType t) { return kTypeSizes[t]; }

struct StructDef;
struct EnumDef;
class Parser;

// Represents any type in the IDL, which is a combination of the BaseType
// and additional information for vectors/structs_.
struct Type {
  explicit Type(BaseType _base_type = BASE_TYPE_NONE, StructDef *_sd = nullptr,
                EnumDef *_ed = nullptr, uint16_t _fixed_length = 0)
      : base_type(_base_type),
        element(BASE_TYPE_NONE),
        struct_def(_sd),
        enum_def(_ed),
        fixed_length(_fixed_length) {}

  bool operator==(const Type &o) const {
    return base_type == o.base_type && element == o.element &&
           struct_def == o.struct_def && enum_def == o.enum_def;
  }

  Type VectorType() const {
    return Type(element, struct_def, enum_def, fixed_length);
  }

  Offset<reflection::Type> Serialize(FlatBufferBuilder *builder) const;

  bool Deserialize(const Parser &parser, const reflection::Type *type);

  BaseType base_type;
  BaseType element;       // only set if t == BASE_TYPE_VECTOR
  StructDef *struct_def;  // only set if t or element == BASE_TYPE_STRUCT
  EnumDef *enum_def;      // set if t == BASE_TYPE_UNION / BASE_TYPE_UTYPE,
                          // or for an integral type derived from an enum.
  uint16_t fixed_length;  // only set if t == BASE_TYPE_ARRAY
};

// Represents a parsed scalar value, it's type, and field offset.
struct Value {
  Value()
      : constant("0"),
        offset(static_cast<voffset_t>(~(static_cast<voffset_t>(0U)))) {}
  Type type;
  std::string constant;
  voffset_t offset;
};

// Helper class that retains the original order of a set of identifiers and
// also provides quick lookup.
template<typename T> class SymbolTable {
 public:
  ~SymbolTable() {
    for (auto it = vec.begin(); it != vec.end(); ++it) { delete *it; }
  }

  bool Add(const std::string &name, T *e) {
    vec.emplace_back(e);
    auto it = dict.find(name);
    if (it != dict.end()) return true;
    dict[name] = e;
    return false;
  }

  void Move(const std::string &oldname, const std::string &newname) {
    auto it = dict.find(oldname);
    if (it != dict.end()) {
      auto obj = it->second;
      dict.erase(it);
      dict[newname] = obj;
    } else {
      FLATBUFFERS_ASSERT(false);
    }
  }

  T *Lookup(const std::string &name) const {
    auto it = dict.find(name);
    return it == dict.end() ? nullptr : it->second;
  }

 public:
  std::map<std::string, T *> dict;  // quick lookup
  std::vector<T *> vec;             // Used to iterate in order of insertion
};

// A name space, as set in the schema.
struct Namespace {
  Namespace() : from_table(0) {}

  // Given a (potentially unqualified) name, return the "fully qualified" name
  // which has a full namespaced descriptor.
  // With max_components you can request less than the number of components
  // the current namespace has.
  std::string GetFullyQualifiedName(const std::string &name,
                                    size_t max_components = 1000) const;

  std::vector<std::string> components;
  size_t from_table;  // Part of the namespace corresponds to a message/table.
};

inline bool operator<(const Namespace &a, const Namespace &b) {
  size_t min_size = std::min(a.components.size(), b.components.size());
  for (size_t i = 0; i < min_size; ++i) {
    if (a.components[i] != b.components[i])
      return a.components[i] < b.components[i];
  }
  return a.components.size() < b.components.size();
}

// Base class for all definition types (fields, structs_, enums_).
struct Definition {
  Definition()
      : generated(false),
        defined_namespace(nullptr),
        serialized_location(0),
        index(-1),
        refcount(1),
        declaration_file(nullptr) {}

  flatbuffers::Offset<
      flatbuffers::Vector<flatbuffers::Offset<reflection::KeyValue>>>
  SerializeAttributes(FlatBufferBuilder *builder, const Parser &parser) const;

  bool DeserializeAttributes(Parser &parser,
                             const Vector<Offset<reflection::KeyValue>> *attrs);

  std::string name;
  std::string file;
  std::vector<std::string> doc_comment;
  SymbolTable<Value> attributes;
  bool generated;  // did we already output code for this definition?
  Namespace *defined_namespace;  // Where it was defined.

  // For use with Serialize()
  uoffset_t serialized_location;
  int index;  // Inside the vector it is stored.
  int refcount;
  const std::string *declaration_file;
};

struct FieldDef : public Definition {
  FieldDef()
      : deprecated(false),
        key(false),
        shared(false),
        native_inline(false),
        flexbuffer(false),
        presence(kDefault),
        nested_flatbuffer(nullptr),
        padding(0) {}

  Offset<reflection::Field> Serialize(FlatBufferBuilder *builder, uint16_t id,
                                      const Parser &parser) const;

  bool Deserialize(Parser &parser, const reflection::Field *field);

  bool IsScalarOptional() const {
    return IsScalar(value.type.base_type) && IsOptional();
  }
  bool IsOptional() const { return presence == kOptional; }
  bool IsRequired() const { return presence == kRequired; }
  bool IsDefault() const { return presence == kDefault; }

  Value value;
  bool deprecated;  // Field is allowed to be present in old data, but can't be.
                    // written in new data nor accessed in new code.
  bool key;         // Field functions as a key for creating sorted vectors.
  bool shared;  // Field will be using string pooling (i.e. CreateSharedString)
                // as default serialization behavior if field is a string.
  bool native_inline;  // Field will be defined inline (instead of as a pointer)
                       // for native tables if field is a struct.
  bool flexbuffer;     // This field contains FlexBuffer data.

  enum Presence {
    // Field must always be present.
    kRequired,
    // Non-presence should be signalled to and controlled by users.
    kOptional,
    // Non-presence is hidden from users.
    // Implementations may omit writing default values.
    kDefault,
  };
  Presence static MakeFieldPresence(bool optional, bool required) {
    FLATBUFFERS_ASSERT(!(required && optional));
    // clang-format off
    return required ? FieldDef::kRequired
         : optional ? FieldDef::kOptional
                    : FieldDef::kDefault;
    // clang-format on
  }
  Presence presence;

  StructDef *nested_flatbuffer;  // This field contains nested FlatBuffer data.
  size_t padding;                // Bytes to always pad after this field.
};

struct StructDef : public Definition {
  StructDef()
      : fixed(false),
        predecl(true),
        sortbysize(true),
        has_key(false),
        minalign(1),
        bytesize(0) {}

  void PadLastField(size_t min_align) {
    auto padding = PaddingBytes(bytesize, min_align);
    bytesize += padding;
    if (fields.vec.size()) fields.vec.back()->padding = padding;
  }

  Offset<reflection::Object> Serialize(FlatBufferBuilder *builder,
                                       const Parser &parser) const;

  bool Deserialize(Parser &parser, const reflection::Object *object);

  SymbolTable<FieldDef> fields;

  bool fixed;       // If it's struct, not a table.
  bool predecl;     // If it's used before it was defined.
  bool sortbysize;  // Whether fields come in the declaration or size order.
  bool has_key;     // It has a key field.
  size_t minalign;  // What the whole object needs to be aligned to.
  size_t bytesize;  // Size if fixed.

  flatbuffers::unique_ptr<std::string> original_location;
};

struct EnumDef;
struct EnumValBuilder;

struct EnumVal {
  Offset<reflection::EnumVal> Serialize(FlatBufferBuilder *builder,
                                        const Parser &parser) const;

  bool Deserialize(Parser &parser, const reflection::EnumVal *val);

  flatbuffers::Offset<
      flatbuffers::Vector<flatbuffers::Offset<reflection::KeyValue>>>
  SerializeAttributes(FlatBufferBuilder *builder, const Parser &parser) const;

  bool DeserializeAttributes(Parser &parser,
                             const Vector<Offset<reflection::KeyValue>> *attrs);

  uint64_t GetAsUInt64() const { return static_cast<uint64_t>(value); }
  int64_t GetAsInt64() const { return value; }
  bool IsZero() const { return 0 == value; }
  bool IsNonZero() const { return !IsZero(); }

  std::string name;
  std::vector<std::string> doc_comment;
  Type union_type;
  SymbolTable<Value> attributes;

 private:
  friend EnumDef;
  friend EnumValBuilder;
  friend bool operator==(const EnumVal &lhs, const EnumVal &rhs);

  EnumVal(const std::string &_name, int64_t _val) : name(_name), value(_val) {}
  EnumVal() : value(0) {}

  int64_t value;
};

struct EnumDef : public Definition {
  EnumDef() : is_union(false), uses_multiple_type_instances(false) {}

  Offset<reflection::Enum> Serialize(FlatBufferBuilder *builder,
                                     const Parser &parser) const;

  bool Deserialize(Parser &parser, const reflection::Enum *values);

  template<typename T> void ChangeEnumValue(EnumVal *ev, T new_val);
  void SortByValue();
  void RemoveDuplicates();

  std::string AllFlags() const;
  const EnumVal *MinValue() const;
  const EnumVal *MaxValue() const;
  // Returns the number of integer steps from v1 to v2.
  uint64_t Distance(const EnumVal *v1, const EnumVal *v2) const;
  // Returns the number of integer steps from Min to Max.
  uint64_t Distance() const { return Distance(MinValue(), MaxValue()); }

  EnumVal *ReverseLookup(int64_t enum_idx,
                         bool skip_union_default = false) const;
  EnumVal *FindByValue(const std::string &constant) const;

  std::string ToString(const EnumVal &ev) const {
    return IsUInt64() ? NumToString(ev.GetAsUInt64())
                      : NumToString(ev.GetAsInt64());
  }

  size_t size() const { return vals.vec.size(); }

  const std::vector<EnumVal *> &Vals() const { return vals.vec; }

  const EnumVal *Lookup(const std::string &enum_name) const {
    return vals.Lookup(enum_name);
  }

  bool is_union;
  // Type is a union which uses type aliases where at least one type is
  // available under two different names.
  bool uses_multiple_type_instances;
  Type underlying_type;

 private:
  bool IsUInt64() const {
    return (BASE_TYPE_ULONG == underlying_type.base_type);
  }

  friend EnumValBuilder;
  SymbolTable<EnumVal> vals;
};

inline bool IsString(const Type &type) {
  return type.base_type == BASE_TYPE_STRING;
}

inline bool IsStruct(const Type &type) {
  return type.base_type == BASE_TYPE_STRUCT && type.struct_def->fixed;
}

inline bool IsTable(const Type &type) {
  return type.base_type == BASE_TYPE_STRUCT && !type.struct_def->fixed;
}

inline bool IsUnion(const Type &type) {
  return type.enum_def != nullptr && type.enum_def->is_union;
}

inline bool IsUnionType(const Type &type) {
  return IsUnion(type) && IsInteger(type.base_type);
}

inline bool IsVector(const Type &type) {
  return type.base_type == BASE_TYPE_VECTOR;
}

inline bool IsVectorOfStruct(const Type &type) {
  return IsVector(type) && IsStruct(type.VectorType());
}

inline bool IsVectorOfTable(const Type &type) {
  return IsVector(type) && IsTable(type.VectorType());
}

inline bool IsArray(const Type &type) {
  return type.base_type == BASE_TYPE_ARRAY;
}

inline bool IsSeries(const Type &type) {
  return IsVector(type) || IsArray(type);
}

inline bool IsEnum(const Type &type) {
  return type.enum_def != nullptr && IsInteger(type.base_type);
}

inline size_t InlineSize(const Type &type) {
  return IsStruct(type)
             ? type.struct_def->bytesize
             : (IsArray(type)
                    ? InlineSize(type.VectorType()) * type.fixed_length
                    : SizeOf(type.base_type));
}

inline size_t InlineAlignment(const Type &type) {
  if (IsStruct(type)) {
    return type.struct_def->minalign;
  } else if (IsArray(type)) {
    return IsStruct(type.VectorType()) ? type.struct_def->minalign
                                       : SizeOf(type.element);
  } else {
    return SizeOf(type.base_type);
  }
}
inline bool operator==(const EnumVal &lhs, const EnumVal &rhs) {
  return lhs.value == rhs.value;
}
inline bool operator!=(const EnumVal &lhs, const EnumVal &rhs) {
  return !(lhs == rhs);
}

inline bool EqualByName(const Type &a, const Type &b) {
  return a.base_type == b.base_type && a.element == b.element &&
         (a.struct_def == b.struct_def ||
          a.struct_def->name == b.struct_def->name) &&
         (a.enum_def == b.enum_def || a.enum_def->name == b.enum_def->name);
}

struct RPCCall : public Definition {
  Offset<reflection::RPCCall> Serialize(FlatBufferBuilder *builder,
                                        const Parser &parser) const;

  bool Deserialize(Parser &parser, const reflection::RPCCall *call);

  StructDef *request, *response;
};

struct ServiceDef : public Definition {
  Offset<reflection::Service> Serialize(FlatBufferBuilder *builder,
                                        const Parser &parser) const;
  bool Deserialize(Parser &parser, const reflection::Service *service);

  SymbolTable<RPCCall> calls;
};

struct IncludedFile {
  // The name of the schema file being included, as defined in the .fbs file.
  // This includes the prefix (e.g., include "foo/bar/baz.fbs" would mean this
  // value is "foo/bar/baz.fbs").
  std::string schema_name;

  // The filename of where the included file was found, after searching the
  // relative paths plus any other paths included with `flatc -I ...`. Note,
  // while this is sometimes the same as schema_name, it is not always, since it
  // can be defined relative to where flatc was invoked.
  std::string filename;
};

// Since IncludedFile is contained within a std::set, need to provide ordering.
inline bool operator<(const IncludedFile &a, const IncludedFile &b) {
  return a.filename < b.filename;
}

// Container of options that may apply to any of the source/text generators.
struct IDLOptions {
  // field case style options for C++
  enum CaseStyle { CaseStyle_Unchanged = 0, CaseStyle_Upper, CaseStyle_Lower };

  bool gen_jvmstatic;
  // Use flexbuffers instead for binary and text generation
  bool use_flexbuffers;
  bool strict_json;
  bool output_default_scalars_in_json;
  int indent_step;
  bool cpp_minify_enums;
  bool output_enum_identifiers;
  bool prefixed_enums;
  bool scoped_enums;
  bool swift_implementation_only;
  bool include_dependence_headers;
  bool mutable_buffer;
  bool one_file;
  bool proto_mode;
  bool proto_oneof_union;
  bool generate_all;
  bool skip_unexpected_fields_in_json;
  bool generate_name_strings;
  bool generate_object_based_api;
  bool gen_compare;
  std::string cpp_object_api_pointer_type;
  std::string cpp_object_api_string_type;
  bool cpp_object_api_string_flexible_constructor;
  CaseStyle cpp_object_api_field_case_style;
  bool cpp_direct_copy;
  bool gen_nullable;
  bool java_checkerframework;
  bool gen_generated;
  bool gen_json_coders;
  std::string object_prefix;
  std::string object_suffix;
  bool union_value_namespacing;
  bool allow_non_utf8;
  bool natural_utf8;
  std::string include_prefix;
  bool keep_prefix;
  bool binary_schema_comments;
  bool binary_schema_builtins;
  bool binary_schema_gen_embed;
  std::string go_import;
  std::string go_namespace;
  std::string go_module_name;
  bool protobuf_ascii_alike;
  bool size_prefixed;
  std::string root_type;
  bool force_defaults;
  bool java_primitive_has_method;
  bool cs_gen_json_serializer;
  std::vector<std::string> cpp_includes;
  std::string cpp_std;
  bool cpp_static_reflection;
  std::string proto_namespace_suffix;
  std::string filename_suffix;
  std::string filename_extension;
  bool no_warnings;
  bool warnings_as_errors;
  std::string project_root;
  bool cs_global_alias;
  bool json_nested_flatbuffers;
  bool json_nested_flexbuffers;
  bool json_nested_legacy_flatbuffers;
  bool ts_flat_file;
  bool no_leak_private_annotations;
  bool require_json_eof;

  // Possible options for the more general generator below.
  enum Language {
    kJava = 1 << 0,
    kCSharp = 1 << 1,
    kGo = 1 << 2,
    kCpp = 1 << 3,
    kPython = 1 << 5,
    kPhp = 1 << 6,
    kJson = 1 << 7,
    kBinary = 1 << 8,
    kTs = 1 << 9,
    kJsonSchema = 1 << 10,
    kDart = 1 << 11,
    kLua = 1 << 12,
    kLobster = 1 << 13,
    kRust = 1 << 14,
    kKotlin = 1 << 15,
    kSwift = 1 << 16,
    kNim = 1 << 17,
    kMAX
  };

  enum MiniReflect { kNone, kTypes, kTypesAndNames };

  MiniReflect mini_reflect;

  // If set, require all fields in a table to be explicitly numbered.
  bool require_explicit_ids;

  // If set, implement serde::Serialize for generated Rust types
  bool rust_serialize;

  // If set, generate rust types in individual files with a root module file.
  bool rust_module_root_file;

  // The corresponding language bit will be set if a language is included
  // for code generation.
  unsigned long lang_to_generate;

  // 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()
      : gen_jvmstatic(false),
        use_flexbuffers(false),
        strict_json(false),
        output_default_scalars_in_json(false),
        indent_step(2),
        cpp_minify_enums(false),
        output_enum_identifiers(true),
        prefixed_enums(true),
        scoped_enums(false),
        swift_implementation_only(false),
        include_dependence_headers(true),
        mutable_buffer(false),
        one_file(false),
        proto_mode(false),
        proto_oneof_union(false),
        generate_all(false),
        skip_unexpected_fields_in_json(false),
        generate_name_strings(false),
        generate_object_based_api(false),
        gen_compare(false),
        cpp_object_api_pointer_type("std::unique_ptr"),
        cpp_object_api_string_flexible_constructor(false),
        cpp_object_api_field_case_style(CaseStyle_Unchanged),
        cpp_direct_copy(true),
        gen_nullable(false),
        java_checkerframework(false),
        gen_generated(false),
        gen_json_coders(false),
        object_suffix("T"),
        union_value_namespacing(true),
        allow_non_utf8(false),
        natural_utf8(false),
        keep_prefix(false),
        binary_schema_comments(false),
        binary_schema_builtins(false),
        binary_schema_gen_embed(false),
        protobuf_ascii_alike(false),
        size_prefixed(false),
        force_defaults(false),
        java_primitive_has_method(false),
        cs_gen_json_serializer(false),
        cpp_static_reflection(false),
        filename_suffix("_generated"),
        filename_extension(),
        no_warnings(false),
        warnings_as_errors(false),
        project_root(""),
        cs_global_alias(false),
        json_nested_flatbuffers(true),
        json_nested_flexbuffers(true),
        json_nested_legacy_flatbuffers(false),
        ts_flat_file(false),
        no_leak_private_annotations(false),
        require_json_eof(true),
        mini_reflect(IDLOptions::kNone),
        require_explicit_ids(false),
        rust_serialize(false),
        rust_module_root_file(false),
        lang_to_generate(0),
        set_empty_strings_to_null(true),
        set_empty_vectors_to_null(true) {}
};

// This encapsulates where the parser is in the current source file.
struct ParserState {
  ParserState()
      : prev_cursor_(nullptr),
        cursor_(nullptr),
        line_start_(nullptr),
        line_(0),
        token_(-1),
        attr_is_trivial_ascii_string_(true) {}

 protected:
  void ResetState(const char *source) {
    prev_cursor_ = source;
    cursor_ = source;
    line_ = 0;
    MarkNewLine();
  }

  void MarkNewLine() {
    line_start_ = cursor_;
    line_ += 1;
  }

  int64_t CursorPosition() const {
    FLATBUFFERS_ASSERT(cursor_ && line_start_ && cursor_ >= line_start_);
    return static_cast<int64_t>(cursor_ - line_start_);
  }
  
  const char *prev_cursor_;
  const char *cursor_;
  const char *line_start_;
  int line_;  // the current line being parsed
  int token_;

  // Flag: text in attribute_ is true ASCII string without escape
  // sequences. Only printable ASCII (without [\t\r\n]).
  // Used for number-in-string (and base64 string in future).
  bool attr_is_trivial_ascii_string_;
  std::string attribute_;
  std::vector<std::string> doc_comment_;
};

// A way to make error propagation less error prone by requiring values to be
// checked.
// Once you create a value of this type you must either:
// - Call Check() on it.
// - Copy or assign it to another value.
// Failure to do so leads to an assert.
// This guarantees that this as return value cannot be ignored.
class CheckedError {
 public:
  explicit CheckedError(bool error)
      : is_error_(error), has_been_checked_(false) {}

  CheckedError &operator=(const CheckedError &other) {
    is_error_ = other.is_error_;
    has_been_checked_ = false;
    other.has_been_checked_ = true;
    return *this;
  }

  CheckedError(const CheckedError &other) {
    *this = other;  // Use assignment operator.
  }

  ~CheckedError() { FLATBUFFERS_ASSERT(has_been_checked_); }

  bool Check() {
    has_been_checked_ = true;
    return is_error_;
  }

 private:
  bool is_error_;
  mutable bool has_been_checked_;
};

// Additionally, in GCC we can get these errors statically, for additional
// assurance:
// clang-format off
#ifdef __GNUC__
#define FLATBUFFERS_CHECKED_ERROR CheckedError \
          __attribute__((warn_unused_result))
#else
#define FLATBUFFERS_CHECKED_ERROR CheckedError
#endif
// clang-format on

class Parser : public ParserState {
 public:
  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),
        has_warning_(false),
        advanced_features_(0),
        source_(nullptr),
        anonymous_counter_(0),
        parse_depth_counter_(0) {
    if (opts.force_defaults) { builder_.ForceDefaults(true); }
    // Start out with the empty namespace being current.
    empty_namespace_ = new Namespace();
    namespaces_.push_back(empty_namespace_);
    current_namespace_ = empty_namespace_;
    known_attributes_["deprecated"] = true;
    known_attributes_["required"] = true;
    known_attributes_["key"] = true;
    known_attributes_["shared"] = true;
    known_attributes_["hash"] = true;
    known_attributes_["id"] = true;
    known_attributes_["force_align"] = true;
    known_attributes_["bit_flags"] = true;
    known_attributes_["original_order"] = true;
    known_attributes_["nested_flatbuffer"] = true;
    known_attributes_["csharp_partial"] = true;
    known_attributes_["streaming"] = true;
    known_attributes_["idempotent"] = true;
    known_attributes_["cpp_type"] = true;
    known_attributes_["cpp_ptr_type"] = true;
    known_attributes_["cpp_ptr_type_get"] = true;
    known_attributes_["cpp_str_type"] = true;
    known_attributes_["cpp_str_flex_ctor"] = true;
    known_attributes_["native_inline"] = true;
    known_attributes_["native_custom_alloc"] = true;
    known_attributes_["native_type"] = true;
    known_attributes_["native_type_pack_name"] = true;
    known_attributes_["native_default"] = true;
    known_attributes_["flexbuffer"] = true;
    known_attributes_["private"] = true;
  }

  ~Parser() {
    for (auto it = namespaces_.begin(); it != namespaces_.end(); ++it) {
      delete *it;
    }
  }

  // Parse the string containing either schema or JSON data, which will
  // populate the SymbolTable's or the FlatBufferBuilder above.
  // include_paths is used to resolve any include statements, and typically
  // should at least include the project path (where you loaded source_ from).
  // include_paths must be nullptr terminated if specified.
  // If include_paths is nullptr, it will attempt to load from the current
  // directory.
  // If the source was loaded from a file and isn't an include file,
  // supply its name in source_filename.
  // All paths specified in this call must be in posix format, if you accept
  // paths from user input, please call PosixPath on them first.
  bool Parse(const char *_source, const char **include_paths = nullptr,
             const char *source_filename = nullptr);

  bool ParseJson(const char *json, const char *json_filename = nullptr);

  // Returns the number of characters were consumed when parsing a JSON string.
  std::ptrdiff_t BytesConsumed() const;

  // Set the root type. May override the one set in the schema.
  bool SetRootType(const char *name);

  // Mark all definitions as already having code generated.
  void MarkGenerated();

  // Get the files recursively included by the given file. The returned
  // container will have at least the given file.
  std::set<std::string> GetIncludedFilesRecursive(
      const std::string &file_name) const;

  // Fills builder_ with a binary version of the schema parsed.
  // See reflection/reflection.fbs
  void Serialize();

  // Deserialize a schema buffer
  bool Deserialize(const uint8_t *buf, const size_t size);

  // Fills internal structure as if the schema passed had been loaded by parsing
  // with Parse except that included filenames will not be populated.
  bool Deserialize(const reflection::Schema *schema);

  Type *DeserializeType(const reflection::Type *type);

  // Checks that the schema represented by this parser is a safe evolution
  // of the schema provided. Returns non-empty error on any problems.
  std::string ConformTo(const Parser &base);

  // Similar to Parse(), but now only accepts JSON to be parsed into a
  // FlexBuffer.
  bool ParseFlexBuffer(const char *source, const char *source_filename,
                       flexbuffers::Builder *builder);

  StructDef *LookupStruct(const std::string &id) const;
  StructDef *LookupStructThruParentNamespaces(const std::string &id) const;

  std::string UnqualifiedName(const std::string &fullQualifiedName);

  FLATBUFFERS_CHECKED_ERROR Error(const std::string &msg);

  // @brief Verify that any of 'opts.lang_to_generate' supports Optional scalars
  // in a schema.
  // @param opts Options used to parce a schema and generate code.
  static bool SupportsOptionalScalars(const flatbuffers::IDLOptions &opts);

  // Get the set of included files that are directly referenced by the file
  // being parsed. This does not include files that are transitively included by
  // others includes.
  std::vector<IncludedFile> GetIncludedFiles() const;

 private:
  class ParseDepthGuard;

  void Message(const std::string &msg);
  void Warning(const std::string &msg);
  FLATBUFFERS_CHECKED_ERROR ParseHexNum(int nibbles, uint64_t *val);
  FLATBUFFERS_CHECKED_ERROR Next();
  FLATBUFFERS_CHECKED_ERROR SkipByteOrderMark();
  bool Is(int t) const;
  bool IsIdent(const char *id) const;
  FLATBUFFERS_CHECKED_ERROR Expect(int t);
  std::string TokenToStringId(int t) const;
  EnumDef *LookupEnum(const std::string &id);
  FLATBUFFERS_CHECKED_ERROR ParseNamespacing(std::string *id,
                                             std::string *last);
  FLATBUFFERS_CHECKED_ERROR ParseTypeIdent(Type &type);
  FLATBUFFERS_CHECKED_ERROR ParseType(Type &type);
  FLATBUFFERS_CHECKED_ERROR AddField(StructDef &struct_def,
                                     const std::string &name, const Type &type,
                                     FieldDef **dest);
  FLATBUFFERS_CHECKED_ERROR ParseField(StructDef &struct_def);
  FLATBUFFERS_CHECKED_ERROR ParseString(Value &val, bool use_string_pooling);
  FLATBUFFERS_CHECKED_ERROR ParseComma();
  FLATBUFFERS_CHECKED_ERROR ParseAnyValue(Value &val, FieldDef *field,
                                          size_t parent_fieldn,
                                          const StructDef *parent_struct_def,
                                          uoffset_t count,
                                          bool inside_vector = false);
  template<typename F>
  FLATBUFFERS_CHECKED_ERROR ParseTableDelimiters(size_t &fieldn,
                                                 const StructDef *struct_def,
                                                 F body);
  FLATBUFFERS_CHECKED_ERROR ParseTable(const StructDef &struct_def,
                                       std::string *value, uoffset_t *ovalue);
  void SerializeStruct(const StructDef &struct_def, const Value &val);
  void SerializeStruct(FlatBufferBuilder &builder, const StructDef &struct_def,
                       const Value &val);
  template<typename F>
  FLATBUFFERS_CHECKED_ERROR ParseVectorDelimiters(uoffset_t &count, F body);
  FLATBUFFERS_CHECKED_ERROR ParseVector(const Type &type, uoffset_t *ovalue,
                                        FieldDef *field, size_t fieldn);
  FLATBUFFERS_CHECKED_ERROR ParseArray(Value &array);
  FLATBUFFERS_CHECKED_ERROR ParseNestedFlatbuffer(
      Value &val, FieldDef *field, size_t fieldn,
      const StructDef *parent_struct_def);
  FLATBUFFERS_CHECKED_ERROR ParseMetaData(SymbolTable<Value> *attributes);
  FLATBUFFERS_CHECKED_ERROR TryTypedValue(const std::string *name, int dtoken,
                                          bool check, Value &e, BaseType req,
                                          bool *destmatch);
  FLATBUFFERS_CHECKED_ERROR ParseHash(Value &e, FieldDef *field);
  FLATBUFFERS_CHECKED_ERROR TokenError();
  FLATBUFFERS_CHECKED_ERROR ParseSingleValue(const std::string *name, Value &e,
                                             bool check_now);
  FLATBUFFERS_CHECKED_ERROR ParseFunction(const std::string *name, Value &e);
  FLATBUFFERS_CHECKED_ERROR ParseEnumFromString(const Type &type,
                                                std::string *result);
  StructDef *LookupCreateStruct(const std::string &name,
                                bool create_if_new = true,
                                bool definition = false);
  FLATBUFFERS_CHECKED_ERROR ParseEnum(bool is_union, EnumDef **dest,
                                      const char *filename);
  FLATBUFFERS_CHECKED_ERROR ParseNamespace();
  FLATBUFFERS_CHECKED_ERROR StartStruct(const std::string &name,
                                        StructDef **dest);
  FLATBUFFERS_CHECKED_ERROR StartEnum(const std::string &name, bool is_union,
                                      EnumDef **dest);
  FLATBUFFERS_CHECKED_ERROR ParseDecl(const char *filename);
  FLATBUFFERS_CHECKED_ERROR ParseService(const char *filename);
  FLATBUFFERS_CHECKED_ERROR ParseProtoFields(StructDef *struct_def,
                                             bool isextend, bool inside_oneof);
  FLATBUFFERS_CHECKED_ERROR ParseProtoMapField(StructDef *struct_def);
  FLATBUFFERS_CHECKED_ERROR ParseProtoOption();
  FLATBUFFERS_CHECKED_ERROR ParseProtoKey();
  FLATBUFFERS_CHECKED_ERROR ParseProtoDecl();
  FLATBUFFERS_CHECKED_ERROR ParseProtoCurliesOrIdent();
  FLATBUFFERS_CHECKED_ERROR ParseTypeFromProtoType(Type *type);
  FLATBUFFERS_CHECKED_ERROR SkipAnyJsonValue();
  FLATBUFFERS_CHECKED_ERROR ParseFlexBufferNumericConstant(
      flexbuffers::Builder *builder);
  FLATBUFFERS_CHECKED_ERROR ParseFlexBufferValue(flexbuffers::Builder *builder);
  FLATBUFFERS_CHECKED_ERROR StartParseFile(const char *source,
                                           const char *source_filename);
  FLATBUFFERS_CHECKED_ERROR ParseRoot(const char *_source,
                                      const char **include_paths,
                                      const char *source_filename);
  FLATBUFFERS_CHECKED_ERROR CheckPrivateLeak();
  FLATBUFFERS_CHECKED_ERROR CheckPrivatelyLeakedFields(
      const Definition &def, const Definition &value_type);
  FLATBUFFERS_CHECKED_ERROR DoParse(const char *_source,
                                    const char **include_paths,
                                    const char *source_filename,
                                    const char *include_filename);
  FLATBUFFERS_CHECKED_ERROR DoParseJson();
  FLATBUFFERS_CHECKED_ERROR CheckClash(std::vector<FieldDef *> &fields,
                                       StructDef *struct_def,
                                       const char *suffix, BaseType baseType);
  FLATBUFFERS_CHECKED_ERROR ParseAlignAttribute(
      const std::string &align_constant, size_t min_align, size_t *align);

  bool SupportsAdvancedUnionFeatures() const;
  bool SupportsAdvancedArrayFeatures() const;
  bool SupportsOptionalScalars() const;
  bool SupportsDefaultVectorsAndStrings() const;
  Namespace *UniqueNamespace(Namespace *ns);

  FLATBUFFERS_CHECKED_ERROR RecurseError();
  template<typename F> CheckedError Recurse(F f);

  const std::string &GetPooledString(const std::string &s) const;

 public:
  SymbolTable<Type> types_;
  SymbolTable<StructDef> structs_;
  SymbolTable<EnumDef> enums_;
  SymbolTable<ServiceDef> services_;
  std::vector<Namespace *> namespaces_;
  Namespace *current_namespace_;
  Namespace *empty_namespace_;
  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_;

  std::map<uint64_t, std::string> included_files_;
  std::map<std::string, std::set<IncludedFile>> files_included_per_file_;
  std::vector<std::string> native_included_files_;

  std::map<std::string, bool> known_attributes_;

  IDLOptions opts;
  bool uses_flexbuffers_;
  bool has_warning_;

  uint64_t advanced_features_;

  std::string file_being_parsed_;

 private:
  const char *source_;

  std::vector<std::pair<Value, FieldDef *>> field_stack_;

  // TODO(cneo): Refactor parser to use string_cache more often to save
  // on memory usage.
  mutable std::set<std::string> string_cache_;

  int anonymous_counter_;
  int parse_depth_counter_;  // stack-overflow guard
};

// Utility functions for multiple generators:

// Generate text (JSON) from a given FlatBuffer, and a given Parser
// object that has been populated with the corresponding schema.
// If ident_step is 0, no indentation will be generated. Additionally,
// if it is less than 0, no linefeeds will be generated either.
// See idl_gen_text.cpp.
// strict_json adds "quotes" around field names if true.
// If the flatbuffer cannot be encoded in JSON (e.g., it contains non-UTF-8
// byte arrays in String values), returns false.
extern bool GenerateTextFromTable(const Parser &parser, const void *table,
                                  const std::string &tablename,
                                  std::string *text);
extern bool GenerateText(const Parser &parser, const void *flatbuffer,
                         std::string *text);
extern bool GenerateTextFile(const Parser &parser, const std::string &path,
                             const std::string &file_name);

// Generate Json schema to string
// See idl_gen_json_schema.cpp.
extern bool GenerateJsonSchema(const Parser &parser, std::string *json);

// Generate binary files from a given FlatBuffer, and a given Parser
// object that has been populated with the corresponding schema.
// See code_generators.cpp.
extern bool GenerateBinary(const Parser &parser, const std::string &path,
                           const std::string &file_name);

// Generate a C++ header from the definitions in the Parser object.
// See idl_gen_cpp.
extern bool GenerateCPP(const Parser &parser, const std::string &path,
                        const std::string &file_name);

// Generate C# files from the definitions in the Parser object.
// See idl_gen_csharp.cpp.
extern bool GenerateCSharp(const Parser &parser, const std::string &path,
                           const std::string &file_name);

extern bool GenerateDart(const Parser &parser, const std::string &path,
                         const std::string &file_name);

// Generate Java files from the definitions in the Parser object.
// See idl_gen_java.cpp.
extern bool GenerateJava(const Parser &parser, const std::string &path,
                         const std::string &file_name);

// Generate JavaScript or TypeScript code from the definitions in the Parser
// object. See idl_gen_js.
extern bool GenerateTS(const Parser &parser, const std::string &path,
                       const std::string &file_name);

// Generate Go files from the definitions in the Parser object.
// See idl_gen_go.cpp.
extern bool GenerateGo(const Parser &parser, const std::string &path,
                       const std::string &file_name);

// Generate Php code from the definitions in the Parser object.
// See idl_gen_php.
extern bool GeneratePhp(const Parser &parser, const std::string &path,
                        const std::string &file_name);

// Generate Python files from the definitions in the Parser object.
// See idl_gen_python.cpp.
extern bool GeneratePython(const Parser &parser, const std::string &path,
                           const std::string &file_name);

// Generate Lobster files from the definitions in the Parser object.
// See idl_gen_lobster.cpp.
extern bool GenerateLobster(const Parser &parser, const std::string &path,
                            const std::string &file_name);

// Generate Lua files from the definitions in the Parser object.
// See idl_gen_lua.cpp.
extern bool GenerateLua(const Parser &parser, const std::string &path,
                        const std::string &file_name);

// Generate Rust files from the definitions in the Parser object.
// See idl_gen_rust.cpp.
extern bool GenerateRust(const Parser &parser, const std::string &path,
                         const std::string &file_name);

// Generate Json schema file
// See idl_gen_json_schema.cpp.
extern bool GenerateJsonSchema(const Parser &parser, const std::string &path,
                               const std::string &file_name);

extern bool GenerateKotlin(const Parser &parser, const std::string &path,
                           const std::string &file_name);

// Generate Swift classes.
// See idl_gen_swift.cpp
extern bool GenerateSwift(const Parser &parser, const std::string &path,
                          const std::string &file_name);

// Generate a schema file from the internal representation, useful after
// parsing a .proto schema.
extern std::string GenerateFBS(const Parser &parser,
                               const std::string &file_name);
extern bool GenerateFBS(const Parser &parser, const std::string &path,
                        const std::string &file_name);

// Generate a make rule for the generated TypeScript code.
// See idl_gen_ts.cpp.
extern std::string TSMakeRule(const Parser &parser, const std::string &path,
                              const std::string &file_name);

// Generate a make rule for the generated C++ header.
// See idl_gen_cpp.cpp.
extern std::string CPPMakeRule(const Parser &parser, const std::string &path,
                               const std::string &file_name);

// Generate a make rule for the generated Dart code
// see idl_gen_dart.cpp
extern std::string DartMakeRule(const Parser &parser, const std::string &path,
                                const std::string &file_name);

// Generate a make rule for the generated Rust code.
// See idl_gen_rust.cpp.
extern std::string RustMakeRule(const Parser &parser, const std::string &path,
                                const std::string &file_name);

// Generate a make rule for generated Java or C# files.
// See code_generators.cpp.
extern std::string CSharpMakeRule(const Parser &parser, const std::string &path,
                                  const std::string &file_name);
extern std::string JavaMakeRule(const Parser &parser, const std::string &path,
                                const std::string &file_name);

// Generate a make rule for the generated text (JSON) files.
// See idl_gen_text.cpp.
extern std::string TextMakeRule(const Parser &parser, const std::string &path,
                                const std::string &file_names);

// Generate a make rule for the generated binary files.
// See code_generators.cpp.
extern std::string BinaryMakeRule(const Parser &parser, const std::string &path,
                                  const std::string &file_name);

// Generate GRPC Cpp interfaces.
// See idl_gen_grpc.cpp.
bool GenerateCppGRPC(const Parser &parser, const std::string &path,
                     const std::string &file_name);

// Generate GRPC Go interfaces.
// See idl_gen_grpc.cpp.
bool GenerateGoGRPC(const Parser &parser, const std::string &path,
                    const std::string &file_name);

// Generate GRPC Java classes.
// See idl_gen_grpc.cpp
bool GenerateJavaGRPC(const Parser &parser, const std::string &path,
                      const std::string &file_name);

// Generate GRPC Python interfaces.
// See idl_gen_grpc.cpp.
bool GeneratePythonGRPC(const Parser &parser, const std::string &path,
                        const std::string &file_name);

// Generate GRPC Swift interfaces.
// See idl_gen_grpc.cpp.
extern bool GenerateSwiftGRPC(const Parser &parser, const std::string &path,
                              const std::string &file_name);

extern bool GenerateTSGRPC(const Parser &parser, const std::string &path,
                           const std::string &file_name);

extern bool GenerateRustModuleRootFile(const Parser &parser,
                                       const std::string &path);
}  // namespace flatbuffers

#endif  // FLATBUFFERS_IDL_H_
