#ifndef GOOGLE_PROTOBUF_REFLECTION_VISIT_FIELD_INFO_H__
#define GOOGLE_PROTOBUF_REFLECTION_VISIT_FIELD_INFO_H__

#include <cstddef>
#include <cstdint>
#include <iterator>
#include <string>
#include <type_traits>
#include <utility>

#include "absl/log/absl_check.h"
#include "absl/strings/cord.h"
#include "absl/strings/string_view.h"
#include "google/protobuf/arenastring.h"
#include "google/protobuf/descriptor.h"
#include "google/protobuf/descriptor.pb.h"
#include "google/protobuf/extension_set.h"
#include "google/protobuf/inlined_string_field.h"
#include "google/protobuf/map_field.h"
#include "google/protobuf/message.h"
#include "google/protobuf/message_lite.h"
#include "google/protobuf/port.h"
#include "google/protobuf/wire_format_lite.h"


// clang-format off
#include "google/protobuf/port_def.inc"
// clang-format on

namespace google {
namespace protobuf {
namespace internal {

// A range adaptor for a pair of iterators.
//
// This just wraps two iterators into a range-compatible interface. Nothing
// fancy at all.
template <typename IteratorT>
class iterator_range {
 public:
  using iterator = IteratorT;
  using const_iterator = IteratorT;
  using value_type = typename std::iterator_traits<IteratorT>::value_type;

  iterator_range() : begin_iterator_(), end_iterator_() {}
  iterator_range(IteratorT begin_iterator, IteratorT end_iterator)
      : begin_iterator_(std::move(begin_iterator)),
        end_iterator_(std::move(end_iterator)) {}

  IteratorT begin() const { return begin_iterator_; }
  IteratorT end() const { return end_iterator_; }

  // Returns the size of the wrapped range.  Does not participate in overload
  // resolution for non-random-access iterators, since in those cases this is a
  // slow operation (it must walk the entire range and maintain a count).
  //
  // Users who need to know the "size" of a non-random-access iterator_range
  // should pass the range to `absl::c_distance()` instead.
  template <class It = IteratorT>
  typename std::enable_if<std::is_base_of<std::random_access_iterator_tag,
                                          typename std::iterator_traits<
                                              It>::iterator_category>::value,
                          size_t>::type
  size() const {
    return std::distance(begin_iterator_, end_iterator_);
  }
  // Returns true if this iterator range refers to an empty sequence, and false
  // otherwise.
  bool empty() const { return begin_iterator_ == end_iterator_; }

 private:
  IteratorT begin_iterator_, end_iterator_;
};

#ifdef __cpp_if_constexpr


template <bool is_oneof>
struct DynamicFieldInfoHelper {
  template <typename T>
  static T Get(const Reflection* reflection, const Message& message,
               const FieldDescriptor* field) {
    if constexpr (is_oneof) {
      return reflection->GetRaw<T>(message, field);
    } else {
      return reflection->GetRawNonOneof<T>(message, field);
    }
  }
  template <typename T>
  static T& GetRef(const Reflection* reflection, const Message& message,
                   const FieldDescriptor* field) {
    if constexpr (is_oneof) {
      return reflection->GetRaw<T>(message, field);
    } else {
      return reflection->GetRawNonOneof<T>(message, field);
    }
  }
  template <typename T>
  static T& Mutable(const Reflection* reflection, Message& message,
                    const FieldDescriptor* field) {
    if constexpr (is_oneof) {
      return *reflection->MutableRaw<T>(&message, field);
    } else {
      return *reflection->MutableRawNonOneof<T>(&message, field);
    }
  }

  static void ClearField(const Reflection* reflection, Message& message,
                         const FieldDescriptor* field) {
    if constexpr (is_oneof) {
      reflection->ClearOneofField(&message, field);
    } else {
      reflection->ClearField(&message, field);
    }
  }

  static absl::string_view GetStringView(const Reflection* reflection,
                                         const Message& message,
                                         const FieldDescriptor* field) {
    auto ctype = cpp::EffectiveStringCType(field);
    ABSL_DCHECK_NE(ctype, FieldOptions::CORD);
    ABSL_DCHECK(!is_oneof || reflection->HasOneofField(message, field));
    auto str = Get<ArenaStringPtr>(reflection, message, field);
    ABSL_DCHECK(!str.IsDefault());
    return str.Get();
  }
};

struct DynamicExtensionInfoHelper {
  using Extension = ExtensionSet::Extension;

#define PROTOBUF_SINGULAR_PRIMITIVE_METHOD(NAME, FIELD_TYPE, VAR) \
  static FIELD_TYPE Get##NAME(const Extension& ext) {             \
    return ext.VAR##_value;                                       \
  }                                                               \
  static void Set##NAME(Extension& ext, FIELD_TYPE value) {       \
    ext.VAR##_value = value;                                      \
  }                                                               \
  static void Clear##NAME(Extension& ext) { ext.is_cleared = true; }

  PROTOBUF_SINGULAR_PRIMITIVE_METHOD(Int32, int32_t, int32_t);
  PROTOBUF_SINGULAR_PRIMITIVE_METHOD(Int64, int64_t, int64_t);
  PROTOBUF_SINGULAR_PRIMITIVE_METHOD(UInt32, uint32_t, uint32_t);
  PROTOBUF_SINGULAR_PRIMITIVE_METHOD(UInt64, uint64_t, uint64_t);
  PROTOBUF_SINGULAR_PRIMITIVE_METHOD(Float, float, float);
  PROTOBUF_SINGULAR_PRIMITIVE_METHOD(Double, double, double);
  PROTOBUF_SINGULAR_PRIMITIVE_METHOD(Bool, bool, bool);
  PROTOBUF_SINGULAR_PRIMITIVE_METHOD(Enum, int, enum);

#undef PROTOBUF_SINGULAR_PRIMITIVE_METHOD

#define PROTOBUF_REPEATED_FIELD_METHODS(NAME, FIELD_TYPE, VAR)              \
  static const RepeatedField<FIELD_TYPE>* GetRepeated##NAME(                \
      const Extension& ext) {                                               \
    return ext.repeated_##VAR##_value;                                      \
  }                                                                         \
  static RepeatedField<FIELD_TYPE>* MutableRepeated##NAME(Extension& ext) { \
    return ext.repeated_##VAR##_value;                                      \
  }                                                                         \
  static void ClearRepeated##NAME(Extension& ext) {                         \
    return ext.repeated_##VAR##_value->Clear();                             \
  }

  PROTOBUF_REPEATED_FIELD_METHODS(Int32, int32_t, int32_t);
  PROTOBUF_REPEATED_FIELD_METHODS(Int64, int64_t, int64_t);
  PROTOBUF_REPEATED_FIELD_METHODS(UInt32, uint32_t, uint32_t);
  PROTOBUF_REPEATED_FIELD_METHODS(UInt64, uint64_t, uint64_t);
  PROTOBUF_REPEATED_FIELD_METHODS(Float, float, float);
  PROTOBUF_REPEATED_FIELD_METHODS(Double, double, double);
  PROTOBUF_REPEATED_FIELD_METHODS(Bool, bool, bool);
  PROTOBUF_REPEATED_FIELD_METHODS(Enum, int, enum);

#undef PROTOBUF_REPEATED_FIELD_METHODS

#define PROTOBUF_REPEATED_PTR_FIELD_METHODS(FIELD_TYPE, NAME, VAR)             \
  static const RepeatedPtrField<FIELD_TYPE>* GetRepeated##NAME(                \
      const Extension& ext) {                                                  \
    return ext.repeated_##VAR##_value;                                         \
  }                                                                            \
  static RepeatedPtrField<FIELD_TYPE>* MutableRepeated##NAME(Extension& ext) { \
    return ext.repeated_##VAR##_value;                                         \
  }                                                                            \
  static void ClearRepeated##NAME(Extension& ext) {                            \
    return ext.repeated_##VAR##_value->Clear();                                \
  }

  PROTOBUF_REPEATED_PTR_FIELD_METHODS(std::string, String, string);
  PROTOBUF_REPEATED_PTR_FIELD_METHODS(MessageLite, Message, message);

