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