File indexing completed on 2025-01-31 10:12:19
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* 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* GetPrototype(const Descriptor* type) override;
0116
0117 private:
0118 const DescriptorPool* pool_;
0119 bool delegate_to_generated_factory_;
0120
0121 struct TypeInfo;
0122 absl::flat_hash_map<const Descriptor*, const TypeInfo*> prototypes_;
0123 mutable absl::Mutex prototypes_mutex_;
0124
0125 friend class DynamicMessage;
0126 const Message* GetPrototypeNoLock(const Descriptor* type);
0127 };
0128
0129
0130 class PROTOBUF_EXPORT DynamicMapSorter {
0131 public:
0132 static std::vector<const Message*> Sort(const Message& message, int map_size,
0133 const Reflection* reflection,
0134 const FieldDescriptor* field) {
0135 std::vector<const Message*> result;
0136 result.reserve(map_size);
0137 RepeatedFieldRef<Message> map_field =
0138 reflection->GetRepeatedFieldRef<Message>(message, field);
0139 for (auto it = map_field.begin(); it != map_field.end(); ++it) {
0140 result.push_back(&*it);
0141 }
0142 MapEntryMessageComparator comparator(field->message_type());
0143 std::stable_sort(result.begin(), result.end(), comparator);
0144
0145 #ifndef NDEBUG
0146 for (size_t j = 1; j < static_cast<size_t>(map_size); ++j) {
0147 if (!comparator(result[j - 1], result[j])) {
0148 ABSL_LOG(ERROR) << (comparator(result[j], result[j - 1])
0149 ? "internal error in map key sorting"
0150 : "map keys are not unique");
0151 }
0152 }
0153 #endif
0154 return result;
0155 }
0156
0157 private:
0158 class PROTOBUF_EXPORT MapEntryMessageComparator {
0159 public:
0160 explicit MapEntryMessageComparator(const Descriptor* descriptor)
0161 : field_(descriptor->field(0)) {}
0162
0163 bool operator()(const Message* a, const Message* b) {
0164 const Reflection* reflection = a->GetReflection();
0165 switch (field_->cpp_type()) {
0166 case FieldDescriptor::CPPTYPE_BOOL: {
0167 bool first = reflection->GetBool(*a, field_);
0168 bool second = reflection->GetBool(*b, field_);
0169 return first < second;
0170 }
0171 case FieldDescriptor::CPPTYPE_INT32: {
0172 int32_t first = reflection->GetInt32(*a, field_);
0173 int32_t second = reflection->GetInt32(*b, field_);
0174 return first < second;
0175 }
0176 case FieldDescriptor::CPPTYPE_INT64: {
0177 int64_t first = reflection->GetInt64(*a, field_);
0178 int64_t second = reflection->GetInt64(*b, field_);
0179 return first < second;
0180 }
0181 case FieldDescriptor::CPPTYPE_UINT32: {
0182 uint32_t first = reflection->GetUInt32(*a, field_);
0183 uint32_t second = reflection->GetUInt32(*b, field_);
0184 return first < second;
0185 }
0186 case FieldDescriptor::CPPTYPE_UINT64: {
0187 uint64_t first = reflection->GetUInt64(*a, field_);
0188 uint64_t second = reflection->GetUInt64(*b, field_);
0189 return first < second;
0190 }
0191 case FieldDescriptor::CPPTYPE_STRING: {
0192 std::string first = reflection->GetString(*a, field_);
0193 std::string second = reflection->GetString(*b, field_);
0194 return first < second;
0195 }
0196 default:
0197 ABSL_DLOG(FATAL) << "Invalid key for map field.";
0198 return true;
0199 }
0200 }
0201
0202 private:
0203 const FieldDescriptor* field_;
0204 };
0205 };
0206
0207 }
0208 }
0209
0210 #include "google/protobuf/port_undef.inc"
0211
0212 #endif