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