| 2766 | } |
| 2767 | |
| 2768 | CheckedError Parser::ParseProtoFields(StructDef *struct_def, bool isextend, |
| 2769 | bool inside_oneof) { |
| 2770 | EXPECT('{'); |
| 2771 | while (token_ != '}') { |
| 2772 | if (IsIdent("message") || IsIdent("extend") || IsIdent("enum")) { |
| 2773 | // Nested declarations. |
| 2774 | ECHECK(ParseProtoDecl()); |
| 2775 | } else if (IsIdent("extensions")) { // Skip these. |
| 2776 | NEXT(); |
| 2777 | EXPECT(kTokenIntegerConstant); |
| 2778 | if (Is(kTokenIdentifier)) { |
| 2779 | NEXT(); // to |
| 2780 | NEXT(); // num |
| 2781 | } |
| 2782 | EXPECT(';'); |
| 2783 | } else if (IsIdent("option")) { // Skip these. |
| 2784 | ECHECK(ParseProtoOption()); |
| 2785 | EXPECT(';'); |
| 2786 | } else if (IsIdent("reserved")) { // Skip these. |
| 2787 | NEXT(); |
| 2788 | while (!Is(';')) { NEXT(); } // A variety of formats, just skip. |
| 2789 | NEXT(); |
| 2790 | } else { |
| 2791 | std::vector<std::string> field_comment = doc_comment_; |
| 2792 | // Parse the qualifier. |
| 2793 | bool required = false; |
| 2794 | bool repeated = false; |
| 2795 | bool oneof = false; |
| 2796 | if (!inside_oneof) { |
| 2797 | if (IsIdent("optional")) { |
| 2798 | // This is the default. |
| 2799 | NEXT(); |
| 2800 | } else if (IsIdent("required")) { |
| 2801 | required = true; |
| 2802 | NEXT(); |
| 2803 | } else if (IsIdent("repeated")) { |
| 2804 | repeated = true; |
| 2805 | NEXT(); |
| 2806 | } else if (IsIdent("oneof")) { |
| 2807 | oneof = true; |
| 2808 | NEXT(); |
| 2809 | } else { |
| 2810 | // can't error, proto3 allows decls without any of the above. |
| 2811 | } |
| 2812 | } |
| 2813 | StructDef *anonymous_struct = nullptr; |
| 2814 | EnumDef *oneof_union = nullptr; |
| 2815 | Type type; |
| 2816 | if (IsIdent("group") || oneof) { |
| 2817 | if (!oneof) NEXT(); |
| 2818 | if (oneof && opts.proto_oneof_union) { |
| 2819 | auto name = MakeCamel(attribute_, true) + "Union"; |
| 2820 | ECHECK(StartEnum(name, true, &oneof_union)); |
| 2821 | type = Type(BASE_TYPE_UNION, nullptr, oneof_union); |
| 2822 | } else { |
| 2823 | auto name = "Anonymous" + NumToString(anonymous_counter_++); |
| 2824 | ECHECK(StartStruct(name, &anonymous_struct)); |
| 2825 | type = Type(BASE_TYPE_STRUCT, anonymous_struct); |
nothing calls this directly
no test coverage detected