aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorthegeorg <thegeorg@yandex-team.com>2024-03-16 14:05:11 +0300
committerthegeorg <thegeorg@yandex-team.com>2024-03-16 14:20:39 +0300
commit4e3ee6b12c3dacb5d556e9afad35dcd6efe58fa1 (patch)
tree7415c5c5bea98154299213abb536d01bcee6c8af
parentd83e7ea91cbc5e5d4ea49195eeab84c364dba4bb (diff)
downloadydb-4e3ee6b12c3dacb5d556e9afad35dcd6efe58fa1.tar.gz
Update contrib/libs/flatbuffers to 24.3.7
ba53b58280bb890a80379f491d436458add8f0ed
-rw-r--r--build/conf/java.conf2
-rw-r--r--build/prebuilt/contrib/tools/flatc/resources.json10
-rw-r--r--build/ymake.core.conf4
-rw-r--r--contrib/libs/flatbuffers/CHANGELOG.md8
-rw-r--r--contrib/libs/flatbuffers/README.md3
-rw-r--r--contrib/libs/flatbuffers/flatc/ya.make1
-rw-r--r--contrib/libs/flatbuffers/include/flatbuffers/base.h19
-rw-r--r--contrib/libs/flatbuffers/include/flatbuffers/flatbuffer_builder.h65
-rw-r--r--contrib/libs/flatbuffers/include/flatbuffers/flatbuffers.h16
-rw-r--r--contrib/libs/flatbuffers/include/flatbuffers/flexbuffers.h87
-rw-r--r--contrib/libs/flatbuffers/include/flatbuffers/idl.h20
-rw-r--r--contrib/libs/flatbuffers/include/flatbuffers/reflection_generated.h6
-rw-r--r--contrib/libs/flatbuffers/include/flatbuffers/stl_emulation.h3
-rw-r--r--contrib/libs/flatbuffers/include/flatbuffers/string.h5
-rw-r--r--contrib/libs/flatbuffers/include/flatbuffers/util.h5
-rw-r--r--contrib/libs/flatbuffers/src/bfbs_gen_nim.cpp1
-rw-r--r--contrib/libs/flatbuffers/src/flatc.cpp12
-rw-r--r--contrib/libs/flatbuffers/src/flatc_main.cpp15
-rw-r--r--contrib/libs/flatbuffers/src/idl_gen_cpp.cpp17
-rw-r--r--contrib/libs/flatbuffers/src/idl_gen_csharp.cpp8
-rw-r--r--contrib/libs/flatbuffers/src/idl_gen_go.cpp71
-rw-r--r--contrib/libs/flatbuffers/src/idl_gen_java.cpp2
-rw-r--r--contrib/libs/flatbuffers/src/idl_gen_kotlin.cpp2
-rw-r--r--contrib/libs/flatbuffers/src/idl_gen_kotlin.h2
-rw-r--r--contrib/libs/flatbuffers/src/idl_gen_kotlin_kmp.cpp1619
-rw-r--r--contrib/libs/flatbuffers/src/idl_gen_lobster.cpp46
-rw-r--r--contrib/libs/flatbuffers/src/idl_gen_python.cpp8
-rw-r--r--contrib/libs/flatbuffers/src/idl_gen_rust.cpp39
-rw-r--r--contrib/libs/flatbuffers/src/idl_gen_swift.cpp2
-rw-r--r--contrib/libs/flatbuffers/src/idl_gen_text.cpp20
-rw-r--r--contrib/libs/flatbuffers/src/idl_gen_ts.cpp15
-rw-r--r--contrib/libs/flatbuffers/src/idl_namer.h5
-rw-r--r--contrib/libs/flatbuffers/src/idl_parser.cpp27
-rw-r--r--contrib/libs/flatbuffers/src/namer.h8
-rw-r--r--contrib/libs/flatbuffers/src/util.cpp4
-rw-r--r--contrib/libs/flatbuffers/ya.make4
36 files changed, 1998 insertions, 183 deletions
diff --git a/build/conf/java.conf b/build/conf/java.conf
index 6d4480b5c9..6e5c3bfe8f 100644
--- a/build/conf/java.conf
+++ b/build/conf/java.conf
@@ -781,7 +781,7 @@ macro JAVA_RESOURCE(JAR, SOURCES="") {
}
# tag:java-specific tag:fbs
-JAVA_FLATBUFFERS_VERSION = 23.5.26
+JAVA_FLATBUFFERS_VERSION = 24.3.7
_KOTLIN_ALLOWED_VERSIONS = contrib/java/org/jetbrains/kotlin/kotlin-allopen/${_KOTLIN_VERSION} \
contrib/java/org/jetbrains/kotlin/kotlin-allopen-compiler-plugin/${_KOTLIN_VERSION} \
diff --git a/build/prebuilt/contrib/tools/flatc/resources.json b/build/prebuilt/contrib/tools/flatc/resources.json
index e6fbd1a12c..24c205107d 100644
--- a/build/prebuilt/contrib/tools/flatc/resources.json
+++ b/build/prebuilt/contrib/tools/flatc/resources.json
@@ -1,19 +1,19 @@
{
"by_platform": {
"darwin": {
- "uri": "sbr:5016255161"
+ "uri": "sbr:5983041213"
},
"darwin-arm64": {
- "uri": "sbr:5016250713"
+ "uri": "sbr:5983040151"
},
"linux": {
- "uri": "sbr:5016249124"
+ "uri": "sbr:5983042955"
},
"linux-aarch64": {
- "uri": "sbr:5016246978"
+ "uri": "sbr:5983042153"
},
"win32-clang-cl": {
- "uri": "sbr:5016265691"
+ "uri": "sbr:5983038870"
}
}
}
diff --git a/build/ymake.core.conf b/build/ymake.core.conf
index 7db071847b..ecc43c8ecd 100644
--- a/build/ymake.core.conf
+++ b/build/ymake.core.conf
@@ -16,7 +16,7 @@ CLANG_TIDY_FAKEID=2023-06-06
CYTHON_FAKE_ID=10784829
JAVA_FAKEID=108490091
PROTO_FAKEID=0
-FBS_FAKEID=2023-09-01
+FBS_FAKEID=2024-03-13
# Change of this value will invalidate some parts of configure cache
# but will not affect builds anyhow (except tests referring build/ directory)
@@ -4457,7 +4457,7 @@ macro _DECL_IN_DIR_GLOB(var_prefix, pattern, rec_part, SRCDIR="", EXCLBASE="", E
### 6. Parameters of macro are somewhat validated and we may add extra checks in the fulture including protection over too broad match.
###
macro DECLARE_IN_DIRS(var_prefix, PATTERN, SRCDIR="", RECURSIVE?"**/":"", EXCLUDES[], DIRS[]) {
- _DECL_IN_DIR_GLOB($var_prefix $PATTERN $RECURSIVE ${pre=SRCDIR ;suf=/:SRCDIR} ${pre=EXCLBASE ${ARCADIA_ROOT}/**/ DUMMY :SRCDIR} EXCLUDES ${EXCLUDES} DIRS ${DIRS})
+ _DECL_IN_DIR_GLOB($var_prefix $PATTERN $RECURSIVE ${pre=SRCDIR ;suf=/:SRCDIR} ${pre=EXCLBASE ${ARCADIA_ROOT}/**/ DUMMY :SRCDIR} EXCLUDES ${EXCLUDES} DIRS ${DIRS})
SET(${var_prefix}_FILES \$_${var_prefix}_FILES)
SET(${var_prefix}_SRCDIR $SRCDIR)
diff --git a/contrib/libs/flatbuffers/CHANGELOG.md b/contrib/libs/flatbuffers/CHANGELOG.md
index 145c62b109..c7d1157f2f 100644
--- a/contrib/libs/flatbuffers/CHANGELOG.md
+++ b/contrib/libs/flatbuffers/CHANGELOG.md
@@ -4,6 +4,14 @@ All major or breaking changes will be documented in this file, as well as any
new features that should be highlighted. Minor fixes or improvements are not
necessarily listed.
+## [24.3.7] (March 7 2024)(https://github.com/google/flatbuffers/releases/tag/v24.3.7)
+
+* Just to fix some of the CI build issues from the 24.3.6 release.
+
+## [24.3.6] (March 6 2024)(https://github.com/google/flatbuffers/releases/tag/v24.3.6)
+
+* Fix typescript object API to allow 0 values for null-default scalars (#7864)
+
## [23.5.26 (May 26 2023)](https://github.com/google/flatbuffers/releases/tag/v23.5.26)
* Mostly bug fixing for 64-bit support
diff --git a/contrib/libs/flatbuffers/README.md b/contrib/libs/flatbuffers/README.md
index 875c73bb9c..47d506720e 100644
--- a/contrib/libs/flatbuffers/README.md
+++ b/contrib/libs/flatbuffers/README.md
@@ -98,10 +98,7 @@ FlatBuffers does not follow traditional SemVer versioning (see [rationale](https
## Community
-* [FlatBuffers Google Group][] to discuss FlatBuffers with other developers and users.
* [Discord Server](https:///discord.gg/6qgKs3R)
-* [Gitter](https://gitter.im/google/flatbuffers)
-
## Security
diff --git a/contrib/libs/flatbuffers/flatc/ya.make b/contrib/libs/flatbuffers/flatc/ya.make
index 63f20cda2d..1b01423fab 100644
--- a/contrib/libs/flatbuffers/flatc/ya.make
+++ b/contrib/libs/flatbuffers/flatc/ya.make
@@ -52,6 +52,7 @@ SRCS(
src/idl_gen_java.cpp
src/idl_gen_json_schema.cpp
src/idl_gen_kotlin.cpp
+ src/idl_gen_kotlin_kmp.cpp
src/idl_gen_lobster.cpp
src/idl_gen_php.cpp
src/idl_gen_python.cpp
diff --git a/contrib/libs/flatbuffers/include/flatbuffers/base.h b/contrib/libs/flatbuffers/include/flatbuffers/base.h
index 506fd545d1..43cfae7fe5 100644
--- a/contrib/libs/flatbuffers/include/flatbuffers/base.h
+++ b/contrib/libs/flatbuffers/include/flatbuffers/base.h
@@ -139,9 +139,9 @@
#endif
#endif // !defined(FLATBUFFERS_LITTLEENDIAN)
-#define FLATBUFFERS_VERSION_MAJOR 23
-#define FLATBUFFERS_VERSION_MINOR 5
-#define FLATBUFFERS_VERSION_REVISION 26
+#define FLATBUFFERS_VERSION_MAJOR 24
+#define FLATBUFFERS_VERSION_MINOR 3
+#define FLATBUFFERS_VERSION_REVISION 7
#define FLATBUFFERS_STRING_EXPAND(X) #X
#define FLATBUFFERS_STRING(X) FLATBUFFERS_STRING_EXPAND(X)
namespace flatbuffers {
@@ -155,7 +155,7 @@ namespace flatbuffers {
#define FLATBUFFERS_FINAL_CLASS final
#define FLATBUFFERS_OVERRIDE override
#define FLATBUFFERS_EXPLICIT_CPP11 explicit
- #define FLATBUFFERS_VTABLE_UNDERLYING_TYPE : flatbuffers::voffset_t
+ #define FLATBUFFERS_VTABLE_UNDERLYING_TYPE : ::flatbuffers::voffset_t
#else
#define FLATBUFFERS_FINAL_CLASS
#define FLATBUFFERS_OVERRIDE
@@ -289,12 +289,12 @@ namespace flatbuffers {
#define FLATBUFFERS_SUPPRESS_UBSAN(type)
#endif
-// This is constexpr function used for checking compile-time constants.
-// Avoid `#pragma warning(disable: 4127) // C4127: expression is constant`.
namespace flatbuffers {
-template<typename T> FLATBUFFERS_CONSTEXPR inline bool IsConstTrue(T t) {
- return !!t;
-}
+ // This is constexpr function used for checking compile-time constants.
+ // Avoid `#pragma warning(disable: 4127) // C4127: expression is constant`.
+ template<typename T> FLATBUFFERS_CONSTEXPR inline bool IsConstTrue(T t) {
+ return !!t;
+ }
}
// Enable C++ attribute [[]] if std:c++17 or higher.
@@ -363,7 +363,6 @@ inline bool VerifyAlignmentRequirements(size_t align, size_t min_align = 1) {
}
#if defined(_MSC_VER)
- #pragma warning(disable: 4351) // C4351: new behavior: elements of array ... will be default initialized
#pragma warning(push)
#pragma warning(disable: 4127) // C4127: conditional expression is constant
#endif
diff --git a/contrib/libs/flatbuffers/include/flatbuffers/flatbuffer_builder.h b/contrib/libs/flatbuffers/include/flatbuffers/flatbuffer_builder.h
index f97daa4046..774b6bdba6 100644
--- a/contrib/libs/flatbuffers/include/flatbuffers/flatbuffer_builder.h
+++ b/contrib/libs/flatbuffers/include/flatbuffers/flatbuffer_builder.h
@@ -45,8 +45,9 @@ inline voffset_t FieldIndexToOffset(voffset_t field_id) {
// Should correspond to what EndTable() below builds up.
const voffset_t fixed_fields =
2 * sizeof(voffset_t); // Vtable size and Object Size.
- return fixed_fields + field_id * sizeof(voffset_t);
-}
+ size_t offset = fixed_fields + field_id * sizeof(voffset_t);
+ FLATBUFFERS_ASSERT(offset < std::numeric_limits<voffset_t>::max());
+ return static_cast<voffset_t>(offset);}
template<typename T, typename Alloc = std::allocator<T>>
const T *data(const std::vector<T, Alloc> &v) {
@@ -220,21 +221,13 @@ template<bool Is64Aware = false> class FlatBufferBuilderImpl {
/// @return Returns a `uint8_t` pointer to the unfinished buffer.
uint8_t *GetCurrentBufferPointer() const { return buf_.data(); }
- /// @brief Get the released pointer to the serialized buffer.
- /// @warning Do NOT attempt to use this FlatBufferBuilder afterwards!
- /// @return A `FlatBuffer` that owns the buffer and its allocator and
- /// behaves similar to a `unique_ptr` with a deleter.
- FLATBUFFERS_ATTRIBUTE([[deprecated("use Release() instead")]])
- DetachedBuffer ReleaseBufferPointer() {
- Finished();
- return buf_.release();
- }
-
/// @brief Get the released DetachedBuffer.
/// @return A `DetachedBuffer` that owns the buffer and its allocator.
DetachedBuffer Release() {
Finished();
- return buf_.release();
+ DetachedBuffer buffer = buf_.release();
+ Clear();
+ return buffer;
}
/// @brief Get the released pointer to the serialized buffer.
@@ -245,10 +238,12 @@ template<bool Is64Aware = false> class FlatBufferBuilderImpl {
/// @return A raw pointer to the start of the memory block containing
/// the serialized `FlatBuffer`.
/// @remark If the allocator is owned, it gets deleted when the destructor is
- /// called..
+ /// called.
uint8_t *ReleaseRaw(size_t &size, size_t &offset) {
Finished();
- return buf_.release_raw(size, offset);
+ uint8_t* raw = buf_.release_raw(size, offset);
+ Clear();
+ return raw;
}
/// @brief get the minimum alignment this buffer needs to be accessed
@@ -566,7 +561,7 @@ template<bool Is64Aware = false> class FlatBufferBuilderImpl {
return CreateString<OffsetT>(str.c_str(), str.length());
}
- // clang-format off
+// clang-format off
#ifdef FLATBUFFERS_HAS_STRING_VIEW
/// @brief Store a string in the buffer, which can contain any binary data.
/// @param[in] str A const string_view to copy in to the buffer.
@@ -588,7 +583,7 @@ template<bool Is64Aware = false> class FlatBufferBuilderImpl {
/// @brief Store a string in the buffer, which can contain any binary data.
/// @param[in] str A const reference to a std::string like type with support
- /// of T::c_str() and T::length() to store in the buffer.
+ /// of T::data() and T::length() to store in the buffer.
/// @return Returns the offset in the buffer where the string starts.
template<template<typename> class OffsetT = Offset,
// No need to explicitly declare the T type, let the compiler deduce
@@ -698,12 +693,27 @@ template<bool Is64Aware = false> class FlatBufferBuilderImpl {
// normally dictate.
// This is useful when storing a nested_flatbuffer in a vector of bytes,
// or when storing SIMD floats, etc.
- void ForceVectorAlignment(size_t len, size_t elemsize, size_t alignment) {
+ void ForceVectorAlignment(const size_t len, const size_t elemsize,
+ const size_t alignment) {
if (len == 0) return;
FLATBUFFERS_ASSERT(VerifyAlignmentRequirements(alignment));
PreAlign(len * elemsize, alignment);
}
+ template<bool is_64 = Is64Aware>
+ typename std::enable_if<is_64, void>::type ForceVectorAlignment64(
+ const size_t len, const size_t elemsize, const size_t alignment) {
+ // If you hit this assertion, you are trying to force alignment on a
+ // vector with offset64 after serializing a 32-bit offset.
+ FLATBUFFERS_ASSERT(GetSize() == length_of_64_bit_region_);
+
+ // Call through.
+ ForceVectorAlignment(len, elemsize, alignment);
+
+ // Update the 64 bit region.
+ length_of_64_bit_region_ = GetSize();
+ }
+
// Similar to ForceVectorAlignment but for String fields.
void ForceStringAlignment(size_t len, size_t alignment) {
if (len == 0) return;
@@ -733,7 +743,7 @@ template<bool Is64Aware = false> class FlatBufferBuilderImpl {
AssertScalarT<T>();
StartVector<T, OffsetT, LenT>(len);
if (len > 0) {
- // clang-format off
+// clang-format off
#if FLATBUFFERS_LITTLEENDIAN
PushBytes(reinterpret_cast<const uint8_t *>(v), len * sizeof(T));
#else
@@ -864,7 +874,9 @@ template<bool Is64Aware = false> class FlatBufferBuilderImpl {
/// where the vector is stored.
template<class It>
Offset<Vector<Offset<String>>> CreateVectorOfStrings(It begin, It end) {
- auto size = std::distance(begin, end);
+ auto distance = std::distance(begin, end);
+ FLATBUFFERS_ASSERT(distance >= 0);
+ auto size = static_cast<size_t>(distance);
auto scratch_buffer_usage = size * sizeof(Offset<String>);
// If there is not enough space to store the offsets, there definitely won't
// be enough space to store all the strings. So ensuring space for the
@@ -874,7 +886,7 @@ template<bool Is64Aware = false> class FlatBufferBuilderImpl {
buf_.scratch_push_small(CreateString(*it));
}
StartVector<Offset<String>>(size);
- for (auto i = 1; i <= size; i++) {
+ for (size_t i = 1; i <= size; i++) {
// Note we re-evaluate the buf location each iteration to account for any
// underlying buffer resizing that may occur.
PushElement(*reinterpret_cast<Offset<String> *>(
@@ -898,8 +910,7 @@ template<bool Is64Aware = false> class FlatBufferBuilderImpl {
typedef typename VectorT<T>::size_type LenT;
typedef typename OffsetT<VectorT<const T *>>::offset_type offset_type;
- StartVector<OffsetT, LenT>(len * sizeof(T) / AlignOf<T>(), sizeof(T),
- AlignOf<T>());
+ StartVector<OffsetT, LenT>(len, sizeof(T), AlignOf<T>());
if (len > 0) {
PushBytes(reinterpret_cast<const uint8_t *>(v), sizeof(T) * len);
}
@@ -1244,6 +1255,9 @@ template<bool Is64Aware = false> class FlatBufferBuilderImpl {
FlatBufferBuilderImpl &operator=(const FlatBufferBuilderImpl &);
void Finish(uoffset_t root, const char *file_identifier, bool size_prefix) {
+ // A buffer can only be finished once. To reuse a builder use `clear()`.
+ FLATBUFFERS_ASSERT(!finished);
+
NotNested();
buf_.clear_scratch();
@@ -1369,8 +1383,7 @@ template<bool Is64Aware = false> class FlatBufferBuilderImpl {
// Must be completed with EndVectorOfStructs().
template<typename T, template<typename> class OffsetT = Offset>
T *StartVectorOfStructs(size_t vector_size) {
- StartVector<OffsetT>(vector_size * sizeof(T) / AlignOf<T>(), sizeof(T),
- AlignOf<T>());
+ StartVector<OffsetT>(vector_size, sizeof(T), AlignOf<T>());
return reinterpret_cast<T *>(buf_.make_space(vector_size * sizeof(T)));
}
@@ -1456,7 +1469,7 @@ T *GetMutableTemporaryPointer(FlatBufferBuilder &fbb, Offset<T> offset) {
}
template<typename T>
-const T *GetTemporaryPointer(FlatBufferBuilder &fbb, Offset<T> offset) {
+const T *GetTemporaryPointer(const FlatBufferBuilder &fbb, Offset<T> offset) {
return GetMutableTemporaryPointer<T>(fbb, offset);
}
diff --git a/contrib/libs/flatbuffers/include/flatbuffers/flatbuffers.h b/contrib/libs/flatbuffers/include/flatbuffers/flatbuffers.h
index 952ea3bcdf..1a81821b54 100644
--- a/contrib/libs/flatbuffers/include/flatbuffers/flatbuffers.h
+++ b/contrib/libs/flatbuffers/include/flatbuffers/flatbuffers.h
@@ -248,31 +248,31 @@ inline const char *flatbuffers_version_string() {
// clang-format off
#define FLATBUFFERS_DEFINE_BITMASK_OPERATORS(E, T)\
- inline E operator | (E lhs, E rhs){\
+ inline FLATBUFFERS_CONSTEXPR_CPP11 E operator | (E lhs, E rhs){\
return E(T(lhs) | T(rhs));\
}\
- inline E operator & (E lhs, E rhs){\
+ inline FLATBUFFERS_CONSTEXPR_CPP11 E operator & (E lhs, E rhs){\
return E(T(lhs) & T(rhs));\
}\
- inline E operator ^ (E lhs, E rhs){\
+ inline FLATBUFFERS_CONSTEXPR_CPP11 E operator ^ (E lhs, E rhs){\
return E(T(lhs) ^ T(rhs));\
}\
- inline E operator ~ (E lhs){\
+ inline FLATBUFFERS_CONSTEXPR_CPP11 E operator ~ (E lhs){\
return E(~T(lhs));\
}\
- inline E operator |= (E &lhs, E rhs){\
+ inline FLATBUFFERS_CONSTEXPR_CPP11 E operator |= (E &lhs, E rhs){\
lhs = lhs | rhs;\
return lhs;\
}\
- inline E operator &= (E &lhs, E rhs){\
+ inline FLATBUFFERS_CONSTEXPR_CPP11 E operator &= (E &lhs, E rhs){\
lhs = lhs & rhs;\
return lhs;\
}\
- inline E operator ^= (E &lhs, E rhs){\
+ inline FLATBUFFERS_CONSTEXPR_CPP11 E operator ^= (E &lhs, E rhs){\
lhs = lhs ^ rhs;\
return lhs;\
}\
- inline bool operator !(E rhs) \
+ inline FLATBUFFERS_CONSTEXPR_CPP11 bool operator !(E rhs) \
{\
return !bool(T(rhs)); \
}
diff --git a/contrib/libs/flatbuffers/include/flatbuffers/flexbuffers.h b/contrib/libs/flatbuffers/include/flatbuffers/flexbuffers.h
index 1fdffb424e..7b5b20b701 100644
--- a/contrib/libs/flatbuffers/include/flatbuffers/flexbuffers.h
+++ b/contrib/libs/flatbuffers/include/flatbuffers/flexbuffers.h
@@ -360,16 +360,40 @@ class Map : public Vector {
bool IsTheEmptyMap() const { return data_ == EmptyMap().data_; }
};
+inline void IndentString(std::string &s, int indent,
+ const char *indent_string) {
+ for (int i = 0; i < indent; i++) s += indent_string;
+}
+
template<typename T>
-void AppendToString(std::string &s, T &&v, bool keys_quoted) {
- s += "[ ";
+void AppendToString(std::string &s, T &&v, bool keys_quoted, bool indented,
+ int cur_indent, const char *indent_string) {
+ s += "[";
+ s += indented ? "\n" : " ";
for (size_t i = 0; i < v.size(); i++) {
- if (i) s += ", ";
- v[i].ToString(true, keys_quoted, s);
+ if (i) {
+ s += ",";
+ s += indented ? "\n" : " ";
+ }
+ if (indented) IndentString(s, cur_indent, indent_string);
+ v[i].ToString(true, keys_quoted, s, indented, cur_indent,
+ indent_string);
}
- s += " ]";
+ if (indented) {
+ s += "\n";
+ IndentString(s, cur_indent - 1, indent_string);
+ } else {
+ s += " ";
+ }
+ s += "]";
}
+template<typename T>
+void AppendToString(std::string &s, T &&v, bool keys_quoted) {
+ AppendToString(s, v, keys_quoted);
+}
+
+
class Reference {
public:
Reference()
@@ -542,8 +566,13 @@ class Reference {
// 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 {
+ ToString(strings_quoted, keys_quoted, s, false, 0, "");
+ }
+
+ // This version additionally allow you to specify if you want indentation.
+ void ToString(bool strings_quoted, bool keys_quoted, std::string &s,
+ bool indented, int cur_indent, const char *indent_string) const {
if (type_ == FBT_STRING) {
String str(Indirect(), byte_width_);
if (strings_quoted) {
@@ -569,7 +598,8 @@ class Reference {
} else if (IsBool()) {
s += AsBool() ? "true" : "false";
} else if (IsMap()) {
- s += "{ ";
+ s += "{";
+ s += indented ? "\n" : " ";
auto m = AsMap();
auto keys = m.Keys();
auto vals = m.Values();
@@ -590,18 +620,28 @@ class Reference {
}
}
}
+ if (indented) IndentString(s, cur_indent + 1, indent_string);
keys[i].ToString(true, kq, s);
s += ": ";
- vals[i].ToString(true, keys_quoted, s);
- if (i < keys.size() - 1) s += ", ";
+ vals[i].ToString(true, keys_quoted, s, indented, cur_indent + 1, indent_string);
+ if (i < keys.size() - 1) {
+ s += ",";
+ if (!indented) s += " ";
+ }
+ if (indented) s += "\n";
}
- s += " }";
+ if (!indented) s += " ";
+ if (indented) IndentString(s, cur_indent, indent_string);
+ s += "}";
} else if (IsVector()) {
- AppendToString<Vector>(s, AsVector(), keys_quoted);
+ AppendToString<Vector>(s, AsVector(), keys_quoted, indented,
+ cur_indent + 1, indent_string);
} else if (IsTypedVector()) {
- AppendToString<TypedVector>(s, AsTypedVector(), keys_quoted);
+ AppendToString<TypedVector>(s, AsTypedVector(), keys_quoted, indented,
+ cur_indent + 1, indent_string);
} else if (IsFixedTypedVector()) {
- AppendToString<FixedTypedVector>(s, AsFixedTypedVector(), keys_quoted);
+ AppendToString<FixedTypedVector>(s, AsFixedTypedVector(), keys_quoted,
+ indented, cur_indent + 1, indent_string);
} else if (IsBlob()) {
auto blob = AsBlob();
flatbuffers::EscapeString(reinterpret_cast<const char *>(blob.data()),
@@ -1128,10 +1168,7 @@ class Builder FLATBUFFERS_FINAL_CLASS {
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;
+ auto len = MapElementCount(start);
// Make sure keys are all strings:
for (auto key = start; key < stack_.size(); key += 2) {
FLATBUFFERS_ASSERT(stack_[key].type_ == FBT_KEY);
@@ -1289,6 +1326,14 @@ class Builder FLATBUFFERS_FINAL_CLASS {
EndMap(start);
}
+ size_t MapElementCount(size_t start) {
+ // Make sure it is an even number:
+ auto len = stack_.size() - start;
+ FLATBUFFERS_ASSERT(!(len & 1));
+ len /= 2;
+ return len;
+ }
+
// 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
@@ -1307,6 +1352,12 @@ class Builder FLATBUFFERS_FINAL_CLASS {
ReuseValue(v);
}
+ // Undo the last element serialized. Call once for a value and once for a
+ // key.
+ void Undo() {
+ stack_.pop_back();
+ }
+
// Overloaded Add that tries to call the correct function above.
void Add(int8_t i) { Int(i); }
void Add(int16_t i) { Int(i); }
@@ -1669,7 +1720,7 @@ class Verifier FLATBUFFERS_FINAL_CLASS {
max_vectors_(buf_len),
check_alignment_(_check_alignment),
reuse_tracker_(reuse_tracker) {
- FLATBUFFERS_ASSERT(size_ < FLATBUFFERS_MAX_BUFFER_SIZE);
+ FLATBUFFERS_ASSERT(static_cast<int32_t>(size_) < FLATBUFFERS_MAX_BUFFER_SIZE);
if (reuse_tracker_) {
reuse_tracker_->clear();
reuse_tracker_->resize(size_, PackedType(BIT_WIDTH_8, FBT_NULL));
diff --git a/contrib/libs/flatbuffers/include/flatbuffers/idl.h b/contrib/libs/flatbuffers/include/flatbuffers/idl.h
index f65f18a9ab..9b9e98fcf4 100644
--- a/contrib/libs/flatbuffers/include/flatbuffers/idl.h
+++ b/contrib/libs/flatbuffers/include/flatbuffers/idl.h
@@ -342,7 +342,10 @@ struct FieldDef : public Definition {
bool Deserialize(Parser &parser, const reflection::Field *field);
bool IsScalarOptional() const {
- return IsScalar(value.type.base_type) && IsOptional();
+ return IsScalar() && IsOptional();
+ }
+ bool IsScalar() const {
+ return ::flatbuffers::IsScalar(value.type.base_type);
}
bool IsOptional() const { return presence == kOptional; }
bool IsRequired() const { return presence == kRequired; }
@@ -673,6 +676,7 @@ struct IDLOptions {
bool binary_schema_comments;
bool binary_schema_builtins;
bool binary_schema_gen_embed;
+ bool binary_schema_absolute_paths;
std::string go_import;
std::string go_namespace;
std::string go_module_name;
@@ -703,6 +707,7 @@ struct IDLOptions {
bool keep_proto_id;
bool python_no_type_prefix_suffix;
bool python_typing;
+ bool ts_omit_entrypoint;
ProtoIdGapAction proto_id_gap_action;
// Possible options for the more general generator below.
@@ -726,6 +731,7 @@ struct IDLOptions {
kCppYandexMapsIter = 1 << 19,
kNim = 1 << 17,
kProto = 1 << 18,
+ kKotlinKmp = 1 << 19,
kMAX
};
@@ -792,6 +798,7 @@ struct IDLOptions {
binary_schema_comments(false),
binary_schema_builtins(false),
binary_schema_gen_embed(false),
+ binary_schema_absolute_paths(false),
protobuf_ascii_alike(false),
size_prefixed(false),
force_defaults(false),
@@ -815,6 +822,7 @@ struct IDLOptions {
keep_proto_id(false),
python_no_type_prefix_suffix(false),
python_typing(false),
+ ts_omit_entrypoint(false),
proto_id_gap_action(ProtoIdGapAction::WARNING),
mini_reflect(IDLOptions::kNone),
require_explicit_ids(false),
@@ -1215,6 +1223,16 @@ class Parser : public ParserState {
// These functions return nullptr on success, or an error string,
// which may happen if the flatbuffer cannot be encoded in JSON (e.g.,
// it contains non-UTF-8 byte arrays in String values).
+extern bool GenerateTextFromTable(const Parser &parser,
+ const void *table,
+ const std::string &tablename,
+ std::string *text);
+extern const char *GenerateText(const Parser &parser, const void *flatbuffer,
+ std::string *text);
+extern const char *GenerateTextFile(const Parser &parser,
+ const std::string &path,
+ const std::string &file_name);
+
extern const char *GenTextFromTable(const Parser &parser, const void *table,
const std::string &tablename,
std::string *text);
diff --git a/contrib/libs/flatbuffers/include/flatbuffers/reflection_generated.h b/contrib/libs/flatbuffers/include/flatbuffers/reflection_generated.h
index 4690434db6..9f83dcb5d4 100644
--- a/contrib/libs/flatbuffers/include/flatbuffers/reflection_generated.h
+++ b/contrib/libs/flatbuffers/include/flatbuffers/reflection_generated.h
@@ -8,9 +8,9 @@
// Ensure the included flatbuffers.h is the same version as when this file was
// generated, otherwise it may not be compatible.
-static_assert(FLATBUFFERS_VERSION_MAJOR == 23 &&
- FLATBUFFERS_VERSION_MINOR == 5 &&
- FLATBUFFERS_VERSION_REVISION == 26,
+static_assert(FLATBUFFERS_VERSION_MAJOR == 24 &&
+ FLATBUFFERS_VERSION_MINOR == 3 &&
+ FLATBUFFERS_VERSION_REVISION == 7,
"Non-compatible flatbuffers version included");
namespace reflection {
diff --git a/contrib/libs/flatbuffers/include/flatbuffers/stl_emulation.h b/contrib/libs/flatbuffers/include/flatbuffers/stl_emulation.h
index c085952b60..6054f78fa6 100644
--- a/contrib/libs/flatbuffers/include/flatbuffers/stl_emulation.h
+++ b/contrib/libs/flatbuffers/include/flatbuffers/stl_emulation.h
@@ -45,7 +45,8 @@
// Testing __cpp_lib_span requires including either <version> or <span>,
// both of which were added in C++20.
// See: https://en.cppreference.com/w/cpp/utility/feature_test
- #if defined(__cplusplus) && __cplusplus >= 202002L
+ #if defined(__cplusplus) && __cplusplus >= 202002L \
+ || (defined(_MSVC_LANG) && _MSVC_LANG >= 202002L)
#define FLATBUFFERS_USE_STD_SPAN 1
#endif
#endif // FLATBUFFERS_USE_STD_SPAN
diff --git a/contrib/libs/flatbuffers/include/flatbuffers/string.h b/contrib/libs/flatbuffers/include/flatbuffers/string.h
index e6b98f0c9f..d33fbfaa88 100644
--- a/contrib/libs/flatbuffers/include/flatbuffers/string.h
+++ b/contrib/libs/flatbuffers/include/flatbuffers/string.h
@@ -31,6 +31,11 @@ struct String : public Vector<char> {
flatbuffers::string_view string_view() const {
return flatbuffers::string_view(c_str(), size());
}
+
+ /* implicit */
+ operator flatbuffers::string_view() const {
+ return flatbuffers::string_view(c_str(), size());
+ }
#endif // FLATBUFFERS_HAS_STRING_VIEW
// clang-format on
diff --git a/contrib/libs/flatbuffers/include/flatbuffers/util.h b/contrib/libs/flatbuffers/include/flatbuffers/util.h
index c781b7e233..6151f4e025 100644
--- a/contrib/libs/flatbuffers/include/flatbuffers/util.h
+++ b/contrib/libs/flatbuffers/include/flatbuffers/util.h
@@ -479,6 +479,11 @@ std::string PosixPath(const std::string &path);
// creating dirs for any parts of the path that don't exist yet.
void EnsureDirExists(const std::string &filepath);
+// Obtains the relative or absolute path.
+std::string FilePath(const std::string &project,
+ const std::string &filePath,
+ bool absolute);
+
// 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);
diff --git a/contrib/libs/flatbuffers/src/bfbs_gen_nim.cpp b/contrib/libs/flatbuffers/src/bfbs_gen_nim.cpp
index a8f4ee0c74..25da044d1a 100644
--- a/contrib/libs/flatbuffers/src/bfbs_gen_nim.cpp
+++ b/contrib/libs/flatbuffers/src/bfbs_gen_nim.cpp
@@ -77,7 +77,6 @@ Namer::Config NimDefaultConfig() {
/*filename_extension=*/".nim" };
}
-const std::string Indent = " ";
const std::string Export = "*";
const std::set<std::string> builtin_types = {
"uint8", "uint8", "bool", "int8", "uint8", "int16",
diff --git a/contrib/libs/flatbuffers/src/flatc.cpp b/contrib/libs/flatbuffers/src/flatc.cpp
index 202c3d644a..f29d109264 100644
--- a/contrib/libs/flatbuffers/src/flatc.cpp
+++ b/contrib/libs/flatbuffers/src/flatc.cpp
@@ -187,6 +187,7 @@ const static FlatCOption flatc_options[] = {
"relative to. The 'root' is denoted with `//`. E.g. if PATH=/a/b/c "
"then /a/d/e.fbs will be serialized as //../d/e.fbs. (PATH defaults to the "
"directory of the first provided schema file." },
+ { "", "bfbs-absolute-paths", "", "Uses absolute paths instead of relative paths in the BFBS output." },
{ "", "bfbs-comments", "", "Add doc comments to the binary schema files." },
{ "", "bfbs-builtins", "",
"Add builtin attributes to the binary schema files." },
@@ -253,6 +254,8 @@ const static FlatCOption flatc_options[] = {
{ "", "python-no-type-prefix-suffix", "",
"Skip emission of Python functions that are prefixed with typenames" },
{ "", "python-typing", "", "Generate Python type annotations" },
+ { "", "ts-omit-entrypoint", "",
+ "Omit emission of namespace entrypoint file" },
{ "", "file-names-only", "",
"Print out generated file names without writing to the files" },
};
@@ -594,6 +597,8 @@ FlatCOptions FlatCompiler::ParseFromCommandLineArguments(int argc,
opts.binary_schema_builtins = true;
} else if (arg == "--bfbs-gen-embed") {
opts.binary_schema_gen_embed = true;
+ } else if (arg == "--bfbs-absolute-paths") {
+ opts.binary_schema_absolute_paths = true;
} else if (arg == "--reflect-types") {
opts.mini_reflect = IDLOptions::kTypes;
} else if (arg == "--reflect-names") {
@@ -659,6 +664,8 @@ FlatCOptions FlatCompiler::ParseFromCommandLineArguments(int argc,
opts.python_no_type_prefix_suffix = true;
} else if (arg == "--python-typing") {
opts.python_typing = true;
+ } else if (arg == "--ts-omit-entrypoint") {
+ opts.ts_omit_entrypoint = true;
} else if (arg == "--annotate-sparse-vectors") {
options.annotate_include_vector_contents = false;
} else if (arg == "--annotate") {
@@ -720,6 +727,11 @@ void FlatCompiler::ValidateOptions(const FlatCOptions &options) {
flatbuffers::Parser FlatCompiler::GetConformParser(
const FlatCOptions &options) {
flatbuffers::Parser conform_parser;
+
+ // conform parser should check advanced options,
+ // so, it have to have knowledge about languages:
+ conform_parser.opts.lang_to_generate = options.opts.lang_to_generate;
+
if (!options.conform_to_schema.empty()) {
std::string contents;
if (!flatbuffers::LoadFile(options.conform_to_schema.c_str(), true,
diff --git a/contrib/libs/flatbuffers/src/flatc_main.cpp b/contrib/libs/flatbuffers/src/flatc_main.cpp
index f2dde958d3..a65804f4d3 100644
--- a/contrib/libs/flatbuffers/src/flatc_main.cpp
+++ b/contrib/libs/flatbuffers/src/flatc_main.cpp
@@ -127,6 +127,11 @@ int main(int argc, const char *argv[]) {
flatbuffers::NewKotlinCodeGenerator());
flatc.RegisterCodeGenerator(
+ flatbuffers::FlatCOption{ "", "kotlin-kmp", "",
+ "Generate Kotlin multiplatform classes for tables/structs" },
+ flatbuffers::NewKotlinKMPCodeGenerator());
+
+ flatc.RegisterCodeGenerator(
flatbuffers::FlatCOption{ "", "lobster", "",
"Generate Lobster files for tables/structs" },
flatbuffers::NewLobsterCodeGenerator());
@@ -162,16 +167,16 @@ int main(int argc, const char *argv[]) {
flatbuffers::NewTextCodeGenerator());
flatc.RegisterCodeGenerator(
- flatbuffers::FlatCOption{ "", "swift", "",
- "Generate Swift files for tables/structs" },
- flatbuffers::NewSwiftCodeGenerator());
-
- flatc.RegisterCodeGenerator(
flatbuffers::FlatCOption{ "", "yandex-maps-iter", "",
"Generate C++ template headers for tables/structs" },
flatbuffers::NewCppYandexMapsIterCodeGenerator());
flatc.RegisterCodeGenerator(
+ flatbuffers::FlatCOption{ "", "swift", "",
+ "Generate Swift files for tables/structs" },
+ flatbuffers::NewSwiftCodeGenerator());
+
+ flatc.RegisterCodeGenerator(
flatbuffers::FlatCOption{ "T", "ts", "",
"Generate TypeScript code for tables/structs" },
flatbuffers::NewTsCodeGenerator());
diff --git a/contrib/libs/flatbuffers/src/idl_gen_cpp.cpp b/contrib/libs/flatbuffers/src/idl_gen_cpp.cpp
index 21a21b8370..47fd153347 100644
--- a/contrib/libs/flatbuffers/src/idl_gen_cpp.cpp
+++ b/contrib/libs/flatbuffers/src/idl_gen_cpp.cpp
@@ -777,10 +777,10 @@ class CppGenerator : public BaseGenerator {
if (type.enum_def) return WrapInNameSpace(*type.enum_def);
if (type.base_type == BASE_TYPE_BOOL) return "bool";
}
- // Get real underlying type for union type
+ // Get real underlying type for union type
auto base_type = type.base_type;
if (type.base_type == BASE_TYPE_UTYPE && type.enum_def != nullptr) {
- base_type = type.enum_def->underlying_type.base_type;
+ base_type = type.enum_def->underlying_type.base_type;
}
return StringOf(base_type);
}
@@ -1051,7 +1051,9 @@ class CppGenerator : public BaseGenerator {
std::string UnionVectorVerifySignature(const EnumDef &enum_def) {
const std::string name = Name(enum_def);
- const std::string &type = opts_.scoped_enums ? name : GenTypeBasic(enum_def.underlying_type, false);
+ const std::string &type =
+ opts_.scoped_enums ? name
+ : GenTypeBasic(enum_def.underlying_type, false);
return "bool Verify" + name + "Vector" +
"(::flatbuffers::Verifier &verifier, " +
"const ::flatbuffers::Vector<::flatbuffers::Offset<void>> "
@@ -2930,8 +2932,10 @@ class CppGenerator : public BaseGenerator {
const std::string &type =
IsStruct(vtype) ? WrapInNameSpace(*vtype.struct_def)
: GenTypeWire(vtype, "", false, field.offset64);
- return "_fbb.ForceVectorAlignment(" + field_size + ", sizeof(" + type +
- "), " + std::to_string(static_cast<long long>(align)) + ");";
+ return std::string("_fbb.ForceVectorAlignment") +
+ (field.offset64 ? "64" : "") + "(" + field_size + ", sizeof(" +
+ type + "), " + std::to_string(static_cast<long long>(align)) +
+ ");";
}
return "";
}
@@ -3505,7 +3509,8 @@ class CppGenerator : public BaseGenerator {
: underlying_type;
auto enum_value = "__va->_" + value + "[i].type";
if (!opts_.scoped_enums)
- enum_value = "static_cast<" + underlying_type + ">(" + enum_value + ")";
+ enum_value =
+ "static_cast<" + underlying_type + ">(" + enum_value + ")";
code += "_fbb.CreateVector<" + type + ">(" + value +
".size(), [](size_t i, _VectorArgs *__va) { return " +
diff --git a/contrib/libs/flatbuffers/src/idl_gen_csharp.cpp b/contrib/libs/flatbuffers/src/idl_gen_csharp.cpp
index 369460d730..bc84ed6643 100644
--- a/contrib/libs/flatbuffers/src/idl_gen_csharp.cpp
+++ b/contrib/libs/flatbuffers/src/idl_gen_csharp.cpp
@@ -431,6 +431,10 @@ class CSharpGenerator : public BaseGenerator {
if (opts.generate_object_based_api) {
GenEnum_ObjectAPI(enum_def, code_ptr, opts);
}
+
+ if (enum_def.is_union) {
+ code += GenUnionVerify(enum_def.underlying_type);
+ }
}
bool HasUnionStringValue(const EnumDef &enum_def) const {
@@ -846,7 +850,7 @@ class CSharpGenerator : public BaseGenerator {
// Force compile time error if not using the same version runtime.
code += " public static void ValidateVersion() {";
code += " FlatBufferConstants.";
- code += "FLATBUFFERS_23_5_26(); ";
+ code += "FLATBUFFERS_24_3_7(); ";
code += "}\n";
// Generate a special accessor for the table that when used as the root
@@ -1755,8 +1759,6 @@ class CSharpGenerator : public BaseGenerator {
code += " }\n";
code += "}\n\n";
- code += GenUnionVerify(enum_def.underlying_type);
-
// JsonConverter
if (opts.cs_gen_json_serializer) {
if (enum_def.attributes.Lookup("private")) {
diff --git a/contrib/libs/flatbuffers/src/idl_gen_go.cpp b/contrib/libs/flatbuffers/src/idl_gen_go.cpp
index e1e84a0e58..6bbc5dc892 100644
--- a/contrib/libs/flatbuffers/src/idl_gen_go.cpp
+++ b/contrib/libs/flatbuffers/src/idl_gen_go.cpp
@@ -102,6 +102,25 @@ class GoGenerator : public BaseGenerator {
bool generate() {
std::string one_file_code;
+
+ if (!generateEnums(&one_file_code)) return false;
+ if (!generateStructs(&one_file_code)) return false;
+
+ if (parser_.opts.one_file) {
+ std::string code = "";
+ const bool is_enum = !parser_.enums_.vec.empty();
+ BeginFile(LastNamespacePart(go_namespace_), true, is_enum, &code);
+ code += one_file_code;
+ const std::string filename =
+ GeneratedFileName(path_, file_name_, parser_.opts);
+ return SaveFile(filename.c_str(), code, false);
+ }
+
+ return true;
+ }
+
+ private:
+ bool generateEnums(std::string *one_file_code) {
bool needs_imports = false;
for (auto it = parser_.enums_.vec.begin(); it != parser_.enums_.vec.end();
++it) {
@@ -109,47 +128,46 @@ class GoGenerator : public BaseGenerator {
needs_imports = false;
ResetImports();
}
+ auto &enum_def = **it;
std::string enumcode;
- GenEnum(**it, &enumcode);
- if ((*it)->is_union && parser_.opts.generate_object_based_api) {
- GenNativeUnion(**it, &enumcode);
- GenNativeUnionPack(**it, &enumcode);
- GenNativeUnionUnPack(**it, &enumcode);
+ GenEnum(enum_def, &enumcode);
+ if (enum_def.is_union && parser_.opts.generate_object_based_api) {
+ GenNativeUnionCreator(enum_def, &enumcode);
needs_imports = true;
}
if (parser_.opts.one_file) {
- one_file_code += enumcode;
+ *one_file_code += enumcode;
} else {
- if (!SaveType(**it, enumcode, needs_imports, true)) return false;
+ if (!SaveType(enum_def, enumcode, needs_imports, true)) return false;
}
}
+ return true;
+ }
+
+ void GenNativeUnionCreator(const EnumDef &enum_def, std::string *code_ptr) {
+ if (enum_def.generated) return;
+ GenNativeUnion(enum_def, code_ptr);
+ GenNativeUnionPack(enum_def, code_ptr);
+ GenNativeUnionUnPack(enum_def, code_ptr);
+ }
+
+ bool generateStructs(std::string *one_file_code) {
for (auto it = parser_.structs_.vec.begin();
it != parser_.structs_.vec.end(); ++it) {
if (!parser_.opts.one_file) { ResetImports(); }
std::string declcode;
- GenStruct(**it, &declcode);
+ auto &struct_def = **it;
+ GenStruct(struct_def, &declcode);
if (parser_.opts.one_file) {
- one_file_code += declcode;
+ *one_file_code += declcode;
} else {
- if (!SaveType(**it, declcode, true, false)) return false;
+ if (!SaveType(struct_def, declcode, true, false)) return false;
}
}
-
- if (parser_.opts.one_file) {
- std::string code = "";
- const bool is_enum = !parser_.enums_.vec.empty();
- BeginFile(LastNamespacePart(go_namespace_), true, is_enum, &code);
- code += one_file_code;
- const std::string filename =
- GeneratedFileName(path_, file_name_, parser_.opts);
- return SaveFile(filename.c_str(), code, false);
- }
-
return true;
}
- private:
Namespace go_namespace_;
Namespace *cur_name_space_;
const IdlNamer namer_;
@@ -176,7 +194,8 @@ class GoGenerator : public BaseGenerator {
code += "type " + namer_.Type(struct_def) + " struct {\n\t";
- // _ is reserved in flatbuffers field names, so no chance of name conflict:
+ // _ is reserved in flatbuffers field names, so no chance of name
+ // conflict:
code += "_tab ";
code += struct_def.fixed ? "flatbuffers.Struct" : "flatbuffers.Table";
code += "\n}\n\n";
@@ -1012,6 +1031,8 @@ class GoGenerator : public BaseGenerator {
}
void GenNativeUnion(const EnumDef &enum_def, std::string *code_ptr) {
+ if (enum_def.generated) return;
+
std::string &code = *code_ptr;
code += "type " + NativeName(enum_def) + " struct {\n";
code += "\tType " + namer_.Type(enum_def) + "\n";
@@ -1020,6 +1041,8 @@ class GoGenerator : public BaseGenerator {
}
void GenNativeUnionPack(const EnumDef &enum_def, std::string *code_ptr) {
+ if (enum_def.generated) return;
+
std::string &code = *code_ptr;
code += "func (t *" + NativeName(enum_def) +
") Pack(builder *flatbuffers.Builder) flatbuffers.UOffsetT {\n";
@@ -1040,6 +1063,8 @@ class GoGenerator : public BaseGenerator {
}
void GenNativeUnionUnPack(const EnumDef &enum_def, std::string *code_ptr) {
+ if (enum_def.generated) return;
+
std::string &code = *code_ptr;
code += "func (rcv " + namer_.Type(enum_def) +
diff --git a/contrib/libs/flatbuffers/src/idl_gen_java.cpp b/contrib/libs/flatbuffers/src/idl_gen_java.cpp
index 252c60f6d9..331d945984 100644
--- a/contrib/libs/flatbuffers/src/idl_gen_java.cpp
+++ b/contrib/libs/flatbuffers/src/idl_gen_java.cpp
@@ -701,7 +701,7 @@ class JavaGenerator : public BaseGenerator {
// Force compile time error if not using the same version runtime.
code += " public static void ValidateVersion() {";
code += " Constants.";
- code += "FLATBUFFERS_23_5_26(); ";
+ code += "FLATBUFFERS_24_3_7(); ";
code += "}\n";
// Generate a special accessor for the table that when used as the root
diff --git a/contrib/libs/flatbuffers/src/idl_gen_kotlin.cpp b/contrib/libs/flatbuffers/src/idl_gen_kotlin.cpp
index ecea21edc9..ab1433ae33 100644
--- a/contrib/libs/flatbuffers/src/idl_gen_kotlin.cpp
+++ b/contrib/libs/flatbuffers/src/idl_gen_kotlin.cpp
@@ -524,7 +524,7 @@ class KotlinGenerator : public BaseGenerator {
// runtime.
GenerateFunOneLine(
writer, "validateVersion", "", "",
- [&]() { writer += "Constants.FLATBUFFERS_23_5_26()"; },
+ [&]() { writer += "Constants.FLATBUFFERS_24_3_7()"; },
options.gen_jvmstatic);
GenerateGetRootAsAccessors(namer_.Type(struct_def), writer, options);
diff --git a/contrib/libs/flatbuffers/src/idl_gen_kotlin.h b/contrib/libs/flatbuffers/src/idl_gen_kotlin.h
index 22d8ff6ca3..c3861a2c16 100644
--- a/contrib/libs/flatbuffers/src/idl_gen_kotlin.h
+++ b/contrib/libs/flatbuffers/src/idl_gen_kotlin.h
@@ -24,6 +24,8 @@ namespace flatbuffers {
// Constructs a new Kotlin code generator.
std::unique_ptr<CodeGenerator> NewKotlinCodeGenerator();
+// Constructs a new Kotlin code generator.
+std::unique_ptr<CodeGenerator> NewKotlinKMPCodeGenerator();
} // namespace flatbuffers
#endif // FLATBUFFERS_IDL_GEN_KOTLIN_H_
diff --git a/contrib/libs/flatbuffers/src/idl_gen_kotlin_kmp.cpp b/contrib/libs/flatbuffers/src/idl_gen_kotlin_kmp.cpp
new file mode 100644
index 0000000000..2dba494256
--- /dev/null
+++ b/contrib/libs/flatbuffers/src/idl_gen_kotlin_kmp.cpp
@@ -0,0 +1,1619 @@
+/*
+ * 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.
+ */
+
+// independent from idl_parser, since this code is not needed for most clients
+
+#include <functional>
+#include <unordered_set>
+
+#include "flatbuffers/code_generators.h"
+#include "flatbuffers/idl.h"
+#include "flatbuffers/util.h"
+#include "idl_gen_kotlin.h"
+#include "idl_namer.h"
+
+namespace flatbuffers {
+
+namespace kotlin {
+
+namespace {
+
+typedef std::map<std::string, std::pair<std::string, std::string> > FbbParamMap;
+static TypedFloatConstantGenerator KotlinFloatGen("Double.", "Float.", "NaN",
+ "POSITIVE_INFINITY",
+ "NEGATIVE_INFINITY");
+
+static const CommentConfig comment_config = { "/**", " *", " */" };
+static const std::string ident_pad = " ";
+static std::set<std::string> KotlinKeywords() {
+ return { "package", "as", "typealias", "class", "this", "super",
+ "val", "var", "fun", "for", "null", "true",
+ "false", "is", "in", "throw", "return", "break",
+ "continue", "object", "if", "try", "else", "while",
+ "do", "when", "interface", "typeof", "Any", "Character" };
+}
+
+static Namer::Config KotlinDefaultConfig() {
+ return { /*types=*/Case::kKeep,
+ /*constants=*/Case::kUpperCamel,
+ /*methods=*/Case::kLowerCamel,
+ /*functions=*/Case::kKeep,
+ /*fields=*/Case::kLowerCamel,
+ /*variables=*/Case::kLowerCamel,
+ /*variants=*/Case::kUpperCamel,
+ /*enum_variant_seperator=*/"", // I.e. Concatenate.
+ /*escape_keywords=*/Namer::Config::Escape::AfterConvertingCase,
+ /*namespaces=*/Case::kLowerCamel,
+ /*namespace_seperator=*/".",
+ /*object_prefix=*/"",
+ /*object_suffix=*/"T",
+ /*keyword_prefix=*/"",
+ /*keyword_suffix=*/"E",
+ /*filenames=*/Case::kUpperCamel,
+ /*directories=*/Case::kLowerCamel,
+ /*output_path=*/"",
+ /*filename_suffix=*/"",
+ /*filename_extension=*/".kt" };
+}
+} // namespace
+
+class KotlinKMPGenerator : public BaseGenerator {
+ public:
+ KotlinKMPGenerator(const Parser &parser, const std::string &path,
+ const std::string &file_name)
+ : BaseGenerator(parser, path, file_name, "", ".", "kt"),
+ namer_(WithFlagOptions(KotlinDefaultConfig(), parser.opts, path),
+ KotlinKeywords()) {}
+
+ KotlinKMPGenerator &operator=(const KotlinKMPGenerator &);
+ bool generate() FLATBUFFERS_OVERRIDE {
+ std::string one_file_code;
+
+ for (auto it = parser_.enums_.vec.begin(); it != parser_.enums_.vec.end();
+ ++it) {
+ CodeWriter enumWriter(ident_pad);
+ auto &enum_def = **it;
+
+ GenEnum(enum_def, enumWriter);
+ enumWriter += "";
+ GenEnumOffsetAlias(enum_def, enumWriter);
+
+ if (parser_.opts.one_file) {
+ one_file_code += enumWriter.ToString();
+ } else {
+ if (!SaveType(namer_.EscapeKeyword(enum_def.name),
+ *enum_def.defined_namespace, enumWriter.ToString(), true))
+ return false;
+ }
+ }
+
+ for (auto it = parser_.structs_.vec.begin();
+ it != parser_.structs_.vec.end(); ++it) {
+ CodeWriter structWriter(ident_pad);
+ auto &struct_def = **it;
+
+ GenStruct(struct_def, structWriter, parser_.opts);
+ structWriter += "";
+ GenStructOffsetAlias(struct_def, structWriter);
+
+ if (parser_.opts.one_file) {
+ one_file_code += structWriter.ToString();
+ } else {
+ if (!SaveType(namer_.EscapeKeyword(struct_def.name),
+ *struct_def.defined_namespace, structWriter.ToString(),
+ true))
+ return false;
+ }
+ }
+
+ if (parser_.opts.one_file) {
+ return SaveType(file_name_, *parser_.current_namespace_, one_file_code,
+ true);
+ }
+ return true;
+ }
+
+ std::string TypeInNameSpace(const Namespace *ns,
+ const std::string &name = "") const {
+ auto qualified = namer_.Namespace(*ns);
+ return qualified.empty() ? name : qualified + qualifying_separator_ + name;
+ }
+
+ std::string TypeInNameSpace(const Definition &def,
+ const std::string &suffix = "") const {
+ return TypeInNameSpace(def.defined_namespace, def.name + suffix);
+ }
+
+ // Save out the generated code for a single class while adding
+ // declaration boilerplate.
+ bool SaveType(const std::string &defname, const Namespace &ns,
+ const std::string &classcode, bool needs_includes) const {
+ if (!classcode.length()) return true;
+
+ std::string code =
+ "// " + std::string(FlatBuffersGeneratedWarning()) + "\n\n";
+ auto qualified = ns.GetFullyQualifiedName("");
+ std::string namespace_name = namer_.Namespace(ns);
+ if (!namespace_name.empty()) {
+ code += "package " + namespace_name;
+ code += "\n\n";
+ }
+ if (needs_includes) { code += "import com.google.flatbuffers.kotlin.*\n"; }
+ code += "import kotlin.jvm.JvmInline\n";
+ code += classcode;
+ const std::string dirs =
+ namer_.Directories(ns, SkipDir::None, Case::kUnknown);
+ EnsureDirExists(dirs);
+ const std::string filename =
+ dirs + namer_.File(defname, /*skips=*/SkipFile::Suffix);
+ return SaveFile(filename.c_str(), code, false);
+ }
+
+ static bool IsEnum(const Type &type) {
+ return type.enum_def != nullptr && IsInteger(type.base_type);
+ }
+
+ std::string GenerateKotlinPrimiteArray(const Type &type) const {
+ if (IsScalar(type.base_type) && !IsEnum(type)) { return GenType(type); }
+
+ if (IsEnum(type) || type.base_type == BASE_TYPE_UTYPE) {
+ return TypeInNameSpace(type.enum_def->defined_namespace,
+ namer_.Type(*type.enum_def));
+ }
+ switch (type.base_type) {
+ case BASE_TYPE_STRUCT:
+ return "Offset<" + TypeInNameSpace(*type.struct_def) + ">";
+ case BASE_TYPE_UNION: return "UnionOffset";
+ case BASE_TYPE_STRING: return "Offset<String>";
+ case BASE_TYPE_UTYPE: return "Offset<UByte>";
+ default: return "Offset<" + GenTypeBasic(type.element) + ">";
+ }
+ }
+
+ std::string GenerateKotlinOffsetArray(const Type &type) const {
+ if (IsScalar(type.base_type) && !IsEnum(type)) {
+ return GenType(type) + "Array";
+ }
+
+ if (IsEnum(type) || type.base_type == BASE_TYPE_UTYPE) {
+ return TypeInNameSpace(type.enum_def->defined_namespace,
+ namer_.Type(*type.enum_def) + "Array");
+ }
+ switch (type.base_type) {
+ case BASE_TYPE_STRUCT:
+ return TypeInNameSpace(*type.struct_def) + "OffsetArray";
+ case BASE_TYPE_UNION: return "UnionOffsetArray";
+ case BASE_TYPE_STRING: return "StringOffsetArray";
+ case BASE_TYPE_UTYPE: return "UByteArray";
+ default: return GenTypeBasic(type.element) + "OffsetArray";
+ }
+ }
+
+ std::string GenTypeBasic(const BaseType &type) const {
+ switch (type) {
+ case BASE_TYPE_NONE:
+ case BASE_TYPE_UTYPE: return "UByte";
+ case BASE_TYPE_BOOL: return "Boolean";
+ case BASE_TYPE_CHAR: return "Byte";
+ case BASE_TYPE_UCHAR: return "UByte";
+ case BASE_TYPE_SHORT: return "Short";
+ case BASE_TYPE_USHORT: return "UShort";
+ case BASE_TYPE_INT: return "Int";
+ case BASE_TYPE_UINT: return "UInt";
+ case BASE_TYPE_LONG: return "Long";
+ case BASE_TYPE_ULONG: return "ULong";
+ case BASE_TYPE_FLOAT: return "Float";
+ case BASE_TYPE_DOUBLE: return "Double";
+ case BASE_TYPE_STRING:
+ case BASE_TYPE_STRUCT: return "Offset";
+ case BASE_TYPE_UNION: return "UnionOffset";
+ case BASE_TYPE_VECTOR:
+ case BASE_TYPE_ARRAY: return "VectorOffset";
+ // VECTOR64 not supported
+ case BASE_TYPE_VECTOR64: FLATBUFFERS_ASSERT(0);
+ }
+ return "Int";
+ }
+
+ std::string GenType(const Type &type) const {
+ auto base_type = GenTypeBasic(type.base_type);
+
+ if (IsEnum(type) || type.base_type == BASE_TYPE_UTYPE) {
+ return TypeInNameSpace(type.enum_def->defined_namespace,
+ namer_.Type(*type.enum_def));
+ }
+ switch (type.base_type) {
+ case BASE_TYPE_ARRAY:
+ case BASE_TYPE_VECTOR: {
+ switch (type.element) {
+ case BASE_TYPE_STRUCT:
+ return base_type + "<" + TypeInNameSpace(*type.struct_def) + ">";
+ case BASE_TYPE_UNION:
+ return base_type + "<" + GenTypeBasic(type.element) + ">";
+ case BASE_TYPE_STRING: return base_type + "<String>";
+ case BASE_TYPE_UTYPE: return base_type + "<UByte>";
+ default: return base_type + "<" + GenTypeBasic(type.element) + ">";
+ }
+ }
+ case BASE_TYPE_STRUCT:
+ return base_type + "<" + TypeInNameSpace(*type.struct_def) + ">";
+ case BASE_TYPE_STRING: return base_type + "<String>";
+ case BASE_TYPE_UNION: return base_type;
+ default: return base_type;
+ }
+ // clang-format on
+ }
+
+ std::string GenTypePointer(const Type &type) const {
+ switch (type.base_type) {
+ case BASE_TYPE_STRING: return "String";
+ case BASE_TYPE_VECTOR: return GenTypeGet(type.VectorType());
+ case BASE_TYPE_STRUCT: return TypeInNameSpace(*type.struct_def);
+ default: return "Table";
+ }
+ }
+
+ // with the addition of optional scalar types,
+ // we are adding the nullable '?' operator to return type of a field.
+ std::string GetterReturnType(const FieldDef &field) const {
+ auto base_type = field.value.type.base_type;
+
+ auto r_type = GenTypeGet(field.value.type);
+ if (field.IsScalarOptional() ||
+ // string, structs and unions
+ (base_type == BASE_TYPE_STRING || base_type == BASE_TYPE_STRUCT ||
+ base_type == BASE_TYPE_UNION) ||
+ // vector of anything not scalar
+ (base_type == BASE_TYPE_VECTOR &&
+ !IsScalar(field.value.type.VectorType().base_type))) {
+ r_type += "?";
+ }
+ return r_type;
+ }
+
+ std::string GenTypeGet(const Type &type) const {
+ return IsScalar(type.base_type) ? GenType(type) : GenTypePointer(type);
+ }
+
+ std::string GenEnumDefaultValue(const FieldDef &field) const {
+ auto &value = field.value;
+ FLATBUFFERS_ASSERT(value.type.enum_def);
+ auto &enum_def = *value.type.enum_def;
+ auto enum_val = enum_def.FindByValue(value.constant);
+ return enum_val ? (TypeInNameSpace(enum_def) + "." + enum_val->name)
+ : value.constant;
+ }
+
+ // differently from GenDefaultValue, the default values are meant
+ // to be inserted in the buffer as the object is building.
+ std::string GenDefaultBufferValue(const FieldDef &field) const {
+ auto &value = field.value;
+ auto base_type = value.type.base_type;
+ auto field_name = field.name;
+ std::string suffix = IsScalar(base_type) ? LiteralSuffix(value.type) : "";
+ if (field.IsScalarOptional()) { return "null"; }
+ if (IsFloat(base_type)) {
+ auto val = KotlinFloatGen.GenFloatConstant(field);
+ if (base_type == BASE_TYPE_DOUBLE && val.back() == 'f') {
+ val.pop_back();
+ }
+ return val;
+ }
+
+ if (base_type == BASE_TYPE_BOOL) {
+ return value.constant == "0" ? "false" : "true";
+ }
+
+ if (IsEnum(field.value.type)) {
+ return value.constant + suffix;
+ } else if ((IsVector(field.value.type) &&
+ field.value.type.element == BASE_TYPE_UTYPE) ||
+ (IsVector(field.value.type) &&
+ field.value.type.VectorType().base_type == BASE_TYPE_UNION)) {
+ return value.constant;
+ } else {
+ return value.constant + suffix;
+ }
+ }
+
+ std::string GenDefaultValue(const FieldDef &field) const {
+ auto &value = field.value;
+ auto base_type = value.type.base_type;
+ auto field_name = field.name;
+ std::string suffix = LiteralSuffix(value.type);
+ if (field.IsScalarOptional()) { return "null"; }
+ if (IsFloat(base_type)) {
+ auto val = KotlinFloatGen.GenFloatConstant(field);
+ if (base_type == BASE_TYPE_DOUBLE && val.back() == 'f') {
+ val.pop_back();
+ }
+ return val;
+ }
+
+ if (base_type == BASE_TYPE_BOOL) {
+ return value.constant == "0" ? "false" : "true";
+ }
+
+ if (IsEnum(field.value.type) ||
+ (IsVector(field.value.type) && IsEnum(field.value.type.VectorType()))) {
+ return WrapEnumValue(field.value.type, value.constant + suffix);
+ }
+
+ if (IsVector(field.value.type) &&
+ (field.value.type.VectorType().base_type == BASE_TYPE_UNION ||
+ field.value.type.VectorType().base_type == BASE_TYPE_STRUCT ||
+ field.value.type.VectorType().base_type == BASE_TYPE_STRING)) {
+ return "null";
+ }
+ if (IsVector(field.value.type)) {
+ switch (field.value.type.element) {
+ case BASE_TYPE_UTYPE:
+ return namer_.Type(*field.value.type.enum_def) + "(" +
+ value.constant + suffix + ")";
+ case BASE_TYPE_UNION:
+ case BASE_TYPE_STRUCT:
+ case BASE_TYPE_STRING: return "null";
+ case BASE_TYPE_BOOL: return value.constant == "0" ? "false" : "true";
+ case BASE_TYPE_FLOAT: return value.constant + "f";
+ case BASE_TYPE_DOUBLE: {
+ return value.constant + ".toDouble()";
+ }
+ default: return value.constant + suffix;
+ }
+ }
+ return value.constant + suffix;
+ }
+
+ void GenEnum(EnumDef &enum_def, CodeWriter &writer) const {
+ if (enum_def.generated) return;
+
+ GenerateComment(enum_def.doc_comment, writer, &comment_config);
+ auto enum_type = namer_.Type(enum_def);
+ auto field_type = GenTypeBasic(enum_def.underlying_type.base_type);
+ writer += "@Suppress(\"unused\")";
+ writer += "@JvmInline";
+ writer += "value class " + enum_type + " (val value: " + field_type + ") {";
+ writer.IncrementIdentLevel();
+
+ GenerateCompanionObject(writer, [&]() {
+ // Write all properties
+ auto vals = enum_def.Vals();
+
+ for (auto it = vals.begin(); it != vals.end(); ++it) {
+ auto &ev = **it;
+ auto val = enum_def.ToString(ev);
+ auto suffix = LiteralSuffix(enum_def.underlying_type);
+ writer.SetValue("name", namer_.Variant(ev));
+ writer.SetValue("type", enum_type);
+ writer.SetValue("val", val + suffix);
+ GenerateComment(ev.doc_comment, writer, &comment_config);
+ writer += "val {{name}} = {{type}}({{val}})";
+ }
+
+ // Generate a generate string table for enum values.
+ // Problem is, if values are very sparse that could generate really
+ // big tables. Ideally in that case we generate a map lookup
+ // instead, but for the moment we simply don't output a table at all.
+ auto range = enum_def.Distance();
+ // Average distance between values above which we consider a table
+ // "too sparse". Change at will.
+ static const uint64_t kMaxSparseness = 5;
+ if (range / static_cast<uint64_t>(enum_def.size()) < kMaxSparseness) {
+ GeneratePropertyOneLine(writer, "names", "Array<String>", [&]() {
+ writer += "arrayOf(\\";
+ auto val = enum_def.Vals().front();
+ for (auto it = vals.begin(); it != vals.end(); ++it) {
+ auto ev = *it;
+ for (auto k = enum_def.Distance(val, ev); k > 1; --k)
+ writer += "\"\", \\";
+ val = ev;
+ writer += "\"" + (*it)->name + "\"\\";
+ if (it + 1 != vals.end()) { writer += ", \\"; }
+ }
+ writer += ")";
+ });
+ std::string e_param = "e: " + enum_type;
+ GenerateFunOneLine(
+ writer, "name", e_param, "String",
+ [&]() {
+ writer += "names[e.value.toInt()\\";
+ if (enum_def.MinValue()->IsNonZero())
+ writer += " - " + namer_.Variant(*enum_def.MinValue()) +
+ ".value.toInt()\\";
+ writer += "]";
+ },
+ parser_.opts.gen_jvmstatic);
+ }
+ });
+ writer.DecrementIdentLevel();
+ writer += "}";
+ }
+
+ // Returns the function name that is able to read a value of the given type.
+ std::string ByteBufferGetter(const Type &type,
+ std::string bb_var_name) const {
+ switch (type.base_type) {
+ case BASE_TYPE_STRING: return "string";
+ case BASE_TYPE_STRUCT: return "__struct";
+ case BASE_TYPE_UNION: return "union";
+ case BASE_TYPE_VECTOR:
+ return ByteBufferGetter(type.VectorType(), bb_var_name);
+ case BASE_TYPE_INT: return bb_var_name + ".getInt";
+ case BASE_TYPE_UINT: return bb_var_name + ".getUInt";
+ case BASE_TYPE_SHORT: return bb_var_name + ".getShort";
+ case BASE_TYPE_USHORT: return bb_var_name + ".getUShort";
+ case BASE_TYPE_ULONG: return bb_var_name + ".getULong";
+ case BASE_TYPE_LONG: return bb_var_name + ".getLong";
+ case BASE_TYPE_FLOAT: return bb_var_name + ".getFloat";
+ case BASE_TYPE_DOUBLE: return bb_var_name + ".getDouble";
+ case BASE_TYPE_UTYPE:
+ case BASE_TYPE_UCHAR: return bb_var_name + ".getUByte";
+ case BASE_TYPE_CHAR:
+ case BASE_TYPE_NONE: return bb_var_name + ".get";
+ case BASE_TYPE_BOOL: return "0.toByte() != " + bb_var_name + ".get";
+ default: return bb_var_name + "." + namer_.Method("get", GenType(type));
+ }
+ }
+
+ // Returns the function name that is able to read a value of the given type.
+ std::string GenLookupByKey(flatbuffers::FieldDef *key_field,
+ const std::string &bb_var_name,
+ const char *num = nullptr) const {
+ auto type = key_field->value.type;
+ return ByteBufferGetter(type, bb_var_name) + "(" +
+ GenOffsetGetter(key_field, num) + ")";
+ }
+
+ // Returns the method name for use with add/put calls.
+ static std::string GenMethod(const Type &type) {
+ return IsStruct(type) ? "Struct" : "";
+ }
+
+ // Recursively generate arguments for a constructor, to deal with nested
+ // structs.
+ void GenStructArgs(const StructDef &struct_def, CodeWriter &writer,
+ const char *nameprefix) const {
+ for (auto it = struct_def.fields.vec.begin();
+ it != struct_def.fields.vec.end(); ++it) {
+ auto &field = **it;
+ if (IsStruct(field.value.type)) {
+ // Generate arguments for a struct inside a struct. To ensure
+ // names don't clash, and to make it obvious these arguments are
+ // constructing a nested struct, prefix the name with the field
+ // name.
+ GenStructArgs(*field.value.type.struct_def, writer,
+ (nameprefix + (field.name + "_")).c_str());
+ } else {
+ writer += std::string(", ") + nameprefix + "\\";
+ writer += namer_.Field(field) + ": \\";
+ writer += GenType(field.value.type) + "\\";
+ }
+ }
+ }
+
+ // Recusively generate struct construction statements of the form:
+ // builder.putType(name);
+ // and insert manual padding.
+ void GenStructBody(const StructDef &struct_def, CodeWriter &writer,
+ const char *nameprefix) const {
+ writer.SetValue("align", NumToString(struct_def.minalign));
+ writer.SetValue("size", NumToString(struct_def.bytesize));
+ writer += "builder.prep({{align}}, {{size}})";
+ auto fields_vec = struct_def.fields.vec;
+ for (auto it = fields_vec.rbegin(); it != fields_vec.rend(); ++it) {
+ auto &field = **it;
+
+ if (field.padding) {
+ writer.SetValue("pad", NumToString(field.padding));
+ writer += "builder.pad({{pad}})";
+ }
+ if (IsStruct(field.value.type)) {
+ GenStructBody(*field.value.type.struct_def, writer,
+ (nameprefix + (field.name + "_")).c_str());
+ } else {
+ auto suffix = IsEnum(field.value.type) ? ".value" : "";
+ writer.SetValue("type", GenMethod(field.value.type));
+ writer.SetValue("argname",
+ nameprefix + namer_.Variable(field) + suffix);
+ writer += "builder.put{{type}}({{argname}})";
+ }
+ }
+ }
+
+ std::string GenOffsetGetter(flatbuffers::FieldDef *key_field,
+ const char *num = nullptr) const {
+ std::string key_offset =
+ "offset(" + NumToString(key_field->value.offset) + ", ";
+ if (num) {
+ key_offset += num;
+ key_offset += ", buffer)";
+ } else {
+ key_offset += "(bb.capacity - tableOffset).toOffset<Int>(), bb)";
+ }
+ return key_offset;
+ }
+
+ bool StructHasUnsignedField(StructDef &struct_def) {
+ auto vec = struct_def.fields.vec;
+ for (auto it = vec.begin(); it != vec.end(); ++it) {
+ auto &field = **it;
+ if (IsUnsigned(field.value.type.base_type)) { return true; }
+ }
+ return false;
+ }
+
+ // This method generate alias types for offset arrays. We need it
+ // to avoid unboxing/boxing of offsets when put into an array.
+ // e.g:
+ // Array<Offset<Monster>> generates boxing.
+ // So we creates a new type to avoid it:
+ // typealias MonterOffsetArray = IntArray
+ void GenStructOffsetAlias(StructDef &struct_def, CodeWriter &writer) const {
+ if (struct_def.generated) return;
+ auto name = namer_.Type(struct_def);
+ // This assumes offset as Ints always.
+ writer += "typealias " + name + "OffsetArray = OffsetArray<" + name + ">";
+
+ // public inline fun <T> MonsterOffsetArray(size: Int, crossinline call:
+ // (Int) -> Offset<T>): OffsetArray<T> {
+ // return OffsetArray(IntArray(size) { call(it).value })
+ // }
+ writer += "";
+ writer += "inline fun " + name +
+ "OffsetArray(size: Int, crossinline call: (Int) -> Offset<" +
+ name + ">): " + name + "OffsetArray =";
+ writer.IncrementIdentLevel();
+ writer += name + "OffsetArray(IntArray(size) { call(it).value })";
+ }
+
+ // This method generate alias types for offset arrays. We need it
+ // to avoid unboxing/boxing of offsets when put into an array.
+ // e.g:
+ // Array<Offset<Monster>> generates boxing.
+ // So we creates a new type to avoid it:
+ // typealias MonterOffsetArray = IntArray
+ void GenEnumOffsetAlias(EnumDef &enum_def, CodeWriter &writer) const {
+ if (enum_def.generated) return;
+ // This assumes offset as Ints always.
+ writer += "typealias " + namer_.Type(enum_def) +
+ "Array = " + GenTypeBasic(enum_def.underlying_type.base_type) +
+ "Array";
+ }
+
+ void GenStruct(StructDef &struct_def, CodeWriter &writer,
+ IDLOptions options) const {
+ if (struct_def.generated) return;
+
+ GenerateComment(struct_def.doc_comment, writer, &comment_config);
+ auto fixed = struct_def.fixed;
+
+ writer.SetValue("struct_name", namer_.Type(struct_def));
+ writer.SetValue("superclass", fixed ? "Struct" : "Table");
+
+ writer += "@Suppress(\"unused\")";
+ writer += "class {{struct_name}} : {{superclass}}() {\n";
+
+ writer.IncrementIdentLevel();
+
+ {
+ auto esc_type = namer_.EscapeKeyword(struct_def.name);
+ // Generate the init() method that sets the field in a pre-existing
+ // accessor object. This is to allow object reuse.
+ GenerateFunOneLine(writer, "init", "i: Int, buffer: ReadWriteBuffer",
+ esc_type, [&]() { writer += "reset(i, buffer)"; });
+ writer += ""; // line break
+
+ // Generate all getters
+ GenerateStructGetters(struct_def, writer);
+
+ // Generate Static Fields
+ GenerateCompanionObject(writer, [&]() {
+ if (!struct_def.fixed) {
+ FieldDef *key_field = nullptr;
+
+ // Generate version check method.
+ // Force compile time error if not using the same version
+ // runtime.
+ GenerateFunOneLine(
+ writer, "validateVersion", "", "",
+ [&]() { writer += "VERSION_2_0_8"; }, options.gen_jvmstatic);
+
+ writer += "";
+ GenerateGetRootAsAccessors(namer_.Type(struct_def), writer, options);
+
+ writer += "";
+ GenerateBufferHasIdentifier(struct_def, writer, options);
+
+ writer += "";
+ GenerateTableCreator(struct_def, writer, options);
+
+ GenerateStartStructMethod(struct_def, writer, options);
+
+ // Static Add for fields
+ auto fields = struct_def.fields.vec;
+ int field_pos = -1;
+ for (auto it = fields.begin(); it != fields.end(); ++it) {
+ auto &field = **it;
+ field_pos++;
+ if (field.deprecated) continue;
+ if (field.key) key_field = &field;
+ writer += "";
+ GenerateAddField(NumToString(field_pos), field, writer, options);
+ if (IsVector(field.value.type)) {
+ auto vector_type = field.value.type.VectorType();
+ if (!IsStruct(vector_type)) {
+ writer += "";
+ GenerateCreateVectorField(field, writer, options);
+ }
+ writer += "";
+ GenerateStartVectorField(field, writer, options);
+ }
+ }
+
+ writer += "";
+ GenerateEndStructMethod(struct_def, writer, options);
+ auto file_identifier = parser_.file_identifier_;
+ if (parser_.root_struct_def_ == &struct_def) {
+ writer += "";
+ GenerateFinishStructBuffer(struct_def, file_identifier, writer,
+ options);
+ writer += "";
+ GenerateFinishSizePrefixed(struct_def, file_identifier, writer,
+ options);
+ }
+
+ if (struct_def.has_key) {
+ writer += "";
+ GenerateLookupByKey(key_field, struct_def, writer, options);
+ }
+ } else {
+ writer += "";
+ GenerateStaticConstructor(struct_def, writer, options);
+ }
+ });
+ }
+
+ // class closing
+ writer.DecrementIdentLevel();
+ writer += "}";
+ }
+
+ // TODO: move key_field to reference instead of pointer
+ void GenerateLookupByKey(FieldDef *key_field, StructDef &struct_def,
+ CodeWriter &writer, const IDLOptions options) const {
+ std::stringstream params;
+ params << "obj: " << namer_.Type(struct_def) << "?"
+ << ", ";
+ params << "vectorLocation: Int, ";
+ params << "key: " << GenTypeGet(key_field->value.type) << ", ";
+ params << "bb: ReadWriteBuffer";
+
+ auto statements = [&]() {
+ auto base_type = key_field->value.type.base_type;
+ writer.SetValue("struct_name", namer_.Type(struct_def));
+ if (base_type == BASE_TYPE_STRING) {
+ writer += "val byteKey = key.encodeToByteArray()";
+ }
+ writer += "var span = bb.getInt(vectorLocation - 4)";
+ writer += "var start = 0";
+ writer += "while (span != 0) {";
+ writer.IncrementIdentLevel();
+ writer += "var middle = span / 2";
+ writer +=
+ "val tableOffset = indirect(vector"
+ "Location + 4 * (start + middle), bb)";
+ if (IsString(key_field->value.type)) {
+ writer += "val comp = compareStrings(\\";
+ writer += GenOffsetGetter(key_field) + "\\";
+ writer += ", byteKey, bb)";
+ } else {
+ auto get_val = GenLookupByKey(key_field, "bb");
+ writer += "val value = " + get_val;
+ writer += "val comp = value.compareTo(key)";
+ }
+ writer += "when {";
+ writer.IncrementIdentLevel();
+ writer += "comp > 0 -> span = middle";
+ writer += "comp < 0 -> {";
+ writer.IncrementIdentLevel();
+ writer += "middle++";
+ writer += "start += middle";
+ writer += "span -= middle";
+ writer.DecrementIdentLevel();
+ writer += "}"; // end comp < 0
+ writer += "else -> {";
+ writer.IncrementIdentLevel();
+ writer += "return (obj ?: {{struct_name}}()).init(tableOffset, bb)";
+ writer.DecrementIdentLevel();
+ writer += "}"; // end else
+ writer.DecrementIdentLevel();
+ writer += "}"; // end when
+ writer.DecrementIdentLevel();
+ writer += "}"; // end while
+ writer += "return null";
+ };
+ GenerateFun(writer, "lookupByKey", params.str(),
+ namer_.Type(struct_def) + "?", statements,
+ options.gen_jvmstatic);
+ }
+
+ void GenerateFinishSizePrefixed(StructDef &struct_def,
+ const std::string &identifier,
+ CodeWriter &writer,
+ const IDLOptions options) const {
+ auto id = identifier.length() > 0 ? ", \"" + identifier + "\"" : "";
+ auto gen_type = "Offset<" + namer_.Type(struct_def.name) + ">";
+ auto params = "builder: FlatBufferBuilder, offset: " + gen_type;
+ auto method_name =
+ namer_.LegacyJavaMethod2("finishSizePrefixed", struct_def, "Buffer");
+ GenerateFunOneLine(
+ writer, method_name, params, "",
+ [&]() { writer += "builder.finishSizePrefixed(offset" + id + ")"; },
+ options.gen_jvmstatic);
+ }
+ void GenerateFinishStructBuffer(StructDef &struct_def,
+ const std::string &identifier,
+ CodeWriter &writer,
+ const IDLOptions options) const {
+ auto id = identifier.length() > 0 ? ", \"" + identifier + "\"" : "";
+ auto gen_type = "Offset<" + namer_.Type(struct_def.name) + ">";
+ auto params = "builder: FlatBufferBuilder, offset: " + gen_type;
+ auto method_name =
+ namer_.LegacyKotlinMethod("finish", struct_def, "Buffer");
+ GenerateFunOneLine(
+ writer, method_name, params, "",
+ [&]() { writer += "builder.finish(offset" + id + ")"; },
+ options.gen_jvmstatic);
+ }
+
+ void GenerateEndStructMethod(StructDef &struct_def, CodeWriter &writer,
+ const IDLOptions options) const {
+ // Generate end{{TableName}}(builder: FlatBufferBuilder) method
+ auto name = namer_.Method("end", struct_def.name);
+ auto params = "builder: FlatBufferBuilder";
+ auto returns = "Offset<" + namer_.Type(struct_def) + '>';
+ auto field_vec = struct_def.fields.vec;
+
+ GenerateFun(
+ writer, name, params, returns,
+ [&]() {
+ writer += "val o: " + returns + " = builder.endTable()";
+ writer.IncrementIdentLevel();
+ for (auto it = field_vec.begin(); it != field_vec.end(); ++it) {
+ auto &field = **it;
+ if (field.deprecated || !field.IsRequired()) { continue; }
+ writer.SetValue("offset", NumToString(field.value.offset));
+ writer.SetValue("field_name", field.name);
+ writer += "builder.required(o, {{offset}}, \"{{field_name}}\")";
+ }
+ writer.DecrementIdentLevel();
+ writer += "return o";
+ },
+ options.gen_jvmstatic);
+ }
+
+ // Generate a method to create a vector from a Kotlin array.
+ void GenerateCreateVectorField(FieldDef &field, CodeWriter &writer,
+ const IDLOptions options) const {
+ auto vector_type = field.value.type.VectorType();
+ auto method_name = namer_.Method("create", field, "vector");
+ auto array_param = GenerateKotlinOffsetArray(vector_type);
+ auto params = "builder: FlatBufferBuilder, vector:" + array_param;
+ auto return_type = GenType(field.value.type);
+ writer.SetValue("size", NumToString(InlineSize(vector_type)));
+ writer.SetValue("align", NumToString(InlineAlignment(vector_type)));
+ writer.SetValue("root", GenMethod(vector_type));
+
+ GenerateFun(
+ writer, method_name, params, return_type,
+ [&]() {
+ writer += "builder.startVector({{size}}, vector.size, {{align}})";
+ writer += "for (i in vector.size - 1 downTo 0) {";
+ writer.IncrementIdentLevel();
+ writer += "builder.add{{root}}(vector[i])";
+ writer.DecrementIdentLevel();
+ writer += "}";
+ writer += "return builder.endVector()";
+ },
+ options.gen_jvmstatic);
+ }
+
+ void GenerateStartVectorField(FieldDef &field, CodeWriter &writer,
+ const IDLOptions options) const {
+ // Generate a method to start a vector, data to be added manually
+ // after.
+ auto vector_type = field.value.type.VectorType();
+ auto params = "builder: FlatBufferBuilder, numElems: Int";
+ writer.SetValue("size", NumToString(InlineSize(vector_type)));
+ writer.SetValue("align", NumToString(InlineAlignment(vector_type)));
+
+ GenerateFunOneLine(
+ writer, namer_.Method("start", field, "Vector"), params, "",
+ [&]() {
+ writer += "builder.startVector({{size}}, numElems, {{align}})";
+ },
+ options.gen_jvmstatic);
+ }
+
+ void GenerateAddField(std::string field_pos, FieldDef &field,
+ CodeWriter &writer, const IDLOptions options) const {
+ auto field_type = GenType(field.value.type);
+ auto secondArg = namer_.Variable(field.name) + ": " + field_type;
+
+ auto content = [&]() {
+ auto method = GenMethod(field.value.type);
+ auto default_value = GenDefaultBufferValue(field);
+ auto field_param = namer_.Field(field);
+ if (IsEnum(field.value.type) || IsStruct(field.value.type)) {
+ field_param += ".value";
+ }
+
+ writer.SetValue("field_name", namer_.Field(field));
+ writer.SetValue("field_param", field_param);
+ writer.SetValue("method_name", method);
+ writer.SetValue("pos", field_pos);
+ writer.SetValue("default", default_value);
+
+ if (field.key) {
+ // field has key attribute, so always need to exist
+ // even if its value is equal to default.
+ // Generated code will bypass default checking
+ // resulting in { builder.addShort(name); slot(id); }
+ writer += "builder.add{{method_name}}({{field_name}})";
+ writer += "builder.slot({{pos}})";
+ } else {
+ writer += "builder.add{{method_name}}({{pos}}, \\";
+ writer += "{{field_param}}, {{default}})";
+ }
+ };
+ auto signature = namer_.LegacyKotlinMethod("add", field, "");
+ auto params = "builder: FlatBufferBuilder, " + secondArg;
+ if (field.key) {
+ GenerateFun(writer, signature, params, "", content,
+ options.gen_jvmstatic);
+ } else {
+ GenerateFunOneLine(writer, signature, params, "", content,
+ options.gen_jvmstatic);
+ }
+ }
+
+ // fun startMonster(builder: FlatBufferBuilder) = builder.startTable(11)
+ void GenerateStartStructMethod(StructDef &struct_def, CodeWriter &code,
+ const IDLOptions options) const {
+ GenerateFunOneLine(
+ code, namer_.LegacyJavaMethod2("start", struct_def, ""),
+ "builder: FlatBufferBuilder", "",
+ [&]() {
+ code += "builder.startTable(" +
+ NumToString(struct_def.fields.vec.size()) + ")";
+ },
+ options.gen_jvmstatic);
+ }
+
+ void GenerateTableCreator(StructDef &struct_def, CodeWriter &writer,
+ const IDLOptions options) const {
+ // Generate a method that creates a table in one go. This is only possible
+ // when the table has no struct fields, since those have to be created
+ // inline, and there's no way to do so in Java.
+ bool has_no_struct_fields = true;
+ int num_fields = 0;
+ auto fields_vec = struct_def.fields.vec;
+
+ for (auto it = fields_vec.begin(); it != fields_vec.end(); ++it) {
+ auto &field = **it;
+ if (field.deprecated) continue;
+ if (IsStruct(field.value.type)) {
+ has_no_struct_fields = false;
+ } else {
+ num_fields++;
+ }
+ }
+ // JVM specifications restrict default constructor params to be < 255.
+ // Longs and doubles take up 2 units, so we set the limit to be < 127.
+ if (has_no_struct_fields && num_fields && num_fields < 127) {
+ // Generate a table constructor of the form:
+ // public static int createName(FlatBufferBuilder builder, args...)
+
+ auto name = namer_.LegacyJavaMethod2("create", struct_def, "");
+ std::stringstream params;
+ params << "builder: FlatBufferBuilder";
+ for (auto it = fields_vec.begin(); it != fields_vec.end(); ++it) {
+ auto &field = **it;
+ if (field.deprecated) continue;
+ params << ", " << namer_.Variable(field);
+ if (!IsScalar(field.value.type.base_type)) {
+ params << "Offset: ";
+ } else {
+ params << ": ";
+ }
+ auto optional = field.IsScalarOptional() ? "?" : "";
+ params << GenType(field.value.type) << optional;
+ }
+
+ GenerateFun(
+ writer, name, params.str(), "Offset<" + namer_.Type(struct_def) + '>',
+ [&]() {
+ writer.SetValue("vec_size", NumToString(fields_vec.size()));
+ writer.SetValue("end_method",
+ namer_.Method("end", struct_def.name));
+ writer += "builder.startTable({{vec_size}})";
+
+ auto sortbysize = struct_def.sortbysize;
+ auto largest = sortbysize ? sizeof(largest_scalar_t) : 1;
+ for (size_t size = largest; size; size /= 2) {
+ for (auto it = fields_vec.rbegin(); it != fields_vec.rend();
+ ++it) {
+ auto &field = **it;
+ auto base_type_size = SizeOf(field.value.type.base_type);
+ if (!field.deprecated &&
+ (!sortbysize || size == base_type_size)) {
+ writer.SetValue("field_name", namer_.Field(field));
+
+ // we wrap on null check for scalar optionals
+ writer += field.IsScalarOptional()
+ ? "{{field_name}}?.run { \\"
+ : "\\";
+
+ writer += namer_.LegacyKotlinMethod("add", field, "") +
+ "(builder, {{field_name}}\\";
+ if (!IsScalar(field.value.type.base_type)) {
+ writer += "Offset\\";
+ }
+ // we wrap on null check for scalar optionals
+ writer += field.IsScalarOptional() ? ") }" : ")";
+ }
+ }
+ }
+ writer += "return {{end_method}}(builder)";
+ },
+ options.gen_jvmstatic);
+ }
+ }
+ void GenerateBufferHasIdentifier(StructDef &struct_def, CodeWriter &writer,
+ IDLOptions options) const {
+ auto file_identifier = parser_.file_identifier_;
+ // Check if a buffer has the identifier.
+ if (parser_.root_struct_def_ != &struct_def || !file_identifier.length())
+ return;
+ auto name = namer_.Function(struct_def);
+ GenerateFunOneLine(
+ writer, name + "BufferHasIdentifier", "buffer: ReadWriteBuffer",
+ "Boolean",
+ [&]() {
+ writer += "hasIdentifier(buffer, \"" + file_identifier + "\")";
+ },
+ options.gen_jvmstatic);
+ }
+
+ void GenerateStructGetters(StructDef &struct_def, CodeWriter &writer) const {
+ auto fields_vec = struct_def.fields.vec;
+ FieldDef *key_field = nullptr;
+ for (auto it = fields_vec.begin(); it != fields_vec.end(); ++it) {
+ auto &field = **it;
+ if (field.deprecated) continue;
+ if (field.key) key_field = &field;
+
+ GenerateComment(field.doc_comment, writer, &comment_config);
+
+ auto field_name = namer_.Field(field);
+ auto field_type = GenTypeGet(field.value.type);
+ auto field_default_value = GenDefaultValue(field);
+ auto return_type = GetterReturnType(field);
+ auto bbgetter = ByteBufferGetter(field.value.type, "bb");
+ auto offset_val = NumToString(field.value.offset);
+ auto offset_prefix =
+ "val o = offset(" + offset_val + "); return o != 0 ? ";
+ auto value_base_type = field.value.type.base_type;
+ // Most field accessors need to retrieve and test the field offset
+ // first, this is the offset value for that:
+ writer.SetValue("offset", NumToString(field.value.offset));
+ writer.SetValue("return_type", return_type);
+ writer.SetValue("field_type", field_type);
+ writer.SetValue("field_name", field_name);
+ writer.SetValue("field_default", field_default_value);
+ writer.SetValue("bbgetter", bbgetter);
+ // Generate the accessors that don't do object reuse.
+ if (value_base_type == BASE_TYPE_STRUCT) {
+ // Calls the accessor that takes an accessor object with a
+ // new object.
+ // val pos
+ // get() = pos(Vec3())
+ GenerateGetterOneLine(writer, field_name, return_type, [&]() {
+ writer += "{{field_name}}({{field_type}}())";
+ });
+ } else if (value_base_type == BASE_TYPE_VECTOR &&
+ field.value.type.element == BASE_TYPE_STRUCT) {
+ // Accessors for vectors of structs also take accessor objects,
+ // this generates a variant without that argument.
+ // ex: fun weapons(j: Int) = weapons(Weapon(), j)
+ GenerateFunOneLine(writer, field_name, "j: Int", return_type, [&]() {
+ writer += "{{field_name}}({{field_type}}(), j)";
+ });
+ }
+
+ if (IsScalar(value_base_type)) {
+ if (struct_def.fixed) {
+ GenerateGetterOneLine(writer, field_name, return_type, [&]() {
+ std::string found = "{{bbgetter}}(bufferPos + {{offset}})";
+ writer += WrapEnumValue(field.value.type, found);
+ });
+ } else {
+ GenerateGetterOneLine(writer, field_name, return_type, [&]() {
+ std::string found = "{{bbgetter}}(it + bufferPos)";
+ writer += LookupFieldOneLine(offset_val,
+ WrapEnumValue(field.value.type, found),
+ "{{field_default}}");
+ });
+ }
+ } else {
+ switch (value_base_type) {
+ case BASE_TYPE_STRUCT:
+ if (struct_def.fixed) {
+ // create getter with object reuse
+ // ex:
+ // fun pos(obj: Vec3) : Vec3? = obj.init(bufferPos + 4, bb)
+ // ? adds nullability annotation
+ GenerateFunOneLine(
+ writer, field_name, "obj: " + field_type, return_type, [&]() {
+ writer += "obj.init(bufferPos + {{offset}}, bb)";
+ });
+ } else {
+ // create getter with object reuse
+ // ex:
+ // fun pos(obj: Vec3) : Vec3? {
+ // val o = offset(4)
+ // return if(o != 0) {
+ // obj.init(o + bufferPos, bb)
+ // else {
+ // null
+ // }
+ // }
+ // ? adds nullability annotation
+ GenerateFunOneLine(
+ writer, field_name, "obj: " + field_type, return_type, [&]() {
+ auto fixed = field.value.type.struct_def->fixed;
+
+ writer.SetValue("seek", Indirect("it + bufferPos", fixed));
+ writer += LookupFieldOneLine(
+ offset_val, "obj.init({{seek}}, bb)", "null");
+ });
+ }
+ break;
+ case BASE_TYPE_STRING:
+ // create string getter
+ // e.g.
+ // val Name : String?
+ // get() = {
+ // val o = offset(10)
+ // return if (o != 0) string(o + bufferPos) else null
+ // }
+ // ? adds nullability annotation
+ GenerateGetterOneLine(writer, field_name, return_type, [&]() {
+ writer += LookupFieldOneLine(offset_val, "string(it + bufferPos)",
+ "null");
+ });
+ break;
+ case BASE_TYPE_VECTOR: {
+ // e.g.
+ // fun inventory(j: Int) : UByte {
+ // val o = offset(14)
+ // return if (o != 0) {
+ // bb.get(vector(it) + j * 1).toUByte()
+ // } else {
+ // 0
+ // }
+ // }
+
+ auto vectortype = field.value.type.VectorType();
+ std::string params = "j: Int";
+
+ if (vectortype.base_type == BASE_TYPE_STRUCT ||
+ vectortype.base_type == BASE_TYPE_UNION) {
+ params = "obj: " + field_type + ", j: Int";
+ }
+
+ GenerateFunOneLine(writer, field_name, params, return_type, [&]() {
+ auto inline_size = NumToString(InlineSize(vectortype));
+ auto index = "vector(it) + j * " + inline_size;
+ std::string found = "";
+ writer.SetValue("index", index);
+
+ if (IsEnum(vectortype)) {
+ found = "{{field_type}}({{bbgetter}}({{index}}))";
+ } else {
+ switch (vectortype.base_type) {
+ case BASE_TYPE_STRUCT: {
+ bool fixed = vectortype.struct_def->fixed;
+ writer.SetValue("index", Indirect(index, fixed));
+ found = "obj.init({{index}}, bb)";
+ break;
+ }
+ case BASE_TYPE_UNION:
+ found = "{{bbgetter}}(obj, {{index}})";
+ break;
+ case BASE_TYPE_UTYPE:
+ found = "{{field_type}}({{bbgetter}}({{index}}))";
+ break;
+ default: found = "{{bbgetter}}({{index}})";
+ }
+ }
+ writer +=
+ LookupFieldOneLine(offset_val, found, "{{field_default}}");
+ });
+ break;
+ }
+ case BASE_TYPE_UNION:
+ GenerateFunOneLine(
+ writer, field_name, "obj: " + field_type, return_type, [&]() {
+ writer += LookupFieldOneLine(
+ offset_val, bbgetter + "(obj, it + bufferPos)", "null");
+ });
+ break;
+ default: FLATBUFFERS_ASSERT(0);
+ }
+ }
+
+ if (value_base_type == BASE_TYPE_VECTOR) {
+ // Generate Lenght functions for vectors
+ GenerateGetterOneLine(writer, field_name + "Length", "Int", [&]() {
+ writer += LookupFieldOneLine(offset_val, "vectorLength(it)", "0");
+ });
+
+ // See if we should generate a by-key accessor.
+ if (field.value.type.element == BASE_TYPE_STRUCT &&
+ !field.value.type.struct_def->fixed) {
+ auto &sd = *field.value.type.struct_def;
+ auto &fields = sd.fields.vec;
+ for (auto kit = fields.begin(); kit != fields.end(); ++kit) {
+ auto &kfield = **kit;
+ if (kfield.key) {
+ auto qualified_name = TypeInNameSpace(sd);
+ auto name = namer_.Method(field, "ByKey");
+ auto params = "key: " + GenTypeGet(kfield.value.type);
+ auto rtype = qualified_name + "?";
+ GenerateFunOneLine(writer, name, params, rtype, [&]() {
+ writer += LookupFieldOneLine(
+ offset_val,
+ qualified_name + ".lookupByKey(null, vector(it), key, bb)",
+ "null");
+ });
+
+ auto param2 = "obj: " + qualified_name +
+ ", key: " + GenTypeGet(kfield.value.type);
+ GenerateFunOneLine(writer, name, param2, rtype, [&]() {
+ writer += LookupFieldOneLine(
+ offset_val,
+ qualified_name + ".lookupByKey(obj, vector(it), key, bb)",
+ "null");
+ });
+
+ break;
+ }
+ }
+ }
+ }
+
+ if ((value_base_type == BASE_TYPE_VECTOR &&
+ IsScalar(field.value.type.VectorType().base_type)) ||
+ value_base_type == BASE_TYPE_STRING) {
+ auto end_idx =
+ NumToString(value_base_type == BASE_TYPE_STRING
+ ? 1
+ : InlineSize(field.value.type.VectorType()));
+
+ // Generate a ByteBuffer accessor for strings & vectors of scalars.
+ // e.g.
+ // fun inventoryInByteBuffer(buffer: Bytebuffer):
+ // ByteBuffer = vectorAsBuffer(buffer, 14, 1)
+ GenerateFunOneLine(
+ writer, field_name + "AsBuffer", "", "ReadBuffer", [&]() {
+ writer.SetValue("end", end_idx);
+ writer += "vectorAsBuffer(bb, {{offset}}, {{end}})";
+ });
+ }
+
+ // generate object accessors if is nested_flatbuffer
+ // fun testnestedflatbufferAsMonster() : Monster?
+ //{ return testnestedflatbufferAsMonster(new Monster()); }
+
+ if (field.nested_flatbuffer) {
+ auto nested_type_name = TypeInNameSpace(*field.nested_flatbuffer);
+ auto nested_method_name =
+ field_name + "As" + field.nested_flatbuffer->name;
+
+ GenerateGetterOneLine(
+ writer, nested_method_name, nested_type_name + "?", [&]() {
+ writer += nested_method_name + "(" + nested_type_name + "())";
+ });
+
+ GenerateFunOneLine(
+ writer, nested_method_name, "obj: " + nested_type_name,
+ nested_type_name + "?", [&]() {
+ writer += LookupFieldOneLine(
+ offset_val, "obj.init(indirect(vector(it)), bb)", "null");
+ });
+ }
+
+ writer += ""; // Initial line break between fields
+ }
+ if (struct_def.has_key && !struct_def.fixed) {
+ // Key Comparison method
+ GenerateOverrideFun(
+ writer, "keysCompare",
+ "o1: Offset<*>, o2: Offset<*>, buffer: ReadWriteBuffer", "Int",
+ [&]() {
+ if (IsString(key_field->value.type)) {
+ writer.SetValue("offset", NumToString(key_field->value.offset));
+ writer +=
+ " return compareStrings(offset({{offset}}, o1, "
+ "buffer), offset({{offset}}, o2, buffer), buffer)";
+
+ } else {
+ auto getter1 = GenLookupByKey(key_field, "buffer", "o1");
+ auto getter2 = GenLookupByKey(key_field, "buffer", "o2");
+ writer += "val a = " + getter1;
+ writer += "val b = " + getter2;
+ writer += "return (a - b).toInt().sign()";
+ }
+ });
+ }
+ }
+
+ static std::string LiteralSuffix(const Type &type) {
+ auto base = IsVector(type) ? type.element : type.base_type;
+ switch (base) {
+ case BASE_TYPE_UINT:
+ case BASE_TYPE_UCHAR:
+ case BASE_TYPE_UTYPE:
+ case BASE_TYPE_USHORT: return "u";
+ case BASE_TYPE_ULONG: return "UL";
+ case BASE_TYPE_LONG: return "L";
+ default: return "";
+ }
+ }
+
+ std::string WrapEnumValue(const Type &type, const std::string value) const {
+ if (IsEnum(type)) { return GenType(type) + "(" + value + ")"; }
+ if (IsVector(type) && IsEnum(type.VectorType())) {
+ return GenType(type.VectorType()) + "(" + value + ")";
+ }
+ return value;
+ }
+
+ void GenerateCompanionObject(CodeWriter &code,
+ const std::function<void()> &callback) const {
+ code += "companion object {";
+ code.IncrementIdentLevel();
+ callback();
+ code.DecrementIdentLevel();
+ code += "}";
+ }
+
+ // Generate a documentation comment, if available.
+ void GenerateComment(const std::vector<std::string> &dc, CodeWriter &writer,
+ const CommentConfig *config) const {
+ if (dc.begin() == dc.end()) {
+ // Don't output empty comment blocks with 0 lines of comment content.
+ return;
+ }
+
+ if (config != nullptr && config->first_line != nullptr) {
+ writer += std::string(config->first_line);
+ }
+ std::string line_prefix =
+ ((config != nullptr && config->content_line_prefix != nullptr)
+ ? config->content_line_prefix
+ : "///");
+ for (auto it = dc.begin(); it != dc.end(); ++it) {
+ writer += line_prefix + *it;
+ }
+ if (config != nullptr && config->last_line != nullptr) {
+ writer += std::string(config->last_line);
+ }
+ }
+
+ void GenerateGetRootAsAccessors(const std::string &struct_name,
+ CodeWriter &writer,
+ IDLOptions options) const {
+ // Generate a special accessor for the table that when used as the root
+ // ex: fun getRootAsMonster(buffer: ByteBuffer): Monster {...}
+ writer.SetValue("gr_name", struct_name);
+
+ // create convenience method that doesn't require an existing object
+ GenerateJvmStaticAnnotation(writer, options.gen_jvmstatic);
+ GenerateFunOneLine(writer, "asRoot", "buffer: ReadWriteBuffer", struct_name,
+ [&]() { writer += "asRoot(buffer, {{gr_name}}())"; });
+
+ // create method that allows object reuse
+ // ex: fun Monster getRootAsMonster(buffer: ByteBuffer, obj: Monster) {...}
+ GenerateJvmStaticAnnotation(writer, options.gen_jvmstatic);
+ GenerateFunOneLine(
+ writer, "asRoot", "buffer: ReadWriteBuffer, obj: {{gr_name}}",
+ struct_name, [&]() {
+ writer +=
+ "obj.init(buffer.getInt(buffer.limit) + buffer.limit, buffer)";
+ });
+ }
+
+ void GenerateStaticConstructor(const StructDef &struct_def, CodeWriter &code,
+ const IDLOptions options) const {
+ // create a struct constructor function
+ auto params = StructConstructorParams(struct_def);
+ GenerateFun(
+ code, namer_.LegacyJavaMethod2("create", struct_def, ""), params,
+ "Offset<" + namer_.Type(struct_def) + '>',
+ [&]() {
+ GenStructBody(struct_def, code, "");
+ code += "return Offset(builder.offset())";
+ },
+ options.gen_jvmstatic);
+ }
+
+ std::string StructConstructorParams(const StructDef &struct_def,
+ const std::string &prefix = "") const {
+ // builder: FlatBufferBuilder
+ std::stringstream out;
+ auto field_vec = struct_def.fields.vec;
+ if (prefix.empty()) { out << "builder: FlatBufferBuilder"; }
+ for (auto it = field_vec.begin(); it != field_vec.end(); ++it) {
+ auto &field = **it;
+ if (IsStruct(field.value.type)) {
+ // Generate arguments for a struct inside a struct. To ensure
+ // names don't clash, and to make it obvious these arguments are
+ // constructing a nested struct, prefix the name with the field
+ // name.
+ out << StructConstructorParams(*field.value.type.struct_def,
+ prefix + (namer_.Variable(field) + "_"));
+ } else {
+ out << ", " << prefix << namer_.Variable(field) << ": "
+ << GenType(field.value.type);
+ }
+ }
+ return out.str();
+ }
+
+ static void GenerateVarGetterSetterOneLine(CodeWriter &writer,
+ const std::string &name,
+ const std::string &type,
+ const std::string &getter,
+ const std::string &setter) {
+ // Generates Kotlin getter for properties
+ // e.g.:
+ // val prop: Mytype
+ // get() = {
+ // return x
+ // }
+ writer.SetValue("name", name);
+ writer.SetValue("type", type);
+ writer += "var {{name}} : {{type}}";
+ writer.IncrementIdentLevel();
+ writer += "get() = " + getter;
+ writer += "set(value) = " + setter;
+ writer.DecrementIdentLevel();
+ }
+
+ static void GeneratePropertyOneLine(CodeWriter &writer,
+ const std::string &name,
+ const std::string &type,
+ const std::function<void()> &body) {
+ // Generates Kotlin getter for properties
+ // e.g.:
+ // val prop: Mytype = x
+ writer.SetValue("_name", name);
+ writer.SetValue("_type", type);
+ writer += "val {{_name}} : {{_type}} = \\";
+ body();
+ }
+ static void GenerateGetterOneLine(CodeWriter &writer, const std::string &name,
+ const std::string &type,
+ const std::function<void()> &body) {
+ // Generates Kotlin getter for properties
+ // e.g.:
+ // val prop: Mytype get() = x
+ writer.SetValue("_name", name);
+ writer.SetValue("_type", type);
+ writer += "val {{_name}} : {{_type}} get() = \\";
+ body();
+ }
+
+ static void GenerateGetter(CodeWriter &writer, const std::string &name,
+ const std::string &type,
+ const std::function<void()> &body) {
+ // Generates Kotlin getter for properties
+ // e.g.:
+ // val prop: Mytype
+ // get() = {
+ // return x
+ // }
+ writer.SetValue("name", name);
+ writer.SetValue("type", type);
+ writer += "val {{name}} : {{type}}";
+ writer.IncrementIdentLevel();
+ writer += "get() {";
+ writer.IncrementIdentLevel();
+ body();
+ writer.DecrementIdentLevel();
+ writer += "}";
+ writer.DecrementIdentLevel();
+ }
+
+ static void GenerateFun(CodeWriter &writer, const std::string &name,
+ const std::string &params,
+ const std::string &returnType,
+ const std::function<void()> &body,
+ bool gen_jvmstatic = false) {
+ // Generates Kotlin function
+ // e.g.:
+ // fun path(j: Int): Vec3 {
+ // return path(Vec3(), j)
+ // }
+ auto noreturn = returnType.empty();
+ writer.SetValue("name", name);
+ writer.SetValue("params", params);
+ writer.SetValue("return_type", noreturn ? "" : ": " + returnType);
+ GenerateJvmStaticAnnotation(writer, gen_jvmstatic);
+ writer += "fun {{name}}({{params}}) {{return_type}} {";
+ writer.IncrementIdentLevel();
+ body();
+ writer.DecrementIdentLevel();
+ writer += "}";
+ }
+
+ static void GenerateFunOneLine(CodeWriter &writer, const std::string &name,
+ const std::string &params,
+ const std::string &returnType,
+ const std::function<void()> &body,
+ bool gen_jvmstatic = false) {
+ // Generates Kotlin function
+ // e.g.:
+ // fun path(j: Int): Vec3 = return path(Vec3(), j)
+ auto ret = returnType.empty() ? "" : " : " + returnType;
+ GenerateJvmStaticAnnotation(writer, gen_jvmstatic);
+ writer += "fun " + name + "(" + params + ")" + ret + " = \\";
+ body();
+ }
+
+ static void GenerateOverrideFun(CodeWriter &writer, const std::string &name,
+ const std::string &params,
+ const std::string &returnType,
+ const std::function<void()> &body) {
+ // Generates Kotlin function
+ // e.g.:
+ // override fun path(j: Int): Vec3 = return path(Vec3(), j)
+ writer += "override \\";
+ GenerateFun(writer, name, params, returnType, body);
+ }
+
+ static void GenerateOverrideFunOneLine(CodeWriter &writer,
+ const std::string &name,
+ const std::string &params,
+ const std::string &returnType,
+ const std::string &statement) {
+ // Generates Kotlin function
+ // e.g.:
+ // override fun path(j: Int): Vec3 = return path(Vec3(), j)
+ writer.SetValue("name", name);
+ writer.SetValue("params", params);
+ writer.SetValue("return_type",
+ returnType.empty() ? "" : " : " + returnType);
+ writer += "override fun {{name}}({{params}}){{return_type}} = \\";
+ writer += statement;
+ }
+
+ static std::string LookupFieldOneLine(const std::string &offset,
+ const std::string &found,
+ const std::string &not_found) {
+ return "lookupField(" + offset + ", " + not_found + " ) { " + found + " }";
+ }
+
+ static std::string Indirect(const std::string &index, bool fixed) {
+ // We apply indirect() and struct is not fixed.
+ if (!fixed) return "indirect(" + index + ")";
+ return index;
+ }
+
+ static std::string NotFoundReturn(BaseType el) {
+ switch (el) {
+ case BASE_TYPE_FLOAT: return "0.0f";
+ case BASE_TYPE_DOUBLE: return "0.0";
+ case BASE_TYPE_BOOL: return "false";
+ case BASE_TYPE_LONG:
+ case BASE_TYPE_INT:
+ case BASE_TYPE_CHAR:
+ case BASE_TYPE_SHORT: return "0";
+ case BASE_TYPE_UINT:
+ case BASE_TYPE_UCHAR:
+ case BASE_TYPE_USHORT:
+ case BASE_TYPE_UTYPE: return "0u";
+ case BASE_TYPE_ULONG: return "0uL";
+ default: return "null";
+ }
+ }
+
+ // Prepend @JvmStatic to methods in companion object.
+ static void GenerateJvmStaticAnnotation(CodeWriter &code,
+ bool gen_jvmstatic) {
+ if (gen_jvmstatic) { code += "@JvmStatic"; }
+ }
+
+ const IdlNamer namer_;
+};
+} // namespace kotlin
+
+static bool GenerateKotlinKMP(const Parser &parser, const std::string &path,
+ const std::string &file_name) {
+ kotlin::KotlinKMPGenerator generator(parser, path, file_name);
+ return generator.generate();
+}
+
+namespace {
+
+class KotlinKMPCodeGenerator : public CodeGenerator {
+ public:
+ Status GenerateCode(const Parser &parser, const std::string &path,
+ const std::string &filename) override {
+ if (!GenerateKotlinKMP(parser, path, filename)) { return Status::ERROR; }
+ return Status::OK;
+ }
+
+ Status GenerateCode(const uint8_t *, int64_t,
+ const CodeGenOptions &) override {
+ return Status::NOT_IMPLEMENTED;
+ }
+
+ Status GenerateMakeRule(const Parser &parser, const std::string &path,
+ const std::string &filename,
+ std::string &output) override {
+ (void)parser;
+ (void)path;
+ (void)filename;
+ (void)output;
+ return Status::NOT_IMPLEMENTED;
+ }
+
+ Status GenerateGrpcCode(const Parser &parser, const std::string &path,
+ const std::string &filename) override {
+ (void)parser;
+ (void)path;
+ (void)filename;
+ return Status::NOT_IMPLEMENTED;
+ }
+
+ Status GenerateRootFile(const Parser &parser,
+ const std::string &path) override {
+ (void)parser;
+ (void)path;
+ return Status::NOT_IMPLEMENTED;
+ }
+ bool IsSchemaOnly() const override { return true; }
+
+ bool SupportsBfbsGeneration() const override { return false; }
+
+ bool SupportsRootFileGeneration() const override { return false; }
+
+ IDLOptions::Language Language() const override {
+ return IDLOptions::kKotlinKmp;
+ }
+
+ std::string LanguageName() const override { return "Kotlin"; }
+};
+} // namespace
+
+std::unique_ptr<CodeGenerator> NewKotlinKMPCodeGenerator() {
+ return std::unique_ptr<KotlinKMPCodeGenerator>(new KotlinKMPCodeGenerator());
+}
+
+} // namespace flatbuffers
diff --git a/contrib/libs/flatbuffers/src/idl_gen_lobster.cpp b/contrib/libs/flatbuffers/src/idl_gen_lobster.cpp
index 37c95e9600..c89e7bb461 100644
--- a/contrib/libs/flatbuffers/src/idl_gen_lobster.cpp
+++ b/contrib/libs/flatbuffers/src/idl_gen_lobster.cpp
@@ -31,7 +31,7 @@ class LobsterGenerator : public BaseGenerator {
public:
LobsterGenerator(const Parser &parser, const std::string &path,
const std::string &file_name)
- : BaseGenerator(parser, path, file_name, "" /* not used */, "_",
+ : BaseGenerator(parser, path, file_name, "" /* not used */, ".",
"lobster") {
static const char *const keywords[] = {
"nil", "true", "false", "return", "struct", "class",
@@ -79,7 +79,7 @@ class LobsterGenerator : public BaseGenerator {
if (IsBool(type.base_type)) return "bool";
if (IsScalar(type.base_type) && type.enum_def)
return NormalizedName(*type.enum_def);
- if (!IsScalar(type.base_type)) return "flatbuffers_offset";
+ if (!IsScalar(type.base_type)) return "flatbuffers.offset";
if (IsString(type)) return "string";
return "int";
}
@@ -119,15 +119,17 @@ class LobsterGenerator : public BaseGenerator {
offsets + ")";
} else {
- auto defval = field.IsOptional() ? "0" : field.value.constant;
- acc = "buf_.flatbuffers_field_" + GenTypeName(field.value.type) +
- "(pos_, " + offsets + ", " + defval + ")";
+ auto defval = field.IsOptional()
+ ? (IsFloat(field.value.type.base_type) ? "0.0" : "0")
+ : field.value.constant;
+ acc = "flatbuffers.field_" + GenTypeName(field.value.type) +
+ "(buf_, pos_, " + offsets + ", " + defval + ")";
if (IsBool(field.value.type.base_type)) acc = "bool(" + acc + ")";
}
if (field.value.type.enum_def)
acc = NormalizedName(*field.value.type.enum_def) + "(" + acc + ")";
if (field.IsOptional()) {
- acc += ", buf_.flatbuffers_field_present(pos_, " + offsets + ")";
+ acc += ", flatbuffers.field_present(buf_, pos_, " + offsets + ")";
code += def + "() -> " + LobsterType(field.value.type) +
", bool:\n return " + acc + "\n";
} else {
@@ -144,9 +146,9 @@ class LobsterGenerator : public BaseGenerator {
code += "return " + name + "{ buf_, pos_ + " + offsets + " }\n";
} else {
code += def + "() -> " + name + "?:\n ";
- code += std::string("let o = buf_.flatbuffers_field_") +
+ code += std::string("let o = flatbuffers.field_") +
(field.value.type.struct_def->fixed ? "struct" : "table") +
- "(pos_, " + offsets + ")\n return if o: " + name +
+ "(buf_, pos_, " + offsets + ")\n return if o: " + name +
" { buf_, o } else: nil\n";
}
break;
@@ -154,16 +156,16 @@ class LobsterGenerator : public BaseGenerator {
case BASE_TYPE_STRING:
code += def +
"() -> string:\n return "
- "buf_.flatbuffers_field_string(pos_, " +
+ "flatbuffers.field_string(buf_, pos_, " +
offsets + ")\n";
break;
case BASE_TYPE_VECTOR: {
auto vectortype = field.value.type.VectorType();
if (vectortype.base_type == BASE_TYPE_STRUCT) {
- auto start = "buf_.flatbuffers_field_vector(pos_, " + offsets +
+ auto start = "flatbuffers.field_vector(buf_, pos_, " + offsets +
") + i * " + NumToString(InlineSize(vectortype));
if (!(vectortype.struct_def->fixed)) {
- start = "buf_.flatbuffers_indirect(" + start + ")";
+ start = "flatbuffers.indirect(buf_, " + start + ")";
}
code += def + "(i:int) -> " +
NamespacedName(*field.value.type.struct_def) +
@@ -173,13 +175,13 @@ class LobsterGenerator : public BaseGenerator {
} else {
if (IsString(vectortype)) {
code += def + "(i:int) -> string:\n return ";
- code += "buf_.flatbuffers_string";
+ code += "flatbuffers.string";
} else {
code += def + "(i:int) -> " + LobsterType(vectortype) +
":\n return ";
- code += "buf_.read_" + GenTypeName(vectortype) + "_le";
+ code += "read_" + GenTypeName(vectortype) + "_le";
}
- code += "(buf_.flatbuffers_field_vector(pos_, " + offsets +
+ code += "(buf_, buf_.flatbuffers.field_vector(pos_, " + offsets +
") + i * " + NumToString(InlineSize(vectortype)) + ")\n";
}
break;
@@ -191,7 +193,7 @@ class LobsterGenerator : public BaseGenerator {
if (ev.IsNonZero()) {
code += def + "_as_" + ev.name + "():\n return " +
NamespacedName(*ev.union_type.struct_def) +
- " { buf_, buf_.flatbuffers_field_table(pos_, " + offsets +
+ " { buf_, flatbuffers.field_table(buf_, pos_, " + offsets +
") }\n";
}
}
@@ -202,7 +204,7 @@ class LobsterGenerator : public BaseGenerator {
if (IsVector(field.value.type)) {
code += def +
"_length() -> int:\n return "
- "buf_.flatbuffers_field_vector_len(pos_, " +
+ "flatbuffers.field_vector_len(buf_, pos_, " +
offsets + ")\n";
}
}
@@ -211,7 +213,7 @@ class LobsterGenerator : public BaseGenerator {
void GenTableBuilders(const StructDef &struct_def, std::string *code_ptr) {
std::string &code = *code_ptr;
code += "struct " + NormalizedName(struct_def) +
- "Builder:\n b_:flatbuffers_builder\n";
+ "Builder:\n b_:flatbuffers.builder\n";
code += " def start():\n b_.StartObject(" +
NumToString(struct_def.fields.vec.size()) +
")\n return this\n";
@@ -236,7 +238,7 @@ class LobsterGenerator : public BaseGenerator {
if (IsVector(field.value.type)) {
code += "def " + NormalizedName(struct_def) + "Start" +
ConvertCase(NormalizedName(field), Case::kUpperCamel) +
- "Vector(b_:flatbuffers_builder, n_:int):\n b_.StartVector(";
+ "Vector(b_:flatbuffers.builder, n_:int):\n b_.StartVector(";
auto vector_type = field.value.type.VectorType();
auto alignment = InlineAlignment(vector_type);
auto elem_size = InlineSize(vector_type);
@@ -246,7 +248,7 @@ class LobsterGenerator : public BaseGenerator {
!vector_type.struct_def->fixed) {
code += "def " + NormalizedName(struct_def) + "Create" +
ConvertCase(NormalizedName(field), Case::kUpperCamel) +
- "Vector(b_:flatbuffers_builder, v_:[" +
+ "Vector(b_:flatbuffers.builder, v_:[" +
LobsterType(vector_type) + "]):\n b_.StartVector(" +
NumToString(elem_size) + ", v_.length, " +
NumToString(alignment) + ")\n reverse(v_) e_: b_.Prepend" +
@@ -271,7 +273,7 @@ class LobsterGenerator : public BaseGenerator {
std::string &code = *code_ptr;
CheckNameSpace(struct_def, &code);
GenComment(struct_def.doc_comment, code_ptr, nullptr, "");
- code += "class " + NormalizedName(struct_def) + " : flatbuffers_handle\n";
+ code += "class " + NormalizedName(struct_def) + " : flatbuffers.handle\n";
for (auto it = struct_def.fields.vec.begin();
it != struct_def.fields.vec.end(); ++it) {
auto &field = **it;
@@ -284,7 +286,7 @@ class LobsterGenerator : public BaseGenerator {
// the root type.
code += "def GetRootAs" + NormalizedName(struct_def) +
"(buf:string): return " + NormalizedName(struct_def) +
- " { buf, buf.flatbuffers_indirect(0) }\n\n";
+ " { buf, flatbuffers.indirect(buf, 0) }\n\n";
}
if (struct_def.fixed) {
// create a struct constructor function
@@ -360,7 +362,7 @@ class LobsterGenerator : public BaseGenerator {
void GenStructBuilder(const StructDef &struct_def, std::string *code_ptr) {
std::string &code = *code_ptr;
code +=
- "def Create" + NormalizedName(struct_def) + "(b_:flatbuffers_builder";
+ "def Create" + NormalizedName(struct_def) + "(b_:flatbuffers.builder";
StructBuilderArgs(struct_def, "", code_ptr);
code += "):\n";
StructBuilderBody(struct_def, "", code_ptr);
diff --git a/contrib/libs/flatbuffers/src/idl_gen_python.cpp b/contrib/libs/flatbuffers/src/idl_gen_python.cpp
index ff535d1574..9e1627592e 100644
--- a/contrib/libs/flatbuffers/src/idl_gen_python.cpp
+++ b/contrib/libs/flatbuffers/src/idl_gen_python.cpp
@@ -815,8 +815,12 @@ class PythonGenerator : public BaseGenerator {
if (!parser_.opts.one_file && !parser_.opts.python_no_type_prefix_suffix) {
// Generate method without struct name.
- code += "def Start" + field_method +
- "Vector(builder, numElems: int) -> int:\n";
+ if (parser_.opts.python_typing) {
+ code += "def Start" + field_method +
+ "Vector(builder, numElems: int) -> int:\n";
+ } else {
+ code += "def Start" + field_method + "Vector(builder, numElems):\n";
+ }
code += Indent + "return " + struct_type + "Start";
code += field_method + "Vector(builder, numElems)\n\n";
}
diff --git a/contrib/libs/flatbuffers/src/idl_gen_rust.cpp b/contrib/libs/flatbuffers/src/idl_gen_rust.cpp
index 95fa39bdd6..a85a7812dc 100644
--- a/contrib/libs/flatbuffers/src/idl_gen_rust.cpp
+++ b/contrib/libs/flatbuffers/src/idl_gen_rust.cpp
@@ -989,7 +989,8 @@ class RustGenerator : public BaseGenerator {
code_ += " }";
// Pack flatbuffers union value
code_ +=
- " pub fn pack(&self, fbb: &mut flatbuffers::FlatBufferBuilder)"
+ " pub fn pack<'b, A: flatbuffers::Allocator + 'b>(&self, fbb: &mut "
+ "flatbuffers::FlatBufferBuilder<'b, A>)"
" -> Option<flatbuffers::WIPOffset<flatbuffers::UnionWIPOffset>>"
" {";
code_ += " match self {";
@@ -1717,8 +1718,11 @@ class RustGenerator : public BaseGenerator {
code_.SetValue("MAYBE_LT",
TableBuilderArgsNeedsLifetime(struct_def) ? "<'args>" : "");
code_ += " #[allow(unused_mut)]";
- code_ += " pub fn create<'bldr: 'args, 'args: 'mut_bldr, 'mut_bldr>(";
- code_ += " _fbb: &'mut_bldr mut flatbuffers::FlatBufferBuilder<'bldr>,";
+ code_ +=
+ " pub fn create<'bldr: 'args, 'args: 'mut_bldr, 'mut_bldr, A: "
+ "flatbuffers::Allocator + 'bldr>(";
+ code_ +=
+ " _fbb: &'mut_bldr mut flatbuffers::FlatBufferBuilder<'bldr, A>,";
code_ += " {{MAYBE_US}}args: &'args {{STRUCT_TY}}Args{{MAYBE_LT}}";
code_ += " ) -> flatbuffers::WIPOffset<{{STRUCT_TY}}<'bldr>> {";
@@ -2117,15 +2121,20 @@ class RustGenerator : public BaseGenerator {
}
// Generate a builder struct:
- code_ += "{{ACCESS_TYPE}} struct {{STRUCT_TY}}Builder<'a: 'b, 'b> {";
- code_ += " fbb_: &'b mut flatbuffers::FlatBufferBuilder<'a>,";
+ code_ +=
+ "{{ACCESS_TYPE}} struct {{STRUCT_TY}}Builder<'a: 'b, 'b, A: "
+ "flatbuffers::Allocator + 'a> {";
+ code_ += " fbb_: &'b mut flatbuffers::FlatBufferBuilder<'a, A>,";
code_ +=
" start_: flatbuffers::WIPOffset<"
"flatbuffers::TableUnfinishedWIPOffset>,";
code_ += "}";
// Generate builder functions:
- code_ += "impl<'a: 'b, 'b> {{STRUCT_TY}}Builder<'a, 'b> {";
+ code_ +=
+ "impl<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> "
+ "{{STRUCT_TY}}Builder<'a, "
+ "'b, A> {";
ForAllTableFields(struct_def, [&](const FieldDef &field) {
const bool is_scalar = IsScalar(field.value.type.base_type);
std::string offset = namer_.LegacyRustFieldOffsetName(field);
@@ -2160,8 +2169,8 @@ class RustGenerator : public BaseGenerator {
// Struct initializer (all fields required);
code_ += " #[inline]";
code_ +=
- " pub fn new(_fbb: &'b mut flatbuffers::FlatBufferBuilder<'a>) -> "
- "{{STRUCT_TY}}Builder<'a, 'b> {";
+ " pub fn new(_fbb: &'b mut flatbuffers::FlatBufferBuilder<'a, A>) -> "
+ "{{STRUCT_TY}}Builder<'a, 'b, A> {";
code_.SetValue("NUM_FIELDS", NumToString(struct_def.fields.vec.size()));
code_ += " let start = _fbb.start_table();";
code_ += " {{STRUCT_TY}}Builder {";
@@ -2264,9 +2273,9 @@ class RustGenerator : public BaseGenerator {
// Generate pack function.
code_ += "impl {{STRUCT_OTY}} {";
- code_ += " pub fn pack<'b>(";
+ code_ += " pub fn pack<'b, A: flatbuffers::Allocator + 'b>(";
code_ += " &self,";
- code_ += " _fbb: &mut flatbuffers::FlatBufferBuilder<'b>";
+ code_ += " _fbb: &mut flatbuffers::FlatBufferBuilder<'b, A>";
code_ += " ) -> flatbuffers::WIPOffset<{{STRUCT_TY}}<'b>> {";
// First we generate variables for each field and then later assemble them
// using "StructArgs" to more easily manage ownership of the builder.
@@ -2551,8 +2560,10 @@ class RustGenerator : public BaseGenerator {
// Finish a buffer with a given root object:
code_ += "#[inline]";
- code_ += "pub fn finish_{{STRUCT_FN}}_buffer<'a, 'b>(";
- code_ += " fbb: &'b mut flatbuffers::FlatBufferBuilder<'a>,";
+ code_ +=
+ "pub fn finish_{{STRUCT_FN}}_buffer<'a, 'b, A: "
+ "flatbuffers::Allocator + 'a>(";
+ code_ += " fbb: &'b mut flatbuffers::FlatBufferBuilder<'a, A>,";
code_ += " root: flatbuffers::WIPOffset<{{STRUCT_TY}}<'a>>) {";
if (parser_.file_identifier_.length()) {
code_ += " fbb.finish(root, Some({{STRUCT_CONST}}_IDENTIFIER));";
@@ -2564,8 +2575,8 @@ class RustGenerator : public BaseGenerator {
code_ += "#[inline]";
code_ +=
"pub fn finish_size_prefixed_{{STRUCT_FN}}_buffer"
- "<'a, 'b>("
- "fbb: &'b mut flatbuffers::FlatBufferBuilder<'a>, "
+ "<'a, 'b, A: flatbuffers::Allocator + 'a>("
+ "fbb: &'b mut flatbuffers::FlatBufferBuilder<'a, A>, "
"root: flatbuffers::WIPOffset<{{STRUCT_TY}}<'a>>) {";
if (parser_.file_identifier_.length()) {
code_ +=
diff --git a/contrib/libs/flatbuffers/src/idl_gen_swift.cpp b/contrib/libs/flatbuffers/src/idl_gen_swift.cpp
index 17f3bf5fa4..6cd1b478ec 100644
--- a/contrib/libs/flatbuffers/src/idl_gen_swift.cpp
+++ b/contrib/libs/flatbuffers/src/idl_gen_swift.cpp
@@ -1845,7 +1845,7 @@ class SwiftGenerator : public BaseGenerator {
}
std::string ValidateFunc() {
- return "static func validateVersion() { FlatBuffersVersion_23_5_26() }";
+ return "static func validateVersion() { FlatBuffersVersion_24_3_7() }";
}
std::string GenType(const Type &type,
diff --git a/contrib/libs/flatbuffers/src/idl_gen_text.cpp b/contrib/libs/flatbuffers/src/idl_gen_text.cpp
index a34667c4b6..895367e9a7 100644
--- a/contrib/libs/flatbuffers/src/idl_gen_text.cpp
+++ b/contrib/libs/flatbuffers/src/idl_gen_text.cpp
@@ -384,6 +384,14 @@ static const char *GenerateTextImpl(const Parser &parser, const Table *table,
}
// Generate a text representation of a flatbuffer in JSON format.
+// Deprecated: please use `GenTextFromTable`
+bool GenerateTextFromTable(const Parser &parser, const void *table,
+ const std::string &table_name,
+ std::string *_text) {
+ return GenTextFromTable(parser, table, table_name, _text) != nullptr;
+}
+
+// Generate a text representation of a flatbuffer in JSON format.
const char *GenTextFromTable(const Parser &parser, const void *table,
const std::string &table_name, std::string *_text) {
auto struct_def = parser.LookupStruct(table_name);
@@ -392,6 +400,12 @@ const char *GenTextFromTable(const Parser &parser, const void *table,
return GenerateTextImpl(parser, root, *struct_def, _text);
}
+// Deprecated: please use `GenText`
+const char *GenerateText(const Parser &parser, const void *flatbuffer,
+ std::string *_text) {
+ return GenText(parser, flatbuffer, _text);
+}
+
// Generate a text representation of a flatbuffer in JSON format.
const char *GenText(const Parser &parser, const void *flatbuffer,
std::string *_text) {
@@ -406,6 +420,12 @@ static std::string TextFileName(const std::string &path,
return path + file_name + ".json";
}
+// Deprecated: please use `GenTextFile`
+const char *GenerateTextFile(const Parser &parser, const std::string &path,
+ const std::string &file_name) {
+ return GenTextFile(parser, path, file_name);
+}
+
const char *GenTextFile(const Parser &parser, const std::string &path,
const std::string &file_name) {
if (parser.opts.use_flexbuffers) {
diff --git a/contrib/libs/flatbuffers/src/idl_gen_ts.cpp b/contrib/libs/flatbuffers/src/idl_gen_ts.cpp
index acd2a4febe..41c05e3b88 100644
--- a/contrib/libs/flatbuffers/src/idl_gen_ts.cpp
+++ b/contrib/libs/flatbuffers/src/idl_gen_ts.cpp
@@ -113,7 +113,7 @@ class TsGenerator : public BaseGenerator {
bool generate() {
generateEnums();
generateStructs();
- generateEntry();
+ if (!parser_.opts.ts_omit_entrypoint) { generateEntry(); }
if (!generateBundle()) return false;
return true;
}
@@ -149,7 +149,8 @@ class TsGenerator : public BaseGenerator {
std::string code;
- code += "// " + std::string(FlatBuffersGeneratedWarning()) + "\n\n";
+ code += "// " + std::string(FlatBuffersGeneratedWarning()) + "\n\n" +
+ "/* eslint-disable @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any, @typescript-eslint/no-non-null-assertion */\n\n";
for (auto it = bare_imports.begin(); it != bare_imports.end(); it++) {
code += it->second.import_statement + "\n";
@@ -254,7 +255,9 @@ class TsGenerator : public BaseGenerator {
}
for (const auto &it : ns_defs_) {
- code = "// " + std::string(FlatBuffersGeneratedWarning()) + "\n\n";
+ code = "// " + std::string(FlatBuffersGeneratedWarning()) + "\n\n" +
+ "/* eslint-disable @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any, @typescript-eslint/no-non-null-assertion */\n\n";
+
// export all definitions in ns entry point module
int export_counter = 0;
for (const auto &def : it.second.definitions) {
@@ -1997,11 +2000,7 @@ class TsGenerator : public BaseGenerator {
if (!IsScalar(field.value.type.base_type)) {
code += "0";
} else if (HasNullDefault(field)) {
- if (IsLong(field.value.type.base_type)) {
- code += "BigInt(0)";
- } else {
- code += "0";
- }
+ code += "null";
} else {
if (field.value.type.base_type == BASE_TYPE_BOOL) { code += "+"; }
code += GenDefaultValue(field, imports);
diff --git a/contrib/libs/flatbuffers/src/idl_namer.h b/contrib/libs/flatbuffers/src/idl_namer.h
index 337ac920b5..9a7fdb8e36 100644
--- a/contrib/libs/flatbuffers/src/idl_namer.h
+++ b/contrib/libs/flatbuffers/src/idl_namer.h
@@ -88,8 +88,9 @@ class IdlNamer : public Namer {
}
std::string Directories(const struct Namespace &ns,
- SkipDir skips = SkipDir::None) const {
- return Directories(ns.components, skips);
+ SkipDir skips = SkipDir::None,
+ Case input_case = Case::kUpperCamel) const {
+ return Directories(ns.components, skips, input_case);
}
// Legacy fields do not really follow the usual config and should be
diff --git a/contrib/libs/flatbuffers/src/idl_parser.cpp b/contrib/libs/flatbuffers/src/idl_parser.cpp
index 8b4f116854..d01e18ef76 100644
--- a/contrib/libs/flatbuffers/src/idl_parser.cpp
+++ b/contrib/libs/flatbuffers/src/idl_parser.cpp
@@ -2118,7 +2118,7 @@ CheckedError Parser::ParseSingleValue(const std::string *name, Value &e,
auto match = false;
#define IF_ECHECK_(force, dtoken, check, req) \
- if (!match && ((dtoken) == token_) && ((check) || IsConstTrue(force))) \
+ if (!match && ((dtoken) == token_) && ((check) || flatbuffers::IsConstTrue(force))) \
ECHECK(TryTypedValue(name, dtoken, check, e, req, &match))
#define TRY_ECHECK(dtoken, check, req) IF_ECHECK_(false, dtoken, check, req)
#define FORCE_ECHECK(dtoken, check, req) IF_ECHECK_(true, dtoken, check, req)
@@ -2483,7 +2483,7 @@ CheckedError Parser::ParseEnum(const bool is_union, EnumDef **dest,
ECHECK(StartEnum(enum_name, is_union, &enum_def));
if (filename != nullptr && !opts.project_root.empty()) {
enum_def->declaration_file =
- &GetPooledString(RelativeToRootPath(opts.project_root, filename));
+ &GetPooledString(FilePath(opts.project_root, filename, opts.binary_schema_absolute_paths));
}
enum_def->doc_comment = enum_comment;
if (!opts.proto_mode) {
@@ -2679,9 +2679,10 @@ std::vector<IncludedFile> Parser::GetIncludedFiles() const {
bool Parser::SupportsOptionalScalars(const flatbuffers::IDLOptions &opts) {
static FLATBUFFERS_CONSTEXPR unsigned long supported_langs =
IDLOptions::kRust | IDLOptions::kSwift | IDLOptions::kLobster |
- IDLOptions::kKotlin | IDLOptions::kCpp | IDLOptions::kJava |
- IDLOptions::kCSharp | IDLOptions::kTs | IDLOptions::kBinary |
- IDLOptions::kGo | IDLOptions::kPython | IDLOptions::kJson |
+ IDLOptions::kKotlin | IDLOptions::kKotlinKmp | IDLOptions::kCpp |
+ IDLOptions::kJava | IDLOptions::kCSharp | IDLOptions::kTs |
+ IDLOptions::kBinary | IDLOptions::kGo | IDLOptions::kPython |
+ IDLOptions::kJson |
IDLOptions::kNim;
unsigned long langs = opts.lang_to_generate;
return (langs > 0 && langs < IDLOptions::kMAX) && !(langs & ~supported_langs);
@@ -2702,7 +2703,7 @@ bool Parser::SupportsAdvancedUnionFeatures() const {
~(IDLOptions::kCpp | IDLOptions::kTs | IDLOptions::kPhp |
IDLOptions::kJava | IDLOptions::kCSharp | IDLOptions::kKotlin |
IDLOptions::kBinary | IDLOptions::kSwift | IDLOptions::kNim |
- IDLOptions::kJson)) == 0;
+ IDLOptions::kJson | IDLOptions::kKotlinKmp)) == 0;
}
bool Parser::SupportsAdvancedArrayFeatures() const {
@@ -2718,7 +2719,8 @@ bool Parser::Supports64BitOffsets() const {
}
bool Parser::SupportsUnionUnderlyingType() const {
- return (opts.lang_to_generate & ~(IDLOptions::kCpp | IDLOptions::kTs)) == 0;
+ return (opts.lang_to_generate & ~(IDLOptions::kCpp | IDLOptions::kTs |
+ IDLOptions::kBinary)) == 0;
}
Namespace *Parser::UniqueNamespace(Namespace *ns) {
@@ -2760,7 +2762,7 @@ CheckedError Parser::ParseDecl(const char *filename) {
struct_def->fixed = fixed;
if (filename && !opts.project_root.empty()) {
struct_def->declaration_file =
- &GetPooledString(RelativeToRootPath(opts.project_root, filename));
+ &GetPooledString(FilePath(opts.project_root, filename, opts.binary_schema_absolute_paths));
}
ECHECK(ParseMetaData(&struct_def->attributes));
struct_def->sortbysize =
@@ -2854,7 +2856,7 @@ CheckedError Parser::ParseService(const char *filename) {
service_def.defined_namespace = current_namespace_;
if (filename != nullptr && !opts.project_root.empty()) {
service_def.declaration_file =
- &GetPooledString(RelativeToRootPath(opts.project_root, filename));
+ &GetPooledString(FilePath(opts.project_root, filename, opts.binary_schema_absolute_paths));
}
if (services_.Add(current_namespace_->GetFullyQualifiedName(service_name),
&service_def))
@@ -3935,11 +3937,12 @@ void Parser::Serialize() {
std::vector<Offset<flatbuffers::String>> included_files;
for (auto f = files_included_per_file_.begin();
f != files_included_per_file_.end(); f++) {
- const auto filename__ = builder_.CreateSharedString(
- RelativeToRootPath(opts.project_root, f->first));
+
+ const auto filename__ = builder_.CreateSharedString(FilePath(
+ opts.project_root, f->first, opts.binary_schema_absolute_paths));
for (auto i = f->second.begin(); i != f->second.end(); i++) {
included_files.push_back(builder_.CreateSharedString(
- RelativeToRootPath(opts.project_root, i->filename)));
+ FilePath(opts.project_root, i->filename, opts.binary_schema_absolute_paths)));
}
const auto included_files__ = builder_.CreateVector(included_files);
included_files.clear();
diff --git a/contrib/libs/flatbuffers/src/namer.h b/contrib/libs/flatbuffers/src/namer.h
index 6a7fadcd14..097d4490bc 100644
--- a/contrib/libs/flatbuffers/src/namer.h
+++ b/contrib/libs/flatbuffers/src/namer.h
@@ -185,15 +185,19 @@ class Namer {
// right seperator. Output path prefixing and the trailing separator may be
// skiped using `skips`.
// Callers may want to use `EnsureDirExists` with the result.
+ // input_case is used to tell how to modify namespace. e.g. kUpperCamel will
+ // add a underscode between case changes, so MyGame turns into My_Game
+ // (depending also on the output_case).
virtual std::string Directories(const std::vector<std::string> &directories,
- SkipDir skips = SkipDir::None) const {
+ SkipDir skips = SkipDir::None,
+ Case input_case = Case::kUpperCamel) const {
const bool skip_output_path =
(skips & SkipDir::OutputPath) != SkipDir::None;
const bool skip_trailing_seperator =
(skips & SkipDir::TrailingPathSeperator) != SkipDir::None;
std::string result = skip_output_path ? "" : config_.output_path;
for (auto d = directories.begin(); d != directories.end(); d++) {
- result += ConvertCase(*d, config_.directories, Case::kUpperCamel);
+ result += ConvertCase(*d, config_.directories, input_case);
result.push_back(kPathSeparator);
}
if (skip_trailing_seperator && !result.empty()) result.pop_back();
diff --git a/contrib/libs/flatbuffers/src/util.cpp b/contrib/libs/flatbuffers/src/util.cpp
index b201246fd7..2d45ee7a0d 100644
--- a/contrib/libs/flatbuffers/src/util.cpp
+++ b/contrib/libs/flatbuffers/src/util.cpp
@@ -336,6 +336,10 @@ void EnsureDirExists(const std::string &filepath) {
// clang-format on
}
+std::string FilePath(const std::string& project, const std::string& filePath, bool absolute) {
+ return (absolute) ? AbsolutePath(filePath) : RelativeToRootPath(project, filePath);
+}
+
std::string AbsolutePath(const std::string &filepath) {
// clang-format off
diff --git a/contrib/libs/flatbuffers/ya.make b/contrib/libs/flatbuffers/ya.make
index 094f7325e5..f4effd0477 100644
--- a/contrib/libs/flatbuffers/ya.make
+++ b/contrib/libs/flatbuffers/ya.make
@@ -6,9 +6,9 @@ LICENSE(Apache-2.0)
LICENSE_TEXTS(.yandex_meta/licenses.list.txt)
-VERSION(23.5.26)
+VERSION(24.3.7)
-ORIGINAL_SOURCE(https://github.com/google/flatbuffers/archive/v23.5.26.tar.gz)
+ORIGINAL_SOURCE(https://github.com/google/flatbuffers/archive/v24.3.7.tar.gz)
PEERDIR(
contrib/restricted/abseil-cpp/absl/base