File indexing completed on 2026-09-10 09:12:04
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #ifndef GOOGLE_PROTOBUF_COMPILER_PARSER_H__
0015 #define GOOGLE_PROTOBUF_COMPILER_PARSER_H__
0016
0017 #include <cstdint>
0018 #include <string>
0019 #include <type_traits>
0020 #include <utility>
0021
0022 #include "absl/container/flat_hash_map.h"
0023 #include "absl/strings/string_view.h"
0024 #include "google/protobuf/descriptor.h"
0025 #include "google/protobuf/descriptor.pb.h"
0026 #include "google/protobuf/io/tokenizer.h"
0027 #include "google/protobuf/repeated_field.h"
0028 #include "google/protobuf/repeated_ptr_field.h"
0029
0030
0031 #include "google/protobuf/port_def.inc"
0032
0033 namespace google {
0034 namespace protobuf {
0035
0036 class Message;
0037
0038 namespace compiler {
0039
0040
0041 class Parser;
0042 class SourceLocationTable;
0043
0044
0045
0046
0047
0048
0049
0050
0051 class PROTOBUF_EXPORT Parser final {
0052 public:
0053 Parser();
0054 Parser(const Parser&) = delete;
0055 Parser& operator=(const Parser&) = delete;
0056 ~Parser();
0057
0058
0059
0060 bool Parse(io::Tokenizer* input, FileDescriptorProto* file);
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071 void RecordSourceLocationsTo(SourceLocationTable* location_table) {
0072 source_location_table_ = location_table;
0073 }
0074
0075
0076
0077 void RecordErrorsTo(io::ErrorCollector* error_collector) {
0078 error_collector_ = error_collector;
0079 }
0080
0081
0082
0083 absl::string_view GetSyntaxIdentifier() { return syntax_identifier_; }
0084
0085
0086
0087
0088
0089 void SetRequireSyntaxIdentifier(bool value) {
0090 require_syntax_identifier_ = value;
0091 }
0092
0093
0094
0095
0096
0097
0098
0099
0100
0101 void SetStopAfterSyntaxIdentifier(bool value) {
0102 stop_after_syntax_identifier_ = value;
0103 }
0104
0105 private:
0106 class LocationRecorder;
0107 struct MapField;
0108
0109
0110
0111
0112
0113
0114
0115
0116
0117
0118
0119
0120
0121 void SkipStatement();
0122
0123
0124
0125 void SkipRestOfBlock();
0126
0127
0128
0129
0130
0131
0132
0133 inline bool AtEnd();
0134
0135
0136 inline bool LookingAt(absl::string_view text);
0137
0138 inline bool LookingAtType(io::Tokenizer::TokenType token_type);
0139
0140
0141
0142 bool TryConsume(absl::string_view text);
0143
0144
0145
0146
0147
0148
0149
0150 class ErrorMaker {
0151 using StorageT = void*;
0152
0153 public:
0154 template <typename F,
0155 typename = std::enable_if_t<std::is_same<
0156 std::string, decltype(std::declval<F>()())>::value>>
0157 ErrorMaker(F f) {
0158 static_assert(sizeof(F) <= sizeof(StorageT), "");
0159 static_assert(alignof(F) <= alignof(StorageT), "");
0160 static_assert(std::is_trivially_destructible<F>::value, "");
0161 ::new (static_cast<void*>(storage_)) F(f);
0162 func_ = [](const void* p) { return (*reinterpret_cast<const F*>(p))(); };
0163 }
0164
0165 ErrorMaker(const char* error) : error_(error), func_(nullptr) {}
0166
0167 std::string get() const { return func_ ? func_(storage_) : error_; }
0168
0169 private:
0170 union {
0171 alignas(StorageT) char storage_[sizeof(StorageT)];
0172 const char* error_;
0173 };
0174 std::string (*func_)(const void*);
0175 };
0176
0177
0178
0179
0180
0181
0182 bool Consume(absl::string_view text, ErrorMaker error);
0183
0184
0185 bool Consume(absl::string_view text);
0186
0187 bool ConsumeIdentifier(std::string* output, ErrorMaker error);
0188
0189 bool ConsumeInteger(int* output, ErrorMaker error);
0190
0191 bool ConsumeSignedInteger(int* output, ErrorMaker error);
0192
0193
0194 bool ConsumeInteger64(uint64_t max_value, uint64_t* output, ErrorMaker error);
0195
0196
0197 bool TryConsumeInteger64(uint64_t max_value, uint64_t* output);
0198
0199
0200 bool ConsumeNumber(double* output, ErrorMaker error);
0201
0202 bool ConsumeString(std::string* output, ErrorMaker error);
0203
0204
0205
0206
0207
0208
0209
0210
0211
0212
0213 bool TryConsumeEndOfDeclaration(absl::string_view text,
0214 const LocationRecorder* location);
0215 bool TryConsumeEndOfDeclarationFinishScope(absl::string_view text,
0216 const LocationRecorder* location);
0217
0218 bool ConsumeEndOfDeclaration(absl::string_view text,
0219 const LocationRecorder* location);
0220
0221
0222
0223
0224
0225 PROTOBUF_NOINLINE void RecordError(int line, int column, ErrorMaker error);
0226
0227
0228
0229 PROTOBUF_NOINLINE void RecordError(ErrorMaker error);
0230
0231
0232 PROTOBUF_NOINLINE void RecordWarning(int line, int column, ErrorMaker error);
0233
0234
0235
0236 PROTOBUF_NOINLINE void RecordWarning(ErrorMaker error);
0237
0238
0239
0240
0241
0242
0243 class PROTOBUF_EXPORT LocationRecorder {
0244 public:
0245
0246 LocationRecorder(Parser* parser);
0247
0248
0249
0250
0251
0252
0253 LocationRecorder(const LocationRecorder& parent);
0254
0255
0256 LocationRecorder(const LocationRecorder& parent, int path1);
0257 LocationRecorder(const LocationRecorder& parent, int path1, int path2);
0258
0259
0260 LocationRecorder(const LocationRecorder& parent, int path1,
0261 SourceCodeInfo* source_code_info);
0262
0263 ~LocationRecorder();
0264
0265
0266
0267 void AddPath(int path_component);
0268
0269
0270
0271
0272 void StartAt(const io::Tokenizer::Token& token);
0273
0274
0275 void StartAt(const LocationRecorder& other);
0276
0277
0278
0279
0280 void EndAt(const io::Tokenizer::Token& token);
0281
0282
0283
0284
0285
0286 void RecordLegacyLocation(
0287 const Message* descriptor,
0288 DescriptorPool::ErrorCollector::ErrorLocation location);
0289 void RecordLegacyImportLocation(const Message* descriptor,
0290 const std::string& name);
0291
0292
0293 int CurrentPathSize() const;
0294
0295
0296
0297
0298
0299
0300
0301 void AttachComments(std::string* leading, std::string* trailing,
0302 std::vector<std::string>* detached_comments) const;
0303
0304 private:
0305 Parser* parser_;
0306 SourceCodeInfo* source_code_info_;
0307 SourceCodeInfo::Location* location_;
0308
0309 void Init(const LocationRecorder& parent, SourceCodeInfo* source_code_info);
0310 };
0311
0312
0313
0314
0315
0316
0317
0318 bool ParseSyntaxIdentifier(const FileDescriptorProto* file,
0319 const LocationRecorder& parent);
0320
0321
0322
0323
0324
0325
0326
0327
0328
0329
0330
0331
0332 bool ParseTopLevelStatement(FileDescriptorProto* file,
0333 const LocationRecorder& root_location);
0334
0335
0336 bool ParseMessageDefinition(DescriptorProto* message,
0337 const SymbolVisibility& visibility,
0338 const LocationRecorder& message_location,
0339 const FileDescriptorProto* containing_file);
0340 bool ParseEnumDefinition(EnumDescriptorProto* enum_type,
0341 const SymbolVisibility& visibility,
0342 const LocationRecorder& enum_location,
0343 const FileDescriptorProto* containing_file);
0344 bool ParseServiceDefinition(ServiceDescriptorProto* service,
0345 const LocationRecorder& service_location,
0346 const FileDescriptorProto* containing_file);
0347 bool ParsePackage(FileDescriptorProto* file,
0348 const LocationRecorder& root_location,
0349 const FileDescriptorProto* containing_file);
0350 bool ParseImport(RepeatedPtrField<std::string>* dependency,
0351 RepeatedPtrField<std::string>* option_dependency,
0352 RepeatedField<int32_t>* public_dependency,
0353 RepeatedField<int32_t>* weak_dependency,
0354 const LocationRecorder& root_location,
0355 const FileDescriptorProto* containing_file);
0356
0357
0358
0359
0360 bool ParseMessageBlock(DescriptorProto* message,
0361 const LocationRecorder& message_location,
0362 const FileDescriptorProto* containing_file);
0363 bool ParseEnumBlock(EnumDescriptorProto* enum_type,
0364 const LocationRecorder& enum_location,
0365 const FileDescriptorProto* containing_file);
0366 bool ParseServiceBlock(ServiceDescriptorProto* service,
0367 const LocationRecorder& service_location,
0368 const FileDescriptorProto* containing_file);
0369
0370
0371
0372 bool ParseMessageStatement(DescriptorProto* message,
0373 const LocationRecorder& message_location,
0374 const FileDescriptorProto* containing_file);
0375 bool ParseEnumStatement(EnumDescriptorProto* message,
0376 const LocationRecorder& enum_location,
0377 const FileDescriptorProto* containing_file);
0378 bool ParseServiceStatement(ServiceDescriptorProto* message,
0379 const LocationRecorder& service_location,
0380 const FileDescriptorProto* containing_file);
0381
0382
0383
0384
0385
0386
0387
0388
0389
0390 bool ParseMessageField(FieldDescriptorProto* field,
0391 RepeatedPtrField<DescriptorProto>* messages,
0392 const LocationRecorder& parent_location,
0393 int location_field_number_for_nested_type,
0394 const LocationRecorder& field_location,
0395 const FileDescriptorProto* containing_file);
0396
0397
0398
0399 bool ParseMessageFieldNoLabel(FieldDescriptorProto* field,
0400 RepeatedPtrField<DescriptorProto>* messages,
0401 const LocationRecorder& parent_location,
0402 int location_field_number_for_nested_type,
0403 const LocationRecorder& field_location,
0404 const FileDescriptorProto* containing_file);
0405
0406 bool ParseMapType(MapField* map_field, FieldDescriptorProto* field,
0407 LocationRecorder& type_name_location);
0408
0409
0410 bool ParseExtensions(DescriptorProto* message,
0411 const LocationRecorder& extensions_location,
0412 const FileDescriptorProto* containing_file);
0413
0414
0415 bool ParseReserved(DescriptorProto* message,
0416 const LocationRecorder& message_location);
0417 bool ParseReservedNames(DescriptorProto* message,
0418 const LocationRecorder& parent_location);
0419 bool ParseReservedName(std::string* name, ErrorMaker error_message);
0420 bool ParseReservedIdentifiers(DescriptorProto* message,
0421 const LocationRecorder& parent_location);
0422 bool ParseReservedIdentifier(std::string* name, ErrorMaker error_message);
0423 bool ParseReservedNumbers(DescriptorProto* message,
0424 const LocationRecorder& parent_location);
0425 bool ParseReserved(EnumDescriptorProto* message,
0426 const LocationRecorder& message_location);
0427 bool ParseReservedNames(EnumDescriptorProto* message,
0428 const LocationRecorder& parent_location);
0429 bool ParseReservedIdentifiers(EnumDescriptorProto* message,
0430 const LocationRecorder& parent_location);
0431 bool ParseReservedNumbers(EnumDescriptorProto* message,
0432 const LocationRecorder& parent_location);
0433
0434
0435
0436 bool ParseExtend(RepeatedPtrField<FieldDescriptorProto>* extensions,
0437 RepeatedPtrField<DescriptorProto>* messages,
0438 const LocationRecorder& parent_location,
0439 int location_field_number_for_nested_type,
0440 const LocationRecorder& extend_location,
0441 const FileDescriptorProto* containing_file);
0442
0443
0444
0445
0446 bool ParseOneof(OneofDescriptorProto* oneof_decl,
0447 DescriptorProto* containing_type, int oneof_index,
0448 const LocationRecorder& oneof_location,
0449 const LocationRecorder& containing_type_location,
0450 const FileDescriptorProto* containing_file);
0451
0452
0453 bool ParseEnumConstant(EnumValueDescriptorProto* enum_value,
0454 const LocationRecorder& enum_value_location,
0455 const FileDescriptorProto* containing_file);
0456
0457
0458
0459 bool ParseEnumConstantOptions(EnumValueDescriptorProto* value,
0460 const LocationRecorder& enum_value_location,
0461 const FileDescriptorProto* containing_file);
0462
0463
0464 bool ParseServiceMethod(MethodDescriptorProto* method,
0465 const LocationRecorder& method_location,
0466 const FileDescriptorProto* containing_file);
0467
0468
0469 bool ParseMethodOptions(const LocationRecorder& parent_location,
0470 const FileDescriptorProto* containing_file,
0471 int optionsFieldNumber, Message* mutable_options);
0472
0473
0474
0475 bool ParseLabel(FieldDescriptorProto::Label* label,
0476 const LocationRecorder& field_location);
0477
0478
0479
0480 bool ParseType(FieldDescriptorProto::Type* type, std::string* type_name);
0481
0482
0483 bool ParseUserDefinedType(std::string* type_name);
0484
0485
0486
0487 bool ParseFieldOptions(FieldDescriptorProto* field,
0488 const LocationRecorder& field_location,
0489 const FileDescriptorProto* containing_file);
0490
0491
0492
0493 bool ParseDefaultAssignment(FieldDescriptorProto* field,
0494 const LocationRecorder& field_location,
0495 const FileDescriptorProto* containing_file);
0496
0497 bool ParseJsonName(FieldDescriptorProto* field,
0498 const LocationRecorder& field_location,
0499 const FileDescriptorProto* containing_file);
0500
0501 enum OptionStyle {
0502 OPTION_ASSIGNMENT,
0503 OPTION_STATEMENT
0504 };
0505
0506
0507
0508
0509 bool ParseOption(Message* options, const LocationRecorder& options_location,
0510 const FileDescriptorProto* containing_file,
0511 OptionStyle style);
0512
0513
0514
0515
0516
0517 bool ParseOptionNamePart(UninterpretedOption* uninterpreted_option,
0518 const LocationRecorder& part_location,
0519 const FileDescriptorProto* containing_file);
0520
0521
0522
0523
0524
0525
0526
0527
0528
0529
0530
0531 bool ParseUninterpretedBlock(std::string* value);
0532
0533
0534
0535
0536 bool ParseVisibility(const FileDescriptorProto* containing_file,
0537 SymbolVisibility* out);
0538
0539 struct MapField {
0540
0541 bool is_map_field;
0542
0543 FieldDescriptorProto::Type key_type;
0544 FieldDescriptorProto::Type value_type;
0545
0546 std::string key_type_name;
0547 std::string value_type_name;
0548
0549 MapField() : is_map_field(false) {}
0550 };
0551
0552 void GenerateMapEntry(const MapField& map_field, FieldDescriptorProto* field,
0553 RepeatedPtrField<DescriptorProto>* messages);
0554
0555
0556 bool DefaultToOptionalFields() const {
0557 if (syntax_identifier_ == "editions") return true;
0558 return syntax_identifier_ == "proto3";
0559 }
0560
0561 bool ValidateMessage(const DescriptorProto* proto);
0562 bool ValidateEnum(const EnumDescriptorProto* proto);
0563
0564
0565
0566 io::Tokenizer* input_;
0567 io::ErrorCollector* error_collector_;
0568 SourceCodeInfo* source_code_info_;
0569 SourceLocationTable* source_location_table_;
0570 bool had_errors_;
0571 bool require_syntax_identifier_;
0572 bool stop_after_syntax_identifier_;
0573 std::string syntax_identifier_;
0574 Edition edition_ = Edition::EDITION_UNKNOWN;
0575 int recursion_depth_;
0576
0577
0578
0579 std::string upcoming_doc_comments_;
0580
0581
0582
0583
0584
0585
0586 std::vector<std::string> upcoming_detached_comments_;
0587 };
0588
0589
0590
0591
0592
0593
0594
0595
0596
0597 class PROTOBUF_EXPORT SourceLocationTable {
0598 public:
0599 SourceLocationTable();
0600 ~SourceLocationTable();
0601
0602
0603
0604
0605
0606
0607 bool Find(const Message* descriptor,
0608 DescriptorPool::ErrorCollector::ErrorLocation location, int* line,
0609 int* column) const;
0610 bool FindImport(const Message* descriptor, absl::string_view name, int* line,
0611 int* column) const;
0612
0613
0614 void Add(const Message* descriptor,
0615 DescriptorPool::ErrorCollector::ErrorLocation location, int line,
0616 int column);
0617 void AddImport(const Message* descriptor, const std::string& name, int line,
0618 int column);
0619
0620
0621 void Clear();
0622
0623 private:
0624 using LocationMap = absl::flat_hash_map<
0625 std::pair<const Message*, DescriptorPool::ErrorCollector::ErrorLocation>,
0626 std::pair<int, int>>;
0627 LocationMap location_map_;
0628 absl::flat_hash_map<std::pair<const Message*, std::string>,
0629 std::pair<int, int>>
0630 import_location_map_;
0631 };
0632
0633 }
0634 }
0635 }
0636
0637 #include "google/protobuf/port_undef.inc"
0638
0639 #endif