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