mirror of
https://github.com/protocolbuffers/protobuf
synced 2026-08-26 02:23:14 -04:00
`New` is more efficient on ClassData than on a prototype, as `New` on the prototype has to first load the class data through the prototype. There's also a small optimization in `LazyField::MergeFromMessage` which avoids loading the class data twice. The redundancy was made more obvious by this refactor. PiperOrigin-RevId: 953889072
102 lines
4.1 KiB
C++
102 lines
4.1 KiB
C++
// Protocol Buffers - Google's data interchange format
|
|
// Copyright 2026 Google LLC. All rights reserved.
|
|
//
|
|
// Use of this source code is governed by a BSD-style
|
|
// license that can be found in the LICENSE file or at
|
|
// https://developers.google.com/open-source/licenses/bsd
|
|
|
|
#include <cstdint>
|
|
#include <string>
|
|
#include <utility>
|
|
|
|
#include "absl/log/absl_check.h"
|
|
#include "google/protobuf/extension_set.h"
|
|
#include "google/protobuf/generated_message_util.h"
|
|
#include "google/protobuf/message_lite.h"
|
|
#include "rust/cpp_kernel/strings.h"
|
|
|
|
static const google::protobuf::internal::ExtensionSet* GetExtensionSet(
|
|
const google::protobuf::MessageLite* m) {
|
|
const google::protobuf::internal::ExtensionSet* ext =
|
|
google::protobuf::internal::PrivateAccess::GetExtensionSet(m);
|
|
ABSL_DCHECK(ext != nullptr);
|
|
return ext;
|
|
}
|
|
|
|
static google::protobuf::internal::ExtensionSet* GetExtensionSet(google::protobuf::MessageLite* m) {
|
|
google::protobuf::internal::ExtensionSet* ext =
|
|
google::protobuf::internal::PrivateAccess::GetExtensionSet(m);
|
|
ABSL_DCHECK(ext != nullptr);
|
|
return ext;
|
|
}
|
|
|
|
extern "C" {
|
|
|
|
bool proto2_rust_Message_has_extension(const google::protobuf::MessageLite* m,
|
|
int32_t number) {
|
|
return GetExtensionSet(m)->Has(number);
|
|
}
|
|
|
|
void proto2_rust_Message_clear_extension(google::protobuf::MessageLite* m,
|
|
int32_t number) {
|
|
GetExtensionSet(m)->ClearExtension(number);
|
|
}
|
|
|
|
#define DEFN_EXT_PRIMITIVE(rust_type, cpp_type) \
|
|
void proto2_rust_Message_set_extension_##rust_type( \
|
|
google::protobuf::MessageLite* m, int32_t number, int32_t type, cpp_type value) { \
|
|
GetExtensionSet(m)->Set<cpp_type>(m->GetArena(), number, type, value, \
|
|
nullptr); \
|
|
} \
|
|
cpp_type proto2_rust_Message_get_extension_##rust_type( \
|
|
google::protobuf::MessageLite* m, int32_t number, cpp_type default_value) { \
|
|
return GetExtensionSet(m)->Get<cpp_type>(number, default_value); \
|
|
}
|
|
|
|
DEFN_EXT_PRIMITIVE(bool, bool)
|
|
DEFN_EXT_PRIMITIVE(float, float)
|
|
DEFN_EXT_PRIMITIVE(double, double)
|
|
DEFN_EXT_PRIMITIVE(int32, int32_t)
|
|
DEFN_EXT_PRIMITIVE(int64, int64_t)
|
|
DEFN_EXT_PRIMITIVE(uint32, uint32_t)
|
|
DEFN_EXT_PRIMITIVE(uint64, uint64_t)
|
|
|
|
#undef DEFN_EXT_PRIMITIVE
|
|
|
|
void proto2_rust_Message_set_extension_string(google::protobuf::MessageLite* m,
|
|
int32_t number, int32_t type,
|
|
std::string* value) {
|
|
GetExtensionSet(m)->Set<std::string>(m->GetArena(), number, type,
|
|
std::move(*value), nullptr);
|
|
delete value;
|
|
}
|
|
|
|
google::protobuf::rust::PtrAndLen proto2_rust_Message_get_extension_string(
|
|
google::protobuf::MessageLite* m, int32_t number,
|
|
google::protobuf::rust::PtrAndLen default_value) {
|
|
if (!proto2_rust_Message_has_extension(m, number)) {
|
|
return default_value;
|
|
}
|
|
std::string fake_default;
|
|
const std::string& value =
|
|
GetExtensionSet(m)->Get<std::string>(number, fake_default);
|
|
return google::protobuf::rust::PtrAndLen{value.data(), value.size()};
|
|
}
|
|
|
|
const google::protobuf::MessageLite* proto2_rust_Message_get_extension_message(
|
|
const google::protobuf::MessageLite* m, int32_t number,
|
|
const google::protobuf::MessageLite* default_instance) {
|
|
const auto* class_data = google::protobuf::internal::GetClassData(*default_instance);
|
|
return &GetExtensionSet(m)->GetMessageByClassData(m->GetArena(), number,
|
|
class_data);
|
|
}
|
|
|
|
google::protobuf::MessageLite* proto2_rust_Message_mutable_extension_message(
|
|
google::protobuf::MessageLite* m, int32_t number, int32_t type,
|
|
const google::protobuf::MessageLite* default_instance) {
|
|
const auto* class_data = google::protobuf::internal::GetClassData(*default_instance);
|
|
return GetExtensionSet(m)->MutableMessageByClassData(
|
|
m->GetArena(), number, type, class_data, nullptr);
|
|
}
|
|
|
|
} // extern "C"
|