github.com/google/syzkaller@v0.0.0-20251211124644-a066d2bc4b02/executor/_include/flatbuffers/idl.h (about) 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 <algorithm> 21 #include <functional> 22 #include <map> 23 #include <memory> 24 #include <stack> 25 26 #include "flatbuffers/base.h" 27 #include "flatbuffers/flatbuffers.h" 28 #include "flatbuffers/flexbuffers.h" 29 #include "flatbuffers/hash.h" 30 #include "flatbuffers/reflection.h" 31 32 // This file defines the data types representing a parsed IDL (Interface 33 // Definition Language) / schema file. 34 35 // Limits maximum depth of nested objects. 36 // Prevents stack overflow while parse scheme, or json, or flexbuffer. 37 #if !defined(FLATBUFFERS_MAX_PARSING_DEPTH) 38 # define FLATBUFFERS_MAX_PARSING_DEPTH 64 39 #endif 40 41 namespace flatbuffers { 42 43 // The order of these matters for Is*() functions below. 44 // Additionally, Parser::ParseType assumes bool..string is a contiguous range 45 // of type tokens. 46 // clang-format off 47 #define FLATBUFFERS_GEN_TYPES_SCALAR(TD) \ 48 TD(NONE, "", uint8_t, byte, byte, byte, uint8, u8, UByte, UInt8, 0) \ 49 TD(UTYPE, "", uint8_t, byte, byte, byte, uint8, u8, UByte, UInt8, 1) /* begin scalar/int */ \ 50 TD(BOOL, "bool", uint8_t, boolean,bool, bool, bool, bool, Boolean, Bool, 2) \ 51 TD(CHAR, "byte", int8_t, byte, int8, sbyte, int8, i8, Byte, Int8, 3) \ 52 TD(UCHAR, "ubyte", uint8_t, byte, byte, byte, uint8, u8, UByte, UInt8, 4) \ 53 TD(SHORT, "short", int16_t, short, int16, short, int16, i16, Short, Int16, 5) \ 54 TD(USHORT, "ushort", uint16_t, short, uint16, ushort, uint16, u16, UShort, UInt16, 6) \ 55 TD(INT, "int", int32_t, int, int32, int, int32, i32, Int, Int32, 7) \ 56 TD(UINT, "uint", uint32_t, int, uint32, uint, uint32, u32, UInt, UInt32, 8) \ 57 TD(LONG, "long", int64_t, long, int64, long, int64, i64, Long, Int64, 9) \ 58 TD(ULONG, "ulong", uint64_t, long, uint64, ulong, uint64, u64, ULong, UInt64, 10) /* end int */ \ 59 TD(FLOAT, "float", float, float, float32, float, float32, f32, Float, Float32, 11) /* begin float */ \ 60 TD(DOUBLE, "double", double, double, float64, double, float64, f64, Double, Double, 12) /* end float/scalar */ 61 #define FLATBUFFERS_GEN_TYPES_POINTER(TD) \ 62 TD(STRING, "string", Offset<void>, int, int, StringOffset, int, unused, Int, Offset<String>, 13) \ 63 TD(VECTOR, "", Offset<void>, int, int, VectorOffset, int, unused, Int, Offset<UOffset>, 14) \ 64 TD(VECTOR64, "", Offset64<void>, int, int, VectorOffset, int, unused, Int, Offset<UOffset>, 18) \ 65 TD(STRUCT, "", Offset<void>, int, int, int, int, unused, Int, Offset<UOffset>, 15) \ 66 TD(UNION, "", Offset<void>, int, int, int, int, unused, Int, Offset<UOffset>, 16) 67 #define FLATBUFFERS_GEN_TYPE_ARRAY(TD) \ 68 TD(ARRAY, "", int, int, int, int, int, unused, Int, Offset<UOffset>, 17) 69 // The fields are: 70 // - enum 71 // - FlatBuffers schema type. 72 // - C++ type. 73 // - Java type. 74 // - Go type. 75 // - C# / .Net type. 76 // - Python type. 77 // - Kotlin type. 78 // - Rust type. 79 // - Swift type. 80 // - enum value (matches the reflected values) 81 82 // using these macros, we can now write code dealing with types just once, e.g. 83 84 /* 85 switch (type) { 86 #define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE, JTYPE, GTYPE, NTYPE, PTYPE, \ 87 RTYPE, KTYPE, STYPE, ...) \ 88 case BASE_TYPE_ ## ENUM: \ 89 // do something specific to CTYPE here 90 FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD) 91 #undef FLATBUFFERS_TD 92 } 93 */ 94 95 // If not all FLATBUFFERS_GEN_() arguments are necessary for implementation 96 // of FLATBUFFERS_TD, you can use a variadic macro (with __VA_ARGS__ if needed). 97 // In the above example, only CTYPE is used to generate the code, it can be rewritten: 98 99 /* 100 switch (type) { 101 #define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE, ...) \ 102 case BASE_TYPE_ ## ENUM: \ 103 // do something specific to CTYPE here 104 FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD) 105 #undef FLATBUFFERS_TD 106 } 107 */ 108 109 #define FLATBUFFERS_GEN_TYPES(TD) \ 110 FLATBUFFERS_GEN_TYPES_SCALAR(TD) \ 111 FLATBUFFERS_GEN_TYPES_POINTER(TD) \ 112 FLATBUFFERS_GEN_TYPE_ARRAY(TD) 113 114 // Create an enum for all the types above. 115 #ifdef __GNUC__ 116 __extension__ // Stop GCC complaining about trailing comma with -Wpendantic. 117 #endif 118 enum BaseType { 119 #define FLATBUFFERS_TD(ENUM, IDLTYPE, \ 120 CTYPE, JTYPE, GTYPE, NTYPE, PTYPE, RTYPE, KTYPE, STYPE, ENUM_VALUE) \ 121 BASE_TYPE_ ## ENUM = ENUM_VALUE, 122 FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD) 123 #undef FLATBUFFERS_TD 124 }; 125 126 #define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE, ...) \ 127 static_assert(sizeof(CTYPE) <= sizeof(largest_scalar_t), \ 128 "define largest_scalar_t as " #CTYPE); 129 FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD) 130 #undef FLATBUFFERS_TD 131 132 inline bool IsScalar (BaseType t) { return t >= BASE_TYPE_UTYPE && 133 t <= BASE_TYPE_DOUBLE; } 134 inline bool IsInteger(BaseType t) { return t >= BASE_TYPE_UTYPE && 135 t <= BASE_TYPE_ULONG; } 136 inline bool IsFloat (BaseType t) { return t == BASE_TYPE_FLOAT || 137 t == BASE_TYPE_DOUBLE; } 138 inline bool IsLong (BaseType t) { return t == BASE_TYPE_LONG || 139 t == BASE_TYPE_ULONG; } 140 inline bool IsBool (BaseType t) { return t == BASE_TYPE_BOOL; } 141 inline bool IsOneByte(BaseType t) { return t >= BASE_TYPE_UTYPE && 142 t <= BASE_TYPE_UCHAR; } 143 inline bool IsVector (BaseType t) { return t == BASE_TYPE_VECTOR || 144 t == BASE_TYPE_VECTOR64; } 145 146 inline bool IsUnsigned(BaseType t) { 147 return (t == BASE_TYPE_UTYPE) || (t == BASE_TYPE_UCHAR) || 148 (t == BASE_TYPE_USHORT) || (t == BASE_TYPE_UINT) || 149 (t == BASE_TYPE_ULONG); 150 } 151 152 inline size_t SizeOf(const BaseType t) { 153 switch (t) { 154 #define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE, ...) \ 155 case BASE_TYPE_##ENUM: return sizeof(CTYPE); 156 FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD) 157 #undef FLATBUFFERS_TD 158 default: FLATBUFFERS_ASSERT(0); 159 } 160 return 0; 161 } 162 163 inline const char* TypeName(const BaseType t) { 164 switch (t) { 165 #define FLATBUFFERS_TD(ENUM, IDLTYPE, ...) \ 166 case BASE_TYPE_##ENUM: return IDLTYPE; 167 FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD) 168 #undef FLATBUFFERS_TD 169 default: FLATBUFFERS_ASSERT(0); 170 } 171 return nullptr; 172 } 173 174 inline const char* StringOf(const BaseType t) { 175 switch (t) { 176 #define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE, ...) \ 177 case BASE_TYPE_##ENUM: return #CTYPE; 178 FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD) 179 #undef FLATBUFFERS_TD 180 default: FLATBUFFERS_ASSERT(0); 181 } 182 return ""; 183 } 184 185 // clang-format on 186 187 struct StructDef; 188 struct EnumDef; 189 class Parser; 190 191 // Represents any type in the IDL, which is a combination of the BaseType 192 // and additional information for vectors/structs_. 193 struct Type { 194 explicit Type(BaseType _base_type = BASE_TYPE_NONE, StructDef *_sd = nullptr, 195 EnumDef *_ed = nullptr, uint16_t _fixed_length = 0) 196 : base_type(_base_type), 197 element(BASE_TYPE_NONE), 198 struct_def(_sd), 199 enum_def(_ed), 200 fixed_length(_fixed_length) {} 201 202 bool operator==(const Type &o) const { 203 return base_type == o.base_type && element == o.element && 204 struct_def == o.struct_def && enum_def == o.enum_def; 205 } 206 207 Type VectorType() const { 208 return Type(element, struct_def, enum_def, fixed_length); 209 } 210 211 Offset<reflection::Type> Serialize(FlatBufferBuilder *builder) const; 212 213 bool Deserialize(const Parser &parser, const reflection::Type *type); 214 215 BaseType base_type; 216 BaseType element; // only set if t == BASE_TYPE_VECTOR or 217 // BASE_TYPE_VECTOR64 218 StructDef *struct_def; // only set if t or element == BASE_TYPE_STRUCT 219 EnumDef *enum_def; // set if t == BASE_TYPE_UNION / BASE_TYPE_UTYPE, 220 // or for an integral type derived from an enum. 221 uint16_t fixed_length; // only set if t == BASE_TYPE_ARRAY 222 }; 223 224 // Represents a parsed scalar value, it's type, and field offset. 225 struct Value { 226 Value() 227 : constant("0"), 228 offset(static_cast<voffset_t>(~(static_cast<voffset_t>(0U)))) {} 229 Type type; 230 std::string constant; 231 voffset_t offset; 232 }; 233 234 // Helper class that retains the original order of a set of identifiers and 235 // also provides quick lookup. 236 template<typename T> class SymbolTable { 237 public: 238 ~SymbolTable() { 239 for (auto it = vec.begin(); it != vec.end(); ++it) { delete *it; } 240 } 241 242 bool Add(const std::string &name, T *e) { 243 vec.emplace_back(e); 244 auto it = dict.find(name); 245 if (it != dict.end()) return true; 246 dict[name] = e; 247 return false; 248 } 249 250 void Move(const std::string &oldname, const std::string &newname) { 251 auto it = dict.find(oldname); 252 if (it != dict.end()) { 253 auto obj = it->second; 254 dict.erase(it); 255 dict[newname] = obj; 256 } else { 257 FLATBUFFERS_ASSERT(false); 258 } 259 } 260 261 T *Lookup(const std::string &name) const { 262 auto it = dict.find(name); 263 return it == dict.end() ? nullptr : it->second; 264 } 265 266 public: 267 std::map<std::string, T *> dict; // quick lookup 268 std::vector<T *> vec; // Used to iterate in order of insertion 269 }; 270 271 // A name space, as set in the schema. 272 struct Namespace { 273 Namespace() : from_table(0) {} 274 275 // Given a (potentially unqualified) name, return the "fully qualified" name 276 // which has a full namespaced descriptor. 277 // With max_components you can request less than the number of components 278 // the current namespace has. 279 std::string GetFullyQualifiedName(const std::string &name, 280 size_t max_components = 1000) const; 281 282 std::vector<std::string> components; 283 size_t from_table; // Part of the namespace corresponds to a message/table. 284 }; 285 286 inline bool operator<(const Namespace &a, const Namespace &b) { 287 size_t min_size = std::min(a.components.size(), b.components.size()); 288 for (size_t i = 0; i < min_size; ++i) { 289 if (a.components[i] != b.components[i]) 290 return a.components[i] < b.components[i]; 291 } 292 return a.components.size() < b.components.size(); 293 } 294 295 // Base class for all definition types (fields, structs_, enums_). 296 struct Definition { 297 Definition() 298 : generated(false), 299 defined_namespace(nullptr), 300 serialized_location(0), 301 index(-1), 302 refcount(1), 303 declaration_file(nullptr) {} 304 305 flatbuffers::Offset< 306 flatbuffers::Vector<flatbuffers::Offset<reflection::KeyValue>>> 307 SerializeAttributes(FlatBufferBuilder *builder, const Parser &parser) const; 308 309 bool DeserializeAttributes(Parser &parser, 310 const Vector<Offset<reflection::KeyValue>> *attrs); 311 312 std::string name; 313 std::string file; 314 std::vector<std::string> doc_comment; 315 SymbolTable<Value> attributes; 316 bool generated; // did we already output code for this definition? 317 Namespace *defined_namespace; // Where it was defined. 318 319 // For use with Serialize() 320 uoffset_t serialized_location; 321 int index; // Inside the vector it is stored. 322 int refcount; 323 const std::string *declaration_file; 324 }; 325 326 struct FieldDef : public Definition { 327 FieldDef() 328 : deprecated(false), 329 key(false), 330 shared(false), 331 native_inline(false), 332 flexbuffer(false), 333 offset64(false), 334 presence(kDefault), 335 nested_flatbuffer(nullptr), 336 padding(0), 337 sibling_union_field(nullptr) {} 338 339 Offset<reflection::Field> Serialize(FlatBufferBuilder *builder, uint16_t id, 340 const Parser &parser) const; 341 342 bool Deserialize(Parser &parser, const reflection::Field *field); 343 344 bool IsScalarOptional() const { 345 return IsScalar(value.type.base_type) && IsOptional(); 346 } 347 bool IsOptional() const { return presence == kOptional; } 348 bool IsRequired() const { return presence == kRequired; } 349 bool IsDefault() const { return presence == kDefault; } 350 351 Value value; 352 bool deprecated; // Field is allowed to be present in old data, but can't be. 353 // written in new data nor accessed in new code. 354 bool key; // Field functions as a key for creating sorted vectors. 355 bool shared; // Field will be using string pooling (i.e. CreateSharedString) 356 // as default serialization behavior if field is a string. 357 bool native_inline; // Field will be defined inline (instead of as a pointer) 358 // for native tables if field is a struct. 359 bool flexbuffer; // This field contains FlexBuffer data. 360 bool offset64; // If the field uses 64-bit offsets. 361 362 enum Presence { 363 // Field must always be present. 364 kRequired, 365 // Non-presence should be signalled to and controlled by users. 366 kOptional, 367 // Non-presence is hidden from users. 368 // Implementations may omit writing default values. 369 kDefault, 370 }; 371 Presence static MakeFieldPresence(bool optional, bool required) { 372 FLATBUFFERS_ASSERT(!(required && optional)); 373 // clang-format off 374 return required ? FieldDef::kRequired 375 : optional ? FieldDef::kOptional 376 : FieldDef::kDefault; 377 // clang-format on 378 } 379 Presence presence; 380 381 StructDef *nested_flatbuffer; // This field contains nested FlatBuffer data. 382 size_t padding; // Bytes to always pad after this field. 383 384 // sibling_union_field is always set to nullptr. The only exception is 385 // when FieldDef is a union field or an union type field. Therefore, 386 // sibling_union_field on a union field points to the union type field 387 // and vice-versa. 388 FieldDef *sibling_union_field; 389 }; 390 391 struct StructDef : public Definition { 392 StructDef() 393 : fixed(false), 394 predecl(true), 395 sortbysize(true), 396 has_key(false), 397 minalign(1), 398 bytesize(0) {} 399 400 void PadLastField(size_t min_align) { 401 auto padding = PaddingBytes(bytesize, min_align); 402 bytesize += padding; 403 if (fields.vec.size()) fields.vec.back()->padding = padding; 404 } 405 406 Offset<reflection::Object> Serialize(FlatBufferBuilder *builder, 407 const Parser &parser) const; 408 409 bool Deserialize(Parser &parser, const reflection::Object *object); 410 411 SymbolTable<FieldDef> fields; 412 413 bool fixed; // If it's struct, not a table. 414 bool predecl; // If it's used before it was defined. 415 bool sortbysize; // Whether fields come in the declaration or size order. 416 bool has_key; // It has a key field. 417 size_t minalign; // What the whole object needs to be aligned to. 418 size_t bytesize; // Size if fixed. 419 420 flatbuffers::unique_ptr<std::string> original_location; 421 std::vector<voffset_t> reserved_ids; 422 }; 423 424 struct EnumDef; 425 struct EnumValBuilder; 426 427 struct EnumVal { 428 Offset<reflection::EnumVal> Serialize(FlatBufferBuilder *builder, 429 const Parser &parser) const; 430 431 bool Deserialize(Parser &parser, const reflection::EnumVal *val); 432 433 flatbuffers::Offset< 434 flatbuffers::Vector<flatbuffers::Offset<reflection::KeyValue>>> 435 SerializeAttributes(FlatBufferBuilder *builder, const Parser &parser) const; 436 437 bool DeserializeAttributes(Parser &parser, 438 const Vector<Offset<reflection::KeyValue>> *attrs); 439 440 uint64_t GetAsUInt64() const { return static_cast<uint64_t>(value); } 441 int64_t GetAsInt64() const { return value; } 442 bool IsZero() const { return 0 == value; } 443 bool IsNonZero() const { return !IsZero(); } 444 445 std::string name; 446 std::vector<std::string> doc_comment; 447 Type union_type; 448 SymbolTable<Value> attributes; 449 450 private: 451 friend EnumDef; 452 friend EnumValBuilder; 453 friend bool operator==(const EnumVal &lhs, const EnumVal &rhs); 454 455 EnumVal(const std::string &_name, int64_t _val) : name(_name), value(_val) {} 456 EnumVal() : value(0) {} 457 458 int64_t value; 459 }; 460 461 struct EnumDef : public Definition { 462 EnumDef() : is_union(false), uses_multiple_type_instances(false) {} 463 464 Offset<reflection::Enum> Serialize(FlatBufferBuilder *builder, 465 const Parser &parser) const; 466 467 bool Deserialize(Parser &parser, const reflection::Enum *values); 468 469 template<typename T> void ChangeEnumValue(EnumVal *ev, T new_val); 470 void SortByValue(); 471 void RemoveDuplicates(); 472 473 std::string AllFlags() const; 474 const EnumVal *MinValue() const; 475 const EnumVal *MaxValue() const; 476 // Returns the number of integer steps from v1 to v2. 477 uint64_t Distance(const EnumVal *v1, const EnumVal *v2) const; 478 // Returns the number of integer steps from Min to Max. 479 uint64_t Distance() const { return Distance(MinValue(), MaxValue()); } 480 481 EnumVal *ReverseLookup(int64_t enum_idx, 482 bool skip_union_default = false) const; 483 EnumVal *FindByValue(const std::string &constant) const; 484 485 std::string ToString(const EnumVal &ev) const { 486 return IsUInt64() ? NumToString(ev.GetAsUInt64()) 487 : NumToString(ev.GetAsInt64()); 488 } 489 490 size_t size() const { return vals.vec.size(); } 491 492 const std::vector<EnumVal *> &Vals() const { return vals.vec; } 493 494 const EnumVal *Lookup(const std::string &enum_name) const { 495 return vals.Lookup(enum_name); 496 } 497 498 bool is_union; 499 // Type is a union which uses type aliases where at least one type is 500 // available under two different names. 501 bool uses_multiple_type_instances; 502 Type underlying_type; 503 504 private: 505 bool IsUInt64() const { 506 return (BASE_TYPE_ULONG == underlying_type.base_type); 507 } 508 509 friend EnumValBuilder; 510 SymbolTable<EnumVal> vals; 511 }; 512 513 inline bool IsString(const Type &type) { 514 return type.base_type == BASE_TYPE_STRING; 515 } 516 517 inline bool IsStruct(const Type &type) { 518 return type.base_type == BASE_TYPE_STRUCT && type.struct_def->fixed; 519 } 520 521 inline bool IsIncompleteStruct(const Type &type) { 522 return type.base_type == BASE_TYPE_STRUCT && type.struct_def->predecl; 523 } 524 525 inline bool IsTable(const Type &type) { 526 return type.base_type == BASE_TYPE_STRUCT && !type.struct_def->fixed; 527 } 528 529 inline bool IsUnion(const Type &type) { 530 return type.enum_def != nullptr && type.enum_def->is_union; 531 } 532 533 inline bool IsUnionType(const Type &type) { 534 return IsUnion(type) && IsInteger(type.base_type); 535 } 536 537 inline bool IsVector(const Type &type) { return IsVector(type.base_type); } 538 539 inline bool IsVectorOfStruct(const Type &type) { 540 return IsVector(type) && IsStruct(type.VectorType()); 541 } 542 543 inline bool IsVectorOfTable(const Type &type) { 544 return IsVector(type) && IsTable(type.VectorType()); 545 } 546 547 inline bool IsArray(const Type &type) { 548 return type.base_type == BASE_TYPE_ARRAY; 549 } 550 551 inline bool IsSeries(const Type &type) { 552 return IsVector(type) || IsArray(type); 553 } 554 555 inline bool IsEnum(const Type &type) { 556 return type.enum_def != nullptr && IsInteger(type.base_type); 557 } 558 559 inline size_t InlineSize(const Type &type) { 560 return IsStruct(type) 561 ? type.struct_def->bytesize 562 : (IsArray(type) 563 ? InlineSize(type.VectorType()) * type.fixed_length 564 : SizeOf(type.base_type)); 565 } 566 567 inline size_t InlineAlignment(const Type &type) { 568 if (IsStruct(type)) { 569 return type.struct_def->minalign; 570 } else if (IsArray(type)) { 571 return IsStruct(type.VectorType()) ? type.struct_def->minalign 572 : SizeOf(type.element); 573 } else { 574 return SizeOf(type.base_type); 575 } 576 } 577 inline bool operator==(const EnumVal &lhs, const EnumVal &rhs) { 578 return lhs.value == rhs.value; 579 } 580 inline bool operator!=(const EnumVal &lhs, const EnumVal &rhs) { 581 return !(lhs == rhs); 582 } 583 584 inline bool EqualByName(const Type &a, const Type &b) { 585 return a.base_type == b.base_type && a.element == b.element && 586 (a.struct_def == b.struct_def || 587 (a.struct_def != nullptr && b.struct_def != nullptr && 588 a.struct_def->name == b.struct_def->name)) && 589 (a.enum_def == b.enum_def || 590 (a.enum_def != nullptr && b.enum_def != nullptr && 591 a.enum_def->name == b.enum_def->name)); 592 } 593 594 struct RPCCall : public Definition { 595 Offset<reflection::RPCCall> Serialize(FlatBufferBuilder *builder, 596 const Parser &parser) const; 597 598 bool Deserialize(Parser &parser, const reflection::RPCCall *call); 599 600 StructDef *request, *response; 601 }; 602 603 struct ServiceDef : public Definition { 604 Offset<reflection::Service> Serialize(FlatBufferBuilder *builder, 605 const Parser &parser) const; 606 bool Deserialize(Parser &parser, const reflection::Service *service); 607 608 SymbolTable<RPCCall> calls; 609 }; 610 611 struct IncludedFile { 612 // The name of the schema file being included, as defined in the .fbs file. 613 // This includes the prefix (e.g., include "foo/bar/baz.fbs" would mean this 614 // value is "foo/bar/baz.fbs"). 615 std::string schema_name; 616 617 // The filename of where the included file was found, after searching the 618 // relative paths plus any other paths included with `flatc -I ...`. Note, 619 // while this is sometimes the same as schema_name, it is not always, since it 620 // can be defined relative to where flatc was invoked. 621 std::string filename; 622 }; 623 624 // Since IncludedFile is contained within a std::set, need to provide ordering. 625 inline bool operator<(const IncludedFile &a, const IncludedFile &b) { 626 return a.filename < b.filename; 627 } 628 629 // Container of options that may apply to any of the source/text generators. 630 struct IDLOptions { 631 // field case style options for C++ 632 enum CaseStyle { CaseStyle_Unchanged = 0, CaseStyle_Upper, CaseStyle_Lower }; 633 enum class ProtoIdGapAction { NO_OP, WARNING, ERROR }; 634 bool gen_jvmstatic; 635 // Use flexbuffers instead for binary and text generation 636 bool use_flexbuffers; 637 bool strict_json; 638 bool output_default_scalars_in_json; 639 int indent_step; 640 bool cpp_minify_enums; 641 bool output_enum_identifiers; 642 bool prefixed_enums; 643 bool scoped_enums; 644 bool emit_min_max_enum_values; 645 bool swift_implementation_only; 646 bool include_dependence_headers; 647 bool mutable_buffer; 648 bool one_file; 649 bool proto_mode; 650 bool proto_oneof_union; 651 bool generate_all; 652 bool skip_unexpected_fields_in_json; 653 bool generate_name_strings; 654 bool generate_object_based_api; 655 bool gen_compare; 656 std::string cpp_object_api_pointer_type; 657 std::string cpp_object_api_string_type; 658 bool cpp_object_api_string_flexible_constructor; 659 CaseStyle cpp_object_api_field_case_style; 660 bool cpp_direct_copy; 661 bool gen_nullable; 662 std::string java_package_prefix; 663 bool java_checkerframework; 664 bool gen_generated; 665 bool gen_json_coders; 666 std::string object_prefix; 667 std::string object_suffix; 668 bool union_value_namespacing; 669 bool allow_non_utf8; 670 bool natural_utf8; 671 std::string include_prefix; 672 bool keep_prefix; 673 bool binary_schema_comments; 674 bool binary_schema_builtins; 675 bool binary_schema_gen_embed; 676 std::string go_import; 677 std::string go_namespace; 678 std::string go_module_name; 679 bool protobuf_ascii_alike; 680 bool size_prefixed; 681 std::string root_type; 682 bool force_defaults; 683 bool java_primitive_has_method; 684 bool cs_gen_json_serializer; 685 std::vector<std::string> cpp_includes; 686 std::string cpp_std; 687 bool cpp_static_reflection; 688 std::string proto_namespace_suffix; 689 std::string filename_suffix; 690 std::string filename_extension; 691 bool no_warnings; 692 bool warnings_as_errors; 693 std::string project_root; 694 bool cs_global_alias; 695 bool json_nested_flatbuffers; 696 bool json_nested_flexbuffers; 697 bool json_nested_legacy_flatbuffers; 698 bool ts_flat_files; 699 bool ts_entry_points; 700 bool ts_no_import_ext; 701 bool no_leak_private_annotations; 702 bool require_json_eof; 703 bool keep_proto_id; 704 bool python_no_type_prefix_suffix; 705 bool python_typing; 706 ProtoIdGapAction proto_id_gap_action; 707 708 // Possible options for the more general generator below. 709 enum Language { 710 kJava = 1 << 0, 711 kCSharp = 1 << 1, 712 kGo = 1 << 2, 713 kCpp = 1 << 3, 714 kPython = 1 << 5, 715 kPhp = 1 << 6, 716 kJson = 1 << 7, 717 kBinary = 1 << 8, 718 kTs = 1 << 9, 719 kJsonSchema = 1 << 10, 720 kDart = 1 << 11, 721 kLua = 1 << 12, 722 kLobster = 1 << 13, 723 kRust = 1 << 14, 724 kKotlin = 1 << 15, 725 kSwift = 1 << 16, 726 kNim = 1 << 17, 727 kProto = 1 << 18, 728 kMAX 729 }; 730 731 enum MiniReflect { kNone, kTypes, kTypesAndNames }; 732 733 MiniReflect mini_reflect; 734 735 // If set, require all fields in a table to be explicitly numbered. 736 bool require_explicit_ids; 737 738 // If set, implement serde::Serialize for generated Rust types 739 bool rust_serialize; 740 741 // If set, generate rust types in individual files with a root module file. 742 bool rust_module_root_file; 743 744 // The corresponding language bit will be set if a language is included 745 // for code generation. 746 unsigned long lang_to_generate; 747 748 // If set (default behavior), empty string fields will be set to nullptr to 749 // make the flatbuffer more compact. 750 bool set_empty_strings_to_null; 751 752 // If set (default behavior), empty vector fields will be set to nullptr to 753 // make the flatbuffer more compact. 754 bool set_empty_vectors_to_null; 755 756 IDLOptions() 757 : gen_jvmstatic(false), 758 use_flexbuffers(false), 759 strict_json(false), 760 output_default_scalars_in_json(false), 761 indent_step(2), 762 cpp_minify_enums(false), 763 output_enum_identifiers(true), 764 prefixed_enums(true), 765 scoped_enums(false), 766 emit_min_max_enum_values(true), 767 swift_implementation_only(false), 768 include_dependence_headers(true), 769 mutable_buffer(false), 770 one_file(false), 771 proto_mode(false), 772 proto_oneof_union(false), 773 generate_all(false), 774 skip_unexpected_fields_in_json(false), 775 generate_name_strings(false), 776 generate_object_based_api(false), 777 gen_compare(false), 778 cpp_object_api_pointer_type("std::unique_ptr"), 779 cpp_object_api_string_flexible_constructor(false), 780 cpp_object_api_field_case_style(CaseStyle_Unchanged), 781 cpp_direct_copy(true), 782 gen_nullable(false), 783 java_checkerframework(false), 784 gen_generated(false), 785 gen_json_coders(false), 786 object_suffix("T"), 787 union_value_namespacing(true), 788 allow_non_utf8(false), 789 natural_utf8(false), 790 keep_prefix(false), 791 binary_schema_comments(false), 792 binary_schema_builtins(false), 793 binary_schema_gen_embed(false), 794 protobuf_ascii_alike(false), 795 size_prefixed(false), 796 force_defaults(false), 797 java_primitive_has_method(false), 798 cs_gen_json_serializer(false), 799 cpp_static_reflection(false), 800 filename_suffix("_generated"), 801 filename_extension(), 802 no_warnings(false), 803 warnings_as_errors(false), 804 project_root(""), 805 cs_global_alias(false), 806 json_nested_flatbuffers(true), 807 json_nested_flexbuffers(true), 808 json_nested_legacy_flatbuffers(false), 809 ts_flat_files(false), 810 ts_entry_points(false), 811 ts_no_import_ext(false), 812 no_leak_private_annotations(false), 813 require_json_eof(true), 814 keep_proto_id(false), 815 python_no_type_prefix_suffix(false), 816 python_typing(false), 817 proto_id_gap_action(ProtoIdGapAction::WARNING), 818 mini_reflect(IDLOptions::kNone), 819 require_explicit_ids(false), 820 rust_serialize(false), 821 rust_module_root_file(false), 822 lang_to_generate(0), 823 set_empty_strings_to_null(true), 824 set_empty_vectors_to_null(true) {} 825 }; 826 827 // This encapsulates where the parser is in the current source file. 828 struct ParserState { 829 ParserState() 830 : prev_cursor_(nullptr), 831 cursor_(nullptr), 832 line_start_(nullptr), 833 line_(0), 834 token_(-1), 835 attr_is_trivial_ascii_string_(true) {} 836 837 protected: 838 void ResetState(const char *source) { 839 prev_cursor_ = source; 840 cursor_ = source; 841 line_ = 0; 842 MarkNewLine(); 843 } 844 845 void MarkNewLine() { 846 line_start_ = cursor_; 847 line_ += 1; 848 } 849 850 int64_t CursorPosition() const { 851 FLATBUFFERS_ASSERT(cursor_ && line_start_ && cursor_ >= line_start_); 852 return static_cast<int64_t>(cursor_ - line_start_); 853 } 854 855 const char *prev_cursor_; 856 const char *cursor_; 857 const char *line_start_; 858 int line_; // the current line being parsed 859 int token_; 860 861 // Flag: text in attribute_ is true ASCII string without escape 862 // sequences. Only printable ASCII (without [\t\r\n]). 863 // Used for number-in-string (and base64 string in future). 864 bool attr_is_trivial_ascii_string_; 865 std::string attribute_; 866 std::vector<std::string> doc_comment_; 867 }; 868 869 // A way to make error propagation less error prone by requiring values to be 870 // checked. 871 // Once you create a value of this type you must either: 872 // - Call Check() on it. 873 // - Copy or assign it to another value. 874 // Failure to do so leads to an assert. 875 // This guarantees that this as return value cannot be ignored. 876 class CheckedError { 877 public: 878 explicit CheckedError(bool error) 879 : is_error_(error), has_been_checked_(false) {} 880 881 CheckedError &operator=(const CheckedError &other) { 882 is_error_ = other.is_error_; 883 has_been_checked_ = false; 884 other.has_been_checked_ = true; 885 return *this; 886 } 887 888 CheckedError(const CheckedError &other) { 889 *this = other; // Use assignment operator. 890 } 891 892 ~CheckedError() { FLATBUFFERS_ASSERT(has_been_checked_); } 893 894 bool Check() { 895 has_been_checked_ = true; 896 return is_error_; 897 } 898 899 private: 900 bool is_error_; 901 mutable bool has_been_checked_; 902 }; 903 904 // Additionally, in GCC we can get these errors statically, for additional 905 // assurance: 906 // clang-format off 907 #ifdef __GNUC__ 908 #define FLATBUFFERS_CHECKED_ERROR CheckedError \ 909 __attribute__((warn_unused_result)) 910 #else 911 #define FLATBUFFERS_CHECKED_ERROR CheckedError 912 #endif 913 // clang-format on 914 915 class Parser : public ParserState { 916 public: 917 explicit Parser(const IDLOptions &options = IDLOptions()) 918 : current_namespace_(nullptr), 919 empty_namespace_(nullptr), 920 flex_builder_(256, flexbuffers::BUILDER_FLAG_SHARE_ALL), 921 root_struct_def_(nullptr), 922 opts(options), 923 uses_flexbuffers_(false), 924 has_warning_(false), 925 advanced_features_(0), 926 source_(nullptr), 927 anonymous_counter_(0), 928 parse_depth_counter_(0) { 929 if (opts.force_defaults) { builder_.ForceDefaults(true); } 930 // Start out with the empty namespace being current. 931 empty_namespace_ = new Namespace(); 932 namespaces_.push_back(empty_namespace_); 933 current_namespace_ = empty_namespace_; 934 known_attributes_["deprecated"] = true; 935 known_attributes_["required"] = true; 936 known_attributes_["key"] = true; 937 known_attributes_["shared"] = true; 938 known_attributes_["hash"] = true; 939 known_attributes_["id"] = true; 940 known_attributes_["force_align"] = true; 941 known_attributes_["bit_flags"] = true; 942 known_attributes_["original_order"] = true; 943 known_attributes_["nested_flatbuffer"] = true; 944 known_attributes_["csharp_partial"] = true; 945 known_attributes_["streaming"] = true; 946 known_attributes_["idempotent"] = true; 947 known_attributes_["cpp_type"] = true; 948 known_attributes_["cpp_ptr_type"] = true; 949 known_attributes_["cpp_ptr_type_get"] = true; 950 known_attributes_["cpp_str_type"] = true; 951 known_attributes_["cpp_str_flex_ctor"] = true; 952 known_attributes_["native_inline"] = true; 953 known_attributes_["native_custom_alloc"] = true; 954 known_attributes_["native_type"] = true; 955 known_attributes_["native_type_pack_name"] = true; 956 known_attributes_["native_default"] = true; 957 known_attributes_["flexbuffer"] = true; 958 known_attributes_["private"] = true; 959 960 // An attribute added to a field to indicate that is uses 64-bit addressing. 961 known_attributes_["offset64"] = true; 962 963 // An attribute added to a vector field to indicate that it uses 64-bit 964 // addressing and it has a 64-bit length. 965 known_attributes_["vector64"] = true; 966 } 967 968 // Copying is not allowed 969 Parser(const Parser &) = delete; 970 Parser &operator=(const Parser &) = delete; 971 972 Parser(Parser &&) = default; 973 Parser &operator=(Parser &&) = default; 974 975 ~Parser() { 976 for (auto it = namespaces_.begin(); it != namespaces_.end(); ++it) { 977 delete *it; 978 } 979 } 980 981 // Parse the string containing either schema or JSON data, which will 982 // populate the SymbolTable's or the FlatBufferBuilder above. 983 // include_paths is used to resolve any include statements, and typically 984 // should at least include the project path (where you loaded source_ from). 985 // include_paths must be nullptr terminated if specified. 986 // If include_paths is nullptr, it will attempt to load from the current 987 // directory. 988 // If the source was loaded from a file and isn't an include file, 989 // supply its name in source_filename. 990 // All paths specified in this call must be in posix format, if you accept 991 // paths from user input, please call PosixPath on them first. 992 bool Parse(const char *_source, const char **include_paths = nullptr, 993 const char *source_filename = nullptr); 994 995 bool ParseJson(const char *json, const char *json_filename = nullptr); 996 997 // Returns the number of characters were consumed when parsing a JSON string. 998 std::ptrdiff_t BytesConsumed() const; 999 1000 // Set the root type. May override the one set in the schema. 1001 bool SetRootType(const char *name); 1002 1003 // Mark all definitions as already having code generated. 1004 void MarkGenerated(); 1005 1006 // Get the files recursively included by the given file. The returned 1007 // container will have at least the given file. 1008 std::set<std::string> GetIncludedFilesRecursive( 1009 const std::string &file_name) const; 1010 1011 // Fills builder_ with a binary version of the schema parsed. 1012 // See reflection/reflection.fbs 1013 void Serialize(); 1014 1015 // Deserialize a schema buffer 1016 bool Deserialize(const uint8_t *buf, const size_t size); 1017 1018 // Fills internal structure as if the schema passed had been loaded by parsing 1019 // with Parse except that included filenames will not be populated. 1020 bool Deserialize(const reflection::Schema *schema); 1021 1022 Type *DeserializeType(const reflection::Type *type); 1023 1024 // Checks that the schema represented by this parser is a safe evolution 1025 // of the schema provided. Returns non-empty error on any problems. 1026 std::string ConformTo(const Parser &base); 1027 1028 // Similar to Parse(), but now only accepts JSON to be parsed into a 1029 // FlexBuffer. 1030 bool ParseFlexBuffer(const char *source, const char *source_filename, 1031 flexbuffers::Builder *builder); 1032 1033 StructDef *LookupStruct(const std::string &id) const; 1034 StructDef *LookupStructThruParentNamespaces(const std::string &id) const; 1035 1036 std::string UnqualifiedName(const std::string &fullQualifiedName); 1037 1038 FLATBUFFERS_CHECKED_ERROR Error(const std::string &msg); 1039 1040 // @brief Verify that any of 'opts.lang_to_generate' supports Optional scalars 1041 // in a schema. 1042 // @param opts Options used to parce a schema and generate code. 1043 static bool SupportsOptionalScalars(const flatbuffers::IDLOptions &opts); 1044 1045 // Get the set of included files that are directly referenced by the file 1046 // being parsed. This does not include files that are transitively included by 1047 // others includes. 1048 std::vector<IncludedFile> GetIncludedFiles() const; 1049 1050 private: 1051 class ParseDepthGuard; 1052 1053 void Message(const std::string &msg); 1054 void Warning(const std::string &msg); 1055 FLATBUFFERS_CHECKED_ERROR ParseHexNum(int nibbles, uint64_t *val); 1056 FLATBUFFERS_CHECKED_ERROR Next(); 1057 FLATBUFFERS_CHECKED_ERROR SkipByteOrderMark(); 1058 bool Is(int t) const; 1059 bool IsIdent(const char *id) const; 1060 FLATBUFFERS_CHECKED_ERROR Expect(int t); 1061 std::string TokenToStringId(int t) const; 1062 EnumDef *LookupEnum(const std::string &id); 1063 FLATBUFFERS_CHECKED_ERROR ParseNamespacing(std::string *id, 1064 std::string *last); 1065 FLATBUFFERS_CHECKED_ERROR ParseTypeIdent(Type &type); 1066 FLATBUFFERS_CHECKED_ERROR ParseType(Type &type); 1067 FLATBUFFERS_CHECKED_ERROR AddField(StructDef &struct_def, 1068 const std::string &name, const Type &type, 1069 FieldDef **dest); 1070 FLATBUFFERS_CHECKED_ERROR ParseField(StructDef &struct_def); 1071 FLATBUFFERS_CHECKED_ERROR ParseString(Value &val, bool use_string_pooling); 1072 FLATBUFFERS_CHECKED_ERROR ParseComma(); 1073 FLATBUFFERS_CHECKED_ERROR ParseAnyValue(Value &val, FieldDef *field, 1074 size_t parent_fieldn, 1075 const StructDef *parent_struct_def, 1076 size_t count, 1077 bool inside_vector = false); 1078 template<typename F> 1079 FLATBUFFERS_CHECKED_ERROR ParseTableDelimiters(size_t &fieldn, 1080 const StructDef *struct_def, 1081 F body); 1082 FLATBUFFERS_CHECKED_ERROR ParseTable(const StructDef &struct_def, 1083 std::string *value, uoffset_t *ovalue); 1084 void SerializeStruct(const StructDef &struct_def, const Value &val); 1085 void SerializeStruct(FlatBufferBuilder &builder, const StructDef &struct_def, 1086 const Value &val); 1087 template<typename F> 1088 FLATBUFFERS_CHECKED_ERROR ParseVectorDelimiters(size_t &count, F body); 1089 FLATBUFFERS_CHECKED_ERROR ParseVector(const Type &type, uoffset_t *ovalue, 1090 FieldDef *field, size_t fieldn); 1091 FLATBUFFERS_CHECKED_ERROR ParseArray(Value &array); 1092 FLATBUFFERS_CHECKED_ERROR ParseNestedFlatbuffer( 1093 Value &val, FieldDef *field, size_t fieldn, 1094 const StructDef *parent_struct_def); 1095 FLATBUFFERS_CHECKED_ERROR ParseMetaData(SymbolTable<Value> *attributes); 1096 FLATBUFFERS_CHECKED_ERROR TryTypedValue(const std::string *name, int dtoken, 1097 bool check, Value &e, BaseType req, 1098 bool *destmatch); 1099 FLATBUFFERS_CHECKED_ERROR ParseHash(Value &e, FieldDef *field); 1100 FLATBUFFERS_CHECKED_ERROR TokenError(); 1101 FLATBUFFERS_CHECKED_ERROR ParseSingleValue(const std::string *name, Value &e, 1102 bool check_now); 1103 FLATBUFFERS_CHECKED_ERROR ParseFunction(const std::string *name, Value &e); 1104 FLATBUFFERS_CHECKED_ERROR ParseEnumFromString(const Type &type, 1105 std::string *result); 1106 StructDef *LookupCreateStruct(const std::string &name, 1107 bool create_if_new = true, 1108 bool definition = false); 1109 FLATBUFFERS_CHECKED_ERROR ParseEnum(bool is_union, EnumDef **dest, 1110 const char *filename); 1111 FLATBUFFERS_CHECKED_ERROR ParseNamespace(); 1112 FLATBUFFERS_CHECKED_ERROR StartStruct(const std::string &name, 1113 StructDef **dest); 1114 FLATBUFFERS_CHECKED_ERROR StartEnum(const std::string &name, bool is_union, 1115 EnumDef **dest); 1116 FLATBUFFERS_CHECKED_ERROR ParseDecl(const char *filename); 1117 FLATBUFFERS_CHECKED_ERROR ParseService(const char *filename); 1118 FLATBUFFERS_CHECKED_ERROR ParseProtoFields(StructDef *struct_def, 1119 bool isextend, bool inside_oneof); 1120 FLATBUFFERS_CHECKED_ERROR ParseProtoMapField(StructDef *struct_def); 1121 FLATBUFFERS_CHECKED_ERROR ParseProtoOption(); 1122 FLATBUFFERS_CHECKED_ERROR ParseProtoKey(); 1123 FLATBUFFERS_CHECKED_ERROR ParseProtoDecl(); 1124 FLATBUFFERS_CHECKED_ERROR ParseProtoCurliesOrIdent(); 1125 FLATBUFFERS_CHECKED_ERROR ParseTypeFromProtoType(Type *type); 1126 FLATBUFFERS_CHECKED_ERROR SkipAnyJsonValue(); 1127 FLATBUFFERS_CHECKED_ERROR ParseFlexBufferNumericConstant( 1128 flexbuffers::Builder *builder); 1129 FLATBUFFERS_CHECKED_ERROR ParseFlexBufferValue(flexbuffers::Builder *builder); 1130 FLATBUFFERS_CHECKED_ERROR StartParseFile(const char *source, 1131 const char *source_filename); 1132 FLATBUFFERS_CHECKED_ERROR ParseRoot(const char *_source, 1133 const char **include_paths, 1134 const char *source_filename); 1135 FLATBUFFERS_CHECKED_ERROR CheckPrivateLeak(); 1136 FLATBUFFERS_CHECKED_ERROR CheckPrivatelyLeakedFields( 1137 const Definition &def, const Definition &value_type); 1138 FLATBUFFERS_CHECKED_ERROR DoParse(const char *_source, 1139 const char **include_paths, 1140 const char *source_filename, 1141 const char *include_filename); 1142 FLATBUFFERS_CHECKED_ERROR DoParseJson(); 1143 FLATBUFFERS_CHECKED_ERROR CheckClash(std::vector<FieldDef *> &fields, 1144 StructDef *struct_def, 1145 const char *suffix, BaseType baseType); 1146 FLATBUFFERS_CHECKED_ERROR ParseAlignAttribute( 1147 const std::string &align_constant, size_t min_align, size_t *align); 1148 1149 bool SupportsAdvancedUnionFeatures() const; 1150 bool SupportsAdvancedArrayFeatures() const; 1151 bool SupportsOptionalScalars() const; 1152 bool SupportsDefaultVectorsAndStrings() const; 1153 bool Supports64BitOffsets() const; 1154 bool SupportsUnionUnderlyingType() const; 1155 Namespace *UniqueNamespace(Namespace *ns); 1156 1157 FLATBUFFERS_CHECKED_ERROR RecurseError(); 1158 template<typename F> CheckedError Recurse(F f); 1159 1160 const std::string &GetPooledString(const std::string &s) const; 1161 1162 public: 1163 SymbolTable<Type> types_; 1164 SymbolTable<StructDef> structs_; 1165 SymbolTable<EnumDef> enums_; 1166 SymbolTable<ServiceDef> services_; 1167 std::vector<Namespace *> namespaces_; 1168 Namespace *current_namespace_; 1169 Namespace *empty_namespace_; 1170 std::string error_; // User readable error_ if Parse() == false 1171 1172 FlatBufferBuilder builder_; // any data contained in the file 1173 flexbuffers::Builder flex_builder_; 1174 flexbuffers::Reference flex_root_; 1175 StructDef *root_struct_def_; 1176 std::string file_identifier_; 1177 std::string file_extension_; 1178 1179 std::map<uint64_t, std::string> included_files_; 1180 std::map<std::string, std::set<IncludedFile>> files_included_per_file_; 1181 std::vector<std::string> native_included_files_; 1182 1183 std::map<std::string, bool> known_attributes_; 1184 1185 IDLOptions opts; 1186 bool uses_flexbuffers_; 1187 bool has_warning_; 1188 1189 uint64_t advanced_features_; 1190 1191 std::string file_being_parsed_; 1192 1193 private: 1194 const char *source_; 1195 1196 std::vector<std::pair<Value, FieldDef *>> field_stack_; 1197 1198 // TODO(cneo): Refactor parser to use string_cache more often to save 1199 // on memory usage. 1200 mutable std::set<std::string> string_cache_; 1201 1202 int anonymous_counter_; 1203 int parse_depth_counter_; // stack-overflow guard 1204 }; 1205 1206 // Utility functions for multiple generators: 1207 1208 // Generate text (JSON) from a given FlatBuffer, and a given Parser 1209 // object that has been populated with the corresponding schema. 1210 // If ident_step is 0, no indentation will be generated. Additionally, 1211 // if it is less than 0, no linefeeds will be generated either. 1212 // See idl_gen_text.cpp. 1213 // strict_json adds "quotes" around field names if true. 1214 // These functions return nullptr on success, or an error string, 1215 // which may happen if the flatbuffer cannot be encoded in JSON (e.g., 1216 // it contains non-UTF-8 byte arrays in String values). 1217 extern const char *GenTextFromTable(const Parser &parser, const void *table, 1218 const std::string &tablename, 1219 std::string *text); 1220 extern const char *GenText(const Parser &parser, const void *flatbuffer, 1221 std::string *text); 1222 extern const char *GenTextFile(const Parser &parser, const std::string &path, 1223 const std::string &file_name); 1224 1225 // Generate GRPC Cpp interfaces. 1226 // See idl_gen_grpc.cpp. 1227 bool GenerateCppGRPC(const Parser &parser, const std::string &path, 1228 const std::string &file_name); 1229 1230 // Generate GRPC Go interfaces. 1231 // See idl_gen_grpc.cpp. 1232 bool GenerateGoGRPC(const Parser &parser, const std::string &path, 1233 const std::string &file_name); 1234 1235 // Generate GRPC Java classes. 1236 // See idl_gen_grpc.cpp 1237 bool GenerateJavaGRPC(const Parser &parser, const std::string &path, 1238 const std::string &file_name); 1239 1240 // Generate GRPC Python interfaces. 1241 // See idl_gen_grpc.cpp. 1242 bool GeneratePythonGRPC(const Parser &parser, const std::string &path, 1243 const std::string &file_name); 1244 1245 // Generate GRPC Swift interfaces. 1246 // See idl_gen_grpc.cpp. 1247 extern bool GenerateSwiftGRPC(const Parser &parser, const std::string &path, 1248 const std::string &file_name); 1249 1250 extern bool GenerateTSGRPC(const Parser &parser, const std::string &path, 1251 const std::string &file_name); 1252 } // namespace flatbuffers 1253 1254 #endif // FLATBUFFERS_IDL_H_