Best effort parsing of .proto declarations, with the aim to turn them in the closest corresponding FlatBuffer equivalent. We parse everything as identifiers instead of keywords, since we don't want protobuf keywords to become invalid identifiers in FlatBuffers.
| 2686 | // We parse everything as identifiers instead of keywords, since we don't |
| 2687 | // want protobuf keywords to become invalid identifiers in FlatBuffers. |
| 2688 | CheckedError Parser::ParseProtoDecl() { |
| 2689 | bool isextend = IsIdent("extend"); |
| 2690 | if (IsIdent("package")) { |
| 2691 | // These are identical in syntax to FlatBuffer's namespace decl. |
| 2692 | ECHECK(ParseNamespace()); |
| 2693 | } else if (IsIdent("message") || isextend) { |
| 2694 | std::vector<std::string> struct_comment = doc_comment_; |
| 2695 | NEXT(); |
| 2696 | StructDef *struct_def = nullptr; |
| 2697 | Namespace *parent_namespace = nullptr; |
| 2698 | if (isextend) { |
| 2699 | if (Is('.')) NEXT(); // qualified names may start with a . ? |
| 2700 | auto id = attribute_; |
| 2701 | EXPECT(kTokenIdentifier); |
| 2702 | ECHECK(ParseNamespacing(&id, nullptr)); |
| 2703 | struct_def = LookupCreateStruct(id, false); |
| 2704 | if (!struct_def) |
| 2705 | return Error("cannot extend unknown message type: " + id); |
| 2706 | } else { |
| 2707 | std::string name = attribute_; |
| 2708 | EXPECT(kTokenIdentifier); |
| 2709 | ECHECK(StartStruct(name, &struct_def)); |
| 2710 | // Since message definitions can be nested, we create a new namespace. |
| 2711 | auto ns = new Namespace(); |
| 2712 | // Copy of current namespace. |
| 2713 | *ns = *current_namespace_; |
| 2714 | // But with current message name. |
| 2715 | ns->components.push_back(name); |
| 2716 | ns->from_table++; |
| 2717 | parent_namespace = current_namespace_; |
| 2718 | current_namespace_ = UniqueNamespace(ns); |
| 2719 | } |
| 2720 | struct_def->doc_comment = struct_comment; |
| 2721 | ECHECK(ParseProtoFields(struct_def, isextend, false)); |
| 2722 | if (!isextend) { current_namespace_ = parent_namespace; } |
| 2723 | if (Is(';')) NEXT(); |
| 2724 | } else if (IsIdent("enum")) { |
| 2725 | // These are almost the same, just with different terminator: |
| 2726 | EnumDef *enum_def; |
| 2727 | ECHECK(ParseEnum(false, &enum_def)); |
| 2728 | if (Is(';')) NEXT(); |
| 2729 | // Temp: remove any duplicates, as .fbs files can't handle them. |
| 2730 | enum_def->RemoveDuplicates(); |
| 2731 | } else if (IsIdent("syntax")) { // Skip these. |
| 2732 | NEXT(); |
| 2733 | EXPECT('='); |
| 2734 | EXPECT(kTokenStringConstant); |
| 2735 | EXPECT(';'); |
| 2736 | } else if (IsIdent("option")) { // Skip these. |
| 2737 | ECHECK(ParseProtoOption()); |
| 2738 | EXPECT(';'); |
| 2739 | } else if (IsIdent("service")) { // Skip these. |
| 2740 | NEXT(); |
| 2741 | EXPECT(kTokenIdentifier); |
| 2742 | ECHECK(ParseProtoCurliesOrIdent()); |
| 2743 | } else { |
| 2744 | return Error("don\'t know how to parse .proto declaration starting with " + |
| 2745 | TokenToStringId(token_)); |
nothing calls this directly
no test coverage detected