#undef PROTOBUF_REPEATED_PTR_FIELD_METHODS

  static absl::string_view GetStringView(const Extension& ext) {
    return *ext.string_value;
  }
  static void SetStringView(Extension& ext, absl::string_view value) {
    ext.string_value->assign(value.data(), value.size());
  }
  static void ClearStringView(Extension& ext) {
    ext.is_cleared = true;
    ext.string_value->clear();
  }

  static const Message& GetMessage(const Extension& ext) {
    return DownCastMessage<Message>(*ext.message_value);
  }
  static Message& MutableMessage(Extension& ext) {
    return DownCastMessage<Message>(*ext.message_value);
  }
  static void ClearMessage(Extension& ext) {
    ext.is_cleared = true;
    ext.message_value->Clear();
  }

  static const Message& GetLazyMessage(const Extension& ext,
                                       const Message& prototype, Arena* arena) {
    return DownCastMessage<Message>(
        ext.lazymessage_value->GetMessage(prototype, arena));
  }
  static const Message& GetLazyMessageIgnoreUnparsed(const Extension& ext,
                                                     const Message& prototype,
                                                     Arena* arena) {
    return DownCastMessage<Message>(
        ext.lazymessage_value->GetMessageIgnoreUnparsed(prototype, arena));
  }
  static Message& MutableLazyMessage(Extension& ext, const Message& prototype,
                                     Arena* arena) {
    return DownCastMessage<Message>(
        *ext.lazymessage_value->MutableMessage(prototype, arena));
  }
  static void ClearLazyMessage(Extension& ext) {
    ext.is_cleared = true;
    return ext.lazymessage_value->Clear();
  }
  static size_t ByteSizeLongLazyMessage(const Extension& ext) {
    return ext.lazymessage_value->ByteSizeLong();
  }
};

////////////////////////////////////////////////////////////////////////
// Primitive fields
////////////////////////////////////////////////////////////////////////
template <typename MessageT, typename FieldT,
          FieldDescriptor::CppType cpp_type_parameter, bool is_oneof_parameter>
struct SingularPrimitive {
  constexpr SingularPrimitive(const Reflection* r, MessageT& m,
                              const FieldDescriptor* f)
      : reflection(r), message(m), field(f) {}

  int number() const { return field->number(); }
  FieldDescriptor::Type type() const { return field->type(); }

  FieldT Get() const {
    return DynamicFieldInfoHelper<is_oneof>::template Get<FieldT>(
        reflection, message, field);
  }
  void Set(FieldT value) {
    DynamicFieldInfoHelper<is_oneof>::template Mutable<FieldT>(
        reflection, message, field) = value;
  }
  void Clear() {
    DynamicFieldInfoHelper<is_oneof>::ClearField(reflection, message, field);
  }

  static constexpr FieldDescriptor::CppType cpp_type =  // NOLINT
      cpp_type_parameter;
  static constexpr bool is_repeated = false;            // NOLINT
  static constexpr bool is_map = false;                 // NOLINT
  static constexpr bool is_extension = false;           // NOLINT
  static constexpr bool is_oneof = is_oneof_parameter;  // NOLINT

  const Reflection* reflection;
  MessageT& message;
  const FieldDescriptor* field;
};

#define PROTOBUF_DYN_FIELD_INFO_VARINT(NAME, CPPTYPE, FIELD_TYPE)         \
  template <typename MessageT, bool is_oneof>                             \
  struct NAME##DynamicFieldInfo                                           \
      : SingularPrimitive<MessageT, FIELD_TYPE,                           \
                          FieldDescriptor::CPPTYPE_##CPPTYPE, is_oneof> { \
    using BaseT =                                                         \
        SingularPrimitive<MessageT, FIELD_TYPE,                           \
                          FieldDescriptor::CPPTYPE_##CPPTYPE, is_oneof>;  \
                                                                          \
    constexpr NAME##DynamicFieldInfo(const Reflection* r, MessageT& m,    \
                                     const FieldDescriptor* f)            \
        : BaseT(r, m, f) {}                                               \
    size_t FieldByteSize() const {                                        \
      return WireFormatLite::NAME##Size(BaseT::Get());                    \
    }                                                                     \
  };

#define PROTOBUF_DYN_FIELD_INFO_FIXED(NAME, CPPTYPE, FIELD_TYPE)          \
  template <typename MessageT, bool is_oneof>                             \
  struct NAME##DynamicFieldInfo                                           \
      : SingularPrimitive<MessageT, FIELD_TYPE,                           \
                          FieldDescriptor::CPPTYPE_##CPPTYPE, is_oneof> { \
    using BaseT =                                                         \
        SingularPrimitive<MessageT, FIELD_TYPE,                           \
                          FieldDescriptor::CPPTYPE_##CPPTYPE, is_oneof>;  \
                                                                          \
    constexpr NAME##DynamicFieldInfo(const Reflection* r, MessageT& m,    \
                                     const FieldDescriptor* f)            \
        : BaseT(r, m, f) {}                                               \
    constexpr size_t FieldByteSize() const {                              \
      return WireFormatLite::k##NAME##Size;                               \
    }                                                                     \
  };

PROTOBUF_DYN_FIELD_INFO_VARINT(Int32, INT32, int32_t);
PROTOBUF_DYN_FIELD_INFO_VARINT(Int64, INT64, int64_t);
PROTOBUF_DYN_FIELD_INFO_VARINT(UInt32, UINT32, uint32_t);
PROTOBUF_DYN_FIELD_INFO_VARINT(UInt64, UINT64, uint64_t);
PROTOBUF_DYN_FIELD_INFO_VARINT(SInt32, INT32, int32_t);
PROTOBUF_DYN_FIELD_INFO_VARINT(SInt64, INT64, int64_t);

PROTOBUF_DYN_FIELD_INFO_FIXED(Fixed32, UINT32, uint32_t);
PROTOBUF_DYN_FIELD_INFO_FIXED(Fixed64, UINT64, uint64_t);
PROTOBUF_DYN_FIELD_INFO_FIXED(SFixed32, INT32, int32_t);
PROTOBUF_DYN_FIELD_INFO_FIXED(SFixed64, INT64, int64_t);
PROTOBUF_DYN_FIELD_INFO_FIXED(Double, DOUBLE, double);
PROTOBUF_DYN_FIELD_INFO_FIXED(Float, FLOAT, float);
PROTOBUF_DYN_FIELD_INFO_FIXED(Bool, BOOL, bool);

#undef PROTOBUF_DYN_FIELD_INFO_VARINT
#undef PROTOBUF_DYN_FIELD_INFO_FIXED

