Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-31 10:12:25

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