aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/libs/flatbuffers/include
diff options
context:
space:
mode:
authormax42 <max42@yandex-team.com>2023-06-30 03:37:03 +0300
committermax42 <max42@yandex-team.com>2023-06-30 03:37:03 +0300
commitfac2bd72b4b31ec3238292caf8fb2a8aaa6d6c4a (patch)
treeb8cbc1deb00309c7f1a7ab6df520a76cf0b5c6d7 /contrib/libs/flatbuffers/include
parent7bf166b1a7ed0af927f230022b245af618e998c1 (diff)
downloadydb-fac2bd72b4b31ec3238292caf8fb2a8aaa6d6c4a.tar.gz
YT-19324: move YT provider to ydb/library/yql
This commit is formed by the following script: https://paste.yandex-team.ru/6f92e4b8-efc5-4d34-948b-15ee2accd7e7/text. This commit has zero effect on all projects that depend on YQL. The summary of changes: - `yql/providers/yt -> ydb/library/yql/providers/yt `- the whole implementation of YT provider is moved into YDB code base for further export as a part of YT YQL plugin shared library; - `yql/providers/stat/{expr_nodes,uploader} -> ydb/library/yql/providers/stat/{expr_nodes,uploader}` - a small interface without implementation and the description of stat expr nodes; - `yql/core/extract_predicate/ut -> ydb/library/yql/core/extract_predicate/ut`; - `yql/core/{ut,ut_common} -> ydb/library/yql/core/{ut,ut_common}`; - `yql/core` is gone; - `yql/library/url_preprocessing -> ydb/library/yql/core/url_preprocessing`. **NB**: all new targets inside `ydb/` are under `IF (NOT CMAKE_EXPORT)` clause which disables them from open-source cmake generation and ya make build. They will be enabled in the subsequent commits.
Diffstat (limited to 'contrib/libs/flatbuffers/include')
-rw-r--r--contrib/libs/flatbuffers/include/flatbuffers/code_generators.h235
-rw-r--r--contrib/libs/flatbuffers/include/flatbuffers/flatbuffers_iter.h640
-rw-r--r--contrib/libs/flatbuffers/include/flatbuffers/flatc.h100
-rw-r--r--contrib/libs/flatbuffers/include/flatbuffers/flexbuffers.h1636
-rw-r--r--contrib/libs/flatbuffers/include/flatbuffers/hash.h127
-rw-r--r--contrib/libs/flatbuffers/include/flatbuffers/idl.h1208
-rw-r--r--contrib/libs/flatbuffers/include/flatbuffers/reflection.h502
-rw-r--r--contrib/libs/flatbuffers/include/flatbuffers/reflection_generated.h1278
-rw-r--r--contrib/libs/flatbuffers/include/flatbuffers/util.h698
9 files changed, 6424 insertions, 0 deletions
diff --git a/contrib/libs/flatbuffers/include/flatbuffers/code_generators.h b/contrib/libs/flatbuffers/include/flatbuffers/code_generators.h
new file mode 100644
index 0000000000..09b773a468
--- /dev/null
+++ b/contrib/libs/flatbuffers/include/flatbuffers/code_generators.h
@@ -0,0 +1,235 @@
+/*
+ * 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_CODE_GENERATORS_H_
+#define FLATBUFFERS_CODE_GENERATORS_H_
+
+#include <map>
+#include <sstream>
+
+#include "idl.h"
+
+namespace flatbuffers {
+
+// Utility class to assist in generating code through use of text templates.
+//
+// Example code:
+// CodeWriter code("\t");
+// code.SetValue("NAME", "Foo");
+// code += "void {{NAME}}() { printf("%s", "{{NAME}}"); }";
+// code.SetValue("NAME", "Bar");
+// code += "void {{NAME}}() { printf("%s", "{{NAME}}"); }";
+// std::cout << code.ToString() << std::endl;
+//
+// Output:
+// void Foo() { printf("%s", "Foo"); }
+// void Bar() { printf("%s", "Bar"); }
+class CodeWriter {
+ public:
+ CodeWriter(std::string pad = std::string())
+ : pad_(pad), cur_ident_lvl_(0), ignore_ident_(false) {}
+
+ // Clears the current "written" code.
+ void Clear() {
+ stream_.str("");
+ stream_.clear();
+ }
+
+ // Associates a key with a value. All subsequent calls to operator+=, where
+ // the specified key is contained in {{ and }} delimiters will be replaced by
+ // the given value.
+ void SetValue(const std::string &key, const std::string &value) {
+ value_map_[key] = value;
+ }
+
+ std::string GetValue(const std::string &key) const {
+ const auto it = value_map_.find(key);
+ return it == value_map_.end() ? "" : it->second;
+ }
+
+ // Appends the given text to the generated code as well as a newline
+ // character. Any text within {{ and }} delimiters is replaced by values
+ // previously stored in the CodeWriter by calling SetValue above. The newline
+ // will be suppressed if the text ends with the \\ character.
+ void operator+=(std::string text);
+
+ // Returns the current contents of the CodeWriter as a std::string.
+ std::string ToString() const { return stream_.str(); }
+
+ // Increase ident level for writing code
+ void IncrementIdentLevel() { cur_ident_lvl_++; }
+ // Decrease ident level for writing code
+ void DecrementIdentLevel() {
+ if (cur_ident_lvl_) cur_ident_lvl_--;
+ }
+
+ void SetPadding(const std::string &padding) { pad_ = padding; }
+
+ private:
+ std::map<std::string, std::string> value_map_;
+ std::stringstream stream_;
+ std::string pad_;
+ int cur_ident_lvl_;
+ bool ignore_ident_;
+
+ // Add ident padding (tab or space) based on ident level
+ void AppendIdent(std::stringstream &stream);
+};
+
+class BaseGenerator {
+ public:
+ virtual bool generate() = 0;
+
+ static std::string NamespaceDir(const Parser &parser, const std::string &path,
+ const Namespace &ns,
+ const bool dasherize = false);
+
+ static std::string ToDasherizedCase(const std::string pascal_case);
+
+ std::string GeneratedFileName(const std::string &path,
+ const std::string &file_name,
+ const IDLOptions &options) const;
+
+ protected:
+ BaseGenerator(const Parser &parser, const std::string &path,
+ const std::string &file_name, std::string qualifying_start,
+ std::string qualifying_separator, std::string default_extension)
+ : parser_(parser),
+ path_(path),
+ file_name_(file_name),
+ qualifying_start_(qualifying_start),
+ qualifying_separator_(qualifying_separator),
+ default_extension_(default_extension) {}
+ virtual ~BaseGenerator() {}
+
+ // No copy/assign.
+ BaseGenerator &operator=(const BaseGenerator &);
+ BaseGenerator(const BaseGenerator &);
+
+ std::string NamespaceDir(const Namespace &ns,
+ const bool dasherize = false) const;
+
+ static const char *FlatBuffersGeneratedWarning();
+
+ static std::string FullNamespace(const char *separator, const Namespace &ns);
+
+ static std::string LastNamespacePart(const Namespace &ns);
+
+ // tracks the current namespace for early exit in WrapInNameSpace
+ // c++, java and csharp returns a different namespace from
+ // the following default (no early exit, always fully qualify),
+ // which works for js and php
+ virtual const Namespace *CurrentNameSpace() const { return nullptr; }
+
+ // Ensure that a type is prefixed with its namespace even within
+ // its own namespace to avoid conflict between generated method
+ // names and similarly named classes or structs
+ std::string WrapInNameSpace(const Namespace *ns,
+ const std::string &name) const;
+
+ std::string WrapInNameSpace(const Definition &def) const;
+
+ std::string GetNameSpace(const Definition &def) const;
+
+ const Parser &parser_;
+ const std::string &path_;
+ const std::string &file_name_;
+ const std::string qualifying_start_;
+ const std::string qualifying_separator_;
+ const std::string default_extension_;
+};
+
+struct CommentConfig {
+ const char *first_line;
+ const char *content_line_prefix;
+ const char *last_line;
+};
+
+extern void GenComment(const std::vector<std::string> &dc,
+ std::string *code_ptr, const CommentConfig *config,
+ const char *prefix = "");
+
+class FloatConstantGenerator {
+ public:
+ virtual ~FloatConstantGenerator() {}
+ std::string GenFloatConstant(const FieldDef &field) const;
+
+ private:
+ virtual std::string Value(double v, const std::string &src) const = 0;
+ virtual std::string Inf(double v) const = 0;
+ virtual std::string NaN(double v) const = 0;
+
+ virtual std::string Value(float v, const std::string &src) const = 0;
+ virtual std::string Inf(float v) const = 0;
+ virtual std::string NaN(float v) const = 0;
+
+ template<typename T>
+ std::string GenFloatConstantImpl(const FieldDef &field) const;
+};
+
+class SimpleFloatConstantGenerator : public FloatConstantGenerator {
+ public:
+ SimpleFloatConstantGenerator(const char *nan_number,
+ const char *pos_inf_number,
+ const char *neg_inf_number);
+
+ private:
+ std::string Value(double v,
+ const std::string &src) const FLATBUFFERS_OVERRIDE;
+ std::string Inf(double v) const FLATBUFFERS_OVERRIDE;
+ std::string NaN(double v) const FLATBUFFERS_OVERRIDE;
+
+ std::string Value(float v, const std::string &src) const FLATBUFFERS_OVERRIDE;
+ std::string Inf(float v) const FLATBUFFERS_OVERRIDE;
+ std::string NaN(float v) const FLATBUFFERS_OVERRIDE;
+
+ const std::string nan_number_;
+ const std::string pos_inf_number_;
+ const std::string neg_inf_number_;
+};
+
+// C++, C#, Java like generator.
+class TypedFloatConstantGenerator : public FloatConstantGenerator {
+ public:
+ TypedFloatConstantGenerator(const char *double_prefix,
+ const char *single_prefix, const char *nan_number,
+ const char *pos_inf_number,
+ const char *neg_inf_number = "");
+
+ private:
+ std::string Value(double v,
+ const std::string &src) const FLATBUFFERS_OVERRIDE;
+ std::string Inf(double v) const FLATBUFFERS_OVERRIDE;
+
+ std::string NaN(double v) const FLATBUFFERS_OVERRIDE;
+
+ std::string Value(float v, const std::string &src) const FLATBUFFERS_OVERRIDE;
+ std::string Inf(float v) const FLATBUFFERS_OVERRIDE;
+ std::string NaN(float v) const FLATBUFFERS_OVERRIDE;
+
+ std::string MakeNaN(const std::string &prefix) const;
+ std::string MakeInf(bool neg, const std::string &prefix) const;
+
+ const std::string double_prefix_;
+ const std::string single_prefix_;
+ const std::string nan_number_;
+ const std::string pos_inf_number_;
+ const std::string neg_inf_number_;
+};
+
+} // namespace flatbuffers
+
+#endif // FLATBUFFERS_CODE_GENERATORS_H_
diff --git a/contrib/libs/flatbuffers/include/flatbuffers/flatbuffers_iter.h b/contrib/libs/flatbuffers/include/flatbuffers/flatbuffers_iter.h
new file mode 100644
index 0000000000..a770983dca
--- /dev/null
+++ b/contrib/libs/flatbuffers/include/flatbuffers/flatbuffers_iter.h
@@ -0,0 +1,640 @@
+/*
+ * 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_ITER_H_
+#define FLATBUFFERS_ITER_H_
+
+#include "flatbuffers.h"
+#include <optional>
+
+/// @file
+namespace yandex {
+namespace maps {
+namespace flatbuffers_iter {
+
+#define FLATBUFFERS_FILE_IDENTIFIER_LENGTH 4
+
+using flatbuffers::uoffset_t;
+using flatbuffers::soffset_t;
+using flatbuffers::voffset_t;
+using flatbuffers::EndianScalar;
+
+// Wrapper for uoffset_t to allow safe template specialization.
+template<typename T> struct Offset {
+ uoffset_t o;
+ Offset() : o(0) {}
+ Offset(uoffset_t _o) : o(_o) {}
+ Offset<void> Union() const { return Offset<void>(o); }
+};
+
+template<typename Iter>
+inline bool hasContiguous(const Iter& spot, uoffset_t length)
+{
+ return spot.hasContiguous(length);
+}
+
+inline bool hasContiguous(const uint8_t* /* spot */, uoffset_t /* length */)
+{
+ return true;
+}
+
+template <typename Iter>
+inline const uint8_t* getRawPointer(const Iter& spot)
+{
+ return spot.rawPointer();
+}
+
+inline const uint8_t* getRawPointer(const uint8_t* spot)
+{
+ return spot;
+}
+
+template<typename T, typename Iter>
+typename std::enable_if<sizeof(T) == 1, T>::type extractValue(const Iter& spot)
+{
+ typename std::remove_cv<T>::type ret;
+ std::memcpy(&ret, getRawPointer(spot), 1);
+ return ret;
+}
+
+template<typename T, typename Iter>
+typename std::enable_if<sizeof(T) != 1, T>::type extractValue(const Iter& spot)
+{
+ if (hasContiguous(spot, sizeof(T))) {
+ typename std::remove_cv<T>::type ret;
+ std::memcpy(&ret, getRawPointer(spot), sizeof(T));
+ return ret;
+ }
+ Iter itr = spot;
+ alignas(T) uint8_t buf[sizeof(T)];
+ for (std::size_t i = 0; i < sizeof(T); ++i) {
+ buf[i] = *itr;
+ ++itr;
+ }
+ return *reinterpret_cast<T*>(buf);
+}
+
+template<typename T, typename Iter> T ReadScalar(Iter p) {
+ return EndianScalar(extractValue<T>(p));
+}
+
+// When we read serialized data from memory, in the case of most scalars,
+// we want to just read T, but in the case of Offset, we want to actually
+// perform the indirection and return a pointer.
+// The template specialization below does just that.
+// It is wrapped in a struct since function templates can't overload on the
+// return type like this.
+// The typedef is for the convenience of callers of this function
+// (avoiding the need for a trailing return decltype)
+template<typename T> struct IndirectHelper {
+ typedef T return_type;
+ typedef T mutable_return_type;
+ static const size_t element_stride = sizeof(T);
+ template<typename Iter>
+ static return_type Read(const Iter& p, uoffset_t i) {
+ return i ? EndianScalar(extractValue<return_type>(p+sizeof(return_type)*i)) : EndianScalar(extractValue<return_type>(p));
+ }
+};
+template<typename T> struct IndirectHelper<Offset<T>> {
+ typedef std::optional<T> return_type;
+ typedef std::optional<T> mutable_return_type;
+ static const size_t element_stride = sizeof(uoffset_t);
+ template<typename Iter>
+ static return_type Read(Iter p, uoffset_t i) {
+ p += i * sizeof(uoffset_t);
+ return return_type(T(p + ReadScalar<uoffset_t>(p)));
+ }
+};
+template<typename T> struct IndirectHelper<const T *> {
+};
+
+
+// An STL compatible iterator implementation for Vector below, effectively
+// calling Get() for every element.
+template<typename T, typename IT, typename Iter>
+struct VectorIterator
+ : public std::iterator<std::random_access_iterator_tag, IT, uoffset_t> {
+
+ typedef std::iterator<std::random_access_iterator_tag, IT, uoffset_t> super_type;
+
+public:
+ VectorIterator(const Iter& data, uoffset_t i) :
+ data_(data + IndirectHelper<T>::element_stride * i) {}
+ VectorIterator(const VectorIterator &other) : data_(other.data_) {}
+ #ifndef FLATBUFFERS_CPP98_STL
+ VectorIterator(VectorIterator &&other) : data_(std::move(other.data_)) {}
+ #endif
+
+ VectorIterator &operator=(const VectorIterator &other) {
+ data_ = other.data_;
+ return *this;
+ }
+
+ VectorIterator &operator=(VectorIterator &&other) {
+ data_ = other.data_;
+ return *this;
+ }
+
+ bool operator==(const VectorIterator &other) const {
+ return data_ == other.data_;
+ }
+
+ bool operator!=(const VectorIterator &other) const {
+ return data_ != other.data_;
+ }
+
+ ptrdiff_t operator-(const VectorIterator &other) const {
+ return (data_ - other.data_) / IndirectHelper<T>::element_stride;
+ }
+
+ typename super_type::value_type operator *() const {
+ return IndirectHelper<T>::Read(data_, 0);
+ }
+
+ typename super_type::value_type operator->() const {
+ return IndirectHelper<T>::Read(data_, 0);
+ }
+
+ VectorIterator &operator++() {
+ data_ += IndirectHelper<T>::element_stride;
+ return *this;
+ }
+
+ VectorIterator operator++(int) {
+ VectorIterator temp(data_, 0);
+ data_ += IndirectHelper<T>::element_stride;
+ return temp;
+ }
+
+ VectorIterator operator+(const uoffset_t &offset) {
+ return VectorIterator(data_ + offset * IndirectHelper<T>::element_stride, 0);
+ }
+
+ VectorIterator& operator+=(const uoffset_t &offset) {
+ data_ += offset * IndirectHelper<T>::element_stride;
+ return *this;
+ }
+
+ VectorIterator &operator--() {
+ data_ -= IndirectHelper<T>::element_stride;
+ return *this;
+ }
+
+ VectorIterator operator--(int) {
+ VectorIterator temp(data_, 0);
+ data_ -= IndirectHelper<T>::element_stride;
+ return temp;
+ }
+
+ VectorIterator operator-(const uoffset_t &offset) {
+ return VectorIterator(data_ - offset * IndirectHelper<T>::element_stride, 0);
+ }
+
+ VectorIterator& operator-=(const uoffset_t &offset) {
+ data_ -= offset * IndirectHelper<T>::element_stride;
+ return *this;
+ }
+
+private:
+ Iter data_;
+};
+
+// This is used as a helper type for accessing vectors.
+// Vector::data() assumes the vector elements start after the length field.
+template<typename T, typename Iter> class Vector {
+public:
+ typedef VectorIterator<T, typename IndirectHelper<T>::mutable_return_type, Iter>
+ iterator;
+ typedef VectorIterator<T, typename IndirectHelper<T>::return_type, Iter>
+ const_iterator;
+
+ Vector(Iter data):
+ data_(data)
+ {}
+
+ uoffset_t size() const { return EndianScalar(extractValue<uoffset_t>(data_)); }
+
+ // Deprecated: use size(). Here for backwards compatibility.
+ uoffset_t Length() const { return size(); }
+
+ typedef typename IndirectHelper<T>::return_type return_type;
+ typedef typename IndirectHelper<T>::mutable_return_type mutable_return_type;
+
+ return_type Get(uoffset_t i) const {
+ assert(i < size());
+ return IndirectHelper<T>::Read(Data(), i);
+ }
+
+ return_type operator[](uoffset_t i) const { return Get(i); }
+
+ // If this is a Vector of enums, T will be its storage type, not the enum
+ // type. This function makes it convenient to retrieve value with enum
+ // type E.
+ template<typename E> E GetEnum(uoffset_t i) const {
+ return static_cast<E>(Get(i));
+ }
+
+ const Iter GetStructFromOffset(size_t o) const {
+ return Data() + o;
+ }
+
+ iterator begin() { return iterator(Data(), 0); }
+ const_iterator begin() const { return const_iterator(Data(), 0); }
+
+ iterator end() { return iterator(Data(), size()); }
+ const_iterator end() const { return const_iterator(Data(), size()); }
+
+ // The raw data in little endian format. Use with care.
+ const Iter Data() const {
+ return data_ + sizeof(uoffset_t);
+ }
+
+ Iter Data() {
+ return data_ + sizeof(uoffset_t);
+ }
+
+ template<typename K> return_type LookupByKey(K key) const {
+ auto search_result = std::lower_bound(begin(), end(), key, KeyCompare<K>);
+
+ if (search_result == end() || (*search_result)->KeyCompareWithValue(key) != 0) {
+ return std::nullopt; // Key not found.
+ }
+
+ return *search_result;
+ }
+
+ operator Iter() const
+ {
+ return data_;
+ }
+
+protected:
+ Iter data_;
+
+private:
+ template<typename K> static int KeyCompare(const return_type& ap, const K& bp) {
+ return ap->KeyCompareWithValue(bp) < 0;
+ }
+};
+
+// Represent a vector much like the template above, but in this case we
+// don't know what the element types are (used with reflection.h).
+template <typename Iter>
+class VectorOfAny {
+public:
+ VectorOfAny(Iter data):
+ data_(data)
+ {}
+
+ uoffset_t size() const { return EndianScalar(extractValue<uoffset_t>(data_)); }
+
+ const Iter Data() const {
+ return data_;
+ }
+ Iter Data() {
+ return data_;
+ }
+protected:
+
+ Iter data_;
+};
+
+// Convenient helper function to get the length of any vector, regardless
+// of wether it is null or not (the field is not set).
+template<typename T, typename Iter> static inline size_t VectorLength(const std::optional<Vector<T, Iter>> &v) {
+ return v ? v->Length() : 0;
+}
+
+template <typename Iter> struct String : public Vector<char, Iter> {
+ using Vector<char,Iter>::Vector;
+ using Vector<char,Iter>::data_;
+
+ std::string str() const {
+ if (hasContiguous(data_, sizeof(uoffset_t) + this->Length()))
+ return std::string(reinterpret_cast<const char*>(getRawPointer(data_)) + sizeof(uoffset_t), this->Length());
+ return std::string(this->begin(), this->begin() + this->Length()); }
+
+ bool operator <(const String &o) const {
+ return str() < o.str();
+ }
+};
+
+// Converts a Field ID to a virtual table offset.
+inline voffset_t FieldIndexToOffset(voffset_t field_id) {
+ // Should correspond to what EndTable() below builds up.
+ const int fixed_fields = 2; // Vtable size and Object Size.
+ return static_cast<voffset_t>((field_id + fixed_fields) * sizeof(voffset_t));
+}
+
+/// @endcond
+
+/// @cond FLATBUFFERS_INTERNAL
+template<typename T, typename Iter> std::optional<T> GetMutableRoot(Iter begin) {
+ flatbuffers::EndianCheck();
+ return T(begin + EndianScalar(extractValue<uoffset_t>(begin)));
+}
+
+template<typename T, typename Iter> std::optional<T> GetRoot(Iter begin) {
+ return GetMutableRoot<T, Iter>(begin);
+}
+
+template<typename T, typename Iter> std::optional<T> GetSizePrefixedRoot(Iter buf) {
+ return GetRoot<T, Iter>(buf + sizeof(uoffset_t));
+}
+
+// Helper to see if the identifier in a buffer has the expected value.
+
+template <typename Iter> inline bool BufferHasIdentifier(const Iter& buf, const char *identifier) {
+ return std::equal(
+ identifier,
+ identifier + std::min(std::strlen(identifier) + 1, static_cast<std::size_t>(FLATBUFFERS_FILE_IDENTIFIER_LENGTH)),
+ buf + sizeof(uoffset_t));
+}
+
+// Helper class to verify the integrity of a FlatBuffer
+template <typename Iter>
+class Verifier FLATBUFFERS_FINAL_CLASS {
+ public:
+ Verifier(const Iter& buf, size_t buf_len, size_t _max_depth = 64,
+ size_t _max_tables = 1000000)
+ : buf_(buf), end_(buf + buf_len), depth_(0), max_depth_(_max_depth),
+ num_tables_(0), max_tables_(_max_tables)
+ #ifdef FLATBUFFERS_TRACK_VERIFIER_BUFFER_SIZE
+ , upper_bound_(buf)
+ #endif
+ {}
+
+ // Central location where any verification failures register.
+ bool Check(bool ok) const {
+ #ifdef FLATBUFFERS_DEBUG_VERIFICATION_FAILURE
+ assert(ok);
+ #endif
+ #ifdef FLATBUFFERS_TRACK_VERIFIER_BUFFER_SIZE
+ if (!ok)
+ upper_bound_ = buf_;
+ #endif
+ return ok;
+ }
+
+ // Verify any range within the buffer.
+ bool Verify(const Iter& elem, size_t elem_len) const {
+ #ifdef FLATBUFFERS_TRACK_VERIFIER_BUFFER_SIZE
+ auto upper_bound = elem + elem_len;
+ if (upper_bound_ < upper_bound)
+ upper_bound_ = upper_bound;
+ #endif
+ return Check(elem_len <= (size_t) (end_ - buf_) &&
+ elem >= buf_ &&
+ elem <= end_ - elem_len);
+ }
+
+ // Verify a range indicated by sizeof(T).
+ template<typename T> bool Verify(const Iter& elem) const {
+ return Verify(elem, sizeof(T));
+ }
+
+ template<typename T> bool VerifyTable(const std::optional<T>& table) {
+ return !table || table->Verify(*this);
+ }
+
+ template<typename T> bool Verify(const std::optional<Vector<T, Iter>>& vec) const {
+ Iter end;
+ return !vec ||
+ VerifyVector(static_cast<Iter>(*vec), sizeof(T),
+ &end);
+ }
+
+ template<typename T> bool Verify(const std::optional<Vector<const T, Iter>>& vec) const {
+ return Verify(*reinterpret_cast<const std::optional<Vector<T, Iter>> *>(&vec));
+ }
+
+ bool Verify(const std::optional<String<Iter>>& str) const {
+ Iter end;
+ return !str ||
+ (VerifyVector(static_cast<Iter>(*str), 1, &end) &&
+ Verify(end, 1) && // Must have terminator
+ Check(*end == '\0')); // Terminating byte must be 0.
+ }
+
+ // Common code between vectors and strings.
+ bool VerifyVector(const Iter& vec, size_t elem_size,
+ Iter *end) const {
+ // Check we can read the size field.
+ if (!Verify<uoffset_t>(vec)) return false;
+ // Check the whole array. If this is a string, the byte past the array
+ // must be 0.
+ auto size = ReadScalar<uoffset_t>(vec);
+ auto max_elems = FLATBUFFERS_MAX_BUFFER_SIZE / elem_size;
+ if (!Check(size < max_elems))
+ return false; // Protect against byte_size overflowing.
+ auto byte_size = sizeof(size) + elem_size * size;
+ *end = vec + byte_size;
+ return Verify(vec, byte_size);
+ }
+
+ // Special case for string contents, after the above has been called.
+ bool VerifyVectorOfStrings(const std::optional<Vector<Offset<String<Iter>>, Iter>>& vec) const {
+ if (vec) {
+ for (uoffset_t i = 0; i < vec->size(); i++) {
+ if (!Verify(vec->Get(i))) return false;
+ }
+ }
+ return true;
+ }
+
+ // Special case for table contents, after the above has been called.
+ template<typename T> bool VerifyVectorOfTables(const std::optional<Vector<Offset<T>, Iter>>& vec) {
+ if (vec) {
+ for (uoffset_t i = 0; i < vec->size(); i++) {
+ if (!vec->Get(i)->Verify(*this)) return false;
+ }
+ }
+ return true;
+ }
+
+ template<typename T> bool VerifyBufferFromStart(const char *identifier,
+ const Iter& start) {
+ if (identifier &&
+ (static_cast<std::size_t>(end_ - start) < 2 * sizeof(flatbuffers_iter::uoffset_t) ||
+ !BufferHasIdentifier(start, identifier))) {
+ return false;
+ }
+
+ // Call T::Verify, which must be in the generated code for this type.
+ return Verify<uoffset_t>(start) &&
+ T(start + ReadScalar<uoffset_t>(start)).
+ Verify(*this)
+ #ifdef FLATBUFFERS_TRACK_VERIFIER_BUFFER_SIZE
+ && GetComputedSize()
+ #endif
+ ;
+ }
+
+ // Verify this whole buffer, starting with root type T.
+ template<typename T> bool VerifyBuffer(const char *identifier) {
+ return VerifyBufferFromStart<T>(identifier, buf_);
+ }
+
+ template<typename T> bool VerifySizePrefixedBuffer(const char *identifier) {
+ return Verify<uoffset_t>(buf_) &&
+ ReadScalar<uoffset_t>(buf_) == end_ - buf_ - sizeof(uoffset_t) &&
+ VerifyBufferFromStart<T>(identifier, buf_ + sizeof(uoffset_t));
+ }
+
+ // Called at the start of a table to increase counters measuring data
+ // structure depth and amount, and possibly bails out with false if
+ // limits set by the constructor have been hit. Needs to be balanced
+ // with EndTable().
+ bool VerifyComplexity() {
+ depth_++;
+ num_tables_++;
+ return Check(depth_ <= max_depth_ && num_tables_ <= max_tables_);
+ }
+
+ // Called at the end of a table to pop the depth count.
+ bool EndTable() {
+ depth_--;
+ return true;
+ }
+
+ #ifdef FLATBUFFERS_TRACK_VERIFIER_BUFFER_SIZE
+ // Returns the message size in bytes
+ size_t GetComputedSize() const {
+ uintptr_t size = upper_bound_ - buf_;
+ // Align the size to uoffset_t
+ size = (size - 1 + sizeof(uoffset_t)) & ~(sizeof(uoffset_t) - 1);
+ return (buf_ + size > end_) ? 0 : size;
+ }
+ #endif
+
+ private:
+ const Iter buf_;
+ const Iter end_;
+ size_t depth_;
+ size_t max_depth_;
+ size_t num_tables_;
+ size_t max_tables_;
+#ifdef FLATBUFFERS_TRACK_VERIFIER_BUFFER_SIZE
+ mutable const Iter upper_bound_;
+#endif
+};
+
+// "structs" are flat structures that do not have an offset table, thus
+// always have all members present and do not support forwards/backwards
+// compatible extensions.
+template <typename Iter>
+class Struct FLATBUFFERS_FINAL_CLASS {
+ public:
+ template<typename T> T GetField(uoffset_t o) const {
+ return ReadScalar<T>(data_ + o);
+ }
+
+ template<typename T> T GetStruct(uoffset_t o) const {
+ return T(data_ + o);
+ }
+
+ private:
+ Iter data_;
+};
+
+// "tables" use an offset table (possibly shared) that allows fields to be
+// omitted and added at will, but uses an extra indirection to read.
+template<typename Iter>
+class Table {
+ public:
+ Table(Iter data): data_(data) {}
+
+ const Iter GetVTable() const {
+ return data_ - ReadScalar<soffset_t>(data_);
+ }
+
+ // This gets the field offset for any of the functions below it, or 0
+ // if the field was not present.
+ voffset_t GetOptionalFieldOffset(voffset_t field) const {
+ // The vtable offset is always at the start.
+ auto vtable = GetVTable();
+ // The first element is the size of the vtable (fields + type id + itself).
+ auto vtsize = ReadScalar<voffset_t>(vtable);
+ // If the field we're accessing is outside the vtable, we're reading older
+ // data, so it's the same as if the offset was 0 (not present).
+ return field < vtsize ? ReadScalar<voffset_t>(vtable + field) : 0;
+ }
+
+ template<typename T> T GetField(voffset_t field, T defaultval) const {
+ auto field_offset = GetOptionalFieldOffset(field);
+ return field_offset ? ReadScalar<T>(data_ + field_offset) : defaultval;
+ }
+
+ template<typename P> std::optional<P> GetPointer(voffset_t field) {
+ auto field_offset = GetOptionalFieldOffset(field);
+ auto p = data_ + field_offset;
+ return field_offset ? std::optional<P>(P(p + ReadScalar<uoffset_t>(p))) : std::nullopt;
+ }
+
+ template<typename P> std::optional<P> GetPointer(voffset_t field) const {
+ return const_cast<Table *>(this)->template GetPointer<P>(field);
+ }
+
+ template<typename P> P GetStruct(voffset_t field) const {
+ auto field_offset = GetOptionalFieldOffset(field);
+ auto p = data_ + field_offset;
+ return extractValue<P>(p);
+ }
+
+ bool CheckField(voffset_t field) const {
+ return GetOptionalFieldOffset(field) != 0;
+ }
+
+ // Verify the vtable of this table.
+ // Call this once per table, followed by VerifyField once per field.
+ bool VerifyTableStart(Verifier<Iter> &verifier) const {
+ // Check the vtable offset.
+ if (!verifier.template Verify<soffset_t>(data_)) return false;
+ auto vtable = GetVTable();
+ // Check the vtable size field, then check vtable fits in its entirety.
+ return verifier.VerifyComplexity() &&
+ verifier.template Verify<voffset_t>(vtable) &&
+ (ReadScalar<voffset_t>(vtable) & (sizeof(voffset_t) - 1)) == 0 &&
+ verifier.Verify(vtable, ReadScalar<voffset_t>(vtable));
+ }
+
+ // Verify a particular field.
+ template<typename T> bool VerifyField(const Verifier<Iter> &verifier,
+ voffset_t field) const {
+ // Calling GetOptionalFieldOffset should be safe now thanks to
+ // VerifyTable().
+ auto field_offset = GetOptionalFieldOffset(field);
+ // Check the actual field.
+ return !field_offset || verifier.template Verify<T>(data_ + field_offset);
+ }
+
+ // VerifyField for required fields.
+ template<typename T> bool VerifyFieldRequired(const Verifier<Iter> &verifier,
+ voffset_t field) const {
+ auto field_offset = GetOptionalFieldOffset(field);
+ return verifier.Check(field_offset != 0) &&
+ verifier.template Verify<T>(data_ + field_offset);
+ }
+
+ private:
+ Iter data_;
+};
+/// @endcond
+} // namespace flatbuffers_iter
+} // namespace maps
+} // namespace yandex
+
+#endif // FLATBUFFERS_H_
diff --git a/contrib/libs/flatbuffers/include/flatbuffers/flatc.h b/contrib/libs/flatbuffers/include/flatbuffers/flatc.h
new file mode 100644
index 0000000000..1466b3651d
--- /dev/null
+++ b/contrib/libs/flatbuffers/include/flatbuffers/flatc.h
@@ -0,0 +1,100 @@
+/*
+ * Copyright 2017 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_FLATC_H_
+#define FLATBUFFERS_FLATC_H_
+
+#include <functional>
+#include <limits>
+#include <string>
+
+#include "flatbuffers.h"
+#include "idl.h"
+#include "util.h"
+
+namespace flatbuffers {
+
+extern void LogCompilerWarn(const std::string &warn);
+extern void LogCompilerError(const std::string &err);
+
+class FlatCompiler {
+ public:
+ // Output generator for the various programming languages and formats we
+ // support.
+ struct Generator {
+ typedef bool (*GenerateFn)(const flatbuffers::Parser &parser,
+ const std::string &path,
+ const std::string &file_name);
+ typedef std::string (*MakeRuleFn)(const flatbuffers::Parser &parser,
+ const std::string &path,
+ const std::string &file_name);
+
+ GenerateFn generate;
+ const char *generator_opt_short;
+ const char *generator_opt_long;
+ const char *lang_name;
+ bool schema_only;
+ GenerateFn generateGRPC;
+ flatbuffers::IDLOptions::Language lang;
+ const char *generator_help;
+ MakeRuleFn make_rule;
+ };
+
+ typedef void (*WarnFn)(const FlatCompiler *flatc, const std::string &warn,
+ bool show_exe_name);
+
+ typedef void (*ErrorFn)(const FlatCompiler *flatc, const std::string &err,
+ bool usage, bool show_exe_name);
+
+ // Parameters required to initialize the FlatCompiler.
+ struct InitParams {
+ InitParams()
+ : generators(nullptr),
+ num_generators(0),
+ warn_fn(nullptr),
+ error_fn(nullptr) {}
+
+ const Generator *generators;
+ size_t num_generators;
+ WarnFn warn_fn;
+ ErrorFn error_fn;
+ };
+
+ explicit FlatCompiler(const InitParams &params) : params_(params) {}
+
+ int Compile(int argc, const char **argv);
+
+ std::string GetUsageString(const char *program_name) const;
+
+ private:
+ void ParseFile(flatbuffers::Parser &parser, const std::string &filename,
+ const std::string &contents,
+ std::vector<const char *> &include_directories) const;
+
+ void LoadBinarySchema(Parser &parser, const std::string &filename,
+ const std::string &contents);
+
+ void Warn(const std::string &warn, bool show_exe_name = true) const;
+
+ void Error(const std::string &err, bool usage = true,
+ bool show_exe_name = true) const;
+
+ InitParams params_;
+};
+
+} // namespace flatbuffers
+
+#endif // FLATBUFFERS_FLATC_H_
diff --git a/contrib/libs/flatbuffers/include/flatbuffers/flexbuffers.h b/contrib/libs/flatbuffers/include/flatbuffers/flexbuffers.h
new file mode 100644
index 0000000000..d855b67731
--- /dev/null
+++ b/contrib/libs/flatbuffers/include/flatbuffers/flexbuffers.h
@@ -0,0 +1,1636 @@
+/*
+ * Copyright 2017 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_FLEXBUFFERS_H_
+#define FLATBUFFERS_FLEXBUFFERS_H_
+
+#include <map>
+// Used to select STL variant.
+#include "base.h"
+// We use the basic binary writing functions from the regular FlatBuffers.
+#include "util.h"
+
+#ifdef _MSC_VER
+# include <intrin.h>
+#endif
+
+#if defined(_MSC_VER)
+# pragma warning(push)
+# pragma warning(disable : 4127) // C4127: conditional expression is constant
+#endif
+
+namespace flexbuffers {
+
+class Reference;
+class Map;
+
+// These are used in the lower 2 bits of a type field to determine the size of
+// the elements (and or size field) of the item pointed to (e.g. vector).
+enum BitWidth {
+ BIT_WIDTH_8 = 0,
+ BIT_WIDTH_16 = 1,
+ BIT_WIDTH_32 = 2,
+ BIT_WIDTH_64 = 3,
+};
+
+// These are used as the upper 6 bits of a type field to indicate the actual
+// type.
+enum Type {
+ FBT_NULL = 0,
+ FBT_INT = 1,
+ FBT_UINT = 2,
+ FBT_FLOAT = 3,
+ // Types above stored inline, types below store an offset.
+ FBT_KEY = 4,
+ FBT_STRING = 5,
+ FBT_INDIRECT_INT = 6,
+ FBT_INDIRECT_UINT = 7,
+ FBT_INDIRECT_FLOAT = 8,
+ FBT_MAP = 9,
+ FBT_VECTOR = 10, // Untyped.
+ FBT_VECTOR_INT = 11, // Typed any size (stores no type table).
+ FBT_VECTOR_UINT = 12,
+ FBT_VECTOR_FLOAT = 13,
+ FBT_VECTOR_KEY = 14,
+ // DEPRECATED, use FBT_VECTOR or FBT_VECTOR_KEY instead.
+ // Read test.cpp/FlexBuffersDeprecatedTest() for details on why.
+ FBT_VECTOR_STRING_DEPRECATED = 15,
+ FBT_VECTOR_INT2 = 16, // Typed tuple (no type table, no size field).
+ FBT_VECTOR_UINT2 = 17,
+ FBT_VECTOR_FLOAT2 = 18,
+ FBT_VECTOR_INT3 = 19, // Typed triple (no type table, no size field).
+ FBT_VECTOR_UINT3 = 20,
+ FBT_VECTOR_FLOAT3 = 21,
+ FBT_VECTOR_INT4 = 22, // Typed quad (no type table, no size field).
+ FBT_VECTOR_UINT4 = 23,
+ FBT_VECTOR_FLOAT4 = 24,
+ FBT_BLOB = 25,
+ FBT_BOOL = 26,
+ FBT_VECTOR_BOOL =
+ 36, // To Allow the same type of conversion of type to vector type
+};
+
+inline bool IsInline(Type t) { return t <= FBT_FLOAT || t == FBT_BOOL; }
+
+inline bool IsTypedVectorElementType(Type t) {
+ return (t >= FBT_INT && t <= FBT_STRING) || t == FBT_BOOL;
+}
+
+inline bool IsTypedVector(Type t) {
+ return (t >= FBT_VECTOR_INT && t <= FBT_VECTOR_STRING_DEPRECATED) ||
+ t == FBT_VECTOR_BOOL;
+}
+
+inline bool IsFixedTypedVector(Type t) {
+ return t >= FBT_VECTOR_INT2 && t <= FBT_VECTOR_FLOAT4;
+}
+
+inline Type ToTypedVector(Type t, size_t fixed_len = 0) {
+ FLATBUFFERS_ASSERT(IsTypedVectorElementType(t));
+ switch (fixed_len) {
+ case 0: return static_cast<Type>(t - FBT_INT + FBT_VECTOR_INT);
+ case 2: return static_cast<Type>(t - FBT_INT + FBT_VECTOR_INT2);
+ case 3: return static_cast<Type>(t - FBT_INT + FBT_VECTOR_INT3);
+ case 4: return static_cast<Type>(t - FBT_INT + FBT_VECTOR_INT4);
+ default: FLATBUFFERS_ASSERT(0); return FBT_NULL;
+ }
+}
+
+inline Type ToTypedVectorElementType(Type t) {
+ FLATBUFFERS_ASSERT(IsTypedVector(t));
+ return static_cast<Type>(t - FBT_VECTOR_INT + FBT_INT);
+}
+
+inline Type ToFixedTypedVectorElementType(Type t, uint8_t *len) {
+ FLATBUFFERS_ASSERT(IsFixedTypedVector(t));
+ auto fixed_type = t - FBT_VECTOR_INT2;
+ *len = static_cast<uint8_t>(fixed_type / 3 +
+ 2); // 3 types each, starting from length 2.
+ return static_cast<Type>(fixed_type % 3 + FBT_INT);
+}
+
+// TODO: implement proper support for 8/16bit floats, or decide not to
+// support them.
+typedef int16_t half;
+typedef int8_t quarter;
+
+// TODO: can we do this without conditionals using intrinsics or inline asm
+// on some platforms? Given branch prediction the method below should be
+// decently quick, but it is the most frequently executed function.
+// We could do an (unaligned) 64-bit read if we ifdef out the platforms for
+// which that doesn't work (or where we'd read into un-owned memory).
+template<typename R, typename T1, typename T2, typename T4, typename T8>
+R ReadSizedScalar(const uint8_t *data, uint8_t byte_width) {
+ return byte_width < 4
+ ? (byte_width < 2
+ ? static_cast<R>(flatbuffers::ReadScalar<T1>(data))
+ : static_cast<R>(flatbuffers::ReadScalar<T2>(data)))
+ : (byte_width < 8
+ ? static_cast<R>(flatbuffers::ReadScalar<T4>(data))
+ : static_cast<R>(flatbuffers::ReadScalar<T8>(data)));
+}
+
+inline int64_t ReadInt64(const uint8_t *data, uint8_t byte_width) {
+ return ReadSizedScalar<int64_t, int8_t, int16_t, int32_t, int64_t>(
+ data, byte_width);
+}
+
+inline uint64_t ReadUInt64(const uint8_t *data, uint8_t byte_width) {
+ // This is the "hottest" function (all offset lookups use this), so worth
+ // optimizing if possible.
+ // TODO: GCC apparently replaces memcpy by a rep movsb, but only if count is a
+ // constant, which here it isn't. Test if memcpy is still faster than
+ // the conditionals in ReadSizedScalar. Can also use inline asm.
+ // clang-format off
+ #if defined(_MSC_VER) && ((defined(_M_X64) && !defined(_M_ARM64EC)) || defined _M_IX86)
+ uint64_t u = 0;
+ __movsb(reinterpret_cast<uint8_t *>(&u),
+ reinterpret_cast<const uint8_t *>(data), byte_width);
+ return flatbuffers::EndianScalar(u);
+ #else
+ return ReadSizedScalar<uint64_t, uint8_t, uint16_t, uint32_t, uint64_t>(
+ data, byte_width);
+ #endif
+ // clang-format on
+}
+
+inline double ReadDouble(const uint8_t *data, uint8_t byte_width) {
+ return ReadSizedScalar<double, quarter, half, float, double>(data,
+ byte_width);
+}
+
+inline const uint8_t *Indirect(const uint8_t *offset, uint8_t byte_width) {
+ return offset - ReadUInt64(offset, byte_width);
+}
+
+template<typename T> const uint8_t *Indirect(const uint8_t *offset) {
+ return offset - flatbuffers::ReadScalar<T>(offset);
+}
+
+inline BitWidth WidthU(uint64_t u) {
+#define FLATBUFFERS_GET_FIELD_BIT_WIDTH(value, width) \
+ { \
+ if (!((u) & ~((1ULL << (width)) - 1ULL))) return BIT_WIDTH_##width; \
+ }
+ FLATBUFFERS_GET_FIELD_BIT_WIDTH(u, 8);
+ FLATBUFFERS_GET_FIELD_BIT_WIDTH(u, 16);
+ FLATBUFFERS_GET_FIELD_BIT_WIDTH(u, 32);
+#undef FLATBUFFERS_GET_FIELD_BIT_WIDTH
+ return BIT_WIDTH_64;
+}
+
+inline BitWidth WidthI(int64_t i) {
+ auto u = static_cast<uint64_t>(i) << 1;
+ return WidthU(i >= 0 ? u : ~u);
+}
+
+inline BitWidth WidthF(double f) {
+ return static_cast<double>(static_cast<float>(f)) == f ? BIT_WIDTH_32
+ : BIT_WIDTH_64;
+}
+
+// Base class of all types below.
+// Points into the data buffer and allows access to one type.
+class Object {
+ public:
+ Object(const uint8_t *data, uint8_t byte_width)
+ : data_(data), byte_width_(byte_width) {}
+
+ protected:
+ const uint8_t *data_;
+ uint8_t byte_width_;
+};
+
+// Object that has a size, obtained either from size prefix, or elsewhere.
+class Sized : public Object {
+ public:
+ // Size prefix.
+ Sized(const uint8_t *data, uint8_t byte_width)
+ : Object(data, byte_width), size_(read_size()) {}
+ // Manual size.
+ Sized(const uint8_t *data, uint8_t byte_width, size_t sz)
+ : Object(data, byte_width), size_(sz) {}
+ size_t size() const { return size_; }
+ // Access size stored in `byte_width_` bytes before data_ pointer.
+ size_t read_size() const {
+ return static_cast<size_t>(ReadUInt64(data_ - byte_width_, byte_width_));
+ }
+
+ protected:
+ size_t size_;
+};
+
+class String : public Sized {
+ public:
+ // Size prefix.
+ String(const uint8_t *data, uint8_t byte_width) : Sized(data, byte_width) {}
+ // Manual size.
+ String(const uint8_t *data, uint8_t byte_width, size_t sz)
+ : Sized(data, byte_width, sz) {}
+
+ size_t length() const { return size(); }
+ const char *c_str() const { return reinterpret_cast<const char *>(data_); }
+ std::string str() const { return std::string(c_str(), size()); }
+
+ static String EmptyString() {
+ static const char *empty_string = "";
+ return String(reinterpret_cast<const uint8_t *>(empty_string), 1, 0);
+ }
+ bool IsTheEmptyString() const { return data_ == EmptyString().data_; }
+};
+
+class Blob : public Sized {
+ public:
+ Blob(const uint8_t *data_buf, uint8_t byte_width)
+ : Sized(data_buf, byte_width) {}
+
+ static Blob EmptyBlob() {
+ static const uint8_t empty_blob[] = { 0 /*len*/ };
+ return Blob(empty_blob + 1, 1);
+ }
+ bool IsTheEmptyBlob() const { return data_ == EmptyBlob().data_; }
+ const uint8_t *data() const { return data_; }
+};
+
+class Vector : public Sized {
+ public:
+ Vector(const uint8_t *data, uint8_t byte_width) : Sized(data, byte_width) {}
+
+ Reference operator[](size_t i) const;
+
+ static Vector EmptyVector() {
+ static const uint8_t empty_vector[] = { 0 /*len*/ };
+ return Vector(empty_vector + 1, 1);
+ }
+ bool IsTheEmptyVector() const { return data_ == EmptyVector().data_; }
+};
+
+class TypedVector : public Sized {
+ public:
+ TypedVector(const uint8_t *data, uint8_t byte_width, Type element_type)
+ : Sized(data, byte_width), type_(element_type) {}
+
+ Reference operator[](size_t i) const;
+
+ static TypedVector EmptyTypedVector() {
+ static const uint8_t empty_typed_vector[] = { 0 /*len*/ };
+ return TypedVector(empty_typed_vector + 1, 1, FBT_INT);
+ }
+ bool IsTheEmptyVector() const {
+ return data_ == TypedVector::EmptyTypedVector().data_;
+ }
+
+ Type ElementType() { return type_; }
+
+ friend Reference;
+
+ private:
+ Type type_;
+
+ friend Map;
+};
+
+class FixedTypedVector : public Object {
+ public:
+ FixedTypedVector(const uint8_t *data, uint8_t byte_width, Type element_type,
+ uint8_t len)
+ : Object(data, byte_width), type_(element_type), len_(len) {}
+
+ Reference operator[](size_t i) const;
+
+ static FixedTypedVector EmptyFixedTypedVector() {
+ static const uint8_t fixed_empty_vector[] = { 0 /* unused */ };
+ return FixedTypedVector(fixed_empty_vector, 1, FBT_INT, 0);
+ }
+ bool IsTheEmptyFixedTypedVector() const {
+ return data_ == FixedTypedVector::EmptyFixedTypedVector().data_;
+ }
+
+ Type ElementType() { return type_; }
+ uint8_t size() { return len_; }
+
+ private:
+ Type type_;
+ uint8_t len_;
+};
+
+class Map : public Vector {
+ public:
+ Map(const uint8_t *data, uint8_t byte_width) : Vector(data, byte_width) {}
+
+ Reference operator[](const char *key) const;
+ Reference operator[](const std::string &key) const;
+
+ Vector Values() const { return Vector(data_, byte_width_); }
+
+ TypedVector Keys() const {
+ const size_t num_prefixed_fields = 3;
+ auto keys_offset = data_ - byte_width_ * num_prefixed_fields;
+ return TypedVector(Indirect(keys_offset, byte_width_),
+ static_cast<uint8_t>(
+ ReadUInt64(keys_offset + byte_width_, byte_width_)),
+ FBT_KEY);
+ }
+
+ static Map EmptyMap() {
+ static const uint8_t empty_map[] = {
+ 0 /*keys_len*/, 0 /*keys_offset*/, 1 /*keys_width*/, 0 /*len*/
+ };
+ return Map(empty_map + 4, 1);
+ }
+
+ bool IsTheEmptyMap() const { return data_ == EmptyMap().data_; }
+};
+
+template<typename T>
+void AppendToString(std::string &s, T &&v, bool keys_quoted) {
+ s += "[ ";
+ for (size_t i = 0; i < v.size(); i++) {
+ if (i) s += ", ";
+ v[i].ToString(true, keys_quoted, s);
+ }
+ s += " ]";
+}
+
+class Reference {
+ public:
+ Reference()
+ : data_(nullptr),
+ parent_width_(0),
+ byte_width_(BIT_WIDTH_8),
+ type_(FBT_NULL) {}
+
+ Reference(const uint8_t *data, uint8_t parent_width, uint8_t byte_width,
+ Type type)
+ : data_(data),
+ parent_width_(parent_width),
+ byte_width_(byte_width),
+ type_(type) {}
+
+ Reference(const uint8_t *data, uint8_t parent_width, uint8_t packed_type)
+ : data_(data), parent_width_(parent_width) {
+ byte_width_ = 1U << static_cast<BitWidth>(packed_type & 3);
+ type_ = static_cast<Type>(packed_type >> 2);
+ }
+
+ Type GetType() const { return type_; }
+
+ bool IsNull() const { return type_ == FBT_NULL; }
+ bool IsBool() const { return type_ == FBT_BOOL; }
+ bool IsInt() const { return type_ == FBT_INT || type_ == FBT_INDIRECT_INT; }
+ bool IsUInt() const {
+ return type_ == FBT_UINT || type_ == FBT_INDIRECT_UINT;
+ }
+ bool IsIntOrUint() const { return IsInt() || IsUInt(); }
+ bool IsFloat() const {
+ return type_ == FBT_FLOAT || type_ == FBT_INDIRECT_FLOAT;
+ }
+ bool IsNumeric() const { return IsIntOrUint() || IsFloat(); }
+ bool IsString() const { return type_ == FBT_STRING; }
+ bool IsKey() const { return type_ == FBT_KEY; }
+ bool IsVector() const { return type_ == FBT_VECTOR || type_ == FBT_MAP; }
+ bool IsUntypedVector() const { return type_ == FBT_VECTOR; }
+ bool IsTypedVector() const { return flexbuffers::IsTypedVector(type_); }
+ bool IsFixedTypedVector() const {
+ return flexbuffers::IsFixedTypedVector(type_);
+ }
+ bool IsAnyVector() const {
+ return (IsTypedVector() || IsFixedTypedVector() || IsVector());
+ }
+ bool IsMap() const { return type_ == FBT_MAP; }
+ bool IsBlob() const { return type_ == FBT_BLOB; }
+ bool AsBool() const {
+ return (type_ == FBT_BOOL ? ReadUInt64(data_, parent_width_)
+ : AsUInt64()) != 0;
+ }
+
+ // Reads any type as a int64_t. Never fails, does most sensible conversion.
+ // Truncates floats, strings are attempted to be parsed for a number,
+ // vectors/maps return their size. Returns 0 if all else fails.
+ int64_t AsInt64() const {
+ if (type_ == FBT_INT) {
+ // A fast path for the common case.
+ return ReadInt64(data_, parent_width_);
+ } else
+ switch (type_) {
+ case FBT_INDIRECT_INT: return ReadInt64(Indirect(), byte_width_);
+ case FBT_UINT: return ReadUInt64(data_, parent_width_);
+ case FBT_INDIRECT_UINT: return ReadUInt64(Indirect(), byte_width_);
+ case FBT_FLOAT:
+ return static_cast<int64_t>(ReadDouble(data_, parent_width_));
+ case FBT_INDIRECT_FLOAT:
+ return static_cast<int64_t>(ReadDouble(Indirect(), byte_width_));
+ case FBT_NULL: return 0;
+ case FBT_STRING: return flatbuffers::StringToInt(AsString().c_str());
+ case FBT_VECTOR: return static_cast<int64_t>(AsVector().size());
+ case FBT_BOOL: return ReadInt64(data_, parent_width_);
+ default:
+ // Convert other things to int.
+ return 0;
+ }
+ }
+
+ // TODO: could specialize these to not use AsInt64() if that saves
+ // extension ops in generated code, and use a faster op than ReadInt64.
+ int32_t AsInt32() const { return static_cast<int32_t>(AsInt64()); }
+ int16_t AsInt16() const { return static_cast<int16_t>(AsInt64()); }
+ int8_t AsInt8() const { return static_cast<int8_t>(AsInt64()); }
+
+ uint64_t AsUInt64() const {
+ if (type_ == FBT_UINT) {
+ // A fast path for the common case.
+ return ReadUInt64(data_, parent_width_);
+ } else
+ switch (type_) {
+ case FBT_INDIRECT_UINT: return ReadUInt64(Indirect(), byte_width_);
+ case FBT_INT: return ReadInt64(data_, parent_width_);
+ case FBT_INDIRECT_INT: return ReadInt64(Indirect(), byte_width_);
+ case FBT_FLOAT:
+ return static_cast<uint64_t>(ReadDouble(data_, parent_width_));
+ case FBT_INDIRECT_FLOAT:
+ return static_cast<uint64_t>(ReadDouble(Indirect(), byte_width_));
+ case FBT_NULL: return 0;
+ case FBT_STRING: return flatbuffers::StringToUInt(AsString().c_str());
+ case FBT_VECTOR: return static_cast<uint64_t>(AsVector().size());
+ case FBT_BOOL: return ReadUInt64(data_, parent_width_);
+ default:
+ // Convert other things to uint.
+ return 0;
+ }
+ }
+
+ uint32_t AsUInt32() const { return static_cast<uint32_t>(AsUInt64()); }
+ uint16_t AsUInt16() const { return static_cast<uint16_t>(AsUInt64()); }
+ uint8_t AsUInt8() const { return static_cast<uint8_t>(AsUInt64()); }
+
+ double AsDouble() const {
+ if (type_ == FBT_FLOAT) {
+ // A fast path for the common case.
+ return ReadDouble(data_, parent_width_);
+ } else
+ switch (type_) {
+ case FBT_INDIRECT_FLOAT: return ReadDouble(Indirect(), byte_width_);
+ case FBT_INT:
+ return static_cast<double>(ReadInt64(data_, parent_width_));
+ case FBT_UINT:
+ return static_cast<double>(ReadUInt64(data_, parent_width_));
+ case FBT_INDIRECT_INT:
+ return static_cast<double>(ReadInt64(Indirect(), byte_width_));
+ case FBT_INDIRECT_UINT:
+ return static_cast<double>(ReadUInt64(Indirect(), byte_width_));
+ case FBT_NULL: return 0.0;
+ case FBT_STRING: {
+ double d;
+ flatbuffers::StringToNumber(AsString().c_str(), &d);
+ return d;
+ }
+ case FBT_VECTOR: return static_cast<double>(AsVector().size());
+ case FBT_BOOL:
+ return static_cast<double>(ReadUInt64(data_, parent_width_));
+ default:
+ // Convert strings and other things to float.
+ return 0;
+ }
+ }
+
+ float AsFloat() const { return static_cast<float>(AsDouble()); }
+
+ const char *AsKey() const {
+ if (type_ == FBT_KEY || type_ == FBT_STRING) {
+ return reinterpret_cast<const char *>(Indirect());
+ } else {
+ return "";
+ }
+ }
+
+ // This function returns the empty string if you try to read something that
+ // is not a string or key.
+ String AsString() const {
+ if (type_ == FBT_STRING) {
+ return String(Indirect(), byte_width_);
+ } else if (type_ == FBT_KEY) {
+ auto key = Indirect();
+ return String(key, byte_width_,
+ strlen(reinterpret_cast<const char *>(key)));
+ } else {
+ return String::EmptyString();
+ }
+ }
+
+ // Unlike AsString(), this will convert any type to a std::string.
+ std::string ToString() const {
+ std::string s;
+ ToString(false, false, s);
+ return s;
+ }
+
+ // Convert any type to a JSON-like string. strings_quoted determines if
+ // string values at the top level receive "" quotes (inside other values
+ // they always do). keys_quoted determines if keys are quoted, at any level.
+ // TODO(wvo): add further options to have indentation/newlines.
+ void ToString(bool strings_quoted, bool keys_quoted, std::string &s) const {
+ if (type_ == FBT_STRING) {
+ String str(Indirect(), byte_width_);
+ if (strings_quoted) {
+ flatbuffers::EscapeString(str.c_str(), str.length(), &s, true, false);
+ } else {
+ s.append(str.c_str(), str.length());
+ }
+ } else if (IsKey()) {
+ auto str = AsKey();
+ if (keys_quoted) {
+ flatbuffers::EscapeString(str, strlen(str), &s, true, false);
+ } else {
+ s += str;
+ }
+ } else if (IsInt()) {
+ s += flatbuffers::NumToString(AsInt64());
+ } else if (IsUInt()) {
+ s += flatbuffers::NumToString(AsUInt64());
+ } else if (IsFloat()) {
+ s += flatbuffers::NumToString(AsDouble());
+ } else if (IsNull()) {
+ s += "null";
+ } else if (IsBool()) {
+ s += AsBool() ? "true" : "false";
+ } else if (IsMap()) {
+ s += "{ ";
+ auto m = AsMap();
+ auto keys = m.Keys();
+ auto vals = m.Values();
+ for (size_t i = 0; i < keys.size(); i++) {
+ keys[i].ToString(true, keys_quoted, s);
+ s += ": ";
+ vals[i].ToString(true, keys_quoted, s);
+ if (i < keys.size() - 1) s += ", ";
+ }
+ s += " }";
+ } else if (IsVector()) {
+ AppendToString<Vector>(s, AsVector(), keys_quoted);
+ } else if (IsTypedVector()) {
+ AppendToString<TypedVector>(s, AsTypedVector(), keys_quoted);
+ } else if (IsFixedTypedVector()) {
+ AppendToString<FixedTypedVector>(s, AsFixedTypedVector(), keys_quoted);
+ } else if (IsBlob()) {
+ auto blob = AsBlob();
+ flatbuffers::EscapeString(reinterpret_cast<const char *>(blob.data()),
+ blob.size(), &s, true, false);
+ } else {
+ s += "(?)";
+ }
+ }
+
+ // This function returns the empty blob if you try to read a not-blob.
+ // Strings can be viewed as blobs too.
+ Blob AsBlob() const {
+ if (type_ == FBT_BLOB || type_ == FBT_STRING) {
+ return Blob(Indirect(), byte_width_);
+ } else {
+ return Blob::EmptyBlob();
+ }
+ }
+
+ // This function returns the empty vector if you try to read a not-vector.
+ // Maps can be viewed as vectors too.
+ Vector AsVector() const {
+ if (type_ == FBT_VECTOR || type_ == FBT_MAP) {
+ return Vector(Indirect(), byte_width_);
+ } else {
+ return Vector::EmptyVector();
+ }
+ }
+
+ TypedVector AsTypedVector() const {
+ if (IsTypedVector()) {
+ auto tv =
+ TypedVector(Indirect(), byte_width_, ToTypedVectorElementType(type_));
+ if (tv.type_ == FBT_STRING) {
+ // These can't be accessed as strings, since we don't know the bit-width
+ // of the size field, see the declaration of
+ // FBT_VECTOR_STRING_DEPRECATED above for details.
+ // We change the type here to be keys, which are a subtype of strings,
+ // and will ignore the size field. This will truncate strings with
+ // embedded nulls.
+ tv.type_ = FBT_KEY;
+ }
+ return tv;
+ } else {
+ return TypedVector::EmptyTypedVector();
+ }
+ }
+
+ FixedTypedVector AsFixedTypedVector() const {
+ if (IsFixedTypedVector()) {
+ uint8_t len = 0;
+ auto vtype = ToFixedTypedVectorElementType(type_, &len);
+ return FixedTypedVector(Indirect(), byte_width_, vtype, len);
+ } else {
+ return FixedTypedVector::EmptyFixedTypedVector();
+ }
+ }
+
+ Map AsMap() const {
+ if (type_ == FBT_MAP) {
+ return Map(Indirect(), byte_width_);
+ } else {
+ return Map::EmptyMap();
+ }
+ }
+
+ template<typename T> T As() const;
+
+ // Experimental: Mutation functions.
+ // These allow scalars in an already created buffer to be updated in-place.
+ // Since by default scalars are stored in the smallest possible space,
+ // the new value may not fit, in which case these functions return false.
+ // To avoid this, you can construct the values you intend to mutate using
+ // Builder::ForceMinimumBitWidth.
+ bool MutateInt(int64_t i) {
+ if (type_ == FBT_INT) {
+ return Mutate(data_, i, parent_width_, WidthI(i));
+ } else if (type_ == FBT_INDIRECT_INT) {
+ return Mutate(Indirect(), i, byte_width_, WidthI(i));
+ } else if (type_ == FBT_UINT) {
+ auto u = static_cast<uint64_t>(i);
+ return Mutate(data_, u, parent_width_, WidthU(u));
+ } else if (type_ == FBT_INDIRECT_UINT) {
+ auto u = static_cast<uint64_t>(i);
+ return Mutate(Indirect(), u, byte_width_, WidthU(u));
+ } else {
+ return false;
+ }
+ }
+
+ bool MutateBool(bool b) {
+ return type_ == FBT_BOOL && Mutate(data_, b, parent_width_, BIT_WIDTH_8);
+ }
+
+ bool MutateUInt(uint64_t u) {
+ if (type_ == FBT_UINT) {
+ return Mutate(data_, u, parent_width_, WidthU(u));
+ } else if (type_ == FBT_INDIRECT_UINT) {
+ return Mutate(Indirect(), u, byte_width_, WidthU(u));
+ } else if (type_ == FBT_INT) {
+ auto i = static_cast<int64_t>(u);
+ return Mutate(data_, i, parent_width_, WidthI(i));
+ } else if (type_ == FBT_INDIRECT_INT) {
+ auto i = static_cast<int64_t>(u);
+ return Mutate(Indirect(), i, byte_width_, WidthI(i));
+ } else {
+ return false;
+ }
+ }
+
+ bool MutateFloat(float f) {
+ if (type_ == FBT_FLOAT) {
+ return MutateF(data_, f, parent_width_, BIT_WIDTH_32);
+ } else if (type_ == FBT_INDIRECT_FLOAT) {
+ return MutateF(Indirect(), f, byte_width_, BIT_WIDTH_32);
+ } else {
+ return false;
+ }
+ }
+
+ bool MutateFloat(double d) {
+ if (type_ == FBT_FLOAT) {
+ return MutateF(data_, d, parent_width_, WidthF(d));
+ } else if (type_ == FBT_INDIRECT_FLOAT) {
+ return MutateF(Indirect(), d, byte_width_, WidthF(d));
+ } else {
+ return false;
+ }
+ }
+
+ bool MutateString(const char *str, size_t len) {
+ auto s = AsString();
+ if (s.IsTheEmptyString()) return false;
+ // This is very strict, could allow shorter strings, but that creates
+ // garbage.
+ if (s.length() != len) return false;
+ memcpy(const_cast<char *>(s.c_str()), str, len);
+ return true;
+ }
+ bool MutateString(const char *str) { return MutateString(str, strlen(str)); }
+ bool MutateString(const std::string &str) {
+ return MutateString(str.data(), str.length());
+ }
+
+ private:
+ const uint8_t *Indirect() const {
+ return flexbuffers::Indirect(data_, parent_width_);
+ }
+
+ template<typename T>
+ bool Mutate(const uint8_t *dest, T t, size_t byte_width,
+ BitWidth value_width) {
+ auto fits = static_cast<size_t>(static_cast<size_t>(1U) << value_width) <=
+ byte_width;
+ if (fits) {
+ t = flatbuffers::EndianScalar(t);
+ memcpy(const_cast<uint8_t *>(dest), &t, byte_width);
+ }
+ return fits;
+ }
+
+ template<typename T>
+ bool MutateF(const uint8_t *dest, T t, size_t byte_width,
+ BitWidth value_width) {
+ if (byte_width == sizeof(double))
+ return Mutate(dest, static_cast<double>(t), byte_width, value_width);
+ if (byte_width == sizeof(float))
+ return Mutate(dest, static_cast<float>(t), byte_width, value_width);
+ FLATBUFFERS_ASSERT(false);
+ return false;
+ }
+
+ const uint8_t *data_;
+ uint8_t parent_width_;
+ uint8_t byte_width_;
+ Type type_;
+};
+
+// Template specialization for As().
+template<> inline bool Reference::As<bool>() const { return AsBool(); }
+
+template<> inline int8_t Reference::As<int8_t>() const { return AsInt8(); }
+template<> inline int16_t Reference::As<int16_t>() const { return AsInt16(); }
+template<> inline int32_t Reference::As<int32_t>() const { return AsInt32(); }
+template<> inline int64_t Reference::As<int64_t>() const { return AsInt64(); }
+
+template<> inline uint8_t Reference::As<uint8_t>() const { return AsUInt8(); }
+template<> inline uint16_t Reference::As<uint16_t>() const {
+ return AsUInt16();
+}
+template<> inline uint32_t Reference::As<uint32_t>() const {
+ return AsUInt32();
+}
+template<> inline uint64_t Reference::As<uint64_t>() const {
+ return AsUInt64();
+}
+
+template<> inline double Reference::As<double>() const { return AsDouble(); }
+template<> inline float Reference::As<float>() const { return AsFloat(); }
+
+template<> inline String Reference::As<String>() const { return AsString(); }
+template<> inline std::string Reference::As<std::string>() const {
+ return AsString().str();
+}
+
+template<> inline Blob Reference::As<Blob>() const { return AsBlob(); }
+template<> inline Vector Reference::As<Vector>() const { return AsVector(); }
+template<> inline TypedVector Reference::As<TypedVector>() const {
+ return AsTypedVector();
+}
+template<> inline FixedTypedVector Reference::As<FixedTypedVector>() const {
+ return AsFixedTypedVector();
+}
+template<> inline Map Reference::As<Map>() const { return AsMap(); }
+
+inline uint8_t PackedType(BitWidth bit_width, Type type) {
+ return static_cast<uint8_t>(bit_width | (type << 2));
+}
+
+inline uint8_t NullPackedType() { return PackedType(BIT_WIDTH_8, FBT_NULL); }
+
+// Vector accessors.
+// Note: if you try to access outside of bounds, you get a Null value back
+// instead. Normally this would be an assert, but since this is "dynamically
+// typed" data, you may not want that (someone sends you a 2d vector and you
+// wanted 3d).
+// The Null converts seamlessly into a default value for any other type.
+// TODO(wvo): Could introduce an #ifdef that makes this into an assert?
+inline Reference Vector::operator[](size_t i) const {
+ auto len = size();
+ if (i >= len) return Reference(nullptr, 1, NullPackedType());
+ auto packed_type = (data_ + len * byte_width_)[i];
+ auto elem = data_ + i * byte_width_;
+ return Reference(elem, byte_width_, packed_type);
+}
+
+inline Reference TypedVector::operator[](size_t i) const {
+ auto len = size();
+ if (i >= len) return Reference(nullptr, 1, NullPackedType());
+ auto elem = data_ + i * byte_width_;
+ return Reference(elem, byte_width_, 1, type_);
+}
+
+inline Reference FixedTypedVector::operator[](size_t i) const {
+ if (i >= len_) return Reference(nullptr, 1, NullPackedType());
+ auto elem = data_ + i * byte_width_;
+ return Reference(elem, byte_width_, 1, type_);
+}
+
+template<typename T> int KeyCompare(const void *key, const void *elem) {
+ auto str_elem = reinterpret_cast<const char *>(
+ Indirect<T>(reinterpret_cast<const uint8_t *>(elem)));
+ auto skey = reinterpret_cast<const char *>(key);
+ return strcmp(skey, str_elem);
+}
+
+inline Reference Map::operator[](const char *key) const {
+ auto keys = Keys();
+ // We can't pass keys.byte_width_ to the comparison function, so we have
+ // to pick the right one ahead of time.
+ int (*comp)(const void *, const void *) = nullptr;
+ switch (keys.byte_width_) {
+ case 1: comp = KeyCompare<uint8_t>; break;
+ case 2: comp = KeyCompare<uint16_t>; break;
+ case 4: comp = KeyCompare<uint32_t>; break;
+ case 8: comp = KeyCompare<uint64_t>; break;
+ }
+ auto res = std::bsearch(key, keys.data_, keys.size(), keys.byte_width_, comp);
+ if (!res) return Reference(nullptr, 1, NullPackedType());
+ auto i = (reinterpret_cast<uint8_t *>(res) - keys.data_) / keys.byte_width_;
+ return (*static_cast<const Vector *>(this))[i];
+}
+
+inline Reference Map::operator[](const std::string &key) const {
+ return (*this)[key.c_str()];
+}
+
+inline Reference GetRoot(const uint8_t *buffer, size_t size) {
+ // See Finish() below for the serialization counterpart of this.
+ // The root starts at the end of the buffer, so we parse backwards from there.
+ auto end = buffer + size;
+ auto byte_width = *--end;
+ auto packed_type = *--end;
+ end -= byte_width; // The root data item.
+ return Reference(end, byte_width, packed_type);
+}
+
+inline Reference GetRoot(const std::vector<uint8_t> &buffer) {
+ return GetRoot(flatbuffers::vector_data(buffer), buffer.size());
+}
+
+// Flags that configure how the Builder behaves.
+// The "Share" flags determine if the Builder automatically tries to pool
+// this type. Pooling can reduce the size of serialized data if there are
+// multiple maps of the same kind, at the expense of slightly slower
+// serialization (the cost of lookups) and more memory use (std::set).
+// By default this is on for keys, but off for strings.
+// Turn keys off if you have e.g. only one map.
+// Turn strings on if you expect many non-unique string values.
+// Additionally, sharing key vectors can save space if you have maps with
+// identical field populations.
+enum BuilderFlag {
+ BUILDER_FLAG_NONE = 0,
+ BUILDER_FLAG_SHARE_KEYS = 1,
+ BUILDER_FLAG_SHARE_STRINGS = 2,
+ BUILDER_FLAG_SHARE_KEYS_AND_STRINGS = 3,
+ BUILDER_FLAG_SHARE_KEY_VECTORS = 4,
+ BUILDER_FLAG_SHARE_ALL = 7,
+};
+
+class Builder FLATBUFFERS_FINAL_CLASS {
+ public:
+ Builder(size_t initial_size = 256,
+ BuilderFlag flags = BUILDER_FLAG_SHARE_KEYS)
+ : buf_(initial_size),
+ finished_(false),
+ has_duplicate_keys_(false),
+ flags_(flags),
+ force_min_bit_width_(BIT_WIDTH_8),
+ key_pool(KeyOffsetCompare(buf_)),
+ string_pool(StringOffsetCompare(buf_)) {
+ buf_.clear();
+ }
+
+#ifdef FLATBUFFERS_DEFAULT_DECLARATION
+ Builder(Builder &&) = default;
+ Builder &operator=(Builder &&) = default;
+#endif
+
+ /// @brief Get the serialized buffer (after you call `Finish()`).
+ /// @return Returns a vector owned by this class.
+ const std::vector<uint8_t> &GetBuffer() const {
+ Finished();
+ return buf_;
+ }
+
+ // Size of the buffer. Does not include unfinished values.
+ size_t GetSize() const { return buf_.size(); }
+
+ // Reset all state so we can re-use the buffer.
+ void Clear() {
+ buf_.clear();
+ stack_.clear();
+ finished_ = false;
+ // flags_ remains as-is;
+ force_min_bit_width_ = BIT_WIDTH_8;
+ key_pool.clear();
+ string_pool.clear();
+ }
+
+ // All value constructing functions below have two versions: one that
+ // takes a key (for placement inside a map) and one that doesn't (for inside
+ // vectors and elsewhere).
+
+ void Null() { stack_.push_back(Value()); }
+ void Null(const char *key) {
+ Key(key);
+ Null();
+ }
+
+ void Int(int64_t i) { stack_.push_back(Value(i, FBT_INT, WidthI(i))); }
+ void Int(const char *key, int64_t i) {
+ Key(key);
+ Int(i);
+ }
+
+ void UInt(uint64_t u) { stack_.push_back(Value(u, FBT_UINT, WidthU(u))); }
+ void UInt(const char *key, uint64_t u) {
+ Key(key);
+ UInt(u);
+ }
+
+ void Float(float f) { stack_.push_back(Value(f)); }
+ void Float(const char *key, float f) {
+ Key(key);
+ Float(f);
+ }
+
+ void Double(double f) { stack_.push_back(Value(f)); }
+ void Double(const char *key, double d) {
+ Key(key);
+ Double(d);
+ }
+
+ void Bool(bool b) { stack_.push_back(Value(b)); }
+ void Bool(const char *key, bool b) {
+ Key(key);
+ Bool(b);
+ }
+
+ void IndirectInt(int64_t i) { PushIndirect(i, FBT_INDIRECT_INT, WidthI(i)); }
+ void IndirectInt(const char *key, int64_t i) {
+ Key(key);
+ IndirectInt(i);
+ }
+
+ void IndirectUInt(uint64_t u) {
+ PushIndirect(u, FBT_INDIRECT_UINT, WidthU(u));
+ }
+ void IndirectUInt(const char *key, uint64_t u) {
+ Key(key);
+ IndirectUInt(u);
+ }
+
+ void IndirectFloat(float f) {
+ PushIndirect(f, FBT_INDIRECT_FLOAT, BIT_WIDTH_32);
+ }
+ void IndirectFloat(const char *key, float f) {
+ Key(key);
+ IndirectFloat(f);
+ }
+
+ void IndirectDouble(double f) {
+ PushIndirect(f, FBT_INDIRECT_FLOAT, WidthF(f));
+ }
+ void IndirectDouble(const char *key, double d) {
+ Key(key);
+ IndirectDouble(d);
+ }
+
+ size_t Key(const char *str, size_t len) {
+ auto sloc = buf_.size();
+ WriteBytes(str, len + 1);
+ if (flags_ & BUILDER_FLAG_SHARE_KEYS) {
+ auto it = key_pool.find(sloc);
+ if (it != key_pool.end()) {
+ // Already in the buffer. Remove key we just serialized, and use
+ // existing offset instead.
+ buf_.resize(sloc);
+ sloc = *it;
+ } else {
+ key_pool.insert(sloc);
+ }
+ }
+ stack_.push_back(Value(static_cast<uint64_t>(sloc), FBT_KEY, BIT_WIDTH_8));
+ return sloc;
+ }
+
+ size_t Key(const char *str) { return Key(str, strlen(str)); }
+ size_t Key(const std::string &str) { return Key(str.c_str(), str.size()); }
+
+ size_t String(const char *str, size_t len) {
+ auto reset_to = buf_.size();
+ auto sloc = CreateBlob(str, len, 1, FBT_STRING);
+ if (flags_ & BUILDER_FLAG_SHARE_STRINGS) {
+ StringOffset so(sloc, len);
+ auto it = string_pool.find(so);
+ if (it != string_pool.end()) {
+ // Already in the buffer. Remove string we just serialized, and use
+ // existing offset instead.
+ buf_.resize(reset_to);
+ sloc = it->first;
+ stack_.back().u_ = sloc;
+ } else {
+ string_pool.insert(so);
+ }
+ }
+ return sloc;
+ }
+ size_t String(const char *str) { return String(str, strlen(str)); }
+ size_t String(const std::string &str) {
+ return String(str.c_str(), str.size());
+ }
+ void String(const flexbuffers::String &str) {
+ String(str.c_str(), str.length());
+ }
+
+ void String(const char *key, const char *str) {
+ Key(key);
+ String(str);
+ }
+ void String(const char *key, const std::string &str) {
+ Key(key);
+ String(str);
+ }
+ void String(const char *key, const flexbuffers::String &str) {
+ Key(key);
+ String(str);
+ }
+
+ size_t Blob(const void *data, size_t len) {
+ return CreateBlob(data, len, 0, FBT_BLOB);
+ }
+ size_t Blob(const std::vector<uint8_t> &v) {
+ return CreateBlob(flatbuffers::vector_data(v), v.size(), 0, FBT_BLOB);
+ }
+
+ // TODO(wvo): support all the FlexBuffer types (like flexbuffers::String),
+ // e.g. Vector etc. Also in overloaded versions.
+ // Also some FlatBuffers types?
+
+ size_t StartVector() { return stack_.size(); }
+ size_t StartVector(const char *key) {
+ Key(key);
+ return stack_.size();
+ }
+ size_t StartMap() { return stack_.size(); }
+ size_t StartMap(const char *key) {
+ Key(key);
+ return stack_.size();
+ }
+
+ // TODO(wvo): allow this to specify an aligment greater than the natural
+ // alignment.
+ size_t EndVector(size_t start, bool typed, bool fixed) {
+ auto vec = CreateVector(start, stack_.size() - start, 1, typed, fixed);
+ // Remove temp elements and return vector.
+ stack_.resize(start);
+ stack_.push_back(vec);
+ return static_cast<size_t>(vec.u_);
+ }
+
+ size_t EndMap(size_t start) {
+ // We should have interleaved keys and values on the stack.
+ // Make sure it is an even number:
+ auto len = stack_.size() - start;
+ FLATBUFFERS_ASSERT(!(len & 1));
+ len /= 2;
+ // Make sure keys are all strings:
+ for (auto key = start; key < stack_.size(); key += 2) {
+ FLATBUFFERS_ASSERT(stack_[key].type_ == FBT_KEY);
+ }
+ // Now sort values, so later we can do a binary search lookup.
+ // We want to sort 2 array elements at a time.
+ struct TwoValue {
+ Value key;
+ Value val;
+ };
+ // TODO(wvo): strict aliasing?
+ // TODO(wvo): allow the caller to indicate the data is already sorted
+ // for maximum efficiency? With an assert to check sortedness to make sure
+ // we're not breaking binary search.
+ // Or, we can track if the map is sorted as keys are added which would be
+ // be quite cheap (cheaper than checking it here), so we can skip this
+ // step automatically when appliccable, and encourage people to write in
+ // sorted fashion.
+ // std::sort is typically already a lot faster on sorted data though.
+ auto dict =
+ reinterpret_cast<TwoValue *>(flatbuffers::vector_data(stack_) + start);
+ std::sort(dict, dict + len,
+ [&](const TwoValue &a, const TwoValue &b) -> bool {
+ auto as = reinterpret_cast<const char *>(
+ flatbuffers::vector_data(buf_) + a.key.u_);
+ auto bs = reinterpret_cast<const char *>(
+ flatbuffers::vector_data(buf_) + b.key.u_);
+ auto comp = strcmp(as, bs);
+ // We want to disallow duplicate keys, since this results in a
+ // map where values cannot be found.
+ // But we can't assert here (since we don't want to fail on
+ // random JSON input) or have an error mechanism.
+ // Instead, we set has_duplicate_keys_ in the builder to
+ // signal this.
+ // TODO: Have to check for pointer equality, as some sort
+ // implementation apparently call this function with the same
+ // element?? Why?
+ if (!comp && &a != &b) has_duplicate_keys_ = true;
+ return comp < 0;
+ });
+ // First create a vector out of all keys.
+ // TODO(wvo): if kBuilderFlagShareKeyVectors is true, see if we can share
+ // the first vector.
+ auto keys = CreateVector(start, len, 2, true, false);
+ auto vec = CreateVector(start + 1, len, 2, false, false, &keys);
+ // Remove temp elements and return map.
+ stack_.resize(start);
+ stack_.push_back(vec);
+ return static_cast<size_t>(vec.u_);
+ }
+
+ // Call this after EndMap to see if the map had any duplicate keys.
+ // Any map with such keys won't be able to retrieve all values.
+ bool HasDuplicateKeys() const { return has_duplicate_keys_; }
+
+ template<typename F> size_t Vector(F f) {
+ auto start = StartVector();
+ f();
+ return EndVector(start, false, false);
+ }
+ template<typename F, typename T> size_t Vector(F f, T &state) {
+ auto start = StartVector();
+ f(state);
+ return EndVector(start, false, false);
+ }
+ template<typename F> size_t Vector(const char *key, F f) {
+ auto start = StartVector(key);
+ f();
+ return EndVector(start, false, false);
+ }
+ template<typename F, typename T>
+ size_t Vector(const char *key, F f, T &state) {
+ auto start = StartVector(key);
+ f(state);
+ return EndVector(start, false, false);
+ }
+
+ template<typename T> void Vector(const T *elems, size_t len) {
+ if (flatbuffers::is_scalar<T>::value) {
+ // This path should be a lot quicker and use less space.
+ ScalarVector(elems, len, false);
+ } else {
+ auto start = StartVector();
+ for (size_t i = 0; i < len; i++) Add(elems[i]);
+ EndVector(start, false, false);
+ }
+ }
+ template<typename T>
+ void Vector(const char *key, const T *elems, size_t len) {
+ Key(key);
+ Vector(elems, len);
+ }
+ template<typename T> void Vector(const std::vector<T> &vec) {
+ Vector(flatbuffers::vector_data(vec), vec.size());
+ }
+
+ template<typename F> size_t TypedVector(F f) {
+ auto start = StartVector();
+ f();
+ return EndVector(start, true, false);
+ }
+ template<typename F, typename T> size_t TypedVector(F f, T &state) {
+ auto start = StartVector();
+ f(state);
+ return EndVector(start, true, false);
+ }
+ template<typename F> size_t TypedVector(const char *key, F f) {
+ auto start = StartVector(key);
+ f();
+ return EndVector(start, true, false);
+ }
+ template<typename F, typename T>
+ size_t TypedVector(const char *key, F f, T &state) {
+ auto start = StartVector(key);
+ f(state);
+ return EndVector(start, true, false);
+ }
+
+ template<typename T> size_t FixedTypedVector(const T *elems, size_t len) {
+ // We only support a few fixed vector lengths. Anything bigger use a
+ // regular typed vector.
+ FLATBUFFERS_ASSERT(len >= 2 && len <= 4);
+ // And only scalar values.
+ static_assert(flatbuffers::is_scalar<T>::value, "Unrelated types");
+ return ScalarVector(elems, len, true);
+ }
+
+ template<typename T>
+ size_t FixedTypedVector(const char *key, const T *elems, size_t len) {
+ Key(key);
+ return FixedTypedVector(elems, len);
+ }
+
+ template<typename F> size_t Map(F f) {
+ auto start = StartMap();
+ f();
+ return EndMap(start);
+ }
+ template<typename F, typename T> size_t Map(F f, T &state) {
+ auto start = StartMap();
+ f(state);
+ return EndMap(start);
+ }
+ template<typename F> size_t Map(const char *key, F f) {
+ auto start = StartMap(key);
+ f();
+ return EndMap(start);
+ }
+ template<typename F, typename T> size_t Map(const char *key, F f, T &state) {
+ auto start = StartMap(key);
+ f(state);
+ return EndMap(start);
+ }
+ template<typename T> void Map(const std::map<std::string, T> &map) {
+ auto start = StartMap();
+ for (auto it = map.begin(); it != map.end(); ++it)
+ Add(it->first.c_str(), it->second);
+ EndMap(start);
+ }
+
+ // If you wish to share a value explicitly (a value not shared automatically
+ // through one of the BUILDER_FLAG_SHARE_* flags) you can do so with these
+ // functions. Or if you wish to turn those flags off for performance reasons
+ // and still do some explicit sharing. For example:
+ // builder.IndirectDouble(M_PI);
+ // auto id = builder.LastValue(); // Remember where we stored it.
+ // .. more code goes here ..
+ // builder.ReuseValue(id); // Refers to same double by offset.
+ // LastValue works regardless of whether the value has a key or not.
+ // Works on any data type.
+ struct Value;
+ Value LastValue() { return stack_.back(); }
+ void ReuseValue(Value v) { stack_.push_back(v); }
+ void ReuseValue(const char *key, Value v) {
+ Key(key);
+ ReuseValue(v);
+ }
+
+ // Overloaded Add that tries to call the correct function above.
+ void Add(int8_t i) { Int(i); }
+ void Add(int16_t i) { Int(i); }
+ void Add(int32_t i) { Int(i); }
+ void Add(int64_t i) { Int(i); }
+ void Add(uint8_t u) { UInt(u); }
+ void Add(uint16_t u) { UInt(u); }
+ void Add(uint32_t u) { UInt(u); }
+ void Add(uint64_t u) { UInt(u); }
+ void Add(float f) { Float(f); }
+ void Add(double d) { Double(d); }
+ void Add(bool b) { Bool(b); }
+ void Add(const char *str) { String(str); }
+ void Add(const std::string &str) { String(str); }
+ void Add(const flexbuffers::String &str) { String(str); }
+
+ template<typename T> void Add(const std::vector<T> &vec) { Vector(vec); }
+
+ template<typename T> void Add(const char *key, const T &t) {
+ Key(key);
+ Add(t);
+ }
+
+ template<typename T> void Add(const std::map<std::string, T> &map) {
+ Map(map);
+ }
+
+ template<typename T> void operator+=(const T &t) { Add(t); }
+
+ // This function is useful in combination with the Mutate* functions above.
+ // It forces elements of vectors and maps to have a minimum size, such that
+ // they can later be updated without failing.
+ // Call with no arguments to reset.
+ void ForceMinimumBitWidth(BitWidth bw = BIT_WIDTH_8) {
+ force_min_bit_width_ = bw;
+ }
+
+ void Finish() {
+ // If you hit this assert, you likely have objects that were never included
+ // in a parent. You need to have exactly one root to finish a buffer.
+ // Check your Start/End calls are matched, and all objects are inside
+ // some other object.
+ FLATBUFFERS_ASSERT(stack_.size() == 1);
+
+ // Write root value.
+ auto byte_width = Align(stack_[0].ElemWidth(buf_.size(), 0));
+ WriteAny(stack_[0], byte_width);
+ // Write root type.
+ Write(stack_[0].StoredPackedType(), 1);
+ // Write root size. Normally determined by parent, but root has no parent :)
+ Write(byte_width, 1);
+
+ finished_ = true;
+ }
+
+ private:
+ void Finished() const {
+ // If you get this assert, you're attempting to get access a buffer
+ // which hasn't been finished yet. Be sure to call
+ // Builder::Finish with your root object.
+ FLATBUFFERS_ASSERT(finished_);
+ }
+
+ // Align to prepare for writing a scalar with a certain size.
+ uint8_t Align(BitWidth alignment) {
+ auto byte_width = 1U << alignment;
+ buf_.insert(buf_.end(), flatbuffers::PaddingBytes(buf_.size(), byte_width),
+ 0);
+ return static_cast<uint8_t>(byte_width);
+ }
+
+ void WriteBytes(const void *val, size_t size) {
+ buf_.insert(buf_.end(), reinterpret_cast<const uint8_t *>(val),
+ reinterpret_cast<const uint8_t *>(val) + size);
+ }
+
+ template<typename T> void Write(T val, size_t byte_width) {
+ FLATBUFFERS_ASSERT(sizeof(T) >= byte_width);
+ val = flatbuffers::EndianScalar(val);
+ WriteBytes(&val, byte_width);
+ }
+
+ void WriteDouble(double f, uint8_t byte_width) {
+ switch (byte_width) {
+ case 8: Write(f, byte_width); break;
+ case 4: Write(static_cast<float>(f), byte_width); break;
+ // case 2: Write(static_cast<half>(f), byte_width); break;
+ // case 1: Write(static_cast<quarter>(f), byte_width); break;
+ default: FLATBUFFERS_ASSERT(0);
+ }
+ }
+
+ void WriteOffset(uint64_t o, uint8_t byte_width) {
+ auto reloff = buf_.size() - o;
+ FLATBUFFERS_ASSERT(byte_width == 8 || reloff < 1ULL << (byte_width * 8));
+ Write(reloff, byte_width);
+ }
+
+ template<typename T> void PushIndirect(T val, Type type, BitWidth bit_width) {
+ auto byte_width = Align(bit_width);
+ auto iloc = buf_.size();
+ Write(val, byte_width);
+ stack_.push_back(Value(static_cast<uint64_t>(iloc), type, bit_width));
+ }
+
+ static BitWidth WidthB(size_t byte_width) {
+ switch (byte_width) {
+ case 1: return BIT_WIDTH_8;
+ case 2: return BIT_WIDTH_16;
+ case 4: return BIT_WIDTH_32;
+ case 8: return BIT_WIDTH_64;
+ default: FLATBUFFERS_ASSERT(false); return BIT_WIDTH_64;
+ }
+ }
+
+ template<typename T> static Type GetScalarType() {
+ static_assert(flatbuffers::is_scalar<T>::value, "Unrelated types");
+ return flatbuffers::is_floating_point<T>::value
+ ? FBT_FLOAT
+ : flatbuffers::is_same<T, bool>::value
+ ? FBT_BOOL
+ : (flatbuffers::is_unsigned<T>::value ? FBT_UINT
+ : FBT_INT);
+ }
+
+ public:
+ // This was really intended to be private, except for LastValue/ReuseValue.
+ struct Value {
+ union {
+ int64_t i_;
+ uint64_t u_;
+ double f_;
+ };
+
+ Type type_;
+
+ // For scalars: of itself, for vector: of its elements, for string: length.
+ BitWidth min_bit_width_;
+
+ Value() : i_(0), type_(FBT_NULL), min_bit_width_(BIT_WIDTH_8) {}
+
+ Value(bool b)
+ : u_(static_cast<uint64_t>(b)),
+ type_(FBT_BOOL),
+ min_bit_width_(BIT_WIDTH_8) {}
+
+ Value(int64_t i, Type t, BitWidth bw)
+ : i_(i), type_(t), min_bit_width_(bw) {}
+ Value(uint64_t u, Type t, BitWidth bw)
+ : u_(u), type_(t), min_bit_width_(bw) {}
+
+ Value(float f)
+ : f_(static_cast<double>(f)),
+ type_(FBT_FLOAT),
+ min_bit_width_(BIT_WIDTH_32) {}
+ Value(double f) : f_(f), type_(FBT_FLOAT), min_bit_width_(WidthF(f)) {}
+
+ uint8_t StoredPackedType(BitWidth parent_bit_width_ = BIT_WIDTH_8) const {
+ return PackedType(StoredWidth(parent_bit_width_), type_);
+ }
+
+ BitWidth ElemWidth(size_t buf_size, size_t elem_index) const {
+ if (IsInline(type_)) {
+ return min_bit_width_;
+ } else {
+ // We have an absolute offset, but want to store a relative offset
+ // elem_index elements beyond the current buffer end. Since whether
+ // the relative offset fits in a certain byte_width depends on
+ // the size of the elements before it (and their alignment), we have
+ // to test for each size in turn.
+ for (size_t byte_width = 1;
+ byte_width <= sizeof(flatbuffers::largest_scalar_t);
+ byte_width *= 2) {
+ // Where are we going to write this offset?
+ auto offset_loc = buf_size +
+ flatbuffers::PaddingBytes(buf_size, byte_width) +
+ elem_index * byte_width;
+ // Compute relative offset.
+ auto offset = offset_loc - u_;
+ // Does it fit?
+ auto bit_width = WidthU(offset);
+ if (static_cast<size_t>(static_cast<size_t>(1U) << bit_width) ==
+ byte_width)
+ return bit_width;
+ }
+ FLATBUFFERS_ASSERT(false); // Must match one of the sizes above.
+ return BIT_WIDTH_64;
+ }
+ }
+
+ BitWidth StoredWidth(BitWidth parent_bit_width_ = BIT_WIDTH_8) const {
+ if (IsInline(type_)) {
+ return (std::max)(min_bit_width_, parent_bit_width_);
+ } else {
+ return min_bit_width_;
+ }
+ }
+ };
+
+ private:
+ void WriteAny(const Value &val, uint8_t byte_width) {
+ switch (val.type_) {
+ case FBT_NULL:
+ case FBT_INT: Write(val.i_, byte_width); break;
+ case FBT_BOOL:
+ case FBT_UINT: Write(val.u_, byte_width); break;
+ case FBT_FLOAT: WriteDouble(val.f_, byte_width); break;
+ default: WriteOffset(val.u_, byte_width); break;
+ }
+ }
+
+ size_t CreateBlob(const void *data, size_t len, size_t trailing, Type type) {
+ auto bit_width = WidthU(len);
+ auto byte_width = Align(bit_width);
+ Write<uint64_t>(len, byte_width);
+ auto sloc = buf_.size();
+ WriteBytes(data, len + trailing);
+ stack_.push_back(Value(static_cast<uint64_t>(sloc), type, bit_width));
+ return sloc;
+ }
+
+ template<typename T>
+ size_t ScalarVector(const T *elems, size_t len, bool fixed) {
+ auto vector_type = GetScalarType<T>();
+ auto byte_width = sizeof(T);
+ auto bit_width = WidthB(byte_width);
+ // If you get this assert, you're trying to write a vector with a size
+ // field that is bigger than the scalars you're trying to write (e.g. a
+ // byte vector > 255 elements). For such types, write a "blob" instead.
+ // TODO: instead of asserting, could write vector with larger elements
+ // instead, though that would be wasteful.
+ FLATBUFFERS_ASSERT(WidthU(len) <= bit_width);
+ Align(bit_width);
+ if (!fixed) Write<uint64_t>(len, byte_width);
+ auto vloc = buf_.size();
+ for (size_t i = 0; i < len; i++) Write(elems[i], byte_width);
+ stack_.push_back(Value(static_cast<uint64_t>(vloc),
+ ToTypedVector(vector_type, fixed ? len : 0),
+ bit_width));
+ return vloc;
+ }
+
+ Value CreateVector(size_t start, size_t vec_len, size_t step, bool typed,
+ bool fixed, const Value *keys = nullptr) {
+ FLATBUFFERS_ASSERT(
+ !fixed ||
+ typed); // typed=false, fixed=true combination is not supported.
+ // Figure out smallest bit width we can store this vector with.
+ auto bit_width = (std::max)(force_min_bit_width_, WidthU(vec_len));
+ auto prefix_elems = 1;
+ if (keys) {
+ // If this vector is part of a map, we will pre-fix an offset to the keys
+ // to this vector.
+ bit_width = (std::max)(bit_width, keys->ElemWidth(buf_.size(), 0));
+ prefix_elems += 2;
+ }
+ Type vector_type = FBT_KEY;
+ // Check bit widths and types for all elements.
+ for (size_t i = start; i < stack_.size(); i += step) {
+ auto elem_width =
+ stack_[i].ElemWidth(buf_.size(), i - start + prefix_elems);
+ bit_width = (std::max)(bit_width, elem_width);
+ if (typed) {
+ if (i == start) {
+ vector_type = stack_[i].type_;
+ } else {
+ // If you get this assert, you are writing a typed vector with
+ // elements that are not all the same type.
+ FLATBUFFERS_ASSERT(vector_type == stack_[i].type_);
+ }
+ }
+ }
+ // If you get this assert, your fixed types are not one of:
+ // Int / UInt / Float / Key.
+ FLATBUFFERS_ASSERT(!fixed || IsTypedVectorElementType(vector_type));
+ auto byte_width = Align(bit_width);
+ // Write vector. First the keys width/offset if available, and size.
+ if (keys) {
+ WriteOffset(keys->u_, byte_width);
+ Write<uint64_t>(1ULL << keys->min_bit_width_, byte_width);
+ }
+ if (!fixed) Write<uint64_t>(vec_len, byte_width);
+ // Then the actual data.
+ auto vloc = buf_.size();
+ for (size_t i = start; i < stack_.size(); i += step) {
+ WriteAny(stack_[i], byte_width);
+ }
+ // Then the types.
+ if (!typed) {
+ for (size_t i = start; i < stack_.size(); i += step) {
+ buf_.push_back(stack_[i].StoredPackedType(bit_width));
+ }
+ }
+ return Value(static_cast<uint64_t>(vloc),
+ keys ? FBT_MAP
+ : (typed ? ToTypedVector(vector_type, fixed ? vec_len : 0)
+ : FBT_VECTOR),
+ bit_width);
+ }
+
+ // You shouldn't really be copying instances of this class.
+ Builder(const Builder &);
+ Builder &operator=(const Builder &);
+
+ std::vector<uint8_t> buf_;
+ std::vector<Value> stack_;
+
+ bool finished_;
+ bool has_duplicate_keys_;
+
+ BuilderFlag flags_;
+
+ BitWidth force_min_bit_width_;
+
+ struct KeyOffsetCompare {
+ explicit KeyOffsetCompare(const std::vector<uint8_t> &buf) : buf_(&buf) {}
+ bool operator()(size_t a, size_t b) const {
+ auto stra =
+ reinterpret_cast<const char *>(flatbuffers::vector_data(*buf_) + a);
+ auto strb =
+ reinterpret_cast<const char *>(flatbuffers::vector_data(*buf_) + b);
+ return strcmp(stra, strb) < 0;
+ }
+ const std::vector<uint8_t> *buf_;
+ };
+
+ typedef std::pair<size_t, size_t> StringOffset;
+ struct StringOffsetCompare {
+ explicit StringOffsetCompare(const std::vector<uint8_t> &buf)
+ : buf_(&buf) {}
+ bool operator()(const StringOffset &a, const StringOffset &b) const {
+ auto stra = reinterpret_cast<const char *>(
+ flatbuffers::vector_data(*buf_) + a.first);
+ auto strb = reinterpret_cast<const char *>(
+ flatbuffers::vector_data(*buf_) + b.first);
+ return strncmp(stra, strb, (std::min)(a.second, b.second) + 1) < 0;
+ }
+ const std::vector<uint8_t> *buf_;
+ };
+
+ typedef std::set<size_t, KeyOffsetCompare> KeyOffsetMap;
+ typedef std::set<StringOffset, StringOffsetCompare> StringOffsetMap;
+
+ KeyOffsetMap key_pool;
+ StringOffsetMap string_pool;
+};
+
+} // namespace flexbuffers
+
+#if defined(_MSC_VER)
+# pragma warning(pop)
+#endif
+
+#endif // FLATBUFFERS_FLEXBUFFERS_H_
diff --git a/contrib/libs/flatbuffers/include/flatbuffers/hash.h b/contrib/libs/flatbuffers/include/flatbuffers/hash.h
new file mode 100644
index 0000000000..52cc628cdf
--- /dev/null
+++ b/contrib/libs/flatbuffers/include/flatbuffers/hash.h
@@ -0,0 +1,127 @@
+/*
+ * 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_HASH_H_
+#define FLATBUFFERS_HASH_H_
+
+#include <cstdint>
+#include <cstring>
+
+#include "flatbuffers.h"
+
+namespace flatbuffers {
+
+template<typename T> struct FnvTraits {
+ static const T kFnvPrime;
+ static const T kOffsetBasis;
+};
+
+template<> struct FnvTraits<uint32_t> {
+ static const uint32_t kFnvPrime = 0x01000193;
+ static const uint32_t kOffsetBasis = 0x811C9DC5;
+};
+
+template<> struct FnvTraits<uint64_t> {
+ static const uint64_t kFnvPrime = 0x00000100000001b3ULL;
+ static const uint64_t kOffsetBasis = 0xcbf29ce484222645ULL;
+};
+
+template<typename T> T HashFnv1(const char *input) {
+ T hash = FnvTraits<T>::kOffsetBasis;
+ for (const char *c = input; *c; ++c) {
+ hash *= FnvTraits<T>::kFnvPrime;
+ hash ^= static_cast<unsigned char>(*c);
+ }
+ return hash;
+}
+
+template<typename T> T HashFnv1a(const char *input) {
+ T hash = FnvTraits<T>::kOffsetBasis;
+ for (const char *c = input; *c; ++c) {
+ hash ^= static_cast<unsigned char>(*c);
+ hash *= FnvTraits<T>::kFnvPrime;
+ }
+ return hash;
+}
+
+template<> inline uint16_t HashFnv1<uint16_t>(const char *input) {
+ uint32_t hash = HashFnv1<uint32_t>(input);
+ return (hash >> 16) ^ (hash & 0xffff);
+}
+
+template<> inline uint16_t HashFnv1a<uint16_t>(const char *input) {
+ uint32_t hash = HashFnv1a<uint32_t>(input);
+ return (hash >> 16) ^ (hash & 0xffff);
+}
+
+template<typename T> struct NamedHashFunction {
+ const char *name;
+
+ typedef T (*HashFunction)(const char *);
+ HashFunction function;
+};
+
+const NamedHashFunction<uint16_t> kHashFunctions16[] = {
+ { "fnv1_16", HashFnv1<uint16_t> },
+ { "fnv1a_16", HashFnv1a<uint16_t> },
+};
+
+const NamedHashFunction<uint32_t> kHashFunctions32[] = {
+ { "fnv1_32", HashFnv1<uint32_t> },
+ { "fnv1a_32", HashFnv1a<uint32_t> },
+};
+
+const NamedHashFunction<uint64_t> kHashFunctions64[] = {
+ { "fnv1_64", HashFnv1<uint64_t> },
+ { "fnv1a_64", HashFnv1a<uint64_t> },
+};
+
+inline NamedHashFunction<uint16_t>::HashFunction FindHashFunction16(
+ const char *name) {
+ std::size_t size = sizeof(kHashFunctions16) / sizeof(kHashFunctions16[0]);
+ for (std::size_t i = 0; i < size; ++i) {
+ if (std::strcmp(name, kHashFunctions16[i].name) == 0) {
+ return kHashFunctions16[i].function;
+ }
+ }
+ return nullptr;
+}
+
+inline NamedHashFunction<uint32_t>::HashFunction FindHashFunction32(
+ const char *name) {
+ std::size_t size = sizeof(kHashFunctions32) / sizeof(kHashFunctions32[0]);
+ for (std::size_t i = 0; i < size; ++i) {
+ if (std::strcmp(name, kHashFunctions32[i].name) == 0) {
+ return kHashFunctions32[i].function;
+ }
+ }
+ return nullptr;
+}
+
+inline NamedHashFunction<uint64_t>::HashFunction FindHashFunction64(
+ const char *name) {
+ std::size_t size = sizeof(kHashFunctions64) / sizeof(kHashFunctions64[0]);
+ for (std::size_t i = 0; i < size; ++i) {
+ if (std::strcmp(name, kHashFunctions64[i].name) == 0) {
+ return kHashFunctions64[i].function;
+ }
+ }
+ return nullptr;
+}
+
+} // namespace flatbuffers
+
+#endif // FLATBUFFERS_HASH_H_
diff --git a/contrib/libs/flatbuffers/include/flatbuffers/idl.h b/contrib/libs/flatbuffers/include/flatbuffers/idl.h
new file mode 100644
index 0000000000..a82ff8a694
--- /dev/null
+++ b/contrib/libs/flatbuffers/include/flatbuffers/idl.h
@@ -0,0 +1,1208 @@
+/*
+ * 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 <map>
+#include <memory>
+#include <stack>
+
+#include "base.h"
+#include "flatbuffers.h"
+#include "flexbuffers.h"
+#include "hash.h"
+#include "reflection.h"
+
+#if !defined(FLATBUFFERS_CPP98_STL)
+# include <functional>
+#endif // !defined(FLATBUFFERS_CPP98_STL)
+
+// 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.
+// - Rust type.
+// - Kotlin 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) {
+ 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) {
+ vector_emplace_back(&vec, 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) {}
+
+ 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;
+};
+
+struct FieldDef : public Definition {
+ FieldDef()
+ : deprecated(false),
+ key(false),
+ shared(false),
+ native_inline(false),
+ flexbuffer(false),
+ presence(kDefault),
+ nested_flatbuffer(NULL),
+ 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(const Parser &parser, const reflection::EnumVal *val);
+
+ 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;
+
+ 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 IsUnion(const Type &type) {
+ return type.enum_def != nullptr && type.enum_def->is_union;
+}
+
+inline bool IsVector(const Type &type) {
+ return type.base_type == BASE_TYPE_VECTOR;
+}
+
+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;
+};
+
+// Container of options that may apply to any of the source/text generators.
+struct IDLOptions {
+ 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 output_enum_identifiers;
+ bool prefixed_enums;
+ bool scoped_enums;
+ 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;
+ bool cpp_direct_copy;
+ bool gen_nullable;
+ bool java_checkerframework;
+ bool gen_generated;
+ 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_include_path;
+ bool binary_schema_comments;
+ bool binary_schema_builtins;
+ bool binary_schema_gen_embed;
+ std::string go_import;
+ std::string go_namespace;
+ 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;
+
+ // 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,
+ kCppYandexMapsIter = 1 << 17,
+ kMAX
+ };
+
+ Language lang;
+
+ enum MiniReflect { kNone, kTypes, kTypesAndNames };
+
+ MiniReflect mini_reflect;
+
+ // If set, require all fields in a table to be explicitly numbered.
+ bool require_explicit_ids;
+
+ // 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),
+ output_enum_identifiers(true),
+ prefixed_enums(true),
+ scoped_enums(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_direct_copy(true),
+ gen_nullable(false),
+ java_checkerframework(false),
+ gen_generated(false),
+ object_suffix("T"),
+ union_value_namespacing(true),
+ allow_non_utf8(false),
+ natural_utf8(false),
+ keep_include_path(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),
+ lang(IDLOptions::kJava),
+ mini_reflect(IDLOptions::kNone),
+ require_explicit_ids(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()
+ : cursor_(nullptr),
+ line_start_(nullptr),
+ line_(0),
+ token_(-1),
+ attr_is_trivial_ascii_string_(true) {}
+
+ protected:
+ void ResetState(const char *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 *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),
+ 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);
+
+ // 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);
+
+ 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);
+ 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();
+ FLATBUFFERS_CHECKED_ERROR ParseService();
+ FLATBUFFERS_CHECKED_ERROR ParseProtoFields(StructDef *struct_def,
+ bool isextend, bool inside_oneof);
+ 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 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);
+
+ 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<std::string>> files_included_per_file_;
+ std::vector<std::string> native_included_files_;
+
+ std::map<std::string, bool> known_attributes_;
+
+ IDLOptions opts;
+ bool uses_flexbuffers_;
+
+ uint64_t advanced_features_;
+
+ private:
+ const char *source_;
+
+ std::string file_being_parsed_;
+
+ std::vector<std::pair<Value, FieldDef *>> field_stack_;
+
+ int anonymous_counter_;
+ int parse_depth_counter_; // stack-overflow guard
+};
+
+// Utility functions for multiple generators:
+
+extern std::string MakeCamel(const std::string &in, bool first = true);
+
+extern std::string MakeScreamingCamel(const std::string &in);
+
+// 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 C++ header for reading with templated file iterator from
+// the definitions in the Parser object.
+// See idl_gen_cpp_yandex_maps_iter.cpp.
+extern std::string GenerateCPPYandexMapsIter(const Parser &parser,
+ const std::string &include_guard_ident);
+extern bool GenerateCPPYandexMapsIter(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 JavaCSharpMakeRule(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);
+} // namespace flatbuffers
+
+#endif // FLATBUFFERS_IDL_H_
diff --git a/contrib/libs/flatbuffers/include/flatbuffers/reflection.h b/contrib/libs/flatbuffers/include/flatbuffers/reflection.h
new file mode 100644
index 0000000000..d268a3ffea
--- /dev/null
+++ b/contrib/libs/flatbuffers/include/flatbuffers/reflection.h
@@ -0,0 +1,502 @@
+/*
+ * 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 "reflection_generated.h"
+
+// Helper functionality for reflection.
+
+namespace flatbuffers {
+
+// ------------------------- GETTERS -------------------------
+
+inline bool IsScalar(reflection::BaseType t) {
+ return t >= reflection::UType && t <= reflection::Double;
+}
+inline bool IsInteger(reflection::BaseType t) {
+ return t >= reflection::UType && t <= reflection::ULong;
+}
+inline bool IsFloat(reflection::BaseType t) {
+ return t == reflection::Float || t == reflection::Double;
+}
+inline bool IsLong(reflection::BaseType t) {
+ return t == reflection::Long || t == reflection::ULong;
+}
+
+// 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, // None
+ 1, // UType
+ 1, // Bool
+ 1, // Byte
+ 1, // UByte
+ 2, // Short
+ 2, // UShort
+ 4, // Int
+ 4, // UInt
+ 8, // Long
+ 8, // ULong
+ 4, // Float
+ 8, // Double
+ 4, // String
+ 4, // Vector
+ 4, // Obj
+ 4, // Union
+ 0, // Array. Only used in structs. 0 was chosen to prevent out-of-bounds
+ // errors.
+
+ 0 // MaxBaseType. This must be kept the last entry in this array.
+ };
+ static_assert(sizeof(sizes) / sizeof(size_t) == reflection::MaxBaseType + 1,
+ "Size of sizes[] array does not match the count of BaseType "
+ "enum values.");
+ 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's default, if you know it's an integer, and its exact type.
+template<typename T> T GetFieldDefaultI(const reflection::Field &field) {
+ FLATBUFFERS_ASSERT(sizeof(T) == GetTypeSize(field.type()->base_type()));
+ return static_cast<T>(field.default_integer());
+}
+
+// Get a field's default, if you know it's floating point and its exact type.
+template<typename T> T GetFieldDefaultF(const reflection::Field &field) {
+ FLATBUFFERS_ASSERT(sizeof(T) == GetTypeSize(field.type()->base_type()));
+ return static_cast<T>(field.default_real());
+}
+
+// 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) {
+ FLATBUFFERS_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) {
+ FLATBUFFERS_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) {
+ FLATBUFFERS_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) {
+ FLATBUFFERS_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) {
+ FLATBUFFERS_ASSERT(field.type()->base_type() == reflection::Obj ||
+ field.type()->base_type() == reflection::Union);
+ return table.GetPointer<Table *>(field.offset());
+}
+
+// Get a field, if you know it's a struct.
+inline const Struct *GetFieldStruct(const Table &table,
+ const reflection::Field &field) {
+ // TODO: This does NOT check if the field is a table or struct, but we'd need
+ // access to the schema to check the is_struct flag.
+ FLATBUFFERS_ASSERT(field.type()->base_type() == reflection::Obj);
+ return table.GetStruct<const Struct *>(field.offset());
+}
+
+// Get a structure's field, if you know it's a struct.
+inline const Struct *GetFieldStruct(const Struct &structure,
+ const reflection::Field &field) {
+ FLATBUFFERS_ASSERT(field.type()->base_type() == reflection::Obj);
+ return structure.GetStruct<const Struct *>(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 reinterpret_cast<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) {
+ return reinterpret_cast<T *>(vec->Data() + elem_size * i);
+}
+
+// Similarly, for elements of tables.
+template<typename T>
+T *GetAnyFieldAddressOf(const Table &table, const reflection::Field &field) {
+ return reinterpret_cast<T *>(table.GetAddressOf(field.offset()));
+}
+
+// Similarly, for elements of structs.
+template<typename T>
+T *GetAnyFieldAddressOf(const Struct &st, const reflection::Field &field) {
+ return reinterpret_cast<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) {
+ reflection::BaseType type = field.type()->base_type();
+ if (!IsScalar(type)) { return false; }
+ FLATBUFFERS_ASSERT(sizeof(T) == GetTypeSize(type));
+ T def;
+ if (IsInteger(type)) {
+ def = GetFieldDefaultI<T>(field);
+ } else {
+ FLATBUFFERS_ASSERT(IsFloat(type));
+ def = GetFieldDefaultF<T>(field);
+ }
+ return table->SetField(field.offset(), val, def);
+}
+
+// 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 val == GetFieldDefaultI<int64_t>(field);
+ 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 val == GetFieldDefaultF<double>(field);
+ 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 *>(flatbuffers::vector_data(vec))),
+ vec_(vec) {}
+
+ T *operator*() const {
+ return reinterpret_cast<T *>(
+ reinterpret_cast<uint8_t *>(flatbuffers::vector_data(vec_)) + offset_);
+ }
+ T *operator->() const { return operator*(); }
+
+ 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());
+ FLATBUFFERS_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);
+
+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 = flatbuffers::is_scalar<T>::value;
+ if (is_scalar) {
+ WriteScalar(loc, val);
+ } else { // struct
+ *reinterpret_cast<T *>(loc) = val;
+ }
+ }
+}
+
+// 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) {
+ FLATBUFFERS_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, uoffset_t max_depth = 64,
+ uoffset_t max_tables = 1000000);
+
+} // namespace flatbuffers
+
+#endif // FLATBUFFERS_REFLECTION_H_
diff --git a/contrib/libs/flatbuffers/include/flatbuffers/reflection_generated.h b/contrib/libs/flatbuffers/include/flatbuffers/reflection_generated.h
new file mode 100644
index 0000000000..93dc4b88b7
--- /dev/null
+++ b/contrib/libs/flatbuffers/include/flatbuffers/reflection_generated.h
@@ -0,0 +1,1278 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+
+#ifndef FLATBUFFERS_GENERATED_REFLECTION_REFLECTION_H_
+#define FLATBUFFERS_GENERATED_REFLECTION_REFLECTION_H_
+
+#include "flatbuffers.h"
+
+namespace reflection {
+
+struct Type;
+struct TypeBuilder;
+
+struct KeyValue;
+struct KeyValueBuilder;
+
+struct EnumVal;
+struct EnumValBuilder;
+
+struct Enum;
+struct EnumBuilder;
+
+struct Field;
+struct FieldBuilder;
+
+struct Object;
+struct ObjectBuilder;
+
+struct RPCCall;
+struct RPCCallBuilder;
+
+struct Service;
+struct ServiceBuilder;
+
+struct Schema;
+struct SchemaBuilder;
+
+enum BaseType {
+ None = 0,
+ UType = 1,
+ Bool = 2,
+ Byte = 3,
+ UByte = 4,
+ Short = 5,
+ UShort = 6,
+ Int = 7,
+ UInt = 8,
+ Long = 9,
+ ULong = 10,
+ Float = 11,
+ Double = 12,
+ String = 13,
+ Vector = 14,
+ Obj = 15,
+ Union = 16,
+ Array = 17,
+ MaxBaseType = 18
+};
+
+inline const BaseType (&EnumValuesBaseType())[19] {
+ static const BaseType values[] = {
+ None,
+ UType,
+ Bool,
+ Byte,
+ UByte,
+ Short,
+ UShort,
+ Int,
+ UInt,
+ Long,
+ ULong,
+ Float,
+ Double,
+ String,
+ Vector,
+ Obj,
+ Union,
+ Array,
+ MaxBaseType
+ };
+ return values;
+}
+
+inline const char * const *EnumNamesBaseType() {
+ static const char * const names[20] = {
+ "None",
+ "UType",
+ "Bool",
+ "Byte",
+ "UByte",
+ "Short",
+ "UShort",
+ "Int",
+ "UInt",
+ "Long",
+ "ULong",
+ "Float",
+ "Double",
+ "String",
+ "Vector",
+ "Obj",
+ "Union",
+ "Array",
+ "MaxBaseType",
+ nullptr
+ };
+ return names;
+}
+
+inline const char *EnumNameBaseType(BaseType e) {
+ if (flatbuffers::IsOutRange(e, None, MaxBaseType)) return "";
+ const size_t index = static_cast<size_t>(e);
+ return EnumNamesBaseType()[index];
+}
+
+enum AdvancedFeatures {
+ AdvancedArrayFeatures = 1ULL,
+ AdvancedUnionFeatures = 2ULL,
+ OptionalScalars = 4ULL,
+ DefaultVectorsAndStrings = 8ULL
+};
+
+inline const AdvancedFeatures (&EnumValuesAdvancedFeatures())[4] {
+ static const AdvancedFeatures values[] = {
+ AdvancedArrayFeatures,
+ AdvancedUnionFeatures,
+ OptionalScalars,
+ DefaultVectorsAndStrings
+ };
+ return values;
+}
+
+inline const char * const *EnumNamesAdvancedFeatures() {
+ static const char * const names[9] = {
+ "AdvancedArrayFeatures",
+ "AdvancedUnionFeatures",
+ "",
+ "OptionalScalars",
+ "",
+ "",
+ "",
+ "DefaultVectorsAndStrings",
+ nullptr
+ };
+ return names;
+}
+
+inline const char *EnumNameAdvancedFeatures(AdvancedFeatures e) {
+ if (flatbuffers::IsOutRange(e, AdvancedArrayFeatures, DefaultVectorsAndStrings)) return "";
+ const size_t index = static_cast<size_t>(e) - static_cast<size_t>(AdvancedArrayFeatures);
+ return EnumNamesAdvancedFeatures()[index];
+}
+
+struct Type FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
+ typedef TypeBuilder Builder;
+ enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
+ VT_BASE_TYPE = 4,
+ VT_ELEMENT = 6,
+ VT_INDEX = 8,
+ VT_FIXED_LENGTH = 10
+ };
+ reflection::BaseType base_type() const {
+ return static_cast<reflection::BaseType>(GetField<int8_t>(VT_BASE_TYPE, 0));
+ }
+ reflection::BaseType element() const {
+ return static_cast<reflection::BaseType>(GetField<int8_t>(VT_ELEMENT, 0));
+ }
+ int32_t index() const {
+ return GetField<int32_t>(VT_INDEX, -1);
+ }
+ uint16_t fixed_length() const {
+ return GetField<uint16_t>(VT_FIXED_LENGTH, 0);
+ }
+ bool Verify(flatbuffers::Verifier &verifier) const {
+ return VerifyTableStart(verifier) &&
+ VerifyField<int8_t>(verifier, VT_BASE_TYPE) &&
+ VerifyField<int8_t>(verifier, VT_ELEMENT) &&
+ VerifyField<int32_t>(verifier, VT_INDEX) &&
+ VerifyField<uint16_t>(verifier, VT_FIXED_LENGTH) &&
+ verifier.EndTable();
+ }
+};
+
+struct TypeBuilder {
+ typedef Type Table;
+ flatbuffers::FlatBufferBuilder &fbb_;
+ flatbuffers::uoffset_t start_;
+ void add_base_type(reflection::BaseType base_type) {
+ fbb_.AddElement<int8_t>(Type::VT_BASE_TYPE, static_cast<int8_t>(base_type), 0);
+ }
+ void add_element(reflection::BaseType element) {
+ fbb_.AddElement<int8_t>(Type::VT_ELEMENT, static_cast<int8_t>(element), 0);
+ }
+ void add_index(int32_t index) {
+ fbb_.AddElement<int32_t>(Type::VT_INDEX, index, -1);
+ }
+ void add_fixed_length(uint16_t fixed_length) {
+ fbb_.AddElement<uint16_t>(Type::VT_FIXED_LENGTH, fixed_length, 0);
+ }
+ explicit TypeBuilder(flatbuffers::FlatBufferBuilder &_fbb)
+ : fbb_(_fbb) {
+ start_ = fbb_.StartTable();
+ }
+ flatbuffers::Offset<Type> Finish() {
+ const auto end = fbb_.EndTable(start_);
+ auto o = flatbuffers::Offset<Type>(end);
+ return o;
+ }
+};
+
+inline flatbuffers::Offset<Type> CreateType(
+ flatbuffers::FlatBufferBuilder &_fbb,
+ reflection::BaseType base_type = reflection::None,
+ reflection::BaseType element = reflection::None,
+ int32_t index = -1,
+ uint16_t fixed_length = 0) {
+ TypeBuilder builder_(_fbb);
+ builder_.add_index(index);
+ builder_.add_fixed_length(fixed_length);
+ builder_.add_element(element);
+ builder_.add_base_type(base_type);
+ return builder_.Finish();
+}
+
+struct KeyValue FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
+ typedef KeyValueBuilder Builder;
+ enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
+ VT_KEY = 4,
+ VT_VALUE = 6
+ };
+ const flatbuffers::String *key() const {
+ return GetPointer<const flatbuffers::String *>(VT_KEY);
+ }
+ bool KeyCompareLessThan(const KeyValue *o) const {
+ return *key() < *o->key();
+ }
+ int KeyCompareWithValue(const char *val) const {
+ return strcmp(key()->c_str(), val);
+ }
+ const flatbuffers::String *value() const {
+ return GetPointer<const flatbuffers::String *>(VT_VALUE);
+ }
+ bool Verify(flatbuffers::Verifier &verifier) const {
+ return VerifyTableStart(verifier) &&
+ VerifyOffsetRequired(verifier, VT_KEY) &&
+ verifier.VerifyString(key()) &&
+ VerifyOffset(verifier, VT_VALUE) &&
+ verifier.VerifyString(value()) &&
+ verifier.EndTable();
+ }
+};
+
+struct KeyValueBuilder {
+ typedef KeyValue Table;
+ flatbuffers::FlatBufferBuilder &fbb_;
+ flatbuffers::uoffset_t start_;
+ void add_key(flatbuffers::Offset<flatbuffers::String> key) {
+ fbb_.AddOffset(KeyValue::VT_KEY, key);
+ }
+ void add_value(flatbuffers::Offset<flatbuffers::String> value) {
+ fbb_.AddOffset(KeyValue::VT_VALUE, value);
+ }
+ explicit KeyValueBuilder(flatbuffers::FlatBufferBuilder &_fbb)
+ : fbb_(_fbb) {
+ start_ = fbb_.StartTable();
+ }
+ flatbuffers::Offset<KeyValue> Finish() {
+ const auto end = fbb_.EndTable(start_);
+ auto o = flatbuffers::Offset<KeyValue>(end);
+ fbb_.Required(o, KeyValue::VT_KEY);
+ return o;
+ }
+};
+
+inline flatbuffers::Offset<KeyValue> CreateKeyValue(
+ flatbuffers::FlatBufferBuilder &_fbb,
+ flatbuffers::Offset<flatbuffers::String> key = 0,
+ flatbuffers::Offset<flatbuffers::String> value = 0) {
+ KeyValueBuilder builder_(_fbb);
+ builder_.add_value(value);
+ builder_.add_key(key);
+ return builder_.Finish();
+}
+
+inline flatbuffers::Offset<KeyValue> CreateKeyValueDirect(
+ flatbuffers::FlatBufferBuilder &_fbb,
+ const char *key = nullptr,
+ const char *value = nullptr) {
+ auto key__ = key ? _fbb.CreateString(key) : 0;
+ auto value__ = value ? _fbb.CreateString(value) : 0;
+ return reflection::CreateKeyValue(
+ _fbb,
+ key__,
+ value__);
+}
+
+struct EnumVal FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
+ typedef EnumValBuilder Builder;
+ enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
+ VT_NAME = 4,
+ VT_VALUE = 6,
+ VT_OBJECT = 8,
+ VT_UNION_TYPE = 10,
+ VT_DOCUMENTATION = 12
+ };
+ const flatbuffers::String *name() const {
+ return GetPointer<const flatbuffers::String *>(VT_NAME);
+ }
+ int64_t value() const {
+ return GetField<int64_t>(VT_VALUE, 0);
+ }
+ bool KeyCompareLessThan(const EnumVal *o) const {
+ return value() < o->value();
+ }
+ int KeyCompareWithValue(int64_t val) const {
+ return static_cast<int>(value() > val) - static_cast<int>(value() < val);
+ }
+ const reflection::Object *object() const {
+ return GetPointer<const reflection::Object *>(VT_OBJECT);
+ }
+ const reflection::Type *union_type() const {
+ return GetPointer<const reflection::Type *>(VT_UNION_TYPE);
+ }
+ const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *documentation() const {
+ return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *>(VT_DOCUMENTATION);
+ }
+ bool Verify(flatbuffers::Verifier &verifier) const {
+ return VerifyTableStart(verifier) &&
+ VerifyOffsetRequired(verifier, VT_NAME) &&
+ verifier.VerifyString(name()) &&
+ VerifyField<int64_t>(verifier, VT_VALUE) &&
+ VerifyOffset(verifier, VT_OBJECT) &&
+ verifier.VerifyTable(object()) &&
+ VerifyOffset(verifier, VT_UNION_TYPE) &&
+ verifier.VerifyTable(union_type()) &&
+ VerifyOffset(verifier, VT_DOCUMENTATION) &&
+ verifier.VerifyVector(documentation()) &&
+ verifier.VerifyVectorOfStrings(documentation()) &&
+ verifier.EndTable();
+ }
+};
+
+struct EnumValBuilder {
+ typedef EnumVal Table;
+ flatbuffers::FlatBufferBuilder &fbb_;
+ flatbuffers::uoffset_t start_;
+ void add_name(flatbuffers::Offset<flatbuffers::String> name) {
+ fbb_.AddOffset(EnumVal::VT_NAME, name);
+ }
+ void add_value(int64_t value) {
+ fbb_.AddElement<int64_t>(EnumVal::VT_VALUE, value, 0);
+ }
+ void add_object(flatbuffers::Offset<reflection::Object> object) {
+ fbb_.AddOffset(EnumVal::VT_OBJECT, object);
+ }
+ void add_union_type(flatbuffers::Offset<reflection::Type> union_type) {
+ fbb_.AddOffset(EnumVal::VT_UNION_TYPE, union_type);
+ }
+ void add_documentation(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> documentation) {
+ fbb_.AddOffset(EnumVal::VT_DOCUMENTATION, documentation);
+ }
+ explicit EnumValBuilder(flatbuffers::FlatBufferBuilder &_fbb)
+ : fbb_(_fbb) {
+ start_ = fbb_.StartTable();
+ }
+ flatbuffers::Offset<EnumVal> Finish() {
+ const auto end = fbb_.EndTable(start_);
+ auto o = flatbuffers::Offset<EnumVal>(end);
+ fbb_.Required(o, EnumVal::VT_NAME);
+ return o;
+ }
+};
+
+inline flatbuffers::Offset<EnumVal> CreateEnumVal(
+ flatbuffers::FlatBufferBuilder &_fbb,
+ flatbuffers::Offset<flatbuffers::String> name = 0,
+ int64_t value = 0,
+ flatbuffers::Offset<reflection::Object> object = 0,
+ flatbuffers::Offset<reflection::Type> union_type = 0,
+ flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> documentation = 0) {
+ EnumValBuilder builder_(_fbb);
+ builder_.add_value(value);
+ builder_.add_documentation(documentation);
+ builder_.add_union_type(union_type);
+ builder_.add_object(object);
+ builder_.add_name(name);
+ return builder_.Finish();
+}
+
+inline flatbuffers::Offset<EnumVal> CreateEnumValDirect(
+ flatbuffers::FlatBufferBuilder &_fbb,
+ const char *name = nullptr,
+ int64_t value = 0,
+ flatbuffers::Offset<reflection::Object> object = 0,
+ flatbuffers::Offset<reflection::Type> union_type = 0,
+ const std::vector<flatbuffers::Offset<flatbuffers::String>> *documentation = nullptr) {
+ auto name__ = name ? _fbb.CreateString(name) : 0;
+ auto documentation__ = documentation ? _fbb.CreateVector<flatbuffers::Offset<flatbuffers::String>>(*documentation) : 0;
+ return reflection::CreateEnumVal(
+ _fbb,
+ name__,
+ value,
+ object,
+ union_type,
+ documentation__);
+}
+
+struct Enum FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
+ typedef EnumBuilder Builder;
+ enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
+ VT_NAME = 4,
+ VT_VALUES = 6,
+ VT_IS_UNION = 8,
+ VT_UNDERLYING_TYPE = 10,
+ VT_ATTRIBUTES = 12,
+ VT_DOCUMENTATION = 14
+ };
+ const flatbuffers::String *name() const {
+ return GetPointer<const flatbuffers::String *>(VT_NAME);
+ }
+ bool KeyCompareLessThan(const Enum *o) const {
+ return *name() < *o->name();
+ }
+ int KeyCompareWithValue(const char *val) const {
+ return strcmp(name()->c_str(), val);
+ }
+ const flatbuffers::Vector<flatbuffers::Offset<reflection::EnumVal>> *values() const {
+ return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<reflection::EnumVal>> *>(VT_VALUES);
+ }
+ bool is_union() const {
+ return GetField<uint8_t>(VT_IS_UNION, 0) != 0;
+ }
+ const reflection::Type *underlying_type() const {
+ return GetPointer<const reflection::Type *>(VT_UNDERLYING_TYPE);
+ }
+ const flatbuffers::Vector<flatbuffers::Offset<reflection::KeyValue>> *attributes() const {
+ return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<reflection::KeyValue>> *>(VT_ATTRIBUTES);
+ }
+ const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *documentation() const {
+ return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *>(VT_DOCUMENTATION);
+ }
+ bool Verify(flatbuffers::Verifier &verifier) const {
+ return VerifyTableStart(verifier) &&
+ VerifyOffsetRequired(verifier, VT_NAME) &&
+ verifier.VerifyString(name()) &&
+ VerifyOffsetRequired(verifier, VT_VALUES) &&
+ verifier.VerifyVector(values()) &&
+ verifier.VerifyVectorOfTables(values()) &&
+ VerifyField<uint8_t>(verifier, VT_IS_UNION) &&
+ VerifyOffsetRequired(verifier, VT_UNDERLYING_TYPE) &&
+ verifier.VerifyTable(underlying_type()) &&
+ VerifyOffset(verifier, VT_ATTRIBUTES) &&
+ verifier.VerifyVector(attributes()) &&
+ verifier.VerifyVectorOfTables(attributes()) &&
+ VerifyOffset(verifier, VT_DOCUMENTATION) &&
+ verifier.VerifyVector(documentation()) &&
+ verifier.VerifyVectorOfStrings(documentation()) &&
+ verifier.EndTable();
+ }
+};
+
+struct EnumBuilder {
+ typedef Enum Table;
+ flatbuffers::FlatBufferBuilder &fbb_;
+ flatbuffers::uoffset_t start_;
+ void add_name(flatbuffers::Offset<flatbuffers::String> name) {
+ fbb_.AddOffset(Enum::VT_NAME, name);
+ }
+ void add_values(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<reflection::EnumVal>>> values) {
+ fbb_.AddOffset(Enum::VT_VALUES, values);
+ }
+ void add_is_union(bool is_union) {
+ fbb_.AddElement<uint8_t>(Enum::VT_IS_UNION, static_cast<uint8_t>(is_union), 0);
+ }
+ void add_underlying_type(flatbuffers::Offset<reflection::Type> underlying_type) {
+ fbb_.AddOffset(Enum::VT_UNDERLYING_TYPE, underlying_type);
+ }
+ void add_attributes(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<reflection::KeyValue>>> attributes) {
+ fbb_.AddOffset(Enum::VT_ATTRIBUTES, attributes);
+ }
+ void add_documentation(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> documentation) {
+ fbb_.AddOffset(Enum::VT_DOCUMENTATION, documentation);
+ }
+ explicit EnumBuilder(flatbuffers::FlatBufferBuilder &_fbb)
+ : fbb_(_fbb) {
+ start_ = fbb_.StartTable();
+ }
+ flatbuffers::Offset<Enum> Finish() {
+ const auto end = fbb_.EndTable(start_);
+ auto o = flatbuffers::Offset<Enum>(end);
+ fbb_.Required(o, Enum::VT_NAME);
+ fbb_.Required(o, Enum::VT_VALUES);
+ fbb_.Required(o, Enum::VT_UNDERLYING_TYPE);
+ return o;
+ }
+};
+
+inline flatbuffers::Offset<Enum> CreateEnum(
+ flatbuffers::FlatBufferBuilder &_fbb,
+ flatbuffers::Offset<flatbuffers::String> name = 0,
+ flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<reflection::EnumVal>>> values = 0,
+ bool is_union = false,
+ flatbuffers::Offset<reflection::Type> underlying_type = 0,
+ flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<reflection::KeyValue>>> attributes = 0,
+ flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> documentation = 0) {
+ EnumBuilder builder_(_fbb);
+ builder_.add_documentation(documentation);
+ builder_.add_attributes(attributes);
+ builder_.add_underlying_type(underlying_type);
+ builder_.add_values(values);
+ builder_.add_name(name);
+ builder_.add_is_union(is_union);
+ return builder_.Finish();
+}
+
+inline flatbuffers::Offset<Enum> CreateEnumDirect(
+ flatbuffers::FlatBufferBuilder &_fbb,
+ const char *name = nullptr,
+ std::vector<flatbuffers::Offset<reflection::EnumVal>> *values = nullptr,
+ bool is_union = false,
+ flatbuffers::Offset<reflection::Type> underlying_type = 0,
+ std::vector<flatbuffers::Offset<reflection::KeyValue>> *attributes = nullptr,
+ const std::vector<flatbuffers::Offset<flatbuffers::String>> *documentation = nullptr) {
+ auto name__ = name ? _fbb.CreateString(name) : 0;
+ auto values__ = values ? _fbb.CreateVectorOfSortedTables<reflection::EnumVal>(values) : 0;
+ auto attributes__ = attributes ? _fbb.CreateVectorOfSortedTables<reflection::KeyValue>(attributes) : 0;
+ auto documentation__ = documentation ? _fbb.CreateVector<flatbuffers::Offset<flatbuffers::String>>(*documentation) : 0;
+ return reflection::CreateEnum(
+ _fbb,
+ name__,
+ values__,
+ is_union,
+ underlying_type,
+ attributes__,
+ documentation__);
+}
+
+struct Field FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
+ typedef FieldBuilder Builder;
+ enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
+ VT_NAME = 4,
+ VT_TYPE = 6,
+ VT_ID = 8,
+ VT_OFFSET = 10,
+ VT_DEFAULT_INTEGER = 12,
+ VT_DEFAULT_REAL = 14,
+ VT_DEPRECATED = 16,
+ VT_REQUIRED = 18,
+ VT_KEY = 20,
+ VT_ATTRIBUTES = 22,
+ VT_DOCUMENTATION = 24,
+ VT_OPTIONAL = 26
+ };
+ const flatbuffers::String *name() const {
+ return GetPointer<const flatbuffers::String *>(VT_NAME);
+ }
+ bool KeyCompareLessThan(const Field *o) const {
+ return *name() < *o->name();
+ }
+ int KeyCompareWithValue(const char *val) const {
+ return strcmp(name()->c_str(), val);
+ }
+ const reflection::Type *type() const {
+ return GetPointer<const reflection::Type *>(VT_TYPE);
+ }
+ uint16_t id() const {
+ return GetField<uint16_t>(VT_ID, 0);
+ }
+ uint16_t offset() const {
+ return GetField<uint16_t>(VT_OFFSET, 0);
+ }
+ int64_t default_integer() const {
+ return GetField<int64_t>(VT_DEFAULT_INTEGER, 0);
+ }
+ double default_real() const {
+ return GetField<double>(VT_DEFAULT_REAL, 0.0);
+ }
+ bool deprecated() const {
+ return GetField<uint8_t>(VT_DEPRECATED, 0) != 0;
+ }
+ bool required() const {
+ return GetField<uint8_t>(VT_REQUIRED, 0) != 0;
+ }
+ bool key() const {
+ return GetField<uint8_t>(VT_KEY, 0) != 0;
+ }
+ const flatbuffers::Vector<flatbuffers::Offset<reflection::KeyValue>> *attributes() const {
+ return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<reflection::KeyValue>> *>(VT_ATTRIBUTES);
+ }
+ const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *documentation() const {
+ return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *>(VT_DOCUMENTATION);
+ }
+ bool optional() const {
+ return GetField<uint8_t>(VT_OPTIONAL, 0) != 0;
+ }
+ bool Verify(flatbuffers::Verifier &verifier) const {
+ return VerifyTableStart(verifier) &&
+ VerifyOffsetRequired(verifier, VT_NAME) &&
+ verifier.VerifyString(name()) &&
+ VerifyOffsetRequired(verifier, VT_TYPE) &&
+ verifier.VerifyTable(type()) &&
+ VerifyField<uint16_t>(verifier, VT_ID) &&
+ VerifyField<uint16_t>(verifier, VT_OFFSET) &&
+ VerifyField<int64_t>(verifier, VT_DEFAULT_INTEGER) &&
+ VerifyField<double>(verifier, VT_DEFAULT_REAL) &&
+ VerifyField<uint8_t>(verifier, VT_DEPRECATED) &&
+ VerifyField<uint8_t>(verifier, VT_REQUIRED) &&
+ VerifyField<uint8_t>(verifier, VT_KEY) &&
+ VerifyOffset(verifier, VT_ATTRIBUTES) &&
+ verifier.VerifyVector(attributes()) &&
+ verifier.VerifyVectorOfTables(attributes()) &&
+ VerifyOffset(verifier, VT_DOCUMENTATION) &&
+ verifier.VerifyVector(documentation()) &&
+ verifier.VerifyVectorOfStrings(documentation()) &&
+ VerifyField<uint8_t>(verifier, VT_OPTIONAL) &&
+ verifier.EndTable();
+ }
+};
+
+struct FieldBuilder {
+ typedef Field Table;
+ flatbuffers::FlatBufferBuilder &fbb_;
+ flatbuffers::uoffset_t start_;
+ void add_name(flatbuffers::Offset<flatbuffers::String> name) {
+ fbb_.AddOffset(Field::VT_NAME, name);
+ }
+ void add_type(flatbuffers::Offset<reflection::Type> type) {
+ fbb_.AddOffset(Field::VT_TYPE, type);
+ }
+ void add_id(uint16_t id) {
+ fbb_.AddElement<uint16_t>(Field::VT_ID, id, 0);
+ }
+ void add_offset(uint16_t offset) {
+ fbb_.AddElement<uint16_t>(Field::VT_OFFSET, offset, 0);
+ }
+ void add_default_integer(int64_t default_integer) {
+ fbb_.AddElement<int64_t>(Field::VT_DEFAULT_INTEGER, default_integer, 0);
+ }
+ void add_default_real(double default_real) {
+ fbb_.AddElement<double>(Field::VT_DEFAULT_REAL, default_real, 0.0);
+ }
+ void add_deprecated(bool deprecated) {
+ fbb_.AddElement<uint8_t>(Field::VT_DEPRECATED, static_cast<uint8_t>(deprecated), 0);
+ }
+ void add_required(bool required) {
+ fbb_.AddElement<uint8_t>(Field::VT_REQUIRED, static_cast<uint8_t>(required), 0);
+ }
+ void add_key(bool key) {
+ fbb_.AddElement<uint8_t>(Field::VT_KEY, static_cast<uint8_t>(key), 0);
+ }
+ void add_attributes(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<reflection::KeyValue>>> attributes) {
+ fbb_.AddOffset(Field::VT_ATTRIBUTES, attributes);
+ }
+ void add_documentation(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> documentation) {
+ fbb_.AddOffset(Field::VT_DOCUMENTATION, documentation);
+ }
+ void add_optional(bool optional) {
+ fbb_.AddElement<uint8_t>(Field::VT_OPTIONAL, static_cast<uint8_t>(optional), 0);
+ }
+ explicit FieldBuilder(flatbuffers::FlatBufferBuilder &_fbb)
+ : fbb_(_fbb) {
+ start_ = fbb_.StartTable();
+ }
+ flatbuffers::Offset<Field> Finish() {
+ const auto end = fbb_.EndTable(start_);
+ auto o = flatbuffers::Offset<Field>(end);
+ fbb_.Required(o, Field::VT_NAME);
+ fbb_.Required(o, Field::VT_TYPE);
+ return o;
+ }
+};
+
+inline flatbuffers::Offset<Field> CreateField(
+ flatbuffers::FlatBufferBuilder &_fbb,
+ flatbuffers::Offset<flatbuffers::String> name = 0,
+ flatbuffers::Offset<reflection::Type> type = 0,
+ uint16_t id = 0,
+ uint16_t offset = 0,
+ int64_t default_integer = 0,
+ double default_real = 0.0,
+ bool deprecated = false,
+ bool required = false,
+ bool key = false,
+ flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<reflection::KeyValue>>> attributes = 0,
+ flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> documentation = 0,
+ bool optional = false) {
+ FieldBuilder builder_(_fbb);
+ builder_.add_default_real(default_real);
+ builder_.add_default_integer(default_integer);
+ builder_.add_documentation(documentation);
+ builder_.add_attributes(attributes);
+ builder_.add_type(type);
+ builder_.add_name(name);
+ builder_.add_offset(offset);
+ builder_.add_id(id);
+ builder_.add_optional(optional);
+ builder_.add_key(key);
+ builder_.add_required(required);
+ builder_.add_deprecated(deprecated);
+ return builder_.Finish();
+}
+
+inline flatbuffers::Offset<Field> CreateFieldDirect(
+ flatbuffers::FlatBufferBuilder &_fbb,
+ const char *name = nullptr,
+ flatbuffers::Offset<reflection::Type> type = 0,
+ uint16_t id = 0,
+ uint16_t offset = 0,
+ int64_t default_integer = 0,
+ double default_real = 0.0,
+ bool deprecated = false,
+ bool required = false,
+ bool key = false,
+ std::vector<flatbuffers::Offset<reflection::KeyValue>> *attributes = nullptr,
+ const std::vector<flatbuffers::Offset<flatbuffers::String>> *documentation = nullptr,
+ bool optional = false) {
+ auto name__ = name ? _fbb.CreateString(name) : 0;
+ auto attributes__ = attributes ? _fbb.CreateVectorOfSortedTables<reflection::KeyValue>(attributes) : 0;
+ auto documentation__ = documentation ? _fbb.CreateVector<flatbuffers::Offset<flatbuffers::String>>(*documentation) : 0;
+ return reflection::CreateField(
+ _fbb,
+ name__,
+ type,
+ id,
+ offset,
+ default_integer,
+ default_real,
+ deprecated,
+ required,
+ key,
+ attributes__,
+ documentation__,
+ optional);
+}
+
+struct Object FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
+ typedef ObjectBuilder Builder;
+ enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
+ VT_NAME = 4,
+ VT_FIELDS = 6,
+ VT_IS_STRUCT = 8,
+ VT_MINALIGN = 10,
+ VT_BYTESIZE = 12,
+ VT_ATTRIBUTES = 14,
+ VT_DOCUMENTATION = 16
+ };
+ const flatbuffers::String *name() const {
+ return GetPointer<const flatbuffers::String *>(VT_NAME);
+ }
+ bool KeyCompareLessThan(const Object *o) const {
+ return *name() < *o->name();
+ }
+ int KeyCompareWithValue(const char *val) const {
+ return strcmp(name()->c_str(), val);
+ }
+ const flatbuffers::Vector<flatbuffers::Offset<reflection::Field>> *fields() const {
+ return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<reflection::Field>> *>(VT_FIELDS);
+ }
+ bool is_struct() const {
+ return GetField<uint8_t>(VT_IS_STRUCT, 0) != 0;
+ }
+ int32_t minalign() const {
+ return GetField<int32_t>(VT_MINALIGN, 0);
+ }
+ int32_t bytesize() const {
+ return GetField<int32_t>(VT_BYTESIZE, 0);
+ }
+ const flatbuffers::Vector<flatbuffers::Offset<reflection::KeyValue>> *attributes() const {
+ return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<reflection::KeyValue>> *>(VT_ATTRIBUTES);
+ }
+ const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *documentation() const {
+ return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *>(VT_DOCUMENTATION);
+ }
+ bool Verify(flatbuffers::Verifier &verifier) const {
+ return VerifyTableStart(verifier) &&
+ VerifyOffsetRequired(verifier, VT_NAME) &&
+ verifier.VerifyString(name()) &&
+ VerifyOffsetRequired(verifier, VT_FIELDS) &&
+ verifier.VerifyVector(fields()) &&
+ verifier.VerifyVectorOfTables(fields()) &&
+ VerifyField<uint8_t>(verifier, VT_IS_STRUCT) &&
+ VerifyField<int32_t>(verifier, VT_MINALIGN) &&
+ VerifyField<int32_t>(verifier, VT_BYTESIZE) &&
+ VerifyOffset(verifier, VT_ATTRIBUTES) &&
+ verifier.VerifyVector(attributes()) &&
+ verifier.VerifyVectorOfTables(attributes()) &&
+ VerifyOffset(verifier, VT_DOCUMENTATION) &&
+ verifier.VerifyVector(documentation()) &&
+ verifier.VerifyVectorOfStrings(documentation()) &&
+ verifier.EndTable();
+ }
+};
+
+struct ObjectBuilder {
+ typedef Object Table;
+ flatbuffers::FlatBufferBuilder &fbb_;
+ flatbuffers::uoffset_t start_;
+ void add_name(flatbuffers::Offset<flatbuffers::String> name) {
+ fbb_.AddOffset(Object::VT_NAME, name);
+ }
+ void add_fields(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<reflection::Field>>> fields) {
+ fbb_.AddOffset(Object::VT_FIELDS, fields);
+ }
+ void add_is_struct(bool is_struct) {
+ fbb_.AddElement<uint8_t>(Object::VT_IS_STRUCT, static_cast<uint8_t>(is_struct), 0);
+ }
+ void add_minalign(int32_t minalign) {
+ fbb_.AddElement<int32_t>(Object::VT_MINALIGN, minalign, 0);
+ }
+ void add_bytesize(int32_t bytesize) {
+ fbb_.AddElement<int32_t>(Object::VT_BYTESIZE, bytesize, 0);
+ }
+ void add_attributes(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<reflection::KeyValue>>> attributes) {
+ fbb_.AddOffset(Object::VT_ATTRIBUTES, attributes);
+ }
+ void add_documentation(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> documentation) {
+ fbb_.AddOffset(Object::VT_DOCUMENTATION, documentation);
+ }
+ explicit ObjectBuilder(flatbuffers::FlatBufferBuilder &_fbb)
+ : fbb_(_fbb) {
+ start_ = fbb_.StartTable();
+ }
+ flatbuffers::Offset<Object> Finish() {
+ const auto end = fbb_.EndTable(start_);
+ auto o = flatbuffers::Offset<Object>(end);
+ fbb_.Required(o, Object::VT_NAME);
+ fbb_.Required(o, Object::VT_FIELDS);
+ return o;
+ }
+};
+
+inline flatbuffers::Offset<Object> CreateObject(
+ flatbuffers::FlatBufferBuilder &_fbb,
+ flatbuffers::Offset<flatbuffers::String> name = 0,
+ flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<reflection::Field>>> fields = 0,
+ bool is_struct = false,
+ int32_t minalign = 0,
+ int32_t bytesize = 0,
+ flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<reflection::KeyValue>>> attributes = 0,
+ flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> documentation = 0) {
+ ObjectBuilder builder_(_fbb);
+ builder_.add_documentation(documentation);
+ builder_.add_attributes(attributes);
+ builder_.add_bytesize(bytesize);
+ builder_.add_minalign(minalign);
+ builder_.add_fields(fields);
+ builder_.add_name(name);
+ builder_.add_is_struct(is_struct);
+ return builder_.Finish();
+}
+
+inline flatbuffers::Offset<Object> CreateObjectDirect(
+ flatbuffers::FlatBufferBuilder &_fbb,
+ const char *name = nullptr,
+ std::vector<flatbuffers::Offset<reflection::Field>> *fields = nullptr,
+ bool is_struct = false,
+ int32_t minalign = 0,
+ int32_t bytesize = 0,
+ std::vector<flatbuffers::Offset<reflection::KeyValue>> *attributes = nullptr,
+ const std::vector<flatbuffers::Offset<flatbuffers::String>> *documentation = nullptr) {
+ auto name__ = name ? _fbb.CreateString(name) : 0;
+ auto fields__ = fields ? _fbb.CreateVectorOfSortedTables<reflection::Field>(fields) : 0;
+ auto attributes__ = attributes ? _fbb.CreateVectorOfSortedTables<reflection::KeyValue>(attributes) : 0;
+ auto documentation__ = documentation ? _fbb.CreateVector<flatbuffers::Offset<flatbuffers::String>>(*documentation) : 0;
+ return reflection::CreateObject(
+ _fbb,
+ name__,
+ fields__,
+ is_struct,
+ minalign,
+ bytesize,
+ attributes__,
+ documentation__);
+}
+
+struct RPCCall FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
+ typedef RPCCallBuilder Builder;
+ enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
+ VT_NAME = 4,
+ VT_REQUEST = 6,
+ VT_RESPONSE = 8,
+ VT_ATTRIBUTES = 10,
+ VT_DOCUMENTATION = 12
+ };
+ const flatbuffers::String *name() const {
+ return GetPointer<const flatbuffers::String *>(VT_NAME);
+ }
+ bool KeyCompareLessThan(const RPCCall *o) const {
+ return *name() < *o->name();
+ }
+ int KeyCompareWithValue(const char *val) const {
+ return strcmp(name()->c_str(), val);
+ }
+ const reflection::Object *request() const {
+ return GetPointer<const reflection::Object *>(VT_REQUEST);
+ }
+ const reflection::Object *response() const {
+ return GetPointer<const reflection::Object *>(VT_RESPONSE);
+ }
+ const flatbuffers::Vector<flatbuffers::Offset<reflection::KeyValue>> *attributes() const {
+ return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<reflection::KeyValue>> *>(VT_ATTRIBUTES);
+ }
+ const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *documentation() const {
+ return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *>(VT_DOCUMENTATION);
+ }
+ bool Verify(flatbuffers::Verifier &verifier) const {
+ return VerifyTableStart(verifier) &&
+ VerifyOffsetRequired(verifier, VT_NAME) &&
+ verifier.VerifyString(name()) &&
+ VerifyOffsetRequired(verifier, VT_REQUEST) &&
+ verifier.VerifyTable(request()) &&
+ VerifyOffsetRequired(verifier, VT_RESPONSE) &&
+ verifier.VerifyTable(response()) &&
+ VerifyOffset(verifier, VT_ATTRIBUTES) &&
+ verifier.VerifyVector(attributes()) &&
+ verifier.VerifyVectorOfTables(attributes()) &&
+ VerifyOffset(verifier, VT_DOCUMENTATION) &&
+ verifier.VerifyVector(documentation()) &&
+ verifier.VerifyVectorOfStrings(documentation()) &&
+ verifier.EndTable();
+ }
+};
+
+struct RPCCallBuilder {
+ typedef RPCCall Table;
+ flatbuffers::FlatBufferBuilder &fbb_;
+ flatbuffers::uoffset_t start_;
+ void add_name(flatbuffers::Offset<flatbuffers::String> name) {
+ fbb_.AddOffset(RPCCall::VT_NAME, name);
+ }
+ void add_request(flatbuffers::Offset<reflection::Object> request) {
+ fbb_.AddOffset(RPCCall::VT_REQUEST, request);
+ }
+ void add_response(flatbuffers::Offset<reflection::Object> response) {
+ fbb_.AddOffset(RPCCall::VT_RESPONSE, response);
+ }
+ void add_attributes(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<reflection::KeyValue>>> attributes) {
+ fbb_.AddOffset(RPCCall::VT_ATTRIBUTES, attributes);
+ }
+ void add_documentation(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> documentation) {
+ fbb_.AddOffset(RPCCall::VT_DOCUMENTATION, documentation);
+ }
+ explicit RPCCallBuilder(flatbuffers::FlatBufferBuilder &_fbb)
+ : fbb_(_fbb) {
+ start_ = fbb_.StartTable();
+ }
+ flatbuffers::Offset<RPCCall> Finish() {
+ const auto end = fbb_.EndTable(start_);
+ auto o = flatbuffers::Offset<RPCCall>(end);
+ fbb_.Required(o, RPCCall::VT_NAME);
+ fbb_.Required(o, RPCCall::VT_REQUEST);
+ fbb_.Required(o, RPCCall::VT_RESPONSE);
+ return o;
+ }
+};
+
+inline flatbuffers::Offset<RPCCall> CreateRPCCall(
+ flatbuffers::FlatBufferBuilder &_fbb,
+ flatbuffers::Offset<flatbuffers::String> name = 0,
+ flatbuffers::Offset<reflection::Object> request = 0,
+ flatbuffers::Offset<reflection::Object> response = 0,
+ flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<reflection::KeyValue>>> attributes = 0,
+ flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> documentation = 0) {
+ RPCCallBuilder builder_(_fbb);
+ builder_.add_documentation(documentation);
+ builder_.add_attributes(attributes);
+ builder_.add_response(response);
+ builder_.add_request(request);
+ builder_.add_name(name);
+ return builder_.Finish();
+}
+
+inline flatbuffers::Offset<RPCCall> CreateRPCCallDirect(
+ flatbuffers::FlatBufferBuilder &_fbb,
+ const char *name = nullptr,
+ flatbuffers::Offset<reflection::Object> request = 0,
+ flatbuffers::Offset<reflection::Object> response = 0,
+ std::vector<flatbuffers::Offset<reflection::KeyValue>> *attributes = nullptr,
+ const std::vector<flatbuffers::Offset<flatbuffers::String>> *documentation = nullptr) {
+ auto name__ = name ? _fbb.CreateString(name) : 0;
+ auto attributes__ = attributes ? _fbb.CreateVectorOfSortedTables<reflection::KeyValue>(attributes) : 0;
+ auto documentation__ = documentation ? _fbb.CreateVector<flatbuffers::Offset<flatbuffers::String>>(*documentation) : 0;
+ return reflection::CreateRPCCall(
+ _fbb,
+ name__,
+ request,
+ response,
+ attributes__,
+ documentation__);
+}
+
+struct Service FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
+ typedef ServiceBuilder Builder;
+ enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
+ VT_NAME = 4,
+ VT_CALLS = 6,
+ VT_ATTRIBUTES = 8,
+ VT_DOCUMENTATION = 10
+ };
+ const flatbuffers::String *name() const {
+ return GetPointer<const flatbuffers::String *>(VT_NAME);
+ }
+ bool KeyCompareLessThan(const Service *o) const {
+ return *name() < *o->name();
+ }
+ int KeyCompareWithValue(const char *val) const {
+ return strcmp(name()->c_str(), val);
+ }
+ const flatbuffers::Vector<flatbuffers::Offset<reflection::RPCCall>> *calls() const {
+ return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<reflection::RPCCall>> *>(VT_CALLS);
+ }
+ const flatbuffers::Vector<flatbuffers::Offset<reflection::KeyValue>> *attributes() const {
+ return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<reflection::KeyValue>> *>(VT_ATTRIBUTES);
+ }
+ const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *documentation() const {
+ return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *>(VT_DOCUMENTATION);
+ }
+ bool Verify(flatbuffers::Verifier &verifier) const {
+ return VerifyTableStart(verifier) &&
+ VerifyOffsetRequired(verifier, VT_NAME) &&
+ verifier.VerifyString(name()) &&
+ VerifyOffset(verifier, VT_CALLS) &&
+ verifier.VerifyVector(calls()) &&
+ verifier.VerifyVectorOfTables(calls()) &&
+ VerifyOffset(verifier, VT_ATTRIBUTES) &&
+ verifier.VerifyVector(attributes()) &&
+ verifier.VerifyVectorOfTables(attributes()) &&
+ VerifyOffset(verifier, VT_DOCUMENTATION) &&
+ verifier.VerifyVector(documentation()) &&
+ verifier.VerifyVectorOfStrings(documentation()) &&
+ verifier.EndTable();
+ }
+};
+
+struct ServiceBuilder {
+ typedef Service Table;
+ flatbuffers::FlatBufferBuilder &fbb_;
+ flatbuffers::uoffset_t start_;
+ void add_name(flatbuffers::Offset<flatbuffers::String> name) {
+ fbb_.AddOffset(Service::VT_NAME, name);
+ }
+ void add_calls(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<reflection::RPCCall>>> calls) {
+ fbb_.AddOffset(Service::VT_CALLS, calls);
+ }
+ void add_attributes(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<reflection::KeyValue>>> attributes) {
+ fbb_.AddOffset(Service::VT_ATTRIBUTES, attributes);
+ }
+ void add_documentation(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> documentation) {
+ fbb_.AddOffset(Service::VT_DOCUMENTATION, documentation);
+ }
+ explicit ServiceBuilder(flatbuffers::FlatBufferBuilder &_fbb)
+ : fbb_(_fbb) {
+ start_ = fbb_.StartTable();
+ }
+ flatbuffers::Offset<Service> Finish() {
+ const auto end = fbb_.EndTable(start_);
+ auto o = flatbuffers::Offset<Service>(end);
+ fbb_.Required(o, Service::VT_NAME);
+ return o;
+ }
+};
+
+inline flatbuffers::Offset<Service> CreateService(
+ flatbuffers::FlatBufferBuilder &_fbb,
+ flatbuffers::Offset<flatbuffers::String> name = 0,
+ flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<reflection::RPCCall>>> calls = 0,
+ flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<reflection::KeyValue>>> attributes = 0,
+ flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> documentation = 0) {
+ ServiceBuilder builder_(_fbb);
+ builder_.add_documentation(documentation);
+ builder_.add_attributes(attributes);
+ builder_.add_calls(calls);
+ builder_.add_name(name);
+ return builder_.Finish();
+}
+
+inline flatbuffers::Offset<Service> CreateServiceDirect(
+ flatbuffers::FlatBufferBuilder &_fbb,
+ const char *name = nullptr,
+ std::vector<flatbuffers::Offset<reflection::RPCCall>> *calls = nullptr,
+ std::vector<flatbuffers::Offset<reflection::KeyValue>> *attributes = nullptr,
+ const std::vector<flatbuffers::Offset<flatbuffers::String>> *documentation = nullptr) {
+ auto name__ = name ? _fbb.CreateString(name) : 0;
+ auto calls__ = calls ? _fbb.CreateVectorOfSortedTables<reflection::RPCCall>(calls) : 0;
+ auto attributes__ = attributes ? _fbb.CreateVectorOfSortedTables<reflection::KeyValue>(attributes) : 0;
+ auto documentation__ = documentation ? _fbb.CreateVector<flatbuffers::Offset<flatbuffers::String>>(*documentation) : 0;
+ return reflection::CreateService(
+ _fbb,
+ name__,
+ calls__,
+ attributes__,
+ documentation__);
+}
+
+struct Schema FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
+ typedef SchemaBuilder Builder;
+ enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
+ VT_OBJECTS = 4,
+ VT_ENUMS = 6,
+ VT_FILE_IDENT = 8,
+ VT_FILE_EXT = 10,
+ VT_ROOT_TABLE = 12,
+ VT_SERVICES = 14,
+ VT_ADVANCED_FEATURES = 16
+ };
+ const flatbuffers::Vector<flatbuffers::Offset<reflection::Object>> *objects() const {
+ return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<reflection::Object>> *>(VT_OBJECTS);
+ }
+ const flatbuffers::Vector<flatbuffers::Offset<reflection::Enum>> *enums() const {
+ return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<reflection::Enum>> *>(VT_ENUMS);
+ }
+ const flatbuffers::String *file_ident() const {
+ return GetPointer<const flatbuffers::String *>(VT_FILE_IDENT);
+ }
+ const flatbuffers::String *file_ext() const {
+ return GetPointer<const flatbuffers::String *>(VT_FILE_EXT);
+ }
+ const reflection::Object *root_table() const {
+ return GetPointer<const reflection::Object *>(VT_ROOT_TABLE);
+ }
+ const flatbuffers::Vector<flatbuffers::Offset<reflection::Service>> *services() const {
+ return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<reflection::Service>> *>(VT_SERVICES);
+ }
+ reflection::AdvancedFeatures advanced_features() const {
+ return static_cast<reflection::AdvancedFeatures>(GetField<uint64_t>(VT_ADVANCED_FEATURES, 0));
+ }
+ bool Verify(flatbuffers::Verifier &verifier) const {
+ return VerifyTableStart(verifier) &&
+ VerifyOffsetRequired(verifier, VT_OBJECTS) &&
+ verifier.VerifyVector(objects()) &&
+ verifier.VerifyVectorOfTables(objects()) &&
+ VerifyOffsetRequired(verifier, VT_ENUMS) &&
+ verifier.VerifyVector(enums()) &&
+ verifier.VerifyVectorOfTables(enums()) &&
+ VerifyOffset(verifier, VT_FILE_IDENT) &&
+ verifier.VerifyString(file_ident()) &&
+ VerifyOffset(verifier, VT_FILE_EXT) &&
+ verifier.VerifyString(file_ext()) &&
+ VerifyOffset(verifier, VT_ROOT_TABLE) &&
+ verifier.VerifyTable(root_table()) &&
+ VerifyOffset(verifier, VT_SERVICES) &&
+ verifier.VerifyVector(services()) &&
+ verifier.VerifyVectorOfTables(services()) &&
+ VerifyField<uint64_t>(verifier, VT_ADVANCED_FEATURES) &&
+ verifier.EndTable();
+ }
+};
+
+struct SchemaBuilder {
+ typedef Schema Table;
+ flatbuffers::FlatBufferBuilder &fbb_;
+ flatbuffers::uoffset_t start_;
+ void add_objects(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<reflection::Object>>> objects) {
+ fbb_.AddOffset(Schema::VT_OBJECTS, objects);
+ }
+ void add_enums(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<reflection::Enum>>> enums) {
+ fbb_.AddOffset(Schema::VT_ENUMS, enums);
+ }
+ void add_file_ident(flatbuffers::Offset<flatbuffers::String> file_ident) {
+ fbb_.AddOffset(Schema::VT_FILE_IDENT, file_ident);
+ }
+ void add_file_ext(flatbuffers::Offset<flatbuffers::String> file_ext) {
+ fbb_.AddOffset(Schema::VT_FILE_EXT, file_ext);
+ }
+ void add_root_table(flatbuffers::Offset<reflection::Object> root_table) {
+ fbb_.AddOffset(Schema::VT_ROOT_TABLE, root_table);
+ }
+ void add_services(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<reflection::Service>>> services) {
+ fbb_.AddOffset(Schema::VT_SERVICES, services);
+ }
+ void add_advanced_features(reflection::AdvancedFeatures advanced_features) {
+ fbb_.AddElement<uint64_t>(Schema::VT_ADVANCED_FEATURES, static_cast<uint64_t>(advanced_features), 0);
+ }
+ explicit SchemaBuilder(flatbuffers::FlatBufferBuilder &_fbb)
+ : fbb_(_fbb) {
+ start_ = fbb_.StartTable();
+ }
+ flatbuffers::Offset<Schema> Finish() {
+ const auto end = fbb_.EndTable(start_);
+ auto o = flatbuffers::Offset<Schema>(end);
+ fbb_.Required(o, Schema::VT_OBJECTS);
+ fbb_.Required(o, Schema::VT_ENUMS);
+ return o;
+ }
+};
+
+inline flatbuffers::Offset<Schema> CreateSchema(
+ flatbuffers::FlatBufferBuilder &_fbb,
+ flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<reflection::Object>>> objects = 0,
+ flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<reflection::Enum>>> enums = 0,
+ flatbuffers::Offset<flatbuffers::String> file_ident = 0,
+ flatbuffers::Offset<flatbuffers::String> file_ext = 0,
+ flatbuffers::Offset<reflection::Object> root_table = 0,
+ flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<reflection::Service>>> services = 0,
+ reflection::AdvancedFeatures advanced_features = static_cast<reflection::AdvancedFeatures>(0)) {
+ SchemaBuilder builder_(_fbb);
+ builder_.add_advanced_features(advanced_features);
+ builder_.add_services(services);
+ builder_.add_root_table(root_table);
+ builder_.add_file_ext(file_ext);
+ builder_.add_file_ident(file_ident);
+ builder_.add_enums(enums);
+ builder_.add_objects(objects);
+ return builder_.Finish();
+}
+
+inline flatbuffers::Offset<Schema> CreateSchemaDirect(
+ flatbuffers::FlatBufferBuilder &_fbb,
+ std::vector<flatbuffers::Offset<reflection::Object>> *objects = nullptr,
+ std::vector<flatbuffers::Offset<reflection::Enum>> *enums = nullptr,
+ const char *file_ident = nullptr,
+ const char *file_ext = nullptr,
+ flatbuffers::Offset<reflection::Object> root_table = 0,
+ std::vector<flatbuffers::Offset<reflection::Service>> *services = nullptr,
+ reflection::AdvancedFeatures advanced_features = static_cast<reflection::AdvancedFeatures>(0)) {
+ auto objects__ = objects ? _fbb.CreateVectorOfSortedTables<reflection::Object>(objects) : 0;
+ auto enums__ = enums ? _fbb.CreateVectorOfSortedTables<reflection::Enum>(enums) : 0;
+ auto file_ident__ = file_ident ? _fbb.CreateString(file_ident) : 0;
+ auto file_ext__ = file_ext ? _fbb.CreateString(file_ext) : 0;
+ auto services__ = services ? _fbb.CreateVectorOfSortedTables<reflection::Service>(services) : 0;
+ return reflection::CreateSchema(
+ _fbb,
+ objects__,
+ enums__,
+ file_ident__,
+ file_ext__,
+ root_table,
+ services__,
+ advanced_features);
+}
+
+inline const reflection::Schema *GetSchema(const void *buf) {
+ return flatbuffers::GetRoot<reflection::Schema>(buf);
+}
+
+inline const reflection::Schema *GetSizePrefixedSchema(const void *buf) {
+ return flatbuffers::GetSizePrefixedRoot<reflection::Schema>(buf);
+}
+
+inline const char *SchemaIdentifier() {
+ return "BFBS";
+}
+
+inline bool SchemaBufferHasIdentifier(const void *buf) {
+ return flatbuffers::BufferHasIdentifier(
+ buf, SchemaIdentifier());
+}
+
+inline bool VerifySchemaBuffer(
+ flatbuffers::Verifier &verifier) {
+ return verifier.VerifyBuffer<reflection::Schema>(SchemaIdentifier());
+}
+
+inline bool VerifySizePrefixedSchemaBuffer(
+ flatbuffers::Verifier &verifier) {
+ return verifier.VerifySizePrefixedBuffer<reflection::Schema>(SchemaIdentifier());
+}
+
+inline const char *SchemaExtension() {
+ return "bfbs";
+}
+
+inline void FinishSchemaBuffer(
+ flatbuffers::FlatBufferBuilder &fbb,
+ flatbuffers::Offset<reflection::Schema> root) {
+ fbb.Finish(root, SchemaIdentifier());
+}
+
+inline void FinishSizePrefixedSchemaBuffer(
+ flatbuffers::FlatBufferBuilder &fbb,
+ flatbuffers::Offset<reflection::Schema> root) {
+ fbb.FinishSizePrefixed(root, SchemaIdentifier());
+}
+
+} // namespace reflection
+
+#endif // FLATBUFFERS_GENERATED_REFLECTION_REFLECTION_H_
diff --git a/contrib/libs/flatbuffers/include/flatbuffers/util.h b/contrib/libs/flatbuffers/include/flatbuffers/util.h
new file mode 100644
index 0000000000..4493c561c2
--- /dev/null
+++ b/contrib/libs/flatbuffers/include/flatbuffers/util.h
@@ -0,0 +1,698 @@
+/*
+ * 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_UTIL_H_
+#define FLATBUFFERS_UTIL_H_
+
+#include <errno.h>
+
+#include "base.h"
+#include "stl_emulation.h"
+
+#ifndef FLATBUFFERS_PREFER_PRINTF
+# include <sstream>
+#else // FLATBUFFERS_PREFER_PRINTF
+# include <float.h>
+# include <stdio.h>
+#endif // FLATBUFFERS_PREFER_PRINTF
+
+#include <iomanip>
+#include <string>
+
+namespace flatbuffers {
+
+// @locale-independent functions for ASCII characters set.
+
+// Fast checking that character lies in closed range: [a <= x <= b]
+// using one compare (conditional branch) operator.
+inline bool check_ascii_range(char x, char a, char b) {
+ FLATBUFFERS_ASSERT(a <= b);
+ // (Hacker's Delight): `a <= x <= b` <=> `(x-a) <={u} (b-a)`.
+ // The x, a, b will be promoted to int and subtracted without overflow.
+ return static_cast<unsigned int>(x - a) <= static_cast<unsigned int>(b - a);
+}
+
+// Case-insensitive isalpha
+inline bool is_alpha(char c) {
+ // ASCII only: alpha to upper case => reset bit 0x20 (~0x20 = 0xDF).
+ return check_ascii_range(c & 0xDF, 'a' & 0xDF, 'z' & 0xDF);
+}
+
+// Check for uppercase alpha
+inline bool is_alpha_upper(char c) { return check_ascii_range(c, 'A', 'Z'); }
+
+// Check (case-insensitive) that `c` is equal to alpha.
+inline bool is_alpha_char(char c, char alpha) {
+ FLATBUFFERS_ASSERT(is_alpha(alpha));
+ // ASCII only: alpha to upper case => reset bit 0x20 (~0x20 = 0xDF).
+ return ((c & 0xDF) == (alpha & 0xDF));
+}
+
+// https://en.cppreference.com/w/cpp/string/byte/isxdigit
+// isdigit and isxdigit are the only standard narrow character classification
+// functions that are not affected by the currently installed C locale. although
+// some implementations (e.g. Microsoft in 1252 codepage) may classify
+// additional single-byte characters as digits.
+inline bool is_digit(char c) { return check_ascii_range(c, '0', '9'); }
+
+inline bool is_xdigit(char c) {
+ // Replace by look-up table.
+ return is_digit(c) || check_ascii_range(c & 0xDF, 'a' & 0xDF, 'f' & 0xDF);
+}
+
+// Case-insensitive isalnum
+inline bool is_alnum(char c) { return is_alpha(c) || is_digit(c); }
+
+inline char CharToUpper(char c) {
+ return static_cast<char>(::toupper(static_cast<unsigned char>(c)));
+}
+
+inline char CharToLower(char c) {
+ return static_cast<char>(::tolower(static_cast<unsigned char>(c)));
+}
+
+// @end-locale-independent functions for ASCII character set
+
+#ifdef FLATBUFFERS_PREFER_PRINTF
+template<typename T> size_t IntToDigitCount(T t) {
+ size_t digit_count = 0;
+ // Count the sign for negative numbers
+ if (t < 0) digit_count++;
+ // Count a single 0 left of the dot for fractional numbers
+ if (-1 < t && t < 1) digit_count++;
+ // Count digits until fractional part
+ T eps = std::numeric_limits<float>::epsilon();
+ while (t <= (-1 + eps) || (1 - eps) <= t) {
+ t /= 10;
+ digit_count++;
+ }
+ return digit_count;
+}
+
+template<typename T> size_t NumToStringWidth(T t, int precision = 0) {
+ size_t string_width = IntToDigitCount(t);
+ // Count the dot for floating point numbers
+ if (precision) string_width += (precision + 1);
+ return string_width;
+}
+
+template<typename T>
+std::string NumToStringImplWrapper(T t, const char *fmt, int precision = 0) {
+ size_t string_width = NumToStringWidth(t, precision);
+ std::string s(string_width, 0x00);
+ // Allow snprintf to use std::string trailing null to detect buffer overflow
+ snprintf(const_cast<char *>(s.data()), (s.size() + 1), fmt, string_width, t);
+ return s;
+}
+#endif // FLATBUFFERS_PREFER_PRINTF
+
+// Convert an integer or floating point value to a string.
+// In contrast to std::stringstream, "char" values are
+// converted to a string of digits, and we don't use scientific notation.
+template<typename T> std::string NumToString(T t) {
+ // clang-format off
+
+ #ifndef FLATBUFFERS_PREFER_PRINTF
+ std::stringstream ss;
+ ss << t;
+ return ss.str();
+ #else // FLATBUFFERS_PREFER_PRINTF
+ auto v = static_cast<long long>(t);
+ return NumToStringImplWrapper(v, "%.*lld");
+ #endif // FLATBUFFERS_PREFER_PRINTF
+ // clang-format on
+}
+// Avoid char types used as character data.
+template<> inline std::string NumToString<signed char>(signed char t) {
+ return NumToString(static_cast<int>(t));
+}
+template<> inline std::string NumToString<unsigned char>(unsigned char t) {
+ return NumToString(static_cast<int>(t));
+}
+template<> inline std::string NumToString<char>(char t) {
+ return NumToString(static_cast<int>(t));
+}
+#if defined(FLATBUFFERS_CPP98_STL)
+template<> inline std::string NumToString<long long>(long long t) {
+ char buf[21]; // (log((1 << 63) - 1) / log(10)) + 2
+ snprintf(buf, sizeof(buf), "%lld", t);
+ return std::string(buf);
+}
+
+template<>
+inline std::string NumToString<unsigned long long>(unsigned long long t) {
+ char buf[22]; // (log((1 << 63) - 1) / log(10)) + 1
+ snprintf(buf, sizeof(buf), "%llu", t);
+ return std::string(buf);
+}
+#endif // defined(FLATBUFFERS_CPP98_STL)
+
+// Special versions for floats/doubles.
+template<typename T> std::string FloatToString(T t, int precision) {
+ // clang-format off
+
+ #ifndef FLATBUFFERS_PREFER_PRINTF
+ // to_string() prints different numbers of digits for floats depending on
+ // platform and isn't available on Android, so we use stringstream
+ std::stringstream ss;
+ // Use std::fixed to suppress scientific notation.
+ ss << std::fixed;
+ // Default precision is 6, we want that to be higher for doubles.
+ ss << std::setprecision(precision);
+ ss << t;
+ auto s = ss.str();
+ #else // FLATBUFFERS_PREFER_PRINTF
+ auto v = static_cast<double>(t);
+ auto s = NumToStringImplWrapper(v, "%0.*f", precision);
+ #endif // FLATBUFFERS_PREFER_PRINTF
+ // clang-format on
+ // Sadly, std::fixed turns "1" into "1.00000", so here we undo that.
+ auto p = s.find_last_not_of('0');
+ if (p != std::string::npos) {
+ // Strip trailing zeroes. If it is a whole number, keep one zero.
+ s.resize(p + (s[p] == '.' ? 2 : 1));
+ }
+ return s;
+}
+
+template<> inline std::string NumToString<double>(double t) {
+ return FloatToString(t, 12);
+}
+template<> inline std::string NumToString<float>(float t) {
+ return FloatToString(t, 6);
+}
+
+// Convert an integer value to a hexadecimal string.
+// The returned string length is always xdigits long, prefixed by 0 digits.
+// For example, IntToStringHex(0x23, 8) returns the string "00000023".
+inline std::string IntToStringHex(int i, int xdigits) {
+ FLATBUFFERS_ASSERT(i >= 0);
+ // clang-format off
+
+ #ifndef FLATBUFFERS_PREFER_PRINTF
+ std::stringstream ss;
+ ss << std::setw(xdigits) << std::setfill('0') << std::hex << std::uppercase
+ << i;
+ return ss.str();
+ #else // FLATBUFFERS_PREFER_PRINTF
+ return NumToStringImplWrapper(i, "%.*X", xdigits);
+ #endif // FLATBUFFERS_PREFER_PRINTF
+ // clang-format on
+}
+
+// clang-format off
+// Use locale independent functions {strtod_l, strtof_l, strtoll_l, strtoull_l}.
+#if defined(FLATBUFFERS_LOCALE_INDEPENDENT) && (FLATBUFFERS_LOCALE_INDEPENDENT > 0)
+ class ClassicLocale {
+ #ifdef _MSC_VER
+ typedef _locale_t locale_type;
+ #else
+ typedef locale_t locale_type; // POSIX.1-2008 locale_t type
+ #endif
+ ClassicLocale();
+ ~ClassicLocale();
+ locale_type locale_;
+ static ClassicLocale instance_;
+ public:
+ static locale_type Get() { return instance_.locale_; }
+ };
+
+ #ifdef _MSC_VER
+ #define __strtoull_impl(s, pe, b) _strtoui64_l(s, pe, b, ClassicLocale::Get())
+ #define __strtoll_impl(s, pe, b) _strtoi64_l(s, pe, b, ClassicLocale::Get())
+ #define __strtod_impl(s, pe) _strtod_l(s, pe, ClassicLocale::Get())
+ #define __strtof_impl(s, pe) _strtof_l(s, pe, ClassicLocale::Get())
+ #else
+ #define __strtoull_impl(s, pe, b) strtoull_l(s, pe, b, ClassicLocale::Get())
+ #define __strtoll_impl(s, pe, b) strtoll_l(s, pe, b, ClassicLocale::Get())
+ #define __strtod_impl(s, pe) strtod_l(s, pe, ClassicLocale::Get())
+ #define __strtof_impl(s, pe) strtof_l(s, pe, ClassicLocale::Get())
+ #endif
+#else
+ #define __strtod_impl(s, pe) strtod(s, pe)
+ #define __strtof_impl(s, pe) static_cast<float>(strtod(s, pe))
+ #ifdef _MSC_VER
+ #define __strtoull_impl(s, pe, b) _strtoui64(s, pe, b)
+ #define __strtoll_impl(s, pe, b) _strtoi64(s, pe, b)
+ #else
+ #define __strtoull_impl(s, pe, b) strtoull(s, pe, b)
+ #define __strtoll_impl(s, pe, b) strtoll(s, pe, b)
+ #endif
+#endif
+
+inline void strtoval_impl(int64_t *val, const char *str, char **endptr,
+ int base) {
+ *val = __strtoll_impl(str, endptr, base);
+}
+
+inline void strtoval_impl(uint64_t *val, const char *str, char **endptr,
+ int base) {
+ *val = __strtoull_impl(str, endptr, base);
+}
+
+inline void strtoval_impl(double *val, const char *str, char **endptr) {
+ *val = __strtod_impl(str, endptr);
+}
+
+// UBSAN: double to float is safe if numeric_limits<float>::is_iec559 is true.
+__supress_ubsan__("float-cast-overflow")
+inline void strtoval_impl(float *val, const char *str, char **endptr) {
+ *val = __strtof_impl(str, endptr);
+}
+#undef __strtoull_impl
+#undef __strtoll_impl
+#undef __strtod_impl
+#undef __strtof_impl
+// clang-format on
+
+// Adaptor for strtoull()/strtoll().
+// Flatbuffers accepts numbers with any count of leading zeros (-009 is -9),
+// while strtoll with base=0 interprets first leading zero as octal prefix.
+// In future, it is possible to add prefixed 0b0101.
+// 1) Checks errno code for overflow condition (out of range).
+// 2) If base <= 0, function try to detect base of number by prefix.
+//
+// Return value (like strtoull and strtoll, but reject partial result):
+// - If successful, an integer value corresponding to the str is returned.
+// - If full string conversion can't be performed, 0 is returned.
+// - If the converted value falls out of range of corresponding return type, a
+// range error occurs. In this case value MAX(T)/MIN(T) is returned.
+template<typename T>
+inline bool StringToIntegerImpl(T *val, const char *const str,
+ const int base = 0,
+ const bool check_errno = true) {
+ // T is int64_t or uint64_T
+ FLATBUFFERS_ASSERT(str);
+ if (base <= 0) {
+ auto s = str;
+ while (*s && !is_digit(*s)) s++;
+ if (s[0] == '0' && is_alpha_char(s[1], 'X'))
+ return StringToIntegerImpl(val, str, 16, check_errno);
+ // if a prefix not match, try base=10
+ return StringToIntegerImpl(val, str, 10, check_errno);
+ } else {
+ if (check_errno) errno = 0; // clear thread-local errno
+ auto endptr = str;
+ strtoval_impl(val, str, const_cast<char **>(&endptr), base);
+ if ((*endptr != '\0') || (endptr == str)) {
+ *val = 0; // erase partial result
+ return false; // invalid string
+ }
+ // errno is out-of-range, return MAX/MIN
+ if (check_errno && errno) return false;
+ return true;
+ }
+}
+
+template<typename T>
+inline bool StringToFloatImpl(T *val, const char *const str) {
+ // Type T must be either float or double.
+ FLATBUFFERS_ASSERT(str && val);
+ auto end = str;
+ strtoval_impl(val, str, const_cast<char **>(&end));
+ auto done = (end != str) && (*end == '\0');
+ if (!done) *val = 0; // erase partial result
+ return done;
+}
+
+// Convert a string to an instance of T.
+// Return value (matched with StringToInteger64Impl and strtod):
+// - If successful, a numeric value corresponding to the str is returned.
+// - If full string conversion can't be performed, 0 is returned.
+// - If the converted value falls out of range of corresponding return type, a
+// range error occurs. In this case value MAX(T)/MIN(T) is returned.
+template<typename T> inline bool StringToNumber(const char *s, T *val) {
+ // Assert on `unsigned long` and `signed long` on LP64.
+ // If it is necessary, it could be solved with flatbuffers::enable_if<B,T>.
+ static_assert(sizeof(T) < sizeof(int64_t), "unexpected type T");
+ FLATBUFFERS_ASSERT(s && val);
+ int64_t i64;
+ // The errno check isn't needed, will return MAX/MIN on overflow.
+ if (StringToIntegerImpl(&i64, s, 0, false)) {
+ const int64_t max = (flatbuffers::numeric_limits<T>::max)();
+ const int64_t min = flatbuffers::numeric_limits<T>::lowest();
+ if (i64 > max) {
+ *val = static_cast<T>(max);
+ return false;
+ }
+ if (i64 < min) {
+ // For unsigned types return max to distinguish from
+ // "no conversion can be performed" when 0 is returned.
+ *val = static_cast<T>(flatbuffers::is_unsigned<T>::value ? max : min);
+ return false;
+ }
+ *val = static_cast<T>(i64);
+ return true;
+ }
+ *val = 0;
+ return false;
+}
+
+template<> inline bool StringToNumber<int64_t>(const char *str, int64_t *val) {
+ return StringToIntegerImpl(val, str);
+}
+
+template<>
+inline bool StringToNumber<uint64_t>(const char *str, uint64_t *val) {
+ if (!StringToIntegerImpl(val, str)) return false;
+ // The strtoull accepts negative numbers:
+ // If the minus sign was part of the input sequence, the numeric value
+ // calculated from the sequence of digits is negated as if by unary minus
+ // in the result type, which applies unsigned integer wraparound rules.
+ // Fix this behaviour (except -0).
+ if (*val) {
+ auto s = str;
+ while (*s && !is_digit(*s)) s++;
+ s = (s > str) ? (s - 1) : s; // step back to one symbol
+ if (*s == '-') {
+ // For unsigned types return the max to distinguish from
+ // "no conversion can be performed".
+ *val = (flatbuffers::numeric_limits<uint64_t>::max)();
+ return false;
+ }
+ }
+ return true;
+}
+
+template<> inline bool StringToNumber(const char *s, float *val) {
+ return StringToFloatImpl(val, s);
+}
+
+template<> inline bool StringToNumber(const char *s, double *val) {
+ return StringToFloatImpl(val, s);
+}
+
+inline int64_t StringToInt(const char *s, int base = 10) {
+ int64_t val;
+ return StringToIntegerImpl(&val, s, base) ? val : 0;
+}
+
+inline uint64_t StringToUInt(const char *s, int base = 10) {
+ uint64_t val;
+ return StringToIntegerImpl(&val, s, base) ? val : 0;
+}
+
+typedef bool (*LoadFileFunction)(const char *filename, bool binary,
+ std::string *dest);
+typedef bool (*FileExistsFunction)(const char *filename);
+
+LoadFileFunction SetLoadFileFunction(LoadFileFunction load_file_function);
+
+FileExistsFunction SetFileExistsFunction(
+ FileExistsFunction file_exists_function);
+
+// Check if file "name" exists.
+bool FileExists(const char *name);
+
+// Check if "name" exists and it is also a directory.
+bool DirExists(const char *name);
+
+// Load file "name" into "buf" returning true if successful
+// false otherwise. If "binary" is false data is read
+// using ifstream's text mode, otherwise data is read with
+// no transcoding.
+bool LoadFile(const char *name, bool binary, std::string *buf);
+
+// Save data "buf" of length "len" bytes into a file
+// "name" returning true if successful, false otherwise.
+// If "binary" is false data is written using ifstream's
+// text mode, otherwise data is written with no
+// transcoding.
+bool SaveFile(const char *name, const char *buf, size_t len, bool binary);
+
+// Save data "buf" into file "name" returning true if
+// successful, false otherwise. If "binary" is false
+// data is written using ifstream's text mode, otherwise
+// data is written with no transcoding.
+inline bool SaveFile(const char *name, const std::string &buf, bool binary) {
+ return SaveFile(name, buf.c_str(), buf.size(), binary);
+}
+
+// Functionality for minimalistic portable path handling.
+
+// The functions below behave correctly regardless of whether posix ('/') or
+// Windows ('/' or '\\') separators are used.
+
+// Any new separators inserted are always posix.
+FLATBUFFERS_CONSTEXPR char kPathSeparator = '/';
+
+// Returns the path with the extension, if any, removed.
+std::string StripExtension(const std::string &filepath);
+
+// Returns the extension, if any.
+std::string GetExtension(const std::string &filepath);
+
+// Return the last component of the path, after the last separator.
+std::string StripPath(const std::string &filepath);
+
+// Strip the last component of the path + separator.
+std::string StripFileName(const std::string &filepath);
+
+// Concatenates a path with a filename, regardless of whether the path
+// ends in a separator or not.
+std::string ConCatPathFileName(const std::string &path,
+ const std::string &filename);
+
+// Replaces any '\\' separators with '/'
+std::string PosixPath(const char *path);
+
+// This function ensure a directory exists, by recursively
+// creating dirs for any parts of the path that don't exist yet.
+void EnsureDirExists(const std::string &filepath);
+
+// Obtains the absolute path from any other path.
+// Returns the input path if the absolute path couldn't be resolved.
+std::string AbsolutePath(const std::string &filepath);
+
+// To and from UTF-8 unicode conversion functions
+
+// Convert a unicode code point into a UTF-8 representation by appending it
+// to a string. Returns the number of bytes generated.
+inline int ToUTF8(uint32_t ucc, std::string *out) {
+ FLATBUFFERS_ASSERT(!(ucc & 0x80000000)); // Top bit can't be set.
+ // 6 possible encodings: http://en.wikipedia.org/wiki/UTF-8
+ for (int i = 0; i < 6; i++) {
+ // Max bits this encoding can represent.
+ uint32_t max_bits = 6 + i * 5 + static_cast<int>(!i);
+ if (ucc < (1u << max_bits)) { // does it fit?
+ // Remaining bits not encoded in the first byte, store 6 bits each
+ uint32_t remain_bits = i * 6;
+ // Store first byte:
+ (*out) += static_cast<char>((0xFE << (max_bits - remain_bits)) |
+ (ucc >> remain_bits));
+ // Store remaining bytes:
+ for (int j = i - 1; j >= 0; j--) {
+ (*out) += static_cast<char>(((ucc >> (j * 6)) & 0x3F) | 0x80);
+ }
+ return i + 1; // Return the number of bytes added.
+ }
+ }
+ FLATBUFFERS_ASSERT(0); // Impossible to arrive here.
+ return -1;
+}
+
+// Converts whatever prefix of the incoming string corresponds to a valid
+// UTF-8 sequence into a unicode code. The incoming pointer will have been
+// advanced past all bytes parsed.
+// returns -1 upon corrupt UTF-8 encoding (ignore the incoming pointer in
+// this case).
+inline int FromUTF8(const char **in) {
+ int len = 0;
+ // Count leading 1 bits.
+ for (int mask = 0x80; mask >= 0x04; mask >>= 1) {
+ if (**in & mask) {
+ len++;
+ } else {
+ break;
+ }
+ }
+ if ((static_cast<unsigned char>(**in) << len) & 0x80)
+ return -1; // Bit after leading 1's must be 0.
+ if (!len) return *(*in)++;
+ // UTF-8 encoded values with a length are between 2 and 4 bytes.
+ if (len < 2 || len > 4) { return -1; }
+ // Grab initial bits of the code.
+ int ucc = *(*in)++ & ((1 << (7 - len)) - 1);
+ for (int i = 0; i < len - 1; i++) {
+ if ((**in & 0xC0) != 0x80) return -1; // Upper bits must 1 0.
+ ucc <<= 6;
+ ucc |= *(*in)++ & 0x3F; // Grab 6 more bits of the code.
+ }
+ // UTF-8 cannot encode values between 0xD800 and 0xDFFF (reserved for
+ // UTF-16 surrogate pairs).
+ if (ucc >= 0xD800 && ucc <= 0xDFFF) { return -1; }
+ // UTF-8 must represent code points in their shortest possible encoding.
+ switch (len) {
+ case 2:
+ // Two bytes of UTF-8 can represent code points from U+0080 to U+07FF.
+ if (ucc < 0x0080 || ucc > 0x07FF) { return -1; }
+ break;
+ case 3:
+ // Three bytes of UTF-8 can represent code points from U+0800 to U+FFFF.
+ if (ucc < 0x0800 || ucc > 0xFFFF) { return -1; }
+ break;
+ case 4:
+ // Four bytes of UTF-8 can represent code points from U+10000 to U+10FFFF.
+ if (ucc < 0x10000 || ucc > 0x10FFFF) { return -1; }
+ break;
+ }
+ return ucc;
+}
+
+#ifndef FLATBUFFERS_PREFER_PRINTF
+// Wraps a string to a maximum length, inserting new lines where necessary. Any
+// existing whitespace will be collapsed down to a single space. A prefix or
+// suffix can be provided, which will be inserted before or after a wrapped
+// line, respectively.
+inline std::string WordWrap(const std::string in, size_t max_length,
+ const std::string wrapped_line_prefix,
+ const std::string wrapped_line_suffix) {
+ std::istringstream in_stream(in);
+ std::string wrapped, line, word;
+
+ in_stream >> word;
+ line = word;
+
+ while (in_stream >> word) {
+ if ((line.length() + 1 + word.length() + wrapped_line_suffix.length()) <
+ max_length) {
+ line += " " + word;
+ } else {
+ wrapped += line + wrapped_line_suffix + "\n";
+ line = wrapped_line_prefix + word;
+ }
+ }
+ wrapped += line;
+
+ return wrapped;
+}
+#endif // !FLATBUFFERS_PREFER_PRINTF
+
+inline bool EscapeString(const char *s, size_t length, std::string *_text,
+ bool allow_non_utf8, bool natural_utf8) {
+ std::string &text = *_text;
+ text += "\"";
+ for (uoffset_t i = 0; i < length; i++) {
+ char c = s[i];
+ switch (c) {
+ case '\n': text += "\\n"; break;
+ case '\t': text += "\\t"; break;
+ case '\r': text += "\\r"; break;
+ case '\b': text += "\\b"; break;
+ case '\f': text += "\\f"; break;
+ case '\"': text += "\\\""; break;
+ case '\\': text += "\\\\"; break;
+ default:
+ if (c >= ' ' && c <= '~') {
+ text += c;
+ } else {
+ // Not printable ASCII data. Let's see if it's valid UTF-8 first:
+ const char *utf8 = s + i;
+ int ucc = FromUTF8(&utf8);
+ if (ucc < 0) {
+ if (allow_non_utf8) {
+ text += "\\x";
+ text += IntToStringHex(static_cast<uint8_t>(c), 2);
+ } else {
+ // There are two cases here:
+ //
+ // 1) We reached here by parsing an IDL file. In that case,
+ // we previously checked for non-UTF-8, so we shouldn't reach
+ // here.
+ //
+ // 2) We reached here by someone calling GenerateText()
+ // on a previously-serialized flatbuffer. The data might have
+ // non-UTF-8 Strings, or might be corrupt.
+ //
+ // In both cases, we have to give up and inform the caller
+ // they have no JSON.
+ return false;
+ }
+ } else {
+ if (natural_utf8) {
+ // utf8 points to past all utf-8 bytes parsed
+ text.append(s + i, static_cast<size_t>(utf8 - s - i));
+ } else if (ucc <= 0xFFFF) {
+ // Parses as Unicode within JSON's \uXXXX range, so use that.
+ text += "\\u";
+ text += IntToStringHex(ucc, 4);
+ } else if (ucc <= 0x10FFFF) {
+ // Encode Unicode SMP values to a surrogate pair using two \u
+ // escapes.
+ uint32_t base = ucc - 0x10000;
+ auto high_surrogate = (base >> 10) + 0xD800;
+ auto low_surrogate = (base & 0x03FF) + 0xDC00;
+ text += "\\u";
+ text += IntToStringHex(high_surrogate, 4);
+ text += "\\u";
+ text += IntToStringHex(low_surrogate, 4);
+ }
+ // Skip past characters recognized.
+ i = static_cast<uoffset_t>(utf8 - s - 1);
+ }
+ }
+ break;
+ }
+ }
+ text += "\"";
+ return true;
+}
+
+inline std::string BufferToHexText(const void *buffer, size_t buffer_size,
+ size_t max_length,
+ const std::string &wrapped_line_prefix,
+ const std::string &wrapped_line_suffix) {
+ std::string text = wrapped_line_prefix;
+ size_t start_offset = 0;
+ const char *s = reinterpret_cast<const char *>(buffer);
+ for (size_t i = 0; s && i < buffer_size; i++) {
+ // Last iteration or do we have more?
+ bool have_more = i + 1 < buffer_size;
+ text += "0x";
+ text += IntToStringHex(static_cast<uint8_t>(s[i]), 2);
+ if (have_more) { text += ','; }
+ // If we have more to process and we reached max_length
+ if (have_more &&
+ text.size() + wrapped_line_suffix.size() >= start_offset + max_length) {
+ text += wrapped_line_suffix;
+ text += '\n';
+ start_offset = text.size();
+ text += wrapped_line_prefix;
+ }
+ }
+ text += wrapped_line_suffix;
+ return text;
+}
+
+// Remove paired quotes in a string: "text"|'text' -> text.
+std::string RemoveStringQuotes(const std::string &s);
+
+// Change th global C-locale to locale with name <locale_name>.
+// Returns an actual locale name in <_value>, useful if locale_name is "" or
+// null.
+bool SetGlobalTestLocale(const char *locale_name,
+ std::string *_value = nullptr);
+
+// Read (or test) a value of environment variable.
+bool ReadEnvironmentVariable(const char *var_name,
+ std::string *_value = nullptr);
+
+// MSVC specific: Send all assert reports to STDOUT to prevent CI hangs.
+void SetupDefaultCRTReportMode();
+
+} // namespace flatbuffers
+
+#endif // FLATBUFFERS_UTIL_H_