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