// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc.  All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file or at
// https://developers.google.com/open-source/licenses/bsd

#import <Foundation/Foundation.h>
#import "GPBMessage_PackagePrivate.h"

#import <objc/message.h>
#import <objc/runtime.h>
#import <os/lock.h>
#import <stdatomic.h>

#import "GPBArray_PackagePrivate.h"
#import "GPBCodedInputStream_PackagePrivate.h"
#import "GPBCodedOutputStream_PackagePrivate.h"
#import "GPBDescriptor_PackagePrivate.h"
#import "GPBDictionary_PackagePrivate.h"
#import "GPBExtensionInternals.h"
#import "GPBExtensionRegistry.h"
#import "GPBRootObject_PackagePrivate.h"
#import "GPBUnknownFieldSet_PackagePrivate.h"
#import "GPBUtilities_PackagePrivate.h"

// Returns a new instance that was automatically created by |autocreator| for
// its field |field|.
static GPBMessage *GPBCreateMessageWithAutocreator(Class msgClass, GPBMessage *autocreator,
                                                   GPBFieldDescriptor *field)
    __attribute__((ns_returns_retained));

// Direct access is use for speed, to avoid even internally declaring things
// read/write, etc. The warning is enabled in the project to ensure code calling
// protos can turn on -Wdirect-ivar-access without issues.
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdirect-ivar-access"

NSString *const GPBMessageErrorDomain = GPBNSStringifySymbol(GPBMessageErrorDomain);

NSString *const GPBErrorReasonKey = @"Reason";

static NSString *const kGPBDataCoderKey = @"GPBData";

// Length-delimited has a max size of 2GB, and thus messages do also.
// src/google/protobuf/message_lite also does this enforcement on the C++ side. Validation for
// parsing is done with GPBCodedInputStream; but for messages, it is less checks to do it within
// the message side since the input stream code calls these same bottlenecks.
// https://protobuf.dev/programming-guides/encoding/#cheat-sheet
static const size_t kMaximumMessageSize = 0x7fffffff;

NSString *const GPBMessageExceptionMessageTooLarge =
    GPBNSStringifySymbol(GPBMessageExceptionMessageTooLarge);

//
// PLEASE REMEMBER:
//
// This is the base class for *all* messages generated, so any selector defined,
// *public* or *private* could end up colliding with a proto message field. So
// avoid using selectors that could match a property, use C functions to hide
// them, etc.
//

@interface GPBMessage () {
 @package
  GPBUnknownFieldSet *unknownFields_;
  NSMutableDictionary *extensionMap_;
  // Readonly access to autocreatedExtensionMap_ is protected via readOnlyLock_.
  NSMutableDictionary *autocreatedExtensionMap_;

  // If the object was autocreated, we remember the creator so that if we get
  // mutated, we can inform the creator to make our field visible.
  GPBMessage *autocreator_;
  GPBFieldDescriptor *autocreatorField_;
  GPBExtensionDescriptor *autocreatorExtension_;

  // Messages can only be mutated from one thread. But some *readonly* operations modify internal
  // state because they autocreate things. The autocreatedExtensionMap_ is one such structure.
  // Access during readonly operations is protected via this lock.
  //
  // Long ago, this was an OSSpinLock, but then it came to light that there were issues for that on
  // iOS:
  //   http://mjtsai.com/blog/2015/12/16/osspinlock-is-unsafe/
  //   https://lists.swift.org/pipermail/swift-dev/Week-of-Mon-20151214/000372.html
  // It was changed to a dispatch_semaphore_t, but that has potential for priority inversion issues.
  // The minOS versions are now high enough that os_unfair_lock can be used, and should provide
  // all the support we need. For more information in the concurrency/locking space see:
  //   https://gist.github.com/tclementdev/6af616354912b0347cdf6db159c37057
  //   https://developer.apple.com/library/archive/documentation/Performance/Conceptual/EnergyGuide-iOS/PrioritizeWorkWithQoS.html
  //   https://developer.apple.com/videos/play/wwdc2017/706/
  os_unfair_lock readOnlyLock_;
}
@end

static id CreateArrayForField(GPBFieldDescriptor *field, GPBMessage *autocreator)
    __attribute__((ns_returns_retained));
static id GetOrCreateArrayIvarWithField(GPBMessage *self, GPBFieldDescriptor *field);
static id GetArrayIvarWithField(GPBMessage *self, GPBFieldDescriptor *field);
static id CreateMapForField(GPBFieldDescriptor *field, GPBMessage *autocreator)
    __attribute__((ns_returns_retained));
static id GetOrCreateMapIvarWithField(GPBMessage *self, GPBFieldDescriptor *field);
static id GetMapIvarWithField(GPBMessage *self, GPBFieldDescriptor *field);
static NSMutableDictionary *CloneExtensionMap(NSDictionary *extensionMap, NSZone *zone)
    __attribute__((ns_returns_retained));
static GPBUnknownFieldSet *GetOrMakeUnknownFields(GPBMessage *self);

#if defined(DEBUG) && DEBUG
static NSError *MessageError(NSInteger code, NSDictionary *userInfo) {
  return [NSError errorWithDomain:GPBMessageErrorDomain code:code userInfo:userInfo];
}
#endif

static NSError *ErrorFromException(NSException *exception) {
  NSError *error = nil;

  if ([exception.name isEqual:GPBCodedInputStreamException]) {
    NSDictionary *exceptionInfo = exception.userInfo;
    error = exceptionInfo[GPBCodedInputStreamUnderlyingErrorKey];
  }

  if (!error) {
    NSString *reason = exception.reason;
    NSDictionary *userInfo = nil;
    if ([reason length]) {
      userInfo = @{GPBErrorReasonKey : reason};
    }

    error = [NSError errorWithDomain:GPBMessageErrorDomain
                                code:GPBMessageErrorCodeOther
                            userInfo:userInfo];
  }
  return error;
}

static void CheckExtension(GPBMessage *self, GPBExtensionDescriptor *extension) {
  if (![self isKindOfClass:extension.containingMessageClass]) {
    [NSException raise:NSInvalidArgumentException
                format:@"Extension %@ used on wrong class (%@ instead of %@)",
                       extension.singletonName, [self class], extension.containingMessageClass];
  }
}

static NSMutableDictionary *CloneExtensionMap(NSDictionary *extensionMap, NSZone *zone) {
  if (extensionMap.count == 0) {
    return nil;
  }
  NSMutableDictionary *result =
      [[NSMutableDictionary allocWithZone:zone] initWithCapacity:extensionMap.count];

  for (GPBExtensionDescriptor *extension in extensionMap) {
    id value = [extensionMap objectForKey:extension];
    BOOL isMessageExtension = GPBExtensionIsMessage(extension);

    if (extension.repeated) {
      if (isMessageExtension) {
        NSMutableArray *list = [[NSMutableArray alloc] initWithCapacity:[value count]];
        for (GPBMessage *listValue in value) {
          GPBMessage *copiedValue = [listValue copyWithZone:zone];
          [list addObject:copiedValue];
          [copiedValue release];
        }
        [result setObject:list forKey:extension];
        [list release];
      } else {
        NSMutableArray *copiedValue = [value mutableCopyWithZone:zone];
        [result setObject:copiedValue forKey:extension];
        [copiedValue release];
      }
    } else {
      if (isMessageExtension) {
        GPBMessage *copiedValue = [value copyWithZone:zone];
        [result setObject:copiedValue forKey:extension];
        [copiedValue release];
      } else {
        [result setObject:value forKey:extension];
      }
    }
  }

  return result;
}

static id CreateArrayForField(GPBFieldDescriptor *field, GPBMessage *autocreator) {
  id result;
  GPBDataType fieldDataType = GPBGetFieldDataType(field);
  switch (fieldDataType) {
    case GPBDataTypeBool:
      result = [[GPBBoolArray alloc] init];
      break;
    case GPBDataTypeFixed32:
    case GPBDataTypeUInt32:
      result = [[GPBUInt32Array alloc] init];
      break;
    case GPBDataTypeInt32:
    case GPBDataTypeSFixed32:
    case GPBDataTypeSInt32:
      result = [[GPBInt32Array alloc] init];
      break;
    case GPBDataTypeFixed64:
    case GPBDataTypeUInt64:
      result = [[GPBUInt64Array alloc] init];
      break;
    case GPBDataTypeInt64:
    case GPBDataTypeSFixed64:
    case GPBDataTypeSInt64:
      result = [[GPBInt64Array alloc] init];
      break;
    case GPBDataTypeFloat:
      result = [[GPBFloatArray alloc] init];
      break;
    case GPBDataTypeDouble:
      result = [[GPBDoubleArray alloc] init];
      break;

    case GPBDataTypeEnum:
      result = [[GPBEnumArray alloc] initWithValidationFunction:field.enumDescriptor.enumVerifier];
      break;

    case GPBDataTypeBytes:
    case GPBDataTypeGroup:
    case GPBDataTypeMessage:
    case GPBDataTypeString:
      if (autocreator) {
        result = [[GPBAutocreatedArray alloc] init];
      } else {
        result = [[NSMutableArray alloc] init];
      }
      break;
  }

  if (autocreator) {
    if (GPBDataTypeIsObject(fieldDataType)) {
      GPBAutocreatedArray *autoArray = result;
      autoArray->_autocreator = autocreator;
    } else {
      GPBInt32Array *gpbArray = result;
      gpbArray->_autocreator = autocreator;
    }
  }

  return result;
}

static id CreateMapForField(GPBFieldDescriptor *field, GPBMessage *autocreator) {
  id result;
  GPBDataType keyDataType = field.mapKeyDataType;
  GPBDataType valueDataType = GPBGetFieldDataType(field);
  switch (keyDataType) {
    case GPBDataTypeBool:
      switch (valueDataType) {
        case GPBDataTypeBool:
          result = [[GPBBoolBoolDictionary alloc] init];
          break;
        case GPBDataTypeFixed32:
        case GPBDataTypeUInt32:
          result = [[GPBBoolUInt32Dictionary alloc] init];
          break;
        case GPBDataTypeInt32:
        case GPBDataTypeSFixed32:
        case GPBDataTypeSInt32:
          result = [[GPBBoolInt32Dictionary alloc] init];
          break;
        case GPBDataTypeFixed64:
        case GPBDataTypeUInt64:
          result = [[GPBBoolUInt64Dictionary alloc] init];
          break;
        case GPBDataTypeInt64:
        case GPBDataTypeSFixed64:
        case GPBDataTypeSInt64:
          result = [[GPBBoolInt64Dictionary alloc] init];
          break;
        case GPBDataTypeFloat:
          result = [[GPBBoolFloatDictionary alloc] init];
          break;
        case GPBDataTypeDouble:
          result = [[GPBBoolDoubleDictionary alloc] init];
          break;
        case GPBDataTypeEnum:
          result = [[GPBBoolEnumDictionary alloc]
              initWithValidationFunction:field.enumDescriptor.enumVerifier];
          break;
        case GPBDataTypeBytes:
        case GPBDataTypeMessage:
        case GPBDataTypeString:
          result = [[GPBBoolObjectDictionary alloc] init];
          break;
        case GPBDataTypeGroup:
          NSCAssert(NO, @"shouldn't happen");
          return nil;
      }
      break;
    case GPBDataTypeFixed32:
    case GPBDataTypeUInt32:
      switch (valueDataType) {
        case GPBDataTypeBool:
          result = [[GPBUInt32BoolDictionary alloc] init];
          break;
        case GPBDataTypeFixed32:
        case GPBDataTypeUInt32:
          result = [[GPBUInt32UInt32Dictionary alloc] init];
          break;
        case GPBDataTypeInt32:
        case GPBDataTypeSFixed32:
        case GPBDataTypeSInt32:
          result = [[GPBUInt32Int32Dictionary alloc] init];
          break;
        case GPBDataTypeFixed64:
        case GPBDataTypeUInt64:
          result = [[GPBUInt32UInt64Dictionary alloc] init];
          break;
        case GPBDataTypeInt64:
        case GPBDataTypeSFixed64:
        case GPBDataTypeSInt64:
          result = [[GPBUInt32Int64Dictionary alloc] init];
          break;
        case GPBDataTypeFloat:
          result = [[GPBUInt32FloatDictionary alloc] init];
          break;
        case GPBDataTypeDouble:
          result = [[GPBUInt32DoubleDictionary alloc] init];
          break;
        case GPBDataTypeEnum:
          result = [[GPBUInt32EnumDictionary alloc]
              initWithValidationFunction:field.enumDescriptor.enumVerifier];
          break;
        case GPBDataTypeBytes:
        case GPBDataTypeMessage:
        case GPBDataTypeString:
          result = [[GPBUInt32ObjectDictionary alloc] init];
          break;
        case GPBDataTypeGroup:
          NSCAssert(NO, @"shouldn't happen");
          return nil;
      }
      break;
    case GPBDataTypeInt32:
    case GPBDataTypeSFixed32:
    case GPBDataTypeSInt32:
      switch (valueDataType) {
        case GPBDataTypeBool:
          result = [[GPBInt32BoolDictionary alloc] init];
          break;
        case GPBDataTypeFixed32:
        case GPBDataTypeUInt32:
          result = [[GPBInt32UInt32Dictionary alloc] init];
          break;
        case GPBDataTypeInt32:
        case GPBDataTypeSFixed32:
        case GPBDataTypeSInt32:
          result = [[GPBInt32Int32Dictionary alloc] init];
          break;
        case GPBDataTypeFixed64:
        case GPBDataTypeUInt64:
          result = [[GPBInt32UInt64Dictionary alloc] init];
          break;
        case GPBDataTypeInt64:
        case GPBDataTypeSFixed64:
        case GPBDataTypeSInt64:
          result = [[GPBInt32Int64Dictionary alloc] init];
          break;
        case GPBDataTypeFloat:
          result = [[GPBInt32FloatDictionary alloc] init];
          break;
        case GPBDataTypeDouble:
          result = [[GPBInt32DoubleDictionary alloc] init];
          break;
        case GPBDataTypeEnum:
          result = [[GPBInt32EnumDictionary alloc]
              initWithValidationFunction:field.enumDescriptor.enumVerifier];
          break;
        case GPBDataTypeBytes:
        case GPBDataTypeMessage:
        case GPBDataTypeString:
          result = [[GPBInt32ObjectDictionary alloc] init];
          break;
        case GPBDataTypeGroup:
          NSCAssert(NO, @"shouldn't happen");
          return nil;
      }
      break;
    case GPBDataTypeFixed64:
    case GPBDataTypeUInt64:
      switch (valueDataType) {
        case GPBDataTypeBool:
          result = [[GPBUInt64BoolDictionary alloc] init];
          break;
        case GPBDataTypeFixed32:
        case GPBDataTypeUInt32:
          result = [[GPBUInt64UInt32Dictionary alloc] init];
          break;
        case GPBDataTypeInt32:
        case GPBDataTypeSFixed32:
        case GPBDataTypeSInt32:
          result = [[GPBUInt64Int32Dictionary alloc] init];
          break;
        case GPBDataTypeFixed64:
        case GPBDataTypeUInt64:
          result = [[GPBUInt64UInt64Dictionary alloc] init];
          break;
        case GPBDataTypeInt64:
        case GPBDataTypeSFixed64:
        case GPBDataTypeSInt64:
          result = [[GPBUInt64Int64Dictionary alloc] init];
          break;
        case GPBDataTypeFloat:
          result = [[GPBUInt64FloatDictionary alloc] init];
          break;
        case GPBDataTypeDouble:
          result = [[GPBUInt64DoubleDictionary alloc] init];
          break;
        case GPBDataTypeEnum:
          result = [[GPBUInt64EnumDictionary alloc]
              initWithValidationFunction:field.enumDescriptor.enumVerifier];
          break;
        case GPBDataTypeBytes:
        case GPBDataTypeMessage:
        case GPBDataTypeString:
          result = [[GPBUInt64ObjectDictionary alloc] init];
          break;
        case GPBDataTypeGroup:
          NSCAssert(NO, @"shouldn't happen");
          return nil;
      }
      break;
    case GPBDataTypeInt64:
    case GPBDataTypeSFixed64:
    case GPBDataTypeSInt64:
      switch (valueDataType) {
        case GPBDataTypeBool:
          result = [[GPBInt64BoolDictionary alloc] init];
          break;
        case GPBDataTypeFixed32:
        case GPBDataTypeUInt32:
          result = [[GPBInt64UInt32Dictionary alloc] init];
          break;
        case GPBDataTypeInt32:
        case GPBDataTypeSFixed32:
        case GPBDataTypeSInt32:
          result = [[GPBInt64Int32Dictionary alloc] init];
          break;
        case GPBDataTypeFixed64:
        case GPBDataTypeUInt64:
          result = [[GPBInt64UInt64Dictionary alloc] init];
          break;
        case GPBDataTypeInt64:
        case GPBDataTypeSFixed64:
        case GPBDataTypeSInt64:
          result = [[GPBInt64Int64Dictionary alloc] init];
          break;
        case GPBDataTypeFloat:
          result = [[GPBInt64FloatDictionary alloc] init];
          break;
        case GPBDataTypeDouble:
          result = [[GPBInt64DoubleDictionary alloc] init];
          break;
        case GPBDataTypeEnum:
          result = [[GPBInt64EnumDictionary alloc]
              initWithValidationFunction:field.enumDescriptor.enumVerifier];
          break;
        case GPBDataTypeBytes:
        case GPBDataTypeMessage:
        case GPBDataTypeString:
          result = [[GPBInt64ObjectDictionary alloc] init];
          break;
        case GPBDataTypeGroup:
          NSCAssert(NO, @"shouldn't happen");
          return nil;
      }
      break;
    case GPBDataTypeString:
      switch (valueDataType) {
        case GPBDataTypeBool:
          result = [[GPBStringBoolDictionary alloc] init];
          break;
        case GPBDataTypeFixed32:
        case GPBDataTypeUInt32:
          result = [[GPBStringUInt32Dictionary alloc] init];
          break;
        case GPBDataTypeInt32:
        case GPBDataTypeSFixed32:
        case GPBDataTypeSInt32:
          result = [[GPBStringInt32Dictionary alloc] init];
          break;
        case GPBDataTypeFixed64:
        case GPBDataTypeUInt64:
          result = [[GPBStringUInt64Dictionary alloc] init];
          break;
        case GPBDataTypeInt64:
        case GPBDataTypeSFixed64:
        case GPBDataTypeSInt64:
          result = [[GPBStringInt64Dictionary alloc] init];
          break;
        case GPBDataTypeFloat:
          result = [[GPBStringFloatDictionary alloc] init];
          break;
        case GPBDataTypeDouble:
          result = [[GPBStringDoubleDictionary alloc] init];
          break;
        case GPBDataTypeEnum:
          result = [[GPBStringEnumDictionary alloc]
              initWithValidationFunction:field.enumDescriptor.enumVerifier];
          break;
        case GPBDataTypeBytes:
        case GPBDataTypeMessage:
        case GPBDataTypeString:
          if (autocreator) {
            result = [[GPBAutocreatedDictionary alloc] init];
          } else {
            result = [[NSMutableDictionary alloc] init];
          }
          break;
        case GPBDataTypeGroup:
          NSCAssert(NO, @"shouldn't happen");
          return nil;
      }
      break;

    case GPBDataTypeFloat:
    case GPBDataTypeDouble:
    case GPBDataTypeEnum:
    case GPBDataTypeBytes:
    case GPBDataTypeGroup:
    case GPBDataTypeMessage:
      NSCAssert(NO, @"shouldn't happen");
      return nil;
  }

  if (autocreator) {
    if ((keyDataType == GPBDataTypeString) && GPBDataTypeIsObject(valueDataType)) {
      GPBAutocreatedDictionary *autoDict = result;
      autoDict->_autocreator = autocreator;
    } else {
      GPBInt32Int32Dictionary *gpbDict = result;
      gpbDict->_autocreator = autocreator;
    }
  }

  return result;
}

