Use the Google Style for clang-format without exceptions (#8706)

This reduces the friction when merging from github and google repos by
using the exact same clang style guide.

MARKDOWN=true
This commit is contained in:
Derek Bailey
2025-09-23 21:19:33 -07:00
committed by GitHub
parent 881eaab706
commit 0e047869da
84 changed files with 8178 additions and 6653 deletions

View File

@@ -1,13 +1,5 @@
--- ---
Language: Cpp Language: Cpp
BasedOnStyle: Google BasedOnStyle: Google
DerivePointerAlignment: false
PointerAlignment: Right
IndentPPDirectives: AfterHash
Cpp11BracedListStyle: false
AlwaysBreakTemplateDeclarations: false
AllowShortCaseLabelsOnASingleLine: true
SpaceAfterTemplateKeyword: false
AllowShortBlocksOnASingleLine: true
... ...

View File

@@ -2,6 +2,10 @@
// swiftlint:disable all // swiftlint:disable all
// swiftformat:disable all // swiftformat:disable all
#if canImport(Common)
import Common
#endif
import FlatBuffers import FlatBuffers
public struct flatbuffers_goldens_Galaxy: FlatBufferObject, Verifiable { public struct flatbuffers_goldens_Galaxy: FlatBufferObject, Verifiable {

View File

@@ -98,7 +98,8 @@ void RunServer() {
server_instance->Wait(); server_instance->Wait();
} }
template<class Builder> void StoreRPC(MonsterStorage::Stub *stub) { template <class Builder>
void StoreRPC(MonsterStorage::Stub* stub) {
Builder fbb; Builder fbb;
grpc::ClientContext context; grpc::ClientContext context;
// Build a request with the name set. // Build a request with the name set.
@@ -119,7 +120,8 @@ template<class Builder> void StoreRPC(MonsterStorage::Stub *stub) {
} }
} }
template<class Builder> void RetrieveRPC(MonsterStorage::Stub *stub) { template <class Builder>
void RetrieveRPC(MonsterStorage::Stub* stub) {
Builder fbb; Builder fbb;
grpc::ClientContext context; grpc::ClientContext context;
fbb.Clear(); fbb.Clear();

View File

@@ -21,13 +21,13 @@ static_assert(std::is_member_function_pointer<
std::function<void(::grpc::Status)>)>( std::function<void(::grpc::Status)>)>(
&Stub::async_Store))>::value, &Stub::async_Store))>::value,
"Function-form unary async_Store missing"); "Function-form unary async_Store missing");
static_assert(std::is_member_function_pointer< static_assert(
std::is_member_function_pointer<
decltype(static_cast<void (Stub::*)( decltype(static_cast<void (Stub::*)(
::grpc::ClientContext*, ::grpc::ClientContext*,
const flatbuffers::grpc::Message<Monster>&, const flatbuffers::grpc::Message<Monster>&,
flatbuffers::grpc::Message<Stat>*, flatbuffers::grpc::Message<Stat>*,
::grpc::ClientUnaryReactor *)>( ::grpc::ClientUnaryReactor*)>(&Stub::async_Store))>::value,
&Stub::async_Store))>::value,
"Reactor-form unary async_Store missing"); "Reactor-form unary async_Store missing");
// Streaming reactor entry points // Streaming reactor entry points
@@ -42,8 +42,7 @@ static_assert(
static_assert( static_assert(
std::is_member_function_pointer< std::is_member_function_pointer<
decltype(static_cast<void (Stub::*)( decltype(static_cast<void (Stub::*)(
::grpc::ClientContext *, ::grpc::ClientContext*, flatbuffers::grpc::Message<Stat>*,
flatbuffers::grpc::Message<Stat> *,
::grpc::ClientWriteReactor<flatbuffers::grpc::Message< ::grpc::ClientWriteReactor<flatbuffers::grpc::Message<
Monster> >*)>(&Stub::async_GetMaxHitPoint))>::value, Monster> >*)>(&Stub::async_GetMaxHitPoint))>::value,
"Client streaming reactor async_GetMaxHitPoint missing"); "Client streaming reactor async_GetMaxHitPoint missing");

View File

@@ -45,7 +45,9 @@ template<class SrcBuilder>
struct BuilderReuseTests<flatbuffers::grpc::MessageBuilder, SrcBuilder> { struct BuilderReuseTests<flatbuffers::grpc::MessageBuilder, SrcBuilder> {
static void builder_reusable_after_release_message_test( static void builder_reusable_after_release_message_test(
TestSelector selector) { TestSelector selector) {
if (!selector.count(REUSABLE_AFTER_RELEASE_MESSAGE)) { return; } if (!selector.count(REUSABLE_AFTER_RELEASE_MESSAGE)) {
return;
}
flatbuffers::grpc::MessageBuilder mb; flatbuffers::grpc::MessageBuilder mb;
std::vector<flatbuffers::grpc::Message<Monster>> buffers; std::vector<flatbuffers::grpc::Message<Monster>> buffers;
@@ -58,7 +60,9 @@ struct BuilderReuseTests<flatbuffers::grpc::MessageBuilder, SrcBuilder> {
} }
static void builder_reusable_after_release_test(TestSelector selector) { static void builder_reusable_after_release_test(TestSelector selector) {
if (!selector.count(REUSABLE_AFTER_RELEASE)) { return; } if (!selector.count(REUSABLE_AFTER_RELEASE)) {
return;
}
// FIXME: Populate-Release loop fails assert(GRPC_SLICE_IS_EMPTY(slice_)) in // FIXME: Populate-Release loop fails assert(GRPC_SLICE_IS_EMPTY(slice_)) in
// SliceAllocator::allocate in the second iteration. // SliceAllocator::allocate in the second iteration.
@@ -74,7 +78,9 @@ struct BuilderReuseTests<flatbuffers::grpc::MessageBuilder, SrcBuilder> {
} }
static void builder_reusable_after_releaseraw_test(TestSelector selector) { static void builder_reusable_after_releaseraw_test(TestSelector selector) {
if (!selector.count(REUSABLE_AFTER_RELEASE_RAW)) { return; } if (!selector.count(REUSABLE_AFTER_RELEASE_RAW)) {
return;
}
flatbuffers::grpc::MessageBuilder mb; flatbuffers::grpc::MessageBuilder mb;
for (int i = 0; i < 5; ++i) { for (int i = 0; i < 5; ++i) {
@@ -89,7 +95,9 @@ struct BuilderReuseTests<flatbuffers::grpc::MessageBuilder, SrcBuilder> {
static void builder_reusable_after_release_and_move_assign_test( static void builder_reusable_after_release_and_move_assign_test(
TestSelector selector) { TestSelector selector) {
if (!selector.count(REUSABLE_AFTER_RELEASE_AND_MOVE_ASSIGN)) { return; } if (!selector.count(REUSABLE_AFTER_RELEASE_AND_MOVE_ASSIGN)) {
return;
}
// FIXME: Release-move_assign loop fails assert(p == // FIXME: Release-move_assign loop fails assert(p ==
// GRPC_SLICE_START_PTR(slice_)) in DetachedBuffer destructor after all the // GRPC_SLICE_START_PTR(slice_)) in DetachedBuffer destructor after all the
@@ -137,7 +145,9 @@ struct BuilderReuseTests<flatbuffers::grpc::MessageBuilder, SrcBuilder> {
static void builder_reusable_after_releaseraw_and_move_assign_test( static void builder_reusable_after_releaseraw_and_move_assign_test(
TestSelector selector) { TestSelector selector) {
if (!selector.count(REUSABLE_AFTER_RELEASE_RAW_AND_MOVE_ASSIGN)) { return; } if (!selector.count(REUSABLE_AFTER_RELEASE_RAW_AND_MOVE_ASSIGN)) {
return;
}
flatbuffers::grpc::MessageBuilder dst; flatbuffers::grpc::MessageBuilder dst;
for (int i = 0; i < 5; ++i) { for (int i = 0; i < 5; ++i) {
@@ -358,8 +368,7 @@ void message_builder_tests() {
REUSABLE_AFTER_RELEASE_RAW, REUSABLE_AFTER_RELEASE_MESSAGE, REUSABLE_AFTER_RELEASE_RAW, REUSABLE_AFTER_RELEASE_MESSAGE,
REUSABLE_AFTER_RELEASE_MESSAGE_AND_MOVE_ASSIGN, REUSABLE_AFTER_RELEASE_MESSAGE_AND_MOVE_ASSIGN,
REUSABLE_AFTER_RELEASE_RAW_AND_MOVE_ASSIGN REUSABLE_AFTER_RELEASE_RAW_AND_MOVE_ASSIGN};
};
BuilderReuseTests<MessageBuilder, MessageBuilder>::run_tests( BuilderReuseTests<MessageBuilder, MessageBuilder>::run_tests(
TestSelector(tests, tests + 6)); TestSelector(tests, tests + 6));

View File

@@ -27,7 +27,8 @@
namespace flatbuffers { namespace flatbuffers {
// This is used as a helper type for accessing arrays. // This is used as a helper type for accessing arrays.
template<typename T, uint16_t length> class Array { template <typename T, uint16_t length>
class Array {
// Array<T> can carry only POD data types (scalars or structs). // Array<T> can carry only POD data types (scalars or structs).
typedef typename flatbuffers::bool_constant<flatbuffers::is_scalar<T>::value> typedef typename flatbuffers::bool_constant<flatbuffers::is_scalar<T>::value>
scalar_tag; scalar_tag;
@@ -55,7 +56,8 @@ template<typename T, uint16_t length> class Array {
// If this is a Vector of enums, T will be its storage type, not the enum // If this is a Vector of enums, T will be its storage type, not the enum
// type. This function makes it convenient to retrieve value with enum // type. This function makes it convenient to retrieve value with enum
// type E. // type E.
template<typename E> E GetEnum(uoffset_t i) const { template <typename E>
E GetEnum(uoffset_t i) const {
return static_cast<E>(Get(i)); return static_cast<E>(Get(i));
} }
@@ -131,7 +133,9 @@ template<typename T, uint16_t length> class Array {
// Copy data from flatbuffers::span with endian conversion. // Copy data from flatbuffers::span with endian conversion.
void CopyFromSpanImpl(flatbuffers::false_type, void CopyFromSpanImpl(flatbuffers::false_type,
flatbuffers::span<const T, length> src) { flatbuffers::span<const T, length> src) {
for (size_type k = 0; k < length; k++) { Mutate(k, src[k]); } for (size_type k = 0; k < length; k++) {
Mutate(k, src[k]);
}
} }
// This class is only used to access pre-existing data. Don't ever // This class is only used to access pre-existing data. Don't ever

View File

@@ -26,7 +26,8 @@ namespace flatbuffers {
// Wrapper for uoffset_t to allow safe template specialization. // Wrapper for uoffset_t to allow safe template specialization.
// Value is allowed to be 0 to indicate a null object (see e.g. AddOffset). // Value is allowed to be 0 to indicate a null object (see e.g. AddOffset).
template<typename T = void> struct Offset { template <typename T = void>
struct Offset {
// The type of offset to use. // The type of offset to use.
typedef uoffset_t offset_type; typedef uoffset_t offset_type;
@@ -37,12 +38,14 @@ template<typename T = void> struct Offset {
bool IsNull() const { return !o; } bool IsNull() const { return !o; }
}; };
template<typename T> struct is_specialisation_of_Offset : false_type {}; template <typename T>
struct is_specialisation_of_Offset : false_type {};
template <typename T> template <typename T>
struct is_specialisation_of_Offset<Offset<T>> : true_type {}; struct is_specialisation_of_Offset<Offset<T>> : true_type {};
// Wrapper for uoffset64_t Offsets. // Wrapper for uoffset64_t Offsets.
template<typename T = void> struct Offset64 { template <typename T = void>
struct Offset64 {
// The type of offset to use. // The type of offset to use.
typedef uoffset64_t offset_type; typedef uoffset64_t offset_type;
@@ -53,7 +56,8 @@ template<typename T = void> struct Offset64 {
bool IsNull() const { return !o; } bool IsNull() const { return !o; }
}; };
template<typename T> struct is_specialisation_of_Offset64 : false_type {}; template <typename T>
struct is_specialisation_of_Offset64 : false_type {};
template <typename T> template <typename T>
struct is_specialisation_of_Offset64<Offset64<T>> : true_type {}; struct is_specialisation_of_Offset64<Offset64<T>> : true_type {};
@@ -69,7 +73,8 @@ inline void EndianCheck() {
(void)endiantest; (void)endiantest;
} }
template<typename T> FLATBUFFERS_CONSTEXPR size_t AlignOf() { template <typename T>
FLATBUFFERS_CONSTEXPR size_t AlignOf() {
// clang-format off // clang-format off
#ifdef _MSC_VER #ifdef _MSC_VER
return __alignof(T); return __alignof(T);
@@ -99,7 +104,8 @@ static inline bool StringLessThan(const char *a_data, uoffset_t a_size,
// return type like this. // return type like this.
// The typedef is for the convenience of callers of this function // The typedef is for the convenience of callers of this function
// (avoiding the need for a trailing return decltype) // (avoiding the need for a trailing return decltype)
template<typename T, typename Enable = void> struct IndirectHelper { template <typename T, typename Enable = void>
struct IndirectHelper {
typedef T return_type; typedef T return_type;
typedef T mutable_return_type; typedef T mutable_return_type;
static const size_t element_stride = sizeof(T); static const size_t element_stride = sizeof(T);
@@ -191,11 +197,11 @@ inline bool BufferHasIdentifier(const void *buf, const char *identifier,
/// @cond FLATBUFFERS_INTERNAL /// @cond FLATBUFFERS_INTERNAL
// Helpers to get a typed pointer to the root object contained in the buffer. // Helpers to get a typed pointer to the root object contained in the buffer.
template<typename T> T *GetMutableRoot(void *buf) { template <typename T>
T* GetMutableRoot(void* buf) {
if (!buf) return nullptr; if (!buf) return nullptr;
EndianCheck(); EndianCheck();
return reinterpret_cast<T *>( return reinterpret_cast<T*>(reinterpret_cast<uint8_t*>(buf) +
reinterpret_cast<uint8_t *>(buf) +
EndianScalar(*reinterpret_cast<uoffset_t*>(buf))); EndianScalar(*reinterpret_cast<uoffset_t*>(buf)));
} }
@@ -204,7 +210,8 @@ T *GetMutableSizePrefixedRoot(void *buf) {
return GetMutableRoot<T>(reinterpret_cast<uint8_t*>(buf) + sizeof(SizeT)); return GetMutableRoot<T>(reinterpret_cast<uint8_t*>(buf) + sizeof(SizeT));
} }
template<typename T> const T *GetRoot(const void *buf) { template <typename T>
const T* GetRoot(const void* buf) {
return GetMutableRoot<T>(const_cast<void*>(buf)); return GetMutableRoot<T>(const_cast<void*>(buf));
} }

View File

@@ -27,7 +27,8 @@ namespace flatbuffers {
// A BufferRef does not own its buffer. // A BufferRef does not own its buffer.
struct BufferRefBase {}; // for std::is_base_of struct BufferRefBase {}; // for std::is_base_of
template<typename T> struct BufferRef : BufferRefBase { template <typename T>
struct BufferRef : BufferRefBase {
BufferRef() : buf(nullptr), len(0), must_free(false) {} BufferRef() : buf(nullptr), len(0), must_free(false) {}
BufferRef(uint8_t* _buf, uoffset_t _len) BufferRef(uint8_t* _buf, uoffset_t _len)
: buf(_buf), len(_len), must_free(false) {} : buf(_buf), len(_len), must_free(false) {}

View File

@@ -100,7 +100,9 @@ class DetachedBuffer {
inline void destroy() { inline void destroy() {
if (buf_) Deallocate(allocator_, buf_, reserved_); if (buf_) Deallocate(allocator_, buf_, reserved_);
if (own_allocator_ && allocator_) { delete allocator_; } if (own_allocator_ && allocator_) {
delete allocator_;
}
reset(); reset();
} }

View File

@@ -74,7 +74,8 @@ T *data(std::vector<T, Alloc> &v) {
/// `PushElement`/`AddElement`/`EndTable`, or the builtin `CreateString`/ /// `PushElement`/`AddElement`/`EndTable`, or the builtin `CreateString`/
/// `CreateVector` functions. Do this is depth-first order to build up a tree to /// `CreateVector` functions. Do this is depth-first order to build up a tree to
/// the root. `Finish()` wraps up the buffer ready for transport. /// the root. `Finish()` wraps up the buffer ready for transport.
template<bool Is64Aware = false> class FlatBufferBuilderImpl { template <bool Is64Aware = false>
class FlatBufferBuilderImpl {
public: public:
// This switches the size type of the builder, based on if its 64-bit aware // This switches the size type of the builder, based on if its 64-bit aware
// (uoffset64_t) or not (uoffset_t). // (uoffset64_t) or not (uoffset_t).
@@ -300,7 +301,8 @@ template<bool Is64Aware = false> class FlatBufferBuilderImpl {
void PopBytes(size_t amount) { buf_.pop(amount); } void PopBytes(size_t amount) { buf_.pop(amount); }
template<typename T> void AssertScalarT() { template <typename T>
void AssertScalarT() {
// The code assumes power of 2 sizes and endian-swap-ability. // The code assumes power of 2 sizes and endian-swap-ability.
static_assert(flatbuffers::is_scalar<T>::value, "T must be a scalar type"); static_assert(flatbuffers::is_scalar<T>::value, "T must be a scalar type");
} }
@@ -326,31 +328,38 @@ template<bool Is64Aware = false> class FlatBufferBuilderImpl {
FieldLoc fl = {off, field}; FieldLoc fl = {off, field};
buf_.scratch_push_small(fl); buf_.scratch_push_small(fl);
num_field_loc++; num_field_loc++;
if (field > max_voffset_) { max_voffset_ = field; } if (field > max_voffset_) {
max_voffset_ = field;
}
} }
// Like PushElement, but additionally tracks the field this represents. // Like PushElement, but additionally tracks the field this represents.
template<typename T> void AddElement(voffset_t field, T e, T def) { template <typename T>
void AddElement(voffset_t field, T e, T def) {
// We don't serialize values equal to the default. // We don't serialize values equal to the default.
if (IsTheSameAs(e, def) && !force_defaults_) return; if (IsTheSameAs(e, def) && !force_defaults_) return;
TrackField(field, PushElement(e)); TrackField(field, PushElement(e));
} }
template<typename T> void AddElement(voffset_t field, T e) { template <typename T>
void AddElement(voffset_t field, T e) {
TrackField(field, PushElement(e)); TrackField(field, PushElement(e));
} }
template<typename T> void AddOffset(voffset_t field, Offset<T> off) { template <typename T>
void AddOffset(voffset_t field, Offset<T> off) {
if (off.IsNull()) return; // Don't store. if (off.IsNull()) return; // Don't store.
AddElement(field, ReferTo(off.o), static_cast<uoffset_t>(0)); AddElement(field, ReferTo(off.o), static_cast<uoffset_t>(0));
} }
template<typename T> void AddOffset(voffset_t field, Offset64<T> off) { template <typename T>
void AddOffset(voffset_t field, Offset64<T> off) {
if (off.IsNull()) return; // Don't store. if (off.IsNull()) return; // Don't store.
AddElement(field, ReferTo(off.o), static_cast<uoffset64_t>(0)); AddElement(field, ReferTo(off.o), static_cast<uoffset64_t>(0));
} }
template<typename T> void AddStruct(voffset_t field, const T *structptr) { template <typename T>
void AddStruct(voffset_t field, const T* structptr) {
if (!structptr) return; // Default, don't store. if (!structptr) return; // Default, don't store.
Align(AlignOf<T>()); Align(AlignOf<T>());
buf_.push_small(*structptr); buf_.push_small(*structptr);
@@ -380,12 +389,14 @@ template<bool Is64Aware = false> class FlatBufferBuilderImpl {
return ReferTo(off, GetSize()); return ReferTo(off, GetSize());
} }
template<typename T, typename T2> T ReferTo(const T off, const T2 size) { template <typename T, typename T2>
T ReferTo(const T off, const T2 size) {
FLATBUFFERS_ASSERT(off && off <= size); FLATBUFFERS_ASSERT(off && off <= size);
return size - off + static_cast<T>(sizeof(T)); return size - off + static_cast<T>(sizeof(T));
} }
template<typename T> T ReferTo(const T off, const T size) { template <typename T>
T ReferTo(const T off, const T size) {
FLATBUFFERS_ASSERT(off && off <= size); FLATBUFFERS_ASSERT(off && off <= size);
return size - off + static_cast<T>(sizeof(T)); return size - off + static_cast<T>(sizeof(T));
} }
@@ -490,7 +501,8 @@ template<bool Is64Aware = false> class FlatBufferBuilderImpl {
// This checks a required field has been set in a given table that has // This checks a required field has been set in a given table that has
// just been constructed. // just been constructed.
template<typename T> void Required(Offset<T> table, voffset_t field) { template <typename T>
void Required(Offset<T> table, voffset_t field) {
auto table_ptr = reinterpret_cast<const Table*>(buf_.data_at(table.o)); auto table_ptr = reinterpret_cast<const Table*>(buf_.data_at(table.o));
bool ok = table_ptr->GetOptionalFieldOffset(field) != 0; bool ok = table_ptr->GetOptionalFieldOffset(field) != 0;
// If this fails, the caller will show what field needs to be set. // If this fails, the caller will show what field needs to be set.
@@ -521,7 +533,8 @@ template<bool Is64Aware = false> class FlatBufferBuilderImpl {
// Aligns such than when "len" bytes are written, an object of type `AlignT` // Aligns such than when "len" bytes are written, an object of type `AlignT`
// can be written after it (forward in the buffer) without padding. // can be written after it (forward in the buffer) without padding.
template<typename AlignT> void PreAlign(size_t len) { template <typename AlignT>
void PreAlign(size_t len) {
AssertScalarT<AlignT>(); AssertScalarT<AlignT>();
PreAlign(len, AlignOf<AlignT>()); PreAlign(len, AlignOf<AlignT>());
} }
@@ -673,7 +686,8 @@ template<bool Is64Aware = false> class FlatBufferBuilderImpl {
return PushElement<LenT, ReturnT>(static_cast<LenT>(len)); return PushElement<LenT, ReturnT>(static_cast<LenT>(len));
} }
template<template<typename> class OffsetT = Offset, typename LenT = uint32_t> template <template <typename> class OffsetT = Offset,
typename LenT = uint32_t>
void StartVector(size_t len, size_t elemsize, size_t alignment) { void StartVector(size_t len, size_t elemsize, size_t alignment) {
NotNested(); NotNested();
nested = true; nested = true;
@@ -768,7 +782,8 @@ template<bool Is64Aware = false> class FlatBufferBuilderImpl {
/// serialize into the buffer as a `vector`. /// serialize into the buffer as a `vector`.
/// @return Returns a typed `Offset` into the serialized data indicating /// @return Returns a typed `Offset` into the serialized data indicating
/// where the vector is stored. /// where the vector is stored.
template<typename T, class C> Offset<Vector<T>> CreateVector(const C &array) { template <typename T, class C>
Offset<Vector<T>> CreateVector(const C& array) {
return CreateVector(array.data(), array.size()); return CreateVector(array.data(), array.size());
} }
@@ -785,7 +800,9 @@ template<bool Is64Aware = false> class FlatBufferBuilderImpl {
template <typename T> template <typename T>
Offset<Vector<Offset<T>>> CreateVector(const Offset<T>* v, size_t len) { Offset<Vector<Offset<T>>> CreateVector(const Offset<T>* v, size_t len) {
StartVector<Offset<T>>(len); StartVector<Offset<T>>(len);
for (auto i = len; i > 0;) { PushElement(v[--i]); } for (auto i = len; i > 0;) {
PushElement(v[--i]);
}
return Offset<Vector<Offset<T>>>(EndVector(len)); return Offset<Vector<Offset<T>>>(EndVector(len));
} }
@@ -971,9 +988,9 @@ template<bool Is64Aware = false> class FlatBufferBuilderImpl {
return CreateVectorOfStructs<T, OffsetT, VectorT>(data(v), v.size()); return CreateVectorOfStructs<T, OffsetT, VectorT>(data(v), v.size());
} }
template<template<typename...> class VectorT = Vector64, int &..., typename T> template <template <typename...> class VectorT = Vector64, int&...,
Offset64<VectorT<const T *>> CreateVectorOfStructs64( typename T>
const std::vector<T> &v) { Offset64<VectorT<const T*>> CreateVectorOfStructs64(const std::vector<T>& v) {
return CreateVectorOfStructs<T, Offset64, VectorT>(data(v), v.size()); return CreateVectorOfStructs<T, Offset64, VectorT>(data(v), v.size());
} }
@@ -992,7 +1009,9 @@ template<bool Is64Aware = false> class FlatBufferBuilderImpl {
const S* v, size_t len, T (*const pack_func)(const S&)) { const S* v, size_t len, T (*const pack_func)(const S&)) {
FLATBUFFERS_ASSERT(pack_func); FLATBUFFERS_ASSERT(pack_func);
auto structs = StartVectorOfStructs<T>(len); auto structs = StartVectorOfStructs<T>(len);
for (size_t i = 0; i < len; i++) { structs[i] = pack_func(v[i]); } for (size_t i = 0; i < len; i++) {
structs[i] = pack_func(v[i]);
}
return EndVectorOfStructs<T>(len); return EndVectorOfStructs<T>(len);
} }
@@ -1005,8 +1024,7 @@ template<bool Is64Aware = false> class FlatBufferBuilderImpl {
/// @return Returns a typed `Offset` into the serialized data indicating /// @return Returns a typed `Offset` into the serialized data indicating
/// where the vector is stored. /// where the vector is stored.
template <typename T, typename S> template <typename T, typename S>
Offset<Vector<const T *>> CreateVectorOfNativeStructs(const S *v, Offset<Vector<const T*>> CreateVectorOfNativeStructs(const S* v, size_t len) {
size_t len) {
extern T Pack(const S&); extern T Pack(const S&);
return CreateVectorOfNativeStructs(v, len, Pack); return CreateVectorOfNativeStructs(v, len, Pack);
} }
@@ -1042,7 +1060,8 @@ template<bool Is64Aware = false> class FlatBufferBuilderImpl {
} }
/// @cond FLATBUFFERS_INTERNAL /// @cond FLATBUFFERS_INTERNAL
template<typename T> struct StructKeyComparator { template <typename T>
struct StructKeyComparator {
bool operator()(const T& a, const T& b) const { bool operator()(const T& a, const T& b) const {
return a.KeyCompareLessThan(&b); return a.KeyCompareLessThan(&b);
} }
@@ -1100,17 +1119,19 @@ template<bool Is64Aware = false> class FlatBufferBuilderImpl {
/// @return Returns a typed `Offset` into the serialized data indicating /// @return Returns a typed `Offset` into the serialized data indicating
/// where the vector is stored. /// where the vector is stored.
template <typename T, typename S> template <typename T, typename S>
Offset<Vector<const T *>> CreateVectorOfSortedNativeStructs(S *v, Offset<Vector<const T*>> CreateVectorOfSortedNativeStructs(S* v, size_t len) {
size_t len) {
extern T Pack(const S&); extern T Pack(const S&);
auto structs = StartVectorOfStructs<T>(len); auto structs = StartVectorOfStructs<T>(len);
for (size_t i = 0; i < len; i++) { structs[i] = Pack(v[i]); } for (size_t i = 0; i < len; i++) {
structs[i] = Pack(v[i]);
}
std::stable_sort(structs, structs + len, StructKeyComparator<T>()); std::stable_sort(structs, structs + len, StructKeyComparator<T>());
return EndVectorOfStructs<T>(len); return EndVectorOfStructs<T>(len);
} }
/// @cond FLATBUFFERS_INTERNAL /// @cond FLATBUFFERS_INTERNAL
template<typename T> struct TableKeyComparator { template <typename T>
struct TableKeyComparator {
explicit TableKeyComparator(vector_downward<SizeT>& buf) : buf_(buf) {} explicit TableKeyComparator(vector_downward<SizeT>& buf) : buf_(buf) {}
TableKeyComparator(const TableKeyComparator& other) : buf_(other.buf_) {} TableKeyComparator(const TableKeyComparator& other) : buf_(other.buf_) {}
bool operator()(const Offset<T>& a, const Offset<T>& b) const { bool operator()(const Offset<T>& a, const Offset<T>& b) const {
@@ -1208,12 +1229,15 @@ template<bool Is64Aware = false> class FlatBufferBuilderImpl {
AssertScalarT<T>(); AssertScalarT<T>();
AssertScalarT<U>(); AssertScalarT<U>();
StartVector<T>(len); StartVector<T>(len);
for (auto i = len; i > 0;) { PushElement(static_cast<T>(v[--i])); } for (auto i = len; i > 0;) {
PushElement(static_cast<T>(v[--i]));
}
return Offset<Vector<T>>(EndVector(len)); return Offset<Vector<T>>(EndVector(len));
} }
/// @brief Write a struct by itself, typically to be part of a union. /// @brief Write a struct by itself, typically to be part of a union.
template<typename T> Offset<const T *> CreateStruct(const T &structobj) { template <typename T>
Offset<const T*> CreateStruct(const T& structobj) {
NotNested(); NotNested();
Align(AlignOf<T>()); Align(AlignOf<T>());
buf_.push_small(structobj); buf_.push_small(structobj);
@@ -1278,7 +1302,9 @@ template<bool Is64Aware = false> class FlatBufferBuilderImpl {
kFileIdentifierLength); kFileIdentifierLength);
} }
PushElement(ReferTo(root)); // Location of root. PushElement(ReferTo(root)); // Location of root.
if (size_prefix) { PushElement(GetSize()); } if (size_prefix) {
PushElement(GetSize());
}
finished = true; finished = true;
} }
@@ -1441,7 +1467,8 @@ inline Offset64<String> FlatBufferBuilder64::CreateString(const char *str,
} }
// Used to distinguish from real Offsets. // Used to distinguish from real Offsets.
template<typename T = void> struct EmptyOffset {}; template <typename T = void>
struct EmptyOffset {};
// TODO(derekbailey): it would be nice to combine these two methods. // TODO(derekbailey): it would be nice to combine these two methods.
template <> template <>

View File

@@ -104,11 +104,17 @@ inline bool IsFixedTypedVector(Type t) {
inline Type ToTypedVector(Type t, size_t fixed_len = 0) { inline Type ToTypedVector(Type t, size_t fixed_len = 0) {
FLATBUFFERS_ASSERT(IsTypedVectorElementType(t)); FLATBUFFERS_ASSERT(IsTypedVectorElementType(t));
switch (fixed_len) { switch (fixed_len) {
case 0: return static_cast<Type>(t - FBT_INT + FBT_VECTOR_INT); case 0:
case 2: return static_cast<Type>(t - FBT_INT + FBT_VECTOR_INT2); return static_cast<Type>(t - FBT_INT + FBT_VECTOR_INT);
case 3: return static_cast<Type>(t - FBT_INT + FBT_VECTOR_INT3); case 2:
case 4: return static_cast<Type>(t - FBT_INT + FBT_VECTOR_INT4); return static_cast<Type>(t - FBT_INT + FBT_VECTOR_INT2);
default: FLATBUFFERS_ASSERT(0); return FBT_NULL; case 3:
return static_cast<Type>(t - FBT_INT + FBT_VECTOR_INT3);
case 4:
return static_cast<Type>(t - FBT_INT + FBT_VECTOR_INT4);
default:
FLATBUFFERS_ASSERT(0);
return FBT_NULL;
} }
} }
@@ -181,7 +187,8 @@ inline const uint8_t *Indirect(const uint8_t *offset, uint8_t byte_width) {
return offset - ReadUInt64(offset, byte_width); return offset - ReadUInt64(offset, byte_width);
} }
template<typename T> const uint8_t *Indirect(const uint8_t *offset) { template <typename T>
const uint8_t* Indirect(const uint8_t* offset) {
return offset - flatbuffers::ReadScalar<T>(offset); return offset - flatbuffers::ReadScalar<T>(offset);
} }
@@ -377,8 +384,8 @@ void AppendToString(std::string &s, T &&v, bool keys_quoted, bool indented,
s += indented ? "\n" : " "; s += indented ? "\n" : " ";
} }
if (indented) IndentString(s, cur_indent, indent_string); if (indented) IndentString(s, cur_indent, indent_string);
v[i].ToString(true, keys_quoted, s, indented, cur_indent, v[i].ToString(true, keys_quoted, s, indented, cur_indent, indent_string,
indent_string, natural_utf8); natural_utf8);
} }
if (indented) { if (indented) {
s += "\n"; s += "\n";
@@ -394,7 +401,6 @@ void AppendToString(std::string &s, T &&v, bool keys_quoted) {
AppendToString(s, v, keys_quoted); AppendToString(s, v, keys_quoted);
} }
class Reference { class Reference {
public: public:
Reference() Reference()
@@ -453,17 +459,24 @@ class Reference {
return ReadInt64(data_, parent_width_); return ReadInt64(data_, parent_width_);
} else } else
switch (type_) { switch (type_) {
case FBT_INDIRECT_INT: return ReadInt64(Indirect(), byte_width_); case FBT_INDIRECT_INT:
case FBT_UINT: return ReadUInt64(data_, parent_width_); return ReadInt64(Indirect(), byte_width_);
case FBT_INDIRECT_UINT: return ReadUInt64(Indirect(), byte_width_); case FBT_UINT:
return ReadUInt64(data_, parent_width_);
case FBT_INDIRECT_UINT:
return ReadUInt64(Indirect(), byte_width_);
case FBT_FLOAT: case FBT_FLOAT:
return static_cast<int64_t>(ReadDouble(data_, parent_width_)); return static_cast<int64_t>(ReadDouble(data_, parent_width_));
case FBT_INDIRECT_FLOAT: case FBT_INDIRECT_FLOAT:
return static_cast<int64_t>(ReadDouble(Indirect(), byte_width_)); return static_cast<int64_t>(ReadDouble(Indirect(), byte_width_));
case FBT_NULL: return 0; case FBT_NULL:
case FBT_STRING: return flatbuffers::StringToInt(AsString().c_str()); return 0;
case FBT_VECTOR: return static_cast<int64_t>(AsVector().size()); case FBT_STRING:
case FBT_BOOL: return ReadInt64(data_, parent_width_); return flatbuffers::StringToInt(AsString().c_str());
case FBT_VECTOR:
return static_cast<int64_t>(AsVector().size());
case FBT_BOOL:
return ReadInt64(data_, parent_width_);
default: default:
// Convert other things to int. // Convert other things to int.
return 0; return 0;
@@ -482,17 +495,24 @@ class Reference {
return ReadUInt64(data_, parent_width_); return ReadUInt64(data_, parent_width_);
} else } else
switch (type_) { switch (type_) {
case FBT_INDIRECT_UINT: return ReadUInt64(Indirect(), byte_width_); case FBT_INDIRECT_UINT:
case FBT_INT: return ReadInt64(data_, parent_width_); return ReadUInt64(Indirect(), byte_width_);
case FBT_INDIRECT_INT: return ReadInt64(Indirect(), byte_width_); case FBT_INT:
return ReadInt64(data_, parent_width_);
case FBT_INDIRECT_INT:
return ReadInt64(Indirect(), byte_width_);
case FBT_FLOAT: case FBT_FLOAT:
return static_cast<uint64_t>(ReadDouble(data_, parent_width_)); return static_cast<uint64_t>(ReadDouble(data_, parent_width_));
case FBT_INDIRECT_FLOAT: case FBT_INDIRECT_FLOAT:
return static_cast<uint64_t>(ReadDouble(Indirect(), byte_width_)); return static_cast<uint64_t>(ReadDouble(Indirect(), byte_width_));
case FBT_NULL: return 0; case FBT_NULL:
case FBT_STRING: return flatbuffers::StringToUInt(AsString().c_str()); return 0;
case FBT_VECTOR: return static_cast<uint64_t>(AsVector().size()); case FBT_STRING:
case FBT_BOOL: return ReadUInt64(data_, parent_width_); return flatbuffers::StringToUInt(AsString().c_str());
case FBT_VECTOR:
return static_cast<uint64_t>(AsVector().size());
case FBT_BOOL:
return ReadUInt64(data_, parent_width_);
default: default:
// Convert other things to uint. // Convert other things to uint.
return 0; return 0;
@@ -509,7 +529,8 @@ class Reference {
return ReadDouble(data_, parent_width_); return ReadDouble(data_, parent_width_);
} else } else
switch (type_) { switch (type_) {
case FBT_INDIRECT_FLOAT: return ReadDouble(Indirect(), byte_width_); case FBT_INDIRECT_FLOAT:
return ReadDouble(Indirect(), byte_width_);
case FBT_INT: case FBT_INT:
return static_cast<double>(ReadInt64(data_, parent_width_)); return static_cast<double>(ReadInt64(data_, parent_width_));
case FBT_UINT: case FBT_UINT:
@@ -518,13 +539,15 @@ class Reference {
return static_cast<double>(ReadInt64(Indirect(), byte_width_)); return static_cast<double>(ReadInt64(Indirect(), byte_width_));
case FBT_INDIRECT_UINT: case FBT_INDIRECT_UINT:
return static_cast<double>(ReadUInt64(Indirect(), byte_width_)); return static_cast<double>(ReadUInt64(Indirect(), byte_width_));
case FBT_NULL: return 0.0; case FBT_NULL:
return 0.0;
case FBT_STRING: { case FBT_STRING: {
double d; double d;
flatbuffers::StringToNumber(AsString().c_str(), &d); flatbuffers::StringToNumber(AsString().c_str(), &d);
return d; return d;
} }
case FBT_VECTOR: return static_cast<double>(AsVector().size()); case FBT_VECTOR:
return static_cast<double>(AsVector().size());
case FBT_BOOL: case FBT_BOOL:
return static_cast<double>(ReadUInt64(data_, parent_width_)); return static_cast<double>(ReadUInt64(data_, parent_width_));
default: default:
@@ -578,7 +601,8 @@ class Reference {
if (type_ == FBT_STRING) { if (type_ == FBT_STRING) {
String str(Indirect(), byte_width_); String str(Indirect(), byte_width_);
if (strings_quoted) { if (strings_quoted) {
flatbuffers::EscapeString(str.c_str(), str.length(), &s, true, natural_utf8); flatbuffers::EscapeString(str.c_str(), str.length(), &s, true,
natural_utf8);
} else { } else {
s.append(str.c_str(), str.length()); s.append(str.c_str(), str.length());
} }
@@ -625,8 +649,8 @@ class Reference {
if (indented) IndentString(s, cur_indent + 1, indent_string); if (indented) IndentString(s, cur_indent + 1, indent_string);
keys[i].ToString(true, kq, s); keys[i].ToString(true, kq, s);
s += ": "; s += ": ";
vals[i].ToString(true, keys_quoted, s, indented, cur_indent + 1, indent_string, vals[i].ToString(true, keys_quoted, s, indented, cur_indent + 1,
natural_utf8); indent_string, natural_utf8);
if (i < keys.size() - 1) { if (i < keys.size() - 1) {
s += ","; s += ",";
if (!indented) s += " "; if (!indented) s += " ";
@@ -641,8 +665,7 @@ class Reference {
cur_indent + 1, indent_string, natural_utf8); cur_indent + 1, indent_string, natural_utf8);
} else if (IsTypedVector()) { } else if (IsTypedVector()) {
AppendToString<TypedVector>(s, AsTypedVector(), keys_quoted, indented, AppendToString<TypedVector>(s, AsTypedVector(), keys_quoted, indented,
cur_indent + 1, indent_string, cur_indent + 1, indent_string, natural_utf8);
natural_utf8);
} else if (IsFixedTypedVector()) { } else if (IsFixedTypedVector()) {
AppendToString<FixedTypedVector>(s, AsFixedTypedVector(), keys_quoted, AppendToString<FixedTypedVector>(s, AsFixedTypedVector(), keys_quoted,
indented, cur_indent + 1, indent_string, indented, cur_indent + 1, indent_string,
@@ -713,7 +736,8 @@ class Reference {
} }
} }
template<typename T> T As() const; template <typename T>
T As() const;
// Experimental: Mutation functions. // Experimental: Mutation functions.
// These allow scalars in an already created buffer to be updated in-place. // These allow scalars in an already created buffer to be updated in-place.
@@ -828,41 +852,83 @@ class Reference {
}; };
// Template specialization for As(). // Template specialization for As().
template<> inline bool Reference::As<bool>() const { return AsBool(); } template <>
inline bool Reference::As<bool>() const {
return AsBool();
}
template<> inline int8_t Reference::As<int8_t>() const { return AsInt8(); } template <>
template<> inline int16_t Reference::As<int16_t>() const { return AsInt16(); } inline int8_t Reference::As<int8_t>() const {
template<> inline int32_t Reference::As<int32_t>() const { return AsInt32(); } return AsInt8();
template<> inline int64_t Reference::As<int64_t>() const { return AsInt64(); } }
template <>
inline int16_t Reference::As<int16_t>() const {
return AsInt16();
}
template <>
inline int32_t Reference::As<int32_t>() const {
return AsInt32();
}
template <>
inline int64_t Reference::As<int64_t>() const {
return AsInt64();
}
template<> inline uint8_t Reference::As<uint8_t>() const { return AsUInt8(); } template <>
template<> inline uint16_t Reference::As<uint16_t>() const { inline uint8_t Reference::As<uint8_t>() const {
return AsUInt8();
}
template <>
inline uint16_t Reference::As<uint16_t>() const {
return AsUInt16(); return AsUInt16();
} }
template<> inline uint32_t Reference::As<uint32_t>() const { template <>
inline uint32_t Reference::As<uint32_t>() const {
return AsUInt32(); return AsUInt32();
} }
template<> inline uint64_t Reference::As<uint64_t>() const { template <>
inline uint64_t Reference::As<uint64_t>() const {
return AsUInt64(); return AsUInt64();
} }
template<> inline double Reference::As<double>() const { return AsDouble(); } template <>
template<> inline float Reference::As<float>() const { return AsFloat(); } inline double Reference::As<double>() const {
return AsDouble();
}
template <>
inline float Reference::As<float>() const {
return AsFloat();
}
template<> inline String Reference::As<String>() const { return AsString(); } template <>
template<> inline std::string Reference::As<std::string>() const { inline String Reference::As<String>() const {
return AsString();
}
template <>
inline std::string Reference::As<std::string>() const {
return AsString().str(); return AsString().str();
} }
template<> inline Blob Reference::As<Blob>() const { return AsBlob(); } template <>
template<> inline Vector Reference::As<Vector>() const { return AsVector(); } inline Blob Reference::As<Blob>() const {
template<> inline TypedVector Reference::As<TypedVector>() const { return AsBlob();
}
template <>
inline Vector Reference::As<Vector>() const {
return AsVector();
}
template <>
inline TypedVector Reference::As<TypedVector>() const {
return AsTypedVector(); return AsTypedVector();
} }
template<> inline FixedTypedVector Reference::As<FixedTypedVector>() const { template <>
inline FixedTypedVector Reference::As<FixedTypedVector>() const {
return AsFixedTypedVector(); return AsFixedTypedVector();
} }
template<> inline Map Reference::As<Map>() const { return AsMap(); } template <>
inline Map Reference::As<Map>() const {
return AsMap();
}
inline uint8_t PackedType(BitWidth bit_width, Type type) { inline uint8_t PackedType(BitWidth bit_width, Type type) {
return static_cast<uint8_t>(bit_width | (type << 2)); return static_cast<uint8_t>(bit_width | (type << 2));
@@ -898,7 +964,8 @@ inline Reference FixedTypedVector::operator[](size_t i) const {
return Reference(elem, byte_width_, 1, type_); return Reference(elem, byte_width_, 1, type_);
} }
template<typename T> int KeyCompare(const void *key, const void *elem) { template <typename T>
int KeyCompare(const void* key, const void* elem) {
auto str_elem = reinterpret_cast<const char*>( auto str_elem = reinterpret_cast<const char*>(
Indirect<T>(reinterpret_cast<const uint8_t*>(elem))); Indirect<T>(reinterpret_cast<const uint8_t*>(elem)));
auto skey = reinterpret_cast<const char*>(key); auto skey = reinterpret_cast<const char*>(key);
@@ -911,11 +978,21 @@ inline Reference Map::operator[](const char *key) const {
// to pick the right one ahead of time. // to pick the right one ahead of time.
int (*comp)(const void*, const void*) = nullptr; int (*comp)(const void*, const void*) = nullptr;
switch (keys.byte_width_) { switch (keys.byte_width_) {
case 1: comp = KeyCompare<uint8_t>; break; case 1:
case 2: comp = KeyCompare<uint16_t>; break; comp = KeyCompare<uint8_t>;
case 4: comp = KeyCompare<uint32_t>; break; break;
case 8: comp = KeyCompare<uint64_t>; break; case 2:
default: FLATBUFFERS_ASSERT(false); return Reference(); comp = KeyCompare<uint16_t>;
break;
case 4:
comp = KeyCompare<uint32_t>;
break;
case 8:
comp = KeyCompare<uint64_t>;
break;
default:
FLATBUFFERS_ASSERT(false);
return Reference();
} }
auto res = std::bsearch(key, keys.data_, keys.size(), keys.byte_width_, comp); auto res = std::bsearch(key, keys.data_, keys.size(), keys.byte_width_, comp);
if (!res) return Reference(nullptr, 1, NullPackedType()); if (!res) return Reference(nullptr, 1, NullPackedType());
@@ -1194,8 +1271,8 @@ class Builder FLATBUFFERS_FINAL_CLASS {
// sorted fashion. // sorted fashion.
// std::sort is typically already a lot faster on sorted data though. // std::sort is typically already a lot faster on sorted data though.
auto dict = reinterpret_cast<TwoValue*>(stack_.data() + start); auto dict = reinterpret_cast<TwoValue*>(stack_.data() + start);
std::sort( std::sort(dict, dict + len,
dict, dict + len, [&](const TwoValue &a, const TwoValue &b) -> bool { [&](const TwoValue& a, const TwoValue& b) -> bool {
auto as = reinterpret_cast<const char*>(buf_.data() + a.key.u_); auto as = reinterpret_cast<const char*>(buf_.data() + a.key.u_);
auto bs = reinterpret_cast<const char*>(buf_.data() + b.key.u_); auto bs = reinterpret_cast<const char*>(buf_.data() + b.key.u_);
auto comp = strcmp(as, bs); auto comp = strcmp(as, bs);
@@ -1226,17 +1303,20 @@ class Builder FLATBUFFERS_FINAL_CLASS {
// Any map with such keys won't be able to retrieve all values. // Any map with such keys won't be able to retrieve all values.
bool HasDuplicateKeys() const { return has_duplicate_keys_; } bool HasDuplicateKeys() const { return has_duplicate_keys_; }
template<typename F> size_t Vector(F f) { template <typename F>
size_t Vector(F f) {
auto start = StartVector(); auto start = StartVector();
f(); f();
return EndVector(start, false, false); return EndVector(start, false, false);
} }
template<typename F, typename T> size_t Vector(F f, T &state) { template <typename F, typename T>
size_t Vector(F f, T& state) {
auto start = StartVector(); auto start = StartVector();
f(state); f(state);
return EndVector(start, false, false); return EndVector(start, false, false);
} }
template<typename F> size_t Vector(const char *key, F f) { template <typename F>
size_t Vector(const char* key, F f) {
auto start = StartVector(key); auto start = StartVector(key);
f(); f();
return EndVector(start, false, false); return EndVector(start, false, false);
@@ -1248,7 +1328,8 @@ class Builder FLATBUFFERS_FINAL_CLASS {
return EndVector(start, false, false); return EndVector(start, false, false);
} }
template<typename T> void Vector(const T *elems, size_t len) { template <typename T>
void Vector(const T* elems, size_t len) {
if (flatbuffers::is_scalar<T>::value) { if (flatbuffers::is_scalar<T>::value) {
// This path should be a lot quicker and use less space. // This path should be a lot quicker and use less space.
ScalarVector(elems, len, false); ScalarVector(elems, len, false);
@@ -1263,21 +1344,25 @@ class Builder FLATBUFFERS_FINAL_CLASS {
Key(key); Key(key);
Vector(elems, len); Vector(elems, len);
} }
template<typename T> void Vector(const std::vector<T> &vec) { template <typename T>
void Vector(const std::vector<T>& vec) {
Vector(vec.data(), vec.size()); Vector(vec.data(), vec.size());
} }
template<typename F> size_t TypedVector(F f) { template <typename F>
size_t TypedVector(F f) {
auto start = StartVector(); auto start = StartVector();
f(); f();
return EndVector(start, true, false); return EndVector(start, true, false);
} }
template<typename F, typename T> size_t TypedVector(F f, T &state) { template <typename F, typename T>
size_t TypedVector(F f, T& state) {
auto start = StartVector(); auto start = StartVector();
f(state); f(state);
return EndVector(start, true, false); return EndVector(start, true, false);
} }
template<typename F> size_t TypedVector(const char *key, F f) { template <typename F>
size_t TypedVector(const char* key, F f) {
auto start = StartVector(key); auto start = StartVector(key);
f(); f();
return EndVector(start, true, false); return EndVector(start, true, false);
@@ -1289,7 +1374,8 @@ class Builder FLATBUFFERS_FINAL_CLASS {
return EndVector(start, true, false); return EndVector(start, true, false);
} }
template<typename T> size_t FixedTypedVector(const T *elems, size_t len) { template <typename T>
size_t FixedTypedVector(const T* elems, size_t len) {
// We only support a few fixed vector lengths. Anything bigger use a // We only support a few fixed vector lengths. Anything bigger use a
// regular typed vector. // regular typed vector.
FLATBUFFERS_ASSERT(len >= 2 && len <= 4); FLATBUFFERS_ASSERT(len >= 2 && len <= 4);
@@ -1304,27 +1390,32 @@ class Builder FLATBUFFERS_FINAL_CLASS {
return FixedTypedVector(elems, len); return FixedTypedVector(elems, len);
} }
template<typename F> size_t Map(F f) { template <typename F>
size_t Map(F f) {
auto start = StartMap(); auto start = StartMap();
f(); f();
return EndMap(start); return EndMap(start);
} }
template<typename F, typename T> size_t Map(F f, T &state) { template <typename F, typename T>
size_t Map(F f, T& state) {
auto start = StartMap(); auto start = StartMap();
f(state); f(state);
return EndMap(start); return EndMap(start);
} }
template<typename F> size_t Map(const char *key, F f) { template <typename F>
size_t Map(const char* key, F f) {
auto start = StartMap(key); auto start = StartMap(key);
f(); f();
return EndMap(start); return EndMap(start);
} }
template<typename F, typename T> size_t Map(const char *key, F f, T &state) { template <typename F, typename T>
size_t Map(const char* key, F f, T& state) {
auto start = StartMap(key); auto start = StartMap(key);
f(state); f(state);
return EndMap(start); return EndMap(start);
} }
template<typename T> void Map(const std::map<std::string, T> &map) { template <typename T>
void Map(const std::map<std::string, T>& map) {
auto start = StartMap(); auto start = StartMap();
for (auto it = map.begin(); it != map.end(); ++it) for (auto it = map.begin(); it != map.end(); ++it)
Add(it->first.c_str(), it->second); Add(it->first.c_str(), it->second);
@@ -1359,9 +1450,7 @@ class Builder FLATBUFFERS_FINAL_CLASS {
// Undo the last element serialized. Call once for a value and once for a // Undo the last element serialized. Call once for a value and once for a
// key. // key.
void Undo() { void Undo() { stack_.pop_back(); }
stack_.pop_back();
}
// Overloaded Add that tries to call the correct function above. // Overloaded Add that tries to call the correct function above.
void Add(int8_t i) { Int(i); } void Add(int8_t i) { Int(i); }
@@ -1379,18 +1468,26 @@ class Builder FLATBUFFERS_FINAL_CLASS {
void Add(const std::string& str) { String(str); } void Add(const std::string& str) { String(str); }
void Add(const flexbuffers::String& str) { String(str); } void Add(const flexbuffers::String& str) { String(str); }
template<typename T> void Add(const std::vector<T> &vec) { Vector(vec); } template <typename T>
void Add(const std::vector<T>& vec) {
Vector(vec);
}
template<typename T> void Add(const char *key, const T &t) { template <typename T>
void Add(const char* key, const T& t) {
Key(key); Key(key);
Add(t); Add(t);
} }
template<typename T> void Add(const std::map<std::string, T> &map) { template <typename T>
void Add(const std::map<std::string, T>& map) {
Map(map); Map(map);
} }
template<typename T> void operator+=(const T &t) { Add(t); } template <typename T>
void operator+=(const T& t) {
Add(t);
}
// This function is useful in combination with the Mutate* functions above. // This function is useful in combination with the Mutate* functions above.
// It forces elements of vectors and maps to have a minimum size, such that // It forces elements of vectors and maps to have a minimum size, such that
@@ -1439,7 +1536,8 @@ class Builder FLATBUFFERS_FINAL_CLASS {
reinterpret_cast<const uint8_t*>(val) + size); reinterpret_cast<const uint8_t*>(val) + size);
} }
template<typename T> void Write(T val, size_t byte_width) { template <typename T>
void Write(T val, size_t byte_width) {
FLATBUFFERS_ASSERT(sizeof(T) >= byte_width); FLATBUFFERS_ASSERT(sizeof(T) >= byte_width);
val = flatbuffers::EndianScalar(val); val = flatbuffers::EndianScalar(val);
WriteBytes(&val, byte_width); WriteBytes(&val, byte_width);
@@ -1447,11 +1545,16 @@ class Builder FLATBUFFERS_FINAL_CLASS {
void WriteDouble(double f, uint8_t byte_width) { void WriteDouble(double f, uint8_t byte_width) {
switch (byte_width) { switch (byte_width) {
case 8: Write(f, byte_width); break; case 8:
case 4: Write(static_cast<float>(f), byte_width); break; Write(f, byte_width);
break;
case 4:
Write(static_cast<float>(f), byte_width);
break;
// case 2: Write(static_cast<half>(f), byte_width); break; // case 2: Write(static_cast<half>(f), byte_width); break;
// case 1: Write(static_cast<quarter>(f), byte_width); break; // case 1: Write(static_cast<quarter>(f), byte_width); break;
default: FLATBUFFERS_ASSERT(0); default:
FLATBUFFERS_ASSERT(0);
} }
} }
@@ -1461,7 +1564,8 @@ class Builder FLATBUFFERS_FINAL_CLASS {
Write(reloff, byte_width); Write(reloff, byte_width);
} }
template<typename T> void PushIndirect(T val, Type type, BitWidth bit_width) { template <typename T>
void PushIndirect(T val, Type type, BitWidth bit_width) {
auto byte_width = Align(bit_width); auto byte_width = Align(bit_width);
auto iloc = buf_.size(); auto iloc = buf_.size();
Write(val, byte_width); Write(val, byte_width);
@@ -1470,15 +1574,22 @@ class Builder FLATBUFFERS_FINAL_CLASS {
static BitWidth WidthB(size_t byte_width) { static BitWidth WidthB(size_t byte_width) {
switch (byte_width) { switch (byte_width) {
case 1: return BIT_WIDTH_8; case 1:
case 2: return BIT_WIDTH_16; return BIT_WIDTH_8;
case 4: return BIT_WIDTH_32; case 2:
case 8: return BIT_WIDTH_64; return BIT_WIDTH_16;
default: FLATBUFFERS_ASSERT(false); return BIT_WIDTH_64; case 4:
return BIT_WIDTH_32;
case 8:
return BIT_WIDTH_64;
default:
FLATBUFFERS_ASSERT(false);
return BIT_WIDTH_64;
} }
} }
template<typename T> static Type GetScalarType() { template <typename T>
static Type GetScalarType() {
static_assert(flatbuffers::is_scalar<T>::value, "Unrelated types"); static_assert(flatbuffers::is_scalar<T>::value, "Unrelated types");
return flatbuffers::is_floating_point<T>::value ? FBT_FLOAT return flatbuffers::is_floating_point<T>::value ? FBT_FLOAT
: flatbuffers::is_same<T, bool>::value : flatbuffers::is_same<T, bool>::value
@@ -1564,11 +1675,19 @@ class Builder FLATBUFFERS_FINAL_CLASS {
void WriteAny(const Value& val, uint8_t byte_width) { void WriteAny(const Value& val, uint8_t byte_width) {
switch (val.type_) { switch (val.type_) {
case FBT_NULL: case FBT_NULL:
case FBT_INT: Write(val.i_, byte_width); break; case FBT_INT:
Write(val.i_, byte_width);
break;
case FBT_BOOL: case FBT_BOOL:
case FBT_UINT: Write(val.u_, byte_width); break; case FBT_UINT:
case FBT_FLOAT: WriteDouble(val.f_, byte_width); break; Write(val.u_, byte_width);
default: WriteOffset(val.u_, byte_width); break; break;
case FBT_FLOAT:
WriteDouble(val.f_, byte_width);
break;
default:
WriteOffset(val.u_, byte_width);
break;
} }
} }
@@ -1725,7 +1844,8 @@ class Verifier FLATBUFFERS_FINAL_CLASS {
max_vectors_(buf_len), max_vectors_(buf_len),
check_alignment_(_check_alignment), check_alignment_(_check_alignment),
reuse_tracker_(reuse_tracker) { reuse_tracker_(reuse_tracker) {
FLATBUFFERS_ASSERT(static_cast<int32_t>(size_) < FLATBUFFERS_MAX_BUFFER_SIZE); FLATBUFFERS_ASSERT(static_cast<int32_t>(size_) <
FLATBUFFERS_MAX_BUFFER_SIZE);
if (reuse_tracker_) { if (reuse_tracker_) {
reuse_tracker_->clear(); reuse_tracker_->clear();
reuse_tracker_->resize(size_, PackedType(BIT_WIDTH_8, FBT_NULL)); reuse_tracker_->resize(size_, PackedType(BIT_WIDTH_8, FBT_NULL));
@@ -1870,20 +1990,28 @@ class Verifier FLATBUFFERS_FINAL_CLASS {
switch (r.type_) { switch (r.type_) {
case FBT_INDIRECT_INT: case FBT_INDIRECT_INT:
case FBT_INDIRECT_UINT: case FBT_INDIRECT_UINT:
case FBT_INDIRECT_FLOAT: return VerifyFromPointer(p, r.byte_width_); case FBT_INDIRECT_FLOAT:
case FBT_KEY: return VerifyKey(p); return VerifyFromPointer(p, r.byte_width_);
case FBT_KEY:
return VerifyKey(p);
case FBT_MAP: case FBT_MAP:
return VerifyVector(r, p, FBT_NULL) && VerifyKeys(p, r.byte_width_); return VerifyVector(r, p, FBT_NULL) && VerifyKeys(p, r.byte_width_);
case FBT_VECTOR: return VerifyVector(r, p, FBT_NULL); case FBT_VECTOR:
case FBT_VECTOR_INT: return VerifyVector(r, p, FBT_INT); return VerifyVector(r, p, FBT_NULL);
case FBT_VECTOR_INT:
return VerifyVector(r, p, FBT_INT);
case FBT_VECTOR_BOOL: case FBT_VECTOR_BOOL:
case FBT_VECTOR_UINT: return VerifyVector(r, p, FBT_UINT); case FBT_VECTOR_UINT:
case FBT_VECTOR_FLOAT: return VerifyVector(r, p, FBT_FLOAT); return VerifyVector(r, p, FBT_UINT);
case FBT_VECTOR_KEY: return VerifyVector(r, p, FBT_KEY); case FBT_VECTOR_FLOAT:
return VerifyVector(r, p, FBT_FLOAT);
case FBT_VECTOR_KEY:
return VerifyVector(r, p, FBT_KEY);
case FBT_VECTOR_STRING_DEPRECATED: case FBT_VECTOR_STRING_DEPRECATED:
// Use of FBT_KEY here intentional, see elsewhere. // Use of FBT_KEY here intentional, see elsewhere.
return VerifyVector(r, p, FBT_KEY); return VerifyVector(r, p, FBT_KEY);
case FBT_BLOB: return VerifyVector(r, p, FBT_UINT); case FBT_BLOB:
return VerifyVector(r, p, FBT_UINT);
case FBT_STRING: case FBT_STRING:
return VerifyVector(r, p, FBT_UINT) && return VerifyVector(r, p, FBT_UINT) &&
VerifyTerminator(String(p, r.byte_width_)); VerifyTerminator(String(p, r.byte_width_));
@@ -1901,7 +2029,8 @@ class Verifier FLATBUFFERS_FINAL_CLASS {
if (!VerifyType(vtype)) return false; if (!VerifyType(vtype)) return false;
return VerifyFromPointer(p, static_cast<size_t>(r.byte_width_) * len); return VerifyFromPointer(p, static_cast<size_t>(r.byte_width_) * len);
} }
default: return false; default:
return false;
} }
} }

View File

@@ -30,7 +30,8 @@ namespace grpc {
// `grpc_slice` and also provides flatbuffers-specific helpers such as `Verify` // `grpc_slice` and also provides flatbuffers-specific helpers such as `Verify`
// and `GetRoot`. Since it is backed by a `grpc_slice`, the underlying buffer // and `GetRoot`. Since it is backed by a `grpc_slice`, the underlying buffer
// is refcounted and ownership is be managed automatically. // is refcounted and ownership is be managed automatically.
template<class T> class Message { template <class T>
class Message {
public: public:
Message() {} Message() {}
@@ -221,7 +222,8 @@ class MessageBuilder : private detail::SliceAllocatorMember,
// GetMessage extracts the subslice of the buffer corresponding to the // GetMessage extracts the subslice of the buffer corresponding to the
// flatbuffers-encoded region and wraps it in a `Message<T>` to handle buffer // flatbuffers-encoded region and wraps it in a `Message<T>` to handle buffer
// ownership. // ownership.
template<class T> Message<T> GetMessage() { template <class T>
Message<T> GetMessage() {
auto buf_data = buf_.scratch_data(); // pointer to memory auto buf_data = buf_.scratch_data(); // pointer to memory
auto buf_size = buf_.capacity(); // size of memory auto buf_size = buf_.capacity(); // size of memory
auto msg_data = buf_.data(); // pointer to msg auto msg_data = buf_.data(); // pointer to msg
@@ -243,7 +245,8 @@ class MessageBuilder : private detail::SliceAllocatorMember,
return msg; return msg;
} }
template<class T> Message<T> ReleaseMessage() { template <class T>
Message<T> ReleaseMessage() {
Message<T> msg = GetMessage<T>(); Message<T> msg = GetMessage<T>();
Reset(); Reset();
return msg; return msg;
@@ -258,7 +261,8 @@ class MessageBuilder : private detail::SliceAllocatorMember,
namespace grpc { namespace grpc {
template<class T> class SerializationTraits<flatbuffers::grpc::Message<T>> { template <class T>
class SerializationTraits<flatbuffers::grpc::Message<T>> {
public: public:
static grpc::Status Serialize(const flatbuffers::grpc::Message<T>& msg, static grpc::Status Serialize(const flatbuffers::grpc::Message<T>& msg,
ByteBuffer* buffer, bool* own_buffer) { ByteBuffer* buffer, bool* own_buffer) {

View File

@@ -24,22 +24,26 @@
namespace flatbuffers { namespace flatbuffers {
template<typename T> struct FnvTraits { template <typename T>
struct FnvTraits {
static const T kFnvPrime; static const T kFnvPrime;
static const T kOffsetBasis; static const T kOffsetBasis;
}; };
template<> struct FnvTraits<uint32_t> { template <>
struct FnvTraits<uint32_t> {
static const uint32_t kFnvPrime = 0x01000193; static const uint32_t kFnvPrime = 0x01000193;
static const uint32_t kOffsetBasis = 0x811C9DC5; static const uint32_t kOffsetBasis = 0x811C9DC5;
}; };
template<> struct FnvTraits<uint64_t> { template <>
struct FnvTraits<uint64_t> {
static const uint64_t kFnvPrime = 0x00000100000001b3ULL; static const uint64_t kFnvPrime = 0x00000100000001b3ULL;
static const uint64_t kOffsetBasis = 0xcbf29ce484222645ULL; static const uint64_t kOffsetBasis = 0xcbf29ce484222645ULL;
}; };
template<typename T> T HashFnv1(const char *input) { template <typename T>
T HashFnv1(const char* input) {
T hash = FnvTraits<T>::kOffsetBasis; T hash = FnvTraits<T>::kOffsetBasis;
for (const char* c = input; *c; ++c) { for (const char* c = input; *c; ++c) {
hash *= FnvTraits<T>::kFnvPrime; hash *= FnvTraits<T>::kFnvPrime;
@@ -48,7 +52,8 @@ template<typename T> T HashFnv1(const char *input) {
return hash; return hash;
} }
template<typename T> T HashFnv1a(const char *input) { template <typename T>
T HashFnv1a(const char* input) {
T hash = FnvTraits<T>::kOffsetBasis; T hash = FnvTraits<T>::kOffsetBasis;
for (const char* c = input; *c; ++c) { for (const char* c = input; *c; ++c) {
hash ^= static_cast<unsigned char>(*c); hash ^= static_cast<unsigned char>(*c);
@@ -57,17 +62,20 @@ template<typename T> T HashFnv1a(const char *input) {
return hash; return hash;
} }
template<> inline uint16_t HashFnv1<uint16_t>(const char *input) { template <>
inline uint16_t HashFnv1<uint16_t>(const char* input) {
uint32_t hash = HashFnv1<uint32_t>(input); uint32_t hash = HashFnv1<uint32_t>(input);
return (hash >> 16) ^ (hash & 0xffff); return (hash >> 16) ^ (hash & 0xffff);
} }
template<> inline uint16_t HashFnv1a<uint16_t>(const char *input) { template <>
inline uint16_t HashFnv1a<uint16_t>(const char* input) {
uint32_t hash = HashFnv1a<uint32_t>(input); uint32_t hash = HashFnv1a<uint32_t>(input);
return (hash >> 16) ^ (hash & 0xffff); return (hash >> 16) ^ (hash & 0xffff);
} }
template<typename T> struct NamedHashFunction { template <typename T>
struct NamedHashFunction {
const char* name; const char* name;
typedef T (*HashFunction)(const char*); typedef T (*HashFunction)(const char*);

View File

@@ -234,10 +234,13 @@ struct Value {
// Helper class that retains the original order of a set of identifiers and // Helper class that retains the original order of a set of identifiers and
// also provides quick lookup. // also provides quick lookup.
template<typename T> class SymbolTable { template <typename T>
class SymbolTable {
public: public:
~SymbolTable() { ~SymbolTable() {
for (auto it = vec.begin(); it != vec.end(); ++it) { delete *it; } for (auto it = vec.begin(); it != vec.end(); ++it) {
delete *it;
}
} }
bool Add(const std::string& name, T* e) { bool Add(const std::string& name, T* e) {
@@ -342,10 +345,7 @@ struct FieldDef : public Definition {
bool Deserialize(Parser& parser, const reflection::Field* field); bool Deserialize(Parser& parser, const reflection::Field* field);
bool IsScalarOptional() const { return IsScalar() && IsOptional(); }
bool IsScalarOptional() const {
return IsScalar() && IsOptional();
}
bool IsScalar() const { bool IsScalar() const {
return ::flatbuffers::IsScalar(value.type.base_type); return ::flatbuffers::IsScalar(value.type.base_type);
} }
@@ -471,7 +471,8 @@ struct EnumDef : public Definition {
bool Deserialize(Parser& parser, const reflection::Enum* values); bool Deserialize(Parser& parser, const reflection::Enum* values);
template<typename T> void ChangeEnumValue(EnumVal *ev, T new_val); template <typename T>
void ChangeEnumValue(EnumVal* ev, T new_val);
void SortByValue(); void SortByValue();
void RemoveDuplicates(); void RemoveDuplicates();
@@ -972,7 +973,9 @@ class Parser : public ParserState {
source_(nullptr), source_(nullptr),
anonymous_counter_(0), anonymous_counter_(0),
parse_depth_counter_(0) { parse_depth_counter_(0) {
if (opts.force_defaults) { builder_.ForceDefaults(true); } if (opts.force_defaults) {
builder_.ForceDefaults(true);
}
// Start out with the empty namespace being current. // Start out with the empty namespace being current.
empty_namespace_ = new Namespace(); empty_namespace_ = new Namespace();
namespaces_.push_back(empty_namespace_); namespaces_.push_back(empty_namespace_);
@@ -1201,7 +1204,8 @@ class Parser : public ParserState {
Namespace* UniqueNamespace(Namespace* ns); Namespace* UniqueNamespace(Namespace* ns);
FLATBUFFERS_CHECKED_ERROR RecurseError(); FLATBUFFERS_CHECKED_ERROR RecurseError();
template<typename F> CheckedError Recurse(F f); template <typename F>
CheckedError Recurse(F f);
const std::string& GetPooledString(const std::string& s) const; const std::string& GetPooledString(const std::string& s) const;
@@ -1260,8 +1264,7 @@ class Parser : public ParserState {
// These functions return nullptr on success, or an error string, // These functions return nullptr on success, or an error string,
// which may happen if the flatbuffer cannot be encoded in JSON (e.g., // which may happen if the flatbuffer cannot be encoded in JSON (e.g.,
// it contains non-UTF-8 byte arrays in String values). // it contains non-UTF-8 byte arrays in String values).
extern bool GenerateTextFromTable(const Parser &parser, extern bool GenerateTextFromTable(const Parser& parser, const void* table,
const void *table,
const std::string& tablename, const std::string& tablename,
std::string* text); std::string* text);
extern const char* GenerateText(const Parser& parser, const void* flatbuffer, extern const char* GenerateText(const Parser& parser, const void* flatbuffer,

View File

@@ -74,25 +74,34 @@ inline size_t InlineSize(ElementaryType type, const TypeTable *type_table) {
case ET_UTYPE: case ET_UTYPE:
case ET_BOOL: case ET_BOOL:
case ET_CHAR: case ET_CHAR:
case ET_UCHAR: return 1; case ET_UCHAR:
return 1;
case ET_SHORT: case ET_SHORT:
case ET_USHORT: return 2; case ET_USHORT:
return 2;
case ET_INT: case ET_INT:
case ET_UINT: case ET_UINT:
case ET_FLOAT: case ET_FLOAT:
case ET_STRING: return 4; case ET_STRING:
return 4;
case ET_LONG: case ET_LONG:
case ET_ULONG: case ET_ULONG:
case ET_DOUBLE: return 8; case ET_DOUBLE:
return 8;
case ET_SEQUENCE: case ET_SEQUENCE:
switch (type_table->st) { switch (type_table->st) {
case ST_TABLE: case ST_TABLE:
case ST_UNION: return 4; case ST_UNION:
return 4;
case ST_STRUCT: case ST_STRUCT:
return static_cast<size_t>(type_table->values[type_table->num_elems]); return static_cast<size_t>(type_table->values[type_table->num_elems]);
default: FLATBUFFERS_ASSERT(false); return 1; default:
FLATBUFFERS_ASSERT(false);
return 1;
} }
default: FLATBUFFERS_ASSERT(false); return 1; default:
FLATBUFFERS_ASSERT(false);
return 1;
} }
} }
@@ -105,7 +114,8 @@ inline int64_t LookupEnum(int64_t enum_val, const int64_t *values,
return -1; // Unknown enum value. return -1; // Unknown enum value.
} }
template<typename T> const char *EnumName(T tval, const TypeTable *type_table) { template <typename T>
const char* EnumName(T tval, const TypeTable* type_table) {
if (!type_table || !type_table->names) return nullptr; if (!type_table || !type_table->names) return nullptr;
auto i = LookupEnum(static_cast<int64_t>(tval), type_table->values, auto i = LookupEnum(static_cast<int64_t>(tval), type_table->values,
type_table->num_elems); type_table->num_elems);
@@ -188,7 +198,9 @@ inline void IterateValue(ElementaryType type, const uint8_t *val,
val += ReadScalar<uoffset_t>(val); val += ReadScalar<uoffset_t>(val);
IterateObject(val, type_table, visitor); IterateObject(val, type_table, visitor);
break; break;
case ST_STRUCT: IterateObject(val, type_table, visitor); break; case ST_STRUCT:
IterateObject(val, type_table, visitor);
break;
case ST_UNION: { case ST_UNION: {
val += ReadScalar<uoffset_t>(val); val += ReadScalar<uoffset_t>(val);
FLATBUFFERS_ASSERT(prev_val); FLATBUFFERS_ASSERT(prev_val);
@@ -211,14 +223,17 @@ inline void IterateValue(ElementaryType type, const uint8_t *val,
case ET_STRING: case ET_STRING:
visitor->String(reinterpret_cast<const String*>(val)); visitor->String(reinterpret_cast<const String*>(val));
break; break;
default: visitor->Unknown(val); default:
visitor->Unknown(val);
} }
} else { } else {
visitor->Unknown(val); visitor->Unknown(val);
} }
break; break;
} }
case ST_ENUM: FLATBUFFERS_ASSERT(false); break; case ST_ENUM:
FLATBUFFERS_ASSERT(false);
break;
} }
break; break;
} }
@@ -241,7 +256,9 @@ inline void IterateObject(const uint8_t *obj, const TypeTable *type_table,
auto is_repeating = type_code.is_repeating != 0; auto is_repeating = type_code.is_repeating != 0;
auto ref_idx = type_code.sequence_ref; auto ref_idx = type_code.sequence_ref;
const TypeTable* ref = nullptr; const TypeTable* ref = nullptr;
if (ref_idx >= 0) { ref = type_table->type_refs[ref_idx](); } if (ref_idx >= 0) {
ref = type_table->type_refs[ref_idx]();
}
auto name = type_table->names ? type_table->names[i] : nullptr; auto name = type_table->names ? type_table->names[i] : nullptr;
const uint8_t* val = nullptr; const uint8_t* val = nullptr;
if (type_table->st == ST_TABLE) { if (type_table->st == ST_TABLE) {
@@ -315,7 +332,9 @@ struct ToStringVisitor : public IterationVisitor {
vector_delimited(true) {} vector_delimited(true) {}
void append_indent() { void append_indent() {
for (size_t i = 0; i < indent_level; i++) { s += in; } for (size_t i = 0; i < indent_level; i++) {
s += in;
}
} }
void StartSequence() { void StartSequence() {
@@ -345,7 +364,8 @@ struct ToStringVisitor : public IterationVisitor {
s += ": "; s += ": ";
} }
} }
template<typename T> void Named(T x, const char *name) { template <typename T>
void Named(T x, const char* name) {
if (name) { if (name) {
if (q) s += "\""; if (q) s += "\"";
s += name; s += name;

View File

@@ -106,13 +106,15 @@ inline const Table *GetAnySizePrefixedRoot(const uint8_t *const flatbuf) {
} }
// Get a field's default, if you know it's an integer, and its exact type. // Get a field's default, if you know it's an integer, and its exact type.
template<typename T> T GetFieldDefaultI(const reflection::Field &field) { template <typename T>
T GetFieldDefaultI(const reflection::Field& field) {
FLATBUFFERS_ASSERT(sizeof(T) == GetTypeSize(field.type()->base_type())); FLATBUFFERS_ASSERT(sizeof(T) == GetTypeSize(field.type()->base_type()));
return static_cast<T>(field.default_integer()); return static_cast<T>(field.default_integer());
} }
// Get a field's default, if you know it's floating point and its exact type. // Get a field's default, if you know it's floating point and its exact type.
template<typename T> T GetFieldDefaultF(const reflection::Field &field) { template <typename T>
T GetFieldDefaultF(const reflection::Field& field) {
FLATBUFFERS_ASSERT(sizeof(T) == GetTypeSize(field.type()->base_type())); FLATBUFFERS_ASSERT(sizeof(T) == GetTypeSize(field.type()->base_type()));
return static_cast<T>(field.default_real()); return static_cast<T>(field.default_real());
} }
@@ -301,7 +303,9 @@ void ForAllFields(const reflection::Object *object, bool reverse,
template <typename T> template <typename T>
bool SetField(Table* table, const reflection::Field& field, T val) { bool SetField(Table* table, const reflection::Field& field, T val) {
reflection::BaseType type = field.type()->base_type(); reflection::BaseType type = field.type()->base_type();
if (!IsScalar(type)) { return false; } if (!IsScalar(type)) {
return false;
}
FLATBUFFERS_ASSERT(sizeof(T) == GetTypeSize(type)); FLATBUFFERS_ASSERT(sizeof(T) == GetTypeSize(type));
T def; T def;
if (IsInteger(type)) { if (IsInteger(type)) {
@@ -391,7 +395,8 @@ inline void SetAnyVectorElemS(VectorOfAny *vec, reflection::BaseType elem_type,
// "smart" pointer for use with resizing vectors: turns a pointer inside // "smart" pointer for use with resizing vectors: turns a pointer inside
// a vector into a relative offset, such that it is not affected by resizes. // a vector into a relative offset, such that it is not affected by resizes.
template<typename T, typename U> class pointer_inside_vector { template <typename T, typename U>
class pointer_inside_vector {
public: public:
pointer_inside_vector(T* ptr, std::vector<U>& vec) pointer_inside_vector(T* ptr, std::vector<U>& vec)
: offset_(reinterpret_cast<uint8_t*>(ptr) - : offset_(reinterpret_cast<uint8_t*>(ptr) -

View File

@@ -27,11 +27,13 @@ namespace flatbuffers {
class Struct FLATBUFFERS_FINAL_CLASS { class Struct FLATBUFFERS_FINAL_CLASS {
public: public:
template<typename T> T GetField(uoffset_t o) const { template <typename T>
T GetField(uoffset_t o) const {
return ReadScalar<T>(&data_[o]); return ReadScalar<T>(&data_[o]);
} }
template<typename T> T GetStruct(uoffset_t o) const { template <typename T>
T GetStruct(uoffset_t o) const {
return reinterpret_cast<T>(&data_[o]); return reinterpret_cast<T>(&data_[o]);
} }

View File

@@ -42,7 +42,8 @@ class Table {
return field < vtsize ? ReadScalar<voffset_t>(vtable + field) : 0; return field < vtsize ? ReadScalar<voffset_t>(vtable + field) : 0;
} }
template<typename T> T GetField(voffset_t field, T defaultval) const { template <typename T>
T GetField(voffset_t field, T defaultval) const {
auto field_offset = GetOptionalFieldOffset(field); auto field_offset = GetOptionalFieldOffset(field);
return field_offset ? ReadScalar<T>(data_ + field_offset) : defaultval; return field_offset ? ReadScalar<T>(data_ + field_offset) : defaultval;
} }
@@ -59,15 +60,18 @@ class Table {
return const_cast<Table*>(this)->GetPointer<P, OffsetSize>(field); return const_cast<Table*>(this)->GetPointer<P, OffsetSize>(field);
} }
template<typename P> P GetPointer64(voffset_t field) { template <typename P>
P GetPointer64(voffset_t field) {
return GetPointer<P, uoffset64_t>(field); return GetPointer<P, uoffset64_t>(field);
} }
template<typename P> P GetPointer64(voffset_t field) const { template <typename P>
P GetPointer64(voffset_t field) const {
return GetPointer<P, uoffset64_t>(field); return GetPointer<P, uoffset64_t>(field);
} }
template<typename P> P GetStruct(voffset_t field) const { template <typename P>
P GetStruct(voffset_t field) const {
auto field_offset = GetOptionalFieldOffset(field); auto field_offset = GetOptionalFieldOffset(field);
auto p = const_cast<uint8_t*>(data_ + field_offset); auto p = const_cast<uint8_t*>(data_ + field_offset);
return field_offset ? reinterpret_cast<P>(p) : nullptr; return field_offset ? reinterpret_cast<P>(p) : nullptr;
@@ -81,13 +85,15 @@ class Table {
: Optional<Face>(); : Optional<Face>();
} }
template<typename T> bool SetField(voffset_t field, T val, T def) { template <typename T>
bool SetField(voffset_t field, T val, T def) {
auto field_offset = GetOptionalFieldOffset(field); auto field_offset = GetOptionalFieldOffset(field);
if (!field_offset) return IsTheSameAs(val, def); if (!field_offset) return IsTheSameAs(val, def);
WriteScalar(data_ + field_offset, val); WriteScalar(data_ + field_offset, val);
return true; return true;
} }
template<typename T> bool SetField(voffset_t field, T val) { template <typename T>
bool SetField(voffset_t field, T val) {
auto field_offset = GetOptionalFieldOffset(field); auto field_offset = GetOptionalFieldOffset(field);
if (!field_offset) return false; if (!field_offset) return false;
WriteScalar(data_ + field_offset, val); WriteScalar(data_ + field_offset, val);

View File

@@ -90,7 +90,8 @@ inline char CharToLower(char c) {
// @end-locale-independent functions for ASCII character set // @end-locale-independent functions for ASCII character set
#ifdef FLATBUFFERS_PREFER_PRINTF #ifdef FLATBUFFERS_PREFER_PRINTF
template<typename T> size_t IntToDigitCount(T t) { template <typename T>
size_t IntToDigitCount(T t) {
size_t digit_count = 0; size_t digit_count = 0;
// Count the sign for negative numbers // Count the sign for negative numbers
if (t < 0) digit_count++; if (t < 0) digit_count++;
@@ -105,7 +106,8 @@ template<typename T> size_t IntToDigitCount(T t) {
return digit_count; return digit_count;
} }
template<typename T> size_t NumToStringWidth(T t, int precision = 0) { template <typename T>
size_t NumToStringWidth(T t, int precision = 0) {
size_t string_width = IntToDigitCount(t); size_t string_width = IntToDigitCount(t);
// Count the dot for floating point numbers // Count the dot for floating point numbers
if (precision) string_width += (precision + 1); if (precision) string_width += (precision + 1);
@@ -125,7 +127,8 @@ std::string NumToStringImplWrapper(T t, const char *fmt, int precision = 0) {
// Convert an integer or floating point value to a string. // Convert an integer or floating point value to a string.
// In contrast to std::stringstream, "char" values are // In contrast to std::stringstream, "char" values are
// converted to a string of digits, and we don't use scientific notation. // converted to a string of digits, and we don't use scientific notation.
template<typename T> std::string NumToString(T t) { template <typename T>
std::string NumToString(T t) {
// clang-format off // clang-format off
#ifndef FLATBUFFERS_PREFER_PRINTF #ifndef FLATBUFFERS_PREFER_PRINTF
@@ -139,18 +142,22 @@ template<typename T> std::string NumToString(T t) {
// clang-format on // clang-format on
} }
// Avoid char types used as character data. // Avoid char types used as character data.
template<> inline std::string NumToString<signed char>(signed char t) { template <>
inline std::string NumToString<signed char>(signed char t) {
return NumToString(static_cast<int>(t)); return NumToString(static_cast<int>(t));
} }
template<> inline std::string NumToString<unsigned char>(unsigned char t) { template <>
inline std::string NumToString<unsigned char>(unsigned char t) {
return NumToString(static_cast<int>(t)); return NumToString(static_cast<int>(t));
} }
template<> inline std::string NumToString<char>(char t) { template <>
inline std::string NumToString<char>(char t) {
return NumToString(static_cast<int>(t)); return NumToString(static_cast<int>(t));
} }
// Special versions for floats/doubles. // Special versions for floats/doubles.
template<typename T> std::string FloatToString(T t, int precision) { template <typename T>
std::string FloatToString(T t, int precision) {
// clang-format off // clang-format off
#ifndef FLATBUFFERS_PREFER_PRINTF #ifndef FLATBUFFERS_PREFER_PRINTF
@@ -177,10 +184,12 @@ template<typename T> std::string FloatToString(T t, int precision) {
return s; return s;
} }
template<> inline std::string NumToString<double>(double t) { template <>
inline std::string NumToString<double>(double t) {
return FloatToString(t, 12); return FloatToString(t, 12);
} }
template<> inline std::string NumToString<float>(float t) { template <>
inline std::string NumToString<float>(float t) {
return FloatToString(t, 6); return FloatToString(t, 6);
} }
@@ -314,7 +323,9 @@ inline bool StringToFloatImpl(T *val, const char *const str) {
strtoval_impl(val, str, const_cast<char**>(&end)); strtoval_impl(val, str, const_cast<char**>(&end));
auto done = (end != str) && (*end == '\0'); auto done = (end != str) && (*end == '\0');
if (!done) *val = 0; // erase partial result if (!done) *val = 0; // erase partial result
if (done && std::isnan(*val)) { *val = std::numeric_limits<T>::quiet_NaN(); } if (done && std::isnan(*val)) {
*val = std::numeric_limits<T>::quiet_NaN();
}
return done; return done;
} }
@@ -324,7 +335,8 @@ inline bool StringToFloatImpl(T *val, const char *const str) {
// - If full string conversion can't be performed, 0 is returned. // - If full string conversion can't be performed, 0 is returned.
// - If the converted value falls out of range of corresponding return type, a // - If the converted value falls out of range of corresponding return type, a
// range error occurs. In this case value MAX(T)/MIN(T) is returned. // range error occurs. In this case value MAX(T)/MIN(T) is returned.
template<typename T> inline bool StringToNumber(const char *s, T *val) { template <typename T>
inline bool StringToNumber(const char* s, T* val) {
// Assert on `unsigned long` and `signed long` on LP64. // Assert on `unsigned long` and `signed long` on LP64.
// If it is necessary, it could be solved with flatbuffers::enable_if<B,T>. // If it is necessary, it could be solved with flatbuffers::enable_if<B,T>.
static_assert(sizeof(T) < sizeof(int64_t), "unexpected type T"); static_assert(sizeof(T) < sizeof(int64_t), "unexpected type T");
@@ -351,7 +363,8 @@ template<typename T> inline bool StringToNumber(const char *s, T *val) {
return false; return false;
} }
template<> inline bool StringToNumber<int64_t>(const char *str, int64_t *val) { template <>
inline bool StringToNumber<int64_t>(const char* str, int64_t* val) {
return StringToIntegerImpl(val, str); return StringToIntegerImpl(val, str);
} }
@@ -377,11 +390,13 @@ inline bool StringToNumber<uint64_t>(const char *str, uint64_t *val) {
return true; return true;
} }
template<> inline bool StringToNumber(const char *s, float *val) { template <>
inline bool StringToNumber(const char* s, float* val) {
return StringToFloatImpl(val, s); return StringToFloatImpl(val, s);
} }
template<> inline bool StringToNumber(const char *s, double *val) { template <>
inline bool StringToNumber(const char* s, double* val) {
return StringToFloatImpl(val, s); return StringToFloatImpl(val, s);
} }
@@ -480,8 +495,7 @@ std::string PosixPath(const std::string &path);
void EnsureDirExists(const std::string& filepath); void EnsureDirExists(const std::string& filepath);
// Obtains the relative or absolute path. // Obtains the relative or absolute path.
std::string FilePath(const std::string &project, std::string FilePath(const std::string& project, const std::string& filePath,
const std::string &filePath,
bool absolute); bool absolute);
// Obtains the absolute path from any other path. // Obtains the absolute path from any other path.
@@ -538,7 +552,9 @@ inline int FromUTF8(const char **in) {
return -1; // Bit after leading 1's must be 0. return -1; // Bit after leading 1's must be 0.
if (!len) return *(*in)++; if (!len) return *(*in)++;
// UTF-8 encoded values with a length are between 2 and 4 bytes. // UTF-8 encoded values with a length are between 2 and 4 bytes.
if (len < 2 || len > 4) { return -1; } if (len < 2 || len > 4) {
return -1;
}
// Grab initial bits of the code. // Grab initial bits of the code.
int ucc = *(*in)++ & ((1 << (7 - len)) - 1); int ucc = *(*in)++ & ((1 << (7 - len)) - 1);
for (int i = 0; i < len - 1; i++) { for (int i = 0; i < len - 1; i++) {
@@ -548,20 +564,28 @@ inline int FromUTF8(const char **in) {
} }
// UTF-8 cannot encode values between 0xD800 and 0xDFFF (reserved for // UTF-8 cannot encode values between 0xD800 and 0xDFFF (reserved for
// UTF-16 surrogate pairs). // UTF-16 surrogate pairs).
if (ucc >= 0xD800 && ucc <= 0xDFFF) { return -1; } if (ucc >= 0xD800 && ucc <= 0xDFFF) {
return -1;
}
// UTF-8 must represent code points in their shortest possible encoding. // UTF-8 must represent code points in their shortest possible encoding.
switch (len) { switch (len) {
case 2: case 2:
// Two bytes of UTF-8 can represent code points from U+0080 to U+07FF. // Two bytes of UTF-8 can represent code points from U+0080 to U+07FF.
if (ucc < 0x0080 || ucc > 0x07FF) { return -1; } if (ucc < 0x0080 || ucc > 0x07FF) {
return -1;
}
break; break;
case 3: case 3:
// Three bytes of UTF-8 can represent code points from U+0800 to U+FFFF. // Three bytes of UTF-8 can represent code points from U+0800 to U+FFFF.
if (ucc < 0x0800 || ucc > 0xFFFF) { return -1; } if (ucc < 0x0800 || ucc > 0xFFFF) {
return -1;
}
break; break;
case 4: case 4:
// Four bytes of UTF-8 can represent code points from U+10000 to U+10FFFF. // Four bytes of UTF-8 can represent code points from U+10000 to U+10FFFF.
if (ucc < 0x10000 || ucc > 0x10FFFF) { return -1; } if (ucc < 0x10000 || ucc > 0x10FFFF) {
return -1;
}
break; break;
} }
return ucc; return ucc;
@@ -603,13 +627,27 @@ inline bool EscapeString(const char *s, size_t length, std::string *_text,
for (uoffset_t i = 0; i < length; i++) { for (uoffset_t i = 0; i < length; i++) {
char c = s[i]; char c = s[i];
switch (c) { switch (c) {
case '\n': text += "\\n"; break; case '\n':
case '\t': text += "\\t"; break; text += "\\n";
case '\r': text += "\\r"; break; break;
case '\b': text += "\\b"; break; case '\t':
case '\f': text += "\\f"; break; text += "\\t";
case '\"': text += "\\\""; break; break;
case '\\': text += "\\\\"; break; case '\r':
text += "\\r";
break;
case '\b':
text += "\\b";
break;
case '\f':
text += "\\f";
break;
case '\"':
text += "\\\"";
break;
case '\\':
text += "\\\\";
break;
default: default:
if (c >= ' ' && c <= '~') { if (c >= ' ' && c <= '~') {
text += c; text += c;
@@ -678,7 +716,9 @@ inline std::string BufferToHexText(const void *buffer, size_t buffer_size,
bool have_more = i + 1 < buffer_size; bool have_more = i + 1 < buffer_size;
text += "0x"; text += "0x";
text += IntToStringHex(static_cast<uint8_t>(s[i]), 2); text += IntToStringHex(static_cast<uint8_t>(s[i]), 2);
if (have_more) { text += ','; } if (have_more) {
text += ',';
}
// If we have more to process and we reached max_length // If we have more to process and we reached max_length
if (have_more && if (have_more &&
text.size() + wrapped_line_suffix.size() >= start_offset + max_length) { text.size() + wrapped_line_suffix.size() >= start_offset + max_length) {

View File

@@ -157,7 +157,8 @@ struct VectorReverseIterator : public std::reverse_iterator<Iterator> {
// This is used as a helper type for accessing vectors. // This is used as a helper type for accessing vectors.
// Vector::data() assumes the vector elements start after the length field. // Vector::data() assumes the vector elements start after the length field.
template<typename T, typename SizeT = uoffset_t> class Vector { template <typename T, typename SizeT = uoffset_t>
class Vector {
public: public:
typedef VectorIterator<T, typename IndirectHelper<T>::mutable_return_type, typedef VectorIterator<T, typename IndirectHelper<T>::mutable_return_type,
uint8_t*, SizeT> uint8_t*, SizeT>
@@ -199,13 +200,15 @@ template<typename T, typename SizeT = uoffset_t> class Vector {
// If this is a Vector of enums, T will be its storage type, not the enum // If this is a Vector of enums, T will be its storage type, not the enum
// type. This function makes it convenient to retrieve value with enum // type. This function makes it convenient to retrieve value with enum
// type E. // type E.
template<typename E> E GetEnum(SizeT i) const { template <typename E>
E GetEnum(SizeT i) const {
return static_cast<E>(Get(i)); return static_cast<E>(Get(i));
} }
// If this a vector of unions, this does the cast for you. There's no check // If this a vector of unions, this does the cast for you. There's no check
// to make sure this is the right type! // to make sure this is the right type!
template<typename U> const U *GetAs(SizeT i) const { template <typename U>
const U* GetAs(SizeT i) const {
return reinterpret_cast<const U*>(Get(i)); return reinterpret_cast<const U*>(Get(i));
} }
@@ -277,7 +280,8 @@ template<typename T, typename SizeT = uoffset_t> class Vector {
const T* data() const { return reinterpret_cast<const T*>(Data()); } const T* data() const { return reinterpret_cast<const T*>(Data()); }
T* data() { return reinterpret_cast<T*>(Data()); } T* data() { return reinterpret_cast<T*>(Data()); }
template<typename K> return_type LookupByKey(K key) const { template <typename K>
return_type LookupByKey(K key) const {
void* search_result = std::bsearch( void* search_result = std::bsearch(
&key, Data(), size(), IndirectHelper<T>::element_stride, KeyCompare<K>); &key, Data(), size(), IndirectHelper<T>::element_stride, KeyCompare<K>);
@@ -290,7 +294,8 @@ template<typename T, typename SizeT = uoffset_t> class Vector {
return IndirectHelper<T>::Read(element, 0); return IndirectHelper<T>::Read(element, 0);
} }
template<typename K> mutable_return_type MutableLookupByKey(K key) { template <typename K>
mutable_return_type MutableLookupByKey(K key) {
return const_cast<mutable_return_type>(LookupByKey(key)); return const_cast<mutable_return_type>(LookupByKey(key));
} }
@@ -307,7 +312,8 @@ template<typename T, typename SizeT = uoffset_t> class Vector {
Vector(const Vector&); Vector(const Vector&);
Vector& operator=(const Vector&); Vector& operator=(const Vector&);
template<typename K> static int KeyCompare(const void *ap, const void *bp) { template <typename K>
static int KeyCompare(const void* ap, const void* bp) {
const K* key = reinterpret_cast<const K*>(ap); const K* key = reinterpret_cast<const K*>(ap);
const uint8_t* data = reinterpret_cast<const uint8_t*>(bp); const uint8_t* data = reinterpret_cast<const uint8_t*>(bp);
auto table = IndirectHelper<T>::Read(data, 0); auto table = IndirectHelper<T>::Read(data, 0);
@@ -318,7 +324,8 @@ template<typename T, typename SizeT = uoffset_t> class Vector {
} }
}; };
template<typename T> using Vector64 = Vector<T, uoffset64_t>; template <typename T>
using Vector64 = Vector<T, uoffset64_t>;
template <class U> template <class U>
FLATBUFFERS_CONSTEXPR_CPP11 flatbuffers::span<U> make_span(Vector<U>& vec) FLATBUFFERS_CONSTEXPR_CPP11 flatbuffers::span<U> make_span(Vector<U>& vec)
@@ -405,7 +412,8 @@ const Vector<Offset<T>> *VectorCast(const Vector<Offset<U>> *ptr) {
// Convenient helper function to get the length of any vector, regardless // Convenient helper function to get the length of any vector, regardless
// of whether it is null or not (the field is not set). // of whether it is null or not (the field is not set).
template<typename T> static inline size_t VectorLength(const Vector<T> *v) { template <typename T>
static inline size_t VectorLength(const Vector<T>* v) {
return v ? v->size() : 0; return v ? v->size() : 0;
} }

View File

@@ -32,7 +32,8 @@ namespace flatbuffers {
// Since this vector leaves the lower part unused, we support a "scratch-pad" // Since this vector leaves the lower part unused, we support a "scratch-pad"
// that can be stored there for temporary data, to share the allocated space. // that can be stored there for temporary data, to share the allocated space.
// Essentially, this supports 2 std::vectors in a single buffer. // Essentially, this supports 2 std::vectors in a single buffer.
template<typename SizeT = uoffset_t> class vector_downward { template <typename SizeT = uoffset_t>
class vector_downward {
public: public:
explicit vector_downward(size_t initial_size, Allocator* allocator, explicit vector_downward(size_t initial_size, Allocator* allocator,
bool own_allocator, size_t buffer_minalign, bool own_allocator, size_t buffer_minalign,
@@ -101,7 +102,9 @@ template<typename SizeT = uoffset_t> class vector_downward {
void clear_scratch() { scratch_ = buf_; } void clear_scratch() { scratch_ = buf_; }
void clear_allocator() { void clear_allocator() {
if (own_allocator_ && allocator_) { delete allocator_; } if (own_allocator_ && allocator_) {
delete allocator_;
}
allocator_ = nullptr; allocator_ = nullptr;
own_allocator_ = false; own_allocator_ = false;
} }
@@ -142,7 +145,9 @@ template<typename SizeT = uoffset_t> class vector_downward {
FLATBUFFERS_ASSERT(cur_ >= scratch_ && scratch_ >= buf_); FLATBUFFERS_ASSERT(cur_ >= scratch_ && scratch_ >= buf_);
// If the length is larger than the unused part of the buffer, we need to // If the length is larger than the unused part of the buffer, we need to
// grow. // grow.
if (len > unused_buffer_size()) { reallocate(len); } if (len > unused_buffer_size()) {
reallocate(len);
}
FLATBUFFERS_ASSERT(size() < max_size_); FLATBUFFERS_ASSERT(size() < max_size_);
return len; return len;
} }
@@ -193,16 +198,20 @@ template<typename SizeT = uoffset_t> class vector_downward {
uint8_t* data_at(size_t offset) const { return buf_ + reserved_ - offset; } uint8_t* data_at(size_t offset) const { return buf_ + reserved_ - offset; }
void push(const uint8_t* bytes, size_t num) { void push(const uint8_t* bytes, size_t num) {
if (num > 0) { memcpy(make_space(num), bytes, num); } if (num > 0) {
memcpy(make_space(num), bytes, num);
}
} }
// Specialized version of push() that avoids memcpy call for small data. // Specialized version of push() that avoids memcpy call for small data.
template<typename T> void push_small(const T &little_endian_t) { template <typename T>
void push_small(const T& little_endian_t) {
make_space(sizeof(T)); make_space(sizeof(T));
*reinterpret_cast<T*>(cur_) = little_endian_t; *reinterpret_cast<T*>(cur_) = little_endian_t;
} }
template<typename T> void scratch_push_small(const T &t) { template <typename T>
void scratch_push_small(const T& t) {
ensure_space(sizeof(T)); ensure_space(sizeof(T));
*reinterpret_cast<T*>(scratch_) = t; *reinterpret_cast<T*>(scratch_) = t;
scratch_ += sizeof(T); scratch_ += sizeof(T);

View File

@@ -91,7 +91,8 @@ class VerifierTemplate FLATBUFFERS_FINAL_CLASS {
} }
// Verify a range indicated by sizeof(T). // Verify a range indicated by sizeof(T).
template<typename T> bool Verify(const size_t elem) const { template <typename T>
bool Verify(const size_t elem) const {
return VerifyAlignment(elem, sizeof(T)) && Verify(elem, sizeof(T)); return VerifyAlignment(elem, sizeof(T)) && Verify(elem, sizeof(T));
} }
@@ -114,7 +115,8 @@ class VerifierTemplate FLATBUFFERS_FINAL_CLASS {
} }
// Verify a pointer (may be NULL) of a table type. // Verify a pointer (may be NULL) of a table type.
template<typename T> bool VerifyTable(const T *const table) { template <typename T>
bool VerifyTable(const T* const table) {
return !table || table->Verify(*this); return !table || table->Verify(*this);
} }
@@ -240,9 +242,13 @@ class VerifierTemplate FLATBUFFERS_FINAL_CLASS {
} }
// Verify this whole buffer, starting with root type T. // Verify this whole buffer, starting with root type T.
template<typename T> bool VerifyBuffer() { return VerifyBuffer<T>(nullptr); } template <typename T>
bool VerifyBuffer() {
return VerifyBuffer<T>(nullptr);
}
template<typename T> bool VerifyBuffer(const char *const identifier) { template <typename T>
bool VerifyBuffer(const char* const identifier) {
return VerifyBufferFromStart<T>(identifier, 0); return VerifyBufferFromStart<T>(identifier, 0);
} }

View File

@@ -37,8 +37,8 @@ int main(int /*argc*/, const char * /*argv*/[]) {
return 1; return 1;
} }
const char *include_directories[] = { "samples", "tests", const char* include_directories[] = {"samples", "tests", "tests/include_test",
"tests/include_test", nullptr }; nullptr};
// parse fbs schema // parse fbs schema
flatbuffers::Parser parser1; flatbuffers::Parser parser1;
ok = parser1.Parse(schema_file.c_str(), include_directories); ok = parser1.Parse(schema_file.c_str(), include_directories);

View File

@@ -30,18 +30,30 @@ struct OutputConfig {
static std::string ToString(const BinarySectionType type) { static std::string ToString(const BinarySectionType type) {
switch (type) { switch (type) {
case BinarySectionType::Header: return "header"; case BinarySectionType::Header:
case BinarySectionType::Table: return "table"; return "header";
case BinarySectionType::RootTable: return "root_table"; case BinarySectionType::Table:
case BinarySectionType::VTable: return "vtable"; return "table";
case BinarySectionType::Struct: return "struct"; case BinarySectionType::RootTable:
case BinarySectionType::String: return "string"; return "root_table";
case BinarySectionType::Vector: return "vector"; case BinarySectionType::VTable:
case BinarySectionType::Vector64: return "vector64"; return "vtable";
case BinarySectionType::Unknown: return "unknown"; case BinarySectionType::Struct:
case BinarySectionType::Union: return "union"; return "struct";
case BinarySectionType::Padding: return "padding"; case BinarySectionType::String:
default: return "todo"; return "string";
case BinarySectionType::Vector:
return "vector";
case BinarySectionType::Vector64:
return "vector64";
case BinarySectionType::Unknown:
return "unknown";
case BinarySectionType::Union:
return "union";
case BinarySectionType::Padding:
return "padding";
default:
return "todo";
} }
} }
@@ -51,7 +63,8 @@ static bool IsOffset(const BinaryRegionType type) {
type == BinaryRegionType::UOffset64; type == BinaryRegionType::UOffset64;
} }
template<typename T> std::string ToString(T value) { template <typename T>
std::string ToString(T value) {
if (std::is_floating_point<T>::value) { if (std::is_floating_point<T>::value) {
std::stringstream ss; std::stringstream ss;
ss << value; ss << value;
@@ -106,21 +119,31 @@ static std::string ToValueString(const BinaryRegion &region,
switch (region.type) { switch (region.type) {
case BinaryRegionType::Uint32: case BinaryRegionType::Uint32:
return ToValueString<uint32_t>(region, binary); return ToValueString<uint32_t>(region, binary);
case BinaryRegionType::Int32: return ToValueString<int32_t>(region, binary); case BinaryRegionType::Int32:
return ToValueString<int32_t>(region, binary);
case BinaryRegionType::Uint16: case BinaryRegionType::Uint16:
return ToValueString<uint16_t>(region, binary); return ToValueString<uint16_t>(region, binary);
case BinaryRegionType::Int16: return ToValueString<int16_t>(region, binary); case BinaryRegionType::Int16:
case BinaryRegionType::Bool: return ToValueString<bool>(region, binary); return ToValueString<int16_t>(region, binary);
case BinaryRegionType::Uint8: return ToValueString<uint8_t>(region, binary); case BinaryRegionType::Bool:
case BinaryRegionType::Char: return ToValueString<char>(region, binary); return ToValueString<bool>(region, binary);
case BinaryRegionType::Uint8:
return ToValueString<uint8_t>(region, binary);
case BinaryRegionType::Char:
return ToValueString<char>(region, binary);
case BinaryRegionType::Byte: case BinaryRegionType::Byte:
case BinaryRegionType::Int8: return ToValueString<int8_t>(region, binary); case BinaryRegionType::Int8:
case BinaryRegionType::Int64: return ToValueString<int64_t>(region, binary); return ToValueString<int8_t>(region, binary);
case BinaryRegionType::Int64:
return ToValueString<int64_t>(region, binary);
case BinaryRegionType::Uint64: case BinaryRegionType::Uint64:
return ToValueString<uint64_t>(region, binary); return ToValueString<uint64_t>(region, binary);
case BinaryRegionType::Double: return ToValueString<double>(region, binary); case BinaryRegionType::Double:
case BinaryRegionType::Float: return ToValueString<float>(region, binary); return ToValueString<double>(region, binary);
case BinaryRegionType::UType: return ToValueString<uint8_t>(region, binary); case BinaryRegionType::Float:
return ToValueString<float>(region, binary);
case BinaryRegionType::UType:
return ToValueString<uint8_t>(region, binary);
// Handle Offsets separately, incase they add additional details. // Handle Offsets separately, incase they add additional details.
case BinaryRegionType::UOffset64: case BinaryRegionType::UOffset64:
@@ -136,7 +159,8 @@ static std::string ToValueString(const BinaryRegion &region,
s += ToValueString<uint16_t>(region, binary); s += ToValueString<uint16_t>(region, binary);
break; break;
default: break; default:
break;
} }
// If this is an offset type, include the calculated offset location in the // If this is an offset type, include the calculated offset location in the
// value. // value.
@@ -167,15 +191,25 @@ static std::string GenerateComment(const BinaryRegionComment &comment,
const BinarySection&) { const BinarySection&) {
std::string s; std::string s;
switch (comment.type) { switch (comment.type) {
case BinaryRegionCommentType::Unknown: s = "unknown"; break; case BinaryRegionCommentType::Unknown:
case BinaryRegionCommentType::SizePrefix: s = "size prefix"; break; s = "unknown";
break;
case BinaryRegionCommentType::SizePrefix:
s = "size prefix";
break;
case BinaryRegionCommentType::RootTableOffset: case BinaryRegionCommentType::RootTableOffset:
s = "offset to root table `" + comment.name + "`"; s = "offset to root table `" + comment.name + "`";
break; break;
// TODO(dbaileychess): make this lowercase to follow the convention. // TODO(dbaileychess): make this lowercase to follow the convention.
case BinaryRegionCommentType::FileIdentifier: s = "File Identifier"; break; case BinaryRegionCommentType::FileIdentifier:
case BinaryRegionCommentType::Padding: s = "padding"; break; s = "File Identifier";
case BinaryRegionCommentType::VTableSize: s = "size of this vtable"; break; break;
case BinaryRegionCommentType::Padding:
s = "padding";
break;
case BinaryRegionCommentType::VTableSize:
s = "size of this vtable";
break;
case BinaryRegionCommentType::VTableRefferingTableLength: case BinaryRegionCommentType::VTableRefferingTableLength:
s = "size of referring table"; s = "size of referring table";
break; break;
@@ -192,7 +226,9 @@ static std::string GenerateComment(const BinaryRegionComment &comment,
case BinaryRegionCommentType::TableField: case BinaryRegionCommentType::TableField:
s = "table field `" + comment.name; s = "table field `" + comment.name;
break; break;
case BinaryRegionCommentType::TableUnknownField: s = "unknown field"; break; case BinaryRegionCommentType::TableUnknownField:
s = "unknown field";
break;
case BinaryRegionCommentType::TableOffsetField: case BinaryRegionCommentType::TableOffsetField:
s = "offset to field `" + comment.name + "`"; s = "offset to field `" + comment.name + "`";
break; break;
@@ -203,8 +239,12 @@ static std::string GenerateComment(const BinaryRegionComment &comment,
s = "array field `" + comment.name + "`[" + s = "array field `" + comment.name + "`[" +
std::to_string(comment.index) + "]"; std::to_string(comment.index) + "]";
break; break;
case BinaryRegionCommentType::StringLength: s = "length of string"; break; case BinaryRegionCommentType::StringLength:
case BinaryRegionCommentType::StringValue: s = "string literal"; break; s = "length of string";
break;
case BinaryRegionCommentType::StringValue:
s = "string literal";
break;
case BinaryRegionCommentType::StringTerminator: case BinaryRegionCommentType::StringTerminator:
s = "string terminator"; s = "string terminator";
break; break;
@@ -224,13 +264,19 @@ static std::string GenerateComment(const BinaryRegionComment &comment,
s = "offset to union[" + std::to_string(comment.index) + "]"; s = "offset to union[" + std::to_string(comment.index) + "]";
break; break;
default: break; default:
break;
}
if (!comment.default_value.empty()) {
s += " " + comment.default_value;
} }
if (!comment.default_value.empty()) { s += " " + comment.default_value; }
switch (comment.status) { switch (comment.status) {
case BinaryRegionStatus::OK: break; // no-op case BinaryRegionStatus::OK:
case BinaryRegionStatus::WARN: s = "WARN: " + s; break; break; // no-op
case BinaryRegionStatus::WARN:
s = "WARN: " + s;
break;
case BinaryRegionStatus::WARN_NO_REFERENCES: case BinaryRegionStatus::WARN_NO_REFERENCES:
s = "WARN: nothing refers to this section."; s = "WARN: nothing refers to this section.";
break; break;
@@ -240,7 +286,9 @@ static std::string GenerateComment(const BinaryRegionComment &comment,
case BinaryRegionStatus::WARN_PADDING_LENGTH: case BinaryRegionStatus::WARN_PADDING_LENGTH:
s = "WARN: padding is longer than expected."; s = "WARN: padding is longer than expected.";
break; break;
case BinaryRegionStatus::ERROR: s = "ERROR: " + s; break; case BinaryRegionStatus::ERROR:
s = "ERROR: " + s;
break;
case BinaryRegionStatus::ERROR_OFFSET_OUT_OF_BINARY: case BinaryRegionStatus::ERROR_OFFSET_OUT_OF_BINARY:
s = "ERROR: " + s + ". Invalid offset, points outside the binary."; s = "ERROR: " + s + ". Invalid offset, points outside the binary.";
break; break;
@@ -369,7 +417,9 @@ static void GenerateSection(std::ostream &os, const BinarySection &section,
const OutputConfig& output_config) { const OutputConfig& output_config) {
os << std::endl; os << std::endl;
os << ToString(section.type); os << ToString(section.type);
if (!section.name.empty()) { os << " (" + section.name + ")"; } if (!section.name.empty()) {
os << " (" + section.name + ")";
}
os << ":"; os << ":";
// As a space saving measure, skip generating every vector element, just put // As a space saving measure, skip generating every vector element, just put

View File

@@ -83,7 +83,9 @@ class LuaBfbsGenerator : public BaseBfbsGenerator {
const CodeGenOptions& options) const CodeGenOptions& options)
FLATBUFFERS_OVERRIDE { FLATBUFFERS_OVERRIDE {
options_ = options; options_ = options;
if (!GenerateEnums(schema->enums())) { return ERROR; } if (!GenerateEnums(schema->enums())) {
return ERROR;
}
if (!GenerateObjects(schema->objects(), schema->root_table())) { if (!GenerateObjects(schema->objects(), schema->root_table())) {
return ERROR; return ERROR;
} }
@@ -217,7 +219,9 @@ class LuaBfbsGenerator : public BaseBfbsGenerator {
// Create all the field accessors. // Create all the field accessors.
ForAllFields(object, /*reverse=*/false, [&](const r::Field* field) { ForAllFields(object, /*reverse=*/false, [&](const r::Field* field) {
// Skip writing deprecated fields altogether. // Skip writing deprecated fields altogether.
if (field->deprecated()) { return; } if (field->deprecated()) {
return;
}
const std::string field_name = namer_.Field(*field); const std::string field_name = namer_.Field(*field);
const r::BaseType base_type = field->type()->base_type(); const r::BaseType base_type = field->type()->base_type();
@@ -247,7 +251,9 @@ class LuaBfbsGenerator : public BaseBfbsGenerator {
std::string getter = std::string getter =
GenerateGetter(field->type()) + "self.view.pos + o)"; GenerateGetter(field->type()) + "self.view.pos + o)";
if (IsBool(base_type)) { getter = "(" + getter + " ~=0)"; } if (IsBool(base_type)) {
getter = "(" + getter + " ~=0)";
}
code += " return " + getter + "\n"; code += " return " + getter + "\n";
code += " end\n"; code += " end\n";
code += " return " + DefaultValue(field) + "\n"; code += " return " + DefaultValue(field) + "\n";
@@ -409,7 +415,9 @@ class LuaBfbsGenerator : public BaseBfbsGenerator {
code += "\n"; code += "\n";
ForAllFields(object, /*reverse=*/false, [&](const r::Field* field) { ForAllFields(object, /*reverse=*/false, [&](const r::Field* field) {
if (field->deprecated()) { return; } if (field->deprecated()) {
return;
}
const std::string field_name = namer_.Field(*field); const std::string field_name = namer_.Field(*field);
const std::string variable_name = namer_.Variable(*field); const std::string variable_name = namer_.Variable(*field);
@@ -455,8 +463,8 @@ class LuaBfbsGenerator : public BaseBfbsGenerator {
private: private:
void GenerateDocumentation( void GenerateDocumentation(
const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>*
*documentation, documentation,
std::string indent, std::string& code) const { std::string indent, std::string& code) const {
flatbuffers::ForAllDocumentation( flatbuffers::ForAllDocumentation(
documentation, [&](const flatbuffers::String* str) { documentation, [&](const flatbuffers::String* str) {
@@ -507,17 +515,24 @@ class LuaBfbsGenerator : public BaseBfbsGenerator {
std::string GenerateMethod(const r::Field* field) const { std::string GenerateMethod(const r::Field* field) const {
const r::BaseType base_type = field->type()->base_type(); const r::BaseType base_type = field->type()->base_type();
if (IsScalar(base_type)) { return namer_.Type(GenerateType(base_type)); } if (IsScalar(base_type)) {
if (IsStructOrTable(base_type)) { return "Struct"; } return namer_.Type(GenerateType(base_type));
}
if (IsStructOrTable(base_type)) {
return "Struct";
}
return "UOffsetTRelative"; return "UOffsetTRelative";
} }
std::string GenerateGetter(const r::Type* type, std::string GenerateGetter(const r::Type* type,
bool element_type = false) const { bool element_type = false) const {
switch (element_type ? type->element() : type->base_type()) { switch (element_type ? type->element() : type->base_type()) {
case r::String: return "self.view:String("; case r::String:
case r::Union: return "self.view:Union("; return "self.view:String(";
case r::Vector: return GenerateGetter(type, true); case r::Union:
return "self.view:Union(";
case r::Vector:
return GenerateGetter(type, true);
default: default:
return "self.view:Get(flatbuffers.N." + return "self.view:Get(flatbuffers.N." +
namer_.Type(GenerateType(type, element_type)) + ", "; namer_.Type(GenerateType(type, element_type)) + ", ";
@@ -528,13 +543,19 @@ class LuaBfbsGenerator : public BaseBfbsGenerator {
bool element_type = false) const { bool element_type = false) const {
const r::BaseType base_type = const r::BaseType base_type =
element_type ? type->element() : type->base_type(); element_type ? type->element() : type->base_type();
if (IsScalar(base_type)) { return GenerateType(base_type); } if (IsScalar(base_type)) {
return GenerateType(base_type);
}
switch (base_type) { switch (base_type) {
case r::String: return "string"; case r::String:
case r::Vector: return GenerateGetter(type, true); return "string";
case r::Obj: return namer_.Type(namer_.Denamespace(GetObject(type))); case r::Vector:
return GenerateGetter(type, true);
case r::Obj:
return namer_.Type(namer_.Denamespace(GetObject(type)));
default: return "*flatbuffers.Table"; default:
return "*flatbuffers.Table";
} }
} }
@@ -542,19 +563,32 @@ class LuaBfbsGenerator : public BaseBfbsGenerator {
// Need to override the default naming to match the Lua runtime libraries. // Need to override the default naming to match the Lua runtime libraries.
// TODO(derekbailey): make overloads in the runtime libraries to avoid this. // TODO(derekbailey): make overloads in the runtime libraries to avoid this.
switch (base_type) { switch (base_type) {
case r::None: return "uint8"; case r::None:
case r::UType: return "uint8"; return "uint8";
case r::Byte: return "int8"; case r::UType:
case r::UByte: return "uint8"; return "uint8";
case r::Short: return "int16"; case r::Byte:
case r::UShort: return "uint16"; return "int8";
case r::Int: return "int32"; case r::UByte:
case r::UInt: return "uint32"; return "uint8";
case r::Long: return "int64"; case r::Short:
case r::ULong: return "uint64"; return "int16";
case r::Float: return "Float32"; case r::UShort:
case r::Double: return "Float64"; return "uint16";
default: return r::EnumNameBaseType(base_type); case r::Int:
return "int32";
case r::UInt:
return "uint32";
case r::Long:
return "int64";
case r::ULong:
return "uint64";
case r::Float:
return "Float32";
case r::Double:
return "Float64";
default:
return r::EnumNameBaseType(base_type);
} }
} }
@@ -566,7 +600,9 @@ class LuaBfbsGenerator : public BaseBfbsGenerator {
if (IsBool(base_type)) { if (IsBool(base_type)) {
return field->default_integer() ? "true" : "false"; return field->default_integer() ? "true" : "false";
} }
if (IsScalar(base_type)) { return NumToString((field->default_integer())); } if (IsScalar(base_type)) {
return NumToString((field->default_integer()));
}
// represents offsets // represents offsets
return "0"; return "0";
} }
@@ -592,11 +628,15 @@ class LuaBfbsGenerator : public BaseBfbsGenerator {
if (IsStructOrTable(type)) { if (IsStructOrTable(type)) {
const r::Object* object = GetObjectByIndex(field->type()->index()); const r::Object* object = GetObjectByIndex(field->type()->index());
if (object == current_obj_) { return namer_.Denamespace(object); } if (object == current_obj_) {
return namer_.Denamespace(object);
}
type_name = object->name()->str(); type_name = object->name()->str();
} else { } else {
const r::Enum* enum_def = GetEnumByIndex(field->type()->index()); const r::Enum* enum_def = GetEnumByIndex(field->type()->index());
if (enum_def == current_enum_) { return namer_.Denamespace(enum_def); } if (enum_def == current_enum_) {
return namer_.Denamespace(enum_def);
}
type_name = enum_def->name()->str(); type_name = enum_def->name()->str();
} }

View File

@@ -81,8 +81,7 @@ const std::string Export = "*";
const std::set<std::string> builtin_types = { const std::set<std::string> builtin_types = {
"uint8", "uint8", "bool", "int8", "uint8", "int16", "uint8", "uint8", "bool", "int8", "uint8", "int16",
"uint16", "int32", "uint32", "int64", "uint64", "float32", "uint16", "int32", "uint32", "int64", "uint64", "float32",
"float64", "string", "int", "uint", "uoffset", "Builder" "float64", "string", "int", "uint", "uoffset", "Builder"};
};
class NimBfbsGenerator : public BaseBfbsGenerator { class NimBfbsGenerator : public BaseBfbsGenerator {
public: public:
@@ -195,7 +194,9 @@ class NimBfbsGenerator : public BaseBfbsGenerator {
// Create all the field accessors. // Create all the field accessors.
ForAllFields(object, /*reverse=*/false, [&](const r::Field* field) { ForAllFields(object, /*reverse=*/false, [&](const r::Field* field) {
// Skip writing deprecated fields altogether. // Skip writing deprecated fields altogether.
if (field->deprecated()) { return; } if (field->deprecated()) {
return;
}
const std::string field_name = namer_.Field(*field); const std::string field_name = namer_.Field(*field);
const r::BaseType base_type = field->type()->base_type(); const r::BaseType base_type = field->type()->base_type();
@@ -256,7 +257,9 @@ class NimBfbsGenerator : public BaseBfbsGenerator {
} }
} }
code += getter_signature + getter_code; code += getter_signature + getter_code;
if (IsScalar(base_type)) { code += setter_signature + setter_code; } if (IsScalar(base_type)) {
code += setter_signature + setter_code;
}
} else if (base_type == r::Array || base_type == r::Vector) { } else if (base_type == r::Array || base_type == r::Vector) {
const r::BaseType vector_base_type = field->type()->element(); const r::BaseType vector_base_type = field->type()->element();
uint32_t element_size = field->type()->element_size(); uint32_t element_size = field->type()->element_size();
@@ -310,7 +313,9 @@ class NimBfbsGenerator : public BaseBfbsGenerator {
")\n"; ")\n";
ForAllFields(object, /*reverse=*/false, [&](const r::Field* field) { ForAllFields(object, /*reverse=*/false, [&](const r::Field* field) {
if (field->deprecated()) { return; } if (field->deprecated()) {
return;
}
const std::string field_name = namer_.Field(*field); const std::string field_name = namer_.Field(*field);
const std::string variable_name = namer_.Variable(*field); const std::string variable_name = namer_.Variable(*field);
@@ -348,8 +353,8 @@ class NimBfbsGenerator : public BaseBfbsGenerator {
private: private:
void GenerateDocumentation( void GenerateDocumentation(
const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>*
*documentation, documentation,
std::string indent, std::string& code) const { std::string indent, std::string& code) const {
flatbuffers::ForAllDocumentation( flatbuffers::ForAllDocumentation(
documentation, [&](const flatbuffers::String* str) { documentation, [&](const flatbuffers::String* str) {
@@ -400,7 +405,9 @@ class NimBfbsGenerator : public BaseBfbsGenerator {
std::string GenerateMethod(const r::Field* field) const { std::string GenerateMethod(const r::Field* field) const {
const r::BaseType base_type = field->type()->base_type(); const r::BaseType base_type = field->type()->base_type();
if (IsStructOrTable(base_type)) { return "Struct"; } if (IsStructOrTable(base_type)) {
return "Struct";
}
return ""; return "";
} }
@@ -409,15 +416,20 @@ class NimBfbsGenerator : public BaseBfbsGenerator {
const r::BaseType base_type = const r::BaseType base_type =
element_type ? type->element() : type->base_type(); element_type ? type->element() : type->base_type();
std::string offset = offsetval; std::string offset = offsetval;
if (!element_type) { offset = "self.tab.Pos + " + offset; } if (!element_type) {
offset = "self.tab.Pos + " + offset;
}
switch (base_type) { switch (base_type) {
case r::String: return "self.tab.String(" + offset + ")"; case r::String:
case r::Union: return "self.tab.Union(" + offsetval + ")"; return "self.tab.String(" + offset + ")";
case r::Union:
return "self.tab.Union(" + offsetval + ")";
case r::Obj: { case r::Obj: {
return GenerateType(type, element_type) + return GenerateType(type, element_type) +
"(tab: Vtable(Bytes: self.tab.Bytes, Pos: " + offset + "))"; "(tab: Vtable(Bytes: self.tab.Bytes, Pos: " + offset + "))";
} }
case r::Vector: return GenerateGetter(type, offsetval, true); case r::Vector:
return GenerateGetter(type, offsetval, true);
default: default:
const r::Enum* type_enum = GetEnum(type, element_type); const r::Enum* type_enum = GetEnum(type, element_type);
if (type_enum != nullptr) { if (type_enum != nullptr) {
@@ -432,7 +444,9 @@ class NimBfbsGenerator : public BaseBfbsGenerator {
std::string Denamespace(const std::string& s, std::string& importns, std::string Denamespace(const std::string& s, std::string& importns,
std::string& ns) const { std::string& ns) const {
if (builtin_types.find(s) != builtin_types.end()) { return s; } if (builtin_types.find(s) != builtin_types.end()) {
return s;
}
std::string type = namer_.Type(namer_.Denamespace(s, ns)); std::string type = namer_.Type(namer_.Denamespace(s, ns));
importns = ns.empty() ? type : ns + "." + type; importns = ns.empty() ? type : ns + "." + type;
std::replace(importns.begin(), importns.end(), '.', '_'); std::replace(importns.begin(), importns.end(), '.', '_');
@@ -461,13 +475,17 @@ class NimBfbsGenerator : public BaseBfbsGenerator {
return importns + "." + type_name; return importns + "." + type_name;
} }
} }
if (IsScalar(base_type)) { return Denamespace(GenerateType(base_type)); } if (IsScalar(base_type)) {
return Denamespace(GenerateType(base_type));
}
switch (base_type) { switch (base_type) {
case r::String: return "string"; case r::String:
return "string";
case r::Vector: { case r::Vector: {
return "seq[" + GenerateType(type, true) + "]"; return "seq[" + GenerateType(type, true) + "]";
} }
case r::Union: return "Vtable"; case r::Union:
return "Vtable";
case r::Obj: { case r::Obj: {
const r::Object* type_obj = GetObject(type, element_type); const r::Object* type_obj = GetObject(type, element_type);
std::string importns; std::string importns;
@@ -478,7 +496,8 @@ class NimBfbsGenerator : public BaseBfbsGenerator {
return importns + "." + type_name; return importns + "." + type_name;
} }
} }
default: return "uoffset"; default:
return "uoffset";
} }
} }
@@ -495,21 +514,36 @@ class NimBfbsGenerator : public BaseBfbsGenerator {
std::string GenerateType(const r::BaseType base_type) const { std::string GenerateType(const r::BaseType base_type) const {
switch (base_type) { switch (base_type) {
case r::None: return "uint8"; case r::None:
case r::UType: return "uint8"; return "uint8";
case r::Bool: return "bool"; case r::UType:
case r::Byte: return "int8"; return "uint8";
case r::UByte: return "uint8"; case r::Bool:
case r::Short: return "int16"; return "bool";
case r::UShort: return "uint16"; case r::Byte:
case r::Int: return "int32"; return "int8";
case r::UInt: return "uint32"; case r::UByte:
case r::Long: return "int64"; return "uint8";
case r::ULong: return "uint64"; case r::Short:
case r::Float: return "float32"; return "int16";
case r::Double: return "float64"; case r::UShort:
case r::String: return "string"; return "uint16";
default: return r::EnumNameBaseType(base_type); case r::Int:
return "int32";
case r::UInt:
return "uint32";
case r::Long:
return "int64";
case r::ULong:
return "uint64";
case r::Float:
return "float32";
case r::Double:
return "float64";
case r::String:
return "string";
default:
return r::EnumNameBaseType(base_type);
} }
} }
@@ -537,7 +571,9 @@ class NimBfbsGenerator : public BaseBfbsGenerator {
} }
return NumToString((field->default_integer())); return NumToString((field->default_integer()));
} }
if (base_type == r::String) { return "\"\""; } if (base_type == r::String) {
return "\"\"";
}
// represents offsets // represents offsets
return "0"; return "0";
} }
@@ -592,7 +628,9 @@ class NimBfbsGenerator : public BaseBfbsGenerator {
std::string new_path; std::string new_path;
for (size_t i = 0; i < str2_vec.size(); ++i) { for (size_t i = 0; i < str2_vec.size(); ++i) {
new_path += str2_vec[i]; new_path += str2_vec[i];
if (i != str2_vec.size() - 1) { new_path += "/"; } if (i != str2_vec.size() - 1) {
new_path += "/";
}
} }
return new_path; return new_path;
} }
@@ -607,13 +645,17 @@ class NimBfbsGenerator : public BaseBfbsGenerator {
if (IsStructOrTable(type)) { if (IsStructOrTable(type)) {
const r::Object* object_def = GetObjectByIndex(field->type()->index()); const r::Object* object_def = GetObjectByIndex(field->type()->index());
if (object_def == current_obj_) { return; } if (object_def == current_obj_) {
return;
}
std::string ns; std::string ns;
type_name = Denamespace(object_def->name()->str(), importns, ns); type_name = Denamespace(object_def->name()->str(), importns, ns);
type_name = ns.empty() ? type_name : ns + "." + type_name; type_name = ns.empty() ? type_name : ns + "." + type_name;
} else { } else {
const r::Enum* enum_def = GetEnumByIndex(field->type()->index()); const r::Enum* enum_def = GetEnumByIndex(field->type()->index());
if (enum_def == current_enum_) { return; } if (enum_def == current_enum_) {
return;
}
std::string ns; std::string ns;
type_name = Denamespace(enum_def->name()->str(), importns, ns); type_name = Denamespace(enum_def->name()->str(), importns, ns);
type_name = ns.empty() ? type_name : ns + "." + type_name; type_name = ns.empty() ? type_name : ns + "." + type_name;

View File

@@ -61,7 +61,9 @@ static BinarySection MakeSingleRegionBinarySection(const std::string &name,
static bool IsNonZeroRegion(const uint64_t offset, const uint64_t length, static bool IsNonZeroRegion(const uint64_t offset, const uint64_t length,
const uint8_t* const binary) { const uint8_t* const binary) {
for (uint64_t i = offset; i < offset + length; ++i) { for (uint64_t i = offset; i < offset + length; ++i) {
if (binary[i] != 0) { return true; } if (binary[i] != 0) {
return true;
}
} }
return false; return false;
} }
@@ -69,7 +71,9 @@ static bool IsNonZeroRegion(const uint64_t offset, const uint64_t length,
static bool IsPrintableRegion(const uint64_t offset, const uint64_t length, static bool IsPrintableRegion(const uint64_t offset, const uint64_t length,
const uint8_t* const binary) { const uint8_t* const binary) {
for (uint64_t i = offset; i < offset + length; ++i) { for (uint64_t i = offset; i < offset + length; ++i) {
if (!isprint(binary[i])) { return false; } if (!isprint(binary[i])) {
return false;
}
} }
return true; return true;
} }
@@ -130,7 +134,9 @@ std::map<uint64_t, BinarySection> BinaryAnnotator::Annotate() {
} }
// The binary is too short to read as a flatbuffers. // The binary is too short to read as a flatbuffers.
if (binary_length_ < FLATBUFFERS_MIN_BUFFER_SIZE) { return {}; } if (binary_length_ < FLATBUFFERS_MIN_BUFFER_SIZE) {
return {};
}
// Make sure we start with a clean slate. // Make sure we start with a clean slate.
vtables_.clear(); vtables_.clear();
@@ -242,12 +248,16 @@ BinaryAnnotator::VTable *BinaryAnnotator::GetOrBuildVTable(
// See if this vtable for the table type has been generated before. // See if this vtable for the table type has been generated before.
for (VTable& vtable : vtables) { for (VTable& vtable : vtables) {
if (vtable.referring_table == table) { return &vtable; } if (vtable.referring_table == table) {
return &vtable;
}
} }
// If we are trying to make a new vtable and it is already encompassed by // If we are trying to make a new vtable and it is already encompassed by
// another binary section, something is corrupted. // another binary section, something is corrupted.
if (vtables.empty() && ContainsSection(vtable_offset)) { return nullptr; } if (vtables.empty() && ContainsSection(vtable_offset)) {
return nullptr;
}
const std::string referring_table_name = table->name()->str(); const std::string referring_table_name = table->name()->str();
@@ -498,7 +508,9 @@ BinaryAnnotator::VTable *BinaryAnnotator::GetOrBuildVTable(
void BinaryAnnotator::BuildTable(const uint64_t table_offset, void BinaryAnnotator::BuildTable(const uint64_t table_offset,
const BinarySectionType type, const BinarySectionType type,
const reflection::Object* const table) { const reflection::Object* const table) {
if (ContainsSection(table_offset)) { return; } if (ContainsSection(table_offset)) {
return;
}
BinaryRegionComment vtable_offset_comment; BinaryRegionComment vtable_offset_comment;
vtable_offset_comment.type = BinaryRegionCommentType::TableVTableOffset; vtable_offset_comment.type = BinaryRegionCommentType::TableVTableOffset;
@@ -610,7 +622,9 @@ void BinaryAnnotator::BuildTable(const uint64_t table_offset,
: table_end_offset) - : table_end_offset) -
field_offset; field_offset;
if (unknown_field_length == 0) { continue; } if (unknown_field_length == 0) {
continue;
}
std::string hint; std::string hint;
@@ -830,7 +844,8 @@ void BinaryAnnotator::BuildTable(const uint64_t table_offset,
} break; } break;
default: break; default:
break;
} }
} }
@@ -858,7 +873,9 @@ uint64_t BinaryAnnotator::BuildStruct(const uint64_t struct_offset,
std::vector<BinaryRegion>& regions, std::vector<BinaryRegion>& regions,
const std::string referring_field_name, const std::string referring_field_name,
const reflection::Object* const object) { const reflection::Object* const object) {
if (!object->is_struct()) { return struct_offset; } if (!object->is_struct()) {
return struct_offset;
}
uint64_t offset = struct_offset; uint64_t offset = struct_offset;
// Loop over all the fields in increasing order // Loop over all the fields in increasing order
@@ -975,7 +992,9 @@ void BinaryAnnotator::BuildString(const uint64_t string_offset,
const reflection::Field* const field) { const reflection::Field* const field) {
// Check if we have already generated this string section, and this is a // Check if we have already generated this string section, and this is a
// shared string instance. // shared string instance.
if (ContainsSection(string_offset)) { return; } if (ContainsSection(string_offset)) {
return;
}
std::vector<BinaryRegion> regions; std::vector<BinaryRegion> regions;
const auto string_length = ReadScalar<uint32_t>(string_offset); const auto string_length = ReadScalar<uint32_t>(string_offset);
@@ -1037,7 +1056,9 @@ void BinaryAnnotator::BuildVector(
const uint64_t vector_offset, const reflection::Object* const table, const uint64_t vector_offset, const reflection::Object* const table,
const reflection::Field* const field, const uint64_t parent_table_offset, const reflection::Field* const field, const uint64_t parent_table_offset,
const std::map<uint16_t, VTable::Entry> vtable_fields) { const std::map<uint16_t, VTable::Entry> vtable_fields) {
if (ContainsSection(vector_offset)) { return; } if (ContainsSection(vector_offset)) {
return;
}
BinaryRegionComment vector_length_comment; BinaryRegionComment vector_length_comment;
vector_length_comment.type = BinaryRegionCommentType::VectorLength; vector_length_comment.type = BinaryRegionCommentType::VectorLength;
@@ -1052,13 +1073,17 @@ void BinaryAnnotator::BuildVector(
if (is_64_bit_vector) { if (is_64_bit_vector) {
auto v = ReadScalar<uint64_t>(vector_offset); auto v = ReadScalar<uint64_t>(vector_offset);
if (v.has_value()) { vector_length = v.value(); } if (v.has_value()) {
vector_length = v.value();
}
vector_length_size_type = sizeof(uint64_t); vector_length_size_type = sizeof(uint64_t);
region_type = BinaryRegionType::Uint64; region_type = BinaryRegionType::Uint64;
section_type = BinarySectionType::Vector64; section_type = BinarySectionType::Vector64;
} else { } else {
auto v = ReadScalar<uint32_t>(vector_offset); auto v = ReadScalar<uint32_t>(vector_offset);
if (v.has_value()) { vector_length = v.value(); } if (v.has_value()) {
vector_length = v.value();
}
vector_length_size_type = sizeof(uint32_t); vector_length_size_type = sizeof(uint32_t);
region_type = BinaryRegionType::Uint32; region_type = BinaryRegionType::Uint32;
section_type = BinarySectionType::Vector; section_type = BinarySectionType::Vector;
@@ -1117,7 +1142,9 @@ void BinaryAnnotator::BuildVector(
// Structs are inline to the vector. // Structs are inline to the vector.
const uint64_t next_offset = const uint64_t next_offset =
BuildStruct(offset, regions, "[" + NumToString(i) + "]", object); BuildStruct(offset, regions, "[" + NumToString(i) + "]", object);
if (next_offset == offset) { break; } if (next_offset == offset) {
break;
}
offset = next_offset; offset = next_offset;
} }
} else { } else {
@@ -1388,7 +1415,9 @@ std::string BinaryAnnotator::BuildUnion(const uint64_t union_offset,
const reflection::EnumVal* enum_val = next_enum->values()->Get(realized_type); const reflection::EnumVal* enum_val = next_enum->values()->Get(realized_type);
if (ContainsSection(union_offset)) { return enum_val->name()->c_str(); } if (ContainsSection(union_offset)) {
return enum_val->name()->c_str();
}
const reflection::Type* union_type = enum_val->union_type(); const reflection::Type* union_type = enum_val->union_type();
@@ -1502,11 +1531,15 @@ void BinaryAnnotator::FixMissingSections() {
bool BinaryAnnotator::ContainsSection(const uint64_t offset) { bool BinaryAnnotator::ContainsSection(const uint64_t offset) {
auto it = sections_.lower_bound(offset); auto it = sections_.lower_bound(offset);
// If the section is found, check that it is exactly equal its offset. // If the section is found, check that it is exactly equal its offset.
if (it != sections_.end() && it->first == offset) { return true; } if (it != sections_.end() && it->first == offset) {
return true;
}
// If this was the first section, there are no other previous sections to // If this was the first section, there are no other previous sections to
// check. // check.
if (it == sections_.begin()) { return false; } if (it == sections_.begin()) {
return false;
}
// Go back one section. // Go back one section.
--it; --it;

View File

@@ -67,10 +67,14 @@ void CodeWriter::operator+=(std::string text) {
while (true) { while (true) {
auto begin = text.find("{{"); auto begin = text.find("{{");
if (begin == std::string::npos) { break; } if (begin == std::string::npos) {
break;
}
auto end = text.find("}}"); auto end = text.find("}}");
if (end == std::string::npos || end < begin) { break; } if (end == std::string::npos || end < begin) {
break;
}
// Write all the text before the first {{ into the stream. // Write all the text before the first {{ into the stream.
stream_.write(text.c_str(), begin); stream_.write(text.c_str(), begin);
@@ -235,8 +239,10 @@ std::string FloatConstantGenerator::GenFloatConstantImpl(
std::string FloatConstantGenerator::GenFloatConstant( std::string FloatConstantGenerator::GenFloatConstant(
const FieldDef& field) const { const FieldDef& field) const {
switch (field.value.type.base_type) { switch (field.value.type.base_type) {
case BASE_TYPE_FLOAT: return GenFloatConstantImpl<float>(field); case BASE_TYPE_FLOAT:
case BASE_TYPE_DOUBLE: return GenFloatConstantImpl<double>(field); return GenFloatConstantImpl<float>(field);
case BASE_TYPE_DOUBLE:
return GenFloatConstantImpl<double>(field);
default: { default: {
FLATBUFFERS_ASSERT(false); FLATBUFFERS_ASSERT(false);
return "INVALID_BASE_TYPE"; return "INVALID_BASE_TYPE";

View File

@@ -48,7 +48,9 @@ void FlatCompiler::ParseFile(
if (!parser.Parse(contents.c_str(), &inc_directories[0], filename.c_str())) { if (!parser.Parse(contents.c_str(), &inc_directories[0], filename.c_str())) {
Error(parser.error_, false, false); Error(parser.error_, false, false);
} }
if (!parser.error_.empty()) { Warn(parser.error_, false); } if (!parser.error_.empty()) {
Warn(parser.error_, false);
}
} }
void FlatCompiler::LoadBinarySchema(flatbuffers::Parser& parser, void FlatCompiler::LoadBinarySchema(flatbuffers::Parser& parser,
@@ -124,7 +126,8 @@ const static FlatCOption flatc_options[] = {
"Add @JvmStatic annotation for Kotlin methods in companion object for " "Add @JvmStatic annotation for Kotlin methods in companion object for "
"interop from Java to Kotlin."}, "interop from Java to Kotlin."},
{"", "gen-all", "", {"", "gen-all", "",
"Generate not just code for the current schema files, but for all files it " "Generate not just code for the current schema files, but for all files "
"it "
"includes as well. If the language uses a single file for output (by " "includes as well. If the language uses a single file for output (by "
"default the case for C++ and JS), all code will end up in this one " "default the case for C++ and JS), all code will end up in this one "
"file."}, "file."},
@@ -134,7 +137,8 @@ const static FlatCOption flatc_options[] = {
{"", "cpp-ptr-type", "T", {"", "cpp-ptr-type", "T",
"Set object API pointer type (default std::unique_ptr)."}, "Set object API pointer type (default std::unique_ptr)."},
{"", "cpp-str-type", "T", {"", "cpp-str-type", "T",
"Set object API string type (default std::string). T::c_str(), T::length() " "Set object API string type (default std::string). T::c_str(), "
"T::length() "
"and T::empty() must be supported. The custom type also needs to be " "and T::empty() must be supported. The custom type also needs to be "
"constructible from std::string (see the --cpp-str-flex-ctor option to " "constructible from std::string (see the --cpp-str-flex-ctor option to "
"change this behavior)"}, "change this behavior)"},
@@ -179,16 +183,19 @@ const static FlatCOption flatc_options[] = {
"'nop' - do not care about gap * 'warn' - A warning message will be shown " "'nop' - do not care about gap * 'warn' - A warning message will be shown "
"about the gap in protobuf ids" "about the gap in protobuf ids"
"(default) " "(default) "
"* 'error' - An error message will be shown and the fbs generation will be " "* 'error' - An error message will be shown and the fbs generation will "
"be "
"interrupted."}, "interrupted."},
{"", "grpc", "", "Generate GRPC interfaces for the specified languages."}, {"", "grpc", "", "Generate GRPC interfaces for the specified languages."},
{"", "schema", "", "Serialize schemas instead of JSON (use with -b)."}, {"", "schema", "", "Serialize schemas instead of JSON (use with -b)."},
{"", "bfbs-filenames", "PATH", {"", "bfbs-filenames", "PATH",
"Sets the root path where reflection filenames in reflection.fbs are " "Sets the root path where reflection filenames in reflection.fbs are "
"relative to. The 'root' is denoted with `//`. E.g. if PATH=/a/b/c " "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 " "then /a/d/e.fbs will be serialized as //../d/e.fbs. (PATH defaults to "
"the "
"directory of the first provided schema file."}, "directory of the first provided schema file."},
{ "", "bfbs-absolute-paths", "", "Uses absolute paths instead of relative paths in the BFBS output." }, {"", "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-comments", "", "Add doc comments to the binary schema files."},
{"", "bfbs-builtins", "", {"", "bfbs-builtins", "",
"Add builtin attributes to the binary schema files."}, "Add builtin attributes to the binary schema files."},
@@ -256,7 +263,8 @@ const static FlatCOption flatc_options[] = {
"Skip emission of Python functions that are prefixed with typenames"}, "Skip emission of Python functions that are prefixed with typenames"},
{"", "python-typing", "", "Generate Python type annotations"}, {"", "python-typing", "", "Generate Python type annotations"},
{"", "python-version", "", "Generate code for the given Python version."}, {"", "python-version", "", "Generate code for the given Python version."},
{ "", "python-decode-obj-api-strings", "", "Decode bytes to strings for the Python Object API"}, {"", "python-decode-obj-api-strings", "",
"Decode bytes to strings for the Python Object API"},
{"", "python-gen-numpy", "", "Whether to generate numpy helpers."}, {"", "python-gen-numpy", "", "Whether to generate numpy helpers."},
{"", "ts-omit-entrypoint", "", {"", "ts-omit-entrypoint", "",
"Omit emission of namespace entrypoint file"}, "Omit emission of namespace entrypoint file"},
@@ -341,9 +349,13 @@ static void AppendShortOption(std::stringstream &ss,
const FlatCOption& option) { const FlatCOption& option) {
if (!option.short_opt.empty()) { if (!option.short_opt.empty()) {
ss << "-" << option.short_opt; ss << "-" << option.short_opt;
if (!option.long_opt.empty()) { ss << "|"; } if (!option.long_opt.empty()) {
ss << "|";
}
}
if (!option.long_opt.empty()) {
ss << "--" << option.long_opt;
} }
if (!option.long_opt.empty()) { ss << "--" << option.long_opt; }
} }
std::string FlatCompiler::GetShortUsageString( std::string FlatCompiler::GetShortUsageString(
@@ -437,7 +449,9 @@ void FlatCompiler::AnnotateBinaries(const uint8_t *binary_schema,
FlatCOptions FlatCompiler::ParseFromCommandLineArguments(int argc, FlatCOptions FlatCompiler::ParseFromCommandLineArguments(int argc,
const char** argv) { const char** argv) {
if (argc <= 1) { Error("Need to provide at least one argument."); } if (argc <= 1) {
Error("Need to provide at least one argument.");
}
FlatCOptions options; FlatCOptions options;
@@ -741,7 +755,9 @@ FlatCOptions FlatCompiler::ParseFromCommandLineArguments(int argc,
arg == "--grpc-callback-api=false") { arg == "--grpc-callback-api=false") {
opts.grpc_callback_api = false; opts.grpc_callback_api = false;
} else { } else {
if (arg == "--proto") { opts.proto_mode = true; } if (arg == "--proto") {
opts.proto_mode = true;
}
auto code_generator_it = code_generators_.find(arg); auto code_generator_it = code_generators_.find(arg);
if (code_generator_it == code_generators_.end()) { if (code_generator_it == code_generators_.end()) {
@@ -1024,8 +1040,7 @@ int FlatCompiler::Compile(const FlatCOptions &options) {
Parser parser(binary_opts); Parser parser(binary_opts);
if (is_binary_schema) { if (is_binary_schema) {
binary_schema = binary_schema = reinterpret_cast<const uint8_t*>(schema_contents.c_str());
reinterpret_cast<const uint8_t *>(schema_contents.c_str());
binary_schema_size = schema_contents.size(); binary_schema_size = schema_contents.size();
} else { } else {
// If we need to generate the .bfbs file from the provided schema file // If we need to generate the .bfbs file from the provided schema file

View File

@@ -45,13 +45,17 @@ static const char *g_program_name = nullptr;
static void Warn(const flatbuffers::FlatCompiler* flatc, static void Warn(const flatbuffers::FlatCompiler* flatc,
const std::string& warn, bool show_exe_name) { const std::string& warn, bool show_exe_name) {
(void)flatc; (void)flatc;
if (show_exe_name) { printf("%s: ", g_program_name); } if (show_exe_name) {
printf("%s: ", g_program_name);
}
fprintf(stderr, "\nwarning:\n %s\n\n", warn.c_str()); fprintf(stderr, "\nwarning:\n %s\n\n", warn.c_str());
} }
static void Error(const flatbuffers::FlatCompiler* flatc, static void Error(const flatbuffers::FlatCompiler* flatc,
const std::string& err, bool usage, bool show_exe_name) { const std::string& err, bool usage, bool show_exe_name) {
if (show_exe_name) { printf("%s: ", g_program_name); } if (show_exe_name) {
printf("%s: ", g_program_name);
}
if (usage && flatc) { if (usage && flatc) {
fprintf(stderr, "%s\n", flatc->GetShortUsageString(g_program_name).c_str()); fprintf(stderr, "%s\n", flatc->GetShortUsageString(g_program_name).c_str());
} }
@@ -126,7 +130,8 @@ int main(int argc, const char *argv[]) {
flatbuffers::NewKotlinCodeGenerator()); flatbuffers::NewKotlinCodeGenerator());
flatc.RegisterCodeGenerator( flatc.RegisterCodeGenerator(
flatbuffers::FlatCOption{ "", "kotlin-kmp", "", flatbuffers::FlatCOption{
"", "kotlin-kmp", "",
"Generate Kotlin multiplatform classes for tables/structs"}, "Generate Kotlin multiplatform classes for tables/structs"},
flatbuffers::NewKotlinKMPCodeGenerator()); flatbuffers::NewKotlinKMPCodeGenerator());
@@ -161,8 +166,8 @@ int main(int argc, const char *argv[]) {
flatbuffers::NewRustCodeGenerator()); flatbuffers::NewRustCodeGenerator());
flatc.RegisterCodeGenerator( flatc.RegisterCodeGenerator(
flatbuffers::FlatCOption{ flatbuffers::FlatCOption{"t", "json", "",
"t", "json", "", "Generate text output for any data definitions" }, "Generate text output for any data definitions"},
flatbuffers::NewTextCodeGenerator()); flatbuffers::NewTextCodeGenerator());
flatc.RegisterCodeGenerator( flatc.RegisterCodeGenerator(

View File

@@ -75,14 +75,15 @@ class BinaryCodeGenerator : public CodeGenerator {
public: public:
Status GenerateCode(const Parser& parser, const std::string& path, Status GenerateCode(const Parser& parser, const std::string& path,
const std::string& filename) override { const std::string& filename) override {
if (!GenerateBinary(parser, path, filename)) { return Status::ERROR; } if (!GenerateBinary(parser, path, filename)) {
return Status::ERROR;
}
return Status::OK; return Status::OK;
} }
// Generate code from the provided `buffer` of given `length`. The buffer is a // Generate code from the provided `buffer` of given `length`. The buffer is a
// serialized reflection.fbs. // serialized reflection.fbs.
Status GenerateCode(const uint8_t *, int64_t, Status GenerateCode(const uint8_t*, int64_t, const CodeGenOptions&) override {
const CodeGenOptions &) override {
return Status::NOT_IMPLEMENTED; return Status::NOT_IMPLEMENTED;
} }

View File

@@ -40,13 +40,15 @@ static inline std::string NumToStringCpp(std::string val, BaseType type) {
switch (type) { switch (type) {
case BASE_TYPE_INT: case BASE_TYPE_INT:
return (val != "-2147483648") ? val : ("(-2147483647 - 1)"); return (val != "-2147483648") ? val : ("(-2147483647 - 1)");
case BASE_TYPE_ULONG: return (val == "0") ? val : (val + "ULL"); case BASE_TYPE_ULONG:
return (val == "0") ? val : (val + "ULL");
case BASE_TYPE_LONG: case BASE_TYPE_LONG:
if (val == "-9223372036854775808") if (val == "-9223372036854775808")
return "(-9223372036854775807LL - 1LL)"; return "(-9223372036854775807LL - 1LL)";
else else
return (val == "0") ? val : (val + "LL"); return (val == "0") ? val : (val + "LL");
default: return val; default:
return val;
} }
} }
@@ -68,7 +70,9 @@ static std::string GenIncludeGuard(const std::string &file_name,
guard += component + "_"; guard += component + "_";
} }
// Anything extra to add to the guard? // Anything extra to add to the guard?
if (!postfix.empty()) { guard += postfix + "_"; } if (!postfix.empty()) {
guard += postfix + "_";
}
guard += "H_"; guard += "H_";
std::transform(guard.begin(), guard.end(), guard.begin(), CharToUpper); std::transform(guard.begin(), guard.end(), guard.begin(), CharToUpper);
return guard; return guard;
@@ -112,12 +116,16 @@ static void ForAllFieldsOrderedByOffset(
const StructDef& object, std::function<void(const FieldDef* field)> func) { const StructDef& object, std::function<void(const FieldDef* field)> func) {
// Loop over all the fields and call the func on all offset64 fields. // Loop over all the fields and call the func on all offset64 fields.
for (const FieldDef* field_def : object.fields.vec) { for (const FieldDef* field_def : object.fields.vec) {
if (field_def->offset64) { func(field_def); } if (field_def->offset64) {
func(field_def);
}
} }
// Loop over all the fields a second time and call the func on all offset // Loop over all the fields a second time and call the func on all offset
// fields. // fields.
for (const FieldDef* field_def : object.fields.vec) { for (const FieldDef* field_def : object.fields.vec) {
if (!field_def->offset64) { func(field_def); } if (!field_def->offset64) {
func(field_def);
}
} }
} }
@@ -288,7 +296,9 @@ class CppGenerator : public BaseGenerator {
} }
void MarkIf64BitBuilderIsNeeded() { void MarkIf64BitBuilderIsNeeded() {
if (needs_64_bit_builder_) { return; } if (needs_64_bit_builder_) {
return;
}
for (auto t : parser_.structs_.vec) { for (auto t : parser_.structs_.vec) {
if (t == nullptr) continue; if (t == nullptr) continue;
for (auto f : t->fields.vec) { for (auto f : t->fields.vec) {
@@ -310,7 +320,9 @@ class CppGenerator : public BaseGenerator {
for (const std::string& cpp_include : opts_.cpp_includes) { for (const std::string& cpp_include : opts_.cpp_includes) {
code_ += "#include \"" + cpp_include + "\""; code_ += "#include \"" + cpp_include + "\"";
} }
if (!opts_.cpp_includes.empty()) { code_ += ""; } if (!opts_.cpp_includes.empty()) {
code_ += "";
}
} }
void GenEmbeddedIncludes() { void GenEmbeddedIncludes() {
@@ -439,7 +451,9 @@ class CppGenerator : public BaseGenerator {
code_ += "#define " + include_guard; code_ += "#define " + include_guard;
code_ += ""; code_ += "";
if (opts_.gen_nullable) { code_ += "#pragma clang system_header\n\n"; } if (opts_.gen_nullable) {
code_ += "#pragma clang system_header\n\n";
}
code_ += "#include \"flatbuffers/flatbuffers.h\""; code_ += "#include \"flatbuffers/flatbuffers.h\"";
if (parser_.uses_flexbuffers_) { if (parser_.uses_flexbuffers_) {
@@ -450,7 +464,9 @@ class CppGenerator : public BaseGenerator {
GenFlatbuffersVersionCheck(); GenFlatbuffersVersionCheck();
code_ += ""; code_ += "";
if (opts_.include_dependence_headers) { GenIncludeDependencies(); } if (opts_.include_dependence_headers) {
GenIncludeDependencies();
}
GenExtraIncludes(); GenExtraIncludes();
GenEmbeddedIncludes(); GenEmbeddedIncludes();
@@ -485,7 +501,9 @@ class CppGenerator : public BaseGenerator {
} }
} }
if (!struct_def->fixed) { code_ += "struct " + nativeName + ";"; } if (!struct_def->fixed) {
code_ += "struct " + nativeName + ";";
}
} }
code_ += ""; code_ += "";
} }
@@ -770,9 +788,13 @@ class CppGenerator : public BaseGenerator {
} }
bool TypeHasKey(const Type& type) { bool TypeHasKey(const Type& type) {
if (type.base_type != BASE_TYPE_STRUCT) { return false; } if (type.base_type != BASE_TYPE_STRUCT) {
return false;
}
for (auto& field : type.struct_def->fields.vec) { for (auto& field : type.struct_def->fields.vec) {
if (field->key) { return true; } if (field->key) {
return true;
}
} }
return false; return false;
} }
@@ -881,7 +903,9 @@ class CppGenerator : public BaseGenerator {
const std::string NativeString(const FieldDef* field) { const std::string NativeString(const FieldDef* field) {
auto attr = field ? field->attributes.Lookup("cpp_str_type") : nullptr; auto attr = field ? field->attributes.Lookup("cpp_str_type") : nullptr;
auto& ret = attr ? attr->constant : opts_.cpp_object_api_string_type; auto& ret = attr ? attr->constant : opts_.cpp_object_api_string_type;
if (ret.empty()) { return "std::string"; } if (ret.empty()) {
return "std::string";
}
return ret; return ret;
} }
@@ -944,7 +968,9 @@ class CppGenerator : public BaseGenerator {
auto type_name = WrapInNameSpace(*type.struct_def); auto type_name = WrapInNameSpace(*type.struct_def);
if (IsStruct(type)) { if (IsStruct(type)) {
auto native_type = type.struct_def->attributes.Lookup("native_type"); auto native_type = type.struct_def->attributes.Lookup("native_type");
if (native_type) { type_name = native_type->constant; } if (native_type) {
type_name = native_type->constant;
}
if (invector || field.native_inline || forcopy) { if (invector || field.native_inline || forcopy) {
return type_name; return type_name;
} else { } else {
@@ -1188,7 +1214,9 @@ class CppGenerator : public BaseGenerator {
type_refs.push_back(ref_name); type_refs.push_back(ref_name);
} }
} }
if (is_array) { array_sizes.push_back(type.fixed_length); } if (is_array) {
array_sizes.push_back(type.fixed_length);
}
ts += "{ ::flatbuffers::" + std::string(ElementaryTypeNames()[et]) + ts += "{ ::flatbuffers::" + std::string(ElementaryTypeNames()[et]) +
", " + NumToString(is_vector || is_array) + ", " + ", " + NumToString(is_vector || is_array) + ", " +
NumToString(ref_idx) + " }"; NumToString(ref_idx) + " }";
@@ -1281,7 +1309,9 @@ class CppGenerator : public BaseGenerator {
GenComment(enum_def.doc_comment); GenComment(enum_def.doc_comment);
code_ += code_ +=
(opts_.scoped_enums ? "enum class " : "enum ") + Name(enum_def) + "\\"; (opts_.scoped_enums ? "enum class " : "enum ") + Name(enum_def) + "\\";
if (opts_.g_only_fixed_enums) { code_ += " : {{BASE_TYPE}}\\"; } if (opts_.g_only_fixed_enums) {
code_ += " : {{BASE_TYPE}}\\";
}
code_ += " {"; code_ += " {";
code_.SetValue("SEP", ","); code_.SetValue("SEP", ",");
@@ -1372,7 +1402,9 @@ class CppGenerator : public BaseGenerator {
// Generate a union type and a trait type for it. // Generate a union type and a trait type for it.
void GenEnumObjectBasedAPI(const EnumDef& enum_def) { void GenEnumObjectBasedAPI(const EnumDef& enum_def) {
if (!(opts_.generate_object_based_api && enum_def.is_union)) { return; } if (!(opts_.generate_object_based_api && enum_def.is_union)) {
return;
}
code_.SetValue("NAME", Name(enum_def)); code_.SetValue("NAME", Name(enum_def));
FLATBUFFERS_ASSERT(enum_def.Lookup("NONE")); FLATBUFFERS_ASSERT(enum_def.Lookup("NONE"));
code_.SetValue("NONE", GetEnumValUse(enum_def, *enum_def.Lookup("NONE"))); code_.SetValue("NONE", GetEnumValUse(enum_def, *enum_def.Lookup("NONE")));
@@ -1435,7 +1467,9 @@ class CppGenerator : public BaseGenerator {
code_ += ""; code_ += "";
for (const auto ev : enum_def.Vals()) { for (const auto ev : enum_def.Vals()) {
if (ev->IsZero()) { continue; } if (ev->IsZero()) {
continue;
}
const auto native_type = GetUnionElement(*ev, true, opts_); const auto native_type = GetUnionElement(*ev, true, opts_);
code_.SetValue("NATIVE_TYPE", native_type); code_.SetValue("NATIVE_TYPE", native_type);
@@ -1652,7 +1686,9 @@ class CppGenerator : public BaseGenerator {
for (auto it = enum_def.Vals().begin(); it != enum_def.Vals().end(); for (auto it = enum_def.Vals().begin(); it != enum_def.Vals().end();
++it) { ++it) {
const auto& ev = **it; const auto& ev = **it;
if (ev.IsZero()) { continue; } if (ev.IsZero()) {
continue;
}
code_.SetValue("LABEL", GetEnumValUse(enum_def, ev)); code_.SetValue("LABEL", GetEnumValUse(enum_def, ev));
code_.SetValue("TYPE", GetUnionElement(ev, false, opts_)); code_.SetValue("TYPE", GetUnionElement(ev, false, opts_));
@@ -1683,7 +1719,9 @@ class CppGenerator : public BaseGenerator {
for (auto it = enum_def.Vals().begin(); it != enum_def.Vals().end(); for (auto it = enum_def.Vals().begin(); it != enum_def.Vals().end();
++it) { ++it) {
auto& ev = **it; auto& ev = **it;
if (ev.IsZero()) { continue; } if (ev.IsZero()) {
continue;
}
code_.SetValue("LABEL", GetEnumValUse(enum_def, ev)); code_.SetValue("LABEL", GetEnumValUse(enum_def, ev));
code_.SetValue("TYPE", GetUnionElement(ev, true, opts_)); code_.SetValue("TYPE", GetUnionElement(ev, true, opts_));
@@ -1715,7 +1753,9 @@ class CppGenerator : public BaseGenerator {
"{{ENUM_NAME}}Union &u) : type(u.type), value(nullptr) {"; "{{ENUM_NAME}}Union &u) : type(u.type), value(nullptr) {";
code_ += " switch (type) {"; code_ += " switch (type) {";
for (const auto& ev : enum_def.Vals()) { for (const auto& ev : enum_def.Vals()) {
if (ev->IsZero()) { continue; } if (ev->IsZero()) {
continue;
}
code_.SetValue("LABEL", GetEnumValUse(enum_def, *ev)); code_.SetValue("LABEL", GetEnumValUse(enum_def, *ev));
code_.SetValue("TYPE", GetUnionElement(*ev, true, opts_)); code_.SetValue("TYPE", GetUnionElement(*ev, true, opts_));
code_ += " case {{LABEL}}: {"; code_ += " case {{LABEL}}: {";
@@ -1759,7 +1799,9 @@ class CppGenerator : public BaseGenerator {
for (auto it = enum_def.Vals().begin(); it != enum_def.Vals().end(); for (auto it = enum_def.Vals().begin(); it != enum_def.Vals().end();
++it) { ++it) {
const auto& ev = **it; const auto& ev = **it;
if (ev.IsZero()) { continue; } if (ev.IsZero()) {
continue;
}
code_.SetValue("LABEL", GetEnumValUse(enum_def, ev)); code_.SetValue("LABEL", GetEnumValUse(enum_def, ev));
code_.SetValue("TYPE", GetUnionElement(ev, true, opts_)); code_.SetValue("TYPE", GetUnionElement(ev, true, opts_));
code_ += " case {{LABEL}}: {"; code_ += " case {{LABEL}}: {";
@@ -1803,7 +1845,9 @@ class CppGenerator : public BaseGenerator {
void GenFullyQualifiedNameGetter(const StructDef& struct_def, void GenFullyQualifiedNameGetter(const StructDef& struct_def,
const std::string& name) { const std::string& name) {
if (!opts_.generate_name_strings) { return; } if (!opts_.generate_name_strings) {
return;
}
auto fullname = struct_def.defined_namespace->GetFullyQualifiedName(name); auto fullname = struct_def.defined_namespace->GetFullyQualifiedName(name);
code_.SetValue("NAME", fullname); code_.SetValue("NAME", fullname);
code_.SetValue("CONSTEXPR", "FLATBUFFERS_CONSTEXPR_CPP11"); code_.SetValue("CONSTEXPR", "FLATBUFFERS_CONSTEXPR_CPP11");
@@ -1936,7 +1980,9 @@ class CppGenerator : public BaseGenerator {
const auto cpp_ptr_type = field->attributes.Lookup("cpp_ptr_type"); const auto cpp_ptr_type = field->attributes.Lookup("cpp_ptr_type");
const bool is_ptr = !(IsStruct(type) && field->native_inline) || const bool is_ptr = !(IsStruct(type) && field->native_inline) ||
(cpp_type && cpp_ptr_type->constant != "naked"); (cpp_type && cpp_ptr_type->constant != "naked");
if (is_ptr) { return true; } if (is_ptr) {
return true;
}
} else if (IsVector(type)) { } else if (IsVector(type)) {
const auto vec_type = type.VectorType(); const auto vec_type = type.VectorType();
if (vec_type.base_type == BASE_TYPE_UTYPE) continue; if (vec_type.base_type == BASE_TYPE_UTYPE) continue;
@@ -1944,7 +1990,9 @@ class CppGenerator : public BaseGenerator {
const auto cpp_ptr_type = field->attributes.Lookup("cpp_ptr_type"); const auto cpp_ptr_type = field->attributes.Lookup("cpp_ptr_type");
const bool is_ptr = IsVectorOfPointers(*field) || const bool is_ptr = IsVectorOfPointers(*field) ||
(cpp_type && cpp_ptr_type->constant != "naked"); (cpp_type && cpp_ptr_type->constant != "naked");
if (is_ptr) { return true; } if (is_ptr) {
return true;
}
} }
} }
return false; return false;
@@ -1975,7 +2023,9 @@ class CppGenerator : public BaseGenerator {
auto native_default = field.attributes.Lookup("native_default"); auto native_default = field.attributes.Lookup("native_default");
// Scalar types get parsed defaults, raw pointers get nullptrs. // Scalar types get parsed defaults, raw pointers get nullptrs.
if (IsScalar(field.value.type.base_type)) { if (IsScalar(field.value.type.base_type)) {
if (!initializer_list.empty()) { initializer_list += ",\n "; } if (!initializer_list.empty()) {
initializer_list += ",\n ";
}
initializer_list += Name(field); initializer_list += Name(field);
initializer_list += initializer_list +=
"(" + "(" +
@@ -1993,7 +2043,9 @@ class CppGenerator : public BaseGenerator {
} }
} }
} else if (cpp_type && !IsVector(field.value.type)) { } else if (cpp_type && !IsVector(field.value.type)) {
if (!initializer_list.empty()) { initializer_list += ",\n "; } if (!initializer_list.empty()) {
initializer_list += ",\n ";
}
initializer_list += Name(field) + "(0)"; initializer_list += Name(field) + "(0)";
} }
} }
@@ -2036,7 +2088,9 @@ class CppGenerator : public BaseGenerator {
const auto& type = field->value.type; const auto& type = field->value.type;
if (field->deprecated || type.base_type == BASE_TYPE_UTYPE) continue; if (field->deprecated || type.base_type == BASE_TYPE_UTYPE) continue;
if (type.base_type == BASE_TYPE_STRUCT) { if (type.base_type == BASE_TYPE_STRUCT) {
if (!initializer_list.empty()) { initializer_list += ",\n "; } if (!initializer_list.empty()) {
initializer_list += ",\n ";
}
const auto cpp_type = field->attributes.Lookup("cpp_type"); const auto cpp_type = field->attributes.Lookup("cpp_type");
const auto cpp_ptr_type = field->attributes.Lookup("cpp_ptr_type"); const auto cpp_ptr_type = field->attributes.Lookup("cpp_ptr_type");
const std::string& type_name = const std::string& type_name =
@@ -2085,19 +2139,25 @@ class CppGenerator : public BaseGenerator {
// For non-pointer elements, use std::vector's copy constructor in the // For non-pointer elements, use std::vector's copy constructor in the
// initializer list. This will yield better performance than an insert // initializer list. This will yield better performance than an insert
// range loop for trivially-copyable element types. // range loop for trivially-copyable element types.
if (!initializer_list.empty()) { initializer_list += ",\n "; } if (!initializer_list.empty()) {
initializer_list += ",\n ";
}
cw += "{{FIELD}}(o.{{FIELD}})\\"; cw += "{{FIELD}}(o.{{FIELD}})\\";
initializer_list += cw.ToString(); initializer_list += cw.ToString();
} }
} else { } else {
if (!initializer_list.empty()) { initializer_list += ",\n "; } if (!initializer_list.empty()) {
initializer_list += ",\n ";
}
CodeWriter cw; CodeWriter cw;
cw.SetValue("FIELD", Name(*field)); cw.SetValue("FIELD", Name(*field));
cw += "{{FIELD}}(o.{{FIELD}})\\"; cw += "{{FIELD}}(o.{{FIELD}})\\";
initializer_list += cw.ToString(); initializer_list += cw.ToString();
} }
{ {
if (!swaps.empty()) { swaps += "\n "; } if (!swaps.empty()) {
swaps += "\n ";
}
CodeWriter cw; CodeWriter cw;
cw.SetValue("FIELD", Name(*field)); cw.SetValue("FIELD", Name(*field));
cw += "std::swap({{FIELD}}, o.{{FIELD}});\\"; cw += "std::swap({{FIELD}}, o.{{FIELD}});\\";
@@ -2107,7 +2167,9 @@ class CppGenerator : public BaseGenerator {
if (!initializer_list.empty()) { if (!initializer_list.empty()) {
initializer_list = "\n : " + initializer_list; initializer_list = "\n : " + initializer_list;
} }
if (!swaps.empty()) { swaps = " " + swaps; } if (!swaps.empty()) {
swaps = " " + swaps;
}
code_.SetValue("NATIVE_NAME", code_.SetValue("NATIVE_NAME",
NativeName(Name(struct_def), &struct_def, opts_)); NativeName(Name(struct_def), &struct_def, opts_));
@@ -2139,7 +2201,9 @@ class CppGenerator : public BaseGenerator {
field.value.type.base_type != BASE_TYPE_UTYPE && field.value.type.base_type != BASE_TYPE_UTYPE &&
(!IsVector(field.value.type) || (!IsVector(field.value.type) ||
field.value.type.element != BASE_TYPE_UTYPE)) { field.value.type.element != BASE_TYPE_UTYPE)) {
if (!compare_op.empty()) { compare_op += " &&\n "; } if (!compare_op.empty()) {
compare_op += " &&\n ";
}
if (struct_def.fixed || field.native_inline || if (struct_def.fixed || field.native_inline ||
field.value.type.base_type != BASE_TYPE_STRUCT) { field.value.type.base_type != BASE_TYPE_STRUCT) {
// If the field is a vector of tables, the table need to be compared // If the field is a vector of tables, the table need to be compared
@@ -2229,7 +2293,9 @@ class CppGenerator : public BaseGenerator {
code_ += "struct {{NATIVE_NAME}} : public ::flatbuffers::NativeTable {"; code_ += "struct {{NATIVE_NAME}} : public ::flatbuffers::NativeTable {";
code_ += " typedef {{STRUCT_NAME}} TableType;"; code_ += " typedef {{STRUCT_NAME}} TableType;";
GenFullyQualifiedNameGetter(struct_def, native_name); GenFullyQualifiedNameGetter(struct_def, native_name);
for (const auto field : struct_def.fields.vec) { GenMember(*field); } for (const auto field : struct_def.fields.vec) {
GenMember(*field);
}
GenOperatorNewDelete(struct_def); GenOperatorNewDelete(struct_def);
GenDefaultConstructor(struct_def); GenDefaultConstructor(struct_def);
GenCopyMoveCtorAndAssigOpDecls(struct_def); GenCopyMoveCtorAndAssigOpDecls(struct_def);
@@ -2316,7 +2382,8 @@ class CppGenerator : public BaseGenerator {
"{{NAME}}_type())\\"; "{{NAME}}_type())\\";
break; break;
} }
default: break; default:
break;
} }
auto nfn = GetNestedFlatBufferName(field); auto nfn = GetNestedFlatBufferName(field);
@@ -2527,7 +2594,9 @@ class CppGenerator : public BaseGenerator {
for (auto u_it = u->Vals().begin(); u_it != u->Vals().end(); ++u_it) { for (auto u_it = u->Vals().begin(); u_it != u->Vals().end(); ++u_it) {
auto& ev = **u_it; auto& ev = **u_it;
if (ev.union_type.base_type == BASE_TYPE_NONE) { continue; } if (ev.union_type.base_type == BASE_TYPE_NONE) {
continue;
}
auto full_struct_name = GetUnionElement(ev, false, opts_); auto full_struct_name = GetUnionElement(ev, false, opts_);
// @TODO: Mby make this decisions more universal? How? // @TODO: Mby make this decisions more universal? How?
@@ -2573,7 +2642,9 @@ class CppGenerator : public BaseGenerator {
auto offset_type = GenTypeGet(type, "", "const ", " *", false); auto offset_type = GenTypeGet(type, "", "const ", " *", false);
auto call = accessor + offset_type + ">(" + offset_str; auto call = accessor + offset_type + ">(" + offset_str;
// Default value as second arg for non-pointer types. // Default value as second arg for non-pointer types.
if (is_scalar) { call += ", " + GenDefaultConstant(field); } if (is_scalar) {
call += ", " + GenDefaultConstant(field);
}
call += ")"; call += ")";
std::string afterptr = " *" + NullableExtension(); std::string afterptr = " *" + NullableExtension();
@@ -2595,7 +2666,9 @@ class CppGenerator : public BaseGenerator {
code_ += " }"; code_ += " }";
} }
if (type.base_type == BASE_TYPE_UNION) { GenTableUnionAsGetters(field); } if (type.base_type == BASE_TYPE_UNION) {
GenTableUnionAsGetters(field);
}
} }
void GenTableFieldType(const FieldDef& field) { void GenTableFieldType(const FieldDef& field) {
@@ -2622,14 +2695,18 @@ class CppGenerator : public BaseGenerator {
} }
void GenFieldTypeHelper(const StructDef& struct_def) { void GenFieldTypeHelper(const StructDef& struct_def) {
if (struct_def.fields.vec.empty()) { return; } if (struct_def.fields.vec.empty()) {
return;
}
code_ += " template<size_t Index>"; code_ += " template<size_t Index>";
code_ += " using FieldType = \\"; code_ += " using FieldType = \\";
code_ += "decltype(std::declval<type>().get_field<Index>());"; code_ += "decltype(std::declval<type>().get_field<Index>());";
} }
void GenIndexBasedFieldGetter(const StructDef& struct_def) { void GenIndexBasedFieldGetter(const StructDef& struct_def) {
if (struct_def.fields.vec.empty()) { return; } if (struct_def.fields.vec.empty()) {
return;
}
code_ += " template<size_t Index>"; code_ += " template<size_t Index>";
code_ += " auto get_field() const {"; code_ += " auto get_field() const {";
@@ -2683,7 +2760,9 @@ class CppGenerator : public BaseGenerator {
} }
code_.SetValue("FIELD_NAME", Name(field)); code_.SetValue("FIELD_NAME", Name(field));
code_ += R"( "{{FIELD_NAME}}"\)"; code_ += R"( "{{FIELD_NAME}}"\)";
if (it + 1 != struct_def.fields.vec.end()) { code_ += ","; } if (it + 1 != struct_def.fields.vec.end()) {
code_ += ",";
}
} }
code_ += "\n };"; code_ += "\n };";
} }
@@ -2762,8 +2841,12 @@ class CppGenerator : public BaseGenerator {
auto postptr = " *" + NullableExtension(); auto postptr = " *" + NullableExtension();
auto wire_type = GenTypeGet(type, " ", "", postptr.c_str(), true); auto wire_type = GenTypeGet(type, " ", "", postptr.c_str(), true);
const std::string accessor = [&]() { const std::string accessor = [&]() {
if (IsStruct(type)) { return "GetStruct<"; } if (IsStruct(type)) {
if (field.offset64) { return "GetPointer64<"; } return "GetStruct<";
}
if (field.offset64) {
return "GetPointer64<";
}
return "GetPointer<"; return "GetPointer<";
}(); }();
auto underlying = accessor + wire_type + ">(" + offset_str + ")"; auto underlying = accessor + wire_type + ">(" + offset_str + ")";
@@ -2793,7 +2876,9 @@ class CppGenerator : public BaseGenerator {
// Generate an accessor struct, builder structs & function for a table. // Generate an accessor struct, builder structs & function for a table.
void GenTable(const StructDef& struct_def) { void GenTable(const StructDef& struct_def) {
if (opts_.generate_object_based_api) { GenNativeTable(struct_def); } if (opts_.generate_object_based_api) {
GenNativeTable(struct_def);
}
// Generate an accessor struct, with methods of the form: // Generate an accessor struct, with methods of the form:
// type name() const { return GetField<type>(offset, defaultval); } // type name() const { return GetField<type>(offset, defaultval); }
@@ -2809,7 +2894,9 @@ class CppGenerator : public BaseGenerator {
code_ += " typedef {{STRUCT_NAME}}Builder Builder;"; code_ += " typedef {{STRUCT_NAME}}Builder Builder;";
GenBinarySchemaTypeDef(parser_.root_struct_def_); GenBinarySchemaTypeDef(parser_.root_struct_def_);
if (opts_.g_cpp_std >= cpp::CPP_STD_17) { code_ += " struct Traits;"; } if (opts_.g_cpp_std >= cpp::CPP_STD_17) {
code_ += " struct Traits;";
}
if (opts_.mini_reflect != IDLOptions::kNone) { if (opts_.mini_reflect != IDLOptions::kNone) {
code_ += code_ +=
" static const ::flatbuffers::TypeTable *MiniReflectTypeTable() {"; " static const ::flatbuffers::TypeTable *MiniReflectTypeTable() {";
@@ -2850,7 +2937,9 @@ class CppGenerator : public BaseGenerator {
code_.SetValue("FIELD_NAME", Name(*field)); code_.SetValue("FIELD_NAME", Name(*field));
GenTableFieldGetter(*field); GenTableFieldGetter(*field);
if (opts_.mutable_buffer) { GenTableFieldSetter(*field); } if (opts_.mutable_buffer) {
GenTableFieldSetter(*field);
}
auto nfn = GetNestedFlatBufferName(*field); auto nfn = GetNestedFlatBufferName(*field);
if (!nfn.empty()) { if (!nfn.empty()) {
@@ -2876,17 +2965,23 @@ class CppGenerator : public BaseGenerator {
} }
// Generate a comparison function for this field if it is a key. // Generate a comparison function for this field if it is a key.
if (field->key) { GenKeyFieldMethods(*field); } if (field->key) {
GenKeyFieldMethods(*field);
}
} }
if (opts_.cpp_static_reflection) { GenIndexBasedFieldGetter(struct_def); } if (opts_.cpp_static_reflection) {
GenIndexBasedFieldGetter(struct_def);
}
// Generate a verifier function that can check a buffer from an untrusted // Generate a verifier function that can check a buffer from an untrusted
// source will never cause reads outside the buffer. // source will never cause reads outside the buffer.
code_ += " bool Verify(::flatbuffers::Verifier &verifier) const {"; code_ += " bool Verify(::flatbuffers::Verifier &verifier) const {";
code_ += " return VerifyTableStart(verifier)\\"; code_ += " return VerifyTableStart(verifier)\\";
for (const auto& field : struct_def.fields.vec) { for (const auto& field : struct_def.fields.vec) {
if (field->deprecated) { continue; } if (field->deprecated) {
continue;
}
GenVerifyCall(*field, " &&\n "); GenVerifyCall(*field, " &&\n ");
} }
@@ -2916,7 +3011,9 @@ class CppGenerator : public BaseGenerator {
for (auto u_it = u->Vals().begin(); u_it != u->Vals().end(); ++u_it) { for (auto u_it = u->Vals().begin(); u_it != u->Vals().end(); ++u_it) {
auto& ev = **u_it; auto& ev = **u_it;
if (ev.union_type.base_type == BASE_TYPE_NONE) { continue; } if (ev.union_type.base_type == BASE_TYPE_NONE) {
continue;
}
auto full_struct_name = GetUnionElement(ev, false, opts_); auto full_struct_name = GetUnionElement(ev, false, opts_);
@@ -2988,7 +3085,9 @@ class CppGenerator : public BaseGenerator {
const bool is_default_scalar = is_scalar && !field.IsScalarOptional(); const bool is_default_scalar = is_scalar && !field.IsScalarOptional();
const bool is_string = IsString(field.value.type); const bool is_string = IsString(field.value.type);
const bool is_vector = IsVector(field.value.type); const bool is_vector = IsVector(field.value.type);
if (is_string || is_vector) { has_string_or_vector_fields = true; } if (is_string || is_vector) {
has_string_or_vector_fields = true;
}
std::string offset = GenFieldOffsetName(field); std::string offset = GenFieldOffsetName(field);
std::string name = GenUnderlyingCast(field, false, Name(field)); std::string name = GenUnderlyingCast(field, false, Name(field));
@@ -3056,7 +3155,9 @@ class CppGenerator : public BaseGenerator {
"Create{{STRUCT_NAME}}("; "Create{{STRUCT_NAME}}(";
code_ += " " + GetBuilder() + " &_fbb\\"; code_ += " " + GetBuilder() + " &_fbb\\";
for (const auto& field : struct_def.fields.vec) { for (const auto& field : struct_def.fields.vec) {
if (!field->deprecated) { GenParam(*field, false, ",\n "); } if (!field->deprecated) {
GenParam(*field, false, ",\n ");
}
} }
code_ += ") {"; code_ += ") {";
@@ -3085,7 +3186,9 @@ class CppGenerator : public BaseGenerator {
// Definition for type traits for this table type. This allows querying var- // Definition for type traits for this table type. This allows querying var-
// ious compile-time traits of the table. // ious compile-time traits of the table.
if (opts_.g_cpp_std >= cpp::CPP_STD_17) { GenTraitsStruct(struct_def); } if (opts_.g_cpp_std >= cpp::CPP_STD_17) {
GenTraitsStruct(struct_def);
}
// Generate a CreateXDirect function with vector types as parameters // Generate a CreateXDirect function with vector types as parameters
if (opts_.cpp_direct_copy && has_string_or_vector_fields) { if (opts_.cpp_direct_copy && has_string_or_vector_fields) {
@@ -3094,7 +3197,9 @@ class CppGenerator : public BaseGenerator {
"Create{{STRUCT_NAME}}Direct("; "Create{{STRUCT_NAME}}Direct(";
code_ += " " + GetBuilder() + " &_fbb\\"; code_ += " " + GetBuilder() + " &_fbb\\";
for (const auto& field : struct_def.fields.vec) { for (const auto& field : struct_def.fields.vec) {
if (!field->deprecated) { GenParam(*field, true, ",\n "); } if (!field->deprecated) {
GenParam(*field, true, ",\n ");
}
} }
// Need to call "Create" with the struct namespace. // Need to call "Create" with the struct namespace.
const auto qualified_create_name = const auto qualified_create_name =
@@ -3109,7 +3214,9 @@ class CppGenerator : public BaseGenerator {
// TODO(derekbailey): maybe optimize for the case where there is no // TODO(derekbailey): maybe optimize for the case where there is no
// 64offsets in the whole schema? // 64offsets in the whole schema?
ForAllFieldsOrderedByOffset(struct_def, [&](const FieldDef* field) { ForAllFieldsOrderedByOffset(struct_def, [&](const FieldDef* field) {
if (field->deprecated) { return; } if (field->deprecated) {
return;
}
code_.SetValue("FIELD_NAME", Name(*field)); code_.SetValue("FIELD_NAME", Name(*field));
if (IsString(field->value.type)) { if (IsString(field->value.type)) {
if (!field->shared) { if (!field->shared) {
@@ -3175,7 +3282,9 @@ class CppGenerator : public BaseGenerator {
code_ += " return {{CREATE_NAME}}{{STRUCT_NAME}}("; code_ += " return {{CREATE_NAME}}{{STRUCT_NAME}}(";
code_ += " _fbb\\"; code_ += " _fbb\\";
for (const auto& field : struct_def.fields.vec) { for (const auto& field : struct_def.fields.vec) {
if (field->deprecated) { continue; } if (field->deprecated) {
continue;
}
code_.SetValue("FIELD_NAME", Name(*field)); code_.SetValue("FIELD_NAME", Name(*field));
code_ += ",\n {{FIELD_NAME}}\\"; code_ += ",\n {{FIELD_NAME}}\\";
if (IsString(field->value.type) || IsVector(field->value.type)) { if (IsString(field->value.type) || IsVector(field->value.type)) {
@@ -3215,7 +3324,9 @@ class CppGenerator : public BaseGenerator {
if (native_type) { if (native_type) {
std::string unpack_call = "::flatbuffers::UnPack"; std::string unpack_call = "::flatbuffers::UnPack";
const auto pack_name = struct_attrs.Lookup("native_type_pack_name"); const auto pack_name = struct_attrs.Lookup("native_type_pack_name");
if (pack_name) { unpack_call += pack_name->constant; } if (pack_name) {
unpack_call += pack_name->constant;
}
unpack_call += "(*" + val + ")"; unpack_call += "(*" + val + ")";
if (invector || afield.native_inline) { if (invector || afield.native_inline) {
return unpack_call; return unpack_call;
@@ -3280,7 +3391,9 @@ class CppGenerator : public BaseGenerator {
WrapInNameSpace(*field.value.type.enum_def) + ">("; WrapInNameSpace(*field.value.type.enum_def) + ">(";
} }
indexing += "_e->Get(_i)"; indexing += "_e->Get(_i)";
if (field.value.type.enum_def) { indexing += ")"; } if (field.value.type.enum_def) {
indexing += ")";
}
if (field.value.type.element == BASE_TYPE_BOOL) { if (field.value.type.element == BASE_TYPE_BOOL) {
indexing += " != 0"; indexing += " != 0";
} }
@@ -3334,7 +3447,9 @@ class CppGenerator : public BaseGenerator {
code += GenUnpackVal(field.value.type.VectorType(), indexing, true, code += GenUnpackVal(field.value.type.VectorType(), indexing, true,
field); field);
code += "; "; code += "; ";
if (is_pointer) { code += "} "; } if (is_pointer) {
code += "} ";
}
} }
code += "} } else { " + vector_field + ".resize(0); }"; code += "} } else { " + vector_field + ".resize(0); }";
} }
@@ -3611,7 +3726,9 @@ class CppGenerator : public BaseGenerator {
code += "::flatbuffers::Pack"; code += "::flatbuffers::Pack";
const auto pack_name = const auto pack_name =
struct_attribs.Lookup("native_type_pack_name"); struct_attribs.Lookup("native_type_pack_name");
if (pack_name) { code += pack_name->constant; } if (pack_name) {
code += pack_name->constant;
}
code += "(" + value + ")"; code += "(" + value + ")";
} else if (native_type && !field.native_inline) { } else if (native_type && !field.native_inline) {
code += WrapInNameSpace(*field.value.type.struct_def) + "{};"; code += WrapInNameSpace(*field.value.type.struct_def) + "{};";
@@ -3642,7 +3759,9 @@ class CppGenerator : public BaseGenerator {
// Generate code for tables that needs to come after the regular definition. // Generate code for tables that needs to come after the regular definition.
void GenTablePost(const StructDef& struct_def) { void GenTablePost(const StructDef& struct_def) {
if (opts_.generate_object_based_api) { GenNativeTablePost(struct_def); } if (opts_.generate_object_based_api) {
GenNativeTablePost(struct_def);
}
code_.SetValue("STRUCT_NAME", Name(struct_def)); code_.SetValue("STRUCT_NAME", Name(struct_def));
code_.SetValue("NATIVE_NAME", code_.SetValue("NATIVE_NAME",
@@ -3681,7 +3800,9 @@ class CppGenerator : public BaseGenerator {
for (auto it = struct_def.fields.vec.begin(); for (auto it = struct_def.fields.vec.begin();
it != struct_def.fields.vec.end(); ++it) { it != struct_def.fields.vec.end(); ++it) {
const auto& field = **it; const auto& field = **it;
if (field.deprecated) { continue; } if (field.deprecated) {
continue;
}
// Assign a value from |this| to |_o|. Values from |this| are stored // Assign a value from |this| to |_o|. Values from |this| are stored
// in a variable |_e| by calling this->field_type(). The value is then // in a variable |_e| by calling this->field_type(). The value is then
@@ -3726,11 +3847,15 @@ class CppGenerator : public BaseGenerator {
for (auto it = struct_def.fields.vec.begin(); for (auto it = struct_def.fields.vec.begin();
it != struct_def.fields.vec.end(); ++it) { it != struct_def.fields.vec.end(); ++it) {
auto& field = **it; auto& field = **it;
if (field.deprecated) { continue; } if (field.deprecated) {
continue;
}
if (IsVector(field.value.type)) { if (IsVector(field.value.type)) {
const std::string force_align_code = const std::string force_align_code =
GenVectorForceAlign(field, "_o->" + Name(field) + ".size()"); GenVectorForceAlign(field, "_o->" + Name(field) + ".size()");
if (!force_align_code.empty()) { code_ += " " + force_align_code; } if (!force_align_code.empty()) {
code_ += " " + force_align_code;
}
} }
code_ += " auto _" + Name(field) + " = " + GenCreateParam(field) + ";"; code_ += " auto _" + Name(field) + " = " + GenCreateParam(field) + ";";
} }
@@ -3742,7 +3867,9 @@ class CppGenerator : public BaseGenerator {
code_ += " return {{CREATE_NAME}}{{STRUCT_NAME}}("; code_ += " return {{CREATE_NAME}}{{STRUCT_NAME}}(";
code_ += " _fbb\\"; code_ += " _fbb\\";
for (const auto& field : struct_def.fields.vec) { for (const auto& field : struct_def.fields.vec) {
if (field->deprecated) { continue; } if (field->deprecated) {
continue;
}
bool pass_by_address = false; bool pass_by_address = false;
bool check_ptr = false; bool check_ptr = false;
@@ -3751,8 +3878,12 @@ class CppGenerator : public BaseGenerator {
auto native_type = auto native_type =
field->value.type.struct_def->attributes.Lookup("native_type"); field->value.type.struct_def->attributes.Lookup("native_type");
auto native_inline = field->attributes.Lookup("native_inline"); auto native_inline = field->attributes.Lookup("native_inline");
if (native_type) { pass_by_address = true; } if (native_type) {
if (native_type && !native_inline) { check_ptr = true; } pass_by_address = true;
}
if (native_type && !native_inline) {
check_ptr = true;
}
} }
} }
@@ -3844,7 +3975,9 @@ class CppGenerator : public BaseGenerator {
code_.SetValue("INIT_LIST", init_list); code_.SetValue("INIT_LIST", init_list);
code_ += " {{STRUCT_NAME}}()"; code_ += " {{STRUCT_NAME}}()";
code_ += " : {{INIT_LIST}} {"; code_ += " : {{INIT_LIST}} {";
if (!body.empty()) { code_ += body; } if (!body.empty()) {
code_ += body;
}
code_ += " }"; code_ += " }";
} }
} }
@@ -3864,14 +3997,18 @@ class CppGenerator : public BaseGenerator {
const auto is_array = IsArray(type); const auto is_array = IsArray(type);
const auto arg_name = "_" + Name(field); const auto arg_name = "_" + Name(field);
if (!is_array || init_arrays) { if (!is_array || init_arrays) {
if (it != first && !arg_list.empty()) { arg_list += ", "; } if (it != first && !arg_list.empty()) {
arg_list += ", ";
}
arg_list += !is_array ? GenTypeGet(type, " ", "const ", " &", true) arg_list += !is_array ? GenTypeGet(type, " ", "const ", " &", true)
: GenTypeSpan(type, true, type.fixed_length); : GenTypeSpan(type, true, type.fixed_length);
arg_list += arg_name; arg_list += arg_name;
} }
// skip an array with initialization from span // skip an array with initialization from span
if (false == (is_array && init_arrays)) { if (false == (is_array && init_arrays)) {
if (it != first && !init_list.empty()) { init_list += ",\n "; } if (it != first && !init_list.empty()) {
init_list += ",\n ";
}
init_list += Name(field) + "_"; init_list += Name(field) + "_";
if (IsScalar(type.base_type)) { if (IsScalar(type.base_type)) {
auto scalar_type = GenUnderlyingCast(field, false, arg_name); auto scalar_type = GenUnderlyingCast(field, false, arg_name);
@@ -3982,7 +4119,9 @@ class CppGenerator : public BaseGenerator {
code_ += ""; code_ += "";
code_ += " public:"; code_ += " public:";
if (opts_.g_cpp_std >= cpp::CPP_STD_17) { code_ += " struct Traits;"; } if (opts_.g_cpp_std >= cpp::CPP_STD_17) {
code_ += " struct Traits;";
}
// Make TypeTable accessible via the generated struct. // Make TypeTable accessible via the generated struct.
if (opts_.mini_reflect != IDLOptions::kNone) { if (opts_.mini_reflect != IDLOptions::kNone) {
@@ -4061,12 +4200,16 @@ class CppGenerator : public BaseGenerator {
} }
// Generate a comparison function for this field if it is a key. // Generate a comparison function for this field if it is a key.
if (field->key) { GenKeyFieldMethods(*field); } if (field->key) {
GenKeyFieldMethods(*field);
}
} }
code_.SetValue("NATIVE_NAME", Name(struct_def)); code_.SetValue("NATIVE_NAME", Name(struct_def));
GenOperatorNewDelete(struct_def); GenOperatorNewDelete(struct_def);
if (opts_.cpp_static_reflection) { GenIndexBasedFieldGetter(struct_def); } if (opts_.cpp_static_reflection) {
GenIndexBasedFieldGetter(struct_def);
}
code_ += "};"; code_ += "};";
@@ -4077,7 +4220,9 @@ class CppGenerator : public BaseGenerator {
// Definition for type traits for this table type. This allows querying var- // Definition for type traits for this table type. This allows querying var-
// ious compile-time traits of the table. // ious compile-time traits of the table.
if (opts_.g_cpp_std >= cpp::CPP_STD_17) { GenTraitsStruct(struct_def); } if (opts_.g_cpp_std >= cpp::CPP_STD_17) {
GenTraitsStruct(struct_def);
}
} }
// Set up the correct namespace. Only open a namespace if the existing one is // Set up the correct namespace. Only open a namespace if the existing one is
@@ -4086,7 +4231,9 @@ class CppGenerator : public BaseGenerator {
// The file must start and end with an empty (or null) namespace so that // The file must start and end with an empty (or null) namespace so that
// namespaces are properly opened and closed. // namespaces are properly opened and closed.
void SetNameSpace(const Namespace* ns) { void SetNameSpace(const Namespace* ns) {
if (cur_name_space_ == ns) { return; } if (cur_name_space_ == ns) {
return;
}
// Compute the size of the longest common namespace prefix. // Compute the size of the longest common namespace prefix.
// If cur_name_space is A::B::C::D and ns is A::B::E::F::G, // If cur_name_space is A::B::C::D and ns is A::B::E::F::G,
@@ -4107,14 +4254,18 @@ class CppGenerator : public BaseGenerator {
for (size_t j = old_size; j > common_prefix_size; --j) { for (size_t j = old_size; j > common_prefix_size; --j) {
code_ += "} // namespace " + cur_name_space_->components[j - 1]; code_ += "} // namespace " + cur_name_space_->components[j - 1];
} }
if (old_size != common_prefix_size) { code_ += ""; } if (old_size != common_prefix_size) {
code_ += "";
}
// open namespace parts to reach the ns namespace // open namespace parts to reach the ns namespace
// in the previous example, E, then F, then G are opened // in the previous example, E, then F, then G are opened
for (auto j = common_prefix_size; j != new_size; ++j) { for (auto j = common_prefix_size; j != new_size; ++j) {
code_ += "namespace " + ns->components[j] + " {"; code_ += "namespace " + ns->components[j] + " {";
} }
if (new_size != common_prefix_size) { code_ += ""; } if (new_size != common_prefix_size) {
code_ += "";
}
cur_name_space_ = ns; cur_name_space_ = ns;
} }
@@ -4180,14 +4331,15 @@ class CppCodeGenerator : public CodeGenerator {
public: public:
Status GenerateCode(const Parser& parser, const std::string& path, Status GenerateCode(const Parser& parser, const std::string& path,
const std::string& filename) override { const std::string& filename) override {
if (!GenerateCPP(parser, path, filename)) { return Status::ERROR; } if (!GenerateCPP(parser, path, filename)) {
return Status::ERROR;
}
return Status::OK; return Status::OK;
} }
// Generate code from the provided `buffer` of given `length`. The buffer is a // Generate code from the provided `buffer` of given `length`. The buffer is a
// serialized reflection.fbs. // serialized reflection.fbs.
Status GenerateCode(const uint8_t *, int64_t, Status GenerateCode(const uint8_t*, int64_t, const CodeGenOptions&) override {
const CodeGenOptions &) override {
return Status::NOT_IMPLEMENTED; return Status::NOT_IMPLEMENTED;
} }
@@ -4200,7 +4352,9 @@ class CppCodeGenerator : public CodeGenerator {
Status GenerateGrpcCode(const Parser& parser, const std::string& path, Status GenerateGrpcCode(const Parser& parser, const std::string& path,
const std::string& filename) override { const std::string& filename) override {
if (!GenerateCppGRPC(parser, path, filename)) { return Status::ERROR; } if (!GenerateCppGRPC(parser, path, filename)) {
return Status::ERROR;
}
return Status::OK; return Status::OK;
} }

View File

@@ -232,9 +232,13 @@ class CSharpGenerator : public BaseGenerator {
code += "using global::Google.FlatBuffers;\n\n"; code += "using global::Google.FlatBuffers;\n\n";
} }
code += classcode; code += classcode;
if (!namespace_name.empty()) { code += "\n}\n"; } if (!namespace_name.empty()) {
code += "\n}\n";
}
auto filename = NamespaceDir(ns) + defname; auto filename = NamespaceDir(ns) + defname;
if (options.one_file) { filename += options.filename_suffix; } if (options.one_file) {
filename += options.filename_suffix;
}
filename += filename +=
options.filename_extension.empty() ? ".cs" : options.filename_extension; options.filename_extension.empty() ? ".cs" : options.filename_extension;
return SaveFile(filename.c_str(), code, false); return SaveFile(filename.c_str(), code, false);
@@ -268,11 +272,16 @@ class CSharpGenerator : public BaseGenerator {
std::string GenTypePointer(const Type& type) const { std::string GenTypePointer(const Type& type) const {
switch (type.base_type) { switch (type.base_type) {
case BASE_TYPE_STRING: return "string"; case BASE_TYPE_STRING:
case BASE_TYPE_VECTOR: return GenTypeGet(type.VectorType()); return "string";
case BASE_TYPE_STRUCT: return NamespacedName(*type.struct_def); case BASE_TYPE_VECTOR:
case BASE_TYPE_UNION: return "TTable"; return GenTypeGet(type.VectorType());
default: return "Table"; case BASE_TYPE_STRUCT:
return NamespacedName(*type.struct_def);
case BASE_TYPE_UNION:
return "TTable";
default:
return "Table";
} }
} }
@@ -336,7 +345,9 @@ class CSharpGenerator : public BaseGenerator {
std::string GenDefaultValue(const FieldDef& field, std::string GenDefaultValue(const FieldDef& field,
bool enableLangOverrides) const { bool enableLangOverrides) const {
// If it is an optional scalar field, the default is null // If it is an optional scalar field, the default is null
if (field.IsScalarOptional()) { return "null"; } if (field.IsScalarOptional()) {
return "null";
}
auto& value = field.value; auto& value = field.value;
if (enableLangOverrides) { if (enableLangOverrides) {
@@ -349,10 +360,13 @@ class CSharpGenerator : public BaseGenerator {
auto longSuffix = ""; auto longSuffix = "";
switch (value.type.base_type) { switch (value.type.base_type) {
case BASE_TYPE_BOOL: return value.constant == "0" ? "false" : "true"; case BASE_TYPE_BOOL:
case BASE_TYPE_ULONG: return value.constant; return value.constant == "0" ? "false" : "true";
case BASE_TYPE_ULONG:
return value.constant;
case BASE_TYPE_UINT: case BASE_TYPE_UINT:
case BASE_TYPE_LONG: return value.constant + longSuffix; case BASE_TYPE_LONG:
return value.constant + longSuffix;
default: default:
if (IsFloat(value.type.base_type)) if (IsFloat(value.type.base_type))
return CSharpFloatGen.GenFloatConstant(field); return CSharpFloatGen.GenFloatConstant(field);
@@ -371,12 +385,15 @@ class CSharpGenerator : public BaseGenerator {
if (!IsScalar(value.type.base_type)) { if (!IsScalar(value.type.base_type)) {
if (enableLangOverrides) { if (enableLangOverrides) {
switch (value.type.base_type) { switch (value.type.base_type) {
case BASE_TYPE_STRING: return "default(StringOffset)"; case BASE_TYPE_STRING:
return "default(StringOffset)";
case BASE_TYPE_STRUCT: case BASE_TYPE_STRUCT:
return "default(Offset<" + NamespacedName(*value.type.struct_def) + return "default(Offset<" + NamespacedName(*value.type.struct_def) +
">)"; ">)";
case BASE_TYPE_VECTOR: return "default(VectorOffset)"; case BASE_TYPE_VECTOR:
default: break; return "default(VectorOffset)";
default:
break;
} }
} }
return "0"; return "0";
@@ -441,7 +458,9 @@ class CSharpGenerator : public BaseGenerator {
if (!enum_def.is_union) return false; if (!enum_def.is_union) return false;
for (auto it = enum_def.Vals().begin(); it != enum_def.Vals().end(); ++it) { for (auto it = enum_def.Vals().begin(); it != enum_def.Vals().end(); ++it) {
auto& val = **it; auto& val = **it;
if (IsString(val.union_type)) { return true; } if (IsString(val.union_type)) {
return true;
}
} }
return false; return false;
} }
@@ -449,11 +468,16 @@ class CSharpGenerator : public BaseGenerator {
// Returns the function name that is able to read a value of the given type. // Returns the function name that is able to read a value of the given type.
std::string GenGetter(const Type& type) const { std::string GenGetter(const Type& type) const {
switch (type.base_type) { switch (type.base_type) {
case BASE_TYPE_STRING: return "__p.__string"; case BASE_TYPE_STRING:
case BASE_TYPE_STRUCT: return "__p.__struct"; return "__p.__string";
case BASE_TYPE_UNION: return "__p.__union"; case BASE_TYPE_STRUCT:
case BASE_TYPE_VECTOR: return GenGetter(type.VectorType()); return "__p.__struct";
case BASE_TYPE_ARRAY: return GenGetter(type.VectorType()); case BASE_TYPE_UNION:
return "__p.__union";
case BASE_TYPE_VECTOR:
return GenGetter(type.VectorType());
case BASE_TYPE_ARRAY:
return GenGetter(type.VectorType());
default: { default: {
std::string getter = "__p.bb.Get"; std::string getter = "__p.bb.Get";
if (type.base_type == BASE_TYPE_BOOL) { if (type.base_type == BASE_TYPE_BOOL) {
@@ -483,7 +507,9 @@ class CSharpGenerator : public BaseGenerator {
// Use the generated type directly, to properly handle default values that // Use the generated type directly, to properly handle default values that
// might not be written to the buffer. // might not be written to the buffer.
auto name = Name(*key_field); auto name = Name(*key_field);
if (name == struct_def.name) { name += "_"; } if (name == struct_def.name) {
name += "_";
}
return GetObjectConstructor(struct_def, data_buffer, offset) + "." + name; return GetObjectConstructor(struct_def, data_buffer, offset) + "." + name;
} }
@@ -531,7 +557,9 @@ class CSharpGenerator : public BaseGenerator {
} else { } else {
code += ", "; code += ", ";
code += GenTypeBasic(type); code += GenTypeBasic(type);
if (field.IsScalarOptional()) { code += "?"; } if (field.IsScalarOptional()) {
code += "?";
}
if (array_cnt > 0) { if (array_cnt > 0) {
code += "["; code += "[";
for (size_t i = 1; i < array_cnt; i++) code += ","; for (size_t i = 1; i < array_cnt; i++) code += ",";
@@ -599,7 +627,9 @@ class CSharpGenerator : public BaseGenerator {
} }
code += ");\n"; code += ");\n";
} }
if (IsArray(field_type)) { code += indent + " }\n"; } if (IsArray(field_type)) {
code += indent + " }\n";
}
} }
} }
} }
@@ -923,12 +953,16 @@ class CSharpGenerator : public BaseGenerator {
optional = "?"; optional = "?";
conditional_cast = "(" + type_name_dest + optional + ")"; conditional_cast = "(" + type_name_dest + optional + ")";
} }
if (field.IsScalarOptional()) { optional = "?"; } if (field.IsScalarOptional()) {
optional = "?";
}
std::string dest_mask = ""; std::string dest_mask = "";
std::string dest_cast = DestinationCast(field.value.type); std::string dest_cast = DestinationCast(field.value.type);
std::string src_cast = SourceCast(field.value.type); std::string src_cast = SourceCast(field.value.type);
std::string field_name_camel = Name(field); std::string field_name_camel = Name(field);
if (field_name_camel == struct_def.name) { field_name_camel += "_"; } if (field_name_camel == struct_def.name) {
field_name_camel += "_";
}
std::string method_start = std::string method_start =
" public " + type_name_dest + optional + " " + field_name_camel; " public " + type_name_dest + optional + " " + field_name_camel;
std::string obj = "(new " + type_name + "())"; std::string obj = "(new " + type_name + "())";
@@ -1008,7 +1042,8 @@ class CSharpGenerator : public BaseGenerator {
code += offset_prefix + getter + "(o + " + "__p."; code += offset_prefix + getter + "(o + " + "__p.";
code += "bb_pos) : null"; code += "bb_pos) : null";
break; break;
case BASE_TYPE_ARRAY: FLATBUFFERS_FALLTHROUGH(); // fall thru case BASE_TYPE_ARRAY:
FLATBUFFERS_FALLTHROUGH(); // fall thru
case BASE_TYPE_VECTOR: { case BASE_TYPE_VECTOR: {
auto vectortype = field.value.type.VectorType(); auto vectortype = field.value.type.VectorType();
if (vectortype.base_type == BASE_TYPE_UNION) { if (vectortype.base_type == BASE_TYPE_UNION) {
@@ -1078,7 +1113,9 @@ class CSharpGenerator : public BaseGenerator {
for (auto uit = field.value.type.enum_def->Vals().begin(); for (auto uit = field.value.type.enum_def->Vals().begin();
uit != field.value.type.enum_def->Vals().end(); ++uit) { uit != field.value.type.enum_def->Vals().end(); ++uit) {
auto val = *uit; auto val = *uit;
if (val->union_type.base_type == BASE_TYPE_NONE) { continue; } if (val->union_type.base_type == BASE_TYPE_NONE) {
continue;
}
auto union_field_type_name = GenTypeGet(val->union_type); auto union_field_type_name = GenTypeGet(val->union_type);
code += member_suffix + "}\n"; code += member_suffix + "}\n";
if (val->union_type.base_type == BASE_TYPE_STRUCT && if (val->union_type.base_type == BASE_TYPE_STRUCT &&
@@ -1097,14 +1134,17 @@ class CSharpGenerator : public BaseGenerator {
} }
} }
break; break;
default: FLATBUFFERS_ASSERT(0); default:
FLATBUFFERS_ASSERT(0);
} }
} }
code += member_suffix; code += member_suffix;
code += "}\n"; code += "}\n";
if (IsVector(field.value.type)) { if (IsVector(field.value.type)) {
auto camel_name = Name(field); auto camel_name = Name(field);
if (camel_name == struct_def.name) { camel_name += "_"; } if (camel_name == struct_def.name) {
camel_name += "_";
}
code += " public int " + camel_name; code += " public int " + camel_name;
code += "Length"; code += "Length";
code += " { get"; code += " { get";
@@ -1318,7 +1358,9 @@ class CSharpGenerator : public BaseGenerator {
code += " = null"; code += " = null";
} else { } else {
code += GenTypeBasic(field.value.type); code += GenTypeBasic(field.value.type);
if (field.IsScalarOptional()) { code += "?"; } if (field.IsScalarOptional()) {
code += "?";
}
code += " "; code += " ";
code += EscapeKeyword(field.name); code += EscapeKeyword(field.name);
if (!IsScalar(field.value.type.base_type)) code += "Offset"; if (!IsScalar(field.value.type.base_type)) code += "Offset";
@@ -1379,7 +1421,9 @@ class CSharpGenerator : public BaseGenerator {
code += GenTypeBasic(field.value.type); code += GenTypeBasic(field.value.type);
auto argname = ConvertCase(field.name, Case::kLowerCamel); auto argname = ConvertCase(field.name, Case::kLowerCamel);
if (!IsScalar(field.value.type.base_type)) argname += "Offset"; if (!IsScalar(field.value.type.base_type)) argname += "Offset";
if (field.IsScalarOptional()) { code += "?"; } if (field.IsScalarOptional()) {
code += "?";
}
code += " " + EscapeKeyword(argname) + ") { builder.Add"; code += " " + EscapeKeyword(argname) + ") { builder.Add";
code += GenMethod(field.value.type) + "("; code += GenMethod(field.value.type) + "(";
code += NumToString(it - struct_def.fields.vec.begin()) + ", "; code += NumToString(it - struct_def.fields.vec.begin()) + ", ";
@@ -1509,7 +1553,9 @@ class CSharpGenerator : public BaseGenerator {
if (struct_def.has_key && !struct_def.fixed) { if (struct_def.has_key && !struct_def.fixed) {
FLATBUFFERS_ASSERT(key_field); FLATBUFFERS_ASSERT(key_field);
auto name = Name(*key_field); auto name = Name(*key_field);
if (name == struct_def.name) { name += "_"; } if (name == struct_def.name) {
name += "_";
}
code += "\n public static VectorOffset "; code += "\n public static VectorOffset ";
code += "CreateSortedVectorOf" + struct_def.name; code += "CreateSortedVectorOf" + struct_def.name;
code += "(FlatBufferBuilder builder, "; code += "(FlatBufferBuilder builder, ";
@@ -1641,7 +1687,9 @@ class CSharpGenerator : public BaseGenerator {
for (auto it = enum_def.Vals().begin(); it != enum_def.Vals().end(); for (auto it = enum_def.Vals().begin(); it != enum_def.Vals().end();
++it) { ++it) {
const auto& ev = **it; const auto& ev = **it;
if (ev.IsZero()) { continue; } if (ev.IsZero()) {
continue;
}
ret += " case " + Name(enum_def) + "." + Name(ev) + ":\n"; ret += " case " + Name(enum_def) + "." + Name(ev) + ":\n";
@@ -1695,7 +1743,9 @@ class CSharpGenerator : public BaseGenerator {
} }
auto union_name = enum_def.name + "Union"; auto union_name = enum_def.name + "Union";
auto class_member = std::string("Value"); auto class_member = std::string("Value");
if (class_member == enum_def.name) { class_member += "_"; }; if (class_member == enum_def.name) {
class_member += "_";
};
code += "class " + union_name + " {\n"; code += "class " + union_name + " {\n";
// Type // Type
code += " public " + enum_def.name + " Type { get; set; }\n"; code += " public " + enum_def.name + " Type { get; set; }\n";
@@ -1922,7 +1972,9 @@ class CSharpGenerator : public BaseGenerator {
auto& field = **it; auto& field = **it;
if (field.deprecated) continue; if (field.deprecated) continue;
auto camel_name = Name(field); auto camel_name = Name(field);
if (camel_name == struct_def.name) { camel_name += "_"; } if (camel_name == struct_def.name) {
camel_name += "_";
}
auto camel_name_short = Name(field); auto camel_name_short = Name(field);
auto start = " _o." + camel_name + " = "; auto start = " _o." + camel_name + " = ";
switch (field.value.type.base_type) { switch (field.value.type.base_type) {
@@ -1975,7 +2027,8 @@ class CSharpGenerator : public BaseGenerator {
code += ");}\n"; code += ");}\n";
} }
break; break;
case BASE_TYPE_UTYPE: break; case BASE_TYPE_UTYPE:
break;
case BASE_TYPE_UNION: { case BASE_TYPE_UNION: {
GenUnionUnPack_ObjectAPI(*field.value.type.enum_def, code_ptr, GenUnionUnPack_ObjectAPI(*field.value.type.enum_def, code_ptr,
camel_name, camel_name_short, false); camel_name, camel_name_short, false);
@@ -1998,7 +2051,9 @@ class CSharpGenerator : public BaseGenerator {
auto& field = **it; auto& field = **it;
if (field.deprecated) continue; if (field.deprecated) continue;
auto camel_name = Name(field); auto camel_name = Name(field);
if (camel_name == struct_def.name) { camel_name += "_"; } if (camel_name == struct_def.name) {
camel_name += "_";
}
auto camel_name_short = Name(field); auto camel_name_short = Name(field);
// pre // pre
switch (field.value.type.base_type) { switch (field.value.type.base_type) {
@@ -2061,7 +2116,9 @@ class CSharpGenerator : public BaseGenerator {
to_array = NamespacedName(*field.value.type.enum_def) + to_array = NamespacedName(*field.value.type.enum_def) +
"Union.Pack(builder, _o." + property_name + "[_j])"; "Union.Pack(builder, _o." + property_name + "[_j])";
break; break;
default: gen_for_loop = false; break; default:
gen_for_loop = false;
break;
} }
code += " var _" + field.name + " = default(VectorOffset);\n"; code += " var _" + field.name + " = default(VectorOffset);\n";
code += " if (_o." + property_name + " != null) {\n"; code += " if (_o." + property_name + " != null) {\n";
@@ -2121,7 +2178,8 @@ class CSharpGenerator : public BaseGenerator {
".Pack(builder, _o." + camel_name + ");\n"; ".Pack(builder, _o." + camel_name + ");\n";
break; break;
} }
default: break; default:
break;
} }
} }
if (struct_has_create) { if (struct_has_create) {
@@ -2133,7 +2191,9 @@ class CSharpGenerator : public BaseGenerator {
auto& field = **it; auto& field = **it;
if (field.deprecated) continue; if (field.deprecated) continue;
auto camel_name = Name(field); auto camel_name = Name(field);
if (camel_name == struct_def.name) { camel_name += "_"; } if (camel_name == struct_def.name) {
camel_name += "_";
}
switch (field.value.type.base_type) { switch (field.value.type.base_type) {
case BASE_TYPE_STRUCT: { case BASE_TYPE_STRUCT: {
if (struct_def.fixed) { if (struct_def.fixed) {
@@ -2165,9 +2225,12 @@ class CSharpGenerator : public BaseGenerator {
} }
break; break;
} }
case BASE_TYPE_UNION: FLATBUFFERS_FALLTHROUGH(); // fall thru case BASE_TYPE_UNION:
case BASE_TYPE_UTYPE: FLATBUFFERS_FALLTHROUGH(); // fall thru FLATBUFFERS_FALLTHROUGH(); // fall thru
case BASE_TYPE_STRING: FLATBUFFERS_FALLTHROUGH(); // fall thru case BASE_TYPE_UTYPE:
FLATBUFFERS_FALLTHROUGH(); // fall thru
case BASE_TYPE_STRING:
FLATBUFFERS_FALLTHROUGH(); // fall thru
case BASE_TYPE_VECTOR: { case BASE_TYPE_VECTOR: {
code += ",\n"; code += ",\n";
code += " _" + field.name; code += " _" + field.name;
@@ -2200,14 +2263,17 @@ class CSharpGenerator : public BaseGenerator {
} }
break; break;
} }
case BASE_TYPE_STRING: FLATBUFFERS_FALLTHROUGH(); // fall thru case BASE_TYPE_STRING:
case BASE_TYPE_ARRAY: FLATBUFFERS_FALLTHROUGH(); // fall thru FLATBUFFERS_FALLTHROUGH(); // fall thru
case BASE_TYPE_ARRAY:
FLATBUFFERS_FALLTHROUGH(); // fall thru
case BASE_TYPE_VECTOR: { case BASE_TYPE_VECTOR: {
code += code +=
" Add" + camel_name + "(builder, _" + field.name + ");\n"; " Add" + camel_name + "(builder, _" + field.name + ");\n";
break; break;
} }
case BASE_TYPE_UTYPE: break; case BASE_TYPE_UTYPE:
break;
case BASE_TYPE_UNION: { case BASE_TYPE_UNION: {
code += " Add" + camel_name + "Type(builder, _" + field.name + code += " Add" + camel_name + "Type(builder, _" + field.name +
"_type);\n"; "_type);\n";
@@ -2261,7 +2327,9 @@ class CSharpGenerator : public BaseGenerator {
if (array_only_lengths.size() > 0) { if (array_only_lengths.size() > 0) {
code += "new " + GenTypeBasic(field_type) + "["; code += "new " + GenTypeBasic(field_type) + "[";
for (size_t i = 0; i < array_only_lengths.size(); ++i) { for (size_t i = 0; i < array_only_lengths.size(); ++i) {
if (i != 0) { code += ","; } if (i != 0) {
code += ",";
}
code += NumToString(array_only_lengths[i].length); code += NumToString(array_only_lengths[i].length);
} }
code += "];\n"; code += "];\n";
@@ -2327,8 +2395,10 @@ class CSharpGenerator : public BaseGenerator {
auto type_name = GenTypeGet(type); auto type_name = GenTypeGet(type);
// Replace to ObjectBaseAPI Type Name // Replace to ObjectBaseAPI Type Name
switch (type.base_type) { switch (type.base_type) {
case BASE_TYPE_STRUCT: FLATBUFFERS_FALLTHROUGH(); // fall thru case BASE_TYPE_STRUCT:
case BASE_TYPE_ARRAY: FLATBUFFERS_FALLTHROUGH(); // fall thru FLATBUFFERS_FALLTHROUGH(); // fall thru
case BASE_TYPE_ARRAY:
FLATBUFFERS_FALLTHROUGH(); // fall thru
case BASE_TYPE_VECTOR: { case BASE_TYPE_VECTOR: {
if (type.struct_def != nullptr) { if (type.struct_def != nullptr) {
auto type_name_length = type.struct_def->name.length(); auto type_name_length = type.struct_def->name.length();
@@ -2346,7 +2416,8 @@ class CSharpGenerator : public BaseGenerator {
type_name = NamespacedName(*type.enum_def) + "Union"; type_name = NamespacedName(*type.enum_def) + "Union";
break; break;
} }
default: break; default:
break;
} }
switch (type.base_type) { switch (type.base_type) {
@@ -2358,7 +2429,8 @@ class CSharpGenerator : public BaseGenerator {
type_name = "List<" + type_name + ">"; type_name = "List<" + type_name + ">";
break; break;
} }
default: break; default:
break;
} }
return type_name; return type_name;
} }
@@ -2388,7 +2460,9 @@ class CSharpGenerator : public BaseGenerator {
auto type_name = GenTypeGet_ObjectAPI(field.value.type, opts); auto type_name = GenTypeGet_ObjectAPI(field.value.type, opts);
if (field.IsScalarOptional()) type_name += "?"; if (field.IsScalarOptional()) type_name += "?";
auto camel_name = Name(field); auto camel_name = Name(field);
if (camel_name == struct_def.name) { camel_name += "_"; } if (camel_name == struct_def.name) {
camel_name += "_";
}
if (opts.cs_gen_json_serializer) { if (opts.cs_gen_json_serializer) {
if (IsUnion(field.value.type)) { if (IsUnion(field.value.type)) {
auto utype_name = NamespacedName(*field.value.type.enum_def); auto utype_name = NamespacedName(*field.value.type.enum_def);
@@ -2455,7 +2529,9 @@ class CSharpGenerator : public BaseGenerator {
if (field.value.type.base_type == BASE_TYPE_UTYPE) continue; if (field.value.type.base_type == BASE_TYPE_UTYPE) continue;
if (field.value.type.element == BASE_TYPE_UTYPE) continue; if (field.value.type.element == BASE_TYPE_UTYPE) continue;
auto camel_name = Name(field); auto camel_name = Name(field);
if (camel_name == struct_def.name) { camel_name += "_"; } if (camel_name == struct_def.name) {
camel_name += "_";
}
code += " this." + camel_name + " = "; code += " this." + camel_name + " = ";
auto type_name = GenTypeGet_ObjectAPI(field.value.type, opts); auto type_name = GenTypeGet_ObjectAPI(field.value.type, opts);
if (IsScalar(field.value.type.base_type)) { if (IsScalar(field.value.type.base_type)) {
@@ -2532,12 +2608,13 @@ class CSharpCodeGenerator : public CodeGenerator {
public: public:
Status GenerateCode(const Parser& parser, const std::string& path, Status GenerateCode(const Parser& parser, const std::string& path,
const std::string& filename) override { const std::string& filename) override {
if (!GenerateCSharp(parser, path, filename)) { return Status::ERROR; } if (!GenerateCSharp(parser, path, filename)) {
return Status::ERROR;
}
return Status::OK; return Status::OK;
} }
Status GenerateCode(const uint8_t *, int64_t, Status GenerateCode(const uint8_t*, int64_t, const CodeGenOptions&) override {
const CodeGenOptions &) override {
return Status::NOT_IMPLEMENTED; return Status::NOT_IMPLEMENTED;
} }

View File

@@ -59,16 +59,18 @@ static std::set<std::string> DartKeywords() {
// see https://www.dartlang.org/guides/language/language-tour#keywords // see https://www.dartlang.org/guides/language/language-tour#keywords
// yield*, async*, and sync* shouldn't be proble // yield*, async*, and sync* shouldn't be proble
return { return {
"abstract", "else", "import", "show", "as", "enum", "abstract", "else", "import", "show", "as",
"in", "static", "assert", "export", "interface", "super", "enum", "in", "static", "assert", "export",
"async", "extends", "is", "switch", "await", "extension", "interface", "super", "async", "extends", "is",
"late", "sync", "break", "external", "library", "this", "switch", "await", "extension", "late", "sync",
"case", "factory", "mixin", "throw", "catch", "false", "break", "external", "library", "this", "case",
"new", "true", "class", "final", "null", "try", "factory", "mixin", "throw", "catch", "false",
"const", "finally", "on", "typedef", "continue", "for", "new", "true", "class", "final", "null",
"operator", "var", "covariant", "Function", "part", "void", "try", "const", "finally", "on", "typedef",
"default", "get", "required", "while", "deferred", "hide", "continue", "for", "operator", "var", "covariant",
"rethrow", "with", "do", "if", "return", "yield", "Function", "part", "void", "default", "get",
"required", "while", "deferred", "hide", "rethrow",
"with", "do", "if", "return", "yield",
"dynamic", "implements", "set", "dynamic", "implements", "set",
}; };
} }
@@ -126,7 +128,9 @@ class DartGenerator : public BaseGenerator {
} }
std::string import_code = ""; std::string import_code = "";
for (const auto &file : imports) { import_code += file; } for (const auto& file : imports) {
import_code += file;
}
import_code += import_code.empty() ? "" : "\n"; import_code += import_code.empty() ? "" : "\n";
@@ -137,7 +141,9 @@ class DartGenerator : public BaseGenerator {
"// ignore_for_file: unused_import, unused_field, unused_element, " "// ignore_for_file: unused_import, unused_field, unused_element, "
"unused_local_variable, constant_identifier_names\n\n"; "unused_local_variable, constant_identifier_names\n\n";
if (!kv->first.empty()) { code += "library " + kv->first + ";\n\n"; } if (!kv->first.empty()) {
code += "library " + kv->first + ";\n\n";
}
code += "import 'dart:typed_data' show Uint8List;\n"; code += "import 'dart:typed_data' show Uint8List;\n";
code += "import 'package:flat_buffers/flat_buffers.dart' as " + _kFb + code += "import 'package:flat_buffers/flat_buffers.dart' as " + _kFb +
@@ -156,7 +162,9 @@ class DartGenerator : public BaseGenerator {
code += kv->second; code += kv->second;
if (!SaveFile(Filename(kv->first).c_str(), code, false)) { return false; } if (!SaveFile(Filename(kv->first).c_str(), code, false)) {
return false;
}
} }
return true; return true;
} }
@@ -227,7 +235,9 @@ class DartGenerator : public BaseGenerator {
if (it != enum_def.Vals().begin()) code += ",\n"; if (it != enum_def.Vals().begin()) code += ",\n";
code += " " + enum_var + "(" + enum_def.ToString(ev) + ")"; code += " " + enum_var + "(" + enum_def.ToString(ev) + ")";
} }
if (auto_default) { code += ",\n _default(0)"; } if (auto_default) {
code += ",\n _default(0)";
}
code += ";\n\n"; code += ";\n\n";
code += " final int value;\n"; code += " final int value;\n";
@@ -285,23 +295,39 @@ class DartGenerator : public BaseGenerator {
std::string GenType(const Type& type) { std::string GenType(const Type& type) {
switch (type.base_type) { switch (type.base_type) {
case BASE_TYPE_BOOL: return "Bool"; case BASE_TYPE_BOOL:
case BASE_TYPE_CHAR: return "Int8"; return "Bool";
case BASE_TYPE_CHAR:
return "Int8";
case BASE_TYPE_UTYPE: case BASE_TYPE_UTYPE:
case BASE_TYPE_UCHAR: return "Uint8"; case BASE_TYPE_UCHAR:
case BASE_TYPE_SHORT: return "Int16"; return "Uint8";
case BASE_TYPE_USHORT: return "Uint16"; case BASE_TYPE_SHORT:
case BASE_TYPE_INT: return "Int32"; return "Int16";
case BASE_TYPE_UINT: return "Uint32"; case BASE_TYPE_USHORT:
case BASE_TYPE_LONG: return "Int64"; return "Uint16";
case BASE_TYPE_ULONG: return "Uint64"; case BASE_TYPE_INT:
case BASE_TYPE_FLOAT: return "Float32"; return "Int32";
case BASE_TYPE_DOUBLE: return "Float64"; case BASE_TYPE_UINT:
case BASE_TYPE_STRING: return "String"; return "Uint32";
case BASE_TYPE_VECTOR: return GenType(type.VectorType()); case BASE_TYPE_LONG:
case BASE_TYPE_STRUCT: return namer_.Type(*type.struct_def); return "Int64";
case BASE_TYPE_UNION: return namer_.Type(*type.enum_def) + "TypeId"; case BASE_TYPE_ULONG:
default: return "Table"; return "Uint64";
case BASE_TYPE_FLOAT:
return "Float32";
case BASE_TYPE_DOUBLE:
return "Float64";
case BASE_TYPE_STRING:
return "String";
case BASE_TYPE_VECTOR:
return GenType(type.VectorType());
case BASE_TYPE_STRUCT:
return namer_.Type(*type.struct_def);
case BASE_TYPE_UNION:
return namer_.Type(*type.enum_def) + "TypeId";
default:
return "Table";
} }
} }
@@ -310,16 +336,21 @@ class DartGenerator : public BaseGenerator {
case BASE_TYPE_BOOL: case BASE_TYPE_BOOL:
case BASE_TYPE_CHAR: case BASE_TYPE_CHAR:
case BASE_TYPE_UTYPE: case BASE_TYPE_UTYPE:
case BASE_TYPE_UCHAR: return "1"; case BASE_TYPE_UCHAR:
return "1";
case BASE_TYPE_SHORT: case BASE_TYPE_SHORT:
case BASE_TYPE_USHORT: return "2"; case BASE_TYPE_USHORT:
return "2";
case BASE_TYPE_INT: case BASE_TYPE_INT:
case BASE_TYPE_UINT: case BASE_TYPE_UINT:
case BASE_TYPE_FLOAT: return "4"; case BASE_TYPE_FLOAT:
return "4";
case BASE_TYPE_LONG: case BASE_TYPE_LONG:
case BASE_TYPE_ULONG: case BASE_TYPE_ULONG:
case BASE_TYPE_DOUBLE: return "8"; case BASE_TYPE_DOUBLE:
default: return "1"; return "8";
default:
return "1";
} }
} }
@@ -371,7 +402,8 @@ class DartGenerator : public BaseGenerator {
} }
switch (type.base_type) { switch (type.base_type) {
case BASE_TYPE_BOOL: return "bool"; case BASE_TYPE_BOOL:
return "bool";
case BASE_TYPE_LONG: case BASE_TYPE_LONG:
case BASE_TYPE_ULONG: case BASE_TYPE_ULONG:
case BASE_TYPE_INT: case BASE_TYPE_INT:
@@ -379,10 +411,13 @@ class DartGenerator : public BaseGenerator {
case BASE_TYPE_SHORT: case BASE_TYPE_SHORT:
case BASE_TYPE_USHORT: case BASE_TYPE_USHORT:
case BASE_TYPE_CHAR: case BASE_TYPE_CHAR:
case BASE_TYPE_UCHAR: return "int"; case BASE_TYPE_UCHAR:
return "int";
case BASE_TYPE_FLOAT: case BASE_TYPE_FLOAT:
case BASE_TYPE_DOUBLE: return "double"; case BASE_TYPE_DOUBLE:
case BASE_TYPE_STRING: return "String"; return "double";
case BASE_TYPE_STRING:
return "String";
case BASE_TYPE_STRUCT: case BASE_TYPE_STRUCT:
return MaybeWrapNamespace( return MaybeWrapNamespace(
namer_.Type(*type.struct_def) + struct_type_suffix, namer_.Type(*type.struct_def) + struct_type_suffix,
@@ -392,7 +427,9 @@ class DartGenerator : public BaseGenerator {
GenDartTypeName(type.VectorType(), current_namespace, def, GenDartTypeName(type.VectorType(), current_namespace, def,
struct_type_suffix) + struct_type_suffix) +
">"; ">";
default: assert(0); return "dynamic"; default:
assert(0);
return "dynamic";
} }
} }
@@ -637,7 +674,9 @@ class DartGenerator : public BaseGenerator {
ns += CharToLower(part[i]); ns += CharToLower(part[i]);
} }
} }
if (it != qualified_name_parts.end() - 1) { ns += "_"; } if (it != qualified_name_parts.end() - 1) {
ns += "_";
}
} }
return ns + "." + namer_.Type(*type.struct_def); return ns + "." + namer_.Type(*type.struct_def);
@@ -730,7 +769,9 @@ class DartGenerator : public BaseGenerator {
escaped_field.push_back(field[i]); escaped_field.push_back(field[i]);
} }
code += escaped_field + ": ${" + field + "}"; code += escaped_field + ": ${" + field + "}";
if (it != non_deprecated_fields.end() - 1) { code += ", "; } if (it != non_deprecated_fields.end() - 1) {
code += ", ";
}
} }
code += "}';\n"; code += "}';\n";
code += " }\n"; code += " }\n";
@@ -739,7 +780,9 @@ class DartGenerator : public BaseGenerator {
std::string getDefaultValue(const Value& value) const { std::string getDefaultValue(const Value& value) const {
if (!value.constant.empty() && value.constant != "0") { if (!value.constant.empty() && value.constant != "0") {
if (IsBool(value.type.base_type)) { return "true"; } if (IsBool(value.type.base_type)) {
return "true";
}
if (IsScalar(value.type.base_type)) { if (IsScalar(value.type.base_type)) {
if (StringIsFlatbufferNan(value.constant)) { if (StringIsFlatbufferNan(value.constant)) {
return "double.nan"; return "double.nan";
@@ -787,7 +830,9 @@ class DartGenerator : public BaseGenerator {
const StructDef& struct_def, const StructDef& struct_def,
const std::vector<std::pair<int, FieldDef*>>& non_deprecated_fields, const std::vector<std::pair<int, FieldDef*>>& non_deprecated_fields,
const std::string& builder_name, std::string& code) { const std::string& builder_name, std::string& code) {
if (non_deprecated_fields.size() == 0) { return; } if (non_deprecated_fields.size() == 0) {
return;
}
code += "class " + builder_name + " {\n"; code += "class " + builder_name + " {\n";
code += " " + builder_name + "(this.fbBuilder);\n\n"; code += " " + builder_name + "(this.fbBuilder);\n\n";
@@ -819,7 +864,9 @@ class DartGenerator : public BaseGenerator {
field); field);
} }
code += " " + field_name; code += " " + field_name;
if (it != non_deprecated_fields.end() - 1) { code += ", "; } if (it != non_deprecated_fields.end() - 1) {
code += ", ";
}
} }
code += ") {\n"; code += ") {\n";
@@ -837,7 +884,9 @@ class DartGenerator : public BaseGenerator {
} else { } else {
code += " fbBuilder.put" + GenType(field.value.type) + "("; code += " fbBuilder.put" + GenType(field.value.type) + "(";
code += field_name; code += field_name;
if (field.value.type.enum_def) { code += ".value"; } if (field.value.type.enum_def) {
code += ".value";
}
code += ");\n"; code += ");\n";
} }
} }
@@ -869,7 +918,9 @@ class DartGenerator : public BaseGenerator {
code += " fbBuilder.add" + GenType(field.value.type) + "(" + code += " fbBuilder.add" + GenType(field.value.type) + "(" +
NumToString(offset) + ", "; NumToString(offset) + ", ";
code += field_var; code += field_var;
if (field.value.type.enum_def) { code += "?.value"; } if (field.value.type.enum_def) {
code += "?.value";
}
code += ");\n"; code += ");\n";
} else if (IsStruct(field.value.type)) { } else if (IsStruct(field.value.type)) {
code += " int " + add_field + "(int offset) {\n"; code += " int " + add_field + "(int offset) {\n";
@@ -1044,13 +1095,19 @@ class DartGenerator : public BaseGenerator {
if (IsStruct(field.value.type)) { if (IsStruct(field.value.type)) {
code += " "; code += " ";
if (prependUnderscore) { code += "_"; } if (prependUnderscore) {
code += "_";
}
code += field_name + (pack ? ".pack" : ".finish") + "(fbBuilder);\n"; code += field_name + (pack ? ".pack" : ".finish") + "(fbBuilder);\n";
} else { } else {
code += " fbBuilder.put" + GenType(field.value.type) + "("; code += " fbBuilder.put" + GenType(field.value.type) + "(";
if (prependUnderscore) { code += "_"; } if (prependUnderscore) {
code += "_";
}
code += field_name; code += field_name;
if (field.value.type.enum_def) { code += ".value"; } if (field.value.type.enum_def) {
code += ".value";
}
code += ");\n"; code += ");\n";
} }
} }
@@ -1127,12 +1184,13 @@ class DartCodeGenerator : public CodeGenerator {
public: public:
Status GenerateCode(const Parser& parser, const std::string& path, Status GenerateCode(const Parser& parser, const std::string& path,
const std::string& filename) override { const std::string& filename) override {
if (!GenerateDart(parser, path, filename)) { return Status::ERROR; } if (!GenerateDart(parser, path, filename)) {
return Status::ERROR;
}
return Status::OK; return Status::OK;
} }
Status GenerateCode(const uint8_t *, int64_t, Status GenerateCode(const uint8_t*, int64_t, const CodeGenOptions&) override {
const CodeGenOptions &) override {
return Status::NOT_IMPLEMENTED; return Status::NOT_IMPLEMENTED;
} }

View File

@@ -35,7 +35,8 @@ static std::string GenType(const Type &type, bool underlying = false) {
case BASE_TYPE_STRUCT: case BASE_TYPE_STRUCT:
return type.struct_def->defined_namespace->GetFullyQualifiedName( return type.struct_def->defined_namespace->GetFullyQualifiedName(
type.struct_def->name); type.struct_def->name);
case BASE_TYPE_VECTOR: return "[" + GenType(type.VectorType()) + "]"; case BASE_TYPE_VECTOR:
return "[" + GenType(type.VectorType()) + "]";
default: default:
if (type.enum_def && !underlying) { if (type.enum_def && !underlying) {
return type.enum_def->defined_namespace->GetFullyQualifiedName( return type.enum_def->defined_namespace->GetFullyQualifiedName(
@@ -66,7 +67,9 @@ static bool HasNonPositiveFieldId(const std::vector<FieldDef *> &fields) {
if (id_attribute != nullptr && !id_attribute->constant.empty()) { if (id_attribute != nullptr && !id_attribute->constant.empty()) {
voffset_t proto_id = 0; voffset_t proto_id = 0;
bool done = StringToNumber(id_attribute->constant.c_str(), &proto_id); bool done = StringToNumber(id_attribute->constant.c_str(), &proto_id);
if (!done) { return true; } if (!done) {
return true;
}
} }
} }
return false; return false;
@@ -82,10 +85,14 @@ static bool HasFieldIdFromReservedIds(
if (id_attribute != nullptr && !id_attribute->constant.empty()) { if (id_attribute != nullptr && !id_attribute->constant.empty()) {
voffset_t proto_id = 0; voffset_t proto_id = 0;
bool done = StringToNumber(id_attribute->constant.c_str(), &proto_id); bool done = StringToNumber(id_attribute->constant.c_str(), &proto_id);
if (!done) { return true; } if (!done) {
return true;
}
auto id_it = auto id_it =
std::find(std::begin(reserved_ids), std::end(reserved_ids), proto_id); std::find(std::begin(reserved_ids), std::end(reserved_ids), proto_id);
if (id_it != reserved_ids.end()) { return true; } if (id_it != reserved_ids.end()) {
return true;
}
} }
} }
return false; return false;
@@ -100,7 +107,9 @@ static std::vector<voffset_t> ExtractProtobufIds(
if (id_attribute != nullptr && !id_attribute->constant.empty()) { if (id_attribute != nullptr && !id_attribute->constant.empty()) {
voffset_t proto_id = 0; voffset_t proto_id = 0;
bool done = StringToNumber(id_attribute->constant.c_str(), &proto_id); bool done = StringToNumber(id_attribute->constant.c_str(), &proto_id);
if (done) { used_proto_ids.push_back(proto_id); } if (done) {
used_proto_ids.push_back(proto_id);
}
} }
} }
@@ -112,7 +121,9 @@ static bool HasTwiceUsedId(const std::vector<FieldDef *> &fields) {
std::sort(std::begin(used_proto_ids), std::end(used_proto_ids)); std::sort(std::begin(used_proto_ids), std::end(used_proto_ids));
for (auto it = std::next(std::begin(used_proto_ids)); for (auto it = std::next(std::begin(used_proto_ids));
it != std::end(used_proto_ids); it++) { it != std::end(used_proto_ids); it++) {
if (*it == *std::prev(it)) { return true; } if (*it == *std::prev(it)) {
return true;
}
} }
return false; return false;
@@ -123,7 +134,9 @@ static bool HasGapInProtoId(const std::vector<FieldDef *> &fields) {
std::sort(std::begin(used_proto_ids), std::end(used_proto_ids)); std::sort(std::begin(used_proto_ids), std::end(used_proto_ids));
for (auto it = std::next(std::begin(used_proto_ids)); for (auto it = std::next(std::begin(used_proto_ids));
it != std::end(used_proto_ids); it++) { it != std::end(used_proto_ids); it++) {
if (*it != *std::prev(it) + 1) { return true; } if (*it != *std::prev(it) + 1) {
return true;
}
} }
return false; return false;
@@ -167,7 +180,9 @@ static bool ProtobufIdSanityCheck(const StructDef &struct_def,
fprintf(stderr, "Fields in struct %s have gap between ids\n", fprintf(stderr, "Fields in struct %s have gap between ids\n",
struct_def.name.c_str()); struct_def.name.c_str());
} }
if (gap_action == IDLOptions::ProtoIdGapAction::ERROR) { return false; } if (gap_action == IDLOptions::ProtoIdGapAction::ERROR) {
return false;
}
} }
} }
@@ -194,7 +209,9 @@ static ProtobufToFbsIdMap MapProtoIdsToFieldsId(
return result; return result;
} }
if (!ProtobufIdSanityCheck(struct_def, gap_action, no_log)) { return {}; } if (!ProtobufIdSanityCheck(struct_def, gap_action, no_log)) {
return {};
}
static constexpr int UNION_ID = -1; static constexpr int UNION_ID = -1;
using ProtoIdFieldNamePair = std::pair<int, std::string>; using ProtoIdFieldNamePair = std::pair<int, std::string>;
@@ -231,7 +248,9 @@ static ProtobufToFbsIdMap MapProtoIdsToFieldsId(
voffset_t id = 0; voffset_t id = 0;
for (const auto& element : proto_ids) { for (const auto& element : proto_ids) {
if (element.first == UNION_ID) { id++; } if (element.first == UNION_ID) {
id++;
}
proto_to_fbs.field_to_id.emplace(element.second, id++); proto_to_fbs.field_to_id.emplace(element.second, id++);
} }
proto_to_fbs.successful = true; proto_to_fbs.successful = true;
@@ -332,7 +351,9 @@ static std::string GenerateFBS(const Parser &parser,
StructDef& struct_def = **it; StructDef& struct_def = **it;
const auto proto_fbs_ids = MapProtoIdsToFieldsId( const auto proto_fbs_ids = MapProtoIdsToFieldsId(
struct_def, parser.opts.proto_id_gap_action, no_log); struct_def, parser.opts.proto_id_gap_action, no_log);
if (!proto_fbs_ids.successful) { return {}; } if (!proto_fbs_ids.successful) {
return {};
}
if (parser.opts.include_dependence_headers && struct_def.generated) { if (parser.opts.include_dependence_headers && struct_def.generated) {
continue; continue;
@@ -379,7 +400,9 @@ static std::string GenerateFBS(const Parser &parser,
static bool GenerateFBS(const Parser& parser, const std::string& path, static bool GenerateFBS(const Parser& parser, const std::string& path,
const std::string& file_name, bool no_log = false) { const std::string& file_name, bool no_log = false) {
const std::string fbs = GenerateFBS(parser, file_name, no_log); const std::string fbs = GenerateFBS(parser, file_name, no_log);
if (fbs.empty()) { return false; } if (fbs.empty()) {
return false;
}
// TODO: Use LogCompilerWarn // TODO: Use LogCompilerWarn
if (!no_log) { if (!no_log) {
fprintf(stderr, fprintf(stderr,
@@ -395,7 +418,9 @@ class FBSCodeGenerator : public CodeGenerator {
Status GenerateCode(const Parser& parser, const std::string& path, Status GenerateCode(const Parser& parser, const std::string& path,
const std::string& filename) override { const std::string& filename) override {
if (!GenerateFBS(parser, path, filename, no_log_)) { return Status::ERROR; } if (!GenerateFBS(parser, path, filename, no_log_)) {
return Status::ERROR;
}
return Status::OK; return Status::OK;
} }
@@ -407,8 +432,7 @@ class FBSCodeGenerator : public CodeGenerator {
// Generate code from the provided `buffer` of given `length`. The buffer is a // Generate code from the provided `buffer` of given `length`. The buffer is a
// serialized reflection.fbs. // serialized reflection.fbs.
Status GenerateCode(const uint8_t *, int64_t, Status GenerateCode(const uint8_t*, int64_t, const CodeGenOptions&) override {
const CodeGenOptions &) override {
return Status::NOT_IMPLEMENTED; return Status::NOT_IMPLEMENTED;
} }

View File

@@ -155,7 +155,9 @@ class GoGenerator : public BaseGenerator {
bool generateStructs(std::string* one_file_code) { bool generateStructs(std::string* one_file_code) {
for (auto it = parser_.structs_.vec.begin(); for (auto it = parser_.structs_.vec.begin();
it != parser_.structs_.vec.end(); ++it) { it != parser_.structs_.vec.end(); ++it) {
if (!parser_.opts.one_file) { ResetImports(); } if (!parser_.opts.one_file) {
ResetImports();
}
std::string declcode; std::string declcode;
auto& struct_def = **it; auto& struct_def = **it;
GenStruct(struct_def, &declcode); GenStruct(struct_def, &declcode);
@@ -444,7 +446,9 @@ class GoGenerator : public BaseGenerator {
code += "\t\treturn "; code += "\t\treturn ";
} }
code += CastToEnum(field.value.type, getter + "(o + rcv._tab.Pos)"); code += CastToEnum(field.value.type, getter + "(o + rcv._tab.Pos)");
if (field.IsScalarOptional()) { code += "\n\t\treturn &v"; } if (field.IsScalarOptional()) {
code += "\n\t\treturn &v";
}
code += "\n\t}\n"; code += "\n\t}\n";
code += "\treturn " + GenConstant(field) + "\n"; code += "\treturn " + GenConstant(field) + "\n";
code += "}\n\n"; code += "}\n\n";
@@ -782,8 +786,11 @@ class GoGenerator : public BaseGenerator {
} }
break; break;
} }
case BASE_TYPE_UNION: GetUnionField(struct_def, field, code_ptr); break; case BASE_TYPE_UNION:
default: FLATBUFFERS_ASSERT(0); GetUnionField(struct_def, field, code_ptr);
break;
default:
FLATBUFFERS_ASSERT(0);
} }
} }
if (IsVector(field.value.type)) { if (IsVector(field.value.type)) {
@@ -964,7 +971,9 @@ class GoGenerator : public BaseGenerator {
code += "buf []byte) bool {\n"; code += "buf []byte) bool {\n";
code += "\tspan := flatbuffers.GetUOffsetT(buf[vectorLocation-4:])\n"; code += "\tspan := flatbuffers.GetUOffsetT(buf[vectorLocation-4:])\n";
code += "\tstart := flatbuffers.UOffsetT(0)\n"; code += "\tstart := flatbuffers.UOffsetT(0)\n";
if (IsString(field.value.type)) { code += "\tbKey := []byte(key)\n"; } if (IsString(field.value.type)) {
code += "\tbKey := []byte(key)\n";
}
code += "\tfor span != 0 {\n"; code += "\tfor span != 0 {\n";
code += "\t\tmiddle := span / 2\n"; code += "\t\tmiddle := span / 2\n";
code += "\t\ttableOffset := flatbuffers.GetIndirectOffset(buf, "; code += "\t\ttableOffset := flatbuffers.GetIndirectOffset(buf, ";
@@ -1015,7 +1024,9 @@ class GoGenerator : public BaseGenerator {
field.value.type.enum_def->is_union) field.value.type.enum_def->is_union)
continue; continue;
code += "\t" + namer_.Field(field) + " "; code += "\t" + namer_.Field(field) + " ";
if (field.IsScalarOptional()) { code += "*"; } if (field.IsScalarOptional()) {
code += "*";
}
code += NativeType(field.value.type) + " `json:\"" + field.name + "\"`" + code += NativeType(field.value.type) + " `json:\"" + field.name + "\"`" +
"\n"; "\n";
} }
@@ -1194,7 +1205,9 @@ class GoGenerator : public BaseGenerator {
code += "\t" + struct_type + "Add" + field_fn + "(builder, " + code += "\t" + struct_type + "Add" + field_fn + "(builder, " +
prefix + "t." + field_field + ")\n"; prefix + "t." + field_field + ")\n";
} }
if (field.IsScalarOptional()) { code += "\t}\n"; } if (field.IsScalarOptional()) {
code += "\t}\n";
}
} else { } else {
if (field.value.type.base_type == BASE_TYPE_STRUCT && if (field.value.type.base_type == BASE_TYPE_STRUCT &&
field.value.type.struct_def->fixed) { field.value.type.struct_def->fixed) {
@@ -1385,10 +1398,14 @@ class GoGenerator : public BaseGenerator {
// Returns the function name that is able to read a value of the given type. // Returns the function name that is able to read a value of the given type.
std::string GenGetter(const Type& type) { std::string GenGetter(const Type& type) {
switch (type.base_type) { switch (type.base_type) {
case BASE_TYPE_STRING: return "rcv._tab.ByteVector"; case BASE_TYPE_STRING:
case BASE_TYPE_UNION: return "rcv._tab.Union"; return "rcv._tab.ByteVector";
case BASE_TYPE_VECTOR: return GenGetter(type.VectorType()); case BASE_TYPE_UNION:
default: return "rcv._tab.Get" + namer_.Function(GenTypeBasic(type)); return "rcv._tab.Union";
case BASE_TYPE_VECTOR:
return GenGetter(type.VectorType());
default:
return "rcv._tab.Get" + namer_.Function(GenTypeBasic(type));
} }
} }
@@ -1413,24 +1430,31 @@ class GoGenerator : public BaseGenerator {
std::string GenTypePointer(const Type& type) { std::string GenTypePointer(const Type& type) {
switch (type.base_type) { switch (type.base_type) {
case BASE_TYPE_STRING: return "[]byte"; case BASE_TYPE_STRING:
case BASE_TYPE_VECTOR: return GenTypeGet(type.VectorType()); return "[]byte";
case BASE_TYPE_VECTOR:
return GenTypeGet(type.VectorType());
case BASE_TYPE_STRUCT: case BASE_TYPE_STRUCT:
return WrapInNameSpaceAndTrack(type.struct_def, type.struct_def->name); return WrapInNameSpaceAndTrack(type.struct_def, type.struct_def->name);
case BASE_TYPE_UNION: case BASE_TYPE_UNION:
// fall through // fall through
default: return "*flatbuffers.Table"; default:
return "*flatbuffers.Table";
} }
} }
std::string GenTypeGet(const Type& type) { std::string GenTypeGet(const Type& type) {
if (type.enum_def != nullptr) { return GetEnumTypeName(*type.enum_def); } if (type.enum_def != nullptr) {
return GetEnumTypeName(*type.enum_def);
}
return IsScalar(type.base_type) ? GenTypeBasic(type) : GenTypePointer(type); return IsScalar(type.base_type) ? GenTypeBasic(type) : GenTypePointer(type);
} }
std::string TypeName(const FieldDef& field) { std::string TypeName(const FieldDef& field) {
std::string prefix; std::string prefix;
if (field.IsScalarOptional()) { prefix = "*"; } if (field.IsScalarOptional()) {
prefix = "*";
}
return prefix + GenTypeGet(field.value.type); return prefix + GenTypeGet(field.value.type);
} }
@@ -1455,7 +1479,9 @@ class GoGenerator : public BaseGenerator {
} }
std::string GenConstant(const FieldDef& field) { std::string GenConstant(const FieldDef& field) {
if (field.IsScalarOptional()) { return "nil"; } if (field.IsScalarOptional()) {
return "nil";
}
switch (field.value.type.base_type) { switch (field.value.type.base_type) {
case BASE_TYPE_BOOL: case BASE_TYPE_BOOL:
return field.value.constant == "0" ? "false" : "true"; return field.value.constant == "0" ? "false" : "true";
@@ -1476,7 +1502,8 @@ class GoGenerator : public BaseGenerator {
} }
return field.value.constant; return field.value.constant;
} }
default: return field.value.constant; default:
return field.value.constant;
} }
} }
@@ -1537,8 +1564,12 @@ class GoGenerator : public BaseGenerator {
code += "\tflatbuffers \"github.com/google/flatbuffers/go\"\n"; code += "\tflatbuffers \"github.com/google/flatbuffers/go\"\n";
} }
// math is needed to support non-finite scalar default values. // math is needed to support non-finite scalar default values.
if (needs_math_import_) { code += "\t\"math\"\n"; } if (needs_math_import_) {
if (is_enum) { code += "\t\"strconv\"\n"; } code += "\t\"math\"\n";
}
if (is_enum) {
code += "\t\"strconv\"\n";
}
if (tracked_imported_namespaces_.size() > 0) { if (tracked_imported_namespaces_.size() > 0) {
code += "\n"; code += "\n";
@@ -1555,7 +1586,9 @@ class GoGenerator : public BaseGenerator {
} }
code += ")\n\n"; code += ")\n\n";
} else { } else {
if (is_enum) { code += "import \"strconv\"\n\n"; } if (is_enum) {
code += "import \"strconv\"\n\n";
}
if (needs_math_import_) { if (needs_math_import_) {
// math is needed to support non-finite scalar default values. // math is needed to support non-finite scalar default values.
code += "import \"math\"\n\n"; code += "import \"math\"\n\n";
@@ -1643,12 +1676,13 @@ class GoCodeGenerator : public CodeGenerator {
public: public:
Status GenerateCode(const Parser& parser, const std::string& path, Status GenerateCode(const Parser& parser, const std::string& path,
const std::string& filename) override { const std::string& filename) override {
if (!GenerateGo(parser, path, filename)) { return Status::ERROR; } if (!GenerateGo(parser, path, filename)) {
return Status::ERROR;
}
return Status::OK; return Status::OK;
} }
Status GenerateCode(const uint8_t *, int64_t, Status GenerateCode(const uint8_t*, int64_t, const CodeGenOptions&) override {
const CodeGenOptions &) override {
return Status::NOT_IMPLEMENTED; return Status::NOT_IMPLEMENTED;
} }
@@ -1664,7 +1698,9 @@ class GoCodeGenerator : public CodeGenerator {
Status GenerateGrpcCode(const Parser& parser, const std::string& path, Status GenerateGrpcCode(const Parser& parser, const std::string& path,
const std::string& filename) override { const std::string& filename) override {
if (!GenerateGoGRPC(parser, path, filename)) { return Status::ERROR; } if (!GenerateGoGRPC(parser, path, filename)) {
return Status::ERROR;
}
return Status::OK; return Status::OK;
} }

View File

@@ -175,7 +175,9 @@ class FlatBufPrinter : public grpc_generator::Printer {
} }
void Print(const char* s) { void Print(const char* s) {
if (s == nullptr || *s == '\0') { return; } if (s == nullptr || *s == '\0') {
return;
}
// Add this string, but for each part separated by \n, add indentation. // Add this string, but for each part separated by \n, add indentation.
for (;;) { for (;;) {
// Current indentation. // Current indentation.

View File

@@ -259,12 +259,16 @@ class JavaGenerator : public BaseGenerator {
std::string GenTypePointer(const Type& type) const { std::string GenTypePointer(const Type& type) const {
switch (type.base_type) { switch (type.base_type) {
case BASE_TYPE_STRING: return "String"; case BASE_TYPE_STRING:
case BASE_TYPE_VECTOR: return GenTypeGet(type.VectorType()); return "String";
case BASE_TYPE_VECTOR:
return GenTypeGet(type.VectorType());
case BASE_TYPE_STRUCT: case BASE_TYPE_STRUCT:
return Prefixed(namer_.NamespacedType(*type.struct_def)); return Prefixed(namer_.NamespacedType(*type.struct_def));
case BASE_TYPE_UNION: FLATBUFFERS_FALLTHROUGH(); // else fall thru case BASE_TYPE_UNION:
default: return "Table"; FLATBUFFERS_FALLTHROUGH(); // else fall thru
default:
return "Table";
} }
} }
@@ -281,14 +285,18 @@ class JavaGenerator : public BaseGenerator {
switch (type.base_type) { switch (type.base_type) {
// We use int for both uchar/ushort, since that generally means less // We use int for both uchar/ushort, since that generally means less
// casting than using short for uchar. // casting than using short for uchar.
case BASE_TYPE_UCHAR: return Type(BASE_TYPE_INT); case BASE_TYPE_UCHAR:
case BASE_TYPE_USHORT: return Type(BASE_TYPE_INT); return Type(BASE_TYPE_INT);
case BASE_TYPE_UINT: return Type(BASE_TYPE_LONG); case BASE_TYPE_USHORT:
return Type(BASE_TYPE_INT);
case BASE_TYPE_UINT:
return Type(BASE_TYPE_LONG);
case BASE_TYPE_ARRAY: case BASE_TYPE_ARRAY:
case BASE_TYPE_VECTOR: case BASE_TYPE_VECTOR:
if (vectorelem) return DestinationType(type.VectorType(), vectorelem); if (vectorelem) return DestinationType(type.VectorType(), vectorelem);
FLATBUFFERS_FALLTHROUGH(); // else fall thru FLATBUFFERS_FALLTHROUGH(); // else fall thru
default: return type; default:
return type;
} }
} }
@@ -308,13 +316,17 @@ class JavaGenerator : public BaseGenerator {
// Mask to turn serialized value into destination type value. // Mask to turn serialized value into destination type value.
std::string DestinationMask(const Type& type, bool vectorelem) const { std::string DestinationMask(const Type& type, bool vectorelem) const {
switch (type.base_type) { switch (type.base_type) {
case BASE_TYPE_UCHAR: return " & 0xFF"; case BASE_TYPE_UCHAR:
case BASE_TYPE_USHORT: return " & 0xFFFF"; return " & 0xFF";
case BASE_TYPE_UINT: return " & 0xFFFFFFFFL"; case BASE_TYPE_USHORT:
return " & 0xFFFF";
case BASE_TYPE_UINT:
return " & 0xFFFFFFFFL";
case BASE_TYPE_VECTOR: case BASE_TYPE_VECTOR:
if (vectorelem) return DestinationMask(type.VectorType(), vectorelem); if (vectorelem) return DestinationMask(type.VectorType(), vectorelem);
FLATBUFFERS_FALLTHROUGH(); // else fall thru FLATBUFFERS_FALLTHROUGH(); // else fall thru
default: return ""; default:
return "";
} }
} }
@@ -376,14 +388,16 @@ class JavaGenerator : public BaseGenerator {
auto constant = field.IsScalarOptional() ? "0" : value.constant; auto constant = field.IsScalarOptional() ? "0" : value.constant;
auto longSuffix = "L"; auto longSuffix = "L";
switch (value.type.base_type) { switch (value.type.base_type) {
case BASE_TYPE_BOOL: return constant == "0" ? "false" : "true"; case BASE_TYPE_BOOL:
return constant == "0" ? "false" : "true";
case BASE_TYPE_ULONG: { case BASE_TYPE_ULONG: {
// Converts the ulong into its bits signed equivalent // Converts the ulong into its bits signed equivalent
uint64_t defaultValue = StringToUInt(constant.c_str()); uint64_t defaultValue = StringToUInt(constant.c_str());
return NumToString(static_cast<int64_t>(defaultValue)) + longSuffix; return NumToString(static_cast<int64_t>(defaultValue)) + longSuffix;
} }
case BASE_TYPE_UINT: case BASE_TYPE_UINT:
case BASE_TYPE_LONG: return constant + longSuffix; case BASE_TYPE_LONG:
return constant + longSuffix;
default: default:
if (IsFloat(value.type.base_type)) { if (IsFloat(value.type.base_type)) {
if (field.IsScalarOptional()) { if (field.IsScalarOptional()) {
@@ -398,7 +412,9 @@ class JavaGenerator : public BaseGenerator {
std::string GenDefaultValueBasic(const FieldDef& field) const { std::string GenDefaultValueBasic(const FieldDef& field) const {
auto& value = field.value; auto& value = field.value;
if (!IsScalar(value.type.base_type)) { return "0"; } if (!IsScalar(value.type.base_type)) {
return "0";
}
return GenDefaultValue(field); return GenDefaultValue(field);
} }
@@ -475,11 +491,16 @@ class JavaGenerator : public BaseGenerator {
// Returns the function name that is able to read a value of the given type. // Returns the function name that is able to read a value of the given type.
std::string GenGetter(const Type& type) const { std::string GenGetter(const Type& type) const {
switch (type.base_type) { switch (type.base_type) {
case BASE_TYPE_STRING: return "__string"; case BASE_TYPE_STRING:
case BASE_TYPE_STRUCT: return "__struct"; return "__string";
case BASE_TYPE_UNION: return "__union"; case BASE_TYPE_STRUCT:
case BASE_TYPE_VECTOR: return GenGetter(type.VectorType()); return "__struct";
case BASE_TYPE_ARRAY: return GenGetter(type.VectorType()); case BASE_TYPE_UNION:
return "__union";
case BASE_TYPE_VECTOR:
return GenGetter(type.VectorType());
case BASE_TYPE_ARRAY:
return GenGetter(type.VectorType());
default: { default: {
std::string getter = "bb.get"; std::string getter = "bb.get";
if (type.base_type == BASE_TYPE_BOOL) { if (type.base_type == BASE_TYPE_BOOL) {
@@ -607,7 +628,9 @@ class JavaGenerator : public BaseGenerator {
} }
code += ");\n"; code += ");\n";
} }
if (IsArray(field_type)) { code += indent + " }\n"; } if (IsArray(field_type)) {
code += indent + " }\n";
}
} }
} }
} }
@@ -787,7 +810,9 @@ class JavaGenerator : public BaseGenerator {
code += "(new " + type_name + "(), j); }\n"; code += "(new " + type_name + "(), j); }\n";
} }
if (field.IsScalarOptional()) { code += GenOptionalScalarCheck(field); } if (field.IsScalarOptional()) {
code += GenOptionalScalarCheck(field);
}
std::string getter = dest_cast + GenGetter(field.value.type); std::string getter = dest_cast + GenGetter(field.value.type);
code += method_start; code += method_start;
std::string member_suffix = "; "; std::string member_suffix = "; ";
@@ -828,7 +853,8 @@ class JavaGenerator : public BaseGenerator {
code += offset_prefix + getter + "(o + "; code += offset_prefix + getter + "(o + ";
code += "bb_pos) : null"; code += "bb_pos) : null";
break; break;
case BASE_TYPE_ARRAY: FLATBUFFERS_FALLTHROUGH(); // fall thru case BASE_TYPE_ARRAY:
FLATBUFFERS_FALLTHROUGH(); // fall thru
case BASE_TYPE_VECTOR: { case BASE_TYPE_VECTOR: {
auto vectortype = field.value.type.VectorType(); auto vectortype = field.value.type.VectorType();
code += "("; code += "(";
@@ -874,7 +900,8 @@ class JavaGenerator : public BaseGenerator {
code += "(" + type_name + " obj)" + offset_prefix + getter; code += "(" + type_name + " obj)" + offset_prefix + getter;
code += "(obj, o + bb_pos) : null"; code += "(obj, o + bb_pos) : null";
break; break;
default: FLATBUFFERS_ASSERT(0); default:
FLATBUFFERS_ASSERT(0);
} }
} }
code += member_suffix; code += member_suffix;
@@ -1357,7 +1384,9 @@ class JavaGenerator : public BaseGenerator {
if (enum_def.generated) return; if (enum_def.generated) return;
code += "import com.google.flatbuffers.FlatBufferBuilder;\n\n"; code += "import com.google.flatbuffers.FlatBufferBuilder;\n\n";
if (!enum_def.attributes.Lookup("private")) { code += "public "; } if (!enum_def.attributes.Lookup("private")) {
code += "public ";
}
auto union_name = namer_.Type(enum_def) + "Union"; auto union_name = namer_.Type(enum_def) + "Union";
auto union_type = auto union_type =
GenTypeBasic(DestinationType(enum_def.underlying_type, false)); GenTypeBasic(DestinationType(enum_def.underlying_type, false));
@@ -1560,7 +1589,8 @@ class JavaGenerator : public BaseGenerator {
code += ";}\n"; code += ";}\n";
} }
break; break;
case BASE_TYPE_UTYPE: break; case BASE_TYPE_UTYPE:
break;
case BASE_TYPE_UNION: { case BASE_TYPE_UNION: {
GenUnionUnPack_ObjectAPI(*field.value.type.enum_def, code, type_name, GenUnionUnPack_ObjectAPI(*field.value.type.enum_def, code, type_name,
accessor, false); accessor, false);
@@ -1746,7 +1776,8 @@ class JavaGenerator : public BaseGenerator {
"Union.pack(builder, _o." + get_field + "());\n"; "Union.pack(builder, _o." + get_field + "());\n";
break; break;
} }
default: break; default:
break;
} }
} }
if (struct_has_create) { if (struct_has_create) {
@@ -1790,9 +1821,12 @@ class JavaGenerator : public BaseGenerator {
} }
break; break;
} }
case BASE_TYPE_UNION: FLATBUFFERS_FALLTHROUGH(); // fall thru case BASE_TYPE_UNION:
case BASE_TYPE_UTYPE: FLATBUFFERS_FALLTHROUGH(); // fall thru FLATBUFFERS_FALLTHROUGH(); // fall thru
case BASE_TYPE_STRING: FLATBUFFERS_FALLTHROUGH(); // fall thru case BASE_TYPE_UTYPE:
FLATBUFFERS_FALLTHROUGH(); // fall thru
case BASE_TYPE_STRING:
FLATBUFFERS_FALLTHROUGH(); // fall thru
case BASE_TYPE_VECTOR: { case BASE_TYPE_VECTOR: {
code += ",\n"; code += ",\n";
code += " _" + field_name; code += " _" + field_name;
@@ -1828,13 +1862,16 @@ class JavaGenerator : public BaseGenerator {
} }
break; break;
} }
case BASE_TYPE_STRING: FLATBUFFERS_FALLTHROUGH(); // fall thru case BASE_TYPE_STRING:
case BASE_TYPE_ARRAY: FLATBUFFERS_FALLTHROUGH(); // fall thru FLATBUFFERS_FALLTHROUGH(); // fall thru
case BASE_TYPE_ARRAY:
FLATBUFFERS_FALLTHROUGH(); // fall thru
case BASE_TYPE_VECTOR: { case BASE_TYPE_VECTOR: {
code += " " + add_field + "(builder, " + arg + ");\n"; code += " " + add_field + "(builder, " + arg + ");\n";
break; break;
} }
case BASE_TYPE_UTYPE: break; case BASE_TYPE_UTYPE:
break;
case BASE_TYPE_UNION: { case BASE_TYPE_UNION: {
code += " " + add_field + "Type(builder, " + arg + "Type);\n"; code += " " + add_field + "Type(builder, " + arg + "Type);\n";
code += " " + add_field + "(builder, " + arg + ");\n"; code += " " + add_field + "(builder, " + arg + ");\n";
@@ -1895,7 +1932,9 @@ class JavaGenerator : public BaseGenerator {
code += " " + name + " = "; code += " " + name + " = ";
code += "new " + GenTypeBasic(field_type) + "["; code += "new " + GenTypeBasic(field_type) + "[";
for (size_t i = 0; i < array_only_lengths.size(); ++i) { for (size_t i = 0; i < array_only_lengths.size(); ++i) {
if (i != 0) { code += "]["; } if (i != 0) {
code += "][";
}
code += NumToString(array_only_lengths[i].length); code += NumToString(array_only_lengths[i].length);
} }
code += "];\n"; code += "];\n";
@@ -1984,8 +2023,10 @@ class JavaGenerator : public BaseGenerator {
auto type_name = GenTypeNameDest(type); auto type_name = GenTypeNameDest(type);
// Replace to ObjectBaseAPI Type Name // Replace to ObjectBaseAPI Type Name
switch (type.base_type) { switch (type.base_type) {
case BASE_TYPE_STRUCT: FLATBUFFERS_FALLTHROUGH(); // fall thru case BASE_TYPE_STRUCT:
case BASE_TYPE_ARRAY: FLATBUFFERS_FALLTHROUGH(); // fall thru FLATBUFFERS_FALLTHROUGH(); // fall thru
case BASE_TYPE_ARRAY:
FLATBUFFERS_FALLTHROUGH(); // fall thru
case BASE_TYPE_VECTOR: { case BASE_TYPE_VECTOR: {
if (type.struct_def != nullptr) { if (type.struct_def != nullptr) {
auto type_name_length = type.struct_def->name.length(); auto type_name_length = type.struct_def->name.length();
@@ -2011,16 +2052,21 @@ class JavaGenerator : public BaseGenerator {
} }
break; break;
} }
default: break; default:
break;
}
if (vectorelem) {
return type_name;
} }
if (vectorelem) { return type_name; }
switch (type.base_type) { switch (type.base_type) {
case BASE_TYPE_ARRAY: FLATBUFFERS_FALLTHROUGH(); // fall thru case BASE_TYPE_ARRAY:
FLATBUFFERS_FALLTHROUGH(); // fall thru
case BASE_TYPE_VECTOR: { case BASE_TYPE_VECTOR: {
type_name = type_name + "[]"; type_name = type_name + "[]";
break; break;
} }
default: break; default:
break;
} }
return type_name; return type_name;
} }
@@ -2030,8 +2076,10 @@ class JavaGenerator : public BaseGenerator {
auto type_name = GenTypeNameDest(type); auto type_name = GenTypeNameDest(type);
// Replace to ObjectBaseAPI Type Name // Replace to ObjectBaseAPI Type Name
switch (type.base_type) { switch (type.base_type) {
case BASE_TYPE_STRUCT: FLATBUFFERS_FALLTHROUGH(); // fall thru case BASE_TYPE_STRUCT:
case BASE_TYPE_ARRAY: FLATBUFFERS_FALLTHROUGH(); // fall thru FLATBUFFERS_FALLTHROUGH(); // fall thru
case BASE_TYPE_ARRAY:
FLATBUFFERS_FALLTHROUGH(); // fall thru
case BASE_TYPE_VECTOR: { case BASE_TYPE_VECTOR: {
if (type.struct_def != nullptr) { if (type.struct_def != nullptr) {
auto type_name_length = type.struct_def->name.length(); auto type_name_length = type.struct_def->name.length();
@@ -2048,16 +2096,19 @@ class JavaGenerator : public BaseGenerator {
type_name = Prefixed(namer_.NamespacedType(*type.enum_def)) + "Union"; type_name = Prefixed(namer_.NamespacedType(*type.enum_def)) + "Union";
break; break;
} }
default: break; default:
break;
} }
switch (type.base_type) { switch (type.base_type) {
case BASE_TYPE_ARRAY: FLATBUFFERS_FALLTHROUGH(); // fall thru case BASE_TYPE_ARRAY:
FLATBUFFERS_FALLTHROUGH(); // fall thru
case BASE_TYPE_VECTOR: { case BASE_TYPE_VECTOR: {
type_name = type_name + "[]"; type_name = type_name + "[]";
break; break;
} }
default: break; default:
break;
} }
return type_name; return type_name;
} }
@@ -2203,12 +2254,13 @@ class JavaCodeGenerator : public CodeGenerator {
public: public:
Status GenerateCode(const Parser& parser, const std::string& path, Status GenerateCode(const Parser& parser, const std::string& path,
const std::string& filename) override { const std::string& filename) override {
if (!GenerateJava(parser, path, filename)) { return Status::ERROR; } if (!GenerateJava(parser, path, filename)) {
return Status::ERROR;
}
return Status::OK; return Status::OK;
} }
Status GenerateCode(const uint8_t *, int64_t, Status GenerateCode(const uint8_t*, int64_t, const CodeGenOptions&) override {
const CodeGenOptions &) override {
return Status::NOT_IMPLEMENTED; return Status::NOT_IMPLEMENTED;
} }
@@ -2221,7 +2273,9 @@ class JavaCodeGenerator : public CodeGenerator {
Status GenerateGrpcCode(const Parser& parser, const std::string& path, Status GenerateGrpcCode(const Parser& parser, const std::string& path,
const std::string& filename) override { const std::string& filename) override {
if (!GenerateJavaGRPC(parser, path, filename)) { return Status::ERROR; } if (!GenerateJavaGRPC(parser, path, filename)) {
return Status::ERROR;
}
return Status::OK; return Status::OK;
} }

View File

@@ -30,7 +30,8 @@ namespace jsons {
namespace { namespace {
template<class T> static std::string GenFullName(const T *enum_def) { template <class T>
static std::string GenFullName(const T* enum_def) {
std::string full_name; std::string full_name;
const auto& name_spaces = enum_def->defined_namespace->components; const auto& name_spaces = enum_def->defined_namespace->components;
for (auto ns = name_spaces.cbegin(); ns != name_spaces.cend(); ++ns) { for (auto ns = name_spaces.cbegin(); ns != name_spaces.cend(); ++ns) {
@@ -40,7 +41,8 @@ template<class T> static std::string GenFullName(const T *enum_def) {
return full_name; return full_name;
} }
template<class T> static std::string GenTypeRef(const T *enum_def) { template <class T>
static std::string GenTypeRef(const T* enum_def) {
return "\"$ref\" : \"#/definitions/" + GenFullName(enum_def) + "\""; return "\"$ref\" : \"#/definitions/" + GenFullName(enum_def) + "\"";
} }
@@ -50,7 +52,8 @@ static std::string GenType(const std::string &name) {
static std::string GenType(BaseType type) { static std::string GenType(BaseType type) {
switch (type) { switch (type) {
case BASE_TYPE_BOOL: return "\"type\" : \"boolean\""; case BASE_TYPE_BOOL:
return "\"type\" : \"boolean\"";
case BASE_TYPE_CHAR: case BASE_TYPE_CHAR:
return "\"type\" : \"integer\", \"minimum\" : " + return "\"type\" : \"integer\", \"minimum\" : " +
NumToString(std::numeric_limits<int8_t>::min()) + NumToString(std::numeric_limits<int8_t>::min()) +
@@ -84,15 +87,22 @@ static std::string GenType(BaseType type) {
return "\"type\" : \"integer\", \"minimum\" : 0, \"maximum\" : " + return "\"type\" : \"integer\", \"minimum\" : 0, \"maximum\" : " +
NumToString(std::numeric_limits<uint64_t>::max()); NumToString(std::numeric_limits<uint64_t>::max());
case BASE_TYPE_FLOAT: case BASE_TYPE_FLOAT:
case BASE_TYPE_DOUBLE: return "\"type\" : \"number\""; case BASE_TYPE_DOUBLE:
case BASE_TYPE_STRING: return "\"type\" : \"string\""; return "\"type\" : \"number\"";
default: return ""; case BASE_TYPE_STRING:
return "\"type\" : \"string\"";
default:
return "";
} }
} }
static std::string GenBaseType(const Type& type) { static std::string GenBaseType(const Type& type) {
if (type.struct_def != nullptr) { return GenTypeRef(type.struct_def); } if (type.struct_def != nullptr) {
if (type.enum_def != nullptr) { return GenTypeRef(type.enum_def); } return GenTypeRef(type.struct_def);
}
if (type.enum_def != nullptr) {
return GenTypeRef(type.enum_def);
}
return GenType(type.base_type); return GenType(type.base_type);
} }
@@ -111,7 +121,8 @@ static std::string GenArrayType(const Type &type) {
static std::string GenType(const Type& type) { static std::string GenType(const Type& type) {
switch (type.base_type) { switch (type.base_type) {
case BASE_TYPE_ARRAY: FLATBUFFERS_FALLTHROUGH(); // fall thru case BASE_TYPE_ARRAY:
FLATBUFFERS_FALLTHROUGH(); // fall thru
case BASE_TYPE_VECTOR: { case BASE_TYPE_VECTOR: {
return GenArrayType(type); return GenArrayType(type);
} }
@@ -123,7 +134,9 @@ static std::string GenType(const Type &type) {
const auto& union_types = type.enum_def->Vals(); const auto& union_types = type.enum_def->Vals();
for (auto ut = union_types.cbegin(); ut < union_types.cend(); ++ut) { for (auto ut = union_types.cbegin(); ut < union_types.cend(); ++ut) {
const auto& union_type = *ut; const auto& union_type = *ut;
if (union_type->union_type.base_type == BASE_TYPE_NONE) { continue; } if (union_type->union_type.base_type == BASE_TYPE_NONE) {
continue;
}
if (union_type->union_type.base_type == BASE_TYPE_STRUCT) { if (union_type->union_type.base_type == BASE_TYPE_STRUCT) {
union_type_string.append( union_type_string.append(
"{ " + GenTypeRef(union_type->union_type.struct_def) + " }"); "{ " + GenTypeRef(union_type->union_type.struct_def) + " }");
@@ -135,7 +148,8 @@ static std::string GenType(const Type &type) {
union_type_string.append("]"); union_type_string.append("]");
return union_type_string; return union_type_string;
} }
case BASE_TYPE_UTYPE: return GenTypeRef(type.enum_def); case BASE_TYPE_UTYPE:
return GenTypeRef(type.enum_def);
default: { default: {
return GenBaseType(type); return GenBaseType(type);
} }
@@ -226,7 +240,9 @@ class JsonSchemaGenerator : public BaseGenerator {
for (auto enum_value = (*e)->Vals().begin(); for (auto enum_value = (*e)->Vals().begin();
enum_value != (*e)->Vals().end(); ++enum_value) { enum_value != (*e)->Vals().end(); ++enum_value) {
enumdef.append("\"" + (*enum_value)->name + "\""); enumdef.append("\"" + (*enum_value)->name + "\"");
if (*enum_value != (*e)->Vals().back()) { enumdef.append(", "); } if (*enum_value != (*e)->Vals().back()) {
enumdef.append(", ");
}
} }
enumdef.append("]"); enumdef.append("]");
code_ += enumdef + NewLine(); code_ += enumdef + NewLine();
@@ -272,7 +288,9 @@ class JsonSchemaGenerator : public BaseGenerator {
} }
typeLine += NewLine() + Indent(7) + "}"; typeLine += NewLine() + Indent(7) + "}";
if (property != properties.back()) { typeLine.append(","); } if (property != properties.back()) {
typeLine.append(",");
}
code_ += typeLine + NewLine(); code_ += typeLine + NewLine();
} }
code_ += Indent(3) + "}," + NewLine(); // close properties code_ += Indent(3) + "}," + NewLine(); // close properties
@@ -295,7 +313,9 @@ class JsonSchemaGenerator : public BaseGenerator {
} }
code_ += Indent(3) + "\"additionalProperties\" : false" + NewLine(); code_ += Indent(3) + "\"additionalProperties\" : false" + NewLine();
auto closeType(Indent(2) + "}"); auto closeType(Indent(2) + "}");
if (*s != parser_.structs_.vec.back()) { closeType.append(","); } if (*s != parser_.structs_.vec.back()) {
closeType.append(",");
}
code_ += closeType + NewLine(); // close type code_ += closeType + NewLine(); // close type
} }
code_ += Indent(1) + "}," + NewLine(); // close definitions code_ += Indent(1) + "}," + NewLine(); // close definitions
@@ -320,7 +340,9 @@ class JsonSchemaGenerator : public BaseGenerator {
static bool GenerateJsonSchema(const Parser& parser, const std::string& path, static bool GenerateJsonSchema(const Parser& parser, const std::string& path,
const std::string& file_name) { const std::string& file_name) {
jsons::JsonSchemaGenerator generator(parser, path, file_name); jsons::JsonSchemaGenerator generator(parser, path, file_name);
if (!generator.generate()) { return false; } if (!generator.generate()) {
return false;
}
return generator.save(); return generator.save();
} }
@@ -330,12 +352,13 @@ class JsonSchemaCodeGenerator : public CodeGenerator {
public: public:
Status GenerateCode(const Parser& parser, const std::string& path, Status GenerateCode(const Parser& parser, const std::string& path,
const std::string& filename) override { const std::string& filename) override {
if (!GenerateJsonSchema(parser, path, filename)) { return Status::ERROR; } if (!GenerateJsonSchema(parser, path, filename)) {
return Status::ERROR;
}
return Status::OK; return Status::OK;
} }
Status GenerateCode(const uint8_t *, int64_t, Status GenerateCode(const uint8_t*, int64_t, const CodeGenOptions&) override {
const CodeGenOptions &) override {
return Status::NOT_IMPLEMENTED; return Status::NOT_IMPLEMENTED;
} }

View File

@@ -178,10 +178,14 @@ class KotlinGenerator : public BaseGenerator {
std::string GenTypePointer(const Type& type) const { std::string GenTypePointer(const Type& type) const {
switch (type.base_type) { switch (type.base_type) {
case BASE_TYPE_STRING: return "String"; case BASE_TYPE_STRING:
case BASE_TYPE_VECTOR: return GenTypeGet(type.VectorType()); return "String";
case BASE_TYPE_STRUCT: return WrapInNameSpace(*type.struct_def); case BASE_TYPE_VECTOR:
default: return "Table"; return GenTypeGet(type.VectorType());
case BASE_TYPE_STRUCT:
return WrapInNameSpace(*type.struct_def);
default:
return "Table";
} }
} }
@@ -231,9 +235,12 @@ class KotlinGenerator : public BaseGenerator {
// calling builder.addMyField() // calling builder.addMyField()
switch (field.value.type.base_type) { switch (field.value.type.base_type) {
case BASE_TYPE_DOUBLE: case BASE_TYPE_DOUBLE:
case BASE_TYPE_FLOAT: return "0.0"; case BASE_TYPE_FLOAT:
case BASE_TYPE_BOOL: return "false"; return "0.0";
default: return "0"; case BASE_TYPE_BOOL:
return "false";
default:
return "0";
} }
} }
auto out = GenDefaultValue(field, true); auto out = GenDefaultValue(field, true);
@@ -262,7 +269,9 @@ class KotlinGenerator : public BaseGenerator {
auto& value = field.value; auto& value = field.value;
auto base_type = field.value.type.base_type; auto base_type = field.value.type.base_type;
if (field.IsScalarOptional()) { return "null"; } if (field.IsScalarOptional()) {
return "null";
}
if (IsFloat(base_type)) { if (IsFloat(base_type)) {
auto val = KotlinFloatGen.GenFloatConstant(field); auto val = KotlinFloatGen.GenFloatConstant(field);
if (base_type == BASE_TYPE_DOUBLE && val.back() == 'f') { if (base_type == BASE_TYPE_DOUBLE && val.back() == 'f') {
@@ -328,7 +337,9 @@ class KotlinGenerator : public BaseGenerator {
writer += "\"\", \\"; writer += "\"\", \\";
val = ev; val = ev;
writer += "\"" + (*it)->name + "\"\\"; writer += "\"" + (*it)->name + "\"\\";
if (it + 1 != vals.end()) { writer += ", \\"; } if (it + 1 != vals.end()) {
writer += ", \\";
}
} }
writer += ")"; writer += ")";
}); });
@@ -351,24 +362,34 @@ class KotlinGenerator : public BaseGenerator {
std::string ByteBufferGetter(const Type& type, std::string ByteBufferGetter(const Type& type,
std::string bb_var_name) const { std::string bb_var_name) const {
switch (type.base_type) { switch (type.base_type) {
case BASE_TYPE_STRING: return "__string"; case BASE_TYPE_STRING:
case BASE_TYPE_STRUCT: return "__struct"; return "__string";
case BASE_TYPE_UNION: return "__union"; case BASE_TYPE_STRUCT:
return "__struct";
case BASE_TYPE_UNION:
return "__union";
case BASE_TYPE_VECTOR: case BASE_TYPE_VECTOR:
return ByteBufferGetter(type.VectorType(), bb_var_name); return ByteBufferGetter(type.VectorType(), bb_var_name);
case BASE_TYPE_INT: case BASE_TYPE_INT:
case BASE_TYPE_UINT: return bb_var_name + ".getInt"; case BASE_TYPE_UINT:
return bb_var_name + ".getInt";
case BASE_TYPE_SHORT: case BASE_TYPE_SHORT:
case BASE_TYPE_USHORT: return bb_var_name + ".getShort"; case BASE_TYPE_USHORT:
return bb_var_name + ".getShort";
case BASE_TYPE_ULONG: case BASE_TYPE_ULONG:
case BASE_TYPE_LONG: return bb_var_name + ".getLong"; case BASE_TYPE_LONG:
case BASE_TYPE_FLOAT: return bb_var_name + ".getFloat"; return bb_var_name + ".getLong";
case BASE_TYPE_DOUBLE: return bb_var_name + ".getDouble"; case BASE_TYPE_FLOAT:
return bb_var_name + ".getFloat";
case BASE_TYPE_DOUBLE:
return bb_var_name + ".getDouble";
case BASE_TYPE_CHAR: case BASE_TYPE_CHAR:
case BASE_TYPE_UCHAR: case BASE_TYPE_UCHAR:
case BASE_TYPE_NONE: case BASE_TYPE_NONE:
case BASE_TYPE_UTYPE: return bb_var_name + ".get"; case BASE_TYPE_UTYPE:
case BASE_TYPE_BOOL: return "0.toByte() != " + bb_var_name + ".get"; return bb_var_name + ".get";
case BASE_TYPE_BOOL:
return "0.toByte() != " + bb_var_name + ".get";
default: default:
return bb_var_name + "." + return bb_var_name + "." +
namer_.Method("get", GenTypeBasic(type.base_type)); namer_.Method("get", GenTypeBasic(type.base_type));
@@ -379,18 +400,24 @@ class KotlinGenerator : public BaseGenerator {
if (IsScalar(type.base_type)) { if (IsScalar(type.base_type)) {
switch (type.base_type) { switch (type.base_type) {
case BASE_TYPE_INT: case BASE_TYPE_INT:
case BASE_TYPE_UINT: return "bb.putInt"; case BASE_TYPE_UINT:
return "bb.putInt";
case BASE_TYPE_SHORT: case BASE_TYPE_SHORT:
case BASE_TYPE_USHORT: return "bb.putShort"; case BASE_TYPE_USHORT:
return "bb.putShort";
case BASE_TYPE_ULONG: case BASE_TYPE_ULONG:
case BASE_TYPE_LONG: return "bb.putLong"; case BASE_TYPE_LONG:
case BASE_TYPE_FLOAT: return "bb.putFloat"; return "bb.putLong";
case BASE_TYPE_DOUBLE: return "bb.putDouble"; case BASE_TYPE_FLOAT:
return "bb.putFloat";
case BASE_TYPE_DOUBLE:
return "bb.putDouble";
case BASE_TYPE_CHAR: case BASE_TYPE_CHAR:
case BASE_TYPE_UCHAR: case BASE_TYPE_UCHAR:
case BASE_TYPE_BOOL: case BASE_TYPE_BOOL:
case BASE_TYPE_NONE: case BASE_TYPE_NONE:
case BASE_TYPE_UTYPE: return "bb.put"; case BASE_TYPE_UTYPE:
return "bb.put";
default: default:
return "bb." + namer_.Method("put", GenTypeBasic(type.base_type)); return "bb." + namer_.Method("put", GenTypeBasic(type.base_type));
} }
@@ -679,7 +706,9 @@ class KotlinGenerator : public BaseGenerator {
writer.IncrementIdentLevel(); writer.IncrementIdentLevel();
for (auto it = field_vec.begin(); it != field_vec.end(); ++it) { for (auto it = field_vec.begin(); it != field_vec.end(); ++it) {
auto& field = **it; auto& field = **it;
if (field.deprecated || !field.IsRequired()) { continue; } if (field.deprecated || !field.IsRequired()) {
continue;
}
writer.SetValue("offset", NumToString(field.value.offset)); writer.SetValue("offset", NumToString(field.value.offset));
writer += "builder.required(o, {{offset}})"; writer += "builder.required(o, {{offset}})";
} }
@@ -772,14 +801,20 @@ class KotlinGenerator : public BaseGenerator {
static std::string ToSignedType(const Type& type) { static std::string ToSignedType(const Type& type) {
switch (type.base_type) { switch (type.base_type) {
case BASE_TYPE_UINT: return GenTypeBasic(BASE_TYPE_INT); case BASE_TYPE_UINT:
case BASE_TYPE_ULONG: return GenTypeBasic(BASE_TYPE_LONG); return GenTypeBasic(BASE_TYPE_INT);
case BASE_TYPE_ULONG:
return GenTypeBasic(BASE_TYPE_LONG);
case BASE_TYPE_UCHAR: case BASE_TYPE_UCHAR:
case BASE_TYPE_NONE: case BASE_TYPE_NONE:
case BASE_TYPE_UTYPE: return GenTypeBasic(BASE_TYPE_CHAR); case BASE_TYPE_UTYPE:
case BASE_TYPE_USHORT: return GenTypeBasic(BASE_TYPE_SHORT); return GenTypeBasic(BASE_TYPE_CHAR);
case BASE_TYPE_VECTOR: return ToSignedType(type.VectorType()); case BASE_TYPE_USHORT:
default: return GenTypeBasic(type.base_type); return GenTypeBasic(BASE_TYPE_SHORT);
case BASE_TYPE_VECTOR:
return ToSignedType(type.VectorType());
default:
return GenTypeBasic(type.base_type);
} }
} }
@@ -1090,7 +1125,8 @@ class KotlinGenerator : public BaseGenerator {
case BASE_TYPE_UNION: case BASE_TYPE_UNION:
found = "{{bbgetter}}(obj, {{index}}){{ucast}}"; found = "{{bbgetter}}(obj, {{index}}){{ucast}}";
break; break;
default: found = "{{bbgetter}}({{index}}){{ucast}}"; default:
found = "{{bbgetter}}({{index}}){{ucast}}";
} }
OffsetWrapper( OffsetWrapper(
writer, offset_val, [&]() { writer += found; }, writer, offset_val, [&]() { writer += found; },
@@ -1105,7 +1141,8 @@ class KotlinGenerator : public BaseGenerator {
offset_val, bbgetter + "(obj, o + bb_pos)", "null"); offset_val, bbgetter + "(obj, o + bb_pos)", "null");
}); });
break; break;
default: FLATBUFFERS_ASSERT(0); default:
FLATBUFFERS_ASSERT(0);
} }
} }
@@ -1292,13 +1329,19 @@ class KotlinGenerator : public BaseGenerator {
static std::string CastToUsigned(const Type type) { static std::string CastToUsigned(const Type type) {
switch (type.base_type) { switch (type.base_type) {
case BASE_TYPE_UINT: return ".toUInt()"; case BASE_TYPE_UINT:
return ".toUInt()";
case BASE_TYPE_UCHAR: case BASE_TYPE_UCHAR:
case BASE_TYPE_UTYPE: return ".toUByte()"; case BASE_TYPE_UTYPE:
case BASE_TYPE_USHORT: return ".toUShort()"; return ".toUByte()";
case BASE_TYPE_ULONG: return ".toULong()"; case BASE_TYPE_USHORT:
case BASE_TYPE_VECTOR: return CastToUsigned(type.VectorType()); return ".toUShort()";
default: return ""; case BASE_TYPE_ULONG:
return ".toULong()";
case BASE_TYPE_VECTOR:
return CastToUsigned(type.VectorType());
default:
return "";
} }
} }
@@ -1308,13 +1351,19 @@ class KotlinGenerator : public BaseGenerator {
static std::string CastToSigned(const Type type) { static std::string CastToSigned(const Type type) {
switch (type.base_type) { switch (type.base_type) {
case BASE_TYPE_UINT: return ".toInt()"; case BASE_TYPE_UINT:
return ".toInt()";
case BASE_TYPE_UCHAR: case BASE_TYPE_UCHAR:
case BASE_TYPE_UTYPE: return ".toByte()"; case BASE_TYPE_UTYPE:
case BASE_TYPE_USHORT: return ".toShort()"; return ".toByte()";
case BASE_TYPE_ULONG: return ".toLong()"; case BASE_TYPE_USHORT:
case BASE_TYPE_VECTOR: return CastToSigned(type.VectorType()); return ".toShort()";
default: return ""; case BASE_TYPE_ULONG:
return ".toLong()";
case BASE_TYPE_VECTOR:
return CastToSigned(type.VectorType());
default:
return "";
} }
} }
@@ -1323,10 +1372,14 @@ class KotlinGenerator : public BaseGenerator {
case BASE_TYPE_UINT: case BASE_TYPE_UINT:
case BASE_TYPE_UCHAR: case BASE_TYPE_UCHAR:
case BASE_TYPE_UTYPE: case BASE_TYPE_UTYPE:
case BASE_TYPE_USHORT: return "u"; case BASE_TYPE_USHORT:
case BASE_TYPE_ULONG: return "UL"; return "u";
case BASE_TYPE_LONG: return "L"; case BASE_TYPE_ULONG:
default: return ""; return "UL";
case BASE_TYPE_LONG:
return "L";
default:
return "";
} }
} }
@@ -1408,7 +1461,9 @@ class KotlinGenerator : public BaseGenerator {
// builder: FlatBufferBuilder // builder: FlatBufferBuilder
std::stringstream out; std::stringstream out;
auto field_vec = struct_def.fields.vec; auto field_vec = struct_def.fields.vec;
if (prefix.empty()) { out << "builder: FlatBufferBuilder"; } if (prefix.empty()) {
out << "builder: FlatBufferBuilder";
}
for (auto it = field_vec.begin(); it != field_vec.end(); ++it) { for (auto it = field_vec.begin(); it != field_vec.end(); ++it) {
auto& field = **it; auto& field = **it;
if (IsStruct(field.value.type)) { if (IsStruct(field.value.type)) {
@@ -1567,26 +1622,35 @@ class KotlinGenerator : public BaseGenerator {
static std::string NotFoundReturn(BaseType el) { static std::string NotFoundReturn(BaseType el) {
switch (el) { switch (el) {
case BASE_TYPE_FLOAT: return "0.0f"; case BASE_TYPE_FLOAT:
case BASE_TYPE_DOUBLE: return "0.0"; return "0.0f";
case BASE_TYPE_BOOL: return "false"; case BASE_TYPE_DOUBLE:
return "0.0";
case BASE_TYPE_BOOL:
return "false";
case BASE_TYPE_LONG: case BASE_TYPE_LONG:
case BASE_TYPE_INT: case BASE_TYPE_INT:
case BASE_TYPE_CHAR: case BASE_TYPE_CHAR:
case BASE_TYPE_SHORT: return "0"; case BASE_TYPE_SHORT:
return "0";
case BASE_TYPE_UINT: case BASE_TYPE_UINT:
case BASE_TYPE_UCHAR: case BASE_TYPE_UCHAR:
case BASE_TYPE_USHORT: case BASE_TYPE_USHORT:
case BASE_TYPE_UTYPE: return "0u"; case BASE_TYPE_UTYPE:
case BASE_TYPE_ULONG: return "0uL"; return "0u";
default: return "null"; case BASE_TYPE_ULONG:
return "0uL";
default:
return "null";
} }
} }
// Prepend @JvmStatic to methods in companion object. // Prepend @JvmStatic to methods in companion object.
static void GenerateJvmStaticAnnotation(CodeWriter& code, static void GenerateJvmStaticAnnotation(CodeWriter& code,
bool gen_jvmstatic) { bool gen_jvmstatic) {
if (gen_jvmstatic) { code += "@JvmStatic"; } if (gen_jvmstatic) {
code += "@JvmStatic";
}
} }
const IdlNamer namer_; const IdlNamer namer_;
@@ -1605,12 +1669,13 @@ class KotlinCodeGenerator : public CodeGenerator {
public: public:
Status GenerateCode(const Parser& parser, const std::string& path, Status GenerateCode(const Parser& parser, const std::string& path,
const std::string& filename) override { const std::string& filename) override {
if (!GenerateKotlin(parser, path, filename)) { return Status::ERROR; } if (!GenerateKotlin(parser, path, filename)) {
return Status::ERROR;
}
return Status::OK; return Status::OK;
} }
Status GenerateCode(const uint8_t *, int64_t, Status GenerateCode(const uint8_t*, int64_t, const CodeGenOptions&) override {
const CodeGenOptions &) override {
return Status::NOT_IMPLEMENTED; return Status::NOT_IMPLEMENTED;
} }

View File

@@ -151,7 +151,9 @@ class KotlinKMPGenerator : public BaseGenerator {
code += "package " + namespace_name; code += "package " + namespace_name;
code += "\n\n"; code += "\n\n";
} }
if (needs_includes) { code += "import com.google.flatbuffers.kotlin.*\n"; } if (needs_includes) {
code += "import com.google.flatbuffers.kotlin.*\n";
}
code += "import kotlin.jvm.JvmInline\n"; code += "import kotlin.jvm.JvmInline\n";
code += classcode; code += classcode;
const std::string dirs = const std::string dirs =
@@ -167,7 +169,9 @@ class KotlinKMPGenerator : public BaseGenerator {
} }
std::string GenerateKotlinPrimiteArray(const Type& type) const { std::string GenerateKotlinPrimiteArray(const Type& type) const {
if (IsScalar(type.base_type) && !IsEnum(type)) { return GenType(type); } if (IsScalar(type.base_type) && !IsEnum(type)) {
return GenType(type);
}
if (IsEnum(type) || type.base_type == BASE_TYPE_UTYPE) { if (IsEnum(type) || type.base_type == BASE_TYPE_UTYPE) {
return TypeInNameSpace(type.enum_def->defined_namespace, return TypeInNameSpace(type.enum_def->defined_namespace,
@@ -176,10 +180,14 @@ class KotlinKMPGenerator : public BaseGenerator {
switch (type.base_type) { switch (type.base_type) {
case BASE_TYPE_STRUCT: case BASE_TYPE_STRUCT:
return "Offset<" + TypeInNameSpace(*type.struct_def) + ">"; return "Offset<" + TypeInNameSpace(*type.struct_def) + ">";
case BASE_TYPE_UNION: return "UnionOffset"; case BASE_TYPE_UNION:
case BASE_TYPE_STRING: return "Offset<String>"; return "UnionOffset";
case BASE_TYPE_UTYPE: return "Offset<UByte>"; case BASE_TYPE_STRING:
default: return "Offset<" + GenTypeBasic(type.element) + ">"; return "Offset<String>";
case BASE_TYPE_UTYPE:
return "Offset<UByte>";
default:
return "Offset<" + GenTypeBasic(type.element) + ">";
} }
} }
@@ -195,35 +203,55 @@ class KotlinKMPGenerator : public BaseGenerator {
switch (type.base_type) { switch (type.base_type) {
case BASE_TYPE_STRUCT: case BASE_TYPE_STRUCT:
return TypeInNameSpace(*type.struct_def) + "OffsetArray"; return TypeInNameSpace(*type.struct_def) + "OffsetArray";
case BASE_TYPE_UNION: return "UnionOffsetArray"; case BASE_TYPE_UNION:
case BASE_TYPE_STRING: return "StringOffsetArray"; return "UnionOffsetArray";
case BASE_TYPE_UTYPE: return "UByteArray"; case BASE_TYPE_STRING:
default: return GenTypeBasic(type.element) + "OffsetArray"; return "StringOffsetArray";
case BASE_TYPE_UTYPE:
return "UByteArray";
default:
return GenTypeBasic(type.element) + "OffsetArray";
} }
} }
std::string GenTypeBasic(const BaseType& type) const { std::string GenTypeBasic(const BaseType& type) const {
switch (type) { switch (type) {
case BASE_TYPE_NONE: case BASE_TYPE_NONE:
case BASE_TYPE_UTYPE: return "UByte"; case BASE_TYPE_UTYPE:
case BASE_TYPE_BOOL: return "Boolean"; return "UByte";
case BASE_TYPE_CHAR: return "Byte"; case BASE_TYPE_BOOL:
case BASE_TYPE_UCHAR: return "UByte"; return "Boolean";
case BASE_TYPE_SHORT: return "Short"; case BASE_TYPE_CHAR:
case BASE_TYPE_USHORT: return "UShort"; return "Byte";
case BASE_TYPE_INT: return "Int"; case BASE_TYPE_UCHAR:
case BASE_TYPE_UINT: return "UInt"; return "UByte";
case BASE_TYPE_LONG: return "Long"; case BASE_TYPE_SHORT:
case BASE_TYPE_ULONG: return "ULong"; return "Short";
case BASE_TYPE_FLOAT: return "Float"; case BASE_TYPE_USHORT:
case BASE_TYPE_DOUBLE: return "Double"; 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_STRING:
case BASE_TYPE_STRUCT: return "Offset"; case BASE_TYPE_STRUCT:
case BASE_TYPE_UNION: return "UnionOffset"; return "Offset";
case BASE_TYPE_UNION:
return "UnionOffset";
case BASE_TYPE_VECTOR: case BASE_TYPE_VECTOR:
case BASE_TYPE_ARRAY: return "VectorOffset"; case BASE_TYPE_ARRAY:
return "VectorOffset";
// VECTOR64 not supported // VECTOR64 not supported
case BASE_TYPE_VECTOR64: FLATBUFFERS_ASSERT(0); case BASE_TYPE_VECTOR64:
FLATBUFFERS_ASSERT(0);
} }
return "Int"; return "Int";
} }
@@ -243,26 +271,36 @@ class KotlinKMPGenerator : public BaseGenerator {
return base_type + "<" + TypeInNameSpace(*type.struct_def) + ">"; return base_type + "<" + TypeInNameSpace(*type.struct_def) + ">";
case BASE_TYPE_UNION: case BASE_TYPE_UNION:
return base_type + "<" + GenTypeBasic(type.element) + ">"; return base_type + "<" + GenTypeBasic(type.element) + ">";
case BASE_TYPE_STRING: return base_type + "<String>"; case BASE_TYPE_STRING:
case BASE_TYPE_UTYPE: return base_type + "<UByte>"; return base_type + "<String>";
default: return base_type + "<" + GenTypeBasic(type.element) + ">"; case BASE_TYPE_UTYPE:
return base_type + "<UByte>";
default:
return base_type + "<" + GenTypeBasic(type.element) + ">";
} }
} }
case BASE_TYPE_STRUCT: case BASE_TYPE_STRUCT:
return base_type + "<" + TypeInNameSpace(*type.struct_def) + ">"; return base_type + "<" + TypeInNameSpace(*type.struct_def) + ">";
case BASE_TYPE_STRING: return base_type + "<String>"; case BASE_TYPE_STRING:
case BASE_TYPE_UNION: return base_type; return base_type + "<String>";
default: return base_type; case BASE_TYPE_UNION:
return base_type;
default:
return base_type;
} }
// clang-format on // clang-format on
} }
std::string GenTypePointer(const Type& type) const { std::string GenTypePointer(const Type& type) const {
switch (type.base_type) { switch (type.base_type) {
case BASE_TYPE_STRING: return "String"; case BASE_TYPE_STRING:
case BASE_TYPE_VECTOR: return GenTypeGet(type.VectorType()); return "String";
case BASE_TYPE_STRUCT: return TypeInNameSpace(*type.struct_def); case BASE_TYPE_VECTOR:
default: return "Table"; return GenTypeGet(type.VectorType());
case BASE_TYPE_STRUCT:
return TypeInNameSpace(*type.struct_def);
default:
return "Table";
} }
} }
@@ -304,7 +342,9 @@ class KotlinKMPGenerator : public BaseGenerator {
auto base_type = value.type.base_type; auto base_type = value.type.base_type;
auto field_name = field.name; auto field_name = field.name;
std::string suffix = IsScalar(base_type) ? LiteralSuffix(value.type) : ""; std::string suffix = IsScalar(base_type) ? LiteralSuffix(value.type) : "";
if (field.IsScalarOptional()) { return "null"; } if (field.IsScalarOptional()) {
return "null";
}
if (IsFloat(base_type)) { if (IsFloat(base_type)) {
auto val = KotlinFloatGen.GenFloatConstant(field); auto val = KotlinFloatGen.GenFloatConstant(field);
if (base_type == BASE_TYPE_DOUBLE && val.back() == 'f') { if (base_type == BASE_TYPE_DOUBLE && val.back() == 'f') {
@@ -334,7 +374,9 @@ class KotlinKMPGenerator : public BaseGenerator {
auto base_type = value.type.base_type; auto base_type = value.type.base_type;
auto field_name = field.name; auto field_name = field.name;
std::string suffix = LiteralSuffix(value.type); std::string suffix = LiteralSuffix(value.type);
if (field.IsScalarOptional()) { return "null"; } if (field.IsScalarOptional()) {
return "null";
}
if (IsFloat(base_type)) { if (IsFloat(base_type)) {
auto val = KotlinFloatGen.GenFloatConstant(field); auto val = KotlinFloatGen.GenFloatConstant(field);
if (base_type == BASE_TYPE_DOUBLE && val.back() == 'f') { if (base_type == BASE_TYPE_DOUBLE && val.back() == 'f') {
@@ -365,13 +407,17 @@ class KotlinKMPGenerator : public BaseGenerator {
value.constant + suffix + ")"; value.constant + suffix + ")";
case BASE_TYPE_UNION: case BASE_TYPE_UNION:
case BASE_TYPE_STRUCT: case BASE_TYPE_STRUCT:
case BASE_TYPE_STRING: return "null"; case BASE_TYPE_STRING:
case BASE_TYPE_BOOL: return value.constant == "0" ? "false" : "true"; return "null";
case BASE_TYPE_FLOAT: return value.constant + "f"; case BASE_TYPE_BOOL:
return value.constant == "0" ? "false" : "true";
case BASE_TYPE_FLOAT:
return value.constant + "f";
case BASE_TYPE_DOUBLE: { case BASE_TYPE_DOUBLE: {
return value.constant + ".toDouble()"; return value.constant + ".toDouble()";
} }
default: return value.constant + suffix; default:
return value.constant + suffix;
} }
} }
return value.constant + suffix; return value.constant + suffix;
@@ -421,7 +467,9 @@ class KotlinKMPGenerator : public BaseGenerator {
writer += "\"\", \\"; writer += "\"\", \\";
val = ev; val = ev;
writer += "\"" + (*it)->name + "\"\\"; writer += "\"" + (*it)->name + "\"\\";
if (it + 1 != vals.end()) { writer += ", \\"; } if (it + 1 != vals.end()) {
writer += ", \\";
}
} }
writer += ")"; writer += ")";
}); });
@@ -446,25 +494,40 @@ class KotlinKMPGenerator : public BaseGenerator {
std::string ByteBufferGetter(const Type& type, std::string ByteBufferGetter(const Type& type,
std::string bb_var_name) const { std::string bb_var_name) const {
switch (type.base_type) { switch (type.base_type) {
case BASE_TYPE_STRING: return "string"; case BASE_TYPE_STRING:
case BASE_TYPE_STRUCT: return "__struct"; return "string";
case BASE_TYPE_UNION: return "union"; case BASE_TYPE_STRUCT:
return "__struct";
case BASE_TYPE_UNION:
return "union";
case BASE_TYPE_VECTOR: case BASE_TYPE_VECTOR:
return ByteBufferGetter(type.VectorType(), bb_var_name); return ByteBufferGetter(type.VectorType(), bb_var_name);
case BASE_TYPE_INT: return bb_var_name + ".getInt"; case BASE_TYPE_INT:
case BASE_TYPE_UINT: return bb_var_name + ".getUInt"; return bb_var_name + ".getInt";
case BASE_TYPE_SHORT: return bb_var_name + ".getShort"; case BASE_TYPE_UINT:
case BASE_TYPE_USHORT: return bb_var_name + ".getUShort"; return bb_var_name + ".getUInt";
case BASE_TYPE_ULONG: return bb_var_name + ".getULong"; case BASE_TYPE_SHORT:
case BASE_TYPE_LONG: return bb_var_name + ".getLong"; return bb_var_name + ".getShort";
case BASE_TYPE_FLOAT: return bb_var_name + ".getFloat"; case BASE_TYPE_USHORT:
case BASE_TYPE_DOUBLE: return bb_var_name + ".getDouble"; 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_UTYPE:
case BASE_TYPE_UCHAR: return bb_var_name + ".getUByte"; case BASE_TYPE_UCHAR:
return bb_var_name + ".getUByte";
case BASE_TYPE_CHAR: case BASE_TYPE_CHAR:
case BASE_TYPE_NONE: return bb_var_name + ".get"; case BASE_TYPE_NONE:
case BASE_TYPE_BOOL: return "0.toByte() != " + bb_var_name + ".get"; return bb_var_name + ".get";
default: return bb_var_name + "." + namer_.Method("get", GenType(type)); case BASE_TYPE_BOOL:
return "0.toByte() != " + bb_var_name + ".get";
default:
return bb_var_name + "." + namer_.Method("get", GenType(type));
} }
} }
@@ -550,7 +613,9 @@ class KotlinKMPGenerator : public BaseGenerator {
auto vec = struct_def.fields.vec; auto vec = struct_def.fields.vec;
for (auto it = vec.begin(); it != vec.end(); ++it) { for (auto it = vec.begin(); it != vec.end(); ++it) {
auto& field = **it; auto& field = **it;
if (IsUnsigned(field.value.type.base_type)) { return true; } if (IsUnsigned(field.value.type.base_type)) {
return true;
}
} }
return false; return false;
} }
@@ -794,7 +859,9 @@ class KotlinKMPGenerator : public BaseGenerator {
writer.IncrementIdentLevel(); writer.IncrementIdentLevel();
for (auto it = field_vec.begin(); it != field_vec.end(); ++it) { for (auto it = field_vec.begin(); it != field_vec.end(); ++it) {
auto& field = **it; auto& field = **it;
if (field.deprecated || !field.IsRequired()) { continue; } if (field.deprecated || !field.IsRequired()) {
continue;
}
writer.SetValue("offset", NumToString(field.value.offset)); writer.SetValue("offset", NumToString(field.value.offset));
writer.SetValue("field_name", field.name); writer.SetValue("field_name", field.name);
writer += "builder.required(o, {{offset}}, \"{{field_name}}\")"; writer += "builder.required(o, {{offset}}, \"{{field_name}}\")";
@@ -1067,9 +1134,8 @@ class KotlinKMPGenerator : public BaseGenerator {
// fun pos(obj: Vec3) : Vec3? = obj.init(bufferPos + 4, bb) // fun pos(obj: Vec3) : Vec3? = obj.init(bufferPos + 4, bb)
// ? adds nullability annotation // ? adds nullability annotation
GenerateFunOneLine( GenerateFunOneLine(
writer, field_name, "obj: " + field_type, return_type, [&]() { writer, field_name, "obj: " + field_type, return_type,
writer += "obj.init(bufferPos + {{offset}}, bb)"; [&]() { writer += "obj.init(bufferPos + {{offset}}, bb)"; });
});
} else { } else {
// create getter with object reuse // create getter with object reuse
// ex: // ex:
@@ -1147,7 +1213,8 @@ class KotlinKMPGenerator : public BaseGenerator {
case BASE_TYPE_UTYPE: case BASE_TYPE_UTYPE:
found = "{{field_type}}({{bbgetter}}({{index}}))"; found = "{{field_type}}({{bbgetter}}({{index}}))";
break; break;
default: found = "{{bbgetter}}({{index}})"; default:
found = "{{bbgetter}}({{index}})";
} }
} }
writer += writer +=
@@ -1162,7 +1229,8 @@ class KotlinKMPGenerator : public BaseGenerator {
offset_val, bbgetter + "(obj, it + bufferPos)", "null"); offset_val, bbgetter + "(obj, it + bufferPos)", "null");
}); });
break; break;
default: FLATBUFFERS_ASSERT(0); default:
FLATBUFFERS_ASSERT(0);
} }
} }
@@ -1278,15 +1346,21 @@ class KotlinKMPGenerator : public BaseGenerator {
case BASE_TYPE_UINT: case BASE_TYPE_UINT:
case BASE_TYPE_UCHAR: case BASE_TYPE_UCHAR:
case BASE_TYPE_UTYPE: case BASE_TYPE_UTYPE:
case BASE_TYPE_USHORT: return "u"; case BASE_TYPE_USHORT:
case BASE_TYPE_ULONG: return "UL"; return "u";
case BASE_TYPE_LONG: return "L"; case BASE_TYPE_ULONG:
default: return ""; return "UL";
case BASE_TYPE_LONG:
return "L";
default:
return "";
} }
} }
std::string WrapEnumValue(const Type& type, const std::string value) const { std::string WrapEnumValue(const Type& type, const std::string value) const {
if (IsEnum(type)) { return GenType(type) + "(" + value + ")"; } if (IsEnum(type)) {
return GenType(type) + "(" + value + ")";
}
if (IsVector(type) && IsEnum(type.VectorType())) { if (IsVector(type) && IsEnum(type.VectorType())) {
return GenType(type.VectorType()) + "(" + value + ")"; return GenType(type.VectorType()) + "(" + value + ")";
} }
@@ -1367,7 +1441,9 @@ class KotlinKMPGenerator : public BaseGenerator {
// builder: FlatBufferBuilder // builder: FlatBufferBuilder
std::stringstream out; std::stringstream out;
auto field_vec = struct_def.fields.vec; auto field_vec = struct_def.fields.vec;
if (prefix.empty()) { out << "builder: FlatBufferBuilder"; } if (prefix.empty()) {
out << "builder: FlatBufferBuilder";
}
for (auto it = field_vec.begin(); it != field_vec.end(); ++it) { for (auto it = field_vec.begin(); it != field_vec.end(); ++it) {
auto& field = **it; auto& field = **it;
if (IsStruct(field.value.type)) { if (IsStruct(field.value.type)) {
@@ -1527,26 +1603,35 @@ class KotlinKMPGenerator : public BaseGenerator {
static std::string NotFoundReturn(BaseType el) { static std::string NotFoundReturn(BaseType el) {
switch (el) { switch (el) {
case BASE_TYPE_FLOAT: return "0.0f"; case BASE_TYPE_FLOAT:
case BASE_TYPE_DOUBLE: return "0.0"; return "0.0f";
case BASE_TYPE_BOOL: return "false"; case BASE_TYPE_DOUBLE:
return "0.0";
case BASE_TYPE_BOOL:
return "false";
case BASE_TYPE_LONG: case BASE_TYPE_LONG:
case BASE_TYPE_INT: case BASE_TYPE_INT:
case BASE_TYPE_CHAR: case BASE_TYPE_CHAR:
case BASE_TYPE_SHORT: return "0"; case BASE_TYPE_SHORT:
return "0";
case BASE_TYPE_UINT: case BASE_TYPE_UINT:
case BASE_TYPE_UCHAR: case BASE_TYPE_UCHAR:
case BASE_TYPE_USHORT: case BASE_TYPE_USHORT:
case BASE_TYPE_UTYPE: return "0u"; case BASE_TYPE_UTYPE:
case BASE_TYPE_ULONG: return "0uL"; return "0u";
default: return "null"; case BASE_TYPE_ULONG:
return "0uL";
default:
return "null";
} }
} }
// Prepend @JvmStatic to methods in companion object. // Prepend @JvmStatic to methods in companion object.
static void GenerateJvmStaticAnnotation(CodeWriter& code, static void GenerateJvmStaticAnnotation(CodeWriter& code,
bool gen_jvmstatic) { bool gen_jvmstatic) {
if (gen_jvmstatic) { code += "@JvmStatic"; } if (gen_jvmstatic) {
code += "@JvmStatic";
}
} }
const IdlNamer namer_; const IdlNamer namer_;
@@ -1565,12 +1650,13 @@ class KotlinKMPCodeGenerator : public CodeGenerator {
public: public:
Status GenerateCode(const Parser& parser, const std::string& path, Status GenerateCode(const Parser& parser, const std::string& path,
const std::string& filename) override { const std::string& filename) override {
if (!GenerateKotlinKMP(parser, path, filename)) { return Status::ERROR; } if (!GenerateKotlinKMP(parser, path, filename)) {
return Status::ERROR;
}
return Status::OK; return Status::OK;
} }
Status GenerateCode(const uint8_t *, int64_t, Status GenerateCode(const uint8_t*, int64_t, const CodeGenOptions&) override {
const CodeGenOptions &) override {
return Status::NOT_IMPLEMENTED; return Status::NOT_IMPLEMENTED;
} }

View File

@@ -205,7 +205,8 @@ class LobsterGenerator : public BaseGenerator {
} }
break; break;
} }
default: FLATBUFFERS_ASSERT(0); default:
FLATBUFFERS_ASSERT(0);
} }
if (IsVector(field.value.type)) { if (IsVector(field.value.type)) {
code += def + code += def +
@@ -425,12 +426,13 @@ class LobsterCodeGenerator : public CodeGenerator {
public: public:
Status GenerateCode(const Parser& parser, const std::string& path, Status GenerateCode(const Parser& parser, const std::string& path,
const std::string& filename) override { const std::string& filename) override {
if (!GenerateLobster(parser, path, filename)) { return Status::ERROR; } if (!GenerateLobster(parser, path, filename)) {
return Status::ERROR;
}
return Status::OK; return Status::OK;
} }
Status GenerateCode(const uint8_t *, int64_t, Status GenerateCode(const uint8_t*, int64_t, const CodeGenOptions&) override {
const CodeGenOptions &) override {
return Status::NOT_IMPLEMENTED; return Status::NOT_IMPLEMENTED;
} }

View File

@@ -382,7 +382,8 @@ class PhpGenerator : public BaseGenerator {
code += Indent + Indent + "return $o != 0 ? $this->"; code += Indent + Indent + "return $o != 0 ? $this->";
code += GenGetter(field.value.type) + "($obj, $o); null;\n"; code += GenGetter(field.value.type) + "($obj, $o); null;\n";
break; break;
default: break; default:
break;
} }
code += Indent + "}\n\n"; code += Indent + "}\n\n";
@@ -520,7 +521,9 @@ class PhpGenerator : public BaseGenerator {
auto& field = **it; auto& field = **it;
if (field.deprecated) continue; if (field.deprecated) continue;
if (it != struct_def.fields.vec.begin()) { code += ", "; } if (it != struct_def.fields.vec.begin()) {
code += ", ";
}
code += "$" + field.name; code += "$" + field.name;
} }
code += ")\n"; code += ")\n";
@@ -697,7 +700,9 @@ class PhpGenerator : public BaseGenerator {
GetStructFieldOfTable(field, code_ptr); GetStructFieldOfTable(field, code_ptr);
} }
break; break;
case BASE_TYPE_STRING: GetStringField(field, code_ptr); break; case BASE_TYPE_STRING:
GetStringField(field, code_ptr);
break;
case BASE_TYPE_VECTOR: { case BASE_TYPE_VECTOR: {
auto vectortype = field.value.type.VectorType(); auto vectortype = field.value.type.VectorType();
if (vectortype.base_type == BASE_TYPE_UNION) { if (vectortype.base_type == BASE_TYPE_UNION) {
@@ -709,8 +714,11 @@ class PhpGenerator : public BaseGenerator {
} }
break; break;
} }
case BASE_TYPE_UNION: GetUnionField(field, code_ptr); break; case BASE_TYPE_UNION:
default: FLATBUFFERS_ASSERT(0); GetUnionField(field, code_ptr);
break;
default:
FLATBUFFERS_ASSERT(0);
} }
} }
if (IsVector(field.value.type)) { if (IsVector(field.value.type)) {
@@ -743,7 +751,9 @@ class PhpGenerator : public BaseGenerator {
} else { } else {
BuildFieldOfTable(field, offset, code_ptr); BuildFieldOfTable(field, offset, code_ptr);
} }
if (IsVector(field.value.type)) { BuildVectorOfTable(field, code_ptr); } if (IsVector(field.value.type)) {
BuildVectorOfTable(field, code_ptr);
}
} }
GetEndOffsetOnTable(struct_def, code_ptr); GetEndOffsetOnTable(struct_def, code_ptr);
@@ -850,11 +860,16 @@ class PhpGenerator : public BaseGenerator {
// Returns the function name that is able to read a value of the given type. // Returns the function name that is able to read a value of the given type.
static std::string GenGetter(const Type& type) { static std::string GenGetter(const Type& type) {
switch (type.base_type) { switch (type.base_type) {
case BASE_TYPE_STRING: return "__string"; case BASE_TYPE_STRING:
case BASE_TYPE_STRUCT: return "__struct"; return "__string";
case BASE_TYPE_UNION: return "__union"; case BASE_TYPE_STRUCT:
case BASE_TYPE_VECTOR: return GenGetter(type.VectorType()); return "__struct";
default: return "Get"; case BASE_TYPE_UNION:
return "__union";
case BASE_TYPE_VECTOR:
return GenGetter(type.VectorType());
default:
return "Get";
} }
} }
@@ -886,9 +901,11 @@ class PhpGenerator : public BaseGenerator {
} }
switch (value.type.base_type) { switch (value.type.base_type) {
case BASE_TYPE_BOOL: return value.constant == "0" ? "false" : "true"; case BASE_TYPE_BOOL:
return value.constant == "0" ? "false" : "true";
case BASE_TYPE_STRING: return "null"; case BASE_TYPE_STRING:
return "null";
case BASE_TYPE_LONG: case BASE_TYPE_LONG:
case BASE_TYPE_ULONG: case BASE_TYPE_ULONG:
@@ -898,18 +915,23 @@ class PhpGenerator : public BaseGenerator {
} }
return "0"; return "0";
default: return value.constant; default:
return value.constant;
} }
} }
static std::string GenTypePointer(const Type& type) { static std::string GenTypePointer(const Type& type) {
switch (type.base_type) { switch (type.base_type) {
case BASE_TYPE_STRING: return "string"; case BASE_TYPE_STRING:
case BASE_TYPE_VECTOR: return GenTypeGet(type.VectorType()); return "string";
case BASE_TYPE_STRUCT: return type.struct_def->name; case BASE_TYPE_VECTOR:
return GenTypeGet(type.VectorType());
case BASE_TYPE_STRUCT:
return type.struct_def->name;
case BASE_TYPE_UNION: case BASE_TYPE_UNION:
// fall through // fall through
default: return "Table"; default:
return "Table";
} }
} }
@@ -951,12 +973,13 @@ class PhpCodeGenerator : public CodeGenerator {
public: public:
Status GenerateCode(const Parser& parser, const std::string& path, Status GenerateCode(const Parser& parser, const std::string& path,
const std::string& filename) override { const std::string& filename) override {
if (!GeneratePhp(parser, path, filename)) { return Status::ERROR; } if (!GeneratePhp(parser, path, filename)) {
return Status::ERROR;
}
return Status::OK; return Status::OK;
} }
Status GenerateCode(const uint8_t *, int64_t, Status GenerateCode(const uint8_t*, int64_t, const CodeGenOptions&) override {
const CodeGenOptions &) override {
return Status::NOT_IMPLEMENTED; return Status::NOT_IMPLEMENTED;
} }

View File

@@ -140,7 +140,8 @@ class PythonStubGenerator {
return module; return module;
} }
template<typename T> std::string ModuleFor(const T *def) const { template <typename T>
std::string ModuleFor(const T* def) const {
if (parser_.opts.one_file) return ModuleForFile(def->file); if (parser_.opts.one_file) return ModuleForFile(def->file);
return namer_.NamespacedType(*def); return namer_.NamespacedType(*def);
} }
@@ -180,9 +181,14 @@ class PythonStubGenerator {
result += import.name; result += import.name;
break; break;
} }
case BASE_TYPE_STRING: result += "str"; break; case BASE_TYPE_STRING:
case BASE_TYPE_NONE: result += "None"; break; result += "str";
default: break; break;
case BASE_TYPE_NONE:
result += "None";
break;
default:
break;
} }
} }
return "typing.Union[" + result + "]"; return "typing.Union[" + result + "]";
@@ -223,14 +229,18 @@ class PythonStubGenerator {
namer_.Type(*type.struct_def)); namer_.Type(*type.struct_def));
return import.name; return import.name;
} }
case BASE_TYPE_STRING: return "str"; case BASE_TYPE_STRING:
return "str";
case BASE_TYPE_ARRAY: case BASE_TYPE_ARRAY:
case BASE_TYPE_VECTOR: { case BASE_TYPE_VECTOR: {
imports->Import("typing"); imports->Import("typing");
return "typing.List[" + TypeOf(type.VectorType(), imports) + "]"; return "typing.List[" + TypeOf(type.VectorType(), imports) + "]";
} }
case BASE_TYPE_UNION: return UnionType(*type.enum_def, imports); case BASE_TYPE_UNION:
default: FLATBUFFERS_ASSERT(0); return ""; return UnionType(*type.enum_def, imports);
default:
FLATBUFFERS_ASSERT(0);
return "";
} }
} }
@@ -252,7 +262,8 @@ class PythonStubGenerator {
namer_.ObjectType(*field_type.struct_def)); namer_.ObjectType(*field_type.struct_def));
return field_name + ": " + import.name + " | None"; return field_name + ": " + import.name + " | None";
} }
case BASE_TYPE_STRING: return field_name + ": str | None"; case BASE_TYPE_STRING:
return field_name + ": str | None";
case BASE_TYPE_ARRAY: case BASE_TYPE_ARRAY:
case BASE_TYPE_VECTOR: { case BASE_TYPE_VECTOR: {
imports->Import("typing"); imports->Import("typing");
@@ -271,7 +282,8 @@ class PythonStubGenerator {
case BASE_TYPE_UNION: case BASE_TYPE_UNION:
return field_name + ": " + return field_name + ": " +
UnionObjectType(*field->value.type.enum_def, imports); UnionObjectType(*field->value.type.enum_def, imports);
default: return field_name; default:
return field_name;
} }
} }
@@ -290,7 +302,9 @@ class PythonStubGenerator {
if (IsScalar(type.base_type)) { if (IsScalar(type.base_type)) {
field_type = TypeOf(type, imports); field_type = TypeOf(type, imports);
if (field->IsOptional()) { field_type += " | None"; } if (field->IsOptional()) {
field_type += " | None";
}
} else { } else {
switch (type.base_type) { switch (type.base_type) {
case BASE_TYPE_STRUCT: { case BASE_TYPE_STRUCT: {
@@ -300,7 +314,9 @@ class PythonStubGenerator {
field_type = "'" + import_.name + "' | None"; field_type = "'" + import_.name + "' | None";
break; break;
} }
case BASE_TYPE_STRING: field_type = "str | None"; break; case BASE_TYPE_STRING:
field_type = "str | None";
break;
case BASE_TYPE_ARRAY: case BASE_TYPE_ARRAY:
case BASE_TYPE_VECTOR: { case BASE_TYPE_VECTOR: {
imports->Import("typing"); imports->Import("typing");
@@ -320,7 +336,9 @@ class PythonStubGenerator {
case BASE_TYPE_UNION: case BASE_TYPE_UNION:
field_type = UnionObjectType(*type.enum_def, imports); field_type = UnionObjectType(*type.enum_def, imports);
break; break;
default: field_type = "typing.Any"; break; default:
field_type = "typing.Any";
break;
} }
} }
stub << " " << field_name << ": " << field_type << " = ...,\n"; stub << " " << field_name << ": " << field_type << " = ...,\n";
@@ -469,7 +487,8 @@ class PythonStubGenerator {
stub << " def " << name << "(self) -> table.Table | None: ...\n"; stub << " def " << name << "(self) -> table.Table | None: ...\n";
break; break;
} }
default: break; default:
break;
} }
} }
} }
@@ -513,7 +532,9 @@ class PythonStubGenerator {
stub << '\n'; stub << '\n';
stub << "def Create" + namer_.Type(*struct_def) stub << "def Create" + namer_.Type(*struct_def)
<< "(builder: flatbuffers.Builder"; << "(builder: flatbuffers.Builder";
for (const std::string &arg : args) { stub << ", " << arg; } for (const std::string& arg : args) {
stub << ", " << arg;
}
stub << ") -> uoffset: ...\n"; stub << ") -> uoffset: ...\n";
} }
@@ -617,7 +638,9 @@ class PythonStubGenerator {
ss << "from __future__ import annotations\n"; ss << "from __future__ import annotations\n";
ss << '\n'; ss << '\n';
ss << "import flatbuffers\n"; ss << "import flatbuffers\n";
if (parser_.opts.python_gen_numpy) { ss << "import numpy as np\n"; } if (parser_.opts.python_gen_numpy) {
ss << "import numpy as np\n";
}
ss << '\n'; ss << '\n';
std::set<std::string> modules; std::set<std::string> modules;
@@ -772,7 +795,9 @@ class PythonGenerator : public BaseGenerator {
GenReceiver(struct_def, code_ptr); GenReceiver(struct_def, code_ptr);
code += namer_.Method(field) + "Length(self)"; code += namer_.Method(field) + "Length(self)";
if (parser_.opts.python_typing) { code += " -> int"; } if (parser_.opts.python_typing) {
code += " -> int";
}
code += ":"; code += ":";
if (!IsArray(field.value.type)) { if (!IsArray(field.value.type)) {
code += OffsetPrefix(field, false); code += OffsetPrefix(field, false);
@@ -791,7 +816,9 @@ class PythonGenerator : public BaseGenerator {
GenReceiver(struct_def, code_ptr); GenReceiver(struct_def, code_ptr);
code += namer_.Method(field) + "IsNone(self)"; code += namer_.Method(field) + "IsNone(self)";
if (parser_.opts.python_typing) { code += " -> bool"; } if (parser_.opts.python_typing) {
code += " -> bool";
}
code += ":"; code += ":";
if (!IsArray(field.value.type)) { if (!IsArray(field.value.type)) {
code += GenIndents(2) + code += GenIndents(2) +
@@ -829,7 +856,9 @@ class PythonGenerator : public BaseGenerator {
code += OffsetPrefix(field); code += OffsetPrefix(field);
getter += "o + self._tab.Pos)"; getter += "o + self._tab.Pos)";
auto is_bool = IsBool(field.value.type.base_type); auto is_bool = IsBool(field.value.type.base_type);
if (is_bool) { getter = "bool(" + getter + ")"; } if (is_bool) {
getter = "bool(" + getter + ")";
}
code += Indent + Indent + Indent + "return " + getter + "\n"; code += Indent + Indent + Indent + "return " + getter + "\n";
std::string default_value; std::string default_value;
if (field.IsScalarOptional()) { if (field.IsScalarOptional()) {
@@ -1014,8 +1043,11 @@ class PythonGenerator : public BaseGenerator {
code += Indent + Indent + "return None\n\n"; code += Indent + Indent + "return None\n\n";
} }
template<typename T> std::string ModuleFor(const T *def) const { template <typename T>
if (!parser_.opts.one_file) { return namer_.NamespacedType(*def); } std::string ModuleFor(const T* def) const {
if (!parser_.opts.one_file) {
return namer_.NamespacedType(*def);
}
std::string filename = std::string filename =
StripExtension(def->file) + parser_.opts.filename_suffix; StripExtension(def->file) + parser_.opts.filename_suffix;
@@ -1116,7 +1148,9 @@ class PythonGenerator : public BaseGenerator {
// Currently, we only support accessing as numpy array if // Currently, we only support accessing as numpy array if
// the vector type is a scalar. // the vector type is a scalar.
if (!(IsScalar(vectortype.base_type))) { return; } if (!(IsScalar(vectortype.base_type))) {
return;
}
GenReceiver(struct_def, code_ptr); GenReceiver(struct_def, code_ptr);
code += namer_.Method(field) + "AsNumpy(self):"; code += namer_.Method(field) + "AsNumpy(self):";
@@ -1163,11 +1197,15 @@ class PythonGenerator : public BaseGenerator {
const FieldDef& field, std::string* code_ptr, const FieldDef& field, std::string* code_ptr,
ImportMap& imports) const { ImportMap& imports) const {
auto nested = field.attributes.Lookup("nested_flatbuffer"); auto nested = field.attributes.Lookup("nested_flatbuffer");
if (!nested) { return; } // There is no nested flatbuffer. if (!nested) {
return;
} // There is no nested flatbuffer.
const std::string unqualified_name = nested->constant; const std::string unqualified_name = nested->constant;
std::string qualified_name = NestedFlatbufferType(unqualified_name); std::string qualified_name = NestedFlatbufferType(unqualified_name);
if (qualified_name.empty()) { qualified_name = nested->constant; } if (qualified_name.empty()) {
qualified_name = nested->constant;
}
const ImportMapEntry import_entry = {qualified_name, unqualified_name}; const ImportMapEntry import_entry = {qualified_name, unqualified_name};
@@ -1231,7 +1269,9 @@ class PythonGenerator : public BaseGenerator {
} else { } else {
auto& code = *code_ptr; auto& code = *code_ptr;
code += std::string(", ") + nameprefix; code += std::string(", ") + nameprefix;
if (has_field_name) { code += namer_.Field(field); } if (has_field_name) {
code += namer_.Field(field);
}
code += namesuffix; code += namesuffix;
} }
} }
@@ -1431,7 +1471,9 @@ class PythonGenerator : public BaseGenerator {
const FieldDef& field, const FieldDef& field,
std::string* code_ptr) const { std::string* code_ptr) const {
auto nested = field.attributes.Lookup("nested_flatbuffer"); auto nested = field.attributes.Lookup("nested_flatbuffer");
if (!nested) { return; } // There is no nested flatbuffer. if (!nested) {
return;
} // There is no nested flatbuffer.
auto& code = *code_ptr; auto& code = *code_ptr;
const std::string field_method = namer_.Method(field); const std::string field_method = namer_.Method(field);
@@ -1546,7 +1588,8 @@ class PythonGenerator : public BaseGenerator {
case BASE_TYPE_UNION: case BASE_TYPE_UNION:
GetUnionField(struct_def, field, code_ptr, imports); GetUnionField(struct_def, field, code_ptr, imports);
break; break;
default: FLATBUFFERS_ASSERT(0); default:
FLATBUFFERS_ASSERT(0);
} }
} }
if (IsVector(field.value.type) || IsArray(field.value.type)) { if (IsVector(field.value.type) || IsArray(field.value.type)) {
@@ -1728,9 +1771,14 @@ class PythonGenerator : public BaseGenerator {
} }
field_type = "'" + field_type + "'"; field_type = "'" + field_type + "'";
break; break;
case BASE_TYPE_STRING: field_type += "str"; break; case BASE_TYPE_STRING:
case BASE_TYPE_NONE: field_type += "None"; break; field_type += "str";
default: break; break;
case BASE_TYPE_NONE:
field_type += "None";
break;
default:
break;
} }
field_types += field_type + separator_string; field_types += field_type + separator_string;
} }
@@ -2161,7 +2209,8 @@ class PythonGenerator : public BaseGenerator {
} }
break; break;
} }
default: GenUnPackForScalar(struct_def, field, &code); default:
GenUnPackForScalar(struct_def, field, &code);
} }
} }
@@ -2264,19 +2313,45 @@ class PythonGenerator : public BaseGenerator {
std::string type_name; std::string type_name;
switch (vectortype.base_type) { switch (vectortype.base_type) {
case BASE_TYPE_BOOL: type_name = "Bool"; break; case BASE_TYPE_BOOL:
case BASE_TYPE_CHAR: type_name = "Byte"; break; type_name = "Bool";
case BASE_TYPE_UCHAR: type_name = "Uint8"; break; break;
case BASE_TYPE_SHORT: type_name = "Int16"; break; case BASE_TYPE_CHAR:
case BASE_TYPE_USHORT: type_name = "Uint16"; break; type_name = "Byte";
case BASE_TYPE_INT: type_name = "Int32"; break; break;
case BASE_TYPE_UINT: type_name = "Uint32"; break; case BASE_TYPE_UCHAR:
case BASE_TYPE_LONG: type_name = "Int64"; break; type_name = "Uint8";
case BASE_TYPE_ULONG: type_name = "Uint64"; break; break;
case BASE_TYPE_FLOAT: type_name = "Float32"; break; case BASE_TYPE_SHORT:
case BASE_TYPE_DOUBLE: type_name = "Float64"; break; type_name = "Int16";
case BASE_TYPE_STRING: type_name = "UOffsetTRelative"; break; break;
default: type_name = "VOffsetT"; break; case BASE_TYPE_USHORT:
type_name = "Uint16";
break;
case BASE_TYPE_INT:
type_name = "Int32";
break;
case BASE_TYPE_UINT:
type_name = "Uint32";
break;
case BASE_TYPE_LONG:
type_name = "Int64";
break;
case BASE_TYPE_ULONG:
type_name = "Uint64";
break;
case BASE_TYPE_FLOAT:
type_name = "Float32";
break;
case BASE_TYPE_DOUBLE:
type_name = "Float64";
break;
case BASE_TYPE_STRING:
type_name = "UOffsetTRelative";
break;
default:
type_name = "VOffsetT";
break;
} }
code += type_name; code += type_name;
} }
@@ -2458,7 +2533,9 @@ class PythonGenerator : public BaseGenerator {
InitializeFromObjForObject(struct_def, &code); InitializeFromObjForObject(struct_def, &code);
if (parser_.opts.gen_compare) { GenCompareOperator(struct_def, &code); } if (parser_.opts.gen_compare) {
GenCompareOperator(struct_def, &code);
}
GenUnPack(struct_def, &code); GenUnPack(struct_def, &code);
@@ -2532,7 +2609,8 @@ class PythonGenerator : public BaseGenerator {
case BASE_TYPE_STRING: case BASE_TYPE_STRING:
GenUnionCreatorForString(enum_def, ev, &code); GenUnionCreatorForString(enum_def, ev, &code);
break; break;
default: break; default:
break;
} }
} }
code += GenIndents(1) + "return None"; code += GenIndents(1) + "return None";
@@ -2555,9 +2633,12 @@ class PythonGenerator : public BaseGenerator {
// Returns the function name that is able to read a value of the given type. // Returns the function name that is able to read a value of the given type.
std::string GenGetter(const Type& type) const { std::string GenGetter(const Type& type) const {
switch (type.base_type) { switch (type.base_type) {
case BASE_TYPE_STRING: return "self._tab.String("; case BASE_TYPE_STRING:
case BASE_TYPE_UNION: return "self._tab.Union("; return "self._tab.String(";
case BASE_TYPE_VECTOR: return GenGetter(type.VectorType()); case BASE_TYPE_UNION:
return "self._tab.Union(";
case BASE_TYPE_VECTOR:
return GenGetter(type.VectorType());
default: default:
return "self._tab.Get(flatbuffers.number_types." + return "self._tab.Get(flatbuffers.number_types." +
namer_.Method(GenTypeGet(type)) + "Flags, "; namer_.Method(GenTypeGet(type)) + "Flags, ";
@@ -2567,11 +2648,17 @@ class PythonGenerator : public BaseGenerator {
std::string GenFieldTy(const FieldDef& field) const { std::string GenFieldTy(const FieldDef& field) const {
if (IsScalar(field.value.type.base_type) || IsArray(field.value.type)) { if (IsScalar(field.value.type.base_type) || IsArray(field.value.type)) {
const std::string ty = GenTypeBasic(field.value.type); const std::string ty = GenTypeBasic(field.value.type);
if (ty.find("int") != std::string::npos) { return "int"; } if (ty.find("int") != std::string::npos) {
return "int";
}
if (ty.find("float") != std::string::npos) { return "float"; } if (ty.find("float") != std::string::npos) {
return "float";
}
if (ty == "bool") { return "bool"; } if (ty == "bool") {
return "bool";
}
return "Any"; return "Any";
} else { } else {
@@ -2606,14 +2693,18 @@ class PythonGenerator : public BaseGenerator {
std::string GenTypePointer(const Type& type) const { std::string GenTypePointer(const Type& type) const {
switch (type.base_type) { switch (type.base_type) {
case BASE_TYPE_STRING: return "string"; case BASE_TYPE_STRING:
return "string";
case BASE_TYPE_VECTOR: case BASE_TYPE_VECTOR:
// fall through // fall through
case BASE_TYPE_ARRAY: return GenTypeGet(type.VectorType()); case BASE_TYPE_ARRAY:
case BASE_TYPE_STRUCT: return type.struct_def->name; return GenTypeGet(type.VectorType());
case BASE_TYPE_STRUCT:
return type.struct_def->name;
case BASE_TYPE_UNION: case BASE_TYPE_UNION:
// fall through // fall through
default: return "*flatbuffers.Table"; default:
return "*flatbuffers.Table";
} }
} }
@@ -2645,7 +2736,9 @@ class PythonGenerator : public BaseGenerator {
const std::string self_type = struct_def.name; const std::string self_type = struct_def.name;
std::string field_type = TypeName(field); std::string field_type = TypeName(field);
if (self_type == field_type) { field_type = "'" + field_type + "'"; } if (self_type == field_type) {
field_type = "'" + field_type + "'";
}
return field_type; return field_type;
} }
@@ -2722,9 +2815,13 @@ class PythonGenerator : public BaseGenerator {
} }
if (parser_.opts.one_file) { if (parser_.opts.one_file) {
if (!declcode.empty()) { *one_file_code += declcode + "\n\n"; } if (!declcode.empty()) {
*one_file_code += declcode + "\n\n";
}
for (auto import_str : imports) { one_file_imports.insert(import_str); } for (auto import_str : imports) {
one_file_imports.insert(import_str);
}
} else { } else {
const std::string mod = const std::string mod =
namer_.File(struct_def, SkipFile::SuffixAndExtension); namer_.File(struct_def, SkipFile::SuffixAndExtension);
@@ -2767,7 +2864,9 @@ class PythonGenerator : public BaseGenerator {
} }
} }
} }
if (parser_.opts.python_gen_numpy) { code += "np = import_numpy()\n\n"; } if (parser_.opts.python_gen_numpy) {
code += "np = import_numpy()\n\n";
}
} }
} }
@@ -2824,12 +2923,13 @@ class PythonCodeGenerator : public CodeGenerator {
public: public:
Status GenerateCode(const Parser& parser, const std::string& path, Status GenerateCode(const Parser& parser, const std::string& path,
const std::string& filename) override { const std::string& filename) override {
if (!GeneratePython(parser, path, filename)) { return Status::ERROR; } if (!GeneratePython(parser, path, filename)) {
return Status::ERROR;
}
return Status::OK; return Status::OK;
} }
Status GenerateCode(const uint8_t *, int64_t, Status GenerateCode(const uint8_t*, int64_t, const CodeGenOptions&) override {
const CodeGenOptions &) override {
return Status::NOT_IMPLEMENTED; return Status::NOT_IMPLEMENTED;
} }
@@ -2845,7 +2945,9 @@ class PythonCodeGenerator : public CodeGenerator {
Status GenerateGrpcCode(const Parser& parser, const std::string& path, Status GenerateGrpcCode(const Parser& parser, const std::string& path,
const std::string& filename) override { const std::string& filename) override {
if (!GeneratePythonGRPC(parser, path, filename)) { return Status::ERROR; } if (!GeneratePythonGRPC(parser, path, filename)) {
return Status::ERROR;
}
return Status::OK; return Status::OK;
} }

View File

@@ -485,7 +485,9 @@ class RustGenerator : public BaseGenerator {
// Generate global helper functions. // Generate global helper functions.
if (parser_.root_struct_def_) { if (parser_.root_struct_def_) {
auto& struct_def = *parser_.root_struct_def_; auto& struct_def = *parser_.root_struct_def_;
if (struct_def.defined_namespace != ns) { continue; } if (struct_def.defined_namespace != ns) {
continue;
}
SetNameSpace(struct_def.defined_namespace); SetNameSpace(struct_def.defined_namespace);
GenRootTableFuncs(struct_def); GenRootTableFuncs(struct_def);
} }
@@ -530,9 +532,13 @@ class RustGenerator : public BaseGenerator {
for (auto it = struct_def.fields.vec.begin(); for (auto it = struct_def.fields.vec.begin();
it != struct_def.fields.vec.end(); ++it) { it != struct_def.fields.vec.end(); ++it) {
const auto& field = **it; const auto& field = **it;
if (field.deprecated) { continue; } if (field.deprecated) {
continue;
}
if (TableBuilderTypeNeedsLifetime(field.value.type)) { return true; } if (TableBuilderTypeNeedsLifetime(field.value.type)) {
return true;
}
} }
return false; return false;
@@ -619,7 +625,9 @@ class RustGenerator : public BaseGenerator {
}; };
// clang-format on // clang-format on
if (type.enum_def) { return WrapInNameSpace(*type.enum_def); } if (type.enum_def) {
return WrapInNameSpace(*type.enum_def);
}
return ctypename[type.base_type]; return ctypename[type.base_type];
} }
@@ -841,7 +849,8 @@ class RustGenerator : public BaseGenerator {
code_ += " #[inline]"; code_ += " #[inline]";
code_ += " unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {"; code_ += " unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {";
code_ += code_ +=
" let b = unsafe { flatbuffers::read_scalar_at::<{{BASE_TYPE}}>(buf, loc) };"; " let b = unsafe { "
"flatbuffers::read_scalar_at::<{{BASE_TYPE}}>(buf, loc) };";
if (IsBitFlagsEnum(enum_def)) { if (IsBitFlagsEnum(enum_def)) {
code_ += " Self::from_bits_retain(b)"; code_ += " Self::from_bits_retain(b)";
} else { } else {
@@ -898,7 +907,9 @@ class RustGenerator : public BaseGenerator {
code_.SetValue("UNION_TYPE", namer_.Type(enum_def)); code_.SetValue("UNION_TYPE", namer_.Type(enum_def));
code_ += "{{ACCESS_TYPE}} struct {{UNION_TYPE}}UnionTableOffset {}"; code_ += "{{ACCESS_TYPE}} struct {{UNION_TYPE}}UnionTableOffset {}";
code_ += ""; code_ += "";
if (parser_.opts.generate_object_based_api) { GenUnionObject(enum_def); } if (parser_.opts.generate_object_based_api) {
GenUnionObject(enum_def);
}
} }
} }
@@ -1033,7 +1044,9 @@ class RustGenerator : public BaseGenerator {
} else { } else {
// This for defaults in objects. // This for defaults in objects.
// Unions have a NONE variant instead of using Rust's None. // Unions have a NONE variant instead of using Rust's None.
if (field.IsOptional() && !IsUnion(field.value.type)) { return "None"; } if (field.IsOptional() && !IsUnion(field.value.type)) {
return "None";
}
} }
switch (GetFullType(field.value.type)) { switch (GetFullType(field.value.type)) {
case ftInteger: { case ftInteger: {
@@ -1596,7 +1609,9 @@ class RustGenerator : public BaseGenerator {
for (auto it = def.Vals().begin(); it != def.Vals().end(); ++it) { for (auto it = def.Vals().begin(); it != def.Vals().end(); ++it) {
const EnumVal& ev = **it; const EnumVal& ev = **it;
// TODO(cneo): Can variants be deprecated, should we skip them? // TODO(cneo): Can variants be deprecated, should we skip them?
if (ev.union_type.base_type == BASE_TYPE_NONE) { continue; } if (ev.union_type.base_type == BASE_TYPE_NONE) {
continue;
}
code_.SetValue( code_.SetValue(
"U_ELEMENT_ENUM_TYPE", "U_ELEMENT_ENUM_TYPE",
WrapInNameSpace(def.defined_namespace, namer_.EnumVariant(def, ev))); WrapInNameSpace(def.defined_namespace, namer_.EnumVariant(def, ev)));
@@ -1736,7 +1751,8 @@ class RustGenerator : public BaseGenerator {
code_ += " let {{FIELD}} = self.{{FIELD}}();"; code_ += " let {{FIELD}} = self.{{FIELD}}();";
return; return;
} }
case ftUnionKey: return; case ftUnionKey:
return;
case ftUnionValue: { case ftUnionValue: {
const auto& enum_def = *type.enum_def; const auto& enum_def = *type.enum_def;
code_.SetValue("ENUM_TY", WrapInNameSpace(enum_def)); code_.SetValue("ENUM_TY", WrapInNameSpace(enum_def));
@@ -1851,7 +1867,9 @@ class RustGenerator : public BaseGenerator {
code_ += "}"; code_ += "}";
// Generate a comparison function for this field if it is a key. // Generate a comparison function for this field if it is a key.
if (field.key) { GenKeyFieldMethods(field); } if (field.key) {
GenKeyFieldMethods(field);
}
// Generate a nested flatbuffer field, if applicable. // Generate a nested flatbuffer field, if applicable.
auto nested = field.attributes.Lookup("nested_flatbuffer"); auto nested = field.attributes.Lookup("nested_flatbuffer");
@@ -2261,7 +2279,8 @@ class RustGenerator : public BaseGenerator {
code_ += " let {{FIELD}} = self.{{FIELD}};"; code_ += " let {{FIELD}} = self.{{FIELD}};";
return; return;
} }
case ftUnionKey: return; // Generate union type with union value. case ftUnionKey:
return; // Generate union type with union value.
case ftUnionValue: { case ftUnionValue: {
code_.SetValue("ENUM_METHOD", code_.SetValue("ENUM_METHOD",
namer_.Method(*field.value.type.enum_def)); namer_.Method(*field.value.type.enum_def));
@@ -2663,7 +2682,9 @@ class RustGenerator : public BaseGenerator {
code_ += " type Inner = &'a {{STRUCT_TY}};"; code_ += " type Inner = &'a {{STRUCT_TY}};";
code_ += " #[inline]"; code_ += " #[inline]";
code_ += " unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {"; code_ += " unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {";
code_ += " unsafe { flatbuffers::follow_cast_ref::<{{STRUCT_TY}}>(buf, loc) }"; code_ +=
" unsafe { flatbuffers::follow_cast_ref::<{{STRUCT_TY}}>(buf, loc) "
"}";
code_ += " }"; code_ += " }";
code_ += "}"; code_ += "}";
code_ += "impl<'b> flatbuffers::Push for {{STRUCT_TY}} {"; code_ += "impl<'b> flatbuffers::Push for {{STRUCT_TY}} {";
@@ -2671,7 +2692,8 @@ class RustGenerator : public BaseGenerator {
code_ += " #[inline]"; code_ += " #[inline]";
code_ += " unsafe fn push(&self, dst: &mut [u8], _written_len: usize) {"; code_ += " unsafe fn push(&self, dst: &mut [u8], _written_len: usize) {";
code_ += code_ +=
" let src = unsafe { ::core::slice::from_raw_parts(self as *const " " let src = unsafe { ::core::slice::from_raw_parts(self as "
"*const "
"{{STRUCT_TY}} as *const u8, <Self as flatbuffers::Push>::size()) };"; "{{STRUCT_TY}} as *const u8, <Self as flatbuffers::Push>::size()) };";
code_ += " dst.copy_from_slice(src);"; code_ += " dst.copy_from_slice(src);";
code_ += " }"; code_ += " }";
@@ -2851,7 +2873,9 @@ class RustGenerator : public BaseGenerator {
code_ += "}\n"; code_ += "}\n";
// Generate a comparison function for this field if it is a key. // Generate a comparison function for this field if it is a key.
if (field.key) { GenKeyFieldMethods(field); } if (field.key) {
GenKeyFieldMethods(field);
}
}); });
// Generate Object API unpack method. // Generate Object API unpack method.
@@ -2964,7 +2988,9 @@ class RustGenerator : public BaseGenerator {
// The file must start and end with an empty (or null) namespace so that // The file must start and end with an empty (or null) namespace so that
// namespaces are properly opened and closed. // namespaces are properly opened and closed.
void SetNameSpace(const Namespace* ns) { void SetNameSpace(const Namespace* ns) {
if (cur_name_space_ == ns) { return; } if (cur_name_space_ == ns) {
return;
}
// Compute the size of the longest common namespace prefix. // Compute the size of the longest common namespace prefix.
// If cur_name_space is A::B::C::D and ns is A::B::E::F::G, // If cur_name_space is A::B::C::D and ns is A::B::E::F::G,
@@ -2985,7 +3011,9 @@ class RustGenerator : public BaseGenerator {
for (size_t j = old_size; j > common_prefix_size; --j) { for (size_t j = old_size; j > common_prefix_size; --j) {
code_ += "} // pub mod " + cur_name_space_->components[j - 1]; code_ += "} // pub mod " + cur_name_space_->components[j - 1];
} }
if (old_size != common_prefix_size) { code_ += ""; } if (old_size != common_prefix_size) {
code_ += "";
}
// open namespace parts to reach the ns namespace // open namespace parts to reach the ns namespace
// in the previous example, E, then F, then G are opened // in the previous example, E, then F, then G are opened
@@ -2995,7 +3023,9 @@ class RustGenerator : public BaseGenerator {
// Generate local namespace imports. // Generate local namespace imports.
GenNamespaceImports(2); GenNamespaceImports(2);
} }
if (new_size != common_prefix_size) { code_ += ""; } if (new_size != common_prefix_size) {
code_ += "";
}
cur_name_space_ = ns; cur_name_space_ = ns;
} }
@@ -3033,12 +3063,13 @@ class RustCodeGenerator : public CodeGenerator {
public: public:
Status GenerateCode(const Parser& parser, const std::string& path, Status GenerateCode(const Parser& parser, const std::string& path,
const std::string& filename) override { const std::string& filename) override {
if (!GenerateRust(parser, path, filename)) { return Status::ERROR; } if (!GenerateRust(parser, path, filename)) {
return Status::ERROR;
}
return Status::OK; return Status::OK;
} }
Status GenerateCode(const uint8_t *, int64_t, Status GenerateCode(const uint8_t*, int64_t, const CodeGenOptions&) override {
const CodeGenOptions &) override {
return Status::NOT_IMPLEMENTED; return Status::NOT_IMPLEMENTED;
} }
@@ -3059,7 +3090,9 @@ class RustCodeGenerator : public CodeGenerator {
Status GenerateRootFile(const Parser& parser, Status GenerateRootFile(const Parser& parser,
const std::string& path) override { const std::string& path) override {
if (!GenerateRustModuleRootFile(parser, path)) { return Status::ERROR; } if (!GenerateRustModuleRootFile(parser, path)) {
return Status::ERROR;
}
return Status::OK; return Status::OK;
} }

View File

@@ -174,7 +174,9 @@ class SwiftGenerator : public BaseGenerator {
code_ += "// swiftlint:disable all"; code_ += "// swiftlint:disable all";
code_ += "// swiftformat:disable all\n"; code_ += "// swiftformat:disable all\n";
if (parser_.opts.include_dependence_headers || parser_.opts.generate_all) { if (parser_.opts.include_dependence_headers || parser_.opts.generate_all) {
code_.SetValue("IMPLEMENTONLY", parser_.opts.swift_implementation_only ? "@_implementationOnly " : ""); code_.SetValue("IMPLEMENTONLY", parser_.opts.swift_implementation_only
? "@_implementationOnly "
: "");
code_ += "#if canImport(Common)"; code_ += "#if canImport(Common)";
code_ += "{{IMPLEMENTONLY}}import Common"; code_ += "{{IMPLEMENTONLY}}import Common";
code_ += "#endif"; code_ += "#endif";
@@ -186,7 +188,9 @@ class SwiftGenerator : public BaseGenerator {
for (auto it = parser_.enums_.vec.begin(); it != parser_.enums_.vec.end(); for (auto it = parser_.enums_.vec.begin(); it != parser_.enums_.vec.end();
++it) { ++it) {
const auto& enum_def = **it; const auto& enum_def = **it;
if (!enum_def.generated) { GenEnum(enum_def); } if (!enum_def.generated) {
GenEnum(enum_def);
}
} }
for (auto it = parser_.structs_.vec.begin(); for (auto it = parser_.structs_.vec.begin();
@@ -269,7 +273,9 @@ class SwiftGenerator : public BaseGenerator {
accessing_value); accessing_value);
base_constructor.push_back("_" + field_var + " = " + base_value); base_constructor.push_back("_" + field_var + " = " + base_value);
if (field.padding) { GenPadding(field, &padding_id); } if (field.padding) {
GenPadding(field, &padding_id);
}
constructor += field_var + ": " + type; constructor += field_var + ": " + type;
} }
code_ += ""; code_ += "";
@@ -444,7 +450,9 @@ class SwiftGenerator : public BaseGenerator {
for (auto it = struct_def.fields.vec.begin(); for (auto it = struct_def.fields.vec.begin();
it != struct_def.fields.vec.end(); ++it) { it != struct_def.fields.vec.end(); ++it) {
const auto& field = **it; const auto& field = **it;
if (field.deprecated) { continue; } if (field.deprecated) {
continue;
}
code_.SetValue("OFFSET_NAME", namer_.Variable(field)); code_.SetValue("OFFSET_NAME", namer_.Variable(field));
code_.SetValue("OFFSET_VALUE", NumToString(field.value.offset)); code_.SetValue("OFFSET_VALUE", NumToString(field.value.offset));
code_ += "case {{OFFSET_NAME}} = {{OFFSET_VALUE}}"; code_ += "case {{OFFSET_NAME}} = {{OFFSET_VALUE}}";
@@ -568,8 +576,7 @@ class SwiftGenerator : public BaseGenerator {
"_ fbb: inout FlatBufferBuilder) -> Offset {"; "_ fbb: inout FlatBufferBuilder) -> Offset {";
Indent(); Indent();
code_ += spacing + "var off = offsets"; code_ += spacing + "var off = offsets";
code_ += code_ += spacing +
spacing +
"off.sort { Table.compare(Table.offset(Int32($1.o), vOffset: " "off.sort { Table.compare(Table.offset(Int32($1.o), vOffset: "
"{{VOFFSET}}, fbb: &fbb), Table.offset(Int32($0.o), vOffset: " "{{VOFFSET}}, fbb: &fbb), Table.offset(Int32($0.o), vOffset: "
"{{VOFFSET}}, fbb: &fbb), fbb: &fbb) < 0 } "; "{{VOFFSET}}, fbb: &fbb), fbb: &fbb) < 0 } ";
@@ -780,8 +787,11 @@ class SwiftGenerator : public BaseGenerator {
"{{ACCESS}}.getVector(at: {{TABLEOFFSET}}.{{OFFSET}}.v) }"; "{{ACCESS}}.getVector(at: {{TABLEOFFSET}}.{{OFFSET}}.v) }";
break; break;
} }
case BASE_TYPE_ARRAY: FLATBUFFERS_FALLTHROUGH(); // fall thru case BASE_TYPE_ARRAY:
case BASE_TYPE_VECTOR: GenTableReaderVectorFields(field); break; FLATBUFFERS_FALLTHROUGH(); // fall thru
case BASE_TYPE_VECTOR:
GenTableReaderVectorFields(field);
break;
case BASE_TYPE_UNION: case BASE_TYPE_UNION:
code_.SetValue("CONSTANT", "nil"); code_.SetValue("CONSTANT", "nil");
code_ += code_ +=
@@ -791,7 +801,8 @@ class SwiftGenerator : public BaseGenerator {
is_required + " { " + GenOffset() + required_reader + is_required + " { " + GenOffset() + required_reader +
"{{ACCESS}}.union(o) }"; "{{ACCESS}}.union(o) }";
break; break;
default: FLATBUFFERS_ASSERT(0); default:
FLATBUFFERS_ASSERT(0);
} }
} }
@@ -943,7 +954,9 @@ class SwiftGenerator : public BaseGenerator {
const auto type = GenType(ev.union_type); const auto type = GenType(ev.union_type);
code_.SetValue("KEY", namer_.LegacySwiftVariant(ev)); code_.SetValue("KEY", namer_.LegacySwiftVariant(ev));
code_.SetValue("VALUETYPE", type); code_.SetValue("VALUETYPE", type);
if (ev.union_type.base_type == BASE_TYPE_NONE) { continue; } if (ev.union_type.base_type == BASE_TYPE_NONE) {
continue;
}
code_ += "case .{{KEY}}:"; code_ += "case .{{KEY}}:";
Indent(); Indent();
code_ += "let _v = {{FIELDVAR}}(at: index, type: {{VALUETYPE}}.self)"; code_ += "let _v = {{FIELDVAR}}(at: index, type: {{VALUETYPE}}.self)";
@@ -964,7 +977,9 @@ class SwiftGenerator : public BaseGenerator {
const auto type = GenType(ev.union_type); const auto type = GenType(ev.union_type);
code_.SetValue("KEY", namer_.LegacySwiftVariant(ev)); code_.SetValue("KEY", namer_.LegacySwiftVariant(ev));
code_.SetValue("VALUETYPE", type); code_.SetValue("VALUETYPE", type);
if (ev.union_type.base_type == BASE_TYPE_NONE) { continue; } if (ev.union_type.base_type == BASE_TYPE_NONE) {
continue;
}
code_ += "case .{{KEY}}:"; code_ += "case .{{KEY}}:";
Indent(); Indent();
code_ += "let _v = {{FIELDVAR}}(type: {{VALUETYPE}}.self)"; code_ += "let _v = {{FIELDVAR}}(type: {{VALUETYPE}}.self)";
@@ -1150,11 +1165,17 @@ class SwiftGenerator : public BaseGenerator {
std::string GenerateNestedVerifierTypes(const Type& type) { std::string GenerateNestedVerifierTypes(const Type& type) {
const auto string_type = GenType(type); const auto string_type = GenType(type);
if (IsScalar(type.base_type)) { return string_type; } if (IsScalar(type.base_type)) {
return string_type;
}
if (IsString(type)) { return "ForwardOffset<" + string_type + ">"; } if (IsString(type)) {
return "ForwardOffset<" + string_type + ">";
}
if (type.struct_def && type.struct_def->fixed) { return string_type; } if (type.struct_def && type.struct_def->fixed) {
return string_type;
}
return "ForwardOffset<" + string_type + ">"; return "ForwardOffset<" + string_type + ">";
} }
@@ -1353,7 +1374,8 @@ class SwiftGenerator : public BaseGenerator {
: "("; : "(";
std::string body = "add" + check_if_vector + field_method + ": "; std::string body = "add" + check_if_vector + field_method + ": ";
switch (field.value.type.base_type) { switch (field.value.type.base_type) {
case BASE_TYPE_ARRAY: FLATBUFFERS_FALLTHROUGH(); case BASE_TYPE_ARRAY:
FLATBUFFERS_FALLTHROUGH();
case BASE_TYPE_VECTOR: { case BASE_TYPE_VECTOR: {
GenerateVectorObjectAPITableExtension(field); GenerateVectorObjectAPITableExtension(field);
unpack_body.push_back("{{STRUCTNAME}}." + body + "__" + field_var + unpack_body.push_back("{{STRUCTNAME}}." + body + "__" + field_var +
@@ -1401,7 +1423,8 @@ class SwiftGenerator : public BaseGenerator {
} }
break; break;
} }
case BASE_TYPE_UTYPE: break; case BASE_TYPE_UTYPE:
break;
default: default:
unpack_body.push_back("{{STRUCTNAME}}." + body + "obj." + unpack_body.push_back("{{STRUCTNAME}}." + body + "obj." +
field_field + builder); field_field + builder);
@@ -1439,7 +1462,8 @@ class SwiftGenerator : public BaseGenerator {
".compactMap { $0?.type })"; ".compactMap { $0?.type })";
break; break;
} }
case BASE_TYPE_UTYPE: break; case BASE_TYPE_UTYPE:
break;
case BASE_TYPE_STRUCT: { case BASE_TYPE_STRUCT: {
if (field_type.struct_def && !field_type.struct_def->fixed) { if (field_type.struct_def && !field_type.struct_def->fixed) {
code_ += "var __" + var + "__: [Offset] = []"; code_ += "var __" + var + "__: [Offset] = []";
@@ -1540,7 +1564,8 @@ class SwiftGenerator : public BaseGenerator {
} }
break; break;
} }
case BASE_TYPE_ARRAY: FLATBUFFERS_FALLTHROUGH(); case BASE_TYPE_ARRAY:
FLATBUFFERS_FALLTHROUGH();
case BASE_TYPE_VECTOR: { case BASE_TYPE_VECTOR: {
BuildObjectAPIConstructorBodyVectors(field, buffer_constructor, BuildObjectAPIConstructorBodyVectors(field, buffer_constructor,
base_constructor, " "); base_constructor, " ");
@@ -1563,7 +1588,8 @@ class SwiftGenerator : public BaseGenerator {
} }
break; break;
} }
case BASE_TYPE_UTYPE: break; case BASE_TYPE_UTYPE:
break;
case BASE_TYPE_UNION: { case BASE_TYPE_UNION: {
BuildUnionEnumSwitchCase(*field.value.type.enum_def, field_var, BuildUnionEnumSwitchCase(*field.value.type.enum_def, field_var,
buffer_constructor); buffer_constructor);
@@ -1630,7 +1656,8 @@ class SwiftGenerator : public BaseGenerator {
} }
break; break;
} }
case BASE_TYPE_ARRAY: FLATBUFFERS_FALLTHROUGH(); case BASE_TYPE_ARRAY:
FLATBUFFERS_FALLTHROUGH();
case BASE_TYPE_VECTOR: { case BASE_TYPE_VECTOR: {
break; break;
} }
@@ -1639,7 +1666,8 @@ class SwiftGenerator : public BaseGenerator {
buffer_constructor, indentation, true); buffer_constructor, indentation, true);
break; break;
} }
case BASE_TYPE_UTYPE: break; case BASE_TYPE_UTYPE:
break;
default: { default: {
code_.SetValue( code_.SetValue(
"VALUETYPE", "VALUETYPE",
@@ -1670,7 +1698,9 @@ class SwiftGenerator : public BaseGenerator {
const auto variant = namer_.LegacySwiftVariant(ev); const auto variant = namer_.LegacySwiftVariant(ev);
const auto type = GenType(ev.union_type); const auto type = GenType(ev.union_type);
const auto is_struct = IsStruct(ev.union_type) ? type + Mutable() : type; const auto is_struct = IsStruct(ev.union_type) ? type + Mutable() : type;
if (ev.union_type.base_type == BASE_TYPE_NONE) { continue; } if (ev.union_type.base_type == BASE_TYPE_NONE) {
continue;
}
code_ += "case ." + variant + ":"; code_ += "case ." + variant + ":";
Indent(); Indent();
code_ += "var __obj = value as? " + GenType(ev.union_type, true); code_ += "var __obj = value as? " + GenType(ev.union_type, true);
@@ -1697,7 +1727,9 @@ class SwiftGenerator : public BaseGenerator {
for (auto it = ed.Vals().begin(); it < ed.Vals().end(); ++it) { for (auto it = ed.Vals().begin(); it < ed.Vals().end(); ++it) {
const auto ev = **it; const auto ev = **it;
const auto variant = namer_.LegacySwiftVariant(ev); const auto variant = namer_.LegacySwiftVariant(ev);
if (ev.union_type.base_type == BASE_TYPE_NONE) { continue; } if (ev.union_type.base_type == BASE_TYPE_NONE) {
continue;
}
const auto type = IsStruct(ev.union_type) const auto type = IsStruct(ev.union_type)
? GenType(ev.union_type) + Mutable() ? GenType(ev.union_type) + Mutable()
: GenType(ev.union_type); : GenType(ev.union_type);
@@ -1791,7 +1823,9 @@ class SwiftGenerator : public BaseGenerator {
// Don't output empty comment blocks with 0 lines of comment content. // Don't output empty comment blocks with 0 lines of comment content.
return; return;
} }
for (auto it = dc.begin(); it != dc.end(); ++it) { code_ += "/// " + *it; } for (auto it = dc.begin(); it != dc.end(); ++it) {
code_ += "/// " + *it;
}
} }
std::string GenOffset() { std::string GenOffset() {
@@ -1872,8 +1906,10 @@ class SwiftGenerator : public BaseGenerator {
std::string GenTypePointer(const Type& type, std::string GenTypePointer(const Type& type,
const bool should_consider_suffix) const { const bool should_consider_suffix) const {
switch (type.base_type) { switch (type.base_type) {
case BASE_TYPE_STRING: return "String"; case BASE_TYPE_STRING:
case BASE_TYPE_VECTOR: return GenType(type.VectorType()); return "String";
case BASE_TYPE_VECTOR:
return GenType(type.VectorType());
case BASE_TYPE_STRUCT: { case BASE_TYPE_STRUCT: {
const auto& sd = *type.struct_def; const auto& sd = *type.struct_def;
if (should_consider_suffix && !sd.fixed) { if (should_consider_suffix && !sd.fixed) {
@@ -1882,7 +1918,8 @@ class SwiftGenerator : public BaseGenerator {
return namer_.NamespacedType(sd); return namer_.NamespacedType(sd);
} }
case BASE_TYPE_UNION: case BASE_TYPE_UNION:
default: return "FlatbuffersInitializable"; default:
return "FlatbuffersInitializable";
} }
} }
@@ -1929,18 +1966,21 @@ class SwiftCodeGenerator : public CodeGenerator {
public: public:
Status GenerateCode(const Parser& parser, const std::string& path, Status GenerateCode(const Parser& parser, const std::string& path,
const std::string& filename) override { const std::string& filename) override {
if (!GenerateSwift(parser, path, filename)) { return Status::ERROR; } if (!GenerateSwift(parser, path, filename)) {
return Status::ERROR;
}
return Status::OK; return Status::OK;
} }
Status GenerateCode(const uint8_t *, int64_t, Status GenerateCode(const uint8_t*, int64_t, const CodeGenOptions&) override {
const CodeGenOptions &) override {
return Status::NOT_IMPLEMENTED; return Status::NOT_IMPLEMENTED;
} }
Status GenerateGrpcCode(const Parser& parser, const std::string& path, Status GenerateGrpcCode(const Parser& parser, const std::string& path,
const std::string& filename) override { const std::string& filename) override {
if (!GenerateSwiftGRPC(parser, path, filename)) { return Status::ERROR; } if (!GenerateSwiftGRPC(parser, path, filename)) {
return Status::ERROR;
}
return Status::OK; return Status::OK;
} }

View File

@@ -30,10 +30,12 @@ namespace flatbuffers {
struct PrintScalarTag {}; struct PrintScalarTag {};
struct PrintPointerTag {}; struct PrintPointerTag {};
template<typename T> struct PrintTag { template <typename T>
struct PrintTag {
typedef PrintScalarTag type; typedef PrintScalarTag type;
}; };
template<> struct PrintTag<const void *> { template <>
struct PrintTag<const void*> {
typedef PrintPointerTag type; typedef PrintPointerTag type;
}; };
@@ -240,11 +242,14 @@ struct JsonPrinter {
// clang-format on // clang-format on
return nullptr; return nullptr;
} }
default: FLATBUFFERS_ASSERT(0); return "unknown type"; default:
FLATBUFFERS_ASSERT(0);
return "unknown type";
} }
} }
template<typename T> static T GetFieldDefault(const FieldDef &fd) { template <typename T>
static T GetFieldDefault(const FieldDef& fd) {
T val{}; T val{};
auto check = StringToNumber(fd.value.constant.c_str(), &val); auto check = StringToNumber(fd.value.constant.c_str(), &val);
(void)check; (void)check;
@@ -320,7 +325,9 @@ struct JsonPrinter {
auto output_anyway = (opts.output_default_scalars_in_json || fd.key) && auto output_anyway = (opts.output_default_scalars_in_json || fd.key) &&
IsScalar(fd.value.type.base_type) && !fd.deprecated; IsScalar(fd.value.type.base_type) && !fd.deprecated;
if (is_present || output_anyway) { if (is_present || output_anyway) {
if (fieldout++) { AddComma(); } if (fieldout++) {
AddComma();
}
AddNewLine(); AddNewLine();
AddIndent(elem_indent); AddIndent(elem_indent);
OutputIdentifier(fd.name); OutputIdentifier(fd.name);
@@ -386,16 +393,18 @@ static const char *GenerateTextImpl(const Parser &parser, const Table *table,
// Generate a text representation of a flatbuffer in JSON format. // Generate a text representation of a flatbuffer in JSON format.
// Deprecated: please use `GenTextFromTable` // Deprecated: please use `GenTextFromTable`
bool GenerateTextFromTable(const Parser& parser, const void* table, bool GenerateTextFromTable(const Parser& parser, const void* table,
const std::string &table_name, const std::string& table_name, std::string* _text) {
std::string *_text) {
return GenTextFromTable(parser, table, table_name, _text) != nullptr; return GenTextFromTable(parser, table, table_name, _text) != nullptr;
} }
// Generate a text representation of a flatbuffer in JSON format. // Generate a text representation of a flatbuffer in JSON format.
const char* GenTextFromTable(const Parser& parser, const void* table, const char* GenTextFromTable(const Parser& parser, const void* table,
const std::string &table_name, std::string *_text) { const std::string& table_name,
std::string* _text) {
auto struct_def = parser.LookupStruct(table_name); auto struct_def = parser.LookupStruct(table_name);
if (struct_def == nullptr) { return "unknown struct"; } if (struct_def == nullptr) {
return "unknown struct";
}
auto root = static_cast<const Table*>(table); auto root = static_cast<const Table*>(table);
return GenerateTextImpl(parser, root, *struct_def, _text); return GenerateTextImpl(parser, root, *struct_def, _text);
} }
@@ -476,8 +485,7 @@ class TextCodeGenerator : public CodeGenerator {
// Generate code from the provided `buffer` of given `length`. The buffer is a // Generate code from the provided `buffer` of given `length`. The buffer is a
// serialized reflection.fbs. // serialized reflection.fbs.
Status GenerateCode(const uint8_t *, int64_t, Status GenerateCode(const uint8_t*, int64_t, const CodeGenOptions&) override {
const CodeGenOptions &) override {
return Status::NOT_IMPLEMENTED; return Status::NOT_IMPLEMENTED;
} }

View File

@@ -91,9 +91,11 @@ std::set<std::string> TypescriptKeywords() {
enum AnnotationType { kParam = 0, kType = 1, kReturns = 2 }; enum AnnotationType { kParam = 0, kType = 1, kReturns = 2 };
template<typename T> struct SupportsObjectAPI : std::false_type {}; template <typename T>
struct SupportsObjectAPI : std::false_type {};
template<> struct SupportsObjectAPI<StructDef> : std::true_type {}; template <>
struct SupportsObjectAPI<StructDef> : std::true_type {};
} // namespace } // namespace
@@ -113,14 +115,18 @@ class TsGenerator : public BaseGenerator {
bool generate() { bool generate() {
generateEnums(); generateEnums();
generateStructs(); generateStructs();
if (!parser_.opts.ts_omit_entrypoint) { generateEntry(); } if (!parser_.opts.ts_omit_entrypoint) {
generateEntry();
}
if (!generateBundle()) return false; if (!generateBundle()) return false;
return true; return true;
} }
std::string GetTypeName(const EnumDef& def, const bool = false, std::string GetTypeName(const EnumDef& def, const bool = false,
const bool force_ns_wrap = false) { const bool force_ns_wrap = false) {
if (force_ns_wrap) { return namer_.NamespacedType(def); } if (force_ns_wrap) {
return namer_.NamespacedType(def);
}
return namer_.Type(def); return namer_.Type(def);
} }
@@ -150,7 +156,9 @@ class TsGenerator : public BaseGenerator {
std::string code; 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"; "/* 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++) { for (auto it = bare_imports.begin(); it != bare_imports.end(); it++) {
code += it->second.import_statement + "\n"; code += it->second.import_statement + "\n";
@@ -256,7 +264,9 @@ class TsGenerator : public BaseGenerator {
for (const auto& it : ns_defs_) { 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"; "/* 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 // export all definitions in ns entry point module
int export_counter = 0; int export_counter = 0;
@@ -303,7 +313,9 @@ class TsGenerator : public BaseGenerator {
std::copy(it2.second.ns->components.end() - count, std::copy(it2.second.ns->components.end() - count,
it2.second.ns->components.end(), it2.second.ns->components.end(),
std::back_inserter(rel_path)); std::back_inserter(rel_path));
code += namer_.Directories(rel_path, SkipDir::OutputPathAndTrailingPathSeparator) + ".js';\n"; code += namer_.Directories(
rel_path, SkipDir::OutputPathAndTrailingPathSeparator) +
".js';\n";
export_counter++; export_counter++;
} }
@@ -371,7 +383,9 @@ class TsGenerator : public BaseGenerator {
for (auto it = enum_def.Vals().begin(); it != enum_def.Vals().end(); ++it) { for (auto it = enum_def.Vals().begin(); it != enum_def.Vals().end(); ++it) {
auto& ev = **it; auto& ev = **it;
if (!ev.doc_comment.empty()) { if (!ev.doc_comment.empty()) {
if (it != enum_def.Vals().begin()) { code += '\n'; } if (it != enum_def.Vals().begin()) {
code += '\n';
}
GenDocComment(ev.doc_comment, code_ptr, " "); GenDocComment(ev.doc_comment, code_ptr, " ");
} }
@@ -391,7 +405,8 @@ class TsGenerator : public BaseGenerator {
code += "'" + enum_def.ToString(ev) + "'"; code += "'" + enum_def.ToString(ev) + "'";
break; break;
} }
default: code += enum_def.ToString(ev); default:
code += enum_def.ToString(ev);
} }
} }
@@ -409,37 +424,57 @@ class TsGenerator : public BaseGenerator {
static std::string GenType(const Type& type) { static std::string GenType(const Type& type) {
switch (type.base_type) { switch (type.base_type) {
case BASE_TYPE_BOOL: case BASE_TYPE_BOOL:
case BASE_TYPE_CHAR: return "Int8"; case BASE_TYPE_CHAR:
case BASE_TYPE_UTYPE: return GenType(GetUnionUnderlyingType(type)); return "Int8";
case BASE_TYPE_UCHAR: return "Uint8"; case BASE_TYPE_UTYPE:
case BASE_TYPE_SHORT: return "Int16"; return GenType(GetUnionUnderlyingType(type));
case BASE_TYPE_USHORT: return "Uint16"; case BASE_TYPE_UCHAR:
case BASE_TYPE_INT: return "Int32"; return "Uint8";
case BASE_TYPE_UINT: return "Uint32"; case BASE_TYPE_SHORT:
case BASE_TYPE_LONG: return "Int64"; return "Int16";
case BASE_TYPE_ULONG: return "Uint64"; case BASE_TYPE_USHORT:
case BASE_TYPE_FLOAT: return "Float32"; return "Uint16";
case BASE_TYPE_DOUBLE: return "Float64"; case BASE_TYPE_INT:
case BASE_TYPE_STRING: return "String"; return "Int32";
case BASE_TYPE_VECTOR: return GenType(type.VectorType()); case BASE_TYPE_UINT:
case BASE_TYPE_STRUCT: return type.struct_def->name; return "Uint32";
default: return "flatbuffers.Table"; case BASE_TYPE_LONG:
return "Int64";
case BASE_TYPE_ULONG:
return "Uint64";
case BASE_TYPE_FLOAT:
return "Float32";
case BASE_TYPE_DOUBLE:
return "Float64";
case BASE_TYPE_STRING:
return "String";
case BASE_TYPE_VECTOR:
return GenType(type.VectorType());
case BASE_TYPE_STRUCT:
return type.struct_def->name;
default:
return "flatbuffers.Table";
} }
} }
std::string GenGetter(const Type& type, const std::string& arguments) { std::string GenGetter(const Type& type, const std::string& arguments) {
switch (type.base_type) { switch (type.base_type) {
case BASE_TYPE_STRING: return GenBBAccess() + ".__string" + arguments; case BASE_TYPE_STRING:
case BASE_TYPE_STRUCT: return GenBBAccess() + ".__struct" + arguments; return GenBBAccess() + ".__string" + arguments;
case BASE_TYPE_STRUCT:
return GenBBAccess() + ".__struct" + arguments;
case BASE_TYPE_UNION: case BASE_TYPE_UNION:
if (!UnionHasStringType(*type.enum_def)) { if (!UnionHasStringType(*type.enum_def)) {
return GenBBAccess() + ".__union" + arguments; return GenBBAccess() + ".__union" + arguments;
} }
return GenBBAccess() + ".__union_with_string" + arguments; return GenBBAccess() + ".__union_with_string" + arguments;
case BASE_TYPE_VECTOR: return GenGetter(type.VectorType(), arguments); case BASE_TYPE_VECTOR:
return GenGetter(type.VectorType(), arguments);
default: { default: {
auto getter = GenBBAccess() + "." + "read" + GenType(type) + arguments; auto getter = GenBBAccess() + "." + "read" + GenType(type) + arguments;
if (type.base_type == BASE_TYPE_BOOL) { getter = "!!" + getter; } if (type.base_type == BASE_TYPE_BOOL) {
getter = "!!" + getter;
}
return getter; return getter;
} }
} }
@@ -448,7 +483,9 @@ class TsGenerator : public BaseGenerator {
std::string GenBBAccess() const { return "this.bb!"; } std::string GenBBAccess() const { return "this.bb!"; }
std::string GenDefaultValue(const FieldDef& field, import_set& imports) { std::string GenDefaultValue(const FieldDef& field, import_set& imports) {
if (field.IsScalarOptional()) { return "null"; } if (field.IsScalarOptional()) {
return "null";
}
const auto& value = field.value; const auto& value = field.value;
if (value.type.enum_def && value.type.base_type != BASE_TYPE_UNION && if (value.type.enum_def && value.type.base_type != BASE_TYPE_UNION &&
@@ -487,7 +524,8 @@ class TsGenerator : public BaseGenerator {
} }
switch (value.type.base_type) { switch (value.type.base_type) {
case BASE_TYPE_BOOL: return value.constant == "0" ? "false" : "true"; case BASE_TYPE_BOOL:
return value.constant == "0" ? "false" : "true";
case BASE_TYPE_STRING: case BASE_TYPE_STRING:
case BASE_TYPE_UNION: case BASE_TYPE_UNION:
@@ -496,7 +534,8 @@ class TsGenerator : public BaseGenerator {
} }
case BASE_TYPE_ARRAY: case BASE_TYPE_ARRAY:
case BASE_TYPE_VECTOR: return "[]"; case BASE_TYPE_VECTOR:
return "[]";
case BASE_TYPE_LONG: case BASE_TYPE_LONG:
case BASE_TYPE_ULONG: { case BASE_TYPE_ULONG: {
@@ -532,9 +571,11 @@ class TsGenerator : public BaseGenerator {
} }
switch (type.base_type) { switch (type.base_type) {
case BASE_TYPE_BOOL: return allowNull ? "boolean|null" : "boolean"; case BASE_TYPE_BOOL:
return allowNull ? "boolean|null" : "boolean";
case BASE_TYPE_LONG: case BASE_TYPE_LONG:
case BASE_TYPE_ULONG: return allowNull ? "bigint|null" : "bigint"; case BASE_TYPE_ULONG:
return allowNull ? "bigint|null" : "bigint";
case BASE_TYPE_ARRAY: { case BASE_TYPE_ARRAY: {
std::string name; std::string name;
if (type.element == BASE_TYPE_LONG || type.element == BASE_TYPE_ULONG) { if (type.element == BASE_TYPE_LONG || type.element == BASE_TYPE_ULONG) {
@@ -564,8 +605,7 @@ class TsGenerator : public BaseGenerator {
} }
} }
static Type GetUnionUnderlyingType(const Type &type) static Type GetUnionUnderlyingType(const Type& type) {
{
if (type.enum_def != nullptr && if (type.enum_def != nullptr &&
type.enum_def->underlying_type.base_type != type.base_type) { type.enum_def->underlying_type.base_type != type.base_type) {
return type.enum_def->underlying_type; return type.enum_def->underlying_type;
@@ -574,32 +614,41 @@ class TsGenerator : public BaseGenerator {
} }
} }
static Type GetUnderlyingVectorType(const Type &vector_type) static Type GetUnderlyingVectorType(const Type& vector_type) {
{ return (vector_type.base_type == BASE_TYPE_UTYPE)
return (vector_type.base_type == BASE_TYPE_UTYPE) ? GetUnionUnderlyingType(vector_type) : vector_type; ? GetUnionUnderlyingType(vector_type)
: vector_type;
} }
// Returns the method name for use with add/put calls. // Returns the method name for use with add/put calls.
std::string GenWriteMethod(const Type& type) { std::string GenWriteMethod(const Type& type) {
// Forward to signed versions since unsigned versions don't exist // Forward to signed versions since unsigned versions don't exist
switch (type.base_type) { switch (type.base_type) {
case BASE_TYPE_UTYPE: return GenWriteMethod(GetUnionUnderlyingType(type)); case BASE_TYPE_UTYPE:
case BASE_TYPE_UCHAR: return GenWriteMethod(Type(BASE_TYPE_CHAR)); return GenWriteMethod(GetUnionUnderlyingType(type));
case BASE_TYPE_USHORT: return GenWriteMethod(Type(BASE_TYPE_SHORT)); case BASE_TYPE_UCHAR:
case BASE_TYPE_UINT: return GenWriteMethod(Type(BASE_TYPE_INT)); return GenWriteMethod(Type(BASE_TYPE_CHAR));
case BASE_TYPE_ULONG: return GenWriteMethod(Type(BASE_TYPE_LONG)); case BASE_TYPE_USHORT:
default: break; return GenWriteMethod(Type(BASE_TYPE_SHORT));
case BASE_TYPE_UINT:
return GenWriteMethod(Type(BASE_TYPE_INT));
case BASE_TYPE_ULONG:
return GenWriteMethod(Type(BASE_TYPE_LONG));
default:
break;
} }
return IsScalar(type.base_type) ? namer_.Type(GenType(type)) return IsScalar(type.base_type) ? namer_.Type(GenType(type))
: (IsStruct(type) ? "Struct" : "Offset"); : (IsStruct(type) ? "Struct" : "Offset");
} }
template<typename T> static std::string MaybeAdd(T value) { template <typename T>
static std::string MaybeAdd(T value) {
return value != 0 ? " + " + NumToString(value) : ""; return value != 0 ? " + " + NumToString(value) : "";
} }
template<typename T> static std::string MaybeScale(T value) { template <typename T>
static std::string MaybeScale(T value) {
return value != 1 ? " * " + NumToString(value) : ""; return value != 1 ? " * " + NumToString(value) : "";
} }
@@ -766,7 +815,9 @@ class TsGenerator : public BaseGenerator {
code += ", '" + parser_.file_identifier_ + "'"; code += ", '" + parser_.file_identifier_ + "'";
} }
if (size_prefixed) { if (size_prefixed) {
if (parser_.file_identifier_.empty()) { code += ", undefined"; } if (parser_.file_identifier_.empty()) {
code += ", undefined";
}
code += ", true"; code += ", true";
} }
code += ");\n"; code += ");\n";
@@ -796,7 +847,9 @@ class TsGenerator : public BaseGenerator {
for (auto it = union_enum.Vals().begin(); it != union_enum.Vals().end(); for (auto it = union_enum.Vals().begin(); it != union_enum.Vals().end();
++it) { ++it) {
const auto& ev = **it; const auto& ev = **it;
if (ev.IsZero()) { continue; } if (ev.IsZero()) {
continue;
}
std::string type = ""; std::string type = "";
if (IsString(ev.union_type)) { if (IsString(ev.union_type)) {
@@ -820,7 +873,9 @@ class TsGenerator : public BaseGenerator {
const std::string& name) { const std::string& name) {
// TODO: this would be better as a hashset. // TODO: this would be better as a hashset.
for (auto it = imports.begin(); it != imports.end(); it++) { for (auto it = imports.begin(); it != imports.end(); it++) {
if (it->second.name == name) { return true; } if (it->second.name == name) {
return true;
}
} }
return false; return false;
} }
@@ -856,8 +911,7 @@ class TsGenerator : public BaseGenerator {
std::string GenSymbolExpression(const EnumDef& enum_def, std::string GenSymbolExpression(const EnumDef& enum_def,
const bool has_name_clash, const bool has_name_clash,
const std::string& import_name, const std::string& import_name,
const std::string &name, const std::string& name, const std::string&) {
const std::string &) {
std::string symbols_expression; std::string symbols_expression;
if (has_name_clash) { if (has_name_clash) {
symbols_expression += import_name + " as " + name; symbols_expression += import_name + " as " + name;
@@ -882,7 +936,9 @@ class TsGenerator : public BaseGenerator {
// Look if we have already added this import and return its name if found. // Look if we have already added this import and return its name if found.
const auto import_pair = imports.find(unique_name); const auto import_pair = imports.find(unique_name);
if (import_pair != imports.end()) { return import_pair->second; } if (import_pair != imports.end()) {
return import_pair->second;
}
// Check if this name would have a name clash with another type. Just use // Check if this name would have a name clash with another type. Just use
// the "base" name (properly escaped) without any namespacing applied. // the "base" name (properly escaped) without any namespacing applied.
@@ -905,7 +961,9 @@ class TsGenerator : public BaseGenerator {
for (size_t i = 0; i < dep_comps.size(); i++) { for (size_t i = 0; i < dep_comps.size(); i++) {
rel_file_path += i == 0 ? ".." : (kPathSeparator + std::string("..")); rel_file_path += i == 0 ? ".." : (kPathSeparator + std::string(".."));
} }
if (dep_comps.size() == 0) { rel_file_path += "."; } if (dep_comps.size() == 0) {
rel_file_path += ".";
}
} else { } else {
rel_file_path += ".."; rel_file_path += "..";
} }
@@ -955,7 +1013,9 @@ class TsGenerator : public BaseGenerator {
for (auto it = union_enum.Vals().begin(); it != union_enum.Vals().end(); for (auto it = union_enum.Vals().begin(); it != union_enum.Vals().end();
++it) { ++it) {
const auto& ev = **it; const auto& ev = **it;
if (ev.IsZero()) { continue; } if (ev.IsZero()) {
continue;
}
std::string type = ""; std::string type = "";
if (IsString(ev.union_type)) { if (IsString(ev.union_type)) {
@@ -1008,7 +1068,9 @@ class TsGenerator : public BaseGenerator {
for (auto it = enum_def.Vals().begin(); it != enum_def.Vals().end(); for (auto it = enum_def.Vals().begin(); it != enum_def.Vals().end();
++it) { ++it) {
const auto& ev = **it; const auto& ev = **it;
if (ev.IsZero()) { continue; } if (ev.IsZero()) {
continue;
}
ret += " case '" + namer_.Variant(ev) + "': "; ret += " case '" + namer_.Variant(ev) + "': ";
@@ -1152,7 +1214,9 @@ class TsGenerator : public BaseGenerator {
} }
} }
if (std::next(it) != struct_def.fields.vec.end()) { ret += delimiter; } if (std::next(it) != struct_def.fields.vec.end()) {
ret += delimiter;
}
} }
return ret; return ret;
@@ -1452,7 +1516,9 @@ class TsGenerator : public BaseGenerator {
break; break;
} }
default: FLATBUFFERS_ASSERT(0); break; default:
FLATBUFFERS_ASSERT(0);
break;
} }
// length 0 vector is simply empty instead of null // length 0 vector is simply empty instead of null
@@ -1463,7 +1529,9 @@ class TsGenerator : public BaseGenerator {
field_offset_decl = field_offset_decl =
" const " + field_field + " = " + field_offset_decl + ";"; " const " + field_field + " = " + field_offset_decl + ";";
} }
if (field_offset_val.empty()) { field_offset_val = field_field; } if (field_offset_val.empty()) {
field_offset_val = field_field;
}
unpack_func += " " + field_val; unpack_func += " " + field_val;
unpack_to_func += " _o." + field_field + " = " + field_val + ";"; unpack_to_func += " _o." + field_field + " = " + field_val + ";";
@@ -1540,7 +1608,8 @@ class TsGenerator : public BaseGenerator {
// to preserve backwards compatibility, we allow the first field to be a // to preserve backwards compatibility, we allow the first field to be a
// struct // struct
return struct_def.fields.vec.size() < 2 || return struct_def.fields.vec.size() < 2 ||
std::all_of(std::begin(struct_def.fields.vec) + 1, std::all_of(
std::begin(struct_def.fields.vec) + 1,
std::end(struct_def.fields.vec), std::end(struct_def.fields.vec),
[](const FieldDef* f) -> bool { [](const FieldDef* f) -> bool {
FLATBUFFERS_ASSERT(f != nullptr); FLATBUFFERS_ASSERT(f != nullptr);
@@ -1653,7 +1722,9 @@ class TsGenerator : public BaseGenerator {
";\n"; ";\n";
} else { } else {
std::string index = "this.bb_pos + offset"; std::string index = "this.bb_pos + offset";
if (is_string) { index += ", optionalEncoding"; } if (is_string) {
index += ", optionalEncoding";
}
code += code +=
offset_prefix + GenGetter(field.value.type, "(" + index + ")"); offset_prefix + GenGetter(field.value.type, "(" + index + ")");
if (field.value.type.base_type != BASE_TYPE_ARRAY) { if (field.value.type.base_type != BASE_TYPE_ARRAY) {
@@ -1701,19 +1772,26 @@ class TsGenerator : public BaseGenerator {
std::string ret_type; std::string ret_type;
bool is_union = false; bool is_union = false;
switch (vectortype.base_type) { switch (vectortype.base_type) {
case BASE_TYPE_STRUCT: ret_type = vectortypename; break; case BASE_TYPE_STRUCT:
case BASE_TYPE_STRING: ret_type = vectortypename; break; ret_type = vectortypename;
break;
case BASE_TYPE_STRING:
ret_type = vectortypename;
break;
case BASE_TYPE_UNION: case BASE_TYPE_UNION:
ret_type = "?flatbuffers.Table"; ret_type = "?flatbuffers.Table";
is_union = true; is_union = true;
break; break;
default: ret_type = vectortypename; default:
ret_type = vectortypename;
} }
GenDocComment(field.doc_comment, code_ptr); GenDocComment(field.doc_comment, code_ptr);
std::string prefix = namer_.Method(field); std::string prefix = namer_.Method(field);
// TODO: make it work without any // TODO: make it work without any
// if (is_union) { prefix += "<T extends flatbuffers.Table>"; } // if (is_union) { prefix += "<T extends flatbuffers.Table>"; }
if (is_union) { prefix += ""; } if (is_union) {
prefix += "";
}
prefix += "(index: number"; prefix += "(index: number";
if (is_union) { if (is_union) {
const auto union_type = const auto union_type =
@@ -1792,19 +1870,26 @@ class TsGenerator : public BaseGenerator {
std::string ret_type; std::string ret_type;
bool is_union = false; bool is_union = false;
switch (vectortype.base_type) { switch (vectortype.base_type) {
case BASE_TYPE_STRUCT: ret_type = vectortypename; break; case BASE_TYPE_STRUCT:
case BASE_TYPE_STRING: ret_type = vectortypename; break; ret_type = vectortypename;
break;
case BASE_TYPE_STRING:
ret_type = vectortypename;
break;
case BASE_TYPE_UNION: case BASE_TYPE_UNION:
ret_type = "?flatbuffers.Table"; ret_type = "?flatbuffers.Table";
is_union = true; is_union = true;
break; break;
default: ret_type = vectortypename; default:
ret_type = vectortypename;
} }
GenDocComment(field.doc_comment, code_ptr); GenDocComment(field.doc_comment, code_ptr);
std::string prefix = namer_.Method(field); std::string prefix = namer_.Method(field);
// TODO: make it work without any // TODO: make it work without any
// if (is_union) { prefix += "<T extends flatbuffers.Table>"; } // if (is_union) { prefix += "<T extends flatbuffers.Table>"; }
if (is_union) { prefix += ""; } if (is_union) {
prefix += "";
}
prefix += "(index: number"; prefix += "(index: number";
if (is_union) { if (is_union) {
const auto union_type = const auto union_type =
@@ -1875,7 +1960,8 @@ class TsGenerator : public BaseGenerator {
" : null;\n"; " : null;\n";
break; break;
} }
default: FLATBUFFERS_ASSERT(0); default:
FLATBUFFERS_ASSERT(0);
} }
} }
code += "}\n\n"; code += "}\n\n";
@@ -1908,7 +1994,9 @@ class TsGenerator : public BaseGenerator {
} }
// special case for bools, which are treated as uint8 // special case for bools, which are treated as uint8
if (field.value.type.base_type == BASE_TYPE_BOOL) { code += "+"; } if (field.value.type.base_type == BASE_TYPE_BOOL) {
code += "+";
}
code += "value);\n"; code += "value);\n";
code += " return true;\n"; code += " return true;\n";
@@ -1945,16 +2033,14 @@ class TsGenerator : public BaseGenerator {
// Emit the fully qualified name // Emit the fully qualified name
if (parser_.opts.generate_name_strings) { if (parser_.opts.generate_name_strings) {
const std::string fullyQualifiedName = struct_def.defined_namespace->GetFullyQualifiedName(struct_def.name); const std::string fullyQualifiedName =
struct_def.defined_namespace->GetFullyQualifiedName(struct_def.name);
GenDocComment(code_ptr); GenDocComment(code_ptr);
code += "static getFullyQualifiedName(): \""; code += "static getFullyQualifiedName(): \"";
code += fullyQualifiedName; code += fullyQualifiedName;
code += "\" {\n"; code += "\" {\n";
code += code += " return '" + fullyQualifiedName + "';\n";
" return '" +
fullyQualifiedName +
"';\n";
code += "}\n\n"; code += "}\n\n";
} }
@@ -2003,14 +2089,18 @@ class TsGenerator : public BaseGenerator {
GetArgType(imports, struct_def, field, false) + ") {\n"; GetArgType(imports, struct_def, field, false) + ") {\n";
code += " builder.addField" + GenWriteMethod(field.value.type) + "("; code += " builder.addField" + GenWriteMethod(field.value.type) + "(";
code += NumToString(it - struct_def.fields.vec.begin()) + ", "; code += NumToString(it - struct_def.fields.vec.begin()) + ", ";
if (field.value.type.base_type == BASE_TYPE_BOOL) { code += "+"; } if (field.value.type.base_type == BASE_TYPE_BOOL) {
code += "+";
}
code += argname + ", "; code += argname + ", ";
if (!IsScalar(field.value.type.base_type)) { if (!IsScalar(field.value.type.base_type)) {
code += "0"; code += "0";
} else if (HasNullDefault(field)) { } else if (HasNullDefault(field)) {
code += "null"; code += "null";
} else { } else {
if (field.value.type.base_type == BASE_TYPE_BOOL) { code += "+"; } if (field.value.type.base_type == BASE_TYPE_BOOL) {
code += "+";
}
code += GenDefaultValue(field, imports); code += GenDefaultValue(field, imports);
} }
code += ");\n}\n\n"; code += ");\n}\n\n";
@@ -2053,7 +2143,9 @@ class TsGenerator : public BaseGenerator {
code += ", data.length, " + NumToString(alignment) + ");\n"; code += ", data.length, " + NumToString(alignment) + ");\n";
code += " for (let i = data.length - 1; i >= 0; i--) {\n"; code += " for (let i = data.length - 1; i >= 0; i--) {\n";
code += " builder.add" + GenWriteMethod(vector_type) + "("; code += " builder.add" + GenWriteMethod(vector_type) + "(";
if (vector_type.base_type == BASE_TYPE_BOOL) { code += "+"; } if (vector_type.base_type == BASE_TYPE_BOOL) {
code += "+";
}
code += "data[i]!);\n"; code += "data[i]!);\n";
code += " }\n"; code += " }\n";
code += " return builder.endVector();\n"; code += " return builder.endVector();\n";
@@ -2173,7 +2265,9 @@ class TsGenerator : public BaseGenerator {
std::string GetArgName(const FieldDef& field) { std::string GetArgName(const FieldDef& field) {
auto argname = namer_.Variable(field); auto argname = namer_.Variable(field);
if (!IsScalar(field.value.type.base_type)) { argname += "Offset"; } if (!IsScalar(field.value.type.base_type)) {
argname += "Offset";
}
return argname; return argname;
} }
@@ -2211,12 +2305,13 @@ class TsCodeGenerator : public CodeGenerator {
public: public:
Status GenerateCode(const Parser& parser, const std::string& path, Status GenerateCode(const Parser& parser, const std::string& path,
const std::string& filename) override { const std::string& filename) override {
if (!GenerateTS(parser, path, filename)) { return Status::ERROR; } if (!GenerateTS(parser, path, filename)) {
return Status::ERROR;
}
return Status::OK; return Status::OK;
} }
Status GenerateCode(const uint8_t *, int64_t, Status GenerateCode(const uint8_t*, int64_t, const CodeGenOptions&) override {
const CodeGenOptions &) override {
return Status::NOT_IMPLEMENTED; return Status::NOT_IMPLEMENTED;
} }
@@ -2229,7 +2324,9 @@ class TsCodeGenerator : public CodeGenerator {
Status GenerateGrpcCode(const Parser& parser, const std::string& path, Status GenerateGrpcCode(const Parser& parser, const std::string& path,
const std::string& filename) override { const std::string& filename) override {
if (!GenerateTSGRPC(parser, path, filename)) { return Status::ERROR; } if (!GenerateTSGRPC(parser, path, filename)) {
return Status::ERROR;
}
return Status::OK; return Status::OK;
} }

View File

@@ -67,7 +67,9 @@ static bool ValidateUTF8(const std::string &str) {
const char* s = &str[0]; const char* s = &str[0];
const char* const sEnd = s + str.length(); const char* const sEnd = s + str.length();
while (s < sEnd) { while (s < sEnd) {
if (FromUTF8(&s) < 0) { return false; } if (FromUTF8(&s) < 0) {
return false;
}
} }
return true; return true;
} }
@@ -91,7 +93,8 @@ static void DeserializeDoc(std::vector<std::string> &doc,
static CheckedError NoError() { return CheckedError(false); } static CheckedError NoError() { return CheckedError(false); }
template<typename T> static std::string TypeToIntervalString() { template <typename T>
static std::string TypeToIntervalString() {
return "[" + NumToString((flatbuffers::numeric_limits<T>::lowest)()) + "; " + return "[" + NumToString((flatbuffers::numeric_limits<T>::lowest)()) + "; " +
NumToString((flatbuffers::numeric_limits<T>::max)()) + "]"; NumToString((flatbuffers::numeric_limits<T>::max)()) + "]";
} }
@@ -207,7 +210,9 @@ static bool CompareSerializedScalars(const uint8_t *a, const uint8_t *b,
#define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE, ...) \ #define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE, ...) \
case BASE_TYPE_##ENUM: { \ case BASE_TYPE_##ENUM: { \
CTYPE def = static_cast<CTYPE>(0); \ CTYPE def = static_cast<CTYPE>(0); \
if (!a || !b) { StringToNumber(key.value.constant.c_str(), &def); } \ if (!a || !b) { \
StringToNumber(key.value.constant.c_str(), &def); \
} \
const auto av = a ? ReadScalar<CTYPE>(a) : def; \ const auto av = a ? ReadScalar<CTYPE>(a) : def; \
const auto bv = b ? ReadScalar<CTYPE>(b) : def; \ const auto bv = b ? ReadScalar<CTYPE>(b) : def; \
return av < bv; \ return av < bv; \
@@ -287,9 +292,12 @@ static void SimpleQsort(T *begin, T *end, size_t width, F comparator,
SimpleQsort(r, end, width, comparator, swapper); SimpleQsort(r, end, width, comparator, swapper);
} }
template<typename T> static inline void SingleValueRepack(Value &e, T val) { template <typename T>
static inline void SingleValueRepack(Value& e, T val) {
// Remove leading zeros. // Remove leading zeros.
if (IsInteger(e.type.base_type)) { e.constant = NumToString(val); } if (IsInteger(e.type.base_type)) {
e.constant = NumToString(val);
}
} }
#if defined(FLATBUFFERS_HAS_NEW_STRTOD) && (FLATBUFFERS_HAS_NEW_STRTOD > 0) #if defined(FLATBUFFERS_HAS_NEW_STRTOD) && (FLATBUFFERS_HAS_NEW_STRTOD > 0)
@@ -303,8 +311,11 @@ static void SingleValueRepack(Value &e, double val) {
} }
#endif #endif
template<typename T> static uint64_t EnumDistanceImpl(T e1, T e2) { template <typename T>
if (e1 < e2) { std::swap(e1, e2); } // use std for scalars static uint64_t EnumDistanceImpl(T e1, T e2) {
if (e1 < e2) {
std::swap(e1, e2);
} // use std for scalars
// Signed overflow may occur, use unsigned calculation. // Signed overflow may occur, use unsigned calculation.
// The unsigned overflow is well-defined by C++ standard (modulo 2^n). // The unsigned overflow is well-defined by C++ standard (modulo 2^n).
return static_cast<uint64_t>(e1) - static_cast<uint64_t>(e2); return static_cast<uint64_t>(e1) - static_cast<uint64_t>(e2);
@@ -333,7 +344,9 @@ static Namespace *GetNamespace(
for (;;) { for (;;) {
dot = qualified_name.find('.', pos); dot = qualified_name.find('.', pos);
if (dot == std::string::npos) { break; } if (dot == std::string::npos) {
break;
}
ns->components.push_back(qualified_name.substr(pos, dot - pos)); ns->components.push_back(qualified_name.substr(pos, dot - pos));
pos = dot + 1; pos = dot + 1;
} }
@@ -354,12 +367,14 @@ static uint64_t HashFile(const char *source_filename, const char *source) {
return hash; return hash;
} }
template<typename T> static bool compareName(const T *a, const T *b) { template <typename T>
static bool compareName(const T* a, const T* b) {
return a->defined_namespace->GetFullyQualifiedName(a->name) < return a->defined_namespace->GetFullyQualifiedName(a->name) <
b->defined_namespace->GetFullyQualifiedName(b->name); b->defined_namespace->GetFullyQualifiedName(b->name);
} }
template<typename T> static void AssignIndices(const std::vector<T *> &defvec) { template <typename T>
static void AssignIndices(const std::vector<T*>& defvec) {
// Pre-sort these vectors, such that we can set the correct indices for them. // Pre-sort these vectors, such that we can set the correct indices for them.
auto vec = defvec; auto vec = defvec;
std::sort(vec.begin(), vec.end(), compareName<T>); std::sort(vec.begin(), vec.end(), compareName<T>);
@@ -433,7 +448,9 @@ class Parser::ParseDepthGuard {
std::string Namespace::GetFullyQualifiedName(const std::string& name, std::string Namespace::GetFullyQualifiedName(const std::string& name,
size_t max_components) const { size_t max_components) const {
// Early exit if we don't have a defined namespace. // Early exit if we don't have a defined namespace.
if (components.empty() || !max_components) { return name; } if (components.empty() || !max_components) {
return name;
}
std::string stream_str; std::string stream_str;
for (size_t i = 0; i < std::min(components.size(), max_components); i++) { for (size_t i = 0; i < std::min(components.size(), max_components); i++) {
stream_str += components[i]; stream_str += components[i];
@@ -492,7 +509,8 @@ CheckedError Parser::Next() {
return NoError(); return NoError();
case ' ': case ' ':
case '\r': case '\r':
case '\t': break; case '\t':
break;
case '\n': case '\n':
MarkNewLine(); MarkNewLine();
seen_newline = true; seen_newline = true;
@@ -508,7 +526,8 @@ CheckedError Parser::Next() {
case ',': case ',':
case ':': case ':':
case ';': case ';':
case '=': return NoError(); case '=':
return NoError();
case '\"': case '\"':
case '\'': { case '\'': {
int unicode_high_surrogate = -1; int unicode_high_surrogate = -1;
@@ -598,7 +617,8 @@ CheckedError Parser::Next() {
} }
break; break;
} }
default: return Error("unknown escape code in string constant"); default:
return Error("unknown escape code in string constant");
} }
} else { // printable chars + UTF-8 bytes } else { // printable chars + UTF-8 bytes
if (unicode_high_surrogate != -1) { if (unicode_high_surrogate != -1) {
@@ -948,10 +968,12 @@ CheckedError Parser::ParseField(StructDef &struct_def) {
// For union fields, add a second auto-generated field to hold the type, // For union fields, add a second auto-generated field to hold the type,
// with a special suffix. // with a special suffix.
// To ensure compatibility with many codes that rely on the BASE_TYPE_UTYPE value to identify union type fields. // To ensure compatibility with many codes that rely on the BASE_TYPE_UTYPE
// value to identify union type fields.
Type union_type(type.enum_def->underlying_type); Type union_type(type.enum_def->underlying_type);
union_type.base_type = BASE_TYPE_UTYPE; union_type.base_type = BASE_TYPE_UTYPE;
ECHECK(AddField(struct_def, name + UnionTypeFieldSuffix(),union_type, &typefield)); ECHECK(AddField(struct_def, name + UnionTypeFieldSuffix(), union_type,
&typefield));
} else if (IsVector(type) && type.element == BASE_TYPE_UNION) { } else if (IsVector(type) && type.element == BASE_TYPE_UNION) {
advanced_features_ |= reflection::AdvancedUnionFeatures; advanced_features_ |= reflection::AdvancedUnionFeatures;
@@ -1170,7 +1192,9 @@ CheckedError Parser::ParseField(StructDef &struct_def) {
// Verify the enum's type and default value. // Verify the enum's type and default value.
const std::string& constant = field->value.constant; const std::string& constant = field->value.constant;
if (type.base_type == BASE_TYPE_UNION) { if (type.base_type == BASE_TYPE_UNION) {
if (constant != "0") { return Error("Union defaults must be NONE"); } if (constant != "0") {
return Error("Union defaults must be NONE");
}
} else if (IsVector(type)) { } else if (IsVector(type)) {
if (constant != "0" && constant != "[]") { if (constant != "0" && constant != "[]") {
return Error("Vector defaults may only be `[]`."); return Error("Vector defaults may only be `[]`.");
@@ -1280,7 +1304,9 @@ CheckedError Parser::ParseField(StructDef &struct_def) {
} }
// if this field is a union that is deprecated, // if this field is a union that is deprecated,
// the automatically added type field should be deprecated as well // the automatically added type field should be deprecated as well
if (field->deprecated) { typefield->deprecated = true; } if (field->deprecated) {
typefield->deprecated = true;
}
} }
EXPECT(';'); EXPECT(';');
@@ -1555,7 +1581,9 @@ CheckedError Parser::ParseTable(const StructDef &struct_def, std::string *value,
for (auto field_it = struct_def.fields.vec.begin(); for (auto field_it = struct_def.fields.vec.begin();
field_it != struct_def.fields.vec.end(); ++field_it) { field_it != struct_def.fields.vec.end(); ++field_it) {
auto required_field = *field_it; auto required_field = *field_it;
if (!required_field->IsRequired()) { continue; } if (!required_field->IsRequired()) {
continue;
}
bool found = false; bool found = false;
for (auto pf_it = field_stack_.end() - fieldn_outer; for (auto pf_it = field_stack_.end() - fieldn_outer;
pf_it != field_stack_.end(); ++pf_it) { pf_it != field_stack_.end(); ++pf_it) {
@@ -1718,7 +1746,9 @@ CheckedError Parser::ParseVector(const Type &vector_type, uoffset_t *ovalue,
if (force_align) { if (force_align) {
size_t align; size_t align;
ECHECK(ParseAlignAttribute(force_align->constant, 1, &align)); ECHECK(ParseAlignAttribute(force_align->constant, 1, &align));
if (align > 1) { builder_.ForceVectorAlignment(len, elemsize, align); } if (align > 1) {
builder_.ForceVectorAlignment(len, elemsize, align);
}
} }
// TODO Fix using element alignment as size (`elemsize`)! // TODO Fix using element alignment as size (`elemsize`)!
@@ -1790,7 +1820,9 @@ CheckedError Parser::ParseVector(const Type &vector_type, uoffset_t *ovalue,
}, },
[struct_size](uint8_t* a, uint8_t* b) { [struct_size](uint8_t* a, uint8_t* b) {
// FIXME: faster? // FIXME: faster?
for (size_t i = 0; i < struct_size; i++) { std::swap(a[i], b[i]); } for (size_t i = 0; i < struct_size; i++) {
std::swap(a[i], b[i]);
}
}); });
} else { } else {
auto v = reinterpret_cast<Vector<Offset<Table>>*>( auto v = reinterpret_cast<Vector<Offset<Table>>*>(
@@ -1897,7 +1929,9 @@ CheckedError Parser::ParseNestedFlatbuffer(Value &val, FieldDef *field,
nested_parser.enums_.dict.clear(); nested_parser.enums_.dict.clear();
nested_parser.enums_.vec.clear(); nested_parser.enums_.vec.clear();
if (!ok) { ECHECK(Error(nested_parser.error_)); } if (!ok) {
ECHECK(Error(nested_parser.error_));
}
// Force alignment for nested flatbuffer // Force alignment for nested flatbuffer
builder_.ForceVectorAlignment( builder_.ForceVectorAlignment(
nested_parser.builder_.GetSize(), sizeof(uint8_t), nested_parser.builder_.GetSize(), sizeof(uint8_t),
@@ -2010,7 +2044,8 @@ CheckedError Parser::ParseHash(Value &e, FieldDef *field) {
e.constant = NumToString(hashed_value); e.constant = NumToString(hashed_value);
break; break;
} }
default: FLATBUFFERS_ASSERT(0); default:
FLATBUFFERS_ASSERT(0);
} }
NEXT(); NEXT();
return NoError(); return NoError();
@@ -2112,7 +2147,9 @@ CheckedError Parser::ParseSingleValue(const std::string *name, Value &e,
const auto is_tok_string = (token_ == kTokenStringConstant); const auto is_tok_string = (token_ == kTokenStringConstant);
// First see if this could be a conversion function. // First see if this could be a conversion function.
if (is_tok_ident && *cursor_ == '(') { return ParseFunction(name, e); } if (is_tok_ident && *cursor_ == '(') {
return ParseFunction(name, e);
}
// clang-format off // clang-format off
auto match = false; auto match = false;
@@ -2195,7 +2232,9 @@ CheckedError Parser::ParseSingleValue(const std::string *name, Value &e,
// Match empty vectors for default-empty-vectors. // Match empty vectors for default-empty-vectors.
if (!match && IsVector(e.type) && token_ == '[') { if (!match && IsVector(e.type) && token_ == '[') {
NEXT(); NEXT();
if (token_ != ']') { return Error("Expected `]` in vector default"); } if (token_ != ']') {
return Error("Expected `]` in vector default");
}
NEXT(); NEXT();
match = true; match = true;
e.constant = "[]"; e.constant = "[]";
@@ -2308,7 +2347,9 @@ EnumVal *EnumDef::ReverseLookup(int64_t enum_idx,
bool skip_union_default) const { bool skip_union_default) const {
auto skip_first = static_cast<int>(is_union && skip_union_default); auto skip_first = static_cast<int>(is_union && skip_union_default);
for (auto it = Vals().begin() + skip_first; it != Vals().end(); ++it) { for (auto it = Vals().begin() + skip_first; it != Vals().end(); ++it) {
if ((*it)->GetAsInt64() == enum_idx) { return *it; } if ((*it)->GetAsInt64() == enum_idx) {
return *it;
}
} }
return nullptr; return nullptr;
} }
@@ -2339,7 +2380,9 @@ void EnumDef::SortByValue() {
}); });
else else
std::sort(v.begin(), v.end(), [](const EnumVal* e1, const EnumVal* e2) { std::sort(v.begin(), v.end(), [](const EnumVal* e1, const EnumVal* e2) {
if (e1->GetAsInt64() == e2->GetAsInt64()) { return e1->name < e2->name; } if (e1->GetAsInt64() == e2->GetAsInt64()) {
return e1->name < e2->name;
}
return e1->GetAsInt64() < e2->GetAsInt64(); return e1->GetAsInt64() < e2->GetAsInt64();
}); });
} }
@@ -2367,15 +2410,18 @@ void EnumDef::RemoveDuplicates() {
vals.vec.erase(++result, last); vals.vec.erase(++result, last);
} }
template<typename T> void EnumDef::ChangeEnumValue(EnumVal *ev, T new_value) { template <typename T>
void EnumDef::ChangeEnumValue(EnumVal* ev, T new_value) {
ev->value = static_cast<int64_t>(new_value); ev->value = static_cast<int64_t>(new_value);
} }
namespace EnumHelper { namespace EnumHelper {
template<BaseType E> struct EnumValType { template <BaseType E>
struct EnumValType {
typedef int64_t type; typedef int64_t type;
}; };
template<> struct EnumValType<BASE_TYPE_ULONG> { template <>
struct EnumValType<BASE_TYPE_ULONG> {
typedef uint64_t type; typedef uint64_t type;
}; };
} // namespace EnumHelper } // namespace EnumHelper
@@ -2482,8 +2528,8 @@ CheckedError Parser::ParseEnum(const bool is_union, EnumDef **dest,
EnumDef* enum_def; EnumDef* enum_def;
ECHECK(StartEnum(enum_name, is_union, &enum_def)); ECHECK(StartEnum(enum_name, is_union, &enum_def));
if (filename != nullptr && !opts.project_root.empty()) { if (filename != nullptr && !opts.project_root.empty()) {
enum_def->declaration_file = enum_def->declaration_file = &GetPooledString(FilePath(
&GetPooledString(FilePath(opts.project_root, filename, opts.binary_schema_absolute_paths)); opts.project_root, filename, opts.binary_schema_absolute_paths));
} }
enum_def->doc_comment = enum_comment; enum_def->doc_comment = enum_comment;
if (!opts.proto_mode) { if (!opts.proto_mode) {
@@ -2511,14 +2557,15 @@ CheckedError Parser::ParseEnum(const bool is_union, EnumDef **dest,
if (explicit_underlying_type) { if (explicit_underlying_type) {
// Specify the integer type underlying this enum. // Specify the integer type underlying this enum.
ECHECK(ParseType(enum_def->underlying_type)); ECHECK(ParseType(enum_def->underlying_type));
if (!IsInteger(enum_def->underlying_type.base_type) || IsBool(enum_def->underlying_type.base_type)) { if (!IsInteger(enum_def->underlying_type.base_type) ||
return Error("underlying " + std::string(is_union ? "union" : "enum") + "type must be integral"); IsBool(enum_def->underlying_type.base_type)) {
return Error("underlying " + std::string(is_union ? "union" : "enum") +
"type must be integral");
} }
// Make this type refer back to the enum it was derived from. // Make this type refer back to the enum it was derived from.
enum_def->underlying_type.enum_def = enum_def; enum_def->underlying_type.enum_def = enum_def;
} }
} }
ECHECK(ParseMetaData(&enum_def->attributes)); ECHECK(ParseMetaData(&enum_def->attributes));
const auto underlying_type = enum_def->underlying_type.base_type; const auto underlying_type = enum_def->underlying_type.base_type;
@@ -2671,7 +2718,9 @@ CheckedError Parser::CheckClash(std::vector<FieldDef *> &fields,
std::vector<IncludedFile> Parser::GetIncludedFiles() const { std::vector<IncludedFile> Parser::GetIncludedFiles() const {
const auto it = files_included_per_file_.find(file_being_parsed_); const auto it = files_included_per_file_.find(file_being_parsed_);
if (it == files_included_per_file_.end()) { return {}; } if (it == files_included_per_file_.end()) {
return {};
}
return {it->second.cbegin(), it->second.cend()}; return {it->second.cbegin(), it->second.cend()};
} }
@@ -2682,8 +2731,7 @@ bool Parser::SupportsOptionalScalars(const flatbuffers::IDLOptions &opts) {
IDLOptions::kKotlin | IDLOptions::kKotlinKmp | IDLOptions::kCpp | IDLOptions::kKotlin | IDLOptions::kKotlinKmp | IDLOptions::kCpp |
IDLOptions::kJava | IDLOptions::kCSharp | IDLOptions::kTs | IDLOptions::kJava | IDLOptions::kCSharp | IDLOptions::kTs |
IDLOptions::kBinary | IDLOptions::kGo | IDLOptions::kPython | IDLOptions::kBinary | IDLOptions::kGo | IDLOptions::kPython |
IDLOptions::kJson | IDLOptions::kJson | IDLOptions::kNim;
IDLOptions::kNim;
unsigned long langs = opts.lang_to_generate; unsigned long langs = opts.lang_to_generate;
return (langs > 0 && langs < IDLOptions::kMAX) && !(langs & ~supported_langs); return (langs > 0 && langs < IDLOptions::kMAX) && !(langs & ~supported_langs);
} }
@@ -2719,8 +2767,8 @@ bool Parser::Supports64BitOffsets() const {
} }
bool Parser::SupportsUnionUnderlyingType() const { bool Parser::SupportsUnionUnderlyingType() const {
return (opts.lang_to_generate & ~(IDLOptions::kCpp | IDLOptions::kTs | return (opts.lang_to_generate &
IDLOptions::kBinary)) == 0; ~(IDLOptions::kCpp | IDLOptions::kTs | IDLOptions::kBinary)) == 0;
} }
Namespace* Parser::UniqueNamespace(Namespace* ns) { Namespace* Parser::UniqueNamespace(Namespace* ns) {
@@ -2761,8 +2809,8 @@ CheckedError Parser::ParseDecl(const char *filename) {
struct_def->doc_comment = dc; struct_def->doc_comment = dc;
struct_def->fixed = fixed; struct_def->fixed = fixed;
if (filename && !opts.project_root.empty()) { if (filename && !opts.project_root.empty()) {
struct_def->declaration_file = struct_def->declaration_file = &GetPooledString(FilePath(
&GetPooledString(FilePath(opts.project_root, filename, opts.binary_schema_absolute_paths)); opts.project_root, filename, opts.binary_schema_absolute_paths));
} }
ECHECK(ParseMetaData(&struct_def->attributes)); ECHECK(ParseMetaData(&struct_def->attributes));
struct_def->sortbysize = struct_def->sortbysize =
@@ -2855,8 +2903,8 @@ CheckedError Parser::ParseService(const char *filename) {
service_def.doc_comment = service_comment; service_def.doc_comment = service_comment;
service_def.defined_namespace = current_namespace_; service_def.defined_namespace = current_namespace_;
if (filename != nullptr && !opts.project_root.empty()) { if (filename != nullptr && !opts.project_root.empty()) {
service_def.declaration_file = service_def.declaration_file = &GetPooledString(FilePath(
&GetPooledString(FilePath(opts.project_root, filename, opts.binary_schema_absolute_paths)); opts.project_root, filename, opts.binary_schema_absolute_paths));
} }
if (services_.Add(current_namespace_->GetFullyQualifiedName(service_name), if (services_.Add(current_namespace_->GetFullyQualifiedName(service_name),
&service_def)) &service_def))
@@ -2906,7 +2954,9 @@ void Parser::MarkGenerated() {
(*it)->generated = true; (*it)->generated = true;
} }
for (auto it = structs_.vec.begin(); it != structs_.vec.end(); ++it) { for (auto it = structs_.vec.begin(); it != structs_.vec.end(); ++it) {
if (!(*it)->predecl) { (*it)->generated = true; } if (!(*it)->predecl) {
(*it)->generated = true;
}
} }
for (auto it = services_.vec.begin(); it != services_.vec.end(); ++it) { for (auto it = services_.vec.begin(); it != services_.vec.end(); ++it) {
(*it)->generated = true; (*it)->generated = true;
@@ -2968,7 +3018,9 @@ CheckedError Parser::ParseProtoDecl() {
} }
struct_def->doc_comment = struct_comment; struct_def->doc_comment = struct_comment;
ECHECK(ParseProtoFields(struct_def, isextend, false)); ECHECK(ParseProtoFields(struct_def, isextend, false));
if (!isextend) { current_namespace_ = parent_namespace; } if (!isextend) {
current_namespace_ = parent_namespace;
}
if (Is(';')) NEXT(); if (Is(';')) NEXT();
} else if (IsIdent("enum")) { } else if (IsIdent("enum")) {
// These are almost the same, just with different terminator: // These are almost the same, just with different terminator:
@@ -3298,8 +3350,7 @@ CheckedError Parser::ParseTypeFromProtoType(Type *type) {
const char* proto_type; const char* proto_type;
BaseType fb_type, element; BaseType fb_type, element;
}; };
static type_lookup lookup[] = { static type_lookup lookup[] = {{"float", BASE_TYPE_FLOAT, BASE_TYPE_NONE},
{ "float", BASE_TYPE_FLOAT, BASE_TYPE_NONE },
{"double", BASE_TYPE_DOUBLE, BASE_TYPE_NONE}, {"double", BASE_TYPE_DOUBLE, BASE_TYPE_NONE},
{"int32", BASE_TYPE_INT, BASE_TYPE_NONE}, {"int32", BASE_TYPE_INT, BASE_TYPE_NONE},
{"int64", BASE_TYPE_LONG, BASE_TYPE_NONE}, {"int64", BASE_TYPE_LONG, BASE_TYPE_NONE},
@@ -3314,8 +3365,7 @@ CheckedError Parser::ParseTypeFromProtoType(Type *type) {
{"bool", BASE_TYPE_BOOL, BASE_TYPE_NONE}, {"bool", BASE_TYPE_BOOL, BASE_TYPE_NONE},
{"string", BASE_TYPE_STRING, BASE_TYPE_NONE}, {"string", BASE_TYPE_STRING, BASE_TYPE_NONE},
{"bytes", BASE_TYPE_VECTOR, BASE_TYPE_UCHAR}, {"bytes", BASE_TYPE_VECTOR, BASE_TYPE_UCHAR},
{ nullptr, BASE_TYPE_NONE, BASE_TYPE_NONE } {nullptr, BASE_TYPE_NONE, BASE_TYPE_NONE}};
};
for (auto tl = lookup; tl->proto_type; tl++) { for (auto tl = lookup; tl->proto_type; tl++) {
if (attribute_ == tl->proto_type) { if (attribute_ == tl->proto_type) {
type->base_type = tl->fb_type; type->base_type = tl->fb_type;
@@ -3351,7 +3401,9 @@ CheckedError Parser::SkipAnyJsonValue() {
} }
case kTokenStringConstant: case kTokenStringConstant:
case kTokenIntegerConstant: case kTokenIntegerConstant:
case kTokenFloatConstant: NEXT(); break; case kTokenFloatConstant:
NEXT();
break;
default: default:
if (IsIdent("true") || IsIdent("false") || IsIdent("null") || if (IsIdent("true") || IsIdent("false") || IsIdent("null") ||
IsIdent("inf")) { IsIdent("inf")) {
@@ -3586,7 +3638,9 @@ CheckedError Parser::ParseRoot(const char *source, const char **include_paths,
if (err.Check()) return err; if (err.Check()) return err;
// Parse JSON object only if the scheme has been parsed. // Parse JSON object only if the scheme has been parsed.
if (token_ == '{') { ECHECK(DoParseJson()); } if (token_ == '{') {
ECHECK(DoParseJson());
}
return NoError(); return NoError();
} }
@@ -3603,11 +3657,15 @@ CheckedError Parser::CheckPrivateLeak() {
if (field.value.type.enum_def) { if (field.value.type.enum_def) {
auto err = auto err =
CheckPrivatelyLeakedFields(struct_def, *field.value.type.enum_def); CheckPrivatelyLeakedFields(struct_def, *field.value.type.enum_def);
if (err.Check()) { return err; } if (err.Check()) {
return err;
}
} else if (field.value.type.struct_def) { } else if (field.value.type.struct_def) {
auto err = CheckPrivatelyLeakedFields(struct_def, auto err = CheckPrivatelyLeakedFields(struct_def,
*field.value.type.struct_def); *field.value.type.struct_def);
if (err.Check()) { return err; } if (err.Check()) {
return err;
}
} }
} }
} }
@@ -3622,7 +3680,9 @@ CheckedError Parser::CheckPrivateLeak() {
if (val.union_type.struct_def) { if (val.union_type.struct_def) {
auto err = auto err =
CheckPrivatelyLeakedFields(enum_def, *val.union_type.struct_def); CheckPrivatelyLeakedFields(enum_def, *val.union_type.struct_def);
if (err.Check()) { return err; } if (err.Check()) {
return err;
}
} }
} }
} }
@@ -3890,7 +3950,9 @@ static bool DeserializeAttributesCommon(
for (uoffset_t i = 0; i < attrs->size(); ++i) { for (uoffset_t i = 0; i < attrs->size(); ++i) {
auto kv = attrs->Get(i); auto kv = attrs->Get(i);
auto value = new Value(); auto value = new Value();
if (kv->value()) { value->constant = kv->value()->str(); } if (kv->value()) {
value->constant = kv->value()->str();
}
if (attributes.Add(kv->key()->str(), value)) { if (attributes.Add(kv->key()->str(), value)) {
delete value; delete value;
return false; return false;
@@ -3937,12 +3999,12 @@ void Parser::Serialize() {
std::vector<Offset<flatbuffers::String>> included_files; std::vector<Offset<flatbuffers::String>> included_files;
for (auto f = files_included_per_file_.begin(); for (auto f = files_included_per_file_.begin();
f != files_included_per_file_.end(); f++) { f != files_included_per_file_.end(); f++) {
const auto filename__ = builder_.CreateSharedString(FilePath( const auto filename__ = builder_.CreateSharedString(FilePath(
opts.project_root, f->first, opts.binary_schema_absolute_paths)); opts.project_root, f->first, opts.binary_schema_absolute_paths));
for (auto i = f->second.begin(); i != f->second.end(); i++) { for (auto i = f->second.begin(); i != f->second.end(); i++) {
included_files.push_back(builder_.CreateSharedString( included_files.push_back(builder_.CreateSharedString(
FilePath(opts.project_root, i->filename, opts.binary_schema_absolute_paths))); FilePath(opts.project_root, i->filename,
opts.binary_schema_absolute_paths)));
} }
const auto included_files__ = builder_.CreateVector(included_files); const auto included_files__ = builder_.CreateVector(included_files);
included_files.clear(); included_files.clear();
@@ -4107,7 +4169,9 @@ bool RPCCall::Deserialize(Parser &parser, const reflection::RPCCall *call) {
DeserializeDoc(doc_comment, call->documentation()); DeserializeDoc(doc_comment, call->documentation());
request = parser.structs_.Lookup(call->request()->name()->str()); request = parser.structs_.Lookup(call->request()->name()->str());
response = parser.structs_.Lookup(call->response()->name()->str()); response = parser.structs_.Lookup(call->response()->name()->str());
if (!request || !response) { return false; } if (!request || !response) {
return false;
}
return true; return true;
} }
@@ -4289,7 +4353,9 @@ bool Parser::Deserialize(const uint8_t *buf, const size_t size) {
} }
auto verify_fn = size_prefixed ? &reflection::VerifySizePrefixedSchemaBuffer auto verify_fn = size_prefixed ? &reflection::VerifySizePrefixedSchemaBuffer
: &reflection::VerifySchemaBuffer; : &reflection::VerifySchemaBuffer;
if (!verify_fn(verifier)) { return false; } if (!verify_fn(verifier)) {
return false;
}
auto schema = size_prefixed ? reflection::GetSizePrefixedSchema(buf) auto schema = size_prefixed ? reflection::GetSizePrefixedSchema(buf)
: reflection::GetSchema(buf); : reflection::GetSchema(buf);
return Deserialize(schema); return Deserialize(schema);
@@ -4338,15 +4404,21 @@ bool Parser::Deserialize(const reflection::Schema *schema) {
auto struct_def = structs_.Lookup(qualified_name); auto struct_def = structs_.Lookup(qualified_name);
struct_def->defined_namespace = struct_def->defined_namespace =
GetNamespace(qualified_name, namespaces_, namespaces_index); GetNamespace(qualified_name, namespaces_, namespaces_index);
if (!struct_def->Deserialize(*this, *it)) { return false; } if (!struct_def->Deserialize(*this, *it)) {
if (schema->root_table() == *it) { root_struct_def_ = struct_def; } return false;
}
if (schema->root_table() == *it) {
root_struct_def_ = struct_def;
}
} }
for (auto it = schema->enums()->begin(); it != schema->enums()->end(); ++it) { for (auto it = schema->enums()->begin(); it != schema->enums()->end(); ++it) {
std::string qualified_name = it->name()->str(); std::string qualified_name = it->name()->str();
auto enum_def = enums_.Lookup(qualified_name); auto enum_def = enums_.Lookup(qualified_name);
enum_def->defined_namespace = enum_def->defined_namespace =
GetNamespace(qualified_name, namespaces_, namespaces_index); GetNamespace(qualified_name, namespaces_, namespaces_index);
if (!enum_def->Deserialize(*this, *it)) { return false; } if (!enum_def->Deserialize(*this, *it)) {
return false;
}
} }
if (schema->services()) { if (schema->services()) {
@@ -4456,8 +4528,11 @@ std::string Parser::ConformTo(const Parser &base) {
} }
} }
// Check underlying type changes // Check underlying type changes
if (enum_def_base->underlying_type.base_type != enum_def.underlying_type.base_type) { if (enum_def_base->underlying_type.base_type !=
return "underlying type differ for " + std::string(enum_def.is_union ? "union: " : "enum: ") + qualified_name; enum_def.underlying_type.base_type) {
return "underlying type differ for " +
std::string(enum_def.is_union ? "union: " : "enum: ") +
qualified_name;
} }
} }
return ""; return "";

View File

@@ -37,7 +37,9 @@ static bool VerifyStruct(flatbuffers::Verifier &v,
voffset_t field_offset, const reflection::Object& obj, voffset_t field_offset, const reflection::Object& obj,
bool required) { bool required) {
auto offset = parent_table.GetOptionalFieldOffset(field_offset); auto offset = parent_table.GetOptionalFieldOffset(field_offset);
if (required && !offset) { return false; } if (required && !offset) {
return false;
}
return !offset || return !offset ||
v.VerifyFieldStruct(reinterpret_cast<const uint8_t*>(&parent_table), v.VerifyFieldStruct(reinterpret_cast<const uint8_t*>(&parent_table),
@@ -50,7 +52,9 @@ static bool VerifyVectorOfStructs(flatbuffers::Verifier &v,
const reflection::Object& obj, const reflection::Object& obj,
bool required) { bool required) {
auto p = parent_table.GetPointer<const uint8_t*>(field_offset); auto p = parent_table.GetPointer<const uint8_t*>(field_offset);
if (required && !p) { return false; } if (required && !p) {
return false;
}
return !p || v.VerifyVectorOrString(p, obj.bytesize()); return !p || v.VerifyVectorOrString(p, obj.bytesize());
} }
@@ -81,9 +85,9 @@ static bool VerifyUnion(flatbuffers::Verifier &v,
} }
} }
case reflection::String: case reflection::String:
return v.VerifyString( return v.VerifyString(reinterpret_cast<const flatbuffers::String*>(elem));
reinterpret_cast<const flatbuffers::String *>(elem)); default:
default: return false; return false;
} }
} }
@@ -162,7 +166,9 @@ static bool VerifyVector(flatbuffers::Verifier &v,
} }
case reflection::Vector: case reflection::Vector:
case reflection::None: case reflection::None:
default: FLATBUFFERS_ASSERT(false); return false; default:
FLATBUFFERS_ASSERT(false);
return false;
} }
} }
@@ -175,7 +181,9 @@ static bool VerifyObject(flatbuffers::Verifier &v,
for (uoffset_t i = 0; i < obj.fields()->size(); i++) { for (uoffset_t i = 0; i < obj.fields()->size(); i++) {
auto field_def = obj.fields()->Get(i); auto field_def = obj.fields()->Get(i);
switch (field_def->type()->base_type()) { switch (field_def->type()->base_type()) {
case reflection::None: FLATBUFFERS_ASSERT(false); break; case reflection::None:
FLATBUFFERS_ASSERT(false);
break;
case reflection::UType: case reflection::UType:
if (!table->VerifyField<uint8_t>(v, field_def->offset(), if (!table->VerifyField<uint8_t>(v, field_def->offset(),
sizeof(uint8_t))) sizeof(uint8_t)))
@@ -245,10 +253,14 @@ static bool VerifyObject(flatbuffers::Verifier &v,
auto utype = table->GetField<uint8_t>(utype_offset, 0); auto utype = table->GetField<uint8_t>(utype_offset, 0);
auto uval = reinterpret_cast<const uint8_t*>( auto uval = reinterpret_cast<const uint8_t*>(
flatbuffers::GetFieldT(*table, *field_def)); flatbuffers::GetFieldT(*table, *field_def));
if (!VerifyUnion(v, schema, utype, uval, *field_def)) { return false; } if (!VerifyUnion(v, schema, utype, uval, *field_def)) {
return false;
}
break; break;
} }
default: FLATBUFFERS_ASSERT(false); break; default:
FLATBUFFERS_ASSERT(false);
break;
} }
} }
@@ -288,8 +300,10 @@ int64_t GetAnyValueI(reflection::BaseType type, const uint8_t *data) {
double GetAnyValueF(reflection::BaseType type, const uint8_t* data) { double GetAnyValueF(reflection::BaseType type, const uint8_t* data) {
switch (type) { switch (type) {
case reflection::Float: return static_cast<double>(ReadScalar<float>(data)); case reflection::Float:
case reflection::Double: return ReadScalar<double>(data); return static_cast<double>(ReadScalar<float>(data));
case reflection::Double:
return ReadScalar<double>(data);
case reflection::String: { case reflection::String: {
auto s = auto s =
reinterpret_cast<const String*>(ReadScalar<uoffset_t>(data) + data); reinterpret_cast<const String*>(ReadScalar<uoffset_t>(data) + data);
@@ -301,7 +315,8 @@ double GetAnyValueF(reflection::BaseType type, const uint8_t *data) {
return 0.0; return 0.0;
} }
} }
default: return static_cast<double>(GetAnyValueI(type, data)); default:
return static_cast<double>(GetAnyValueI(type, data));
} }
} }
@@ -309,7 +324,8 @@ std::string GetAnyValueS(reflection::BaseType type, const uint8_t *data,
const reflection::Schema* schema, int type_index) { const reflection::Schema* schema, int type_index) {
switch (type) { switch (type) {
case reflection::Float: case reflection::Float:
case reflection::Double: return NumToString(GetAnyValueF(type, data)); case reflection::Double:
return NumToString(GetAnyValueF(type, data));
case reflection::String: { case reflection::String: {
auto s = auto s =
reinterpret_cast<const String*>(ReadScalar<uoffset_t>(data) + data); reinterpret_cast<const String*>(ReadScalar<uoffset_t>(data) + data);
@@ -352,8 +368,10 @@ std::string GetAnyValueS(reflection::BaseType type, const uint8_t *data,
} }
case reflection::Vector: case reflection::Vector:
return "[(elements)]"; // TODO: implement this as well. return "[(elements)]"; // TODO: implement this as well.
case reflection::Union: return "(union)"; // TODO: implement this as well. case reflection::Union:
default: return NumToString(GetAnyValueI(type, data)); return "(union)"; // TODO: implement this as well.
default:
return NumToString(GetAnyValueI(type, data));
} }
} }
@@ -399,10 +417,16 @@ void SetAnyValueI(reflection::BaseType type, uint8_t *data, int64_t val) {
void SetAnyValueF(reflection::BaseType type, uint8_t* data, double val) { void SetAnyValueF(reflection::BaseType type, uint8_t* data, double val) {
switch (type) { switch (type) {
case reflection::Float: WriteScalar(data, static_cast<float>(val)); break; case reflection::Float:
case reflection::Double: WriteScalar(data, val); break; WriteScalar(data, static_cast<float>(val));
break;
case reflection::Double:
WriteScalar(data, val);
break;
// TODO: support strings. // TODO: support strings.
default: SetAnyValueI(type, data, static_cast<int64_t>(val)); break; default:
SetAnyValueI(type, data, static_cast<int64_t>(val));
break;
} }
} }
@@ -416,7 +440,9 @@ void SetAnyValueS(reflection::BaseType type, uint8_t *data, const char *val) {
break; break;
} }
// TODO: support strings. // TODO: support strings.
default: SetAnyValueI(type, data, StringToInt(val)); break; default:
SetAnyValueI(type, data, StringToInt(val));
break;
} }
} }
@@ -541,8 +567,10 @@ class ResizeContext {
reinterpret_cast<Table*>(ref)); reinterpret_cast<Table*>(ref));
break; break;
} }
case reflection::String: break; case reflection::String:
default: FLATBUFFERS_ASSERT(false); break;
default:
FLATBUFFERS_ASSERT(false);
} }
} }
// Check if the vtable offset points beyond the insertion point. // Check if the vtable offset points beyond the insertion point.
@@ -707,7 +735,9 @@ Offset<const Table *> CopyTable(FlatBufferBuilder &fbb,
default: // Scalars. default: // Scalars.
break; break;
} }
if (offset) { offsets.push_back(offset); } if (offset) {
offsets.push_back(offset);
}
} }
// Now we can build the actual table from either offsets or scalar data. // Now we can build the actual table from either offsets or scalar data.
auto start = objectdef.is_struct() ? fbb.StartStruct(objectdef.minalign()) auto start = objectdef.is_struct() ? fbb.StartStruct(objectdef.minalign())

View File

@@ -130,7 +130,9 @@ static std::string ToSnakeCase(const std::string &input, bool screaming) {
std::string ToAll(const std::string& input, std::string ToAll(const std::string& input,
std::function<char(const char)> transform) { std::function<char(const char)> transform) {
std::string s; std::string s;
for (size_t i = 0; i < input.length(); i++) { s += transform(input[i]); } for (size_t i = 0; i < input.length(); i++) {
s += transform(input[i]);
}
return s; return s;
} }
@@ -336,8 +338,10 @@ void EnsureDirExists(const std::string &filepath) {
// clang-format on // clang-format on
} }
std::string FilePath(const std::string& project, const std::string& filePath, bool absolute) { std::string FilePath(const std::string& project, const std::string& filePath,
return (absolute) ? AbsolutePath(filePath) : RelativeToRootPath(project, filePath); bool absolute) {
return (absolute) ? AbsolutePath(filePath)
: RelativeToRootPath(project, filePath);
} }
std::string AbsolutePath(const std::string& filepath) { std::string AbsolutePath(const std::string& filepath) {
@@ -449,26 +453,39 @@ std::string ConvertCase(const std::string &input, Case output_case,
case Case::kLowerCamel: case Case::kLowerCamel:
case Case::kUpperCamel: case Case::kUpperCamel:
return ConvertCase(CamelToSnake(input), output_case); return ConvertCase(CamelToSnake(input), output_case);
case Case::kDasher: return ConvertCase(DasherToSnake(input), output_case); case Case::kDasher:
case Case::kKeep: printf("WARNING: Converting from kKeep case.\n"); break; return ConvertCase(DasherToSnake(input), output_case);
case Case::kKeep:
printf("WARNING: Converting from kKeep case.\n");
break;
default: default:
case Case::kSnake: case Case::kSnake:
case Case::kScreamingSnake: case Case::kScreamingSnake:
case Case::kAllLower: case Case::kAllLower:
case Case::kAllUpper: break; case Case::kAllUpper:
break;
} }
switch (output_case) { switch (output_case) {
case Case::kUpperCamel: return ToCamelCase(input, true); case Case::kUpperCamel:
case Case::kLowerCamel: return ToCamelCase(input, false); return ToCamelCase(input, true);
case Case::kSnake: return input; case Case::kLowerCamel:
case Case::kScreamingSnake: return ToSnakeCase(input, true); return ToCamelCase(input, false);
case Case::kAllUpper: return ToAll(input, CharToUpper); case Case::kSnake:
case Case::kAllLower: return ToAll(input, CharToLower); return input;
case Case::kDasher: return ToDasher(input); case Case::kScreamingSnake:
case Case::kSnake2: return SnakeToSnake2(input); return ToSnakeCase(input, true);
case Case::kAllUpper:
return ToAll(input, CharToUpper);
case Case::kAllLower:
return ToAll(input, CharToLower);
case Case::kDasher:
return ToDasher(input);
case Case::kSnake2:
return SnakeToSnake2(input);
default: default:
case Case::kUnknown: return input; case Case::kUnknown:
return input;
} }
} }

View File

@@ -1,9 +1,9 @@
#include "alignment_test.h" #include "alignment_test.h"
#include "tests/alignment_test_generated.h"
#include "flatbuffers/flatbuffer_builder.h" #include "flatbuffers/flatbuffer_builder.h"
#include "flatbuffers/util.h" #include "flatbuffers/util.h"
#include "test_assert.h" #include "test_assert.h"
#include "tests/alignment_test_generated.h"
namespace flatbuffers { namespace flatbuffers {
namespace tests { namespace tests {
@@ -27,7 +27,6 @@ void AlignmentTest() {
Verifier verifier(builder.GetBufferPointer(), builder.GetSize()); Verifier verifier(builder.GetBufferPointer(), builder.GetSize());
TEST_ASSERT(verifier.VerifyBuffer<BadAlignmentRoot>(nullptr)); TEST_ASSERT(verifier.VerifyBuffer<BadAlignmentRoot>(nullptr));
// ============= Test Small Structs Vector misalignment ======== // ============= Test Small Structs Vector misalignment ========
builder.Clear(); builder.Clear();
@@ -35,9 +34,7 @@ void AlignmentTest() {
// creating 5 structs with 2 bytes each // creating 5 structs with 2 bytes each
// 10 bytes in total for Vector data is needed // 10 bytes in total for Vector data is needed
std::vector<EvenSmallStruct> even_vector = {{2, 1}, {3, 1}, {4, 1}}; std::vector<EvenSmallStruct> even_vector = {{2, 1}, {3, 1}, {4, 1}};
std::vector<OddSmallStruct> odd_vector = { { 6, 5, 4 }, std::vector<OddSmallStruct> odd_vector = {{6, 5, 4}, {9, 8, 7}, {1, 2, 3}};
{ 9, 8, 7 },
{ 1, 2, 3 } };
// CreateVectorOfStructs is used in the generated CreateSmallStructsDirect() // CreateVectorOfStructs is used in the generated CreateSmallStructsDirect()
// method, but we test it directly // method, but we test it directly
Offset<Vector<const EvenSmallStruct*>> even_structs_offset = Offset<Vector<const EvenSmallStruct*>> even_structs_offset =

View File

@@ -112,11 +112,13 @@ void ConformTest() {
"field renamed to different type: T2.df (renamed from T2.f)"); "field renamed to different type: T2.df (renamed from T2.f)");
// Check enum underlying type changes. // Check enum underlying type changes.
test_conform("enum E:int32 {A}", "enum E: byte {A}", "underlying type differ for enum: E"); test_conform("enum E:int32 {A}", "enum E: byte {A}",
"underlying type differ for enum: E");
// Check union underlying type changes. // Check union underlying type changes.
const char ref3[] = "table A {} table B {} union C {A, B}"; const char ref3[] = "table A {} table B {} union C {A, B}";
test_conform(ref3, "table A {} table B {} union C:int32 {A, B}", "underlying type differ for union: C"); test_conform(ref3, "table A {} table B {} union C:int32 {A, B}",
"underlying type differ for union: C");
// Check conformity for Offset64-related changes. // Check conformity for Offset64-related changes.
{ {

View File

@@ -136,7 +136,8 @@ void FlexBuffersTest() {
std::string jsonback_indented; std::string jsonback_indented;
jroot.ToString(true, false, jsonback_indented, true, 0, " "); jroot.ToString(true, false, jsonback_indented, true, 0, " ");
auto jsontest_indented = auto jsontest_indented =
"{\n a: [\n 123,\n 456.0\n ],\n b: \"hello\",\n c: true,\n d: false\n}"; "{\n a: [\n 123,\n 456.0\n ],\n b: \"hello\",\n c: true,\n d: "
"false\n}";
TEST_EQ_STR(jsontest_indented, jsonback_indented.c_str()); TEST_EQ_STR(jsontest_indented, jsonback_indented.c_str());
slb.Clear(); slb.Clear();

View File

@@ -64,17 +64,39 @@ void FuzzTest1() {
int choice = lcg_rand() % test_values_max; int choice = lcg_rand() % test_values_max;
auto off = flatbuffers::FieldIndexToOffset(f); auto off = flatbuffers::FieldIndexToOffset(f);
switch (choice) { switch (choice) {
case 0: builder.AddElement<uint8_t>(off, bool_val, 0); break; case 0:
case 1: builder.AddElement<int8_t>(off, char_val, 0); break; builder.AddElement<uint8_t>(off, bool_val, 0);
case 2: builder.AddElement<uint8_t>(off, uchar_val, 0); break; break;
case 3: builder.AddElement<int16_t>(off, short_val, 0); break; case 1:
case 4: builder.AddElement<uint16_t>(off, ushort_val, 0); break; builder.AddElement<int8_t>(off, char_val, 0);
case 5: builder.AddElement<int32_t>(off, int_val, 0); break; break;
case 6: builder.AddElement<uint32_t>(off, uint_val, 0); break; case 2:
case 7: builder.AddElement<int64_t>(off, long_val, 0); break; builder.AddElement<uint8_t>(off, uchar_val, 0);
case 8: builder.AddElement<uint64_t>(off, ulong_val, 0); break; break;
case 9: builder.AddElement<float>(off, float_val, 0); break; case 3:
case 10: builder.AddElement<double>(off, double_val, 0); break; builder.AddElement<int16_t>(off, short_val, 0);
break;
case 4:
builder.AddElement<uint16_t>(off, ushort_val, 0);
break;
case 5:
builder.AddElement<int32_t>(off, int_val, 0);
break;
case 6:
builder.AddElement<uint32_t>(off, uint_val, 0);
break;
case 7:
builder.AddElement<int64_t>(off, long_val, 0);
break;
case 8:
builder.AddElement<uint64_t>(off, ulong_val, 0);
break;
case 9:
builder.AddElement<float>(off, float_val, 0);
break;
case 10:
builder.AddElement<double>(off, double_val, 0);
break;
} }
} }
objects[i] = builder.EndTable(start); objects[i] = builder.EndTable(start);
@@ -94,17 +116,39 @@ void FuzzTest1() {
int choice = lcg_rand() % test_values_max; int choice = lcg_rand() % test_values_max;
flatbuffers::voffset_t off = flatbuffers::FieldIndexToOffset(f); flatbuffers::voffset_t off = flatbuffers::FieldIndexToOffset(f);
switch (choice) { switch (choice) {
case 0: CompareTableFieldValue(table, off, bool_val); break; case 0:
case 1: CompareTableFieldValue(table, off, char_val); break; CompareTableFieldValue(table, off, bool_val);
case 2: CompareTableFieldValue(table, off, uchar_val); break; break;
case 3: CompareTableFieldValue(table, off, short_val); break; case 1:
case 4: CompareTableFieldValue(table, off, ushort_val); break; CompareTableFieldValue(table, off, char_val);
case 5: CompareTableFieldValue(table, off, int_val); break; break;
case 6: CompareTableFieldValue(table, off, uint_val); break; case 2:
case 7: CompareTableFieldValue(table, off, long_val); break; CompareTableFieldValue(table, off, uchar_val);
case 8: CompareTableFieldValue(table, off, ulong_val); break; break;
case 9: CompareTableFieldValue(table, off, float_val); break; case 3:
case 10: CompareTableFieldValue(table, off, double_val); break; CompareTableFieldValue(table, off, short_val);
break;
case 4:
CompareTableFieldValue(table, off, ushort_val);
break;
case 5:
CompareTableFieldValue(table, off, int_val);
break;
case 6:
CompareTableFieldValue(table, off, uint_val);
break;
case 7:
CompareTableFieldValue(table, off, long_val);
break;
case 8:
CompareTableFieldValue(table, off, ulong_val);
break;
case 9:
CompareTableFieldValue(table, off, float_val);
break;
case 10:
CompareTableFieldValue(table, off, double_val);
break;
} }
} }
} }

View File

@@ -170,18 +170,15 @@ void FixedSizedStructArrayKeyInStructTest() {
Rice test_rice_array1[3] = { Rice test_rice_array1[3] = {
Rice(flatbuffers::make_span(test_char_array1), 2), Rice(flatbuffers::make_span(test_char_array1), 2),
Rice(flatbuffers::make_span(test_char_array2), 1), Rice(flatbuffers::make_span(test_char_array2), 1),
Rice(flatbuffers::make_span(test_char_array3), 2) Rice(flatbuffers::make_span(test_char_array3), 2)};
};
Rice test_rice_array2[3] = { Rice test_rice_array2[3] = {
Rice(flatbuffers::make_span(test_char_array4), 2), Rice(flatbuffers::make_span(test_char_array4), 2),
Rice(flatbuffers::make_span(test_char_array5), 1), Rice(flatbuffers::make_span(test_char_array5), 1),
Rice(flatbuffers::make_span(test_char_array6), 2) Rice(flatbuffers::make_span(test_char_array6), 2)};
};
Rice test_rice_array3[3] = { Rice test_rice_array3[3] = {
Rice(flatbuffers::make_span(test_char_array4), 2), Rice(flatbuffers::make_span(test_char_array4), 2),
Rice(flatbuffers::make_span(test_char_array6), 1), Rice(flatbuffers::make_span(test_char_array6), 1),
Rice(flatbuffers::make_span(test_char_array1), 2) Rice(flatbuffers::make_span(test_char_array1), 2)};
};
grains.push_back(Grain(flatbuffers::make_span(test_rice_array1), 3)); grains.push_back(Grain(flatbuffers::make_span(test_rice_array1), 3));
grains.push_back(Grain(flatbuffers::make_span(test_rice_array2), 1)); grains.push_back(Grain(flatbuffers::make_span(test_rice_array2), 1));
@@ -209,8 +206,7 @@ void FixedSizedStructArrayKeyInStructTest() {
3); 3);
Rice test_rice_array[3] = {Rice(flatbuffers::make_span(test_char_array3), 2), Rice test_rice_array[3] = {Rice(flatbuffers::make_span(test_char_array3), 2),
Rice(flatbuffers::make_span(test_char_array2), 1), Rice(flatbuffers::make_span(test_char_array2), 1),
Rice(flatbuffers::make_span(test_char_array1), Rice(flatbuffers::make_span(test_char_array1), 2)};
2) };
TEST_EQ( TEST_EQ(
sorted_grain_vec->LookupByKey(&flatbuffers::CastToArray(test_rice_array)), sorted_grain_vec->LookupByKey(&flatbuffers::CastToArray(test_rice_array)),
static_cast<const Grain*>(nullptr)); static_cast<const Grain*>(nullptr));

View File

@@ -100,7 +100,9 @@ flatbuffers::DetachedBuffer CreateFlatBufferTest(std::string &buffer) {
// Create many vectors of strings // Create many vectors of strings
std::vector<std::string> manyNames; std::vector<std::string> manyNames;
for (auto i = 0; i < 100; i++) { manyNames.push_back("john_doe"); } for (auto i = 0; i < 100; i++) {
manyNames.push_back("john_doe");
}
auto manyNamesVec = builder.CreateVectorOfStrings(manyNames); auto manyNamesVec = builder.CreateVectorOfStrings(manyNames);
TEST_EQ(false, manyNamesVec.IsNull()); TEST_EQ(false, manyNamesVec.IsNull());
auto manyNamesVec2 = auto manyNamesVec2 =
@@ -350,8 +352,7 @@ void AccessFlatBufferTest(const uint8_t *flatbuf, size_t length, bool pooled) {
} }
TEST_NOTNULL(vecofstructs->LookupByKey(0)); // test default value TEST_NOTNULL(vecofstructs->LookupByKey(0)); // test default value
TEST_NOTNULL(vecofstructs->LookupByKey(3)); TEST_NOTNULL(vecofstructs->LookupByKey(3));
TEST_EQ(static_cast<const Ability *>(nullptr), TEST_EQ(static_cast<const Ability*>(nullptr), vecofstructs->LookupByKey(5));
vecofstructs->LookupByKey(5));
} }
if (auto vec_of_stat = monster->scalar_key_sorted_tables()) { if (auto vec_of_stat = monster->scalar_key_sorted_tables()) {
@@ -801,8 +802,8 @@ void ParseAndGenerateTextTest(const std::string &tests_data_path, bool binary) {
schemafile.size()); schemafile.size());
TEST_EQ(reflection::VerifySchemaBuffer(verifier), true); TEST_EQ(reflection::VerifySchemaBuffer(verifier), true);
// auto schema = reflection::GetSchema(schemafile.c_str()); // auto schema = reflection::GetSchema(schemafile.c_str());
TEST_EQ(parser.Deserialize( TEST_EQ(
reinterpret_cast<const uint8_t *>(schemafile.c_str()), parser.Deserialize(reinterpret_cast<const uint8_t*>(schemafile.c_str()),
schemafile.size()), schemafile.size()),
true); true);
} else { } else {

View File

@@ -468,7 +468,9 @@ T TestValue(const char *json, const char *type_name,
flatbuffers::Parser parser; flatbuffers::Parser parser;
parser.builder_.ForceDefaults(true); // return defaults parser.builder_.ForceDefaults(true); // return defaults
auto check_default = json ? false : true; auto check_default = json ? false : true;
if (check_default) { parser.opts.output_default_scalars_in_json = true; } if (check_default) {
parser.opts.output_default_scalars_in_json = true;
}
// Simple schema. // Simple schema.
std::string schema = std::string(decls ? decls : "") + "\n" + std::string schema = std::string(decls ? decls : "") + "\n" +
"table X { y:" + std::string(type_name) + "table X { y:" + std::string(type_name) +
@@ -486,7 +488,9 @@ T TestValue(const char *json, const char *type_name,
parser.opts.indent_step = -1; parser.opts.indent_step = -1;
TEST_NULL(GenText(parser, parser.builder_.GetBufferPointer(), &print_back)); TEST_NULL(GenText(parser, parser.builder_.GetBufferPointer(), &print_back));
// restore value from its default // restore value from its default
if (check_default) { TEST_EQ(parser.Parse(print_back.c_str()), true); } if (check_default) {
TEST_EQ(parser.Parse(print_back.c_str()), true);
}
auto root = flatbuffers::GetRoot<flatbuffers::Table>( auto root = flatbuffers::GetRoot<flatbuffers::Table>(
parser.builder_.GetBufferPointer()); parser.builder_.GetBufferPointer());
@@ -843,9 +847,12 @@ void ParseUnionTest() {
true); true);
// Test union underlying type // Test union underlying type
const char *source = "table A {} table B {} union U : int {A, B} table C {test_union: U; test_vector_of_union: [U];}"; const char* source =
"table A {} table B {} union U : int {A, B} table C {test_union: U; "
"test_vector_of_union: [U];}";
flatbuffers::Parser parser3; flatbuffers::Parser parser3;
parser3.opts.lang_to_generate = flatbuffers::IDLOptions::kCpp | flatbuffers::IDLOptions::kTs; parser3.opts.lang_to_generate =
flatbuffers::IDLOptions::kCpp | flatbuffers::IDLOptions::kTs;
TEST_EQ(parser3.Parse(source), true); TEST_EQ(parser3.Parse(source), true);
parser3.opts.lang_to_generate &= flatbuffers::IDLOptions::kJava; parser3.opts.lang_to_generate &= flatbuffers::IDLOptions::kJava;

View File

@@ -325,8 +325,7 @@ void ParseProtoBufAsciiTest() {
// Similarly, in text output, it should omit these. // Similarly, in text output, it should omit these.
std::string text; std::string text;
auto err = auto err =
flatbuffers::GenText( flatbuffers::GenText(parser, parser.builder_.GetBufferPointer(), &text);
parser, parser.builder_.GetBufferPointer(), &text);
TEST_NULL(err); TEST_NULL(err);
TEST_EQ_STR(text.c_str(), TEST_EQ_STR(text.c_str(),
"{\n A [\n 1\n 2\n ]\n C {\n B: 2\n }\n}\n"); "{\n A [\n 1\n 2\n ]\n C {\n B: 2\n }\n}\n");

View File

@@ -1,6 +1,5 @@
#include "reflection_test.h" #include "reflection_test.h"
#include "tests/arrays_test_generated.h"
#include "flatbuffers/minireflect.h" #include "flatbuffers/minireflect.h"
#include "flatbuffers/reflection.h" #include "flatbuffers/reflection.h"
#include "flatbuffers/reflection_generated.h" #include "flatbuffers/reflection_generated.h"
@@ -8,6 +7,7 @@
#include "monster_test.h" #include "monster_test.h"
#include "monster_test_generated.h" #include "monster_test_generated.h"
#include "test_assert.h" #include "test_assert.h"
#include "tests/arrays_test_generated.h"
namespace flatbuffers { namespace flatbuffers {
namespace tests { namespace tests {
@@ -218,8 +218,7 @@ void ReflectionTest(const std::string &tests_data_path, uint8_t *flatbuf,
TEST_EQ_STR(rtestarrayofstring->Get(2)->c_str(), "hank"); TEST_EQ_STR(rtestarrayofstring->Get(2)->c_str(), "hank");
// Test integrity of all resize operations above. // Test integrity of all resize operations above.
flatbuffers::Verifier resize_verifier( flatbuffers::Verifier resize_verifier(
reinterpret_cast<const uint8_t *>(resizingbuf.data()), reinterpret_cast<const uint8_t*>(resizingbuf.data()), resizingbuf.size());
resizingbuf.size());
TEST_EQ(VerifyMonsterBuffer(resize_verifier), true); TEST_EQ(VerifyMonsterBuffer(resize_verifier), true);
// Test buffer is valid using reflection as well // Test buffer is valid using reflection as well

View File

@@ -128,8 +128,8 @@ void GenerateTableTextTest(const std::string &tests_data_path) {
TEST_EQ(abilities->Get(2)->distance(), 12); TEST_EQ(abilities->Get(2)->distance(), 12);
std::string jsongen; std::string jsongen;
auto result = GenTextFromTable(parser, monster, "MyGame.Example.Monster", auto result =
&jsongen); GenTextFromTable(parser, monster, "MyGame.Example.Monster", &jsongen);
TEST_NULL(result); TEST_NULL(result);
// Test sub table // Test sub table
const Vec3* pos = monster->pos(); const Vec3* pos = monster->pos();
@@ -141,14 +141,12 @@ void GenerateTableTextTest(const std::string &tests_data_path) {
"{x: 1.0,y: 2.0,z: 3.0,test1: 3.0,test2: \"Green\",test3: {a: 5,b: 6}}"); "{x: 1.0,y: 2.0,z: 3.0,test1: 3.0,test2: \"Green\",test3: {a: 5,b: 6}}");
const Test& test3 = pos->test3(); const Test& test3 = pos->test3();
jsongen.clear(); jsongen.clear();
result = result = GenTextFromTable(parser, &test3, "MyGame.Example.Test", &jsongen);
GenTextFromTable(parser, &test3, "MyGame.Example.Test", &jsongen);
TEST_NULL(result); TEST_NULL(result);
TEST_EQ_STR(jsongen.c_str(), "{a: 5,b: 6}"); TEST_EQ_STR(jsongen.c_str(), "{a: 5,b: 6}");
const Test* test4 = monster->test4()->Get(0); const Test* test4 = monster->test4()->Get(0);
jsongen.clear(); jsongen.clear();
result = result = GenTextFromTable(parser, test4, "MyGame.Example.Test", &jsongen);
GenTextFromTable(parser, test4, "MyGame.Example.Test", &jsongen);
TEST_NULL(result); TEST_NULL(result);
TEST_EQ_STR(jsongen.c_str(), "{a: 10,b: 20}"); TEST_EQ_STR(jsongen.c_str(), "{a: 10,b: 20}");
} }
@@ -560,8 +558,7 @@ void CreateSharedStringTest() {
// Put the strings into an array for round trip verification. // Put the strings into an array for round trip verification.
std::array<flatbuffers::Offset<flatbuffers::String>, 7> array = { std::array<flatbuffers::Offset<flatbuffers::String>, 7> array = {
one1, two, one2, onetwo, null_b1, null_c, null_b2 one1, two, one2, onetwo, null_b1, null_c, null_b2};
};
const auto vector_offset = const auto vector_offset =
builder.CreateVector<flatbuffers::Offset<flatbuffers::String>>(array); builder.CreateVector<flatbuffers::Offset<flatbuffers::String>>(array);
MonsterBuilder monster_builder(builder); MonsterBuilder monster_builder(builder);
@@ -782,7 +779,9 @@ void FixedLengthArrayTest() {
#define new DEBUG_NEW #define new DEBUG_NEW
#endif #endif
(void)ap; (void)ap;
for (size_t i = 0; i < arr_size; ++i) { TEST_EQ(non_zero_memory[i], 0); } for (size_t i = 0; i < arr_size; ++i) {
TEST_EQ(non_zero_memory[i], 0);
}
} }
#else #else
void FixedLengthArrayTest() {} void FixedLengthArrayTest() {}
@@ -801,8 +800,7 @@ void FixedLengthArrayConstructorTest() {
nested_c, int64_2), nested_c, int64_2),
MyGame::Example::NestedStruct(nested_a, MyGame::Example::TestEnum::A, MyGame::Example::NestedStruct(nested_a, MyGame::Example::TestEnum::A,
nested_c, nested_c,
std::array<int64_t, 2>{ { 12, 13 } }) } std::array<int64_t, 2>{{12, 13}})}};
};
MyGame::Example::ArrayStruct arr_struct( MyGame::Example::ArrayStruct arr_struct(
8.125, 8.125,
@@ -871,8 +869,7 @@ void FixedLengthArrayOperatorEqualTest() {
nested_c, int64_2), nested_c, int64_2),
MyGame::Example::NestedStruct(nested_a, MyGame::Example::TestEnum::B, MyGame::Example::NestedStruct(nested_a, MyGame::Example::TestEnum::B,
nested_c, nested_c,
std::array<int64_t, 2>{ { -2, -1 } }) } std::array<int64_t, 2>{{-2, -1}})}};
};
auto different = MyGame::Example::NestedStruct( auto different = MyGame::Example::NestedStruct(
nested_a, MyGame::Example::TestEnum::B, nested_cc, nested_a, MyGame::Example::TestEnum::B, nested_cc,
@@ -898,8 +895,7 @@ void FixedLengthArrayOperatorEqualTest() {
8.125, 8.125,
std::array<int32_t, 0xF>{ std::array<int32_t, 0xF>{
{1000, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}}, {1000, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}},
-17, init_d, 10, int64_2) -17, init_d, 10, int64_2)};
};
TEST_ASSERT(arr_struct[0] == arr_struct[1]); TEST_ASSERT(arr_struct[0] == arr_struct[1]);
TEST_ASSERT(arr_struct[1] != arr_struct[2]); TEST_ASSERT(arr_struct[1] != arr_struct[2]);
@@ -1139,7 +1135,8 @@ void TestEmbeddedBinarySchema(const std::string &tests_data_path) {
} }
#endif #endif
template<typename T> void EmbeddedSchemaAccessByType() { template <typename T>
void EmbeddedSchemaAccessByType() {
// Get the binary schema from the Type itself. // Get the binary schema from the Type itself.
// Verify the schema is OK. // Verify the schema is OK.
flatbuffers::Verifier verifierEmbeddedSchema( flatbuffers::Verifier verifierEmbeddedSchema(
@@ -1527,7 +1524,9 @@ void NativeInlineTableVectorTest() {
TestNativeInlineTableT unpacked; TestNativeInlineTableT unpacked;
root->UnPackTo(&unpacked); root->UnPackTo(&unpacked);
for (int i = 0; i < 10; ++i) { TEST_ASSERT(unpacked.t[i] == test.t[i]); } for (int i = 0; i < 10; ++i) {
TEST_ASSERT(unpacked.t[i] == test.t[i]);
}
TEST_ASSERT(unpacked.t == test.t); TEST_ASSERT(unpacked.t == test.t);
} }
@@ -1602,14 +1601,12 @@ void UnionUnderlyingTypeTest() {
auto offset = D::Pack(fbb, &buffer); auto offset = D::Pack(fbb, &buffer);
fbb.Finish(offset); fbb.Finish(offset);
auto *root = auto* root = flatbuffers::GetRoot<D>(fbb.GetBufferPointer());
flatbuffers::GetRoot<D>(fbb.GetBufferPointer());
DT unpacked; DT unpacked;
root->UnPackTo(&unpacked); root->UnPackTo(&unpacked);
TEST_ASSERT(unpacked.test_union == buffer.test_union); TEST_ASSERT(unpacked.test_union == buffer.test_union);
TEST_ASSERT(unpacked.test_vector_of_union == buffer.test_vector_of_union); TEST_ASSERT(unpacked.test_vector_of_union == buffer.test_vector_of_union);
} }
static void Offset64Tests() { static void Offset64Tests() {

View File

@@ -131,8 +131,7 @@ void FlatBufferBuilderTest() {
BuilderReuseTestSelector tests[4] = { BuilderReuseTestSelector tests[4] = {
REUSABLE_AFTER_RELEASE, REUSABLE_AFTER_RELEASE_RAW, REUSABLE_AFTER_RELEASE, REUSABLE_AFTER_RELEASE_RAW,
REUSABLE_AFTER_RELEASE_AND_MOVE_ASSIGN, REUSABLE_AFTER_RELEASE_AND_MOVE_ASSIGN,
REUSABLE_AFTER_RELEASE_RAW_AND_MOVE_ASSIGN REUSABLE_AFTER_RELEASE_RAW_AND_MOVE_ASSIGN};
};
BuilderReuseTests<FlatBufferBuilder, FlatBufferBuilder>::run_tests( BuilderReuseTests<FlatBufferBuilder, FlatBufferBuilder>::run_tests(
TestSelector(tests, tests + 4)); TestSelector(tests, tests + 4));

View File

@@ -93,15 +93,13 @@ void UtilConvertCase() {
cases.push_back({"single", flatbuffers::Case::kUpperCamel, "Single"}); cases.push_back({"single", flatbuffers::Case::kUpperCamel, "Single"});
cases.push_back({"Single", flatbuffers::Case::kUpperCamel, "Single"}); cases.push_back({"Single", flatbuffers::Case::kUpperCamel, "Single"});
cases.push_back({"_leading", flatbuffers::Case::kUpperCamel, "_Leading"}); cases.push_back({"_leading", flatbuffers::Case::kUpperCamel, "_Leading"});
cases.push_back( cases.push_back({"trailing_", flatbuffers::Case::kUpperCamel, "Trailing_"});
{ "trailing_", flatbuffers::Case::kUpperCamel, "Trailing_" });
cases.push_back({"double__underscore", flatbuffers::Case::kUpperCamel, cases.push_back({"double__underscore", flatbuffers::Case::kUpperCamel,
"Double_underscore"}); "Double_underscore"});
cases.push_back({"single", flatbuffers::Case::kLowerCamel, "single"}); cases.push_back({"single", flatbuffers::Case::kLowerCamel, "single"});
cases.push_back({"Single", flatbuffers::Case::kLowerCamel, "single"}); cases.push_back({"Single", flatbuffers::Case::kLowerCamel, "single"});
cases.push_back({"_leading", flatbuffers::Case::kLowerCamel, "_Leading"}); cases.push_back({"_leading", flatbuffers::Case::kLowerCamel, "_Leading"});
cases.push_back( cases.push_back({"trailing_", flatbuffers::Case::kLowerCamel, "trailing_"});
{ "trailing_", flatbuffers::Case::kLowerCamel, "trailing_" });
cases.push_back({"double__underscore", flatbuffers::Case::kLowerCamel, cases.push_back({"double__underscore", flatbuffers::Case::kLowerCamel,
"double_underscore"}); "double_underscore"});