semantics.c (72098B)
1 #include <string.h> 2 #include <assert.h> 3 4 #include "semantics.h" 5 #include "parser.h" 6 #include "coerce.h" 7 #include "stdio.h" 8 9 /* -DFLATCC_PORTABLE may help if inttypes.h is missing. */ 10 #ifndef PRId64 11 #include <inttypes.h> 12 #endif 13 14 /* Same order as enum! */ 15 static const char *fb_known_attribute_names[] = { 16 "", 17 "id", 18 "deprecated", 19 "original_order", 20 "force_align", 21 "bit_flags", 22 "nested_flatbuffer", 23 "key", 24 "required", 25 "hash", 26 "base64", 27 "base64url", 28 "primary_key", 29 "sorted", 30 }; 31 32 static const int fb_known_attribute_types[] = { 33 vt_invalid, /* Unknowns have arbitrary types. */ 34 vt_uint, 35 vt_missing, 36 vt_missing, 37 vt_uint, 38 vt_missing, 39 vt_string, 40 vt_missing, 41 vt_missing, 42 vt_string, 43 vt_missing, 44 vt_missing, 45 vt_missing, 46 vt_missing, 47 }; 48 49 static fb_scalar_type_t map_scalar_token_type(fb_token_t *t) 50 { 51 switch (t->id) { 52 case tok_kw_uint64: 53 case tok_kw_ulong: 54 return fb_ulong; 55 case tok_kw_uint32: 56 case tok_kw_uint: 57 return fb_uint; 58 case tok_kw_uint16: 59 case tok_kw_ushort: 60 return fb_ushort; 61 case tok_kw_uint8: 62 case tok_kw_ubyte: 63 return fb_ubyte; 64 case tok_kw_char: 65 return fb_char; 66 case tok_kw_bool: 67 return fb_bool; 68 case tok_kw_int64: 69 case tok_kw_long: 70 return fb_long; 71 case tok_kw_int32: 72 case tok_kw_int: 73 return fb_int; 74 case tok_kw_int16: 75 case tok_kw_short: 76 return fb_short; 77 case tok_kw_int8: 78 case tok_kw_byte: 79 return fb_byte; 80 case tok_kw_float64: 81 case tok_kw_double: 82 return fb_double; 83 case tok_kw_float32: 84 case tok_kw_float: 85 return fb_float; 86 default: 87 return fb_missing_type; 88 } 89 } 90 91 /* 92 * The flatc compiler currently has a 256 limit. 93 * 94 * Some target C compilers might respect anything above 95 * 16 and may reguire that PAD option of the C code generator. 96 */ 97 static inline int is_valid_align(uint64_t align) 98 { 99 uint64_t n = 1; 100 if (align == 0 || align > FLATCC_FORCE_ALIGN_MAX) { 101 return 0; 102 } 103 while (n <= align) { 104 if (n == align) { 105 return 1; 106 } 107 n *= 2; 108 } 109 return 0; 110 } 111 112 static inline uint64_t fb_align(uint64_t size, uint64_t align) 113 { 114 assert(is_valid_align(align)); 115 116 return (size + align - 1) & ~(align - 1); 117 } 118 119 /* 120 * The FNV-1a 32-bit little endian hash is a FlatBuffers standard for 121 * transmission of type identifiers in a compact form, in particular as 122 * alternative file identifiers. Note that if hash becomes 0, we map it 123 * to hash(""). 124 */ 125 static inline void set_type_hash(fb_compound_type_t *ct) 126 { 127 fb_ref_t *name; 128 fb_symbol_t *sym; 129 uint32_t hash; 130 131 hash = fb_hash_fnv1a_32_init(); 132 if (ct->scope) { 133 for (name = ct->scope->name; name; name = name->link) { 134 hash = fb_hash_fnv1a_32_append(hash, name->ident->text, (size_t)name->ident->len); 135 hash = fb_hash_fnv1a_32_append(hash, ".", 1); 136 } 137 } 138 sym = &ct->symbol; 139 hash = fb_hash_fnv1a_32_append(hash, sym->ident->text, (size_t)sym->ident->len); 140 if (hash == 0) { 141 hash = fb_hash_fnv1a_32_init(); 142 } 143 ct->type_hash = hash; 144 } 145 146 static inline fb_scope_t *fb_find_scope_by_string(fb_schema_t *S, const char *name, size_t len) 147 { 148 if (!S || !S->root_schema) { 149 return 0; 150 } 151 if (len == 0) { 152 /* Global scope. */ 153 name = 0; 154 } 155 return fb_scope_table_find(&S->root_schema->scope_index, name, len); 156 } 157 158 /* count = 0 indicates zero-terminated ref list, name = 0 indicates global scope. */ 159 static inline fb_scope_t *fb_find_scope_by_ref(fb_schema_t *S, const fb_ref_t *name, int count) 160 { 161 if (!S || !S->root_schema) { 162 return 0; 163 } 164 return fb_scope_table_find(&S->root_schema->scope_index, name, (size_t)(-count)); 165 } 166 167 static inline fb_symbol_t *define_fb_symbol(fb_symbol_table_t *si, fb_symbol_t *sym) 168 { 169 return fb_symbol_table_insert_item(si, sym, ht_keep); 170 } 171 172 static inline fb_symbol_t *find_fb_symbol_by_token(fb_symbol_table_t *si, fb_token_t *token) 173 { 174 return fb_symbol_table_find(si, token->text, (size_t)token->len); 175 } 176 177 static inline fb_name_t *define_fb_name(fb_name_table_t *ni, fb_name_t *name) 178 { 179 return fb_name_table_insert_item(ni, name, ht_keep); 180 } 181 182 static inline fb_name_t *find_fb_name_by_token(fb_name_table_t *ni, fb_token_t *token) 183 { 184 return fb_name_table_find(ni, token->text, (size_t)token->len); 185 } 186 187 /* Returns 1 if value exists, 0 otherwise, */ 188 static inline int add_to_value_set(fb_value_set_t *vs, fb_value_t *value) 189 { 190 return fb_value_set_insert_item(vs, value, ht_keep) != 0; 191 } 192 193 static inline int is_in_value_set(fb_value_set_t *vs, fb_value_t *value) 194 { 195 return 0 != fb_value_set_find_item(vs, value); 196 } 197 198 /* 199 * An immediate parent scope does not necessarily exist and it might 200 * appear in a later search, so we return the nearest existing parent 201 * and do not cache the parent. 202 */ 203 static inline fb_scope_t *find_parent_scope(fb_parser_t *P, fb_scope_t *scope) 204 { 205 fb_ref_t *p; 206 int count; 207 fb_scope_t *parent; 208 209 parent = 0; 210 count = 0; 211 if (scope == 0) { 212 return 0; 213 } 214 p = scope->name; 215 while (p) { 216 ++count; 217 p = p->link; 218 } 219 if (count == 0) { 220 return 0; 221 } 222 while (count-- > 1) { 223 if ((parent = fb_find_scope_by_ref(&P->schema, scope->name, count))) { 224 return parent; 225 } 226 } 227 /* Root scope. */ 228 return fb_find_scope_by_ref(&P->schema, 0, 0); 229 } 230 231 static inline fb_symbol_t *lookup_string_reference(fb_parser_t *P, fb_scope_t *local, const char *s, size_t len) 232 { 233 fb_symbol_t *sym; 234 fb_scope_t *scope; 235 const char *name, *basename; 236 size_t k; 237 238 name = s; 239 basename = s; 240 k = len; 241 while (k > 0) { 242 if (s[--k] == '.') { 243 basename = s + k + 1; 244 --len; 245 break; 246 } 247 } 248 len -= k; 249 if (local && k == 0) { 250 do { 251 if ((sym = fb_symbol_table_find(&local->symbol_index, basename, len))) { 252 if (get_compound_if_visible(&P->schema, sym)) { 253 return sym; 254 } 255 } 256 local = find_parent_scope(P, local); 257 } while (local); 258 return 0; 259 } 260 if (!(scope = fb_find_scope_by_string(&P->schema, name, k))) { 261 return 0; 262 } 263 return fb_symbol_table_find(&scope->symbol_index, basename, len); 264 } 265 266 /* 267 * First search the optional local scope, then the scope of the namespace prefix if any. 268 * If `enumval` is non-zero, the last namepart is stored in that 269 * pointer and the lookup stops before that part. 270 * 271 * If the reference is prefixed with a namespace then the scope is 272 * looked up relative to root then the basename is searched in that 273 * scope. 274 * 275 * If the refernce is not prefixed with a namespace then the name is 276 * search in the local symbol table (which may be the root if null) and 277 * if that fails, the nearest existing parent scope is used as the new 278 * local scope and the process is repeated until local is root. 279 * 280 * This means that namespace prefixes cannot be relative to a parent 281 * namespace or to the current scope, but simple names can be found in a 282 * parent namespace. 283 */ 284 static inline fb_symbol_t *lookup_reference(fb_parser_t *P, fb_scope_t *local, fb_ref_t *name, fb_ref_t **enumval) 285 { 286 fb_ref_t *basename, *last, *p; 287 fb_scope_t *scope; 288 fb_symbol_t *sym; 289 int count; 290 291 count = 0; 292 scope = 0; 293 p = name; 294 last = 0; 295 basename = 0; 296 while (p) { 297 basename = last; 298 last = p; 299 p = p->link; 300 ++count; 301 } 302 if (enumval) { 303 --count; 304 *enumval = last; 305 } else { 306 basename = last; 307 } 308 if (!basename) { 309 return 0; 310 } 311 if (local && count == 1) { 312 do { 313 if ((sym = find_fb_symbol_by_token(&local->symbol_index, basename->ident))) { 314 if (get_compound_if_visible(&P->schema, sym)) { 315 return sym; 316 } 317 } 318 local = find_parent_scope(P, local); 319 } while (local); 320 return 0; 321 } 322 /* Null name is valid in scope lookup, indicating global scope. */ 323 if (count == 1) { 324 name = 0; 325 } 326 if (!(scope = fb_find_scope_by_ref(&P->schema, name, count - 1))) { 327 return 0; 328 } 329 sym = find_fb_symbol_by_token(&scope->symbol_index, basename->ident); 330 if (sym && get_compound_if_visible(&P->schema, sym)) { 331 return sym; 332 } 333 return 0; 334 } 335 336 static inline fb_symbol_t *lookup_type_reference(fb_parser_t *P, fb_scope_t *local, fb_ref_t *name) 337 { 338 return lookup_reference(P, local, name, 0); 339 } 340 341 /* 342 * `ct` is null when looking up names for scalar types and otherwise it is 343 * the enum type being assigned. The provided reference may reference 344 * an enum value in the `ct` type, or another enum if a scope/type is 345 * given. 346 */ 347 static inline int lookup_enum_name(fb_parser_t *P, fb_scope_t *local, fb_compound_type_t *ct, fb_ref_t *ref, fb_value_t *value) 348 { 349 fb_symbol_t *sym; 350 fb_ref_t *enumval; 351 fb_member_t *member; 352 353 enumval = 0; 354 assert(ref); 355 assert(ct == 0 || ct->symbol.kind == fb_is_enum); 356 sym = lookup_reference(P, local, ref, &enumval); 357 if (sym && sym->kind == fb_is_enum) { 358 ct = (fb_compound_type_t *)sym; 359 } else if (ref->link) { 360 /* If there was a scope / type prefix, it was not found, or it was not an enum type. */ 361 return -1; 362 } 363 if (!ct) { 364 return -1; 365 } 366 sym = find_fb_symbol_by_token(&ct->index, enumval->ident); 367 if (!sym) { 368 return -1; 369 } 370 member = (fb_member_t *)sym; 371 *value = member->value; 372 return 0; 373 } 374 375 /* This is repeated for every include file, but this pose no problem. */ 376 static void install_known_attributes(fb_parser_t *P) 377 { 378 unsigned int i; 379 fb_attribute_t *a; 380 381 for (i = 0; i < KNOWN_ATTR_COUNT; ++i) { 382 /* Don't put it in the parsed list, just the index. */ 383 a = new_elem(P, sizeof(*a)); 384 a->known = i; 385 a->name.name.s.s = (char *)fb_known_attribute_names[i]; 386 a->name.name.s.len = (int)strlen(fb_known_attribute_names[i]); 387 a->name.name.type = vt_string; 388 a->name.link = 0; 389 if ((a = (fb_attribute_t *)define_fb_name(&P->schema.root_schema->attribute_index, &a->name))) { 390 /* 391 * If the user alredy defined the attribute, keep that instead. 392 * (Memory leak is ok here.) 393 */ 394 a->known = i; 395 } 396 } 397 } 398 399 static void revert_order(fb_compound_type_t **list) { 400 fb_compound_type_t *next, *prev = 0, *link = *list; 401 402 while (link) { 403 next = link->order; 404 link->order = prev; 405 prev = link; 406 link = next; 407 } 408 *list = prev; 409 } 410 411 static inline unsigned short process_metadata(fb_parser_t *P, fb_metadata_t *m, 412 uint16_t expect, fb_metadata_t *out[KNOWN_ATTR_COUNT]) 413 { 414 uint16_t flags; 415 unsigned int i, n = FLATCC_ATTR_MAX; 416 int type; 417 fb_attribute_t *a; 418 419 memset(out, 0, sizeof(out[0]) * KNOWN_ATTR_COUNT); 420 for (flags = 0; m && n; --n, m = m->link) { 421 a = (fb_attribute_t *)find_fb_name_by_token(&P->schema.root_schema->attribute_index, m->ident); 422 if (!a) { 423 error_tok(P, m->ident, "unknown attribute not declared"); 424 continue; 425 } 426 if (!(i = a->known)) { 427 continue; 428 } 429 if (!((1 << i) & expect)) { 430 error_tok(P, m->ident, "known attribute not expected in this context"); 431 continue; 432 } 433 flags |= 1 << i; 434 if (out[i]) { 435 error_tok(P, m->ident, "known attribute listed multiple times"); 436 continue; 437 } 438 out[i] = m; 439 type = fb_known_attribute_types[i]; 440 if (type == vt_missing && m->value.type != vt_missing) { 441 error_tok(P, m->ident, "known attribute does not expect a value"); 442 continue; 443 } 444 if (type == vt_string && m->value.type != vt_string) { 445 error_tok(P, m->ident, "known attribute expects a string"); 446 continue; 447 } 448 if (type == vt_uint && m->value.type != vt_uint) { 449 error_tok(P, m->ident, "known attribute expects an unsigned integer"); 450 continue; 451 } 452 if (type == vt_int && m->value.type != vt_uint && m->value.type != vt_int) { 453 error_tok(P, m->ident, "known attribute expects an integer"); 454 continue; 455 } 456 if (type == vt_bool && m->value.type != vt_bool) { 457 error_tok(P, m->ident, "known attribute expects 'true' or 'false'"); 458 continue; 459 } 460 } 461 if (m) { 462 error_tok(P, m->ident, "too many attributes"); 463 } 464 return flags; 465 } 466 467 /* 468 * Recursive types are allowed, according to FlatBuffers Internals doc., 469 * but this cannot be possible for structs because they have no default 470 * value or null option, and can only hold scalars and other structs, so 471 * recursion would never terminate. Enums are simple types and cannot be 472 * recursive either. Unions reference tables which may reference unions, 473 * and recursion works well here. Tables allow any other table, union, 474 * or scalar value to be optional or default, so recursion is possible. 475 * In conclusion, Unions and Table members may reference all other 476 * types, and self. Enums are trivially checked because the only allow 477 * scalars, which leaves structs that can build illegal forms. 478 * 479 * Object instances cannot be recursive meaning the object graph is 480 * always a tree, but this isn't really a concern for the schema 481 * compiler, and for the builder it happens naturally as it only adds to 482 * the buffer (though a compressor might reuse old data without 483 * violating the tree?). 484 * 485 * Conclusion: check structs for circular references and allow 486 * everything else to unfold, provided they otherwise pass type checks. 487 * 488 * Algorithm: 489 * 490 * Depth first search of the struct reference tree. We maintain flags to 491 * find back-links. We prune sub-trees already fully analyzed by using 492 * the closed flag. This operation is O(N) since each struct member is 493 * visited once. 494 * 495 * Recursion is limited to prevent blowing the stack and to protect 496 * against abuse. 497 */ 498 static int analyze_struct(fb_parser_t *P, fb_compound_type_t *ct) 499 { 500 fb_symbol_t *sym; 501 fb_compound_type_t *type; 502 fb_member_t *member; 503 int ret = 0; 504 uint64_t size; 505 uint16_t align; 506 fb_token_t *t; 507 508 assert(ct->symbol.kind == fb_is_struct); 509 510 assert(!(ct->symbol.flags & fb_circular_open)); 511 if (ct->symbol.flags & fb_circular_closed) { 512 return 0; 513 } 514 assert(!ct->order); 515 ct->symbol.flags |= fb_circular_open; 516 align = 1; 517 for (sym = ct->members; sym; sym = sym->link) { 518 type = 0; 519 if (P->nesting_level >= FLATCC_NESTING_MAX) { 520 error(P, "maximum allowed nesting level exceeded while processing struct hierarchy"); 521 return -1; 522 } 523 member = (fb_member_t *)sym; 524 switch (member->type.type) { 525 case vt_fixed_array_type: 526 case vt_scalar_type: 527 t = member->type.t; 528 member->type.st = map_scalar_token_type(t); 529 size = sizeof_scalar_type(member->type.st); 530 if (size < 1) { 531 error_sym_tok(P, sym, "unexpected type", t); 532 return -1; 533 } 534 member->align = (uint16_t)size; 535 member->size = size * member->type.len; 536 break; 537 case vt_fixed_array_compound_type_ref: 538 case vt_compound_type_ref: 539 /* Enums might not be valid, but then it would be detected earlier. */ 540 if (member->type.ct->symbol.kind == fb_is_enum) { 541 type = member->type.ct; 542 size = type->size; 543 member->align = (uint16_t)size; 544 member->size = member->type.len * type->size; 545 break; 546 } else if (member->type.ct->symbol.kind == fb_is_struct) { 547 type = member->type.ct; 548 if (type->symbol.flags & fb_circular_open) { 549 error_sym_2(P, sym, "circular reference to struct at", &type->symbol); 550 return -1; 551 } 552 if (!(type->symbol.flags & fb_circular_closed)) { 553 if (P->opts.hide_later_struct) { 554 error_sym_2(P, sym, "dependency on later defined struct not permitted with current settings", &type->symbol); 555 } 556 ++P->nesting_level; 557 ret = analyze_struct(P, type); 558 --P->nesting_level; 559 if (ret) { 560 return ret; 561 } 562 } 563 member->align = type->align; 564 member->size = member->type.len * type->size; 565 break; 566 } else { 567 error_sym(P, sym, "unexpected compound type for field"); 568 return -1; 569 } 570 break; 571 case vt_invalid: 572 /* Old error. */ 573 return -1; 574 default: 575 error_sym(P, sym, "unexpected type"); 576 return -1; 577 } 578 member->offset = fb_align(ct->size, member->align); 579 if (member->offset < ct->size || member->offset + member->size < member->offset) { 580 error_sym(P, sym, "struct size overflow"); 581 return -1; 582 } 583 size = member->offset + member->size; 584 if (size < ct->size || size > FLATCC_STRUCT_MAX_SIZE) { 585 error_sym(P, sym, "struct field overflows maximum allowed struct size"); 586 }; 587 ct->size = size; 588 /* 589 * FB spec is not very clear on this - but experimentally a 590 * force aligned member struct will force that alignment upon a 591 * containing struct if the alignment would otherwise be 592 * smaller. In otherwise, a struct is aligned to the alignment 593 * of the largest member, not just the largest scalar member 594 * (directly or indirectly). 595 */ 596 if (align < member->align) { 597 align = member->align; 598 } 599 } 600 if (ct->align > 0) { 601 if (align > ct->align) { 602 error_sym(P, &ct->symbol, "'force_align' cannot be smaller than natural alignment for"); 603 ct->align = align; 604 } 605 } else { 606 ct->align = align; 607 } 608 /* Add trailing padding if necessary. */ 609 ct->size = fb_align(ct->size, ct->align); 610 611 if (ct->size == 0) { 612 error_sym(P, &ct->symbol, "struct cannot be empty"); 613 return -1; 614 } 615 616 ct->symbol.flags |= fb_circular_closed; 617 ct->symbol.flags &= (uint16_t)~fb_circular_open; 618 ct->order = P->schema.ordered_structs; 619 P->schema.ordered_structs = ct; 620 return ret; 621 } 622 623 static int define_nested_table(fb_parser_t *P, fb_scope_t *local, fb_member_t *member, fb_metadata_t *m) 624 { 625 fb_symbol_t *type_sym; 626 627 if (member->type.type != vt_vector_type || member->type.st != fb_ubyte) { 628 error_tok(P, m->ident, "'nested_flatbuffer' attribute requires a [ubyte] vector type"); 629 return -1; 630 } 631 if (m->value.type != vt_string) { 632 /* All known attributes get automatically type checked, so just ignore. */ 633 return -1; 634 } 635 type_sym = lookup_string_reference(P, local, m->value.s.s, (size_t)m->value.s.len); 636 if (!type_sym) { 637 error_tok_as_string(P, m->ident, "nested reference not found", m->value.s.s, (size_t)m->value.s.len); 638 return -1; 639 } 640 if (type_sym->kind != fb_is_table) { 641 if (!P->opts.allow_struct_root) { 642 error_tok_2(P, m->ident, "nested reference does not refer to a table", type_sym->ident); 643 return -1; 644 } 645 if (type_sym->kind != fb_is_struct) { 646 error_tok_2(P, m->ident, "nested reference does not refer to a table or a struct", type_sym->ident); 647 return -1; 648 } 649 } 650 member->nest = (fb_compound_type_t *)type_sym; 651 return 0; 652 } 653 654 static int process_struct(fb_parser_t *P, fb_compound_type_t *ct) 655 { 656 fb_symbol_t *sym, *old, *type_sym; 657 fb_member_t *member; 658 fb_metadata_t *knowns[KNOWN_ATTR_COUNT], *m; 659 uint16_t allow_flags; 660 int key_count = 0, primary_count = 0, key_ok = 0; 661 662 if (ct->type.type) { 663 error_sym(P, &ct->symbol, "internal error: struct cannot have a type"); 664 return -1; 665 } 666 ct->metadata_flags = process_metadata(P, ct->metadata, fb_f_force_align, knowns); 667 if ((m = knowns[fb_attr_force_align])) { 668 if (!is_valid_align(m->value.u)) { 669 error_sym(P, &ct->symbol, "'force_align' exceeds maximum permitted alignment or is not a power of 2"); 670 } else { 671 /* This may still fail on natural alignment size. */ 672 ct->align = (uint16_t)m->value.u; 673 } 674 } 675 for (sym = ct->members; sym; sym = sym->link) { 676 if ((old = define_fb_symbol(&ct->index, sym))) { 677 error_sym_2(P, sym, "struct field already defined here", old); 678 continue; 679 } 680 if (sym->kind != fb_is_member) { 681 error_sym(P, sym, "internal error: field type expected"); 682 return -1; 683 } 684 key_ok = 1; 685 member = (fb_member_t *)sym; 686 allow_flags = 0; 687 /* Notice the difference between fb_f_ and fb_attr_ (flag vs index). */ 688 if (P->opts.allow_struct_field_key) { 689 allow_flags |= fb_f_key; 690 if (P->opts.allow_primary_key) { 691 allow_flags |= fb_f_primary_key; 692 } 693 } 694 if (P->opts.allow_struct_field_deprecate) { 695 allow_flags |= fb_f_deprecated; 696 } 697 member->metadata_flags = process_metadata(P, member->metadata, allow_flags, knowns); 698 switch (member->type.type) { 699 case vt_fixed_array_type_ref: 700 key_ok = 0; 701 goto lbl_type_ref; 702 case vt_type_ref: 703 lbl_type_ref: 704 type_sym = lookup_type_reference(P, ct->scope, member->type.ref); 705 if (!type_sym) { 706 error_ref_sym(P, member->type.ref, "unknown type reference used with struct field", sym); 707 member->type.type = vt_invalid; 708 continue; 709 } 710 member->type.ct = (fb_compound_type_t*)type_sym; 711 member->type.type = member->type.type == vt_fixed_array_type_ref ? 712 vt_fixed_array_compound_type_ref : vt_compound_type_ref; 713 if (type_sym->kind != fb_is_struct) { 714 if (P->opts.allow_enum_struct_field) { 715 if (type_sym->kind != fb_is_enum) { 716 error_sym_2(P, sym, "struct fields can only be scalars, structs, and enums, or arrays of these, but has type", type_sym); 717 member->type.type = vt_invalid; 718 return -1; 719 } 720 if (!P->opts.allow_enum_key) { 721 key_ok = 0; 722 break; 723 } 724 } else { 725 error_sym_2(P, sym, "struct fields can only be scalars and structs, or arrays of these, but has type", type_sym); 726 member->type.type = vt_invalid; 727 return -1; 728 } 729 } else { 730 key_ok = 0; 731 } 732 break; 733 case vt_fixed_array_string_type: 734 error_sym(P, sym, "fixed length arrays cannot have string elements"); 735 member->type.type = vt_invalid; 736 return -1; 737 case vt_fixed_array_type: 738 key_ok = 0; 739 break; 740 case vt_scalar_type: 741 break; 742 default: 743 error_sym(P, sym, "struct member member can only be of struct scalar, or fixed length scalar array type"); 744 return -1; 745 } 746 if (!key_ok) { 747 if (member->metadata_flags & fb_f_key) { 748 member->type.type = vt_invalid; 749 error_sym(P, sym, "key attribute now allowed for this kind of field"); 750 return -1; 751 } 752 if (member->metadata_flags & fb_f_primary_key) { 753 member->type.type = vt_invalid; 754 error_sym(P, sym, "primary_key attribute now allowed for this kind of field"); 755 return -1; 756 } 757 } 758 if (member->metadata_flags & fb_f_deprecated) { 759 if (member->metadata_flags & fb_f_key) { 760 error_sym(P, sym, "key attribute not allowed for deprecated struct member"); 761 return -1; 762 } else if (member->metadata_flags & fb_f_primary_key) { 763 error_sym(P, sym, "primary_key attribute not allowed for deprecated struct member"); 764 return -1; 765 } 766 } 767 if (member->metadata_flags & fb_f_key) { 768 if (member->metadata_flags & fb_f_primary_key) { 769 error_sym(P, sym, "primary_key attribute conflicts with key attribute"); 770 member->type.type = vt_invalid; 771 return -1; 772 } 773 key_count++; 774 if (!ct->primary_key) { 775 /* First key is primary key if no primary key is given explicitly. */ 776 ct->primary_key = member; 777 } 778 } else if (member->metadata_flags & fb_f_primary_key) { 779 if (primary_count++) { 780 error_sym(P, sym, "at most one struct member can have a primary_key attribute"); 781 member->type.type = vt_invalid; 782 return -1; 783 } 784 key_count++; 785 /* Allow backends to treat primary key as an ordinary key. */ 786 member->metadata_flags |= fb_f_key; 787 ct->primary_key = member; 788 } 789 if (member->value.type) { 790 error_sym(P, sym, "struct member member cannot have a default value"); 791 continue; 792 } 793 } 794 if (key_count) { 795 ct->symbol.flags |= fb_indexed; 796 } 797 /* Set primary key flag for backends even if chosen by default. */ 798 if (ct->primary_key) { 799 ct->primary_key->metadata_flags |= fb_f_primary_key; 800 } 801 if (key_count > 1 && !P->opts.allow_multiple_key_fields) { 802 error_sym(P, &ct->symbol, "table has multiple key fields, but at most one is permitted"); 803 return -1; 804 } 805 return 0; 806 } 807 808 static fb_member_t *original_order_members(fb_parser_t *P, fb_member_t *next) 809 { 810 fb_member_t *head = 0; 811 fb_member_t **tail = &head; 812 813 /* Not used for now, but in case we need error messages etc. */ 814 (void)P; 815 816 while (next) { 817 *tail = next; 818 tail = &next->order; 819 next = (fb_member_t *)(((fb_symbol_t *)next)->link); 820 } 821 *tail = 0; 822 return head; 823 } 824 825 /* 826 * Alignment of table offset fields are generally not stored, and 827 * vectors store the element alignment for scalar types, so we 828 * detect alignment based on type also. Unions are tricky since they 829 * use a single byte type followed by an offset, but it is impractical 830 * to store these separately so we sort by the type field. 831 */ 832 static fb_member_t *align_order_members(fb_parser_t *P, fb_member_t *members) 833 { 834 uint16_t i, j, k; 835 fb_member_t *heads[9] = {0}; 836 fb_member_t **tails[9] = {0}; 837 fb_member_t *next = members; 838 839 while (next) { 840 k = next->align; 841 switch (next->type.type) { 842 case vt_compound_type_ref: 843 switch (next->type.ct->symbol.kind) { 844 case fb_is_struct: 845 case fb_is_enum: 846 k = next->type.ct->align; 847 break; 848 case fb_is_union: 849 /* 850 * Unions align to their offsets because the type can 851 * always be added last in a second pass since it is 1 852 * byte. 853 */ 854 k = (uint16_t)P->opts.offset_size; 855 break; 856 default: 857 k = (uint16_t)P->opts.offset_size; 858 break; 859 } 860 break; 861 case vt_vector_compound_type_ref: 862 case vt_string_type: 863 case vt_vector_type: 864 case vt_vector_string_type: 865 k = (uint16_t)P->opts.offset_size; 866 break; 867 case vt_invalid: 868 /* Just to have some sane behavior. */ 869 return original_order_members(P, members); 870 default: 871 k = next->align; 872 break; 873 } 874 assert(k > 0); 875 i = 0; 876 while (k >>= 1) { 877 ++i; 878 } 879 /* Normally the largest alignment is 256, but otherwise we group them together. */ 880 if (i > 7) { 881 i = 7; 882 } 883 if (!heads[i]) { 884 heads[i] = next; 885 } else { 886 *tails[i] = next; 887 } 888 tails[i] = &next->order; 889 next = (fb_member_t *)(((fb_symbol_t *)next)->link); 890 } 891 i = j = 8; 892 tails[8] = &heads[8]; 893 while (j) { 894 while (i && !heads[--i]) { 895 } 896 *tails[j] = heads[i]; 897 j = i; 898 } 899 return heads[8]; 900 } 901 902 /* Temporary markers only used during assignment of field identifiers. */ 903 enum { unused_field = 0, normal_field, type_field }; 904 905 static int process_table(fb_parser_t *P, fb_compound_type_t *ct) 906 { 907 char msg_buf [100]; 908 fb_symbol_t *sym, *old, *type_sym; 909 fb_member_t *member; 910 fb_metadata_t *knowns[KNOWN_ATTR_COUNT], *m; 911 int ret = 0; 912 uint64_t count = 0; 913 int need_id = 0, id_failed = 0; 914 uint64_t max_id = 0; 915 int key_ok, key_count = 0, primary_count = 0; 916 int is_union_vector, is_vector; 917 uint64_t i, j; 918 int max_id_errors = 10; 919 int allow_flags = 0; 920 921 /* 922 * This just tracks the presence of a `normal_field` or a hidden 923 * `type_field`. The size is litmited to 16-bit unsigned offsets. 924 * It is only of relevance for ithe optional `id` table field 925 * attribute. 926 */ 927 uint8_t *field_marker = 0; 928 fb_symbol_t **field_index = 0; 929 930 assert(ct->symbol.kind == fb_is_table); 931 assert(!ct->type.type); 932 933 ct->metadata_flags = process_metadata(P, ct->metadata, fb_f_original_order, knowns); 934 /* 935 * `original_order` now lives as a flag, we need not consider it 936 * further until code generation. 937 */ 938 for (sym = ct->members; sym; sym = sym->link) { 939 key_ok = 0; 940 type_sym = 0; 941 is_vector = 0; 942 is_union_vector = 0; 943 if ((old = define_fb_symbol(&ct->index, sym))) { 944 error_sym_2(P, sym, "table member already defined here", old); 945 continue; 946 } 947 if (sym->kind != fb_is_member) { 948 error_sym(P, sym, "internal error: member type expected"); 949 return -1; 950 } 951 member = (fb_member_t *)sym; 952 if (member->type.type == vt_invalid) { 953 continue; 954 } 955 if (member->type.type == vt_scalar_type || member->type.type == vt_vector_type) { 956 member->type.st = map_scalar_token_type(member->type.t); 957 } 958 allow_flags = 959 fb_f_id | fb_f_nested_flatbuffer | fb_f_deprecated | fb_f_key | 960 fb_f_required | fb_f_hash | fb_f_base64 | fb_f_base64url | fb_f_sorted; 961 962 if (P->opts.allow_primary_key) { 963 allow_flags |= fb_f_primary_key; 964 } 965 member->metadata_flags = process_metadata(P, member->metadata, (uint16_t)allow_flags, knowns); 966 if ((m = knowns[fb_attr_nested_flatbuffer])) { 967 define_nested_table(P, ct->scope, member, m); 968 } 969 /* Note: we allow base64 and base64url with nested attribute. */ 970 if ((member->metadata_flags & fb_f_base64) && 971 (member->type.type != vt_vector_type || member->type.st != fb_ubyte)) { 972 error_sym(P, sym, "'base64' attribute is only allowed on vectors of type ubyte"); 973 } 974 if ((member->metadata_flags & fb_f_base64url) && 975 (member->type.type != vt_vector_type || member->type.st != fb_ubyte)) { 976 error_sym(P, sym, "'base64url' attribute is only allowed on vectors of type ubyte"); 977 } 978 if ((member->metadata_flags & (fb_f_base64 | fb_f_base64url)) == 979 (fb_f_base64 | fb_f_base64url)) { 980 error_sym(P, sym, "'base64' and 'base64url' attributes cannot both be set"); 981 } 982 m = knowns[fb_attr_id]; 983 if (m && count == 0) { 984 need_id = 1; 985 field_marker = P->tmp_field_marker; 986 memset(field_marker, 0, (size_t)P->opts.vt_max_count); 987 } 988 if (!id_failed) { 989 if (count >= P->opts.vt_max_count) { 990 error_sym(P, sym, "too many fields for vtable size"); 991 id_failed = 1; 992 } else if (!need_id) { 993 member->id = (unsigned short)count; 994 } 995 ++count; 996 } 997 switch (member->type.type) { 998 case vt_scalar_type: 999 if (member->value.type == vt_null) { 1000 member->value.type = vt_uint; 1001 member->value.u = 0; 1002 member->flags |= fb_fm_optional; 1003 } 1004 if (member->metadata_flags & fb_f_required) { 1005 if (member->flags & fb_fm_optional) { 1006 error_sym(P, sym, "'required' attribute is incompatible with optional table field (= null)"); 1007 } else { 1008 error_sym(P, sym, "'required' attribute is redundant on scalar table field"); 1009 } 1010 } 1011 key_ok = 1; 1012 if (member->value.type == vt_name_ref) { 1013 if (lookup_enum_name(P, ct->scope, 0, member->value.ref, &member->value)) { 1014 error_ref_sym(P, member->value.ref, "unknown name used as initializer for scalar field", sym); 1015 member->type.type = vt_invalid; 1016 continue; 1017 } 1018 } 1019 if (!member->value.type) { 1020 /* 1021 * Simplifying by ensuring we always have a default 1022 * value where an initializer is possible (also goes for enum). 1023 */ 1024 member->value.type = vt_uint; 1025 member->value.u = 0; 1026 } 1027 if (fb_coerce_scalar_type(P, sym, member->type.st, &member->value)) { 1028 member->type.type = vt_invalid; 1029 continue; 1030 } 1031 member->size = sizeof_scalar_type(member->type.st); 1032 member->align = (uint16_t)member->size; 1033 break; 1034 case vt_vector_type: 1035 is_vector = 1; 1036 member->size = sizeof_scalar_type(member->type.st); 1037 member->align =(uint16_t) member->size; 1038 if (member->value.type) { 1039 error_sym(P, sym, "scalar vectors cannot have an initializer"); 1040 member->type.type = vt_invalid; 1041 continue; 1042 } 1043 break; 1044 case vt_fixed_array_type_ref: 1045 case vt_fixed_array_string_type: 1046 case vt_fixed_array_type: 1047 error_sym(P, sym, "fixed length arrays can only be used with structs"); 1048 member->type.type = vt_invalid; 1049 return -1; 1050 case vt_string_type: 1051 /* `size` or `align` not defined - these are implicit uoffset types. */ 1052 key_ok = P->opts.allow_string_key; 1053 if (member->value.type) { 1054 error_sym(P, sym, "strings cannot have an initializer"); 1055 member->type.type = vt_invalid; 1056 continue; 1057 } 1058 break; 1059 case vt_vector_string_type: 1060 is_vector = 1; 1061 /* `size` or `align` not defined - these are implicit uoffset types. */ 1062 if (member->value.type) { 1063 error_sym(P, sym, "string vectors cannot have an initializer"); 1064 member->type.type = vt_invalid; 1065 continue; 1066 } 1067 break; 1068 case vt_type_ref: 1069 type_sym = lookup_type_reference(P, ct->scope, member->type.ref); 1070 if (!type_sym) { 1071 error_ref_sym(P, member->type.ref, "unknown type reference used with table field", sym); 1072 member->type.type = vt_invalid; 1073 /* We cannot count id's without knowing if it is a union. */ 1074 id_failed = 1; 1075 continue; 1076 } 1077 switch (type_sym->kind) { 1078 case fb_is_enum: 1079 /* 1080 * Note the enums without a 0 element requires an 1081 * initializer in the schema, but that cannot happen 1082 * with a null value, so in this case the value is force 1083 * to 0. This is only relevant when using the `_get()` 1084 * accessor instead of the `_option()`. 1085 */ 1086 if (member->value.type == vt_null) { 1087 member->value.type = vt_uint; 1088 member->value.u = 0; 1089 member->flags |= fb_fm_optional; 1090 } 1091 if (member->metadata_flags & fb_f_required) { 1092 if (member->flags & fb_fm_optional) { 1093 error_sym(P, sym, "'required' attribute is incompatible with optional enum table field (= null)"); 1094 } else { 1095 error_sym(P, sym, "'required' attribute is redundant on enum table field"); 1096 } 1097 } 1098 key_ok = P->opts.allow_enum_key; 1099 break; 1100 case fb_is_table: 1101 case fb_is_struct: 1102 case fb_is_union: 1103 break; 1104 case fb_is_rpc_service: 1105 error_sym_2(P, sym, "rpc service is not a valid table field type", type_sym); 1106 member->type.type = vt_invalid; 1107 continue; 1108 default: 1109 error_sym_2(P, sym, "internal error: unexpected field type", type_sym); 1110 member->type.type = vt_invalid; 1111 continue; 1112 } 1113 member->type.type = vt_compound_type_ref; 1114 member->type.ct = (fb_compound_type_t*)type_sym; 1115 /* 1116 * Note: this information transfer won't always work because 1117 * structs do not know their full size at this point so 1118 * codegen must use the member->type.ct values. 1119 */ 1120 member->size = member->type.ct->size; 1121 member->align = member->type.ct->align; 1122 1123 if (type_sym->kind == fb_is_union && !id_failed) { 1124 /* Hidden union type field. */ 1125 if (!need_id) { 1126 member->id = (unsigned short)count; 1127 } 1128 ++count; 1129 } 1130 if (member->value.type) { 1131 if (type_sym->kind != fb_is_enum) { 1132 error_sym(P, sym, "non-scalar field cannot have an initializer"); 1133 member->type.type = vt_invalid; 1134 continue; 1135 } 1136 if (member->value.type == vt_name_ref) { 1137 if (lookup_enum_name(P, ct->scope, member->type.ct, member->value.ref, &member->value)) { 1138 error_ref_sym(P, member->value.ref, "unknown name used as initializer for enum field", sym); 1139 member->type.type = vt_invalid; 1140 continue; 1141 } 1142 } else { 1143 if (fb_coerce_scalar_type(P, sym, ((fb_compound_type_t *)type_sym)->type.st, &member->value)) { 1144 member->type.type = vt_invalid; 1145 continue; 1146 } 1147 /* Bitflags can have complex combinations of values, and do not nativele have a 0 value. */ 1148 if (P->opts.strict_enum_init && !(member->type.ct->metadata_flags & fb_f_bit_flags) 1149 && !(member->flags & fb_fm_optional)) { 1150 if (!is_in_value_set(&member->type.ct->value_set, &member->value)) { 1151 error_sym(P, sym, "initializer does not match a defined enum value"); 1152 member->type.type = vt_invalid; 1153 continue; 1154 } 1155 } 1156 } 1157 } else { 1158 /* Enum is the only type that cannot always default to 0. */ 1159 if (type_sym->kind == fb_is_enum) { 1160 member->value.type = vt_uint; 1161 member->value.u = 0; 1162 if (fb_coerce_scalar_type(P, type_sym, ((fb_compound_type_t *)type_sym)->type.st, &member->value)) { 1163 member->type.type = vt_invalid; 1164 continue; 1165 } 1166 if (P->opts.strict_enum_init) { 1167 /* TODO: consider if this error is necessary for bit_flags - flatc 2.0.0 errors on this. */ 1168 if (!is_in_value_set(&member->type.ct->value_set, &member->value)) { 1169 error_sym_2(P, sym, 1170 "enum type requires an explicit initializer because it has no 0 value", type_sym); 1171 member->type.type = vt_invalid; 1172 continue; 1173 } 1174 } 1175 } 1176 } 1177 break; 1178 case vt_vector_type_ref: 1179 type_sym = lookup_type_reference(P, ct->scope, member->type.ref); 1180 if (!type_sym) { 1181 error_ref_sym(P, member->type.ref, "unknown vector type reference used with table field", sym); 1182 member->type.type = vt_invalid; 1183 continue; 1184 } 1185 switch (type_sym->kind) { 1186 case fb_is_enum: 1187 case fb_is_table: 1188 case fb_is_struct: 1189 case fb_is_union: 1190 break; 1191 default: 1192 /* Vectors of strings are handled separately but this is irrelevant to the user. */ 1193 error_sym_tok(P, sym, "vectors can only hold scalars, structs, enums, strings, tables, and unions", member->type.t); 1194 member->type.type = vt_invalid; 1195 continue; 1196 } 1197 is_vector = 1; 1198 is_union_vector = type_sym->kind == fb_is_union; 1199 if (member->value.type) { 1200 error_sym(P, sym, "non-scalar field cannot have an initializer"); 1201 member->type.type = vt_invalid; 1202 continue; 1203 } 1204 /* Size of the vector element, not of the vector itself. */ 1205 member->type.type = vt_vector_compound_type_ref; 1206 member->type.ct = (fb_compound_type_t*)type_sym; 1207 member->size = member->type.ct->size; 1208 member->align = member->type.ct->align; 1209 if (type_sym->kind == fb_is_union && !id_failed) { 1210 /* Hidden union type field. */ 1211 if (!need_id) { 1212 member->id = (unsigned short)count; 1213 } 1214 ++count; 1215 } 1216 break; 1217 default: 1218 error_sym(P, sym, "unexpected table field type encountered"); 1219 member->type.type = vt_invalid; 1220 continue; 1221 } 1222 if (!id_failed) { 1223 if (m && !need_id && !id_failed) { 1224 error_tok(P, m->ident, "unexpected id attribute, must be used on all fields, or none"); 1225 id_failed = 1; 1226 } else if (!m && need_id && !id_failed) { 1227 error_sym(P, sym, "id attribute missing, must be used on all fields, or none"); 1228 id_failed = 1; 1229 } else if (m) { 1230 if (m->value.type == vt_uint) { 1231 if (m->value.u >= P->opts.vt_max_count) { 1232 error_sym(P, sym, "id too large to fit in vtable"); 1233 id_failed = 1; 1234 } else { 1235 member->id = (unsigned short)m->value.u; 1236 if (member->id > max_id) { 1237 max_id = member->id; 1238 } 1239 } 1240 } else if (m->value.type == vt_int) { 1241 error_tok(P, m->ident, "id attribute cannot be negative"); 1242 id_failed = 1; 1243 } else { 1244 error_tok(P, m->ident, "unexpecte id attribute type"); 1245 id_failed = 1; 1246 } 1247 } 1248 } 1249 if (need_id && !id_failed) { 1250 if (field_marker[member->id] == type_field) { 1251 error_tok(P, m->ident, "id attribute value conflicts with a hidden type field"); 1252 id_failed = normal_field; 1253 } else if (field_marker[member->id]) { 1254 error_tok(P, m->ident, "id attribute value conflicts with another field"); 1255 } else { 1256 field_marker[member->id] = normal_field; 1257 } 1258 if (!id_failed && type_sym && type_sym->kind == fb_is_union) { 1259 if (member->id <= 1) { 1260 error_tok(P, m->ident, is_union_vector ? 1261 "id attribute value should be larger to accommodate hidden union vector type field" : 1262 "id attribute value should be larger to accommodate hidden union type field"); 1263 id_failed = 1; 1264 } else if (field_marker[member->id - 1] == type_field) { 1265 error_tok(P, m->ident, is_union_vector ? 1266 "hidden union vector type field below attribute id value conflicts with another hidden type field" : 1267 "hidden union type field below attribute id value conflicts with another hidden type field"); 1268 id_failed = 1; 1269 } else if (field_marker[member->id - 1]) { 1270 error_tok(P, m->ident, is_union_vector ? 1271 "hidden union vector type field below attribute id value conflicts with another field" : 1272 "hidden union type field below attribute id value conflicts with another field"); 1273 id_failed = 1; 1274 } else { 1275 field_marker[member->id - 1] = type_field; 1276 } 1277 } 1278 } 1279 if (member->metadata_flags & fb_f_deprecated) { 1280 if (member->metadata_flags & fb_f_key) { 1281 error_sym(P, sym, "key attribute not allowed for deprecated field"); 1282 return -1; 1283 } else if (member->metadata_flags & fb_f_primary_key) { 1284 error_sym(P, sym, "primary_key attribute not allowed for deprecated field"); 1285 return -1; 1286 } 1287 } 1288 if (member->metadata_flags & fb_f_key) { 1289 ++key_count; 1290 if (!key_ok) { 1291 error_sym(P, sym, "key attribute not allowed for this kind of field"); 1292 member->type.type = vt_invalid; 1293 } else if (member->metadata_flags & fb_f_primary_key) { 1294 error_sym(P, sym, "primary_key attribute conflicts with key attribute"); 1295 member->type.type = vt_invalid; 1296 } else if (!ct->primary_key || 1297 (primary_count == 0 && ct->primary_key->id > member->id)) { 1298 /* 1299 * Set key field with lowest id as default primary key 1300 * unless a key field also has a primary attribute. 1301 */ 1302 ct->primary_key = member; 1303 } 1304 } else if (member->metadata_flags & fb_f_primary_key) { 1305 if (member->metadata_flags & fb_f_primary_key) { 1306 if (primary_count++) { 1307 error_sym(P, sym, "at most one field can have a primary_key attribute"); 1308 member->type.type = vt_invalid; 1309 continue; 1310 } else { 1311 ct->primary_key = member; 1312 } 1313 } 1314 key_count++; 1315 /* Allow backends to treat primary key as an ordinary key. */ 1316 member->metadata_flags |= fb_f_key; 1317 } 1318 if (member->metadata_flags & fb_f_sorted) { 1319 if (is_union_vector) { 1320 error_sym(P, sym, "sorted attribute not allowed for union vectors"); 1321 member->type.type = vt_invalid; 1322 return -1; 1323 } else if (!is_vector) { 1324 error_sym(P, sym, "sorted attribute only allowed for vectors"); 1325 member->type.type = vt_invalid; 1326 return -1; 1327 } 1328 /* 1329 * A subsequent call to validate_table_attr will verify that a 1330 * sorted vector of tables or structs have a defined field 1331 * key. This cannot be done before all types have been 1332 * processed. 1333 */ 1334 } 1335 } 1336 if (!id_failed) { 1337 ct->count = count; 1338 } 1339 if (!id_failed && need_id) { 1340 if (count && max_id >= count) { 1341 for (i = 0; i < max_id; ++i) { 1342 if (field_marker[i] == 0) { 1343 if (!max_id_errors--) { 1344 error_sym(P, &ct->symbol, "... more id's missing"); 1345 break; 1346 } 1347 sprintf(msg_buf, "id range not consequtive from 0, missing id: %"PRIu64"", i); 1348 error_sym(P, &ct->symbol, msg_buf); 1349 } 1350 } 1351 id_failed = 1; 1352 } 1353 } 1354 /* Order in which data is ordered in binary buffer. */ 1355 if (ct->metadata_flags & fb_f_original_order) { 1356 ct->ordered_members = original_order_members(P, (fb_member_t *)ct->members); 1357 } else { 1358 /* Size efficient ordering. */ 1359 ct->ordered_members = align_order_members(P, (fb_member_t *)ct->members); 1360 } 1361 if (!id_failed && need_id && count > 0) { 1362 field_index = P->tmp_field_index; 1363 memset(field_index, 0, sizeof(field_index[0]) * (size_t)P->opts.vt_max_count); 1364 /* 1365 * Reorder by id so table constructor arguments in code 1366 * generators always use same ordering across versions. 1367 */ 1368 for (sym = ct->members; sym; sym = sym->link) { 1369 member = (fb_member_t *)sym; 1370 field_index[member->id] = sym; 1371 } 1372 j = 0; 1373 if (field_index[0] == 0) { 1374 j = 1; /* Adjust for union type. */ 1375 } 1376 ct->members = field_index[j]; 1377 for (i = j + 1; i <= max_id; ++i) { 1378 if (field_index[i] == 0) ++i; /* Adjust for union type. */ 1379 field_index[j]->link = field_index[i]; 1380 j = i; 1381 } 1382 field_index[max_id]->link = 0; 1383 } 1384 if (key_count) { 1385 ct->symbol.flags |= fb_indexed; 1386 } 1387 /* Set primary key flag for backends even if chosen by default. */ 1388 if (ct->primary_key) { 1389 ct->primary_key->metadata_flags |= fb_f_primary_key; 1390 } 1391 if (key_count > 1 && !P->opts.allow_multiple_key_fields) { 1392 error_sym(P, &ct->symbol, "table has multiple key fields, but at most one is permitted"); 1393 ret = -1; 1394 } 1395 if (id_failed) { 1396 ret = -1; 1397 } 1398 return ret; 1399 } 1400 1401 /* 1402 * Post processing of process_table because some information is only 1403 * available when all types have been processed. 1404 */ 1405 static int validate_table_attr(fb_parser_t *P, fb_compound_type_t *ct) 1406 { 1407 fb_symbol_t *sym; 1408 fb_member_t *member; 1409 1410 for (sym = ct->members; sym; sym = sym->link) { 1411 member = (fb_member_t *)sym; 1412 if (member->metadata_flags & fb_f_deprecated) { 1413 continue; 1414 } 1415 1416 if (member->type.type == vt_vector_compound_type_ref && 1417 member->metadata_flags & fb_f_sorted) { 1418 switch (member->type.ct->symbol.kind) { 1419 case fb_is_table: 1420 if (!member->type.ct->primary_key) { 1421 error_sym(P, sym, "sorted table vector only valid when table has a key field"); 1422 return -1; 1423 } 1424 break; 1425 case fb_is_struct: 1426 if (!member->type.ct->primary_key) { 1427 error_sym(P, sym, "sorted struct vector only valid when struct has a key field"); 1428 return -1; 1429 } 1430 break; 1431 /* Other cases already handled in process_table. */ 1432 default: 1433 continue; 1434 } 1435 } 1436 } 1437 return 0; 1438 } 1439 1440 /* 1441 * The parser already makes sure we have exactly one request type, 1442 * one response type, and no initializer. 1443 * 1444 * We are a bit heavy on flagging attributes because their behavior 1445 * isn't really specified at this point. 1446 */ 1447 static int process_rpc_service(fb_parser_t *P, fb_compound_type_t *ct) 1448 { 1449 fb_symbol_t *sym, *old, *type_sym; 1450 fb_member_t *member; 1451 #if FLATCC_ALLOW_RPC_SERVICE_ATTRIBUTES || FLATCC_ALLOW_RPC_METHOD_ATTRIBUTES 1452 fb_metadata_t *knowns[KNOWN_ATTR_COUNT]; 1453 #endif 1454 1455 assert(ct->symbol.kind == fb_is_rpc_service); 1456 assert(!ct->type.type); 1457 1458 /* 1459 * Deprecated is defined for fields - but it is unclear if this also 1460 * covers rpc services. Anyway, we accept it since it may be useful, 1461 * and does not harm. 1462 */ 1463 #if FLATCC_ALLOW_RPC_SERVICE_ATTRIBUTES 1464 /* But we have no known attributes to support. */ 1465 ct->metadata_flags = process_metadata(P, ct->metadata, 0, knowns); 1466 #else 1467 if (ct->metadata) { 1468 error_sym(P, &ct->symbol, "rpc services cannot have attributes"); 1469 /* Non-fatal. */ 1470 } 1471 #endif 1472 1473 /* 1474 * `original_order` now lives as a flag, we need not consider it 1475 * further until code generation. 1476 */ 1477 for (sym = ct->members; sym; sym = sym->link) { 1478 type_sym = 0; 1479 if ((old = define_fb_symbol(&ct->index, sym))) { 1480 error_sym_2(P, sym, "rpc method already defined here", old); 1481 continue; 1482 } 1483 if (sym->kind != fb_is_member) { 1484 error_sym(P, sym, "internal error: member type expected"); 1485 return -1; 1486 } 1487 member = (fb_member_t *)sym; 1488 if (member->value.type) { 1489 error_sym(P, sym, "internal error: initializer should have been rejected by parser"); 1490 } 1491 if (member->type.type == vt_invalid) { 1492 continue; 1493 } 1494 if (member->type.type != vt_type_ref) { 1495 error_sym(P, sym, "internal error: request type expected to be a type reference"); 1496 } 1497 type_sym = lookup_type_reference(P, ct->scope, member->req_type.ref); 1498 if (!type_sym) { 1499 error_ref_sym(P, member->req_type.ref, "unknown type reference used with rpc request type", sym); 1500 member->type.type = vt_invalid; 1501 continue; 1502 } else { 1503 if (type_sym->kind != fb_is_table) { 1504 error_sym_2(P, sym, "rpc request type must reference a table, defined here", type_sym); 1505 member->type.type = vt_invalid; 1506 continue; 1507 } 1508 member->req_type.type = vt_compound_type_ref; 1509 member->req_type.ct = (fb_compound_type_t*)type_sym; 1510 } 1511 type_sym = lookup_type_reference(P, ct->scope, member->type.ref); 1512 if (!type_sym) { 1513 error_ref_sym(P, member->type.ref, "unknown type reference used with rpc response type", sym); 1514 member->type.type = vt_invalid; 1515 continue; 1516 } else { 1517 if (type_sym->kind != fb_is_table) { 1518 error_sym_2(P, sym, "rpc response type must reference a table, defined here", type_sym); 1519 member->type.type = vt_invalid; 1520 continue; 1521 } 1522 member->type.type = vt_compound_type_ref; 1523 member->type.ct = (fb_compound_type_t*)type_sym; 1524 /* Symbols have no size. */ 1525 member->size = 0; 1526 } 1527 #if FLATCC_ALLOW_RPC_METHOD_ATTRIBUTES 1528 #if FLATCC_ALLOW_DEPRECATED_RPC_METHOD 1529 member->metadata_flags = process_metadata(P, member->metadata, fb_f_deprecated, knowns); 1530 #else 1531 member->metadata_flags = process_metadata(P, member->metadata, 0, knowns); 1532 #endif 1533 #else 1534 if (member->metadata) { 1535 error_sym(P, sym, "rpc methods cannot have attributes"); 1536 /* Non-fatal. */ 1537 continue; 1538 } 1539 #endif 1540 } 1541 return 0; 1542 } 1543 1544 static int process_enum(fb_parser_t *P, fb_compound_type_t *ct) 1545 { 1546 fb_symbol_t *sym, *old, *type_sym; 1547 fb_member_t *member; 1548 fb_metadata_t *knowns[KNOWN_ATTR_COUNT]; 1549 fb_value_t index = { { { 0 } }, 0, 0 }; 1550 fb_value_t old_index; 1551 int first = 1; 1552 int bit_flags = 0; 1553 int is_union = ct->symbol.kind == fb_is_union; 1554 1555 if (!is_union) { 1556 assert(ct->symbol.kind == fb_is_enum); 1557 if (!ct->type.type) { 1558 ct->type.type = vt_invalid; 1559 error_sym(P, &ct->symbol, "enum must have a type"); 1560 return -1; 1561 } 1562 if (ct->type.type == vt_missing) { 1563 /* 1564 * Enums normally require a type, but the parser may have an 1565 * option to allow missing type, and then we provide a 1566 * sensible default. 1567 */ 1568 ct->type.st = fb_int; 1569 ct->type.type = vt_scalar_type; 1570 } else if (ct->type.type == vt_scalar_type) { 1571 ct->type.st = map_scalar_token_type(ct->type.t); 1572 } else { 1573 /* Spec does not mention boolean type in enum, but we allow it. */ 1574 error_sym(P, &ct->symbol, "enum type must be a scalar integral type or bool"); 1575 return -1; 1576 } 1577 ct->size = sizeof_scalar_type(ct->type.st); 1578 ct->align = (uint16_t)ct->size; 1579 } else { 1580 if (ct->type.type) { 1581 error_sym(P, &ct->symbol, "unions cannot have a type, they are always enumerated as ubyte"); 1582 return -1; 1583 } 1584 /* 1585 * We preprocess unions as enums to get the value assignments. 1586 * The type field is not documented, but generated output from 1587 * flatc suggests ubyte. We use a an injected token to represent 1588 * the ubyte type so we do not have to hardcode elsewhere. 1589 */ 1590 ct->type.type = vt_scalar_type; 1591 ct->type.st = fb_ubyte; 1592 /* 1593 * The union field use the type field and not the offset field 1594 * to define its size because type.type is scalar. 1595 */ 1596 ct->size = sizeof_scalar_type(fb_ubyte); 1597 ct->align = (uint16_t)ct->size; 1598 } 1599 1600 ct->metadata_flags = process_metadata(P, ct->metadata, fb_f_bit_flags, knowns); 1601 if (ct->metadata_flags & fb_f_bit_flags) { 1602 bit_flags = 1; 1603 index.type = vt_uint; 1604 index.u = 0; 1605 } 1606 1607 if (ct->type.st == fb_bool) { 1608 index.b = 0; 1609 index.type = vt_bool; 1610 } else { 1611 index.i = 0; 1612 index.type = vt_int; 1613 if (fb_coerce_scalar_type(P, (fb_symbol_t *)ct, ct->type.st, &index)) { 1614 error(P, "internal error: unexpected conversion failure on enum 0 index"); 1615 return -1; 1616 } 1617 } 1618 old_index = index; 1619 1620 for (sym = ct->members; sym; sym = sym->link, first = 0) { 1621 member = (fb_member_t *)sym; 1622 if ((old = define_fb_symbol(&ct->index, sym))) { 1623 if (old->ident == &P->t_none) { 1624 /* 1625 * Parser injects `NONE` as the first union member and 1626 * it therefore gets index 0. Additional use of NONE 1627 * will fail. 1628 */ 1629 error_sym(P, sym, "'NONE' is a predefined value"); 1630 member->type.type = vt_invalid; 1631 continue; 1632 } 1633 error_sym_2(P, sym, "value already defined here", old); 1634 member->type.type = vt_invalid; 1635 continue; 1636 } 1637 if (sym->kind != fb_is_member) { 1638 error_sym(P, sym, "internal error: enum value type expected"); 1639 return -1; 1640 } 1641 /* Enum / union values cannot have metadata. */ 1642 assert(member->metadata == 0); 1643 if (is_union) { 1644 if (member->symbol.ident == &P->t_none) { 1645 /* Handle implicit NONE specially. */ 1646 member->type.type = vt_missing; 1647 } else if (member->type.type == vt_string_type) { 1648 member->size = 0; 1649 } else if (member->type.type != vt_type_ref) { 1650 if (member->type.type != vt_invalid) { 1651 error_sym(P, sym, "union member type must be string or a reference to a table or a struct"); 1652 member->type.type = vt_invalid; 1653 } 1654 continue; 1655 } else { 1656 type_sym = lookup_type_reference(P, ct->scope, member->type.ref); 1657 if (!type_sym) { 1658 error_ref_sym(P, member->type.ref, "unknown type reference used with union member", sym); 1659 member->type.type = vt_invalid; 1660 continue; 1661 } else { 1662 if (type_sym->kind != fb_is_table && type_sym->kind != fb_is_struct) { 1663 error_sym_2(P, sym, "union member type reference must be a table or a struct, defined here", type_sym); 1664 member->type.type = vt_invalid; 1665 continue; 1666 } 1667 member->type.type = vt_compound_type_ref; 1668 member->type.ct = (fb_compound_type_t*)type_sym; 1669 /* Symbols have no size. */ 1670 member->size = 0; 1671 } 1672 } 1673 } 1674 if (!member->value.type && !first) { 1675 if (index.type == vt_uint) { 1676 if (ct->type.st == fb_long && index.u == UINT64_MAX) { 1677 /* Not captured by range check. */ 1678 error_sym(P, sym, "64-bit unsigned int overflow"); 1679 } 1680 index.u = index.u + 1; 1681 } else if (index.type == vt_int && !first) { 1682 if (ct->type.st == fb_long && index.i == INT64_MAX) { 1683 /* Not captured by range check. */ 1684 error_sym(P, sym, "64-bit signed int overflow"); 1685 } 1686 index.i = index.i + 1; 1687 } else if (index.type == vt_bool && !first) { 1688 if (index.b == 1) { 1689 error_sym(P, sym, "boolean overflow: cannot enumerate past true"); 1690 } 1691 index.b = 1; 1692 } 1693 } 1694 if (bit_flags) { 1695 if (member->value.type) { 1696 if (member->value.type != vt_uint) { 1697 error_sym(P, sym, "enum value must be unsigned int when used with 'bit_flags'"); 1698 return -1; 1699 } else { 1700 index = member->value; 1701 } 1702 } 1703 if (index.u >= sizeof_scalar_type(ct->type.st) * 8) { 1704 error_sym(P, sym, "enum value out of range when used with 'bit_flags'"); 1705 return -1; 1706 } 1707 member->value.u = UINT64_C(1) << index.u; 1708 member->value.type = vt_uint; 1709 if (fb_coerce_scalar_type(P, sym, ct->type.st, &member->value)) { 1710 /* E.g. enumval = 15 causes signed overflow with short. */ 1711 error_sym(P, sym, "enum value out of range when used with 'bit_flags'"); 1712 return -1; 1713 } 1714 } else { 1715 if (member->value.type) { 1716 index = member->value; 1717 } 1718 /* 1719 * Captures errors in user assigned values. Also captures 1720 * overflow on auto-increment on all types except maximum 1721 * representation size, i.e. long or ulong which we handled 1722 * above. 1723 */ 1724 if (fb_coerce_scalar_type(P, sym, ct->type.st, &index)) { 1725 return -1; 1726 } 1727 member->value = index; 1728 } 1729 if (!first && P->opts.ascending_enum) { 1730 /* Without ascending enum we also allow duplicate values (but not names). */ 1731 if ((index.type == vt_uint && index.u <= old_index.u) || 1732 (index.type == vt_int && index.i <= old_index.i)) { 1733 if (is_union && old_index.u == 0) { 1734 /* 1735 * The user explicitly assigned zero, or less, to the first 1736 * element (here second element after parser injecting 1737 * the NONE element). 1738 */ 1739 error_sym(P, sym, "union values must be positive, 0 is reserved for implicit 'NONE'"); 1740 member->value.type = vt_invalid; 1741 return -1; 1742 } 1743 error_sym(P, sym, "enum values must be in ascending order"); 1744 member->value.type = vt_invalid; 1745 return -1; 1746 } 1747 if (index.type == vt_bool && index.b <= old_index.b) { 1748 error_sym(P, sym, "enum of type bool can only enumerate from false (0) to true (1)"); 1749 member->value.type = vt_invalid; 1750 return -1; 1751 } 1752 } 1753 old_index = index; 1754 if (add_to_value_set(&ct->value_set, &member->value)) { 1755 if (is_union) { 1756 error_sym(P, sym, "union members require unique positive values (0 being reserved for 'NONE'"); 1757 member->value.type = vt_invalid; 1758 return -1; 1759 } else { 1760 /* 1761 * With ascending enums this won't happen, but 1762 * otherwise flag secondary values so we can remove them 1763 * from inverse name mappings in code gen. 1764 */ 1765 member->symbol.flags |= fb_duplicate; 1766 } 1767 } 1768 if (member->metadata) { 1769 error_sym(P, sym, "enum values cannot have attributes"); 1770 /* Non-fatal. */ 1771 continue; 1772 } 1773 } 1774 return 0; 1775 } 1776 1777 static inline int process_union(fb_parser_t *P, fb_compound_type_t *ct) 1778 { 1779 return process_enum(P, ct); 1780 } 1781 1782 int fb_build_schema(fb_parser_t *P) 1783 { 1784 fb_schema_t *S = &P->schema; 1785 fb_symbol_t *sym, *old_sym; 1786 fb_name_t *old_name; 1787 fb_compound_type_t *ct; 1788 fb_attribute_t *a; 1789 1790 /* Make sure self is visible at this point in time. */ 1791 assert(ptr_set_exists(&P->schema.visible_schema, &P->schema)); 1792 for (sym = S->symbols; sym; sym = sym->link) { 1793 switch (sym->kind) { 1794 case fb_is_table: 1795 case fb_is_enum: 1796 case fb_is_union: 1797 case fb_is_struct: 1798 case fb_is_rpc_service: 1799 ct = (fb_compound_type_t *)sym; 1800 set_type_hash(ct); 1801 ct->schema = &P->schema; 1802 if (ct->scope && (old_sym = define_fb_symbol(&ct->scope->symbol_index, sym))) { 1803 error_sym_2(P, sym, "symbol already defined here", old_sym); 1804 } 1805 } 1806 } 1807 1808 /* 1809 * Known attributes will be pre-defined if not provided by the 1810 * user. After that point, all attribute references must be 1811 * defined. 1812 */ 1813 for (a = (fb_attribute_t *)S->attributes; a; a = (fb_attribute_t *)a->name.link) { 1814 if ((old_name = define_fb_name(&S->root_schema->attribute_index, &a->name))) { 1815 /* 1816 * Allow attributes to be defined multiple times, including 1817 * known attributes. 1818 */ 1819 #if 0 1820 error_name(P, &a->name, "attribute already defined"); 1821 #endif 1822 } 1823 } 1824 install_known_attributes(P); 1825 1826 if (!P->opts.hide_later_enum) { 1827 for (sym = S->symbols; sym; sym = sym->link) { 1828 switch (sym->kind) { 1829 case fb_is_enum: 1830 ct = (fb_compound_type_t *)sym; 1831 if (process_enum(P, ct)) { 1832 ct->type.type = vt_invalid; 1833 continue; 1834 } 1835 break; 1836 default: 1837 continue; 1838 } 1839 } 1840 } 1841 1842 /* 1843 * Resolve type references both earlier and later than point of 1844 * reference. This also supports recursion for tables and unions. 1845 */ 1846 for (sym = S->symbols; sym; sym = sym->link) { 1847 switch (sym->kind) { 1848 case fb_is_struct: 1849 ct = (fb_compound_type_t *)sym; 1850 if (process_struct(P, ct)) { 1851 ct->type.type = vt_invalid; 1852 continue; 1853 } 1854 break; 1855 case fb_is_table: 1856 /* Handle after structs and enums. */ 1857 continue; 1858 case fb_is_rpc_service: 1859 /* 1860 * Also handle rpc_service later like tables, just in case 1861 * we allow non-table types in request/response type. 1862 */ 1863 continue; 1864 case fb_is_enum: 1865 if (P->opts.hide_later_enum) { 1866 ct = (fb_compound_type_t *)sym; 1867 if (process_enum(P, ct)) { 1868 ct->type.type = vt_invalid; 1869 continue; 1870 } 1871 } 1872 break; 1873 case fb_is_union: 1874 ct = (fb_compound_type_t *)sym; 1875 if (process_union(P, ct)) { 1876 ct->type.type = vt_invalid; 1877 continue; 1878 } 1879 break; 1880 default: 1881 error_sym(P, sym, "internal error: unexpected symbol at schema level"); 1882 return -1; 1883 } 1884 } 1885 for (sym = P->schema.symbols; sym; sym = sym->link) { 1886 switch (sym->kind) { 1887 case fb_is_struct: 1888 /* 1889 * Structs need two stages, first process symbols, then 1890 * analyze for size, alignment, and circular references. 1891 */ 1892 ct = (fb_compound_type_t *)sym; 1893 if (ct->type.type != vt_invalid && analyze_struct(P, ct)) { 1894 ct->type.type = vt_invalid; 1895 continue; 1896 } 1897 break; 1898 default: 1899 continue; 1900 } 1901 } 1902 for (sym = P->schema.symbols; sym; sym = sym->link) { 1903 switch (sym->kind) { 1904 case fb_is_table: 1905 ct = (fb_compound_type_t *)sym; 1906 /* Only now is the full struct size available. */ 1907 if (ct->type.type != vt_invalid && process_table(P, ct)) { 1908 ct->type.type = vt_invalid; 1909 continue; 1910 } 1911 break; 1912 case fb_is_rpc_service: 1913 ct = (fb_compound_type_t *)sym; 1914 /* Only now is the full struct size available. */ 1915 if (ct->type.type != vt_invalid && process_rpc_service(P, ct)) { 1916 ct->type.type = vt_invalid; 1917 continue; 1918 } 1919 } 1920 } 1921 for (sym = P->schema.symbols; sym; sym = sym->link) { 1922 switch (sym->kind) { 1923 case fb_is_table: 1924 ct = (fb_compound_type_t *)sym; 1925 /* 1926 * Some table attributes depend on attributes on members and 1927 * therefore can only be validated after procesing. 1928 */ 1929 if (ct->type.type != vt_invalid && validate_table_attr(P, ct)) { 1930 ct->type.type = vt_invalid; 1931 continue; 1932 } 1933 } 1934 } 1935 revert_order(&P->schema.ordered_structs); 1936 if (!S->root_type.name) { 1937 if (P->opts.require_root_type) { 1938 error(P, "root type not declared"); 1939 } 1940 } else { 1941 sym = S->root_type.type = lookup_type_reference(P, 1942 S->root_type.scope, S->root_type.name); 1943 if (!sym) { 1944 error_ref(P, S->root_type.name, "root type not found"); 1945 } else if (P->opts.allow_struct_root) { 1946 if (sym->kind != fb_is_struct && sym->kind != fb_is_table) { 1947 error_ref(P, S->root_type.name, "root type must be a struct or a table"); 1948 } else { 1949 S->root_type.type = sym; 1950 } 1951 } else { 1952 if (sym->kind != fb_is_table) { 1953 error_ref(P, S->root_type.name, "root type must be a table"); 1954 } else { 1955 S->root_type.type = sym; 1956 } 1957 } 1958 S->root_type.name = 0; 1959 } 1960 P->has_schema = !P->failed; 1961 return P->failed; 1962 }