////////////////////////////////////////////////////////////////////////
// Extension primitive fields
////////////////////////////////////////////////////////////////////////
#define PROTOBUF_DYN_EXTENSION_INFO_VARINT(NAME, CPPNAME, CPPTYPE, FIELD_TYPE) \
  template <typename ExtensionT>                                               \
  struct NAME##DynamicExtensionInfo {                                          \
    constexpr NAME##DynamicExtensionInfo(ExtensionT& e, int n)                 \
        : ext(e), ext_number(n) {}                                             \
    int number() const { return ext_number; }                                  \
    FieldDescriptor::Type type() const {                                       \
      return static_cast<FieldDescriptor::Type>(ext.type);                     \
    }                                                                          \
    FIELD_TYPE Get() const {                                                   \
      return DynamicExtensionInfoHelper::Get##CPPNAME(ext);                    \
    }                                                                          \
    void Set(FIELD_TYPE value) {                                               \
      DynamicExtensionInfoHelper::Set##CPPNAME(ext, value);                    \
    }                                                                          \
    void Clear() { DynamicExtensionInfoHelper::Clear##CPPNAME(ext); }          \
    size_t FieldByteSize() const { return WireFormatLite::NAME##Size(Get()); } \
                                                                               \
    static constexpr FieldDescriptor::CppType cpp_type =                       \
        FieldDescriptor::CPPTYPE_##CPPTYPE;                                    \
    static constexpr bool is_repeated = false;                                 \
    static constexpr bool is_map = false;                                      \
    static constexpr bool is_extension = true;                                 \
    static constexpr bool is_oneof = false;                                    \
                                                                               \
    ExtensionT& ext;                                                           \
    int ext_number;                                                            \
  };

#define PROTOBUF_DYN_EXTENSION_INFO_FIXED(NAME, CPPNAME, CPPTYPE, FIELD_TYPE) \
  template <typename ExtensionT>                                              \
  struct NAME##DynamicExtensionInfo {                                         \
    constexpr NAME##DynamicExtensionInfo(ExtensionT& e, int n)                \
        : ext(e), ext_number(n) {}                                            \
    int number() const { return ext_number; }                                 \
    FieldDescriptor::Type type() const {                                      \
      return static_cast<FieldDescriptor::Type>(ext.type);                    \
    }                                                                         \
    FIELD_TYPE Get() const {                                                  \
      return DynamicExtensionInfoHelper::Get##CPPNAME(ext);                   \
    }                                                                         \
    void Set(FIELD_TYPE value) {                                              \
      DynamicExtensionInfoHelper::Set##CPPNAME(ext, value);                   \
    }                                                                         \
    void Clear() { DynamicExtensionInfoHelper::Clear##CPPNAME(ext); }         \
    constexpr size_t FieldByteSize() const {                                  \
      return WireFormatLite::k##NAME##Size;                                   \
    }                                                                         \
                                                                              \
    static constexpr FieldDescriptor::CppType cpp_type =                      \
        FieldDescriptor::CPPTYPE_##CPPTYPE;                                   \
    static constexpr bool is_repeated = false;                                \
    static constexpr bool is_map = false;                                     \
    static constexpr bool is_extension = true;                                \
    static constexpr bool is_oneof = false;                                   \
                                                                              \
    ExtensionT& ext;                                                          \
    int ext_number;                                                           \
  };

PROTOBUF_DYN_EXTENSION_INFO_VARINT(Int32, Int32, INT32, int32_t);
PROTOBUF_DYN_EXTENSION_INFO_VARINT(Int64, Int64, INT64, int64_t);
PROTOBUF_DYN_EXTENSION_INFO_VARINT(UInt32, UInt32, UINT32, uint32_t);
PROTOBUF_DYN_EXTENSION_INFO_VARINT(UInt64, UInt64, UINT64, uint64_t);
PROTOBUF_DYN_EXTENSION_INFO_VARINT(SInt32, Int32, INT32, int32_t);
PROTOBUF_DYN_EXTENSION_INFO_VARINT(SInt64, Int64, INT64, int64_t);
PROTOBUF_DYN_EXTENSION_INFO_VARINT(Enum, Enum, ENUM, int);

PROTOBUF_DYN_EXTENSION_INFO_FIXED(Fixed32, UInt32, UINT32, uint32_t);
PROTOBUF_DYN_EXTENSION_INFO_FIXED(Fixed64, UInt64, UINT64, uint64_t);
PROTOBUF_DYN_EXTENSION_INFO_FIXED(SFixed32, Int32, INT32, int32_t);
PROTOBUF_DYN_EXTENSION_INFO_FIXED(SFixed64, Int64, INT64, int64_t);
PROTOBUF_DYN_EXTENSION_INFO_FIXED(Double, Double, DOUBLE, double);
PROTOBUF_DYN_EXTENSION_INFO_FIXED(Float, Float, FLOAT, float);
PROTOBUF_DYN_EXTENSION_INFO_FIXED(Bool, Bool, BOOL, bool);

#undef PROTOBUF_DYN_EXTENSION_INFO_VARINT
#undef PROTOBUF_DYN_EXTENSION_INFO_FIXED

////////////////////////////////////////////////////////////////////////
// Enum fields (to handle closed enums).
////////////////////////////////////////////////////////////////////////

template <typename MessageT, bool is_oneof_parameter>
struct EnumDynamicFieldInfo {
  constexpr EnumDynamicFieldInfo(const Reflection* r, MessageT& m,
                                 const FieldDescriptor* f)
      : reflection(r), message(m), field(f) {}

  int number() const { return field->number(); }
  FieldDescriptor::Type type() const { return field->type(); }

  int Get() const {
    if constexpr (is_oneof) {
      return reflection->GetEnumValue(message, field);
    } else {
      return DynamicFieldInfoHelper<false>::Get<int>(reflection, message,
                                                     field);
    }
  }
  void Set(int value) { reflection->SetEnumValue(&message, field, value); }
  void Clear() {
    DynamicFieldInfoHelper<is_oneof>::ClearField(reflection, message, field);
  }
  size_t FieldByteSize() const { return WireFormatLite::EnumSize(Get()); }

  static constexpr FieldDescriptor::CppType cpp_type =  // NOLINT
      FieldDescriptor::CPPTYPE_ENUM;
  static constexpr bool is_repeated = false;            // NOLINT
  static constexpr bool is_map = false;                 // NOLINT
  static constexpr bool is_extension = false;           // NOLINT
  static constexpr bool is_oneof = is_oneof_parameter;  // NOLINT

  const Reflection* reflection;
  MessageT& message;
  const FieldDescriptor* field;
};

////////////////////////////////////////////////////////////////////////
// String fields
////////////////////////////////////////////////////////////////////////
template <typename MessageT, bool is_oneof_parameter>
struct StringDynamicFieldInfo {
  constexpr StringDynamicFieldInfo(const Reflection* r, MessageT& m,
                                   const FieldDescriptor* f)
      : reflection(r), message(m), field(f) {}

  int number() const { return field->number(); }
  FieldDescriptor::Type type() const { return field->type(); }

  absl::string_view Get() const {
    return DynamicFieldInfoHelper<is_oneof>::GetStringView(reflection, message,
                                                           field);
  }
  void Set(std::string value) {
    reflection->SetString(&message, field, std::move(value));
  }
  void Clear() {
    DynamicFieldInfoHelper<is_oneof>::ClearField(reflection, message, field);
  }
  size_t FieldByteSize() const { return WireFormatLite::StringSize(Get()); }

  static constexpr FieldDescriptor::CppType cpp_type =  // NOLINT
      FieldDescriptor::CPPTYPE_STRING;
  static constexpr bool is_repeated = false;            // NOLINT
  static constexpr bool is_map = false;                 // NOLINT
  static constexpr bool is_extension = false;           // NOLINT
  static constexpr bool is_oneof = is_oneof_parameter;  // NOLINT
  static constexpr bool is_cord = false;                // NOLINT

  const Reflection* reflection;
  MessageT& message;
  const FieldDescriptor* field;
};

////////////////////////////////////////////////////////////////////////
// Extension string fields
////////////////////////////////////////////////////////////////////////
template <typename ExtensionT>
struct StringDynamicExtensionInfo {
  constexpr StringDynamicExtensionInfo(ExtensionT& e, int n)
      : ext(e), ext_number(n) {}

  int number() const { return ext_number; }
  FieldDescriptor::Type type() const {
    return static_cast<FieldDescriptor::Type>(ext.type);
  }

  absl::string_view Get() const {
    return DynamicExtensionInfoHelper::GetStringView(ext);
  }
  void Set(absl::string_view value) {
    DynamicExtensionInfoHelper::SetStringView(ext, value);
  }
  void Clear() { DynamicExtensionInfoHelper::ClearStringView(ext); }
  size_t FieldByteSize() const { return WireFormatLite::StringSize(Get()); }

  static constexpr FieldDescriptor::CppType cpp_type =  // NOLINT
      FieldDescriptor::CPPTYPE_STRING;
  static constexpr bool is_repeated = false;  // NOLINT
  static constexpr bool is_map = false;       // NOLINT
  static constexpr bool is_extension = true;  // NOLINT
  static constexpr bool is_oneof = false;     // NOLINT
  static constexpr bool is_cord = false;      // NOLINT

  ExtensionT& ext;
  int ext_number;
};

////////////////////////////////////////////////////////////////////////
// Cord fields
////////////////////////////////////////////////////////////////////////
template <typename MessageT, bool is_oneof_parameter>
struct CordDynamicFieldInfo {
  constexpr CordDynamicFieldInfo(const Reflection* r, MessageT& m,
                                 const FieldDescriptor* f)
      : reflection(r), message(m), field(f) {}

  int number() const { return field->number(); }
  FieldDescriptor::Type type() const { return field->type(); }

  ::absl::Cord Get() const { return reflection->GetCord(message, field); }
  void Set(const ::absl::Cord& value) {
    reflection->SetString(&message, field, value);
  }
  void Clear() {
    DynamicFieldInfoHelper<is_oneof>::ClearField(reflection, message, field);
  }
  size_t FieldByteSize() const { return WireFormatLite::StringSize(Get()); }

  static constexpr FieldDescriptor::CppType cpp_type =  // NOLINT
      FieldDescriptor::CPPTYPE_STRING;
  static constexpr bool is_repeated = false;            // NOLINT
  static constexpr bool is_map = false;                 // NOLINT
  static constexpr bool is_extension = false;           // NOLINT
  static constexpr bool is_oneof = is_oneof_parameter;  // NOLINT
  static constexpr bool is_cord = true;                 // NOLINT

  const Reflection* reflection;
  MessageT& message;
  const FieldDescriptor* field;
};

////////////////////////////////////////////////////////////////////////
// Message fields
////////////////////////////////////////////////////////////////////////
template <typename MessageT, bool is_oneof_parameter>
struct MessageDynamicFieldInfo {
  constexpr MessageDynamicFieldInfo(const Reflection* r, MessageT& m,
                                    const FieldDescriptor* f)
      : reflection(r), message(m), field(f) {}

  int number() const { return field->number(); }
  FieldDescriptor::Type type() const { return field->type(); }
  const Message& Get(MessageFactory* factory = nullptr) {
    return reflection->GetMessage(message, field, factory);
  }
  Message& Mutable(MessageFactory* factory = nullptr) {
    return *reflection->MutableMessage(&message, field, factory);
  }
  void Clear() { reflection->ClearField(&message, field); }
  size_t FieldByteSize(MessageFactory* factory = nullptr) {
    return Get(factory).ByteSizeLong();
  }

  static constexpr FieldDescriptor::CppType cpp_type =  // NOLINT
      FieldDescriptor::CPPTYPE_MESSAGE;
  static constexpr bool is_repeated = false;            // NOLINT
  static constexpr bool is_map = false;                 // NOLINT
  static constexpr bool is_extension = false;           // NOLINT
  static constexpr bool is_oneof = is_oneof_parameter;  // NOLINT
  static constexpr bool is_lazy = false;                // NOLINT

  const Reflection* reflection;
  MessageT& message;
  const FieldDescriptor* field;
};


////////////////////////////////////////////////////////////////////////
// Extension message fields
////////////////////////////////////////////////////////////////////////
struct SingularMessageDynamicExtensionInfo {
  static constexpr FieldDescriptor::CppType cpp_type =  // NOLINT
      FieldDescriptor::CPPTYPE_MESSAGE;
  static constexpr bool is_repeated = false;  // NOLINT
  static constexpr bool is_map = false;       // NOLINT
  static constexpr bool is_extension = true;  // NOLINT
  static constexpr bool is_oneof = false;     // NOLINT
  static constexpr bool is_lazy = false;      // NOLINT
};

template <typename ExtensionT>
struct MessageDynamicExtensionInfo : SingularMessageDynamicExtensionInfo {
  constexpr MessageDynamicExtensionInfo(ExtensionT& e, int n, bool mset)
      : ext(e), ext_number(n), is_message_set(mset) {}

  int number() const { return ext_number; }
  FieldDescriptor::Type type() const {
    return static_cast<FieldDescriptor::Type>(ext.type);
  }
  const Message& Get() const {
    return DynamicExtensionInfoHelper::GetMessage(ext);
  }
  Message& Mutable() { return DynamicExtensionInfoHelper::MutableMessage(ext); }
  void Clear() { DynamicExtensionInfoHelper::ClearMessage(ext); }
  size_t FieldByteSize() const {
    return DynamicExtensionInfoHelper::GetMessage(ext).ByteSizeLong();
  }

  ExtensionT& ext;
  int ext_number;
  bool is_message_set;
};

template <typename ExtensionT>
struct GroupDynamicExtensionInfo : SingularMessageDynamicExtensionInfo {
  constexpr GroupDynamicExtensionInfo(ExtensionT& e, int n)
      : ext(e), ext_number(n), is_message_set(false) {}

  int number() const { return ext_number; }
  FieldDescriptor::Type type() const {
    return static_cast<FieldDescriptor::Type>(ext.type);
  }
  const Message& Get() const {
    return DynamicExtensionInfoHelper::GetMessage(ext);
  }
  Message& Mutable() { return DynamicExtensionInfoHelper::MutableMessage(ext); }
  void Clear() { DynamicExtensionInfoHelper::ClearMessage(ext); }
  size_t FieldByteSize() const {
    return DynamicExtensionInfoHelper::GetMessage(ext).ByteSizeLong();
  }

  ExtensionT& ext;
  int ext_number;
  bool is_message_set;
};

struct SingularLazyMessageDynamicExtensionInfo {
  static constexpr FieldDescriptor::CppType cpp_type =  // NOLINT
      FieldDescriptor::CPPTYPE_MESSAGE;
  static constexpr bool is_repeated = false;  // NOLINT
  static constexpr bool is_map = false;       // NOLINT
  static constexpr bool is_extension = true;  // NOLINT
  static constexpr bool is_oneof = false;     // NOLINT
  static constexpr bool is_lazy = true;       // NOLINT
};

template <typename ExtensionT>
struct LazyMessageDynamicExtensionInfo
    : SingularLazyMessageDynamicExtensionInfo {
  LazyMessageDynamicExtensionInfo(ExtensionT& e, int n, bool mset,
                                  const Message& p, Arena* a)
      : ext(e), ext_number(n), is_message_set(mset), prototype(p), arena(a) {}

  int number() const { return ext_number; }
  FieldDescriptor::Type type() const {
    return static_cast<FieldDescriptor::Type>(ext.type);
  }
  const Message& Get() const {
    return DynamicExtensionInfoHelper::GetLazyMessage(ext, prototype, arena);
  }
  const Message& GetIgnoreUnparsed() const {
    return DynamicExtensionInfoHelper::GetLazyMessageIgnoreUnparsed(
        ext, prototype, arena);
  }
  Message& Mutable() {
    return DynamicExtensionInfoHelper::MutableLazyMessage(ext, prototype,
                                                          arena);
  }
  void Clear() { DynamicExtensionInfoHelper::ClearLazyMessage(ext); }
  size_t FieldByteSize() const {
    return DynamicExtensionInfoHelper::ByteSizeLongLazyMessage(ext);
  }

  ExtensionT& ext;
  int ext_number;
  bool is_message_set;
  const Message& prototype;
  Arena* arena;
};

////////////////////////////////////////////////////////////////////////
// Repeated fields
////////////////////////////////////////////////////////////////////////
template <typename MessageT, typename FieldT>
struct RepeatedEntityDynamicFieldInfoBase {
  constexpr RepeatedEntityDynamicFieldInfoBase(const Reflection* r, MessageT& m,
                                               const FieldDescriptor* f,
                                               const RepeatedField<FieldT>& rep)
      : reflection(r), message(m), field(f), const_repeated(rep) {}

  int number() const { return field->number(); }
  FieldDescriptor::Type type() const { return field->type(); }
  bool is_packed() const { return field->is_packed(); }

  int size() const { return const_repeated.size(); }
  iterator_range<typename RepeatedField<FieldT>::const_iterator> Get() const {
    return {const_repeated.cbegin(), const_repeated.cend()};
  }
  iterator_range<typename RepeatedField<FieldT>::iterator> Mutable() {
    auto& rep = *reflection->MutableRepeatedField<FieldT>(&message, field);
    return {rep.begin(), rep.end()};
  }
  void Clear() {
    reflection->MutableRepeatedField<FieldT>(&message, field)->Clear();
  }

  const Reflection* reflection;
  MessageT& message;
  const FieldDescriptor* field;
  const RepeatedField<FieldT>& const_repeated;
};

#define PROTOBUF_DYN_FIELD_INFO_REPEATED_VARINT(NAME, CPPTYPE, FIELD_TYPE)  \
  template <typename MessageT>                                              \
  struct Repeated##NAME##DynamicFieldInfo                                   \
      : RepeatedEntityDynamicFieldInfoBase<MessageT, FIELD_TYPE> {          \
    using BaseT = RepeatedEntityDynamicFieldInfoBase<MessageT, FIELD_TYPE>; \
                                                                            \
    constexpr Repeated##NAME##DynamicFieldInfo(                             \
        const Reflection* r, MessageT& m, const FieldDescriptor* f,         \
        const RepeatedField<FIELD_TYPE>& rep)                               \
        : BaseT(r, m, f, rep) {}                                            \
                                                                            \
    size_t FieldByteSize() const {                                          \
      size_t byte_size = 0;                                                 \
      for (auto it : BaseT::const_repeated) {                               \
        byte_size += WireFormatLite::NAME##Size(it);                        \
      }                                                                     \
      return byte_size;                                                     \
    }                                                                       \
                                                                            \
    static constexpr FieldDescriptor::CppType cpp_type =                    \
        FieldDescriptor::CPPTYPE_##CPPTYPE;                                 \
    static constexpr bool is_repeated = true;                               \
    static constexpr bool is_map = false;                                   \
    static constexpr bool is_extension = false;                             \
    static constexpr bool is_oneof = false;                                 \
  };

