Merge pull request #10527 from mkruskal-google/sync-stage

Integrate from Piper for C++, Java, and Python
pull/10403/head
Mike Kruskal 2 years ago committed by GitHub
commit 4fdfab1ec5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 9
      CHANGES.txt
  2. 2
      cmake/abseil-cpp.cmake
  3. 63
      conformance/binary_json_conformance_suite.cc
  4. 24
      conformance/conformance_cpp.cc
  5. 12
      conformance/conformance_test.cc
  6. 6
      conformance/conformance_test.h
  7. 2
      conformance/conformance_test_runner.cc
  8. 8
      conformance/text_format_conformance_suite.cc
  9. 4
      protobuf_deps.bzl
  10. 1
      python/google/protobuf/internal/message_test.py
  11. 2
      python/google/protobuf/internal/python_protobuf.cc
  12. 1
      python/google/protobuf/internal/text_format_test.py
  13. 4
      python/google/protobuf/proto_api.h
  14. 18
      python/google/protobuf/pyext/descriptor.cc
  15. 2
      python/google/protobuf/pyext/descriptor.h
  16. 10
      python/google/protobuf/pyext/descriptor_containers.cc
  17. 12
      python/google/protobuf/pyext/descriptor_database.cc
  18. 2
      python/google/protobuf/pyext/descriptor_database.h
  19. 14
      python/google/protobuf/pyext/descriptor_pool.cc
  20. 2
      python/google/protobuf/pyext/descriptor_pool.h
  21. 26
      python/google/protobuf/pyext/extension_dict.cc
  22. 2
      python/google/protobuf/pyext/extension_dict.h
  23. 8
      python/google/protobuf/pyext/field.cc
  24. 21
      python/google/protobuf/pyext/map_container.cc
  25. 6
      python/google/protobuf/pyext/map_container.h
  26. 76
      python/google/protobuf/pyext/message.cc
  27. 2
      python/google/protobuf/pyext/message.h
  28. 10
      python/google/protobuf/pyext/message_factory.cc
  29. 4
      python/google/protobuf/pyext/message_factory.h
  30. 12
      python/google/protobuf/pyext/message_module.cc
  31. 25
      python/google/protobuf/pyext/repeated_composite_container.cc
  32. 2
      python/google/protobuf/pyext/repeated_composite_container.h
  33. 20
      python/google/protobuf/pyext/repeated_scalar_container.cc
  34. 4
      python/google/protobuf/pyext/repeated_scalar_container.h
  35. 4
      python/google/protobuf/pyext/safe_numerics.h
  36. 12
      python/google/protobuf/pyext/unknown_field_set.cc
  37. 2
      python/google/protobuf/pyext/unknown_field_set.h
  38. 12
      python/google/protobuf/pyext/unknown_fields.cc
  39. 2
      python/google/protobuf/pyext/unknown_fields.h
  40. 14
      src/file_lists.cmake
  41. 7
      src/google/protobuf/BUILD.bazel
  42. 14
      src/google/protobuf/any.cc
  43. 10
      src/google/protobuf/any.h
  44. 18
      src/google/protobuf/any.pb.cc
  45. 34
      src/google/protobuf/any.pb.h
  46. 10
      src/google/protobuf/any_lite.cc
  47. 8
      src/google/protobuf/any_test.cc
  48. 18
      src/google/protobuf/api.pb.cc
  49. 34
      src/google/protobuf/api.pb.h
  50. 387
      src/google/protobuf/arena.cc
  51. 11
      src/google/protobuf/arena.h
  52. 53
      src/google/protobuf/arena_config.cc
  53. 73
      src/google/protobuf/arena_config.h
  54. 120
      src/google/protobuf/arena_impl.h
  55. 6
      src/google/protobuf/arena_test_util.cc
  56. 10
      src/google/protobuf/arena_test_util.h
  57. 36
      src/google/protobuf/arena_unittest.cc
  58. 18
      src/google/protobuf/arenastring.cc
  59. 14
      src/google/protobuf/arenastring.h
  60. 18
      src/google/protobuf/arenastring_unittest.cc
  61. 4
      src/google/protobuf/arenaz_sampler.cc
  62. 4
      src/google/protobuf/arenaz_sampler.h
  63. 4
      src/google/protobuf/arenaz_sampler_test.cc
  64. 20
      src/google/protobuf/compiler/annotation_test_util.cc
  65. 4
      src/google/protobuf/compiler/annotation_test_util.h
  66. 12
      src/google/protobuf/compiler/code_generator.cc
  67. 7
      src/google/protobuf/compiler/code_generator.h
  68. 73
      src/google/protobuf/compiler/command_line_interface.cc
  69. 6
      src/google/protobuf/compiler/command_line_interface.h
  70. 52
      src/google/protobuf/compiler/command_line_interface_unittest.cc
  71. 1
      src/google/protobuf/compiler/cpp/BUILD.bazel
  72. 20
      src/google/protobuf/compiler/cpp/bootstrap_unittest.cc
  73. 2
      src/google/protobuf/compiler/cpp/cpp_generator.h
  74. 16
      src/google/protobuf/compiler/cpp/enum.cc
  75. 4
      src/google/protobuf/compiler/cpp/enum.h
  76. 12
      src/google/protobuf/compiler/cpp/enum_field.cc
  77. 2
      src/google/protobuf/compiler/cpp/enum_field.h
  78. 14
      src/google/protobuf/compiler/cpp/extension.cc
  79. 4
      src/google/protobuf/compiler/cpp/extension.h
  80. 30
      src/google/protobuf/compiler/cpp/field.cc
  81. 6
      src/google/protobuf/compiler/cpp/field.h
  82. 45
      src/google/protobuf/compiler/cpp/file.cc
  83. 17
      src/google/protobuf/compiler/cpp/file.h
  84. 222
      src/google/protobuf/compiler/cpp/generator.cc
  85. 25
      src/google/protobuf/compiler/cpp/generator.h
  86. 189
      src/google/protobuf/compiler/cpp/helpers.cc
  87. 48
      src/google/protobuf/compiler/cpp/helpers.h
  88. 10
      src/google/protobuf/compiler/cpp/map_field.cc
  89. 4
      src/google/protobuf/compiler/cpp/map_field.h
  90. 39
      src/google/protobuf/compiler/cpp/message.cc
  91. 10
      src/google/protobuf/compiler/cpp/message.h
  92. 12
      src/google/protobuf/compiler/cpp/message_field.cc
  93. 4
      src/google/protobuf/compiler/cpp/message_field.h
  94. 4
      src/google/protobuf/compiler/cpp/message_layout_helper.h
  95. 4
      src/google/protobuf/compiler/cpp/message_size_unittest.cc
  96. 16
      src/google/protobuf/compiler/cpp/metadata_test.cc
  97. 6
      src/google/protobuf/compiler/cpp/move_unittest.cc
  98. 4
      src/google/protobuf/compiler/cpp/names.h
  99. 4
      src/google/protobuf/compiler/cpp/padding_optimizer.cc
  100. 2
      src/google/protobuf/compiler/cpp/padding_optimizer.h
  101. Some files were not shown because too many files have changed in this diff Show More

@ -12,6 +12,15 @@
* Use table-driven parser for reflection based objects. * Use table-driven parser for reflection based objects.
* Update Map's InternalSwap() to take a pointer to the other Map. * Update Map's InternalSwap() to take a pointer to the other Map.
* Add ARM-optimized Varint decoding functions. * Add ARM-optimized Varint decoding functions.
* Minor optimization for parsing groups
* Declare ReflectiveProtoHook class
* Reduce size of VarintParse code in protocol buffers, by calling the shared
routine after handling just one-byte varint encoding inline, rather than
handling one-byte and two-byte varints inline.
* Avoid inlining some large heavily duplicated routines in repeated_ptr_field.h
* Add ReflectiveProtoHook to Reflection.
* Turns on table-driven parser for reflection based objects.
Kotlin Kotlin
* Suppress deprecation warnings in Kotlin generated code. * Suppress deprecation warnings in Kotlin generated code.

