Branch data Line data Source code
1 : : /* Flatbuffers parser attributes and symbols. */
2 : :
3 : : #ifndef SYMBOLS_H
4 : : #define SYMBOLS_H
5 : :
6 : : #include <stdint.h>
7 : :
8 : : #include "config.h"
9 : : #include "lex/tokens.h"
10 : : #include "hash/hash_table.h"
11 : : #include "hash/ptr_set.h"
12 : :
13 : : typedef struct fb_token fb_token_t;
14 : : typedef struct fb_string fb_string_t;
15 : : typedef struct fb_value fb_value_t;
16 : : typedef struct fb_symbol fb_symbol_t;
17 : :
18 : : typedef struct fb_metadata fb_metadata_t;
19 : :
20 : : typedef struct fb_name fb_name_t;
21 : : typedef fb_symbol_t fb_namespace_t;
22 : : typedef fb_symbol_t fb_ref_t;
23 : : /* Doc is not strictly a symbol, just a chained token list, but close enough. */
24 : : typedef fb_symbol_t fb_doc_t;
25 : : typedef fb_name_t fb_include_t;
26 : : typedef struct fb_attribute fb_attribute_t;
27 : :
28 : : typedef struct fb_member fb_member_t;
29 : : typedef struct fb_compound_type fb_compound_type_t;
30 : :
31 : : typedef struct fb_scope fb_scope_t;
32 : : typedef struct fb_root_schema fb_root_schema_t;
33 : : typedef struct fb_root_type fb_root_type_t;
34 : : typedef struct fb_schema fb_schema_t;
35 : :
36 : : enum {
37 : : tok_kw_base = LEX_TOK_KW_BASE,
38 : : tok_kw_int,
39 : : tok_kw_bool,
40 : : tok_kw_byte,
41 : : tok_kw_enum,
42 : : tok_kw_long,
43 : : tok_kw_true,
44 : : tok_kw_uint,
45 : : tok_kw_false,
46 : : tok_kw_float,
47 : : tok_kw_short,
48 : : tok_kw_table,
49 : : tok_kw_ubyte,
50 : : tok_kw_ulong,
51 : : tok_kw_union,
52 : : tok_kw_double,
53 : : tok_kw_string,
54 : : tok_kw_struct,
55 : : tok_kw_ushort,
56 : : tok_kw_include,
57 : : tok_kw_attribute,
58 : : tok_kw_namespace,
59 : : tok_kw_root_type,
60 : : tok_kw_rpc_service,
61 : : tok_kw_file_extension,
62 : : tok_kw_file_identifier,
63 : : /* Pseudo keywords. */
64 : : tok_kw_doc_comment
65 : : };
66 : :
67 : : struct fb_token {
68 : : const char *text;
69 : : long len;
70 : : long linenum;
71 : : long pos;
72 : : long id;
73 : : };
74 : :
75 : : enum fb_scalar_type {
76 : : fb_missing_type = 0,
77 : : fb_ulong,
78 : : fb_uint,
79 : : fb_ushort,
80 : : fb_ubyte,
81 : : fb_bool,
82 : : fb_long,
83 : : fb_int,
84 : : fb_short,
85 : : fb_byte,
86 : : fb_double,
87 : : fb_float,
88 : : };
89 : :
90 : : typedef enum fb_scalar_type fb_scalar_type_t;
91 : :
92 : : enum fb_value_type {
93 : : vt_missing = 0,
94 : : vt_invalid = 1,
95 : : vt_string,
96 : : vt_float,
97 : : vt_int,
98 : : vt_uint,
99 : : vt_bool,
100 : : vt_vector_type,
101 : : vt_scalar_type,
102 : : vt_vector_string_type,
103 : : vt_string_type,
104 : : vt_vector_type_ref,
105 : : vt_type_ref,
106 : : vt_name_ref,
107 : : vt_compound_type_ref,
108 : : vt_vector_compound_type_ref
109 : : };
110 : :
111 : : struct fb_string {
112 : : char *s;
113 : : /* printf statements relies on this being int. */
114 : : int len;
115 : : };
116 : :
117 : : struct fb_value {
118 : : union {
119 : : fb_string_t s;
120 : : double f;
121 : : int64_t i;
122 : : uint64_t u;
123 : : uint8_t b;
124 : : fb_token_t *t;
125 : : fb_compound_type_t *ct;
126 : : fb_scalar_type_t st;
127 : : fb_ref_t *ref;
128 : : };
129 : : unsigned short type;
130 : : };
131 : :
132 : : enum fb_kind {
133 : : fb_is_table,
134 : : fb_is_struct,
135 : : fb_is_rpc_service,
136 : : fb_is_enum,
137 : : fb_is_union,
138 : : fb_is_member
139 : : };
140 : :
141 : : /*
142 : : * Used for white, gray, black graph coloring while detecting circular
143 : : * references.
144 : : */
145 : : enum fb_symbol_flags {
146 : : fb_circular_open = 1,
147 : : fb_circular_closed = 2,
148 : : fb_duplicate = 4,
149 : : fb_indexed = 8,
150 : : };
151 : :
152 : : /*
153 : : * We keep the link first in all structs so that we can use a
154 : : * generic list reverse function after all symbols have been pushed
155 : : * within a scope.
156 : : */
157 : : struct fb_symbol {
158 : : fb_symbol_t *link;
159 : : fb_token_t *ident;
160 : : uint16_t kind;
161 : : uint16_t flags;
162 : : };
163 : :
164 : : struct fb_name {
165 : : fb_name_t *link;
166 : : fb_value_t name;
167 : : };
168 : :
169 : : #define fb_name_table __flatcc_fb_name_table
170 : : #define fb_value_set __flatcc_fb_value_set
171 : : #define fb_symbol_table __flatcc_fb_symbol_table
172 : : #define fb_scope_table __flatcc_fb_scope_table
173 : :
174 : : DECLARE_HASH_TABLE(fb_name_table, fb_name_t *)
175 : : DECLARE_HASH_TABLE(fb_schema_table, fb_schema_t *)
176 : : DECLARE_HASH_TABLE(fb_value_set, fb_value_t *)
177 : : DECLARE_HASH_TABLE(fb_symbol_table, fb_symbol_t *)
178 : : DECLARE_HASH_TABLE(fb_scope_table, fb_scope_t *)
179 : :
180 : : struct fb_member {
181 : : fb_symbol_t symbol;
182 : : /* Struct or table field type, or method response type. */
183 : : fb_value_t type;
184 : : /* Method request type only used for methods. */
185 : : fb_value_t req_type;
186 : : fb_value_t value;
187 : : fb_metadata_t *metadata;
188 : : fb_doc_t *doc;
189 : : uint16_t metadata_flags;
190 : : /*
191 : : * `align`, `offset` are for structs only. 64-bit allows for
192 : : * dynamically configured 64-bit file offsets. Align is restricted to
193 : : * at most 256 and must be a power of 2.
194 : : */
195 : : uint16_t align;
196 : : uint64_t offset;
197 : : uint64_t size;
198 : :
199 : : /* `id` is for table fields only. */
200 : : uint64_t id;
201 : : /*
202 : : * Resolved `nested_flatbuffer` attribute type. Always a table if
203 : : * set, and only on struct and table fields.
204 : : */
205 : : fb_compound_type_t *nest;
206 : : /* Used to generate table fields in sorted order. */
207 : : fb_member_t *order;
208 : :
209 : : /*
210 : : * Use by code generators. Only valid during export and may hold
211 : : * garbage from a prevous export.
212 : : */
213 : : size_t export_index;
214 : : };
215 : :
216 : : struct fb_metadata {
217 : : fb_metadata_t *link;
218 : : fb_token_t *ident;
219 : : fb_value_t value;
220 : : };
221 : :
222 : : struct fb_compound_type {
223 : : fb_symbol_t symbol;
224 : : /* `scope` may span multiple input files, but has a unique namespace. */
225 : : fb_scope_t *scope;
226 : : /* Identifies the the schema the symbol belongs. */
227 : : fb_schema_t *schema;
228 : : fb_symbol_t *members;
229 : : fb_member_t *ordered_members;
230 : : fb_metadata_t *metadata;
231 : : fb_doc_t *doc;
232 : : fb_value_t type;
233 : : fb_symbol_table_t index;
234 : : /* Only for enums. */
235 : : fb_value_set_t value_set;
236 : : /* FNV-1a 32 bit hash of fully qualified name, accidental 0 maps to hash(""). */
237 : : uint32_t type_hash;
238 : : uint16_t metadata_flags;
239 : : /* `count` is for tables only. */
240 : : uint64_t count;
241 : : /* `align`, `size` is for structs only. */
242 : : uint16_t align;
243 : : uint64_t size;
244 : : /* Sort structs with forward references. */
245 : : fb_compound_type_t *order;
246 : : /*
247 : : * Use by code generators. Only valid during export and may hold
248 : : * garbage from a prevous export.
249 : : */
250 : : size_t export_index;
251 : : };
252 : :
253 : : enum fb_known_attributes {
254 : : fb_attr_unknown = 0,
255 : : fb_attr_id = 1,
256 : : fb_attr_deprecated = 2,
257 : : fb_attr_original_order = 3,
258 : : fb_attr_force_align = 4,
259 : : fb_attr_bit_flags = 5,
260 : : fb_attr_nested_flatbuffer = 6,
261 : : fb_attr_key = 7,
262 : : fb_attr_required = 8,
263 : : fb_attr_hash = 9,
264 : : KNOWN_ATTR_COUNT
265 : : };
266 : :
267 : : enum fb_known_attribute_flags {
268 : : fb_f_unknown = 1 << fb_attr_unknown,
269 : : fb_f_id = 1 << fb_attr_id,
270 : : fb_f_deprecated = 1 << fb_attr_deprecated,
271 : : fb_f_original_order = 1 << fb_attr_original_order,
272 : : fb_f_force_align = 1 << fb_attr_force_align,
273 : : fb_f_bit_flags = 1 << fb_attr_bit_flags,
274 : : fb_f_nested_flatbuffer = 1 << fb_attr_nested_flatbuffer,
275 : : fb_f_key = 1 << fb_attr_key,
276 : : fb_f_required = 1 << fb_attr_required,
277 : : fb_f_hash = 1 << fb_attr_hash
278 : : };
279 : :
280 : : struct fb_attribute {
281 : : fb_name_t name;
282 : : unsigned int known;
283 : : };
284 : :
285 : : struct fb_scope {
286 : : fb_ref_t *name;
287 : : fb_symbol_table_t symbol_index;
288 : : fb_string_t prefix;
289 : : };
290 : :
291 : : struct fb_root_schema {
292 : : fb_scope_table_t scope_index;
293 : : fb_name_table_t attribute_index;
294 : : fb_schema_table_t include_index;
295 : : int include_count;
296 : : int include_depth;
297 : : size_t total_source_size;
298 : : };
299 : :
300 : : struct fb_root_type {
301 : : /* Root decl. before symbol is visible. */
302 : : fb_ref_t *name;
303 : : /* Resolved symbol. */
304 : : fb_symbol_t *type;
305 : : fb_scope_t *scope;
306 : : };
307 : :
308 : : /*
309 : : * We store the parsed structure as token references. Tokens are stored
310 : : * in a single array pointing into the source buffer.
311 : : *
312 : : * Strings may contain multiple tokens when holding control characters
313 : : * and line breaks, but for our purposes the first string part is
314 : : * sufficient.
315 : : */
316 : :
317 : : struct fb_schema {
318 : : fb_include_t *includes;
319 : : fb_name_t *attributes;
320 : : fb_value_t file_identifier;
321 : : fb_value_t file_extension;
322 : : fb_symbol_t *symbols;
323 : : /* Topologically sorted structs. */
324 : : fb_compound_type_t *ordered_structs;
325 : : fb_root_type_t root_type;
326 : : fb_root_schema_t *root_schema;
327 : : /* Only used if schema is root. */
328 : : fb_root_schema_t root_schema_instance;
329 : :
330 : : /* An optional scope prefix for generated code. */
331 : : fb_string_t prefix;
332 : :
333 : : /* The basenameup in a format that can be index. */
334 : : fb_name_t name;
335 : :
336 : : /* These are allocated strings that must be freed. */
337 : :
338 : : /* Name of schema being processed without path or default extension. */
339 : : char *basename;
340 : : /* Uppercase basename for codegen and for case insenstive file inclusion check. */
341 : : char *basenameup;
342 : : /* Basename with extension. */
343 : : char *errorname;
344 : :
345 : : /*
346 : : * The dependency schemas visible to this schema (includes self).
347 : : * Compound symbols have a link to schema which can be checked
348 : : * against this set to see if the symbol is visible in this
349 : : * conctext.
350 : : */
351 : : ptr_set_t visible_schema;
352 : : };
353 : :
354 : : /*
355 : : * Helpers to ensure a symbol is actually visible because a scope
356 : : * (namespace) may be extended when a parent inlcudes another file
357 : : * first.
358 : : */
359 : : static inline fb_compound_type_t *get_enum_if_visible(fb_schema_t *schema, fb_symbol_t *sym)
360 : : {
361 : : fb_compound_type_t *ct = 0;
362 : :
363 [ + + ][ + + ]: 67 : switch (sym->kind) {
364 : : case fb_is_enum:
365 : : ct = (fb_compound_type_t *)sym;
366 [ - + ][ + + ]: 14 : if (!ptr_set_exists(&schema->visible_schema, ct->schema)) {
367 : : ct = 0;
368 : : }
369 : : break;
370 : : default:
371 : : break;
372 : : }
373 : : return ct;
374 : : }
375 : :
376 : : static inline fb_compound_type_t *get_compound_if_visible(fb_schema_t *schema, fb_symbol_t *sym)
377 : : {
378 : : fb_compound_type_t *ct = 0;
379 : :
380 [ + - ][ + - ]: 387 : switch (sym->kind) {
381 : : case fb_is_struct:
382 : : case fb_is_table:
383 : : case fb_is_rpc_service:
384 : : case fb_is_union:
385 : : case fb_is_enum:
386 : : ct = (fb_compound_type_t *)sym;
387 [ + + ][ + + ]: 387 : if (!ptr_set_exists(&schema->visible_schema, ct->schema)) {
388 : : ct = 0;
389 : : }
390 : : break;
391 : : default:
392 : : break;
393 : : }
394 : : return ct;
395 : : }
396 : :
397 : : /* Constants are specific to 32-bit FNV-1a hash. It is important to use unsigned integers. */
398 : : static inline uint32_t fb_hash_fnv1a_32_init()
399 : : {
400 : : return 2166136261UL;
401 : : }
402 : :
403 : : static inline uint32_t fb_hash_fnv1a_32_append(uint32_t hash, const char *data, size_t len)
404 : : {
405 [ + + ][ + + ]: 4396 : while (len--) {
[ + + ]
406 : 3917 : hash ^= *(uint8_t *)data++;
407 : 3917 : hash = hash * 16777619UL;
408 : : }
409 : : return hash;
410 : : }
411 : :
412 : : #endif /* SYMBOLS_H */
|