#define PROTOBUF_DYN_FIELD_INFO_REPEATED_FIXED(NAME, CPPTYPE, FIELD_TYPE)   \
  template <typename MessageT>                                              \
  struct Repeated##NAME##DynamicFieldInfo                                   \
      : RepeatedEntityDynamicFieldInfoBase<MessageT, FIELD_TYPE> {          \
    using BaseT = RepeatedEntityDynamicFieldInfoBase<MessageT, FIELD_TYPE>; \
                                                                            \
    constexpr Repeated##NAME##DynamicFieldInfo(                             \
        const Reflection* r, MessageT& m, const FieldDescriptor* f,         \
        const RepeatedField<FIELD_TYPE>& rep)                               \
        : BaseT(r, m, f, rep) {}                                            \
                                                                            \
    size_t FieldByteSize() const {                                          \
      return static_cast<size_t>(BaseT::size()) *                           \
             WireFormatLite::k##NAME##Size;                                 \
    }                                                                       \
                                                                            \
    static constexpr FieldDescriptor::CppType cpp_type =                    \
        FieldDescriptor::CPPTYPE_##CPPTYPE;                                 \
    static constexpr bool is_repeated = true;                               \
    static constexpr bool is_map = false;                                   \
    static constexpr bool is_extension = false;                             \
    static constexpr bool is_oneof = false;                                 \
  };

