Selaa lähdekoodia

Beta quality drop of Objective C Support.

- Add more to the ObjC dir readme.
- Merge the ExtensionField and ExtensionDescriptor to reduce overhead.
- Fix an initialization race.
- Clean up the Xcode schemes.
- Remove the class/enum filter.
- Remove some forced inline that were bloating things without proof of performance wins.
- Rename some internal types to avoid conflicts with the well know types protos.
- Drop the use of ApplyFunctions to the compiler/optimizer can do what it wants.
- Better document some possible future improvements.
- Add missing support for parsing repeated primitive fields in packed or unpacked forms.
- Improve -hash.
- Add *Count for repeated and map<> fields to avoid auto create when checking for them being set.
Thomas Van Lenten 10 vuotta sitten
vanhempi
commit
d846b0b059
94 muutettua tiedostoa jossa 4792 lisäystä ja 4237 poistoa
  1. 6 12
      Makefile.am
  2. 113 0
      objectivec/DevTools/compile_testing_protos.sh
  3. 1 1
      objectivec/DevTools/full_mac_build.sh
  4. 1 1
      objectivec/GPBArray.h
  5. 1 1
      objectivec/GPBCodedInputStream.h
  6. 13 13
      objectivec/GPBCodedInputStream.m
  7. 2 2
      objectivec/GPBCodedInputStream_PackagePrivate.h
  8. 59 59
      objectivec/GPBCodedOutputStream.h
  9. 63 63
      objectivec/GPBCodedOutputStream.m
  10. 8 6
      objectivec/GPBDescriptor.h
  11. 220 87
      objectivec/GPBDescriptor.m
  12. 38 12
      objectivec/GPBDescriptor_PackagePrivate.h
  13. 1 1
      objectivec/GPBDictionary.h
  14. 255 248
      objectivec/GPBDictionary.m
  15. 16 15
      objectivec/GPBDictionary_PackagePrivate.h
  16. 0 525
      objectivec/GPBExtensionField.m
  17. 0 51
      objectivec/GPBExtensionField_PackagePrivate.h
  18. 11 12
      objectivec/GPBExtensionInternals.h
  19. 380 0
      objectivec/GPBExtensionInternals.m
  20. 4 4
      objectivec/GPBExtensionRegistry.h
  21. 17 15
      objectivec/GPBExtensionRegistry.m
  22. 7 7
      objectivec/GPBMessage.h
  23. 248 231
      objectivec/GPBMessage.m
  24. 2 2
      objectivec/GPBMessage_PackagePrivate.h
  25. 1 2
      objectivec/GPBProtocolBuffers.h
  26. 15 2
      objectivec/GPBProtocolBuffers.m
  27. 1 2
      objectivec/GPBProtocolBuffers_RuntimeSupport.h
  28. 3 4
      objectivec/GPBRootObject.m
  29. 2 2
      objectivec/GPBRootObject_PackagePrivate.h
  30. 24 24
      objectivec/GPBRuntimeTypes.h
  31. 3 3
      objectivec/GPBUnknownField.h
  32. 13 15
      objectivec/GPBUnknownField.m
  33. 3 3
      objectivec/GPBUnknownFieldSet.h
  34. 28 27
      objectivec/GPBUnknownFieldSet.m
  35. 3 3
      objectivec/GPBUnknownField_PackagePrivate.h
  36. 132 131
      objectivec/GPBUtilities.h
  37. 307 283
      objectivec/GPBUtilities.m
  38. 25 120
      objectivec/GPBUtilities_PackagePrivate.h
  39. 2 2
      objectivec/GPBWireFormat.h
  40. 20 20
      objectivec/GPBWireFormat.m
  41. 109 93
      objectivec/ProtocolBuffers_OSX.xcodeproj/project.pbxproj
  42. 213 6
      objectivec/ProtocolBuffers_OSX.xcodeproj/xcshareddata/xcschemes/PerformanceTests.xcscheme
  43. 1 1
      objectivec/ProtocolBuffers_OSX.xcodeproj/xcshareddata/xcschemes/ProtocolBuffers.xcscheme
  44. 113 97
      objectivec/ProtocolBuffers_iOS.xcodeproj/project.pbxproj
  45. 215 7
      objectivec/ProtocolBuffers_iOS.xcodeproj/xcshareddata/xcschemes/PerformanceTests.xcscheme
  46. 1 1
      objectivec/ProtocolBuffers_iOS.xcodeproj/xcshareddata/xcschemes/ProtocolBuffers.xcscheme
  47. 84 9
      objectivec/README.md
  48. 0 35
      objectivec/Tests/Filter2.txt
  49. 1 2
      objectivec/Tests/GPBARCUnittestProtos.m
  50. 1 1
      objectivec/Tests/GPBCodedInputStreamTests.m
  51. 2 1
      objectivec/Tests/GPBConcurrencyTests.m
  52. 0 98
      objectivec/Tests/GPBFilteredMessageTests.m
  53. 126 16
      objectivec/Tests/GPBMessageTests+Runtime.m
  54. 130 6
      objectivec/Tests/GPBMessageTests+Serialization.m
  55. 23 26
      objectivec/Tests/GPBMessageTests.m
  56. 6 0
      objectivec/Tests/GPBTestUtilities.h
  57. 300 86
      objectivec/Tests/GPBTestUtilities.m
  58. 1 2
      objectivec/Tests/GPBUnittestProtos.m
  59. 24 23
      objectivec/Tests/GPBUnknownFieldSetTest.m
  60. 0 190
      objectivec/Tests/GPBUtilitiesTests.m
  61. 6 6
      objectivec/Tests/GPBWireFormatTests.m
  62. 0 71
      objectivec/Tests/unittest_filter.proto
  63. 0 37
      objectivec/Tests/unittest_name_mangling.proto
  64. 17 8
      objectivec/Tests/unittest_objc_startup.proto
  65. 29 23
      objectivec/google/protobuf/Any.pbobjc.m
  66. 3 0
      objectivec/google/protobuf/Api.pbobjc.h
  67. 79 72
      objectivec/google/protobuf/Api.pbobjc.m
  68. 30 0
      objectivec/google/protobuf/Descriptor.pbobjc.h
  69. 273 249
      objectivec/google/protobuf/Descriptor.pbobjc.m
  70. 28 22
      objectivec/google/protobuf/Duration.pbobjc.m
  71. 22 18
      objectivec/google/protobuf/Empty.pbobjc.m
  72. 1 0
      objectivec/google/protobuf/FieldMask.pbobjc.h
  73. 26 20
      objectivec/google/protobuf/FieldMask.pbobjc.m
  74. 25 19
      objectivec/google/protobuf/SourceContext.pbobjc.m
  75. 2 0
      objectivec/google/protobuf/Struct.pbobjc.h
  76. 87 75
      objectivec/google/protobuf/Struct.pbobjc.m
  77. 28 22
      objectivec/google/protobuf/Timestamp.pbobjc.m
  78. 7 0
      objectivec/google/protobuf/Type.pbobjc.h
  79. 175 159
      objectivec/google/protobuf/Type.pbobjc.m
  80. 201 171
      objectivec/google/protobuf/Wrappers.pbobjc.m
  81. 1 1
      src/Makefile.am
  82. 3 9
      src/google/protobuf/compiler/objectivec/objectivec_enum_field.cc
  83. 5 34
      src/google/protobuf/compiler/objectivec/objectivec_extension.cc
  84. 1 5
      src/google/protobuf/compiler/objectivec/objectivec_extension.h
  85. 23 68
      src/google/protobuf/compiler/objectivec/objectivec_field.cc
  86. 126 167
      src/google/protobuf/compiler/objectivec/objectivec_file.cc
  87. 0 4
      src/google/protobuf/compiler/objectivec/objectivec_file.h
  88. 0 4
      src/google/protobuf/compiler/objectivec/objectivec_generator.cc
  89. 4 59
      src/google/protobuf/compiler/objectivec/objectivec_helpers.cc
  90. 1 4
      src/google/protobuf/compiler/objectivec/objectivec_helpers.h
  91. 8 0
      src/google/protobuf/compiler/objectivec/objectivec_helpers_unittest.cc
  92. 181 188
      src/google/protobuf/compiler/objectivec/objectivec_message.cc
  93. 1 10
      src/google/protobuf/compiler/objectivec/objectivec_message.h
  94. 1 1
      src/google/protobuf/compiler/objectivec/objectivec_message_field.cc

+ 6 - 12
Makefile.am

@@ -506,14 +506,10 @@ objectivec_EXTRA_DIST=                                                       \
   objectivec/GPBDictionary.h                                                 \
   objectivec/GPBDictionary.m                                                 \
   objectivec/GPBDictionary_PackagePrivate.h                                  \
-  objectivec/GPBExtensionField.h                                             \
-  objectivec/GPBExtensionField.m                                             \
-  objectivec/GPBExtensionField_PackagePrivate.h                              \
+  objectivec/GPBExtensionInternals.h                                         \
+  objectivec/GPBExtensionInternals.m                                         \
   objectivec/GPBExtensionRegistry.h                                          \
   objectivec/GPBExtensionRegistry.m                                          \
-  objectivec/GPBField.h                                                      \
-  objectivec/GPBField.m                                                      \
-  objectivec/GPBField_PackagePrivate.h                                       \
   objectivec/GPBMessage.h                                                    \
   objectivec/GPBMessage.m                                                    \
   objectivec/GPBMessage_PackagePrivate.h                                     \
@@ -523,7 +519,10 @@ objectivec_EXTRA_DIST=                                                       \
   objectivec/GPBRootObject.h                                                 \
   objectivec/GPBRootObject.m                                                 \
   objectivec/GPBRootObject_PackagePrivate.h                                  \
-  objectivec/GPBTypes.h                                                      \
+  objectivec/GPBRuntimeTypes.h                                               \
+  objectivec/GPBUnknownField.h                                               \
+  objectivec/GPBUnknownField.m                                               \
+  objectivec/GPBUnknownField_PackagePrivate.h                                \
   objectivec/GPBUnknownFieldSet.h                                            \
   objectivec/GPBUnknownFieldSet.m                                            \
   objectivec/GPBUnknownFieldSet_PackagePrivate.h                             \
@@ -547,8 +546,6 @@ objectivec_EXTRA_DIST=                                                       \
   objectivec/ProtocolBuffers_OSX.xcodeproj/xcshareddata/xcschemes/PerformanceTests.xcscheme \
   objectivec/ProtocolBuffers_OSX.xcodeproj/xcshareddata/xcschemes/ProtocolBuffers.xcscheme \
   objectivec/README.md                                                       \
-  objectivec/Tests/Filter1.txt                                               \
-  objectivec/Tests/Filter2.txt                                               \
   objectivec/Tests/golden_message                                            \
   objectivec/Tests/golden_packed_fields_message                              \
   objectivec/Tests/GPBARCUnittestProtos.m                                    \
@@ -564,7 +561,6 @@ objectivec_EXTRA_DIST=                                                       \
   objectivec/Tests/GPBDictionaryTests+UInt32.m                               \
   objectivec/Tests/GPBDictionaryTests+UInt64.m                               \
   objectivec/Tests/GPBDictionaryTests.pddm                                   \
-  objectivec/Tests/GPBFilteredMessageTests.m                                 \
   objectivec/Tests/GPBMessageTests+Merge.m                                   \
   objectivec/Tests/GPBMessageTests+Runtime.m                                 \
   objectivec/Tests/GPBMessageTests+Serialization.m                           \
@@ -596,8 +592,6 @@ objectivec_EXTRA_DIST=                                                       \
   objectivec/Tests/text_format_map_unittest_data.txt                          \
   objectivec/Tests/text_format_unittest_data.txt                              \
   objectivec/Tests/unittest_cycle.proto                                       \
-  objectivec/Tests/unittest_filter.proto                                      \
-  objectivec/Tests/unittest_name_mangling.proto                               \
   objectivec/Tests/unittest_objc.proto                                        \
   objectivec/Tests/unittest_runtime_proto2.proto                              \
   objectivec/Tests/unittest_runtime_proto3.proto                              \

+ 113 - 0
objectivec/DevTools/compile_testing_protos.sh

@@ -0,0 +1,113 @@
+#!/bin/bash
+
+# Invoked by the Xcode projects to build the protos needed for the unittests.
+
+set -eu
+
+readonly OUTPUT_DIR="${PROJECT_DERIVED_FILE_DIR}/protos"
+
+# Helper for bailing.
+die() {
+  echo "Error: $1"
+  exit 2
+}
+
+# What to do.
+case "${ACTION}" in
+  "")
+    # Build, fall thru
+    ;;
+  "clean")
+    rm -rf "${OUTPUT_DIR}"
+    exit 0
+    ;;
+  *)
+    die "Unknown action requested: ${ACTION}"
+    ;;
+esac
+
+# Move to the top of the protobuf directories.
+cd "${SRCROOT}/.."
+
+[[ -x src/protoc ]] || \
+  die "Could not find the protoc binary; make sure you have built it (objectivec/DevTools/full_mac_build.sh -h)."
+
+RUN_PROTOC=no
+if [[ ! -d "${OUTPUT_DIR}" ]] ; then
+  RUN_PROTOC=yes
+else
+  # Find the newest input file (protos, compiler, and this script).
+  # (these patterns catch some extra stuff, but better to over sample than
+  # under)
+  readonly NewestInput=$(find \
+     src/google/protobuf/*.proto \
+     objectivec/Tests/*.proto \
+     src/.libs src/*.la src/protoc \
+     objectivec/DevTools/compile_testing_protos.sh \
+        -type f -print0 \
+        | xargs -0 stat -f "%m %N" \
+        | sort -n | tail -n1 | cut -f2- -d" ")
+  # Find the oldest output file.
+  readonly OldestOutput=$(find \
+        "${OUTPUT_DIR}" \
+        -type f -print0 \
+        | xargs -0 stat -f "%m %N" \
+        | sort -n -r | tail -n1 | cut -f2- -d" ")
+  # If the newest input is newer than the oldest output, regenerate.
+  if [[ "${NewestInput}" -nt "${OldestOutput}" ]] ; then
+    RUN_PROTOC=yes
+  fi
+fi
+
+if [[ "${RUN_PROTOC}" != "yes" ]] ; then
+  # Up to date.
+  exit 0
+fi
+
+# Ensure the output dir exists
+mkdir -p "${OUTPUT_DIR}/google/protobuf"
+
+CORE_PROTO_FILES=(                                         \
+  src/google/protobuf/unittest_custom_options.proto        \
+  src/google/protobuf/unittest_enormous_descriptor.proto   \
+  src/google/protobuf/unittest_embed_optimize_for.proto    \
+  src/google/protobuf/unittest_empty.proto                 \
+  src/google/protobuf/unittest_import.proto                \
+  src/google/protobuf/unittest_import_lite.proto           \
+  src/google/protobuf/unittest_lite.proto                  \
+  src/google/protobuf/unittest_mset.proto                  \
+  src/google/protobuf/unittest_no_generic_services.proto   \
+  src/google/protobuf/unittest_optimize_for.proto          \
+  src/google/protobuf/unittest.proto                       \
+  src/google/protobuf/unittest_import_public.proto         \
+  src/google/protobuf/unittest_import_public_lite.proto    \
+  src/google/protobuf/unittest_drop_unknown_fields.proto   \
+  src/google/protobuf/unittest_preserve_unknown_enum.proto \
+  src/google/protobuf/map_lite_unittest.proto              \
+  src/google/protobuf/map_proto2_unittest.proto            \
+  src/google/protobuf/map_unittest.proto                   \
+)
+
+compile_proto() {
+  src/protoc                                   \
+    --objc_out="${OUTPUT_DIR}/google/protobuf" \
+    --proto_path=src/google/protobuf/          \
+    --proto_path=src                           \
+    $*
+}
+
+for a_proto in "${CORE_PROTO_FILES[@]}" ; do
+  compile_proto "${a_proto}"
+done
+
+OBJC_PROTO_FILES=(                               \
+  objectivec/Tests/unittest_cycle.proto          \
+  objectivec/Tests/unittest_runtime_proto2.proto \
+  objectivec/Tests/unittest_runtime_proto3.proto \
+  objectivec/Tests/unittest_objc.proto           \
+  objectivec/Tests/unittest_objc_startup.proto   \
+)
+
+for a_proto in "${OBJC_PROTO_FILES[@]}" ; do
+  compile_proto --proto_path="objectivec/Tests" "${a_proto}"
+done

+ 1 - 1
objectivec/DevTools/full_mac_build.sh

@@ -162,7 +162,7 @@ wrapped_make -j "${NUM_MAKE_JOBS}" all
 wrapped_make -j "${NUM_MAKE_JOBS}" check
 
 header "Ensuring the ObjC descriptors are current."
-# Find the newest input file (protos, compiler, and this script).
+# Find the newest input file (protos, compiler, and the generator script).
 # (these patterns catch some extra stuff, but better to over sample than under)
 readonly NewestInput=$(find \
    src/google/protobuf/*.proto \

+ 1 - 1
objectivec/GPBArray.h

@@ -30,7 +30,7 @@
 
 #import <Foundation/Foundation.h>
 
-#import "GPBTypes.h"
+#import "GPBRuntimeTypes.h"
 
 // These classes are used for repeated fields of basic data types. They are used because
 // they perform better than boxing into NSNumbers in NSArrays.

+ 1 - 1
objectivec/GPBCodedInputStream.h

@@ -60,7 +60,7 @@
 - (int64_t)readSInt64;
 - (BOOL)readBool;
 - (NSString *)readString;
-- (NSData *)readData;
+- (NSData *)readBytes;
 
 // Read an embedded message field value from the stream.
 - (void)readMessage:(GPBMessage *)message

+ 13 - 13
objectivec/GPBCodedInputStream.m

@@ -38,7 +38,7 @@
 
 static const NSUInteger kDefaultRecursionLimit = 64;
 
-static inline void CheckSize(GPBCodedInputStreamState *state, size_t size) {
+static void CheckSize(GPBCodedInputStreamState *state, size_t size) {
   size_t newSize = state->bufferPos + size;
   if (newSize > state->bufferSize) {
     [NSException raise:NSParseErrorException format:@""];
@@ -50,26 +50,26 @@ static inline void CheckSize(GPBCodedInputStreamState *state, size_t size) {
   }
 }
 
-static inline int8_t ReadRawByte(GPBCodedInputStreamState *state) {
+static int8_t ReadRawByte(GPBCodedInputStreamState *state) {
   CheckSize(state, sizeof(int8_t));
   return ((int8_t *)state->bytes)[state->bufferPos++];
 }
 
-static inline int32_t ReadRawLittleEndian32(GPBCodedInputStreamState *state) {
+static int32_t ReadRawLittleEndian32(GPBCodedInputStreamState *state) {
   CheckSize(state, sizeof(int32_t));
   int32_t value = OSReadLittleInt32(state->bytes, state->bufferPos);
   state->bufferPos += sizeof(int32_t);
   return value;
 }
 
-static inline int64_t ReadRawLittleEndian64(GPBCodedInputStreamState *state) {
+static int64_t ReadRawLittleEndian64(GPBCodedInputStreamState *state) {
   CheckSize(state, sizeof(int64_t));
   int64_t value = OSReadLittleInt64(state->bytes, state->bufferPos);
   state->bufferPos += sizeof(int64_t);
   return value;
 }
 
-static inline int32_t ReadRawVarint32(GPBCodedInputStreamState *state) {
+static int32_t ReadRawVarint32(GPBCodedInputStreamState *state) {
   int8_t tmp = ReadRawByte(state);
   if (tmp >= 0) {
     return tmp;
@@ -104,7 +104,7 @@ static inline int32_t ReadRawVarint32(GPBCodedInputStreamState *state) {
   return result;
 }
 
-static inline int64_t ReadRawVarint64(GPBCodedInputStreamState *state) {
+static int64_t ReadRawVarint64(GPBCodedInputStreamState *state) {
   int32_t shift = 0;
   int64_t result = 0;
   while (shift < 64) {
@@ -119,7 +119,7 @@ static inline int64_t ReadRawVarint64(GPBCodedInputStreamState *state) {
   return 0;
 }
 
-static inline void SkipRawData(GPBCodedInputStreamState *state, size_t size) {
+static void SkipRawData(GPBCodedInputStreamState *state, size_t size) {
   CheckSize(state, size);
   state->bufferPos += size;
 }
@@ -222,7 +222,7 @@ NSString *GPBCodedInputStreamReadRetainedString(
   return result;
 }
 
-NSData *GPBCodedInputStreamReadRetainedData(GPBCodedInputStreamState *state) {
+NSData *GPBCodedInputStreamReadRetainedBytes(GPBCodedInputStreamState *state) {
   int32_t size = ReadRawVarint32(state);
   if (size < 0) return nil;
   CheckSize(state, size);
@@ -232,7 +232,7 @@ NSData *GPBCodedInputStreamReadRetainedData(GPBCodedInputStreamState *state) {
   return result;
 }
 
-NSData *GPBCodedInputStreamReadRetainedDataNoCopy(
+NSData *GPBCodedInputStreamReadRetainedBytesNoCopy(
     GPBCodedInputStreamState *state) {
   int32_t size = ReadRawVarint32(state);
   if (size < 0) return nil;
@@ -453,8 +453,8 @@ void GPBCodedInputStreamCheckLastTagWas(GPBCodedInputStreamState *state,
   GPBCodedInputStreamPopLimit(&state_, oldLimit);
 }
 
-- (NSData *)readData {
-  return [GPBCodedInputStreamReadRetainedData(&state_) autorelease];
+- (NSData *)readBytes {
+  return [GPBCodedInputStreamReadRetainedBytes(&state_) autorelease];
 }
 
 - (uint32_t)readUInt32 {
@@ -499,7 +499,7 @@ void GPBCodedInputStreamCheckLastTagWas(GPBCodedInputStreamState *state,
 
 // Returns true if the passed in bytes are 7 bit ascii.
 // This routine needs to be fast.
-static inline bool AreBytesIn7BitASCII(const uint8_t *bytes, NSUInteger len) {
+static bool AreBytesIn7BitASCII(const uint8_t *bytes, NSUInteger len) {
 // In the loops below, it's more efficient to collect rather than do
 // conditional at every step.
 #if __LP64__
@@ -587,7 +587,7 @@ static inline bool AreBytesIn7BitASCII(const uint8_t *bytes, NSUInteger len) {
   return true;
 }
 
-static inline void GPBStringInitStringValue(GPBString *string) {
+static void GPBStringInitStringValue(GPBString *string) {
   OSSpinLockLock(&string->lock_);
   GPBStringInitStringValueAlreadyLocked(string);
   OSSpinLockUnlock(&string->lock_);

+ 2 - 2
objectivec/GPBCodedInputStream_PackagePrivate.h

@@ -114,9 +114,9 @@ int64_t GPBCodedInputStreamReadSInt64(GPBCodedInputStreamState *state);
 BOOL GPBCodedInputStreamReadBool(GPBCodedInputStreamState *state);
 NSString *GPBCodedInputStreamReadRetainedString(GPBCodedInputStreamState *state)
     __attribute((ns_returns_retained));
-NSData *GPBCodedInputStreamReadRetainedData(GPBCodedInputStreamState *state)
+NSData *GPBCodedInputStreamReadRetainedBytes(GPBCodedInputStreamState *state)
     __attribute((ns_returns_retained));
-NSData *GPBCodedInputStreamReadRetainedDataNoCopy(
+NSData *GPBCodedInputStreamReadRetainedBytesNoCopy(
     GPBCodedInputStreamState *state) __attribute((ns_returns_retained));
 
 size_t GPBCodedInputStreamPushLimit(GPBCodedInputStreamState *state,

+ 59 - 59
objectivec/GPBCodedOutputStream.h

@@ -30,7 +30,7 @@
 
 #import <Foundation/Foundation.h>
 
-#import "GPBTypes.h"
+#import "GPBRuntimeTypes.h"
 #import "GPBWireFormat.h"
 
 @class GPBBoolArray;
@@ -84,110 +84,110 @@
 // This block of code is generated, do not edit it directly.
 
 - (void)writeDouble:(int32_t)fieldNumber value:(double)value;
-- (void)writeDoubles:(int32_t)fieldNumber
-              values:(GPBDoubleArray *)values
-                 tag:(uint32_t)tag;
+- (void)writeDoubleArray:(int32_t)fieldNumber
+                  values:(GPBDoubleArray *)values
+                     tag:(uint32_t)tag;
 - (void)writeDoubleNoTag:(double)value;
 
 - (void)writeFloat:(int32_t)fieldNumber value:(float)value;
-- (void)writeFloats:(int32_t)fieldNumber
-             values:(GPBFloatArray *)values
-                tag:(uint32_t)tag;
+- (void)writeFloatArray:(int32_t)fieldNumber
+                 values:(GPBFloatArray *)values
+                    tag:(uint32_t)tag;
 - (void)writeFloatNoTag:(float)value;
 
 - (void)writeUInt64:(int32_t)fieldNumber value:(uint64_t)value;
-- (void)writeUInt64s:(int32_t)fieldNumber
-              values:(GPBUInt64Array *)values
-                 tag:(uint32_t)tag;
+- (void)writeUInt64Array:(int32_t)fieldNumber
+                  values:(GPBUInt64Array *)values
+                     tag:(uint32_t)tag;
 - (void)writeUInt64NoTag:(uint64_t)value;
 
 - (void)writeInt64:(int32_t)fieldNumber value:(int64_t)value;
-- (void)writeInt64s:(int32_t)fieldNumber
-             values:(GPBInt64Array *)values
-                tag:(uint32_t)tag;
+- (void)writeInt64Array:(int32_t)fieldNumber
+                 values:(GPBInt64Array *)values
+                    tag:(uint32_t)tag;
 - (void)writeInt64NoTag:(int64_t)value;
 
 - (void)writeInt32:(int32_t)fieldNumber value:(int32_t)value;
-- (void)writeInt32s:(int32_t)fieldNumber
-             values:(GPBInt32Array *)values
-                tag:(uint32_t)tag;
+- (void)writeInt32Array:(int32_t)fieldNumber
+                 values:(GPBInt32Array *)values
+                    tag:(uint32_t)tag;
 - (void)writeInt32NoTag:(int32_t)value;
 
 - (void)writeUInt32:(int32_t)fieldNumber value:(uint32_t)value;
-- (void)writeUInt32s:(int32_t)fieldNumber
-              values:(GPBUInt32Array *)values
-                 tag:(uint32_t)tag;
+- (void)writeUInt32Array:(int32_t)fieldNumber
+                  values:(GPBUInt32Array *)values
+                     tag:(uint32_t)tag;
 - (void)writeUInt32NoTag:(uint32_t)value;
 
 - (void)writeFixed64:(int32_t)fieldNumber value:(uint64_t)value;
-- (void)writeFixed64s:(int32_t)fieldNumber
-               values:(GPBUInt64Array *)values
-                  tag:(uint32_t)tag;
+- (void)writeFixed64Array:(int32_t)fieldNumber
+                   values:(GPBUInt64Array *)values
+                      tag:(uint32_t)tag;
 - (void)writeFixed64NoTag:(uint64_t)value;
 
 - (void)writeFixed32:(int32_t)fieldNumber value:(uint32_t)value;
-- (void)writeFixed32s:(int32_t)fieldNumber
-               values:(GPBUInt32Array *)values
-                  tag:(uint32_t)tag;
+- (void)writeFixed32Array:(int32_t)fieldNumber
+                   values:(GPBUInt32Array *)values
+                      tag:(uint32_t)tag;
 - (void)writeFixed32NoTag:(uint32_t)value;
 
 - (void)writeSInt32:(int32_t)fieldNumber value:(int32_t)value;
-- (void)writeSInt32s:(int32_t)fieldNumber
-              values:(GPBInt32Array *)values
-                 tag:(uint32_t)tag;
+- (void)writeSInt32Array:(int32_t)fieldNumber
+                  values:(GPBInt32Array *)values
+                     tag:(uint32_t)tag;
 - (void)writeSInt32NoTag:(int32_t)value;
 
 - (void)writeSInt64:(int32_t)fieldNumber value:(int64_t)value;
-- (void)writeSInt64s:(int32_t)fieldNumber
-              values:(GPBInt64Array *)values
-                 tag:(uint32_t)tag;
+- (void)writeSInt64Array:(int32_t)fieldNumber
+                  values:(GPBInt64Array *)values
+                     tag:(uint32_t)tag;
 - (void)writeSInt64NoTag:(int64_t)value;
 
 - (void)writeSFixed64:(int32_t)fieldNumber value:(int64_t)value;
-- (void)writeSFixed64s:(int32_t)fieldNumber
-                values:(GPBInt64Array *)values
-                   tag:(uint32_t)tag;
+- (void)writeSFixed64Array:(int32_t)fieldNumber
+                    values:(GPBInt64Array *)values
+                       tag:(uint32_t)tag;
 - (void)writeSFixed64NoTag:(int64_t)value;
 
 - (void)writeSFixed32:(int32_t)fieldNumber value:(int32_t)value;
-- (void)writeSFixed32s:(int32_t)fieldNumber
-                values:(GPBInt32Array *)values
-                   tag:(uint32_t)tag;
+- (void)writeSFixed32Array:(int32_t)fieldNumber
+                    values:(GPBInt32Array *)values
+                       tag:(uint32_t)tag;
 - (void)writeSFixed32NoTag:(int32_t)value;
 
 - (void)writeBool:(int32_t)fieldNumber value:(BOOL)value;
-- (void)writeBools:(int32_t)fieldNumber
-            values:(GPBBoolArray *)values
-               tag:(uint32_t)tag;
+- (void)writeBoolArray:(int32_t)fieldNumber
+                values:(GPBBoolArray *)values
+                   tag:(uint32_t)tag;
 - (void)writeBoolNoTag:(BOOL)value;
 
 - (void)writeEnum:(int32_t)fieldNumber value:(int32_t)value;
-- (void)writeEnums:(int32_t)fieldNumber
-            values:(GPBEnumArray *)values
-               tag:(uint32_t)tag;
+- (void)writeEnumArray:(int32_t)fieldNumber
+                values:(GPBEnumArray *)values
+                   tag:(uint32_t)tag;
 - (void)writeEnumNoTag:(int32_t)value;
 
 - (void)writeString:(int32_t)fieldNumber value:(NSString *)value;
-- (void)writeStrings:(int32_t)fieldNumber values:(NSArray *)values;
+- (void)writeStringArray:(int32_t)fieldNumber values:(NSArray *)values;
 - (void)writeStringNoTag:(NSString *)value;
 
 - (void)writeMessage:(int32_t)fieldNumber value:(GPBMessage *)value;
-- (void)writeMessages:(int32_t)fieldNumber values:(NSArray *)values;
+- (void)writeMessageArray:(int32_t)fieldNumber values:(NSArray *)values;
 - (void)writeMessageNoTag:(GPBMessage *)value;
 
-- (void)writeData:(int32_t)fieldNumber value:(NSData *)value;
-- (void)writeDatas:(int32_t)fieldNumber values:(NSArray *)values;
-- (void)writeDataNoTag:(NSData *)value;
+- (void)writeBytes:(int32_t)fieldNumber value:(NSData *)value;
+- (void)writeBytesArray:(int32_t)fieldNumber values:(NSArray *)values;
+- (void)writeBytesNoTag:(NSData *)value;
 
 - (void)writeGroup:(int32_t)fieldNumber
              value:(GPBMessage *)value;
-- (void)writeGroups:(int32_t)fieldNumber values:(NSArray *)values;
+- (void)writeGroupArray:(int32_t)fieldNumber values:(NSArray *)values;
 - (void)writeGroupNoTag:(int32_t)fieldNumber
                   value:(GPBMessage *)value;
 
 - (void)writeUnknownGroup:(int32_t)fieldNumber
                     value:(GPBUnknownFieldSet *)value;
-- (void)writeUnknownGroups:(int32_t)fieldNumber values:(NSArray *)values;
+- (void)writeUnknownGroupArray:(int32_t)fieldNumber values:(NSArray *)values;
 - (void)writeUnknownGroupNoTag:(int32_t)fieldNumber
                          value:(GPBUnknownFieldSet *)value;
 
@@ -230,7 +230,7 @@ size_t GPBComputeUnknownGroupSize(int32_t fieldNumber,
     __attribute__((const));
 size_t GPBComputeMessageSize(int32_t fieldNumber, GPBMessage *value)
     __attribute__((const));
-size_t GPBComputeDataSize(int32_t fieldNumber, NSData *value)
+size_t GPBComputeBytesSize(int32_t fieldNumber, NSData *value)
     __attribute__((const));
 size_t GPBComputeUInt32Size(int32_t fieldNumber, uint32_t value)
     __attribute__((const));
@@ -243,7 +243,7 @@ size_t GPBComputeSInt32Size(int32_t fieldNumber, int32_t value)
 size_t GPBComputeSInt64Size(int32_t fieldNumber, int64_t value)
     __attribute__((const));
 size_t GPBComputeTagSize(int32_t fieldNumber) __attribute__((const));
-size_t GPBComputeWireFormatTagSize(int field_number, GPBType type)
+size_t GPBComputeWireFormatTagSize(int field_number, GPBDataType dataType)
     __attribute__((const));
 
 size_t GPBComputeDoubleSizeNoTag(double value) __attribute__((const));
@@ -259,7 +259,7 @@ size_t GPBComputeGroupSizeNoTag(GPBMessage *value) __attribute__((const));
 size_t GPBComputeUnknownGroupSizeNoTag(GPBUnknownFieldSet *value)
     __attribute__((const));
 size_t GPBComputeMessageSizeNoTag(GPBMessage *value) __attribute__((const));
-size_t GPBComputeDataSizeNoTag(NSData *value) __attribute__((const));
+size_t GPBComputeBytesSizeNoTag(NSData *value) __attribute__((const));
 size_t GPBComputeUInt32SizeNoTag(int32_t value) __attribute__((const));
 size_t GPBComputeEnumSizeNoTag(int32_t value) __attribute__((const));
 size_t GPBComputeSFixed32SizeNoTag(int32_t value) __attribute__((const));
@@ -297,22 +297,22 @@ CF_EXTERN_C_END
 // Write methods for types that can be in packed arrays.
 //%PDDM-DEFINE _WRITE_PACKABLE_DECLS(NAME, ARRAY_TYPE, TYPE)
 //%- (void)write##NAME:(int32_t)fieldNumber value:(TYPE)value;
-//%- (void)write##NAME##s:(int32_t)fieldNumber
-//%       NAME$S values:(GPB##ARRAY_TYPE##Array *)values
-//%       NAME$S    tag:(uint32_t)tag;
+//%- (void)write##NAME##Array:(int32_t)fieldNumber
+//%       NAME$S     values:(GPB##ARRAY_TYPE##Array *)values
+//%       NAME$S        tag:(uint32_t)tag;
 //%- (void)write##NAME##NoTag:(TYPE)value;
 //%
 // Write methods for types that aren't in packed arrays.
 //%PDDM-DEFINE _WRITE_UNPACKABLE_DECLS(NAME, TYPE)
 //%- (void)write##NAME:(int32_t)fieldNumber value:(TYPE)value;
-//%- (void)write##NAME##s:(int32_t)fieldNumber values:(NSArray *)values;
+//%- (void)write##NAME##Array:(int32_t)fieldNumber values:(NSArray *)values;
 //%- (void)write##NAME##NoTag:(TYPE)value;
 //%
 // Special write methods for Groups.
 //%PDDM-DEFINE _WRITE_GROUP_DECLS(NAME, TYPE)
 //%- (void)write##NAME:(int32_t)fieldNumber
 //%       NAME$S value:(TYPE)value;
-//%- (void)write##NAME##s:(int32_t)fieldNumber values:(NSArray *)values;
+//%- (void)write##NAME##Array:(int32_t)fieldNumber values:(NSArray *)values;
 //%- (void)write##NAME##NoTag:(int32_t)fieldNumber
 //%            NAME$S value:(TYPE)value;
 //%
@@ -335,6 +335,6 @@ CF_EXTERN_C_END
 //%_WRITE_PACKABLE_DECLS(Enum, Enum, int32_t)
 //%_WRITE_UNPACKABLE_DECLS(String, NSString *)
 //%_WRITE_UNPACKABLE_DECLS(Message, GPBMessage *)
-//%_WRITE_UNPACKABLE_DECLS(Data, NSData *)
+//%_WRITE_UNPACKABLE_DECLS(Bytes, NSData *)
 //%_WRITE_GROUP_DECLS(Group, GPBMessage *)
 //%_WRITE_GROUP_DECLS(UnknownGroup, GPBUnknownFieldSet *)

+ 63 - 63
objectivec/GPBCodedOutputStream.m

@@ -372,14 +372,14 @@ static void GPBWriteRawLittleEndian64(GPBOutputBufferState *state,
   [self writeMessageNoTag:value];
 }
 
-- (void)writeDataNoTag:(NSData *)value {
+- (void)writeBytesNoTag:(NSData *)value {
   GPBWriteRawVarint32(&state_, (int32_t)[value length]);
   [self writeRawData:value];
 }
 
-- (void)writeData:(int32_t)fieldNumber value:(NSData *)value {
+- (void)writeBytes:(int32_t)fieldNumber value:(NSData *)value {
   GPBWriteTagWithFormat(&state_, fieldNumber, GPBWireFormatLengthDelimited);
-  [self writeDataNoTag:value];
+  [self writeBytesNoTag:value];
 }
 
 - (void)writeUInt32NoTag:(uint32_t)value {
@@ -436,9 +436,9 @@ static void GPBWriteRawLittleEndian64(GPBOutputBufferState *state,
 }
 
 //%PDDM-DEFINE WRITE_PACKABLE_DEFNS(NAME, ARRAY_TYPE, TYPE, ACCESSOR_NAME)
-//%- (void)write##NAME##s:(int32_t)fieldNumber
-//%       NAME$S values:(GPB##ARRAY_TYPE##Array *)values
-//%       NAME$S    tag:(uint32_t)tag {
+//%- (void)write##NAME##Array:(int32_t)fieldNumber
+//%       NAME$S     values:(GPB##ARRAY_TYPE##Array *)values
+//%       NAME$S        tag:(uint32_t)tag {
 //%  if (tag != 0) {
 //%    if (values.count == 0) return;
 //%    __block size_t dataSize = 0;
@@ -461,7 +461,7 @@ static void GPBWriteRawLittleEndian64(GPBOutputBufferState *state,
 //%}
 //%
 //%PDDM-DEFINE WRITE_UNPACKABLE_DEFNS(NAME, TYPE)
-//%- (void)write##NAME##s:(int32_t)fieldNumber values:(NSArray *)values {
+//%- (void)write##NAME##Array:(int32_t)fieldNumber values:(NSArray *)values {
 //%  for (TYPE *value in values) {
 //%    [self write##NAME:fieldNumber value:value];
 //%  }
@@ -470,9 +470,9 @@ static void GPBWriteRawLittleEndian64(GPBOutputBufferState *state,
 //%PDDM-EXPAND WRITE_PACKABLE_DEFNS(Double, Double, double, )
 // This block of code is generated, do not edit it directly.
 
-- (void)writeDoubles:(int32_t)fieldNumber
-              values:(GPBDoubleArray *)values
-                 tag:(uint32_t)tag {
+- (void)writeDoubleArray:(int32_t)fieldNumber
+                  values:(GPBDoubleArray *)values
+                     tag:(uint32_t)tag {
   if (tag != 0) {
     if (values.count == 0) return;
     __block size_t dataSize = 0;
@@ -497,9 +497,9 @@ static void GPBWriteRawLittleEndian64(GPBOutputBufferState *state,
 //%PDDM-EXPAND WRITE_PACKABLE_DEFNS(Float, Float, float, )
 // This block of code is generated, do not edit it directly.
 
-- (void)writeFloats:(int32_t)fieldNumber
-             values:(GPBFloatArray *)values
-                tag:(uint32_t)tag {
+- (void)writeFloatArray:(int32_t)fieldNumber
+                 values:(GPBFloatArray *)values
+                    tag:(uint32_t)tag {
   if (tag != 0) {
     if (values.count == 0) return;
     __block size_t dataSize = 0;
@@ -524,9 +524,9 @@ static void GPBWriteRawLittleEndian64(GPBOutputBufferState *state,
 //%PDDM-EXPAND WRITE_PACKABLE_DEFNS(UInt64, UInt64, uint64_t, )
 // This block of code is generated, do not edit it directly.
 
-- (void)writeUInt64s:(int32_t)fieldNumber
-              values:(GPBUInt64Array *)values
-                 tag:(uint32_t)tag {
+- (void)writeUInt64Array:(int32_t)fieldNumber
+                  values:(GPBUInt64Array *)values
+                     tag:(uint32_t)tag {
   if (tag != 0) {
     if (values.count == 0) return;
     __block size_t dataSize = 0;
@@ -551,9 +551,9 @@ static void GPBWriteRawLittleEndian64(GPBOutputBufferState *state,
 //%PDDM-EXPAND WRITE_PACKABLE_DEFNS(Int64, Int64, int64_t, )
 // This block of code is generated, do not edit it directly.
 
-- (void)writeInt64s:(int32_t)fieldNumber
-             values:(GPBInt64Array *)values
-                tag:(uint32_t)tag {
+- (void)writeInt64Array:(int32_t)fieldNumber
+                 values:(GPBInt64Array *)values
+                    tag:(uint32_t)tag {
   if (tag != 0) {
     if (values.count == 0) return;
     __block size_t dataSize = 0;
@@ -578,9 +578,9 @@ static void GPBWriteRawLittleEndian64(GPBOutputBufferState *state,
 //%PDDM-EXPAND WRITE_PACKABLE_DEFNS(Int32, Int32, int32_t, )
 // This block of code is generated, do not edit it directly.
 
-- (void)writeInt32s:(int32_t)fieldNumber
-             values:(GPBInt32Array *)values
-                tag:(uint32_t)tag {
+- (void)writeInt32Array:(int32_t)fieldNumber
+                 values:(GPBInt32Array *)values
+                    tag:(uint32_t)tag {
   if (tag != 0) {
     if (values.count == 0) return;
     __block size_t dataSize = 0;
@@ -605,9 +605,9 @@ static void GPBWriteRawLittleEndian64(GPBOutputBufferState *state,
 //%PDDM-EXPAND WRITE_PACKABLE_DEFNS(UInt32, UInt32, uint32_t, )
 // This block of code is generated, do not edit it directly.
 
-- (void)writeUInt32s:(int32_t)fieldNumber
-              values:(GPBUInt32Array *)values
-                 tag:(uint32_t)tag {
+- (void)writeUInt32Array:(int32_t)fieldNumber
+                  values:(GPBUInt32Array *)values
+                     tag:(uint32_t)tag {
   if (tag != 0) {
     if (values.count == 0) return;
     __block size_t dataSize = 0;
@@ -632,9 +632,9 @@ static void GPBWriteRawLittleEndian64(GPBOutputBufferState *state,
 //%PDDM-EXPAND WRITE_PACKABLE_DEFNS(Fixed64, UInt64, uint64_t, )
 // This block of code is generated, do not edit it directly.
 
-- (void)writeFixed64s:(int32_t)fieldNumber
-               values:(GPBUInt64Array *)values
-                  tag:(uint32_t)tag {
+- (void)writeFixed64Array:(int32_t)fieldNumber
+                   values:(GPBUInt64Array *)values
+                      tag:(uint32_t)tag {
   if (tag != 0) {
     if (values.count == 0) return;
     __block size_t dataSize = 0;
@@ -659,9 +659,9 @@ static void GPBWriteRawLittleEndian64(GPBOutputBufferState *state,
 //%PDDM-EXPAND WRITE_PACKABLE_DEFNS(Fixed32, UInt32, uint32_t, )
 // This block of code is generated, do not edit it directly.
 
-- (void)writeFixed32s:(int32_t)fieldNumber
-               values:(GPBUInt32Array *)values
-                  tag:(uint32_t)tag {
+- (void)writeFixed32Array:(int32_t)fieldNumber
+                   values:(GPBUInt32Array *)values
+                      tag:(uint32_t)tag {
   if (tag != 0) {
     if (values.count == 0) return;
     __block size_t dataSize = 0;
@@ -686,9 +686,9 @@ static void GPBWriteRawLittleEndian64(GPBOutputBufferState *state,
 //%PDDM-EXPAND WRITE_PACKABLE_DEFNS(SInt32, Int32, int32_t, )
 // This block of code is generated, do not edit it directly.
 
-- (void)writeSInt32s:(int32_t)fieldNumber
-              values:(GPBInt32Array *)values
-                 tag:(uint32_t)tag {
+- (void)writeSInt32Array:(int32_t)fieldNumber
+                  values:(GPBInt32Array *)values
+                     tag:(uint32_t)tag {
   if (tag != 0) {
     if (values.count == 0) return;
     __block size_t dataSize = 0;
@@ -713,9 +713,9 @@ static void GPBWriteRawLittleEndian64(GPBOutputBufferState *state,
 //%PDDM-EXPAND WRITE_PACKABLE_DEFNS(SInt64, Int64, int64_t, )
 // This block of code is generated, do not edit it directly.
 
-- (void)writeSInt64s:(int32_t)fieldNumber
-              values:(GPBInt64Array *)values
-                 tag:(uint32_t)tag {
+- (void)writeSInt64Array:(int32_t)fieldNumber
+                  values:(GPBInt64Array *)values
+                     tag:(uint32_t)tag {
   if (tag != 0) {
     if (values.count == 0) return;
     __block size_t dataSize = 0;
@@ -740,9 +740,9 @@ static void GPBWriteRawLittleEndian64(GPBOutputBufferState *state,
 //%PDDM-EXPAND WRITE_PACKABLE_DEFNS(SFixed64, Int64, int64_t, )
 // This block of code is generated, do not edit it directly.
 
-- (void)writeSFixed64s:(int32_t)fieldNumber
-                values:(GPBInt64Array *)values
-                   tag:(uint32_t)tag {
+- (void)writeSFixed64Array:(int32_t)fieldNumber
+                    values:(GPBInt64Array *)values
+                       tag:(uint32_t)tag {
   if (tag != 0) {
     if (values.count == 0) return;
     __block size_t dataSize = 0;
@@ -767,9 +767,9 @@ static void GPBWriteRawLittleEndian64(GPBOutputBufferState *state,
 //%PDDM-EXPAND WRITE_PACKABLE_DEFNS(SFixed32, Int32, int32_t, )
 // This block of code is generated, do not edit it directly.
 
-- (void)writeSFixed32s:(int32_t)fieldNumber
-                values:(GPBInt32Array *)values
-                   tag:(uint32_t)tag {
+- (void)writeSFixed32Array:(int32_t)fieldNumber
+                    values:(GPBInt32Array *)values
+                       tag:(uint32_t)tag {
   if (tag != 0) {
     if (values.count == 0) return;
     __block size_t dataSize = 0;
@@ -794,9 +794,9 @@ static void GPBWriteRawLittleEndian64(GPBOutputBufferState *state,
 //%PDDM-EXPAND WRITE_PACKABLE_DEFNS(Bool, Bool, BOOL, )
 // This block of code is generated, do not edit it directly.
 
-- (void)writeBools:(int32_t)fieldNumber
-            values:(GPBBoolArray *)values
-               tag:(uint32_t)tag {
+- (void)writeBoolArray:(int32_t)fieldNumber
+                values:(GPBBoolArray *)values
+                   tag:(uint32_t)tag {
   if (tag != 0) {
     if (values.count == 0) return;
     __block size_t dataSize = 0;
@@ -821,9 +821,9 @@ static void GPBWriteRawLittleEndian64(GPBOutputBufferState *state,
 //%PDDM-EXPAND WRITE_PACKABLE_DEFNS(Enum, Enum, int32_t, Raw)
 // This block of code is generated, do not edit it directly.
 
-- (void)writeEnums:(int32_t)fieldNumber
-            values:(GPBEnumArray *)values
-               tag:(uint32_t)tag {
+- (void)writeEnumArray:(int32_t)fieldNumber
+                values:(GPBEnumArray *)values
+                   tag:(uint32_t)tag {
   if (tag != 0) {
     if (values.count == 0) return;
     __block size_t dataSize = 0;
@@ -848,7 +848,7 @@ static void GPBWriteRawLittleEndian64(GPBOutputBufferState *state,
 //%PDDM-EXPAND WRITE_UNPACKABLE_DEFNS(String, NSString)
 // This block of code is generated, do not edit it directly.
 
-- (void)writeStrings:(int32_t)fieldNumber values:(NSArray *)values {
+- (void)writeStringArray:(int32_t)fieldNumber values:(NSArray *)values {
   for (NSString *value in values) {
     [self writeString:fieldNumber value:value];
   }
@@ -857,25 +857,25 @@ static void GPBWriteRawLittleEndian64(GPBOutputBufferState *state,
 //%PDDM-EXPAND WRITE_UNPACKABLE_DEFNS(Message, GPBMessage)
 // This block of code is generated, do not edit it directly.
 
-- (void)writeMessages:(int32_t)fieldNumber values:(NSArray *)values {
+- (void)writeMessageArray:(int32_t)fieldNumber values:(NSArray *)values {
   for (GPBMessage *value in values) {
     [self writeMessage:fieldNumber value:value];
   }
 }
 
-//%PDDM-EXPAND WRITE_UNPACKABLE_DEFNS(Data, NSData)
+//%PDDM-EXPAND WRITE_UNPACKABLE_DEFNS(Bytes, NSData)
 // This block of code is generated, do not edit it directly.
 
-- (void)writeDatas:(int32_t)fieldNumber values:(NSArray *)values {
+- (void)writeBytesArray:(int32_t)fieldNumber values:(NSArray *)values {
   for (NSData *value in values) {
-    [self writeData:fieldNumber value:value];
+    [self writeBytes:fieldNumber value:value];
   }
 }
 
 //%PDDM-EXPAND WRITE_UNPACKABLE_DEFNS(Group, GPBMessage)
 // This block of code is generated, do not edit it directly.
 
-- (void)writeGroups:(int32_t)fieldNumber values:(NSArray *)values {
+- (void)writeGroupArray:(int32_t)fieldNumber values:(NSArray *)values {
   for (GPBMessage *value in values) {
     [self writeGroup:fieldNumber value:value];
   }
@@ -884,7 +884,7 @@ static void GPBWriteRawLittleEndian64(GPBOutputBufferState *state,
 //%PDDM-EXPAND WRITE_UNPACKABLE_DEFNS(UnknownGroup, GPBUnknownFieldSet)
 // This block of code is generated, do not edit it directly.
 
-- (void)writeUnknownGroups:(int32_t)fieldNumber values:(NSArray *)values {
+- (void)writeUnknownGroupArray:(int32_t)fieldNumber values:(NSArray *)values {
   for (GPBUnknownFieldSet *value in values) {
     [self writeUnknownGroup:fieldNumber value:value];
   }
@@ -906,7 +906,7 @@ static void GPBWriteRawLittleEndian64(GPBOutputBufferState *state,
   GPBWriteTagWithFormat(&state_, GPBWireFormatMessageSetItem,
                         GPBWireFormatStartGroup);
   GPBWriteUInt32(&state_, GPBWireFormatMessageSetTypeId, fieldNumber);
-  [self writeData:GPBWireFormatMessageSetMessage value:value];
+  [self writeBytes:GPBWireFormatMessageSetMessage value:value];
   GPBWriteTagWithFormat(&state_, GPBWireFormatMessageSetItem,
                         GPBWireFormatEndGroup);
 }
@@ -1062,7 +1062,7 @@ size_t GPBComputeMessageSizeNoTag(GPBMessage *value) {
   return GPBComputeRawVarint32SizeForInteger(size) + size;
 }
 
-size_t GPBComputeDataSizeNoTag(NSData *value) {
+size_t GPBComputeBytesSizeNoTag(NSData *value) {
   NSUInteger valueLength = [value length];
   return GPBComputeRawVarint32SizeForInteger(valueLength) + valueLength;
 }
@@ -1143,8 +1143,8 @@ size_t GPBComputeMessageSize(int32_t fieldNumber, GPBMessage *value) {
   return GPBComputeTagSize(fieldNumber) + GPBComputeMessageSizeNoTag(value);
 }
 
-size_t GPBComputeDataSize(int32_t fieldNumber, NSData *value) {
-  return GPBComputeTagSize(fieldNumber) + GPBComputeDataSizeNoTag(value);
+size_t GPBComputeBytesSize(int32_t fieldNumber, NSData *value) {
+  return GPBComputeTagSize(fieldNumber) + GPBComputeBytesSizeNoTag(value);
 }
 
 size_t GPBComputeUInt32Size(int32_t fieldNumber, uint32_t value) {
@@ -1183,7 +1183,7 @@ size_t GPBComputeRawMessageSetExtensionSize(int32_t fieldNumber,
                                             NSData *value) {
   return GPBComputeTagSize(GPBWireFormatMessageSetItem) * 2 +
          GPBComputeUInt32Size(GPBWireFormatMessageSetTypeId, fieldNumber) +
-         GPBComputeDataSize(GPBWireFormatMessageSetMessage, value);
+         GPBComputeBytesSize(GPBWireFormatMessageSetMessage, value);
 }
 
 size_t GPBComputeTagSize(int32_t fieldNumber) {
@@ -1191,9 +1191,9 @@ size_t GPBComputeTagSize(int32_t fieldNumber) {
       GPBWireFormatMakeTag(fieldNumber, GPBWireFormatVarint));
 }
 
-size_t GPBComputeWireFormatTagSize(int field_number, GPBType type) {
+size_t GPBComputeWireFormatTagSize(int field_number, GPBDataType dataType) {
   size_t result = GPBComputeTagSize(field_number);
-  if (type == GPBTypeGroup) {
+  if (dataType == GPBDataTypeGroup) {
     // Groups have both a start and an end tag.
     return result * 2;
   } else {

+ 8 - 6
objectivec/GPBDescriptor.h

@@ -30,7 +30,7 @@
 
 #import <Foundation/Foundation.h>
 
-#import "GPBTypes.h"
+#import "GPBRuntimeTypes.h"
 
 @class GPBEnumDescriptor;
 @class GPBFieldDescriptor;
@@ -89,14 +89,14 @@ typedef NS_ENUM(NSInteger, GPBFieldType) {
 
 @property(nonatomic, readonly, copy) NSString *name;
 @property(nonatomic, readonly) uint32_t number;
-@property(nonatomic, readonly) GPBType type;
+@property(nonatomic, readonly) GPBDataType dataType;
 @property(nonatomic, readonly) BOOL hasDefaultValue;
-@property(nonatomic, readonly) GPBValue defaultValue;
+@property(nonatomic, readonly) GPBGenericValue defaultValue;
 @property(nonatomic, readonly, getter=isRequired) BOOL required;
 @property(nonatomic, readonly, getter=isOptional) BOOL optional;
 @property(nonatomic, readonly) GPBFieldType fieldType;
 // If it is a map, the value type is in -type.
-@property(nonatomic, readonly) GPBType mapKeyType;
+@property(nonatomic, readonly) GPBDataType mapKeyDataType;
 @property(nonatomic, readonly, getter=isPackable) BOOL packable;
 
 @property(nonatomic, readonly, assign) GPBOneofDescriptor *containingOneof;
@@ -129,12 +129,14 @@ typedef NS_ENUM(NSInteger, GPBFieldType) {
 
 @end
 
-@interface GPBExtensionDescriptor : NSObject
+@interface GPBExtensionDescriptor : NSObject<NSCopying>
 @property(nonatomic, readonly) uint32_t fieldNumber;
-@property(nonatomic, readonly) GPBType type;
+@property(nonatomic, readonly) Class containingMessageClass;
+@property(nonatomic, readonly) GPBDataType dataType;
 @property(nonatomic, readonly, getter=isRepeated) BOOL repeated;
 @property(nonatomic, readonly, getter=isPackable) BOOL packable;
 @property(nonatomic, readonly, assign) Class msgClass;
 @property(nonatomic, readonly) NSString *singletonName;
 @property(nonatomic, readonly, strong) GPBEnumDescriptor *enumDescriptor;
+@property(nonatomic, readonly) id defaultValue;
 @end

+ 220 - 87
objectivec/GPBDescriptor.m

@@ -369,16 +369,26 @@ uint32_t GPBFieldTag(GPBFieldDescriptor *self) {
   GPBWireFormat format;
   if ((description->flags & GPBFieldMapKeyMask) != 0) {
     // Maps are repeated messages on the wire.
-    format = GPBWireFormatForType(GPBTypeMessage, NO);
+    format = GPBWireFormatForType(GPBDataTypeMessage, NO);
   } else {
-    format = GPBWireFormatForType(description->type,
-                                  description->flags & GPBFieldPacked);
+    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 {
-  GPBValue defaultValue_;
+  GPBGenericValue defaultValue_;
   GPBFieldOptions *fieldOptions_;
 
   // Message ivars
@@ -416,12 +426,66 @@ uint32_t GPBFieldTag(GPBFieldDescriptor *self) {
     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) {
-      // FieldOptions stored as a length prefixed c-escaped string in descriptor
-      // records.
       uint8_t *optionsBytes = (uint8_t *)description->fieldOptions;
       uint32_t optionsLength = *((uint32_t *)optionsBytes);
-      // The length is stored in network byte order.
       optionsLength = ntohl(optionsLength);
       if (optionsLength > 0) {
         optionsBytes += sizeof(optionsLength);
@@ -434,69 +498,20 @@ uint32_t GPBFieldTag(GPBFieldDescriptor *self) {
                                                   error:NULL] retain];
       }
     }
-
-    GPBType type = description->type;
-    BOOL isMessage = GPBTypeIsMessage(type);
-    if (isMessage) {
-      // No has* for repeated/map or something in a oneof (we can't check
-      // containingOneof_ because it isn't set until after initialization).
-      if ((description->hasIndex >= 0) &&
-          (description->hasIndex != GPBNoHasBit)) {
-        hasSel_ = SelFromStrings("has", description->name, NULL, NO);
-        setHasSel_ = SelFromStrings("setHas", description->name, NULL, YES);
-      }
-      const char *className = description->typeSpecific.className;
-      msgClass_ = objc_getClass(className);
-      NSAssert1(msgClass_, @"Class %s not defined", className);
-      // The defaultValue_ is fetched directly in -defaultValue to avoid
-      // initialization order issues.
-    } else {
-      if (!GPBFieldIsMapOrArray(self)) {
-        defaultValue_ = description->defaultValue;
-        if (type == GPBTypeData) {
-          // Data stored as a length prefixed c-string in descriptor records.
-          const uint8_t *bytes = (const uint8_t *)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];
-          }
-        }
-        // No has* methods for proto3 or if our hasIndex is < 0 because it
-        // means the field is in a oneof (we can't check containingOneof_
-        // because it isn't set until after initialization).
-        if ((syntax != GPBFileSyntaxProto3) && (description->hasIndex >= 0) &&
-            (description->hasIndex != GPBNoHasBit)) {
-          hasSel_ = SelFromStrings("has", description->name, NULL, NO);
-          setHasSel_ = SelFromStrings("setHas", description->name, NULL, YES);
-        }
-      }
-      if (GPBTypeIsEnum(type)) {
-        if (description_->flags & GPBFieldHasEnumDescriptor) {
-          enumHandling_.enumDescriptor_ =
-              description->typeSpecific.enumDescFunc();
-        } else {
-          enumHandling_.enumVerifier_ = description->typeSpecific.enumVerifier;
-        }
-      }
-    }
   }
   return self;
 }
 
 - (void)dealloc {
-  if (description_->type == GPBTypeData &&
+  if (description_->dataType == GPBDataTypeBytes &&
       !(description_->flags & GPBFieldRepeated)) {
     [defaultValue_.valueData release];
   }
   [super dealloc];
 }
 
-- (GPBType)type {
-  return description_->type;
+- (GPBDataType)dataType {
+  return description_->dataType;
 }
 
 - (BOOL)hasDefaultValue {
@@ -530,36 +545,36 @@ uint32_t GPBFieldTag(GPBFieldDescriptor *self) {
   }
 }
 
-- (GPBType)mapKeyType {
+- (GPBDataType)mapKeyDataType {
   switch (description_->flags & GPBFieldMapKeyMask) {
     case GPBFieldMapKeyInt32:
-      return GPBTypeInt32;
+      return GPBDataTypeInt32;
     case GPBFieldMapKeyInt64:
-      return GPBTypeInt64;
+      return GPBDataTypeInt64;
     case GPBFieldMapKeyUInt32:
-      return GPBTypeUInt32;
+      return GPBDataTypeUInt32;
     case GPBFieldMapKeyUInt64:
-      return GPBTypeUInt64;
+      return GPBDataTypeUInt64;
     case GPBFieldMapKeySInt32:
-      return GPBTypeSInt32;
+      return GPBDataTypeSInt32;
     case GPBFieldMapKeySInt64:
-      return GPBTypeSInt64;
+      return GPBDataTypeSInt64;
     case GPBFieldMapKeyFixed32:
-      return GPBTypeFixed32;
+      return GPBDataTypeFixed32;
     case GPBFieldMapKeyFixed64:
-      return GPBTypeFixed64;
+      return GPBDataTypeFixed64;
     case GPBFieldMapKeySFixed32:
-      return GPBTypeSFixed32;
+      return GPBDataTypeSFixed32;
     case GPBFieldMapKeySFixed64:
-      return GPBTypeSFixed64;
+      return GPBDataTypeSFixed64;
     case GPBFieldMapKeyBool:
-      return GPBTypeBool;
+      return GPBDataTypeBool;
     case GPBFieldMapKeyString:
-      return GPBTypeString;
+      return GPBDataTypeString;
 
     default:
       NSAssert(0, @"Not a map type");
-      return GPBTypeInt32;  // For lack of anything better.
+      return GPBDataTypeInt32;  // For lack of anything better.
   }
 }
 
@@ -568,8 +583,8 @@ uint32_t GPBFieldTag(GPBFieldDescriptor *self) {
 }
 
 - (BOOL)isValidEnumValue:(int32_t)value {
-  NSAssert(description_->type == GPBTypeEnum,
-           @"Field Must be of type GPBTypeEnum");
+  NSAssert(description_->dataType == GPBDataTypeEnum,
+           @"Field Must be of type GPBDataTypeEnum");
   if (description_->flags & GPBFieldHasEnumDescriptor) {
     return enumHandling_.enumDescriptor_.enumVerifier(value);
   } else {
@@ -585,18 +600,18 @@ uint32_t GPBFieldTag(GPBFieldDescriptor *self) {
   }
 }
 
-- (GPBValue)defaultValue {
+- (GPBGenericValue)defaultValue {
   // Depends on the fact that defaultValue_ is initialized either to "0/nil" or
   // to an actual defaultValue in our initializer.
-  GPBValue value = defaultValue_;
+  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.
-    GPBType type = description_->type;
-    if (type == GPBTypeData && value.valueData == nil) {
+    GPBDataType type = description_->dataType;
+    if (type == GPBDataTypeBytes && value.valueData == nil) {
       value.valueData = GPBEmptyNSData();
-    } else if (type == GPBTypeString && value.valueString == nil) {
+    } else if (type == GPBDataTypeString && value.valueString == nil) {
       value.valueString = @"";
     }
   }
@@ -635,7 +650,7 @@ uint32_t GPBFieldTag(GPBFieldDescriptor *self) {
   }
 
   // Groups vs. other fields.
-  if (description_->type == GPBTypeGroup) {
+  if (description_->dataType == GPBDataTypeGroup) {
     // Just capitalize the first letter.
     unichar firstChar = [name characterAtIndex:0];
     if (firstChar >= 'a' && firstChar <= 'z') {
@@ -811,16 +826,70 @@ uint32_t GPBFieldTag(GPBFieldDescriptor *self) {
 
 @end
 
-@implementation GPBExtensionDescriptor
+@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);
 }
@@ -833,12 +902,24 @@ uint32_t GPBFieldTag(GPBFieldDescriptor *self) {
   return description_->fieldNumber;
 }
 
-- (GPBType)type {
-  return description_->type;
+- (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 (description_->options & GPBExtensionRepeated) != 0;
+  return GPBExtensionIsRepeated(description_);
 }
 
 - (BOOL)isMap {
@@ -846,7 +927,7 @@ uint32_t GPBFieldTag(GPBFieldDescriptor *self) {
 }
 
 - (BOOL)isPackable {
-  return (description_->options & GPBExtensionPacked) != 0;
+  return GPBExtensionIsPacked(description_);
 }
 
 - (Class)msgClass {
@@ -854,11 +935,63 @@ uint32_t GPBFieldTag(GPBFieldDescriptor *self) {
 }
 
 - (GPBEnumDescriptor *)enumDescriptor {
-  if (GPBTypeIsEnum(description_->type)) {
+  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

+ 38 - 12
objectivec/GPBDescriptor_PackagePrivate.h

@@ -33,6 +33,7 @@
 // subject to change at any time without notice.
 
 #import "GPBDescriptor.h"
+#import "GPBWireFormat.h"
 
 // Describes attributes of the field.
 typedef NS_OPTIONS(uint32_t, GPBFieldFlags) {
@@ -66,8 +67,6 @@ typedef NS_OPTIONS(uint32_t, GPBFieldFlags) {
   // set, the name can be derived from the ObjC name.
   GPBFieldTextFormatNameCustom = 1 << 16,
   // Indicates the field has an enum descriptor.
-  // TODO(thomasvl): Output the CPP check to use descFunc or validator based
-  // on final compile.  This will then get added based on that.
   GPBFieldHasEnumDescriptor = 1 << 17,
 };
 
@@ -84,21 +83,21 @@ typedef struct GPBMessageFieldDescription {
   int32_t hasIndex;
   // Field flags. Use accessor functions below.
   GPBFieldFlags flags;
-  // Type of the ivar.
-  GPBType type;
+  // Data type of the ivar.
+  GPBDataType dataType;
   // Offset of the variable into it's structure struct.
   size_t offset;
   // FieldOptions protobuf, serialized as string.
   const char *fieldOptions;
 
-  GPBValue defaultValue;  // Default value for the ivar.
+  GPBGenericValue defaultValue;  // Default value for the ivar.
   union {
     const char *className;  // Name for message class.
     // For enums only: If EnumDescriptors are compiled in, it will be that,
     // otherwise it will be the verifier.
     GPBEnumDescriptorFunc enumDescFunc;
     GPBEnumValidationFunc enumVerifier;
-  } typeSpecific;
+  } dataTypeSpecific;
 } GPBMessageFieldDescription;
 
 // Describes a oneof.
@@ -133,10 +132,10 @@ typedef NS_OPTIONS(uint32_t, GPBExtensionOptions) {
 // An extension
 typedef struct GPBExtensionDescription {
   const char *singletonName;
-  GPBType type;
+  GPBDataType dataType;
   const char *extendedClass;
   int32_t fieldNumber;
-  GPBValue defaultValue;
+  GPBGenericValue defaultValue;
   const char *messageOrGroupClassName;
   GPBExtensionOptions options;
   GPBEnumDescriptorFunc enumDescriptorFunc;
@@ -217,7 +216,7 @@ typedef struct GPBExtensionDescription {
 
   SEL getSel_;
   SEL setSel_;
-  SEL hasSel_;
+  SEL hasOrCountSel_;  // *Count for map<>/repeated fields, has* otherwise.
   SEL setHasSel_;
 }
 
@@ -254,10 +253,18 @@ typedef struct GPBExtensionDescription {
  @package
   GPBExtensionDescription *description_;
 }
+@property(nonatomic, readonly) GPBWireFormat wireType;
+
+// For repeated extensions, alternateWireType is the wireType with the opposite
+// value for the packable property.  i.e. - if the extension was marked packed
+// it would be the wire type for unpacked; if the extension was marked unpacked,
+// it would be the wire type for packed.
+@property(nonatomic, readonly) GPBWireFormat alternateWireType;
 
 // description has to be long lived, it is held as a raw pointer.
 - (instancetype)initWithExtensionDescription:
-        (GPBExtensionDescription *)description;
+    (GPBExtensionDescription *)description;
+- (NSComparisonResult)compareByFieldNumber:(GPBExtensionDescriptor *)other;
 @end
 
 CF_EXTERN_C_BEGIN
@@ -267,8 +274,8 @@ GPB_INLINE BOOL GPBFieldIsMapOrArray(GPBFieldDescriptor *field) {
           (GPBFieldRepeated | GPBFieldMapKeyMask)) != 0;
 }
 
-GPB_INLINE GPBType GPBGetFieldType(GPBFieldDescriptor *field) {
-  return field->description_->type;
+GPB_INLINE GPBDataType GPBGetFieldDataType(GPBFieldDescriptor *field) {
+  return field->description_->dataType;
 }
 
 GPB_INLINE int32_t GPBFieldHasIndex(GPBFieldDescriptor *field) {
@@ -281,6 +288,12 @@ GPB_INLINE uint32_t GPBFieldNumber(GPBFieldDescriptor *field) {
 
 uint32_t GPBFieldTag(GPBFieldDescriptor *self);
 
+// For repeated fields, alternateWireType is the wireType with the opposite
+// value for the packable property.  i.e. - if the field was marked packed it
+// would be the wire type for unpacked; if the field was marked unpacked, it
+// would be the wire type for packed.
+uint32_t GPBFieldAlternateTag(GPBFieldDescriptor *self);
+
 GPB_INLINE BOOL GPBPreserveUnknownFields(GPBFileSyntax syntax) {
   return syntax != GPBFileSyntaxProto3;
 }
@@ -289,4 +302,17 @@ GPB_INLINE BOOL GPBHasPreservingUnknownEnumSemantics(GPBFileSyntax syntax) {
   return syntax == GPBFileSyntaxProto3;
 }
 
+GPB_INLINE BOOL GPBExtensionIsRepeated(GPBExtensionDescription *description) {
+  return (description->options & GPBExtensionRepeated) != 0;
+}
+
+GPB_INLINE BOOL GPBExtensionIsPacked(GPBExtensionDescription *description) {
+  return (description->options & GPBExtensionPacked) != 0;
+}
+
+GPB_INLINE BOOL GPBExtensionIsWireFormat(GPBExtensionDescription *description) {
+  return (description->options & GPBExtensionSetWireFormat) != 0;
+}
+
+
 CF_EXTERN_C_END

+ 1 - 1
objectivec/GPBDictionary.h

@@ -30,7 +30,7 @@
 
 #import <Foundation/Foundation.h>
 
-#import "GPBTypes.h"
+#import "GPBRuntimeTypes.h"
 
 // These classes are used for map fields of basic data types. They are used because
 // they perform better than boxing into NSNumbers in NSDictionaries.

Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 255 - 248
objectivec/GPBDictionary.m


+ 16 - 15
objectivec/GPBDictionary_PackagePrivate.h

@@ -41,7 +41,8 @@
 - (size_t)computeSerializedSizeAsField:(GPBFieldDescriptor *)field;
 - (void)writeToCodedOutputStream:(GPBCodedOutputStream *)outputStream
                          asField:(GPBFieldDescriptor *)field;
-- (void)setGPBValue:(GPBValue *)value forGPBValueKey:(GPBValue *)key;
+- (void)setGPBGenericValue:(GPBGenericValue *)value
+     forGPBGenericValueKey:(GPBGenericValue *)key;
 - (void)enumerateForTextFormat:(void (^)(id keyObj, id valueObj))block;
 @end
 
@@ -75,8 +76,8 @@
 //%
 //%PDDM-DEFINE EXTRA_DICTIONARY_PRIVATE_INTERFACES_Enum()
 //%- (NSData *)serializedDataForUnknownValue:(int32_t)value
-//%                                   forKey:(GPBValue *)key
-//%                                  keyType:(GPBType)keyType;
+//%                                   forKey:(GPBGenericValue *)key
+//%                              keyDataType:(GPBDataType)keyDataType;
 //%
 
 //%PDDM-EXPAND DICTIONARY_PRIV_INTERFACES_FOR_POD_KEY(UInt32)
@@ -129,8 +130,8 @@
   GPB_UNSAFE_UNRETAINED GPBMessage *_autocreator;
 }
 - (NSData *)serializedDataForUnknownValue:(int32_t)value
-                                   forKey:(GPBValue *)key
-                                  keyType:(GPBType)keyType;
+                                   forKey:(GPBGenericValue *)key
+                              keyDataType:(GPBDataType)keyDataType;
 @end
 
 @interface GPBUInt32ObjectDictionary () <GPBDictionaryInternalsProtocol> {
@@ -192,8 +193,8 @@
   GPB_UNSAFE_UNRETAINED GPBMessage *_autocreator;
 }
 - (NSData *)serializedDataForUnknownValue:(int32_t)value
-                                   forKey:(GPBValue *)key
-                                  keyType:(GPBType)keyType;
+                                   forKey:(GPBGenericValue *)key
+                              keyDataType:(GPBDataType)keyDataType;
 @end
 
 @interface GPBInt32ObjectDictionary () <GPBDictionaryInternalsProtocol> {
@@ -255,8 +256,8 @@
   GPB_UNSAFE_UNRETAINED GPBMessage *_autocreator;
 }
 - (NSData *)serializedDataForUnknownValue:(int32_t)value
-                                   forKey:(GPBValue *)key
-                                  keyType:(GPBType)keyType;
+                                   forKey:(GPBGenericValue *)key
+                              keyDataType:(GPBDataType)keyDataType;
 @end
 
 @interface GPBUInt64ObjectDictionary () <GPBDictionaryInternalsProtocol> {
@@ -318,8 +319,8 @@
   GPB_UNSAFE_UNRETAINED GPBMessage *_autocreator;
 }
 - (NSData *)serializedDataForUnknownValue:(int32_t)value
-                                   forKey:(GPBValue *)key
-                                  keyType:(GPBType)keyType;
+                                   forKey:(GPBGenericValue *)key
+                              keyDataType:(GPBDataType)keyDataType;
 @end
 
 @interface GPBInt64ObjectDictionary () <GPBDictionaryInternalsProtocol> {
@@ -381,8 +382,8 @@
   GPB_UNSAFE_UNRETAINED GPBMessage *_autocreator;
 }
 - (NSData *)serializedDataForUnknownValue:(int32_t)value
-                                   forKey:(GPBValue *)key
-                                  keyType:(GPBType)keyType;
+                                   forKey:(GPBGenericValue *)key
+                              keyDataType:(GPBDataType)keyDataType;
 @end
 
 @interface GPBBoolObjectDictionary () <GPBDictionaryInternalsProtocol> {
@@ -444,8 +445,8 @@
   GPB_UNSAFE_UNRETAINED GPBMessage *_autocreator;
 }
 - (NSData *)serializedDataForUnknownValue:(int32_t)value
-                                   forKey:(GPBValue *)key
-                                  keyType:(GPBType)keyType;
+                                   forKey:(GPBGenericValue *)key
+                              keyDataType:(GPBDataType)keyDataType;
 @end
 
 //%PDDM-EXPAND-END (6 expansions)

+ 0 - 525
objectivec/GPBExtensionField.m

@@ -1,525 +0,0 @@
-// 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 "GPBExtensionField_PackagePrivate.h"
-
-#import <objc/runtime.h>
-
-#import "GPBCodedInputStream_PackagePrivate.h"
-#import "GPBCodedOutputStream.h"
-#import "GPBDescriptor_PackagePrivate.h"
-#import "GPBMessage_PackagePrivate.h"
-#import "GPBUtilities_PackagePrivate.h"
-
-GPB_INLINE size_t TypeSize(GPBType type) {
-  switch (type) {
-    case GPBTypeBool:
-      return 1;
-    case GPBTypeFixed32:
-    case GPBTypeSFixed32:
-    case GPBTypeFloat:
-      return 4;
-    case GPBTypeFixed64:
-    case GPBTypeSFixed64:
-    case GPBTypeDouble:
-      return 8;
-    default:
-      return 0;
-  }
-}
-
-GPB_INLINE BOOL ExtensionIsRepeated(GPBExtensionDescription *description) {
-  return (description->options & GPBExtensionRepeated) != 0;
-}
-
-GPB_INLINE BOOL ExtensionIsPacked(GPBExtensionDescription *description) {
-  return (description->options & GPBExtensionPacked) != 0;
-}
-
-GPB_INLINE BOOL ExtensionIsWireFormat(GPBExtensionDescription *description) {
-  return (description->options & GPBExtensionSetWireFormat) != 0;
-}
-
-static size_t ComputePBSerializedSizeNoTagOfObject(GPBType type, id object) {
-#define FIELD_CASE(TYPE, ACCESSOR) \
-  case GPBType##TYPE:              \
-    return GPBCompute##TYPE##SizeNoTag([(NSNumber *)object ACCESSOR]);
-#define FIELD_CASE2(TYPE) \
-  case GPBType##TYPE:     \
-    return GPBCompute##TYPE##SizeNoTag(object);
-  switch (type) {
-    FIELD_CASE(Bool, boolValue)
-    FIELD_CASE(Float, floatValue)
-    FIELD_CASE(Double, doubleValue)
-    FIELD_CASE(Int32, intValue)
-    FIELD_CASE(SFixed32, intValue)
-    FIELD_CASE(SInt32, intValue)
-    FIELD_CASE(Enum, intValue)
-    FIELD_CASE(Int64, longLongValue)
-    FIELD_CASE(SInt64, longLongValue)
-    FIELD_CASE(SFixed64, longLongValue)
-    FIELD_CASE(UInt32, unsignedIntValue)
-    FIELD_CASE(Fixed32, unsignedIntValue)
-    FIELD_CASE(UInt64, unsignedLongLongValue)
-    FIELD_CASE(Fixed64, unsignedLongLongValue)
-    FIELD_CASE2(Data)
-    FIELD_CASE2(String)
-    FIELD_CASE2(Message)
-    FIELD_CASE2(Group)
-  }
-#undef FIELD_CASE
-#undef FIELD_CASE2
-}
-
-static size_t ComputeSerializedSizeIncludingTagOfObject(
-    GPBExtensionDescription *description, id object) {
-#define FIELD_CASE(TYPE, ACCESSOR)                          \
-  case GPBType##TYPE:                                       \
-    return GPBCompute##TYPE##Size(description->fieldNumber, \
-                                  [(NSNumber *)object ACCESSOR]);
-#define FIELD_CASE2(TYPE) \
-  case GPBType##TYPE:     \
-    return GPBCompute##TYPE##Size(description->fieldNumber, object);
-  switch (description->type) {
-    FIELD_CASE(Bool, boolValue)
-    FIELD_CASE(Float, floatValue)
-    FIELD_CASE(Double, doubleValue)
-    FIELD_CASE(Int32, intValue)
-    FIELD_CASE(SFixed32, intValue)
-    FIELD_CASE(SInt32, intValue)
-    FIELD_CASE(Enum, intValue)
-    FIELD_CASE(Int64, longLongValue)
-    FIELD_CASE(SInt64, longLongValue)
-    FIELD_CASE(SFixed64, longLongValue)
-    FIELD_CASE(UInt32, unsignedIntValue)
-    FIELD_CASE(Fixed32, unsignedIntValue)
-    FIELD_CASE(UInt64, unsignedLongLongValue)
-    FIELD_CASE(Fixed64, unsignedLongLongValue)
-    FIELD_CASE2(Data)
-    FIELD_CASE2(String)
-    FIELD_CASE2(Group)
-    case GPBTypeMessage:
-      if (ExtensionIsWireFormat(description)) {
-        return GPBComputeMessageSetExtensionSize(description->fieldNumber,
-                                                 object);
-      } else {
-        return GPBComputeMessageSize(description->fieldNumber, object);
-      }
-  }
-#undef FIELD_CASE
-#undef FIELD_CASE2
-}
-
-static size_t ComputeSerializedSizeIncludingTagOfArray(
-    GPBExtensionDescription *description, NSArray *values) {
-  if (ExtensionIsPacked(description)) {
-    size_t size = 0;
-    size_t typeSize = TypeSize(description->type);
-    if (typeSize != 0) {
-      size = values.count * typeSize;
-    } else {
-      for (id value in values) {
-        size += ComputePBSerializedSizeNoTagOfObject(description->type, value);
-      }
-    }
-    return size + GPBComputeTagSize(description->fieldNumber) +
-           GPBComputeRawVarint32SizeForInteger(size);
-  } else {
-    size_t size = 0;
-    for (id value in values) {
-      size += ComputeSerializedSizeIncludingTagOfObject(description, value);
-    }
-    return size;
-  }
-}
-
-static void WriteObjectIncludingTagToCodedOutputStream(
-    id object, GPBExtensionDescription *description,
-    GPBCodedOutputStream *output) {
-#define FIELD_CASE(TYPE, ACCESSOR)                      \
-  case GPBType##TYPE:                                   \
-    [output write##TYPE:description->fieldNumber        \
-                  value:[(NSNumber *)object ACCESSOR]]; \
-    return;
-#define FIELD_CASE2(TYPE)                                       \
-  case GPBType##TYPE:                                           \
-    [output write##TYPE:description->fieldNumber value:object]; \
-    return;
-  switch (description->type) {
-    FIELD_CASE(Bool, boolValue)
-    FIELD_CASE(Float, floatValue)
-    FIELD_CASE(Double, doubleValue)
-    FIELD_CASE(Int32, intValue)
-    FIELD_CASE(SFixed32, intValue)
-    FIELD_CASE(SInt32, intValue)
-    FIELD_CASE(Enum, intValue)
-    FIELD_CASE(Int64, longLongValue)
-    FIELD_CASE(SInt64, longLongValue)
-    FIELD_CASE(SFixed64, longLongValue)
-    FIELD_CASE(UInt32, unsignedIntValue)
-    FIELD_CASE(Fixed32, unsignedIntValue)
-    FIELD_CASE(UInt64, unsignedLongLongValue)
-    FIELD_CASE(Fixed64, unsignedLongLongValue)
-    FIELD_CASE2(Data)
-    FIELD_CASE2(String)
-    FIELD_CASE2(Group)
-    case GPBTypeMessage:
-      if (ExtensionIsWireFormat(description)) {
-        [output writeMessageSetExtension:description->fieldNumber value:object];
-      } else {
-        [output writeMessage:description->fieldNumber value:object];
-      }
-      return;
-  }
-#undef FIELD_CASE
-#undef FIELD_CASE2
-}
-
-static void WriteObjectNoTagToCodedOutputStream(
-    id object, GPBExtensionDescription *description,
-    GPBCodedOutputStream *output) {
-#define FIELD_CASE(TYPE, ACCESSOR)                             \
-  case GPBType##TYPE:                                          \
-    [output write##TYPE##NoTag:[(NSNumber *)object ACCESSOR]]; \
-    return;
-#define FIELD_CASE2(TYPE)               \
-  case GPBType##TYPE:                   \
-    [output write##TYPE##NoTag:object]; \
-    return;
-  switch (description->type) {
-    FIELD_CASE(Bool, boolValue)
-    FIELD_CASE(Float, floatValue)
-    FIELD_CASE(Double, doubleValue)
-    FIELD_CASE(Int32, intValue)
-    FIELD_CASE(SFixed32, intValue)
-    FIELD_CASE(SInt32, intValue)
-    FIELD_CASE(Enum, intValue)
-    FIELD_CASE(Int64, longLongValue)
-    FIELD_CASE(SInt64, longLongValue)
-    FIELD_CASE(SFixed64, longLongValue)
-    FIELD_CASE(UInt32, unsignedIntValue)
-    FIELD_CASE(Fixed32, unsignedIntValue)
-    FIELD_CASE(UInt64, unsignedLongLongValue)
-    FIELD_CASE(Fixed64, unsignedLongLongValue)
-    FIELD_CASE2(Data)
-    FIELD_CASE2(String)
-    FIELD_CASE2(Message)
-    case GPBTypeGroup:
-      [output writeGroupNoTag:description->fieldNumber value:object];
-      return;
-  }
-#undef FIELD_CASE
-#undef FIELD_CASE2
-}
-
-static void WriteArrayIncludingTagsToCodedOutputStream(
-    NSArray *values, GPBExtensionDescription *description,
-    GPBCodedOutputStream *output) {
-  if (ExtensionIsPacked(description)) {
-    [output writeTag:description->fieldNumber
-              format:GPBWireFormatLengthDelimited];
-    size_t dataSize = 0;
-    size_t typeSize = TypeSize(description->type);
-    if (typeSize != 0) {
-      dataSize = values.count * typeSize;
-    } else {
-      for (id value in values) {
-        dataSize +=
-            ComputePBSerializedSizeNoTagOfObject(description->type, value);
-      }
-    }
-    [output writeRawVarintSizeTAs32:dataSize];
-    for (id value in values) {
-      WriteObjectNoTagToCodedOutputStream(value, description, output);
-    }
-  } else {
-    for (id value in values) {
-      WriteObjectIncludingTagToCodedOutputStream(value, description, output);
-    }
-  }
-}
-
-@implementation GPBExtensionField {
-  GPBExtensionDescription *description_;
-  GPBExtensionDescriptor *descriptor_;
-  GPBValue defaultValue_;
-}
-
-@synthesize containingType = containingType_;
-@synthesize descriptor = descriptor_;
-
-- (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)initWithDescription:(GPBExtensionDescription *)description {
-  if ((self = [super init])) {
-    description_ = description;
-    if (description->extendedClass) {
-      Class containingClass = objc_lookUpClass(description->extendedClass);
-      NSAssert1(containingClass, @"Class %s not defined",
-                description->extendedClass);
-      containingType_ = [containingClass descriptor];
-    }
-#if DEBUG
-    const char *className = description->messageOrGroupClassName;
-    if (className) {
-      NSAssert1(objc_lookUpClass(className) != Nil, @"Class %s not defined",
-                className);
-    }
-#endif
-    descriptor_ = [[GPBExtensionDescriptor alloc]
-        initWithExtensionDescription:description];
-    GPBType type = description_->type;
-    if (type == GPBTypeData) {
-      // 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 == GPBTypeMessage || type == GPBTypeGroup) {
-      // 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_->type == GPBTypeData) &&
-      !ExtensionIsRepeated(description_)) {
-    [defaultValue_.valueData release];
-  }
-  [descriptor_ release];
-  [super dealloc];
-}
-
-- (NSString *)description {
-  return [NSString stringWithFormat:@"<%@ %p> FieldNumber:%d ContainingType:%@",
-                                    [self class], self, self.fieldNumber,
-                                    self.containingType];
-}
-
-- (id)copyWithZone:(NSZone *)__unused zone {
-  return [self retain];
-}
-
-#pragma mark Properties
-
-- (int32_t)fieldNumber {
-  return description_->fieldNumber;
-}
-
-- (GPBWireFormat)wireType {
-  return GPBWireFormatForType(description_->type,
-                              ExtensionIsPacked(description_));
-}
-
-- (BOOL)isRepeated {
-  return ExtensionIsRepeated(description_);
-}
-
-- (id)defaultValue {
-  if (ExtensionIsRepeated(description_)) {
-    return nil;
-  }
-
-  switch (description_->type) {
-    case GPBTypeBool:
-      return @(defaultValue_.valueBool);
-    case GPBTypeFloat:
-      return @(defaultValue_.valueFloat);
-    case GPBTypeDouble:
-      return @(defaultValue_.valueDouble);
-    case GPBTypeInt32:
-    case GPBTypeSInt32:
-    case GPBTypeEnum:
-    case GPBTypeSFixed32:
-      return @(defaultValue_.valueInt32);
-    case GPBTypeInt64:
-    case GPBTypeSInt64:
-    case GPBTypeSFixed64:
-      return @(defaultValue_.valueInt64);
-    case GPBTypeUInt32:
-    case GPBTypeFixed32:
-      return @(defaultValue_.valueUInt32);
-    case GPBTypeUInt64:
-    case GPBTypeFixed64:
-      return @(defaultValue_.valueUInt64);
-    case GPBTypeData:
-      // Like message fields, the default is zero length data.
-      return (defaultValue_.valueData ? defaultValue_.valueData
-                                      : GPBEmptyNSData());
-    case GPBTypeString:
-      // Like message fields, the default is zero length string.
-      return (defaultValue_.valueString ? defaultValue_.valueString : @"");
-    case GPBTypeGroup:
-    case GPBTypeMessage:
-      NSAssert(0, @"Shouldn't get here");
-      return nil;
-  }
-}
-
-#pragma mark Internals
-
-- (void)mergeFromCodedInputStream:(GPBCodedInputStream *)input
-                extensionRegistry:(GPBExtensionRegistry *)extensionRegistry
-                          message:(GPBMessage *)message {
-  GPBCodedInputStreamState *state = &input->state_;
-  if (ExtensionIsPacked(description_)) {
-    int32_t length = GPBCodedInputStreamReadInt32(state);
-    size_t limit = GPBCodedInputStreamPushLimit(state, length);
-    while (GPBCodedInputStreamBytesUntilLimit(state) > 0) {
-      id value = [self newSingleValueFromCodedInputStream:input
-                                        extensionRegistry:extensionRegistry
-                                            existingValue:nil];
-      [message addExtension:self value:value];
-      [value release];
-    }
-    GPBCodedInputStreamPopLimit(state, limit);
-  } else {
-    id existingValue = nil;
-    BOOL isRepeated = ExtensionIsRepeated(description_);
-    if (!isRepeated && GPBTypeIsMessage(description_->type)) {
-      existingValue = [message getExistingExtension:self];
-    }
-    id value = [self newSingleValueFromCodedInputStream:input
-                                      extensionRegistry:extensionRegistry
-                                          existingValue:existingValue];
-    if (isRepeated) {
-      [message addExtension:self value:value];
-    } else {
-      [message setExtension:self value:value];
-    }
-    [value release];
-  }
-}
-
-- (void)writeValue:(id)value
-    includingTagToCodedOutputStream:(GPBCodedOutputStream *)output {
-  if (ExtensionIsRepeated(description_)) {
-    WriteArrayIncludingTagsToCodedOutputStream(value, description_, output);
-  } else {
-    WriteObjectIncludingTagToCodedOutputStream(value, description_, output);
-  }
-}
-
-- (size_t)computeSerializedSizeIncludingTag:(id)value {
-  if (ExtensionIsRepeated(description_)) {
-    return ComputeSerializedSizeIncludingTagOfArray(description_, value);
-  } else {
-    return ComputeSerializedSizeIncludingTagOfObject(description_, value);
-  }
-}
-
-// Note that this returns a retained value intentionally.
-- (id)newSingleValueFromCodedInputStream:(GPBCodedInputStream *)input
-                        extensionRegistry:(GPBExtensionRegistry *)extensionRegistry
-                            existingValue:(GPBMessage *)existingValue {
-  GPBCodedInputStreamState *state = &input->state_;
-  switch (description_->type) {
-    case GPBTypeBool:     return [[NSNumber alloc] initWithBool:GPBCodedInputStreamReadBool(state)];
-    case GPBTypeFixed32:  return [[NSNumber alloc] initWithUnsignedInt:GPBCodedInputStreamReadFixed32(state)];
-    case GPBTypeSFixed32: return [[NSNumber alloc] initWithInt:GPBCodedInputStreamReadSFixed32(state)];
-    case GPBTypeFloat:    return [[NSNumber alloc] initWithFloat:GPBCodedInputStreamReadFloat(state)];
-    case GPBTypeFixed64:  return [[NSNumber alloc] initWithUnsignedLongLong:GPBCodedInputStreamReadFixed64(state)];
-    case GPBTypeSFixed64: return [[NSNumber alloc] initWithLongLong:GPBCodedInputStreamReadSFixed64(state)];
-    case GPBTypeDouble:   return [[NSNumber alloc] initWithDouble:GPBCodedInputStreamReadDouble(state)];
-    case GPBTypeInt32:    return [[NSNumber alloc] initWithInt:GPBCodedInputStreamReadInt32(state)];
-    case GPBTypeInt64:    return [[NSNumber alloc] initWithLongLong:GPBCodedInputStreamReadInt64(state)];
-    case GPBTypeSInt32:   return [[NSNumber alloc] initWithInt:GPBCodedInputStreamReadSInt32(state)];
-    case GPBTypeSInt64:   return [[NSNumber alloc] initWithLongLong:GPBCodedInputStreamReadSInt64(state)];
-    case GPBTypeUInt32:   return [[NSNumber alloc] initWithUnsignedInt:GPBCodedInputStreamReadUInt32(state)];
-    case GPBTypeUInt64:   return [[NSNumber alloc] initWithUnsignedLongLong:GPBCodedInputStreamReadUInt64(state)];
-    case GPBTypeData:     return GPBCodedInputStreamReadRetainedData(state);
-    case GPBTypeString:   return GPBCodedInputStreamReadRetainedString(state);
-    case GPBTypeEnum:     return [[NSNumber alloc] initWithInt:GPBCodedInputStreamReadEnum(state)];
-    case GPBTypeGroup:
-    case GPBTypeMessage: {
-      GPBMessage *message;
-      if (existingValue) {
-        message = [existingValue retain];
-      } else {
-        GPBDescriptor *decriptor = [descriptor_.msgClass descriptor];
-        message = [[decriptor.messageClass alloc] init];
-      }
-
-      if (description_->type == GPBTypeGroup) {
-        [input readGroup:description_->fieldNumber
-                 message:message
-            extensionRegistry:extensionRegistry];
-      } else {
-        // description_->type == GPBTypeMessage
-        if (ExtensionIsWireFormat(description_)) {
-          // For MessageSet fields the message length will have already been
-          // read.
-          [message mergeFromCodedInputStream:input
-                           extensionRegistry:extensionRegistry];
-        } else {
-          [input readMessage:message extensionRegistry:extensionRegistry];
-        }
-      }
-
-      return message;
-    }
-  }
-
-  return nil;
-}
-
-- (NSComparisonResult)compareByFieldNumber:(GPBExtensionField *)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

+ 0 - 51
objectivec/GPBExtensionField_PackagePrivate.h

@@ -1,51 +0,0 @@
-// 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 <Foundation/Foundation.h>
-
-#import "GPBExtensionField.h"
-
-struct GPBExtensionDescription;
-
-@interface GPBExtensionField ()
-
-- (void)mergeFromCodedInputStream:(GPBCodedInputStream *)input
-                extensionRegistry:(GPBExtensionRegistry *)extensionRegistry
-                          message:(GPBMessage *)message;
-
-- (instancetype)initWithDescription:(struct GPBExtensionDescription *)description;
-
-- (size_t)computeSerializedSizeIncludingTag:(id)value;
-- (void)writeValue:(id)value
-    includingTagToCodedOutputStream:(GPBCodedOutputStream *)output;
-
-- (NSComparisonResult)compareByFieldNumber:(GPBExtensionField *)other;
-
-@end

+ 11 - 12
objectivec/GPBExtensionField.h → objectivec/GPBExtensionInternals.h

@@ -30,22 +30,21 @@
 
 #import <Foundation/Foundation.h>
 
-#import "GPBWireFormat.h"
-#import "GPBTypes.h"
+#import "GPBDescriptor.h"
 
 @class GPBCodedInputStream;
 @class GPBCodedOutputStream;
 @class GPBExtensionRegistry;
-@class GPBDescriptor;
-@class GPBExtensionDescriptor;
 
-@interface GPBExtensionField : NSObject<NSCopying>
+void GPBExtensionMergeFromInputStream(GPBExtensionDescriptor *extension,
+                                      BOOL isPackedOnStream,
+                                      GPBCodedInputStream *input,
+                                      GPBExtensionRegistry *extensionRegistry,
+                                      GPBMessage *message);
 
-@property(nonatomic, readonly) int32_t fieldNumber;
-@property(nonatomic, readonly) GPBWireFormat wireType;
-@property(nonatomic, readonly) BOOL isRepeated;
-@property(nonatomic, readonly) GPBDescriptor *containingType;
-@property(nonatomic, readonly) id defaultValue;
-@property(nonatomic, readonly) GPBExtensionDescriptor *descriptor;
+size_t GPBComputeExtensionSerializedSizeIncludingTag(
+    GPBExtensionDescriptor *extension, id value);
 
-@end
+void GPBWriteExtensionValueToOutputStream(GPBExtensionDescriptor *extension,
+                                          id value,
+                                          GPBCodedOutputStream *output);

+ 380 - 0
objectivec/GPBExtensionInternals.m

@@ -0,0 +1,380 @@
+// 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 "GPBExtensionInternals.h"
+
+#import <objc/runtime.h>
+
+#import "GPBCodedInputStream_PackagePrivate.h"
+#import "GPBCodedOutputStream.h"
+#import "GPBDescriptor_PackagePrivate.h"
+#import "GPBMessage_PackagePrivate.h"
+#import "GPBUtilities_PackagePrivate.h"
+
+static id NewSingleValueFromInputStream(GPBExtensionDescriptor *extension,
+                                        GPBCodedInputStream *input,
+                                        GPBExtensionRegistry *extensionRegistry,
+                                        GPBMessage *existingValue)
+    __attribute__((ns_returns_retained));
+
+GPB_INLINE size_t DataTypeSize(GPBDataType dataType) {
+  switch (dataType) {
+    case GPBDataTypeBool:
+      return 1;
+    case GPBDataTypeFixed32:
+    case GPBDataTypeSFixed32:
+    case GPBDataTypeFloat:
+      return 4;
+    case GPBDataTypeFixed64:
+    case GPBDataTypeSFixed64:
+    case GPBDataTypeDouble:
+      return 8;
+    default:
+      return 0;
+  }
+}
+
+static size_t ComputePBSerializedSizeNoTagOfObject(GPBDataType dataType, id object) {
+#define FIELD_CASE(TYPE, ACCESSOR)                                     \
+  case GPBDataType##TYPE:                                              \
+    return GPBCompute##TYPE##SizeNoTag([(NSNumber *)object ACCESSOR]);
+#define FIELD_CASE2(TYPE)                                              \
+  case GPBDataType##TYPE:                                              \
+    return GPBCompute##TYPE##SizeNoTag(object);
+  switch (dataType) {
+    FIELD_CASE(Bool, boolValue)
+    FIELD_CASE(Float, floatValue)
+    FIELD_CASE(Double, doubleValue)
+    FIELD_CASE(Int32, intValue)
+    FIELD_CASE(SFixed32, intValue)
+    FIELD_CASE(SInt32, intValue)
+    FIELD_CASE(Enum, intValue)
+    FIELD_CASE(Int64, longLongValue)
+    FIELD_CASE(SInt64, longLongValue)
+    FIELD_CASE(SFixed64, longLongValue)
+    FIELD_CASE(UInt32, unsignedIntValue)
+    FIELD_CASE(Fixed32, unsignedIntValue)
+    FIELD_CASE(UInt64, unsignedLongLongValue)
+    FIELD_CASE(Fixed64, unsignedLongLongValue)
+    FIELD_CASE2(Bytes)
+    FIELD_CASE2(String)
+    FIELD_CASE2(Message)
+    FIELD_CASE2(Group)
+  }
+#undef FIELD_CASE
+#undef FIELD_CASE2
+}
+
+static size_t ComputeSerializedSizeIncludingTagOfObject(
+    GPBExtensionDescription *description, id object) {
+#define FIELD_CASE(TYPE, ACCESSOR)                                   \
+  case GPBDataType##TYPE:                                            \
+    return GPBCompute##TYPE##Size(description->fieldNumber,          \
+                                  [(NSNumber *)object ACCESSOR]);
+#define FIELD_CASE2(TYPE)                                            \
+  case GPBDataType##TYPE:                                            \
+    return GPBCompute##TYPE##Size(description->fieldNumber, object);
+  switch (description->dataType) {
+    FIELD_CASE(Bool, boolValue)
+    FIELD_CASE(Float, floatValue)
+    FIELD_CASE(Double, doubleValue)
+    FIELD_CASE(Int32, intValue)
+    FIELD_CASE(SFixed32, intValue)
+    FIELD_CASE(SInt32, intValue)
+    FIELD_CASE(Enum, intValue)
+    FIELD_CASE(Int64, longLongValue)
+    FIELD_CASE(SInt64, longLongValue)
+    FIELD_CASE(SFixed64, longLongValue)
+    FIELD_CASE(UInt32, unsignedIntValue)
+    FIELD_CASE(Fixed32, unsignedIntValue)
+    FIELD_CASE(UInt64, unsignedLongLongValue)
+    FIELD_CASE(Fixed64, unsignedLongLongValue)
+    FIELD_CASE2(Bytes)
+    FIELD_CASE2(String)
+    FIELD_CASE2(Group)
+    case GPBDataTypeMessage:
+      if (GPBExtensionIsWireFormat(description)) {
+        return GPBComputeMessageSetExtensionSize(description->fieldNumber,
+                                                 object);
+      } else {
+        return GPBComputeMessageSize(description->fieldNumber, object);
+      }
+  }
+#undef FIELD_CASE
+#undef FIELD_CASE2
+}
+
+static size_t ComputeSerializedSizeIncludingTagOfArray(
+    GPBExtensionDescription *description, NSArray *values) {
+  if (GPBExtensionIsPacked(description)) {
+    size_t size = 0;
+    size_t typeSize = DataTypeSize(description->dataType);
+    if (typeSize != 0) {
+      size = values.count * typeSize;
+    } else {
+      for (id value in values) {
+        size +=
+            ComputePBSerializedSizeNoTagOfObject(description->dataType, value);
+      }
+    }
+    return size + GPBComputeTagSize(description->fieldNumber) +
+           GPBComputeRawVarint32SizeForInteger(size);
+  } else {
+    size_t size = 0;
+    for (id value in values) {
+      size += ComputeSerializedSizeIncludingTagOfObject(description, value);
+    }
+    return size;
+  }
+}
+
+static void WriteObjectIncludingTagToCodedOutputStream(
+    id object, GPBExtensionDescription *description,
+    GPBCodedOutputStream *output) {
+#define FIELD_CASE(TYPE, ACCESSOR)                      \
+  case GPBDataType##TYPE:                               \
+    [output write##TYPE:description->fieldNumber        \
+                  value:[(NSNumber *)object ACCESSOR]]; \
+    return;
+#define FIELD_CASE2(TYPE)                                       \
+  case GPBDataType##TYPE:                                       \
+    [output write##TYPE:description->fieldNumber value:object]; \
+    return;
+  switch (description->dataType) {
+    FIELD_CASE(Bool, boolValue)
+    FIELD_CASE(Float, floatValue)
+    FIELD_CASE(Double, doubleValue)
+    FIELD_CASE(Int32, intValue)
+    FIELD_CASE(SFixed32, intValue)
+    FIELD_CASE(SInt32, intValue)
+    FIELD_CASE(Enum, intValue)
+    FIELD_CASE(Int64, longLongValue)
+    FIELD_CASE(SInt64, longLongValue)
+    FIELD_CASE(SFixed64, longLongValue)
+    FIELD_CASE(UInt32, unsignedIntValue)
+    FIELD_CASE(Fixed32, unsignedIntValue)
+    FIELD_CASE(UInt64, unsignedLongLongValue)
+    FIELD_CASE(Fixed64, unsignedLongLongValue)
+    FIELD_CASE2(Bytes)
+    FIELD_CASE2(String)
+    FIELD_CASE2(Group)
+    case GPBDataTypeMessage:
+      if (GPBExtensionIsWireFormat(description)) {
+        [output writeMessageSetExtension:description->fieldNumber value:object];
+      } else {
+        [output writeMessage:description->fieldNumber value:object];
+      }
+      return;
+  }
+#undef FIELD_CASE
+#undef FIELD_CASE2
+}
+
+static void WriteObjectNoTagToCodedOutputStream(
+    id object, GPBExtensionDescription *description,
+    GPBCodedOutputStream *output) {
+#define FIELD_CASE(TYPE, ACCESSOR)                             \
+  case GPBDataType##TYPE:                                      \
+    [output write##TYPE##NoTag:[(NSNumber *)object ACCESSOR]]; \
+    return;
+#define FIELD_CASE2(TYPE)               \
+  case GPBDataType##TYPE:               \
+    [output write##TYPE##NoTag:object]; \
+    return;
+  switch (description->dataType) {
+    FIELD_CASE(Bool, boolValue)
+    FIELD_CASE(Float, floatValue)
+    FIELD_CASE(Double, doubleValue)
+    FIELD_CASE(Int32, intValue)
+    FIELD_CASE(SFixed32, intValue)
+    FIELD_CASE(SInt32, intValue)
+    FIELD_CASE(Enum, intValue)
+    FIELD_CASE(Int64, longLongValue)
+    FIELD_CASE(SInt64, longLongValue)
+    FIELD_CASE(SFixed64, longLongValue)
+    FIELD_CASE(UInt32, unsignedIntValue)
+    FIELD_CASE(Fixed32, unsignedIntValue)
+    FIELD_CASE(UInt64, unsignedLongLongValue)
+    FIELD_CASE(Fixed64, unsignedLongLongValue)
+    FIELD_CASE2(Bytes)
+    FIELD_CASE2(String)
+    FIELD_CASE2(Message)
+    case GPBDataTypeGroup:
+      [output writeGroupNoTag:description->fieldNumber value:object];
+      return;
+  }
+#undef FIELD_CASE
+#undef FIELD_CASE2
+}
+
+static void WriteArrayIncludingTagsToCodedOutputStream(
+    NSArray *values, GPBExtensionDescription *description,
+    GPBCodedOutputStream *output) {
+  if (GPBExtensionIsPacked(description)) {
+    [output writeTag:description->fieldNumber
+              format:GPBWireFormatLengthDelimited];
+    size_t dataSize = 0;
+    size_t typeSize = DataTypeSize(description->dataType);
+    if (typeSize != 0) {
+      dataSize = values.count * typeSize;
+    } else {
+      for (id value in values) {
+        dataSize +=
+            ComputePBSerializedSizeNoTagOfObject(description->dataType, value);
+      }
+    }
+    [output writeRawVarintSizeTAs32:dataSize];
+    for (id value in values) {
+      WriteObjectNoTagToCodedOutputStream(value, description, output);
+    }
+  } else {
+    for (id value in values) {
+      WriteObjectIncludingTagToCodedOutputStream(value, description, output);
+    }
+  }
+}
+
+void GPBExtensionMergeFromInputStream(GPBExtensionDescriptor *extension,
+                                      BOOL isPackedOnStream,
+                                      GPBCodedInputStream *input,
+                                      GPBExtensionRegistry *extensionRegistry,
+                                      GPBMessage *message) {
+  GPBExtensionDescription *description = extension->description_;
+  GPBCodedInputStreamState *state = &input->state_;
+  if (isPackedOnStream) {
+    NSCAssert(GPBExtensionIsRepeated(description),
+              @"How was it packed if it isn't repeated?");
+    int32_t length = GPBCodedInputStreamReadInt32(state);
+    size_t limit = GPBCodedInputStreamPushLimit(state, length);
+    while (GPBCodedInputStreamBytesUntilLimit(state) > 0) {
+      id value = NewSingleValueFromInputStream(extension,
+                                               input,
+                                               extensionRegistry,
+                                               nil);
+      [message addExtension:extension value:value];
+      [value release];
+    }
+    GPBCodedInputStreamPopLimit(state, limit);
+  } else {
+    id existingValue = nil;
+    BOOL isRepeated = GPBExtensionIsRepeated(description);
+    if (!isRepeated && GPBDataTypeIsMessage(description->dataType)) {
+      existingValue = [message getExistingExtension:extension];
+    }
+    id value = NewSingleValueFromInputStream(extension,
+                                             input,
+                                             extensionRegistry,
+                                             existingValue);
+    if (isRepeated) {
+      [message addExtension:extension value:value];
+    } else {
+      [message setExtension:extension value:value];
+    }
+    [value release];
+  }
+}
+
+void GPBWriteExtensionValueToOutputStream(GPBExtensionDescriptor *extension,
+                                          id value,
+                                          GPBCodedOutputStream *output) {
+  GPBExtensionDescription *description = extension->description_;
+  if (GPBExtensionIsRepeated(description)) {
+    WriteArrayIncludingTagsToCodedOutputStream(value, description, output);
+  } else {
+    WriteObjectIncludingTagToCodedOutputStream(value, description, output);
+  }
+}
+
+size_t GPBComputeExtensionSerializedSizeIncludingTag(
+    GPBExtensionDescriptor *extension, id value) {
+  GPBExtensionDescription *description = extension->description_;
+  if (GPBExtensionIsRepeated(description)) {
+    return ComputeSerializedSizeIncludingTagOfArray(description, value);
+  } else {
+    return ComputeSerializedSizeIncludingTagOfObject(description, value);
+  }
+}
+
+// Note that this returns a retained value intentionally.
+static id NewSingleValueFromInputStream(GPBExtensionDescriptor *extension,
+                                        GPBCodedInputStream *input,
+                                        GPBExtensionRegistry *extensionRegistry,
+                                        GPBMessage *existingValue) {
+  GPBExtensionDescription *description = extension->description_;
+  GPBCodedInputStreamState *state = &input->state_;
+  switch (description->dataType) {
+    case GPBDataTypeBool:     return [[NSNumber alloc] initWithBool:GPBCodedInputStreamReadBool(state)];
+    case GPBDataTypeFixed32:  return [[NSNumber alloc] initWithUnsignedInt:GPBCodedInputStreamReadFixed32(state)];
+    case GPBDataTypeSFixed32: return [[NSNumber alloc] initWithInt:GPBCodedInputStreamReadSFixed32(state)];
+    case GPBDataTypeFloat:    return [[NSNumber alloc] initWithFloat:GPBCodedInputStreamReadFloat(state)];
+    case GPBDataTypeFixed64:  return [[NSNumber alloc] initWithUnsignedLongLong:GPBCodedInputStreamReadFixed64(state)];
+    case GPBDataTypeSFixed64: return [[NSNumber alloc] initWithLongLong:GPBCodedInputStreamReadSFixed64(state)];
+    case GPBDataTypeDouble:   return [[NSNumber alloc] initWithDouble:GPBCodedInputStreamReadDouble(state)];
+    case GPBDataTypeInt32:    return [[NSNumber alloc] initWithInt:GPBCodedInputStreamReadInt32(state)];
+    case GPBDataTypeInt64:    return [[NSNumber alloc] initWithLongLong:GPBCodedInputStreamReadInt64(state)];
+    case GPBDataTypeSInt32:   return [[NSNumber alloc] initWithInt:GPBCodedInputStreamReadSInt32(state)];
+    case GPBDataTypeSInt64:   return [[NSNumber alloc] initWithLongLong:GPBCodedInputStreamReadSInt64(state)];
+    case GPBDataTypeUInt32:   return [[NSNumber alloc] initWithUnsignedInt:GPBCodedInputStreamReadUInt32(state)];
+    case GPBDataTypeUInt64:   return [[NSNumber alloc] initWithUnsignedLongLong:GPBCodedInputStreamReadUInt64(state)];
+    case GPBDataTypeBytes:    return GPBCodedInputStreamReadRetainedBytes(state);
+    case GPBDataTypeString:   return GPBCodedInputStreamReadRetainedString(state);
+    case GPBDataTypeEnum:     return [[NSNumber alloc] initWithInt:GPBCodedInputStreamReadEnum(state)];
+    case GPBDataTypeGroup:
+    case GPBDataTypeMessage: {
+      GPBMessage *message;
+      if (existingValue) {
+        message = [existingValue retain];
+      } else {
+        GPBDescriptor *decriptor = [extension.msgClass descriptor];
+        message = [[decriptor.messageClass alloc] init];
+      }
+
+      if (description->dataType == GPBDataTypeGroup) {
+        [input readGroup:description->fieldNumber
+                 message:message
+            extensionRegistry:extensionRegistry];
+      } else {
+        // description->dataType == GPBDataTypeMessage
+        if (GPBExtensionIsWireFormat(description)) {
+          // For MessageSet fields the message length will have already been
+          // read.
+          [message mergeFromCodedInputStream:input
+                           extensionRegistry:extensionRegistry];
+        } else {
+          [input readMessage:message extensionRegistry:extensionRegistry];
+        }
+      }
+
+      return message;
+    }
+  }
+
+  return nil;
+}

+ 4 - 4
objectivec/GPBExtensionRegistry.h

@@ -31,7 +31,7 @@
 #import <Foundation/Foundation.h>
 
 @class GPBDescriptor;
-@class GPBExtensionField;
+@class GPBExtensionDescriptor;
 
 // A table of known extensions, searchable by name or field number.  When
 // parsing a protocol message that might have extensions, you must provide an
@@ -54,10 +54,10 @@
 //
 @interface GPBExtensionRegistry : NSObject<NSCopying>
 
-- (void)addExtension:(GPBExtensionField *)extension;
+- (void)addExtension:(GPBExtensionDescriptor *)extension;
 - (void)addExtensions:(GPBExtensionRegistry *)registry;
 
-- (GPBExtensionField *)getExtension:(GPBDescriptor *)containingType
-                        fieldNumber:(NSInteger)fieldNumber;
+- (GPBExtensionDescriptor *)extensionForDescriptor:(GPBDescriptor *)descriptor
+                                       fieldNumber:(NSInteger)fieldNumber;
 
 @end

+ 17 - 15
objectivec/GPBExtensionRegistry.m

@@ -32,7 +32,6 @@
 
 #import "GPBBootstrap.h"
 #import "GPBDescriptor.h"
-#import "GPBExtensionField.h"
 
 @implementation GPBExtensionRegistry {
   // TODO(dmaclach): Reimplement with CFDictionaries that don't use
@@ -60,31 +59,34 @@
   return result;
 }
 
-- (NSMutableDictionary *)extensionMapForContainingType:
-        (GPBDescriptor *)containingType {
+- (NSMutableDictionary *)extensionMapForContainingMessageClass:
+        (Class)containingMessageClass {
   NSMutableDictionary *extensionMap =
-      [mutableClassMap_ objectForKey:containingType];
+      [mutableClassMap_ objectForKey:containingMessageClass];
   if (extensionMap == nil) {
     extensionMap = [NSMutableDictionary dictionary];
-    [mutableClassMap_ setObject:extensionMap forKey:containingType];
+    [mutableClassMap_ setObject:extensionMap
+                         forKey:(id<NSCopying>)containingMessageClass];
   }
   return extensionMap;
 }
 
-- (void)addExtension:(GPBExtensionField *)extension {
+- (void)addExtension:(GPBExtensionDescriptor *)extension {
   if (extension == nil) {
     return;
   }
 
-  GPBDescriptor *containingType = [extension containingType];
+  Class containingMessageClass = extension.containingMessageClass;
   NSMutableDictionary *extensionMap =
-      [self extensionMapForContainingType:containingType];
-  [extensionMap setObject:extension forKey:@([extension fieldNumber])];
+      [self extensionMapForContainingMessageClass:containingMessageClass];
+  [extensionMap setObject:extension forKey:@(extension.fieldNumber)];
 }
 
-- (GPBExtensionField *)getExtension:(GPBDescriptor *)containingType
-                        fieldNumber:(NSInteger)fieldNumber {
-  NSDictionary *extensionMap = [mutableClassMap_ objectForKey:containingType];
+- (GPBExtensionDescriptor *)extensionForDescriptor:(GPBDescriptor *)descriptor
+                                       fieldNumber:(NSInteger)fieldNumber {
+  Class messageClass = descriptor.messageClass;
+  NSDictionary *extensionMap =
+      [mutableClassMap_ objectForKey:messageClass];
   return [extensionMap objectForKey:@(fieldNumber)];
 }
 
@@ -94,11 +96,11 @@
     return;
   }
   NSMutableDictionary *otherClassMap = registry->mutableClassMap_;
-  for (GPBDescriptor *containingType in otherClassMap) {
+  for (Class containingMessageClass in otherClassMap) {
     NSMutableDictionary *extensionMap =
-        [self extensionMapForContainingType:containingType];
+        [self extensionMapForContainingMessageClass:containingMessageClass];
     NSMutableDictionary *otherExtensionMap =
-        [registry extensionMapForContainingType:containingType];
+        [registry extensionMapForContainingMessageClass:containingMessageClass];
     [extensionMap addEntriesFromDictionary:otherExtensionMap];
   }
 }

+ 7 - 7
objectivec/GPBMessage.h

@@ -35,7 +35,7 @@
 @class GPBDescriptor;
 @class GPBCodedInputStream;
 @class GPBCodedOutputStream;
-@class GPBExtensionField;
+@class GPBExtensionDescriptor;
 @class GPBExtensionRegistry;
 @class GPBFieldDescriptor;
 @class GPBUnknownFieldSet;
@@ -148,14 +148,14 @@ CF_EXTERN_C_END
 // Extensions use boxed values (NSNumbers) for PODs, NSMutableArrays for
 // repeated. If the extension is a Message one will be auto created for you
 // and returned similar to fields.
-- (BOOL)hasExtension:(GPBExtensionField *)extension;
-- (id)getExtension:(GPBExtensionField *)extension;
-- (void)setExtension:(GPBExtensionField *)extension value:(id)value;
-- (void)addExtension:(GPBExtensionField *)extension value:(id)value;
-- (void)setExtension:(GPBExtensionField *)extension
+- (BOOL)hasExtension:(GPBExtensionDescriptor *)extension;
+- (id)getExtension:(GPBExtensionDescriptor *)extension;
+- (void)setExtension:(GPBExtensionDescriptor *)extension value:(id)value;
+- (void)addExtension:(GPBExtensionDescriptor *)extension value:(id)value;
+- (void)setExtension:(GPBExtensionDescriptor *)extension
                index:(NSUInteger)index
                value:(id)value;
-- (void)clearExtension:(GPBExtensionField *)extension;
+- (void)clearExtension:(GPBExtensionDescriptor *)extension;
 
 - (void)setUnknownFields:(GPBUnknownFieldSet *)unknownFields;
 

Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 248 - 231
objectivec/GPBMessage.m


+ 2 - 2
objectivec/GPBMessage_PackagePrivate.h

@@ -67,9 +67,9 @@ typedef struct GPBMessage_Storage *GPBMessage_StoragePtr;
 
 // Gets an extension value without autocreating the result if not found. (i.e.
 // returns nil if the extension is not set)
-- (id)getExistingExtension:(GPBExtensionField *)extension;
+- (id)getExistingExtension:(GPBExtensionDescriptor *)extension;
 
-// Returns an array of GPBExtensionField* for all the extensions currently
+// Returns an array of GPBExtensionDescriptor* for all the extensions currently
 // in use on the message.  They are sorted by field number.
 - (NSArray *)sortedExtensionsInUse;
 

+ 1 - 2
objectivec/GPBProtocolBuffers.h

@@ -35,11 +35,10 @@
 #import "GPBCodedOutputStream.h"
 #import "GPBDescriptor.h"
 #import "GPBDictionary.h"
-#import "GPBExtensionField.h"
 #import "GPBExtensionRegistry.h"
-#import "GPBField.h"
 #import "GPBMessage.h"
 #import "GPBRootObject.h"
+#import "GPBUnknownField.h"
 #import "GPBUnknownFieldSet.h"
 #import "GPBUtilities.h"
 #import "GPBWireFormat.h"

+ 15 - 2
objectivec/GPBProtocolBuffers.m

@@ -36,14 +36,27 @@
 #import "GPBCodedOutputStream.m"
 #import "GPBDescriptor.m"
 #import "GPBDictionary.m"
-#import "GPBExtensionField.m"
+#import "GPBExtensionInternals.m"
 #import "GPBExtensionRegistry.m"
-#import "GPBField.m"
 #import "GPBMessage.m"
 #import "GPBRootObject.m"
+#import "GPBUnknownField.m"
 #import "GPBUnknownFieldSet.m"
 #import "GPBUtilities.m"
 #import "GPBWellKnownTypes.m"
 #import "GPBWireFormat.m"
 
 #import "google/protobuf/Descriptor.pbobjc.m"
+
+// Duration and Timestamp are #imported into GPBWellKnownTypes.m to the
+// Objective C categories added will always be linked in with the classes.
+#import "google/protobuf/Any.pbobjc.m"
+#import "google/protobuf/Api.pbobjc.m"
+// #import "google/protobuf/Duration.pbobjc.m"
+#import "google/protobuf/Empty.pbobjc.m"
+#import "google/protobuf/FieldMask.pbobjc.m"
+#import "google/protobuf/SourceContext.pbobjc.m"
+#import "google/protobuf/Struct.pbobjc.m"
+// #import "google/protobuf/Timestamp.pbobjc.m"
+#import "google/protobuf/Type.pbobjc.m"
+#import "google/protobuf/Wrappers.pbobjc.m"

+ 1 - 2
objectivec/GPBProtocolBuffers_RuntimeSupport.h

@@ -34,8 +34,7 @@
 #import "GPBProtocolBuffers.h"
 
 #import "GPBDescriptor_PackagePrivate.h"
-#import "GPBExtensionField_PackagePrivate.h"
-#import "GPBExtensionRegistry.h"
+#import "GPBExtensionInternals.h"
 #import "GPBMessage_PackagePrivate.h"
 #import "GPBRootObject_PackagePrivate.h"
 #import "GPBUtilities_PackagePrivate.h"

+ 3 - 4
objectivec/GPBRootObject.m

@@ -36,7 +36,6 @@
 #import <CoreFoundation/CoreFoundation.h>
 
 #import "GPBDescriptor.h"
-#import "GPBExtensionField.h"
 #import "GPBUtilities_PackagePrivate.h"
 
 @interface GPBExtensionDescriptor (GPBRootObject)
@@ -130,14 +129,14 @@ static CFMutableDictionaryRef gExtensionSingletonDictionary = NULL;
   return nil;
 }
 
-+ (void)globallyRegisterExtension:(GPBExtensionField *)field {
-  const char *key = [field.descriptor singletonNameC];
++ (void)globallyRegisterExtension:(GPBExtensionDescriptor *)field {
+  const char *key = [field singletonNameC];
   OSSpinLockLock(&gExtensionSingletonDictionaryLock_);
   CFDictionarySetValue(gExtensionSingletonDictionary, key, field);
   OSSpinLockUnlock(&gExtensionSingletonDictionaryLock_);
 }
 
-GPB_INLINE id ExtensionForName(id self, SEL _cmd) {
+static id ExtensionForName(id self, SEL _cmd) {
   // Really fast way of doing "classname_selName".
   // This came up as a hotspot (creation of NSString *) when accessing a
   // lot of extensions.

+ 2 - 2
objectivec/GPBRootObject_PackagePrivate.h

@@ -32,12 +32,12 @@
 
 #import "GPBRootObject.h"
 
-@class GPBExtensionField;
+@class GPBExtensionDescriptor;
 
 @interface GPBRootObject ()
 
 // Globally register.
-+ (void)globallyRegisterExtension:(GPBExtensionField *)field;
++ (void)globallyRegisterExtension:(GPBExtensionDescriptor *)field;
 
 @end
 

+ 24 - 24
objectivec/GPBTypes.h → objectivec/GPBRuntimeTypes.h

@@ -63,36 +63,36 @@ typedef union {
   GPB_UNSAFE_UNRETAINED NSString *valueString;
   GPB_UNSAFE_UNRETAINED GPBMessage *valueMessage;
   int32_t valueEnum;
-} GPBValue;
+} GPBGenericValue;
 
 // Do not change the order of this enum (or add things to it) without thinking
 // about it very carefully. There are several things that depend on the order.
 typedef enum {
-  GPBTypeBool = 0,
-  GPBTypeFixed32,
-  GPBTypeSFixed32,
-  GPBTypeFloat,
-  GPBTypeFixed64,
-  GPBTypeSFixed64,
-  GPBTypeDouble,
-  GPBTypeInt32,
-  GPBTypeInt64,
-  GPBTypeSInt32,
-  GPBTypeSInt64,
-  GPBTypeUInt32,
-  GPBTypeUInt64,
-  GPBTypeData,  // Maps to Bytes Protobuf type
-  GPBTypeString,
-  GPBTypeMessage,
-  GPBTypeGroup,
-  GPBTypeEnum,
-} GPBType;
+  GPBDataTypeBool = 0,
+  GPBDataTypeFixed32,
+  GPBDataTypeSFixed32,
+  GPBDataTypeFloat,
+  GPBDataTypeFixed64,
+  GPBDataTypeSFixed64,
+  GPBDataTypeDouble,
+  GPBDataTypeInt32,
+  GPBDataTypeInt64,
+  GPBDataTypeSInt32,
+  GPBDataTypeSInt64,
+  GPBDataTypeUInt32,
+  GPBDataTypeUInt64,
+  GPBDataTypeBytes,
+  GPBDataTypeString,
+  GPBDataTypeMessage,
+  GPBDataTypeGroup,
+  GPBDataTypeEnum,
+} GPBDataType;
 
 enum {
-  // A count of the number of types in GPBType. Separated out from the GPBType
-  // enum to avoid warnings regarding not handling GPBTypeCount in switch
-  // statements.
-  GPBTypeCount = GPBTypeEnum + 1
+  // A count of the number of types in GPBDataType. Separated out from the
+  // GPBDataType enum to avoid warnings regarding not handling
+  // GPBDataType_Count in switch statements.
+  GPBDataType_Count = GPBDataTypeEnum + 1
 };
 
 // An extension range.

+ 3 - 3
objectivec/GPBField.h → objectivec/GPBUnknownField.h

@@ -35,7 +35,7 @@
 @class GPBUInt64Array;
 @class GPBUnknownFieldSet;
 
-@interface GPBField : NSObject<NSCopying>
+@interface GPBUnknownField : NSObject<NSCopying>
 
 @property(nonatomic, readonly, assign) int32_t number;
 
@@ -43,8 +43,8 @@
 @property(nonatomic, readonly, strong) GPBUInt64Array *varintList;
 @property(nonatomic, readonly, strong) GPBUInt32Array *fixed32List;
 @property(nonatomic, readonly, strong) GPBUInt64Array *fixed64List;
-@property(nonatomic, readonly, strong) NSArray *lengthDelimitedList;
-@property(nonatomic, readonly, strong) NSArray *groupList;
+@property(nonatomic, readonly, strong) NSArray *lengthDelimitedList;  // NSData
+@property(nonatomic, readonly, strong) NSArray *groupList;  // GPBUnknownFieldSet
 
 // Only one of these should be used per Field.
 - (void)addVarint:(uint64_t)value;

+ 13 - 15
objectivec/GPBField.m → objectivec/GPBUnknownField.m

@@ -28,12 +28,12 @@
 // (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 "GPBField_PackagePrivate.h"
+#import "GPBUnknownField_PackagePrivate.h"
 
 #import "GPBArray.h"
 #import "GPBCodedOutputStream.h"
 
-@interface GPBField () {
+@implementation GPBUnknownField {
  @protected
   int32_t number_;
   GPBUInt64Array *mutableVarintList_;
@@ -42,9 +42,6 @@
   NSMutableArray *mutableLengthDelimitedList_;
   NSMutableArray *mutableGroupList_;
 }
-@end
-
-@implementation GPBField
 
 @synthesize number = number_;
 @synthesize varintList = mutableVarintList_;
@@ -71,7 +68,8 @@
 }
 
 - (id)copyWithZone:(NSZone *)zone {
-  GPBField *result = [[GPBField allocWithZone:zone] initWithNumber:number_];
+  GPBUnknownField *result =
+      [[GPBUnknownField allocWithZone:zone] initWithNumber:number_];
   result->mutableFixed32List_ = [mutableFixed32List_ copyWithZone:zone];
   result->mutableFixed64List_ = [mutableFixed64List_ copyWithZone:zone];
   result->mutableLengthDelimitedList_ =
@@ -91,8 +89,8 @@
 
 - (BOOL)isEqual:(id)object {
   if (self == object) return YES;
-  if (![object isKindOfClass:[GPBField class]]) return NO;
-  GPBField *field = (GPBField *)object;
+  if (![object isKindOfClass:[GPBUnknownField class]]) return NO;
+  GPBUnknownField *field = (GPBUnknownField *)object;
   BOOL equalVarint =
       (mutableVarintList_.count == 0 && field->mutableVarintList_.count == 0) ||
       [mutableVarintList_ isEqual:field->mutableVarintList_];
@@ -131,23 +129,23 @@
 - (void)writeToOutput:(GPBCodedOutputStream *)output {
   NSUInteger count = mutableVarintList_.count;
   if (count > 0) {
-    [output writeUInt64s:number_ values:mutableVarintList_ tag:0];
+    [output writeUInt64Array:number_ values:mutableVarintList_ tag:0];
   }
   count = mutableFixed32List_.count;
   if (count > 0) {
-    [output writeFixed32s:number_ values:mutableFixed32List_ tag:0];
+    [output writeFixed32Array:number_ values:mutableFixed32List_ tag:0];
   }
   count = mutableFixed64List_.count;
   if (count > 0) {
-    [output writeFixed64s:number_ values:mutableFixed64List_ tag:0];
+    [output writeFixed64Array:number_ values:mutableFixed64List_ tag:0];
   }
   count = mutableLengthDelimitedList_.count;
   if (count > 0) {
-    [output writeDatas:number_ values:mutableLengthDelimitedList_];
+    [output writeBytesArray:number_ values:mutableLengthDelimitedList_];
   }
   count = mutableGroupList_.count;
   if (count > 0) {
-    [output writeUnknownGroups:number_ values:mutableGroupList_];
+    [output writeUnknownGroupArray:number_ values:mutableGroupList_];
   }
 }
 
@@ -173,7 +171,7 @@
       }];
 
   for (NSData *data in mutableLengthDelimitedList_) {
-    result += GPBComputeDataSize(number, data);
+    result += GPBComputeBytesSize(number, data);
   }
 
   for (GPBUnknownFieldSet *set in mutableGroupList_) {
@@ -229,7 +227,7 @@
   return description;
 }
 
-- (void)mergeFromField:(GPBField *)other {
+- (void)mergeFromField:(GPBUnknownField *)other {
   GPBUInt64Array *otherVarintList = other.varintList;
   if (otherVarintList.count > 0) {
     if (mutableVarintList_ == nil) {

+ 3 - 3
objectivec/GPBUnknownFieldSet.h

@@ -30,15 +30,15 @@
 
 #import <Foundation/Foundation.h>
 
-@class GPBField;
+@class GPBUnknownField;
 
 @interface GPBUnknownFieldSet : NSObject<NSCopying>
 
 - (BOOL)hasField:(int32_t)number;
-- (GPBField *)getField:(int32_t)number;
+- (GPBUnknownField *)getField:(int32_t)number;
 - (NSUInteger)countOfFields;
 
-- (void)addField:(GPBField *)field;
+- (void)addField:(GPBUnknownField *)field;
 
 // Returns an NSArray of the GPBFields sorted by the field numbers.
 - (NSArray *)sortedFields;

+ 28 - 27
objectivec/GPBUnknownFieldSet.m

@@ -32,7 +32,7 @@
 
 #import "GPBCodedInputStream_PackagePrivate.h"
 #import "GPBCodedOutputStream.h"
-#import "GPBField_PackagePrivate.h"
+#import "GPBUnknownField_PackagePrivate.h"
 #import "GPBUtilities.h"
 #import "GPBWireFormat.h"
 
@@ -85,10 +85,10 @@ static void checkNumber(int32_t number) {
 
 static void CopyWorker(const void *key, const void *value, void *context) {
 #pragma unused(key)
-  GPBField *field = value;
+  GPBUnknownField *field = value;
   GPBUnknownFieldSet *result = context;
 
-  GPBField *copied = [field copy];
+  GPBUnknownField *copied = [field copy];
   [result addField:copied];
   [copied release];
 }
@@ -136,9 +136,10 @@ static void CopyWorker(const void *key, const void *value, void *context) {
   return fields_ ? (CFDictionaryGetValue(fields_, (void *)key) != nil) : NO;
 }
 
-- (GPBField *)getField:(int32_t)number {
+- (GPBUnknownField *)getField:(int32_t)number {
   ssize_t key = number;
-  GPBField *result = fields_ ? CFDictionaryGetValue(fields_, (void *)key) : nil;
+  GPBUnknownField *result =
+      fields_ ? CFDictionaryGetValue(fields_, (void *)key) : nil;
   return result;
 }
 
@@ -150,12 +151,12 @@ static void CopyWorker(const void *key, const void *value, void *context) {
   if (!fields_) return nil;
   size_t count = CFDictionaryGetCount(fields_);
   ssize_t keys[count];
-  GPBField *values[count];
+  GPBUnknownField *values[count];
   CFDictionaryGetKeysAndValues(fields_, (const void **)keys,
                                (const void **)values);
   struct GPBFieldPair {
     ssize_t key;
-    GPBField *value;
+    GPBUnknownField *value;
   } pairs[count];
   for (size_t i = 0; i < count; ++i) {
     pairs[i].key = keys[i];
@@ -179,13 +180,13 @@ static void CopyWorker(const void *key, const void *value, void *context) {
   if (!fields_) return;
   size_t count = CFDictionaryGetCount(fields_);
   ssize_t keys[count];
-  GPBField *values[count];
+  GPBUnknownField *values[count];
   CFDictionaryGetKeysAndValues(fields_, (const void **)keys,
                                (const void **)values);
   if (count > 1) {
     struct GPBFieldPair {
       ssize_t key;
-      GPBField *value;
+      GPBUnknownField *value;
     } pairs[count];
 
     for (size_t i = 0; i < count; ++i) {
@@ -199,7 +200,7 @@ static void CopyWorker(const void *key, const void *value, void *context) {
               return (a->key > b->key) ? 1 : ((a->key == b->key) ? 0 : -1);
             });
     for (size_t i = 0; i < count; ++i) {
-      GPBField *value = pairs[i].value;
+      GPBUnknownField *value = pairs[i].value;
       [value writeToOutput:output];
     }
   } else {
@@ -219,7 +220,7 @@ static void CopyWorker(const void *key, const void *value, void *context) {
 static void GPBUnknownFieldSetSerializedSize(const void *key, const void *value,
                                              void *context) {
 #pragma unused(key)
-  GPBField *field = value;
+  GPBUnknownField *field = value;
   size_t *result = context;
   *result += [field serializedSize];
 }
@@ -237,7 +238,7 @@ static void GPBUnknownFieldSetWriteAsMessageSetTo(const void *key,
                                                   const void *value,
                                                   void *context) {
 #pragma unused(key)
-  GPBField *field = value;
+  GPBUnknownField *field = value;
   GPBCodedOutputStream *output = context;
   [field writeAsMessageSetExtensionToOutput:output];
 }
@@ -253,7 +254,7 @@ static void GPBUnknownFieldSetSerializedSizeAsMessageSet(const void *key,
                                                          const void *value,
                                                          void *context) {
 #pragma unused(key)
-  GPBField *field = value;
+  GPBUnknownField *field = value;
   size_t *result = context;
   *result += [field serializedSizeAsMessageSetExtension];
 }
@@ -280,7 +281,7 @@ static void GPBUnknownFieldSetSerializedSizeAsMessageSet(const void *key,
   return GPBWireFormatGetTagWireType(tag) != GPBWireFormatEndGroup;
 }
 
-- (void)addField:(GPBField *)field {
+- (void)addField:(GPBUnknownField *)field {
   int32_t number = [field number];
   checkNumber(number);
   if (!fields_) {
@@ -297,12 +298,12 @@ static void GPBUnknownFieldSetSerializedSizeAsMessageSet(const void *key,
   CFDictionarySetValue(fields_, (const void *)key, field);
 }
 
-- (GPBField *)mutableFieldForNumber:(int32_t)number create:(BOOL)create {
+- (GPBUnknownField *)mutableFieldForNumber:(int32_t)number create:(BOOL)create {
   ssize_t key = number;
-  GPBField *existing =
+  GPBUnknownField *existing =
       fields_ ? CFDictionaryGetValue(fields_, (const void *)key) : nil;
   if (!existing && create) {
-    existing = [[GPBField alloc] initWithNumber:number];
+    existing = [[GPBUnknownField alloc] initWithNumber:number];
     // This retains existing.
     [self addField:existing];
     [existing release];
@@ -314,19 +315,19 @@ static void GPBUnknownFieldSetMergeUnknownFields(const void *key,
                                                  const void *value,
                                                  void *context) {
 #pragma unused(key)
-  GPBField *field = value;
+  GPBUnknownField *field = value;
   GPBUnknownFieldSet *self = context;
 
   int32_t number = [field number];
   checkNumber(number);
-  GPBField *oldField = [self mutableFieldForNumber:number create:NO];
+  GPBUnknownField *oldField = [self mutableFieldForNumber:number create:NO];
   if (oldField) {
     [oldField mergeFromField:field];
   } else {
     // Merge only comes from GPBMessage's mergeFrom:, so it means we are on
     // mutable message and are an mutable instance, so make sure we need
     // mutable fields.
-    GPBField *fieldCopy = [field copy];
+    GPBUnknownField *fieldCopy = [field copy];
     [self addField:fieldCopy];
     [fieldCopy release];
   }
@@ -356,18 +357,18 @@ static void GPBUnknownFieldSetMergeUnknownFields(const void *key,
   GPBCodedInputStreamState *state = &input->state_;
   switch (GPBWireFormatGetTagWireType(tag)) {
     case GPBWireFormatVarint: {
-      GPBField *field = [self mutableFieldForNumber:number create:YES];
+      GPBUnknownField *field = [self mutableFieldForNumber:number create:YES];
       [field addVarint:GPBCodedInputStreamReadInt64(state)];
       return YES;
     }
     case GPBWireFormatFixed64: {
-      GPBField *field = [self mutableFieldForNumber:number create:YES];
+      GPBUnknownField *field = [self mutableFieldForNumber:number create:YES];
       [field addFixed64:GPBCodedInputStreamReadFixed64(state)];
       return YES;
     }
     case GPBWireFormatLengthDelimited: {
-      NSData *data = GPBCodedInputStreamReadRetainedData(state);
-      GPBField *field = [self mutableFieldForNumber:number create:YES];
+      NSData *data = GPBCodedInputStreamReadRetainedBytes(state);
+      GPBUnknownField *field = [self mutableFieldForNumber:number create:YES];
       [field addLengthDelimited:data];
       [data release];
       return YES;
@@ -375,7 +376,7 @@ static void GPBUnknownFieldSetMergeUnknownFields(const void *key,
     case GPBWireFormatStartGroup: {
       GPBUnknownFieldSet *unknownFieldSet = [[GPBUnknownFieldSet alloc] init];
       [input readUnknownGroup:number message:unknownFieldSet];
-      GPBField *field = [self mutableFieldForNumber:number create:YES];
+      GPBUnknownField *field = [self mutableFieldForNumber:number create:YES];
       [field addGroup:unknownFieldSet];
       [unknownFieldSet release];
       return YES;
@@ -383,7 +384,7 @@ static void GPBUnknownFieldSetMergeUnknownFields(const void *key,
     case GPBWireFormatEndGroup:
       return NO;
     case GPBWireFormatFixed32: {
-      GPBField *field = [self mutableFieldForNumber:number create:YES];
+      GPBUnknownField *field = [self mutableFieldForNumber:number create:YES];
       [field addFixed32:GPBCodedInputStreamReadFixed32(state)];
       return YES;
     }
@@ -396,7 +397,7 @@ static void GPBUnknownFieldSetMergeUnknownFields(const void *key,
 }
 
 - (void)addUnknownMapEntry:(int32_t)fieldNum value:(NSData *)data {
-  GPBField *field = [self mutableFieldForNumber:fieldNum create:YES];
+  GPBUnknownField *field = [self mutableFieldForNumber:fieldNum create:YES];
   [field addLengthDelimited:data];
 }
 

+ 3 - 3
objectivec/GPBField_PackagePrivate.h → objectivec/GPBUnknownField_PackagePrivate.h

@@ -30,11 +30,11 @@
 
 #import <Foundation/Foundation.h>
 
-#import "GPBField.h"
+#import "GPBUnknownField.h"
 
 @class GPBCodedOutputStream;
 
-@interface GPBField ()
+@interface GPBUnknownField ()
 
 - (instancetype)initWithNumber:(int32_t)number;
 
@@ -44,6 +44,6 @@
 - (void)writeAsMessageSetExtensionToOutput:(GPBCodedOutputStream *)output;
 - (size_t)serializedSizeAsMessageSetExtension;
 
-- (void)mergeFromField:(GPBField *)other;
+- (void)mergeFromField:(GPBUnknownField *)other;
 
 @end

+ 132 - 131
objectivec/GPBUtilities.h

@@ -30,152 +30,153 @@
 
 #import <Foundation/Foundation.h>
 
+#import "GPBArray.h"
 #import "GPBMessage.h"
-#import "GPBTypes.h"
+#import "GPBRuntimeTypes.h"
 
 CF_EXTERN_C_BEGIN
 
+// Generates a string that should be a valid "Text Format" for the C++ version
+// of Protocol Buffers. lineIndent can be nil if no additional line indent is
+// needed. The comments provide the names according to the ObjC library, they
+// most likely won't exactly match the original .proto file.
+NSString *GPBTextFormatForMessage(GPBMessage *message, NSString *lineIndent);
+NSString *GPBTextFormatForUnknownFieldSet(GPBUnknownFieldSet *unknownSet,
+                                          NSString *lineIndent);
+
+//
+// Test if the given field is set on a message.
+//
 BOOL GPBMessageHasFieldNumberSet(GPBMessage *self, uint32_t fieldNumber);
 BOOL GPBMessageHasFieldSet(GPBMessage *self, GPBFieldDescriptor *field);
 
+//
+// Clear the given field of a message.
+//
 void GPBClearMessageField(GPBMessage *self, GPBFieldDescriptor *field);
 
+//%PDDM-EXPAND GPB_ACCESSORS()
+// This block of code is generated, do not edit it directly.
+
+
+//
+// Get/Set the given field of a message.
+//
+
+// Single Fields
+
+NSData *GPBGetMessageBytesField(GPBMessage *self, GPBFieldDescriptor *field);
+void GPBSetMessageBytesField(GPBMessage *self, GPBFieldDescriptor *field, NSData *value);
+
+NSString *GPBGetMessageStringField(GPBMessage *self, GPBFieldDescriptor *field);
+void GPBSetMessageStringField(GPBMessage *self, GPBFieldDescriptor *field, NSString *value);
+
+GPBMessage *GPBGetMessageMessageField(GPBMessage *self, GPBFieldDescriptor *field);
+void GPBSetMessageMessageField(GPBMessage *self, GPBFieldDescriptor *field, GPBMessage *value);
+
+GPBMessage *GPBGetMessageGroupField(GPBMessage *self, GPBFieldDescriptor *field);
+void GPBSetMessageGroupField(GPBMessage *self, GPBFieldDescriptor *field, GPBMessage *value);
+
+BOOL GPBGetMessageBoolField(GPBMessage *self, GPBFieldDescriptor *field);
+void GPBSetMessageBoolField(GPBMessage *self, GPBFieldDescriptor *field, BOOL value);
+
+int32_t GPBGetMessageInt32Field(GPBMessage *self, GPBFieldDescriptor *field);
+void GPBSetMessageInt32Field(GPBMessage *self, GPBFieldDescriptor *field, int32_t value);
+
+uint32_t GPBGetMessageUInt32Field(GPBMessage *self, GPBFieldDescriptor *field);
+void GPBSetMessageUInt32Field(GPBMessage *self, GPBFieldDescriptor *field, uint32_t value);
+
+int64_t GPBGetMessageInt64Field(GPBMessage *self, GPBFieldDescriptor *field);
+void GPBSetMessageInt64Field(GPBMessage *self, GPBFieldDescriptor *field, int64_t value);
+
+uint64_t GPBGetMessageUInt64Field(GPBMessage *self, GPBFieldDescriptor *field);
+void GPBSetMessageUInt64Field(GPBMessage *self, GPBFieldDescriptor *field, uint64_t value);
+
+float GPBGetMessageFloatField(GPBMessage *self, GPBFieldDescriptor *field);
+void GPBSetMessageFloatField(GPBMessage *self, GPBFieldDescriptor *field, float value);
+
+double GPBGetMessageDoubleField(GPBMessage *self, GPBFieldDescriptor *field);
+void GPBSetMessageDoubleField(GPBMessage *self, GPBFieldDescriptor *field, double value);
+
+// Get/Set the given enum field of a message.  You can only Set values that are
+// members of the enum.  For proto3, when doing a Get, if the value isn't a
+// memeber of the enum, kGPBUnrecognizedEnumeratorValue will be returned. The
+// the functions with "Raw" in the will bypass all checks.
+int32_t GPBGetMessageEnumField(GPBMessage *self, GPBFieldDescriptor *field);
+void GPBSetMessageEnumField(GPBMessage *self, GPBFieldDescriptor *field, int32_t value);
+int32_t GPBGetMessageRawEnumField(GPBMessage *self, GPBFieldDescriptor *field);
+void GPBSetMessageRawEnumField(GPBMessage *self, GPBFieldDescriptor *field, int32_t value);
+
+// Repeated Fields
+
+// The object will/should be GPB*Array or NSMutableArray based on the field's
+// type.
+id GPBGetMessageRepeatedField(GPBMessage *self, GPBFieldDescriptor *field);
+void GPBSetMessageRepeatedField(GPBMessage *self, GPBFieldDescriptor *field, id array);
+
+// Map Fields
+
+// The object will/should be GPB*Dictionary or NSMutableDictionary based on the
+// field's type.
+id GPBGetMessageMapField(GPBMessage *self, GPBFieldDescriptor *field);
+void GPBSetMessageMapField(GPBMessage *self, GPBFieldDescriptor *field, id dictionary);
+
+//%PDDM-EXPAND-END GPB_ACCESSORS()
+
 // Returns an empty NSData to assign to byte fields when you wish
 // to assign them to empty. Prevents allocating a lot of little [NSData data]
 // objects.
 NSData *GPBEmptyNSData(void) __attribute__((pure));
 
-//%PDDM-EXPAND GPB_IVAR_ACCESSORS()
-// This block of code is generated, do not edit it directly.
+CF_EXTERN_C_END
 
-// Getters and Setters for ivars named |name| from instance self.
-
-NSData* GPBGetDataIvarWithField(GPBMessage *self,
-                                GPBFieldDescriptor *field);
-void GPBSetDataIvarWithField(GPBMessage *self,
-                             GPBFieldDescriptor *field,
-                             NSData* value);
-NSString* GPBGetStringIvarWithField(GPBMessage *self,
-                                    GPBFieldDescriptor *field);
-void GPBSetStringIvarWithField(GPBMessage *self,
-                               GPBFieldDescriptor *field,
-                               NSString* value);
-GPBMessage* GPBGetMessageIvarWithField(GPBMessage *self,
-                                       GPBFieldDescriptor *field);
-void GPBSetMessageIvarWithField(GPBMessage *self,
-                                GPBFieldDescriptor *field,
-                                GPBMessage* value);
-GPBMessage* GPBGetGroupIvarWithField(GPBMessage *self,
-                                     GPBFieldDescriptor *field);
-void GPBSetGroupIvarWithField(GPBMessage *self,
-                              GPBFieldDescriptor *field,
-                              GPBMessage* value);
-BOOL GPBGetBoolIvarWithField(GPBMessage *self,
-                             GPBFieldDescriptor *field);
-void GPBSetBoolIvarWithField(GPBMessage *self,
-                             GPBFieldDescriptor *field,
-                             BOOL value);
-int32_t GPBGetInt32IvarWithField(GPBMessage *self,
-                                 GPBFieldDescriptor *field);
-void GPBSetInt32IvarWithField(GPBMessage *self,
-                              GPBFieldDescriptor *field,
-                              int32_t value);
-int32_t GPBGetSFixed32IvarWithField(GPBMessage *self,
-                                    GPBFieldDescriptor *field);
-void GPBSetSFixed32IvarWithField(GPBMessage *self,
-                                 GPBFieldDescriptor *field,
-                                 int32_t value);
-int32_t GPBGetSInt32IvarWithField(GPBMessage *self,
-                                  GPBFieldDescriptor *field);
-void GPBSetSInt32IvarWithField(GPBMessage *self,
-                               GPBFieldDescriptor *field,
-                               int32_t value);
-int32_t GPBGetEnumIvarWithField(GPBMessage *self,
-                                GPBFieldDescriptor *field);
-void GPBSetEnumIvarWithField(GPBMessage *self,
-                             GPBFieldDescriptor *field,
-                             int32_t value);
-uint32_t GPBGetUInt32IvarWithField(GPBMessage *self,
-                                   GPBFieldDescriptor *field);
-void GPBSetUInt32IvarWithField(GPBMessage *self,
-                               GPBFieldDescriptor *field,
-                               uint32_t value);
-uint32_t GPBGetFixed32IvarWithField(GPBMessage *self,
-                                    GPBFieldDescriptor *field);
-void GPBSetFixed32IvarWithField(GPBMessage *self,
-                                GPBFieldDescriptor *field,
-                                uint32_t value);
-int64_t GPBGetInt64IvarWithField(GPBMessage *self,
-                                 GPBFieldDescriptor *field);
-void GPBSetInt64IvarWithField(GPBMessage *self,
-                              GPBFieldDescriptor *field,
-                              int64_t value);
-int64_t GPBGetSInt64IvarWithField(GPBMessage *self,
-                                  GPBFieldDescriptor *field);
-void GPBSetSInt64IvarWithField(GPBMessage *self,
-                               GPBFieldDescriptor *field,
-                               int64_t value);
-int64_t GPBGetSFixed64IvarWithField(GPBMessage *self,
-                                    GPBFieldDescriptor *field);
-void GPBSetSFixed64IvarWithField(GPBMessage *self,
-                                 GPBFieldDescriptor *field,
-                                 int64_t value);
-uint64_t GPBGetUInt64IvarWithField(GPBMessage *self,
-                                   GPBFieldDescriptor *field);
-void GPBSetUInt64IvarWithField(GPBMessage *self,
-                               GPBFieldDescriptor *field,
-                               uint64_t value);
-uint64_t GPBGetFixed64IvarWithField(GPBMessage *self,
-                                    GPBFieldDescriptor *field);
-void GPBSetFixed64IvarWithField(GPBMessage *self,
-                                GPBFieldDescriptor *field,
-                                uint64_t value);
-float GPBGetFloatIvarWithField(GPBMessage *self,
-                               GPBFieldDescriptor *field);
-void GPBSetFloatIvarWithField(GPBMessage *self,
-                              GPBFieldDescriptor *field,
-                              float value);
-double GPBGetDoubleIvarWithField(GPBMessage *self,
-                                 GPBFieldDescriptor *field);
-void GPBSetDoubleIvarWithField(GPBMessage *self,
-                               GPBFieldDescriptor *field,
-                               double value);
-//%PDDM-EXPAND-END GPB_IVAR_ACCESSORS()
-
-// Generates a sting that should be a valid "Text Format" for the C++ version
-// of Protocol Buffers. lineIndent can be nil if no additional line indent is
-// needed. The comments provide the names according to the ObjC library, they
-// most likely won't exactly match the original .proto file.
-NSString *GPBTextFormatForMessage(GPBMessage *message, NSString *lineIndent);
-NSString *GPBTextFormatForUnknownFieldSet(GPBUnknownFieldSet *unknownSet,
-                                          NSString *lineIndent);
 
-CF_EXTERN_C_END
+//%PDDM-DEFINE GPB_ACCESSORS()
+//%
+//%//
+//%// Get/Set the given field of a message.
+//%//
+//%
+//%// Single Fields
+//%
+//%GPB_ACCESSOR_SINGLE_FULL(Bytes, NSData, *)
+//%GPB_ACCESSOR_SINGLE_FULL(String, NSString, *)
+//%GPB_ACCESSOR_SINGLE_FULL(Message, GPBMessage, *)
+//%GPB_ACCESSOR_SINGLE_FULL(Group, GPBMessage, *)
+//%GPB_ACCESSOR_SINGLE(Bool, BOOL)
+//%GPB_ACCESSOR_SINGLE(Int32, int32_t)
+//%GPB_ACCESSOR_SINGLE(UInt32, uint32_t)
+//%GPB_ACCESSOR_SINGLE(Int64, int64_t)
+//%GPB_ACCESSOR_SINGLE(UInt64, uint64_t)
+//%GPB_ACCESSOR_SINGLE(Float, float)
+//%GPB_ACCESSOR_SINGLE(Double, double)
+//%// Get/Set the given enum field of a message.  You can only Set values that are
+//%// members of the enum.  For proto3, when doing a Get, if the value isn't a
+//%// memeber of the enum, kGPBUnrecognizedEnumeratorValue will be returned. The
+//%// the functions with "Raw" in the will bypass all checks.
+//%int32_t GPBGetMessageEnumField(GPBMessage *self, GPBFieldDescriptor *field);
+//%void GPBSetMessageEnumField(GPBMessage *self, GPBFieldDescriptor *field, int32_t value);
+//%int32_t GPBGetMessageRawEnumField(GPBMessage *self, GPBFieldDescriptor *field);
+//%void GPBSetMessageRawEnumField(GPBMessage *self, GPBFieldDescriptor *field, int32_t value);
+//%
+//%// Repeated Fields
+//%
+//%// The object will/should be GPB*Array or NSMutableArray based on the field's
+//%// type.
+//%id GPBGetMessageRepeatedField(GPBMessage *self, GPBFieldDescriptor *field);
+//%void GPBSetMessageRepeatedField(GPBMessage *self, GPBFieldDescriptor *field, id array);
+//%
+//%// Map Fields
+//%
+//%// The object will/should be GPB*Dictionary or NSMutableDictionary based on the
+//%// field's type.
+//%id GPBGetMessageMapField(GPBMessage *self, GPBFieldDescriptor *field);
+//%void GPBSetMessageMapField(GPBMessage *self, GPBFieldDescriptor *field, id dictionary);
+//%
 
-//%PDDM-DEFINE GPB_IVAR_ACCESSORS()
-//%// Getters and Setters for ivars named |name| from instance self.
+//%PDDM-DEFINE GPB_ACCESSOR_SINGLE(NAME, TYPE)
+//%GPB_ACCESSOR_SINGLE_FULL(NAME, TYPE, )
+//%PDDM-DEFINE GPB_ACCESSOR_SINGLE_FULL(NAME, TYPE, TisP)
+//%TYPE TisP##GPBGetMessage##NAME##Field(GPBMessage *self, GPBFieldDescriptor *field);
+//%void GPBSetMessage##NAME##Field(GPBMessage *self, GPBFieldDescriptor *field, TYPE TisP##value);
 //%
-//%GPB_IVAR_ACCESSORS_DECL(Data, NSData*)
-//%GPB_IVAR_ACCESSORS_DECL(String, NSString*)
-//%GPB_IVAR_ACCESSORS_DECL(Message, GPBMessage*)
-//%GPB_IVAR_ACCESSORS_DECL(Group, GPBMessage*)
-//%GPB_IVAR_ACCESSORS_DECL(Bool, BOOL)
-//%GPB_IVAR_ACCESSORS_DECL(Int32, int32_t)
-//%GPB_IVAR_ACCESSORS_DECL(SFixed32, int32_t)
-//%GPB_IVAR_ACCESSORS_DECL(SInt32, int32_t)
-//%GPB_IVAR_ACCESSORS_DECL(Enum, int32_t)
-//%GPB_IVAR_ACCESSORS_DECL(UInt32, uint32_t)
-//%GPB_IVAR_ACCESSORS_DECL(Fixed32, uint32_t)
-//%GPB_IVAR_ACCESSORS_DECL(Int64, int64_t)
-//%GPB_IVAR_ACCESSORS_DECL(SInt64, int64_t)
-//%GPB_IVAR_ACCESSORS_DECL(SFixed64, int64_t)
-//%GPB_IVAR_ACCESSORS_DECL(UInt64, uint64_t)
-//%GPB_IVAR_ACCESSORS_DECL(Fixed64, uint64_t)
-//%GPB_IVAR_ACCESSORS_DECL(Float, float)
-//%GPB_IVAR_ACCESSORS_DECL(Double, double)
-//%PDDM-DEFINE GPB_IVAR_ACCESSORS_DECL(NAME, TYPE)
-//%TYPE GPBGet##NAME##IvarWithField(GPBMessage *self,
-//% TYPE$S     NAME$S               GPBFieldDescriptor *field);
-//%void GPBSet##NAME##IvarWithField(GPBMessage *self,
-//%            NAME$S             GPBFieldDescriptor *field,
-//%            NAME$S             TYPE value);

Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 307 - 283
objectivec/GPBUtilities.m


+ 25 - 120
objectivec/GPBUtilities_PackagePrivate.h

@@ -48,6 +48,15 @@
 
 CF_EXTERN_C_BEGIN
 
+// These two are used to inject a runtime check for version mismatch into the
+// generated sources to make sure they are linked with a supporting runtime.
+void GPBCheckRuntimeVersionInternal(int32_t version);
+GPB_INLINE void GPBDebugCheckRuntimeVersion() {
+#if DEBUG
+  GPBCheckRuntimeVersionInternal(GOOGLE_PROTOBUF_OBJC_GEN_VERSION);
+#endif
+}
+
 // Conversion functions for de/serializing floating point types.
 
 GPB_INLINE int64_t GPBConvertDoubleToInt64(double v) {
@@ -116,40 +125,38 @@ GPB_INLINE uint64_t GPBEncodeZigZag64(int64_t n) {
   return (n << 1) ^ (n >> 63);
 }
 
-GPB_INLINE BOOL GPBTypeIsObject(GPBType type) {
+GPB_INLINE BOOL GPBDataTypeIsObject(GPBDataType type) {
   switch (type) {
-    case GPBTypeData:
-    case GPBTypeString:
-    case GPBTypeMessage:
-    case GPBTypeGroup:
+    case GPBDataTypeBytes:
+    case GPBDataTypeString:
+    case GPBDataTypeMessage:
+    case GPBDataTypeGroup:
       return YES;
     default:
       return NO;
   }
 }
 
-GPB_INLINE BOOL GPBTypeIsMessage(GPBType type) {
+GPB_INLINE BOOL GPBDataTypeIsMessage(GPBDataType type) {
   switch (type) {
-    case GPBTypeMessage:
-    case GPBTypeGroup:
+    case GPBDataTypeMessage:
+    case GPBDataTypeGroup:
       return YES;
     default:
       return NO;
   }
 }
 
-GPB_INLINE BOOL GPBTypeIsEnum(GPBType type) { return type == GPBTypeEnum; }
-
-GPB_INLINE BOOL GPBFieldTypeIsMessage(GPBFieldDescriptor *field) {
-  return GPBTypeIsMessage(field->description_->type);
+GPB_INLINE BOOL GPBFieldDataTypeIsMessage(GPBFieldDescriptor *field) {
+  return GPBDataTypeIsMessage(field->description_->dataType);
 }
 
-GPB_INLINE BOOL GPBFieldTypeIsObject(GPBFieldDescriptor *field) {
-  return GPBTypeIsObject(field->description_->type);
+GPB_INLINE BOOL GPBFieldDataTypeIsObject(GPBFieldDescriptor *field) {
+  return GPBDataTypeIsObject(field->description_->dataType);
 }
 
 GPB_INLINE BOOL GPBExtensionIsMessage(GPBExtensionDescriptor *ext) {
-  return GPBTypeIsMessage(ext->description_->type);
+  return GPBDataTypeIsMessage(ext->description_->dataType);
 }
 
 // The field is an array/map or it has an object value.
@@ -158,7 +165,7 @@ GPB_INLINE BOOL GPBFieldStoresObject(GPBFieldDescriptor *field) {
   if ((desc->flags & (GPBFieldRepeated | GPBFieldMapKeyMask)) != 0) {
     return YES;
   }
-  return GPBTypeIsObject(desc->type);
+  return GPBDataTypeIsObject(desc->dataType);
 }
 
 BOOL GPBGetHasIvar(GPBMessage *self, int32_t index, uint32_t fieldNumber);
@@ -272,109 +279,6 @@ void GPBSetAutocreatedRetainedObjectIvarWithField(
 void GPBClearAutocreatedMessageIvarWithField(GPBMessage *self,
                                              GPBFieldDescriptor *field);
 
-// Utilities for applying various functions based on Objective C types.
-
-// A basic functor that is passed a field and a context. Returns YES
-// if the calling function should continue processing, and NO if the calling
-// function should stop processing.
-typedef BOOL (*GPBApplyFunction)(GPBFieldDescriptor *field, void *context);
-
-// Functions called for various types. See ApplyFunctionsToMessageFields.
-typedef enum {
-  GPBApplyFunctionObject,
-  GPBApplyFunctionBool,
-  GPBApplyFunctionInt32,
-  GPBApplyFunctionUInt32,
-  GPBApplyFunctionInt64,
-  GPBApplyFunctionUInt64,
-  GPBApplyFunctionFloat,
-  GPBApplyFunctionDouble,
-} GPBApplyFunctionOrder;
-
-enum {
-  // A count of the number of types in GPBApplyFunctionOrder. Separated out
-  // from the GPBApplyFunctionOrder enum to avoid warnings regarding not
-  // handling GPBApplyFunctionCount in switch statements.
-  GPBApplyFunctionCount = GPBApplyFunctionDouble + 1
-};
-
-typedef GPBApplyFunction GPBApplyFunctions[GPBApplyFunctionCount];
-
-// Functions called for various types.
-// See ApplyStrictFunctionsToMessageFields.
-// They are in the same order as the GPBTypes enum.
-typedef GPBApplyFunction GPBApplyStrictFunctions[GPBTypeCount];
-
-// A macro for easily initializing a GPBApplyFunctions struct
-// GPBApplyFunctions foo = GPBAPPLY_FUNCTIONS_INIT(Foo);
-#define GPBAPPLY_FUNCTIONS_INIT(PREFIX) \
-  { \
-    PREFIX##Object,  \
-    PREFIX##Bool,    \
-    PREFIX##Int32,   \
-    PREFIX##UInt32,  \
-    PREFIX##Int64,   \
-    PREFIX##UInt64,  \
-    PREFIX##Float,   \
-    PREFIX##Double,  \
-  }
-
-// A macro for easily initializing a GPBApplyStrictFunctions struct
-// GPBApplyStrictFunctions foo = GPBAPPLY_STRICT_FUNCTIONS_INIT(Foo);
-// These need to stay in the same order as
-// the GPBType enum.
-#define GPBAPPLY_STRICT_FUNCTIONS_INIT(PREFIX) \
-  { \
-    PREFIX##Bool,     \
-    PREFIX##Fixed32,  \
-    PREFIX##SFixed32, \
-    PREFIX##Float,    \
-    PREFIX##Fixed64,  \
-    PREFIX##SFixed64, \
-    PREFIX##Double,   \
-    PREFIX##Int32,    \
-    PREFIX##Int64,    \
-    PREFIX##SInt32,   \
-    PREFIX##SInt64,   \
-    PREFIX##UInt32,   \
-    PREFIX##UInt64,   \
-    PREFIX##Data,     \
-    PREFIX##String,   \
-    PREFIX##Message,  \
-    PREFIX##Group,    \
-    PREFIX##Enum,     \
-}
-
-// Iterates over the fields of a proto |msg| and applies the functions in
-// |functions| to them with |context|. If one of the functions in |functions|
-// returns NO, it will return immediately and not process the rest of the
-// ivars. The types in the fields are mapped so:
-// Int32, Enum, SInt32 and SFixed32 will be mapped to the int32Function,
-// UInt32 and Fixed32 will be mapped to the uint32Function,
-// Bytes, String, Message and Group will be mapped to the objectFunction,
-// etc..
-// If you require more specific mappings look at
-// GPBApplyStrictFunctionsToMessageFields.
-void GPBApplyFunctionsToMessageFields(GPBApplyFunctions *functions,
-                                      GPBMessage *msg, void *context);
-
-// Iterates over the fields of a proto |msg| and applies the functions in
-// |functions| to them with |context|. If one of the functions in |functions|
-// returns NO, it will return immediately and not process the rest of the
-// ivars. The types in the fields are mapped directly:
-// Int32 -> functions[GPBTypeInt32],
-// SFixed32 -> functions[GPBTypeSFixed32],
-// etc...
-// If you can use looser mappings look at GPBApplyFunctionsToMessageFields.
-void GPBApplyStrictFunctionsToMessageFields(GPBApplyStrictFunctions *functions,
-                                            GPBMessage *msg, void *context);
-
-// Applies the appropriate function in |functions| based on |field|.
-// Returns the value from function(name, context).
-// Throws an exception if the type is unrecognized.
-BOOL GPBApplyFunctionsBasedOnField(GPBFieldDescriptor *field,
-                                   GPBApplyFunctions *functions, void *context);
-
 // Returns an Objective C encoding for |selector|. |instanceSel| should be
 // YES if it's an instance selector (as opposed to a class selector).
 // |selector| must be a selector from MessageSignatureProtocol.
@@ -410,7 +314,7 @@ GPB_MESSAGE_SIGNATURE_ENTRY(int32_t, SInt32)
 GPB_MESSAGE_SIGNATURE_ENTRY(int64_t, SInt64)
 GPB_MESSAGE_SIGNATURE_ENTRY(uint32_t, UInt32)
 GPB_MESSAGE_SIGNATURE_ENTRY(uint64_t, UInt64)
-GPB_MESSAGE_SIGNATURE_ENTRY(NSData *, Data)
+GPB_MESSAGE_SIGNATURE_ENTRY(NSData *, Bytes)
 GPB_MESSAGE_SIGNATURE_ENTRY(NSString *, String)
 GPB_MESSAGE_SIGNATURE_ENTRY(GPBMessage *, Message)
 GPB_MESSAGE_SIGNATURE_ENTRY(GPBMessage *, Group)
@@ -419,6 +323,7 @@ GPB_MESSAGE_SIGNATURE_ENTRY(int32_t, Enum)
 #undef GPB_MESSAGE_SIGNATURE_ENTRY
 
 - (id)getArray;
+- (NSUInteger)getArrayCount;
 - (void)setArray:(NSArray *)array;
 + (id)getClassValue;
 @end

+ 2 - 2
objectivec/GPBWireFormat.h

@@ -28,7 +28,7 @@
 // (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 "GPBTypes.h"
+#import "GPBRuntimeTypes.h"
 
 CF_EXTERN_C_BEGIN
 
@@ -52,7 +52,7 @@ uint32_t GPBWireFormatMakeTag(uint32_t fieldNumber, GPBWireFormat wireType)
 GPBWireFormat GPBWireFormatGetTagWireType(uint32_t tag) __attribute__((const));
 uint32_t GPBWireFormatGetTagFieldNumber(uint32_t tag) __attribute__((const));
 
-GPBWireFormat GPBWireFormatForType(GPBType type, BOOL isPacked)
+GPBWireFormat GPBWireFormatForType(GPBDataType dataType, BOOL isPacked)
     __attribute__((const));
 
 #define GPBWireFormatMessageSetItemTag \

+ 20 - 20
objectivec/GPBWireFormat.m

@@ -49,30 +49,30 @@ uint32_t GPBWireFormatGetTagFieldNumber(uint32_t tag) {
   return GPBLogicalRightShift32(tag, GPBWireFormatTagTypeBits);
 }
 
-GPBWireFormat GPBWireFormatForType(GPBType type, BOOL isPacked) {
+GPBWireFormat GPBWireFormatForType(GPBDataType type, BOOL isPacked) {
   if (isPacked) {
     return GPBWireFormatLengthDelimited;
   }
 
-  static const GPBWireFormat format[GPBTypeCount] = {
-      GPBWireFormatVarint,           // GPBTypeBool
-      GPBWireFormatFixed32,          // GPBTypeFixed32
-      GPBWireFormatFixed32,          // GPBTypeSFixed32
-      GPBWireFormatFixed32,          // GPBTypeFloat
-      GPBWireFormatFixed64,          // GPBTypeFixed64
-      GPBWireFormatFixed64,          // GPBTypeSFixed64
-      GPBWireFormatFixed64,          // GPBTypeDouble
-      GPBWireFormatVarint,           // GPBTypeInt32
-      GPBWireFormatVarint,           // GPBTypeInt64
-      GPBWireFormatVarint,           // GPBTypeSInt32
-      GPBWireFormatVarint,           // GPBTypeSInt64
-      GPBWireFormatVarint,           // GPBTypeUInt32
-      GPBWireFormatVarint,           // GPBTypeUInt64
-      GPBWireFormatLengthDelimited,  // GPBTypeBytes
-      GPBWireFormatLengthDelimited,  // GPBTypeString
-      GPBWireFormatLengthDelimited,  // GPBTypeMessage
-      GPBWireFormatStartGroup,       // GPBTypeGroup
-      GPBWireFormatVarint            // GPBTypeEnum
+  static const GPBWireFormat format[GPBDataType_Count] = {
+      GPBWireFormatVarint,           // GPBDataTypeBool
+      GPBWireFormatFixed32,          // GPBDataTypeFixed32
+      GPBWireFormatFixed32,          // GPBDataTypeSFixed32
+      GPBWireFormatFixed32,          // GPBDataTypeFloat
+      GPBWireFormatFixed64,          // GPBDataTypeFixed64
+      GPBWireFormatFixed64,          // GPBDataTypeSFixed64
+      GPBWireFormatFixed64,          // GPBDataTypeDouble
+      GPBWireFormatVarint,           // GPBDataTypeInt32
+      GPBWireFormatVarint,           // GPBDataTypeInt64
+      GPBWireFormatVarint,           // GPBDataTypeSInt32
+      GPBWireFormatVarint,           // GPBDataTypeSInt64
+      GPBWireFormatVarint,           // GPBDataTypeUInt32
+      GPBWireFormatVarint,           // GPBDataTypeUInt64
+      GPBWireFormatLengthDelimited,  // GPBDataTypeBytes
+      GPBWireFormatLengthDelimited,  // GPBDataTypeString
+      GPBWireFormatLengthDelimited,  // GPBDataTypeMessage
+      GPBWireFormatStartGroup,       // GPBDataTypeGroup
+      GPBWireFormatVarint            // GPBDataTypeEnum
   };
   return format[type];
 }

Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 109 - 93
objectivec/ProtocolBuffers_OSX.xcodeproj/project.pbxproj


+ 213 - 6
objectivec/ProtocolBuffers_OSX.xcodeproj/xcshareddata/xcschemes/PerformanceTests.xcscheme

@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <Scheme
-   LastUpgradeVersion = "0620"
+   LastUpgradeVersion = "0630"
    version = "1.3">
    <BuildAction
       parallelizeBuildables = "YES"
@@ -38,9 +38,6 @@
                ReferencedContainer = "container:ProtocolBuffers_OSX.xcodeproj">
             </BuildableReference>
             <SkippedTests>
-               <Test
-                  Identifier = "ArrayTests">
-               </Test>
                <Test
                   Identifier = "CodedInputStreamTests">
                </Test>
@@ -51,16 +48,223 @@
                   Identifier = "ConcurrencyTests">
                </Test>
                <Test
-                  Identifier = "FilteredMessageTests">
+                  Identifier = "DescriptorTests">
+               </Test>
+               <Test
+                  Identifier = "GPBBoolArrayTests">
+               </Test>
+               <Test
+                  Identifier = "GPBBoolBoolDictionaryTests">
+               </Test>
+               <Test
+                  Identifier = "GPBBoolDoubleDictionaryTests">
+               </Test>
+               <Test
+                  Identifier = "GPBBoolFloatDictionaryTests">
+               </Test>
+               <Test
+                  Identifier = "GPBBoolInt32DictionaryTests">
+               </Test>
+               <Test
+                  Identifier = "GPBBoolInt64DictionaryTests">
+               </Test>
+               <Test
+                  Identifier = "GPBBoolObjectDictionaryTests">
+               </Test>
+               <Test
+                  Identifier = "GPBBoolUInt32DictionaryTests">
+               </Test>
+               <Test
+                  Identifier = "GPBBoolUInt64DictionaryTests">
+               </Test>
+               <Test
+                  Identifier = "GPBBridgeTests">
+               </Test>
+               <Test
+                  Identifier = "GPBDoubleArrayTests">
+               </Test>
+               <Test
+                  Identifier = "GPBEnumArrayCustomTests">
+               </Test>
+               <Test
+                  Identifier = "GPBEnumArrayTests">
+               </Test>
+               <Test
+                  Identifier = "GPBFloatArrayTests">
+               </Test>
+               <Test
+                  Identifier = "GPBInt32ArrayTests">
+               </Test>
+               <Test
+                  Identifier = "GPBInt32BoolDictionaryTests">
+               </Test>
+               <Test
+                  Identifier = "GPBInt32DoubleDictionaryTests">
+               </Test>
+               <Test
+                  Identifier = "GPBInt32EnumDictionaryTests">
+               </Test>
+               <Test
+                  Identifier = "GPBInt32EnumDictionaryUnknownEnumTests">
+               </Test>
+               <Test
+                  Identifier = "GPBInt32FloatDictionaryTests">
+               </Test>
+               <Test
+                  Identifier = "GPBInt32Int32DictionaryTests">
+               </Test>
+               <Test
+                  Identifier = "GPBInt32Int64DictionaryTests">
+               </Test>
+               <Test
+                  Identifier = "GPBInt32ObjectDictionaryTests">
+               </Test>
+               <Test
+                  Identifier = "GPBInt32UInt32DictionaryTests">
+               </Test>
+               <Test
+                  Identifier = "GPBInt32UInt64DictionaryTests">
+               </Test>
+               <Test
+                  Identifier = "GPBInt64ArrayTests">
+               </Test>
+               <Test
+                  Identifier = "GPBInt64BoolDictionaryTests">
+               </Test>
+               <Test
+                  Identifier = "GPBInt64DoubleDictionaryTests">
+               </Test>
+               <Test
+                  Identifier = "GPBInt64EnumDictionaryTests">
+               </Test>
+               <Test
+                  Identifier = "GPBInt64EnumDictionaryUnknownEnumTests">
+               </Test>
+               <Test
+                  Identifier = "GPBInt64FloatDictionaryTests">
+               </Test>
+               <Test
+                  Identifier = "GPBInt64Int32DictionaryTests">
+               </Test>
+               <Test
+                  Identifier = "GPBInt64Int64DictionaryTests">
+               </Test>
+               <Test
+                  Identifier = "GPBInt64ObjectDictionaryTests">
+               </Test>
+               <Test
+                  Identifier = "GPBInt64UInt32DictionaryTests">
+               </Test>
+               <Test
+                  Identifier = "GPBInt64UInt64DictionaryTests">
+               </Test>
+               <Test
+                  Identifier = "GPBStringBoolDictionaryTests">
+               </Test>
+               <Test
+                  Identifier = "GPBStringDoubleDictionaryTests">
+               </Test>
+               <Test
+                  Identifier = "GPBStringEnumDictionaryTests">
+               </Test>
+               <Test
+                  Identifier = "GPBStringEnumDictionaryUnknownEnumTests">
+               </Test>
+               <Test
+                  Identifier = "GPBStringFloatDictionaryTests">
+               </Test>
+               <Test
+                  Identifier = "GPBStringInt32DictionaryTests">
+               </Test>
+               <Test
+                  Identifier = "GPBStringInt64DictionaryTests">
                </Test>
                <Test
                   Identifier = "GPBStringTests">
                </Test>
+               <Test
+                  Identifier = "GPBStringUInt32DictionaryTests">
+               </Test>
+               <Test
+                  Identifier = "GPBStringUInt64DictionaryTests">
+               </Test>
                <Test
                   Identifier = "GPBTestCase">
                </Test>
                <Test
-                  Identifier = "GeneratedMessageTests">
+                  Identifier = "GPBUInt32ArrayTests">
+               </Test>
+               <Test
+                  Identifier = "GPBUInt32BoolDictionaryTests">
+               </Test>
+               <Test
+                  Identifier = "GPBUInt32DoubleDictionaryTests">
+               </Test>
+               <Test
+                  Identifier = "GPBUInt32EnumDictionaryTests">
+               </Test>
+               <Test
+                  Identifier = "GPBUInt32EnumDictionaryUnknownEnumTests">
+               </Test>
+               <Test
+                  Identifier = "GPBUInt32FloatDictionaryTests">
+               </Test>
+               <Test
+                  Identifier = "GPBUInt32Int32DictionaryTests">
+               </Test>
+               <Test
+                  Identifier = "GPBUInt32Int64DictionaryTests">
+               </Test>
+               <Test
+                  Identifier = "GPBUInt32ObjectDictionaryTests">
+               </Test>
+               <Test
+                  Identifier = "GPBUInt32UInt32DictionaryTests">
+               </Test>
+               <Test
+                  Identifier = "GPBUInt32UInt64DictionaryTests">
+               </Test>
+               <Test
+                  Identifier = "GPBUInt64ArrayTests">
+               </Test>
+               <Test
+                  Identifier = "GPBUInt64BoolDictionaryTests">
+               </Test>
+               <Test
+                  Identifier = "GPBUInt64DoubleDictionaryTests">
+               </Test>
+               <Test
+                  Identifier = "GPBUInt64EnumDictionaryTests">
+               </Test>
+               <Test
+                  Identifier = "GPBUInt64EnumDictionaryUnknownEnumTests">
+               </Test>
+               <Test
+                  Identifier = "GPBUInt64FloatDictionaryTests">
+               </Test>
+               <Test
+                  Identifier = "GPBUInt64Int32DictionaryTests">
+               </Test>
+               <Test
+                  Identifier = "GPBUInt64Int64DictionaryTests">
+               </Test>
+               <Test
+                  Identifier = "GPBUInt64ObjectDictionaryTests">
+               </Test>
+               <Test
+                  Identifier = "GPBUInt64UInt32DictionaryTests">
+               </Test>
+               <Test
+                  Identifier = "GPBUInt64UInt64DictionaryTests">
+               </Test>
+               <Test
+                  Identifier = "MessageMergeTests">
+               </Test>
+               <Test
+                  Identifier = "MessageRuntimeTests">
+               </Test>
+               <Test
+                  Identifier = "MessageSerializationTests">
                </Test>
                <Test
                   Identifier = "MessageTests">
@@ -71,6 +275,9 @@
                <Test
                   Identifier = "UtilitiesTests">
                </Test>
+               <Test
+                  Identifier = "WellKnownTypesTest">
+               </Test>
                <Test
                   Identifier = "WireFormatTests">
                </Test>

+ 1 - 1
objectivec/ProtocolBuffers_OSX.xcodeproj/xcshareddata/xcschemes/ProtocolBuffers.xcscheme

@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <Scheme
-   LastUpgradeVersion = "0620"
+   LastUpgradeVersion = "0630"
    version = "1.3">
    <BuildAction
       parallelizeBuildables = "YES"

Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 113 - 97
objectivec/ProtocolBuffers_iOS.xcodeproj/project.pbxproj


+ 215 - 7
objectivec/ProtocolBuffers_iOS.xcodeproj/xcshareddata/xcschemes/PerformanceTests.xcscheme

@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <Scheme
-   LastUpgradeVersion = "0610"
+   LastUpgradeVersion = "0630"
    version = "1.3">
    <BuildAction
       parallelizeBuildables = "YES"
@@ -38,9 +38,6 @@
                ReferencedContainer = "container:ProtocolBuffers_iOS.xcodeproj">
             </BuildableReference>
             <SkippedTests>
-               <Test
-                  Identifier = "ArrayTests">
-               </Test>
                <Test
                   Identifier = "CodedInputStreamTests">
                </Test>
@@ -51,16 +48,223 @@
                   Identifier = "ConcurrencyTests">
                </Test>
                <Test
-                  Identifier = "FilteredMessageTests">
+                  Identifier = "DescriptorTests">
+               </Test>
+               <Test
+                  Identifier = "GPBBoolArrayTests">
+               </Test>
+               <Test
+                  Identifier = "GPBBoolBoolDictionaryTests">
+               </Test>
+               <Test
+                  Identifier = "GPBBoolDoubleDictionaryTests">
+               </Test>
+               <Test
+                  Identifier = "GPBBoolFloatDictionaryTests">
+               </Test>
+               <Test
+                  Identifier = "GPBBoolInt32DictionaryTests">
+               </Test>
+               <Test
+                  Identifier = "GPBBoolInt64DictionaryTests">
+               </Test>
+               <Test
+                  Identifier = "GPBBoolObjectDictionaryTests">
+               </Test>
+               <Test
+                  Identifier = "GPBBoolUInt32DictionaryTests">
+               </Test>
+               <Test
+                  Identifier = "GPBBoolUInt64DictionaryTests">
+               </Test>
+               <Test
+                  Identifier = "GPBBridgeTests">
+               </Test>
+               <Test
+                  Identifier = "GPBDoubleArrayTests">
+               </Test>
+               <Test
+                  Identifier = "GPBEnumArrayCustomTests">
+               </Test>
+               <Test
+                  Identifier = "GPBEnumArrayTests">
+               </Test>
+               <Test
+                  Identifier = "GPBFloatArrayTests">
+               </Test>
+               <Test
+                  Identifier = "GPBInt32ArrayTests">
+               </Test>
+               <Test
+                  Identifier = "GPBInt32BoolDictionaryTests">
+               </Test>
+               <Test
+                  Identifier = "GPBInt32DoubleDictionaryTests">
+               </Test>
+               <Test
+                  Identifier = "GPBInt32EnumDictionaryTests">
+               </Test>
+               <Test
+                  Identifier = "GPBInt32EnumDictionaryUnknownEnumTests">
+               </Test>
+               <Test
+                  Identifier = "GPBInt32FloatDictionaryTests">
+               </Test>
+               <Test
+                  Identifier = "GPBInt32Int32DictionaryTests">
+               </Test>
+               <Test
+                  Identifier = "GPBInt32Int64DictionaryTests">
+               </Test>
+               <Test
+                  Identifier = "GPBInt32ObjectDictionaryTests">
+               </Test>
+               <Test
+                  Identifier = "GPBInt32UInt32DictionaryTests">
+               </Test>
+               <Test
+                  Identifier = "GPBInt32UInt64DictionaryTests">
+               </Test>
+               <Test
+                  Identifier = "GPBInt64ArrayTests">
+               </Test>
+               <Test
+                  Identifier = "GPBInt64BoolDictionaryTests">
+               </Test>
+               <Test
+                  Identifier = "GPBInt64DoubleDictionaryTests">
+               </Test>
+               <Test
+                  Identifier = "GPBInt64EnumDictionaryTests">
+               </Test>
+               <Test
+                  Identifier = "GPBInt64EnumDictionaryUnknownEnumTests">
+               </Test>
+               <Test
+                  Identifier = "GPBInt64FloatDictionaryTests">
+               </Test>
+               <Test
+                  Identifier = "GPBInt64Int32DictionaryTests">
+               </Test>
+               <Test
+                  Identifier = "GPBInt64Int64DictionaryTests">
+               </Test>
+               <Test
+                  Identifier = "GPBInt64ObjectDictionaryTests">
+               </Test>
+               <Test
+                  Identifier = "GPBInt64UInt32DictionaryTests">
+               </Test>
+               <Test
+                  Identifier = "GPBInt64UInt64DictionaryTests">
+               </Test>
+               <Test
+                  Identifier = "GPBStringBoolDictionaryTests">
+               </Test>
+               <Test
+                  Identifier = "GPBStringDoubleDictionaryTests">
+               </Test>
+               <Test
+                  Identifier = "GPBStringEnumDictionaryTests">
+               </Test>
+               <Test
+                  Identifier = "GPBStringEnumDictionaryUnknownEnumTests">
+               </Test>
+               <Test
+                  Identifier = "GPBStringFloatDictionaryTests">
+               </Test>
+               <Test
+                  Identifier = "GPBStringInt32DictionaryTests">
+               </Test>
+               <Test
+                  Identifier = "GPBStringInt64DictionaryTests">
                </Test>
                <Test
                   Identifier = "GPBStringTests">
                </Test>
+               <Test
+                  Identifier = "GPBStringUInt32DictionaryTests">
+               </Test>
+               <Test
+                  Identifier = "GPBStringUInt64DictionaryTests">
+               </Test>
                <Test
                   Identifier = "GPBTestCase">
                </Test>
                <Test
-                  Identifier = "GeneratedMessageTests">
+                  Identifier = "GPBUInt32ArrayTests">
+               </Test>
+               <Test
+                  Identifier = "GPBUInt32BoolDictionaryTests">
+               </Test>
+               <Test
+                  Identifier = "GPBUInt32DoubleDictionaryTests">
+               </Test>
+               <Test
+                  Identifier = "GPBUInt32EnumDictionaryTests">
+               </Test>
+               <Test
+                  Identifier = "GPBUInt32EnumDictionaryUnknownEnumTests">
+               </Test>
+               <Test
+                  Identifier = "GPBUInt32FloatDictionaryTests">
+               </Test>
+               <Test
+                  Identifier = "GPBUInt32Int32DictionaryTests">
+               </Test>
+               <Test
+                  Identifier = "GPBUInt32Int64DictionaryTests">
+               </Test>
+               <Test
+                  Identifier = "GPBUInt32ObjectDictionaryTests">
+               </Test>
+               <Test
+                  Identifier = "GPBUInt32UInt32DictionaryTests">
+               </Test>
+               <Test
+                  Identifier = "GPBUInt32UInt64DictionaryTests">
+               </Test>
+               <Test
+                  Identifier = "GPBUInt64ArrayTests">
+               </Test>
+               <Test
+                  Identifier = "GPBUInt64BoolDictionaryTests">
+               </Test>
+               <Test
+                  Identifier = "GPBUInt64DoubleDictionaryTests">
+               </Test>
+               <Test
+                  Identifier = "GPBUInt64EnumDictionaryTests">
+               </Test>
+               <Test
+                  Identifier = "GPBUInt64EnumDictionaryUnknownEnumTests">
+               </Test>
+               <Test
+                  Identifier = "GPBUInt64FloatDictionaryTests">
+               </Test>
+               <Test
+                  Identifier = "GPBUInt64Int32DictionaryTests">
+               </Test>
+               <Test
+                  Identifier = "GPBUInt64Int64DictionaryTests">
+               </Test>
+               <Test
+                  Identifier = "GPBUInt64ObjectDictionaryTests">
+               </Test>
+               <Test
+                  Identifier = "GPBUInt64UInt32DictionaryTests">
+               </Test>
+               <Test
+                  Identifier = "GPBUInt64UInt64DictionaryTests">
+               </Test>
+               <Test
+                  Identifier = "MessageMergeTests">
+               </Test>
+               <Test
+                  Identifier = "MessageRuntimeTests">
+               </Test>
+               <Test
+                  Identifier = "MessageSerializationTests">
                </Test>
                <Test
                   Identifier = "MessageTests">
@@ -71,6 +275,9 @@
                <Test
                   Identifier = "UtilitiesTests">
                </Test>
+               <Test
+                  Identifier = "WellKnownTypesTest">
+               </Test>
                <Test
                   Identifier = "WireFormatTests">
                </Test>
@@ -96,7 +303,8 @@
       ignoresPersistentStateOnLaunch = "NO"
       debugDocumentVersioning = "YES"
       allowLocationSimulation = "YES">
-      <BuildableProductRunnable>
+      <BuildableProductRunnable
+         runnableDebuggingMode = "0">
          <BuildableReference
             BuildableIdentifier = "primary"
             BlueprintIdentifier = "8B9A5EA41831993600A9D33B"

+ 1 - 1
objectivec/ProtocolBuffers_iOS.xcodeproj/xcshareddata/xcschemes/ProtocolBuffers.xcscheme

@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <Scheme
-   LastUpgradeVersion = "0610"
+   LastUpgradeVersion = "0630"
    version = "1.3">
    <BuildAction
       parallelizeBuildables = "YES"

+ 84 - 9
objectivec/README.md

@@ -21,15 +21,15 @@ Installation
 ------------
 
 The full distribution pulled from github includes the sources for both the
-compiler (protoc) and the runtime (this directory).  To build the compiler
+compiler (protoc) and the runtime (this directory). To build the compiler
 and run the runtime tests, you can use:
 
      $ objectivec/DevTools/full_mac_build.sh
 
 This will generate the `src/protoc` binary.
 
-Usage
------
+Building
+--------
 
 There are two ways to include the Runtime sources in your project:
 
@@ -47,6 +47,80 @@ If the target is using ARC, remember to turn off ARC (`-fno-objc-arc`) for the
 The files generated by `protoc` for the `*.proto` files (`\*.pbobjc.h' and
 `\*.pbobjc.m`) are then also added to the target.
 
+Usage
+-----
+
+The objects generated for messages should work like any other Objective C
+object. They are mutable objects, but if you don't change them, they are safe
+to share between threads (similar to passing an NSMutableDictionary between
+threads/queues; as long as no one mutates it, things are fine).
+
+There are a few behaviors worth calling out:
+
+A property that is type NSString\* will never return nil. If the value is
+unset, it will return an empty string (@""). This is inpart to align things
+with the Protocol Buffers spec which says the default for strings is an empty
+string, but also so you can always safely pass them to isEqual:/compare:, etc.
+and have deterministic results.
+
+A property that is type NSData\* also won't return nil, it will return an empty
+data ([NSData data]). The reasoning is the same as for NSString not returning
+nil.
+
+A property that is another GPBMessage class also will not return nil. If the
+field wasn't already set, you will get a instance of the correct class. This
+instance will be a temporary instance unless you mutate it, at which point it
+will be attached to its parent object. We call this pattern *autocreators*.
+Similar to NSString and NSData properties it makes things a little safer when
+using them with isEqual:/etc.; but more importantly, this allows you to write
+code that uses Objective C's property dot notation to walk into nested objects
+and access and/or assign things without having to check that they are not nil
+and create them each step along the way. You can write this:
+
+```
+- (void)updateRecord:(MyMessage *)msg {
+  ...
+  // Note: You don't have to check subMessage and otherMessage for nil and
+  // alloc/init/assign them back along the way.
+  msg.subMessage.otherMessage.lastName = @"Smith";
+  ...
+}
+```
+
+If you want to check if a GPBMessage property is present, there is always as
+`has\[NAME\]` property to go with the main property to check if it is set.
+
+A property that is of an Array or Dictionary type also provides *autocreator*
+behavior and will never return nil. This provides all the same benefits you
+see for the message properties. Again, you can write:
+
+```
+- (void)updateRecord:(MyMessage *)msg {
+  ...
+  // Note: Just like above, you don't have to check subMessage and otherMessage
+  // for nil and alloc/init/assign them back along the way. You also don't have
+  // to create the siblingsArray, you can safely just append to it.
+  [msg.subMessage.otherMessage.siblingsArray addObject:@"Pat"];
+  ...
+}
+```
+
+If you are inspecting a message you got from some other place (server, disk,
+etc), you may want to check if the Array or Dictionary has entries without
+causing it to be created for you. For this, there is always a `\[NAME\]_Count`
+property also provided that can return zero or the real count, but won't trigger
+the creation.
+
+For primitive type fields (ints, floats, bools, enum) in messages defined in a
+`.proto` file that use *proto2* syntax there are conceptual differences between
+having an *explicit* and *default* value. You can always get the value of the
+property. In the case that it hasn't been set you will get the default. In
+cases where you need to know whether it was set explicitly or you are just
+getting the default, you can use the `has\[NAME\]` property. If the value has
+been set, and you want to clear it, you can set the `has\[NAME\]` to `NO`.
+*proto3* syntax messages do away with this concept, thus the default values are
+never included when the message is encoded.
+
 The Objective C classes/enums can be used from Swift code.
 
 Objective C Generator Options
@@ -55,18 +129,19 @@ Objective C Generator Options
 **objc_class_prefix=\<prefix\>** (no default)
 
 Since Objective C uses a global namespace for all of its classes, there can
-be collisions.  This option provides a prefix that will be added to the Enums
-and Objects (for messages) generated from the proto.  Convention is to base
+be collisions. This option provides a prefix that will be added to the Enums
+and Objects (for messages) generated from the proto. Convention is to base
 the prefix on the package the proto is in.
 
 Contributing
 ------------
 
 Please make updates to the tests along with changes. If just changing the
-runtime, the Xcode projects can be used to build and run tests.  If change also
-require changes to the generated code, `objectivec/DevTools/full_mac_build.sh`
-can be used to easily rebuild and test changes. Passing `-h` to the script will
-show the addition options that could be useful.
+runtime, the Xcode projects can be used to build and run tests. If your change
+also requires changes to the generated code,
+`objectivec/DevTools/full_mac_build.sh` can be used to easily rebuild and test
+changes. Passing `-h` to the script will show the addition options that could
+be useful.
 
 Documentation
 -------------

+ 0 - 35
objectivec/Tests/Filter2.txt

@@ -1,35 +0,0 @@
-// Protocol Buffers - Google's data interchange format
-// Copyright 2014 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.
-
-
-// Test the filter system for the ObjC Protocol Buffer Compiler to test
-// multiple filter support.
-
-Other

+ 1 - 2
objectivec/Tests/GPBARCUnittestProtos.m

@@ -41,16 +41,15 @@
 #import "google/protobuf/UnittestEmbedOptimizeFor.pbobjc.h"
 #import "google/protobuf/UnittestEmpty.pbobjc.h"
 #import "google/protobuf/UnittestEnormousDescriptor.pbobjc.h"
-#import "google/protobuf/UnittestFilter.pbobjc.h"
 #import "google/protobuf/UnittestImport.pbobjc.h"
 #import "google/protobuf/UnittestImportLite.pbobjc.h"
 #import "google/protobuf/UnittestImportPublic.pbobjc.h"
 #import "google/protobuf/UnittestImportPublicLite.pbobjc.h"
 #import "google/protobuf/UnittestLite.pbobjc.h"
 #import "google/protobuf/UnittestMset.pbobjc.h"
-#import "google/protobuf/UnittestNameMangling.pbobjc.h"
 #import "google/protobuf/UnittestNoGenericServices.pbobjc.h"
 #import "google/protobuf/UnittestObjc.pbobjc.h"
+#import "google/protobuf/UnittestObjcStartup.pbobjc.h"
 #import "google/protobuf/UnittestOptimizeFor.pbobjc.h"
 #import "google/protobuf/UnittestPreserveUnknownEnum.pbobjc.h"
 #import "google/protobuf/UnittestRuntimeProto2.pbobjc.h"

+ 1 - 1
objectivec/Tests/GPBCodedInputStreamTests.m

@@ -260,7 +260,7 @@
       [GPBCodedInputStream streamWithData:[NSMutableData dataWithData:data]];
   XCTAssertEqual(tag, [input readTag]);
 
-  XCTAssertThrows([input readData]);
+  XCTAssertThrows([input readBytes]);
 }
 
 // Verifies fix for b/10315336.

+ 2 - 1
objectivec/Tests/GPBConcurrencyTests.m

@@ -196,7 +196,8 @@ static const int kNumMessages = 100;
   NSArray *threads = [self createThreadsWithSelector:sel object:messages];
   [self startThreads:threads];
   [self joinThreads:threads];
-  GPBExtensionField *extension = [UnittestRoot optionalForeignMessageExtension];
+  GPBExtensionDescriptor *extension =
+      [UnittestRoot optionalForeignMessageExtension];
   for (TestAllExtensions *message in messages) {
     XCTAssertFalse([message hasExtension:extension]);
   }

+ 0 - 98
objectivec/Tests/GPBFilteredMessageTests.m

@@ -1,98 +0,0 @@
-// Protocol Buffers - Google's data interchange format
-// Copyright 2013 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.
-
-// Tests our filter system for ObjC.
-// The proto being filtered is unittest_filter.proto.
-// The filter file is Filter.txt.
-
-#import "GPBTestUtilities.h"
-
-#import "google/protobuf/UnittestFilter.pbobjc.h"
-
-// If we get an error about this already being defined, it is most likely
-// because of an error in protoc which is supposed to be filtering
-// the Remove message.
-enum { Other_FieldNumber_B = 0 };
-
-@interface FilteredMessageTests : GPBTestCase
-@end
-
-@implementation FilteredMessageTests
-
-- (void)testEnumFiltering {
-  // If compile fails here it is because protoc did not generate KeepEnum.
-  XCTAssertTrue(KeepEnum_IsValidValue(KeepEnum_KeepValue));
-  XCTAssertNotNil(KeepEnum_EnumDescriptor());
-
-  // If compile fails here it is because protoc did not generate
-  // KeepEnumInsideEnum and is probably due to nested enum handling being
-  // broken.
-  XCTAssertTrue(RemoveEnumMessage_KeepEnumInside_IsValidValue(
-      RemoveEnumMessage_KeepEnumInside_KeepValue));
-  XCTAssertNotNil(RemoveEnumMessage_KeepEnumInside_EnumDescriptor());
-}
-
-- (void)testMessageFiltering {
-  // Messages that should be generated.
-  XCTAssertNil([UnittestFilterRoot extensionRegistry]);
-  XCTAssertNotNil([[[Keep alloc] init] autorelease]);
-  XCTAssertNotNil([[[Other alloc] init] autorelease]);
-  XCTAssertNotNil([[[RemoveJustKidding alloc] init] autorelease]);
-  XCTAssertNotNil(
-      [[[RemoveEnumMessage_KeepNestedInside alloc] init] autorelease]);
-
-  // Messages that should not be generated
-  XCTAssertNil(NSClassFromString(@"Remove"));
-  XCTAssertNil(NSClassFromString(@"RemoveEnumMessage"));
-  XCTAssertNil(NSClassFromString(@"RemoveEnumMessage_RemoveNestedInside"));
-
-  // These should all fail compile if protoc is bad.
-  XCTAssertTrue([Other instancesRespondToSelector:@selector(hasA)]);
-  XCTAssertTrue([Other instancesRespondToSelector:@selector(setHasA:)]);
-  XCTAssertTrue([Other instancesRespondToSelector:@selector(a)]);
-  XCTAssertTrue([Other instancesRespondToSelector:@selector(setA:)]);
-
-  // These the compiler should not generate.
-  XCTAssertFalse(
-      [Other instancesRespondToSelector:NSSelectorFromString(@"hasB")]);
-  XCTAssertFalse(
-      [Other instancesRespondToSelector:NSSelectorFromString(@"setHasB:")]);
-  XCTAssertFalse([Other instancesRespondToSelector:NSSelectorFromString(@"b")]);
-  XCTAssertFalse(
-      [Other instancesRespondToSelector:NSSelectorFromString(@"setB:")]);
-
-  // This should fail if protoc filters it.
-  XCTAssertEqual(Other_FieldNumber_A, 1);
-
-  // Make sure the definition at the top of the file is providing the value.
-  XCTAssertEqual(Other_FieldNumber_B, 0);
-}
-
-@end

+ 126 - 16
objectivec/Tests/GPBMessageTests+Runtime.m

@@ -36,6 +36,7 @@
 
 #import "google/protobuf/MapUnittest.pbobjc.h"
 #import "google/protobuf/Unittest.pbobjc.h"
+#import "google/protobuf/UnittestObjcStartup.pbobjc.h"
 #import "google/protobuf/UnittestRuntimeProto2.pbobjc.h"
 #import "google/protobuf/UnittestRuntimeProto3.pbobjc.h"
 
@@ -47,6 +48,14 @@
 // TODO(thomasvl): Pull tests over from GPBMessageTests that are runtime
 // specific.
 
+- (void)testStartupOrdering {
+  // Just have to create a message.  Nothing else uses the classes from
+  // this file, so the first selector invoked on the class will initialize
+  // it, which also initializes the root.
+  TestObjCStartupMessage *message = [TestObjCStartupMessage message];
+  XCTAssertNotNil(message);
+}
+
 - (void)testProto2HasMethodSupport {
   NSArray *names = @[
     @"Int32",
@@ -70,8 +79,8 @@
   ];
 
   // Proto2 gets:
-  //  - has* on all non repeated fields.
-  //  - setHas* on all non repeated fields.
+
+  // Single fields - has*/setHas* is valid.
 
   for (NSString *name in names) {
     // build the selector, i.e. - hasOptionalInt32/setHasOptionalInt32:
@@ -85,21 +94,28 @@
                   name);
   }
 
-  // Repeated - no has/setHas
+  // Repeated fields
+  //  - no has*/setHas*
+  //  - *Count
 
   for (NSString *name in names) {
-    // build the selector, i.e. - hasRepeatedInt32/setHasRepeatedInt32:
+    // build the selector, i.e. - hasRepeatedInt32Array/setHasRepeatedInt32Array:
     SEL hasSel = NSSelectorFromString(
-        [NSString stringWithFormat:@"hasRepeated%@", name]);
+        [NSString stringWithFormat:@"hasRepeated%@Array", name]);
     SEL setHasSel = NSSelectorFromString(
-        [NSString stringWithFormat:@"setHasRepeated%@:", name]);
+        [NSString stringWithFormat:@"setHasRepeated%@Array:", name]);
     XCTAssertFalse([Message2 instancesRespondToSelector:hasSel], @"field: %@",
                    name);
     XCTAssertFalse([Message2 instancesRespondToSelector:setHasSel],
                    @"field: %@", name);
+    // build the selector, i.e. - repeatedInt32Array_Count
+    SEL countSel = NSSelectorFromString(
+        [NSString stringWithFormat:@"repeated%@Array_Count", name]);
+    XCTAssertTrue([Message2 instancesRespondToSelector:countSel], @"field: %@",
+                   name);
   }
 
-  // Oneofs - no has/setHas
+  // OneOf fields - no has*/setHas*
 
   for (NSString *name in names) {
     // build the selector, i.e. - hasOneofInt32/setHasOneofInt32:
@@ -112,6 +128,50 @@
     XCTAssertFalse([Message2 instancesRespondToSelector:setHasSel],
                    @"field: %@", name);
   }
+
+  // map<> fields
+  //  - no has*/setHas*
+  //  - *Count
+
+  NSArray *mapNames = @[
+    @"Int32Int32",
+    @"Int64Int64",
+    @"Uint32Uint32",
+    @"Uint64Uint64",
+    @"Sint32Sint32",
+    @"Sint64Sint64",
+    @"Fixed32Fixed32",
+    @"Fixed64Fixed64",
+    @"Sfixed32Sfixed32",
+    @"Sfixed64Sfixed64",
+    @"Int32Float",
+    @"Int32Double",
+    @"BoolBool",
+    @"StringString",
+    @"StringBytes",
+    @"StringMessage",
+    @"Int32Bytes",
+    @"Int32Enum",
+    @"Int32Message",
+  ];
+
+  for (NSString *name in mapNames) {
+    // build the selector, i.e. - hasMapInt32Int32/setHasMapInt32Int32:
+    SEL hasSel = NSSelectorFromString(
+        [NSString stringWithFormat:@"hasMap%@", name]);
+    SEL setHasSel = NSSelectorFromString(
+        [NSString stringWithFormat:@"setHasMap%@:", name]);
+    XCTAssertFalse([Message2 instancesRespondToSelector:hasSel], @"field: %@",
+                   name);
+    XCTAssertFalse([Message2 instancesRespondToSelector:setHasSel],
+                   @"field: %@", name);
+    // build the selector, i.e. - mapInt32Int32Count
+    SEL countSel = NSSelectorFromString(
+        [NSString stringWithFormat:@"map%@_Count", name]);
+    XCTAssertTrue([Message2 instancesRespondToSelector:countSel], @"field: %@",
+                   name);
+  }
+
 }
 
 - (void)testProto3HasMethodSupport {
@@ -136,10 +196,10 @@
   ];
 
   // Proto3 gets:
-  //  - has* on non repeated message fields.
-  //  - setHas* on all non repeated message fields.
 
-  // Singlular
+  // Single fields
+  //  - has*/setHas* invalid for primative types.
+  //  - has*/setHas* valid for Message.
 
   for (NSString *name in names) {
     // build the selector, i.e. - hasOptionalInt32/setHasOptionalInt32:
@@ -147,7 +207,7 @@
         [NSString stringWithFormat:@"hasOptional%@", name]);
     SEL setHasSel = NSSelectorFromString(
         [NSString stringWithFormat:@"setHasOptional%@:", name]);
-    if ([name isEqual:@"Group"] || [name isEqual:@"Message"]) {
+    if ([name isEqual:@"Message"]) {
       // Sub messages/groups are the exception.
       XCTAssertTrue([Message3 instancesRespondToSelector:hasSel], @"field: %@",
                     name);
@@ -161,21 +221,28 @@
     }
   }
 
-  // Repeated - no has/setHas
+  // Repeated fields
+  //  - no has*/setHas*
+  //  - *Count
 
   for (NSString *name in names) {
-    // build the selector, i.e. - hasRepeatedInt32/setHasRepeatedInt32:
+    // build the selector, i.e. - hasRepeatedInt32Array/setHasRepeatedInt32Array:
     SEL hasSel = NSSelectorFromString(
-        [NSString stringWithFormat:@"hasRepeated%@", name]);
+        [NSString stringWithFormat:@"hasRepeated%@Array", name]);
     SEL setHasSel = NSSelectorFromString(
-        [NSString stringWithFormat:@"setHasRepeated%@:", name]);
+        [NSString stringWithFormat:@"setHasRepeated%@Array:", name]);
     XCTAssertFalse([Message3 instancesRespondToSelector:hasSel], @"field: %@",
                    name);
     XCTAssertFalse([Message3 instancesRespondToSelector:setHasSel],
                    @"field: %@", name);
+    // build the selector, i.e. - repeatedInt32Array_Count
+    SEL countSel = NSSelectorFromString(
+        [NSString stringWithFormat:@"repeated%@Array_Count", name]);
+    XCTAssertTrue([Message2 instancesRespondToSelector:countSel], @"field: %@",
+                  name);
   }
 
-  // Oneofs - no has/setHas
+  // OneOf fields - no has*/setHas*
 
   for (NSString *name in names) {
     // build the selector, i.e. - hasOneofInt32/setHasOneofInt32:
@@ -188,6 +255,49 @@
     XCTAssertFalse([Message2 instancesRespondToSelector:setHasSel],
                    @"field: %@", name);
   }
+
+  // map<> fields
+  //  - no has*/setHas*
+  //  - *Count
+
+  NSArray *mapNames = @[
+    @"Int32Int32",
+    @"Int64Int64",
+    @"Uint32Uint32",
+    @"Uint64Uint64",
+    @"Sint32Sint32",
+    @"Sint64Sint64",
+    @"Fixed32Fixed32",
+    @"Fixed64Fixed64",
+    @"Sfixed32Sfixed32",
+    @"Sfixed64Sfixed64",
+    @"Int32Float",
+    @"Int32Double",
+    @"BoolBool",
+    @"StringString",
+    @"StringBytes",
+    @"StringMessage",
+    @"Int32Bytes",
+    @"Int32Enum",
+    @"Int32Message",
+  ];
+
+  for (NSString *name in mapNames) {
+    // build the selector, i.e. - hasMapInt32Int32/setHasMapInt32Int32:
+    SEL hasSel = NSSelectorFromString(
+        [NSString stringWithFormat:@"hasMap%@", name]);
+    SEL setHasSel = NSSelectorFromString(
+        [NSString stringWithFormat:@"setHasMap%@:", name]);
+    XCTAssertFalse([Message2 instancesRespondToSelector:hasSel], @"field: %@",
+                   name);
+    XCTAssertFalse([Message2 instancesRespondToSelector:setHasSel],
+                   @"field: %@", name);
+    // build the selector, i.e. - mapInt32Int32Count
+    SEL countSel = NSSelectorFromString(
+        [NSString stringWithFormat:@"map%@_Count", name]);
+    XCTAssertTrue([Message2 instancesRespondToSelector:countSel], @"field: %@",
+                   name);
+  }
 }
 
 - (void)testProto2SingleFieldHasBehavior {

+ 130 - 6
objectivec/Tests/GPBMessageTests+Serialization.m

@@ -36,6 +36,7 @@
 
 #import "google/protobuf/MapProto2Unittest.pbobjc.h"
 #import "google/protobuf/MapUnittest.pbobjc.h"
+#import "google/protobuf/Unittest.pbobjc.h"
 #import "google/protobuf/UnittestDropUnknownFields.pbobjc.h"
 #import "google/protobuf/UnittestPreserveUnknownEnum.pbobjc.h"
 #import "google/protobuf/UnittestRuntimeProto2.pbobjc.h"
@@ -166,17 +167,15 @@ static NSData *DataFromCStr(const char *str) {
       [unknownFields hasField:Message2_FieldNumber_RepeatedEnumArray]);
   XCTAssertTrue([unknownFields hasField:Message2_FieldNumber_OneofEnum]);
 
-  GPBField *field = [unknownFields getField:Message2_FieldNumber_OptionalEnum];
+  GPBUnknownField *field =
+      [unknownFields getField:Message2_FieldNumber_OptionalEnum];
   XCTAssertEqual(field.varintList.count, 1U);
   XCTAssertEqual([field.varintList valueAtIndex:0],
                  (uint64_t)Message3_Enum_Extra3);
 
-  // Repeated in proto3 default to packed, so this will be length delimited
-  // unknown field, and the value (Message3_Enum_Extra3) encodes into one byte.
   field = [unknownFields getField:Message2_FieldNumber_RepeatedEnumArray];
-  XCTAssertEqual(field.lengthDelimitedList.count, 1U);
-  NSData *expected = DataFromCStr("\x1E");
-  XCTAssertEqualObjects([field.lengthDelimitedList objectAtIndex:0], expected);
+  XCTAssertEqual(field.varintList.count, 1U);
+  XCTAssertEqual([field.varintList valueAtIndex:0], (uint64_t)Message3_Enum_Extra3);
 
   field = [unknownFields getField:Message2_FieldNumber_OneofEnum];
   XCTAssertEqual(field.varintList.count, 1U);
@@ -678,6 +677,131 @@ static NSData *DataFromCStr(const char *str) {
 
 //%PDDM-EXPAND-END (2 expansions)
 
+- (void)testPackedUnpackedMessageParsing {
+  // packed is optional, a repeated field should parse when packed or unpacked.
+
+  TestPackedTypes *packedOrig = [TestPackedTypes message];
+  TestUnpackedTypes *unpackedOrig = [TestUnpackedTypes message];
+  [self setPackedFields:packedOrig repeatedCount:4];
+  [self setUnpackedFields:unpackedOrig repeatedCount:4];
+
+  NSData *packedData = [packedOrig data];
+  NSData *unpackedData = [unpackedOrig data];
+  XCTAssertNotNil(packedData);
+  XCTAssertNotNil(unpackedData);
+  XCTAssertNotEqualObjects(packedData, unpackedData,
+                           @"Data should differ (packed vs unpacked) use");
+
+  NSError *error = nil;
+  TestPackedTypes *packedParse =
+      [TestPackedTypes parseFromData:unpackedData error:&error];
+  XCTAssertNotNil(packedParse);
+  XCTAssertNil(error);
+  XCTAssertEqualObjects(packedParse, packedOrig);
+
+  error = nil;
+  TestUnpackedTypes *unpackedParsed =
+      [TestUnpackedTypes parseFromData:packedData error:&error];
+  XCTAssertNotNil(unpackedParsed);
+  XCTAssertNil(error);
+  XCTAssertEqualObjects(unpackedParsed, unpackedOrig);
+}
+
+- (void)testPackedUnpackedExtensionParsing {
+  // packed is optional, a repeated extension should parse when packed or
+  // unpacked.
+
+  TestPackedExtensions *packedOrig = [TestPackedExtensions message];
+  TestUnpackedExtensions *unpackedOrig = [TestUnpackedExtensions message];
+  [self setPackedExtensions:packedOrig repeatedCount:kGPBDefaultRepeatCount];
+  [self setUnpackedExtensions:unpackedOrig repeatedCount:kGPBDefaultRepeatCount];
+
+  NSData *packedData = [packedOrig data];
+  NSData *unpackedData = [unpackedOrig data];
+  XCTAssertNotNil(packedData);
+  XCTAssertNotNil(unpackedData);
+  XCTAssertNotEqualObjects(packedData, unpackedData,
+                           @"Data should differ (packed vs unpacked) use");
+
+  NSError *error = nil;
+  TestPackedExtensions *packedParse =
+      [TestPackedExtensions parseFromData:unpackedData
+                        extensionRegistry:[UnittestRoot extensionRegistry]
+                                    error:&error];
+  XCTAssertNotNil(packedParse);
+  XCTAssertNil(error);
+  XCTAssertEqualObjects(packedParse, packedOrig);
+
+  error = nil;
+  TestUnpackedExtensions *unpackedParsed =
+      [TestUnpackedExtensions parseFromData:packedData
+                          extensionRegistry:[UnittestRoot extensionRegistry]
+                                      error:&error];
+  XCTAssertNotNil(unpackedParsed);
+  XCTAssertNil(error);
+  XCTAssertEqualObjects(unpackedParsed, unpackedOrig);
+}
+
+- (void)testPackedExtensionVsFieldParsing {
+  // Extensions and fields end up on the wire the same way, so they can parse
+  // each other.
+
+  TestPackedTypes *fieldsOrig = [TestPackedTypes message];
+  TestPackedExtensions *extsOrig = [TestPackedExtensions message];
+  [self setPackedFields:fieldsOrig repeatedCount:kGPBDefaultRepeatCount];
+  [self setPackedExtensions:extsOrig repeatedCount:kGPBDefaultRepeatCount];
+
+  NSData *fieldsData = [fieldsOrig data];
+  NSData *extsData = [extsOrig data];
+  XCTAssertNotNil(fieldsData);
+  XCTAssertNotNil(extsData);
+  XCTAssertEqualObjects(fieldsData, extsData);
+
+  NSError *error = nil;
+  TestPackedTypes *fieldsParse =
+      [TestPackedTypes parseFromData:extsData error:&error];
+  XCTAssertNotNil(fieldsParse);
+  XCTAssertNil(error);
+  XCTAssertEqualObjects(fieldsParse, fieldsOrig);
+
+  error = nil;
+  TestPackedExtensions *extsParse =
+      [TestPackedExtensions parseFromData:fieldsData
+                        extensionRegistry:[UnittestRoot extensionRegistry]
+                                    error:&error];
+  XCTAssertNotNil(extsParse);
+  XCTAssertNil(error);
+  XCTAssertEqualObjects(extsParse, extsOrig);
+}
+
+- (void)testUnpackedExtensionVsFieldParsing {
+  // Extensions and fields end up on the wire the same way, so they can parse
+  // each other.
+
+  TestUnpackedTypes *fieldsOrig = [TestUnpackedTypes message];
+  TestUnpackedExtensions *extsOrig = [TestUnpackedExtensions message];
+  [self setUnpackedFields:fieldsOrig repeatedCount:3];
+  [self setUnpackedExtensions:extsOrig repeatedCount:3];
+
+  NSData *fieldsData = [fieldsOrig data];
+  NSData *extsData = [extsOrig data];
+  XCTAssertNotNil(fieldsData);
+  XCTAssertNotNil(extsData);
+  XCTAssertEqualObjects(fieldsData, extsData);
+
+  TestUnpackedTypes *fieldsParse =
+      [TestUnpackedTypes parseFromData:extsData error:NULL];
+  XCTAssertNotNil(fieldsParse);
+  XCTAssertEqualObjects(fieldsParse, fieldsOrig);
+
+  TestUnpackedExtensions *extsParse =
+      [TestUnpackedExtensions parseFromData:fieldsData
+                          extensionRegistry:[UnittestRoot extensionRegistry]
+                                      error:NULL];
+  XCTAssertNotNil(extsParse);
+  XCTAssertEqualObjects(extsParse, extsOrig);
+}
+
 #pragma mark - Subset from from map_tests.cc
 
 // TEST(GeneratedMapFieldTest, StandardWireFormat)

+ 23 - 26
objectivec/Tests/GPBMessageTests.m

@@ -35,12 +35,11 @@
 #import "GPBArray_PackagePrivate.h"
 #import "GPBDescriptor.h"
 #import "GPBDictionary_PackagePrivate.h"
-#import "GPBField_PackagePrivate.h"
 #import "GPBMessage_PackagePrivate.h"
+#import "GPBUnknownField_PackagePrivate.h"
 #import "GPBUnknownFieldSet_PackagePrivate.h"
 #import "google/protobuf/Unittest.pbobjc.h"
 #import "google/protobuf/UnittestObjc.pbobjc.h"
-#import "google/protobuf/UnittestNameMangling.pbobjc.h"
 
 @interface MessageTests : GPBTestCase
 @end
@@ -420,10 +419,11 @@
 
   GPBUnknownFieldSet *unknownFields =
       [[[GPBUnknownFieldSet alloc] init] autorelease];
-  GPBField *field = [[[GPBField alloc] initWithNumber:2] autorelease];
+  GPBUnknownField *field =
+      [[[GPBUnknownField alloc] initWithNumber:2] autorelease];
   [field addVarint:2];
   [unknownFields addField:field];
-  field = [[[GPBField alloc] initWithNumber:3] autorelease];
+  field = [[[GPBUnknownField alloc] initWithNumber:3] autorelease];
   [field addVarint:4];
   [unknownFields addField:field];
 
@@ -451,7 +451,7 @@
   GPBFieldDescriptor *fieldDescriptor =
       [descriptor fieldWithName:@"defaultInt32"];
   XCTAssertNotNil(fieldDescriptor);
-  GPBValue defaultValue = [fieldDescriptor defaultValue];
+  GPBGenericValue defaultValue = [fieldDescriptor defaultValue];
   [message setDefaultInt32:defaultValue.valueInt32];
   XCTAssertTrue(message.hasDefaultInt32);
   XCTAssertEqual(message.defaultInt32, defaultValue.valueInt32);
@@ -1554,7 +1554,7 @@
   // The other should not.
   TestAllExtensions *message = [TestAllExtensions message];
   TestAllExtensions *message2 = [TestAllExtensions message];
-  GPBExtensionField *extension = [UnittestRoot optionalGroupExtension];
+  GPBExtensionDescriptor *extension = [UnittestRoot optionalGroupExtension];
   [message setExtension:extension value:[message2 getExtension:extension]];
   XCTAssertEqual([message getExtension:extension],
                  [message2 getExtension:extension]);
@@ -1571,9 +1571,9 @@
 - (void)testCopyWithAutocreatedExtension {
   // Mutable copy shouldn't copy autocreated extensions.
   TestAllExtensions *message = [TestAllExtensions message];
-  GPBExtensionField *optionalGroupExtension =
+  GPBExtensionDescriptor *optionalGroupExtension =
       [UnittestRoot optionalGroupExtension];
-  GPBExtensionField *optionalNestedMessageExtesion =
+  GPBExtensionDescriptor *optionalNestedMessageExtesion =
       [UnittestRoot optionalNestedMessageExtension];
   TestAllTypes_OptionalGroup *optionalGroup =
       [message getExtension:optionalGroupExtension];
@@ -1603,7 +1603,7 @@
 - (void)testClearMessageAutocreatedExtension {
   // Call clear should cause it to recreate its autocreated extensions.
   TestAllExtensions *message = [TestAllExtensions message];
-  GPBExtensionField *optionalGroupExtension =
+  GPBExtensionDescriptor *optionalGroupExtension =
       [UnittestRoot optionalGroupExtension];
   TestAllTypes_OptionalGroup *optionalGroup =
       [[message getExtension:optionalGroupExtension] retain];
@@ -1620,7 +1620,7 @@
   // Should be able to retain autocreated extension while the creator is
   // dealloced.
   TestAllExtensions *message = [TestAllExtensions message];
-  GPBExtensionField *optionalGroupExtension =
+  GPBExtensionDescriptor *optionalGroupExtension =
       [UnittestRoot optionalGroupExtension];
 
   @autoreleasepool {
@@ -1638,7 +1638,7 @@
 - (void)testClearAutocreatedExtension {
   // Clearing autocreated extension should NOT cause it to lose its creator.
   TestAllExtensions *message = [TestAllExtensions message];
-  GPBExtensionField *optionalGroupExtension =
+  GPBExtensionDescriptor *optionalGroupExtension =
       [UnittestRoot optionalGroupExtension];
   TestAllTypes_OptionalGroup *optionalGroup =
       [[message getExtension:optionalGroupExtension] retain];
@@ -1651,7 +1651,8 @@
 
   // Clearing autocreated extension should not cause its creator to become
   // visible
-  GPBExtensionField *recursiveExtension = [UnittestObjcRoot recursiveExtension];
+  GPBExtensionDescriptor *recursiveExtension =
+      [UnittestObjcRoot recursiveExtension];
   TestAllExtensions *message_lvl2 = [message getExtension:recursiveExtension];
   TestAllExtensions *message_lvl3 =
       [message_lvl2 getExtension:recursiveExtension];
@@ -1663,7 +1664,8 @@
   // Setting an extension should cause the extension to appear to its creator.
   // Test this several levels deep.
   TestAllExtensions *message = [TestAllExtensions message];
-  GPBExtensionField *recursiveExtension = [UnittestObjcRoot recursiveExtension];
+  GPBExtensionDescriptor *recursiveExtension =
+      [UnittestObjcRoot recursiveExtension];
   TestAllExtensions *message_lvl2 = [message getExtension:recursiveExtension];
   TestAllExtensions *message_lvl3 =
       [message_lvl2 getExtension:recursiveExtension];
@@ -1686,7 +1688,7 @@
 - (void)testSetAutocreatedExtensionToSelf {
   // Setting extension to itself should cause it to become visible.
   TestAllExtensions *message = [TestAllExtensions message];
-  GPBExtensionField *optionalGroupExtension =
+  GPBExtensionDescriptor *optionalGroupExtension =
       [UnittestRoot optionalGroupExtension];
   XCTAssertNotNil([message getExtension:optionalGroupExtension]);
   XCTAssertFalse([message hasExtension:optionalGroupExtension]);
@@ -1696,7 +1698,8 @@
 }
 
 - (void)testAutocreatedExtensionMemoryLeaks {
-  GPBExtensionField *recursiveExtension = [UnittestObjcRoot recursiveExtension];
+  GPBExtensionDescriptor *recursiveExtension =
+      [UnittestObjcRoot recursiveExtension];
 
   // Test for memory leaks with autocreated extensions.
   TestAllExtensions *message;
@@ -1729,7 +1732,8 @@
 }
 
 - (void)testSetExtensionWithAutocreatedValue {
-  GPBExtensionField *recursiveExtension = [UnittestObjcRoot recursiveExtension];
+  GPBExtensionDescriptor *recursiveExtension =
+      [UnittestObjcRoot recursiveExtension];
 
   TestAllExtensions *message;
   @autoreleasepool {
@@ -1814,9 +1818,9 @@
 }
 
 - (void)testEnumDescriptorFromExtensionDescriptor {
-  GPBExtensionField *extField = [UnittestRoot optionalForeignEnumExtension];
-  GPBExtensionDescriptor *extDescriptor = extField.descriptor;
-  XCTAssertEqual(extDescriptor.type, GPBTypeEnum);
+  GPBExtensionDescriptor *extDescriptor =
+      [UnittestRoot optionalForeignEnumExtension];
+  XCTAssertEqual(extDescriptor.dataType, GPBDataTypeEnum);
   GPBEnumDescriptor *enumDescriptor = extDescriptor.enumDescriptor;
   GPBEnumDescriptor *expectedDescriptor = ForeignEnum_EnumDescriptor();
   XCTAssertEqualObjects(enumDescriptor, expectedDescriptor);
@@ -1925,11 +1929,4 @@
                  EnumTestMsg_MyEnum_NegTwo);
 }
 
-- (void)testMutableNameManagling {
-  // These basically confirm that all the expected name mangling happened by not
-  // having compile errors.
-
-  // TODO(thomasvl): Write these, see unittest_name_mangling.proto.
-}
-
 @end

+ 6 - 0
objectivec/Tests/GPBTestUtilities.h

@@ -35,6 +35,8 @@
 @class TestMap;
 @class TestPackedTypes;
 @class TestPackedExtensions;
+@class TestUnpackedTypes;
+@class TestUnpackedExtensions;
 @class GPBExtensionRegistry;
 
 
@@ -55,8 +57,12 @@ extern const uint32_t kGPBDefaultRepeatCount;
            repeatedCount:(uint32_t)count;
 - (void)setPackedFields:(TestPackedTypes *)message
           repeatedCount:(uint32_t)count;
+- (void)setUnpackedFields:(TestUnpackedTypes *)message
+            repeatedCount:(uint32_t)count;
 - (void)setPackedExtensions:(TestPackedExtensions *)message
               repeatedCount:(uint32_t)count;
+- (void)setUnpackedExtensions:(TestUnpackedExtensions *)message
+              repeatedCount:(uint32_t)count;
 - (void)setAllMapFields:(TestMap *)message numEntries:(uint32_t)count;
 
 - (TestAllTypes *)allSetRepeatedCount:(uint32_t)count;

+ 300 - 86
objectivec/Tests/GPBTestUtilities.m

@@ -599,6 +599,33 @@ const uint32_t kGPBDefaultRepeatCount = 2;
   XCTAssertEqual(count, message.repeatedStringPieceArray.count);
   XCTAssertEqual(count, message.repeatedCordArray.count);
 
+  XCTAssertEqual(count, message.repeatedInt32Array_Count);
+  XCTAssertEqual(count, message.repeatedInt64Array_Count);
+  XCTAssertEqual(count, message.repeatedUint32Array_Count);
+  XCTAssertEqual(count, message.repeatedUint64Array_Count);
+  XCTAssertEqual(count, message.repeatedSint32Array_Count);
+  XCTAssertEqual(count, message.repeatedSint64Array_Count);
+  XCTAssertEqual(count, message.repeatedFixed32Array_Count);
+  XCTAssertEqual(count, message.repeatedFixed64Array_Count);
+  XCTAssertEqual(count, message.repeatedSfixed32Array_Count);
+  XCTAssertEqual(count, message.repeatedSfixed64Array_Count);
+  XCTAssertEqual(count, message.repeatedFloatArray_Count);
+  XCTAssertEqual(count, message.repeatedDoubleArray_Count);
+  XCTAssertEqual(count, message.repeatedBoolArray_Count);
+  XCTAssertEqual(count, message.repeatedStringArray_Count);
+  XCTAssertEqual(count, message.repeatedBytesArray_Count);
+
+  XCTAssertEqual(count, message.repeatedGroupArray_Count);
+  XCTAssertEqual(count, message.repeatedNestedMessageArray_Count);
+  XCTAssertEqual(count, message.repeatedForeignMessageArray_Count);
+  XCTAssertEqual(count, message.repeatedImportMessageArray_Count);
+  XCTAssertEqual(count, message.repeatedNestedEnumArray_Count);
+  XCTAssertEqual(count, message.repeatedForeignEnumArray_Count);
+  XCTAssertEqual(count, message.repeatedImportEnumArray_Count);
+
+  XCTAssertEqual(count, message.repeatedStringPieceArray_Count);
+  XCTAssertEqual(count, message.repeatedCordArray_Count);
+
   for (uint32_t i = 0; i < count; ++i) {
     XCTAssertEqual((int)(201 + i * 100),
                    [message.repeatedInt32Array valueAtIndex:i]);
@@ -1097,6 +1124,72 @@ const uint32_t kGPBDefaultRepeatCount = 2;
   }
 }
 
+- (void)setAllTestPackedFields:(TestPackedTypes *)message {
+  // Must match -setAllTestUnpackedFields:
+  [message.packedInt32Array addValue:101];
+  [message.packedInt64Array addValue:102];
+  [message.packedUint32Array addValue:103];
+  [message.packedUint64Array addValue:104];
+  [message.packedSint32Array addValue:105];
+  [message.packedSint64Array addValue:106];
+  [message.packedFixed32Array addValue:107];
+  [message.packedFixed64Array addValue:108];
+  [message.packedSfixed32Array addValue:109];
+  [message.packedSfixed64Array addValue:110];
+  [message.packedFloatArray addValue:111.f];
+  [message.packedDoubleArray addValue:112.];
+  [message.packedBoolArray addValue:YES];
+  [message.packedEnumArray addValue:ForeignEnum_ForeignBar];
+
+  [message.packedInt32Array addValue:201];
+  [message.packedInt64Array addValue:302];
+  [message.packedUint32Array addValue:203];
+  [message.packedUint64Array addValue:204];
+  [message.packedSint32Array addValue:205];
+  [message.packedSint64Array addValue:206];
+  [message.packedFixed32Array addValue:207];
+  [message.packedFixed64Array addValue:208];
+  [message.packedSfixed32Array addValue:209];
+  [message.packedSfixed64Array addValue:210];
+  [message.packedFloatArray addValue:211.f];
+  [message.packedDoubleArray addValue:212.];
+  [message.packedBoolArray addValue:NO];
+  [message.packedEnumArray addValue:ForeignEnum_ForeignBaz];
+}
+
+- (void)setAllTestUnpackedFields:(TestUnpackedTypes *)message {
+  // Must match -setAllTestPackedFields:
+  [message.unpackedInt32Array addValue:101];
+  [message.unpackedInt64Array addValue:102];
+  [message.unpackedUint32Array addValue:103];
+  [message.unpackedUint64Array addValue:104];
+  [message.unpackedSint32Array addValue:105];
+  [message.unpackedSint64Array addValue:106];
+  [message.unpackedFixed32Array addValue:107];
+  [message.unpackedFixed64Array addValue:108];
+  [message.unpackedSfixed32Array addValue:109];
+  [message.unpackedSfixed64Array addValue:110];
+  [message.unpackedFloatArray addValue:111.f];
+  [message.unpackedDoubleArray addValue:112.];
+  [message.unpackedBoolArray addValue:YES];
+  [message.unpackedEnumArray addValue:ForeignEnum_ForeignBar];
+
+  [message.unpackedInt32Array addValue:201];
+  [message.unpackedInt64Array addValue:302];
+  [message.unpackedUint32Array addValue:203];
+  [message.unpackedUint64Array addValue:204];
+  [message.unpackedSint32Array addValue:205];
+  [message.unpackedSint64Array addValue:206];
+  [message.unpackedFixed32Array addValue:207];
+  [message.unpackedFixed64Array addValue:208];
+  [message.unpackedSfixed32Array addValue:209];
+  [message.unpackedSfixed64Array addValue:210];
+  [message.unpackedFloatArray addValue:211.f];
+  [message.unpackedDoubleArray addValue:212.];
+  [message.unpackedBoolArray addValue:NO];
+  [message.unpackedEnumArray addValue:ForeignEnum_ForeignBaz];
+}
+
 - (GPBExtensionRegistry *)extensionRegistry {
   return [UnittestRoot extensionRegistry];
 }
@@ -1189,6 +1282,7 @@ const uint32_t kGPBDefaultRepeatCount = 2;
   XCTAssertEqualObjects(message.optionalCord, @"");
 
   // Repeated fields are empty.
+
   XCTAssertEqual(0U, message.repeatedInt32Array.count);
   XCTAssertEqual(0U, message.repeatedInt64Array.count);
   XCTAssertEqual(0U, message.repeatedUint32Array.count);
@@ -1216,6 +1310,33 @@ const uint32_t kGPBDefaultRepeatCount = 2;
   XCTAssertEqual(0U, message.repeatedStringPieceArray.count);
   XCTAssertEqual(0U, message.repeatedCordArray.count);
 
+  XCTAssertEqual(0U, message.repeatedInt32Array_Count);
+  XCTAssertEqual(0U, message.repeatedInt64Array_Count);
+  XCTAssertEqual(0U, message.repeatedUint32Array_Count);
+  XCTAssertEqual(0U, message.repeatedUint64Array_Count);
+  XCTAssertEqual(0U, message.repeatedSint32Array_Count);
+  XCTAssertEqual(0U, message.repeatedSint64Array_Count);
+  XCTAssertEqual(0U, message.repeatedFixed32Array_Count);
+  XCTAssertEqual(0U, message.repeatedFixed64Array_Count);
+  XCTAssertEqual(0U, message.repeatedSfixed32Array_Count);
+  XCTAssertEqual(0U, message.repeatedSfixed64Array_Count);
+  XCTAssertEqual(0U, message.repeatedFloatArray_Count);
+  XCTAssertEqual(0U, message.repeatedDoubleArray_Count);
+  XCTAssertEqual(0U, message.repeatedBoolArray_Count);
+  XCTAssertEqual(0U, message.repeatedStringArray_Count);
+  XCTAssertEqual(0U, message.repeatedBytesArray_Count);
+
+  XCTAssertEqual(0U, message.repeatedGroupArray_Count);
+  XCTAssertEqual(0U, message.repeatedNestedMessageArray_Count);
+  XCTAssertEqual(0U, message.repeatedForeignMessageArray_Count);
+  XCTAssertEqual(0U, message.repeatedImportMessageArray_Count);
+  XCTAssertEqual(0U, message.repeatedNestedEnumArray_Count);
+  XCTAssertEqual(0U, message.repeatedForeignEnumArray_Count);
+  XCTAssertEqual(0U, message.repeatedImportEnumArray_Count);
+
+  XCTAssertEqual(0U, message.repeatedStringPieceArray_Count);
+  XCTAssertEqual(0U, message.repeatedCordArray_Count);
+
   // hasBlah() should also be NO for all default fields.
   XCTAssertFalse(message.hasDefaultInt32);
   XCTAssertFalse(message.hasDefaultInt64);
@@ -1474,6 +1595,7 @@ const uint32_t kGPBDefaultRepeatCount = 2;
   // ModifyRepeatedFields only sets the second repeated element of each
   // field.  In addition to verifying this, we also verify that the first
   // element and size were *not* modified.
+
   XCTAssertEqual(count, message.repeatedInt32Array.count);
   XCTAssertEqual(count, message.repeatedInt64Array.count);
   XCTAssertEqual(count, message.repeatedUint32Array.count);
@@ -1501,6 +1623,33 @@ const uint32_t kGPBDefaultRepeatCount = 2;
   XCTAssertEqual(count, message.repeatedStringPieceArray.count);
   XCTAssertEqual(count, message.repeatedCordArray.count);
 
+  XCTAssertEqual(count, message.repeatedInt32Array_Count);
+  XCTAssertEqual(count, message.repeatedInt64Array_Count);
+  XCTAssertEqual(count, message.repeatedUint32Array_Count);
+  XCTAssertEqual(count, message.repeatedUint64Array_Count);
+  XCTAssertEqual(count, message.repeatedSint32Array_Count);
+  XCTAssertEqual(count, message.repeatedSint64Array_Count);
+  XCTAssertEqual(count, message.repeatedFixed32Array_Count);
+  XCTAssertEqual(count, message.repeatedFixed64Array_Count);
+  XCTAssertEqual(count, message.repeatedSfixed32Array_Count);
+  XCTAssertEqual(count, message.repeatedSfixed64Array_Count);
+  XCTAssertEqual(count, message.repeatedFloatArray_Count);
+  XCTAssertEqual(count, message.repeatedDoubleArray_Count);
+  XCTAssertEqual(count, message.repeatedBoolArray_Count);
+  XCTAssertEqual(count, message.repeatedStringArray_Count);
+  XCTAssertEqual(count, message.repeatedBytesArray_Count);
+
+  XCTAssertEqual(count, message.repeatedGroupArray_Count);
+  XCTAssertEqual(count, message.repeatedNestedMessageArray_Count);
+  XCTAssertEqual(count, message.repeatedForeignMessageArray_Count);
+  XCTAssertEqual(count, message.repeatedImportMessageArray_Count);
+  XCTAssertEqual(count, message.repeatedNestedEnumArray_Count);
+  XCTAssertEqual(count, message.repeatedForeignEnumArray_Count);
+  XCTAssertEqual(count, message.repeatedImportEnumArray_Count);
+
+  XCTAssertEqual(count, message.repeatedStringPieceArray_Count);
+  XCTAssertEqual(count, message.repeatedCordArray_Count);
+
   XCTAssertEqual(201, [message.repeatedInt32Array valueAtIndex:0]);
   XCTAssertEqual(202LL, [message.repeatedInt64Array valueAtIndex:0]);
   XCTAssertEqual(203U, [message.repeatedUint32Array valueAtIndex:0]);
@@ -1563,105 +1712,101 @@ const uint32_t kGPBDefaultRepeatCount = 2;
 
 - (void)setPackedFields:(TestPackedTypes *)message
           repeatedCount:(uint32_t)count {
-  {
-    GPBInt32Array *scratch = [GPBInt32Array array];
-    for (uint32_t i = 0; i < count; ++i) {
-      [scratch addValue:601 + i * 100];
-    }
-    [message setPackedInt32Array:scratch];
+  // Must match -setUnpackedFields:repeatedCount:
+  // Must match -setPackedExtensions:repeatedCount:
+  // Must match -setUnpackedExtensions:repeatedCount:
+  for (uint32_t i = 0; i < count; ++i) {
+    [message.packedInt32Array addValue:601 + i * 100];
   }
-  {
-    GPBInt64Array *scratch = [GPBInt64Array array];
-    for (uint32_t i = 0; i < count; ++i) {
-      [scratch addValue:602 + i * 100];
-    }
-    [message setPackedInt64Array:scratch];
+  for (uint32_t i = 0; i < count; ++i) {
+    [message.packedInt64Array addValue:602 + i * 100];
   }
-  {
-    GPBUInt32Array *scratch = [GPBUInt32Array array];
-    for (uint32_t i = 0; i < count; ++i) {
-      [scratch addValue:603 + i * 100];
-    }
-    [message setPackedUint32Array:scratch];
+  for (uint32_t i = 0; i < count; ++i) {
+    [message.packedUint32Array addValue:603 + i * 100];
   }
-  {
-    GPBUInt64Array *scratch = [GPBUInt64Array array];
-    for (uint32_t i = 0; i < count; ++i) {
-      [scratch addValue:604 + i * 100];
-    }
-    [message setPackedUint64Array:scratch];
+  for (uint32_t i = 0; i < count; ++i) {
+    [message.packedUint64Array addValue:604 + i * 100];
   }
-  {
-    GPBInt32Array *scratch = [GPBInt32Array array];
-    for (uint32_t i = 0; i < count; ++i) {
-      [scratch addValue:605 + i * 100];
-    }
-    [message setPackedSint32Array:scratch];
+  for (uint32_t i = 0; i < count; ++i) {
+    [message.packedSint32Array addValue:605 + i * 100];
   }
-  {
-    GPBInt64Array *scratch = [GPBInt64Array array];
-    for (uint32_t i = 0; i < count; ++i) {
-      [scratch addValue:606 + i * 100];
-    }
-    [message setPackedSint64Array:scratch];
+  for (uint32_t i = 0; i < count; ++i) {
+    [message.packedSint64Array addValue:606 + i * 100];
   }
-  {
-    GPBUInt32Array *scratch = [GPBUInt32Array array];
-    for (uint32_t i = 0; i < count; ++i) {
-      [scratch addValue:607 + i * 100];
-    }
-    [message setPackedFixed32Array:scratch];
+  for (uint32_t i = 0; i < count; ++i) {
+    [message.packedFixed32Array addValue:607 + i * 100];
   }
-  {
-    GPBUInt64Array *scratch = [GPBUInt64Array array];
-    for (uint32_t i = 0; i < count; ++i) {
-      [scratch addValue:608 + i * 100];
-    }
-    [message setPackedFixed64Array:scratch];
+  for (uint32_t i = 0; i < count; ++i) {
+    [message.packedFixed64Array addValue:608 + i * 100];
   }
-  {
-    GPBInt32Array *scratch = [GPBInt32Array array];
-    for (uint32_t i = 0; i < count; ++i) {
-      [scratch addValue:609 + i * 100];
-    }
-    [message setPackedSfixed32Array:scratch];
+  for (uint32_t i = 0; i < count; ++i) {
+    [message.packedSfixed32Array addValue:609 + i * 100];
   }
-  {
-    GPBInt64Array *scratch = [GPBInt64Array array];
-    for (uint32_t i = 0; i < count; ++i) {
-      [scratch addValue:610 + i * 100];
-    }
-    [message setPackedSfixed64Array:scratch];
+  for (uint32_t i = 0; i < count; ++i) {
+    [message.packedSfixed64Array addValue:610 + i * 100];
   }
-  {
-    GPBFloatArray *scratch = [GPBFloatArray array];
-    for (uint32_t i = 0; i < count; ++i) {
-      [scratch addValue:611 + i * 100];
-    }
-    [message setPackedFloatArray:scratch];
+  for (uint32_t i = 0; i < count; ++i) {
+    [message.packedFloatArray addValue:611 + i * 100];
   }
-  {
-    GPBDoubleArray *scratch = [GPBDoubleArray array];
-    for (uint32_t i = 0; i < count; ++i) {
-      [scratch addValue:612 + i * 100];
-    }
-    [message setPackedDoubleArray:scratch];
+  for (uint32_t i = 0; i < count; ++i) {
+    [message.packedDoubleArray addValue:612 + i * 100];
   }
-  {
-    GPBBoolArray *scratch = [GPBBoolArray array];
-    for (uint32_t i = 0; i < count; ++i) {
-      [scratch addValue:(i % 2) ? YES : NO];
-    }
-    [message setPackedBoolArray:scratch];
+  for (uint32_t i = 0; i < count; ++i) {
+    [message.packedBoolArray addValue:(i % 2) ? YES : NO];
   }
-  {
-    GPBEnumArray *scratch =
-        [GPBEnumArray arrayWithValidationFunction:ForeignEnum_IsValidValue];
-    for (uint32_t i = 0; i < count; ++i) {
-      [scratch
-          addValue:(i % 2) ? ForeignEnum_ForeignBar : ForeignEnum_ForeignBaz];
-    }
-    [message setPackedEnumArray:scratch];
+  for (uint32_t i = 0; i < count; ++i) {
+    [message.packedEnumArray
+        addValue:(i % 2) ? ForeignEnum_ForeignBar : ForeignEnum_ForeignBaz];
+  }
+}
+
+- (void)setUnpackedFields:(TestUnpackedTypes *)message
+            repeatedCount:(uint32_t)count {
+  // Must match -setPackedFields:repeatedCount:
+  // Must match -setPackedExtensions:repeatedCount:
+  // Must match -setUnpackedExtensions:repeatedCount:
+  for (uint32_t i = 0; i < count; ++i) {
+    [message.unpackedInt32Array addValue:601 + i * 100];
+  }
+  for (uint32_t i = 0; i < count; ++i) {
+    [message.unpackedInt64Array addValue:602 + i * 100];
+  }
+  for (uint32_t i = 0; i < count; ++i) {
+    [message.unpackedUint32Array addValue:603 + i * 100];
+  }
+  for (uint32_t i = 0; i < count; ++i) {
+    [message.unpackedUint64Array addValue:604 + i * 100];
+  }
+  for (uint32_t i = 0; i < count; ++i) {
+    [message.unpackedSint32Array addValue:605 + i * 100];
+  }
+  for (uint32_t i = 0; i < count; ++i) {
+    [message.unpackedSint64Array addValue:606 + i * 100];
+  }
+  for (uint32_t i = 0; i < count; ++i) {
+    [message.unpackedFixed32Array addValue:607 + i * 100];
+  }
+  for (uint32_t i = 0; i < count; ++i) {
+    [message.unpackedFixed64Array addValue:608 + i * 100];
+  }
+  for (uint32_t i = 0; i < count; ++i) {
+    [message.unpackedSfixed32Array addValue:609 + i * 100];
+  }
+  for (uint32_t i = 0; i < count; ++i) {
+    [message.unpackedSfixed64Array addValue:610 + i * 100];
+  }
+  for (uint32_t i = 0; i < count; ++i) {
+    [message.unpackedFloatArray addValue:611 + i * 100];
+  }
+  for (uint32_t i = 0; i < count; ++i) {
+    [message.unpackedDoubleArray addValue:612 + i * 100];
+  }
+  for (uint32_t i = 0; i < count; ++i) {
+    [message.unpackedBoolArray addValue:(i % 2) ? YES : NO];
+  }
+  for (uint32_t i = 0; i < count; ++i) {
+    [message.unpackedEnumArray
+        addValue:(i % 2) ? ForeignEnum_ForeignBar : ForeignEnum_ForeignBaz];
   }
 }
 
@@ -1708,6 +1853,9 @@ const uint32_t kGPBDefaultRepeatCount = 2;
 
 - (void)setPackedExtensions:(TestPackedExtensions *)message
               repeatedCount:(uint32_t)count {
+  // Must match -setPackedFields:repeatedCount:
+  // Must match -setUnpackedFields:repeatedCount:
+  // Must match -setUnpackedExtensions:repeatedCount:
   for (uint32_t i = 0; i < count; i++) {
     [message addExtension:[UnittestRoot packedInt32Extension]
                     value:@(601 + i * 100)];
@@ -1741,6 +1889,44 @@ const uint32_t kGPBDefaultRepeatCount = 2;
   }
 }
 
+- (void)setUnpackedExtensions:(TestUnpackedExtensions *)message
+                repeatedCount:(uint32_t)count {
+  // Must match -setPackedFields:repeatedCount:
+  // Must match -setUnpackedFields:repeatedCount:
+  // Must match -setPackedExtensions:repeatedCount:
+  for (uint32_t i = 0; i < count; i++) {
+    [message addExtension:[UnittestRoot unpackedInt32Extension]
+                    value:@(601 + i * 100)];
+    [message addExtension:[UnittestRoot unpackedInt64Extension]
+                    value:@(602 + i * 100)];
+    [message addExtension:[UnittestRoot unpackedUint32Extension]
+                    value:@(603 + i * 100)];
+    [message addExtension:[UnittestRoot unpackedUint64Extension]
+                    value:@(604 + i * 100)];
+    [message addExtension:[UnittestRoot unpackedSint32Extension]
+                    value:@(605 + i * 100)];
+    [message addExtension:[UnittestRoot unpackedSint64Extension]
+                    value:@(606 + i * 100)];
+    [message addExtension:[UnittestRoot unpackedFixed32Extension]
+                    value:@(607 + i * 100)];
+    [message addExtension:[UnittestRoot unpackedFixed64Extension]
+                    value:@(608 + i * 100)];
+    [message addExtension:[UnittestRoot unpackedSfixed32Extension]
+                    value:@(609 + i * 100)];
+    [message addExtension:[UnittestRoot unpackedSfixed64Extension]
+                    value:@(610 + i * 100)];
+    [message addExtension:[UnittestRoot unpackedFloatExtension]
+                    value:@(611 + i * 100)];
+    [message addExtension:[UnittestRoot unpackedDoubleExtension]
+                    value:@(612 + i * 100)];
+    [message addExtension:[UnittestRoot unpackedBoolExtension]
+                    value:@((i % 2) ? YES : NO)];
+    [message addExtension:[UnittestRoot unpackedEnumExtension]
+                    value:@((i % 2) ? ForeignEnum_ForeignBar
+                         : ForeignEnum_ForeignBaz)];
+  }
+}
+
 - (void)assertPackedExtensionsSet:(TestPackedExtensions *)message
                     repeatedCount:(uint32_t)count{
   XCTAssertEqual(count, [[message getExtension:[UnittestRoot packedInt32Extension]] count]);
@@ -1884,6 +2070,34 @@ const uint32_t kGPBDefaultRepeatCount = 2;
   XCTAssertEqualObjects(message.repeatedStringPieceArray, [message valueForKey:@"repeatedStringPieceArray"]);
   XCTAssertEqualObjects(message.repeatedCordArray, [message valueForKey:@"repeatedCordArray"]);
 
+  XCTAssertEqualObjects(@(message.repeatedInt32Array_Count), [message valueForKey:@"repeatedInt32Array_Count"]);
+  XCTAssertEqualObjects(@(message.repeatedInt64Array_Count), [message valueForKey:@"repeatedInt64Array_Count"]);
+  XCTAssertEqualObjects(@(message.repeatedUint32Array_Count), [message valueForKey:@"repeatedUint32Array_Count"]);
+  XCTAssertEqualObjects(@(message.repeatedUint64Array_Count), [message valueForKey:@"repeatedUint64Array_Count"]);
+  XCTAssertEqualObjects(@(message.repeatedSint32Array_Count), [message valueForKey:@"repeatedSint32Array_Count"]);
+  XCTAssertEqualObjects(@(message.repeatedSint64Array_Count), [message valueForKey:@"repeatedSint64Array_Count"]);
+  XCTAssertEqualObjects(@(message.repeatedFixed32Array_Count), [message valueForKey:@"repeatedFixed32Array_Count"]);
+  XCTAssertEqualObjects(@(message.repeatedFixed64Array_Count), [message valueForKey:@"repeatedFixed64Array_Count"]);
+  XCTAssertEqualObjects(@(message.repeatedSfixed32Array_Count), [message valueForKey:@"repeatedSfixed32Array_Count"]);
+  XCTAssertEqualObjects(@(message.repeatedSfixed64Array_Count), [message valueForKey:@"repeatedSfixed64Array_Count"]);
+  XCTAssertEqualObjects(@(message.repeatedFloatArray_Count), [message valueForKey:@"repeatedFloatArray_Count"]);
+  XCTAssertEqualObjects(@(message.repeatedDoubleArray_Count), [message valueForKey:@"repeatedDoubleArray_Count"]);
+  XCTAssertEqualObjects(@(message.repeatedBoolArray_Count), [message valueForKey:@"repeatedBoolArray_Count"]);
+  XCTAssertEqualObjects(@(message.repeatedStringArray_Count), [message valueForKey:@"repeatedStringArray_Count"]);
+  XCTAssertEqualObjects(@(message.repeatedBytesArray_Count), [message valueForKey:@"repeatedBytesArray_Count"]);
+
+  XCTAssertEqualObjects(@(message.repeatedGroupArray_Count), [message valueForKey:@"repeatedGroupArray_Count"]);
+  XCTAssertEqualObjects(@(message.repeatedNestedMessageArray_Count), [message valueForKey:@"repeatedNestedMessageArray_Count"]);
+  XCTAssertEqualObjects(@(message.repeatedForeignMessageArray_Count), [message valueForKey:@"repeatedForeignMessageArray_Count"]);
+  XCTAssertEqualObjects(@(message.repeatedImportMessageArray_Count), [message valueForKey:@"repeatedImportMessageArray_Count"]);
+
+  XCTAssertEqualObjects(@(message.repeatedNestedEnumArray_Count), [message valueForKey:@"repeatedNestedEnumArray_Count"]);
+  XCTAssertEqualObjects(@(message.repeatedForeignEnumArray_Count), [message valueForKey:@"repeatedForeignEnumArray_Count"]);
+  XCTAssertEqualObjects(@(message.repeatedImportEnumArray_Count), [message valueForKey:@"repeatedImportEnumArray_Count"]);
+
+  XCTAssertEqualObjects(@(message.repeatedStringPieceArray_Count), [message valueForKey:@"repeatedStringPieceArray_Count"]);
+  XCTAssertEqualObjects(@(message.repeatedCordArray_Count), [message valueForKey:@"repeatedCordArray_Count"]);
+
   // -----------------------------------------------------------------
 
   XCTAssertEqualObjects([message valueForKey:@"hasDefaultInt32"], @YES);

+ 1 - 2
objectivec/Tests/GPBUnittestProtos.m

@@ -40,16 +40,15 @@
 #import "google/protobuf/UnittestEmbedOptimizeFor.pbobjc.m"
 #import "google/protobuf/UnittestEmpty.pbobjc.m"
 #import "google/protobuf/UnittestEnormousDescriptor.pbobjc.m"
-#import "google/protobuf/UnittestFilter.pbobjc.m"
 #import "google/protobuf/UnittestImport.pbobjc.m"
 #import "google/protobuf/UnittestImportLite.pbobjc.m"
 #import "google/protobuf/UnittestImportPublic.pbobjc.m"
 #import "google/protobuf/UnittestImportPublicLite.pbobjc.m"
 #import "google/protobuf/UnittestLite.pbobjc.m"
 #import "google/protobuf/UnittestMset.pbobjc.m"
-#import "google/protobuf/UnittestNameMangling.pbobjc.m"
 #import "google/protobuf/UnittestNoGenericServices.pbobjc.m"
 #import "google/protobuf/UnittestObjc.pbobjc.m"
+#import "google/protobuf/UnittestObjcStartup.pbobjc.m"
 #import "google/protobuf/UnittestOptimizeFor.pbobjc.m"
 #import "google/protobuf/UnittestPreserveUnknownEnum.pbobjc.m"
 #import "google/protobuf/UnittestRuntimeProto2.pbobjc.m"

+ 24 - 23
objectivec/Tests/GPBUnknownFieldSetTest.m

@@ -30,7 +30,7 @@
 
 #import "GPBTestUtilities.h"
 
-#import "GPBField_PackagePrivate.h"
+#import "GPBUnknownField_PackagePrivate.h"
 #import "GPBUnknownFieldSet_PackagePrivate.h"
 #import "google/protobuf/Unittest.pbobjc.h"
 
@@ -60,7 +60,7 @@
   unknownFields_ = emptyMessage_.unknownFields;
 }
 
-- (GPBField*)getField:(int32_t)number {
+- (GPBUnknownField *)getField:(int32_t)number {
   return [unknownFields_ getField:number];
 }
 
@@ -75,17 +75,17 @@
   [unknownFields_ getTags:tags];
   for (NSUInteger i = 0; i < count; ++i) {
     int32_t tag = tags[i];
-    GPBField* field = [unknownFields_ getField:tag];
+    GPBUnknownField* field = [unknownFields_ getField:tag];
     if (field.varintList.count == 0) {
       // Original field is not a varint, so use a varint.
-      GPBField* varintField =
-          [[[GPBField alloc] initWithNumber:tag] autorelease];
+      GPBUnknownField* varintField =
+          [[[GPBUnknownField alloc] initWithNumber:tag] autorelease];
       [varintField addVarint:1];
       [bizarroFields addField:varintField];
     } else {
       // Original field *is* a varint, so use something else.
-      GPBField* fixed32Field =
-          [[[GPBField alloc] initWithNumber:tag] autorelease];
+      GPBUnknownField* fixed32Field =
+          [[[GPBUnknownField alloc] initWithNumber:tag] autorelease];
       [fixed32Field addFixed32:1];
       [bizarroFields addField:fixed32Field];
     }
@@ -110,34 +110,34 @@
 
 - (void)testMergeFrom {
   GPBUnknownFieldSet* set1 = [[[GPBUnknownFieldSet alloc] init] autorelease];
-  GPBField* field = [[[GPBField alloc] initWithNumber:2] autorelease];
+  GPBUnknownField* field = [[[GPBUnknownField alloc] initWithNumber:2] autorelease];
   [field addVarint:2];
   [set1 addField:field];
-  field = [[[GPBField alloc] initWithNumber:3] autorelease];
+  field = [[[GPBUnknownField alloc] initWithNumber:3] autorelease];
   [field addVarint:4];
   [set1 addField:field];
 
   GPBUnknownFieldSet* set2 = [[[GPBUnknownFieldSet alloc] init] autorelease];
-  field = [[[GPBField alloc] initWithNumber:1] autorelease];
+  field = [[[GPBUnknownField alloc] initWithNumber:1] autorelease];
   [field addVarint:1];
   [set2 addField:field];
-  field = [[[GPBField alloc] initWithNumber:3] autorelease];
+  field = [[[GPBUnknownField alloc] initWithNumber:3] autorelease];
   [field addVarint:3];
   [set2 addField:field];
 
   GPBUnknownFieldSet* set3 = [[[GPBUnknownFieldSet alloc] init] autorelease];
-  field = [[[GPBField alloc] initWithNumber:1] autorelease];
+  field = [[[GPBUnknownField alloc] initWithNumber:1] autorelease];
   [field addVarint:1];
   [set3 addField:field];
-  field = [[[GPBField alloc] initWithNumber:3] autorelease];
+  field = [[[GPBUnknownField alloc] initWithNumber:3] autorelease];
   [field addVarint:4];
   [set3 addField:field];
 
   GPBUnknownFieldSet* set4 = [[[GPBUnknownFieldSet alloc] init] autorelease];
-  field = [[[GPBField alloc] initWithNumber:2] autorelease];
+  field = [[[GPBUnknownField alloc] initWithNumber:2] autorelease];
   [field addVarint:2];
   [set4 addField:field];
-  field = [[[GPBField alloc] initWithNumber:3] autorelease];
+  field = [[[GPBUnknownField alloc] initWithNumber:3] autorelease];
   [field addVarint:3];
   [set4 addField:field];
 
@@ -162,7 +162,7 @@
 }
 
 - (void)testClearMessage {
-  TestEmptyMessage* message = [TestEmptyMessage message];
+  TestEmptyMessage *message = [TestEmptyMessage message];
   [message mergeFrom:emptyMessage_];
   [message clear];
   XCTAssertEqual(message.serializedSize, (size_t)0);
@@ -170,8 +170,9 @@
 
 - (void)testParseKnownAndUnknown {
   // Test mixing known and unknown fields when parsing.
-  GPBUnknownFieldSet* fields = [[unknownFields_ copy] autorelease];
-  GPBField* field = [[[GPBField alloc] initWithNumber:123456] autorelease];
+  GPBUnknownFieldSet *fields = [[unknownFields_ copy] autorelease];
+  GPBUnknownField *field =
+    [[[GPBUnknownField alloc] initWithNumber:123456] autorelease];
   [field addVarint:654321];
   [fields addField:field];
 
@@ -181,7 +182,7 @@
   [self assertAllFieldsSet:destination repeatedCount:kGPBDefaultRepeatCount];
   XCTAssertEqual(destination.unknownFields.countOfFields, (NSUInteger)1);
 
-  GPBField* field2 = [destination.unknownFields getField:123456];
+  GPBUnknownField* field2 = [destination.unknownFields getField:123456];
   XCTAssertEqual(field2.varintList.count, (NSUInteger)1);
   XCTAssertEqual(654321ULL, [field2.varintList valueAtIndex:0]);
 }
@@ -230,7 +231,7 @@
 
 - (void)testLargeVarint {
   GPBUnknownFieldSet* fields = [[unknownFields_ copy] autorelease];
-  GPBField* field = [[[GPBField alloc] initWithNumber:1] autorelease];
+  GPBUnknownField* field = [[[GPBUnknownField alloc] initWithNumber:1] autorelease];
   [field addVarint:0x7FFFFFFFFFFFFFFFL];
   [fields addField:field];
 
@@ -238,19 +239,19 @@
 
   GPBUnknownFieldSet* parsed = [[[GPBUnknownFieldSet alloc] init] autorelease];
   [parsed mergeFromData:data];
-  GPBField* field2 = [parsed getField:1];
+  GPBUnknownField* field2 = [parsed getField:1];
   XCTAssertEqual(field2.varintList.count, (NSUInteger)1);
   XCTAssertEqual(0x7FFFFFFFFFFFFFFFULL, [field2.varintList valueAtIndex:0]);
 }
 
 - (void)testMergingFields {
-  GPBField* field1 = [[[GPBField alloc] initWithNumber:1] autorelease];
+  GPBUnknownField* field1 = [[[GPBUnknownField alloc] initWithNumber:1] autorelease];
   [field1 addVarint:1];
   [field1 addFixed32:2];
   [field1 addFixed64:3];
   [field1 addLengthDelimited:[NSData dataWithBytes:"hello" length:5]];
   [field1 addGroup:[[unknownFields_ copy] autorelease]];
-  GPBField* field2 = [[[GPBField alloc] initWithNumber:2] autorelease];
+  GPBUnknownField* field2 = [[[GPBUnknownField alloc] initWithNumber:2] autorelease];
   [field2 mergeFromField:field1];
   XCTAssertEqualObjects(field1, field2);
 }

+ 0 - 190
objectivec/Tests/GPBUtilitiesTests.m

@@ -47,141 +47,6 @@
 @interface UtilitiesTests : GPBTestCase
 @end
 
-// Support code for testing
-typedef struct {
-  uint32_t _has_storage_[1];
-  BOOL aBool;
-  int32_t aInt32;
-  uint32_t aUInt32;
-  int64_t aInt64;
-  uint64_t aUInt64;
-  float aFloat;
-  double aDouble;
-  id aObject;
-  BOOL _hasTest;
-  BOOL stopper;
-  BOOL shouldNotBeCounted;
-  GPBInt32Array *anArray;
-} ApplyFunctionsTest_Storage;
-
-@interface ApplyFunctionsTest : GPBMessage
-@property(nonatomic, readwrite) BOOL aBool;
-@property(nonatomic, readwrite) int32_t aInt32;
-@property(nonatomic, readwrite) uint32_t aUInt32;
-@property(nonatomic, readwrite) int64_t aInt64;
-@property(nonatomic, readwrite) uint64_t aUInt64;
-@property(nonatomic, readwrite) float aFloat;
-@property(nonatomic, readwrite) double aDouble;
-@property(nonatomic, readwrite, retain) id aObject;
-@property(nonatomic, readwrite) BOOL _hasTest;
-@property(nonatomic, readwrite) BOOL stopper;
-@property(nonatomic, readwrite) BOOL shouldNotBeCounted;
-@property(nonatomic, readwrite, retain) GPBInt32Array *anArray;
-@end
-
-@implementation ApplyFunctionsTest
-
-@dynamic aBool, aInt32, aUInt32, aInt64, aUInt64, aFloat, aDouble, aObject;
-@dynamic _hasTest, stopper, shouldNotBeCounted, anArray;
-
-+ (GPBDescriptor *)descriptor {
-  static GPBDescriptor *descriptor = NULL;
-  if (!descriptor) {
-    static GPBMessageFieldDescription fields[] = {
-#define FIELD_ENTRY(NAME, INDEX)                                 \
-  {                                                              \
-    .name = "a" #NAME, .hasIndex = INDEX, .type = GPBType##NAME, \
-    .offset = offsetof(ApplyFunctionsTest_Storage, a##NAME),     \
-  }
-        FIELD_ENTRY(Bool, 1),
-        FIELD_ENTRY(Int32, 2),
-        FIELD_ENTRY(UInt32, 3),
-        FIELD_ENTRY(Int64, 4),
-        FIELD_ENTRY(UInt64, 5),
-        FIELD_ENTRY(Float, 6),
-        FIELD_ENTRY(Double, 7),
-#undef FIELD_ENTRY
-        {
-         .name = "aObject",
-         .type = GPBTypeString,
-         .hasIndex = 8,
-         .offset = offsetof(ApplyFunctionsTest_Storage, aObject),
-        },
-        {
-         .name = "stopper",
-         .type = GPBTypeBool,
-         .hasIndex = 9,
-         .offset = offsetof(ApplyFunctionsTest_Storage, stopper),
-        },
-        {
-         .name = "shouldNotBeCounted",
-         .type = GPBTypeBool,
-         .hasIndex = 10,
-         .offset = offsetof(ApplyFunctionsTest_Storage, shouldNotBeCounted),
-        },
-        {
-         .name = "anArray",
-         .type = GPBTypeInt32,
-         .hasIndex = 11,
-         .flags = GPBFieldRepeated,
-         .offset = offsetof(ApplyFunctionsTest_Storage, anArray),
-        },
-    };
-    descriptor = [GPBDescriptor
-        allocDescriptorForClass:[self class]
-                      rootClass:Nil
-                           file:nil
-                         fields:fields
-                     fieldCount:sizeof(fields) /
-                                sizeof(GPBMessageFieldDescription)
-                         oneofs:NULL
-                     oneofCount:0
-                          enums:NULL
-                      enumCount:0
-                         ranges:NULL
-                     rangeCount:0
-                    storageSize:sizeof(ApplyFunctionsTest_Storage)
-                     wireFormat:NO];
-  }
-  return descriptor;
-}
-
-@end
-
-typedef struct {
-  int calledBool;
-  int calledInt32;
-  int calledUInt32;
-  int calledInt64;
-  int calledUInt64;
-  int calledFloat;
-  int calledDouble;
-  int calledObject;
-  int hitCount;
-} TestApplyFunctionsContext;
-
-// Really, who needs templates?
-// Macro for testing apply functions. Declares a variety of different functions
-// base on |NAME|.
-#define TEST_APPLY_FUNCTIONS_FUNC(NAME)                          \
-  static BOOL TestApplyFunction##NAME(GPBFieldDescriptor *field, \
-                                      void *voidContext) {       \
-    TestApplyFunctionsContext *context = voidContext;            \
-    if (field->getSel_ == sel_getUid("stopper")) return NO;      \
-    context->called##NAME += 1;                                  \
-    context->hitCount += 1;                                      \
-    return YES;                                                  \
-  }
-
-TEST_APPLY_FUNCTIONS_FUNC(Bool)
-TEST_APPLY_FUNCTIONS_FUNC(Int32)
-TEST_APPLY_FUNCTIONS_FUNC(UInt32)
-TEST_APPLY_FUNCTIONS_FUNC(Int64)
-TEST_APPLY_FUNCTIONS_FUNC(UInt64)
-TEST_APPLY_FUNCTIONS_FUNC(Float)
-TEST_APPLY_FUNCTIONS_FUNC(Double)
-TEST_APPLY_FUNCTIONS_FUNC(Object)
-
 @implementation UtilitiesTests
 
 - (void)testRightShiftFunctions {
@@ -194,61 +59,6 @@ TEST_APPLY_FUNCTIONS_FUNC(Object)
   XCTAssertEqual(GPBLogicalRightShift64((1LL << 63), 63), 1LL);
 }
 
-- (void)testMutability {
-  ApplyFunctionsTest *foo_message = [ApplyFunctionsTest message];
-  XCTAssertEqual(0, [foo_message aInt32]);
-  [foo_message setAInt32:100];
-  XCTAssertEqual(100, [foo_message aInt32]);
-}
-
-- (void)testSerializedSize {
-  ApplyFunctionsTest *foo_message = [ApplyFunctionsTest message];
-  [foo_message setAInt32:100];
-  size_t size1 = [foo_message serializedSize];
-  [foo_message setAInt64:100];
-  size_t size2 = [foo_message serializedSize];
-
-  // Intentionally doing a pointer comparison.
-  XCTAssertNotEqual(size1, size2);
-}
-
-- (void)testCopying {
-  ApplyFunctionsTest *foo_message = [ApplyFunctionsTest message];
-  [foo_message setAInt32:100];
-  [foo_message setAObject:@"Happy"];
-  ApplyFunctionsTest *foo = [[foo_message copy] autorelease];
-  XCTAssertNotEqual(foo, foo_message);  // Pointer comparision
-  XCTAssertEqualObjects(foo, foo_message);
-}
-
-- (void)testApplyFunctions {
-  // Covers ApplyFunctionsToProtoVariables and
-  // ApplyFunctionsBasedOnEncodingType.
-  // This test depends on the layout of the ivars to be in the order
-  // declared in the interface. If this is not true, it will fail and will
-  // need to be rewritten to accomodate.
-  TestApplyFunctionsContext context;
-  memset(&context, 0, sizeof(context));
-  GPBApplyFunctions foo = GPBAPPLY_FUNCTIONS_INIT(TestApplyFunction);
-  ApplyFunctionsTest *msg = [ApplyFunctionsTest message];
-  GPBApplyFunctionsToMessageFields(&foo, msg, &context);
-
-  // Only eight vars should be set.
-  // "stopper" should cause the loop to quit so it and shouldNotBeCounted should
-  // not be counted.
-  // "_hasTest" should be skipped over.
-  // Each of the vars should only be set once.
-  XCTAssertEqual(context.hitCount, 8);
-  XCTAssertEqual(context.calledBool, 1);
-  XCTAssertEqual(context.calledInt32, 1);
-  XCTAssertEqual(context.calledUInt32, 1);
-  XCTAssertEqual(context.calledInt64, 1);
-  XCTAssertEqual(context.calledUInt64, 1);
-  XCTAssertEqual(context.calledFloat, 1);
-  XCTAssertEqual(context.calledDouble, 1);
-  XCTAssertEqual(context.calledObject, 1);
-}
-
 - (void)testGPBDecodeTextFormatName {
   uint8_t decodeData[] = {
     0x6,

+ 6 - 6
objectivec/Tests/GPBWireFormatTests.m

@@ -32,7 +32,7 @@
 
 #import "GPBCodedInputStream.h"
 #import "GPBMessage_PackagePrivate.h"
-#import "GPBField_PackagePrivate.h"
+#import "GPBUnknownField_PackagePrivate.h"
 #import "google/protobuf/Unittest.pbobjc.h"
 #import "google/protobuf/UnittestMset.pbobjc.h"
 
@@ -143,8 +143,8 @@ const int kUnknownTypeId = 1550055;
       setI:123];
   [[message_set getExtension:[TestMessageSetExtension2 messageSetExtension]]
       setStr:@"foo"];
-  GPBField* unknownField =
-      [[[GPBField alloc] initWithNumber:kUnknownTypeId] autorelease];
+  GPBUnknownField* unknownField =
+      [[[GPBUnknownField alloc] initWithNumber:kUnknownTypeId] autorelease];
   [unknownField addLengthDelimited:[NSData dataWithBytes:"bar" length:3]];
   GPBUnknownFieldSet* unknownFieldSet =
       [[[GPBUnknownFieldSet alloc] init] autorelease];
@@ -159,9 +159,9 @@ const int kUnknownTypeId = 1550055;
   XCTAssertEqual([raw.unknownFields countOfFields], (NSUInteger)0);
 
   XCTAssertEqual(raw.itemArray.count, (NSUInteger)3);
-  XCTAssertEqual([raw.itemArray[0] typeId],
+  XCTAssertEqual((uint32_t)[raw.itemArray[0] typeId],
                  [TestMessageSetExtension1 messageSetExtension].fieldNumber);
-  XCTAssertEqual([raw.itemArray[1] typeId],
+  XCTAssertEqual((uint32_t)[raw.itemArray[1] typeId],
                  [TestMessageSetExtension2 messageSetExtension].fieldNumber);
   XCTAssertEqual([raw.itemArray[2] typeId], kUnknownTypeId);
 
@@ -227,7 +227,7 @@ const int kUnknownTypeId = 1550055;
       @"foo");
 
   XCTAssertEqual([messageSet.unknownFields countOfFields], (NSUInteger)1);
-  GPBField* unknownField = [messageSet.unknownFields getField:kUnknownTypeId];
+  GPBUnknownField* unknownField = [messageSet.unknownFields getField:kUnknownTypeId];
   XCTAssertNotNil(unknownField);
   XCTAssertEqual(unknownField.lengthDelimitedList.count, (NSUInteger)1);
   XCTAssertEqualObjects(unknownField.lengthDelimitedList[0],

+ 0 - 71
objectivec/Tests/unittest_filter.proto

@@ -1,71 +0,0 @@
-// Protocol Buffers - Google's data interchange format
-// Copyright 2013 Google Inc.  All rights reserved.
-//
-// 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.
-
-syntax = "proto2";
-
-package protobuf_unittest;
-
-
-message Keep {
-}
-
-message Remove {
-}
-
-message RemoveJustKidding {
-}
-
-message Other {
-  optional Keep a = 1;
-  optional Remove b = 2;
-}
-
-enum RemoveEnum {
-  RemoveValue = 1;
-}
-
-enum KeepEnum {
-  KeepValue = 1;
-}
-
-message RemoveEnumMessage {
-  enum KeepEnumInside {
-    KeepValue = 1;
-  }
-
-  enum RemoveEnumInside {
-    RemoveValue = 1;
-  }
-
-  message KeepNestedInside {
-  }
-
-  message RemoveNestedInside {
-  }
-}

+ 0 - 37
objectivec/Tests/unittest_name_mangling.proto

@@ -1,37 +0,0 @@
-// Protocol Buffers - Google's data interchange format
-// Copyright 2015 Google Inc.  All rights reserved.
-//
-// 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.
-
-syntax = "proto2";
-
-option objc_class_prefix = "ABC";
-
-package protobuf_unittest;
-
-// TODO(thomasvl): Add tests for the special cases in name mangling.
-

+ 17 - 8
objectivec/Tests/Filter1.txt → objectivec/Tests/unittest_objc_startup.proto

@@ -1,5 +1,5 @@
 // Protocol Buffers - Google's data interchange format
-// Copyright 2014 Google Inc.  All rights reserved.
+// Copyright 2008 Google Inc.  All rights reserved.
 // https://developers.google.com/protocol-buffers/
 //
 // Redistribution and use in source and binary forms, with or without
@@ -28,13 +28,22 @@
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
+syntax = "proto2";
 
-// Test the filter system for the ObjC Protocol Buffer Compiler.
+package protobuf_objc_unittest;
 
-// Class names are matched using file name globbing rules.
-// Whitespace is not allowed at the beginning of a line (except for a line
-// that is a single newline).
+message TestObjCStartupMessage {
+  extensions 1 to max;
+}
 
-Keep
-RemoveEnumMessage_KeepNestedInside
-RemoveJustKidding
+extend TestObjCStartupMessage {
+  // Singular
+  optional    int32 optional_int32_extension    = 1;
+  repeated    int32 repeated_int32_extension    = 2;
+}
+
+message TestObjCStartupNested {
+  extend TestObjCStartupMessage {
+    optional string nested_string_extension = 3;
+  }
+}

+ 29 - 23
objectivec/google/protobuf/Any.pbobjc.m

@@ -11,11 +11,14 @@
 
 @end
 
+#pragma mark - GPBAnyRoot_FileDescriptor
+
 static GPBFileDescriptor *GPBAnyRoot_FileDescriptor(void) {
   // This is called by +initialize so there is no need to worry
   // about thread safety of the singleton.
   static GPBFileDescriptor *descriptor = NULL;
   if (!descriptor) {
+    GPBDebugCheckRuntimeVersion();
     descriptor = [[GPBFileDescriptor alloc] initWithPackage:@"google.protobuf"
                                                      syntax:GPBFileSyntaxProto3];
   }
@@ -29,16 +32,16 @@ static GPBFileDescriptor *GPBAnyRoot_FileDescriptor(void) {
 @dynamic typeURL;
 @dynamic value;
 
-typedef struct GPBAny_Storage {
+typedef struct GPBAny__storage_ {
   uint32_t _has_storage_[1];
   NSString *typeURL;
   NSData *value;
-} GPBAny_Storage;
+} GPBAny__storage_;
 
 // This method is threadsafe because it is initially called
 // in +initialize for each subclass.
 + (GPBDescriptor *)descriptor {
-  static GPBDescriptor *descriptor = NULL;
+  static GPBDescriptor *descriptor = nil;
   if (!descriptor) {
     static GPBMessageFieldDescription fields[] = {
       {
@@ -46,10 +49,10 @@ typedef struct GPBAny_Storage {
         .number = GPBAny_FieldNumber_TypeURL,
         .hasIndex = 0,
         .flags = GPBFieldOptional | GPBFieldTextFormatNameCustom,
-        .type = GPBTypeString,
-        .offset = offsetof(GPBAny_Storage, typeURL),
+        .dataType = GPBDataTypeString,
+        .offset = offsetof(GPBAny__storage_, typeURL),
         .defaultValue.valueString = nil,
-        .typeSpecific.className = NULL,
+        .dataTypeSpecific.className = NULL,
         .fieldOptions = NULL,
       },
       {
@@ -57,10 +60,10 @@ typedef struct GPBAny_Storage {
         .number = GPBAny_FieldNumber_Value,
         .hasIndex = 1,
         .flags = GPBFieldOptional,
-        .type = GPBTypeData,
-        .offset = offsetof(GPBAny_Storage, value),
+        .dataType = GPBDataTypeBytes,
+        .offset = offsetof(GPBAny__storage_, value),
         .defaultValue.valueData = nil,
-        .typeSpecific.className = NULL,
+        .dataTypeSpecific.className = NULL,
         .fieldOptions = NULL,
       },
     };
@@ -69,20 +72,23 @@ typedef struct GPBAny_Storage {
 #else
     static const char *extraTextFormatInfo = "\001\001\004\241!!\000";
 #endif  // GPBOBJC_SKIP_MESSAGE_TEXTFORMAT_EXTRAS
-    descriptor = [GPBDescriptor allocDescriptorForClass:[GPBAny class]
-                                              rootClass:[GPBAnyRoot class]
-                                                   file:GPBAnyRoot_FileDescriptor()
-                                                 fields:fields
-                                             fieldCount:sizeof(fields) / sizeof(GPBMessageFieldDescription)
-                                                 oneofs:NULL
-                                             oneofCount:0
-                                                  enums:NULL
-                                              enumCount:0
-                                                 ranges:NULL
-                                             rangeCount:0
-                                            storageSize:sizeof(GPBAny_Storage)
-                                             wireFormat:NO
-                                    extraTextFormatInfo:extraTextFormatInfo];
+    GPBDescriptor *localDescriptor =
+        [GPBDescriptor allocDescriptorForClass:[GPBAny class]
+                                     rootClass:[GPBAnyRoot class]
+                                          file:GPBAnyRoot_FileDescriptor()
+                                        fields:fields
+                                    fieldCount:sizeof(fields) / sizeof(GPBMessageFieldDescription)
+                                        oneofs:NULL
+                                    oneofCount:0
+                                         enums:NULL
+                                     enumCount:0
+                                        ranges:NULL
+                                    rangeCount:0
+                                   storageSize:sizeof(GPBAny__storage_)
+                                    wireFormat:NO
+                           extraTextFormatInfo:extraTextFormatInfo];
+    NSAssert(descriptor == nil, @"Startup recursed!");
+    descriptor = localDescriptor;
   }
   return descriptor;
 }

+ 3 - 0
objectivec/google/protobuf/Api.pbobjc.h

@@ -45,10 +45,12 @@ typedef GPB_ENUM(GPBApi_FieldNumber) {
 // The methods of this api, in unspecified order.
 // |methodsArray| contains |GPBMethod|
 @property(nonatomic, readwrite, strong) NSMutableArray *methodsArray;
+@property(nonatomic, readonly) NSUInteger methodsArray_Count;
 
 // Any metadata attached to the API.
 // |optionsArray| contains |GPBOption|
 @property(nonatomic, readwrite, strong) NSMutableArray *optionsArray;
+@property(nonatomic, readonly) NSUInteger optionsArray_Count;
 
 // A version string for this api. If specified, must have the form
 // `major-version.minor-version`, as in `1.10`. If the minor version
@@ -113,6 +115,7 @@ typedef GPB_ENUM(GPBMethod_FieldNumber) {
 // Any metadata attached to the method.
 // |optionsArray| contains |GPBOption|
 @property(nonatomic, readwrite, strong) NSMutableArray *optionsArray;
+@property(nonatomic, readonly) NSUInteger optionsArray_Count;
 
 @end
 

+ 79 - 72
objectivec/google/protobuf/Api.pbobjc.m

@@ -16,10 +16,8 @@
   // about thread safety and initialization of registry.
   static GPBExtensionRegistry* registry = nil;
   if (!registry) {
+    GPBDebugCheckRuntimeVersion();
     registry = [[GPBExtensionRegistry alloc] init];
-    static GPBExtensionDescription descriptions[] = {
-    };
-    #pragma unused (descriptions)
     [registry addExtensions:[GPBSourceContextRoot extensionRegistry]];
     [registry addExtensions:[GPBTypeRoot extensionRegistry]];
   }
@@ -28,11 +26,14 @@
 
 @end
 
+#pragma mark - GPBApiRoot_FileDescriptor
+
 static GPBFileDescriptor *GPBApiRoot_FileDescriptor(void) {
   // This is called by +initialize so there is no need to worry
   // about thread safety of the singleton.
   static GPBFileDescriptor *descriptor = NULL;
   if (!descriptor) {
+    GPBDebugCheckRuntimeVersion();
     descriptor = [[GPBFileDescriptor alloc] initWithPackage:@"google.protobuf"
                                                      syntax:GPBFileSyntaxProto3];
   }
@@ -44,24 +45,24 @@ static GPBFileDescriptor *GPBApiRoot_FileDescriptor(void) {
 @implementation GPBApi
 
 @dynamic name;
-@dynamic methodsArray;
-@dynamic optionsArray;
+@dynamic methodsArray, methodsArray_Count;
+@dynamic optionsArray, optionsArray_Count;
 @dynamic version;
 @dynamic hasSourceContext, sourceContext;
 
-typedef struct GPBApi_Storage {
+typedef struct GPBApi__storage_ {
   uint32_t _has_storage_[1];
   NSString *name;
   NSMutableArray *methodsArray;
   NSMutableArray *optionsArray;
   NSString *version;
   GPBSourceContext *sourceContext;
-} GPBApi_Storage;
+} GPBApi__storage_;
 
 // This method is threadsafe because it is initially called
 // in +initialize for each subclass.
 + (GPBDescriptor *)descriptor {
-  static GPBDescriptor *descriptor = NULL;
+  static GPBDescriptor *descriptor = nil;
   if (!descriptor) {
     static GPBMessageFieldDescription fields[] = {
       {
@@ -69,10 +70,10 @@ typedef struct GPBApi_Storage {
         .number = GPBApi_FieldNumber_Name,
         .hasIndex = 0,
         .flags = GPBFieldOptional,
-        .type = GPBTypeString,
-        .offset = offsetof(GPBApi_Storage, name),
+        .dataType = GPBDataTypeString,
+        .offset = offsetof(GPBApi__storage_, name),
         .defaultValue.valueString = nil,
-        .typeSpecific.className = NULL,
+        .dataTypeSpecific.className = NULL,
         .fieldOptions = NULL,
       },
       {
@@ -80,10 +81,10 @@ typedef struct GPBApi_Storage {
         .number = GPBApi_FieldNumber_MethodsArray,
         .hasIndex = GPBNoHasBit,
         .flags = GPBFieldRepeated,
-        .type = GPBTypeMessage,
-        .offset = offsetof(GPBApi_Storage, methodsArray),
+        .dataType = GPBDataTypeMessage,
+        .offset = offsetof(GPBApi__storage_, methodsArray),
         .defaultValue.valueMessage = nil,
-        .typeSpecific.className = GPBStringifySymbol(GPBMethod),
+        .dataTypeSpecific.className = GPBStringifySymbol(GPBMethod),
         .fieldOptions = NULL,
       },
       {
@@ -91,10 +92,10 @@ typedef struct GPBApi_Storage {
         .number = GPBApi_FieldNumber_OptionsArray,
         .hasIndex = GPBNoHasBit,
         .flags = GPBFieldRepeated,
-        .type = GPBTypeMessage,
-        .offset = offsetof(GPBApi_Storage, optionsArray),
+        .dataType = GPBDataTypeMessage,
+        .offset = offsetof(GPBApi__storage_, optionsArray),
         .defaultValue.valueMessage = nil,
-        .typeSpecific.className = GPBStringifySymbol(GPBOption),
+        .dataTypeSpecific.className = GPBStringifySymbol(GPBOption),
         .fieldOptions = NULL,
       },
       {
@@ -102,10 +103,10 @@ typedef struct GPBApi_Storage {
         .number = GPBApi_FieldNumber_Version,
         .hasIndex = 3,
         .flags = GPBFieldOptional,
-        .type = GPBTypeString,
-        .offset = offsetof(GPBApi_Storage, version),
+        .dataType = GPBDataTypeString,
+        .offset = offsetof(GPBApi__storage_, version),
         .defaultValue.valueString = nil,
-        .typeSpecific.className = NULL,
+        .dataTypeSpecific.className = NULL,
         .fieldOptions = NULL,
       },
       {
@@ -113,26 +114,29 @@ typedef struct GPBApi_Storage {
         .number = GPBApi_FieldNumber_SourceContext,
         .hasIndex = 4,
         .flags = GPBFieldOptional,
-        .type = GPBTypeMessage,
-        .offset = offsetof(GPBApi_Storage, sourceContext),
+        .dataType = GPBDataTypeMessage,
+        .offset = offsetof(GPBApi__storage_, sourceContext),
         .defaultValue.valueMessage = nil,
-        .typeSpecific.className = GPBStringifySymbol(GPBSourceContext),
+        .dataTypeSpecific.className = GPBStringifySymbol(GPBSourceContext),
         .fieldOptions = NULL,
       },
     };
-    descriptor = [GPBDescriptor allocDescriptorForClass:[GPBApi class]
-                                              rootClass:[GPBApiRoot class]
-                                                   file:GPBApiRoot_FileDescriptor()
-                                                 fields:fields
-                                             fieldCount:sizeof(fields) / sizeof(GPBMessageFieldDescription)
-                                                 oneofs:NULL
-                                             oneofCount:0
-                                                  enums:NULL
-                                              enumCount:0
-                                                 ranges:NULL
-                                             rangeCount:0
-                                            storageSize:sizeof(GPBApi_Storage)
-                                             wireFormat:NO];
+    GPBDescriptor *localDescriptor =
+        [GPBDescriptor allocDescriptorForClass:[GPBApi class]
+                                     rootClass:[GPBApiRoot class]
+                                          file:GPBApiRoot_FileDescriptor()
+                                        fields:fields
+                                    fieldCount:sizeof(fields) / sizeof(GPBMessageFieldDescription)
+                                        oneofs:NULL
+                                    oneofCount:0
+                                         enums:NULL
+                                     enumCount:0
+                                        ranges:NULL
+                                    rangeCount:0
+                                   storageSize:sizeof(GPBApi__storage_)
+                                    wireFormat:NO];
+    NSAssert(descriptor == nil, @"Startup recursed!");
+    descriptor = localDescriptor;
   }
   return descriptor;
 }
@@ -148,9 +152,9 @@ typedef struct GPBApi_Storage {
 @dynamic requestStreaming;
 @dynamic responseTypeURL;
 @dynamic responseStreaming;
-@dynamic optionsArray;
+@dynamic optionsArray, optionsArray_Count;
 
-typedef struct GPBMethod_Storage {
+typedef struct GPBMethod__storage_ {
   uint32_t _has_storage_[1];
   BOOL requestStreaming;
   BOOL responseStreaming;
@@ -158,12 +162,12 @@ typedef struct GPBMethod_Storage {
   NSString *requestTypeURL;
   NSString *responseTypeURL;
   NSMutableArray *optionsArray;
-} GPBMethod_Storage;
+} GPBMethod__storage_;
 
 // This method is threadsafe because it is initially called
 // in +initialize for each subclass.
 + (GPBDescriptor *)descriptor {
-  static GPBDescriptor *descriptor = NULL;
+  static GPBDescriptor *descriptor = nil;
   if (!descriptor) {
     static GPBMessageFieldDescription fields[] = {
       {
@@ -171,10 +175,10 @@ typedef struct GPBMethod_Storage {
         .number = GPBMethod_FieldNumber_Name,
         .hasIndex = 0,
         .flags = GPBFieldOptional,
-        .type = GPBTypeString,
-        .offset = offsetof(GPBMethod_Storage, name),
+        .dataType = GPBDataTypeString,
+        .offset = offsetof(GPBMethod__storage_, name),
         .defaultValue.valueString = nil,
-        .typeSpecific.className = NULL,
+        .dataTypeSpecific.className = NULL,
         .fieldOptions = NULL,
       },
       {
@@ -182,10 +186,10 @@ typedef struct GPBMethod_Storage {
         .number = GPBMethod_FieldNumber_RequestTypeURL,
         .hasIndex = 1,
         .flags = GPBFieldOptional | GPBFieldTextFormatNameCustom,
-        .type = GPBTypeString,
-        .offset = offsetof(GPBMethod_Storage, requestTypeURL),
+        .dataType = GPBDataTypeString,
+        .offset = offsetof(GPBMethod__storage_, requestTypeURL),
         .defaultValue.valueString = nil,
-        .typeSpecific.className = NULL,
+        .dataTypeSpecific.className = NULL,
         .fieldOptions = NULL,
       },
       {
@@ -193,10 +197,10 @@ typedef struct GPBMethod_Storage {
         .number = GPBMethod_FieldNumber_RequestStreaming,
         .hasIndex = 2,
         .flags = GPBFieldOptional,
-        .type = GPBTypeBool,
-        .offset = offsetof(GPBMethod_Storage, requestStreaming),
+        .dataType = GPBDataTypeBool,
+        .offset = offsetof(GPBMethod__storage_, requestStreaming),
         .defaultValue.valueBool = NO,
-        .typeSpecific.className = NULL,
+        .dataTypeSpecific.className = NULL,
         .fieldOptions = NULL,
       },
       {
@@ -204,10 +208,10 @@ typedef struct GPBMethod_Storage {
         .number = GPBMethod_FieldNumber_ResponseTypeURL,
         .hasIndex = 3,
         .flags = GPBFieldOptional | GPBFieldTextFormatNameCustom,
-        .type = GPBTypeString,
-        .offset = offsetof(GPBMethod_Storage, responseTypeURL),
+        .dataType = GPBDataTypeString,
+        .offset = offsetof(GPBMethod__storage_, responseTypeURL),
         .defaultValue.valueString = nil,
-        .typeSpecific.className = NULL,
+        .dataTypeSpecific.className = NULL,
         .fieldOptions = NULL,
       },
       {
@@ -215,10 +219,10 @@ typedef struct GPBMethod_Storage {
         .number = GPBMethod_FieldNumber_ResponseStreaming,
         .hasIndex = 4,
         .flags = GPBFieldOptional,
-        .type = GPBTypeBool,
-        .offset = offsetof(GPBMethod_Storage, responseStreaming),
+        .dataType = GPBDataTypeBool,
+        .offset = offsetof(GPBMethod__storage_, responseStreaming),
         .defaultValue.valueBool = NO,
-        .typeSpecific.className = NULL,
+        .dataTypeSpecific.className = NULL,
         .fieldOptions = NULL,
       },
       {
@@ -226,10 +230,10 @@ typedef struct GPBMethod_Storage {
         .number = GPBMethod_FieldNumber_OptionsArray,
         .hasIndex = GPBNoHasBit,
         .flags = GPBFieldRepeated,
-        .type = GPBTypeMessage,
-        .offset = offsetof(GPBMethod_Storage, optionsArray),
+        .dataType = GPBDataTypeMessage,
+        .offset = offsetof(GPBMethod__storage_, optionsArray),
         .defaultValue.valueMessage = nil,
-        .typeSpecific.className = GPBStringifySymbol(GPBOption),
+        .dataTypeSpecific.className = GPBStringifySymbol(GPBOption),
         .fieldOptions = NULL,
       },
     };
@@ -238,20 +242,23 @@ typedef struct GPBMethod_Storage {
 #else
     static const char *extraTextFormatInfo = "\002\002\007\244\241!!\000\004\010\244\241!!\000";
 #endif  // GPBOBJC_SKIP_MESSAGE_TEXTFORMAT_EXTRAS
-    descriptor = [GPBDescriptor allocDescriptorForClass:[GPBMethod class]
-                                              rootClass:[GPBApiRoot class]
-                                                   file:GPBApiRoot_FileDescriptor()
-                                                 fields:fields
-                                             fieldCount:sizeof(fields) / sizeof(GPBMessageFieldDescription)
-                                                 oneofs:NULL
-                                             oneofCount:0
-                                                  enums:NULL
-                                              enumCount:0
-                                                 ranges:NULL
-                                             rangeCount:0
-                                            storageSize:sizeof(GPBMethod_Storage)
-                                             wireFormat:NO
-                                    extraTextFormatInfo:extraTextFormatInfo];
+    GPBDescriptor *localDescriptor =
+        [GPBDescriptor allocDescriptorForClass:[GPBMethod class]
+                                     rootClass:[GPBApiRoot class]
+                                          file:GPBApiRoot_FileDescriptor()
+                                        fields:fields
+                                    fieldCount:sizeof(fields) / sizeof(GPBMessageFieldDescription)
+                                        oneofs:NULL
+                                    oneofCount:0
+                                         enums:NULL
+                                     enumCount:0
+                                        ranges:NULL
+                                    rangeCount:0
+                                   storageSize:sizeof(GPBMethod__storage_)
+                                    wireFormat:NO
+                           extraTextFormatInfo:extraTextFormatInfo];
+    NSAssert(descriptor == nil, @"Startup recursed!");
+    descriptor = localDescriptor;
   }
   return descriptor;
 }

+ 30 - 0
objectivec/google/protobuf/Descriptor.pbobjc.h

@@ -152,6 +152,7 @@ typedef GPB_ENUM(GPBFileDescriptorSet_FieldNumber) {
 
 // |fileArray| contains |GPBFileDescriptorProto|
 @property(nonatomic, readwrite, strong) NSMutableArray *fileArray;
+@property(nonatomic, readonly) NSUInteger fileArray_Count;
 
 @end
 
@@ -186,26 +187,33 @@ typedef GPB_ENUM(GPBFileDescriptorProto_FieldNumber) {
 // Names of files imported by this file.
 // |dependencyArray| contains |NSString|
 @property(nonatomic, readwrite, strong) NSMutableArray *dependencyArray;
+@property(nonatomic, readonly) NSUInteger dependencyArray_Count;
 
 // Indexes of the public imported files in the dependency list above.
 @property(nonatomic, readwrite, strong) GPBInt32Array *publicDependencyArray;
+@property(nonatomic, readonly) NSUInteger publicDependencyArray_Count;
 
 // Indexes of the weak imported files in the dependency list.
 // For Google-internal migration only. Do not use.
 @property(nonatomic, readwrite, strong) GPBInt32Array *weakDependencyArray;
+@property(nonatomic, readonly) NSUInteger weakDependencyArray_Count;
 
 // All top-level definitions in this file.
 // |messageTypeArray| contains |GPBDescriptorProto|
 @property(nonatomic, readwrite, strong) NSMutableArray *messageTypeArray;
+@property(nonatomic, readonly) NSUInteger messageTypeArray_Count;
 
 // |enumTypeArray| contains |GPBEnumDescriptorProto|
 @property(nonatomic, readwrite, strong) NSMutableArray *enumTypeArray;
+@property(nonatomic, readonly) NSUInteger enumTypeArray_Count;
 
 // |serviceArray| contains |GPBServiceDescriptorProto|
 @property(nonatomic, readwrite, strong) NSMutableArray *serviceArray;
+@property(nonatomic, readonly) NSUInteger serviceArray_Count;
 
 // |extensionArray| contains |GPBFieldDescriptorProto|
 @property(nonatomic, readwrite, strong) NSMutableArray *extensionArray;
+@property(nonatomic, readonly) NSUInteger extensionArray_Count;
 
 @property(nonatomic, readwrite) BOOL hasOptions;
 @property(nonatomic, readwrite, strong) GPBFileOptions *options;
@@ -247,32 +255,40 @@ typedef GPB_ENUM(GPBDescriptorProto_FieldNumber) {
 
 // |fieldArray| contains |GPBFieldDescriptorProto|
 @property(nonatomic, readwrite, strong) NSMutableArray *fieldArray;
+@property(nonatomic, readonly) NSUInteger fieldArray_Count;
 
 // |extensionArray| contains |GPBFieldDescriptorProto|
 @property(nonatomic, readwrite, strong) NSMutableArray *extensionArray;
+@property(nonatomic, readonly) NSUInteger extensionArray_Count;
 
 // |nestedTypeArray| contains |GPBDescriptorProto|
 @property(nonatomic, readwrite, strong) NSMutableArray *nestedTypeArray;
+@property(nonatomic, readonly) NSUInteger nestedTypeArray_Count;
 
 // |enumTypeArray| contains |GPBEnumDescriptorProto|
 @property(nonatomic, readwrite, strong) NSMutableArray *enumTypeArray;
+@property(nonatomic, readonly) NSUInteger enumTypeArray_Count;
 
 // |extensionRangeArray| contains |GPBDescriptorProto_ExtensionRange|
 @property(nonatomic, readwrite, strong) NSMutableArray *extensionRangeArray;
+@property(nonatomic, readonly) NSUInteger extensionRangeArray_Count;
 
 // |oneofDeclArray| contains |GPBOneofDescriptorProto|
 @property(nonatomic, readwrite, strong) NSMutableArray *oneofDeclArray;
+@property(nonatomic, readonly) NSUInteger oneofDeclArray_Count;
 
 @property(nonatomic, readwrite) BOOL hasOptions;
 @property(nonatomic, readwrite, strong) GPBMessageOptions *options;
 
 // |reservedRangeArray| contains |GPBDescriptorProto_ReservedRange|
 @property(nonatomic, readwrite, strong) NSMutableArray *reservedRangeArray;
+@property(nonatomic, readonly) NSUInteger reservedRangeArray_Count;
 
 // Reserved field names, which may not be used by fields in the same message.
 // A given name may only be reserved once.
 // |reservedNameArray| contains |NSString|
 @property(nonatomic, readwrite, strong) NSMutableArray *reservedNameArray;
+@property(nonatomic, readonly) NSUInteger reservedNameArray_Count;
 
 @end
 
@@ -407,6 +423,7 @@ typedef GPB_ENUM(GPBEnumDescriptorProto_FieldNumber) {
 
 // |valueArray| contains |GPBEnumValueDescriptorProto|
 @property(nonatomic, readwrite, strong) NSMutableArray *valueArray;
+@property(nonatomic, readonly) NSUInteger valueArray_Count;
 
 @property(nonatomic, readwrite) BOOL hasOptions;
 @property(nonatomic, readwrite, strong) GPBEnumOptions *options;
@@ -451,6 +468,7 @@ typedef GPB_ENUM(GPBServiceDescriptorProto_FieldNumber) {
 
 // |methodArray| contains |GPBMethodDescriptorProto|
 @property(nonatomic, readwrite, strong) NSMutableArray *methodArray;
+@property(nonatomic, readonly) NSUInteger methodArray_Count;
 
 @property(nonatomic, readwrite) BOOL hasOptions;
 @property(nonatomic, readwrite, strong) GPBServiceOptions *options;
@@ -617,6 +635,7 @@ typedef GPB_ENUM(GPBFileOptions_FieldNumber) {
 // The parser stores options it doesn't recognize here. See above.
 // |uninterpretedOptionArray| contains |GPBUninterpretedOption|
 @property(nonatomic, readwrite, strong) NSMutableArray *uninterpretedOptionArray;
+@property(nonatomic, readonly) NSUInteger uninterpretedOptionArray_Count;
 
 @end
 
@@ -693,6 +712,7 @@ typedef GPB_ENUM(GPBMessageOptions_FieldNumber) {
 // The parser stores options it doesn't recognize here. See above.
 // |uninterpretedOptionArray| contains |GPBUninterpretedOption|
 @property(nonatomic, readwrite, strong) NSMutableArray *uninterpretedOptionArray;
+@property(nonatomic, readonly) NSUInteger uninterpretedOptionArray_Count;
 
 @end
 
@@ -782,6 +802,7 @@ typedef GPB_ENUM(GPBFieldOptions_FieldNumber) {
 // The parser stores options it doesn't recognize here. See above.
 // |uninterpretedOptionArray| contains |GPBUninterpretedOption|
 @property(nonatomic, readwrite, strong) NSMutableArray *uninterpretedOptionArray;
+@property(nonatomic, readonly) NSUInteger uninterpretedOptionArray_Count;
 
 @end
 
@@ -810,6 +831,7 @@ typedef GPB_ENUM(GPBEnumOptions_FieldNumber) {
 // The parser stores options it doesn't recognize here. See above.
 // |uninterpretedOptionArray| contains |GPBUninterpretedOption|
 @property(nonatomic, readwrite, strong) NSMutableArray *uninterpretedOptionArray;
+@property(nonatomic, readonly) NSUInteger uninterpretedOptionArray_Count;
 
 @end
 
@@ -832,6 +854,7 @@ typedef GPB_ENUM(GPBEnumValueOptions_FieldNumber) {
 // The parser stores options it doesn't recognize here. See above.
 // |uninterpretedOptionArray| contains |GPBUninterpretedOption|
 @property(nonatomic, readwrite, strong) NSMutableArray *uninterpretedOptionArray;
+@property(nonatomic, readonly) NSUInteger uninterpretedOptionArray_Count;
 
 @end
 
@@ -854,6 +877,7 @@ typedef GPB_ENUM(GPBServiceOptions_FieldNumber) {
 // The parser stores options it doesn't recognize here. See above.
 // |uninterpretedOptionArray| contains |GPBUninterpretedOption|
 @property(nonatomic, readwrite, strong) NSMutableArray *uninterpretedOptionArray;
+@property(nonatomic, readonly) NSUInteger uninterpretedOptionArray_Count;
 
 @end
 
@@ -876,6 +900,7 @@ typedef GPB_ENUM(GPBMethodOptions_FieldNumber) {
 // The parser stores options it doesn't recognize here. See above.
 // |uninterpretedOptionArray| contains |GPBUninterpretedOption|
 @property(nonatomic, readwrite, strong) NSMutableArray *uninterpretedOptionArray;
+@property(nonatomic, readonly) NSUInteger uninterpretedOptionArray_Count;
 
 @end
 
@@ -901,6 +926,7 @@ typedef GPB_ENUM(GPBUninterpretedOption_FieldNumber) {
 
 // |nameArray| contains |GPBUninterpretedOption_NamePart|
 @property(nonatomic, readwrite, strong) NSMutableArray *nameArray;
+@property(nonatomic, readonly) NSUInteger nameArray_Count;
 
 // The value of the uninterpreted option, in whatever type the tokenizer
 // identified it as during parsing. Exactly one of these should be set.
@@ -1001,6 +1027,7 @@ typedef GPB_ENUM(GPBSourceCodeInfo_FieldNumber) {
 //   be recorded in the future.
 // |locationArray| contains |GPBSourceCodeInfo_Location|
 @property(nonatomic, readwrite, strong) NSMutableArray *locationArray;
+@property(nonatomic, readonly) NSUInteger locationArray_Count;
 
 @end
 
@@ -1040,6 +1067,7 @@ typedef GPB_ENUM(GPBSourceCodeInfo_Location_FieldNumber) {
 // this path refers to the whole field declaration (from the beginning
 // of the label to the terminating semicolon).
 @property(nonatomic, readwrite, strong) GPBInt32Array *pathArray;
+@property(nonatomic, readonly) NSUInteger pathArray_Count;
 
 // Always has exactly three or four elements: start line, start column,
 // end line (optional, otherwise assumed same as start line), end column.
@@ -1047,6 +1075,7 @@ typedef GPB_ENUM(GPBSourceCodeInfo_Location_FieldNumber) {
 // and column numbers are zero-based -- typically you will want to add
 // 1 to each before displaying to a user.
 @property(nonatomic, readwrite, strong) GPBInt32Array *spanArray;
+@property(nonatomic, readonly) NSUInteger spanArray_Count;
 
 // If this SourceCodeInfo represents a complete declaration, these are any
 // comments appearing before and after the declaration which appear to be
@@ -1103,6 +1132,7 @@ typedef GPB_ENUM(GPBSourceCodeInfo_Location_FieldNumber) {
 
 // |leadingDetachedCommentsArray| contains |NSString|
 @property(nonatomic, readwrite, strong) NSMutableArray *leadingDetachedCommentsArray;
+@property(nonatomic, readonly) NSUInteger leadingDetachedCommentsArray_Count;
 
 @end
 

Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 273 - 249
objectivec/google/protobuf/Descriptor.pbobjc.m


+ 28 - 22
objectivec/google/protobuf/Duration.pbobjc.m

@@ -11,11 +11,14 @@
 
 @end
 
+#pragma mark - GPBDurationRoot_FileDescriptor
+
 static GPBFileDescriptor *GPBDurationRoot_FileDescriptor(void) {
   // This is called by +initialize so there is no need to worry
   // about thread safety of the singleton.
   static GPBFileDescriptor *descriptor = NULL;
   if (!descriptor) {
+    GPBDebugCheckRuntimeVersion();
     descriptor = [[GPBFileDescriptor alloc] initWithPackage:@"google.protobuf"
                                                      syntax:GPBFileSyntaxProto3];
   }
@@ -29,16 +32,16 @@ static GPBFileDescriptor *GPBDurationRoot_FileDescriptor(void) {
 @dynamic seconds;
 @dynamic nanos;
 
-typedef struct GPBDuration_Storage {
+typedef struct GPBDuration__storage_ {
   uint32_t _has_storage_[1];
   int32_t nanos;
   int64_t seconds;
-} GPBDuration_Storage;
+} GPBDuration__storage_;
 
 // This method is threadsafe because it is initially called
 // in +initialize for each subclass.
 + (GPBDescriptor *)descriptor {
-  static GPBDescriptor *descriptor = NULL;
+  static GPBDescriptor *descriptor = nil;
   if (!descriptor) {
     static GPBMessageFieldDescription fields[] = {
       {
@@ -46,10 +49,10 @@ typedef struct GPBDuration_Storage {
         .number = GPBDuration_FieldNumber_Seconds,
         .hasIndex = 0,
         .flags = GPBFieldOptional,
-        .type = GPBTypeInt64,
-        .offset = offsetof(GPBDuration_Storage, seconds),
+        .dataType = GPBDataTypeInt64,
+        .offset = offsetof(GPBDuration__storage_, seconds),
         .defaultValue.valueInt64 = 0LL,
-        .typeSpecific.className = NULL,
+        .dataTypeSpecific.className = NULL,
         .fieldOptions = NULL,
       },
       {
@@ -57,26 +60,29 @@ typedef struct GPBDuration_Storage {
         .number = GPBDuration_FieldNumber_Nanos,
         .hasIndex = 1,
         .flags = GPBFieldOptional,
-        .type = GPBTypeInt32,
-        .offset = offsetof(GPBDuration_Storage, nanos),
+        .dataType = GPBDataTypeInt32,
+        .offset = offsetof(GPBDuration__storage_, nanos),
         .defaultValue.valueInt32 = 0,
-        .typeSpecific.className = NULL,
+        .dataTypeSpecific.className = NULL,
         .fieldOptions = NULL,
       },
     };
-    descriptor = [GPBDescriptor allocDescriptorForClass:[GPBDuration class]
-                                              rootClass:[GPBDurationRoot class]
-                                                   file:GPBDurationRoot_FileDescriptor()
-                                                 fields:fields
-                                             fieldCount:sizeof(fields) / sizeof(GPBMessageFieldDescription)
-                                                 oneofs:NULL
-                                             oneofCount:0
-                                                  enums:NULL
-                                              enumCount:0
-                                                 ranges:NULL
-                                             rangeCount:0
-                                            storageSize:sizeof(GPBDuration_Storage)
-                                             wireFormat:NO];
+    GPBDescriptor *localDescriptor =
+        [GPBDescriptor allocDescriptorForClass:[GPBDuration class]
+                                     rootClass:[GPBDurationRoot class]
+                                          file:GPBDurationRoot_FileDescriptor()
+                                        fields:fields
+                                    fieldCount:sizeof(fields) / sizeof(GPBMessageFieldDescription)
+                                        oneofs:NULL
+                                    oneofCount:0
+                                         enums:NULL
+                                     enumCount:0
+                                        ranges:NULL
+                                    rangeCount:0
+                                   storageSize:sizeof(GPBDuration__storage_)
+                                    wireFormat:NO];
+    NSAssert(descriptor == nil, @"Startup recursed!");
+    descriptor = localDescriptor;
   }
   return descriptor;
 }

+ 22 - 18
objectivec/google/protobuf/Empty.pbobjc.m

@@ -11,11 +11,14 @@
 
 @end
 
+#pragma mark - GPBEmptyRoot_FileDescriptor
+
 static GPBFileDescriptor *GPBEmptyRoot_FileDescriptor(void) {
   // This is called by +initialize so there is no need to worry
   // about thread safety of the singleton.
   static GPBFileDescriptor *descriptor = NULL;
   if (!descriptor) {
+    GPBDebugCheckRuntimeVersion();
     descriptor = [[GPBFileDescriptor alloc] initWithPackage:@"google.protobuf"
                                                      syntax:GPBFileSyntaxProto3];
   }
@@ -27,30 +30,31 @@ static GPBFileDescriptor *GPBEmptyRoot_FileDescriptor(void) {
 @implementation GPBEmpty
 
 
-typedef struct GPBEmpty_Storage {
+typedef struct GPBEmpty__storage_ {
   uint32_t _has_storage_[0];
-} GPBEmpty_Storage;
+} GPBEmpty__storage_;
 
 // This method is threadsafe because it is initially called
 // in +initialize for each subclass.
 + (GPBDescriptor *)descriptor {
-  static GPBDescriptor *descriptor = NULL;
+  static GPBDescriptor *descriptor = nil;
   if (!descriptor) {
-    static GPBMessageFieldDescription fields[] = {
-    };
-    descriptor = [GPBDescriptor allocDescriptorForClass:[GPBEmpty class]
-                                              rootClass:[GPBEmptyRoot class]
-                                                   file:GPBEmptyRoot_FileDescriptor()
-                                                 fields:fields
-                                             fieldCount:sizeof(fields) / sizeof(GPBMessageFieldDescription)
-                                                 oneofs:NULL
-                                             oneofCount:0
-                                                  enums:NULL
-                                              enumCount:0
-                                                 ranges:NULL
-                                             rangeCount:0
-                                            storageSize:sizeof(GPBEmpty_Storage)
-                                             wireFormat:NO];
+    GPBDescriptor *localDescriptor =
+        [GPBDescriptor allocDescriptorForClass:[GPBEmpty class]
+                                     rootClass:[GPBEmptyRoot class]
+                                          file:GPBEmptyRoot_FileDescriptor()
+                                        fields:NULL
+                                    fieldCount:0
+                                        oneofs:NULL
+                                    oneofCount:0
+                                         enums:NULL
+                                     enumCount:0
+                                        ranges:NULL
+                                    rangeCount:0
+                                   storageSize:sizeof(GPBEmpty__storage_)
+                                    wireFormat:NO];
+    NSAssert(descriptor == nil, @"Startup recursed!");
+    descriptor = localDescriptor;
   }
   return descriptor;
 }

+ 1 - 0
objectivec/google/protobuf/FieldMask.pbobjc.h

@@ -152,6 +152,7 @@ typedef GPB_ENUM(GPBFieldMask_FieldNumber) {
 // The set of field mask paths.
 // |pathsArray| contains |NSString|
 @property(nonatomic, readwrite, strong) NSMutableArray *pathsArray;
+@property(nonatomic, readonly) NSUInteger pathsArray_Count;
 
 @end
 

+ 26 - 20
objectivec/google/protobuf/FieldMask.pbobjc.m

@@ -11,11 +11,14 @@
 
 @end
 
+#pragma mark - GPBFieldMaskRoot_FileDescriptor
+
 static GPBFileDescriptor *GPBFieldMaskRoot_FileDescriptor(void) {
   // This is called by +initialize so there is no need to worry
   // about thread safety of the singleton.
   static GPBFileDescriptor *descriptor = NULL;
   if (!descriptor) {
+    GPBDebugCheckRuntimeVersion();
     descriptor = [[GPBFileDescriptor alloc] initWithPackage:@"google.protobuf"
                                                      syntax:GPBFileSyntaxProto3];
   }
@@ -26,17 +29,17 @@ static GPBFileDescriptor *GPBFieldMaskRoot_FileDescriptor(void) {
 
 @implementation GPBFieldMask
 
-@dynamic pathsArray;
+@dynamic pathsArray, pathsArray_Count;
 
-typedef struct GPBFieldMask_Storage {
+typedef struct GPBFieldMask__storage_ {
   uint32_t _has_storage_[1];
   NSMutableArray *pathsArray;
-} GPBFieldMask_Storage;
+} GPBFieldMask__storage_;
 
 // This method is threadsafe because it is initially called
 // in +initialize for each subclass.
 + (GPBDescriptor *)descriptor {
-  static GPBDescriptor *descriptor = NULL;
+  static GPBDescriptor *descriptor = nil;
   if (!descriptor) {
     static GPBMessageFieldDescription fields[] = {
       {
@@ -44,26 +47,29 @@ typedef struct GPBFieldMask_Storage {
         .number = GPBFieldMask_FieldNumber_PathsArray,
         .hasIndex = GPBNoHasBit,
         .flags = GPBFieldRepeated,
-        .type = GPBTypeString,
-        .offset = offsetof(GPBFieldMask_Storage, pathsArray),
+        .dataType = GPBDataTypeString,
+        .offset = offsetof(GPBFieldMask__storage_, pathsArray),
         .defaultValue.valueMessage = nil,
-        .typeSpecific.className = NULL,
+        .dataTypeSpecific.className = NULL,
         .fieldOptions = NULL,
       },
     };
-    descriptor = [GPBDescriptor allocDescriptorForClass:[GPBFieldMask class]
-                                              rootClass:[GPBFieldMaskRoot class]
-                                                   file:GPBFieldMaskRoot_FileDescriptor()
-                                                 fields:fields
-                                             fieldCount:sizeof(fields) / sizeof(GPBMessageFieldDescription)
-                                                 oneofs:NULL
-                                             oneofCount:0
-                                                  enums:NULL
-                                              enumCount:0
-                                                 ranges:NULL
-                                             rangeCount:0
-                                            storageSize:sizeof(GPBFieldMask_Storage)
-                                             wireFormat:NO];
+    GPBDescriptor *localDescriptor =
+        [GPBDescriptor allocDescriptorForClass:[GPBFieldMask class]
+                                     rootClass:[GPBFieldMaskRoot class]
+                                          file:GPBFieldMaskRoot_FileDescriptor()
+                                        fields:fields
+                                    fieldCount:sizeof(fields) / sizeof(GPBMessageFieldDescription)
+                                        oneofs:NULL
+                                    oneofCount:0
+                                         enums:NULL
+                                     enumCount:0
+                                        ranges:NULL
+                                    rangeCount:0
+                                   storageSize:sizeof(GPBFieldMask__storage_)
+                                    wireFormat:NO];
+    NSAssert(descriptor == nil, @"Startup recursed!");
+    descriptor = localDescriptor;
   }
   return descriptor;
 }

+ 25 - 19
objectivec/google/protobuf/SourceContext.pbobjc.m

@@ -11,11 +11,14 @@
 
 @end
 
+#pragma mark - GPBSourceContextRoot_FileDescriptor
+
 static GPBFileDescriptor *GPBSourceContextRoot_FileDescriptor(void) {
   // This is called by +initialize so there is no need to worry
   // about thread safety of the singleton.
   static GPBFileDescriptor *descriptor = NULL;
   if (!descriptor) {
+    GPBDebugCheckRuntimeVersion();
     descriptor = [[GPBFileDescriptor alloc] initWithPackage:@"google.protobuf"
                                                      syntax:GPBFileSyntaxProto3];
   }
@@ -28,15 +31,15 @@ static GPBFileDescriptor *GPBSourceContextRoot_FileDescriptor(void) {
 
 @dynamic fileName;
 
-typedef struct GPBSourceContext_Storage {
+typedef struct GPBSourceContext__storage_ {
   uint32_t _has_storage_[1];
   NSString *fileName;
-} GPBSourceContext_Storage;
+} GPBSourceContext__storage_;
 
 // This method is threadsafe because it is initially called
 // in +initialize for each subclass.
 + (GPBDescriptor *)descriptor {
-  static GPBDescriptor *descriptor = NULL;
+  static GPBDescriptor *descriptor = nil;
   if (!descriptor) {
     static GPBMessageFieldDescription fields[] = {
       {
@@ -44,26 +47,29 @@ typedef struct GPBSourceContext_Storage {
         .number = GPBSourceContext_FieldNumber_FileName,
         .hasIndex = 0,
         .flags = GPBFieldOptional,
-        .type = GPBTypeString,
-        .offset = offsetof(GPBSourceContext_Storage, fileName),
+        .dataType = GPBDataTypeString,
+        .offset = offsetof(GPBSourceContext__storage_, fileName),
         .defaultValue.valueString = nil,
-        .typeSpecific.className = NULL,
+        .dataTypeSpecific.className = NULL,
         .fieldOptions = NULL,
       },
     };
-    descriptor = [GPBDescriptor allocDescriptorForClass:[GPBSourceContext class]
-                                              rootClass:[GPBSourceContextRoot class]
-                                                   file:GPBSourceContextRoot_FileDescriptor()
-                                                 fields:fields
-                                             fieldCount:sizeof(fields) / sizeof(GPBMessageFieldDescription)
-                                                 oneofs:NULL
-                                             oneofCount:0
-                                                  enums:NULL
-                                              enumCount:0
-                                                 ranges:NULL
-                                             rangeCount:0
-                                            storageSize:sizeof(GPBSourceContext_Storage)
-                                             wireFormat:NO];
+    GPBDescriptor *localDescriptor =
+        [GPBDescriptor allocDescriptorForClass:[GPBSourceContext class]
+                                     rootClass:[GPBSourceContextRoot class]
+                                          file:GPBSourceContextRoot_FileDescriptor()
+                                        fields:fields
+                                    fieldCount:sizeof(fields) / sizeof(GPBMessageFieldDescription)
+                                        oneofs:NULL
+                                    oneofCount:0
+                                         enums:NULL
+                                     enumCount:0
+                                        ranges:NULL
+                                    rangeCount:0
+                                   storageSize:sizeof(GPBSourceContext__storage_)
+                                    wireFormat:NO];
+    NSAssert(descriptor == nil, @"Startup recursed!");
+    descriptor = localDescriptor;
   }
   return descriptor;
 }

+ 2 - 0
objectivec/google/protobuf/Struct.pbobjc.h

@@ -57,6 +57,7 @@ typedef GPB_ENUM(GPBStruct_FieldNumber) {
 // Map of dynamically typed values.
 // |fields| values are |GPBValue|
 @property(nonatomic, readwrite, strong) NSMutableDictionary *fields;
+@property(nonatomic, readonly) NSUInteger fields_Count;
 
 @end
 
@@ -126,6 +127,7 @@ typedef GPB_ENUM(GPBListValue_FieldNumber) {
 // Repeated field of dynamically typed values.
 // |valuesArray| contains |GPBValue|
 @property(nonatomic, readwrite, strong) NSMutableArray *valuesArray;
+@property(nonatomic, readonly) NSUInteger valuesArray_Count;
 
 @end
 

+ 87 - 75
objectivec/google/protobuf/Struct.pbobjc.m

@@ -11,11 +11,14 @@
 
 @end
 
+#pragma mark - GPBStructRoot_FileDescriptor
+
 static GPBFileDescriptor *GPBStructRoot_FileDescriptor(void) {
   // This is called by +initialize so there is no need to worry
   // about thread safety of the singleton.
   static GPBFileDescriptor *descriptor = NULL;
   if (!descriptor) {
+    GPBDebugCheckRuntimeVersion();
     descriptor = [[GPBFileDescriptor alloc] initWithPackage:@"google.protobuf"
                                                      syntax:GPBFileSyntaxProto3];
   }
@@ -51,17 +54,17 @@ BOOL GPBNullValue_IsValidValue(int32_t value__) {
 
 @implementation GPBStruct
 
-@dynamic fields;
+@dynamic fields, fields_Count;
 
-typedef struct GPBStruct_Storage {
+typedef struct GPBStruct__storage_ {
   uint32_t _has_storage_[1];
   NSMutableDictionary *fields;
-} GPBStruct_Storage;
+} GPBStruct__storage_;
 
 // This method is threadsafe because it is initially called
 // in +initialize for each subclass.
 + (GPBDescriptor *)descriptor {
-  static GPBDescriptor *descriptor = NULL;
+  static GPBDescriptor *descriptor = nil;
   if (!descriptor) {
     static GPBMessageFieldDescription fields[] = {
       {
@@ -69,26 +72,29 @@ typedef struct GPBStruct_Storage {
         .number = GPBStruct_FieldNumber_Fields,
         .hasIndex = GPBNoHasBit,
         .flags = GPBFieldMapKeyString,
-        .type = GPBTypeMessage,
-        .offset = offsetof(GPBStruct_Storage, fields),
+        .dataType = GPBDataTypeMessage,
+        .offset = offsetof(GPBStruct__storage_, fields),
         .defaultValue.valueMessage = nil,
-        .typeSpecific.className = GPBStringifySymbol(GPBValue),
+        .dataTypeSpecific.className = GPBStringifySymbol(GPBValue),
         .fieldOptions = NULL,
       },
     };
-    descriptor = [GPBDescriptor allocDescriptorForClass:[GPBStruct class]
-                                              rootClass:[GPBStructRoot class]
-                                                   file:GPBStructRoot_FileDescriptor()
-                                                 fields:fields
-                                             fieldCount:sizeof(fields) / sizeof(GPBMessageFieldDescription)
-                                                 oneofs:NULL
-                                             oneofCount:0
-                                                  enums:NULL
-                                              enumCount:0
-                                                 ranges:NULL
-                                             rangeCount:0
-                                            storageSize:sizeof(GPBStruct_Storage)
-                                             wireFormat:NO];
+    GPBDescriptor *localDescriptor =
+        [GPBDescriptor allocDescriptorForClass:[GPBStruct class]
+                                     rootClass:[GPBStructRoot class]
+                                          file:GPBStructRoot_FileDescriptor()
+                                        fields:fields
+                                    fieldCount:sizeof(fields) / sizeof(GPBMessageFieldDescription)
+                                        oneofs:NULL
+                                    oneofCount:0
+                                         enums:NULL
+                                     enumCount:0
+                                        ranges:NULL
+                                    rangeCount:0
+                                   storageSize:sizeof(GPBStruct__storage_)
+                                    wireFormat:NO];
+    NSAssert(descriptor == nil, @"Startup recursed!");
+    descriptor = localDescriptor;
   }
   return descriptor;
 }
@@ -107,7 +113,7 @@ typedef struct GPBStruct_Storage {
 @dynamic structValue;
 @dynamic listValue;
 
-typedef struct GPBValue_Storage {
+typedef struct GPBValue__storage_ {
   uint32_t _has_storage_[2];
   BOOL boolValue;
   GPBNullValue nullValue;
@@ -115,12 +121,12 @@ typedef struct GPBValue_Storage {
   GPBStruct *structValue;
   GPBListValue *listValue;
   double numberValue;
-} GPBValue_Storage;
+} GPBValue__storage_;
 
 // This method is threadsafe because it is initially called
 // in +initialize for each subclass.
 + (GPBDescriptor *)descriptor {
-  static GPBDescriptor *descriptor = NULL;
+  static GPBDescriptor *descriptor = nil;
   if (!descriptor) {
     static GPBMessageOneofDescription oneofs[] = {
       {
@@ -134,10 +140,10 @@ typedef struct GPBValue_Storage {
         .number = GPBValue_FieldNumber_NullValue,
         .hasIndex = -1,
         .flags = GPBFieldOptional | GPBFieldHasEnumDescriptor,
-        .type = GPBTypeEnum,
-        .offset = offsetof(GPBValue_Storage, nullValue),
+        .dataType = GPBDataTypeEnum,
+        .offset = offsetof(GPBValue__storage_, nullValue),
         .defaultValue.valueEnum = GPBNullValue_NullValue,
-        .typeSpecific.enumDescFunc = GPBNullValue_EnumDescriptor,
+        .dataTypeSpecific.enumDescFunc = GPBNullValue_EnumDescriptor,
         .fieldOptions = NULL,
       },
       {
@@ -145,10 +151,10 @@ typedef struct GPBValue_Storage {
         .number = GPBValue_FieldNumber_NumberValue,
         .hasIndex = -1,
         .flags = GPBFieldOptional,
-        .type = GPBTypeDouble,
-        .offset = offsetof(GPBValue_Storage, numberValue),
+        .dataType = GPBDataTypeDouble,
+        .offset = offsetof(GPBValue__storage_, numberValue),
         .defaultValue.valueDouble = 0,
-        .typeSpecific.className = NULL,
+        .dataTypeSpecific.className = NULL,
         .fieldOptions = NULL,
       },
       {
@@ -156,10 +162,10 @@ typedef struct GPBValue_Storage {
         .number = GPBValue_FieldNumber_StringValue,
         .hasIndex = -1,
         .flags = GPBFieldOptional,
-        .type = GPBTypeString,
-        .offset = offsetof(GPBValue_Storage, stringValue),
+        .dataType = GPBDataTypeString,
+        .offset = offsetof(GPBValue__storage_, stringValue),
         .defaultValue.valueString = nil,
-        .typeSpecific.className = NULL,
+        .dataTypeSpecific.className = NULL,
         .fieldOptions = NULL,
       },
       {
@@ -167,10 +173,10 @@ typedef struct GPBValue_Storage {
         .number = GPBValue_FieldNumber_BoolValue,
         .hasIndex = -1,
         .flags = GPBFieldOptional,
-        .type = GPBTypeBool,
-        .offset = offsetof(GPBValue_Storage, boolValue),
+        .dataType = GPBDataTypeBool,
+        .offset = offsetof(GPBValue__storage_, boolValue),
         .defaultValue.valueBool = NO,
-        .typeSpecific.className = NULL,
+        .dataTypeSpecific.className = NULL,
         .fieldOptions = NULL,
       },
       {
@@ -178,10 +184,10 @@ typedef struct GPBValue_Storage {
         .number = GPBValue_FieldNumber_StructValue,
         .hasIndex = -1,
         .flags = GPBFieldOptional,
-        .type = GPBTypeMessage,
-        .offset = offsetof(GPBValue_Storage, structValue),
+        .dataType = GPBDataTypeMessage,
+        .offset = offsetof(GPBValue__storage_, structValue),
         .defaultValue.valueMessage = nil,
-        .typeSpecific.className = GPBStringifySymbol(GPBStruct),
+        .dataTypeSpecific.className = GPBStringifySymbol(GPBStruct),
         .fieldOptions = NULL,
       },
       {
@@ -189,26 +195,29 @@ typedef struct GPBValue_Storage {
         .number = GPBValue_FieldNumber_ListValue,
         .hasIndex = -1,
         .flags = GPBFieldOptional,
-        .type = GPBTypeMessage,
-        .offset = offsetof(GPBValue_Storage, listValue),
+        .dataType = GPBDataTypeMessage,
+        .offset = offsetof(GPBValue__storage_, listValue),
         .defaultValue.valueMessage = nil,
-        .typeSpecific.className = GPBStringifySymbol(GPBListValue),
+        .dataTypeSpecific.className = GPBStringifySymbol(GPBListValue),
         .fieldOptions = NULL,
       },
     };
-    descriptor = [GPBDescriptor allocDescriptorForClass:[GPBValue class]
-                                              rootClass:[GPBStructRoot class]
-                                                   file:GPBStructRoot_FileDescriptor()
-                                                 fields:fields
-                                             fieldCount:sizeof(fields) / sizeof(GPBMessageFieldDescription)
-                                                 oneofs:oneofs
-                                             oneofCount:sizeof(oneofs) / sizeof(GPBMessageOneofDescription)
-                                                  enums:NULL
-                                              enumCount:0
-                                                 ranges:NULL
-                                             rangeCount:0
-                                            storageSize:sizeof(GPBValue_Storage)
-                                             wireFormat:NO];
+    GPBDescriptor *localDescriptor =
+        [GPBDescriptor allocDescriptorForClass:[GPBValue class]
+                                     rootClass:[GPBStructRoot class]
+                                          file:GPBStructRoot_FileDescriptor()
+                                        fields:fields
+                                    fieldCount:sizeof(fields) / sizeof(GPBMessageFieldDescription)
+                                        oneofs:oneofs
+                                    oneofCount:sizeof(oneofs) / sizeof(GPBMessageOneofDescription)
+                                         enums:NULL
+                                     enumCount:0
+                                        ranges:NULL
+                                    rangeCount:0
+                                   storageSize:sizeof(GPBValue__storage_)
+                                    wireFormat:NO];
+    NSAssert(descriptor == nil, @"Startup recursed!");
+    descriptor = localDescriptor;
   }
   return descriptor;
 }
@@ -218,7 +227,7 @@ typedef struct GPBValue_Storage {
 int32_t GPBValue_NullValue_RawValue(GPBValue *message) {
   GPBDescriptor *descriptor = [GPBValue descriptor];
   GPBFieldDescriptor *field = [descriptor fieldWithNumber:GPBValue_FieldNumber_NullValue];
-  return GPBGetInt32IvarWithField(message, field);
+  return GPBGetMessageInt32Field(message, field);
 }
 
 void SetGPBValue_NullValue_RawValue(GPBValue *message, int32_t value) {
@@ -236,17 +245,17 @@ void GPBValue_ClearKindOneOfCase(GPBValue *message) {
 
 @implementation GPBListValue
 
-@dynamic valuesArray;
+@dynamic valuesArray, valuesArray_Count;
 
-typedef struct GPBListValue_Storage {
+typedef struct GPBListValue__storage_ {
   uint32_t _has_storage_[1];
   NSMutableArray *valuesArray;
-} GPBListValue_Storage;
+} GPBListValue__storage_;
 
 // This method is threadsafe because it is initially called
 // in +initialize for each subclass.
 + (GPBDescriptor *)descriptor {
-  static GPBDescriptor *descriptor = NULL;
+  static GPBDescriptor *descriptor = nil;
   if (!descriptor) {
     static GPBMessageFieldDescription fields[] = {
       {
@@ -254,26 +263,29 @@ typedef struct GPBListValue_Storage {
         .number = GPBListValue_FieldNumber_ValuesArray,
         .hasIndex = GPBNoHasBit,
         .flags = GPBFieldRepeated,
-        .type = GPBTypeMessage,
-        .offset = offsetof(GPBListValue_Storage, valuesArray),
+        .dataType = GPBDataTypeMessage,
+        .offset = offsetof(GPBListValue__storage_, valuesArray),
         .defaultValue.valueMessage = nil,
-        .typeSpecific.className = GPBStringifySymbol(GPBValue),
+        .dataTypeSpecific.className = GPBStringifySymbol(GPBValue),
         .fieldOptions = NULL,
       },
     };
-    descriptor = [GPBDescriptor allocDescriptorForClass:[GPBListValue class]
-                                              rootClass:[GPBStructRoot class]
-                                                   file:GPBStructRoot_FileDescriptor()
-                                                 fields:fields
-                                             fieldCount:sizeof(fields) / sizeof(GPBMessageFieldDescription)
-                                                 oneofs:NULL
-                                             oneofCount:0
-                                                  enums:NULL
-                                              enumCount:0
-                                                 ranges:NULL
-                                             rangeCount:0
-                                            storageSize:sizeof(GPBListValue_Storage)
-                                             wireFormat:NO];
+    GPBDescriptor *localDescriptor =
+        [GPBDescriptor allocDescriptorForClass:[GPBListValue class]
+                                     rootClass:[GPBStructRoot class]
+                                          file:GPBStructRoot_FileDescriptor()
+                                        fields:fields
+                                    fieldCount:sizeof(fields) / sizeof(GPBMessageFieldDescription)
+                                        oneofs:NULL
+                                    oneofCount:0
+                                         enums:NULL
+                                     enumCount:0
+                                        ranges:NULL
+                                    rangeCount:0
+                                   storageSize:sizeof(GPBListValue__storage_)
+                                    wireFormat:NO];
+    NSAssert(descriptor == nil, @"Startup recursed!");
+    descriptor = localDescriptor;
   }
   return descriptor;
 }

+ 28 - 22
objectivec/google/protobuf/Timestamp.pbobjc.m

@@ -11,11 +11,14 @@
 
 @end
 
+#pragma mark - GPBTimestampRoot_FileDescriptor
+
 static GPBFileDescriptor *GPBTimestampRoot_FileDescriptor(void) {
   // This is called by +initialize so there is no need to worry
   // about thread safety of the singleton.
   static GPBFileDescriptor *descriptor = NULL;
   if (!descriptor) {
+    GPBDebugCheckRuntimeVersion();
     descriptor = [[GPBFileDescriptor alloc] initWithPackage:@"google.protobuf"
                                                      syntax:GPBFileSyntaxProto3];
   }
@@ -29,16 +32,16 @@ static GPBFileDescriptor *GPBTimestampRoot_FileDescriptor(void) {
 @dynamic seconds;
 @dynamic nanos;
 
-typedef struct GPBTimestamp_Storage {
+typedef struct GPBTimestamp__storage_ {
   uint32_t _has_storage_[1];
   int32_t nanos;
   int64_t seconds;
-} GPBTimestamp_Storage;
+} GPBTimestamp__storage_;
 
 // This method is threadsafe because it is initially called
 // in +initialize for each subclass.
 + (GPBDescriptor *)descriptor {
-  static GPBDescriptor *descriptor = NULL;
+  static GPBDescriptor *descriptor = nil;
   if (!descriptor) {
     static GPBMessageFieldDescription fields[] = {
       {
@@ -46,10 +49,10 @@ typedef struct GPBTimestamp_Storage {
         .number = GPBTimestamp_FieldNumber_Seconds,
         .hasIndex = 0,
         .flags = GPBFieldOptional,
-        .type = GPBTypeInt64,
-        .offset = offsetof(GPBTimestamp_Storage, seconds),
+        .dataType = GPBDataTypeInt64,
+        .offset = offsetof(GPBTimestamp__storage_, seconds),
         .defaultValue.valueInt64 = 0LL,
-        .typeSpecific.className = NULL,
+        .dataTypeSpecific.className = NULL,
         .fieldOptions = NULL,
       },
       {
@@ -57,26 +60,29 @@ typedef struct GPBTimestamp_Storage {
         .number = GPBTimestamp_FieldNumber_Nanos,
         .hasIndex = 1,
         .flags = GPBFieldOptional,
-        .type = GPBTypeInt32,
-        .offset = offsetof(GPBTimestamp_Storage, nanos),
+        .dataType = GPBDataTypeInt32,
+        .offset = offsetof(GPBTimestamp__storage_, nanos),
         .defaultValue.valueInt32 = 0,
-        .typeSpecific.className = NULL,
+        .dataTypeSpecific.className = NULL,
         .fieldOptions = NULL,
       },
     };
-    descriptor = [GPBDescriptor allocDescriptorForClass:[GPBTimestamp class]
-                                              rootClass:[GPBTimestampRoot class]
-                                                   file:GPBTimestampRoot_FileDescriptor()
-                                                 fields:fields
-                                             fieldCount:sizeof(fields) / sizeof(GPBMessageFieldDescription)
-                                                 oneofs:NULL
-                                             oneofCount:0
-                                                  enums:NULL
-                                              enumCount:0
-                                                 ranges:NULL
-                                             rangeCount:0
-                                            storageSize:sizeof(GPBTimestamp_Storage)
-                                             wireFormat:NO];
+    GPBDescriptor *localDescriptor =
+        [GPBDescriptor allocDescriptorForClass:[GPBTimestamp class]
+                                     rootClass:[GPBTimestampRoot class]
+                                          file:GPBTimestampRoot_FileDescriptor()
+                                        fields:fields
+                                    fieldCount:sizeof(fields) / sizeof(GPBMessageFieldDescription)
+                                        oneofs:NULL
+                                    oneofCount:0
+                                         enums:NULL
+                                     enumCount:0
+                                        ranges:NULL
+                                    rangeCount:0
+                                   storageSize:sizeof(GPBTimestamp__storage_)
+                                    wireFormat:NO];
+    NSAssert(descriptor == nil, @"Startup recursed!");
+    descriptor = localDescriptor;
   }
   return descriptor;
 }

+ 7 - 0
objectivec/google/protobuf/Type.pbobjc.h

@@ -132,15 +132,18 @@ typedef GPB_ENUM(GPBType_FieldNumber) {
 // The list of fields.
 // |fieldsArray| contains |GPBField|
 @property(nonatomic, readwrite, strong) NSMutableArray *fieldsArray;
+@property(nonatomic, readonly) NSUInteger fieldsArray_Count;
 
 // The list of oneof definitions.
 // The list of oneofs declared in this Type
 // |oneofsArray| contains |NSString|
 @property(nonatomic, readwrite, strong) NSMutableArray *oneofsArray;
+@property(nonatomic, readonly) NSUInteger oneofsArray_Count;
 
 // The proto options.
 // |optionsArray| contains |GPBOption|
 @property(nonatomic, readwrite, strong) NSMutableArray *optionsArray;
+@property(nonatomic, readonly) NSUInteger optionsArray_Count;
 
 // The source context.
 @property(nonatomic, readwrite) BOOL hasSourceContext;
@@ -189,6 +192,7 @@ typedef GPB_ENUM(GPBField_FieldNumber) {
 // The proto options.
 // |optionsArray| contains |GPBOption|
 @property(nonatomic, readwrite, strong) NSMutableArray *optionsArray;
+@property(nonatomic, readonly) NSUInteger optionsArray_Count;
 
 @end
 
@@ -216,10 +220,12 @@ typedef GPB_ENUM(GPBEnum_FieldNumber) {
 // Enum value definitions.
 // |enumvalueArray| contains |GPBEnumValue|
 @property(nonatomic, readwrite, strong) NSMutableArray *enumvalueArray;
+@property(nonatomic, readonly) NSUInteger enumvalueArray_Count;
 
 // Proto options for the enum type.
 // |optionsArray| contains |GPBOption|
 @property(nonatomic, readwrite, strong) NSMutableArray *optionsArray;
+@property(nonatomic, readonly) NSUInteger optionsArray_Count;
 
 // The source context.
 @property(nonatomic, readwrite) BOOL hasSourceContext;
@@ -247,6 +253,7 @@ typedef GPB_ENUM(GPBEnumValue_FieldNumber) {
 // Proto options for the enum value.
 // |optionsArray| contains |GPBOption|
 @property(nonatomic, readwrite, strong) NSMutableArray *optionsArray;
+@property(nonatomic, readonly) NSUInteger optionsArray_Count;
 
 @end
 

+ 175 - 159
objectivec/google/protobuf/Type.pbobjc.m

@@ -16,10 +16,8 @@
   // about thread safety and initialization of registry.
   static GPBExtensionRegistry* registry = nil;
   if (!registry) {
+    GPBDebugCheckRuntimeVersion();
     registry = [[GPBExtensionRegistry alloc] init];
-    static GPBExtensionDescription descriptions[] = {
-    };
-    #pragma unused (descriptions)
     [registry addExtensions:[GPBAnyRoot extensionRegistry]];
     [registry addExtensions:[GPBSourceContextRoot extensionRegistry]];
   }
@@ -28,11 +26,14 @@
 
 @end
 
+#pragma mark - GPBTypeRoot_FileDescriptor
+
 static GPBFileDescriptor *GPBTypeRoot_FileDescriptor(void) {
   // This is called by +initialize so there is no need to worry
   // about thread safety of the singleton.
   static GPBFileDescriptor *descriptor = NULL;
   if (!descriptor) {
+    GPBDebugCheckRuntimeVersion();
     descriptor = [[GPBFileDescriptor alloc] initWithPackage:@"google.protobuf"
                                                      syntax:GPBFileSyntaxProto3];
   }
@@ -44,24 +45,24 @@ static GPBFileDescriptor *GPBTypeRoot_FileDescriptor(void) {
 @implementation GPBType
 
 @dynamic name;
-@dynamic fieldsArray;
-@dynamic oneofsArray;
-@dynamic optionsArray;
+@dynamic fieldsArray, fieldsArray_Count;
+@dynamic oneofsArray, oneofsArray_Count;
+@dynamic optionsArray, optionsArray_Count;
 @dynamic hasSourceContext, sourceContext;
 
-typedef struct GPBType_Storage {
+typedef struct GPBType__storage_ {
   uint32_t _has_storage_[1];
   NSString *name;
   NSMutableArray *fieldsArray;
   NSMutableArray *oneofsArray;
   NSMutableArray *optionsArray;
   GPBSourceContext *sourceContext;
-} GPBType_Storage;
+} GPBType__storage_;
 
 // This method is threadsafe because it is initially called
 // in +initialize for each subclass.
 + (GPBDescriptor *)descriptor {
-  static GPBDescriptor *descriptor = NULL;
+  static GPBDescriptor *descriptor = nil;
   if (!descriptor) {
     static GPBMessageFieldDescription fields[] = {
       {
@@ -69,10 +70,10 @@ typedef struct GPBType_Storage {
         .number = GPBType_FieldNumber_Name,
         .hasIndex = 0,
         .flags = GPBFieldOptional,
-        .type = GPBTypeString,
-        .offset = offsetof(GPBType_Storage, name),
+        .dataType = GPBDataTypeString,
+        .offset = offsetof(GPBType__storage_, name),
         .defaultValue.valueString = nil,
-        .typeSpecific.className = NULL,
+        .dataTypeSpecific.className = NULL,
         .fieldOptions = NULL,
       },
       {
@@ -80,10 +81,10 @@ typedef struct GPBType_Storage {
         .number = GPBType_FieldNumber_FieldsArray,
         .hasIndex = GPBNoHasBit,
         .flags = GPBFieldRepeated,
-        .type = GPBTypeMessage,
-        .offset = offsetof(GPBType_Storage, fieldsArray),
+        .dataType = GPBDataTypeMessage,
+        .offset = offsetof(GPBType__storage_, fieldsArray),
         .defaultValue.valueMessage = nil,
-        .typeSpecific.className = GPBStringifySymbol(GPBField),
+        .dataTypeSpecific.className = GPBStringifySymbol(GPBField),
         .fieldOptions = NULL,
       },
       {
@@ -91,10 +92,10 @@ typedef struct GPBType_Storage {
         .number = GPBType_FieldNumber_OneofsArray,
         .hasIndex = GPBNoHasBit,
         .flags = GPBFieldRepeated,
-        .type = GPBTypeString,
-        .offset = offsetof(GPBType_Storage, oneofsArray),
+        .dataType = GPBDataTypeString,
+        .offset = offsetof(GPBType__storage_, oneofsArray),
         .defaultValue.valueMessage = nil,
-        .typeSpecific.className = NULL,
+        .dataTypeSpecific.className = NULL,
         .fieldOptions = NULL,
       },
       {
@@ -102,10 +103,10 @@ typedef struct GPBType_Storage {
         .number = GPBType_FieldNumber_OptionsArray,
         .hasIndex = GPBNoHasBit,
         .flags = GPBFieldRepeated,
-        .type = GPBTypeMessage,
-        .offset = offsetof(GPBType_Storage, optionsArray),
+        .dataType = GPBDataTypeMessage,
+        .offset = offsetof(GPBType__storage_, optionsArray),
         .defaultValue.valueMessage = nil,
-        .typeSpecific.className = GPBStringifySymbol(GPBOption),
+        .dataTypeSpecific.className = GPBStringifySymbol(GPBOption),
         .fieldOptions = NULL,
       },
       {
@@ -113,26 +114,29 @@ typedef struct GPBType_Storage {
         .number = GPBType_FieldNumber_SourceContext,
         .hasIndex = 4,
         .flags = GPBFieldOptional,
-        .type = GPBTypeMessage,
-        .offset = offsetof(GPBType_Storage, sourceContext),
+        .dataType = GPBDataTypeMessage,
+        .offset = offsetof(GPBType__storage_, sourceContext),
         .defaultValue.valueMessage = nil,
-        .typeSpecific.className = GPBStringifySymbol(GPBSourceContext),
+        .dataTypeSpecific.className = GPBStringifySymbol(GPBSourceContext),
         .fieldOptions = NULL,
       },
     };
-    descriptor = [GPBDescriptor allocDescriptorForClass:[GPBType class]
-                                              rootClass:[GPBTypeRoot class]
-                                                   file:GPBTypeRoot_FileDescriptor()
-                                                 fields:fields
-                                             fieldCount:sizeof(fields) / sizeof(GPBMessageFieldDescription)
-                                                 oneofs:NULL
-                                             oneofCount:0
-                                                  enums:NULL
-                                              enumCount:0
-                                                 ranges:NULL
-                                             rangeCount:0
-                                            storageSize:sizeof(GPBType_Storage)
-                                             wireFormat:NO];
+    GPBDescriptor *localDescriptor =
+        [GPBDescriptor allocDescriptorForClass:[GPBType class]
+                                     rootClass:[GPBTypeRoot class]
+                                          file:GPBTypeRoot_FileDescriptor()
+                                        fields:fields
+                                    fieldCount:sizeof(fields) / sizeof(GPBMessageFieldDescription)
+                                        oneofs:NULL
+                                    oneofCount:0
+                                         enums:NULL
+                                     enumCount:0
+                                        ranges:NULL
+                                    rangeCount:0
+                                   storageSize:sizeof(GPBType__storage_)
+                                    wireFormat:NO];
+    NSAssert(descriptor == nil, @"Startup recursed!");
+    descriptor = localDescriptor;
   }
   return descriptor;
 }
@@ -150,9 +154,9 @@ typedef struct GPBType_Storage {
 @dynamic typeURL;
 @dynamic oneofIndex;
 @dynamic packed;
-@dynamic optionsArray;
+@dynamic optionsArray, optionsArray_Count;
 
-typedef struct GPBField_Storage {
+typedef struct GPBField__storage_ {
   uint32_t _has_storage_[1];
   BOOL packed;
   GPBField_Kind kind;
@@ -162,12 +166,12 @@ typedef struct GPBField_Storage {
   NSString *name;
   NSString *typeURL;
   NSMutableArray *optionsArray;
-} GPBField_Storage;
+} GPBField__storage_;
 
 // This method is threadsafe because it is initially called
 // in +initialize for each subclass.
 + (GPBDescriptor *)descriptor {
-  static GPBDescriptor *descriptor = NULL;
+  static GPBDescriptor *descriptor = nil;
   if (!descriptor) {
     static GPBMessageFieldDescription fields[] = {
       {
@@ -175,10 +179,10 @@ typedef struct GPBField_Storage {
         .number = GPBField_FieldNumber_Kind,
         .hasIndex = 0,
         .flags = GPBFieldOptional | GPBFieldHasEnumDescriptor,
-        .type = GPBTypeEnum,
-        .offset = offsetof(GPBField_Storage, kind),
+        .dataType = GPBDataTypeEnum,
+        .offset = offsetof(GPBField__storage_, kind),
         .defaultValue.valueEnum = GPBField_Kind_TypeUnknown,
-        .typeSpecific.enumDescFunc = GPBField_Kind_EnumDescriptor,
+        .dataTypeSpecific.enumDescFunc = GPBField_Kind_EnumDescriptor,
         .fieldOptions = NULL,
       },
       {
@@ -186,10 +190,10 @@ typedef struct GPBField_Storage {
         .number = GPBField_FieldNumber_Cardinality,
         .hasIndex = 1,
         .flags = GPBFieldOptional | GPBFieldHasEnumDescriptor,
-        .type = GPBTypeEnum,
-        .offset = offsetof(GPBField_Storage, cardinality),
+        .dataType = GPBDataTypeEnum,
+        .offset = offsetof(GPBField__storage_, cardinality),
         .defaultValue.valueEnum = GPBField_Cardinality_CardinalityUnknown,
-        .typeSpecific.enumDescFunc = GPBField_Cardinality_EnumDescriptor,
+        .dataTypeSpecific.enumDescFunc = GPBField_Cardinality_EnumDescriptor,
         .fieldOptions = NULL,
       },
       {
@@ -197,10 +201,10 @@ typedef struct GPBField_Storage {
         .number = GPBField_FieldNumber_Number,
         .hasIndex = 2,
         .flags = GPBFieldOptional,
-        .type = GPBTypeInt32,
-        .offset = offsetof(GPBField_Storage, number),
+        .dataType = GPBDataTypeInt32,
+        .offset = offsetof(GPBField__storage_, number),
         .defaultValue.valueInt32 = 0,
-        .typeSpecific.className = NULL,
+        .dataTypeSpecific.className = NULL,
         .fieldOptions = NULL,
       },
       {
@@ -208,10 +212,10 @@ typedef struct GPBField_Storage {
         .number = GPBField_FieldNumber_Name,
         .hasIndex = 3,
         .flags = GPBFieldOptional,
-        .type = GPBTypeString,
-        .offset = offsetof(GPBField_Storage, name),
+        .dataType = GPBDataTypeString,
+        .offset = offsetof(GPBField__storage_, name),
         .defaultValue.valueString = nil,
-        .typeSpecific.className = NULL,
+        .dataTypeSpecific.className = NULL,
         .fieldOptions = NULL,
       },
       {
@@ -219,10 +223,10 @@ typedef struct GPBField_Storage {
         .number = GPBField_FieldNumber_TypeURL,
         .hasIndex = 4,
         .flags = GPBFieldOptional | GPBFieldTextFormatNameCustom,
-        .type = GPBTypeString,
-        .offset = offsetof(GPBField_Storage, typeURL),
+        .dataType = GPBDataTypeString,
+        .offset = offsetof(GPBField__storage_, typeURL),
         .defaultValue.valueString = nil,
-        .typeSpecific.className = NULL,
+        .dataTypeSpecific.className = NULL,
         .fieldOptions = NULL,
       },
       {
@@ -230,10 +234,10 @@ typedef struct GPBField_Storage {
         .number = GPBField_FieldNumber_OneofIndex,
         .hasIndex = 5,
         .flags = GPBFieldOptional,
-        .type = GPBTypeInt32,
-        .offset = offsetof(GPBField_Storage, oneofIndex),
+        .dataType = GPBDataTypeInt32,
+        .offset = offsetof(GPBField__storage_, oneofIndex),
         .defaultValue.valueInt32 = 0,
-        .typeSpecific.className = NULL,
+        .dataTypeSpecific.className = NULL,
         .fieldOptions = NULL,
       },
       {
@@ -241,10 +245,10 @@ typedef struct GPBField_Storage {
         .number = GPBField_FieldNumber_Packed,
         .hasIndex = 6,
         .flags = GPBFieldOptional,
-        .type = GPBTypeBool,
-        .offset = offsetof(GPBField_Storage, packed),
+        .dataType = GPBDataTypeBool,
+        .offset = offsetof(GPBField__storage_, packed),
         .defaultValue.valueBool = NO,
-        .typeSpecific.className = NULL,
+        .dataTypeSpecific.className = NULL,
         .fieldOptions = NULL,
       },
       {
@@ -252,10 +256,10 @@ typedef struct GPBField_Storage {
         .number = GPBField_FieldNumber_OptionsArray,
         .hasIndex = GPBNoHasBit,
         .flags = GPBFieldRepeated,
-        .type = GPBTypeMessage,
-        .offset = offsetof(GPBField_Storage, optionsArray),
+        .dataType = GPBDataTypeMessage,
+        .offset = offsetof(GPBField__storage_, optionsArray),
         .defaultValue.valueMessage = nil,
-        .typeSpecific.className = GPBStringifySymbol(GPBOption),
+        .dataTypeSpecific.className = GPBStringifySymbol(GPBOption),
         .fieldOptions = NULL,
       },
     };
@@ -268,20 +272,23 @@ typedef struct GPBField_Storage {
 #else
     static const char *extraTextFormatInfo = "\001\006\004\241!!\000";
 #endif  // GPBOBJC_SKIP_MESSAGE_TEXTFORMAT_EXTRAS
-    descriptor = [GPBDescriptor allocDescriptorForClass:[GPBField class]
-                                              rootClass:[GPBTypeRoot class]
-                                                   file:GPBTypeRoot_FileDescriptor()
-                                                 fields:fields
-                                             fieldCount:sizeof(fields) / sizeof(GPBMessageFieldDescription)
-                                                 oneofs:NULL
-                                             oneofCount:0
-                                                  enums:enums
-                                              enumCount:sizeof(enums) / sizeof(GPBMessageEnumDescription)
-                                                 ranges:NULL
-                                             rangeCount:0
-                                            storageSize:sizeof(GPBField_Storage)
-                                             wireFormat:NO
-                                    extraTextFormatInfo:extraTextFormatInfo];
+    GPBDescriptor *localDescriptor =
+        [GPBDescriptor allocDescriptorForClass:[GPBField class]
+                                     rootClass:[GPBTypeRoot class]
+                                          file:GPBTypeRoot_FileDescriptor()
+                                        fields:fields
+                                    fieldCount:sizeof(fields) / sizeof(GPBMessageFieldDescription)
+                                        oneofs:NULL
+                                    oneofCount:0
+                                         enums:enums
+                                     enumCount:sizeof(enums) / sizeof(GPBMessageEnumDescription)
+                                        ranges:NULL
+                                    rangeCount:0
+                                   storageSize:sizeof(GPBField__storage_)
+                                    wireFormat:NO
+                           extraTextFormatInfo:extraTextFormatInfo];
+    NSAssert(descriptor == nil, @"Startup recursed!");
+    descriptor = localDescriptor;
   }
   return descriptor;
 }
@@ -291,7 +298,7 @@ typedef struct GPBField_Storage {
 int32_t GPBField_Kind_RawValue(GPBField *message) {
   GPBDescriptor *descriptor = [GPBField descriptor];
   GPBFieldDescriptor *field = [descriptor fieldWithNumber:GPBField_FieldNumber_Kind];
-  return GPBGetInt32IvarWithField(message, field);
+  return GPBGetMessageInt32Field(message, field);
 }
 
 void SetGPBField_Kind_RawValue(GPBField *message, int32_t value) {
@@ -303,7 +310,7 @@ void SetGPBField_Kind_RawValue(GPBField *message, int32_t value) {
 int32_t GPBField_Cardinality_RawValue(GPBField *message) {
   GPBDescriptor *descriptor = [GPBField descriptor];
   GPBFieldDescriptor *field = [descriptor fieldWithNumber:GPBField_FieldNumber_Cardinality];
-  return GPBGetInt32IvarWithField(message, field);
+  return GPBGetMessageInt32Field(message, field);
 }
 
 void SetGPBField_Cardinality_RawValue(GPBField *message, int32_t value) {
@@ -407,22 +414,22 @@ BOOL GPBField_Cardinality_IsValidValue(int32_t value__) {
 @implementation GPBEnum
 
 @dynamic name;
-@dynamic enumvalueArray;
-@dynamic optionsArray;
+@dynamic enumvalueArray, enumvalueArray_Count;
+@dynamic optionsArray, optionsArray_Count;
 @dynamic hasSourceContext, sourceContext;
 
-typedef struct GPBEnum_Storage {
+typedef struct GPBEnum__storage_ {
   uint32_t _has_storage_[1];
   NSString *name;
   NSMutableArray *enumvalueArray;
   NSMutableArray *optionsArray;
   GPBSourceContext *sourceContext;
-} GPBEnum_Storage;
+} GPBEnum__storage_;
 
 // This method is threadsafe because it is initially called
 // in +initialize for each subclass.
 + (GPBDescriptor *)descriptor {
-  static GPBDescriptor *descriptor = NULL;
+  static GPBDescriptor *descriptor = nil;
   if (!descriptor) {
     static GPBMessageFieldDescription fields[] = {
       {
@@ -430,10 +437,10 @@ typedef struct GPBEnum_Storage {
         .number = GPBEnum_FieldNumber_Name,
         .hasIndex = 0,
         .flags = GPBFieldOptional,
-        .type = GPBTypeString,
-        .offset = offsetof(GPBEnum_Storage, name),
+        .dataType = GPBDataTypeString,
+        .offset = offsetof(GPBEnum__storage_, name),
         .defaultValue.valueString = nil,
-        .typeSpecific.className = NULL,
+        .dataTypeSpecific.className = NULL,
         .fieldOptions = NULL,
       },
       {
@@ -441,10 +448,10 @@ typedef struct GPBEnum_Storage {
         .number = GPBEnum_FieldNumber_EnumvalueArray,
         .hasIndex = GPBNoHasBit,
         .flags = GPBFieldRepeated,
-        .type = GPBTypeMessage,
-        .offset = offsetof(GPBEnum_Storage, enumvalueArray),
+        .dataType = GPBDataTypeMessage,
+        .offset = offsetof(GPBEnum__storage_, enumvalueArray),
         .defaultValue.valueMessage = nil,
-        .typeSpecific.className = GPBStringifySymbol(GPBEnumValue),
+        .dataTypeSpecific.className = GPBStringifySymbol(GPBEnumValue),
         .fieldOptions = NULL,
       },
       {
@@ -452,10 +459,10 @@ typedef struct GPBEnum_Storage {
         .number = GPBEnum_FieldNumber_OptionsArray,
         .hasIndex = GPBNoHasBit,
         .flags = GPBFieldRepeated,
-        .type = GPBTypeMessage,
-        .offset = offsetof(GPBEnum_Storage, optionsArray),
+        .dataType = GPBDataTypeMessage,
+        .offset = offsetof(GPBEnum__storage_, optionsArray),
         .defaultValue.valueMessage = nil,
-        .typeSpecific.className = GPBStringifySymbol(GPBOption),
+        .dataTypeSpecific.className = GPBStringifySymbol(GPBOption),
         .fieldOptions = NULL,
       },
       {
@@ -463,26 +470,29 @@ typedef struct GPBEnum_Storage {
         .number = GPBEnum_FieldNumber_SourceContext,
         .hasIndex = 3,
         .flags = GPBFieldOptional,
-        .type = GPBTypeMessage,
-        .offset = offsetof(GPBEnum_Storage, sourceContext),
+        .dataType = GPBDataTypeMessage,
+        .offset = offsetof(GPBEnum__storage_, sourceContext),
         .defaultValue.valueMessage = nil,
-        .typeSpecific.className = GPBStringifySymbol(GPBSourceContext),
+        .dataTypeSpecific.className = GPBStringifySymbol(GPBSourceContext),
         .fieldOptions = NULL,
       },
     };
-    descriptor = [GPBDescriptor allocDescriptorForClass:[GPBEnum class]
-                                              rootClass:[GPBTypeRoot class]
-                                                   file:GPBTypeRoot_FileDescriptor()
-                                                 fields:fields
-                                             fieldCount:sizeof(fields) / sizeof(GPBMessageFieldDescription)
-                                                 oneofs:NULL
-                                             oneofCount:0
-                                                  enums:NULL
-                                              enumCount:0
-                                                 ranges:NULL
-                                             rangeCount:0
-                                            storageSize:sizeof(GPBEnum_Storage)
-                                             wireFormat:NO];
+    GPBDescriptor *localDescriptor =
+        [GPBDescriptor allocDescriptorForClass:[GPBEnum class]
+                                     rootClass:[GPBTypeRoot class]
+                                          file:GPBTypeRoot_FileDescriptor()
+                                        fields:fields
+                                    fieldCount:sizeof(fields) / sizeof(GPBMessageFieldDescription)
+                                        oneofs:NULL
+                                    oneofCount:0
+                                         enums:NULL
+                                     enumCount:0
+                                        ranges:NULL
+                                    rangeCount:0
+                                   storageSize:sizeof(GPBEnum__storage_)
+                                    wireFormat:NO];
+    NSAssert(descriptor == nil, @"Startup recursed!");
+    descriptor = localDescriptor;
   }
   return descriptor;
 }
@@ -495,19 +505,19 @@ typedef struct GPBEnum_Storage {
 
 @dynamic name;
 @dynamic number;
-@dynamic optionsArray;
+@dynamic optionsArray, optionsArray_Count;
 
-typedef struct GPBEnumValue_Storage {
+typedef struct GPBEnumValue__storage_ {
   uint32_t _has_storage_[1];
   int32_t number;
   NSString *name;
   NSMutableArray *optionsArray;
-} GPBEnumValue_Storage;
+} GPBEnumValue__storage_;
 
 // This method is threadsafe because it is initially called
 // in +initialize for each subclass.
 + (GPBDescriptor *)descriptor {
-  static GPBDescriptor *descriptor = NULL;
+  static GPBDescriptor *descriptor = nil;
   if (!descriptor) {
     static GPBMessageFieldDescription fields[] = {
       {
@@ -515,10 +525,10 @@ typedef struct GPBEnumValue_Storage {
         .number = GPBEnumValue_FieldNumber_Name,
         .hasIndex = 0,
         .flags = GPBFieldOptional,
-        .type = GPBTypeString,
-        .offset = offsetof(GPBEnumValue_Storage, name),
+        .dataType = GPBDataTypeString,
+        .offset = offsetof(GPBEnumValue__storage_, name),
         .defaultValue.valueString = nil,
-        .typeSpecific.className = NULL,
+        .dataTypeSpecific.className = NULL,
         .fieldOptions = NULL,
       },
       {
@@ -526,10 +536,10 @@ typedef struct GPBEnumValue_Storage {
         .number = GPBEnumValue_FieldNumber_Number,
         .hasIndex = 1,
         .flags = GPBFieldOptional,
-        .type = GPBTypeInt32,
-        .offset = offsetof(GPBEnumValue_Storage, number),
+        .dataType = GPBDataTypeInt32,
+        .offset = offsetof(GPBEnumValue__storage_, number),
         .defaultValue.valueInt32 = 0,
-        .typeSpecific.className = NULL,
+        .dataTypeSpecific.className = NULL,
         .fieldOptions = NULL,
       },
       {
@@ -537,26 +547,29 @@ typedef struct GPBEnumValue_Storage {
         .number = GPBEnumValue_FieldNumber_OptionsArray,
         .hasIndex = GPBNoHasBit,
         .flags = GPBFieldRepeated,
-        .type = GPBTypeMessage,
-        .offset = offsetof(GPBEnumValue_Storage, optionsArray),
+        .dataType = GPBDataTypeMessage,
+        .offset = offsetof(GPBEnumValue__storage_, optionsArray),
         .defaultValue.valueMessage = nil,
-        .typeSpecific.className = GPBStringifySymbol(GPBOption),
+        .dataTypeSpecific.className = GPBStringifySymbol(GPBOption),
         .fieldOptions = NULL,
       },
     };
-    descriptor = [GPBDescriptor allocDescriptorForClass:[GPBEnumValue class]
-                                              rootClass:[GPBTypeRoot class]
-                                                   file:GPBTypeRoot_FileDescriptor()
-                                                 fields:fields
-                                             fieldCount:sizeof(fields) / sizeof(GPBMessageFieldDescription)
-                                                 oneofs:NULL
-                                             oneofCount:0
-                                                  enums:NULL
-                                              enumCount:0
-                                                 ranges:NULL
-                                             rangeCount:0
-                                            storageSize:sizeof(GPBEnumValue_Storage)
-                                             wireFormat:NO];
+    GPBDescriptor *localDescriptor =
+        [GPBDescriptor allocDescriptorForClass:[GPBEnumValue class]
+                                     rootClass:[GPBTypeRoot class]
+                                          file:GPBTypeRoot_FileDescriptor()
+                                        fields:fields
+                                    fieldCount:sizeof(fields) / sizeof(GPBMessageFieldDescription)
+                                        oneofs:NULL
+                                    oneofCount:0
+                                         enums:NULL
+                                     enumCount:0
+                                        ranges:NULL
+                                    rangeCount:0
+                                   storageSize:sizeof(GPBEnumValue__storage_)
+                                    wireFormat:NO];
+    NSAssert(descriptor == nil, @"Startup recursed!");
+    descriptor = localDescriptor;
   }
   return descriptor;
 }
@@ -570,16 +583,16 @@ typedef struct GPBEnumValue_Storage {
 @dynamic name;
 @dynamic hasValue, value;
 
-typedef struct GPBOption_Storage {
+typedef struct GPBOption__storage_ {
   uint32_t _has_storage_[1];
   NSString *name;
   GPBAny *value;
-} GPBOption_Storage;
+} GPBOption__storage_;
 
 // This method is threadsafe because it is initially called
 // in +initialize for each subclass.
 + (GPBDescriptor *)descriptor {
-  static GPBDescriptor *descriptor = NULL;
+  static GPBDescriptor *descriptor = nil;
   if (!descriptor) {
     static GPBMessageFieldDescription fields[] = {
       {
@@ -587,10 +600,10 @@ typedef struct GPBOption_Storage {
         .number = GPBOption_FieldNumber_Name,
         .hasIndex = 0,
         .flags = GPBFieldOptional,
-        .type = GPBTypeString,
-        .offset = offsetof(GPBOption_Storage, name),
+        .dataType = GPBDataTypeString,
+        .offset = offsetof(GPBOption__storage_, name),
         .defaultValue.valueString = nil,
-        .typeSpecific.className = NULL,
+        .dataTypeSpecific.className = NULL,
         .fieldOptions = NULL,
       },
       {
@@ -598,26 +611,29 @@ typedef struct GPBOption_Storage {
         .number = GPBOption_FieldNumber_Value,
         .hasIndex = 1,
         .flags = GPBFieldOptional,
-        .type = GPBTypeMessage,
-        .offset = offsetof(GPBOption_Storage, value),
+        .dataType = GPBDataTypeMessage,
+        .offset = offsetof(GPBOption__storage_, value),
         .defaultValue.valueMessage = nil,
-        .typeSpecific.className = GPBStringifySymbol(GPBAny),
+        .dataTypeSpecific.className = GPBStringifySymbol(GPBAny),
         .fieldOptions = NULL,
       },
     };
-    descriptor = [GPBDescriptor allocDescriptorForClass:[GPBOption class]
-                                              rootClass:[GPBTypeRoot class]
-                                                   file:GPBTypeRoot_FileDescriptor()
-                                                 fields:fields
-                                             fieldCount:sizeof(fields) / sizeof(GPBMessageFieldDescription)
-                                                 oneofs:NULL
-                                             oneofCount:0
-                                                  enums:NULL
-                                              enumCount:0
-                                                 ranges:NULL
-                                             rangeCount:0
-                                            storageSize:sizeof(GPBOption_Storage)
-                                             wireFormat:NO];
+    GPBDescriptor *localDescriptor =
+        [GPBDescriptor allocDescriptorForClass:[GPBOption class]
+                                     rootClass:[GPBTypeRoot class]
+                                          file:GPBTypeRoot_FileDescriptor()
+                                        fields:fields
+                                    fieldCount:sizeof(fields) / sizeof(GPBMessageFieldDescription)
+                                        oneofs:NULL
+                                    oneofCount:0
+                                         enums:NULL
+                                     enumCount:0
+                                        ranges:NULL
+                                    rangeCount:0
+                                   storageSize:sizeof(GPBOption__storage_)
+                                    wireFormat:NO];
+    NSAssert(descriptor == nil, @"Startup recursed!");
+    descriptor = localDescriptor;
   }
   return descriptor;
 }

+ 201 - 171
objectivec/google/protobuf/Wrappers.pbobjc.m

@@ -11,11 +11,14 @@
 
 @end
 
+#pragma mark - GPBWrappersRoot_FileDescriptor
+
 static GPBFileDescriptor *GPBWrappersRoot_FileDescriptor(void) {
   // This is called by +initialize so there is no need to worry
   // about thread safety of the singleton.
   static GPBFileDescriptor *descriptor = NULL;
   if (!descriptor) {
+    GPBDebugCheckRuntimeVersion();
     descriptor = [[GPBFileDescriptor alloc] initWithPackage:@"google.protobuf"
                                                      syntax:GPBFileSyntaxProto3];
   }
@@ -28,15 +31,15 @@ static GPBFileDescriptor *GPBWrappersRoot_FileDescriptor(void) {
 
 @dynamic value;
 
-typedef struct GPBDoubleValue_Storage {
+typedef struct GPBDoubleValue__storage_ {
   uint32_t _has_storage_[1];
   double value;
-} GPBDoubleValue_Storage;
+} GPBDoubleValue__storage_;
 
 // This method is threadsafe because it is initially called
 // in +initialize for each subclass.
 + (GPBDescriptor *)descriptor {
-  static GPBDescriptor *descriptor = NULL;
+  static GPBDescriptor *descriptor = nil;
   if (!descriptor) {
     static GPBMessageFieldDescription fields[] = {
       {
@@ -44,26 +47,29 @@ typedef struct GPBDoubleValue_Storage {
         .number = GPBDoubleValue_FieldNumber_Value,
         .hasIndex = 0,
         .flags = GPBFieldOptional,
-        .type = GPBTypeDouble,
-        .offset = offsetof(GPBDoubleValue_Storage, value),
+        .dataType = GPBDataTypeDouble,
+        .offset = offsetof(GPBDoubleValue__storage_, value),
         .defaultValue.valueDouble = 0,
-        .typeSpecific.className = NULL,
+        .dataTypeSpecific.className = NULL,
         .fieldOptions = NULL,
       },
     };
-    descriptor = [GPBDescriptor allocDescriptorForClass:[GPBDoubleValue class]
-                                              rootClass:[GPBWrappersRoot class]
-                                                   file:GPBWrappersRoot_FileDescriptor()
-                                                 fields:fields
-                                             fieldCount:sizeof(fields) / sizeof(GPBMessageFieldDescription)
-                                                 oneofs:NULL
-                                             oneofCount:0
-                                                  enums:NULL
-                                              enumCount:0
-                                                 ranges:NULL
-                                             rangeCount:0
-                                            storageSize:sizeof(GPBDoubleValue_Storage)
-                                             wireFormat:NO];
+    GPBDescriptor *localDescriptor =
+        [GPBDescriptor allocDescriptorForClass:[GPBDoubleValue class]
+                                     rootClass:[GPBWrappersRoot class]
+                                          file:GPBWrappersRoot_FileDescriptor()
+                                        fields:fields
+                                    fieldCount:sizeof(fields) / sizeof(GPBMessageFieldDescription)
+                                        oneofs:NULL
+                                    oneofCount:0
+                                         enums:NULL
+                                     enumCount:0
+                                        ranges:NULL
+                                    rangeCount:0
+                                   storageSize:sizeof(GPBDoubleValue__storage_)
+                                    wireFormat:NO];
+    NSAssert(descriptor == nil, @"Startup recursed!");
+    descriptor = localDescriptor;
   }
   return descriptor;
 }
@@ -76,15 +82,15 @@ typedef struct GPBDoubleValue_Storage {
 
 @dynamic value;
 
-typedef struct GPBFloatValue_Storage {
+typedef struct GPBFloatValue__storage_ {
   uint32_t _has_storage_[1];
   float value;
-} GPBFloatValue_Storage;
+} GPBFloatValue__storage_;
 
 // This method is threadsafe because it is initially called
 // in +initialize for each subclass.
 + (GPBDescriptor *)descriptor {
-  static GPBDescriptor *descriptor = NULL;
+  static GPBDescriptor *descriptor = nil;
   if (!descriptor) {
     static GPBMessageFieldDescription fields[] = {
       {
@@ -92,26 +98,29 @@ typedef struct GPBFloatValue_Storage {
         .number = GPBFloatValue_FieldNumber_Value,
         .hasIndex = 0,
         .flags = GPBFieldOptional,
-        .type = GPBTypeFloat,
-        .offset = offsetof(GPBFloatValue_Storage, value),
+        .dataType = GPBDataTypeFloat,
+        .offset = offsetof(GPBFloatValue__storage_, value),
         .defaultValue.valueFloat = 0,
-        .typeSpecific.className = NULL,
+        .dataTypeSpecific.className = NULL,
         .fieldOptions = NULL,
       },
     };
-    descriptor = [GPBDescriptor allocDescriptorForClass:[GPBFloatValue class]
-                                              rootClass:[GPBWrappersRoot class]
-                                                   file:GPBWrappersRoot_FileDescriptor()
-                                                 fields:fields
-                                             fieldCount:sizeof(fields) / sizeof(GPBMessageFieldDescription)
-                                                 oneofs:NULL
-                                             oneofCount:0
-                                                  enums:NULL
-                                              enumCount:0
-                                                 ranges:NULL
-                                             rangeCount:0
-                                            storageSize:sizeof(GPBFloatValue_Storage)
-                                             wireFormat:NO];
+    GPBDescriptor *localDescriptor =
+        [GPBDescriptor allocDescriptorForClass:[GPBFloatValue class]
+                                     rootClass:[GPBWrappersRoot class]
+                                          file:GPBWrappersRoot_FileDescriptor()
+                                        fields:fields
+                                    fieldCount:sizeof(fields) / sizeof(GPBMessageFieldDescription)
+                                        oneofs:NULL
+                                    oneofCount:0
+                                         enums:NULL
+                                     enumCount:0
+                                        ranges:NULL
+                                    rangeCount:0
+                                   storageSize:sizeof(GPBFloatValue__storage_)
+                                    wireFormat:NO];
+    NSAssert(descriptor == nil, @"Startup recursed!");
+    descriptor = localDescriptor;
   }
   return descriptor;
 }
@@ -124,15 +133,15 @@ typedef struct GPBFloatValue_Storage {
 
 @dynamic value;
 
-typedef struct GPBInt64Value_Storage {
+typedef struct GPBInt64Value__storage_ {
   uint32_t _has_storage_[1];
   int64_t value;
-} GPBInt64Value_Storage;
+} GPBInt64Value__storage_;
 
 // This method is threadsafe because it is initially called
 // in +initialize for each subclass.
 + (GPBDescriptor *)descriptor {
-  static GPBDescriptor *descriptor = NULL;
+  static GPBDescriptor *descriptor = nil;
   if (!descriptor) {
     static GPBMessageFieldDescription fields[] = {
       {
@@ -140,26 +149,29 @@ typedef struct GPBInt64Value_Storage {
         .number = GPBInt64Value_FieldNumber_Value,
         .hasIndex = 0,
         .flags = GPBFieldOptional,
-        .type = GPBTypeInt64,
-        .offset = offsetof(GPBInt64Value_Storage, value),
+        .dataType = GPBDataTypeInt64,
+        .offset = offsetof(GPBInt64Value__storage_, value),
         .defaultValue.valueInt64 = 0LL,
-        .typeSpecific.className = NULL,
+        .dataTypeSpecific.className = NULL,
         .fieldOptions = NULL,
       },
     };
-    descriptor = [GPBDescriptor allocDescriptorForClass:[GPBInt64Value class]
-                                              rootClass:[GPBWrappersRoot class]
-                                                   file:GPBWrappersRoot_FileDescriptor()
-                                                 fields:fields
-                                             fieldCount:sizeof(fields) / sizeof(GPBMessageFieldDescription)
-                                                 oneofs:NULL
-                                             oneofCount:0
-                                                  enums:NULL
-                                              enumCount:0
-                                                 ranges:NULL
-                                             rangeCount:0
-                                            storageSize:sizeof(GPBInt64Value_Storage)
-                                             wireFormat:NO];
+    GPBDescriptor *localDescriptor =
+        [GPBDescriptor allocDescriptorForClass:[GPBInt64Value class]
+                                     rootClass:[GPBWrappersRoot class]
+                                          file:GPBWrappersRoot_FileDescriptor()
+                                        fields:fields
+                                    fieldCount:sizeof(fields) / sizeof(GPBMessageFieldDescription)
+                                        oneofs:NULL
+                                    oneofCount:0
+                                         enums:NULL
+                                     enumCount:0
+                                        ranges:NULL
+                                    rangeCount:0
+                                   storageSize:sizeof(GPBInt64Value__storage_)
+                                    wireFormat:NO];
+    NSAssert(descriptor == nil, @"Startup recursed!");
+    descriptor = localDescriptor;
   }
   return descriptor;
 }
@@ -172,15 +184,15 @@ typedef struct GPBInt64Value_Storage {
 
 @dynamic value;
 
-typedef struct GPBUInt64Value_Storage {
+typedef struct GPBUInt64Value__storage_ {
   uint32_t _has_storage_[1];
   uint64_t value;
-} GPBUInt64Value_Storage;
+} GPBUInt64Value__storage_;
 
 // This method is threadsafe because it is initially called
 // in +initialize for each subclass.
 + (GPBDescriptor *)descriptor {
-  static GPBDescriptor *descriptor = NULL;
+  static GPBDescriptor *descriptor = nil;
   if (!descriptor) {
     static GPBMessageFieldDescription fields[] = {
       {
@@ -188,26 +200,29 @@ typedef struct GPBUInt64Value_Storage {
         .number = GPBUInt64Value_FieldNumber_Value,
         .hasIndex = 0,
         .flags = GPBFieldOptional,
-        .type = GPBTypeUInt64,
-        .offset = offsetof(GPBUInt64Value_Storage, value),
+        .dataType = GPBDataTypeUInt64,
+        .offset = offsetof(GPBUInt64Value__storage_, value),
         .defaultValue.valueUInt64 = 0ULL,
-        .typeSpecific.className = NULL,
+        .dataTypeSpecific.className = NULL,
         .fieldOptions = NULL,
       },
     };
-    descriptor = [GPBDescriptor allocDescriptorForClass:[GPBUInt64Value class]
-                                              rootClass:[GPBWrappersRoot class]
-                                                   file:GPBWrappersRoot_FileDescriptor()
-                                                 fields:fields
-                                             fieldCount:sizeof(fields) / sizeof(GPBMessageFieldDescription)
-                                                 oneofs:NULL
-                                             oneofCount:0
-                                                  enums:NULL
-                                              enumCount:0
-                                                 ranges:NULL
-                                             rangeCount:0
-                                            storageSize:sizeof(GPBUInt64Value_Storage)
-                                             wireFormat:NO];
+    GPBDescriptor *localDescriptor =
+        [GPBDescriptor allocDescriptorForClass:[GPBUInt64Value class]
+                                     rootClass:[GPBWrappersRoot class]
+                                          file:GPBWrappersRoot_FileDescriptor()
+                                        fields:fields
+                                    fieldCount:sizeof(fields) / sizeof(GPBMessageFieldDescription)
+                                        oneofs:NULL
+                                    oneofCount:0
+                                         enums:NULL
+                                     enumCount:0
+                                        ranges:NULL
+                                    rangeCount:0
+                                   storageSize:sizeof(GPBUInt64Value__storage_)
+                                    wireFormat:NO];
+    NSAssert(descriptor == nil, @"Startup recursed!");
+    descriptor = localDescriptor;
   }
   return descriptor;
 }
@@ -220,15 +235,15 @@ typedef struct GPBUInt64Value_Storage {
 
 @dynamic value;
 
-typedef struct GPBInt32Value_Storage {
+typedef struct GPBInt32Value__storage_ {
   uint32_t _has_storage_[1];
   int32_t value;
-} GPBInt32Value_Storage;
+} GPBInt32Value__storage_;
 
 // This method is threadsafe because it is initially called
 // in +initialize for each subclass.
 + (GPBDescriptor *)descriptor {
-  static GPBDescriptor *descriptor = NULL;
+  static GPBDescriptor *descriptor = nil;
   if (!descriptor) {
     static GPBMessageFieldDescription fields[] = {
       {
@@ -236,26 +251,29 @@ typedef struct GPBInt32Value_Storage {
         .number = GPBInt32Value_FieldNumber_Value,
         .hasIndex = 0,
         .flags = GPBFieldOptional,
-        .type = GPBTypeInt32,
-        .offset = offsetof(GPBInt32Value_Storage, value),
+        .dataType = GPBDataTypeInt32,
+        .offset = offsetof(GPBInt32Value__storage_, value),
         .defaultValue.valueInt32 = 0,
-        .typeSpecific.className = NULL,
+        .dataTypeSpecific.className = NULL,
         .fieldOptions = NULL,
       },
     };
-    descriptor = [GPBDescriptor allocDescriptorForClass:[GPBInt32Value class]
-                                              rootClass:[GPBWrappersRoot class]
-                                                   file:GPBWrappersRoot_FileDescriptor()
-                                                 fields:fields
-                                             fieldCount:sizeof(fields) / sizeof(GPBMessageFieldDescription)
-                                                 oneofs:NULL
-                                             oneofCount:0
-                                                  enums:NULL
-                                              enumCount:0
-                                                 ranges:NULL
-                                             rangeCount:0
-                                            storageSize:sizeof(GPBInt32Value_Storage)
-                                             wireFormat:NO];
+    GPBDescriptor *localDescriptor =
+        [GPBDescriptor allocDescriptorForClass:[GPBInt32Value class]
+                                     rootClass:[GPBWrappersRoot class]
+                                          file:GPBWrappersRoot_FileDescriptor()
+                                        fields:fields
+                                    fieldCount:sizeof(fields) / sizeof(GPBMessageFieldDescription)
+                                        oneofs:NULL
+                                    oneofCount:0
+                                         enums:NULL
+                                     enumCount:0
+                                        ranges:NULL
+                                    rangeCount:0
+                                   storageSize:sizeof(GPBInt32Value__storage_)
+                                    wireFormat:NO];
+    NSAssert(descriptor == nil, @"Startup recursed!");
+    descriptor = localDescriptor;
   }
   return descriptor;
 }
@@ -268,15 +286,15 @@ typedef struct GPBInt32Value_Storage {
 
 @dynamic value;
 
-typedef struct GPBUInt32Value_Storage {
+typedef struct GPBUInt32Value__storage_ {
   uint32_t _has_storage_[1];
   uint32_t value;
-} GPBUInt32Value_Storage;
+} GPBUInt32Value__storage_;
 
 // This method is threadsafe because it is initially called
 // in +initialize for each subclass.
 + (GPBDescriptor *)descriptor {
-  static GPBDescriptor *descriptor = NULL;
+  static GPBDescriptor *descriptor = nil;
   if (!descriptor) {
     static GPBMessageFieldDescription fields[] = {
       {
@@ -284,26 +302,29 @@ typedef struct GPBUInt32Value_Storage {
         .number = GPBUInt32Value_FieldNumber_Value,
         .hasIndex = 0,
         .flags = GPBFieldOptional,
-        .type = GPBTypeUInt32,
-        .offset = offsetof(GPBUInt32Value_Storage, value),
+        .dataType = GPBDataTypeUInt32,
+        .offset = offsetof(GPBUInt32Value__storage_, value),
         .defaultValue.valueUInt32 = 0U,
-        .typeSpecific.className = NULL,
+        .dataTypeSpecific.className = NULL,
         .fieldOptions = NULL,
       },
     };
-    descriptor = [GPBDescriptor allocDescriptorForClass:[GPBUInt32Value class]
-                                              rootClass:[GPBWrappersRoot class]
-                                                   file:GPBWrappersRoot_FileDescriptor()
-                                                 fields:fields
-                                             fieldCount:sizeof(fields) / sizeof(GPBMessageFieldDescription)
-                                                 oneofs:NULL
-                                             oneofCount:0
-                                                  enums:NULL
-                                              enumCount:0
-                                                 ranges:NULL
-                                             rangeCount:0
-                                            storageSize:sizeof(GPBUInt32Value_Storage)
-                                             wireFormat:NO];
+    GPBDescriptor *localDescriptor =
+        [GPBDescriptor allocDescriptorForClass:[GPBUInt32Value class]
+                                     rootClass:[GPBWrappersRoot class]
+                                          file:GPBWrappersRoot_FileDescriptor()
+                                        fields:fields
+                                    fieldCount:sizeof(fields) / sizeof(GPBMessageFieldDescription)
+                                        oneofs:NULL
+                                    oneofCount:0
+                                         enums:NULL
+                                     enumCount:0
+                                        ranges:NULL
+                                    rangeCount:0
+                                   storageSize:sizeof(GPBUInt32Value__storage_)
+                                    wireFormat:NO];
+    NSAssert(descriptor == nil, @"Startup recursed!");
+    descriptor = localDescriptor;
   }
   return descriptor;
 }
@@ -316,15 +337,15 @@ typedef struct GPBUInt32Value_Storage {
 
 @dynamic value;
 
-typedef struct GPBBoolValue_Storage {
+typedef struct GPBBoolValue__storage_ {
   uint32_t _has_storage_[1];
   BOOL value;
-} GPBBoolValue_Storage;
+} GPBBoolValue__storage_;
 
 // This method is threadsafe because it is initially called
 // in +initialize for each subclass.
 + (GPBDescriptor *)descriptor {
-  static GPBDescriptor *descriptor = NULL;
+  static GPBDescriptor *descriptor = nil;
   if (!descriptor) {
     static GPBMessageFieldDescription fields[] = {
       {
@@ -332,26 +353,29 @@ typedef struct GPBBoolValue_Storage {
         .number = GPBBoolValue_FieldNumber_Value,
         .hasIndex = 0,
         .flags = GPBFieldOptional,
-        .type = GPBTypeBool,
-        .offset = offsetof(GPBBoolValue_Storage, value),
+        .dataType = GPBDataTypeBool,
+        .offset = offsetof(GPBBoolValue__storage_, value),
         .defaultValue.valueBool = NO,
-        .typeSpecific.className = NULL,
+        .dataTypeSpecific.className = NULL,
         .fieldOptions = NULL,
       },
     };
-    descriptor = [GPBDescriptor allocDescriptorForClass:[GPBBoolValue class]
-                                              rootClass:[GPBWrappersRoot class]
-                                                   file:GPBWrappersRoot_FileDescriptor()
-                                                 fields:fields
-                                             fieldCount:sizeof(fields) / sizeof(GPBMessageFieldDescription)
-                                                 oneofs:NULL
-                                             oneofCount:0
-                                                  enums:NULL
-                                              enumCount:0
-                                                 ranges:NULL
-                                             rangeCount:0
-                                            storageSize:sizeof(GPBBoolValue_Storage)
-                                             wireFormat:NO];
+    GPBDescriptor *localDescriptor =
+        [GPBDescriptor allocDescriptorForClass:[GPBBoolValue class]
+                                     rootClass:[GPBWrappersRoot class]
+                                          file:GPBWrappersRoot_FileDescriptor()
+                                        fields:fields
+                                    fieldCount:sizeof(fields) / sizeof(GPBMessageFieldDescription)
+                                        oneofs:NULL
+                                    oneofCount:0
+                                         enums:NULL
+                                     enumCount:0
+                                        ranges:NULL
+                                    rangeCount:0
+                                   storageSize:sizeof(GPBBoolValue__storage_)
+                                    wireFormat:NO];
+    NSAssert(descriptor == nil, @"Startup recursed!");
+    descriptor = localDescriptor;
   }
   return descriptor;
 }
@@ -364,15 +388,15 @@ typedef struct GPBBoolValue_Storage {
 
 @dynamic value;
 
-typedef struct GPBStringValue_Storage {
+typedef struct GPBStringValue__storage_ {
   uint32_t _has_storage_[1];
   NSString *value;
-} GPBStringValue_Storage;
+} GPBStringValue__storage_;
 
 // This method is threadsafe because it is initially called
 // in +initialize for each subclass.
 + (GPBDescriptor *)descriptor {
-  static GPBDescriptor *descriptor = NULL;
+  static GPBDescriptor *descriptor = nil;
   if (!descriptor) {
     static GPBMessageFieldDescription fields[] = {
       {
@@ -380,26 +404,29 @@ typedef struct GPBStringValue_Storage {
         .number = GPBStringValue_FieldNumber_Value,
         .hasIndex = 0,
         .flags = GPBFieldOptional,
-        .type = GPBTypeString,
-        .offset = offsetof(GPBStringValue_Storage, value),
+        .dataType = GPBDataTypeString,
+        .offset = offsetof(GPBStringValue__storage_, value),
         .defaultValue.valueString = nil,
-        .typeSpecific.className = NULL,
+        .dataTypeSpecific.className = NULL,
         .fieldOptions = NULL,
       },
     };
-    descriptor = [GPBDescriptor allocDescriptorForClass:[GPBStringValue class]
-                                              rootClass:[GPBWrappersRoot class]
-                                                   file:GPBWrappersRoot_FileDescriptor()
-                                                 fields:fields
-                                             fieldCount:sizeof(fields) / sizeof(GPBMessageFieldDescription)
-                                                 oneofs:NULL
-                                             oneofCount:0
-                                                  enums:NULL
-                                              enumCount:0
-                                                 ranges:NULL
-                                             rangeCount:0
-                                            storageSize:sizeof(GPBStringValue_Storage)
-                                             wireFormat:NO];
+    GPBDescriptor *localDescriptor =
+        [GPBDescriptor allocDescriptorForClass:[GPBStringValue class]
+                                     rootClass:[GPBWrappersRoot class]
+                                          file:GPBWrappersRoot_FileDescriptor()
+                                        fields:fields
+                                    fieldCount:sizeof(fields) / sizeof(GPBMessageFieldDescription)
+                                        oneofs:NULL
+                                    oneofCount:0
+                                         enums:NULL
+                                     enumCount:0
+                                        ranges:NULL
+                                    rangeCount:0
+                                   storageSize:sizeof(GPBStringValue__storage_)
+                                    wireFormat:NO];
+    NSAssert(descriptor == nil, @"Startup recursed!");
+    descriptor = localDescriptor;
   }
   return descriptor;
 }
@@ -412,15 +439,15 @@ typedef struct GPBStringValue_Storage {
 
 @dynamic value;
 
-typedef struct GPBBytesValue_Storage {
+typedef struct GPBBytesValue__storage_ {
   uint32_t _has_storage_[1];
   NSData *value;
-} GPBBytesValue_Storage;
+} GPBBytesValue__storage_;
 
 // This method is threadsafe because it is initially called
 // in +initialize for each subclass.
 + (GPBDescriptor *)descriptor {
-  static GPBDescriptor *descriptor = NULL;
+  static GPBDescriptor *descriptor = nil;
   if (!descriptor) {
     static GPBMessageFieldDescription fields[] = {
       {
@@ -428,26 +455,29 @@ typedef struct GPBBytesValue_Storage {
         .number = GPBBytesValue_FieldNumber_Value,
         .hasIndex = 0,
         .flags = GPBFieldOptional,
-        .type = GPBTypeData,
-        .offset = offsetof(GPBBytesValue_Storage, value),
+        .dataType = GPBDataTypeBytes,
+        .offset = offsetof(GPBBytesValue__storage_, value),
         .defaultValue.valueData = nil,
-        .typeSpecific.className = NULL,
+        .dataTypeSpecific.className = NULL,
         .fieldOptions = NULL,
       },
     };
-    descriptor = [GPBDescriptor allocDescriptorForClass:[GPBBytesValue class]
-                                              rootClass:[GPBWrappersRoot class]
-                                                   file:GPBWrappersRoot_FileDescriptor()
-                                                 fields:fields
-                                             fieldCount:sizeof(fields) / sizeof(GPBMessageFieldDescription)
-                                                 oneofs:NULL
-                                             oneofCount:0
-                                                  enums:NULL
-                                              enumCount:0
-                                                 ranges:NULL
-                                             rangeCount:0
-                                            storageSize:sizeof(GPBBytesValue_Storage)
-                                             wireFormat:NO];
+    GPBDescriptor *localDescriptor =
+        [GPBDescriptor allocDescriptorForClass:[GPBBytesValue class]
+                                     rootClass:[GPBWrappersRoot class]
+                                          file:GPBWrappersRoot_FileDescriptor()
+                                        fields:fields
+                                    fieldCount:sizeof(fields) / sizeof(GPBMessageFieldDescription)
+                                        oneofs:NULL
+                                    oneofCount:0
+                                         enums:NULL
+                                     enumCount:0
+                                        ranges:NULL
+                                    rangeCount:0
+                                   storageSize:sizeof(GPBBytesValue__storage_)
+                                    wireFormat:NO];
+    NSAssert(descriptor == nil, @"Startup recursed!");
+    descriptor = localDescriptor;
   }
   return descriptor;
 }

+ 1 - 1
src/Makefile.am

@@ -147,7 +147,7 @@ nobase_include_HEADERS =                                        \
   google/protobuf/compiler/java/java_names.h                    \
   google/protobuf/compiler/javanano/javanano_generator.h        \
   google/protobuf/compiler/objectivec/objectivec_generator.h    \
-  google/protobuf/compiler/objectivec/objectivec_helpers.h     \
+  google/protobuf/compiler/objectivec/objectivec_helpers.h      \
   google/protobuf/compiler/python/python_generator.h            \
   google/protobuf/compiler/ruby/ruby_generator.h                \
   google/protobuf/compiler/csharp/csharp_generator.h

+ 3 - 9
src/google/protobuf/compiler/objectivec/objectivec_enum_field.cc

@@ -55,8 +55,6 @@ void SetEnumVariables(const FieldDescriptor* descriptor,
       (descriptor->file() != descriptor->enum_type()->file())) {
     (*variables)["property_type"] = "enum " + type;
   }
-  // TODO(thomasvl): Make inclusion of descriptor compile time and output
-  // both of these. Note: Extensions currently have to have the EnumDescription.
   (*variables)["enum_verifier"] = type + "_IsValidValue";
   (*variables)["enum_desc_func"] = type + "_EnumDescriptor";
 
@@ -74,11 +72,9 @@ EnumFieldGenerator::~EnumFieldGenerator() {}
 
 void EnumFieldGenerator::GenerateFieldDescriptionTypeSpecific(
     io::Printer* printer) const {
-  // TODO(thomasvl): Output the CPP check to use descFunc or validator based
-  // on final compile.
   printer->Print(
       variables_,
-      "  .typeSpecific.enumDescFunc = $enum_desc_func$,\n");
+      "  .dataTypeSpecific.enumDescFunc = $enum_desc_func$,\n");
 }
 
 void EnumFieldGenerator::GenerateCFunctionDeclarations(
@@ -103,7 +99,7 @@ void EnumFieldGenerator::GenerateCFunctionImplementations(
       "int32_t $owning_message_class$_$capitalized_name$_RawValue($owning_message_class$ *message) {\n"
       "  GPBDescriptor *descriptor = [$owning_message_class$ descriptor];\n"
       "  GPBFieldDescriptor *field = [descriptor fieldWithNumber:$field_number_name$];\n"
-      "  return GPBGetInt32IvarWithField(message, field);\n"
+      "  return GPBGetMessageInt32Field(message, field);\n"
       "}\n"
       "\n"
       "void Set$owning_message_class$_$capitalized_name$_RawValue($owning_message_class$ *message, int32_t value) {\n"
@@ -137,11 +133,9 @@ RepeatedEnumFieldGenerator::~RepeatedEnumFieldGenerator() {}
 
 void RepeatedEnumFieldGenerator::GenerateFieldDescriptionTypeSpecific(
     io::Printer* printer) const {
-  // TODO(thomasvl): Output the CPP check to use descFunc or validator based
-  // on final compile.
   printer->Print(
       variables_,
-      "  .typeSpecific.enumDescFunc = $enum_desc_func$,\n");
+      "  .dataTypeSpecific.enumDescFunc = $enum_desc_func$,\n");
 }
 
 }  // namespace objectivec

+ 5 - 34
src/google/protobuf/compiler/objectivec/objectivec_extension.cc

@@ -46,24 +46,6 @@ ExtensionGenerator::ExtensionGenerator(const string& root_class_name,
     : method_name_(ExtensionMethodName(descriptor)),
       root_class_and_method_name_(root_class_name + "_" + method_name_),
       descriptor_(descriptor) {
-  // Extensions can be filtered via the method they are accessed off the
-  // file's Root with.
-  if (FilterClass(root_class_and_method_name_)) {
-    filter_reason_ =
-        string("Extension |") + root_class_and_method_name_ + "| was not whitelisted.";
-  } else {
-    // Extensions that add a Message field also require that field be allowed
-    // by the filter, or they aren't usable.
-    ObjectiveCType objc_type = GetObjectiveCType(descriptor_);
-    if (objc_type == OBJECTIVECTYPE_MESSAGE) {
-      const string message_class_name(ClassName(descriptor_->message_type()));
-      if (FilterClass(message_class_name)) {
-        filter_reason_ = string("Extension |") + root_class_and_method_name_ +
-                         "| needs message |" + message_class_name +
-                         "|, which was not whitelisted.";
-      }
-    }
-  }
   if (descriptor->is_map()) {
     // NOTE: src/google/protobuf/compiler/plugin.cc makes use of cerr for some
     // error cases, so it seems to be ok to use as a back door for errors.
@@ -77,10 +59,6 @@ ExtensionGenerator::ExtensionGenerator(const string& root_class_name,
 ExtensionGenerator::~ExtensionGenerator() {}
 
 void ExtensionGenerator::GenerateMembersHeader(io::Printer* printer) {
-  if (IsFiltered()) {
-    printer->Print("// $filter_reason$\n\n", "filter_reason", filter_reason_);
-    return;
-  }
   map<string, string> vars;
   vars["method_name"] = method_name_;
   SourceLocation location;
@@ -91,15 +69,11 @@ void ExtensionGenerator::GenerateMembersHeader(io::Printer* printer) {
   }
   printer->Print(vars,
                  "$comments$"
-                 "+ (GPBExtensionField*)$method_name$;\n");
+                 "+ (GPBExtensionDescriptor *)$method_name$;\n");
 }
 
 void ExtensionGenerator::GenerateStaticVariablesInitialization(
-    io::Printer* printer, bool* out_generated, bool root) {
-  if (IsFiltered()) {
-    return;
-  }
-  *out_generated = true;
+    io::Printer* printer) {
   map<string, string> vars;
   vars["root_class_and_method_name"] = root_class_and_method_name_;
   vars["extended_type"] = ClassName(descriptor_->containing_type());
@@ -122,14 +96,14 @@ void ExtensionGenerator::GenerateStaticVariablesInitialization(
     vars["type"] = "NULL";
   }
 
-  vars["default_name"] = GPBValueFieldName(descriptor_);
+  vars["default_name"] = GPBGenericValueFieldName(descriptor_);
   if (descriptor_->is_repeated()) {
     vars["default"] = "nil";
   } else {
     vars["default"] = DefaultValue(descriptor_);
   }
   string type = GetCapitalizedType(descriptor_);
-  vars["extension_type"] = string("GPBType") + type;
+  vars["extension_type"] = string("GPBDataType") + type;
 
   if (objc_type == OBJECTIVECTYPE_ENUM) {
     vars["enum_desc_func_name"] =
@@ -141,7 +115,7 @@ void ExtensionGenerator::GenerateStaticVariablesInitialization(
   printer->Print(vars,
                  "{\n"
                  "  .singletonName = GPBStringifySymbol($root_class_and_method_name$),\n"
-                 "  .type = $extension_type$,\n"
+                 "  .dataType = $extension_type$,\n"
                  "  .extendedClass = GPBStringifySymbol($extended_type$),\n"
                  "  .fieldNumber = $number$,\n"
                  "  .defaultValue.$default_name$ = $default$,\n"
@@ -152,9 +126,6 @@ void ExtensionGenerator::GenerateStaticVariablesInitialization(
 }
 
 void ExtensionGenerator::GenerateRegistrationSource(io::Printer* printer) {
-  if (IsFiltered()) {
-    return;
-  }
   printer->Print(
       "[registry addExtension:$root_class_and_method_name$];\n",
       "root_class_and_method_name", root_class_and_method_name_);

+ 1 - 5
src/google/protobuf/compiler/objectivec/objectivec_extension.h

@@ -52,16 +52,12 @@ class ExtensionGenerator {
   ~ExtensionGenerator();
 
   void GenerateMembersHeader(io::Printer* printer);
-  void GenerateStaticVariablesInitialization(io::Printer* printer,
-                                             bool* out_generated, bool root);
+  void GenerateStaticVariablesInitialization(io::Printer* printer);
   void GenerateRegistrationSource(io::Printer* printer);
 
-  bool IsFiltered() const { return filter_reason_.length() > 0; }
-
  private:
   string method_name_;
   string root_class_and_method_name_;
-  string filter_reason_;
   const FieldDescriptor* descriptor_;
 
   GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ExtensionGenerator);

+ 23 - 68
src/google/protobuf/compiler/objectivec/objectivec_field.cc

@@ -87,18 +87,16 @@ void SetCommonFieldVariables(const FieldDescriptor* descriptor,
     field_flags.push_back("GPBFieldHasDefaultValue");
   if (needs_custom_name) field_flags.push_back("GPBFieldTextFormatNameCustom");
   if (descriptor->type() == FieldDescriptor::TYPE_ENUM) {
-  // TODO(thomasvl): Output the CPP check to use descFunc or validator based
-  // on final compile.
     field_flags.push_back("GPBFieldHasEnumDescriptor");
   }
 
   (*variables)["fieldflags"] = BuildFlagsString(field_flags);
 
   (*variables)["default"] = DefaultValue(descriptor);
-  (*variables)["default_name"] = GPBValueFieldName(descriptor);
+  (*variables)["default_name"] = GPBGenericValueFieldName(descriptor);
 
-  (*variables)["typeSpecific_name"] = "className";
-  (*variables)["typeSpecific_value"] = "NULL";
+  (*variables)["dataTypeSpecific_name"] = "className";
+  (*variables)["dataTypeSpecific_value"] = "NULL";
 
   string field_options = descriptor->options().SerializeAsString();
   // Must convert to a standard byte order for packing length into
@@ -117,45 +115,6 @@ void SetCommonFieldVariables(const FieldDescriptor* descriptor,
   (*variables)["storage_attribute"] = "";
 }
 
-// A field generator that writes nothing.
-class EmptyFieldGenerator : public FieldGenerator {
- public:
-  EmptyFieldGenerator(const FieldDescriptor* descriptor, const string& reason)
-      : FieldGenerator(descriptor), reason_(reason) {}
-  virtual ~EmptyFieldGenerator() {}
-
-  virtual void GenerateFieldStorageDeclaration(io::Printer* printer) const {}
-  virtual void GeneratePropertyDeclaration(io::Printer* printer) const {
-    string name = FieldName(descriptor_);
-    string type;
-    switch (GetObjectiveCType(descriptor_)) {
-      case OBJECTIVECTYPE_MESSAGE:
-        type = ClassName(descriptor_->message_type()) + " *";
-        break;
-
-      case OBJECTIVECTYPE_ENUM:
-        type = EnumName(descriptor_->enum_type()) + " ";
-        break;
-
-      default:
-        type = string(descriptor_->type_name()) + " ";
-        break;
-    }
-    printer->Print("// Field |$type$$name$| $reason$\n\n", "type", type, "name",
-                   name, "reason", reason_);
-  }
-
-  virtual void GenerateFieldNumberConstant(io::Printer* printer) const {}
-  virtual void GeneratePropertyImplementation(io::Printer* printer) const {}
-  virtual void GenerateFieldDescription(io::Printer* printer) const {}
-
-  virtual bool WantsHasProperty(void) const { return false; }
-
- private:
-  string reason_;
-  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(EmptyFieldGenerator);
-};
-
 }  // namespace
 
 FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field) {
@@ -163,12 +122,7 @@ FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field) {
   if (field->is_repeated()) {
     switch (GetObjectiveCType(field)) {
       case OBJECTIVECTYPE_MESSAGE: {
-        string type = ClassName(field->message_type());
-        if (FilterClass(type)) {
-          string reason =
-              "Filtered by |" + type + "| not being whitelisted.";
-          result = new EmptyFieldGenerator(field, reason);
-        } else if (field->is_map()) {
+        if (field->is_map()) {
           result = new MapFieldGenerator(field);
         } else {
           result = new RepeatedMessageFieldGenerator(field);
@@ -185,14 +139,7 @@ FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field) {
   } else {
     switch (GetObjectiveCType(field)) {
       case OBJECTIVECTYPE_MESSAGE: {
-        string type = ClassName(field->message_type());
-        if (FilterClass(type)) {
-          string reason =
-              "Filtered by |" + type + "| not being whitelisted.";
-          result = new EmptyFieldGenerator(field, reason);
-        } else {
-          result = new MessageFieldGenerator(field);
-        }
+        result = new MessageFieldGenerator(field);
         break;
       }
       case OBJECTIVECTYPE_ENUM:
@@ -249,11 +196,17 @@ void FieldGenerator::GenerateFieldDescription(
       "  .number = $field_number_name$,\n"
       "  .hasIndex = $has_index$,\n"
       "  .flags = $fieldflags$,\n"
-      "  .type = GPBType$field_type$,\n"
-      "  .offset = offsetof($classname$_Storage, $name$),\n"
+      "  .dataType = GPBDataType$field_type$,\n"
+      "  .offset = offsetof($classname$__storage_, $name$),\n"
       "  .defaultValue.$default_name$ = $default$,\n");
 
-  // "  .typeSpecific.value* = [something],"
+  // TODO(thomasvl): It might be useful to add a CPP wrapper to support
+  // compiling away the EnumDescriptors.  To do that, we'd need a #if here
+  // to control setting the descriptor vs. the validator, and above in
+  // SetCommonFieldVariables() we'd want to wrap how we add
+  // GPBFieldHasDefaultValue to the flags.
+
+  // "  .dataTypeSpecific.value* = [something],"
   GenerateFieldDescriptionTypeSpecific(printer);
 
   const string& field_options(variables_.find("fieldoptions")->second);
@@ -280,7 +233,7 @@ void FieldGenerator::GenerateFieldDescriptionTypeSpecific(
     io::Printer* printer) const {
   printer->Print(
       variables_,
-      "  .typeSpecific.$typeSpecific_name$ = $typeSpecific_value$,\n");
+      "  .dataTypeSpecific.$dataTypeSpecific_name$ = $dataTypeSpecific_value$,\n");
 }
 
 void FieldGenerator::SetOneofIndexBase(int index_base) {
@@ -410,22 +363,24 @@ void RepeatedFieldGenerator::GenerateFieldStorageDeclaration(
 
 void RepeatedFieldGenerator::GeneratePropertyImplementation(
     io::Printer* printer) const {
-  printer->Print(variables_, "@dynamic $name$;\n");
+  printer->Print(variables_, "@dynamic $name$, $name$_Count;\n");
 }
 
 void RepeatedFieldGenerator::GeneratePropertyDeclaration(
     io::Printer* printer) const {
 
-  // Repeated fields don't need the has* properties, but this has the same
-  // logic as ObjCObjFieldGenerator::GeneratePropertyDeclaration() for dealing
-  // with needing Objective C's rules around storage name conventions (init*,
-  // new*, etc.)
+  // Repeated fields don't need the has* properties, but they do expose a
+  // *Count (to check without autocreation).  So for the field property we need
+  // the same logic as ObjCObjFieldGenerator::GeneratePropertyDeclaration() for
+  // dealing with needing Objective C's rules around storage name conventions
+  // (init*, new*, etc.)
 
   printer->Print(
       variables_,
       "$comments$"
       "$array_comment$"
-      "@property(nonatomic, readwrite, strong) $array_storage_type$ *$name$$storage_attribute$;\n");
+      "@property(nonatomic, readwrite, strong) $array_storage_type$ *$name$$storage_attribute$;\n"
+      "@property(nonatomic, readonly) NSUInteger $name$_Count;\n");
   if (IsInitName(variables_.find("name")->second)) {
     // If property name starts with init we need to annotate it to get past ARC.
     // http://stackoverflow.com/questions/18723226/how-do-i-annotate-an-objective-c-property-with-an-objc-method-family/18723227#18723227

+ 126 - 167
src/google/protobuf/compiler/objectivec/objectivec_file.cc

@@ -54,35 +54,24 @@ namespace objectivec {
 FileGenerator::FileGenerator(const FileDescriptor *file)
     : file_(file),
       root_class_name_(FileClassName(file)),
-      is_filtered_(true),
-      all_extensions_filtered_(true),
       is_public_dep_(false) {
-  // Validate the objc prefix, do this even if the file's contents are filtered
-  // to catch a bad prefix as soon as it is found.
+  // Validate the objc prefix.
   ValidateObjCClassPrefix(file_);
 
   for (int i = 0; i < file_->enum_type_count(); i++) {
     EnumGenerator *generator = new EnumGenerator(file_->enum_type(i));
-    // The enums are exposed via C functions, so they will dead strip if
-    // not used.
-    is_filtered_ &= false;
     enum_generators_.push_back(generator);
   }
   for (int i = 0; i < file_->message_type_count(); i++) {
     MessageGenerator *generator =
         new MessageGenerator(root_class_name_, file_->message_type(i));
-    is_filtered_ &= generator->IsFiltered();
-    is_filtered_ &= generator->IsSubContentFiltered();
     message_generators_.push_back(generator);
   }
   for (int i = 0; i < file_->extension_count(); i++) {
     ExtensionGenerator *generator =
         new ExtensionGenerator(root_class_name_, file_->extension(i));
-    is_filtered_ &= generator->IsFiltered();
-    all_extensions_filtered_ &= generator->IsFiltered();
     extension_generators_.push_back(generator);
   }
-  // If there is nothing in the file we filter it.
 }
 
 FileGenerator::~FileGenerator() {
@@ -116,8 +105,7 @@ void FileGenerator::GenerateHeader(io::Printer *printer) {
       "protoc_gen_objc_version",
       SimpleItoa(GOOGLE_PROTOBUF_OBJC_GEN_VERSION));
 
-  const vector<FileGenerator *> &dependency_generators =
-      DependencyGenerators();
+  const vector<FileGenerator *> &dependency_generators = DependencyGenerators();
   for (vector<FileGenerator *>::const_iterator iter =
            dependency_generators.begin();
        iter != dependency_generators.end(); ++iter) {
@@ -133,19 +121,17 @@ void FileGenerator::GenerateHeader(io::Printer *printer) {
 
   printer->Print("CF_EXTERN_C_BEGIN\n\n");
 
-  if (!IsFiltered()) {
-    set<string> fwd_decls;
-    for (vector<MessageGenerator *>::iterator iter = message_generators_.begin();
-         iter != message_generators_.end(); ++iter) {
-      (*iter)->DetermineForwardDeclarations(&fwd_decls);
-    }
-    for (set<string>::const_iterator i(fwd_decls.begin());
-         i != fwd_decls.end(); ++i) {
-      printer->Print("$value$;\n", "value", *i);
-    }
-    if (fwd_decls.begin() != fwd_decls.end()) {
-      printer->Print("\n");
-    }
+  set<string> fwd_decls;
+  for (vector<MessageGenerator *>::iterator iter = message_generators_.begin();
+       iter != message_generators_.end(); ++iter) {
+    (*iter)->DetermineForwardDeclarations(&fwd_decls);
+  }
+  for (set<string>::const_iterator i(fwd_decls.begin());
+       i != fwd_decls.end(); ++i) {
+    printer->Print("$value$;\n", "value", *i);
+  }
+  if (fwd_decls.begin() != fwd_decls.end()) {
+    printer->Print("\n");
   }
 
   // need to write out all enums first
@@ -160,36 +146,27 @@ void FileGenerator::GenerateHeader(io::Printer *printer) {
   }
 
   // For extensions to chain together, the Root gets created even if there
-  // are no extensions. So if the entire file isn't filtered away, output it.
-  if (!IsFiltered()) {
-    printer->Print(
-        "\n"
-        "#pragma mark - $root_class_name$\n"
-        "\n"
-        "@interface $root_class_name$ : GPBRootObject\n"
-        "\n"
-        "// The base class provides:\n"
-        "//   + (GPBExtensionRegistry *)extensionRegistry;\n"
-        "// which is an GPBExtensionRegistry that includes all the extensions defined by\n"
-        "// this file and all files that it depends on.\n"
-        "\n"
-        "@end\n"
-        "\n",
-        "root_class_name", root_class_name_);
-  }
+  // are no extensions.
+  printer->Print(
+      "\n"
+      "#pragma mark - $root_class_name$\n"
+      "\n"
+      "@interface $root_class_name$ : GPBRootObject\n"
+      "\n"
+      "// The base class provides:\n"
+      "//   + (GPBExtensionRegistry *)extensionRegistry;\n"
+      "// which is an GPBExtensionRegistry that includes all the extensions defined by\n"
+      "// this file and all files that it depends on.\n"
+      "\n"
+      "@end\n"
+      "\n",
+      "root_class_name", root_class_name_);
 
   if (extension_generators_.size() > 0) {
-    // The dynamic methods block is only needed if there are extensions. If
-    // they are all filtered, output the @interface as a comment so there is
-    // something left in the header for anyone that looks.
-    const char *root_line_prefix = "";
-    if (AreAllExtensionsFiltered()) {
-      root_line_prefix = "// ";
-    }
+    // The dynamic methods block is only needed if there are extensions.
     printer->Print(
-        "$root_line_prefix$@interface $root_class_name$ (DynamicMethods)\n",
-        "root_class_name", root_class_name_,
-        "root_line_prefix", root_line_prefix);
+        "@interface $root_class_name$ (DynamicMethods)\n",
+        "root_class_name", root_class_name_);
 
     for (vector<ExtensionGenerator *>::iterator iter =
              extension_generators_.begin();
@@ -197,8 +174,7 @@ void FileGenerator::GenerateHeader(io::Printer *printer) {
       (*iter)->GenerateMembersHeader(printer);
     }
 
-    printer->Print("$root_line_prefix$@end\n\n",
-                   "root_line_prefix", root_line_prefix);
+    printer->Print("@end\n\n");
   }  // extension_generators_.size() > 0
 
   for (vector<MessageGenerator *>::iterator iter = message_generators_.begin();
@@ -239,136 +215,119 @@ void FileGenerator::GenerateSource(io::Printer *printer) {
       "// @@protoc_insertion_point(imports)\n"
       "\n");
 
-  if (IsFiltered()) {
-    printer->Print(
-        "// File empty because all messages, extensions and enum have been filtered.\n"
-        "\n"
-        "\n"
-        "// Dummy symbol that will be stripped but will avoid linker warnings about\n"
-        "// no symbols in the .o form compiling this file.\n"
-        "static int $root_class_name$_dummy __attribute__((unused,used)) = 0;\n"
-        "\n"
-        "// @@protoc_insertion_point(global_scope)\n",
-        "root_class_name", root_class_name_);
-    return;
-  }
-
   printer->Print(
       "#pragma mark - $root_class_name$\n"
       "\n"
       "@implementation $root_class_name$\n\n",
       "root_class_name", root_class_name_);
 
-  bool generated_extensions = false;
-  if (file_->extension_count() + file_->message_type_count() +
-          file_->dependency_count() >
-      0) {
-    ostringstream extensions_stringstream;
-
-    if (file_->extension_count() + file_->message_type_count() > 0) {
-      io::OstreamOutputStream extensions_outputstream(&extensions_stringstream);
-      io::Printer extensions_printer(&extensions_outputstream, '$');
-      extensions_printer.Print(
-          "static GPBExtensionDescription descriptions[] = {\n");
-      extensions_printer.Indent();
-      for (vector<ExtensionGenerator *>::iterator iter =
-               extension_generators_.begin();
-           iter != extension_generators_.end(); ++iter) {
-        (*iter)->GenerateStaticVariablesInitialization(
-            &extensions_printer, &generated_extensions, true);
-      }
-      for (vector<MessageGenerator *>::iterator iter =
-               message_generators_.begin();
-           iter != message_generators_.end(); ++iter) {
-        (*iter)->GenerateStaticVariablesInitialization(&extensions_printer,
-                                                       &generated_extensions);
-      }
-      extensions_printer.Outdent();
-      extensions_printer.Print("};\n");
-      if (generated_extensions) {
-        extensions_printer.Print(
-            "for (size_t i = 0; i < sizeof(descriptions) / sizeof(descriptions[0]); ++i) {\n"
-            "  GPBExtensionField *extension = [[GPBExtensionField alloc] initWithDescription:&descriptions[i]];\n"
-            "  [registry addExtension:extension];\n"
-            "  [self globallyRegisterExtension:extension];\n"
-            "  [extension release];\n"
-            "}\n");
-      } else {
-        extensions_printer.Print("#pragma unused (descriptions)\n");
-      }
-      const vector<FileGenerator *> &dependency_generators =
-          DependencyGenerators();
-      if (dependency_generators.size()) {
-        for (vector<FileGenerator *>::const_iterator iter =
-                 dependency_generators.begin();
-             iter != dependency_generators.end(); ++iter) {
-          if (!(*iter)->IsFiltered()) {
-            extensions_printer.Print(
-                "[registry addExtensions:[$dependency$ extensionRegistry]];\n",
-                "dependency", (*iter)->RootClassName());
-            generated_extensions = true;
-          }
-        }
-      } else if (!generated_extensions) {
-        extensions_printer.Print("#pragma unused (registry)\n");
-      }
+  // Generate the extension initialization structures for the top level and
+  // any nested messages.
+  ostringstream extensions_stringstream;
+  if (file_->extension_count() + file_->message_type_count() > 0) {
+    io::OstreamOutputStream extensions_outputstream(&extensions_stringstream);
+    io::Printer extensions_printer(&extensions_outputstream, '$');
+    for (vector<ExtensionGenerator *>::iterator iter =
+             extension_generators_.begin();
+         iter != extension_generators_.end(); ++iter) {
+      (*iter)->GenerateStaticVariablesInitialization(&extensions_printer);
+    }
+    for (vector<MessageGenerator *>::iterator iter =
+             message_generators_.begin();
+         iter != message_generators_.end(); ++iter) {
+      (*iter)->GenerateStaticVariablesInitialization(&extensions_printer);
     }
+    extensions_stringstream.flush();
+  }
 
-    if (generated_extensions) {
+  // If there were any extensions or this file has any dependencies, output
+  // a registry to override to create the file specific registry.
+  const string& extensions_str = extensions_stringstream.str();
+  if (extensions_str.length() > 0 || file_->dependency_count() > 0) {
+    printer->Print(
+        "+ (GPBExtensionRegistry*)extensionRegistry {\n"
+        "  // This is called by +initialize so there is no need to worry\n"
+        "  // about thread safety and initialization of registry.\n"
+        "  static GPBExtensionRegistry* registry = nil;\n"
+        "  if (!registry) {\n"
+        "    GPBDebugCheckRuntimeVersion();\n"
+        "    registry = [[GPBExtensionRegistry alloc] init];\n");
+
+    printer->Indent();
+    printer->Indent();
+
+    if (extensions_str.length() > 0) {
       printer->Print(
-          "+ (GPBExtensionRegistry*)extensionRegistry {\n"
-          "  // This is called by +initialize so there is no need to worry\n"
-          "  // about thread safety and initialization of registry.\n"
-          "  static GPBExtensionRegistry* registry = nil;\n"
-          "  if (!registry) {\n"
-          "    registry = [[GPBExtensionRegistry alloc] init];\n");
-
-      printer->Indent();
+          "static GPBExtensionDescription descriptions[] = {\n");
       printer->Indent();
-
-      extensions_stringstream.flush();
-      printer->Print(extensions_stringstream.str().c_str());
-      printer->Outdent();
+      printer->Print(extensions_str.c_str());
       printer->Outdent();
+      printer->Print(
+          "};\n"
+          "for (size_t i = 0; i < sizeof(descriptions) / sizeof(descriptions[0]); ++i) {\n"
+          "  GPBExtensionDescriptor *extension =\n"
+          "      [[GPBExtensionDescriptor alloc] initWithExtensionDescription:&descriptions[i]];\n"
+          "  [registry addExtension:extension];\n"
+          "  [self globallyRegisterExtension:extension];\n"
+          "  [extension release];\n"
+          "}\n");
+    }
 
+    const vector<FileGenerator *> &dependency_generators =
+        DependencyGenerators();
+    for (vector<FileGenerator *>::const_iterator iter =
+             dependency_generators.begin();
+         iter != dependency_generators.end(); ++iter) {
       printer->Print(
-          "  }\n"
-          "  return registry;\n"
-          "}\n"
-          "\n");
+          "[registry addExtensions:[$dependency$ extensionRegistry]];\n",
+          "dependency", (*iter)->RootClassName());
     }
+
+    printer->Outdent();
+    printer->Outdent();
+
+    printer->Print(
+        "  }\n"
+        "  return registry;\n"
+        "}\n"
+        "\n");
   }
 
   printer->Print("@end\n\n");
 
-
-  string syntax;
-  switch (file_->syntax()) {
-    case FileDescriptor::SYNTAX_UNKNOWN:
-      syntax = "GPBFileSyntaxUnknown";
-      break;
-    case FileDescriptor::SYNTAX_PROTO2:
-      syntax = "GPBFileSyntaxProto2";
-      break;
-    case FileDescriptor::SYNTAX_PROTO3:
-      syntax = "GPBFileSyntaxProto3";
-      break;
+  // File descriptor only needed if there are messages to use it.
+  if (message_generators_.size() > 0) {
+    string syntax;
+    switch (file_->syntax()) {
+      case FileDescriptor::SYNTAX_UNKNOWN:
+        syntax = "GPBFileSyntaxUnknown";
+        break;
+      case FileDescriptor::SYNTAX_PROTO2:
+        syntax = "GPBFileSyntaxProto2";
+        break;
+      case FileDescriptor::SYNTAX_PROTO3:
+        syntax = "GPBFileSyntaxProto3";
+        break;
+    }
+    printer->Print(
+        "#pragma mark - $root_class_name$_FileDescriptor\n"
+        "\n"
+        "static GPBFileDescriptor *$root_class_name$_FileDescriptor(void) {\n"
+        "  // This is called by +initialize so there is no need to worry\n"
+        "  // about thread safety of the singleton.\n"
+        "  static GPBFileDescriptor *descriptor = NULL;\n"
+        "  if (!descriptor) {\n"
+        "    GPBDebugCheckRuntimeVersion();\n"
+        "    descriptor = [[GPBFileDescriptor alloc] initWithPackage:@\"$package$\"\n"
+        "                                                     syntax:$syntax$];\n"
+        "  }\n"
+        "  return descriptor;\n"
+        "}\n"
+        "\n",
+        "root_class_name", root_class_name_,
+        "package", file_->package(),
+        "syntax", syntax);
   }
-  printer->Print(
-      "static GPBFileDescriptor *$root_class_name$_FileDescriptor(void) {\n"
-      "  // This is called by +initialize so there is no need to worry\n"
-      "  // about thread safety of the singleton.\n"
-      "  static GPBFileDescriptor *descriptor = NULL;\n"
-      "  if (!descriptor) {\n"
-      "    descriptor = [[GPBFileDescriptor alloc] initWithPackage:@\"$package$\"\n"
-      "                                                     syntax:$syntax$];\n"
-      "  }\n"
-      "  return descriptor;\n"
-      "}\n"
-      "\n",
-      "root_class_name", root_class_name_,
-      "package", file_->package(),
-      "syntax", syntax);
 
   for (vector<EnumGenerator *>::iterator iter = enum_generators_.begin();
        iter != enum_generators_.end(); ++iter) {

+ 0 - 4
src/google/protobuf/compiler/objectivec/objectivec_file.h

@@ -64,8 +64,6 @@ class FileGenerator {
   const string& RootClassName() const { return root_class_name_; }
   const string Path() const;
 
-  bool IsFiltered() const { return is_filtered_; }
-  bool AreAllExtensionsFiltered() const { return all_extensions_filtered_; }
   bool IsPublicDependency() const { return is_public_dep_; }
 
  protected:
@@ -84,8 +82,6 @@ class FileGenerator {
   vector<EnumGenerator*> enum_generators_;
   vector<MessageGenerator*> message_generators_;
   vector<ExtensionGenerator*> extension_generators_;
-  bool is_filtered_;
-  bool all_extensions_filtered_;
   bool is_public_dep_;
 
   const vector<FileGenerator*>& DependencyGenerators();

+ 0 - 4
src/google/protobuf/compiler/objectivec/objectivec_generator.cc

@@ -58,10 +58,6 @@ bool ObjectiveCGenerator::Generate(const FileDescriptor* file,
     return false;
   }
 
-  if (!InitializeClassWhitelist(error)) {
-    return false;
-  }
-
   FileGenerator file_generator(file);
 
   string filepath = FilePath(file);

+ 4 - 59
src/google/protobuf/compiler/objectivec/objectivec_helpers.cc

@@ -50,8 +50,6 @@ namespace objectivec {
 
 namespace {
 
-hash_set<string> gClassWhitelist;
-
 // islower()/isupper()/tolower()/toupper() change based on locale.
 //
 // src/google/protobuf/stubs/strutil.h:150 has the same pattern. For the
@@ -580,7 +578,7 @@ string GetCapitalizedType(const FieldDescriptor* field) {
     case FieldDescriptor::TYPE_STRING:
       return "String";
     case FieldDescriptor::TYPE_BYTES:
-      return "Data";
+      return "Bytes";
     case FieldDescriptor::TYPE_ENUM:
       return "Enum";
     case FieldDescriptor::TYPE_GROUP:
@@ -684,8 +682,9 @@ static string HandleExtremeFloatingPoint(string val, bool add_float_suffix) {
   }
 }
 
-string GPBValueFieldName(const FieldDescriptor* field) {
-  // Returns the field within the GPBValue union to use for the given field.
+string GPBGenericValueFieldName(const FieldDescriptor* field) {
+  // Returns the field within the GPBGenericValue union to use for the given
+  // field.
   if (field->is_repeated()) {
       return "valueMessage";
   }
@@ -831,60 +830,6 @@ string BuildCommentsString(const SourceLocation& location) {
   return final_comments;
 }
 
-bool InitializeClassWhitelist(string* error) {
-  const char* env_var_value = getenv("GPB_OBJC_CLASS_WHITELIST_PATHS");
-  if (env_var_value == NULL) {
-    return true;
-  }
-
-  // The values are joined with ';' in case we ever want to make this a
-  // generator parameter also (instead of env var), and generator parameter
-  // parsing already has meaning for ',' and ':'.
-  vector<string> file_paths = Split(env_var_value, ";", true);
-
-  for (vector<string>::const_iterator i = file_paths.begin();
-       i != file_paths.end(); ++i) {
-    const string& file_path = *i;
-
-    ifstream stream(file_path.c_str(), ifstream::in);
-    if (!stream.good()) {
-      if (error != NULL) {
-        stringstream err_stream;
-        err_stream << endl << file_path << ":0:0: error: Unable to open";
-        *error = err_stream.str();
-        return false;
-      }
-    }
-
-    string input_line;
-    while (stream.good()) {
-      getline(stream, input_line);
-      string trimmed_line(TrimString(input_line));
-      if (trimmed_line.length() == 0) {
-        // Skip empty lines
-        continue;
-      }
-      if (trimmed_line[0] == '/' || trimmed_line[0] == '#') {
-        // Skip comments and potential preprocessor symbols
-        continue;
-      }
-      gClassWhitelist.insert(trimmed_line);
-    }
-  }
-  return true;
-}
-
-bool FilterClass(const string& name) {
-  if (gClassWhitelist.count(name) > 0) {
-    // Whitelisted, don't filter.
-    return false;
-  }
-
-  // If there was no list, default to everything in.
-  // If there was a list, default to everything out.
-  return gClassWhitelist.size() > 0;
-}
-
 void TextFormatDecodeData::AddString(int32 key,
                                      const string& input_for_decode,
                                      const string& desired_output) {

+ 1 - 4
src/google/protobuf/compiler/objectivec/objectivec_helpers.h

@@ -138,16 +138,13 @@ inline ObjectiveCType GetObjectiveCType(const FieldDescriptor* field) {
 bool IsPrimitiveType(const FieldDescriptor* field);
 bool IsReferenceType(const FieldDescriptor* field);
 
-string GPBValueFieldName(const FieldDescriptor* field);
+string GPBGenericValueFieldName(const FieldDescriptor* field);
 string DefaultValue(const FieldDescriptor* field);
 
 string BuildFlagsString(const vector<string>& strings);
 
 string BuildCommentsString(const SourceLocation& location);
 
-bool InitializeClassWhitelist(string* error);
-bool FilterClass(const string& name);
-
 // Generate decode data needed for ObjC's GPBDecodeTextFormatName() to transform
 // the input into the the expected output.
 class LIBPROTOC_EXPORT TextFormatDecodeData {

+ 8 - 0
src/google/protobuf/compiler/objectivec/objectivec_helpers_unittest.cc

@@ -242,6 +242,14 @@ TEST(ObjCHelperDeathTest, TextFormatDecodeData_Failures) {
 }
 #endif  // PROTOBUF_HAS_DEATH_TEST
 
+// TODO(thomasvl): Should probably add some unittests for all the special cases
+// of name mangling (class name, field name, enum names).  Rather than doing
+// this with an ObjC test in the objectivec directory, we should be able to
+// use src/google/protobuf/compiler/importer* (like other tests) to support a
+// virtual file system to feed in protos, once we have the Descriptor tree, the
+// tests could use the helper methods for generating names and validate the
+// right things are happening.
+
 }  // namespace
 }  // namespace objectivec
 }  // namespace compiler

+ 181 - 188
src/google/protobuf/compiler/objectivec/objectivec_message.cc

@@ -178,49 +178,25 @@ MessageGenerator::MessageGenerator(const string& root_classname,
     : root_classname_(root_classname),
       descriptor_(descriptor),
       field_generators_(descriptor),
-      class_name_(ClassName(descriptor_)),
-      sub_content_filtered_(true) {
-  if (FilterClass(class_name_)) {
-    filter_reason_ =
-        string("Message |") + class_name_ + "| was not whitelisted.";
+      class_name_(ClassName(descriptor_)) {
+  for (int i = 0; i < descriptor_->extension_count(); i++) {
+    extension_generators_.push_back(
+        new ExtensionGenerator(class_name_, descriptor_->extension(i)));
   }
-  if (!IsFiltered()) {
-    // No need to generate extensions if this message is filtered
-    for (int i = 0; i < descriptor_->extension_count(); i++) {
-      extension_generators_.push_back(
-          new ExtensionGenerator(class_name_, descriptor_->extension(i)));
-    }
-    // No need to generate oneofs if this message is filtered.
-    for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
-      OneofGenerator* generator = new OneofGenerator(descriptor_->oneof_decl(i));
-      oneof_generators_.push_back(generator);
-    }
+
+  for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
+    OneofGenerator* generator = new OneofGenerator(descriptor_->oneof_decl(i));
+    oneof_generators_.push_back(generator);
   }
 
-  // We may have enums of this message that are used even if the message
-  // itself is filtered.
   for (int i = 0; i < descriptor_->enum_type_count(); i++) {
     EnumGenerator* generator = new EnumGenerator(descriptor_->enum_type(i));
-    // The enums are exposed via C functions, so they will dead strip if
-    // not used.
-    sub_content_filtered_ &= false;
     enum_generators_.push_back(generator);
   }
 
-  // We may have nested messages that are used even if the message itself
-  // is filtered.
   for (int i = 0; i < descriptor_->nested_type_count(); i++) {
-    const Descriptor* nested_descriptor = descriptor_->nested_type(i);
     MessageGenerator* generator =
-        new MessageGenerator(root_classname_, nested_descriptor);
-    // Don't check map entries for being filtered, as they don't directly
-    // generate anything in Objective C.  In theory, they only should include
-    // references to other toplevel types, but we still make the generators
-    // to be safe.
-    if (!IsMapEntryMessage(nested_descriptor)) {
-      sub_content_filtered_ &= generator->IsFiltered();
-    }
-    sub_content_filtered_ &= generator->IsSubContentFiltered();
+        new MessageGenerator(root_classname_, descriptor_->nested_type(i));
     nested_message_generators_.push_back(generator);
   }
 }
@@ -236,31 +212,26 @@ MessageGenerator::~MessageGenerator() {
 }
 
 void MessageGenerator::GenerateStaticVariablesInitialization(
-    io::Printer* printer, bool* out_generated) {
-  if (!IsFiltered()) {
-    // Skip extensions if we are filtered.
-    for (vector<ExtensionGenerator*>::iterator iter =
-             extension_generators_.begin();
-         iter != extension_generators_.end(); ++iter) {
-      (*iter)->GenerateStaticVariablesInitialization(printer, out_generated,
-                                                     false);
-    }
+    io::Printer* printer) {
+  for (vector<ExtensionGenerator*>::iterator iter =
+           extension_generators_.begin();
+       iter != extension_generators_.end(); ++iter) {
+    (*iter)->GenerateStaticVariablesInitialization(printer);
   }
 
-  // Generating sub messages is perfectly fine though.
   for (vector<MessageGenerator*>::iterator iter =
            nested_message_generators_.begin();
        iter != nested_message_generators_.end(); ++iter) {
-    (*iter)->GenerateStaticVariablesInitialization(printer, out_generated);
+    (*iter)->GenerateStaticVariablesInitialization(printer);
   }
 }
 
 void MessageGenerator::DetermineForwardDeclarations(set<string>* fwd_decls) {
-  if (!IsFiltered() && !IsMapEntryMessage(descriptor_)) {
+  if (!IsMapEntryMessage(descriptor_)) {
     for (int i = 0; i < descriptor_->field_count(); i++) {
       const FieldDescriptor* fieldDescriptor = descriptor_->field(i);
-      // If it is a the field is repeated, the type will be and *Array,
-      // and we don't need any forward decl.
+      // If it is a the field is repeated, the type will be and *Array, and we
+      // don't need any forward decl.
       if (fieldDescriptor->is_repeated()) {
         continue;
       }
@@ -291,12 +262,10 @@ void MessageGenerator::GenerateEnumHeader(io::Printer* printer) {
 
 void MessageGenerator::GenerateExtensionRegistrationSource(
     io::Printer* printer) {
-  if (!IsFiltered()) {
-    for (vector<ExtensionGenerator*>::iterator iter =
-             extension_generators_.begin();
-         iter != extension_generators_.end(); ++iter) {
-      (*iter)->GenerateRegistrationSource(printer);
-    }
+  for (vector<ExtensionGenerator*>::iterator iter =
+           extension_generators_.begin();
+       iter != extension_generators_.end(); ++iter) {
+    (*iter)->GenerateRegistrationSource(printer);
   }
 
   for (vector<MessageGenerator*>::iterator iter =
@@ -317,101 +286,84 @@ void MessageGenerator::GenerateMessageHeader(io::Printer* printer) {
     return;
   }
 
-  if (IsFiltered()) {
-    printer->Print("// $filter_reason$\n\n",
-                   "filter_reason", filter_reason_);
-  } else {
-    printer->Print(
-        "#pragma mark - $classname$\n"
-        "\n",
-        "classname", class_name_);
+  printer->Print(
+      "#pragma mark - $classname$\n"
+      "\n",
+      "classname", class_name_);
 
-    if (descriptor_->field_count()) {
-      // Even if there are fields, they could be filtered away, so always use
-      // a buffer to confirm we have something.
-      ostringstream fieldnumber_stringstream;
-      {
-        scoped_array<const FieldDescriptor*> sorted_fields(
-            SortFieldsByNumber(descriptor_));
-
-        io::OstreamOutputStream fieldnumber_outputstream(
-            &fieldnumber_stringstream);
-        io::Printer fieldnumber_printer(&fieldnumber_outputstream, '$');
-        for (int i = 0; i < descriptor_->field_count(); i++) {
-          field_generators_.get(sorted_fields[i])
-              .GenerateFieldNumberConstant(&fieldnumber_printer);
-        }
-        fieldnumber_stringstream.flush();
-      }
-      const string& fieldnumber_str = fieldnumber_stringstream.str();
-      if (fieldnumber_str.length()) {
-        printer->Print("typedef GPB_ENUM($classname$_FieldNumber) {\n",
-                       "classname", class_name_);
-        printer->Indent();
-        printer->Print(fieldnumber_str.c_str());
-        printer->Outdent();
-        printer->Print("};\n\n");
-      }
-    }
+  if (descriptor_->field_count()) {
+    scoped_array<const FieldDescriptor*> sorted_fields(
+        SortFieldsByNumber(descriptor_));
 
-    for (vector<OneofGenerator*>::iterator iter = oneof_generators_.begin();
-         iter != oneof_generators_.end(); ++iter) {
-      (*iter)->GenerateCaseEnum(printer);
-    }
+    printer->Print("typedef GPB_ENUM($classname$_FieldNumber) {\n",
+                   "classname", class_name_);
+    printer->Indent();
 
-    string message_comments;
-    SourceLocation location;
-    if (descriptor_->GetSourceLocation(&location)) {
-      message_comments = BuildCommentsString(location);
-    } else {
-      message_comments = "";
+    for (int i = 0; i < descriptor_->field_count(); i++) {
+      field_generators_.get(sorted_fields[i])
+          .GenerateFieldNumberConstant(printer);
     }
 
-    printer->Print(
-        "$comments$@interface $classname$ : GPBMessage\n\n",
-        "classname", class_name_,
-        "comments", message_comments);
+    printer->Outdent();
+    printer->Print("};\n\n");
+  }
 
-    vector<char> seen_oneofs(descriptor_->oneof_decl_count(), 0);
-    for (int i = 0; i < descriptor_->field_count(); i++) {
-      const FieldDescriptor* field = descriptor_->field(i);
-      if (field->containing_oneof() != NULL) {
-        const int oneof_index = field->containing_oneof()->index();
-        if (!seen_oneofs[oneof_index]) {
-          seen_oneofs[oneof_index] = 1;
-          oneof_generators_[oneof_index]->GeneratePublicCasePropertyDeclaration(
-              printer);
-        }
+  for (vector<OneofGenerator*>::iterator iter = oneof_generators_.begin();
+       iter != oneof_generators_.end(); ++iter) {
+    (*iter)->GenerateCaseEnum(printer);
+  }
+
+  string message_comments;
+  SourceLocation location;
+  if (descriptor_->GetSourceLocation(&location)) {
+    message_comments = BuildCommentsString(location);
+  } else {
+    message_comments = "";
+  }
+
+  printer->Print(
+      "$comments$@interface $classname$ : GPBMessage\n\n",
+      "classname", class_name_,
+      "comments", message_comments);
+
+  vector<char> seen_oneofs(descriptor_->oneof_decl_count(), 0);
+  for (int i = 0; i < descriptor_->field_count(); i++) {
+    const FieldDescriptor* field = descriptor_->field(i);
+    if (field->containing_oneof() != NULL) {
+      const int oneof_index = field->containing_oneof()->index();
+      if (!seen_oneofs[oneof_index]) {
+        seen_oneofs[oneof_index] = 1;
+        oneof_generators_[oneof_index]->GeneratePublicCasePropertyDeclaration(
+            printer);
       }
-      field_generators_.get(field)
-          .GeneratePropertyDeclaration(printer);
     }
+    field_generators_.get(field).GeneratePropertyDeclaration(printer);
+  }
 
-    printer->Print("@end\n\n");
+  printer->Print("@end\n\n");
 
-    for (int i = 0; i < descriptor_->field_count(); i++) {
-      field_generators_.get(descriptor_->field(i))
-          .GenerateCFunctionDeclarations(printer);
-    }
+  for (int i = 0; i < descriptor_->field_count(); i++) {
+    field_generators_.get(descriptor_->field(i))
+        .GenerateCFunctionDeclarations(printer);
+  }
 
-    if (!oneof_generators_.empty()) {
-      for (vector<OneofGenerator*>::iterator iter = oneof_generators_.begin();
-           iter != oneof_generators_.end(); ++iter) {
-        (*iter)->GenerateClearFunctionDeclaration(printer);
-      }
-      printer->Print("\n");
+  if (!oneof_generators_.empty()) {
+    for (vector<OneofGenerator*>::iterator iter = oneof_generators_.begin();
+         iter != oneof_generators_.end(); ++iter) {
+      (*iter)->GenerateClearFunctionDeclaration(printer);
     }
+    printer->Print("\n");
+  }
 
-    if (descriptor_->extension_count() > 0) {
-      printer->Print("@interface $classname$ (DynamicMethods)\n\n",
-                     "classname", class_name_);
-      for (vector<ExtensionGenerator*>::iterator iter =
-               extension_generators_.begin();
-           iter != extension_generators_.end(); ++iter) {
-        (*iter)->GenerateMembersHeader(printer);
-      }
-      printer->Print("@end\n\n");
+  if (descriptor_->extension_count() > 0) {
+    printer->Print("@interface $classname$ (DynamicMethods)\n\n",
+                   "classname", class_name_);
+    for (vector<ExtensionGenerator*>::iterator iter =
+             extension_generators_.begin();
+         iter != extension_generators_.end(); ++iter) {
+      (*iter)->GenerateMembersHeader(printer);
     }
+    printer->Print("@end\n\n");
   }
 
   for (vector<MessageGenerator*>::iterator iter =
@@ -422,7 +374,7 @@ void MessageGenerator::GenerateMessageHeader(io::Printer* printer) {
 }
 
 void MessageGenerator::GenerateSource(io::Printer* printer) {
-  if (!IsFiltered() && !IsMapEntryMessage(descriptor_)) {
+  if (!IsMapEntryMessage(descriptor_)) {
     printer->Print(
         "#pragma mark - $classname$\n"
         "\n",
@@ -454,6 +406,23 @@ void MessageGenerator::GenerateSource(io::Printer* printer) {
     sort(sorted_extensions.begin(), sorted_extensions.end(),
          ExtensionRangeOrdering());
 
+    // TODO(thomasvl): Finish optimizing has bit. The current behavior is as
+    // follows:
+    // 1. objectivec_field.cc's SetCommonFieldVariables() defaults the has_index
+    //    to the field's index in the list of fields.
+    // 2. RepeatedFieldGenerator::RepeatedFieldGenerator() sets has_index to
+    //    GPBNoHasBit because repeated fields & map<> fields don't use the has
+    //    bit.
+    // 3. FieldGenerator::SetOneofIndexBase() overrides has_bit with a negative
+    //    index that groups all the elements on of the oneof.
+    // So in has_storage, we need enough bits for the single fields that aren't
+    // in any oneof, and then one int32 for each oneof (to store the field
+    // number).  So we could save a little space by not using the field's index
+    // and instead make a second pass only assigning indexes for the fields
+    // that would need it.  The only savings would come when messages have over
+    // a multiple of 32 fields with some number being repeated or in oneofs to
+    // drop the count below that 32 multiple; so it hasn't seemed worth doing
+    // at the moment.
     size_t num_has_bits = descriptor_->field_count();
     size_t sizeof_has_storage = (num_has_bits + 31) / 32;
     // Tell all the fields the oneof base.
@@ -467,7 +436,7 @@ void MessageGenerator::GenerateSource(io::Printer* printer) {
 
     printer->Print(
         "\n"
-        "typedef struct $classname$_Storage {\n"
+        "typedef struct $classname$__storage_ {\n"
         "  uint32_t _has_storage_[$sizeof_has_storage$];\n",
         "classname", class_name_,
         "sizeof_has_storage", SimpleItoa(sizeof_has_storage));
@@ -479,14 +448,14 @@ void MessageGenerator::GenerateSource(io::Printer* printer) {
     }
     printer->Outdent();
 
-    printer->Print("} $classname$_Storage;\n\n", "classname", class_name_);
+    printer->Print("} $classname$__storage_;\n\n", "classname", class_name_);
 
 
     printer->Print(
         "// This method is threadsafe because it is initially called\n"
         "// in +initialize for each subclass.\n"
         "+ (GPBDescriptor *)descriptor {\n"
-        "  static GPBDescriptor *descriptor = NULL;\n"
+        "  static GPBDescriptor *descriptor = nil;\n"
         "  if (!descriptor) {\n");
 
     bool has_oneofs = oneof_generators_.size();
@@ -507,30 +476,45 @@ void MessageGenerator::GenerateSource(io::Printer* printer) {
           "    };\n");
     }
 
-    printer->Print(
-        "    static GPBMessageFieldDescription fields[] = {\n");
-    printer->Indent();
-    printer->Indent();
-    printer->Indent();
     TextFormatDecodeData text_format_decode_data;
-    for (int i = 0; i < descriptor_->field_count(); ++i) {
-      const FieldGenerator& field_generator =
-          field_generators_.get(sorted_fields[i]);
-      field_generator.GenerateFieldDescription(printer);
-      if (field_generator.needs_textformat_name_support()) {
-        text_format_decode_data.AddString(sorted_fields[i]->number(),
-                                          field_generator.generated_objc_name(),
-                                          field_generator.raw_field_name());
+    bool has_fields = descriptor_->field_count() > 0;
+    if (has_fields) {
+      // TODO(thomasvl): The plugin's FieldGenerator::GenerateFieldDescription()
+      // wraps the fieldOptions's value of this structure in an CPP gate so
+      // they can be compiled away; but that still results in a const char* in
+      // the structure for a NULL pointer for every message field.  If the
+      // fieldOptions are moved to a separate payload like the TextFormat extra
+      // data is, then it would shrink that static data shrinking the binaries
+      // a little more.
+      // TODO(thomasvl): proto3 syntax doens't need a defaultValue in the
+      // structure because primitive types are always zero.  If we add a second
+      // structure and a different initializer, we can avoid the wasted static
+      // storage for every field in a proto3 message.
+      printer->Print(
+          "    static GPBMessageFieldDescription fields[] = {\n");
+      printer->Indent();
+      printer->Indent();
+      printer->Indent();
+      for (int i = 0; i < descriptor_->field_count(); ++i) {
+        const FieldGenerator& field_generator =
+            field_generators_.get(sorted_fields[i]);
+        field_generator.GenerateFieldDescription(printer);
+        if (field_generator.needs_textformat_name_support()) {
+          text_format_decode_data.AddString(sorted_fields[i]->number(),
+                                            field_generator.generated_objc_name(),
+                                            field_generator.raw_field_name());
+        }
       }
+      printer->Outdent();
+      printer->Outdent();
+      printer->Outdent();
+      printer->Print(
+          "    };\n");
     }
-    printer->Outdent();
-    printer->Outdent();
-    printer->Outdent();
 
     bool has_enums = enum_generators_.size();
     if (has_enums) {
       printer->Print(
-          "    };\n"
           "    static GPBMessageEnumDescription enums[] = {\n");
       printer->Indent();
       printer->Indent();
@@ -543,12 +527,13 @@ void MessageGenerator::GenerateSource(io::Printer* printer) {
       printer->Outdent();
       printer->Outdent();
       printer->Outdent();
+      printer->Print(
+          "    };\n");
     }
 
     bool has_extensions = sorted_extensions.size();
     if (has_extensions) {
       printer->Print(
-          "    };\n"
           "    static GPBExtensionRange ranges[] = {\n");
       printer->Indent();
       printer->Indent();
@@ -561,11 +546,16 @@ void MessageGenerator::GenerateSource(io::Printer* printer) {
       printer->Outdent();
       printer->Outdent();
       printer->Outdent();
+      printer->Print(
+          "    };\n");
     }
 
     map<string, string> vars;
     vars["classname"] = class_name_;
     vars["rootclassname"] = root_classname_;
+    vars["fields"] = has_fields ? "fields" : "NULL";
+    vars["fields_count"] =
+        has_fields ? "sizeof(fields) / sizeof(GPBMessageFieldDescription)" : "0";
     vars["oneofs"] = has_oneofs ? "oneofs" : "NULL";
     vars["oneof_count"] =
         has_oneofs ? "sizeof(oneofs) / sizeof(GPBMessageOneofDescription)" : "0";
@@ -578,23 +568,23 @@ void MessageGenerator::GenerateSource(io::Printer* printer) {
     vars["wireformat"] =
         descriptor_->options().message_set_wire_format() ? "YES" : "NO";
 
-    printer->Print("    };\n");
     if (text_format_decode_data.num_entries() == 0) {
       printer->Print(
           vars,
-          "    descriptor = [GPBDescriptor allocDescriptorForClass:[$classname$ class]\n"
-          "                                              rootClass:[$rootclassname$ class]\n"
-          "                                                   file:$rootclassname$_FileDescriptor()\n"
-          "                                                 fields:fields\n"
-          "                                             fieldCount:sizeof(fields) / sizeof(GPBMessageFieldDescription)\n"
-          "                                                 oneofs:$oneofs$\n"
-          "                                             oneofCount:$oneof_count$\n"
-          "                                                  enums:$enums$\n"
-          "                                              enumCount:$enum_count$\n"
-          "                                                 ranges:$ranges$\n"
-          "                                             rangeCount:$range_count$\n"
-          "                                            storageSize:sizeof($classname$_Storage)\n"
-          "                                             wireFormat:$wireformat$];\n");
+          "    GPBDescriptor *localDescriptor =\n"
+          "        [GPBDescriptor allocDescriptorForClass:[$classname$ class]\n"
+          "                                     rootClass:[$rootclassname$ class]\n"
+          "                                          file:$rootclassname$_FileDescriptor()\n"
+          "                                        fields:$fields$\n"
+          "                                    fieldCount:$fields_count$\n"
+          "                                        oneofs:$oneofs$\n"
+          "                                    oneofCount:$oneof_count$\n"
+          "                                         enums:$enums$\n"
+          "                                     enumCount:$enum_count$\n"
+          "                                        ranges:$ranges$\n"
+          "                                    rangeCount:$range_count$\n"
+          "                                   storageSize:sizeof($classname$__storage_)\n"
+          "                                    wireFormat:$wireformat$];\n");
     } else {
       vars["extraTextFormatInfo"] = CEscape(text_format_decode_data.Data());
       printer->Print(
@@ -604,26 +594,29 @@ void MessageGenerator::GenerateSource(io::Printer* printer) {
           "#else\n"
           "    static const char *extraTextFormatInfo = \"$extraTextFormatInfo$\";\n"
           "#endif  // GPBOBJC_SKIP_MESSAGE_TEXTFORMAT_EXTRAS\n"
-          "    descriptor = [GPBDescriptor allocDescriptorForClass:[$classname$ class]\n"
-          "                                              rootClass:[$rootclassname$ class]\n"
-          "                                                   file:$rootclassname$_FileDescriptor()\n"
-          "                                                 fields:fields\n"
-          "                                             fieldCount:sizeof(fields) / sizeof(GPBMessageFieldDescription)\n"
-          "                                                 oneofs:$oneofs$\n"
-          "                                             oneofCount:$oneof_count$\n"
-          "                                                  enums:$enums$\n"
-          "                                              enumCount:$enum_count$\n"
-          "                                                 ranges:$ranges$\n"
-          "                                             rangeCount:$range_count$\n"
-          "                                            storageSize:sizeof($classname$_Storage)\n"
-          "                                             wireFormat:$wireformat$\n"
-          "                                    extraTextFormatInfo:extraTextFormatInfo];\n");
+          "    GPBDescriptor *localDescriptor =\n"
+          "        [GPBDescriptor allocDescriptorForClass:[$classname$ class]\n"
+          "                                     rootClass:[$rootclassname$ class]\n"
+          "                                          file:$rootclassname$_FileDescriptor()\n"
+          "                                        fields:$fields$\n"
+          "                                    fieldCount:$fields_count$\n"
+          "                                        oneofs:$oneofs$\n"
+          "                                    oneofCount:$oneof_count$\n"
+          "                                         enums:$enums$\n"
+          "                                     enumCount:$enum_count$\n"
+          "                                        ranges:$ranges$\n"
+          "                                    rangeCount:$range_count$\n"
+          "                                   storageSize:sizeof($classname$__storage_)\n"
+          "                                    wireFormat:$wireformat$\n"
+          "                           extraTextFormatInfo:extraTextFormatInfo];\n");
       }
       printer->Print(
-        "  }\n"
-        "  return descriptor;\n"
-        "}\n\n"
-        "@end\n\n");
+          "    NSAssert(descriptor == nil, @\"Startup recursed!\");\n"
+          "    descriptor = localDescriptor;\n"
+          "  }\n"
+          "  return descriptor;\n"
+          "}\n\n"
+          "@end\n\n");
 
     for (int i = 0; i < descriptor_->field_count(); i++) {
       field_generators_.get(descriptor_->field(i))

+ 1 - 10
src/google/protobuf/compiler/objectivec/objectivec_message.h

@@ -57,20 +57,13 @@ class MessageGenerator {
   MessageGenerator(const string& root_classname, const Descriptor* descriptor);
   ~MessageGenerator();
 
-  void GenerateStaticVariablesInitialization(io::Printer* printer,
-                                             bool* out_generated);
+  void GenerateStaticVariablesInitialization(io::Printer* printer);
   void GenerateEnumHeader(io::Printer* printer);
   void GenerateMessageHeader(io::Printer* printer);
   void GenerateSource(io::Printer* printer);
   void GenerateExtensionRegistrationSource(io::Printer* printer);
   void DetermineForwardDeclarations(set<string>* fwd_decls);
 
-  // This only speaks for this message, not sub message/enums.
-  bool IsFiltered() const { return filter_reason_.length() > 0; }
-  // This message being filtered doesn't effect this, instead it covers if
-  // there are any nested messages or enums.
-  bool IsSubContentFiltered() const { return sub_content_filtered_; }
-
  private:
   void GenerateParseFromMethodsHeader(io::Printer* printer);
 
@@ -87,8 +80,6 @@ class MessageGenerator {
   const Descriptor* descriptor_;
   FieldGeneratorMap field_generators_;
   const string class_name_;
-  string filter_reason_;
-  bool sub_content_filtered_;
   vector<ExtensionGenerator*> extension_generators_;
   vector<EnumGenerator*> enum_generators_;
   vector<MessageGenerator*> nested_message_generators_;

+ 1 - 1
src/google/protobuf/compiler/objectivec/objectivec_message_field.cc

@@ -53,7 +53,7 @@ void SetMessageVariables(const FieldDescriptor* descriptor,
   (*variables)["group_or_message"] =
       (descriptor->type() == FieldDescriptor::TYPE_GROUP) ? "Group" : "Message";
 
-  (*variables)["typeSpecific_value"] = "GPBStringifySymbol(" + message_type + ")";
+  (*variables)["dataTypeSpecific_value"] = "GPBStringifySymbol(" + message_type + ")";
 }
 
 }  // namespace

Kaikkia tiedostoja ei voida näyttää, sillä liian monta tiedostoa muuttui tässä diffissä