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