#ifndef GOOGLE_PROTOBUF_COMPILER_PARSER_H__
#define GOOGLE_PROTOBUF_COMPILER_PARSER_H__
#include <cstdint>
#include <map>
#include <string>
#include <utility>
#include <google/protobuf/descriptor.h>
#include <google/protobuf/descriptor.pb.h>
#include <google/protobuf/io/tokenizer.h>
#include <google/protobuf/repeated_field.h>
#include <google/protobuf/port_def.inc>
namespace google {
namespace protobuf {
class Message;
namespace compiler {
class Parser;
class SourceLocationTable;
class PROTOBUF_EXPORT Parser {
public:
Parser();
~Parser();
bool Parse(io::Tokenizer* input, FileDescriptorProto* file);
void RecordSourceLocationsTo(SourceLocationTable* location_table) {
source_location_table_ = location_table;
}
void RecordErrorsTo(io::ErrorCollector* error_collector) {
error_collector_ = error_collector;
}
const std::string& GetSyntaxIdentifier() { return syntax_identifier_; }
void SetRequireSyntaxIdentifier(bool value) {
require_syntax_identifier_ = value;
}
void SetStopAfterSyntaxIdentifier(bool value) {
stop_after_syntax_identifier_ = value;
}
private:
class LocationRecorder;
struct MapField;
void SkipStatement();
void SkipRestOfBlock();
inline bool AtEnd();
inline bool LookingAt(const char* text);
inline bool LookingAtType(io::Tokenizer::TokenType token_type);
bool TryConsume(const char* text);
bool Consume(const char* text, const char* error);
bool Consume(const char* text);
bool ConsumeIdentifier(std::string* output, const char* error);
bool ConsumeInteger(int* output, const char* error);
bool ConsumeSignedInteger(int* output, const char* error);
bool ConsumeInteger64(uint64_t max_value, uint64_t* output,
const char* error);
bool ConsumeNumber(double* output, const char* error);
bool ConsumeString(std::string* output, const char* error);
bool TryConsumeEndOfDeclaration(const char* text,
const LocationRecorder* location);
bool TryConsumeEndOfDeclarationFinishScope(const char* text,
const LocationRecorder* location);
bool ConsumeEndOfDeclaration(const char* text,
const LocationRecorder* location);
void AddError(int line, int column, const std::string& error);
void AddError(const std::string& error);
void AddWarning(const std::string& warning);
class PROTOBUF_EXPORT LocationRecorder {
public:
LocationRecorder(Parser* parser);
LocationRecorder(const LocationRecorder& parent);
LocationRecorder(const LocationRecorder& parent, int path1);
LocationRecorder(const LocationRecorder& parent, int path1, int path2);
LocationRecorder(const LocationRecorder& parent, int path1,
SourceCodeInfo* source_code_info);
~LocationRecorder();
void AddPath(int path_component);
void StartAt(const io::Tokenizer::Token& token);
void StartAt(const LocationRecorder& other);
void EndAt(const io::Tokenizer::Token& token);
void RecordLegacyLocation(
const Message* descriptor,
DescriptorPool::ErrorCollector::ErrorLocation location);
void RecordLegacyImportLocation(const Message* descriptor,
const std::string& name);
int CurrentPathSize() const;
void AttachComments(std::string* leading, std::string* trailing,
std::vector<std::string>* detached_comments) const;
private:
Parser* parser_;
SourceCodeInfo* source_code_info_;
SourceCodeInfo::Location* location_;
void Init(const LocationRecorder& parent, SourceCodeInfo* source_code_info);
};
bool ParseSyntaxIdentifier(const LocationRecorder& parent);
bool ParseTopLevelStatement(FileDescriptorProto* file,
const LocationRecorder& root_location);
bool ParseMessageDefinition(DescriptorProto* message,
const LocationRecorder& message_location,
const FileDescriptorProto* containing_file);
bool ParseEnumDefinition(EnumDescriptorProto* enum_type,
const LocationRecorder& enum_location,
const FileDescriptorProto* containing_file);
bool ParseServiceDefinition(ServiceDescriptorProto* service,
const LocationRecorder& service_location,
const FileDescriptorProto* containing_file);
bool ParsePackage(FileDescriptorProto* file,
const LocationRecorder& root_location,
const FileDescriptorProto* containing_file);
bool ParseImport(RepeatedPtrField<std::string>* dependency,
RepeatedField<int32_t>* public_dependency,
RepeatedField<int32_t>* weak_dependency,
const LocationRecorder& root_location,
const FileDescriptorProto* containing_file);
bool ParseMessageBlock(DescriptorProto* message,
const LocationRecorder& message_location,
const FileDescriptorProto* containing_file);
bool ParseEnumBlock(EnumDescriptorProto* enum_type,
const LocationRecorder& enum_location,
const FileDescriptorProto* containing_file);
bool ParseServiceBlock(ServiceDescriptorProto* service,
const LocationRecorder& service_location,
const FileDescriptorProto* containing_file);
bool ParseMessageStatement(DescriptorProto* message,
const LocationRecorder& message_location,
const FileDescriptorProto* containing_file);
bool ParseEnumStatement(EnumDescriptorProto* message,
const LocationRecorder& enum_location,
const FileDescriptorProto* containing_file);
bool ParseServiceStatement(ServiceDescriptorProto* message,
const LocationRecorder& service_location,
const FileDescriptorProto* containing_file);
bool ParseMessageField(FieldDescriptorProto* field,
RepeatedPtrField<DescriptorProto>* messages,
const LocationRecorder& parent_location,
int location_field_number_for_nested_type,
const LocationRecorder& field_location,
const FileDescriptorProto* containing_file);
bool ParseMessageFieldNoLabel(FieldDescriptorProto* field,
RepeatedPtrField<DescriptorProto>* messages,
const LocationRecorder& parent_location,
int location_field_number_for_nested_type,
const LocationRecorder& field_location,
const FileDescriptorProto* containing_file);
bool ParseMapType(MapField* map_field, FieldDescriptorProto* field,
LocationRecorder& type_name_location);
bool ParseExtensions(DescriptorProto* message,
const LocationRecorder& extensions_location,
const FileDescriptorProto* containing_file);
bool ParseReserved(DescriptorProto* message,
const LocationRecorder& message_location);
bool ParseReservedNames(DescriptorProto* message,
const LocationRecorder& parent_location);
bool ParseReservedNumbers(DescriptorProto* message,
const LocationRecorder& parent_location);
bool ParseReserved(EnumDescriptorProto* message,
const LocationRecorder& message_location);
bool ParseReservedNames(EnumDescriptorProto* message,
const LocationRecorder& parent_location);
bool ParseReservedNumbers(EnumDescriptorProto* message,
const LocationRecorder& parent_location);
bool ParseExtend(RepeatedPtrField<FieldDescriptorProto>* extensions,
RepeatedPtrField<DescriptorProto>* messages,
const LocationRecorder& parent_location,
int location_field_number_for_nested_type,
const LocationRecorder& extend_location,
const FileDescriptorProto* containing_file);
bool ParseOneof(OneofDescriptorProto* oneof_decl,
DescriptorProto* containing_type, int oneof_index,
const LocationRecorder& oneof_location,
const LocationRecorder& containing_type_location,
const FileDescriptorProto* containing_file);
bool ParseEnumConstant(EnumValueDescriptorProto* enum_value,
const LocationRecorder& enum_value_location,
const FileDescriptorProto* containing_file);
bool ParseEnumConstantOptions(EnumValueDescriptorProto* value,
const LocationRecorder& enum_value_location,
const FileDescriptorProto* containing_file);
bool ParseServiceMethod(MethodDescriptorProto* method,
const LocationRecorder& method_location,
const FileDescriptorProto* containing_file);
bool ParseMethodOptions(const LocationRecorder& parent_location,
const FileDescriptorProto* containing_file,
const int optionsFieldNumber,
Message* mutable_options);
bool ParseLabel(FieldDescriptorProto::Label* label,
const LocationRecorder& field_location);
bool ParseType(FieldDescriptorProto::Type* type, std::string* type_name);
bool ParseUserDefinedType(std::string* type_name);
bool ParseFieldOptions(FieldDescriptorProto* field,
const LocationRecorder& field_location,
const FileDescriptorProto* containing_file);
bool ParseDefaultAssignment(FieldDescriptorProto* field,
const LocationRecorder& field_location,
const FileDescriptorProto* containing_file);
bool ParseJsonName(FieldDescriptorProto* field,
const LocationRecorder& field_location,
const FileDescriptorProto* containing_file);
enum OptionStyle {
OPTION_ASSIGNMENT, OPTION_STATEMENT };
bool ParseOption(Message* options, const LocationRecorder& options_location,
const FileDescriptorProto* containing_file,
OptionStyle style);
bool ParseOptionNamePart(UninterpretedOption* uninterpreted_option,
const LocationRecorder& part_location,
const FileDescriptorProto* containing_file);
bool ParseUninterpretedBlock(std::string* value);
struct MapField {
bool is_map_field;
FieldDescriptorProto::Type key_type;
FieldDescriptorProto::Type value_type;
std::string key_type_name;
std::string value_type_name;
MapField() : is_map_field(false) {}
};
void GenerateMapEntry(const MapField& map_field, FieldDescriptorProto* field,
RepeatedPtrField<DescriptorProto>* messages);
bool DefaultToOptionalFields() const {
return syntax_identifier_ == "proto3";
}
bool ValidateEnum(const EnumDescriptorProto* proto);
io::Tokenizer* input_;
io::ErrorCollector* error_collector_;
SourceCodeInfo* source_code_info_;
SourceLocationTable* source_location_table_; bool had_errors_;
bool require_syntax_identifier_;
bool stop_after_syntax_identifier_;
std::string syntax_identifier_;
std::string upcoming_doc_comments_;
std::vector<std::string> upcoming_detached_comments_;
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Parser);
};
class PROTOBUF_EXPORT SourceLocationTable {
public:
SourceLocationTable();
~SourceLocationTable();
bool Find(const Message* descriptor,
DescriptorPool::ErrorCollector::ErrorLocation location, int* line,
int* column) const;
bool FindImport(const Message* descriptor, const std::string& name, int* line,
int* column) const;
void Add(const Message* descriptor,
DescriptorPool::ErrorCollector::ErrorLocation location, int line,
int column);
void AddImport(const Message* descriptor, const std::string& name, int line,
int column);
void Clear();
private:
typedef std::map<
std::pair<const Message*, DescriptorPool::ErrorCollector::ErrorLocation>,
std::pair<int, int> >
LocationMap;
LocationMap location_map_;
std::map<std::pair<const Message*, std::string>, std::pair<int, int> >
import_location_map_;
};
} } }
#include <google/protobuf/port_undef.inc>
#endif