#if !defined(__clang_analyzer__)
// These functions are blocked from the analyzer because the analyzer sees the
// GPBSetRetainedObjectIvarWithFieldPrivate() call as consuming the array/map,
// so use of the array/map after the call returns is flagged as a use after
// free.
// But GPBSetRetainedObjectIvarWithFieldPrivate() is "consuming" the retain
// count be holding onto the object (it is transferring it), the object is
// still valid after returning from the call.  The other way to avoid this
// would be to add a -retain/-autorelease, but that would force every
// repeated/map field parsed into the autorelease pool which is both a memory
// and performance hit.

static id GetOrCreateArrayIvarWithField(GPBMessage *self, GPBFieldDescriptor *field) {
  id array = GPBGetObjectIvarWithFieldNoAutocreate(self, field);
  if (!array) {
    // No lock needed, this is called from places expecting to mutate
    // so no threading protection is needed.
    array = CreateArrayForField(field, nil);
    GPBSetRetainedObjectIvarWithFieldPrivate(self, field, array);
  }
  return array;
}

// This is like GPBGetObjectIvarWithField(), but for arrays, it should
// only be used to wire the method into the class.
static id GetArrayIvarWithField(GPBMessage *self, GPBFieldDescriptor *field) {
  uint8_t *storage = (uint8_t *)self->messageStorage_;
  _Atomic(id) *typePtr = (_Atomic(id) *)&storage[field->description_->offset];
  id array = atomic_load(typePtr);
  if (array) {
    return array;
  }

  id expected = nil;
  id autocreated = CreateArrayForField(field, self);
  if (atomic_compare_exchange_strong(typePtr, &expected, autocreated)) {
    // Value was set, return it.
    return autocreated;
  }

  // Some other thread set it, release the one created and return what got set.
  if (GPBFieldDataTypeIsObject(field)) {
    GPBAutocreatedArray *autoArray = autocreated;
    autoArray->_autocreator = nil;
  } else {
    GPBInt32Array *gpbArray = autocreated;
    gpbArray->_autocreator = nil;
  }
  [autocreated release];
  return expected;
}

static id GetOrCreateMapIvarWithField(GPBMessage *self, GPBFieldDescriptor *field) {
  id dict = GPBGetObjectIvarWithFieldNoAutocreate(self, field);
  if (!dict) {
    // No lock needed, this is called from places expecting to mutate
    // so no threading protection is needed.
    dict = CreateMapForField(field, nil);
    GPBSetRetainedObjectIvarWithFieldPrivate(self, field, dict);
  }
  return dict;
}

// This is like GPBGetObjectIvarWithField(), but for maps, it should
// only be used to wire the method into the class.
static id GetMapIvarWithField(GPBMessage *self, GPBFieldDescriptor *field) {
  uint8_t *storage = (uint8_t *)self->messageStorage_;
  _Atomic(id) *typePtr = (_Atomic(id) *)&storage[field->description_->offset];
  id dict = atomic_load(typePtr);
  if (dict) {
    return dict;
  }

  id expected = nil;
  id autocreated = CreateMapForField(field, self);
  if (atomic_compare_exchange_strong(typePtr, &expected, autocreated)) {
    // Value was set, return it.
    return autocreated;
  }

  // Some other thread set it, release the one created and return what got set.
  if ((field.mapKeyDataType == GPBDataTypeString) && GPBFieldDataTypeIsObject(field)) {
    GPBAutocreatedDictionary *autoDict = autocreated;
    autoDict->_autocreator = nil;
  } else {
    GPBInt32Int32Dictionary *gpbDict = autocreated;
    gpbDict->_autocreator = nil;
  }
  [autocreated release];
  return expected;
}

#endif  // !defined(__clang_analyzer__)

static void DecodeSingleValueFromInputStream(GPBExtensionDescriptor *extension,
                                             GPBMessage *messageToGetExtension,
                                             GPBCodedInputStream *input,
                                             id<GPBExtensionRegistry> extensionRegistry,
                                             BOOL isRepeated, GPBMessage *targetMessage) {
  GPBExtensionDescription *description = extension->description_;
#if defined(DEBUG) && DEBUG && !defined(NS_BLOCK_ASSERTIONS)
  if (GPBDataTypeIsMessage(description->dataType)) {
    NSCAssert(targetMessage != nil, @"Internal error: must have a target message");
  } else {
    NSCAssert(targetMessage == nil, @"Internal error: should not have a target message");
  }
#endif
  GPBCodedInputStreamState *state = &input->state_;
  id nsValue;
  switch (description->dataType) {
    case GPBDataTypeBool: {
      BOOL value = GPBCodedInputStreamReadBool(state);
      nsValue = [[NSNumber alloc] initWithBool:value];
      break;
    }
    case GPBDataTypeFixed32: {
      uint32_t value = GPBCodedInputStreamReadFixed32(state);
      nsValue = [[NSNumber alloc] initWithUnsignedInt:value];
      break;
    }
    case GPBDataTypeSFixed32: {
      int32_t value = GPBCodedInputStreamReadSFixed32(state);
      nsValue = [[NSNumber alloc] initWithInt:value];
      break;
    }
    case GPBDataTypeFloat: {
      float value = GPBCodedInputStreamReadFloat(state);
      nsValue = [[NSNumber alloc] initWithFloat:value];
      break;
    }
    case GPBDataTypeFixed64: {
      uint64_t value = GPBCodedInputStreamReadFixed64(state);
      nsValue = [[NSNumber alloc] initWithUnsignedLongLong:value];
      break;
    }
    case GPBDataTypeSFixed64: {
      int64_t value = GPBCodedInputStreamReadSFixed64(state);
      nsValue = [[NSNumber alloc] initWithLongLong:value];
      break;
    }
    case GPBDataTypeDouble: {
      double value = GPBCodedInputStreamReadDouble(state);
      nsValue = [[NSNumber alloc] initWithDouble:value];
      break;
    }
    case GPBDataTypeInt32: {
      int32_t value = GPBCodedInputStreamReadInt32(state);
      nsValue = [[NSNumber alloc] initWithInt:value];
      break;
    }
    case GPBDataTypeInt64: {
      int64_t value = GPBCodedInputStreamReadInt64(state);
      nsValue = [[NSNumber alloc] initWithLongLong:value];
      break;
    }
    case GPBDataTypeSInt32: {
      int32_t value = GPBCodedInputStreamReadSInt32(state);
      nsValue = [[NSNumber alloc] initWithInt:value];
      break;
    }
    case GPBDataTypeSInt64: {
      int64_t value = GPBCodedInputStreamReadSInt64(state);
      nsValue = [[NSNumber alloc] initWithLongLong:value];
      break;
    }
    case GPBDataTypeUInt32: {
      uint32_t value = GPBCodedInputStreamReadUInt32(state);
      nsValue = [[NSNumber alloc] initWithUnsignedInt:value];
      break;
    }
    case GPBDataTypeUInt64: {
      uint64_t value = GPBCodedInputStreamReadUInt64(state);
      nsValue = [[NSNumber alloc] initWithUnsignedLongLong:value];
      break;
    }
    case GPBDataTypeBytes:
      nsValue = GPBCodedInputStreamReadRetainedBytes(state);
      break;
    case GPBDataTypeString:
      nsValue = GPBCodedInputStreamReadRetainedString(state);
      break;
    case GPBDataTypeEnum: {
      int32_t val = GPBCodedInputStreamReadEnum(&input->state_);
      GPBEnumDescriptor *enumDescriptor = extension.enumDescriptor;
      // If run with source generated before the closed enum support, all enums
      // will be considers not closed, so casing to the enum type for a switch
      // could cause things to fall off the end of a switch.
      if (!enumDescriptor.isClosed || enumDescriptor.enumVerifier(val)) {
        nsValue = [[NSNumber alloc] initWithInt:val];
      } else {
        GPBUnknownFieldSet *unknownFields = GetOrMakeUnknownFields(messageToGetExtension);
        [unknownFields mergeVarintField:extension->description_->fieldNumber value:val];
        nsValue = nil;
      }
      break;
    }
    case GPBDataTypeGroup:
    case GPBDataTypeMessage: {
      if (description->dataType == GPBDataTypeGroup) {
        [input readGroup:description->fieldNumber
                      message:targetMessage
            extensionRegistry:extensionRegistry];
      } else {
        // description->dataType == GPBDataTypeMessage
        if (GPBExtensionIsWireFormat(description)) {
          // For MessageSet fields the message length will have already been
          // read.
          [targetMessage mergeFromCodedInputStream:input extensionRegistry:extensionRegistry];
        } else {
          [input readMessage:targetMessage extensionRegistry:extensionRegistry];
        }
      }
      // Nothing to add below since the caller provided the message (and added it).
      nsValue = nil;
      break;
    }
  }  // switch

  if (nsValue) {
    if (isRepeated) {
      [messageToGetExtension addExtension:extension value:nsValue];
    } else {
      [messageToGetExtension setExtension:extension value:nsValue];
    }
    [nsValue release];
  }
}

static void ExtensionMergeFromInputStream(GPBExtensionDescriptor *extension, BOOL isPackedOnStream,
                                          GPBCodedInputStream *input,
                                          id<GPBExtensionRegistry> extensionRegistry,
                                          GPBMessage *message) {
  GPBExtensionDescription *description = extension->description_;
  GPBCodedInputStreamState *state = &input->state_;
  if (isPackedOnStream) {
#if defined(DEBUG) && DEBUG && !defined(NS_BLOCK_ASSERTIONS)
    NSCAssert(GPBExtensionIsRepeated(description), @"How was it packed if it isn't repeated?");
#endif
    int32_t length = GPBCodedInputStreamReadInt32(state);
    size_t limit = GPBCodedInputStreamPushLimit(state, length);
    while (GPBCodedInputStreamBytesUntilLimit(state) > 0) {
      DecodeSingleValueFromInputStream(extension, message, input, extensionRegistry,
                                       /*isRepeated=*/YES, nil);
    }
    GPBCodedInputStreamPopLimit(state, limit);
  } else {
    BOOL isRepeated = GPBExtensionIsRepeated(description);
    GPBMessage *targetMessage = nil;
    if (GPBDataTypeIsMessage(description->dataType)) {
      // For messages/groups create the targetMessage out here and add it to the objects graph in
      // advance, that way if DecodeSingleValueFromInputStream() throw for a parsing issue, the
      // object won't be leaked.
      if (isRepeated) {
        GPBDescriptor *descriptor = [extension.msgClass descriptor];
        targetMessage = [[descriptor.messageClass alloc] init];
        [message addExtension:extension value:targetMessage];
        [targetMessage release];
      } else {
        targetMessage = [message getExistingExtension:extension];
        if (!targetMessage) {
          GPBDescriptor *descriptor = [extension.msgClass descriptor];
          targetMessage = [[descriptor.messageClass alloc] init];
          [message setExtension:extension value:targetMessage];
          [targetMessage release];
        }
      }
    }
    DecodeSingleValueFromInputStream(extension, message, input, extensionRegistry, isRepeated,
                                     targetMessage);
  }
}

static GPBMessage *GPBCreateMessageWithAutocreator(Class msgClass, GPBMessage *autocreator,
                                                   GPBFieldDescriptor *field) {
  GPBMessage *message = [[msgClass alloc] init];
  message->autocreator_ = autocreator;
  message->autocreatorField_ = [field retain];
  return message;
}

static GPBMessage *CreateMessageWithAutocreatorForExtension(Class msgClass, GPBMessage *autocreator,
                                                            GPBExtensionDescriptor *extension)
    __attribute__((ns_returns_retained));

static GPBMessage *CreateMessageWithAutocreatorForExtension(Class msgClass, GPBMessage *autocreator,
                                                            GPBExtensionDescriptor *extension) {
  GPBMessage *message = [[msgClass alloc] init];
  message->autocreator_ = autocreator;
  message->autocreatorExtension_ = [extension retain];
  return message;
}

BOOL GPBWasMessageAutocreatedBy(GPBMessage *message, GPBMessage *parent) {
  return (message->autocreator_ == parent);
}

void GPBBecomeVisibleToAutocreator(GPBMessage *self) {
  // Message objects that are implicitly created by accessing a message field
  // are initially not visible via the hasX selector. This method makes them
  // visible.
  if (self->autocreator_) {
    // This will recursively make all parent messages visible until it reaches a
    // super-creator that's visible.
    if (self->autocreatorField_) {
      GPBSetObjectIvarWithFieldPrivate(self->autocreator_, self->autocreatorField_, self);
    } else {
      [self->autocreator_ setExtension:self->autocreatorExtension_ value:self];
    }
  }
}

void GPBAutocreatedArrayModified(GPBMessage *self, id array) {
  // When one of our autocreated arrays adds elements, make it visible.
  GPBDescriptor *descriptor = [[self class] descriptor];
  for (GPBFieldDescriptor *field in descriptor->fields_) {
    if (field.fieldType == GPBFieldTypeRepeated) {
      id curArray = GPBGetObjectIvarWithFieldNoAutocreate(self, field);
      if (curArray == array) {
        if (GPBFieldDataTypeIsObject(field)) {
          GPBAutocreatedArray *autoArray = array;
          autoArray->_autocreator = nil;
        } else {
          GPBInt32Array *gpbArray = array;
          gpbArray->_autocreator = nil;
        }
        GPBBecomeVisibleToAutocreator(self);
        return;
      }
    }
  }
  NSCAssert(NO, @"Unknown autocreated %@ for %@.", [array class], self);
}

void GPBAutocreatedDictionaryModified(GPBMessage *self, id dictionary) {
  // When one of our autocreated dicts adds elements, make it visible.
  GPBDescriptor *descriptor = [[self class] descriptor];
  for (GPBFieldDescriptor *field in descriptor->fields_) {
    if (field.fieldType == GPBFieldTypeMap) {
      id curDict = GPBGetObjectIvarWithFieldNoAutocreate(self, field);
      if (curDict == dictionary) {
        if ((field.mapKeyDataType == GPBDataTypeString) && GPBFieldDataTypeIsObject(field)) {
          GPBAutocreatedDictionary *autoDict = dictionary;
          autoDict->_autocreator = nil;
        } else {
          GPBInt32Int32Dictionary *gpbDict = dictionary;
          gpbDict->_autocreator = nil;
        }
        GPBBecomeVisibleToAutocreator(self);
        return;
      }
    }
  }
  NSCAssert(NO, @"Unknown autocreated %@ for %@.", [dictionary class], self);
}

void GPBClearMessageAutocreator(GPBMessage *self) {
  if ((self == nil) || !self->autocreator_) {
    return;
  }

#if defined(DEBUG) && DEBUG && !defined(NS_BLOCK_ASSERTIONS)
  // Either the autocreator must have its "has" flag set to YES, or it must be
  // NO and not equal to ourselves.
  BOOL autocreatorHas =
      (self->autocreatorField_ ? GPBGetHasIvarField(self->autocreator_, self->autocreatorField_)
                               : [self->autocreator_ hasExtension:self->autocreatorExtension_]);
  GPBMessage *autocreatorFieldValue =
      (self->autocreatorField_
           ? GPBGetObjectIvarWithFieldNoAutocreate(self->autocreator_, self->autocreatorField_)
           : [self->autocreator_->autocreatedExtensionMap_
                 objectForKey:self->autocreatorExtension_]);
  NSCAssert(autocreatorHas || autocreatorFieldValue != self,
            @"Cannot clear autocreator because it still refers to self, self: %@.", self);

#endif  // DEBUG && !defined(NS_BLOCK_ASSERTIONS)

  self->autocreator_ = nil;
  [self->autocreatorField_ release];
  self->autocreatorField_ = nil;
  [self->autocreatorExtension_ release];
  self->autocreatorExtension_ = nil;
}

