Back to home page

EIC code displayed by LXR

 
 

    


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 // clang-format off
0027 #include "google/protobuf/port_def.inc"
0028 // clang-format on
0029 
0030 namespace google {
0031 namespace protobuf {
0032 namespace internal {
0033 
0034 // A range adaptor for a pair of iterators.
0035 //
0036 // This just wraps two iterators into a range-compatible interface. Nothing
0037 // fancy at all.
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   // Returns the size of the wrapped range.  Does not participate in overload
0054   // resolution for non-random-access iterators, since in those cases this is a
0055   // slow operation (it must walk the entire range and maintain a count).
0056   //
0057   // Users who need to know the "size" of a non-random-access iterator_range
0058   // should pass the range to `absl::c_distance()` instead.
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   // Returns true if this iterator range refers to an empty sequence, and false
0068   // otherwise.
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 // Primitive fields
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 =  // NOLINT
0259       cpp_type_parameter;
0260   static constexpr bool is_repeated = false;            // NOLINT
0261   static constexpr bool is_map = false;                 // NOLINT
0262   static constexpr bool is_extension = false;           // NOLINT
0263   static constexpr bool is_oneof = is_oneof_parameter;  // NOLINT
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 // Extension primitive fields
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 // Enum fields (to handle closed enums).
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 =  // NOLINT
0432       FieldDescriptor::CPPTYPE_ENUM;
0433   static constexpr bool is_repeated = false;            // NOLINT
0434   static constexpr bool is_map = false;                 // NOLINT
0435   static constexpr bool is_extension = false;           // NOLINT
0436   static constexpr bool is_oneof = is_oneof_parameter;  // NOLINT
0437 
0438   const Reflection* reflection;
0439   MessageT& message;
0440   const FieldDescriptor* field;
0441 };
0442 
0443 ////////////////////////////////////////////////////////////////////////
0444 // String fields
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 =  // NOLINT
0468       FieldDescriptor::CPPTYPE_STRING;
0469   static constexpr bool is_repeated = false;            // NOLINT
0470   static constexpr bool is_map = false;                 // NOLINT
0471   static constexpr bool is_extension = false;           // NOLINT
0472   static constexpr bool is_oneof = is_oneof_parameter;  // NOLINT
0473   static constexpr bool is_cord = false;                // NOLINT
0474 
0475   const Reflection* reflection;
0476   MessageT& message;
0477   const FieldDescriptor* field;
0478 };
0479 
0480 ////////////////////////////////////////////////////////////////////////
0481 // Extension string fields
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 =  // NOLINT
0503       FieldDescriptor::CPPTYPE_STRING;
0504   static constexpr bool is_repeated = false;  // NOLINT
0505   static constexpr bool is_map = false;       // NOLINT
0506   static constexpr bool is_extension = true;  // NOLINT
0507   static constexpr bool is_oneof = false;     // NOLINT
0508   static constexpr bool is_cord = false;      // NOLINT
0509 
0510   ExtensionT& ext;
0511   int ext_number;
0512 };
0513 
0514 ////////////////////////////////////////////////////////////////////////
0515 // Cord fields
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 =  // NOLINT
0536       FieldDescriptor::CPPTYPE_STRING;
0537   static constexpr bool is_repeated = false;            // NOLINT
0538   static constexpr bool is_map = false;                 // NOLINT
0539   static constexpr bool is_extension = false;           // NOLINT
0540   static constexpr bool is_oneof = is_oneof_parameter;  // NOLINT
0541   static constexpr bool is_cord = true;                 // NOLINT
0542 
0543   const Reflection* reflection;
0544   MessageT& message;
0545   const FieldDescriptor* field;
0546 };
0547 
0548 ////////////////////////////////////////////////////////////////////////
0549 // Message fields
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 =  // NOLINT
0571       FieldDescriptor::CPPTYPE_MESSAGE;
0572   static constexpr bool is_repeated = false;            // NOLINT
0573   static constexpr bool is_map = false;                 // NOLINT
0574   static constexpr bool is_extension = false;           // NOLINT
0575   static constexpr bool is_oneof = is_oneof_parameter;  // NOLINT
0576   static constexpr bool is_lazy = false;                // NOLINT
0577 
0578   const Reflection* reflection;
0579   MessageT& message;
0580   const FieldDescriptor* field;
0581 };
0582 
0583 
0584 ////////////////////////////////////////////////////////////////////////
0585 // Extension message fields
0586 ////////////////////////////////////////////////////////////////////////
0587 struct SingularMessageDynamicExtensionInfo {
0588   static constexpr FieldDescriptor::CppType cpp_type =  // NOLINT
0589       FieldDescriptor::CPPTYPE_MESSAGE;
0590   static constexpr bool is_repeated = false;  // NOLINT
0591   static constexpr bool is_map = false;       // NOLINT
0592   static constexpr bool is_extension = true;  // NOLINT
0593   static constexpr bool is_oneof = false;     // NOLINT
0594   static constexpr bool is_lazy = false;      // NOLINT
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 =  // NOLINT
0645       FieldDescriptor::CPPTYPE_MESSAGE;
0646   static constexpr bool is_repeated = false;  // NOLINT
0647   static constexpr bool is_map = false;       // NOLINT
0648   static constexpr bool is_extension = true;  // NOLINT
0649   static constexpr bool is_oneof = false;     // NOLINT
0650   static constexpr bool is_lazy = true;       // NOLINT
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 // Repeated fields
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 =  // NOLINT
0850       FieldDescriptor::CPPTYPE_STRING;
0851   static constexpr bool is_repeated = true;       // NOLINT
0852   static constexpr bool is_map = false;           // NOLINT
0853   static constexpr bool is_extension = false;     // NOLINT
0854   static constexpr bool is_oneof = false;         // NOLINT
0855   static constexpr bool is_cord = false;          // NOLINT
0856   static constexpr bool is_string_piece = false;  // NOLINT
0857 };
0858 
0859 
0860 struct RepeatedMessageDynamicFieldInfoMeta {
0861   static constexpr FieldDescriptor::CppType cpp_type =  // NOLINT
0862       FieldDescriptor::CPPTYPE_MESSAGE;
0863   static constexpr bool is_repeated = true;    // NOLINT
0864   static constexpr bool is_map = false;        // NOLINT
0865   static constexpr bool is_extension = false;  // NOLINT
0866   static constexpr bool is_oneof = false;      // NOLINT
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 // Extension repeated fields
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 =  // NOLINT
1047       FieldDescriptor::CPPTYPE_STRING;
1048   static constexpr bool is_repeated = true;       // NOLINT
1049   static constexpr bool is_map = false;           // NOLINT
1050   static constexpr bool is_extension = true;      // NOLINT
1051   static constexpr bool is_oneof = false;         // NOLINT
1052   static constexpr bool is_cord = false;          // NOLINT
1053   static constexpr bool is_string_piece = false;  // NOLINT
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 =  // NOLINT
1084       FieldDescriptor::CPPTYPE_MESSAGE;
1085   static constexpr bool is_repeated = true;   // NOLINT
1086   static constexpr bool is_map = false;       // NOLINT
1087   static constexpr bool is_extension = true;  // NOLINT
1088   static constexpr bool is_oneof = false;     // NOLINT
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 // Map fields
1130 ////////////////////////////////////////////////////////////////////////
1131 
1132 // Returns the encoded size for (cpp_type, type, value). Some types are fixed
1133 // sized; while others are variable. Dispatch done here at compile time frees
1134 // users from a similar dispatch without creating KeyInfo or ValueInfo per type.
1135 template <FieldDescriptor::CppType cpp_type, typename T>
1136 inline size_t MapPrimitiveFieldByteSize(FieldDescriptor::Type type, T value) {
1137   // There is a bug in GCC 9.5 where if-constexpr arguments are not understood
1138   // if encased in a switch statement. A reproduction of the bug can be found
1139   // at: https://godbolt.org/z/qo51cKe7b
1140   // This is fixed in GCC 10.1+.
1141   (void)type;   // Suppress -Wunused-but-set-parameter
1142   (void)value;  // Suppress -Wunused-but-set-parameter
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     /* Set() API doesn't make sense because MapIter always returns const \
1211      * MapKey&. */                                                       \
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 =  // NOLINT
1265       FieldDescriptor::CPPTYPE_MESSAGE;
1266 
1267   MapValueRefT& value;
1268 };
1269 
1270 // Calls "cb" with the corresponding ValueInfo. Typically called from
1271 // MapDynamicFieldVisitKey.
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 // Dispatches based on key type to instantiate a right KeyInfo, then calls
1299 // MapDynamicFieldVisitValue to dispatch on the value type.
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   // go/ranked-overloads for the rationale.
1352   struct Rank0 {};
1353   struct Rank1 : Rank0 {};
1354 
1355   // Preferred version when "msg" is non-const.
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   // Fallback version otherwise.
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;    // NOLINT
1405   static constexpr bool is_packed = false;     // NOLINT
1406   static constexpr bool is_map = true;         // NOLINT
1407   static constexpr bool is_extension = false;  // NOLINT
1408   static constexpr bool is_oneof = false;      // NOLINT
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 }  // namespace internal
1419 }  // namespace protobuf
1420 }  // namespace google
1421 
1422 #include "google/protobuf/port_undef.inc"
1423 
1424 #endif  // GOOGLE_PROTOBUF_REFLECTION_VISIT_FIELD_INFO_H__