File indexing completed on 2026-09-21 09:12:43
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015 #ifndef GOOGLE_PROTOBUF_DYNAMIC_MESSAGE_H__
0016 #define GOOGLE_PROTOBUF_DYNAMIC_MESSAGE_H__
0017
0018 #include <algorithm>
0019 #include <cstddef>
0020 #include <cstdint>
0021 #include <string>
0022 #include <vector>
0023
0024 #include "absl/container/flat_hash_map.h"
0025 #include "absl/log/absl_log.h"
0026 #include "absl/synchronization/mutex.h"
0027 #include "google/protobuf/descriptor.h"
0028 #include "google/protobuf/message.h"
0029 #include "google/protobuf/reflection.h"
0030 #include "google/protobuf/repeated_field.h"
0031
0032 #ifdef SWIG
0033 #error "You cannot SWIG proto headers"
0034 #endif
0035
0036
0037 #include "google/protobuf/port_def.inc"
0038
0039 namespace google {
0040 namespace protobuf {
0041
0042
0043 class Descriptor;
0044 class DescriptorPool;
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066 class PROTOBUF_EXPORT DynamicMessageFactory : public MessageFactory {
0067 public:
0068
0069
0070 DynamicMessageFactory();
0071
0072
0073
0074
0075
0076
0077
0078
0079 #ifndef PROTOBUF_FUTURE_BREAKING_CHANGES
0080 explicit
0081 #endif
0082 DynamicMessageFactory(const DescriptorPool* PROTOBUF_NONNULL pool);
0083 DynamicMessageFactory(const DynamicMessageFactory&) = delete;
0084 DynamicMessageFactory& operator=(const DynamicMessageFactory&) = delete;
0085
0086 ~DynamicMessageFactory() override;
0087
0088
0089
0090
0091
0092
0093
0094 void SetDelegateToGeneratedFactory(bool enable) {
0095 delegate_to_generated_factory_ = enable;
0096 }
0097
0098
0099
0100
0101
0102
0103
0104
0105
0106
0107
0108
0109
0110
0111
0112
0113
0114
0115 const Message* PROTOBUF_NONNULL
0116 GetPrototype(const Descriptor* PROTOBUF_NONNULL type) override;
0117
0118 private:
0119 const DescriptorPool* PROTOBUF_NULLABLE pool_;
0120 bool delegate_to_generated_factory_;
0121
0122 struct TypeInfo;
0123 absl::flat_hash_map<const Descriptor*, const TypeInfo*> prototypes_;
0124 mutable absl::Mutex prototypes_mutex_;
0125
0126 friend class DynamicMessage;
0127 const Message* PROTOBUF_NONNULL
0128 GetPrototypeNoLock(const Descriptor* PROTOBUF_NONNULL type);
0129 };
0130
0131
0132 class PROTOBUF_EXPORT DynamicMapSorter {
0133 public:
0134 static std::vector<const Message*> Sort(
0135 const Message& message, int map_size,
0136 const Reflection* PROTOBUF_NONNULL reflection,
0137 const FieldDescriptor* PROTOBUF_NONNULL field) {
0138 std::vector<const Message*> result;
0139 result.reserve(map_size);
0140 RepeatedFieldRef<Message> map_field =
0141 reflection->GetRepeatedFieldRef<Message>(message, field);
0142 for (auto it = map_field.begin(); it != map_field.end(); ++it) {
0143 result.push_back(&*it);
0144 }
0145 MapEntryMessageComparator comparator(field->message_type());
0146 std::stable_sort(result.begin(), result.end(), comparator);
0147
0148 #ifndef NDEBUG
0149 for (size_t j = 1; j < static_cast<size_t>(map_size); ++j) {
0150 if (!comparator(result[j - 1], result[j])) {
0151 ABSL_LOG(ERROR) << (comparator(result[j], result[j - 1])
0152 ? "internal error in map key sorting"
0153 : "map keys are not unique");
0154 }
0155 }
0156 #endif
0157 return result;
0158 }
0159
0160 private:
0161 class PROTOBUF_EXPORT MapEntryMessageComparator {
0162 public:
0163 explicit MapEntryMessageComparator(
0164 const Descriptor* PROTOBUF_NONNULL descriptor)
0165 : field_(descriptor->field(0)) {}
0166
0167 bool operator()(const Message* PROTOBUF_NONNULL a,
0168 const Message* PROTOBUF_NONNULL b) {
0169 const Reflection* reflection = a->GetReflection();
0170 switch (field_->cpp_type()) {
0171 case FieldDescriptor::CPPTYPE_BOOL: {
0172 bool first = reflection->GetBool(*a, field_);
0173 bool second = reflection->GetBool(*b, field_);
0174 return first < second;
0175 }
0176 case FieldDescriptor::CPPTYPE_INT32: {
0177 int32_t first = reflection->GetInt32(*a, field_);
0178 int32_t second = reflection->GetInt32(*b, field_);
0179 return first < second;
0180 }
0181 case FieldDescriptor::CPPTYPE_INT64: {
0182 int64_t first = reflection->GetInt64(*a, field_);
0183 int64_t second = reflection->GetInt64(*b, field_);
0184 return first < second;
0185 }
0186 case FieldDescriptor::CPPTYPE_UINT32: {
0187 uint32_t first = reflection->GetUInt32(*a, field_);
0188 uint32_t second = reflection->GetUInt32(*b, field_);
0189 return first < second;
0190 }
0191 case FieldDescriptor::CPPTYPE_UINT64: {
0192 uint64_t first = reflection->GetUInt64(*a, field_);
0193 uint64_t second = reflection->GetUInt64(*b, field_);
0194 return first < second;
0195 }
0196 case FieldDescriptor::CPPTYPE_STRING: {
0197 std::string first = reflection->GetString(*a, field_);
0198 std::string second = reflection->GetString(*b, field_);
0199 return first < second;
0200 }
0201 default:
0202 ABSL_DLOG(FATAL) << "Invalid key for map field.";
0203 return true;
0204 }
0205 }
0206
0207 private:
0208 const FieldDescriptor* PROTOBUF_NONNULL field_;
0209 };
0210 };
0211
0212 }
0213 }
0214
0215 #include "google/protobuf/port_undef.inc"
0216
0217 #endif