static GPBUnknownFieldSet *GetOrMakeUnknownFields(GPBMessage *self) {
  if (!self->unknownFields_) {
    self->unknownFields_ = [[GPBUnknownFieldSet alloc] init];
    GPBBecomeVisibleToAutocreator(self);
  }
  return self->unknownFields_;
}

@implementation GPBMessage

+ (void)initialize {
  Class pbMessageClass = [GPBMessage class];
  if ([self class] == pbMessageClass) {
    // This is here to start up the "base" class descriptor.
    [self descriptor];
    // Message shares extension method resolving with GPBRootObject so insure
    // it is started up at the same time.
    (void)[GPBRootObject class];
  } else if ([self superclass] == pbMessageClass) {
    // This is here to start up all the "message" subclasses. Just needs to be
    // done for the messages, not any of the subclasses.
    // This must be done in initialize to enforce thread safety of start up of
    // the protocol buffer library.
    // Note: The generated code for -descriptor calls
    // +[GPBDescriptor allocDescriptorForClass:...], passing the GPBRootObject
    // subclass for the file.  That call chain is what ensures that *Root class
    // is started up to support extension resolution off the message class
    // (+resolveClassMethod: below) in a thread safe manner.
    [self descriptor];
  }
}

+ (instancetype)allocWithZone:(NSZone *)zone {
  // Override alloc to allocate our classes with the additional storage
  // required for the instance variables.
  GPBDescriptor *descriptor = [self descriptor];
  return NSAllocateObject(self, descriptor->storageSize_, zone);
}

+ (instancetype)alloc {
  return [self allocWithZone:nil];
}

+ (GPBDescriptor *)descriptor {
  // This is thread safe because it is called from +initialize.
  static GPBDescriptor *descriptor = NULL;
  static GPBFileDescriptor *fileDescriptor = NULL;
  if (!descriptor) {
    fileDescriptor = [[GPBFileDescriptor alloc] initWithPackage:@"internal"
                                                         syntax:GPBFileSyntaxProto2];

    descriptor = [GPBDescriptor allocDescriptorForClass:[GPBMessage class]
                                              rootClass:Nil
                                                   file:fileDescriptor
                                                 fields:NULL
                                             fieldCount:0
                                            storageSize:0
                                                  flags:0];
  }
  return descriptor;
}

+ (instancetype)message {
  return [[[self alloc] init] autorelease];
}

- (instancetype)init {
  if ((self = [super init])) {
    messageStorage_ =
        (GPBMessage_StoragePtr)(((uint8_t *)self) + class_getInstanceSize([self class]));
    readOnlyLock_ = OS_UNFAIR_LOCK_INIT;
  }

  return self;
}

- (instancetype)initWithData:(NSData *)data error:(NSError **)errorPtr {
  return [self initWithData:data extensionRegistry:nil error:errorPtr];
}

- (instancetype)initWithData:(NSData *)data
           extensionRegistry:(id<GPBExtensionRegistry>)extensionRegistry
                       error:(NSError **)errorPtr {
  if ((self = [self init])) {
    if (![self mergeFromData:data extensionRegistry:extensionRegistry error:errorPtr]) {
      [self release];
      self = nil;
#if defined(DEBUG) && DEBUG
    } else if (!self.initialized) {
      [self release];
      self = nil;
      if (errorPtr) {
        *errorPtr = MessageError(GPBMessageErrorCodeMissingRequiredField, nil);
      }
#endif
    }
  }
  return self;
}

- (instancetype)initWithCodedInputStream:(GPBCodedInputStream *)input
                       extensionRegistry:(id<GPBExtensionRegistry>)extensionRegistry
                                   error:(NSError **)errorPtr {
  if ((self = [self init])) {
    @try {
      [self mergeFromCodedInputStream:input extensionRegistry:extensionRegistry];
      if (errorPtr) {
        *errorPtr = nil;
      }
    } @catch (NSException *exception) {
      [self release];
      self = nil;
      if (errorPtr) {
        *errorPtr = ErrorFromException(exception);
      }
    }
#if defined(DEBUG) && DEBUG
    if (self && !self.initialized) {
      [self release];
      self = nil;
      if (errorPtr) {
        *errorPtr = MessageError(GPBMessageErrorCodeMissingRequiredField, nil);
      }
    }
#endif
  }
  return self;
}

- (void)dealloc {
  [self internalClear:NO];
  NSCAssert(!autocreator_, @"Autocreator was not cleared before dealloc.");
  [super dealloc];
}

- (void)copyFieldsInto:(GPBMessage *)message
                  zone:(NSZone *)zone
            descriptor:(GPBDescriptor *)descriptor {
  // Copy all the storage...
  memcpy(message->messageStorage_, messageStorage_, descriptor->storageSize_);

  // Loop over the fields doing fixup...
  for (GPBFieldDescriptor *field in descriptor->fields_) {
    if (GPBFieldIsMapOrArray(field)) {
      id value = GPBGetObjectIvarWithFieldNoAutocreate(self, field);
      if (value) {
        // We need to copy the array/map, but the catch is for message fields,
        // we also need to ensure all the messages as those need copying also.
        id newValue;
        if (GPBFieldDataTypeIsMessage(field)) {
          if (field.fieldType == GPBFieldTypeRepeated) {
            NSArray *existingArray = (NSArray *)value;
            NSMutableArray *newArray =
                [[NSMutableArray alloc] initWithCapacity:existingArray.count];
            newValue = newArray;
            for (GPBMessage *msg in existingArray) {
              GPBMessage *copiedMsg = [msg copyWithZone:zone];
              [newArray addObject:copiedMsg];
              [copiedMsg release];
            }
          } else {
            if (field.mapKeyDataType == GPBDataTypeString) {
              // Map is an NSDictionary.
              NSDictionary *existingDict = value;
              NSMutableDictionary *newDict =
                  [[NSMutableDictionary alloc] initWithCapacity:existingDict.count];
              newValue = newDict;
              [existingDict enumerateKeysAndObjectsUsingBlock:^(NSString *key, GPBMessage *msg,
                                                                __unused BOOL *stop) {
                GPBMessage *copiedMsg = [msg copyWithZone:zone];
                [newDict setObject:copiedMsg forKey:key];
                [copiedMsg release];
              }];
            } else {
              // Is one of the GPB*ObjectDictionary classes.  Type doesn't
              // matter, just need one to invoke the selector.
              GPBInt32ObjectDictionary *existingDict = value;
              newValue = [existingDict deepCopyWithZone:zone];
            }
          }
        } else {
          // Not messages (but is a map/array)...
          if (field.fieldType == GPBFieldTypeRepeated) {
            if (GPBFieldDataTypeIsObject(field)) {
              // NSArray
              newValue = [value mutableCopyWithZone:zone];
            } else {
              // GPB*Array
              newValue = [value copyWithZone:zone];
            }
          } else {
            if ((field.mapKeyDataType == GPBDataTypeString) && GPBFieldDataTypeIsObject(field)) {
              // NSDictionary
              newValue = [value mutableCopyWithZone:zone];
            } else {
              // Is one of the GPB*Dictionary classes.  Type doesn't matter,
              // just need one to invoke the selector.
              GPBInt32Int32Dictionary *existingDict = value;
              newValue = [existingDict copyWithZone:zone];
            }
          }
        }
        // We retain here because the memcpy picked up the pointer value and
        // the next call to SetRetainedObject... will release the current value.
        [value retain];
        GPBSetRetainedObjectIvarWithFieldPrivate(message, field, newValue);
      }
    } else if (GPBFieldDataTypeIsMessage(field)) {
      // For object types, if we have a value, copy it.  If we don't,
      // zero it to remove the pointer to something that was autocreated
      // (and the ptr just got memcpyed).
      if (GPBGetHasIvarField(self, field)) {
        GPBMessage *value = GPBGetObjectIvarWithFieldNoAutocreate(self, field);
        GPBMessage *newValue = [value copyWithZone:zone];
        // We retain here because the memcpy picked up the pointer value and
        // the next call to SetRetainedObject... will release the current value.
        [value retain];
        GPBSetRetainedObjectIvarWithFieldPrivate(message, field, newValue);
      } else {
        uint8_t *storage = (uint8_t *)message->messageStorage_;
        id *typePtr = (id *)&storage[field->description_->offset];
        *typePtr = NULL;
      }
    } else if (GPBFieldDataTypeIsObject(field) && GPBGetHasIvarField(self, field)) {
      // A set string/data value (message picked off above), copy it.
      id value = GPBGetObjectIvarWithFieldNoAutocreate(self, field);
      id newValue = [value copyWithZone:zone];
      // We retain here because the memcpy picked up the pointer value and
      // the next call to SetRetainedObject... will release the current value.
      [value retain];
      GPBSetRetainedObjectIvarWithFieldPrivate(message, field, newValue);
    } else {
      // memcpy took care of the rest of the primitive fields if they were set.
    }
  }  // for (field in descriptor->fields_)
}

- (id)copyWithZone:(NSZone *)zone {
  GPBDescriptor *descriptor = [self descriptor];
  GPBMessage *result = [[descriptor.messageClass allocWithZone:zone] init];

  [self copyFieldsInto:result zone:zone descriptor:descriptor];
  // Make immutable copies of the extra bits.
  result->unknownFields_ = [unknownFields_ copyWithZone:zone];
  result->extensionMap_ = CloneExtensionMap(extensionMap_, zone);
  return result;
}

- (void)clear {
  [self internalClear:YES];
}

- (void)internalClear:(BOOL)zeroStorage {
  GPBDescriptor *descriptor = [self descriptor];
  for (GPBFieldDescriptor *field in descriptor->fields_) {
    if (GPBFieldIsMapOrArray(field)) {
      id arrayOrMap = GPBGetObjectIvarWithFieldNoAutocreate(self, field);
      if (arrayOrMap) {
        if (field.fieldType == GPBFieldTypeRepeated) {
          if (GPBFieldDataTypeIsObject(field)) {
            if ([arrayOrMap isKindOfClass:[GPBAutocreatedArray class]]) {
              GPBAutocreatedArray *autoArray = arrayOrMap;
              if (autoArray->_autocreator == self) {
                autoArray->_autocreator = nil;
              }
            }
          } else {
            // Type doesn't matter, it is a GPB*Array.
            GPBInt32Array *gpbArray = arrayOrMap;
            if (gpbArray->_autocreator == self) {
              gpbArray->_autocreator = nil;
            }
          }
        } else {
          if ((field.mapKeyDataType == GPBDataTypeString) && GPBFieldDataTypeIsObject(field)) {
            if ([arrayOrMap isKindOfClass:[GPBAutocreatedDictionary class]]) {
              GPBAutocreatedDictionary *autoDict = arrayOrMap;
              if (autoDict->_autocreator == self) {
                autoDict->_autocreator = nil;
              }
            }
          } else {
            // Type doesn't matter, it is a GPB*Dictionary.
            GPBInt32Int32Dictionary *gpbDict = arrayOrMap;
            if (gpbDict->_autocreator == self) {
              gpbDict->_autocreator = nil;
            }
          }
        }
        [arrayOrMap release];
      }
    } else if (GPBFieldDataTypeIsMessage(field)) {
      GPBClearAutocreatedMessageIvarWithField(self, field);
      GPBMessage *value = GPBGetObjectIvarWithFieldNoAutocreate(self, field);
      [value release];
    } else if (GPBFieldDataTypeIsObject(field) && GPBGetHasIvarField(self, field)) {
      id value = GPBGetObjectIvarWithField(self, field);
      [value release];
    }
  }

  // GPBClearMessageAutocreator() expects that its caller has already been
  // removed from autocreatedExtensionMap_ so we set to nil first.
  NSArray *autocreatedValues = [autocreatedExtensionMap_ allValues];
  [autocreatedExtensionMap_ release];
  autocreatedExtensionMap_ = nil;

  // Since we're clearing all of our extensions, make sure that we clear the
  // autocreator on any that we've created so they no longer refer to us.
  for (GPBMessage *value in autocreatedValues) {
    NSCAssert(GPBWasMessageAutocreatedBy(value, self),
              @"Autocreated extension does not refer back to self.");
    GPBClearMessageAutocreator(value);
  }

  [extensionMap_ release];
  extensionMap_ = nil;
  [unknownFields_ release];
  unknownFields_ = nil;

  // Note that clearing does not affect autocreator_. If we are being cleared
  // because of a dealloc, then autocreator_ should be nil anyway. If we are
  // being cleared because someone explicitly clears us, we don't want to
  // sever our relationship with our autocreator.

  if (zeroStorage) {
    memset(messageStorage_, 0, descriptor->storageSize_);
  }
}

- (BOOL)isInitialized {
  GPBDescriptor *descriptor = [self descriptor];
  for (GPBFieldDescriptor *field in descriptor->fields_) {
    if (field.isRequired) {
      if (!GPBGetHasIvarField(self, field)) {
        return NO;
      }
    }
    if (GPBFieldDataTypeIsMessage(field)) {
      GPBFieldType fieldType = field.fieldType;
      if (fieldType == GPBFieldTypeSingle) {
        if (field.isRequired) {
          GPBMessage *message = GPBGetMessageMessageField(self, field);
          if (!message.initialized) {
            return NO;
          }
        } else {
          NSAssert(field.isOptional, @"%@: Single message field %@ not required or optional?",
                   [self class], field.name);
          if (GPBGetHasIvarField(self, field)) {
            GPBMessage *message = GPBGetMessageMessageField(self, field);
            if (!message.initialized) {
              return NO;
            }
          }
        }
      } else if (fieldType == GPBFieldTypeRepeated) {
        NSArray *array = GPBGetObjectIvarWithFieldNoAutocreate(self, field);
        for (GPBMessage *message in array) {
          if (!message.initialized) {
            return NO;
          }
        }
      } else {  // fieldType == GPBFieldTypeMap
        if (field.mapKeyDataType == GPBDataTypeString) {
          NSDictionary *map = GPBGetObjectIvarWithFieldNoAutocreate(self, field);
          if (map && !GPBDictionaryIsInitializedInternalHelper(map, field)) {
            return NO;
          }
        } else {
          // Real type is GPB*ObjectDictionary, exact type doesn't matter.
          GPBInt32ObjectDictionary *map = GPBGetObjectIvarWithFieldNoAutocreate(self, field);
          if (map && ![map isInitialized]) {
            return NO;
          }
        }
      }
    }
  }

  __block BOOL result = YES;
  [extensionMap_
      enumerateKeysAndObjectsUsingBlock:^(GPBExtensionDescriptor *extension, id obj, BOOL *stop) {
        if (GPBExtensionIsMessage(extension)) {
          if (extension.isRepeated) {
            for (GPBMessage *msg in obj) {
              if (!msg.initialized) {
                result = NO;
                *stop = YES;
                break;
              }
            }
          } else {
            GPBMessage *asMsg = obj;
            if (!asMsg.initialized) {
              result = NO;
              *stop = YES;
            }
          }
        }
      }];
  return result;
}

- (GPBDescriptor *)descriptor {
  return [[self class] descriptor];
}

- (NSData *)data {
#if defined(DEBUG) && DEBUG
  if (!self.initialized) {
    return nil;
  }
#endif
  size_t expectedSize = [self serializedSize];
  if (expectedSize > kMaximumMessageSize) {
    return nil;
  }
  NSMutableData *data = [NSMutableData dataWithLength:expectedSize];
  GPBCodedOutputStream *stream = [[GPBCodedOutputStream alloc] initWithData:data];
  @try {
    [self writeToCodedOutputStream:stream];
  } @catch (NSException *exception) {
    // This really shouldn't happen. Normally, this could mean there was a bug in the library and it
    // failed to match between computing the size and writing out the bytes. However, the more
    // common cause is while one thread was writing out the data, some other thread had a reference
    // to this message or a message used as a nested field, and that other thread mutated that
    // message, causing the pre computed serializedSize to no longer match the final size after
    // serialization. It is not safe to mutate a message while accessing it from another thread.
#if defined(DEBUG) && DEBUG
    NSLog(@"%@: Internal exception while building message data: %@", [self class], exception);
#endif
    data = nil;
  }
#if defined(DEBUG) && DEBUG
  NSAssert(!data || [stream bytesWritten] == expectedSize, @"Internal error within the library");
#endif
  [stream release];
  return data;
}

- (NSData *)delimitedData {
  size_t serializedSize = [self serializedSize];
  size_t varintSize = GPBComputeRawVarint32SizeForInteger(serializedSize);
  NSMutableData *data = [NSMutableData dataWithLength:(serializedSize + varintSize)];
  GPBCodedOutputStream *stream = [[GPBCodedOutputStream alloc] initWithData:data];
  @try {
    [self writeDelimitedToCodedOutputStream:stream];
    [stream flush];
  } @catch (NSException *exception) {
    // This really shouldn't happen. Normally, this could mean there was a bug in the library and it
    // failed to match between computing the size and writing out the bytes. However, the more
    // common cause is while one thread was writing out the data, some other thread had a reference
    // to this message or a message used as a nested field, and that other thread mutated that
    // message, causing the pre computed serializedSize to no longer match the final size after
    // serialization. It is not safe to mutate a message while accessing it from another thread.
#if defined(DEBUG) && DEBUG
    NSLog(@"%@: Internal exception while building message delimitedData: %@", [self class],
          exception);
#endif
    // If it happens, return an empty data.
    [stream release];
    return [NSData data];
  }
  [stream release];
  return data;
}