PROTOBUF_DYN_FIELD_INFO_REPEATED_VARINT(Int32, INT32, int32_t);
PROTOBUF_DYN_FIELD_INFO_REPEATED_VARINT(Int64, INT64, int64_t);
PROTOBUF_DYN_FIELD_INFO_REPEATED_VARINT(UInt32, UINT32, uint32_t);
PROTOBUF_DYN_FIELD_INFO_REPEATED_VARINT(UInt64, UINT64, uint64_t);
PROTOBUF_DYN_FIELD_INFO_REPEATED_VARINT(SInt32, INT32, int32_t);
PROTOBUF_DYN_FIELD_INFO_REPEATED_VARINT(SInt64, INT64, int64_t);
PROTOBUF_DYN_FIELD_INFO_REPEATED_VARINT(Enum, ENUM, int);

PROTOBUF_DYN_FIELD_INFO_REPEATED_FIXED(Fixed32, UINT32, uint32_t);
PROTOBUF_DYN_FIELD_INFO_REPEATED_FIXED(Fixed64, UINT64, uint64_t);
PROTOBUF_DYN_FIELD_INFO_REPEATED_FIXED(SFixed32, INT32, int32_t);
PROTOBUF_DYN_FIELD_INFO_REPEATED_FIXED(SFixed64, INT64, int64_t);
PROTOBUF_DYN_FIELD_INFO_REPEATED_FIXED(Double, DOUBLE, double);
PROTOBUF_DYN_FIELD_INFO_REPEATED_FIXED(Float, FLOAT, float);
PROTOBUF_DYN_FIELD_INFO_REPEATED_FIXED(Bool, BOOL, bool);

#undef PROTOBUF_DYN_FIELD_INFO_REPEATED_VARINT
#undef PROTOBUF_DYN_FIELD_INFO_REPEATED_FIXED

template <typename MessageT, typename FieldT>
struct RepeatedPtrEntityDynamicFieldInfoBase {
  constexpr RepeatedPtrEntityDynamicFieldInfoBase(
      const Reflection* r, MessageT& m, const FieldDescriptor* f,
      const RepeatedPtrField<FieldT>& rep)
      : reflection(r), message(m), field(f), const_repeated(rep) {}

  int number() const { return field->number(); }
  FieldDescriptor::Type type() const { return field->type(); }
  bool is_packed() const { return field->is_packed(); }

  int size() const { return const_repeated.size(); }
  iterator_range<typename RepeatedPtrField<FieldT>::const_iterator> Get()
      const {
    return {const_repeated.cbegin(), const_repeated.cend()};
  }
  iterator_range<typename RepeatedPtrField<FieldT>::iterator> Mutable() {
    auto& rep = *reflection->MutableRepeatedPtrField<FieldT>(&message, field);
    return {rep.begin(), rep.end()};
  }
  void Clear() {
    reflection->MutableRepeatedPtrField<FieldT>(&message, field)->Clear();
  }

  const Reflection* reflection;
  MessageT& message;
  const FieldDescriptor* field;
  const RepeatedPtrField<FieldT>& const_repeated;
};

template <typename MessageT, typename FieldT>
struct RepeatedStringDynamicFieldInfoBase
    : RepeatedPtrEntityDynamicFieldInfoBase<MessageT, FieldT> {
  using BaseT = RepeatedPtrEntityDynamicFieldInfoBase<MessageT, FieldT>;

  constexpr RepeatedStringDynamicFieldInfoBase(
      const Reflection* r, MessageT& m, const FieldDescriptor* f,
      const RepeatedPtrField<FieldT>& rep)
      : BaseT(r, m, f, rep) {}
  size_t FieldByteSize() const {
    size_t byte_size = 0;
    for (auto& it : BaseT::const_repeated) {
      byte_size += WireFormatLite::LengthDelimitedSize(it.size());
    }
    return byte_size;
  }
};

template <typename MessageT>
struct RepeatedStringDynamicFieldInfo
    : RepeatedStringDynamicFieldInfoBase<MessageT, std::string> {
  constexpr RepeatedStringDynamicFieldInfo(
      const Reflection* r, MessageT& m, const FieldDescriptor* f,
      const RepeatedPtrField<std::string>& rep)
      : RepeatedStringDynamicFieldInfoBase<MessageT, std::string>(r, m, f,
                                                                  rep) {}

  static constexpr FieldDescriptor::CppType cpp_type =  // NOLINT
      FieldDescriptor::CPPTYPE_STRING;
  static constexpr bool is_repeated = true;       // NOLINT
  static constexpr bool is_map = false;           // NOLINT
  static constexpr bool is_extension = false;     // NOLINT
  static constexpr bool is_oneof = false;         // NOLINT
  static constexpr bool is_cord = false;          // NOLINT
  static constexpr bool is_string_piece = false;  // NOLINT
};


struct RepeatedMessageDynamicFieldInfoMeta {
  static constexpr FieldDescriptor::CppType cpp_type =  // NOLINT
      FieldDescriptor::CPPTYPE_MESSAGE;
  static constexpr bool is_repeated = true;    // NOLINT
  static constexpr bool is_map = false;        // NOLINT
  static constexpr bool is_extension = false;  // NOLINT
  static constexpr bool is_oneof = false;      // NOLINT
};

template <typename MessageT>
struct RepeatedMessageDynamicFieldInfo
    : RepeatedPtrEntityDynamicFieldInfoBase<MessageT, Message>,
      RepeatedMessageDynamicFieldInfoMeta {
  using BaseT = RepeatedPtrEntityDynamicFieldInfoBase<MessageT, Message>;

  constexpr RepeatedMessageDynamicFieldInfo(
      const Reflection* r, MessageT& m, const FieldDescriptor* f,
      const RepeatedPtrField<Message>& rep)
      : BaseT(r, m, f, rep) {}

  size_t FieldByteSize() const {
    size_t byte_size = 0;
    for (auto& it : BaseT::const_repeated) {
      byte_size += WireFormatLite::LengthDelimitedSize(it.ByteSizeLong());
    }
    return byte_size;
  }
};

template <typename MessageT>
struct RepeatedGroupDynamicFieldInfo
    : RepeatedPtrEntityDynamicFieldInfoBase<MessageT, Message>,
      RepeatedMessageDynamicFieldInfoMeta {
  using BaseT = RepeatedPtrEntityDynamicFieldInfoBase<MessageT, Message>;

  constexpr RepeatedGroupDynamicFieldInfo(const Reflection* r, MessageT& m,
                                          const FieldDescriptor* f,
                                          const RepeatedPtrField<Message>& rep)
      : BaseT(r, m, f, rep) {}

  size_t FieldByteSize() const {
    size_t byte_size = 0;
    for (auto& it : BaseT::const_repeated) {
      byte_size += it.ByteSizeLong();
    }
    return byte_size;
  }
};

