mirror of
https://github.com/google/flatbuffers.git
synced 2026-06-16 09:12:22 +00:00
JSON Parser allows union type fields to come after unions.
This is useful because many JSON generators will sort the fields, cause X_type to follow X. Change-Id: I00ef3ac05418224fc05aee93e6b3b3597e73ffe3 Tested: on Linux. Bug: 29221752
This commit is contained in:
@@ -359,6 +359,19 @@ struct IDLOptions {
|
||||
lang(IDLOptions::kJava) {}
|
||||
};
|
||||
|
||||
// This encapsulates where the parser is in the current source file.
|
||||
struct ParserState {
|
||||
ParserState() : cursor_(nullptr), line_(1), token_(-1) {}
|
||||
|
||||
protected:
|
||||
const char *cursor_;
|
||||
int line_; // the current line being parsed
|
||||
int token_;
|
||||
|
||||
std::string attribute_;
|
||||
std::vector<std::string> doc_comment_;
|
||||
};
|
||||
|
||||
// A way to make error propagation less error prone by requiring values to be
|
||||
// checked.
|
||||
// Once you create a value of this type you must either:
|
||||
@@ -400,14 +413,12 @@ class CheckedError {
|
||||
#define FLATBUFFERS_CHECKED_ERROR CheckedError
|
||||
#endif
|
||||
|
||||
class Parser {
|
||||
class Parser : public ParserState {
|
||||
public:
|
||||
explicit Parser(const IDLOptions &options = IDLOptions())
|
||||
: root_struct_def_(nullptr),
|
||||
opts(options),
|
||||
source_(nullptr),
|
||||
cursor_(nullptr),
|
||||
line_(1),
|
||||
anonymous_counter(0) {
|
||||
// Just in case none are declared:
|
||||
namespaces_.push_back(new Namespace());
|
||||
@@ -478,7 +489,8 @@ private:
|
||||
FieldDef **dest);
|
||||
FLATBUFFERS_CHECKED_ERROR ParseField(StructDef &struct_def);
|
||||
FLATBUFFERS_CHECKED_ERROR ParseAnyValue(Value &val, FieldDef *field,
|
||||
size_t parent_fieldn);
|
||||
size_t parent_fieldn,
|
||||
const StructDef *parent_struct_def);
|
||||
FLATBUFFERS_CHECKED_ERROR ParseTable(const StructDef &struct_def,
|
||||
std::string *value, uoffset_t *ovalue);
|
||||
void SerializeStruct(const StructDef &struct_def, const Value &val);
|
||||
@@ -538,13 +550,9 @@ private:
|
||||
IDLOptions opts;
|
||||
|
||||
private:
|
||||
const char *source_, *cursor_;
|
||||
int line_; // the current line being parsed
|
||||
int token_;
|
||||
std::string file_being_parsed_;
|
||||
const char *source_;
|
||||
|
||||
std::string attribute_;
|
||||
std::vector<std::string> doc_comment_;
|
||||
std::string file_being_parsed_;
|
||||
|
||||
std::vector<std::pair<Value, FieldDef *>> field_stack_;
|
||||
|
||||
|
||||
@@ -335,6 +335,8 @@ template<typename T, typename U> pointer_inside_vector<T, U> piv(T *ptr,
|
||||
return pointer_inside_vector<T, U>(ptr, vec);
|
||||
}
|
||||
|
||||
inline const char *UnionTypeFieldSuffix() { return "_type"; }
|
||||
|
||||
// Helper to figure out the actual table type a union refers to.
|
||||
inline const reflection::Object &GetUnionType(
|
||||
const reflection::Schema &schema, const reflection::Object &parent,
|
||||
@@ -342,7 +344,7 @@ inline const reflection::Object &GetUnionType(
|
||||
auto enumdef = schema.enums()->Get(unionfield.type()->index());
|
||||
// TODO: this is clumsy and slow, but no other way to find it?
|
||||
auto type_field = parent.fields()->LookupByKey(
|
||||
(unionfield.name()->str() + "_type").c_str());
|
||||
(unionfield.name()->str() + UnionTypeFieldSuffix()).c_str());
|
||||
assert(type_field);
|
||||
auto union_type = GetFieldI<uint8_t>(table, *type_field);
|
||||
auto enumval = enumdef->values()->LookupByKey(union_type);
|
||||
|
||||
Reference in New Issue
Block a user