Remove all remaining STL sets in favor of Abseil containers.

PiperOrigin-RevId: 497069721
pull/11350/head
Mike Kruskal 2 years ago committed by Copybara-Service
parent 757b7d179f
commit 2166cce734
  1. 169
      conformance/conformance_test.cc
  2. 14
      conformance/conformance_test.h
  3. 4
      src/google/protobuf/compiler/java/message_builder.cc
  4. 1
      src/google/protobuf/descriptor.cc
  5. 1
      src/google/protobuf/descriptor.h
  6. 28
      src/google/protobuf/descriptor_database.cc
  7. 13
      src/google/protobuf/descriptor_unittest.cc
  8. 7
      src/google/protobuf/generated_message_reflection.cc
  9. 20
      src/google/protobuf/map_test.inc
  10. 1
      src/google/protobuf/stubs/common.h
  11. 2
      src/google/protobuf/text_format.cc

@ -33,7 +33,6 @@
#include <stdarg.h>
#include <fstream>
#include <set>
#include <string>
#include "google/protobuf/message.h"
@ -44,6 +43,7 @@
#include "google/protobuf/stubs/logging.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/str_format.h"
#include "absl/strings/string_view.h"
#include "conformance/conformance.pb.h"
#include "conformance/conformance.pb.h"
@ -72,17 +72,52 @@ static string ToOctString(const string& binary_string) {
return oct_string;
}
template <typename SetT>
bool CheckSetEmpty(const SetT& set_to_check, absl::string_view write_to_file,
absl::string_view msg, absl::string_view output_dir,
std::string* output) {
if (set_to_check.empty()) return true;
absl::StrAppendFormat(output, "\n");
absl::StrAppendFormat(output, "%s\n\n", msg);
for (absl::string_view v : set_to_check) {
absl::StrAppendFormat(output, " %s\n", v);
}
absl::StrAppendFormat(output, "\n");
if (!write_to_file.empty()) {
std::string full_filename;
absl::string_view filename = write_to_file;
if (!output_dir.empty()) {
full_filename = std::string(output_dir);
if (*output_dir.rbegin() != '/') {
full_filename.push_back('/');
}
absl::StrAppend(&full_filename, write_to_file);
filename = full_filename;
}
std::ofstream os{std::string(filename)};
if (os) {
for (absl::string_view v : set_to_check) {
os << v << "\n";
}
} else {
absl::StrAppendFormat(output, "Failed to open file: %s\n", filename);
}
}
return false;
}
} // namespace
namespace google {
namespace protobuf {
ConformanceTestSuite::ConformanceRequestSetting::ConformanceRequestSetting(
ConformanceLevel level,
conformance::WireFormat input_format,
ConformanceLevel level, conformance::WireFormat input_format,
conformance::WireFormat output_format,
conformance::TestCategory test_category,
const Message& prototype_message,
conformance::TestCategory test_category, const Message& prototype_message,
const string& test_name, const string& input)
: level_(level),
input_format_(input_format),
@ -126,30 +161,32 @@ ConformanceTestSuite::ConformanceRequestSetting::NewTestMessage() const {
return std::unique_ptr<Message>(prototype_message_for_compare_->New());
}
string ConformanceTestSuite::ConformanceRequestSetting::
GetTestName() const {
string rname =
prototype_message_.GetDescriptor()->file()->syntax() ==
FileDescriptor::SYNTAX_PROTO3 ? "Proto3" : "Proto2";
string ConformanceTestSuite::ConformanceRequestSetting::GetTestName() const {
string rname = prototype_message_.GetDescriptor()->file()->syntax() ==
FileDescriptor::SYNTAX_PROTO3
? "Proto3"
: "Proto2";
return absl::StrCat(ConformanceLevelToString(level_), ".", rname, ".",
InputFormatString(input_format_), ".", test_name_, ".",
OutputFormatString(output_format_));
}
string ConformanceTestSuite::ConformanceRequestSetting::
ConformanceLevelToString(
ConformanceLevel level) const {
string
ConformanceTestSuite::ConformanceRequestSetting::ConformanceLevelToString(
ConformanceLevel level) const {
switch (level) {
case REQUIRED: return "Required";
case RECOMMENDED: return "Recommended";
case REQUIRED:
return "Required";
case RECOMMENDED:
return "Recommended";
}
GOOGLE_ABSL_LOG(FATAL) << "Unknown value: " << level;
return "";
}
string ConformanceTestSuite::ConformanceRequestSetting::
InputFormatString(conformance::WireFormat format) const {
string ConformanceTestSuite::ConformanceRequestSetting::InputFormatString(
conformance::WireFormat format) const {
switch (format) {
case conformance::PROTOBUF:
return "ProtobufInput";
@ -163,8 +200,8 @@ string ConformanceTestSuite::ConformanceRequestSetting::
return "";
}
string ConformanceTestSuite::ConformanceRequestSetting::
OutputFormatString(conformance::WireFormat format) const {
string ConformanceTestSuite::ConformanceRequestSetting::OutputFormatString(
conformance::WireFormat format) const {
switch (format) {
case conformance::PROTOBUF:
return "ProtobufOutput";
@ -250,8 +287,7 @@ void ConformanceTestSuite::ReportFailure(const string& test_name,
absl::string_view message) {
if (expected_to_fail_.erase(test_name) == 1) {
expected_failures_++;
if (!verbose_)
return;
if (!verbose_) return;
} else if (level == RECOMMENDED && !enforce_recommended_) {
absl::StrAppendFormat(&output_, "WARNING, test=%s: ", test_name);
} else {
@ -390,47 +426,7 @@ void ConformanceTestSuite::RunTest(const string& test_name,
}
}
bool ConformanceTestSuite::CheckSetEmpty(
const std::set<string>& set_to_check,
const std::string& write_to_file,
const std::string& msg) {
if (set_to_check.empty()) {
return true;
} else {
absl::StrAppendFormat(&output_, "\n");
absl::StrAppendFormat(&output_, "%s\n\n", msg);
for (absl::string_view v : set_to_check) {
absl::StrAppendFormat(&output_, " %s\n", v);
}
absl::StrAppendFormat(&output_, "\n");
if (!write_to_file.empty()) {
std::string full_filename;
const std::string* filename = &write_to_file;
if (!output_dir_.empty()) {
full_filename = output_dir_;
if (*output_dir_.rbegin() != '/') {
full_filename.push_back('/');
}
full_filename += write_to_file;
filename = &full_filename;
}
std::ofstream os(*filename);
if (os) {
for (absl::string_view v : set_to_check) {
os << v << "\n";
}
} else {
absl::StrAppendFormat(&output_, "Failed to open file: %s\n", *filename);
}
}
return false;
}
}
string ConformanceTestSuite::WireFormatToString(
WireFormat wire_format) {
string ConformanceTestSuite::WireFormatToString(WireFormat wire_format) {
switch (wire_format) {
case conformance::PROTOBUF:
return "PROTOBUF";
@ -473,36 +469,45 @@ bool ConformanceTestSuite::RunSuite(ConformanceTestRunner* runner,
RunSuiteImpl();
bool ok = true;
if (!CheckSetEmpty(expected_to_fail_, "nonexistent_tests.txt",
"These tests were listed in the failure list, but they "
"don't exist. Remove them from the failure list by "
"running:\n"
" ./update_failure_list.py " + failure_list_filename_ +
" --remove nonexistent_tests.txt")) {
if (!CheckSetEmpty(
expected_to_fail_, "nonexistent_tests.txt",
absl::StrCat("These tests were listed in the failure list, but they "
"don't exist. Remove them from the failure list by "
"running:\n"
" ./update_failure_list.py ",
failure_list_filename_,
" --remove nonexistent_tests.txt"),
output_dir_, &output_)) {
ok = false;
}
if (!CheckSetEmpty(unexpected_failing_tests_, "failing_tests.txt",
"These tests failed. If they can't be fixed right now, "
"you can add them to the failure list so the overall "
"suite can succeed. Add them to the failure list by "
"running:\n"
" ./update_failure_list.py " + failure_list_filename_ +
" --add failing_tests.txt")) {
if (!CheckSetEmpty(
unexpected_failing_tests_, "failing_tests.txt",
absl::StrCat("These tests failed. If they can't be fixed right now, "
"you can add them to the failure list so the overall "
"suite can succeed. Add them to the failure list by "
"running:\n"
" ./update_failure_list.py ",
failure_list_filename_, " --add failing_tests.txt"),
output_dir_, &output_)) {
ok = false;
}
if (!CheckSetEmpty(unexpected_succeeding_tests_, "succeeding_tests.txt",
"These tests succeeded, even though they were listed in "
"the failure list. Remove them from the failure list "
"by running:\n"
" ./update_failure_list.py " + failure_list_filename_ +
" --remove succeeding_tests.txt")) {
if (!CheckSetEmpty(
unexpected_succeeding_tests_, "succeeding_tests.txt",
absl::StrCat("These tests succeeded, even though they were listed in "
"the failure list. Remove them from the failure list "
"by running:\n"
" ./update_failure_list.py ",
failure_list_filename_,
" --remove succeeding_tests.txt"),
output_dir_, &output_)) {
ok = false;
}
if (verbose_) {
CheckSetEmpty(skipped_, "",
"These tests were skipped (probably because support for some "
"features is not implemented)");
"features is not implemented)",
output_dir_, &output_);
}
absl::StrAppendFormat(&output_,

@ -44,6 +44,8 @@
#include "google/protobuf/descriptor.h"
#include "google/protobuf/util/type_resolver.h"
#include "absl/container/btree_set.h"
#include "absl/container/flat_hash_set.h"
#include "conformance/conformance.pb.h"
#include "google/protobuf/wire_format_lite.h"
@ -261,8 +263,6 @@ class ConformanceTestSuite {
std::string test_name_;
};
bool CheckSetEmpty(const std::set<std::string>& set_to_check,
const std::string& write_to_file, const std::string& msg);
std::string WireFormatToString(conformance::WireFormat wire_format);
// Parse payload in the response to the given message. Returns true on
@ -319,20 +319,20 @@ class ConformanceTestSuite {
// The set of test names that are expected to fail in this run, but haven't
// failed yet.
std::set<std::string> expected_to_fail_;
absl::btree_set<std::string> expected_to_fail_;
// The set of test names that have been run. Used to ensure that there are no
// duplicate names in the suite.
std::set<std::string> test_names_;
absl::flat_hash_set<std::string> test_names_;
// The set of tests that failed, but weren't expected to.
std::set<std::string> unexpected_failing_tests_;
absl::btree_set<std::string> unexpected_failing_tests_;
// The set of tests that succeeded, but weren't expected to.
std::set<std::string> unexpected_succeeding_tests_;
absl::btree_set<std::string> unexpected_succeeding_tests_;
// The set of tests that the testee opted out of;
std::set<std::string> skipped_;
absl::btree_set<std::string> skipped_;
};
} // namespace protobuf

@ -36,9 +36,9 @@
#include <algorithm>
#include <memory>
#include <set>
#include <vector>
#include "absl/container/btree_set.h"
#include "absl/container/flat_hash_map.h"
#include "absl/strings/ascii.h"
#include "absl/strings/str_cat.h"
@ -667,7 +667,7 @@ int MessageBuilderGenerator::GenerateBuildPartialPiece(io::Printer* printer,
"classname", name_resolver_->GetImmutableClassName(descriptor_), "piece",
absl::StrCat(piece), "bit_field_name", GetBitFieldName(piece));
printer->Indent();
std::set<int> declared_to_bitfields;
absl::btree_set<int> declared_to_bitfields;
int bit = 0;
int next = first_field;

@ -41,7 +41,6 @@
#include <limits>
#include <map>
#include <memory>
#include <set>
#include <sstream>
#include <string>
#include <type_traits>

@ -58,7 +58,6 @@
#include <cstdint>
#include <iterator>
#include <memory>
#include <set>
#include <string>
#include <vector>

@ -35,13 +35,15 @@
#include "google/protobuf/descriptor_database.h"
#include <algorithm>
#include <set>
#include <string>
#include <utility>
#include <vector>
#include "absl/container/btree_set.h"
#include "absl/strings/ascii.h"
#include "absl/strings/match.h"
#include "absl/strings/str_replace.h"
#include "absl/strings/string_view.h"
#include "google/protobuf/descriptor.pb.h"
@ -50,8 +52,8 @@ namespace protobuf {
namespace {
void RecordMessageNames(const DescriptorProto& desc_proto,
const std::string& prefix,
std::set<std::string>* output) {
absl::string_view prefix,
absl::btree_set<std::string>* output) {
GOOGLE_ABSL_CHECK(desc_proto.has_name());
std::string full_name = prefix.empty()
? desc_proto.name()
@ -64,7 +66,7 @@ void RecordMessageNames(const DescriptorProto& desc_proto,
}
void RecordMessageNames(const FileDescriptorProto& file_proto,
std::set<std::string>* output) {
absl::btree_set<std::string>* output) {
for (const auto& d : file_proto.message_type()) {
RecordMessageNames(d, file_proto.package(), output);
}
@ -77,7 +79,7 @@ bool ForAllFileProtos(DescriptorDatabase* db, Fn callback,
if (!db->FindAllFileNames(&file_names)) {
return false;
}
std::set<std::string> set;
absl::btree_set<std::string> set;
FileDescriptorProto file_proto;
for (const auto& f : file_names) {
file_proto.Clear();
@ -92,12 +94,13 @@ bool ForAllFileProtos(DescriptorDatabase* db, Fn callback,
}
} // namespace
DescriptorDatabase::~DescriptorDatabase() {}
DescriptorDatabase::~DescriptorDatabase() = default;
bool DescriptorDatabase::FindAllPackageNames(std::vector<std::string>* output) {
return ForAllFileProtos(
this,
[](const FileDescriptorProto& file_proto, std::set<std::string>* set) {
[](const FileDescriptorProto& file_proto,
absl::btree_set<std::string>* set) {
set->insert(file_proto.package());
},
output);
@ -106,7 +109,8 @@ bool DescriptorDatabase::FindAllPackageNames(std::vector<std::string>* output) {
bool DescriptorDatabase::FindAllMessageNames(std::vector<std::string>* output) {
return ForAllFileProtos(
this,
[](const FileDescriptorProto& file_proto, std::set<std::string>* set) {
[](const FileDescriptorProto& file_proto,
absl::btree_set<std::string>* set) {
RecordMessageNames(file_proto, set);
},
output);
@ -426,7 +430,7 @@ class EncodedDescriptorDatabase::DescriptorIndex {
bool AddExtension(absl::string_view filename, const FieldProto& field);
// All the maps below have two representations:
// - a std::set<> where we insert initially.
// - a absl::btree_set<> where we insert initially.
// - a std::vector<> where we flatten the structure on demand.
// The initial tree helps avoid O(N) behavior of inserting into a sorted
// vector, while the vector reduces the heap requirements of the data
@ -1018,15 +1022,15 @@ bool MergedDescriptorDatabase::FindFileContainingExtension(
bool MergedDescriptorDatabase::FindAllExtensionNumbers(
const std::string& extendee_type, std::vector<int>* output) {
std::set<int> merged_results;
absl::btree_set<int> merged_results;
std::vector<int> results;
bool success = false;
for (DescriptorDatabase* source : sources_) {
if (source->FindAllExtensionNumbers(extendee_type, &results)) {
std::copy(results.begin(), results.end(),
std::insert_iterator<std::set<int> >(merged_results,
merged_results.begin()));
std::insert_iterator<absl::btree_set<int> >(
merged_results, merged_results.begin()));
success = true;
}
results.clear();

@ -42,6 +42,8 @@
#include "google/protobuf/compiler/importer.h"
#include "google/protobuf/compiler/parser.h"
#include "google/protobuf/descriptor.pb.h"
#include "absl/container/btree_set.h"
#include "absl/container/flat_hash_set.h"
#include "absl/strings/str_format.h"
#include "google/protobuf/unittest.pb.h"
#include "google/protobuf/unittest_custom_options.pb.h"
@ -577,7 +579,7 @@ TEST_F(FileDescriptorTest, CopyHeadingTo) {
}
void ExtractDebugString(
const FileDescriptor* file, std::set<std::string>* visited,
const FileDescriptor* file, absl::flat_hash_set<std::string>* visited,
std::vector<std::pair<std::string, std::string>>* debug_strings) {
if (!visited->insert(file->name()).second) {
return;
@ -603,7 +605,7 @@ class SimpleErrorCollector : public io::ErrorCollector {
// Test that the result of FileDescriptor::DebugString() can be used to create
// the original descriptors.
TEST_F(FileDescriptorTest, DebugStringRoundTrip) {
std::set<std::string> visited;
absl::flat_hash_set<std::string> visited;
std::vector<std::pair<std::string, std::string>> debug_strings;
ExtractDebugString(protobuf_unittest::TestAllTypes::descriptor()->file(),
&visited, &debug_strings);
@ -850,12 +852,13 @@ TEST_F(DescriptorTest, ContainingType) {
TEST_F(DescriptorTest, FieldNamesDedup) {
const auto collect_unique_names = [](const FieldDescriptor* field) {
std::set<std::string> names{field->name(), field->lowercase_name(),
field->camelcase_name(), field->json_name()};
absl::btree_set<std::string> names{field->name(), field->lowercase_name(),
field->camelcase_name(),
field->json_name()};
// Verify that we have the same number of string objects as we have string
// values. That is, duplicate names use the same std::string object.
// This is for memory efficiency.
EXPECT_EQ(names.size(), (std::set<const std::string*>{
EXPECT_EQ(names.size(), (absl::flat_hash_set<const std::string*>{
&field->name(), &field->lowercase_name(),
&field->camelcase_name(), &field->json_name()}
.size()))

@ -38,11 +38,11 @@
#include <atomic>
#include <cstdint>
#include <cstring>
#include <set>
#include <string>
#include "absl/base/casts.h"
#include "absl/container/flat_hash_map.h"
#include "absl/container/flat_hash_set.h"
#include "google/protobuf/stubs/logging.h"
#include "google/protobuf/stubs/logging.h"
#include "absl/strings/match.h"
@ -1076,7 +1076,7 @@ void Reflection::SwapFieldsImpl(
<< "\"). Note that the exact same class is required; not just the same "
"descriptor.";
std::set<int> swapped_oneof;
absl::flat_hash_set<int> swapped_oneof;
const Message* prototype =
message_factory_->GetPrototype(message1->GetDescriptor());
@ -1094,10 +1094,9 @@ void Reflection::SwapFieldsImpl(
if (schema_.InRealOneof(field)) {
int oneof_index = field->containing_oneof()->index();
// Only swap the oneof field once.
if (swapped_oneof.find(oneof_index) != swapped_oneof.end()) {
if (!swapped_oneof.insert(oneof_index).second) {
continue;
}
swapped_oneof.insert(oneof_index);
SwapOneofField<unsafe_shallow_swap>(message1, message2,
field->containing_oneof());
} else {

@ -39,7 +39,6 @@
#include <algorithm>
#include <memory>
#include <random>
#include <set>
#include <sstream>
#include <vector>
@ -49,6 +48,7 @@
#include "google/protobuf/testing/googletest.h"
#include <gtest/gtest.h>
#include "absl/base/casts.h"
#include "absl/container/btree_set.h"
#include "absl/container/flat_hash_map.h"
#include "absl/container/flat_hash_set.h"
#include "google/protobuf/stubs/logging.h"
@ -436,7 +436,7 @@ TEST_F(MapImplTest, BeginIsFast) {
// was triggered. This test is a hacky, but probably better than nothing.
TEST_F(MapImplTest, HashFlood) {
const int kTestSize = 1024; // must be a power of 2
std::set<int> s;
absl::btree_set<int> s;
for (int i = 0; s.size() < kTestSize; i++) {
if ((map_.hash_function()(i) & (kTestSize - 1)) < 3) {
s.insert(i);
@ -447,7 +447,7 @@ TEST_F(MapImplTest, HashFlood) {
// of 2 for table sizes, and that it's sufficient to "flood" with respect to
// the low bits of the output of map_.hash_function().
std::vector<int64_t> times;
std::set<int>::iterator it = s.begin();
auto it = s.begin();
int count = 0;
do {
const int64_t start = Now();
@ -475,9 +475,7 @@ TEST_F(MapImplTest, CopyIteratorStressTest) {
map_[key] = i;
v.push_back(map_.find(key));
}
for (std::vector<Map<int32_t, int32_t>::iterator>::const_iterator it =
v.begin();
it != v.end(); it++) {
for (auto it = v.begin(); it != v.end(); it++) {
Map<int32_t, int32_t>::iterator i = *it;
ASSERT_EQ(i->first, (*it)->first);
ASSERT_EQ(i->second, (*it)->second);
@ -594,9 +592,9 @@ static void StressTestIterators(int n) {
v.push_back(it);
}
ASSERT_EQ(m.size(), v.size());
const Map<int, int>::iterator erase_result = m.erase(m.find(last_key));
const auto erase_result = m.erase(m.find(last_key));
int index = 0;
for (Map<int, int>::iterator it = m.begin(); it != m.end(); ++it, ++index) {
for (auto it = m.begin(); it != m.end(); ++it, ++index) {
if (index == position_of_last_key) {
EXPECT_EQ(&*erase_result, &*v[++index]);
}
@ -611,7 +609,7 @@ TEST_F(MapImplTest, IteratorInvalidation) {
#else
const int kMaxSizeToTest = 1000 * 1000;
#endif
std::set<int> s;
absl::btree_set<int> s;
int n = kMaxSizeToTest;
unsigned int frog = k1 + n;
while (n > 1 && s.size() < 25) {
@ -625,8 +623,8 @@ TEST_F(MapImplTest, IteratorInvalidation) {
s.insert(2);
s.insert(3);
// Now, the real work.
for (std::set<int>::iterator i = s.begin(); i != s.end(); ++i) {
StressTestIterators(*i);
for (int i : s) {
StressTestIterators(i);
}
}

@ -39,7 +39,6 @@
#include <iostream>
#include <map>
#include <memory>
#include <set>
#include <string>
#include <vector>

@ -42,11 +42,11 @@
#include <climits>
#include <cmath>
#include <limits>
#include <set>
#include <string>
#include <utility>
#include <vector>
#include "absl/container/btree_set.h"
#include "absl/strings/ascii.h"
#include "absl/strings/escaping.h"
#include "absl/strings/numbers.h"

Loading…
Cancel
Save