////////////////////////////////////////////////////////////////////////
// Extension repeated fields
////////////////////////////////////////////////////////////////////////
#define PROTOBUF_DYN_EXTENSION_INFO_REPEATED_VARINT(NAME, CPPNAME, CPPTYPE, \
                                                    FIELD_TYPE)             \
  template <typename ExtensionT>                                            \
  struct Repeated##NAME##DynamicExtensionInfo {                             \
    constexpr Repeated##NAME##DynamicExtensionInfo(ExtensionT& e, int n)    \
        : ext(e), ext_number(n) {}                                          \
                                                                            \
    int number() const { return ext_number; }                               \
    FieldDescriptor::Type type() const {                                    \
      return static_cast<FieldDescriptor::Type>(ext.type);                  \
    }                                                                       \
    bool is_packed() const { return ext.is_packed; }                        \
                                                                            \
    int size() const {                                                      \
      return DynamicExtensionInfoHelper::GetRepeated##CPPNAME(ext)->size(); \
    }                                                                       \
    const RepeatedField<FIELD_TYPE>& Get() const {                          \
      return *DynamicExtensionInfoHelper::GetRepeated##CPPNAME(ext);        \
    }                                                                       \
    RepeatedField<FIELD_TYPE>& Mutable() {                                  \
      return *DynamicExtensionInfoHelper::MutableRepeated##CPPNAME(ext);    \
    }                                                                       \
    void Clear() {                                                          \
      DynamicExtensionInfoHelper::MutableRepeated##CPPNAME(ext)->Clear();   \
    }                                                                       \
    size_t FieldByteSize() const {                                          \
      size_t byte_size = 0;                                                 \
      for (auto it : Get()) {                                               \
        byte_size += WireFormatLite::NAME##Size(it);                        \
      }                                                                     \
      return byte_size;                                                     \
    }                                                                       \
                                                                            \
    static constexpr FieldDescriptor::CppType cpp_type =                    \
        FieldDescriptor::CPPTYPE_##CPPTYPE;                                 \
    static constexpr bool is_repeated = true;                               \
    static constexpr bool is_map = false;                                   \
    static constexpr bool is_extension = true;                              \
    static constexpr bool is_oneof = false;                                 \
                                                                            \
    ExtensionT& ext;                                                        \
    int ext_number;                                                         \
  };

#define PROTOBUF_DYN_EXTENSION_INFO_REPEATED_FIXED(NAME, CPPNAME, CPPTYPE,  \
                                                   FIELD_TYPE)              \
  template <typename ExtensionT>                                            \
  struct Repeated##NAME##DynamicExtensionInfo {                             \
    constexpr Repeated##NAME##DynamicExtensionInfo(ExtensionT& e, int n)    \
        : ext(e), ext_number(n) {}                                          \
                                                                            \
    int number() const { return ext_number; }                               \
    FieldDescriptor::Type type() const {                                    \
      return static_cast<FieldDescriptor::Type>(ext.type);                  \
    }                                                                       \
    bool is_packed() const { return ext.is_packed; }                        \
                                                                            \
    int size() const {                                                      \
      return DynamicExtensionInfoHelper::GetRepeated##CPPNAME(ext)->size(); \
    }                                                                       \
    const RepeatedField<FIELD_TYPE>& Get() const {                          \
      return *DynamicExtensionInfoHelper::GetRepeated##CPPNAME(ext);        \
    }                                                                       \
    RepeatedField<FIELD_TYPE>& Mutable() {                                  \
      return *DynamicExtensionInfoHelper::MutableRepeated##CPPNAME(ext);    \
    }                                                                       \
    void Clear() {                                                          \
      DynamicExtensionInfoHelper::MutableRepeated##CPPNAME(ext)->Clear();   \
    }                                                                       \
    size_t FieldByteSize() const {                                          \
      return static_cast<size_t>(size()) * WireFormatLite::k##NAME##Size;   \
    }                                                                       \
                                                                            \
    static constexpr FieldDescriptor::CppType cpp_type =                    \
        FieldDescriptor::CPPTYPE_##CPPTYPE;                                 \
    static constexpr bool is_repeated = true;                               \
    static constexpr bool is_map = false;                                   \
    static constexpr bool is_extension = true;                              \
    static constexpr bool is_oneof = false;                                 \
                                                                            \
    ExtensionT& ext;                                                        \
    int ext_number;                                                         \
  };

PROTOBUF_DYN_EXTENSION_INFO_REPEATED_VARINT(Int32, Int32, INT32, int32_t);
PROTOBUF_DYN_EXTENSION_INFO_REPEATED_VARINT(Int64, Int64, INT64, int64_t);
PROTOBUF_DYN_EXTENSION_INFO_REPEATED_VARINT(UInt32, UInt32, UINT32, uint32_t);
PROTOBUF_DYN_EXTENSION_INFO_REPEATED_VARINT(UInt64, UInt64, UINT64, uint64_t);
PROTOBUF_DYN_EXTENSION_INFO_REPEATED_VARINT(SInt32, Int32, INT32, int32_t);
PROTOBUF_DYN_EXTENSION_INFO_REPEATED_VARINT(SInt64, Int64, INT64, int64_t);
PROTOBUF_DYN_EXTENSION_INFO_REPEATED_VARINT(Enum, Enum, ENUM, int);

PROTOBUF_DYN_EXTENSION_INFO_REPEATED_FIXED(Fixed32, UInt32, UINT32, uint32_t);
PROTOBUF_DYN_EXTENSION_INFO_REPEATED_FIXED(Fixed64, UInt64, UINT64, uint64_t);
PROTOBUF_DYN_EXTENSION_INFO_REPEATED_FIXED(SFixed32, Int32, INT32, int32_t);
PROTOBUF_DYN_EXTENSION_INFO_REPEATED_FIXED(SFixed64, Int64, INT64, int64_t);
PROTOBUF_DYN_EXTENSION_INFO_REPEATED_FIXED(Double, Double, DOUBLE, double);
PROTOBUF_DYN_EXTENSION_INFO_REPEATED_FIXED(Float, Float, FLOAT, float);
PROTOBUF_DYN_EXTENSION_INFO_REPEATED_FIXED(Bool, Bool, BOOL, bool);

#undef PROTOBUF_DYN_EXTENSION_INFO_REPEATED_VARINT
#undef PROTOBUF_DYN_EXTENSION_INFO_REPEATED_FIXED

template <typename ExtensionT>
struct RepeatedStringDynamicExtensionInfo {
  constexpr RepeatedStringDynamicExtensionInfo(ExtensionT& ext, int n)
      : ext(ext), ext_number(n) {}

  int number() const { return ext_number; }
  FieldDescriptor::Type type() const {
    return static_cast<FieldDescriptor::Type>(ext.type);
  }
  constexpr bool is_packed() const { return false; }

  int size() const {
    return DynamicExtensionInfoHelper::GetRepeatedString(ext)->size();
  }
  const RepeatedPtrField<std::string>& Get() const {
    return *DynamicExtensionInfoHelper::GetRepeatedString(ext);
  }
  RepeatedPtrField<std::string>& Mutable() {
    return *DynamicExtensionInfoHelper::MutableRepeatedString(ext);
  }
  void Clear() {
    DynamicExtensionInfoHelper::MutableRepeatedString(ext)->Clear();
  }
  size_t FieldByteSize() const {
    size_t byte_size = 0;
    for (auto& it : Get()) {
      byte_size += WireFormatLite::LengthDelimitedSize(it.size());
    }
    return byte_size;
  }

  static constexpr FieldDescriptor::CppType cpp_type =  // NOLINT
      FieldDescriptor::CPPTYPE_STRING;
  static constexpr bool is_repeated = true;       // NOLINT
  static constexpr bool is_map = false;           // NOLINT
  static constexpr bool is_extension = true;      // NOLINT
  static constexpr bool is_oneof = false;         // NOLINT
  static constexpr bool is_cord = false;          // NOLINT
  static constexpr bool is_string_piece = false;  // NOLINT

