const char* _InternalParse(const char* ptr, internal::ParseContext* ctx) {
    // Parse a MessageSetItem
    auto metadata = reflection->MutableInternalMetadata(msg);
    enum class State { kNoTag, kHasType, kHasPayload, kDone };
    State state = State::kNoTag;

    std::string payload;
    uint32_t type_id = 0;
    while (!ctx->Done(&ptr)) {
      // We use 64 bit tags in order to allow typeid's that span the whole
      // range of 32 bit numbers.
      uint32_t tag = static_cast<uint8_t>(*ptr++);
      if (tag == WireFormatLite::kMessageSetTypeIdTag) {
        uint64_t tmp;
        ptr = ParseBigVarint(ptr, &tmp);
        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
        if (state == State::kNoTag) {
          type_id = tmp;
          state = State::kHasType;
        } else if (state == State::kHasPayload) {
          type_id = tmp;
          const FieldDescriptor* field;
          if (ctx->data().pool == nullptr) {
            field = reflection->FindKnownExtensionByNumber(type_id);
          } else {
            field =
                ctx->data().pool->FindExtensionByNumber(descriptor, type_id);
          }
          if (field == nullptr || field->message_type() == nullptr) {
            WriteLengthDelimited(
                type_id, payload,
                metadata->mutable_unknown_fields<UnknownFieldSet>());
          } else {
            Message* value =
                field->is_repeated()
                    ? reflection->AddMessage(msg, field, ctx->data().factory)
                    : reflection->MutableMessage(msg, field,
                                                 ctx->data().factory);
            const char* p;
            // We can't use regular parse from string as we have to track
            // proper recursion depth and descriptor pools.
            ParseContext tmp_ctx(ctx->depth(), false, &p, payload);
            tmp_ctx.data().pool = ctx->data().pool;
            tmp_ctx.data().factory = ctx->data().factory;
            GOOGLE_PROTOBUF_PARSER_ASSERT(value->_InternalParse(p, &tmp_ctx) &&
                                           tmp_ctx.EndedAtLimit());
          }
          state = State::kDone;
        }
        continue;
      } else if (tag == WireFormatLite::kMessageSetMessageTag) {
        if (state == State::kNoTag) {
          int32_t size = ReadSize(&ptr);
          GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
          ptr = ctx->ReadString(ptr, size, &payload);
          GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
          state = State::kHasPayload;
        } else if (state == State::kHasType) {
          // We're now parsing the payload
          const FieldDescriptor* field = nullptr;
          if (descriptor->IsExtensionNumber(type_id)) {
            if (ctx->data().pool == nullptr) {
              field = reflection->FindKnownExtensionByNumber(type_id);
            } else {
              field =
                  ctx->data().pool->FindExtensionByNumber(descriptor, type_id);
            }
          }
          ptr = WireFormat::_InternalParseAndMergeField(
              msg, ptr, ctx, static_cast<uint64_t>(type_id) * 8 + 2, reflection,
              field);
          state = State::kDone;
        } else {
          int32_t size = ReadSize(&ptr);
          GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
          ptr = ctx->Skip(ptr, size);
          GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
        }
      } else {
        // An unknown field in MessageSetItem.
        ptr = ReadTag(ptr - 1, &tag);
        if (tag == 0 || (tag & 7) == WireFormatLite::WIRETYPE_END_GROUP) {
          ctx->SetLastTag(tag);
          return ptr;
        }
        // Skip field.
        ptr = internal::UnknownFieldParse(
            tag, static_cast<std::string*>(nullptr), ptr, ctx);
      }
      GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
    }
    return ptr;
  }