- (void)writeToOutputStream:(NSOutputStream *)output {
  GPBCodedOutputStream *stream = [[GPBCodedOutputStream alloc] initWithOutputStream:output];
  @try {
    [self writeToCodedOutputStream:stream];
    size_t bytesWritten = [stream bytesWritten];
    if (bytesWritten > kMaximumMessageSize) {
      [NSException raise:GPBMessageExceptionMessageTooLarge
                  format:@"Message would have been %zu bytes", bytesWritten];
    }
  } @finally {
    [stream release];
  }
}

- (void)writeToCodedOutputStream:(GPBCodedOutputStream *)output {
  GPBDescriptor *descriptor = [self descriptor];
  NSArray *fieldsArray = descriptor->fields_;
  NSUInteger fieldCount = fieldsArray.count;
  const GPBExtensionRange *extensionRanges = descriptor.extensionRanges;
  NSUInteger extensionRangesCount = descriptor.extensionRangesCount;
  NSArray *sortedExtensions =
      [[extensionMap_ allKeys] sortedArrayUsingSelector:@selector(compareByFieldNumber:)];
  for (NSUInteger i = 0, j = 0; i < fieldCount || j < extensionRangesCount;) {
    if (i == fieldCount) {
      [self writeExtensionsToCodedOutputStream:output
                                         range:extensionRanges[j++]
                              sortedExtensions:sortedExtensions];
    } else if (j == extensionRangesCount ||
               GPBFieldNumber(fieldsArray[i]) < extensionRanges[j].start) {
      [self writeField:fieldsArray[i++] toCodedOutputStream:output];
    } else {
      [self writeExtensionsToCodedOutputStream:output
                                         range:extensionRanges[j++]
                              sortedExtensions:sortedExtensions];
    }
  }
  if (descriptor.isWireFormat) {
    [unknownFields_ writeAsMessageSetTo:output];
  } else {
    [unknownFields_ writeToCodedOutputStream:output];
  }
}

- (void)writeDelimitedToOutputStream:(NSOutputStream *)output {
  GPBCodedOutputStream *codedOutput = [[GPBCodedOutputStream alloc] initWithOutputStream:output];
  @try {
    [self writeDelimitedToCodedOutputStream:codedOutput];
  } @finally {
    [codedOutput release];
  }
}

- (void)writeDelimitedToCodedOutputStream:(GPBCodedOutputStream *)output {
  size_t expectedSize = [self serializedSize];
  if (expectedSize > kMaximumMessageSize) {
    [NSException raise:GPBMessageExceptionMessageTooLarge
                format:@"Message would have been %zu bytes", expectedSize];
  }
  [output writeRawVarintSizeTAs32:expectedSize];
#if defined(DEBUG) && DEBUG && !defined(NS_BLOCK_ASSERTIONS)
  size_t initialSize = [output bytesWritten];
#endif
  [self writeToCodedOutputStream:output];
#if defined(DEBUG) && DEBUG && !defined(NS_BLOCK_ASSERTIONS)
  NSAssert(([output bytesWritten] - initialSize) == expectedSize,
           @"Internal error within the library");
#endif
}

- (void)writeField:(GPBFieldDescriptor *)field toCodedOutputStream:(GPBCodedOutputStream *)output {
  GPBFieldType fieldType = field.fieldType;
  if (fieldType == GPBFieldTypeSingle) {
    BOOL has = GPBGetHasIvarField(self, field);
    if (!has) {
      return;
    }
  }
  uint32_t fieldNumber = GPBFieldNumber(field);

  switch (GPBGetFieldDataType(field)) {
      // clang-format off

//%PDDM-DEFINE FIELD_CASE(TYPE, REAL_TYPE)
//%FIELD_CASE_FULL(TYPE, REAL_TYPE, REAL_TYPE)
//%PDDM-DEFINE FIELD_CASE_FULL(TYPE, REAL_TYPE, ARRAY_TYPE)
//%    case GPBDataType##TYPE:
//%      if (fieldType == GPBFieldTypeRepeated) {
//%        uint32_t tag = field.isPackable ? GPBFieldTag(field) : 0;
//%        GPB##ARRAY_TYPE##Array *array =
//%            GPBGetObjectIvarWithFieldNoAutocreate(self, field);
//%        [output write##TYPE##Array:fieldNumber values:array tag:tag];
//%      } else if (fieldType == GPBFieldTypeSingle) {
//%        [output write##TYPE:fieldNumber
//%              TYPE$S  value:GPBGetMessage##REAL_TYPE##Field(self, field)];
//%      } else {  // fieldType == GPBFieldTypeMap
//%        // Exact type here doesn't matter.
//%        GPBInt32##ARRAY_TYPE##Dictionary *dict =
//%            GPBGetObjectIvarWithFieldNoAutocreate(self, field);
//%        [dict writeToCodedOutputStream:output asField:field];
//%      }
//%      break;
//%
//%PDDM-DEFINE FIELD_CASE2(TYPE)
//%    case GPBDataType##TYPE:
//%      if (fieldType == GPBFieldTypeRepeated) {
//%        NSArray *array = GPBGetObjectIvarWithFieldNoAutocreate(self, field);
//%        [output write##TYPE##Array:fieldNumber values:array];
//%      } else if (fieldType == GPBFieldTypeSingle) {
//%        // GPBGetObjectIvarWithFieldNoAutocreate() avoids doing the has check
//%        // again.
//%        [output write##TYPE:fieldNumber
//%              TYPE$S  value:GPBGetObjectIvarWithFieldNoAutocreate(self, field)];
//%      } else {  // fieldType == GPBFieldTypeMap
//%        // Exact type here doesn't matter.
//%        id dict = GPBGetObjectIvarWithFieldNoAutocreate(self, field);
//%        GPBDataType mapKeyDataType = field.mapKeyDataType;
//%        if (mapKeyDataType == GPBDataTypeString) {
//%          GPBDictionaryWriteToStreamInternalHelper(output, dict, field);
//%        } else {
//%          [dict writeToCodedOutputStream:output asField:field];
//%        }
//%      }
//%      break;
//%
//%PDDM-EXPAND FIELD_CASE(Bool, Bool)
// This block of code is generated, do not edit it directly.

    case GPBDataTypeBool:
      if (fieldType == GPBFieldTypeRepeated) {
        uint32_t tag = field.isPackable ? GPBFieldTag(field) : 0;
        GPBBoolArray *array =
            GPBGetObjectIvarWithFieldNoAutocreate(self, field);
        [output writeBoolArray:fieldNumber values:array tag:tag];
      } else if (fieldType == GPBFieldTypeSingle) {
        [output writeBool:fieldNumber
                    value:GPBGetMessageBoolField(self, field)];
      } else {  // fieldType == GPBFieldTypeMap
        // Exact type here doesn't matter.
        GPBInt32BoolDictionary *dict =
            GPBGetObjectIvarWithFieldNoAutocreate(self, field);
        [dict writeToCodedOutputStream:output asField:field];
      }
      break;

//%PDDM-EXPAND FIELD_CASE(Fixed32, UInt32)
// This block of code is generated, do not edit it directly.

    case GPBDataTypeFixed32:
      if (fieldType == GPBFieldTypeRepeated) {
        uint32_t tag = field.isPackable ? GPBFieldTag(field) : 0;
        GPBUInt32Array *array =
            GPBGetObjectIvarWithFieldNoAutocreate(self, field);
        [output writeFixed32Array:fieldNumber values:array tag:tag];
      } else if (fieldType == GPBFieldTypeSingle) {
        [output writeFixed32:fieldNumber
                       value:GPBGetMessageUInt32Field(self, field)];
      } else {  // fieldType == GPBFieldTypeMap
        // Exact type here doesn't matter.
        GPBInt32UInt32Dictionary *dict =
            GPBGetObjectIvarWithFieldNoAutocreate(self, field);
        [dict writeToCodedOutputStream:output asField:field];
      }
      break;

//%PDDM-EXPAND FIELD_CASE(SFixed32, Int32)
// This block of code is generated, do not edit it directly.

    case GPBDataTypeSFixed32:
      if (fieldType == GPBFieldTypeRepeated) {
        uint32_t tag = field.isPackable ? GPBFieldTag(field) : 0;
        GPBInt32Array *array =
            GPBGetObjectIvarWithFieldNoAutocreate(self, field);
        [output writeSFixed32Array:fieldNumber values:array tag:tag];
      } else if (fieldType == GPBFieldTypeSingle) {
        [output writeSFixed32:fieldNumber
                        value:GPBGetMessageInt32Field(self, field)];
      } else {  // fieldType == GPBFieldTypeMap
        // Exact type here doesn't matter.
        GPBInt32Int32Dictionary *dict =
            GPBGetObjectIvarWithFieldNoAutocreate(self, field);
        [dict writeToCodedOutputStream:output asField:field];
      }
      break;

//%PDDM-EXPAND FIELD_CASE(Float, Float)
// This block of code is generated, do not edit it directly.

    case GPBDataTypeFloat:
      if (fieldType == GPBFieldTypeRepeated) {
        uint32_t tag = field.isPackable ? GPBFieldTag(field) : 0;
        GPBFloatArray *array =
            GPBGetObjectIvarWithFieldNoAutocreate(self, field);
        [output writeFloatArray:fieldNumber values:array tag:tag];
      } else if (fieldType == GPBFieldTypeSingle) {
        [output writeFloat:fieldNumber
                     value:GPBGetMessageFloatField(self, field)];
      } else {  // fieldType == GPBFieldTypeMap
        // Exact type here doesn't matter.
        GPBInt32FloatDictionary *dict =
            GPBGetObjectIvarWithFieldNoAutocreate(self, field);
        [dict writeToCodedOutputStream:output asField:field];
      }
      break;

//%PDDM-EXPAND FIELD_CASE(Fixed64, UInt64)
// This block of code is generated, do not edit it directly.

    case GPBDataTypeFixed64:
      if (fieldType == GPBFieldTypeRepeated) {
        uint32_t tag = field.isPackable ? GPBFieldTag(field) : 0;
        GPBUInt64Array *array =
            GPBGetObjectIvarWithFieldNoAutocreate(self, field);
        [output writeFixed64Array:fieldNumber values:array tag:tag];
      } else if (fieldType == GPBFieldTypeSingle) {
        [output writeFixed64:fieldNumber
                       value:GPBGetMessageUInt64Field(self, field)];
      } else {  // fieldType == GPBFieldTypeMap
        // Exact type here doesn't matter.
        GPBInt32UInt64Dictionary *dict =
            GPBGetObjectIvarWithFieldNoAutocreate(self, field);
        [dict writeToCodedOutputStream:output asField:field];
      }
      break;

//%PDDM-EXPAND FIELD_CASE(SFixed64, Int64)
// This block of code is generated, do not edit it directly.

    case GPBDataTypeSFixed64:
      if (fieldType == GPBFieldTypeRepeated) {
        uint32_t tag = field.isPackable ? GPBFieldTag(field) : 0;
        GPBInt64Array *array =
            GPBGetObjectIvarWithFieldNoAutocreate(self, field);
        [output writeSFixed64Array:fieldNumber values:array tag:tag];
      } else if (fieldType == GPBFieldTypeSingle) {
        [output writeSFixed64:fieldNumber
                        value:GPBGetMessageInt64Field(self, field)];
      } else {  // fieldType == GPBFieldTypeMap
        // Exact type here doesn't matter.
        GPBInt32Int64Dictionary *dict =
            GPBGetObjectIvarWithFieldNoAutocreate(self, field);
        [dict writeToCodedOutputStream:output asField:field];
      }
      break;

//%PDDM-EXPAND FIELD_CASE(Double, Double)
// This block of code is generated, do not edit it directly.

    case GPBDataTypeDouble:
      if (fieldType == GPBFieldTypeRepeated) {
        uint32_t tag = field.isPackable ? GPBFieldTag(field) : 0;
        GPBDoubleArray *array =
            GPBGetObjectIvarWithFieldNoAutocreate(self, field);
        [output writeDoubleArray:fieldNumber values:array tag:tag];
      } else if (fieldType == GPBFieldTypeSingle) {
        [output writeDouble:fieldNumber
                      value:GPBGetMessageDoubleField(self, field)];
      } else {  // fieldType == GPBFieldTypeMap
        // Exact type here doesn't matter.
        GPBInt32DoubleDictionary *dict =
            GPBGetObjectIvarWithFieldNoAutocreate(self, field);
        [dict writeToCodedOutputStream:output asField:field];
      }
      break;

//%PDDM-EXPAND FIELD_CASE(Int32, Int32)
// This block of code is generated, do not edit it directly.

    case GPBDataTypeInt32:
      if (fieldType == GPBFieldTypeRepeated) {
        uint32_t tag = field.isPackable ? GPBFieldTag(field) : 0;
        GPBInt32Array *array =
            GPBGetObjectIvarWithFieldNoAutocreate(self, field);
        [output writeInt32Array:fieldNumber values:array tag:tag];
      } else if (fieldType == GPBFieldTypeSingle) {
        [output writeInt32:fieldNumber
                     value:GPBGetMessageInt32Field(self, field)];
      } else {  // fieldType == GPBFieldTypeMap
        // Exact type here doesn't matter.
        GPBInt32Int32Dictionary *dict =
            GPBGetObjectIvarWithFieldNoAutocreate(self, field);
        [dict writeToCodedOutputStream:output asField:field];
      }
      break;

//%PDDM-EXPAND FIELD_CASE(Int64, Int64)
// This block of code is generated, do not edit it directly.

    case GPBDataTypeInt64:
      if (fieldType == GPBFieldTypeRepeated) {
        uint32_t tag = field.isPackable ? GPBFieldTag(field) : 0;
        GPBInt64Array *array =
            GPBGetObjectIvarWithFieldNoAutocreate(self, field);
        [output writeInt64Array:fieldNumber values:array tag:tag];
      } else if (fieldType == GPBFieldTypeSingle) {
        [output writeInt64:fieldNumber
                     value:GPBGetMessageInt64Field(self, field)];
      } else {  // fieldType == GPBFieldTypeMap
        // Exact type here doesn't matter.
        GPBInt32Int64Dictionary *dict =
            GPBGetObjectIvarWithFieldNoAutocreate(self, field);
        [dict writeToCodedOutputStream:output asField:field];
      }
      break;

//%PDDM-EXPAND FIELD_CASE(SInt32, Int32)
// This block of code is generated, do not edit it directly.

    case GPBDataTypeSInt32:
      if (fieldType == GPBFieldTypeRepeated) {
        uint32_t tag = field.isPackable ? GPBFieldTag(field) : 0;
        GPBInt32Array *array =
            GPBGetObjectIvarWithFieldNoAutocreate(self, field);
        [output writeSInt32Array:fieldNumber values:array tag:tag];
      } else if (fieldType == GPBFieldTypeSingle) {
        [output writeSInt32:fieldNumber
                      value:GPBGetMessageInt32Field(self, field)];
      } else {  // fieldType == GPBFieldTypeMap
        // Exact type here doesn't matter.
        GPBInt32Int32Dictionary *dict =
            GPBGetObjectIvarWithFieldNoAutocreate(self, field);
        [dict writeToCodedOutputStream:output asField:field];
      }
      break;

//%PDDM-EXPAND FIELD_CASE(SInt64, Int64)
// This block of code is generated, do not edit it directly.

    case GPBDataTypeSInt64:
      if (fieldType == GPBFieldTypeRepeated) {
        uint32_t tag = field.isPackable ? GPBFieldTag(field) : 0;
        GPBInt64Array *array =
            GPBGetObjectIvarWithFieldNoAutocreate(self, field);
        [output writeSInt64Array:fieldNumber values:array tag:tag];
      } else if (fieldType == GPBFieldTypeSingle) {
        [output writeSInt64:fieldNumber
                      value:GPBGetMessageInt64Field(self, field)];
      } else {  // fieldType == GPBFieldTypeMap
        // Exact type here doesn't matter.
        GPBInt32Int64Dictionary *dict =
            GPBGetObjectIvarWithFieldNoAutocreate(self, field);
        [dict writeToCodedOutputStream:output asField:field];
      }
      break;

//%PDDM-EXPAND FIELD_CASE(UInt32, UInt32)
// This block of code is generated, do not edit it directly.

    case GPBDataTypeUInt32:
      if (fieldType == GPBFieldTypeRepeated) {
        uint32_t tag = field.isPackable ? GPBFieldTag(field) : 0;
        GPBUInt32Array *array =
            GPBGetObjectIvarWithFieldNoAutocreate(self, field);
        [output writeUInt32Array:fieldNumber values:array tag:tag];
      } else if (fieldType == GPBFieldTypeSingle) {
        [output writeUInt32:fieldNumber
                      value:GPBGetMessageUInt32Field(self, field)];
      } else {  // fieldType == GPBFieldTypeMap
        // Exact type here doesn't matter.
        GPBInt32UInt32Dictionary *dict =
            GPBGetObjectIvarWithFieldNoAutocreate(self, field);
        [dict writeToCodedOutputStream:output asField:field];
      }
      break;

//%PDDM-EXPAND FIELD_CASE(UInt64, UInt64)
// This block of code is generated, do not edit it directly.

    case GPBDataTypeUInt64:
      if (fieldType == GPBFieldTypeRepeated) {
        uint32_t tag = field.isPackable ? GPBFieldTag(field) : 0;
        GPBUInt64Array *array =
            GPBGetObjectIvarWithFieldNoAutocreate(self, field);
        [output writeUInt64Array:fieldNumber values:array tag:tag];
      } else if (fieldType == GPBFieldTypeSingle) {
        [output writeUInt64:fieldNumber
                      value:GPBGetMessageUInt64Field(self, field)];
      } else {  // fieldType == GPBFieldTypeMap
        // Exact type here doesn't matter.
        GPBInt32UInt64Dictionary *dict =
            GPBGetObjectIvarWithFieldNoAutocreate(self, field);
        [dict writeToCodedOutputStream:output asField:field];
      }
      break;

//%PDDM-EXPAND FIELD_CASE_FULL(Enum, Int32, Enum)
// This block of code is generated, do not edit it directly.

    case GPBDataTypeEnum:
      if (fieldType == GPBFieldTypeRepeated) {
        uint32_t tag = field.isPackable ? GPBFieldTag(field) : 0;
        GPBEnumArray *array =
            GPBGetObjectIvarWithFieldNoAutocreate(self, field);
        [output writeEnumArray:fieldNumber values:array tag:tag];
      } else if (fieldType == GPBFieldTypeSingle) {
        [output writeEnum:fieldNumber
                    value:GPBGetMessageInt32Field(self, field)];
      } else {  // fieldType == GPBFieldTypeMap
        // Exact type here doesn't matter.
        GPBInt32EnumDictionary *dict =
            GPBGetObjectIvarWithFieldNoAutocreate(self, field);
        [dict writeToCodedOutputStream:output asField:field];
      }
      break;

//%PDDM-EXPAND FIELD_CASE2(Bytes)
// This block of code is generated, do not edit it directly.

    case GPBDataTypeBytes:
      if (fieldType == GPBFieldTypeRepeated) {
        NSArray *array = GPBGetObjectIvarWithFieldNoAutocreate(self, field);
        [output writeBytesArray:fieldNumber values:array];
      } else if (fieldType == GPBFieldTypeSingle) {
        // GPBGetObjectIvarWithFieldNoAutocreate() avoids doing the has check
        // again.
        [output writeBytes:fieldNumber
                     value:GPBGetObjectIvarWithFieldNoAutocreate(self, field)];
      } else {  // fieldType == GPBFieldTypeMap
        // Exact type here doesn't matter.
        id dict = GPBGetObjectIvarWithFieldNoAutocreate(self, field);
        GPBDataType mapKeyDataType = field.mapKeyDataType;
        if (mapKeyDataType == GPBDataTypeString) {
          GPBDictionaryWriteToStreamInternalHelper(output, dict, field);
        } else {
          [dict writeToCodedOutputStream:output asField:field];
        }
      }
      break;

//%PDDM-EXPAND FIELD_CASE2(String)
// This block of code is generated, do not edit it directly.

    case GPBDataTypeString:
      if (fieldType == GPBFieldTypeRepeated) {
        NSArray *array = GPBGetObjectIvarWithFieldNoAutocreate(self, field);
        [output writeStringArray:fieldNumber values:array];
      } else if (fieldType == GPBFieldTypeSingle) {
        // GPBGetObjectIvarWithFieldNoAutocreate() avoids doing the has check
        // again.
        [output writeString:fieldNumber
                      value:GPBGetObjectIvarWithFieldNoAutocreate(self, field)];
      } else {  // fieldType == GPBFieldTypeMap
        // Exact type here doesn't matter.
        id dict = GPBGetObjectIvarWithFieldNoAutocreate(self, field);
        GPBDataType mapKeyDataType = field.mapKeyDataType;
        if (mapKeyDataType == GPBDataTypeString) {
          GPBDictionaryWriteToStreamInternalHelper(output, dict, field);
        } else {
          [dict writeToCodedOutputStream:output asField:field];
        }
      }
      break;

//%PDDM-EXPAND FIELD_CASE2(Message)
// This block of code is generated, do not edit it directly.

    case GPBDataTypeMessage:
      if (fieldType == GPBFieldTypeRepeated) {
        NSArray *array = GPBGetObjectIvarWithFieldNoAutocreate(self, field);
        [output writeMessageArray:fieldNumber values:array];
      } else if (fieldType == GPBFieldTypeSingle) {
        // GPBGetObjectIvarWithFieldNoAutocreate() avoids doing the has check
        // again.
        [output writeMessage:fieldNumber
                       value:GPBGetObjectIvarWithFieldNoAutocreate(self, field)];
      } else {  // fieldType == GPBFieldTypeMap
        // Exact type here doesn't matter.
        id dict = GPBGetObjectIvarWithFieldNoAutocreate(self, field);
        GPBDataType mapKeyDataType = field.mapKeyDataType;
        if (mapKeyDataType == GPBDataTypeString) {
          GPBDictionaryWriteToStreamInternalHelper(output, dict, field);
        } else {
          [dict writeToCodedOutputStream:output asField:field];
        }
      }
      break;

//%PDDM-EXPAND FIELD_CASE2(Group)
// This block of code is generated, do not edit it directly.

    case GPBDataTypeGroup:
      if (fieldType == GPBFieldTypeRepeated) {
        NSArray *array = GPBGetObjectIvarWithFieldNoAutocreate(self, field);
        [output writeGroupArray:fieldNumber values:array];
      } else if (fieldType == GPBFieldTypeSingle) {
        // GPBGetObjectIvarWithFieldNoAutocreate() avoids doing the has check
        // again.
        [output writeGroup:fieldNumber
                     value:GPBGetObjectIvarWithFieldNoAutocreate(self, field)];
      } else {  // fieldType == GPBFieldTypeMap
        // Exact type here doesn't matter.
        id dict = GPBGetObjectIvarWithFieldNoAutocreate(self, field);
        GPBDataType mapKeyDataType = field.mapKeyDataType;
        if (mapKeyDataType == GPBDataTypeString) {
          GPBDictionaryWriteToStreamInternalHelper(output, dict, field);
        } else {
          [dict writeToCodedOutputStream:output asField:field];
        }
      }
      break;

//%PDDM-EXPAND-END (18 expansions)

      // clang-format on
  }
}