  ExtensionT& ext;
  int ext_number;
};

template <typename ExtensionT>
struct RepeatedMessageDynamicExtensionInfoBase {
  constexpr RepeatedMessageDynamicExtensionInfoBase(ExtensionT& e, int n)
      : ext(e), ext_number(n) {}

  int number() const { return ext_number; }
  FieldDescriptor::Type type() const {
    return static_cast<FieldDescriptor::Type>(ext.type);
  }
  constexpr bool is_packed() const { return false; }

  int size() const {
    return DynamicExtensionInfoHelper::GetRepeatedMessage(ext)->size();
  }
  const RepeatedPtrField<MessageLite>& Get() const {
    return *DynamicExtensionInfoHelper::GetRepeatedMessage(ext);
  }
  RepeatedPtrField<MessageLite>& Mutable() {
    return *DynamicExtensionInfoHelper::MutableRepeatedMessage(ext);
  }
  void Clear() {
    DynamicExtensionInfoHelper::MutableRepeatedMessage(ext)->Clear();
  }

  static constexpr FieldDescriptor::CppType cpp_type =  // NOLINT
      FieldDescriptor::CPPTYPE_MESSAGE;
  static constexpr bool is_repeated = true;   // NOLINT
  static constexpr bool is_map = false;       // NOLINT
  static constexpr bool is_extension = true;  // NOLINT
  static constexpr bool is_oneof = false;     // NOLINT

  ExtensionT& ext;
  int ext_number;
};

template <typename ExtensionT>
struct RepeatedMessageDynamicExtensionInfo
    : RepeatedMessageDynamicExtensionInfoBase<ExtensionT> {
  using BaseT = RepeatedMessageDynamicExtensionInfoBase<ExtensionT>;

  constexpr RepeatedMessageDynamicExtensionInfo(ExtensionT& e, int n)
      : BaseT(e, n) {}

  size_t FieldByteSize() const {
    size_t byte_size = 0;
    for (auto& it : BaseT::Get()) {
      byte_size += WireFormatLite::LengthDelimitedSize(it.ByteSizeLong());
    }
    return byte_size;
  }
};

template <typename ExtensionT>
struct RepeatedGroupDynamicExtensionInfo
    : RepeatedMessageDynamicExtensionInfoBase<ExtensionT> {
  using BaseT = RepeatedMessageDynamicExtensionInfoBase<ExtensionT>;

  constexpr RepeatedGroupDynamicExtensionInfo(ExtensionT& e, int n)
      : BaseT(e, n) {}

  size_t FieldByteSize() const {
    size_t byte_size = 0;
    for (auto& it : BaseT::Get()) {
      byte_size += it.ByteSizeLong();
    }
    return byte_size;
  }
};

////////////////////////////////////////////////////////////////////////
// Map fields
////////////////////////////////////////////////////////////////////////

// Returns the encoded size for (cpp_type, type, value). Some types are fixed
// sized; while others are variable. Dispatch done here at compile time frees
// users from a similar dispatch without creating KeyInfo or ValueInfo per type.
template <FieldDescriptor::CppType cpp_type, typename T>
inline size_t MapPrimitiveFieldByteSize(FieldDescriptor::Type type, T value) {
  if constexpr (cpp_type == FieldDescriptor::CPPTYPE_INT32) {
    static_assert(std::is_same_v<T, int32_t>, "type mismatch");
    switch (type) {
      case FieldDescriptor::TYPE_INT32:
        return WireFormatLite::Int32Size(value);
      case FieldDescriptor::TYPE_SINT32:
        return WireFormatLite::SInt32Size(value);
      case FieldDescriptor::TYPE_SFIXED32:
        return WireFormatLite::kSFixed32Size;
      default:
        Unreachable();
    }
  } else if constexpr (cpp_type == FieldDescriptor::CPPTYPE_INT64) {
    static_assert(std::is_same_v<T, int64_t>, "type mismatch");
    switch (type) {
      case FieldDescriptor::TYPE_INT64:
        return WireFormatLite::Int64Size(value);
      case FieldDescriptor::TYPE_SINT64:
        return WireFormatLite::SInt64Size(value);
      case FieldDescriptor::TYPE_SFIXED64:
        return WireFormatLite::kSFixed64Size;
      default:
        Unreachable();
    }
  } else if constexpr (cpp_type == FieldDescriptor::CPPTYPE_UINT32) {
    static_assert(std::is_same_v<T, uint32_t>, "type mismatch");
    switch (type) {
      case FieldDescriptor::TYPE_UINT32:
        return WireFormatLite::UInt32Size(value);
      case FieldDescriptor::TYPE_FIXED32:
        return WireFormatLite::kSFixed32Size;
      default:
        Unreachable();
    }
  } else if constexpr (cpp_type == FieldDescriptor::CPPTYPE_UINT64) {
    static_assert(std::is_same_v<T, uint64_t>, "type mismatch");
    switch (type) {
      case FieldDescriptor::TYPE_UINT64:
        return WireFormatLite::UInt64Size(value);
      case FieldDescriptor::TYPE_FIXED64:
        return WireFormatLite::kSFixed64Size;
      default:
        Unreachable();
    }
  } else if constexpr (cpp_type == FieldDescriptor::CPPTYPE_ENUM) {
    static_assert(std::is_same_v<T, int>, "type mismatch");
    return WireFormatLite::EnumSize(value);
  } else if constexpr (cpp_type == FieldDescriptor::CPPTYPE_BOOL) {
    static_assert(std::is_same_v<T, bool>, "type mismatch");
    return WireFormatLite::kBoolSize;
  } else if constexpr (cpp_type == FieldDescriptor::CPPTYPE_FLOAT) {
    static_assert(std::is_same_v<T, float>, "type mismatch");
    return WireFormatLite::kFloatSize;
  } else if constexpr (cpp_type == FieldDescriptor::CPPTYPE_DOUBLE) {
    static_assert(std::is_same_v<T, double>, "type mismatch");
    return WireFormatLite::kDoubleSize;
  }
}

#define PROTOBUF_MAP_KEY_INFO(NAME, KEY_TYPE, CPPTYPE)                   \
  struct MapDynamicField##NAME##KeyInfo {                                \
    explicit MapDynamicField##NAME##KeyInfo(const MapKey& k) : key(k) {  \
      ABSL_DCHECK_EQ(cpp_type, key.type());                              \
    }                                                                    \
                                                                         \
    KEY_TYPE Get() const { return key.Get##NAME##Value(); }              \
    /* Set() API doesn't make sense because MapIter always returns const \
     * MapKey&. */                                                       \
                                                                         \
    static constexpr FieldDescriptor::CppType cpp_type =                 \
        FieldDescriptor::CPPTYPE_##CPPTYPE;                              \
                                                                         \
    const MapKey& key;                                                   \
  };

PROTOBUF_MAP_KEY_INFO(Int32, int32_t, INT32);
PROTOBUF_MAP_KEY_INFO(Int64, int64_t, INT64);
PROTOBUF_MAP_KEY_INFO(UInt32, uint32_t, UINT32);
PROTOBUF_MAP_KEY_INFO(UInt64, uint64_t, UINT64);
PROTOBUF_MAP_KEY_INFO(Bool, bool, BOOL);
PROTOBUF_MAP_KEY_INFO(String, const std::string&, STRING);

#undef PROTOBUF_MAP_KEY_INFO

