diff --git a/objectivec/GPBDescriptor.m b/objectivec/GPBDescriptor.m
new file mode 100644
index 0000000..bae9187
--- /dev/null
+++ b/objectivec/GPBDescriptor.m
@@ -0,0 +1,997 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#import "GPBDescriptor_PackagePrivate.h"
+
+#import <objc/runtime.h>
+
+#import "GPBUtilities_PackagePrivate.h"
+#import "GPBWireFormat.h"
+#import "GPBMessage_PackagePrivate.h"
+#import "google/protobuf/Descriptor.pbobjc.h"
+
+// The address of this variable is used as a key for obj_getAssociatedObject.
+static const char kTextFormatExtraValueKey = 0;
+
+// Utility function to generate selectors on the fly.
+static SEL SelFromStrings(const char *prefix, const char *middle,
+                          const char *suffix, BOOL takesArg) {
+  if (prefix == NULL && suffix == NULL && !takesArg) {
+    return sel_getUid(middle);
+  }
+  const size_t prefixLen = prefix != NULL ? strlen(prefix) : 0;
+  const size_t middleLen = strlen(middle);
+  const size_t suffixLen = suffix != NULL ? strlen(suffix) : 0;
+  size_t totalLen =
+      prefixLen + middleLen + suffixLen + 1;  // include space for null on end.
+  if (takesArg) {
+    totalLen += 1;
+  }
+  char buffer[totalLen];
+  if (prefix != NULL) {
+    memcpy(buffer, prefix, prefixLen);
+    memcpy(buffer + prefixLen, middle, middleLen);
+    buffer[prefixLen] = (char)toupper(buffer[prefixLen]);
+  } else {
+    memcpy(buffer, middle, middleLen);
+  }
+  if (suffix != NULL) {
+    memcpy(buffer + prefixLen + middleLen, suffix, suffixLen);
+  }
+  if (takesArg) {
+    buffer[totalLen - 2] = ':';
+  }
+  // Always null terminate it.
+  buffer[totalLen - 1] = 0;
+
+  SEL result = sel_getUid(buffer);
+  return result;
+}
+
+static NSArray *NewFieldsArrayForHasIndex(int hasIndex,
+                                          NSArray *allMessageFields)
+    __attribute__((ns_returns_retained));
+
+static NSArray *NewFieldsArrayForHasIndex(int hasIndex,
+                                          NSArray *allMessageFields) {
+  NSMutableArray *result = [[NSMutableArray alloc] init];
+  for (GPBFieldDescriptor *fieldDesc in allMessageFields) {
+    if (fieldDesc->description_->hasIndex == hasIndex) {
+      [result addObject:fieldDesc];
+    }
+  }
+  return result;
+}
+
+@implementation GPBDescriptor {
+  Class messageClass_;
+  NSArray *enums_;
+  GPBFileDescriptor *file_;
+  BOOL wireFormat_;
+}
+
+@synthesize messageClass = messageClass_;
+@synthesize fields = fields_;
+@synthesize oneofs = oneofs_;
+@synthesize enums = enums_;
+@synthesize extensionRanges = extensionRanges_;
+@synthesize extensionRangesCount = extensionRangesCount_;
+@synthesize file = file_;
+@synthesize wireFormat = wireFormat_;
+
++ (instancetype)
+    allocDescriptorForClass:(Class)messageClass
+                  rootClass:(Class)rootClass
+                       file:(GPBFileDescriptor *)file
+                     fields:(GPBMessageFieldDescription *)fieldDescriptions
+                 fieldCount:(NSUInteger)fieldCount
+                     oneofs:(GPBMessageOneofDescription *)oneofDescriptions
+                 oneofCount:(NSUInteger)oneofCount
+                      enums:(GPBMessageEnumDescription *)enumDescriptions
+                  enumCount:(NSUInteger)enumCount
+                     ranges:(const GPBExtensionRange *)ranges
+                 rangeCount:(NSUInteger)rangeCount
+                storageSize:(size_t)storageSize
+                 wireFormat:(BOOL)wireFormat {
+  NSMutableArray *fields = nil;
+  NSMutableArray *oneofs = nil;
+  NSMutableArray *enums = nil;
+  NSMutableArray *extensionRanges = nil;
+  GPBFileSyntax syntax = file.syntax;
+  for (NSUInteger i = 0; i < fieldCount; ++i) {
+    if (fields == nil) {
+      fields = [[NSMutableArray alloc] initWithCapacity:fieldCount];
+    }
+    GPBFieldDescriptor *fieldDescriptor = [[GPBFieldDescriptor alloc]
+        initWithFieldDescription:&fieldDescriptions[i]
+                       rootClass:rootClass
+                          syntax:syntax];
+    [fields addObject:fieldDescriptor];
+    [fieldDescriptor release];
+  }
+  for (NSUInteger i = 0; i < oneofCount; ++i) {
+    if (oneofs == nil) {
+      oneofs = [[NSMutableArray alloc] initWithCapacity:oneofCount];
+    }
+    GPBMessageOneofDescription *oneofDescription = &oneofDescriptions[i];
+    NSArray *fieldsForOneof =
+        NewFieldsArrayForHasIndex(oneofDescription->index, fields);
+    GPBOneofDescriptor *oneofDescriptor =
+        [[GPBOneofDescriptor alloc] initWithOneofDescription:oneofDescription
+                                                      fields:fieldsForOneof];
+    [oneofs addObject:oneofDescriptor];
+    [oneofDescriptor release];
+    [fieldsForOneof release];
+  }
+  for (NSUInteger i = 0; i < enumCount; ++i) {
+    if (enums == nil) {
+      enums = [[NSMutableArray alloc] initWithCapacity:enumCount];
+    }
+    GPBEnumDescriptor *enumDescriptor =
+        enumDescriptions[i].enumDescriptorFunc();
+    [enums addObject:enumDescriptor];
+  }
+
+  GPBDescriptor *descriptor = [[self alloc] initWithClass:messageClass
+                                                     file:file
+                                                   fields:fields
+                                                   oneofs:oneofs
+                                                    enums:enums
+                                          extensionRanges:ranges
+                                     extensionRangesCount:rangeCount
+                                              storageSize:storageSize
+                                               wireFormat:wireFormat];
+  [fields release];
+  [oneofs release];
+  [enums release];
+  [extensionRanges release];
+  return descriptor;
+}
+
++ (instancetype)
+    allocDescriptorForClass:(Class)messageClass
+                  rootClass:(Class)rootClass
+                       file:(GPBFileDescriptor *)file
+                     fields:(GPBMessageFieldDescription *)fieldDescriptions
+                 fieldCount:(NSUInteger)fieldCount
+                     oneofs:(GPBMessageOneofDescription *)oneofDescriptions
+                 oneofCount:(NSUInteger)oneofCount
+                      enums:(GPBMessageEnumDescription *)enumDescriptions
+                  enumCount:(NSUInteger)enumCount
+                     ranges:(const GPBExtensionRange *)ranges
+                 rangeCount:(NSUInteger)rangeCount
+                storageSize:(size_t)storageSize
+                 wireFormat:(BOOL)wireFormat
+        extraTextFormatInfo:(const char *)extraTextFormatInfo {
+  GPBDescriptor *descriptor = [self allocDescriptorForClass:messageClass
+                                                  rootClass:rootClass
+                                                       file:file
+                                                     fields:fieldDescriptions
+                                                 fieldCount:fieldCount
+                                                     oneofs:oneofDescriptions
+                                                 oneofCount:oneofCount
+                                                      enums:enumDescriptions
+                                                  enumCount:enumCount
+                                                     ranges:ranges
+                                                 rangeCount:rangeCount
+                                                storageSize:storageSize
+                                                 wireFormat:wireFormat];
+  // Extra info is a compile time option, so skip the work if not needed.
+  if (extraTextFormatInfo) {
+    NSValue *extraInfoValue = [NSValue valueWithPointer:extraTextFormatInfo];
+    for (GPBFieldDescriptor *fieldDescriptor in descriptor->fields_) {
+      if (fieldDescriptor->description_->flags & GPBFieldTextFormatNameCustom) {
+        objc_setAssociatedObject(fieldDescriptor, &kTextFormatExtraValueKey,
+                                 extraInfoValue,
+                                 OBJC_ASSOCIATION_RETAIN_NONATOMIC);
+      }
+    }
+  }
+  return descriptor;
+}
+
+- (instancetype)initWithClass:(Class)messageClass
+                         file:(GPBFileDescriptor *)file
+                       fields:(NSArray *)fields
+                       oneofs:(NSArray *)oneofs
+                        enums:(NSArray *)enums
+              extensionRanges:(const GPBExtensionRange *)extensionRanges
+         extensionRangesCount:(NSUInteger)extensionRangesCount
+                  storageSize:(size_t)storageSize
+                   wireFormat:(BOOL)wireFormat {
+  if ((self = [super init])) {
+    messageClass_ = messageClass;
+    file_ = file;
+    fields_ = [fields retain];
+    oneofs_ = [oneofs retain];
+    enums_ = [enums retain];
+    extensionRanges_ = extensionRanges;
+    extensionRangesCount_ = extensionRangesCount;
+    storageSize_ = storageSize;
+    wireFormat_ = wireFormat;
+  }
+  return self;
+}
+
+- (void)dealloc {
+  [fields_ release];
+  [oneofs_ release];
+  [enums_ release];
+  [super dealloc];
+}
+
+- (NSString *)name {
+  return NSStringFromClass(messageClass_);
+}
+
+- (id)copyWithZone:(NSZone *)zone {
+#pragma unused(zone)
+  return [self retain];
+}
+
+- (GPBFieldDescriptor *)fieldWithNumber:(uint32_t)fieldNumber {
+  for (GPBFieldDescriptor *descriptor in fields_) {
+    if (GPBFieldNumber(descriptor) == fieldNumber) {
+      return descriptor;
+    }
+  }
+  return nil;
+}
+
+- (GPBFieldDescriptor *)fieldWithName:(NSString *)name {
+  for (GPBFieldDescriptor *descriptor in fields_) {
+    if ([descriptor.name isEqual:name]) {
+      return descriptor;
+    }
+  }
+  return nil;
+}
+
+- (GPBOneofDescriptor *)oneofWithName:(NSString *)name {
+  for (GPBOneofDescriptor *descriptor in oneofs_) {
+    if ([descriptor.name isEqual:name]) {
+      return descriptor;
+    }
+  }
+  return nil;
+}
+
+- (GPBEnumDescriptor *)enumWithName:(NSString *)name {
+  for (GPBEnumDescriptor *descriptor in enums_) {
+    if ([descriptor.name isEqual:name]) {
+      return descriptor;
+    }
+  }
+  return nil;
+}
+
+@end
+
+@implementation GPBFileDescriptor {
+  NSString *package_;
+  GPBFileSyntax syntax_;
+}
+
+@synthesize package = package_;
+@synthesize syntax = syntax_;
+
+- (instancetype)initWithPackage:(NSString *)package
+                         syntax:(GPBFileSyntax)syntax {
+  self = [super init];
+  if (self) {
+    package_ = [package copy];
+    syntax_ = syntax;
+  }
+  return self;
+}
+
+@end
+
+@implementation GPBOneofDescriptor
+
+@synthesize fields = fields_;
+
+- (instancetype)initWithOneofDescription:
+                    (GPBMessageOneofDescription *)oneofDescription
+                                  fields:(NSArray *)fields {
+  self = [super init];
+  if (self) {
+    NSAssert(oneofDescription->index < 0, @"Should always be <0");
+    oneofDescription_ = oneofDescription;
+    fields_ = [fields retain];
+    for (GPBFieldDescriptor *fieldDesc in fields) {
+      fieldDesc->containingOneof_ = self;
+    }
+
+    caseSel_ = SelFromStrings(NULL, oneofDescription->name, "OneOfCase", NO);
+  }
+  return self;
+}
+
+- (void)dealloc {
+  [fields_ release];
+  [super dealloc];
+}
+
+- (NSString *)name {
+  return @(oneofDescription_->name);
+}
+
+- (GPBFieldDescriptor *)fieldWithNumber:(uint32_t)fieldNumber {
+  for (GPBFieldDescriptor *descriptor in fields_) {
+    if (GPBFieldNumber(descriptor) == fieldNumber) {
+      return descriptor;
+    }
+  }
+  return nil;
+}
+
+- (GPBFieldDescriptor *)fieldWithName:(NSString *)name {
+  for (GPBFieldDescriptor *descriptor in fields_) {
+    if ([descriptor.name isEqual:name]) {
+      return descriptor;
+    }
+  }
+  return nil;
+}
+
+@end
+
+uint32_t GPBFieldTag(GPBFieldDescriptor *self) {
+  GPBMessageFieldDescription *description = self->description_;
+  GPBWireFormat format;
+  if ((description->flags & GPBFieldMapKeyMask) != 0) {
+    // Maps are repeated messages on the wire.
+    format = GPBWireFormatForType(GPBDataTypeMessage, NO);
+  } else {
+    format = GPBWireFormatForType(description->dataType,
+                                  ((description->flags & GPBFieldPacked) != 0));
+  }
+  return GPBWireFormatMakeTag(description->number, format);
+}
+
+uint32_t GPBFieldAlternateTag(GPBFieldDescriptor *self) {
+  GPBMessageFieldDescription *description = self->description_;
+  NSCAssert((description->flags & GPBFieldRepeated) != 0,
+            @"Only valid on repeated fields");
+  GPBWireFormat format =
+      GPBWireFormatForType(description->dataType,
+                           ((description->flags & GPBFieldPacked) == 0));
+  return GPBWireFormatMakeTag(description->number, format);
+}
+
+@implementation GPBFieldDescriptor {
+  GPBGenericValue defaultValue_;
+  GPBFieldOptions *fieldOptions_;
+
+  // Message ivars
+  Class msgClass_;
+
+  // Enum ivars.
+  // If protos are generated with GenerateEnumDescriptors on then it will
+  // be a enumDescriptor, otherwise it will be a enumVerifier.
+  union {
+    GPBEnumDescriptor *enumDescriptor_;
+    GPBEnumValidationFunc enumVerifier_;
+  } enumHandling_;
+}
+
+@synthesize fieldOptions = fieldOptions_;
+@synthesize msgClass = msgClass_;
+@synthesize containingOneof = containingOneof_;
+
+- (instancetype)init {
+  // Throw an exception if people attempt to not use the designated initializer.
+  self = [super init];
+  if (self != nil) {
+    [self doesNotRecognizeSelector:_cmd];
+    self = nil;
+  }
+  return self;
+}
+
+- (instancetype)initWithFieldDescription:
+                    (GPBMessageFieldDescription *)description
+                               rootClass:(Class)rootClass
+                                  syntax:(GPBFileSyntax)syntax {
+  if ((self = [super init])) {
+    description_ = description;
+    getSel_ = sel_getUid(description->name);
+    setSel_ = SelFromStrings("set", description->name, NULL, YES);
+
+    GPBDataType dataType = description->dataType;
+    BOOL isMessage = GPBDataTypeIsMessage(dataType);
+    BOOL isMapOrArray = GPBFieldIsMapOrArray(self);
+
+    if (isMapOrArray) {
+      // map<>/repeated fields get a *Count property (inplace of a has*) to
+      // support checking if there are any entries without triggering
+      // autocreation.
+      hasOrCountSel_ = SelFromStrings(NULL, description->name, "_Count", NO);
+    } else {
+      // If there is a positive hasIndex, then:
+      //   - All fields types for proto2 messages get has* selectors.
+      //   - Only message fields for proto3 messages get has* selectors.
+      // Note: the positive check is to handle oneOfs, we can't check
+      // containingOneof_ because it isn't set until after initialization.
+      if ((description->hasIndex >= 0) &&
+          (description->hasIndex != GPBNoHasBit) &&
+          ((syntax != GPBFileSyntaxProto3) || isMessage)) {
+        hasOrCountSel_ = SelFromStrings("has", description->name, NULL, NO);
+        setHasSel_ = SelFromStrings("setHas", description->name, NULL, YES);
+      }
+    }
+
+    // Extra type specific data.
+    if (isMessage) {
+      const char *className = description->dataTypeSpecific.className;
+      msgClass_ = objc_getClass(className);
+      NSAssert(msgClass_, @"Class %s not defined", className);
+    } else if (dataType == GPBDataTypeEnum) {
+      if ((description_->flags & GPBFieldHasEnumDescriptor) != 0) {
+        enumHandling_.enumDescriptor_ =
+            description->dataTypeSpecific.enumDescFunc();
+      } else {
+        enumHandling_.enumVerifier_ =
+            description->dataTypeSpecific.enumVerifier;
+      }
+    }
+
+    // Non map<>/repeated fields can have defaults.
+    if (!isMapOrArray) {
+      defaultValue_ = description->defaultValue;
+      if (dataType == GPBDataTypeBytes) {
+        // Data stored as a length prefixed (network byte order) c-string in
+        // descriptor structure.
+        const uint8_t *bytes = (const uint8_t *)defaultValue_.valueData;
+        if (bytes) {
+          uint32_t length = *((uint32_t *)bytes);
+          length = ntohl(length);
+          bytes += sizeof(length);
+          defaultValue_.valueData =
+              [[NSData alloc] initWithBytes:bytes length:length];
+        }
+      }
+    }
+
+    // FieldOptions stored as a length prefixed (network byte order) c-escaped
+    // string in descriptor records.
+    if (description->fieldOptions) {
+      uint8_t *optionsBytes = (uint8_t *)description->fieldOptions;
+      uint32_t optionsLength = *((uint32_t *)optionsBytes);
+      optionsLength = ntohl(optionsLength);
+      if (optionsLength > 0) {
+        optionsBytes += sizeof(optionsLength);
+        NSData *optionsData = [NSData dataWithBytesNoCopy:optionsBytes
+                                                   length:optionsLength
+                                             freeWhenDone:NO];
+        GPBExtensionRegistry *registry = [rootClass extensionRegistry];
+        fieldOptions_ = [[GPBFieldOptions parseFromData:optionsData
+                                      extensionRegistry:registry
+                                                  error:NULL] retain];
+      }
+    }
+  }
+  return self;
+}
+
+- (void)dealloc {
+  if (description_->dataType == GPBDataTypeBytes &&
+      !(description_->flags & GPBFieldRepeated)) {
+    [defaultValue_.valueData release];
+  }
+  [super dealloc];
+}
+
+- (GPBDataType)dataType {
+  return description_->dataType;
+}
+
+- (BOOL)hasDefaultValue {
+  return (description_->flags & GPBFieldHasDefaultValue) != 0;
+}
+
+- (uint32_t)number {
+  return description_->number;
+}
+
+- (NSString *)name {
+  return @(description_->name);
+}
+
+- (BOOL)isRequired {
+  return (description_->flags & GPBFieldRequired) != 0;
+}
+
+- (BOOL)isOptional {
+  return (description_->flags & GPBFieldOptional) != 0;
+}
+
+- (GPBFieldType)fieldType {
+  GPBFieldFlags flags = description_->flags;
+  if ((flags & GPBFieldRepeated) != 0) {
+    return GPBFieldTypeRepeated;
+  } else if ((flags & GPBFieldMapKeyMask) != 0) {
+    return GPBFieldTypeMap;
+  } else {
+    return GPBFieldTypeSingle;
+  }
+}
+
+- (GPBDataType)mapKeyDataType {
+  switch (description_->flags & GPBFieldMapKeyMask) {
+    case GPBFieldMapKeyInt32:
+      return GPBDataTypeInt32;
+    case GPBFieldMapKeyInt64:
+      return GPBDataTypeInt64;
+    case GPBFieldMapKeyUInt32:
+      return GPBDataTypeUInt32;
+    case GPBFieldMapKeyUInt64:
+      return GPBDataTypeUInt64;
+    case GPBFieldMapKeySInt32:
+      return GPBDataTypeSInt32;
+    case GPBFieldMapKeySInt64:
+      return GPBDataTypeSInt64;
+    case GPBFieldMapKeyFixed32:
+      return GPBDataTypeFixed32;
+    case GPBFieldMapKeyFixed64:
+      return GPBDataTypeFixed64;
+    case GPBFieldMapKeySFixed32:
+      return GPBDataTypeSFixed32;
+    case GPBFieldMapKeySFixed64:
+      return GPBDataTypeSFixed64;
+    case GPBFieldMapKeyBool:
+      return GPBDataTypeBool;
+    case GPBFieldMapKeyString:
+      return GPBDataTypeString;
+
+    default:
+      NSAssert(0, @"Not a map type");
+      return GPBDataTypeInt32;  // For lack of anything better.
+  }
+}
+
+- (BOOL)isPackable {
+  return (description_->flags & GPBFieldPacked) != 0;
+}
+
+- (BOOL)isValidEnumValue:(int32_t)value {
+  NSAssert(description_->dataType == GPBDataTypeEnum,
+           @"Field Must be of type GPBDataTypeEnum");
+  if (description_->flags & GPBFieldHasEnumDescriptor) {
+    return enumHandling_.enumDescriptor_.enumVerifier(value);
+  } else {
+    return enumHandling_.enumVerifier_(value);
+  }
+}
+
+- (GPBEnumDescriptor *)enumDescriptor {
+  if (description_->flags & GPBFieldHasEnumDescriptor) {
+    return enumHandling_.enumDescriptor_;
+  } else {
+    return nil;
+  }
+}
+
+- (GPBGenericValue)defaultValue {
+  // Depends on the fact that defaultValue_ is initialized either to "0/nil" or
+  // to an actual defaultValue in our initializer.
+  GPBGenericValue value = defaultValue_;
+
+  if (!(description_->flags & GPBFieldRepeated)) {
+    // We special handle data and strings. If they are nil, we replace them
+    // with empty string/empty data.
+    GPBDataType type = description_->dataType;
+    if (type == GPBDataTypeBytes && value.valueData == nil) {
+      value.valueData = GPBEmptyNSData();
+    } else if (type == GPBDataTypeString && value.valueString == nil) {
+      value.valueString = @"";
+    }
+  }
+  return value;
+}
+
+- (NSString *)textFormatName {
+  if ((description_->flags & GPBFieldTextFormatNameCustom) != 0) {
+    NSValue *extraInfoValue =
+        objc_getAssociatedObject(self, &kTextFormatExtraValueKey);
+    // Support can be left out at generation time.
+    if (!extraInfoValue) {
+      return nil;
+    }
+    const uint8_t *extraTextFormatInfo = [extraInfoValue pointerValue];
+    return GPBDecodeTextFormatName(extraTextFormatInfo, GPBFieldNumber(self),
+                                   self.name);
+  }
+
+  // The logic here has to match SetCommonFieldVariables() from
+  // objectivec_field.cc in the proto compiler.
+  NSString *name = self.name;
+  NSUInteger len = [name length];
+
+  // Remove the "_p" added to reserved names.
+  if ([name hasSuffix:@"_p"]) {
+    name = [name substringToIndex:(len - 2)];
+    len = [name length];
+  }
+
+  // Remove "Array" from the end for repeated fields.
+  if (((description_->flags & GPBFieldRepeated) != 0) &&
+      [name hasSuffix:@"Array"]) {
+    name = [name substringToIndex:(len - 5)];
+    len = [name length];
+  }
+
+  // Groups vs. other fields.
+  if (description_->dataType == GPBDataTypeGroup) {
+    // Just capitalize the first letter.
+    unichar firstChar = [name characterAtIndex:0];
+    if (firstChar >= 'a' && firstChar <= 'z') {
+      NSString *firstCharString =
+          [NSString stringWithFormat:@"%C", (unichar)(firstChar - 'a' + 'A')];
+      NSString *result =
+          [name stringByReplacingCharactersInRange:NSMakeRange(0, 1)
+                                        withString:firstCharString];
+      return result;
+    }
+    return name;
+
+  } else {
+    // Undo the CamelCase.
+    NSMutableString *result = [NSMutableString stringWithCapacity:len];
+    for (NSUInteger i = 0; i < len; i++) {
+      unichar c = [name characterAtIndex:i];
+      if (c >= 'A' && c <= 'Z') {
+        if (i > 0) {
+          [result appendFormat:@"_%C", (unichar)(c - 'A' + 'a')];
+        } else {
+          [result appendFormat:@"%C", c];
+        }
+      } else {
+        [result appendFormat:@"%C", c];
+      }
+    }
+    return result;
+  }
+}
+
+@end
+
+@implementation GPBEnumDescriptor {
+  NSString *name_;
+  GPBMessageEnumValueDescription *valueDescriptions_;
+  NSUInteger valueDescriptionsCount_;
+  GPBEnumValidationFunc enumVerifier_;
+  const uint8_t *extraTextFormatInfo_;
+}
+
+@synthesize name = name_;
+@synthesize enumVerifier = enumVerifier_;
+
++ (instancetype)
+    allocDescriptorForName:(NSString *)name
+                    values:(GPBMessageEnumValueDescription *)valueDescriptions
+                valueCount:(NSUInteger)valueCount
+              enumVerifier:(GPBEnumValidationFunc)enumVerifier {
+  GPBEnumDescriptor *descriptor = [[self alloc] initWithName:name
+                                                      values:valueDescriptions
+                                                  valueCount:valueCount
+                                                enumVerifier:enumVerifier];
+  return descriptor;
+}
+
++ (instancetype)
+    allocDescriptorForName:(NSString *)name
+                    values:(GPBMessageEnumValueDescription *)valueDescriptions
+                valueCount:(NSUInteger)valueCount
+              enumVerifier:(GPBEnumValidationFunc)enumVerifier
+       extraTextFormatInfo:(const char *)extraTextFormatInfo {
+  // Call the common case.
+  GPBEnumDescriptor *descriptor = [self allocDescriptorForName:name
+                                                        values:valueDescriptions
+                                                    valueCount:valueCount
+                                                  enumVerifier:enumVerifier];
+  // Set the extra info.
+  descriptor->extraTextFormatInfo_ = (const uint8_t *)extraTextFormatInfo;
+  return descriptor;
+}
+
+- (instancetype)initWithName:(NSString *)name
+                      values:(GPBMessageEnumValueDescription *)valueDescriptions
+                  valueCount:(NSUInteger)valueCount
+                enumVerifier:(GPBEnumValidationFunc)enumVerifier {
+  if ((self = [super init])) {
+    name_ = [name copy];
+    valueDescriptions_ = valueDescriptions;
+    valueDescriptionsCount_ = valueCount;
+    enumVerifier_ = enumVerifier;
+  }
+  return self;
+}
+
+- (NSString *)enumNameForValue:(int32_t)number {
+  for (NSUInteger i = 0; i < valueDescriptionsCount_; ++i) {
+    GPBMessageEnumValueDescription *scan = &valueDescriptions_[i];
+    if ((scan->number == number) && (scan->name != NULL)) {
+      NSString *fullName =
+          [NSString stringWithFormat:@"%@_%s", name_, scan->name];
+      return fullName;
+    }
+  }
+  return nil;
+}
+
+- (BOOL)getValue:(int32_t *)outValue forEnumName:(NSString *)name {
+  // Must have the prefix.
+  NSUInteger prefixLen = name_.length + 1;
+  if ((name.length <= prefixLen) || ![name hasPrefix:name_] ||
+      ([name characterAtIndex:prefixLen - 1] != '_')) {
+    return NO;
+  }
+
+  // Skip over the prefix.
+  const char *nameAsCStr = [name UTF8String];
+  nameAsCStr += prefixLen;
+
+  // Find it.
+  for (NSUInteger i = 0; i < valueDescriptionsCount_; ++i) {
+    GPBMessageEnumValueDescription *scan = &valueDescriptions_[i];
+    if ((scan->name != NULL) && (strcmp(nameAsCStr, scan->name) == 0)) {
+      if (outValue) {
+        *outValue = scan->number;
+      }
+      return YES;
+    }
+  }
+  return NO;
+}
+
+- (void)dealloc {
+  [name_ release];
+  [super dealloc];
+}
+
+- (NSString *)textFormatNameForValue:(int32_t)number {
+  // Find the EnumValue descriptor and its index.
+  GPBMessageEnumValueDescription *valueDescriptor = NULL;
+  NSUInteger valueDescriptorIndex;
+  for (valueDescriptorIndex = 0; valueDescriptorIndex < valueDescriptionsCount_;
+       ++valueDescriptorIndex) {
+    GPBMessageEnumValueDescription *scan =
+        &valueDescriptions_[valueDescriptorIndex];
+    if (scan->number == number) {
+      valueDescriptor = scan;
+      break;
+    }
+  }
+
+  // If we didn't find it, or names were disable at proto compile time, nothing
+  // we can do.
+  if (!valueDescriptor || !valueDescriptor->name) {
+    return nil;
+  }
+
+  NSString *result = nil;
+  // Naming adds an underscore between enum name and value name, skip that also.
+  NSString *shortName = @(valueDescriptor->name);
+
+  // See if it is in the map of special format handling.
+  if (extraTextFormatInfo_) {
+    result = GPBDecodeTextFormatName(extraTextFormatInfo_,
+                                     (int32_t)valueDescriptorIndex, shortName);
+  }
+  // Logic here needs to match what objectivec_enum.cc does in the proto
+  // compiler.
+  if (result == nil) {
+    NSUInteger len = [shortName length];
+    NSMutableString *worker = [NSMutableString stringWithCapacity:len];
+    for (NSUInteger i = 0; i < len; i++) {
+      unichar c = [shortName characterAtIndex:i];
+      if (i > 0 && c >= 'A' && c <= 'Z') {
+        [worker appendString:@"_"];
+      }
+      [worker appendFormat:@"%c", toupper((char)c)];
+    }
+    result = worker;
+  }
+  return result;
+}
+
+@end
+
+@implementation GPBExtensionDescriptor {
+  GPBGenericValue defaultValue_;
+}
+
+@synthesize containingMessageClass = containingMessageClass_;
+
+- (instancetype)initWithExtensionDescription:
+        (GPBExtensionDescription *)description {
+  if ((self = [super init])) {
+    description_ = description;
+
+#if DEBUG
+    const char *className = description->messageOrGroupClassName;
+    if (className) {
+      NSAssert(objc_lookUpClass(className) != Nil,
+               @"Class %s not defined", className);
+    }
+#endif
+
+    if (description->extendedClass) {
+      Class containingClass = objc_lookUpClass(description->extendedClass);
+      NSAssert(containingClass, @"Class %s not defined",
+               description->extendedClass);
+      containingMessageClass_ = containingClass;
+    }
+
+    GPBDataType type = description_->dataType;
+    if (type == GPBDataTypeBytes) {
+      // Data stored as a length prefixed c-string in descriptor records.
+      const uint8_t *bytes =
+          (const uint8_t *)description->defaultValue.valueData;
+      if (bytes) {
+        uint32_t length = *((uint32_t *)bytes);
+        // The length is stored in network byte order.
+        length = ntohl(length);
+        bytes += sizeof(length);
+        defaultValue_.valueData =
+            [[NSData alloc] initWithBytes:bytes length:length];
+      }
+    } else if (type == GPBDataTypeMessage || type == GPBDataTypeGroup) {
+      // The default is looked up in -defaultValue instead since extensions
+      // aren't common, we avoid the hit startup hit and it avoid initialization
+      // order issues.
+    } else {
+      defaultValue_ = description->defaultValue;
+    }
+  }
+  return self;
+}
+
+- (void)dealloc {
+  if ((description_->dataType == GPBDataTypeBytes) &&
+      !GPBExtensionIsRepeated(description_)) {
+    [defaultValue_.valueData release];
+  }
+  [super dealloc];
+}
+
+- (instancetype)copyWithZone:(NSZone *)zone {
+#pragma unused(zone)
+  // Immutable.
+  return [self retain];
+}
+
+- (NSString *)singletonName {
+  return @(description_->singletonName);
+}
+
+- (const char *)singletonNameC {
+  return description_->singletonName;
+}
+
+- (uint32_t)fieldNumber {
+  return description_->fieldNumber;
+}
+
+- (GPBDataType)dataType {
+  return description_->dataType;
+}
+
+- (GPBWireFormat)wireType {
+  return GPBWireFormatForType(description_->dataType,
+                              GPBExtensionIsPacked(description_));
+}
+
+- (GPBWireFormat)alternateWireType {
+  NSAssert(GPBExtensionIsRepeated(description_),
+           @"Only valid on repeated extensions");
+  return GPBWireFormatForType(description_->dataType,
+                              !GPBExtensionIsPacked(description_));
+}
+
+- (BOOL)isRepeated {
+  return GPBExtensionIsRepeated(description_);
+}
+
+- (BOOL)isMap {
+  return (description_->options & GPBFieldMapKeyMask) != 0;
+}
+
+- (BOOL)isPackable {
+  return GPBExtensionIsPacked(description_);
+}
+
+- (Class)msgClass {
+  return objc_getClass(description_->messageOrGroupClassName);
+}
+
+- (GPBEnumDescriptor *)enumDescriptor {
+  if (description_->dataType == GPBDataTypeEnum) {
+    GPBEnumDescriptor *enumDescriptor = description_->enumDescriptorFunc();
+    return enumDescriptor;
+  }
+  return nil;
+}
+
+- (id)defaultValue {
+  if (GPBExtensionIsRepeated(description_)) {
+    return nil;
+  }
+
+  switch (description_->dataType) {
+    case GPBDataTypeBool:
+      return @(defaultValue_.valueBool);
+    case GPBDataTypeFloat:
+      return @(defaultValue_.valueFloat);
+    case GPBDataTypeDouble:
+      return @(defaultValue_.valueDouble);
+    case GPBDataTypeInt32:
+    case GPBDataTypeSInt32:
+    case GPBDataTypeEnum:
+    case GPBDataTypeSFixed32:
+      return @(defaultValue_.valueInt32);
+    case GPBDataTypeInt64:
+    case GPBDataTypeSInt64:
+    case GPBDataTypeSFixed64:
+      return @(defaultValue_.valueInt64);
+    case GPBDataTypeUInt32:
+    case GPBDataTypeFixed32:
+      return @(defaultValue_.valueUInt32);
+    case GPBDataTypeUInt64:
+    case GPBDataTypeFixed64:
+      return @(defaultValue_.valueUInt64);
+    case GPBDataTypeBytes:
+      // Like message fields, the default is zero length data.
+      return (defaultValue_.valueData ? defaultValue_.valueData
+                                      : GPBEmptyNSData());
+    case GPBDataTypeString:
+      // Like message fields, the default is zero length string.
+      return (defaultValue_.valueString ? defaultValue_.valueString : @"");
+    case GPBDataTypeGroup:
+    case GPBDataTypeMessage:
+      return nil;
+  }
+}
+
+- (NSComparisonResult)compareByFieldNumber:(GPBExtensionDescriptor *)other {
+  int32_t selfNumber = description_->fieldNumber;
+  int32_t otherNumber = other->description_->fieldNumber;
+  if (selfNumber < otherNumber) {
+    return NSOrderedAscending;
+  } else if (selfNumber == otherNumber) {
+    return NSOrderedSame;
+  } else {
+    return NSOrderedDescending;
+  }
+}
+
+@end