#pragma mark - Extensions

- (id)getExtension:(GPBExtensionDescriptor *)extension {
  CheckExtension(self, extension);
  id value = [extensionMap_ objectForKey:extension];
  if (value != nil) {
    return value;
  }

  // No default for repeated.
  if (extension.isRepeated) {
    return nil;
  }
  // Non messages get their default.
  if (!GPBExtensionIsMessage(extension)) {
    return extension.defaultValue;
  }

  // Check for an autocreated value.
  os_unfair_lock_lock(&readOnlyLock_);
  value = [autocreatedExtensionMap_ objectForKey:extension];
  if (!value) {
    // Auto create the message extensions to match normal fields.
    value = CreateMessageWithAutocreatorForExtension(extension.msgClass, self, extension);

    if (autocreatedExtensionMap_ == nil) {
      autocreatedExtensionMap_ = [[NSMutableDictionary alloc] init];
    }

    // We can't simply call setExtension here because that would clear the new
    // value's autocreator.
    [autocreatedExtensionMap_ setObject:value forKey:extension];
    [value release];
  }

  os_unfair_lock_unlock(&readOnlyLock_);
  return value;
}

- (id)getExistingExtension:(GPBExtensionDescriptor *)extension {
  // This is an internal method so we don't need to call CheckExtension().
  return [extensionMap_ objectForKey:extension];
}

- (BOOL)hasExtension:(GPBExtensionDescriptor *)extension {
#if defined(DEBUG) && DEBUG
  CheckExtension(self, extension);
#endif  // DEBUG
  return nil != [extensionMap_ objectForKey:extension];
}

- (NSArray *)extensionsCurrentlySet {
  return [extensionMap_ allKeys];
}

- (void)writeExtensionsToCodedOutputStream:(GPBCodedOutputStream *)output
                                     range:(GPBExtensionRange)range
                          sortedExtensions:(NSArray *)sortedExtensions {
  uint32_t start = range.start;
  uint32_t end = range.end;
  for (GPBExtensionDescriptor *extension in sortedExtensions) {
    uint32_t fieldNumber = extension.fieldNumber;
    if (fieldNumber < start) {
      continue;
    }
    if (fieldNumber >= end) {
      break;
    }
    id value = [extensionMap_ objectForKey:extension];
    GPBWriteExtensionValueToOutputStream(extension, value, output);
  }
}

- (void)setExtension:(GPBExtensionDescriptor *)extension value:(id)value {
  if (!value) {
    [self clearExtension:extension];
    return;
  }

  CheckExtension(self, extension);

  if (extension.repeated) {
    [NSException raise:NSInvalidArgumentException
                format:@"Must call addExtension() for repeated types."];
  }

  if (extensionMap_ == nil) {
    extensionMap_ = [[NSMutableDictionary alloc] init];
  }

  // This pointless cast is for CLANG_WARN_NULLABLE_TO_NONNULL_CONVERSION.
  // Without it, the compiler complains we're passing an id nullable when
  // setObject:forKey: requires a id nonnull for the value. The check for
  // !value at the start of the method ensures it isn't nil, but the check
  // isn't smart enough to realize that.
  [extensionMap_ setObject:(id)value forKey:extension];

  GPBExtensionDescriptor *descriptor = extension;

  if (GPBExtensionIsMessage(descriptor) && !descriptor.isRepeated) {
    GPBMessage *autocreatedValue = [[autocreatedExtensionMap_ objectForKey:extension] retain];
    // Must remove from the map before calling GPBClearMessageAutocreator() so
    // that GPBClearMessageAutocreator() knows its safe to clear.
    [autocreatedExtensionMap_ removeObjectForKey:extension];
    GPBClearMessageAutocreator(autocreatedValue);
    [autocreatedValue release];
  }

  GPBBecomeVisibleToAutocreator(self);
}

- (void)addExtension:(GPBExtensionDescriptor *)extension value:(id)value {
  CheckExtension(self, extension);

  if (!extension.repeated) {
    [NSException raise:NSInvalidArgumentException
                format:@"Must call setExtension() for singular types."];
  }

  if (extensionMap_ == nil) {
    extensionMap_ = [[NSMutableDictionary alloc] init];
  }
  NSMutableArray *list = [extensionMap_ objectForKey:extension];
  if (list == nil) {
    list = [NSMutableArray array];
    [extensionMap_ setObject:list forKey:extension];
  }

  [list addObject:value];
  GPBBecomeVisibleToAutocreator(self);
}

- (void)setExtension:(GPBExtensionDescriptor *)extension index:(NSUInteger)idx value:(id)value {
  CheckExtension(self, extension);

  if (!extension.repeated) {
    [NSException raise:NSInvalidArgumentException
                format:@"Must call setExtension() for singular types."];
  }

  if (extensionMap_ == nil) {
    extensionMap_ = [[NSMutableDictionary alloc] init];
  }

  NSMutableArray *list = [extensionMap_ objectForKey:extension];

  [list replaceObjectAtIndex:idx withObject:value];
  GPBBecomeVisibleToAutocreator(self);
}

- (void)clearExtension:(GPBExtensionDescriptor *)extension {
  CheckExtension(self, extension);

  // Only become visible if there was actually a value to clear.
  if ([extensionMap_ objectForKey:extension]) {
    [extensionMap_ removeObjectForKey:extension];
    GPBBecomeVisibleToAutocreator(self);
  }
}

#pragma mark - mergeFrom

- (void)mergeFromData:(NSData *)data extensionRegistry:(id<GPBExtensionRegistry>)extensionRegistry {
  GPBCodedInputStream *input = [[GPBCodedInputStream alloc] initWithData:data];
  @try {
    [self mergeFromCodedInputStream:input extensionRegistry:extensionRegistry];
    [input checkLastTagWas:0];
  } @finally {
    [input release];
  }
}

- (BOOL)mergeFromData:(NSData *)data
    extensionRegistry:(nullable id<GPBExtensionRegistry>)extensionRegistry
                error:(NSError **)errorPtr {
  GPBCodedInputStream *input = [[GPBCodedInputStream alloc] initWithData:data];
  @try {
    [self mergeFromCodedInputStream:input extensionRegistry:extensionRegistry];
    [input checkLastTagWas:0];
    if (errorPtr) {
      *errorPtr = nil;
    }
  } @catch (NSException *exception) {
    [input release];
    if (errorPtr) {
      *errorPtr = ErrorFromException(exception);
    }
    return NO;
  }
  [input release];
  return YES;
}

#pragma mark - Parse From Data Support

+ (instancetype)parseFromData:(NSData *)data error:(NSError **)errorPtr {
  return [self parseFromData:data extensionRegistry:nil error:errorPtr];
}

+ (instancetype)parseFromData:(NSData *)data
            extensionRegistry:(id<GPBExtensionRegistry>)extensionRegistry
                        error:(NSError **)errorPtr {
  return [[[self alloc] initWithData:data extensionRegistry:extensionRegistry
                               error:errorPtr] autorelease];
}

+ (instancetype)parseFromCodedInputStream:(GPBCodedInputStream *)input
                        extensionRegistry:(id<GPBExtensionRegistry>)extensionRegistry
                                    error:(NSError **)errorPtr {
  return [[[self alloc] initWithCodedInputStream:input
                               extensionRegistry:extensionRegistry
                                           error:errorPtr] autorelease];
}

#pragma mark - Parse Delimited From Data Support

+ (instancetype)parseDelimitedFromCodedInputStream:(GPBCodedInputStream *)input
                                 extensionRegistry:(id<GPBExtensionRegistry>)extensionRegistry
                                             error:(NSError **)errorPtr {
  GPBCodedInputStreamState *state = &input->state_;
  // This doesn't completely match the C++, but if the stream has nothing, just make an empty
  // message.
  if (GPBCodedInputStreamIsAtEnd(state)) {
    return [[[self alloc] init] autorelease];
  }

  // Manually extract the data and parse it. If we read a varint and push a limit, that consumes
  // some of the recursion buffer which isn't correct, it also can result in a change in error
  // codes for attempts to parse partial data; and there are projects sensitive to that, so this
  // maintains existing error flows.

  // Extract the data, but in a "no copy" mode since we will immediately parse it so this NSData
  // is transient.
  NSData *data = nil;
  @try {
    data = GPBCodedInputStreamReadRetainedBytesNoCopy(state);
  } @catch (NSException *exception) {
    if (errorPtr) {
      *errorPtr = ErrorFromException(exception);
    }
    return nil;
  }

  GPBMessage *result = [self parseFromData:data extensionRegistry:extensionRegistry error:errorPtr];
  [data release];
  if (result && errorPtr) {
    *errorPtr = nil;
  }
  return result;
}

#pragma mark - Unknown Field Support

- (GPBUnknownFieldSet *)unknownFields {
  return unknownFields_;
}

- (void)setUnknownFields:(GPBUnknownFieldSet *)unknownFields {
  if (unknownFields != unknownFields_) {
    [unknownFields_ release];
    unknownFields_ = [unknownFields copy];
    GPBBecomeVisibleToAutocreator(self);
  }
}

- (void)parseMessageSet:(GPBCodedInputStream *)input
      extensionRegistry:(id<GPBExtensionRegistry>)extensionRegistry {
  uint32_t typeId = 0;
  NSData *rawBytes = nil;
  GPBExtensionDescriptor *extension = nil;
  GPBCodedInputStreamState *state = &input->state_;
  while (true) {
    uint32_t tag = GPBCodedInputStreamReadTag(state);
    if (tag == 0) {
      break;
    }

    if (tag == GPBWireFormatMessageSetTypeIdTag) {
      typeId = GPBCodedInputStreamReadUInt32(state);
      if (typeId != 0) {
        extension = [extensionRegistry extensionForDescriptor:[self descriptor] fieldNumber:typeId];
      }
    } else if (tag == GPBWireFormatMessageSetMessageTag) {
      rawBytes = [GPBCodedInputStreamReadRetainedBytesNoCopy(state) autorelease];
    } else {
      if (![input skipField:tag]) {
        break;
      }
    }
  }

  [input checkLastTagWas:GPBWireFormatMessageSetItemEndTag];

  if (rawBytes != nil && typeId != 0) {
    if (extension != nil) {
      GPBCodedInputStream *newInput = [[GPBCodedInputStream alloc] initWithData:rawBytes];
      @try {
        ExtensionMergeFromInputStream(extension, extension.packable, newInput, extensionRegistry,
                                      self);
      } @finally {
        [newInput release];
      }
    } else {
      GPBUnknownFieldSet *unknownFields = GetOrMakeUnknownFields(self);
      // rawBytes was created via a NoCopy, so it can be reusing a
      // subrange of another NSData that might go out of scope as things
      // unwind, so a copy is needed to ensure what is saved in the
      // unknown fields stays valid.
      NSData *cloned = [NSData dataWithData:rawBytes];
      [unknownFields mergeMessageSetMessage:typeId data:cloned];
    }
  }
}

- (BOOL)parseUnknownField:(GPBCodedInputStream *)input
        extensionRegistry:(id<GPBExtensionRegistry>)extensionRegistry
                      tag:(uint32_t)tag {
  GPBWireFormat wireType = GPBWireFormatGetTagWireType(tag);
  int32_t fieldNumber = GPBWireFormatGetTagFieldNumber(tag);

  GPBDescriptor *descriptor = [self descriptor];
  GPBExtensionDescriptor *extension = [extensionRegistry extensionForDescriptor:descriptor
                                                                    fieldNumber:fieldNumber];
  if (extension == nil) {
    if (descriptor.wireFormat && GPBWireFormatMessageSetItemTag == tag) {
      [self parseMessageSet:input extensionRegistry:extensionRegistry];
      return YES;
    }
  } else {
    if (extension.wireType == wireType) {
      ExtensionMergeFromInputStream(extension, extension.packable, input, extensionRegistry, self);
      return YES;
    }
    // Primitive, repeated types can be packed on unpacked on the wire, and are
    // parsed either way.
    if ([extension isRepeated] && !GPBDataTypeIsObject(extension->description_->dataType) &&
        (extension.alternateWireType == wireType)) {
      ExtensionMergeFromInputStream(extension, !extension.packable, input, extensionRegistry, self);
      return YES;
    }
  }
  if ([GPBUnknownFieldSet isFieldTag:tag]) {
    GPBUnknownFieldSet *unknownFields = GetOrMakeUnknownFields(self);
    return [unknownFields mergeFieldFrom:tag input:input];
  } else {
    return NO;
  }
}

