Kaynağa Gözat

Merge pull request #410 from thomasvl/objc_alpha2_drop

Objective C Second Alpha Drop
Paul Yang 10 yıl önce
ebeveyn
işleme
48f95941bc
95 değiştirilmiş dosya ile 5593 ekleme ve 1250 silme
  1. 2 2
      Makefile.am
  2. 1 1
      configure.ac
  3. 2 2
      objectivec/DevTools/check_version_stamps.sh
  4. 228 0
      objectivec/DevTools/full_mac_build.sh
  5. 0 36
      objectivec/DevTools/generate_descriptors_proto.sh
  6. 50 30
      objectivec/GPBArray.m
  7. 3 3
      objectivec/GPBBootstrap.h
  8. 5 3
      objectivec/GPBCodedInputStream.h
  9. 0 3
      objectivec/GPBDescriptor.h
  10. 6 30
      objectivec/GPBDescriptor.m
  11. 0 1
      objectivec/GPBDescriptor_PackagePrivate.h
  12. 288 52
      objectivec/GPBDictionary.m
  13. 234 324
      objectivec/GPBDictionary_PackagePrivate.h
  14. 18 1
      objectivec/GPBExtensionRegistry.h
  15. 9 1
      objectivec/GPBExtensionRegistry.m
  16. 0 40
      objectivec/GPBExtensionRegistry_PackagePrivate.h
  17. 59 35
      objectivec/GPBMessage.h
  18. 515 329
      objectivec/GPBMessage.m
  19. 4 2
      objectivec/GPBMessage_PackagePrivate.h
  20. 1 1
      objectivec/GPBProtocolBuffers_RuntimeSupport.h
  21. 48 13
      objectivec/GPBRootObject.m
  22. 4 0
      objectivec/GPBRootObject_PackagePrivate.h
  23. 69 28
      objectivec/GPBUtilities.m
  24. 0 2
      objectivec/ProtocolBuffers_OSX.xcodeproj/project.pbxproj
  25. 14 0
      objectivec/ProtocolBuffers_OSX.xcodeproj/xcshareddata/xcschemes/ProtocolBuffers.xcscheme
  26. 0 2
      objectivec/ProtocolBuffers_iOS.xcodeproj/project.pbxproj
  27. 14 0
      objectivec/ProtocolBuffers_iOS.xcodeproj/xcshareddata/xcschemes/ProtocolBuffers.xcscheme
  28. 77 0
      objectivec/README.md
  29. 80 7
      objectivec/Tests/GPBArrayTests.m
  30. 7 5
      objectivec/Tests/GPBCodedInputStreamTests.m
  31. 48 0
      objectivec/Tests/GPBConcurrencyTests.m
  32. 1 4
      objectivec/Tests/GPBDictionaryTests+Bool.m
  33. 1 4
      objectivec/Tests/GPBDictionaryTests+Int32.m
  34. 1 4
      objectivec/Tests/GPBDictionaryTests+Int64.m
  35. 1 4
      objectivec/Tests/GPBDictionaryTests+String.m
  36. 1 4
      objectivec/Tests/GPBDictionaryTests+UInt32.m
  37. 1 4
      objectivec/Tests/GPBDictionaryTests+UInt64.m
  38. 0 4
      objectivec/Tests/GPBDictionaryTests.pddm
  39. 3 2
      objectivec/Tests/GPBMessageTests+Merge.m
  40. 7 4
      objectivec/Tests/GPBMessageTests+Runtime.m
  41. 126 57
      objectivec/Tests/GPBMessageTests+Serialization.m
  42. 246 39
      objectivec/Tests/GPBMessageTests.m
  43. 5 4
      objectivec/Tests/GPBPerfTests.m
  44. 1 4
      objectivec/Tests/GPBStringTests.m
  45. 56 1
      objectivec/Tests/GPBSwiftTests.swift
  46. 7 0
      objectivec/Tests/GPBTestUtilities.h
  47. 1 19
      objectivec/Tests/GPBTestUtilities.m
  48. 10 7
      objectivec/Tests/GPBUnknownFieldSetTest.m
  49. 17 11
      objectivec/Tests/GPBWireFormatTests.m
  50. 2 0
      objectivec/Tests/unittest_objc.proto
  51. 21 0
      objectivec/Tests/unittest_runtime_proto2.proto
  52. 21 0
      objectivec/Tests/unittest_runtime_proto3.proto
  53. 54 0
      objectivec/generate_descriptors_proto.sh
  54. 100 0
      objectivec/google/protobuf/Any.pbobjc.h
  55. 93 0
      objectivec/google/protobuf/Any.pbobjc.m
  56. 121 0
      objectivec/google/protobuf/Api.pbobjc.h
  57. 262 0
      objectivec/google/protobuf/Api.pbobjc.m
  58. 10 13
      objectivec/google/protobuf/Descriptor.pbobjc.h
  59. 3 1
      objectivec/google/protobuf/Descriptor.pbobjc.m
  60. 10 2
      objectivec/google/protobuf/Duration.pbobjc.h
  61. 3 1
      objectivec/google/protobuf/Duration.pbobjc.m
  62. 41 0
      objectivec/google/protobuf/Empty.pbobjc.h
  63. 61 0
      objectivec/google/protobuf/Empty.pbobjc.m
  64. 160 0
      objectivec/google/protobuf/FieldMask.pbobjc.h
  65. 74 0
      objectivec/google/protobuf/FieldMask.pbobjc.m
  66. 44 0
      objectivec/google/protobuf/SourceContext.pbobjc.h
  67. 74 0
      objectivec/google/protobuf/SourceContext.pbobjc.m
  68. 134 0
      objectivec/google/protobuf/Struct.pbobjc.h
  69. 284 0
      objectivec/google/protobuf/Struct.pbobjc.m
  70. 10 2
      objectivec/google/protobuf/Timestamp.pbobjc.h
  71. 3 1
      objectivec/google/protobuf/Timestamp.pbobjc.m
  72. 274 0
      objectivec/google/protobuf/Type.pbobjc.h
  73. 628 0
      objectivec/google/protobuf/Type.pbobjc.m
  74. 154 0
      objectivec/google/protobuf/Wrappers.pbobjc.h
  75. 458 0
      objectivec/google/protobuf/Wrappers.pbobjc.m
  76. 1 1
      src/google/protobuf/compiler/objectivec/objectivec_enum.h
  77. 22 1
      src/google/protobuf/compiler/objectivec/objectivec_enum_field.cc
  78. 2 1
      src/google/protobuf/compiler/objectivec/objectivec_enum_field.h
  79. 2 2
      src/google/protobuf/compiler/objectivec/objectivec_extension.cc
  80. 2 2
      src/google/protobuf/compiler/objectivec/objectivec_extension.h
  81. 15 6
      src/google/protobuf/compiler/objectivec/objectivec_field.cc
  82. 7 5
      src/google/protobuf/compiler/objectivec/objectivec_field.h
  83. 76 60
      src/google/protobuf/compiler/objectivec/objectivec_file.cc
  84. 9 2
      src/google/protobuf/compiler/objectivec/objectivec_file.h
  85. 44 7
      src/google/protobuf/compiler/objectivec/objectivec_helpers.cc
  86. 3 0
      src/google/protobuf/compiler/objectivec/objectivec_helpers.h
  87. 2 0
      src/google/protobuf/compiler/objectivec/objectivec_map_field.cc
  88. 1 1
      src/google/protobuf/compiler/objectivec/objectivec_map_field.h
  89. 17 6
      src/google/protobuf/compiler/objectivec/objectivec_message.cc
  90. 1 1
      src/google/protobuf/compiler/objectivec/objectivec_message.h
  91. 6 0
      src/google/protobuf/compiler/objectivec/objectivec_message_field.cc
  92. 5 2
      src/google/protobuf/compiler/objectivec/objectivec_message_field.h
  93. 1 1
      src/google/protobuf/compiler/objectivec/objectivec_oneof.h
  94. 4 0
      src/google/protobuf/compiler/objectivec/objectivec_primitive_field.cc
  95. 3 3
      src/google/protobuf/compiler/objectivec/objectivec_primitive_field.h

+ 2 - 2
Makefile.am

@@ -212,9 +212,10 @@ javanano_EXTRA_DIST=
   javanano/pom.xml
 
 objectivec_EXTRA_DIST=                                                       \
-  objectivec/DevTools/generate_descriptors_proto.sh                          \
+  objectivec/DevTools/check_version_stamps.sh                                \
   objectivec/DevTools/pddm.py                                                \
   objectivec/DevTools/pddm_tests.py                                          \
+  objectivec/generate_descriptors_proto.sh                                   \
   objectivec/google/protobuf/Descriptor.pbobjc.h                             \
   objectivec/google/protobuf/Descriptor.pbobjc.m                             \
   objectivec/google/protobuf/Duration.pbobjc.h                               \
@@ -241,7 +242,6 @@ objectivec_EXTRA_DIST=                                                       \
   objectivec/GPBExtensionField_PackagePrivate.h                              \
   objectivec/GPBExtensionRegistry.h                                          \
   objectivec/GPBExtensionRegistry.m                                          \
-  objectivec/GPBExtensionRegistry_PackagePrivate.h                           \
   objectivec/GPBField.h                                                      \
   objectivec/GPBField.m                                                      \
   objectivec/GPBField_PackagePrivate.h                                       \

+ 1 - 1
configure.ac

@@ -23,7 +23,7 @@ AC_CONFIG_MACRO_DIR([m4])
 AC_ARG_VAR(DIST_LANG, [language to include in the distribution package (i.e., make dist)])
 case "$DIST_LANG" in
   "") DIST_LANG=all ;;
-  all | cpp | java | python | javanano | ruby) ;;
+  all | cpp | java | python | javanano | objectivec | ruby) ;;
   *) AC_MSG_FAILURE([unknown language: $DIST_LANG]) ;;
 esac
 AC_SUBST(DIST_LANG)

+ 2 - 2
objectivec/DevTools/check_version_stamps.sh

@@ -29,7 +29,7 @@ readonly PluginVersion=$( \
 )
 
 if [[ -z "${PluginVersion}" ]] ; then
-    die "Failed to fine ${ConstantName} in the plugin source (${PluginSrc})."
+    die "Failed to find ${ConstantName} in the plugin source (${PluginSrc})."
 fi
 
 # Collect version from runtime sources.
@@ -41,7 +41,7 @@ readonly RuntimeVersion=$( \
 )
 
 if [[ -z "${RuntimeVersion}" ]] ; then
-    die "Failed to fine ${ConstantName} in the runtime source (${RuntimeSrc})."
+    die "Failed to find ${ConstantName} in the runtime source (${RuntimeSrc})."
 fi
 
 # Compare them.

+ 228 - 0
objectivec/DevTools/full_mac_build.sh

@@ -0,0 +1,228 @@
+#!/bin/bash
+#
+# Helper to do build so you don't have to remember all the steps/args.
+
+
+set -eu
+
+# Some base locations.
+readonly ScriptDir=$(dirname "$(echo $0 | sed -e "s,^\([^/]\),$(pwd)/\1,")")
+readonly ProtoRootDir="${ScriptDir}/../.."
+
+printUsage() {
+  NAME=$(basename "${0}")
+  cat << EOF
+usage: ${NAME} [OPTIONS]
+
+This script does the common build steps needed.
+
+OPTIONS:
+
+ General:
+
+   -h, --help
+         Show this message
+   -c, --clean
+         Issue a clean before the normal build.
+   -a, --autogen
+         Start by rerunning autogen & configure.
+   -r, --regenerate-descriptors
+         The descriptor.proto is checked in generated, cause it to regenerate.
+   -j #, --jobs #
+         Force the number of parallel jobs (useful for debugging build issues).
+   --skip-xcode
+         Skip the invoke of Xcode to test the runtime on both iOS and OS X.
+   --skip-xcode-ios
+         Skip the invoke of Xcode to test the runtime on iOS.
+   --skip-xcode-osx
+         Skip the invoke of Xcode to test the runtime on OS X.
+
+EOF
+}
+
+header() {
+  echo ""
+  echo "========================================================================"
+  echo "    ${@}"
+  echo "========================================================================"
+}
+
+# Thanks to libtool, builds can fail in odd ways and since it eats some output
+# it can be hard to spot, so force error output if make exits with a non zero.
+wrapped_make() {
+  set +e  # Don't stop if the command fails.
+  make $*
+  MAKE_EXIT_STATUS=$?
+  if [ ${MAKE_EXIT_STATUS} -ne 0 ]; then
+    echo "Error: 'make $*' exited with status ${MAKE_EXIT_STATUS}"
+    exit ${MAKE_EXIT_STATUS}
+  fi
+  set -e
+}
+
+NUM_MAKE_JOBS=$(/usr/sbin/sysctl -n hw.ncpu)
+if [[ "${NUM_MAKE_JOBS}" -lt 4 ]] ; then
+  NUM_MAKE_JOBS=4
+fi
+
+DO_AUTOGEN=no
+DO_CLEAN=no
+REGEN_CPP_DESCRIPTORS=no
+DO_XCODE_IOS_TESTS=yes
+DO_XCODE_OSX_TESTS=yes
+while [[ $# != 0 ]]; do
+  case "${1}" in
+    -h | --help )
+      printUsage
+      exit 0
+      ;;
+    -c | --clean )
+      DO_CLEAN=yes
+      ;;
+    -a | --autogen )
+      DO_AUTOGEN=yes
+      ;;
+    -r | --regenerate-cpp-descriptors )
+      REGEN_CPP_DESCRIPTORS=yes
+      ;;
+    -j | --jobs )
+      shift
+      NUM_MAKE_JOBS="${1}"
+      ;;
+    --skip-xcode )
+      DO_XCODE_IOS_TESTS=no
+      DO_XCODE_OSX_TESTS=no
+      ;;
+    --skip-xcode-ios )
+      DO_XCODE_IOS_TESTS=no
+      ;;
+    --skip-xcode-osx )
+      DO_XCODE_OSX_TESTS=no
+      ;;
+    -*)
+      echo "ERROR: Unknown option: ${1}" 1>&2
+      printUsage
+      exit 1
+      ;;
+    *)
+      echo "ERROR: Unknown argument: ${1}" 1>&2
+      printUsage
+      exit 1
+      ;;
+  esac
+  shift
+done
+
+# Into the proto dir.
+pushd "${ProtoRootDir}"
+
+# if no Makefile, force the autogen.
+if [[ ! -f Makefile ]] ; then
+  DO_AUTOGEN=yes
+fi
+
+if [[ "${DO_AUTOGEN}" == "yes" ]] ; then
+  header "Running autogen & configure"
+  ./autogen.sh
+  ./configure CXXFLAGS="-mmacosx-version-min=10.9 -Wnon-virtual-dtor -Woverloaded-virtual -Wunused-const-variable -Wunused-function"
+fi
+
+if [[ "${DO_CLEAN}" == "yes" ]] ; then
+  header "Cleaning"
+  wrapped_make clean
+  if [[ "${DO_XCODE_IOS_TESTS}" == "yes" ]] ; then
+    XCODEBUILD_CLEAN_BASE_IOS=(
+      xcodebuild
+        -project objectivec/ProtocolBuffers_iOS.xcodeproj
+        -scheme ProtocolBuffers
+    )
+  "${XCODEBUILD_CLEAN_BASE_IOS[@]}" -configuration Debug clean
+  "${XCODEBUILD_CLEAN_BASE_IOS[@]}" -configuration Release clean
+  fi
+  if [[ "${DO_XCODE_OSX_TESTS}" == "yes" ]] ; then
+    XCODEBUILD_CLEAN_BASE_OSX=(
+      xcodebuild
+        -project objectivec/ProtocolBuffers_OSX.xcodeproj
+        -scheme ProtocolBuffers
+    )
+  "${XCODEBUILD_CLEAN_BASE_OSX[@]}" -configuration Debug clean
+  "${XCODEBUILD_CLEAN_BASE_OSX[@]}" -configuration Release clean
+  fi
+fi
+
+if [[ "${REGEN_CPP_DESCRIPTORS}" == "yes" ]] ; then
+  header "Regenerating the C++ descriptor sources."
+  ./generate_descriptor_proto.sh -j "${NUM_MAKE_JOBS}"
+fi
+
+header "Building"
+# Can't issue these together, when fully parallel, something sometimes chokes
+# at random.
+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).
+# (these patterns catch some extra stuff, but better to over sample than under)
+readonly NewestInput=$(find \
+   src/google/protobuf/*.proto \
+   src/.libs src/*.la src/protoc \
+   objectivec/generate_descriptors_proto.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 \
+      "${ProtoRootDir}/objectivec/google" \
+      -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
+  echo ">> Newest input is newer than oldest output, regenerating."
+  objectivec/generate_descriptors_proto.sh -j "${NUM_MAKE_JOBS}"
+else
+  echo ">> Newest input is older than oldest output, no need to regenerating."
+fi
+
+header "Checking on the ObjC Runtime Code"
+objectivec/DevTools/pddm_tests.py
+if ! objectivec/DevTools/pddm.py --dry-run objectivec/*.[hm] objectivec/Tests/*.[hm] ; then
+  echo ""
+  echo "Update by running:"
+  echo "   objectivec/DevTools/pddm.py objectivec/*.[hm] objectivec/Tests/*.[hm]"
+  exit 1
+fi
+
+if [[ "${DO_XCODE_IOS_TESTS}" == "yes" ]] ; then
+  XCODEBUILD_TEST_BASE_IOS=(
+    xcodebuild
+      -project objectivec/ProtocolBuffers_iOS.xcodeproj
+      -scheme ProtocolBuffers
+      # Don't need to worry about form factors or retina/non retina;
+      # just pick a mix of OS Versions and 32/64 bit.
+      -destination "platform=iOS Simulator,name=iPhone 4s,OS=7.1" # 32bit
+      -destination "platform=iOS Simulator,name=iPhone 6,OS=8.3" # 64bit
+      -destination "platform=iOS Simulator,name=iPad 2,OS=7.1" # 32bit
+      -destination "platform=iOS Simulator,name=iPad Air,OS=8.3" # 64bit
+  )
+  header "Doing Xcode iOS build/tests - Debug"
+  "${XCODEBUILD_TEST_BASE_IOS[@]}" -configuration Debug test
+  header "Doing Xcode iOS build/tests - Release"
+  "${XCODEBUILD_TEST_BASE_IOS[@]}" -configuration Release test
+  # Don't leave the simulator in the developer's face.
+  killall "iOS Simulator"
+fi
+if [[ "${DO_XCODE_OSX_TESTS}" == "yes" ]] ; then
+  XCODEBUILD_TEST_BASE_OSX=(
+    xcodebuild
+      -project objectivec/ProtocolBuffers_OSX.xcodeproj
+      -scheme ProtocolBuffers
+      # Since the ObjC 2.0 Runtime is required, 32bit OS X isn't supported.
+      -destination "platform=OS X,arch=x86_64" # 64bit
+  )
+  header "Doing Xcode OS X build/tests - Debug"
+  "${XCODEBUILD_TEST_BASE_OSX[@]}" -configuration Debug test
+  header "Doing Xcode OS X build/tests - Release"
+  "${XCODEBUILD_TEST_BASE_OSX[@]}" -configuration Release test
+fi

+ 0 - 36
objectivec/DevTools/generate_descriptors_proto.sh

@@ -1,36 +0,0 @@
-#!/bin/bash
-
-# This script will generate the common descriptors needed by the Objective C
-# runtime.
-
-# HINT:  Flags passed to generate_descriptor_proto.sh will be passed directly
-#   to make when building protoc.  This is particularly useful for passing
-#   -j4 to run 4 jobs simultaneously.
-
-set -eu
-
-readonly ScriptDir=$(dirname "$(echo $0 | sed -e "s,^\([^/]\),$(pwd)/\1,")")
-readonly ProtoRootDir="${ScriptDir}/../.."
-readonly ProtoC="${ProtoRootDir}/src/protoc"
-
-pushd "${ProtoRootDir}" > /dev/null
-
-# Compiler build fails if config.h hasn't been made yet (even if configure/etc.
-# have been run, so get that made first).
-make $@ config.h
-
-# Make sure the compiler is current.
-cd src
-make $@ protoc
-
-# These really should only be run when the inputs or compiler are newer than
-# the outputs.
-
-# Needed by the runtime.
-./protoc --objc_out="${ProtoRootDir}/objectivec" google/protobuf/descriptor.proto
-
-# Well known types that the library provides helpers for.
-./protoc --objc_out="${ProtoRootDir}/objectivec" google/protobuf/timestamp.proto
-./protoc --objc_out="${ProtoRootDir}/objectivec" google/protobuf/duration.proto
-
-popd > /dev/null

+ 50 - 30
objectivec/GPBArray.m

@@ -149,7 +149,9 @@ static BOOL ArrayDefault_IsValidValue(int32_t value) {
 
 //%PDDM-DEFINE ARRAY_IMMUTABLE_CORE(NAME, TYPE, ACCESSOR_NAME, FORMAT)
 //%- (void)dealloc {
-//%  NSAssert(!_autocreator, @"Autocreator must be cleared before release.");
+//%  NSAssert(!_autocreator,
+//%           @"%@: Autocreator must be cleared before release, autocreator: %@",
+//%           [self class], _autocreator);
 //%  free(_values);
 //%  [super dealloc];
 //%}
@@ -214,7 +216,7 @@ static BOOL ArrayDefault_IsValidValue(int32_t value) {
 //%  if (values == NULL || count == 0) return;
 //%MUTATION_HOOK_##HOOK_1()  NSUInteger initialCount = _count;
 //%  NSUInteger newCount = initialCount + count;
-//%MAYBE_GROW_TO_SET_COUNT(newCount);
+//%MAYBE_GROW_TO_SET_COUNT(newCount)
 //%  memcpy(&_values[initialCount], values, count * sizeof(TYPE));
 //%  if (_autocreator) {
 //%    GPBAutocreatedArrayModified(_autocreator, self);
@@ -225,7 +227,7 @@ static BOOL ArrayDefault_IsValidValue(int32_t value) {
 //%VALIDATE_RANGE(index, _count + 1)
 //%MUTATION_HOOK_##HOOK_2()  NSUInteger initialCount = _count;
 //%  NSUInteger newCount = initialCount + 1;
-//%MAYBE_GROW_TO_SET_COUNT(newCount);
+//%MAYBE_GROW_TO_SET_COUNT(newCount)
 //%  if (index != initialCount) {
 //%    memmove(&_values[index + 1], &_values[index], (initialCount - index) * sizeof(TYPE));
 //%  }
@@ -355,7 +357,9 @@ static BOOL ArrayDefault_IsValidValue(int32_t value) {
 }
 
 - (void)dealloc {
-  NSAssert(!_autocreator, @"Autocreator must be cleared before release.");
+  NSAssert(!_autocreator,
+           @"%@: Autocreator must be cleared before release, autocreator: %@",
+           [self class], _autocreator);
   free(_values);
   [super dealloc];
 }
@@ -442,7 +446,7 @@ static BOOL ArrayDefault_IsValidValue(int32_t value) {
   if (newCount > _capacity) {
     [self internalResizeToCapacity:CapacityFromCount(newCount)];
   }
-  _count = newCount;;
+  _count = newCount;
   memcpy(&_values[initialCount], values, count * sizeof(int32_t));
   if (_autocreator) {
     GPBAutocreatedArrayModified(_autocreator, self);
@@ -460,7 +464,7 @@ static BOOL ArrayDefault_IsValidValue(int32_t value) {
   if (newCount > _capacity) {
     [self internalResizeToCapacity:CapacityFromCount(newCount)];
   }
-  _count = newCount;;
+  _count = newCount;
   if (index != initialCount) {
     memmove(&_values[index + 1], &_values[index], (initialCount - index) * sizeof(int32_t));
   }
@@ -598,7 +602,9 @@ static BOOL ArrayDefault_IsValidValue(int32_t value) {
 }
 
 - (void)dealloc {
-  NSAssert(!_autocreator, @"Autocreator must be cleared before release.");
+  NSAssert(!_autocreator,
+           @"%@: Autocreator must be cleared before release, autocreator: %@",
+           [self class], _autocreator);
   free(_values);
   [super dealloc];
 }
@@ -685,7 +691,7 @@ static BOOL ArrayDefault_IsValidValue(int32_t value) {
   if (newCount > _capacity) {
     [self internalResizeToCapacity:CapacityFromCount(newCount)];
   }
-  _count = newCount;;
+  _count = newCount;
   memcpy(&_values[initialCount], values, count * sizeof(uint32_t));
   if (_autocreator) {
     GPBAutocreatedArrayModified(_autocreator, self);
@@ -703,7 +709,7 @@ static BOOL ArrayDefault_IsValidValue(int32_t value) {
   if (newCount > _capacity) {
     [self internalResizeToCapacity:CapacityFromCount(newCount)];
   }
-  _count = newCount;;
+  _count = newCount;
   if (index != initialCount) {
     memmove(&_values[index + 1], &_values[index], (initialCount - index) * sizeof(uint32_t));
   }
@@ -841,7 +847,9 @@ static BOOL ArrayDefault_IsValidValue(int32_t value) {
 }
 
 - (void)dealloc {
-  NSAssert(!_autocreator, @"Autocreator must be cleared before release.");
+  NSAssert(!_autocreator,
+           @"%@: Autocreator must be cleared before release, autocreator: %@",
+           [self class], _autocreator);
   free(_values);
   [super dealloc];
 }
@@ -928,7 +936,7 @@ static BOOL ArrayDefault_IsValidValue(int32_t value) {
   if (newCount > _capacity) {
     [self internalResizeToCapacity:CapacityFromCount(newCount)];
   }
-  _count = newCount;;
+  _count = newCount;
   memcpy(&_values[initialCount], values, count * sizeof(int64_t));
   if (_autocreator) {
     GPBAutocreatedArrayModified(_autocreator, self);
@@ -946,7 +954,7 @@ static BOOL ArrayDefault_IsValidValue(int32_t value) {
   if (newCount > _capacity) {
     [self internalResizeToCapacity:CapacityFromCount(newCount)];
   }
-  _count = newCount;;
+  _count = newCount;
   if (index != initialCount) {
     memmove(&_values[index + 1], &_values[index], (initialCount - index) * sizeof(int64_t));
   }
@@ -1084,7 +1092,9 @@ static BOOL ArrayDefault_IsValidValue(int32_t value) {
 }
 
 - (void)dealloc {
-  NSAssert(!_autocreator, @"Autocreator must be cleared before release.");
+  NSAssert(!_autocreator,
+           @"%@: Autocreator must be cleared before release, autocreator: %@",
+           [self class], _autocreator);
   free(_values);
   [super dealloc];
 }
@@ -1171,7 +1181,7 @@ static BOOL ArrayDefault_IsValidValue(int32_t value) {
   if (newCount > _capacity) {
     [self internalResizeToCapacity:CapacityFromCount(newCount)];
   }
-  _count = newCount;;
+  _count = newCount;
   memcpy(&_values[initialCount], values, count * sizeof(uint64_t));
   if (_autocreator) {
     GPBAutocreatedArrayModified(_autocreator, self);
@@ -1189,7 +1199,7 @@ static BOOL ArrayDefault_IsValidValue(int32_t value) {
   if (newCount > _capacity) {
     [self internalResizeToCapacity:CapacityFromCount(newCount)];
   }
-  _count = newCount;;
+  _count = newCount;
   if (index != initialCount) {
     memmove(&_values[index + 1], &_values[index], (initialCount - index) * sizeof(uint64_t));
   }
@@ -1327,7 +1337,9 @@ static BOOL ArrayDefault_IsValidValue(int32_t value) {
 }
 
 - (void)dealloc {
-  NSAssert(!_autocreator, @"Autocreator must be cleared before release.");
+  NSAssert(!_autocreator,
+           @"%@: Autocreator must be cleared before release, autocreator: %@",
+           [self class], _autocreator);
   free(_values);
   [super dealloc];
 }
@@ -1414,7 +1426,7 @@ static BOOL ArrayDefault_IsValidValue(int32_t value) {
   if (newCount > _capacity) {
     [self internalResizeToCapacity:CapacityFromCount(newCount)];
   }
-  _count = newCount;;
+  _count = newCount;
   memcpy(&_values[initialCount], values, count * sizeof(float));
   if (_autocreator) {
     GPBAutocreatedArrayModified(_autocreator, self);
@@ -1432,7 +1444,7 @@ static BOOL ArrayDefault_IsValidValue(int32_t value) {
   if (newCount > _capacity) {
     [self internalResizeToCapacity:CapacityFromCount(newCount)];
   }
-  _count = newCount;;
+  _count = newCount;
   if (index != initialCount) {
     memmove(&_values[index + 1], &_values[index], (initialCount - index) * sizeof(float));
   }
@@ -1570,7 +1582,9 @@ static BOOL ArrayDefault_IsValidValue(int32_t value) {
 }
 
 - (void)dealloc {
-  NSAssert(!_autocreator, @"Autocreator must be cleared before release.");
+  NSAssert(!_autocreator,
+           @"%@: Autocreator must be cleared before release, autocreator: %@",
+           [self class], _autocreator);
   free(_values);
   [super dealloc];
 }
@@ -1657,7 +1671,7 @@ static BOOL ArrayDefault_IsValidValue(int32_t value) {
   if (newCount > _capacity) {
     [self internalResizeToCapacity:CapacityFromCount(newCount)];
   }
-  _count = newCount;;
+  _count = newCount;
   memcpy(&_values[initialCount], values, count * sizeof(double));
   if (_autocreator) {
     GPBAutocreatedArrayModified(_autocreator, self);
@@ -1675,7 +1689,7 @@ static BOOL ArrayDefault_IsValidValue(int32_t value) {
   if (newCount > _capacity) {
     [self internalResizeToCapacity:CapacityFromCount(newCount)];
   }
-  _count = newCount;;
+  _count = newCount;
   if (index != initialCount) {
     memmove(&_values[index + 1], &_values[index], (initialCount - index) * sizeof(double));
   }
@@ -1813,7 +1827,9 @@ static BOOL ArrayDefault_IsValidValue(int32_t value) {
 }
 
 - (void)dealloc {
-  NSAssert(!_autocreator, @"Autocreator must be cleared before release.");
+  NSAssert(!_autocreator,
+           @"%@: Autocreator must be cleared before release, autocreator: %@",
+           [self class], _autocreator);
   free(_values);
   [super dealloc];
 }
@@ -1900,7 +1916,7 @@ static BOOL ArrayDefault_IsValidValue(int32_t value) {
   if (newCount > _capacity) {
     [self internalResizeToCapacity:CapacityFromCount(newCount)];
   }
-  _count = newCount;;
+  _count = newCount;
   memcpy(&_values[initialCount], values, count * sizeof(BOOL));
   if (_autocreator) {
     GPBAutocreatedArrayModified(_autocreator, self);
@@ -1918,7 +1934,7 @@ static BOOL ArrayDefault_IsValidValue(int32_t value) {
   if (newCount > _capacity) {
     [self internalResizeToCapacity:CapacityFromCount(newCount)];
   }
-  _count = newCount;;
+  _count = newCount;
   if (index != initialCount) {
     memmove(&_values[index + 1], &_values[index], (initialCount - index) * sizeof(BOOL));
   }
@@ -2083,7 +2099,9 @@ static BOOL ArrayDefault_IsValidValue(int32_t value) {
 // This block of code is generated, do not edit it directly.
 
 - (void)dealloc {
-  NSAssert(!_autocreator, @"Autocreator must be cleared before release.");
+  NSAssert(!_autocreator,
+           @"%@: Autocreator must be cleared before release, autocreator: %@",
+           [self class], _autocreator);
   free(_values);
   [super dealloc];
 }
@@ -2229,7 +2247,7 @@ static BOOL ArrayDefault_IsValidValue(int32_t value) {
   if (newCount > _capacity) {
     [self internalResizeToCapacity:CapacityFromCount(newCount)];
   }
-  _count = newCount;;
+  _count = newCount;
   memcpy(&_values[initialCount], values, count * sizeof(int32_t));
   if (_autocreator) {
     GPBAutocreatedArrayModified(_autocreator, self);
@@ -2247,7 +2265,7 @@ static BOOL ArrayDefault_IsValidValue(int32_t value) {
   if (newCount > _capacity) {
     [self internalResizeToCapacity:CapacityFromCount(newCount)];
   }
-  _count = newCount;;
+  _count = newCount;
   if (index != initialCount) {
     memmove(&_values[index + 1], &_values[index], (initialCount - index) * sizeof(int32_t));
   }
@@ -2332,7 +2350,7 @@ static BOOL ArrayDefault_IsValidValue(int32_t value) {
   if (newCount > _capacity) {
     [self internalResizeToCapacity:CapacityFromCount(newCount)];
   }
-  _count = newCount;;
+  _count = newCount;
   memcpy(&_values[initialCount], values, count * sizeof(int32_t));
   if (_autocreator) {
     GPBAutocreatedArrayModified(_autocreator, self);
@@ -2355,7 +2373,7 @@ static BOOL ArrayDefault_IsValidValue(int32_t value) {
   if (newCount > _capacity) {
     [self internalResizeToCapacity:CapacityFromCount(newCount)];
   }
-  _count = newCount;;
+  _count = newCount;
   if (index != initialCount) {
     memmove(&_values[index + 1], &_values[index], (initialCount - index) * sizeof(int32_t));
   }
@@ -2407,7 +2425,9 @@ static BOOL ArrayDefault_IsValidValue(int32_t value) {
 }
 
 - (void)dealloc {
-  NSAssert(!_autocreator, @"Autocreator must be cleared before release.");
+  NSAssert(!_autocreator,
+           @"%@: Autocreator must be cleared before release, autocreator: %@",
+           [self class], _autocreator);
   [_array release];
   [super dealloc];
 }

+ 3 - 3
objectivec/GPBBootstrap.h

@@ -51,11 +51,11 @@
 // the Swift bridge will have one where the names line up to support short
 // names since they are scoped to the enum.
 // https://developer.apple.com/library/ios/documentation/Swift/Conceptual/BuildingCocoaApps/InteractingWithCAPIs.html#//apple_ref/doc/uid/TP40014216-CH8-XID_11
-#define GPB_ENUM(X) enum X##_ : int32_t X; typedef NS_ENUM(int32_t, X##_)
-// GPB_ENUM_FWD_DECLARE is used for forward declaring enums ex:
+#define GPB_ENUM(X) NS_ENUM(int32_t, X)
+// GPB_ENUM_FWD_DECLARE is used for forward declaring enums, ex:
 //   GPB_ENUM_FWD_DECLARE(Foo_Enum)
 //   @property (nonatomic) Foo_Enum value;
-#define GPB_ENUM_FWD_DECLARE(_name) enum _name : int32_t
+#define GPB_ENUM_FWD_DECLARE(X) enum X : int32_t
 
 // Based upon CF_INLINE. Forces inlining in release.
 #if !defined(DEBUG)

+ 5 - 3
objectivec/GPBCodedInputStream.h

@@ -66,7 +66,9 @@
 - (void)readMessage:(GPBMessage *)message
     extensionRegistry:(GPBExtensionRegistry *)extensionRegistry;
 
-// Reads and discards a single field, given its tag value.
+// Reads and discards a single field, given its tag value. Returns NO if the
+// tag is an endgroup tag, in which case nothing is skipped.  Otherwise,
+// returns YES.
 - (BOOL)skipField:(int32_t)tag;
 
 // Reads and discards an entire message.  This will read either until EOF
@@ -74,8 +76,8 @@
 - (void)skipMessage;
 
 // Verifies that the last call to readTag() returned the given tag value.
-// This is used to verify that a nested group ended with the correct
-// end tag.
+// This is used to verify that a nested group ended with the correct end tag.
+// Throws NSParseErrorException if value does not match the last tag.
 - (void)checkLastTagWas:(int32_t)value;
 
 @end

+ 0 - 3
objectivec/GPBDescriptor.h

@@ -56,7 +56,6 @@ typedef NS_ENUM(NSInteger, GPBFieldType) {
 @property(nonatomic, readonly, strong) NSArray *fields;
 @property(nonatomic, readonly, strong) NSArray *oneofs;
 @property(nonatomic, readonly, strong) NSArray *enums;
-@property(nonatomic, readonly, strong) NSArray *extensions;
 @property(nonatomic, readonly) const GPBExtensionRange *extensionRanges;
 @property(nonatomic, readonly) NSUInteger extensionRangesCount;
 @property(nonatomic, readonly, assign) GPBFileDescriptor *file;
@@ -68,8 +67,6 @@ typedef NS_ENUM(NSInteger, GPBFieldType) {
 - (GPBFieldDescriptor *)fieldWithName:(NSString *)name;
 - (GPBOneofDescriptor *)oneofWithName:(NSString *)name;
 - (GPBEnumDescriptor *)enumWithName:(NSString *)name;
-- (GPBFieldDescriptor *)extensionWithNumber:(uint32_t)fieldNumber;
-- (GPBFieldDescriptor *)extensionWithName:(NSString *)name;
 
 @end
 

+ 6 - 30
objectivec/GPBDescriptor.m

@@ -93,7 +93,6 @@ static NSArray *NewFieldsArrayForHasIndex(int hasIndex,
 @implementation GPBDescriptor {
   Class messageClass_;
   NSArray *enums_;
-  NSArray *extensions_;
   GPBFileDescriptor *file_;
   BOOL wireFormat_;
 }
@@ -102,7 +101,6 @@ static NSArray *NewFieldsArrayForHasIndex(int hasIndex,
 @synthesize fields = fields_;
 @synthesize oneofs = oneofs_;
 @synthesize enums = enums_;
-@synthesize extensions = extensions_;
 @synthesize extensionRanges = extensionRanges_;
 @synthesize extensionRangesCount = extensionRangesCount_;
 @synthesize file = file_;
@@ -161,13 +159,11 @@ static NSArray *NewFieldsArrayForHasIndex(int hasIndex,
     [enums addObject:enumDescriptor];
   }
 
-  // TODO(dmaclach): Add support for extensions
   GPBDescriptor *descriptor = [[self alloc] initWithClass:messageClass
                                                      file:file
                                                    fields:fields
                                                    oneofs:oneofs
                                                     enums:enums
-                                               extensions:nil
                                           extensionRanges:ranges
                                      extensionRangesCount:rangeCount
                                               storageSize:storageSize
@@ -226,7 +222,6 @@ static NSArray *NewFieldsArrayForHasIndex(int hasIndex,
                        fields:(NSArray *)fields
                        oneofs:(NSArray *)oneofs
                         enums:(NSArray *)enums
-                   extensions:(NSArray *)extensions
               extensionRanges:(const GPBExtensionRange *)extensionRanges
          extensionRangesCount:(NSUInteger)extensionRangesCount
                   storageSize:(size_t)storageSize
@@ -237,7 +232,6 @@ static NSArray *NewFieldsArrayForHasIndex(int hasIndex,
     fields_ = [fields retain];
     oneofs_ = [oneofs retain];
     enums_ = [enums retain];
-    extensions_ = [extensions retain];
     extensionRanges_ = extensionRanges;
     extensionRangesCount_ = extensionRangesCount;
     storageSize_ = storageSize;
@@ -250,7 +244,6 @@ static NSArray *NewFieldsArrayForHasIndex(int hasIndex,
   [fields_ release];
   [oneofs_ release];
   [enums_ release];
-  [extensions_ release];
   [super dealloc];
 }
 
@@ -299,24 +292,6 @@ static NSArray *NewFieldsArrayForHasIndex(int hasIndex,
   return nil;
 }
 
-- (GPBFieldDescriptor *)extensionWithNumber:(uint32_t)fieldNumber {
-  for (GPBFieldDescriptor *descriptor in extensions_) {
-    if (GPBFieldNumber(descriptor) == fieldNumber) {
-      return descriptor;
-    }
-  }
-  return nil;
-}
-
-- (GPBFieldDescriptor *)extensionWithName:(NSString *)name {
-  for (GPBFieldDescriptor *descriptor in extensions_) {
-    if ([descriptor.name isEqual:name]) {
-      return descriptor;
-    }
-  }
-  return nil;
-}
-
 @end
 
 @implementation GPBFileDescriptor {
@@ -366,7 +341,7 @@ static NSArray *NewFieldsArrayForHasIndex(int hasIndex,
 }
 
 - (NSString *)name {
-  return [NSString stringWithUTF8String:oneofDescription_->name];
+  return @(oneofDescription_->name);
 }
 
 - (GPBFieldDescriptor *)fieldWithNumber:(uint32_t)fieldNumber {
@@ -455,7 +430,8 @@ uint32_t GPBFieldTag(GPBFieldDescriptor *self) {
                                              freeWhenDone:NO];
         GPBExtensionRegistry *registry = [rootClass extensionRegistry];
         fieldOptions_ = [[GPBFieldOptions parseFromData:optionsData
-                                      extensionRegistry:registry] retain];
+                                      extensionRegistry:registry
+                                                  error:NULL] retain];
       }
     }
 
@@ -532,7 +508,7 @@ uint32_t GPBFieldTag(GPBFieldDescriptor *self) {
 }
 
 - (NSString *)name {
-  return [NSString stringWithUTF8String:description_->name];
+  return @(description_->name);
 }
 
 - (BOOL)isRequired {
@@ -809,7 +785,7 @@ uint32_t GPBFieldTag(GPBFieldDescriptor *self) {
 
   NSString *result = nil;
   // Naming adds an underscore between enum name and value name, skip that also.
-  NSString *shortName = [NSString stringWithUTF8String:valueDescriptor->name];
+  NSString *shortName = @(valueDescriptor->name);
 
   // See if it is in the map of special format handling.
   if (extraTextFormatInfo_) {
@@ -846,7 +822,7 @@ uint32_t GPBFieldTag(GPBFieldDescriptor *self) {
 }
 
 - (NSString *)singletonName {
-  return [NSString stringWithUTF8String:description_->singletonName];
+  return @(description_->singletonName);
 }
 
 - (const char *)singletonNameC {

+ 0 - 1
objectivec/GPBDescriptor_PackagePrivate.h

@@ -186,7 +186,6 @@ typedef struct GPBExtensionDescription {
                        fields:(NSArray *)fields
                        oneofs:(NSArray *)oneofs
                         enums:(NSArray *)enums
-                   extensions:(NSArray *)extensions
               extensionRanges:(const GPBExtensionRange *)ranges
          extensionRangesCount:(NSUInteger)rangeCount
                   storageSize:(size_t)storage

Dosya farkı çok büyük olduğundan ihmal edildi
+ 288 - 52
objectivec/GPBDictionary.m


+ 234 - 324
objectivec/GPBDictionary_PackagePrivate.h

@@ -37,6 +37,14 @@
 @class GPBExtensionRegistry;
 @class GPBFieldDescriptor;
 
+@protocol GPBDictionaryInternalsProtocol
+- (size_t)computeSerializedSizeAsField:(GPBFieldDescriptor *)field;
+- (void)writeToCodedOutputStream:(GPBCodedOutputStream *)outputStream
+                         asField:(GPBFieldDescriptor *)field;
+- (void)setGPBValue:(GPBValue *)value forGPBValueKey:(GPBValue *)key;
+- (void)enumerateForTextFormat:(void (^)(id keyObj, id valueObj))block;
+@end
+
 //%PDDM-DEFINE DICTIONARY_PRIV_INTERFACES_FOR_POD_KEY(KEY_NAME)
 //%DICTIONARY_POD_PRIV_INTERFACES_FOR_KEY(KEY_NAME)
 //%DICTIONARY_PRIVATE_INTERFACES(KEY_NAME, Object, Object)
@@ -51,12 +59,10 @@
 //%DICTIONARY_PRIVATE_INTERFACES(KEY_NAME, Enum, Enum)
 
 //%PDDM-DEFINE DICTIONARY_PRIVATE_INTERFACES(KEY_NAME, VALUE_NAME, HELPER)
-//%@interface GPB##KEY_NAME##VALUE_NAME##Dictionary ()
-//%- (size_t)computeSerializedSizeAsField:(GPBFieldDescriptor *)field;
-//%- (void)writeToCodedOutputStream:(GPBCodedOutputStream *)outputStream
-//%                         asField:(GPBFieldDescriptor *)field;
-//%- (void)setGPBValue:(GPBValue *)value forGPBValueKey:(GPBValue *)key;
-//%- (void)enumerateForTextFormat:(void (^)(id keyObj, id valueObj))block;
+//%@interface GPB##KEY_NAME##VALUE_NAME##Dictionary () <GPBDictionaryInternalsProtocol> {
+//% @package
+//%  GPB_UNSAFE_UNRETAINED GPBMessage *_autocreator;
+//%}
 //%EXTRA_DICTIONARY_PRIVATE_INTERFACES_##HELPER()@end
 //%
 
@@ -76,79 +82,61 @@
 //%PDDM-EXPAND DICTIONARY_PRIV_INTERFACES_FOR_POD_KEY(UInt32)
 // This block of code is generated, do not edit it directly.
 
-@interface GPBUInt32UInt32Dictionary ()
-- (size_t)computeSerializedSizeAsField:(GPBFieldDescriptor *)field;
-- (void)writeToCodedOutputStream:(GPBCodedOutputStream *)outputStream
-                         asField:(GPBFieldDescriptor *)field;
-- (void)setGPBValue:(GPBValue *)value forGPBValueKey:(GPBValue *)key;
-- (void)enumerateForTextFormat:(void (^)(id keyObj, id valueObj))block;
+@interface GPBUInt32UInt32Dictionary () <GPBDictionaryInternalsProtocol> {
+ @package
+  GPB_UNSAFE_UNRETAINED GPBMessage *_autocreator;
+}
 @end
 
-@interface GPBUInt32Int32Dictionary ()
-- (size_t)computeSerializedSizeAsField:(GPBFieldDescriptor *)field;
-- (void)writeToCodedOutputStream:(GPBCodedOutputStream *)outputStream
-                         asField:(GPBFieldDescriptor *)field;
-- (void)setGPBValue:(GPBValue *)value forGPBValueKey:(GPBValue *)key;
-- (void)enumerateForTextFormat:(void (^)(id keyObj, id valueObj))block;
+@interface GPBUInt32Int32Dictionary () <GPBDictionaryInternalsProtocol> {
+ @package
+  GPB_UNSAFE_UNRETAINED GPBMessage *_autocreator;
+}
 @end
 
-@interface GPBUInt32UInt64Dictionary ()
-- (size_t)computeSerializedSizeAsField:(GPBFieldDescriptor *)field;
-- (void)writeToCodedOutputStream:(GPBCodedOutputStream *)outputStream
-                         asField:(GPBFieldDescriptor *)field;
-- (void)setGPBValue:(GPBValue *)value forGPBValueKey:(GPBValue *)key;
-- (void)enumerateForTextFormat:(void (^)(id keyObj, id valueObj))block;
+@interface GPBUInt32UInt64Dictionary () <GPBDictionaryInternalsProtocol> {
+ @package
+  GPB_UNSAFE_UNRETAINED GPBMessage *_autocreator;
+}
 @end
 
-@interface GPBUInt32Int64Dictionary ()
-- (size_t)computeSerializedSizeAsField:(GPBFieldDescriptor *)field;
-- (void)writeToCodedOutputStream:(GPBCodedOutputStream *)outputStream
-                         asField:(GPBFieldDescriptor *)field;
-- (void)setGPBValue:(GPBValue *)value forGPBValueKey:(GPBValue *)key;
-- (void)enumerateForTextFormat:(void (^)(id keyObj, id valueObj))block;
+@interface GPBUInt32Int64Dictionary () <GPBDictionaryInternalsProtocol> {
+ @package
+  GPB_UNSAFE_UNRETAINED GPBMessage *_autocreator;
+}
 @end
 
-@interface GPBUInt32BoolDictionary ()
-- (size_t)computeSerializedSizeAsField:(GPBFieldDescriptor *)field;
-- (void)writeToCodedOutputStream:(GPBCodedOutputStream *)outputStream
-                         asField:(GPBFieldDescriptor *)field;
-- (void)setGPBValue:(GPBValue *)value forGPBValueKey:(GPBValue *)key;
-- (void)enumerateForTextFormat:(void (^)(id keyObj, id valueObj))block;
+@interface GPBUInt32BoolDictionary () <GPBDictionaryInternalsProtocol> {
+ @package
+  GPB_UNSAFE_UNRETAINED GPBMessage *_autocreator;
+}
 @end
 
-@interface GPBUInt32FloatDictionary ()
-- (size_t)computeSerializedSizeAsField:(GPBFieldDescriptor *)field;
-- (void)writeToCodedOutputStream:(GPBCodedOutputStream *)outputStream
-                         asField:(GPBFieldDescriptor *)field;
-- (void)setGPBValue:(GPBValue *)value forGPBValueKey:(GPBValue *)key;
-- (void)enumerateForTextFormat:(void (^)(id keyObj, id valueObj))block;
+@interface GPBUInt32FloatDictionary () <GPBDictionaryInternalsProtocol> {
+ @package
+  GPB_UNSAFE_UNRETAINED GPBMessage *_autocreator;
+}
 @end
 
-@interface GPBUInt32DoubleDictionary ()
-- (size_t)computeSerializedSizeAsField:(GPBFieldDescriptor *)field;
-- (void)writeToCodedOutputStream:(GPBCodedOutputStream *)outputStream
-                         asField:(GPBFieldDescriptor *)field;
-- (void)setGPBValue:(GPBValue *)value forGPBValueKey:(GPBValue *)key;
-- (void)enumerateForTextFormat:(void (^)(id keyObj, id valueObj))block;
+@interface GPBUInt32DoubleDictionary () <GPBDictionaryInternalsProtocol> {
+ @package
+  GPB_UNSAFE_UNRETAINED GPBMessage *_autocreator;
+}
 @end
 
-@interface GPBUInt32EnumDictionary ()
-- (size_t)computeSerializedSizeAsField:(GPBFieldDescriptor *)field;
-- (void)writeToCodedOutputStream:(GPBCodedOutputStream *)outputStream
-                         asField:(GPBFieldDescriptor *)field;
-- (void)setGPBValue:(GPBValue *)value forGPBValueKey:(GPBValue *)key;
-- (void)enumerateForTextFormat:(void (^)(id keyObj, id valueObj))block;
+@interface GPBUInt32EnumDictionary () <GPBDictionaryInternalsProtocol> {
+ @package
+  GPB_UNSAFE_UNRETAINED GPBMessage *_autocreator;
+}
 - (NSData *)serializedDataForUnknownValue:(int32_t)value
                                    forKey:(GPBValue *)key
                                   keyType:(GPBType)keyType;
 @end
 
-@interface GPBUInt32ObjectDictionary ()
-- (size_t)computeSerializedSizeAsField:(GPBFieldDescriptor *)field;
-- (void)writeToCodedOutputStream:(GPBCodedOutputStream *)outputStream
-                         asField:(GPBFieldDescriptor *)field;
-- (void)setGPBValue:(GPBValue *)value forGPBValueKey:(GPBValue *)key;
-- (void)enumerateForTextFormat:(void (^)(id keyObj, id valueObj))block;
+@interface GPBUInt32ObjectDictionary () <GPBDictionaryInternalsProtocol> {
+ @package
+  GPB_UNSAFE_UNRETAINED GPBMessage *_autocreator;
+}
 - (BOOL)isInitialized;
 - (instancetype)deepCopyWithZone:(NSZone *)zone
     __attribute__((ns_returns_retained));
@@ -157,79 +145,61 @@
 //%PDDM-EXPAND DICTIONARY_PRIV_INTERFACES_FOR_POD_KEY(Int32)
 // This block of code is generated, do not edit it directly.
 
-@interface GPBInt32UInt32Dictionary ()
-- (size_t)computeSerializedSizeAsField:(GPBFieldDescriptor *)field;
-- (void)writeToCodedOutputStream:(GPBCodedOutputStream *)outputStream
-                         asField:(GPBFieldDescriptor *)field;
-- (void)setGPBValue:(GPBValue *)value forGPBValueKey:(GPBValue *)key;
-- (void)enumerateForTextFormat:(void (^)(id keyObj, id valueObj))block;
+@interface GPBInt32UInt32Dictionary () <GPBDictionaryInternalsProtocol> {
+ @package
+  GPB_UNSAFE_UNRETAINED GPBMessage *_autocreator;
+}
 @end
 
-@interface GPBInt32Int32Dictionary ()
-- (size_t)computeSerializedSizeAsField:(GPBFieldDescriptor *)field;
-- (void)writeToCodedOutputStream:(GPBCodedOutputStream *)outputStream
-                         asField:(GPBFieldDescriptor *)field;
-- (void)setGPBValue:(GPBValue *)value forGPBValueKey:(GPBValue *)key;
-- (void)enumerateForTextFormat:(void (^)(id keyObj, id valueObj))block;
+@interface GPBInt32Int32Dictionary () <GPBDictionaryInternalsProtocol> {
+ @package
+  GPB_UNSAFE_UNRETAINED GPBMessage *_autocreator;
+}
 @end
 
-@interface GPBInt32UInt64Dictionary ()
-- (size_t)computeSerializedSizeAsField:(GPBFieldDescriptor *)field;
-- (void)writeToCodedOutputStream:(GPBCodedOutputStream *)outputStream
-                         asField:(GPBFieldDescriptor *)field;
-- (void)setGPBValue:(GPBValue *)value forGPBValueKey:(GPBValue *)key;
-- (void)enumerateForTextFormat:(void (^)(id keyObj, id valueObj))block;
+@interface GPBInt32UInt64Dictionary () <GPBDictionaryInternalsProtocol> {
+ @package
+  GPB_UNSAFE_UNRETAINED GPBMessage *_autocreator;
+}
 @end
 
-@interface GPBInt32Int64Dictionary ()
-- (size_t)computeSerializedSizeAsField:(GPBFieldDescriptor *)field;
-- (void)writeToCodedOutputStream:(GPBCodedOutputStream *)outputStream
-                         asField:(GPBFieldDescriptor *)field;
-- (void)setGPBValue:(GPBValue *)value forGPBValueKey:(GPBValue *)key;
-- (void)enumerateForTextFormat:(void (^)(id keyObj, id valueObj))block;
+@interface GPBInt32Int64Dictionary () <GPBDictionaryInternalsProtocol> {
+ @package
+  GPB_UNSAFE_UNRETAINED GPBMessage *_autocreator;
+}
 @end
 
-@interface GPBInt32BoolDictionary ()
-- (size_t)computeSerializedSizeAsField:(GPBFieldDescriptor *)field;
-- (void)writeToCodedOutputStream:(GPBCodedOutputStream *)outputStream
-                         asField:(GPBFieldDescriptor *)field;
-- (void)setGPBValue:(GPBValue *)value forGPBValueKey:(GPBValue *)key;
-- (void)enumerateForTextFormat:(void (^)(id keyObj, id valueObj))block;
+@interface GPBInt32BoolDictionary () <GPBDictionaryInternalsProtocol> {
+ @package
+  GPB_UNSAFE_UNRETAINED GPBMessage *_autocreator;
+}
 @end
 
-@interface GPBInt32FloatDictionary ()
-- (size_t)computeSerializedSizeAsField:(GPBFieldDescriptor *)field;
-- (void)writeToCodedOutputStream:(GPBCodedOutputStream *)outputStream
-                         asField:(GPBFieldDescriptor *)field;
-- (void)setGPBValue:(GPBValue *)value forGPBValueKey:(GPBValue *)key;
-- (void)enumerateForTextFormat:(void (^)(id keyObj, id valueObj))block;
+@interface GPBInt32FloatDictionary () <GPBDictionaryInternalsProtocol> {
+ @package
+  GPB_UNSAFE_UNRETAINED GPBMessage *_autocreator;
+}
 @end
 
-@interface GPBInt32DoubleDictionary ()
-- (size_t)computeSerializedSizeAsField:(GPBFieldDescriptor *)field;
-- (void)writeToCodedOutputStream:(GPBCodedOutputStream *)outputStream
-                         asField:(GPBFieldDescriptor *)field;
-- (void)setGPBValue:(GPBValue *)value forGPBValueKey:(GPBValue *)key;
-- (void)enumerateForTextFormat:(void (^)(id keyObj, id valueObj))block;
+@interface GPBInt32DoubleDictionary () <GPBDictionaryInternalsProtocol> {
+ @package
+  GPB_UNSAFE_UNRETAINED GPBMessage *_autocreator;
+}
 @end
 
-@interface GPBInt32EnumDictionary ()
-- (size_t)computeSerializedSizeAsField:(GPBFieldDescriptor *)field;
-- (void)writeToCodedOutputStream:(GPBCodedOutputStream *)outputStream
-                         asField:(GPBFieldDescriptor *)field;
-- (void)setGPBValue:(GPBValue *)value forGPBValueKey:(GPBValue *)key;
-- (void)enumerateForTextFormat:(void (^)(id keyObj, id valueObj))block;
+@interface GPBInt32EnumDictionary () <GPBDictionaryInternalsProtocol> {
+ @package
+  GPB_UNSAFE_UNRETAINED GPBMessage *_autocreator;
+}
 - (NSData *)serializedDataForUnknownValue:(int32_t)value
                                    forKey:(GPBValue *)key
                                   keyType:(GPBType)keyType;
 @end
 
-@interface GPBInt32ObjectDictionary ()
-- (size_t)computeSerializedSizeAsField:(GPBFieldDescriptor *)field;
-- (void)writeToCodedOutputStream:(GPBCodedOutputStream *)outputStream
-                         asField:(GPBFieldDescriptor *)field;
-- (void)setGPBValue:(GPBValue *)value forGPBValueKey:(GPBValue *)key;
-- (void)enumerateForTextFormat:(void (^)(id keyObj, id valueObj))block;
+@interface GPBInt32ObjectDictionary () <GPBDictionaryInternalsProtocol> {
+ @package
+  GPB_UNSAFE_UNRETAINED GPBMessage *_autocreator;
+}
 - (BOOL)isInitialized;
 - (instancetype)deepCopyWithZone:(NSZone *)zone
     __attribute__((ns_returns_retained));
@@ -238,79 +208,61 @@
 //%PDDM-EXPAND DICTIONARY_PRIV_INTERFACES_FOR_POD_KEY(UInt64)
 // This block of code is generated, do not edit it directly.
 
-@interface GPBUInt64UInt32Dictionary ()
-- (size_t)computeSerializedSizeAsField:(GPBFieldDescriptor *)field;
-- (void)writeToCodedOutputStream:(GPBCodedOutputStream *)outputStream
-                         asField:(GPBFieldDescriptor *)field;
-- (void)setGPBValue:(GPBValue *)value forGPBValueKey:(GPBValue *)key;
-- (void)enumerateForTextFormat:(void (^)(id keyObj, id valueObj))block;
+@interface GPBUInt64UInt32Dictionary () <GPBDictionaryInternalsProtocol> {
+ @package
+  GPB_UNSAFE_UNRETAINED GPBMessage *_autocreator;
+}
 @end
 
-@interface GPBUInt64Int32Dictionary ()
-- (size_t)computeSerializedSizeAsField:(GPBFieldDescriptor *)field;
-- (void)writeToCodedOutputStream:(GPBCodedOutputStream *)outputStream
-                         asField:(GPBFieldDescriptor *)field;
-- (void)setGPBValue:(GPBValue *)value forGPBValueKey:(GPBValue *)key;
-- (void)enumerateForTextFormat:(void (^)(id keyObj, id valueObj))block;
+@interface GPBUInt64Int32Dictionary () <GPBDictionaryInternalsProtocol> {
+ @package
+  GPB_UNSAFE_UNRETAINED GPBMessage *_autocreator;
+}
 @end
 
-@interface GPBUInt64UInt64Dictionary ()
-- (size_t)computeSerializedSizeAsField:(GPBFieldDescriptor *)field;
-- (void)writeToCodedOutputStream:(GPBCodedOutputStream *)outputStream
-                         asField:(GPBFieldDescriptor *)field;
-- (void)setGPBValue:(GPBValue *)value forGPBValueKey:(GPBValue *)key;
-- (void)enumerateForTextFormat:(void (^)(id keyObj, id valueObj))block;
+@interface GPBUInt64UInt64Dictionary () <GPBDictionaryInternalsProtocol> {
+ @package
+  GPB_UNSAFE_UNRETAINED GPBMessage *_autocreator;
+}
 @end
 
-@interface GPBUInt64Int64Dictionary ()
-- (size_t)computeSerializedSizeAsField:(GPBFieldDescriptor *)field;
-- (void)writeToCodedOutputStream:(GPBCodedOutputStream *)outputStream
-                         asField:(GPBFieldDescriptor *)field;
-- (void)setGPBValue:(GPBValue *)value forGPBValueKey:(GPBValue *)key;
-- (void)enumerateForTextFormat:(void (^)(id keyObj, id valueObj))block;
+@interface GPBUInt64Int64Dictionary () <GPBDictionaryInternalsProtocol> {
+ @package
+  GPB_UNSAFE_UNRETAINED GPBMessage *_autocreator;
+}
 @end
 
-@interface GPBUInt64BoolDictionary ()
-- (size_t)computeSerializedSizeAsField:(GPBFieldDescriptor *)field;
-- (void)writeToCodedOutputStream:(GPBCodedOutputStream *)outputStream
-                         asField:(GPBFieldDescriptor *)field;
-- (void)setGPBValue:(GPBValue *)value forGPBValueKey:(GPBValue *)key;
-- (void)enumerateForTextFormat:(void (^)(id keyObj, id valueObj))block;
+@interface GPBUInt64BoolDictionary () <GPBDictionaryInternalsProtocol> {
+ @package
+  GPB_UNSAFE_UNRETAINED GPBMessage *_autocreator;
+}
 @end
 
-@interface GPBUInt64FloatDictionary ()
-- (size_t)computeSerializedSizeAsField:(GPBFieldDescriptor *)field;
-- (void)writeToCodedOutputStream:(GPBCodedOutputStream *)outputStream
-                         asField:(GPBFieldDescriptor *)field;
-- (void)setGPBValue:(GPBValue *)value forGPBValueKey:(GPBValue *)key;
-- (void)enumerateForTextFormat:(void (^)(id keyObj, id valueObj))block;
+@interface GPBUInt64FloatDictionary () <GPBDictionaryInternalsProtocol> {
+ @package
+  GPB_UNSAFE_UNRETAINED GPBMessage *_autocreator;
+}
 @end
 
-@interface GPBUInt64DoubleDictionary ()
-- (size_t)computeSerializedSizeAsField:(GPBFieldDescriptor *)field;
-- (void)writeToCodedOutputStream:(GPBCodedOutputStream *)outputStream
-                         asField:(GPBFieldDescriptor *)field;
-- (void)setGPBValue:(GPBValue *)value forGPBValueKey:(GPBValue *)key;
-- (void)enumerateForTextFormat:(void (^)(id keyObj, id valueObj))block;
+@interface GPBUInt64DoubleDictionary () <GPBDictionaryInternalsProtocol> {
+ @package
+  GPB_UNSAFE_UNRETAINED GPBMessage *_autocreator;
+}
 @end
 
-@interface GPBUInt64EnumDictionary ()
-- (size_t)computeSerializedSizeAsField:(GPBFieldDescriptor *)field;
-- (void)writeToCodedOutputStream:(GPBCodedOutputStream *)outputStream
-                         asField:(GPBFieldDescriptor *)field;
-- (void)setGPBValue:(GPBValue *)value forGPBValueKey:(GPBValue *)key;
-- (void)enumerateForTextFormat:(void (^)(id keyObj, id valueObj))block;
+@interface GPBUInt64EnumDictionary () <GPBDictionaryInternalsProtocol> {
+ @package
+  GPB_UNSAFE_UNRETAINED GPBMessage *_autocreator;
+}
 - (NSData *)serializedDataForUnknownValue:(int32_t)value
                                    forKey:(GPBValue *)key
                                   keyType:(GPBType)keyType;
 @end
 
-@interface GPBUInt64ObjectDictionary ()
-- (size_t)computeSerializedSizeAsField:(GPBFieldDescriptor *)field;
-- (void)writeToCodedOutputStream:(GPBCodedOutputStream *)outputStream
-                         asField:(GPBFieldDescriptor *)field;
-- (void)setGPBValue:(GPBValue *)value forGPBValueKey:(GPBValue *)key;
-- (void)enumerateForTextFormat:(void (^)(id keyObj, id valueObj))block;
+@interface GPBUInt64ObjectDictionary () <GPBDictionaryInternalsProtocol> {
+ @package
+  GPB_UNSAFE_UNRETAINED GPBMessage *_autocreator;
+}
 - (BOOL)isInitialized;
 - (instancetype)deepCopyWithZone:(NSZone *)zone
     __attribute__((ns_returns_retained));
@@ -319,79 +271,61 @@
 //%PDDM-EXPAND DICTIONARY_PRIV_INTERFACES_FOR_POD_KEY(Int64)
 // This block of code is generated, do not edit it directly.
 
-@interface GPBInt64UInt32Dictionary ()
-- (size_t)computeSerializedSizeAsField:(GPBFieldDescriptor *)field;
-- (void)writeToCodedOutputStream:(GPBCodedOutputStream *)outputStream
-                         asField:(GPBFieldDescriptor *)field;
-- (void)setGPBValue:(GPBValue *)value forGPBValueKey:(GPBValue *)key;
-- (void)enumerateForTextFormat:(void (^)(id keyObj, id valueObj))block;
+@interface GPBInt64UInt32Dictionary () <GPBDictionaryInternalsProtocol> {
+ @package
+  GPB_UNSAFE_UNRETAINED GPBMessage *_autocreator;
+}
 @end
 
-@interface GPBInt64Int32Dictionary ()
-- (size_t)computeSerializedSizeAsField:(GPBFieldDescriptor *)field;
-- (void)writeToCodedOutputStream:(GPBCodedOutputStream *)outputStream
-                         asField:(GPBFieldDescriptor *)field;
-- (void)setGPBValue:(GPBValue *)value forGPBValueKey:(GPBValue *)key;
-- (void)enumerateForTextFormat:(void (^)(id keyObj, id valueObj))block;
+@interface GPBInt64Int32Dictionary () <GPBDictionaryInternalsProtocol> {
+ @package
+  GPB_UNSAFE_UNRETAINED GPBMessage *_autocreator;
+}
 @end
 
-@interface GPBInt64UInt64Dictionary ()
-- (size_t)computeSerializedSizeAsField:(GPBFieldDescriptor *)field;
-- (void)writeToCodedOutputStream:(GPBCodedOutputStream *)outputStream
-                         asField:(GPBFieldDescriptor *)field;
-- (void)setGPBValue:(GPBValue *)value forGPBValueKey:(GPBValue *)key;
-- (void)enumerateForTextFormat:(void (^)(id keyObj, id valueObj))block;
+@interface GPBInt64UInt64Dictionary () <GPBDictionaryInternalsProtocol> {
+ @package
+  GPB_UNSAFE_UNRETAINED GPBMessage *_autocreator;
+}
 @end
 
-@interface GPBInt64Int64Dictionary ()
-- (size_t)computeSerializedSizeAsField:(GPBFieldDescriptor *)field;
-- (void)writeToCodedOutputStream:(GPBCodedOutputStream *)outputStream
-                         asField:(GPBFieldDescriptor *)field;
-- (void)setGPBValue:(GPBValue *)value forGPBValueKey:(GPBValue *)key;
-- (void)enumerateForTextFormat:(void (^)(id keyObj, id valueObj))block;
+@interface GPBInt64Int64Dictionary () <GPBDictionaryInternalsProtocol> {
+ @package
+  GPB_UNSAFE_UNRETAINED GPBMessage *_autocreator;
+}
 @end
 
-@interface GPBInt64BoolDictionary ()
-- (size_t)computeSerializedSizeAsField:(GPBFieldDescriptor *)field;
-- (void)writeToCodedOutputStream:(GPBCodedOutputStream *)outputStream
-                         asField:(GPBFieldDescriptor *)field;
-- (void)setGPBValue:(GPBValue *)value forGPBValueKey:(GPBValue *)key;
-- (void)enumerateForTextFormat:(void (^)(id keyObj, id valueObj))block;
+@interface GPBInt64BoolDictionary () <GPBDictionaryInternalsProtocol> {
+ @package
+  GPB_UNSAFE_UNRETAINED GPBMessage *_autocreator;
+}
 @end
 
-@interface GPBInt64FloatDictionary ()
-- (size_t)computeSerializedSizeAsField:(GPBFieldDescriptor *)field;
-- (void)writeToCodedOutputStream:(GPBCodedOutputStream *)outputStream
-                         asField:(GPBFieldDescriptor *)field;
-- (void)setGPBValue:(GPBValue *)value forGPBValueKey:(GPBValue *)key;
-- (void)enumerateForTextFormat:(void (^)(id keyObj, id valueObj))block;
+@interface GPBInt64FloatDictionary () <GPBDictionaryInternalsProtocol> {
+ @package
+  GPB_UNSAFE_UNRETAINED GPBMessage *_autocreator;
+}
 @end
 
-@interface GPBInt64DoubleDictionary ()
-- (size_t)computeSerializedSizeAsField:(GPBFieldDescriptor *)field;
-- (void)writeToCodedOutputStream:(GPBCodedOutputStream *)outputStream
-                         asField:(GPBFieldDescriptor *)field;
-- (void)setGPBValue:(GPBValue *)value forGPBValueKey:(GPBValue *)key;
-- (void)enumerateForTextFormat:(void (^)(id keyObj, id valueObj))block;
+@interface GPBInt64DoubleDictionary () <GPBDictionaryInternalsProtocol> {
+ @package
+  GPB_UNSAFE_UNRETAINED GPBMessage *_autocreator;
+}
 @end
 
-@interface GPBInt64EnumDictionary ()
-- (size_t)computeSerializedSizeAsField:(GPBFieldDescriptor *)field;
-- (void)writeToCodedOutputStream:(GPBCodedOutputStream *)outputStream
-                         asField:(GPBFieldDescriptor *)field;
-- (void)setGPBValue:(GPBValue *)value forGPBValueKey:(GPBValue *)key;
-- (void)enumerateForTextFormat:(void (^)(id keyObj, id valueObj))block;
+@interface GPBInt64EnumDictionary () <GPBDictionaryInternalsProtocol> {
+ @package
+  GPB_UNSAFE_UNRETAINED GPBMessage *_autocreator;
+}
 - (NSData *)serializedDataForUnknownValue:(int32_t)value
                                    forKey:(GPBValue *)key
                                   keyType:(GPBType)keyType;
 @end
 
-@interface GPBInt64ObjectDictionary ()
-- (size_t)computeSerializedSizeAsField:(GPBFieldDescriptor *)field;
-- (void)writeToCodedOutputStream:(GPBCodedOutputStream *)outputStream
-                         asField:(GPBFieldDescriptor *)field;
-- (void)setGPBValue:(GPBValue *)value forGPBValueKey:(GPBValue *)key;
-- (void)enumerateForTextFormat:(void (^)(id keyObj, id valueObj))block;
+@interface GPBInt64ObjectDictionary () <GPBDictionaryInternalsProtocol> {
+ @package
+  GPB_UNSAFE_UNRETAINED GPBMessage *_autocreator;
+}
 - (BOOL)isInitialized;
 - (instancetype)deepCopyWithZone:(NSZone *)zone
     __attribute__((ns_returns_retained));
@@ -400,79 +334,61 @@
 //%PDDM-EXPAND DICTIONARY_PRIV_INTERFACES_FOR_POD_KEY(Bool)
 // This block of code is generated, do not edit it directly.
 
-@interface GPBBoolUInt32Dictionary ()
-- (size_t)computeSerializedSizeAsField:(GPBFieldDescriptor *)field;
-- (void)writeToCodedOutputStream:(GPBCodedOutputStream *)outputStream
-                         asField:(GPBFieldDescriptor *)field;
-- (void)setGPBValue:(GPBValue *)value forGPBValueKey:(GPBValue *)key;
-- (void)enumerateForTextFormat:(void (^)(id keyObj, id valueObj))block;
+@interface GPBBoolUInt32Dictionary () <GPBDictionaryInternalsProtocol> {
+ @package
+  GPB_UNSAFE_UNRETAINED GPBMessage *_autocreator;
+}
 @end
 
-@interface GPBBoolInt32Dictionary ()
-- (size_t)computeSerializedSizeAsField:(GPBFieldDescriptor *)field;
-- (void)writeToCodedOutputStream:(GPBCodedOutputStream *)outputStream
-                         asField:(GPBFieldDescriptor *)field;
-- (void)setGPBValue:(GPBValue *)value forGPBValueKey:(GPBValue *)key;
-- (void)enumerateForTextFormat:(void (^)(id keyObj, id valueObj))block;
+@interface GPBBoolInt32Dictionary () <GPBDictionaryInternalsProtocol> {
+ @package
+  GPB_UNSAFE_UNRETAINED GPBMessage *_autocreator;
+}
 @end
 
-@interface GPBBoolUInt64Dictionary ()
-- (size_t)computeSerializedSizeAsField:(GPBFieldDescriptor *)field;
-- (void)writeToCodedOutputStream:(GPBCodedOutputStream *)outputStream
-                         asField:(GPBFieldDescriptor *)field;
-- (void)setGPBValue:(GPBValue *)value forGPBValueKey:(GPBValue *)key;
-- (void)enumerateForTextFormat:(void (^)(id keyObj, id valueObj))block;
+@interface GPBBoolUInt64Dictionary () <GPBDictionaryInternalsProtocol> {
+ @package
+  GPB_UNSAFE_UNRETAINED GPBMessage *_autocreator;
+}
 @end
 
-@interface GPBBoolInt64Dictionary ()
-- (size_t)computeSerializedSizeAsField:(GPBFieldDescriptor *)field;
-- (void)writeToCodedOutputStream:(GPBCodedOutputStream *)outputStream
-                         asField:(GPBFieldDescriptor *)field;
-- (void)setGPBValue:(GPBValue *)value forGPBValueKey:(GPBValue *)key;
-- (void)enumerateForTextFormat:(void (^)(id keyObj, id valueObj))block;
+@interface GPBBoolInt64Dictionary () <GPBDictionaryInternalsProtocol> {
+ @package
+  GPB_UNSAFE_UNRETAINED GPBMessage *_autocreator;
+}
 @end
 
-@interface GPBBoolBoolDictionary ()
-- (size_t)computeSerializedSizeAsField:(GPBFieldDescriptor *)field;
-- (void)writeToCodedOutputStream:(GPBCodedOutputStream *)outputStream
-                         asField:(GPBFieldDescriptor *)field;
-- (void)setGPBValue:(GPBValue *)value forGPBValueKey:(GPBValue *)key;
-- (void)enumerateForTextFormat:(void (^)(id keyObj, id valueObj))block;
+@interface GPBBoolBoolDictionary () <GPBDictionaryInternalsProtocol> {
+ @package
+  GPB_UNSAFE_UNRETAINED GPBMessage *_autocreator;
+}
 @end
 
-@interface GPBBoolFloatDictionary ()
-- (size_t)computeSerializedSizeAsField:(GPBFieldDescriptor *)field;
-- (void)writeToCodedOutputStream:(GPBCodedOutputStream *)outputStream
-                         asField:(GPBFieldDescriptor *)field;
-- (void)setGPBValue:(GPBValue *)value forGPBValueKey:(GPBValue *)key;
-- (void)enumerateForTextFormat:(void (^)(id keyObj, id valueObj))block;
+@interface GPBBoolFloatDictionary () <GPBDictionaryInternalsProtocol> {
+ @package
+  GPB_UNSAFE_UNRETAINED GPBMessage *_autocreator;
+}
 @end
 
-@interface GPBBoolDoubleDictionary ()
-- (size_t)computeSerializedSizeAsField:(GPBFieldDescriptor *)field;
-- (void)writeToCodedOutputStream:(GPBCodedOutputStream *)outputStream
-                         asField:(GPBFieldDescriptor *)field;
-- (void)setGPBValue:(GPBValue *)value forGPBValueKey:(GPBValue *)key;
-- (void)enumerateForTextFormat:(void (^)(id keyObj, id valueObj))block;
+@interface GPBBoolDoubleDictionary () <GPBDictionaryInternalsProtocol> {
+ @package
+  GPB_UNSAFE_UNRETAINED GPBMessage *_autocreator;
+}
 @end
 
-@interface GPBBoolEnumDictionary ()
-- (size_t)computeSerializedSizeAsField:(GPBFieldDescriptor *)field;
-- (void)writeToCodedOutputStream:(GPBCodedOutputStream *)outputStream
-                         asField:(GPBFieldDescriptor *)field;
-- (void)setGPBValue:(GPBValue *)value forGPBValueKey:(GPBValue *)key;
-- (void)enumerateForTextFormat:(void (^)(id keyObj, id valueObj))block;
+@interface GPBBoolEnumDictionary () <GPBDictionaryInternalsProtocol> {
+ @package
+  GPB_UNSAFE_UNRETAINED GPBMessage *_autocreator;
+}
 - (NSData *)serializedDataForUnknownValue:(int32_t)value
                                    forKey:(GPBValue *)key
                                   keyType:(GPBType)keyType;
 @end
 
-@interface GPBBoolObjectDictionary ()
-- (size_t)computeSerializedSizeAsField:(GPBFieldDescriptor *)field;
-- (void)writeToCodedOutputStream:(GPBCodedOutputStream *)outputStream
-                         asField:(GPBFieldDescriptor *)field;
-- (void)setGPBValue:(GPBValue *)value forGPBValueKey:(GPBValue *)key;
-- (void)enumerateForTextFormat:(void (^)(id keyObj, id valueObj))block;
+@interface GPBBoolObjectDictionary () <GPBDictionaryInternalsProtocol> {
+ @package
+  GPB_UNSAFE_UNRETAINED GPBMessage *_autocreator;
+}
 - (BOOL)isInitialized;
 - (instancetype)deepCopyWithZone:(NSZone *)zone
     __attribute__((ns_returns_retained));
@@ -481,68 +397,52 @@
 //%PDDM-EXPAND DICTIONARY_POD_PRIV_INTERFACES_FOR_KEY(String)
 // This block of code is generated, do not edit it directly.
 
-@interface GPBStringUInt32Dictionary ()
-- (size_t)computeSerializedSizeAsField:(GPBFieldDescriptor *)field;
-- (void)writeToCodedOutputStream:(GPBCodedOutputStream *)outputStream
-                         asField:(GPBFieldDescriptor *)field;
-- (void)setGPBValue:(GPBValue *)value forGPBValueKey:(GPBValue *)key;
-- (void)enumerateForTextFormat:(void (^)(id keyObj, id valueObj))block;
+@interface GPBStringUInt32Dictionary () <GPBDictionaryInternalsProtocol> {
+ @package
+  GPB_UNSAFE_UNRETAINED GPBMessage *_autocreator;
+}
 @end
 
-@interface GPBStringInt32Dictionary ()
-- (size_t)computeSerializedSizeAsField:(GPBFieldDescriptor *)field;
-- (void)writeToCodedOutputStream:(GPBCodedOutputStream *)outputStream
-                         asField:(GPBFieldDescriptor *)field;
-- (void)setGPBValue:(GPBValue *)value forGPBValueKey:(GPBValue *)key;
-- (void)enumerateForTextFormat:(void (^)(id keyObj, id valueObj))block;
+@interface GPBStringInt32Dictionary () <GPBDictionaryInternalsProtocol> {
+ @package
+  GPB_UNSAFE_UNRETAINED GPBMessage *_autocreator;
+}
 @end
 
-@interface GPBStringUInt64Dictionary ()
-- (size_t)computeSerializedSizeAsField:(GPBFieldDescriptor *)field;
-- (void)writeToCodedOutputStream:(GPBCodedOutputStream *)outputStream
-                         asField:(GPBFieldDescriptor *)field;
-- (void)setGPBValue:(GPBValue *)value forGPBValueKey:(GPBValue *)key;
-- (void)enumerateForTextFormat:(void (^)(id keyObj, id valueObj))block;
+@interface GPBStringUInt64Dictionary () <GPBDictionaryInternalsProtocol> {
+ @package
+  GPB_UNSAFE_UNRETAINED GPBMessage *_autocreator;
+}
 @end
 
-@interface GPBStringInt64Dictionary ()
-- (size_t)computeSerializedSizeAsField:(GPBFieldDescriptor *)field;
-- (void)writeToCodedOutputStream:(GPBCodedOutputStream *)outputStream
-                         asField:(GPBFieldDescriptor *)field;
-- (void)setGPBValue:(GPBValue *)value forGPBValueKey:(GPBValue *)key;
-- (void)enumerateForTextFormat:(void (^)(id keyObj, id valueObj))block;
+@interface GPBStringInt64Dictionary () <GPBDictionaryInternalsProtocol> {
+ @package
+  GPB_UNSAFE_UNRETAINED GPBMessage *_autocreator;
+}
 @end
 
-@interface GPBStringBoolDictionary ()
-- (size_t)computeSerializedSizeAsField:(GPBFieldDescriptor *)field;
-- (void)writeToCodedOutputStream:(GPBCodedOutputStream *)outputStream
-                         asField:(GPBFieldDescriptor *)field;
-- (void)setGPBValue:(GPBValue *)value forGPBValueKey:(GPBValue *)key;
-- (void)enumerateForTextFormat:(void (^)(id keyObj, id valueObj))block;
+@interface GPBStringBoolDictionary () <GPBDictionaryInternalsProtocol> {
+ @package
+  GPB_UNSAFE_UNRETAINED GPBMessage *_autocreator;
+}
 @end
 
-@interface GPBStringFloatDictionary ()
-- (size_t)computeSerializedSizeAsField:(GPBFieldDescriptor *)field;
-- (void)writeToCodedOutputStream:(GPBCodedOutputStream *)outputStream
-                         asField:(GPBFieldDescriptor *)field;
-- (void)setGPBValue:(GPBValue *)value forGPBValueKey:(GPBValue *)key;
-- (void)enumerateForTextFormat:(void (^)(id keyObj, id valueObj))block;
+@interface GPBStringFloatDictionary () <GPBDictionaryInternalsProtocol> {
+ @package
+  GPB_UNSAFE_UNRETAINED GPBMessage *_autocreator;
+}
 @end
 
-@interface GPBStringDoubleDictionary ()
-- (size_t)computeSerializedSizeAsField:(GPBFieldDescriptor *)field;
-- (void)writeToCodedOutputStream:(GPBCodedOutputStream *)outputStream
-                         asField:(GPBFieldDescriptor *)field;
-- (void)setGPBValue:(GPBValue *)value forGPBValueKey:(GPBValue *)key;
-- (void)enumerateForTextFormat:(void (^)(id keyObj, id valueObj))block;
+@interface GPBStringDoubleDictionary () <GPBDictionaryInternalsProtocol> {
+ @package
+  GPB_UNSAFE_UNRETAINED GPBMessage *_autocreator;
+}
 @end
 
-@interface GPBStringEnumDictionary ()
-- (size_t)computeSerializedSizeAsField:(GPBFieldDescriptor *)field;
-- (void)writeToCodedOutputStream:(GPBCodedOutputStream *)outputStream
-                         asField:(GPBFieldDescriptor *)field;
-- (void)setGPBValue:(GPBValue *)value forGPBValueKey:(GPBValue *)key;
-- (void)enumerateForTextFormat:(void (^)(id keyObj, id valueObj))block;
+@interface GPBStringEnumDictionary () <GPBDictionaryInternalsProtocol> {
+ @package
+  GPB_UNSAFE_UNRETAINED GPBMessage *_autocreator;
+}
 - (NSData *)serializedDataForUnknownValue:(int32_t)value
                                    forKey:(GPBValue *)key
                                   keyType:(GPBType)keyType;
@@ -550,6 +450,16 @@
 
 //%PDDM-EXPAND-END (6 expansions)
 
+#pragma mark - NSDictionary Subclass
+
+@interface GPBAutocreatedDictionary : NSMutableDictionary {
+  @package
+  GPB_UNSAFE_UNRETAINED GPBMessage *_autocreator;
+}
+@end
+
+#pragma mark - Helpers
+
 CF_EXTERN_C_BEGIN
 
 // Helper to compute size when an NSDictionary is used for the map instead

+ 18 - 1
objectivec/GPBExtensionRegistry.h

@@ -38,7 +38,24 @@
 // ExtensionRegistry in which you have registered any extensions that you want
 // to be able to parse.  Otherwise, those extensions will just be treated like
 // unknown fields.
-@interface GPBExtensionRegistry : NSObject
+//
+// The *Root classes provide +extensionRegistry for the extensions defined in a
+// given file *and* all files it imports.  You can also create a
+// GPBExtensionRegistry, and merge those registries to handle parsing extensions
+// defined from non overlapping files.
+//
+//    GPBExtensionRegistry *registry =
+//        [[[MyProtoFileRoot extensionRegistry] copy] autorelease];
+//    [registry addExtension:[OtherMessage neededExtension];  // Not in MyProtoFile
+//    NSError *parseError = nil;
+//    MyMessage *msg = [MyMessage parseData:data
+//                        extensionRegistry:registry
+//                                    error:&parseError];
+//
+@interface GPBExtensionRegistry : NSObject<NSCopying>
+
+- (void)addExtension:(GPBExtensionField *)extension;
+- (void)addExtensions:(GPBExtensionRegistry *)registry;
 
 - (GPBExtensionField *)getExtension:(GPBDescriptor *)containingType
                         fieldNumber:(NSInteger)fieldNumber;

+ 9 - 1
objectivec/GPBExtensionRegistry.m

@@ -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 "GPBExtensionRegistry_PackagePrivate.h"
+#import "GPBExtensionRegistry.h"
 
 #import "GPBBootstrap.h"
 #import "GPBDescriptor.h"
@@ -52,6 +52,14 @@
   [super dealloc];
 }
 
+- (instancetype)copyWithZone:(NSZone *)zone {
+  GPBExtensionRegistry *result = [[[self class] allocWithZone:zone] init];
+  if (result && mutableClassMap_.count) {
+    [result->mutableClassMap_ addEntriesFromDictionary:mutableClassMap_];
+  }
+  return result;
+}
+
 - (NSMutableDictionary *)extensionMapForContainingType:
         (GPBDescriptor *)containingType {
   NSMutableDictionary *extensionMap =

+ 0 - 40
objectivec/GPBExtensionRegistry_PackagePrivate.h

@@ -1,40 +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 "GPBExtensionRegistry.h"
-
-@interface GPBExtensionRegistry ()
-
-- (void)addExtension:(GPBExtensionField *)extension;
-- (void)addExtensions:(GPBExtensionRegistry *)registry;
-
-@end

+ 59 - 35
objectivec/GPBMessage.h

@@ -28,15 +28,28 @@
 // (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 "GPBRootObject.h"
+#import <Foundation/Foundation.h>
+
+#import "GPBBootstrap.h"
 
 @class GPBDescriptor;
 @class GPBCodedInputStream;
 @class GPBCodedOutputStream;
 @class GPBExtensionField;
+@class GPBExtensionRegistry;
 @class GPBFieldDescriptor;
 @class GPBUnknownFieldSet;
 
+CF_EXTERN_C_BEGIN
+
+// NSError domain used for errors.
+extern NSString *const GPBMessageErrorDomain;
+
+typedef NS_ENUM(NSInteger, GPBMessageErrorCode) {
+  GPBMessageErrorCodeMalformedData = -100,
+  GPBMessageErrorCodeMissingRequiredField = -101,
+};
+
 // In DEBUG ONLY, an NSException is thrown when a parsed message doesn't
 // contain required fields. This key allows you to retrieve the parsed message
 // from the exception's |userInfo| dictionary.
@@ -44,12 +57,14 @@
 extern NSString *const GPBExceptionMessageKey;
 #endif  // DEBUG
 
-// NOTE:
-// If you add a instance method/property to this class that may conflict with
-// methods declared in protos, you need to update objective_helpers.cc.
+CF_EXTERN_C_END
+
+@interface GPBMessage : NSObject<NSSecureCoding, NSCopying>
+
+// NOTE: If you add a instance method/property to this class that may conflict
+// with methods declared in protos, you need to update objective_helpers.cc.
 // The main cases are methods that take no arguments, or setFoo:/hasFoo: type
 // methods.
-@interface GPBMessage : GPBRootObject<NSCoding, NSCopying>
 
 @property(nonatomic, readonly) GPBUnknownFieldSet *unknownFields;
 
@@ -59,29 +74,38 @@ extern NSString *const GPBExceptionMessageKey;
 // Returns an autoreleased instance.
 + (instancetype)message;
 
-// Create a message based on a variety of inputs.
-// In DEBUG ONLY
-// @throws NSInternalInconsistencyException The message is missing one or more
-//         required fields (i.e. -[isInitialized] returns false). Use
-//         GGPBExceptionMessageKey to retrieve the message from |userInfo|.
-+ (instancetype)parseFromData:(NSData *)data;
+// Create a message based on a variety of inputs.  If there is a data parse
+// error, nil is returned and if not NULL, errorPtr is filled in.
+// NOTE: In DEBUG ONLY, the message is also checked for all required field,
+// if one is missing, the parse will fail (returning nil, filling in errorPtr).
++ (instancetype)parseFromData:(NSData *)data error:(NSError **)errorPtr;
 + (instancetype)parseFromData:(NSData *)data
-            extensionRegistry:(GPBExtensionRegistry *)extensionRegistry;
+            extensionRegistry:(GPBExtensionRegistry *)extensionRegistry
+                        error:(NSError **)errorPtr;
 + (instancetype)parseFromCodedInputStream:(GPBCodedInputStream *)input
                         extensionRegistry:
-                            (GPBExtensionRegistry *)extensionRegistry;
+                            (GPBExtensionRegistry *)extensionRegistry
+                                    error:(NSError **)errorPtr;
 
-// Create a message based on delimited input.
+// Create a message based on delimited input.  If there is a data parse
+// error, nil is returned and if not NULL, errorPtr is filled in.
 + (instancetype)parseDelimitedFromCodedInputStream:(GPBCodedInputStream *)input
                                  extensionRegistry:
-                                     (GPBExtensionRegistry *)extensionRegistry;
-
-- (instancetype)initWithData:(NSData *)data;
+                                     (GPBExtensionRegistry *)extensionRegistry
+                                             error:(NSError **)errorPtr;
+
+// If there is a data parse error, nil is returned and if not NULL, errorPtr is
+// filled in.
+// NOTE: In DEBUG ONLY, the message is also checked for all required field,
+// if one is missing, the parse will fail (returning nil, filling in errorPtr).
+- (instancetype)initWithData:(NSData *)data error:(NSError **)errorPtr;
 - (instancetype)initWithData:(NSData *)data
-           extensionRegistry:(GPBExtensionRegistry *)extensionRegistry;
+           extensionRegistry:(GPBExtensionRegistry *)extensionRegistry
+                       error:(NSError **)errorPtr;
 - (instancetype)initWithCodedInputStream:(GPBCodedInputStream *)input
                        extensionRegistry:
-                           (GPBExtensionRegistry *)extensionRegistry;
+                           (GPBExtensionRegistry *)extensionRegistry
+                                   error:(NSError **)errorPtr;
 
 // Serializes the message and writes it to output.
 - (void)writeToCodedOutputStream:(GPBCodedOutputStream *)output;
@@ -93,11 +117,10 @@ extern NSString *const GPBExceptionMessageKey;
 - (void)writeDelimitedToOutputStream:(NSOutputStream *)output;
 
 // Serializes the message to an NSData. Note that this value is not cached, so
-// if you are using it repeatedly, cache it yourself.
-// In DEBUG ONLY:
-// @throws NSInternalInconsistencyException The message is missing one or more
-//         required fields (i.e. -[isInitialized] returns false). Use
-//         GPBExceptionMessageKey to retrieve the message from |userInfo|.
+// if you are using it repeatedly, cache it yourself. If there is an error
+// while generating the data, nil is returned.
+// NOTE: In DEBUG ONLY, the message is also checked for all required field,
+// if one is missing, nil will be returned.
 - (NSData *)data;
 
 // Same as -[data], except a delimiter is added to the start of the data
@@ -106,16 +129,16 @@ extern NSString *const GPBExceptionMessageKey;
 
 // Returns the size of the object if it were serialized.
 // This is not a cached value. If you are following a pattern like this:
-// size_t size = [aMsg serializedSize];
-// NSMutableData *foo = [NSMutableData dataWithCapacity:size + sizeof(size)];
-// [foo writeSize:size];
-// [foo appendData:[aMsg data]];
+//   size_t size = [aMsg serializedSize];
+//   NSMutableData *foo = [NSMutableData dataWithCapacity:size + sizeof(size)];
+//   [foo writeSize:size];
+//   [foo appendData:[aMsg data]];
 // you would be better doing:
-// NSData *data = [aMsg data];
-// NSUInteger size = [aMsg length];
-// NSMutableData *foo = [NSMutableData dataWithCapacity:size + sizeof(size)];
-// [foo writeSize:size];
-// [foo appendData:data];
+//   NSData *data = [aMsg data];
+//   NSUInteger size = [aMsg length];
+//   NSMutableData *foo = [NSMutableData dataWithCapacity:size + sizeof(size)];
+//   [foo writeSize:size];
+//   [foo appendData:data];
 - (size_t)serializedSize;
 
 // Return the descriptor for the message
@@ -123,8 +146,8 @@ extern NSString *const GPBExceptionMessageKey;
 - (GPBDescriptor *)descriptor;
 
 // Extensions use boxed values (NSNumbers) for PODs, NSMutableArrays for
-// repeated. If the extension is a Message, just like fields, one will be
-// auto created for you and returned.
+// 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;
@@ -141,6 +164,7 @@ extern NSString *const GPBExceptionMessageKey;
 
 // Parses a message of this type from the input and merges it with this
 // message.
+// NOTE: This will throw if there is an error parsing the data.
 - (void)mergeFromData:(NSData *)data
     extensionRegistry:(GPBExtensionRegistry *)extensionRegistry;
 

Dosya farkı çok büyük olduğundan ihmal edildi
+ 515 - 329
objectivec/GPBMessage.m


+ 4 - 2
objectivec/GPBMessage_PackagePrivate.h

@@ -82,6 +82,7 @@ typedef struct GPBMessage_Storage *GPBMessage_StoragePtr;
 // -[CodedInputStream checkLastTagWas:] after calling this to
 // verify that the last tag seen was the appropriate end-group tag,
 // or zero for EOF.
+// NOTE: This will throw if there is an error while parsing.
 - (void)mergeFromCodedInputStream:(GPBCodedInputStream *)input
                 extensionRegistry:(GPBExtensionRegistry *)extensionRegistry;
 
@@ -113,9 +114,10 @@ BOOL GPBWasMessageAutocreatedBy(GPBMessage *message, GPBMessage *parent);
 // visible to its autocreator.
 void GPBBecomeVisibleToAutocreator(GPBMessage *self);
 
-// Call this when an array is mutabled so the parent message that autocreated
-// it can react.
+// Call this when an array/dictionary is mutated so the parent message that
+// autocreated it can react.
 void GPBAutocreatedArrayModified(GPBMessage *self, id array);
+void GPBAutocreatedDictionaryModified(GPBMessage *self, id dictionary);
 
 // Clear the autocreator, if any. Asserts if the autocreator still has an
 // autocreated reference to this message.

+ 1 - 1
objectivec/GPBProtocolBuffers_RuntimeSupport.h

@@ -35,7 +35,7 @@
 
 #import "GPBDescriptor_PackagePrivate.h"
 #import "GPBExtensionField_PackagePrivate.h"
-#import "GPBExtensionRegistry_PackagePrivate.h"
+#import "GPBExtensionRegistry.h"
 #import "GPBMessage_PackagePrivate.h"
 #import "GPBRootObject_PackagePrivate.h"
 #import "GPBUtilities_PackagePrivate.h"

+ 48 - 13
objectivec/GPBRootObject.m

@@ -31,6 +31,7 @@
 #import "GPBRootObject_PackagePrivate.h"
 
 #import <objc/runtime.h>
+#import <libkern/OSAtomic.h>
 
 #import <CoreFoundation/CoreFoundation.h>
 
@@ -95,9 +96,11 @@ static CFHashCode GPBRootExtensionKeyHash(const void *value) {
   return jenkins_one_at_a_time_hash(key);
 }
 
+static OSSpinLock gExtensionSingletonDictionaryLock_ = OS_SPINLOCK_INIT;
 static CFMutableDictionaryRef gExtensionSingletonDictionary = NULL;
 
 + (void)initialize {
+  // Ensure the global is started up.
   if (!gExtensionSingletonDictionary) {
     CFDictionaryKeyCallBacks keyCallBacks = {
       // See description above for reason for using custom dictionary.
@@ -112,6 +115,13 @@ static CFMutableDictionaryRef gExtensionSingletonDictionary = NULL;
         CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &keyCallBacks,
                                   &kCFTypeDictionaryValueCallBacks);
   }
+
+  if ([self superclass] == [GPBRootObject class]) {
+    // This is here to start up all the per file "Root" subclasses.
+    // This must be done in initialize to enforce thread safety of start up of
+    // the protocol buffer library.
+    [self extensionRegistry];
+  }
 }
 
 + (GPBExtensionRegistry *)extensionRegistry {
@@ -122,39 +132,54 @@ static CFMutableDictionaryRef gExtensionSingletonDictionary = NULL;
 
 + (void)globallyRegisterExtension:(GPBExtensionField *)field {
   const char *key = [field.descriptor singletonNameC];
-  // Register happens at startup, so there is no thread safety issue in
-  // modifying the dictionary.
+  OSSpinLockLock(&gExtensionSingletonDictionaryLock_);
   CFDictionarySetValue(gExtensionSingletonDictionary, key, field);
+  OSSpinLockUnlock(&gExtensionSingletonDictionaryLock_);
 }
 
-static id ExtensionForName(id self, SEL _cmd) {
+GPB_INLINE 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.
-  const char *className = class_getName(self);
   const char *selName = sel_getName(_cmd);
+  if (selName[0] == '_') {
+    return nil;  // Apple internal selector.
+  }
+  size_t selNameLen = 0;
+  while (1) {
+    char c = selName[selNameLen];
+    if (c == '\0') {  // String end.
+      break;
+    }
+    if (c == ':') {
+      return nil;  // Selector took an arg, not one of the runtime methods.
+    }
+    ++selNameLen;
+  }
+
+  const char *className = class_getName(self);
   size_t classNameLen = strlen(className);
-  size_t selNameLen = strlen(selName);
   char key[classNameLen + selNameLen + 2];
   memcpy(key, className, classNameLen);
   key[classNameLen] = '_';
   memcpy(&key[classNameLen + 1], selName, selNameLen);
   key[classNameLen + 1 + selNameLen] = '\0';
+  OSSpinLockLock(&gExtensionSingletonDictionaryLock_);
   id extension = (id)CFDictionaryGetValue(gExtensionSingletonDictionary, key);
-  // We can't remove the key from the dictionary here (as an optimization),
-  // because resolveClassMethod can happen on any thread and we'd then need
-  // a lock.
+  if (extension) {
+    // The method is getting wired in to the class, so no need to keep it in
+    // the dictionary.
+    CFDictionaryRemoveValue(gExtensionSingletonDictionary, key);
+  }
+  OSSpinLockUnlock(&gExtensionSingletonDictionaryLock_);
   return extension;
 }
 
-+ (BOOL)resolveClassMethod:(SEL)sel {
+BOOL GPBResolveExtensionClassMethod(Class self, SEL sel) {
   // Another option would be to register the extensions with the class at
   // globallyRegisterExtension:
   // Timing the two solutions, this solution turned out to be much faster
   // and reduced startup time, and runtime memory.
-  // On an iPhone 5s:
-  // ResolveClassMethod: 1515583 nanos
-  // globallyRegisterExtension: 2453083 nanos
   // The advantage to globallyRegisterExtension is that it would reduce the
   // size of the protos somewhat because the singletonNameC wouldn't need
   // to include the class name. For a class with a lot of extensions it
@@ -169,7 +194,17 @@ static id ExtensionForName(id self, SEL _cmd) {
 #pragma unused(obj)
       return extension;
     });
-    return class_addMethod(metaClass, sel, imp, encoding);
+    if (class_addMethod(metaClass, sel, imp, encoding)) {
+      return YES;
+    }
+  }
+  return NO;
+}
+
+
++ (BOOL)resolveClassMethod:(SEL)sel {
+  if (GPBResolveExtensionClassMethod(self, sel)) {
+    return YES;
   }
   return [super resolveClassMethod:sel];
 }

+ 4 - 0
objectivec/GPBRootObject_PackagePrivate.h

@@ -40,3 +40,7 @@
 + (void)globallyRegisterExtension:(GPBExtensionField *)field;
 
 @end
+
+// Returns YES if the selector was resolved and added to the class,
+// NO otherwise.
+BOOL GPBResolveExtensionClassMethod(Class self, SEL sel);

+ 69 - 28
objectivec/GPBUtilities.m

@@ -93,7 +93,9 @@ void GPBClearMessageField(GPBMessage *self, GPBFieldDescriptor *field) {
 }
 
 BOOL GPBGetHasIvar(GPBMessage *self, int32_t idx, uint32_t fieldNumber) {
-  NSCAssert(self->messageStorage_ != NULL, @"How?");
+  NSCAssert(self->messageStorage_ != NULL,
+            @"%@: All messages should have storage (from init)",
+            [self class]);
   if (idx < 0) {
     NSCAssert(fieldNumber != 0, @"Invalid field number.");
     BOOL hasIvar = (self->messageStorage_->_has_storage_[-idx] == fieldNumber);
@@ -109,7 +111,8 @@ BOOL GPBGetHasIvar(GPBMessage *self, int32_t idx, uint32_t fieldNumber) {
 }
 
 uint32_t GPBGetHasOneof(GPBMessage *self, int32_t idx) {
-  NSCAssert(idx < 0, @"invalid index for oneof.");
+  NSCAssert(idx < 0, @"%@: invalid index (%d) for oneof.",
+            [self class], idx);
   uint32_t result = self->messageStorage_->_has_storage_[-idx];
   return result;
 }
@@ -145,7 +148,9 @@ void GPBMaybeClearOneof(GPBMessage *self, GPBOneofDescriptor *oneof,
   // Like GPBClearMessageField(), free the memory if an objecttype is set,
   // pod types don't need to do anything.
   GPBFieldDescriptor *fieldSet = [oneof fieldWithNumber:fieldNumberSet];
-  NSCAssert(fieldSet, @"oneof set to something not in the oneof?");
+  NSCAssert(fieldSet,
+            @"%@: oneof set to something (%u) not in the oneof?",
+            [self class], fieldNumberSet);
   if (fieldSet && GPBFieldStoresObject(fieldSet)) {
     uint8_t *storage = (uint8_t *)self->messageStorage_;
     id *typePtr = (id *)&storage[fieldSet->description_->offset];
@@ -189,7 +194,9 @@ void GPBMaybeClearOneof(GPBMessage *self, GPBOneofDescriptor *oneof,
 //%  if (oneof) {
 //%    GPBMaybeClearOneof(self, oneof, GPBFieldNumber(field));
 //%  }
-//%  NSCAssert(self->messageStorage_ != NULL, @"How?");
+//%  NSCAssert(self->messageStorage_ != NULL,
+//%            @"%@: All messages should have storage (from init)",
+//%            [self class]);
 //%#if defined(__clang_analyzer__)
 //%  if (self->messageStorage_ == NULL) return;
 //%#endif
@@ -263,7 +270,9 @@ void GPBSetObjectIvarWithFieldInternal(GPBMessage *self,
 void GPBSetRetainedObjectIvarWithFieldInternal(GPBMessage *self,
                                                GPBFieldDescriptor *field,
                                                id value, GPBFileSyntax syntax) {
-  NSCAssert(self->messageStorage_ != NULL, @"How?");
+  NSCAssert(self->messageStorage_ != NULL,
+            @"%@: All messages should have storage (from init)",
+            [self class]);
 #if defined(__clang_analyzer__)
   if (self->messageStorage_ == NULL) return;
 #endif
@@ -328,7 +337,7 @@ void GPBSetRetainedObjectIvarWithFieldInternal(GPBMessage *self,
   if (oldValue) {
     if (isMapOrArray) {
       if (field.fieldType == GPBFieldTypeRepeated) {
-        // If the old message value was autocreated by us, then clear it.
+        // If the old array was autocreated by us, then clear it.
         if (GPBTypeIsObject(fieldType)) {
           GPBAutocreatedArray *autoArray = oldValue;
           if (autoArray->_autocreator == self) {
@@ -341,6 +350,21 @@ void GPBSetRetainedObjectIvarWithFieldInternal(GPBMessage *self,
             gpbArray->_autocreator = nil;
           }
         }
+      } else { // GPBFieldTypeMap
+        // If the old map was autocreated by us, then clear it.
+        if ((field.mapKeyType == GPBTypeString) &&
+            GPBTypeIsObject(fieldType)) {
+          GPBAutocreatedDictionary *autoDict = oldValue;
+          if (autoDict->_autocreator == self) {
+            autoDict->_autocreator = nil;
+          }
+        } else {
+          // Type doesn't matter, it is a GPB*Dictionary.
+          GPBInt32Int32Dictionary *gpbDict = oldValue;
+          if (gpbDict->_autocreator == self) {
+            gpbDict->_autocreator = nil;
+          }
+        }
       }
     } else if (fieldIsMessage) {
       // If the old message value was autocreated by us, then clear it.
@@ -461,7 +485,9 @@ void GPBSetBoolIvarWithFieldInternal(GPBMessage *self,
   if (oneof) {
     GPBMaybeClearOneof(self, oneof, GPBFieldNumber(field));
   }
-  NSCAssert(self->messageStorage_ != NULL, @"How?");
+  NSCAssert(self->messageStorage_ != NULL,
+            @"%@: All messages should have storage (from init)",
+            [self class]);
 #if defined(__clang_analyzer__)
   if (self->messageStorage_ == NULL) return;
 #endif
@@ -507,7 +533,9 @@ void GPBSetInt32IvarWithFieldInternal(GPBMessage *self,
   if (oneof) {
     GPBMaybeClearOneof(self, oneof, GPBFieldNumber(field));
   }
-  NSCAssert(self->messageStorage_ != NULL, @"How?");
+  NSCAssert(self->messageStorage_ != NULL,
+            @"%@: All messages should have storage (from init)",
+            [self class]);
 #if defined(__clang_analyzer__)
   if (self->messageStorage_ == NULL) return;
 #endif
@@ -553,7 +581,9 @@ void GPBSetUInt32IvarWithFieldInternal(GPBMessage *self,
   if (oneof) {
     GPBMaybeClearOneof(self, oneof, GPBFieldNumber(field));
   }
-  NSCAssert(self->messageStorage_ != NULL, @"How?");
+  NSCAssert(self->messageStorage_ != NULL,
+            @"%@: All messages should have storage (from init)",
+            [self class]);
 #if defined(__clang_analyzer__)
   if (self->messageStorage_ == NULL) return;
 #endif
@@ -599,7 +629,9 @@ void GPBSetInt64IvarWithFieldInternal(GPBMessage *self,
   if (oneof) {
     GPBMaybeClearOneof(self, oneof, GPBFieldNumber(field));
   }
-  NSCAssert(self->messageStorage_ != NULL, @"How?");
+  NSCAssert(self->messageStorage_ != NULL,
+            @"%@: All messages should have storage (from init)",
+            [self class]);
 #if defined(__clang_analyzer__)
   if (self->messageStorage_ == NULL) return;
 #endif
@@ -645,7 +677,9 @@ void GPBSetUInt64IvarWithFieldInternal(GPBMessage *self,
   if (oneof) {
     GPBMaybeClearOneof(self, oneof, GPBFieldNumber(field));
   }
-  NSCAssert(self->messageStorage_ != NULL, @"How?");
+  NSCAssert(self->messageStorage_ != NULL,
+            @"%@: All messages should have storage (from init)",
+            [self class]);
 #if defined(__clang_analyzer__)
   if (self->messageStorage_ == NULL) return;
 #endif
@@ -691,7 +725,9 @@ void GPBSetFloatIvarWithFieldInternal(GPBMessage *self,
   if (oneof) {
     GPBMaybeClearOneof(self, oneof, GPBFieldNumber(field));
   }
-  NSCAssert(self->messageStorage_ != NULL, @"How?");
+  NSCAssert(self->messageStorage_ != NULL,
+            @"%@: All messages should have storage (from init)",
+            [self class]);
 #if defined(__clang_analyzer__)
   if (self->messageStorage_ == NULL) return;
 #endif
@@ -737,7 +773,9 @@ void GPBSetDoubleIvarWithFieldInternal(GPBMessage *self,
   if (oneof) {
     GPBMaybeClearOneof(self, oneof, GPBFieldNumber(field));
   }
-  NSCAssert(self->messageStorage_ != NULL, @"How?");
+  NSCAssert(self->messageStorage_ != NULL,
+            @"%@: All messages should have storage (from init)",
+            [self class]);
 #if defined(__clang_analyzer__)
   if (self->messageStorage_ == NULL) return;
 #endif
@@ -1152,30 +1190,32 @@ static void AppendTextFormatForMessageField(GPBMessage *message,
                                             GPBFieldDescriptor *field,
                                             NSMutableString *toStr,
                                             NSString *lineIndent) {
-  id array;
-  NSUInteger arrayCount;
+  id arrayOrMap;
+  NSUInteger count;
   GPBFieldType fieldType = field.fieldType;
   switch (fieldType) {
     case GPBFieldTypeSingle:
-      array = nil;
-      arrayCount = (GPBGetHasIvarField(message, field) ? 1 : 0);
+      arrayOrMap = nil;
+      count = (GPBGetHasIvarField(message, field) ? 1 : 0);
       break;
 
     case GPBFieldTypeRepeated:
-      array = GPBGetObjectIvarWithFieldNoAutocreate(message, field);
-      arrayCount = [(NSArray *)array count];
+      // Will be NSArray or GPB*Array, type doesn't matter, they both
+      // implement count.
+      arrayOrMap = GPBGetObjectIvarWithFieldNoAutocreate(message, field);
+      count = [(NSArray *)arrayOrMap count];
       break;
 
     case GPBFieldTypeMap: {
-      // Could be a GPB*Dictionary or NSMutableDictionary, type doesn't matter,
-      // just want count.
-      array = GPBGetObjectIvarWithFieldNoAutocreate(message, field);
-      arrayCount = [(NSArray *)array count];
+      // Will be GPB*Dictionary or NSMutableDictionary, type doesn't matter,
+      // they both implement count.
+      arrayOrMap = GPBGetObjectIvarWithFieldNoAutocreate(message, field);
+      count = [(NSDictionary *)arrayOrMap count];
       break;
     }
   }
 
-  if (arrayCount == 0) {
+  if (count == 0) {
     // Nothing to print, out of here.
     return;
   }
@@ -1189,7 +1229,7 @@ static void AppendTextFormatForMessageField(GPBMessage *message,
     fieldName = [NSString stringWithFormat:@"%u", GPBFieldNumber(field)];
     // If there is only one entry, put the objc name as a comment, other wise
     // add it before the the repeated values.
-    if (arrayCount > 1) {
+    if (count > 1) {
       [toStr appendFormat:@"%@# %@\n", lineIndent, field.name];
     } else {
       lineEnding = [NSString stringWithFormat:@"  # %@", field.name];
@@ -1197,16 +1237,17 @@ static void AppendTextFormatForMessageField(GPBMessage *message,
   }
 
   if (fieldType == GPBFieldTypeMap) {
-    AppendTextFormatForMapMessageField(array, field, toStr, lineIndent,
+    AppendTextFormatForMapMessageField(arrayOrMap, field, toStr, lineIndent,
                                        fieldName, lineEnding);
     return;
   }
 
+  id array = arrayOrMap;
   const BOOL isRepeated = (array != nil);
 
   GPBType fieldDataType = GPBGetFieldType(field);
   BOOL isMessageField = GPBTypeIsMessage(fieldDataType);
-  for (NSUInteger j = 0; j < arrayCount; ++j) {
+  for (NSUInteger j = 0; j < count; ++j) {
     // Start the line.
     [toStr appendFormat:@"%@%@%s ", lineIndent, fieldName,
                         (isMessageField ? "" : ":")];
@@ -1291,7 +1332,7 @@ static void AppendTextFormatForMessageField(GPBMessage *message,
     // End the line.
     [toStr appendFormat:@"%@\n", lineEnding];
 
-  }  // for(arrayCount)
+  }  // for(count)
 }
 
 static void AppendTextFormatForMessageExtensionRange(GPBMessage *message,

Dosya farkı çok büyük olduğundan ihmal edildi
+ 0 - 2
objectivec/ProtocolBuffers_OSX.xcodeproj/project.pbxproj


+ 14 - 0
objectivec/ProtocolBuffers_OSX.xcodeproj/xcshareddata/xcschemes/ProtocolBuffers.xcscheme

@@ -34,6 +34,20 @@
                ReferencedContainer = "container:ProtocolBuffers_OSX.xcodeproj">
             </BuildableReference>
          </BuildActionEntry>
+         <BuildActionEntry
+            buildForTesting = "YES"
+            buildForRunning = "NO"
+            buildForProfiling = "NO"
+            buildForArchiving = "NO"
+            buildForAnalyzing = "YES">
+            <BuildableReference
+               BuildableIdentifier = "primary"
+               BlueprintIdentifier = "8BBEA4A5147C727100C4ADB7"
+               BuildableName = "UnitTests.xctest"
+               BlueprintName = "UnitTests"
+               ReferencedContainer = "container:ProtocolBuffers_OSX.xcodeproj">
+            </BuildableReference>
+         </BuildActionEntry>
       </BuildActionEntries>
    </BuildAction>
    <TestAction

Dosya farkı çok büyük olduğundan ihmal edildi
+ 0 - 2
objectivec/ProtocolBuffers_iOS.xcodeproj/project.pbxproj


+ 14 - 0
objectivec/ProtocolBuffers_iOS.xcodeproj/xcshareddata/xcschemes/ProtocolBuffers.xcscheme

@@ -34,6 +34,20 @@
                ReferencedContainer = "container:ProtocolBuffers_iOS.xcodeproj">
             </BuildableReference>
          </BuildActionEntry>
+         <BuildActionEntry
+            buildForTesting = "YES"
+            buildForRunning = "NO"
+            buildForProfiling = "NO"
+            buildForArchiving = "NO"
+            buildForAnalyzing = "YES">
+            <BuildableReference
+               BuildableIdentifier = "primary"
+               BlueprintIdentifier = "8BBEA4A5147C727100C4ADB7"
+               BuildableName = "UnitTests.xctest"
+               BlueprintName = "UnitTests"
+               ReferencedContainer = "container:ProtocolBuffers_iOS.xcodeproj">
+            </BuildableReference>
+         </BuildActionEntry>
       </BuildActionEntries>
    </BuildAction>
    <TestAction

+ 77 - 0
objectivec/README.md

@@ -0,0 +1,77 @@
+Protocol Buffers - Google's data interchange format
+===================================================
+
+[![Build Status](https://travis-ci.org/google/protobuf.svg?branch=master)](https://travis-ci.org/google/protobuf)
+
+Copyright 2008 Google Inc.
+
+This directory contains the Objective C Protocol Buffers runtime library.
+
+Requirements
+------------
+
+The Objective C implemention requires:
+
+- Objective C 2.0 Runtime (32bit & 64bit iOS, 64bit OS X).
+- Xcode 6.3 (or later).
+- The library code does *not* use ARC (for performance reasons), but it all can
+  be called from ARC code.
+
+Installation
+------------
+
+The full distribution pulled from github includes the sources for both the
+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
+-----
+
+There are two ways to include the Runtime sources in your project:
+
+Add `objectivec/\*.h` & `objectivec/GPBProtocolBuffers.m` to your project.
+
+*or*
+
+Add `objectivec/\*.h` & `objectivec/\*.m` except for
+`objectivec/GPBProtocolBuffers.m` to your project.
+
+
+If the target is using ARC, remember to turn off ARC (`-fno-objc-arc`) for the
+`.m` files.
+
+The files generated by `protoc` for the `*.proto` files (`\*.pbobjc.h' and
+`\*.pbobjc.m`) are then also added to the target.
+
+The Objective C classes/enums can be used from Swift code.
+
+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
+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.
+
+Documentation
+-------------
+
+The complete documentation for Protocol Buffers is available via the
+web at:
+
+    https://developers.google.com/protocol-buffers/

+ 80 - 7
objectivec/Tests/GPBArrayTests.m

@@ -29,14 +29,11 @@
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 #import <Foundation/Foundation.h>
-
 #import <XCTest/XCTest.h>
 
 #import "GPBArray.h"
 
-#ifndef GPBARRAYSIZE
-#define GPBARRAYSIZE(a) ((sizeof(a) / sizeof((a[0]))))
-#endif  // GPBARRAYSIZE
+#import "GPBTestUtilities.h"
 
 // To let the testing macros work, add some extra methods to simplify things.
 @interface GPBEnumArray (TestingTweak)
@@ -233,6 +230,8 @@ static BOOL TestingEnum_IsValidValue2(int32_t value) {
 //%  // Should be new object but equal.
 //%  XCTAssertNotEqual(array, array2);
 //%  XCTAssertEqualObjects(array, array2);
+//%  [array2 release];
+//%  [array release];
 //%}
 //%
 //%- (void)testArrayFromArray {
@@ -248,6 +247,7 @@ static BOOL TestingEnum_IsValidValue2(int32_t value) {
 //%  // Should be new pointer, but equal objects.
 //%  XCTAssertNotEqual(array, array2);
 //%  XCTAssertEqualObjects(array, array2);
+//%  [array release];
 //%}
 //%
 //%- (void)testAdds {
@@ -275,6 +275,7 @@ static BOOL TestingEnum_IsValidValue2(int32_t value) {
 //%  XCTAssertEqual([array valueAtIndex:2], VAL3);
 //%  XCTAssertEqual([array valueAtIndex:3], VAL4);
 //%  XCTAssertEqual([array valueAtIndex:4], VAL1);
+//%  [array2 release];
 //%}
 //%
 //%- (void)testInsert {
@@ -307,6 +308,7 @@ static BOOL TestingEnum_IsValidValue2(int32_t value) {
 //%  XCTAssertEqual([array valueAtIndex:3], VAL2);
 //%  XCTAssertEqual([array valueAtIndex:4], VAL3);
 //%  XCTAssertEqual([array valueAtIndex:5], VAL4);
+//%  [array release];
 //%}
 //%
 //%- (void)testRemove {
@@ -343,6 +345,7 @@ static BOOL TestingEnum_IsValidValue2(int32_t value) {
 //%  XCTAssertEqual(array.count, 0U);
 //%  XCTAssertThrowsSpecificNamed([array removeValueAtIndex:0],
 //%                               NSException, NSRangeException);
+//%  [array release];
 //%}
 //%
 //%- (void)testInplaceMutation {
@@ -381,6 +384,7 @@ static BOOL TestingEnum_IsValidValue2(int32_t value) {
 //%                               NSException, NSRangeException);
 //%  XCTAssertThrowsSpecificNamed([array exchangeValueAtIndex:1 withValueAtIndex:4],
 //%                               NSException, NSRangeException);
+//%  [array release];
 //%}
 //%
 //%- (void)testInternalResizing {
@@ -405,6 +409,7 @@ static BOOL TestingEnum_IsValidValue2(int32_t value) {
 //%  XCTAssertEqual(array.count, 404U);
 //%  [array removeAll];
 //%  XCTAssertEqual(array.count, 0U);
+//%  [array release];
 //%}
 //%
 //%@end
@@ -558,6 +563,8 @@ static BOOL TestingEnum_IsValidValue2(int32_t value) {
   // Should be new object but equal.
   XCTAssertNotEqual(array, array2);
   XCTAssertEqualObjects(array, array2);
+  [array2 release];
+  [array release];
 }
 
 - (void)testArrayFromArray {
@@ -573,6 +580,7 @@ static BOOL TestingEnum_IsValidValue2(int32_t value) {
   // Should be new pointer, but equal objects.
   XCTAssertNotEqual(array, array2);
   XCTAssertEqualObjects(array, array2);
+  [array release];
 }
 
 - (void)testAdds {
@@ -600,6 +608,7 @@ static BOOL TestingEnum_IsValidValue2(int32_t value) {
   XCTAssertEqual([array valueAtIndex:2], 3);
   XCTAssertEqual([array valueAtIndex:3], 4);
   XCTAssertEqual([array valueAtIndex:4], 1);
+  [array2 release];
 }
 
 - (void)testInsert {
@@ -632,6 +641,7 @@ static BOOL TestingEnum_IsValidValue2(int32_t value) {
   XCTAssertEqual([array valueAtIndex:3], 2);
   XCTAssertEqual([array valueAtIndex:4], 3);
   XCTAssertEqual([array valueAtIndex:5], 4);
+  [array release];
 }
 
 - (void)testRemove {
@@ -668,6 +678,7 @@ static BOOL TestingEnum_IsValidValue2(int32_t value) {
   XCTAssertEqual(array.count, 0U);
   XCTAssertThrowsSpecificNamed([array removeValueAtIndex:0],
                                NSException, NSRangeException);
+  [array release];
 }
 
 - (void)testInplaceMutation {
@@ -706,6 +717,7 @@ static BOOL TestingEnum_IsValidValue2(int32_t value) {
                                NSException, NSRangeException);
   XCTAssertThrowsSpecificNamed([array exchangeValueAtIndex:1 withValueAtIndex:4],
                                NSException, NSRangeException);
+  [array release];
 }
 
 - (void)testInternalResizing {
@@ -730,6 +742,7 @@ static BOOL TestingEnum_IsValidValue2(int32_t value) {
   XCTAssertEqual(array.count, 404U);
   [array removeAll];
   XCTAssertEqual(array.count, 0U);
+  [array release];
 }
 
 @end
@@ -883,6 +896,8 @@ static BOOL TestingEnum_IsValidValue2(int32_t value) {
   // Should be new object but equal.
   XCTAssertNotEqual(array, array2);
   XCTAssertEqualObjects(array, array2);
+  [array2 release];
+  [array release];
 }
 
 - (void)testArrayFromArray {
@@ -898,6 +913,7 @@ static BOOL TestingEnum_IsValidValue2(int32_t value) {
   // Should be new pointer, but equal objects.
   XCTAssertNotEqual(array, array2);
   XCTAssertEqualObjects(array, array2);
+  [array release];
 }
 
 - (void)testAdds {
@@ -925,6 +941,7 @@ static BOOL TestingEnum_IsValidValue2(int32_t value) {
   XCTAssertEqual([array valueAtIndex:2], 13U);
   XCTAssertEqual([array valueAtIndex:3], 14U);
   XCTAssertEqual([array valueAtIndex:4], 11U);
+  [array2 release];
 }
 
 - (void)testInsert {
@@ -957,6 +974,7 @@ static BOOL TestingEnum_IsValidValue2(int32_t value) {
   XCTAssertEqual([array valueAtIndex:3], 12U);
   XCTAssertEqual([array valueAtIndex:4], 13U);
   XCTAssertEqual([array valueAtIndex:5], 14U);
+  [array release];
 }
 
 - (void)testRemove {
@@ -993,6 +1011,7 @@ static BOOL TestingEnum_IsValidValue2(int32_t value) {
   XCTAssertEqual(array.count, 0U);
   XCTAssertThrowsSpecificNamed([array removeValueAtIndex:0],
                                NSException, NSRangeException);
+  [array release];
 }
 
 - (void)testInplaceMutation {
@@ -1031,6 +1050,7 @@ static BOOL TestingEnum_IsValidValue2(int32_t value) {
                                NSException, NSRangeException);
   XCTAssertThrowsSpecificNamed([array exchangeValueAtIndex:1 withValueAtIndex:4],
                                NSException, NSRangeException);
+  [array release];
 }
 
 - (void)testInternalResizing {
@@ -1055,6 +1075,7 @@ static BOOL TestingEnum_IsValidValue2(int32_t value) {
   XCTAssertEqual(array.count, 404U);
   [array removeAll];
   XCTAssertEqual(array.count, 0U);
+  [array release];
 }
 
 @end
@@ -1208,6 +1229,8 @@ static BOOL TestingEnum_IsValidValue2(int32_t value) {
   // Should be new object but equal.
   XCTAssertNotEqual(array, array2);
   XCTAssertEqualObjects(array, array2);
+  [array2 release];
+  [array release];
 }
 
 - (void)testArrayFromArray {
@@ -1223,6 +1246,7 @@ static BOOL TestingEnum_IsValidValue2(int32_t value) {
   // Should be new pointer, but equal objects.
   XCTAssertNotEqual(array, array2);
   XCTAssertEqualObjects(array, array2);
+  [array release];
 }
 
 - (void)testAdds {
@@ -1250,6 +1274,7 @@ static BOOL TestingEnum_IsValidValue2(int32_t value) {
   XCTAssertEqual([array valueAtIndex:2], 33LL);
   XCTAssertEqual([array valueAtIndex:3], 34LL);
   XCTAssertEqual([array valueAtIndex:4], 31LL);
+  [array2 release];
 }
 
 - (void)testInsert {
@@ -1282,6 +1307,7 @@ static BOOL TestingEnum_IsValidValue2(int32_t value) {
   XCTAssertEqual([array valueAtIndex:3], 32LL);
   XCTAssertEqual([array valueAtIndex:4], 33LL);
   XCTAssertEqual([array valueAtIndex:5], 34LL);
+  [array release];
 }
 
 - (void)testRemove {
@@ -1318,6 +1344,7 @@ static BOOL TestingEnum_IsValidValue2(int32_t value) {
   XCTAssertEqual(array.count, 0U);
   XCTAssertThrowsSpecificNamed([array removeValueAtIndex:0],
                                NSException, NSRangeException);
+  [array release];
 }
 
 - (void)testInplaceMutation {
@@ -1356,6 +1383,7 @@ static BOOL TestingEnum_IsValidValue2(int32_t value) {
                                NSException, NSRangeException);
   XCTAssertThrowsSpecificNamed([array exchangeValueAtIndex:1 withValueAtIndex:4],
                                NSException, NSRangeException);
+  [array release];
 }
 
 - (void)testInternalResizing {
@@ -1380,6 +1408,7 @@ static BOOL TestingEnum_IsValidValue2(int32_t value) {
   XCTAssertEqual(array.count, 404U);
   [array removeAll];
   XCTAssertEqual(array.count, 0U);
+  [array release];
 }
 
 @end
@@ -1533,6 +1562,8 @@ static BOOL TestingEnum_IsValidValue2(int32_t value) {
   // Should be new object but equal.
   XCTAssertNotEqual(array, array2);
   XCTAssertEqualObjects(array, array2);
+  [array2 release];
+  [array release];
 }
 
 - (void)testArrayFromArray {
@@ -1548,6 +1579,7 @@ static BOOL TestingEnum_IsValidValue2(int32_t value) {
   // Should be new pointer, but equal objects.
   XCTAssertNotEqual(array, array2);
   XCTAssertEqualObjects(array, array2);
+  [array release];
 }
 
 - (void)testAdds {
@@ -1575,6 +1607,7 @@ static BOOL TestingEnum_IsValidValue2(int32_t value) {
   XCTAssertEqual([array valueAtIndex:2], 43ULL);
   XCTAssertEqual([array valueAtIndex:3], 44ULL);
   XCTAssertEqual([array valueAtIndex:4], 41ULL);
+  [array2 release];
 }
 
 - (void)testInsert {
@@ -1607,6 +1640,7 @@ static BOOL TestingEnum_IsValidValue2(int32_t value) {
   XCTAssertEqual([array valueAtIndex:3], 42ULL);
   XCTAssertEqual([array valueAtIndex:4], 43ULL);
   XCTAssertEqual([array valueAtIndex:5], 44ULL);
+  [array release];
 }
 
 - (void)testRemove {
@@ -1643,6 +1677,7 @@ static BOOL TestingEnum_IsValidValue2(int32_t value) {
   XCTAssertEqual(array.count, 0U);
   XCTAssertThrowsSpecificNamed([array removeValueAtIndex:0],
                                NSException, NSRangeException);
+  [array release];
 }
 
 - (void)testInplaceMutation {
@@ -1681,6 +1716,7 @@ static BOOL TestingEnum_IsValidValue2(int32_t value) {
                                NSException, NSRangeException);
   XCTAssertThrowsSpecificNamed([array exchangeValueAtIndex:1 withValueAtIndex:4],
                                NSException, NSRangeException);
+  [array release];
 }
 
 - (void)testInternalResizing {
@@ -1705,6 +1741,7 @@ static BOOL TestingEnum_IsValidValue2(int32_t value) {
   XCTAssertEqual(array.count, 404U);
   [array removeAll];
   XCTAssertEqual(array.count, 0U);
+  [array release];
 }
 
 @end
@@ -1858,6 +1895,8 @@ static BOOL TestingEnum_IsValidValue2(int32_t value) {
   // Should be new object but equal.
   XCTAssertNotEqual(array, array2);
   XCTAssertEqualObjects(array, array2);
+  [array2 release];
+  [array release];
 }
 
 - (void)testArrayFromArray {
@@ -1873,6 +1912,7 @@ static BOOL TestingEnum_IsValidValue2(int32_t value) {
   // Should be new pointer, but equal objects.
   XCTAssertNotEqual(array, array2);
   XCTAssertEqualObjects(array, array2);
+  [array release];
 }
 
 - (void)testAdds {
@@ -1900,6 +1940,7 @@ static BOOL TestingEnum_IsValidValue2(int32_t value) {
   XCTAssertEqual([array valueAtIndex:2], 53.f);
   XCTAssertEqual([array valueAtIndex:3], 54.f);
   XCTAssertEqual([array valueAtIndex:4], 51.f);
+  [array2 release];
 }
 
 - (void)testInsert {
@@ -1932,6 +1973,7 @@ static BOOL TestingEnum_IsValidValue2(int32_t value) {
   XCTAssertEqual([array valueAtIndex:3], 52.f);
   XCTAssertEqual([array valueAtIndex:4], 53.f);
   XCTAssertEqual([array valueAtIndex:5], 54.f);
+  [array release];
 }
 
 - (void)testRemove {
@@ -1968,6 +2010,7 @@ static BOOL TestingEnum_IsValidValue2(int32_t value) {
   XCTAssertEqual(array.count, 0U);
   XCTAssertThrowsSpecificNamed([array removeValueAtIndex:0],
                                NSException, NSRangeException);
+  [array release];
 }
 
 - (void)testInplaceMutation {
@@ -2006,6 +2049,7 @@ static BOOL TestingEnum_IsValidValue2(int32_t value) {
                                NSException, NSRangeException);
   XCTAssertThrowsSpecificNamed([array exchangeValueAtIndex:1 withValueAtIndex:4],
                                NSException, NSRangeException);
+  [array release];
 }
 
 - (void)testInternalResizing {
@@ -2030,6 +2074,7 @@ static BOOL TestingEnum_IsValidValue2(int32_t value) {
   XCTAssertEqual(array.count, 404U);
   [array removeAll];
   XCTAssertEqual(array.count, 0U);
+  [array release];
 }
 
 @end
@@ -2183,6 +2228,8 @@ static BOOL TestingEnum_IsValidValue2(int32_t value) {
   // Should be new object but equal.
   XCTAssertNotEqual(array, array2);
   XCTAssertEqualObjects(array, array2);
+  [array2 release];
+  [array release];
 }
 
 - (void)testArrayFromArray {
@@ -2198,6 +2245,7 @@ static BOOL TestingEnum_IsValidValue2(int32_t value) {
   // Should be new pointer, but equal objects.
   XCTAssertNotEqual(array, array2);
   XCTAssertEqualObjects(array, array2);
+  [array release];
 }
 
 - (void)testAdds {
@@ -2225,6 +2273,7 @@ static BOOL TestingEnum_IsValidValue2(int32_t value) {
   XCTAssertEqual([array valueAtIndex:2], 63.);
   XCTAssertEqual([array valueAtIndex:3], 64.);
   XCTAssertEqual([array valueAtIndex:4], 61.);
+  [array2 release];
 }
 
 - (void)testInsert {
@@ -2257,6 +2306,7 @@ static BOOL TestingEnum_IsValidValue2(int32_t value) {
   XCTAssertEqual([array valueAtIndex:3], 62.);
   XCTAssertEqual([array valueAtIndex:4], 63.);
   XCTAssertEqual([array valueAtIndex:5], 64.);
+  [array release];
 }
 
 - (void)testRemove {
@@ -2293,6 +2343,7 @@ static BOOL TestingEnum_IsValidValue2(int32_t value) {
   XCTAssertEqual(array.count, 0U);
   XCTAssertThrowsSpecificNamed([array removeValueAtIndex:0],
                                NSException, NSRangeException);
+  [array release];
 }
 
 - (void)testInplaceMutation {
@@ -2331,6 +2382,7 @@ static BOOL TestingEnum_IsValidValue2(int32_t value) {
                                NSException, NSRangeException);
   XCTAssertThrowsSpecificNamed([array exchangeValueAtIndex:1 withValueAtIndex:4],
                                NSException, NSRangeException);
+  [array release];
 }
 
 - (void)testInternalResizing {
@@ -2355,6 +2407,7 @@ static BOOL TestingEnum_IsValidValue2(int32_t value) {
   XCTAssertEqual(array.count, 404U);
   [array removeAll];
   XCTAssertEqual(array.count, 0U);
+  [array release];
 }
 
 @end
@@ -2508,6 +2561,8 @@ static BOOL TestingEnum_IsValidValue2(int32_t value) {
   // Should be new object but equal.
   XCTAssertNotEqual(array, array2);
   XCTAssertEqualObjects(array, array2);
+  [array2 release];
+  [array release];
 }
 
 - (void)testArrayFromArray {
@@ -2523,6 +2578,7 @@ static BOOL TestingEnum_IsValidValue2(int32_t value) {
   // Should be new pointer, but equal objects.
   XCTAssertNotEqual(array, array2);
   XCTAssertEqualObjects(array, array2);
+  [array release];
 }
 
 - (void)testAdds {
@@ -2550,6 +2606,7 @@ static BOOL TestingEnum_IsValidValue2(int32_t value) {
   XCTAssertEqual([array valueAtIndex:2], FALSE);
   XCTAssertEqual([array valueAtIndex:3], FALSE);
   XCTAssertEqual([array valueAtIndex:4], TRUE);
+  [array2 release];
 }
 
 - (void)testInsert {
@@ -2582,6 +2639,7 @@ static BOOL TestingEnum_IsValidValue2(int32_t value) {
   XCTAssertEqual([array valueAtIndex:3], TRUE);
   XCTAssertEqual([array valueAtIndex:4], FALSE);
   XCTAssertEqual([array valueAtIndex:5], FALSE);
+  [array release];
 }
 
 - (void)testRemove {
@@ -2618,6 +2676,7 @@ static BOOL TestingEnum_IsValidValue2(int32_t value) {
   XCTAssertEqual(array.count, 0U);
   XCTAssertThrowsSpecificNamed([array removeValueAtIndex:0],
                                NSException, NSRangeException);
+  [array release];
 }
 
 - (void)testInplaceMutation {
@@ -2656,6 +2715,7 @@ static BOOL TestingEnum_IsValidValue2(int32_t value) {
                                NSException, NSRangeException);
   XCTAssertThrowsSpecificNamed([array exchangeValueAtIndex:1 withValueAtIndex:4],
                                NSException, NSRangeException);
+  [array release];
 }
 
 - (void)testInternalResizing {
@@ -2680,6 +2740,7 @@ static BOOL TestingEnum_IsValidValue2(int32_t value) {
   XCTAssertEqual(array.count, 404U);
   [array removeAll];
   XCTAssertEqual(array.count, 0U);
+  [array release];
 }
 
 @end
@@ -2833,6 +2894,8 @@ static BOOL TestingEnum_IsValidValue2(int32_t value) {
   // Should be new object but equal.
   XCTAssertNotEqual(array, array2);
   XCTAssertEqualObjects(array, array2);
+  [array2 release];
+  [array release];
 }
 
 - (void)testArrayFromArray {
@@ -2848,6 +2911,7 @@ static BOOL TestingEnum_IsValidValue2(int32_t value) {
   // Should be new pointer, but equal objects.
   XCTAssertNotEqual(array, array2);
   XCTAssertEqualObjects(array, array2);
+  [array release];
 }
 
 - (void)testAdds {
@@ -2875,6 +2939,7 @@ static BOOL TestingEnum_IsValidValue2(int32_t value) {
   XCTAssertEqual([array valueAtIndex:2], 73);
   XCTAssertEqual([array valueAtIndex:3], 74);
   XCTAssertEqual([array valueAtIndex:4], 71);
+  [array2 release];
 }
 
 - (void)testInsert {
@@ -2907,6 +2972,7 @@ static BOOL TestingEnum_IsValidValue2(int32_t value) {
   XCTAssertEqual([array valueAtIndex:3], 72);
   XCTAssertEqual([array valueAtIndex:4], 73);
   XCTAssertEqual([array valueAtIndex:5], 74);
+  [array release];
 }
 
 - (void)testRemove {
@@ -2943,6 +3009,7 @@ static BOOL TestingEnum_IsValidValue2(int32_t value) {
   XCTAssertEqual(array.count, 0U);
   XCTAssertThrowsSpecificNamed([array removeValueAtIndex:0],
                                NSException, NSRangeException);
+  [array release];
 }
 
 - (void)testInplaceMutation {
@@ -2981,6 +3048,7 @@ static BOOL TestingEnum_IsValidValue2(int32_t value) {
                                NSException, NSRangeException);
   XCTAssertThrowsSpecificNamed([array exchangeValueAtIndex:1 withValueAtIndex:4],
                                NSException, NSRangeException);
+  [array release];
 }
 
 - (void)testInternalResizing {
@@ -3005,6 +3073,7 @@ static BOOL TestingEnum_IsValidValue2(int32_t value) {
   XCTAssertEqual(array.count, 404U);
   [array removeAll];
   XCTAssertEqual(array.count, 0U);
+  [array release];
 }
 
 @end
@@ -3165,6 +3234,8 @@ static BOOL TestingEnum_IsValidValue2(int32_t value) {
   XCTAssertEqual([array2 rawValueAtIndex:1], 72);
   XCTAssertEqual([array2 rawValueAtIndex:2], 1000);
   XCTAssertEqual([array2 valueAtIndex:2], kGPBUnrecognizedEnumeratorValue);
+  [array2 release];
+  [array release];
 }
 
 - (void)testArrayFromArray {
@@ -3182,6 +3253,7 @@ static BOOL TestingEnum_IsValidValue2(int32_t value) {
   XCTAssertNotEqual(array, array2);
   XCTAssertEqualObjects(array, array2);
   XCTAssertEqual(array.validationFunc, array2.validationFunc);
+  [array release];
 }
 
 - (void)testUnknownAdds {
@@ -3197,7 +3269,6 @@ static BOOL TestingEnum_IsValidValue2(int32_t value) {
   XCTAssertThrowsSpecificNamed([array addValues:kValues1 count:GPBARRAYSIZE(kValues1)],
                                NSException, NSInvalidArgumentException);
   XCTAssertEqual(array.count, 0U);
-
   [array release];
 }
 
@@ -3229,7 +3300,6 @@ static BOOL TestingEnum_IsValidValue2(int32_t value) {
   XCTAssertEqual([array valueAtIndex:2], kGPBUnrecognizedEnumeratorValue);
   XCTAssertEqual([array rawValueAtIndex:3], 74);
   XCTAssertEqual([array rawValueAtIndex:4], 71);
-
   [array release];
 }
 
@@ -3256,6 +3326,7 @@ static BOOL TestingEnum_IsValidValue2(int32_t value) {
   XCTAssertThrowsSpecificNamed([array insertValue:374 atIndex:3],
                                NSException, NSInvalidArgumentException);
   XCTAssertEqual(array.count, 3U);
+  [array release];
 }
 
 - (void)testRawInsert {
@@ -3292,7 +3363,6 @@ static BOOL TestingEnum_IsValidValue2(int32_t value) {
   XCTAssertEqual([array rawValueAtIndex:4], 73);
   XCTAssertEqual([array rawValueAtIndex:5], 374);
   XCTAssertEqual([array valueAtIndex:5], kGPBUnrecognizedEnumeratorValue);
-
   [array release];
 }
 
@@ -3313,6 +3383,7 @@ static BOOL TestingEnum_IsValidValue2(int32_t value) {
   XCTAssertEqual([array valueAtIndex:1], 72);
   XCTAssertEqual([array valueAtIndex:2], 73);
   XCTAssertEqual([array valueAtIndex:3], 74);
+  [array release];
 }
 
 
@@ -3336,6 +3407,7 @@ static BOOL TestingEnum_IsValidValue2(int32_t value) {
 
   XCTAssertThrowsSpecificNamed([array replaceValueAtIndex:4 withRawValue:74],
                                NSException, NSRangeException);
+  [array release];
 }
 
 - (void)testRawInternalResizing {
@@ -3360,6 +3432,7 @@ static BOOL TestingEnum_IsValidValue2(int32_t value) {
   XCTAssertEqual(array.count, 404U);
   [array removeAll];
   XCTAssertEqual(array.count, 0U);
+  [array release];
 }
 
 @end

+ 7 - 5
objectivec/Tests/GPBCodedInputStreamTests.m

@@ -184,7 +184,7 @@
   XCTAssertEqual(message.serializedSize, (size_t)rawBytes.length);
 
   TestAllTypes* message2 =
-      [TestAllTypes parseFromData:rawBytes extensionRegistry:nil];
+      [TestAllTypes parseFromData:rawBytes extensionRegistry:nil error:NULL];
   [self assertAllFieldsSet:message2 repeatedCount:kGPBDefaultRepeatCount];
 }
 
@@ -227,8 +227,9 @@
   // reading.
   GPBCodedInputStream* stream =
       [GPBCodedInputStream streamWithData:message.data];
-  TestAllTypes* message2 =
-      [TestAllTypes parseFromCodedInputStream:stream extensionRegistry:nil];
+  TestAllTypes* message2 = [TestAllTypes parseFromCodedInputStream:stream
+                                                 extensionRegistry:nil
+                                                             error:NULL];
 
   XCTAssertEqualObjects(message.optionalBytes, message2.optionalBytes);
 
@@ -280,8 +281,9 @@
   NSData* data =
       [rawOutput propertyForKey:NSStreamDataWrittenToMemoryStreamKey];
   GPBCodedInputStream* input = [GPBCodedInputStream streamWithData:data];
-  TestAllTypes* message =
-      [TestAllTypes parseFromCodedInputStream:input extensionRegistry:nil];
+  TestAllTypes* message = [TestAllTypes parseFromCodedInputStream:input
+                                                extensionRegistry:nil
+                                                            error:NULL];
   // Make sure we can read string properties twice without crashing.
   XCTAssertEqual([message.defaultString length], (NSUInteger)0);
   XCTAssertEqualObjects(@"", message.defaultString);

+ 48 - 0
objectivec/Tests/GPBConcurrencyTests.m

@@ -31,10 +31,16 @@
 #import "GPBTestUtilities.h"
 
 #import "google/protobuf/Unittest.pbobjc.h"
+#import "google/protobuf/UnittestObjc.pbobjc.h"
 
 static const int kNumThreads = 100;
 static const int kNumMessages = 100;
 
+// NOTE: Most of these tests don't "fail" in the sense that the XCTAsserts
+// trip.  Rather, the asserts simply exercise the apis, and if there is
+// a concurancy issue, the NSAsserts in the runtime code fire and/or the
+// code just crashes outright.
+
 @interface ConcurrencyTests : GPBTestCase
 @end
 
@@ -132,6 +138,48 @@ static const int kNumMessages = 100;
   }
 }
 
+- (void)readInt32Int32Map:(NSArray *)messages {
+  for (int i = 0; i < 10; i++) {
+    for (TestRecursiveMessageWithRepeatedField *message in messages) {
+      XCTAssertEqual([message.iToI count], (NSUInteger)0);
+    }
+  }
+}
+
+- (void)testConcurrentReadOfUnsetInt32Int32MapField {
+  NSArray *messages =
+      [self createMessagesWithType:[TestRecursiveMessageWithRepeatedField class]];
+  NSArray *threads =
+      [self createThreadsWithSelector:@selector(readInt32Int32Map:)
+                               object:messages];
+  [self startThreads:threads];
+  [self joinThreads:threads];
+  for (TestRecursiveMessageWithRepeatedField *message in messages) {
+    XCTAssertEqual([message.iToI count], (NSUInteger)0);
+  }
+}
+
+- (void)readStringStringMap:(NSArray *)messages {
+  for (int i = 0; i < 10; i++) {
+    for (TestRecursiveMessageWithRepeatedField *message in messages) {
+      XCTAssertEqual([message.strToStr count], (NSUInteger)0);
+    }
+  }
+}
+
+- (void)testConcurrentReadOfUnsetStringStringMapField {
+  NSArray *messages =
+      [self createMessagesWithType:[TestRecursiveMessageWithRepeatedField class]];
+  NSArray *threads =
+      [self createThreadsWithSelector:@selector(readStringStringMap:)
+                               object:messages];
+  [self startThreads:threads];
+  [self joinThreads:threads];
+  for (TestRecursiveMessageWithRepeatedField *message in messages) {
+    XCTAssertEqual([message.strToStr count], (NSUInteger)0);
+  }
+}
+
 - (void)readOptionalForeignMessageExtension:(NSArray *)messages {
   for (int i = 0; i < 10; i++) {
     for (TestAllExtensions *message in messages) {

+ 1 - 4
objectivec/Tests/GPBDictionaryTests+Bool.m

@@ -33,12 +33,9 @@
 
 #import "GPBDictionary.h"
 
+#import "GPBTestUtilities.h"
 #import "google/protobuf/UnittestRuntimeProto2.pbobjc.h"
 
-#ifndef GPBARRAYSIZE
-#define GPBARRAYSIZE(a) ((sizeof(a) / sizeof((a[0]))))
-#endif  // GPBARRAYSIZE
-
 // Pull in the macros (using an external file because expanding all tests
 // in a single file makes a file that is failing to work with within Xcode.
 //%PDDM-IMPORT-DEFINES GPBDictionaryTests.pddm

+ 1 - 4
objectivec/Tests/GPBDictionaryTests+Int32.m

@@ -33,6 +33,7 @@
 
 #import "GPBDictionary.h"
 
+#import "GPBTestUtilities.h"
 #import "google/protobuf/UnittestRuntimeProto2.pbobjc.h"
 
 // Pull in the macros (using an external file because expanding all tests
@@ -42,10 +43,6 @@
 //%PDDM-EXPAND TEST_FOR_POD_KEY(Int32, int32_t, 11, 12, 13, 14)
 // This block of code is generated, do not edit it directly.
 
-#ifndef GPBARRAYSIZE
-#define GPBARRAYSIZE(a) ((sizeof(a) / sizeof((a[0]))))
-#endif  // GPBARRAYSIZE
-
 // To let the testing macros work, add some extra methods to simplify things.
 @interface GPBInt32EnumDictionary (TestingTweak)
 + (instancetype)dictionaryWithValue:(int32_t)value forKey:(int32_t)key;

+ 1 - 4
objectivec/Tests/GPBDictionaryTests+Int64.m

@@ -33,6 +33,7 @@
 
 #import "GPBDictionary.h"
 
+#import "GPBTestUtilities.h"
 #import "google/protobuf/UnittestRuntimeProto2.pbobjc.h"
 
 // Pull in the macros (using an external file because expanding all tests
@@ -42,10 +43,6 @@
 //%PDDM-EXPAND TEST_FOR_POD_KEY(Int64, int64_t, 21LL, 22LL, 23LL, 24LL)
 // This block of code is generated, do not edit it directly.
 
-#ifndef GPBARRAYSIZE
-#define GPBARRAYSIZE(a) ((sizeof(a) / sizeof((a[0]))))
-#endif  // GPBARRAYSIZE
-
 // To let the testing macros work, add some extra methods to simplify things.
 @interface GPBInt64EnumDictionary (TestingTweak)
 + (instancetype)dictionaryWithValue:(int32_t)value forKey:(int64_t)key;

+ 1 - 4
objectivec/Tests/GPBDictionaryTests+String.m

@@ -33,6 +33,7 @@
 
 #import "GPBDictionary.h"
 
+#import "GPBTestUtilities.h"
 #import "google/protobuf/UnittestRuntimeProto2.pbobjc.h"
 
 // Pull in the macros (using an external file because expanding all tests
@@ -42,10 +43,6 @@
 //%PDDM-EXPAND TESTS_FOR_POD_VALUES(String, NSString, *, Objects, @"foo", @"bar", @"baz", @"mumble")
 // This block of code is generated, do not edit it directly.
 
-#ifndef GPBARRAYSIZE
-#define GPBARRAYSIZE(a) ((sizeof(a) / sizeof((a[0]))))
-#endif  // GPBARRAYSIZE
-
 // To let the testing macros work, add some extra methods to simplify things.
 @interface GPBStringEnumDictionary (TestingTweak)
 + (instancetype)dictionaryWithValue:(int32_t)value forKey:(NSString *)key;

+ 1 - 4
objectivec/Tests/GPBDictionaryTests+UInt32.m

@@ -33,6 +33,7 @@
 
 #import "GPBDictionary.h"
 
+#import "GPBTestUtilities.h"
 #import "google/protobuf/UnittestRuntimeProto2.pbobjc.h"
 
 // Pull in the macros (using an external file because expanding all tests
@@ -42,10 +43,6 @@
 //%PDDM-EXPAND TEST_FOR_POD_KEY(UInt32, uint32_t, 1U, 2U, 3U, 4U)
 // This block of code is generated, do not edit it directly.
 
-#ifndef GPBARRAYSIZE
-#define GPBARRAYSIZE(a) ((sizeof(a) / sizeof((a[0]))))
-#endif  // GPBARRAYSIZE
-
 // To let the testing macros work, add some extra methods to simplify things.
 @interface GPBUInt32EnumDictionary (TestingTweak)
 + (instancetype)dictionaryWithValue:(int32_t)value forKey:(uint32_t)key;

+ 1 - 4
objectivec/Tests/GPBDictionaryTests+UInt64.m

@@ -33,6 +33,7 @@
 
 #import "GPBDictionary.h"
 
+#import "GPBTestUtilities.h"
 #import "google/protobuf/UnittestRuntimeProto2.pbobjc.h"
 
 // Pull in the macros (using an external file because expanding all tests
@@ -42,10 +43,6 @@
 //%PDDM-EXPAND TEST_FOR_POD_KEY(UInt64, uint64_t, 31ULL, 32ULL, 33ULL, 34ULL)
 // This block of code is generated, do not edit it directly.
 
-#ifndef GPBARRAYSIZE
-#define GPBARRAYSIZE(a) ((sizeof(a) / sizeof((a[0]))))
-#endif  // GPBARRAYSIZE
-
 // To let the testing macros work, add some extra methods to simplify things.
 @interface GPBUInt64EnumDictionary (TestingTweak)
 + (instancetype)dictionaryWithValue:(int32_t)value forKey:(uint64_t)key;

+ 0 - 4
objectivec/Tests/GPBDictionaryTests.pddm

@@ -720,10 +720,6 @@
 //
 
 //%PDDM-DEFINE TEST_HELPERS(KEY_NAME, KEY_TYPE, KisP)
-//%#ifndef GPBARRAYSIZE
-//%#define GPBARRAYSIZE(a) ((sizeof(a) / sizeof((a[0]))))
-//%#endif  // GPBARRAYSIZE
-//%
 //%// To let the testing macros work, add some extra methods to simplify things.
 //%@interface GPB##KEY_NAME##EnumDictionary (TestingTweak)
 //%+ (instancetype)dictionaryWithValue:(int32_t)value forKey:(KEY_TYPE##KisP$S##KisP)key;

+ 3 - 2
objectivec/Tests/GPBMessageTests+Merge.m

@@ -35,6 +35,7 @@
 #import "GPBMessage.h"
 
 #import "google/protobuf/MapUnittest.pbobjc.h"
+#import "google/protobuf/Unittest.pbobjc.h"
 #import "google/protobuf/UnittestPreserveUnknownEnum.pbobjc.h"
 #import "google/protobuf/UnittestRuntimeProto2.pbobjc.h"
 #import "google/protobuf/UnittestRuntimeProto3.pbobjc.h"
@@ -431,7 +432,7 @@
   XCTAssertNotNil(dst.oneofGroup);
   XCTAssertNotEqual(dst.oneofGroup, mergedGroup);  // Pointer comparision.
 
-  // Back to something else ot make sure message clears out ok.
+  // Back to something else to make sure message clears out ok.
 
   src.oneofInt32 = 10;
   [dst mergeFrom:src];
@@ -640,7 +641,7 @@
   XCTAssertEqualObjects(mergedSubMessage, subMessage);
   XCTAssertEqualObjects(dst.oneofBytes, oneofBytesDefault);
 
-  // Back to something else ot make sure message clears out ok.
+  // Back to something else to make sure message clears out ok.
 
   src.oneofInt32 = 10;
   [dst mergeFrom:src];

+ 7 - 4
objectivec/Tests/GPBMessageTests+Runtime.m

@@ -35,6 +35,7 @@
 #import "GPBMessage.h"
 
 #import "google/protobuf/MapUnittest.pbobjc.h"
+#import "google/protobuf/Unittest.pbobjc.h"
 #import "google/protobuf/UnittestRuntimeProto2.pbobjc.h"
 #import "google/protobuf/UnittestRuntimeProto3.pbobjc.h"
 
@@ -772,6 +773,8 @@
   XCTAssertThrowsSpecificNamed(msg.oneofEnum = 666, NSException,
                                NSInvalidArgumentException);
   XCTAssertEqual(msg.oneofEnum, Message2_Enum_Bar);
+
+  [msg release];
 }
 
 - (void)testAccessingProto3UnknownEnumValues {
@@ -1261,7 +1264,7 @@
     Message2_O_OneOfCase_OneofEnum,
   };
 
-  for (size_t i = 0; i < (sizeof(values) / sizeof((values[0]))); ++i) {
+  for (size_t i = 0; i < GPBARRAYSIZE(values); ++i) {
     switch (values[i]) {
       case Message2_O_OneOfCase_OneofInt32:
         msg.oneofInt32 = 1;
@@ -1318,7 +1321,7 @@
         msg.oneofEnum = Message2_Enum_Bar;
         break;
       default:
-        XCTFail(@"shouldn't happen, loop: %zd", i);
+        XCTFail(@"shouldn't happen, loop: %zd, value: %d", i, values[i]);
         break;
     }
 
@@ -1770,7 +1773,7 @@
     Message3_O_OneOfCase_OneofEnum,
   };
 
-  for (size_t i = 0; i < (sizeof(values) / sizeof((values[0]))); ++i) {
+  for (size_t i = 0; i < GPBARRAYSIZE(values); ++i) {
     switch (values[i]) {
       case Message3_O_OneOfCase_OneofInt32:
         msg.oneofInt32 = 1;
@@ -1824,7 +1827,7 @@
         msg.oneofEnum = Message3_Enum_Baz;
         break;
       default:
-        XCTFail(@"shouldn't happen, loop: %zd", i);
+        XCTFail(@"shouldn't happen, loop: %zd, value: %d", i, values[i]);
         break;
     }
 

+ 126 - 57
objectivec/Tests/GPBMessageTests+Serialization.m

@@ -41,10 +41,6 @@
 #import "google/protobuf/UnittestRuntimeProto2.pbobjc.h"
 #import "google/protobuf/UnittestRuntimeProto3.pbobjc.h"
 
-#ifndef GPBARRAYSIZE
-#define GPBARRAYSIZE(a) ((sizeof(a) / sizeof((a[0]))))
-#endif  // GPBARRAYSIZE
-
 static NSData *DataFromCStr(const char *str) {
   return [NSData dataWithBytes:str length:strlen(str)];
 }
@@ -124,7 +120,8 @@ static NSData *DataFromCStr(const char *str) {
   fooWithExtras.enumValue = DropUnknownsFooWithExtraFields_NestedEnum_Baz;
   fooWithExtras.extraInt32Value = 2;
 
-  DropUnknownsFoo *foo = [DropUnknownsFoo parseFromData:[fooWithExtras data]];
+  DropUnknownsFoo *foo =
+      [DropUnknownsFoo parseFromData:[fooWithExtras data] error:NULL];
 
   XCTAssertEqual(foo.int32Value, 1);
   XCTAssertEqual(foo.enumValue, DropUnknownsFoo_NestedEnum_Baz);
@@ -132,7 +129,8 @@ static NSData *DataFromCStr(const char *str) {
   XCTAssertEqual([foo.unknownFields countOfFields], 0U);
 
   [fooWithExtras release];
-  fooWithExtras = [DropUnknownsFooWithExtraFields parseFromData:[foo data]];
+  fooWithExtras =
+      [DropUnknownsFooWithExtraFields parseFromData:[foo data] error:NULL];
   XCTAssertEqual(fooWithExtras.int32Value, 1);
   XCTAssertEqual(fooWithExtras.enumValue,
                  DropUnknownsFooWithExtraFields_NestedEnum_Baz);
@@ -153,7 +151,7 @@ static NSData *DataFromCStr(const char *str) {
                                        rawValue:Message3_Enum_Extra3];
   orig.oneofEnum = Message3_Enum_Extra3;
 
-  Message2 *msg = [[Message2 alloc] initWithData:[orig data]];
+  Message2 *msg = [[Message2 alloc] initWithData:[orig data] error:NULL];
 
   // None of the fields should be set.
 
@@ -214,7 +212,7 @@ static NSData *DataFromCStr(const char *str) {
   // Everything should be there via raw values.
 
   UnknownEnumsMyMessage *msg =
-      [UnknownEnumsMyMessage parseFromData:[orig data]];
+      [UnknownEnumsMyMessage parseFromData:[orig data] error:NULL];
 
   XCTAssertEqual(msg.e, UnknownEnumsMyEnum_GPBUnrecognizedEnumeratorValue);
   XCTAssertEqual(UnknownEnumsMyMessage_E_RawValue(msg),
@@ -236,7 +234,7 @@ static NSData *DataFromCStr(const char *str) {
 
   // Everything should go out and come back.
 
-  orig = [UnknownEnumsMyMessagePlusExtra parseFromData:[msg data]];
+  orig = [UnknownEnumsMyMessagePlusExtra parseFromData:[msg data] error:NULL];
 
   XCTAssertEqual(orig.e, UnknownEnumsMyEnumPlusExtra_EExtra);
   XCTAssertEqual(orig.repeatedEArray.count, 1U);
@@ -255,7 +253,7 @@ static NSData *DataFromCStr(const char *str) {
 //%    MESSAGE *orig = [[MESSAGE alloc] init];
 //%    orig.oneof##FIELD = VALUE;
 //%    XCTAssertEqual(orig.oOneOfCase, MESSAGE##_O_OneOfCase_Oneof##FIELD);
-//%    MESSAGE *msg = [MESSAGE parseFromData:[orig data]];
+//%    MESSAGE *msg = [MESSAGE parseFromData:[orig data] error:NULL];
 //%    XCTAssertEqual(msg.oOneOfCase, MESSAGE##_O_OneOfCase_Oneof##FIELD);
 //%    XCTAssertEqual##EQ_SUFFIX(msg.oneof##FIELD, VALUE);
 //%    [orig release];
@@ -323,7 +321,7 @@ static NSData *DataFromCStr(const char *str) {
     Message2 *orig = [[Message2 alloc] init];
     orig.oneofInt32 = 1;
     XCTAssertEqual(orig.oOneOfCase, Message2_O_OneOfCase_OneofInt32);
-    Message2 *msg = [Message2 parseFromData:[orig data]];
+    Message2 *msg = [Message2 parseFromData:[orig data] error:NULL];
     XCTAssertEqual(msg.oOneOfCase, Message2_O_OneOfCase_OneofInt32);
     XCTAssertEqual(msg.oneofInt32, 1);
     [orig release];
@@ -333,7 +331,7 @@ static NSData *DataFromCStr(const char *str) {
     Message2 *orig = [[Message2 alloc] init];
     orig.oneofInt64 = 2;
     XCTAssertEqual(orig.oOneOfCase, Message2_O_OneOfCase_OneofInt64);
-    Message2 *msg = [Message2 parseFromData:[orig data]];
+    Message2 *msg = [Message2 parseFromData:[orig data] error:NULL];
     XCTAssertEqual(msg.oOneOfCase, Message2_O_OneOfCase_OneofInt64);
     XCTAssertEqual(msg.oneofInt64, 2);
     [orig release];
@@ -343,7 +341,7 @@ static NSData *DataFromCStr(const char *str) {
     Message2 *orig = [[Message2 alloc] init];
     orig.oneofUint32 = 3U;
     XCTAssertEqual(orig.oOneOfCase, Message2_O_OneOfCase_OneofUint32);
-    Message2 *msg = [Message2 parseFromData:[orig data]];
+    Message2 *msg = [Message2 parseFromData:[orig data] error:NULL];
     XCTAssertEqual(msg.oOneOfCase, Message2_O_OneOfCase_OneofUint32);
     XCTAssertEqual(msg.oneofUint32, 3U);
     [orig release];
@@ -353,7 +351,7 @@ static NSData *DataFromCStr(const char *str) {
     Message2 *orig = [[Message2 alloc] init];
     orig.oneofUint64 = 4U;
     XCTAssertEqual(orig.oOneOfCase, Message2_O_OneOfCase_OneofUint64);
-    Message2 *msg = [Message2 parseFromData:[orig data]];
+    Message2 *msg = [Message2 parseFromData:[orig data] error:NULL];
     XCTAssertEqual(msg.oOneOfCase, Message2_O_OneOfCase_OneofUint64);
     XCTAssertEqual(msg.oneofUint64, 4U);
     [orig release];
@@ -363,7 +361,7 @@ static NSData *DataFromCStr(const char *str) {
     Message2 *orig = [[Message2 alloc] init];
     orig.oneofSint32 = 5;
     XCTAssertEqual(orig.oOneOfCase, Message2_O_OneOfCase_OneofSint32);
-    Message2 *msg = [Message2 parseFromData:[orig data]];
+    Message2 *msg = [Message2 parseFromData:[orig data] error:NULL];
     XCTAssertEqual(msg.oOneOfCase, Message2_O_OneOfCase_OneofSint32);
     XCTAssertEqual(msg.oneofSint32, 5);
     [orig release];
@@ -373,7 +371,7 @@ static NSData *DataFromCStr(const char *str) {
     Message2 *orig = [[Message2 alloc] init];
     orig.oneofSint64 = 6;
     XCTAssertEqual(orig.oOneOfCase, Message2_O_OneOfCase_OneofSint64);
-    Message2 *msg = [Message2 parseFromData:[orig data]];
+    Message2 *msg = [Message2 parseFromData:[orig data] error:NULL];
     XCTAssertEqual(msg.oOneOfCase, Message2_O_OneOfCase_OneofSint64);
     XCTAssertEqual(msg.oneofSint64, 6);
     [orig release];
@@ -383,7 +381,7 @@ static NSData *DataFromCStr(const char *str) {
     Message2 *orig = [[Message2 alloc] init];
     orig.oneofFixed32 = 7U;
     XCTAssertEqual(orig.oOneOfCase, Message2_O_OneOfCase_OneofFixed32);
-    Message2 *msg = [Message2 parseFromData:[orig data]];
+    Message2 *msg = [Message2 parseFromData:[orig data] error:NULL];
     XCTAssertEqual(msg.oOneOfCase, Message2_O_OneOfCase_OneofFixed32);
     XCTAssertEqual(msg.oneofFixed32, 7U);
     [orig release];
@@ -393,7 +391,7 @@ static NSData *DataFromCStr(const char *str) {
     Message2 *orig = [[Message2 alloc] init];
     orig.oneofFixed64 = 8U;
     XCTAssertEqual(orig.oOneOfCase, Message2_O_OneOfCase_OneofFixed64);
-    Message2 *msg = [Message2 parseFromData:[orig data]];
+    Message2 *msg = [Message2 parseFromData:[orig data] error:NULL];
     XCTAssertEqual(msg.oOneOfCase, Message2_O_OneOfCase_OneofFixed64);
     XCTAssertEqual(msg.oneofFixed64, 8U);
     [orig release];
@@ -403,7 +401,7 @@ static NSData *DataFromCStr(const char *str) {
     Message2 *orig = [[Message2 alloc] init];
     orig.oneofSfixed32 = 9;
     XCTAssertEqual(orig.oOneOfCase, Message2_O_OneOfCase_OneofSfixed32);
-    Message2 *msg = [Message2 parseFromData:[orig data]];
+    Message2 *msg = [Message2 parseFromData:[orig data] error:NULL];
     XCTAssertEqual(msg.oOneOfCase, Message2_O_OneOfCase_OneofSfixed32);
     XCTAssertEqual(msg.oneofSfixed32, 9);
     [orig release];
@@ -413,7 +411,7 @@ static NSData *DataFromCStr(const char *str) {
     Message2 *orig = [[Message2 alloc] init];
     orig.oneofSfixed64 = 10;
     XCTAssertEqual(orig.oOneOfCase, Message2_O_OneOfCase_OneofSfixed64);
-    Message2 *msg = [Message2 parseFromData:[orig data]];
+    Message2 *msg = [Message2 parseFromData:[orig data] error:NULL];
     XCTAssertEqual(msg.oOneOfCase, Message2_O_OneOfCase_OneofSfixed64);
     XCTAssertEqual(msg.oneofSfixed64, 10);
     [orig release];
@@ -423,7 +421,7 @@ static NSData *DataFromCStr(const char *str) {
     Message2 *orig = [[Message2 alloc] init];
     orig.oneofFloat = 11.0f;
     XCTAssertEqual(orig.oOneOfCase, Message2_O_OneOfCase_OneofFloat);
-    Message2 *msg = [Message2 parseFromData:[orig data]];
+    Message2 *msg = [Message2 parseFromData:[orig data] error:NULL];
     XCTAssertEqual(msg.oOneOfCase, Message2_O_OneOfCase_OneofFloat);
     XCTAssertEqual(msg.oneofFloat, 11.0f);
     [orig release];
@@ -433,7 +431,7 @@ static NSData *DataFromCStr(const char *str) {
     Message2 *orig = [[Message2 alloc] init];
     orig.oneofDouble = 12.0;
     XCTAssertEqual(orig.oOneOfCase, Message2_O_OneOfCase_OneofDouble);
-    Message2 *msg = [Message2 parseFromData:[orig data]];
+    Message2 *msg = [Message2 parseFromData:[orig data] error:NULL];
     XCTAssertEqual(msg.oOneOfCase, Message2_O_OneOfCase_OneofDouble);
     XCTAssertEqual(msg.oneofDouble, 12.0);
     [orig release];
@@ -443,7 +441,7 @@ static NSData *DataFromCStr(const char *str) {
     Message2 *orig = [[Message2 alloc] init];
     orig.oneofBool = NO;
     XCTAssertEqual(orig.oOneOfCase, Message2_O_OneOfCase_OneofBool);
-    Message2 *msg = [Message2 parseFromData:[orig data]];
+    Message2 *msg = [Message2 parseFromData:[orig data] error:NULL];
     XCTAssertEqual(msg.oOneOfCase, Message2_O_OneOfCase_OneofBool);
     XCTAssertEqual(msg.oneofBool, NO);
     [orig release];
@@ -453,7 +451,7 @@ static NSData *DataFromCStr(const char *str) {
     Message2 *orig = [[Message2 alloc] init];
     orig.oneofString = @"foo";
     XCTAssertEqual(orig.oOneOfCase, Message2_O_OneOfCase_OneofString);
-    Message2 *msg = [Message2 parseFromData:[orig data]];
+    Message2 *msg = [Message2 parseFromData:[orig data] error:NULL];
     XCTAssertEqual(msg.oOneOfCase, Message2_O_OneOfCase_OneofString);
     XCTAssertEqualObjects(msg.oneofString, @"foo");
     [orig release];
@@ -463,7 +461,7 @@ static NSData *DataFromCStr(const char *str) {
     Message2 *orig = [[Message2 alloc] init];
     orig.oneofBytes = [@"bar" dataUsingEncoding:NSUTF8StringEncoding];
     XCTAssertEqual(orig.oOneOfCase, Message2_O_OneOfCase_OneofBytes);
-    Message2 *msg = [Message2 parseFromData:[orig data]];
+    Message2 *msg = [Message2 parseFromData:[orig data] error:NULL];
     XCTAssertEqual(msg.oOneOfCase, Message2_O_OneOfCase_OneofBytes);
     XCTAssertEqualObjects(msg.oneofBytes, [@"bar" dataUsingEncoding:NSUTF8StringEncoding]);
     [orig release];
@@ -473,7 +471,7 @@ static NSData *DataFromCStr(const char *str) {
     Message2 *orig = [[Message2 alloc] init];
     orig.oneofGroup = group;
     XCTAssertEqual(orig.oOneOfCase, Message2_O_OneOfCase_OneofGroup);
-    Message2 *msg = [Message2 parseFromData:[orig data]];
+    Message2 *msg = [Message2 parseFromData:[orig data] error:NULL];
     XCTAssertEqual(msg.oOneOfCase, Message2_O_OneOfCase_OneofGroup);
     XCTAssertEqualObjects(msg.oneofGroup, group);
     [orig release];
@@ -483,7 +481,7 @@ static NSData *DataFromCStr(const char *str) {
     Message2 *orig = [[Message2 alloc] init];
     orig.oneofMessage = subMessage;
     XCTAssertEqual(orig.oOneOfCase, Message2_O_OneOfCase_OneofMessage);
-    Message2 *msg = [Message2 parseFromData:[orig data]];
+    Message2 *msg = [Message2 parseFromData:[orig data] error:NULL];
     XCTAssertEqual(msg.oOneOfCase, Message2_O_OneOfCase_OneofMessage);
     XCTAssertEqualObjects(msg.oneofMessage, subMessage);
     [orig release];
@@ -493,7 +491,7 @@ static NSData *DataFromCStr(const char *str) {
     Message2 *orig = [[Message2 alloc] init];
     orig.oneofEnum = Message2_Enum_Bar;
     XCTAssertEqual(orig.oOneOfCase, Message2_O_OneOfCase_OneofEnum);
-    Message2 *msg = [Message2 parseFromData:[orig data]];
+    Message2 *msg = [Message2 parseFromData:[orig data] error:NULL];
     XCTAssertEqual(msg.oOneOfCase, Message2_O_OneOfCase_OneofEnum);
     XCTAssertEqual(msg.oneofEnum, Message2_Enum_Bar);
     [orig release];
@@ -516,7 +514,7 @@ static NSData *DataFromCStr(const char *str) {
     Message3 *orig = [[Message3 alloc] init];
     orig.oneofInt32 = 1;
     XCTAssertEqual(orig.oOneOfCase, Message3_O_OneOfCase_OneofInt32);
-    Message3 *msg = [Message3 parseFromData:[orig data]];
+    Message3 *msg = [Message3 parseFromData:[orig data] error:NULL];
     XCTAssertEqual(msg.oOneOfCase, Message3_O_OneOfCase_OneofInt32);
     XCTAssertEqual(msg.oneofInt32, 1);
     [orig release];
@@ -526,7 +524,7 @@ static NSData *DataFromCStr(const char *str) {
     Message3 *orig = [[Message3 alloc] init];
     orig.oneofInt64 = 2;
     XCTAssertEqual(orig.oOneOfCase, Message3_O_OneOfCase_OneofInt64);
-    Message3 *msg = [Message3 parseFromData:[orig data]];
+    Message3 *msg = [Message3 parseFromData:[orig data] error:NULL];
     XCTAssertEqual(msg.oOneOfCase, Message3_O_OneOfCase_OneofInt64);
     XCTAssertEqual(msg.oneofInt64, 2);
     [orig release];
@@ -536,7 +534,7 @@ static NSData *DataFromCStr(const char *str) {
     Message3 *orig = [[Message3 alloc] init];
     orig.oneofUint32 = 3U;
     XCTAssertEqual(orig.oOneOfCase, Message3_O_OneOfCase_OneofUint32);
-    Message3 *msg = [Message3 parseFromData:[orig data]];
+    Message3 *msg = [Message3 parseFromData:[orig data] error:NULL];
     XCTAssertEqual(msg.oOneOfCase, Message3_O_OneOfCase_OneofUint32);
     XCTAssertEqual(msg.oneofUint32, 3U);
     [orig release];
@@ -546,7 +544,7 @@ static NSData *DataFromCStr(const char *str) {
     Message3 *orig = [[Message3 alloc] init];
     orig.oneofUint64 = 4U;
     XCTAssertEqual(orig.oOneOfCase, Message3_O_OneOfCase_OneofUint64);
-    Message3 *msg = [Message3 parseFromData:[orig data]];
+    Message3 *msg = [Message3 parseFromData:[orig data] error:NULL];
     XCTAssertEqual(msg.oOneOfCase, Message3_O_OneOfCase_OneofUint64);
     XCTAssertEqual(msg.oneofUint64, 4U);
     [orig release];
@@ -556,7 +554,7 @@ static NSData *DataFromCStr(const char *str) {
     Message3 *orig = [[Message3 alloc] init];
     orig.oneofSint32 = 5;
     XCTAssertEqual(orig.oOneOfCase, Message3_O_OneOfCase_OneofSint32);
-    Message3 *msg = [Message3 parseFromData:[orig data]];
+    Message3 *msg = [Message3 parseFromData:[orig data] error:NULL];
     XCTAssertEqual(msg.oOneOfCase, Message3_O_OneOfCase_OneofSint32);
     XCTAssertEqual(msg.oneofSint32, 5);
     [orig release];
@@ -566,7 +564,7 @@ static NSData *DataFromCStr(const char *str) {
     Message3 *orig = [[Message3 alloc] init];
     orig.oneofSint64 = 6;
     XCTAssertEqual(orig.oOneOfCase, Message3_O_OneOfCase_OneofSint64);
-    Message3 *msg = [Message3 parseFromData:[orig data]];
+    Message3 *msg = [Message3 parseFromData:[orig data] error:NULL];
     XCTAssertEqual(msg.oOneOfCase, Message3_O_OneOfCase_OneofSint64);
     XCTAssertEqual(msg.oneofSint64, 6);
     [orig release];
@@ -576,7 +574,7 @@ static NSData *DataFromCStr(const char *str) {
     Message3 *orig = [[Message3 alloc] init];
     orig.oneofFixed32 = 7U;
     XCTAssertEqual(orig.oOneOfCase, Message3_O_OneOfCase_OneofFixed32);
-    Message3 *msg = [Message3 parseFromData:[orig data]];
+    Message3 *msg = [Message3 parseFromData:[orig data] error:NULL];
     XCTAssertEqual(msg.oOneOfCase, Message3_O_OneOfCase_OneofFixed32);
     XCTAssertEqual(msg.oneofFixed32, 7U);
     [orig release];
@@ -586,7 +584,7 @@ static NSData *DataFromCStr(const char *str) {
     Message3 *orig = [[Message3 alloc] init];
     orig.oneofFixed64 = 8U;
     XCTAssertEqual(orig.oOneOfCase, Message3_O_OneOfCase_OneofFixed64);
-    Message3 *msg = [Message3 parseFromData:[orig data]];
+    Message3 *msg = [Message3 parseFromData:[orig data] error:NULL];
     XCTAssertEqual(msg.oOneOfCase, Message3_O_OneOfCase_OneofFixed64);
     XCTAssertEqual(msg.oneofFixed64, 8U);
     [orig release];
@@ -596,7 +594,7 @@ static NSData *DataFromCStr(const char *str) {
     Message3 *orig = [[Message3 alloc] init];
     orig.oneofSfixed32 = 9;
     XCTAssertEqual(orig.oOneOfCase, Message3_O_OneOfCase_OneofSfixed32);
-    Message3 *msg = [Message3 parseFromData:[orig data]];
+    Message3 *msg = [Message3 parseFromData:[orig data] error:NULL];
     XCTAssertEqual(msg.oOneOfCase, Message3_O_OneOfCase_OneofSfixed32);
     XCTAssertEqual(msg.oneofSfixed32, 9);
     [orig release];
@@ -606,7 +604,7 @@ static NSData *DataFromCStr(const char *str) {
     Message3 *orig = [[Message3 alloc] init];
     orig.oneofSfixed64 = 10;
     XCTAssertEqual(orig.oOneOfCase, Message3_O_OneOfCase_OneofSfixed64);
-    Message3 *msg = [Message3 parseFromData:[orig data]];
+    Message3 *msg = [Message3 parseFromData:[orig data] error:NULL];
     XCTAssertEqual(msg.oOneOfCase, Message3_O_OneOfCase_OneofSfixed64);
     XCTAssertEqual(msg.oneofSfixed64, 10);
     [orig release];
@@ -616,7 +614,7 @@ static NSData *DataFromCStr(const char *str) {
     Message3 *orig = [[Message3 alloc] init];
     orig.oneofFloat = 11.0f;
     XCTAssertEqual(orig.oOneOfCase, Message3_O_OneOfCase_OneofFloat);
-    Message3 *msg = [Message3 parseFromData:[orig data]];
+    Message3 *msg = [Message3 parseFromData:[orig data] error:NULL];
     XCTAssertEqual(msg.oOneOfCase, Message3_O_OneOfCase_OneofFloat);
     XCTAssertEqual(msg.oneofFloat, 11.0f);
     [orig release];
@@ -626,7 +624,7 @@ static NSData *DataFromCStr(const char *str) {
     Message3 *orig = [[Message3 alloc] init];
     orig.oneofDouble = 12.0;
     XCTAssertEqual(orig.oOneOfCase, Message3_O_OneOfCase_OneofDouble);
-    Message3 *msg = [Message3 parseFromData:[orig data]];
+    Message3 *msg = [Message3 parseFromData:[orig data] error:NULL];
     XCTAssertEqual(msg.oOneOfCase, Message3_O_OneOfCase_OneofDouble);
     XCTAssertEqual(msg.oneofDouble, 12.0);
     [orig release];
@@ -636,7 +634,7 @@ static NSData *DataFromCStr(const char *str) {
     Message3 *orig = [[Message3 alloc] init];
     orig.oneofBool = YES;
     XCTAssertEqual(orig.oOneOfCase, Message3_O_OneOfCase_OneofBool);
-    Message3 *msg = [Message3 parseFromData:[orig data]];
+    Message3 *msg = [Message3 parseFromData:[orig data] error:NULL];
     XCTAssertEqual(msg.oOneOfCase, Message3_O_OneOfCase_OneofBool);
     XCTAssertEqual(msg.oneofBool, YES);
     [orig release];
@@ -646,7 +644,7 @@ static NSData *DataFromCStr(const char *str) {
     Message3 *orig = [[Message3 alloc] init];
     orig.oneofString = @"foo";
     XCTAssertEqual(orig.oOneOfCase, Message3_O_OneOfCase_OneofString);
-    Message3 *msg = [Message3 parseFromData:[orig data]];
+    Message3 *msg = [Message3 parseFromData:[orig data] error:NULL];
     XCTAssertEqual(msg.oOneOfCase, Message3_O_OneOfCase_OneofString);
     XCTAssertEqualObjects(msg.oneofString, @"foo");
     [orig release];
@@ -656,7 +654,7 @@ static NSData *DataFromCStr(const char *str) {
     Message3 *orig = [[Message3 alloc] init];
     orig.oneofBytes = [@"bar" dataUsingEncoding:NSUTF8StringEncoding];
     XCTAssertEqual(orig.oOneOfCase, Message3_O_OneOfCase_OneofBytes);
-    Message3 *msg = [Message3 parseFromData:[orig data]];
+    Message3 *msg = [Message3 parseFromData:[orig data] error:NULL];
     XCTAssertEqual(msg.oOneOfCase, Message3_O_OneOfCase_OneofBytes);
     XCTAssertEqualObjects(msg.oneofBytes, [@"bar" dataUsingEncoding:NSUTF8StringEncoding]);
     [orig release];
@@ -668,7 +666,7 @@ static NSData *DataFromCStr(const char *str) {
     Message3 *orig = [[Message3 alloc] init];
     orig.oneofMessage = subMessage;
     XCTAssertEqual(orig.oOneOfCase, Message3_O_OneOfCase_OneofMessage);
-    Message3 *msg = [Message3 parseFromData:[orig data]];
+    Message3 *msg = [Message3 parseFromData:[orig data] error:NULL];
     XCTAssertEqual(msg.oOneOfCase, Message3_O_OneOfCase_OneofMessage);
     XCTAssertEqualObjects(msg.oneofMessage, subMessage);
     [orig release];
@@ -678,7 +676,7 @@ static NSData *DataFromCStr(const char *str) {
     Message3 *orig = [[Message3 alloc] init];
     orig.oneofEnum = Message2_Enum_Bar;
     XCTAssertEqual(orig.oOneOfCase, Message3_O_OneOfCase_OneofEnum);
-    Message3 *msg = [Message3 parseFromData:[orig data]];
+    Message3 *msg = [Message3 parseFromData:[orig data] error:NULL];
     XCTAssertEqual(msg.oOneOfCase, Message3_O_OneOfCase_OneofEnum);
     XCTAssertEqual(msg.oneofEnum, Message2_Enum_Bar);
     [orig release];
@@ -695,7 +693,7 @@ static NSData *DataFromCStr(const char *str) {
 - (void)testMap_StandardWireFormat {
   NSData *data = DataFromCStr("\x0A\x04\x08\x01\x10\x01");
 
-  TestMap *msg = [[TestMap alloc] initWithData:data];
+  TestMap *msg = [[TestMap alloc] initWithData:data error:NULL];
   XCTAssertEqual(msg.mapInt32Int32.count, 1U);
   int32_t val = 666;
   XCTAssertTrue([msg.mapInt32Int32 valueForKey:1 value:&val]);
@@ -709,7 +707,7 @@ static NSData *DataFromCStr(const char *str) {
   // put value before key in wire format
   NSData *data = DataFromCStr("\x0A\x04\x10\x01\x08\x02");
 
-  TestMap *msg = [[TestMap alloc] initWithData:data];
+  TestMap *msg = [[TestMap alloc] initWithData:data error:NULL];
   XCTAssertEqual(msg.mapInt32Int32.count, 1U);
   int32_t val = 666;
   XCTAssertTrue([msg.mapInt32Int32 valueForKey:2 value:&val]);
@@ -723,7 +721,7 @@ static NSData *DataFromCStr(const char *str) {
   // Two key fields in wire format
   NSData *data = DataFromCStr("\x0A\x06\x08\x01\x08\x02\x10\x01");
 
-  TestMap *msg = [[TestMap alloc] initWithData:data];
+  TestMap *msg = [[TestMap alloc] initWithData:data error:NULL];
   XCTAssertEqual(msg.mapInt32Int32.count, 1U);
   int32_t val = 666;
   XCTAssertTrue([msg.mapInt32Int32 valueForKey:2 value:&val]);
@@ -737,7 +735,7 @@ static NSData *DataFromCStr(const char *str) {
   // Two value fields in wire format
   NSData *data = DataFromCStr("\x0A\x06\x08\x01\x10\x01\x10\x02");
 
-  TestMap *msg = [[TestMap alloc] initWithData:data];
+  TestMap *msg = [[TestMap alloc] initWithData:data error:NULL];
   XCTAssertEqual(msg.mapInt32Int32.count, 1U);
   int32_t val = 666;
   XCTAssertTrue([msg.mapInt32Int32 valueForKey:1 value:&val]);
@@ -751,7 +749,7 @@ static NSData *DataFromCStr(const char *str) {
   // No key field in wire format
   NSData *data = DataFromCStr("\x0A\x02\x10\x01");
 
-  TestMap *msg = [[TestMap alloc] initWithData:data];
+  TestMap *msg = [[TestMap alloc] initWithData:data error:NULL];
   XCTAssertEqual(msg.mapInt32Int32.count, 1U);
   int32_t val = 666;
   XCTAssertTrue([msg.mapInt32Int32 valueForKey:0 value:&val]);
@@ -765,7 +763,7 @@ static NSData *DataFromCStr(const char *str) {
   // No value field in wire format
   NSData *data = DataFromCStr("\x0A\x02\x08\x01");
 
-  TestMap *msg = [[TestMap alloc] initWithData:data];
+  TestMap *msg = [[TestMap alloc] initWithData:data error:NULL];
   XCTAssertEqual(msg.mapInt32Int32.count, 1U);
   int32_t val = 666;
   XCTAssertTrue([msg.mapInt32Int32 valueForKey:1 value:&val]);
@@ -779,7 +777,7 @@ static NSData *DataFromCStr(const char *str) {
   // Unknown field in wire format
   NSData *data = DataFromCStr("\x0A\x06\x08\x02\x10\x03\x18\x01");
 
-  TestMap *msg = [[TestMap alloc] initWithData:data];
+  TestMap *msg = [[TestMap alloc] initWithData:data error:NULL];
   XCTAssertEqual(msg.mapInt32Int32.count, 1U);
   int32_t val = 666;
   XCTAssertTrue([msg.mapInt32Int32 valueForKey:2 value:&val]);
@@ -793,8 +791,12 @@ static NSData *DataFromCStr(const char *str) {
   // corrupted data in wire format
   NSData *data = DataFromCStr("\x0A\x06\x08\x02\x11\x03");
 
-  XCTAssertThrowsSpecificNamed([TestMap parseFromData:data], NSException,
-                               NSParseErrorException);
+  NSError *error = nil;
+  TestMap *msg = [TestMap parseFromData:data error:&error];
+  XCTAssertNil(msg);
+  XCTAssertNotNil(error);
+  XCTAssertEqualObjects(error.domain, GPBMessageErrorDomain);
+  XCTAssertEqual(error.code, GPBMessageErrorCodeMalformedData);
 }
 
 // TEST(GeneratedMapFieldTest, Proto2UnknownEnum)
@@ -810,14 +812,15 @@ static NSData *DataFromCStr(const char *str) {
   [orig.unknownMapField setValue:Proto2MapEnumPlusExtra_EProto2MapEnumExtra
                           forKey:0];
 
-  TestEnumMap *msg1 = [TestEnumMap parseFromData:[orig data]];
+  TestEnumMap *msg1 = [TestEnumMap parseFromData:[orig data] error:NULL];
   XCTAssertEqual(msg1.knownMapField.count, 1U);
   int32_t val = -1;
   XCTAssertTrue([msg1.knownMapField valueForKey:0 value:&val]);
   XCTAssertEqual(val, Proto2MapEnum_Proto2MapEnumFoo);
   XCTAssertEqual(msg1.unknownFields.countOfFields, 1U);
 
-  TestEnumMapPlusExtra *msg2 = [TestEnumMapPlusExtra parseFromData:[msg1 data]];
+  TestEnumMapPlusExtra *msg2 =
+      [TestEnumMapPlusExtra parseFromData:[msg1 data] error:NULL];
   val = -1;
   XCTAssertEqual(msg2.knownMapField.count, 1U);
   XCTAssertTrue([msg2.knownMapField valueForKey:0 value:&val]);
@@ -833,6 +836,72 @@ static NSData *DataFromCStr(const char *str) {
   [orig release];
 }
 
-#pragma mark -
+#pragma mark - Map Round Tripping
+
+- (void)testProto2MapRoundTripping {
+  Message2 *msg = [[Message2 alloc] init];
+
+  // Key/Value data should result in different byte lengths on wire to ensure
+  // everything is right.
+  [msg.mapInt32Int32 setValue:1000 forKey:200];
+  [msg.mapInt32Int32 setValue:101 forKey:2001];
+  [msg.mapInt64Int64 setValue:1002 forKey:202];
+  [msg.mapInt64Int64 setValue:103 forKey:2003];
+  [msg.mapUint32Uint32 setValue:1004 forKey:204];
+  [msg.mapUint32Uint32 setValue:105 forKey:2005];
+  [msg.mapUint64Uint64 setValue:1006 forKey:206];
+  [msg.mapUint64Uint64 setValue:107 forKey:2007];
+  [msg.mapSint32Sint32 setValue:1008 forKey:208];
+  [msg.mapSint32Sint32 setValue:109 forKey:2009];
+  [msg.mapSint64Sint64 setValue:1010 forKey:210];
+  [msg.mapSint64Sint64 setValue:111 forKey:2011];
+  [msg.mapFixed32Fixed32 setValue:1012 forKey:212];
+  [msg.mapFixed32Fixed32 setValue:113 forKey:2013];
+  [msg.mapFixed64Fixed64 setValue:1014 forKey:214];
+  [msg.mapFixed64Fixed64 setValue:115 forKey:2015];
+  [msg.mapSfixed32Sfixed32 setValue:1016 forKey:216];
+  [msg.mapSfixed32Sfixed32 setValue:117 forKey:2017];
+  [msg.mapSfixed64Sfixed64 setValue:1018 forKey:218];
+  [msg.mapSfixed64Sfixed64 setValue:119 forKey:2019];
+  [msg.mapInt32Float setValue:1020.f forKey:220];
+  [msg.mapInt32Float setValue:121.f forKey:2021];
+  [msg.mapInt32Double setValue:1022. forKey:222];
+  [msg.mapInt32Double setValue:123. forKey:2023];
+  [msg.mapBoolBool setValue:false forKey:true];
+  [msg.mapBoolBool setValue:true forKey:false];
+  msg.mapStringString[@"224"] = @"1024";
+  msg.mapStringString[@"2025"] = @"125";
+  msg.mapStringBytes[@"226"] = DataFromCStr("1026");
+  msg.mapStringBytes[@"2027"] = DataFromCStr("127");
+  Message2 *val1 = [[Message2 alloc] init];
+  val1.optionalInt32 = 1028;
+  Message2 *val2 = [[Message2 alloc] init];
+  val2.optionalInt32 = 129;
+  [msg.mapStringMessage setValue:val1 forKey:@"228"];
+  [msg.mapStringMessage setValue:val2 forKey:@"2029"];
+  [msg.mapInt32Bytes setValue:DataFromCStr("1030 bytes") forKey:230];
+  [msg.mapInt32Bytes setValue:DataFromCStr("131") forKey:2031];
+  [msg.mapInt32Enum setValue:Message2_Enum_Bar forKey:232];
+  [msg.mapInt32Enum setValue:Message2_Enum_Baz forKey:2033];
+  Message2 *val3 = [[Message2 alloc] init];
+  val3.optionalInt32 = 1034;
+  Message2 *val4 = [[Message2 alloc] init];
+  val4.optionalInt32 = 135;
+  [msg.mapInt32Message setValue:val3 forKey:234];
+  [msg.mapInt32Message setValue:val4 forKey:2035];
+
+  NSData *data = [msg data];
+  Message2 *msg2 = [[Message2 alloc] initWithData:data error:NULL];
+
+  XCTAssertNotEqual(msg2, msg);  // Pointer comparison
+  XCTAssertEqualObjects(msg2, msg);
+
+  [val4 release];
+  [val3 release];
+  [val2 release];
+  [val1 release];
+  [msg2 release];
+  [msg release];
+}
 
 @end

+ 246 - 39
objectivec/Tests/GPBMessageTests.m

@@ -34,6 +34,7 @@
 
 #import "GPBArray_PackagePrivate.h"
 #import "GPBDescriptor.h"
+#import "GPBDictionary_PackagePrivate.h"
 #import "GPBField_PackagePrivate.h"
 #import "GPBMessage_PackagePrivate.h"
 #import "GPBUnknownFieldSet_PackagePrivate.h"
@@ -47,23 +48,9 @@
 @implementation MessageTests
 
 // TODO(thomasvl): this should get split into a few files of logic junks, it is
-// a jumble
-// of things at the moment (and the testutils have a bunch of the real
+// a jumble of things at the moment (and the testutils have a bunch of the real
 // assertions).
 
-#ifdef DEBUG
-- (void)assertBlock:(void (^)())block
-    throwsWithMessageInUserInfo:(GPBMessage *)message {
-  @try {
-    block();
-    XCTAssertTrue(NO);
-  }
-  @catch (NSException *e) {
-    XCTAssertEqualObjects([e userInfo][GPBExceptionMessageKey], message);
-  }
-}
-#endif  // DEBUG
-
 - (TestAllTypes *)mergeSource {
   TestAllTypes *message = [TestAllTypes message];
   [message setOptionalInt32:1];
@@ -290,14 +277,18 @@
   XCTAssertTrue(message.initialized);
 }
 
-#ifdef DEBUG
-- (void)testUninitializedException {
+- (void)testDataFromUninitialized {
   TestRequired *message = [TestRequired message];
-  [self assertBlock:^{
-    [message data];
-  } throwsWithMessageInUserInfo:message];
-}
+  NSData *data = [message data];
+  // In DEBUG, the data generation will fail, but in non DEBUG, it passes
+  // because the check isn't done (for speed).
+#ifdef DEBUG
+  XCTAssertNil(data);
+#else
+  XCTAssertNotNil(data);
+  XCTAssertFalse(message.initialized);
 #endif  // DEBUG
+}
 
 - (void)testInitialized {
   // We're mostly testing that no exception is thrown.
@@ -305,18 +296,22 @@
   XCTAssertFalse(message.initialized);
 }
 
-#ifdef DEBUG
-- (void)testNestedUninitializedException {
+- (void)testDataFromNestedUninitialized {
   TestRequiredForeign *message = [TestRequiredForeign message];
   [message setOptionalMessage:[TestRequired message]];
   message.repeatedMessageArray = [NSMutableArray array];
   [message.repeatedMessageArray addObject:[TestRequired message]];
   [message.repeatedMessageArray addObject:[TestRequired message]];
-  [self assertBlock:^{
-    [message data];
-  } throwsWithMessageInUserInfo:message];
-}
+  NSData *data = [message data];
+  // In DEBUG, the data generation will fail, but in non DEBUG, it passes
+  // because the check isn't done (for speed).
+#ifdef DEBUG
+  XCTAssertNil(data);
+#else
+  XCTAssertNotNil(data);
+  XCTAssertFalse(message.initialized);
 #endif  // DEBUG
+}
 
 - (void)testNestedInitialized {
   // We're mostly testing that no exception is thrown.
@@ -330,13 +325,23 @@
   XCTAssertFalse(message.initialized);
 }
 
-#ifdef DEBUG
 - (void)testParseUninitialized {
-  [self assertBlock:^{
-    [TestRequired parseFromData:GPBEmptyNSData()];
-  } throwsWithMessageInUserInfo:[TestRequired message]];
-}
+  NSError *error = nil;
+  TestRequired *msg =
+      [TestRequired parseFromData:GPBEmptyNSData() error:&error];
+  // In DEBUG, the parse will fail, but in non DEBUG, it passes because
+  // the check isn't done (for speed).
+#ifdef DEBUG
+  XCTAssertNil(msg);
+  XCTAssertNotNil(error);
+  XCTAssertEqualObjects(error.domain, GPBMessageErrorDomain);
+  XCTAssertEqual(error.code, GPBMessageErrorCodeMissingRequiredField);
+#else
+  XCTAssertNotNil(msg);
+  XCTAssertNil(error);
+  XCTAssertFalse(msg.initialized);
 #endif  // DEBUG
+}
 
 - (void)testCoding {
   NSData *data =
@@ -1033,7 +1038,7 @@
   message3.repeatedStringArray = [NSMutableArray arrayWithObject:@"wee"];
   XCTAssertNotNil(message.repeatedInt32Array);
   XCTAssertNotNil(message.repeatedStringArray);
-  TestAllTypes *message4 = [message3 copy];
+  TestAllTypes *message4 = [[message3 copy] autorelease];
   XCTAssertNotEqual(message3.repeatedInt32Array, message4.repeatedInt32Array);
   XCTAssertEqualObjects(message3.repeatedInt32Array,
                         message4.repeatedInt32Array);
@@ -1156,6 +1161,205 @@
   XCTAssertFalse([message hasA]);
 }
 
+- (void)testDefaultingMaps {
+  // Basic tests for default creation of maps in a message.
+  TestRecursiveMessageWithRepeatedField *message =
+      [TestRecursiveMessageWithRepeatedField message];
+  TestRecursiveMessageWithRepeatedField *message2 =
+      [TestRecursiveMessageWithRepeatedField message];
+
+  // Simply accessing the map should not make any fields visible.
+  XCTAssertNotNil(message.a.a.iToI);
+  XCTAssertFalse([message hasA]);
+  XCTAssertFalse([message.a hasA]);
+  XCTAssertNotNil(message2.a.a.strToStr);
+  XCTAssertFalse([message2 hasA]);
+  XCTAssertFalse([message2.a hasA]);
+
+  // But adding an element to the map should.
+  [message.a.a.iToI setValue:100 forKey:200];
+  XCTAssertTrue([message hasA]);
+  XCTAssertTrue([message.a hasA]);
+  XCTAssertEqual([message.a.a.iToI count], (NSUInteger)1);
+  [message2.a.a.strToStr setObject:@"foo" forKey:@"bar"];
+  XCTAssertTrue([message2 hasA]);
+  XCTAssertTrue([message2.a hasA]);
+  XCTAssertEqual([message2.a.a.strToStr count], (NSUInteger)1);
+}
+
+- (void)testAutocreatedMapShared {
+  // Multiple objects pointing to the same map.
+  TestRecursiveMessageWithRepeatedField *message1a =
+      [TestRecursiveMessageWithRepeatedField message];
+  TestRecursiveMessageWithRepeatedField *message1b =
+      [TestRecursiveMessageWithRepeatedField message];
+  message1a.a.iToI = message1b.a.iToI;
+  XCTAssertTrue([message1a hasA]);
+  XCTAssertFalse([message1b hasA]);
+  [message1a.a.iToI setValue:1 forKey:2];
+  XCTAssertTrue([message1a hasA]);
+  XCTAssertTrue([message1b hasA]);
+  XCTAssertEqual(message1a.a.iToI, message1b.a.iToI);
+
+  TestRecursiveMessageWithRepeatedField *message2a =
+      [TestRecursiveMessageWithRepeatedField message];
+  TestRecursiveMessageWithRepeatedField *message2b =
+      [TestRecursiveMessageWithRepeatedField message];
+  message2a.a.strToStr = message2b.a.strToStr;
+  XCTAssertTrue([message2a hasA]);
+  XCTAssertFalse([message2b hasA]);
+  [message2a.a.strToStr setObject:@"bar" forKey:@"foo"];
+  XCTAssertTrue([message2a hasA]);
+  XCTAssertTrue([message2b hasA]);
+  XCTAssertEqual(message2a.a.strToStr, message2b.a.strToStr);
+}
+
+- (void)testAutocreatedMapCopy {
+  // Copy should not copy autocreated maps.
+  TestRecursiveMessageWithRepeatedField *message =
+      [TestRecursiveMessageWithRepeatedField message];
+  XCTAssertNotNil(message.strToStr);
+  XCTAssertNotNil(message.iToI);
+  TestRecursiveMessageWithRepeatedField *message2 =
+      [[message copy] autorelease];
+  // Pointer conparisions.
+  XCTAssertNotEqual(message.strToStr, message2.strToStr);
+  XCTAssertNotEqual(message.iToI, message2.iToI);
+
+  // Mutable copy should copy empty arrays that were explicitly set (end up
+  // with different objects that are equal).
+  TestRecursiveMessageWithRepeatedField *message3 =
+      [TestRecursiveMessageWithRepeatedField message];
+  message3.iToI = [GPBInt32Int32Dictionary dictionaryWithValue:10 forKey:20];
+  message3.strToStr =
+      [NSMutableDictionary dictionaryWithObject:@"abc" forKey:@"123"];
+  XCTAssertNotNil(message.iToI);
+  XCTAssertNotNil(message.iToI);
+  TestRecursiveMessageWithRepeatedField *message4 =
+      [[message3 copy] autorelease];
+  XCTAssertNotEqual(message3.iToI, message4.iToI);
+  XCTAssertEqualObjects(message3.iToI, message4.iToI);
+  XCTAssertNotEqual(message3.strToStr, message4.strToStr);
+  XCTAssertEqualObjects(message3.strToStr, message4.strToStr);
+}
+
+- (void)testAutocreatedMapRetain {
+  // Should be able to retain autocreated map while the creator is dealloced.
+  TestRecursiveMessageWithRepeatedField *message =
+      [TestRecursiveMessageWithRepeatedField message];
+
+  @autoreleasepool {
+    TestRecursiveMessageWithRepeatedField *message2 =
+        [TestRecursiveMessageWithRepeatedField message];
+    message.iToI = message2.iToI;
+    message.strToStr = message2.strToStr;
+    // Pointer conparision
+    XCTAssertEqual(message.iToI->_autocreator, message2);
+    XCTAssertTrue([message.strToStr
+        isKindOfClass:[GPBAutocreatedDictionary class]]);
+    XCTAssertEqual(
+        ((GPBAutocreatedDictionary *)message.strToStr)->_autocreator,
+        message2);
+  }
+
+  XCTAssertNil(message.iToI->_autocreator);
+  XCTAssertTrue(
+      [message.strToStr isKindOfClass:[GPBAutocreatedDictionary class]]);
+  XCTAssertNil(
+      ((GPBAutocreatedDictionary *)message.strToStr)->_autocreator);
+}
+
+- (void)testSetNilAutocreatedMap {
+  // Setting map to nil should cause it to lose its delegate.
+  TestRecursiveMessageWithRepeatedField *message =
+      [TestRecursiveMessageWithRepeatedField message];
+  GPBInt32Int32Dictionary *iToI = [message.iToI retain];
+  GPBAutocreatedDictionary *strToStr =
+      (GPBAutocreatedDictionary *)[message.strToStr retain];
+  XCTAssertTrue([strToStr isKindOfClass:[GPBAutocreatedDictionary class]]);
+  XCTAssertEqual(iToI->_autocreator, message);
+  XCTAssertEqual(strToStr->_autocreator, message);
+  message.iToI = nil;
+  message.strToStr = nil;
+  XCTAssertNil(iToI->_autocreator);
+  XCTAssertNil(strToStr->_autocreator);
+  [iToI release];
+  [strToStr release];
+}
+
+- (void)testReplaceAutocreatedMap {
+  // Replacing map should orphan the old one and cause its creator to become
+  // visible.
+  {
+    TestRecursiveMessageWithRepeatedField *message =
+        [TestRecursiveMessageWithRepeatedField message];
+    XCTAssertNotNil(message.a);
+    XCTAssertNotNil(message.a.iToI);
+    XCTAssertFalse([message hasA]);
+    GPBInt32Int32Dictionary *iToI = [message.a.iToI retain];
+    XCTAssertEqual(iToI->_autocreator, message.a);  // Pointer comparision
+    message.a.iToI = [GPBInt32Int32Dictionary dictionaryWithValue:6 forKey:7];
+    XCTAssertTrue([message hasA]);
+    XCTAssertNotEqual(message.a.iToI, iToI);  // Pointer comparision
+    XCTAssertNil(iToI->_autocreator);
+    [iToI release];
+  }
+
+  {
+    TestRecursiveMessageWithRepeatedField *message =
+        [TestRecursiveMessageWithRepeatedField message];
+    XCTAssertNotNil(message.a);
+    XCTAssertNotNil(message.a.strToStr);
+    XCTAssertFalse([message hasA]);
+    GPBAutocreatedDictionary *strToStr =
+        (GPBAutocreatedDictionary *)[message.a.strToStr retain];
+    XCTAssertTrue([strToStr isKindOfClass:[GPBAutocreatedDictionary class]]);
+    XCTAssertEqual(strToStr->_autocreator, message.a);  // Pointer comparision
+    message.a.strToStr =
+        [NSMutableDictionary dictionaryWithObject:@"abc" forKey:@"def"];
+    XCTAssertTrue([message hasA]);
+    XCTAssertNotEqual(message.a.strToStr, strToStr);  // Pointer comparision
+    XCTAssertNil(strToStr->_autocreator);
+    [strToStr release];
+  }
+}
+
+- (void)testSetAutocreatedMapToSelf {
+  // Setting map to itself should cause it to become visible.
+  {
+    TestRecursiveMessageWithRepeatedField *message =
+        [TestRecursiveMessageWithRepeatedField message];
+    XCTAssertNotNil(message.a);
+    XCTAssertNotNil(message.a.iToI);
+    XCTAssertFalse([message hasA]);
+    message.a.iToI = message.a.iToI;
+    XCTAssertTrue([message hasA]);
+    XCTAssertNil(message.a.iToI->_autocreator);
+  }
+
+  {
+    TestRecursiveMessageWithRepeatedField *message =
+        [TestRecursiveMessageWithRepeatedField message];
+    XCTAssertNotNil(message.a);
+    XCTAssertNotNil(message.a.strToStr);
+    XCTAssertFalse([message hasA]);
+    message.a.strToStr = message.a.strToStr;
+    XCTAssertTrue([message hasA]);
+    XCTAssertTrue([message.a.strToStr isKindOfClass:[GPBAutocreatedDictionary class]]);
+    XCTAssertNil(((GPBAutocreatedDictionary *)message.a.strToStr)->_autocreator);
+  }
+}
+
+- (void)testAutocreatedMapRemoveAllValues {
+  // Calling removeAll on autocreated map should not cause it to be visible.
+  TestRecursiveMessageWithRepeatedField *message =
+      [TestRecursiveMessageWithRepeatedField message];
+  [message.a.iToI removeAll];
+  XCTAssertFalse([message hasA]);
+  [message.a.strToStr removeAllObjects];
+  XCTAssertFalse([message hasA]);
+}
+
 - (void)testExtensionAccessors {
   TestAllExtensions *message = [TestAllExtensions message];
   [self setAllExtensions:message repeatedCount:kGPBDefaultRepeatCount];
@@ -1555,7 +1759,8 @@
   GPBMessage *message = [GPBMessage message];
   [message setUnknownFields:unknowns];
   NSData *data = [message data];
-  GPBMessage *message2 = [GPBMessage parseFromData:data extensionRegistry:nil];
+  GPBMessage *message2 =
+      [GPBMessage parseFromData:data extensionRegistry:nil error:NULL];
   XCTAssertEqualObjects(message, message2);
 }
 
@@ -1579,9 +1784,11 @@
   GPBCodedInputStream *input =
       [GPBCodedInputStream streamWithData:delimitedData];
   GPBMessage *message3 = [GPBMessage parseDelimitedFromCodedInputStream:input
-                                                      extensionRegistry:nil];
+                                                      extensionRegistry:nil
+                                                                  error:NULL];
   GPBMessage *message4 = [GPBMessage parseDelimitedFromCodedInputStream:input
-                                                      extensionRegistry:nil];
+                                                      extensionRegistry:nil
+                                                                  error:NULL];
   XCTAssertEqualObjects(message1, message3);
   XCTAssertEqualObjects(message2, message4);
 }
@@ -1673,7 +1880,7 @@
   XCTAssertEqual(msg.bar, EnumTestMsg_MyEnum_One);
   XCTAssertEqual(msg.baz, EnumTestMsg_MyEnum_NegOne);
   // Bounce to wire and back.
-  EnumTestMsg *msgPrime = [EnumTestMsg parseFromData:[msg data]];
+  EnumTestMsg *msgPrime = [EnumTestMsg parseFromData:[msg data] error:NULL];
   XCTAssertEqualObjects(msgPrime, msg);
   XCTAssertEqual(msgPrime.foo, EnumTestMsg_MyEnum_Zero);
   XCTAssertEqual(msgPrime.bar, EnumTestMsg_MyEnum_One);
@@ -1685,7 +1892,7 @@
   XCTAssertEqual(msg.bar, EnumTestMsg_MyEnum_Two);
   XCTAssertEqual(msg.baz, EnumTestMsg_MyEnum_NegTwo);
   // Bounce to wire and back.
-  msgPrime = [EnumTestMsg parseFromData:[msg data]];
+  msgPrime = [EnumTestMsg parseFromData:[msg data] error:NULL];
   XCTAssertEqualObjects(msgPrime, msg);
   XCTAssertEqual(msgPrime.foo, EnumTestMsg_MyEnum_Zero);
   XCTAssertEqual(msgPrime.bar, EnumTestMsg_MyEnum_Two);
@@ -1706,7 +1913,7 @@
   XCTAssertEqual([msg.mumbleArray valueAtIndex:3], EnumTestMsg_MyEnum_NegOne);
   XCTAssertEqual([msg.mumbleArray valueAtIndex:4], EnumTestMsg_MyEnum_NegTwo);
   // Bounce to wire and back.
-  msgPrime = [EnumTestMsg parseFromData:[msg data]];
+  msgPrime = [EnumTestMsg parseFromData:[msg data] error:NULL];
   XCTAssertEqualObjects(msgPrime, msg);
   XCTAssertEqual([msgPrime.mumbleArray valueAtIndex:0],
                  EnumTestMsg_MyEnum_Zero);

+ 5 - 4
objectivec/Tests/GPBPerfTests.m

@@ -30,6 +30,7 @@
 
 #import "GPBTestUtilities.h"
 #import "google/protobuf/Unittest.pbobjc.h"
+#import "google/protobuf/UnittestImport.pbobjc.h"
 #import "google/protobuf/UnittestObjc.pbobjc.h"
 
 //
@@ -57,7 +58,7 @@ static const uint32_t kRepeatedCount = 100;
       [self setAllFields:message repeatedCount:kRepeatedCount];
       NSData* rawBytes = [message data];
       [message release];
-      message = [[TestAllTypes alloc] initWithData:rawBytes];
+      message = [[TestAllTypes alloc] initWithData:rawBytes error:NULL];
       [message release];
     }
   }];
@@ -71,7 +72,7 @@ static const uint32_t kRepeatedCount = 100;
       NSData* rawBytes = [message data];
       [message release];
       TestAllExtensions* message2 =
-          [[TestAllExtensions alloc] initWithData:rawBytes];
+          [[TestAllExtensions alloc] initWithData:rawBytes error:NULL];
       [message2 release];
     }
   }];
@@ -84,7 +85,7 @@ static const uint32_t kRepeatedCount = 100;
       [self setPackedFields:message repeatedCount:kRepeatedCount];
       NSData* rawBytes = [message data];
       [message release];
-      message = [[TestPackedTypes alloc] initWithData:rawBytes];
+      message = [[TestPackedTypes alloc] initWithData:rawBytes error:NULL];
       [message release];
     }
   }];
@@ -98,7 +99,7 @@ static const uint32_t kRepeatedCount = 100;
       NSData* rawBytes = [message data];
       [message release];
       TestPackedExtensions* message2 =
-          [[TestPackedExtensions alloc] initWithData:rawBytes];
+          [[TestPackedExtensions alloc] initWithData:rawBytes error:NULL];
       [message2 release];
     }
   }];

+ 1 - 4
objectivec/Tests/GPBStringTests.m

@@ -31,10 +31,7 @@
 #import <XCTest/XCTest.h>
 
 #import "GPBCodedInputStream_PackagePrivate.h"
-
-#ifndef GPBARRAYSIZE
-#define GPBARRAYSIZE(a) ((sizeof(a) / sizeof((a[0]))))
-#endif  // GPBARRAYSIZE
+#import "GPBTestUtilities.h"
 
 @interface TestClass : NSObject
 @property(nonatomic, retain) NSString *foo;

+ 56 - 1
objectivec/Tests/GPBSwiftTests.swift

@@ -53,6 +53,12 @@ class GPBBridgeTests: XCTestCase {
     msg.repeatedStringArray.addObject("pqr")
     msg.repeatedEnumArray.addValue(Message2_Enum.Bar.rawValue)
     msg.repeatedEnumArray.addValue(Message2_Enum.Baz.rawValue)
+    msg.mapInt32Int32.setValue(400, forKey:500)
+    msg.mapInt32Int32.setValue(401, forKey:501)
+    msg.mapStringString.setObject("foo", forKey:"bar")
+    msg.mapStringString.setObject("abc", forKey:"xyz")
+    msg.mapInt32Enum.setValue(Message2_Enum.Bar.rawValue, forKey:600)
+    msg.mapInt32Enum.setValue(Message2_Enum.Baz.rawValue, forKey:601)
 
     // Check has*.
     XCTAssertTrue(msg.hasOptionalInt32)
@@ -83,6 +89,20 @@ class GPBBridgeTests: XCTestCase {
     XCTAssertEqual(msg.repeatedEnumArray.valueAtIndex(0), Message2_Enum.Bar.rawValue)
     XCTAssertEqual(msg.repeatedEnumArray.valueAtIndex(1), Message2_Enum.Baz.rawValue)
     XCTAssertEqual(msg.repeatedInt64Array.count, UInt(0))
+    XCTAssertEqual(msg.mapInt32Int32.count, UInt(2))
+    var intValue: Int32 = 0;
+    XCTAssertTrue(msg.mapInt32Int32.valueForKey(500, value:&intValue))
+    XCTAssertEqual(intValue, Int32(400))
+    XCTAssertTrue(msg.mapInt32Int32.valueForKey(501, value:&intValue))
+    XCTAssertEqual(intValue, Int32(401))
+    XCTAssertEqual(msg.mapStringString.count, Int(2))
+    XCTAssertEqual(msg.mapStringString.objectForKey("bar") as! String, "foo")
+    XCTAssertEqual(msg.mapStringString.objectForKey("xyz") as! String, "abc")
+    XCTAssertEqual(msg.mapInt32Enum.count, UInt(2))
+    XCTAssertTrue(msg.mapInt32Enum.valueForKey(600, value:&intValue))
+    XCTAssertEqual(intValue, Message2_Enum.Bar.rawValue)
+    XCTAssertTrue(msg.mapInt32Enum.valueForKey(601, value:&intValue))
+    XCTAssertEqual(intValue, Message2_Enum.Baz.rawValue)
 
     // Clearing a string with nil.
     msg2.optionalString = nil
@@ -109,6 +129,9 @@ class GPBBridgeTests: XCTestCase {
     XCTAssertEqual(msg.repeatedInt32Array.count, UInt(0))
     XCTAssertEqual(msg.repeatedStringArray.count, Int(0))
     XCTAssertEqual(msg.repeatedEnumArray.count, UInt(0))
+    XCTAssertEqual(msg.mapInt32Int32.count, UInt(0))
+    XCTAssertEqual(msg.mapStringString.count, Int(0))
+    XCTAssertEqual(msg.mapInt32Enum.count, UInt(0))
   }
 
   func testProto3Basics() {
@@ -128,6 +151,13 @@ class GPBBridgeTests: XCTestCase {
     msg.repeatedEnumArray.addValue(Message3_Enum.Bar.rawValue)
     msg.repeatedEnumArray.addRawValue(666)
     SetMessage3_OptionalEnum_RawValue(msg2, 666)
+    msg.mapInt32Int32.setValue(400, forKey:500)
+    msg.mapInt32Int32.setValue(401, forKey:501)
+    msg.mapStringString.setObject("foo", forKey:"bar")
+    msg.mapStringString.setObject("abc", forKey:"xyz")
+    msg.mapInt32Enum.setValue(Message2_Enum.Bar.rawValue, forKey:600)
+    // "proto3" syntax lets enum get unknown values.
+    msg.mapInt32Enum.setRawValue(666, forKey:601)
 
     // Has only exists on for message fields.
     XCTAssertTrue(msg.hasOptionalMessage)
@@ -152,6 +182,22 @@ class GPBBridgeTests: XCTestCase {
     XCTAssertEqual(msg.repeatedEnumArray.rawValueAtIndex(1), 666)
     XCTAssertEqual(msg2.optionalEnum, Message3_Enum.GPBUnrecognizedEnumeratorValue)
     XCTAssertEqual(Message3_OptionalEnum_RawValue(msg2), Int32(666))
+    XCTAssertEqual(msg.mapInt32Int32.count, UInt(2))
+    var intValue: Int32 = 0;
+    XCTAssertTrue(msg.mapInt32Int32.valueForKey(500, value:&intValue))
+    XCTAssertEqual(intValue, Int32(400))
+    XCTAssertTrue(msg.mapInt32Int32.valueForKey(501, value:&intValue))
+    XCTAssertEqual(intValue, Int32(401))
+    XCTAssertEqual(msg.mapStringString.count, Int(2))
+    XCTAssertEqual(msg.mapStringString.objectForKey("bar") as! String, "foo")
+    XCTAssertEqual(msg.mapStringString.objectForKey("xyz") as! String, "abc")
+    XCTAssertEqual(msg.mapInt32Enum.count, UInt(2))
+    XCTAssertTrue(msg.mapInt32Enum.valueForKey(600, value:&intValue))
+    XCTAssertEqual(intValue, Message2_Enum.Bar.rawValue)
+    XCTAssertTrue(msg.mapInt32Enum.valueForKey(601, value:&intValue))
+    XCTAssertEqual(intValue, Message3_Enum.GPBUnrecognizedEnumeratorValue.rawValue)
+    XCTAssertTrue(msg.mapInt32Enum.valueForKey(601, rawValue:&intValue))
+    XCTAssertEqual(intValue, 666)
 
     // Clearing a string with nil.
     msg2.optionalString = nil
@@ -175,6 +221,9 @@ class GPBBridgeTests: XCTestCase {
     msg2.clear()
     XCTAssertEqual(msg2.optionalEnum, Message3_Enum.Foo)  // Default
     XCTAssertEqual(Message3_OptionalEnum_RawValue(msg2), Message3_Enum.Foo.rawValue)
+    XCTAssertEqual(msg.mapInt32Int32.count, UInt(0))
+    XCTAssertEqual(msg.mapStringString.count, Int(0))
+    XCTAssertEqual(msg.mapInt32Enum.count, UInt(0))
   }
 
   func testAutoCreation() {
@@ -390,15 +439,21 @@ class GPBBridgeTests: XCTestCase {
     msg.optionalGroup.a = 102
     msg.repeatedStringArray.addObject("abc")
     msg.repeatedStringArray.addObject("def")
+    msg.mapInt32Int32.setValue(200, forKey:300)
+    msg.mapInt32Int32.setValue(201, forKey:201)
+    msg.mapStringString.setObject("foo", forKey:"bar")
+    msg.mapStringString.setObject("abc", forKey:"xyz")
 
     let data = msg.data()
 
-    let msg2 = Message2(data: data)
+    let msg2 = Message2(data: data, error:nil)
     XCTAssertTrue(msg2 !== msg)  // New instance
     XCTAssertEqual(msg.optionalInt32, Int32(100))
     XCTAssertEqual(msg.optionalInt64, Int64(101))
     XCTAssertEqual(msg.optionalGroup.a, Int32(102))
     XCTAssertEqual(msg.repeatedStringArray.count, Int(2))
+    XCTAssertEqual(msg.mapInt32Int32.count, UInt(2))
+    XCTAssertEqual(msg.mapStringString.count, Int(2))
     XCTAssertEqual(msg2, msg)
   }
 

+ 7 - 0
objectivec/Tests/GPBTestUtilities.h

@@ -37,6 +37,13 @@
 @class TestPackedExtensions;
 @class GPBExtensionRegistry;
 
+
+// Helper for uses of C arrays in tests cases.
+#ifndef GPBARRAYSIZE
+#define GPBARRAYSIZE(a) ((sizeof(a) / sizeof((a[0]))))
+#endif  // GPBARRAYSIZE
+
+
 // The number of repetitions of any repeated objects inside of test messages.
 extern const uint32_t kGPBDefaultRepeatCount;
 

+ 1 - 19
objectivec/Tests/GPBTestUtilities.m

@@ -32,6 +32,7 @@
 
 #import "google/protobuf/MapUnittest.pbobjc.h"
 #import "google/protobuf/Unittest.pbobjc.h"
+#import "google/protobuf/UnittestImport.pbobjc.h"
 
 const uint32_t kGPBDefaultRepeatCount = 2;
 
@@ -1060,25 +1061,6 @@ const uint32_t kGPBDefaultRepeatCount = 2;
 }
 
 - (void)setAllMapFields:(TestMap *)message numEntries:(uint32_t)count {
-  message.mapInt32Int32 = [GPBInt32Int32Dictionary dictionary];
-  message.mapInt64Int64 = [GPBInt64Int64Dictionary dictionary];
-  message.mapUint32Uint32 = [GPBUInt32UInt32Dictionary dictionary];
-  message.mapUint64Uint64 = [GPBUInt64UInt64Dictionary dictionary];
-  message.mapSint32Sint32 = [GPBInt32Int32Dictionary dictionary];
-  message.mapSint64Sint64 = [GPBInt64Int64Dictionary dictionary];
-  message.mapFixed32Fixed32 = [GPBUInt32UInt32Dictionary dictionary];
-  message.mapFixed64Fixed64 = [GPBUInt64UInt64Dictionary dictionary];
-  message.mapSfixed32Sfixed32 = [GPBInt32Int32Dictionary dictionary];
-  message.mapSfixed64Sfixed64 = [GPBInt64Int64Dictionary dictionary];
-  message.mapInt32Float = [GPBInt32FloatDictionary dictionary];
-  message.mapInt32Double = [GPBInt32DoubleDictionary dictionary];
-  message.mapBoolBool = [GPBBoolBoolDictionary dictionary];
-  message.mapStringString = [NSMutableDictionary dictionary];
-  message.mapInt32Bytes = [GPBInt32ObjectDictionary dictionary];
-  message.mapInt32Enum = [GPBInt32EnumDictionary
-      dictionaryWithValidationFunction:MapEnum_IsValidValue];
-  message.mapInt32ForeignMessage = [GPBInt32ObjectDictionary dictionary];
-
   for (uint32_t i = 0; i < count; i++) {
     [message.mapInt32Int32 setValue:(i + 1) forKey:100 + i * 100];
     [message.mapInt64Int64 setValue:(i + 1) forKey:101 + i * 100];

+ 10 - 7
objectivec/Tests/GPBUnknownFieldSetTest.m

@@ -56,7 +56,7 @@
 - (void)setUp {
   allFields_ = [self allSetRepeatedCount:kGPBDefaultRepeatCount];
   allFieldsData_ = [allFields_ data];
-  emptyMessage_ = [TestEmptyMessage parseFromData:allFieldsData_];
+  emptyMessage_ = [TestEmptyMessage parseFromData:allFieldsData_ error:NULL];
   unknownFields_ = emptyMessage_.unknownFields;
 }
 
@@ -176,7 +176,7 @@
   [fields addField:field];
 
   NSData* data = fields.data;
-  TestAllTypes* destination = [TestAllTypes parseFromData:data];
+  TestAllTypes* destination = [TestAllTypes parseFromData:data error:NULL];
 
   [self assertAllFieldsSet:destination repeatedCount:kGPBDefaultRepeatCount];
   XCTAssertEqual(destination.unknownFields.countOfFields, (NSUInteger)1);
@@ -191,8 +191,10 @@
   // when parsing.
 
   NSData* bizarroData = [self getBizarroData];
-  TestAllTypes* allTypesMessage = [TestAllTypes parseFromData:bizarroData];
-  TestEmptyMessage* emptyMessage = [TestEmptyMessage parseFromData:bizarroData];
+  TestAllTypes* allTypesMessage =
+      [TestAllTypes parseFromData:bizarroData error:NULL];
+  TestEmptyMessage* emptyMessage =
+      [TestEmptyMessage parseFromData:bizarroData error:NULL];
 
   // All fields should have been interpreted as unknown, so the debug strings
   // should be the same.
@@ -204,7 +206,7 @@
   // they are declared as extension numbers.
 
   TestEmptyMessageWithExtensions* message =
-      [TestEmptyMessageWithExtensions parseFromData:allFieldsData_];
+      [TestEmptyMessageWithExtensions parseFromData:allFieldsData_ error:NULL];
 
   XCTAssertEqual(unknownFields_.countOfFields,
                  message.unknownFields.countOfFields);
@@ -217,8 +219,9 @@
 
   NSData* bizarroData = [self getBizarroData];
   TestAllExtensions* allExtensionsMessage =
-      [TestAllExtensions parseFromData:bizarroData];
-  TestEmptyMessage* emptyMessage = [TestEmptyMessage parseFromData:bizarroData];
+      [TestAllExtensions parseFromData:bizarroData error:NULL];
+  TestEmptyMessage* emptyMessage =
+      [TestEmptyMessage parseFromData:bizarroData error:NULL];
 
   // All fields should have been interpreted as unknown, so the debug strings
   // should be the same.

+ 17 - 11
objectivec/Tests/GPBWireFormatTests.m

@@ -47,7 +47,7 @@
   NSData* rawBytes = message.data;
   XCTAssertEqual(message.serializedSize, (size_t)rawBytes.length);
 
-  TestAllTypes* message2 = [TestAllTypes parseFromData:rawBytes];
+  TestAllTypes* message2 = [TestAllTypes parseFromData:rawBytes error:NULL];
 
   [self assertAllFieldsSet:message2 repeatedCount:kGPBDefaultRepeatCount];
 }
@@ -59,7 +59,8 @@
   NSData* rawBytes = message.data;
   XCTAssertEqual(message.serializedSize, (size_t)rawBytes.length);
 
-  TestPackedTypes* message2 = [TestPackedTypes parseFromData:rawBytes];
+  TestPackedTypes* message2 =
+      [TestPackedTypes parseFromData:rawBytes error:NULL];
 
   [self assertPackedFieldsSet:message2 repeatedCount:kGPBDefaultRepeatCount];
 }
@@ -74,7 +75,7 @@
   NSData* rawBytes = message.data;
   XCTAssertEqual(message.serializedSize, (size_t)rawBytes.length);
 
-  TestAllTypes* message2 = [TestAllTypes parseFromData:rawBytes];
+  TestAllTypes* message2 = [TestAllTypes parseFromData:rawBytes error:NULL];
 
   [self assertAllFieldsSet:message2 repeatedCount:kGPBDefaultRepeatCount];
 }
@@ -103,8 +104,9 @@
 
   GPBExtensionRegistry* registry = [self extensionRegistry];
 
-  TestAllExtensions* message2 =
-      [TestAllExtensions parseFromData:rawBytes extensionRegistry:registry];
+  TestAllExtensions* message2 = [TestAllExtensions parseFromData:rawBytes
+                                               extensionRegistry:registry
+                                                           error:NULL];
 
   [self assertAllExtensionsSet:message2 repeatedCount:kGPBDefaultRepeatCount];
 }
@@ -124,8 +126,9 @@
 
   GPBExtensionRegistry* registry = [self extensionRegistry];
 
-  TestPackedExtensions* message2 =
-      [TestPackedExtensions parseFromData:rawBytes extensionRegistry:registry];
+  TestPackedExtensions* message2 = [TestPackedExtensions parseFromData:rawBytes
+                                                     extensionRegistry:registry
+                                                                 error:NULL];
 
   [self assertPackedExtensionsSet:message2
                     repeatedCount:kGPBDefaultRepeatCount];
@@ -151,7 +154,7 @@ const int kUnknownTypeId = 1550055;
   NSData* data = [message_set data];
 
   // Parse back using RawMessageSet and check the contents.
-  RawMessageSet* raw = [RawMessageSet parseFromData:data];
+  RawMessageSet* raw = [RawMessageSet parseFromData:data error:NULL];
 
   XCTAssertEqual([raw.unknownFields countOfFields], (NSUInteger)0);
 
@@ -163,11 +166,13 @@ const int kUnknownTypeId = 1550055;
   XCTAssertEqual([raw.itemArray[2] typeId], kUnknownTypeId);
 
   TestMessageSetExtension1* message1 =
-      [TestMessageSetExtension1 parseFromData:[raw.itemArray[0] message]];
+      [TestMessageSetExtension1 parseFromData:[raw.itemArray[0] message]
+                                        error:NULL];
   XCTAssertEqual(message1.i, 123);
 
   TestMessageSetExtension2* message2 =
-      [TestMessageSetExtension2 parseFromData:[raw.itemArray[1] message]];
+      [TestMessageSetExtension2 parseFromData:[raw.itemArray[1] message]
+                                        error:NULL];
   XCTAssertEqualObjects(message2.str, @"foo");
 
   XCTAssertEqualObjects([raw.itemArray[2] message],
@@ -209,7 +214,8 @@ const int kUnknownTypeId = 1550055;
   // Parse as a TestMessageSet and check the contents.
   TestMessageSet* messageSet =
       [TestMessageSet parseFromData:data
-                  extensionRegistry:[UnittestMsetRoot extensionRegistry]];
+                  extensionRegistry:[UnittestMsetRoot extensionRegistry]
+                              error:NULL];
 
   XCTAssertEqual(
       [[messageSet

+ 2 - 0
objectivec/Tests/unittest_objc.proto

@@ -44,6 +44,8 @@ message TestRecursiveMessageWithRepeatedField {
   optional TestRecursiveMessageWithRepeatedField a = 1;
   repeated int32 i = 2;
   repeated string str = 3;
+  map<int32, int32> i_to_i = 4;
+  map<string, string> str_to_str = 5;
 }
 
 // Recursive message and extension to for testing autocreators at different

+ 21 - 0
objectivec/Tests/unittest_runtime_proto2.proto

@@ -105,4 +105,25 @@ message Message2 {
      Message2 oneof_message = 68;
      Enum        oneof_enum = 69 [default = BAZ];
   }
+
+  // Some token map cases, too many combinations to list them all.
+  map<int32   , int32   > map_int32_int32       = 70;
+  map<int64   , int64   > map_int64_int64       = 71;
+  map<uint32  , uint32  > map_uint32_uint32     = 72;
+  map<uint64  , uint64  > map_uint64_uint64     = 73;
+  map<sint32  , sint32  > map_sint32_sint32     = 74;
+  map<sint64  , sint64  > map_sint64_sint64     = 75;
+  map<fixed32 , fixed32 > map_fixed32_fixed32   = 76;
+  map<fixed64 , fixed64 > map_fixed64_fixed64   = 77;
+  map<sfixed32, sfixed32> map_sfixed32_sfixed32 = 78;
+  map<sfixed64, sfixed64> map_sfixed64_sfixed64 = 79;
+  map<int32   , float   > map_int32_float       = 80;
+  map<int32   , double  > map_int32_double      = 81;
+  map<bool    , bool    > map_bool_bool         = 82;
+  map<string  , string  > map_string_string     = 83;
+  map<string  , bytes   > map_string_bytes      = 84;
+  map<string  , Message2> map_string_message    = 85;
+  map<int32   , bytes   > map_int32_bytes       = 86;
+  map<int32   , Enum    > map_int32_enum        = 87;
+  map<int32   , Message2> map_int32_message     = 88;
 }

+ 21 - 0
objectivec/Tests/unittest_runtime_proto3.proto

@@ -98,4 +98,25 @@ message Message3 {
     Message3 oneof_message  = 68;
         Enum oneof_enum     = 69;
   }
+
+  // Some token map cases, too many combinations to list them all.
+  map<int32   , int32   > map_int32_int32       = 70;
+  map<int64   , int64   > map_int64_int64       = 71;
+  map<uint32  , uint32  > map_uint32_uint32     = 72;
+  map<uint64  , uint64  > map_uint64_uint64     = 73;
+  map<sint32  , sint32  > map_sint32_sint32     = 74;
+  map<sint64  , sint64  > map_sint64_sint64     = 75;
+  map<fixed32 , fixed32 > map_fixed32_fixed32   = 76;
+  map<fixed64 , fixed64 > map_fixed64_fixed64   = 77;
+  map<sfixed32, sfixed32> map_sfixed32_sfixed32 = 78;
+  map<sfixed64, sfixed64> map_sfixed64_sfixed64 = 79;
+  map<int32   , float   > map_int32_float       = 80;
+  map<int32   , double  > map_int32_double      = 81;
+  map<bool    , bool    > map_bool_bool         = 82;
+  map<string  , string  > map_string_string     = 83;
+  map<string  , bytes   > map_string_bytes      = 84;
+  map<string  , Message3> map_string_message    = 85;
+  map<int32   , bytes   > map_int32_bytes       = 86;
+  map<int32   , Enum    > map_int32_enum        = 87;
+  map<int32   , Message3> map_int32_message     = 88;
 }

+ 54 - 0
objectivec/generate_descriptors_proto.sh

@@ -0,0 +1,54 @@
+#!/bin/bash
+
+# Run this script to regenerate descriptor.pbobjc.{h,m} after the protocol
+# compiler changes.
+
+# HINT:  Flags passed to generate_descriptor_proto.sh will be passed directly
+#   to make when building protoc.  This is particularly useful for passing
+#   -j4 to run 4 jobs simultaneously.
+
+set -eu
+
+readonly ScriptDir=$(dirname "$(echo $0 | sed -e "s,^\([^/]\),$(pwd)/\1,")")
+readonly ProtoRootDir="${ScriptDir}/.."
+readonly ProtoC="${ProtoRootDir}/src/protoc"
+
+pushd "${ProtoRootDir}" > /dev/null
+
+if test ! -e src/google/protobuf/stubs/common.h; then
+  cat >&2 << __EOF__
+Could not find source code.  Make sure you are running this script from the
+root of the distribution tree.
+__EOF__
+  exit 1
+fi
+
+if test ! -e src/Makefile; then
+  cat >&2 << __EOF__
+Could not find src/Makefile.  You must run ./configure (and perhaps
+./autogen.sh) first.
+__EOF__
+  exit 1
+fi
+
+# Make sure the compiler is current.
+cd src
+make $@ google/protobuf/stubs/pbconfig.h
+make $@ protoc
+
+declare -a RUNTIME_PROTO_FILES=(\
+  google/protobuf/any.proto \
+  google/protobuf/api.proto \
+  google/protobuf/descriptor.proto \
+  google/protobuf/duration.proto \
+  google/protobuf/empty.proto \
+  google/protobuf/field_mask.proto \
+  google/protobuf/source_context.proto \
+  google/protobuf/struct.proto \
+  google/protobuf/timestamp.proto \
+  google/protobuf/type.proto \
+  google/protobuf/wrappers.proto)
+
+./protoc --objc_out="${ProtoRootDir}/objectivec" ${RUNTIME_PROTO_FILES[@]}
+
+popd > /dev/null

+ 100 - 0
objectivec/google/protobuf/Any.pbobjc.h

@@ -0,0 +1,100 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: google/protobuf/any.proto
+
+#import "GPBProtocolBuffers.h"
+
+#if GOOGLE_PROTOBUF_OBJC_GEN_VERSION != 30000
+#error This file was generated by a different version of protoc-gen-objc which is incompatible with your Protocol Buffer sources.
+#endif
+
+// @@protoc_insertion_point(imports)
+
+CF_EXTERN_C_BEGIN
+
+
+#pragma mark - GPBAnyRoot
+
+@interface GPBAnyRoot : GPBRootObject
+
+// The base class provides:
+//   + (GPBExtensionRegistry *)extensionRegistry;
+// which is an GPBExtensionRegistry that includes all the extensions defined by
+// this file and all files that it depends on.
+
+@end
+
+#pragma mark - GPBAny
+
+typedef GPB_ENUM(GPBAny_FieldNumber) {
+  GPBAny_FieldNumber_TypeURL = 1,
+  GPBAny_FieldNumber_Value = 2,
+};
+
+// `Any` contains an arbitrary serialized message along with a URL
+// that describes the type of the serialized message.
+//
+// The proto runtimes and/or compiler will eventually
+//  provide utilities to pack/unpack Any values (projected Q1/15).
+//
+// # JSON
+// The JSON representation of an `Any` value uses the regular
+// representation of the deserialized, embedded message, with an
+// additional field `@type` which contains the type URL. Example:
+//
+//     package google.profile;
+//     message Person {
+//       string first_name = 1;
+//       string last_name = 2;
+//     }
+//
+//     {
+//       "@type": "type.googleapis.com/google.profile.Person",
+//       "firstName": <string>,
+//       "lastName": <string>
+//     }
+//
+// If the embedded message type is well-known and has a custom JSON
+// representation, that representation will be embedded adding a field
+// `value` which holds the custom JSON in addition to the the `@type`
+// field. Example (for message [google.protobuf.Duration][google.protobuf.Duration]):
+//
+//     {
+//       "@type": "type.googleapis.com/google.protobuf.Duration",
+//       "value": "1.212s"
+//     }
+@interface GPBAny : GPBMessage
+
+// A URL/resource name whose content describes the type of the
+// serialized message.
+//
+// For URLs which use the schema `http`, `https`, or no schema, the
+// following restrictions and interpretations apply:
+//
+// * If no schema is provided, `https` is assumed.
+// * The last segment of the URL's path must represent the fully
+//   qualified name of the type (as in `path/google.protobuf.Duration`).
+// * An HTTP GET on the URL must yield a [google.protobuf.Type][google.protobuf.Type]
+//   value in binary format, or produce an error.
+// * Applications are allowed to cache lookup results based on the
+//   URL, or have them precompiled into a binary to avoid any
+//   lookup. Therefore, binary compatibility needs to be preserved
+//   on changes to types. (Use versioned type names to manage
+//   breaking changes.)
+//
+// Schemas other than `http`, `https` (or the empty schema) might be
+// used with implementation specific semantics.
+//
+// Types originating from the `google.*` package
+// namespace should use `type.googleapis.com/full.type.name` (without
+// schema and path). A type service will eventually become available which
+// serves those URLs (projected Q2/15).
+@property(nonatomic, readwrite, copy) NSString *typeURL;
+
+// Must be valid serialized data of the above specified type.
+@property(nonatomic, readwrite, copy) NSData *value;
+
+@end
+
+CF_EXTERN_C_END
+
+// @@protoc_insertion_point(global_scope)

+ 93 - 0
objectivec/google/protobuf/Any.pbobjc.m

@@ -0,0 +1,93 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: google/protobuf/any.proto
+
+#import "GPBProtocolBuffers_RuntimeSupport.h"
+#import "google/protobuf/Any.pbobjc.h"
+// @@protoc_insertion_point(imports)
+
+#pragma mark - GPBAnyRoot
+
+@implementation GPBAnyRoot
+
+@end
+
+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) {
+    descriptor = [[GPBFileDescriptor alloc] initWithPackage:@"google.protobuf"
+                                                     syntax:GPBFileSyntaxProto3];
+  }
+  return descriptor;
+}
+
+#pragma mark - GPBAny
+
+@implementation GPBAny
+
+@dynamic typeURL;
+@dynamic value;
+
+typedef struct GPBAny_Storage {
+  uint32_t _has_storage_[1];
+  NSString *typeURL;
+  NSData *value;
+} GPBAny_Storage;
+
+// This method is threadsafe because it is initially called
+// in +initialize for each subclass.
++ (GPBDescriptor *)descriptor {
+  static GPBDescriptor *descriptor = NULL;
+  if (!descriptor) {
+    static GPBMessageFieldDescription fields[] = {
+      {
+        .name = "typeURL",
+        .number = GPBAny_FieldNumber_TypeURL,
+        .hasIndex = 0,
+        .flags = GPBFieldOptional | GPBFieldTextFormatNameCustom,
+        .type = GPBTypeString,
+        .offset = offsetof(GPBAny_Storage, typeURL),
+        .defaultValue.valueString = nil,
+        .typeSpecific.className = NULL,
+        .fieldOptions = NULL,
+      },
+      {
+        .name = "value",
+        .number = GPBAny_FieldNumber_Value,
+        .hasIndex = 1,
+        .flags = GPBFieldOptional,
+        .type = GPBTypeData,
+        .offset = offsetof(GPBAny_Storage, value),
+        .defaultValue.valueData = nil,
+        .typeSpecific.className = NULL,
+        .fieldOptions = NULL,
+      },
+    };
+#if GPBOBJC_SKIP_MESSAGE_TEXTFORMAT_EXTRAS
+    const char *extraTextFormatInfo = NULL;
+#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];
+  }
+  return descriptor;
+}
+
+@end
+
+
+// @@protoc_insertion_point(global_scope)

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

@@ -0,0 +1,121 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: google/protobuf/api.proto
+
+#import "GPBProtocolBuffers.h"
+
+#if GOOGLE_PROTOBUF_OBJC_GEN_VERSION != 30000
+#error This file was generated by a different version of protoc-gen-objc which is incompatible with your Protocol Buffer sources.
+#endif
+
+// @@protoc_insertion_point(imports)
+
+CF_EXTERN_C_BEGIN
+
+@class GPBSourceContext;
+
+
+#pragma mark - GPBApiRoot
+
+@interface GPBApiRoot : GPBRootObject
+
+// The base class provides:
+//   + (GPBExtensionRegistry *)extensionRegistry;
+// which is an GPBExtensionRegistry that includes all the extensions defined by
+// this file and all files that it depends on.
+
+@end
+
+#pragma mark - GPBApi
+
+typedef GPB_ENUM(GPBApi_FieldNumber) {
+  GPBApi_FieldNumber_Name = 1,
+  GPBApi_FieldNumber_MethodsArray = 2,
+  GPBApi_FieldNumber_OptionsArray = 3,
+  GPBApi_FieldNumber_Version = 4,
+  GPBApi_FieldNumber_SourceContext = 5,
+};
+
+// Api is a light-weight descriptor for a protocol buffer service.
+@interface GPBApi : GPBMessage
+
+// The fully qualified name of this api, including package name
+// followed by the api's simple name.
+@property(nonatomic, readwrite, copy) NSString *name;
+
+// The methods of this api, in unspecified order.
+// |methodsArray| contains |GPBMethod|
+@property(nonatomic, readwrite, strong) NSMutableArray *methodsArray;
+
+// Any metadata attached to the API.
+// |optionsArray| contains |GPBOption|
+@property(nonatomic, readwrite, strong) NSMutableArray *optionsArray;
+
+// A version string for this api. If specified, must have the form
+// `major-version.minor-version`, as in `1.10`. If the minor version
+// is omitted, it defaults to zero. If the entire version field is
+// empty, the major version is derived from the package name, as
+// outlined below. If the field is not empty, the version in the
+// package name will be verified to be consistent with what is
+// provided here.
+//
+// The versioning schema uses [semantic
+// versioning](http://semver.org) where the major version number
+// indicates a breaking change and the minor version an additive,
+// non-breaking change. Both version numbers are signals to users
+// what to expect from different versions, and should be carefully
+// chosen based on the product plan.
+//
+// The major version is also reflected in the package name of the
+// API, which must end in `v<major-version>`, as in
+// `google.feature.v1`. For major versions 0 and 1, the suffix can
+// be omitted. Zero major versions must only be used for
+// experimental, none-GA apis.
+//
+// See also: [design doc](http://go/api-versioning).
+@property(nonatomic, readwrite, copy) NSString *version;
+
+// Source context for the protocol buffer service represented by this
+// message.
+@property(nonatomic, readwrite) BOOL hasSourceContext;
+@property(nonatomic, readwrite, strong) GPBSourceContext *sourceContext;
+
+@end
+
+#pragma mark - GPBMethod
+
+typedef GPB_ENUM(GPBMethod_FieldNumber) {
+  GPBMethod_FieldNumber_Name = 1,
+  GPBMethod_FieldNumber_RequestTypeURL = 2,
+  GPBMethod_FieldNumber_RequestStreaming = 3,
+  GPBMethod_FieldNumber_ResponseTypeURL = 4,
+  GPBMethod_FieldNumber_ResponseStreaming = 5,
+  GPBMethod_FieldNumber_OptionsArray = 6,
+};
+
+// Method represents a method of an api.
+@interface GPBMethod : GPBMessage
+
+// The simple name of this method.
+@property(nonatomic, readwrite, copy) NSString *name;
+
+// A URL of the input message type.
+@property(nonatomic, readwrite, copy) NSString *requestTypeURL;
+
+// If true, the request is streamed.
+@property(nonatomic, readwrite) BOOL requestStreaming;
+
+// The URL of the output message type.
+@property(nonatomic, readwrite, copy) NSString *responseTypeURL;
+
+// If true, the response is streamed.
+@property(nonatomic, readwrite) BOOL responseStreaming;
+
+// Any metadata attached to the method.
+// |optionsArray| contains |GPBOption|
+@property(nonatomic, readwrite, strong) NSMutableArray *optionsArray;
+
+@end
+
+CF_EXTERN_C_END
+
+// @@protoc_insertion_point(global_scope)

+ 262 - 0
objectivec/google/protobuf/Api.pbobjc.m

@@ -0,0 +1,262 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: google/protobuf/api.proto
+
+#import "GPBProtocolBuffers_RuntimeSupport.h"
+#import "google/protobuf/Api.pbobjc.h"
+#import "google/protobuf/SourceContext.pbobjc.h"
+#import "google/protobuf/Type.pbobjc.h"
+// @@protoc_insertion_point(imports)
+
+#pragma mark - GPBApiRoot
+
+@implementation GPBApiRoot
+
++ (GPBExtensionRegistry*)extensionRegistry {
+  // This is called by +initialize so there is no need to worry
+  // about thread safety and initialization of registry.
+  static GPBExtensionRegistry* registry = nil;
+  if (!registry) {
+    registry = [[GPBExtensionRegistry alloc] init];
+    static GPBExtensionDescription descriptions[] = {
+    };
+    #pragma unused (descriptions)
+    [registry addExtensions:[GPBSourceContextRoot extensionRegistry]];
+    [registry addExtensions:[GPBTypeRoot extensionRegistry]];
+  }
+  return registry;
+}
+
+@end
+
+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) {
+    descriptor = [[GPBFileDescriptor alloc] initWithPackage:@"google.protobuf"
+                                                     syntax:GPBFileSyntaxProto3];
+  }
+  return descriptor;
+}
+
+#pragma mark - GPBApi
+
+@implementation GPBApi
+
+@dynamic name;
+@dynamic methodsArray;
+@dynamic optionsArray;
+@dynamic version;
+@dynamic hasSourceContext, sourceContext;
+
+typedef struct GPBApi_Storage {
+  uint32_t _has_storage_[1];
+  NSString *name;
+  NSMutableArray *methodsArray;
+  NSMutableArray *optionsArray;
+  NSString *version;
+  GPBSourceContext *sourceContext;
+} GPBApi_Storage;
+
+// This method is threadsafe because it is initially called
+// in +initialize for each subclass.
++ (GPBDescriptor *)descriptor {
+  static GPBDescriptor *descriptor = NULL;
+  if (!descriptor) {
+    static GPBMessageFieldDescription fields[] = {
+      {
+        .name = "name",
+        .number = GPBApi_FieldNumber_Name,
+        .hasIndex = 0,
+        .flags = GPBFieldOptional,
+        .type = GPBTypeString,
+        .offset = offsetof(GPBApi_Storage, name),
+        .defaultValue.valueString = nil,
+        .typeSpecific.className = NULL,
+        .fieldOptions = NULL,
+      },
+      {
+        .name = "methodsArray",
+        .number = GPBApi_FieldNumber_MethodsArray,
+        .hasIndex = GPBNoHasBit,
+        .flags = GPBFieldRepeated,
+        .type = GPBTypeMessage,
+        .offset = offsetof(GPBApi_Storage, methodsArray),
+        .defaultValue.valueMessage = nil,
+        .typeSpecific.className = GPBStringifySymbol(GPBMethod),
+        .fieldOptions = NULL,
+      },
+      {
+        .name = "optionsArray",
+        .number = GPBApi_FieldNumber_OptionsArray,
+        .hasIndex = GPBNoHasBit,
+        .flags = GPBFieldRepeated,
+        .type = GPBTypeMessage,
+        .offset = offsetof(GPBApi_Storage, optionsArray),
+        .defaultValue.valueMessage = nil,
+        .typeSpecific.className = GPBStringifySymbol(GPBOption),
+        .fieldOptions = NULL,
+      },
+      {
+        .name = "version",
+        .number = GPBApi_FieldNumber_Version,
+        .hasIndex = 3,
+        .flags = GPBFieldOptional,
+        .type = GPBTypeString,
+        .offset = offsetof(GPBApi_Storage, version),
+        .defaultValue.valueString = nil,
+        .typeSpecific.className = NULL,
+        .fieldOptions = NULL,
+      },
+      {
+        .name = "sourceContext",
+        .number = GPBApi_FieldNumber_SourceContext,
+        .hasIndex = 4,
+        .flags = GPBFieldOptional,
+        .type = GPBTypeMessage,
+        .offset = offsetof(GPBApi_Storage, sourceContext),
+        .defaultValue.valueMessage = nil,
+        .typeSpecific.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];
+  }
+  return descriptor;
+}
+
+@end
+
+#pragma mark - GPBMethod
+
+@implementation GPBMethod
+
+@dynamic name;
+@dynamic requestTypeURL;
+@dynamic requestStreaming;
+@dynamic responseTypeURL;
+@dynamic responseStreaming;
+@dynamic optionsArray;
+
+typedef struct GPBMethod_Storage {
+  uint32_t _has_storage_[1];
+  BOOL requestStreaming;
+  BOOL responseStreaming;
+  NSString *name;
+  NSString *requestTypeURL;
+  NSString *responseTypeURL;
+  NSMutableArray *optionsArray;
+} GPBMethod_Storage;
+
+// This method is threadsafe because it is initially called
+// in +initialize for each subclass.
++ (GPBDescriptor *)descriptor {
+  static GPBDescriptor *descriptor = NULL;
+  if (!descriptor) {
+    static GPBMessageFieldDescription fields[] = {
+      {
+        .name = "name",
+        .number = GPBMethod_FieldNumber_Name,
+        .hasIndex = 0,
+        .flags = GPBFieldOptional,
+        .type = GPBTypeString,
+        .offset = offsetof(GPBMethod_Storage, name),
+        .defaultValue.valueString = nil,
+        .typeSpecific.className = NULL,
+        .fieldOptions = NULL,
+      },
+      {
+        .name = "requestTypeURL",
+        .number = GPBMethod_FieldNumber_RequestTypeURL,
+        .hasIndex = 1,
+        .flags = GPBFieldOptional | GPBFieldTextFormatNameCustom,
+        .type = GPBTypeString,
+        .offset = offsetof(GPBMethod_Storage, requestTypeURL),
+        .defaultValue.valueString = nil,
+        .typeSpecific.className = NULL,
+        .fieldOptions = NULL,
+      },
+      {
+        .name = "requestStreaming",
+        .number = GPBMethod_FieldNumber_RequestStreaming,
+        .hasIndex = 2,
+        .flags = GPBFieldOptional,
+        .type = GPBTypeBool,
+        .offset = offsetof(GPBMethod_Storage, requestStreaming),
+        .defaultValue.valueBool = NO,
+        .typeSpecific.className = NULL,
+        .fieldOptions = NULL,
+      },
+      {
+        .name = "responseTypeURL",
+        .number = GPBMethod_FieldNumber_ResponseTypeURL,
+        .hasIndex = 3,
+        .flags = GPBFieldOptional | GPBFieldTextFormatNameCustom,
+        .type = GPBTypeString,
+        .offset = offsetof(GPBMethod_Storage, responseTypeURL),
+        .defaultValue.valueString = nil,
+        .typeSpecific.className = NULL,
+        .fieldOptions = NULL,
+      },
+      {
+        .name = "responseStreaming",
+        .number = GPBMethod_FieldNumber_ResponseStreaming,
+        .hasIndex = 4,
+        .flags = GPBFieldOptional,
+        .type = GPBTypeBool,
+        .offset = offsetof(GPBMethod_Storage, responseStreaming),
+        .defaultValue.valueBool = NO,
+        .typeSpecific.className = NULL,
+        .fieldOptions = NULL,
+      },
+      {
+        .name = "optionsArray",
+        .number = GPBMethod_FieldNumber_OptionsArray,
+        .hasIndex = GPBNoHasBit,
+        .flags = GPBFieldRepeated,
+        .type = GPBTypeMessage,
+        .offset = offsetof(GPBMethod_Storage, optionsArray),
+        .defaultValue.valueMessage = nil,
+        .typeSpecific.className = GPBStringifySymbol(GPBOption),
+        .fieldOptions = NULL,
+      },
+    };
+#if GPBOBJC_SKIP_MESSAGE_TEXTFORMAT_EXTRAS
+    const char *extraTextFormatInfo = NULL;
+#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];
+  }
+  return descriptor;
+}
+
+@end
+
+
+// @@protoc_insertion_point(global_scope)

+ 10 - 13
objectivec/google/protobuf/Descriptor.pbobjc.h

@@ -7,29 +7,18 @@
 #error This file was generated by a different version of protoc-gen-objc which is incompatible with your Protocol Buffer sources.
 #endif
 
+// @@protoc_insertion_point(imports)
+
 CF_EXTERN_C_BEGIN
 
-@class GPBDescriptorProto;
-@class GPBDescriptorProto_ExtensionRange;
-@class GPBEnumDescriptorProto;
 @class GPBEnumOptions;
-@class GPBEnumValueDescriptorProto;
 @class GPBEnumValueOptions;
-@class GPBFieldDescriptorProto;
 @class GPBFieldOptions;
-@class GPBFileDescriptorProto;
-@class GPBFileDescriptorSet;
 @class GPBFileOptions;
 @class GPBMessageOptions;
-@class GPBMethodDescriptorProto;
 @class GPBMethodOptions;
-@class GPBOneofDescriptorProto;
-@class GPBServiceDescriptorProto;
 @class GPBServiceOptions;
 @class GPBSourceCodeInfo;
-@class GPBSourceCodeInfo_Location;
-@class GPBUninterpretedOption;
-@class GPBUninterpretedOption_NamePart;
 
 #pragma mark - Enum GPBFieldDescriptorProto_Type
 
@@ -126,6 +115,12 @@ BOOL GPBFieldOptions_CType_IsValidValue(int32_t value);
 #pragma mark - GPBDescriptorRoot
 
 @interface GPBDescriptorRoot : GPBRootObject
+
+// The base class provides:
+//   + (GPBExtensionRegistry *)extensionRegistry;
+// which is an GPBExtensionRegistry that includes all the extensions defined by
+// this file and all files that it depends on.
+
 @end
 
 #pragma mark - GPBFileDescriptorSet
@@ -1049,3 +1044,5 @@ typedef GPB_ENUM(GPBSourceCodeInfo_Location_FieldNumber) {
 @end
 
 CF_EXTERN_C_END
+
+// @@protoc_insertion_point(global_scope)

+ 3 - 1
objectivec/google/protobuf/Descriptor.pbobjc.m

@@ -2,8 +2,8 @@
 // source: google/protobuf/descriptor.proto
 
 #import "GPBProtocolBuffers_RuntimeSupport.h"
-
 #import "google/protobuf/Descriptor.pbobjc.h"
+// @@protoc_insertion_point(imports)
 
 #pragma mark - GPBDescriptorRoot
 
@@ -2216,3 +2216,5 @@ typedef struct GPBSourceCodeInfo_Location_Storage {
 
 @end
 
+
+// @@protoc_insertion_point(global_scope)

+ 10 - 2
objectivec/google/protobuf/Duration.pbobjc.h

@@ -7,14 +7,20 @@
 #error This file was generated by a different version of protoc-gen-objc which is incompatible with your Protocol Buffer sources.
 #endif
 
-CF_EXTERN_C_BEGIN
+// @@protoc_insertion_point(imports)
 
-@class GPBDuration;
+CF_EXTERN_C_BEGIN
 
 
 #pragma mark - GPBDurationRoot
 
 @interface GPBDurationRoot : GPBRootObject
+
+// The base class provides:
+//   + (GPBExtensionRegistry *)extensionRegistry;
+// which is an GPBExtensionRegistry that includes all the extensions defined by
+// this file and all files that it depends on.
+
 @end
 
 #pragma mark - GPBDuration
@@ -81,3 +87,5 @@ typedef GPB_ENUM(GPBDuration_FieldNumber) {
 @end
 
 CF_EXTERN_C_END
+
+// @@protoc_insertion_point(global_scope)

+ 3 - 1
objectivec/google/protobuf/Duration.pbobjc.m

@@ -2,8 +2,8 @@
 // source: google/protobuf/duration.proto
 
 #import "GPBProtocolBuffers_RuntimeSupport.h"
-
 #import "google/protobuf/Duration.pbobjc.h"
+// @@protoc_insertion_point(imports)
 
 #pragma mark - GPBDurationRoot
 
@@ -83,3 +83,5 @@ typedef struct GPBDuration_Storage {
 
 @end
 
+
+// @@protoc_insertion_point(global_scope)

+ 41 - 0
objectivec/google/protobuf/Empty.pbobjc.h

@@ -0,0 +1,41 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: google/protobuf/empty.proto
+
+#import "GPBProtocolBuffers.h"
+
+#if GOOGLE_PROTOBUF_OBJC_GEN_VERSION != 30000
+#error This file was generated by a different version of protoc-gen-objc which is incompatible with your Protocol Buffer sources.
+#endif
+
+// @@protoc_insertion_point(imports)
+
+CF_EXTERN_C_BEGIN
+
+
+#pragma mark - GPBEmptyRoot
+
+@interface GPBEmptyRoot : GPBRootObject
+
+// The base class provides:
+//   + (GPBExtensionRegistry *)extensionRegistry;
+// which is an GPBExtensionRegistry that includes all the extensions defined by
+// this file and all files that it depends on.
+
+@end
+
+#pragma mark - GPBEmpty
+
+// A generic empty message that you can re-use to avoid defining duplicated
+// empty messages in your APIs. A typical example is to use it as the request
+// or the response type of an API method. For instance:
+//
+//     service Foo {
+//       rpc Bar(google.protobuf.Empty) returns (google.protobuf.Empty);
+//     }
+@interface GPBEmpty : GPBMessage
+
+@end
+
+CF_EXTERN_C_END
+
+// @@protoc_insertion_point(global_scope)

+ 61 - 0
objectivec/google/protobuf/Empty.pbobjc.m

@@ -0,0 +1,61 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: google/protobuf/empty.proto
+
+#import "GPBProtocolBuffers_RuntimeSupport.h"
+#import "google/protobuf/Empty.pbobjc.h"
+// @@protoc_insertion_point(imports)
+
+#pragma mark - GPBEmptyRoot
+
+@implementation GPBEmptyRoot
+
+@end
+
+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) {
+    descriptor = [[GPBFileDescriptor alloc] initWithPackage:@"google.protobuf"
+                                                     syntax:GPBFileSyntaxProto3];
+  }
+  return descriptor;
+}
+
+#pragma mark - GPBEmpty
+
+@implementation GPBEmpty
+
+
+typedef struct GPBEmpty_Storage {
+  uint32_t _has_storage_[0];
+} GPBEmpty_Storage;
+
+// This method is threadsafe because it is initially called
+// in +initialize for each subclass.
++ (GPBDescriptor *)descriptor {
+  static GPBDescriptor *descriptor = NULL;
+  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];
+  }
+  return descriptor;
+}
+
+@end
+
+
+// @@protoc_insertion_point(global_scope)

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

@@ -0,0 +1,160 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: google/protobuf/field_mask.proto
+
+#import "GPBProtocolBuffers.h"
+
+#if GOOGLE_PROTOBUF_OBJC_GEN_VERSION != 30000
+#error This file was generated by a different version of protoc-gen-objc which is incompatible with your Protocol Buffer sources.
+#endif
+
+// @@protoc_insertion_point(imports)
+
+CF_EXTERN_C_BEGIN
+
+
+#pragma mark - GPBFieldMaskRoot
+
+@interface GPBFieldMaskRoot : GPBRootObject
+
+// The base class provides:
+//   + (GPBExtensionRegistry *)extensionRegistry;
+// which is an GPBExtensionRegistry that includes all the extensions defined by
+// this file and all files that it depends on.
+
+@end
+
+#pragma mark - GPBFieldMask
+
+typedef GPB_ENUM(GPBFieldMask_FieldNumber) {
+  GPBFieldMask_FieldNumber_PathsArray = 1,
+};
+
+// `FieldMask` represents a set of symbolic field paths, for example:
+//
+//     paths: "f.a"
+//     paths: "f.b.d"
+//
+// Here `f` represents a field in some root message, `a` and `b`
+// fields in the message found in `f`, and `d` a field found in the
+// message in `f.b`.
+//
+// Field masks are used to specify a subset of fields that should be
+// returned by a get operation or modified by an update operation.
+// Field masks also have a custom JSON encoding (see below).
+//
+// # Field Masks in Projections
+// When used in the context of a projection, a response message or
+// sub-message is filtered by the API to only contain those fields as
+// specified in the mask. For example, if the mask in the previous
+// example is applied to a response message as follows:
+//
+//     f {
+//       a : 22
+//       b {
+//         d : 1
+//         x : 2
+//       }
+//       y : 13
+//     }
+//     z: 8
+//
+// The result will not contain specific values for fields x,y and z
+// (there value will be set to the default, and omitted in proto text
+// output):
+//
+//
+//     f {
+//       a : 22
+//       b {
+//         d : 1
+//       }
+//     }
+//
+// A repeated field is not allowed except at the last position of a
+// field mask.
+//
+// If a FieldMask object is not present in a get operation, the
+// operation applies to all fields (as if a FieldMask of all fields
+// had been specified).
+//
+// Note that a field mask does not necessarily applies to the
+// top-level response message. In case of a REST get operation, the
+// field mask applies directly to the response, but in case of a REST
+// list operation, the mask instead applies to each individual message
+// in the returned resource list. In case of a REST custom method,
+// other definitions may be used. Where the mask applies will be
+// clearly documented together with its declaration in the API.  In
+// any case, the effect on the returned resource/resources is required
+// behavior for APIs.
+//
+// # Field Masks in Update Operations
+// A field mask in update operations specifies which fields of the
+// targeted resource are going to be updated. The API is required
+// to only change the values of the fields as specified in the mask
+// and leave the others untouched. If a resource is passed in to
+// describe the updated values, the API ignores the values of all
+// fields not covered by the mask.
+//
+// In order to reset a field's value to the default, the field must
+// be in the mask and set to the default value in the provided resource.
+// Hence, in order to reset all fields of a resource, provide a default
+// instance of the resource and set all fields in the mask, or do
+// not provide a mask as described below.
+//
+// If a field mask is not present on update, the operation applies to
+// all fields (as if a field mask of all fields has been specified).
+// Note that in the presence of schema evolution, this may mean that
+// fields the client does not know and has therefore not filled into
+// the request will be reset to their default. If this is unwanted
+// behavior, a specific service may require a client to always specify
+// a field mask, producing an error if not.
+//
+// As with get operations, the location of the resource which
+// describes the updated values in the request message depends on the
+// operation kind. In any case, the effect of the field mask is
+// required to be honored by the API.
+//
+// ## Considerations for HTTP REST
+// The HTTP kind of an update operation which uses a field mask must
+// be set to PATCH instead of PUT in order to satisfy HTTP semantics
+// (PUT must only be used for full updates).
+//
+// # JSON Encoding of Field Masks
+// In JSON, a field mask is encoded as a single string where paths are
+// separated by a comma. Fields name in each path are converted
+// to/from lower-camel naming conventions.
+//
+// As an example, consider the following message declarations:
+//
+//     message Profile {
+//       User user = 1;
+//       Photo photo = 2;
+//     }
+//     message User {
+//       string display_name = 1;
+//       string address = 2;
+//     }
+//
+// In proto a field mask for `Profile` may look as such:
+//
+//     mask {
+//       paths: "user.display_name"
+//       paths: "photo"
+//     }
+//
+// In JSON, the same mask is represented as below:
+//
+//     {
+//       mask: "user.displayName,photo"
+//     }
+@interface GPBFieldMask : GPBMessage
+
+// The set of field mask paths.
+// |pathsArray| contains |NSString|
+@property(nonatomic, readwrite, strong) NSMutableArray *pathsArray;
+
+@end
+
+CF_EXTERN_C_END
+
+// @@protoc_insertion_point(global_scope)

+ 74 - 0
objectivec/google/protobuf/FieldMask.pbobjc.m

@@ -0,0 +1,74 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: google/protobuf/field_mask.proto
+
+#import "GPBProtocolBuffers_RuntimeSupport.h"
+#import "google/protobuf/FieldMask.pbobjc.h"
+// @@protoc_insertion_point(imports)
+
+#pragma mark - GPBFieldMaskRoot
+
+@implementation GPBFieldMaskRoot
+
+@end
+
+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) {
+    descriptor = [[GPBFileDescriptor alloc] initWithPackage:@"google.protobuf"
+                                                     syntax:GPBFileSyntaxProto3];
+  }
+  return descriptor;
+}
+
+#pragma mark - GPBFieldMask
+
+@implementation GPBFieldMask
+
+@dynamic pathsArray;
+
+typedef struct GPBFieldMask_Storage {
+  uint32_t _has_storage_[1];
+  NSMutableArray *pathsArray;
+} GPBFieldMask_Storage;
+
+// This method is threadsafe because it is initially called
+// in +initialize for each subclass.
++ (GPBDescriptor *)descriptor {
+  static GPBDescriptor *descriptor = NULL;
+  if (!descriptor) {
+    static GPBMessageFieldDescription fields[] = {
+      {
+        .name = "pathsArray",
+        .number = GPBFieldMask_FieldNumber_PathsArray,
+        .hasIndex = GPBNoHasBit,
+        .flags = GPBFieldRepeated,
+        .type = GPBTypeString,
+        .offset = offsetof(GPBFieldMask_Storage, pathsArray),
+        .defaultValue.valueMessage = nil,
+        .typeSpecific.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];
+  }
+  return descriptor;
+}
+
+@end
+
+
+// @@protoc_insertion_point(global_scope)

+ 44 - 0
objectivec/google/protobuf/SourceContext.pbobjc.h

@@ -0,0 +1,44 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: google/protobuf/source_context.proto
+
+#import "GPBProtocolBuffers.h"
+
+#if GOOGLE_PROTOBUF_OBJC_GEN_VERSION != 30000
+#error This file was generated by a different version of protoc-gen-objc which is incompatible with your Protocol Buffer sources.
+#endif
+
+// @@protoc_insertion_point(imports)
+
+CF_EXTERN_C_BEGIN
+
+
+#pragma mark - GPBSourceContextRoot
+
+@interface GPBSourceContextRoot : GPBRootObject
+
+// The base class provides:
+//   + (GPBExtensionRegistry *)extensionRegistry;
+// which is an GPBExtensionRegistry that includes all the extensions defined by
+// this file and all files that it depends on.
+
+@end
+
+#pragma mark - GPBSourceContext
+
+typedef GPB_ENUM(GPBSourceContext_FieldNumber) {
+  GPBSourceContext_FieldNumber_FileName = 1,
+};
+
+// `SourceContext` represents information about the source of a
+// protobuf element, like the file in which it is defined.
+@interface GPBSourceContext : GPBMessage
+
+// The path-qualified name of the .proto file that contained the associated
+// protobuf element.  For example: `"google/protobuf/source.proto"`.
+@property(nonatomic, readwrite, copy) NSString *fileName;
+
+@end
+
+CF_EXTERN_C_END
+
+// @@protoc_insertion_point(global_scope)

+ 74 - 0
objectivec/google/protobuf/SourceContext.pbobjc.m

@@ -0,0 +1,74 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: google/protobuf/source_context.proto
+
+#import "GPBProtocolBuffers_RuntimeSupport.h"
+#import "google/protobuf/SourceContext.pbobjc.h"
+// @@protoc_insertion_point(imports)
+
+#pragma mark - GPBSourceContextRoot
+
+@implementation GPBSourceContextRoot
+
+@end
+
+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) {
+    descriptor = [[GPBFileDescriptor alloc] initWithPackage:@"google.protobuf"
+                                                     syntax:GPBFileSyntaxProto3];
+  }
+  return descriptor;
+}
+
+#pragma mark - GPBSourceContext
+
+@implementation GPBSourceContext
+
+@dynamic fileName;
+
+typedef struct GPBSourceContext_Storage {
+  uint32_t _has_storage_[1];
+  NSString *fileName;
+} GPBSourceContext_Storage;
+
+// This method is threadsafe because it is initially called
+// in +initialize for each subclass.
++ (GPBDescriptor *)descriptor {
+  static GPBDescriptor *descriptor = NULL;
+  if (!descriptor) {
+    static GPBMessageFieldDescription fields[] = {
+      {
+        .name = "fileName",
+        .number = GPBSourceContext_FieldNumber_FileName,
+        .hasIndex = 0,
+        .flags = GPBFieldOptional,
+        .type = GPBTypeString,
+        .offset = offsetof(GPBSourceContext_Storage, fileName),
+        .defaultValue.valueString = nil,
+        .typeSpecific.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];
+  }
+  return descriptor;
+}
+
+@end
+
+
+// @@protoc_insertion_point(global_scope)

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

@@ -0,0 +1,134 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: google/protobuf/struct.proto
+
+#import "GPBProtocolBuffers.h"
+
+#if GOOGLE_PROTOBUF_OBJC_GEN_VERSION != 30000
+#error This file was generated by a different version of protoc-gen-objc which is incompatible with your Protocol Buffer sources.
+#endif
+
+// @@protoc_insertion_point(imports)
+
+CF_EXTERN_C_BEGIN
+
+@class GPBListValue;
+@class GPBStruct;
+
+#pragma mark - Enum GPBNullValue
+
+// `NullValue` is a singleton enumeration to represent the null
+// value for the `Value` type union.
+typedef GPB_ENUM(GPBNullValue) {
+  GPBNullValue_GPBUnrecognizedEnumeratorValue = kGPBUnrecognizedEnumeratorValue,
+  // Null value.
+  GPBNullValue_NullValue = 0,
+};
+
+GPBEnumDescriptor *GPBNullValue_EnumDescriptor(void);
+
+BOOL GPBNullValue_IsValidValue(int32_t value);
+
+
+#pragma mark - GPBStructRoot
+
+@interface GPBStructRoot : GPBRootObject
+
+// The base class provides:
+//   + (GPBExtensionRegistry *)extensionRegistry;
+// which is an GPBExtensionRegistry that includes all the extensions defined by
+// this file and all files that it depends on.
+
+@end
+
+#pragma mark - GPBStruct
+
+typedef GPB_ENUM(GPBStruct_FieldNumber) {
+  GPBStruct_FieldNumber_Fields = 1,
+};
+
+// `Struct` represents a structured data value, consisting of fields
+// which map to dynamically typed values. In some languages, `Struct`
+// might be supported by a native representation. For example, in
+// scripting languages like JS a struct is represented as an
+// object. The details of that representation are described together
+// with the proto support for the language.
+@interface GPBStruct : GPBMessage
+
+// Map of dynamically typed values.
+// |fields| values are |GPBValue|
+@property(nonatomic, readwrite, strong) NSMutableDictionary *fields;
+
+@end
+
+#pragma mark - GPBValue
+
+typedef GPB_ENUM(GPBValue_FieldNumber) {
+  GPBValue_FieldNumber_NullValue = 1,
+  GPBValue_FieldNumber_NumberValue = 2,
+  GPBValue_FieldNumber_StringValue = 3,
+  GPBValue_FieldNumber_BoolValue = 4,
+  GPBValue_FieldNumber_StructValue = 5,
+  GPBValue_FieldNumber_ListValue = 6,
+};
+
+typedef GPB_ENUM(GPBValue_Kind_OneOfCase) {
+  GPBValue_Kind_OneOfCase_GPBUnsetOneOfCase = 0,
+  GPBValue_Kind_OneOfCase_NullValue = 1,
+  GPBValue_Kind_OneOfCase_NumberValue = 2,
+  GPBValue_Kind_OneOfCase_StringValue = 3,
+  GPBValue_Kind_OneOfCase_BoolValue = 4,
+  GPBValue_Kind_OneOfCase_StructValue = 5,
+  GPBValue_Kind_OneOfCase_ListValue = 6,
+};
+
+// `Value` represents a dynamically typed value which can be either
+// null, a number, a string, a boolean, a recursive struct value, or a
+// list of values. A producer of value is expected to set one of that
+// variants, absence of any variant indicates an error.
+@interface GPBValue : GPBMessage
+
+@property(nonatomic, readonly) GPBValue_Kind_OneOfCase kindOneOfCase;
+
+// Represents a null value.
+@property(nonatomic, readwrite) GPBNullValue nullValue;
+
+// Represents a double value.
+@property(nonatomic, readwrite) double numberValue;
+
+// Represents a string value.
+@property(nonatomic, readwrite, copy) NSString *stringValue;
+
+// Represents a boolean value.
+@property(nonatomic, readwrite) BOOL boolValue;
+
+// Represents a structured value.
+@property(nonatomic, readwrite, strong) GPBStruct *structValue;
+
+// Represents a repeated `Value`.
+@property(nonatomic, readwrite, strong) GPBListValue *listValue;
+
+@end
+
+int32_t GPBValue_NullValue_RawValue(GPBValue *message);
+void SetGPBValue_NullValue_RawValue(GPBValue *message, int32_t value);
+
+void GPBValue_ClearKindOneOfCase(GPBValue *message);
+
+#pragma mark - GPBListValue
+
+typedef GPB_ENUM(GPBListValue_FieldNumber) {
+  GPBListValue_FieldNumber_ValuesArray = 1,
+};
+
+// `ListValue` is a wrapper around a repeated field of values.
+@interface GPBListValue : GPBMessage
+
+// Repeated field of dynamically typed values.
+// |valuesArray| contains |GPBValue|
+@property(nonatomic, readwrite, strong) NSMutableArray *valuesArray;
+
+@end
+
+CF_EXTERN_C_END
+
+// @@protoc_insertion_point(global_scope)

+ 284 - 0
objectivec/google/protobuf/Struct.pbobjc.m

@@ -0,0 +1,284 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: google/protobuf/struct.proto
+
+#import "GPBProtocolBuffers_RuntimeSupport.h"
+#import "google/protobuf/Struct.pbobjc.h"
+// @@protoc_insertion_point(imports)
+
+#pragma mark - GPBStructRoot
+
+@implementation GPBStructRoot
+
+@end
+
+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) {
+    descriptor = [[GPBFileDescriptor alloc] initWithPackage:@"google.protobuf"
+                                                     syntax:GPBFileSyntaxProto3];
+  }
+  return descriptor;
+}
+
+#pragma mark - Enum GPBNullValue
+
+GPBEnumDescriptor *GPBNullValue_EnumDescriptor(void) {
+  static GPBEnumDescriptor *descriptor = NULL;
+  if (!descriptor) {
+    static GPBMessageEnumValueDescription values[] = {
+      { .name = "NullValue", .number = GPBNullValue_NullValue },
+    };
+    descriptor = [GPBEnumDescriptor allocDescriptorForName:GPBNSStringifySymbol(GPBNullValue)
+                                                   values:values
+                                               valueCount:sizeof(values) / sizeof(GPBMessageEnumValueDescription)
+                                             enumVerifier:GPBNullValue_IsValidValue];
+  }
+  return descriptor;
+}
+
+BOOL GPBNullValue_IsValidValue(int32_t value__) {
+  switch (value__) {
+    case GPBNullValue_NullValue:
+      return YES;
+    default:
+      return NO;
+  }
+}
+
+#pragma mark - GPBStruct
+
+@implementation GPBStruct
+
+@dynamic fields;
+
+typedef struct GPBStruct_Storage {
+  uint32_t _has_storage_[1];
+  NSMutableDictionary *fields;
+} GPBStruct_Storage;
+
+// This method is threadsafe because it is initially called
+// in +initialize for each subclass.
++ (GPBDescriptor *)descriptor {
+  static GPBDescriptor *descriptor = NULL;
+  if (!descriptor) {
+    static GPBMessageFieldDescription fields[] = {
+      {
+        .name = "fields",
+        .number = GPBStruct_FieldNumber_Fields,
+        .hasIndex = GPBNoHasBit,
+        .flags = GPBFieldMapKeyString,
+        .type = GPBTypeMessage,
+        .offset = offsetof(GPBStruct_Storage, fields),
+        .defaultValue.valueMessage = nil,
+        .typeSpecific.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];
+  }
+  return descriptor;
+}
+
+@end
+
+#pragma mark - GPBValue
+
+@implementation GPBValue
+
+@dynamic kindOneOfCase;
+@dynamic nullValue;
+@dynamic numberValue;
+@dynamic stringValue;
+@dynamic boolValue;
+@dynamic structValue;
+@dynamic listValue;
+
+typedef struct GPBValue_Storage {
+  uint32_t _has_storage_[2];
+  BOOL boolValue;
+  GPBNullValue nullValue;
+  NSString *stringValue;
+  GPBStruct *structValue;
+  GPBListValue *listValue;
+  double numberValue;
+} GPBValue_Storage;
+
+// This method is threadsafe because it is initially called
+// in +initialize for each subclass.
++ (GPBDescriptor *)descriptor {
+  static GPBDescriptor *descriptor = NULL;
+  if (!descriptor) {
+    static GPBMessageOneofDescription oneofs[] = {
+      {
+        .name = "kind",
+        .index = -1,
+      },
+    };
+    static GPBMessageFieldDescription fields[] = {
+      {
+        .name = "nullValue",
+        .number = GPBValue_FieldNumber_NullValue,
+        .hasIndex = -1,
+        .flags = GPBFieldOptional | GPBFieldHasEnumDescriptor,
+        .type = GPBTypeEnum,
+        .offset = offsetof(GPBValue_Storage, nullValue),
+        .defaultValue.valueEnum = GPBNullValue_NullValue,
+        .typeSpecific.enumDescFunc = GPBNullValue_EnumDescriptor,
+        .fieldOptions = NULL,
+      },
+      {
+        .name = "numberValue",
+        .number = GPBValue_FieldNumber_NumberValue,
+        .hasIndex = -1,
+        .flags = GPBFieldOptional,
+        .type = GPBTypeDouble,
+        .offset = offsetof(GPBValue_Storage, numberValue),
+        .defaultValue.valueDouble = 0,
+        .typeSpecific.className = NULL,
+        .fieldOptions = NULL,
+      },
+      {
+        .name = "stringValue",
+        .number = GPBValue_FieldNumber_StringValue,
+        .hasIndex = -1,
+        .flags = GPBFieldOptional,
+        .type = GPBTypeString,
+        .offset = offsetof(GPBValue_Storage, stringValue),
+        .defaultValue.valueString = nil,
+        .typeSpecific.className = NULL,
+        .fieldOptions = NULL,
+      },
+      {
+        .name = "boolValue",
+        .number = GPBValue_FieldNumber_BoolValue,
+        .hasIndex = -1,
+        .flags = GPBFieldOptional,
+        .type = GPBTypeBool,
+        .offset = offsetof(GPBValue_Storage, boolValue),
+        .defaultValue.valueBool = NO,
+        .typeSpecific.className = NULL,
+        .fieldOptions = NULL,
+      },
+      {
+        .name = "structValue",
+        .number = GPBValue_FieldNumber_StructValue,
+        .hasIndex = -1,
+        .flags = GPBFieldOptional,
+        .type = GPBTypeMessage,
+        .offset = offsetof(GPBValue_Storage, structValue),
+        .defaultValue.valueMessage = nil,
+        .typeSpecific.className = GPBStringifySymbol(GPBStruct),
+        .fieldOptions = NULL,
+      },
+      {
+        .name = "listValue",
+        .number = GPBValue_FieldNumber_ListValue,
+        .hasIndex = -1,
+        .flags = GPBFieldOptional,
+        .type = GPBTypeMessage,
+        .offset = offsetof(GPBValue_Storage, listValue),
+        .defaultValue.valueMessage = nil,
+        .typeSpecific.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];
+  }
+  return descriptor;
+}
+
+@end
+
+int32_t GPBValue_NullValue_RawValue(GPBValue *message) {
+  GPBDescriptor *descriptor = [GPBValue descriptor];
+  GPBFieldDescriptor *field = [descriptor fieldWithNumber:GPBValue_FieldNumber_NullValue];
+  return GPBGetInt32IvarWithField(message, field);
+}
+
+void SetGPBValue_NullValue_RawValue(GPBValue *message, int32_t value) {
+  GPBDescriptor *descriptor = [GPBValue descriptor];
+  GPBFieldDescriptor *field = [descriptor fieldWithNumber:GPBValue_FieldNumber_NullValue];
+  GPBSetInt32IvarWithFieldInternal(message, field, value, descriptor.file.syntax);
+}
+
+void GPBValue_ClearKindOneOfCase(GPBValue *message) {
+  GPBDescriptor *descriptor = [message descriptor];
+  GPBOneofDescriptor *oneof = descriptor->oneofs_[0];
+  GPBMaybeClearOneof(message, oneof, 0);
+}
+#pragma mark - GPBListValue
+
+@implementation GPBListValue
+
+@dynamic valuesArray;
+
+typedef struct GPBListValue_Storage {
+  uint32_t _has_storage_[1];
+  NSMutableArray *valuesArray;
+} GPBListValue_Storage;
+
+// This method is threadsafe because it is initially called
+// in +initialize for each subclass.
++ (GPBDescriptor *)descriptor {
+  static GPBDescriptor *descriptor = NULL;
+  if (!descriptor) {
+    static GPBMessageFieldDescription fields[] = {
+      {
+        .name = "valuesArray",
+        .number = GPBListValue_FieldNumber_ValuesArray,
+        .hasIndex = GPBNoHasBit,
+        .flags = GPBFieldRepeated,
+        .type = GPBTypeMessage,
+        .offset = offsetof(GPBListValue_Storage, valuesArray),
+        .defaultValue.valueMessage = nil,
+        .typeSpecific.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];
+  }
+  return descriptor;
+}
+
+@end
+
+
+// @@protoc_insertion_point(global_scope)

+ 10 - 2
objectivec/google/protobuf/Timestamp.pbobjc.h

@@ -7,14 +7,20 @@
 #error This file was generated by a different version of protoc-gen-objc which is incompatible with your Protocol Buffer sources.
 #endif
 
-CF_EXTERN_C_BEGIN
+// @@protoc_insertion_point(imports)
 
-@class GPBTimestamp;
+CF_EXTERN_C_BEGIN
 
 
 #pragma mark - GPBTimestampRoot
 
 @interface GPBTimestampRoot : GPBRootObject
+
+// The base class provides:
+//   + (GPBExtensionRegistry *)extensionRegistry;
+// which is an GPBExtensionRegistry that includes all the extensions defined by
+// this file and all files that it depends on.
+
 @end
 
 #pragma mark - GPBTimestamp
@@ -92,3 +98,5 @@ typedef GPB_ENUM(GPBTimestamp_FieldNumber) {
 @end
 
 CF_EXTERN_C_END
+
+// @@protoc_insertion_point(global_scope)

+ 3 - 1
objectivec/google/protobuf/Timestamp.pbobjc.m

@@ -2,8 +2,8 @@
 // source: google/protobuf/timestamp.proto
 
 #import "GPBProtocolBuffers_RuntimeSupport.h"
-
 #import "google/protobuf/Timestamp.pbobjc.h"
+// @@protoc_insertion_point(imports)
 
 #pragma mark - GPBTimestampRoot
 
@@ -83,3 +83,5 @@ typedef struct GPBTimestamp_Storage {
 
 @end
 
+
+// @@protoc_insertion_point(global_scope)

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

@@ -0,0 +1,274 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: google/protobuf/type.proto
+
+#import "GPBProtocolBuffers.h"
+
+#if GOOGLE_PROTOBUF_OBJC_GEN_VERSION != 30000
+#error This file was generated by a different version of protoc-gen-objc which is incompatible with your Protocol Buffer sources.
+#endif
+
+// @@protoc_insertion_point(imports)
+
+CF_EXTERN_C_BEGIN
+
+@class GPBAny;
+@class GPBSourceContext;
+
+#pragma mark - Enum GPBField_Kind
+
+// Kind represents a basic field type.
+typedef GPB_ENUM(GPBField_Kind) {
+  GPBField_Kind_GPBUnrecognizedEnumeratorValue = kGPBUnrecognizedEnumeratorValue,
+  // Field type unknown.
+  GPBField_Kind_TypeUnknown = 0,
+
+  // Field type double.
+  GPBField_Kind_TypeDouble = 1,
+
+  // Field type float.
+  GPBField_Kind_TypeFloat = 2,
+
+  // Field type int64.
+  GPBField_Kind_TypeInt64 = 3,
+
+  // Field type uint64.
+  GPBField_Kind_TypeUint64 = 4,
+
+  // Field type int32.
+  GPBField_Kind_TypeInt32 = 5,
+
+  // Field type fixed64.
+  GPBField_Kind_TypeFixed64 = 6,
+
+  // Field type fixed32.
+  GPBField_Kind_TypeFixed32 = 7,
+
+  // Field type bool.
+  GPBField_Kind_TypeBool = 8,
+
+  // Field type string.
+  GPBField_Kind_TypeString = 9,
+
+  // Field type message.
+  GPBField_Kind_TypeMessage = 11,
+
+  // Field type bytes.
+  GPBField_Kind_TypeBytes = 12,
+
+  // Field type uint32.
+  GPBField_Kind_TypeUint32 = 13,
+
+  // Field type enum.
+  GPBField_Kind_TypeEnum = 14,
+
+  // Field type sfixed32.
+  GPBField_Kind_TypeSfixed32 = 15,
+
+  // Field type sfixed64.
+  GPBField_Kind_TypeSfixed64 = 16,
+
+  // Field type sint32.
+  GPBField_Kind_TypeSint32 = 17,
+
+  // Field type sint64.
+  GPBField_Kind_TypeSint64 = 18,
+};
+
+GPBEnumDescriptor *GPBField_Kind_EnumDescriptor(void);
+
+BOOL GPBField_Kind_IsValidValue(int32_t value);
+
+#pragma mark - Enum GPBField_Cardinality
+
+// Cardinality represents whether a field is optional, required, or
+// repeated.
+typedef GPB_ENUM(GPBField_Cardinality) {
+  GPBField_Cardinality_GPBUnrecognizedEnumeratorValue = kGPBUnrecognizedEnumeratorValue,
+  // The field cardinality is unknown. Typically an error condition.
+  GPBField_Cardinality_CardinalityUnknown = 0,
+
+  // For optional fields.
+  GPBField_Cardinality_CardinalityOptional = 1,
+
+  // For required fields. Not used for proto3.
+  GPBField_Cardinality_CardinalityRequired = 2,
+
+  // For repeated fields.
+  GPBField_Cardinality_CardinalityRepeated = 3,
+};
+
+GPBEnumDescriptor *GPBField_Cardinality_EnumDescriptor(void);
+
+BOOL GPBField_Cardinality_IsValidValue(int32_t value);
+
+
+#pragma mark - GPBTypeRoot
+
+@interface GPBTypeRoot : GPBRootObject
+
+// The base class provides:
+//   + (GPBExtensionRegistry *)extensionRegistry;
+// which is an GPBExtensionRegistry that includes all the extensions defined by
+// this file and all files that it depends on.
+
+@end
+
+#pragma mark - GPBType
+
+typedef GPB_ENUM(GPBType_FieldNumber) {
+  GPBType_FieldNumber_Name = 1,
+  GPBType_FieldNumber_FieldsArray = 2,
+  GPBType_FieldNumber_OneofsArray = 3,
+  GPBType_FieldNumber_OptionsArray = 4,
+  GPBType_FieldNumber_SourceContext = 5,
+};
+
+// A light-weight descriptor for a proto message type.
+@interface GPBType : GPBMessage
+
+// The fully qualified message name.
+@property(nonatomic, readwrite, copy) NSString *name;
+
+// The list of fields.
+// |fieldsArray| contains |GPBField|
+@property(nonatomic, readwrite, strong) NSMutableArray *fieldsArray;
+
+// The list of oneof definitions.
+// The list of oneofs declared in this Type
+// |oneofsArray| contains |NSString|
+@property(nonatomic, readwrite, strong) NSMutableArray *oneofsArray;
+
+// The proto options.
+// |optionsArray| contains |GPBOption|
+@property(nonatomic, readwrite, strong) NSMutableArray *optionsArray;
+
+// The source context.
+@property(nonatomic, readwrite) BOOL hasSourceContext;
+@property(nonatomic, readwrite, strong) GPBSourceContext *sourceContext;
+
+@end
+
+#pragma mark - GPBField
+
+typedef GPB_ENUM(GPBField_FieldNumber) {
+  GPBField_FieldNumber_Kind = 1,
+  GPBField_FieldNumber_Cardinality = 2,
+  GPBField_FieldNumber_Number = 3,
+  GPBField_FieldNumber_Name = 4,
+  GPBField_FieldNumber_TypeURL = 6,
+  GPBField_FieldNumber_OneofIndex = 7,
+  GPBField_FieldNumber_Packed = 8,
+  GPBField_FieldNumber_OptionsArray = 9,
+};
+
+// Field represents a single field of a message type.
+@interface GPBField : GPBMessage
+
+// The field kind.
+@property(nonatomic, readwrite) GPBField_Kind kind;
+
+// The field cardinality, i.e. optional/required/repeated.
+@property(nonatomic, readwrite) GPBField_Cardinality cardinality;
+
+// The proto field number.
+@property(nonatomic, readwrite) int32_t number;
+
+// The field name.
+@property(nonatomic, readwrite, copy) NSString *name;
+
+// The type URL (without the scheme) when the type is MESSAGE or ENUM,
+// such as `type.googleapis.com/google.protobuf.Empty`.
+@property(nonatomic, readwrite, copy) NSString *typeURL;
+
+// Index in Type.oneofs. Starts at 1. Zero means no oneof mapping.
+@property(nonatomic, readwrite) int32_t oneofIndex;
+
+// Whether to use alternative packed wire representation.
+@property(nonatomic, readwrite) BOOL packed;
+
+// The proto options.
+// |optionsArray| contains |GPBOption|
+@property(nonatomic, readwrite, strong) NSMutableArray *optionsArray;
+
+@end
+
+int32_t GPBField_Kind_RawValue(GPBField *message);
+void SetGPBField_Kind_RawValue(GPBField *message, int32_t value);
+
+int32_t GPBField_Cardinality_RawValue(GPBField *message);
+void SetGPBField_Cardinality_RawValue(GPBField *message, int32_t value);
+
+#pragma mark - GPBEnum
+
+typedef GPB_ENUM(GPBEnum_FieldNumber) {
+  GPBEnum_FieldNumber_Name = 1,
+  GPBEnum_FieldNumber_EnumvalueArray = 2,
+  GPBEnum_FieldNumber_OptionsArray = 3,
+  GPBEnum_FieldNumber_SourceContext = 4,
+};
+
+// Enum type definition.
+@interface GPBEnum : GPBMessage
+
+// Enum type name.
+@property(nonatomic, readwrite, copy) NSString *name;
+
+// Enum value definitions.
+// |enumvalueArray| contains |GPBEnumValue|
+@property(nonatomic, readwrite, strong) NSMutableArray *enumvalueArray;
+
+// Proto options for the enum type.
+// |optionsArray| contains |GPBOption|
+@property(nonatomic, readwrite, strong) NSMutableArray *optionsArray;
+
+// The source context.
+@property(nonatomic, readwrite) BOOL hasSourceContext;
+@property(nonatomic, readwrite, strong) GPBSourceContext *sourceContext;
+
+@end
+
+#pragma mark - GPBEnumValue
+
+typedef GPB_ENUM(GPBEnumValue_FieldNumber) {
+  GPBEnumValue_FieldNumber_Name = 1,
+  GPBEnumValue_FieldNumber_Number = 2,
+  GPBEnumValue_FieldNumber_OptionsArray = 3,
+};
+
+// Enum value definition.
+@interface GPBEnumValue : GPBMessage
+
+// Enum value name.
+@property(nonatomic, readwrite, copy) NSString *name;
+
+// Enum value number.
+@property(nonatomic, readwrite) int32_t number;
+
+// Proto options for the enum value.
+// |optionsArray| contains |GPBOption|
+@property(nonatomic, readwrite, strong) NSMutableArray *optionsArray;
+
+@end
+
+#pragma mark - GPBOption
+
+typedef GPB_ENUM(GPBOption_FieldNumber) {
+  GPBOption_FieldNumber_Name = 1,
+  GPBOption_FieldNumber_Value = 2,
+};
+
+// Proto option attached to messages/fields/enums etc.
+@interface GPBOption : GPBMessage
+
+// Proto option name.
+@property(nonatomic, readwrite, copy) NSString *name;
+
+// Proto option value.
+@property(nonatomic, readwrite) BOOL hasValue;
+@property(nonatomic, readwrite, strong) GPBAny *value;
+
+@end
+
+CF_EXTERN_C_END
+
+// @@protoc_insertion_point(global_scope)

+ 628 - 0
objectivec/google/protobuf/Type.pbobjc.m

@@ -0,0 +1,628 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: google/protobuf/type.proto
+
+#import "GPBProtocolBuffers_RuntimeSupport.h"
+#import "google/protobuf/Type.pbobjc.h"
+#import "google/protobuf/Any.pbobjc.h"
+#import "google/protobuf/SourceContext.pbobjc.h"
+// @@protoc_insertion_point(imports)
+
+#pragma mark - GPBTypeRoot
+
+@implementation GPBTypeRoot
+
++ (GPBExtensionRegistry*)extensionRegistry {
+  // This is called by +initialize so there is no need to worry
+  // about thread safety and initialization of registry.
+  static GPBExtensionRegistry* registry = nil;
+  if (!registry) {
+    registry = [[GPBExtensionRegistry alloc] init];
+    static GPBExtensionDescription descriptions[] = {
+    };
+    #pragma unused (descriptions)
+    [registry addExtensions:[GPBAnyRoot extensionRegistry]];
+    [registry addExtensions:[GPBSourceContextRoot extensionRegistry]];
+  }
+  return registry;
+}
+
+@end
+
+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) {
+    descriptor = [[GPBFileDescriptor alloc] initWithPackage:@"google.protobuf"
+                                                     syntax:GPBFileSyntaxProto3];
+  }
+  return descriptor;
+}
+
+#pragma mark - GPBType
+
+@implementation GPBType
+
+@dynamic name;
+@dynamic fieldsArray;
+@dynamic oneofsArray;
+@dynamic optionsArray;
+@dynamic hasSourceContext, sourceContext;
+
+typedef struct GPBType_Storage {
+  uint32_t _has_storage_[1];
+  NSString *name;
+  NSMutableArray *fieldsArray;
+  NSMutableArray *oneofsArray;
+  NSMutableArray *optionsArray;
+  GPBSourceContext *sourceContext;
+} GPBType_Storage;
+
+// This method is threadsafe because it is initially called
+// in +initialize for each subclass.
++ (GPBDescriptor *)descriptor {
+  static GPBDescriptor *descriptor = NULL;
+  if (!descriptor) {
+    static GPBMessageFieldDescription fields[] = {
+      {
+        .name = "name",
+        .number = GPBType_FieldNumber_Name,
+        .hasIndex = 0,
+        .flags = GPBFieldOptional,
+        .type = GPBTypeString,
+        .offset = offsetof(GPBType_Storage, name),
+        .defaultValue.valueString = nil,
+        .typeSpecific.className = NULL,
+        .fieldOptions = NULL,
+      },
+      {
+        .name = "fieldsArray",
+        .number = GPBType_FieldNumber_FieldsArray,
+        .hasIndex = GPBNoHasBit,
+        .flags = GPBFieldRepeated,
+        .type = GPBTypeMessage,
+        .offset = offsetof(GPBType_Storage, fieldsArray),
+        .defaultValue.valueMessage = nil,
+        .typeSpecific.className = GPBStringifySymbol(GPBField),
+        .fieldOptions = NULL,
+      },
+      {
+        .name = "oneofsArray",
+        .number = GPBType_FieldNumber_OneofsArray,
+        .hasIndex = GPBNoHasBit,
+        .flags = GPBFieldRepeated,
+        .type = GPBTypeString,
+        .offset = offsetof(GPBType_Storage, oneofsArray),
+        .defaultValue.valueMessage = nil,
+        .typeSpecific.className = NULL,
+        .fieldOptions = NULL,
+      },
+      {
+        .name = "optionsArray",
+        .number = GPBType_FieldNumber_OptionsArray,
+        .hasIndex = GPBNoHasBit,
+        .flags = GPBFieldRepeated,
+        .type = GPBTypeMessage,
+        .offset = offsetof(GPBType_Storage, optionsArray),
+        .defaultValue.valueMessage = nil,
+        .typeSpecific.className = GPBStringifySymbol(GPBOption),
+        .fieldOptions = NULL,
+      },
+      {
+        .name = "sourceContext",
+        .number = GPBType_FieldNumber_SourceContext,
+        .hasIndex = 4,
+        .flags = GPBFieldOptional,
+        .type = GPBTypeMessage,
+        .offset = offsetof(GPBType_Storage, sourceContext),
+        .defaultValue.valueMessage = nil,
+        .typeSpecific.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];
+  }
+  return descriptor;
+}
+
+@end
+
+#pragma mark - GPBField
+
+@implementation GPBField
+
+@dynamic kind;
+@dynamic cardinality;
+@dynamic number;
+@dynamic name;
+@dynamic typeURL;
+@dynamic oneofIndex;
+@dynamic packed;
+@dynamic optionsArray;
+
+typedef struct GPBField_Storage {
+  uint32_t _has_storage_[1];
+  BOOL packed;
+  GPBField_Kind kind;
+  GPBField_Cardinality cardinality;
+  int32_t number;
+  int32_t oneofIndex;
+  NSString *name;
+  NSString *typeURL;
+  NSMutableArray *optionsArray;
+} GPBField_Storage;
+
+// This method is threadsafe because it is initially called
+// in +initialize for each subclass.
++ (GPBDescriptor *)descriptor {
+  static GPBDescriptor *descriptor = NULL;
+  if (!descriptor) {
+    static GPBMessageFieldDescription fields[] = {
+      {
+        .name = "kind",
+        .number = GPBField_FieldNumber_Kind,
+        .hasIndex = 0,
+        .flags = GPBFieldOptional | GPBFieldHasEnumDescriptor,
+        .type = GPBTypeEnum,
+        .offset = offsetof(GPBField_Storage, kind),
+        .defaultValue.valueEnum = GPBField_Kind_TypeUnknown,
+        .typeSpecific.enumDescFunc = GPBField_Kind_EnumDescriptor,
+        .fieldOptions = NULL,
+      },
+      {
+        .name = "cardinality",
+        .number = GPBField_FieldNumber_Cardinality,
+        .hasIndex = 1,
+        .flags = GPBFieldOptional | GPBFieldHasEnumDescriptor,
+        .type = GPBTypeEnum,
+        .offset = offsetof(GPBField_Storage, cardinality),
+        .defaultValue.valueEnum = GPBField_Cardinality_CardinalityUnknown,
+        .typeSpecific.enumDescFunc = GPBField_Cardinality_EnumDescriptor,
+        .fieldOptions = NULL,
+      },
+      {
+        .name = "number",
+        .number = GPBField_FieldNumber_Number,
+        .hasIndex = 2,
+        .flags = GPBFieldOptional,
+        .type = GPBTypeInt32,
+        .offset = offsetof(GPBField_Storage, number),
+        .defaultValue.valueInt32 = 0,
+        .typeSpecific.className = NULL,
+        .fieldOptions = NULL,
+      },
+      {
+        .name = "name",
+        .number = GPBField_FieldNumber_Name,
+        .hasIndex = 3,
+        .flags = GPBFieldOptional,
+        .type = GPBTypeString,
+        .offset = offsetof(GPBField_Storage, name),
+        .defaultValue.valueString = nil,
+        .typeSpecific.className = NULL,
+        .fieldOptions = NULL,
+      },
+      {
+        .name = "typeURL",
+        .number = GPBField_FieldNumber_TypeURL,
+        .hasIndex = 4,
+        .flags = GPBFieldOptional | GPBFieldTextFormatNameCustom,
+        .type = GPBTypeString,
+        .offset = offsetof(GPBField_Storage, typeURL),
+        .defaultValue.valueString = nil,
+        .typeSpecific.className = NULL,
+        .fieldOptions = NULL,
+      },
+      {
+        .name = "oneofIndex",
+        .number = GPBField_FieldNumber_OneofIndex,
+        .hasIndex = 5,
+        .flags = GPBFieldOptional,
+        .type = GPBTypeInt32,
+        .offset = offsetof(GPBField_Storage, oneofIndex),
+        .defaultValue.valueInt32 = 0,
+        .typeSpecific.className = NULL,
+        .fieldOptions = NULL,
+      },
+      {
+        .name = "packed",
+        .number = GPBField_FieldNumber_Packed,
+        .hasIndex = 6,
+        .flags = GPBFieldOptional,
+        .type = GPBTypeBool,
+        .offset = offsetof(GPBField_Storage, packed),
+        .defaultValue.valueBool = NO,
+        .typeSpecific.className = NULL,
+        .fieldOptions = NULL,
+      },
+      {
+        .name = "optionsArray",
+        .number = GPBField_FieldNumber_OptionsArray,
+        .hasIndex = GPBNoHasBit,
+        .flags = GPBFieldRepeated,
+        .type = GPBTypeMessage,
+        .offset = offsetof(GPBField_Storage, optionsArray),
+        .defaultValue.valueMessage = nil,
+        .typeSpecific.className = GPBStringifySymbol(GPBOption),
+        .fieldOptions = NULL,
+      },
+    };
+    static GPBMessageEnumDescription enums[] = {
+      { .enumDescriptorFunc = GPBField_Kind_EnumDescriptor },
+      { .enumDescriptorFunc = GPBField_Cardinality_EnumDescriptor },
+    };
+#if GPBOBJC_SKIP_MESSAGE_TEXTFORMAT_EXTRAS
+    const char *extraTextFormatInfo = NULL;
+#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];
+  }
+  return descriptor;
+}
+
+@end
+
+int32_t GPBField_Kind_RawValue(GPBField *message) {
+  GPBDescriptor *descriptor = [GPBField descriptor];
+  GPBFieldDescriptor *field = [descriptor fieldWithNumber:GPBField_FieldNumber_Kind];
+  return GPBGetInt32IvarWithField(message, field);
+}
+
+void SetGPBField_Kind_RawValue(GPBField *message, int32_t value) {
+  GPBDescriptor *descriptor = [GPBField descriptor];
+  GPBFieldDescriptor *field = [descriptor fieldWithNumber:GPBField_FieldNumber_Kind];
+  GPBSetInt32IvarWithFieldInternal(message, field, value, descriptor.file.syntax);
+}
+
+int32_t GPBField_Cardinality_RawValue(GPBField *message) {
+  GPBDescriptor *descriptor = [GPBField descriptor];
+  GPBFieldDescriptor *field = [descriptor fieldWithNumber:GPBField_FieldNumber_Cardinality];
+  return GPBGetInt32IvarWithField(message, field);
+}
+
+void SetGPBField_Cardinality_RawValue(GPBField *message, int32_t value) {
+  GPBDescriptor *descriptor = [GPBField descriptor];
+  GPBFieldDescriptor *field = [descriptor fieldWithNumber:GPBField_FieldNumber_Cardinality];
+  GPBSetInt32IvarWithFieldInternal(message, field, value, descriptor.file.syntax);
+}
+
+#pragma mark - Enum GPBField_Kind
+
+GPBEnumDescriptor *GPBField_Kind_EnumDescriptor(void) {
+  static GPBEnumDescriptor *descriptor = NULL;
+  if (!descriptor) {
+    static GPBMessageEnumValueDescription values[] = {
+      { .name = "TypeUnknown", .number = GPBField_Kind_TypeUnknown },
+      { .name = "TypeDouble", .number = GPBField_Kind_TypeDouble },
+      { .name = "TypeFloat", .number = GPBField_Kind_TypeFloat },
+      { .name = "TypeInt64", .number = GPBField_Kind_TypeInt64 },
+      { .name = "TypeUint64", .number = GPBField_Kind_TypeUint64 },
+      { .name = "TypeInt32", .number = GPBField_Kind_TypeInt32 },
+      { .name = "TypeFixed64", .number = GPBField_Kind_TypeFixed64 },
+      { .name = "TypeFixed32", .number = GPBField_Kind_TypeFixed32 },
+      { .name = "TypeBool", .number = GPBField_Kind_TypeBool },
+      { .name = "TypeString", .number = GPBField_Kind_TypeString },
+      { .name = "TypeMessage", .number = GPBField_Kind_TypeMessage },
+      { .name = "TypeBytes", .number = GPBField_Kind_TypeBytes },
+      { .name = "TypeUint32", .number = GPBField_Kind_TypeUint32 },
+      { .name = "TypeEnum", .number = GPBField_Kind_TypeEnum },
+      { .name = "TypeSfixed32", .number = GPBField_Kind_TypeSfixed32 },
+      { .name = "TypeSfixed64", .number = GPBField_Kind_TypeSfixed64 },
+      { .name = "TypeSint32", .number = GPBField_Kind_TypeSint32 },
+      { .name = "TypeSint64", .number = GPBField_Kind_TypeSint64 },
+    };
+    descriptor = [GPBEnumDescriptor allocDescriptorForName:GPBNSStringifySymbol(GPBField_Kind)
+                                                   values:values
+                                               valueCount:sizeof(values) / sizeof(GPBMessageEnumValueDescription)
+                                             enumVerifier:GPBField_Kind_IsValidValue];
+  }
+  return descriptor;
+}
+
+BOOL GPBField_Kind_IsValidValue(int32_t value__) {
+  switch (value__) {
+    case GPBField_Kind_TypeUnknown:
+    case GPBField_Kind_TypeDouble:
+    case GPBField_Kind_TypeFloat:
+    case GPBField_Kind_TypeInt64:
+    case GPBField_Kind_TypeUint64:
+    case GPBField_Kind_TypeInt32:
+    case GPBField_Kind_TypeFixed64:
+    case GPBField_Kind_TypeFixed32:
+    case GPBField_Kind_TypeBool:
+    case GPBField_Kind_TypeString:
+    case GPBField_Kind_TypeMessage:
+    case GPBField_Kind_TypeBytes:
+    case GPBField_Kind_TypeUint32:
+    case GPBField_Kind_TypeEnum:
+    case GPBField_Kind_TypeSfixed32:
+    case GPBField_Kind_TypeSfixed64:
+    case GPBField_Kind_TypeSint32:
+    case GPBField_Kind_TypeSint64:
+      return YES;
+    default:
+      return NO;
+  }
+}
+
+#pragma mark - Enum GPBField_Cardinality
+
+GPBEnumDescriptor *GPBField_Cardinality_EnumDescriptor(void) {
+  static GPBEnumDescriptor *descriptor = NULL;
+  if (!descriptor) {
+    static GPBMessageEnumValueDescription values[] = {
+      { .name = "CardinalityUnknown", .number = GPBField_Cardinality_CardinalityUnknown },
+      { .name = "CardinalityOptional", .number = GPBField_Cardinality_CardinalityOptional },
+      { .name = "CardinalityRequired", .number = GPBField_Cardinality_CardinalityRequired },
+      { .name = "CardinalityRepeated", .number = GPBField_Cardinality_CardinalityRepeated },
+    };
+    descriptor = [GPBEnumDescriptor allocDescriptorForName:GPBNSStringifySymbol(GPBField_Cardinality)
+                                                   values:values
+                                               valueCount:sizeof(values) / sizeof(GPBMessageEnumValueDescription)
+                                             enumVerifier:GPBField_Cardinality_IsValidValue];
+  }
+  return descriptor;
+}
+
+BOOL GPBField_Cardinality_IsValidValue(int32_t value__) {
+  switch (value__) {
+    case GPBField_Cardinality_CardinalityUnknown:
+    case GPBField_Cardinality_CardinalityOptional:
+    case GPBField_Cardinality_CardinalityRequired:
+    case GPBField_Cardinality_CardinalityRepeated:
+      return YES;
+    default:
+      return NO;
+  }
+}
+
+#pragma mark - GPBEnum
+
+@implementation GPBEnum
+
+@dynamic name;
+@dynamic enumvalueArray;
+@dynamic optionsArray;
+@dynamic hasSourceContext, sourceContext;
+
+typedef struct GPBEnum_Storage {
+  uint32_t _has_storage_[1];
+  NSString *name;
+  NSMutableArray *enumvalueArray;
+  NSMutableArray *optionsArray;
+  GPBSourceContext *sourceContext;
+} GPBEnum_Storage;
+
+// This method is threadsafe because it is initially called
+// in +initialize for each subclass.
++ (GPBDescriptor *)descriptor {
+  static GPBDescriptor *descriptor = NULL;
+  if (!descriptor) {
+    static GPBMessageFieldDescription fields[] = {
+      {
+        .name = "name",
+        .number = GPBEnum_FieldNumber_Name,
+        .hasIndex = 0,
+        .flags = GPBFieldOptional,
+        .type = GPBTypeString,
+        .offset = offsetof(GPBEnum_Storage, name),
+        .defaultValue.valueString = nil,
+        .typeSpecific.className = NULL,
+        .fieldOptions = NULL,
+      },
+      {
+        .name = "enumvalueArray",
+        .number = GPBEnum_FieldNumber_EnumvalueArray,
+        .hasIndex = GPBNoHasBit,
+        .flags = GPBFieldRepeated,
+        .type = GPBTypeMessage,
+        .offset = offsetof(GPBEnum_Storage, enumvalueArray),
+        .defaultValue.valueMessage = nil,
+        .typeSpecific.className = GPBStringifySymbol(GPBEnumValue),
+        .fieldOptions = NULL,
+      },
+      {
+        .name = "optionsArray",
+        .number = GPBEnum_FieldNumber_OptionsArray,
+        .hasIndex = GPBNoHasBit,
+        .flags = GPBFieldRepeated,
+        .type = GPBTypeMessage,
+        .offset = offsetof(GPBEnum_Storage, optionsArray),
+        .defaultValue.valueMessage = nil,
+        .typeSpecific.className = GPBStringifySymbol(GPBOption),
+        .fieldOptions = NULL,
+      },
+      {
+        .name = "sourceContext",
+        .number = GPBEnum_FieldNumber_SourceContext,
+        .hasIndex = 3,
+        .flags = GPBFieldOptional,
+        .type = GPBTypeMessage,
+        .offset = offsetof(GPBEnum_Storage, sourceContext),
+        .defaultValue.valueMessage = nil,
+        .typeSpecific.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];
+  }
+  return descriptor;
+}
+
+@end
+
+#pragma mark - GPBEnumValue
+
+@implementation GPBEnumValue
+
+@dynamic name;
+@dynamic number;
+@dynamic optionsArray;
+
+typedef struct GPBEnumValue_Storage {
+  uint32_t _has_storage_[1];
+  int32_t number;
+  NSString *name;
+  NSMutableArray *optionsArray;
+} GPBEnumValue_Storage;
+
+// This method is threadsafe because it is initially called
+// in +initialize for each subclass.
++ (GPBDescriptor *)descriptor {
+  static GPBDescriptor *descriptor = NULL;
+  if (!descriptor) {
+    static GPBMessageFieldDescription fields[] = {
+      {
+        .name = "name",
+        .number = GPBEnumValue_FieldNumber_Name,
+        .hasIndex = 0,
+        .flags = GPBFieldOptional,
+        .type = GPBTypeString,
+        .offset = offsetof(GPBEnumValue_Storage, name),
+        .defaultValue.valueString = nil,
+        .typeSpecific.className = NULL,
+        .fieldOptions = NULL,
+      },
+      {
+        .name = "number",
+        .number = GPBEnumValue_FieldNumber_Number,
+        .hasIndex = 1,
+        .flags = GPBFieldOptional,
+        .type = GPBTypeInt32,
+        .offset = offsetof(GPBEnumValue_Storage, number),
+        .defaultValue.valueInt32 = 0,
+        .typeSpecific.className = NULL,
+        .fieldOptions = NULL,
+      },
+      {
+        .name = "optionsArray",
+        .number = GPBEnumValue_FieldNumber_OptionsArray,
+        .hasIndex = GPBNoHasBit,
+        .flags = GPBFieldRepeated,
+        .type = GPBTypeMessage,
+        .offset = offsetof(GPBEnumValue_Storage, optionsArray),
+        .defaultValue.valueMessage = nil,
+        .typeSpecific.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];
+  }
+  return descriptor;
+}
+
+@end
+
+#pragma mark - GPBOption
+
+@implementation GPBOption
+
+@dynamic name;
+@dynamic hasValue, value;
+
+typedef struct GPBOption_Storage {
+  uint32_t _has_storage_[1];
+  NSString *name;
+  GPBAny *value;
+} GPBOption_Storage;
+
+// This method is threadsafe because it is initially called
+// in +initialize for each subclass.
++ (GPBDescriptor *)descriptor {
+  static GPBDescriptor *descriptor = NULL;
+  if (!descriptor) {
+    static GPBMessageFieldDescription fields[] = {
+      {
+        .name = "name",
+        .number = GPBOption_FieldNumber_Name,
+        .hasIndex = 0,
+        .flags = GPBFieldOptional,
+        .type = GPBTypeString,
+        .offset = offsetof(GPBOption_Storage, name),
+        .defaultValue.valueString = nil,
+        .typeSpecific.className = NULL,
+        .fieldOptions = NULL,
+      },
+      {
+        .name = "value",
+        .number = GPBOption_FieldNumber_Value,
+        .hasIndex = 1,
+        .flags = GPBFieldOptional,
+        .type = GPBTypeMessage,
+        .offset = offsetof(GPBOption_Storage, value),
+        .defaultValue.valueMessage = nil,
+        .typeSpecific.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];
+  }
+  return descriptor;
+}
+
+@end
+
+
+// @@protoc_insertion_point(global_scope)

+ 154 - 0
objectivec/google/protobuf/Wrappers.pbobjc.h

@@ -0,0 +1,154 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: google/protobuf/wrappers.proto
+
+#import "GPBProtocolBuffers.h"
+
+#if GOOGLE_PROTOBUF_OBJC_GEN_VERSION != 30000
+#error This file was generated by a different version of protoc-gen-objc which is incompatible with your Protocol Buffer sources.
+#endif
+
+// @@protoc_insertion_point(imports)
+
+CF_EXTERN_C_BEGIN
+
+
+#pragma mark - GPBWrappersRoot
+
+@interface GPBWrappersRoot : GPBRootObject
+
+// The base class provides:
+//   + (GPBExtensionRegistry *)extensionRegistry;
+// which is an GPBExtensionRegistry that includes all the extensions defined by
+// this file and all files that it depends on.
+
+@end
+
+#pragma mark - GPBDoubleValue
+
+typedef GPB_ENUM(GPBDoubleValue_FieldNumber) {
+  GPBDoubleValue_FieldNumber_Value = 1,
+};
+
+// Wrapper message for double.
+@interface GPBDoubleValue : GPBMessage
+
+// The double value.
+@property(nonatomic, readwrite) double value;
+
+@end
+
+#pragma mark - GPBFloatValue
+
+typedef GPB_ENUM(GPBFloatValue_FieldNumber) {
+  GPBFloatValue_FieldNumber_Value = 1,
+};
+
+// Wrapper message for float.
+@interface GPBFloatValue : GPBMessage
+
+// The float value.
+@property(nonatomic, readwrite) float value;
+
+@end
+
+#pragma mark - GPBInt64Value
+
+typedef GPB_ENUM(GPBInt64Value_FieldNumber) {
+  GPBInt64Value_FieldNumber_Value = 1,
+};
+
+// Wrapper message for int64.
+@interface GPBInt64Value : GPBMessage
+
+// The int64 value.
+@property(nonatomic, readwrite) int64_t value;
+
+@end
+
+#pragma mark - GPBUInt64Value
+
+typedef GPB_ENUM(GPBUInt64Value_FieldNumber) {
+  GPBUInt64Value_FieldNumber_Value = 1,
+};
+
+// Wrapper message for uint64.
+@interface GPBUInt64Value : GPBMessage
+
+// The uint64 value.
+@property(nonatomic, readwrite) uint64_t value;
+
+@end
+
+#pragma mark - GPBInt32Value
+
+typedef GPB_ENUM(GPBInt32Value_FieldNumber) {
+  GPBInt32Value_FieldNumber_Value = 1,
+};
+
+// Wrapper message for int32.
+@interface GPBInt32Value : GPBMessage
+
+// The int32 value.
+@property(nonatomic, readwrite) int32_t value;
+
+@end
+
+#pragma mark - GPBUInt32Value
+
+typedef GPB_ENUM(GPBUInt32Value_FieldNumber) {
+  GPBUInt32Value_FieldNumber_Value = 1,
+};
+
+// Wrapper message for uint32.
+@interface GPBUInt32Value : GPBMessage
+
+// The uint32 value.
+@property(nonatomic, readwrite) uint32_t value;
+
+@end
+
+#pragma mark - GPBBoolValue
+
+typedef GPB_ENUM(GPBBoolValue_FieldNumber) {
+  GPBBoolValue_FieldNumber_Value = 1,
+};
+
+// Wrapper message for bool.
+@interface GPBBoolValue : GPBMessage
+
+// The bool value.
+@property(nonatomic, readwrite) BOOL value;
+
+@end
+
+#pragma mark - GPBStringValue
+
+typedef GPB_ENUM(GPBStringValue_FieldNumber) {
+  GPBStringValue_FieldNumber_Value = 1,
+};
+
+// Wrapper message for string.
+@interface GPBStringValue : GPBMessage
+
+// The string value.
+@property(nonatomic, readwrite, copy) NSString *value;
+
+@end
+
+#pragma mark - GPBBytesValue
+
+typedef GPB_ENUM(GPBBytesValue_FieldNumber) {
+  GPBBytesValue_FieldNumber_Value = 1,
+};
+
+// Wrapper message for bytes.
+@interface GPBBytesValue : GPBMessage
+
+// The bytes value.
+@property(nonatomic, readwrite, copy) NSData *value;
+
+@end
+
+CF_EXTERN_C_END
+
+// @@protoc_insertion_point(global_scope)

+ 458 - 0
objectivec/google/protobuf/Wrappers.pbobjc.m

@@ -0,0 +1,458 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: google/protobuf/wrappers.proto
+
+#import "GPBProtocolBuffers_RuntimeSupport.h"
+#import "google/protobuf/Wrappers.pbobjc.h"
+// @@protoc_insertion_point(imports)
+
+#pragma mark - GPBWrappersRoot
+
+@implementation GPBWrappersRoot
+
+@end
+
+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) {
+    descriptor = [[GPBFileDescriptor alloc] initWithPackage:@"google.protobuf"
+                                                     syntax:GPBFileSyntaxProto3];
+  }
+  return descriptor;
+}
+
+#pragma mark - GPBDoubleValue
+
+@implementation GPBDoubleValue
+
+@dynamic value;
+
+typedef struct GPBDoubleValue_Storage {
+  uint32_t _has_storage_[1];
+  double value;
+} GPBDoubleValue_Storage;
+
+// This method is threadsafe because it is initially called
+// in +initialize for each subclass.
++ (GPBDescriptor *)descriptor {
+  static GPBDescriptor *descriptor = NULL;
+  if (!descriptor) {
+    static GPBMessageFieldDescription fields[] = {
+      {
+        .name = "value",
+        .number = GPBDoubleValue_FieldNumber_Value,
+        .hasIndex = 0,
+        .flags = GPBFieldOptional,
+        .type = GPBTypeDouble,
+        .offset = offsetof(GPBDoubleValue_Storage, value),
+        .defaultValue.valueDouble = 0,
+        .typeSpecific.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];
+  }
+  return descriptor;
+}
+
+@end
+
+#pragma mark - GPBFloatValue
+
+@implementation GPBFloatValue
+
+@dynamic value;
+
+typedef struct GPBFloatValue_Storage {
+  uint32_t _has_storage_[1];
+  float value;
+} GPBFloatValue_Storage;
+
+// This method is threadsafe because it is initially called
+// in +initialize for each subclass.
++ (GPBDescriptor *)descriptor {
+  static GPBDescriptor *descriptor = NULL;
+  if (!descriptor) {
+    static GPBMessageFieldDescription fields[] = {
+      {
+        .name = "value",
+        .number = GPBFloatValue_FieldNumber_Value,
+        .hasIndex = 0,
+        .flags = GPBFieldOptional,
+        .type = GPBTypeFloat,
+        .offset = offsetof(GPBFloatValue_Storage, value),
+        .defaultValue.valueFloat = 0,
+        .typeSpecific.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];
+  }
+  return descriptor;
+}
+
+@end
+
+#pragma mark - GPBInt64Value
+
+@implementation GPBInt64Value
+
+@dynamic value;
+
+typedef struct GPBInt64Value_Storage {
+  uint32_t _has_storage_[1];
+  int64_t value;
+} GPBInt64Value_Storage;
+
+// This method is threadsafe because it is initially called
+// in +initialize for each subclass.
++ (GPBDescriptor *)descriptor {
+  static GPBDescriptor *descriptor = NULL;
+  if (!descriptor) {
+    static GPBMessageFieldDescription fields[] = {
+      {
+        .name = "value",
+        .number = GPBInt64Value_FieldNumber_Value,
+        .hasIndex = 0,
+        .flags = GPBFieldOptional,
+        .type = GPBTypeInt64,
+        .offset = offsetof(GPBInt64Value_Storage, value),
+        .defaultValue.valueInt64 = 0LL,
+        .typeSpecific.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];
+  }
+  return descriptor;
+}
+
+@end
+
+#pragma mark - GPBUInt64Value
+
+@implementation GPBUInt64Value
+
+@dynamic value;
+
+typedef struct GPBUInt64Value_Storage {
+  uint32_t _has_storage_[1];
+  uint64_t value;
+} GPBUInt64Value_Storage;
+
+// This method is threadsafe because it is initially called
+// in +initialize for each subclass.
++ (GPBDescriptor *)descriptor {
+  static GPBDescriptor *descriptor = NULL;
+  if (!descriptor) {
+    static GPBMessageFieldDescription fields[] = {
+      {
+        .name = "value",
+        .number = GPBUInt64Value_FieldNumber_Value,
+        .hasIndex = 0,
+        .flags = GPBFieldOptional,
+        .type = GPBTypeUInt64,
+        .offset = offsetof(GPBUInt64Value_Storage, value),
+        .defaultValue.valueUInt64 = 0ULL,
+        .typeSpecific.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];
+  }
+  return descriptor;
+}
+
+@end
+
+#pragma mark - GPBInt32Value
+
+@implementation GPBInt32Value
+
+@dynamic value;
+
+typedef struct GPBInt32Value_Storage {
+  uint32_t _has_storage_[1];
+  int32_t value;
+} GPBInt32Value_Storage;
+
+// This method is threadsafe because it is initially called
+// in +initialize for each subclass.
++ (GPBDescriptor *)descriptor {
+  static GPBDescriptor *descriptor = NULL;
+  if (!descriptor) {
+    static GPBMessageFieldDescription fields[] = {
+      {
+        .name = "value",
+        .number = GPBInt32Value_FieldNumber_Value,
+        .hasIndex = 0,
+        .flags = GPBFieldOptional,
+        .type = GPBTypeInt32,
+        .offset = offsetof(GPBInt32Value_Storage, value),
+        .defaultValue.valueInt32 = 0,
+        .typeSpecific.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];
+  }
+  return descriptor;
+}
+
+@end
+
+#pragma mark - GPBUInt32Value
+
+@implementation GPBUInt32Value
+
+@dynamic value;
+
+typedef struct GPBUInt32Value_Storage {
+  uint32_t _has_storage_[1];
+  uint32_t value;
+} GPBUInt32Value_Storage;
+
+// This method is threadsafe because it is initially called
+// in +initialize for each subclass.
++ (GPBDescriptor *)descriptor {
+  static GPBDescriptor *descriptor = NULL;
+  if (!descriptor) {
+    static GPBMessageFieldDescription fields[] = {
+      {
+        .name = "value",
+        .number = GPBUInt32Value_FieldNumber_Value,
+        .hasIndex = 0,
+        .flags = GPBFieldOptional,
+        .type = GPBTypeUInt32,
+        .offset = offsetof(GPBUInt32Value_Storage, value),
+        .defaultValue.valueUInt32 = 0U,
+        .typeSpecific.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];
+  }
+  return descriptor;
+}
+
+@end
+
+#pragma mark - GPBBoolValue
+
+@implementation GPBBoolValue
+
+@dynamic value;
+
+typedef struct GPBBoolValue_Storage {
+  uint32_t _has_storage_[1];
+  BOOL value;
+} GPBBoolValue_Storage;
+
+// This method is threadsafe because it is initially called
+// in +initialize for each subclass.
++ (GPBDescriptor *)descriptor {
+  static GPBDescriptor *descriptor = NULL;
+  if (!descriptor) {
+    static GPBMessageFieldDescription fields[] = {
+      {
+        .name = "value",
+        .number = GPBBoolValue_FieldNumber_Value,
+        .hasIndex = 0,
+        .flags = GPBFieldOptional,
+        .type = GPBTypeBool,
+        .offset = offsetof(GPBBoolValue_Storage, value),
+        .defaultValue.valueBool = NO,
+        .typeSpecific.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];
+  }
+  return descriptor;
+}
+
+@end
+
+#pragma mark - GPBStringValue
+
+@implementation GPBStringValue
+
+@dynamic value;
+
+typedef struct GPBStringValue_Storage {
+  uint32_t _has_storage_[1];
+  NSString *value;
+} GPBStringValue_Storage;
+
+// This method is threadsafe because it is initially called
+// in +initialize for each subclass.
++ (GPBDescriptor *)descriptor {
+  static GPBDescriptor *descriptor = NULL;
+  if (!descriptor) {
+    static GPBMessageFieldDescription fields[] = {
+      {
+        .name = "value",
+        .number = GPBStringValue_FieldNumber_Value,
+        .hasIndex = 0,
+        .flags = GPBFieldOptional,
+        .type = GPBTypeString,
+        .offset = offsetof(GPBStringValue_Storage, value),
+        .defaultValue.valueString = nil,
+        .typeSpecific.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];
+  }
+  return descriptor;
+}
+
+@end
+
+#pragma mark - GPBBytesValue
+
+@implementation GPBBytesValue
+
+@dynamic value;
+
+typedef struct GPBBytesValue_Storage {
+  uint32_t _has_storage_[1];
+  NSData *value;
+} GPBBytesValue_Storage;
+
+// This method is threadsafe because it is initially called
+// in +initialize for each subclass.
++ (GPBDescriptor *)descriptor {
+  static GPBDescriptor *descriptor = NULL;
+  if (!descriptor) {
+    static GPBMessageFieldDescription fields[] = {
+      {
+        .name = "value",
+        .number = GPBBytesValue_FieldNumber_Value,
+        .hasIndex = 0,
+        .flags = GPBFieldOptional,
+        .type = GPBTypeData,
+        .offset = offsetof(GPBBytesValue_Storage, value),
+        .defaultValue.valueData = nil,
+        .typeSpecific.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];
+  }
+  return descriptor;
+}
+
+@end
+
+
+// @@protoc_insertion_point(global_scope)

+ 1 - 1
src/google/protobuf/compiler/objectivec/objectivec_enum.h

@@ -49,7 +49,7 @@ namespace objectivec {
 
 class EnumGenerator {
  public:
-  EnumGenerator(const EnumDescriptor* descriptor);
+  explicit EnumGenerator(const EnumDescriptor* descriptor);
   ~EnumGenerator();
 
   void GenerateHeader(io::Printer* printer);

+ 22 - 1
src/google/protobuf/compiler/objectivec/objectivec_enum_field.cc

@@ -48,6 +48,13 @@ void SetEnumVariables(const FieldDescriptor* descriptor,
                       map<string, string>* variables) {
   string type = EnumName(descriptor->enum_type());
   (*variables)["storage_type"] = type;
+  // For non repeated fields, if it was defined in a different file, the
+  // property decls need to use "enum NAME" rather than just "NAME" to support
+  // the forward declaration of the enums.
+  if (!descriptor->is_repeated() &&
+      (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";
@@ -76,7 +83,9 @@ void EnumFieldGenerator::GenerateFieldDescriptionTypeSpecific(
 
 void EnumFieldGenerator::GenerateCFunctionDeclarations(
     io::Printer* printer) const {
-  if (!HasPreservingUnknownEnumSemantics(descriptor_->file())) return;
+  if (!HasPreservingUnknownEnumSemantics(descriptor_->file())) {
+    return;
+  }
 
   printer->Print(
       variables_,
@@ -105,6 +114,18 @@ void EnumFieldGenerator::GenerateCFunctionImplementations(
       "\n");
 }
 
+void EnumFieldGenerator::DetermineForwardDeclarations(
+    set<string>* fwd_decls) const {
+  // If it is an enum defined in a different file, then we'll need a forward
+  // declaration for it.  When it is in our file, all the enums are output
+  // before the message, so it will be declared before it is needed.
+  if (descriptor_->file() != descriptor_->enum_type()->file()) {
+    // Enum name is already in "storage_type".
+    const string& name = variable("storage_type");
+    fwd_decls->insert("GPB_ENUM_FWD_DECLARE(" + name + ")");
+  }
+}
+
 RepeatedEnumFieldGenerator::RepeatedEnumFieldGenerator(
     const FieldDescriptor* descriptor)
     : RepeatedFieldGenerator(descriptor) {

+ 2 - 1
src/google/protobuf/compiler/objectivec/objectivec_enum_field.h

@@ -47,9 +47,10 @@ class EnumFieldGenerator : public SingleFieldGenerator {
   virtual void GenerateFieldDescriptionTypeSpecific(io::Printer* printer) const;
   virtual void GenerateCFunctionDeclarations(io::Printer* printer) const;
   virtual void GenerateCFunctionImplementations(io::Printer* printer) const;
+  virtual void DetermineForwardDeclarations(set<string>* fwd_decls) const;
 
  protected:
-  EnumFieldGenerator(const FieldDescriptor* descriptor);
+  explicit EnumFieldGenerator(const FieldDescriptor* descriptor);
   virtual ~EnumFieldGenerator();
 
  private:

+ 2 - 2
src/google/protobuf/compiler/objectivec/objectivec_extension.cc

@@ -66,7 +66,7 @@ ExtensionGenerator::ExtensionGenerator(const string& root_class_name,
   }
   if (descriptor->is_map()) {
     // NOTE: src/google/protobuf/compiler/plugin.cc makes use of cerr for some
-    // error case, so it seem to be ok to use as a back door for errors.
+    // error cases, so it seems to be ok to use as a back door for errors.
     cerr << "error: Extension is a map<>!"
          << " That used to be blocked by the compiler." << endl;
     cerr.flush();
@@ -107,7 +107,7 @@ void ExtensionGenerator::GenerateStaticVariablesInitialization(
 
   std::vector<string> options;
   if (descriptor_->is_repeated()) options.push_back("GPBExtensionRepeated");
-  if (descriptor_->options().packed()) options.push_back("GPBExtensionPacked");
+  if (descriptor_->is_packed()) options.push_back("GPBExtensionPacked");
   if (descriptor_->containing_type()->options().message_set_wire_format())
     options.push_back("GPBExtensionSetWireFormat");
 

+ 2 - 2
src/google/protobuf/compiler/objectivec/objectivec_extension.h

@@ -47,8 +47,8 @@ namespace objectivec {
 
 class ExtensionGenerator {
  public:
-  explicit ExtensionGenerator(const string& root_class_name,
-                              const FieldDescriptor* descriptor);
+  ExtensionGenerator(const string& root_class_name,
+                     const FieldDescriptor* descriptor);
   ~ExtensionGenerator();
 
   void GenerateMembersHeader(io::Printer* printer);

+ 15 - 6
src/google/protobuf/compiler/objectivec/objectivec_field.cc

@@ -80,7 +80,7 @@ void SetCommonFieldVariables(const FieldDescriptor* descriptor,
   if (descriptor->is_repeated()) field_flags.push_back("GPBFieldRepeated");
   if (descriptor->is_required()) field_flags.push_back("GPBFieldRequired");
   if (descriptor->is_optional()) field_flags.push_back("GPBFieldOptional");
-  if (descriptor->options().packed()) field_flags.push_back("GPBFieldPacked");
+  if (descriptor->is_packed()) field_flags.push_back("GPBFieldPacked");
 
   // ObjC custom flags.
   if (descriptor->has_default_value())
@@ -235,6 +235,11 @@ void FieldGenerator::GenerateCFunctionImplementations(
   // Nothing
 }
 
+void FieldGenerator::DetermineForwardDeclarations(
+    set<string>* fwd_decls) const {
+  // Nothing
+}
+
 void FieldGenerator::GenerateFieldDescription(
     io::Printer* printer) const {
   printer->Print(
@@ -282,12 +287,16 @@ void FieldGenerator::SetOneofIndexBase(int index_base) {
   if (descriptor_->containing_oneof() != NULL) {
     int index = descriptor_->containing_oneof()->index() + index_base;
     // Flip the sign to mark it as a oneof.
-    variables_["has_index"] = SimpleItoa(-index);;
+    variables_["has_index"] = SimpleItoa(-index);
   }
 }
 
 void FieldGenerator::FinishInitialization(void) {
-  // Nothing
+  // If "property_type" wasn't set, make it "storage_type".
+  if ((variables_.find("property_type") == variables_.end()) &&
+      (variables_.find("storage_type") != variables_.end())) {
+    variables_["property_type"] = variable("storage_type");
+  }
 }
 
 SingleFieldGenerator::SingleFieldGenerator(
@@ -313,7 +322,7 @@ void SingleFieldGenerator::GeneratePropertyDeclaration(
   }
   printer->Print(
       variables_,
-      "@property(nonatomic, readwrite) $storage_type$ $name$;\n"
+      "@property(nonatomic, readwrite) $property_type$ $name$;\n"
       "\n");
 }
 
@@ -369,12 +378,12 @@ void ObjCObjFieldGenerator::GeneratePropertyDeclaration(
   }
   printer->Print(
       variables_,
-      "@property(nonatomic, readwrite, $property_storage_attribute$) $storage_type$ *$name$$storage_attribute$;\n");
+      "@property(nonatomic, readwrite, $property_storage_attribute$) $property_type$ *$name$$storage_attribute$;\n");
   if (IsInitName(variables_.at("name"))) {
     // 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
     printer->Print(variables_,
-                   "- ($storage_type$ *)$name$ GPB_METHOD_FAMILY_NONE;\n");
+                   "- ($property_type$ *)$name$ GPB_METHOD_FAMILY_NONE;\n");
   }
   printer->Print("\n");
 }

+ 7 - 5
src/google/protobuf/compiler/objectivec/objectivec_field.h

@@ -65,6 +65,8 @@ class FieldGenerator {
   virtual void GenerateCFunctionDeclarations(io::Printer* printer) const;
   virtual void GenerateCFunctionImplementations(io::Printer* printer) const;
 
+  virtual void DetermineForwardDeclarations(set<string>* fwd_decls) const;
+
   void SetOneofIndexBase(int index_base);
 
   string variable(const char* key) const {
@@ -79,7 +81,7 @@ class FieldGenerator {
   string raw_field_name() const { return variable("raw_field_name"); }
 
  protected:
-  FieldGenerator(const FieldDescriptor* descriptor);
+  explicit FieldGenerator(const FieldDescriptor* descriptor);
 
   virtual void FinishInitialization(void);
   virtual bool WantsHasProperty(void) const = 0;
@@ -101,7 +103,7 @@ class SingleFieldGenerator : public FieldGenerator {
   virtual void GeneratePropertyImplementation(io::Printer* printer) const;
 
  protected:
-  SingleFieldGenerator(const FieldDescriptor* descriptor);
+  explicit SingleFieldGenerator(const FieldDescriptor* descriptor);
   virtual bool WantsHasProperty(void) const;
 
  private:
@@ -117,7 +119,7 @@ class ObjCObjFieldGenerator : public SingleFieldGenerator {
   virtual void GeneratePropertyDeclaration(io::Printer* printer) const;
 
  protected:
-  ObjCObjFieldGenerator(const FieldDescriptor* descriptor);
+  explicit ObjCObjFieldGenerator(const FieldDescriptor* descriptor);
 
  private:
   GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ObjCObjFieldGenerator);
@@ -133,7 +135,7 @@ class RepeatedFieldGenerator : public ObjCObjFieldGenerator {
   virtual void GeneratePropertyImplementation(io::Printer* printer) const;
 
  protected:
-  RepeatedFieldGenerator(const FieldDescriptor* descriptor);
+  explicit RepeatedFieldGenerator(const FieldDescriptor* descriptor);
   virtual void FinishInitialization(void);
   virtual bool WantsHasProperty(void) const;
 
@@ -144,7 +146,7 @@ class RepeatedFieldGenerator : public ObjCObjFieldGenerator {
 // Convenience class which constructs FieldGenerators for a Descriptor.
 class FieldGeneratorMap {
  public:
-  FieldGeneratorMap(const Descriptor* descriptor);
+  explicit FieldGeneratorMap(const Descriptor* descriptor);
   ~FieldGeneratorMap();
 
   const FieldGenerator& get(const FieldDescriptor* field) const;

+ 76 - 60
src/google/protobuf/compiler/objectivec/objectivec_file.cc

@@ -50,11 +50,17 @@ const int32 GOOGLE_PROTOBUF_OBJC_GEN_VERSION = 30000;
 
 namespace compiler {
 namespace objectivec {
+
 FileGenerator::FileGenerator(const FileDescriptor *file)
     : file_(file),
       root_class_name_(FileClassName(file)),
       is_filtered_(true),
-      all_extensions_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.
+  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
@@ -96,7 +102,9 @@ void FileGenerator::GenerateHeader(io::Printer *printer) {
       "\n",
       "filename", file_->name());
 
-  printer->Print("#import \"GPBProtocolBuffers.h\"\n\n");
+  printer->Print(
+      "#import \"GPBProtocolBuffers.h\"\n"
+      "\n");
 
   // Add some verification that the generated code matches the source the
   // code is being compiled with.
@@ -108,31 +116,34 @@ void FileGenerator::GenerateHeader(io::Printer *printer) {
       "protoc_gen_objc_version",
       SimpleItoa(GOOGLE_PROTOBUF_OBJC_GEN_VERSION));
 
-  if (!IsFiltered()) {
-    const vector<FileGenerator *> &dependency_generators =
-        DependencyGenerators();
-    if (dependency_generators.size() > 0) {
-      for (vector<FileGenerator *>::const_iterator iter =
-               dependency_generators.begin();
-           iter != dependency_generators.end(); ++iter) {
-        printer->Print("#import \"$header$.pbobjc.h\"\n",
-                       "header", (*iter)->Path());
-      }
-      printer->Print("\n");
+  const vector<FileGenerator *> &dependency_generators =
+      DependencyGenerators();
+  for (vector<FileGenerator *>::const_iterator iter =
+           dependency_generators.begin();
+       iter != dependency_generators.end(); ++iter) {
+    if ((*iter)->IsPublicDependency()) {
+      printer->Print("#import \"$header$.pbobjc.h\"\n",
+                     "header", (*iter)->Path());
     }
   }
 
+  printer->Print(
+      "// @@protoc_insertion_point(imports)\n"
+      "\n");
+
   printer->Print("CF_EXTERN_C_BEGIN\n\n");
 
   if (!IsFiltered()) {
-    set<string> dependencies;
-    DetermineDependencies(&dependencies);
-    for (set<string>::const_iterator i(dependencies.begin());
-         i != dependencies.end(); ++i) {
+    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 (dependencies.begin() != dependencies.end()) {
+    if (fwd_decls.begin() != fwd_decls.end()) {
       printer->Print("\n");
     }
   }
@@ -156,7 +167,14 @@ void FileGenerator::GenerateHeader(io::Printer *printer) {
         "#pragma mark - $root_class_name$\n"
         "\n"
         "@interface $root_class_name$ : GPBRootObject\n"
-        "@end\n\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_);
   }
 
@@ -189,33 +207,10 @@ void FileGenerator::GenerateHeader(io::Printer *printer) {
   }
 
   printer->Print("CF_EXTERN_C_END\n");
-}
-
-void DetermineDependenciesWorker(set<string> *dependencies,
-                                 set<string> *seen_files,
-                                 const string &classname,
-                                 const FileDescriptor *file) {
-  if (seen_files->find(file->name()) != seen_files->end()) {
-    // don't infinitely recurse
-    return;
-  }
-
-  seen_files->insert(file->name());
-
-  for (int i = 0; i < file->dependency_count(); i++) {
-    DetermineDependenciesWorker(dependencies, seen_files, classname,
-                                file->dependency(i));
-  }
-  for (int i = 0; i < file->message_type_count(); i++) {
-    MessageGenerator(classname, file->message_type(i))
-        .DetermineDependencies(dependencies);
-  }
-}
 
-void FileGenerator::DetermineDependencies(set<string> *dependencies) {
-  set<string> seen_files;
-  DetermineDependenciesWorker(dependencies, &seen_files, root_class_name_,
-                              file_);
+  printer->Print(
+    "\n"
+    "// @@protoc_insertion_point(global_scope)\n");
 }
 
 void FileGenerator::GenerateSource(io::Printer *printer) {
@@ -225,6 +220,25 @@ void FileGenerator::GenerateSource(io::Printer *printer) {
       "\n",
       "filename", file_->name());
 
+  string header_file = Path() + ".pbobjc.h";
+  printer->Print(
+      "#import \"GPBProtocolBuffers_RuntimeSupport.h\"\n"
+      "#import \"$header_file$\"\n",
+      "header_file", header_file);
+  const vector<FileGenerator *> &dependency_generators =
+      DependencyGenerators();
+  for (vector<FileGenerator *>::const_iterator iter =
+           dependency_generators.begin();
+       iter != dependency_generators.end(); ++iter) {
+    if (!(*iter)->IsPublicDependency()) {
+      printer->Print("#import \"$header$.pbobjc.h\"\n",
+                     "header", (*iter)->Path());
+    }
+  }
+  printer->Print(
+      "// @@protoc_insertion_point(imports)\n"
+      "\n");
+
   if (IsFiltered()) {
     printer->Print(
         "// File empty because all messages, extensions and enum have been filtered.\n"
@@ -232,22 +246,17 @@ void FileGenerator::GenerateSource(io::Printer *printer) {
         "\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",
+        "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("#import \"GPBProtocolBuffers_RuntimeSupport.h\"\n\n");
-
-  string header_file = Path() + ".pbobjc.h";
-
   printer->Print(
-      "#import \"$header_file$\"\n"
-      "\n"
       "#pragma mark - $root_class_name$\n"
       "\n"
       "@implementation $root_class_name$\n\n",
-      "header_file", header_file,
       "root_class_name", root_class_name_);
 
   bool generated_extensions = false;
@@ -326,12 +335,7 @@ void FileGenerator::GenerateSource(io::Printer *printer) {
           "  }\n"
           "  return registry;\n"
           "}\n"
-          "\n"
-          "+ (void)load {\n"
-          "  @autoreleasepool {\n"
-          "    [self extensionRegistry]; // Construct extension registry.\n"
-          "  }\n"
-          "}\n\n");
+          "\n");
     }
   }
 
@@ -374,19 +378,31 @@ void FileGenerator::GenerateSource(io::Printer *printer) {
        iter != message_generators_.end(); ++iter) {
     (*iter)->GenerateSource(printer);
   }
+
+  printer->Print(
+    "\n"
+    "// @@protoc_insertion_point(global_scope)\n");
 }
 
 const string FileGenerator::Path() const { return FilePath(file_); }
 
 const vector<FileGenerator *> &FileGenerator::DependencyGenerators() {
   if (file_->dependency_count() != dependency_generators_.size()) {
+    set<string> public_import_names;
+    for (int i = 0; i < file_->public_dependency_count(); i++) {
+      public_import_names.insert(file_->public_dependency(i)->name());
+    }
     for (int i = 0; i < file_->dependency_count(); i++) {
       FileGenerator *generator = new FileGenerator(file_->dependency(i));
+      const string& name = file_->dependency(i)->name();
+      bool public_import = (public_import_names.count(name) != 0);
+      generator->SetIsPublicDependency(public_import);
       dependency_generators_.push_back(generator);
     }
   }
   return dependency_generators_;
 }
+
 }  // namespace objectivec
 }  // namespace compiler
 }  // namespace protobuf

+ 9 - 2
src/google/protobuf/compiler/objectivec/objectivec_file.h

@@ -66,6 +66,12 @@ class FileGenerator {
 
   bool IsFiltered() const { return is_filtered_; }
   bool AreAllExtensionsFiltered() const { return all_extensions_filtered_; }
+  bool IsPublicDependency() const { return is_public_dep_; }
+
+ protected:
+  void SetIsPublicDependency(bool is_public_dep) {
+    is_public_dep_ = is_public_dep;
+  }
 
  private:
   const FileDescriptor* file_;
@@ -80,15 +86,16 @@ class FileGenerator {
   vector<ExtensionGenerator*> extension_generators_;
   bool is_filtered_;
   bool all_extensions_filtered_;
-
-  void DetermineDependencies(set<string>* dependencies);
+  bool is_public_dep_;
 
   const vector<FileGenerator*>& DependencyGenerators();
 
   GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FileGenerator);
 };
+
 }  // namespace objectivec
 }  // namespace compiler
 }  // namespace protobuf
 }  // namespace google
+
 #endif  // GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_FILE_H__

+ 44 - 7
src/google/protobuf/compiler/objectivec/objectivec_helpers.cc

@@ -41,7 +41,7 @@
 #include <google/protobuf/stubs/strutil.h>
 
 // NOTE: src/google/protobuf/compiler/plugin.cc makes use of cerr for some
-// error case, so it seem to be ok to use as a back door for errors.
+// error cases, so it seems to be ok to use as a back door for errors.
 
 namespace google {
 namespace protobuf {
@@ -53,6 +53,11 @@ 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
+// Objective C plugin, test failures were seen on TravisCI because isupper('A')
+// was coming back false for some server's locale.  This approach avoids any
+// such issues.
 
 bool IsLower(const char c) {
   return ('a' <= c && c <= 'z');
@@ -205,10 +210,9 @@ const char* const kReservedWordList[] = {
     // Only need to add instance methods that may conflict with
     // method declared in protos. The main cases are methods
     // that take no arguments, or setFoo:/hasFoo: type methods.
-    // These are currently in the same order as in GPBMessage.h.
-    "unknownFields", "extensionRegistry", "isInitialized",
-    "data", "delimitedData", "serializedSize",
-    "descriptor", "extensionsCurrentlySet", "clear", "sortedExtensionsInUse",
+    "clear", "data", "delimitedData", "descriptor", "extensionRegistry",
+    "extensionsCurrentlySet", "isInitialized", "serializedSize",
+    "sortedExtensionsInUse", "unknownFields",
 
     // MacTypes.h names
     "Fixed", "Fract", "Size", "LogicalAddress", "PhysicalAddress", "ByteCount",
@@ -335,7 +339,32 @@ string FilePath(const FileDescriptor* file) {
 
 string FileClassPrefix(const FileDescriptor* file) {
   // Default is empty string, no need to check has_objc_class_prefix.
-  return file->options().objc_class_prefix();
+  string result = file->options().objc_class_prefix();
+  return result;
+}
+
+void ValidateObjCClassPrefix(const FileDescriptor* file) {
+  string prefix = file->options().objc_class_prefix();
+  if (prefix.length() > 0) {
+    // 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.
+    if (!IsUpper(prefix[0])) {
+      cerr << endl
+           << "protoc:0: warning: Invalid 'option objc_class_prefix = \""
+           << prefix << "\";' in '" << file->name() << "';"
+           << " it should start with a capital letter."
+           << endl;
+      cerr.flush();
+    }
+    if (prefix.length() < 3) {
+      cerr << endl
+           << "protoc:0: warning: Invalid 'option objc_class_prefix = \""
+           << prefix << "\";' in '" << file->name() << "';"
+           << " Apple recommends they should be at least 3 characters long."
+           << endl;
+      cerr.flush();
+    }
+  }
 }
 
 string FileClassName(const FileDescriptor* file) {
@@ -468,7 +497,7 @@ string OneofEnumName(const OneofDescriptor* descriptor) {
   const Descriptor* fieldDescriptor = descriptor->containing_type();
   string name = ClassName(fieldDescriptor);
   name += "_" + UnderscoresToCamelCase(descriptor->name(), true) + "_OneOfCase";
-  // No sanitize needed because it the OS never has names that end in OneOfCase.
+  // No sanitize needed because the OS never has names that end in _OneOfCase.
   return name;
 }
 
@@ -560,6 +589,8 @@ string GetCapitalizedType(const FieldDescriptor* field) {
       return "Message";
   }
 
+  // Some compilers report reaching end of function even though all cases of
+  // the enum are handed in the switch.
   GOOGLE_LOG(FATAL) << "Can't get here.";
   return NULL;
 }
@@ -607,6 +638,8 @@ ObjectiveCType GetObjectiveCType(FieldDescriptor::Type field_type) {
       return OBJECTIVECTYPE_MESSAGE;
   }
 
+  // Some compilers report reaching end of function even though all cases of
+  // the enum are handed in the switch.
   GOOGLE_LOG(FATAL) << "Can't get here.";
   return OBJECTIVECTYPE_INT32;
 }
@@ -683,6 +716,8 @@ string GPBValueFieldName(const FieldDescriptor* field) {
       return "valueMessage";
   }
 
+  // Some compilers report reaching end of function even though all cases of
+  // the enum are handed in the switch.
   GOOGLE_LOG(FATAL) << "Can't get here.";
   return NULL;
 }
@@ -753,6 +788,8 @@ string DefaultValue(const FieldDescriptor* field) {
       return "nil";
   }
 
+  // Some compilers report reaching end of function even though all cases of
+  // the enum are handed in the switch.
   GOOGLE_LOG(FATAL) << "Can't get here.";
   return NULL;
 }

+ 3 - 0
src/google/protobuf/compiler/objectivec/objectivec_helpers.h

@@ -62,6 +62,9 @@ string FileName(const FileDescriptor* file);
 // declared in the proto package.
 string FilePath(const FileDescriptor* file);
 
+// Checks the prefix for a given file and outputs any warnings/errors needed.
+void ValidateObjCClassPrefix(const FileDescriptor* file);
+
 // Gets the name of the root class we'll generate in the file.  This class
 // is not meant for external consumption, but instead contains helpers that
 // the rest of the the classes need

+ 2 - 0
src/google/protobuf/compiler/objectivec/objectivec_map_field.cc

@@ -76,6 +76,8 @@ const char* MapEntryTypeName(const FieldDescriptor* descriptor, bool isKey) {
       return "Object";
   }
 
+  // Some compilers report reaching end of function even though all cases of
+  // the enum are handed in the switch.
   GOOGLE_LOG(FATAL) << "Can't get here.";
   return NULL;
 }

+ 1 - 1
src/google/protobuf/compiler/objectivec/objectivec_map_field.h

@@ -48,7 +48,7 @@ class MapFieldGenerator : public RepeatedFieldGenerator {
   virtual void GenerateFieldDescriptionTypeSpecific(io::Printer* printer) const;
 
  protected:
-  MapFieldGenerator(const FieldDescriptor* descriptor);
+  explicit MapFieldGenerator(const FieldDescriptor* descriptor);
   virtual ~MapFieldGenerator();
 
  private:

+ 17 - 6
src/google/protobuf/compiler/objectivec/objectivec_message.cc

@@ -120,6 +120,8 @@ int OrderGroupForFieldDescriptor(const FieldDescriptor* descriptor) {
       return 1;
   }
 
+  // Some compilers report reaching end of function even though all cases of
+  // the enum are handed in the switch.
   GOOGLE_LOG(FATAL) << "Can't get here.";
   return 0;
 }
@@ -188,7 +190,7 @@ MessageGenerator::MessageGenerator(const string& root_classname,
       extension_generators_.push_back(
           new ExtensionGenerator(class_name_, descriptor_->extension(i)));
     }
-    // No need to oneofs if this message is filtered
+    // 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);
@@ -253,15 +255,24 @@ void MessageGenerator::GenerateStaticVariablesInitialization(
   }
 }
 
-void MessageGenerator::DetermineDependencies(set<string>* dependencies) {
+void MessageGenerator::DetermineForwardDeclarations(set<string>* fwd_decls) {
   if (!IsFiltered() && !IsMapEntryMessage(descriptor_)) {
-    dependencies->insert("@class " + class_name_);
+    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 (fieldDescriptor->is_repeated()) {
+        continue;
+      }
+      field_generators_.get(fieldDescriptor)
+          .DetermineForwardDeclarations(fwd_decls);
+    }
   }
 
   for (vector<MessageGenerator*>::iterator iter =
            nested_message_generators_.begin();
        iter != nested_message_generators_.end(); ++iter) {
-    (*iter)->DetermineDependencies(dependencies);
+    (*iter)->DetermineForwardDeclarations(fwd_decls);
   }
 }
 
@@ -361,13 +372,13 @@ void MessageGenerator::GenerateMessageHeader(io::Printer* printer) {
         "classname", class_name_,
         "comments", message_comments);
 
-    vector<bool> seen_oneofs(descriptor_->oneof_decl_count(), false);
+    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] = true;
+          seen_oneofs[oneof_index] = 1;
           oneof_generators_[oneof_index]->GeneratePublicCasePropertyDeclaration(
               printer);
         }

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

@@ -63,7 +63,7 @@ class MessageGenerator {
   void GenerateMessageHeader(io::Printer* printer);
   void GenerateSource(io::Printer* printer);
   void GenerateExtensionRegistrationSource(io::Printer* printer);
-  void DetermineDependencies(set<string>* dependencies);
+  void DetermineForwardDeclarations(set<string>* fwd_decls);
 
   // This only speaks for this message, not sub message/enums.
   bool IsFiltered() const { return filter_reason_.length() > 0; }

+ 6 - 0
src/google/protobuf/compiler/objectivec/objectivec_message_field.cc

@@ -65,6 +65,12 @@ MessageFieldGenerator::MessageFieldGenerator(const FieldDescriptor* descriptor)
 
 MessageFieldGenerator::~MessageFieldGenerator() {}
 
+void MessageFieldGenerator::DetermineForwardDeclarations(
+    set<string>* fwd_decls) const {
+  // Class name is already in "storage_type".
+  fwd_decls->insert("@class " + variable("storage_type"));
+}
+
 bool MessageFieldGenerator::WantsHasProperty(void) const {
   if (descriptor_->containing_oneof() != NULL) {
     // If in a oneof, it uses the oneofcase instead of a has bit.

+ 5 - 2
src/google/protobuf/compiler/objectivec/objectivec_message_field.h

@@ -44,10 +44,13 @@ class MessageFieldGenerator : public ObjCObjFieldGenerator {
   friend FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field);
 
  protected:
-  MessageFieldGenerator(const FieldDescriptor* descriptor);
+  explicit MessageFieldGenerator(const FieldDescriptor* descriptor);
   virtual ~MessageFieldGenerator();
   virtual bool WantsHasProperty(void) const;
 
+ public:
+  virtual void DetermineForwardDeclarations(set<string>* fwd_decls) const;
+
  private:
   GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MessageFieldGenerator);
 };
@@ -56,7 +59,7 @@ class RepeatedMessageFieldGenerator : public RepeatedFieldGenerator {
   friend FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field);
 
  protected:
-  RepeatedMessageFieldGenerator(const FieldDescriptor* descriptor);
+  explicit RepeatedMessageFieldGenerator(const FieldDescriptor* descriptor);
   virtual ~RepeatedMessageFieldGenerator();
 
  private:

+ 1 - 1
src/google/protobuf/compiler/objectivec/objectivec_oneof.h

@@ -49,7 +49,7 @@ namespace objectivec {
 
 class OneofGenerator {
  public:
-  OneofGenerator(const OneofDescriptor* descriptor);
+  explicit OneofGenerator(const OneofDescriptor* descriptor);
   ~OneofGenerator();
 
   void SetOneofIndexBase(int index_base);

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

@@ -77,6 +77,8 @@ const char* PrimitiveTypeName(const FieldDescriptor* descriptor) {
       return NULL;
   }
 
+  // Some compilers report reaching end of function even though all cases of
+  // the enum are handed in the switch.
   GOOGLE_LOG(FATAL) << "Can't get here.";
   return NULL;
 }
@@ -108,6 +110,8 @@ const char* PrimitiveArrayTypeName(const FieldDescriptor* descriptor) {
       return "";  // Want NSArray
   }
 
+  // Some compilers report reaching end of function even though all cases of
+  // the enum are handed in the switch.
   GOOGLE_LOG(FATAL) << "Can't get here.";
   return NULL;
 }

+ 3 - 3
src/google/protobuf/compiler/objectivec/objectivec_primitive_field.h

@@ -44,7 +44,7 @@ class PrimitiveFieldGenerator : public SingleFieldGenerator {
   friend FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field);
 
  protected:
-  PrimitiveFieldGenerator(const FieldDescriptor* descriptor);
+  explicit PrimitiveFieldGenerator(const FieldDescriptor* descriptor);
   virtual ~PrimitiveFieldGenerator();
 
  private:
@@ -55,7 +55,7 @@ class PrimitiveObjFieldGenerator : public ObjCObjFieldGenerator {
   friend FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field);
 
  protected:
-  PrimitiveObjFieldGenerator(const FieldDescriptor* descriptor);
+  explicit PrimitiveObjFieldGenerator(const FieldDescriptor* descriptor);
   virtual ~PrimitiveObjFieldGenerator();
 
  private:
@@ -66,7 +66,7 @@ class RepeatedPrimitiveFieldGenerator : public RepeatedFieldGenerator {
   friend FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field);
 
  protected:
-  RepeatedPrimitiveFieldGenerator(const FieldDescriptor* descriptor);
+  explicit RepeatedPrimitiveFieldGenerator(const FieldDescriptor* descriptor);
   virtual ~RepeatedPrimitiveFieldGenerator();
   virtual void FinishInitialization(void);
 

Bu fark içinde çok fazla dosya değişikliği olduğu için bazı dosyalar gösterilmiyor