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