- (void)addUnknownMapEntry:(int32_t)fieldNum value:(NSData *)data {
  GPBUnknownFieldSet *unknownFields = GetOrMakeUnknownFields(self);
  [unknownFields addUnknownMapEntry:fieldNum value:data];
}

#pragma mark - MergeFromCodedInputStream Support

static void MergeSingleFieldFromCodedInputStream(GPBMessage *self, GPBFieldDescriptor *field,
                                                 GPBCodedInputStream *input,
                                                 id<GPBExtensionRegistry> extensionRegistry) {
  GPBDataType fieldDataType = GPBGetFieldDataType(field);
  switch (fieldDataType) {
#define CASE_SINGLE_POD(NAME, TYPE, FUNC_TYPE)                 \
  case GPBDataType##NAME: {                                    \
    TYPE val = GPBCodedInputStreamRead##NAME(&input->state_);  \
    GPBSet##FUNC_TYPE##IvarWithFieldPrivate(self, field, val); \
    break;                                                     \
  }
#define CASE_SINGLE_OBJECT(NAME)                                    \
  case GPBDataType##NAME: {                                         \
    id val = GPBCodedInputStreamReadRetained##NAME(&input->state_); \
    GPBSetRetainedObjectIvarWithFieldPrivate(self, field, val);     \
    break;                                                          \
  }
    CASE_SINGLE_POD(Bool, BOOL, Bool)
    CASE_SINGLE_POD(Fixed32, uint32_t, UInt32)
    CASE_SINGLE_POD(SFixed32, int32_t, Int32)
    CASE_SINGLE_POD(Float, float, Float)
    CASE_SINGLE_POD(Fixed64, uint64_t, UInt64)
    CASE_SINGLE_POD(SFixed64, int64_t, Int64)
    CASE_SINGLE_POD(Double, double, Double)
    CASE_SINGLE_POD(Int32, int32_t, Int32)
    CASE_SINGLE_POD(Int64, int64_t, Int64)
    CASE_SINGLE_POD(SInt32, int32_t, Int32)
    CASE_SINGLE_POD(SInt64, int64_t, Int64)
    CASE_SINGLE_POD(UInt32, uint32_t, UInt32)
    CASE_SINGLE_POD(UInt64, uint64_t, UInt64)
    CASE_SINGLE_OBJECT(Bytes)
    CASE_SINGLE_OBJECT(String)
#undef CASE_SINGLE_POD
#undef CASE_SINGLE_OBJECT

    case GPBDataTypeMessage: {
      if (GPBGetHasIvarField(self, field)) {
        // GPBGetObjectIvarWithFieldNoAutocreate() avoids doing the has
        // check again.
        GPBMessage *message = GPBGetObjectIvarWithFieldNoAutocreate(self, field);
        [input readMessage:message extensionRegistry:extensionRegistry];
      } else {
        GPBMessage *message = [[field.msgClass alloc] init];
        GPBSetRetainedObjectIvarWithFieldPrivate(self, field, message);
        [input readMessage:message extensionRegistry:extensionRegistry];
      }
      break;
    }

    case GPBDataTypeGroup: {
      if (GPBGetHasIvarField(self, field)) {
        // GPBGetObjectIvarWithFieldNoAutocreate() avoids doing the has
        // check again.
        GPBMessage *message = GPBGetObjectIvarWithFieldNoAutocreate(self, field);
        [input readGroup:GPBFieldNumber(field) message:message extensionRegistry:extensionRegistry];
      } else {
        GPBMessage *message = [[field.msgClass alloc] init];
        GPBSetRetainedObjectIvarWithFieldPrivate(self, field, message);
        [input readGroup:GPBFieldNumber(field) message:message extensionRegistry:extensionRegistry];
      }
      break;
    }

    case GPBDataTypeEnum: {
      int32_t val = GPBCodedInputStreamReadEnum(&input->state_);
      if (!GPBFieldIsClosedEnum(field) || [field isValidEnumValue:val]) {
        GPBSetInt32IvarWithFieldPrivate(self, field, val);
      } else {
        GPBUnknownFieldSet *unknownFields = GetOrMakeUnknownFields(self);
        [unknownFields mergeVarintField:GPBFieldNumber(field) value:val];
      }
    }
  }  // switch
}

