Sync from upstream

This commit is contained in:
吴凡
2016-07-01 11:03:25 +08:00
296 changed files with 16524 additions and 8059 deletions

View File

@@ -18,7 +18,6 @@
#define FLATBUFFERS_IDL_H_
#include <map>
#include <set>
#include <stack>
#include <memory>
#include <functional>
@@ -113,6 +112,7 @@ inline size_t SizeOf(BaseType t) {
struct StructDef;
struct EnumDef;
class Parser;
// Represents any type in the IDL, which is a combination of the BaseType
// and additional information for vectors/structs_.
@@ -184,10 +184,8 @@ template<typename T> class SymbolTable {
return it == dict.end() ? nullptr : it->second;
}
private:
std::map<std::string, T *> dict; // quick lookup
public:
std::map<std::string, T *> dict; // quick lookup
std::vector<T *> vec; // Used to iterate in order of insertion
};
@@ -208,6 +206,11 @@ struct Definition {
Definition() : generated(false), defined_namespace(nullptr),
serialized_location(0), index(-1) {}
flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<
reflection::KeyValue>>>
SerializeAttributes(FlatBufferBuilder *builder,
const Parser &parser) const;
std::string name;
std::string file;
std::vector<std::string> doc_comment;
@@ -223,8 +226,8 @@ struct Definition {
struct FieldDef : public Definition {
FieldDef() : deprecated(false), required(false), key(false), padding(0) {}
Offset<reflection::Field> Serialize(FlatBufferBuilder *builder, uint16_t id)
const;
Offset<reflection::Field> Serialize(FlatBufferBuilder *builder, uint16_t id,
const Parser &parser) const;
Value value;
bool deprecated; // Field is allowed to be present in old data, but can't be
@@ -250,7 +253,8 @@ struct StructDef : public Definition {
if (fields.vec.size()) fields.vec.back()->padding = padding;
}
Offset<reflection::Object> Serialize(FlatBufferBuilder *builder) const;
Offset<reflection::Object> Serialize(FlatBufferBuilder *builder,
const Parser &parser) const;
SymbolTable<FieldDef> fields;
bool fixed; // If it's struct, not a table.
@@ -299,34 +303,137 @@ struct EnumDef : public Definition {
return nullptr;
}
Offset<reflection::Enum> Serialize(FlatBufferBuilder *builder) const;
Offset<reflection::Enum> Serialize(FlatBufferBuilder *builder,
const Parser &parser) const;
SymbolTable<EnumVal> vals;
bool is_union;
Type underlying_type;
};
class Parser {
struct RPCCall {
std::string name;
SymbolTable<Value> attributes;
StructDef *request, *response;
};
struct ServiceDef : public Definition {
SymbolTable<RPCCall> calls;
};
// Container of options that may apply to any of the source/text generators.
struct IDLOptions {
bool strict_json;
bool skip_js_exports;
bool output_default_scalars_in_json;
int indent_step;
bool output_enum_identifiers;
bool prefixed_enums;
bool scoped_enums;
bool include_dependence_headers;
bool mutable_buffer;
bool one_file;
bool proto_mode;
bool generate_all;
bool skip_unexpected_fields_in_json;
bool generate_name_strings;
// Possible options for the more general generator below.
enum Language { kJava, kCSharp, kGo, kMAX };
Language lang;
IDLOptions()
: strict_json(false),
skip_js_exports(false),
output_default_scalars_in_json(false),
indent_step(2),
output_enum_identifiers(true), prefixed_enums(true), scoped_enums(false),
include_dependence_headers(true),
mutable_buffer(false),
one_file(false),
proto_mode(false),
generate_all(false),
skip_unexpected_fields_in_json(false),
generate_name_strings(false),
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:
// - Call Check() on it.
// - Copy or assign it to another value.
// Failure to do so leads to an assert.
// This guarantees that this as return value cannot be ignored.
class CheckedError {
public:
Parser(bool strict_json = false, bool proto_mode = false)
explicit CheckedError(bool error)
: is_error_(error), has_been_checked_(false) {}
CheckedError &operator=(const CheckedError &other) {
is_error_ = other.is_error_;
has_been_checked_ = false;
other.has_been_checked_ = true;
return *this;
}
CheckedError(const CheckedError &other) {
*this = other; // Use assignment operator.
}
~CheckedError() { assert(has_been_checked_); }
bool Check() { has_been_checked_ = true; return is_error_; }
private:
bool is_error_;
mutable bool has_been_checked_;
};
// Additionally, in GCC we can get these errors statically, for additional
// assurance:
#ifdef __GNUC__
#define FLATBUFFERS_CHECKED_ERROR CheckedError \
__attribute__((warn_unused_result))
#else
#define FLATBUFFERS_CHECKED_ERROR CheckedError
#endif
class Parser : public ParserState {
public:
explicit Parser(const IDLOptions &options = IDLOptions())
: root_struct_def_(nullptr),
opts(options),
source_(nullptr),
cursor_(nullptr),
line_(1),
proto_mode_(proto_mode),
strict_json_(strict_json),
anonymous_counter(0) {
// Just in case none are declared:
namespaces_.push_back(new Namespace());
known_attributes_.insert("deprecated");
known_attributes_.insert("required");
known_attributes_.insert("key");
known_attributes_.insert("hash");
known_attributes_.insert("id");
known_attributes_.insert("force_align");
known_attributes_.insert("bit_flags");
known_attributes_.insert("original_order");
known_attributes_.insert("nested_flatbuffer");
known_attributes_["deprecated"] = true;
known_attributes_["required"] = true;
known_attributes_["key"] = true;
known_attributes_["hash"] = true;
known_attributes_["id"] = true;
known_attributes_["force_align"] = true;
known_attributes_["bit_flags"] = true;
known_attributes_["original_order"] = true;
known_attributes_["nested_flatbuffer"] = true;
known_attributes_["csharp_partial"] = true;
known_attributes_["streaming"] = true;
known_attributes_["idempotent"] = true;
}
~Parser() {
@@ -362,48 +469,71 @@ class Parser {
// See reflection/reflection.fbs
void Serialize();
private:
int64_t ParseHexNum(int nibbles);
void Next();
bool IsNext(int t);
void Expect(int t);
FLATBUFFERS_CHECKED_ERROR CheckBitsFit(int64_t val, size_t bits);
private:
FLATBUFFERS_CHECKED_ERROR Error(const std::string &msg);
FLATBUFFERS_CHECKED_ERROR ParseHexNum(int nibbles, int64_t *val);
FLATBUFFERS_CHECKED_ERROR Next();
FLATBUFFERS_CHECKED_ERROR SkipByteOrderMark();
bool Is(int t);
FLATBUFFERS_CHECKED_ERROR Expect(int t);
std::string TokenToStringId(int t);
EnumDef *LookupEnum(const std::string &id);
void ParseNamespacing(std::string *id, std::string *last);
void ParseTypeIdent(Type &type);
void ParseType(Type &type);
FieldDef &AddField(StructDef &struct_def,
const std::string &name,
const Type &type);
void ParseField(StructDef &struct_def);
void ParseAnyValue(Value &val, FieldDef *field, size_t parent_fieldn);
uoffset_t ParseTable(const StructDef &struct_def, std::string *value);
FLATBUFFERS_CHECKED_ERROR ParseNamespacing(std::string *id,
std::string *last);
FLATBUFFERS_CHECKED_ERROR ParseTypeIdent(Type &type);
FLATBUFFERS_CHECKED_ERROR ParseType(Type &type);
FLATBUFFERS_CHECKED_ERROR AddField(StructDef &struct_def,
const std::string &name, const Type &type,
FieldDef **dest);
FLATBUFFERS_CHECKED_ERROR ParseField(StructDef &struct_def);
FLATBUFFERS_CHECKED_ERROR ParseAnyValue(Value &val, FieldDef *field,
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);
void AddVector(bool sortbysize, int count);
uoffset_t ParseVector(const Type &type);
void ParseMetaData(Definition &def);
bool TryTypedValue(int dtoken, bool check, Value &e, BaseType req);
void ParseHash(Value &e, FieldDef* field);
void ParseSingleValue(Value &e);
int64_t ParseIntegerFromString(Type &type);
FLATBUFFERS_CHECKED_ERROR ParseVector(const Type &type, uoffset_t *ovalue);
FLATBUFFERS_CHECKED_ERROR ParseMetaData(SymbolTable<Value> *attributes);
FLATBUFFERS_CHECKED_ERROR TryTypedValue(int dtoken, bool check, Value &e,
BaseType req, bool *destmatch);
FLATBUFFERS_CHECKED_ERROR ParseHash(Value &e, FieldDef* field);
FLATBUFFERS_CHECKED_ERROR ParseSingleValue(Value &e);
FLATBUFFERS_CHECKED_ERROR ParseEnumFromString(Type &type, int64_t *result);
StructDef *LookupCreateStruct(const std::string &name,
bool create_if_new = true,
bool definition = false);
EnumDef &ParseEnum(bool is_union);
void ParseNamespace();
StructDef &StartStruct(const std::string &name);
void ParseDecl();
void ParseProtoFields(StructDef *struct_def, bool isextend,
bool inside_oneof);
void ParseProtoOption();
void ParseProtoKey();
void ParseProtoDecl();
void ParseProtoCurliesOrIdent();
Type ParseTypeFromProtoType();
FLATBUFFERS_CHECKED_ERROR ParseEnum(bool is_union, EnumDef **dest);
FLATBUFFERS_CHECKED_ERROR ParseNamespace();
FLATBUFFERS_CHECKED_ERROR StartStruct(const std::string &name,
StructDef **dest);
FLATBUFFERS_CHECKED_ERROR ParseDecl();
FLATBUFFERS_CHECKED_ERROR ParseService();
FLATBUFFERS_CHECKED_ERROR ParseProtoFields(StructDef *struct_def,
bool isextend, bool inside_oneof);
FLATBUFFERS_CHECKED_ERROR ParseProtoOption();
FLATBUFFERS_CHECKED_ERROR ParseProtoKey();
FLATBUFFERS_CHECKED_ERROR ParseProtoDecl();
FLATBUFFERS_CHECKED_ERROR ParseProtoCurliesOrIdent();
FLATBUFFERS_CHECKED_ERROR ParseTypeFromProtoType(Type *type);
FLATBUFFERS_CHECKED_ERROR SkipAnyJsonValue();
FLATBUFFERS_CHECKED_ERROR SkipJsonObject();
FLATBUFFERS_CHECKED_ERROR SkipJsonArray();
FLATBUFFERS_CHECKED_ERROR SkipJsonString();
FLATBUFFERS_CHECKED_ERROR DoParse(const char *_source,
const char **include_paths,
const char *source_filename);
FLATBUFFERS_CHECKED_ERROR CheckClash(std::vector<FieldDef*> &fields,
StructDef *struct_def,
const char *suffix,
BaseType baseType);
public:
SymbolTable<StructDef> structs_;
SymbolTable<EnumDef> enums_;
SymbolTable<ServiceDef> services_;
std::vector<Namespace *> namespaces_;
std::string error_; // User readable error_ if Parse() == false
@@ -415,7 +545,12 @@ class Parser {
std::map<std::string, bool> included_files_;
std::map<std::string, std::set<std::string>> files_included_per_file_;
std::map<std::string, bool> known_attributes_;
IDLOptions opts;
private:
<<<<<<< HEAD
const char *source_, *cursor_;
int line_; // the current line being parsed
int token_;
@@ -424,11 +559,14 @@ class Parser {
bool strict_json_;
std::string attribute_;
std::vector<std::string> doc_comment_;
=======
const char *source_;
>>>>>>> 48f37f9e0a04f2b60046dda7fef20a8b0ebc1a70
std::string file_being_parsed_;
std::vector<std::pair<Value, FieldDef *>> field_stack_;
std::set<std::string> known_attributes_;
int anonymous_counter;
};
@@ -443,35 +581,6 @@ extern void GenComment(const std::vector<std::string> &dc,
const CommentConfig *config,
const char *prefix = "");
// Container of options that may apply to any of the source/text generators.
struct GeneratorOptions {
bool strict_json;
bool skip_js_exports;
bool output_default_scalars_in_json;
int indent_step;
bool output_enum_identifiers;
bool prefixed_enums;
bool scoped_enums;
bool include_dependence_headers;
bool mutable_buffer;
bool one_file;
// Possible options for the more general generator below.
enum Language { kJava, kCSharp, kGo, kMAX };
Language lang;
GeneratorOptions() : strict_json(false),
skip_js_exports(false),
output_default_scalars_in_json(false),
indent_step(2),
output_enum_identifiers(true), prefixed_enums(true), scoped_enums(false),
include_dependence_headers(true),
mutable_buffer(false),
one_file(false),
lang(GeneratorOptions::kJava) {}
};
// Generate text (JSON) from a given FlatBuffer, and a given Parser
// object that has been populated with the corresponding schema.
// If ident_step is 0, no indentation will be generated. Additionally,
@@ -480,126 +589,112 @@ struct GeneratorOptions {
// strict_json adds "quotes" around field names if true.
extern void GenerateText(const Parser &parser,
const void *flatbuffer,
const GeneratorOptions &opts,
std::string *text);
extern bool GenerateTextFile(const Parser &parser,
const std::string &path,
const std::string &file_name,
const GeneratorOptions &opts);
const std::string &file_name);
// Generate binary files from a given FlatBuffer, and a given Parser
// object that has been populated with the corresponding schema.
// See idl_gen_general.cpp.
extern bool GenerateBinary(const Parser &parser,
const std::string &path,
const std::string &file_name,
const GeneratorOptions &opts);
const std::string &file_name);
// Generate a C++ header from the definitions in the Parser object.
// See idl_gen_cpp.
extern std::string GenerateCPP(const Parser &parser,
const std::string &include_guard_ident,
const GeneratorOptions &opts);
const std::string &include_guard_ident);
extern bool GenerateCPP(const Parser &parser,
const std::string &path,
const std::string &file_name,
const GeneratorOptions &opts);
const std::string &file_name);
// Generate JavaScript code from the definitions in the Parser object.
// See idl_gen_js.
extern std::string GenerateJS(const Parser &parser,
const GeneratorOptions &opts);
extern std::string GenerateJS(const Parser &parser);
extern bool GenerateJS(const Parser &parser,
const std::string &path,
const std::string &file_name,
const GeneratorOptions &opts);
const std::string &file_name);
// Generate Go files from the definitions in the Parser object.
// See idl_gen_go.cpp.
extern bool GenerateGo(const Parser &parser,
const std::string &path,
const std::string &file_name,
const GeneratorOptions &opts);
const std::string &file_name);
// Generate Java files from the definitions in the Parser object.
// See idl_gen_java.cpp.
extern bool GenerateJava(const Parser &parser,
const std::string &path,
const std::string &file_name,
const GeneratorOptions &opts);
const std::string &file_name);
// Generate Php code from the definitions in the Parser object.
// See idl_gen_php.
extern bool GeneratePhp(const Parser &parser,
const std::string &path,
const std::string &file_name,
const GeneratorOptions &opts);
const std::string &file_name);
// Generate Python files from the definitions in the Parser object.
// See idl_gen_python.cpp.
extern bool GeneratePython(const Parser &parser,
const std::string &path,
const std::string &file_name,
const GeneratorOptions &opts);
const std::string &file_name);
// Generate C# files from the definitions in the Parser object.
// See idl_gen_csharp.cpp.
extern bool GenerateCSharp(const Parser &parser,
const std::string &path,
const std::string &file_name,
const GeneratorOptions &opts);
const std::string &file_name);
// Generate Java/C#/.. files from the definitions in the Parser object.
// See idl_gen_general.cpp.
extern bool GenerateGeneral(const Parser &parser,
const std::string &path,
const std::string &file_name,
const GeneratorOptions &opts);
const std::string &file_name);
// Generate a schema file from the internal representation, useful after
// parsing a .proto schema.
extern std::string GenerateFBS(const Parser &parser,
const std::string &file_name,
const GeneratorOptions &opts);
const std::string &file_name);
extern bool GenerateFBS(const Parser &parser,
const std::string &path,
const std::string &file_name,
const GeneratorOptions &opts);
const std::string &file_name);
// Generate a make rule for the generated JavaScript code.
// See idl_gen_js.cpp.
extern std::string JSMakeRule(const Parser &parser,
const std::string &path,
const std::string &file_name,
const GeneratorOptions &opts);
const std::string &file_name);
// Generate a make rule for the generated C++ header.
// See idl_gen_cpp.cpp.
extern std::string CPPMakeRule(const Parser &parser,
const std::string &path,
const std::string &file_name,
const GeneratorOptions &opts);
const std::string &file_name);
// Generate a make rule for the generated Java/C#/... files.
// See idl_gen_general.cpp.
extern std::string GeneralMakeRule(const Parser &parser,
const std::string &path,
const std::string &file_name,
const GeneratorOptions &opts);
const std::string &file_name);
// Generate a make rule for the generated text (JSON) files.
// See idl_gen_text.cpp.
extern std::string TextMakeRule(const Parser &parser,
const std::string &path,
const std::string &file_name,
const GeneratorOptions &opts);
const std::string &file_names);
// Generate a make rule for the generated binary files.
// See idl_gen_general.cpp.
extern std::string BinaryMakeRule(const Parser &parser,
const std::string &path,
const std::string &file_name,
const GeneratorOptions &opts);
const std::string &file_name);
// Generate GRPC interfaces.
// See idl_gen_grpc.cpp.
bool GenerateGRPC(const Parser &parser,
const std::string &path,
const std::string &file_name);
} // namespace flatbuffers