@ -33,6 +33,7 @@ set(protobuf_ABSL_USED_TARGETS
absl::algorithm absl::algorithm
absl::base absl::base
absl::bind_front absl::bind_front
absl::bits
absl::cleanup absl::cleanup
absl::cord absl::cord
absl::core_headers absl::core_headers
@ -43,6 +44,7 @@ set(protobuf_ABSL_USED_TARGETS
absl::flat_hash_set absl::flat_hash_set
absl::function_ref absl::function_ref
absl::hash absl::hash
absl::layout
absl::memory absl::memory
absl::optional absl::optional
absl::span absl::span

@ -30,15 +30,15 @@
#include "binary_json_conformance_suite.h" #include "binary_json_conformance_suite.h"
#include <google/protobuf/text_format.h> #include "google/protobuf/text_format.h"
#include <google/protobuf/wire_format_lite.h> #include "google/protobuf/wire_format_lite.h"
#include <google/protobuf/util/json_util.h> #include "google/protobuf/util/json_util.h"
#include <google/protobuf/util/type_resolver_util.h> #include "google/protobuf/util/type_resolver_util.h"
#include "absl/status/status.h" #include "absl/status/status.h"
#include "third_party/jsoncpp/json.h" #include "third_party/jsoncpp/json.h"
#include "conformance_test.h" #include "conformance_test.h"
#include <google/protobuf/test_messages_proto2.pb.h> #include "google/protobuf/test_messages_proto2.pb.h"
#include <google/protobuf/test_messages_proto3.pb.h> #include "google/protobuf/test_messages_proto3.pb.h"
namespace proto2_messages = protobuf_test_messages::proto2; namespace proto2_messages = protobuf_test_messages::proto2;
@ -765,7 +765,8 @@ void BinaryAndJsonConformanceSuite::TestValidDataForType(
: cat(tag(field->number(), wire_type), values[i].second); : cat(tag(field->number(), wire_type), values[i].second);
std::unique_ptr<Message> test_message = NewTestMessage(is_proto3); std::unique_ptr<Message> test_message = NewTestMessage(is_proto3);
test_message->MergeFromString(expected_proto); test_message->MergeFromString(expected_proto);
string text = test_message->DebugString(); string text;
TextFormat::PrintToString(*test_message, &text);
RunValidProtobufTest( RunValidProtobufTest(
absl::StrCat("ValidDataScalar", type_name, "[", i, "]"), REQUIRED, absl::StrCat("ValidDataScalar", type_name, "[", i, "]"), REQUIRED,
@ -787,7 +788,8 @@ void BinaryAndJsonConformanceSuite::TestValidDataForType(
cat(tag(field->number(), wire_type), values.back().second); cat(tag(field->number(), wire_type), values.back().second);
std::unique_ptr<Message> test_message = NewTestMessage(is_proto3); std::unique_ptr<Message> test_message = NewTestMessage(is_proto3);
test_message->MergeFromString(expected_proto); test_message->MergeFromString(expected_proto);
string text = test_message->DebugString(); string text;
TextFormat::PrintToString(*test_message, &text);
RunValidProtobufTest("RepeatedScalarSelectsLast" + type_name, REQUIRED, RunValidProtobufTest("RepeatedScalarSelectsLast" + type_name, REQUIRED,
proto, text, is_proto3); proto, text, is_proto3);
@ -848,7 +850,8 @@ void BinaryAndJsonConformanceSuite::TestValidDataForType(
std::unique_ptr<Message> test_message = NewTestMessage(is_proto3); std::unique_ptr<Message> test_message = NewTestMessage(is_proto3);
test_message->MergeFromString(default_proto_packed_expected); test_message->MergeFromString(default_proto_packed_expected);
string text = test_message->DebugString(); string text;
TextFormat::PrintToString(*test_message, &text);
// Ensures both packed and unpacked data can be parsed. // Ensures both packed and unpacked data can be parsed.
RunValidProtobufTest( RunValidProtobufTest(
@ -897,7 +900,8 @@ void BinaryAndJsonConformanceSuite::TestValidDataForType(
} }
std::unique_ptr<Message> test_message = NewTestMessage(is_proto3); std::unique_ptr<Message> test_message = NewTestMessage(is_proto3);
test_message->MergeFromString(expected_proto); test_message->MergeFromString(expected_proto);
string text = test_message->DebugString(); string text;
TextFormat::PrintToString(*test_message, &text);
RunValidProtobufTest(absl::StrCat("ValidDataRepeated", type_name), RunValidProtobufTest(absl::StrCat("ValidDataRepeated", type_name),
REQUIRED, proto, text, is_proto3); REQUIRED, proto, text, is_proto3);
@ -974,7 +978,8 @@ void BinaryAndJsonConformanceSuite::TestValidDataForMapType(
delim(cat(key1_data, value1_data))); delim(cat(key1_data, value1_data)));
std::unique_ptr<Message> test_message = NewTestMessage(is_proto3); std::unique_ptr<Message> test_message = NewTestMessage(is_proto3);
test_message->MergeFromString(proto); test_message->MergeFromString(proto);
string text = test_message->DebugString(); string text;
TextFormat::PrintToString(*test_message, &text);
RunValidProtobufTest(absl::StrCat("ValidDataMap", key_type_name, RunValidProtobufTest(absl::StrCat("ValidDataMap", key_type_name,
value_type_name, ".Default"), value_type_name, ".Default"),
REQUIRED, proto, text, is_proto3); REQUIRED, proto, text, is_proto3);
@ -987,7 +992,8 @@ void BinaryAndJsonConformanceSuite::TestValidDataForMapType(
delim("")); delim(""));
std::unique_ptr<Message> test_message = NewTestMessage(is_proto3); std::unique_ptr<Message> test_message = NewTestMessage(is_proto3);
test_message->MergeFromString(proto); test_message->MergeFromString(proto);
string text = test_message->DebugString(); string text;
TextFormat::PrintToString(*test_message, &text);
RunValidProtobufTest(absl::StrCat("ValidDataMap", key_type_name, RunValidProtobufTest(absl::StrCat("ValidDataMap", key_type_name,
value_type_name, ".MissingDefault"), value_type_name, ".MissingDefault"),
REQUIRED, proto, text, is_proto3); REQUIRED, proto, text, is_proto3);
@ -1000,7 +1006,8 @@ void BinaryAndJsonConformanceSuite::TestValidDataForMapType(
delim(cat(key2_data, value2_data))); delim(cat(key2_data, value2_data)));
std::unique_ptr<Message> test_message = NewTestMessage(is_proto3); std::unique_ptr<Message> test_message = NewTestMessage(is_proto3);
test_message->MergeFromString(proto); test_message->MergeFromString(proto);
string text = test_message->DebugString(); string text;
TextFormat::PrintToString(*test_message, &text);
RunValidProtobufTest(absl::StrCat("ValidDataMap", key_type_name, RunValidProtobufTest(absl::StrCat("ValidDataMap", key_type_name,
value_type_name, ".NonDefault"), value_type_name, ".NonDefault"),
REQUIRED, proto, text, is_proto3); REQUIRED, proto, text, is_proto3);
@ -1013,7 +1020,8 @@ void BinaryAndJsonConformanceSuite::TestValidDataForMapType(
delim(cat(value2_data, key2_data))); delim(cat(value2_data, key2_data)));
std::unique_ptr<Message> test_message = NewTestMessage(is_proto3); std::unique_ptr<Message> test_message = NewTestMessage(is_proto3);
test_message->MergeFromString(proto); test_message->MergeFromString(proto);
string text = test_message->DebugString(); string text;
TextFormat::PrintToString(*test_message, &text);
RunValidProtobufTest(absl::StrCat("ValidDataMap", key_type_name, RunValidProtobufTest(absl::StrCat("ValidDataMap", key_type_name,
value_type_name, ".Unordered"), value_type_name, ".Unordered"),
REQUIRED, proto, text, is_proto3); REQUIRED, proto, text, is_proto3);
@ -1030,7 +1038,8 @@ void BinaryAndJsonConformanceSuite::TestValidDataForMapType(
string proto = cat(proto1, proto2); string proto = cat(proto1, proto2);
std::unique_ptr<Message> test_message = NewTestMessage(is_proto3); std::unique_ptr<Message> test_message = NewTestMessage(is_proto3);
test_message->MergeFromString(proto2); test_message->MergeFromString(proto2);
string text = test_message->DebugString(); string text;
TextFormat::PrintToString(*test_message, &text);
RunValidProtobufTest(absl::StrCat("ValidDataMap", key_type_name, RunValidProtobufTest(absl::StrCat("ValidDataMap", key_type_name,
value_type_name, ".DuplicateKey"), value_type_name, ".DuplicateKey"),
REQUIRED, proto, text, is_proto3); REQUIRED, proto, text, is_proto3);
@ -1043,7 +1052,8 @@ void BinaryAndJsonConformanceSuite::TestValidDataForMapType(
delim(cat(key1_data, key2_data, value2_data))); delim(cat(key1_data, key2_data, value2_data)));
std::unique_ptr<Message> test_message = NewTestMessage(is_proto3); std::unique_ptr<Message> test_message = NewTestMessage(is_proto3);
test_message->MergeFromString(proto); test_message->MergeFromString(proto);
string text = test_message->DebugString(); string text;
TextFormat::PrintToString(*test_message, &text);
RunValidProtobufTest( RunValidProtobufTest(
absl::StrCat("ValidDataMap", key_type_name, value_type_name, absl::StrCat("ValidDataMap", key_type_name, value_type_name,
".DuplicateKeyInMapEntry"), ".DuplicateKeyInMapEntry"),
@ -1057,7 +1067,8 @@ void BinaryAndJsonConformanceSuite::TestValidDataForMapType(
delim(cat(key2_data, value1_data, value2_data))); delim(cat(key2_data, value1_data, value2_data)));
std::unique_ptr<Message> test_message = NewTestMessage(is_proto3); std::unique_ptr<Message> test_message = NewTestMessage(is_proto3);
test_message->MergeFromString(proto); test_message->MergeFromString(proto);
string text = test_message->DebugString(); string text;
TextFormat::PrintToString(*test_message, &text);
RunValidProtobufTest( RunValidProtobufTest(
absl::StrCat("ValidDataMap", key_type_name, value_type_name, absl::StrCat("ValidDataMap", key_type_name, value_type_name,
".DuplicateValueInMapEntry"), ".DuplicateValueInMapEntry"),
@ -1097,7 +1108,8 @@ void BinaryAndJsonConformanceSuite::TestOverwriteMessageValueMap() {
string proto = cat(proto1, proto2); string proto = cat(proto1, proto2);
std::unique_ptr<Message> test_message = NewTestMessage(is_proto3); std::unique_ptr<Message> test_message = NewTestMessage(is_proto3);
test_message->MergeFromString(proto2); test_message->MergeFromString(proto2);
string text = test_message->DebugString(); string text;
TextFormat::PrintToString(*test_message, &text);
RunValidProtobufTest("ValidDataMap.STRING.MESSAGE.MergeValue", REQUIRED, RunValidProtobufTest("ValidDataMap.STRING.MESSAGE.MergeValue", REQUIRED,
proto, text, is_proto3); proto, text, is_proto3);
} }
@ -1122,7 +1134,8 @@ void BinaryAndJsonConformanceSuite::TestValidDataForOneofType(
const string proto = default_value; const string proto = default_value;
std::unique_ptr<Message> test_message = NewTestMessage(is_proto3); std::unique_ptr<Message> test_message = NewTestMessage(is_proto3);
test_message->MergeFromString(proto); test_message->MergeFromString(proto);
string text = test_message->DebugString(); string text;
TextFormat::PrintToString(*test_message, &text);
RunValidProtobufTest( RunValidProtobufTest(
absl::StrCat("ValidDataOneof", type_name, ".DefaultValue"), REQUIRED, absl::StrCat("ValidDataOneof", type_name, ".DefaultValue"), REQUIRED,
@ -1137,7 +1150,8 @@ void BinaryAndJsonConformanceSuite::TestValidDataForOneofType(
const string proto = non_default_value; const string proto = non_default_value;
std::unique_ptr<Message> test_message = NewTestMessage(is_proto3); std::unique_ptr<Message> test_message = NewTestMessage(is_proto3);
test_message->MergeFromString(proto); test_message->MergeFromString(proto);
string text = test_message->DebugString(); string text;
TextFormat::PrintToString(*test_message, &text);
RunValidProtobufTest( RunValidProtobufTest(
absl::StrCat("ValidDataOneof", type_name, ".NonDefaultValue"), absl::StrCat("ValidDataOneof", type_name, ".NonDefaultValue"),
@ -1153,7 +1167,8 @@ void BinaryAndJsonConformanceSuite::TestValidDataForOneofType(
const string expected_proto = non_default_value; const string expected_proto = non_default_value;
std::unique_ptr<Message> test_message = NewTestMessage(is_proto3); std::unique_ptr<Message> test_message = NewTestMessage(is_proto3);
test_message->MergeFromString(expected_proto); test_message->MergeFromString(expected_proto);
string text = test_message->DebugString(); string text;
TextFormat::PrintToString(*test_message, &text);
RunValidProtobufTest(absl::StrCat("ValidDataOneof", type_name, RunValidProtobufTest(absl::StrCat("ValidDataOneof", type_name,
".MultipleValuesForSameField"), ".MultipleValuesForSameField"),
@ -1179,7 +1194,8 @@ void BinaryAndJsonConformanceSuite::TestValidDataForOneofType(
const string expected_proto = non_default_value; const string expected_proto = non_default_value;
std::unique_ptr<Message> test_message = NewTestMessage(is_proto3); std::unique_ptr<Message> test_message = NewTestMessage(is_proto3);
test_message->MergeFromString(expected_proto); test_message->MergeFromString(expected_proto);
string text = test_message->DebugString(); string text;
TextFormat::PrintToString(*test_message, &text);
RunValidProtobufTest(absl::StrCat("ValidDataOneof", type_name, RunValidProtobufTest(absl::StrCat("ValidDataOneof", type_name,
".MultipleValuesForDifferentField"), ".MultipleValuesForDifferentField"),
@ -1224,7 +1240,8 @@ void BinaryAndJsonConformanceSuite::TestMergeOneofMessage() {
std::unique_ptr<Message> test_message = NewTestMessage(is_proto3); std::unique_ptr<Message> test_message = NewTestMessage(is_proto3);
test_message->MergeFromString(expected_proto); test_message->MergeFromString(expected_proto);
string text = test_message->DebugString(); string text;
TextFormat::PrintToString(*test_message, &text);
RunValidProtobufTest("ValidDataOneof.MESSAGE.Merge", REQUIRED, proto, text, RunValidProtobufTest("ValidDataOneof.MESSAGE.Merge", REQUIRED, proto, text,
is_proto3); is_proto3);
RunValidBinaryProtobufTest("ValidDataOneofBinary.MESSAGE.Merge", RunValidBinaryProtobufTest("ValidDataOneofBinary.MESSAGE.Merge",

@ -36,24 +36,24 @@
#include <string> #include <string>
#include <utility> #include <utility>
#include <google/protobuf/stubs/logging.h> #include "google/protobuf/stubs/logging.h"
#include <google/protobuf/stubs/common.h> #include "google/protobuf/stubs/common.h"
#include <google/protobuf/message.h> #include "google/protobuf/message.h"
#include <google/protobuf/text_format.h> #include "google/protobuf/text_format.h"
#include <google/protobuf/util/json_util.h> #include "google/protobuf/util/json_util.h"
#include <google/protobuf/util/type_resolver_util.h> #include "google/protobuf/util/type_resolver_util.h"
#include "absl/status/status.h" #include "absl/status/status.h"
#include "absl/status/statusor.h" #include "absl/status/statusor.h"
#include "conformance/conformance.pb.h" #include "conformance/conformance.pb.h"
#include "conformance/conformance.pb.h" #include "conformance/conformance.pb.h"
#include <google/protobuf/test_messages_proto2.pb.h> #include "google/protobuf/test_messages_proto2.pb.h"
#include <google/protobuf/test_messages_proto3.pb.h> #include "google/protobuf/test_messages_proto3.pb.h"
#include <google/protobuf/test_messages_proto3.pb.h> #include "google/protobuf/test_messages_proto3.pb.h"
#include <google/protobuf/util/type_resolver.h> #include "google/protobuf/util/type_resolver.h"
#include <google/protobuf/stubs/status_macros.h> #include "google/protobuf/stubs/status_macros.h"
// Must be included last. // Must be included last.
#include <google/protobuf/port_def.inc> #include "google/protobuf/port_def.inc"
namespace google { namespace google {
namespace protobuf { namespace protobuf {

@ -36,12 +36,12 @@
#include <set> #include <set>
#include <string> #include <string>
#include <google/protobuf/stubs/stringprintf.h> #include "google/protobuf/stubs/stringprintf.h"
#include <google/protobuf/message.h> #include "google/protobuf/message.h"
#include <google/protobuf/text_format.h> #include "google/protobuf/text_format.h"
#include <google/protobuf/util/field_comparator.h> #include "google/protobuf/util/field_comparator.h"
#include <google/protobuf/util/json_util.h> #include "google/protobuf/util/json_util.h"
#include <google/protobuf/util/message_differencer.h> #include "google/protobuf/util/message_differencer.h"
#include "conformance/conformance.pb.h" #include "conformance/conformance.pb.h"
using conformance::ConformanceRequest; using conformance::ConformanceRequest;

@ -42,9 +42,9 @@
#include <string> #include <string>
#include <vector> #include <vector>
#include <google/protobuf/descriptor.h> #include "google/protobuf/descriptor.h"
#include <google/protobuf/wire_format_lite.h> #include "google/protobuf/wire_format_lite.h"
#include <google/protobuf/util/type_resolver.h> #include "google/protobuf/util/type_resolver.h"
#include "conformance/conformance.pb.h" #include "conformance/conformance.pb.h"
namespace conformance { namespace conformance {

@ -62,7 +62,7 @@
#include <fstream> #include <fstream>
#include <vector> #include <vector>
#include <google/protobuf/stubs/stringprintf.h> #include "google/protobuf/stubs/stringprintf.h"
#include "conformance/conformance.pb.h" #include "conformance/conformance.pb.h"
#include "conformance_test.h" #include "conformance_test.h"

@ -30,11 +30,11 @@
#include "text_format_conformance_suite.h" #include "text_format_conformance_suite.h"
#include <google/protobuf/any.pb.h> #include "google/protobuf/any.pb.h"
#include <google/protobuf/text_format.h> #include "google/protobuf/text_format.h"
#include "conformance_test.h" #include "conformance_test.h"
#include <google/protobuf/test_messages_proto2.pb.h> #include "google/protobuf/test_messages_proto2.pb.h"
#include <google/protobuf/test_messages_proto3.pb.h> #include "google/protobuf/test_messages_proto3.pb.h"
namespace proto2_messages = protobuf_test_messages::proto2; namespace proto2_messages = protobuf_test_messages::proto2;

@ -115,6 +115,6 @@ def protobuf_deps():
_github_archive( _github_archive(
name = "upb", name = "upb",
repo = "https://github.com/protocolbuffers/upb", repo = "https://github.com/protocolbuffers/upb",
commit = "470f06cccbf26f98dd2df7ddecf24a78f140fe11", commit = "5485645125ba3783ae2b597bd7b77679721cb1c6",
sha256 = "c3137f3da811142d33d2ad278d093152610d3a773b17839d272bca4b1a6e304b", sha256 = "86de85c58eb3cb04b0987a7642ce84e55629f704ab4a9a0210a660a1115f1dd0",
) )

@ -889,6 +889,7 @@ class MessageTest(unittest.TestCase):
def testOneofClearField(self, message_module): def testOneofClearField(self, message_module):
m = message_module.TestAllTypes() m = message_module.TestAllTypes()
m.ClearField('oneof_field')
m.oneof_uint32 = 11 m.oneof_uint32 = 11
m.ClearField('oneof_field') m.ClearField('oneof_field')
if message_module is unittest_pb2: if message_module is unittest_pb2:

@ -30,7 +30,7 @@
// Author: qrczak@google.com (Marcin Kowalczyk) // Author: qrczak@google.com (Marcin Kowalczyk)
#include <google/protobuf/python/python_protobuf.h> #include "google/protobuf/python/python_protobuf.h"
namespace google { namespace google {
namespace protobuf { namespace protobuf {

@ -2485,6 +2485,5 @@ class OptionalColonMessageToStringTest(unittest.TestCase):
if __name__ == '__main__': if __name__ == '__main__':
unittest.main() unittest.main()

@ -48,8 +48,8 @@
#define PY_SSIZE_T_CLEAN #define PY_SSIZE_T_CLEAN
#include <Python.h> #include <Python.h>
#include <google/protobuf/descriptor_database.h> #include "google/protobuf/descriptor_database.h"
#include <google/protobuf/message.h> #include "google/protobuf/message.h"
namespace google { namespace google {
namespace protobuf { namespace protobuf {

@ -30,7 +30,7 @@
// Author: petar@google.com (Petar Petrov) // Author: petar@google.com (Petar Petrov)
#include <google/protobuf/pyext/descriptor.h> #include "google/protobuf/pyext/descriptor.h"
#define PY_SSIZE_T_CLEAN #define PY_SSIZE_T_CLEAN
#include <Python.h> #include <Python.h>
@ -40,15 +40,15 @@
#include <string> #include <string>
#include <unordered_map> #include <unordered_map>
#include <google/protobuf/descriptor.pb.h> #include "google/protobuf/descriptor.pb.h"
#include <google/protobuf/dynamic_message.h> #include "google/protobuf/dynamic_message.h"
#include <google/protobuf/pyext/descriptor_containers.h> #include "google/protobuf/pyext/descriptor_containers.h"
#include <google/protobuf/pyext/descriptor_pool.h> #include "google/protobuf/pyext/descriptor_pool.h"
#include <google/protobuf/pyext/message.h> #include "google/protobuf/pyext/message.h"
#include <google/protobuf/pyext/message_factory.h> #include "google/protobuf/pyext/message_factory.h"
#include <google/protobuf/pyext/scoped_pyobject_ptr.h> #include "google/protobuf/pyext/scoped_pyobject_ptr.h"
#include "absl/strings/string_view.h" #include "absl/strings/string_view.h"
#include <google/protobuf/io/coded_stream.h> #include "google/protobuf/io/coded_stream.h"
#define PyString_AsStringAndSize(ob, charpp, sizep) \ #define PyString_AsStringAndSize(ob, charpp, sizep) \
(PyUnicode_Check(ob) \ (PyUnicode_Check(ob) \

@ -36,7 +36,7 @@
#define PY_SSIZE_T_CLEAN #define PY_SSIZE_T_CLEAN
#include <Python.h> #include <Python.h>
#include <google/protobuf/descriptor.h> #include "google/protobuf/descriptor.h"
namespace google { namespace google {
namespace protobuf { namespace protobuf {

@ -54,13 +54,13 @@
// This inclusion must appear before all the others. // This inclusion must appear before all the others.
#include <Python.h> #include <Python.h>
#include <google/protobuf/pyext/descriptor_containers.h> #include "google/protobuf/pyext/descriptor_containers.h"
// clang-format on // clang-format on
#include <google/protobuf/descriptor.h> #include "google/protobuf/descriptor.h"
#include <google/protobuf/pyext/descriptor.h> #include "google/protobuf/pyext/descriptor.h"
#include <google/protobuf/pyext/descriptor_pool.h> #include "google/protobuf/pyext/descriptor_pool.h"
#include <google/protobuf/pyext/scoped_pyobject_ptr.h> #include "google/protobuf/pyext/scoped_pyobject_ptr.h"
#include "absl/strings/string_view.h" #include "absl/strings/string_view.h"
#define PyString_AsStringAndSize(ob, charpp, sizep) \ #define PyString_AsStringAndSize(ob, charpp, sizep) \

@ -31,15 +31,15 @@
// This file defines a C++ DescriptorDatabase, which wraps a Python Database // This file defines a C++ DescriptorDatabase, which wraps a Python Database
// and delegate all its operations to Python methods. // and delegate all its operations to Python methods.
#include <google/protobuf/pyext/descriptor_database.h> #include "google/protobuf/pyext/descriptor_database.h"
#include <cstdint> #include <cstdint>
#include <google/protobuf/stubs/logging.h> #include "google/protobuf/stubs/logging.h"
#include <google/protobuf/stubs/common.h> #include "google/protobuf/stubs/common.h"
#include <google/protobuf/descriptor.pb.h> #include "google/protobuf/descriptor.pb.h"
#include <google/protobuf/pyext/message.h> #include "google/protobuf/pyext/message.h"
#include <google/protobuf/pyext/scoped_pyobject_ptr.h> #include "google/protobuf/pyext/scoped_pyobject_ptr.h"
namespace google { namespace google {
namespace protobuf { namespace protobuf {

@ -34,7 +34,7 @@
#define PY_SSIZE_T_CLEAN #define PY_SSIZE_T_CLEAN
#include <Python.h> #include <Python.h>
#include <google/protobuf/descriptor_database.h> #include "google/protobuf/descriptor_database.h"
namespace google { namespace google {
namespace protobuf { namespace protobuf {

@ -35,13 +35,13 @@
#define PY_SSIZE_T_CLEAN #define PY_SSIZE_T_CLEAN
#include <Python.h> #include <Python.h>
#include <google/protobuf/descriptor.pb.h> #include "google/protobuf/descriptor.pb.h"
#include <google/protobuf/pyext/descriptor.h> #include "google/protobuf/pyext/descriptor.h"
#include <google/protobuf/pyext/descriptor_database.h> #include "google/protobuf/pyext/descriptor_database.h"
#include <google/protobuf/pyext/descriptor_pool.h> #include "google/protobuf/pyext/descriptor_pool.h"
#include <google/protobuf/pyext/message.h> #include "google/protobuf/pyext/message.h"
#include <google/protobuf/pyext/message_factory.h> #include "google/protobuf/pyext/message_factory.h"
#include <google/protobuf/pyext/scoped_pyobject_ptr.h> #include "google/protobuf/pyext/scoped_pyobject_ptr.h"
#include "absl/strings/string_view.h" #include "absl/strings/string_view.h"
#define PyString_AsStringAndSize(ob, charpp, sizep) \ #define PyString_AsStringAndSize(ob, charpp, sizep) \

@ -35,7 +35,7 @@
#include <Python.h> #include <Python.h>
#include <unordered_map> #include <unordered_map>
#include <google/protobuf/descriptor.h> #include "google/protobuf/descriptor.h"
namespace google { namespace google {
namespace protobuf { namespace protobuf {

@ -31,23 +31,23 @@
// Author: anuraag@google.com (Anuraag Agrawal) // Author: anuraag@google.com (Anuraag Agrawal)
// Author: tibell@google.com (Johan Tibell) // Author: tibell@google.com (Johan Tibell)
#include <google/protobuf/pyext/extension_dict.h> #include "google/protobuf/pyext/extension_dict.h"
#include <cstdint> #include <cstdint>
#include <memory> #include <memory>
#include <google/protobuf/stubs/logging.h> #include "google/protobuf/stubs/logging.h"
#include <google/protobuf/stubs/common.h> #include "google/protobuf/stubs/common.h"
#include <google/protobuf/descriptor.pb.h> #include "google/protobuf/descriptor.pb.h"
#include <google/protobuf/descriptor.h> #include "google/protobuf/descriptor.h"
#include <google/protobuf/dynamic_message.h> #include "google/protobuf/dynamic_message.h"
#include <google/protobuf/message.h> #include "google/protobuf/message.h"
#include <google/protobuf/pyext/descriptor.h> #include "google/protobuf/pyext/descriptor.h"
#include <google/protobuf/pyext/message.h> #include "google/protobuf/pyext/message.h"
#include <google/protobuf/pyext/message_factory.h> #include "google/protobuf/pyext/message_factory.h"
#include <google/protobuf/pyext/repeated_composite_container.h> #include "google/protobuf/pyext/repeated_composite_container.h"
#include <google/protobuf/pyext/repeated_scalar_container.h> #include "google/protobuf/pyext/repeated_scalar_container.h"
#include <google/protobuf/pyext/scoped_pyobject_ptr.h> #include "google/protobuf/pyext/scoped_pyobject_ptr.h"
#include "absl/strings/string_view.h" #include "absl/strings/string_view.h"
#define PyString_AsStringAndSize(ob, charpp, sizep) \ #define PyString_AsStringAndSize(ob, charpp, sizep) \

@ -37,7 +37,7 @@
#define PY_SSIZE_T_CLEAN #define PY_SSIZE_T_CLEAN
#include <Python.h> #include <Python.h>
#include <google/protobuf/pyext/message.h> #include "google/protobuf/pyext/message.h"
namespace google { namespace google {
namespace protobuf { namespace protobuf {

@ -28,11 +28,11 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <google/protobuf/pyext/field.h> #include "google/protobuf/pyext/field.h"
#include <google/protobuf/descriptor.h> #include "google/protobuf/descriptor.h"
#include <google/protobuf/pyext/descriptor.h> #include "google/protobuf/pyext/descriptor.h"
#include <google/protobuf/pyext/message.h> #include "google/protobuf/pyext/message.h"
namespace google { namespace google {
namespace protobuf { namespace protobuf {

@ -30,21 +30,20 @@
// Author: haberman@google.com (Josh Haberman) // Author: haberman@google.com (Josh Haberman)
#include <google/protobuf/pyext/map_container.h> #include "google/protobuf/pyext/map_container.h"
#include <cstdint> #include <cstdint>
#include <memory> #include <memory>
#include <google/protobuf/stubs/logging.h> #include "google/protobuf/stubs/logging.h"
#include <google/protobuf/stubs/common.h> #include "google/protobuf/stubs/common.h"
#include <google/protobuf/map.h> #include "google/protobuf/map.h"
#include <google/protobuf/map_field.h> #include "google/protobuf/map_field.h"
#include <google/protobuf/message.h> #include "google/protobuf/message.h"
#include <google/protobuf/pyext/message.h> #include "google/protobuf/pyext/message.h"
#include <google/protobuf/pyext/message_factory.h> #include "google/protobuf/pyext/message_factory.h"
#include <google/protobuf/pyext/repeated_composite_container.h> #include "google/protobuf/pyext/repeated_composite_container.h"
#include <google/protobuf/pyext/scoped_pyobject_ptr.h> #include "google/protobuf/pyext/scoped_pyobject_ptr.h"
#include <google/protobuf/stubs/map_util.h>
namespace google { namespace google {
namespace protobuf { namespace protobuf {

@ -36,9 +36,9 @@
#include <cstdint> #include <cstdint>
#include <google/protobuf/descriptor.h> #include "google/protobuf/descriptor.h"
#include <google/protobuf/message.h> #include "google/protobuf/message.h"
#include <google/protobuf/pyext/message.h> #include "google/protobuf/pyext/message.h"
namespace google { namespace google {
namespace protobuf { namespace protobuf {

@ -31,7 +31,7 @@
// Author: anuraag@google.com (Anuraag Agrawal) // Author: anuraag@google.com (Anuraag Agrawal)
// Author: tibell@google.com (Johan Tibell) // Author: tibell@google.com (Johan Tibell)
#include <google/protobuf/pyext/message.h> #include "google/protobuf/pyext/message.h"
#include <structmember.h> // A Python header file. #include <structmember.h> // A Python header file.
@ -41,7 +41,7 @@
#include <string> #include <string>
#include <vector> #include <vector>
#include <google/protobuf/stubs/strutil.h> #include "google/protobuf/stubs/strutil.h"
#ifndef PyVarObject_HEAD_INIT #ifndef PyVarObject_HEAD_INIT
#define PyVarObject_HEAD_INIT(type, size) PyObject_HEAD_INIT(type) size, #define PyVarObject_HEAD_INIT(type, size) PyObject_HEAD_INIT(type) size,
@ -49,34 +49,33 @@
#ifndef Py_TYPE #ifndef Py_TYPE
#define Py_TYPE(ob) (((PyObject*)(ob))->ob_type) #define Py_TYPE(ob) (((PyObject*)(ob))->ob_type)
#endif #endif
#include <google/protobuf/stubs/common.h> #include "google/protobuf/stubs/common.h"
#include <google/protobuf/stubs/logging.h> #include "google/protobuf/stubs/logging.h"
#include <google/protobuf/descriptor.pb.h> #include "google/protobuf/descriptor.pb.h"
#include <google/protobuf/descriptor.h> #include "google/protobuf/descriptor.h"
#include <google/protobuf/message.h> #include "google/protobuf/message.h"
#include <google/protobuf/text_format.h> #include "google/protobuf/text_format.h"
#include <google/protobuf/unknown_field_set.h> #include "google/protobuf/unknown_field_set.h"
#include <google/protobuf/pyext/descriptor.h> #include "google/protobuf/pyext/descriptor.h"
#include <google/protobuf/pyext/descriptor_pool.h> #include "google/protobuf/pyext/descriptor_pool.h"
#include <google/protobuf/pyext/extension_dict.h> #include "google/protobuf/pyext/extension_dict.h"
#include <google/protobuf/pyext/field.h> #include "google/protobuf/pyext/field.h"
#include <google/protobuf/pyext/map_container.h> #include "google/protobuf/pyext/map_container.h"
#include <google/protobuf/pyext/message_factory.h> #include "google/protobuf/pyext/message_factory.h"
#include <google/protobuf/pyext/repeated_composite_container.h> #include "google/protobuf/pyext/repeated_composite_container.h"
#include <google/protobuf/pyext/repeated_scalar_container.h> #include "google/protobuf/pyext/repeated_scalar_container.h"
#include <google/protobuf/pyext/safe_numerics.h> #include "google/protobuf/pyext/safe_numerics.h"
#include <google/protobuf/pyext/scoped_pyobject_ptr.h> #include "google/protobuf/pyext/scoped_pyobject_ptr.h"
#include <google/protobuf/pyext/unknown_field_set.h> #include "google/protobuf/pyext/unknown_field_set.h"
#include <google/protobuf/pyext/unknown_fields.h> #include "google/protobuf/pyext/unknown_fields.h"
#include <google/protobuf/util/message_differencer.h> #include "google/protobuf/util/message_differencer.h"
#include "absl/strings/string_view.h" #include "absl/strings/string_view.h"
#include <google/protobuf/io/coded_stream.h> #include "google/protobuf/io/coded_stream.h"
#include <google/protobuf/io/strtod.h> #include "google/protobuf/io/strtod.h"
#include <google/protobuf/io/zero_copy_stream_impl_lite.h> #include "google/protobuf/io/zero_copy_stream_impl_lite.h"
#include <google/protobuf/stubs/map_util.h>
// clang-format off // clang-format off
#include <google/protobuf/port_def.inc> #include "google/protobuf/port_def.inc"
// clang-format on // clang-format on
#define PyString_AsString(ob) \ #define PyString_AsString(ob) \
@ -2677,12 +2676,13 @@ CMessage* CMessage::BuildSubMessageFromPointer(
if (!this->child_submessages) { if (!this->child_submessages) {
this->child_submessages = new CMessage::SubMessagesMap(); this->child_submessages = new CMessage::SubMessagesMap();
} }
CMessage* cmsg = FindPtrOrNull( auto it = this->child_submessages->find(sub_message);
*this->child_submessages, sub_message); if (it != this->child_submessages->end()) {
if (cmsg) { Py_INCREF(it->second);
Py_INCREF(cmsg); return it->second;
} else { }
cmsg = cmessage::NewEmptyMessage(message_class);
CMessage* cmsg = cmessage::NewEmptyMessage(message_class);
if (cmsg == nullptr) { if (cmsg == nullptr) {
return nullptr; return nullptr;
@ -2692,7 +2692,6 @@ CMessage* CMessage::BuildSubMessageFromPointer(
cmsg->parent = this; cmsg->parent = this;
cmsg->parent_field_descriptor = field_descriptor; cmsg->parent_field_descriptor = field_descriptor;
cmessage::SetSubmessage(this, cmsg); cmessage::SetSubmessage(this, cmsg);
}
return cmsg; return cmsg;
} }
@ -2700,11 +2699,10 @@ CMessage* CMessage::MaybeReleaseSubMessage(Message* sub_message) {
if (!this->child_submessages) { if (!this->child_submessages) {
return nullptr; return nullptr;
} }
CMessage* released = FindPtrOrNull( auto it = this->child_submessages->find(sub_message);
*this->child_submessages, sub_message); if (it == this->child_submessages->end()) return nullptr;
if (!released) { CMessage* released = it->second;
return nullptr;
}
// The target message will now own its content. // The target message will now own its content.
Py_CLEAR(released->parent); Py_CLEAR(released->parent);
released->parent_field_descriptor = nullptr; released->parent_field_descriptor = nullptr;

@ -42,7 +42,7 @@
#include <string> #include <string>
#include <unordered_map> #include <unordered_map>
#include <google/protobuf/stubs/common.h> #include "google/protobuf/stubs/common.h"
namespace google { namespace google {
namespace protobuf { namespace protobuf {

@ -33,11 +33,11 @@
#define PY_SSIZE_T_CLEAN #define PY_SSIZE_T_CLEAN
#include <Python.h> #include <Python.h>
#include <google/protobuf/dynamic_message.h> #include "google/protobuf/dynamic_message.h"
#include <google/protobuf/pyext/descriptor.h> #include "google/protobuf/pyext/descriptor.h"
#include <google/protobuf/pyext/message.h> #include "google/protobuf/pyext/message.h"
#include <google/protobuf/pyext/message_factory.h> #include "google/protobuf/pyext/message_factory.h"
#include <google/protobuf/pyext/scoped_pyobject_ptr.h> #include "google/protobuf/pyext/scoped_pyobject_ptr.h"
#define PyString_AsStringAndSize(ob, charpp, sizep) \ #define PyString_AsStringAndSize(ob, charpp, sizep) \
(PyUnicode_Check(ob) \ (PyUnicode_Check(ob) \

@ -35,8 +35,8 @@
#include <Python.h> #include <Python.h>
#include <unordered_map> #include <unordered_map>
#include <google/protobuf/descriptor.h> #include "google/protobuf/descriptor.h"
#include <google/protobuf/pyext/descriptor_pool.h> #include "google/protobuf/pyext/descriptor_pool.h"
namespace google { namespace google {
namespace protobuf { namespace protobuf {

@ -31,12 +31,12 @@
#define PY_SSIZE_T_CLEAN #define PY_SSIZE_T_CLEAN
#include <Python.h> #include <Python.h>
#include <google/protobuf/message_lite.h> #include "google/protobuf/message_lite.h"
#include <google/protobuf/pyext/descriptor.h> #include "google/protobuf/pyext/descriptor.h"
#include <google/protobuf/pyext/descriptor_pool.h> #include "google/protobuf/pyext/descriptor_pool.h"
#include <google/protobuf/pyext/message.h> #include "google/protobuf/pyext/message.h"
#include <google/protobuf/pyext/message_factory.h> #include "google/protobuf/pyext/message_factory.h"
#include <google/protobuf/proto_api.h> #include "google/protobuf/proto_api.h"
namespace { namespace {

@ -31,22 +31,21 @@
// Author: anuraag@google.com (Anuraag Agrawal) // Author: anuraag@google.com (Anuraag Agrawal)
// Author: tibell@google.com (Johan Tibell) // Author: tibell@google.com (Johan Tibell)
#include <google/protobuf/pyext/repeated_composite_container.h> #include "google/protobuf/pyext/repeated_composite_container.h"
#include <memory> #include <memory>
#include <google/protobuf/stubs/logging.h> #include "google/protobuf/stubs/logging.h"
#include <google/protobuf/stubs/common.h> #include "google/protobuf/stubs/common.h"
#include <google/protobuf/descriptor.h> #include "google/protobuf/descriptor.h"
#include <google/protobuf/dynamic_message.h> #include "google/protobuf/dynamic_message.h"
#include <google/protobuf/message.h> #include "google/protobuf/message.h"
#include <google/protobuf/reflection.h> #include "google/protobuf/reflection.h"
#include <google/protobuf/pyext/descriptor.h> #include "google/protobuf/pyext/descriptor.h"
#include <google/protobuf/pyext/descriptor_pool.h> #include "google/protobuf/pyext/descriptor_pool.h"
#include <google/protobuf/pyext/message.h> #include "google/protobuf/pyext/message.h"
#include <google/protobuf/pyext/message_factory.h> #include "google/protobuf/pyext/message_factory.h"
#include <google/protobuf/pyext/scoped_pyobject_ptr.h> #include "google/protobuf/pyext/scoped_pyobject_ptr.h"
#include <google/protobuf/stubs/map_util.h>
namespace google { namespace google {
namespace protobuf { namespace protobuf {

@ -37,7 +37,7 @@
#define PY_SSIZE_T_CLEAN #define PY_SSIZE_T_CLEAN
#include <Python.h> #include <Python.h>
#include <google/protobuf/pyext/message.h> #include "google/protobuf/pyext/message.h"
namespace google { namespace google {
namespace protobuf { namespace protobuf {

@ -31,20 +31,20 @@
// Author: anuraag@google.com (Anuraag Agrawal) // Author: anuraag@google.com (Anuraag Agrawal)
// Author: tibell@google.com (Johan Tibell) // Author: tibell@google.com (Johan Tibell)
#include <google/protobuf/pyext/repeated_scalar_container.h> #include "google/protobuf/pyext/repeated_scalar_container.h"
#include <cstdint> #include <cstdint>
#include <memory> #include <memory>
#include <google/protobuf/stubs/common.h> #include "google/protobuf/stubs/common.h"
#include <google/protobuf/stubs/logging.h> #include "google/protobuf/stubs/logging.h"
#include <google/protobuf/descriptor.h> #include "google/protobuf/descriptor.h"
#include <google/protobuf/dynamic_message.h> #include "google/protobuf/dynamic_message.h"
#include <google/protobuf/message.h> #include "google/protobuf/message.h"
#include <google/protobuf/pyext/descriptor.h> #include "google/protobuf/pyext/descriptor.h"
#include <google/protobuf/pyext/descriptor_pool.h> #include "google/protobuf/pyext/descriptor_pool.h"
#include <google/protobuf/pyext/message.h> #include "google/protobuf/pyext/message.h"
#include <google/protobuf/pyext/scoped_pyobject_ptr.h> #include "google/protobuf/pyext/scoped_pyobject_ptr.h"
#define PyString_AsString(ob) \ #define PyString_AsString(ob) \
(PyUnicode_Check(ob) ? PyUnicode_AsUTF8(ob) : PyBytes_AsString(ob)) (PyUnicode_Check(ob) ? PyUnicode_AsUTF8(ob) : PyBytes_AsString(ob))

@ -37,8 +37,8 @@
#define PY_SSIZE_T_CLEAN #define PY_SSIZE_T_CLEAN
#include <Python.h> #include <Python.h>
#include <google/protobuf/descriptor.h> #include "google/protobuf/descriptor.h"
#include <google/protobuf/pyext/message.h> #include "google/protobuf/pyext/message.h"
namespace google { namespace google {
namespace protobuf { namespace protobuf {

@ -34,8 +34,8 @@
#include <limits> #include <limits>
#include <google/protobuf/stubs/logging.h> #include "google/protobuf/stubs/logging.h"
#include <google/protobuf/stubs/common.h> #include "google/protobuf/stubs/common.h"
namespace google { namespace google {
namespace protobuf { namespace protobuf {

@ -28,7 +28,7 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <google/protobuf/pyext/unknown_field_set.h> #include "google/protobuf/pyext/unknown_field_set.h"
#define PY_SSIZE_T_CLEAN #define PY_SSIZE_T_CLEAN
#include <Python.h> #include <Python.h>
@ -36,11 +36,11 @@
#include <memory> #include <memory>
#include <set> #include <set>
#include <google/protobuf/message.h> #include "google/protobuf/message.h"
#include <google/protobuf/unknown_field_set.h> #include "google/protobuf/unknown_field_set.h"
#include <google/protobuf/wire_format_lite.h> #include "google/protobuf/wire_format_lite.h"
#include <google/protobuf/pyext/message.h> #include "google/protobuf/pyext/message.h"
#include <google/protobuf/pyext/scoped_pyobject_ptr.h> #include "google/protobuf/pyext/scoped_pyobject_ptr.h"
namespace google { namespace google {
namespace protobuf { namespace protobuf {

@ -37,7 +37,7 @@
#include <memory> #include <memory>
#include <set> #include <set>
#include <google/protobuf/pyext/message.h> #include "google/protobuf/pyext/message.h"
namespace google { namespace google {
namespace protobuf { namespace protobuf {

@ -28,18 +28,18 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <google/protobuf/pyext/unknown_fields.h> #include "google/protobuf/pyext/unknown_fields.h"
#define PY_SSIZE_T_CLEAN #define PY_SSIZE_T_CLEAN
#include <Python.h> #include <Python.h>
#include <set> #include <set>
#include <memory> #include <memory>
#include <google/protobuf/message.h> #include "google/protobuf/message.h"
#include <google/protobuf/pyext/message.h> #include "google/protobuf/pyext/message.h"
#include <google/protobuf/pyext/scoped_pyobject_ptr.h> #include "google/protobuf/pyext/scoped_pyobject_ptr.h"
#include <google/protobuf/unknown_field_set.h> #include "google/protobuf/unknown_field_set.h"
#include <google/protobuf/wire_format_lite.h> #include "google/protobuf/wire_format_lite.h"
namespace google { namespace google {
namespace protobuf { namespace protobuf {

@ -37,7 +37,7 @@
#include <memory> #include <memory>
#include <set> #include <set>
#include <google/protobuf/pyext/message.h> #include "google/protobuf/pyext/message.h"
namespace google { namespace google {
namespace protobuf { namespace protobuf {

@ -16,6 +16,7 @@ set(libprotobuf_srcs
${protobuf_SOURCE_DIR}/src/google/protobuf/any_lite.cc ${protobuf_SOURCE_DIR}/src/google/protobuf/any_lite.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/api.pb.cc ${protobuf_SOURCE_DIR}/src/google/protobuf/api.pb.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/arena.cc ${protobuf_SOURCE_DIR}/src/google/protobuf/arena.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/arena_config.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/arenastring.cc ${protobuf_SOURCE_DIR}/src/google/protobuf/arenastring.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/arenaz_sampler.cc ${protobuf_SOURCE_DIR}/src/google/protobuf/arenaz_sampler.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/importer.cc ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/importer.cc
@ -61,7 +62,6 @@ set(libprotobuf_srcs
${protobuf_SOURCE_DIR}/src/google/protobuf/struct.pb.cc ${protobuf_SOURCE_DIR}/src/google/protobuf/struct.pb.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/stubs/bytestream.cc ${protobuf_SOURCE_DIR}/src/google/protobuf/stubs/bytestream.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/stubs/common.cc ${protobuf_SOURCE_DIR}/src/google/protobuf/stubs/common.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/stubs/int128.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/stubs/stringprintf.cc ${protobuf_SOURCE_DIR}/src/google/protobuf/stubs/stringprintf.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/stubs/structurally_valid.cc ${protobuf_SOURCE_DIR}/src/google/protobuf/stubs/structurally_valid.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/stubs/strutil.cc ${protobuf_SOURCE_DIR}/src/google/protobuf/stubs/strutil.cc
@ -100,6 +100,7 @@ set(libprotobuf_hdrs
${protobuf_SOURCE_DIR}/src/google/protobuf/any.pb.h ${protobuf_SOURCE_DIR}/src/google/protobuf/any.pb.h
${protobuf_SOURCE_DIR}/src/google/protobuf/api.pb.h ${protobuf_SOURCE_DIR}/src/google/protobuf/api.pb.h
${protobuf_SOURCE_DIR}/src/google/protobuf/arena.h ${protobuf_SOURCE_DIR}/src/google/protobuf/arena.h
${protobuf_SOURCE_DIR}/src/google/protobuf/arena_config.h
${protobuf_SOURCE_DIR}/src/google/protobuf/arena_impl.h ${protobuf_SOURCE_DIR}/src/google/protobuf/arena_impl.h
${protobuf_SOURCE_DIR}/src/google/protobuf/arenastring.h ${protobuf_SOURCE_DIR}/src/google/protobuf/arenastring.h
${protobuf_SOURCE_DIR}/src/google/protobuf/arenaz_sampler.h ${protobuf_SOURCE_DIR}/src/google/protobuf/arenaz_sampler.h
@ -162,10 +163,7 @@ set(libprotobuf_hdrs
${protobuf_SOURCE_DIR}/src/google/protobuf/stubs/bytestream.h ${protobuf_SOURCE_DIR}/src/google/protobuf/stubs/bytestream.h
${protobuf_SOURCE_DIR}/src/google/protobuf/stubs/callback.h ${protobuf_SOURCE_DIR}/src/google/protobuf/stubs/callback.h
${protobuf_SOURCE_DIR}/src/google/protobuf/stubs/common.h ${protobuf_SOURCE_DIR}/src/google/protobuf/stubs/common.h
${protobuf_SOURCE_DIR}/src/google/protobuf/stubs/int128.h
${protobuf_SOURCE_DIR}/src/google/protobuf/stubs/logging.h ${protobuf_SOURCE_DIR}/src/google/protobuf/stubs/logging.h
${protobuf_SOURCE_DIR}/src/google/protobuf/stubs/macros.h
${protobuf_SOURCE_DIR}/src/google/protobuf/stubs/map_util.h
${protobuf_SOURCE_DIR}/src/google/protobuf/stubs/mathutil.h ${protobuf_SOURCE_DIR}/src/google/protobuf/stubs/mathutil.h
${protobuf_SOURCE_DIR}/src/google/protobuf/stubs/platform_macros.h ${protobuf_SOURCE_DIR}/src/google/protobuf/stubs/platform_macros.h
${protobuf_SOURCE_DIR}/src/google/protobuf/stubs/port.h ${protobuf_SOURCE_DIR}/src/google/protobuf/stubs/port.h
@ -211,6 +209,7 @@ set(libprotobuf_hdrs
set(libprotobuf_lite_srcs set(libprotobuf_lite_srcs
${protobuf_SOURCE_DIR}/src/google/protobuf/any_lite.cc ${protobuf_SOURCE_DIR}/src/google/protobuf/any_lite.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/arena.cc ${protobuf_SOURCE_DIR}/src/google/protobuf/arena.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/arena_config.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/arenastring.cc ${protobuf_SOURCE_DIR}/src/google/protobuf/arenastring.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/arenaz_sampler.cc ${protobuf_SOURCE_DIR}/src/google/protobuf/arenaz_sampler.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/extension_set.cc ${protobuf_SOURCE_DIR}/src/google/protobuf/extension_set.cc
@ -231,7 +230,6 @@ set(libprotobuf_lite_srcs
${protobuf_SOURCE_DIR}/src/google/protobuf/repeated_ptr_field.cc ${protobuf_SOURCE_DIR}/src/google/protobuf/repeated_ptr_field.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/stubs/bytestream.cc ${protobuf_SOURCE_DIR}/src/google/protobuf/stubs/bytestream.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/stubs/common.cc ${protobuf_SOURCE_DIR}/src/google/protobuf/stubs/common.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/stubs/int128.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/stubs/stringprintf.cc ${protobuf_SOURCE_DIR}/src/google/protobuf/stubs/stringprintf.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/stubs/structurally_valid.cc ${protobuf_SOURCE_DIR}/src/google/protobuf/stubs/structurally_valid.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/stubs/strutil.cc ${protobuf_SOURCE_DIR}/src/google/protobuf/stubs/strutil.cc
@ -242,6 +240,7 @@ set(libprotobuf_lite_srcs
set(libprotobuf_lite_hdrs set(libprotobuf_lite_hdrs
${protobuf_SOURCE_DIR}/src/google/protobuf/any.h ${protobuf_SOURCE_DIR}/src/google/protobuf/any.h
${protobuf_SOURCE_DIR}/src/google/protobuf/arena.h ${protobuf_SOURCE_DIR}/src/google/protobuf/arena.h
${protobuf_SOURCE_DIR}/src/google/protobuf/arena_config.h
${protobuf_SOURCE_DIR}/src/google/protobuf/arena_impl.h ${protobuf_SOURCE_DIR}/src/google/protobuf/arena_impl.h
${protobuf_SOURCE_DIR}/src/google/protobuf/arenastring.h ${protobuf_SOURCE_DIR}/src/google/protobuf/arenastring.h
${protobuf_SOURCE_DIR}/src/google/protobuf/arenaz_sampler.h ${protobuf_SOURCE_DIR}/src/google/protobuf/arenaz_sampler.h
@ -274,10 +273,7 @@ set(libprotobuf_lite_hdrs
${protobuf_SOURCE_DIR}/src/google/protobuf/stubs/bytestream.h ${protobuf_SOURCE_DIR}/src/google/protobuf/stubs/bytestream.h
${protobuf_SOURCE_DIR}/src/google/protobuf/stubs/callback.h ${protobuf_SOURCE_DIR}/src/google/protobuf/stubs/callback.h
${protobuf_SOURCE_DIR}/src/google/protobuf/stubs/common.h ${protobuf_SOURCE_DIR}/src/google/protobuf/stubs/common.h
${protobuf_SOURCE_DIR}/src/google/protobuf/stubs/int128.h
${protobuf_SOURCE_DIR}/src/google/protobuf/stubs/logging.h ${protobuf_SOURCE_DIR}/src/google/protobuf/stubs/logging.h
${protobuf_SOURCE_DIR}/src/google/protobuf/stubs/macros.h
${protobuf_SOURCE_DIR}/src/google/protobuf/stubs/map_util.h
${protobuf_SOURCE_DIR}/src/google/protobuf/stubs/mathutil.h ${protobuf_SOURCE_DIR}/src/google/protobuf/stubs/mathutil.h
${protobuf_SOURCE_DIR}/src/google/protobuf/stubs/platform_macros.h ${protobuf_SOURCE_DIR}/src/google/protobuf/stubs/platform_macros.h
${protobuf_SOURCE_DIR}/src/google/protobuf/stubs/port.h ${protobuf_SOURCE_DIR}/src/google/protobuf/stubs/port.h
@ -788,6 +784,7 @@ set(test_plugin_files
set(io_test_files set(io_test_files
${protobuf_SOURCE_DIR}/src/google/protobuf/io/coded_stream_unittest.cc ${protobuf_SOURCE_DIR}/src/google/protobuf/io/coded_stream_unittest.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/io/io_win32_unittest.cc ${protobuf_SOURCE_DIR}/src/google/protobuf/io/io_win32_unittest.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/io/printer_death_test.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/io/printer_unittest.cc ${protobuf_SOURCE_DIR}/src/google/protobuf/io/printer_unittest.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/io/tokenizer_unittest.cc ${protobuf_SOURCE_DIR}/src/google/protobuf/io/tokenizer_unittest.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/io/zero_copy_sink_test.cc ${protobuf_SOURCE_DIR}/src/google/protobuf/io/zero_copy_sink_test.cc
@ -845,7 +842,6 @@ set(util_test_protos_files
set(stubs_test_files set(stubs_test_files
${protobuf_SOURCE_DIR}/src/google/protobuf/stubs/bytestream_unittest.cc ${protobuf_SOURCE_DIR}/src/google/protobuf/stubs/bytestream_unittest.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/stubs/common_unittest.cc ${protobuf_SOURCE_DIR}/src/google/protobuf/stubs/common_unittest.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/stubs/int128_unittest.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/stubs/stringprintf_unittest.cc ${protobuf_SOURCE_DIR}/src/google/protobuf/stubs/stringprintf_unittest.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/stubs/structurally_valid_unittest.cc ${protobuf_SOURCE_DIR}/src/google/protobuf/stubs/structurally_valid_unittest.cc
${protobuf_SOURCE_DIR}/src/google/protobuf/stubs/strutil_unittest.cc ${protobuf_SOURCE_DIR}/src/google/protobuf/stubs/strutil_unittest.cc

@ -115,9 +115,11 @@ cc_library(
name = "arena", name = "arena",
srcs = [ srcs = [
"arena.cc", "arena.cc",
"arena_config.cc",
], ],
hdrs = [ hdrs = [
"arena.h", "arena.h",
"arena_config.h",
"arena_impl.h", "arena_impl.h",
"arenaz_sampler.h", "arenaz_sampler.h",
], ],
@ -136,6 +138,7 @@ cc_library(
name = "protobuf_lite", name = "protobuf_lite",
srcs = [ srcs = [
"any_lite.cc", "any_lite.cc",
"arena_config.cc",
"arenastring.cc", "arenastring.cc",
"arenaz_sampler.cc", "arenaz_sampler.cc",
"extension_set.cc", "extension_set.cc",
@ -154,6 +157,7 @@ cc_library(
hdrs = [ hdrs = [
"any.h", "any.h",
"arena.h", "arena.h",
"arena_config.h",
"arena_impl.h", "arena_impl.h",
"arenastring.h", "arenastring.h",
"arenaz_sampler.h", "arenaz_sampler.h",
@ -199,6 +203,8 @@ cc_library(
"//src/google/protobuf/io", "//src/google/protobuf/io",
"//src/google/protobuf/stubs:lite", "//src/google/protobuf/stubs:lite",
"@com_google_absl//absl/container:flat_hash_set", "@com_google_absl//absl/container:flat_hash_set",
"@com_google_absl//absl/numeric:bits",
"@com_google_absl//absl/strings:internal",
"@com_google_absl//absl/synchronization", "@com_google_absl//absl/synchronization",
"@com_google_absl//absl/time", "@com_google_absl//absl/time",
], ],
@ -288,6 +294,7 @@ cc_library(
"@com_google_absl//absl/container:flat_hash_map", "@com_google_absl//absl/container:flat_hash_map",
"@com_google_absl//absl/container:flat_hash_set", "@com_google_absl//absl/container:flat_hash_set",
"@com_google_absl//absl/hash", "@com_google_absl//absl/hash",
"@com_google_absl//absl/strings:internal",
"@com_google_absl//absl/synchronization", "@com_google_absl//absl/synchronization",
"@com_google_absl//absl/time", "@com_google_absl//absl/time",
], ],

@ -28,15 +28,15 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <google/protobuf/any.h> #include "google/protobuf/any.h"
#include <google/protobuf/arenastring.h> #include "google/protobuf/arenastring.h"
#include <google/protobuf/descriptor.h> #include "google/protobuf/descriptor.h"
#include <google/protobuf/generated_message_util.h> #include "google/protobuf/generated_message_util.h"
#include <google/protobuf/message.h> #include "google/protobuf/message.h"
// Must be included last. // Must be included last.
#include <google/protobuf/port_def.inc> #include "google/protobuf/port_def.inc"
namespace google { namespace google {
namespace protobuf { namespace protobuf {
@ -79,4 +79,4 @@ bool GetAnyFieldDescriptors(const Message& message,
} // namespace protobuf } // namespace protobuf
} // namespace google } // namespace google
#include <google/protobuf/port_undef.inc> #include "google/protobuf/port_undef.inc"

@ -33,12 +33,12 @@
#include <string> #include <string>
#include <google/protobuf/stubs/common.h> #include "google/protobuf/port.h"
#include <google/protobuf/arenastring.h> #include "google/protobuf/arenastring.h"
#include <google/protobuf/message_lite.h> #include "google/protobuf/message_lite.h"
// Must be included last. // Must be included last.
#include <google/protobuf/port_def.inc> #include "google/protobuf/port_def.inc"
namespace google { namespace google {
namespace protobuf { namespace protobuf {
@ -152,6 +152,6 @@ bool GetAnyFieldDescriptors(const Message& message,
} // namespace protobuf } // namespace protobuf
} // namespace google } // namespace google
#include <google/protobuf/port_undef.inc> #include "google/protobuf/port_undef.inc"
#endif // GOOGLE_PROTOBUF_ANY_H__ #endif // GOOGLE_PROTOBUF_ANY_H__

@ -5,15 +5,15 @@
#include <algorithm> #include <algorithm>
#include <google/protobuf/io/coded_stream.h> #include "google/protobuf/io/coded_stream.h"
#include <google/protobuf/extension_set.h> #include "google/protobuf/extension_set.h"
#include <google/protobuf/wire_format_lite.h> #include "google/protobuf/wire_format_lite.h"
#include <google/protobuf/descriptor.h> #include "google/protobuf/descriptor.h"
#include <google/protobuf/generated_message_reflection.h> #include "google/protobuf/generated_message_reflection.h"
#include <google/protobuf/reflection_ops.h> #include "google/protobuf/reflection_ops.h"
#include <google/protobuf/wire_format.h> #include "google/protobuf/wire_format.h"
// @@protoc_insertion_point(includes) // @@protoc_insertion_point(includes)
#include <google/protobuf/port_def.inc> #include "google/protobuf/port_def.inc"
PROTOBUF_PRAGMA_INIT_SEG PROTOBUF_PRAGMA_INIT_SEG
@ -367,4 +367,4 @@ PROTOBUF_NAMESPACE_CLOSE
#if defined(__llvm__) #if defined(__llvm__)
#pragma clang diagnostic pop #pragma clang diagnostic pop
#endif // __llvm__ #endif // __llvm__
#include <google/protobuf/port_undef.inc> #include "google/protobuf/port_undef.inc"

@ -1,13 +1,13 @@
// Generated by the protocol buffer compiler. DO NOT EDIT! // Generated by the protocol buffer compiler. DO NOT EDIT!
// source: google/protobuf/any.proto // source: google/protobuf/any.proto
#ifndef GOOGLE_PROTOBUF_INCLUDED_google_2fprotobuf_2fany_2eproto #ifndef GOOGLE_PROTOBUF_INCLUDED_google_2fprotobuf_2fany_2eproto_2epb_2eh
#define GOOGLE_PROTOBUF_INCLUDED_google_2fprotobuf_2fany_2eproto #define GOOGLE_PROTOBUF_INCLUDED_google_2fprotobuf_2fany_2eproto_2epb_2eh
#include <limits> #include <limits>
#include <string> #include <string>
#include <google/protobuf/port_def.inc> #include "google/protobuf/port_def.inc"
#if PROTOBUF_VERSION < 3021000 #if PROTOBUF_VERSION < 3021000
#error This file was generated by a newer version of protoc which is #error This file was generated by a newer version of protoc which is
#error incompatible with your Protocol Buffer headers. Please update #error incompatible with your Protocol Buffer headers. Please update
@ -19,19 +19,19 @@
#error regenerate this file with a newer version of protoc. #error regenerate this file with a newer version of protoc.
#endif #endif
#include <google/protobuf/port_undef.inc> #include "google/protobuf/port_undef.inc"
#include <google/protobuf/io/coded_stream.h> #include "google/protobuf/io/coded_stream.h"
#include <google/protobuf/arena.h> #include "google/protobuf/arena.h"
#include <google/protobuf/arenastring.h> #include "google/protobuf/arenastring.h"
#include <google/protobuf/generated_message_util.h> #include "google/protobuf/generated_message_util.h"
#include <google/protobuf/metadata_lite.h> #include "google/protobuf/metadata_lite.h"
#include <google/protobuf/generated_message_reflection.h> #include "google/protobuf/generated_message_reflection.h"
#include <google/protobuf/message.h> #include "google/protobuf/message.h"
#include <google/protobuf/repeated_field.h> // IWYU pragma: export #include "google/protobuf/repeated_field.h" // IWYU pragma: export
#include <google/protobuf/extension_set.h> // IWYU pragma: export #include "google/protobuf/extension_set.h" // IWYU pragma: export
#include <google/protobuf/unknown_field_set.h> #include "google/protobuf/unknown_field_set.h"
// @@protoc_insertion_point(includes) // @@protoc_insertion_point(includes)
#include <google/protobuf/port_def.inc> #include "google/protobuf/port_def.inc"
#define PROTOBUF_INTERNAL_EXPORT_google_2fprotobuf_2fany_2eproto PROTOBUF_EXPORT #define PROTOBUF_INTERNAL_EXPORT_google_2fprotobuf_2fany_2eproto PROTOBUF_EXPORT
PROTOBUF_NAMESPACE_OPEN PROTOBUF_NAMESPACE_OPEN
namespace internal { namespace internal {
@ -380,5 +380,5 @@ PROTOBUF_NAMESPACE_CLOSE
// @@protoc_insertion_point(global_scope) // @@protoc_insertion_point(global_scope)
#include <google/protobuf/port_undef.inc> #include "google/protobuf/port_undef.inc"
#endif // GOOGLE_PROTOBUF_INCLUDED_GOOGLE_PROTOBUF_INCLUDED_google_2fprotobuf_2fany_2eproto #endif // GOOGLE_PROTOBUF_INCLUDED_GOOGLE_PROTOBUF_INCLUDED_google_2fprotobuf_2fany_2eproto_2epb_2eh

@ -28,12 +28,12 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <google/protobuf/io/zero_copy_stream_impl_lite.h> #include "google/protobuf/io/zero_copy_stream_impl_lite.h"
#include <google/protobuf/stubs/strutil.h> #include "google/protobuf/stubs/strutil.h"
#include "absl/strings/str_cat.h" #include "absl/strings/str_cat.h"
#include <google/protobuf/any.h> #include "google/protobuf/any.h"
#include <google/protobuf/arenastring.h> #include "google/protobuf/arenastring.h"
#include <google/protobuf/generated_message_util.h> #include "google/protobuf/generated_message_util.h"
namespace google { namespace google {
namespace protobuf { namespace protobuf {

@ -28,14 +28,14 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <google/protobuf/any_test.pb.h> #include "google/protobuf/any_test.pb.h"
#include <google/protobuf/unittest.pb.h> #include "google/protobuf/unittest.pb.h"
#include <gtest/gtest.h> #include <gtest/gtest.h>
#include "absl/strings/str_cat.h" #include "absl/strings/str_cat.h"
// Must be included last. // Must be included last.
#include <google/protobuf/port_def.inc> #include "google/protobuf/port_def.inc"
namespace google { namespace google {
namespace protobuf { namespace protobuf {
@ -192,4 +192,4 @@ TEST(AnyTest, PackSelfDeath) {
} // namespace protobuf } // namespace protobuf
} // namespace google } // namespace google
#include <google/protobuf/port_undef.inc> #include "google/protobuf/port_undef.inc"

@ -5,15 +5,15 @@
#include <algorithm> #include <algorithm>
#include <google/protobuf/io/coded_stream.h> #include "google/protobuf/io/coded_stream.h"
#include <google/protobuf/extension_set.h> #include "google/protobuf/extension_set.h"
#include <google/protobuf/wire_format_lite.h> #include "google/protobuf/wire_format_lite.h"
#include <google/protobuf/descriptor.h> #include "google/protobuf/descriptor.h"
#include <google/protobuf/generated_message_reflection.h> #include "google/protobuf/generated_message_reflection.h"
#include <google/protobuf/reflection_ops.h> #include "google/protobuf/reflection_ops.h"
#include <google/protobuf/wire_format.h> #include "google/protobuf/wire_format.h"
// @@protoc_insertion_point(includes) // @@protoc_insertion_point(includes)
#include <google/protobuf/port_def.inc> #include "google/protobuf/port_def.inc"
PROTOBUF_PRAGMA_INIT_SEG PROTOBUF_PRAGMA_INIT_SEG
@ -1312,4 +1312,4 @@ Arena::CreateMaybeMessage< ::PROTOBUF_NAMESPACE_ID::Mixin >(Arena* arena) {
PROTOBUF_NAMESPACE_CLOSE PROTOBUF_NAMESPACE_CLOSE
// @@protoc_insertion_point(global_scope) // @@protoc_insertion_point(global_scope)
#include <google/protobuf/port_undef.inc> #include "google/protobuf/port_undef.inc"

@ -1,13 +1,13 @@
// Generated by the protocol buffer compiler. DO NOT EDIT! // Generated by the protocol buffer compiler. DO NOT EDIT!
// source: google/protobuf/api.proto // source: google/protobuf/api.proto
#ifndef GOOGLE_PROTOBUF_INCLUDED_google_2fprotobuf_2fapi_2eproto #ifndef GOOGLE_PROTOBUF_INCLUDED_google_2fprotobuf_2fapi_2eproto_2epb_2eh
#define GOOGLE_PROTOBUF_INCLUDED_google_2fprotobuf_2fapi_2eproto #define GOOGLE_PROTOBUF_INCLUDED_google_2fprotobuf_2fapi_2eproto_2epb_2eh
#include <limits> #include <limits>
#include <string> #include <string>
#include <google/protobuf/port_def.inc> #include "google/protobuf/port_def.inc"
#if PROTOBUF_VERSION < 3021000 #if PROTOBUF_VERSION < 3021000
#error This file was generated by a newer version of protoc which is #error This file was generated by a newer version of protoc which is
#error incompatible with your Protocol Buffer headers. Please update #error incompatible with your Protocol Buffer headers. Please update
@ -19,21 +19,21 @@
#error regenerate this file with a newer version of protoc. #error regenerate this file with a newer version of protoc.
#endif #endif
#include <google/protobuf/port_undef.inc> #include "google/protobuf/port_undef.inc"
#include <google/protobuf/io/coded_stream.h> #include "google/protobuf/io/coded_stream.h"
#include <google/protobuf/arena.h> #include "google/protobuf/arena.h"
#include <google/protobuf/arenastring.h> #include "google/protobuf/arenastring.h"
#include <google/protobuf/generated_message_util.h> #include "google/protobuf/generated_message_util.h"
#include <google/protobuf/metadata_lite.h> #include "google/protobuf/metadata_lite.h"
#include <google/protobuf/generated_message_reflection.h> #include "google/protobuf/generated_message_reflection.h"
#include <google/protobuf/message.h> #include "google/protobuf/message.h"
#include <google/protobuf/repeated_field.h> // IWYU pragma: export #include "google/protobuf/repeated_field.h" // IWYU pragma: export
#include <google/protobuf/extension_set.h> // IWYU pragma: export #include "google/protobuf/extension_set.h" // IWYU pragma: export
#include <google/protobuf/unknown_field_set.h> #include "google/protobuf/unknown_field_set.h"
#include <google/protobuf/source_context.pb.h> #include <google/protobuf/source_context.pb.h>
#include <google/protobuf/type.pb.h> #include <google/protobuf/type.pb.h>
// @@protoc_insertion_point(includes) // @@protoc_insertion_point(includes)
#include <google/protobuf/port_def.inc> #include "google/protobuf/port_def.inc"
#define PROTOBUF_INTERNAL_EXPORT_google_2fprotobuf_2fapi_2eproto PROTOBUF_EXPORT #define PROTOBUF_INTERNAL_EXPORT_google_2fprotobuf_2fapi_2eproto PROTOBUF_EXPORT
PROTOBUF_NAMESPACE_OPEN PROTOBUF_NAMESPACE_OPEN
namespace internal { namespace internal {
@ -1433,5 +1433,5 @@ PROTOBUF_NAMESPACE_CLOSE
// @@protoc_insertion_point(global_scope) // @@protoc_insertion_point(global_scope)
#include <google/protobuf/port_undef.inc> #include "google/protobuf/port_undef.inc"
#endif // GOOGLE_PROTOBUF_INCLUDED_GOOGLE_PROTOBUF_INCLUDED_google_2fprotobuf_2fapi_2eproto #endif // GOOGLE_PROTOBUF_INCLUDED_GOOGLE_PROTOBUF_INCLUDED_google_2fprotobuf_2fapi_2eproto_2epb_2eh

@ -28,7 +28,7 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <google/protobuf/arena.h> #include "google/protobuf/arena.h"
#include <algorithm> #include <algorithm>
#include <atomic> #include <atomic>
@ -38,9 +38,9 @@
#include <typeinfo> #include <typeinfo>
#include "absl/synchronization/mutex.h" #include "absl/synchronization/mutex.h"
#include <google/protobuf/arena_impl.h> #include "google/protobuf/arena_impl.h"
#include <google/protobuf/arenaz_sampler.h> #include "google/protobuf/arenaz_sampler.h"
#include <google/protobuf/port.h> #include "google/protobuf/port.h"
#ifdef ADDRESS_SANITIZER #ifdef ADDRESS_SANITIZER
@ -48,7 +48,7 @@
#endif // ADDRESS_SANITIZER #endif // ADDRESS_SANITIZER
// Must be included last. // Must be included last.
#include <google/protobuf/port_def.inc> #include "google/protobuf/port_def.inc"
namespace google { namespace google {
namespace protobuf { namespace protobuf {
@ -105,20 +105,20 @@ class GetDeallocator {
size_t* space_allocated_; size_t* space_allocated_;
}; };
SerialArena::SerialArena(Block* b, void* owner) : space_allocated_(b->size()) { SerialArena::SerialArena(Block* b, ThreadSafeArena& parent)
owner_ = owner; : parent_(parent), space_allocated_(b->size()) {
set_head(b); set_head(b);
set_ptr(b->Pointer(kBlockHeaderSize + ThreadSafeArena::kSerialArenaSize)); set_ptr(b->Pointer(kBlockHeaderSize + ThreadSafeArena::kSerialArenaSize));
limit_ = b->Pointer(b->size() & static_cast<size_t>(-8)); limit_ = b->Pointer(b->size() & static_cast<size_t>(-8));
} }
SerialArena* SerialArena::New(Memory mem, void* owner, SerialArena* SerialArena::New(Memory mem, ThreadSafeArena& parent) {
ThreadSafeArenaStats* stats) {
GOOGLE_DCHECK_LE(kBlockHeaderSize + ThreadSafeArena::kSerialArenaSize, mem.size); GOOGLE_DCHECK_LE(kBlockHeaderSize + ThreadSafeArena::kSerialArenaSize, mem.size);
ThreadSafeArenaStats::RecordAllocateStats( ThreadSafeArenaStats::RecordAllocateStats(parent.arena_stats_.MutableStats(),
stats, /*used=*/0, /*allocated=*/mem.size, /*wasted=*/0); /*used=*/0, /*allocated=*/mem.size,
/*wasted=*/0);
auto b = new (mem.ptr) Block{nullptr, mem.size}; auto b = new (mem.ptr) Block{nullptr, mem.size};
return new (b->Pointer(kBlockHeaderSize)) SerialArena(b, owner); return new (b->Pointer(kBlockHeaderSize)) SerialArena(b, parent);
} }
template <typename Deallocator> template <typename Deallocator>
@ -134,33 +134,27 @@ SerialArena::Memory SerialArena::Free(Deallocator deallocator) {
} }
PROTOBUF_NOINLINE PROTOBUF_NOINLINE
void* SerialArena::AllocateAlignedFallback(size_t n, void* SerialArena::AllocateAlignedFallback(size_t n) {
const AllocationPolicy* policy, AllocateNewBlock(n);
ThreadSafeArenaStats* stats) {
AllocateNewBlock(n, policy, stats);
return AllocateFromExisting(n); return AllocateFromExisting(n);
} }
PROTOBUF_NOINLINE PROTOBUF_NOINLINE
void* SerialArena::AllocateAlignedWithCleanupFallback( void* SerialArena::AllocateAlignedWithCleanupFallback(
size_t n, size_t align, void (*destructor)(void*), size_t n, size_t align, void (*destructor)(void*)) {
const AllocationPolicy* policy, ThreadSafeArenaStats* stats) {
size_t required = AlignUpTo(n, align) + cleanup::Size(destructor); size_t required = AlignUpTo(n, align) + cleanup::Size(destructor);
AllocateNewBlock(required, policy, stats); AllocateNewBlock(required);
return AllocateFromExistingWithCleanupFallback(n, align, destructor); return AllocateFromExistingWithCleanupFallback(n, align, destructor);
} }
PROTOBUF_NOINLINE PROTOBUF_NOINLINE
void SerialArena::AddCleanupFallback(void* elem, void (*destructor)(void*), void SerialArena::AddCleanupFallback(void* elem, void (*destructor)(void*)) {
const AllocationPolicy* policy,
ThreadSafeArenaStats* stats) {
size_t required = cleanup::Size(destructor); size_t required = cleanup::Size(destructor);
AllocateNewBlock(required, policy, stats); AllocateNewBlock(required);
AddCleanupFromExisting(elem, destructor); AddCleanupFromExisting(elem, destructor);
} }
void SerialArena::AllocateNewBlock(size_t n, const AllocationPolicy* policy, void SerialArena::AllocateNewBlock(size_t n) {
ThreadSafeArenaStats* stats) {
// Sync limit to block // Sync limit to block
head()->cleanup_nodes = limit_; head()->cleanup_nodes = limit_;
@ -175,14 +169,15 @@ void SerialArena::AllocateNewBlock(size_t n, const AllocationPolicy* policy,
// but with a CPU regression. The regression might have been an artifact of // but with a CPU regression. The regression might have been an artifact of
// the microbenchmark. // the microbenchmark.
auto mem = AllocateMemory(policy, head()->size(), n); auto mem = AllocateMemory(parent_.AllocPolicy(), head()->size(), n);
// We don't want to emit an expensive RMW instruction that requires // We don't want to emit an expensive RMW instruction that requires
// exclusive access to a cacheline. Hence we write it in terms of a // exclusive access to a cacheline. Hence we write it in terms of a
// regular add. // regular add.
space_allocated_.store( space_allocated_.store(
space_allocated_.load(std::memory_order_relaxed) + mem.size, space_allocated_.load(std::memory_order_relaxed) + mem.size,
std::memory_order_relaxed); std::memory_order_relaxed);
ThreadSafeArenaStats::RecordAllocateStats(stats, /*used=*/used, ThreadSafeArenaStats::RecordAllocateStats(parent_.arena_stats_.MutableStats(),
/*used=*/used,
/*allocated=*/mem.size, wasted); /*allocated=*/mem.size, wasted);
set_head(new (mem.ptr) Block{head(), mem.size}); set_head(new (mem.ptr) Block{head(), mem.size});
set_ptr(head()->Pointer(kBlockHeaderSize)); set_ptr(head()->Pointer(kBlockHeaderSize));
@ -257,6 +252,160 @@ void SerialArena::CleanupList() {
} while (b); } while (b);
} }
// Stores arrays of void* and SerialArena* instead of linked list of
// SerialArena* to speed up traversing all SerialArena. The cost of walk is non
// trivial when there are many nodes. Separately storing "ids" minimizes cache
// footprints and more efficient when looking for matching arena.
//
// Uses absl::container_internal::Layout to emulate the following:
//
// struct SerialArenaChunk {
// SerialArenaChunk* next_chunk;
// const uint32_t capacity;
// std::atomic<uint32_t> size;
// std::atomic<void*> ids[];
// std::atomic<SerialArena*> arenas[];
// };
//
// where the size of "ids" and "arenas" is determined at runtime; hence the use
// of Layout.
class ThreadSafeArena::SerialArenaChunk {
public:
explicit SerialArenaChunk(uint32_t capacity) {
set_next(nullptr);
set_capacity(capacity);
new (&size()) std::atomic<uint32_t>{0};
for (unsigned i = 0; i < capacity; ++i) {
new (&id(i)) std::atomic<void*>{nullptr};
}
for (unsigned i = 0; i < capacity; ++i) {
new (&arena(i)) std::atomic<void*>{nullptr};
}
}
SerialArenaChunk(uint32_t capacity, void* me, SerialArena* serial) {
set_next(nullptr);
set_capacity(capacity);
new (&size()) std::atomic<uint32_t>{1};
new (&id(0)) std::atomic<void*>{me};
for (unsigned i = 1; i < capacity; ++i) {
new (&id(i)) std::atomic<void*>{nullptr};
}
new (&arena(0)) std::atomic<SerialArena*>{serial};
for (unsigned i = 1; i < capacity; ++i) {
new (&arena(i)) std::atomic<void*>{nullptr};
}
}
// next_chunk
const SerialArenaChunk* next_chunk() const {
return *layout_type::Partial().Pointer<kNextChunk>(ptr());
}
SerialArenaChunk* next_chunk() {
return *layout_type::Partial().Pointer<kNextChunk>(ptr());
}
void set_next(SerialArenaChunk* next_chunk) {
*layout_type::Partial().Pointer<kNextChunk>(ptr()) = next_chunk;
}
// capacity
uint32_t capacity() const {
return *layout_type::Partial(1u).Pointer<kCapacity>(ptr());
}
void set_capacity(uint32_t capacity) {
*layout_type::Partial(1u).Pointer<kCapacity>(ptr()) = capacity;
}
// ids: returns up to size().
absl::Span<const std::atomic<void*>> ids() const {
return Layout(capacity()).Slice<kIds>(ptr()).first(safe_size());
}
absl::Span<std::atomic<void*>> ids() {
return Layout(capacity()).Slice<kIds>(ptr()).first(safe_size());
}
std::atomic<void*>& id(unsigned i) {
GOOGLE_DCHECK_LT(i, capacity());
return Layout(capacity()).Pointer<kIds>(ptr())[i];
}
// arenas: returns up to size().
absl::Span<const std::atomic<SerialArena*>> arenas() const {
return Layout(capacity()).Slice<kArenas>(ptr()).first(safe_size());
}
absl::Span<std::atomic<SerialArena*>> arenas() {
return Layout(capacity()).Slice<kArenas>(ptr()).first(safe_size());
}
std::atomic<SerialArena*>& arena(unsigned i) {
GOOGLE_DCHECK_LT(i, capacity());
return Layout(capacity()).Pointer<kArenas>(ptr())[i];
}
// Tries to insert {id, serial} to head chunk. Returns false if the head is
// already full.
//
// Note that the updating "size", "id", "arena" is individually atomic but
// those are not protected by a mutex. This is acceptable because concurrent
// lookups from SpaceUsed or SpaceAllocated accept inaccuracy due to race. On
// other paths, either race is not possible (GetSerialArenaFallback) or must
// be prevented by users (CleanupList, Free).
bool insert(void* me, SerialArena* serial) {
uint32_t idx = size().fetch_add(1, std::memory_order_relaxed);
// Bail out if this chunk is full.
if (idx >= capacity()) {
// Write old value back to avoid potential overflow.
size().store(capacity(), std::memory_order_relaxed);
return false;
}
id(idx).store(me, std::memory_order_relaxed);
arena(idx).store(serial, std::memory_order_relaxed);
return true;
}
constexpr static size_t AllocSize(size_t n) { return Layout(n).AllocSize(); }
private:
constexpr static int kNextChunk = 0;
constexpr static int kCapacity = 1;
constexpr static int kSize = 2;
constexpr static int kIds = 3;
constexpr static int kArenas = 4;
using layout_type = absl::container_internal::Layout<
SerialArenaChunk*, uint32_t, std::atomic<uint32_t>, std::atomic<void*>,
std::atomic<SerialArena*>>;
const char* ptr() const { return reinterpret_cast<const char*>(this); }
char* ptr() { return reinterpret_cast<char*>(this); }
std::atomic<uint32_t>& size() {
return *layout_type::Partial(1u, 1u).Pointer<kSize>(ptr());
}
const std::atomic<uint32_t>& size() const {
return *layout_type::Partial(1u, 1u).Pointer<kSize>(ptr());
}
// Returns the size capped by the capacity as fetch_add may result in a size
// greater than capacity.
uint32_t safe_size() const {
return std::min(capacity(), size().load(std::memory_order_relaxed));
}
constexpr static layout_type Layout(size_t n) {
return layout_type(
/*next_chunk*/ 1,
/*capacity*/ 1,
/*size*/ 1,
/*ids*/ n,
/*arenas*/ n);
}
};
ThreadSafeArena::CacheAlignedLifecycleIdGenerator ThreadSafeArena::CacheAlignedLifecycleIdGenerator
ThreadSafeArena::lifecycle_id_generator_; ThreadSafeArena::lifecycle_id_generator_;
@ -326,9 +475,8 @@ void ThreadSafeArena::InitializeWithPolicy(void* mem, size_t size,
mem = tmp.ptr; mem = tmp.ptr;
size = tmp.size; size = tmp.size;
} }
SetInitialBlock(mem, size); SerialArena* sa = SetInitialBlock(mem, size);
auto sa = threads_.load(std::memory_order_relaxed);
// We ensured enough space so this cannot fail. // We ensured enough space so this cannot fail.
void* p; void* p;
if (!sa || !sa->MaybeAllocateAligned(kAPSize, &p)) { if (!sa || !sa->MaybeAllocateAligned(kAPSize, &p)) {
@ -362,6 +510,64 @@ uint64_t ThreadSafeArena::GetNextLifeCycleId() {
return id; return id;
} }
// We assume that #threads / arena is bimodal; i.e. majority small ones are
// single threaded but some big ones are highly concurrent. To balance between
// memory overhead and minimum pointer chasing, we start with few entries and
// exponentially (4x) grow with a limit (255 entries). Note that parameters are
// picked for x64 architectures as hint and the actual size is calculated by
// Layout.
ThreadSafeArena::SerialArenaChunk* ThreadSafeArena::NewSerialArenaChunk(
uint32_t prev_capacity, void* id, SerialArena* serial) {
constexpr size_t kMaxBytes = 4096; // Can hold up to 255 entries.
constexpr size_t kGrowthFactor = 4;
constexpr size_t kHeaderSize = SerialArenaChunk::AllocSize(0);
constexpr size_t kEntrySize = SerialArenaChunk::AllocSize(1) - kHeaderSize;
// On x64 arch: {4, 16, 64, 256, 256, ...} * 16.
size_t prev_bytes = SerialArenaChunk::AllocSize(prev_capacity);
size_t next_bytes = std::min(kMaxBytes, prev_bytes * kGrowthFactor);
uint32_t next_capacity =
static_cast<uint32_t>(next_bytes - kHeaderSize) / kEntrySize;
// Growth based on bytes needs to be adjusted by AllocSize.
next_bytes = SerialArenaChunk::AllocSize(next_capacity);
void* mem;
mem = ::operator new(next_bytes);
if (serial == nullptr) {
return new (mem) SerialArenaChunk{next_capacity};
}
return new (mem) SerialArenaChunk{next_capacity, id, serial};
}
// Tries to reserve an entry by atomic fetch_add. If the head chunk is already
// full (size >= capacity), acquires the mutex and adds a new head.
void ThreadSafeArena::AddSerialArena(void* id, SerialArena* serial) {
SerialArenaChunk* head = head_.load(std::memory_order_acquire);
GOOGLE_DCHECK_NE(head, nullptr);
// Fast path without acquiring mutex.
if (head->insert(id, serial)) {
return;
}
// Slow path with acquiring mutex.
absl::MutexLock lock(&mutex_);
// Refetch and if someone else installed a new head, try allocating on that!
SerialArenaChunk* new_head = head_.load(std::memory_order_acquire);
if (new_head != head) {
if (new_head->insert(id, serial)) return;
// Update head to link to the latest one.
head = new_head;
}
new_head = NewSerialArenaChunk(head->capacity(), id, serial);
new_head->set_next(head);
// Use "std::memory_order_release" to make sure prior stores are visible after
// this one.
head_.store(new_head, std::memory_order_release);
}
void ThreadSafeArena::Init() { void ThreadSafeArena::Init() {
const bool message_owned = IsMessageOwned(); const bool message_owned = IsMessageOwned();
if (!message_owned) { if (!message_owned) {
@ -370,17 +576,17 @@ void ThreadSafeArena::Init() {
} else { } else {
GOOGLE_DCHECK_EQ(tag_and_id_, kMessageOwnedArena); GOOGLE_DCHECK_EQ(tag_and_id_, kMessageOwnedArena);
} }
threads_.store(nullptr, std::memory_order_relaxed); auto* empty_chunk = NewSerialArenaChunk(0, nullptr, nullptr);
head_.store(empty_chunk, std::memory_order_relaxed);
GOOGLE_DCHECK_EQ(message_owned, IsMessageOwned()); GOOGLE_DCHECK_EQ(message_owned, IsMessageOwned());
arena_stats_ = Sample(); arena_stats_ = Sample();
} }
void ThreadSafeArena::SetInitialBlock(void* mem, size_t size) { SerialArena* ThreadSafeArena::SetInitialBlock(void* mem, size_t size) {
SerialArena* serial = SerialArena::New({mem, size}, &thread_cache(), SerialArena* serial = SerialArena::New({mem, size}, *this);
arena_stats_.MutableStats()); AddSerialArena(&thread_cache(), serial);
serial->set_next(nullptr);
threads_.store(serial, std::memory_order_relaxed);
CacheSerialArena(serial); CacheSerialArena(serial);
return serial;
} }
ThreadSafeArena::~ThreadSafeArena() { ThreadSafeArena::~ThreadSafeArena() {
@ -408,6 +614,14 @@ SerialArena::Memory ThreadSafeArena::Free(size_t* space_allocated) {
if (mem.ptr) deallocator(mem); if (mem.ptr) deallocator(mem);
mem = a->Free(deallocator); mem = a->Free(deallocator);
}); });
// Free chunks that stored SerialArena.
SerialArenaChunk* chunk = head_.load(std::memory_order_relaxed);
while (chunk != nullptr) {
SerialArenaChunk* next_chunk = chunk->next_chunk();
internal::SizedDelete(chunk,
SerialArenaChunk::AllocSize(chunk->capacity()));
chunk = next_chunk;
}
return mem; return mem;
} }
@ -449,8 +663,7 @@ void* ThreadSafeArena::AllocateAlignedWithCleanup(size_t n, size_t align,
void (*destructor)(void*)) { void (*destructor)(void*)) {
SerialArena* arena; SerialArena* arena;
if (PROTOBUF_PREDICT_TRUE(GetSerialArenaFast(&arena))) { if (PROTOBUF_PREDICT_TRUE(GetSerialArenaFast(&arena))) {
return arena->AllocateAlignedWithCleanup( return arena->AllocateAlignedWithCleanup(n, align, destructor);
n, align, destructor, alloc_policy_.get(), arena_stats_.MutableStats());
} else { } else {
return AllocateAlignedWithCleanupFallback(n, align, destructor); return AllocateAlignedWithCleanupFallback(n, align, destructor);
} }
@ -459,7 +672,7 @@ void* ThreadSafeArena::AllocateAlignedWithCleanup(size_t n, size_t align,
void ThreadSafeArena::AddCleanup(void* elem, void (*cleanup)(void*)) { void ThreadSafeArena::AddCleanup(void* elem, void (*cleanup)(void*)) {
SerialArena* arena; SerialArena* arena;
if (PROTOBUF_PREDICT_FALSE(!GetSerialArenaFast(&arena))) { if (PROTOBUF_PREDICT_FALSE(!GetSerialArenaFast(&arena))) {
arena = GetSerialArenaFallback(&thread_cache()); arena = GetSerialArenaFallback();
} }
arena->AddCleanup(elem, cleanup, AllocPolicy(), arena_stats_.MutableStats()); arena->AddCleanup(elem, cleanup, AllocPolicy(), arena_stats_.MutableStats());
} }
@ -467,26 +680,71 @@ void ThreadSafeArena::AddCleanup(void* elem, void (*cleanup)(void*)) {
PROTOBUF_NOINLINE PROTOBUF_NOINLINE
void* ThreadSafeArena::AllocateAlignedWithCleanupFallback( void* ThreadSafeArena::AllocateAlignedWithCleanupFallback(
size_t n, size_t align, void (*destructor)(void*)) { size_t n, size_t align, void (*destructor)(void*)) {
return GetSerialArenaFallback(&thread_cache()) return GetSerialArenaFallback()->AllocateAlignedWithCleanup(n, align,
->AllocateAlignedWithCleanup(n, align, destructor, alloc_policy_.get(), destructor);
arena_stats_.MutableStats());
} }
uint64_t ThreadSafeArena::SpaceAllocated() const { template <typename Functor>
SerialArena* serial = threads_.load(std::memory_order_acquire); void ThreadSafeArena::PerConstSerialArena(Functor fn) const {
uint64_t res = 0; const SerialArenaChunk* chunk = head_.load(std::memory_order_acquire);
for (; serial; serial = serial->next()) {
res += serial->SpaceAllocated(); for (; chunk; chunk = chunk->next_chunk()) {
absl::Span<const std::atomic<SerialArena*>> span = chunk->arenas();
// Walks arenas backward to handle the first serial arena the last. This is
// necessary to special-case the initial block.
for (auto it = span.crbegin(); it != span.crend(); ++it) {
const SerialArena* serial = it->load(std::memory_order_relaxed);
// It is possible that newly added SerialArena is not updated although
// size was. This is acceptable for SpaceAllocated and SpaceUsed.
if (serial == nullptr) continue;
fn(serial);
}
} }
return res;
} }
template <typename Functor>
void ThreadSafeArena::PerSerialArena(Functor fn) {
// By omitting an Acquire barrier we help the sanitizer that any user code
// that doesn't properly synchronize Reset() or the destructor will throw a
// TSAN warning.
SerialArenaChunk* chunk = head_.load(std::memory_order_relaxed);
for (; chunk; chunk = chunk->next_chunk()) {
absl::Span<std::atomic<SerialArena*>> span = chunk->arenas();
// Walks arenas backward to handle the first serial arena the last. This is
// necessary to special-case the initial block.
for (auto it = span.rbegin(); it != span.rend(); ++it) {
SerialArena* serial = it->load(std::memory_order_relaxed);
GOOGLE_DCHECK_NE(serial, nullptr);
if (serial == nullptr) continue;
fn(serial);
}
}
}
uint64_t ThreadSafeArena::SpaceAllocated() const {
uint64_t space_allocated = 0;
PerConstSerialArena([&space_allocated](const SerialArena* serial) {
space_allocated += serial->SpaceAllocated();
});
return space_allocated;
}
template <AllocationClient alloc_client>
PROTOBUF_NOINLINE void* ThreadSafeArena::AllocateAlignedFallback(size_t n) {
return GetSerialArenaFallback()->AllocateAligned<alloc_client>(n);
}
template void* ThreadSafeArena::AllocateAlignedFallback<
AllocationClient::kDefault>(size_t);
template void*
ThreadSafeArena::AllocateAlignedFallback<AllocationClient::kArray>(size_t);
uint64_t ThreadSafeArena::SpaceUsed() const { uint64_t ThreadSafeArena::SpaceUsed() const {
SerialArena* serial = threads_.load(std::memory_order_acquire);
uint64_t space_used = 0; uint64_t space_used = 0;
for (; serial; serial = serial->next()) { PerConstSerialArena([&space_used](const SerialArena* serial) {
space_used += serial->SpaceUsed(); space_used += serial->SpaceUsed();
} });
return space_used - (alloc_policy_.get() ? sizeof(AllocationPolicy) : 0); return space_used - (alloc_policy_.get() ? sizeof(AllocationPolicy) : 0);
} }
@ -495,27 +753,30 @@ void ThreadSafeArena::CleanupList() {
} }
PROTOBUF_NOINLINE PROTOBUF_NOINLINE
SerialArena* ThreadSafeArena::GetSerialArenaFallback(void* me) { SerialArena* ThreadSafeArena::GetSerialArenaFallback() {
// Look for this SerialArena in our linked list. void* const id = &thread_cache();
SerialArena* serial = threads_.load(std::memory_order_acquire); SerialArena* serial = nullptr;
for (; serial; serial = serial->next()) {
if (serial->owner() == me) { // Search matching SerialArena.
SerialArenaChunk* chunk = head_.load(std::memory_order_acquire);
for (; chunk; chunk = chunk->next_chunk()) {
absl::Span<std::atomic<void*>> ids = chunk->ids();
for (unsigned i = 0; i < ids.size(); ++i) {
if (ids[i].load(std::memory_order_relaxed) == id) {
serial = chunk->arena(i).load(std::memory_order_relaxed);
GOOGLE_DCHECK_NE(serial, nullptr);
break; break;
} }
} }
}
if (!serial) { if (!serial) {
// This thread doesn't have any SerialArena, which also means it doesn't // This thread doesn't have any SerialArena, which also means it doesn't
// have any blocks yet. So we'll allocate its first block now. // have any blocks yet. So we'll allocate its first block now.
serial = SerialArena::New( serial = SerialArena::New(
AllocateMemory(alloc_policy_.get(), 0, kSerialArenaSize), me, AllocateMemory(alloc_policy_.get(), 0, kSerialArenaSize), *this);
arena_stats_.MutableStats());
SerialArena* head = threads_.load(std::memory_order_relaxed); AddSerialArena(id, serial);
do {
serial->set_next(head);
} while (!threads_.compare_exchange_weak(
head, serial, std::memory_order_release, std::memory_order_relaxed));
} }
CacheSerialArena(serial); CacheSerialArena(serial);
@ -538,4 +799,4 @@ void* Arena::AllocateAlignedWithCleanup(size_t n, size_t align,
} // namespace protobuf } // namespace protobuf
} // namespace google } // namespace google
#include <google/protobuf/port_undef.inc> #include "google/protobuf/port_undef.inc"

@ -49,11 +49,12 @@ using type_info = ::type_info;
#endif #endif
#include <type_traits> #include <type_traits>
#include <google/protobuf/arena_impl.h> #include "google/protobuf/arena_config.h"
#include <google/protobuf/port.h> #include "google/protobuf/arena_impl.h"
#include "google/protobuf/port.h"
// Must be included last. // Must be included last.
#include <google/protobuf/port_def.inc> #include "google/protobuf/port_def.inc"
#ifdef SWIG #ifdef SWIG
#error "You cannot SWIG proto headers" #error "You cannot SWIG proto headers"
@ -143,7 +144,7 @@ struct ArenaOptions {
ArenaOptions() ArenaOptions()
: start_block_size(internal::AllocationPolicy::kDefaultStartBlockSize), : start_block_size(internal::AllocationPolicy::kDefaultStartBlockSize),
max_block_size(internal::AllocationPolicy::kDefaultMaxBlockSize), max_block_size(internal::GetDefaultArenaMaxBlockSize()),
initial_block(nullptr), initial_block(nullptr),
initial_block_size(0), initial_block_size(0),
block_alloc(nullptr), block_alloc(nullptr),
@ -770,6 +771,6 @@ class PROTOBUF_EXPORT PROTOBUF_ALIGNAS(8) Arena final {
} // namespace protobuf } // namespace protobuf
} // namespace google } // namespace google
#include <google/protobuf/port_undef.inc> #include "google/protobuf/port_undef.inc"
#endif // GOOGLE_PROTOBUF_ARENA_H__ #endif // GOOGLE_PROTOBUF_ARENA_H__

@ -0,0 +1,53 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "google/protobuf/arena_config.h"
#include <atomic>
#include <cstddef>
// Must be included last.
#include "google/protobuf/port_def.inc"
namespace google {
namespace protobuf {
namespace internal {
PROTOBUF_CONSTINIT const size_t kDefaultDefaultArenaMaxBlockSize = 8 << 10;
namespace arena_config_internal {
std::atomic<size_t> default_arena_max_block_size{
kDefaultDefaultArenaMaxBlockSize};
} // namespace arena_config_internal
} // namespace internal
} // namespace protobuf
} // namespace google

@ -0,0 +1,73 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef GOOGLE_PROTOBUF_ARENA_CONFIG_H__
#define GOOGLE_PROTOBUF_ARENA_CONFIG_H__
#include <atomic>
#include <cstddef>
// Must be included last.
#include "google/protobuf/port_def.inc"
namespace google {
namespace protobuf {
namespace internal {
namespace arena_config_internal {
// We use an atomic here only for correctness so that we can read/write
// concurrently. We don't have memory order requirements so we use relaxed
// memory ordering.
PROTOBUF_EXPORT extern std::atomic<size_t> default_arena_max_block_size;
} // namespace arena_config_internal
// The default value to use for DefaultArenaMaxBlockSize when
// SetDefaultArenaMaxBlockSize hasn't been called.
PROTOBUF_EXPORT extern const size_t kDefaultDefaultArenaMaxBlockSize;
// The default value to use for arena max block size when no value is provided
// in ArenaOptions.
inline size_t GetDefaultArenaMaxBlockSize() {
return arena_config_internal::default_arena_max_block_size.load(
std::memory_order_relaxed);
}
inline void SetDefaultArenaMaxBlockSize(size_t default_arena_max_block_size) {
return arena_config_internal::default_arena_max_block_size.store(
default_arena_max_block_size, std::memory_order_relaxed);
}
} // namespace internal
} // namespace protobuf
} // namespace google
#include "google/protobuf/port_undef.inc"
#endif // GOOGLE_PROTOBUF_ARENA_CONFIG_H__

@ -38,19 +38,22 @@
#include <string> #include <string>
#include <typeinfo> #include <typeinfo>
#include <google/protobuf/stubs/common.h> #include "google/protobuf/stubs/common.h"
#include <google/protobuf/stubs/logging.h> #include "google/protobuf/stubs/logging.h"
#include <google/protobuf/stubs/port.h> #include "absl/numeric/bits.h"
#include "absl/synchronization/mutex.h"
#include "google/protobuf/port.h"
#ifdef ADDRESS_SANITIZER #ifdef ADDRESS_SANITIZER
#include <sanitizer/asan_interface.h> #include <sanitizer/asan_interface.h>
#endif // ADDRESS_SANITIZER #endif // ADDRESS_SANITIZER
#include <google/protobuf/arenaz_sampler.h> #include "google/protobuf/arena_config.h"
#include "google/protobuf/arenaz_sampler.h"
// Must be included last. // Must be included last.
#include <google/protobuf/port_def.inc> #include "google/protobuf/port_def.inc"
namespace google { namespace google {
@ -243,17 +246,16 @@ class PROTOBUF_EXPORT ArenaMetricsCollector {
struct AllocationPolicy { struct AllocationPolicy {
static constexpr size_t kDefaultStartBlockSize = 256; static constexpr size_t kDefaultStartBlockSize = 256;
static constexpr size_t kDefaultMaxBlockSize = 8192;
size_t start_block_size = kDefaultStartBlockSize; size_t start_block_size = kDefaultStartBlockSize;
size_t max_block_size = kDefaultMaxBlockSize; size_t max_block_size = GetDefaultArenaMaxBlockSize();
void* (*block_alloc)(size_t) = nullptr; void* (*block_alloc)(size_t) = nullptr;
void (*block_dealloc)(void*, size_t) = nullptr; void (*block_dealloc)(void*, size_t) = nullptr;
bool IsDefault() const { bool IsDefault() const {
return start_block_size == kDefaultStartBlockSize && return start_block_size == kDefaultStartBlockSize &&
max_block_size == kDefaultMaxBlockSize && block_alloc == nullptr && max_block_size == GetDefaultArenaMaxBlockSize() &&
block_dealloc == nullptr; block_alloc == nullptr && block_dealloc == nullptr;
} }
}; };
@ -317,6 +319,8 @@ class TaggedAllocationPolicyPtr {
enum class AllocationClient { kDefault, kArray }; enum class AllocationClient { kDefault, kArray };
class ThreadSafeArena;
// A simple arena allocator. Calls to allocate functions must be properly // A simple arena allocator. Calls to allocate functions must be properly
// serialized by the caller, hence this class cannot be used as a general // serialized by the caller, hence this class cannot be used as a general
// purpose allocator in a multi-threaded program. It serves as a building block // purpose allocator in a multi-threaded program. It serves as a building block
@ -350,7 +354,7 @@ class PROTOBUF_EXPORT SerialArena {
if (PROTOBUF_PREDICT_FALSE(size < 16)) return nullptr; if (PROTOBUF_PREDICT_FALSE(size < 16)) return nullptr;
// We round up to the next larger block in case the memory doesn't match // We round up to the next larger block in case the memory doesn't match
// the pattern we are looking for. // the pattern we are looking for.
const size_t index = Bits::Log2FloorNonZero64(size - 1) - 3; const size_t index = absl::bit_width(size - 1) - 4;
if (index >= cached_block_length_) return nullptr; if (index >= cached_block_length_) return nullptr;
auto& cached_head = cached_blocks_[index]; auto& cached_head = cached_blocks_[index];
@ -372,8 +376,7 @@ class PROTOBUF_EXPORT SerialArena {
// the right size. We can statically know if the allocation size can benefit // the right size. We can statically know if the allocation size can benefit
// from it. // from it.
template <AllocationClient alloc_client = AllocationClient::kDefault> template <AllocationClient alloc_client = AllocationClient::kDefault>
void* AllocateAligned(size_t n, const AllocationPolicy* policy, void* AllocateAligned(size_t n) {
ThreadSafeArenaStats* stats) {
GOOGLE_DCHECK_EQ(internal::AlignUpTo8(n), n); // Must be already aligned. GOOGLE_DCHECK_EQ(internal::AlignUpTo8(n), n); // Must be already aligned.
GOOGLE_DCHECK_GE(limit_, ptr()); GOOGLE_DCHECK_GE(limit_, ptr());
@ -384,7 +387,7 @@ class PROTOBUF_EXPORT SerialArena {
} }
if (PROTOBUF_PREDICT_FALSE(!HasSpace(n))) { if (PROTOBUF_PREDICT_FALSE(!HasSpace(n))) {
return AllocateAlignedFallback(n, policy, stats); return AllocateAlignedFallback(n);
} }
return AllocateFromExisting(n); return AllocateFromExisting(n);
} }
@ -407,13 +410,13 @@ class PROTOBUF_EXPORT SerialArena {
if (sizeof(void*) < 8) { if (sizeof(void*) < 8) {
if (PROTOBUF_PREDICT_FALSE(size < 16)) return; if (PROTOBUF_PREDICT_FALSE(size < 16)) return;
} else { } else {
GOOGLE_DCHECK(size >= 16); PROTOBUF_ASSUME(size >= 16);
} }
// We round down to the next smaller block in case the memory doesn't match // We round down to the next smaller block in case the memory doesn't match
// the pattern we are looking for. eg, someone might have called Reserve() // the pattern we are looking for. eg, someone might have called Reserve()
// on the repeated field. // on the repeated field.
const size_t index = Bits::Log2FloorNonZero64(size) - 4; const size_t index = absl::bit_width(size) - 5;
if (PROTOBUF_PREDICT_FALSE(index >= cached_block_length_)) { if (PROTOBUF_PREDICT_FALSE(index >= cached_block_length_)) {
// We can't put this object on the freelist so make this object the // We can't put this object on the freelist so make this object the
@ -485,13 +488,10 @@ class PROTOBUF_EXPORT SerialArena {
PROTOBUF_ALWAYS_INLINE PROTOBUF_ALWAYS_INLINE
void* AllocateAlignedWithCleanup(size_t n, size_t align, void* AllocateAlignedWithCleanup(size_t n, size_t align,
void (*destructor)(void*), void (*destructor)(void*)) {
const AllocationPolicy* policy,
ThreadSafeArenaStats* stats) {
size_t required = AlignUpTo(n, align) + cleanup::Size(destructor); size_t required = AlignUpTo(n, align) + cleanup::Size(destructor);
if (PROTOBUF_PREDICT_FALSE(!HasSpace(required))) { if (PROTOBUF_PREDICT_FALSE(!HasSpace(required))) {
return AllocateAlignedWithCleanupFallback(n, align, destructor, policy, return AllocateAlignedWithCleanupFallback(n, align, destructor);
stats);
} }
return AllocateFromExistingWithCleanupFallback(n, align, destructor); return AllocateFromExistingWithCleanupFallback(n, align, destructor);
} }
@ -501,7 +501,7 @@ class PROTOBUF_EXPORT SerialArena {
const AllocationPolicy* policy, ThreadSafeArenaStats* stats) { const AllocationPolicy* policy, ThreadSafeArenaStats* stats) {
size_t required = cleanup::Size(destructor); size_t required = cleanup::Size(destructor);
if (PROTOBUF_PREDICT_FALSE(!HasSpace(required))) { if (PROTOBUF_PREDICT_FALSE(!HasSpace(required))) {
return AddCleanupFallback(elem, destructor, policy, stats); return AddCleanupFallback(elem, destructor);
} }
AddCleanupFromExisting(elem, destructor); AddCleanupFromExisting(elem, destructor);
} }
@ -533,18 +533,14 @@ class PROTOBUF_EXPORT SerialArena {
cleanup::CreateNode(tag, limit_, elem, destructor); cleanup::CreateNode(tag, limit_, elem, destructor);
} }
public:
void* owner() const { return owner_; }
SerialArena* next() const { return next_; }
void set_next(SerialArena* next) { next_ = next; }
private: private:
friend class ThreadSafeArena; friend class ThreadSafeArena;
// Creates a new SerialArena inside mem using the remaining memory as for // Creates a new SerialArena inside mem using the remaining memory as for
// future allocations. // future allocations.
static SerialArena* New(SerialArena::Memory mem, void* owner, // The `parent` arena must outlive the serial arena, which is guaranteed
ThreadSafeArenaStats* stats); // because the parent manages the lifetime of the serial arenas.
static SerialArena* New(SerialArena::Memory mem, ThreadSafeArena& parent);
// Free SerialArena returning the memory passed in to New // Free SerialArena returning the memory passed in to New
template <typename Deallocator> template <typename Deallocator>
Memory Free(Deallocator deallocator); Memory Free(Deallocator deallocator);
@ -570,9 +566,8 @@ class PROTOBUF_EXPORT SerialArena {
// data follows // data follows
}; };
void* owner_; // &ThreadCache of this thread; ThreadSafeArena& parent_;
std::atomic<Block*> head_; // Head of linked list of blocks. std::atomic<Block*> head_; // Head of linked list of blocks.
SerialArena* next_; // Next SerialArena in this linked list.
std::atomic<size_t> space_used_{0}; // Necessary for metrics. std::atomic<size_t> space_used_{0}; // Necessary for metrics.
std::atomic<size_t> space_allocated_; std::atomic<size_t> space_allocated_;
@ -609,18 +604,12 @@ class PROTOBUF_EXPORT SerialArena {
CachedBlock** cached_blocks_ = nullptr; CachedBlock** cached_blocks_ = nullptr;
// Constructor is private as only New() should be used. // Constructor is private as only New() should be used.
inline SerialArena(Block* b, void* owner); inline SerialArena(Block* b, ThreadSafeArena& parent);
void* AllocateAlignedFallback(size_t n, const AllocationPolicy* policy, void* AllocateAlignedFallback(size_t n);
ThreadSafeArenaStats* stats);
void* AllocateAlignedWithCleanupFallback(size_t n, size_t align, void* AllocateAlignedWithCleanupFallback(size_t n, size_t align,
void (*destructor)(void*), void (*destructor)(void*));
const AllocationPolicy* policy, void AddCleanupFallback(void* elem, void (*destructor)(void*));
ThreadSafeArenaStats* stats); void AllocateNewBlock(size_t n);
void AddCleanupFallback(void* elem, void (*destructor)(void*),
const AllocationPolicy* policy,
ThreadSafeArenaStats* stats);
void AllocateNewBlock(size_t n, const AllocationPolicy* policy,
ThreadSafeArenaStats* stats);
public: public:
static constexpr size_t kBlockHeaderSize = AlignUpTo8(sizeof(Block)); static constexpr size_t kBlockHeaderSize = AlignUpTo8(sizeof(Block));
@ -677,11 +666,9 @@ class PROTOBUF_EXPORT ThreadSafeArena {
void* AllocateAligned(size_t n) { void* AllocateAligned(size_t n) {
SerialArena* arena; SerialArena* arena;
if (PROTOBUF_PREDICT_TRUE(GetSerialArenaFast(&arena))) { if (PROTOBUF_PREDICT_TRUE(GetSerialArenaFast(&arena))) {
return arena->AllocateAligned<alloc_client>(n, AllocPolicy(), return arena->AllocateAligned<alloc_client>(n);
arena_stats_.MutableStats());
} else { } else {
return GetSerialArenaFallback(&thread_cache()) return AllocateAlignedFallback<alloc_client>(n);
->AllocateAligned(n, AllocPolicy(), arena_stats_.MutableStats());
} }
} }
@ -717,9 +704,21 @@ class PROTOBUF_EXPORT ThreadSafeArena {
} }
private: private:
friend class ArenaBenchmark;
friend class TcParser; friend class TcParser;
friend class SerialArena;
static uint64_t GetNextLifeCycleId(); static uint64_t GetNextLifeCycleId();
class SerialArenaChunk;
// Returns a new SerialArenaChunk that has {id, serial} at slot 0. It may
// grow based on "prev_num_slots".
static SerialArenaChunk* NewSerialArenaChunk(uint32_t prev_capacity, void* id,
SerialArena* serial);
// Adds SerialArena to the chunked list. May create a new chunk.
void AddSerialArena(void* id, SerialArena* serial);
// Unique for each arena. Changes on Reset(). // Unique for each arena. Changes on Reset().
uint64_t tag_and_id_ = 0; uint64_t tag_and_id_ = 0;
// The LSB of tag_and_id_ indicates if the arena is message-owned. // The LSB of tag_and_id_ indicates if the arena is message-owned.
@ -729,8 +728,11 @@ class PROTOBUF_EXPORT ThreadSafeArena {
static_assert(std::is_trivially_destructible<SerialArena>{}, static_assert(std::is_trivially_destructible<SerialArena>{},
"SerialArena needs to be trivially destructible."); "SerialArena needs to be trivially destructible.");
// Pointer to a linked list of SerialArena. // Pointer to a linked list of SerialArenaChunk.
std::atomic<SerialArena*> threads_; std::atomic<SerialArenaChunk*> head_;
// Adding a new chunk to head_ must be protected by mutex_.
absl::Mutex mutex_;
const AllocationPolicy* AllocPolicy() const { return alloc_policy_.get(); } const AllocationPolicy* AllocPolicy() const { return alloc_policy_.get(); }
void InitializeFrom(void* mem, size_t size); void InitializeFrom(void* mem, size_t size);
@ -739,7 +741,7 @@ class PROTOBUF_EXPORT ThreadSafeArena {
void (*destructor)(void*)); void (*destructor)(void*));
void Init(); void Init();
void SetInitialBlock(void* mem, size_t size); SerialArena* SetInitialBlock(void* mem, size_t size);
// Delete or Destruct all objects owned by the arena. // Delete or Destruct all objects owned by the arena.
void CleanupList(); void CleanupList();
@ -762,16 +764,22 @@ class PROTOBUF_EXPORT ThreadSafeArena {
} }
return false; return false;
} }
SerialArena* GetSerialArenaFallback(void* me);
// Finds SerialArena or creates one if not found.
SerialArena* GetSerialArenaFallback();
template <AllocationClient alloc_client = AllocationClient::kDefault>
void* AllocateAlignedFallback(size_t n);
// Executes callback function over chunked list of SerialArena in reverse
// chronological order. Passes const SerialArena*.
template <typename Functor> template <typename Functor>
void PerSerialArena(Functor fn) { void PerConstSerialArena(Functor fn) const;
// By omitting an Acquire barrier we ensure that any user code that doesn't
// properly synchronize Reset() or the destructor will throw a TSAN warning.
SerialArena* serial = threads_.load(std::memory_order_relaxed);
for (; serial; serial = serial->next()) fn(serial); // Executes callback function over chunked list of SerialArena in reverse
} // chronological order.
template <typename Functor>
void PerSerialArena(Functor fn);
// Releases all memory except the first block which it returns. The first // Releases all memory except the first block which it returns. The first
// block might be owned by the user and thus need some extra checks before // block might be owned by the user and thus need some extra checks before
@ -847,6 +855,6 @@ class PROTOBUF_EXPORT ThreadSafeArena {
} // namespace protobuf } // namespace protobuf
} // namespace google } // namespace google
#include <google/protobuf/port_undef.inc> #include "google/protobuf/port_undef.inc"
#endif // GOOGLE_PROTOBUF_ARENA_IMPL_H__ #endif // GOOGLE_PROTOBUF_ARENA_IMPL_H__

@ -28,10 +28,10 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <google/protobuf/arena_test_util.h> #include "google/protobuf/arena_test_util.h"
#include <google/protobuf/stubs/logging.h> #include "google/protobuf/stubs/logging.h"
#include <google/protobuf/stubs/common.h> #include "google/protobuf/stubs/common.h"
#define EXPECT_EQ GOOGLE_CHECK_EQ #define EXPECT_EQ GOOGLE_CHECK_EQ

@ -31,11 +31,11 @@
#ifndef GOOGLE_PROTOBUF_ARENA_TEST_UTIL_H__ #ifndef GOOGLE_PROTOBUF_ARENA_TEST_UTIL_H__
#define GOOGLE_PROTOBUF_ARENA_TEST_UTIL_H__ #define GOOGLE_PROTOBUF_ARENA_TEST_UTIL_H__
#include <google/protobuf/stubs/logging.h> #include "google/protobuf/stubs/logging.h"
#include <google/protobuf/stubs/common.h> #include "google/protobuf/stubs/common.h"
#include <google/protobuf/arena.h> #include "google/protobuf/arena.h"
#include <google/protobuf/io/coded_stream.h> #include "google/protobuf/io/coded_stream.h"
#include <google/protobuf/io/zero_copy_stream_impl_lite.h> #include "google/protobuf/io/zero_copy_stream_impl_lite.h"
namespace google { namespace google {
namespace protobuf { namespace protobuf {

@ -28,7 +28,7 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <google/protobuf/arena.h> #include "google/protobuf/arena.h"
#include <algorithm> #include <algorithm>
#include <cstddef> #include <cstddef>
@ -39,29 +39,29 @@
#include <typeinfo> #include <typeinfo>
#include <vector> #include <vector>
#include <google/protobuf/stubs/logging.h> #include "google/protobuf/stubs/logging.h"
#include <google/protobuf/stubs/common.h> #include "google/protobuf/stubs/common.h"
#include <google/protobuf/unittest.pb.h> #include "google/protobuf/unittest.pb.h"
#include <google/protobuf/unittest_arena.pb.h> #include "google/protobuf/unittest_arena.pb.h"
#include <gmock/gmock.h> #include <gmock/gmock.h>
#include <gtest/gtest.h> #include <gtest/gtest.h>
#include "absl/strings/string_view.h" #include "absl/strings/string_view.h"
#include <google/protobuf/arena_test_util.h> #include "google/protobuf/arena_test_util.h"
#include <google/protobuf/descriptor.h> #include "google/protobuf/descriptor.h"
#include <google/protobuf/extension_set.h> #include "google/protobuf/extension_set.h"
#include <google/protobuf/io/coded_stream.h> #include "google/protobuf/io/coded_stream.h"
#include <google/protobuf/io/zero_copy_stream_impl_lite.h> #include "google/protobuf/io/zero_copy_stream_impl_lite.h"
#include <google/protobuf/message.h> #include "google/protobuf/message.h"
#include <google/protobuf/message_lite.h> #include "google/protobuf/message_lite.h"
#include <google/protobuf/repeated_field.h> #include "google/protobuf/repeated_field.h"
#include <google/protobuf/test_util.h> #include "google/protobuf/test_util.h"
#include <google/protobuf/unknown_field_set.h> #include "google/protobuf/unknown_field_set.h"
#include <google/protobuf/wire_format_lite.h> #include "google/protobuf/wire_format_lite.h"
#include "absl/synchronization/mutex.h" #include "absl/synchronization/mutex.h"
// Must be included last // Must be included last
#include <google/protobuf/port_def.inc> #include "google/protobuf/port_def.inc"
using proto2_arena_unittest::ArenaMessage; using proto2_arena_unittest::ArenaMessage;
using protobuf_unittest::ForeignMessage; using protobuf_unittest::ForeignMessage;
@ -1575,4 +1575,4 @@ TEST(ArenaTest, SpaceReusePoisonsAndUnpoisonsMemory) {
} // namespace protobuf } // namespace protobuf
} // namespace google } // namespace google
#include <google/protobuf/port_undef.inc> #include "google/protobuf/port_undef.inc"

@ -28,21 +28,21 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <google/protobuf/arenastring.h> #include "google/protobuf/arenastring.h"
#include <cstddef> #include <cstddef>
#include <google/protobuf/stubs/logging.h> #include "google/protobuf/stubs/logging.h"
#include <google/protobuf/stubs/common.h> #include "google/protobuf/stubs/common.h"
#include <google/protobuf/io/coded_stream.h> #include "google/protobuf/io/coded_stream.h"
#include "absl/strings/string_view.h" #include "absl/strings/string_view.h"
#include "absl/synchronization/mutex.h" #include "absl/synchronization/mutex.h"
#include <google/protobuf/message_lite.h> #include "google/protobuf/message_lite.h"
#include <google/protobuf/parse_context.h> #include "google/protobuf/parse_context.h"
#include <google/protobuf/stubs/stl_util.h> #include "google/protobuf/stubs/stl_util.h"
// clang-format off // clang-format off
#include <google/protobuf/port_def.inc> #include "google/protobuf/port_def.inc"
// clang-format on // clang-format on
namespace google { namespace google {
@ -277,4 +277,4 @@ const char* EpsCopyInputStream::ReadArenaString(const char* ptr,
} // namespace protobuf } // namespace protobuf
} // namespace google } // namespace google
#include <google/protobuf/port_undef.inc> #include "google/protobuf/port_undef.inc"

@ -36,15 +36,15 @@
#include <type_traits> #include <type_traits>
#include <utility> #include <utility>
#include <google/protobuf/stubs/logging.h> #include "google/protobuf/stubs/logging.h"
#include <google/protobuf/stubs/common.h> #include "google/protobuf/stubs/common.h"
#include <google/protobuf/arena.h> #include "google/protobuf/arena.h"
#include <google/protobuf/port.h> #include "google/protobuf/port.h"
#include "absl/strings/string_view.h" #include "absl/strings/string_view.h"
#include <google/protobuf/explicitly_constructed.h> #include "google/protobuf/explicitly_constructed.h"
// must be last: // must be last:
#include <google/protobuf/port_def.inc> #include "google/protobuf/port_def.inc"
#ifdef SWIG #ifdef SWIG
#error "You cannot SWIG proto headers" #error "You cannot SWIG proto headers"
@ -476,6 +476,6 @@ inline std::string* ArenaStringPtr::UnsafeMutablePointer() {
} // namespace protobuf } // namespace protobuf
} // namespace google } // namespace google
#include <google/protobuf/port_undef.inc> #include "google/protobuf/port_undef.inc"
#endif // GOOGLE_PROTOBUF_ARENASTRING_H__ #endif // GOOGLE_PROTOBUF_ARENASTRING_H__

@ -28,7 +28,7 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <google/protobuf/arenastring.h> #include "google/protobuf/arenastring.h"
#include <algorithm> #include <algorithm>
#include <cstdlib> #include <cstdlib>
@ -37,18 +37,18 @@
#include <utility> #include <utility>
#include <vector> #include <vector>
#include <google/protobuf/stubs/logging.h> #include "google/protobuf/stubs/logging.h"
#include <google/protobuf/stubs/common.h> #include "google/protobuf/stubs/common.h"
#include <google/protobuf/io/coded_stream.h> #include "google/protobuf/io/coded_stream.h"
#include <google/protobuf/io/zero_copy_stream_impl.h> #include "google/protobuf/io/zero_copy_stream_impl.h"
#include <google/protobuf/generated_message_util.h> #include "google/protobuf/generated_message_util.h"
#include <google/protobuf/message_lite.h> #include "google/protobuf/message_lite.h"
#include <gtest/gtest.h> #include <gtest/gtest.h>
#include "absl/strings/string_view.h" #include "absl/strings/string_view.h"
// Must be included last. // Must be included last.
#include <google/protobuf/port_def.inc> #include "google/protobuf/port_def.inc"
namespace google { namespace google {
namespace protobuf { namespace protobuf {
@ -151,4 +151,4 @@ TEST_P(DualArena, Swap) {
} // namespace protobuf } // namespace protobuf
} // namespace google } // namespace google
#include <google/protobuf/port_undef.inc> #include "google/protobuf/port_undef.inc"

@ -28,7 +28,7 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <google/protobuf/arenaz_sampler.h> #include "google/protobuf/arenaz_sampler.h"
#include <atomic> #include <atomic>
#include <cstdint> #include <cstdint>
@ -37,7 +37,7 @@
// Must be included last. // Must be included last.
#include <google/protobuf/port_def.inc> #include "google/protobuf/port_def.inc"
namespace google { namespace google {
namespace protobuf { namespace protobuf {

@ -39,7 +39,7 @@
// Must be included last. // Must be included last.
#include <google/protobuf/port_def.inc> #include "google/protobuf/port_def.inc"
namespace google { namespace google {
namespace protobuf { namespace protobuf {
@ -257,5 +257,5 @@ void SetThreadSafeArenazGlobalNextSample(int64_t next_sample);
} // namespace protobuf } // namespace protobuf
} // namespace google } // namespace google
#include <google/protobuf/port_undef.inc> #include "google/protobuf/port_undef.inc"
#endif // GOOGLE_PROTOBUF_SRC_PROTOBUF_ARENAZ_SAMPLER_H__ #endif // GOOGLE_PROTOBUF_SRC_PROTOBUF_ARENAZ_SAMPLER_H__

@ -28,7 +28,7 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <google/protobuf/arenaz_sampler.h> #include "google/protobuf/arenaz_sampler.h"
#include <atomic> #include <atomic>
#include <limits> #include <limits>
@ -42,7 +42,7 @@
// Must be included last. // Must be included last.
#include <google/protobuf/port_def.inc> #include "google/protobuf/port_def.inc"
namespace google { namespace google {
namespace protobuf { namespace protobuf {

@ -28,20 +28,20 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <google/protobuf/compiler/annotation_test_util.h> #include "google/protobuf/compiler/annotation_test_util.h"
#include <cstdint> #include <cstdint>
#include <memory> #include <memory>
#include <google/protobuf/testing/file.h> #include "google/protobuf/testing/file.h"
#include <google/protobuf/testing/file.h> #include "google/protobuf/testing/file.h"
#include <google/protobuf/compiler/code_generator.h> #include "google/protobuf/compiler/code_generator.h"
#include <google/protobuf/compiler/command_line_interface.h> #include "google/protobuf/compiler/command_line_interface.h"
#include <google/protobuf/io/printer.h> #include "google/protobuf/io/printer.h"
#include <google/protobuf/io/zero_copy_stream.h> #include "google/protobuf/io/zero_copy_stream.h"
#include <google/protobuf/io/zero_copy_stream_impl_lite.h> #include "google/protobuf/io/zero_copy_stream_impl_lite.h"
#include <google/protobuf/descriptor.pb.h> #include "google/protobuf/descriptor.pb.h"
#include <google/protobuf/testing/googletest.h> #include "google/protobuf/testing/googletest.h"
#include <gtest/gtest.h> #include <gtest/gtest.h>
namespace google { namespace google {

@ -31,8 +31,8 @@
#ifndef GOOGLE_PROTOBUF_COMPILER_ANNOTATION_TEST_UTIL_H__ #ifndef GOOGLE_PROTOBUF_COMPILER_ANNOTATION_TEST_UTIL_H__
#define GOOGLE_PROTOBUF_COMPILER_ANNOTATION_TEST_UTIL_H__ #define GOOGLE_PROTOBUF_COMPILER_ANNOTATION_TEST_UTIL_H__
#include <google/protobuf/descriptor.pb.h> #include "google/protobuf/descriptor.pb.h"
#include <google/protobuf/testing/googletest.h> #include "google/protobuf/testing/googletest.h"
#include <gtest/gtest.h> #include <gtest/gtest.h>
// Utilities that assist in writing tests for generator annotations. // Utilities that assist in writing tests for generator annotations.

@ -32,13 +32,13 @@
// Based on original Protocol Buffers design by // Based on original Protocol Buffers design by
// Sanjay Ghemawat, Jeff Dean, and others. // Sanjay Ghemawat, Jeff Dean, and others.
#include <google/protobuf/compiler/code_generator.h> #include "google/protobuf/compiler/code_generator.h"
#include <google/protobuf/stubs/logging.h> #include "google/protobuf/stubs/logging.h"
#include <google/protobuf/stubs/common.h> #include "google/protobuf/stubs/common.h"
#include <google/protobuf/compiler/plugin.pb.h> #include "google/protobuf/compiler/plugin.pb.h"
#include <google/protobuf/descriptor.h> #include "google/protobuf/descriptor.h"
#include <google/protobuf/stubs/strutil.h> #include "google/protobuf/stubs/strutil.h"
#include "absl/strings/str_split.h" #include "absl/strings/str_split.h"
namespace google { namespace google {

@ -41,10 +41,11 @@
#include <string> #include <string>
#include <utility> #include <utility>
#include <vector> #include <vector>
#include <google/protobuf/stubs/common.h>
#include "google/protobuf/port.h"
// Must be included last. // Must be included last.
#include <google/protobuf/port_def.inc> #include "google/protobuf/port_def.inc"
namespace google { namespace google {
namespace protobuf { namespace protobuf {
@ -200,6 +201,6 @@ PROTOC_EXPORT std::string StripProto(const std::string& filename);
} // namespace protobuf } // namespace protobuf
} // namespace google } // namespace google
#include <google/protobuf/port_undef.inc> #include "google/protobuf/port_undef.inc"
#endif // GOOGLE_PROTOBUF_COMPILER_CODE_GENERATOR_H__ #endif // GOOGLE_PROTOBUF_COMPILER_CODE_GENERATOR_H__

@ -32,11 +32,12 @@
// Based on original Protocol Buffers design by // Based on original Protocol Buffers design by
// Sanjay Ghemawat, Jeff Dean, and others. // Sanjay Ghemawat, Jeff Dean, and others.
#include <google/protobuf/compiler/command_line_interface.h> #include "google/protobuf/compiler/command_line_interface.h"
#include <google/protobuf/stubs/platform_macros.h> #include "google/protobuf/stubs/platform_macros.h"
#include <stdio.h> #include <stdio.h>
#include <stdlib.h>
#include <sys/types.h> #include <sys/types.h>
#ifdef major #ifdef major
#undef major #undef major
@ -58,6 +59,10 @@
#include <limits.h> // For PATH_MAX #include <limits.h> // For PATH_MAX
#include <memory> #include <memory>
#include <string>
#include <unordered_set>
#include <utility>
#include <vector>
#if defined(__APPLE__) #if defined(__APPLE__)
#include <mach-o/dyld.h> #include <mach-o/dyld.h>
@ -65,30 +70,30 @@
#include <sys/sysctl.h> #include <sys/sysctl.h>
#endif #endif
#include <google/protobuf/stubs/common.h> #include "google/protobuf/stubs/common.h"
#include <google/protobuf/stubs/logging.h> #include "google/protobuf/stubs/logging.h"
#include <google/protobuf/compiler/subprocess.h> #include "google/protobuf/compiler/subprocess.h"
#include <google/protobuf/compiler/plugin.pb.h> #include "google/protobuf/compiler/plugin.pb.h"
#include <google/protobuf/stubs/strutil.h> #include "google/protobuf/stubs/strutil.h"
#include <google/protobuf/stubs/stringprintf.h> #include "google/protobuf/stubs/stringprintf.h"
#include "absl/strings/str_replace.h" #include "absl/strings/str_replace.h"
#include "absl/strings/str_split.h" #include "absl/strings/str_split.h"
#include "absl/strings/substitute.h" #include "absl/strings/substitute.h"
#include <google/protobuf/compiler/code_generator.h> #include "google/protobuf/compiler/code_generator.h"
#include <google/protobuf/compiler/importer.h> #include "google/protobuf/compiler/importer.h"
#include <google/protobuf/compiler/zip_writer.h> #include "google/protobuf/compiler/zip_writer.h"
#include <google/protobuf/descriptor.h> #include "google/protobuf/descriptor.h"
#include <google/protobuf/dynamic_message.h> #include "google/protobuf/dynamic_message.h"
#include <google/protobuf/io/coded_stream.h> #include "google/protobuf/io/coded_stream.h"
#include <google/protobuf/io/io_win32.h> #include "google/protobuf/io/io_win32.h"
#include <google/protobuf/io/printer.h> #include "google/protobuf/io/printer.h"
#include <google/protobuf/io/zero_copy_stream_impl.h> #include "google/protobuf/io/zero_copy_stream_impl.h"
#include <google/protobuf/text_format.h> #include "google/protobuf/text_format.h"
#include <google/protobuf/stubs/stl_util.h> #include "google/protobuf/stubs/stl_util.h"
// Must be included last. // Must be included last.
#include <google/protobuf/port_def.inc> #include "google/protobuf/port_def.inc"
namespace google { namespace google {
namespace protobuf { namespace protobuf {
@ -1298,9 +1303,9 @@ bool CommandLineInterface::ParseInputFiles(
direct_dependencies_.end()) { direct_dependencies_.end()) {
indirect_imports = true; indirect_imports = true;
std::cerr << parsed_file->name() << ": " std::cerr << parsed_file->name() << ": "
<< StringReplace(direct_dependencies_violation_msg_, "%s", << absl::StrReplaceAll(
parsed_file->dependency(i)->name(), direct_dependencies_violation_msg_,
true /* replace_all */) {{"%s", parsed_file->dependency(i)->name()}})
<< std::endl; << std::endl;
} }
} }
@ -1945,6 +1950,23 @@ CommandLineInterface::InterpretArgument(const std::string& name,
} }
mode_ = MODE_PRINT; mode_ = MODE_PRINT;
print_mode_ = PRINT_FREE_FIELDS; print_mode_ = PRINT_FREE_FIELDS;
} else if (name == "--enable_codegen_trace") {
// We use environment variables here so that subprocesses see this setting
// when we spawn them.
//
// Setting environment variables is more-or-less asking for a data race,
// because C got this wrong and did not mandate synchronization.
// In practice, this code path is "only" in the main thread of protoc, and
// it is common knowledge that touching setenv in a library is asking for
// life-ruining bugs *anyways*. As such, there is a reasonable probability
// that there isn't another thread kicking environment variables at this
// moment.
#ifdef _WIN32
::_putenv(absl::StrCat(io::Printer::kProtocCodegenTrace, "=yes").c_str());
#else
::setenv(io::Printer::kProtocCodegenTrace.data(), "yes", 0);
#endif
} else { } else {
// Some other flag. Look it up in the generators list. // Some other flag. Look it up in the generators list.
const GeneratorInfo* generator_info = FindGeneratorByFlag(name); const GeneratorInfo* generator_info = FindGeneratorByFlag(name);
@ -2070,7 +2092,10 @@ Parse PROTO_FILES and generate output based on the options given:
defined in the given proto files. Groups share defined in the given proto files. Groups share
the same field number space with the parent the same field number space with the parent
message. Extension ranges are counted as message. Extension ranges are counted as
occupied fields numbers.)"; occupied fields numbers.
--enable_codegen_trace Enables tracing which parts of protoc are
responsible for what codegen output. Not supported
by all backends or on all platforms.)";
if (!plugin_prefix_.empty()) { if (!plugin_prefix_.empty()) {
std::cout << R"( std::cout << R"(
--plugin=EXECUTABLE Specifies a plugin executable to use. --plugin=EXECUTABLE Specifies a plugin executable to use.

@ -49,11 +49,11 @@
#include <utility> #include <utility>
#include <vector> #include <vector>
#include <google/protobuf/stubs/common.h>
#include "absl/strings/string_view.h" #include "absl/strings/string_view.h"
#include "google/protobuf/port.h"
// Must be included last. // Must be included last.
#include <google/protobuf/port_def.inc> #include "google/protobuf/port_def.inc"
namespace google { namespace google {
namespace protobuf { namespace protobuf {
@ -465,6 +465,6 @@ class PROTOC_EXPORT CommandLineInterface {
} // namespace protobuf } // namespace protobuf
} // namespace google } // namespace google
#include <google/protobuf/port_undef.inc> #include "google/protobuf/port_undef.inc"
#endif // GOOGLE_PROTOBUF_COMPILER_COMMAND_LINE_INTERFACE_H__ #endif // GOOGLE_PROTOBUF_COMPILER_COMMAND_LINE_INTERFACE_H__

@ -45,35 +45,35 @@
#include <string> #include <string>
#include <vector> #include <vector>
#include <google/protobuf/stubs/stringprintf.h> #include "google/protobuf/stubs/stringprintf.h"
#include <google/protobuf/testing/file.h> #include "google/protobuf/testing/file.h"
#include <google/protobuf/testing/file.h> #include "google/protobuf/testing/file.h"
#include <google/protobuf/testing/file.h> #include "google/protobuf/testing/file.h"
#include <google/protobuf/any.pb.h> #include "google/protobuf/any.pb.h"
#include <google/protobuf/test_util2.h> #include "google/protobuf/test_util2.h"
#include <google/protobuf/unittest.pb.h> #include "google/protobuf/unittest.pb.h"
#include <google/protobuf/unittest_custom_options.pb.h> #include "google/protobuf/unittest_custom_options.pb.h"
#include <google/protobuf/descriptor.pb.h> #include "google/protobuf/descriptor.pb.h"
#include <google/protobuf/testing/googletest.h> #include "google/protobuf/testing/googletest.h"
#include <gtest/gtest.h> #include <gtest/gtest.h>
#include "absl/status/status.h" #include "absl/status/status.h"
#include "absl/strings/str_replace.h" #include "absl/strings/str_replace.h"
#include "absl/strings/str_split.h" #include "absl/strings/str_split.h"
#include "absl/strings/string_view.h" #include "absl/strings/string_view.h"
#include "absl/strings/substitute.h" #include "absl/strings/substitute.h"
#include <google/protobuf/compiler/code_generator.h> #include "google/protobuf/compiler/code_generator.h"
#include <google/protobuf/compiler/command_line_interface.h> #include "google/protobuf/compiler/command_line_interface.h"
#include <google/protobuf/compiler/mock_code_generator.h> #include "google/protobuf/compiler/mock_code_generator.h"
#include <google/protobuf/compiler/subprocess.h> #include "google/protobuf/compiler/subprocess.h"
#include <google/protobuf/descriptor.h> #include "google/protobuf/descriptor.h"
#include <google/protobuf/io/io_win32.h> #include "google/protobuf/io/io_win32.h"
#include <google/protobuf/io/printer.h> #include "google/protobuf/io/printer.h"
#include <google/protobuf/io/zero_copy_stream.h> #include "google/protobuf/io/zero_copy_stream.h"
#include <google/protobuf/stubs/strutil.h> #include "google/protobuf/stubs/strutil.h"
// Must be included last. // Must be included last.
#include <google/protobuf/port_def.inc> #include "google/protobuf/port_def.inc"
namespace google { namespace google {
namespace protobuf { namespace protobuf {
@ -372,8 +372,8 @@ void CommandLineInterfaceTest::RunWithArgs(std::vector<std::string> args) {
std::unique_ptr<const char*[]> argv(new const char*[args.size()]); std::unique_ptr<const char*[]> argv(new const char*[args.size()]);
for (int i = 0; i < args.size(); i++) { for (size_t i = 0; i < args.size(); i++) {
args[i] = StringReplace(args[i], "$tmpdir", temp_directory_, true); args[i] = absl::StrReplaceAll(args[i], {{"$tmpdir", temp_directory_}});
argv[i] = args[i].c_str(); argv[i] = args[i].c_str();
} }
@ -410,7 +410,7 @@ void CommandLineInterfaceTest::CreateTempFile(const std::string& name,
// Write file. // Write file.
std::string full_name = temp_directory_ + "/" + name; std::string full_name = temp_directory_ + "/" + name;
GOOGLE_CHECK_OK(File::SetContents( GOOGLE_CHECK_OK(File::SetContents(
full_name, StringReplace(contents, "$tmpdir", temp_directory_, true), full_name, absl::StrReplaceAll(contents, {{"$tmpdir", temp_directory_}}),
true)); true));
} }
@ -429,7 +429,7 @@ void CommandLineInterfaceTest::ExpectNoErrors() {
void CommandLineInterfaceTest::ExpectErrorText( void CommandLineInterfaceTest::ExpectErrorText(
const std::string& expected_text) { const std::string& expected_text) {
EXPECT_NE(0, return_code_); EXPECT_NE(0, return_code_);
EXPECT_EQ(StringReplace(expected_text, "$tmpdir", temp_directory_, true), EXPECT_EQ(absl::StrReplaceAll(expected_text, {{"$tmpdir", temp_directory_}}),
error_text_); error_text_);
} }
@ -542,7 +542,7 @@ void CommandLineInterfaceTest::ExpectFileContent(const std::string& filename,
std::string file_contents; std::string file_contents;
GOOGLE_CHECK_OK(File::GetContents(path, &file_contents, true)); GOOGLE_CHECK_OK(File::GetContents(path, &file_contents, true));
EXPECT_EQ(StringReplace(content, "$tmpdir", temp_directory_, true), EXPECT_EQ(absl::StrReplaceAll(content, {{"$tmpdir", temp_directory_}}),
file_contents); file_contents);
} }
@ -2785,7 +2785,7 @@ INSTANTIATE_TEST_SUITE_P(FileDescriptorSetSource, EncodeDecodeTest,
#endif // !GOOGLE_PROTOBUF_HEAP_CHECK_DRACONIAN #endif // !GOOGLE_PROTOBUF_HEAP_CHECK_DRACONIAN
#include <google/protobuf/port_undef.inc> #include "google/protobuf/port_undef.inc"
} // namespace compiler } // namespace compiler
} // namespace protobuf } // namespace protobuf

@ -58,6 +58,7 @@ cc_library(
"@com_google_absl//absl/base:core_headers", "@com_google_absl//absl/base:core_headers",
"@com_google_absl//absl/container:flat_hash_map", "@com_google_absl//absl/container:flat_hash_map",
"@com_google_absl//absl/container:flat_hash_set", "@com_google_absl//absl/container:flat_hash_set",
"@com_google_absl//absl/container:layout",
"@com_google_absl//absl/strings", "@com_google_absl//absl/strings",
"@com_google_absl//absl/synchronization", "@com_google_absl//absl/synchronization",
], ],

@ -44,19 +44,19 @@
#include <string> #include <string>
#include <google/protobuf/testing/file.h> #include "google/protobuf/testing/file.h"
#include <google/protobuf/testing/file.h> #include "google/protobuf/testing/file.h"
#include <google/protobuf/compiler/cpp/generator.h> #include "google/protobuf/compiler/cpp/generator.h"
#include <google/protobuf/compiler/importer.h> #include "google/protobuf/compiler/importer.h"
#include <google/protobuf/test_util2.h> #include "google/protobuf/test_util2.h"
#include <google/protobuf/io/zero_copy_stream_impl.h> #include "google/protobuf/io/zero_copy_stream_impl.h"
#include <google/protobuf/descriptor.h> #include "google/protobuf/descriptor.h"
#include <google/protobuf/testing/googletest.h> #include "google/protobuf/testing/googletest.h"
#include <gtest/gtest.h> #include <gtest/gtest.h>
#include "absl/container/flat_hash_map.h" #include "absl/container/flat_hash_map.h"
#include "absl/strings/substitute.h" #include "absl/strings/substitute.h"
#include <google/protobuf/compiler/cpp/helpers.h> #include "google/protobuf/compiler/cpp/helpers.h"
#include <google/protobuf/stubs/stl_util.h> #include "google/protobuf/stubs/stl_util.h"
namespace google { namespace google {
namespace protobuf { namespace protobuf {

@ -1,6 +1,6 @@
#ifndef GOOGLE_PROTOBUF_COMPILER_CPP_CPP_GENERATOR_H_ #ifndef GOOGLE_PROTOBUF_COMPILER_CPP_CPP_GENERATOR_H_
#define GOOGLE_PROTOBUF_COMPILER_CPP_CPP_GENERATOR_H_ #define GOOGLE_PROTOBUF_COMPILER_CPP_CPP_GENERATOR_H_
#include <google/protobuf/compiler/cpp/generator.h> #include "google/protobuf/compiler/cpp/generator.h"
#endif // GOOGLE_PROTOBUF_COMPILER_CPP_CPP_GENERATOR_H_ #endif // GOOGLE_PROTOBUF_COMPILER_CPP_CPP_GENERATOR_H_

@ -32,7 +32,7 @@
// Based on original Protocol Buffers design by // Based on original Protocol Buffers design by
// Sanjay Ghemawat, Jeff Dean, and others. // Sanjay Ghemawat, Jeff Dean, and others.
#include <google/protobuf/compiler/cpp/enum.h> #include "google/protobuf/compiler/cpp/enum.h"
#include <cstdint> #include <cstdint>
#include <limits> #include <limits>
@ -40,10 +40,10 @@
#include <unordered_set> #include <unordered_set>
#include <utility> #include <utility>
#include <google/protobuf/io/printer.h> #include "google/protobuf/io/printer.h"
#include <google/protobuf/stubs/strutil.h> #include "google/protobuf/stubs/strutil.h"
#include <google/protobuf/compiler/cpp/helpers.h> #include "google/protobuf/compiler/cpp/helpers.h"
#include <google/protobuf/compiler/cpp/names.h> #include "google/protobuf/compiler/cpp/names.h"
namespace google { namespace google {
namespace protobuf { namespace protobuf {
@ -51,9 +51,9 @@ namespace compiler {
namespace cpp { namespace cpp {
namespace { namespace {
// The GOOGLE_ARRAYSIZE constant is the max enum value plus 1. If the max enum value // The ARRAYSIZE constant is the max enum value plus 1. If the max enum value
// is kint32max, GOOGLE_ARRAYSIZE will overflow. In such cases we should omit the // is kint32max, ARRAYSIZE will overflow. In such cases we should omit the
// generation of the GOOGLE_ARRAYSIZE constant. // generation of the ARRAYSIZE constant.
bool ShouldGenerateArraySize(const EnumDescriptor* descriptor) { bool ShouldGenerateArraySize(const EnumDescriptor* descriptor) {
int32_t max_value = descriptor->value(0)->number(); int32_t max_value = descriptor->value(0)->number();
for (int i = 0; i < descriptor->value_count(); i++) { for (int i = 0; i < descriptor->value_count(); i++) {

@ -39,8 +39,8 @@
#include <set> #include <set>
#include <string> #include <string>
#include <google/protobuf/descriptor.h> #include "google/protobuf/descriptor.h"
#include <google/protobuf/compiler/cpp/options.h> #include "google/protobuf/compiler/cpp/options.h"
namespace google { namespace google {
namespace protobuf { namespace protobuf {

@ -32,13 +32,13 @@
// Based on original Protocol Buffers design by // Based on original Protocol Buffers design by
// Sanjay Ghemawat, Jeff Dean, and others. // Sanjay Ghemawat, Jeff Dean, and others.
#include <google/protobuf/compiler/cpp/enum_field.h> #include "google/protobuf/compiler/cpp/enum_field.h"
#include <google/protobuf/io/printer.h> #include "google/protobuf/io/printer.h"
#include <google/protobuf/wire_format.h> #include "google/protobuf/wire_format.h"
#include <google/protobuf/stubs/strutil.h> #include "google/protobuf/stubs/strutil.h"
#include <google/protobuf/compiler/cpp/field.h> #include "google/protobuf/compiler/cpp/field.h"
#include <google/protobuf/compiler/cpp/helpers.h> #include "google/protobuf/compiler/cpp/helpers.h"
namespace google { namespace google {
namespace protobuf { namespace protobuf {

@ -38,7 +38,7 @@
#include <map> #include <map>
#include <string> #include <string>
#include <google/protobuf/compiler/cpp/field.h> #include "google/protobuf/compiler/cpp/field.h"
namespace google { namespace google {
namespace protobuf { namespace protobuf {

@ -32,16 +32,16 @@
// Based on original Protocol Buffers design by // Based on original Protocol Buffers design by
// Sanjay Ghemawat, Jeff Dean, and others. // Sanjay Ghemawat, Jeff Dean, and others.
#include <google/protobuf/compiler/cpp/extension.h> #include "google/protobuf/compiler/cpp/extension.h"
#include <map> #include <map>
#include <google/protobuf/io/printer.h> #include "google/protobuf/io/printer.h"
#include <google/protobuf/stubs/strutil.h> #include "google/protobuf/stubs/strutil.h"
#include "absl/strings/str_cat.h" #include "absl/strings/str_cat.h"
#include "absl/strings/str_replace.h" #include "absl/strings/str_replace.h"
#include <google/protobuf/compiler/cpp/helpers.h> #include "google/protobuf/compiler/cpp/helpers.h"
#include <google/protobuf/descriptor.pb.h> #include "google/protobuf/descriptor.pb.h"
namespace google { namespace google {
namespace protobuf { namespace protobuf {
@ -79,7 +79,6 @@ ExtensionGenerator::ExtensionGenerator(const FieldDescriptor* descriptor,
type_traits_.append(" >"); type_traits_.append(" >");
break; break;
} }
SetCommonVars(options, &variables_);
SetCommonMessageDataVariables(descriptor_->containing_type(), &variables_); SetCommonMessageDataVariables(descriptor_->containing_type(), &variables_);
variables_["extendee"] = variables_["extendee"] =
QualifiedClassName(descriptor_->containing_type(), options_); QualifiedClassName(descriptor_->containing_type(), options_);
@ -161,7 +160,8 @@ void ExtensionGenerator::GenerateDefinition(io::Printer* printer) {
// it in the header which would be annoying for other reasons. So we // it in the header which would be annoying for other reasons. So we
// replace :: with _ in the name and declare it as a global. // replace :: with _ in the name and declare it as a global.
default_str = default_str =
StringReplace(variables_["scoped_name"], "::", "_", true) + "_default"; absl::StrReplaceAll(variables_["scoped_name"], {{"::", "_"}}) +
"_default";
format("const std::string $1$($2$);\n", default_str, format("const std::string $1$($2$);\n", default_str,
DefaultValue(options_, descriptor_)); DefaultValue(options_, descriptor_));
} else if (descriptor_->message_type()) { } else if (descriptor_->message_type()) {

@ -38,8 +38,8 @@
#include <map> #include <map>
#include <string> #include <string>
#include <google/protobuf/stubs/common.h> #include "google/protobuf/compiler/cpp/options.h"
#include <google/protobuf/compiler/cpp/options.h> #include "google/protobuf/port.h"
namespace google { namespace google {
namespace protobuf { namespace protobuf {

@ -32,7 +32,7 @@
// Based on original Protocol Buffers design by // Based on original Protocol Buffers design by
// Sanjay Ghemawat, Jeff Dean, and others. // Sanjay Ghemawat, Jeff Dean, and others.
#include <google/protobuf/compiler/cpp/field.h> #include "google/protobuf/compiler/cpp/field.h"
#include <cstdint> #include <cstdint>
#include <memory> #include <memory>
@ -41,18 +41,18 @@
#include "absl/strings/str_cat.h" #include "absl/strings/str_cat.h"
#include "absl/strings/string_view.h" #include "absl/strings/string_view.h"
#include "absl/strings/substitute.h" #include "absl/strings/substitute.h"
#include <google/protobuf/compiler/cpp/helpers.h> #include "google/protobuf/compiler/cpp/helpers.h"
#include <google/protobuf/compiler/cpp/primitive_field.h> #include "google/protobuf/compiler/cpp/primitive_field.h"
#include <google/protobuf/compiler/cpp/string_field.h> #include "google/protobuf/compiler/cpp/string_field.h"
#include <google/protobuf/stubs/logging.h> #include "google/protobuf/stubs/logging.h"
#include <google/protobuf/stubs/common.h> #include "google/protobuf/stubs/common.h"
#include <google/protobuf/io/printer.h> #include "google/protobuf/io/printer.h"
#include <google/protobuf/wire_format.h> #include "google/protobuf/wire_format.h"
#include <google/protobuf/stubs/strutil.h> #include "google/protobuf/stubs/strutil.h"
#include <google/protobuf/compiler/cpp/enum_field.h> #include "google/protobuf/compiler/cpp/enum_field.h"
#include <google/protobuf/compiler/cpp/map_field.h> #include "google/protobuf/compiler/cpp/map_field.h"
#include <google/protobuf/compiler/cpp/message_field.h> #include "google/protobuf/compiler/cpp/message_field.h"
#include <google/protobuf/descriptor.pb.h> #include "google/protobuf/descriptor.pb.h"
namespace google { namespace google {
namespace protobuf { namespace protobuf {
@ -155,7 +155,6 @@ void AddAccessorAnnotations(const FieldDescriptor* descriptor,
std::string field_member = (*variables)["field"]; std::string field_member = (*variables)["field"];
const google::protobuf::OneofDescriptor* oneof_member = const google::protobuf::OneofDescriptor* oneof_member =
descriptor->real_containing_oneof(); descriptor->real_containing_oneof();
const std::string proto_ns = (*variables)["proto_ns"];
const std::string substitute_template_prefix = const std::string substitute_template_prefix =
absl::StrCat(" ", (*variables)["tracker"], ".$1<$0>(this, "); absl::StrCat(" ", (*variables)["tracker"], ".$1<$0>(this, ");
std::string prepared_template; std::string prepared_template;
@ -183,7 +182,7 @@ void AddAccessorAnnotations(const FieldDescriptor* descriptor,
} else if (descriptor->cpp_type() == FieldDescriptor::CPPTYPE_STRING) { } else if (descriptor->cpp_type() == FieldDescriptor::CPPTYPE_STRING) {
if (oneof_member) { if (oneof_member) {
prepared_template = GenerateTemplateForOneofString( prepared_template = GenerateTemplateForOneofString(
descriptor, (*variables)["proto_ns"], field_member); descriptor, ProtobufNamespace(options), field_member);
} else { } else {
prepared_template = prepared_template =
GenerateTemplateForSingleString(descriptor, field_member); GenerateTemplateForSingleString(descriptor, field_member);
@ -237,7 +236,6 @@ void AddAccessorAnnotations(const FieldDescriptor* descriptor,
void SetCommonFieldVariables(const FieldDescriptor* descriptor, void SetCommonFieldVariables(const FieldDescriptor* descriptor,
std::map<std::string, std::string>* variables, std::map<std::string, std::string>* variables,
const Options& options) { const Options& options) {
SetCommonVars(options, variables);
SetCommonMessageDataVariables(descriptor->containing_type(), variables); SetCommonMessageDataVariables(descriptor->containing_type(), variables);
(*variables)["ns"] = Namespace(descriptor, options); (*variables)["ns"] = Namespace(descriptor, options);

@ -40,9 +40,9 @@
#include <memory> #include <memory>
#include <string> #include <string>
#include <google/protobuf/descriptor.h> #include "google/protobuf/descriptor.h"
#include <google/protobuf/compiler/cpp/helpers.h> #include "google/protobuf/compiler/cpp/helpers.h"
#include <google/protobuf/compiler/cpp/options.h> #include "google/protobuf/compiler/cpp/options.h"
namespace google { namespace google {
namespace protobuf { namespace protobuf {

@ -32,7 +32,7 @@
// Based on original Protocol Buffers design by // Based on original Protocol Buffers design by
// Sanjay Ghemawat, Jeff Dean, and others. // Sanjay Ghemawat, Jeff Dean, and others.
#include <google/protobuf/compiler/cpp/file.h> #include "google/protobuf/compiler/cpp/file.h"
#include <iostream> #include <iostream>
#include <map> #include <map>
@ -42,20 +42,20 @@
#include <unordered_set> #include <unordered_set>
#include <vector> #include <vector>
#include <google/protobuf/compiler/scc.h> #include "google/protobuf/compiler/scc.h"
#include "absl/strings/escaping.h" #include "absl/strings/escaping.h"
#include "absl/strings/str_cat.h" #include "absl/strings/str_cat.h"
#include "absl/strings/str_replace.h" #include "absl/strings/str_replace.h"
#include <google/protobuf/compiler/cpp/enum.h> #include "google/protobuf/compiler/cpp/enum.h"
#include <google/protobuf/compiler/cpp/extension.h> #include "google/protobuf/compiler/cpp/extension.h"
#include <google/protobuf/compiler/cpp/helpers.h> #include "google/protobuf/compiler/cpp/helpers.h"
#include <google/protobuf/compiler/cpp/message.h> #include "google/protobuf/compiler/cpp/message.h"
#include <google/protobuf/compiler/cpp/service.h> #include "google/protobuf/compiler/cpp/service.h"
#include <google/protobuf/descriptor.h> #include "google/protobuf/descriptor.h"
#include <google/protobuf/descriptor.pb.h> #include "google/protobuf/descriptor.pb.h"
// Must be last. // Must be last.
#include <google/protobuf/port_def.inc> #include "google/protobuf/port_def.inc"
namespace google { namespace google {
namespace protobuf { namespace protobuf {
@ -110,7 +110,6 @@ inline void UnmuteWuninitialized(Formatter& format) {
FileGenerator::FileGenerator(const FileDescriptor* file, const Options& options) FileGenerator::FileGenerator(const FileDescriptor* file, const Options& options)
: file_(file), options_(options), scc_analyzer_(options) { : file_(file), options_(options), scc_analyzer_(options) {
// These variables are the same on a file level // These variables are the same on a file level
SetCommonVars(options, &variables_);
variables_["dllexport_decl"] = options.dllexport_decl; variables_["dllexport_decl"] = options.dllexport_decl;
variables_["tablename"] = UniqueName("TableStruct", file_, options_); variables_["tablename"] = UniqueName("TableStruct", file_, options_);
variables_["file_level_metadata"] = variables_["file_level_metadata"] =
@ -258,7 +257,8 @@ void FileGenerator::GenerateProtoHeader(io::Printer* printer,
return; return;
} }
GenerateTopHeaderGuard(printer, false); GenerateTopHeaderGuard(printer,
google::protobuf::compiler::cpp::GeneratedFileType::kProtoH);
if (!options_.opensource_runtime) { if (!options_.opensource_runtime) {
format( format(
@ -286,13 +286,15 @@ void FileGenerator::GenerateProtoHeader(io::Printer* printer,
GenerateHeader(printer); GenerateHeader(printer);
GenerateBottomHeaderGuard(printer, false); GenerateBottomHeaderGuard(printer,
google::protobuf::compiler::cpp::GeneratedFileType::kProtoH);
} }
void FileGenerator::GeneratePBHeader(io::Printer* printer, void FileGenerator::GeneratePBHeader(io::Printer* printer,
const std::string& info_path) { const std::string& info_path) {
Formatter format(printer, variables_); Formatter format(printer, variables_);
GenerateTopHeaderGuard(printer, true); GenerateTopHeaderGuard(printer,
google::protobuf::compiler::cpp::GeneratedFileType::kPbH);
if (options_.proto_h) { if (options_.proto_h) {
std::string target_basename = StripProto(file_->name()); std::string target_basename = StripProto(file_->name());
@ -331,7 +333,8 @@ void FileGenerator::GeneratePBHeader(io::Printer* printer,
"\n"); "\n");
} }
GenerateBottomHeaderGuard(printer, true); GenerateBottomHeaderGuard(printer,
google::protobuf::compiler::cpp::GeneratedFileType::kPbH);
} }
void FileGenerator::DoIncludeFile(const std::string& google3_name, void FileGenerator::DoIncludeFile(const std::string& google3_name,
@ -347,7 +350,7 @@ void FileGenerator::DoIncludeFile(const std::string& google3_name,
path = StringReplace(path, "proto/", "", false); path = StringReplace(path, "proto/", "", false);
path = StringReplace(path, "public/", "", false); path = StringReplace(path, "public/", "", false);
if (options_.runtime_include_base.empty()) { if (options_.runtime_include_base.empty()) {
format("#include <google/protobuf/$1$>", path); format("#include \"google/protobuf/$1$\"", path);
} else { } else {
format("#include \"$1$google/protobuf/$2$\"", format("#include \"$1$google/protobuf/$2$\"",
options_.runtime_include_base, path); options_.runtime_include_base, path);
@ -1084,7 +1087,8 @@ void FileGenerator::GenerateForwardDeclarations(io::Printer* printer) {
format("PROTOBUF_NAMESPACE_CLOSE\n"); format("PROTOBUF_NAMESPACE_CLOSE\n");
} }
void FileGenerator::GenerateTopHeaderGuard(io::Printer* printer, bool pb_h) { void FileGenerator::GenerateTopHeaderGuard(
io::Printer* printer, google::protobuf::compiler::cpp::GeneratedFileType file_type) {
Formatter format(printer, variables_); Formatter format(printer, variables_);
// Generate top of header. // Generate top of header.
format( format(
@ -1096,7 +1100,7 @@ void FileGenerator::GenerateTopHeaderGuard(io::Printer* printer, bool pb_h) {
"\n" "\n"
"#include <limits>\n" "#include <limits>\n"
"#include <string>\n", "#include <string>\n",
IncludeGuard(file_, pb_h, options_)); IncludeGuard(file_, file_type, options_));
if (!options_.opensource_runtime && !enum_generators_.empty()) { if (!options_.opensource_runtime && !enum_generators_.empty()) {
// Add header to provide std::is_integral for safe Enum_Name() function. // Add header to provide std::is_integral for safe Enum_Name() function.
format("#include <type_traits>\n"); format("#include <type_traits>\n");
@ -1104,10 +1108,11 @@ void FileGenerator::GenerateTopHeaderGuard(io::Printer* printer, bool pb_h) {
format("\n"); format("\n");
} }
void FileGenerator::GenerateBottomHeaderGuard(io::Printer* printer, bool pb_h) { void FileGenerator::GenerateBottomHeaderGuard(
io::Printer* printer, google::protobuf::compiler::cpp::GeneratedFileType file_type) {
Formatter format(printer, variables_); Formatter format(printer, variables_);
format("#endif // $GOOGLE_PROTOBUF$_INCLUDED_$1$\n", format("#endif // $GOOGLE_PROTOBUF$_INCLUDED_$1$\n",
IncludeGuard(file_, pb_h, options_)); IncludeGuard(file_, file_type, options_));
} }
void FileGenerator::GenerateLibraryIncludes(io::Printer* printer) { void FileGenerator::GenerateLibraryIncludes(io::Printer* printer) {

@ -41,11 +41,12 @@
#include <string> #include <string>
#include <vector> #include <vector>
#include <google/protobuf/stubs/common.h> #include "google/protobuf/stubs/common.h"
#include <google/protobuf/compiler/cpp/field.h> #include "google/protobuf/compiler/cpp/field.h"
#include <google/protobuf/compiler/cpp/helpers.h> #include "google/protobuf/compiler/cpp/helpers.h"
#include <google/protobuf/compiler/scc.h> #include "google/protobuf/port.h"
#include <google/protobuf/compiler/cpp/options.h> #include "google/protobuf/compiler/scc.h"
#include "google/protobuf/compiler/cpp/options.h"
namespace google { namespace google {
namespace protobuf { namespace protobuf {
@ -136,8 +137,10 @@ class FileGenerator {
void GenerateForwardDeclarations(io::Printer* printer); void GenerateForwardDeclarations(io::Printer* printer);
// Generates top or bottom of a header file. // Generates top or bottom of a header file.
void GenerateTopHeaderGuard(io::Printer* printer, bool pb_h); void GenerateTopHeaderGuard(
void GenerateBottomHeaderGuard(io::Printer* printer, bool pb_h); io::Printer* printer, google::protobuf::compiler::cpp::GeneratedFileType file_type);
void GenerateBottomHeaderGuard(
io::Printer* printer, google::protobuf::compiler::cpp::GeneratedFileType file_type);
// Generates #include directives. // Generates #include directives.
void GenerateLibraryIncludes(io::Printer* printer); void GenerateLibraryIncludes(io::Printer* printer);

@ -32,41 +32,69 @@
// Based on original Protocol Buffers design by // Based on original Protocol Buffers design by
// Sanjay Ghemawat, Jeff Dean, and others. // Sanjay Ghemawat, Jeff Dean, and others.
#include <google/protobuf/compiler/cpp/generator.h> #include "google/protobuf/compiler/cpp/generator.h"
#include <memory> #include <memory>
#include <string> #include <string>
#include <utility> #include <utility>
#include <vector> #include <vector>
#include <google/protobuf/stubs/strutil.h> #include "google/protobuf/stubs/strutil.h"
#include <google/protobuf/io/printer.h> #include "google/protobuf/io/printer.h"
#include <google/protobuf/io/zero_copy_stream.h> #include "google/protobuf/io/zero_copy_stream.h"
#include "absl/strings/str_cat.h" #include "absl/strings/str_cat.h"
#include "absl/strings/str_replace.h" #include "absl/strings/str_replace.h"
#include <google/protobuf/compiler/cpp/file.h> #include "google/protobuf/compiler/cpp/file.h"
#include <google/protobuf/compiler/cpp/helpers.h> #include "google/protobuf/compiler/cpp/helpers.h"
#include <google/protobuf/descriptor.pb.h> #include "google/protobuf/descriptor.pb.h"
namespace google { namespace google {
namespace protobuf { namespace protobuf {
namespace compiler { namespace compiler {
namespace cpp { namespace cpp {
CppGenerator::CppGenerator() {}
CppGenerator::~CppGenerator() {}
namespace { namespace {
std::string NumberedCcFileName(const std::string& basename, int number) { std::string NumberedCcFileName(absl::string_view basename, int number) {
return absl::StrCat(basename, ".out/", number, ".cc"); return absl::StrCat(basename, ".out/", number, ".cc");
} }
absl::flat_hash_map<std::string, std::string> CommonVars(
const Options& options) {
bool is_oss = options.opensource_runtime;
return {
{"proto_ns", ProtobufNamespace(options)},
{"string", "std::string"},
{"int8", "int8_t"},
{"int32", "int32_t"},
{"int64", "int64_t"},
{"uint8", "uint8_t"},
{"uint32", "uint32_t"},
{"uint64", "uint64_t"},
// Warning: there is some clever naming/splitting here to avoid extract
// script rewrites. The names of these variables must not be things that
// the extract script will rewrite. That's why we use "CHK" (for example)
// instead of "GOOGLE_CHECK".
//
// These values are things the extract script would rewrite if we did not
// split them. It might not strictly matter since we don't generate
// google3 code in open-source. But it's good to prevent surprising
// things from happening.
{"GOOGLE_PROTOBUF", is_oss ? "GOOGLE_PROTOBUF"
: "GOOGLE3_PROTOBU"
"F"},
{"CHK", is_oss ? "GOOGLE_CHECK"
: "CHECK"},
{"DCHK", is_oss ? "GOOGLE_DCHECK"
: "DCHECK"},
};
}
} // namespace } // namespace
bool CppGenerator::Generate(const FileDescriptor* file, bool CppGenerator::Generate(const FileDescriptor* file,
const std::string& parameter, const std::string& parameter,
GeneratorContext* generator_context, GeneratorContext* generator_context,
std::string* error) const { std::string* error) const {
std::vector<std::pair<std::string, std::string> > options; std::vector<std::pair<std::string, std::string>> options;
ParseGeneratorParameter(parameter, &options); ParseGeneratorParameter(parameter, &options);
// ----------------------------------------------------------------- // -----------------------------------------------------------------
@ -95,68 +123,70 @@ bool CppGenerator::Generate(const FileDescriptor* file,
file_options.opensource_runtime = opensource_runtime_; file_options.opensource_runtime = opensource_runtime_;
file_options.runtime_include_base = runtime_include_base_; file_options.runtime_include_base = runtime_include_base_;
for (int i = 0; i < options.size(); i++) { for (const auto& option : options) {
if (options[i].first == "dllexport_decl") { const auto& key = option.first;
file_options.dllexport_decl = options[i].second; const auto& value = option.second;
} else if (options[i].first == "safe_boundary_check") {
if (key == "dllexport_decl") {
file_options.dllexport_decl = value;
} else if (key == "safe_boundary_check") {
file_options.safe_boundary_check = true; file_options.safe_boundary_check = true;
} else if (options[i].first == "annotate_headers") { } else if (key == "annotate_headers") {
file_options.annotate_headers = true; file_options.annotate_headers = true;
} else if (options[i].first == "annotation_pragma_name") { } else if (key == "annotation_pragma_name") {
file_options.annotation_pragma_name = options[i].second; file_options.annotation_pragma_name = value;
} else if (options[i].first == "annotation_guard_name") { } else if (key == "annotation_guard_name") {
file_options.annotation_guard_name = options[i].second; file_options.annotation_guard_name = value;
} else if (options[i].first == "speed") { } else if (key == "speed") {
file_options.enforce_mode = EnforceOptimizeMode::kSpeed; file_options.enforce_mode = EnforceOptimizeMode::kSpeed;
} else if (options[i].first == "code_size") { } else if (key == "code_size") {
file_options.enforce_mode = EnforceOptimizeMode::kCodeSize; file_options.enforce_mode = EnforceOptimizeMode::kCodeSize;
} else if (options[i].first == "lite") { } else if (key == "lite") {
file_options.enforce_mode = EnforceOptimizeMode::kLiteRuntime; file_options.enforce_mode = EnforceOptimizeMode::kLiteRuntime;
} else if (options[i].first == "lite_implicit_weak_fields") { } else if (key == "lite_implicit_weak_fields") {
file_options.enforce_mode = EnforceOptimizeMode::kLiteRuntime; file_options.enforce_mode = EnforceOptimizeMode::kLiteRuntime;
file_options.lite_implicit_weak_fields = true; file_options.lite_implicit_weak_fields = true;
if (!options[i].second.empty()) { if (!value.empty()) {
file_options.num_cc_files = file_options.num_cc_files = strto32(value.c_str(), nullptr, 10);
strto32(options[i].second.c_str(), nullptr, 10);
} }
} else if (options[i].first == "proto_h") { } else if (key == "proto_h") {
file_options.proto_h = true; file_options.proto_h = true;
} else if (options[i].first == "annotate_accessor") { } else if (key == "annotate_accessor") {
file_options.annotate_accessor = true; file_options.annotate_accessor = true;
} else if (options[i].first == "inject_field_listener_events") { } else if (key == "inject_field_listener_events") {
file_options.field_listener_options.inject_field_listener_events = true; file_options.field_listener_options.inject_field_listener_events = true;
} else if (options[i].first == "forbidden_field_listener_events") { } else if (key == "forbidden_field_listener_events") {
std::size_t pos = 0; std::size_t pos = 0;
do { do {
std::size_t next_pos = options[i].second.find_first_of("+", pos); std::size_t next_pos = value.find_first_of("+", pos);
if (next_pos == std::string::npos) { if (next_pos == std::string::npos) {
next_pos = options[i].second.size(); next_pos = value.size();
} }
if (next_pos > pos) if (next_pos > pos)
file_options.field_listener_options.forbidden_field_listener_events file_options.field_listener_options.forbidden_field_listener_events
.insert(options[i].second.substr(pos, next_pos - pos)); .insert(value.substr(pos, next_pos - pos));
pos = next_pos + 1; pos = next_pos + 1;
} while (pos < options[i].second.size()); } while (pos < value.size());
} else if (options[i].first == "unverified_lazy_message_sets") { } else if (key == "unverified_lazy_message_sets") {
file_options.unverified_lazy_message_sets = true; file_options.unverified_lazy_message_sets = true;
} else if (options[i].first == "message_owned_arena_trial") { } else if (key == "message_owned_arena_trial") {
file_options.message_owned_arena_trial = true; file_options.message_owned_arena_trial = true;
} else if (options[i].first == "force_eagerly_verified_lazy") { } else if (key == "force_eagerly_verified_lazy") {
file_options.force_eagerly_verified_lazy = true; file_options.force_eagerly_verified_lazy = true;
} else if (options[i].first == "experimental_tail_call_table_mode") { } else if (key == "experimental_tail_call_table_mode") {
if (options[i].second == "never") { if (value == "never") {
file_options.tctable_mode = Options::kTCTableNever; file_options.tctable_mode = Options::kTCTableNever;
} else if (options[i].second == "guarded") { } else if (value == "guarded") {
file_options.tctable_mode = Options::kTCTableGuarded; file_options.tctable_mode = Options::kTCTableGuarded;
} else if (options[i].second == "always") { } else if (value == "always") {
file_options.tctable_mode = Options::kTCTableAlways; file_options.tctable_mode = Options::kTCTableAlways;
} else { } else {
*error = "Unknown value for experimental_tail_call_table_mode: " + *error =
options[i].second; "Unknown value for experimental_tail_call_table_mode: " + value;
return false; return false;
} }
} else { } else {
*error = "Unknown generator option: " + options[i].first; *error = "Unknown generator option: " + key;
return false; return false;
} }
} }
@ -183,39 +213,51 @@ bool CppGenerator::Generate(const FileDescriptor* file,
// Generate header(s). // Generate header(s).
if (file_options.proto_h) { if (file_options.proto_h) {
std::unique_ptr<io::ZeroCopyOutputStream> output( auto output = absl::WrapUnique(
generator_context->Open(basename + ".proto.h")); generator_context->Open(absl::StrCat(basename, ".proto.h")));
GeneratedCodeInfo annotations; GeneratedCodeInfo annotations;
io::AnnotationProtoCollector<GeneratedCodeInfo> annotation_collector( io::AnnotationProtoCollector<GeneratedCodeInfo> annotation_collector(
&annotations); &annotations);
std::string info_path = basename + ".proto.h.meta"; io::Printer::Options options;
io::Printer printer( if (file_options.annotate_headers) {
output.get(), '$', options.annotation_collector = &annotation_collector;
file_options.annotate_headers ? &annotation_collector : nullptr); }
io::Printer p(output.get(), options);
auto v = p.WithVars(CommonVars(file_options));
std::string info_path = absl::StrCat(basename, ".proto.h.meta");
file_generator.GenerateProtoHeader( file_generator.GenerateProtoHeader(
&printer, file_options.annotate_headers ? info_path : ""); &p, file_options.annotate_headers ? info_path : "");
if (file_options.annotate_headers) { if (file_options.annotate_headers) {
std::unique_ptr<io::ZeroCopyOutputStream> info_output( auto info_output = absl::WrapUnique(generator_context->Open(info_path));
generator_context->Open(info_path));
annotations.SerializeToZeroCopyStream(info_output.get()); annotations.SerializeToZeroCopyStream(info_output.get());
} }
} }
{ {
std::unique_ptr<io::ZeroCopyOutputStream> output( auto output = absl::WrapUnique(
generator_context->Open(basename + ".pb.h")); generator_context->Open(absl::StrCat(basename, ".pb.h")));
GeneratedCodeInfo annotations; GeneratedCodeInfo annotations;
io::AnnotationProtoCollector<GeneratedCodeInfo> annotation_collector( io::AnnotationProtoCollector<GeneratedCodeInfo> annotation_collector(
&annotations); &annotations);
std::string info_path = basename + ".pb.h.meta"; io::Printer::Options options;
io::Printer printer( if (file_options.annotate_headers) {
output.get(), '$', options.annotation_collector = &annotation_collector;
file_options.annotate_headers ? &annotation_collector : nullptr); }
io::Printer p(output.get(), options);
auto v = p.WithVars(CommonVars(file_options));
std::string info_path = absl::StrCat(basename, ".pb.h.meta");
file_generator.GeneratePBHeader( file_generator.GeneratePBHeader(
&printer, file_options.annotate_headers ? info_path : ""); &p, file_options.annotate_headers ? info_path : "");
if (file_options.annotate_headers) { if (file_options.annotate_headers) {
std::unique_ptr<io::ZeroCopyOutputStream> info_output( auto info_output = absl::WrapUnique(generator_context->Open(info_path));
generator_context->Open(info_path));
annotations.SerializeToZeroCopyStream(info_output.get()); annotations.SerializeToZeroCopyStream(info_output.get());
} }
} }
@ -225,10 +267,12 @@ bool CppGenerator::Generate(const FileDescriptor* file,
{ {
// This is the global .cc file, containing // This is the global .cc file, containing
// enum/services/tables/reflection // enum/services/tables/reflection
std::unique_ptr<io::ZeroCopyOutputStream> output( auto output = absl::WrapUnique(
generator_context->Open(basename + ".pb.cc")); generator_context->Open(absl::StrCat(basename, ".pb.cc")));
io::Printer printer(output.get(), '$'); io::Printer p(output.get());
file_generator.GenerateGlobalSource(&printer); auto v = p.WithVars(CommonVars(file_options));
file_generator.GenerateGlobalSource(&p);
} }
int num_cc_files = int num_cc_files =
@ -244,35 +288,43 @@ bool CppGenerator::Generate(const FileDescriptor* file,
"and extensions."; "and extensions.";
num_cc_files = file_options.num_cc_files; num_cc_files = file_options.num_cc_files;
} }
int cc_file_number = 0; int cc_file_number = 0;
for (int i = 0; i < file_generator.NumMessages(); i++) { for (int i = 0; i < file_generator.NumMessages(); ++i) {
std::unique_ptr<io::ZeroCopyOutputStream> output(generator_context->Open( auto output = absl::WrapUnique(generator_context->Open(
NumberedCcFileName(basename, cc_file_number++))); NumberedCcFileName(basename, cc_file_number++)));
io::Printer printer(output.get(), '$'); io::Printer p(output.get());
file_generator.GenerateSourceForMessage(i, &printer); auto v = p.WithVars(CommonVars(file_options));
file_generator.GenerateSourceForMessage(i, &p);
} }
for (int i = 0; i < file_generator.NumExtensions(); i++) {
std::unique_ptr<io::ZeroCopyOutputStream> output(generator_context->Open( for (int i = 0; i < file_generator.NumExtensions(); ++i) {
auto output = absl::WrapUnique(generator_context->Open(
NumberedCcFileName(basename, cc_file_number++))); NumberedCcFileName(basename, cc_file_number++)));
io::Printer printer(output.get(), '$'); io::Printer p(output.get());
file_generator.GenerateSourceForExtension(i, &printer); auto v = p.WithVars(CommonVars(file_options));
file_generator.GenerateSourceForExtension(i, &p);
} }
// Create empty placeholder files if necessary to match the expected number // Create empty placeholder files if necessary to match the expected number
// of files. // of files.
for (; cc_file_number < num_cc_files; ++cc_file_number) { while (cc_file_number < num_cc_files) {
std::unique_ptr<io::ZeroCopyOutputStream> output(generator_context->Open( (void)absl::WrapUnique(generator_context->Open(
NumberedCcFileName(basename, cc_file_number))); NumberedCcFileName(basename, cc_file_number++)));
} }
} else { } else {
std::unique_ptr<io::ZeroCopyOutputStream> output( auto output = absl::WrapUnique(
generator_context->Open(basename + ".pb.cc")); generator_context->Open(absl::StrCat(basename, ".pb.cc")));
io::Printer printer(output.get(), '$'); io::Printer p(output.get());
file_generator.GenerateSource(&printer); auto v = p.WithVars(CommonVars(file_options));
file_generator.GenerateSource(&p);
} }
return true; return true;
} }
} // namespace cpp } // namespace cpp
} // namespace compiler } // namespace compiler
} // namespace protobuf } // namespace protobuf

@ -38,26 +38,27 @@
#define GOOGLE_PROTOBUF_COMPILER_CPP_GENERATOR_H__ #define GOOGLE_PROTOBUF_COMPILER_CPP_GENERATOR_H__
#include <string> #include <string>
#include <google/protobuf/compiler/code_generator.h> #include <utility>
#include "google/protobuf/compiler/code_generator.h"
// Must be included last. // Must be included last.
#include <google/protobuf/port_def.inc> #include "google/protobuf/port_def.inc"
namespace google { namespace google {
namespace protobuf { namespace protobuf {
namespace compiler { namespace compiler {
namespace cpp { namespace cpp {
// CodeGenerator implementation which generates a C++ source file and // CodeGenerator implementation which generates a C++ source file and
// header. If you create your own protocol compiler binary and you want // header. If you create your own protocol compiler binary and you want
// it to support C++ output, you can do so by registering an instance of this // it to support C++ output, you can do so by registering an instance of this
// CodeGenerator with the CommandLineInterface in your main() function. // CodeGenerator with the CommandLineInterface in your main() function.
class PROTOC_EXPORT CppGenerator : public CodeGenerator { class PROTOC_EXPORT CppGenerator : public CodeGenerator {
public: public:
CppGenerator(); CppGenerator() = default;
CppGenerator(const CppGenerator&) = delete; CppGenerator(const CppGenerator&) = delete;
CppGenerator& operator=(const CppGenerator&) = delete; CppGenerator& operator=(const CppGenerator&) = delete;
~CppGenerator() override; ~CppGenerator() override = default;
enum class Runtime { enum class Runtime {
kGoogle3, // Use the internal google3 runtime. kGoogle3, // Use the internal google3 runtime.
@ -76,33 +77,29 @@ class PROTOC_EXPORT CppGenerator : public CodeGenerator {
// If set to a non-empty string, generated code will do: // If set to a non-empty string, generated code will do:
// #include "<BASE>/google/protobuf/message.h" // #include "<BASE>/google/protobuf/message.h"
// instead of: // instead of:
// #include <google/protobuf/message.h> // #include "google/protobuf/message.h"
// This has no effect if opensource_runtime = false. // This has no effect if opensource_runtime = false.
void set_runtime_include_base(const std::string& base) { void set_runtime_include_base(std::string base) {
runtime_include_base_ = base; runtime_include_base_ = std::move(base);
} }
// implements CodeGenerator ----------------------------------------
bool Generate(const FileDescriptor* file, const std::string& parameter, bool Generate(const FileDescriptor* file, const std::string& parameter,
GeneratorContext* generator_context, GeneratorContext* generator_context,
std::string* error) const override; std::string* error) const override;
uint64_t GetSupportedFeatures() const override { uint64_t GetSupportedFeatures() const override {
// We don't fully support this yet, but this is needed to unblock the tests,
// and we will have full support before the experimental flag is removed.
return FEATURE_PROTO3_OPTIONAL; return FEATURE_PROTO3_OPTIONAL;
} }
private: private:
bool opensource_runtime_ = true; bool opensource_runtime_ = PROTO2_IS_OSS;
std::string runtime_include_base_; std::string runtime_include_base_;
}; };
} // namespace cpp } // namespace cpp
} // namespace compiler } // namespace compiler
} // namespace protobuf } // namespace protobuf
} // namespace google } // namespace google
#include <google/protobuf/port_undef.inc> #include "google/protobuf/port_undef.inc"
#endif // GOOGLE_PROTOBUF_COMPILER_CPP_GENERATOR_H__ #endif // GOOGLE_PROTOBUF_COMPILER_CPP_GENERATOR_H__

@ -32,7 +32,7 @@
// Based on original Protocol Buffers design by // Based on original Protocol Buffers design by
// Sanjay Ghemawat, Jeff Dean, and others. // Sanjay Ghemawat, Jeff Dean, and others.
#include <google/protobuf/compiler/cpp/helpers.h> #include "google/protobuf/compiler/cpp/helpers.h"
#include <algorithm> #include <algorithm>
#include <cstdint> #include <cstdint>
@ -41,18 +41,20 @@
#include <map> #include <map>
#include <memory> #include <memory>
#include <queue> #include <queue>
#include <set>
#include <string>
#include <vector> #include <vector>
#include <google/protobuf/stubs/common.h> #include "google/protobuf/stubs/common.h"
#include <google/protobuf/stubs/logging.h> #include "google/protobuf/stubs/logging.h"
#include <google/protobuf/compiler/scc.h> #include "google/protobuf/compiler/scc.h"
#include <google/protobuf/io/printer.h> #include "google/protobuf/io/printer.h"
#include <google/protobuf/io/zero_copy_stream.h> #include "google/protobuf/io/zero_copy_stream.h"
#include <google/protobuf/descriptor.h> #include "google/protobuf/descriptor.h"
#include <google/protobuf/dynamic_message.h> #include "google/protobuf/dynamic_message.h"
#include <google/protobuf/wire_format.h> #include "google/protobuf/wire_format.h"
#include <google/protobuf/wire_format_lite.h> #include "google/protobuf/wire_format_lite.h"
#include <google/protobuf/stubs/strutil.h> #include "google/protobuf/stubs/strutil.h"
#include "absl/container/flat_hash_map.h" #include "absl/container/flat_hash_map.h"
#include "absl/container/flat_hash_set.h" #include "absl/container/flat_hash_set.h"
#include "absl/strings/ascii.h" #include "absl/strings/ascii.h"
@ -62,13 +64,13 @@
#include "absl/strings/string_view.h" #include "absl/strings/string_view.h"
#include "absl/strings/substitute.h" #include "absl/strings/substitute.h"
#include "absl/synchronization/mutex.h" #include "absl/synchronization/mutex.h"
#include <google/protobuf/compiler/cpp/names.h> #include "google/protobuf/compiler/cpp/names.h"
#include <google/protobuf/compiler/cpp/options.h> #include "google/protobuf/compiler/cpp/options.h"
#include <google/protobuf/descriptor.pb.h> #include "google/protobuf/descriptor.pb.h"
// Must be last. // Must be last.
#include <google/protobuf/port_def.inc> #include "google/protobuf/port_def.inc"
namespace google { namespace google {
namespace protobuf { namespace protobuf {
@ -80,8 +82,8 @@ namespace {
static const char kAnyMessageName[] = "Any"; static const char kAnyMessageName[] = "Any";
static const char kAnyProtoFile[] = "google/protobuf/any.proto"; static const char kAnyProtoFile[] = "google/protobuf/any.proto";
std::string DotsToColons(const std::string& name) { std::string DotsToColons(absl::string_view name) {
return StringReplace(name, ".", "::", true); return absl::StrReplaceAll(name, {{".", "::"}});
} }
static const char* const kKeywordList[] = { static const char* const kKeywordList[] = {
@ -199,17 +201,13 @@ std::string IntTypeName(const Options& options, const std::string& type) {
return type + "_t"; return type + "_t";
} }
void SetIntVar(const Options& options, const std::string& type,
std::map<std::string, std::string>* variables) {
(*variables)[type] = IntTypeName(options, type);
}
// Returns true if the message can potentially allocate memory for its field. // Returns true if the message can potentially allocate memory for its field.
// This is used to determine if message-owned arena will be useful. // This is used to determine if message-owned arena will be useful.
bool AllocExpected(const Descriptor* descriptor) { bool AllocExpected(const Descriptor* descriptor) {
return false; return false;
} }
} // namespace } // namespace
bool IsLazy(const FieldDescriptor* field, const Options& options, bool IsLazy(const FieldDescriptor* field, const Options& options,
@ -236,43 +234,6 @@ bool IsLazilyVerifiedLazy(const FieldDescriptor* field,
return false; return false;
} }
void SetCommonVars(const Options& options,
std::map<std::string, std::string>* variables) {
(*variables)["proto_ns"] = ProtobufNamespace(options);
// Warning: there is some clever naming/splitting here to avoid extract script
// rewrites. The names of these variables must not be things that the extract
// script will rewrite. That's why we use "CHK" (for example) instead of
// "GOOGLE_CHECK".
if (options.opensource_runtime) {
(*variables)["GOOGLE_PROTOBUF"] = "GOOGLE_PROTOBUF";
(*variables)["CHK"] = "GOOGLE_CHECK";
(*variables)["DCHK"] = "GOOGLE_DCHECK";
} else {
// These values are things the extract script would rewrite if we did not
// split them. It might not strictly matter since we don't generate google3
// code in open-source. But it's good to prevent surprising things from
// happening.
(*variables)["GOOGLE_PROTOBUF"] =
"GOOGLE3"
"_PROTOBUF";
(*variables)["CHK"] =
"CH"
"ECK";
(*variables)["DCHK"] =
"DCH"
"ECK";
}
SetIntVar(options, "int8", variables);
SetIntVar(options, "uint8", variables);
SetIntVar(options, "uint32", variables);
SetIntVar(options, "uint64", variables);
SetIntVar(options, "int32", variables);
SetIntVar(options, "int64", variables);
(*variables)["string"] = "std::string";
}
void SetCommonMessageDataVariables( void SetCommonMessageDataVariables(
const Descriptor* descriptor, const Descriptor* descriptor,
std::map<std::string, std::string>* variables) { std::map<std::string, std::string>* variables) {
@ -840,8 +801,8 @@ std::string QualifiedFileLevelSymbol(const FileDescriptor* file,
} }
// Escape C++ trigraphs by escaping question marks to \? // Escape C++ trigraphs by escaping question marks to \?
std::string EscapeTrigraphs(const std::string& to_escape) { std::string EscapeTrigraphs(absl::string_view to_escape) {
return StringReplace(to_escape, "?", "\\?", true); return absl::StrReplaceAll(to_escape, {{"?", "\\?"}});
} }
// Escaped function name to eliminate naming conflict. // Escaped function name to eliminate naming conflict.
@ -1375,70 +1336,64 @@ bool MaybeBootstrap(const Options& options, GeneratorContext* generator_context,
// Adjust basename, but don't abort code generation. // Adjust basename, but don't abort code generation.
*basename = bootstrap_basename; *basename = bootstrap_basename;
return false; return false;
} else {
const std::string& forward_to_basename = bootstrap_basename;
// Generate forwarding headers and empty .pb.cc.
{
std::unique_ptr<io::ZeroCopyOutputStream> output(
generator_context->Open(*basename + ".pb.h"));
io::Printer printer(output.get(), '$', nullptr);
printer.Print(
"#ifndef PROTOBUF_INCLUDED_$filename_identifier$_FORWARD_PB_H\n"
"#define PROTOBUF_INCLUDED_$filename_identifier$_FORWARD_PB_H\n"
"#include \"$forward_to_basename$.pb.h\" // IWYU pragma: export\n"
"#endif // PROTOBUF_INCLUDED_$filename_identifier$_FORWARD_PB_H\n",
"forward_to_basename", forward_to_basename, "filename_identifier",
FilenameIdentifier(*basename));
if (!options.opensource_runtime) {
// HACK HACK HACK, tech debt from the deeps of proto1 and SWIG
// protocoltype is SWIG'ed and we need to forward
if (*basename == "net/proto/protocoltype") {
printer.Print(
"#ifdef SWIG\n"
"%include \"$forward_to_basename$.pb.h\"\n"
"#endif // SWIG\n",
"forward_to_basename", forward_to_basename);
}
}
}
{
std::unique_ptr<io::ZeroCopyOutputStream> output(
generator_context->Open(*basename + ".proto.h"));
io::Printer printer(output.get(), '$', nullptr);
printer.Print(
"#ifndef PROTOBUF_INCLUDED_$filename_identifier$_FORWARD_PROTO_H\n"
"#define PROTOBUF_INCLUDED_$filename_identifier$_FORWARD_PROTO_H\n"
"#include \"$forward_to_basename$.proto.h\" // IWYU pragma: "
"export\n"
"#endif // "
"PROTOBUF_INCLUDED_$filename_identifier$_FORWARD_PROTO_H\n",
"forward_to_basename", forward_to_basename, "filename_identifier",
FilenameIdentifier(*basename));
} }
{ auto pb_h = absl::WrapUnique(
std::unique_ptr<io::ZeroCopyOutputStream> output( generator_context->Open(absl::StrCat(*basename, ".pb.h")));
generator_context->Open(*basename + ".pb.cc"));
io::Printer printer(output.get(), '$', nullptr);
printer.Print("\n");
}
io::Printer p(pb_h.get());
p.Emit(
{ {
std::unique_ptr<io::ZeroCopyOutputStream> output( {"fwd_to", bootstrap_basename},
generator_context->Open(*basename + ".pb.h.meta")); {"file", FilenameIdentifier(*basename)},
} {"fwd_to_suffix", options.opensource_runtime ? "pb" : "proto"},
{"swig_evil",
[&] {
if (options.opensource_runtime) {
return;
}
p.Emit(R"(
#ifdef SWIG
%include "$fwd_to$.pb.h"
#endif // SWIG
)");
}},
},
R"(
#ifndef PROTOBUF_INCLUDED_$file$_FORWARD_PB_H
#define PROTOBUF_INCLUDED_$file$_FORWARD_PB_H
#include "$fwd_to$.$fwd_to_suffix$.h" // IWYU pragma: export
#endif // PROTOBUF_INCLUDED_$file$_FORWARD_PB_H
$swig_evil$;
)");
auto proto_h = absl::WrapUnique(
generator_context->Open(absl::StrCat(*basename, ".proto.h")));
io::Printer(proto_h.get())
.Emit(
{ {
std::unique_ptr<io::ZeroCopyOutputStream> output( {"fwd_to", bootstrap_basename},
generator_context->Open(*basename + ".proto.h.meta")); {"file", FilenameIdentifier(*basename)},
} },
R"(
#ifndef PROTOBUF_INCLUDED_$file$_FORWARD_PROTO_H
#define PROTOBUF_INCLUDED_$file$_FORWARD_PROTO_H
#include "$fwd_to$.proto.h" // IWYU pragma: export
#endif // PROTOBUF_INCLUDED_$file$_FORWARD_PROTO_H
)");
auto pb_cc = absl::WrapUnique(
generator_context->Open(absl::StrCat(*basename, ".pb.cc")));
io::Printer(pb_cc.get()).PrintRaw("\n");
(void)absl::WrapUnique(
generator_context->Open(absl::StrCat(*basename, ".pb.h.meta")));
(void)absl::WrapUnique(
generator_context->Open(absl::StrCat(*basename, ".proto.h.meta")));
// Abort code generation. // Abort code generation.
return true; return true;
}
} }
static bool HasExtensionFromFile(const Message& msg, const FileDescriptor* file, static bool HasExtensionFromFile(const Message& msg, const FileDescriptor* file,

@ -41,20 +41,21 @@
#include <map> #include <map>
#include <string> #include <string>
#include <google/protobuf/compiler/scc.h> #include "google/protobuf/compiler/scc.h"
#include <google/protobuf/compiler/code_generator.h> #include "google/protobuf/compiler/code_generator.h"
#include "absl/container/flat_hash_map.h"
#include "google/protobuf/stubs/strutil.h"
#include "absl/strings/str_split.h" #include "absl/strings/str_split.h"
#include <google/protobuf/compiler/cpp/names.h> #include "google/protobuf/compiler/cpp/names.h"
#include <google/protobuf/compiler/cpp/options.h> #include "google/protobuf/compiler/cpp/options.h"
#include <google/protobuf/descriptor.pb.h> #include "google/protobuf/descriptor.pb.h"
#include <google/protobuf/io/printer.h> #include "google/protobuf/io/printer.h"
#include <google/protobuf/descriptor.h> #include "google/protobuf/descriptor.h"
#include <google/protobuf/port.h> #include "google/protobuf/port.h"
#include <google/protobuf/stubs/strutil.h>
#include "absl/strings/str_cat.h" #include "absl/strings/str_cat.h"
// Must be included last. // Must be included last.
#include <google/protobuf/port_def.inc> #include "google/protobuf/port_def.inc"
namespace google { namespace google {
namespace protobuf { namespace protobuf {
@ -86,9 +87,6 @@ inline std::string DeprecatedAttribute(const Options& /* options */,
extern const char kThickSeparator[]; extern const char kThickSeparator[];
extern const char kThinSeparator[]; extern const char kThinSeparator[];
void SetCommonVars(const Options& options,
std::map<std::string, std::string>* variables);
// Variables to access message data from the message scope. // Variables to access message data from the message scope.
void SetCommonMessageDataVariables( void SetCommonMessageDataVariables(
const Descriptor* descriptor, const Descriptor* descriptor,
@ -298,7 +296,7 @@ std::string QualifiedFileLevelSymbol(const FileDescriptor* file,
const Options& options); const Options& options);
// Escape C++ trigraphs by escaping question marks to \? // Escape C++ trigraphs by escaping question marks to \?
std::string EscapeTrigraphs(const std::string& to_escape); std::string EscapeTrigraphs(absl::string_view to_escape);
// Escaped function name to eliminate naming conflict. // Escaped function name to eliminate naming conflict.
std::string SafeFunctionName(const Descriptor* descriptor, std::string SafeFunctionName(const Descriptor* descriptor,
@ -518,12 +516,26 @@ bool IsAnyMessage(const Descriptor* descriptor, const Options& options);
bool IsWellKnownMessage(const FileDescriptor* descriptor); bool IsWellKnownMessage(const FileDescriptor* descriptor);
inline std::string IncludeGuard(const FileDescriptor* file, bool pb_h, enum class GeneratedFileType : int { kPbH, kProtoH, kProtoStaticReflectionH };
inline std::string IncludeGuard(const FileDescriptor* file,
GeneratedFileType file_type,
const Options& options) { const Options& options) {
// If we are generating a .pb.h file and the proto_h option is enabled, then // If we are generating a .pb.h file and the proto_h option is enabled, then
// the .pb.h gets an extra suffix. // the .pb.h gets an extra suffix.
std::string filename_identifier = FilenameIdentifier( std::string extension;
file->name() + (pb_h && options.proto_h ? ".pb.h" : "")); switch (file_type) {
case GeneratedFileType::kPbH:
extension = ".pb.h";
break;
case GeneratedFileType::kProtoH:
extension = ".proto.h";
break;
case GeneratedFileType::kProtoStaticReflectionH:
extension = ".proto.static_reflection.h";
}
std::string filename_identifier =
FilenameIdentifier(file->name() + extension);
if (IsWellKnownMessage(file)) { if (IsWellKnownMessage(file)) {
// For well-known messages we need third_party/protobuf and net/proto2 to // For well-known messages we need third_party/protobuf and net/proto2 to
@ -1000,6 +1012,6 @@ bool HasMessageFieldOrExtension(const Descriptor* desc);
} // namespace protobuf } // namespace protobuf
} // namespace google } // namespace google
#include <google/protobuf/port_undef.inc> #include "google/protobuf/port_undef.inc"
#endif // GOOGLE_PROTOBUF_COMPILER_CPP_HELPERS_H__ #endif // GOOGLE_PROTOBUF_COMPILER_CPP_HELPERS_H__

@ -28,13 +28,13 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <google/protobuf/compiler/cpp/map_field.h> #include "google/protobuf/compiler/cpp/map_field.h"
#include <google/protobuf/io/printer.h> #include "google/protobuf/io/printer.h"
#include <google/protobuf/wire_format.h> #include "google/protobuf/wire_format.h"
#include <google/protobuf/stubs/strutil.h> #include "google/protobuf/stubs/strutil.h"
#include "absl/strings/ascii.h" #include "absl/strings/ascii.h"
#include <google/protobuf/compiler/cpp/helpers.h> #include "google/protobuf/compiler/cpp/helpers.h"
namespace google { namespace google {

@ -34,8 +34,8 @@
#include <map> #include <map>
#include <string> #include <string>
#include <google/protobuf/compiler/cpp/helpers.h> #include "google/protobuf/compiler/cpp/helpers.h"
#include <google/protobuf/compiler/cpp/message_field.h> #include "google/protobuf/compiler/cpp/message_field.h"
namespace google { namespace google {
namespace protobuf { namespace protobuf {

@ -32,7 +32,7 @@
// Based on original Protocol Buffers design by // Based on original Protocol Buffers design by
// Sanjay Ghemawat, Jeff Dean, and others. // Sanjay Ghemawat, Jeff Dean, and others.
#include <google/protobuf/compiler/cpp/message.h> #include "google/protobuf/compiler/cpp/message.h"
#include <algorithm> #include <algorithm>
#include <cstdint> #include <cstdint>
@ -45,31 +45,31 @@
#include <utility> #include <utility>
#include <vector> #include <vector>
#include <google/protobuf/stubs/common.h> #include "google/protobuf/stubs/common.h"
#include <google/protobuf/io/coded_stream.h> #include "google/protobuf/io/coded_stream.h"
#include <google/protobuf/io/printer.h> #include "google/protobuf/io/printer.h"
#include <google/protobuf/descriptor.h> #include "google/protobuf/descriptor.h"
#include <google/protobuf/generated_message_util.h> #include "google/protobuf/generated_message_util.h"
#include <google/protobuf/map_entry_lite.h> #include "google/protobuf/map_entry_lite.h"
#include <google/protobuf/wire_format.h> #include "google/protobuf/wire_format.h"
#include <google/protobuf/stubs/strutil.h> #include "google/protobuf/stubs/strutil.h"
#include "absl/strings/ascii.h" #include "absl/strings/ascii.h"
#include "absl/strings/str_cat.h" #include "absl/strings/str_cat.h"
#include <google/protobuf/stubs/stringprintf.h> #include "google/protobuf/stubs/stringprintf.h"
#include "absl/strings/str_join.h" #include "absl/strings/str_join.h"
#include "absl/strings/string_view.h" #include "absl/strings/string_view.h"
#include "absl/strings/substitute.h" #include "absl/strings/substitute.h"
#include <google/protobuf/compiler/cpp/enum.h> #include "google/protobuf/compiler/cpp/enum.h"
#include <google/protobuf/compiler/cpp/extension.h> #include "google/protobuf/compiler/cpp/extension.h"
#include <google/protobuf/compiler/cpp/field.h> #include "google/protobuf/compiler/cpp/field.h"
#include <google/protobuf/compiler/cpp/helpers.h> #include "google/protobuf/compiler/cpp/helpers.h"
#include <google/protobuf/compiler/cpp/padding_optimizer.h> #include "google/protobuf/compiler/cpp/padding_optimizer.h"
#include <google/protobuf/compiler/cpp/parse_function_generator.h> #include "google/protobuf/compiler/cpp/parse_function_generator.h"
#include <google/protobuf/descriptor.pb.h> #include "google/protobuf/descriptor.pb.h"
// Must be included last. // Must be included last.
#include <google/protobuf/port_def.inc> #include "google/protobuf/port_def.inc"
namespace google { namespace google {
namespace protobuf { namespace protobuf {
@ -410,7 +410,6 @@ class ColdChunkSkipper {
has_bit_indices_(has_bit_indices), has_bit_indices_(has_bit_indices),
access_info_map_(options.access_info_map), access_info_map_(options.access_info_map),
cold_threshold_(cold_threshold) { cold_threshold_(cold_threshold) {
SetCommonVars(options, &variables_);
SetCommonMessageDataVariables(descriptor, &variables_); SetCommonMessageDataVariables(descriptor, &variables_);
} }
@ -4450,4 +4449,4 @@ void MessageGenerator::GenerateIsInitialized(io::Printer* printer) {
} // namespace protobuf } // namespace protobuf
} // namespace google } // namespace google
#include <google/protobuf/port_undef.inc> #include "google/protobuf/port_undef.inc"

@ -41,11 +41,11 @@
#include <set> #include <set>
#include <string> #include <string>
#include <google/protobuf/compiler/cpp/field.h> #include "google/protobuf/compiler/cpp/field.h"
#include <google/protobuf/compiler/cpp/helpers.h> #include "google/protobuf/compiler/cpp/helpers.h"
#include <google/protobuf/compiler/cpp/message_layout_helper.h> #include "google/protobuf/compiler/cpp/message_layout_helper.h"
#include <google/protobuf/compiler/cpp/options.h> #include "google/protobuf/compiler/cpp/options.h"
#include <google/protobuf/compiler/cpp/parse_function_generator.h> #include "google/protobuf/compiler/cpp/parse_function_generator.h"
namespace google { namespace google {
namespace protobuf { namespace protobuf {

@ -32,13 +32,13 @@
// Based on original Protocol Buffers design by // Based on original Protocol Buffers design by
// Sanjay Ghemawat, Jeff Dean, and others. // Sanjay Ghemawat, Jeff Dean, and others.
#include <google/protobuf/compiler/cpp/message_field.h> #include "google/protobuf/compiler/cpp/message_field.h"
#include <google/protobuf/io/printer.h> #include "google/protobuf/io/printer.h"
#include <google/protobuf/compiler/cpp/field.h> #include "google/protobuf/compiler/cpp/field.h"
#include <google/protobuf/compiler/cpp/helpers.h> #include "google/protobuf/compiler/cpp/helpers.h"
#include <google/protobuf/stubs/strutil.h> #include "google/protobuf/stubs/strutil.h"
namespace google { namespace google {
namespace protobuf { namespace protobuf {
@ -73,7 +73,7 @@ void SetMessageVariables(const FieldDescriptor* descriptor,
QualifiedDefaultInstancePtr(descriptor->message_type(), options), QualifiedDefaultInstancePtr(descriptor->message_type(), options),
implicit_weak); implicit_weak);
(*variables)["type_reference_function"] = (*variables)["type_reference_function"] =
implicit_weak ? (" ::" + (*variables)["proto_ns"] + implicit_weak ? (" ::" + ProtobufNamespace(options) +
"::internal::StrongReference(reinterpret_cast<const " + "::internal::StrongReference(reinterpret_cast<const " +
(*variables)["type"] + "&>(\n" + (*variables)["type"] + "&>(\n" +
(*variables)["type_default_instance"] + "));\n") (*variables)["type_default_instance"] + "));\n")

@ -38,8 +38,8 @@
#include <map> #include <map>
#include <string> #include <string>
#include <google/protobuf/compiler/cpp/field.h> #include "google/protobuf/compiler/cpp/field.h"
#include <google/protobuf/compiler/cpp/helpers.h> #include "google/protobuf/compiler/cpp/helpers.h"
namespace google { namespace google {
namespace protobuf { namespace protobuf {

@ -35,8 +35,8 @@
#ifndef GOOGLE_PROTOBUF_COMPILER_CPP_MESSAGE_LAYOUT_HELPER_H__ #ifndef GOOGLE_PROTOBUF_COMPILER_CPP_MESSAGE_LAYOUT_HELPER_H__
#define GOOGLE_PROTOBUF_COMPILER_CPP_MESSAGE_LAYOUT_HELPER_H__ #define GOOGLE_PROTOBUF_COMPILER_CPP_MESSAGE_LAYOUT_HELPER_H__
#include <google/protobuf/descriptor.h> #include "google/protobuf/descriptor.h"
#include <google/protobuf/compiler/cpp/options.h> #include "google/protobuf/compiler/cpp/options.h"
namespace google { namespace google {
namespace protobuf { namespace protobuf {

@ -28,10 +28,10 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <google/protobuf/unittest.pb.h> #include "google/protobuf/unittest.pb.h"
#include <gmock/gmock.h> #include <gmock/gmock.h>
#include <gtest/gtest.h> #include <gtest/gtest.h>
#include <google/protobuf/descriptor.h> #include "google/protobuf/descriptor.h"
namespace google { namespace google {
namespace protobuf { namespace protobuf {

@ -30,15 +30,15 @@
#include <memory> #include <memory>
#include <google/protobuf/testing/file.h> #include "google/protobuf/testing/file.h"
#include <google/protobuf/testing/file.h> #include "google/protobuf/testing/file.h"
#include <google/protobuf/compiler/cpp/generator.h> #include "google/protobuf/compiler/cpp/generator.h"
#include <google/protobuf/compiler/command_line_interface.h> #include "google/protobuf/compiler/command_line_interface.h"
#include <google/protobuf/descriptor.pb.h> #include "google/protobuf/descriptor.pb.h"
#include <google/protobuf/testing/googletest.h> #include "google/protobuf/testing/googletest.h"
#include <gtest/gtest.h> #include <gtest/gtest.h>
#include <google/protobuf/compiler/annotation_test_util.h> #include "google/protobuf/compiler/annotation_test_util.h"
#include <google/protobuf/compiler/cpp/helpers.h> #include "google/protobuf/compiler/cpp/helpers.h"
namespace google { namespace google {
namespace protobuf { namespace protobuf {

@ -28,9 +28,9 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <google/protobuf/stubs/common.h> #include "google/protobuf/stubs/common.h"
#include <google/protobuf/test_util.h> #include "google/protobuf/test_util.h"
#include <google/protobuf/unittest.pb.h> #include "google/protobuf/unittest.pb.h"
#include <gtest/gtest.h> #include <gtest/gtest.h>
#if LANG_CXX11 #if LANG_CXX11

@ -34,7 +34,7 @@
#include <string> #include <string>
// Must be included last. // Must be included last.
#include <google/protobuf/port_def.inc> #include "google/protobuf/port_def.inc"
namespace google { namespace google {
namespace protobuf { namespace protobuf {
@ -92,6 +92,6 @@ PROTOC_EXPORT std::string StripProto(const std::string& filename);
} // namespace protobuf } // namespace protobuf
} // namespace google } // namespace google
#include <google/protobuf/port_undef.inc> #include "google/protobuf/port_undef.inc"
#endif // GOOGLE_PROTOBUF_COMPILER_CPP_NAMES_H__ #endif // GOOGLE_PROTOBUF_COMPILER_CPP_NAMES_H__

@ -28,9 +28,9 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <google/protobuf/compiler/cpp/padding_optimizer.h> #include "google/protobuf/compiler/cpp/padding_optimizer.h"
#include <google/protobuf/compiler/cpp/helpers.h> #include "google/protobuf/compiler/cpp/helpers.h"
namespace google { namespace google {
namespace protobuf { namespace protobuf {

@ -35,7 +35,7 @@
#ifndef GOOGLE_PROTOBUF_COMPILER_CPP_PADDING_OPTIMIZER_H__ #ifndef GOOGLE_PROTOBUF_COMPILER_CPP_PADDING_OPTIMIZER_H__
#define GOOGLE_PROTOBUF_COMPILER_CPP_PADDING_OPTIMIZER_H__ #define GOOGLE_PROTOBUF_COMPILER_CPP_PADDING_OPTIMIZER_H__
#include <google/protobuf/compiler/cpp/message_layout_helper.h> #include "google/protobuf/compiler/cpp/message_layout_helper.h"
namespace google { namespace google {
namespace protobuf { namespace protobuf {

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save