static void MergeRepeatedPackedFieldFromCodedInputStream(GPBMessage *self,
                                                         GPBFieldDescriptor *field,
                                                         GPBCodedInputStream *input) {
  GPBDataType fieldDataType = GPBGetFieldDataType(field);
  GPBCodedInputStreamState *state = &input->state_;
  id genericArray = GetOrCreateArrayIvarWithField(self, field);
  int32_t length = GPBCodedInputStreamReadInt32(state);
  size_t limit = GPBCodedInputStreamPushLimit(state, length);
  while (GPBCodedInputStreamBytesUntilLimit(state) > 0) {
    switch (fieldDataType) {
#define CASE_REPEATED_PACKED_POD(NAME, TYPE, ARRAY_TYPE)   \
  case GPBDataType##NAME: {                                \
    TYPE val = GPBCodedInputStreamRead##NAME(state);       \
    [(GPB##ARRAY_TYPE##Array *)genericArray addValue:val]; \
    break;                                                 \
  }
      CASE_REPEATED_PACKED_POD(Bool, BOOL, Bool)
      CASE_REPEATED_PACKED_POD(Fixed32, uint32_t, UInt32)
      CASE_REPEATED_PACKED_POD(SFixed32, int32_t, Int32)
      CASE_REPEATED_PACKED_POD(Float, float, Float)
      CASE_REPEATED_PACKED_POD(Fixed64, uint64_t, UInt64)
      CASE_REPEATED_PACKED_POD(SFixed64, int64_t, Int64)
      CASE_REPEATED_PACKED_POD(Double, double, Double)
      CASE_REPEATED_PACKED_POD(Int32, int32_t, Int32)
      CASE_REPEATED_PACKED_POD(Int64, int64_t, Int64)
      CASE_REPEATED_PACKED_POD(SInt32, int32_t, Int32)
      CASE_REPEATED_PACKED_POD(SInt64, int64_t, Int64)
      CASE_REPEATED_PACKED_POD(UInt32, uint32_t, UInt32)
      CASE_REPEATED_PACKED_POD(UInt64, uint64_t, UInt64)
#undef CASE_REPEATED_PACKED_POD

      case GPBDataTypeBytes:
      case GPBDataTypeString:
      case GPBDataTypeMessage:
      case GPBDataTypeGroup:
        NSCAssert(NO, @"Non primitive types can't be packed");
        break;

      case GPBDataTypeEnum: {
        int32_t val = GPBCodedInputStreamReadEnum(state);
        if (!GPBFieldIsClosedEnum(field) || [field isValidEnumValue:val]) {
          [(GPBEnumArray *)genericArray addRawValue:val];
        } else {
          GPBUnknownFieldSet *unknownFields = GetOrMakeUnknownFields(self);
          [unknownFields mergeVarintField:GPBFieldNumber(field) value:val];
        }
        break;
      }
    }  // switch
  }    // while(BytesUntilLimit() > 0)
  GPBCodedInputStreamPopLimit(state, limit);
}

static void MergeRepeatedNotPackedFieldFromCodedInputStream(
    GPBMessage *self, GPBFieldDescriptor *field, GPBCodedInputStream *input,
    id<GPBExtensionRegistry> extensionRegistry) {
  GPBCodedInputStreamState *state = &input->state_;
  id genericArray = GetOrCreateArrayIvarWithField(self, field);
  switch (GPBGetFieldDataType(field)) {
#define CASE_REPEATED_NOT_PACKED_POD(NAME, TYPE, ARRAY_TYPE) \
  case GPBDataType##NAME: {                                  \
    TYPE val = GPBCodedInputStreamRead##NAME(state);         \
    [(GPB##ARRAY_TYPE##Array *)genericArray addValue:val];   \
    break;                                                   \
  }
#define CASE_REPEATED_NOT_PACKED_OBJECT(NAME)              \
  case GPBDataType##NAME: {                                \
    id val = GPBCodedInputStreamReadRetained##NAME(state); \
    [(NSMutableArray *)genericArray addObject:val];        \
    [val release];                                         \
    break;                                                 \
  }
    CASE_REPEATED_NOT_PACKED_POD(Bool, BOOL, Bool)
    CASE_REPEATED_NOT_PACKED_POD(Fixed32, uint32_t, UInt32)
    CASE_REPEATED_NOT_PACKED_POD(SFixed32, int32_t, Int32)
    CASE_REPEATED_NOT_PACKED_POD(Float, float, Float)
    CASE_REPEATED_NOT_PACKED_POD(Fixed64, uint64_t, UInt64)
    CASE_REPEATED_NOT_PACKED_POD(SFixed64, int64_t, Int64)
    CASE_REPEATED_NOT_PACKED_POD(Double, double, Double)
    CASE_REPEATED_NOT_PACKED_POD(Int32, int32_t, Int32)
    CASE_REPEATED_NOT_PACKED_POD(Int64, int64_t, Int64)
    CASE_REPEATED_NOT_PACKED_POD(SInt32, int32_t, Int32)
    CASE_REPEATED_NOT_PACKED_POD(SInt64, int64_t, Int64)
    CASE_REPEATED_NOT_PACKED_POD(UInt32, uint32_t, UInt32)
    CASE_REPEATED_NOT_PACKED_POD(UInt64, uint64_t, UInt64)
    CASE_REPEATED_NOT_PACKED_OBJECT(Bytes)
    CASE_REPEATED_NOT_PACKED_OBJECT(String)
#undef CASE_REPEATED_NOT_PACKED_POD
#undef CASE_NOT_PACKED_OBJECT
    case GPBDataTypeMessage: {
      GPBMessage *message = [[field.msgClass alloc] init];
      [(NSMutableArray *)genericArray addObject:message];
      // The array will now retain message, so go ahead and release it in case
      // -readMessage:extensionRegistry: throws so it won't be leaked.
      [message release];
      [input readMessage:message extensionRegistry:extensionRegistry];
      break;
    }
    case GPBDataTypeGroup: {
      GPBMessage *message = [[field.msgClass alloc] init];
      [(NSMutableArray *)genericArray addObject:message];
      // The array will now retain message, so go ahead and release it in case
      // -readGroup:extensionRegistry: throws so it won't be leaked.
      [message release];
      [input readGroup:GPBFieldNumber(field) message:message extensionRegistry:extensionRegistry];
      break;
    }
    case GPBDataTypeEnum: {
      int32_t val = GPBCodedInputStreamReadEnum(state);
      if (!GPBFieldIsClosedEnum(field) || [field isValidEnumValue:val]) {
        [(GPBEnumArray *)genericArray addRawValue:val];
      } else {
        GPBUnknownFieldSet *unknownFields = GetOrMakeUnknownFields(self);
        [unknownFields mergeVarintField:GPBFieldNumber(field) value:val];
      }
      break;
    }
  }  // switch
}

- (void)mergeFromCodedInputStream:(GPBCodedInputStream *)input
                extensionRegistry:(id<GPBExtensionRegistry>)extensionRegistry {
  GPBDescriptor *descriptor = [self descriptor];
  GPBCodedInputStreamState *state = &input->state_;
  uint32_t tag = 0;
  NSUInteger startingIndex = 0;
  NSArray *fields = descriptor->fields_;
  NSUInteger numFields = fields.count;
  while (YES) {
    BOOL merged = NO;
    tag = GPBCodedInputStreamReadTag(state);
    if (tag == 0) {
      break;  // Reached end.
    }
    for (NSUInteger i = 0; i < numFields; ++i) {
      if (startingIndex >= numFields) startingIndex = 0;
      GPBFieldDescriptor *fieldDescriptor = fields[startingIndex];
      if (GPBFieldTag(fieldDescriptor) == tag) {
        GPBFieldType fieldType = fieldDescriptor.fieldType;
        if (fieldType == GPBFieldTypeSingle) {
          MergeSingleFieldFromCodedInputStream(self, fieldDescriptor, input, extensionRegistry);
          // Well formed protos will only have a single field once, advance
          // the starting index to the next field.
          startingIndex += 1;
        } else if (fieldType == GPBFieldTypeRepeated) {
          if (fieldDescriptor.isPackable) {
            MergeRepeatedPackedFieldFromCodedInputStream(self, fieldDescriptor, input);
            // Well formed protos will only have a repeated field that is
            // packed once, advance the starting index to the next field.
            startingIndex += 1;
          } else {
            MergeRepeatedNotPackedFieldFromCodedInputStream(self, fieldDescriptor, input,
                                                            extensionRegistry);
          }
        } else {  // fieldType == GPBFieldTypeMap
          // GPB*Dictionary or NSDictionary, exact type doesn't matter at this
          // point.
          id map = GetOrCreateMapIvarWithField(self, fieldDescriptor);
          [input readMapEntry:map
              extensionRegistry:extensionRegistry
                          field:fieldDescriptor
                  parentMessage:self];
        }
        merged = YES;
        break;
      } else {
        startingIndex += 1;
      }
    }  // for(i < numFields)

    if (!merged && (tag != 0)) {
      // Primitive, repeated types can be packed on unpacked on the wire, and
      // are parsed either way.  The above loop covered tag in the preferred
      // for, so this need to check the alternate form.
      for (NSUInteger i = 0; i < numFields; ++i) {
        if (startingIndex >= numFields) startingIndex = 0;
        GPBFieldDescriptor *fieldDescriptor = fields[startingIndex];
        if ((fieldDescriptor.fieldType == GPBFieldTypeRepeated) &&
            !GPBFieldDataTypeIsObject(fieldDescriptor) &&
            (GPBFieldAlternateTag(fieldDescriptor) == tag)) {
          BOOL alternateIsPacked = !fieldDescriptor.isPackable;
          if (alternateIsPacked) {
            MergeRepeatedPackedFieldFromCodedInputStream(self, fieldDescriptor, input);
            // Well formed protos will only have a repeated field that is
            // packed once, advance the starting index to the next field.
            startingIndex += 1;
          } else {
            MergeRepeatedNotPackedFieldFromCodedInputStream(self, fieldDescriptor, input,
                                                            extensionRegistry);
          }
          merged = YES;
          break;
        } else {
          startingIndex += 1;
        }
      }
    }

    if (!merged) {
      if (tag == 0) {
        // zero signals EOF / limit reached
        return;
      } else {
        if (![self parseUnknownField:input extensionRegistry:extensionRegistry tag:tag]) {
          // it's an endgroup tag
          return;
        }
      }
    }  // if(!merged)

  }  // while(YES)
}

#pragma mark - MergeFrom Support

- (void)mergeFrom:(GPBMessage *)other {
  Class selfClass = [self class];
  Class otherClass = [other class];
  if (!([selfClass isSubclassOfClass:otherClass] || [otherClass isSubclassOfClass:selfClass])) {
    [NSException raise:NSInvalidArgumentException
                format:@"Classes must match %@ != %@", selfClass, otherClass];
  }

  // We assume something will be done and become visible.
  GPBBecomeVisibleToAutocreator(self);

  GPBDescriptor *descriptor = [[self class] descriptor];

  for (GPBFieldDescriptor *field in descriptor->fields_) {
    GPBFieldType fieldType = field.fieldType;
    if (fieldType == GPBFieldTypeSingle) {
      int32_t hasIndex = GPBFieldHasIndex(field);
      uint32_t fieldNumber = GPBFieldNumber(field);
      if (!GPBGetHasIvar(other, hasIndex, fieldNumber)) {
        // Other doesn't have the field set, on to the next.
        continue;
      }
      GPBDataType fieldDataType = GPBGetFieldDataType(field);
      switch (fieldDataType) {
        case GPBDataTypeBool:
          GPBSetBoolIvarWithFieldPrivate(self, field, GPBGetMessageBoolField(other, field));
          break;
        case GPBDataTypeSFixed32:
        case GPBDataTypeEnum:
        case GPBDataTypeInt32:
        case GPBDataTypeSInt32:
          GPBSetInt32IvarWithFieldPrivate(self, field, GPBGetMessageInt32Field(other, field));
          break;
        case GPBDataTypeFixed32:
        case GPBDataTypeUInt32:
          GPBSetUInt32IvarWithFieldPrivate(self, field, GPBGetMessageUInt32Field(other, field));
          break;
        case GPBDataTypeSFixed64:
        case GPBDataTypeInt64:
        case GPBDataTypeSInt64:
          GPBSetInt64IvarWithFieldPrivate(self, field, GPBGetMessageInt64Field(other, field));
          break;
        case GPBDataTypeFixed64:
        case GPBDataTypeUInt64:
          GPBSetUInt64IvarWithFieldPrivate(self, field, GPBGetMessageUInt64Field(other, field));
          break;
        case GPBDataTypeFloat:
          GPBSetFloatIvarWithFieldPrivate(self, field, GPBGetMessageFloatField(other, field));
          break;
        case GPBDataTypeDouble:
          GPBSetDoubleIvarWithFieldPrivate(self, field, GPBGetMessageDoubleField(other, field));
          break;
        case GPBDataTypeBytes:
        case GPBDataTypeString: {
          id otherVal = GPBGetObjectIvarWithFieldNoAutocreate(other, field);
          GPBSetObjectIvarWithFieldPrivate(self, field, otherVal);
          break;
        }
        case GPBDataTypeMessage:
        case GPBDataTypeGroup: {
          id otherVal = GPBGetObjectIvarWithFieldNoAutocreate(other, field);
          if (GPBGetHasIvar(self, hasIndex, fieldNumber)) {
            GPBMessage *message = GPBGetObjectIvarWithFieldNoAutocreate(self, field);
            [message mergeFrom:otherVal];
          } else {
            GPBMessage *message = [otherVal copy];
            GPBSetRetainedObjectIvarWithFieldPrivate(self, field, message);
          }
          break;
        }
      }  // switch()
    } else if (fieldType == GPBFieldTypeRepeated) {
      // In the case of a list, they need to be appended, and there is no
      // _hasIvar to worry about setting.
      id otherArray = GPBGetObjectIvarWithFieldNoAutocreate(other, field);
      if (otherArray) {
        GPBDataType fieldDataType = field->description_->dataType;
        if (GPBDataTypeIsObject(fieldDataType)) {
          NSMutableArray *resultArray = GetOrCreateArrayIvarWithField(self, field);
          [resultArray addObjectsFromArray:otherArray];
        } else if (fieldDataType == GPBDataTypeEnum) {
          GPBEnumArray *resultArray = GetOrCreateArrayIvarWithField(self, field);
          [resultArray addRawValuesFromArray:otherArray];
        } else {
          // The array type doesn't matter, that all implement
          // -addValuesFromArray:.
          GPBInt32Array *resultArray = GetOrCreateArrayIvarWithField(self, field);
          [resultArray addValuesFromArray:otherArray];
        }
      }
    } else {  // fieldType = GPBFieldTypeMap
      // In the case of a map, they need to be merged, and there is no
      // _hasIvar to worry about setting.
      id otherDict = GPBGetObjectIvarWithFieldNoAutocreate(other, field);
      if (otherDict) {
        GPBDataType keyDataType = field.mapKeyDataType;
        GPBDataType valueDataType = field->description_->dataType;
        if (GPBDataTypeIsObject(keyDataType) && GPBDataTypeIsObject(valueDataType)) {
          NSMutableDictionary *resultDict = GetOrCreateMapIvarWithField(self, field);
          [resultDict addEntriesFromDictionary:otherDict];
        } else if (valueDataType == GPBDataTypeEnum) {
          // The exact type doesn't matter, just need to know it is a
          // GPB*EnumDictionary.
          GPBInt32EnumDictionary *resultDict = GetOrCreateMapIvarWithField(self, field);
          [resultDict addRawEntriesFromDictionary:otherDict];
        } else {
          // The exact type doesn't matter, they all implement
          // -addEntriesFromDictionary:.
          GPBInt32Int32Dictionary *resultDict = GetOrCreateMapIvarWithField(self, field);
          [resultDict addEntriesFromDictionary:otherDict];
        }
      }
    }  // if (fieldType)..else if...else
  }    // for(fields)

  // Unknown fields.
  if (!unknownFields_) {
    [self setUnknownFields:other.unknownFields];
  } else {
    [unknownFields_ mergeUnknownFields:other.unknownFields];
  }

  // Extensions

  if (other->extensionMap_.count == 0) {
    return;
  }

  if (extensionMap_ == nil) {
    extensionMap_ = CloneExtensionMap(other->extensionMap_, NSZoneFromPointer(self));
  } else {
    for (GPBExtensionDescriptor *extension in other->extensionMap_) {
      id otherValue = [other->extensionMap_ objectForKey:extension];
      id value = [extensionMap_ objectForKey:extension];
      BOOL isMessageExtension = GPBExtensionIsMessage(extension);

      if (extension.repeated) {
        NSMutableArray *list = value;
        if (list == nil) {
          list = [[NSMutableArray alloc] init];
          [extensionMap_ setObject:list forKey:extension];
          [list release];
        }
        if (isMessageExtension) {
          for (GPBMessage *otherListValue in otherValue) {
            GPBMessage *copiedValue = [otherListValue copy];
            [list addObject:copiedValue];
            [copiedValue release];
          }
        } else {
          [list addObjectsFromArray:otherValue];
        }
      } else {
        if (isMessageExtension) {
          if (value) {
            [(GPBMessage *)value mergeFrom:(GPBMessage *)otherValue];
          } else {
            GPBMessage *copiedValue = [otherValue copy];
            [extensionMap_ setObject:copiedValue forKey:extension];
            [copiedValue release];
          }
        } else {
          [extensionMap_ setObject:otherValue forKey:extension];
        }
      }

      if (isMessageExtension && !extension.isRepeated) {
        GPBMessage *autocreatedValue = [[autocreatedExtensionMap_ objectForKey:extension] retain];
        // Must remove from the map before calling GPBClearMessageAutocreator()
        // so that GPBClearMessageAutocreator() knows its safe to clear.
        [autocreatedExtensionMap_ removeObjectForKey:extension];
        GPBClearMessageAutocreator(autocreatedValue);
        [autocreatedValue release];
      }
    }
  }
}

#pragma mark - isEqual: & hash Support

- (BOOL)isEqual:(id)other {
  if (other == self) {
    return YES;
  }
  if (![other isKindOfClass:[GPBMessage class]]) {
    return NO;
  }
  GPBMessage *otherMsg = other;
  GPBDescriptor *descriptor = [[self class] descriptor];
  if ([[otherMsg class] descriptor] != descriptor) {
    return NO;
  }
  uint8_t *selfStorage = (uint8_t *)messageStorage_;
  uint8_t *otherStorage = (uint8_t *)otherMsg->messageStorage_;

  for (GPBFieldDescriptor *field in descriptor->fields_) {
    if (GPBFieldIsMapOrArray(field)) {
      // In the case of a list or map, there is no _hasIvar to worry about.
      // NOTE: These are NSArray/GPB*Array or NSDictionary/GPB*Dictionary, but
      // the type doesn't really matter as the objects all support -count and
      // -isEqual:.
      NSArray *resultMapOrArray = GPBGetObjectIvarWithFieldNoAutocreate(self, field);
      NSArray *otherMapOrArray = GPBGetObjectIvarWithFieldNoAutocreate(other, field);
      // nil and empty are equal
      if (resultMapOrArray.count != 0 || otherMapOrArray.count != 0) {
        if (![resultMapOrArray isEqual:otherMapOrArray]) {
          return NO;
        }
      }
    } else {  // Single field
      int32_t hasIndex = GPBFieldHasIndex(field);
      uint32_t fieldNum = GPBFieldNumber(field);
      BOOL selfHas = GPBGetHasIvar(self, hasIndex, fieldNum);
      BOOL otherHas = GPBGetHasIvar(other, hasIndex, fieldNum);
      if (selfHas != otherHas) {
        return NO;  // Differing has values, not equal.
      }
      if (!selfHas) {
        // Same has values, was no, nothing else to check for this field.
        continue;
      }
      // Now compare the values.
      GPBDataType fieldDataType = GPBGetFieldDataType(field);
      size_t fieldOffset = field->description_->offset;
      switch (fieldDataType) {
        case GPBDataTypeBool: {
          // Bools are stored in has_bits to avoid needing explicit space in
          // the storage structure.
          // (the field number passed to the HasIvar helper doesn't really
          // matter since the offset is never negative)
          BOOL selfValue = GPBGetHasIvar(self, (int32_t)(fieldOffset), 0);
          BOOL otherValue = GPBGetHasIvar(other, (int32_t)(fieldOffset), 0);
          if (selfValue != otherValue) {
            return NO;
          }
          break;
        }
        case GPBDataTypeSFixed32:
        case GPBDataTypeInt32:
        case GPBDataTypeSInt32:
        case GPBDataTypeEnum:
        case GPBDataTypeFixed32:
        case GPBDataTypeUInt32:
        case GPBDataTypeFloat: {
          GPBInternalCompileAssert(sizeof(float) == sizeof(uint32_t), float_not_32_bits);
          // These are all 32bit, signed/unsigned doesn't matter for equality.
          uint32_t *selfValPtr = (uint32_t *)&selfStorage[fieldOffset];
          uint32_t *otherValPtr = (uint32_t *)&otherStorage[fieldOffset];
          if (*selfValPtr != *otherValPtr) {
            return NO;
          }
          break;
        }
        case GPBDataTypeSFixed64:
        case GPBDataTypeInt64:
        case GPBDataTypeSInt64:
        case GPBDataTypeFixed64:
        case GPBDataTypeUInt64:
        case GPBDataTypeDouble: {
          GPBInternalCompileAssert(sizeof(double) == sizeof(uint64_t), double_not_64_bits);
          // These are all 64bit, signed/unsigned doesn't matter for equality.
          uint64_t *selfValPtr = (uint64_t *)&selfStorage[fieldOffset];
          uint64_t *otherValPtr = (uint64_t *)&otherStorage[fieldOffset];
          if (*selfValPtr != *otherValPtr) {
            return NO;
          }
          break;
        }
        case GPBDataTypeBytes:
        case GPBDataTypeString:
        case GPBDataTypeMessage:
        case GPBDataTypeGroup: {
          // Type doesn't matter here, they all implement -isEqual:.
          id *selfValPtr = (id *)&selfStorage[fieldOffset];
          id *otherValPtr = (id *)&otherStorage[fieldOffset];
          if (![*selfValPtr isEqual:*otherValPtr]) {
            return NO;
          }
          break;
        }
      }  // switch()
    }    // if(mapOrArray)...else
  }      // for(fields)

  // nil and empty are equal
  if (extensionMap_.count != 0 || otherMsg->extensionMap_.count != 0) {
    if (![extensionMap_ isEqual:otherMsg->extensionMap_]) {
      return NO;
    }
  }

  // nil and empty are equal
  GPBUnknownFieldSet *otherUnknowns = otherMsg->unknownFields_;
  if ([unknownFields_ countOfFields] != 0 || [otherUnknowns countOfFields] != 0) {
    if (![unknownFields_ isEqual:otherUnknowns]) {
      return NO;
    }
  }

  return YES;
}

// It is very difficult to implement a generic hash for ProtoBuf messages that
// will perform well. If you need hashing on your ProtoBufs (eg you are using
// them as dictionary keys) you will probably want to implement a ProtoBuf
// message specific hash as a category on your protobuf class. Do not make it a
// category on GPBMessage as you will conflict with this hash, and will possibly
// override hash for all generated protobufs. A good implementation of hash will
// be really fast, so we would recommend only hashing protobufs that have an
// identifier field of some kind that you can easily hash. If you implement
// hash, we would strongly recommend overriding isEqual: in your category as
// well, as the default implementation of isEqual: is extremely slow, and may
// drastically affect performance in large sets.
- (NSUInteger)hash {
  GPBDescriptor *descriptor = [[self class] descriptor];
  const NSUInteger prime = 19;
  uint8_t *storage = (uint8_t *)messageStorage_;

  // Start with the descriptor and then mix it with some instance info.
  // Hopefully that will give a spread based on classes and what fields are set.
  NSUInteger result = (NSUInteger)descriptor;

  for (GPBFieldDescriptor *field in descriptor->fields_) {
    if (GPBFieldIsMapOrArray(field)) {
      // Exact type doesn't matter, just check if there are any elements.
      NSArray *mapOrArray = GPBGetObjectIvarWithFieldNoAutocreate(self, field);
      NSUInteger count = mapOrArray.count;
      if (count) {
        // NSArray/NSDictionary use count, use the field number and the count.
        result = prime * result + GPBFieldNumber(field);
        result = prime * result + count;
      }
    } else if (GPBGetHasIvarField(self, field)) {
      // Just using the field number seemed simple/fast, but then a small
      // message class where all the same fields are always set (to different
      // things would end up all with the same hash, so pull in some data).
      GPBDataType fieldDataType = GPBGetFieldDataType(field);
      size_t fieldOffset = field->description_->offset;
      switch (fieldDataType) {
        case GPBDataTypeBool: {
          // Bools are stored in has_bits to avoid needing explicit space in
          // the storage structure.
          // (the field number passed to the HasIvar helper doesn't really
          // matter since the offset is never negative)
          BOOL value = GPBGetHasIvar(self, (int32_t)(fieldOffset), 0);
          result = prime * result + value;
          break;
        }
        case GPBDataTypeSFixed32:
        case GPBDataTypeInt32:
        case GPBDataTypeSInt32:
        case GPBDataTypeEnum:
        case GPBDataTypeFixed32:
        case GPBDataTypeUInt32:
        case GPBDataTypeFloat: {
          GPBInternalCompileAssert(sizeof(float) == sizeof(uint32_t), float_not_32_bits);
          // These are all 32bit, just mix it in.
          uint32_t *valPtr = (uint32_t *)&storage[fieldOffset];
          result = prime * result + *valPtr;
          break;
        }
        case GPBDataTypeSFixed64:
        case GPBDataTypeInt64:
        case GPBDataTypeSInt64:
        case GPBDataTypeFixed64:
        case GPBDataTypeUInt64:
        case GPBDataTypeDouble: {
          GPBInternalCompileAssert(sizeof(double) == sizeof(uint64_t), double_not_64_bits);
          // These are all 64bit, just mix what fits into an NSUInteger in.
          uint64_t *valPtr = (uint64_t *)&storage[fieldOffset];
          result = prime * result + (NSUInteger)(*valPtr);
          break;
        }
        case GPBDataTypeBytes:
        case GPBDataTypeString: {
          // Type doesn't matter here, they both implement -hash:.
          id *valPtr = (id *)&storage[fieldOffset];
          result = prime * result + [*valPtr hash];
          break;
        }

        case GPBDataTypeMessage:
        case GPBDataTypeGroup: {
          GPBMessage **valPtr = (GPBMessage **)&storage[fieldOffset];
          // Could call -hash on the sub message, but that could recurse pretty
          // deep; follow the lead of NSArray/NSDictionary and don't really
          // recurse for hash, instead use the field number and the descriptor
          // of the sub message.  Yes, this could suck for a bunch of messages
          // where they all only differ in the sub messages, but if you are
          // using a message with sub messages for something that needs -hash,
          // odds are you are also copying them as keys, and that deep copy
          // will also suck.
          result = prime * result + GPBFieldNumber(field);
          result = prime * result + (NSUInteger)[[*valPtr class] descriptor];
          break;
        }
      }  // switch()
    }
  }

  // Unknowns and extensions are not included.

  return result;
}

#pragma mark - Description Support

- (NSString *)description {
  NSString *textFormat = GPBTextFormatForMessage(self, @"    ");
  NSString *description =
      [NSString stringWithFormat:@"<%@ %p>: {\n%@}", [self class], self, textFormat];
  return description;
}

#if defined(DEBUG) && DEBUG

// Xcode 5.1 added support for custom quick look info.
// https://developer.apple.com/library/ios/documentation/IDEs/Conceptual/CustomClassDisplay_in_QuickLook/CH01-quick_look_for_custom_objects/CH01-quick_look_for_custom_objects.html#//apple_ref/doc/uid/TP40014001-CH2-SW1
- (id)debugQuickLookObject {
  return GPBTextFormatForMessage(self, nil);
}

#endif  // DEBUG

#pragma mark - SerializedSize

- (size_t)serializedSize {
  GPBDescriptor *descriptor = [[self class] descriptor];
  size_t result = 0;

  // Has check is done explicitly, so GPBGetObjectIvarWithFieldNoAutocreate()
  // avoids doing the has check again.

  // Fields.
  for (GPBFieldDescriptor *fieldDescriptor in descriptor->fields_) {
    GPBFieldType fieldType = fieldDescriptor.fieldType;
    GPBDataType fieldDataType = GPBGetFieldDataType(fieldDescriptor);

    // Single Fields
    if (fieldType == GPBFieldTypeSingle) {
      BOOL selfHas = GPBGetHasIvarField(self, fieldDescriptor);
      if (!selfHas) {
        continue;  // Nothing to do.
      }

      uint32_t fieldNumber = GPBFieldNumber(fieldDescriptor);

      switch (fieldDataType) {
#define CASE_SINGLE_POD(NAME, TYPE, FUNC_TYPE)                              \
  case GPBDataType##NAME: {                                                 \
    TYPE fieldVal = GPBGetMessage##FUNC_TYPE##Field(self, fieldDescriptor); \
    result += GPBCompute##NAME##Size(fieldNumber, fieldVal);                \
    break;                                                                  \
  }
#define CASE_SINGLE_OBJECT(NAME)                                                \
  case GPBDataType##NAME: {                                                     \
    id fieldVal = GPBGetObjectIvarWithFieldNoAutocreate(self, fieldDescriptor); \
    result += GPBCompute##NAME##Size(fieldNumber, fieldVal);                    \
    break;                                                                      \
  }
        CASE_SINGLE_POD(Bool, BOOL, Bool)
        CASE_SINGLE_POD(Fixed32, uint32_t, UInt32)
        CASE_SINGLE_POD(SFixed32, int32_t, Int32)
        CASE_SINGLE_POD(Float, float, Float)
        CASE_SINGLE_POD(Fixed64, uint64_t, UInt64)
        CASE_SINGLE_POD(SFixed64, int64_t, Int64)
        CASE_SINGLE_POD(Double, double, Double)
        CASE_SINGLE_POD(Int32, int32_t, Int32)
        CASE_SINGLE_POD(Int64, int64_t, Int64)
        CASE_SINGLE_POD(SInt32, int32_t, Int32)
        CASE_SINGLE_POD(SInt64, int64_t, Int64)
        CASE_SINGLE_POD(UInt32, uint32_t, UInt32)
        CASE_SINGLE_POD(UInt64, uint64_t, UInt64)
        CASE_SINGLE_OBJECT(Bytes)
        CASE_SINGLE_OBJECT(String)
        CASE_SINGLE_OBJECT(Message)
        CASE_SINGLE_OBJECT(Group)
        CASE_SINGLE_POD(Enum, int32_t, Int32)
#undef CASE_SINGLE_POD
#undef CASE_SINGLE_OBJECT
      }

      // Repeated Fields
    } else if (fieldType == GPBFieldTypeRepeated) {
      id genericArray = GPBGetObjectIvarWithFieldNoAutocreate(self, fieldDescriptor);
      NSUInteger count = [genericArray count];
      if (count == 0) {
        continue;  // Nothing to add.
      }
      __block size_t dataSize = 0;

      switch (fieldDataType) {
#define CASE_REPEATED_POD(NAME, TYPE, ARRAY_TYPE) CASE_REPEATED_POD_EXTRA(NAME, TYPE, ARRAY_TYPE, )
#define CASE_REPEATED_POD_EXTRA(NAME, TYPE, ARRAY_TYPE, ARRAY_ACCESSOR_NAME)           \
  case GPBDataType##NAME: {                                                            \
    GPB##ARRAY_TYPE##Array *array = genericArray;                                      \
    [array enumerate##ARRAY_ACCESSOR_NAME##                                            \
        ValuesWithBlock:^(TYPE value, __unused NSUInteger idx, __unused BOOL * stop) { \
          dataSize += GPBCompute##NAME##SizeNoTag(value);                              \
        }];                                                                            \
    break;                                                                             \
  }
#define CASE_REPEATED_OBJECT(NAME)                    \
  case GPBDataType##NAME: {                           \
    for (id value in genericArray) {                  \
      dataSize += GPBCompute##NAME##SizeNoTag(value); \
    }                                                 \
    break;                                            \
  }
        CASE_REPEATED_POD(Bool, BOOL, Bool)
        CASE_REPEATED_POD(Fixed32, uint32_t, UInt32)
        CASE_REPEATED_POD(SFixed32, int32_t, Int32)
        CASE_REPEATED_POD(Float, float, Float)
        CASE_REPEATED_POD(Fixed64, uint64_t, UInt64)
        CASE_REPEATED_POD(SFixed64, int64_t, Int64)
        CASE_REPEATED_POD(Double, double, Double)
        CASE_REPEATED_POD(Int32, int32_t, Int32)
        CASE_REPEATED_POD(Int64, int64_t, Int64)
        CASE_REPEATED_POD(SInt32, int32_t, Int32)
        CASE_REPEATED_POD(SInt64, int64_t, Int64)
        CASE_REPEATED_POD(UInt32, uint32_t, UInt32)
        CASE_REPEATED_POD(UInt64, uint64_t, UInt64)
        CASE_REPEATED_OBJECT(Bytes)
        CASE_REPEATED_OBJECT(String)
        CASE_REPEATED_OBJECT(Message)
        CASE_REPEATED_OBJECT(Group)
        CASE_REPEATED_POD_EXTRA(Enum, int32_t, Enum, Raw)
#undef CASE_REPEATED_POD
#undef CASE_REPEATED_POD_EXTRA
#undef CASE_REPEATED_OBJECT
      }  // switch
      result += dataSize;
      size_t tagSize = GPBComputeTagSize(GPBFieldNumber(fieldDescriptor));
      if (fieldDataType == GPBDataTypeGroup) {
        // Groups have both a start and an end tag.
        tagSize *= 2;
      }
      if (fieldDescriptor.isPackable) {
        result += tagSize;
        result += GPBComputeSizeTSizeAsInt32NoTag(dataSize);
      } else {
        result += count * tagSize;
      }

      // Map<> Fields
    } else {  // fieldType == GPBFieldTypeMap
      if (GPBDataTypeIsObject(fieldDataType) &&
          (fieldDescriptor.mapKeyDataType == GPBDataTypeString)) {
        // If key type was string, then the map is an NSDictionary.
        NSDictionary *map = GPBGetObjectIvarWithFieldNoAutocreate(self, fieldDescriptor);
        if (map) {
          result += GPBDictionaryComputeSizeInternalHelper(map, fieldDescriptor);
        }
      } else {
        // Type will be GPB*GroupDictionary, exact type doesn't matter.
        GPBInt32Int32Dictionary *map = GPBGetObjectIvarWithFieldNoAutocreate(self, fieldDescriptor);
        result += [map computeSerializedSizeAsField:fieldDescriptor];
      }
    }
  }  // for(fields)

  // Add any unknown fields.
  if (descriptor.wireFormat) {
    result += [unknownFields_ serializedSizeAsMessageSet];
  } else {
    result += [unknownFields_ serializedSize];
  }

  // Add any extensions.
  for (GPBExtensionDescriptor *extension in extensionMap_) {
    id value = [extensionMap_ objectForKey:extension];
    result += GPBComputeExtensionSerializedSizeIncludingTag(extension, value);
  }

  return result;
}

