File indexing completed on 2026-09-25 09:15:37
0001 #ifndef GOOGLE_PROTOBUF_REFLECTION_VISIT_FIELD_INFO_H__
0002 #define GOOGLE_PROTOBUF_REFLECTION_VISIT_FIELD_INFO_H__
0003
0004 #include <cstddef>
0005 #include <cstdint>
0006 #include <iterator>
0007 #include <string>
0008 #include <type_traits>
0009 #include <utility>
0010
0011 #include "absl/log/absl_check.h"
0012 #include "absl/strings/cord.h"
0013 #include "absl/strings/string_view.h"
0014 #include "google/protobuf/arenastring.h"
0015 #include "google/protobuf/descriptor.h"
0016 #include "google/protobuf/descriptor.pb.h"
0017 #include "google/protobuf/extension_set.h"
0018 #include "google/protobuf/inlined_string_field.h"
0019 #include "google/protobuf/map_field.h"
0020 #include "google/protobuf/message.h"
0021 #include "google/protobuf/message_lite.h"
0022 #include "google/protobuf/port.h"
0023 #include "google/protobuf/wire_format_lite.h"
0024
0025
0026
0027 #include "google/protobuf/port_def.inc"
0028
0029
0030 namespace google {
0031 namespace protobuf {
0032 namespace internal {
0033
0034
0035
0036
0037
0038 template <typename IteratorT>
0039 class iterator_range {
0040 public:
0041 using iterator = IteratorT;
0042 using const_iterator = IteratorT;
0043 using value_type = typename std::iterator_traits<IteratorT>::value_type;
0044
0045 iterator_range() : begin_iterator_(), end_iterator_() {}
0046 iterator_range(IteratorT begin_iterator, IteratorT end_iterator)
0047 : begin_iterator_(std::move(begin_iterator)),
0048 end_iterator_(std::move(end_iterator)) {}
0049
0050 IteratorT begin() const { return begin_iterator_; }
0051 IteratorT end() const { return end_iterator_; }
0052
0053
0054
0055
0056
0057
0058
0059 template <class It = IteratorT>
0060 typename std::enable_if<std::is_base_of<std::random_access_iterator_tag,
0061 typename std::iterator_traits<
0062 It>::iterator_category>::value,
0063 size_t>::type
0064 size() const {
0065 return std::distance(begin_iterator_, end_iterator_);
0066 }
0067
0068
0069 bool empty() const { return begin_iterator_ == end_iterator_; }
0070
0071 private:
0072 IteratorT begin_iterator_, end_iterator_;
0073 };
0074
0075
0076 template <bool is_oneof>
0077 struct DynamicFieldInfoHelper {
0078 template <typename T>
0079 static T Get(const Reflection* reflection, const Message& message,
0080 const FieldDescriptor* field) {
0081 if constexpr (is_oneof) {
0082 }
0083 return reflection->GetRaw<T>(message, field);
0084 }
0085 template <typename T>
0086 static T& GetRef(const Reflection* reflection, const Message& message,
0087 const FieldDescriptor* field) {
0088 if constexpr (is_oneof) {
0089 }
0090 return reflection->GetRaw<T>(message, field);
0091 }
0092 template <typename T>
0093 static T& Mutable(const Reflection* reflection, Message& message,
0094 const FieldDescriptor* field) {
0095 if constexpr (is_oneof) {
0096 return *reflection->MutableRaw<T>(&message, field);
0097 } else {
0098 return *reflection->MutableRaw<T>(&message, field);
0099 }
0100 }
0101
0102 static void ClearField(const Reflection* reflection, Message& message,
0103 const FieldDescriptor* field) {
0104 if constexpr (is_oneof) {
0105 reflection->ClearOneofField(&message, field);
0106 } else {
0107 reflection->ClearField(&message, field);
0108 }
0109 }
0110
0111 static absl::string_view GetStringView(const Reflection* reflection,
0112 const Message& message,
0113 const FieldDescriptor* field) {
0114 auto string_type = field->cpp_string_type();
0115 ABSL_DCHECK(string_type != FieldDescriptor::CppStringType::kCord);
0116 ABSL_DCHECK(!is_oneof || reflection->HasOneofField(message, field));
0117 auto str = Get<ArenaStringPtr>(reflection, message, field);
0118 ABSL_DCHECK(!str.IsDefault());
0119 return str.Get();
0120 }
0121 };
0122
0123 struct DynamicExtensionInfoHelper {
0124 using Extension = ExtensionSet::Extension;
0125
0126 #define PROTOBUF_SINGULAR_PRIMITIVE_METHOD(NAME, FIELD_TYPE, VAR) \
0127 static FIELD_TYPE Get##NAME(const Extension& ext) { \
0128 return ext.VAR##_value; \
0129 } \
0130 static void Set##NAME(Extension& ext, FIELD_TYPE value) { \
0131 ext.VAR##_value = value; \
0132 } \
0133 static void Clear##NAME(Extension& ext) { ext.is_cleared = true; }
0134
0135 PROTOBUF_SINGULAR_PRIMITIVE_METHOD(Int32, int32_t, int32_t);
0136 PROTOBUF_SINGULAR_PRIMITIVE_METHOD(Int64, int64_t, int64_t);
0137 PROTOBUF_SINGULAR_PRIMITIVE_METHOD(UInt32, uint32_t, uint32_t);
0138 PROTOBUF_SINGULAR_PRIMITIVE_METHOD(UInt64, uint64_t, uint64_t);
0139 PROTOBUF_SINGULAR_PRIMITIVE_METHOD(Float, float, float);
0140 PROTOBUF_SINGULAR_PRIMITIVE_METHOD(Double, double, double);
0141 PROTOBUF_SINGULAR_PRIMITIVE_METHOD(Bool, bool, bool);
0142 PROTOBUF_SINGULAR_PRIMITIVE_METHOD(Enum, int, int32_t);
0143
0144 #undef PROTOBUF_SINGULAR_PRIMITIVE_METHOD
0145
0146 #define PROTOBUF_REPEATED_FIELD_METHODS(NAME, FIELD_TYPE, VAR) \
0147 static const RepeatedField<FIELD_TYPE>* GetRepeated##NAME( \
0148 const Extension& ext) { \
0149 return ext.ptr.repeated_##VAR##_value; \
0150 } \
0151 static RepeatedField<FIELD_TYPE>* MutableRepeated##NAME(Extension& ext) { \
0152 return ext.ptr.repeated_##VAR##_value; \
0153 } \
0154 static void ClearRepeated##NAME(Extension& ext) { \
0155 return ext.ptr.repeated_##VAR##_value->Clear(); \
0156 }
0157
0158 PROTOBUF_REPEATED_FIELD_METHODS(Int32, int32_t, int32_t);
0159 PROTOBUF_REPEATED_FIELD_METHODS(Int64, int64_t, int64_t);
0160 PROTOBUF_REPEATED_FIELD_METHODS(UInt32, uint32_t, uint32_t);
0161 PROTOBUF_REPEATED_FIELD_METHODS(UInt64, uint64_t, uint64_t);
0162 PROTOBUF_REPEATED_FIELD_METHODS(Float, float, float);
0163 PROTOBUF_REPEATED_FIELD_METHODS(Double, double, double);
0164 PROTOBUF_REPEATED_FIELD_METHODS(Bool, bool, bool);
0165 PROTOBUF_REPEATED_FIELD_METHODS(Enum, int, int32_t);
0166
0167 #undef PROTOBUF_REPEATED_FIELD_METHODS
0168
0169 #define PROTOBUF_REPEATED_PTR_FIELD_METHODS(FIELD_TYPE, NAME, VAR) \
0170 static const RepeatedPtrField<FIELD_TYPE>* GetRepeated##NAME( \
0171 const Extension& ext) { \
0172 return ext.ptr.repeated_##VAR##_value; \
0173 } \
0174 static RepeatedPtrField<FIELD_TYPE>* MutableRepeated##NAME(Extension& ext) { \
0175 return ext.ptr.repeated_##VAR##_value; \
0176 } \
0177 static void ClearRepeated##NAME(Extension& ext) { \
0178 return ext.ptr.repeated_##VAR##_value->Clear(); \
0179 }
0180
0181 PROTOBUF_REPEATED_PTR_FIELD_METHODS(std::string, String, string);
0182 PROTOBUF_REPEATED_PTR_FIELD_METHODS(MessageLite, Message, message);
0183
0184 #undef PROTOBUF_REPEATED_PTR_FIELD_METHODS
0185
0186 static absl::string_view GetStringView(const Extension& ext) {
0187 return *ext.ptr.string_value;
0188 }
0189 static void SetStringView(Extension& ext, absl::string_view value) {
0190 ext.ptr.string_value->assign(value.data(), value.size());
0191 }
0192 static void ClearStringView(Extension& ext) {
0193 ext.is_cleared = true;
0194 ext.ptr.string_value->clear();
0195 }
0196
0197 static const Message& GetMessage(const Extension& ext) {
0198 return DownCastMessage<Message>(*ext.ptr.message_value);
0199 }
0200 static Message& MutableMessage(Extension& ext) {
0201 return DownCastMessage<Message>(*ext.ptr.message_value);
0202 }
0203 static void ClearMessage(Extension& ext) {
0204 ext.is_cleared = true;
0205 ext.ptr.message_value->Clear();
0206 }
0207
0208 static const Message& GetLazyMessage(const Extension& ext,
0209 const Message& prototype, Arena* arena) {
0210 return DownCastMessage<Message>(
0211 ext.ptr.lazymessage_value->GetMessage(prototype, arena));
0212 }
0213 static const Message& GetLazyMessageIgnoreUnparsed(const Extension& ext,
0214 const Message& prototype,
0215 Arena* arena) {
0216 return DownCastMessage<Message>(
0217 ext.ptr.lazymessage_value->GetMessageIgnoreUnparsed(prototype, arena));
0218 }
0219 static Message& MutableLazyMessage(Extension& ext, const Message& prototype,
0220 Arena* arena) {
0221 return DownCastMessage<Message>(
0222 *ext.ptr.lazymessage_value->MutableMessage(prototype, arena));
0223 }
0224 static void ClearLazyMessage(Extension& ext) {
0225 ext.is_cleared = true;
0226 return ext.ptr.lazymessage_value->Clear();
0227 }
0228 static size_t ByteSizeLongLazyMessage(const Extension& ext) {
0229 return ext.ptr.lazymessage_value->ByteSizeLong();
0230 }
0231 };
0232
0233
0234
0235
0236 template <typename MessageT, typename FieldT,
0237 FieldDescriptor::CppType cpp_type_parameter, bool is_oneof_parameter>
0238 struct SingularPrimitive {
0239 constexpr SingularPrimitive(const Reflection* r, MessageT& m,
0240 const FieldDescriptor* f)
0241 : reflection(r), message(m), field(f) {}
0242
0243 int number() const { return field->number(); }
0244 FieldDescriptor::Type type() const { return field->type(); }
0245
0246 FieldT Get() const {
0247 return DynamicFieldInfoHelper<is_oneof>::template Get<FieldT>(
0248 reflection, message, field);
0249 }
0250 void Set(FieldT value) {
0251 DynamicFieldInfoHelper<is_oneof>::template Mutable<FieldT>(
0252 reflection, message, field) = value;
0253 }
0254 void Clear() {
0255 DynamicFieldInfoHelper<is_oneof>::ClearField(reflection, message, field);
0256 }
0257
0258 static constexpr FieldDescriptor::CppType cpp_type =
0259 cpp_type_parameter;
0260 static constexpr bool is_repeated = false;
0261 static constexpr bool is_map = false;
0262 static constexpr bool is_extension = false;
0263 static constexpr bool is_oneof = is_oneof_parameter;
0264
0265 const Reflection* reflection;
0266 MessageT& message;
0267 const FieldDescriptor* field;
0268 };
0269
0270 #define PROTOBUF_DYN_FIELD_INFO_VARINT(NAME, CPPTYPE, FIELD_TYPE) \
0271 template <typename MessageT, bool is_oneof> \
0272 struct NAME##DynamicFieldInfo \
0273 : SingularPrimitive<MessageT, FIELD_TYPE, \
0274 FieldDescriptor::CPPTYPE_##CPPTYPE, is_oneof> { \
0275 using BaseT = \
0276 SingularPrimitive<MessageT, FIELD_TYPE, \
0277 FieldDescriptor::CPPTYPE_##CPPTYPE, is_oneof>; \
0278 \
0279 constexpr NAME##DynamicFieldInfo(const Reflection* r, MessageT& m, \
0280 const FieldDescriptor* f) \
0281 : BaseT(r, m, f) {} \
0282 size_t FieldByteSize() const { \
0283 return WireFormatLite::NAME##Size(BaseT::Get()); \
0284 } \
0285 };
0286
0287 #define PROTOBUF_DYN_FIELD_INFO_FIXED(NAME, CPPTYPE, FIELD_TYPE) \
0288 template <typename MessageT, bool is_oneof> \
0289 struct NAME##DynamicFieldInfo \
0290 : SingularPrimitive<MessageT, FIELD_TYPE, \
0291 FieldDescriptor::CPPTYPE_##CPPTYPE, is_oneof> { \
0292 using BaseT = \
0293 SingularPrimitive<MessageT, FIELD_TYPE, \
0294 FieldDescriptor::CPPTYPE_##CPPTYPE, is_oneof>; \
0295 \
0296 constexpr NAME##DynamicFieldInfo(const Reflection* r, MessageT& m, \
0297 const FieldDescriptor* f) \
0298 : BaseT(r, m, f) {} \
0299 constexpr size_t FieldByteSize() const { \
0300 return WireFormatLite::k##NAME##Size; \
0301 } \
0302 };
0303
0304 PROTOBUF_DYN_FIELD_INFO_VARINT(Int32, INT32, int32_t);
0305 PROTOBUF_DYN_FIELD_INFO_VARINT(Int64, INT64, int64_t);
0306 PROTOBUF_DYN_FIELD_INFO_VARINT(UInt32, UINT32, uint32_t);
0307 PROTOBUF_DYN_FIELD_INFO_VARINT(UInt64, UINT64, uint64_t);
0308 PROTOBUF_DYN_FIELD_INFO_VARINT(SInt32, INT32, int32_t);
0309 PROTOBUF_DYN_FIELD_INFO_VARINT(SInt64, INT64, int64_t);
0310
0311 PROTOBUF_DYN_FIELD_INFO_FIXED(Fixed32, UINT32, uint32_t);
0312 PROTOBUF_DYN_FIELD_INFO_FIXED(Fixed64, UINT64, uint64_t);
0313 PROTOBUF_DYN_FIELD_INFO_FIXED(SFixed32, INT32, int32_t);
0314 PROTOBUF_DYN_FIELD_INFO_FIXED(SFixed64, INT64, int64_t);
0315 PROTOBUF_DYN_FIELD_INFO_FIXED(Double, DOUBLE, double);
0316 PROTOBUF_DYN_FIELD_INFO_FIXED(Float, FLOAT, float);
0317 PROTOBUF_DYN_FIELD_INFO_FIXED(Bool, BOOL, bool);
0318
0319 #undef PROTOBUF_DYN_FIELD_INFO_VARINT
0320 #undef PROTOBUF_DYN_FIELD_INFO_FIXED
0321
0322
0323
0324
0325 #define PROTOBUF_DYN_EXTENSION_INFO_VARINT(NAME, CPPNAME, CPPTYPE, FIELD_TYPE) \
0326 template <typename ExtensionT> \
0327 struct NAME##DynamicExtensionInfo { \
0328 constexpr NAME##DynamicExtensionInfo(ExtensionT& e, int n) \
0329 : ext(e), ext_number(n) {} \
0330 int number() const { return ext_number; } \
0331 FieldDescriptor::Type type() const { \
0332 return static_cast<FieldDescriptor::Type>(ext.type); \
0333 } \
0334 FIELD_TYPE Get() const { \
0335 return DynamicExtensionInfoHelper::Get##CPPNAME(ext); \
0336 } \
0337 void Set(FIELD_TYPE value) { \
0338 DynamicExtensionInfoHelper::Set##CPPNAME(ext, value); \
0339 } \
0340 void Clear() { DynamicExtensionInfoHelper::Clear##CPPNAME(ext); } \
0341 size_t FieldByteSize() const { return WireFormatLite::NAME##Size(Get()); } \
0342 \
0343 static constexpr FieldDescriptor::CppType cpp_type = \
0344 FieldDescriptor::CPPTYPE_##CPPTYPE; \
0345 static constexpr bool is_repeated = false; \
0346 static constexpr bool is_map = false; \
0347 static constexpr bool is_extension = true; \
0348 static constexpr bool is_oneof = false; \
0349 \
0350 ExtensionT& ext; \
0351 int ext_number; \
0352 };
0353
0354 #define PROTOBUF_DYN_EXTENSION_INFO_FIXED(NAME, CPPNAME, CPPTYPE, FIELD_TYPE) \
0355 template <typename ExtensionT> \
0356 struct NAME##DynamicExtensionInfo { \
0357 constexpr NAME##DynamicExtensionInfo(ExtensionT& e, int n) \
0358 : ext(e), ext_number(n) {} \
0359 int number() const { return ext_number; } \
0360 FieldDescriptor::Type type() const { \
0361 return static_cast<FieldDescriptor::Type>(ext.type); \
0362 } \
0363 FIELD_TYPE Get() const { \
0364 return DynamicExtensionInfoHelper::Get##CPPNAME(ext); \
0365 } \
0366 void Set(FIELD_TYPE value) { \
0367 DynamicExtensionInfoHelper::Set##CPPNAME(ext, value); \
0368 } \
0369 void Clear() { DynamicExtensionInfoHelper::Clear##CPPNAME(ext); } \
0370 constexpr size_t FieldByteSize() const { \
0371 return WireFormatLite::k##NAME##Size; \
0372 } \
0373 \
0374 static constexpr FieldDescriptor::CppType cpp_type = \
0375 FieldDescriptor::CPPTYPE_##CPPTYPE; \
0376 static constexpr bool is_repeated = false; \
0377 static constexpr bool is_map = false; \
0378 static constexpr bool is_extension = true; \
0379 static constexpr bool is_oneof = false; \
0380 \
0381 ExtensionT& ext; \
0382 int ext_number; \
0383 };
0384
0385 PROTOBUF_DYN_EXTENSION_INFO_VARINT(Int32, Int32, INT32, int32_t);
0386 PROTOBUF_DYN_EXTENSION_INFO_VARINT(Int64, Int64, INT64, int64_t);
0387 PROTOBUF_DYN_EXTENSION_INFO_VARINT(UInt32, UInt32, UINT32, uint32_t);
0388 PROTOBUF_DYN_EXTENSION_INFO_VARINT(UInt64, UInt64, UINT64, uint64_t);
0389 PROTOBUF_DYN_EXTENSION_INFO_VARINT(SInt32, Int32, INT32, int32_t);
0390 PROTOBUF_DYN_EXTENSION_INFO_VARINT(SInt64, Int64, INT64, int64_t);
0391 PROTOBUF_DYN_EXTENSION_INFO_VARINT(Enum, Enum, ENUM, int);
0392
0393 PROTOBUF_DYN_EXTENSION_INFO_FIXED(Fixed32, UInt32, UINT32, uint32_t);
0394 PROTOBUF_DYN_EXTENSION_INFO_FIXED(Fixed64, UInt64, UINT64, uint64_t);
0395 PROTOBUF_DYN_EXTENSION_INFO_FIXED(SFixed32, Int32, INT32, int32_t);
0396 PROTOBUF_DYN_EXTENSION_INFO_FIXED(SFixed64, Int64, INT64, int64_t);
0397 PROTOBUF_DYN_EXTENSION_INFO_FIXED(Double, Double, DOUBLE, double);
0398 PROTOBUF_DYN_EXTENSION_INFO_FIXED(Float, Float, FLOAT, float);
0399 PROTOBUF_DYN_EXTENSION_INFO_FIXED(Bool, Bool, BOOL, bool);
0400
0401 #undef PROTOBUF_DYN_EXTENSION_INFO_VARINT
0402 #undef PROTOBUF_DYN_EXTENSION_INFO_FIXED
0403
0404
0405
0406
0407
0408 template <typename MessageT, bool is_oneof_parameter>
0409 struct EnumDynamicFieldInfo {
0410 constexpr EnumDynamicFieldInfo(const Reflection* r, MessageT& m,
0411 const FieldDescriptor* f)
0412 : reflection(r), message(m), field(f) {}
0413
0414 int number() const { return field->number(); }
0415 FieldDescriptor::Type type() const { return field->type(); }
0416
0417 int Get() const {
0418 if constexpr (is_oneof) {
0419 return reflection->GetEnumValue(message, field);
0420 } else {
0421 return DynamicFieldInfoHelper<false>::Get<int>(reflection, message,
0422 field);
0423 }
0424 }
0425 void Set(int value) { reflection->SetEnumValue(&message, field, value); }
0426 void Clear() {
0427 DynamicFieldInfoHelper<is_oneof>::ClearField(reflection, message, field);
0428 }
0429 size_t FieldByteSize() const { return WireFormatLite::EnumSize(Get()); }
0430
0431 static constexpr FieldDescriptor::CppType cpp_type =
0432 FieldDescriptor::CPPTYPE_ENUM;
0433 static constexpr bool is_repeated = false;
0434 static constexpr bool is_map = false;
0435 static constexpr bool is_extension = false;
0436 static constexpr bool is_oneof = is_oneof_parameter;
0437
0438 const Reflection* reflection;
0439 MessageT& message;
0440 const FieldDescriptor* field;
0441 };
0442
0443
0444
0445
0446 template <typename MessageT, bool is_oneof_parameter>
0447 struct StringDynamicFieldInfo {
0448 constexpr StringDynamicFieldInfo(const Reflection* r, MessageT& m,
0449 const FieldDescriptor* f)
0450 : reflection(r), message(m), field(f) {}
0451
0452 int number() const { return field->number(); }
0453 FieldDescriptor::Type type() const { return field->type(); }
0454
0455 absl::string_view Get() const {
0456 return DynamicFieldInfoHelper<is_oneof>::GetStringView(reflection, message,
0457 field);
0458 }
0459 void Set(std::string value) {
0460 reflection->SetString(&message, field, std::move(value));
0461 }
0462 void Clear() {
0463 DynamicFieldInfoHelper<is_oneof>::ClearField(reflection, message, field);
0464 }
0465 size_t FieldByteSize() const { return WireFormatLite::StringSize(Get()); }
0466
0467 static constexpr FieldDescriptor::CppType cpp_type =
0468 FieldDescriptor::CPPTYPE_STRING;
0469 static constexpr bool is_repeated = false;
0470 static constexpr bool is_map = false;
0471 static constexpr bool is_extension = false;
0472 static constexpr bool is_oneof = is_oneof_parameter;
0473 static constexpr bool is_cord = false;
0474
0475 const Reflection* reflection;
0476 MessageT& message;
0477 const FieldDescriptor* field;
0478 };
0479
0480
0481
0482
0483 template <typename ExtensionT>
0484 struct StringDynamicExtensionInfo {
0485 constexpr StringDynamicExtensionInfo(ExtensionT& e, int n)
0486 : ext(e), ext_number(n) {}
0487
0488 int number() const { return ext_number; }
0489 FieldDescriptor::Type type() const {
0490 return static_cast<FieldDescriptor::Type>(ext.type);
0491 }
0492
0493 absl::string_view Get() const {
0494 return DynamicExtensionInfoHelper::GetStringView(ext);
0495 }
0496 void Set(absl::string_view value) {
0497 DynamicExtensionInfoHelper::SetStringView(ext, value);
0498 }
0499 void Clear() { DynamicExtensionInfoHelper::ClearStringView(ext); }
0500 size_t FieldByteSize() const { return WireFormatLite::StringSize(Get()); }
0501
0502 static constexpr FieldDescriptor::CppType cpp_type =
0503 FieldDescriptor::CPPTYPE_STRING;
0504 static constexpr bool is_repeated = false;
0505 static constexpr bool is_map = false;
0506 static constexpr bool is_extension = true;
0507 static constexpr bool is_oneof = false;
0508 static constexpr bool is_cord = false;
0509
0510 ExtensionT& ext;
0511 int ext_number;
0512 };
0513
0514
0515
0516
0517 template <typename MessageT, bool is_oneof_parameter>
0518 struct CordDynamicFieldInfo {
0519 constexpr CordDynamicFieldInfo(const Reflection* r, MessageT& m,
0520 const FieldDescriptor* f)
0521 : reflection(r), message(m), field(f) {}
0522
0523 int number() const { return field->number(); }
0524 FieldDescriptor::Type type() const { return field->type(); }
0525
0526 ::absl::Cord Get() const { return reflection->GetCord(message, field); }
0527 void Set(const ::absl::Cord& value) {
0528 reflection->SetString(&message, field, value);
0529 }
0530 void Clear() {
0531 DynamicFieldInfoHelper<is_oneof>::ClearField(reflection, message, field);
0532 }
0533 size_t FieldByteSize() const { return WireFormatLite::StringSize(Get()); }
0534
0535 static constexpr FieldDescriptor::CppType cpp_type =
0536 FieldDescriptor::CPPTYPE_STRING;
0537 static constexpr bool is_repeated = false;
0538 static constexpr bool is_map = false;
0539 static constexpr bool is_extension = false;
0540 static constexpr bool is_oneof = is_oneof_parameter;
0541 static constexpr bool is_cord = true;
0542
0543 const Reflection* reflection;
0544 MessageT& message;
0545 const FieldDescriptor* field;
0546 };
0547
0548
0549
0550
0551 template <typename MessageT, bool is_oneof_parameter>
0552 struct MessageDynamicFieldInfo {
0553 constexpr MessageDynamicFieldInfo(const Reflection* r, MessageT& m,
0554 const FieldDescriptor* f)
0555 : reflection(r), message(m), field(f) {}
0556
0557 int number() const { return field->number(); }
0558 FieldDescriptor::Type type() const { return field->type(); }
0559 const Message& Get(MessageFactory* factory = nullptr) {
0560 return reflection->GetMessage(message, field, factory);
0561 }
0562 Message& Mutable(MessageFactory* factory = nullptr) {
0563 return *reflection->MutableMessage(&message, field, factory);
0564 }
0565 void Clear() { reflection->ClearField(&message, field); }
0566 size_t FieldByteSize(MessageFactory* factory = nullptr) {
0567 return Get(factory).ByteSizeLong();
0568 }
0569
0570 static constexpr FieldDescriptor::CppType cpp_type =
0571 FieldDescriptor::CPPTYPE_MESSAGE;
0572 static constexpr bool is_repeated = false;
0573 static constexpr bool is_map = false;
0574 static constexpr bool is_extension = false;
0575 static constexpr bool is_oneof = is_oneof_parameter;
0576 static constexpr bool is_lazy = false;
0577
0578 const Reflection* reflection;
0579 MessageT& message;
0580 const FieldDescriptor* field;
0581 };
0582
0583
0584
0585
0586
0587 struct SingularMessageDynamicExtensionInfo {
0588 static constexpr FieldDescriptor::CppType cpp_type =
0589 FieldDescriptor::CPPTYPE_MESSAGE;
0590 static constexpr bool is_repeated = false;
0591 static constexpr bool is_map = false;
0592 static constexpr bool is_extension = true;
0593 static constexpr bool is_oneof = false;
0594 static constexpr bool is_lazy = false;
0595 };
0596
0597 template <typename ExtensionT>
0598 struct MessageDynamicExtensionInfo : SingularMessageDynamicExtensionInfo {
0599 constexpr MessageDynamicExtensionInfo(ExtensionT& e, int n, bool mset)
0600 : ext(e), ext_number(n), is_message_set(mset) {}
0601
0602 int number() const { return ext_number; }
0603 FieldDescriptor::Type type() const {
0604 return static_cast<FieldDescriptor::Type>(ext.type);
0605 }
0606 const Message& Get() const {
0607 return DynamicExtensionInfoHelper::GetMessage(ext);
0608 }
0609 Message& Mutable() { return DynamicExtensionInfoHelper::MutableMessage(ext); }
0610 void Clear() { DynamicExtensionInfoHelper::ClearMessage(ext); }
0611 size_t FieldByteSize() const {
0612 return DynamicExtensionInfoHelper::GetMessage(ext).ByteSizeLong();
0613 }
0614
0615 ExtensionT& ext;
0616 int ext_number;
0617 bool is_message_set;
0618 };
0619
0620 template <typename ExtensionT>
0621 struct GroupDynamicExtensionInfo : SingularMessageDynamicExtensionInfo {
0622 constexpr GroupDynamicExtensionInfo(ExtensionT& e, int n)
0623 : ext(e), ext_number(n), is_message_set(false) {}
0624
0625 int number() const { return ext_number; }
0626 FieldDescriptor::Type type() const {
0627 return static_cast<FieldDescriptor::Type>(ext.type);
0628 }
0629 const Message& Get() const {
0630 return DynamicExtensionInfoHelper::GetMessage(ext);
0631 }
0632 Message& Mutable() { return DynamicExtensionInfoHelper::MutableMessage(ext); }
0633 void Clear() { DynamicExtensionInfoHelper::ClearMessage(ext); }
0634 size_t FieldByteSize() const {
0635 return DynamicExtensionInfoHelper::GetMessage(ext).ByteSizeLong();
0636 }
0637
0638 ExtensionT& ext;
0639 int ext_number;
0640 bool is_message_set;
0641 };
0642
0643 struct SingularLazyMessageDynamicExtensionInfo {
0644 static constexpr FieldDescriptor::CppType cpp_type =
0645 FieldDescriptor::CPPTYPE_MESSAGE;
0646 static constexpr bool is_repeated = false;
0647 static constexpr bool is_map = false;
0648 static constexpr bool is_extension = true;
0649 static constexpr bool is_oneof = false;
0650 static constexpr bool is_lazy = true;
0651 };
0652
0653 template <typename ExtensionT>
0654 struct LazyMessageDynamicExtensionInfo
0655 : SingularLazyMessageDynamicExtensionInfo {
0656 LazyMessageDynamicExtensionInfo(ExtensionT& e, int n, bool mset,
0657 const Message& p, Arena* a)
0658 : ext(e), ext_number(n), is_message_set(mset), prototype(p), arena(a) {}
0659
0660 int number() const { return ext_number; }
0661 FieldDescriptor::Type type() const {
0662 return static_cast<FieldDescriptor::Type>(ext.type);
0663 }
0664 const Message& Get() const {
0665 return DynamicExtensionInfoHelper::GetLazyMessage(ext, prototype, arena);
0666 }
0667 const Message& GetIgnoreUnparsed() const {
0668 return DynamicExtensionInfoHelper::GetLazyMessageIgnoreUnparsed(
0669 ext, prototype, arena);
0670 }
0671 Message& Mutable() {
0672 return DynamicExtensionInfoHelper::MutableLazyMessage(ext, prototype,
0673 arena);
0674 }
0675 void Clear() { DynamicExtensionInfoHelper::ClearLazyMessage(ext); }
0676 size_t FieldByteSize() const {
0677 return DynamicExtensionInfoHelper::ByteSizeLongLazyMessage(ext);
0678 }
0679
0680 ExtensionT& ext;
0681 int ext_number;
0682 bool is_message_set;
0683 const Message& prototype;
0684 Arena* arena;
0685 };
0686
0687
0688
0689
0690 template <typename MessageT, typename FieldT>
0691 struct RepeatedEntityDynamicFieldInfoBase {
0692 constexpr RepeatedEntityDynamicFieldInfoBase(const Reflection* r, MessageT& m,
0693 const FieldDescriptor* f,
0694 const RepeatedField<FieldT>& rep)
0695 : reflection(r), message(m), field(f), const_repeated(rep) {}
0696
0697 int number() const { return field->number(); }
0698 FieldDescriptor::Type type() const { return field->type(); }
0699 bool is_packed() const { return field->is_packed(); }
0700
0701 int size() const { return const_repeated.size(); }
0702 iterator_range<typename RepeatedField<FieldT>::const_iterator> Get() const {
0703 return {const_repeated.cbegin(), const_repeated.cend()};
0704 }
0705 iterator_range<typename RepeatedField<FieldT>::iterator> Mutable() {
0706 auto& rep =
0707 *reflection->MutableRepeatedFieldInternal<FieldT>(&message, field);
0708 return {rep.begin(), rep.end()};
0709 }
0710 void Clear() {
0711 reflection->MutableRepeatedFieldInternal<FieldT>(&message, field)->Clear();
0712 }
0713
0714 const Reflection* reflection;
0715 MessageT& message;
0716 const FieldDescriptor* field;
0717 const RepeatedField<FieldT>& const_repeated;
0718 };
0719
0720 #define PROTOBUF_DYN_FIELD_INFO_REPEATED_VARINT(NAME, CPPTYPE, FIELD_TYPE) \
0721 template <typename MessageT> \
0722 struct Repeated##NAME##DynamicFieldInfo \
0723 : RepeatedEntityDynamicFieldInfoBase<MessageT, FIELD_TYPE> { \
0724 using BaseT = RepeatedEntityDynamicFieldInfoBase<MessageT, FIELD_TYPE>; \
0725 \
0726 constexpr Repeated##NAME##DynamicFieldInfo( \
0727 const Reflection* r, MessageT& m, const FieldDescriptor* f, \
0728 const RepeatedField<FIELD_TYPE>& rep) \
0729 : BaseT(r, m, f, rep) {} \
0730 \
0731 size_t FieldByteSize() const { \
0732 size_t byte_size = 0; \
0733 for (auto it : BaseT::const_repeated) { \
0734 byte_size += WireFormatLite::NAME##Size(it); \
0735 } \
0736 return byte_size; \
0737 } \
0738 \
0739 static constexpr FieldDescriptor::CppType cpp_type = \
0740 FieldDescriptor::CPPTYPE_##CPPTYPE; \
0741 static constexpr bool is_repeated = true; \
0742 static constexpr bool is_map = false; \
0743 static constexpr bool is_extension = false; \
0744 static constexpr bool is_oneof = false; \
0745 };
0746
0747 #define PROTOBUF_DYN_FIELD_INFO_REPEATED_FIXED(NAME, CPPTYPE, FIELD_TYPE) \
0748 template <typename MessageT> \
0749 struct Repeated##NAME##DynamicFieldInfo \
0750 : RepeatedEntityDynamicFieldInfoBase<MessageT, FIELD_TYPE> { \
0751 using BaseT = RepeatedEntityDynamicFieldInfoBase<MessageT, FIELD_TYPE>; \
0752 \
0753 constexpr Repeated##NAME##DynamicFieldInfo( \
0754 const Reflection* r, MessageT& m, const FieldDescriptor* f, \
0755 const RepeatedField<FIELD_TYPE>& rep) \
0756 : BaseT(r, m, f, rep) {} \
0757 \
0758 size_t FieldByteSize() const { \
0759 return static_cast<size_t>(BaseT::size()) * \
0760 WireFormatLite::k##NAME##Size; \
0761 } \
0762 \
0763 static constexpr FieldDescriptor::CppType cpp_type = \
0764 FieldDescriptor::CPPTYPE_##CPPTYPE; \
0765 static constexpr bool is_repeated = true; \
0766 static constexpr bool is_map = false; \
0767 static constexpr bool is_extension = false; \
0768 static constexpr bool is_oneof = false; \
0769 };
0770
0771 PROTOBUF_DYN_FIELD_INFO_REPEATED_VARINT(Int32, INT32, int32_t);
0772 PROTOBUF_DYN_FIELD_INFO_REPEATED_VARINT(Int64, INT64, int64_t);
0773 PROTOBUF_DYN_FIELD_INFO_REPEATED_VARINT(UInt32, UINT32, uint32_t);
0774 PROTOBUF_DYN_FIELD_INFO_REPEATED_VARINT(UInt64, UINT64, uint64_t);
0775 PROTOBUF_DYN_FIELD_INFO_REPEATED_VARINT(SInt32, INT32, int32_t);
0776 PROTOBUF_DYN_FIELD_INFO_REPEATED_VARINT(SInt64, INT64, int64_t);
0777 PROTOBUF_DYN_FIELD_INFO_REPEATED_VARINT(Enum, ENUM, int);
0778
0779 PROTOBUF_DYN_FIELD_INFO_REPEATED_FIXED(Fixed32, UINT32, uint32_t);
0780 PROTOBUF_DYN_FIELD_INFO_REPEATED_FIXED(Fixed64, UINT64, uint64_t);
0781 PROTOBUF_DYN_FIELD_INFO_REPEATED_FIXED(SFixed32, INT32, int32_t);
0782 PROTOBUF_DYN_FIELD_INFO_REPEATED_FIXED(SFixed64, INT64, int64_t);
0783 PROTOBUF_DYN_FIELD_INFO_REPEATED_FIXED(Double, DOUBLE, double);
0784 PROTOBUF_DYN_FIELD_INFO_REPEATED_FIXED(Float, FLOAT, float);
0785 PROTOBUF_DYN_FIELD_INFO_REPEATED_FIXED(Bool, BOOL, bool);
0786
0787 #undef PROTOBUF_DYN_FIELD_INFO_REPEATED_VARINT
0788 #undef PROTOBUF_DYN_FIELD_INFO_REPEATED_FIXED
0789
0790 template <typename MessageT, typename FieldT>
0791 struct RepeatedPtrEntityDynamicFieldInfoBase {
0792 constexpr RepeatedPtrEntityDynamicFieldInfoBase(
0793 const Reflection* r, MessageT& m, const FieldDescriptor* f,
0794 const RepeatedPtrField<FieldT>& rep)
0795 : reflection(r), message(m), field(f), const_repeated(rep) {}
0796
0797 int number() const { return field->number(); }
0798 FieldDescriptor::Type type() const { return field->type(); }
0799 bool is_packed() const { return field->is_packed(); }
0800
0801 int size() const { return const_repeated.size(); }
0802 iterator_range<typename RepeatedPtrField<FieldT>::const_iterator> Get()
0803 const {
0804 return {const_repeated.cbegin(), const_repeated.cend()};
0805 }
0806 iterator_range<typename RepeatedPtrField<FieldT>::iterator> Mutable() {
0807 auto& rep =
0808 *reflection->MutableRepeatedPtrFieldInternal<FieldT>(&message, field);
0809 return {rep.begin(), rep.end()};
0810 }
0811 void Clear() {
0812 reflection->MutableRepeatedPtrFieldInternal<FieldT>(&message, field)
0813 ->Clear();
0814 }
0815
0816 const Reflection* reflection;
0817 MessageT& message;
0818 const FieldDescriptor* field;
0819 const RepeatedPtrField<FieldT>& const_repeated;
0820 };
0821
0822 template <typename MessageT, typename FieldT>
0823 struct RepeatedStringDynamicFieldInfoBase
0824 : RepeatedPtrEntityDynamicFieldInfoBase<MessageT, FieldT> {
0825 using BaseT = RepeatedPtrEntityDynamicFieldInfoBase<MessageT, FieldT>;
0826
0827 constexpr RepeatedStringDynamicFieldInfoBase(
0828 const Reflection* r, MessageT& m, const FieldDescriptor* f,
0829 const RepeatedPtrField<FieldT>& rep)
0830 : BaseT(r, m, f, rep) {}
0831 size_t FieldByteSize() const {
0832 size_t byte_size = 0;
0833 for (auto& it : BaseT::const_repeated) {
0834 byte_size += WireFormatLite::LengthDelimitedSize(it.size());
0835 }
0836 return byte_size;
0837 }
0838 };
0839
0840 template <typename MessageT>
0841 struct RepeatedStringDynamicFieldInfo
0842 : RepeatedStringDynamicFieldInfoBase<MessageT, std::string> {
0843 constexpr RepeatedStringDynamicFieldInfo(
0844 const Reflection* r, MessageT& m, const FieldDescriptor* f,
0845 const RepeatedPtrField<std::string>& rep)
0846 : RepeatedStringDynamicFieldInfoBase<MessageT, std::string>(r, m, f,
0847 rep) {}
0848
0849 static constexpr FieldDescriptor::CppType cpp_type =
0850 FieldDescriptor::CPPTYPE_STRING;
0851 static constexpr bool is_repeated = true;
0852 static constexpr bool is_map = false;
0853 static constexpr bool is_extension = false;
0854 static constexpr bool is_oneof = false;
0855 static constexpr bool is_cord = false;
0856 static constexpr bool is_string_piece = false;
0857 };
0858
0859
0860 struct RepeatedMessageDynamicFieldInfoMeta {
0861 static constexpr FieldDescriptor::CppType cpp_type =
0862 FieldDescriptor::CPPTYPE_MESSAGE;
0863 static constexpr bool is_repeated = true;
0864 static constexpr bool is_map = false;
0865 static constexpr bool is_extension = false;
0866 static constexpr bool is_oneof = false;
0867 };
0868
0869 template <typename MessageT>
0870 struct RepeatedMessageDynamicFieldInfo
0871 : RepeatedPtrEntityDynamicFieldInfoBase<MessageT, Message>,
0872 RepeatedMessageDynamicFieldInfoMeta {
0873 using BaseT = RepeatedPtrEntityDynamicFieldInfoBase<MessageT, Message>;
0874
0875 constexpr RepeatedMessageDynamicFieldInfo(
0876 const Reflection* r, MessageT& m, const FieldDescriptor* f,
0877 const RepeatedPtrField<Message>& rep)
0878 : BaseT(r, m, f, rep) {}
0879
0880 size_t FieldByteSize() const {
0881 size_t byte_size = 0;
0882 for (auto& it : BaseT::const_repeated) {
0883 byte_size += WireFormatLite::LengthDelimitedSize(it.ByteSizeLong());
0884 }
0885 return byte_size;
0886 }
0887 };
0888
0889 template <typename MessageT>
0890 struct RepeatedGroupDynamicFieldInfo
0891 : RepeatedPtrEntityDynamicFieldInfoBase<MessageT, Message>,
0892 RepeatedMessageDynamicFieldInfoMeta {
0893 using BaseT = RepeatedPtrEntityDynamicFieldInfoBase<MessageT, Message>;
0894
0895 constexpr RepeatedGroupDynamicFieldInfo(const Reflection* r, MessageT& m,
0896 const FieldDescriptor* f,
0897 const RepeatedPtrField<Message>& rep)
0898 : BaseT(r, m, f, rep) {}
0899
0900 size_t FieldByteSize() const {
0901 size_t byte_size = 0;
0902 for (auto& it : BaseT::const_repeated) {
0903 byte_size += it.ByteSizeLong();
0904 }
0905 return byte_size;
0906 }
0907 };
0908
0909
0910
0911
0912 #define PROTOBUF_DYN_EXTENSION_INFO_REPEATED_VARINT(NAME, CPPNAME, CPPTYPE, \
0913 FIELD_TYPE) \
0914 template <typename ExtensionT> \
0915 struct Repeated##NAME##DynamicExtensionInfo { \
0916 constexpr Repeated##NAME##DynamicExtensionInfo(ExtensionT& e, int n) \
0917 : ext(e), ext_number(n) {} \
0918 \
0919 int number() const { return ext_number; } \
0920 FieldDescriptor::Type type() const { \
0921 return static_cast<FieldDescriptor::Type>(ext.type); \
0922 } \
0923 bool is_packed() const { return ext.is_packed; } \
0924 \
0925 int size() const { \
0926 return DynamicExtensionInfoHelper::GetRepeated##CPPNAME(ext)->size(); \
0927 } \
0928 const RepeatedField<FIELD_TYPE>& Get() const { \
0929 return *DynamicExtensionInfoHelper::GetRepeated##CPPNAME(ext); \
0930 } \
0931 RepeatedField<FIELD_TYPE>& Mutable() { \
0932 return *DynamicExtensionInfoHelper::MutableRepeated##CPPNAME(ext); \
0933 } \
0934 void Clear() { \
0935 DynamicExtensionInfoHelper::MutableRepeated##CPPNAME(ext)->Clear(); \
0936 } \
0937 size_t FieldByteSize() const { \
0938 size_t byte_size = 0; \
0939 for (auto it : Get()) { \
0940 byte_size += WireFormatLite::NAME##Size(it); \
0941 } \
0942 return byte_size; \
0943 } \
0944 \
0945 static constexpr FieldDescriptor::CppType cpp_type = \
0946 FieldDescriptor::CPPTYPE_##CPPTYPE; \
0947 static constexpr bool is_repeated = true; \
0948 static constexpr bool is_map = false; \
0949 static constexpr bool is_extension = true; \
0950 static constexpr bool is_oneof = false; \
0951 \
0952 ExtensionT& ext; \
0953 int ext_number; \
0954 };
0955
0956 #define PROTOBUF_DYN_EXTENSION_INFO_REPEATED_FIXED(NAME, CPPNAME, CPPTYPE, \
0957 FIELD_TYPE) \
0958 template <typename ExtensionT> \
0959 struct Repeated##NAME##DynamicExtensionInfo { \
0960 constexpr Repeated##NAME##DynamicExtensionInfo(ExtensionT& e, int n) \
0961 : ext(e), ext_number(n) {} \
0962 \
0963 int number() const { return ext_number; } \
0964 FieldDescriptor::Type type() const { \
0965 return static_cast<FieldDescriptor::Type>(ext.type); \
0966 } \
0967 bool is_packed() const { return ext.is_packed; } \
0968 \
0969 int size() const { \
0970 return DynamicExtensionInfoHelper::GetRepeated##CPPNAME(ext)->size(); \
0971 } \
0972 const RepeatedField<FIELD_TYPE>& Get() const { \
0973 return *DynamicExtensionInfoHelper::GetRepeated##CPPNAME(ext); \
0974 } \
0975 RepeatedField<FIELD_TYPE>& Mutable() { \
0976 return *DynamicExtensionInfoHelper::MutableRepeated##CPPNAME(ext); \
0977 } \
0978 void Clear() { \
0979 DynamicExtensionInfoHelper::MutableRepeated##CPPNAME(ext)->Clear(); \
0980 } \
0981 size_t FieldByteSize() const { \
0982 return static_cast<size_t>(size()) * WireFormatLite::k##NAME##Size; \
0983 } \
0984 \
0985 static constexpr FieldDescriptor::CppType cpp_type = \
0986 FieldDescriptor::CPPTYPE_##CPPTYPE; \
0987 static constexpr bool is_repeated = true; \
0988 static constexpr bool is_map = false; \
0989 static constexpr bool is_extension = true; \
0990 static constexpr bool is_oneof = false; \
0991 \
0992 ExtensionT& ext; \
0993 int ext_number; \
0994 };
0995
0996 PROTOBUF_DYN_EXTENSION_INFO_REPEATED_VARINT(Int32, Int32, INT32, int32_t);
0997 PROTOBUF_DYN_EXTENSION_INFO_REPEATED_VARINT(Int64, Int64, INT64, int64_t);
0998 PROTOBUF_DYN_EXTENSION_INFO_REPEATED_VARINT(UInt32, UInt32, UINT32, uint32_t);
0999 PROTOBUF_DYN_EXTENSION_INFO_REPEATED_VARINT(UInt64, UInt64, UINT64, uint64_t);
1000 PROTOBUF_DYN_EXTENSION_INFO_REPEATED_VARINT(SInt32, Int32, INT32, int32_t);
1001 PROTOBUF_DYN_EXTENSION_INFO_REPEATED_VARINT(SInt64, Int64, INT64, int64_t);
1002 PROTOBUF_DYN_EXTENSION_INFO_REPEATED_VARINT(Enum, Enum, ENUM, int);
1003
1004 PROTOBUF_DYN_EXTENSION_INFO_REPEATED_FIXED(Fixed32, UInt32, UINT32, uint32_t);
1005 PROTOBUF_DYN_EXTENSION_INFO_REPEATED_FIXED(Fixed64, UInt64, UINT64, uint64_t);
1006 PROTOBUF_DYN_EXTENSION_INFO_REPEATED_FIXED(SFixed32, Int32, INT32, int32_t);
1007 PROTOBUF_DYN_EXTENSION_INFO_REPEATED_FIXED(SFixed64, Int64, INT64, int64_t);
1008 PROTOBUF_DYN_EXTENSION_INFO_REPEATED_FIXED(Double, Double, DOUBLE, double);
1009 PROTOBUF_DYN_EXTENSION_INFO_REPEATED_FIXED(Float, Float, FLOAT, float);
1010 PROTOBUF_DYN_EXTENSION_INFO_REPEATED_FIXED(Bool, Bool, BOOL, bool);
1011
1012 #undef PROTOBUF_DYN_EXTENSION_INFO_REPEATED_VARINT
1013 #undef PROTOBUF_DYN_EXTENSION_INFO_REPEATED_FIXED
1014
1015 template <typename ExtensionT>
1016 struct RepeatedStringDynamicExtensionInfo {
1017 constexpr RepeatedStringDynamicExtensionInfo(ExtensionT& ext, int n)
1018 : ext(ext), ext_number(n) {}
1019
1020 int number() const { return ext_number; }
1021 FieldDescriptor::Type type() const {
1022 return static_cast<FieldDescriptor::Type>(ext.type);
1023 }
1024 constexpr bool is_packed() const { return false; }
1025
1026 int size() const {
1027 return DynamicExtensionInfoHelper::GetRepeatedString(ext)->size();
1028 }
1029 const RepeatedPtrField<std::string>& Get() const {
1030 return *DynamicExtensionInfoHelper::GetRepeatedString(ext);
1031 }
1032 RepeatedPtrField<std::string>& Mutable() {
1033 return *DynamicExtensionInfoHelper::MutableRepeatedString(ext);
1034 }
1035 void Clear() {
1036 DynamicExtensionInfoHelper::MutableRepeatedString(ext)->Clear();
1037 }
1038 size_t FieldByteSize() const {
1039 size_t byte_size = 0;
1040 for (auto& it : Get()) {
1041 byte_size += WireFormatLite::LengthDelimitedSize(it.size());
1042 }
1043 return byte_size;
1044 }
1045
1046 static constexpr FieldDescriptor::CppType cpp_type =
1047 FieldDescriptor::CPPTYPE_STRING;
1048 static constexpr bool is_repeated = true;
1049 static constexpr bool is_map = false;
1050 static constexpr bool is_extension = true;
1051 static constexpr bool is_oneof = false;
1052 static constexpr bool is_cord = false;
1053 static constexpr bool is_string_piece = false;
1054
1055 ExtensionT& ext;
1056 int ext_number;
1057 };
1058
1059 template <typename ExtensionT>
1060 struct RepeatedMessageDynamicExtensionInfoBase {
1061 constexpr RepeatedMessageDynamicExtensionInfoBase(ExtensionT& e, int n)
1062 : ext(e), ext_number(n) {}
1063
1064 int number() const { return ext_number; }
1065 FieldDescriptor::Type type() const {
1066 return static_cast<FieldDescriptor::Type>(ext.type);
1067 }
1068 constexpr bool is_packed() const { return false; }
1069
1070 int size() const {
1071 return DynamicExtensionInfoHelper::GetRepeatedMessage(ext)->size();
1072 }
1073 const RepeatedPtrField<MessageLite>& Get() const {
1074 return *DynamicExtensionInfoHelper::GetRepeatedMessage(ext);
1075 }
1076 RepeatedPtrField<MessageLite>& Mutable() {
1077 return *DynamicExtensionInfoHelper::MutableRepeatedMessage(ext);
1078 }
1079 void Clear() {
1080 DynamicExtensionInfoHelper::MutableRepeatedMessage(ext)->Clear();
1081 }
1082
1083 static constexpr FieldDescriptor::CppType cpp_type =
1084 FieldDescriptor::CPPTYPE_MESSAGE;
1085 static constexpr bool is_repeated = true;
1086 static constexpr bool is_map = false;
1087 static constexpr bool is_extension = true;
1088 static constexpr bool is_oneof = false;
1089
1090 ExtensionT& ext;
1091 int ext_number;
1092 };
1093
1094 template <typename ExtensionT>
1095 struct RepeatedMessageDynamicExtensionInfo
1096 : RepeatedMessageDynamicExtensionInfoBase<ExtensionT> {
1097 using BaseT = RepeatedMessageDynamicExtensionInfoBase<ExtensionT>;
1098
1099 constexpr RepeatedMessageDynamicExtensionInfo(ExtensionT& e, int n)
1100 : BaseT(e, n) {}
1101
1102 size_t FieldByteSize() const {
1103 size_t byte_size = 0;
1104 for (auto& it : BaseT::Get()) {
1105 byte_size += WireFormatLite::LengthDelimitedSize(it.ByteSizeLong());
1106 }
1107 return byte_size;
1108 }
1109 };
1110
1111 template <typename ExtensionT>
1112 struct RepeatedGroupDynamicExtensionInfo
1113 : RepeatedMessageDynamicExtensionInfoBase<ExtensionT> {
1114 using BaseT = RepeatedMessageDynamicExtensionInfoBase<ExtensionT>;
1115
1116 constexpr RepeatedGroupDynamicExtensionInfo(ExtensionT& e, int n)
1117 : BaseT(e, n) {}
1118
1119 size_t FieldByteSize() const {
1120 size_t byte_size = 0;
1121 for (auto& it : BaseT::Get()) {
1122 byte_size += it.ByteSizeLong();
1123 }
1124 return byte_size;
1125 }
1126 };
1127
1128
1129
1130
1131
1132
1133
1134
1135 template <FieldDescriptor::CppType cpp_type, typename T>
1136 inline size_t MapPrimitiveFieldByteSize(FieldDescriptor::Type type, T value) {
1137
1138
1139
1140
1141 (void)type;
1142 (void)value;
1143
1144 if constexpr (cpp_type == FieldDescriptor::CPPTYPE_INT32) {
1145 static_assert(std::is_same_v<T, int32_t>, "type mismatch");
1146 switch (type) {
1147 case FieldDescriptor::TYPE_INT32:
1148 return WireFormatLite::Int32Size(value);
1149 case FieldDescriptor::TYPE_SINT32:
1150 return WireFormatLite::SInt32Size(value);
1151 case FieldDescriptor::TYPE_SFIXED32:
1152 return WireFormatLite::kSFixed32Size;
1153 default:
1154 Unreachable();
1155 }
1156 } else if constexpr (cpp_type == FieldDescriptor::CPPTYPE_INT64) {
1157 static_assert(std::is_same_v<T, int64_t>, "type mismatch");
1158 switch (type) {
1159 case FieldDescriptor::TYPE_INT64:
1160 return WireFormatLite::Int64Size(value);
1161 case FieldDescriptor::TYPE_SINT64:
1162 return WireFormatLite::SInt64Size(value);
1163 case FieldDescriptor::TYPE_SFIXED64:
1164 return WireFormatLite::kSFixed64Size;
1165 default:
1166 Unreachable();
1167 }
1168 } else if constexpr (cpp_type == FieldDescriptor::CPPTYPE_UINT32) {
1169 static_assert(std::is_same_v<T, uint32_t>, "type mismatch");
1170 switch (type) {
1171 case FieldDescriptor::TYPE_UINT32:
1172 return WireFormatLite::UInt32Size(value);
1173 case FieldDescriptor::TYPE_FIXED32:
1174 return WireFormatLite::kSFixed32Size;
1175 default:
1176 Unreachable();
1177 }
1178 } else if constexpr (cpp_type == FieldDescriptor::CPPTYPE_UINT64) {
1179 static_assert(std::is_same_v<T, uint64_t>, "type mismatch");
1180 switch (type) {
1181 case FieldDescriptor::TYPE_UINT64:
1182 return WireFormatLite::UInt64Size(value);
1183 case FieldDescriptor::TYPE_FIXED64:
1184 return WireFormatLite::kSFixed64Size;
1185 default:
1186 Unreachable();
1187 }
1188 } else if constexpr (cpp_type == FieldDescriptor::CPPTYPE_ENUM) {
1189 static_assert(std::is_same_v<T, int>, "type mismatch");
1190 return WireFormatLite::EnumSize(value);
1191 } else if constexpr (cpp_type == FieldDescriptor::CPPTYPE_BOOL) {
1192 static_assert(std::is_same_v<T, bool>, "type mismatch");
1193 return WireFormatLite::kBoolSize;
1194 } else if constexpr (cpp_type == FieldDescriptor::CPPTYPE_FLOAT) {
1195 static_assert(std::is_same_v<T, float>, "type mismatch");
1196 return WireFormatLite::kFloatSize;
1197 } else if constexpr (cpp_type == FieldDescriptor::CPPTYPE_DOUBLE) {
1198 static_assert(std::is_same_v<T, double>, "type mismatch");
1199 return WireFormatLite::kDoubleSize;
1200 }
1201 }
1202
1203 #define PROTOBUF_MAP_KEY_INFO(NAME, KEY_TYPE, CPPTYPE) \
1204 struct MapDynamicField##NAME##KeyInfo { \
1205 explicit MapDynamicField##NAME##KeyInfo(const MapKey& k) : key(k) { \
1206 ABSL_DCHECK_EQ(cpp_type, key.type()); \
1207 } \
1208 \
1209 KEY_TYPE Get() const { return key.Get##NAME##Value(); } \
1210
1211 \
1212 \
1213 static constexpr FieldDescriptor::CppType cpp_type = \
1214 FieldDescriptor::CPPTYPE_##CPPTYPE; \
1215 \
1216 const MapKey& key; \
1217 };
1218
1219 PROTOBUF_MAP_KEY_INFO(Int32, int32_t, INT32);
1220 PROTOBUF_MAP_KEY_INFO(Int64, int64_t, INT64);
1221 PROTOBUF_MAP_KEY_INFO(UInt32, uint32_t, UINT32);
1222 PROTOBUF_MAP_KEY_INFO(UInt64, uint64_t, UINT64);
1223 PROTOBUF_MAP_KEY_INFO(Bool, bool, BOOL);
1224 PROTOBUF_MAP_KEY_INFO(String, absl::string_view, STRING);
1225
1226 #undef PROTOBUF_MAP_KEY_INFO
1227
1228 #define PROTOBUF_MAP_VALUE_INFO(NAME, VALUE_TYPE, CPPTYPE) \
1229 template <typename MapValueRefT> \
1230 struct MapDynamicField##NAME##ValueInfo { \
1231 explicit MapDynamicField##NAME##ValueInfo(MapValueRefT& v) : value(v) { \
1232 ABSL_DCHECK_EQ(cpp_type, value.type()); \
1233 } \
1234 \
1235 VALUE_TYPE Get() const { return value.Get##NAME##Value(); } \
1236 void Set(VALUE_TYPE val) { value.Set##NAME##Value(val); } \
1237 \
1238 static constexpr FieldDescriptor::CppType cpp_type = \
1239 FieldDescriptor::CPPTYPE_##CPPTYPE; \
1240 \
1241 MapValueRefT& value; \
1242 };
1243
1244 PROTOBUF_MAP_VALUE_INFO(Int32, int32_t, INT32);
1245 PROTOBUF_MAP_VALUE_INFO(Int64, int64_t, INT64);
1246 PROTOBUF_MAP_VALUE_INFO(UInt32, uint32_t, UINT32);
1247 PROTOBUF_MAP_VALUE_INFO(UInt64, uint64_t, UINT64);
1248 PROTOBUF_MAP_VALUE_INFO(Bool, bool, BOOL);
1249 PROTOBUF_MAP_VALUE_INFO(Enum, int, ENUM);
1250 PROTOBUF_MAP_VALUE_INFO(Float, float, FLOAT);
1251 PROTOBUF_MAP_VALUE_INFO(Double, double, DOUBLE);
1252 PROTOBUF_MAP_VALUE_INFO(String, absl::string_view, STRING);
1253
1254 #undef PROTOBUF_MAP_VALUE_INFO
1255
1256 template <typename MapValueRefT>
1257 struct MapDynamicFieldMessageValueInfo {
1258 explicit constexpr MapDynamicFieldMessageValueInfo(MapValueRefT& v)
1259 : value(v) {}
1260
1261 const Message& Get() const { return value.GetMessageValue(); }
1262 Message* Mutable() { return value.MutableMessageValue(); }
1263
1264 static constexpr FieldDescriptor::CppType cpp_type =
1265 FieldDescriptor::CPPTYPE_MESSAGE;
1266
1267 MapValueRefT& value;
1268 };
1269
1270
1271
1272 template <typename MapValueRefT, typename MapValueCallback>
1273 void MapDynamicFieldVisitValue(MapValueRefT& value, MapValueCallback&& cb) {
1274 switch (value.type()) {
1275 #define PROTOBUF_HANDLE_MAP_VALUE_CASE(NAME, VALUE_TYPE, CPPTYPE) \
1276 case FieldDescriptor::CPPTYPE_##CPPTYPE: \
1277 cb(MapDynamicField##NAME##ValueInfo<MapValueRefT>{value}); \
1278 break;
1279
1280 PROTOBUF_HANDLE_MAP_VALUE_CASE(Int32, int32_t, INT32);
1281 PROTOBUF_HANDLE_MAP_VALUE_CASE(Int64, int64_t, INT64);
1282 PROTOBUF_HANDLE_MAP_VALUE_CASE(UInt32, uint32_t, UINT32);
1283 PROTOBUF_HANDLE_MAP_VALUE_CASE(UInt64, uint64_t, UINT64);
1284 PROTOBUF_HANDLE_MAP_VALUE_CASE(Bool, bool, BOOL);
1285 PROTOBUF_HANDLE_MAP_VALUE_CASE(Enum, int, ENUM);
1286 PROTOBUF_HANDLE_MAP_VALUE_CASE(Float, float, FLOAT);
1287 PROTOBUF_HANDLE_MAP_VALUE_CASE(Double, double, DOUBLE);
1288 PROTOBUF_HANDLE_MAP_VALUE_CASE(String, std::string, STRING);
1289 PROTOBUF_HANDLE_MAP_VALUE_CASE(Message, Message, MESSAGE);
1290
1291 default:
1292 internal::Unreachable();
1293
1294 #undef PROTOBUF_HANDLE_MAP_VALUE_CASE
1295 }
1296 }
1297
1298
1299
1300 template <typename MapValueRefT, typename MapFieldCallback>
1301 void MapDynamicFieldVisitKey(const MapKey& key, MapValueRefT& value,
1302 const MapFieldCallback& user_cb) {
1303 switch (key.type()) {
1304 #define PROTOBUF_HANDLE_MAP_KEY_CASE(NAME, CPPTYPE) \
1305 case FieldDescriptor::CPPTYPE_##CPPTYPE: { \
1306 auto key_info = MapDynamicField##NAME##KeyInfo{key}; \
1307 MapDynamicFieldVisitValue(value, [key_info, &user_cb](auto&& value_info) { \
1308 user_cb(key_info, value_info); \
1309 }); \
1310 break; \
1311 }
1312
1313 PROTOBUF_HANDLE_MAP_KEY_CASE(Int32, INT32);
1314 PROTOBUF_HANDLE_MAP_KEY_CASE(Int64, INT64);
1315 PROTOBUF_HANDLE_MAP_KEY_CASE(UInt32, UINT32);
1316 PROTOBUF_HANDLE_MAP_KEY_CASE(UInt64, UINT64);
1317 PROTOBUF_HANDLE_MAP_KEY_CASE(Bool, BOOL);
1318 PROTOBUF_HANDLE_MAP_KEY_CASE(String, STRING);
1319
1320 #undef PROTOBUF_HANDLE_MAP_KEY_CASE
1321
1322 default:
1323 internal::Unreachable();
1324 break;
1325 }
1326 }
1327
1328 template <typename MessageT>
1329 struct MapDynamicFieldInfo {
1330 constexpr MapDynamicFieldInfo(const Reflection* r, MessageT& m,
1331 const FieldDescriptor* f,
1332 const FieldDescriptor* key_f,
1333 const FieldDescriptor* val_f,
1334 const MapFieldBase& map_field)
1335 : reflection(r),
1336 message(m),
1337 field(f),
1338 key(key_f),
1339 value(val_f),
1340 const_map_field(map_field) {
1341 ABSL_DCHECK(f->is_map());
1342 ABSL_DCHECK_NE(key_f, nullptr);
1343 ABSL_DCHECK_NE(val_f, nullptr);
1344 }
1345
1346 int number() const { return field->number(); }
1347 FieldDescriptor::Type key_type() const { return key->type(); }
1348 FieldDescriptor::Type value_type() const { return value->type(); }
1349 int size() const { return const_map_field.size(); }
1350
1351
1352 struct Rank0 {};
1353 struct Rank1 : Rank0 {};
1354
1355
1356 template <typename T, typename Callback,
1357 typename = std::enable_if_t<!std::is_const_v<T>>>
1358 static void VisitElementsImpl(T& msg, const Reflection* reflection,
1359 const FieldDescriptor* field,
1360 const MapFieldBase&, Callback&& cb, Rank1) {
1361 auto& map_field =
1362 DynamicFieldInfoHelper<false>::template Mutable<MapFieldBase>(
1363 reflection, msg, field);
1364 const Descriptor* descriptor = field->message_type();
1365 MapIterator begin(&map_field, descriptor), end(&map_field, descriptor);
1366 map_field.MapBegin(&begin);
1367 map_field.MapEnd(&end);
1368
1369 for (auto it = begin; it != end; ++it) {
1370 MapDynamicFieldVisitKey(it.GetKey(), *it.MutableValueRef(), cb);
1371 }
1372 }
1373
1374
1375 template <typename T, typename Callback>
1376 static void VisitElementsImpl(T& msg, const Reflection*,
1377 const FieldDescriptor* field,
1378 const MapFieldBase& map_field, Callback&& cb,
1379 Rank0) {
1380 const Descriptor* descriptor = field->message_type();
1381 ConstMapIterator begin(&map_field, descriptor), end(&map_field, descriptor);
1382 map_field.ConstMapBegin(&begin);
1383 map_field.ConstMapEnd(&end);
1384
1385 for (auto it = begin; it != end; ++it) {
1386 MapDynamicFieldVisitKey(it.GetKey(), it.GetValueRef(), cb);
1387 }
1388 }
1389
1390 template <typename MapFieldCallback>
1391 void VisitElements(MapFieldCallback&& cb) const {
1392 VisitElementsImpl(message, reflection, field, const_map_field,
1393 static_cast<MapFieldCallback&&>(cb), Rank1{});
1394 }
1395
1396 void Clear() {
1397 auto& map_field =
1398 DynamicFieldInfoHelper<false>::template Mutable<MapFieldBase>(
1399 reflection, message, field);
1400
1401 map_field.Clear();
1402 }
1403
1404 static constexpr bool is_repeated = true;
1405 static constexpr bool is_packed = false;
1406 static constexpr bool is_map = true;
1407 static constexpr bool is_extension = false;
1408 static constexpr bool is_oneof = false;
1409
1410 const Reflection* reflection;
1411 MessageT& message;
1412 const FieldDescriptor* field;
1413 const FieldDescriptor* key;
1414 const FieldDescriptor* value;
1415 const MapFieldBase& const_map_field;
1416 };
1417
1418 }
1419 }
1420 }
1421
1422 #include "google/protobuf/port_undef.inc"
1423
1424 #endif