1 /* 2 * Copyright 2014 Google Inc. All rights reserved. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #ifndef FLATBUFFERS_IDL_H_ 18 #define FLATBUFFERS_IDL_H_ 19 20 #include <map> 21 #include <stack> 22 #include <memory> 23 24 #include "flatbuffers/base.h" 25 #include "flatbuffers/flatbuffers.h" 26 #include "flatbuffers/hash.h" 27 #include "flatbuffers/reflection.h" 28 #include "flatbuffers/flexbuffers.h" 29 30 #if !defined(FLATBUFFERS_CPP98_STL) 31 #include <functional> 32 #endif // !defined(FLATBUFFERS_CPP98_STL) 33 34 // This file defines the data types representing a parsed IDL (Interface 35 // Definition Language) / schema file. 36 37 namespace flatbuffers { 38 39 // The order of these matters for Is*() functions below. 40 // Additionally, Parser::ParseType assumes bool..string is a contiguous range 41 // of type tokens. 42 #define FLATBUFFERS_GEN_TYPES_SCALAR(TD) \ 43 TD(NONE, "", uint8_t, byte, byte, byte, uint8) \ 44 TD(UTYPE, "", uint8_t, byte, byte, byte, uint8) /* begin scalar/int */ \ 45 TD(BOOL, "bool", uint8_t, boolean,byte, bool, bool) \ 46 TD(CHAR, "byte", int8_t, byte, int8, sbyte, int8) \ 47 TD(UCHAR, "ubyte", uint8_t, byte, byte, byte, uint8) \ 48 TD(SHORT, "short", int16_t, short, int16, short, int16) \ 49 TD(USHORT, "ushort", uint16_t, short, uint16, ushort, uint16) \ 50 TD(INT, "int", int32_t, int, int32, int, int32) \ 51 TD(UINT, "uint", uint32_t, int, uint32, uint, uint32) \ 52 TD(LONG, "long", int64_t, long, int64, long, int64) \ 53 TD(ULONG, "ulong", uint64_t, long, uint64, ulong, uint64) /* end int */ \ 54 TD(FLOAT, "float", float, float, float32, float, float32) /* begin float */ \ 55 TD(DOUBLE, "double", double, double, float64, double, float64) /* end float/scalar */ 56 #define FLATBUFFERS_GEN_TYPES_POINTER(TD) \ 57 TD(STRING, "string", Offset<void>, int, int, StringOffset, int) \ 58 TD(VECTOR, "", Offset<void>, int, int, VectorOffset, int) \ 59 TD(STRUCT, "", Offset<void>, int, int, int, int) \ 60 TD(UNION, "", Offset<void>, int, int, int, int) 61 62 // The fields are: 63 // - enum 64 // - FlatBuffers schema type. 65 // - C++ type. 66 // - Java type. 67 // - Go type. 68 // - C# / .Net type. 69 // - Python type. 70 71 // using these macros, we can now write code dealing with types just once, e.g. 72 73 /* 74 switch (type) { 75 #define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE, JTYPE, GTYPE, NTYPE, PTYPE) \ 76 case BASE_TYPE_ ## ENUM: \ 77 // do something specific to CTYPE here 78 FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD) 79 #undef FLATBUFFERS_TD 80 } 81 */ 82 83 #define FLATBUFFERS_GEN_TYPES(TD) \ 84 FLATBUFFERS_GEN_TYPES_SCALAR(TD) \ 85 FLATBUFFERS_GEN_TYPES_POINTER(TD) 86 87 // Create an enum for all the types above. 88 #ifdef __GNUC__ 89 __extension__ // Stop GCC complaining about trailing comma with -Wpendantic. 90 #endif 91 enum BaseType { 92 #define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE, JTYPE, GTYPE, NTYPE, PTYPE) \ 93 BASE_TYPE_ ## ENUM, 94 FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD) 95 #undef FLATBUFFERS_TD 96 }; 97 98 #define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE, JTYPE, GTYPE, NTYPE, PTYPE) \ 99 static_assert(sizeof(CTYPE) <= sizeof(largest_scalar_t), \ 100 "define largest_scalar_t as " #CTYPE); 101 FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD) 102 #undef FLATBUFFERS_TD 103 104 inline bool IsScalar (BaseType t) { return t >= BASE_TYPE_UTYPE && 105 t <= BASE_TYPE_DOUBLE; } 106 inline bool IsInteger(BaseType t) { return t >= BASE_TYPE_UTYPE && 107 t <= BASE_TYPE_ULONG; } 108 inline bool IsFloat (BaseType t) { return t == BASE_TYPE_FLOAT || 109 t == BASE_TYPE_DOUBLE; } 110 inline bool IsLong (BaseType t) { return t == BASE_TYPE_LONG || 111 t == BASE_TYPE_ULONG; } 112 inline bool IsBool (BaseType t) { return t == BASE_TYPE_BOOL; } 113 114 extern const char *const kTypeNames[]; 115 extern const char kTypeSizes[]; 116 117 inline size_t SizeOf(BaseType t) { 118 return kTypeSizes[t]; 119 } 120 121 struct StructDef; 122 struct EnumDef; 123 class Parser; 124 125 // Represents any type in the IDL, which is a combination of the BaseType 126 // and additional information for vectors/structs_. 127 struct Type { 128 explicit Type(BaseType _base_type = BASE_TYPE_NONE, 129 StructDef *_sd = nullptr, EnumDef *_ed = nullptr) 130 : base_type(_base_type), 131 element(BASE_TYPE_NONE), 132 struct_def(_sd), 133 enum_def(_ed) 134 {} 135 136 bool operator==(const Type &o) { 137 return base_type == o.base_type && element == o.element && 138 struct_def == o.struct_def && enum_def == o.enum_def; 139 } 140 141 Type VectorType() const { return Type(element, struct_def, enum_def); } 142 143 Offset<reflection::Type> Serialize(FlatBufferBuilder *builder) const; 144 145 BaseType base_type; 146 BaseType element; // only set if t == BASE_TYPE_VECTOR 147 StructDef *struct_def; // only set if t or element == BASE_TYPE_STRUCT 148 EnumDef *enum_def; // set if t == BASE_TYPE_UNION / BASE_TYPE_UTYPE, 149 // or for an integral type derived from an enum. 150 }; 151 152 // Represents a parsed scalar value, it's type, and field offset. 153 struct Value { 154 Value() : constant("0"), offset(static_cast<voffset_t>( 155 ~(static_cast<voffset_t>(0U)))) {} 156 Type type; 157 std::string constant; 158 voffset_t offset; 159 }; 160 161 // Helper class that retains the original order of a set of identifiers and 162 // also provides quick lookup. 163 template<typename T> class SymbolTable { 164 public: 165 ~SymbolTable() { 166 for (auto it = vec.begin(); it != vec.end(); ++it) { 167 delete *it; 168 } 169 } 170 171 bool Add(const std::string &name, T *e) { 172 vector_emplace_back(&vec, e); 173 auto it = dict.find(name); 174 if (it != dict.end()) return true; 175 dict[name] = e; 176 return false; 177 } 178 179 void Move(const std::string &oldname, const std::string &newname) { 180 auto it = dict.find(oldname); 181 if (it != dict.end()) { 182 auto obj = it->second; 183 dict.erase(it); 184 dict[newname] = obj; 185 } else { 186 assert(false); 187 } 188 } 189 190 T *Lookup(const std::string &name) const { 191 auto it = dict.find(name); 192 return it == dict.end() ? nullptr : it->second; 193 } 194 195 public: 196 std::map<std::string, T *> dict; // quick lookup 197 std::vector<T *> vec; // Used to iterate in order of insertion 198 }; 199 200 // A name space, as set in the schema. 201 struct Namespace { 202 Namespace() : from_table(0) {} 203 204 205 // Given a (potentally unqualified) name, return the "fully qualified" name 206 // which has a full namespaced descriptor. 207 // With max_components you can request less than the number of components 208 // the current namespace has. 209 std::string GetFullyQualifiedName(const std::string &name, 210 size_t max_components = 1000) const; 211 212 std::vector<std::string> components; 213 size_t from_table; // Part of the namespace corresponds to a message/table. 214 }; 215 216 // Base class for all definition types (fields, structs_, enums_). 217 struct Definition { 218 Definition() : generated(false), defined_namespace(nullptr), 219 serialized_location(0), index(-1), refcount(1) {} 220 221 flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset< 222 reflection::KeyValue>>> 223 SerializeAttributes(FlatBufferBuilder *builder, 224 const Parser &parser) const; 225 226 std::string name; 227 std::string file; 228 std::vector<std::string> doc_comment; 229 SymbolTable<Value> attributes; 230 bool generated; // did we already output code for this definition? 231 Namespace *defined_namespace; // Where it was defined. 232 233 // For use with Serialize() 234 uoffset_t serialized_location; 235 int index; // Inside the vector it is stored. 236 int refcount; 237 }; 238 239 struct FieldDef : public Definition { 240 FieldDef() : deprecated(false), required(false), key(false), 241 native_inline(false), flexbuffer(false), nested_flatbuffer(NULL), 242 padding(0) {} 243 244 Offset<reflection::Field> Serialize(FlatBufferBuilder *builder, uint16_t id, 245 const Parser &parser) const; 246 247 Value value; 248 bool deprecated; // Field is allowed to be present in old data, but can't be. 249 // written in new data nor accessed in new code. 250 bool required; // Field must always be present. 251 bool key; // Field functions as a key for creating sorted vectors. 252 bool native_inline; // Field will be defined inline (instead of as a pointer) 253 // for native tables if field is a struct. 254 bool flexbuffer; // This field contains FlexBuffer data. 255 StructDef *nested_flatbuffer; // This field contains nested FlatBuffer data. 256 size_t padding; // Bytes to always pad after this field. 257 }; 258 259 struct StructDef : public Definition { 260 StructDef() 261 : fixed(false), 262 predecl(true), 263 sortbysize(true), 264 has_key(false), 265 minalign(1), 266 bytesize(0) 267 {} 268 269 void PadLastField(size_t min_align) { 270 auto padding = PaddingBytes(bytesize, min_align); 271 bytesize += padding; 272 if (fields.vec.size()) fields.vec.back()->padding = padding; 273 } 274 275 Offset<reflection::Object> Serialize(FlatBufferBuilder *builder, 276 const Parser &parser) const; 277 278 SymbolTable<FieldDef> fields; 279 280 bool fixed; // If it's struct, not a table. 281 bool predecl; // If it's used before it was defined. 282 bool sortbysize; // Whether fields come in the declaration or size order. 283 bool has_key; // It has a key field. 284 size_t minalign; // What the whole object needs to be aligned to. 285 size_t bytesize; // Size if fixed. 286 287 flatbuffers::unique_ptr<std::string> original_location; 288 }; 289 290 inline bool IsStruct(const Type &type) { 291 return type.base_type == BASE_TYPE_STRUCT && type.struct_def->fixed; 292 } 293 294 inline size_t InlineSize(const Type &type) { 295 return IsStruct(type) ? type.struct_def->bytesize : SizeOf(type.base_type); 296 } 297 298 inline size_t InlineAlignment(const Type &type) { 299 return IsStruct(type) ? type.struct_def->minalign : SizeOf(type.base_type); 300 } 301 302 struct EnumVal { 303 EnumVal(const std::string &_name, int64_t _val) 304 : name(_name), value(_val) {} 305 306 Offset<reflection::EnumVal> Serialize(FlatBufferBuilder *builder) const; 307 308 std::string name; 309 std::vector<std::string> doc_comment; 310 int64_t value; 311 Type union_type; 312 }; 313 314 struct EnumDef : public Definition { 315 EnumDef() : is_union(false), uses_type_aliases(false) {} 316 317 EnumVal *ReverseLookup(int enum_idx, bool skip_union_default = true) { 318 for (auto it = vals.vec.begin() + static_cast<int>(is_union && 319 skip_union_default); 320 it != vals.vec.end(); ++it) { 321 if ((*it)->value == enum_idx) { 322 return *it; 323 } 324 } 325 return nullptr; 326 } 327 328 Offset<reflection::Enum> Serialize(FlatBufferBuilder *builder, 329 const Parser &parser) const; 330 331 SymbolTable<EnumVal> vals; 332 bool is_union; 333 bool uses_type_aliases; 334 Type underlying_type; 335 }; 336 337 inline bool EqualByName(const Type &a, const Type &b) { 338 return a.base_type == b.base_type && a.element == b.element && 339 (a.struct_def == b.struct_def || 340 a.struct_def->name == b.struct_def->name) && 341 (a.enum_def == b.enum_def || 342 a.enum_def->name == b.enum_def->name); 343 } 344 345 struct RPCCall { 346 std::string name; 347 SymbolTable<Value> attributes; 348 StructDef *request, *response; 349 }; 350 351 struct ServiceDef : public Definition { 352 SymbolTable<RPCCall> calls; 353 }; 354 355 // Container of options that may apply to any of the source/text generators. 356 struct IDLOptions { 357 bool strict_json; 358 bool skip_js_exports; 359 bool use_goog_js_export_format; 360 bool output_default_scalars_in_json; 361 int indent_step; 362 bool output_enum_identifiers; 363 bool prefixed_enums; 364 bool scoped_enums; 365 bool include_dependence_headers; 366 bool mutable_buffer; 367 bool one_file; 368 bool proto_mode; 369 bool generate_all; 370 bool skip_unexpected_fields_in_json; 371 bool generate_name_strings; 372 bool generate_object_based_api; 373 std::string cpp_object_api_pointer_type; 374 std::string cpp_object_api_string_type; 375 bool gen_nullable; 376 std::string object_prefix; 377 std::string object_suffix; 378 bool union_value_namespacing; 379 bool allow_non_utf8; 380 std::string include_prefix; 381 bool keep_include_path; 382 bool binary_schema_comments; 383 bool skip_flatbuffers_import; 384 std::string go_import; 385 std::string go_namespace; 386 bool reexport_ts_modules; 387 bool protobuf_ascii_alike; 388 389 // Possible options for the more general generator below. 390 enum Language { 391 kJava = 1 << 0, 392 kCSharp = 1 << 1, 393 kGo = 1 << 2, 394 kCpp = 1 << 3, 395 kJs = 1 << 4, 396 kPython = 1 << 5, 397 kPhp = 1 << 6, 398 kJson = 1 << 7, 399 kBinary = 1 << 8, 400 kTs = 1 << 9, 401 kJsonSchema = 1 << 10, 402 kMAX 403 }; 404 405 Language lang; 406 407 enum MiniReflect { kNone, kTypes, kTypesAndNames }; 408 409 MiniReflect mini_reflect; 410 411 // The corresponding language bit will be set if a language is included 412 // for code generation. 413 unsigned long lang_to_generate; 414 415 IDLOptions() 416 : strict_json(false), 417 skip_js_exports(false), 418 use_goog_js_export_format(false), 419 output_default_scalars_in_json(false), 420 indent_step(2), 421 output_enum_identifiers(true), prefixed_enums(true), scoped_enums(false), 422 include_dependence_headers(true), 423 mutable_buffer(false), 424 one_file(false), 425 proto_mode(false), 426 generate_all(false), 427 skip_unexpected_fields_in_json(false), 428 generate_name_strings(false), 429 generate_object_based_api(false), 430 cpp_object_api_pointer_type("std::unique_ptr"), 431 gen_nullable(false), 432 object_suffix("T"), 433 union_value_namespacing(true), 434 allow_non_utf8(false), 435 keep_include_path(false), 436 binary_schema_comments(false), 437 skip_flatbuffers_import(false), 438 reexport_ts_modules(true), 439 protobuf_ascii_alike(false), 440 lang(IDLOptions::kJava), 441 mini_reflect(IDLOptions::kNone), 442 lang_to_generate(0) {} 443 }; 444 445 // This encapsulates where the parser is in the current source file. 446 struct ParserState { 447 ParserState() : cursor_(nullptr), line_(1), token_(-1) {} 448 449 protected: 450 const char *cursor_; 451 int line_; // the current line being parsed 452 int token_; 453 454 std::string attribute_; 455 std::vector<std::string> doc_comment_; 456 }; 457 458 // A way to make error propagation less error prone by requiring values to be 459 // checked. 460 // Once you create a value of this type you must either: 461 // - Call Check() on it. 462 // - Copy or assign it to another value. 463 // Failure to do so leads to an assert. 464 // This guarantees that this as return value cannot be ignored. 465 class CheckedError { 466 public: 467 explicit CheckedError(bool error) 468 : is_error_(error), has_been_checked_(false) {} 469 470 CheckedError &operator=(const CheckedError &other) { 471 is_error_ = other.is_error_; 472 has_been_checked_ = false; 473 other.has_been_checked_ = true; 474 return *this; 475 } 476 477 CheckedError(const CheckedError &other) { 478 *this = other; // Use assignment operator. 479 } 480 481 ~CheckedError() { assert(has_been_checked_); } 482 483 bool Check() { has_been_checked_ = true; return is_error_; } 484 485 private: 486 bool is_error_; 487 mutable bool has_been_checked_; 488 }; 489 490 // Additionally, in GCC we can get these errors statically, for additional 491 // assurance: 492 #ifdef __GNUC__ 493 #define FLATBUFFERS_CHECKED_ERROR CheckedError \ 494 __attribute__((warn_unused_result)) 495 #else 496 #define FLATBUFFERS_CHECKED_ERROR CheckedError 497 #endif 498 499 class Parser : public ParserState { 500 public: 501 explicit Parser(const IDLOptions &options = IDLOptions()) 502 : current_namespace_(nullptr), 503 empty_namespace_(nullptr), 504 root_struct_def_(nullptr), 505 opts(options), 506 uses_flexbuffers_(false), 507 source_(nullptr), 508 anonymous_counter(0) { 509 // Start out with the empty namespace being current. 510 empty_namespace_ = new Namespace(); 511 namespaces_.push_back(empty_namespace_); 512 current_namespace_ = empty_namespace_; 513 known_attributes_["deprecated"] = true; 514 known_attributes_["required"] = true; 515 known_attributes_["key"] = true; 516 known_attributes_["hash"] = true; 517 known_attributes_["id"] = true; 518 known_attributes_["force_align"] = true; 519 known_attributes_["bit_flags"] = true; 520 known_attributes_["original_order"] = true; 521 known_attributes_["nested_flatbuffer"] = true; 522 known_attributes_["csharp_partial"] = true; 523 known_attributes_["streaming"] = true; 524 known_attributes_["idempotent"] = true; 525 known_attributes_["cpp_type"] = true; 526 known_attributes_["cpp_ptr_type"] = true; 527 known_attributes_["cpp_str_type"] = true; 528 known_attributes_["native_inline"] = true; 529 known_attributes_["native_custom_alloc"] = true; 530 known_attributes_["native_type"] = true; 531 known_attributes_["native_default"] = true; 532 known_attributes_["flexbuffer"] = true; 533 } 534 535 ~Parser() { 536 for (auto it = namespaces_.begin(); it != namespaces_.end(); ++it) { 537 delete *it; 538 } 539 } 540 541 // Parse the string containing either schema or JSON data, which will 542 // populate the SymbolTable's or the FlatBufferBuilder above. 543 // include_paths is used to resolve any include statements, and typically 544 // should at least include the project path (where you loaded source_ from). 545 // include_paths must be nullptr terminated if specified. 546 // If include_paths is nullptr, it will attempt to load from the current 547 // directory. 548 // If the source was loaded from a file and isn't an include file, 549 // supply its name in source_filename. 550 // All paths specified in this call must be in posix format, if you accept 551 // paths from user input, please call PosixPath on them first. 552 bool Parse(const char *_source, const char **include_paths = nullptr, 553 const char *source_filename = nullptr); 554 555 // Set the root type. May override the one set in the schema. 556 bool SetRootType(const char *name); 557 558 // Mark all definitions as already having code generated. 559 void MarkGenerated(); 560 561 // Get the files recursively included by the given file. The returned 562 // container will have at least the given file. 563 std::set<std::string> GetIncludedFilesRecursive( 564 const std::string &file_name) const; 565 566 // Fills builder_ with a binary version of the schema parsed. 567 // See reflection/reflection.fbs 568 void Serialize(); 569 570 // Checks that the schema represented by this parser is a safe evolution 571 // of the schema provided. Returns non-empty error on any problems. 572 std::string ConformTo(const Parser &base); 573 574 // Similar to Parse(), but now only accepts JSON to be parsed into a 575 // FlexBuffer. 576 bool ParseFlexBuffer(const char *source, const char *source_filename, 577 flexbuffers::Builder *builder); 578 579 FLATBUFFERS_CHECKED_ERROR CheckInRange(int64_t val, int64_t min, int64_t max); 580 581 StructDef *LookupStruct(const std::string &id) const; 582 583 private: 584 void Message(const std::string &msg); 585 void Warning(const std::string &msg); 586 FLATBUFFERS_CHECKED_ERROR Error(const std::string &msg); 587 FLATBUFFERS_CHECKED_ERROR ParseHexNum(int nibbles, uint64_t *val); 588 FLATBUFFERS_CHECKED_ERROR Next(); 589 FLATBUFFERS_CHECKED_ERROR SkipByteOrderMark(); 590 bool Is(int t); 591 bool IsIdent(const char *id); 592 FLATBUFFERS_CHECKED_ERROR Expect(int t); 593 std::string TokenToStringId(int t); 594 EnumDef *LookupEnum(const std::string &id); 595 FLATBUFFERS_CHECKED_ERROR ParseNamespacing(std::string *id, 596 std::string *last); 597 FLATBUFFERS_CHECKED_ERROR ParseTypeIdent(Type &type); 598 FLATBUFFERS_CHECKED_ERROR ParseType(Type &type); 599 FLATBUFFERS_CHECKED_ERROR AddField(StructDef &struct_def, 600 const std::string &name, const Type &type, 601 FieldDef **dest); 602 FLATBUFFERS_CHECKED_ERROR ParseField(StructDef &struct_def); 603 FLATBUFFERS_CHECKED_ERROR ParseString(Value &val); 604 FLATBUFFERS_CHECKED_ERROR ParseComma(); 605 FLATBUFFERS_CHECKED_ERROR ParseAnyValue(Value &val, FieldDef *field, 606 size_t parent_fieldn, 607 const StructDef *parent_struct_def); 608 #if defined(FLATBUFFERS_CPP98_STL) 609 typedef CheckedError (*ParseTableDelimitersBody)( 610 const std::string &name, size_t &fieldn, const StructDef *struct_def, 611 void *state); 612 #else 613 typedef std::function<CheckedError(const std::string&, size_t&, 614 const StructDef*, void*)> 615 ParseTableDelimitersBody; 616 #endif // defined(FLATBUFFERS_CPP98_STL) 617 FLATBUFFERS_CHECKED_ERROR ParseTableDelimiters(size_t &fieldn, 618 const StructDef *struct_def, 619 ParseTableDelimitersBody body, 620 void *state); 621 FLATBUFFERS_CHECKED_ERROR ParseTable(const StructDef &struct_def, 622 std::string *value, uoffset_t *ovalue); 623 void SerializeStruct(const StructDef &struct_def, const Value &val); 624 void AddVector(bool sortbysize, int count); 625 #if defined(FLATBUFFERS_CPP98_STL) 626 typedef CheckedError (*ParseVectorDelimitersBody)(size_t &count, 627 void *state); 628 #else 629 typedef std::function<CheckedError(size_t&, void*)> 630 ParseVectorDelimitersBody; 631 #endif // defined(FLATBUFFERS_CPP98_STL) 632 FLATBUFFERS_CHECKED_ERROR ParseVectorDelimiters( 633 size_t &count, ParseVectorDelimitersBody body, void *state); 634 FLATBUFFERS_CHECKED_ERROR ParseVector(const Type &type, uoffset_t *ovalue); 635 FLATBUFFERS_CHECKED_ERROR ParseNestedFlatbuffer(Value &val, FieldDef *field, 636 size_t fieldn, 637 const StructDef *parent_struct_def); 638 FLATBUFFERS_CHECKED_ERROR ParseMetaData(SymbolTable<Value> *attributes); 639 FLATBUFFERS_CHECKED_ERROR TryTypedValue(int dtoken, bool check, Value &e, 640 BaseType req, bool *destmatch); 641 FLATBUFFERS_CHECKED_ERROR ParseHash(Value &e, FieldDef* field); 642 FLATBUFFERS_CHECKED_ERROR TokenError(); 643 FLATBUFFERS_CHECKED_ERROR ParseSingleValue(Value &e); 644 FLATBUFFERS_CHECKED_ERROR ParseEnumFromString(Type &type, int64_t *result); 645 StructDef *LookupCreateStruct(const std::string &name, 646 bool create_if_new = true, 647 bool definition = false); 648 FLATBUFFERS_CHECKED_ERROR ParseEnum(bool is_union, EnumDef **dest); 649 FLATBUFFERS_CHECKED_ERROR ParseNamespace(); 650 FLATBUFFERS_CHECKED_ERROR StartStruct(const std::string &name, 651 StructDef **dest); 652 FLATBUFFERS_CHECKED_ERROR ParseDecl(); 653 FLATBUFFERS_CHECKED_ERROR ParseService(); 654 FLATBUFFERS_CHECKED_ERROR ParseProtoFields(StructDef *struct_def, 655 bool isextend, bool inside_oneof); 656 FLATBUFFERS_CHECKED_ERROR ParseProtoOption(); 657 FLATBUFFERS_CHECKED_ERROR ParseProtoKey(); 658 FLATBUFFERS_CHECKED_ERROR ParseProtoDecl(); 659 FLATBUFFERS_CHECKED_ERROR ParseProtoCurliesOrIdent(); 660 FLATBUFFERS_CHECKED_ERROR ParseTypeFromProtoType(Type *type); 661 FLATBUFFERS_CHECKED_ERROR SkipAnyJsonValue(); 662 FLATBUFFERS_CHECKED_ERROR ParseFlexBufferValue(flexbuffers::Builder *builder); 663 FLATBUFFERS_CHECKED_ERROR StartParseFile(const char *source, 664 const char *source_filename); 665 FLATBUFFERS_CHECKED_ERROR ParseRoot(const char *_source, 666 const char **include_paths, 667 const char *source_filename); 668 FLATBUFFERS_CHECKED_ERROR DoParse(const char *_source, 669 const char **include_paths, 670 const char *source_filename, 671 const char *include_filename); 672 FLATBUFFERS_CHECKED_ERROR CheckClash(std::vector<FieldDef*> &fields, 673 StructDef *struct_def, 674 const char *suffix, 675 BaseType baseType); 676 677 bool SupportsVectorOfUnions() const; 678 Namespace *UniqueNamespace(Namespace *ns); 679 680 public: 681 SymbolTable<Type> types_; 682 SymbolTable<StructDef> structs_; 683 SymbolTable<EnumDef> enums_; 684 SymbolTable<ServiceDef> services_; 685 std::vector<Namespace *> namespaces_; 686 Namespace *current_namespace_; 687 Namespace *empty_namespace_; 688 std::string error_; // User readable error_ if Parse() == false 689 690 FlatBufferBuilder builder_; // any data contained in the file 691 StructDef *root_struct_def_; 692 std::string file_identifier_; 693 std::string file_extension_; 694 695 std::map<std::string, std::string> included_files_; 696 std::map<std::string, std::set<std::string>> files_included_per_file_; 697 std::vector<std::string> native_included_files_; 698 699 std::map<std::string, bool> known_attributes_; 700 701 IDLOptions opts; 702 bool uses_flexbuffers_; 703 704 private: 705 const char *source_; 706 707 std::string file_being_parsed_; 708 709 std::vector<std::pair<Value, FieldDef *>> field_stack_; 710 711 int anonymous_counter; 712 }; 713 714 // Utility functions for multiple generators: 715 716 extern std::string MakeCamel(const std::string &in, bool first = true); 717 718 // Generate text (JSON) from a given FlatBuffer, and a given Parser 719 // object that has been populated with the corresponding schema. 720 // If ident_step is 0, no indentation will be generated. Additionally, 721 // if it is less than 0, no linefeeds will be generated either. 722 // See idl_gen_text.cpp. 723 // strict_json adds "quotes" around field names if true. 724 // If the flatbuffer cannot be encoded in JSON (e.g., it contains non-UTF-8 725 // byte arrays in String values), returns false. 726 extern bool GenerateText(const Parser &parser, 727 const void *flatbuffer, 728 std::string *text); 729 extern bool GenerateTextFile(const Parser &parser, 730 const std::string &path, 731 const std::string &file_name); 732 733 // Generate binary files from a given FlatBuffer, and a given Parser 734 // object that has been populated with the corresponding schema. 735 // See idl_gen_general.cpp. 736 extern bool GenerateBinary(const Parser &parser, 737 const std::string &path, 738 const std::string &file_name); 739 740 // Generate a C++ header from the definitions in the Parser object. 741 // See idl_gen_cpp. 742 extern std::string GenerateCPP(const Parser &parser, 743 const std::string &include_guard_ident); 744 extern bool GenerateCPP(const Parser &parser, 745 const std::string &path, 746 const std::string &file_name); 747 748 // Generate JavaScript or TypeScript code from the definitions in the Parser object. 749 // See idl_gen_js. 750 extern std::string GenerateJS(const Parser &parser); 751 extern bool GenerateJS(const Parser &parser, 752 const std::string &path, 753 const std::string &file_name); 754 755 // Generate Go files from the definitions in the Parser object. 756 // See idl_gen_go.cpp. 757 extern bool GenerateGo(const Parser &parser, 758 const std::string &path, 759 const std::string &file_name); 760 761 // Generate Java files from the definitions in the Parser object. 762 // See idl_gen_java.cpp. 763 extern bool GenerateJava(const Parser &parser, 764 const std::string &path, 765 const std::string &file_name); 766 767 // Generate Php code from the definitions in the Parser object. 768 // See idl_gen_php. 769 extern bool GeneratePhp(const Parser &parser, 770 const std::string &path, 771 const std::string &file_name); 772 773 // Generate Python files from the definitions in the Parser object. 774 // See idl_gen_python.cpp. 775 extern bool GeneratePython(const Parser &parser, 776 const std::string &path, 777 const std::string &file_name); 778 779 // Generate Json schema file 780 // See idl_gen_json_schema.cpp. 781 extern bool GenerateJsonSchema(const Parser &parser, 782 const std::string &path, 783 const std::string &file_name); 784 785 // Generate C# files from the definitions in the Parser object. 786 // See idl_gen_csharp.cpp. 787 extern bool GenerateCSharp(const Parser &parser, 788 const std::string &path, 789 const std::string &file_name); 790 791 // Generate Java/C#/.. files from the definitions in the Parser object. 792 // See idl_gen_general.cpp. 793 extern bool GenerateGeneral(const Parser &parser, 794 const std::string &path, 795 const std::string &file_name); 796 797 // Generate a schema file from the internal representation, useful after 798 // parsing a .proto schema. 799 extern std::string GenerateFBS(const Parser &parser, 800 const std::string &file_name); 801 extern bool GenerateFBS(const Parser &parser, 802 const std::string &path, 803 const std::string &file_name); 804 805 // Generate a make rule for the generated JavaScript or TypeScript code. 806 // See idl_gen_js.cpp. 807 extern std::string JSMakeRule(const Parser &parser, 808 const std::string &path, 809 const std::string &file_name); 810 811 // Generate a make rule for the generated C++ header. 812 // See idl_gen_cpp.cpp. 813 extern std::string CPPMakeRule(const Parser &parser, 814 const std::string &path, 815 const std::string &file_name); 816 817 // Generate a make rule for the generated Java/C#/... files. 818 // See idl_gen_general.cpp. 819 extern std::string GeneralMakeRule(const Parser &parser, 820 const std::string &path, 821 const std::string &file_name); 822 823 // Generate a make rule for the generated text (JSON) files. 824 // See idl_gen_text.cpp. 825 extern std::string TextMakeRule(const Parser &parser, 826 const std::string &path, 827 const std::string &file_names); 828 829 // Generate a make rule for the generated binary files. 830 // See idl_gen_general.cpp. 831 extern std::string BinaryMakeRule(const Parser &parser, 832 const std::string &path, 833 const std::string &file_name); 834 835 // Generate GRPC Cpp interfaces. 836 // See idl_gen_grpc.cpp. 837 bool GenerateCppGRPC(const Parser &parser, 838 const std::string &path, 839 const std::string &file_name); 840 841 // Generate GRPC Go interfaces. 842 // See idl_gen_grpc.cpp. 843 bool GenerateGoGRPC(const Parser &parser, 844 const std::string &path, 845 const std::string &file_name); 846 847 } // namespace flatbuffers 848 849 #endif // FLATBUFFERS_IDL_H_ 850