#pragma mark - Resolve Methods Support

typedef struct ResolveIvarAccessorMethodResult {
  IMP impToAdd;
  SEL encodingSelector;
} ResolveIvarAccessorMethodResult;

// |field| can be __unsafe_unretained because they are created at startup
// and are essentially global. No need to pay for retain/release when
// they are captured in blocks.
static void ResolveIvarGet(__unsafe_unretained GPBFieldDescriptor *field,
                           ResolveIvarAccessorMethodResult *result) {
  GPBDataType fieldDataType = GPBGetFieldDataType(field);
  switch (fieldDataType) {
#define CASE_GET(NAME, TYPE, TRUE_NAME)                        \
  case GPBDataType##NAME: {                                    \
    result->impToAdd = imp_implementationWithBlock(^(id obj) { \
      return GPBGetMessage##TRUE_NAME##Field(obj, field);      \
    });                                                        \
    result->encodingSelector = @selector(get##NAME);           \
    break;                                                     \
  }
#define CASE_GET_OBJECT(NAME, TYPE, TRUE_NAME)                 \
  case GPBDataType##NAME: {                                    \
    result->impToAdd = imp_implementationWithBlock(^(id obj) { \
      return GPBGetObjectIvarWithField(obj, field);            \
    });                                                        \
    result->encodingSelector = @selector(get##NAME);           \
    break;                                                     \
  }
    CASE_GET(Bool, BOOL, Bool)
    CASE_GET(Fixed32, uint32_t, UInt32)
    CASE_GET(SFixed32, int32_t, Int32)
    CASE_GET(Float, float, Float)
    CASE_GET(Fixed64, uint64_t, UInt64)
    CASE_GET(SFixed64, int64_t, Int64)
    CASE_GET(Double, double, Double)
    CASE_GET(Int32, int32_t, Int32)
    CASE_GET(Int64, int64_t, Int64)
    CASE_GET(SInt32, int32_t, Int32)
    CASE_GET(SInt64, int64_t, Int64)
    CASE_GET(UInt32, uint32_t, UInt32)
    CASE_GET(UInt64, uint64_t, UInt64)
    CASE_GET_OBJECT(Bytes, id, Object)
    CASE_GET_OBJECT(String, id, Object)
    CASE_GET_OBJECT(Message, id, Object)
    CASE_GET_OBJECT(Group, id, Object)
    CASE_GET(Enum, int32_t, Enum)
#undef CASE_GET
  }
}

// See comment about __unsafe_unretained on ResolveIvarGet.
static void ResolveIvarSet(__unsafe_unretained GPBFieldDescriptor *field,
                           ResolveIvarAccessorMethodResult *result) {
  GPBDataType fieldDataType = GPBGetFieldDataType(field);
  switch (fieldDataType) {
#define CASE_SET(NAME, TYPE, TRUE_NAME)                                    \
  case GPBDataType##NAME: {                                                \
    result->impToAdd = imp_implementationWithBlock(^(id obj, TYPE value) { \
      return GPBSet##TRUE_NAME##IvarWithFieldPrivate(obj, field, value);   \
    });                                                                    \
    result->encodingSelector = @selector(set##NAME:);                      \
    break;                                                                 \
  }
#define CASE_SET_COPY(NAME)                                                      \
  case GPBDataType##NAME: {                                                      \
    result->impToAdd = imp_implementationWithBlock(^(id obj, id value) {         \
      return GPBSetRetainedObjectIvarWithFieldPrivate(obj, field, [value copy]); \
    });                                                                          \
    result->encodingSelector = @selector(set##NAME:);                            \
    break;                                                                       \
  }
    CASE_SET(Bool, BOOL, Bool)
    CASE_SET(Fixed32, uint32_t, UInt32)
    CASE_SET(SFixed32, int32_t, Int32)
    CASE_SET(Float, float, Float)
    CASE_SET(Fixed64, uint64_t, UInt64)
    CASE_SET(SFixed64, int64_t, Int64)
    CASE_SET(Double, double, Double)
    CASE_SET(Int32, int32_t, Int32)
    CASE_SET(Int64, int64_t, Int64)
    CASE_SET(SInt32, int32_t, Int32)
    CASE_SET(SInt64, int64_t, Int64)
    CASE_SET(UInt32, uint32_t, UInt32)
    CASE_SET(UInt64, uint64_t, UInt64)
    CASE_SET_COPY(Bytes)
    CASE_SET_COPY(String)
    CASE_SET(Message, id, Object)
    CASE_SET(Group, id, Object)
    CASE_SET(Enum, int32_t, Enum)
#undef CASE_SET
  }
}

+ (BOOL)resolveInstanceMethod:(SEL)sel {
  const GPBDescriptor *descriptor = [self descriptor];
  if (!descriptor) {
    return [super resolveInstanceMethod:sel];
  }

  // NOTE: hasOrCountSel_/setHasSel_ will be NULL if the field for the given
  // message should not have has support (done in GPBDescriptor.m), so there is
  // no need for checks here to see if has*/setHas* are allowed.
  ResolveIvarAccessorMethodResult result = {NULL, NULL};

  // See comment about __unsafe_unretained on ResolveIvarGet.
  for (__unsafe_unretained GPBFieldDescriptor *field in descriptor->fields_) {
    BOOL isMapOrArray = GPBFieldIsMapOrArray(field);
    if (!isMapOrArray) {
      // Single fields.
      if (sel == field->getSel_) {
        ResolveIvarGet(field, &result);
        break;
      } else if (sel == field->setSel_) {
        ResolveIvarSet(field, &result);
        break;
      } else if (sel == field->hasOrCountSel_) {
        int32_t index = GPBFieldHasIndex(field);
        uint32_t fieldNum = GPBFieldNumber(field);
        result.impToAdd = imp_implementationWithBlock(^(id obj) {
          return GPBGetHasIvar(obj, index, fieldNum);
        });
        result.encodingSelector = @selector(getBool);
        break;
      } else if (sel == field->setHasSel_) {
        result.impToAdd = imp_implementationWithBlock(^(id obj, BOOL value) {
          if (value) {
            [NSException raise:NSInvalidArgumentException
                        format:@"%@: %@ can only be set to NO (to clear field).", [obj class],
                               NSStringFromSelector(field->setHasSel_)];
          }
          GPBClearMessageField(obj, field);
        });
        result.encodingSelector = @selector(setBool:);
        break;
      } else {
        GPBOneofDescriptor *oneof = field->containingOneof_;
        if (oneof && (sel == oneof->caseSel_)) {
          int32_t index = GPBFieldHasIndex(field);
          result.impToAdd = imp_implementationWithBlock(^(id obj) {
            return GPBGetHasOneof(obj, index);
          });
          result.encodingSelector = @selector(getEnum);
          break;
        }
      }
    } else {
      // map<>/repeated fields.
      if (sel == field->getSel_) {
        if (field.fieldType == GPBFieldTypeRepeated) {
          result.impToAdd = imp_implementationWithBlock(^(id obj) {
            return GetArrayIvarWithField(obj, field);
          });
        } else {
          result.impToAdd = imp_implementationWithBlock(^(id obj) {
            return GetMapIvarWithField(obj, field);
          });
        }
        result.encodingSelector = @selector(getArray);
        break;
      } else if (sel == field->setSel_) {
        // Local for syntax so the block can directly capture it and not the
        // full lookup.
        result.impToAdd = imp_implementationWithBlock(^(id obj, id value) {
          GPBSetObjectIvarWithFieldPrivate(obj, field, value);
        });
        result.encodingSelector = @selector(setArray:);
        break;
      } else if (sel == field->hasOrCountSel_) {
        result.impToAdd = imp_implementationWithBlock(^(id obj) {
          // Type doesn't matter, all *Array and *Dictionary types support
          // -count.
          NSArray *arrayOrMap = GPBGetObjectIvarWithFieldNoAutocreate(obj, field);
          return [arrayOrMap count];
        });
        result.encodingSelector = @selector(getArrayCount);
        break;
      }
    }
  }
  if (result.impToAdd) {
    const char *encoding = GPBMessageEncodingForSelector(result.encodingSelector, YES);
    Class msgClass = descriptor.messageClass;
    BOOL methodAdded = class_addMethod(msgClass, sel, result.impToAdd, encoding);
    // class_addMethod() is documented as also failing if the method was already
    // added; so we check if the method is already there and return success so
    // the method dispatch will still happen.  Why would it already be added?
    // Two threads could cause the same method to be bound at the same time,
    // but only one will actually bind it; the other still needs to return true
    // so things will dispatch.
    if (!methodAdded) {
      methodAdded = GPBClassHasSel(msgClass, sel);
    }
    return methodAdded;
  }
  return [super resolveInstanceMethod:sel];
}

+ (BOOL)resolveClassMethod:(SEL)sel {
  // Extensions scoped to a Message and looked up via class methods.
  if (GPBResolveExtensionClassMethod(self, sel)) {
    return YES;
  }
  return [super resolveClassMethod:sel];
}

#pragma mark - NSCoding Support

+ (BOOL)supportsSecureCoding {
  return YES;
}

- (instancetype)initWithCoder:(NSCoder *)aDecoder {
  self = [self init];
  if (self) {
    NSData *data = [aDecoder decodeObjectOfClass:[NSData class] forKey:kGPBDataCoderKey];
    if (data.length) {
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
      [self mergeFromData:data extensionRegistry:nil];
#pragma clang diagnostic pop
    }
  }
  return self;
}

- (void)encodeWithCoder:(NSCoder *)aCoder {
#if defined(DEBUG) && DEBUG
  if (extensionMap_.count) {
    // Hint to go along with the docs on GPBMessage about this.
    //
    // Note: This is incomplete, in that it only checked the "root" message,
    // if a sub message in a field has extensions, the issue still exists. A
    // recursive check could be done here (like the work in
    // GPBMessageDropUnknownFieldsRecursively()), but that has the potential to
    // be expensive and could slow down serialization in DEBUG enough to cause
    // developers other problems.
    NSLog(@"Warning: writing out a GPBMessage (%@) via NSCoding and it"
          @" has %ld extensions; when read back in, those fields will be"
          @" in the unknownFields property instead.",
          [self class], (long)extensionMap_.count);
  }
#endif
  NSData *data = [self data];
  if (data.length) {
    [aCoder encodeObject:data forKey:kGPBDataCoderKey];
  }
}

#pragma mark - KVC Support

+ (BOOL)accessInstanceVariablesDirectly {
  // Make sure KVC doesn't use instance variables.
  return NO;
}

@end

#pragma mark - Messages from GPBUtilities.h but defined here for access to helpers.

// Only exists for public api, no core code should use this.
id GPBGetMessageRepeatedField(GPBMessage *self, GPBFieldDescriptor *field) {
#if defined(DEBUG) && DEBUG
  if (field.fieldType != GPBFieldTypeRepeated) {
    [NSException raise:NSInvalidArgumentException
                format:@"%@.%@ is not a repeated field.", [self class], field.name];
  }
#endif
  return GetOrCreateArrayIvarWithField(self, field);
}

// Only exists for public api, no core code should use this.
id GPBGetMessageMapField(GPBMessage *self, GPBFieldDescriptor *field) {
#if defined(DEBUG) && DEBUG
  if (field.fieldType != GPBFieldTypeMap) {
    [NSException raise:NSInvalidArgumentException
                format:@"%@.%@ is not a map<> field.", [self class], field.name];
  }
#endif
  return GetOrCreateMapIvarWithField(self, field);
}

id GPBGetObjectIvarWithField(GPBMessage *self, GPBFieldDescriptor *field) {
  NSCAssert(!GPBFieldIsMapOrArray(field), @"Shouldn't get here");
  if (!GPBFieldDataTypeIsMessage(field)) {
    if (GPBGetHasIvarField(self, field)) {
      uint8_t *storage = (uint8_t *)self->messageStorage_;
      id *typePtr = (id *)&storage[field->description_->offset];
      return *typePtr;
    }
    // Not set...non messages (string/data), get their default.
    return field.defaultValue.valueMessage;
  }

  uint8_t *storage = (uint8_t *)self->messageStorage_;
  _Atomic(id) *typePtr = (_Atomic(id) *)&storage[field->description_->offset];
  id msg = atomic_load(typePtr);
  if (msg) {
    return msg;
  }

  id expected = nil;
  id autocreated = GPBCreateMessageWithAutocreator(field.msgClass, self, field);
  if (atomic_compare_exchange_strong(typePtr, &expected, autocreated)) {
    // Value was set, return it.
    return autocreated;
  }

  // Some other thread set it, release the one created and return what got set.
  GPBClearMessageAutocreator(autocreated);
  [autocreated release];
  return expected;
}

#pragma clang diagnostic pop
