summaryrefslogtreecommitdiffstats
path: root/contrib/libs/protoc/src/google/protobuf/compiler/parser.cc
diff options
context:
space:
mode:
authornechda <[email protected]>2024-08-29 23:50:27 +0300
committernechda <[email protected]>2024-08-30 00:05:25 +0300
commite10d6638f07a82edae3ea8197b9f5c0affcc07ea (patch)
tree571c38cec05813766a1ad290c9d51ce7ace52919 /contrib/libs/protoc/src/google/protobuf/compiler/parser.cc
parente79b38f2bbbf78d295d1901d2a79f898022d5224 (diff)
Update cpp-protobuf to 22.5
Привет!\ Этот PR переключат cpp & python библиотеки protobuf на версию 22.5 Если у вас возникли проблемы после влития этого PR: 1. Если начали падать канон тесты, то проведите их переканонизацию 2. Прочитайте <https://wiki.yandex-team.ru/users/nechda/obnovlenie-cpp-protobuf-22.5/> страничку с основными изменениями 3. Если страничка в вики не помогла, то пишите в [DEVTOOLSSUPPORT](https://st.yandex-team.ru/DEVTOOLSSUPPORT) 7fecade616c20a841b9e9af7b7998bdfc8d2807d
Diffstat (limited to 'contrib/libs/protoc/src/google/protobuf/compiler/parser.cc')
-rw-r--r--contrib/libs/protoc/src/google/protobuf/compiler/parser.cc398
1 files changed, 219 insertions, 179 deletions
diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/parser.cc b/contrib/libs/protoc/src/google/protobuf/compiler/parser.cc
index 2900d324d21..e244db96cc8 100644
--- a/contrib/libs/protoc/src/google/protobuf/compiler/parser.cc
+++ b/contrib/libs/protoc/src/google/protobuf/compiler/parser.cc
@@ -34,35 +34,43 @@
//
// Recursive descent FTW.
-#include <google/protobuf/compiler/parser.h>
+#include "google/protobuf/compiler/parser.h"
#include <float.h>
#include <cstdint>
#include <limits>
-#include <unordered_map>
-#include <unordered_set>
-
-#include <google/protobuf/stubs/casts.h>
-#include <google/protobuf/stubs/logging.h>
-#include <google/protobuf/stubs/common.h>
-#include <google/protobuf/stubs/strutil.h>
-#include <google/protobuf/descriptor.h>
-#include <google/protobuf/descriptor.pb.h>
-#include <google/protobuf/io/tokenizer.h>
-#include <google/protobuf/wire_format.h>
-#include <google/protobuf/stubs/map_util.h>
-#include <google/protobuf/stubs/hash.h>
+#include <string>
+#include <tuple>
+#include <utility>
+#include <vector>
+
+#include "y_absl/base/casts.h"
+#include "y_absl/container/flat_hash_map.h"
+#include "y_absl/container/flat_hash_set.h"
+#include "y_absl/log/absl_check.h"
+#include "y_absl/log/absl_log.h"
+#include "y_absl/strings/ascii.h"
+#include "y_absl/strings/escaping.h"
+#include "y_absl/strings/str_cat.h"
+#include "y_absl/strings/str_format.h"
+#include "y_absl/strings/string_view.h"
+#include "google/protobuf/descriptor.h"
+#include "google/protobuf/descriptor.pb.h"
+#include "google/protobuf/io/strtod.h"
+#include "google/protobuf/io/tokenizer.h"
+#include "google/protobuf/port.h"
+#include "google/protobuf/wire_format.h"
namespace google {
namespace protobuf {
namespace compiler {
-
-using internal::WireFormat;
-
namespace {
-typedef std::unordered_map<TProtoStringType, FieldDescriptorProto::Type> TypeNameMap;
+using ::google::protobuf::internal::DownCast;
+
+using TypeNameMap =
+ y_absl::flat_hash_map<y_absl::string_view, FieldDescriptorProto::Type>;
const TypeNameMap& GetTypeNameTable() {
static auto* table = new auto([]() {
@@ -93,7 +101,7 @@ const TypeNameMap& GetTypeNameTable() {
// Camel-case the field name and append "Entry" for generated map entry name.
// e.g. map<KeyType, ValueType> foo_map => FooMapEntry
-TProtoStringType MapEntryName(const TProtoStringType& field_name) {
+TProtoStringType MapEntryName(y_absl::string_view field_name) {
TProtoStringType result;
static const char kSuffix[] = "Entry";
result.reserve(field_name.size() + sizeof(kSuffix));
@@ -123,7 +131,7 @@ bool IsLowercase(char c) { return c >= 'a' && c <= 'z'; }
bool IsNumber(char c) { return c >= '0' && c <= '9'; }
-bool IsUpperCamelCase(const TProtoStringType& name) {
+bool IsUpperCamelCase(y_absl::string_view name) {
if (name.empty()) {
return true;
}
@@ -140,7 +148,7 @@ bool IsUpperCamelCase(const TProtoStringType& name) {
return true;
}
-bool IsUpperUnderscore(const TProtoStringType& name) {
+bool IsUpperUnderscore(y_absl::string_view name) {
for (const char c : name) {
if (!IsUppercase(c) && c != '_' && !IsNumber(c)) {
return false;
@@ -149,7 +157,7 @@ bool IsUpperUnderscore(const TProtoStringType& name) {
return true;
}
-bool IsLowerUnderscore(const TProtoStringType& name) {
+bool IsLowerUnderscore(y_absl::string_view name) {
for (const char c : name) {
if (!IsLowercase(c) && c != '_' && !IsNumber(c)) {
return false;
@@ -158,7 +166,7 @@ bool IsLowerUnderscore(const TProtoStringType& name) {
return true;
}
-bool IsNumberFollowUnderscore(const TProtoStringType& name) {
+bool IsNumberFollowUnderscore(y_absl::string_view name) {
for (int i = 1; i < name.length(); i++) {
const char c = name[i];
if (IsNumber(c) && name[i - 1] == '_') {
@@ -193,7 +201,7 @@ Parser::~Parser() {}
// ===================================================================
-inline bool Parser::LookingAt(const char* text) {
+inline bool Parser::LookingAt(y_absl::string_view text) {
return input_->current().text == text;
}
@@ -203,7 +211,7 @@ inline bool Parser::LookingAtType(io::Tokenizer::TokenType token_type) {
inline bool Parser::AtEnd() { return LookingAtType(io::Tokenizer::TYPE_END); }
-bool Parser::TryConsume(const char* text) {
+bool Parser::TryConsume(y_absl::string_view text) {
if (LookingAt(text)) {
input_->Next();
return true;
@@ -212,50 +220,49 @@ bool Parser::TryConsume(const char* text) {
}
}
-bool Parser::Consume(const char* text, const char* error) {
+bool Parser::Consume(y_absl::string_view text, y_absl::string_view error) {
if (TryConsume(text)) {
return true;
} else {
- AddError(error);
+ RecordError(error);
return false;
}
}
-bool Parser::Consume(const char* text) {
- TProtoStringType error = "Expected \"" + TProtoStringType(text) + "\".";
- return Consume(text, error.c_str());
+bool Parser::Consume(y_absl::string_view text) {
+ return Consume(text, y_absl::StrCat("Expected \"", text, "\"."));
}
-bool Parser::ConsumeIdentifier(TProtoStringType* output, const char* error) {
+bool Parser::ConsumeIdentifier(TProtoStringType* output, y_absl::string_view error) {
if (LookingAtType(io::Tokenizer::TYPE_IDENTIFIER)) {
*output = input_->current().text;
input_->Next();
return true;
} else {
- AddError(error);
+ RecordError(error);
return false;
}
}
-bool Parser::ConsumeInteger(int* output, const char* error) {
+bool Parser::ConsumeInteger(int* output, y_absl::string_view error) {
if (LookingAtType(io::Tokenizer::TYPE_INTEGER)) {
arc_ui64 value = 0;
if (!io::Tokenizer::ParseInteger(input_->current().text,
std::numeric_limits<arc_i32>::max(),
&value)) {
- AddError("Integer out of range.");
+ RecordError("Integer out of range.");
// We still return true because we did, in fact, parse an integer.
}
*output = value;
input_->Next();
return true;
} else {
- AddError(error);
+ RecordError(error);
return false;
}
}
-bool Parser::ConsumeSignedInteger(int* output, const char* error) {
+bool Parser::ConsumeSignedInteger(int* output, y_absl::string_view error) {
bool is_negative = false;
arc_ui64 max_value = std::numeric_limits<arc_i32>::max();
if (TryConsume("-")) {
@@ -270,23 +277,32 @@ bool Parser::ConsumeSignedInteger(int* output, const char* error) {
}
bool Parser::ConsumeInteger64(arc_ui64 max_value, arc_ui64* output,
- const char* error) {
+ y_absl::string_view error) {
if (LookingAtType(io::Tokenizer::TYPE_INTEGER)) {
if (!io::Tokenizer::ParseInteger(input_->current().text, max_value,
output)) {
- AddError("Integer out of range.");
+ RecordError("Integer out of range.");
// We still return true because we did, in fact, parse an integer.
*output = 0;
}
input_->Next();
return true;
} else {
- AddError(error);
+ RecordError(error);
return false;
}
}
-bool Parser::ConsumeNumber(double* output, const char* error) {
+bool Parser::TryConsumeInteger64(arc_ui64 max_value, arc_ui64* output) {
+ if (LookingAtType(io::Tokenizer::TYPE_INTEGER) &&
+ io::Tokenizer::ParseInteger(input_->current().text, max_value, output)) {
+ input_->Next();
+ return true;
+ }
+ return false;
+}
+
+bool Parser::ConsumeNumber(double* output, y_absl::string_view error) {
if (LookingAtType(io::Tokenizer::TYPE_FLOAT)) {
*output = io::Tokenizer::ParseFloat(input_->current().text);
input_->Next();
@@ -294,13 +310,19 @@ bool Parser::ConsumeNumber(double* output, const char* error) {
} else if (LookingAtType(io::Tokenizer::TYPE_INTEGER)) {
// Also accept integers.
arc_ui64 value = 0;
- if (!io::Tokenizer::ParseInteger(input_->current().text,
- std::numeric_limits<arc_ui64>::max(),
- &value)) {
- AddError("Integer out of range.");
+ if (io::Tokenizer::ParseInteger(input_->current().text,
+ std::numeric_limits<arc_ui64>::max(),
+ &value)) {
+ *output = value;
+ } else if (input_->current().text[0] == '0') {
+ // octal or hexadecimal; don't bother parsing as float
+ RecordError("Integer out of range.");
+ // We still return true because we did, in fact, parse a number.
+ } else if (!io::Tokenizer::TryParseFloat(input_->current().text, output)) {
+ // out of int range, and not valid float? 🤷
+ RecordError("Integer out of range.");
// We still return true because we did, in fact, parse a number.
}
- *output = value;
input_->Next();
return true;
} else if (LookingAt("inf")) {
@@ -312,12 +334,12 @@ bool Parser::ConsumeNumber(double* output, const char* error) {
input_->Next();
return true;
} else {
- AddError(error);
+ RecordError(error);
return false;
}
}
-bool Parser::ConsumeString(TProtoStringType* output, const char* error) {
+bool Parser::ConsumeString(TProtoStringType* output, y_absl::string_view error) {
if (LookingAtType(io::Tokenizer::TYPE_STRING)) {
io::Tokenizer::ParseString(input_->current().text, output);
input_->Next();
@@ -328,12 +350,12 @@ bool Parser::ConsumeString(TProtoStringType* output, const char* error) {
}
return true;
} else {
- AddError(error);
+ RecordError(error);
return false;
}
}
-bool Parser::TryConsumeEndOfDeclaration(const char* text,
+bool Parser::TryConsumeEndOfDeclaration(y_absl::string_view text,
const LocationRecorder* location) {
if (LookingAt(text)) {
TProtoStringType leading, trailing;
@@ -347,7 +369,7 @@ bool Parser::TryConsumeEndOfDeclaration(const char* text,
if (location != nullptr) {
upcoming_detached_comments_.swap(detached);
location->AttachComments(&leading, &trailing, &detached);
- } else if (strcmp(text, "}") == 0) {
+ } else if (text == "}") {
// If the current location is null and we are finishing the current scope,
// drop pending upcoming detached comments.
upcoming_detached_comments_.swap(detached);
@@ -364,36 +386,39 @@ bool Parser::TryConsumeEndOfDeclaration(const char* text,
}
}
-bool Parser::ConsumeEndOfDeclaration(const char* text,
+bool Parser::ConsumeEndOfDeclaration(y_absl::string_view text,
const LocationRecorder* location) {
if (TryConsumeEndOfDeclaration(text, location)) {
return true;
} else {
- AddError("Expected \"" + TProtoStringType(text) + "\".");
+ RecordError(y_absl::StrCat("Expected \"", text, "\"."));
return false;
}
}
// -------------------------------------------------------------------
-void Parser::AddError(int line, int column, const TProtoStringType& error) {
+void Parser::RecordError(int line, int column, y_absl::string_view error) {
if (error_collector_ != nullptr) {
- error_collector_->AddError(line, column, error);
+ error_collector_->RecordError(line, column, error);
}
had_errors_ = true;
}
-void Parser::AddError(const TProtoStringType& error) {
- AddError(input_->current().line, input_->current().column, error);
+void Parser::RecordError(y_absl::string_view error) {
+ RecordError(input_->current().line, input_->current().column, error);
}
-void Parser::AddWarning(const TProtoStringType& warning) {
+void Parser::RecordWarning(int line, int column, y_absl::string_view warning) {
if (error_collector_ != nullptr) {
- error_collector_->AddWarning(input_->current().line,
- input_->current().column, warning);
+ error_collector_->RecordWarning(line, column, warning);
}
}
+void Parser::RecordWarning(y_absl::string_view warning) {
+ RecordWarning(input_->current().line, input_->current().column, warning);
+}
+
// -------------------------------------------------------------------
Parser::LocationRecorder::LocationRecorder(Parser* parser)
@@ -491,8 +516,8 @@ int Parser::LocationRecorder::CurrentPathSize() const {
void Parser::LocationRecorder::AttachComments(
TProtoStringType* leading, TProtoStringType* trailing,
std::vector<TProtoStringType>* detached_comments) const {
- GOOGLE_CHECK(!location_->has_leading_comments());
- GOOGLE_CHECK(!location_->has_trailing_comments());
+ Y_ABSL_CHECK(!location_->has_leading_comments());
+ Y_ABSL_CHECK(!location_->has_trailing_comments());
if (!leading->empty()) {
location_->mutable_leading_comments()->swap(*leading);
@@ -563,16 +588,16 @@ bool Parser::ValidateEnum(const EnumDescriptorProto* proto) {
}
if (has_allow_alias && !allow_alias) {
- TProtoStringType error =
- "\"" + proto->name() +
+ TProtoStringType error = y_absl::StrCat(
+ "\"", proto->name(),
"\" declares 'option allow_alias = false;' which has no effect. "
- "Please remove the declaration.";
+ "Please remove the declaration.");
// This needlessly clutters declarations with nops.
- AddError(error);
+ RecordError(error);
return false;
}
- std::set<int> used_values;
+ y_absl::flat_hash_set<int> used_values;
bool has_duplicates = false;
for (int i = 0; i < proto->value_size(); ++i) {
const EnumValueDescriptorProto& enum_value = proto->value(i);
@@ -584,14 +609,14 @@ bool Parser::ValidateEnum(const EnumDescriptorProto* proto) {
}
}
if (allow_alias && !has_duplicates) {
- TProtoStringType error =
- "\"" + proto->name() +
+ TProtoStringType error = y_absl::StrCat(
+ "\"", proto->name(),
"\" declares support for enum aliases but no enum values share field "
"numbers. Please remove the unnecessary 'option allow_alias = true;' "
- "declaration.";
+ "declaration.");
// Generate an error if an enum declares support for duplicate enum values
// and does not use it protect future authors.
- AddError(error);
+ RecordError(error);
return false;
}
@@ -600,10 +625,9 @@ bool Parser::ValidateEnum(const EnumDescriptorProto* proto) {
if (!allow_alias) {
for (const auto& enum_value : proto->value()) {
if (!IsUpperUnderscore(enum_value.name())) {
- AddWarning(
- "Enum constant should be in UPPER_CASE. Found: " +
- enum_value.name() +
- ". See https://developers.google.com/protocol-buffers/docs/style");
+ RecordWarning(y_absl::StrCat(
+ "Enum constant should be in UPPER_CASE. Found: ", enum_value.name(),
+ ". See https://developers.google.com/protocol-buffers/docs/style"));
}
}
}
@@ -634,14 +658,17 @@ bool Parser::Parse(io::Tokenizer* input, FileDescriptorProto* file) {
root_location.RecordLegacyLocation(file,
DescriptorPool::ErrorCollector::OTHER);
- if (require_syntax_identifier_ || LookingAt("syntax")) {
+ if (require_syntax_identifier_ || LookingAt("syntax")
+ ) {
if (!ParseSyntaxIdentifier(root_location)) {
// Don't attempt to parse the file if we didn't recognize the syntax
// identifier.
return false;
}
// Store the syntax into the file.
- if (file != nullptr) file->set_syntax(syntax_identifier_);
+ if (file != nullptr) {
+ file->set_syntax(syntax_identifier_);
+ }
} else if (!stop_after_syntax_identifier_) {
syntax_identifier_ = "proto2";
}
@@ -656,7 +683,7 @@ bool Parser::Parse(io::Tokenizer* input, FileDescriptorProto* file) {
SkipStatement();
if (LookingAt("}")) {
- AddError("Unmatched \"}\".");
+ RecordError("Unmatched \"}\".");
input_->NextWithComments(nullptr, &upcoming_detached_comments_,
&upcoming_doc_comments_);
}
@@ -674,9 +701,10 @@ bool Parser::Parse(io::Tokenizer* input, FileDescriptorProto* file) {
bool Parser::ParseSyntaxIdentifier(const LocationRecorder& parent) {
LocationRecorder syntax_location(parent,
FileDescriptorProto::kSyntaxFieldNumber);
- DO(Consume(
- "syntax",
- "File must begin with a syntax statement, e.g. 'syntax = \"proto2\";'."));
+ DO(Consume("syntax",
+ "File must begin with a syntax statement, e.g. 'syntax = "
+ "\"proto2\";'."));
+
DO(Consume("="));
io::Tokenizer::Token syntax_token = input_->current();
TProtoStringType syntax;
@@ -684,13 +712,12 @@ bool Parser::ParseSyntaxIdentifier(const LocationRecorder& parent) {
DO(ConsumeEndOfDeclaration(";", &syntax_location));
syntax_identifier_ = syntax;
-
if (syntax != "proto2" && syntax != "proto3" &&
!stop_after_syntax_identifier_) {
- AddError(syntax_token.line, syntax_token.column,
- "Unrecognized syntax identifier \"" + syntax +
- "\". This parser "
- "only recognizes \"proto2\" and \"proto3\".");
+ RecordError(syntax_token.line, syntax_token.column,
+ y_absl::StrCat("Unrecognized syntax identifier \"", syntax,
+ "\". This parser "
+ "only recognizes \"proto2\" and \"proto3\"."));
return false;
}
@@ -735,7 +762,7 @@ bool Parser::ParseTopLevelStatement(FileDescriptorProto* file,
return ParseOption(file->mutable_options(), location, file,
OPTION_STATEMENT);
} else {
- AddError("Expected top-level statement (e.g. \"message\").");
+ RecordError("Expected top-level statement (e.g. \"message\").");
return false;
}
}
@@ -754,10 +781,9 @@ bool Parser::ParseMessageDefinition(
DescriptorPool::ErrorCollector::NAME);
DO(ConsumeIdentifier(message->mutable_name(), "Expected message name."));
if (!IsUpperCamelCase(message->name())) {
- AddWarning(
- "Message name should be in UpperCamelCase. Found: " +
- message->name() +
- ". See https://developers.google.com/protocol-buffers/docs/style");
+ RecordWarning(y_absl::StrCat(
+ "Message name should be in UpperCamelCase. Found: ", message->name(),
+ ". See https://developers.google.com/protocol-buffers/docs/style"));
}
}
DO(ParseMessageBlock(message, message_location, containing_file));
@@ -768,7 +794,7 @@ bool Parser::ParseMessageDefinition(
//
// We have to make sure the oneof names don't conflict with any other
// field or oneof.
- std::unordered_set<TProtoStringType> names;
+ y_absl::flat_hash_set<TProtoStringType> names;
for (const auto& field : message->field()) {
names.insert(field.name());
}
@@ -793,7 +819,7 @@ bool Parser::ParseMessageDefinition(
names.insert(oneof_name);
field.set_oneof_index(message->oneof_decl_size());
OneofDescriptorProto* oneof = message->add_oneof_decl();
- oneof->set_name(oneof_name);
+ oneof->set_name(std::move(oneof_name));
}
}
}
@@ -857,7 +883,7 @@ bool Parser::ParseMessageBlock(DescriptorProto* message,
while (!TryConsumeEndOfDeclaration("}", nullptr)) {
if (AtEnd()) {
- AddError("Reached end of input in message definition (missing '}').");
+ RecordError("Reached end of input in message definition (missing '}').");
return false;
}
@@ -986,7 +1012,7 @@ bool Parser::ParseMessageFieldNoLabel(
field->set_label(FieldDescriptorProto::LABEL_OPTIONAL);
}
if (!field->has_label()) {
- AddError("Expected \"required\", \"optional\", or \"repeated\".");
+ RecordError("Expected \"required\", \"optional\", or \"repeated\".");
// We can actually reasonably recover here by just assuming the user
// forgot the label altogether.
field->set_label(FieldDescriptorProto::LABEL_OPTIONAL);
@@ -1016,15 +1042,15 @@ bool Parser::ParseMessageFieldNoLabel(
DO(ConsumeIdentifier(field->mutable_name(), "Expected field name."));
if (!IsLowerUnderscore(field->name())) {
- AddWarning(
- "Field name should be lowercase. Found: " + field->name() +
- ". See: https://developers.google.com/protocol-buffers/docs/style");
+ RecordWarning(y_absl::StrCat(
+ "Field name should be lowercase. Found: ", field->name(),
+ ". See: https://developers.google.com/protocol-buffers/docs/style"));
}
if (IsNumberFollowUnderscore(field->name())) {
- AddWarning(
- "Number should not come right after an underscore. Found: " +
- field->name() +
- ". See: https://developers.google.com/protocol-buffers/docs/style");
+ RecordWarning(y_absl::StrCat(
+ "Number should not come right after an underscore. Found: ",
+ field->name(),
+ ". See: https://developers.google.com/protocol-buffers/docs/style"));
}
}
DO(Consume("=", "Missing field number."));
@@ -1077,16 +1103,16 @@ bool Parser::ParseMessageFieldNoLabel(
// with a capital letter and lower-case the field name. New code should
// not use groups; it should use nested messages.
if (group->name()[0] < 'A' || 'Z' < group->name()[0]) {
- AddError(name_token.line, name_token.column,
- "Group names must start with a capital letter.");
+ RecordError(name_token.line, name_token.column,
+ "Group names must start with a capital letter.");
}
- LowerString(field->mutable_name());
+ y_absl::AsciiStrToLower(field->mutable_name());
field->set_type_name(group->name());
if (LookingAt("{")) {
DO(ParseMessageBlock(group, group_location, containing_file));
} else {
- AddError("Missing group body.");
+ RecordError("Missing group body.");
return false;
}
} else {
@@ -1104,17 +1130,17 @@ bool Parser::ParseMessageFieldNoLabel(
bool Parser::ParseMapType(MapField* map_field, FieldDescriptorProto* field,
LocationRecorder& type_name_location) {
if (field->has_oneof_index()) {
- AddError("Map fields are not allowed in oneofs.");
+ RecordError("Map fields are not allowed in oneofs.");
return false;
}
if (field->has_label()) {
- AddError(
+ RecordError(
"Field labels (required/optional/repeated) are not allowed on "
"map fields.");
return false;
}
if (field->has_extendee()) {
- AddError("Map fields are not allowed to be extensions.");
+ RecordError("Map fields are not allowed to be extensions.");
return false;
}
field->set_label(FieldDescriptorProto::LABEL_REPEATED);
@@ -1226,7 +1252,7 @@ bool Parser::ParseDefaultAssignment(
FieldDescriptorProto* field, const LocationRecorder& field_location,
const FileDescriptorProto* containing_file) {
if (field->has_default_value()) {
- AddError("Already set option \"default\".");
+ RecordError("Already set option \"default\".");
field->clear_default_value();
}
@@ -1279,7 +1305,7 @@ bool Parser::ParseDefaultAssignment(
DO(ConsumeInteger64(max_value, &value,
"Expected integer for field default value."));
// And stringify it again.
- default_value->append(StrCat(value));
+ default_value->append(y_absl::StrCat(value));
break;
}
@@ -1295,38 +1321,38 @@ bool Parser::ParseDefaultAssignment(
// Numeric, not negative.
if (TryConsume("-")) {
- AddError("Unsigned field can't have negative default value.");
+ RecordError("Unsigned field can't have negative default value.");
}
// Parse the integer to verify that it is not out-of-range.
arc_ui64 value;
DO(ConsumeInteger64(max_value, &value,
"Expected integer for field default value."));
// And stringify it again.
- default_value->append(StrCat(value));
+ default_value->append(y_absl::StrCat(value));
break;
}
case FieldDescriptorProto::TYPE_FLOAT:
- case FieldDescriptorProto::TYPE_DOUBLE:
+ case FieldDescriptorProto::TYPE_DOUBLE: {
// These types can be negative.
if (TryConsume("-")) {
default_value->append("-");
}
// Parse the integer because we have to convert hex integers to decimal
// floats.
- double value;
+ double value = 0.0;
DO(ConsumeNumber(&value, "Expected number."));
// And stringify it again.
- default_value->append(SimpleDtoa(value));
+ default_value->append(io::SimpleDtoa(value));
break;
-
+ }
case FieldDescriptorProto::TYPE_BOOL:
if (TryConsume("true")) {
default_value->assign("true");
} else if (TryConsume("false")) {
default_value->assign("false");
} else {
- AddError("Expected \"true\" or \"false\".");
+ RecordError("Expected \"true\" or \"false\".");
return false;
}
break;
@@ -1342,7 +1368,7 @@ bool Parser::ParseDefaultAssignment(
case FieldDescriptorProto::TYPE_BYTES:
DO(ConsumeString(default_value, "Expected string."));
- *default_value = CEscape(*default_value);
+ *default_value = y_absl::CEscape(*default_value);
break;
case FieldDescriptorProto::TYPE_ENUM:
@@ -1353,7 +1379,7 @@ bool Parser::ParseDefaultAssignment(
case FieldDescriptorProto::TYPE_MESSAGE:
case FieldDescriptorProto::TYPE_GROUP:
- AddError("Messages can't have default values.");
+ RecordError("Messages can't have default values.");
return false;
}
@@ -1364,7 +1390,7 @@ bool Parser::ParseJsonName(FieldDescriptorProto* field,
const LocationRecorder& field_location,
const FileDescriptorProto* containing_file) {
if (field->has_json_name()) {
- AddError("Already set option \"json_name\".");
+ RecordError("Already set option \"json_name\".");
field->clear_json_name();
}
@@ -1443,7 +1469,7 @@ bool Parser::ParseUninterpretedBlock(TProtoStringType* value) {
value->append(input_->current().text);
input_->Next();
}
- AddError("Unexpected end of stream while parsing aggregate value.");
+ RecordError("Unexpected end of stream while parsing aggregate value.");
return false;
}
@@ -1456,7 +1482,7 @@ bool Parser::ParseOption(Message* options,
// Create an entry in the uninterpreted_option field.
const FieldDescriptor* uninterpreted_option_field =
options->GetDescriptor()->FindFieldByName("uninterpreted_option");
- GOOGLE_CHECK(uninterpreted_option_field != nullptr)
+ Y_ABSL_CHECK(uninterpreted_option_field != nullptr)
<< "No field named \"uninterpreted_option\" in the Options proto.";
const Reflection* reflection = options->GetReflection();
@@ -1470,7 +1496,7 @@ bool Parser::ParseOption(Message* options,
}
UninterpretedOption* uninterpreted_option =
- down_cast<UninterpretedOption*>(options->GetReflection()->AddMessage(
+ DownCast<UninterpretedOption*>(options->GetReflection()->AddMessage(
options, uninterpreted_option_field));
// Parse dot-separated name.
@@ -1509,25 +1535,26 @@ bool Parser::ParseOption(Message* options,
switch (input_->current().type) {
case io::Tokenizer::TYPE_START:
- GOOGLE_LOG(FATAL) << "Trying to read value before any tokens have been read.";
+ Y_ABSL_LOG(FATAL)
+ << "Trying to read value before any tokens have been read.";
return false;
case io::Tokenizer::TYPE_END:
- AddError("Unexpected end of stream while parsing option value.");
+ RecordError("Unexpected end of stream while parsing option value.");
return false;
case io::Tokenizer::TYPE_WHITESPACE:
case io::Tokenizer::TYPE_NEWLINE:
- GOOGLE_CHECK(!input_->report_whitespace() && !input_->report_newlines())
+ Y_ABSL_CHECK(!input_->report_whitespace() && !input_->report_newlines())
<< "Whitespace tokens were not requested.";
- GOOGLE_LOG(FATAL) << "Tokenizer reported whitespace.";
+ Y_ABSL_LOG(FATAL) << "Tokenizer reported whitespace.";
return false;
case io::Tokenizer::TYPE_IDENTIFIER: {
value_location.AddPath(
UninterpretedOption::kIdentifierValueFieldNumber);
if (is_negative) {
- AddError("Invalid '-' symbol before identifier.");
+ RecordError("Invalid '-' symbol before identifier.");
return false;
}
TProtoStringType value;
@@ -1542,23 +1569,27 @@ bool Parser::ParseOption(Message* options,
is_negative
? static_cast<arc_ui64>(std::numeric_limits<arc_i64>::max()) + 1
: std::numeric_limits<arc_ui64>::max();
- DO(ConsumeInteger64(max_value, &value, "Expected integer."));
- if (is_negative) {
- value_location.AddPath(
- UninterpretedOption::kNegativeIntValueFieldNumber);
- uninterpreted_option->set_negative_int_value(
- static_cast<arc_i64>(0 - value));
- } else {
- value_location.AddPath(
- UninterpretedOption::kPositiveIntValueFieldNumber);
- uninterpreted_option->set_positive_int_value(value);
+ if (TryConsumeInteger64(max_value, &value)) {
+ if (is_negative) {
+ value_location.AddPath(
+ UninterpretedOption::kNegativeIntValueFieldNumber);
+ uninterpreted_option->set_negative_int_value(
+ static_cast<arc_i64>(0 - value));
+ } else {
+ value_location.AddPath(
+ UninterpretedOption::kPositiveIntValueFieldNumber);
+ uninterpreted_option->set_positive_int_value(value);
+ }
+ break;
}
- break;
+ // value too large for an integer; fall through below to treat as
+ // floating point
+ Y_ABSL_FALLTHROUGH_INTENDED;
}
case io::Tokenizer::TYPE_FLOAT: {
value_location.AddPath(UninterpretedOption::kDoubleValueFieldNumber);
- double value;
+ double value = 0.0;
DO(ConsumeNumber(&value, "Expected number."));
uninterpreted_option->set_double_value(is_negative ? -value : value);
break;
@@ -1567,7 +1598,7 @@ bool Parser::ParseOption(Message* options,
case io::Tokenizer::TYPE_STRING: {
value_location.AddPath(UninterpretedOption::kStringValueFieldNumber);
if (is_negative) {
- AddError("Invalid '-' symbol before string.");
+ RecordError("Invalid '-' symbol before string.");
return false;
}
TProtoStringType value;
@@ -1583,7 +1614,7 @@ bool Parser::ParseOption(Message* options,
DO(ParseUninterpretedBlock(
uninterpreted_option->mutable_aggregate_value()));
} else {
- AddError("Expected option value.");
+ RecordError("Expected option value.");
return false;
}
break;
@@ -1719,11 +1750,27 @@ bool Parser::ParseReserved(DescriptorProto* message,
}
}
+bool Parser::ParseReservedName(TProtoStringType* name,
+ y_absl::string_view error_message) {
+ // Capture the position of the token, in case we have to report an
+ // error after it is consumed.
+ int line = input_->current().line;
+ int col = input_->current().column;
+ DO(ConsumeString(name, error_message));
+ if (!io::Tokenizer::IsIdentifier(*name)) {
+ RecordWarning(
+ line, col,
+ y_absl::StrFormat("Reserved name \"%s\" is not a valid identifier.",
+ *name));
+ }
+ return true;
+}
+
bool Parser::ParseReservedNames(DescriptorProto* message,
const LocationRecorder& parent_location) {
do {
LocationRecorder location(parent_location, message->reserved_name_size());
- DO(ConsumeString(message->add_reserved_name(), "Expected field name."));
+ DO(ParseReservedName(message->add_reserved_name(), "Expected field name."));
} while (TryConsume(","));
DO(ConsumeEndOfDeclaration(";", &parent_location));
return true;
@@ -1778,42 +1825,41 @@ bool Parser::ParseReservedNumbers(DescriptorProto* message,
return true;
}
-bool Parser::ParseReserved(EnumDescriptorProto* message,
- const LocationRecorder& message_location) {
+bool Parser::ParseReserved(EnumDescriptorProto* proto,
+ const LocationRecorder& enum_location) {
io::Tokenizer::Token start_token = input_->current();
// Parse the declaration.
DO(Consume("reserved"));
if (LookingAtType(io::Tokenizer::TYPE_STRING)) {
- LocationRecorder location(message_location,
+ LocationRecorder location(enum_location,
EnumDescriptorProto::kReservedNameFieldNumber);
location.StartAt(start_token);
- return ParseReservedNames(message, location);
+ return ParseReservedNames(proto, location);
} else {
- LocationRecorder location(message_location,
+ LocationRecorder location(enum_location,
EnumDescriptorProto::kReservedRangeFieldNumber);
location.StartAt(start_token);
- return ParseReservedNumbers(message, location);
+ return ParseReservedNumbers(proto, location);
}
}
-bool Parser::ParseReservedNames(EnumDescriptorProto* message,
+bool Parser::ParseReservedNames(EnumDescriptorProto* proto,
const LocationRecorder& parent_location) {
do {
- LocationRecorder location(parent_location, message->reserved_name_size());
- DO(ConsumeString(message->add_reserved_name(), "Expected enum value."));
+ LocationRecorder location(parent_location, proto->reserved_name_size());
+ DO(ParseReservedName(proto->add_reserved_name(), "Expected enum value."));
} while (TryConsume(","));
DO(ConsumeEndOfDeclaration(";", &parent_location));
return true;
}
-bool Parser::ParseReservedNumbers(EnumDescriptorProto* message,
+bool Parser::ParseReservedNumbers(EnumDescriptorProto* proto,
const LocationRecorder& parent_location) {
bool first = true;
do {
- LocationRecorder location(parent_location, message->reserved_range_size());
+ LocationRecorder location(parent_location, proto->reserved_range_size());
- EnumDescriptorProto::EnumReservedRange* range =
- message->add_reserved_range();
+ EnumDescriptorProto::EnumReservedRange* range = proto->add_reserved_range();
int start, end;
io::Tokenizer::Token start_token;
{
@@ -1873,7 +1919,7 @@ bool Parser::ParseExtend(RepeatedPtrField<FieldDescriptorProto>* extensions,
do {
if (AtEnd()) {
- AddError("Reached end of input in extend definition (missing '}').");
+ RecordError("Reached end of input in extend definition (missing '}').");
return false;
}
@@ -1926,7 +1972,7 @@ bool Parser::ParseOneof(OneofDescriptorProto* oneof_decl,
do {
if (AtEnd()) {
- AddError("Reached end of input in oneof definition (missing '}').");
+ RecordError("Reached end of input in oneof definition (missing '}').");
return false;
}
@@ -1944,7 +1990,7 @@ bool Parser::ParseOneof(OneofDescriptorProto* oneof_decl,
// on an individual member of a oneof.
if (LookingAt("required") || LookingAt("optional") ||
LookingAt("repeated")) {
- AddError(
+ RecordError(
"Fields in oneofs must not have labels (required / optional "
"/ repeated).");
// We can continue parsing here because we understand what the user
@@ -2003,7 +2049,7 @@ bool Parser::ParseEnumBlock(EnumDescriptorProto* enum_type,
while (!TryConsumeEndOfDeclaration("}", nullptr)) {
if (AtEnd()) {
- AddError("Reached end of input in enum definition (missing '}').");
+ RecordError("Reached end of input in enum definition (missing '}').");
return false;
}
@@ -2120,7 +2166,7 @@ bool Parser::ParseServiceBlock(ServiceDescriptorProto* service,
while (!TryConsumeEndOfDeclaration("}", nullptr)) {
if (AtEnd()) {
- AddError("Reached end of input in service definition (missing '}').");
+ RecordError("Reached end of input in service definition (missing '}').");
return false;
}
@@ -2224,7 +2270,7 @@ bool Parser::ParseMethodOptions(const LocationRecorder& parent_location,
ConsumeEndOfDeclaration("{", &parent_location);
while (!TryConsumeEndOfDeclaration("}", nullptr)) {
if (AtEnd()) {
- AddError("Reached end of input in method options (missing '}').");
+ RecordError("Reached end of input in method options (missing '}').");
return false;
}
@@ -2288,7 +2334,7 @@ bool Parser::ParseUserDefinedType(TProtoStringType* type_name) {
// if we are parsing a field type then we would not get here because
// primitives are allowed there as well. So this error message doesn't
// need to account for enums.
- AddError("Expected message type.");
+ RecordError("Expected message type.");
// Pretend to accept this type so that we can go on parsing.
*type_name = input_->current().text;
@@ -2320,7 +2366,7 @@ bool Parser::ParsePackage(FileDescriptorProto* file,
const LocationRecorder& root_location,
const FileDescriptorProto* containing_file) {
if (file->has_package()) {
- AddError("Multiple package definitions.");
+ RecordError("Multiple package definitions.");
// Don't append the new package to the old one. Just replace it. Not
// that it really matters since this is an error anyway.
file->clear_package();
@@ -2391,33 +2437,27 @@ bool SourceLocationTable::Find(
const Message* descriptor,
DescriptorPool::ErrorCollector::ErrorLocation location, int* line,
int* column) const {
- const std::pair<int, int>* result =
- FindOrNull(location_map_, std::make_pair(descriptor, location));
- if (result == nullptr) {
+ auto it = location_map_.find({descriptor, location});
+ if (it == location_map_.end()) {
*line = -1;
*column = 0;
return false;
- } else {
- *line = result->first;
- *column = result->second;
- return true;
}
+ std::tie(*line, *column) = it->second;
+ return true;
}
bool SourceLocationTable::FindImport(const Message* descriptor,
- const TProtoStringType& name, int* line,
+ y_absl::string_view name, int* line,
int* column) const {
- const std::pair<int, int>* result =
- FindOrNull(import_location_map_, std::make_pair(descriptor, name));
- if (result == nullptr) {
+ auto it = import_location_map_.find({descriptor, TProtoStringType(name)});
+ if (it == import_location_map_.end()) {
*line = -1;
*column = 0;
return false;
- } else {
- *line = result->first;
- *column = result->second;
- return true;
}
+ std::tie(*line, *column) = it->second;
+ return true;
}
void SourceLocationTable::Add(