diff --git a/csharp/src/Google.Protobuf/Reflection/FeatureSetDescriptor.g.cs b/csharp/src/Google.Protobuf/Reflection/FeatureSetDescriptor.g.cs deleted file mode 100644 index 208ce1fcb6319..0000000000000 --- a/csharp/src/Google.Protobuf/Reflection/FeatureSetDescriptor.g.cs +++ /dev/null @@ -1,17 +0,0 @@ -#region Copyright notice and license -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file or at -// https://developers.google.com/open-source/licenses/bsd -#endregion - -namespace Google.Protobuf.Reflection; - -internal sealed partial class FeatureSetDescriptor -{ - // Canonical serialized form of the edition defaults, generated by embed_edition_defaults. - private const string DefaultsBase64 = - "ChMYhAciACoMCAEQAhgCIAMoATACChMY5wciACoMCAIQARgBIAIoATABChMY6AciDAgBEAEYASACKAEwASoAIOYHKOgH"; -} diff --git a/src/google/protobuf/compiler/cpp/file.cc b/src/google/protobuf/compiler/cpp/file.cc index 0d048c8eb173b..c9e664b5e150f 100644 --- a/src/google/protobuf/compiler/cpp/file.cc +++ b/src/google/protobuf/compiler/cpp/file.cc @@ -1769,9 +1769,14 @@ void FileGenerator::GenerateGlobalStateFunctionDeclarations(io::Printer* p) { )cc"); if (HasDescriptorMethods(file_, options_)) { + // The DescriptorTable needs to be extern "C" so that we can access it from + // Rust. We do not attempt to read the contents of the table in Rust, but + // just use the symbol to force-link the C++ generated code when necessary. p->Emit(R"cc( + extern "C" { $dllexport_decl $extern const ::$proto_ns$::internal::DescriptorTable $desc_table$; + } // extern "C" )cc"); } } diff --git a/src/google/protobuf/compiler/java/java_features.pb.h b/src/google/protobuf/compiler/java/java_features.pb.h index 89c2d0bf635c3..c54089c4b1fbc 100644 --- a/src/google/protobuf/compiler/java/java_features.pb.h +++ b/src/google/protobuf/compiler/java/java_features.pb.h @@ -51,8 +51,10 @@ ::absl::string_view GetAnyMessageName(); struct PROTOC_EXPORT TableStruct_google_2fprotobuf_2fcompiler_2fjava_2fjava_5ffeatures_2eproto { static const ::uint32_t offsets[]; }; +extern "C" { PROTOC_EXPORT extern const ::google::protobuf::internal::DescriptorTable descriptor_table_google_2fprotobuf_2fcompiler_2fjava_2fjava_5ffeatures_2eproto; +} // extern "C" namespace pb { enum JavaFeatures_Utf8Validation : int; PROTOC_EXPORT bool JavaFeatures_Utf8Validation_IsValid(int value); diff --git a/src/google/protobuf/compiler/plugin.pb.h b/src/google/protobuf/compiler/plugin.pb.h index f6158e5ba4027..21418aed6109e 100644 --- a/src/google/protobuf/compiler/plugin.pb.h +++ b/src/google/protobuf/compiler/plugin.pb.h @@ -57,8 +57,10 @@ ::absl::string_view GetAnyMessageName(); struct PROTOC_EXPORT TableStruct_google_2fprotobuf_2fcompiler_2fplugin_2eproto { static const ::uint32_t offsets[]; }; +extern "C" { PROTOC_EXPORT extern const ::google::protobuf::internal::DescriptorTable descriptor_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto; +} // extern "C" namespace google { namespace protobuf { namespace compiler { diff --git a/src/google/protobuf/cpp_features.pb.h b/src/google/protobuf/cpp_features.pb.h index 666216843a1a5..32168f7048f7a 100644 --- a/src/google/protobuf/cpp_features.pb.h +++ b/src/google/protobuf/cpp_features.pb.h @@ -51,8 +51,10 @@ ::absl::string_view GetAnyMessageName(); struct PROTOBUF_EXPORT TableStruct_google_2fprotobuf_2fcpp_5ffeatures_2eproto { static const ::uint32_t offsets[]; }; +extern "C" { PROTOBUF_EXPORT extern const ::google::protobuf::internal::DescriptorTable descriptor_table_google_2fprotobuf_2fcpp_5ffeatures_2eproto; +} // extern "C" namespace pb { enum CppFeatures_StringType : int; PROTOBUF_EXPORT bool CppFeatures_StringType_IsValid(int value); diff --git a/src/google/protobuf/descriptor.pb.h b/src/google/protobuf/descriptor.pb.h index c01af468b7a11..12e086359f2ed 100644 --- a/src/google/protobuf/descriptor.pb.h +++ b/src/google/protobuf/descriptor.pb.h @@ -50,8 +50,10 @@ ::absl::string_view GetAnyMessageName(); struct PROTOBUF_EXPORT TableStruct_google_2fprotobuf_2fdescriptor_2eproto { static const ::uint32_t offsets[]; }; +extern "C" { PROTOBUF_EXPORT extern const ::google::protobuf::internal::DescriptorTable descriptor_table_google_2fprotobuf_2fdescriptor_2eproto; +} // extern "C" namespace google { namespace protobuf { enum Edition : int; diff --git a/src/google/protobuf/descriptor_unittest.cc b/src/google/protobuf/descriptor_unittest.cc index 347e05fec846c..319c809e50e1d 100644 --- a/src/google/protobuf/descriptor_unittest.cc +++ b/src/google/protobuf/descriptor_unittest.cc @@ -44,6 +44,7 @@ #include "absl/log/scoped_mock_log.h" #include "absl/status/status.h" #include "absl/status/statusor.h" +#include "absl/strings/match.h" #include "absl/strings/numbers.h" #include "absl/strings/str_cat.h" #include "absl/strings/str_format.h" @@ -14104,6 +14105,28 @@ TEST_F(LazilyBuildDependenciesTest, Dependency) { // =================================================================== +// This is effectively a static_assert ensuring that the generated +// descriptor_table variable is marked extern "C". The compiler will give us an +// error if the generated declaration does not match this one. We need this +// variable to be extern "C" so that we can refer to it from Rust. +// +// If this causes a linker error, it is likely because the name mangling +// changed. That can be fixed by updating to the new name from the generated +// code for unittest.proto. + +#define DESCRIPTOR_TABLE_NAME \ + descriptor_table_google_2fprotobuf_2funittest_2eproto + +extern "C" { +extern const ::google::protobuf::internal::DescriptorTable DESCRIPTOR_TABLE_NAME; +} + +TEST(DescriptorTableExternLinkageTest, DescriptorTableExternLinkageTest) { + // The goal of this assertion is just to verify that the descriptor_table + // variable declaration above still refers to a real thing. + EXPECT_TRUE(absl::EndsWith(DESCRIPTOR_TABLE_NAME.filename, "unittest.proto")); +} + } // namespace descriptor_unittest } // namespace protobuf