// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc.  All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//     * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#ifndef GOOGLE_PROTOBUF_GENERATED_MESSAGE_TABLE_DRIVEN_LITE_H__
#define GOOGLE_PROTOBUF_GENERATED_MESSAGE_TABLE_DRIVEN_LITE_H__

#include <google/protobuf/generated_message_table_driven.h>

#include <google/protobuf/stubs/type_traits.h>

#include <google/protobuf/io/zero_copy_stream_impl_lite.h>
#include <google/protobuf/extension_set.h>
#include <google/protobuf/metadata_lite.h>
#include <google/protobuf/repeated_field.h>
#include <google/protobuf/wire_format_lite.h>
#include <google/protobuf/wire_format_lite_inl.h>


namespace google {
namespace protobuf {
namespace internal {


enum StringType {
  StringType_STRING = 0,
  StringType_CORD = 1,
  StringType_STRING_PIECE = 2
};

// Logically a superset of StringType, consisting of all field types that
// require special initialization.
enum ProcessingType {
  ProcessingType_STRING = 0,
  ProcessingType_CORD = 1,
  ProcessingType_STRING_PIECE = 2,
  ProcessingType_MESSAGE = 3
};

enum Cardinality {
  Cardinality_SINGULAR = 0,
  Cardinality_REPEATED = 1,
  Cardinality_ONEOF = 3
};

template <typename Type>
inline Type* Raw(MessageLite* msg, int64 offset) {
  return reinterpret_cast<Type*>(reinterpret_cast<uint8*>(msg) + offset);
}

template <typename Type>
inline const Type* Raw(const MessageLite* msg, int64 offset) {
  return reinterpret_cast<const Type*>(reinterpret_cast<const uint8*>(msg) +
                                       offset);
}

template <typename InternalMetadata>
inline Arena* GetArena(MessageLite* msg, int64 arena_offset) {
  if (GOOGLE_PREDICT_FALSE(arena_offset == -1)) {
    return NULL;
  }

  return Raw<InternalMetadata>(msg, arena_offset)->arena();
}

inline ExtensionSet* GetExtensionSet(MessageLite* msg, int64 extension_offset) {
  if (extension_offset == -1) {
    return NULL;
  }

  return Raw<ExtensionSet>(msg, extension_offset);
}

template <typename Type>
inline Type* AddField(MessageLite* msg, int64 offset) {
#if LANG_CXX11
  static_assert(has_trivial_copy<Type>::value,
                "Do not assign");
#endif

  google::protobuf::RepeatedField<Type>* repeated =
      Raw<google::protobuf::RepeatedField<Type> >(msg, offset);
  return repeated->Add();
}

template <>
inline string* AddField<string>(MessageLite* msg, int64 offset) {
  google::protobuf::RepeatedPtrField<string>* repeated =
      Raw<google::protobuf::RepeatedPtrField<string> >(msg, offset);
  return repeated->Add();
}


template <typename Type>
inline void AddField(MessageLite* msg, int64 offset, Type value) {
#if LANG_CXX11
  static_assert(has_trivial_copy<Type>::value,
                "Do not assign");
#endif
  *AddField<Type>(msg, offset) = value;
}

inline void SetBit(uint32* has_bits, uint32 has_bit_index) {
  GOOGLE_DCHECK(has_bits != NULL);

  uint32 mask = static_cast<uint32>(1u) << (has_bit_index % 32);
  has_bits[has_bit_index / 32u] |= mask;
}

template <typename Type>
inline Type* MutableField(MessageLite* msg, uint32* has_bits,
                          uint32 has_bit_index, int64 offset) {
  SetBit(has_bits, has_bit_index);
  return Raw<Type>(msg, offset);
}

template <typename Type>
inline void SetField(MessageLite* msg, uint32* has_bits, uint32 has_bit_index,
                     int64 offset, Type value) {
#if LANG_CXX11
  static_assert(has_trivial_copy<Type>::value,
                "Do not assign");
#endif
  *MutableField<Type>(msg, has_bits, has_bit_index, offset) = value;
}

template <typename Type>
inline void SetOneofField(MessageLite* msg, uint32* oneof_case,
                          uint32 oneof_case_index, int64 offset,
                          int field_number, Type value) {
  oneof_case[oneof_case_index] = field_number;
  *Raw<Type>(msg, offset) = value;
}

// Clears a oneof field. The field argument should correspond to the particular
// field that is currently set in the oneof.
inline void ClearOneofField(const ParseTableField& field, Arena* arena,
                     MessageLite* msg) {
  switch (field.processing_type & kTypeMask) {
    case WireFormatLite::TYPE_MESSAGE:
      if (arena == NULL) {
        delete *Raw<MessageLite*>(msg, field.offset);
      }
      break;

    case WireFormatLite::TYPE_STRING:
    case WireFormatLite::TYPE_BYTES:
      Raw<ArenaStringPtr>(msg, field.offset)
          ->Destroy(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), arena);
      break;

    default:
      // No cleanup needed.
      break;
  }
}

// Clears and reinitializes a oneof field as necessary, in preparation for
// parsing a new value with type field_type and field number field_number.
//
// Note: the oneof_case argument should point directly to the _oneof_case_
// element corresponding to this particular oneof, not to the beginning of the
// _oneof_case_ array.
template <ProcessingType field_type>
inline void ResetOneofField(const ParseTable& table, int field_number,
                            Arena* arena, MessageLite* msg, uint32* oneof_case,
                            int64 offset, const void* default_ptr) {
  if (*oneof_case == field_number) {
    // The oneof is already set to the right type, so there is no need to clear
    // it.
    return;
  }

  if (*oneof_case != 0) {
    ClearOneofField(table.fields[*oneof_case], arena, msg);
  }
  *oneof_case = field_number;

  switch (field_type) {
    case ProcessingType_STRING:
      Raw<ArenaStringPtr>(msg, offset)
          ->UnsafeSetDefault(static_cast<const string*>(default_ptr));
      break;
    case ProcessingType_MESSAGE:
      MessageLite** submessage = Raw<MessageLite*>(msg, offset);
      const MessageLite* prototype =
          table.aux[field_number].messages.default_message();
      *submessage = prototype->New(arena);
      break;
  }
}

template <Cardinality cardinality, bool validate, StringType ctype>
static inline bool HandleString(io::CodedInputStream* input, MessageLite* msg,
                                Arena* arena, uint32* has_bits,
                                uint32 has_bit_index, int64 offset,
                                const void* default_ptr,
                                const char* field_name) {
#ifdef GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED
  const char* sdata;
  size_t size;
#endif

    string* value;
    switch (cardinality) {
      case Cardinality_SINGULAR:
        // TODO(ckennelly): Is this optimal?
        value =
            MutableField<ArenaStringPtr>(msg, has_bits, has_bit_index, offset)
                ->Mutable(static_cast<const string*>(default_ptr), arena);
        break;
      case Cardinality_REPEATED:
        value = AddField<string>(msg, offset);
        break;
      case Cardinality_ONEOF:
        value = Raw<ArenaStringPtr>(msg, offset)
                    ->Mutable(static_cast<const string*>(default_ptr), arena);
        break;
    }
    GOOGLE_DCHECK(value != NULL);

    if (GOOGLE_PREDICT_FALSE(!WireFormatLite::ReadString(input, value))) {
      return false;
    }

#ifdef GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED
    sdata = value->data();
    size = value->size();
#endif

#ifdef GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED
  if (validate) {
    WireFormatLite::VerifyUtf8String(sdata, size, WireFormatLite::PARSE,
                                     field_name);
  }
#endif

  return true;
}

template <typename UnknownFieldHandler, typename InternalMetadata,
          Cardinality cardinality>
inline bool HandleEnum(const ParseTable& table, io::CodedInputStream* input,
                       MessageLite* msg, uint32* presence,
                       uint32 presence_index, int64 offset, uint32 tag,
                       int field_number) {
  int value;
  if (GOOGLE_PREDICT_FALSE(
          (!WireFormatLite::ReadPrimitive<int, WireFormatLite::TYPE_ENUM>(
              input, &value)))) {
    return false;
  }

  AuxillaryParseTableField::EnumValidator validator =
      table.aux[field_number].enums.validator;
  if (validator(value)) {
    switch (cardinality) {
      case Cardinality_SINGULAR:
        SetField(msg, presence, presence_index, offset, value);
        break;
      case Cardinality_REPEATED:
        AddField(msg, offset, value);
        break;
      case Cardinality_ONEOF:
        ClearOneofField(table.fields[presence[presence_index]],
                        GetArena<InternalMetadata>(msg, table.arena_offset),
                        msg);
        SetOneofField(msg, presence, presence_index, offset, field_number,
                      value);
        break;
    }
  } else {
    UnknownFieldHandler::Varint(msg, table, tag, value);
  }

  return true;
}

// RepeatedMessageTypeHandler allows us to operate on RepeatedPtrField fields
// without instantiating the specific template.
class RepeatedMessageTypeHandler {
 public:
  typedef MessageLite Type;
  static Arena* GetArena(Type* t) { return t->GetArena(); }
  static void* GetMaybeArenaPointer(Type* t) {
    return t->GetMaybeArenaPointer();
  }
  static inline Type* NewFromPrototype(const Type* prototype,
                                       Arena* arena = NULL) {
    return prototype->New(arena);
  }
  static void Delete(Type* t, Arena* arena = NULL) {
    if (arena == NULL) {
      delete t;
    }
  }
};

inline bool ReadGroup(int field_number, io::CodedInputStream* input,
                      MessageLite* value) {
  if (GOOGLE_PREDICT_FALSE(!input->IncrementRecursionDepth())) {
    return false;
  }

  if (GOOGLE_PREDICT_FALSE(!value->MergePartialFromCodedStream(input))) {
    return false;
  }

  input->DecrementRecursionDepth();
  // Make sure the last thing read was an end tag for this group.
  if (GOOGLE_PREDICT_FALSE(!input->LastTagWas(WireFormatLite::MakeTag(
          field_number, WireFormatLite::WIRETYPE_END_GROUP)))) {
    return false;
  }

  return true;
}

inline bool ReadMessage(io::CodedInputStream* input, MessageLite* value) {
  int length;
  if (GOOGLE_PREDICT_FALSE(!input->ReadVarintSizeAsInt(&length))) {
    return false;
  }

  std::pair<io::CodedInputStream::Limit, int> p =
      input->IncrementRecursionDepthAndPushLimit(length);
  if (GOOGLE_PREDICT_FALSE(p.second < 0 ||
                    !value->MergePartialFromCodedStream(input))) {
    return false;
  }

  // Make sure that parsing stopped when the limit was hit, not at an endgroup
  // tag.
  return input->DecrementRecursionDepthAndPopLimit(p.first);
}

class MergePartialFromCodedStreamHelper {
 public:
  static MessageLite* Add(RepeatedPtrFieldBase* field,
                          const MessageLite* prototype) {
    return field->Add<RepeatedMessageTypeHandler>(
        const_cast<MessageLite*>(prototype));
  }
};

template <typename UnknownFieldHandler, typename InternalMetadata>
bool MergePartialFromCodedStreamImpl(MessageLite* msg, const ParseTable& table,
                                     io::CodedInputStream* input) {
  // We require that has_bits are present, as to avoid having to check for them
  // for every field.
  //
  // TODO(ckennelly):  Make this a compile-time parameter with templates.
  GOOGLE_DCHECK_GE(table.has_bits_offset, 0);
  uint32* has_bits = Raw<uint32>(msg, table.has_bits_offset);
  GOOGLE_DCHECK(has_bits != NULL);

  while (true) {
    uint32 tag = input->ReadTag();

    const WireFormatLite::WireType wire_type =
        WireFormatLite::GetTagWireType(tag);
    const int field_number = WireFormatLite::GetTagFieldNumber(tag);

    if (field_number > table.max_field_number) {
      // check for possible extensions
      if (UnknownFieldHandler::ParseExtension(msg, table, input, tag)) {
        // successfully parsed
        continue;
      }

      if (GOOGLE_PREDICT_FALSE(!UnknownFieldHandler::Skip(msg, table, input, tag))) {
        return false;
      }

      continue;
    }

    // We implicitly verify that data points to a valid field as we check the
    // wire types.  Entries in table.fields[i] that do not correspond to valid
    // field numbers have their normal_wiretype and packed_wiretype fields set
    // with the kInvalidMask value.  As wire_type cannot take on that value, we
    // will never match.
    const ParseTableField* data = table.fields + field_number;

    // TODO(ckennelly): Avoid sign extension
    const int64 presence_index = data->presence_index;
    const int64 offset = data->offset;
    const unsigned char processing_type = data->processing_type;

    if (data->normal_wiretype == static_cast<unsigned char>(wire_type)) {
      // TODO(ckennelly): Use a computed goto on GCC/LLVM or otherwise eliminate
      // the bounds check on processing_type.

      switch (processing_type) {
#define HANDLE_TYPE(TYPE, CPPTYPE)                                             \
  case (WireFormatLite::TYPE_##TYPE): {                                        \
    CPPTYPE value;                                                             \
    if (GOOGLE_PREDICT_FALSE(                                                         \
            (!WireFormatLite::ReadPrimitive<                                   \
                CPPTYPE, WireFormatLite::TYPE_##TYPE>(input, &value)))) {      \
      return false;                                                            \
    }                                                                          \
    SetField(msg, has_bits, presence_index, offset, value);                    \
    break;                                                                     \
  }                                                                            \
  case (WireFormatLite::TYPE_##TYPE) | kRepeatedMask: {                        \
    google::protobuf::RepeatedField<CPPTYPE>* values =                                   \
        Raw<google::protobuf::RepeatedField<CPPTYPE> >(msg, offset);                     \
    if (GOOGLE_PREDICT_FALSE((!WireFormatLite::ReadRepeatedPrimitive<                 \
                       CPPTYPE, WireFormatLite::TYPE_##TYPE>(                  \
            data->tag_size, tag, input, values)))) {                           \
      return false;                                                            \
    }                                                                          \
    break;                                                                     \
  }                                                                            \
  case (WireFormatLite::TYPE_##TYPE) | kOneofMask: {                           \
    uint32* oneof_case = Raw<uint32>(msg, table.oneof_case_offset);            \
    CPPTYPE value;                                                             \
    if (GOOGLE_PREDICT_FALSE(                                                         \
            (!WireFormatLite::ReadPrimitive<                                   \
                CPPTYPE, WireFormatLite::TYPE_##TYPE>(input, &value)))) {      \
      return false;                                                            \
    }                                                                          \
    ClearOneofField(table.fields[oneof_case[presence_index]],                  \
                    GetArena<InternalMetadata>(msg, table.arena_offset), msg); \
    SetOneofField(msg, oneof_case, presence_index, offset, field_number,       \
                  value);                                                      \
    break;                                                                     \
  }

        HANDLE_TYPE(INT32, int32)
        HANDLE_TYPE(INT64, int64)
        HANDLE_TYPE(SINT32, int32)
        HANDLE_TYPE(SINT64, int64)
        HANDLE_TYPE(UINT32, uint32)
        HANDLE_TYPE(UINT64, uint64)

        HANDLE_TYPE(FIXED32, uint32)
        HANDLE_TYPE(FIXED64, uint64)
        HANDLE_TYPE(SFIXED32, int32)
        HANDLE_TYPE(SFIXED64, int64)

        HANDLE_TYPE(FLOAT, float)
        HANDLE_TYPE(DOUBLE, double)

        HANDLE_TYPE(BOOL, bool)
#undef HANDLE_TYPE
        case WireFormatLite::TYPE_BYTES:
#ifndef GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED
        case WireFormatLite::TYPE_STRING:
#endif
        {
          Arena* const arena =
              GetArena<InternalMetadata>(msg, table.arena_offset);
          const void* default_ptr = table.aux[field_number].strings.default_ptr;

          if (GOOGLE_PREDICT_FALSE((
                  !HandleString<Cardinality_SINGULAR, false, StringType_STRING>(
                      input, msg, arena, has_bits, presence_index, offset,
                      default_ptr, NULL)))) {
            return false;
          }
          break;
        }
        case WireFormatLite::TYPE_BYTES | kOneofMask:
#ifndef GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED
        case WireFormatLite::TYPE_STRING | kOneofMask:
#endif
        {
          Arena* const arena =
              GetArena<InternalMetadata>(msg, table.arena_offset);
          uint32* oneof_case = Raw<uint32>(msg, table.oneof_case_offset);
          const void* default_ptr = table.aux[field_number].strings.default_ptr;

          ResetOneofField<ProcessingType_STRING>(
              table, field_number, arena, msg, oneof_case + presence_index,
              offset, default_ptr);

          if (GOOGLE_PREDICT_FALSE(
                  (!HandleString<Cardinality_ONEOF, false, StringType_STRING>(
                      input, msg, arena, has_bits, presence_index, offset,
                      default_ptr, NULL)))) {
            return false;
          }
          break;
        }
        case (WireFormatLite::TYPE_BYTES) | kRepeatedMask:
#ifndef GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED
        case (WireFormatLite::TYPE_STRING) | kRepeatedMask:
#endif
        {
          Arena* const arena =
              GetArena<InternalMetadata>(msg, table.arena_offset);
          const void* default_ptr =
              table.aux[field_number].strings.default_ptr;

          if (GOOGLE_PREDICT_FALSE((
                  !HandleString<Cardinality_REPEATED, false, StringType_STRING>(
                      input, msg, arena, has_bits, presence_index, offset,
                      default_ptr, NULL)))) {
            return false;
          }
          break;
        }
#ifdef GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED
        case (WireFormatLite::TYPE_STRING): {
          Arena* const arena =
              GetArena<InternalMetadata>(msg, table.arena_offset);
          const void* default_ptr = table.aux[field_number].strings.default_ptr;
          const char* field_name = table.aux[field_number].strings.field_name;

          if (GOOGLE_PREDICT_FALSE(
                  (!HandleString<Cardinality_SINGULAR, true, StringType_STRING>(
                      input, msg, arena, has_bits, presence_index, offset,
                      default_ptr, field_name)))) {
            return false;
          }
          break;
        }
        case (WireFormatLite::TYPE_STRING) | kRepeatedMask: {
          Arena* const arena =
              GetArena<InternalMetadata>(msg, table.arena_offset);
          const void* default_ptr = table.aux[field_number].strings.default_ptr;
          const char* field_name = table.aux[field_number].strings.field_name;

          if (GOOGLE_PREDICT_FALSE(
                  (!HandleString<Cardinality_REPEATED, true, StringType_STRING>(
                      input, msg, arena, has_bits, presence_index, offset,
                      default_ptr, field_name)))) {
            return false;
          }
          break;
        }
        case (WireFormatLite::TYPE_STRING) | kOneofMask: {
          Arena* const arena =
              GetArena<InternalMetadata>(msg, table.arena_offset);
          uint32* oneof_case = Raw<uint32>(msg, table.oneof_case_offset);
          const void* default_ptr = table.aux[field_number].strings.default_ptr;
          const char* field_name = table.aux[field_number].strings.field_name;

          ResetOneofField<ProcessingType_STRING>(
              table, field_number, arena, msg, oneof_case + presence_index,
              offset, default_ptr);

          if (GOOGLE_PREDICT_FALSE(
                  (!HandleString<Cardinality_ONEOF, true, StringType_STRING>(
                      input, msg, arena, has_bits, presence_index, offset,
                      default_ptr, field_name)))) {
            return false;
          }
          break;
        }
#endif
        case WireFormatLite::TYPE_ENUM: {
          if (GOOGLE_PREDICT_FALSE((!HandleEnum<UnknownFieldHandler, InternalMetadata,
                                         Cardinality_SINGULAR>(
                  table, input, msg, has_bits, presence_index, offset, tag,
                  field_number)))) {
            return false;
          }
          break;
        }
        case WireFormatLite::TYPE_ENUM | kRepeatedMask: {
          if (GOOGLE_PREDICT_FALSE((!HandleEnum<UnknownFieldHandler, InternalMetadata,
                                         Cardinality_REPEATED>(
                  table, input, msg, has_bits, presence_index, offset, tag,
                  field_number)))) {
            return false;
          }
          break;
        }
        case WireFormatLite::TYPE_ENUM | kOneofMask: {
          uint32* oneof_case = Raw<uint32>(msg, table.oneof_case_offset);
          if (GOOGLE_PREDICT_FALSE((!HandleEnum<UnknownFieldHandler, InternalMetadata,
                                         Cardinality_ONEOF>(
                  table, input, msg, oneof_case, presence_index, offset, tag,
                  field_number)))) {
            return false;
          }
          break;
        }
        case WireFormatLite::TYPE_GROUP: {
          MessageLite** submsg_holder =
              MutableField<MessageLite*>(msg, has_bits, presence_index, offset);
          MessageLite* submsg = *submsg_holder;

          if (submsg == NULL) {
            Arena* const arena =
                GetArena<InternalMetadata>(msg, table.arena_offset);
            const MessageLite* prototype =
                table.aux[field_number].messages.default_message();
            submsg = prototype->New(arena);
            *submsg_holder = submsg;
          }

          if (GOOGLE_PREDICT_FALSE(!WireFormatLite::ReadGroup(
              field_number, input, submsg))) {
            return false;
          }

          break;
        }
        case WireFormatLite::TYPE_GROUP | kRepeatedMask: {
          RepeatedPtrFieldBase* field = Raw<RepeatedPtrFieldBase>(msg, offset);
          const MessageLite* prototype =
              table.aux[field_number].messages.default_message();
          GOOGLE_DCHECK(prototype != NULL);

          MessageLite* submsg =
              MergePartialFromCodedStreamHelper::Add(field, prototype);

          if (GOOGLE_PREDICT_FALSE(!WireFormatLite::ReadGroup(
              field_number, input, submsg))) {
            return false;
          }

          break;
        }
        case WireFormatLite::TYPE_MESSAGE: {
          MessageLite** submsg_holder =
              MutableField<MessageLite*>(msg, has_bits, presence_index, offset);
          MessageLite* submsg = *submsg_holder;

          if (submsg == NULL) {
            Arena* const arena =
                GetArena<InternalMetadata>(msg, table.arena_offset);
            const MessageLite* prototype =
                table.aux[field_number].messages.default_message();
            submsg = prototype->New(arena);
            *submsg_holder = submsg;
          }

          if (GOOGLE_PREDICT_FALSE(!WireFormatLite::ReadMessage(input, submsg))) {
            return false;
          }

          break;
        }
        // TODO(ckennelly):  Adapt ReadMessageNoVirtualNoRecursionDepth and
        // manage input->IncrementRecursionDepth() here.
        case WireFormatLite::TYPE_MESSAGE | kRepeatedMask: {
          RepeatedPtrFieldBase* field = Raw<RepeatedPtrFieldBase>(msg, offset);
          const MessageLite* prototype =
              table.aux[field_number].messages.default_message();
          GOOGLE_DCHECK(prototype != NULL);

          MessageLite* submsg =
              MergePartialFromCodedStreamHelper::Add(field, prototype);

          if (GOOGLE_PREDICT_FALSE(!WireFormatLite::ReadMessage(input, submsg))) {
            return false;
          }

          break;
        }
        case WireFormatLite::TYPE_MESSAGE | kOneofMask: {
          Arena* const arena =
              GetArena<InternalMetadata>(msg, table.arena_offset);
          uint32* oneof_case = Raw<uint32>(msg, table.oneof_case_offset);
          MessageLite** submsg_holder = Raw<MessageLite*>(msg, offset);
          ResetOneofField<ProcessingType_MESSAGE>(
              table, field_number, arena, msg, oneof_case + presence_index,
              offset, NULL);
          MessageLite* submsg = *submsg_holder;

          if (GOOGLE_PREDICT_FALSE(!WireFormatLite::ReadMessage(input, submsg))) {
            return false;
          }

          break;
        }
        case TYPE_MAP: {
          if (GOOGLE_PREDICT_FALSE(!(*table.aux[field_number].maps.parse_map)(
                  input, Raw<void>(msg, offset)))) {
            return false;
          }
          break;
        }
        case 0: {
          // Done.
          return true;
        }
        default:
          break;
      }
    } else if (data->packed_wiretype == static_cast<unsigned char>(wire_type)) {
      // Non-packable fields have their packed_wiretype masked with
      // kNotPackedMask, which is impossible to match here.
      GOOGLE_DCHECK(processing_type & kRepeatedMask);
      GOOGLE_DCHECK_NE(processing_type, kRepeatedMask);
      GOOGLE_DCHECK_EQ(0, processing_type & kOneofMask);



      // TODO(ckennelly): Use a computed goto on GCC/LLVM.
      //
      // Mask out kRepeatedMask bit, allowing the jump table to be smaller.
      switch (static_cast<WireFormatLite::FieldType>(
          processing_type ^ kRepeatedMask)) {
#define HANDLE_PACKED_TYPE(TYPE, CPPTYPE, CPPTYPE_METHOD)                 \
  case WireFormatLite::TYPE_##TYPE: {                                     \
    google::protobuf::RepeatedField<CPPTYPE>* values =                              \
        Raw<google::protobuf::RepeatedField<CPPTYPE> >(msg, offset);                \
    if (GOOGLE_PREDICT_FALSE(                                                    \
            (!WireFormatLite::ReadPackedPrimitive<                        \
                CPPTYPE, WireFormatLite::TYPE_##TYPE>(input, values)))) { \
      return false;                                                       \
    }                                                                     \
    break;                                                                \
  }

        HANDLE_PACKED_TYPE(INT32, int32, Int32)
        HANDLE_PACKED_TYPE(INT64, int64, Int64)
        HANDLE_PACKED_TYPE(SINT32, int32, Int32)
        HANDLE_PACKED_TYPE(SINT64, int64, Int64)
        HANDLE_PACKED_TYPE(UINT32, uint32, UInt32)
        HANDLE_PACKED_TYPE(UINT64, uint64, UInt64)

        HANDLE_PACKED_TYPE(FIXED32, uint32, UInt32)
        HANDLE_PACKED_TYPE(FIXED64, uint64, UInt64)
        HANDLE_PACKED_TYPE(SFIXED32, int32, Int32)
        HANDLE_PACKED_TYPE(SFIXED64, int64, Int64)

        HANDLE_PACKED_TYPE(FLOAT, float, Float)
        HANDLE_PACKED_TYPE(DOUBLE, double, Double)

        HANDLE_PACKED_TYPE(BOOL, bool, Bool)
#undef HANDLE_PACKED_TYPE
        case WireFormatLite::TYPE_ENUM: {
          // To avoid unnecessarily calling MutableUnknownFields (which mutates
          // InternalMetadataWithArena) when all inputs in the repeated series
          // are valid, we implement our own parser rather than call
          // WireFormat::ReadPackedEnumPreserveUnknowns.
          uint32 length;
          if (GOOGLE_PREDICT_FALSE(!input->ReadVarint32(&length))) {
            return false;
          }

          AuxillaryParseTableField::EnumValidator validator =
              table.aux[field_number].enums.validator;
          google::protobuf::RepeatedField<int>* values =
              Raw<google::protobuf::RepeatedField<int> >(msg, offset);

          io::CodedInputStream::Limit limit = input->PushLimit(length);
          while (input->BytesUntilLimit() > 0) {
            int value;
            if (GOOGLE_PREDICT_FALSE(
                    (!google::protobuf::internal::WireFormatLite::ReadPrimitive<
                        int, WireFormatLite::TYPE_ENUM>(input, &value)))) {
              return false;
            }

            if (validator(value)) {
              values->Add(value);
            } else {
              // TODO(ckennelly): Consider caching here.
              UnknownFieldHandler::Varint(msg, table, tag, value);
            }
          }
          input->PopLimit(limit);

          break;
        }
        case WireFormatLite::TYPE_STRING:
        case WireFormatLite::TYPE_GROUP:
        case WireFormatLite::TYPE_MESSAGE:
        case WireFormatLite::TYPE_BYTES:
          GOOGLE_DCHECK(false);
          return false;
        default:
          break;
      }
    } else {
      if (wire_type == WireFormatLite::WIRETYPE_END_GROUP) {
        // Must be the end of the message.
        return true;
      }

      // check for possible extensions
      if (UnknownFieldHandler::ParseExtension(msg, table, input, tag)) {
        // successfully parsed
        continue;
      }

      // process unknown field.
      if (GOOGLE_PREDICT_FALSE(!UnknownFieldHandler::Skip(msg, table, input, tag))) {
        return false;
      }
    }
  }
}

}  // namespace internal
}  // namespace protobuf

}  // namespace google
#endif  // GOOGLE_PROTOBUF_GENERATED_MESSAGE_TABLE_DRIVEN_LITE_H__