#define PROTOBUF_MAP_VALUE_INFO(NAME, VALUE_TYPE, CPPTYPE)                  \
  template <typename MapValueRefT>                                          \
  struct MapDynamicField##NAME##ValueInfo {                                 \
    explicit MapDynamicField##NAME##ValueInfo(MapValueRefT& v) : value(v) { \
      ABSL_DCHECK_EQ(cpp_type, value.type());                               \
    }                                                                       \
                                                                            \
    VALUE_TYPE Get() const { return value.Get##NAME##Value(); }             \
    void Set(VALUE_TYPE val) { value.Set##NAME##Value(val); }               \
                                                                            \
    static constexpr FieldDescriptor::CppType cpp_type =                    \
        FieldDescriptor::CPPTYPE_##CPPTYPE;                                 \
                                                                            \
    MapValueRefT& value;                                                    \
  };

PROTOBUF_MAP_VALUE_INFO(Int32, int32_t, INT32);
PROTOBUF_MAP_VALUE_INFO(Int64, int64_t, INT64);
PROTOBUF_MAP_VALUE_INFO(UInt32, uint32_t, UINT32);
PROTOBUF_MAP_VALUE_INFO(UInt64, uint64_t, UINT64);
PROTOBUF_MAP_VALUE_INFO(Bool, bool, BOOL);
PROTOBUF_MAP_VALUE_INFO(Enum, int, ENUM);
PROTOBUF_MAP_VALUE_INFO(Float, float, FLOAT);
PROTOBUF_MAP_VALUE_INFO(Double, double, DOUBLE);
PROTOBUF_MAP_VALUE_INFO(String, const std::string&, STRING);

#undef PROTOBUF_MAP_VALUE_INFO

template <typename MapValueRefT>
struct MapDynamicFieldMessageValueInfo {
  explicit constexpr MapDynamicFieldMessageValueInfo(MapValueRefT& v)
      : value(v) {}

  const Message& Get() const { return value.GetMessageValue(); }
  Message* Mutable() { return value.MutableMessageValue(); }

  static constexpr FieldDescriptor::CppType cpp_type =  // NOLINT
      FieldDescriptor::CPPTYPE_MESSAGE;

  MapValueRefT& value;
};

// Calls "cb" with the corresponding ValueInfo. Typically called from
// MapDynamicFieldVisitKey.
template <typename MapValueRefT, typename MapValueCallback>
void MapDynamicFieldVisitValue(MapValueRefT& value, MapValueCallback&& cb) {
  switch (value.type()) {
#define PROTOBUF_HANDLE_MAP_VALUE_CASE(NAME, VALUE_TYPE, CPPTYPE) \
  case FieldDescriptor::CPPTYPE_##CPPTYPE:                        \
    cb(MapDynamicField##NAME##ValueInfo<MapValueRefT>{value});    \
    break;

    PROTOBUF_HANDLE_MAP_VALUE_CASE(Int32, int32_t, INT32);
    PROTOBUF_HANDLE_MAP_VALUE_CASE(Int64, int64_t, INT64);
    PROTOBUF_HANDLE_MAP_VALUE_CASE(UInt32, uint32_t, UINT32);
    PROTOBUF_HANDLE_MAP_VALUE_CASE(UInt64, uint64_t, UINT64);
    PROTOBUF_HANDLE_MAP_VALUE_CASE(Bool, bool, BOOL);
    PROTOBUF_HANDLE_MAP_VALUE_CASE(Enum, int, ENUM);
    PROTOBUF_HANDLE_MAP_VALUE_CASE(Float, float, FLOAT);
    PROTOBUF_HANDLE_MAP_VALUE_CASE(Double, double, DOUBLE);
    PROTOBUF_HANDLE_MAP_VALUE_CASE(String, std::string, STRING);
    PROTOBUF_HANDLE_MAP_VALUE_CASE(Message, Message, MESSAGE);

    default:
      internal::Unreachable();

#undef PROTOBUF_HANDLE_MAP_VALUE_CASE
  }
}

// Dispatches based on key type to instantiate a right KeyInfo, then calls
// MapDynamicFieldVisitValue to dispatch on the value type.
template <typename MapValueRefT, typename MapFieldCallback>
void MapDynamicFieldVisitKey(const MapKey& key, MapValueRefT& value,
                             const MapFieldCallback& user_cb) {
  switch (key.type()) {
#define PROTOBUF_HANDLE_MAP_KEY_CASE(NAME, CPPTYPE)                            \
  case FieldDescriptor::CPPTYPE_##CPPTYPE: {                                   \
    auto key_info = MapDynamicField##NAME##KeyInfo{key};                       \
    MapDynamicFieldVisitValue(value, [key_info, &user_cb](auto&& value_info) { \
      user_cb(key_info, value_info);                                           \
    });                                                                        \
    break;                                                                     \
  }

    PROTOBUF_HANDLE_MAP_KEY_CASE(Int32, INT32);
    PROTOBUF_HANDLE_MAP_KEY_CASE(Int64, INT64);
    PROTOBUF_HANDLE_MAP_KEY_CASE(UInt32, UINT32);
    PROTOBUF_HANDLE_MAP_KEY_CASE(UInt64, UINT64);
    PROTOBUF_HANDLE_MAP_KEY_CASE(Bool, BOOL);
    PROTOBUF_HANDLE_MAP_KEY_CASE(String, STRING);

#undef PROTOBUF_HANDLE_MAP_KEY_CASE

    default:
      internal::Unreachable();
      break;
  }
}

template <typename MessageT>
struct MapDynamicFieldInfo {
  constexpr MapDynamicFieldInfo(const Reflection* r, MessageT& m,
                                const FieldDescriptor* f,
                                const FieldDescriptor* key_f,
                                const FieldDescriptor* val_f,
                                const MapFieldBase& map_field)
      : reflection(r),
        message(m),
        field(f),
        key(key_f),
        value(val_f),
        const_map_field(map_field) {
    ABSL_DCHECK(f->is_map());
    ABSL_DCHECK_NE(key_f, nullptr);
    ABSL_DCHECK_NE(val_f, nullptr);
  }

  int number() const { return field->number(); }
  FieldDescriptor::Type key_type() const { return key->type(); }
  FieldDescriptor::Type value_type() const { return value->type(); }
  int size() const { return const_map_field.size(); }

  // go/ranked-overloads for the rationale.
  struct Rank0 {};
  struct Rank1 : Rank0 {};

  // Preferred version when "msg" is non-const.
  template <typename T, typename Callback,
            typename = std::enable_if_t<!std::is_const_v<T>>>
  static void VisitElementsImpl(T& msg, const Reflection* reflection,
                                const FieldDescriptor* field,
                                const MapFieldBase&, Callback&& cb, Rank1) {
    auto& map_field =
        DynamicFieldInfoHelper<false>::template Mutable<MapFieldBase>(
            reflection, msg, field);
    const Descriptor* descriptor = field->message_type();
    MapIterator begin(&map_field, descriptor), end(&map_field, descriptor);
    map_field.MapBegin(&begin);
    map_field.MapEnd(&end);

    for (auto it = begin; it != end; ++it) {
      MapDynamicFieldVisitKey(it.GetKey(), *it.MutableValueRef(), cb);
    }
  }

  // Fallback version otherwise.
  template <typename T, typename Callback>
  static void VisitElementsImpl(T& msg, const Reflection*,
                                const FieldDescriptor* field,
                                const MapFieldBase& const_map_field,
                                Callback&& cb, Rank0) {
    // Unfortunately, we have to const_cast here because MapIterator only takes
    // a mutable MapFieldBase pointer. This is still safe because value iterator
    // is not mutable.
    MapFieldBase* map_field = const_cast<MapFieldBase*>(&const_map_field);
    const Descriptor* descriptor = field->message_type();
    MapIterator begin(map_field, descriptor), end(map_field, descriptor);
    const_map_field.MapBegin(&begin);
    const_map_field.MapEnd(&end);

    for (auto it = begin; it != end; ++it) {
      MapDynamicFieldVisitKey(it.GetKey(), it.GetValueRef(), cb);
    }
  }

  template <typename MapFieldCallback>
  void VisitElements(MapFieldCallback&& cb) const {
    VisitElementsImpl(message, reflection, field, const_map_field,
                      static_cast<MapFieldCallback&&>(cb), Rank1{});
  }

  void Clear() {
    auto& map_field =
        DynamicFieldInfoHelper<false>::template Mutable<MapFieldBase>(
            reflection, message, field);

    map_field.Clear();
  }

  static constexpr bool is_repeated = true;    // NOLINT
  static constexpr bool is_packed = false;     // NOLINT
  static constexpr bool is_map = true;         // NOLINT
  static constexpr bool is_extension = false;  // NOLINT
  static constexpr bool is_oneof = false;      // NOLINT

  const Reflection* reflection;
  MessageT& message;
  const FieldDescriptor* field;
  const FieldDescriptor* key;
  const FieldDescriptor* value;
  const MapFieldBase& const_map_field;
};

#endif  // __cpp_if_constexpr

}  // namespace internal
}  // namespace protobuf
}  // namespace google

#include "google/protobuf/port_undef.inc"

#endif  // GOOGLE_PROTOBUF_REFLECTION_VISIT_FIELD_INFO_H__
