[C++] Refactor to conform to Google C++ style guide (#5608)

* Automatic refractor of C++ headers to Google C++ style guide

* Automatic refractor of C++ source to Google C++ style guide

* Automatic refractor of C++ tests to Google C++ style guide

* Fixed clang-format issues by running clang-format twice to correct itself. Kotlin was missing clang-format on after turning it off, so it was changed,
This commit is contained in:
Derek Bailey
2019-11-07 12:22:54 -08:00
committed by Wouter van Oortmerssen
parent e837d5a296
commit f0f0efe7b8
36 changed files with 3157 additions and 3294 deletions

View File

@@ -19,6 +19,7 @@
#include <map> #include <map>
#include <sstream> #include <sstream>
#include "flatbuffers/idl.h" #include "flatbuffers/idl.h"
namespace flatbuffers { namespace flatbuffers {
@@ -95,8 +96,7 @@ class BaseGenerator {
protected: protected:
BaseGenerator(const Parser &parser, const std::string &path, BaseGenerator(const Parser &parser, const std::string &path,
const std::string &file_name, const std::string &file_name, std::string qualifying_start,
std::string qualifying_start,
std::string qualifying_separator) std::string qualifying_separator)
: parser_(parser), : parser_(parser),
path_(path), path_(path),

View File

@@ -203,11 +203,10 @@ template<typename T, typename IT> struct VectorIterator {
const uint8_t *data_; const uint8_t *data_;
}; };
template<typename Iterator> struct VectorReverseIterator : template<typename Iterator>
public std::reverse_iterator<Iterator> { struct VectorReverseIterator : public std::reverse_iterator<Iterator> {
explicit VectorReverseIterator(Iterator iter)
explicit VectorReverseIterator(Iterator iter) : : std::reverse_iterator<Iterator>(iter) {}
std::reverse_iterator<Iterator>(iter) {}
typename Iterator::value_type operator*() const { typename Iterator::value_type operator*() const {
return *(std::reverse_iterator<Iterator>::current); return *(std::reverse_iterator<Iterator>::current);
@@ -277,10 +276,14 @@ template<typename T> class Vector {
const_iterator end() const { return const_iterator(Data(), size()); } const_iterator end() const { return const_iterator(Data(), size()); }
reverse_iterator rbegin() { return reverse_iterator(end() - 1); } reverse_iterator rbegin() { return reverse_iterator(end() - 1); }
const_reverse_iterator rbegin() const { return const_reverse_iterator(end() - 1); } const_reverse_iterator rbegin() const {
return const_reverse_iterator(end() - 1);
}
reverse_iterator rend() { return reverse_iterator(begin() - 1); } reverse_iterator rend() { return reverse_iterator(begin() - 1); }
const_reverse_iterator rend() const { return const_reverse_iterator(begin() - 1); } const_reverse_iterator rend() const {
return const_reverse_iterator(begin() - 1);
}
const_iterator cbegin() const { return begin(); } const_iterator cbegin() const { return begin(); }
@@ -403,7 +406,8 @@ template<typename T> static inline size_t VectorLength(const Vector<T> *v) {
// 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 {
typedef typedef
typename flatbuffers::integral_constant<bool, flatbuffers::is_scalar<T>::value> typename flatbuffers::integral_constant<bool,
flatbuffers::is_scalar<T>::value>
scalar_tag; scalar_tag;
typedef typedef
typename flatbuffers::conditional<scalar_tag::value, T, const T *>::type typename flatbuffers::conditional<scalar_tag::value, T, const T *>::type
@@ -449,9 +453,7 @@ template<typename T, uint16_t length> class Array {
} }
// Change elements if you have a non-const pointer to this object. // Change elements if you have a non-const pointer to this object.
void Mutate(uoffset_t i, const T &val) { void Mutate(uoffset_t i, const T &val) { MutateImpl(scalar_tag(), i, val); }
MutateImpl(scalar_tag(), i, val);
}
// The raw data in little endian format. Use with care. // The raw data in little endian format. Use with care.
const uint8_t *Data() const { return data_; } const uint8_t *Data() const { return data_; }
@@ -587,9 +589,9 @@ class Allocator {
// to `new_p` of `new_size`. Only memory of size `in_use_front` and // to `new_p` of `new_size`. Only memory of size `in_use_front` and
// `in_use_back` will be copied from the front and back of the old memory // `in_use_back` will be copied from the front and back of the old memory
// allocation. // allocation.
void memcpy_downward(uint8_t *old_p, size_t old_size, void memcpy_downward(uint8_t *old_p, size_t old_size, uint8_t *new_p,
uint8_t *new_p, size_t new_size, size_t new_size, size_t in_use_back,
size_t in_use_back, size_t in_use_front) { size_t in_use_front) {
memcpy(new_p + new_size - in_use_back, old_p + old_size - in_use_back, memcpy(new_p + new_size - in_use_back, old_p + old_size - in_use_back,
in_use_back); in_use_back);
memcpy(new_p, old_p, in_use_front); memcpy(new_p, old_p, in_use_front);
@@ -603,13 +605,9 @@ class DefaultAllocator : public Allocator {
return new uint8_t[size]; return new uint8_t[size];
} }
void deallocate(uint8_t *p, size_t) FLATBUFFERS_OVERRIDE { void deallocate(uint8_t *p, size_t) FLATBUFFERS_OVERRIDE { delete[] p; }
delete[] p;
}
static void dealloc(void *p, size_t) { static void dealloc(void *p, size_t) { delete[] static_cast<uint8_t *>(p); }
delete[] static_cast<uint8_t *>(p);
}
}; };
// These functions allow for a null allocator to mean use the default allocator, // These functions allow for a null allocator to mean use the default allocator,
@@ -622,18 +620,19 @@ inline uint8_t *Allocate(Allocator *allocator, size_t size) {
} }
inline void Deallocate(Allocator *allocator, uint8_t *p, size_t size) { inline void Deallocate(Allocator *allocator, uint8_t *p, size_t size) {
if (allocator) allocator->deallocate(p, size); if (allocator)
else DefaultAllocator().deallocate(p, size); allocator->deallocate(p, size);
else
DefaultAllocator().deallocate(p, size);
} }
inline uint8_t *ReallocateDownward(Allocator *allocator, uint8_t *old_p, inline uint8_t *ReallocateDownward(Allocator *allocator, uint8_t *old_p,
size_t old_size, size_t new_size, size_t old_size, size_t new_size,
size_t in_use_back, size_t in_use_front) { size_t in_use_back, size_t in_use_front) {
return allocator return allocator ? allocator->reallocate_downward(old_p, old_size, new_size,
? allocator->reallocate_downward(old_p, old_size, new_size,
in_use_back, in_use_front) in_use_back, in_use_front)
: DefaultAllocator().reallocate_downward(old_p, old_size, new_size, : DefaultAllocator().reallocate_downward(
in_use_back, in_use_front); old_p, old_size, new_size, in_use_back, in_use_front);
} }
// DetachedBuffer is a finished flatbuffer memory region, detached from its // DetachedBuffer is a finished flatbuffer memory region, detached from its
@@ -678,8 +677,7 @@ class DetachedBuffer {
#if !defined(FLATBUFFERS_CPP98_STL) #if !defined(FLATBUFFERS_CPP98_STL)
// clang-format on // clang-format on
DetachedBuffer &operator=(DetachedBuffer &&other) { DetachedBuffer &operator=(DetachedBuffer &&other) {
if (this == &other) if (this == &other) return *this;
return *this;
destroy(); destroy();
@@ -769,10 +767,8 @@ protected:
// Essentially, this supports 2 std::vectors in a single buffer. // Essentially, this supports 2 std::vectors in a single buffer.
class vector_downward { class vector_downward {
public: public:
explicit vector_downward(size_t initial_size, explicit vector_downward(size_t initial_size, Allocator *allocator,
Allocator *allocator, bool own_allocator, size_t buffer_minalign)
bool own_allocator,
size_t buffer_minalign)
: allocator_(allocator), : allocator_(allocator),
own_allocator_(own_allocator), own_allocator_(own_allocator),
initial_size_(initial_size), initial_size_(initial_size),
@@ -840,9 +836,7 @@ class vector_downward {
clear_scratch(); clear_scratch();
} }
void clear_scratch() { void clear_scratch() { scratch_ = buf_; }
scratch_ = buf_;
}
void clear_allocator() { void clear_allocator() {
if (own_allocator_ && allocator_) { delete allocator_; } if (own_allocator_ && allocator_) { delete allocator_; }
@@ -995,8 +989,8 @@ class vector_downward {
auto old_reserved = reserved_; auto old_reserved = reserved_;
auto old_size = size(); auto old_size = size();
auto old_scratch_size = scratch_size(); auto old_scratch_size = scratch_size();
reserved_ += (std::max)(len, reserved_ +=
old_reserved ? old_reserved / 2 : initial_size_); (std::max)(len, old_reserved ? old_reserved / 2 : initial_size_);
reserved_ = (reserved_ + buffer_minalign_ - 1) & ~(buffer_minalign_ - 1); reserved_ = (reserved_ + buffer_minalign_ - 1) & ~(buffer_minalign_ - 1);
if (buf_) { if (buf_) {
buf_ = ReallocateDownward(allocator_, buf_, old_reserved, reserved_, buf_ = ReallocateDownward(allocator_, buf_, old_reserved, reserved_,
@@ -1054,11 +1048,10 @@ class FlatBufferBuilder {
/// minimum alignment upon reallocation. Only needed if you intend to store /// minimum alignment upon reallocation. Only needed if you intend to store
/// types with custom alignment AND you wish to read the buffer in-place /// types with custom alignment AND you wish to read the buffer in-place
/// directly after creation. /// directly after creation.
explicit FlatBufferBuilder(size_t initial_size = 1024, explicit FlatBufferBuilder(
Allocator *allocator = nullptr, size_t initial_size = 1024, Allocator *allocator = nullptr,
bool own_allocator = false, bool own_allocator = false,
size_t buffer_minalign = size_t buffer_minalign = AlignOf<largest_scalar_t>())
AlignOf<largest_scalar_t>())
: buf_(initial_size, allocator, own_allocator, buffer_minalign), : buf_(initial_size, allocator, own_allocator, buffer_minalign),
num_field_loc(0), num_field_loc(0),
max_voffset_(0), max_voffset_(0),
@@ -1161,8 +1154,8 @@ class FlatBufferBuilder {
/// @warning Do NOT attempt to use this FlatBufferBuilder afterwards! /// @warning Do NOT attempt to use this FlatBufferBuilder afterwards!
/// @return A `FlatBuffer` that owns the buffer and its allocator and /// @return A `FlatBuffer` that owns the buffer and its allocator and
/// behaves similar to a `unique_ptr` with a deleter. /// behaves similar to a `unique_ptr` with a deleter.
FLATBUFFERS_ATTRIBUTE(deprecated("use Release() instead")) DetachedBuffer FLATBUFFERS_ATTRIBUTE(deprecated("use Release() instead"))
ReleaseBufferPointer() { DetachedBuffer ReleaseBufferPointer() {
Finished(); Finished();
return buf_.release(); return buf_.release();
} }
@@ -1181,7 +1174,8 @@ class FlatBufferBuilder {
/// `FlatBuffer` starts. /// `FlatBuffer` starts.
/// @return A raw pointer to the start of the memory block containing /// @return A raw pointer to the start of the memory block containing
/// the serialized `FlatBuffer`. /// the serialized `FlatBuffer`.
/// @remark If the allocator is owned, it gets deleted when the destructor is called.. /// @remark If the allocator is owned, it gets deleted when the destructor is
/// called..
uint8_t *ReleaseRaw(size_t &size, size_t &offset) { uint8_t *ReleaseRaw(size_t &size, size_t &offset) {
Finished(); Finished();
return buf_.release_raw(size, offset); return buf_.release_raw(size, offset);
@@ -1210,8 +1204,9 @@ class FlatBufferBuilder {
/// @brief In order to save space, fields that are set to their default value /// @brief In order to save space, fields that are set to their default value
/// don't get serialized into the buffer. /// don't get serialized into the buffer.
/// @param[in] fd When set to `true`, always serializes default values that are set. /// @param[in] fd When set to `true`, always serializes default values that
/// Optional fields which are not set explicitly, will still not be serialized. /// are set. Optional fields which are not set explicitly, will still not be
/// serialized.
void ForceDefaults(bool fd) { force_defaults_ = fd; } void ForceDefaults(bool fd) { force_defaults_ = fd; }
/// @brief By default vtables are deduped in order to save space. /// @brief By default vtables are deduped in order to save space.
@@ -1916,12 +1911,12 @@ class FlatBufferBuilder {
} }
template<typename T> template<typename T>
Offset<Vector<const T*>> CreateUninitializedVectorOfStructs(size_t len, T **buf) { Offset<Vector<const T *>> CreateUninitializedVectorOfStructs(size_t len,
T **buf) {
return CreateUninitializedVector(len, sizeof(T), return CreateUninitializedVector(len, sizeof(T),
reinterpret_cast<uint8_t **>(buf)); reinterpret_cast<uint8_t **>(buf));
} }
// @brief Create a vector of scalar type T given as input a vector of scalar // @brief Create a vector of scalar type T given as input a vector of scalar
// type U, useful with e.g. pre "enum class" enums, or any existing scalar // type U, useful with e.g. pre "enum class" enums, or any existing scalar
// data of the wrong type. // data of the wrong type.
@@ -1971,7 +1966,6 @@ class FlatBufferBuilder {
} }
protected: protected:
// You shouldn't really be copying instances of this class. // You shouldn't really be copying instances of this class.
FlatBufferBuilder(const FlatBufferBuilder &); FlatBufferBuilder(const FlatBufferBuilder &);
FlatBufferBuilder &operator=(const FlatBufferBuilder &); FlatBufferBuilder &operator=(const FlatBufferBuilder &);
@@ -2024,8 +2018,8 @@ protected:
bool operator()(const Offset<String> &a, const Offset<String> &b) const { bool operator()(const Offset<String> &a, const Offset<String> &b) const {
auto stra = reinterpret_cast<const String *>(buf_->data_at(a.o)); auto stra = reinterpret_cast<const String *>(buf_->data_at(a.o));
auto strb = reinterpret_cast<const String *>(buf_->data_at(b.o)); auto strb = reinterpret_cast<const String *>(buf_->data_at(b.o));
return StringLessThan(stra->data(), stra->size(), return StringLessThan(stra->data(), stra->size(), strb->data(),
strb->data(), strb->size()); strb->size());
} }
const vector_downward *buf_; const vector_downward *buf_;
}; };
@@ -2089,13 +2083,15 @@ const T *GetTemporaryPointer(FlatBufferBuilder &fbb, Offset<T> offset) {
/// This function is UNDEFINED for FlatBuffers whose schema does not include /// This function is UNDEFINED for FlatBuffers whose schema does not include
/// a file_identifier (likely points at padding or the start of a the root /// a file_identifier (likely points at padding or the start of a the root
/// vtable). /// vtable).
inline const char *GetBufferIdentifier(const void *buf, bool size_prefixed = false) { inline const char *GetBufferIdentifier(const void *buf,
bool size_prefixed = false) {
return reinterpret_cast<const char *>(buf) + return reinterpret_cast<const char *>(buf) +
((size_prefixed) ? 2 * sizeof(uoffset_t) : sizeof(uoffset_t)); ((size_prefixed) ? 2 * sizeof(uoffset_t) : sizeof(uoffset_t));
} }
// Helper to see if the identifier in a buffer has the expected value. // Helper to see if the identifier in a buffer has the expected value.
inline bool BufferHasIdentifier(const void *buf, const char *identifier, bool size_prefixed = false) { inline bool BufferHasIdentifier(const void *buf, const char *identifier,
bool size_prefixed = false) {
return strncmp(GetBufferIdentifier(buf, size_prefixed), identifier, return strncmp(GetBufferIdentifier(buf, size_prefixed), identifier,
FlatBufferBuilder::kFileIdentifierLength) == 0; FlatBufferBuilder::kFileIdentifierLength) == 0;
} }
@@ -2112,8 +2108,7 @@ class Verifier FLATBUFFERS_FINAL_CLASS {
num_tables_(0), num_tables_(0),
max_tables_(_max_tables), max_tables_(_max_tables),
upper_bound_(0), upper_bound_(0),
check_alignment_(_check_alignment) check_alignment_(_check_alignment) {
{
FLATBUFFERS_ASSERT(size_ < FLATBUFFERS_MAX_BUFFER_SIZE); FLATBUFFERS_ASSERT(size_ < FLATBUFFERS_MAX_BUFFER_SIZE);
} }
@@ -2162,8 +2157,8 @@ class Verifier FLATBUFFERS_FINAL_CLASS {
return Verify(static_cast<size_t>(base - buf_) + elem_off, elem_len); return Verify(static_cast<size_t>(base - buf_) + elem_off, elem_len);
} }
template<typename T> bool Verify(const uint8_t *base, voffset_t elem_off) template<typename T>
const { bool Verify(const uint8_t *base, voffset_t elem_off) const {
return Verify(static_cast<size_t>(base - buf_) + elem_off, sizeof(T)); return Verify(static_cast<size_t>(base - buf_) + elem_off, sizeof(T));
} }
@@ -2186,8 +2181,7 @@ class Verifier FLATBUFFERS_FINAL_CLASS {
// Verify a pointer (may be NULL) to string. // Verify a pointer (may be NULL) to string.
bool VerifyString(const String *str) const { bool VerifyString(const String *str) const {
size_t end; size_t end;
return !str || return !str || (VerifyVectorOrString(reinterpret_cast<const uint8_t *>(str),
(VerifyVectorOrString(reinterpret_cast<const uint8_t *>(str),
1, &end) && 1, &end) &&
Verify(end, 1) && // Must have terminator Verify(end, 1) && // Must have terminator
Check(buf_[end] == '\0')); // Terminating byte must be 0. Check(buf_[end] == '\0')); // Terminating byte must be 0.
@@ -2230,8 +2224,8 @@ class Verifier FLATBUFFERS_FINAL_CLASS {
return true; return true;
} }
__supress_ubsan__("unsigned-integer-overflow") __supress_ubsan__("unsigned-integer-overflow") bool VerifyTableStart(
bool VerifyTableStart(const uint8_t *table) { const uint8_t *table) {
// Check the vtable offset. // Check the vtable offset.
auto tableo = static_cast<size_t>(table - buf_); auto tableo = static_cast<size_t>(table - buf_);
if (!Verify<soffset_t>(tableo)) return false; if (!Verify<soffset_t>(tableo)) return false;
@@ -2246,8 +2240,7 @@ class Verifier FLATBUFFERS_FINAL_CLASS {
template<typename T> template<typename T>
bool VerifyBufferFromStart(const char *identifier, size_t start) { bool VerifyBufferFromStart(const char *identifier, size_t start) {
if (identifier && if (identifier && (size_ < 2 * sizeof(flatbuffers::uoffset_t) ||
(size_ < 2 * sizeof(flatbuffers::uoffset_t) ||
!BufferHasIdentifier(buf_ + start, identifier))) { !BufferHasIdentifier(buf_ + start, identifier))) {
return false; return false;
} }
@@ -2496,8 +2489,8 @@ class Table {
uint8_t data_[1]; uint8_t data_[1];
}; };
template<typename T> void FlatBufferBuilder::Required(Offset<T> table, template<typename T>
voffset_t field) { void FlatBufferBuilder::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.
@@ -2544,7 +2537,9 @@ inline const uint8_t *GetBufferStartFromRootPointer(const void *root) {
} }
/// @brief This return the prefixed size of a FlatBuffer. /// @brief This return the prefixed size of a FlatBuffer.
inline uoffset_t GetPrefixedSize(const uint8_t* buf){ return ReadScalar<uoffset_t>(buf); } inline uoffset_t GetPrefixedSize(const uint8_t *buf) {
return ReadScalar<uoffset_t>(buf);
}
// Base class for native objects (FlatBuffer data de-serialized into native // Base class for native objects (FlatBuffer data de-serialized into native
// C++ data structures). // C++ data structures).

View File

@@ -17,6 +17,7 @@
#include <functional> #include <functional>
#include <limits> #include <limits>
#include <string> #include <string>
#include "flatbuffers/flatbuffers.h" #include "flatbuffers/flatbuffers.h"
#include "flatbuffers/idl.h" #include "flatbuffers/idl.h"
#include "flatbuffers/util.h" #include "flatbuffers/util.h"

View File

@@ -386,8 +386,12 @@ class Reference {
bool IsVector() const { return type_ == FBT_VECTOR || type_ == FBT_MAP; } bool IsVector() const { return type_ == FBT_VECTOR || type_ == FBT_MAP; }
bool IsUntypedVector() const { return type_ == FBT_VECTOR; } bool IsUntypedVector() const { return type_ == FBT_VECTOR; }
bool IsTypedVector() const { return flexbuffers::IsTypedVector(type_); } bool IsTypedVector() const { return flexbuffers::IsTypedVector(type_); }
bool IsFixedTypedVector() const { return flexbuffers::IsFixedTypedVector(type_); } bool IsFixedTypedVector() const {
bool IsAnyVector() const { return (IsTypedVector() || IsFixedTypedVector() || IsVector());} return flexbuffers::IsFixedTypedVector(type_);
}
bool IsAnyVector() const {
return (IsTypedVector() || IsFixedTypedVector() || IsVector());
}
bool IsMap() const { return type_ == FBT_MAP; } bool IsMap() const { return type_ == FBT_MAP; }
bool IsBlob() const { return type_ == FBT_BLOB; } bool IsBlob() const { return type_ == FBT_BLOB; }
bool AsBool() const { bool AsBool() const {
@@ -555,7 +559,8 @@ class Reference {
AppendToString<FixedTypedVector>(s, AsFixedTypedVector(), keys_quoted); AppendToString<FixedTypedVector>(s, AsFixedTypedVector(), keys_quoted);
} else if (IsBlob()) { } else if (IsBlob()) {
auto blob = AsBlob(); auto blob = AsBlob();
flatbuffers::EscapeString(reinterpret_cast<const char*>(blob.data()), blob.size(), &s, true, false); flatbuffers::EscapeString(reinterpret_cast<const char *>(blob.data()),
blob.size(), &s, true, false);
} else { } else {
s += "(?)"; s += "(?)";
} }
@@ -729,9 +734,15 @@ template<> inline int32_t Reference::As<int32_t>() const { return AsInt32(); }
template<> inline int64_t Reference::As<int64_t>() const { return AsInt64(); } template<> inline int64_t Reference::As<int64_t>() const { return AsInt64(); }
template<> inline uint8_t Reference::As<uint8_t>() const { return AsUInt8(); } template<> inline uint8_t Reference::As<uint8_t>() const { return AsUInt8(); }
template<> inline uint16_t Reference::As<uint16_t>() const { return AsUInt16(); } template<> inline uint16_t Reference::As<uint16_t>() const {
template<> inline uint32_t Reference::As<uint32_t>() const { return AsUInt32(); } return AsUInt16();
template<> inline uint64_t Reference::As<uint64_t>() const { return AsUInt64(); } }
template<> inline uint32_t Reference::As<uint32_t>() const {
return AsUInt32();
}
template<> inline uint64_t Reference::As<uint64_t>() const {
return AsUInt64();
}
template<> inline double Reference::As<double>() const { return AsDouble(); } template<> inline double Reference::As<double>() const { return AsDouble(); }
template<> inline float Reference::As<float>() const { return AsFloat(); } template<> inline float Reference::As<float>() const { return AsFloat(); }
@@ -920,9 +931,7 @@ class Builder FLATBUFFERS_FINAL_CLASS {
Bool(b); Bool(b);
} }
void IndirectInt(int64_t i) { void IndirectInt(int64_t i) { PushIndirect(i, FBT_INDIRECT_INT, WidthI(i)); }
PushIndirect(i, FBT_INDIRECT_INT, WidthI(i));
}
void IndirectInt(const char *key, int64_t i) { void IndirectInt(const char *key, int64_t i) {
Key(key); Key(key);
IndirectInt(i); IndirectInt(i);
@@ -1214,9 +1223,7 @@ class Builder FLATBUFFERS_FINAL_CLASS {
// Works on any data type. // Works on any data type.
struct Value; struct Value;
Value LastValue() { return stack_.back(); } Value LastValue() { return stack_.back(); }
void ReuseValue(Value v) { void ReuseValue(Value v) { stack_.push_back(v); }
stack_.push_back(v);
}
void ReuseValue(const char *key, Value v) { void ReuseValue(const char *key, Value v) {
Key(key); Key(key);
ReuseValue(v); ReuseValue(v);
@@ -1462,7 +1469,9 @@ class Builder FLATBUFFERS_FINAL_CLASS {
Value CreateVector(size_t start, size_t vec_len, size_t step, bool typed, Value CreateVector(size_t start, size_t vec_len, size_t step, bool typed,
bool fixed, const Value *keys = nullptr) { bool fixed, const Value *keys = nullptr) {
FLATBUFFERS_ASSERT(!fixed || typed); // typed=false, fixed=true combination is not supported. FLATBUFFERS_ASSERT(
!fixed ||
typed); // typed=false, fixed=true combination is not supported.
// Figure out smallest bit width we can store this vector with. // Figure out smallest bit width we can store this vector with.
auto bit_width = (std::max)(force_min_bit_width_, WidthU(vec_len)); auto bit_width = (std::max)(force_min_bit_width_, WidthU(vec_len));
auto prefix_elems = 1; auto prefix_elems = 1;
@@ -1542,7 +1551,8 @@ class Builder FLATBUFFERS_FINAL_CLASS {
typedef std::pair<size_t, size_t> StringOffset; typedef std::pair<size_t, size_t> StringOffset;
struct StringOffsetCompare { struct StringOffsetCompare {
explicit StringOffsetCompare(const std::vector<uint8_t> &buf) : buf_(&buf) {} explicit StringOffsetCompare(const std::vector<uint8_t> &buf)
: buf_(&buf) {}
bool operator()(const StringOffset &a, const StringOffset &b) const { bool operator()(const StringOffset &a, const StringOffset &b) const {
auto stra = reinterpret_cast<const char *>( auto stra = reinterpret_cast<const char *>(
flatbuffers::vector_data(*buf_) + a.first); flatbuffers::vector_data(*buf_) + a.first);

View File

@@ -88,8 +88,7 @@ class SliceAllocator : public Allocator {
SliceAllocator(const SliceAllocator &other) = delete; SliceAllocator(const SliceAllocator &other) = delete;
SliceAllocator &operator=(const SliceAllocator &other) = delete; SliceAllocator &operator=(const SliceAllocator &other) = delete;
SliceAllocator(SliceAllocator &&other) SliceAllocator(SliceAllocator &&other) : slice_(grpc_empty_slice()) {
: slice_(grpc_empty_slice()) {
// default-construct and swap idiom // default-construct and swap idiom
swap(other); swap(other);
} }
@@ -176,7 +175,9 @@ class MessageBuilder : private detail::SliceAllocatorMember,
} }
/// Create a MessageBuilder from a FlatBufferBuilder. /// Create a MessageBuilder from a FlatBufferBuilder.
explicit MessageBuilder(FlatBufferBuilder &&src, void (*dealloc)(void*, size_t) = &DefaultAllocator::dealloc) explicit MessageBuilder(FlatBufferBuilder &&src,
void (*dealloc)(void *,
size_t) = &DefaultAllocator::dealloc)
: FlatBufferBuilder(1024, &slice_allocator_, false) { : FlatBufferBuilder(1024, &slice_allocator_, false) {
src.Swap(*this); src.Swap(*this);
src.SwapBufAllocator(*this); src.SwapBufAllocator(*this);
@@ -184,14 +185,14 @@ class MessageBuilder : private detail::SliceAllocatorMember,
uint8_t *buf = buf_.scratch_data(); // pointer to memory uint8_t *buf = buf_.scratch_data(); // pointer to memory
size_t capacity = buf_.capacity(); // size of memory size_t capacity = buf_.capacity(); // size of memory
slice_allocator_.slice_ = grpc_slice_new_with_len(buf, capacity, dealloc); slice_allocator_.slice_ = grpc_slice_new_with_len(buf, capacity, dealloc);
} } else {
else {
slice_allocator_.slice_ = grpc_empty_slice(); slice_allocator_.slice_ = grpc_empty_slice();
} }
} }
/// Move-assign a FlatBufferBuilder to a MessageBuilder. /// Move-assign a FlatBufferBuilder to a MessageBuilder.
/// Only FlatBufferBuilder with default allocator (basically, nullptr) is supported. /// Only FlatBufferBuilder with default allocator (basically, nullptr) is
/// supported.
MessageBuilder &operator=(FlatBufferBuilder &&src) { MessageBuilder &operator=(FlatBufferBuilder &&src) {
// Move construct a temporary and swap // Move construct a temporary and swap
MessageBuilder temp(std::move(src)); MessageBuilder temp(std::move(src));
@@ -209,10 +210,11 @@ class MessageBuilder : private detail::SliceAllocatorMember,
void Swap(MessageBuilder &other) { void Swap(MessageBuilder &other) {
slice_allocator_.swap(other.slice_allocator_); slice_allocator_.swap(other.slice_allocator_);
FlatBufferBuilder::Swap(other); FlatBufferBuilder::Swap(other);
// After swapping the FlatBufferBuilder, we swap back the allocator, which restores // After swapping the FlatBufferBuilder, we swap back the allocator, which
// the original allocator back in place. This is necessary because MessageBuilder's // restores the original allocator back in place. This is necessary because
// allocator is its own member (SliceAllocatorMember). The allocator passed to // MessageBuilder's allocator is its own member (SliceAllocatorMember). The
// FlatBufferBuilder::vector_downward must point to this member. // allocator passed to FlatBufferBuilder::vector_downward must point to this
// member.
buf_.swap_allocator(other.buf_); buf_.swap_allocator(other.buf_);
} }

View File

@@ -338,13 +338,12 @@ struct StructDef : public Definition {
flatbuffers::unique_ptr<std::string> original_location; flatbuffers::unique_ptr<std::string> original_location;
}; };
struct EnumDef; struct EnumDef;
struct EnumValBuilder; struct EnumValBuilder;
struct EnumVal { struct EnumVal {
Offset<reflection::EnumVal> Serialize(FlatBufferBuilder *builder, const Parser &parser) const; Offset<reflection::EnumVal> Serialize(FlatBufferBuilder *builder,
const Parser &parser) const;
bool Deserialize(const Parser &parser, const reflection::EnumVal *val); bool Deserialize(const Parser &parser, const reflection::EnumVal *val);
@@ -480,7 +479,8 @@ inline bool EqualByName(const Type &a, const Type &b) {
} }
struct RPCCall : public Definition { struct RPCCall : public Definition {
Offset<reflection::RPCCall> Serialize(FlatBufferBuilder *builder, const Parser &parser) const; Offset<reflection::RPCCall> Serialize(FlatBufferBuilder *builder,
const Parser &parser) const;
bool Deserialize(Parser &parser, const reflection::RPCCall *call); bool Deserialize(Parser &parser, const reflection::RPCCall *call);
@@ -488,7 +488,8 @@ struct RPCCall : public Definition {
}; };
struct ServiceDef : public Definition { struct ServiceDef : public Definition {
Offset<reflection::Service> Serialize(FlatBufferBuilder *builder, const Parser &parser) const; Offset<reflection::Service> Serialize(FlatBufferBuilder *builder,
const Parser &parser) const;
bool Deserialize(Parser &parser, const reflection::Service *service); bool Deserialize(Parser &parser, const reflection::Service *service);
SymbolTable<RPCCall> calls; SymbolTable<RPCCall> calls;
@@ -722,9 +723,7 @@ class Parser : public ParserState {
source_(nullptr), source_(nullptr),
anonymous_counter(0), anonymous_counter(0),
recurse_protection_counter(0) { recurse_protection_counter(0) {
if (opts.force_defaults) { if (opts.force_defaults) { builder_.ForceDefaults(true); }
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_);
@@ -854,16 +853,19 @@ class Parser : public ParserState {
FLATBUFFERS_CHECKED_ERROR ParseVector(const Type &type, uoffset_t *ovalue, FLATBUFFERS_CHECKED_ERROR ParseVector(const Type &type, uoffset_t *ovalue,
FieldDef *field, size_t fieldn); FieldDef *field, size_t fieldn);
FLATBUFFERS_CHECKED_ERROR ParseArray(Value &array); FLATBUFFERS_CHECKED_ERROR ParseArray(Value &array);
FLATBUFFERS_CHECKED_ERROR ParseNestedFlatbuffer(Value &val, FieldDef *field, FLATBUFFERS_CHECKED_ERROR ParseNestedFlatbuffer(
size_t fieldn, Value &val, FieldDef *field, size_t fieldn,
const StructDef *parent_struct_def); const StructDef *parent_struct_def);
FLATBUFFERS_CHECKED_ERROR ParseMetaData(SymbolTable<Value> *attributes); FLATBUFFERS_CHECKED_ERROR ParseMetaData(SymbolTable<Value> *attributes);
FLATBUFFERS_CHECKED_ERROR TryTypedValue(const std::string *name, int dtoken, bool check, Value &e, FLATBUFFERS_CHECKED_ERROR TryTypedValue(const std::string *name, int dtoken,
BaseType req, bool *destmatch); bool check, Value &e, BaseType req,
bool *destmatch);
FLATBUFFERS_CHECKED_ERROR ParseHash(Value &e, FieldDef *field); FLATBUFFERS_CHECKED_ERROR ParseHash(Value &e, FieldDef *field);
FLATBUFFERS_CHECKED_ERROR TokenError(); FLATBUFFERS_CHECKED_ERROR TokenError();
FLATBUFFERS_CHECKED_ERROR ParseSingleValue(const std::string *name, Value &e, bool check_now); FLATBUFFERS_CHECKED_ERROR ParseSingleValue(const std::string *name, Value &e,
FLATBUFFERS_CHECKED_ERROR ParseEnumFromString(const Type &type, std::string *result); bool check_now);
FLATBUFFERS_CHECKED_ERROR ParseEnumFromString(const Type &type,
std::string *result);
StructDef *LookupCreateStruct(const std::string &name, StructDef *LookupCreateStruct(const std::string &name,
bool create_if_new = true, bool create_if_new = true,
bool definition = false); bool definition = false);
@@ -871,8 +873,7 @@ class Parser : public ParserState {
FLATBUFFERS_CHECKED_ERROR ParseNamespace(); FLATBUFFERS_CHECKED_ERROR ParseNamespace();
FLATBUFFERS_CHECKED_ERROR StartStruct(const std::string &name, FLATBUFFERS_CHECKED_ERROR StartStruct(const std::string &name,
StructDef **dest); StructDef **dest);
FLATBUFFERS_CHECKED_ERROR StartEnum(const std::string &name, FLATBUFFERS_CHECKED_ERROR StartEnum(const std::string &name, bool is_union,
bool is_union,
EnumDef **dest); EnumDef **dest);
FLATBUFFERS_CHECKED_ERROR ParseDecl(); FLATBUFFERS_CHECKED_ERROR ParseDecl();
FLATBUFFERS_CHECKED_ERROR ParseService(); FLATBUFFERS_CHECKED_ERROR ParseService();
@@ -896,8 +897,7 @@ class Parser : public ParserState {
const char *include_filename); const char *include_filename);
FLATBUFFERS_CHECKED_ERROR CheckClash(std::vector<FieldDef *> &fields, FLATBUFFERS_CHECKED_ERROR CheckClash(std::vector<FieldDef *> &fields,
StructDef *struct_def, StructDef *struct_def,
const char *suffix, const char *suffix, BaseType baseType);
BaseType baseType);
bool SupportsAdvancedUnionFeatures() const; bool SupportsAdvancedUnionFeatures() const;
bool SupportsAdvancedArrayFeatures() const; bool SupportsAdvancedArrayFeatures() const;
@@ -957,80 +957,66 @@ extern std::string MakeScreamingCamel(const std::string &in);
// strict_json adds "quotes" around field names if true. // strict_json adds "quotes" around field names if true.
// If the flatbuffer cannot be encoded in JSON (e.g., it contains non-UTF-8 // If the flatbuffer cannot be encoded in JSON (e.g., it contains non-UTF-8
// byte arrays in String values), returns false. // byte arrays in String values), returns false.
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 bool GenerateText(const Parser &parser, extern bool GenerateText(const Parser &parser, const void *flatbuffer,
const void *flatbuffer,
std::string *text); std::string *text);
extern bool GenerateTextFile(const Parser &parser, extern bool GenerateTextFile(const Parser &parser, const std::string &path,
const std::string &path,
const std::string &file_name); const std::string &file_name);
// Generate binary files from a given FlatBuffer, and a given Parser // Generate binary files from a given FlatBuffer, and a given Parser
// object that has been populated with the corresponding schema. // object that has been populated with the corresponding schema.
// See idl_gen_general.cpp. // See idl_gen_general.cpp.
extern bool GenerateBinary(const Parser &parser, extern bool GenerateBinary(const Parser &parser, const std::string &path,
const std::string &path,
const std::string &file_name); const std::string &file_name);
// Generate a C++ header from the definitions in the Parser object. // Generate a C++ header from the definitions in the Parser object.
// See idl_gen_cpp. // See idl_gen_cpp.
extern bool GenerateCPP(const Parser &parser, extern bool GenerateCPP(const Parser &parser, const std::string &path,
const std::string &path,
const std::string &file_name); const std::string &file_name);
extern bool GenerateDart(const Parser &parser, extern bool GenerateDart(const Parser &parser, const std::string &path,
const std::string &path,
const std::string &file_name); const std::string &file_name);
// Generate JavaScript or TypeScript code from the definitions in the Parser object. // Generate JavaScript or TypeScript code from the definitions in the Parser
// See idl_gen_js. // object. See idl_gen_js.
extern bool GenerateJSTS(const Parser &parser, extern bool GenerateJSTS(const Parser &parser, const std::string &path,
const std::string &path,
const std::string &file_name); const std::string &file_name);
// Generate Go files from the definitions in the Parser object. // Generate Go files from the definitions in the Parser object.
// See idl_gen_go.cpp. // See idl_gen_go.cpp.
extern bool GenerateGo(const Parser &parser, extern bool GenerateGo(const Parser &parser, const std::string &path,
const std::string &path,
const std::string &file_name); const std::string &file_name);
// Generate Php code from the definitions in the Parser object. // Generate Php code from the definitions in the Parser object.
// See idl_gen_php. // See idl_gen_php.
extern bool GeneratePhp(const Parser &parser, extern bool GeneratePhp(const Parser &parser, const std::string &path,
const std::string &path,
const std::string &file_name); const std::string &file_name);
// Generate Python files from the definitions in the Parser object. // Generate Python files from the definitions in the Parser object.
// See idl_gen_python.cpp. // See idl_gen_python.cpp.
extern bool GeneratePython(const Parser &parser, extern bool GeneratePython(const Parser &parser, const std::string &path,
const std::string &path,
const std::string &file_name); const std::string &file_name);
// Generate Lobster files from the definitions in the Parser object. // Generate Lobster files from the definitions in the Parser object.
// See idl_gen_lobster.cpp. // See idl_gen_lobster.cpp.
extern bool GenerateLobster(const Parser &parser, extern bool GenerateLobster(const Parser &parser, const std::string &path,
const std::string &path,
const std::string &file_name); const std::string &file_name);
// Generate Lua files from the definitions in the Parser object. // Generate Lua files from the definitions in the Parser object.
// See idl_gen_lua.cpp. // See idl_gen_lua.cpp.
extern bool GenerateLua(const Parser &parser, extern bool GenerateLua(const Parser &parser, const std::string &path,
const std::string &path,
const std::string &file_name); const std::string &file_name);
// Generate Rust files from the definitions in the Parser object. // Generate Rust files from the definitions in the Parser object.
// See idl_gen_rust.cpp. // See idl_gen_rust.cpp.
extern bool GenerateRust(const Parser &parser, extern bool GenerateRust(const Parser &parser, const std::string &path,
const std::string &path,
const std::string &file_name); const std::string &file_name);
// Generate Json schema file // Generate Json schema file
// See idl_gen_json_schema.cpp. // See idl_gen_json_schema.cpp.
extern bool GenerateJsonSchema(const Parser &parser, extern bool GenerateJsonSchema(const Parser &parser, const std::string &path,
const std::string &path,
const std::string &file_name); const std::string &file_name);
extern bool GenerateKotlin(const Parser &parser, const std::string &path, extern bool GenerateKotlin(const Parser &parser, const std::string &path,
@@ -1038,40 +1024,34 @@ extern bool GenerateKotlin(const Parser &parser, const std::string &path,
// Generate Java/C#/.. files from the definitions in the Parser object. // Generate Java/C#/.. files from the definitions in the Parser object.
// See idl_gen_general.cpp. // See idl_gen_general.cpp.
extern bool GenerateGeneral(const Parser &parser, extern bool GenerateGeneral(const Parser &parser, const std::string &path,
const std::string &path,
const std::string &file_name); const std::string &file_name);
// Generate a schema file from the internal representation, useful after // Generate a schema file from the internal representation, useful after
// parsing a .proto schema. // parsing a .proto schema.
extern std::string GenerateFBS(const Parser &parser, extern std::string GenerateFBS(const Parser &parser,
const std::string &file_name); const std::string &file_name);
extern bool GenerateFBS(const Parser &parser, extern bool GenerateFBS(const Parser &parser, const std::string &path,
const std::string &path,
const std::string &file_name); const std::string &file_name);
// Generate a make rule for the generated JavaScript or TypeScript code. // Generate a make rule for the generated JavaScript or TypeScript code.
// See idl_gen_js.cpp. // See idl_gen_js.cpp.
extern std::string JSTSMakeRule(const Parser &parser, extern std::string JSTSMakeRule(const Parser &parser, const std::string &path,
const std::string &path,
const std::string &file_name); const std::string &file_name);
// Generate a make rule for the generated C++ header. // Generate a make rule for the generated C++ header.
// See idl_gen_cpp.cpp. // See idl_gen_cpp.cpp.
extern std::string CPPMakeRule(const Parser &parser, extern std::string CPPMakeRule(const Parser &parser, const std::string &path,
const std::string &path,
const std::string &file_name); const std::string &file_name);
// Generate a make rule for the generated Dart code // Generate a make rule for the generated Dart code
// see idl_gen_dart.cpp // see idl_gen_dart.cpp
extern std::string DartMakeRule(const Parser &parser, extern std::string DartMakeRule(const Parser &parser, const std::string &path,
const std::string &path,
const std::string &file_name); const std::string &file_name);
// Generate a make rule for the generated Rust code. // Generate a make rule for the generated Rust code.
// See idl_gen_rust.cpp. // See idl_gen_rust.cpp.
extern std::string RustMakeRule(const Parser &parser, extern std::string RustMakeRule(const Parser &parser, const std::string &path,
const std::string &path,
const std::string &file_name); const std::string &file_name);
// Generate a make rule for the generated Java/C#/... files. // Generate a make rule for the generated Java/C#/... files.
@@ -1082,32 +1062,27 @@ extern std::string GeneralMakeRule(const Parser &parser,
// Generate a make rule for the generated text (JSON) files. // Generate a make rule for the generated text (JSON) files.
// See idl_gen_text.cpp. // See idl_gen_text.cpp.
extern std::string TextMakeRule(const Parser &parser, extern std::string TextMakeRule(const Parser &parser, const std::string &path,
const std::string &path,
const std::string &file_names); const std::string &file_names);
// Generate a make rule for the generated binary files. // Generate a make rule for the generated binary files.
// See idl_gen_general.cpp. // See idl_gen_general.cpp.
extern std::string BinaryMakeRule(const Parser &parser, extern std::string BinaryMakeRule(const Parser &parser, const std::string &path,
const std::string &path,
const std::string &file_name); const std::string &file_name);
// Generate GRPC Cpp interfaces. // Generate GRPC Cpp interfaces.
// See idl_gen_grpc.cpp. // See idl_gen_grpc.cpp.
bool GenerateCppGRPC(const Parser &parser, bool GenerateCppGRPC(const Parser &parser, const std::string &path,
const std::string &path,
const std::string &file_name); const std::string &file_name);
// Generate GRPC Go interfaces. // Generate GRPC Go interfaces.
// See idl_gen_grpc.cpp. // See idl_gen_grpc.cpp.
bool GenerateGoGRPC(const Parser &parser, bool GenerateGoGRPC(const Parser &parser, const std::string &path,
const std::string &path,
const std::string &file_name); const std::string &file_name);
// Generate GRPC Java classes. // Generate GRPC Java classes.
// See idl_gen_grpc.cpp // See idl_gen_grpc.cpp
bool GenerateJavaGRPC(const Parser &parser, bool GenerateJavaGRPC(const Parser &parser, const std::string &path,
const std::string &path,
const std::string &file_name); const std::string &file_name);
} // namespace flatbuffers } // namespace flatbuffers

View File

@@ -88,7 +88,8 @@ inline size_t InlineSize(ElementaryType type, const TypeTable *type_table) {
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: return static_cast<size_t>(type_table->values[type_table->num_elems]); case ST_STRUCT:
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;

View File

@@ -17,10 +17,10 @@
#ifndef FLATBUFFERS_UTIL_H_ #ifndef FLATBUFFERS_UTIL_H_
#define FLATBUFFERS_UTIL_H_ #define FLATBUFFERS_UTIL_H_
#include "flatbuffers/base.h"
#include <errno.h> #include <errno.h>
#include "flatbuffers/base.h"
#ifndef FLATBUFFERS_PREFER_PRINTF #ifndef FLATBUFFERS_PREFER_PRINTF
# include <sstream> # include <sstream>
#else // FLATBUFFERS_PREFER_PRINTF #else // FLATBUFFERS_PREFER_PRINTF

View File

@@ -15,12 +15,14 @@
*/ */
#include "flatbuffers/code_generators.h" #include "flatbuffers/code_generators.h"
#include <assert.h> #include <assert.h>
#include "flatbuffers/base.h"
#include "flatbuffers/util.h"
#include <cmath> #include <cmath>
#include "flatbuffers/base.h"
#include "flatbuffers/util.h"
#if defined(_MSC_VER) #if defined(_MSC_VER)
# pragma warning(push) # pragma warning(push)
# pragma warning(disable : 4127) // C4127: conditional expression is constant # pragma warning(disable : 4127) // C4127: conditional expression is constant

View File

@@ -402,7 +402,8 @@ int FlatCompiler::Compile(int argc, const char **argv) {
"\" matches the schema, use --raw-binary to read this file" "\" matches the schema, use --raw-binary to read this file"
" anyway."); " anyway.");
} else if (!flatbuffers::BufferHasIdentifier( } else if (!flatbuffers::BufferHasIdentifier(
contents.c_str(), parser->file_identifier_.c_str(), opts.size_prefixed)) { contents.c_str(), parser->file_identifier_.c_str(),
opts.size_prefixed)) {
Error("binary \"" + filename + Error("binary \"" + filename +
"\" does not have expected file_identifier \"" + "\" does not have expected file_identifier \"" +
parser->file_identifier_ + parser->file_identifier_ +

View File

@@ -61,13 +61,15 @@ int main(int argc, const char *argv[]) {
flatbuffers::GeneralMakeRule }, flatbuffers::GeneralMakeRule },
{ flatbuffers::GenerateJSTS, "-s", "--js", "JavaScript", true, nullptr, { flatbuffers::GenerateJSTS, "-s", "--js", "JavaScript", true, nullptr,
flatbuffers::IDLOptions::kJs, flatbuffers::IDLOptions::kJs,
"Generate JavaScript code for tables/structs", flatbuffers::JSTSMakeRule }, "Generate JavaScript code for tables/structs",
flatbuffers::JSTSMakeRule },
{ flatbuffers::GenerateDart, "-d", "--dart", "Dart", true, nullptr, { flatbuffers::GenerateDart, "-d", "--dart", "Dart", true, nullptr,
flatbuffers::IDLOptions::kDart, flatbuffers::IDLOptions::kDart,
"Generate Dart classes for tables/structs", flatbuffers::DartMakeRule }, "Generate Dart classes for tables/structs", flatbuffers::DartMakeRule },
{ flatbuffers::GenerateJSTS, "-T", "--ts", "TypeScript", true, nullptr, { flatbuffers::GenerateJSTS, "-T", "--ts", "TypeScript", true, nullptr,
flatbuffers::IDLOptions::kTs, flatbuffers::IDLOptions::kTs,
"Generate TypeScript code for tables/structs", flatbuffers::JSTSMakeRule }, "Generate TypeScript code for tables/structs",
flatbuffers::JSTSMakeRule },
{ flatbuffers::GenerateGeneral, "-n", "--csharp", "C#", true, nullptr, { flatbuffers::GenerateGeneral, "-n", "--csharp", "C#", true, nullptr,
flatbuffers::IDLOptions::kCSharp, flatbuffers::IDLOptions::kCSharp,
"Generate C# classes for tables/structs", flatbuffers::GeneralMakeRule }, "Generate C# classes for tables/structs", flatbuffers::GeneralMakeRule },
@@ -75,23 +77,22 @@ int main(int argc, const char *argv[]) {
flatbuffers::IDLOptions::kPython, flatbuffers::IDLOptions::kPython,
"Generate Python files for tables/structs", "Generate Python files for tables/structs",
flatbuffers::GeneralMakeRule }, flatbuffers::GeneralMakeRule },
{ flatbuffers::GenerateLobster, nullptr, "--lobster", "Lobster", true, nullptr, { flatbuffers::GenerateLobster, nullptr, "--lobster", "Lobster", true,
flatbuffers::IDLOptions::kLobster, nullptr, flatbuffers::IDLOptions::kLobster,
"Generate Lobster files for tables/structs", "Generate Lobster files for tables/structs",
flatbuffers::GeneralMakeRule }, flatbuffers::GeneralMakeRule },
{ flatbuffers::GenerateLua, "-l", "--lua", "Lua", true, nullptr, { flatbuffers::GenerateLua, "-l", "--lua", "Lua", true, nullptr,
flatbuffers::IDLOptions::kLua, flatbuffers::IDLOptions::kLua, "Generate Lua files for tables/structs",
"Generate Lua files for tables/structs",
flatbuffers::GeneralMakeRule }, flatbuffers::GeneralMakeRule },
{ flatbuffers::GenerateRust, "-r", "--rust", "Rust", true, nullptr, { flatbuffers::GenerateRust, "-r", "--rust", "Rust", true, nullptr,
flatbuffers::IDLOptions::kRust, flatbuffers::IDLOptions::kRust, "Generate Rust files for tables/structs",
"Generate Rust files for tables/structs",
flatbuffers::RustMakeRule }, flatbuffers::RustMakeRule },
{ flatbuffers::GeneratePhp, nullptr, "--php", "PHP", true, nullptr, { flatbuffers::GeneratePhp, nullptr, "--php", "PHP", true, nullptr,
flatbuffers::IDLOptions::kPhp, "Generate PHP files for tables/structs", flatbuffers::IDLOptions::kPhp, "Generate PHP files for tables/structs",
flatbuffers::GeneralMakeRule }, flatbuffers::GeneralMakeRule },
{ flatbuffers::GenerateKotlin, nullptr, "--kotlin", "Kotlin", true, nullptr, { flatbuffers::GenerateKotlin, nullptr, "--kotlin", "Kotlin", true, nullptr,
flatbuffers::IDLOptions::kKotlin, "Generate Kotlin classes for tables/structs", flatbuffers::IDLOptions::kKotlin,
"Generate Kotlin classes for tables/structs",
flatbuffers::GeneralMakeRule }, flatbuffers::GeneralMakeRule },
{ flatbuffers::GenerateJsonSchema, nullptr, "--jsonschema", "JsonSchema", { flatbuffers::GenerateJsonSchema, nullptr, "--jsonschema", "JsonSchema",
true, nullptr, flatbuffers::IDLOptions::kJsonSchema, true, nullptr, flatbuffers::IDLOptions::kJsonSchema,

View File

@@ -15,9 +15,11 @@
*/ */
#include <stdio.h> #include <stdio.h>
#include <iostream> #include <iostream>
#include <sstream> #include <sstream>
#include <string> #include <string>
#include "flatbuffers/hash.h" #include "flatbuffers/hash.h"
enum OutputFormat { kDecimal, kHexadecimal, kHexadecimal0x }; enum OutputFormat { kDecimal, kHexadecimal, kHexadecimal0x };

View File

@@ -16,13 +16,13 @@
// independent from idl_parser, since this code is not needed for most clients // independent from idl_parser, since this code is not needed for most clients
#include <unordered_set>
#include "flatbuffers/code_generators.h" #include "flatbuffers/code_generators.h"
#include "flatbuffers/flatbuffers.h" #include "flatbuffers/flatbuffers.h"
#include "flatbuffers/idl.h" #include "flatbuffers/idl.h"
#include "flatbuffers/util.h" #include "flatbuffers/util.h"
#include <unordered_set>
namespace flatbuffers { namespace flatbuffers {
// Pedantic warning free version of toupper(). // Pedantic warning free version of toupper().
@@ -208,9 +208,7 @@ class CppGenerator : public BaseGenerator {
for (std::size_t i = 0; i < parser_.opts.cpp_includes.size(); ++i) { for (std::size_t i = 0; i < parser_.opts.cpp_includes.size(); ++i) {
code_ += "#include \"" + parser_.opts.cpp_includes[i] + "\""; code_ += "#include \"" + parser_.opts.cpp_includes[i] + "\"";
} }
if (!parser_.opts.cpp_includes.empty()) { if (!parser_.opts.cpp_includes.empty()) { code_ += ""; }
code_ += "";
}
} }
std::string EscapeKeyword(const std::string &name) const { std::string EscapeKeyword(const std::string &name) const {
@@ -577,7 +575,9 @@ class CppGenerator : public BaseGenerator {
} }
case BASE_TYPE_UNION: case BASE_TYPE_UNION:
// fall through // fall through
default: { return "void"; } default: {
return "void";
}
} }
} }
@@ -696,7 +696,9 @@ class CppGenerator : public BaseGenerator {
case BASE_TYPE_UNION: { case BASE_TYPE_UNION: {
return type.enum_def->name + "Union"; return type.enum_def->name + "Union";
} }
default: { return GenTypeBasic(type, true); } default: {
return GenTypeBasic(type, true);
}
} }
} }
@@ -1163,7 +1165,8 @@ class CppGenerator : public BaseGenerator {
code_ += " void Set(T&& val) {"; code_ += " void Set(T&& val) {";
code_ += " using RT = typename std::remove_reference<T>::type;"; code_ += " using RT = typename std::remove_reference<T>::type;";
code_ += " Reset();"; code_ += " Reset();";
code_ += " type = {{NAME}}Traits<typename RT::TableType>::enum_value;"; code_ +=
" type = {{NAME}}Traits<typename RT::TableType>::enum_value;";
code_ += " if (type != {{NONE}}) {"; code_ += " if (type != {{NONE}}) {";
code_ += " value = new RT(std::forward<T>(val));"; code_ += " value = new RT(std::forward<T>(val));";
code_ += " }"; code_ += " }";
@@ -1276,7 +1279,8 @@ class CppGenerator : public BaseGenerator {
" auto ptr = reinterpret_cast<const {{TYPE}} *>(obj);"; " auto ptr = reinterpret_cast<const {{TYPE}} *>(obj);";
if (ev.union_type.base_type == BASE_TYPE_STRUCT) { if (ev.union_type.base_type == BASE_TYPE_STRUCT) {
if (ev.union_type.struct_def->fixed) { if (ev.union_type.struct_def->fixed) {
code_ += " return verifier.Verify<{{TYPE}}>(static_cast<const " code_ +=
" return verifier.Verify<{{TYPE}}>(static_cast<const "
"uint8_t *>(obj), 0);"; "uint8_t *>(obj), 0);";
} else { } else {
code_ += getptr; code_ += getptr;
@@ -1763,7 +1767,9 @@ class CppGenerator : public BaseGenerator {
} }
break; break;
} }
default: { break; } default: {
break;
}
} }
} }
@@ -1925,7 +1931,8 @@ class CppGenerator : public BaseGenerator {
} }
} }
if (parser_.opts.mutable_buffer && !(is_scalar && IsUnion(field.value.type))) { if (parser_.opts.mutable_buffer &&
!(is_scalar && IsUnion(field.value.type))) {
if (is_scalar) { if (is_scalar) {
const auto type = GenTypeWire(field.value.type, "", false); const auto type = GenTypeWire(field.value.type, "", false);
code_.SetValue("SET_FN", "SetField<" + type + ">"); code_.SetValue("SET_FN", "SetField<" + type + ">");
@@ -2901,8 +2908,8 @@ class CppGenerator : public BaseGenerator {
} else if (IsArray(field.value.type)) { } else if (IsArray(field.value.type)) {
auto underlying = GenTypeGet(field.value.type, "", "", "", false); auto underlying = GenTypeGet(field.value.type, "", "", "", false);
code_ += " flatbuffers::Array<" + mut_field_type + ", " + code_ += " flatbuffers::Array<" + mut_field_type + ", " +
NumToString(field.value.type.fixed_length) + NumToString(field.value.type.fixed_length) + "> *" +
"> *" + "mutable_{{FIELD_NAME}}() {"; "mutable_{{FIELD_NAME}}() {";
code_ += " return reinterpret_cast<flatbuffers::Array<" + code_ += " return reinterpret_cast<flatbuffers::Array<" +
mut_field_type + ", " + mut_field_type + ", " +
NumToString(field.value.type.fixed_length) + NumToString(field.value.type.fixed_length) +

View File

@@ -71,9 +71,7 @@ class DartGenerator : public BaseGenerator {
"// ignore_for_file: unused_import, unused_field, " "// ignore_for_file: unused_import, unused_field, "
"unused_local_variable\n\n"; "unused_local_variable\n\n";
if (!kv->first.empty()) { if (!kv->first.empty()) { code += "library " + kv->first + ";\n\n"; }
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 +
@@ -87,15 +85,19 @@ class DartGenerator : public BaseGenerator {
++kv2) { ++kv2) {
if (kv2->first != kv->first) { if (kv2->first != kv->first) {
code += "import '" + code += "import '" +
GeneratedFileName("./", file_name_ + (!kv2->first.empty() ? "_" + kv2->first : "")) + GeneratedFileName(
"./", file_name_ +
(!kv2->first.empty() ? "_" + kv2->first : "")) +
"' as " + ImportAliasName(kv2->first) + ";\n"; "' as " + ImportAliasName(kv2->first) + ";\n";
} }
} }
code += "\n"; code += "\n";
code += kv->second; code += kv->second;
if (!SaveFile( if (!SaveFile(GeneratedFileName(
GeneratedFileName(path_, file_name_ + (!kv->first.empty() ? "_" + kv->first : "")).c_str(), path_, file_name_ +
(!kv->first.empty() ? "_" + kv->first : ""))
.c_str(),
code, false)) { code, false)) {
return false; return false;
} }
@@ -117,9 +119,7 @@ class DartGenerator : public BaseGenerator {
} }
static std::string BuildNamespaceName(const Namespace &ns) { static std::string BuildNamespaceName(const Namespace &ns) {
if (ns.components.empty()) { if (ns.components.empty()) { return ""; }
return "";
}
std::stringstream sstream; std::stringstream sstream;
std::copy(ns.components.begin(), ns.components.end() - 1, std::copy(ns.components.begin(), ns.components.end() - 1,
std::ostream_iterator<std::string>(sstream, ".")); std::ostream_iterator<std::string>(sstream, "."));
@@ -139,7 +139,8 @@ class DartGenerator : public BaseGenerator {
return ret; return ret;
} }
void GenIncludeDependencies(std::string* code, const std::string& the_namespace) { void GenIncludeDependencies(std::string *code,
const std::string &the_namespace) {
for (auto it = parser_.included_files_.begin(); for (auto it = parser_.included_files_.begin();
it != parser_.included_files_.end(); ++it) { it != parser_.included_files_.end(); ++it) {
if (it->second.empty()) continue; if (it->second.empty()) continue;
@@ -147,7 +148,11 @@ class DartGenerator : public BaseGenerator {
auto noext = flatbuffers::StripExtension(it->second); auto noext = flatbuffers::StripExtension(it->second);
auto basename = flatbuffers::StripPath(noext); auto basename = flatbuffers::StripPath(noext);
*code += "import '" + GeneratedFileName("", basename + (the_namespace == "" ? "" : "_" + the_namespace)) + "';\n"; *code +=
"import '" +
GeneratedFileName(
"", basename + (the_namespace == "" ? "" : "_" + the_namespace)) +
"';\n";
} }
} }
@@ -798,7 +803,8 @@ class DartGenerator : public BaseGenerator {
} }
code += "\n : null;\n"; code += "\n : null;\n";
} else if (field.value.type.base_type == BASE_TYPE_STRING) { } else if (field.value.type.base_type == BASE_TYPE_STRING) {
code += " = fbBuilder.writeString(_" + MakeCamel(field.name, false) + ");\n"; code += " = fbBuilder.writeString(_" + MakeCamel(field.name, false) +
");\n";
} else { } else {
code += " = _" + MakeCamel(field.name, false) + code += " = _" + MakeCamel(field.name, false) +
"?.getOrCreateOffset(fbBuilder);\n"; "?.getOrCreateOffset(fbBuilder);\n";

View File

@@ -69,8 +69,7 @@ const LanguageParameters &GetLangParams(IDLOptions::Language lang) {
"Double.", "Float.", "NaN", "POSITIVE_INFINITY", "NEGATIVE_INFINITY"); "Double.", "Float.", "NaN", "POSITIVE_INFINITY", "NEGATIVE_INFINITY");
static const LanguageParameters language_parameters[] = { static const LanguageParameters language_parameters[] = {
{ { IDLOptions::kJava,
IDLOptions::kJava,
false, false,
".java", ".java",
"String", "String",
@@ -102,10 +101,8 @@ const LanguageParameters &GetLangParams(IDLOptions::Language lang) {
" *", " *",
" */", " */",
}, },
&JavaFloatGen &JavaFloatGen },
}, { IDLOptions::kCSharp,
{
IDLOptions::kCSharp,
true, true,
".cs", ".cs",
"string", "string",
@@ -136,8 +133,7 @@ const LanguageParameters &GetLangParams(IDLOptions::Language lang) {
"///", "///",
nullptr, nullptr,
}, },
&CSharpFloatGen &CSharpFloatGen },
},
}; };
if (lang == IDLOptions::kJava) { if (lang == IDLOptions::kJava) {
@@ -233,9 +229,7 @@ class GeneralGenerator : public BaseGenerator {
} }
code += lang_.class_annotation; code += lang_.class_annotation;
} }
if (parser_.opts.gen_generated) { if (parser_.opts.gen_generated) { code += lang_.generated_type_annotation; }
code += lang_.generated_type_annotation;
}
code += classcode; code += classcode;
if (!namespace_name.empty()) code += lang_.namespace_end; if (!namespace_name.empty()) code += lang_.namespace_end;
auto filename = NamespaceDir(ns) + defname + lang_.file_extension; auto filename = NamespaceDir(ns) + defname + lang_.file_extension;
@@ -440,7 +434,9 @@ class GeneralGenerator : public BaseGenerator {
return ""; return "";
} }
std::string SourceCast(const Type &type) const { return SourceCast(type, true); } std::string SourceCast(const Type &type) const {
return SourceCast(type, true);
}
std::string SourceCastBasic(const Type &type, bool castFromDest) const { std::string SourceCastBasic(const Type &type, bool castFromDest) const {
return IsScalar(type.base_type) ? SourceCast(type, castFromDest) : ""; return IsScalar(type.base_type) ? SourceCast(type, castFromDest) : "";
@@ -459,7 +455,8 @@ class GeneralGenerator : public BaseGenerator {
: value.constant; : value.constant;
} }
std::string GenDefaultValue(const FieldDef &field, bool enableLangOverrides) const { std::string GenDefaultValue(const FieldDef &field,
bool enableLangOverrides) const {
auto &value = field.value; auto &value = field.value;
if (enableLangOverrides) { if (enableLangOverrides) {
// handles both enum case and vector of enum case // handles both enum case and vector of enum case
@@ -530,15 +527,14 @@ class GeneralGenerator : public BaseGenerator {
GenComment(enum_def.doc_comment, code_ptr, &lang_.comment_config); GenComment(enum_def.doc_comment, code_ptr, &lang_.comment_config);
// In C# this indicates enumeration values can be treated as bit flags. // In C# this indicates enumeration values can be treated as bit flags.
if (lang_.language == IDLOptions::kCSharp && enum_def.attributes.Lookup("bit_flags")) { if (lang_.language == IDLOptions::kCSharp &&
enum_def.attributes.Lookup("bit_flags")) {
code += "[System.FlagsAttribute]\n"; code += "[System.FlagsAttribute]\n";
} }
if (enum_def.attributes.Lookup("private")) { if (enum_def.attributes.Lookup("private")) {
// For Java, we leave the enum unmarked to indicate package-private // For Java, we leave the enum unmarked to indicate package-private
// For C# we mark the enum as internal // For C# we mark the enum as internal
if (lang_.language == IDLOptions::kCSharp) { if (lang_.language == IDLOptions::kCSharp) { code += "internal "; }
code += "internal ";
}
} else { } else {
code += "public "; code += "public ";
} }
@@ -870,9 +866,7 @@ class GeneralGenerator : public BaseGenerator {
if (struct_def.attributes.Lookup("private")) { if (struct_def.attributes.Lookup("private")) {
// For Java, we leave the struct unmarked to indicate package-private // For Java, we leave the struct unmarked to indicate package-private
// For C# we mark the struct as internal // For C# we mark the struct as internal
if (lang_.language == IDLOptions::kCSharp) { if (lang_.language == IDLOptions::kCSharp) { code += "internal "; }
code += "internal ";
}
} else { } else {
code += "public "; code += "public ";
} }
@@ -1145,7 +1139,8 @@ class GeneralGenerator : public BaseGenerator {
if (lang_.language == IDLOptions::kCSharp) { if (lang_.language == IDLOptions::kCSharp) {
code += "() where TTable : struct, IFlatbufferObject"; code += "() where TTable : struct, IFlatbufferObject";
code += offset_prefix + "(TTable?)" + getter; code += offset_prefix + "(TTable?)" + getter;
code += "<TTable>(o + " + lang_.accessor_prefix + "bb_pos) : null"; code +=
"<TTable>(o + " + lang_.accessor_prefix + "bb_pos) : null";
} else { } else {
code += "(" + type_name + " obj)" + offset_prefix + getter; code += "(" + type_name + " obj)" + offset_prefix + getter;
code += "(obj, o + " + lang_.accessor_prefix + "bb_pos) : null"; code += "(obj, o + " + lang_.accessor_prefix + "bb_pos) : null";
@@ -1174,19 +1169,21 @@ class GeneralGenerator : public BaseGenerator {
auto &key_field = **kit; auto &key_field = **kit;
if (key_field.key) { if (key_field.key) {
auto qualified_name = WrapInNameSpace(sd); auto qualified_name = WrapInNameSpace(sd);
code += " public " + qualified_name + lang_.optional_suffix + " "; code +=
" public " + qualified_name + lang_.optional_suffix + " ";
code += MakeCamel(field.name, lang_.first_camel_upper) + "ByKey("; code += MakeCamel(field.name, lang_.first_camel_upper) + "ByKey(";
code += GenTypeNameDest(key_field.value.type) + " key)"; code += GenTypeNameDest(key_field.value.type) + " key)";
code += offset_prefix; code += offset_prefix;
code += qualified_name + ".__lookup_by_key("; code += qualified_name + ".__lookup_by_key(";
if (lang_.language == IDLOptions::kJava) if (lang_.language == IDLOptions::kJava) code += "null, ";
code += "null, ";
code += lang_.accessor_prefix + "__vector(o), key, "; code += lang_.accessor_prefix + "__vector(o), key, ";
code += lang_.accessor_prefix + "bb) : null; "; code += lang_.accessor_prefix + "bb) : null; ";
code += "}\n"; code += "}\n";
if (lang_.language == IDLOptions::kJava) { if (lang_.language == IDLOptions::kJava) {
code += " public " + qualified_name + lang_.optional_suffix + " "; code +=
code += MakeCamel(field.name, lang_.first_camel_upper) + "ByKey("; " public " + qualified_name + lang_.optional_suffix + " ";
code +=
MakeCamel(field.name, lang_.first_camel_upper) + "ByKey(";
code += qualified_name + lang_.optional_suffix + " obj, "; code += qualified_name + lang_.optional_suffix + " obj, ";
code += GenTypeNameDest(key_field.value.type) + " key)"; code += GenTypeNameDest(key_field.value.type) + " key)";
code += offset_prefix; code += offset_prefix;
@@ -1259,12 +1256,15 @@ class GeneralGenerator : public BaseGenerator {
break; break;
case IDLOptions::kCSharp: case IDLOptions::kCSharp:
code += "#if ENABLE_SPAN_T\n"; code += "#if ENABLE_SPAN_T\n";
code += " public Span<" + GenTypeBasic(field.value.type.VectorType()) + "> Get"; code += " public Span<" +
GenTypeBasic(field.value.type.VectorType()) + "> Get";
code += MakeCamel(field.name, lang_.first_camel_upper); code += MakeCamel(field.name, lang_.first_camel_upper);
code += "Bytes() { return "; code += "Bytes() { return ";
code += lang_.accessor_prefix + "__vector_as_span<"+ GenTypeBasic(field.value.type.VectorType()) +">("; code += lang_.accessor_prefix + "__vector_as_span<" +
GenTypeBasic(field.value.type.VectorType()) + ">(";
code += NumToString(field.value.offset); code += NumToString(field.value.offset);
code += ", " + NumToString(SizeOf(field.value.type.VectorType().base_type)); code += ", " + NumToString(
SizeOf(field.value.type.VectorType().base_type));
code += "); }\n"; code += "); }\n";
code += "#else\n"; code += "#else\n";
code += " public ArraySegment<byte>? Get"; code += " public ArraySegment<byte>? Get";
@@ -1596,10 +1596,10 @@ class GeneralGenerator : public BaseGenerator {
std::string size_prefix[] = { "", "SizePrefixed" }; std::string size_prefix[] = { "", "SizePrefixed" };
for (int i = 0; i < 2; ++i) { for (int i = 0; i < 2; ++i) {
code += " public static void "; code += " public static void ";
code += FunctionStart('F') + "inish" + size_prefix[i] + code +=
struct_def.name; FunctionStart('F') + "inish" + size_prefix[i] + struct_def.name;
code += "Buffer(FlatBufferBuilder builder, " + code +=
GenOffsetType(struct_def); "Buffer(FlatBufferBuilder builder, " + GenOffsetType(struct_def);
code += " offset) {"; code += " offset) {";
code += " builder." + FunctionStart('F') + "inish" + size_prefix[i] + code += " builder." + FunctionStart('F') + "inish" + size_prefix[i] +
"(offset"; "(offset";
@@ -1684,8 +1684,7 @@ class GeneralGenerator : public BaseGenerator {
// Generate a vector of structs accessor class. // Generate a vector of structs accessor class.
code += "\n"; code += "\n";
code += " "; code += " ";
if (!struct_def.attributes.Lookup("private")) if (!struct_def.attributes.Lookup("private")) code += "public ";
code += "public ";
code += "static "; code += "static ";
code += lang_.unsubclassable_decl; code += lang_.unsubclassable_decl;
code += lang_.accessor_type + "Vector" + lang_.inheritance_marker; code += lang_.accessor_type + "Vector" + lang_.inheritance_marker;

View File

@@ -151,7 +151,8 @@ class GoGenerator : public BaseGenerator {
// Construct the name of the type for this enum. // Construct the name of the type for this enum.
std::string GetEnumTypeName(const EnumDef &enum_def) { std::string GetEnumTypeName(const EnumDef &enum_def) {
return WrapInNameSpaceAndTrack(enum_def.defined_namespace, GoIdentity(enum_def.name)); return WrapInNameSpaceAndTrack(enum_def.defined_namespace,
GoIdentity(enum_def.name));
} }
// Create a type for the enum values. // Create a type for the enum values.
@@ -325,23 +326,21 @@ class GoGenerator : public BaseGenerator {
// Get the value of a struct's scalar. // Get the value of a struct's scalar.
void GetScalarFieldOfStruct(const StructDef &struct_def, void GetScalarFieldOfStruct(const StructDef &struct_def,
const FieldDef &field, const FieldDef &field, std::string *code_ptr) {
std::string *code_ptr) {
std::string &code = *code_ptr; std::string &code = *code_ptr;
std::string getter = GenGetter(field.value.type); std::string getter = GenGetter(field.value.type);
GenReceiver(struct_def, code_ptr); GenReceiver(struct_def, code_ptr);
code += " " + MakeCamel(field.name); code += " " + MakeCamel(field.name);
code += "() " + TypeName(field) + " {\n"; code += "() " + TypeName(field) + " {\n";
code += "\treturn " + CastToEnum( code += "\treturn " +
field.value.type, CastToEnum(field.value.type,
getter + "(rcv._tab.Pos + flatbuffers.UOffsetT(" + getter + "(rcv._tab.Pos + flatbuffers.UOffsetT(" +
NumToString(field.value.offset) + "))"); NumToString(field.value.offset) + "))");
code += "\n}\n"; code += "\n}\n";
} }
// Get the value of a table's scalar. // Get the value of a table's scalar.
void GetScalarFieldOfTable(const StructDef &struct_def, void GetScalarFieldOfTable(const StructDef &struct_def, const FieldDef &field,
const FieldDef &field,
std::string *code_ptr) { std::string *code_ptr) {
std::string &code = *code_ptr; std::string &code = *code_ptr;
std::string getter = GenGetter(field.value.type); std::string getter = GenGetter(field.value.type);
@@ -358,8 +357,7 @@ class GoGenerator : public BaseGenerator {
// Get a struct by initializing an existing struct. // Get a struct by initializing an existing struct.
// Specific to Struct. // Specific to Struct.
void GetStructFieldOfStruct(const StructDef &struct_def, void GetStructFieldOfStruct(const StructDef &struct_def,
const FieldDef &field, const FieldDef &field, std::string *code_ptr) {
std::string *code_ptr) {
std::string &code = *code_ptr; std::string &code = *code_ptr;
GenReceiver(struct_def, code_ptr); GenReceiver(struct_def, code_ptr);
code += " " + MakeCamel(field.name); code += " " + MakeCamel(field.name);
@@ -377,8 +375,7 @@ class GoGenerator : public BaseGenerator {
// Get a struct by initializing an existing struct. // Get a struct by initializing an existing struct.
// Specific to Table. // Specific to Table.
void GetStructFieldOfTable(const StructDef &struct_def, void GetStructFieldOfTable(const StructDef &struct_def, const FieldDef &field,
const FieldDef &field,
std::string *code_ptr) { std::string *code_ptr) {
std::string &code = *code_ptr; std::string &code = *code_ptr;
GenReceiver(struct_def, code_ptr); GenReceiver(struct_def, code_ptr);
@@ -400,8 +397,7 @@ class GoGenerator : public BaseGenerator {
} }
// Get the value of a string. // Get the value of a string.
void GetStringField(const StructDef &struct_def, void GetStringField(const StructDef &struct_def, const FieldDef &field,
const FieldDef &field,
std::string *code_ptr) { std::string *code_ptr) {
std::string &code = *code_ptr; std::string &code = *code_ptr;
GenReceiver(struct_def, code_ptr); GenReceiver(struct_def, code_ptr);
@@ -428,8 +424,7 @@ class GoGenerator : public BaseGenerator {
// Get the value of a vector's struct member. // Get the value of a vector's struct member.
void GetMemberOfVectorOfStruct(const StructDef &struct_def, void GetMemberOfVectorOfStruct(const StructDef &struct_def,
const FieldDef &field, const FieldDef &field, std::string *code_ptr) {
std::string *code_ptr) {
std::string &code = *code_ptr; std::string &code = *code_ptr;
auto vectortype = field.value.type.VectorType(); auto vectortype = field.value.type.VectorType();
@@ -461,9 +456,10 @@ class GoGenerator : public BaseGenerator {
code += "(j int) " + TypeName(field) + " "; code += "(j int) " + TypeName(field) + " ";
code += OffsetPrefix(field); code += OffsetPrefix(field);
code += "\t\ta := rcv._tab.Vector(o)\n"; code += "\t\ta := rcv._tab.Vector(o)\n";
code += "\t\treturn " + CastToEnum( code += "\t\treturn " +
field.value.type, CastToEnum(field.value.type,
GenGetter(field.value.type) + "(a + flatbuffers.UOffsetT(j*" + GenGetter(field.value.type) +
"(a + flatbuffers.UOffsetT(j*" +
NumToString(InlineSize(vectortype)) + "))"); NumToString(InlineSize(vectortype)) + "))");
code += "\n\t}\n"; code += "\n\t}\n";
if (vectortype.base_type == BASE_TYPE_STRING) { if (vectortype.base_type == BASE_TYPE_STRING) {
@@ -518,8 +514,8 @@ class GoGenerator : public BaseGenerator {
// Recursively generate struct construction statements and instert manual // Recursively generate struct construction statements and instert manual
// padding. // padding.
void StructBuilderBody(const StructDef &struct_def, void StructBuilderBody(const StructDef &struct_def, const char *nameprefix,
const char *nameprefix, std::string *code_ptr) { std::string *code_ptr) {
std::string &code = *code_ptr; std::string &code = *code_ptr;
code += "\tbuilder.Prep(" + NumToString(struct_def.minalign) + ", "; code += "\tbuilder.Prep(" + NumToString(struct_def.minalign) + ", ";
code += NumToString(struct_def.bytesize) + ")\n"; code += NumToString(struct_def.bytesize) + ")\n";
@@ -533,7 +529,9 @@ class GoGenerator : public BaseGenerator {
(nameprefix + (field.name + "_")).c_str(), code_ptr); (nameprefix + (field.name + "_")).c_str(), code_ptr);
} else { } else {
code += "\tbuilder.Prepend" + GenMethod(field) + "("; code += "\tbuilder.Prepend" + GenMethod(field) + "(";
code += CastToBaseType(field.value.type, nameprefix + GoIdentity(field.name)) + ")\n"; code += CastToBaseType(field.value.type,
nameprefix + GoIdentity(field.name)) +
")\n";
} }
} }
} }
@@ -582,8 +580,8 @@ class GoGenerator : public BaseGenerator {
} }
// Set the value of one of the members of a table's vector. // Set the value of one of the members of a table's vector.
void BuildVectorOfTable(const StructDef &struct_def, void BuildVectorOfTable(const StructDef &struct_def, const FieldDef &field,
const FieldDef &field, std::string *code_ptr) { std::string *code_ptr) {
std::string &code = *code_ptr; std::string &code = *code_ptr;
code += "func " + struct_def.name + "Start"; code += "func " + struct_def.name + "Start";
code += MakeCamel(field.name); code += MakeCamel(field.name);
@@ -612,8 +610,8 @@ class GoGenerator : public BaseGenerator {
} }
// Generate a struct field getter, conditioned on its child type(s). // Generate a struct field getter, conditioned on its child type(s).
void GenStructAccessor(const StructDef &struct_def, void GenStructAccessor(const StructDef &struct_def, const FieldDef &field,
const FieldDef &field, std::string *code_ptr) { std::string *code_ptr) {
GenComment(field.doc_comment, code_ptr, nullptr, ""); GenComment(field.doc_comment, code_ptr, nullptr, "");
if (IsScalar(field.value.type.base_type)) { if (IsScalar(field.value.type.base_type)) {
if (struct_def.fixed) { if (struct_def.fixed) {
@@ -630,7 +628,9 @@ class GoGenerator : public BaseGenerator {
GetStructFieldOfTable(struct_def, field, code_ptr); GetStructFieldOfTable(struct_def, field, code_ptr);
} }
break; break;
case BASE_TYPE_STRING: GetStringField(struct_def, field, code_ptr); break; case BASE_TYPE_STRING:
GetStringField(struct_def, 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_STRUCT) { if (vectortype.base_type == BASE_TYPE_STRUCT) {
@@ -654,8 +654,7 @@ class GoGenerator : public BaseGenerator {
// Mutate the value of a struct's scalar. // Mutate the value of a struct's scalar.
void MutateScalarFieldOfStruct(const StructDef &struct_def, void MutateScalarFieldOfStruct(const StructDef &struct_def,
const FieldDef &field, const FieldDef &field, std::string *code_ptr) {
std::string *code_ptr) {
std::string &code = *code_ptr; std::string &code = *code_ptr;
std::string type = MakeCamel(GenTypeBasic(field.value.type)); std::string type = MakeCamel(GenTypeBasic(field.value.type));
std::string setter = "rcv._tab.Mutate" + type; std::string setter = "rcv._tab.Mutate" + type;
@@ -669,8 +668,7 @@ class GoGenerator : public BaseGenerator {
// Mutate the value of a table's scalar. // Mutate the value of a table's scalar.
void MutateScalarFieldOfTable(const StructDef &struct_def, void MutateScalarFieldOfTable(const StructDef &struct_def,
const FieldDef &field, const FieldDef &field, std::string *code_ptr) {
std::string *code_ptr) {
std::string &code = *code_ptr; std::string &code = *code_ptr;
std::string type = MakeCamel(GenTypeBasic(field.value.type)); std::string type = MakeCamel(GenTypeBasic(field.value.type));
std::string setter = "rcv._tab.Mutate" + type + "Slot"; std::string setter = "rcv._tab.Mutate" + type + "Slot";
@@ -916,9 +914,9 @@ class GoGenerator : public BaseGenerator {
if (IsScalar(field.value.type.element)) { if (IsScalar(field.value.type.element)) {
code += "\t\t\tbuilder.Prepend" + code += "\t\t\tbuilder.Prepend" +
MakeCamel(GenTypeBasic(field.value.type.VectorType())) + "(" + MakeCamel(GenTypeBasic(field.value.type.VectorType())) + "(" +
CastToBaseType( CastToBaseType(field.value.type.VectorType(),
field.value.type.VectorType(), "t." + MakeCamel(field.name) + "[j]") +
"t." + MakeCamel(field.name) + "[j]") + ")\n"; ")\n";
} else if (field.value.type.element == BASE_TYPE_STRUCT && } else if (field.value.type.element == BASE_TYPE_STRUCT &&
field.value.type.struct_def->fixed) { field.value.type.struct_def->fixed) {
code += "\t\t\t" + code += "\t\t\t" +
@@ -979,8 +977,8 @@ class GoGenerator : public BaseGenerator {
code += "}\n\n"; code += "}\n\n";
} }
void GenNativeTableUnPack( void GenNativeTableUnPack(const StructDef &struct_def,
const StructDef &struct_def, std::string *code_ptr) { std::string *code_ptr) {
std::string &code = *code_ptr; std::string &code = *code_ptr;
code += "func (rcv *" + struct_def.name + ") UnPackTo(t *" + code += "func (rcv *" + struct_def.name + ") UnPackTo(t *" +
@@ -995,8 +993,8 @@ class GoGenerator : public BaseGenerator {
if (field.value.type.enum_def != nullptr && if (field.value.type.enum_def != nullptr &&
field.value.type.enum_def->is_union) field.value.type.enum_def->is_union)
continue; continue;
code += "\tt." + field_name_camel + " = rcv." + field_name_camel + code +=
"()\n"; "\tt." + field_name_camel + " = rcv." + field_name_camel + "()\n";
} else if (field.value.type.base_type == BASE_TYPE_STRING) { } else if (field.value.type.base_type == BASE_TYPE_STRING) {
code += "\tt." + field_name_camel + " = string(rcv." + code += "\tt." + field_name_camel + " = string(rcv." +
field_name_camel + "())\n"; field_name_camel + "())\n";
@@ -1084,8 +1082,8 @@ class GoGenerator : public BaseGenerator {
} }
} }
void GenNativeStructUnPack( void GenNativeStructUnPack(const StructDef &struct_def,
const StructDef &struct_def, std::string *code_ptr) { std::string *code_ptr) {
std::string &code = *code_ptr; std::string &code = *code_ptr;
code += "func (rcv *" + struct_def.name + ") UnPackTo(t *" + code += "func (rcv *" + struct_def.name + ") UnPackTo(t *" +
@@ -1137,8 +1135,7 @@ class GoGenerator : public BaseGenerator {
EndEnumNames(code_ptr); EndEnumNames(code_ptr);
BeginEnumValues(enum_def, code_ptr); BeginEnumValues(enum_def, code_ptr);
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;
EnumValueMember(enum_def, ev, max_name_length, code_ptr); EnumValueMember(enum_def, ev, max_name_length, code_ptr);
} }
@@ -1189,9 +1186,7 @@ class GoGenerator : public BaseGenerator {
} }
std::string GenTypeGet(const Type &type) { std::string GenTypeGet(const Type &type) {
if (type.enum_def != nullptr) { if (type.enum_def != nullptr) { return GetEnumTypeName(*type.enum_def); }
return GetEnumTypeName(*type.enum_def);
}
return IsScalar(type.base_type) ? GenTypeBasic(type) : GenTypePointer(type); return IsScalar(type.base_type) ? GenTypeBasic(type) : GenTypePointer(type);
} }
@@ -1221,7 +1216,8 @@ class GoGenerator : public BaseGenerator {
std::string GenConstant(const FieldDef &field) { std::string GenConstant(const FieldDef &field) {
switch (field.value.type.base_type) { switch (field.value.type.base_type) {
case BASE_TYPE_BOOL: return field.value.constant == "0" ? "false" : "true"; case BASE_TYPE_BOOL:
return field.value.constant == "0" ? "false" : "true";
default: return field.value.constant; default: return field.value.constant;
} }
} }
@@ -1248,11 +1244,11 @@ class GoGenerator : public BaseGenerator {
} else if (type.base_type == BASE_TYPE_VECTOR) { } else if (type.base_type == BASE_TYPE_VECTOR) {
return "[]" + NativeType(type.VectorType()); return "[]" + NativeType(type.VectorType());
} else if (type.base_type == BASE_TYPE_STRUCT) { } else if (type.base_type == BASE_TYPE_STRUCT) {
return "*" + WrapInNameSpaceAndTrack( return "*" + WrapInNameSpaceAndTrack(type.struct_def->defined_namespace,
type.struct_def->defined_namespace, NativeName(*type.struct_def)); NativeName(*type.struct_def));
} else if (type.base_type == BASE_TYPE_UNION) { } else if (type.base_type == BASE_TYPE_UNION) {
return "*" + WrapInNameSpaceAndTrack( return "*" + WrapInNameSpaceAndTrack(type.enum_def->defined_namespace,
type.enum_def->defined_namespace, NativeName(*type.enum_def)); NativeName(*type.enum_def));
} }
FLATBUFFERS_ASSERT(0); FLATBUFFERS_ASSERT(0);
return std::string(); return std::string();
@@ -1271,13 +1267,12 @@ class GoGenerator : public BaseGenerator {
void BeginFile(const std::string &name_space_name, const bool needs_imports, void BeginFile(const std::string &name_space_name, const bool needs_imports,
const bool is_enum, std::string *code_ptr) { const bool is_enum, std::string *code_ptr) {
std::string &code = *code_ptr; std::string &code = *code_ptr;
code = code + "// Code generated by the FlatBuffers compiler. DO NOT EDIT.\n\n"; code = code +
"// Code generated by the FlatBuffers compiler. DO NOT EDIT.\n\n";
code += "package " + name_space_name + "\n\n"; code += "package " + name_space_name + "\n\n";
if (needs_imports) { if (needs_imports) {
code += "import (\n"; code += "import (\n";
if (is_enum) { if (is_enum) { code += "\t\"strconv\"\n\n"; }
code += "\t\"strconv\"\n\n";
}
if (!parser_.opts.go_import.empty()) { if (!parser_.opts.go_import.empty()) {
code += "\tflatbuffers \"" + parser_.opts.go_import + "\"\n"; code += "\tflatbuffers \"" + parser_.opts.go_import + "\"\n";
} else { } else {
@@ -1286,17 +1281,14 @@ class GoGenerator : public BaseGenerator {
if (tracked_imported_namespaces_.size() > 0) { if (tracked_imported_namespaces_.size() > 0) {
code += "\n"; code += "\n";
for (auto it = tracked_imported_namespaces_.begin(); for (auto it = tracked_imported_namespaces_.begin();
it != tracked_imported_namespaces_.end(); it != tracked_imported_namespaces_.end(); ++it) {
++it) { code += "\t" + NamespaceImportName(*it) + " \"" +
code += "\t" + NamespaceImportName(*it) + " \"" + \
NamespaceImportPath(*it) + "\"\n"; NamespaceImportPath(*it) + "\"\n";
} }
} }
code += ")\n\n"; code += ")\n\n";
} else { } else {
if (is_enum) { if (is_enum) { code += "import \"strconv\"\n\n"; }
code += "import \"strconv\"\n\n";
}
} }
} }
@@ -1364,8 +1356,7 @@ class GoGenerator : public BaseGenerator {
static size_t MaxNameLength(const EnumDef &enum_def) { static size_t MaxNameLength(const EnumDef &enum_def) {
size_t max = 0; size_t max = 0;
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) {
max = std::max((*it)->name.length(), max); max = std::max((*it)->name.length(), max);
} }
return max; return max;

View File

@@ -20,7 +20,6 @@
#include "flatbuffers/flatbuffers.h" #include "flatbuffers/flatbuffers.h"
#include "flatbuffers/idl.h" #include "flatbuffers/idl.h"
#include "flatbuffers/util.h" #include "flatbuffers/util.h"
#include "src/compiler/cpp_generator.h" #include "src/compiler/cpp_generator.h"
#include "src/compiler/go_generator.h" #include "src/compiler/go_generator.h"
#include "src/compiler/java_generator.h" #include "src/compiler/java_generator.h"
@@ -35,9 +34,7 @@ namespace flatbuffers {
class FlatBufMethod : public grpc_generator::Method { class FlatBufMethod : public grpc_generator::Method {
public: public:
enum Streaming { enum Streaming { kNone, kClient, kServer, kBiDi };
kNone, kClient, kServer, kBiDi
};
FlatBufMethod(const RPCCall *method) : method_(method) { FlatBufMethod(const RPCCall *method) : method_(method) {
streaming_ = kNone; streaming_ = kNone;
@@ -182,9 +179,7 @@ class FlatBufPrinter : public grpc_generator::Printer {
class FlatBufFile : public grpc_generator::File { class FlatBufFile : public grpc_generator::File {
public: public:
enum Language { enum Language { kLanguageGo, kLanguageCpp, kLanguageJava };
kLanguageGo, kLanguageCpp, kLanguageJava
};
FlatBufFile(const Parser &parser, const std::string &file_name, FlatBufFile(const Parser &parser, const std::string &file_name,
Language language) Language language)
@@ -270,7 +265,8 @@ class GoGRPCGenerator : public flatbuffers::BaseGenerator {
auto service = file.service(i); auto service = file.service(i);
const Definition *def = parser_.services_.vec[i]; const Definition *def = parser_.services_.vec[i];
p.package_name = LastNamespacePart(*(def->defined_namespace)); p.package_name = LastNamespacePart(*(def->defined_namespace));
p.service_prefix = def->defined_namespace->GetFullyQualifiedName(""); // file.package(); p.service_prefix =
def->defined_namespace->GetFullyQualifiedName(""); // file.package();
std::string output = std::string output =
grpc_go_generator::GenerateServiceSource(&file, service.get(), &p); grpc_go_generator::GenerateServiceSource(&file, service.get(), &p);
std::string filename = std::string filename =

View File

@@ -127,9 +127,7 @@ class JsTsGenerator : public BaseGenerator {
const auto &file = *it; const auto &file = *it;
const auto basename = const auto basename =
flatbuffers::StripPath(flatbuffers::StripExtension(file)); flatbuffers::StripPath(flatbuffers::StripExtension(file));
if (basename != file_name_) { if (basename != file_name_) { code += GenPrefixedImport(file, basename); }
code += GenPrefixedImport(file, basename);
}
} }
} }
@@ -309,14 +307,12 @@ class JsTsGenerator : public BaseGenerator {
result += " " + type_name; result += " " + type_name;
break; break;
} }
default: { result += " {" + type_name + "}"; } default: {
result += " {" + type_name + "}";
} }
if (!arg_name.empty()) {
result += " " + arg_name;
}
if (include_newline) {
result += "\n";
} }
if (!arg_name.empty()) { result += " " + arg_name; }
if (include_newline) { result += "\n"; }
return result; return result;
} }
@@ -605,7 +601,8 @@ class JsTsGenerator : public BaseGenerator {
} }
void GenerateRootAccessor(StructDef &struct_def, std::string *code_ptr, void GenerateRootAccessor(StructDef &struct_def, std::string *code_ptr,
std::string &code, std::string &object_name, bool size_prefixed) { std::string &code, std::string &object_name,
bool size_prefixed) {
if (!struct_def.fixed) { if (!struct_def.fixed) {
GenDocComment(code_ptr, GenDocComment(code_ptr,
GenTypeAnnotation(kParam, "flatbuffers.ByteBuffer", "bb") + GenTypeAnnotation(kParam, "flatbuffers.ByteBuffer", "bb") +
@@ -613,11 +610,13 @@ class JsTsGenerator : public BaseGenerator {
GenTypeAnnotation(kReturns, object_name, "", false)); GenTypeAnnotation(kReturns, object_name, "", false));
std::string sizePrefixed("SizePrefixed"); std::string sizePrefixed("SizePrefixed");
if (lang_.language == IDLOptions::kTs) { if (lang_.language == IDLOptions::kTs) {
code += "static get" + (size_prefixed ? sizePrefixed : "") + "Root" + Verbose(struct_def, "As"); code += "static get" + (size_prefixed ? sizePrefixed : "") + "Root" +
Verbose(struct_def, "As");
code += "(bb:flatbuffers.ByteBuffer, obj?:" + object_name + code += "(bb:flatbuffers.ByteBuffer, obj?:" + object_name +
"):" + object_name + " {\n"; "):" + object_name + " {\n";
} else { } else {
code += object_name + ".get" + (size_prefixed ? sizePrefixed : "") + "Root" + Verbose(struct_def, "As"); code += object_name + ".get" + (size_prefixed ? sizePrefixed : "") +
"Root" + Verbose(struct_def, "As");
code += " = function(bb, obj) {\n"; code += " = function(bb, obj) {\n";
} }
code += " return (obj || new " + object_name; code += " return (obj || new " + object_name;
@@ -627,21 +626,22 @@ class JsTsGenerator : public BaseGenerator {
} }
void GenerateFinisher(StructDef &struct_def, std::string *code_ptr, void GenerateFinisher(StructDef &struct_def, std::string *code_ptr,
std::string &code, std::string &object_name, bool size_prefixed) { std::string &code, std::string &object_name,
bool size_prefixed) {
if (parser_.root_struct_def_ == &struct_def) { if (parser_.root_struct_def_ == &struct_def) {
std::string sizePrefixed("SizePrefixed"); std::string sizePrefixed("SizePrefixed");
GenDocComment( GenDocComment(
code_ptr, code_ptr,
GenTypeAnnotation(kParam, "flatbuffers.Builder", "builder") + GenTypeAnnotation(kParam, "flatbuffers.Builder", "builder") +
GenTypeAnnotation(kParam, "flatbuffers.Offset", "offset", GenTypeAnnotation(kParam, "flatbuffers.Offset", "offset", false));
false));
if (lang_.language == IDLOptions::kTs) { if (lang_.language == IDLOptions::kTs) {
code += "static finish" + (size_prefixed ? sizePrefixed : "") + Verbose(struct_def) + "Buffer"; code += "static finish" + (size_prefixed ? sizePrefixed : "") +
code += Verbose(struct_def) + "Buffer";
"(builder:flatbuffers.Builder, offset:flatbuffers.Offset) {\n"; code += "(builder:flatbuffers.Builder, offset:flatbuffers.Offset) {\n";
} else { } else {
code += object_name + ".finish" + (size_prefixed ? sizePrefixed : "") + Verbose(struct_def) + "Buffer"; code += object_name + ".finish" + (size_prefixed ? sizePrefixed : "") +
Verbose(struct_def) + "Buffer";
code += " = function(builder, offset) {\n"; code += " = function(builder, offset) {\n";
} }
@@ -650,9 +650,7 @@ class JsTsGenerator : public BaseGenerator {
code += ", '" + parser_.file_identifier_ + "'"; code += ", '" + parser_.file_identifier_ + "'";
} }
if (size_prefixed) { if (size_prefixed) {
if (parser_.file_identifier_.empty()) { if (parser_.file_identifier_.empty()) { code += ", undefined"; }
code += ", undefined";
}
code += ", true"; code += ", true";
} }
code += ");\n"; code += ");\n";
@@ -682,7 +680,8 @@ class JsTsGenerator : public BaseGenerator {
code += " {\n"; code += " {\n";
if (lang_.language != IDLOptions::kTs) { if (lang_.language != IDLOptions::kTs) {
code += " /**\n"; code += " /**\n";
code += " * " + GenTypeAnnotation(kType, "flatbuffers.ByteBuffer", ""); code +=
" * " + GenTypeAnnotation(kType, "flatbuffers.ByteBuffer", "");
code += " */\n"; code += " */\n";
} }
code += " bb: flatbuffers.ByteBuffer|null = null;\n"; code += " bb: flatbuffers.ByteBuffer|null = null;\n";
@@ -752,8 +751,7 @@ class JsTsGenerator : public BaseGenerator {
// Generate the identifier check method // Generate the identifier check method
if (!struct_def.fixed && parser_.root_struct_def_ == &struct_def && if (!struct_def.fixed && parser_.root_struct_def_ == &struct_def &&
!parser_.file_identifier_.empty()) { !parser_.file_identifier_.empty()) {
GenDocComment( GenDocComment(code_ptr,
code_ptr,
GenTypeAnnotation(kParam, "flatbuffers.ByteBuffer", "bb") + GenTypeAnnotation(kParam, "flatbuffers.ByteBuffer", "bb") +
GenTypeAnnotation(kReturns, "boolean", "", false)); GenTypeAnnotation(kReturns, "boolean", "", false));
if (lang_.language == IDLOptions::kTs) { if (lang_.language == IDLOptions::kTs) {
@@ -872,7 +870,8 @@ class JsTsGenerator : public BaseGenerator {
code += ", " + GenBBAccess() + ") : null;\n"; code += ", " + GenBBAccess() + ") : null;\n";
} }
if (lang_.language == IDLOptions::kTs && !parser_.opts.generate_all) { if (lang_.language == IDLOptions::kTs &&
!parser_.opts.generate_all) {
imported_files.insert(field.value.type.struct_def->file); imported_files.insert(field.value.type.struct_def->file);
} }
@@ -1290,8 +1289,7 @@ class JsTsGenerator : 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) if (field.deprecated) continue;
continue;
paramDoc += paramDoc +=
GenTypeAnnotation(kParam, GetArgType(field), GetArgName(field)); GenTypeAnnotation(kParam, GetArgType(field), GetArgName(field));
} }
@@ -1311,8 +1309,7 @@ class JsTsGenerator : 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) if (field.deprecated) continue;
continue;
if (lang_.language == IDLOptions::kTs) { if (lang_.language == IDLOptions::kTs) {
code += ", " + GetArgName(field) + ":" + GetArgType(field); code += ", " + GetArgName(field) + ":" + GetArgType(field);
@@ -1336,8 +1333,7 @@ class JsTsGenerator : 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) if (field.deprecated) continue;
continue;
code += " " + methodPrefix + ".add" + MakeCamel(field.name) + "("; code += " " + methodPrefix + ".add" + MakeCamel(field.name) + "(";
code += "builder, " + GetArgName(field) + ");\n"; code += "builder, " + GetArgName(field) + ");\n";
@@ -1346,14 +1342,11 @@ class JsTsGenerator : public BaseGenerator {
code += " return " + methodPrefix + ".end" + Verbose(struct_def) + code += " return " + methodPrefix + ".end" + Verbose(struct_def) +
"(builder);\n"; "(builder);\n";
code += "}\n"; code += "}\n";
if (lang_.language == IDLOptions::kJs) if (lang_.language == IDLOptions::kJs) code += "\n";
code += "\n";
} }
if (lang_.language == IDLOptions::kTs) { if (lang_.language == IDLOptions::kTs) {
if (!object_namespace.empty()) { if (!object_namespace.empty()) { code += "}\n"; }
code += "}\n";
}
code += "}\n"; code += "}\n";
} }
} }
@@ -1372,9 +1365,7 @@ class JsTsGenerator : public BaseGenerator {
return argname; return argname;
} }
std::string Verbose(const StructDef &struct_def, std::string Verbose(const StructDef &struct_def, const char *prefix = "") {
const char* prefix = "")
{
return parser_.opts.js_ts_short_names ? "" : prefix + struct_def.name; return parser_.opts.js_ts_short_names ? "" : prefix + struct_def.name;
} }
}; };

View File

@@ -15,6 +15,7 @@
*/ */
#include <iostream> #include <iostream>
#include "flatbuffers/code_generators.h" #include "flatbuffers/code_generators.h"
#include "flatbuffers/idl.h" #include "flatbuffers/idl.h"
#include "flatbuffers/util.h" #include "flatbuffers/util.h"

View File

@@ -18,6 +18,7 @@
#include <functional> #include <functional>
#include <unordered_set> #include <unordered_set>
#include "flatbuffers/code_generators.h" #include "flatbuffers/code_generators.h"
#include "flatbuffers/flatbuffers.h" #include "flatbuffers/flatbuffers.h"
#include "flatbuffers/idl.h" #include "flatbuffers/idl.h"
@@ -42,14 +43,13 @@ static const char *keywords[] = {
"val", "var", "fun", "for", "null", "true", "val", "var", "fun", "for", "null", "true",
"false", "is", "in", "throw", "return", "break", "false", "is", "in", "throw", "return", "break",
"continue", "object", "if", "try", "else", "while", "continue", "object", "if", "try", "else", "while",
"do", "when", "interface", "typeof", "Any", "Character"}; "do", "when", "interface", "typeof", "Any", "Character"
};
// Escape Keywords // Escape Keywords
static std::string Esc(const std::string &name) { static std::string Esc(const std::string &name) {
for (size_t i = 0; i < sizeof(keywords) / sizeof(keywords[0]); i++) { for (size_t i = 0; i < sizeof(keywords) / sizeof(keywords[0]); i++) {
if (name == keywords[i]) { if (name == keywords[i]) { return MakeCamel(name + "_", false); }
return MakeCamel(name + "_", false);
}
} }
return MakeCamel(name, false); return MakeCamel(name, false);
@@ -145,21 +145,17 @@ class KotlinGenerator : public BaseGenerator {
#KTYPE, #KTYPE,
FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD) FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD)
#undef FLATBUFFERS_TD #undef FLATBUFFERS_TD
// clang-format on
}; };
return kotlin_typename[type]; return kotlin_typename[type];
} }
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: case BASE_TYPE_STRING: return "String";
return "String"; case BASE_TYPE_VECTOR: return GenTypeGet(type.VectorType());
case BASE_TYPE_VECTOR: case BASE_TYPE_STRUCT: return WrapInNameSpace(*type.struct_def);
return GenTypeGet(type.VectorType()); default: return "Table";
case BASE_TYPE_STRUCT:
return WrapInNameSpace(*type.struct_def);
default:
return "Table";
} }
} }
@@ -177,7 +173,6 @@ class KotlinGenerator : public BaseGenerator {
: value.constant; : value.constant;
} }
// Generate default values to compare against a default value when // Generate default values to compare against a default value when
// `force_defaults` is `false`. // `force_defaults` is `false`.
// Main differences are: // Main differences are:
@@ -192,12 +187,10 @@ class KotlinGenerator : public BaseGenerator {
} }
} }
// Guarantee all values are doubles // Guarantee all values are doubles
if (out.back() == 'f') if (out.back() == 'f') out.pop_back();
out.pop_back();
return out; return out;
} }
// FlatBufferBuilder only store signed types, so this function // FlatBufferBuilder only store signed types, so this function
// returns a cast for unsigned values // returns a cast for unsigned values
std::string GenFBBValueCast(const FieldDef &field) const { std::string GenFBBValueCast(const FieldDef &field) const {
@@ -213,8 +206,7 @@ class KotlinGenerator : public BaseGenerator {
auto base_type = field.value.type.base_type; auto base_type = field.value.type.base_type;
if (IsFloat(base_type)) { if (IsFloat(base_type)) {
auto val = KotlinFloatGen.GenFloatConstant(field); auto val = KotlinFloatGen.GenFloatConstant(field);
if (base_type == BASE_TYPE_DOUBLE && if (base_type == BASE_TYPE_DOUBLE && val.back() == 'f') {
val.back() == 'f') {
val.pop_back(); val.pop_back();
} }
return val; return val;
@@ -266,8 +258,7 @@ class KotlinGenerator : public BaseGenerator {
// "too sparse". Change at will. // "too sparse". Change at will.
static const uint64_t kMaxSparseness = 5; static const uint64_t kMaxSparseness = 5;
if (range / static_cast<uint64_t>(enum_def.size()) < kMaxSparseness) { if (range / static_cast<uint64_t>(enum_def.size()) < kMaxSparseness) {
GeneratePropertyOneLine(writer, "names", "Array<String>", GeneratePropertyOneLine(writer, "names", "Array<String>", [&]() {
[&](){
writer += "arrayOf(\\"; writer += "arrayOf(\\";
auto val = enum_def.Vals().front(); auto val = enum_def.Vals().front();
for (auto it = vals.begin(); it != vals.end(); ++it) { for (auto it = vals.begin(); it != vals.end(); ++it) {
@@ -276,9 +267,7 @@ class KotlinGenerator : public BaseGenerator {
writer += "\"\", \\"; writer += "\"\", \\";
val = ev; val = ev;
writer += "\"" + (*it)->name + "\"\\"; writer += "\"" + (*it)->name + "\"\\";
if (it+1 != vals.end()) { if (it + 1 != vals.end()) { writer += ", \\"; }
writer += ", \\";
}
} }
writer += ")"; writer += ")";
}); });
@@ -295,36 +284,27 @@ class KotlinGenerator : 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 ByteBufferGetter(const Type &type, std::string bb_var_name) const { std::string ByteBufferGetter(const Type &type,
std::string bb_var_name) const {
switch (type.base_type) { switch (type.base_type) {
case BASE_TYPE_STRING: case BASE_TYPE_STRING: return "__string";
return "__string"; case BASE_TYPE_STRUCT: return "__struct";
case BASE_TYPE_STRUCT: case BASE_TYPE_UNION: return "__union";
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: case BASE_TYPE_UINT: return bb_var_name + ".getInt";
return bb_var_name + ".getInt";
case BASE_TYPE_SHORT: case BASE_TYPE_SHORT:
case BASE_TYPE_USHORT: case BASE_TYPE_USHORT: return bb_var_name + ".getShort";
return bb_var_name + ".getShort";
case BASE_TYPE_ULONG: case BASE_TYPE_ULONG:
case BASE_TYPE_LONG: case BASE_TYPE_LONG: return bb_var_name + ".getLong";
return bb_var_name + ".getLong"; case BASE_TYPE_FLOAT: return bb_var_name + ".getFloat";
case BASE_TYPE_FLOAT: case BASE_TYPE_DOUBLE: return bb_var_name + ".getDouble";
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: case BASE_TYPE_UTYPE: return bb_var_name + ".get";
return bb_var_name + ".get"; case BASE_TYPE_BOOL: return "0.toByte() != " + bb_var_name + ".get";
case BASE_TYPE_BOOL:
return "0.toByte() != " + bb_var_name + ".get";
default: default:
return bb_var_name + ".get" + MakeCamel(GenTypeBasic(type.base_type)); return bb_var_name + ".get" + MakeCamel(GenTypeBasic(type.base_type));
} }
@@ -334,26 +314,19 @@ 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: case BASE_TYPE_UINT: return "bb.putInt";
return "bb.putInt";
case BASE_TYPE_SHORT: case BASE_TYPE_SHORT:
case BASE_TYPE_USHORT: case BASE_TYPE_USHORT: return "bb.putShort";
return "bb.putShort";
case BASE_TYPE_ULONG: case BASE_TYPE_ULONG:
case BASE_TYPE_LONG: case BASE_TYPE_LONG: return "bb.putLong";
return "bb.putLong"; case BASE_TYPE_FLOAT: return "bb.putFloat";
case BASE_TYPE_FLOAT: case BASE_TYPE_DOUBLE: return "bb.putDouble";
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: case BASE_TYPE_UTYPE: return "bb.put";
return "bb.put"; default: return "bb.put" + MakeCamel(GenTypeBasic(type.base_type));
default:
return "bb.put" + MakeCamel(GenTypeBasic(type.base_type));
} }
} }
return ""; return "";
@@ -364,8 +337,8 @@ class KotlinGenerator : public BaseGenerator {
const std::string &bb_var_name, const std::string &bb_var_name,
const char *num = nullptr) const { const char *num = nullptr) const {
auto type = key_field->value.type; auto type = key_field->value.type;
return ByteBufferGetter(type, bb_var_name) + "(" + GenOffsetGetter(key_field, num) + ")"; return ByteBufferGetter(type, bb_var_name) + "(" +
GenOffsetGetter(key_field, num) + ")";
} }
// Returns the method name for use with add/put calls. // Returns the method name for use with add/put calls.
@@ -417,8 +390,7 @@ class KotlinGenerator : public BaseGenerator {
(nameprefix + (field.name + "_")).c_str()); (nameprefix + (field.name + "_")).c_str());
} else { } else {
writer.SetValue("type", GenMethod(field.value.type)); writer.SetValue("type", GenMethod(field.value.type));
writer.SetValue("argname", nameprefix + writer.SetValue("argname", nameprefix + MakeCamel(field.name, false));
MakeCamel(field.name, false));
writer.SetValue("cast", CastToSigned(field.value.type)); writer.SetValue("cast", CastToSigned(field.value.type));
writer += "builder.put{{type}}({{argname}}{{cast}})"; writer += "builder.put{{type}}({{argname}}{{cast}})";
} }
@@ -433,8 +405,8 @@ class KotlinGenerator : public BaseGenerator {
std::string GenOffsetGetter(flatbuffers::FieldDef *key_field, std::string GenOffsetGetter(flatbuffers::FieldDef *key_field,
const char *num = nullptr) const { const char *num = nullptr) const {
std::string key_offset = "__offset(" + std::string key_offset =
NumToString(key_field->value.offset) + ", "; "__offset(" + NumToString(key_field->value.offset) + ", ";
if (num) { if (num) {
key_offset += num; key_offset += num;
key_offset += ", _bb)"; key_offset += ", _bb)";
@@ -463,9 +435,8 @@ class KotlinGenerator : public BaseGenerator {
{ {
// Generate the __init() method that sets the field in a pre-existing // Generate the __init() method that sets the field in a pre-existing
// accessor object. This is to allow object reuse. // accessor object. This is to allow object reuse.
GenerateFun(writer, "__init", "_i: Int, _bb: ByteBuffer", "", [&]() { GenerateFun(writer, "__init", "_i: Int, _bb: ByteBuffer", "",
writer += "__reset(_i, _bb)"; [&]() { writer += "__reset(_i, _bb)"; });
});
// Generate assign method // Generate assign method
GenerateFun(writer, "__assign", "_i: Int, _bb: ByteBuffer", GenerateFun(writer, "__assign", "_i: Int, _bb: ByteBuffer",
@@ -479,7 +450,6 @@ class KotlinGenerator : public BaseGenerator {
// Generate Static Fields // Generate Static Fields
GenerateCompanionObject(writer, [&]() { GenerateCompanionObject(writer, [&]() {
if (!struct_def.fixed) { if (!struct_def.fixed) {
FieldDef *key_field = nullptr; FieldDef *key_field = nullptr;
@@ -518,12 +488,8 @@ class KotlinGenerator : public BaseGenerator {
GenerateEndStructMethod(struct_def, writer); GenerateEndStructMethod(struct_def, writer);
auto file_identifier = parser_.file_identifier_; auto file_identifier = parser_.file_identifier_;
if (parser_.root_struct_def_ == &struct_def) { if (parser_.root_struct_def_ == &struct_def) {
GenerateFinishStructBuffer(struct_def, GenerateFinishStructBuffer(struct_def, file_identifier, writer);
file_identifier, GenerateFinishSizePrefixed(struct_def, file_identifier, writer);
writer);
GenerateFinishSizePrefixed(struct_def,
file_identifier,
writer);
} }
if (struct_def.has_key) { if (struct_def.has_key) {
@@ -544,7 +510,8 @@ class KotlinGenerator : public BaseGenerator {
void GenerateLookupByKey(FieldDef *key_field, StructDef &struct_def, void GenerateLookupByKey(FieldDef *key_field, StructDef &struct_def,
CodeWriter &writer) const { CodeWriter &writer) const {
std::stringstream params; std::stringstream params;
params << "obj: " << Esc(struct_def.name) << "?" << ", "; params << "obj: " << Esc(struct_def.name) << "?"
<< ", ";
params << "vectorLocation: Int, "; params << "vectorLocation: Int, ";
params << "key: " << GenTypeGet(key_field->value.type) << ", "; params << "key: " << GenTypeGet(key_field->value.type) << ", ";
params << "bb: ByteBuffer"; params << "bb: ByteBuffer";
@@ -553,7 +520,8 @@ class KotlinGenerator : public BaseGenerator {
auto base_type = key_field->value.type.base_type; auto base_type = key_field->value.type.base_type;
writer.SetValue("struct_name", Esc(struct_def.name)); writer.SetValue("struct_name", Esc(struct_def.name));
if (base_type == BASE_TYPE_STRING) { if (base_type == BASE_TYPE_STRING) {
writer += "val byteKey = key." writer +=
"val byteKey = key."
"toByteArray(Table.UTF8_CHARSET.get()!!)"; "toByteArray(Table.UTF8_CHARSET.get()!!)";
} }
writer += "var span = bb.getInt(vectorLocation - 4)"; writer += "var span = bb.getInt(vectorLocation - 4)";
@@ -561,7 +529,8 @@ class KotlinGenerator : public BaseGenerator {
writer += "while (span != 0) {"; writer += "while (span != 0) {";
writer.IncrementIdentLevel(); writer.IncrementIdentLevel();
writer += "var middle = span / 2"; writer += "var middle = span / 2";
writer += "val tableOffset = __indirect(vector" writer +=
"val tableOffset = __indirect(vector"
"Location + 4 * (start + middle), bb)"; "Location + 4 * (start + middle), bb)";
if (key_field->value.type.base_type == BASE_TYPE_STRING) { if (key_field->value.type.base_type == BASE_TYPE_STRING) {
writer += "val comp = compareStrings(\\"; writer += "val comp = compareStrings(\\";
@@ -594,10 +563,8 @@ class KotlinGenerator : public BaseGenerator {
writer += "}"; // end while writer += "}"; // end while
writer += "return null"; writer += "return null";
}; };
GenerateFun(writer, "__lookup_by_key", GenerateFun(writer, "__lookup_by_key", params.str(),
params.str(), Esc(struct_def.name) + "?", statements);
Esc(struct_def.name) + "?",
statements);
} }
void GenerateFinishSizePrefixed(StructDef &struct_def, void GenerateFinishSizePrefixed(StructDef &struct_def,
@@ -616,12 +583,12 @@ class KotlinGenerator : public BaseGenerator {
auto id = identifier.length() > 0 ? ", \"" + identifier + "\"" : ""; auto id = identifier.length() > 0 ? ", \"" + identifier + "\"" : "";
auto params = "builder: FlatBufferBuilder, offset: Int"; auto params = "builder: FlatBufferBuilder, offset: Int";
auto method_name = "finish" + Esc(struct_def.name) + "Buffer"; auto method_name = "finish" + Esc(struct_def.name) + "Buffer";
GenerateFunOneLine(writer, method_name, params, "", [&]() { GenerateFunOneLine(writer, method_name, params, "",
writer += "builder.finish(offset" + id + ")"; [&]() { writer += "builder.finish(offset" + id + ")"; });
});
} }
void GenerateEndStructMethod(StructDef &struct_def, CodeWriter &writer) const { void GenerateEndStructMethod(StructDef &struct_def,
CodeWriter &writer) const {
// Generate end{{TableName}}(builder: FlatBufferBuilder) method // Generate end{{TableName}}(builder: FlatBufferBuilder) method
auto name = "end" + Esc(struct_def.name); auto name = "end" + Esc(struct_def.name);
auto params = "builder: FlatBufferBuilder"; auto params = "builder: FlatBufferBuilder";
@@ -633,9 +600,7 @@ 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.required) { if (field.deprecated || !field.required) { continue; }
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}})";
} }
@@ -674,11 +639,9 @@ class KotlinGenerator : public BaseGenerator {
writer.SetValue("size", NumToString(InlineSize(vector_type))); writer.SetValue("size", NumToString(InlineSize(vector_type)));
writer.SetValue("align", NumToString(InlineAlignment(vector_type))); writer.SetValue("align", NumToString(InlineAlignment(vector_type)));
GenerateFunOneLine(writer, GenerateFunOneLine(
"start" + MakeCamel(Esc(field.name) + "Vector", true), writer, "start" + MakeCamel(Esc(field.name) + "Vector", true), params,
params, "", [&]() {
"",
[&]() {
writer += "builder.startVector({{size}}, numElems, {{align}})"; writer += "builder.startVector({{size}}, numElems, {{align}})";
}); });
} }
@@ -690,7 +653,8 @@ class KotlinGenerator : public BaseGenerator {
GenerateFunOneLine(writer, "add" + MakeCamel(Esc(field.name), true), GenerateFunOneLine(writer, "add" + MakeCamel(Esc(field.name), true),
"builder: FlatBufferBuilder, " + secondArg, "", [&]() { "builder: FlatBufferBuilder, " + secondArg, "", [&]() {
auto method = GenMethod(field.value.type); auto method = GenMethod(field.value.type);
writer.SetValue("field_name", MakeCamel(Esc(field.name), false)); writer.SetValue("field_name",
MakeCamel(Esc(field.name), false));
writer.SetValue("method_name", method); writer.SetValue("method_name", method);
writer.SetValue("pos", field_pos); writer.SetValue("pos", field_pos);
writer.SetValue("default", GenFBBDefaultValue(field)); writer.SetValue("default", GenFBBDefaultValue(field));
@@ -703,26 +667,19 @@ 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: case BASE_TYPE_UINT: return GenTypeBasic(BASE_TYPE_INT);
return GenTypeBasic(BASE_TYPE_INT); case BASE_TYPE_ULONG: return GenTypeBasic(BASE_TYPE_LONG);
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: case BASE_TYPE_UTYPE: return GenTypeBasic(BASE_TYPE_CHAR);
return GenTypeBasic(BASE_TYPE_CHAR); case BASE_TYPE_USHORT: return GenTypeBasic(BASE_TYPE_SHORT);
case BASE_TYPE_USHORT: case BASE_TYPE_VECTOR: return ToSignedType(type.VectorType());
return GenTypeBasic(BASE_TYPE_SHORT); default: return GenTypeBasic(type.base_type);
case BASE_TYPE_VECTOR:
return ToSignedType(type.VectorType());
default:
return GenTypeBasic(type.base_type);
} }
} }
static std::string FlexBufferBuilderCast(const std::string &method, static std::string FlexBufferBuilderCast(const std::string &method,
FieldDef &field, FieldDef &field, bool isFirst) {
bool isFirst) {
auto field_type = GenTypeBasic(field.value.type.base_type); auto field_type = GenTypeBasic(field.value.type.base_type);
std::string to_type; std::string to_type;
if (method == "Boolean") if (method == "Boolean")
@@ -741,16 +698,18 @@ class KotlinGenerator : public BaseGenerator {
to_type = isFirst ? "Float" : "Double"; to_type = isFirst ? "Float" : "Double";
else if (method == "UByte") else if (method == "UByte")
if (field_type != to_type) if (field_type != to_type) return ".to" + to_type + "()";
return ".to" + to_type + "()";
return ""; return "";
} }
// fun startMonster(builder: FlatBufferBuilder) = builder.startTable(11) // fun startMonster(builder: FlatBufferBuilder) = builder.startTable(11)
void GenerateStartStructMethod(StructDef &struct_def, CodeWriter &code) const { void GenerateStartStructMethod(StructDef &struct_def,
CodeWriter &code) const {
GenerateFunOneLine(code, "start" + Esc(struct_def.name), GenerateFunOneLine(code, "start" + Esc(struct_def.name),
"builder: FlatBufferBuilder", "", [&]() { "builder: FlatBufferBuilder", "", [&]() {
code += "builder.startTable("+ NumToString(struct_def.fields.vec.size()) + ")"; code += "builder.startTable(" +
NumToString(struct_def.fields.vec.size()) +
")";
}); });
} }
@@ -800,16 +759,13 @@ class KotlinGenerator : public BaseGenerator {
auto sortbysize = struct_def.sortbysize; auto sortbysize = struct_def.sortbysize;
auto largest = sortbysize ? sizeof(largest_scalar_t) : 1; auto largest = sortbysize ? sizeof(largest_scalar_t) : 1;
for (size_t size = largest; size; size /= 2) { for (size_t size = largest; size; size /= 2) {
for (auto it = fields_vec.rbegin(); it != fields_vec.rend(); for (auto it = fields_vec.rbegin(); it != fields_vec.rend(); ++it) {
++it) {
auto &field = **it; auto &field = **it;
auto base_type_size = SizeOf(field.value.type.base_type); auto base_type_size = SizeOf(field.value.type.base_type);
if (!field.deprecated && if (!field.deprecated && (!sortbysize || size == base_type_size)) {
(!sortbysize || size == base_type_size)) {
writer.SetValue("camel_field_name", writer.SetValue("camel_field_name",
MakeCamel(Esc(field.name), true)); MakeCamel(Esc(field.name), true));
writer.SetValue("field_name", writer.SetValue("field_name", MakeCamel(Esc(field.name), false));
MakeCamel(Esc(field.name), false));
writer += "add{{camel_field_name}}(builder, {{field_name}}\\"; writer += "add{{camel_field_name}}(builder, {{field_name}}\\";
if (!IsScalar(field.value.type.base_type)) { if (!IsScalar(field.value.type.base_type)) {
@@ -822,7 +778,6 @@ class KotlinGenerator : public BaseGenerator {
writer += "return end{{struct_name}}(builder)"; writer += "return end{{struct_name}}(builder)";
}); });
} }
} }
void GenerateBufferHasIdentifier(StructDef &struct_def, void GenerateBufferHasIdentifier(StructDef &struct_def,
CodeWriter &writer) const { CodeWriter &writer) const {
@@ -831,11 +786,10 @@ class KotlinGenerator : public BaseGenerator {
if (parser_.root_struct_def_ != &struct_def || !file_identifier.length()) if (parser_.root_struct_def_ != &struct_def || !file_identifier.length())
return; return;
auto name = MakeCamel(Esc(struct_def.name), false); auto name = MakeCamel(Esc(struct_def.name), false);
GenerateFunOneLine(writer, name + "BufferHasIdentifier", GenerateFunOneLine(writer, name + "BufferHasIdentifier", "_bb: ByteBuffer",
"_bb: ByteBuffer", "Boolean", [&]() {
"Boolean", writer += "__has_identifier(_bb, \"" +
[&]() { file_identifier + "\")";
writer += "__has_identifier(_bb, \"" + file_identifier + "\")";
}); });
} }
@@ -856,8 +810,8 @@ class KotlinGenerator : public BaseGenerator {
auto bbgetter = ByteBufferGetter(field.value.type, "bb"); auto bbgetter = ByteBufferGetter(field.value.type, "bb");
auto ucast = CastToUsigned(field); auto ucast = CastToUsigned(field);
auto offset_val = NumToString(field.value.offset); auto offset_val = NumToString(field.value.offset);
auto offset_prefix = "val o = __offset(" + offset_val auto offset_prefix =
+ "); return o != 0 ? "; "val o = __offset(" + offset_val + "); return o != 0 ? ";
auto value_base_type = field.value.type.base_type; auto value_base_type = field.value.type.base_type;
// Most field accessors need to retrieve and test the field offset // Most field accessors need to retrieve and test the field offset
// first, this is the offset value for that: // first, this is the offset value for that:
@@ -897,7 +851,8 @@ class KotlinGenerator : public BaseGenerator {
} else { } else {
GenerateGetter(writer, field_name, return_type, [&]() { GenerateGetter(writer, field_name, return_type, [&]() {
writer += "val o = __offset({{offset}})"; writer += "val o = __offset({{offset}})";
writer += "return if(o != 0) {{bbgetter}}" writer +=
"return if(o != 0) {{bbgetter}}"
"(o + bb_pos){{ucast}} else " "(o + bb_pos){{ucast}} else "
"{{field_default}}"; "{{field_default}}";
}); });
@@ -910,11 +865,9 @@ class KotlinGenerator : public BaseGenerator {
// ex: // ex:
// fun pos(obj: Vec3) : Vec3? = obj.__assign(bb_pos + 4, bb) // fun pos(obj: Vec3) : Vec3? = obj.__assign(bb_pos + 4, bb)
// ? adds nullability annotation // ? adds nullability annotation
GenerateFunOneLine(writer, GenerateFunOneLine(
field_name, "obj: " + field_type , writer, field_name, "obj: " + field_type, return_type + "?",
return_type + "?", [&](){ [&]() { writer += "obj.__assign(bb_pos + {{offset}}, bb)"; });
writer += "obj.__assign(bb_pos + {{offset}}, bb)";
});
} else { } else {
// create getter with object reuse // create getter with object reuse
// ex: // ex:
@@ -927,13 +880,14 @@ class KotlinGenerator : public BaseGenerator {
// } // }
// } // }
// ? adds nullability annotation // ? adds nullability annotation
GenerateFun(writer, field_name, "obj: " + field_type, GenerateFun(
return_type + "?", [&](){ writer, field_name, "obj: " + field_type, return_type + "?",
[&]() {
auto fixed = field.value.type.struct_def->fixed; auto fixed = field.value.type.struct_def->fixed;
writer.SetValue("seek", Indirect("o + bb_pos", fixed)); writer.SetValue("seek", Indirect("o + bb_pos", fixed));
OffsetWrapper(writer, OffsetWrapper(
offset_val, writer, offset_val,
[&]() { writer += "obj.__assign({{seek}}, bb)"; }, [&]() { writer += "obj.__assign({{seek}}, bb)"; },
[&]() { writer += "null"; }); [&]() { writer += "null"; });
}); });
@@ -949,7 +903,6 @@ class KotlinGenerator : public BaseGenerator {
// } // }
// ? adds nullability annotation // ? adds nullability annotation
GenerateGetter(writer, field_name, return_type + "?", [&]() { GenerateGetter(writer, field_name, return_type + "?", [&]() {
writer += "val o = __offset({{offset}})"; writer += "val o = __offset({{offset}})";
writer += "return if (o != 0) __string(o + bb_pos) else null"; writer += "return if (o != 0) __string(o + bb_pos) else null";
}); });
@@ -967,8 +920,7 @@ class KotlinGenerator : public BaseGenerator {
auto vectortype = field.value.type.VectorType(); auto vectortype = field.value.type.VectorType();
std::string params = "j: Int"; std::string params = "j: Int";
std::string nullable = IsScalar(vectortype.base_type) ? "" std::string nullable = IsScalar(vectortype.base_type) ? "" : "?";
: "?";
if (vectortype.base_type == BASE_TYPE_STRUCT || if (vectortype.base_type == BASE_TYPE_STRUCT ||
vectortype.base_type == BASE_TYPE_UNION) { vectortype.base_type == BASE_TYPE_UNION) {
@@ -992,11 +944,10 @@ class KotlinGenerator : public BaseGenerator {
case BASE_TYPE_UNION: case BASE_TYPE_UNION:
found = "{{bbgetter}}(obj, {{index}} - bb_pos){{ucast}}"; found = "{{bbgetter}}(obj, {{index}} - bb_pos){{ucast}}";
break; break;
default: default: found = "{{bbgetter}}({{index}}){{ucast}}";
found = "{{bbgetter}}({{index}}){{ucast}}";
} }
OffsetWrapper(writer, offset_val, OffsetWrapper(
[&]() { writer += found; } , writer, offset_val, [&]() { writer += found; },
[&]() { writer += not_found; }); [&]() { writer += not_found; });
}); });
break; break;
@@ -1004,21 +955,19 @@ class KotlinGenerator : public BaseGenerator {
case BASE_TYPE_UNION: case BASE_TYPE_UNION:
GenerateFun(writer, field_name, "obj: " + field_type, GenerateFun(writer, field_name, "obj: " + field_type,
return_type + "?", [&]() { return_type + "?", [&]() {
writer += OffsetWrapperOneLine(offset_val, writer += OffsetWrapperOneLine(
bbgetter + "(obj, o + bb_pos)", offset_val, bbgetter + "(obj, o + bb_pos)",
"null"); "null");
}); });
break; break;
default: default: FLATBUFFERS_ASSERT(0);
FLATBUFFERS_ASSERT(0);
} }
} }
if (value_base_type == BASE_TYPE_VECTOR) { if (value_base_type == BASE_TYPE_VECTOR) {
// Generate Lenght functions for vectors // Generate Lenght functions for vectors
GenerateGetter(writer, field_name + "Length", "Int", [&]() { GenerateGetter(writer, field_name + "Length", "Int", [&]() {
writer += OffsetWrapperOneLine(offset_val, writer += OffsetWrapperOneLine(offset_val, "__vector_len(o)", "0");
"__vector_len(o)", "0");
}); });
// See if we should generate a by-key accessor. // See if we should generate a by-key accessor.
@@ -1034,21 +983,20 @@ class KotlinGenerator : public BaseGenerator {
auto params = "key: " + GenTypeGet(kfield.value.type); auto params = "key: " + GenTypeGet(kfield.value.type);
auto rtype = qualified_name + "?"; auto rtype = qualified_name + "?";
GenerateFun(writer, name, params, rtype, [&]() { GenerateFun(writer, name, params, rtype, [&]() {
OffsetWrapper(writer, offset_val, OffsetWrapper(
writer, offset_val,
[&]() { [&]() {
writer += qualified_name + writer += qualified_name +
".__lookup_by_key(null, __vector(o), key, bb)"; ".__lookup_by_key(null, __vector(o), key, bb)";
}, },
[&] () { [&]() { writer += "null"; });
writer += "null";
});
}); });
auto param2 = "obj: " + qualified_name + auto param2 = "obj: " + qualified_name +
", key: " + ", key: " + GenTypeGet(kfield.value.type);
GenTypeGet(kfield.value.type);
GenerateFun(writer, name, param2, rtype, [&]() { GenerateFun(writer, name, param2, rtype, [&]() {
OffsetWrapper(writer, offset_val, OffsetWrapper(
writer, offset_val,
[&]() { [&]() {
writer += qualified_name + writer += qualified_name +
".__lookup_by_key(obj, __vector(o), key, bb)"; ".__lookup_by_key(obj, __vector(o), key, bb)";
@@ -1065,8 +1013,8 @@ class KotlinGenerator : public BaseGenerator {
if ((value_base_type == BASE_TYPE_VECTOR && if ((value_base_type == BASE_TYPE_VECTOR &&
IsScalar(field.value.type.VectorType().base_type)) || IsScalar(field.value.type.VectorType().base_type)) ||
value_base_type == BASE_TYPE_STRING) { value_base_type == BASE_TYPE_STRING) {
auto end_idx =
auto end_idx = NumToString(value_base_type == BASE_TYPE_STRING NumToString(value_base_type == BASE_TYPE_STRING
? 1 ? 1
: InlineSize(field.value.type.VectorType())); : InlineSize(field.value.type.VectorType()));
// Generate a ByteBuffer accessor for strings & vectors of scalars. // Generate a ByteBuffer accessor for strings & vectors of scalars.
@@ -1074,8 +1022,8 @@ class KotlinGenerator : public BaseGenerator {
// val inventoryByteBuffer: ByteBuffer // val inventoryByteBuffer: ByteBuffer
// get = __vector_as_bytebuffer(14, 1) // get = __vector_as_bytebuffer(14, 1)
GenerateGetterOneLine(writer, field_name + "AsByteBuffer", GenerateGetterOneLine(
"ByteBuffer", [&](){ writer, field_name + "AsByteBuffer", "ByteBuffer", [&]() {
writer.SetValue("end", end_idx); writer.SetValue("end", end_idx);
writer += "__vector_as_bytebuffer({{offset}}, {{end}})"; writer += "__vector_as_bytebuffer({{offset}}, {{end}})";
}); });
@@ -1084,8 +1032,9 @@ class KotlinGenerator : public BaseGenerator {
// e.g. // e.g.
// fun inventoryInByteBuffer(_bb: Bytebuffer): // fun inventoryInByteBuffer(_bb: Bytebuffer):
// ByteBuffer = __vector_as_bytebuffer(_bb, 14, 1) // ByteBuffer = __vector_as_bytebuffer(_bb, 14, 1)
GenerateFunOneLine(writer, field_name + "InByteBuffer", GenerateFunOneLine(
"_bb: ByteBuffer", "ByteBuffer", [&](){ writer, field_name + "InByteBuffer", "_bb: ByteBuffer",
"ByteBuffer", [&]() {
writer.SetValue("end", end_idx); writer.SetValue("end", end_idx);
writer += "__vector_in_bytebuffer(_bb, {{offset}}, {{end}})"; writer += "__vector_in_bytebuffer(_bb, {{offset}}, {{end}})";
}); });
@@ -1098,21 +1047,21 @@ class KotlinGenerator : public BaseGenerator {
if (field.nested_flatbuffer) { if (field.nested_flatbuffer) {
auto nested_type_name = WrapInNameSpace(*field.nested_flatbuffer); auto nested_type_name = WrapInNameSpace(*field.nested_flatbuffer);
auto nested_method_name = auto nested_method_name =
field_name + "As" + field_name + "As" + field.nested_flatbuffer->name;
field.nested_flatbuffer->name;
GenerateGetterOneLine(writer, GenerateGetterOneLine(
nested_method_name, writer, nested_method_name, nested_type_name + "?", [&]() {
nested_type_name + "?", [&](){
writer += nested_method_name + "(" + nested_type_name + "())"; writer += nested_method_name + "(" + nested_type_name + "())";
}); });
GenerateFun(writer, GenerateFun(writer, nested_method_name, "obj: " + nested_type_name,
nested_method_name,
"obj: " + nested_type_name,
nested_type_name + "?", [&]() { nested_type_name + "?", [&]() {
OffsetWrapper(writer, offset_val, OffsetWrapper(
[&]() { writer += "obj.__assign(__indirect(__vector(o)), bb)"; }, writer, offset_val,
[&]() {
writer +=
"obj.__assign(__indirect(__vector(o)), bb)";
},
[&]() { writer += "null"; }); [&]() { writer += "null"; });
}); });
} }
@@ -1128,23 +1077,22 @@ class KotlinGenerator : public BaseGenerator {
auto params = Esc(field.name) + ": " + GenTypeGet(underlying_type); auto params = Esc(field.name) + ": " + GenTypeGet(underlying_type);
// A vector mutator also needs the index of the vector element it should // A vector mutator also needs the index of the vector element it should
// mutate. // mutate.
if (value_base_type == BASE_TYPE_VECTOR) if (value_base_type == BASE_TYPE_VECTOR) params.insert(0, "j: Int, ");
params.insert(0, "j: Int, ");
// Boolean parameters have to be explicitly converted to byte // Boolean parameters have to be explicitly converted to byte
// representation. // representation.
auto setter_parameter = underlying_type.base_type == BASE_TYPE_BOOL auto setter_parameter =
underlying_type.base_type == BASE_TYPE_BOOL
? "(if(" + Esc(field.name) + ") 1 else 0).toByte()" ? "(if(" + Esc(field.name) + ") 1 else 0).toByte()"
: Esc(field.name); : Esc(field.name);
auto setter_index = value_base_type == BASE_TYPE_VECTOR auto setter_index =
value_base_type == BASE_TYPE_VECTOR
? "__vector(o) + j * " + size ? "__vector(o) + j * " + size
: (struct_def.fixed : (struct_def.fixed ? "bb_pos + " + offset_val : "o + bb_pos");
? "bb_pos + " + offset_val if (IsScalar(value_base_type) ||
: "o + bb_pos"); (value_base_type == BASE_TYPE_VECTOR &&
if (IsScalar(value_base_type) || (value_base_type == BASE_TYPE_VECTOR &&
IsScalar(value_type.VectorType().base_type))) { IsScalar(value_type.VectorType().base_type))) {
auto statements = [&]() { auto statements = [&]() {
writer.SetValue("bbsetter", ByteBufferSetter(underlying_type)); writer.SetValue("bbsetter", ByteBufferSetter(underlying_type));
writer.SetValue("index", setter_index); writer.SetValue("index", setter_index);
@@ -1153,19 +1101,20 @@ class KotlinGenerator : public BaseGenerator {
if (struct_def.fixed) { if (struct_def.fixed) {
writer += "{{bbsetter}}({{index}}, {{params}}{{cast}})"; writer += "{{bbsetter}}({{index}}, {{params}}{{cast}})";
} else { } else {
OffsetWrapper(writer, offset_val, [&](){ OffsetWrapper(
writer, offset_val,
[&]() {
writer += "{{bbsetter}}({{index}}, {{params}}{{cast}})"; writer += "{{bbsetter}}({{index}}, {{params}}{{cast}})";
writer += "true"; writer += "true";
}, [&](){ writer += "false";}); },
[&]() { writer += "false"; });
} }
}; };
if (struct_def.fixed) { if (struct_def.fixed) {
GenerateFunOneLine(writer, name, params, "ByteBuffer", GenerateFunOneLine(writer, name, params, "ByteBuffer", statements);
statements);
} else { } else {
GenerateFun(writer, name, params, "Boolean", GenerateFun(writer, name, params, "Boolean", statements);
statements);
} }
} }
} }
@@ -1173,12 +1122,12 @@ class KotlinGenerator : public BaseGenerator {
if (struct_def.has_key && !struct_def.fixed) { if (struct_def.has_key && !struct_def.fixed) {
// Key Comparison method // Key Comparison method
GenerateOverrideFun( GenerateOverrideFun(
writer, writer, "keysCompare", "o1: Int, o2: Int, _bb: ByteBuffer", "Int",
"keysCompare", [&]() {
"o1: Int, o2: Int, _bb: ByteBuffer", "Int", [&]() {
if (key_field->value.type.base_type == BASE_TYPE_STRING) { if (key_field->value.type.base_type == BASE_TYPE_STRING) {
writer.SetValue("offset", NumToString(key_field->value.offset)); writer.SetValue("offset", NumToString(key_field->value.offset));
writer += " return compareStrings(__offset({{offset}}, o1, " writer +=
" return compareStrings(__offset({{offset}}, o1, "
"_bb), __offset({{offset}}, o2, _bb), _bb)"; "_bb), __offset({{offset}}, o2, _bb), _bb)";
} else { } else {
@@ -1198,19 +1147,13 @@ 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: case BASE_TYPE_UINT: return ".toUInt()";
return ".toUInt()";
case BASE_TYPE_UCHAR: case BASE_TYPE_UCHAR:
case BASE_TYPE_UTYPE: case BASE_TYPE_UTYPE: return ".toUByte()";
return ".toUByte()"; case BASE_TYPE_USHORT: return ".toUShort()";
case BASE_TYPE_USHORT: case BASE_TYPE_ULONG: return ".toULong()";
return ".toUShort()"; case BASE_TYPE_VECTOR: return CastToUsigned(type.VectorType());
case BASE_TYPE_ULONG: default: return "";
return ".toULong()";
case BASE_TYPE_VECTOR:
return CastToUsigned(type.VectorType());
default:
return "";
} }
} }
@@ -1220,19 +1163,13 @@ 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: case BASE_TYPE_UINT: return ".toInt()";
return ".toInt()";
case BASE_TYPE_UCHAR: case BASE_TYPE_UCHAR:
case BASE_TYPE_UTYPE: case BASE_TYPE_UTYPE: return ".toByte()";
return ".toByte()"; case BASE_TYPE_USHORT: return ".toShort()";
case BASE_TYPE_USHORT: case BASE_TYPE_ULONG: return ".toLong()";
return ".toShort()"; case BASE_TYPE_VECTOR: return CastToSigned(type.VectorType());
case BASE_TYPE_ULONG: default: return "";
return ".toLong()";
case BASE_TYPE_VECTOR:
return CastToSigned(type.VectorType());
default:
return "";
} }
} }
@@ -1241,14 +1178,10 @@ 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: case BASE_TYPE_USHORT: return "u";
return "u"; case BASE_TYPE_ULONG: return "UL";
case BASE_TYPE_ULONG: case BASE_TYPE_LONG: return "L";
return "UL"; default: return "";
case BASE_TYPE_LONG:
return "L";
default:
return "";
} }
} }
@@ -1297,11 +1230,13 @@ class KotlinGenerator : public BaseGenerator {
// create method that allows object reuse // create method that allows object reuse
// ex: fun Monster getRootAsMonster(_bb: ByteBuffer, obj: Monster) {...} // ex: fun Monster getRootAsMonster(_bb: ByteBuffer, obj: Monster) {...}
writer += "fun {{gr_method}}" writer +=
"fun {{gr_method}}"
"(_bb: ByteBuffer, obj: {{gr_name}}): {{gr_name}} {"; "(_bb: ByteBuffer, obj: {{gr_name}}): {{gr_name}} {";
writer.IncrementIdentLevel(); writer.IncrementIdentLevel();
writer += "_bb.order(ByteOrder.LITTLE_ENDIAN)"; writer += "_bb.order(ByteOrder.LITTLE_ENDIAN)";
writer += "return (obj.__assign(_bb.getInt(_bb.position())" writer +=
"return (obj.__assign(_bb.getInt(_bb.position())"
" + _bb.position(), _bb))"; " + _bb.position(), _bb))";
writer.DecrementIdentLevel(); writer.DecrementIdentLevel();
writer += "}"; writer += "}";
@@ -1322,9 +1257,7 @@ 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()) { if (prefix.empty()) { out << "builder: FlatBufferBuilder"; }
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)) {
@@ -1335,8 +1268,7 @@ class KotlinGenerator : public BaseGenerator {
out << StructConstructorParams(*field.value.type.struct_def, out << StructConstructorParams(*field.value.type.struct_def,
prefix + (Esc(field.name) + "_")); prefix + (Esc(field.name) + "_"));
} else { } else {
out << ", " << prefix << MakeCamel(Esc(field.name), false) out << ", " << prefix << MakeCamel(Esc(field.name), false) << ": "
<< ": "
<< GenTypeBasic(field.value.type.base_type); << GenTypeBasic(field.value.type.base_type);
} }
} }
@@ -1355,8 +1287,7 @@ class KotlinGenerator : public BaseGenerator {
writer += "val {{_name}} : {{_type}} = \\"; writer += "val {{_name}} : {{_type}} = \\";
body(); body();
} }
static void GenerateGetterOneLine(CodeWriter &writer, static void GenerateGetterOneLine(CodeWriter &writer, const std::string &name,
const std::string &name,
const std::string &type, const std::string &type,
const std::function<void()> &body) { const std::function<void()> &body) {
// Generates Kotlin getter for properties // Generates Kotlin getter for properties
@@ -1368,8 +1299,7 @@ class KotlinGenerator : public BaseGenerator {
body(); body();
} }
static void GenerateGetter(CodeWriter &writer, static void GenerateGetter(CodeWriter &writer, const std::string &name,
const std::string &name,
const std::string &type, const std::string &type,
const std::function<void()> &body) { const std::function<void()> &body) {
// Generates Kotlin getter for properties // Generates Kotlin getter for properties
@@ -1390,8 +1320,7 @@ class KotlinGenerator : public BaseGenerator {
writer.DecrementIdentLevel(); writer.DecrementIdentLevel();
} }
static void GenerateFun(CodeWriter &writer, static void GenerateFun(CodeWriter &writer, const std::string &name,
const std::string &name,
const std::string &params, const std::string &params,
const std::string &returnType, const std::string &returnType,
const std::function<void()> &body) { const std::function<void()> &body) {
@@ -1411,8 +1340,7 @@ class KotlinGenerator : public BaseGenerator {
writer += "}"; writer += "}";
} }
static void GenerateFunOneLine(CodeWriter &writer, static void GenerateFunOneLine(CodeWriter &writer, const std::string &name,
const std::string &name,
const std::string &params, const std::string &params,
const std::string &returnType, const std::string &returnType,
const std::function<void()> &body) { const std::function<void()> &body) {
@@ -1421,14 +1349,13 @@ class KotlinGenerator : public BaseGenerator {
// fun path(j: Int): Vec3 = return path(Vec3(), j) // fun path(j: Int): Vec3 = return path(Vec3(), j)
writer.SetValue("name", name); writer.SetValue("name", name);
writer.SetValue("params", params); writer.SetValue("params", params);
writer.SetValue("return_type_p", returnType.empty() ? "" : writer.SetValue("return_type_p",
" : " + returnType); returnType.empty() ? "" : " : " + returnType);
writer += "fun {{name}}({{params}}){{return_type_p}} = \\"; writer += "fun {{name}}({{params}}){{return_type_p}} = \\";
body(); body();
} }
static void GenerateOverrideFun(CodeWriter &writer, static void GenerateOverrideFun(CodeWriter &writer, const std::string &name,
const std::string &name,
const std::string &params, const std::string &params,
const std::string &returnType, const std::string &returnType,
const std::function<void()> &body) { const std::function<void()> &body) {
@@ -1449,8 +1376,8 @@ class KotlinGenerator : public BaseGenerator {
// override fun path(j: Int): Vec3 = return path(Vec3(), j) // override fun path(j: Int): Vec3 = return path(Vec3(), j)
writer.SetValue("name", name); writer.SetValue("name", name);
writer.SetValue("params", params); writer.SetValue("params", params);
writer.SetValue("return_type", returnType.empty() ? "" : writer.SetValue("return_type",
" : " + returnType); returnType.empty() ? "" : " : " + returnType);
writer += "override fun {{name}}({{params}}){{return_type}} = \\"; writer += "override fun {{name}}({{params}}){{return_type}} = \\";
writer += statement; writer += statement;
} }
@@ -1462,8 +1389,7 @@ class KotlinGenerator : public BaseGenerator {
" else " + not_found; " else " + not_found;
} }
static void OffsetWrapper(CodeWriter &code, static void OffsetWrapper(CodeWriter &code, const std::string &offset,
const std::string &offset,
const std::function<void()> &found, const std::function<void()> &found,
const std::function<void()> &not_found) { const std::function<void()> &not_found) {
code += "val o = __offset(" + offset + ")"; code += "val o = __offset(" + offset + ")";
@@ -1480,33 +1406,25 @@ class KotlinGenerator : public BaseGenerator {
static std::string Indirect(const std::string &index, bool fixed) { static std::string Indirect(const std::string &index, bool fixed) {
// We apply __indirect() and struct is not fixed. // We apply __indirect() and struct is not fixed.
if (!fixed) if (!fixed) return "__indirect(" + index + ")";
return "__indirect(" + index + ")";
return index; return index;
} }
static std::string NotFoundReturn(BaseType el) { static std::string NotFoundReturn(BaseType el) {
switch (el) { switch (el) {
case BASE_TYPE_FLOAT: case BASE_TYPE_FLOAT: return "0.0f";
return "0.0f"; case BASE_TYPE_DOUBLE: return "0.0";
case BASE_TYPE_DOUBLE: case BASE_TYPE_BOOL: return "false";
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: case BASE_TYPE_SHORT: return "0";
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: case BASE_TYPE_UTYPE: return "0u";
return "0u"; case BASE_TYPE_ULONG: return "0uL";
case BASE_TYPE_ULONG: default: return "null";
return "0uL";
default:
return "null";
} }
} }

View File

@@ -31,10 +31,12 @@ class LobsterGenerator : public BaseGenerator {
const std::string &file_name) const std::string &file_name)
: BaseGenerator(parser, path, file_name, "" /* not used */, "_") { : BaseGenerator(parser, path, file_name, "" /* not used */, "_") {
static const char *const keywords[] = { static const char *const keywords[] = {
"nil", "true", "false", "return", "struct", "class", "import", "int", "nil", "true", "false", "return", "struct", "class",
"float", "string", "any", "def", "is", "from", "program", "private", "import", "int", "float", "string", "any", "def",
"coroutine", "resource", "enum", "typeof", "var", "let", "pakfile", "is", "from", "program", "private", "coroutine", "resource",
"switch", "case", "default", "namespace", "not", "and", "or", "bool", "enum", "typeof", "var", "let", "pakfile", "switch",
"case", "default", "namespace", "not", "and", "or",
"bool",
}; };
keywords_.insert(std::begin(keywords), std::end(keywords)); keywords_.insert(std::begin(keywords), std::end(keywords));
} }
@@ -66,7 +68,8 @@ class LobsterGenerator : public BaseGenerator {
std::string LobsterType(const Type &type) { std::string LobsterType(const Type &type) {
if (IsFloat(type.base_type)) return "float"; if (IsFloat(type.base_type)) return "float";
if (IsScalar(type.base_type) && type.enum_def) return NormalizedName(*type.enum_def); if (IsScalar(type.base_type) && type.enum_def)
return NormalizedName(*type.enum_def);
if (!IsScalar(type.base_type)) return "flatbuffers_offset"; if (!IsScalar(type.base_type)) return "flatbuffers_offset";
return "int"; return "int";
} }
@@ -93,8 +96,8 @@ class LobsterGenerator : public BaseGenerator {
} }
// Generate a struct field, conditioned on its child type(s). // Generate a struct field, conditioned on its child type(s).
void GenStructAccessor(const StructDef &struct_def, void GenStructAccessor(const StructDef &struct_def, const FieldDef &field,
const FieldDef &field, std::string *code_ptr) { std::string *code_ptr) {
GenComment(field.doc_comment, code_ptr, nullptr, " "); GenComment(field.doc_comment, code_ptr, nullptr, " ");
std::string &code = *code_ptr; std::string &code = *code_ptr;
auto offsets = NumToString(field.value.offset); auto offsets = NumToString(field.value.offset);
@@ -102,13 +105,12 @@ class LobsterGenerator : public BaseGenerator {
if (IsScalar(field.value.type.base_type)) { if (IsScalar(field.value.type.base_type)) {
std::string acc; std::string acc;
if (struct_def.fixed) { if (struct_def.fixed) {
acc = "buf_.read_" + GenTypeName(field.value.type) + acc = "buf_.read_" + GenTypeName(field.value.type) + "_le(pos_ + " +
"_le(pos_ + " + offsets + ")"; offsets + ")";
} else { } else {
acc = "buf_.flatbuffers_field_" + acc = "buf_.flatbuffers_field_" + GenTypeName(field.value.type) +
GenTypeName(field.value.type) + "(pos_, " + offsets + ", " + "(pos_, " + offsets + ", " + field.value.constant + ")";
field.value.constant + ")";
} }
if (field.value.type.enum_def) if (field.value.type.enum_def)
acc = NormalizedName(*field.value.type.enum_def) + "(" + acc + ")"; acc = NormalizedName(*field.value.type.enum_def) + "(" + acc + ")";
@@ -130,7 +132,8 @@ class LobsterGenerator : public BaseGenerator {
break; break;
} }
case BASE_TYPE_STRING: case BASE_TYPE_STRING:
code += def + "():\n return buf_.flatbuffers_field_string(pos_, " + code += def +
"():\n return buf_.flatbuffers_field_string(pos_, " +
offsets + ")\n"; offsets + ")\n";
break; break;
case BASE_TYPE_VECTOR: { case BASE_TYPE_VECTOR: {
@@ -171,19 +174,20 @@ class LobsterGenerator : public BaseGenerator {
} }
if (field.value.type.base_type == BASE_TYPE_VECTOR) { if (field.value.type.base_type == BASE_TYPE_VECTOR) {
code += def + code += def +
"_length():\n return buf_.flatbuffers_field_vector_len(pos_, " + "_length():\n return "
"buf_.flatbuffers_field_vector_len(pos_, " +
offsets + ")\n"; offsets + ")\n";
} }
} }
// Generate table constructors, conditioned on its members' types. // Generate table constructors, conditioned on its members' types.
void GenTableBuilders(const StructDef &struct_def, void GenTableBuilders(const StructDef &struct_def, std::string *code_ptr) {
std::string *code_ptr) {
std::string &code = *code_ptr; std::string &code = *code_ptr;
code += "struct " + NormalizedName(struct_def) + code += "struct " + NormalizedName(struct_def) +
"Builder:\n b_:flatbuffers_builder\n"; "Builder:\n b_:flatbuffers_builder\n";
code += " def start():\n b_.StartObject(" + code += " def start():\n b_.StartObject(" +
NumToString(struct_def.fields.vec.size()) + ")\n return this\n"; NumToString(struct_def.fields.vec.size()) +
")\n return this\n";
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;
@@ -209,8 +213,8 @@ class LobsterGenerator : public BaseGenerator {
auto vector_type = field.value.type.VectorType(); auto vector_type = field.value.type.VectorType();
auto alignment = InlineAlignment(vector_type); auto alignment = InlineAlignment(vector_type);
auto elem_size = InlineSize(vector_type); auto elem_size = InlineSize(vector_type);
code += NumToString(elem_size) + ", n_, " + NumToString(alignment) + code +=
")\n"; NumToString(elem_size) + ", n_, " + NumToString(alignment) + ")\n";
if (vector_type.base_type != BASE_TYPE_STRUCT || if (vector_type.base_type != BASE_TYPE_STRUCT ||
!vector_type.struct_def->fixed) { !vector_type.struct_def->fixed) {
code += "def " + NormalizedName(struct_def) + "Create" + code += "def " + NormalizedName(struct_def) + "Create" +
@@ -218,8 +222,7 @@ class LobsterGenerator : public BaseGenerator {
"Vector(b_:flatbuffers_builder, v_:[" + "Vector(b_:flatbuffers_builder, v_:[" +
LobsterType(vector_type) + "]):\n b_.StartVector(" + LobsterType(vector_type) + "]):\n b_.StartVector(" +
NumToString(elem_size) + ", v_.length, " + NumToString(elem_size) + ", v_.length, " +
NumToString(alignment) + NumToString(alignment) + ")\n reverse(v_) e_: b_.Prepend" +
")\n reverse(v_) e_: b_.Prepend" +
GenMethod(vector_type) + GenMethod(vector_type) +
"(e_)\n return b_.EndVector(v_.length)\n"; "(e_)\n return b_.EndVector(v_.length)\n";
} }
@@ -252,8 +255,8 @@ class LobsterGenerator : public BaseGenerator {
if (!struct_def.fixed) { if (!struct_def.fixed) {
// Generate a special accessor for the table that has been declared as // Generate a special accessor for the table that has been declared as
// the root type. // the root type.
code += "def GetRootAs" + NormalizedName(struct_def) + "(buf:string): return " + code += "def GetRootAs" + NormalizedName(struct_def) +
NormalizedName(struct_def) + "(buf:string): return " + NormalizedName(struct_def) +
" { buf, buf.flatbuffers_indirect(0) }\n\n"; " { buf, buf.flatbuffers_indirect(0) }\n\n";
} }
if (struct_def.fixed) { if (struct_def.fixed) {
@@ -283,8 +286,8 @@ class LobsterGenerator : public BaseGenerator {
// Recursively generate arguments for a constructor, to deal with nested // Recursively generate arguments for a constructor, to deal with nested
// structs. // structs.
void StructBuilderArgs(const StructDef &struct_def, void StructBuilderArgs(const StructDef &struct_def, const char *nameprefix,
const char *nameprefix, std::string *code_ptr) { std::string *code_ptr) {
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;
@@ -293,7 +296,8 @@ class LobsterGenerator : public BaseGenerator {
// don't clash, and to make it obvious these arguments are constructing // don't clash, and to make it obvious these arguments are constructing
// a nested struct, prefix the name with the field name. // a nested struct, prefix the name with the field name.
StructBuilderArgs(*field.value.type.struct_def, StructBuilderArgs(*field.value.type.struct_def,
(nameprefix + (NormalizedName(field) + "_")).c_str(), code_ptr); (nameprefix + (NormalizedName(field) + "_")).c_str(),
code_ptr);
} else { } else {
std::string &code = *code_ptr; std::string &code = *code_ptr;
code += ", " + (nameprefix + NormalizedName(field)) + ":" + code += ", " + (nameprefix + NormalizedName(field)) + ":" +
@@ -304,8 +308,8 @@ class LobsterGenerator : public BaseGenerator {
// Recursively generate struct construction statements and instert manual // Recursively generate struct construction statements and instert manual
// padding. // padding.
void StructBuilderBody(const StructDef &struct_def, void StructBuilderBody(const StructDef &struct_def, const char *nameprefix,
const char *nameprefix, std::string *code_ptr) { std::string *code_ptr) {
std::string &code = *code_ptr; std::string &code = *code_ptr;
code += " b_.Prep(" + NumToString(struct_def.minalign) + ", " + code += " b_.Prep(" + NumToString(struct_def.minalign) + ", " +
NumToString(struct_def.bytesize) + ")\n"; NumToString(struct_def.bytesize) + ")\n";
@@ -316,7 +320,8 @@ class LobsterGenerator : public BaseGenerator {
code += " b_.Pad(" + NumToString(field.padding) + ")\n"; code += " b_.Pad(" + NumToString(field.padding) + ")\n";
if (IsStruct(field.value.type)) { if (IsStruct(field.value.type)) {
StructBuilderBody(*field.value.type.struct_def, StructBuilderBody(*field.value.type.struct_def,
(nameprefix + (NormalizedName(field) + "_")).c_str(), code_ptr); (nameprefix + (NormalizedName(field) + "_")).c_str(),
code_ptr);
} else { } else {
code += " b_.Prepend" + GenMethod(field.value.type) + "(" + code += " b_.Prepend" + GenMethod(field.value.type) + "(" +
nameprefix + NormalizedName(field) + ")\n"; nameprefix + NormalizedName(field) + ")\n";
@@ -325,11 +330,10 @@ class LobsterGenerator : public BaseGenerator {
} }
// Create a struct with a builder and the struct's arguments. // Create a struct with a builder and the struct's arguments.
void GenStructBuilder(const StructDef &struct_def, void GenStructBuilder(const StructDef &struct_def, std::string *code_ptr) {
std::string *code_ptr) {
std::string &code = *code_ptr; std::string &code = *code_ptr;
code += "def Create" + NormalizedName(struct_def) + code +=
"(b_:flatbuffers_builder"; "def Create" + NormalizedName(struct_def) + "(b_:flatbuffers_builder";
StructBuilderArgs(struct_def, "", code_ptr); StructBuilderArgs(struct_def, "", code_ptr);
code += "):\n"; code += "):\n";
StructBuilderBody(struct_def, "", code_ptr); StructBuilderBody(struct_def, "", code_ptr);
@@ -363,8 +367,8 @@ class LobsterGenerator : public BaseGenerator {
auto &struct_def = **it; auto &struct_def = **it;
GenStruct(struct_def, &code); GenStruct(struct_def, &code);
} }
return SaveFile((path_ + file_name_ + "_generated.lobster").c_str(), return SaveFile((path_ + file_name_ + "_generated.lobster").c_str(), code,
code, false); false);
} }
private: private:

View File

@@ -17,14 +17,13 @@
// independent from idl_parser, since this code is not needed for most clients // independent from idl_parser, since this code is not needed for most clients
#include <string> #include <string>
#include <unordered_set>
#include "flatbuffers/code_generators.h" #include "flatbuffers/code_generators.h"
#include "flatbuffers/flatbuffers.h" #include "flatbuffers/flatbuffers.h"
#include "flatbuffers/idl.h" #include "flatbuffers/idl.h"
#include "flatbuffers/util.h" #include "flatbuffers/util.h"
#include <unordered_set>
namespace flatbuffers { namespace flatbuffers {
namespace lua { namespace lua {
@@ -45,28 +44,9 @@ namespace lua {
: BaseGenerator(parser, path, file_name, "" /* not used */, : BaseGenerator(parser, path, file_name, "" /* not used */,
"" /* not used */) { "" /* not used */) {
static const char *const keywords[] = { static const char *const keywords[] = {
"and", "and", "break", "do", "else", "elseif", "end", "false", "for",
"break", "function", "goto", "if", "in", "local", "nil", "not", "or",
"do", "repeat", "return", "then", "true", "until", "while"
"else",
"elseif",
"end",
"false",
"for",
"function",
"goto",
"if",
"in",
"local",
"nil",
"not",
"or",
"repeat",
"return",
"then",
"true",
"until",
"while"
}; };
keywords_.insert(std::begin(keywords), std::end(keywords)); keywords_.insert(std::begin(keywords), std::end(keywords));
} }
@@ -74,16 +54,17 @@ namespace lua {
// Most field accessors need to retrieve and test the field offset first, // Most field accessors need to retrieve and test the field offset first,
// this is the prefix code for that. // this is the prefix code for that.
std::string OffsetPrefix(const FieldDef &field) { std::string OffsetPrefix(const FieldDef &field) {
return std::string(Indent) + return std::string(Indent) + "local o = " + SelfData + ":Offset(" +
"local o = " + SelfData + ":Offset(" + NumToString(field.value.offset) + ")\n" + NumToString(field.value.offset) + ")\n" + Indent +
Indent + "if o ~= 0 then\n"; "if o ~= 0 then\n";
} }
// Begin a class declaration. // Begin a class declaration.
void BeginClass(const StructDef &struct_def, std::string *code_ptr) { void BeginClass(const StructDef &struct_def, std::string *code_ptr) {
std::string &code = *code_ptr; std::string &code = *code_ptr;
code += "local " + NormalizedName(struct_def) + " = {} -- the module\n"; code += "local " + NormalizedName(struct_def) + " = {} -- the module\n";
code += "local " + NormalizedMetaName(struct_def) + " = {} -- the class metatable\n"; code += "local " + NormalizedMetaName(struct_def) +
" = {} -- the class metatable\n";
code += "\n"; code += "\n";
} }
@@ -110,7 +91,8 @@ namespace lua {
} }
// A single enum member. // A single enum member.
void EnumMember(const EnumDef &enum_def, const EnumVal &ev, std::string *code_ptr) { void EnumMember(const EnumDef &enum_def, const EnumVal &ev,
std::string *code_ptr) {
std::string &code = *code_ptr; std::string &code = *code_ptr;
code += std::string(Indent) + NormalizedName(ev) + " = " + code += std::string(Indent) + NormalizedName(ev) + " = " +
enum_def.ToString(ev) + ",\n"; enum_def.ToString(ev) + ",\n";
@@ -128,7 +110,9 @@ namespace lua {
code += "function " + NormalizedName(struct_def) + ".New()\n"; code += "function " + NormalizedName(struct_def) + ".New()\n";
code += std::string(Indent) + "local o = {}\n"; code += std::string(Indent) + "local o = {}\n";
code += std::string(Indent) + "setmetatable(o, {__index = " + NormalizedMetaName(struct_def) + "})\n"; code += std::string(Indent) +
"setmetatable(o, {__index = " + NormalizedMetaName(struct_def) +
"})\n";
code += std::string(Indent) + "return o\n"; code += std::string(Indent) + "return o\n";
code += EndFunc; code += EndFunc;
} }
@@ -138,22 +122,25 @@ namespace lua {
std::string *code_ptr) { std::string *code_ptr) {
std::string &code = *code_ptr; std::string &code = *code_ptr;
code += "function " + NormalizedName(struct_def) + ".GetRootAs" + NormalizedName(struct_def) + "(buf, offset)\n"; code += "function " + NormalizedName(struct_def) + ".GetRootAs" +
code += std::string(Indent) + "local n = flatbuffers.N.UOffsetT:Unpack(buf, offset)\n"; NormalizedName(struct_def) + "(buf, offset)\n";
code += std::string(Indent) + "local o = " + NormalizedName(struct_def) + ".New()\n"; code += std::string(Indent) +
"local n = flatbuffers.N.UOffsetT:Unpack(buf, offset)\n";
code += std::string(Indent) + "local o = " + NormalizedName(struct_def) +
".New()\n";
code += std::string(Indent) + "o:Init(buf, n + offset)\n"; code += std::string(Indent) + "o:Init(buf, n + offset)\n";
code += std::string(Indent) + "return o\n"; code += std::string(Indent) + "return o\n";
code += EndFunc; code += EndFunc;
} }
// Initialize an existing object with other data, to avoid an allocation. // Initialize an existing object with other data, to avoid an allocation.
void InitializeExisting(const StructDef &struct_def, void InitializeExisting(const StructDef &struct_def, std::string *code_ptr) {
std::string *code_ptr) {
std::string &code = *code_ptr; std::string &code = *code_ptr;
GenReceiver(struct_def, code_ptr); GenReceiver(struct_def, code_ptr);
code += "Init(buf, pos)\n"; code += "Init(buf, pos)\n";
code += std::string(Indent) + SelfData + " = flatbuffers.view.New(buf, pos)\n"; code +=
std::string(Indent) + SelfData + " = flatbuffers.view.New(buf, pos)\n";
code += EndFunc; code += EndFunc;
} }
@@ -165,7 +152,8 @@ namespace lua {
GenReceiver(struct_def, code_ptr); GenReceiver(struct_def, code_ptr);
code += MakeCamel(NormalizedName(field)) + "Length()\n"; code += MakeCamel(NormalizedName(field)) + "Length()\n";
code += OffsetPrefix(field); code += OffsetPrefix(field);
code += std::string(Indent) + Indent + "return " + SelfData + ":VectorLen(o)\n"; code +=
std::string(Indent) + Indent + "return " + SelfData + ":VectorLen(o)\n";
code += std::string(Indent) + End; code += std::string(Indent) + End;
code += std::string(Indent) + "return 0\n"; code += std::string(Indent) + "return 0\n";
code += EndFunc; code += EndFunc;
@@ -173,21 +161,20 @@ namespace lua {
// Get the value of a struct's scalar. // Get the value of a struct's scalar.
void GetScalarFieldOfStruct(const StructDef &struct_def, void GetScalarFieldOfStruct(const StructDef &struct_def,
const FieldDef &field, const FieldDef &field, std::string *code_ptr) {
std::string *code_ptr) {
std::string &code = *code_ptr; std::string &code = *code_ptr;
std::string getter = GenGetter(field.value.type); std::string getter = GenGetter(field.value.type);
GenReceiver(struct_def, code_ptr); GenReceiver(struct_def, code_ptr);
code += MakeCamel(NormalizedName(field)); code += MakeCamel(NormalizedName(field));
code += "()\n"; code += "()\n";
code += std::string(Indent) + "return " + getter; code += std::string(Indent) + "return " + getter;
code += std::string(SelfDataPos) + " + " + NumToString(field.value.offset) + ")\n"; code += std::string(SelfDataPos) + " + " + NumToString(field.value.offset) +
")\n";
code += EndFunc; code += EndFunc;
} }
// Get the value of a table's scalar. // Get the value of a table's scalar.
void GetScalarFieldOfTable(const StructDef &struct_def, void GetScalarFieldOfTable(const StructDef &struct_def, const FieldDef &field,
const FieldDef &field,
std::string *code_ptr) { std::string *code_ptr) {
std::string &code = *code_ptr; std::string &code = *code_ptr;
std::string getter = GenGetter(field.value.type); std::string getter = GenGetter(field.value.type);
@@ -197,16 +184,13 @@ namespace lua {
code += OffsetPrefix(field); code += OffsetPrefix(field);
getter += std::string("o + ") + SelfDataPos + ")"; getter += std::string("o + ") + SelfDataPos + ")";
auto is_bool = field.value.type.base_type == BASE_TYPE_BOOL; auto is_bool = field.value.type.base_type == BASE_TYPE_BOOL;
if (is_bool) { if (is_bool) { getter = "(" + getter + " ~= 0)"; }
getter = "(" + getter + " ~= 0)";
}
code += std::string(Indent) + Indent + "return " + getter + "\n"; code += std::string(Indent) + Indent + "return " + getter + "\n";
code += std::string(Indent) + End; code += std::string(Indent) + End;
std::string default_value; std::string default_value;
if (is_bool) { if (is_bool) {
default_value = field.value.constant == "0" ? "false" : "true"; default_value = field.value.constant == "0" ? "false" : "true";
} } else {
else {
default_value = field.value.constant; default_value = field.value.constant;
} }
code += std::string(Indent) + "return " + default_value + "\n"; code += std::string(Indent) + "return " + default_value + "\n";
@@ -216,13 +200,13 @@ namespace lua {
// Get a struct by initializing an existing struct. // Get a struct by initializing an existing struct.
// Specific to Struct. // Specific to Struct.
void GetStructFieldOfStruct(const StructDef &struct_def, void GetStructFieldOfStruct(const StructDef &struct_def,
const FieldDef &field, const FieldDef &field, std::string *code_ptr) {
std::string *code_ptr) {
std::string &code = *code_ptr; std::string &code = *code_ptr;
GenReceiver(struct_def, code_ptr); GenReceiver(struct_def, code_ptr);
code += MakeCamel(NormalizedName(field)); code += MakeCamel(NormalizedName(field));
code += "(obj)\n"; code += "(obj)\n";
code += std::string(Indent) + "obj:Init(" + SelfDataBytes + ", " + SelfDataPos + " + "; code += std::string(Indent) + "obj:Init(" + SelfDataBytes + ", " +
SelfDataPos + " + ";
code += NumToString(field.value.offset) + ")\n"; code += NumToString(field.value.offset) + ")\n";
code += std::string(Indent) + "return obj\n"; code += std::string(Indent) + "return obj\n";
code += EndFunc; code += EndFunc;
@@ -230,8 +214,7 @@ namespace lua {
// Get a struct by initializing an existing struct. // Get a struct by initializing an existing struct.
// Specific to Table. // Specific to Table.
void GetStructFieldOfTable(const StructDef &struct_def, void GetStructFieldOfTable(const StructDef &struct_def, const FieldDef &field,
const FieldDef &field,
std::string *code_ptr) { std::string *code_ptr) {
std::string &code = *code_ptr; std::string &code = *code_ptr;
GenReceiver(struct_def, code_ptr); GenReceiver(struct_def, code_ptr);
@@ -239,13 +222,16 @@ namespace lua {
code += "()\n"; code += "()\n";
code += OffsetPrefix(field); code += OffsetPrefix(field);
if (field.value.type.struct_def->fixed) { if (field.value.type.struct_def->fixed) {
code += std::string(Indent) + Indent + "local x = o + " + SelfDataPos + "\n"; code +=
std::string(Indent) + Indent + "local x = o + " + SelfDataPos + "\n";
} else {
code += std::string(Indent) + Indent + "local x = " + SelfData +
":Indirect(o + " + SelfDataPos + ")\n";
} }
else { code += std::string(Indent) + Indent + "local obj = require('" +
code += std::string(Indent) + Indent + "local x = " + SelfData + ":Indirect(o + " + SelfDataPos + ")\n"; TypeNameWithNamespace(field) + "').New()\n";
} code +=
code += std::string(Indent) + Indent + "local obj = require('" + TypeNameWithNamespace(field) + "').New()\n"; std::string(Indent) + Indent + "obj:Init(" + SelfDataBytes + ", x)\n";
code += std::string(Indent) + Indent + "obj:Init(" + SelfDataBytes + ", x)\n";
code += std::string(Indent) + Indent + "return obj\n"; code += std::string(Indent) + Indent + "return obj\n";
code += std::string(Indent) + End; code += std::string(Indent) + End;
code += EndFunc; code += EndFunc;
@@ -259,7 +245,8 @@ namespace lua {
code += MakeCamel(NormalizedName(field)); code += MakeCamel(NormalizedName(field));
code += "()\n"; code += "()\n";
code += OffsetPrefix(field); code += OffsetPrefix(field);
code += std::string(Indent) + Indent + "return " + GenGetter(field.value.type); code +=
std::string(Indent) + Indent + "return " + GenGetter(field.value.type);
code += std::string("o + ") + SelfDataPos + ")\n"; code += std::string("o + ") + SelfDataPos + ")\n";
code += std::string(Indent) + End; code += std::string(Indent) + End;
code += EndFunc; code += EndFunc;
@@ -276,13 +263,19 @@ namespace lua {
// TODO(rw): this works and is not the good way to it: // TODO(rw): this works and is not the good way to it:
// bool is_native_table = TypeName(field) == "*flatbuffers.Table"; // bool is_native_table = TypeName(field) == "*flatbuffers.Table";
// if (is_native_table) { // if (is_native_table) {
// code += std::string(Indent) + Indent + "from flatbuffers.table import Table\n"; // code += std::string(Indent) + Indent + "from flatbuffers.table import
// Table\n";
//} else { //} else {
// code += std::string(Indent) + Indent + // code += std::string(Indent) + Indent +
// code += "from ." + TypeName(field) + " import " + TypeName(field) + "\n"; // code += "from ." + TypeName(field) + " import " + TypeName(field) +
// "\n";
//} //}
code += std::string(Indent) + Indent + "local obj = flatbuffers.view.New(require('flatbuffers.binaryarray').New(0), 0)\n"; code +=
code += std::string(Indent) + Indent + GenGetter(field.value.type) + "obj, o)\n"; std::string(Indent) + Indent +
"local obj = "
"flatbuffers.view.New(require('flatbuffers.binaryarray').New(0), 0)\n";
code += std::string(Indent) + Indent + GenGetter(field.value.type) +
"obj, o)\n";
code += std::string(Indent) + Indent + "return obj\n"; code += std::string(Indent) + Indent + "return obj\n";
code += std::string(Indent) + End; code += std::string(Indent) + End;
code += EndFunc; code += EndFunc;
@@ -290,8 +283,7 @@ namespace lua {
// Get the value of a vector's struct member. // Get the value of a vector's struct member.
void GetMemberOfVectorOfStruct(const StructDef &struct_def, void GetMemberOfVectorOfStruct(const StructDef &struct_def,
const FieldDef &field, const FieldDef &field, std::string *code_ptr) {
std::string *code_ptr) {
std::string &code = *code_ptr; std::string &code = *code_ptr;
auto vectortype = field.value.type.VectorType(); auto vectortype = field.value.type.VectorType();
@@ -299,14 +291,18 @@ namespace lua {
code += MakeCamel(NormalizedName(field)); code += MakeCamel(NormalizedName(field));
code += "(j)\n"; code += "(j)\n";
code += OffsetPrefix(field); code += OffsetPrefix(field);
code += std::string(Indent) + Indent + "local x = " + SelfData + ":Vector(o)\n"; code +=
std::string(Indent) + Indent + "local x = " + SelfData + ":Vector(o)\n";
code += std::string(Indent) + Indent + "x = x + ((j-1) * "; code += std::string(Indent) + Indent + "x = x + ((j-1) * ";
code += NumToString(InlineSize(vectortype)) + ")\n"; code += NumToString(InlineSize(vectortype)) + ")\n";
if (!(vectortype.struct_def->fixed)) { if (!(vectortype.struct_def->fixed)) {
code += std::string(Indent) + Indent + "x = " + SelfData + ":Indirect(x)\n"; code +=
std::string(Indent) + Indent + "x = " + SelfData + ":Indirect(x)\n";
} }
code += std::string(Indent) + Indent + "local obj = require('" + TypeNameWithNamespace(field) + "').New()\n"; code += std::string(Indent) + Indent + "local obj = require('" +
code += std::string(Indent) + Indent + "obj:Init(" + SelfDataBytes + ", x)\n"; TypeNameWithNamespace(field) + "').New()\n";
code +=
std::string(Indent) + Indent + "obj:Init(" + SelfDataBytes + ", x)\n";
code += std::string(Indent) + Indent + "return obj\n"; code += std::string(Indent) + Indent + "return obj\n";
code += std::string(Indent) + End; code += std::string(Indent) + End;
code += EndFunc; code += EndFunc;
@@ -324,7 +320,8 @@ namespace lua {
code += MakeCamel(NormalizedName(field)); code += MakeCamel(NormalizedName(field));
code += "(j)\n"; code += "(j)\n";
code += OffsetPrefix(field); code += OffsetPrefix(field);
code += std::string(Indent) + Indent + "local a = " + SelfData + ":Vector(o)\n"; code +=
std::string(Indent) + Indent + "local a = " + SelfData + ":Vector(o)\n";
code += std::string(Indent) + Indent; code += std::string(Indent) + Indent;
code += "return " + GenGetter(field.value.type); code += "return " + GenGetter(field.value.type);
code += "a + ((j-1) * "; code += "a + ((j-1) * ";
@@ -332,26 +329,25 @@ namespace lua {
code += std::string(Indent) + End; code += std::string(Indent) + End;
if (vectortype.base_type == BASE_TYPE_STRING) { if (vectortype.base_type == BASE_TYPE_STRING) {
code += std::string(Indent) + "return ''\n"; code += std::string(Indent) + "return ''\n";
} } else {
else {
code += std::string(Indent) + "return 0\n"; code += std::string(Indent) + "return 0\n";
} }
code += EndFunc; code += EndFunc;
} }
// Begin the creator function signature. // Begin the creator function signature.
void BeginBuilderArgs(const StructDef &struct_def, void BeginBuilderArgs(const StructDef &struct_def, std::string *code_ptr) {
std::string *code_ptr) {
std::string &code = *code_ptr; std::string &code = *code_ptr;
code += "function " + NormalizedName(struct_def) + ".Create" + NormalizedName(struct_def); code += "function " + NormalizedName(struct_def) + ".Create" +
NormalizedName(struct_def);
code += "(builder"; code += "(builder";
} }
// Recursively generate arguments for a constructor, to deal with nested // Recursively generate arguments for a constructor, to deal with nested
// structs. // structs.
void StructBuilderArgs(const StructDef &struct_def, void StructBuilderArgs(const StructDef &struct_def, const char *nameprefix,
const char *nameprefix, std::string *code_ptr) { std::string *code_ptr) {
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;
@@ -360,9 +356,9 @@ namespace lua {
// don't clash, and to make it obvious these arguments are constructing // don't clash, and to make it obvious these arguments are constructing
// a nested struct, prefix the name with the field name. // a nested struct, prefix the name with the field name.
StructBuilderArgs(*field.value.type.struct_def, StructBuilderArgs(*field.value.type.struct_def,
(nameprefix + (NormalizedName(field) + "_")).c_str(), code_ptr); (nameprefix + (NormalizedName(field) + "_")).c_str(),
} code_ptr);
else { } else {
std::string &code = *code_ptr; std::string &code = *code_ptr;
code += std::string(", ") + nameprefix; code += std::string(", ") + nameprefix;
code += MakeCamel(NormalizedName(field), false); code += MakeCamel(NormalizedName(field), false);
@@ -378,22 +374,25 @@ namespace lua {
// Recursively generate struct construction statements and instert manual // Recursively generate struct construction statements and instert manual
// padding. // padding.
void StructBuilderBody(const StructDef &struct_def, void StructBuilderBody(const StructDef &struct_def, const char *nameprefix,
const char *nameprefix, std::string *code_ptr) { std::string *code_ptr) {
std::string &code = *code_ptr; std::string &code = *code_ptr;
code += std::string(Indent) + "builder:Prep(" + NumToString(struct_def.minalign) + ", "; code += std::string(Indent) + "builder:Prep(" +
NumToString(struct_def.minalign) + ", ";
code += NumToString(struct_def.bytesize) + ")\n"; code += NumToString(struct_def.bytesize) + ")\n";
for (auto it = struct_def.fields.vec.rbegin(); for (auto it = struct_def.fields.vec.rbegin();
it != struct_def.fields.vec.rend(); ++it) { it != struct_def.fields.vec.rend(); ++it) {
auto &field = **it; auto &field = **it;
if (field.padding) if (field.padding)
code += std::string(Indent) + "builder:Pad(" + NumToString(field.padding) + ")\n"; code += std::string(Indent) + "builder:Pad(" +
NumToString(field.padding) + ")\n";
if (IsStruct(field.value.type)) { if (IsStruct(field.value.type)) {
StructBuilderBody(*field.value.type.struct_def, StructBuilderBody(*field.value.type.struct_def,
(nameprefix + (NormalizedName(field) + "_")).c_str(), code_ptr); (nameprefix + (NormalizedName(field) + "_")).c_str(),
} code_ptr);
else { } else {
code += std::string(Indent) + "builder:Prepend" + GenMethod(field) + "("; code +=
std::string(Indent) + "builder:Prepend" + GenMethod(field) + "(";
code += nameprefix + MakeCamel(NormalizedName(field), false) + ")\n"; code += nameprefix + MakeCamel(NormalizedName(field), false) + ")\n";
} }
} }
@@ -406,8 +405,7 @@ namespace lua {
} }
// Get the value of a table's starting offset. // Get the value of a table's starting offset.
void GetStartOfTable(const StructDef &struct_def, void GetStartOfTable(const StructDef &struct_def, std::string *code_ptr) {
std::string *code_ptr) {
std::string &code = *code_ptr; std::string &code = *code_ptr;
code += "function " + NormalizedName(struct_def) + ".Start"; code += "function " + NormalizedName(struct_def) + ".Start";
code += "(builder) "; code += "(builder) ";
@@ -417,11 +415,11 @@ namespace lua {
} }
// Set the value of a table's field. // Set the value of a table's field.
void BuildFieldOfTable(const StructDef &struct_def, void BuildFieldOfTable(const StructDef &struct_def, const FieldDef &field,
const FieldDef &field, const size_t offset, const size_t offset, std::string *code_ptr) {
std::string *code_ptr) {
std::string &code = *code_ptr; std::string &code = *code_ptr;
code += "function " + NormalizedName(struct_def) + ".Add" + MakeCamel(NormalizedName(field)); code += "function " + NormalizedName(struct_def) + ".Add" +
MakeCamel(NormalizedName(field));
code += "(builder, "; code += "(builder, ";
code += MakeCamel(NormalizedName(field), false); code += MakeCamel(NormalizedName(field), false);
code += ") "; code += ") ";
@@ -441,8 +439,8 @@ namespace lua {
} }
// Set the value of one of the members of a table's vector. // Set the value of one of the members of a table's vector.
void BuildVectorOfTable(const StructDef &struct_def, void BuildVectorOfTable(const StructDef &struct_def, const FieldDef &field,
const FieldDef &field, std::string *code_ptr) { std::string *code_ptr) {
std::string &code = *code_ptr; std::string &code = *code_ptr;
code += "function " + NormalizedName(struct_def) + ".Start"; code += "function " + NormalizedName(struct_def) + ".Start";
code += MakeCamel(NormalizedName(field)); code += MakeCamel(NormalizedName(field));
@@ -456,8 +454,7 @@ namespace lua {
} }
// Get the offset of the end of a table. // Get the offset of the end of a table.
void GetEndOffsetOnTable(const StructDef &struct_def, void GetEndOffsetOnTable(const StructDef &struct_def, std::string *code_ptr) {
std::string *code_ptr) {
std::string &code = *code_ptr; std::string &code = *code_ptr;
code += "function " + NormalizedName(struct_def) + ".End"; code += "function " + NormalizedName(struct_def) + ".End";
code += "(builder) "; code += "(builder) ";
@@ -471,34 +468,32 @@ namespace lua {
} }
// Generate a struct field, conditioned on its child type(s). // Generate a struct field, conditioned on its child type(s).
void GenStructAccessor(const StructDef &struct_def, void GenStructAccessor(const StructDef &struct_def, const FieldDef &field,
const FieldDef &field, std::string *code_ptr) { std::string *code_ptr) {
GenComment(field.doc_comment, code_ptr, &def_comment); GenComment(field.doc_comment, code_ptr, &def_comment);
if (IsScalar(field.value.type.base_type)) { if (IsScalar(field.value.type.base_type)) {
if (struct_def.fixed) { if (struct_def.fixed) {
GetScalarFieldOfStruct(struct_def, field, code_ptr); GetScalarFieldOfStruct(struct_def, field, code_ptr);
} } else {
else {
GetScalarFieldOfTable(struct_def, field, code_ptr); GetScalarFieldOfTable(struct_def, field, code_ptr);
} }
} } else {
else {
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) {
GetStructFieldOfStruct(struct_def, field, code_ptr); GetStructFieldOfStruct(struct_def, field, code_ptr);
} } else {
else {
GetStructFieldOfTable(struct_def, field, code_ptr); GetStructFieldOfTable(struct_def, field, code_ptr);
} }
break; break;
case BASE_TYPE_STRING: GetStringField(struct_def, field, code_ptr); break; case BASE_TYPE_STRING:
GetStringField(struct_def, 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_STRUCT) { if (vectortype.base_type == BASE_TYPE_STRUCT) {
GetMemberOfVectorOfStruct(struct_def, field, code_ptr); GetMemberOfVectorOfStruct(struct_def, field, code_ptr);
} } else {
else {
GetMemberOfVectorOfNonStruct(struct_def, field, code_ptr); GetMemberOfVectorOfNonStruct(struct_def, field, code_ptr);
} }
break; break;
@@ -513,8 +508,7 @@ namespace lua {
} }
// Generate table constructors, conditioned on its members' types. // Generate table constructors, conditioned on its members' types.
void GenTableBuilders(const StructDef &struct_def, void GenTableBuilders(const StructDef &struct_def, std::string *code_ptr) {
std::string *code_ptr) {
GetStartOfTable(struct_def, code_ptr); GetStartOfTable(struct_def, code_ptr);
for (auto it = struct_def.fields.vec.begin(); for (auto it = struct_def.fields.vec.begin();
@@ -561,8 +555,7 @@ namespace lua {
if (struct_def.fixed) { if (struct_def.fixed) {
// create a struct constructor function // create a struct constructor function
GenStructBuilder(struct_def, code_ptr); GenStructBuilder(struct_def, code_ptr);
} } else {
else {
// Create a set of functions that allow table construction. // Create a set of functions that allow table construction.
GenTableBuilders(struct_def, code_ptr); GenTableBuilders(struct_def, code_ptr);
} }
@@ -574,8 +567,7 @@ namespace lua {
GenComment(enum_def.doc_comment, code_ptr, &def_comment); GenComment(enum_def.doc_comment, code_ptr, &def_comment);
BeginEnum(NormalizedName(enum_def), code_ptr); BeginEnum(NormalizedName(enum_def), code_ptr);
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;
GenComment(ev.doc_comment, code_ptr, &def_comment, Indent); GenComment(ev.doc_comment, code_ptr, &def_comment, Indent);
EnumMember(enum_def, ev, code_ptr); EnumMember(enum_def, ev, code_ptr);
@@ -631,7 +623,8 @@ namespace lua {
} }
std::string GetNamespace(const Type &type) { std::string GetNamespace(const Type &type) {
return type.struct_def->defined_namespace->GetFullyQualifiedName(type.struct_def->name); return type.struct_def->defined_namespace->GetFullyQualifiedName(
type.struct_def->name);
} }
std::string TypeName(const FieldDef &field) { std::string TypeName(const FieldDef &field) {
@@ -643,8 +636,7 @@ namespace lua {
} }
// Create a struct with a builder and the struct's arguments. // Create a struct with a builder and the struct's arguments.
void GenStructBuilder(const StructDef &struct_def, void GenStructBuilder(const StructDef &struct_def, std::string *code_ptr) {
std::string *code_ptr) {
BeginBuilderArgs(struct_def, code_ptr); BeginBuilderArgs(struct_def, code_ptr);
StructBuilderArgs(struct_def, "", code_ptr); StructBuilderArgs(struct_def, "", code_ptr);
EndBuilderArgs(code_ptr); EndBuilderArgs(code_ptr);
@@ -711,11 +703,13 @@ namespace lua {
BeginFile(LastNamespacePart(*def.defined_namespace), needs_imports, &code); BeginFile(LastNamespacePart(*def.defined_namespace), needs_imports, &code);
code += classcode; code += classcode;
code += "\n"; code += "\n";
code += "return " + NormalizedName(def) + " " + Comment + "return the module"; code +=
"return " + NormalizedName(def) + " " + Comment + "return the module";
std::string filename = std::string filename =
NamespaceDir(*def.defined_namespace) + NormalizedName(def) + ".lua"; NamespaceDir(*def.defined_namespace) + NormalizedName(def) + ".lua";
return SaveFile(filename.c_str(), code, false); return SaveFile(filename.c_str(), code, false);
} }
private: private:
std::unordered_set<std::string> keywords_; std::unordered_set<std::string> keywords_;
}; };

View File

@@ -826,7 +826,8 @@ class PhpGenerator : public BaseGenerator {
code += Indent + "private static $names = array(\n"; code += Indent + "private static $names = array(\n";
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;
code += Indent + Indent + enum_def.name + "::" + ev.name + "=>" + "\"" + ev.name + "\",\n"; code += Indent + Indent + enum_def.name + "::" + ev.name + "=>" + "\"" +
ev.name + "\",\n";
} }
code += Indent + ");\n\n"; code += Indent + ");\n\n";

View File

@@ -17,14 +17,13 @@
// independent from idl_parser, since this code is not needed for most clients // independent from idl_parser, since this code is not needed for most clients
#include <string> #include <string>
#include <unordered_set>
#include "flatbuffers/code_generators.h" #include "flatbuffers/code_generators.h"
#include "flatbuffers/flatbuffers.h" #include "flatbuffers/flatbuffers.h"
#include "flatbuffers/idl.h" #include "flatbuffers/idl.h"
#include "flatbuffers/util.h" #include "flatbuffers/util.h"
#include <unordered_set>
namespace flatbuffers { namespace flatbuffers {
namespace python { namespace python {
@@ -40,39 +39,11 @@ class PythonGenerator : public BaseGenerator {
"" /* not used */), "" /* not used */),
float_const_gen_("float('nan')", "float('inf')", "float('-inf')") { float_const_gen_("float('nan')", "float('inf')", "float('-inf')") {
static const char *const keywords[] = { static const char *const keywords[] = {
"False", "False", "None", "True", "and", "as", "assert", "break",
"None", "class", "continue", "def", "del", "elif", "else", "except",
"True", "finally", "for", "from", "global", "if", "import", "in",
"and", "is", "lambda", "nonlocal", "not", "or", "pass", "raise",
"as", "return", "try", "while", "with", "yield"
"assert",
"break",
"class",
"continue",
"def",
"del",
"elif",
"else",
"except",
"finally",
"for",
"from",
"global",
"if",
"import",
"in",
"is",
"lambda",
"nonlocal",
"not",
"or",
"pass",
"raise",
"return",
"try",
"while",
"with",
"yield"
}; };
keywords_.insert(std::begin(keywords), std::end(keywords)); keywords_.insert(std::begin(keywords), std::end(keywords));
} }
@@ -148,8 +119,7 @@ class PythonGenerator : public BaseGenerator {
} }
// Initialize an existing object with other data, to avoid an allocation. // Initialize an existing object with other data, to avoid an allocation.
void InitializeExisting(const StructDef &struct_def, void InitializeExisting(const StructDef &struct_def, std::string *code_ptr) {
std::string *code_ptr) {
std::string &code = *code_ptr; std::string &code = *code_ptr;
GenReceiver(struct_def, code_ptr); GenReceiver(struct_def, code_ptr);
@@ -172,8 +142,7 @@ class PythonGenerator : public BaseGenerator {
// Get the value of a struct's scalar. // Get the value of a struct's scalar.
void GetScalarFieldOfStruct(const StructDef &struct_def, void GetScalarFieldOfStruct(const StructDef &struct_def,
const FieldDef &field, const FieldDef &field, std::string *code_ptr) {
std::string *code_ptr) {
std::string &code = *code_ptr; std::string &code = *code_ptr;
std::string getter = GenGetter(field.value.type); std::string getter = GenGetter(field.value.type);
GenReceiver(struct_def, code_ptr); GenReceiver(struct_def, code_ptr);
@@ -184,8 +153,7 @@ class PythonGenerator : public BaseGenerator {
} }
// Get the value of a table's scalar. // Get the value of a table's scalar.
void GetScalarFieldOfTable(const StructDef &struct_def, void GetScalarFieldOfTable(const StructDef &struct_def, const FieldDef &field,
const FieldDef &field,
std::string *code_ptr) { std::string *code_ptr) {
std::string &code = *code_ptr; std::string &code = *code_ptr;
std::string getter = GenGetter(field.value.type); std::string getter = GenGetter(field.value.type);
@@ -195,9 +163,7 @@ 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) { if (is_bool) { getter = "bool(" + getter + ")"; }
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 (is_bool) { if (is_bool) {
@@ -213,8 +179,7 @@ class PythonGenerator : public BaseGenerator {
// Get a struct by initializing an existing struct. // Get a struct by initializing an existing struct.
// Specific to Struct. // Specific to Struct.
void GetStructFieldOfStruct(const StructDef &struct_def, void GetStructFieldOfStruct(const StructDef &struct_def,
const FieldDef &field, const FieldDef &field, std::string *code_ptr) {
std::string *code_ptr) {
std::string &code = *code_ptr; std::string &code = *code_ptr;
GenReceiver(struct_def, code_ptr); GenReceiver(struct_def, code_ptr);
code += MakeCamel(NormalizedName(field)); code += MakeCamel(NormalizedName(field));
@@ -250,8 +215,7 @@ class PythonGenerator : public BaseGenerator {
// Get a struct by initializing an existing struct. // Get a struct by initializing an existing struct.
// Specific to Table. // Specific to Table.
void GetStructFieldOfTable(const StructDef &struct_def, void GetStructFieldOfTable(const StructDef &struct_def, const FieldDef &field,
const FieldDef &field,
std::string *code_ptr) { std::string *code_ptr) {
std::string &code = *code_ptr; std::string &code = *code_ptr;
GenReceiver(struct_def, code_ptr); GenReceiver(struct_def, code_ptr);
@@ -296,7 +260,8 @@ class PythonGenerator : public BaseGenerator {
// TODO(rw): this works and is not the good way to it: // TODO(rw): this works and is not the good way to it:
bool is_native_table = TypeName(field) == "*flatbuffers.Table"; bool is_native_table = TypeName(field) == "*flatbuffers.Table";
if (is_native_table) { if (is_native_table) {
code += Indent + Indent + Indent + "from flatbuffers.table import Table\n"; code +=
Indent + Indent + Indent + "from flatbuffers.table import Table\n";
} else { } else {
code += Indent + Indent + Indent; code += Indent + Indent + Indent;
code += "from ." + TypeName(field) + " import " + TypeName(field) + "\n"; code += "from ." + TypeName(field) + " import " + TypeName(field) + "\n";
@@ -309,8 +274,7 @@ class PythonGenerator : public BaseGenerator {
// Get the value of a vector's struct member. // Get the value of a vector's struct member.
void GetMemberOfVectorOfStruct(const StructDef &struct_def, void GetMemberOfVectorOfStruct(const StructDef &struct_def,
const FieldDef &field, const FieldDef &field, std::string *code_ptr) {
std::string *code_ptr) {
std::string &code = *code_ptr; std::string &code = *code_ptr;
auto vectortype = field.value.type.VectorType(); auto vectortype = field.value.type.VectorType();
@@ -388,8 +352,7 @@ class PythonGenerator : public BaseGenerator {
} }
// Begin the creator function signature. // Begin the creator function signature.
void BeginBuilderArgs(const StructDef &struct_def, void BeginBuilderArgs(const StructDef &struct_def, std::string *code_ptr) {
std::string *code_ptr) {
std::string &code = *code_ptr; std::string &code = *code_ptr;
code += "\n"; code += "\n";
@@ -399,8 +362,8 @@ class PythonGenerator : public BaseGenerator {
// Recursively generate arguments for a constructor, to deal with nested // Recursively generate arguments for a constructor, to deal with nested
// structs. // structs.
void StructBuilderArgs(const StructDef &struct_def, void StructBuilderArgs(const StructDef &struct_def, const char *nameprefix,
const char *nameprefix, std::string *code_ptr) { std::string *code_ptr) {
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;
@@ -484,8 +447,7 @@ class PythonGenerator : public BaseGenerator {
} }
// Get the value of a table's starting offset. // Get the value of a table's starting offset.
void GetStartOfTable(const StructDef &struct_def, void GetStartOfTable(const StructDef &struct_def, std::string *code_ptr) {
std::string *code_ptr) {
std::string &code = *code_ptr; std::string &code = *code_ptr;
code += "def " + NormalizedName(struct_def) + "Start"; code += "def " + NormalizedName(struct_def) + "Start";
code += "(builder): "; code += "(builder): ";
@@ -495,11 +457,11 @@ class PythonGenerator : public BaseGenerator {
} }
// Set the value of a table's field. // Set the value of a table's field.
void BuildFieldOfTable(const StructDef &struct_def, void BuildFieldOfTable(const StructDef &struct_def, const FieldDef &field,
const FieldDef &field, const size_t offset, const size_t offset, std::string *code_ptr) {
std::string *code_ptr) {
std::string &code = *code_ptr; std::string &code = *code_ptr;
code += "def " + NormalizedName(struct_def) + "Add" + MakeCamel(NormalizedName(field)); code += "def " + NormalizedName(struct_def) + "Add" +
MakeCamel(NormalizedName(field));
code += "(builder, "; code += "(builder, ";
code += MakeCamel(NormalizedName(field), false); code += MakeCamel(NormalizedName(field), false);
code += "): "; code += "): ";
@@ -521,8 +483,8 @@ class PythonGenerator : public BaseGenerator {
} }
// Set the value of one of the members of a table's vector. // Set the value of one of the members of a table's vector.
void BuildVectorOfTable(const StructDef &struct_def, void BuildVectorOfTable(const StructDef &struct_def, const FieldDef &field,
const FieldDef &field, std::string *code_ptr) { std::string *code_ptr) {
std::string &code = *code_ptr; std::string &code = *code_ptr;
code += "def " + NormalizedName(struct_def) + "Start"; code += "def " + NormalizedName(struct_def) + "Start";
code += MakeCamel(NormalizedName(field)); code += MakeCamel(NormalizedName(field));
@@ -536,8 +498,7 @@ class PythonGenerator : public BaseGenerator {
} }
// Get the offset of the end of a table. // Get the offset of the end of a table.
void GetEndOffsetOnTable(const StructDef &struct_def, void GetEndOffsetOnTable(const StructDef &struct_def, std::string *code_ptr) {
std::string *code_ptr) {
std::string &code = *code_ptr; std::string &code = *code_ptr;
code += "def " + NormalizedName(struct_def) + "End"; code += "def " + NormalizedName(struct_def) + "End";
code += "(builder): "; code += "(builder): ";
@@ -552,8 +513,8 @@ class PythonGenerator : public BaseGenerator {
} }
// Generate a struct field, conditioned on its child type(s). // Generate a struct field, conditioned on its child type(s).
void GenStructAccessor(const StructDef &struct_def, void GenStructAccessor(const StructDef &struct_def, const FieldDef &field,
const FieldDef &field, std::string *code_ptr) { std::string *code_ptr) {
GenComment(field.doc_comment, code_ptr, &def_comment, Indent.c_str()); GenComment(field.doc_comment, code_ptr, &def_comment, Indent.c_str());
if (IsScalar(field.value.type.base_type)) { if (IsScalar(field.value.type.base_type)) {
if (struct_def.fixed) { if (struct_def.fixed) {
@@ -572,7 +533,9 @@ class PythonGenerator : public BaseGenerator {
GetStructFieldOfTable(struct_def, field, code_ptr); GetStructFieldOfTable(struct_def, field, code_ptr);
} }
break; break;
case BASE_TYPE_STRING: GetStringField(struct_def, field, code_ptr); break; case BASE_TYPE_STRING:
GetStringField(struct_def, 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_STRUCT) { if (vectortype.base_type == BASE_TYPE_STRUCT) {
@@ -593,8 +556,7 @@ class PythonGenerator : public BaseGenerator {
} }
// Generate table constructors, conditioned on its members' types. // Generate table constructors, conditioned on its members' types.
void GenTableBuilders(const StructDef &struct_def, void GenTableBuilders(const StructDef &struct_def, std::string *code_ptr) {
std::string *code_ptr) {
GetStartOfTable(struct_def, code_ptr); GetStartOfTable(struct_def, code_ptr);
for (auto it = struct_def.fields.vec.begin(); for (auto it = struct_def.fields.vec.begin();
@@ -738,8 +700,7 @@ class PythonGenerator : public BaseGenerator {
} }
// Create a struct with a builder and the struct's arguments. // Create a struct with a builder and the struct's arguments.
void GenStructBuilder(const StructDef &struct_def, void GenStructBuilder(const StructDef &struct_def, std::string *code_ptr) {
std::string *code_ptr) {
BeginBuilderArgs(struct_def, code_ptr); BeginBuilderArgs(struct_def, code_ptr);
StructBuilderArgs(struct_def, "", code_ptr); StructBuilderArgs(struct_def, "", code_ptr);
EndBuilderArgs(code_ptr); EndBuilderArgs(code_ptr);
@@ -807,6 +768,7 @@ class PythonGenerator : public BaseGenerator {
NamespaceDir(*def.defined_namespace) + NormalizedName(def) + ".py"; NamespaceDir(*def.defined_namespace) + NormalizedName(def) + ".py";
return SaveFile(filename.c_str(), code, false); return SaveFile(filename.c_str(), code, false);
} }
private: private:
std::unordered_set<std::string> keywords_; std::unordered_set<std::string> keywords_;
const SimpleFloatConstantGenerator float_const_gen_; const SimpleFloatConstantGenerator float_const_gen_;

View File

@@ -40,9 +40,7 @@ std::string MakeSnakeCase(const std::string &in) {
} else if (!islower(in[i])) { } else if (!islower(in[i])) {
// Prevent duplicate underscores for Upper_Snake_Case strings // Prevent duplicate underscores for Upper_Snake_Case strings
// and UPPERCASE strings. // and UPPERCASE strings.
if (islower(in[i - 1])) { if (islower(in[i - 1])) { s += '_'; }
s += '_';
}
s += static_cast<char>(tolower(in[i])); s += static_cast<char>(tolower(in[i]));
} else { } else {
s += in[i]; s += in[i];
@@ -200,77 +198,19 @@ class RustGenerator : public BaseGenerator {
// changes to that webpage in the future. // changes to that webpage in the future.
// currently-used keywords // currently-used keywords
"as", "as", "break", "const", "continue", "crate", "else", "enum", "extern",
"break", "false", "fn", "for", "if", "impl", "in", "let", "loop", "match", "mod",
"const", "move", "mut", "pub", "ref", "return", "Self", "self", "static", "struct",
"continue", "super", "trait", "true", "type", "unsafe", "use", "where", "while",
"crate",
"else",
"enum",
"extern",
"false",
"fn",
"for",
"if",
"impl",
"in",
"let",
"loop",
"match",
"mod",
"move",
"mut",
"pub",
"ref",
"return",
"Self",
"self",
"static",
"struct",
"super",
"trait",
"true",
"type",
"unsafe",
"use",
"where",
"while",
// future possible keywords // future possible keywords
"abstract", "abstract", "alignof", "become", "box", "do", "final", "macro",
"alignof", "offsetof", "override", "priv", "proc", "pure", "sizeof", "typeof",
"become", "unsized", "virtual", "yield",
"box",
"do",
"final",
"macro",
"offsetof",
"override",
"priv",
"proc",
"pure",
"sizeof",
"typeof",
"unsized",
"virtual",
"yield",
// other rust terms we should not use // other rust terms we should not use
"std", "std", "usize", "isize", "u8", "i8", "u16", "i16", "u32", "i32", "u64",
"usize", "i64", "u128", "i128", "f32", "f64",
"isize",
"u8",
"i8",
"u16",
"i16",
"u32",
"i32",
"u64",
"i64",
"u128",
"i128",
"f32",
"f64",
// These are terms the code generator can implement on types. // These are terms the code generator can implement on types.
// //
@@ -281,13 +221,9 @@ class RustGenerator : public BaseGenerator {
// implementation detail, and how we implement methods could change in // implementation detail, and how we implement methods could change in
// the future. as a result, we proactively block these out as reserved // the future. as a result, we proactively block these out as reserved
// words. // words.
"follow", "follow", "push", "size", "alignment", "to_little_endian",
"push", "from_little_endian", nullptr
"size", };
"alignment",
"to_little_endian",
"from_little_endian",
nullptr };
for (auto kw = keywords; *kw; kw++) keywords_.insert(*kw); for (auto kw = keywords; *kw; kw++) keywords_.insert(*kw);
} }
@@ -310,8 +246,7 @@ class RustGenerator : public BaseGenerator {
// TODO(rw): Use a set data structure to reduce namespace evaluations from // TODO(rw): Use a set data structure to reduce namespace evaluations from
// O(n**2) to O(n). // O(n**2) to O(n).
for (auto ns_it = parser_.namespaces_.begin(); for (auto ns_it = parser_.namespaces_.begin();
ns_it != parser_.namespaces_.end(); ns_it != parser_.namespaces_.end(); ++ns_it) {
++ns_it) {
const auto &ns = *ns_it; const auto &ns = *ns_it;
// Generate code for all the enum declarations. // Generate code for all the enum declarations.
@@ -381,8 +316,12 @@ class RustGenerator : public BaseGenerator {
case ftBool: case ftBool:
case ftEnumKey: case ftEnumKey:
case ftUnionKey: case ftUnionKey:
case ftUnionValue: { return false; } case ftUnionValue: {
default: { return true; } return false;
}
default: {
return true;
}
} }
} }
@@ -393,13 +332,9 @@ 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) { if (field.deprecated) { continue; }
continue;
}
if (TableBuilderTypeNeedsLifetime(field.value.type)) { if (TableBuilderTypeNeedsLifetime(field.value.type)) { return true; }
return true;
}
} }
return false; return false;
@@ -412,8 +347,12 @@ class RustGenerator : public BaseGenerator {
case ftInteger: // requires endian swap case ftInteger: // requires endian swap
case ftFloat: // requires endian swap case ftFloat: // requires endian swap
case ftBool: // no endian-swap, but do the copy for UX consistency case ftBool: // no endian-swap, but do the copy for UX consistency
case ftEnumKey: { return true; } // requires endian swap case ftEnumKey: {
case ftStruct: { return false; } // no endian swap return true;
} // requires endian swap
case ftStruct: {
return false;
} // no endian swap
default: { default: {
// logic error: no other types can be struct members. // logic error: no other types can be struct members.
FLATBUFFERS_ASSERT(false && "invalid struct member type"); FLATBUFFERS_ASSERT(false && "invalid struct member type");
@@ -486,9 +425,7 @@ class RustGenerator : public BaseGenerator {
++i; ++i;
} }
for (; s != src->components.end(); ++s) { for (; s != src->components.end(); ++s) { stream << "super::"; }
stream << "super::";
}
for (; d != dst->components.end(); ++d) { for (; d != dst->components.end(); ++d) {
stream << MakeSnakeCase(*d) + "::"; stream << MakeSnakeCase(*d) + "::";
} }
@@ -509,8 +446,12 @@ class RustGenerator : public BaseGenerator {
case ftFloat: case ftFloat:
case ftBool: case ftBool:
case ftEnumKey: case ftEnumKey:
case ftUnionKey: { break; } case ftUnionKey: {
default: { FLATBUFFERS_ASSERT(false && "incorrect type given");} break;
}
default: {
FLATBUFFERS_ASSERT(false && "incorrect type given");
}
} }
// clang-format off // clang-format off
@@ -560,13 +501,17 @@ class RustGenerator : public BaseGenerator {
case ftBool: case ftBool:
case ftEnumKey: case ftEnumKey:
case ftUnionKey: { case ftUnionKey: {
return GetTypeBasic(type); } return GetTypeBasic(type);
}
case ftTable: { case ftTable: {
return WrapInNameSpace(type.struct_def->defined_namespace, return WrapInNameSpace(type.struct_def->defined_namespace,
type.struct_def->name) + "<'a>"; } type.struct_def->name) +
"<'a>";
}
default: { default: {
return WrapInNameSpace(type.struct_def->defined_namespace, return WrapInNameSpace(type.struct_def->defined_namespace,
type.struct_def->name); } type.struct_def->name);
}
} }
} }
@@ -586,7 +531,8 @@ class RustGenerator : public BaseGenerator {
GenComment(enum_def.doc_comment); GenComment(enum_def.doc_comment);
code_ += "#[allow(non_camel_case_types)]"; code_ += "#[allow(non_camel_case_types)]";
code_ += "#[repr({{BASE_TYPE}})]"; code_ += "#[repr({{BASE_TYPE}})]";
code_ += "#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]"; code_ +=
"#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]";
code_ += "pub enum " + Name(enum_def) + " {"; code_ += "pub enum " + Name(enum_def) + " {";
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) {
@@ -644,7 +590,8 @@ class RustGenerator : public BaseGenerator {
code_ += " type Output = {{ENUM_NAME}};"; code_ += " type Output = {{ENUM_NAME}};";
code_ += " #[inline]"; code_ += " #[inline]";
code_ += " fn push(&self, dst: &mut [u8], _rest: &[u8]) {"; code_ += " fn push(&self, dst: &mut [u8], _rest: &[u8]) {";
code_ += " flatbuffers::emplace_scalar::<{{ENUM_NAME}}>" code_ +=
" flatbuffers::emplace_scalar::<{{ENUM_NAME}}>"
"(dst, *self);"; "(dst, *self);";
code_ += " }"; code_ += " }";
code_ += "}"; code_ += "}";
@@ -727,8 +674,12 @@ class RustGenerator : public BaseGenerator {
std::string GetDefaultScalarValue(const FieldDef &field) { std::string GetDefaultScalarValue(const FieldDef &field) {
switch (GetFullType(field.value.type)) { switch (GetFullType(field.value.type)) {
case ftInteger: { return GetDefaultConstant(field); } case ftInteger: {
case ftFloat: { return GetDefaultConstant(field); } return GetDefaultConstant(field);
}
case ftFloat: {
return GetDefaultConstant(field);
}
case ftBool: { case ftBool: {
return field.value.constant == "0" ? "false" : "true"; return field.value.constant == "0" ? "false" : "true";
} }
@@ -742,7 +693,9 @@ class RustGenerator : public BaseGenerator {
// All pointer-ish types have a default value of None, because they are // All pointer-ish types have a default value of None, because they are
// wrapped in Option. // wrapped in Option.
default: { return "None"; } default: {
return "None";
}
} }
} }
@@ -774,7 +727,7 @@ class RustGenerator : public BaseGenerator {
} }
case ftTable: { case ftTable: {
const auto typname = WrapInNameSpace(*type.struct_def); const auto typname = WrapInNameSpace(*type.struct_def);
return "Option<flatbuffers::WIPOffset<" + typname + "<" + lifetime + \ return "Option<flatbuffers::WIPOffset<" + typname + "<" + lifetime +
">>>"; ">>>";
} }
case ftString: { case ftString: {
@@ -792,40 +745,40 @@ class RustGenerator : public BaseGenerator {
case ftVectorOfInteger: case ftVectorOfInteger:
case ftVectorOfFloat: { case ftVectorOfFloat: {
const auto typname = GetTypeBasic(type.VectorType()); const auto typname = GetTypeBasic(type.VectorType());
return "Option<flatbuffers::WIPOffset<flatbuffers::Vector<" + \ return "Option<flatbuffers::WIPOffset<flatbuffers::Vector<" + lifetime +
lifetime + ", " + typname + ">>>"; ", " + typname + ">>>";
} }
case ftVectorOfBool: { case ftVectorOfBool: {
return "Option<flatbuffers::WIPOffset<flatbuffers::Vector<" + \ return "Option<flatbuffers::WIPOffset<flatbuffers::Vector<" + lifetime +
lifetime + ", bool>>>"; ", bool>>>";
} }
case ftVectorOfEnumKey: { case ftVectorOfEnumKey: {
const auto typname = WrapInNameSpace(*type.enum_def); const auto typname = WrapInNameSpace(*type.enum_def);
return "Option<flatbuffers::WIPOffset<flatbuffers::Vector<" + \ return "Option<flatbuffers::WIPOffset<flatbuffers::Vector<" + lifetime +
lifetime + ", " + typname + ">>>"; ", " + typname + ">>>";
} }
case ftVectorOfStruct: { case ftVectorOfStruct: {
const auto typname = WrapInNameSpace(*type.struct_def); const auto typname = WrapInNameSpace(*type.struct_def);
return "Option<flatbuffers::WIPOffset<flatbuffers::Vector<" + \ return "Option<flatbuffers::WIPOffset<flatbuffers::Vector<" + lifetime +
lifetime + ", " + typname + ">>>"; ", " + typname + ">>>";
} }
case ftVectorOfTable: { case ftVectorOfTable: {
const auto typname = WrapInNameSpace(*type.struct_def); const auto typname = WrapInNameSpace(*type.struct_def);
return "Option<flatbuffers::WIPOffset<flatbuffers::Vector<" + \ return "Option<flatbuffers::WIPOffset<flatbuffers::Vector<" + lifetime +
lifetime + ", flatbuffers::ForwardsUOffset<" + typname + \ ", flatbuffers::ForwardsUOffset<" + typname + "<" + lifetime +
"<" + lifetime + ">>>>>"; ">>>>>";
} }
case ftVectorOfString: { case ftVectorOfString: {
return "Option<flatbuffers::WIPOffset<flatbuffers::Vector<" + \ return "Option<flatbuffers::WIPOffset<flatbuffers::Vector<" + lifetime +
lifetime + ", flatbuffers::ForwardsUOffset<&" + lifetime + \ ", flatbuffers::ForwardsUOffset<&" + lifetime + " str>>>>";
" str>>>>";
} }
case ftVectorOfUnionValue: { case ftVectorOfUnionValue: {
const auto typname = WrapInNameSpace(*type.enum_def) + \ const auto typname =
"UnionTableOffset"; WrapInNameSpace(*type.enum_def) + "UnionTableOffset";
return "Option<flatbuffers::WIPOffset<flatbuffers::Vector<" + \ return "Option<flatbuffers::WIPOffset<flatbuffers::Vector<" + lifetime +
lifetime + ", flatbuffers::ForwardsUOffset<" ", flatbuffers::ForwardsUOffset<"
"flatbuffers::Table<" + lifetime + ">>>>"; "flatbuffers::Table<" +
lifetime + ">>>>";
} }
} }
return "INVALID_CODE_GENERATION"; // for return analysis return "INVALID_CODE_GENERATION"; // for return analysis
@@ -839,11 +792,14 @@ class RustGenerator : public BaseGenerator {
switch (GetFullType(field.value.type)) { switch (GetFullType(field.value.type)) {
case ftUnionKey: case ftUnionKey:
case ftEnumKey: { case ftEnumKey: {
const std::string basetype = GetTypeBasic(field.value.type); //<- never used const std::string basetype =
GetTypeBasic(field.value.type); //<- never used
return GetDefaultScalarValue(field); return GetDefaultScalarValue(field);
} }
default: { return GetDefaultScalarValue(field); } default: {
return GetDefaultScalarValue(field);
}
} }
} }
@@ -854,38 +810,38 @@ class RustGenerator : public BaseGenerator {
switch (GetFullType(field.value.type)) { switch (GetFullType(field.value.type)) {
case ftVectorOfStruct: { case ftVectorOfStruct: {
const auto typname = WrapInNameSpace(*type.struct_def); const auto typname = WrapInNameSpace(*type.struct_def);
return "flatbuffers::WIPOffset<flatbuffers::Vector<" + lifetime + \ return "flatbuffers::WIPOffset<flatbuffers::Vector<" + lifetime + ", " +
", " + typname + ">>"; typname + ">>";
} }
case ftVectorOfTable: { case ftVectorOfTable: {
const auto typname = WrapInNameSpace(*type.struct_def); const auto typname = WrapInNameSpace(*type.struct_def);
return "flatbuffers::WIPOffset<flatbuffers::Vector<" + lifetime + \ return "flatbuffers::WIPOffset<flatbuffers::Vector<" + lifetime +
", flatbuffers::ForwardsUOffset<" + typname + \ ", flatbuffers::ForwardsUOffset<" + typname + "<" + lifetime +
"<" + lifetime + ">>>>"; ">>>>";
} }
case ftVectorOfInteger: case ftVectorOfInteger:
case ftVectorOfFloat: { case ftVectorOfFloat: {
const auto typname = GetTypeBasic(type.VectorType()); const auto typname = GetTypeBasic(type.VectorType());
return "flatbuffers::WIPOffset<flatbuffers::Vector<" + lifetime + \ return "flatbuffers::WIPOffset<flatbuffers::Vector<" + lifetime + ", " +
", " + typname + ">>"; typname + ">>";
} }
case ftVectorOfBool: { case ftVectorOfBool: {
return "flatbuffers::WIPOffset<flatbuffers::Vector<" + lifetime + \ return "flatbuffers::WIPOffset<flatbuffers::Vector<" + lifetime +
", bool>>"; ", bool>>";
} }
case ftVectorOfString: { case ftVectorOfString: {
return "flatbuffers::WIPOffset<flatbuffers::Vector<" + lifetime + \ return "flatbuffers::WIPOffset<flatbuffers::Vector<" + lifetime +
", flatbuffers::ForwardsUOffset<&" + lifetime + " str>>>"; ", flatbuffers::ForwardsUOffset<&" + lifetime + " str>>>";
} }
case ftVectorOfEnumKey: { case ftVectorOfEnumKey: {
const auto typname = WrapInNameSpace(*type.enum_def); const auto typname = WrapInNameSpace(*type.enum_def);
return "flatbuffers::WIPOffset<flatbuffers::Vector<" + lifetime + \ return "flatbuffers::WIPOffset<flatbuffers::Vector<" + lifetime + ", " +
", " + typname + ">>"; typname + ">>";
} }
case ftVectorOfUnionValue: { case ftVectorOfUnionValue: {
return "flatbuffers::WIPOffset<flatbuffers::Vector<" + lifetime + \ return "flatbuffers::WIPOffset<flatbuffers::Vector<" + lifetime +
", flatbuffers::ForwardsUOffset<flatbuffers::Table<" + \ ", flatbuffers::ForwardsUOffset<flatbuffers::Table<" + lifetime +
lifetime + ">>>"; ">>>";
} }
case ftEnumKey: { case ftEnumKey: {
const auto typname = WrapInNameSpace(*type.enum_def); const auto typname = WrapInNameSpace(*type.enum_def);
@@ -947,7 +903,7 @@ class RustGenerator : public BaseGenerator {
} }
case ftTable: { case ftTable: {
const auto typname = WrapInNameSpace(*type.struct_def); const auto typname = WrapInNameSpace(*type.struct_def);
return "self.fbb_.push_slot_always::<flatbuffers::WIPOffset<" + \ return "self.fbb_.push_slot_always::<flatbuffers::WIPOffset<" +
typname + ">>"; typname + ">>";
} }
@@ -982,11 +938,13 @@ class RustGenerator : public BaseGenerator {
} }
case ftStruct: { case ftStruct: {
const auto typname = WrapInNameSpace(*type.struct_def); const auto typname = WrapInNameSpace(*type.struct_def);
return WrapInOptionIfNotRequired("&" + lifetime + " " + typname, field.required); return WrapInOptionIfNotRequired("&" + lifetime + " " + typname,
field.required);
} }
case ftTable: { case ftTable: {
const auto typname = WrapInNameSpace(*type.struct_def); const auto typname = WrapInNameSpace(*type.struct_def);
return WrapInOptionIfNotRequired(typname + "<" + lifetime + ">", field.required); return WrapInOptionIfNotRequired(typname + "<" + lifetime + ">",
field.required);
} }
case ftEnumKey: case ftEnumKey:
case ftUnionKey: { case ftUnionKey: {
@@ -995,38 +953,51 @@ class RustGenerator : public BaseGenerator {
} }
case ftUnionValue: { case ftUnionValue: {
return WrapInOptionIfNotRequired("flatbuffers::Table<" + lifetime + ">", field.required); return WrapInOptionIfNotRequired("flatbuffers::Table<" + lifetime + ">",
field.required);
} }
case ftString: { case ftString: {
return WrapInOptionIfNotRequired("&" + lifetime + " str", field.required); return WrapInOptionIfNotRequired("&" + lifetime + " str",
field.required);
} }
case ftVectorOfInteger: case ftVectorOfInteger:
case ftVectorOfFloat: { case ftVectorOfFloat: {
const auto typname = GetTypeBasic(type.VectorType()); const auto typname = GetTypeBasic(type.VectorType());
if (IsOneByte(type.VectorType().base_type)) { if (IsOneByte(type.VectorType().base_type)) {
return WrapInOptionIfNotRequired("&" + lifetime + " [" + typname + "]", field.required); return WrapInOptionIfNotRequired(
"&" + lifetime + " [" + typname + "]", field.required);
} }
return WrapInOptionIfNotRequired("flatbuffers::Vector<" + lifetime + ", " + typname + ">", field.required); return WrapInOptionIfNotRequired(
"flatbuffers::Vector<" + lifetime + ", " + typname + ">",
field.required);
} }
case ftVectorOfBool: { case ftVectorOfBool: {
return WrapInOptionIfNotRequired("&" + lifetime + " [bool]", field.required); return WrapInOptionIfNotRequired("&" + lifetime + " [bool]",
field.required);
} }
case ftVectorOfEnumKey: { case ftVectorOfEnumKey: {
const auto typname = WrapInNameSpace(*type.enum_def); const auto typname = WrapInNameSpace(*type.enum_def);
return WrapInOptionIfNotRequired("flatbuffers::Vector<" + lifetime + ", " + typname + ">", field.required); return WrapInOptionIfNotRequired(
"flatbuffers::Vector<" + lifetime + ", " + typname + ">",
field.required);
} }
case ftVectorOfStruct: { case ftVectorOfStruct: {
const auto typname = WrapInNameSpace(*type.struct_def); const auto typname = WrapInNameSpace(*type.struct_def);
return WrapInOptionIfNotRequired("&" + lifetime + " [" + typname + "]", field.required); return WrapInOptionIfNotRequired("&" + lifetime + " [" + typname + "]",
field.required);
} }
case ftVectorOfTable: { case ftVectorOfTable: {
const auto typname = WrapInNameSpace(*type.struct_def); const auto typname = WrapInNameSpace(*type.struct_def);
return WrapInOptionIfNotRequired("flatbuffers::Vector<" + lifetime + ", flatbuffers::ForwardsUOffset<" + \ return WrapInOptionIfNotRequired("flatbuffers::Vector<" + lifetime +
typname + "<" + lifetime + ">>>", field.required); ", flatbuffers::ForwardsUOffset<" +
typname + "<" + lifetime + ">>>",
field.required);
} }
case ftVectorOfString: { case ftVectorOfString: {
return WrapInOptionIfNotRequired("flatbuffers::Vector<" + lifetime + ", flatbuffers::ForwardsUOffset<&" + \ return WrapInOptionIfNotRequired(
lifetime + " str>>", field.required); "flatbuffers::Vector<" + lifetime +
", flatbuffers::ForwardsUOffset<&" + lifetime + " str>>",
field.required);
} }
case ftVectorOfUnionValue: { case ftVectorOfUnionValue: {
FLATBUFFERS_ASSERT(false && "vectors of unions are not yet supported"); FLATBUFFERS_ASSERT(false && "vectors of unions are not yet supported");
@@ -1041,8 +1012,8 @@ class RustGenerator : public BaseGenerator {
std::string GenTableAccessorFuncBody(const FieldDef &field, std::string GenTableAccessorFuncBody(const FieldDef &field,
const std::string &lifetime, const std::string &lifetime,
const std::string &offset_prefix) { const std::string &offset_prefix) {
const std::string offset_name = offset_prefix + "::" + \ const std::string offset_name =
GetFieldOffsetName(field); offset_prefix + "::" + GetFieldOffsetName(field);
const Type &type = field.value.type; const Type &type = field.value.type;
switch (GetFullType(field.value.type)) { switch (GetFullType(field.value.type)) {
@@ -1051,42 +1022,51 @@ class RustGenerator : public BaseGenerator {
case ftBool: { case ftBool: {
const auto typname = GetTypeBasic(type); const auto typname = GetTypeBasic(type);
const auto default_value = GetDefaultScalarValue(field); const auto default_value = GetDefaultScalarValue(field);
return "self._tab.get::<" + typname + ">(" + offset_name + ", Some(" + \ return "self._tab.get::<" + typname + ">(" + offset_name + ", Some(" +
default_value + ")).unwrap()"; default_value + ")).unwrap()";
} }
case ftStruct: { case ftStruct: {
const auto typname = WrapInNameSpace(*type.struct_def); const auto typname = WrapInNameSpace(*type.struct_def);
return AddUnwrapIfRequired("self._tab.get::<" + typname + ">(" + offset_name + ", None)", field.required); return AddUnwrapIfRequired(
"self._tab.get::<" + typname + ">(" + offset_name + ", None)",
field.required);
} }
case ftTable: { case ftTable: {
const auto typname = WrapInNameSpace(*type.struct_def); const auto typname = WrapInNameSpace(*type.struct_def);
return AddUnwrapIfRequired("self._tab.get::<flatbuffers::ForwardsUOffset<" + \ return AddUnwrapIfRequired(
typname + "<" + lifetime + ">>>(" + offset_name + ", None)", field.required); "self._tab.get::<flatbuffers::ForwardsUOffset<" + typname + "<" +
lifetime + ">>>(" + offset_name + ", None)",
field.required);
} }
case ftUnionValue: { case ftUnionValue: {
return AddUnwrapIfRequired("self._tab.get::<flatbuffers::ForwardsUOffset<" return AddUnwrapIfRequired(
"flatbuffers::Table<" + lifetime + ">>>(" + offset_name + \ "self._tab.get::<flatbuffers::ForwardsUOffset<"
", None)", field.required); "flatbuffers::Table<" +
lifetime + ">>>(" + offset_name + ", None)",
field.required);
} }
case ftUnionKey: case ftUnionKey:
case ftEnumKey: { case ftEnumKey: {
const auto underlying_typname = GetTypeBasic(type); //<- never used const auto underlying_typname = GetTypeBasic(type); //<- never used
const auto typname = WrapInNameSpace(*type.enum_def); const auto typname = WrapInNameSpace(*type.enum_def);
const auto default_value = GetDefaultScalarValue(field); const auto default_value = GetDefaultScalarValue(field);
return "self._tab.get::<" + typname + ">(" + offset_name + \ return "self._tab.get::<" + typname + ">(" + offset_name + ", Some(" +
", Some(" + default_value + ")).unwrap()"; default_value + ")).unwrap()";
} }
case ftString: { case ftString: {
return AddUnwrapIfRequired("self._tab.get::<flatbuffers::ForwardsUOffset<&str>>(" + \ return AddUnwrapIfRequired(
offset_name + ", None)", field.required); "self._tab.get::<flatbuffers::ForwardsUOffset<&str>>(" +
offset_name + ", None)",
field.required);
} }
case ftVectorOfInteger: case ftVectorOfInteger:
case ftVectorOfFloat: { case ftVectorOfFloat: {
const auto typname = GetTypeBasic(type.VectorType()); const auto typname = GetTypeBasic(type.VectorType());
std::string s = "self._tab.get::<flatbuffers::ForwardsUOffset<" std::string s =
"flatbuffers::Vector<" + lifetime + ", " + typname + \ "self._tab.get::<flatbuffers::ForwardsUOffset<"
">>>(" + offset_name + ", None)"; "flatbuffers::Vector<" +
lifetime + ", " + typname + ">>>(" + offset_name + ", None)";
// single-byte values are safe to slice // single-byte values are safe to slice
if (IsOneByte(type.VectorType().base_type)) { if (IsOneByte(type.VectorType().base_type)) {
s += ".map(|v| v.safe_slice())"; s += ".map(|v| v.safe_slice())";
@@ -1094,32 +1074,44 @@ class RustGenerator : public BaseGenerator {
return AddUnwrapIfRequired(s, field.required); return AddUnwrapIfRequired(s, field.required);
} }
case ftVectorOfBool: { case ftVectorOfBool: {
return AddUnwrapIfRequired("self._tab.get::<flatbuffers::ForwardsUOffset<" return AddUnwrapIfRequired(
"flatbuffers::Vector<" + lifetime + ", bool>>>(" + \ "self._tab.get::<flatbuffers::ForwardsUOffset<"
offset_name + ", None).map(|v| v.safe_slice())", field.required); "flatbuffers::Vector<" +
lifetime + ", bool>>>(" + offset_name +
", None).map(|v| v.safe_slice())",
field.required);
} }
case ftVectorOfEnumKey: { case ftVectorOfEnumKey: {
const auto typname = WrapInNameSpace(*type.enum_def); const auto typname = WrapInNameSpace(*type.enum_def);
return AddUnwrapIfRequired("self._tab.get::<flatbuffers::ForwardsUOffset<" return AddUnwrapIfRequired(
"flatbuffers::Vector<" + lifetime + ", " + typname + ">>>(" + \ "self._tab.get::<flatbuffers::ForwardsUOffset<"
offset_name + ", None)", field.required); "flatbuffers::Vector<" +
lifetime + ", " + typname + ">>>(" + offset_name + ", None)",
field.required);
} }
case ftVectorOfStruct: { case ftVectorOfStruct: {
const auto typname = WrapInNameSpace(*type.struct_def); const auto typname = WrapInNameSpace(*type.struct_def);
return AddUnwrapIfRequired("self._tab.get::<flatbuffers::ForwardsUOffset<" return AddUnwrapIfRequired(
"flatbuffers::Vector<" + typname + ">>>(" + \ "self._tab.get::<flatbuffers::ForwardsUOffset<"
offset_name + ", None).map(|v| v.safe_slice() )", field.required); "flatbuffers::Vector<" +
typname + ">>>(" + offset_name +
", None).map(|v| v.safe_slice() )",
field.required);
} }
case ftVectorOfTable: { case ftVectorOfTable: {
const auto typname = WrapInNameSpace(*type.struct_def); const auto typname = WrapInNameSpace(*type.struct_def);
return AddUnwrapIfRequired("self._tab.get::<flatbuffers::ForwardsUOffset<" return AddUnwrapIfRequired(
"flatbuffers::Vector<flatbuffers::ForwardsUOffset<" + typname + \ "self._tab.get::<flatbuffers::ForwardsUOffset<"
"<" + lifetime + ">>>>>(" + offset_name + ", None)", field.required); "flatbuffers::Vector<flatbuffers::ForwardsUOffset<" +
typname + "<" + lifetime + ">>>>>(" + offset_name + ", None)",
field.required);
} }
case ftVectorOfString: { case ftVectorOfString: {
return AddUnwrapIfRequired("self._tab.get::<flatbuffers::ForwardsUOffset<" return AddUnwrapIfRequired(
"flatbuffers::Vector<flatbuffers::ForwardsUOffset<&" + \ "self._tab.get::<flatbuffers::ForwardsUOffset<"
lifetime + " str>>>>(" + offset_name + ", None)", field.required); "flatbuffers::Vector<flatbuffers::ForwardsUOffset<&" +
lifetime + " str>>>>(" + offset_name + ", None)",
field.required);
} }
case ftVectorOfUnionValue: { case ftVectorOfUnionValue: {
FLATBUFFERS_ASSERT(false && "vectors of unions are not yet supported"); FLATBUFFERS_ASSERT(false && "vectors of unions are not yet supported");
@@ -1135,8 +1127,7 @@ class RustGenerator : public BaseGenerator {
case ftFloat: case ftFloat:
case ftBool: case ftBool:
case ftEnumKey: case ftEnumKey:
case ftUnionKey: case ftUnionKey: return false;
return false;
default: return true; default: return true;
} }
} }
@@ -1172,7 +1163,8 @@ class RustGenerator : public BaseGenerator {
code_ += ""; code_ += "";
code_ += "impl<'a> {{STRUCT_NAME}}<'a> {"; code_ += "impl<'a> {{STRUCT_NAME}}<'a> {";
code_ += " #[inline]"; code_ += " #[inline]";
code_ += " pub fn init_from_table(table: flatbuffers::Table<'a>) -> " code_ +=
" pub fn init_from_table(table: flatbuffers::Table<'a>) -> "
"Self {"; "Self {";
code_ += " {{STRUCT_NAME}} {"; code_ += " {{STRUCT_NAME}} {";
code_ += " _tab: table,"; code_ += " _tab: table,";
@@ -1181,15 +1173,16 @@ class RustGenerator : public BaseGenerator {
// Generate a convenient create* function that uses the above builder // Generate a convenient create* function that uses the above builder
// to create a table in one function call. // to create a table in one function call.
code_.SetValue("MAYBE_US", code_.SetValue("MAYBE_US", struct_def.fields.vec.size() == 0 ? "_" : "");
struct_def.fields.vec.size() == 0 ? "_" : "");
code_.SetValue("MAYBE_LT", code_.SetValue("MAYBE_LT",
TableBuilderArgsNeedsLifetime(struct_def) ? "<'args>" : ""); TableBuilderArgsNeedsLifetime(struct_def) ? "<'args>" : "");
code_ += " #[allow(unused_mut)]"; code_ += " #[allow(unused_mut)]";
code_ += " pub fn create<'bldr: 'args, 'args: 'mut_bldr, 'mut_bldr>("; code_ += " pub fn create<'bldr: 'args, 'args: 'mut_bldr, 'mut_bldr>(";
code_ += " _fbb: " code_ +=
" _fbb: "
"&'mut_bldr mut flatbuffers::FlatBufferBuilder<'bldr>,"; "&'mut_bldr mut flatbuffers::FlatBufferBuilder<'bldr>,";
code_ += " {{MAYBE_US}}args: &'args {{STRUCT_NAME}}Args{{MAYBE_LT}})" code_ +=
" {{MAYBE_US}}args: &'args {{STRUCT_NAME}}Args{{MAYBE_LT}})"
" -> flatbuffers::WIPOffset<{{STRUCT_NAME}}<'bldr>> {"; " -> flatbuffers::WIPOffset<{{STRUCT_NAME}}<'bldr>> {";
code_ += " let mut builder = {{STRUCT_NAME}}Builder::new(_fbb);"; code_ += " let mut builder = {{STRUCT_NAME}}Builder::new(_fbb);";
@@ -1203,7 +1196,8 @@ class RustGenerator : public BaseGenerator {
size == SizeOf(field.value.type.base_type))) { size == SizeOf(field.value.type.base_type))) {
code_.SetValue("FIELD_NAME", Name(field)); code_.SetValue("FIELD_NAME", Name(field));
if (TableFieldReturnsOption(field.value.type)) { if (TableFieldReturnsOption(field.value.type)) {
code_ += " if let Some(x) = args.{{FIELD_NAME}} " code_ +=
" if let Some(x) = args.{{FIELD_NAME}} "
"{ builder.add_{{FIELD_NAME}}(x); }"; "{ builder.add_{{FIELD_NAME}}(x); }";
} else { } else {
code_ += " builder.add_{{FIELD_NAME}}(args.{{FIELD_NAME}});"; code_ += " builder.add_{{FIELD_NAME}}(args.{{FIELD_NAME}});";
@@ -1227,7 +1221,8 @@ class RustGenerator : public BaseGenerator {
code_.SetValue("OFFSET_NAME", GetFieldOffsetName(field)); code_.SetValue("OFFSET_NAME", GetFieldOffsetName(field));
code_.SetValue("OFFSET_VALUE", NumToString(field.value.offset)); code_.SetValue("OFFSET_VALUE", NumToString(field.value.offset));
code_ += " pub const {{OFFSET_NAME}}: flatbuffers::VOffsetT = " code_ +=
" pub const {{OFFSET_NAME}}: flatbuffers::VOffsetT = "
"{{OFFSET_VALUE}};"; "{{OFFSET_VALUE}};";
} }
code_ += ""; code_ += "";
@@ -1266,9 +1261,7 @@ 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) { if (field.key) { GenKeyFieldMethods(field); }
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");
@@ -1285,13 +1278,15 @@ class RustGenerator : public BaseGenerator {
code_.SetValue("OFFSET_NAME", code_.SetValue("OFFSET_NAME",
offset_prefix + "::" + GetFieldOffsetName(field)); offset_prefix + "::" + GetFieldOffsetName(field));
code_ += " pub fn {{FIELD_NAME}}_nested_flatbuffer(&'a self) -> " code_ +=
" pub fn {{FIELD_NAME}}_nested_flatbuffer(&'a self) -> "
" Option<{{STRUCT_NAME}}<'a>> {"; " Option<{{STRUCT_NAME}}<'a>> {";
code_ += " match self.{{FIELD_NAME}}() {"; code_ += " match self.{{FIELD_NAME}}() {";
code_ += " None => { None }"; code_ += " None => { None }";
code_ += " Some(data) => {"; code_ += " Some(data) => {";
code_ += " use self::flatbuffers::Follow;"; code_ += " use self::flatbuffers::Follow;";
code_ += " Some(<flatbuffers::ForwardsUOffset" code_ +=
" Some(<flatbuffers::ForwardsUOffset"
"<{{STRUCT_NAME}}<'a>>>::follow(data, 0))"; "<{{STRUCT_NAME}}<'a>>>::follow(data, 0))";
code_ += " },"; code_ += " },";
code_ += " }"; code_ += " }";
@@ -1315,21 +1310,25 @@ class RustGenerator : public BaseGenerator {
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 table_init_type = WrapInNameSpace( auto table_init_type =
ev.union_type.struct_def->defined_namespace, WrapInNameSpace(ev.union_type.struct_def->defined_namespace,
ev.union_type.struct_def->name); ev.union_type.struct_def->name);
code_.SetValue("U_ELEMENT_ENUM_TYPE", code_.SetValue(
"U_ELEMENT_ENUM_TYPE",
WrapInNameSpace(u->defined_namespace, GetEnumValUse(*u, ev))); WrapInNameSpace(u->defined_namespace, GetEnumValUse(*u, ev)));
code_.SetValue("U_ELEMENT_TABLE_TYPE", table_init_type); code_.SetValue("U_ELEMENT_TABLE_TYPE", table_init_type);
code_.SetValue("U_ELEMENT_NAME", MakeSnakeCase(Name(ev))); code_.SetValue("U_ELEMENT_NAME", MakeSnakeCase(Name(ev)));
code_ += " #[inline]"; code_ += " #[inline]";
code_ += " #[allow(non_snake_case)]"; code_ += " #[allow(non_snake_case)]";
code_ += " pub fn {{FIELD_NAME}}_as_{{U_ELEMENT_NAME}}(&self) -> " code_ +=
" pub fn {{FIELD_NAME}}_as_{{U_ELEMENT_NAME}}(&self) -> "
"Option<{{U_ELEMENT_TABLE_TYPE}}<'a>> {"; "Option<{{U_ELEMENT_TABLE_TYPE}}<'a>> {";
code_ += " if self.{{FIELD_NAME}}_type() == {{U_ELEMENT_ENUM_TYPE}} {"; code_ +=
code_ += " self.{{FIELD_NAME}}().map(|u| " " if self.{{FIELD_NAME}}_type() == {{U_ELEMENT_ENUM_TYPE}} {";
code_ +=
" self.{{FIELD_NAME}}().map(|u| "
"{{U_ELEMENT_TABLE_TYPE}}::init_from_table(u))"; "{{U_ELEMENT_TABLE_TYPE}}::init_from_table(u))";
code_ += " } else {"; code_ += " } else {";
code_ += " None"; code_ += " None";
@@ -1379,7 +1378,8 @@ class RustGenerator : public BaseGenerator {
// Generate a builder struct: // Generate a builder struct:
code_ += "pub struct {{STRUCT_NAME}}Builder<'a: 'b, 'b> {"; code_ += "pub struct {{STRUCT_NAME}}Builder<'a: 'b, 'b> {";
code_ += " fbb_: &'b mut flatbuffers::FlatBufferBuilder<'a>,"; code_ += " fbb_: &'b mut flatbuffers::FlatBufferBuilder<'a>,";
code_ += " start_: flatbuffers::WIPOffset<" code_ +=
" start_: flatbuffers::WIPOffset<"
"flatbuffers::TableUnfinishedWIPOffset>,"; "flatbuffers::TableUnfinishedWIPOffset>,";
code_ += "}"; code_ += "}";
@@ -1409,12 +1409,14 @@ class RustGenerator : public BaseGenerator {
code_.SetValue("FIELD_TYPE", TableBuilderArgsAddFuncType(field, "'b ")); code_.SetValue("FIELD_TYPE", TableBuilderArgsAddFuncType(field, "'b "));
code_.SetValue("FUNC_BODY", TableBuilderArgsAddFuncBody(field)); code_.SetValue("FUNC_BODY", TableBuilderArgsAddFuncBody(field));
code_ += " #[inline]"; code_ += " #[inline]";
code_ += " pub fn add_{{FIELD_NAME}}(&mut self, {{FIELD_NAME}}: " code_ +=
" pub fn add_{{FIELD_NAME}}(&mut self, {{FIELD_NAME}}: "
"{{FIELD_TYPE}}) {"; "{{FIELD_TYPE}}) {";
if (is_scalar) { if (is_scalar) {
code_.SetValue("FIELD_DEFAULT_VALUE", code_.SetValue("FIELD_DEFAULT_VALUE",
TableBuilderAddFuncDefaultValue(field)); TableBuilderAddFuncDefaultValue(field));
code_ += " {{FUNC_BODY}}({{FIELD_OFFSET}}, {{FIELD_NAME}}, " code_ +=
" {{FUNC_BODY}}({{FIELD_OFFSET}}, {{FIELD_NAME}}, "
"{{FIELD_DEFAULT_VALUE}});"; "{{FIELD_DEFAULT_VALUE}});";
} else { } else {
code_ += " {{FUNC_BODY}}({{FIELD_OFFSET}}, {{FIELD_NAME}});"; code_ += " {{FUNC_BODY}}({{FIELD_OFFSET}}, {{FIELD_NAME}});";
@@ -1438,7 +1440,8 @@ class RustGenerator : public BaseGenerator {
// finish() function. // finish() function.
code_ += " #[inline]"; code_ += " #[inline]";
code_ += " pub fn finish(self) -> " code_ +=
" pub fn finish(self) -> "
"flatbuffers::WIPOffset<{{STRUCT_NAME}}<'a>> {"; "flatbuffers::WIPOffset<{{STRUCT_NAME}}<'a>> {";
code_ += " let o = self.fbb_.end_table(self.start_);"; code_ += " let o = self.fbb_.end_table(self.start_);";
@@ -1448,7 +1451,8 @@ class RustGenerator : public BaseGenerator {
if (!field.deprecated && field.required) { if (!field.deprecated && field.required) {
code_.SetValue("FIELD_NAME", MakeSnakeCase(Name(field))); code_.SetValue("FIELD_NAME", MakeSnakeCase(Name(field)));
code_.SetValue("OFFSET_NAME", GetFieldOffsetName(field)); code_.SetValue("OFFSET_NAME", GetFieldOffsetName(field));
code_ += " self.fbb_.required(o, {{STRUCT_NAME}}::{{OFFSET_NAME}}," code_ +=
" self.fbb_.required(o, {{STRUCT_NAME}}::{{OFFSET_NAME}},"
"\"{{FIELD_NAME}}\");"; "\"{{FIELD_NAME}}\");";
} }
} }
@@ -1466,13 +1470,15 @@ class RustGenerator : public BaseGenerator {
code_.SetValue("KEY_TYPE", GenTableAccessorFuncReturnType(field, "")); code_.SetValue("KEY_TYPE", GenTableAccessorFuncReturnType(field, ""));
code_ += " #[inline]"; code_ += " #[inline]";
code_ += " pub fn key_compare_less_than(&self, o: &{{STRUCT_NAME}}) -> " code_ +=
" pub fn key_compare_less_than(&self, o: &{{STRUCT_NAME}}) -> "
" bool {"; " bool {";
code_ += " self.{{FIELD_NAME}}() < o.{{FIELD_NAME}}()"; code_ += " self.{{FIELD_NAME}}() < o.{{FIELD_NAME}}()";
code_ += " }"; code_ += " }";
code_ += ""; code_ += "";
code_ += " #[inline]"; code_ += " #[inline]";
code_ += " pub fn key_compare_with_value(&self, val: {{KEY_TYPE}}) -> " code_ +=
" pub fn key_compare_with_value(&self, val: {{KEY_TYPE}}) -> "
" ::std::cmp::Ordering {"; " ::std::cmp::Ordering {";
code_ += " let key = self.{{FIELD_NAME}}();"; code_ += " let key = self.{{FIELD_NAME}}();";
code_ += " key.cmp(&val)"; code_ += " key.cmp(&val)";
@@ -1499,9 +1505,11 @@ class RustGenerator : public BaseGenerator {
code_ += ""; code_ += "";
code_ += "#[inline]"; code_ += "#[inline]";
code_ += "pub fn get_size_prefixed_root_as_{{STRUCT_NAME_SNAKECASE}}" code_ +=
"pub fn get_size_prefixed_root_as_{{STRUCT_NAME_SNAKECASE}}"
"<'a>(buf: &'a [u8]) -> {{STRUCT_NAME}}<'a> {"; "<'a>(buf: &'a [u8]) -> {{STRUCT_NAME}}<'a> {";
code_ += " flatbuffers::get_size_prefixed_root::<{{STRUCT_NAME}}<'a>>" code_ +=
" flatbuffers::get_size_prefixed_root::<{{STRUCT_NAME}}<'a>>"
"(buf)"; "(buf)";
code_ += "}"; code_ += "}";
code_ += ""; code_ += "";
@@ -1550,12 +1558,14 @@ class RustGenerator : public BaseGenerator {
code_ += "}"; code_ += "}";
code_ += ""; code_ += "";
code_ += "#[inline]"; code_ += "#[inline]";
code_ += "pub fn finish_size_prefixed_{{STRUCT_NAME_SNAKECASE}}_buffer" code_ +=
"pub fn finish_size_prefixed_{{STRUCT_NAME_SNAKECASE}}_buffer"
"<'a, 'b>(" "<'a, 'b>("
"fbb: &'b mut flatbuffers::FlatBufferBuilder<'a>, " "fbb: &'b mut flatbuffers::FlatBufferBuilder<'a>, "
"root: flatbuffers::WIPOffset<{{STRUCT_NAME}}<'a>>) {"; "root: flatbuffers::WIPOffset<{{STRUCT_NAME}}<'a>>) {";
if (parser_.file_identifier_.length()) { if (parser_.file_identifier_.length()) {
code_ += " fbb.finish_size_prefixed(root, " code_ +=
" fbb.finish_size_prefixed(root, "
"Some({{STRUCT_NAME_CAPS}}_IDENTIFIER));"; "Some({{STRUCT_NAME_CAPS}}_IDENTIFIER));";
} else { } else {
code_ += " fbb.finish_size_prefixed(root, None);"; code_ += " fbb.finish_size_prefixed(root, None);";
@@ -1577,8 +1587,8 @@ class RustGenerator : public BaseGenerator {
} }
static void PaddingDefinition(int bits, std::string *code_ptr, int *id) { static void PaddingDefinition(int bits, std::string *code_ptr, int *id) {
*code_ptr += " padding" + NumToString((*id)++) + "__: u" + \ *code_ptr +=
NumToString(bits) + ","; " padding" + NumToString((*id)++) + "__: u" + NumToString(bits) + ",";
} }
static void PaddingInitializer(int bits, std::string *code_ptr, int *id) { static void PaddingInitializer(int bits, std::string *code_ptr, int *id) {
@@ -1644,7 +1654,8 @@ class RustGenerator : public BaseGenerator {
code_ += " #[inline]"; code_ += " #[inline]";
code_ += " fn push(&self, dst: &mut [u8], _rest: &[u8]) {"; code_ += " fn push(&self, dst: &mut [u8], _rest: &[u8]) {";
code_ += " let src = unsafe {"; code_ += " let src = unsafe {";
code_ += " ::std::slice::from_raw_parts(" code_ +=
" ::std::slice::from_raw_parts("
"self as *const {{STRUCT_NAME}} as *const u8, Self::size())"; "self as *const {{STRUCT_NAME}} as *const u8, Self::size())";
code_ += " };"; code_ += " };";
code_ += " dst.copy_from_slice(src);"; code_ += " dst.copy_from_slice(src);";
@@ -1656,7 +1667,8 @@ class RustGenerator : public BaseGenerator {
code_ += " #[inline]"; code_ += " #[inline]";
code_ += " fn push(&self, dst: &mut [u8], _rest: &[u8]) {"; code_ += " fn push(&self, dst: &mut [u8], _rest: &[u8]) {";
code_ += " let src = unsafe {"; code_ += " let src = unsafe {";
code_ += " ::std::slice::from_raw_parts(" code_ +=
" ::std::slice::from_raw_parts("
"*self as *const {{STRUCT_NAME}} as *const u8, Self::size())"; "*self as *const {{STRUCT_NAME}} as *const u8, Self::size())";
code_ += " };"; code_ += " };";
code_ += " dst.copy_from_slice(src);"; code_ += " dst.copy_from_slice(src);";
@@ -1674,14 +1686,12 @@ class RustGenerator : public BaseGenerator {
it != struct_def.fields.vec.end(); ++it) { it != struct_def.fields.vec.end(); ++it) {
const auto &field = **it; const auto &field = **it;
const auto member_name = Name(field) + "_"; const auto member_name = Name(field) + "_";
const auto reference = StructMemberAccessNeedsCopy(field.value.type) const auto reference =
? "" : "&'a "; StructMemberAccessNeedsCopy(field.value.type) ? "" : "&'a ";
const auto arg_name = "_" + Name(field); const auto arg_name = "_" + Name(field);
const auto arg_type = reference + GetTypeGet(field.value.type); const auto arg_type = reference + GetTypeGet(field.value.type);
if (it != struct_def.fields.vec.begin()) { if (it != struct_def.fields.vec.begin()) { arg_list += ", "; }
arg_list += ", ";
}
arg_list += arg_name + ": "; arg_list += arg_name + ": ";
arg_list += arg_type; arg_list += arg_type;
init_list += " " + member_name; init_list += " " + member_name;
@@ -1717,8 +1727,9 @@ class RustGenerator : public BaseGenerator {
auto field_type = TableBuilderArgsAddFuncType(field, "'a"); auto field_type = TableBuilderArgsAddFuncType(field, "'a");
auto member = "self." + Name(field) + "_"; auto member = "self." + Name(field) + "_";
auto value = StructMemberAccessNeedsCopy(field.value.type) ? auto value = StructMemberAccessNeedsCopy(field.value.type)
member + ".from_little_endian()" : member; ? member + ".from_little_endian()"
: member;
code_.SetValue("FIELD_NAME", Name(field)); code_.SetValue("FIELD_NAME", Name(field));
code_.SetValue("FIELD_TYPE", field_type); code_.SetValue("FIELD_TYPE", field_type);
@@ -1731,9 +1742,7 @@ 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) { if (field.key) { GenKeyFieldMethods(field); }
GenKeyFieldMethods(field);
}
} }
code_ += "}"; code_ += "}";
code_ += ""; code_ += "";

View File

@@ -142,8 +142,8 @@ bool Print<const void *>(const void *val, Type type, int indent,
FLATBUFFERS_ASSERT(prev_val); FLATBUFFERS_ASSERT(prev_val);
auto union_type_byte = *prev_val; // Always a uint8_t. auto union_type_byte = *prev_val; // Always a uint8_t.
if (vector_index >= 0) { if (vector_index >= 0) {
auto type_vec = reinterpret_cast<const Vector<uint8_t> *>(prev_val + auto type_vec = reinterpret_cast<const Vector<uint8_t> *>(
ReadScalar<uoffset_t>(prev_val)); prev_val + ReadScalar<uoffset_t>(prev_val));
union_type_byte = type_vec->Get(static_cast<uoffset_t>(vector_index)); union_type_byte = type_vec->Get(static_cast<uoffset_t>(vector_index));
} }
auto enum_val = type.enum_def->ReverseLookup(union_type_byte, true); auto enum_val = type.enum_def->ReverseLookup(union_type_byte, true);
@@ -205,9 +205,7 @@ bool Print<const void *>(const void *val, Type type, int indent,
// clang-format on // clang-format on
return true; return true;
} }
default: default: FLATBUFFERS_ASSERT(0); return false;
FLATBUFFERS_ASSERT(0);
return false;
} }
} }
@@ -330,15 +328,11 @@ static bool GenStruct(const StructDef &struct_def, const Table *table,
bool GenerateTextFromTable(const Parser &parser, const void *table, bool GenerateTextFromTable(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) { if (struct_def == nullptr) { return false; }
return false;
}
auto &text = *_text; auto &text = *_text;
text.reserve(1024); // Reduce amount of inevitable reallocs. text.reserve(1024); // Reduce amount of inevitable reallocs.
auto root = static_cast<const Table *>(table); auto root = static_cast<const Table *>(table);
if (!GenStruct(*struct_def, root, 0, parser.opts, &text)) { if (!GenStruct(*struct_def, root, 0, parser.opts, &text)) { return false; }
return false;
}
text += NewLine(parser.opts); text += NewLine(parser.opts);
return true; return true;
} }
@@ -349,8 +343,8 @@ bool GenerateText(const Parser &parser, const void *flatbuffer,
std::string &text = *_text; std::string &text = *_text;
FLATBUFFERS_ASSERT(parser.root_struct_def_); // call SetRootType() FLATBUFFERS_ASSERT(parser.root_struct_def_); // call SetRootType()
text.reserve(1024); // Reduce amount of inevitable reallocs. text.reserve(1024); // Reduce amount of inevitable reallocs.
auto root = parser.opts.size_prefixed ? auto root = parser.opts.size_prefixed ? GetSizePrefixedRoot<Table>(flatbuffer)
GetSizePrefixedRoot<Table>(flatbuffer) : GetRoot<Table>(flatbuffer); : GetRoot<Table>(flatbuffer);
if (!GenStruct(*parser.root_struct_def_, root, 0, parser.opts, _text)) { if (!GenStruct(*parser.root_struct_def_, root, 0, parser.opts, _text)) {
return false; return false;
} }

View File

@@ -15,12 +15,11 @@
*/ */
#include <algorithm> #include <algorithm>
#include <cmath>
#include <list> #include <list>
#include <string> #include <string>
#include <utility> #include <utility>
#include <cmath>
#include "flatbuffers/idl.h" #include "flatbuffers/idl.h"
#include "flatbuffers/util.h" #include "flatbuffers/util.h"
@@ -399,7 +398,8 @@ CheckedError Parser::Next() {
"illegal Unicode sequence (unpaired high surrogate)"); "illegal Unicode sequence (unpaired high surrogate)");
} }
// reset if non-printable // reset if non-printable
attr_is_trivial_ascii_string_ &= check_ascii_range(*cursor_, ' ', '~'); attr_is_trivial_ascii_string_ &=
check_ascii_range(*cursor_, ' ', '~');
attribute_ += *cursor_++; attribute_ += *cursor_++;
} }
@@ -451,7 +451,8 @@ CheckedError Parser::Next() {
return NoError(); return NoError();
} }
auto dot_lvl = (c == '.') ? 0 : 1; // dot_lvl==0 <=> exactly one '.' seen auto dot_lvl =
(c == '.') ? 0 : 1; // dot_lvl==0 <=> exactly one '.' seen
if (!dot_lvl && !is_digit(*cursor_)) return NoError(); // enum? if (!dot_lvl && !is_digit(*cursor_)) return NoError(); // enum?
// Parser accepts hexadecimal-floating-literal (see C++ 5.13.4). // Parser accepts hexadecimal-floating-literal (see C++ 5.13.4).
if (is_digit(c) || has_sign || !dot_lvl) { if (is_digit(c) || has_sign || !dot_lvl) {
@@ -501,7 +502,8 @@ CheckedError Parser::Next() {
} }
std::string ch; std::string ch;
ch = c; ch = c;
if (false == check_ascii_range(c, ' ', '~')) ch = "code: " + NumToString(c); if (false == check_ascii_range(c, ' ', '~'))
ch = "code: " + NumToString(c);
return Error("illegal character: " + ch); return Error("illegal character: " + ch);
} }
} }
@@ -774,7 +776,8 @@ CheckedError Parser::ParseField(StructDef &struct_def) {
field->deprecated = field->attributes.Lookup("deprecated") != nullptr; field->deprecated = field->attributes.Lookup("deprecated") != nullptr;
auto hash_name = field->attributes.Lookup("hash"); auto hash_name = field->attributes.Lookup("hash");
if (hash_name) { if (hash_name) {
switch ((type.base_type == BASE_TYPE_VECTOR) ? type.element : type.base_type) { switch ((type.base_type == BASE_TYPE_VECTOR) ? type.element
: type.base_type) {
case BASE_TYPE_SHORT: case BASE_TYPE_SHORT:
case BASE_TYPE_USHORT: { case BASE_TYPE_USHORT: {
if (FindHashFunction16(hash_name->constant.c_str()) == nullptr) if (FindHashFunction16(hash_name->constant.c_str()) == nullptr)
@@ -798,7 +801,8 @@ CheckedError Parser::ParseField(StructDef &struct_def) {
} }
default: default:
return Error( return Error(
"only short, ushort, int, uint, long and ulong data types support hashing."); "only short, ushort, int, uint, long and ulong data types support "
"hashing.");
} }
} }
auto cpp_type = field->attributes.Lookup("cpp_type"); auto cpp_type = field->attributes.Lookup("cpp_type");
@@ -817,8 +821,7 @@ CheckedError Parser::ParseField(StructDef &struct_def) {
if (field->deprecated && struct_def.fixed) if (field->deprecated && struct_def.fixed)
return Error("can't deprecate fields in a struct"); return Error("can't deprecate fields in a struct");
field->required = field->attributes.Lookup("required") != nullptr; field->required = field->attributes.Lookup("required") != nullptr;
if (field->required && if (field->required && (struct_def.fixed || IsScalar(type.base_type)))
(struct_def.fixed || IsScalar(type.base_type)))
return Error("only non-scalar fields in tables may be 'required'"); return Error("only non-scalar fields in tables may be 'required'");
field->key = field->attributes.Lookup("key") != nullptr; field->key = field->attributes.Lookup("key") != nullptr;
if (field->key) { if (field->key) {
@@ -861,8 +864,7 @@ CheckedError Parser::ParseField(StructDef &struct_def) {
if (field->attributes.Lookup("flexbuffer")) { if (field->attributes.Lookup("flexbuffer")) {
field->flexbuffer = true; field->flexbuffer = true;
uses_flexbuffers_ = true; uses_flexbuffers_ = true;
if (type.base_type != BASE_TYPE_VECTOR || if (type.base_type != BASE_TYPE_VECTOR || type.element != BASE_TYPE_UCHAR)
type.element != BASE_TYPE_UCHAR)
return Error("flexbuffer attribute may only apply to a vector of ubyte"); return Error("flexbuffer attribute may only apply to a vector of ubyte");
} }
@@ -902,8 +904,7 @@ CheckedError Parser::ParseComma() {
CheckedError Parser::ParseAnyValue(Value &val, FieldDef *field, CheckedError Parser::ParseAnyValue(Value &val, FieldDef *field,
size_t parent_fieldn, size_t parent_fieldn,
const StructDef *parent_struct_def, const StructDef *parent_struct_def,
uoffset_t count, uoffset_t count, bool inside_vector) {
bool inside_vector) {
switch (val.type.base_type) { switch (val.type.base_type) {
case BASE_TYPE_UNION: { case BASE_TYPE_UNION: {
FLATBUFFERS_ASSERT(field); FLATBUFFERS_ASSERT(field);
@@ -921,8 +922,8 @@ CheckedError Parser::ParseAnyValue(Value &val, FieldDef *field,
uoffset_t offset; uoffset_t offset;
ECHECK(atot(elem->first.constant.c_str(), *this, &offset)); ECHECK(atot(elem->first.constant.c_str(), *this, &offset));
vector_of_union_types = reinterpret_cast<Vector<uint8_t> *>( vector_of_union_types = reinterpret_cast<Vector<uint8_t> *>(
builder_.GetCurrentBufferPointer() + builder_.GetCurrentBufferPointer() + builder_.GetSize() -
builder_.GetSize() - offset); offset);
break; break;
} }
} else { } else {
@@ -964,8 +965,7 @@ CheckedError Parser::ParseAnyValue(Value &val, FieldDef *field,
} }
} }
if (constant.empty() && !vector_of_union_types) { if (constant.empty() && !vector_of_union_types) {
return Error("missing type field for this union value: " + return Error("missing type field for this union value: " + field->name);
field->name);
} }
uint8_t enum_idx; uint8_t enum_idx;
if (vector_of_union_types) { if (vector_of_union_types) {
@@ -1042,8 +1042,7 @@ void Parser::SerializeStruct(FlatBufferBuilder &builder,
template<typename F> template<typename F>
CheckedError Parser::ParseTableDelimiters(size_t &fieldn, CheckedError Parser::ParseTableDelimiters(size_t &fieldn,
const StructDef *struct_def, const StructDef *struct_def, F body) {
F body) {
// We allow tables both as JSON object{ .. } with field names // We allow tables both as JSON object{ .. } with field names
// or vector[..] with all fields in order // or vector[..] with all fields in order
char terminator = '}'; char terminator = '}';
@@ -1259,10 +1258,9 @@ CheckedError Parser::ParseVectorDelimiters(uoffset_t &count, F body) {
static bool CompareType(const uint8_t *a, const uint8_t *b, BaseType ftype) { static bool CompareType(const uint8_t *a, const uint8_t *b, BaseType ftype) {
switch (ftype) { switch (ftype) {
#define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE, JTYPE, GTYPE, NTYPE, \ #define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE, JTYPE, GTYPE, NTYPE, PTYPE, \
PTYPE, RTYPE, KTYPE) \ RTYPE, KTYPE) \
case BASE_TYPE_ ## ENUM: \ case BASE_TYPE_##ENUM: return ReadScalar<CTYPE>(a) < ReadScalar<CTYPE>(b);
return ReadScalar<CTYPE>(a) < ReadScalar<CTYPE>(b);
FLATBUFFERS_GEN_TYPES_SCALAR(FLATBUFFERS_TD) FLATBUFFERS_GEN_TYPES_SCALAR(FLATBUFFERS_TD)
#undef FLATBUFFERS_TD #undef FLATBUFFERS_TD
case BASE_TYPE_STRING: case BASE_TYPE_STRING:
@@ -1359,14 +1357,15 @@ CheckedError Parser::ParseVector(const Type &type, uoffset_t *ovalue,
static BaseType ftype = key->value.type.base_type; static BaseType ftype = key->value.type.base_type;
if (type.struct_def->fixed) { if (type.struct_def->fixed) {
auto v = reinterpret_cast<VectorOfAny *>( auto v =
builder_.GetCurrentBufferPointer()); reinterpret_cast<VectorOfAny *>(builder_.GetCurrentBufferPointer());
SimpleQsort<uint8_t>(v->Data(), SimpleQsort<uint8_t>(
v->Data() + v->size() * type.struct_def->bytesize, v->Data(), v->Data() + v->size() * type.struct_def->bytesize,
type.struct_def->bytesize, type.struct_def->bytesize,
[](const uint8_t *a, const uint8_t *b) -> bool { [](const uint8_t *a, const uint8_t *b) -> bool {
return CompareType(a + offset, b + offset, ftype); return CompareType(a + offset, b + offset, ftype);
}, [&](uint8_t *a, uint8_t *b) { },
[&](uint8_t *a, uint8_t *b) {
// FIXME: faster? // FIXME: faster?
for (size_t i = 0; i < type.struct_def->bytesize; i++) { for (size_t i = 0; i < type.struct_def->bytesize; i++) {
std::swap(a[i], b[i]); std::swap(a[i], b[i]);
@@ -1378,7 +1377,8 @@ CheckedError Parser::ParseVector(const Type &type, uoffset_t *ovalue,
// Here also can't use std::sort. We do have an iterator type for it, // Here also can't use std::sort. We do have an iterator type for it,
// but it is non-standard as it will dereference the offsets, and thus // but it is non-standard as it will dereference the offsets, and thus
// can't be used to swap elements. // can't be used to swap elements.
SimpleQsort<Offset<Table>>(v->data(), v->data() + v->size(), 1, SimpleQsort<Offset<Table>>(
v->data(), v->data() + v->size(), 1,
[](const Offset<Table> *_a, const Offset<Table> *_b) -> bool { [](const Offset<Table> *_a, const Offset<Table> *_b) -> bool {
// Indirect offset pointer to table pointer. // Indirect offset pointer to table pointer.
auto a = reinterpret_cast<const uint8_t *>(_a) + auto a = reinterpret_cast<const uint8_t *>(_a) +
@@ -1389,7 +1389,8 @@ CheckedError Parser::ParseVector(const Type &type, uoffset_t *ovalue,
a = reinterpret_cast<const Table *>(a)->GetAddressOf(offset); a = reinterpret_cast<const Table *>(a)->GetAddressOf(offset);
b = reinterpret_cast<const Table *>(b)->GetAddressOf(offset); b = reinterpret_cast<const Table *>(b)->GetAddressOf(offset);
return CompareType(a, b, ftype); return CompareType(a, b, ftype);
}, [&](Offset<Table> *a, Offset<Table> *b) { },
[&](Offset<Table> *a, Offset<Table> *b) {
// These are serialized offsets, so are relative where they are // These are serialized offsets, so are relative where they are
// stored in memory, so compute the distance between these pointers: // stored in memory, so compute the distance between these pointers:
ptrdiff_t diff = (b - a) * sizeof(Offset<Table>); ptrdiff_t diff = (b - a) * sizeof(Offset<Table>);
@@ -1478,11 +1479,10 @@ 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) { if (!ok) { ECHECK(Error(nested_parser.error_)); }
ECHECK(Error(nested_parser.error_));
}
// Force alignment for nested flatbuffer // Force alignment for nested flatbuffer
builder_.ForceVectorAlignment(nested_parser.builder_.GetSize(), sizeof(uint8_t), builder_.ForceVectorAlignment(
nested_parser.builder_.GetSize(), sizeof(uint8_t),
nested_parser.builder_.GetBufferMinAlignment()); nested_parser.builder_.GetBufferMinAlignment());
auto off = builder_.CreateVector(nested_parser.builder_.GetBufferPointer(), auto off = builder_.CreateVector(nested_parser.builder_.GetBufferPointer(),
@@ -2210,11 +2210,10 @@ CheckedError Parser::CheckClash(std::vector<FieldDef *> &fields,
bool Parser::SupportsAdvancedUnionFeatures() const { bool Parser::SupportsAdvancedUnionFeatures() const {
return opts.lang_to_generate != 0 && return opts.lang_to_generate != 0 &&
(opts.lang_to_generate & ~(IDLOptions::kCpp | IDLOptions::kJs | (opts.lang_to_generate &
IDLOptions::kTs | IDLOptions::kPhp | ~(IDLOptions::kCpp | IDLOptions::kJs | IDLOptions::kTs |
IDLOptions::kJava | IDLOptions::kCSharp | IDLOptions::kPhp | IDLOptions::kJava | IDLOptions::kCSharp |
IDLOptions::kKotlin | IDLOptions::kKotlin | IDLOptions::kBinary)) == 0;
IDLOptions::kBinary)) == 0;
} }
bool Parser::SupportsAdvancedArrayFeatures() const { bool Parser::SupportsAdvancedArrayFeatures() const {
@@ -2486,8 +2485,8 @@ CheckedError Parser::StartEnum(const std::string &enum_name, bool is_union,
if (enums_.Add(current_namespace_->GetFullyQualifiedName(enum_name), if (enums_.Add(current_namespace_->GetFullyQualifiedName(enum_name),
&enum_def)) &enum_def))
return Error("enum already exists: " + enum_name); return Error("enum already exists: " + enum_name);
enum_def.underlying_type.base_type = is_union ? BASE_TYPE_UTYPE enum_def.underlying_type.base_type =
: BASE_TYPE_INT; is_union ? BASE_TYPE_UTYPE : BASE_TYPE_INT;
enum_def.underlying_type.enum_def = &enum_def; enum_def.underlying_type.enum_def = &enum_def;
if (dest) *dest = &enum_def; if (dest) *dest = &enum_def;
return NoError(); return NoError();
@@ -2989,9 +2988,7 @@ CheckedError Parser::DoParse(const char *source, const char **include_paths,
// entered into included_files_. // entered into included_files_.
// This is recursive, but only go as deep as the number of include // This is recursive, but only go as deep as the number of include
// statements. // statements.
if (source_filename) { if (source_filename) { included_files_.erase(source_filename); }
included_files_.erase(source_filename);
}
return DoParse(source, include_paths, source_filename, return DoParse(source, include_paths, source_filename,
include_filename); include_filename);
} }
@@ -3015,9 +3012,9 @@ CheckedError Parser::DoParse(const char *source, const char **include_paths,
uoffset_t toff; uoffset_t toff;
ECHECK(ParseTable(*root_struct_def_, nullptr, &toff)); ECHECK(ParseTable(*root_struct_def_, nullptr, &toff));
if (opts.size_prefixed) { if (opts.size_prefixed) {
builder_.FinishSizePrefixed(Offset<Table>(toff), file_identifier_.length() builder_.FinishSizePrefixed(
? file_identifier_.c_str() Offset<Table>(toff),
: nullptr); file_identifier_.length() ? file_identifier_.c_str() : nullptr);
} else { } else {
builder_.Finish(Offset<Table>(toff), file_identifier_.length() builder_.Finish(Offset<Table>(toff), file_identifier_.length()
? file_identifier_.c_str() ? file_identifier_.c_str()
@@ -3038,8 +3035,7 @@ CheckedError Parser::DoParse(const char *source, const char **include_paths,
if (opts.root_type.empty()) { if (opts.root_type.empty()) {
if (!SetRootType(root_type.c_str())) if (!SetRootType(root_type.c_str()))
return Error("unknown root type: " + root_type); return Error("unknown root type: " + root_type);
if (root_struct_def_->fixed) if (root_struct_def_->fixed) return Error("root type must be a table");
return Error("root type must be a table");
} }
EXPECT(';'); EXPECT(';');
} else if (IsIdent("file_identifier")) { } else if (IsIdent("file_identifier")) {
@@ -3144,10 +3140,9 @@ void Parser::Serialize() {
auto fiid__ = builder_.CreateString(file_identifier_); auto fiid__ = builder_.CreateString(file_identifier_);
auto fext__ = builder_.CreateString(file_extension_); auto fext__ = builder_.CreateString(file_extension_);
auto serv__ = builder_.CreateVectorOfSortedTables(&service_offsets); auto serv__ = builder_.CreateVectorOfSortedTables(&service_offsets);
auto schema_offset = auto schema_offset = reflection::CreateSchema(
reflection::CreateSchema(builder_, objs__, enum__, fiid__, fext__, builder_, objs__, enum__, fiid__, fext__,
(root_struct_def_ ? root_struct_def_->serialized_location : 0), (root_struct_def_ ? root_struct_def_->serialized_location : 0), serv__);
serv__);
if (opts.size_prefixed) { if (opts.size_prefixed) {
builder_.FinishSizePrefixed(schema_offset, reflection::SchemaIdentifier()); builder_.FinishSizePrefixed(schema_offset, reflection::SchemaIdentifier());
} else { } else {
@@ -3197,13 +3192,11 @@ Offset<reflection::Object> StructDef::Serialize(FlatBufferBuilder *builder,
: 0; : 0;
return reflection::CreateObject(*builder, name__, flds__, fixed, return reflection::CreateObject(*builder, name__, flds__, fixed,
static_cast<int>(minalign), static_cast<int>(minalign),
static_cast<int>(bytesize), static_cast<int>(bytesize), attr__, docs__);
attr__, docs__);
} }
bool StructDef::Deserialize(Parser &parser, const reflection::Object *object) { bool StructDef::Deserialize(Parser &parser, const reflection::Object *object) {
if (!DeserializeAttributes(parser, object->attributes())) if (!DeserializeAttributes(parser, object->attributes())) return false;
return false;
DeserializeDoc(doc_comment, object->documentation()); DeserializeDoc(doc_comment, object->documentation());
name = parser.UnqualifiedName(object->name()->str()); name = parser.UnqualifiedName(object->name()->str());
predecl = false; predecl = false;
@@ -3224,9 +3217,7 @@ bool StructDef::Deserialize(Parser &parser, const reflection::Object *object) {
// Recompute padding since that's currently not serialized. // Recompute padding since that's currently not serialized.
auto size = InlineSize(field_def->value.type); auto size = InlineSize(field_def->value.type);
auto next_field = auto next_field =
i + 1 < indexes.size() i + 1 < indexes.size() ? of.Get(indexes[i + 1]) : nullptr;
? of.Get(indexes[i+1])
: nullptr;
tmp_struct_size += size; tmp_struct_size += size;
field_def->padding = field_def->padding =
next_field ? (next_field->offset() - field_def->value.offset) - size next_field ? (next_field->offset() - field_def->value.offset) - size
@@ -3247,7 +3238,8 @@ Offset<reflection::Field> FieldDef::Serialize(FlatBufferBuilder *builder,
auto docs__ = parser.opts.binary_schema_comments auto docs__ = parser.opts.binary_schema_comments
? builder->CreateVectorOfStrings(doc_comment) ? builder->CreateVectorOfStrings(doc_comment)
: 0; : 0;
return reflection::CreateField(*builder, name__, type__, id, value.offset, return reflection::CreateField(
*builder, name__, type__, id, value.offset,
// Is uint64>max(int64) tested? // Is uint64>max(int64) tested?
IsInteger(value.type.base_type) ? StringToInt(value.constant.c_str()) : 0, IsInteger(value.type.base_type) ? StringToInt(value.constant.c_str()) : 0,
// result may be platform-dependent if underlying is float (not double) // result may be platform-dependent if underlying is float (not double)
@@ -3261,8 +3253,7 @@ Offset<reflection::Field> FieldDef::Serialize(FlatBufferBuilder *builder,
bool FieldDef::Deserialize(Parser &parser, const reflection::Field *field) { bool FieldDef::Deserialize(Parser &parser, const reflection::Field *field) {
name = field->name()->str(); name = field->name()->str();
defined_namespace = parser.current_namespace_; defined_namespace = parser.current_namespace_;
if (!value.type.Deserialize(parser, field->type())) if (!value.type.Deserialize(parser, field->type())) return false;
return false;
value.offset = field->offset(); value.offset = field->offset();
if (IsInteger(value.type.base_type)) { if (IsInteger(value.type.base_type)) {
value.constant = NumToString(field->default_integer()); value.constant = NumToString(field->default_integer());
@@ -3276,8 +3267,7 @@ bool FieldDef::Deserialize(Parser &parser, const reflection::Field *field) {
deprecated = field->deprecated(); deprecated = field->deprecated();
required = field->required(); required = field->required();
key = field->key(); key = field->key();
if (!DeserializeAttributes(parser, field->attributes())) if (!DeserializeAttributes(parser, field->attributes())) return false;
return false;
// TODO: this should probably be handled by a separate attribute // TODO: this should probably be handled by a separate attribute
if (attributes.Lookup("flexbuffer")) { if (attributes.Lookup("flexbuffer")) {
flexbuffer = true; flexbuffer = true;
@@ -3303,16 +3293,14 @@ Offset<reflection::RPCCall> RPCCall::Serialize(FlatBufferBuilder *builder,
auto docs__ = parser.opts.binary_schema_comments auto docs__ = parser.opts.binary_schema_comments
? builder->CreateVectorOfStrings(doc_comment) ? builder->CreateVectorOfStrings(doc_comment)
: 0; : 0;
return reflection::CreateRPCCall(*builder, name__, return reflection::CreateRPCCall(
request->serialized_location, *builder, name__, request->serialized_location,
response->serialized_location, response->serialized_location, attr__, docs__);
attr__, docs__);
} }
bool RPCCall::Deserialize(Parser &parser, const reflection::RPCCall *call) { bool RPCCall::Deserialize(Parser &parser, const reflection::RPCCall *call) {
name = call->name()->str(); name = call->name()->str();
if (!DeserializeAttributes(parser, call->attributes())) if (!DeserializeAttributes(parser, call->attributes())) return false;
return false;
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());
@@ -3349,8 +3337,7 @@ bool ServiceDef::Deserialize(Parser &parser,
} }
} }
} }
if (!DeserializeAttributes(parser, service->attributes())) if (!DeserializeAttributes(parser, service->attributes())) return false;
return false;
DeserializeDoc(doc_comment, service->documentation()); DeserializeDoc(doc_comment, service->documentation());
return true; return true;
} }
@@ -3387,8 +3374,7 @@ bool EnumDef::Deserialize(Parser &parser, const reflection::Enum *_enum) {
if (!underlying_type.Deserialize(parser, _enum->underlying_type())) { if (!underlying_type.Deserialize(parser, _enum->underlying_type())) {
return false; return false;
} }
if (!DeserializeAttributes(parser, _enum->attributes())) if (!DeserializeAttributes(parser, _enum->attributes())) return false;
return false;
DeserializeDoc(doc_comment, _enum->documentation()); DeserializeDoc(doc_comment, _enum->documentation());
return true; return true;
} }
@@ -3400,7 +3386,8 @@ Offset<reflection::EnumVal> EnumVal::Serialize(FlatBufferBuilder *builder,
auto docs__ = parser.opts.binary_schema_comments auto docs__ = parser.opts.binary_schema_comments
? builder->CreateVectorOfStrings(doc_comment) ? builder->CreateVectorOfStrings(doc_comment)
: 0; : 0;
return reflection::CreateEnumVal(*builder, name__, value, return reflection::CreateEnumVal(
*builder, name__, value,
union_type.struct_def ? union_type.struct_def->serialized_location : 0, union_type.struct_def ? union_type.struct_def->serialized_location : 0,
type__, docs__); type__, docs__);
} }
@@ -3409,8 +3396,7 @@ bool EnumVal::Deserialize(const Parser &parser,
const reflection::EnumVal *val) { const reflection::EnumVal *val) {
name = val->name()->str(); name = val->name()->str();
value = val->value(); value = val->value();
if (!union_type.Deserialize(parser, val->union_type())) if (!union_type.Deserialize(parser, val->union_type())) return false;
return false;
DeserializeDoc(doc_comment, val->documentation()); DeserializeDoc(doc_comment, val->documentation());
return true; return true;
} }
@@ -3432,8 +3418,7 @@ bool Type::Deserialize(const Parser &parser, const reflection::Type *type) {
bool is_series = type->base_type() == reflection::Vector || bool is_series = type->base_type() == reflection::Vector ||
type->base_type() == reflection::Array; type->base_type() == reflection::Array;
if (type->base_type() == reflection::Obj || if (type->base_type() == reflection::Obj ||
(is_series && (is_series && type->element() == reflection::Obj)) {
type->element() == reflection::Obj)) {
if (static_cast<size_t>(type->index()) < parser.structs_.vec.size()) { if (static_cast<size_t>(type->index()) < parser.structs_.vec.size()) {
struct_def = parser.structs_.vec[type->index()]; struct_def = parser.structs_.vec[type->index()];
struct_def->refcount++; struct_def->refcount++;
@@ -3474,8 +3459,7 @@ Definition::SerializeAttributes(FlatBufferBuilder *builder,
bool Definition::DeserializeAttributes( bool Definition::DeserializeAttributes(
Parser &parser, const Vector<Offset<reflection::KeyValue>> *attrs) { Parser &parser, const Vector<Offset<reflection::KeyValue>> *attrs) {
if (attrs == nullptr) if (attrs == nullptr) return true;
return true;
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();
@@ -3504,9 +3488,7 @@ 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)) { if (!verify_fn(verifier)) { return false; }
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);

View File

@@ -15,6 +15,7 @@
*/ */
#include "flatbuffers/reflection.h" #include "flatbuffers/reflection.h"
#include "flatbuffers/util.h" #include "flatbuffers/util.h"
// Helper functionality for reflection. // Helper functionality for reflection.
@@ -495,9 +496,8 @@ bool VerifyStruct(flatbuffers::Verifier &v,
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.Verify(reinterpret_cast<const uint8_t *>(&parent_table),
v.Verify(reinterpret_cast<const uint8_t *>(&parent_table), offset, offset, obj.bytesize());
obj.bytesize());
} }
bool VerifyVectorOfStructs(flatbuffers::Verifier &v, bool VerifyVectorOfStructs(flatbuffers::Verifier &v,
@@ -536,8 +536,7 @@ bool VerifyUnion(flatbuffers::Verifier &v, const reflection::Schema &schema,
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;
} }
} }
@@ -597,27 +596,24 @@ bool VerifyVector(flatbuffers::Verifier &v, const reflection::Schema &schema,
} }
} }
case reflection::Union: { case reflection::Union: {
auto vec = flatbuffers::GetFieldV<flatbuffers::Offset<uint8_t>>(table, auto vec = flatbuffers::GetFieldV<flatbuffers::Offset<uint8_t>>(
vec_field); table, vec_field);
if (!v.VerifyVector(vec)) return false; if (!v.VerifyVector(vec)) return false;
if (!vec) return true; if (!vec) return true;
auto type_vec = table.GetPointer<Vector<uint8_t> *> auto type_vec = table.GetPointer<Vector<uint8_t> *>(vec_field.offset() -
(vec_field.offset() - sizeof(voffset_t)); sizeof(voffset_t));
if (!v.VerifyVector(type_vec)) return false; if (!v.VerifyVector(type_vec)) return false;
for (uoffset_t j = 0; j < vec->size(); j++) { for (uoffset_t j = 0; j < vec->size(); j++) {
// get union type from the prev field // get union type from the prev field
auto utype = type_vec->Get(j); auto utype = type_vec->Get(j);
auto elem = vec->Get(j); auto elem = vec->Get(j);
if (!VerifyUnion(v, schema, utype, elem, vec_field)) if (!VerifyUnion(v, schema, utype, elem, vec_field)) return false;
return false;
} }
return true; return true;
} }
case reflection::Vector: case reflection::Vector:
case reflection::None: case reflection::None:
default: default: FLATBUFFERS_ASSERT(false); return false;
FLATBUFFERS_ASSERT(false);
return false;
} }
} }
@@ -663,8 +659,7 @@ bool VerifyObject(flatbuffers::Verifier &v, const reflection::Schema &schema,
} }
break; break;
case reflection::Vector: case reflection::Vector:
if (!VerifyVector(v, schema, *table, *field_def)) if (!VerifyVector(v, schema, *table, *field_def)) return false;
return false;
break; break;
case reflection::Obj: { case reflection::Obj: {
auto child_obj = schema.objects()->Get(field_def->type()->index()); auto child_obj = schema.objects()->Get(field_def->type()->index());
@@ -688,14 +683,10 @@ bool VerifyObject(flatbuffers::Verifier &v, const reflection::Schema &schema,
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)) { if (!VerifyUnion(v, schema, utype, uval, *field_def)) { return false; }
return false;
}
break; break;
} }
default: default: FLATBUFFERS_ASSERT(false); break;
FLATBUFFERS_ASSERT(false);
break;
} }
} }

View File

@@ -1,4 +1,5 @@
#include "native_type_test_impl.h" #include "native_type_test_impl.h"
#include "native_type_test_generated.h" #include "native_type_test_generated.h"
namespace flatbuffers { namespace flatbuffers {
@@ -9,5 +10,4 @@ namespace flatbuffers {
const Native::Vector3D UnPack(const Geometry::Vector3D &obj) { const Native::Vector3D UnPack(const Geometry::Vector3D &obj) {
return Native::Vector3D(obj.x(), obj.y(), obj.z()); return Native::Vector3D(obj.x(), obj.y(), obj.z());
} }
} } // namespace flatbuffers

View File

@@ -7,10 +7,18 @@ namespace Native {
float y; float y;
float z; float z;
Vector3D() { x = 0; y = 0; z = 0; }; Vector3D() {
Vector3D(float _x, float _y, float _z) { this->x = _x; this->y = _y; this->z = _z; } x = 0;
y = 0;
z = 0;
}; };
Vector3D(float _x, float _y, float _z) {
this->x = _x;
this->y = _y;
this->z = _z;
} }
};
} // namespace Native
namespace Geometry { namespace Geometry {
struct Vector3D; struct Vector3D;
@@ -19,6 +27,6 @@ namespace Geometry {
namespace flatbuffers { namespace flatbuffers {
Geometry::Vector3D Pack(const Native::Vector3D &obj); Geometry::Vector3D Pack(const Native::Vector3D &obj);
const Native::Vector3D UnPack(const Geometry::Vector3D &obj); const Native::Vector3D UnPack(const Geometry::Vector3D &obj);
} } // namespace flatbuffers
#endif // VECTOR3D_PACK_H #endif // VECTOR3D_PACK_H

View File

@@ -14,6 +14,7 @@
* limitations under the License. * limitations under the License.
*/ */
#include <cmath> #include <cmath>
#include "flatbuffers/flatbuffers.h" #include "flatbuffers/flatbuffers.h"
#include "flatbuffers/idl.h" #include "flatbuffers/idl.h"
#include "flatbuffers/minireflect.h" #include "flatbuffers/minireflect.h"
@@ -43,7 +44,6 @@
#include "flatbuffers/flexbuffers.h" #include "flatbuffers/flexbuffers.h"
// clang-format off // clang-format off
// Check that char* and uint8_t* are interoperable types. // Check that char* and uint8_t* are interoperable types.
// The reinterpret_cast<> between the pointers are used to simplify data loading. // The reinterpret_cast<> between the pointers are used to simplify data loading.
@@ -72,7 +72,8 @@ void FlatBufferBuilderTest();
// http://en.wikipedia.org/wiki/Park%E2%80%93Miller_random_number_generator // http://en.wikipedia.org/wiki/Park%E2%80%93Miller_random_number_generator
uint32_t lcg_seed = 48271; uint32_t lcg_seed = 48271;
uint32_t lcg_rand() { uint32_t lcg_rand() {
return lcg_seed = (static_cast<uint64_t>(lcg_seed) * 279470273UL) % 4294967291UL; return lcg_seed =
(static_cast<uint64_t>(lcg_seed) * 279470273UL) % 4294967291UL;
} }
void lcg_reset() { lcg_seed = 48271; } void lcg_reset() { lcg_seed = 48271; }
@@ -200,14 +201,13 @@ flatbuffers::DetachedBuffer CreateFlatBufferTest(std::string &buffer) {
auto vecofcolors = builder.CreateVectorScalarCast<uint8_t, Color>(colors, 2); auto vecofcolors = builder.CreateVectorScalarCast<uint8_t, Color>(colors, 2);
// shortcut for creating monster with all fields set: // shortcut for creating monster with all fields set:
auto mloc = CreateMonster(builder, &vec, 150, 80, name, inventory, Color_Blue, auto mloc = CreateMonster(
Any_Monster, mlocs[1].Union(), // Store a union. builder, &vec, 150, 80, name, inventory, Color_Blue, Any_Monster,
testv, vecofstrings, vecoftables, 0, mlocs[1].Union(), // Store a union.
nested_flatbuffer_vector, 0, false, 0, 0, 0, 0, 0, testv, vecofstrings, vecoftables, 0, nested_flatbuffer_vector, 0, false,
0, 0, 0, 0, 3.14159f, 3.0f, 0.0f, vecofstrings2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3.14159f, 3.0f, 0.0f, vecofstrings2,
vecofstructs, flex, testv2, 0, 0, 0, 0, 0, 0, 0, 0, vecofstructs, flex, testv2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, AnyUniqueAliases_NONE, 0, AnyUniqueAliases_NONE, 0, AnyAmbiguousAliases_NONE, 0, vecofcolors);
AnyAmbiguousAliases_NONE, 0, vecofcolors);
FinishMonsterBuffer(builder, mloc); FinishMonsterBuffer(builder, mloc);
@@ -567,8 +567,7 @@ void SizePrefixedTest() {
// Create size prefixed buffer. // Create size prefixed buffer.
flatbuffers::FlatBufferBuilder fbb; flatbuffers::FlatBufferBuilder fbb;
FinishSizePrefixedMonsterBuffer( FinishSizePrefixedMonsterBuffer(
fbb, fbb, CreateMonster(fbb, 0, 200, 300, fbb.CreateString("bob")));
CreateMonster(fbb, 0, 200, 300, fbb.CreateString("bob")));
// Verify it. // Verify it.
flatbuffers::Verifier verifier(fbb.GetBufferPointer(), fbb.GetSize()); flatbuffers::Verifier verifier(fbb.GetBufferPointer(), fbb.GetSize());
@@ -598,7 +597,8 @@ void JsonDefaultTest() {
// load FlatBuffer schema (.fbs) from disk // load FlatBuffer schema (.fbs) from disk
std::string schemafile; std::string schemafile;
TEST_EQ(flatbuffers::LoadFile((test_data_path + "monster_test.fbs").c_str(), TEST_EQ(flatbuffers::LoadFile((test_data_path + "monster_test.fbs").c_str(),
false, &schemafile), true); false, &schemafile),
true);
// parse schema first, so we can use it to parse the data after // parse schema first, so we can use it to parse the data after
flatbuffers::Parser parser; flatbuffers::Parser parser;
auto include_test_path = auto include_test_path =
@@ -783,7 +783,9 @@ void ParseAndGenerateTextTest(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((const uint8_t *)schemafile.c_str(), schemafile.size()), true); TEST_EQ(parser.Deserialize((const uint8_t *)schemafile.c_str(),
schemafile.size()),
true);
} else { } else {
TEST_EQ(parser.Parse(schemafile.c_str(), include_directories), true); TEST_EQ(parser.Parse(schemafile.c_str(), include_directories), true);
} }
@@ -1029,7 +1031,8 @@ void ReflectionTest(uint8_t *flatbuf, size_t length) {
} }
void MiniReflectFlatBuffersTest(uint8_t *flatbuf) { void MiniReflectFlatBuffersTest(uint8_t *flatbuf) {
auto s = flatbuffers::FlatBufferToString(flatbuf, Monster::MiniReflectTypeTable()); auto s =
flatbuffers::FlatBufferToString(flatbuf, Monster::MiniReflectTypeTable());
TEST_EQ_STR( TEST_EQ_STR(
s.c_str(), s.c_str(),
"{ " "{ "
@@ -1066,9 +1069,9 @@ void MiniReflectFlatBuffersTest(uint8_t *flatbuf) {
auto vec_buffer = vec_builder.Release(); auto vec_buffer = vec_builder.Release();
auto vec_str = flatbuffers::FlatBufferToString(vec_buffer.data(), auto vec_str = flatbuffers::FlatBufferToString(vec_buffer.data(),
Vec3::MiniReflectTypeTable()); Vec3::MiniReflectTypeTable());
TEST_EQ_STR( TEST_EQ_STR(vec_str.c_str(),
vec_str.c_str(), "{ x: 1.0, y: 2.0, z: 3.0, test1: 1.5, test2: Red, test3: { a: "
"{ x: 1.0, y: 2.0, z: 3.0, test1: 1.5, test2: Red, test3: { a: 16, b: 32 } }"); "16, b: 32 } }");
} }
// Parse a .proto schema, output as .fbs // Parse a .proto schema, output as .fbs
@@ -1085,10 +1088,9 @@ void ParseProtoTest() {
flatbuffers::LoadFile((test_data_path + "prototest/test.golden").c_str(), flatbuffers::LoadFile((test_data_path + "prototest/test.golden").c_str(),
false, &goldenfile), false, &goldenfile),
true); true);
TEST_EQ( TEST_EQ(flatbuffers::LoadFile(
flatbuffers::LoadFile((test_data_path + (test_data_path + "prototest/test_union.golden").c_str(), false,
"prototest/test_union.golden").c_str(), &goldenunionfile),
false, &goldenunionfile),
true); true);
flatbuffers::IDLOptions opts; flatbuffers::IDLOptions opts;
@@ -1526,8 +1528,8 @@ bool FloatCompare(float a, float b) { return fabs(a - b) < 0.001; }
// Additional parser testing not covered elsewhere. // Additional parser testing not covered elsewhere.
void ValueTest() { void ValueTest() {
// Test scientific notation numbers. // Test scientific notation numbers.
TEST_EQ(FloatCompare(TestValue<float>("{ Y:0.0314159e+2 }", "float"), TEST_EQ(
3.14159f), FloatCompare(TestValue<float>("{ Y:0.0314159e+2 }", "float"), 3.14159f),
true); true);
// number in string // number in string
TEST_EQ(FloatCompare(TestValue<float>("{ Y:\"0.0314159e+2\" }", "float"), TEST_EQ(FloatCompare(TestValue<float>("{ Y:\"0.0314159e+2\" }", "float"),
@@ -1566,7 +1568,6 @@ void ValueTest() {
// check comments before and after json object // check comments before and after json object
TEST_EQ(TestValue<int>("/*before*/ { Y:1 } /*after*/", "int"), 1); TEST_EQ(TestValue<int>("/*before*/ { Y:1 } /*after*/", "int"), 1);
TEST_EQ(TestValue<int>("//before \n { Y:1 } //after", "int"), 1); TEST_EQ(TestValue<int>("//before \n { Y:1 } //after", "int"), 1);
} }
void NestedListTest() { void NestedListTest() {
@@ -1629,12 +1630,14 @@ void EnumOutOfRangeTest() {
TestError("enum X:uint { Y = -1 }", "enum value does not fit"); TestError("enum X:uint { Y = -1 }", "enum value does not fit");
TestError("enum X:uint { Y = 4294967297 }", "enum value does not fit"); TestError("enum X:uint { Y = 4294967297 }", "enum value does not fit");
TestError("enum X:long { Y = 9223372036854775808 }", "does not fit"); TestError("enum X:long { Y = 9223372036854775808 }", "does not fit");
TestError("enum X:long { Y = 9223372036854775807, Z }", "enum value does not fit"); TestError("enum X:long { Y = 9223372036854775807, Z }",
"enum value does not fit");
TestError("enum X:ulong { Y = -1 }", "does not fit"); TestError("enum X:ulong { Y = -1 }", "does not fit");
TestError("enum X:ubyte (bit_flags) { Y=8 }", "bit flag out"); TestError("enum X:ubyte (bit_flags) { Y=8 }", "bit flag out");
TestError("enum X:byte (bit_flags) { Y=7 }", "must be unsigned"); // -128 TestError("enum X:byte (bit_flags) { Y=7 }", "must be unsigned"); // -128
// bit_flgs out of range // bit_flgs out of range
TestError("enum X:ubyte (bit_flags) { Y0,Y1,Y2,Y3,Y4,Y5,Y6,Y7,Y8 }", "out of range"); TestError("enum X:ubyte (bit_flags) { Y0,Y1,Y2,Y3,Y4,Y5,Y6,Y7,Y8 }",
"out of range");
} }
void EnumValueTest() { void EnumValueTest() {
@@ -1734,11 +1737,12 @@ void IntegerOutOfRangeTest() {
void IntegerBoundaryTest() { void IntegerBoundaryTest() {
// Check numerical compatibility with non-C++ languages. // Check numerical compatibility with non-C++ languages.
// By the C++ standard, std::numerical_limits<int64_t>::min() == -9223372036854775807 (-2^63+1) or less* // By the C++ standard, std::numerical_limits<int64_t>::min() ==
// The Flatbuffers grammar and most of the languages (C#, Java, Rust) expect // -9223372036854775807 (-2^63+1) or less* The Flatbuffers grammar and most of
// that minimum values are: -128, -32768,.., -9223372036854775808. // the languages (C#, Java, Rust) expect that minimum values are: -128,
// Since C++20, static_cast<int64>(0x8000000000000000ULL) is well-defined two's complement cast. // -32768,.., -9223372036854775808. Since C++20,
// Therefore -9223372036854775808 should be valid negative value. // static_cast<int64>(0x8000000000000000ULL) is well-defined two's complement
// cast. Therefore -9223372036854775808 should be valid negative value.
TEST_EQ(flatbuffers::numeric_limits<int8_t>::min(), -128); TEST_EQ(flatbuffers::numeric_limits<int8_t>::min(), -128);
TEST_EQ(flatbuffers::numeric_limits<int8_t>::max(), 127); TEST_EQ(flatbuffers::numeric_limits<int8_t>::max(), 127);
TEST_EQ(flatbuffers::numeric_limits<int16_t>::min(), -32768); TEST_EQ(flatbuffers::numeric_limits<int16_t>::min(), -32768);
@@ -2311,8 +2315,8 @@ void UnionVectorTest() {
// load FlatBuffer fbs schema and json. // load FlatBuffer fbs schema and json.
std::string schemafile, jsonfile; std::string schemafile, jsonfile;
TEST_EQ(flatbuffers::LoadFile( TEST_EQ(flatbuffers::LoadFile(
(test_data_path + "union_vector/union_vector.fbs").c_str(), (test_data_path + "union_vector/union_vector.fbs").c_str(), false,
false, &schemafile), &schemafile),
true); true);
TEST_EQ(flatbuffers::LoadFile( TEST_EQ(flatbuffers::LoadFile(
(test_data_path + "union_vector/union_vector.json").c_str(), (test_data_path + "union_vector/union_vector.json").c_str(),
@@ -2420,11 +2424,9 @@ void UnionVectorTest() {
"characters: [ { books_read: 7 }, { sword_attack_damage: 5 }, " "characters: [ { books_read: 7 }, { sword_attack_damage: 5 }, "
"{ books_read: 2 }, \"Other\", \"Unused\" ] }"); "{ books_read: 2 }, \"Other\", \"Unused\" ] }");
flatbuffers::ToStringVisitor visitor("\n", true, " "); flatbuffers::ToStringVisitor visitor("\n", true, " ");
IterateFlatBuffer(fbb.GetBufferPointer(), MovieTypeTable(), &visitor); IterateFlatBuffer(fbb.GetBufferPointer(), MovieTypeTable(), &visitor);
TEST_EQ_STR( TEST_EQ_STR(visitor.s.c_str(),
visitor.s.c_str(),
"{\n" "{\n"
" \"main_character_type\": \"Rapunzel\",\n" " \"main_character_type\": \"Rapunzel\",\n"
" \"main_character\": {\n" " \"main_character\": {\n"
@@ -2456,8 +2458,7 @@ void UnionVectorTest() {
std::string jsongen; std::string jsongen;
auto result = GenerateText(parser, fbb.GetBufferPointer(), &jsongen); auto result = GenerateText(parser, fbb.GetBufferPointer(), &jsongen);
TEST_EQ(result, true); TEST_EQ(result, true);
TEST_EQ_STR( TEST_EQ_STR(jsongen.c_str(),
jsongen.c_str(),
"{\n" "{\n"
" main_character_type: \"Rapunzel\",\n" " main_character_type: \"Rapunzel\",\n"
" main_character: {\n" " main_character: {\n"
@@ -2496,7 +2497,8 @@ void UnionVectorTest() {
TEST_EQ(parser2.Parse("struct Bool { b:bool; }" TEST_EQ(parser2.Parse("struct Bool { b:bool; }"
"union Any { Bool }" "union Any { Bool }"
"table Root { a:Any; }" "table Root { a:Any; }"
"root_type Root;"), true); "root_type Root;"),
true);
TEST_EQ(parser2.Parse("{a_type:Bool,a:{b:true}}"), true); TEST_EQ(parser2.Parse("{a_type:Bool,a:{b:true}}"), true);
} }
@@ -2729,14 +2731,16 @@ void UninitializedVectorTest() {
flatbuffers::FlatBufferBuilder builder; flatbuffers::FlatBufferBuilder builder;
Test *buf = nullptr; Test *buf = nullptr;
auto vector_offset = builder.CreateUninitializedVectorOfStructs<Test>(2, &buf); auto vector_offset =
builder.CreateUninitializedVectorOfStructs<Test>(2, &buf);
TEST_NOTNULL(buf); TEST_NOTNULL(buf);
buf[0] = Test(10, 20); buf[0] = Test(10, 20);
buf[1] = Test(30, 40); buf[1] = Test(30, 40);
auto required_name = builder.CreateString("myMonster"); auto required_name = builder.CreateString("myMonster");
auto monster_builder = MonsterBuilder(builder); auto monster_builder = MonsterBuilder(builder);
monster_builder.add_name(required_name); // required field mandated for monster. monster_builder.add_name(
required_name); // required field mandated for monster.
monster_builder.add_test4(vector_offset); monster_builder.add_test4(vector_offset);
builder.Finish(monster_builder.Finish()); builder.Finish(monster_builder.Finish());
@@ -2781,9 +2785,9 @@ void EqualOperatorTest() {
// For testing any binaries, e.g. from fuzzing. // For testing any binaries, e.g. from fuzzing.
void LoadVerifyBinaryTest() { void LoadVerifyBinaryTest() {
std::string binary; std::string binary;
if (flatbuffers::LoadFile((test_data_path + if (flatbuffers::LoadFile(
"fuzzer/your-filename-here").c_str(), (test_data_path + "fuzzer/your-filename-here").c_str(), true,
true, &binary)) { &binary)) {
flatbuffers::Verifier verifier( flatbuffers::Verifier verifier(
reinterpret_cast<const uint8_t *>(binary.data()), binary.size()); reinterpret_cast<const uint8_t *>(binary.data()), binary.size());
TEST_EQ(VerifyMonsterBuffer(verifier), true); TEST_EQ(VerifyMonsterBuffer(verifier), true);
@@ -2810,15 +2814,19 @@ void CreateSharedStringTest() {
TEST_EQ(null_b1.o, null_b2.o); TEST_EQ(null_b1.o, null_b2.o);
// Put the strings into an array for round trip verification. // Put the strings into an array for round trip verification.
const flatbuffers::Offset<flatbuffers::String> array[7] = { one1, two, one2, onetwo, null_b1, null_c, null_b2 }; const flatbuffers::Offset<flatbuffers::String> array[7] = {
const auto vector_offset = builder.CreateVector(array, flatbuffers::uoffset_t(7)); one1, two, one2, onetwo, null_b1, null_c, null_b2
};
const auto vector_offset =
builder.CreateVector(array, flatbuffers::uoffset_t(7));
MonsterBuilder monster_builder(builder); MonsterBuilder monster_builder(builder);
monster_builder.add_name(two); monster_builder.add_name(two);
monster_builder.add_testarrayofstring(vector_offset); monster_builder.add_testarrayofstring(vector_offset);
builder.Finish(monster_builder.Finish()); builder.Finish(monster_builder.Finish());
// Read the Monster back. // Read the Monster back.
const auto *monster = flatbuffers::GetRoot<Monster>(builder.GetBufferPointer()); const auto *monster =
flatbuffers::GetRoot<Monster>(builder.GetBufferPointer());
TEST_EQ_STR(monster->name()->c_str(), "two"); TEST_EQ_STR(monster->name()->c_str(), "two");
const auto *testarrayofstring = monster->testarrayofstring(); const auto *testarrayofstring = monster->testarrayofstring();
TEST_EQ(testarrayofstring->size(), flatbuffers::uoffset_t(7)); TEST_EQ(testarrayofstring->size(), flatbuffers::uoffset_t(7));
@@ -2831,7 +2839,8 @@ void CreateSharedStringTest() {
TEST_EQ(a[5]->str(), (std::string(chars_c, sizeof(chars_c)))); TEST_EQ(a[5]->str(), (std::string(chars_c, sizeof(chars_c))));
TEST_EQ(a[6]->str(), (std::string(chars_b, sizeof(chars_b)))); TEST_EQ(a[6]->str(), (std::string(chars_b, sizeof(chars_b))));
// Make sure String::operator< works, too, since it is related to StringOffsetCompare. // Make sure String::operator< works, too, since it is related to
// StringOffsetCompare.
TEST_EQ((*a[0]) < (*a[1]), true); TEST_EQ((*a[0]) < (*a[1]), true);
TEST_EQ((*a[1]) < (*a[0]), false); TEST_EQ((*a[1]) < (*a[0]), false);
TEST_EQ((*a[1]) < (*a[2]), false); TEST_EQ((*a[1]) < (*a[2]), false);
@@ -2943,7 +2952,8 @@ void NativeTypeTest() {
src_data.vectors.reserve(N); src_data.vectors.reserve(N);
for (int i = 0; i < N; ++i) { for (int i = 0; i < N; ++i) {
src_data.vectors.push_back (Native::Vector3D(10 * i + 0.1f, 10 * i + 0.2f, 10 * i + 0.3f)); src_data.vectors.push_back(
Native::Vector3D(10 * i + 0.1f, 10 * i + 0.2f, 10 * i + 0.3f));
} }
flatbuffers::FlatBufferBuilder fbb; flatbuffers::FlatBufferBuilder fbb;

View File

@@ -1,8 +1,8 @@
#include "flatbuffers/stl_emulation.h"
#include "monster_test_generated.h"
#include "test_builder.h" #include "test_builder.h"
#include "flatbuffers/stl_emulation.h"
#include "monster_test_generated.h"
using namespace MyGame::Example; using namespace MyGame::Example;
const std::string m1_name = "Cyberdemon"; const std::string m1_name = "Cyberdemon";
@@ -77,53 +77,63 @@ public:
void Swap(GrpcLikeMessageBuilder &other) { void Swap(GrpcLikeMessageBuilder &other) {
// No need to swap member_allocator_ because it's stateless. // No need to swap member_allocator_ because it's stateless.
FlatBufferBuilder::Swap(other); FlatBufferBuilder::Swap(other);
// After swapping the FlatBufferBuilder, we swap back the allocator, which restores // After swapping the FlatBufferBuilder, we swap back the allocator, which
// the original allocator back in place. This is necessary because MessageBuilder's // restores the original allocator back in place. This is necessary because
// allocator is its own member (SliceAllocatorMember). The allocator passed to // MessageBuilder's allocator is its own member (SliceAllocatorMember). The
// FlatBufferBuilder::vector_downward must point to this member. // allocator passed to FlatBufferBuilder::vector_downward must point to this
// member.
buf_.swap_allocator(other.buf_); buf_.swap_allocator(other.buf_);
} }
}; };
flatbuffers::Offset<Monster> populate1(flatbuffers::FlatBufferBuilder &builder) { flatbuffers::Offset<Monster> populate1(
flatbuffers::FlatBufferBuilder &builder) {
auto name_offset = builder.CreateString(m1_name); auto name_offset = builder.CreateString(m1_name);
return CreateMonster(builder, nullptr, 0, 0, name_offset, 0, m1_color); return CreateMonster(builder, nullptr, 0, 0, name_offset, 0, m1_color);
} }
flatbuffers::Offset<Monster> populate2(flatbuffers::FlatBufferBuilder &builder) { flatbuffers::Offset<Monster> populate2(
flatbuffers::FlatBufferBuilder &builder) {
auto name_offset = builder.CreateString(m2_name); auto name_offset = builder.CreateString(m2_name);
return CreateMonster(builder, nullptr, 0, 0, name_offset, 0, m2_color); return CreateMonster(builder, nullptr, 0, 0, name_offset, 0, m2_color);
} }
uint8_t *release_raw_base(flatbuffers::FlatBufferBuilder &fbb, size_t &size, size_t &offset) { uint8_t *release_raw_base(flatbuffers::FlatBufferBuilder &fbb, size_t &size,
size_t &offset) {
return fbb.ReleaseRaw(size, offset); return fbb.ReleaseRaw(size, offset);
} }
void free_raw(flatbuffers::grpc::MessageBuilder &, uint8_t *) { void free_raw(flatbuffers::grpc::MessageBuilder &, uint8_t *) {
// release_raw_base calls FlatBufferBuilder::ReleaseRaw on the argument MessageBuilder. // release_raw_base calls FlatBufferBuilder::ReleaseRaw on the argument
// It's semantically wrong as MessageBuilder has its own ReleaseRaw member function that // MessageBuilder. It's semantically wrong as MessageBuilder has its own
// takes three arguments. In such cases though, ~MessageBuilder() invokes // ReleaseRaw member function that takes three arguments. In such cases
// ~SliceAllocator() that takes care of deleting memory as it calls grpc_slice_unref. // though, ~MessageBuilder() invokes ~SliceAllocator() that takes care of
// Obviously, this behavior is very surprising as the pointer returned by // deleting memory as it calls grpc_slice_unref. Obviously, this behavior is
// FlatBufferBuilder::ReleaseRaw is not valid as soon as MessageBuilder goes out of scope. // very surprising as the pointer returned by FlatBufferBuilder::ReleaseRaw is
// This problem does not occur with FlatBufferBuilder. // not valid as soon as MessageBuilder goes out of scope. This problem does
// not occur with FlatBufferBuilder.
} }
void free_raw(flatbuffers::FlatBufferBuilder &, uint8_t *buf) { void free_raw(flatbuffers::FlatBufferBuilder &, uint8_t *buf) {
flatbuffers::DefaultAllocator().deallocate(buf, 0); flatbuffers::DefaultAllocator().deallocate(buf, 0);
} }
bool verify(const flatbuffers::DetachedBuffer &buf, const std::string &expected_name, Color color) { bool verify(const flatbuffers::DetachedBuffer &buf,
const std::string &expected_name, Color color) {
const Monster *monster = flatbuffers::GetRoot<Monster>(buf.data()); const Monster *monster = flatbuffers::GetRoot<Monster>(buf.data());
return (monster->name()->str() == expected_name) && (monster->color() == color); return (monster->name()->str() == expected_name) &&
(monster->color() == color);
} }
bool verify(const uint8_t *buf, size_t offset, const std::string &expected_name, Color color) { bool verify(const uint8_t *buf, size_t offset, const std::string &expected_name,
Color color) {
const Monster *monster = flatbuffers::GetRoot<Monster>(buf + offset); const Monster *monster = flatbuffers::GetRoot<Monster>(buf + offset);
return (monster->name()->str() == expected_name) && (monster->color() == color); return (monster->name()->str() == expected_name) &&
(monster->color() == color);
} }
bool release_n_verify(flatbuffers::FlatBufferBuilder &fbb, const std::string &expected_name, Color color) { bool release_n_verify(flatbuffers::FlatBufferBuilder &fbb,
const std::string &expected_name, Color color) {
flatbuffers::DetachedBuffer buf = fbb.Release(); flatbuffers::DetachedBuffer buf = fbb.Release();
return verify(buf, expected_name, color); return verify(buf, expected_name, color);
} }
@@ -136,13 +146,15 @@ void FlatBufferBuilderTest() {
BuilderTests<GrpcLikeMessageBuilder>::all_tests(); BuilderTests<GrpcLikeMessageBuilder>::all_tests();
BuilderReuseTestSelector tests[4] = { BuilderReuseTestSelector tests[4] = {
REUSABLE_AFTER_RELEASE, REUSABLE_AFTER_RELEASE, REUSABLE_AFTER_RELEASE_RAW,
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(TestSelector(tests, tests+4)); BuilderReuseTests<FlatBufferBuilder, FlatBufferBuilder>::run_tests(
BuilderReuseTests<TestHeapBuilder, TestHeapBuilder>::run_tests(TestSelector(tests, tests+4)); TestSelector(tests, tests + 4));
BuilderReuseTests<GrpcLikeMessageBuilder, GrpcLikeMessageBuilder>::run_tests(TestSelector(tests, tests+4)); BuilderReuseTests<TestHeapBuilder, TestHeapBuilder>::run_tests(
TestSelector(tests, tests + 4));
BuilderReuseTests<GrpcLikeMessageBuilder, GrpcLikeMessageBuilder>::run_tests(
TestSelector(tests, tests + 4));
} }

View File

@@ -3,8 +3,9 @@
#include <set> #include <set>
#include <type_traits> #include <type_traits>
#include "monster_test_generated.h"
#include "flatbuffers/flatbuffers.h" #include "flatbuffers/flatbuffers.h"
#include "monster_test_generated.h"
#include "test_assert.h" #include "test_assert.h"
using MyGame::Example::Color; using MyGame::Example::Color;
@@ -14,17 +15,11 @@ namespace flatbuffers {
namespace grpc { namespace grpc {
class MessageBuilder; class MessageBuilder;
} }
} } // namespace flatbuffers
template <class T, class U> template<class T, class U> struct is_same { static const bool value = false; };
struct is_same {
static const bool value = false;
};
template <class T> template<class T> struct is_same<T, T> { static const bool value = true; };
struct is_same<T, T> {
static const bool value = true;
};
extern const std::string m1_name; extern const std::string m1_name;
extern const Color m1_color; extern const Color m1_color;
@@ -34,16 +29,21 @@ extern const Color m2_color;
flatbuffers::Offset<Monster> populate1(flatbuffers::FlatBufferBuilder &builder); flatbuffers::Offset<Monster> populate1(flatbuffers::FlatBufferBuilder &builder);
flatbuffers::Offset<Monster> populate2(flatbuffers::FlatBufferBuilder &builder); flatbuffers::Offset<Monster> populate2(flatbuffers::FlatBufferBuilder &builder);
uint8_t *release_raw_base(flatbuffers::FlatBufferBuilder &fbb, size_t &size, size_t &offset); uint8_t *release_raw_base(flatbuffers::FlatBufferBuilder &fbb, size_t &size,
size_t &offset);
void free_raw(flatbuffers::grpc::MessageBuilder &mbb, uint8_t *buf); void free_raw(flatbuffers::grpc::MessageBuilder &mbb, uint8_t *buf);
void free_raw(flatbuffers::FlatBufferBuilder &fbb, uint8_t *buf); void free_raw(flatbuffers::FlatBufferBuilder &fbb, uint8_t *buf);
bool verify(const flatbuffers::DetachedBuffer &buf, const std::string &expected_name, Color color); bool verify(const flatbuffers::DetachedBuffer &buf,
bool verify(const uint8_t *buf, size_t offset, const std::string &expected_name, Color color); const std::string &expected_name, Color color);
bool verify(const uint8_t *buf, size_t offset, const std::string &expected_name,
Color color);
bool release_n_verify(flatbuffers::FlatBufferBuilder &fbb, const std::string &expected_name, Color color); bool release_n_verify(flatbuffers::FlatBufferBuilder &fbb,
bool release_n_verify(flatbuffers::grpc::MessageBuilder &mbb, const std::string &expected_name, Color color); const std::string &expected_name, Color color);
bool release_n_verify(flatbuffers::grpc::MessageBuilder &mbb,
const std::string &expected_name, Color color);
// clang-format off // clang-format off
#if !defined(FLATBUFFERS_CPP98_STL) #if !defined(FLATBUFFERS_CPP98_STL)
@@ -55,7 +55,8 @@ void builder_move_assign_after_releaseraw_test(Builder b1) {
auto root_offset1 = populate1(b1); auto root_offset1 = populate1(b1);
b1.Finish(root_offset1); b1.Finish(root_offset1);
size_t size, offset; size_t size, offset;
std::shared_ptr<uint8_t> raw(b1.ReleaseRaw(size, offset), [size](uint8_t *ptr) { std::shared_ptr<uint8_t> raw(
b1.ReleaseRaw(size, offset), [size](uint8_t *ptr) {
flatbuffers::DefaultAllocator::dealloc(ptr, size); flatbuffers::DefaultAllocator::dealloc(ptr, size);
}); });
Builder src; Builder src;
@@ -72,7 +73,8 @@ void builder_move_assign_after_releaseraw_test(Builder b1) {
#endif // !defined(FLATBUFFERS_CPP98_STL) #endif // !defined(FLATBUFFERS_CPP98_STL)
// clang-format on // clang-format on
void builder_move_assign_after_releaseraw_test(flatbuffers::grpc::MessageBuilder b1); void builder_move_assign_after_releaseraw_test(
flatbuffers::grpc::MessageBuilder b1);
template<class DestBuilder, class SrcBuilder = DestBuilder> template<class DestBuilder, class SrcBuilder = DestBuilder>
struct BuilderTests { struct BuilderTests {
@@ -164,7 +166,8 @@ struct BuilderTests {
#endif // !defined(FLATBUFFERS_CPP98_STL) #endif // !defined(FLATBUFFERS_CPP98_STL)
// clang-format on // clang-format on
static void builder_swap_before_finish_test(bool run = is_same<DestBuilder, SrcBuilder>::value) { static void builder_swap_before_finish_test(
bool run = is_same<DestBuilder, SrcBuilder>::value) {
/// Swap is allowed only when lhs and rhs are the same concrete type. /// Swap is allowed only when lhs and rhs are the same concrete type.
if (run) { if (run) {
SrcBuilder src; SrcBuilder src;
@@ -183,7 +186,8 @@ struct BuilderTests {
} }
} }
static void builder_swap_after_finish_test(bool run = is_same<DestBuilder, SrcBuilder>::value) { static void builder_swap_after_finish_test(
bool run = is_same<DestBuilder, SrcBuilder>::value) {
/// Swap is allowed only when lhs and rhs are the same concrete type. /// Swap is allowed only when lhs and rhs are the same concrete type.
if (run) { if (run) {
SrcBuilder src; SrcBuilder src;
@@ -233,12 +237,9 @@ enum BuilderReuseTestSelector {
typedef std::set<BuilderReuseTestSelector> TestSelector; typedef std::set<BuilderReuseTestSelector> TestSelector;
template <class DestBuilder, class SrcBuilder> template<class DestBuilder, class SrcBuilder> struct BuilderReuseTests {
struct BuilderReuseTests {
static void builder_reusable_after_release_test(TestSelector selector) { static void builder_reusable_after_release_test(TestSelector selector) {
if (!selector.count(REUSABLE_AFTER_RELEASE)) { if (!selector.count(REUSABLE_AFTER_RELEASE)) { return; }
return;
}
DestBuilder fbb; DestBuilder fbb;
std::vector<flatbuffers::DetachedBuffer> buffers; std::vector<flatbuffers::DetachedBuffer> buffers;
@@ -251,9 +252,7 @@ struct BuilderReuseTests {
} }
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)) { if (!selector.count(REUSABLE_AFTER_RELEASE_RAW)) { return; }
return;
}
DestBuilder fbb; DestBuilder fbb;
for (int i = 0; i < 5; ++i) { for (int i = 0; i < 5; ++i) {
@@ -269,10 +268,9 @@ struct BuilderReuseTests {
// clang-format off // clang-format off
#if !defined(FLATBUFFERS_CPP98_STL) #if !defined(FLATBUFFERS_CPP98_STL)
// clang-format on // clang-format on
static void builder_reusable_after_release_and_move_assign_test(TestSelector selector) { static void builder_reusable_after_release_and_move_assign_test(
if (!selector.count(REUSABLE_AFTER_RELEASE_AND_MOVE_ASSIGN)) { TestSelector selector) {
return; if (!selector.count(REUSABLE_AFTER_RELEASE_AND_MOVE_ASSIGN)) { return; }
}
DestBuilder dst; DestBuilder dst;
std::vector<flatbuffers::DetachedBuffer> buffers; std::vector<flatbuffers::DetachedBuffer> buffers;
@@ -287,10 +285,9 @@ struct BuilderReuseTests {
} }
} }
static void builder_reusable_after_releaseraw_and_move_assign_test(TestSelector selector) { static void builder_reusable_after_releaseraw_and_move_assign_test(
if (!selector.count(REUSABLE_AFTER_RELEASE_RAW_AND_MOVE_ASSIGN)) { TestSelector selector) {
return; if (!selector.count(REUSABLE_AFTER_RELEASE_RAW_AND_MOVE_ASSIGN)) { return; }
}
DestBuilder dst; DestBuilder dst;
for (int i = 0; i < 5; ++i) { for (int i = 0; i < 5; ++i) {