Internal change

PiperOrigin-RevId: 610422312
pull/15923/head
Protobuf Team Bot 12 months ago committed by Copybara-Service
parent 7e5962d3bc
commit afbe9cc9b5
  1. 3
      src/google/protobuf/compiler/BUILD.bazel
  2. 57
      src/google/protobuf/compiler/allowlists/BUILD.bazel
  3. 146
      src/google/protobuf/compiler/allowlists/allowlist.h
  4. 97
      src/google/protobuf/compiler/allowlists/allowlist_test.cc
  5. 43
      src/google/protobuf/compiler/allowlists/allowlists.h
  6. 36
      src/google/protobuf/compiler/allowlists/open_enum.cc
  7. 1
      src/google/protobuf/compiler/code_generator.cc
  8. 1
      src/google/protobuf/compiler/command_line_interface.cc
  9. 3
      src/google/protobuf/compiler/cpp/generator.cc
  10. 1
      src/google/protobuf/compiler/cpp/generator.h

@ -83,7 +83,6 @@ cc_library(
"//src/google/protobuf:port",
"//src/google/protobuf:protobuf_lite",
"//src/google/protobuf/compiler:retention",
"//src/google/protobuf/compiler/allowlists",
"//src/google/protobuf/io",
"//src/google/protobuf/io:io_win32",
"@com_google_absl//absl/container:flat_hash_map",
@ -152,7 +151,6 @@ cc_library(
":versions",
"//src/google/protobuf",
"//src/google/protobuf:port",
"//src/google/protobuf/compiler/allowlists",
"//src/google/protobuf/io",
"//src/google/protobuf/io:io_win32",
"//src/google/protobuf/io:printer",
@ -600,7 +598,6 @@ filegroup(
],
allow_empty = True,
) + [
"//src/google/protobuf/compiler/allowlists:test_srcs",
"//src/google/protobuf/compiler/cpp:test_srcs",
"//src/google/protobuf/compiler/csharp:test_srcs",
"//src/google/protobuf/compiler/java:test_srcs",

@ -1,57 +0,0 @@
load("@rules_cc//cc:defs.bzl", "cc_library", "cc_test")
load("//build_defs:cpp_opts.bzl", "COPTS")
package(default_visibility = ["//visibility:private"])
cc_library(
name = "allowlist",
hdrs = ["allowlist.h"],
copts = COPTS,
strip_include_prefix = "/src",
deps = [
"//src/google/protobuf/stubs",
"@com_google_absl//absl/algorithm:container",
"@com_google_absl//absl/base:core_headers",
"@com_google_absl//absl/container:flat_hash_set",
"@com_google_absl//absl/strings",
"@com_google_absl//absl/types:span",
],
)
cc_library(
name = "allowlists",
srcs = [
"open_enum.cc",
],
hdrs = ["allowlists.h"],
copts = COPTS,
strip_include_prefix = "/src",
visibility = ["//src/google/protobuf:__subpackages__"],
deps = [
":allowlist",
"@com_google_absl//absl/strings",
],
)
cc_test(
name = "allowlist_test",
srcs = ["allowlist_test.cc"],
copts = COPTS,
deps = [
":allowlist",
"@com_google_googletest//:gtest",
"@com_google_googletest//:gtest_main",
],
)
filegroup(
name = "test_srcs",
srcs = glob(
[
"*_test.cc",
"*unittest.cc",
],
allow_empty = True,
),
visibility = ["//src/google/protobuf/compiler:__pkg__"],
)

@ -1,146 +0,0 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file or at
// https://developers.google.com/open-source/licenses/bsd
#ifndef GOOGLE_PROTOBUF_COMPILER_ALLOWLISTS_ALLOWLIST_H__
#define GOOGLE_PROTOBUF_COMPILER_ALLOWLISTS_ALLOWLIST_H__
#include <cstddef>
#include <cstring>
#include <string>
#include <type_traits>
#include "absl/algorithm/container.h"
#include "google/protobuf/stubs/common.h"
#include "absl/container/flat_hash_set.h"
#include "absl/strings/match.h"
#include "absl/strings/string_view.h"
#include "absl/types/span.h"
// Must be included last.
#include "google/protobuf/port_def.inc"
namespace google {
namespace protobuf {
namespace compiler {
namespace internal {
enum AllowlistFlags : unsigned int {
kNone = 0,
kMatchPrefix = 1 << 1,
kAllowAllInOss = 1 << 2,
kAllowAllWhenEmpty = 1 << 3,
kMatchRegex = 1 << 4,
};
#if !defined(__GNUC__) || defined(__clang__) || PROTOBUF_GNUC_MIN(9, 1)
using maybe_string_view = absl::string_view;
#else
// In GCC versions before 9.1, template substitution fails because of the
// implicit conversion between `const char*` and absl::string_view. In these
// cases we can just use a raw string and convert later. See
// https://godbolt.org/z/r57fx37d1 for an example of the failure.
using maybe_string_view = const char*;
#endif
// An allowlist of things (messages, files, targets) that are allowed to violate
// some constraint.
//
// This is fundamentally a simple API over a set of static strings. It should
// only ever be used as a `static const` variable.
//
// These allowlists are usually only used internally within Google, and contain
// the names of internal files and Protobufs. In open source, these lists become
// no-ops (either they always or never allow everything).
template <size_t n>
class Allowlist final {
public:
template <size_t m = n, typename = std::enable_if_t<m != 0>>
constexpr Allowlist(const maybe_string_view (&list)[n], AllowlistFlags flags)
: flags_(flags) {
for (size_t i = 0; i < n; ++i) {
list_[i] = list[i];
if (i != 0) {
ABSL_ASSERT(list_[i - 1] < list_[i] && "Allowlist must be sorted!");
}
}
}
template <size_t m = n, typename = std::enable_if_t<m == 0>>
explicit constexpr Allowlist(AllowlistFlags flags)
: list_(nullptr, 0), flags_(flags) {}
// Checks if the element is allowed by this allowlist.
bool Allows(absl::string_view name) const {
if (flags_ & AllowlistFlags::kAllowAllInOss) return true;
// Convert to a span to get access to standard algorithms without resorting
// to horrible things like std::end().
absl::Span<const absl::string_view> list = list_;
auto bound = absl::c_lower_bound(list, name);
if (bound == list.end()) {
// If this string has the last element as a prefix, it will appear as if
// the element is not present in the list; we can take care of this case
// by manually checking the last element.
//
// This will also spuriously fire if a string sorts before everything in
// the list, but in that case the check will still return false as
// expected.
if (flags_ & AllowlistFlags::kMatchPrefix && !list.empty()) {
return absl::StartsWith(name, list.back());
}
return false;
}
if (name == *bound) return true;
if (flags_ & AllowlistFlags::kMatchPrefix && bound != list.begin()) {
return absl::StartsWith(name, bound[-1]);
}
return false;
}
private:
constexpr absl::Span<const absl::string_view> list() const { return list_; }
// NOTE: std::array::operator[] is *not* constexpr before C++17.
//
// In order for a zero-element list to work, we replace the array with a
// null string view when the size is zero.
std::conditional_t<n != 0, absl::string_view[n],
absl::Span<absl::string_view>>
list_;
AllowlistFlags flags_;
};
struct EmptyAllowlistSentinel {};
// This overload picks up MakeAllowlist({}), since zero-length arrays are not
// a thing in C++.
constexpr Allowlist<0> MakeAllowlist(
EmptyAllowlistSentinel, // This binds to `{}`.
AllowlistFlags flags = AllowlistFlags::kNone) {
return Allowlist<0>(flags);
}
template <size_t n>
constexpr Allowlist<n> MakeAllowlist(
const maybe_string_view (&list)[n],
AllowlistFlags flags = AllowlistFlags::kNone) {
return Allowlist<n>(list, flags);
}
} // namespace internal
} // namespace compiler
} // namespace protobuf
} // namespace google
#include "google/protobuf/port_undef.inc"
#endif // GOOGLE_PROTOBUF_COMPILER_ALLOWLISTS_ALLOWLIST_H__

@ -1,97 +0,0 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file or at
// https://developers.google.com/open-source/licenses/bsd
#include "google/protobuf/compiler/allowlists/allowlist.h"
#include <gtest/gtest.h>
namespace google {
namespace protobuf {
namespace compiler {
namespace internal {
namespace {
TEST(AllowlistTest, Smoke) {
static const auto kList = MakeAllowlist({
"bar",
"baz",
"foo",
});
EXPECT_TRUE(kList.Allows("bar"));
EXPECT_TRUE(kList.Allows("baz"));
EXPECT_TRUE(kList.Allows("foo"));
EXPECT_FALSE(kList.Allows("barf"));
EXPECT_FALSE(kList.Allows("baq"));
EXPECT_FALSE(kList.Allows("bak"));
EXPECT_FALSE(kList.Allows("foob"));
}
TEST(AllowlistTest, Empty) {
static const auto kList = MakeAllowlist({});
EXPECT_FALSE(kList.Allows("bar"));
EXPECT_FALSE(kList.Allows("baz"));
EXPECT_FALSE(kList.Allows("foo"));
EXPECT_FALSE(kList.Allows("barf"));
EXPECT_FALSE(kList.Allows("baq"));
EXPECT_FALSE(kList.Allows("bak"));
EXPECT_FALSE(kList.Allows("foob"));
}
TEST(AllowlistTest, Prefix) {
static const auto kList = MakeAllowlist(
{
"bar",
"baz",
"foo",
},
AllowlistFlags::kMatchPrefix);
EXPECT_TRUE(kList.Allows("bar"));
EXPECT_TRUE(kList.Allows("baz"));
EXPECT_TRUE(kList.Allows("foo"));
EXPECT_TRUE(kList.Allows("barf"));
EXPECT_TRUE(kList.Allows("foon"));
EXPECT_TRUE(kList.Allows("bazaar"));
EXPECT_FALSE(kList.Allows("baq"));
EXPECT_FALSE(kList.Allows("bbr"));
EXPECT_FALSE(kList.Allows("fbar"));
EXPECT_FALSE(kList.Allows("ba"));
EXPECT_FALSE(kList.Allows("fon"));
EXPECT_FALSE(kList.Allows("fop"));
}
TEST(AllowlistTest, Oss) {
static const auto kList = MakeAllowlist(
{
"bar",
"baz",
"foo",
},
AllowlistFlags::kAllowAllInOss);
EXPECT_TRUE(kList.Allows("bar"));
EXPECT_TRUE(kList.Allows("baz"));
EXPECT_TRUE(kList.Allows("foo"));
EXPECT_TRUE(kList.Allows("barf"));
EXPECT_TRUE(kList.Allows("baq"));
EXPECT_TRUE(kList.Allows("bak"));
EXPECT_TRUE(kList.Allows("foob"));
}
#if GTEST_HAS_DEATH_TEST && !defined(NDEBUG)
TEST(AllowlistTest, Unsorted) {
EXPECT_DEATH(MakeAllowlist({"foo", "bar"}), "Allowlist must be sorted!");
}
#endif
} // namespace
} // namespace internal
} // namespace compiler
} // namespace protobuf
} // namespace google

@ -1,43 +0,0 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file or at
// https://developers.google.com/open-source/licenses/bsd
#ifndef GOOGLE_PROTOBUF_COMPILER_ALLOWLISTS_ALLOWLISTS_H__
#define GOOGLE_PROTOBUF_COMPILER_ALLOWLISTS_ALLOWLISTS_H__
#include "absl/strings/string_view.h"
namespace google {
namespace protobuf {
namespace compiler {
// Returns whether a file can use the `import weak` syntax.
bool IsWeakImportFile(absl::string_view file);
// Returns whether a file can have an empty package.
bool IsEmptyPackageFile(absl::string_view file);
// Returns whether a file can contain a cc_open_enum.
bool IsOpenEnumFile(absl::string_view file);
// Returns whether a message can contain a cc_open_enum.
bool IsOpenEnumMessage(absl::string_view msg);
// Returns whether a file can contain an unused import.
bool IsUnusedImportFile(absl::string_view file);
// Returns whether a file has early access to editions.
bool IsEarlyEditionsFile(absl::string_view file);
// Returns whether a file allows required fields.
bool IsRequiredFieldFile(absl::string_view file);
} // namespace compiler
} // namespace protobuf
} // namespace google
#endif // GOOGLE_PROTOBUF_ALLOWLISTS_COMPILER_ALLOWLISTS_H__

@ -1,36 +0,0 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file or at
// https://developers.google.com/open-source/licenses/bsd
#include "absl/strings/string_view.h"
#include "google/protobuf/compiler/allowlists/allowlist.h"
#include "google/protobuf/compiler/allowlists/allowlists.h"
namespace google {
namespace protobuf {
namespace compiler {
// NOTE: Allowlists in this file are not accepting new entries unless otherwise
// specified.
static constexpr auto kOpenEnumFiles = internal::MakeAllowlist({
// Intentionally left blank.
});
static constexpr auto kOpenEnumMessages = internal::MakeAllowlist({
// Intentionally left blank.
});
bool IsOpenEnumFile(absl::string_view file) {
return kOpenEnumFiles.Allows(file);
}
bool IsOpenEnumMessage(absl::string_view msg) {
return kOpenEnumMessages.Allows(msg);
}
} // namespace compiler
} // namespace protobuf
} // namespace google

@ -23,7 +23,6 @@
#include "absl/strings/str_split.h"
#include "absl/strings/string_view.h"
#include "absl/strings/strip.h"
#include "google/protobuf/compiler/allowlists/allowlists.h"
#include "google/protobuf/compiler/plugin.pb.h"
#include "google/protobuf/descriptor.h"
#include "google/protobuf/feature_resolver.h"

@ -26,7 +26,6 @@
#include "absl/status/statusor.h"
#include "absl/strings/str_cat.h"
#include "absl/types/span.h"
#include "google/protobuf/compiler/allowlists/allowlists.h"
#include "google/protobuf/compiler/versions.h"
#include "google/protobuf/descriptor_database.h"
#include "google/protobuf/descriptor_visitor.h"

@ -12,6 +12,7 @@
#include "google/protobuf/compiler/cpp/generator.h"
#include <cstdlib>
#include <cstring>
#include <memory>
#include <string>
#include <utility>
@ -87,6 +88,7 @@ absl::flat_hash_map<absl::string_view, std::string> CommonVars(
};
}
} // namespace
bool CppGenerator::Generate(const FileDescriptor* file,
@ -223,6 +225,7 @@ bool CppGenerator::Generate(const FileDescriptor* file,
return false;
}
FileGenerator file_generator(file, file_options);
// Generate header(s).

@ -20,6 +20,7 @@
#include <vector>
#include "absl/status/status.h"
#include "absl/strings/string_view.h"
#include "google/protobuf/compiler/code_generator.h"
#include "google/protobuf/cpp_features.pb.h"
#include "google/protobuf/descriptor.pb.h"

Loading…
Cancel
Save