/*
 * Copyright 2015 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_REFLECTION_H_
#define FLATBUFFERS_REFLECTION_H_

// This is somewhat of a circular dependency because flatc (and thus this
// file) is needed to generate this header in the first place.
// Should normally not be a problem since it can be generated by the
// previous version of flatc whenever this code needs to change.
// See reflection/generate_code.sh
#include "flatbuffers/reflection_generated.h"

// Helper functionality for reflection.

namespace flatbuffers {

// ------------------------- GETTERS -------------------------

// Size of a basic type, don't use with structs.
inline size_t GetTypeSize(reflection::BaseType base_type) {
  // This needs to correspond to the BaseType enum.
  static size_t sizes[] = { 0, 1, 1, 1, 1, 2, 2, 4, 4, 8, 8, 4, 8, 4, 4, 4, 4 };
  return sizes[base_type];
}

// Same as above, but now correctly returns the size of a struct if
// the field (or vector element) is a struct.
inline size_t GetTypeSizeInline(reflection::BaseType base_type,
                                int type_index,
                                const reflection::Schema &schema) {
  if (base_type == reflection::Obj &&
      schema.objects()->Get(type_index)->is_struct()) {
    return schema.objects()->Get(type_index)->bytesize();
  } else {
    return GetTypeSize(base_type);
  }
}

// Get the root, regardless of what type it is.
inline Table *GetAnyRoot(uint8_t *flatbuf) {
  return GetMutableRoot<Table>(flatbuf);
}
inline const Table *GetAnyRoot(const uint8_t *flatbuf) {
  return GetRoot<Table>(flatbuf);
}

// Get a field, if you know it's an integer, and its exact type.
template<typename T> T GetFieldI(const Table &table,
                                 const reflection::Field &field) {
  assert(sizeof(T) == GetTypeSize(field.type()->base_type()));
  return table.GetField<T>(field.offset(),
                           static_cast<T>(field.default_integer()));
}

// Get a field, if you know it's floating point and its exact type.
template<typename T> T GetFieldF(const Table &table,
                                 const reflection::Field &field) {
  assert(sizeof(T) == GetTypeSize(field.type()->base_type()));
  return table.GetField<T>(field.offset(),
                           static_cast<T>(field.default_real()));
}

// Get a field, if you know it's a string.
inline const String *GetFieldS(const Table &table,
                               const reflection::Field &field) {
  assert(field.type()->base_type() == reflection::String);
  return table.GetPointer<const String *>(field.offset());
}

// Get a field, if you know it's a vector.
template<typename T> Vector<T> *GetFieldV(const Table &table,
                                          const reflection::Field &field) {
  assert(field.type()->base_type() == reflection::Vector &&
         sizeof(T) == GetTypeSize(field.type()->element()));
  return table.GetPointer<Vector<T> *>(field.offset());
}

// Get a field, if you know it's a vector, generically.
// To actually access elements, use the return value together with
// field.type()->element() in any of GetAnyVectorElemI below etc.
inline VectorOfAny *GetFieldAnyV(const Table &table,
                                 const reflection::Field &field) {
  return table.GetPointer<VectorOfAny *>(field.offset());
}

// Get a field, if you know it's a table.
inline Table *GetFieldT(const Table &table,
                        const reflection::Field &field) {
  assert(field.type()->base_type() == reflection::Obj ||
         field.type()->base_type() == reflection::Union);
  return table.GetPointer<Table *>(field.offset());
}

// Raw helper functions used below: get any value in memory as a 64bit int, a
// double or a string.
// All scalars get static_cast to an int64_t, strings use strtoull, every other
// data type returns 0.
int64_t GetAnyValueI(reflection::BaseType type, const uint8_t *data);
// All scalars static cast to double, strings use strtod, every other data
// type is 0.0.
double GetAnyValueF(reflection::BaseType type, const uint8_t *data);
// All scalars converted using stringstream, strings as-is, and all other
// data types provide some level of debug-pretty-printing.
std::string GetAnyValueS(reflection::BaseType type, const uint8_t *data,
                         const reflection::Schema *schema,
                         int type_index);

// Get any table field as a 64bit int, regardless of what type it is.
inline int64_t GetAnyFieldI(const Table &table,
                            const reflection::Field &field) {
  auto field_ptr = table.GetAddressOf(field.offset());
  return field_ptr ? GetAnyValueI(field.type()->base_type(), field_ptr)
                   : field.default_integer();
}

// Get any table field as a double, regardless of what type it is.
inline double GetAnyFieldF(const Table &table,
                           const reflection::Field &field) {
  auto field_ptr = table.GetAddressOf(field.offset());
  return field_ptr ? GetAnyValueF(field.type()->base_type(), field_ptr)
                   : field.default_real();
}


// Get any table field as a string, regardless of what type it is.
// You may pass nullptr for the schema if you don't care to have fields that
// are of table type pretty-printed.
inline std::string GetAnyFieldS(const Table &table,
                                const reflection::Field &field,
                                const reflection::Schema *schema) {
  auto field_ptr = table.GetAddressOf(field.offset());
  return field_ptr ? GetAnyValueS(field.type()->base_type(), field_ptr, schema,
                                  field.type()->index())
                   : "";
}

// Get any struct field as a 64bit int, regardless of what type it is.
inline int64_t GetAnyFieldI(const Struct &st,
                            const reflection::Field &field) {
  return GetAnyValueI(field.type()->base_type(),
                      st.GetAddressOf(field.offset()));
}

// Get any struct field as a double, regardless of what type it is.
inline double GetAnyFieldF(const Struct &st,
                           const reflection::Field &field) {
  return GetAnyValueF(field.type()->base_type(),
                      st.GetAddressOf(field.offset()));
}

// Get any struct field as a string, regardless of what type it is.
inline std::string GetAnyFieldS(const Struct &st,
                                const reflection::Field &field) {
  return GetAnyValueS(field.type()->base_type(),
                      st.GetAddressOf(field.offset()), nullptr, -1);
}

// Get any vector element as a 64bit int, regardless of what type it is.
inline int64_t GetAnyVectorElemI(const VectorOfAny *vec,
                                 reflection::BaseType elem_type, size_t i) {
  return GetAnyValueI(elem_type, vec->Data() + GetTypeSize(elem_type) * i);
}

// Get any vector element as a double, regardless of what type it is.
inline double GetAnyVectorElemF(const VectorOfAny *vec,
                                reflection::BaseType elem_type, size_t i) {
  return GetAnyValueF(elem_type, vec->Data() + GetTypeSize(elem_type) * i);
}

// Get any vector element as a string, regardless of what type it is.
inline std::string GetAnyVectorElemS(const VectorOfAny *vec,
                                     reflection::BaseType elem_type, size_t i) {
  return GetAnyValueS(elem_type, vec->Data() + GetTypeSize(elem_type) * i,
                      nullptr, -1);
}

// Get a vector element that's a table/string/vector from a generic vector.
// Pass Table/String/VectorOfAny as template parameter.
// Warning: does no typechecking.
template<typename T> T *GetAnyVectorElemPointer(const VectorOfAny *vec,
                                                size_t i) {
  auto elem_ptr = vec->Data() + sizeof(uoffset_t) * i;
  return (T *)(elem_ptr + ReadScalar<uoffset_t>(elem_ptr));
}

// Get the inline-address of a vector element. Useful for Structs (pass Struct
// as template arg), or being able to address a range of scalars in-line.
// Get elem_size from GetTypeSizeInline().
// Note: little-endian data on all platforms, use EndianScalar() instead of
// raw pointer access with scalars).
template<typename T> T *GetAnyVectorElemAddressOf(const VectorOfAny *vec,
                                                  size_t i,
                                                  size_t elem_size) {
  // C-cast to allow const conversion.
  return (T *)(vec->Data() + elem_size * i);
}

// Similarly, for elements of tables.
template<typename T> T *GetAnyFieldAddressOf(const Table &table,
                                             const reflection::Field &field) {
  return (T *)table.GetAddressOf(field.offset());
}

// Similarly, for elements of structs.
template<typename T> T *GetAnyFieldAddressOf(const Struct &st,
                                             const reflection::Field &field) {
  return (T *)st.GetAddressOf(field.offset());
}

// ------------------------- SETTERS -------------------------

// Set any scalar field, if you know its exact type.
template<typename T> bool SetField(Table *table, const reflection::Field &field,
                                   T val) {
  assert(sizeof(T) == GetTypeSize(field.type()->base_type()));
  return table->SetField(field.offset(), val);
}

// Raw helper functions used below: set any value in memory as a 64bit int, a
// double or a string.
// These work for all scalar values, but do nothing for other data types.
// To set a string, see SetString below.
void SetAnyValueI(reflection::BaseType type, uint8_t *data, int64_t val);
void SetAnyValueF(reflection::BaseType type, uint8_t *data, double val);
void SetAnyValueS(reflection::BaseType type, uint8_t *data, const char *val);

// Set any table field as a 64bit int, regardless of type what it is.
inline bool SetAnyFieldI(Table *table, const reflection::Field &field,
                         int64_t val) {
  auto field_ptr = table->GetAddressOf(field.offset());
  if (!field_ptr) return false;
  SetAnyValueI(field.type()->base_type(), field_ptr, val);
  return true;
}

// Set any table field as a double, regardless of what type it is.
inline bool SetAnyFieldF(Table *table, const reflection::Field &field,
                         double val) {
  auto field_ptr = table->GetAddressOf(field.offset());
  if (!field_ptr) return false;
  SetAnyValueF(field.type()->base_type(), field_ptr, val);
  return true;
}

// Set any table field as a string, regardless of what type it is.
inline bool SetAnyFieldS(Table *table, const reflection::Field &field,
                  const char *val) {
  auto field_ptr = table->GetAddressOf(field.offset());
  if (!field_ptr) return false;
  SetAnyValueS(field.type()->base_type(), field_ptr, val);
  return true;
}

// Set any struct field as a 64bit int, regardless of type what it is.
inline void SetAnyFieldI(Struct *st, const reflection::Field &field,
                         int64_t val) {
  SetAnyValueI(field.type()->base_type(), st->GetAddressOf(field.offset()),
               val);
}

// Set any struct field as a double, regardless of type what it is.
inline void SetAnyFieldF(Struct *st, const reflection::Field &field,
                         double val) {
  SetAnyValueF(field.type()->base_type(), st->GetAddressOf(field.offset()),
               val);
}

// Set any struct field as a string, regardless of type what it is.
inline void SetAnyFieldS(Struct *st, const reflection::Field &field,
                         const char *val) {
  SetAnyValueS(field.type()->base_type(), st->GetAddressOf(field.offset()),
               val);
}

// Set any vector element as a 64bit int, regardless of type what it is.
inline void SetAnyVectorElemI(VectorOfAny *vec, reflection::BaseType elem_type,
                              size_t i, int64_t val) {
  SetAnyValueI(elem_type, vec->Data() + GetTypeSize(elem_type) * i, val);
}

// Set any vector element as a double, regardless of type what it is.
inline void SetAnyVectorElemF(VectorOfAny *vec, reflection::BaseType elem_type,
                              size_t i, double val) {
  SetAnyValueF(elem_type, vec->Data() + GetTypeSize(elem_type) * i, val);
}

// Set any vector element as a string, regardless of type what it is.
inline void SetAnyVectorElemS(VectorOfAny *vec, reflection::BaseType elem_type,
                              size_t i, const char *val) {
  SetAnyValueS(elem_type, vec->Data() + GetTypeSize(elem_type) * i, val);
}


// ------------------------- RESIZING SETTERS -------------------------

// "smart" pointer for use with resizing vectors: turns a pointer inside
// a vector into a relative offset, such that it is not affected by resizes.
template<typename T, typename U> class pointer_inside_vector {
 public:
  pointer_inside_vector(T *ptr, std::vector<U> &vec)
    : offset_(reinterpret_cast<uint8_t *>(ptr) -
              reinterpret_cast<uint8_t *>(vec.data())),
      vec_(vec) {}

  T *operator*() const {
    return reinterpret_cast<T *>(
             reinterpret_cast<uint8_t *>(vec_.data()) + offset_);
  }
  T *operator->() const {
    return operator*();
  }
  void operator=(const pointer_inside_vector &piv);
 private:
  size_t offset_;
  std::vector<U> &vec_;
};

// Helper to create the above easily without specifying template args.
template<typename T, typename U> pointer_inside_vector<T, U> piv(T *ptr,
                                                          std::vector<U> &vec) {
  return pointer_inside_vector<T, U>(ptr, vec);
}

inline const char *UnionTypeFieldSuffix() { return "_type"; }

// Helper to figure out the actual table type a union refers to.
inline const reflection::Object &GetUnionType(
    const reflection::Schema &schema, const reflection::Object &parent,
    const reflection::Field &unionfield, const Table &table) {
  auto enumdef = schema.enums()->Get(unionfield.type()->index());
  // TODO: this is clumsy and slow, but no other way to find it?
  auto type_field = parent.fields()->LookupByKey(
            (unionfield.name()->str() + UnionTypeFieldSuffix()).c_str());
  assert(type_field);
  auto union_type = GetFieldI<uint8_t>(table, *type_field);
  auto enumval = enumdef->values()->LookupByKey(union_type);
  return *enumval->object();
}

// Changes the contents of a string inside a FlatBuffer. FlatBuffer must
// live inside a std::vector so we can resize the buffer if needed.
// "str" must live inside "flatbuf" and may be invalidated after this call.
// If your FlatBuffer's root table is not the schema's root table, you should
// pass in your root_table type as well.
void SetString(const reflection::Schema &schema, const std::string &val,
               const String *str, std::vector<uint8_t> *flatbuf,
               const reflection::Object *root_table = nullptr);

// Resizes a flatbuffers::Vector inside a FlatBuffer. FlatBuffer must
// live inside a std::vector so we can resize the buffer if needed.
// "vec" must live inside "flatbuf" and may be invalidated after this call.
// If your FlatBuffer's root table is not the schema's root table, you should
// pass in your root_table type as well.
uint8_t *ResizeAnyVector(const reflection::Schema &schema, uoffset_t newsize,
                         const VectorOfAny *vec, uoffset_t num_elems,
                         uoffset_t elem_size, std::vector<uint8_t> *flatbuf,
                         const reflection::Object *root_table = nullptr);

#ifndef FLATBUFFERS_CPP98_STL
template <typename T>
void ResizeVector(const reflection::Schema &schema, uoffset_t newsize, T val,
                  const Vector<T> *vec, std::vector<uint8_t> *flatbuf,
                  const reflection::Object *root_table = nullptr) {
  auto delta_elem = static_cast<int>(newsize) - static_cast<int>(vec->size());
  auto newelems = ResizeAnyVector(schema, newsize,
                                  reinterpret_cast<const VectorOfAny *>(vec),
                                  vec->size(),
                                  static_cast<uoffset_t>(sizeof(T)), flatbuf,
                                  root_table);
  // Set new elements to "val".
  for (int i = 0; i < delta_elem; i++) {
    auto loc = newelems + i * sizeof(T);
    auto is_scalar = std::is_scalar<T>::value;
    if (is_scalar) {
      WriteScalar(loc, val);
    } else {  // struct
      *reinterpret_cast<T *>(loc) = val;
    }
  }
}
#endif

// Adds any new data (in the form of a new FlatBuffer) to an existing
// FlatBuffer. This can be used when any of the above methods are not
// sufficient, in particular for adding new tables and new fields.
// This is potentially slightly less efficient than a FlatBuffer constructed
// in one piece, since the new FlatBuffer doesn't share any vtables with the
// existing one.
// The return value can now be set using Vector::MutateOffset or SetFieldT
// below.
const uint8_t *AddFlatBuffer(std::vector<uint8_t> &flatbuf,
                             const uint8_t *newbuf, size_t newlen);

inline bool SetFieldT(Table *table, const reflection::Field &field,
                      const uint8_t *val) {
  assert(sizeof(uoffset_t) == GetTypeSize(field.type()->base_type()));
  return table->SetPointer(field.offset(), val);
}

// ------------------------- COPYING -------------------------

// Generic copying of tables from a FlatBuffer into a FlatBuffer builder.
// Can be used to do any kind of merging/selecting you may want to do out
// of existing buffers. Also useful to reconstruct a whole buffer if the
// above resizing functionality has introduced garbage in a buffer you want
// to remove.
// Note: this does not deal with DAGs correctly. If the table passed forms a
// DAG, the copy will be a tree instead (with duplicates). Strings can be
// shared however, by passing true for use_string_pooling.

Offset<const Table *> CopyTable(FlatBufferBuilder &fbb,
                                const reflection::Schema &schema,
                                const reflection::Object &objectdef,
                                const Table &table,
                                bool use_string_pooling = false);

// Verifies the provided flatbuffer using reflection.
// root should point to the root type for this flatbuffer.
// buf should point to the start of flatbuffer data.
// length specifies the size of the flatbuffer data.
bool Verify(const reflection::Schema &schema,
            const reflection::Object &root,
            const uint8_t *buf,
            size_t length);

}  // namespace flatbuffers

#endif  // FLATBUFFERS_REFLECTION_H_
