Merge pull request #382 from jtattermusch/integrate_from_master

Integrate changes from latest master branch into csharp branch.
pull/384/head
Jie Luo 10 years ago
commit 2d9b1c592f
  1. 7
      .gitignore
  2. 1
      .travis.yml
  3. 124
      Makefile.am
  4. 120
      conformance/ConformanceJava.java
  5. 31
      conformance/Makefile.am
  6. 1
      conformance/conformance.proto
  7. 4
      conformance/conformance_test_runner.cc
  8. 4
      csharp/src/ProtocolBuffers.Test/TestProtos/UnittestDropUnknownFields.cs
  9. 2
      examples/add_person.py
  10. 2
      examples/list_people.py
  11. 1
      generate_descriptor_proto.sh
  12. 23
      javanano/README.md
  13. 15
      javanano/pom.xml
  14. 2
      javanano/src/main/java/com/google/protobuf/nano/CodedInputByteBufferNano.java
  15. 264
      javanano/src/main/java/com/google/protobuf/nano/CodedOutputByteBufferNano.java
  16. 28
      javanano/src/main/java/com/google/protobuf/nano/ExtendableMessageNano.java
  17. 33
      javanano/src/main/java/com/google/protobuf/nano/Extension.java
  18. 34
      javanano/src/main/java/com/google/protobuf/nano/FieldArray.java
  19. 52
      javanano/src/main/java/com/google/protobuf/nano/FieldData.java
  20. 8
      javanano/src/main/java/com/google/protobuf/nano/InternalNano.java
  21. 8
      javanano/src/main/java/com/google/protobuf/nano/MessageNano.java
  22. 4
      javanano/src/main/java/com/google/protobuf/nano/MessageNanoPrinter.java
  23. 4
      javanano/src/main/java/com/google/protobuf/nano/UnknownFieldData.java
  24. 80
      javanano/src/test/java/com/google/protobuf/nano/NanoTest.java
  25. 4
      javanano/src/test/java/com/google/protobuf/nano/unittest_extension_nano.proto
  26. 56
      objectivec/DevTools/check_version_stamps.sh
  27. 36
      objectivec/DevTools/generate_descriptors_proto.sh
  28. 687
      objectivec/DevTools/pddm.py
  29. 515
      objectivec/DevTools/pddm_tests.py
  30. 535
      objectivec/GPBArray.h
  31. 2499
      objectivec/GPBArray.m
  32. 130
      objectivec/GPBArray_PackagePrivate.h
  33. 84
      objectivec/GPBBootstrap.h
  34. 81
      objectivec/GPBCodedInputStream.h
  35. 801
      objectivec/GPBCodedInputStream.m
  36. 131
      objectivec/GPBCodedInputStream_PackagePrivate.h
  37. 340
      objectivec/GPBCodedOutputStream.h
  38. 1229
      objectivec/GPBCodedOutputStream.m
  39. 143
      objectivec/GPBDescriptor.h
  40. 888
      objectivec/GPBDescriptor.m
  41. 293
      objectivec/GPBDescriptor_PackagePrivate.h
  42. 2233
      objectivec/GPBDictionary.h
  43. 12627
      objectivec/GPBDictionary.m
  44. 577
      objectivec/GPBDictionary_PackagePrivate.h
  45. 51
      objectivec/GPBExtensionField.h
  46. 525
      objectivec/GPBExtensionField.m
  47. 51
      objectivec/GPBExtensionField_PackagePrivate.h
  48. 46
      objectivec/GPBExtensionRegistry.h
  49. 98
      objectivec/GPBExtensionRegistry.m
  50. 40
      objectivec/GPBExtensionRegistry_PackagePrivate.h
  51. 56
      objectivec/GPBField.h
  52. 328
      objectivec/GPBField.m
  53. 49
      objectivec/GPBField_PackagePrivate.h
  54. 151
      objectivec/GPBMessage.h
  55. 4735
      objectivec/GPBMessage.m
  56. 124
      objectivec/GPBMessage_PackagePrivate.h
  57. 45
      objectivec/GPBProtocolBuffers.h
  58. 49
      objectivec/GPBProtocolBuffers.m
  59. 41
      objectivec/GPBProtocolBuffers_RuntimeSupport.h
  60. 42
      objectivec/GPBRootObject.h
  61. 177
      objectivec/GPBRootObject.m
  62. 42
      objectivec/GPBRootObject_PackagePrivate.h
  63. 102
      objectivec/GPBTypes.h
  64. 46
      objectivec/GPBUnknownFieldSet.h
  65. 422
      objectivec/GPBUnknownFieldSet.m
  66. 61
      objectivec/GPBUnknownFieldSet_PackagePrivate.h
  67. 181
      objectivec/GPBUtilities.h
  68. 1645
      objectivec/GPBUtilities.m
  69. 426
      objectivec/GPBUtilities_PackagePrivate.h
  70. 48
      objectivec/GPBWellKnownTypes.h
  71. 117
      objectivec/GPBWellKnownTypes.m
  72. 68
      objectivec/GPBWireFormat.h
  73. 78
      objectivec/GPBWireFormat.m
  74. 919
      objectivec/ProtocolBuffers_OSX.xcodeproj/project.pbxproj
  75. 7
      objectivec/ProtocolBuffers_OSX.xcodeproj/project.xcworkspace/contents.xcworkspacedata
  76. 8
      objectivec/ProtocolBuffers_OSX.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings
  77. 125
      objectivec/ProtocolBuffers_OSX.xcodeproj/xcshareddata/xcschemes/PerformanceTests.xcscheme
  78. 115
      objectivec/ProtocolBuffers_OSX.xcodeproj/xcshareddata/xcschemes/ProtocolBuffers.xcscheme
  79. 1093
      objectivec/ProtocolBuffers_iOS.xcodeproj/project.pbxproj
  80. 7
      objectivec/ProtocolBuffers_iOS.xcodeproj/project.xcworkspace/contents.xcworkspacedata
  81. 8
      objectivec/ProtocolBuffers_iOS.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings
  82. 62
      objectivec/ProtocolBuffers_iOS.xcodeproj/xcshareddata/xcbaselines/8BBEA4A5147C727100C4ADB7.xcbaseline/FFE465CA-0E74-40E8-9F09-500B66B7DCB2.plist
  83. 21
      objectivec/ProtocolBuffers_iOS.xcodeproj/xcshareddata/xcbaselines/8BBEA4A5147C727100C4ADB7.xcbaseline/Info.plist
  84. 134
      objectivec/ProtocolBuffers_iOS.xcodeproj/xcshareddata/xcschemes/PerformanceTests.xcscheme
  85. 116
      objectivec/ProtocolBuffers_iOS.xcodeproj/xcshareddata/xcschemes/ProtocolBuffers.xcscheme
  86. 40
      objectivec/Tests/Filter1.txt
  87. 35
      objectivec/Tests/Filter2.txt
  88. 57
      objectivec/Tests/GPBARCUnittestProtos.m
  89. 3365
      objectivec/Tests/GPBArrayTests.m
  90. 290
      objectivec/Tests/GPBCodedInputStreamTests.m
  91. 321
      objectivec/Tests/GPBCodedOuputStreamTests.m
  92. 157
      objectivec/Tests/GPBConcurrencyTests.m
  93. 232
      objectivec/Tests/GPBDescriptorTests.m
  94. 2421
      objectivec/Tests/GPBDictionaryTests+Bool.m
  95. 3650
      objectivec/Tests/GPBDictionaryTests+Int32.m
  96. 3650
      objectivec/Tests/GPBDictionaryTests+Int64.m
  97. 3362
      objectivec/Tests/GPBDictionaryTests+String.m
  98. 3650
      objectivec/Tests/GPBDictionaryTests+UInt32.m
  99. 3649
      objectivec/Tests/GPBDictionaryTests+UInt64.m
  100. 1044
      objectivec/Tests/GPBDictionaryTests.pddm
  101. Some files were not shown because too many files have changed in this diff Show More

7
.gitignore vendored

@ -51,6 +51,7 @@ cpp_test*.pb.*
*.pyc
*.egg-info
*_pb2.py
python/*.egg
python/.eggs/
python/build/
python/google/protobuf/compiler/
@ -82,3 +83,9 @@ vsprojects/Release
# NuGet packages: we want the repository configuration, but not the
# packages themselves.
/csharp/src/packages/*/
# Directories created by opening the Objective C Xcode projects.
objectivec/ProtocolBuffers_OSX.xcodeproj/project.xcworkspace/xcuserdata/
objectivec/ProtocolBuffers_OSX.xcodeproj/xcuserdata/
objectivec/ProtocolBuffers_iOS.xcodeproj/project.xcworkspace/xcuserdata/
objectivec/ProtocolBuffers_iOS.xcodeproj/xcuserdata/

@ -14,6 +14,7 @@ script:
- cd python && python setup.py build && python setup.py test && cd ..
- export LD_LIBRARY_PATH=../src/.libs
- cd python && python setup.py build --cpp_implementation && python setup.py test --cpp_implementation && cd ..
- cd conformance && make test_java && cd ..
- make distcheck -j2
notifications:
email: false

@ -197,6 +197,128 @@ javanano_EXTRA_DIST=
javanano/README.md \
javanano/pom.xml
objectivec_EXTRA_DIST= \
objectivec/DevTools/generate_descriptors_proto.sh \
objectivec/DevTools/pddm.py \
objectivec/DevTools/pddm_tests.py \
objectivec/google/protobuf/Descriptor.pbobjc.h \
objectivec/google/protobuf/Descriptor.pbobjc.m \
objectivec/google/protobuf/Duration.pbobjc.h \
objectivec/google/protobuf/Duration.pbobjc.m \
objectivec/google/protobuf/Timestamp.pbobjc.h \
objectivec/google/protobuf/Timestamp.pbobjc.m \
objectivec/GPBArray.h \
objectivec/GPBArray.m \
objectivec/GPBArray_PackagePrivate.h \
objectivec/GPBBootstrap.h \
objectivec/GPBCodedInputStream.h \
objectivec/GPBCodedInputStream.m \
objectivec/GPBCodedInputStream_PackagePrivate.h \
objectivec/GPBCodedOutputStream.h \
objectivec/GPBCodedOutputStream.m \
objectivec/GPBDescriptor.h \
objectivec/GPBDescriptor.m \
objectivec/GPBDescriptor_PackagePrivate.h \
objectivec/GPBDictionary.h \
objectivec/GPBDictionary.m \
objectivec/GPBDictionary_PackagePrivate.h \
objectivec/GPBExtensionField.h \
objectivec/GPBExtensionField.m \
objectivec/GPBExtensionField_PackagePrivate.h \
objectivec/GPBExtensionRegistry.h \
objectivec/GPBExtensionRegistry.m \
objectivec/GPBExtensionRegistry_PackagePrivate.h \
objectivec/GPBField.h \
objectivec/GPBField.m \
objectivec/GPBField_PackagePrivate.h \
objectivec/GPBMessage.h \
objectivec/GPBMessage.m \
objectivec/GPBMessage_PackagePrivate.h \
objectivec/GPBProtocolBuffers.h \
objectivec/GPBProtocolBuffers.m \
objectivec/GPBProtocolBuffers_RuntimeSupport.h \
objectivec/GPBRootObject.h \
objectivec/GPBRootObject.m \
objectivec/GPBRootObject_PackagePrivate.h \
objectivec/GPBTypes.h \
objectivec/GPBUnknownFieldSet.h \
objectivec/GPBUnknownFieldSet.m \
objectivec/GPBUnknownFieldSet_PackagePrivate.h \
objectivec/GPBUtilities.h \
objectivec/GPBUtilities.m \
objectivec/GPBUtilities_PackagePrivate.h \
objectivec/GPBWellKnownTypes.h \
objectivec/GPBWellKnownTypes.m \
objectivec/GPBWireFormat.h \
objectivec/GPBWireFormat.m \
objectivec/ProtocolBuffers_iOS.xcodeproj/project.pbxproj \
objectivec/ProtocolBuffers_iOS.xcodeproj/project.xcworkspace/contents.xcworkspacedata \
objectivec/ProtocolBuffers_iOS.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings \
objectivec/ProtocolBuffers_iOS.xcodeproj/xcshareddata/xcbaselines/8BBEA4A5147C727100C4ADB7.xcbaseline/FFE465CA-0E74-40E8-9F09-500B66B7DCB2.plist \
objectivec/ProtocolBuffers_iOS.xcodeproj/xcshareddata/xcbaselines/8BBEA4A5147C727100C4ADB7.xcbaseline/Info.plist \
objectivec/ProtocolBuffers_iOS.xcodeproj/xcshareddata/xcschemes/PerformanceTests.xcscheme \
objectivec/ProtocolBuffers_iOS.xcodeproj/xcshareddata/xcschemes/ProtocolBuffers.xcscheme \
objectivec/ProtocolBuffers_OSX.xcodeproj/project.pbxproj \
objectivec/ProtocolBuffers_OSX.xcodeproj/project.xcworkspace/contents.xcworkspacedata \
objectivec/ProtocolBuffers_OSX.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings \
objectivec/ProtocolBuffers_OSX.xcodeproj/xcshareddata/xcschemes/PerformanceTests.xcscheme \
objectivec/ProtocolBuffers_OSX.xcodeproj/xcshareddata/xcschemes/ProtocolBuffers.xcscheme \
objectivec/Tests/Filter1.txt \
objectivec/Tests/Filter2.txt \
objectivec/Tests/golden_message \
objectivec/Tests/golden_packed_fields_message \
objectivec/Tests/GPBARCUnittestProtos.m \
objectivec/Tests/GPBArrayTests.m \
objectivec/Tests/GPBCodedInputStreamTests.m \
objectivec/Tests/GPBCodedOuputStreamTests.m \
objectivec/Tests/GPBConcurrencyTests.m \
objectivec/Tests/GPBDescriptorTests.m \
objectivec/Tests/GPBDictionaryTests+Bool.m \
objectivec/Tests/GPBDictionaryTests+Int32.m \
objectivec/Tests/GPBDictionaryTests+Int64.m \
objectivec/Tests/GPBDictionaryTests+String.m \
objectivec/Tests/GPBDictionaryTests+UInt32.m \
objectivec/Tests/GPBDictionaryTests+UInt64.m \
objectivec/Tests/GPBDictionaryTests.pddm \
objectivec/Tests/GPBFilteredMessageTests.m \
objectivec/Tests/GPBMessageTests+Merge.m \
objectivec/Tests/GPBMessageTests+Runtime.m \
objectivec/Tests/GPBMessageTests+Serialization.m \
objectivec/Tests/GPBMessageTests.m \
objectivec/Tests/GPBPerfTests.m \
objectivec/Tests/GPBStringTests.m \
objectivec/Tests/GPBSwiftTests.swift \
objectivec/Tests/GPBTestUtilities.h \
objectivec/Tests/GPBTestUtilities.m \
objectivec/Tests/GPBUnittestProtos.m \
objectivec/Tests/GPBUnknownFieldSetTest.m \
objectivec/Tests/GPBUtilitiesTests.m \
objectivec/Tests/GPBWellKnownTypesTest.m \
objectivec/Tests/GPBWireFormatTests.m \
objectivec/Tests/iOSTestHarness/AppDelegate.m \
objectivec/Tests/iOSTestHarness/en.lproj/InfoPlist.strings \
objectivec/Tests/iOSTestHarness/Images.xcassets/AppIcon.appiconset/Contents.json \
objectivec/Tests/iOSTestHarness/Images.xcassets/AppIcon.appiconset/iPad6.png \
objectivec/Tests/iOSTestHarness/Images.xcassets/AppIcon.appiconset/iPad6@2x.png \
objectivec/Tests/iOSTestHarness/Images.xcassets/AppIcon.appiconset/iPad7.png \
objectivec/Tests/iOSTestHarness/Images.xcassets/AppIcon.appiconset/iPad7@2x.png \
objectivec/Tests/iOSTestHarness/Images.xcassets/AppIcon.appiconset/iPhone6.png \
objectivec/Tests/iOSTestHarness/Images.xcassets/AppIcon.appiconset/iPhone6@2x.png \
objectivec/Tests/iOSTestHarness/Images.xcassets/AppIcon.appiconset/iPhone7@2x.png \
objectivec/Tests/iOSTestHarness/Images.xcassets/AppIcon.appiconset/iPhone7@3x.png \
objectivec/Tests/iOSTestHarness/Images.xcassets/LaunchImage.launchimage/Contents.json \
objectivec/Tests/iOSTestHarness/Info.plist \
objectivec/Tests/iOSTestHarness/LaunchScreen.xib \
objectivec/Tests/text_format_map_unittest_data.txt \
objectivec/Tests/text_format_unittest_data.txt \
objectivec/Tests/unittest_cycle.proto \
objectivec/Tests/unittest_filter.proto \
objectivec/Tests/unittest_name_mangling.proto \
objectivec/Tests/unittest_objc.proto \
objectivec/Tests/unittest_runtime_proto2.proto \
objectivec/Tests/unittest_runtime_proto3.proto \
objectivec/Tests/UnitTests-Bridging-Header.h \
objectivec/Tests/UnitTests-Info.plist
python_EXTRA_DIST= \
python/google/protobuf/internal/api_implementation.cc \
@ -301,7 +423,7 @@ ruby_EXTRA_DIST= \
ruby/tests/generated_code.rb \
ruby/tests/generated_code_test.rb
all_EXTRA_DIST=$(java_EXTRA_DIST) $(javanano_EXTRA_DIST) $(python_EXTRA_DIST) $(ruby_EXTRA_DIST)
all_EXTRA_DIST=$(java_EXTRA_DIST) $(javanano_EXTRA_DIST) $(objectivec_EXTRA_DIST) $(python_EXTRA_DIST) $(ruby_EXTRA_DIST)
EXTRA_DIST = $(@DIST_LANG@_EXTRA_DIST) \
autogen.sh \

@ -0,0 +1,120 @@
import com.google.protobuf.conformance.Conformance;
import com.google.protobuf.InvalidProtocolBufferException;
class ConformanceJava {
private int testCount = 0;
private boolean readFromStdin(byte[] buf, int len) throws Exception {
int ofs = 0;
while (len > 0) {
int read = System.in.read(buf, ofs, len);
if (read == -1) {
return false; // EOF
}
ofs += read;
len -= read;
}
return true;
}
private void writeToStdout(byte[] buf) throws Exception {
System.out.write(buf);
}
// Returns -1 on EOF (the actual values will always be positive).
private int readLittleEndianIntFromStdin() throws Exception {
byte[] buf = new byte[4];
if (!readFromStdin(buf, 4)) {
return -1;
}
return buf[0] | (buf[1] << 1) | (buf[2] << 2) | (buf[3] << 3);
}
private void writeLittleEndianIntToStdout(int val) throws Exception {
byte[] buf = new byte[4];
buf[0] = (byte)val;
buf[1] = (byte)(val >> 8);
buf[2] = (byte)(val >> 16);
buf[3] = (byte)(val >> 24);
writeToStdout(buf);
}
private Conformance.ConformanceResponse doTest(Conformance.ConformanceRequest request) {
Conformance.TestAllTypes testMessage;
switch (request.getPayloadCase()) {
case PROTOBUF_PAYLOAD: {
try {
testMessage = Conformance.TestAllTypes.parseFrom(request.getProtobufPayload());
} catch (InvalidProtocolBufferException e) {
return Conformance.ConformanceResponse.newBuilder().setParseError(e.getMessage()).build();
}
break;
}
case JSON_PAYLOAD: {
return Conformance.ConformanceResponse.newBuilder().setRuntimeError("JSON not yet supported.").build();
}
case PAYLOAD_NOT_SET: {
throw new RuntimeException("Request didn't have payload.");
}
default: {
throw new RuntimeException("Unexpected payload case.");
}
}
switch (request.getRequestedOutput()) {
case UNSPECIFIED:
throw new RuntimeException("Unspecified output format.");
case PROTOBUF:
return Conformance.ConformanceResponse.newBuilder().setProtobufPayload(testMessage.toByteString()).build();
case JSON:
return Conformance.ConformanceResponse.newBuilder().setRuntimeError("JSON not yet supported.").build();
default: {
throw new RuntimeException("Unexpected request output.");
}
}
}
private boolean doTestIo() throws Exception {
int bytes = readLittleEndianIntFromStdin();
if (bytes == -1) {
return false; // EOF
}
byte[] serializedInput = new byte[bytes];
if (!readFromStdin(serializedInput, bytes)) {
throw new RuntimeException("Unexpected EOF from test program.");
}
Conformance.ConformanceRequest request =
Conformance.ConformanceRequest.parseFrom(serializedInput);
Conformance.ConformanceResponse response = doTest(request);
byte[] serializedOutput = response.toByteArray();
writeLittleEndianIntToStdout(serializedOutput.length);
writeToStdout(serializedOutput);
return true;
}
public void run() throws Exception {
while (doTestIo()) {
// Empty.
}
System.err.println("ConformanceJava: received EOF from test runner after " +
this.testCount + " tests");
}
public static void main(String[] args) throws Exception {
new ConformanceJava().run();
}
}

@ -21,30 +21,43 @@ conformance_cpp_CPPFLAGS = -I$(top_srcdir)/src
if USE_EXTERNAL_PROTOC
unittest_proto_middleman: $(protoc_inputs)
$(PROTOC) -I$(srcdir) --cpp_out=. $^
touch unittest_proto_middleman
protoc_middleman: $(protoc_inputs)
$(PROTOC) -I$(srcdir) --cpp_out=. --java_out=. $^
touch protoc_middleman
else
# We have to cd to $(srcdir) before executing protoc because $(protoc_inputs) is
# relative to srcdir, which may not be the same as the current directory when
# building out-of-tree.
unittest_proto_middleman: $(top_srcdir)/src/protoc$(EXEEXT) $(protoc_inputs)
oldpwd=`pwd` && ( cd $(srcdir) && $$oldpwd/../src/protoc$(EXEEXT) -I. --cpp_out=$$oldpwd $(protoc_inputs) )
touch unittest_proto_middleman
protoc_middleman: $(top_srcdir)/src/protoc$(EXEEXT) $(protoc_inputs)
oldpwd=`pwd` && ( cd $(srcdir) && $$oldpwd/../src/protoc$(EXEEXT) -I. --cpp_out=$$oldpwd --java_out=$$oldpwd $(protoc_inputs) )
touch protoc_middleman
endif
$(protoc_outputs): unittest_proto_middleman
$(protoc_outputs): protoc_middleman
BUILT_SOURCES = $(protoc_outputs)
CLEANFILES = $(protoc_outputs) unittest_proto_middleman
CLEANFILES = $(protoc_outputs) protoc_middleman javac_middleman conformance-java
MAINTAINERCLEANFILES = \
Makefile.in
javac_middleman: ConformanceJava.java protoc_middleman
javac -classpath ../java/target/classes ConformanceJava.java com/google/protobuf/conformance/Conformance.java
@touch javac_middleman
conformance-java: javac_middleman
@echo "Writing shortcut script conformance-java..."
@echo '#! /bin/sh' > conformance-java
@echo 'java -classpath .:../java/target/classes ConformanceJava "$$@"' >> conformance-java
@chmod +x conformance-java
# Targets for actually running tests.
test_cpp: unittest_proto_middleman conformance-test-runner conformance-cpp
test_cpp: protoc_middleman conformance-test-runner conformance-cpp
./conformance-test-runner ./conformance-cpp
test_java: protoc_middleman conformance-test-runner conformance-java
./conformance-test-runner ./conformance-java

@ -30,6 +30,7 @@
syntax = "proto3";
package conformance;
option java_package = "com.google.protobuf.conformance";
// This defines the conformance testing protocol. This protocol exists between
// the conformance test suite itself and the code being tested. For each test,

@ -48,9 +48,9 @@
// Every test consists of a ConformanceRequest/ConformanceResponse
// request/reply pair. The protocol on the pipe is simply:
//
// 1. tester sends 4-byte length N
// 1. tester sends 4-byte length N (little endian)
// 2. tester sends N bytes representing a ConformanceRequest proto
// 3. testee sends 4-byte length M
// 3. testee sends 4-byte length M (little endian)
// 4. testee sends M bytes representing a ConformanceResponse proto
#include <errno.h>

@ -40,8 +40,8 @@ namespace Google.ProtocolBuffers.TestProtos {
"X3ZhbHVlGAIgASgOMjsudW5pdHRlc3RfZHJvcF91bmtub3duX2ZpZWxkcy5G",
"b29XaXRoRXh0cmFGaWVsZHMuTmVzdGVkRW51bRIZChFleHRyYV9pbnQzMl92",
"YWx1ZRgDIAEoBSIwCgpOZXN0ZWRFbnVtEgcKA0ZPTxAAEgcKA0JBUhABEgcK",
"A0JBWhACEgcKA1FVWBADQiSqAiFHb29nbGUuUHJvdG9jb2xCdWZmZXJzLlRl",
"c3RQcm90b3NiBnByb3RvMw=="));
"A0JBWhACEgcKA1FVWBADQjOiAgxEcm9wVW5rbm93bnOqAiFHb29nbGUuUHJv",
"dG9jb2xCdWZmZXJzLlRlc3RQcm90b3NiBnByb3RvMw=="));
pbd::FileDescriptor.InternalDescriptorAssigner assigner = delegate(pbd::FileDescriptor root) {
descriptor = root;
internal__static_unittest_drop_unknown_fields_Foo__Descriptor = Descriptor.MessageTypes[0];

@ -1,4 +1,4 @@
#! /usr/bin/python
#! /usr/bin/env python
# See README.txt for information and build instructions.

@ -1,4 +1,4 @@
#! /usr/bin/python
#! /usr/bin/env python
# See README.txt for information and build instructions.

@ -27,6 +27,7 @@ __EOF__
fi
cd src
make $@ google/protobuf/stubs/pbconfig.h
CORE_PROTO_IS_CORRECT=0
while [ $CORE_PROTO_IS_CORRECT -ne 1 ]
do

@ -145,6 +145,7 @@ optional_field_style -> default or accessors
enum_style -> c or java
ignore_services -> true or false
parcelable_messages -> true or false
generate_intdefs -> true or false
```
**java_package=\<file-name\>|\<package-name\>** (no default)
@ -302,6 +303,28 @@ parcelable_messages -> true or false
Android-specific option to generate Parcelable messages.
**generate_intdefs={true,false}** (default: false)
Android-specific option to generate @IntDef annotations for enums.
If turned on, an '@IntDef' annotation (a public @interface) will be
generated for each enum, and every integer parameter and return
value in the generated code meant for this enum will be annotated
with it. This interface is generated with the same name and at the
same place as the enum members' container interfaces described
above under 'enum_style=java', regardless of the enum_style option
used. When this is combined with enum_style=java, the interface
will be both the '@IntDef' annotation and the container of the enum
members; otherwise the interface has an empty body.
Your app must declare a compile-time dependency on the
android-support-annotations library.
For more information on how these @IntDef annotations help with
compile-time type safety, see:
https://sites.google.com/a/android.com/tools/tech-docs/support-annotations
and
https://developer.android.com/reference/android/support/annotation/IntDef.html
To use nano protobufs within the Android repo:
----------------------------------------------

@ -97,19 +97,19 @@
<arg value="src/test/java/com/google/protobuf/nano/map_test.proto" />
</exec>
<exec executable="../src/protoc">
<arg value="--javanano_out=store_unknown_fields=true,generate_equals=true:target/generated-test-sources" />
<arg value="--javanano_out=store_unknown_fields=true,generate_equals=true,generate_clone=true:target/generated-test-sources" />
<arg value="--proto_path=src/test/java/com" />
<arg value="src/test/java/com/google/protobuf/nano/unittest_extension_nano.proto" />
<arg value="src/test/java/com/google/protobuf/nano/unittest_extension_singular_nano.proto" />
<arg value="src/test/java/com/google/protobuf/nano/unittest_extension_repeated_nano.proto" />
</exec>
<exec executable="../src/protoc">
<arg value="--javanano_out=store_unknown_fields=true:target/generated-test-sources" />
<arg value="--javanano_out=store_unknown_fields=true,generate_clone=true:target/generated-test-sources" />
<arg value="--proto_path=src/test/java/com" />
<arg value="src/test/java/com/google/protobuf/nano/unittest_extension_packed_nano.proto" />
</exec>
<exec executable="../src/protoc">
<arg value="--javanano_out=java_nano_generate_has=true,generate_equals=true:target/generated-test-sources" />
<arg value="--javanano_out=java_nano_generate_has=true,generate_equals=true,generate_clone=true:target/generated-test-sources" />
<arg value="--proto_path=src/test/java/com" />
<arg value="src/test/java/com/google/protobuf/nano/unittest_has_nano.proto" />
</exec>
@ -139,6 +139,15 @@
<arg value="--proto_path=src/test/java/com" />
<arg value="src/test/java/com/google/protobuf/nano/unittest_reference_types_nano.proto" />
</exec>
<exec executable="../src/protoc">
<arg value="--javanano_out=
optional_field_style=reftypes_compat_mode,
generate_equals=true,
java_outer_classname=google/protobuf/nano/unittest_reference_types_nano.proto|NanoReferenceTypesCompat
:target/generated-test-sources" />
<arg value="--proto_path=src/test/java/com" />
<arg value="src/test/java/com/google/protobuf/nano/unittest_reference_types_nano.proto" />
</exec>
</tasks>
<testSourceRoot>target/generated-test-sources</testSourceRoot>
</configuration>

@ -236,6 +236,8 @@ public final class CodedInputByteBufferNano {
System.arraycopy(buffer, bufferPos, result, 0, size);
bufferPos += size;
return result;
} else if (size == 0) {
return WireFormatNano.EMPTY_BYTES;
} else {
// Slow path: Build a byte array first then copy it.
return readRawBytes(size);

@ -31,6 +31,9 @@
package com.google.protobuf.nano;
import java.io.IOException;
import java.nio.BufferOverflowException;
import java.nio.ByteBuffer;
import java.nio.ReadOnlyBufferException;
/**
* Encodes and writes protocol message fields.
@ -47,15 +50,17 @@ import java.io.IOException;
* @author kneton@google.com Kenton Varda
*/
public final class CodedOutputByteBufferNano {
private final byte[] buffer;
private final int limit;
private int position;
/* max bytes per java UTF-16 char in UTF-8 */
private static final int MAX_UTF8_EXPANSION = 3;
private final ByteBuffer buffer;
private CodedOutputByteBufferNano(final byte[] buffer, final int offset,
final int length) {
this(ByteBuffer.wrap(buffer, offset, length));
}
private CodedOutputByteBufferNano(final ByteBuffer buffer) {
this.buffer = buffer;
position = offset;
limit = offset + length;
}
/**
@ -287,14 +292,213 @@ public final class CodedOutputByteBufferNano {
/** Write a {@code string} field to the stream. */
public void writeStringNoTag(final String value) throws IOException {
// Unfortunately there does not appear to be any way to tell Java to encode
// UTF-8 directly into our buffer, so we have to let it create its own byte
// array and then copy.
final byte[] bytes = value.getBytes(InternalNano.UTF_8);
writeRawVarint32(bytes.length);
writeRawBytes(bytes);
// UTF-8 byte length of the string is at least its UTF-16 code unit length (value.length()),
// and at most 3 times of it. Optimize for the case where we know this length results in a
// constant varint length - saves measuring length of the string.
try {
final int minLengthVarIntSize = computeRawVarint32Size(value.length());
final int maxLengthVarIntSize = computeRawVarint32Size(value.length() * MAX_UTF8_EXPANSION);
if (minLengthVarIntSize == maxLengthVarIntSize) {
int oldPosition = buffer.position();
// Buffer.position, when passed a position that is past its limit, throws
// IllegalArgumentException, and this class is documented to throw
// OutOfSpaceException instead.
if (buffer.remaining() < minLengthVarIntSize) {
throw new OutOfSpaceException(oldPosition + minLengthVarIntSize, buffer.limit());
}
buffer.position(oldPosition + minLengthVarIntSize);
encode(value, buffer);
int newPosition = buffer.position();
buffer.position(oldPosition);
writeRawVarint32(newPosition - oldPosition - minLengthVarIntSize);
buffer.position(newPosition);
} else {
writeRawVarint32(encodedLength(value));
encode(value, buffer);
}
} catch (BufferOverflowException e) {
final OutOfSpaceException outOfSpaceException = new OutOfSpaceException(buffer.position(),
buffer.limit());
outOfSpaceException.initCause(e);
throw outOfSpaceException;
}
}
// These UTF-8 handling methods are copied from Guava's Utf8 class.
/**
* Returns the number of bytes in the UTF-8-encoded form of {@code sequence}. For a string,
* this method is equivalent to {@code string.getBytes(UTF_8).length}, but is more efficient in
* both time and space.
*
* @throws IllegalArgumentException if {@code sequence} contains ill-formed UTF-16 (unpaired
* surrogates)
*/
private static int encodedLength(CharSequence sequence) {
// Warning to maintainers: this implementation is highly optimized.
int utf16Length = sequence.length();
int utf8Length = utf16Length;
int i = 0;
// This loop optimizes for pure ASCII.
while (i < utf16Length && sequence.charAt(i) < 0x80) {
i++;
}
// This loop optimizes for chars less than 0x800.
for (; i < utf16Length; i++) {
char c = sequence.charAt(i);
if (c < 0x800) {
utf8Length += ((0x7f - c) >>> 31); // branch free!
} else {
utf8Length += encodedLengthGeneral(sequence, i);
break;
}
}
if (utf8Length < utf16Length) {
// Necessary and sufficient condition for overflow because of maximum 3x expansion
throw new IllegalArgumentException("UTF-8 length does not fit in int: "
+ (utf8Length + (1L << 32)));
}
return utf8Length;
}
private static int encodedLengthGeneral(CharSequence sequence, int start) {
int utf16Length = sequence.length();
int utf8Length = 0;
for (int i = start; i < utf16Length; i++) {
char c = sequence.charAt(i);
if (c < 0x800) {
utf8Length += (0x7f - c) >>> 31; // branch free!
} else {
utf8Length += 2;
// jdk7+: if (Character.isSurrogate(c)) {
if (Character.MIN_SURROGATE <= c && c <= Character.MAX_SURROGATE) {
// Check that we have a well-formed surrogate pair.
int cp = Character.codePointAt(sequence, i);
if (cp < Character.MIN_SUPPLEMENTARY_CODE_POINT) {
throw new IllegalArgumentException("Unpaired surrogate at index " + i);
}
i++;
}
}
}
return utf8Length;
}
/**
* Encodes {@code sequence} into UTF-8, in {@code byteBuffer}. For a string, this method is
* equivalent to {@code buffer.put(string.getBytes(UTF_8))}, but is more efficient in both time
* and space. Bytes are written starting at the current position. This method requires paired
* surrogates, and therefore does not support chunking.
*
* <p>To ensure sufficient space in the output buffer, either call {@link #encodedLength} to
* compute the exact amount needed, or leave room for {@code 3 * sequence.length()}, which is the
* largest possible number of bytes that any input can be encoded to.
*
* @throws IllegalArgumentException if {@code sequence} contains ill-formed UTF-16 (unpaired
* surrogates)
* @throws BufferOverflowException if {@code sequence} encoded in UTF-8 does not fit in
* {@code byteBuffer}'s remaining space.
* @throws ReadOnlyBufferException if {@code byteBuffer} is a read-only buffer.
*/
private static void encode(CharSequence sequence, ByteBuffer byteBuffer) {
if (byteBuffer.isReadOnly()) {
throw new ReadOnlyBufferException();
} else if (byteBuffer.hasArray()) {
try {
int encoded = encode(sequence,
byteBuffer.array(),
byteBuffer.arrayOffset() + byteBuffer.position(),
byteBuffer.remaining());
byteBuffer.position(encoded - byteBuffer.arrayOffset());
} catch (ArrayIndexOutOfBoundsException e) {
BufferOverflowException boe = new BufferOverflowException();
boe.initCause(e);
throw boe;
}
} else {
encodeDirect(sequence, byteBuffer);
}
}
private static void encodeDirect(CharSequence sequence, ByteBuffer byteBuffer) {
int utf16Length = sequence.length();
for (int i = 0; i < utf16Length; i++) {
final char c = sequence.charAt(i);
if (c < 0x80) { // ASCII
byteBuffer.put((byte) c);
} else if (c < 0x800) { // 11 bits, two UTF-8 bytes
byteBuffer.put((byte) ((0xF << 6) | (c >>> 6)));
byteBuffer.put((byte) (0x80 | (0x3F & c)));
} else if (c < Character.MIN_SURROGATE || Character.MAX_SURROGATE < c) {
// Maximium single-char code point is 0xFFFF, 16 bits, three UTF-8 bytes
byteBuffer.put((byte) ((0xF << 5) | (c >>> 12)));
byteBuffer.put((byte) (0x80 | (0x3F & (c >>> 6))));
byteBuffer.put((byte) (0x80 | (0x3F & c)));
} else {
final char low;
if (i + 1 == sequence.length()
|| !Character.isSurrogatePair(c, (low = sequence.charAt(++i)))) {
throw new IllegalArgumentException("Unpaired surrogate at index " + (i - 1));
}
int codePoint = Character.toCodePoint(c, low);
byteBuffer.put((byte) ((0xF << 4) | (codePoint >>> 18)));
byteBuffer.put((byte) (0x80 | (0x3F & (codePoint >>> 12))));
byteBuffer.put((byte) (0x80 | (0x3F & (codePoint >>> 6))));
byteBuffer.put((byte) (0x80 | (0x3F & codePoint)));
}
}
}
private static int encode(CharSequence sequence, byte[] bytes, int offset, int length) {
int utf16Length = sequence.length();
int j = offset;
int i = 0;
int limit = offset + length;
// Designed to take advantage of
// https://wikis.oracle.com/display/HotSpotInternals/RangeCheckElimination
for (char c; i < utf16Length && i + j < limit && (c = sequence.charAt(i)) < 0x80; i++) {
bytes[j + i] = (byte) c;
}
if (i == utf16Length) {
return j + utf16Length;
}
j += i;
for (char c; i < utf16Length; i++) {
c = sequence.charAt(i);
if (c < 0x80 && j < limit) {
bytes[j++] = (byte) c;
} else if (c < 0x800 && j <= limit - 2) { // 11 bits, two UTF-8 bytes
bytes[j++] = (byte) ((0xF << 6) | (c >>> 6));
bytes[j++] = (byte) (0x80 | (0x3F & c));
} else if ((c < Character.MIN_SURROGATE || Character.MAX_SURROGATE < c) && j <= limit - 3) {
// Maximum single-char code point is 0xFFFF, 16 bits, three UTF-8 bytes
bytes[j++] = (byte) ((0xF << 5) | (c >>> 12));
bytes[j++] = (byte) (0x80 | (0x3F & (c >>> 6)));
bytes[j++] = (byte) (0x80 | (0x3F & c));
} else if (j <= limit - 4) {
// Minimum code point represented by a surrogate pair is 0x10000, 17 bits, four UTF-8 bytes
final char low;
if (i + 1 == sequence.length()
|| !Character.isSurrogatePair(c, (low = sequence.charAt(++i)))) {
throw new IllegalArgumentException("Unpaired surrogate at index " + (i - 1));
}
int codePoint = Character.toCodePoint(c, low);
bytes[j++] = (byte) ((0xF << 4) | (codePoint >>> 18));
bytes[j++] = (byte) (0x80 | (0x3F & (codePoint >>> 12)));
bytes[j++] = (byte) (0x80 | (0x3F & (codePoint >>> 6)));
bytes[j++] = (byte) (0x80 | (0x3F & codePoint));
} else {
throw new ArrayIndexOutOfBoundsException("Failed writing " + c + " at index " + j);
}
}
return j;
}
// End guava UTF-8 methods
/** Write a {@code group} field to the stream. */
public void writeGroupNoTag(final MessageNano value) throws IOException {
value.writeTo(this);
@ -602,9 +806,8 @@ public final class CodedOutputByteBufferNano {
* {@code string} field.
*/
public static int computeStringSizeNoTag(final String value) {
final byte[] bytes = value.getBytes(InternalNano.UTF_8);
return computeRawVarint32Size(bytes.length) +
bytes.length;
final int length = encodedLength(value);
return computeRawVarint32Size(length) + length;
}
/**
@ -687,7 +890,7 @@ public final class CodedOutputByteBufferNano {
* Otherwise, throws {@code UnsupportedOperationException}.
*/
public int spaceLeft() {
return limit - position;
return buffer.remaining();
}
/**
@ -704,6 +907,23 @@ public final class CodedOutputByteBufferNano {
}
}
/**
* Returns the position within the internal buffer.
*/
public int position() {
return buffer.position();
}
/**
* Resets the position within the internal buffer to zero.
*
* @see #position
* @see #spaceLeft
*/
public void reset() {
buffer.clear();
}
/**
* If you create a CodedOutputStream around a simple flat array, you must
* not attempt to write more bytes than the array has space. Otherwise,
@ -720,12 +940,12 @@ public final class CodedOutputByteBufferNano {
/** Write a single byte. */
public void writeRawByte(final byte value) throws IOException {
if (position == limit) {
if (!buffer.hasRemaining()) {
// We're writing to a single buffer.
throw new OutOfSpaceException(position, limit);
throw new OutOfSpaceException(buffer.position(), buffer.limit());
}
buffer[position++] = value;
buffer.put(value);
}
/** Write a single byte, represented by an integer value. */
@ -741,13 +961,11 @@ public final class CodedOutputByteBufferNano {
/** Write part of an array of bytes. */
public void writeRawBytes(final byte[] value, int offset, int length)
throws IOException {
if (limit - position >= length) {
// We have room in the current buffer.
System.arraycopy(value, offset, buffer, position, length);
position += length;
if (buffer.remaining() >= length) {
buffer.put(value, offset, length);
} else {
// We're writing to a single buffer.
throw new OutOfSpaceException(position, limit);
throw new OutOfSpaceException(buffer.position(), buffer.limit());
}
}

@ -160,28 +160,10 @@ public abstract class ExtendableMessageNano<M extends ExtendableMessageNano<M>>
return true;
}
/**
* Returns whether the stored unknown field data in this message is equivalent to that in the
* other message.
*
* @param other the other message.
* @return whether the two sets of unknown field data are equal.
*/
protected final boolean unknownFieldDataEquals(M other) {
if (unknownFieldData == null || unknownFieldData.isEmpty()) {
return other.unknownFieldData == null || other.unknownFieldData.isEmpty();
} else {
return unknownFieldData.equals(other.unknownFieldData);
}
}
/**
* Computes the hashcode representing the unknown field data stored in this message.
*
* @return the hashcode for the unknown field data.
*/
protected final int unknownFieldDataHashCode() {
return (unknownFieldData == null || unknownFieldData.isEmpty()
? 0 : unknownFieldData.hashCode());
@Override
public M clone() throws CloneNotSupportedException {
M cloned = (M) super.clone();
InternalNano.cloneUnknownFieldData(this, cloned);
return cloned;
}
}

@ -79,12 +79,30 @@ public class Extension<M extends ExtendableMessageNano<M>, T> {
* Should be used by the generated code only.
*
* @param type {@link #TYPE_MESSAGE} or {@link #TYPE_GROUP}
* @deprecated use {@link #createMessageTyped(int, Class, long)} instead.
*/
@Deprecated
public static <M extends ExtendableMessageNano<M>, T extends MessageNano>
Extension<M, T> createMessageTyped(int type, Class<T> clazz, int tag) {
return new Extension<M, T>(type, clazz, tag, false);
}
// Note: these create...() methods take a long for the tag parameter,
// because tags are represented as unsigned ints, and these values exist
// in generated code as long values. However, they can fit in 32-bits, so
// it's safe to cast them to int without loss of precision.
/**
* Creates an {@code Extension} of the given message type and tag number.
* Should be used by the generated code only.
*
* @param type {@link #TYPE_MESSAGE} or {@link #TYPE_GROUP}
*/
public static <M extends ExtendableMessageNano<M>, T extends MessageNano>
Extension<M, T> createMessageTyped(int type, Class<T> clazz, long tag) {
return new Extension<M, T>(type, clazz, (int) tag, false);
}
/**
* Creates a repeated {@code Extension} of the given message type and tag number.
* Should be used by the generated code only.
@ -92,8 +110,8 @@ public class Extension<M extends ExtendableMessageNano<M>, T> {
* @param type {@link #TYPE_MESSAGE} or {@link #TYPE_GROUP}
*/
public static <M extends ExtendableMessageNano<M>, T extends MessageNano>
Extension<M, T[]> createRepeatedMessageTyped(int type, Class<T[]> clazz, int tag) {
return new Extension<M, T[]>(type, clazz, tag, true);
Extension<M, T[]> createRepeatedMessageTyped(int type, Class<T[]> clazz, long tag) {
return new Extension<M, T[]>(type, clazz, (int) tag, true);
}
/**
@ -104,8 +122,8 @@ public class Extension<M extends ExtendableMessageNano<M>, T> {
* @param clazz the boxed Java type of this extension
*/
public static <M extends ExtendableMessageNano<M>, T>
Extension<M, T> createPrimitiveTyped(int type, Class<T> clazz, int tag) {
return new PrimitiveExtension<M, T>(type, clazz, tag, false, 0, 0);
Extension<M, T> createPrimitiveTyped(int type, Class<T> clazz, long tag) {
return new PrimitiveExtension<M, T>(type, clazz, (int) tag, false, 0, 0);
}
/**
@ -117,8 +135,9 @@ public class Extension<M extends ExtendableMessageNano<M>, T> {
*/
public static <M extends ExtendableMessageNano<M>, T>
Extension<M, T> createRepeatedPrimitiveTyped(
int type, Class<T> clazz, int tag, int nonPackedTag, int packedTag) {
return new PrimitiveExtension<M, T>(type, clazz, tag, true, nonPackedTag, packedTag);
int type, Class<T> clazz, long tag, long nonPackedTag, long packedTag) {
return new PrimitiveExtension<M, T>(type, clazz, (int) tag, true,
(int) nonPackedTag, (int) packedTag);
}
/**
@ -136,7 +155,7 @@ public class Extension<M extends ExtendableMessageNano<M>, T> {
protected final Class<T> clazz;
/**
* Tag number of this extension.
* Tag number of this extension. The data should be viewed as an unsigned 32-bit value.
*/
public final int tag;

@ -35,9 +35,12 @@ package com.google.protobuf.nano;
* A custom version of {@link android.util.SparseArray} with the minimal API
* for storing {@link FieldData} objects.
*
* <p>This class is an internal implementation detail of nano and should not
* be called directly by clients.
*
* Based on {@link android.support.v4.util.SpareArrayCompat}.
*/
class FieldArray {
public final class FieldArray implements Cloneable {
private static final FieldData DELETED = new FieldData();
private boolean mGarbage = false;
@ -48,7 +51,7 @@ class FieldArray {
/**
* Creates a new FieldArray containing no fields.
*/
public FieldArray() {
FieldArray() {
this(10);
}
@ -57,7 +60,7 @@ class FieldArray {
* require any additional memory allocation to store the specified
* number of mappings.
*/
public FieldArray(int initialCapacity) {
FieldArray(int initialCapacity) {
initialCapacity = idealIntArraySize(initialCapacity);
mFieldNumbers = new int[initialCapacity];
mData = new FieldData[initialCapacity];
@ -68,7 +71,7 @@ class FieldArray {
* Gets the FieldData mapped from the specified fieldNumber, or <code>null</code>
* if no such mapping has been made.
*/
public FieldData get(int fieldNumber) {
FieldData get(int fieldNumber) {
int i = binarySearch(fieldNumber);
if (i < 0 || mData[i] == DELETED) {
@ -81,7 +84,7 @@ class FieldArray {
/**
* Removes the data from the specified fieldNumber, if there was any.
*/
public void remove(int fieldNumber) {
void remove(int fieldNumber) {
int i = binarySearch(fieldNumber);
if (i >= 0 && mData[i] != DELETED) {
@ -118,7 +121,7 @@ class FieldArray {
* Adds a mapping from the specified fieldNumber to the specified data,
* replacing the previous mapping if there was one.
*/
public void put(int fieldNumber, FieldData data) {
void put(int fieldNumber, FieldData data) {
int i = binarySearch(fieldNumber);
if (i >= 0) {
@ -167,7 +170,7 @@ class FieldArray {
* Returns the number of key-value mappings that this FieldArray
* currently stores.
*/
public int size() {
int size() {
if (mGarbage) {
gc();
}
@ -184,7 +187,7 @@ class FieldArray {
* the value from the <code>index</code>th key-value mapping that this
* FieldArray stores.
*/
public FieldData dataAt(int index) {
FieldData dataAt(int index) {
if (mGarbage) {
gc();
}
@ -270,4 +273,19 @@ class FieldArray {
}
return true;
}
@Override
public final FieldArray clone() {
// Trigger GC so we compact and don't copy DELETED elements.
int size = size();
FieldArray clone = new FieldArray(size);
System.arraycopy(mFieldNumbers, 0, clone.mFieldNumbers, 0, size);
for (int i = 0; i < size; i++) {
if (mData[i] != null) {
clone.mData[i] = mData[i].clone();
}
}
clone.mSize = size;
return clone;
}
}

@ -39,7 +39,7 @@ import java.util.List;
* Stores unknown fields. These might be extensions or fields that the generated API doesn't
* know about yet.
*/
class FieldData {
class FieldData implements Cloneable {
private Extension<?, ?> cachedExtension;
private Object value;
/** The serialised values for this object. Will be cleared if getValue is called */
@ -187,4 +187,54 @@ class FieldData {
return result;
}
@Override
public final FieldData clone() {
FieldData clone = new FieldData();
try {
clone.cachedExtension = cachedExtension;
if (unknownFieldData == null) {
clone.unknownFieldData = null;
} else {
clone.unknownFieldData.addAll(unknownFieldData);
}
// Whether we need to deep clone value depends on its type. Primitive reference types
// (e.g. Integer, Long etc.) are ok, since they're immutable. We need to clone arrays
// and messages.
if (value == null) {
// No cloning required.
} else if (value instanceof MessageNano) {
clone.value = ((MessageNano) value).clone();
} else if (value instanceof byte[]) {
clone.value = ((byte[]) value).clone();
} else if (value instanceof byte[][]) {
byte[][] valueArray = (byte[][]) value;
byte[][] cloneArray = new byte[valueArray.length][];
clone.value = cloneArray;
for (int i = 0; i < valueArray.length; i++) {
cloneArray[i] = valueArray[i].clone();
}
} else if (value instanceof boolean[]) {
clone.value = ((boolean[]) value).clone();
} else if (value instanceof int[]) {
clone.value = ((int[]) value).clone();
} else if (value instanceof long[]) {
clone.value = ((long[]) value).clone();
} else if (value instanceof float[]) {
clone.value = ((float[]) value).clone();
} else if (value instanceof double[]) {
clone.value = ((double[]) value).clone();
} else if (value instanceof MessageNano[]) {
MessageNano[] valueArray = (MessageNano[]) value;
MessageNano[] cloneArray = new MessageNano[valueArray.length];
clone.value = cloneArray;
for (int i = 0; i < valueArray.length; i++) {
cloneArray[i] = valueArray[i].clone();
}
}
return clone;
} catch (CloneNotSupportedException e) {
throw new AssertionError(e);
}
}
}

@ -536,4 +536,12 @@ public final class InternalNano {
}
return o.hashCode();
}
// This avoids having to make FieldArray public.
public static void cloneUnknownFieldData(ExtendableMessageNano original,
ExtendableMessageNano cloned) {
if (original.unknownFieldData != null) {
cloned.unknownFieldData = (FieldArray) original.unknownFieldData.clone();
}
}
}

@ -187,4 +187,12 @@ public abstract class MessageNano {
public String toString() {
return MessageNanoPrinter.print(this);
}
/**
* Provides support for cloning. This only works if you specify the generate_clone method.
*/
@Override
public MessageNano clone() throws CloneNotSupportedException {
return (MessageNano) super.clone();
}
}

@ -109,6 +109,10 @@ public final class MessageNanoPrinter {
for (Field field : clazz.getFields()) {
int modifiers = field.getModifiers();
String fieldName = field.getName();
if ("cachedSize".equals(fieldName)) {
// TODO(bduff): perhaps cachedSize should have a more obscure name.
continue;
}
if ((modifiers & Modifier.PUBLIC) == Modifier.PUBLIC
&& (modifiers & Modifier.STATIC) != Modifier.STATIC

@ -42,6 +42,10 @@ import java.util.Arrays;
final class UnknownFieldData {
final int tag;
/**
* Important: this should be treated as immutable, even though it's possible
* to change the array values.
*/
final byte[] bytes;
UnknownFieldData(int tag, byte[] bytes) {

@ -31,11 +31,13 @@
package com.google.protobuf.nano;
import com.google.protobuf.nano.MapTestProto.TestMap;
import com.google.protobuf.nano.CodedOutputByteBufferNano;
import com.google.protobuf.nano.MapTestProto.TestMap.MessageValue;
import com.google.protobuf.nano.NanoAccessorsOuterClass.TestNanoAccessors;
import com.google.protobuf.nano.NanoHasOuterClass.TestAllTypesNanoHas;
import com.google.protobuf.nano.NanoOuterClass.TestAllTypesNano;
import com.google.protobuf.nano.UnittestRecursiveNano.RecursiveMessageNano;
import com.google.protobuf.nano.NanoReferenceTypesCompat;
import com.google.protobuf.nano.UnittestSimpleNano.SimpleMessageNano;
import com.google.protobuf.nano.UnittestSingleNano.SingleMessageNano;
import com.google.protobuf.nano.testext.Extensions;
@ -2300,6 +2302,59 @@ public class NanoTest extends TestCase {
}
}
public void testDifferentStringLengthsNano() throws Exception {
// Test string serialization roundtrip using strings of the following lengths,
// with ASCII and Unicode characters requiring different UTF-8 byte counts per
// char, hence causing the length delimiter varint to sometimes require more
// bytes for the Unicode strings than the ASCII string of the same length.
int[] lengths = new int[] {
0,
1,
(1 << 4) - 1, // 1 byte for ASCII and Unicode
(1 << 7) - 1, // 1 byte for ASCII, 2 bytes for Unicode
(1 << 11) - 1, // 2 bytes for ASCII and Unicode
(1 << 14) - 1, // 2 bytes for ASCII, 3 bytes for Unicode
(1 << 17) - 1, // 3 bytes for ASCII and Unicode
};
for (int i : lengths) {
testEncodingOfString('q', i); // 1 byte per char
testEncodingOfString('\u07FF', i); // 2 bytes per char
testEncodingOfString('\u0981', i); // 3 bytes per char
}
}
/** Regression test for https://github.com/google/protobuf/issues/292 */
public void testCorrectExceptionThrowWhenEncodingStringsWithoutEnoughSpace() throws Exception {
String testCase = "Foooooooo";
assertEquals(CodedOutputByteBufferNano.computeRawVarint32Size(testCase.length()),
CodedOutputByteBufferNano.computeRawVarint32Size(testCase.length() * 3));
assertEquals(11, CodedOutputByteBufferNano.computeStringSize(1, testCase));
// Tag is one byte, varint describing string length is 1 byte, string length is 9 bytes.
// An array of size 1 will cause a failure when trying to write the varint.
for (int i = 0; i < 11; i++) {
CodedOutputByteBufferNano bufferNano = CodedOutputByteBufferNano.newInstance(new byte[i]);
try {
bufferNano.writeString(1, testCase);
fail("Should have thrown an out of space exception");
} catch (CodedOutputByteBufferNano.OutOfSpaceException expected) {}
}
}
private void testEncodingOfString(char c, int length) throws InvalidProtocolBufferNanoException {
TestAllTypesNano testAllTypesNano = new TestAllTypesNano();
final String fullString = fullString(c, length);
testAllTypesNano.optionalString = fullString;
final TestAllTypesNano resultNano = new TestAllTypesNano();
MessageNano.mergeFrom(resultNano, MessageNano.toByteArray(testAllTypesNano));
assertEquals(fullString, resultNano.optionalString);
}
private String fullString(char c, int length) {
char[] result = new char[length];
Arrays.fill(result, c);
return new String(result);
}
public void testNanoWithHasParseFrom() throws Exception {
TestAllTypesNanoHas msg = null;
// Test false on creation, after clear and upon empty parse.
@ -2986,6 +3041,10 @@ public class NanoTest extends TestCase {
assertTrue(Arrays.equals(floats, message.getExtension(RepeatedExtensions.repeatedFloat)));
assertTrue(Arrays.equals(doubles, message.getExtension(RepeatedExtensions.repeatedDouble)));
assertTrue(Arrays.equals(enums, message.getExtension(RepeatedExtensions.repeatedEnum)));
// Clone the message and ensure it's still equal.
Extensions.ExtendableMessage clone = message.clone();
assertEquals(clone, message);
}
public void testNullExtensions() throws Exception {
@ -4345,6 +4404,11 @@ public class NanoTest extends TestCase {
assertMapSet(testMap.sfixed64ToSfixed64Field, int64Values, int64Values);
}
public void testRepeatedFieldInitializedInReftypesCompatMode() {
NanoReferenceTypesCompat.TestAllTypesNano proto = new NanoReferenceTypesCompat.TestAllTypesNano();
assertNotNull(proto.repeatedString);
}
private void assertRepeatedPackablesEqual(
NanoRepeatedPackables.NonPacked nonPacked, NanoRepeatedPackables.Packed packed) {
// Not using MessageNano.equals() -- that belongs to a separate test.
@ -4364,6 +4428,22 @@ public class NanoTest extends TestCase {
assertTrue(Arrays.equals(nonPacked.enums, packed.enums));
}
public void testClone() throws Exception {
// A simple message.
AnotherMessage anotherMessage = new AnotherMessage();
anotherMessage.string = "Hello";
anotherMessage.value = true;
anotherMessage.integers = new int[] { 1, 2, 3 };
AnotherMessage clone = anotherMessage.clone();
assertEquals(clone, anotherMessage);
// Verify it was a deep clone - changes to the clone shouldn't affect the
// original.
clone.integers[1] = 100;
assertFalse(clone.equals(anotherMessage));
}
private void assertHasWireData(MessageNano message, boolean expected) {
byte[] bytes = MessageNano.toByteArray(message);
int wireLength = bytes.length;

@ -16,11 +16,15 @@ enum AnEnum {
message AnotherMessage {
optional string string = 1;
optional bool value = 2;
repeated int32 integers = 3;
}
message ContainerMessage {
extend ExtendableMessage {
optional bool another_thing = 100;
// The largest permitted field number, per
// https://developers.google.com/protocol-buffers/docs/proto#simple
optional bool large_field_number = 536870911;
}
}

@ -0,0 +1,56 @@
#!/bin/bash
# This script checks that the runtime version number constant in the compiler
# source and in the runtime source is the same.
#
# A distro can be made of the protobuf sources with only a subset of the
# languages, so if the compiler depended on the Objective C runtime, those
# builds would break. At the same time, we don't want the runtime source
# depending on the compiler sources; so two copies of the constant are needed.
set -eu
readonly ScriptDir=$(dirname "$(echo $0 | sed -e "s,^\([^/]\),$(pwd)/\1,")")
readonly ProtoRootDir="${ScriptDir}/../.."
die() {
echo "Error: $1"
exit 1
}
readonly ConstantName=GOOGLE_PROTOBUF_OBJC_GEN_VERSION
# Collect version from plugin sources.
readonly PluginSrc="${ProtoRootDir}/src/google/protobuf/compiler/objectivec/objectivec_file.cc"
readonly PluginVersion=$( \
cat "${PluginSrc}" \
| sed -n -e "s:const int32_t ${ConstantName} = \([0-9]*\);:\1:p"
)
if [[ -z "${PluginVersion}" ]] ; then
die "Failed to fine ${ConstantName} in the plugin source (${PluginSrc})."
fi
# Collect version from runtime sources.
readonly RuntimeSrc="${ProtoRootDir}/objectivec/GPBBootstrap.h"
readonly RuntimeVersion=$( \
cat "${RuntimeSrc}" \
| sed -n -e "s:#define ${ConstantName} \([0-9]*\):\1:p"
)
if [[ -z "${RuntimeVersion}" ]] ; then
die "Failed to fine ${ConstantName} in the runtime source (${RuntimeSrc})."
fi
# Compare them.
if [[ "${PluginVersion}" != "${RuntimeVersion}" ]] ; then
die "Versions don't match!
Plugin: ${PluginVersion} from ${PluginSrc}
Runtime: ${RuntimeVersion} from ${RuntimeSrc}
"
fi
# Success

@ -0,0 +1,36 @@
#!/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

@ -0,0 +1,687 @@
#! /usr/bin/python
#
# Protocol Buffers - Google's data interchange format
# Copyright 2015 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.
"""PDDM - Poor Developers' Debug-able Macros
A simple markup that can be added in comments of source so they can then be
expanded out into code. Most of this could be done with CPP macros, but then
developers can't really step through them in the debugger, this way they are
expanded to the same code, but you can debug them.
Any file can be processed, but the syntax is designed around a C based compiler.
Processed lines start with "//%". There are three types of sections you can
create: Text (left alone), Macro Definitions, and Macro Expansions. There is
no order required between definitions and expansions, all definitions are read
before any expansions are processed (thus, if desired, definitions can be put
at the end of the file to keep them out of the way of the code).
Macro Definitions are started with "//%PDDM-DEFINE Name(args)" and all lines
afterwards that start with "//%" are included in the definition. Multiple
macros can be defined in one block by just using a another "//%PDDM-DEFINE"
line to start the next macro. Optionally, a macro can be ended with
"//%PDDM-DEFINE-END", this can be useful when you want to make it clear that
trailing blank lines are included in the macro. You can also end a definition
with an expansion.
Macro Expansions are started by single lines containing
"//%PDDM-EXPAND Name(args)" and then with "//%PDDM-EXPAND-END" or another
expansions. All lines in-between are replaced by the result of the expansion.
The first line of the expansion is always a blank like just for readability.
Expansion itself is pretty simple, one macro can invoke another macro, but
you cannot nest the invoke of a macro in another macro (i.e. - can't do
"foo(bar(a))", but you can define foo(a) and bar(b) where bar invokes foo()
within its expansion.
When macros are expanded, the arg references can also add "$O" suffix to the
name (i.e. - "NAME$O") to specify an option to be applied. The options are:
$S - Replace each character in the value with a space.
$l - Lowercase the first letter of the value.
$L - Lowercase the whole value.
$u - Uppercase the first letter of the value.
$U - Uppercase the whole value.
Within a macro you can use ## to cause things to get joined together after
expansion (i.e. - "a##b" within a macro will become "ab").
Example:
int foo(MyEnum x) {
switch (x) {
//%PDDM-EXPAND case(Enum_Left, 1)
//%PDDM-EXPAND case(Enum_Center, 2)
//%PDDM-EXPAND case(Enum_Right, 3)
//%PDDM-EXPAND-END
}
//%PDDM-DEFINE case(_A, _B)
//% case _A:
//% return _B;
A macro ends at the start of the next one, or an optional %PDDM-DEFINE-END
can be used to avoid adding extra blank lines/returns (or make it clear when
it is desired).
One macro can invoke another by simply using its name NAME(ARGS). You cannot
nest an invoke inside another (i.e. - NAME1(NAME2(ARGS)) isn't supported).
Within a macro you can use ## to cause things to get joined together after
processing (i.e. - "a##b" within a macro will become "ab").
"""
import optparse
import os
import re
import sys
# Regex for macro definition.
_MACRO_RE = re.compile(r'(?P<name>\w+)\((?P<args>.*?)\)')
# Regex for macro's argument definition.
_MACRO_ARG_NAME_RE = re.compile(r'^\w+$')
# Line inserted after each EXPAND.
_GENERATED_CODE_LINE = (
'// This block of code is generated, do not edit it directly.'
)
def _MacroRefRe(macro_names):
# Takes in a list of macro names and makes a regex that will match invokes
# of those macros.
return re.compile(r'\b(?P<macro_ref>(?P<name>(%s))\((?P<args>.*?)\))' %
'|'.join(macro_names))
def _MacroArgRefRe(macro_arg_names):
# Takes in a list of macro arg names and makes a regex that will match
# uses of those args.
return re.compile(r'\b(?P<name>(%s))(\$(?P<option>.))?\b' %
'|'.join(macro_arg_names))
class PDDMError(Exception):
"""Error thrown by pddm."""
pass
class MacroCollection(object):
"""Hold a set of macros and can resolve/expand them."""
def __init__(self, a_file=None):
"""Initializes the collection.
Args:
a_file: The file like stream to parse.
Raises:
PDDMError if there are any issues.
"""
self._macros = dict()
if a_file:
self.ParseInput(a_file)
class MacroDefinition(object):
"""Holds a macro definition."""
def __init__(self, name, arg_names):
self._name = name
self._args = tuple(arg_names)
self._body = ''
self._needNewLine = False
def AppendLine(self, line):
if self._needNewLine:
self._body += '\n'
self._body += line
self._needNewLine = not line.endswith('\n')
@property
def name(self):
return self._name
@property
def args(self):
return self._args
@property
def body(self):
return self._body
def ParseInput(self, a_file):
"""Consumes input extracting definitions.
Args:
a_file: The file like stream to parse.
Raises:
PDDMError if there are any issues.
"""
input_lines = a_file.read().splitlines()
self.ParseLines(input_lines)
def ParseLines(self, input_lines):
"""Parses list of lines.
Args:
input_lines: A list of strings of input to parse (no newlines on the
strings).
Raises:
PDDMError if there are any issues.
"""
current_macro = None
for line in input_lines:
if line.startswith('PDDM-'):
directive = line.split(' ', 1)[0]
if directive == 'PDDM-DEFINE':
name, args = self._ParseDefineLine(line)
if self._macros.get(name):
raise PDDMError('Attempt to redefine macro: "%s"' % line)
current_macro = self.MacroDefinition(name, args)
self._macros[name] = current_macro
continue
if directive == 'PDDM-DEFINE-END':
if not current_macro:
raise PDDMError('Got DEFINE-END directive without an active macro:'
' "%s"' % line)
current_macro = None
continue
raise PDDMError('Hit a line with an unknown directive: "%s"' % line)
if current_macro:
current_macro.AppendLine(line)
continue
# Allow blank lines between macro definitions.
if line.strip() == '':
continue
raise PDDMError('Hit a line that wasn\'t a directive and no open macro'
' definition: "%s"' % line)
def _ParseDefineLine(self, input_line):
assert input_line.startswith('PDDM-DEFINE')
line = input_line[12:].strip()
match = _MACRO_RE.match(line)
# Must match full line
if match is None or match.group(0) != line:
raise PDDMError('Failed to parse macro definition: "%s"' % input_line)
name = match.group('name')
args_str = match.group('args').strip()
args = []
if args_str:
for part in args_str.split(','):
arg = part.strip()
if arg == '':
raise PDDMError('Empty arg name in macro definition: "%s"'
% input_line)
if not _MACRO_ARG_NAME_RE.match(arg):
raise PDDMError('Invalid arg name "%s" in macro definition: "%s"'
% (arg, input_line))
if arg in args:
raise PDDMError('Arg name "%s" used more than once in macro'
' definition: "%s"' % (arg, input_line))
args.append(arg)
return (name, tuple(args))
def Expand(self, macro_ref_str):
"""Expands the macro reference.
Args:
macro_ref_str: String of a macro reference (i.e. foo(a, b)).
Returns:
The text from the expansion.
Raises:
PDDMError if there are any issues.
"""
match = _MACRO_RE.match(macro_ref_str)
if match is None or match.group(0) != macro_ref_str:
raise PDDMError('Failed to parse macro reference: "%s"' % macro_ref_str)
if match.group('name') not in self._macros:
raise PDDMError('No macro named "%s".' % match.group('name'))
return self._Expand(match, [], macro_ref_str)
def _FormatStack(self, macro_ref_stack):
result = ''
for _, macro_ref in reversed(macro_ref_stack):
result += '\n...while expanding "%s".' % macro_ref
return result
def _Expand(self, macro_ref_match, macro_stack, macro_ref_str=None):
if macro_ref_str is None:
macro_ref_str = macro_ref_match.group('macro_ref')
name = macro_ref_match.group('name')
for prev_name, prev_macro_ref in macro_stack:
if name == prev_name:
raise PDDMError('Found macro recusion, invoking "%s":%s' %
(macro_ref_str, self._FormatStack(macro_stack)))
macro = self._macros[name]
args_str = macro_ref_match.group('args').strip()
args = []
if args_str or len(macro.args):
args = [x.strip() for x in args_str.split(',')]
if len(args) != len(macro.args):
raise PDDMError('Expected %d args, got: "%s".%s' %
(len(macro.args), macro_ref_str,
self._FormatStack(macro_stack)))
# Replace args usages.
result = self._ReplaceArgValues(macro, args, macro_ref_str, macro_stack)
# Expand any macro invokes.
new_macro_stack = macro_stack + [(name, macro_ref_str)]
while True:
eval_result = self._EvalMacrosRefs(result, new_macro_stack)
# Consume all ## directives to glue things together.
eval_result = eval_result.replace('##', '')
if eval_result == result:
break
result = eval_result
return result
def _ReplaceArgValues(self,
macro, arg_values, macro_ref_to_report, macro_stack):
if len(arg_values) == 0:
# Nothing to do
return macro.body
assert len(arg_values) == len(macro.args)
args = dict(zip(macro.args, arg_values))
def _lookupArg(match):
val = args[match.group('name')]
opt = match.group('option')
if opt:
if opt == 'S': # Spaces for the length
return ' ' * len(val)
elif opt == 'l': # Lowercase first character
if val:
return val[0].lower() + val[1:]
else:
return val
elif opt == 'L': # All Lowercase
return val.lower()
elif opt == 'u': # Uppercase first character
if val:
return val[0].upper() + val[1:]
else:
return val
elif opt == 'U': # All Uppercase
return val.upper()
else:
raise PDDMError('Unknown arg option "%s$%s" while expanding "%s".%s'
% (match.group('name'), match.group('option'),
macro_ref_to_report,
self._FormatStack(macro_stack)))
return val
# Let the regex do the work!
macro_arg_ref_re = _MacroArgRefRe(macro.args)
return macro_arg_ref_re.sub(_lookupArg, macro.body)
def _EvalMacrosRefs(self, text, macro_stack):
macro_ref_re = _MacroRefRe(self._macros.keys())
def _resolveMacro(match):
return self._Expand(match, macro_stack)
return macro_ref_re.sub(_resolveMacro, text)
class SourceFile(object):
"""Represents a source file with PDDM directives in it."""
def __init__(self, a_file, import_resolver=None):
"""Initializes the file reading in the file.
Args:
a_file: The file to read in.
import_resolver: a function that given a path will return a stream for
the contents.
Raises:
PDDMError if there are any issues.
"""
self._sections = []
self._original_content = a_file.read()
self._import_resolver = import_resolver
self._processed_content = None
class SectionBase(object):
def __init__(self, first_line_num):
self._lines = []
self._first_line_num = first_line_num
def TryAppend(self, line, line_num):
"""Try appending a line.
Args:
line: The line to append.
line_num: The number of the line.
Returns:
A tuple of (SUCCESS, CAN_ADD_MORE). If SUCCESS if False, the line
wasn't append. If SUCCESS is True, then CAN_ADD_MORE is True/False to
indicate if more lines can be added after this one.
"""
assert False, "sublcass should have overridden"
return (False, False)
def HitEOF(self):
"""Called when the EOF was reached for for a given section."""
pass
def BindMacroCollection(self, macro_collection):
"""Binds the chunk to a macro collection.
Args:
macro_collection: The collection to bind too.
"""
pass
def Append(self, line):
self._lines.append(line)
@property
def lines(self):
return self._lines
@property
def num_lines_captured(self):
return len(self._lines)
@property
def first_line_num(self):
return self._first_line_num
@property
def first_line(self):
if not self._lines:
return ''
return self._lines[0]
@property
def text(self):
return '\n'.join(self.lines) + '\n'
class TextSection(SectionBase):
"""Text section that is echoed out as is."""
def TryAppend(self, line, line_num):
if line.startswith('//%PDDM'):
return (False, False)
self.Append(line)
return (True, True)
class ExpansionSection(SectionBase):
"""Section that is the result of an macro expansion."""
def __init__(self, first_line_num):
SourceFile.SectionBase.__init__(self, first_line_num)
self._macro_collection = None
def TryAppend(self, line, line_num):
if line.startswith('//%PDDM'):
directive = line.split(' ', 1)[0]
if directive == '//%PDDM-EXPAND':
self.Append(line)
return (True, True)
if directive == '//%PDDM-EXPAND-END':
assert self.num_lines_captured > 0
return (True, False)
raise PDDMError('Ran into directive ("%s", line %d) while in "%s".' %
(directive, line_num, self.first_line))
# Eat other lines.
return (True, True)
def HitEOF(self):
raise PDDMError('Hit the end of the file while in "%s".' %
self.first_line)
def BindMacroCollection(self, macro_collection):
self._macro_collection = macro_collection
@property
def lines(self):
captured_lines = SourceFile.SectionBase.lines.fget(self)
directive_len = len('//%PDDM-EXPAND')
result = []
for line in captured_lines:
result.append(line)
if self._macro_collection:
# Always add a blank line, seems to read better. (If need be, add an
# option to the EXPAND to indicate if this should be done.)
result.extend([_GENERATED_CODE_LINE, ''])
macro = line[directive_len:].strip()
try:
expand_result = self._macro_collection.Expand(macro)
# Since expansions are line oriented, strip trailing whitespace
# from the lines.
lines = [x.rstrip() for x in expand_result.split('\n')]
result.append('\n'.join(lines))
except PDDMError as e:
raise PDDMError('%s\n...while expanding "%s" from the section'
' that started:\n Line %d: %s' %
(e.message, macro,
self.first_line_num, self.first_line))
# Add the ending marker.
if len(captured_lines) == 1:
result.append('//%%PDDM-EXPAND-END %s' %
captured_lines[0][directive_len:].strip())
else:
result.append('//%%PDDM-EXPAND-END (%s expansions)' % len(captured_lines))
return result
class DefinitionSection(SectionBase):
"""Section containing macro definitions"""
def TryAppend(self, line, line_num):
if not line.startswith('//%'):
return (False, False)
if line.startswith('//%PDDM'):
directive = line.split(' ', 1)[0]
if directive == "//%PDDM-EXPAND":
return False, False
if directive not in ('//%PDDM-DEFINE', '//%PDDM-DEFINE-END'):
raise PDDMError('Ran into directive ("%s", line %d) while in "%s".' %
(directive, line_num, self.first_line))
self.Append(line)
return (True, True)
def BindMacroCollection(self, macro_collection):
if macro_collection:
try:
# Parse the lines after stripping the prefix.
macro_collection.ParseLines([x[3:] for x in self.lines])
except PDDMError as e:
raise PDDMError('%s\n...while parsing section that started:\n'
' Line %d: %s' %
(e.message, self.first_line_num, self.first_line))
class ImportDefinesSection(SectionBase):
"""Section containing an import of PDDM-DEFINES from an external file."""
def __init__(self, first_line_num, import_resolver):
SourceFile.SectionBase.__init__(self, first_line_num)
self._import_resolver = import_resolver
def TryAppend(self, line, line_num):
if not line.startswith('//%PDDM-IMPORT-DEFINES '):
return (False, False)
assert self.num_lines_captured == 0
self.Append(line)
return (True, False)
def BindMacroCollection(self, macro_colletion):
if not macro_colletion:
return
if self._import_resolver is None:
raise PDDMError('Got an IMPORT-DEFINES without a resolver (line %d):'
' "%s".' % (self.first_line_num, self.first_line))
import_name = self.first_line.split(' ', 1)[1].strip()
imported_file = self._import_resolver(import_name)
if imported_file is None:
raise PDDMError('Resolver failed to find "%s" (line %d):'
' "%s".' %
(import_name, self.first_line_num, self.first_line))
try:
imported_src_file = SourceFile(imported_file, self._import_resolver)
imported_src_file._ParseFile()
for section in imported_src_file._sections:
section.BindMacroCollection(macro_colletion)
except PDDMError as e:
raise PDDMError('%s\n...while importing defines:\n'
' Line %d: %s' %
(e.message, self.first_line_num, self.first_line))
def _ParseFile(self):
self._sections = []
lines = self._original_content.splitlines()
cur_section = None
for line_num, line in enumerate(lines, 1):
if not cur_section:
cur_section = self._MakeSection(line, line_num)
was_added, accept_more = cur_section.TryAppend(line, line_num)
if not was_added:
cur_section = self._MakeSection(line, line_num)
was_added, accept_more = cur_section.TryAppend(line, line_num)
assert was_added
if not accept_more:
cur_section = None
if cur_section:
cur_section.HitEOF()
def _MakeSection(self, line, line_num):
if not line.startswith('//%PDDM'):
section = self.TextSection(line_num)
else:
directive = line.split(' ', 1)[0]
if directive == '//%PDDM-EXPAND':
section = self.ExpansionSection(line_num)
elif directive == '//%PDDM-DEFINE':
section = self.DefinitionSection(line_num)
elif directive == '//%PDDM-IMPORT-DEFINES':
section = self.ImportDefinesSection(line_num, self._import_resolver)
else:
raise PDDMError('Unexpected line %d: "%s".' % (line_num, line))
self._sections.append(section)
return section
def ProcessContent(self, strip_expansion=False):
"""Processes the file contents."""
self._ParseFile()
if strip_expansion:
# Without a collection the expansions become blank, removing them.
collection = None
else:
collection = MacroCollection()
for section in self._sections:
section.BindMacroCollection(collection)
result = ''
for section in self._sections:
result += section.text
self._processed_content = result
@property
def original_content(self):
return self._original_content
@property
def processed_content(self):
return self._processed_content
def main(args):
usage = '%prog [OPTIONS] PATH ...'
description = (
'Processes PDDM directives in the the given paths and write them back'
' out.'
)
parser = optparse.OptionParser(usage=usage, description=description)
parser.add_option('--dry-run',
default=False, action='store_true',
help='Don\'t write back to the file(s), just report if the'
' contents needs an update and exit with a value of 1.')
parser.add_option('--verbose',
default=False, action='store_true',
help='Reports is a file is already current.')
parser.add_option('--collapse',
default=False, action='store_true',
help='Removes all the generated code.')
opts, extra_args = parser.parse_args(args)
if not extra_args:
parser.error('Need atleast one file to process')
result = 0
for a_path in extra_args:
if not os.path.exists(a_path):
sys.stderr.write('ERROR: File not found: %s\n' % a_path)
return 100
def _ImportResolver(name):
# resolve based on the file being read.
a_dir = os.path.dirname(a_path)
import_path = os.path.join(a_dir, name)
if not os.path.exists(import_path):
return None
return open(import_path, 'r')
with open(a_path, 'r') as f:
src_file = SourceFile(f, _ImportResolver)
try:
src_file.ProcessContent(strip_expansion=opts.collapse)
except PDDMError as e:
sys.stderr.write('ERROR: %s\n...While processing "%s"\n' %
(e.message, a_path))
return 101
if src_file.processed_content != src_file.original_content:
if not opts.dry_run:
print 'Updating for "%s".' % a_path
with open(a_path, 'w') as f:
f.write(src_file.processed_content)
else:
# Special result to indicate things need updating.
print 'Update needed for "%s".' % a_path
result = 1
elif opts.verbose:
print 'No update for "%s".' % a_path
return result
if __name__ == '__main__':
sys.exit(main(sys.argv[1:]))

@ -0,0 +1,515 @@
#! /usr/bin/python
#
# Protocol Buffers - Google's data interchange format
# Copyright 2015 Google Inc. All rights reserved.
# https://developers.google.com/protocol-buffers/
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following disclaimer
# in the documentation and/or other materials provided with the
# distribution.
# * Neither the name of Google Inc. nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
"""Tests for pddm.py."""
import io
import unittest
import pddm
class TestParsingMacros(unittest.TestCase):
def testParseEmpty(self):
f = io.StringIO(u'')
result = pddm.MacroCollection(f)
self.assertEqual(len(result._macros), 0)
def testParseOne(self):
f = io.StringIO(u"""PDDM-DEFINE foo( )
body""")
result = pddm.MacroCollection(f)
self.assertEqual(len(result._macros), 1)
macro = result._macros.get('foo')
self.assertIsNotNone(macro)
self.assertEquals(macro.name, 'foo')
self.assertEquals(macro.args, tuple())
self.assertEquals(macro.body, 'body')
def testParseGeneral(self):
# Tests multiple defines, spaces in all places, etc.
f = io.StringIO(u"""
PDDM-DEFINE noArgs( )
body1
body2
PDDM-DEFINE-END
PDDM-DEFINE oneArg(foo)
body3
PDDM-DEFINE twoArgs( bar_ , baz )
body4
body5""")
result = pddm.MacroCollection(f)
self.assertEqual(len(result._macros), 3)
macro = result._macros.get('noArgs')
self.assertIsNotNone(macro)
self.assertEquals(macro.name, 'noArgs')
self.assertEquals(macro.args, tuple())
self.assertEquals(macro.body, 'body1\nbody2\n')
macro = result._macros.get('oneArg')
self.assertIsNotNone(macro)
self.assertEquals(macro.name, 'oneArg')
self.assertEquals(macro.args, ('foo',))
self.assertEquals(macro.body, 'body3')
macro = result._macros.get('twoArgs')
self.assertIsNotNone(macro)
self.assertEquals(macro.name, 'twoArgs')
self.assertEquals(macro.args, ('bar_', 'baz'))
self.assertEquals(macro.body, 'body4\nbody5')
# Add into existing collection
f = io.StringIO(u"""
PDDM-DEFINE another(a,b,c)
body1
body2""")
result.ParseInput(f)
self.assertEqual(len(result._macros), 4)
macro = result._macros.get('another')
self.assertIsNotNone(macro)
self.assertEquals(macro.name, 'another')
self.assertEquals(macro.args, ('a', 'b', 'c'))
self.assertEquals(macro.body, 'body1\nbody2')
def testParseDirectiveIssues(self):
test_list = [
# Unknown directive
(u'PDDM-DEFINE foo()\nbody\nPDDM-DEFINED foo\nbaz',
'Hit a line with an unknown directive: '),
# End without begin
(u'PDDM-DEFINE foo()\nbody\nPDDM-DEFINE-END\nPDDM-DEFINE-END\n',
'Got DEFINE-END directive without an active macro: '),
# Line not in macro block
(u'PDDM-DEFINE foo()\nbody\nPDDM-DEFINE-END\nmumble\n',
'Hit a line that wasn\'t a directive and no open macro definition: '),
# Redefine macro
(u'PDDM-DEFINE foo()\nbody\nPDDM-DEFINE foo(a)\nmumble\n',
'Attempt to redefine macro: '),
]
for idx, (input_str, expected_prefix) in enumerate(test_list, 1):
f = io.StringIO(input_str)
try:
result = pddm.MacroCollection(f)
self.fail('Should throw exception, entry %d' % idx)
except pddm.PDDMError as e:
self.assertTrue(e.message.startswith(expected_prefix),
'Entry %d failed: %r' % (idx, e))
def testParseBeginIssues(self):
test_list = [
# 1. No name
(u'PDDM-DEFINE\nmumble',
'Failed to parse macro definition: '),
# 2. No name (with spaces)
(u'PDDM-DEFINE \nmumble',
'Failed to parse macro definition: '),
# 3. No open paren
(u'PDDM-DEFINE foo\nmumble',
'Failed to parse macro definition: '),
# 4. No close paren
(u'PDDM-DEFINE foo(\nmumble',
'Failed to parse macro definition: '),
# 5. No close paren (with args)
(u'PDDM-DEFINE foo(a, b\nmumble',
'Failed to parse macro definition: '),
# 6. No name before args
(u'PDDM-DEFINE (a, b)\nmumble',
'Failed to parse macro definition: '),
# 7. No name before args
(u'PDDM-DEFINE foo bar(a, b)\nmumble',
'Failed to parse macro definition: '),
# 8. Empty arg name
(u'PDDM-DEFINE foo(a, ,b)\nmumble',
'Empty arg name in macro definition: '),
(u'PDDM-DEFINE foo(a,,b)\nmumble',
'Empty arg name in macro definition: '),
# 10. Duplicate name
(u'PDDM-DEFINE foo(a,b,a,c)\nmumble',
'Arg name "a" used more than once in macro definition: '),
# 11. Invalid arg name
(u'PDDM-DEFINE foo(a b,c)\nmumble',
'Invalid arg name "a b" in macro definition: '),
(u'PDDM-DEFINE foo(a.b,c)\nmumble',
'Invalid arg name "a.b" in macro definition: '),
(u'PDDM-DEFINE foo(a-b,c)\nmumble',
'Invalid arg name "a-b" in macro definition: '),
(u'PDDM-DEFINE foo(a,b,c.)\nmumble',
'Invalid arg name "c." in macro definition: '),
# 15. Extra stuff after the name
(u'PDDM-DEFINE foo(a,c) foo\nmumble',
'Failed to parse macro definition: '),
(u'PDDM-DEFINE foo(a,c) foo)\nmumble',
'Failed to parse macro definition: '),
]
for idx, (input_str, expected_prefix) in enumerate(test_list, 1):
f = io.StringIO(input_str)
try:
result = pddm.MacroCollection(f)
self.fail('Should throw exception, entry %d' % idx)
except pddm.PDDMError as e:
self.assertTrue(e.message.startswith(expected_prefix),
'Entry %d failed: %r' % (idx, e))
class TestExpandingMacros(unittest.TestCase):
def testExpandBasics(self):
f = io.StringIO(u"""
PDDM-DEFINE noArgs( )
body1
body2
PDDM-DEFINE-END
PDDM-DEFINE oneArg(a)
body3 a
PDDM-DEFINE-END
PDDM-DEFINE twoArgs(b,c)
body4 b c
body5
PDDM-DEFINE-END
""")
mc = pddm.MacroCollection(f)
test_list = [
(u'noArgs()',
'body1\nbody2\n'),
(u'oneArg(wee)',
'body3 wee\n'),
(u'twoArgs(having some, fun)',
'body4 having some fun\nbody5'),
# One arg, pass empty.
(u'oneArg()',
'body3 \n'),
# Two args, gets empty in each slot.
(u'twoArgs(, empty)',
'body4 empty\nbody5'),
(u'twoArgs(empty, )',
'body4 empty \nbody5'),
(u'twoArgs(, )',
'body4 \nbody5'),
]
for idx, (input_str, expected) in enumerate(test_list, 1):
result = mc.Expand(input_str)
self.assertEqual(result, expected,
'Entry %d --\n Result: %r\n Expected: %r' %
(idx, result, expected))
def testExpandArgOptions(self):
f = io.StringIO(u"""
PDDM-DEFINE bar(a)
a-a$S-a$l-a$L-a$u-a$U
PDDM-DEFINE-END
""")
mc = pddm.MacroCollection(f)
self.assertEqual(mc.Expand('bar(xYz)'), 'xYz- -xYz-xyz-XYz-XYZ')
self.assertEqual(mc.Expand('bar(MnoP)'), 'MnoP- -mnoP-mnop-MnoP-MNOP')
# Test empty
self.assertEqual(mc.Expand('bar()'), '-----')
def testExpandSimpleMacroErrors(self):
f = io.StringIO(u"""
PDDM-DEFINE foo(a, b)
<a-z>
PDDM-DEFINE baz(a)
a - a$z
""")
mc = pddm.MacroCollection(f)
test_list = [
# 1. Unknown macro
(u'bar()',
'No macro named "bar".'),
(u'bar(a)',
'No macro named "bar".'),
# 3. Arg mismatch
(u'foo()',
'Expected 2 args, got: "foo()".'),
(u'foo(a b)',
'Expected 2 args, got: "foo(a b)".'),
(u'foo(a,b,c)',
'Expected 2 args, got: "foo(a,b,c)".'),
# 6. Unknown option in expansion
(u'baz(mumble)',
'Unknown arg option "a$z" while expanding "baz(mumble)".'),
]
for idx, (input_str, expected_err) in enumerate(test_list, 1):
try:
result = mc.Expand(input_str)
self.fail('Should throw exception, entry %d' % idx)
except pddm.PDDMError as e:
self.assertEqual(e.message, expected_err,
'Entry %d failed: %r' % (idx, e))
def testExpandReferences(self):
f = io.StringIO(u"""
PDDM-DEFINE StartIt()
foo(abc, def)
foo(ghi, jkl)
PDDM-DEFINE foo(a, b)
bar(a, int)
bar(b, NSString *)
PDDM-DEFINE bar(n, t)
- (t)n;
- (void)set##n$u##:(t)value;
""")
mc = pddm.MacroCollection(f)
expected = """- (int)abc;
- (void)setAbc:(int)value;
- (NSString *)def;
- (void)setDef:(NSString *)value;
- (int)ghi;
- (void)setGhi:(int)value;
- (NSString *)jkl;
- (void)setJkl:(NSString *)value;
"""
self.assertEqual(mc.Expand('StartIt()'), expected)
def testCatchRecursion(self):
f = io.StringIO(u"""
PDDM-DEFINE foo(a, b)
bar(1, a)
bar(2, b)
PDDM-DEFINE bar(x, y)
foo(x, y)
""")
mc = pddm.MacroCollection(f)
try:
result = mc.Expand('foo(A,B)')
self.fail('Should throw exception, entry %d' % idx)
except pddm.PDDMError as e:
self.assertEqual(e.message,
'Found macro recusion, invoking "foo(1, A)":\n...while expanding "bar(1, A)".\n...while expanding "foo(A,B)".')
class TestParsingSource(unittest.TestCase):
def testBasicParse(self):
test_list = [
# 1. no directives
(u'a\nb\nc',
(3,) ),
# 2. One define
(u'a\n//%PDDM-DEFINE foo()\n//%body\nc',
(1, 2, 1) ),
# 3. Two defines
(u'a\n//%PDDM-DEFINE foo()\n//%body\n//%PDDM-DEFINE bar()\n//%body2\nc',
(1, 4, 1) ),
# 4. Two defines with ends
(u'a\n//%PDDM-DEFINE foo()\n//%body\n//%PDDM-DEFINE-END\n'
u'//%PDDM-DEFINE bar()\n//%body2\n//%PDDM-DEFINE-END\nc',
(1, 6, 1) ),
# 5. One expand, one define (that runs to end of file)
(u'a\n//%PDDM-EXPAND foo()\nbody\n//%PDDM-EXPAND-END\n'
u'//%PDDM-DEFINE bar()\n//%body2\n',
(1, 1, 2) ),
# 6. One define ended with an expand.
(u'a\nb\n//%PDDM-DEFINE bar()\n//%body2\n'
u'//%PDDM-EXPAND bar()\nbody2\n//%PDDM-EXPAND-END\n',
(2, 2, 1) ),
# 7. Two expands (one end), one define.
(u'a\n//%PDDM-EXPAND foo(1)\nbody\n//%PDDM-EXPAND foo(2)\nbody2\n//%PDDM-EXPAND-END\n'
u'//%PDDM-DEFINE foo()\n//%body2\n',
(1, 2, 2) ),
]
for idx, (input_str, line_counts) in enumerate(test_list, 1):
f = io.StringIO(input_str)
sf = pddm.SourceFile(f)
sf._ParseFile()
self.assertEqual(len(sf._sections), len(line_counts),
'Entry %d -- %d != %d' %
(idx, len(sf._sections), len(line_counts)))
for idx2, (sec, expected) in enumerate(zip(sf._sections, line_counts), 1):
self.assertEqual(sec.num_lines_captured, expected,
'Entry %d, section %d -- %d != %d' %
(idx, idx2, sec.num_lines_captured, expected))
def testErrors(self):
test_list = [
# 1. Directive within expansion
(u'//%PDDM-EXPAND a()\n//%PDDM-BOGUS',
'Ran into directive ("//%PDDM-BOGUS", line 2) while in "//%PDDM-EXPAND a()".'),
(u'//%PDDM-EXPAND a()\n//%PDDM-DEFINE a()\n//%body\n',
'Ran into directive ("//%PDDM-DEFINE", line 2) while in "//%PDDM-EXPAND a()".'),
# 3. Expansion ran off end of file
(u'//%PDDM-EXPAND a()\na\nb\n',
'Hit the end of the file while in "//%PDDM-EXPAND a()".'),
# 4. Directive within define
(u'//%PDDM-DEFINE a()\n//%body\n//%PDDM-BOGUS',
'Ran into directive ("//%PDDM-BOGUS", line 3) while in "//%PDDM-DEFINE a()".'),
(u'//%PDDM-DEFINE a()\n//%body\n//%PDDM-EXPAND-END a()',
'Ran into directive ("//%PDDM-EXPAND-END", line 3) while in "//%PDDM-DEFINE a()".'),
# 6. Directives that shouldn't start sections
(u'a\n//%PDDM-DEFINE-END a()\n//a\n',
'Unexpected line 2: "//%PDDM-DEFINE-END a()".'),
(u'a\n//%PDDM-EXPAND-END a()\n//a\n',
'Unexpected line 2: "//%PDDM-EXPAND-END a()".'),
(u'//%PDDM-BOGUS\n//a\n',
'Unexpected line 1: "//%PDDM-BOGUS".'),
]
for idx, (input_str, expected_err) in enumerate(test_list, 1):
f = io.StringIO(input_str)
try:
pddm.SourceFile(f)._ParseFile()
self.fail('Should throw exception, entry %d' % idx)
except pddm.PDDMError as e:
self.assertEqual(e.message, expected_err,
'Entry %d failed: %r' % (idx, e))
class TestProcessingSource(unittest.TestCase):
def testBasics(self):
input_str = u"""
//%PDDM-IMPORT-DEFINES ImportFile
foo
//%PDDM-EXPAND mumble(abc)
//%PDDM-EXPAND-END
bar
//%PDDM-EXPAND mumble(def)
//%PDDM-EXPAND mumble(ghi)
//%PDDM-EXPAND-END
baz
//%PDDM-DEFINE mumble(a_)
//%a_: getName(a_)
"""
input_str2 = u"""
//%PDDM-DEFINE getName(x_)
//%do##x_$u##(int x_);
"""
expected = u"""
//%PDDM-IMPORT-DEFINES ImportFile
foo
//%PDDM-EXPAND mumble(abc)
// This block of code is generated, do not edit it directly.
abc: doAbc(int abc);
//%PDDM-EXPAND-END mumble(abc)
bar
//%PDDM-EXPAND mumble(def)
// This block of code is generated, do not edit it directly.
def: doDef(int def);
//%PDDM-EXPAND mumble(ghi)
// This block of code is generated, do not edit it directly.
ghi: doGhi(int ghi);
//%PDDM-EXPAND-END (2 expansions)
baz
//%PDDM-DEFINE mumble(a_)
//%a_: getName(a_)
"""
expected_stripped = u"""
//%PDDM-IMPORT-DEFINES ImportFile
foo
//%PDDM-EXPAND mumble(abc)
//%PDDM-EXPAND-END mumble(abc)
bar
//%PDDM-EXPAND mumble(def)
//%PDDM-EXPAND mumble(ghi)
//%PDDM-EXPAND-END (2 expansions)
baz
//%PDDM-DEFINE mumble(a_)
//%a_: getName(a_)
"""
def _Resolver(name):
self.assertEqual(name, 'ImportFile')
return io.StringIO(input_str2)
f = io.StringIO(input_str)
sf = pddm.SourceFile(f, _Resolver)
sf.ProcessContent()
self.assertEqual(sf.processed_content, expected)
# Feed it through and nothing should change.
f2 = io.StringIO(sf.processed_content)
sf2 = pddm.SourceFile(f2, _Resolver)
sf2.ProcessContent()
self.assertEqual(sf2.processed_content, expected)
self.assertEqual(sf2.processed_content, sf.processed_content)
# Test stripping (with the original input and expanded version).
f2 = io.StringIO(input_str)
sf2 = pddm.SourceFile(f2)
sf2.ProcessContent(strip_expansion=True)
self.assertEqual(sf2.processed_content, expected_stripped)
f2 = io.StringIO(sf.processed_content)
sf2 = pddm.SourceFile(f2, _Resolver)
sf2.ProcessContent(strip_expansion=True)
self.assertEqual(sf2.processed_content, expected_stripped)
def testProcessFileWithMacroParseError(self):
input_str = u"""
foo
//%PDDM-DEFINE mumble(a_)
//%body
//%PDDM-DEFINE mumble(x_)
//%body2
"""
f = io.StringIO(input_str)
sf = pddm.SourceFile(f)
try:
sf.ProcessContent()
self.fail('Should throw exception, entry %d' % idx)
except pddm.PDDMError as e:
self.assertEqual(e.message,
'Attempt to redefine macro: "PDDM-DEFINE mumble(x_)"\n'
'...while parsing section that started:\n'
' Line 3: //%PDDM-DEFINE mumble(a_)')
def testProcessFileWithExpandError(self):
input_str = u"""
foo
//%PDDM-DEFINE mumble(a_)
//%body
//%PDDM-EXPAND foobar(x_)
//%PDDM-EXPAND-END
"""
f = io.StringIO(input_str)
sf = pddm.SourceFile(f)
try:
sf.ProcessContent()
self.fail('Should throw exception, entry %d' % idx)
except pddm.PDDMError as e:
self.assertEqual(e.message,
'No macro named "foobar".\n'
'...while expanding "foobar(x_)" from the section that'
' started:\n Line 5: //%PDDM-EXPAND foobar(x_)')
if __name__ == '__main__':
unittest.main()

@ -0,0 +1,535 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2015 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 "GPBTypes.h"
// These classes are used for repeated fields of basic data types. They are used because
// they perform better than boxing into NSNumbers in NSArrays.
// Note: These are not meant to be subclassed.
//%PDDM-EXPAND DECLARE_ARRAYS()
// This block of code is generated, do not edit it directly.
#pragma mark - Int32
@interface GPBInt32Array : NSObject <NSCopying>
@property(nonatomic, readonly) NSUInteger count;
+ (instancetype)array;
+ (instancetype)arrayWithValue:(int32_t)value;
+ (instancetype)arrayWithValueArray:(GPBInt32Array *)array;
+ (instancetype)arrayWithCapacity:(NSUInteger)count;
// Initializes the array, copying the values.
- (instancetype)initWithValues:(const int32_t [])values
count:(NSUInteger)count NS_DESIGNATED_INITIALIZER;
- (instancetype)initWithValueArray:(GPBInt32Array *)array;
- (instancetype)initWithCapacity:(NSUInteger)count;
- (int32_t)valueAtIndex:(NSUInteger)index;
- (void)enumerateValuesWithBlock:(void (^)(int32_t value, NSUInteger idx, BOOL *stop))block;
- (void)enumerateValuesWithOptions:(NSEnumerationOptions)opts
usingBlock:(void (^)(int32_t value, NSUInteger idx, BOOL *stop))block;
- (void)addValue:(int32_t)value;
- (void)addValues:(const int32_t [])values count:(NSUInteger)count;
- (void)addValuesFromArray:(GPBInt32Array *)array;
- (void)insertValue:(int32_t)value atIndex:(NSUInteger)index;
- (void)replaceValueAtIndex:(NSUInteger)index withValue:(int32_t)value;
- (void)removeValueAtIndex:(NSUInteger)index;
- (void)removeAll;
- (void)exchangeValueAtIndex:(NSUInteger)idx1
withValueAtIndex:(NSUInteger)idx2;
@end
#pragma mark - UInt32
@interface GPBUInt32Array : NSObject <NSCopying>
@property(nonatomic, readonly) NSUInteger count;
+ (instancetype)array;
+ (instancetype)arrayWithValue:(uint32_t)value;
+ (instancetype)arrayWithValueArray:(GPBUInt32Array *)array;
+ (instancetype)arrayWithCapacity:(NSUInteger)count;
// Initializes the array, copying the values.
- (instancetype)initWithValues:(const uint32_t [])values
count:(NSUInteger)count NS_DESIGNATED_INITIALIZER;
- (instancetype)initWithValueArray:(GPBUInt32Array *)array;
- (instancetype)initWithCapacity:(NSUInteger)count;
- (uint32_t)valueAtIndex:(NSUInteger)index;
- (void)enumerateValuesWithBlock:(void (^)(uint32_t value, NSUInteger idx, BOOL *stop))block;
- (void)enumerateValuesWithOptions:(NSEnumerationOptions)opts
usingBlock:(void (^)(uint32_t value, NSUInteger idx, BOOL *stop))block;
- (void)addValue:(uint32_t)value;
- (void)addValues:(const uint32_t [])values count:(NSUInteger)count;
- (void)addValuesFromArray:(GPBUInt32Array *)array;
- (void)insertValue:(uint32_t)value atIndex:(NSUInteger)index;
- (void)replaceValueAtIndex:(NSUInteger)index withValue:(uint32_t)value;
- (void)removeValueAtIndex:(NSUInteger)index;
- (void)removeAll;
- (void)exchangeValueAtIndex:(NSUInteger)idx1
withValueAtIndex:(NSUInteger)idx2;
@end
#pragma mark - Int64
@interface GPBInt64Array : NSObject <NSCopying>
@property(nonatomic, readonly) NSUInteger count;
+ (instancetype)array;
+ (instancetype)arrayWithValue:(int64_t)value;
+ (instancetype)arrayWithValueArray:(GPBInt64Array *)array;
+ (instancetype)arrayWithCapacity:(NSUInteger)count;
// Initializes the array, copying the values.
- (instancetype)initWithValues:(const int64_t [])values
count:(NSUInteger)count NS_DESIGNATED_INITIALIZER;
- (instancetype)initWithValueArray:(GPBInt64Array *)array;
- (instancetype)initWithCapacity:(NSUInteger)count;
- (int64_t)valueAtIndex:(NSUInteger)index;
- (void)enumerateValuesWithBlock:(void (^)(int64_t value, NSUInteger idx, BOOL *stop))block;
- (void)enumerateValuesWithOptions:(NSEnumerationOptions)opts
usingBlock:(void (^)(int64_t value, NSUInteger idx, BOOL *stop))block;
- (void)addValue:(int64_t)value;
- (void)addValues:(const int64_t [])values count:(NSUInteger)count;
- (void)addValuesFromArray:(GPBInt64Array *)array;
- (void)insertValue:(int64_t)value atIndex:(NSUInteger)index;
- (void)replaceValueAtIndex:(NSUInteger)index withValue:(int64_t)value;
- (void)removeValueAtIndex:(NSUInteger)index;
- (void)removeAll;
- (void)exchangeValueAtIndex:(NSUInteger)idx1
withValueAtIndex:(NSUInteger)idx2;
@end
#pragma mark - UInt64
@interface GPBUInt64Array : NSObject <NSCopying>
@property(nonatomic, readonly) NSUInteger count;
+ (instancetype)array;
+ (instancetype)arrayWithValue:(uint64_t)value;
+ (instancetype)arrayWithValueArray:(GPBUInt64Array *)array;
+ (instancetype)arrayWithCapacity:(NSUInteger)count;
// Initializes the array, copying the values.
- (instancetype)initWithValues:(const uint64_t [])values
count:(NSUInteger)count NS_DESIGNATED_INITIALIZER;
- (instancetype)initWithValueArray:(GPBUInt64Array *)array;
- (instancetype)initWithCapacity:(NSUInteger)count;
- (uint64_t)valueAtIndex:(NSUInteger)index;
- (void)enumerateValuesWithBlock:(void (^)(uint64_t value, NSUInteger idx, BOOL *stop))block;
- (void)enumerateValuesWithOptions:(NSEnumerationOptions)opts
usingBlock:(void (^)(uint64_t value, NSUInteger idx, BOOL *stop))block;
- (void)addValue:(uint64_t)value;
- (void)addValues:(const uint64_t [])values count:(NSUInteger)count;
- (void)addValuesFromArray:(GPBUInt64Array *)array;
- (void)insertValue:(uint64_t)value atIndex:(NSUInteger)index;
- (void)replaceValueAtIndex:(NSUInteger)index withValue:(uint64_t)value;
- (void)removeValueAtIndex:(NSUInteger)index;
- (void)removeAll;
- (void)exchangeValueAtIndex:(NSUInteger)idx1
withValueAtIndex:(NSUInteger)idx2;
@end
#pragma mark - Float
@interface GPBFloatArray : NSObject <NSCopying>
@property(nonatomic, readonly) NSUInteger count;
+ (instancetype)array;
+ (instancetype)arrayWithValue:(float)value;
+ (instancetype)arrayWithValueArray:(GPBFloatArray *)array;
+ (instancetype)arrayWithCapacity:(NSUInteger)count;
// Initializes the array, copying the values.
- (instancetype)initWithValues:(const float [])values
count:(NSUInteger)count NS_DESIGNATED_INITIALIZER;
- (instancetype)initWithValueArray:(GPBFloatArray *)array;
- (instancetype)initWithCapacity:(NSUInteger)count;
- (float)valueAtIndex:(NSUInteger)index;
- (void)enumerateValuesWithBlock:(void (^)(float value, NSUInteger idx, BOOL *stop))block;
- (void)enumerateValuesWithOptions:(NSEnumerationOptions)opts
usingBlock:(void (^)(float value, NSUInteger idx, BOOL *stop))block;
- (void)addValue:(float)value;
- (void)addValues:(const float [])values count:(NSUInteger)count;
- (void)addValuesFromArray:(GPBFloatArray *)array;
- (void)insertValue:(float)value atIndex:(NSUInteger)index;
- (void)replaceValueAtIndex:(NSUInteger)index withValue:(float)value;
- (void)removeValueAtIndex:(NSUInteger)index;
- (void)removeAll;
- (void)exchangeValueAtIndex:(NSUInteger)idx1
withValueAtIndex:(NSUInteger)idx2;
@end
#pragma mark - Double
@interface GPBDoubleArray : NSObject <NSCopying>
@property(nonatomic, readonly) NSUInteger count;
+ (instancetype)array;
+ (instancetype)arrayWithValue:(double)value;
+ (instancetype)arrayWithValueArray:(GPBDoubleArray *)array;
+ (instancetype)arrayWithCapacity:(NSUInteger)count;
// Initializes the array, copying the values.
- (instancetype)initWithValues:(const double [])values
count:(NSUInteger)count NS_DESIGNATED_INITIALIZER;
- (instancetype)initWithValueArray:(GPBDoubleArray *)array;
- (instancetype)initWithCapacity:(NSUInteger)count;
- (double)valueAtIndex:(NSUInteger)index;
- (void)enumerateValuesWithBlock:(void (^)(double value, NSUInteger idx, BOOL *stop))block;
- (void)enumerateValuesWithOptions:(NSEnumerationOptions)opts
usingBlock:(void (^)(double value, NSUInteger idx, BOOL *stop))block;
- (void)addValue:(double)value;
- (void)addValues:(const double [])values count:(NSUInteger)count;
- (void)addValuesFromArray:(GPBDoubleArray *)array;
- (void)insertValue:(double)value atIndex:(NSUInteger)index;
- (void)replaceValueAtIndex:(NSUInteger)index withValue:(double)value;
- (void)removeValueAtIndex:(NSUInteger)index;
- (void)removeAll;
- (void)exchangeValueAtIndex:(NSUInteger)idx1
withValueAtIndex:(NSUInteger)idx2;
@end
#pragma mark - Bool
@interface GPBBoolArray : NSObject <NSCopying>
@property(nonatomic, readonly) NSUInteger count;
+ (instancetype)array;
+ (instancetype)arrayWithValue:(BOOL)value;
+ (instancetype)arrayWithValueArray:(GPBBoolArray *)array;
+ (instancetype)arrayWithCapacity:(NSUInteger)count;
// Initializes the array, copying the values.
- (instancetype)initWithValues:(const BOOL [])values
count:(NSUInteger)count NS_DESIGNATED_INITIALIZER;
- (instancetype)initWithValueArray:(GPBBoolArray *)array;
- (instancetype)initWithCapacity:(NSUInteger)count;
- (BOOL)valueAtIndex:(NSUInteger)index;
- (void)enumerateValuesWithBlock:(void (^)(BOOL value, NSUInteger idx, BOOL *stop))block;
- (void)enumerateValuesWithOptions:(NSEnumerationOptions)opts
usingBlock:(void (^)(BOOL value, NSUInteger idx, BOOL *stop))block;
- (void)addValue:(BOOL)value;
- (void)addValues:(const BOOL [])values count:(NSUInteger)count;
- (void)addValuesFromArray:(GPBBoolArray *)array;
- (void)insertValue:(BOOL)value atIndex:(NSUInteger)index;
- (void)replaceValueAtIndex:(NSUInteger)index withValue:(BOOL)value;
- (void)removeValueAtIndex:(NSUInteger)index;
- (void)removeAll;
- (void)exchangeValueAtIndex:(NSUInteger)idx1
withValueAtIndex:(NSUInteger)idx2;
@end
#pragma mark - Enum
@interface GPBEnumArray : NSObject <NSCopying>
@property(nonatomic, readonly) NSUInteger count;
@property(nonatomic, readonly) GPBEnumValidationFunc validationFunc;
+ (instancetype)array;
+ (instancetype)arrayWithValidationFunction:(GPBEnumValidationFunc)func;
+ (instancetype)arrayWithValidationFunction:(GPBEnumValidationFunc)func
rawValue:(int32_t)value;
+ (instancetype)arrayWithValueArray:(GPBEnumArray *)array;
+ (instancetype)arrayWithValidationFunction:(GPBEnumValidationFunc)func
capacity:(NSUInteger)count;
- (instancetype)initWithValidationFunction:(GPBEnumValidationFunc)func;
// Initializes the array, copying the values.
- (instancetype)initWithValidationFunction:(GPBEnumValidationFunc)func
rawValues:(const int32_t [])values
count:(NSUInteger)count NS_DESIGNATED_INITIALIZER;
- (instancetype)initWithValueArray:(GPBEnumArray *)array;
- (instancetype)initWithValidationFunction:(GPBEnumValidationFunc)func
capacity:(NSUInteger)count;
// These will return kGPBUnrecognizedEnumeratorValue if the value at index is not a
// valid enumerator as defined by validationFunc. If the actual value is
// desired, use "raw" version of the method.
- (int32_t)valueAtIndex:(NSUInteger)index;
- (void)enumerateValuesWithBlock:(void (^)(int32_t value, NSUInteger idx, BOOL *stop))block;
- (void)enumerateValuesWithOptions:(NSEnumerationOptions)opts
usingBlock:(void (^)(int32_t value, NSUInteger idx, BOOL *stop))block;
// These methods bypass the validationFunc to provide access to values that were not
// known at the time the binary was compiled.
- (int32_t)rawValueAtIndex:(NSUInteger)index;
- (void)enumerateRawValuesWithBlock:(void (^)(int32_t value, NSUInteger idx, BOOL *stop))block;
- (void)enumerateRawValuesWithOptions:(NSEnumerationOptions)opts
usingBlock:(void (^)(int32_t value, NSUInteger idx, BOOL *stop))block;
// If value is not a valid enumerator as defined by validationFunc, these
// methods will assert in debug, and will log in release and assign the value
// to the default value. Use the rawValue methods below to assign non enumerator
// values.
- (void)addValue:(int32_t)value;
- (void)addValues:(const int32_t [])values count:(NSUInteger)count;
- (void)insertValue:(int32_t)value atIndex:(NSUInteger)index;
- (void)replaceValueAtIndex:(NSUInteger)index withValue:(int32_t)value;
// These methods bypass the validationFunc to provide setting of values that were not
// known at the time the binary was compiled.
- (void)addRawValue:(int32_t)value;
- (void)addRawValuesFromArray:(GPBEnumArray *)array;
- (void)addRawValues:(const int32_t [])values count:(NSUInteger)count;
- (void)insertRawValue:(int32_t)value atIndex:(NSUInteger)index;
- (void)replaceValueAtIndex:(NSUInteger)index withRawValue:(int32_t)value;
// No validation applies to these methods.
- (void)removeValueAtIndex:(NSUInteger)index;
- (void)removeAll;
- (void)exchangeValueAtIndex:(NSUInteger)idx1
withValueAtIndex:(NSUInteger)idx2;
@end
//%PDDM-EXPAND-END DECLARE_ARRAYS()
//%PDDM-DEFINE DECLARE_ARRAYS()
//%ARRAY_INTERFACE_SIMPLE(Int32, int32_t)
//%ARRAY_INTERFACE_SIMPLE(UInt32, uint32_t)
//%ARRAY_INTERFACE_SIMPLE(Int64, int64_t)
//%ARRAY_INTERFACE_SIMPLE(UInt64, uint64_t)
//%ARRAY_INTERFACE_SIMPLE(Float, float)
//%ARRAY_INTERFACE_SIMPLE(Double, double)
//%ARRAY_INTERFACE_SIMPLE(Bool, BOOL)
//%ARRAY_INTERFACE_ENUM(Enum, int32_t)
//
// The common case (everything but Enum)
//
//%PDDM-DEFINE ARRAY_INTERFACE_SIMPLE(NAME, TYPE)
//%#pragma mark - NAME
//%
//%@interface GPB##NAME##Array : NSObject <NSCopying>
//%
//%@property(nonatomic, readonly) NSUInteger count;
//%
//%+ (instancetype)array;
//%+ (instancetype)arrayWithValue:(TYPE)value;
//%+ (instancetype)arrayWithValueArray:(GPB##NAME##Array *)array;
//%+ (instancetype)arrayWithCapacity:(NSUInteger)count;
//%
//%// Initializes the array, copying the values.
//%- (instancetype)initWithValues:(const TYPE [])values
//% count:(NSUInteger)count NS_DESIGNATED_INITIALIZER;
//%- (instancetype)initWithValueArray:(GPB##NAME##Array *)array;
//%- (instancetype)initWithCapacity:(NSUInteger)count;
//%
//%ARRAY_IMMUTABLE_INTERFACE(NAME, TYPE, Basic)
//%
//%ARRAY_MUTABLE_INTERFACE(NAME, TYPE, Basic)
//%
//%@end
//%
//
// Macros specific to Enums (to tweak their interface).
//
//%PDDM-DEFINE ARRAY_INTERFACE_ENUM(NAME, TYPE)
//%#pragma mark - NAME
//%
//%@interface GPB##NAME##Array : NSObject <NSCopying>
//%
//%@property(nonatomic, readonly) NSUInteger count;
//%@property(nonatomic, readonly) GPBEnumValidationFunc validationFunc;
//%
//%+ (instancetype)array;
//%+ (instancetype)arrayWithValidationFunction:(GPBEnumValidationFunc)func;
//%+ (instancetype)arrayWithValidationFunction:(GPBEnumValidationFunc)func
//% rawValue:(TYPE)value;
//%+ (instancetype)arrayWithValueArray:(GPB##NAME##Array *)array;
//%+ (instancetype)arrayWithValidationFunction:(GPBEnumValidationFunc)func
//% capacity:(NSUInteger)count;
//%
//%- (instancetype)initWithValidationFunction:(GPBEnumValidationFunc)func;
//%
//%// Initializes the array, copying the values.
//%- (instancetype)initWithValidationFunction:(GPBEnumValidationFunc)func
//% rawValues:(const TYPE [])values
//% count:(NSUInteger)count NS_DESIGNATED_INITIALIZER;
//%- (instancetype)initWithValueArray:(GPB##NAME##Array *)array;
//%- (instancetype)initWithValidationFunction:(GPBEnumValidationFunc)func
//% capacity:(NSUInteger)count;
//%
//%// These will return kGPBUnrecognizedEnumeratorValue if the value at index is not a
//%// valid enumerator as defined by validationFunc. If the actual value is
//%// desired, use "raw" version of the method.
//%
//%ARRAY_IMMUTABLE_INTERFACE(NAME, TYPE, NAME)
//%
//%// These methods bypass the validationFunc to provide access to values that were not
//%// known at the time the binary was compiled.
//%
//%- (TYPE)rawValueAtIndex:(NSUInteger)index;
//%
//%- (void)enumerateRawValuesWithBlock:(void (^)(TYPE value, NSUInteger idx, BOOL *stop))block;
//%- (void)enumerateRawValuesWithOptions:(NSEnumerationOptions)opts
//% usingBlock:(void (^)(TYPE value, NSUInteger idx, BOOL *stop))block;
//%
//%// If value is not a valid enumerator as defined by validationFunc, these
//%// methods will assert in debug, and will log in release and assign the value
//%// to the default value. Use the rawValue methods below to assign non enumerator
//%// values.
//%
//%ARRAY_MUTABLE_INTERFACE(NAME, TYPE, NAME)
//%
//%@end
//%
//%PDDM-DEFINE ARRAY_IMMUTABLE_INTERFACE(NAME, TYPE, HELPER_NAME)
//%- (TYPE)valueAtIndex:(NSUInteger)index;
//%
//%- (void)enumerateValuesWithBlock:(void (^)(TYPE value, NSUInteger idx, BOOL *stop))block;
//%- (void)enumerateValuesWithOptions:(NSEnumerationOptions)opts
//% usingBlock:(void (^)(TYPE value, NSUInteger idx, BOOL *stop))block;
//%PDDM-DEFINE ARRAY_MUTABLE_INTERFACE(NAME, TYPE, HELPER_NAME)
//%- (void)addValue:(TYPE)value;
//%- (void)addValues:(const TYPE [])values count:(NSUInteger)count;
//%ARRAY_EXTRA_MUTABLE_METHODS1_##HELPER_NAME(NAME, TYPE)
//%- (void)insertValue:(TYPE)value atIndex:(NSUInteger)index;
//%
//%- (void)replaceValueAtIndex:(NSUInteger)index withValue:(TYPE)value;
//%ARRAY_EXTRA_MUTABLE_METHODS2_##HELPER_NAME(NAME, TYPE)
//%- (void)removeValueAtIndex:(NSUInteger)index;
//%- (void)removeAll;
//%
//%- (void)exchangeValueAtIndex:(NSUInteger)idx1
//% withValueAtIndex:(NSUInteger)idx2;
//
// These are hooks invoked by the above to do insert as needed.
//
//%PDDM-DEFINE ARRAY_EXTRA_MUTABLE_METHODS1_Basic(NAME, TYPE)
//%- (void)addValuesFromArray:(GPB##NAME##Array *)array;
//%
//%PDDM-DEFINE ARRAY_EXTRA_MUTABLE_METHODS2_Basic(NAME, TYPE)
// Empty
//%PDDM-DEFINE ARRAY_EXTRA_MUTABLE_METHODS1_Enum(NAME, TYPE)
// Empty
//%PDDM-DEFINE ARRAY_EXTRA_MUTABLE_METHODS2_Enum(NAME, TYPE)
//%
//%// These methods bypass the validationFunc to provide setting of values that were not
//%// known at the time the binary was compiled.
//%
//%- (void)addRawValue:(TYPE)value;
//%- (void)addRawValuesFromArray:(GPB##NAME##Array *)array;
//%- (void)addRawValues:(const TYPE [])values count:(NSUInteger)count;
//%
//%- (void)insertRawValue:(TYPE)value atIndex:(NSUInteger)index;
//%
//%- (void)replaceValueAtIndex:(NSUInteger)index withRawValue:(TYPE)value;
//%
//%// No validation applies to these methods.
//%

File diff suppressed because it is too large Load Diff

@ -0,0 +1,130 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2015 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 "GPBArray.h"
@class GPBMessage;
//%PDDM-DEFINE DECLARE_ARRAY_EXTRAS()
//%ARRAY_INTERFACE_EXTRAS(Int32, int32_t)
//%ARRAY_INTERFACE_EXTRAS(UInt32, uint32_t)
//%ARRAY_INTERFACE_EXTRAS(Int64, int64_t)
//%ARRAY_INTERFACE_EXTRAS(UInt64, uint64_t)
//%ARRAY_INTERFACE_EXTRAS(Float, float)
//%ARRAY_INTERFACE_EXTRAS(Double, double)
//%ARRAY_INTERFACE_EXTRAS(Bool, BOOL)
//%ARRAY_INTERFACE_EXTRAS(Enum, int32_t)
//%PDDM-DEFINE ARRAY_INTERFACE_EXTRAS(NAME, TYPE)
//%#pragma mark - NAME
//%
//%@interface GPB##NAME##Array () {
//% @package
//% GPB_UNSAFE_UNRETAINED GPBMessage *_autocreator;
//%}
//%@end
//%
//%PDDM-EXPAND DECLARE_ARRAY_EXTRAS()
// This block of code is generated, do not edit it directly.
#pragma mark - Int32
@interface GPBInt32Array () {
@package
GPB_UNSAFE_UNRETAINED GPBMessage *_autocreator;
}
@end
#pragma mark - UInt32
@interface GPBUInt32Array () {
@package
GPB_UNSAFE_UNRETAINED GPBMessage *_autocreator;
}
@end
#pragma mark - Int64
@interface GPBInt64Array () {
@package
GPB_UNSAFE_UNRETAINED GPBMessage *_autocreator;
}
@end
#pragma mark - UInt64
@interface GPBUInt64Array () {
@package
GPB_UNSAFE_UNRETAINED GPBMessage *_autocreator;
}
@end
#pragma mark - Float
@interface GPBFloatArray () {
@package
GPB_UNSAFE_UNRETAINED GPBMessage *_autocreator;
}
@end
#pragma mark - Double
@interface GPBDoubleArray () {
@package
GPB_UNSAFE_UNRETAINED GPBMessage *_autocreator;
}
@end
#pragma mark - Bool
@interface GPBBoolArray () {
@package
GPB_UNSAFE_UNRETAINED GPBMessage *_autocreator;
}
@end
#pragma mark - Enum
@interface GPBEnumArray () {
@package
GPB_UNSAFE_UNRETAINED GPBMessage *_autocreator;
}
@end
//%PDDM-EXPAND-END DECLARE_ARRAY_EXTRAS()
#pragma mark - NSArray Subclass
@interface GPBAutocreatedArray : NSMutableArray {
@package
GPB_UNSAFE_UNRETAINED GPBMessage *_autocreator;
}
@end

@ -0,0 +1,84 @@
// 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.
// The Objective C runtime has complete enough info that most protos don’t end
// up using this, so leaving it on is no cost or very little cost. If you
// happen to see it causing bloat, this is the way to disable it. If you do
// need to disable it, try only disabling it for Release builds as having
// full TextFormat can be useful for debugging.
#ifndef GPBOBJC_SKIP_MESSAGE_TEXTFORMAT_EXTRAS
#define GPBOBJC_SKIP_MESSAGE_TEXTFORMAT_EXTRAS 0
#endif
// Most uses of protocol buffers don't need field options, by default the
// static data will be compiled out, define this to 1 to include it. The only
// time you need this is if you are doing introspection of the protocol buffers.
#ifndef GPBOBJC_INCLUDE_FIELD_OPTIONS
#define GPBOBJC_INCLUDE_FIELD_OPTIONS 0
#endif
// Used in the generated code to give sizes to enums. int32_t was chosen based
// on the fact that Protocol Buffers enums are limited to this range.
// The complexity and double definition here are so we get the nice name
// for objective C, but also define the name with a trailing underscore so
// 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:
// GPB_ENUM_FWD_DECLARE(Foo_Enum)
// @property (nonatomic) Foo_Enum value;
#define GPB_ENUM_FWD_DECLARE(_name) enum _name : int32_t
// Based upon CF_INLINE. Forces inlining in release.
#if !defined(DEBUG)
#define GPB_INLINE static __inline__ __attribute__((always_inline))
#else
#define GPB_INLINE static __inline__
#endif
// For use in public headers that might need to deal with ARC.
#ifndef GPB_UNSAFE_UNRETAINED
#if __has_feature(objc_arc)
#define GPB_UNSAFE_UNRETAINED __unsafe_unretained
#else
#define GPB_UNSAFE_UNRETAINED
#endif
#endif
// 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
#define GPB_METHOD_FAMILY_NONE __attribute__((objc_method_family(none)))
// The protoc-gen-objc version which works with the current version of the
// generated Objective C sources. In general we don't want to change the
// runtime interfaces (or this version) as it means everything has to be
// regenerated.
#define GOOGLE_PROTOBUF_OBJC_GEN_VERSION 30000

@ -0,0 +1,81 @@
// 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>
@class GPBMessage;
@class GPBExtensionRegistry;
// Reads and decodes protocol message fields.
// Subclassing of GPBCodedInputStream is NOT supported.
@interface GPBCodedInputStream : NSObject
+ (instancetype)streamWithData:(NSData *)data;
- (instancetype)initWithData:(NSData *)data;
// Attempt to read a field tag, returning zero if we have reached EOF.
// Protocol message parsers use this to read tags, since a protocol message
// may legally end wherever a tag occurs, and zero is not a valid tag number.
- (int32_t)readTag;
- (double)readDouble;
- (float)readFloat;
- (uint64_t)readUInt64;
- (uint32_t)readUInt32;
- (int64_t)readInt64;
- (int32_t)readInt32;
- (uint64_t)readFixed64;
- (uint32_t)readFixed32;
- (int32_t)readEnum;
- (int32_t)readSFixed32;
- (int64_t)readSFixed64;
- (int32_t)readSInt32;
- (int64_t)readSInt64;
- (BOOL)readBool;
- (NSString *)readString;
- (NSData *)readData;
// Read an embedded message field value from the stream.
- (void)readMessage:(GPBMessage *)message
extensionRegistry:(GPBExtensionRegistry *)extensionRegistry;
// Reads and discards a single field, given its tag value.
- (BOOL)skipField:(int32_t)tag;
// Reads and discards an entire message. This will read either until EOF
// or until an endgroup tag, whichever comes first.
- (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.
- (void)checkLastTagWas:(int32_t)value;
@end

@ -0,0 +1,801 @@
// 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 "GPBCodedInputStream_PackagePrivate.h"
#import "GPBDictionary_PackagePrivate.h"
#import "GPBMessage_PackagePrivate.h"
#import "GPBUnknownFieldSet_PackagePrivate.h"
#import "GPBUtilities_PackagePrivate.h"
#import "GPBWireFormat.h"
static const NSUInteger kDefaultRecursionLimit = 64;
static inline void CheckSize(GPBCodedInputStreamState *state, size_t size) {
size_t newSize = state->bufferPos + size;
if (newSize > state->bufferSize) {
[NSException raise:NSParseErrorException format:@""];
}
if (newSize > state->currentLimit) {
// Fast forward to end of currentLimit;
state->bufferPos = state->currentLimit;
[NSException raise:NSParseErrorException format:@""];
}
}
static inline int8_t ReadRawByte(GPBCodedInputStreamState *state) {
CheckSize(state, sizeof(int8_t));
return ((int8_t *)state->bytes)[state->bufferPos++];
}
static inline int32_t ReadRawLittleEndian32(GPBCodedInputStreamState *state) {
CheckSize(state, sizeof(int32_t));
int32_t value = OSReadLittleInt32(state->bytes, state->bufferPos);
state->bufferPos += sizeof(int32_t);
return value;
}
static inline int64_t ReadRawLittleEndian64(GPBCodedInputStreamState *state) {
CheckSize(state, sizeof(int64_t));
int64_t value = OSReadLittleInt64(state->bytes, state->bufferPos);
state->bufferPos += sizeof(int64_t);
return value;
}
static inline int32_t ReadRawVarint32(GPBCodedInputStreamState *state) {
int8_t tmp = ReadRawByte(state);
if (tmp >= 0) {
return tmp;
}
int32_t result = tmp & 0x7f;
if ((tmp = ReadRawByte(state)) >= 0) {
result |= tmp << 7;
} else {
result |= (tmp & 0x7f) << 7;
if ((tmp = ReadRawByte(state)) >= 0) {
result |= tmp << 14;
} else {
result |= (tmp & 0x7f) << 14;
if ((tmp = ReadRawByte(state)) >= 0) {
result |= tmp << 21;
} else {
result |= (tmp & 0x7f) << 21;
result |= (tmp = ReadRawByte(state)) << 28;
if (tmp < 0) {
// Discard upper 32 bits.
for (int i = 0; i < 5; i++) {
if (ReadRawByte(state) >= 0) {
return result;
}
}
[NSException raise:NSParseErrorException
format:@"Unable to read varint32"];
}
}
}
}
return result;
}
static inline int64_t ReadRawVarint64(GPBCodedInputStreamState *state) {
int32_t shift = 0;
int64_t result = 0;
while (shift < 64) {
int8_t b = ReadRawByte(state);
result |= (int64_t)(b & 0x7F) << shift;
if ((b & 0x80) == 0) {
return result;
}
shift += 7;
}
[NSException raise:NSParseErrorException format:@"Unable to read varint64"];
return 0;
}
static inline void SkipRawData(GPBCodedInputStreamState *state, size_t size) {
CheckSize(state, size);
state->bufferPos += size;
}
double GPBCodedInputStreamReadDouble(GPBCodedInputStreamState *state) {
int64_t value = ReadRawLittleEndian64(state);
return GPBConvertInt64ToDouble(value);
}
float GPBCodedInputStreamReadFloat(GPBCodedInputStreamState *state) {
int32_t value = ReadRawLittleEndian32(state);
return GPBConvertInt32ToFloat(value);
}
uint64_t GPBCodedInputStreamReadUInt64(GPBCodedInputStreamState *state) {
uint64_t value = ReadRawVarint64(state);
return value;
}
uint32_t GPBCodedInputStreamReadUInt32(GPBCodedInputStreamState *state) {
uint32_t value = ReadRawVarint32(state);
return value;
}
int64_t GPBCodedInputStreamReadInt64(GPBCodedInputStreamState *state) {
int64_t value = ReadRawVarint64(state);
return value;
}
int32_t GPBCodedInputStreamReadInt32(GPBCodedInputStreamState *state) {
int32_t value = ReadRawVarint32(state);
return value;
}
uint64_t GPBCodedInputStreamReadFixed64(GPBCodedInputStreamState *state) {
uint64_t value = ReadRawLittleEndian64(state);
return value;
}
uint32_t GPBCodedInputStreamReadFixed32(GPBCodedInputStreamState *state) {
uint32_t value = ReadRawLittleEndian32(state);
return value;
}
int32_t GPBCodedInputStreamReadEnum(GPBCodedInputStreamState *state) {
int32_t value = ReadRawVarint32(state);
return value;
}
int32_t GPBCodedInputStreamReadSFixed32(GPBCodedInputStreamState *state) {
int32_t value = ReadRawLittleEndian32(state);
return value;
}
int64_t GPBCodedInputStreamReadSFixed64(GPBCodedInputStreamState *state) {
int64_t value = ReadRawLittleEndian64(state);
return value;
}
int32_t GPBCodedInputStreamReadSInt32(GPBCodedInputStreamState *state) {
int32_t value = GPBDecodeZigZag32(ReadRawVarint32(state));
return value;
}
int64_t GPBCodedInputStreamReadSInt64(GPBCodedInputStreamState *state) {
int64_t value = GPBDecodeZigZag64(ReadRawVarint64(state));
return value;
}
BOOL GPBCodedInputStreamReadBool(GPBCodedInputStreamState *state) {
return ReadRawVarint32(state) != 0;
}
int32_t GPBCodedInputStreamReadTag(GPBCodedInputStreamState *state) {
if (GPBCodedInputStreamIsAtEnd(state)) {
state->lastTag = 0;
return 0;
}
state->lastTag = ReadRawVarint32(state);
if (state->lastTag == 0) {
// If we actually read zero, that's not a valid tag.
[NSException raise:NSParseErrorException
format:@"Invalid last tag %d", state->lastTag];
}
return state->lastTag;
}
NSString *GPBCodedInputStreamReadRetainedString(
GPBCodedInputStreamState *state) {
int32_t size = ReadRawVarint32(state);
NSString *result;
if (size == 0) {
result = @"";
} else {
CheckSize(state, size);
result = GPBCreateGPBStringWithUTF8(&state->bytes[state->bufferPos], size);
state->bufferPos += size;
}
return result;
}
NSData *GPBCodedInputStreamReadRetainedData(GPBCodedInputStreamState *state) {
int32_t size = ReadRawVarint32(state);
if (size < 0) return nil;
CheckSize(state, size);
NSData *result = [[NSData alloc] initWithBytes:state->bytes + state->bufferPos
length:size];
state->bufferPos += size;
return result;
}
NSData *GPBCodedInputStreamReadRetainedDataNoCopy(
GPBCodedInputStreamState *state) {
int32_t size = ReadRawVarint32(state);
if (size < 0) return nil;
CheckSize(state, size);
// Cast is safe because freeWhenDone is NO.
NSData *result = [[NSData alloc]
initWithBytesNoCopy:(void *)(state->bytes + state->bufferPos)
length:size
freeWhenDone:NO];
state->bufferPos += size;
return result;
}
size_t GPBCodedInputStreamPushLimit(GPBCodedInputStreamState *state,
size_t byteLimit) {
byteLimit += state->bufferPos;
size_t oldLimit = state->currentLimit;
if (byteLimit > oldLimit) {
[NSException raise:NSInvalidArgumentException
format:@"byteLimit > oldLimit: %tu > %tu", byteLimit, oldLimit];
}
state->currentLimit = byteLimit;
return oldLimit;
}
void GPBCodedInputStreamPopLimit(GPBCodedInputStreamState *state,
size_t oldLimit) {
state->currentLimit = oldLimit;
}
size_t GPBCodedInputStreamBytesUntilLimit(GPBCodedInputStreamState *state) {
if (state->currentLimit == SIZE_T_MAX) {
return state->currentLimit;
}
return state->currentLimit - state->bufferPos;
}
BOOL GPBCodedInputStreamIsAtEnd(GPBCodedInputStreamState *state) {
return (state->bufferPos == state->bufferSize) ||
(state->bufferPos == state->currentLimit);
}
void GPBCodedInputStreamCheckLastTagWas(GPBCodedInputStreamState *state,
int32_t value) {
if (state->lastTag != value) {
[NSException raise:NSParseErrorException
format:@"Last tag: %d should be %d", state->lastTag, value];
}
}
@implementation GPBCodedInputStream
+ (instancetype)streamWithData:(NSData *)data {
return [[[self alloc] initWithData:data] autorelease];
}
- (instancetype)initWithData:(NSData *)data {
if ((self = [super init])) {
#ifdef DEBUG
NSCAssert([self class] == [GPBCodedInputStream class],
@"Subclassing of GPBCodedInputStream is not allowed.");
#endif
buffer_ = [data retain];
state_.bytes = (const uint8_t *)[data bytes];
state_.bufferSize = [data length];
state_.currentLimit = NSUIntegerMax;
}
return self;
}
- (void)dealloc {
[buffer_ release];
[super dealloc];
}
- (int32_t)readTag {
return GPBCodedInputStreamReadTag(&state_);
}
- (void)checkLastTagWas:(int32_t)value {
GPBCodedInputStreamCheckLastTagWas(&state_, value);
}
- (BOOL)skipField:(int32_t)tag {
switch (GPBWireFormatGetTagWireType(tag)) {
case GPBWireFormatVarint:
GPBCodedInputStreamReadInt32(&state_);
return YES;
case GPBWireFormatFixed64:
SkipRawData(&state_, sizeof(int64_t));
return YES;
case GPBWireFormatLengthDelimited:
SkipRawData(&state_, ReadRawVarint32(&state_));
return YES;
case GPBWireFormatStartGroup:
[self skipMessage];
GPBCodedInputStreamCheckLastTagWas(
&state_, GPBWireFormatMakeTag(GPBWireFormatGetTagFieldNumber(tag),
GPBWireFormatEndGroup));
return YES;
case GPBWireFormatEndGroup:
return NO;
case GPBWireFormatFixed32:
SkipRawData(&state_, sizeof(int32_t));
return YES;
}
[NSException raise:NSParseErrorException format:@"Invalid tag %d", tag];
return NO;
}
- (void)skipMessage {
while (YES) {
int32_t tag = GPBCodedInputStreamReadTag(&state_);
if (tag == 0 || ![self skipField:tag]) {
return;
}
}
}
- (double)readDouble {
return GPBCodedInputStreamReadDouble(&state_);
}
- (float)readFloat {
return GPBCodedInputStreamReadFloat(&state_);
}
- (uint64_t)readUInt64 {
return GPBCodedInputStreamReadUInt64(&state_);
}
- (int64_t)readInt64 {
return GPBCodedInputStreamReadInt64(&state_);
}
- (int32_t)readInt32 {
return GPBCodedInputStreamReadInt32(&state_);
}
- (uint64_t)readFixed64 {
return GPBCodedInputStreamReadFixed64(&state_);
}
- (uint32_t)readFixed32 {
return GPBCodedInputStreamReadFixed32(&state_);
}
- (BOOL)readBool {
return GPBCodedInputStreamReadBool(&state_);
}
- (NSString *)readString {
return [GPBCodedInputStreamReadRetainedString(&state_) autorelease];
}
- (void)readGroup:(int32_t)fieldNumber
message:(GPBMessage *)message
extensionRegistry:(GPBExtensionRegistry *)extensionRegistry {
if (state_.recursionDepth >= kDefaultRecursionLimit) {
[NSException raise:NSParseErrorException
format:@"recursionDepth(%tu) >= %tu", state_.recursionDepth,
kDefaultRecursionLimit];
}
++state_.recursionDepth;
[message mergeFromCodedInputStream:self extensionRegistry:extensionRegistry];
GPBCodedInputStreamCheckLastTagWas(
&state_, GPBWireFormatMakeTag(fieldNumber, GPBWireFormatEndGroup));
--state_.recursionDepth;
}
- (void)readUnknownGroup:(int32_t)fieldNumber
message:(GPBUnknownFieldSet *)message {
if (state_.recursionDepth >= kDefaultRecursionLimit) {
[NSException raise:NSParseErrorException
format:@"recursionDepth(%tu) >= %tu", state_.recursionDepth,
kDefaultRecursionLimit];
}
++state_.recursionDepth;
[message mergeFromCodedInputStream:self];
GPBCodedInputStreamCheckLastTagWas(
&state_, GPBWireFormatMakeTag(fieldNumber, GPBWireFormatEndGroup));
--state_.recursionDepth;
}
- (void)readMessage:(GPBMessage *)message
extensionRegistry:(GPBExtensionRegistry *)extensionRegistry {
int32_t length = ReadRawVarint32(&state_);
if (state_.recursionDepth >= kDefaultRecursionLimit) {
[NSException raise:NSParseErrorException
format:@"recursionDepth(%tu) >= %tu", state_.recursionDepth,
kDefaultRecursionLimit];
}
size_t oldLimit = GPBCodedInputStreamPushLimit(&state_, length);
++state_.recursionDepth;
[message mergeFromCodedInputStream:self extensionRegistry:extensionRegistry];
GPBCodedInputStreamCheckLastTagWas(&state_, 0);
--state_.recursionDepth;
GPBCodedInputStreamPopLimit(&state_, oldLimit);
}
- (void)readMapEntry:(id)mapDictionary
extensionRegistry:(GPBExtensionRegistry *)extensionRegistry
field:(GPBFieldDescriptor *)field
parentMessage:(GPBMessage *)parentMessage {
int32_t length = ReadRawVarint32(&state_);
if (state_.recursionDepth >= kDefaultRecursionLimit) {
[NSException raise:NSParseErrorException
format:@"recursionDepth(%tu) >= %tu", state_.recursionDepth,
kDefaultRecursionLimit];
}
size_t oldLimit = GPBCodedInputStreamPushLimit(&state_, length);
++state_.recursionDepth;
GPBDictionaryReadEntry(mapDictionary, self, extensionRegistry, field,
parentMessage);
GPBCodedInputStreamCheckLastTagWas(&state_, 0);
--state_.recursionDepth;
GPBCodedInputStreamPopLimit(&state_, oldLimit);
}
- (NSData *)readData {
return [GPBCodedInputStreamReadRetainedData(&state_) autorelease];
}
- (uint32_t)readUInt32 {
return GPBCodedInputStreamReadUInt32(&state_);
}
- (int32_t)readEnum {
return GPBCodedInputStreamReadEnum(&state_);
}
- (int32_t)readSFixed32 {
return GPBCodedInputStreamReadSFixed32(&state_);
}
- (int64_t)readSFixed64 {
return GPBCodedInputStreamReadSFixed64(&state_);
}
- (int32_t)readSInt32 {
return GPBCodedInputStreamReadSInt32(&state_);
}
- (int64_t)readSInt64 {
return GPBCodedInputStreamReadSInt64(&state_);
}
@end
@implementation GPBString {
@package
CFStringRef string_;
unsigned char *utf8_;
NSUInteger utf8Len_;
// This lock is used to gate access to utf8_. Once GPBStringInitStringValue()
// has been called, string_ will be filled in, and utf8_ will be NULL.
OSSpinLock lock_;
BOOL hasBOM_;
BOOL is7BitAscii_;
}
// Returns true if the passed in bytes are 7 bit ascii.
// This routine needs to be fast.
static inline bool AreBytesIn7BitASCII(const uint8_t *bytes, NSUInteger len) {
// In the loops below, it's more efficient to collect rather than do
// conditional at every step.
#if __LP64__
// Align bytes. This is especially important in case of 3 byte BOM.
while (len > 0 && ((size_t)bytes & 0x07)) {
if (*bytes++ & 0x80) return false;
len--;
}
while (len >= 32) {
uint64_t val = *(const uint64_t *)bytes;
uint64_t hiBits = (val & 0x8080808080808080ULL);
bytes += 8;
val = *(const uint64_t *)bytes;
hiBits |= (val & 0x8080808080808080ULL);
bytes += 8;
val = *(const uint64_t *)bytes;
hiBits |= (val & 0x8080808080808080ULL);
bytes += 8;
val = *(const uint64_t *)bytes;
if (hiBits | (val & 0x8080808080808080ULL)) return false;
bytes += 8;
len -= 32;
}
while (len >= 16) {
uint64_t val = *(const uint64_t *)bytes;
uint64_t hiBits = (val & 0x8080808080808080ULL);
bytes += 8;
val = *(const uint64_t *)bytes;
if (hiBits | (val & 0x8080808080808080ULL)) return false;
bytes += 8;
len -= 16;
}
while (len >= 8) {
uint64_t val = *(const uint64_t *)bytes;
if (val & 0x8080808080808080ULL) return false;
bytes += 8;
len -= 8;
}
#else // __LP64__
// Align bytes. This is especially important in case of 3 byte BOM.
while (len > 0 && ((size_t)bytes & 0x03)) {
if (*bytes++ & 0x80) return false;
len--;
}
while (len >= 16) {
uint32_t val = *(const uint32_t *)bytes;
uint32_t hiBits = (val & 0x80808080U);
bytes += 4;
val = *(const uint32_t *)bytes;
hiBits |= (val & 0x80808080U);
bytes += 4;
val = *(const uint32_t *)bytes;
hiBits |= (val & 0x80808080U);
bytes += 4;
val = *(const uint32_t *)bytes;
if (hiBits | (val & 0x80808080U)) return false;
bytes += 4;
len -= 16;
}
while (len >= 8) {
uint32_t val = *(const uint32_t *)bytes;
uint32_t hiBits = (val & 0x80808080U);
bytes += 4;
val = *(const uint32_t *)bytes;
if (hiBits | (val & 0x80808080U)) return false;
bytes += 4;
len -= 8;
}
#endif // __LP64__
while (len >= 4) {
uint32_t val = *(const uint32_t *)bytes;
if (val & 0x80808080U) return false;
bytes += 4;
len -= 4;
}
while (len--) {
if (*bytes++ & 0x80) return false;
}
return true;
}
static inline void GPBStringInitStringValue(GPBString *string) {
OSSpinLockLock(&string->lock_);
GPBStringInitStringValueAlreadyLocked(string);
OSSpinLockUnlock(&string->lock_);
}
static void GPBStringInitStringValueAlreadyLocked(GPBString *string) {
if (string->string_ == NULL && string->utf8_ != NULL) {
// Using kCFAllocatorMalloc for contentsDeallocator, as buffer in
// string->utf8_ is being handed off.
string->string_ = CFStringCreateWithBytesNoCopy(
NULL, string->utf8_, string->utf8Len_, kCFStringEncodingUTF8, false,
kCFAllocatorMalloc);
if (!string->string_) {
#ifdef DEBUG
// https://developers.google.com/protocol-buffers/docs/proto#scalar
NSLog(@"UTF8 failure, is some field type 'string' when it should be "
@"'bytes'?");
#endif
string->string_ = CFSTR("");
string->utf8Len_ = 0;
// On failure, we have to clean up the buffer.
free(string->utf8_);
}
string->utf8_ = NULL;
}
}
GPBString *GPBCreateGPBStringWithUTF8(const void *bytes, NSUInteger length) {
GPBString *result = [[GPBString alloc] initWithBytes:bytes length:length];
return result;
}
- (instancetype)initWithBytes:(const void *)bytes length:(NSUInteger)length {
self = [super init];
if (self) {
utf8_ = malloc(length);
memcpy(utf8_, bytes, length);
utf8Len_ = length;
lock_ = OS_SPINLOCK_INIT;
is7BitAscii_ = AreBytesIn7BitASCII(bytes, length);
if (length >= 3 && memcmp(utf8_, "\xef\xbb\xbf", 3) == 0) {
// We can't just remove the BOM from the string here, because in the case
// where we have > 1 BOM at the beginning of the string, we will remove one,
// and the internal NSString we create will remove the next one, and we will
// end up with a GPBString != NSString issue.
// We also just can't remove all the BOMs because then we would end up with
// potential cases where a GPBString and an NSString made with the same
// UTF8 buffer would in fact be different.
// We record the fact we have a BOM, and use it as necessary to simulate
// what NSString would return for various calls.
hasBOM_ = YES;
#if DEBUG
// Sending BOMs across the line is just wasting bits.
NSLog(@"Bad data? String should not have BOM!");
#endif // DEBUG
}
}
return self;
}
- (void)dealloc {
if (string_ != NULL) {
CFRelease(string_);
}
if (utf8_ != NULL) {
free(utf8_);
}
[super dealloc];
}
// Required NSString overrides.
- (NSUInteger)length {
if (is7BitAscii_) {
return utf8Len_;
} else {
GPBStringInitStringValue(self);
return CFStringGetLength(string_);
}
}
- (unichar)characterAtIndex:(NSUInteger)anIndex {
OSSpinLockLock(&lock_);
if (is7BitAscii_ && utf8_) {
unichar result = utf8_[anIndex];
OSSpinLockUnlock(&lock_);
return result;
} else {
GPBStringInitStringValueAlreadyLocked(self);
OSSpinLockUnlock(&lock_);
return CFStringGetCharacterAtIndex(string_, anIndex);
}
}
// Override a couple of methods that typically want high performance.
- (id)copyWithZone:(NSZone *)zone {
GPBStringInitStringValue(self);
return [(NSString *)string_ copyWithZone:zone];
}
- (id)mutableCopyWithZone:(NSZone *)zone {
GPBStringInitStringValue(self);
return [(NSString *)string_ mutableCopyWithZone:zone];
}
- (NSUInteger)hash {
// Must convert to string here to make sure that the hash is always
// consistent no matter what state the GPBString is in.
GPBStringInitStringValue(self);
return CFHash(string_);
}
- (BOOL)isEqual:(id)object {
if (self == object) {
return YES;
}
if ([object isKindOfClass:[NSString class]]) {
GPBStringInitStringValue(self);
return CFStringCompare(string_, (CFStringRef)object, 0) ==
kCFCompareEqualTo;
}
return NO;
}
- (void)getCharacters:(unichar *)buffer range:(NSRange)aRange {
OSSpinLockLock(&lock_);
if (is7BitAscii_ && utf8_) {
unsigned char *bytes = &(utf8_[aRange.location]);
for (NSUInteger i = 0; i < aRange.length; ++i) {
buffer[i] = bytes[i];
}
OSSpinLockUnlock(&lock_);
} else {
GPBStringInitStringValueAlreadyLocked(self);
OSSpinLockUnlock(&lock_);
CFStringGetCharacters(string_, CFRangeMake(aRange.location, aRange.length),
buffer);
}
}
- (NSUInteger)lengthOfBytesUsingEncoding:(NSStringEncoding)encoding {
if ((encoding == NSUTF8StringEncoding) ||
(encoding == NSASCIIStringEncoding && is7BitAscii_)) {
return utf8Len_ - (hasBOM_ ? 3 : 0);
} else {
GPBStringInitStringValue(self);
return [(NSString *)string_ lengthOfBytesUsingEncoding:encoding];
}
}
- (BOOL)getBytes:(void *)buffer
maxLength:(NSUInteger)maxLength
usedLength:(NSUInteger *)usedLength
encoding:(NSStringEncoding)encoding
options:(NSStringEncodingConversionOptions)options
range:(NSRange)range
remainingRange:(NSRangePointer)remainingRange {
// [NSString getBytes:maxLength:usedLength:encoding:options:range:remainingRange]
// does not return reliable results if the maxLength argument is 0
// (Radar 16385183). Therefore we have special cased it as a slow case so
// that it behaves however Apple intends it to behave. It should be a rare
// case.
//
// [NSString getBytes:maxLength:usedLength:encoding:options:range:remainingRange]
// does not return reliable results if the range is outside of the strings
// length (Radar 16396177). Therefore we have special cased it as a slow
// case so that it behaves however Apple intends it to behave. It should
// be a rare case.
//
// We can optimize the UTF8StringEncoding and NSASCIIStringEncoding with no
// options cases.
if ((options == 0) &&
(encoding == NSUTF8StringEncoding || encoding == NSASCIIStringEncoding) &&
(maxLength != 0) &&
(NSMaxRange(range) <= utf8Len_)) {
// Might be able to optimize it.
OSSpinLockLock(&lock_);
if (is7BitAscii_ && utf8_) {
NSUInteger length = range.length;
length = (length < maxLength) ? length : maxLength;
memcpy(buffer, utf8_ + range.location, length);
if (usedLength) {
*usedLength = length;
}
if (remainingRange) {
remainingRange->location = range.location + length;
remainingRange->length = range.length - length;
}
OSSpinLockUnlock(&lock_);
if (length > 0) {
return YES;
} else {
return NO;
}
} else {
GPBStringInitStringValueAlreadyLocked(self);
OSSpinLockUnlock(&lock_);
}
} else {
GPBStringInitStringValue(self);
}
return [(NSString *)string_ getBytes:buffer
maxLength:maxLength
usedLength:usedLength
encoding:encoding
options:options
range:range
remainingRange:remainingRange];
}
@end

@ -0,0 +1,131 @@
// 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.
// This header is private to the ProtobolBuffers library and must NOT be
// included by any sources outside this library. The contents of this file are
// subject to change at any time without notice.
#import "GPBCodedInputStream.h"
#import <libkern/OSAtomic.h>
@class GPBUnknownFieldSet;
@class GPBFieldDescriptor;
// GPBString is a string subclass that avoids the overhead of initializing
// a full NSString until it is actually needed. Lots of protocol buffers contain
// strings, and instantiating all of those strings and having them parsed to
// verify correctness when the message was being read was expensive, when many
// of the strings were never being used.
//
// Note for future-self. I tried implementing this using a NSProxy.
// Turned out the performance was horrible in client apps because folks
// like to use libraries like SBJSON that grab characters one at a time.
// The proxy overhead was a killer.
@interface GPBString : NSString
@end
typedef struct GPBCodedInputStreamState {
const uint8_t *bytes;
size_t bufferSize;
size_t bufferPos;
// For parsing subsections of an input stream you can put a hard limit on
// how much should be read. Normally the limit is the end of the stream,
// but you can adjust it to anywhere, and if you hit it you will be at the
// end of the stream, until you adjust the limit.
size_t currentLimit;
int32_t lastTag;
NSUInteger recursionDepth;
} GPBCodedInputStreamState;
@interface GPBCodedInputStream () {
@package
struct GPBCodedInputStreamState state_;
NSData *buffer_;
}
// Group support is deprecated, so we hide this interface from users, but
// support for older data.
- (void)readGroup:(int32_t)fieldNumber
message:(GPBMessage *)message
extensionRegistry:(GPBExtensionRegistry *)extensionRegistry;
// Reads a group field value from the stream and merges it into the given
// UnknownFieldSet.
- (void)readUnknownGroup:(int32_t)fieldNumber
message:(GPBUnknownFieldSet *)message;
// Reads a map entry.
- (void)readMapEntry:(id)mapDictionary
extensionRegistry:(GPBExtensionRegistry *)extensionRegistry
field:(GPBFieldDescriptor *)field
parentMessage:(GPBMessage *)parentMessage;
@end
CF_EXTERN_C_BEGIN
// Returns a GPBString with a +1 retain count.
GPBString *GPBCreateGPBStringWithUTF8(const void *bytes, NSUInteger length)
__attribute__((ns_returns_retained));
int32_t GPBCodedInputStreamReadTag(GPBCodedInputStreamState *state);
double GPBCodedInputStreamReadDouble(GPBCodedInputStreamState *state);
float GPBCodedInputStreamReadFloat(GPBCodedInputStreamState *state);
uint64_t GPBCodedInputStreamReadUInt64(GPBCodedInputStreamState *state);
uint32_t GPBCodedInputStreamReadUInt32(GPBCodedInputStreamState *state);
int64_t GPBCodedInputStreamReadInt64(GPBCodedInputStreamState *state);
int32_t GPBCodedInputStreamReadInt32(GPBCodedInputStreamState *state);
uint64_t GPBCodedInputStreamReadFixed64(GPBCodedInputStreamState *state);
uint32_t GPBCodedInputStreamReadFixed32(GPBCodedInputStreamState *state);
int32_t GPBCodedInputStreamReadEnum(GPBCodedInputStreamState *state);
int32_t GPBCodedInputStreamReadSFixed32(GPBCodedInputStreamState *state);
int64_t GPBCodedInputStreamReadSFixed64(GPBCodedInputStreamState *state);
int32_t GPBCodedInputStreamReadSInt32(GPBCodedInputStreamState *state);
int64_t GPBCodedInputStreamReadSInt64(GPBCodedInputStreamState *state);
BOOL GPBCodedInputStreamReadBool(GPBCodedInputStreamState *state);
NSString *GPBCodedInputStreamReadRetainedString(GPBCodedInputStreamState *state)
__attribute((ns_returns_retained));
NSData *GPBCodedInputStreamReadRetainedData(GPBCodedInputStreamState *state)
__attribute((ns_returns_retained));
NSData *GPBCodedInputStreamReadRetainedDataNoCopy(
GPBCodedInputStreamState *state) __attribute((ns_returns_retained));
size_t GPBCodedInputStreamPushLimit(GPBCodedInputStreamState *state,
size_t byteLimit);
void GPBCodedInputStreamPopLimit(GPBCodedInputStreamState *state,
size_t oldLimit);
size_t GPBCodedInputStreamBytesUntilLimit(GPBCodedInputStreamState *state);
BOOL GPBCodedInputStreamIsAtEnd(GPBCodedInputStreamState *state);
void GPBCodedInputStreamCheckLastTagWas(GPBCodedInputStreamState *state,
int32_t value);
CF_EXTERN_C_END

@ -0,0 +1,340 @@
// 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 "GPBTypes.h"
#import "GPBWireFormat.h"
@class GPBBoolArray;
@class GPBDoubleArray;
@class GPBEnumArray;
@class GPBFloatArray;
@class GPBMessage;
@class GPBInt32Array;
@class GPBInt64Array;
@class GPBUInt32Array;
@class GPBUInt64Array;
@class GPBUnknownFieldSet;
@interface GPBCodedOutputStream : NSObject
// Creates a new stream to write into data. Data must be sized to fit or it
// will error when it runs out of space.
+ (instancetype)streamWithData:(NSMutableData *)data;
+ (instancetype)streamWithOutputStream:(NSOutputStream *)output;
+ (instancetype)streamWithOutputStream:(NSOutputStream *)output
bufferSize:(size_t)bufferSize;
- (instancetype)initWithOutputStream:(NSOutputStream *)output;
- (instancetype)initWithData:(NSMutableData *)data;
- (instancetype)initWithOutputStream:(NSOutputStream *)output
bufferSize:(size_t)bufferSize;
- (instancetype)initWithOutputStream:(NSOutputStream *)output
data:(NSMutableData *)data;
- (void)flush;
- (void)writeRawByte:(uint8_t)value;
- (void)writeTag:(uint32_t)fieldNumber format:(GPBWireFormat)format;
- (void)writeRawLittleEndian32:(int32_t)value;
- (void)writeRawLittleEndian64:(int64_t)value;
- (void)writeRawVarint32:(int32_t)value;
- (void)writeRawVarint64:(int64_t)value;
// Note that this will truncate 64 bit values to 32.
- (void)writeRawVarintSizeTAs32:(size_t)value;
- (void)writeRawData:(NSData *)data;
- (void)writeRawPtr:(const void *)data
offset:(size_t)offset
length:(size_t)length;
//%PDDM-EXPAND _WRITE_DECLS()
// This block of code is generated, do not edit it directly.
- (void)writeDouble:(int32_t)fieldNumber value:(double)value;
- (void)writeDoubles:(int32_t)fieldNumber
values:(GPBDoubleArray *)values
tag:(uint32_t)tag;
- (void)writeDoubleNoTag:(double)value;
- (void)writeFloat:(int32_t)fieldNumber value:(float)value;
- (void)writeFloats:(int32_t)fieldNumber
values:(GPBFloatArray *)values
tag:(uint32_t)tag;
- (void)writeFloatNoTag:(float)value;
- (void)writeUInt64:(int32_t)fieldNumber value:(uint64_t)value;
- (void)writeUInt64s:(int32_t)fieldNumber
values:(GPBUInt64Array *)values
tag:(uint32_t)tag;
- (void)writeUInt64NoTag:(uint64_t)value;
- (void)writeInt64:(int32_t)fieldNumber value:(int64_t)value;
- (void)writeInt64s:(int32_t)fieldNumber
values:(GPBInt64Array *)values
tag:(uint32_t)tag;
- (void)writeInt64NoTag:(int64_t)value;
- (void)writeInt32:(int32_t)fieldNumber value:(int32_t)value;
- (void)writeInt32s:(int32_t)fieldNumber
values:(GPBInt32Array *)values
tag:(uint32_t)tag;
- (void)writeInt32NoTag:(int32_t)value;
- (void)writeUInt32:(int32_t)fieldNumber value:(uint32_t)value;
- (void)writeUInt32s:(int32_t)fieldNumber
values:(GPBUInt32Array *)values
tag:(uint32_t)tag;
- (void)writeUInt32NoTag:(uint32_t)value;
- (void)writeFixed64:(int32_t)fieldNumber value:(uint64_t)value;
- (void)writeFixed64s:(int32_t)fieldNumber
values:(GPBUInt64Array *)values
tag:(uint32_t)tag;
- (void)writeFixed64NoTag:(uint64_t)value;
- (void)writeFixed32:(int32_t)fieldNumber value:(uint32_t)value;
- (void)writeFixed32s:(int32_t)fieldNumber
values:(GPBUInt32Array *)values
tag:(uint32_t)tag;
- (void)writeFixed32NoTag:(uint32_t)value;
- (void)writeSInt32:(int32_t)fieldNumber value:(int32_t)value;
- (void)writeSInt32s:(int32_t)fieldNumber
values:(GPBInt32Array *)values
tag:(uint32_t)tag;
- (void)writeSInt32NoTag:(int32_t)value;
- (void)writeSInt64:(int32_t)fieldNumber value:(int64_t)value;
- (void)writeSInt64s:(int32_t)fieldNumber
values:(GPBInt64Array *)values
tag:(uint32_t)tag;
- (void)writeSInt64NoTag:(int64_t)value;
- (void)writeSFixed64:(int32_t)fieldNumber value:(int64_t)value;
- (void)writeSFixed64s:(int32_t)fieldNumber
values:(GPBInt64Array *)values
tag:(uint32_t)tag;
- (void)writeSFixed64NoTag:(int64_t)value;
- (void)writeSFixed32:(int32_t)fieldNumber value:(int32_t)value;
- (void)writeSFixed32s:(int32_t)fieldNumber
values:(GPBInt32Array *)values
tag:(uint32_t)tag;
- (void)writeSFixed32NoTag:(int32_t)value;
- (void)writeBool:(int32_t)fieldNumber value:(BOOL)value;
- (void)writeBools:(int32_t)fieldNumber
values:(GPBBoolArray *)values
tag:(uint32_t)tag;
- (void)writeBoolNoTag:(BOOL)value;
- (void)writeEnum:(int32_t)fieldNumber value:(int32_t)value;
- (void)writeEnums:(int32_t)fieldNumber
values:(GPBEnumArray *)values
tag:(uint32_t)tag;
- (void)writeEnumNoTag:(int32_t)value;
- (void)writeString:(int32_t)fieldNumber value:(NSString *)value;
- (void)writeStrings:(int32_t)fieldNumber values:(NSArray *)values;
- (void)writeStringNoTag:(NSString *)value;
- (void)writeMessage:(int32_t)fieldNumber value:(GPBMessage *)value;
- (void)writeMessages:(int32_t)fieldNumber values:(NSArray *)values;
- (void)writeMessageNoTag:(GPBMessage *)value;
- (void)writeData:(int32_t)fieldNumber value:(NSData *)value;
- (void)writeDatas:(int32_t)fieldNumber values:(NSArray *)values;
- (void)writeDataNoTag:(NSData *)value;
- (void)writeGroup:(int32_t)fieldNumber
value:(GPBMessage *)value;
- (void)writeGroups:(int32_t)fieldNumber values:(NSArray *)values;
- (void)writeGroupNoTag:(int32_t)fieldNumber
value:(GPBMessage *)value;
- (void)writeUnknownGroup:(int32_t)fieldNumber
value:(GPBUnknownFieldSet *)value;
- (void)writeUnknownGroups:(int32_t)fieldNumber values:(NSArray *)values;
- (void)writeUnknownGroupNoTag:(int32_t)fieldNumber
value:(GPBUnknownFieldSet *)value;
//%PDDM-EXPAND-END _WRITE_DECLS()
// Write a MessageSet extension field to the stream. For historical reasons,
// the wire format differs from normal fields.
- (void)writeMessageSetExtension:(int32_t)fieldNumber value:(GPBMessage *)value;
// Write an unparsed MessageSet extension field to the stream. For
// historical reasons, the wire format differs from normal fields.
- (void)writeRawMessageSetExtension:(int32_t)fieldNumber value:(NSData *)value;
@end
CF_EXTERN_C_BEGIN
size_t GPBComputeDoubleSize(int32_t fieldNumber, double value)
__attribute__((const));
size_t GPBComputeFloatSize(int32_t fieldNumber, float value)
__attribute__((const));
size_t GPBComputeUInt64Size(int32_t fieldNumber, uint64_t value)
__attribute__((const));
size_t GPBComputeInt64Size(int32_t fieldNumber, int64_t value)
__attribute__((const));
size_t GPBComputeInt32Size(int32_t fieldNumber, int32_t value)
__attribute__((const));
size_t GPBComputeFixed64Size(int32_t fieldNumber, uint64_t value)
__attribute__((const));
size_t GPBComputeFixed32Size(int32_t fieldNumber, uint32_t value)
__attribute__((const));
size_t GPBComputeBoolSize(int32_t fieldNumber, BOOL value)
__attribute__((const));
size_t GPBComputeStringSize(int32_t fieldNumber, NSString *value)
__attribute__((const));
size_t GPBComputeGroupSize(int32_t fieldNumber, GPBMessage *value)
__attribute__((const));
size_t GPBComputeUnknownGroupSize(int32_t fieldNumber,
GPBUnknownFieldSet *value)
__attribute__((const));
size_t GPBComputeMessageSize(int32_t fieldNumber, GPBMessage *value)
__attribute__((const));
size_t GPBComputeDataSize(int32_t fieldNumber, NSData *value)
__attribute__((const));
size_t GPBComputeUInt32Size(int32_t fieldNumber, uint32_t value)
__attribute__((const));
size_t GPBComputeSFixed32Size(int32_t fieldNumber, int32_t value)
__attribute__((const));
size_t GPBComputeSFixed64Size(int32_t fieldNumber, int64_t value)
__attribute__((const));
size_t GPBComputeSInt32Size(int32_t fieldNumber, int32_t value)
__attribute__((const));
size_t GPBComputeSInt64Size(int32_t fieldNumber, int64_t value)
__attribute__((const));
size_t GPBComputeTagSize(int32_t fieldNumber) __attribute__((const));
size_t GPBComputeWireFormatTagSize(int field_number, GPBType type)
__attribute__((const));
size_t GPBComputeDoubleSizeNoTag(double value) __attribute__((const));
size_t GPBComputeFloatSizeNoTag(float value) __attribute__((const));
size_t GPBComputeUInt64SizeNoTag(uint64_t value) __attribute__((const));
size_t GPBComputeInt64SizeNoTag(int64_t value) __attribute__((const));
size_t GPBComputeInt32SizeNoTag(int32_t value) __attribute__((const));
size_t GPBComputeFixed64SizeNoTag(uint64_t value) __attribute__((const));
size_t GPBComputeFixed32SizeNoTag(uint32_t value) __attribute__((const));
size_t GPBComputeBoolSizeNoTag(BOOL value) __attribute__((const));
size_t GPBComputeStringSizeNoTag(NSString *value) __attribute__((const));
size_t GPBComputeGroupSizeNoTag(GPBMessage *value) __attribute__((const));
size_t GPBComputeUnknownGroupSizeNoTag(GPBUnknownFieldSet *value)
__attribute__((const));
size_t GPBComputeMessageSizeNoTag(GPBMessage *value) __attribute__((const));
size_t GPBComputeDataSizeNoTag(NSData *value) __attribute__((const));
size_t GPBComputeUInt32SizeNoTag(int32_t value) __attribute__((const));
size_t GPBComputeEnumSizeNoTag(int32_t value) __attribute__((const));
size_t GPBComputeSFixed32SizeNoTag(int32_t value) __attribute__((const));
size_t GPBComputeSFixed64SizeNoTag(int64_t value) __attribute__((const));
size_t GPBComputeSInt32SizeNoTag(int32_t value) __attribute__((const));
size_t GPBComputeSInt64SizeNoTag(int64_t value) __attribute__((const));
// Note that this will calculate the size of 64 bit values truncated to 32.
size_t GPBComputeSizeTSizeAsInt32NoTag(size_t value) __attribute__((const));
size_t GPBComputeRawVarint32Size(int32_t value) __attribute__((const));
size_t GPBComputeRawVarint64Size(int64_t value) __attribute__((const));
// Note that this will calculate the size of 64 bit values truncated to 32.
size_t GPBComputeRawVarint32SizeForInteger(NSInteger value)
__attribute__((const));
// Compute the number of bytes that would be needed to encode a
// MessageSet extension to the stream. For historical reasons,
// the wire format differs from normal fields.
size_t GPBComputeMessageSetExtensionSize(int32_t fieldNumber, GPBMessage *value)
__attribute__((const));
// Compute the number of bytes that would be needed to encode an
// unparsed MessageSet extension field to the stream. For
// historical reasons, the wire format differs from normal fields.
size_t GPBComputeRawMessageSetExtensionSize(int32_t fieldNumber, NSData *value)
__attribute__((const));
size_t GPBComputeEnumSize(int32_t fieldNumber, int32_t value)
__attribute__((const));
CF_EXTERN_C_END
// Write methods for types that can be in packed arrays.
//%PDDM-DEFINE _WRITE_PACKABLE_DECLS(NAME, ARRAY_TYPE, TYPE)
//%- (void)write##NAME:(int32_t)fieldNumber value:(TYPE)value;
//%- (void)write##NAME##s:(int32_t)fieldNumber
//% NAME$S values:(GPB##ARRAY_TYPE##Array *)values
//% NAME$S tag:(uint32_t)tag;
//%- (void)write##NAME##NoTag:(TYPE)value;
//%
// Write methods for types that aren't in packed arrays.
//%PDDM-DEFINE _WRITE_UNPACKABLE_DECLS(NAME, TYPE)
//%- (void)write##NAME:(int32_t)fieldNumber value:(TYPE)value;
//%- (void)write##NAME##s:(int32_t)fieldNumber values:(NSArray *)values;
//%- (void)write##NAME##NoTag:(TYPE)value;
//%
// Special write methods for Groups.
//%PDDM-DEFINE _WRITE_GROUP_DECLS(NAME, TYPE)
//%- (void)write##NAME:(int32_t)fieldNumber
//% NAME$S value:(TYPE)value;
//%- (void)write##NAME##s:(int32_t)fieldNumber values:(NSArray *)values;
//%- (void)write##NAME##NoTag:(int32_t)fieldNumber
//% NAME$S value:(TYPE)value;
//%
// One macro to hide it all up above.
//%PDDM-DEFINE _WRITE_DECLS()
//%_WRITE_PACKABLE_DECLS(Double, Double, double)
//%_WRITE_PACKABLE_DECLS(Float, Float, float)
//%_WRITE_PACKABLE_DECLS(UInt64, UInt64, uint64_t)
//%_WRITE_PACKABLE_DECLS(Int64, Int64, int64_t)
//%_WRITE_PACKABLE_DECLS(Int32, Int32, int32_t)
//%_WRITE_PACKABLE_DECLS(UInt32, UInt32, uint32_t)
//%_WRITE_PACKABLE_DECLS(Fixed64, UInt64, uint64_t)
//%_WRITE_PACKABLE_DECLS(Fixed32, UInt32, uint32_t)
//%_WRITE_PACKABLE_DECLS(SInt32, Int32, int32_t)
//%_WRITE_PACKABLE_DECLS(SInt64, Int64, int64_t)
//%_WRITE_PACKABLE_DECLS(SFixed64, Int64, int64_t)
//%_WRITE_PACKABLE_DECLS(SFixed32, Int32, int32_t)
//%_WRITE_PACKABLE_DECLS(Bool, Bool, BOOL)
//%_WRITE_PACKABLE_DECLS(Enum, Enum, int32_t)
//%_WRITE_UNPACKABLE_DECLS(String, NSString *)
//%_WRITE_UNPACKABLE_DECLS(Message, GPBMessage *)
//%_WRITE_UNPACKABLE_DECLS(Data, NSData *)
//%_WRITE_GROUP_DECLS(Group, GPBMessage *)
//%_WRITE_GROUP_DECLS(UnknownGroup, GPBUnknownFieldSet *)

File diff suppressed because it is too large Load Diff

@ -0,0 +1,143 @@
// 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 "GPBTypes.h"
@class GPBEnumDescriptor;
@class GPBFieldDescriptor;
@class GPBFieldOptions;
@class GPBFileDescriptor;
@class GPBOneofDescriptor;
typedef NS_ENUM(NSInteger, GPBFileSyntax) {
GPBFileSyntaxUnknown = 0,
GPBFileSyntaxProto2 = 2,
GPBFileSyntaxProto3 = 3,
};
typedef NS_ENUM(NSInteger, GPBFieldType) {
GPBFieldTypeSingle, // optional/required
GPBFieldTypeRepeated, // repeated
GPBFieldTypeMap, // map<K,V>
};
@interface GPBDescriptor : NSObject<NSCopying>
@property(nonatomic, readonly, copy) NSString *name;
@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;
@property(nonatomic, readonly, getter=isWireFormat) BOOL wireFormat;
@property(nonatomic, readonly) Class messageClass;
- (GPBFieldDescriptor *)fieldWithNumber:(uint32_t)fieldNumber;
- (GPBFieldDescriptor *)fieldWithName:(NSString *)name;
- (GPBOneofDescriptor *)oneofWithName:(NSString *)name;
- (GPBEnumDescriptor *)enumWithName:(NSString *)name;
- (GPBFieldDescriptor *)extensionWithNumber:(uint32_t)fieldNumber;
- (GPBFieldDescriptor *)extensionWithName:(NSString *)name;
@end
@interface GPBFileDescriptor : NSObject
@property(nonatomic, readonly, copy) NSString *package;
@property(nonatomic, readonly) GPBFileSyntax syntax;
@end
@interface GPBOneofDescriptor : NSObject
@property(nonatomic, readonly) NSString *name;
@property(nonatomic, readonly) NSArray *fields;
- (GPBFieldDescriptor *)fieldWithNumber:(uint32_t)fieldNumber;
- (GPBFieldDescriptor *)fieldWithName:(NSString *)name;
@end
@interface GPBFieldDescriptor : NSObject
@property(nonatomic, readonly, copy) NSString *name;
@property(nonatomic, readonly) uint32_t number;
@property(nonatomic, readonly) GPBType type;
@property(nonatomic, readonly) BOOL hasDefaultValue;
@property(nonatomic, readonly) GPBValue defaultValue;
@property(nonatomic, readonly, getter=isRequired) BOOL required;
@property(nonatomic, readonly, getter=isOptional) BOOL optional;
@property(nonatomic, readonly) GPBFieldType fieldType;
// If it is a map, the value type is in -type.
@property(nonatomic, readonly) GPBType mapKeyType;
@property(nonatomic, readonly, getter=isPackable) BOOL packable;
@property(nonatomic, readonly, assign) GPBOneofDescriptor *containingOneof;
@property(nonatomic, readonly) GPBFieldOptions *fieldOptions;
// Message properties
@property(nonatomic, readonly, assign) Class msgClass;
// Enum properties
@property(nonatomic, readonly, strong) GPBEnumDescriptor *enumDescriptor;
- (BOOL)isValidEnumValue:(int32_t)value;
// For now, this will return nil if it doesn't know the name to use for
// TextFormat.
- (NSString *)textFormatName;
@end
@interface GPBEnumDescriptor : NSObject
@property(nonatomic, readonly, copy) NSString *name;
@property(nonatomic, readonly) GPBEnumValidationFunc enumVerifier;
- (NSString *)enumNameForValue:(int32_t)number;
- (BOOL)getValue:(int32_t *)outValue forEnumName:(NSString *)name;
- (NSString *)textFormatNameForValue:(int32_t)number;
@end
@interface GPBExtensionDescriptor : NSObject
@property(nonatomic, readonly) uint32_t fieldNumber;
@property(nonatomic, readonly) GPBType type;
@property(nonatomic, readonly, getter=isRepeated) BOOL repeated;
@property(nonatomic, readonly, getter=isPackable) BOOL packable;
@property(nonatomic, readonly, assign) Class msgClass;
@property(nonatomic, readonly) NSString *singletonName;
@property(nonatomic, readonly, strong) GPBEnumDescriptor *enumDescriptor;
@end

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

@ -0,0 +1,293 @@
// 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.
// This header is private to the ProtobolBuffers library and must NOT be
// included by any sources outside this library. The contents of this file are
// subject to change at any time without notice.
#import "GPBDescriptor.h"
// Describes attributes of the field.
typedef NS_OPTIONS(uint32_t, GPBFieldFlags) {
// These map to standard protobuf concepts.
GPBFieldRequired = 1 << 0,
GPBFieldRepeated = 1 << 1,
GPBFieldPacked = 1 << 2,
GPBFieldOptional = 1 << 3,
GPBFieldHasDefaultValue = 1 << 4,
// These are not standard protobuf concepts, they are specific to the
// Objective C runtime.
// These bits are used to mark the field as a map and what the key
// type is.
GPBFieldMapKeyMask = 0xF << 8,
GPBFieldMapKeyInt32 = 1 << 8,
GPBFieldMapKeyInt64 = 2 << 8,
GPBFieldMapKeyUInt32 = 3 << 8,
GPBFieldMapKeyUInt64 = 4 << 8,
GPBFieldMapKeySInt32 = 5 << 8,
GPBFieldMapKeySInt64 = 6 << 8,
GPBFieldMapKeyFixed32 = 7 << 8,
GPBFieldMapKeyFixed64 = 8 << 8,
GPBFieldMapKeySFixed32 = 9 << 8,
GPBFieldMapKeySFixed64 = 10 << 8,
GPBFieldMapKeyBool = 11 << 8,
GPBFieldMapKeyString = 12 << 8,
// Indicates the field needs custom handling for the TextFormat name, if not
// set, the name can be derived from the ObjC name.
GPBFieldTextFormatNameCustom = 1 << 16,
// Indicates the field has an enum descriptor.
// TODO(thomasvl): Output the CPP check to use descFunc or validator based
// on final compile. This will then get added based on that.
GPBFieldHasEnumDescriptor = 1 << 17,
};
// Describes a single field in a protobuf as it is represented as an ivar.
typedef struct GPBMessageFieldDescription {
// Name of ivar.
const char *name;
// The field number for the ivar.
uint32_t number;
// The index (in bits) into _has_storage_.
// > 0: the bit to use for a value being set.
// = 0: no storage used.
// < 0: in a oneOf, use a full int32 to record the field active.
int32_t hasIndex;
// Field flags. Use accessor functions below.
GPBFieldFlags flags;
// Type of the ivar.
GPBType type;
// Offset of the variable into it's structure struct.
size_t offset;
// FieldOptions protobuf, serialized as string.
const char *fieldOptions;
GPBValue defaultValue; // Default value for the ivar.
union {
const char *className; // Name for message class.
// For enums only: If EnumDescriptors are compiled in, it will be that,
// otherwise it will be the verifier.
GPBEnumDescriptorFunc enumDescFunc;
GPBEnumValidationFunc enumVerifier;
} typeSpecific;
} GPBMessageFieldDescription;
// Describes a oneof.
typedef struct GPBMessageOneofDescription {
// Name of this enum oneof.
const char *name;
// The index of this oneof in the has_storage.
int32_t index;
} GPBMessageOneofDescription;
// Describes an enum type defined in a .proto file.
typedef struct GPBMessageEnumDescription {
GPBEnumDescriptorFunc enumDescriptorFunc;
} GPBMessageEnumDescription;
// Describes an individual enum constant of a particular type.
typedef struct GPBMessageEnumValueDescription {
// Name of this enum constant.
const char *name;
// Numeric value of this enum constant.
int32_t number;
} GPBMessageEnumValueDescription;
// Describes attributes of the extension.
typedef NS_OPTIONS(uint32_t, GPBExtensionOptions) {
// These map to standard protobuf concepts.
GPBExtensionRepeated = 1 << 0,
GPBExtensionPacked = 1 << 1,
GPBExtensionSetWireFormat = 1 << 2,
};
// An extension
typedef struct GPBExtensionDescription {
const char *singletonName;
GPBType type;
const char *extendedClass;
int32_t fieldNumber;
GPBValue defaultValue;
const char *messageOrGroupClassName;
GPBExtensionOptions options;
GPBEnumDescriptorFunc enumDescriptorFunc;
} GPBExtensionDescription;
@interface GPBDescriptor () {
@package
NSArray *fields_;
NSArray *oneofs_;
size_t storageSize_;
}
// fieldDescriptions, enumDescriptions, rangeDescriptions, and
// extraTextFormatInfo have to be long lived, they are held as raw pointers.
+ (instancetype)
allocDescriptorForClass:(Class)messageClass
rootClass:(Class)rootClass
file:(GPBFileDescriptor *)file
fields:(GPBMessageFieldDescription *)fieldDescriptions
fieldCount:(NSUInteger)fieldCount
oneofs:(GPBMessageOneofDescription *)oneofDescriptions
oneofCount:(NSUInteger)oneofCount
enums:(GPBMessageEnumDescription *)enumDescriptions
enumCount:(NSUInteger)enumCount
ranges:(const GPBExtensionRange *)ranges
rangeCount:(NSUInteger)rangeCount
storageSize:(size_t)storageSize
wireFormat:(BOOL)wireFormat;
+ (instancetype)
allocDescriptorForClass:(Class)messageClass
rootClass:(Class)rootClass
file:(GPBFileDescriptor *)file
fields:(GPBMessageFieldDescription *)fieldDescriptions
fieldCount:(NSUInteger)fieldCount
oneofs:(GPBMessageOneofDescription *)oneofDescriptions
oneofCount:(NSUInteger)oneofCount
enums:(GPBMessageEnumDescription *)enumDescriptions
enumCount:(NSUInteger)enumCount
ranges:(const GPBExtensionRange *)ranges
rangeCount:(NSUInteger)rangeCount
storageSize:(size_t)storageSize
wireFormat:(BOOL)wireFormat
extraTextFormatInfo:(const char *)extraTextFormatInfo;
- (instancetype)initWithClass:(Class)messageClass
file:(GPBFileDescriptor *)file
fields:(NSArray *)fields
oneofs:(NSArray *)oneofs
enums:(NSArray *)enums
extensions:(NSArray *)extensions
extensionRanges:(const GPBExtensionRange *)ranges
extensionRangesCount:(NSUInteger)rangeCount
storageSize:(size_t)storage
wireFormat:(BOOL)wireFormat;
@end
@interface GPBFileDescriptor ()
- (instancetype)initWithPackage:(NSString *)package
syntax:(GPBFileSyntax)syntax;
@end
@interface GPBOneofDescriptor () {
@package
GPBMessageOneofDescription *oneofDescription_;
NSArray *fields_;
SEL caseSel_;
}
- (instancetype)initWithOneofDescription:
(GPBMessageOneofDescription *)oneofDescription
fields:(NSArray *)fields;
@end
@interface GPBFieldDescriptor () {
@package
GPBMessageFieldDescription *description_;
GPB_UNSAFE_UNRETAINED GPBOneofDescriptor *containingOneof_;
SEL getSel_;
SEL setSel_;
SEL hasSel_;
SEL setHasSel_;
}
// Single initializer
// description has to be long lived, it is held as a raw pointer.
- (instancetype)initWithFieldDescription:
(GPBMessageFieldDescription *)description
rootClass:(Class)rootClass
syntax:(GPBFileSyntax)syntax;
@end
@interface GPBEnumDescriptor ()
// valueDescriptions and extraTextFormatInfo have to be long lived, they are
// held as raw pointers.
+ (instancetype)
allocDescriptorForName:(NSString *)name
values:(GPBMessageEnumValueDescription *)valueDescriptions
valueCount:(NSUInteger)valueCount
enumVerifier:(GPBEnumValidationFunc)enumVerifier;
+ (instancetype)
allocDescriptorForName:(NSString *)name
values:(GPBMessageEnumValueDescription *)valueDescriptions
valueCount:(NSUInteger)valueCount
enumVerifier:(GPBEnumValidationFunc)enumVerifier
extraTextFormatInfo:(const char *)extraTextFormatInfo;
- (instancetype)initWithName:(NSString *)name
values:(GPBMessageEnumValueDescription *)valueDescriptions
valueCount:(NSUInteger)valueCount
enumVerifier:(GPBEnumValidationFunc)enumVerifier;
@end
@interface GPBExtensionDescriptor () {
@package
GPBExtensionDescription *description_;
}
// description has to be long lived, it is held as a raw pointer.
- (instancetype)initWithExtensionDescription:
(GPBExtensionDescription *)description;
@end
CF_EXTERN_C_BEGIN
GPB_INLINE BOOL GPBFieldIsMapOrArray(GPBFieldDescriptor *field) {
return (field->description_->flags &
(GPBFieldRepeated | GPBFieldMapKeyMask)) != 0;
}
GPB_INLINE GPBType GPBGetFieldType(GPBFieldDescriptor *field) {
return field->description_->type;
}
GPB_INLINE int32_t GPBFieldHasIndex(GPBFieldDescriptor *field) {
return field->description_->hasIndex;
}
GPB_INLINE uint32_t GPBFieldNumber(GPBFieldDescriptor *field) {
return field->description_->number;
}
uint32_t GPBFieldTag(GPBFieldDescriptor *self);
GPB_INLINE BOOL GPBPreserveUnknownFields(GPBFileSyntax syntax) {
return syntax != GPBFileSyntaxProto3;
}
GPB_INLINE BOOL GPBHasPreservingUnknownEnumSemantics(GPBFileSyntax syntax) {
return syntax == GPBFileSyntaxProto3;
}
CF_EXTERN_C_END

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

@ -0,0 +1,577 @@
// 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 "GPBDictionary.h"
@class GPBCodedInputStream;
@class GPBCodedOutputStream;
@class GPBExtensionRegistry;
@class GPBFieldDescriptor;
//%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)
//%PDDM-DEFINE DICTIONARY_POD_PRIV_INTERFACES_FOR_KEY(KEY_NAME)
//%DICTIONARY_PRIVATE_INTERFACES(KEY_NAME, UInt32, Basic)
//%DICTIONARY_PRIVATE_INTERFACES(KEY_NAME, Int32, Basic)
//%DICTIONARY_PRIVATE_INTERFACES(KEY_NAME, UInt64, Basic)
//%DICTIONARY_PRIVATE_INTERFACES(KEY_NAME, Int64, Basic)
//%DICTIONARY_PRIVATE_INTERFACES(KEY_NAME, Bool, Basic)
//%DICTIONARY_PRIVATE_INTERFACES(KEY_NAME, Float, Basic)
//%DICTIONARY_PRIVATE_INTERFACES(KEY_NAME, Double, Basic)
//%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;
//%EXTRA_DICTIONARY_PRIVATE_INTERFACES_##HELPER()@end
//%
//%PDDM-DEFINE EXTRA_DICTIONARY_PRIVATE_INTERFACES_Basic()
// Empty
//%PDDM-DEFINE EXTRA_DICTIONARY_PRIVATE_INTERFACES_Object()
//%- (BOOL)isInitialized;
//%- (instancetype)deepCopyWithZone:(NSZone *)zone
//% __attribute__((ns_returns_retained));
//%
//%PDDM-DEFINE EXTRA_DICTIONARY_PRIVATE_INTERFACES_Enum()
//%- (NSData *)serializedDataForUnknownValue:(int32_t)value
//% forKey:(GPBValue *)key
//% keyType:(GPBType)keyType;
//%
//%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;
@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;
@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;
@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;
@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;
@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;
@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;
@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;
- (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;
- (BOOL)isInitialized;
- (instancetype)deepCopyWithZone:(NSZone *)zone
__attribute__((ns_returns_retained));
@end
//%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;
@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;
@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;
@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;
@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;
@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;
@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;
@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;
- (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;
- (BOOL)isInitialized;
- (instancetype)deepCopyWithZone:(NSZone *)zone
__attribute__((ns_returns_retained));
@end
//%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;
@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;
@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;
@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;
@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;
@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;
@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;
@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;
- (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;
- (BOOL)isInitialized;
- (instancetype)deepCopyWithZone:(NSZone *)zone
__attribute__((ns_returns_retained));
@end
//%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;
@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;
@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;
@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;
@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;
@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;
@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;
@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;
- (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;
- (BOOL)isInitialized;
- (instancetype)deepCopyWithZone:(NSZone *)zone
__attribute__((ns_returns_retained));
@end
//%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;
@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;
@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;
@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;
@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;
@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;
@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;
@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;
- (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;
- (BOOL)isInitialized;
- (instancetype)deepCopyWithZone:(NSZone *)zone
__attribute__((ns_returns_retained));
@end
//%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;
@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;
@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;
@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;
@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;
@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;
@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;
@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;
- (NSData *)serializedDataForUnknownValue:(int32_t)value
forKey:(GPBValue *)key
keyType:(GPBType)keyType;
@end
//%PDDM-EXPAND-END (6 expansions)
CF_EXTERN_C_BEGIN
// Helper to compute size when an NSDictionary is used for the map instead
// of a custom type.
size_t GPBDictionaryComputeSizeInternalHelper(NSDictionary *dict,
GPBFieldDescriptor *field);
// Helper to write out when an NSDictionary is used for the map instead
// of a custom type.
void GPBDictionaryWriteToStreamInternalHelper(
GPBCodedOutputStream *outputStream, NSDictionary *dict,
GPBFieldDescriptor *field);
// Helper to check message initialization when an NSDictionary is used for
// the map instead of a custom type.
BOOL GPBDictionaryIsInitializedInternalHelper(NSDictionary *dict,
GPBFieldDescriptor *field);
// Helper to read a map instead.
void GPBDictionaryReadEntry(id mapDictionary, GPBCodedInputStream *stream,
GPBExtensionRegistry *registry,
GPBFieldDescriptor *field,
GPBMessage *parentMessage);
CF_EXTERN_C_END

@ -0,0 +1,51 @@
// 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 "GPBWireFormat.h"
#import "GPBTypes.h"
@class GPBCodedInputStream;
@class GPBCodedOutputStream;
@class GPBExtensionRegistry;
@class GPBDescriptor;
@class GPBExtensionDescriptor;
@interface GPBExtensionField : NSObject<NSCopying>
@property(nonatomic, readonly) int32_t fieldNumber;
@property(nonatomic, readonly) GPBWireFormat wireType;
@property(nonatomic, readonly) BOOL isRepeated;
@property(nonatomic, readonly) GPBDescriptor *containingType;
@property(nonatomic, readonly) id defaultValue;
@property(nonatomic, readonly) GPBExtensionDescriptor *descriptor;
@end

@ -0,0 +1,525 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#import "GPBExtensionField_PackagePrivate.h"
#import <objc/runtime.h>
#import "GPBCodedInputStream_PackagePrivate.h"
#import "GPBCodedOutputStream.h"
#import "GPBDescriptor_PackagePrivate.h"
#import "GPBMessage_PackagePrivate.h"
#import "GPBUtilities_PackagePrivate.h"
GPB_INLINE size_t TypeSize(GPBType type) {
switch (type) {
case GPBTypeBool:
return 1;
case GPBTypeFixed32:
case GPBTypeSFixed32:
case GPBTypeFloat:
return 4;
case GPBTypeFixed64:
case GPBTypeSFixed64:
case GPBTypeDouble:
return 8;
default:
return 0;
}
}
GPB_INLINE BOOL ExtensionIsRepeated(GPBExtensionDescription *description) {
return (description->options & GPBExtensionRepeated) != 0;
}
GPB_INLINE BOOL ExtensionIsPacked(GPBExtensionDescription *description) {
return (description->options & GPBExtensionPacked) != 0;
}
GPB_INLINE BOOL ExtensionIsWireFormat(GPBExtensionDescription *description) {
return (description->options & GPBExtensionSetWireFormat) != 0;
}
static size_t ComputePBSerializedSizeNoTagOfObject(GPBType type, id object) {
#define FIELD_CASE(TYPE, ACCESSOR) \
case GPBType##TYPE: \
return GPBCompute##TYPE##SizeNoTag([(NSNumber *)object ACCESSOR]);
#define FIELD_CASE2(TYPE) \
case GPBType##TYPE: \
return GPBCompute##TYPE##SizeNoTag(object);
switch (type) {
FIELD_CASE(Bool, boolValue)
FIELD_CASE(Float, floatValue)
FIELD_CASE(Double, doubleValue)
FIELD_CASE(Int32, intValue)
FIELD_CASE(SFixed32, intValue)
FIELD_CASE(SInt32, intValue)
FIELD_CASE(Enum, intValue)
FIELD_CASE(Int64, longLongValue)
FIELD_CASE(SInt64, longLongValue)
FIELD_CASE(SFixed64, longLongValue)
FIELD_CASE(UInt32, unsignedIntValue)
FIELD_CASE(Fixed32, unsignedIntValue)
FIELD_CASE(UInt64, unsignedLongLongValue)
FIELD_CASE(Fixed64, unsignedLongLongValue)
FIELD_CASE2(Data)
FIELD_CASE2(String)
FIELD_CASE2(Message)
FIELD_CASE2(Group)
}
#undef FIELD_CASE
#undef FIELD_CASE2
}
static size_t ComputeSerializedSizeIncludingTagOfObject(
GPBExtensionDescription *description, id object) {
#define FIELD_CASE(TYPE, ACCESSOR) \
case GPBType##TYPE: \
return GPBCompute##TYPE##Size(description->fieldNumber, \
[(NSNumber *)object ACCESSOR]);
#define FIELD_CASE2(TYPE) \
case GPBType##TYPE: \
return GPBCompute##TYPE##Size(description->fieldNumber, object);
switch (description->type) {
FIELD_CASE(Bool, boolValue)
FIELD_CASE(Float, floatValue)
FIELD_CASE(Double, doubleValue)
FIELD_CASE(Int32, intValue)
FIELD_CASE(SFixed32, intValue)
FIELD_CASE(SInt32, intValue)
FIELD_CASE(Enum, intValue)
FIELD_CASE(Int64, longLongValue)
FIELD_CASE(SInt64, longLongValue)
FIELD_CASE(SFixed64, longLongValue)
FIELD_CASE(UInt32, unsignedIntValue)
FIELD_CASE(Fixed32, unsignedIntValue)
FIELD_CASE(UInt64, unsignedLongLongValue)
FIELD_CASE(Fixed64, unsignedLongLongValue)
FIELD_CASE2(Data)
FIELD_CASE2(String)
FIELD_CASE2(Group)
case GPBTypeMessage:
if (ExtensionIsWireFormat(description)) {
return GPBComputeMessageSetExtensionSize(description->fieldNumber,
object);
} else {
return GPBComputeMessageSize(description->fieldNumber, object);
}
}
#undef FIELD_CASE
#undef FIELD_CASE2
}
static size_t ComputeSerializedSizeIncludingTagOfArray(
GPBExtensionDescription *description, NSArray *values) {
if (ExtensionIsPacked(description)) {
size_t size = 0;
size_t typeSize = TypeSize(description->type);
if (typeSize != 0) {
size = values.count * typeSize;
} else {
for (id value in values) {
size += ComputePBSerializedSizeNoTagOfObject(description->type, value);
}
}
return size + GPBComputeTagSize(description->fieldNumber) +
GPBComputeRawVarint32SizeForInteger(size);
} else {
size_t size = 0;
for (id value in values) {
size += ComputeSerializedSizeIncludingTagOfObject(description, value);
}
return size;
}
}
static void WriteObjectIncludingTagToCodedOutputStream(
id object, GPBExtensionDescription *description,
GPBCodedOutputStream *output) {
#define FIELD_CASE(TYPE, ACCESSOR) \
case GPBType##TYPE: \
[output write##TYPE:description->fieldNumber \
value:[(NSNumber *)object ACCESSOR]]; \
return;
#define FIELD_CASE2(TYPE) \
case GPBType##TYPE: \
[output write##TYPE:description->fieldNumber value:object]; \
return;
switch (description->type) {
FIELD_CASE(Bool, boolValue)
FIELD_CASE(Float, floatValue)
FIELD_CASE(Double, doubleValue)
FIELD_CASE(Int32, intValue)
FIELD_CASE(SFixed32, intValue)
FIELD_CASE(SInt32, intValue)
FIELD_CASE(Enum, intValue)
FIELD_CASE(Int64, longLongValue)
FIELD_CASE(SInt64, longLongValue)
FIELD_CASE(SFixed64, longLongValue)
FIELD_CASE(UInt32, unsignedIntValue)
FIELD_CASE(Fixed32, unsignedIntValue)
FIELD_CASE(UInt64, unsignedLongLongValue)
FIELD_CASE(Fixed64, unsignedLongLongValue)
FIELD_CASE2(Data)
FIELD_CASE2(String)
FIELD_CASE2(Group)
case GPBTypeMessage:
if (ExtensionIsWireFormat(description)) {
[output writeMessageSetExtension:description->fieldNumber value:object];
} else {
[output writeMessage:description->fieldNumber value:object];
}
return;
}
#undef FIELD_CASE
#undef FIELD_CASE2
}
static void WriteObjectNoTagToCodedOutputStream(
id object, GPBExtensionDescription *description,
GPBCodedOutputStream *output) {
#define FIELD_CASE(TYPE, ACCESSOR) \
case GPBType##TYPE: \
[output write##TYPE##NoTag:[(NSNumber *)object ACCESSOR]]; \
return;
#define FIELD_CASE2(TYPE) \
case GPBType##TYPE: \
[output write##TYPE##NoTag:object]; \
return;
switch (description->type) {
FIELD_CASE(Bool, boolValue)
FIELD_CASE(Float, floatValue)
FIELD_CASE(Double, doubleValue)
FIELD_CASE(Int32, intValue)
FIELD_CASE(SFixed32, intValue)
FIELD_CASE(SInt32, intValue)
FIELD_CASE(Enum, intValue)
FIELD_CASE(Int64, longLongValue)
FIELD_CASE(SInt64, longLongValue)
FIELD_CASE(SFixed64, longLongValue)
FIELD_CASE(UInt32, unsignedIntValue)
FIELD_CASE(Fixed32, unsignedIntValue)
FIELD_CASE(UInt64, unsignedLongLongValue)
FIELD_CASE(Fixed64, unsignedLongLongValue)
FIELD_CASE2(Data)
FIELD_CASE2(String)
FIELD_CASE2(Message)
case GPBTypeGroup:
[output writeGroupNoTag:description->fieldNumber value:object];
return;
}
#undef FIELD_CASE
#undef FIELD_CASE2
}
static void WriteArrayIncludingTagsToCodedOutputStream(
NSArray *values, GPBExtensionDescription *description,
GPBCodedOutputStream *output) {
if (ExtensionIsPacked(description)) {
[output writeTag:description->fieldNumber
format:GPBWireFormatLengthDelimited];
size_t dataSize = 0;
size_t typeSize = TypeSize(description->type);
if (typeSize != 0) {
dataSize = values.count * typeSize;
} else {
for (id value in values) {
dataSize +=
ComputePBSerializedSizeNoTagOfObject(description->type, value);
}
}
[output writeRawVarintSizeTAs32:dataSize];
for (id value in values) {
WriteObjectNoTagToCodedOutputStream(value, description, output);
}
} else {
for (id value in values) {
WriteObjectIncludingTagToCodedOutputStream(value, description, output);
}
}
}
@implementation GPBExtensionField {
GPBExtensionDescription *description_;
GPBExtensionDescriptor *descriptor_;
GPBValue defaultValue_;
}
@synthesize containingType = containingType_;
@synthesize descriptor = descriptor_;
- (instancetype)init {
// Throw an exception if people attempt to not use the designated initializer.
self = [super init];
if (self != nil) {
[self doesNotRecognizeSelector:_cmd];
self = nil;
}
return self;
}
- (instancetype)initWithDescription:(GPBExtensionDescription *)description {
if ((self = [super init])) {
description_ = description;
if (description->extendedClass) {
Class containingClass = objc_lookUpClass(description->extendedClass);
NSAssert1(containingClass, @"Class %s not defined",
description->extendedClass);
containingType_ = [containingClass descriptor];
}
#if DEBUG
const char *className = description->messageOrGroupClassName;
if (className) {
NSAssert1(objc_lookUpClass(className) != Nil, @"Class %s not defined",
className);
}
#endif
descriptor_ = [[GPBExtensionDescriptor alloc]
initWithExtensionDescription:description];
GPBType type = description_->type;
if (type == GPBTypeData) {
// Data stored as a length prefixed c-string in descriptor records.
const uint8_t *bytes =
(const uint8_t *)description->defaultValue.valueData;
if (bytes) {
uint32_t length = *((uint32_t *)bytes);
// The length is stored in network byte order.
length = ntohl(length);
bytes += sizeof(length);
defaultValue_.valueData =
[[NSData alloc] initWithBytes:bytes length:length];
}
} else if (type == GPBTypeMessage || type == GPBTypeGroup) {
// The default is looked up in -defaultValue instead since extensions
// aren't
// common, we avoid the hit startup hit and it avoid initialization order
// issues.
} else {
defaultValue_ = description->defaultValue;
}
}
return self;
}
- (void)dealloc {
if ((description_->type == GPBTypeData) &&
!ExtensionIsRepeated(description_)) {
[defaultValue_.valueData release];
}
[descriptor_ release];
[super dealloc];
}
- (NSString *)description {
return [NSString stringWithFormat:@"<%@ %p> FieldNumber:%d ContainingType:%@",
[self class], self, self.fieldNumber,
self.containingType];
}
- (id)copyWithZone:(NSZone *)__unused zone {
return [self retain];
}
#pragma mark Properties
- (int32_t)fieldNumber {
return description_->fieldNumber;
}
- (GPBWireFormat)wireType {
return GPBWireFormatForType(description_->type,
ExtensionIsPacked(description_));
}
- (BOOL)isRepeated {
return ExtensionIsRepeated(description_);
}
- (id)defaultValue {
if (ExtensionIsRepeated(description_)) {
return nil;
}
switch (description_->type) {
case GPBTypeBool:
return @(defaultValue_.valueBool);
case GPBTypeFloat:
return @(defaultValue_.valueFloat);
case GPBTypeDouble:
return @(defaultValue_.valueDouble);
case GPBTypeInt32:
case GPBTypeSInt32:
case GPBTypeEnum:
case GPBTypeSFixed32:
return @(defaultValue_.valueInt32);
case GPBTypeInt64:
case GPBTypeSInt64:
case GPBTypeSFixed64:
return @(defaultValue_.valueInt64);
case GPBTypeUInt32:
case GPBTypeFixed32:
return @(defaultValue_.valueUInt32);
case GPBTypeUInt64:
case GPBTypeFixed64:
return @(defaultValue_.valueUInt64);
case GPBTypeData:
// Like message fields, the default is zero length data.
return (defaultValue_.valueData ? defaultValue_.valueData
: GPBEmptyNSData());
case GPBTypeString:
// Like message fields, the default is zero length string.
return (defaultValue_.valueString ? defaultValue_.valueString : @"");
case GPBTypeGroup:
case GPBTypeMessage:
NSAssert(0, @"Shouldn't get here");
return nil;
}
}
#pragma mark Internals
- (void)mergeFromCodedInputStream:(GPBCodedInputStream *)input
extensionRegistry:(GPBExtensionRegistry *)extensionRegistry
message:(GPBMessage *)message {
GPBCodedInputStreamState *state = &input->state_;
if (ExtensionIsPacked(description_)) {
int32_t length = GPBCodedInputStreamReadInt32(state);
size_t limit = GPBCodedInputStreamPushLimit(state, length);
while (GPBCodedInputStreamBytesUntilLimit(state) > 0) {
id value = [self newSingleValueFromCodedInputStream:input
extensionRegistry:extensionRegistry
existingValue:nil];
[message addExtension:self value:value];
[value release];
}
GPBCodedInputStreamPopLimit(state, limit);
} else {
id existingValue = nil;
BOOL isRepeated = ExtensionIsRepeated(description_);
if (!isRepeated && GPBTypeIsMessage(description_->type)) {
existingValue = [message getExistingExtension:self];
}
id value = [self newSingleValueFromCodedInputStream:input
extensionRegistry:extensionRegistry
existingValue:existingValue];
if (isRepeated) {
[message addExtension:self value:value];
} else {
[message setExtension:self value:value];
}
[value release];
}
}
- (void)writeValue:(id)value
includingTagToCodedOutputStream:(GPBCodedOutputStream *)output {
if (ExtensionIsRepeated(description_)) {
WriteArrayIncludingTagsToCodedOutputStream(value, description_, output);
} else {
WriteObjectIncludingTagToCodedOutputStream(value, description_, output);
}
}
- (size_t)computeSerializedSizeIncludingTag:(id)value {
if (ExtensionIsRepeated(description_)) {
return ComputeSerializedSizeIncludingTagOfArray(description_, value);
} else {
return ComputeSerializedSizeIncludingTagOfObject(description_, value);
}
}
// Note that this returns a retained value intentionally.
- (id)newSingleValueFromCodedInputStream:(GPBCodedInputStream *)input
extensionRegistry:(GPBExtensionRegistry *)extensionRegistry
existingValue:(GPBMessage *)existingValue {
GPBCodedInputStreamState *state = &input->state_;
switch (description_->type) {
case GPBTypeBool: return [[NSNumber alloc] initWithBool:GPBCodedInputStreamReadBool(state)];
case GPBTypeFixed32: return [[NSNumber alloc] initWithUnsignedInt:GPBCodedInputStreamReadFixed32(state)];
case GPBTypeSFixed32: return [[NSNumber alloc] initWithInt:GPBCodedInputStreamReadSFixed32(state)];
case GPBTypeFloat: return [[NSNumber alloc] initWithFloat:GPBCodedInputStreamReadFloat(state)];
case GPBTypeFixed64: return [[NSNumber alloc] initWithUnsignedLongLong:GPBCodedInputStreamReadFixed64(state)];
case GPBTypeSFixed64: return [[NSNumber alloc] initWithLongLong:GPBCodedInputStreamReadSFixed64(state)];
case GPBTypeDouble: return [[NSNumber alloc] initWithDouble:GPBCodedInputStreamReadDouble(state)];
case GPBTypeInt32: return [[NSNumber alloc] initWithInt:GPBCodedInputStreamReadInt32(state)];
case GPBTypeInt64: return [[NSNumber alloc] initWithLongLong:GPBCodedInputStreamReadInt64(state)];
case GPBTypeSInt32: return [[NSNumber alloc] initWithInt:GPBCodedInputStreamReadSInt32(state)];
case GPBTypeSInt64: return [[NSNumber alloc] initWithLongLong:GPBCodedInputStreamReadSInt64(state)];
case GPBTypeUInt32: return [[NSNumber alloc] initWithUnsignedInt:GPBCodedInputStreamReadUInt32(state)];
case GPBTypeUInt64: return [[NSNumber alloc] initWithUnsignedLongLong:GPBCodedInputStreamReadUInt64(state)];
case GPBTypeData: return GPBCodedInputStreamReadRetainedData(state);
case GPBTypeString: return GPBCodedInputStreamReadRetainedString(state);
case GPBTypeEnum: return [[NSNumber alloc] initWithInt:GPBCodedInputStreamReadEnum(state)];
case GPBTypeGroup:
case GPBTypeMessage: {
GPBMessage *message;
if (existingValue) {
message = [existingValue retain];
} else {
GPBDescriptor *decriptor = [descriptor_.msgClass descriptor];
message = [[decriptor.messageClass alloc] init];
}
if (description_->type == GPBTypeGroup) {
[input readGroup:description_->fieldNumber
message:message
extensionRegistry:extensionRegistry];
} else {
// description_->type == GPBTypeMessage
if (ExtensionIsWireFormat(description_)) {
// For MessageSet fields the message length will have already been
// read.
[message mergeFromCodedInputStream:input
extensionRegistry:extensionRegistry];
} else {
[input readMessage:message extensionRegistry:extensionRegistry];
}
}
return message;
}
}
return nil;
}
- (NSComparisonResult)compareByFieldNumber:(GPBExtensionField *)other {
int32_t selfNumber = description_->fieldNumber;
int32_t otherNumber = other->description_->fieldNumber;
if (selfNumber < otherNumber) {
return NSOrderedAscending;
} else if (selfNumber == otherNumber) {
return NSOrderedSame;
} else {
return NSOrderedDescending;
}
}
@end

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

@ -0,0 +1,46 @@
// 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>
@class GPBDescriptor;
@class GPBExtensionField;
// A table of known extensions, searchable by name or field number. When
// parsing a protocol message that might have extensions, you must provide an
// 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
- (GPBExtensionField *)getExtension:(GPBDescriptor *)containingType
fieldNumber:(NSInteger)fieldNumber;
@end

@ -0,0 +1,98 @@
// 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 "GPBExtensionRegistry_PackagePrivate.h"
#import "GPBBootstrap.h"
#import "GPBDescriptor.h"
#import "GPBExtensionField.h"
@implementation GPBExtensionRegistry {
// TODO(dmaclach): Reimplement with CFDictionaries that don't use
// objects as keys.
NSMutableDictionary *mutableClassMap_;
}
- (instancetype)init {
if ((self = [super init])) {
mutableClassMap_ = [[NSMutableDictionary alloc] init];
}
return self;
}
- (void)dealloc {
[mutableClassMap_ release];
[super dealloc];
}
- (NSMutableDictionary *)extensionMapForContainingType:
(GPBDescriptor *)containingType {
NSMutableDictionary *extensionMap =
[mutableClassMap_ objectForKey:containingType];
if (extensionMap == nil) {
extensionMap = [NSMutableDictionary dictionary];
[mutableClassMap_ setObject:extensionMap forKey:containingType];
}
return extensionMap;
}
- (void)addExtension:(GPBExtensionField *)extension {
if (extension == nil) {
return;
}
GPBDescriptor *containingType = [extension containingType];
NSMutableDictionary *extensionMap =
[self extensionMapForContainingType:containingType];
[extensionMap setObject:extension forKey:@([extension fieldNumber])];
}
- (GPBExtensionField *)getExtension:(GPBDescriptor *)containingType
fieldNumber:(NSInteger)fieldNumber {
NSDictionary *extensionMap = [mutableClassMap_ objectForKey:containingType];
return [extensionMap objectForKey:@(fieldNumber)];
}
- (void)addExtensions:(GPBExtensionRegistry *)registry {
if (registry == nil) {
// In the case where there are no extensions just ignore.
return;
}
NSMutableDictionary *otherClassMap = registry->mutableClassMap_;
for (GPBDescriptor *containingType in otherClassMap) {
NSMutableDictionary *extensionMap =
[self extensionMapForContainingType:containingType];
NSMutableDictionary *otherExtensionMap =
[registry extensionMapForContainingType:containingType];
[extensionMap addEntriesFromDictionary:otherExtensionMap];
}
}
@end

@ -0,0 +1,40 @@
// 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

@ -0,0 +1,56 @@
// 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>
@class GPBCodedOutputStream;
@class GPBUInt32Array;
@class GPBUInt64Array;
@class GPBUnknownFieldSet;
@interface GPBField : NSObject<NSCopying>
@property(nonatomic, readonly, assign) int32_t number;
// Only one of these will be set.
@property(nonatomic, readonly, strong) GPBUInt64Array *varintList;
@property(nonatomic, readonly, strong) GPBUInt32Array *fixed32List;
@property(nonatomic, readonly, strong) GPBUInt64Array *fixed64List;
@property(nonatomic, readonly, strong) NSArray *lengthDelimitedList;
@property(nonatomic, readonly, strong) NSArray *groupList;
// Only one of these should be used per Field.
- (void)addVarint:(uint64_t)value;
- (void)addFixed32:(uint32_t)value;
- (void)addFixed64:(uint64_t)value;
- (void)addLengthDelimited:(NSData *)value;
- (void)addGroup:(GPBUnknownFieldSet *)value;
@end

@ -0,0 +1,328 @@
// 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 "GPBField_PackagePrivate.h"
#import "GPBArray.h"
#import "GPBCodedOutputStream.h"
@interface GPBField () {
@protected
int32_t number_;
GPBUInt64Array *mutableVarintList_;
GPBUInt32Array *mutableFixed32List_;
GPBUInt64Array *mutableFixed64List_;
NSMutableArray *mutableLengthDelimitedList_;
NSMutableArray *mutableGroupList_;
}
@end
@implementation GPBField
@synthesize number = number_;
@synthesize varintList = mutableVarintList_;
@synthesize fixed32List = mutableFixed32List_;
@synthesize fixed64List = mutableFixed64List_;
@synthesize lengthDelimitedList = mutableLengthDelimitedList_;
@synthesize groupList = mutableGroupList_;
- (instancetype)initWithNumber:(int32_t)number {
if ((self = [super init])) {
number_ = number;
}
return self;
}
- (void)dealloc {
[mutableVarintList_ release];
[mutableFixed32List_ release];
[mutableFixed64List_ release];
[mutableLengthDelimitedList_ release];
[mutableGroupList_ release];
[super dealloc];
}
- (id)copyWithZone:(NSZone *)zone {
GPBField *result = [[GPBField allocWithZone:zone] initWithNumber:number_];
result->mutableFixed32List_ = [mutableFixed32List_ copyWithZone:zone];
result->mutableFixed64List_ = [mutableFixed64List_ copyWithZone:zone];
result->mutableLengthDelimitedList_ =
[mutableLengthDelimitedList_ copyWithZone:zone];
result->mutableVarintList_ = [mutableVarintList_ copyWithZone:zone];
if (mutableGroupList_.count) {
result->mutableGroupList_ = [[NSMutableArray allocWithZone:zone]
initWithCapacity:mutableGroupList_.count];
for (GPBUnknownFieldSet *group in mutableGroupList_) {
GPBUnknownFieldSet *copied = [group copyWithZone:zone];
[result->mutableGroupList_ addObject:copied];
[copied release];
}
}
return result;
}
- (BOOL)isEqual:(id)object {
if (self == object) return YES;
if (![object isKindOfClass:[GPBField class]]) return NO;
GPBField *field = (GPBField *)object;
BOOL equalVarint =
(mutableVarintList_.count == 0 && field->mutableVarintList_.count == 0) ||
[mutableVarintList_ isEqual:field->mutableVarintList_];
if (!equalVarint) return NO;
BOOL equalFixed32 = (mutableFixed32List_.count == 0 &&
field->mutableFixed32List_.count == 0) ||
[mutableFixed32List_ isEqual:field->mutableFixed32List_];
if (!equalFixed32) return NO;
BOOL equalFixed64 = (mutableFixed64List_.count == 0 &&
field->mutableFixed64List_.count == 0) ||
[mutableFixed64List_ isEqual:field->mutableFixed64List_];
if (!equalFixed64) return NO;
BOOL equalLDList =
(mutableLengthDelimitedList_.count == 0 &&
field->mutableLengthDelimitedList_.count == 0) ||
[mutableLengthDelimitedList_ isEqual:field->mutableLengthDelimitedList_];
if (!equalLDList) return NO;
BOOL equalGroupList =
(mutableGroupList_.count == 0 && field->mutableGroupList_.count == 0) ||
[mutableGroupList_ isEqual:field->mutableGroupList_];
if (!equalGroupList) return NO;
return YES;
}
- (NSUInteger)hash {
// Just mix the hashes of the possible sub arrays.
const int prime = 31;
NSUInteger result = prime + [mutableVarintList_ hash];
result = prime * result + [mutableFixed32List_ hash];
result = prime * result + [mutableFixed64List_ hash];
result = prime * result + [mutableLengthDelimitedList_ hash];
result = prime * result + [mutableGroupList_ hash];
return result;
}
- (void)writeToOutput:(GPBCodedOutputStream *)output {
NSUInteger count = mutableVarintList_.count;
if (count > 0) {
[output writeUInt64s:number_ values:mutableVarintList_ tag:0];
}
count = mutableFixed32List_.count;
if (count > 0) {
[output writeFixed32s:number_ values:mutableFixed32List_ tag:0];
}
count = mutableFixed64List_.count;
if (count > 0) {
[output writeFixed64s:number_ values:mutableFixed64List_ tag:0];
}
count = mutableLengthDelimitedList_.count;
if (count > 0) {
[output writeDatas:number_ values:mutableLengthDelimitedList_];
}
count = mutableGroupList_.count;
if (count > 0) {
[output writeUnknownGroups:number_ values:mutableGroupList_];
}
}
- (size_t)serializedSize {
__block size_t result = 0;
int32_t number = number_;
[mutableVarintList_
enumerateValuesWithBlock:^(uint64_t value, NSUInteger idx, BOOL *stop) {
#pragma unused(idx, stop)
result += GPBComputeUInt64Size(number, value);
}];
[mutableFixed32List_
enumerateValuesWithBlock:^(uint32_t value, NSUInteger idx, BOOL *stop) {
#pragma unused(idx, stop)
result += GPBComputeFixed32Size(number, value);
}];
[mutableFixed64List_
enumerateValuesWithBlock:^(uint64_t value, NSUInteger idx, BOOL *stop) {
#pragma unused(idx, stop)
result += GPBComputeFixed64Size(number, value);
}];
for (NSData *data in mutableLengthDelimitedList_) {
result += GPBComputeDataSize(number, data);
}
for (GPBUnknownFieldSet *set in mutableGroupList_) {
result += GPBComputeUnknownGroupSize(number, set);
}
return result;
}
- (void)writeAsMessageSetExtensionToOutput:(GPBCodedOutputStream *)output {
for (NSData *data in mutableLengthDelimitedList_) {
[output writeRawMessageSetExtension:number_ value:data];
}
}
- (size_t)serializedSizeAsMessageSetExtension {
size_t result = 0;
for (NSData *data in mutableLengthDelimitedList_) {
result += GPBComputeRawMessageSetExtensionSize(number_, data);
}
return result;
}
- (NSString *)description {
NSMutableString *description = [NSMutableString
stringWithFormat:@"<%@ %p>: Field: %d {\n", [self class], self, number_];
[mutableVarintList_
enumerateValuesWithBlock:^(uint64_t value, NSUInteger idx, BOOL *stop) {
#pragma unused(idx, stop)
[description appendFormat:@"\t%llu\n", value];
}];
[mutableFixed32List_
enumerateValuesWithBlock:^(uint32_t value, NSUInteger idx, BOOL *stop) {
#pragma unused(idx, stop)
[description appendFormat:@"\t%u\n", value];
}];
[mutableFixed64List_
enumerateValuesWithBlock:^(uint64_t value, NSUInteger idx, BOOL *stop) {
#pragma unused(idx, stop)
[description appendFormat:@"\t%llu\n", value];
}];
for (NSData *data in mutableLengthDelimitedList_) {
[description appendFormat:@"\t%@\n", data];
}
for (GPBUnknownFieldSet *set in mutableGroupList_) {
[description appendFormat:@"\t%@\n", set];
}
[description appendString:@"}"];
return description;
}
- (void)mergeFromField:(GPBField *)other {
GPBUInt64Array *otherVarintList = other.varintList;
if (otherVarintList.count > 0) {
if (mutableVarintList_ == nil) {
mutableVarintList_ = [otherVarintList copy];
} else {
[mutableVarintList_ addValuesFromArray:otherVarintList];
}
}
GPBUInt32Array *otherFixed32List = other.fixed32List;
if (otherFixed32List.count > 0) {
if (mutableFixed32List_ == nil) {
mutableFixed32List_ = [otherFixed32List copy];
} else {
[mutableFixed32List_ addValuesFromArray:otherFixed32List];
}
}
GPBUInt64Array *otherFixed64List = other.fixed64List;
if (otherFixed64List.count > 0) {
if (mutableFixed64List_ == nil) {
mutableFixed64List_ = [otherFixed64List copy];
} else {
[mutableFixed64List_ addValuesFromArray:otherFixed64List];
}
}
NSArray *otherLengthDelimitedList = other.lengthDelimitedList;
if (otherLengthDelimitedList.count > 0) {
if (mutableLengthDelimitedList_ == nil) {
mutableLengthDelimitedList_ = [otherLengthDelimitedList mutableCopy];
} else {
[mutableLengthDelimitedList_
addObjectsFromArray:otherLengthDelimitedList];
}
}
NSArray *otherGroupList = other.groupList;
if (otherGroupList.count > 0) {
if (mutableGroupList_ == nil) {
mutableGroupList_ =
[[NSMutableArray alloc] initWithCapacity:otherGroupList.count];
}
// Make our own mutable copies.
for (GPBUnknownFieldSet *group in otherGroupList) {
GPBUnknownFieldSet *copied = [group copy];
[mutableGroupList_ addObject:copied];
[copied release];
}
}
}
- (void)addVarint:(uint64_t)value {
if (mutableVarintList_ == nil) {
mutableVarintList_ = [[GPBUInt64Array alloc] initWithValues:&value count:1];
} else {
[mutableVarintList_ addValue:value];
}
}
- (void)addFixed32:(uint32_t)value {
if (mutableFixed32List_ == nil) {
mutableFixed32List_ =
[[GPBUInt32Array alloc] initWithValues:&value count:1];
} else {
[mutableFixed32List_ addValue:value];
}
}
- (void)addFixed64:(uint64_t)value {
if (mutableFixed64List_ == nil) {
mutableFixed64List_ =
[[GPBUInt64Array alloc] initWithValues:&value count:1];
} else {
[mutableFixed64List_ addValue:value];
}
}
- (void)addLengthDelimited:(NSData *)value {
if (mutableLengthDelimitedList_ == nil) {
mutableLengthDelimitedList_ =
[[NSMutableArray alloc] initWithObjects:&value count:1];
} else {
[mutableLengthDelimitedList_ addObject:value];
}
}
- (void)addGroup:(GPBUnknownFieldSet *)value {
if (mutableGroupList_ == nil) {
mutableGroupList_ = [[NSMutableArray alloc] initWithObjects:&value count:1];
} else {
[mutableGroupList_ addObject:value];
}
}
@end

@ -0,0 +1,49 @@
// 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 "GPBField.h"
@class GPBCodedOutputStream;
@interface GPBField ()
- (instancetype)initWithNumber:(int32_t)number;
- (void)writeToOutput:(GPBCodedOutputStream *)output;
- (size_t)serializedSize;
- (void)writeAsMessageSetExtensionToOutput:(GPBCodedOutputStream *)output;
- (size_t)serializedSizeAsMessageSetExtension;
- (void)mergeFromField:(GPBField *)other;
@end

@ -0,0 +1,151 @@
// 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 "GPBRootObject.h"
@class GPBDescriptor;
@class GPBCodedInputStream;
@class GPBCodedOutputStream;
@class GPBExtensionField;
@class GPBFieldDescriptor;
@class GPBUnknownFieldSet;
// 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.
#ifdef DEBUG
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.
// The main cases are methods that take no arguments, or setFoo:/hasFoo: type
// methods.
@interface GPBMessage : GPBRootObject<NSCoding, NSCopying>
@property(nonatomic, readonly) GPBUnknownFieldSet *unknownFields;
// Are all required fields in the message and all embedded messages set.
@property(nonatomic, readonly, getter=isInitialized) BOOL initialized;
// 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;
+ (instancetype)parseFromData:(NSData *)data
extensionRegistry:(GPBExtensionRegistry *)extensionRegistry;
+ (instancetype)parseFromCodedInputStream:(GPBCodedInputStream *)input
extensionRegistry:
(GPBExtensionRegistry *)extensionRegistry;
// Create a message based on delimited input.
+ (instancetype)parseDelimitedFromCodedInputStream:(GPBCodedInputStream *)input
extensionRegistry:
(GPBExtensionRegistry *)extensionRegistry;
- (instancetype)initWithData:(NSData *)data;
- (instancetype)initWithData:(NSData *)data
extensionRegistry:(GPBExtensionRegistry *)extensionRegistry;
- (instancetype)initWithCodedInputStream:(GPBCodedInputStream *)input
extensionRegistry:
(GPBExtensionRegistry *)extensionRegistry;
// Serializes the message and writes it to output.
- (void)writeToCodedOutputStream:(GPBCodedOutputStream *)output;
- (void)writeToOutputStream:(NSOutputStream *)output;
// Serializes the message and writes it to output, but writes the size of the
// message as a variant before writing the message.
- (void)writeDelimitedToCodedOutputStream:(GPBCodedOutputStream *)output;
- (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|.
- (NSData *)data;
// Same as -[data], except a delimiter is added to the start of the data
// indicating the size of the message data that follows.
- (NSData *)delimitedData;
// 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]];
// 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];
- (size_t)serializedSize;
// Return the descriptor for the message
+ (GPBDescriptor *)descriptor;
- (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.
- (BOOL)hasExtension:(GPBExtensionField *)extension;
- (id)getExtension:(GPBExtensionField *)extension;
- (void)setExtension:(GPBExtensionField *)extension value:(id)value;
- (void)addExtension:(GPBExtensionField *)extension value:(id)value;
- (void)setExtension:(GPBExtensionField *)extension
index:(NSUInteger)index
value:(id)value;
- (void)clearExtension:(GPBExtensionField *)extension;
- (void)setUnknownFields:(GPBUnknownFieldSet *)unknownFields;
// Resets all fields to their default values.
- (void)clear;
// Parses a message of this type from the input and merges it with this
// message.
- (void)mergeFromData:(NSData *)data
extensionRegistry:(GPBExtensionRegistry *)extensionRegistry;
// Merges the fields from another message (of the same type) into this
// message.
- (void)mergeFrom:(GPBMessage *)other;
@end

File diff suppressed because it is too large Load Diff

@ -0,0 +1,124 @@
// 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.
// This header is private to the ProtobolBuffers library and must NOT be
// included by any sources outside this library. The contents of this file are
// subject to change at any time without notice.
#import "GPBMessage.h"
#import <libkern/OSAtomic.h>
#import "GPBBootstrap.h"
typedef struct GPBMessage_Storage {
uint32_t _has_storage_[0];
} GPBMessage_Storage;
typedef struct GPBMessage_Storage *GPBMessage_StoragePtr;
@interface GPBMessage () {
@package
// NOTE: Because of the +allocWithZone code using NSAllocateObject(),
// this structure should ideally always be kept pointer aligned where the
// real storage starts is also pointer aligned. The compiler/runtime already
// do this, but it may not be documented.
// A pointer to the actual fields of the subclasses. The actual structure
// pointed to by this pointer will depend on the subclass.
// All of the actual structures will start the same as
// GPBMessage_Storage with _has_storage__ as the first field.
// Kept public because static functions need to access it.
GPBMessage_StoragePtr messageStorage_;
// A lock to provide mutual exclusion from internal data that can be modified
// by *read* operations such as getters (autocreation of message fields and
// message extensions, not setting of values). Used to guarantee thread safety
// for concurrent reads on the message.
OSSpinLock readOnlyMutex_;
}
// Gets an extension value without autocreating the result if not found. (i.e.
// returns nil if the extension is not set)
- (id)getExistingExtension:(GPBExtensionField *)extension;
// Returns an array of GPBExtensionField* for all the extensions currently
// in use on the message. They are sorted by field number.
- (NSArray *)sortedExtensionsInUse;
// Parses a message of this type from the input and merges it with this
// message.
//
// Warning: This does not verify that all required fields are present in
// the input message.
// Note: The caller should call
// -[CodedInputStream checkLastTagWas:] after calling this to
// verify that the last tag seen was the appropriate end-group tag,
// or zero for EOF.
- (void)mergeFromCodedInputStream:(GPBCodedInputStream *)input
extensionRegistry:(GPBExtensionRegistry *)extensionRegistry;
// Parses the next delimited message of this type from the input and merges it
// with this message.
- (void)mergeDelimitedFromCodedInputStream:(GPBCodedInputStream *)input
extensionRegistry:
(GPBExtensionRegistry *)extensionRegistry;
- (void)addUnknownMapEntry:(int32_t)fieldNum value:(NSData *)data;
@end
CF_EXTERN_C_BEGIN
// Returns a new instance that was automatically created by |autocreator| for
// its field |field|.
GPBMessage *GPBCreateMessageWithAutocreator(Class msgClass,
GPBMessage *autocreator,
GPBFieldDescriptor *field)
__attribute__((ns_returns_retained));
// Returns whether |message| autocreated this message. This is NO if the message
// was not autocreated by |message| or if it has been mutated since
// autocreation.
BOOL GPBWasMessageAutocreatedBy(GPBMessage *message, GPBMessage *parent);
// Call this when you mutate a message. It will cause the message to become
// visible to its autocreator.
void GPBBecomeVisibleToAutocreator(GPBMessage *self);
// Call this when an array is mutabled so the parent message that autocreated
// it can react.
void GPBAutocreatedArrayModified(GPBMessage *self, id array);
// Clear the autocreator, if any. Asserts if the autocreator still has an
// autocreated reference to this message.
void GPBClearMessageAutocreator(GPBMessage *self);
CF_EXTERN_C_END

@ -0,0 +1,45 @@
// 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 "GPBBootstrap.h"
#import "GPBArray.h"
#import "GPBCodedInputStream.h"
#import "GPBCodedOutputStream.h"
#import "GPBDescriptor.h"
#import "GPBDictionary.h"
#import "GPBExtensionField.h"
#import "GPBExtensionRegistry.h"
#import "GPBField.h"
#import "GPBMessage.h"
#import "GPBRootObject.h"
#import "GPBUnknownFieldSet.h"
#import "GPBUtilities.h"
#import "GPBWireFormat.h"

@ -0,0 +1,49 @@
// 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.
// If you want to build protocol buffers in your own project without adding the
// project dependency, you can just add this file.
#import "GPBArray.m"
#import "GPBCodedInputStream.m"
#import "GPBCodedOutputStream.m"
#import "GPBDescriptor.m"
#import "GPBDictionary.m"
#import "GPBExtensionField.m"
#import "GPBExtensionRegistry.m"
#import "GPBField.m"
#import "GPBMessage.m"
#import "GPBRootObject.m"
#import "GPBUnknownFieldSet.m"
#import "GPBUtilities.m"
#import "GPBWellKnownTypes.m"
#import "GPBWireFormat.m"
#import "google/protobuf/Descriptor.pbobjc.m"

@ -0,0 +1,41 @@
// 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.
// This header is meant to only be used by the generated source, it should not
// be included in code using protocol buffers.
#import "GPBProtocolBuffers.h"
#import "GPBDescriptor_PackagePrivate.h"
#import "GPBExtensionField_PackagePrivate.h"
#import "GPBExtensionRegistry_PackagePrivate.h"
#import "GPBMessage_PackagePrivate.h"
#import "GPBRootObject_PackagePrivate.h"
#import "GPBUtilities_PackagePrivate.h"

@ -0,0 +1,42 @@
// 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>
@class GPBExtensionRegistry;
// All Root Objects derive from GPBRootObject. It supplies a registry
// for derived classes to register their extensions to.
@interface GPBRootObject : NSObject
// Per class registry.
+ (GPBExtensionRegistry *)extensionRegistry;
@end

@ -0,0 +1,177 @@
// 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 "GPBRootObject_PackagePrivate.h"
#import <objc/runtime.h>
#import <CoreFoundation/CoreFoundation.h>
#import "GPBDescriptor.h"
#import "GPBExtensionField.h"
#import "GPBUtilities_PackagePrivate.h"
@interface GPBExtensionDescriptor (GPBRootObject)
// Get singletonName as a c string.
- (const char *)singletonNameC;
@end
@implementation GPBRootObject
// Taken from http://www.burtleburtle.net/bob/hash/doobs.html
// Public Domain
static uint32_t jenkins_one_at_a_time_hash(const char *key) {
uint32_t hash = 0;
for (uint32_t i = 0; key[i] != '\0'; ++i) {
hash += key[i];
hash += (hash << 10);
hash ^= (hash >> 6);
}
hash += (hash << 3);
hash ^= (hash >> 11);
hash += (hash << 15);
return hash;
}
// Key methods for our custom CFDictionary.
// Note that the dictionary lasts for the lifetime of our app, so no need
// to worry about deallocation. All of the items are added to it at
// startup, and so the keys don't need to be retained/released.
// Keys are NULL terminated char *.
static const void *GPBRootExtensionKeyRetain(CFAllocatorRef allocator,
const void *value) {
#pragma unused(allocator)
return value;
}
static void GPBRootExtensionKeyRelease(CFAllocatorRef allocator,
const void *value) {
#pragma unused(allocator)
#pragma unused(value)
}
static CFStringRef GPBRootExtensionCopyKeyDescription(const void *value) {
const char *key = (const char *)value;
return CFStringCreateWithCString(kCFAllocatorDefault, key,
kCFStringEncodingUTF8);
}
static Boolean GPBRootExtensionKeyEqual(const void *value1,
const void *value2) {
const char *key1 = (const char *)value1;
const char *key2 = (const char *)value2;
return strcmp(key1, key2) == 0;
}
static CFHashCode GPBRootExtensionKeyHash(const void *value) {
const char *key = (const char *)value;
return jenkins_one_at_a_time_hash(key);
}
static CFMutableDictionaryRef gExtensionSingletonDictionary = NULL;
+ (void)initialize {
if (!gExtensionSingletonDictionary) {
CFDictionaryKeyCallBacks keyCallBacks = {
// See description above for reason for using custom dictionary.
0,
GPBRootExtensionKeyRetain,
GPBRootExtensionKeyRelease,
GPBRootExtensionCopyKeyDescription,
GPBRootExtensionKeyEqual,
GPBRootExtensionKeyHash,
};
gExtensionSingletonDictionary =
CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &keyCallBacks,
&kCFTypeDictionaryValueCallBacks);
}
}
+ (GPBExtensionRegistry *)extensionRegistry {
// Is overridden in all the subclasses that provide extensions to provide the
// per class one.
return nil;
}
+ (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.
CFDictionarySetValue(gExtensionSingletonDictionary, key, field);
}
static id ExtensionForName(id self, SEL _cmd) {
// Really fast way of doing "classname_selName".
// This came up as a hotspot (creation of NSString *) when accessing a
// lot of extensions.
const char *className = class_getName(self);
const char *selName = sel_getName(_cmd);
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';
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.
return extension;
}
+ (BOOL)resolveClassMethod:(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
// can add up. You could also significantly reduce the code complexity of this
// file.
id extension = ExtensionForName(self, sel);
if (extension != nil) {
const char *encoding =
GPBMessageEncodingForSelector(@selector(getClassValue), NO);
Class metaClass = objc_getMetaClass(class_getName(self));
IMP imp = imp_implementationWithBlock(^(id obj) {
#pragma unused(obj)
return extension;
});
return class_addMethod(metaClass, sel, imp, encoding);
}
return [super resolveClassMethod:sel];
}
@end

@ -0,0 +1,42 @@
// 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 "GPBRootObject.h"
@class GPBExtensionField;
@interface GPBRootObject ()
// Globally register.
+ (void)globallyRegisterExtension:(GPBExtensionField *)field;
@end

@ -0,0 +1,102 @@
// 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 "GPBBootstrap.h"
@class GPBEnumDescriptor;
@class GPBMessage;
@class GPBInt32Array;
// Function used to verify that a given value can be represented by an
// enum type.
typedef BOOL (*GPBEnumValidationFunc)(int32_t);
// Function used to fetch an EnumDescriptor.
typedef GPBEnumDescriptor *(*GPBEnumDescriptorFunc)(void);
// Magic values used for when an the at runtime to indicate an enum value
// that wasn't know at compile time.
enum {
kGPBUnrecognizedEnumeratorValue = (int32_t)0xFBADBEEF,
};
// A union for storing all possible Protobuf values.
// Note that owner is responsible for memory management of object types.
typedef union {
BOOL valueBool;
int32_t valueInt32;
int64_t valueInt64;
uint32_t valueUInt32;
uint64_t valueUInt64;
float valueFloat;
double valueDouble;
GPB_UNSAFE_UNRETAINED NSData *valueData;
GPB_UNSAFE_UNRETAINED NSString *valueString;
GPB_UNSAFE_UNRETAINED GPBMessage *valueMessage;
int32_t valueEnum;
} GPBValue;
// Do not change the order of this enum (or add things to it) without thinking
// about it very carefully. There are several things that depend on the order.
typedef enum {
GPBTypeBool = 0,
GPBTypeFixed32,
GPBTypeSFixed32,
GPBTypeFloat,
GPBTypeFixed64,
GPBTypeSFixed64,
GPBTypeDouble,
GPBTypeInt32,
GPBTypeInt64,
GPBTypeSInt32,
GPBTypeSInt64,
GPBTypeUInt32,
GPBTypeUInt64,
GPBTypeData, // Maps to Bytes Protobuf type
GPBTypeString,
GPBTypeMessage,
GPBTypeGroup,
GPBTypeEnum,
} GPBType;
enum {
// A count of the number of types in GPBType. Separated out from the GPBType
// enum to avoid warnings regarding not handling GPBTypeCount in switch
// statements.
GPBTypeCount = GPBTypeEnum + 1
};
// An extension range.
typedef struct GPBExtensionRange {
uint32_t start; // inclusive
uint32_t end; // exclusive
} GPBExtensionRange;

@ -0,0 +1,46 @@
// 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>
@class GPBField;
@interface GPBUnknownFieldSet : NSObject<NSCopying>
- (BOOL)hasField:(int32_t)number;
- (GPBField *)getField:(int32_t)number;
- (NSUInteger)countOfFields;
- (void)addField:(GPBField *)field;
// Returns an NSArray of the GPBFields sorted by the field numbers.
- (NSArray *)sortedFields;
@end

@ -0,0 +1,422 @@
// 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 "GPBUnknownFieldSet_PackagePrivate.h"
#import "GPBCodedInputStream_PackagePrivate.h"
#import "GPBCodedOutputStream.h"
#import "GPBField_PackagePrivate.h"
#import "GPBUtilities.h"
#import "GPBWireFormat.h"
#pragma mark CFDictionaryKeyCallBacks
// We use a custom dictionary here because our keys are numbers and
// conversion back and forth from NSNumber was costing us performance.
// If/when we move to C++ this could be done using a std::map and some
// careful retain/release calls.
static const void *GPBUnknownFieldSetKeyRetain(CFAllocatorRef allocator,
const void *value) {
#pragma unused(allocator)
return value;
}
static void GPBUnknownFieldSetKeyRelease(CFAllocatorRef allocator,
const void *value) {
#pragma unused(allocator)
#pragma unused(value)
}
static CFStringRef GPBUnknownFieldSetCopyKeyDescription(const void *value) {
return CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("%d"),
(int)value);
}
static Boolean GPBUnknownFieldSetKeyEqual(const void *value1,
const void *value2) {
return value1 == value2;
}
static CFHashCode GPBUnknownFieldSetKeyHash(const void *value) {
return (CFHashCode)value;
}
#pragma mark Helpers
static void checkNumber(int32_t number) {
if (number == 0) {
[NSException raise:NSInvalidArgumentException
format:@"Zero is not a valid field number."];
}
}
@implementation GPBUnknownFieldSet {
@package
CFMutableDictionaryRef fields_;
}
static void CopyWorker(const void *key, const void *value, void *context) {
#pragma unused(key)
GPBField *field = value;
GPBUnknownFieldSet *result = context;
GPBField *copied = [field copy];
[result addField:copied];
[copied release];
}
- (id)copyWithZone:(NSZone *)zone {
GPBUnknownFieldSet *result = [[GPBUnknownFieldSet allocWithZone:zone] init];
if (fields_) {
CFDictionaryApplyFunction(fields_, CopyWorker, result);
}
return result;
}
- (void)dealloc {
if (fields_) {
CFRelease(fields_);
}
[super dealloc];
}
- (BOOL)isEqual:(id)object {
BOOL equal = NO;
if ([object isKindOfClass:[GPBUnknownFieldSet class]]) {
GPBUnknownFieldSet *set = (GPBUnknownFieldSet *)object;
if ((fields_ == NULL) && (set->fields_ == NULL)) {
equal = YES;
} else if ((fields_ != NULL) && (set->fields_ != NULL)) {
equal = CFEqual(fields_, set->fields_);
}
}
return equal;
}
- (NSUInteger)hash {
// Return the hash of the fields dictionary (or just some value).
if (fields_) {
return CFHash(fields_);
}
return (NSUInteger)[GPBUnknownFieldSet class];
}
#pragma mark - Public Methods
- (BOOL)hasField:(int32_t)number {
ssize_t key = number;
return fields_ ? (CFDictionaryGetValue(fields_, (void *)key) != nil) : NO;
}
- (GPBField *)getField:(int32_t)number {
ssize_t key = number;
GPBField *result = fields_ ? CFDictionaryGetValue(fields_, (void *)key) : nil;
return result;
}
- (NSUInteger)countOfFields {
return fields_ ? CFDictionaryGetCount(fields_) : 0;
}
- (NSArray *)sortedFields {
if (!fields_) return nil;
size_t count = CFDictionaryGetCount(fields_);
ssize_t keys[count];
GPBField *values[count];
CFDictionaryGetKeysAndValues(fields_, (const void **)keys,
(const void **)values);
struct GPBFieldPair {
ssize_t key;
GPBField *value;
} pairs[count];
for (size_t i = 0; i < count; ++i) {
pairs[i].key = keys[i];
pairs[i].value = values[i];
};
qsort_b(pairs, count, sizeof(struct GPBFieldPair),
^(const void *first, const void *second) {
const struct GPBFieldPair *a = first;
const struct GPBFieldPair *b = second;
return (a->key > b->key) ? 1 : ((a->key == b->key) ? 0 : -1);
});
for (size_t i = 0; i < count; ++i) {
values[i] = pairs[i].value;
};
return [NSArray arrayWithObjects:values count:count];
}
#pragma mark - Internal Methods
- (void)writeToCodedOutputStream:(GPBCodedOutputStream *)output {
if (!fields_) return;
size_t count = CFDictionaryGetCount(fields_);
ssize_t keys[count];
GPBField *values[count];
CFDictionaryGetKeysAndValues(fields_, (const void **)keys,
(const void **)values);
if (count > 1) {
struct GPBFieldPair {
ssize_t key;
GPBField *value;
} pairs[count];
for (size_t i = 0; i < count; ++i) {
pairs[i].key = keys[i];
pairs[i].value = values[i];
};
qsort_b(pairs, count, sizeof(struct GPBFieldPair),
^(const void *first, const void *second) {
const struct GPBFieldPair *a = first;
const struct GPBFieldPair *b = second;
return (a->key > b->key) ? 1 : ((a->key == b->key) ? 0 : -1);
});
for (size_t i = 0; i < count; ++i) {
GPBField *value = pairs[i].value;
[value writeToOutput:output];
}
} else {
[values[0] writeToOutput:output];
}
}
- (NSString *)description {
NSMutableString *description = [NSMutableString
stringWithFormat:@"<%@ %p>: TextFormat: {\n", [self class], self];
NSString *textFormat = GPBTextFormatForUnknownFieldSet(self, @" ");
[description appendString:textFormat];
[description appendString:@"}"];
return description;
}
static void GPBUnknownFieldSetSerializedSize(const void *key, const void *value,
void *context) {
#pragma unused(key)
GPBField *field = value;
size_t *result = context;
*result += [field serializedSize];
}
- (size_t)serializedSize {
size_t result = 0;
if (fields_) {
CFDictionaryApplyFunction(fields_, GPBUnknownFieldSetSerializedSize,
&result);
}
return result;
}
static void GPBUnknownFieldSetWriteAsMessageSetTo(const void *key,
const void *value,
void *context) {
#pragma unused(key)
GPBField *field = value;
GPBCodedOutputStream *output = context;
[field writeAsMessageSetExtensionToOutput:output];
}
- (void)writeAsMessageSetTo:(GPBCodedOutputStream *)output {
if (fields_) {
CFDictionaryApplyFunction(fields_, GPBUnknownFieldSetWriteAsMessageSetTo,
output);
}
}
static void GPBUnknownFieldSetSerializedSizeAsMessageSet(const void *key,
const void *value,
void *context) {
#pragma unused(key)
GPBField *field = value;
size_t *result = context;
*result += [field serializedSizeAsMessageSetExtension];
}
- (size_t)serializedSizeAsMessageSet {
size_t result = 0;
if (fields_) {
CFDictionaryApplyFunction(
fields_, GPBUnknownFieldSetSerializedSizeAsMessageSet, &result);
}
return result;
}
- (NSData *)data {
NSMutableData *data = [NSMutableData dataWithLength:self.serializedSize];
GPBCodedOutputStream *output =
[[GPBCodedOutputStream alloc] initWithData:data];
[self writeToCodedOutputStream:output];
[output release];
return data;
}
+ (BOOL)isFieldTag:(int32_t)tag {
return GPBWireFormatGetTagWireType(tag) != GPBWireFormatEndGroup;
}
- (void)addField:(GPBField *)field {
int32_t number = [field number];
checkNumber(number);
if (!fields_) {
CFDictionaryKeyCallBacks keyCallBacks = {
// See description above for reason for using custom dictionary.
0, GPBUnknownFieldSetKeyRetain, GPBUnknownFieldSetKeyRelease,
GPBUnknownFieldSetCopyKeyDescription, GPBUnknownFieldSetKeyEqual,
GPBUnknownFieldSetKeyHash,
};
fields_ = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &keyCallBacks,
&kCFTypeDictionaryValueCallBacks);
}
ssize_t key = number;
CFDictionarySetValue(fields_, (const void *)key, field);
}
- (GPBField *)mutableFieldForNumber:(int32_t)number create:(BOOL)create {
ssize_t key = number;
GPBField *existing =
fields_ ? CFDictionaryGetValue(fields_, (const void *)key) : nil;
if (!existing && create) {
existing = [[GPBField alloc] initWithNumber:number];
// This retains existing.
[self addField:existing];
[existing release];
}
return existing;
}
static void GPBUnknownFieldSetMergeUnknownFields(const void *key,
const void *value,
void *context) {
#pragma unused(key)
GPBField *field = value;
GPBUnknownFieldSet *self = context;
int32_t number = [field number];
checkNumber(number);
GPBField *oldField = [self mutableFieldForNumber:number create:NO];
if (oldField) {
[oldField mergeFromField:field];
} else {
// Merge only comes from GPBMessage's mergeFrom:, so it means we are on
// mutable message and are an mutable instance, so make sure we need
// mutable fields.
GPBField *fieldCopy = [field copy];
[self addField:fieldCopy];
[fieldCopy release];
}
}
- (void)mergeUnknownFields:(GPBUnknownFieldSet *)other {
if (other && other->fields_) {
CFDictionaryApplyFunction(other->fields_,
GPBUnknownFieldSetMergeUnknownFields, self);
}
}
- (void)mergeFromData:(NSData *)data {
GPBCodedInputStream *input = [[GPBCodedInputStream alloc] initWithData:data];
[self mergeFromCodedInputStream:input];
[input checkLastTagWas:0];
[input release];
}
- (void)mergeVarintField:(int32_t)number value:(int32_t)value {
checkNumber(number);
[[self mutableFieldForNumber:number create:YES] addVarint:value];
}
- (BOOL)mergeFieldFrom:(int32_t)tag input:(GPBCodedInputStream *)input {
int32_t number = GPBWireFormatGetTagFieldNumber(tag);
GPBCodedInputStreamState *state = &input->state_;
switch (GPBWireFormatGetTagWireType(tag)) {
case GPBWireFormatVarint: {
GPBField *field = [self mutableFieldForNumber:number create:YES];
[field addVarint:GPBCodedInputStreamReadInt64(state)];
return YES;
}
case GPBWireFormatFixed64: {
GPBField *field = [self mutableFieldForNumber:number create:YES];
[field addFixed64:GPBCodedInputStreamReadFixed64(state)];
return YES;
}
case GPBWireFormatLengthDelimited: {
NSData *data = GPBCodedInputStreamReadRetainedData(state);
GPBField *field = [self mutableFieldForNumber:number create:YES];
[field addLengthDelimited:data];
[data release];
return YES;
}
case GPBWireFormatStartGroup: {
GPBUnknownFieldSet *unknownFieldSet = [[GPBUnknownFieldSet alloc] init];
[input readUnknownGroup:number message:unknownFieldSet];
GPBField *field = [self mutableFieldForNumber:number create:YES];
[field addGroup:unknownFieldSet];
[unknownFieldSet release];
return YES;
}
case GPBWireFormatEndGroup:
return NO;
case GPBWireFormatFixed32: {
GPBField *field = [self mutableFieldForNumber:number create:YES];
[field addFixed32:GPBCodedInputStreamReadFixed32(state)];
return YES;
}
}
}
- (void)mergeMessageSetMessage:(int32_t)number data:(NSData *)messageData {
[[self mutableFieldForNumber:number create:YES]
addLengthDelimited:messageData];
}
- (void)addUnknownMapEntry:(int32_t)fieldNum value:(NSData *)data {
GPBField *field = [self mutableFieldForNumber:fieldNum create:YES];
[field addLengthDelimited:data];
}
- (void)mergeFromCodedInputStream:(GPBCodedInputStream *)input {
while (YES) {
int32_t tag = GPBCodedInputStreamReadTag(&input->state_);
if (tag == 0 || ![self mergeFieldFrom:tag input:input]) {
break;
}
}
}
- (void)getTags:(int32_t *)tags {
if (!fields_) return;
size_t count = CFDictionaryGetCount(fields_);
ssize_t keys[count];
CFDictionaryGetKeysAndValues(fields_, (const void **)keys, NULL);
for (size_t i = 0; i < count; ++i) {
tags[i] = (int32_t)keys[i];
}
}
@end

@ -0,0 +1,61 @@
// 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 "GPBUnknownFieldSet.h"
@class GPBCodedOutputStream;
@class GPBCodedInputStream;
@interface GPBUnknownFieldSet ()
+ (BOOL)isFieldTag:(int32_t)tag;
- (NSData *)data;
- (size_t)serializedSize;
- (size_t)serializedSizeAsMessageSet;
- (void)writeToCodedOutputStream:(GPBCodedOutputStream *)output;
- (void)writeAsMessageSetTo:(GPBCodedOutputStream *)output;
- (void)mergeUnknownFields:(GPBUnknownFieldSet *)other;
- (void)mergeFromCodedInputStream:(GPBCodedInputStream *)input;
- (void)mergeFromData:(NSData *)data;
- (void)mergeVarintField:(int32_t)number value:(int32_t)value;
- (BOOL)mergeFieldFrom:(int32_t)tag input:(GPBCodedInputStream *)input;
- (void)mergeMessageSetMessage:(int32_t)number data:(NSData *)messageData;
- (void)addUnknownMapEntry:(int32_t)fieldNum value:(NSData *)data;
@end

@ -0,0 +1,181 @@
// 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 "GPBMessage.h"
#import "GPBTypes.h"
CF_EXTERN_C_BEGIN
BOOL GPBMessageHasFieldNumberSet(GPBMessage *self, uint32_t fieldNumber);
BOOL GPBMessageHasFieldSet(GPBMessage *self, GPBFieldDescriptor *field);
void GPBClearMessageField(GPBMessage *self, GPBFieldDescriptor *field);
// Returns an empty NSData to assign to byte fields when you wish
// to assign them to empty. Prevents allocating a lot of little [NSData data]
// objects.
NSData *GPBEmptyNSData(void) __attribute__((pure));
//%PDDM-EXPAND GPB_IVAR_ACCESSORS()
// This block of code is generated, do not edit it directly.
// Getters and Setters for ivars named |name| from instance self.
NSData* GPBGetDataIvarWithField(GPBMessage *self,
GPBFieldDescriptor *field);
void GPBSetDataIvarWithField(GPBMessage *self,
GPBFieldDescriptor *field,
NSData* value);
NSString* GPBGetStringIvarWithField(GPBMessage *self,
GPBFieldDescriptor *field);
void GPBSetStringIvarWithField(GPBMessage *self,
GPBFieldDescriptor *field,
NSString* value);
GPBMessage* GPBGetMessageIvarWithField(GPBMessage *self,
GPBFieldDescriptor *field);
void GPBSetMessageIvarWithField(GPBMessage *self,
GPBFieldDescriptor *field,
GPBMessage* value);
GPBMessage* GPBGetGroupIvarWithField(GPBMessage *self,
GPBFieldDescriptor *field);
void GPBSetGroupIvarWithField(GPBMessage *self,
GPBFieldDescriptor *field,
GPBMessage* value);
BOOL GPBGetBoolIvarWithField(GPBMessage *self,
GPBFieldDescriptor *field);
void GPBSetBoolIvarWithField(GPBMessage *self,
GPBFieldDescriptor *field,
BOOL value);
int32_t GPBGetInt32IvarWithField(GPBMessage *self,
GPBFieldDescriptor *field);
void GPBSetInt32IvarWithField(GPBMessage *self,
GPBFieldDescriptor *field,
int32_t value);
int32_t GPBGetSFixed32IvarWithField(GPBMessage *self,
GPBFieldDescriptor *field);
void GPBSetSFixed32IvarWithField(GPBMessage *self,
GPBFieldDescriptor *field,
int32_t value);
int32_t GPBGetSInt32IvarWithField(GPBMessage *self,
GPBFieldDescriptor *field);
void GPBSetSInt32IvarWithField(GPBMessage *self,
GPBFieldDescriptor *field,
int32_t value);
int32_t GPBGetEnumIvarWithField(GPBMessage *self,
GPBFieldDescriptor *field);
void GPBSetEnumIvarWithField(GPBMessage *self,
GPBFieldDescriptor *field,
int32_t value);
uint32_t GPBGetUInt32IvarWithField(GPBMessage *self,
GPBFieldDescriptor *field);
void GPBSetUInt32IvarWithField(GPBMessage *self,
GPBFieldDescriptor *field,
uint32_t value);
uint32_t GPBGetFixed32IvarWithField(GPBMessage *self,
GPBFieldDescriptor *field);
void GPBSetFixed32IvarWithField(GPBMessage *self,
GPBFieldDescriptor *field,
uint32_t value);
int64_t GPBGetInt64IvarWithField(GPBMessage *self,
GPBFieldDescriptor *field);
void GPBSetInt64IvarWithField(GPBMessage *self,
GPBFieldDescriptor *field,
int64_t value);
int64_t GPBGetSInt64IvarWithField(GPBMessage *self,
GPBFieldDescriptor *field);
void GPBSetSInt64IvarWithField(GPBMessage *self,
GPBFieldDescriptor *field,
int64_t value);
int64_t GPBGetSFixed64IvarWithField(GPBMessage *self,
GPBFieldDescriptor *field);
void GPBSetSFixed64IvarWithField(GPBMessage *self,
GPBFieldDescriptor *field,
int64_t value);
uint64_t GPBGetUInt64IvarWithField(GPBMessage *self,
GPBFieldDescriptor *field);
void GPBSetUInt64IvarWithField(GPBMessage *self,
GPBFieldDescriptor *field,
uint64_t value);
uint64_t GPBGetFixed64IvarWithField(GPBMessage *self,
GPBFieldDescriptor *field);
void GPBSetFixed64IvarWithField(GPBMessage *self,
GPBFieldDescriptor *field,
uint64_t value);
float GPBGetFloatIvarWithField(GPBMessage *self,
GPBFieldDescriptor *field);
void GPBSetFloatIvarWithField(GPBMessage *self,
GPBFieldDescriptor *field,
float value);
double GPBGetDoubleIvarWithField(GPBMessage *self,
GPBFieldDescriptor *field);
void GPBSetDoubleIvarWithField(GPBMessage *self,
GPBFieldDescriptor *field,
double value);
//%PDDM-EXPAND-END GPB_IVAR_ACCESSORS()
// Generates a sting that should be a valid "Text Format" for the C++ version
// of Protocol Buffers. lineIndent can be nil if no additional line indent is
// needed. The comments provide the names according to the ObjC library, they
// most likely won't exactly match the original .proto file.
NSString *GPBTextFormatForMessage(GPBMessage *message, NSString *lineIndent);
NSString *GPBTextFormatForUnknownFieldSet(GPBUnknownFieldSet *unknownSet,
NSString *lineIndent);
CF_EXTERN_C_END
//%PDDM-DEFINE GPB_IVAR_ACCESSORS()
//%// Getters and Setters for ivars named |name| from instance self.
//%
//%GPB_IVAR_ACCESSORS_DECL(Data, NSData*)
//%GPB_IVAR_ACCESSORS_DECL(String, NSString*)
//%GPB_IVAR_ACCESSORS_DECL(Message, GPBMessage*)
//%GPB_IVAR_ACCESSORS_DECL(Group, GPBMessage*)
//%GPB_IVAR_ACCESSORS_DECL(Bool, BOOL)
//%GPB_IVAR_ACCESSORS_DECL(Int32, int32_t)
//%GPB_IVAR_ACCESSORS_DECL(SFixed32, int32_t)
//%GPB_IVAR_ACCESSORS_DECL(SInt32, int32_t)
//%GPB_IVAR_ACCESSORS_DECL(Enum, int32_t)
//%GPB_IVAR_ACCESSORS_DECL(UInt32, uint32_t)
//%GPB_IVAR_ACCESSORS_DECL(Fixed32, uint32_t)
//%GPB_IVAR_ACCESSORS_DECL(Int64, int64_t)
//%GPB_IVAR_ACCESSORS_DECL(SInt64, int64_t)
//%GPB_IVAR_ACCESSORS_DECL(SFixed64, int64_t)
//%GPB_IVAR_ACCESSORS_DECL(UInt64, uint64_t)
//%GPB_IVAR_ACCESSORS_DECL(Fixed64, uint64_t)
//%GPB_IVAR_ACCESSORS_DECL(Float, float)
//%GPB_IVAR_ACCESSORS_DECL(Double, double)
//%PDDM-DEFINE GPB_IVAR_ACCESSORS_DECL(NAME, TYPE)
//%TYPE GPBGet##NAME##IvarWithField(GPBMessage *self,
//% TYPE$S NAME$S GPBFieldDescriptor *field);
//%void GPBSet##NAME##IvarWithField(GPBMessage *self,
//% NAME$S GPBFieldDescriptor *field,
//% NAME$S TYPE value);

File diff suppressed because it is too large Load Diff

@ -0,0 +1,426 @@
// 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 "GPBUtilities.h"
#import "GPBDescriptor_PackagePrivate.h"
// Macros for stringifying library symbols. These are used in the generated
// PB descriptor classes wherever a library symbol name is represented as a
// string. See README.google for more information.
#define GPBStringify(S) #S
#define GPBStringifySymbol(S) GPBStringify(S)
#define GPBNSStringify(S) @#S
#define GPBNSStringifySymbol(S) GPBNSStringify(S)
// Constant to internally mark when there is no has bit.
#define GPBNoHasBit INT32_MAX
CF_EXTERN_C_BEGIN
// Conversion functions for de/serializing floating point types.
GPB_INLINE int64_t GPBConvertDoubleToInt64(double v) {
union { double f; int64_t i; } u;
u.f = v;
return u.i;
}
GPB_INLINE int32_t GPBConvertFloatToInt32(float v) {
union { float f; int32_t i; } u;
u.f = v;
return u.i;
}
GPB_INLINE double GPBConvertInt64ToDouble(int64_t v) {
union { double f; int64_t i; } u;
u.i = v;
return u.f;
}
GPB_INLINE float GPBConvertInt32ToFloat(int32_t v) {
union { float f; int32_t i; } u;
u.i = v;
return u.f;
}
GPB_INLINE int32_t GPBLogicalRightShift32(int32_t value, int32_t spaces) {
return (int32_t)((uint32_t)(value) >> spaces);
}
GPB_INLINE int64_t GPBLogicalRightShift64(int64_t value, int32_t spaces) {
return (int64_t)((uint64_t)(value) >> spaces);
}
// Decode a ZigZag-encoded 32-bit value. ZigZag encodes signed integers
// into values that can be efficiently encoded with varint. (Otherwise,
// negative values must be sign-extended to 64 bits to be varint encoded,
// thus always taking 10 bytes on the wire.)
GPB_INLINE int32_t GPBDecodeZigZag32(uint32_t n) {
return GPBLogicalRightShift32(n, 1) ^ -(n & 1);
}
// Decode a ZigZag-encoded 64-bit value. ZigZag encodes signed integers
// into values that can be efficiently encoded with varint. (Otherwise,
// negative values must be sign-extended to 64 bits to be varint encoded,
// thus always taking 10 bytes on the wire.)
GPB_INLINE int64_t GPBDecodeZigZag64(uint64_t n) {
return GPBLogicalRightShift64(n, 1) ^ -(n & 1);
}
// Encode a ZigZag-encoded 32-bit value. ZigZag encodes signed integers
// into values that can be efficiently encoded with varint. (Otherwise,
// negative values must be sign-extended to 64 bits to be varint encoded,
// thus always taking 10 bytes on the wire.)
GPB_INLINE uint32_t GPBEncodeZigZag32(int32_t n) {
// Note: the right-shift must be arithmetic
return (n << 1) ^ (n >> 31);
}
// Encode a ZigZag-encoded 64-bit value. ZigZag encodes signed integers
// into values that can be efficiently encoded with varint. (Otherwise,
// negative values must be sign-extended to 64 bits to be varint encoded,
// thus always taking 10 bytes on the wire.)
GPB_INLINE uint64_t GPBEncodeZigZag64(int64_t n) {
// Note: the right-shift must be arithmetic
return (n << 1) ^ (n >> 63);
}
GPB_INLINE BOOL GPBTypeIsObject(GPBType type) {
switch (type) {
case GPBTypeData:
case GPBTypeString:
case GPBTypeMessage:
case GPBTypeGroup:
return YES;
default:
return NO;
}
}
GPB_INLINE BOOL GPBTypeIsMessage(GPBType type) {
switch (type) {
case GPBTypeMessage:
case GPBTypeGroup:
return YES;
default:
return NO;
}
}
GPB_INLINE BOOL GPBTypeIsEnum(GPBType type) { return type == GPBTypeEnum; }
GPB_INLINE BOOL GPBFieldTypeIsMessage(GPBFieldDescriptor *field) {
return GPBTypeIsMessage(field->description_->type);
}
GPB_INLINE BOOL GPBFieldTypeIsObject(GPBFieldDescriptor *field) {
return GPBTypeIsObject(field->description_->type);
}
GPB_INLINE BOOL GPBExtensionIsMessage(GPBExtensionDescriptor *ext) {
return GPBTypeIsMessage(ext->description_->type);
}
// The field is an array/map or it has an object value.
GPB_INLINE BOOL GPBFieldStoresObject(GPBFieldDescriptor *field) {
GPBMessageFieldDescription *desc = field->description_;
if ((desc->flags & (GPBFieldRepeated | GPBFieldMapKeyMask)) != 0) {
return YES;
}
return GPBTypeIsObject(desc->type);
}
BOOL GPBGetHasIvar(GPBMessage *self, int32_t index, uint32_t fieldNumber);
void GPBSetHasIvar(GPBMessage *self, int32_t idx, uint32_t fieldNumber,
BOOL value);
uint32_t GPBGetHasOneof(GPBMessage *self, int32_t index);
GPB_INLINE BOOL
GPBGetHasIvarField(GPBMessage *self, GPBFieldDescriptor *field) {
GPBMessageFieldDescription *fieldDesc = field->description_;
return GPBGetHasIvar(self, fieldDesc->hasIndex, fieldDesc->number);
}
GPB_INLINE void GPBSetHasIvarField(GPBMessage *self, GPBFieldDescriptor *field,
BOOL value) {
GPBMessageFieldDescription *fieldDesc = field->description_;
GPBSetHasIvar(self, fieldDesc->hasIndex, fieldDesc->number, value);
}
void GPBMaybeClearOneof(GPBMessage *self, GPBOneofDescriptor *oneof,
uint32_t fieldNumberNotToClear);
//%PDDM-DEFINE GPB_IVAR_SET_DECL(NAME, TYPE)
//%void GPBSet##NAME##IvarWithFieldInternal(GPBMessage *self,
//% NAME$S GPBFieldDescriptor *field,
//% NAME$S TYPE value,
//% NAME$S GPBFileSyntax syntax);
//%PDDM-EXPAND GPB_IVAR_SET_DECL(Bool, BOOL)
// This block of code is generated, do not edit it directly.
void GPBSetBoolIvarWithFieldInternal(GPBMessage *self,
GPBFieldDescriptor *field,
BOOL value,
GPBFileSyntax syntax);
//%PDDM-EXPAND GPB_IVAR_SET_DECL(Int32, int32_t)
// This block of code is generated, do not edit it directly.
void GPBSetInt32IvarWithFieldInternal(GPBMessage *self,
GPBFieldDescriptor *field,
int32_t value,
GPBFileSyntax syntax);
//%PDDM-EXPAND GPB_IVAR_SET_DECL(UInt32, uint32_t)
// This block of code is generated, do not edit it directly.
void GPBSetUInt32IvarWithFieldInternal(GPBMessage *self,
GPBFieldDescriptor *field,
uint32_t value,
GPBFileSyntax syntax);
//%PDDM-EXPAND GPB_IVAR_SET_DECL(Int64, int64_t)
// This block of code is generated, do not edit it directly.
void GPBSetInt64IvarWithFieldInternal(GPBMessage *self,
GPBFieldDescriptor *field,
int64_t value,
GPBFileSyntax syntax);
//%PDDM-EXPAND GPB_IVAR_SET_DECL(UInt64, uint64_t)
// This block of code is generated, do not edit it directly.
void GPBSetUInt64IvarWithFieldInternal(GPBMessage *self,
GPBFieldDescriptor *field,
uint64_t value,
GPBFileSyntax syntax);
//%PDDM-EXPAND GPB_IVAR_SET_DECL(Float, float)
// This block of code is generated, do not edit it directly.
void GPBSetFloatIvarWithFieldInternal(GPBMessage *self,
GPBFieldDescriptor *field,
float value,
GPBFileSyntax syntax);
//%PDDM-EXPAND GPB_IVAR_SET_DECL(Double, double)
// This block of code is generated, do not edit it directly.
void GPBSetDoubleIvarWithFieldInternal(GPBMessage *self,
GPBFieldDescriptor *field,
double value,
GPBFileSyntax syntax);
//%PDDM-EXPAND GPB_IVAR_SET_DECL(Enum, int32_t)
// This block of code is generated, do not edit it directly.
void GPBSetEnumIvarWithFieldInternal(GPBMessage *self,
GPBFieldDescriptor *field,
int32_t value,
GPBFileSyntax syntax);
//%PDDM-EXPAND-END (8 expansions)
int32_t GPBGetEnumIvarWithFieldInternal(GPBMessage *self,
GPBFieldDescriptor *field,
GPBFileSyntax syntax);
id GPBGetObjectIvarWithField(GPBMessage *self, GPBFieldDescriptor *field);
void GPBSetObjectIvarWithFieldInternal(GPBMessage *self,
GPBFieldDescriptor *field, id value,
GPBFileSyntax syntax);
void GPBSetRetainedObjectIvarWithFieldInternal(GPBMessage *self,
GPBFieldDescriptor *field,
id __attribute__((ns_consumed))
value,
GPBFileSyntax syntax);
// GPBGetObjectIvarWithField will automatically create the field (message) if
// it doesn't exist. GPBGetObjectIvarWithFieldNoAutocreate will return nil.
id GPBGetObjectIvarWithFieldNoAutocreate(GPBMessage *self,
GPBFieldDescriptor *field);
void GPBSetAutocreatedRetainedObjectIvarWithField(
GPBMessage *self, GPBFieldDescriptor *field,
id __attribute__((ns_consumed)) value);
// Clears and releases the autocreated message ivar, if it's autocreated. If
// it's not set as autocreated, this method does nothing.
void GPBClearAutocreatedMessageIvarWithField(GPBMessage *self,
GPBFieldDescriptor *field);
// Utilities for applying various functions based on Objective C types.
// A basic functor that is passed a field and a context. Returns YES
// if the calling function should continue processing, and NO if the calling
// function should stop processing.
typedef BOOL (*GPBApplyFunction)(GPBFieldDescriptor *field, void *context);
// Functions called for various types. See ApplyFunctionsToMessageFields.
typedef enum {
GPBApplyFunctionObject,
GPBApplyFunctionBool,
GPBApplyFunctionInt32,
GPBApplyFunctionUInt32,
GPBApplyFunctionInt64,
GPBApplyFunctionUInt64,
GPBApplyFunctionFloat,
GPBApplyFunctionDouble,
} GPBApplyFunctionOrder;
enum {
// A count of the number of types in GPBApplyFunctionOrder. Separated out
// from the GPBApplyFunctionOrder enum to avoid warnings regarding not
// handling GPBApplyFunctionCount in switch statements.
GPBApplyFunctionCount = GPBApplyFunctionDouble + 1
};
typedef GPBApplyFunction GPBApplyFunctions[GPBApplyFunctionCount];
// Functions called for various types.
// See ApplyStrictFunctionsToMessageFields.
// They are in the same order as the GPBTypes enum.
typedef GPBApplyFunction GPBApplyStrictFunctions[GPBTypeCount];
// A macro for easily initializing a GPBApplyFunctions struct
// GPBApplyFunctions foo = GPBAPPLY_FUNCTIONS_INIT(Foo);
#define GPBAPPLY_FUNCTIONS_INIT(PREFIX) \
{ \
PREFIX##Object, \
PREFIX##Bool, \
PREFIX##Int32, \
PREFIX##UInt32, \
PREFIX##Int64, \
PREFIX##UInt64, \
PREFIX##Float, \
PREFIX##Double, \
}
// A macro for easily initializing a GPBApplyStrictFunctions struct
// GPBApplyStrictFunctions foo = GPBAPPLY_STRICT_FUNCTIONS_INIT(Foo);
// These need to stay in the same order as
// the GPBType enum.
#define GPBAPPLY_STRICT_FUNCTIONS_INIT(PREFIX) \
{ \
PREFIX##Bool, \
PREFIX##Fixed32, \
PREFIX##SFixed32, \
PREFIX##Float, \
PREFIX##Fixed64, \
PREFIX##SFixed64, \
PREFIX##Double, \
PREFIX##Int32, \
PREFIX##Int64, \
PREFIX##SInt32, \
PREFIX##SInt64, \
PREFIX##UInt32, \
PREFIX##UInt64, \
PREFIX##Data, \
PREFIX##String, \
PREFIX##Message, \
PREFIX##Group, \
PREFIX##Enum, \
}
// Iterates over the fields of a proto |msg| and applies the functions in
// |functions| to them with |context|. If one of the functions in |functions|
// returns NO, it will return immediately and not process the rest of the
// ivars. The types in the fields are mapped so:
// Int32, Enum, SInt32 and SFixed32 will be mapped to the int32Function,
// UInt32 and Fixed32 will be mapped to the uint32Function,
// Bytes, String, Message and Group will be mapped to the objectFunction,
// etc..
// If you require more specific mappings look at
// GPBApplyStrictFunctionsToMessageFields.
void GPBApplyFunctionsToMessageFields(GPBApplyFunctions *functions,
GPBMessage *msg, void *context);
// Iterates over the fields of a proto |msg| and applies the functions in
// |functions| to them with |context|. If one of the functions in |functions|
// returns NO, it will return immediately and not process the rest of the
// ivars. The types in the fields are mapped directly:
// Int32 -> functions[GPBTypeInt32],
// SFixed32 -> functions[GPBTypeSFixed32],
// etc...
// If you can use looser mappings look at GPBApplyFunctionsToMessageFields.
void GPBApplyStrictFunctionsToMessageFields(GPBApplyStrictFunctions *functions,
GPBMessage *msg, void *context);
// Applies the appropriate function in |functions| based on |field|.
// Returns the value from function(name, context).
// Throws an exception if the type is unrecognized.
BOOL GPBApplyFunctionsBasedOnField(GPBFieldDescriptor *field,
GPBApplyFunctions *functions, void *context);
// Returns an Objective C encoding for |selector|. |instanceSel| should be
// YES if it's an instance selector (as opposed to a class selector).
// |selector| must be a selector from MessageSignatureProtocol.
const char *GPBMessageEncodingForSelector(SEL selector, BOOL instanceSel);
// Helper for text format name encoding.
// decodeData is the data describing the sepecial decodes.
// key and inputString are the input that needs decoding.
NSString *GPBDecodeTextFormatName(const uint8_t *decodeData, int32_t key,
NSString *inputString);
// A series of selectors that are used solely to get @encoding values
// for them by the dynamic protobuf runtime code. See
// GPBMessageEncodingForSelector for details.
@protocol GPBMessageSignatureProtocol
@optional
#define GPB_MESSAGE_SIGNATURE_ENTRY(TYPE, NAME) \
-(TYPE)get##NAME; \
-(void)set##NAME : (TYPE)value; \
-(TYPE)get##NAME##AtIndex : (NSUInteger)index;
GPB_MESSAGE_SIGNATURE_ENTRY(BOOL, Bool)
GPB_MESSAGE_SIGNATURE_ENTRY(uint32_t, Fixed32)
GPB_MESSAGE_SIGNATURE_ENTRY(int32_t, SFixed32)
GPB_MESSAGE_SIGNATURE_ENTRY(float, Float)
GPB_MESSAGE_SIGNATURE_ENTRY(uint64_t, Fixed64)
GPB_MESSAGE_SIGNATURE_ENTRY(int64_t, SFixed64)
GPB_MESSAGE_SIGNATURE_ENTRY(double, Double)
GPB_MESSAGE_SIGNATURE_ENTRY(int32_t, Int32)
GPB_MESSAGE_SIGNATURE_ENTRY(int64_t, Int64)
GPB_MESSAGE_SIGNATURE_ENTRY(int32_t, SInt32)
GPB_MESSAGE_SIGNATURE_ENTRY(int64_t, SInt64)
GPB_MESSAGE_SIGNATURE_ENTRY(uint32_t, UInt32)
GPB_MESSAGE_SIGNATURE_ENTRY(uint64_t, UInt64)
GPB_MESSAGE_SIGNATURE_ENTRY(NSData *, Data)
GPB_MESSAGE_SIGNATURE_ENTRY(NSString *, String)
GPB_MESSAGE_SIGNATURE_ENTRY(GPBMessage *, Message)
GPB_MESSAGE_SIGNATURE_ENTRY(GPBMessage *, Group)
GPB_MESSAGE_SIGNATURE_ENTRY(int32_t, Enum)
#undef GPB_MESSAGE_SIGNATURE_ENTRY
- (id)getArray;
- (void)setArray:(NSArray *)array;
+ (id)getClassValue;
@end
CF_EXTERN_C_END

@ -0,0 +1,48 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2015 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 "google/protobuf/Timestamp.pbobjc.h"
#import "google/protobuf/Duration.pbobjc.h"
// Extension to GPBTimestamp to work with standard Foundation time/date types.
@interface GPBTimestamp (GBPWellKnownTypes)
@property(nonatomic, readwrite, strong) NSDate *date;
@property(nonatomic, readwrite) NSTimeInterval timeIntervalSince1970;
- (instancetype)initWithDate:(NSDate *)date;
- (instancetype)initWithTimeIntervalSince1970:(NSTimeInterval)timeIntervalSince1970;
@end
// Extension to GPBDuration to work with standard Foundation time type.
@interface GPBDuration (GBPWellKnownTypes)
@property(nonatomic, readwrite) NSTimeInterval timeIntervalSince1970;
- (instancetype)initWithTimeIntervalSince1970:(NSTimeInterval)timeIntervalSince1970;
@end

@ -0,0 +1,117 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2015 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.
// Importing sources here to force the linker to include our category methods in
// the static library. If these were compiled separately, the category methods
// below would be stripped by the linker.
#import "google/protobuf/Timestamp.pbobjc.m"
#import "google/protobuf/Duration.pbobjc.m"
#import "GPBWellKnownTypes.h"
static NSTimeInterval TimeIntervalSince1970FromSecondsAndNanos(int64_t seconds,
int32_t nanos) {
return seconds + (NSTimeInterval)nanos / 1e9;
}
static int32_t SecondsAndNanosFromTimeIntervalSince1970(NSTimeInterval time,
int64_t *outSeconds) {
NSTimeInterval seconds;
NSTimeInterval nanos = modf(time, &seconds);
nanos *= 1e9;
*outSeconds = (int64_t)seconds;
return (int32_t)nanos;
}
@implementation GPBTimestamp (GBPWellKnownTypes)
- (instancetype)initWithDate:(NSDate *)date {
return [self initWithTimeIntervalSince1970:date.timeIntervalSince1970];
}
- (instancetype)initWithTimeIntervalSince1970:(NSTimeInterval)timeIntervalSince1970 {
if ((self = [super init])) {
int64_t seconds;
int32_t nanos = SecondsAndNanosFromTimeIntervalSince1970(
timeIntervalSince1970, &seconds);
self.seconds = seconds;
self.nanos = nanos;
}
return self;
}
- (NSDate *)date {
return [NSDate dateWithTimeIntervalSince1970:self.timeIntervalSince1970];
}
- (void)setDate:(NSDate *)date {
self.timeIntervalSince1970 = date.timeIntervalSince1970;
}
- (NSTimeInterval)timeIntervalSince1970 {
return TimeIntervalSince1970FromSecondsAndNanos(self.seconds, self.nanos);
}
- (void)setTimeIntervalSince1970:(NSTimeInterval)timeIntervalSince1970 {
int64_t seconds;
int32_t nanos =
SecondsAndNanosFromTimeIntervalSince1970(timeIntervalSince1970, &seconds);
self.seconds = seconds;
self.nanos = nanos;
}
@end
@implementation GPBDuration (GBPWellKnownTypes)
- (instancetype)initWithTimeIntervalSince1970:(NSTimeInterval)timeIntervalSince1970 {
if ((self = [super init])) {
int64_t seconds;
int32_t nanos = SecondsAndNanosFromTimeIntervalSince1970(
timeIntervalSince1970, &seconds);
self.seconds = seconds;
self.nanos = nanos;
}
return self;
}
- (NSTimeInterval)timeIntervalSince1970 {
return TimeIntervalSince1970FromSecondsAndNanos(self.seconds, self.nanos);
}
- (void)setTimeIntervalSince1970:(NSTimeInterval)timeIntervalSince1970 {
int64_t seconds;
int32_t nanos =
SecondsAndNanosFromTimeIntervalSince1970(timeIntervalSince1970, &seconds);
self.seconds = seconds;
self.nanos = nanos;
}
@end

@ -0,0 +1,68 @@
// 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 "GPBTypes.h"
CF_EXTERN_C_BEGIN
typedef enum {
GPBWireFormatVarint = 0,
GPBWireFormatFixed64 = 1,
GPBWireFormatLengthDelimited = 2,
GPBWireFormatStartGroup = 3,
GPBWireFormatEndGroup = 4,
GPBWireFormatFixed32 = 5,
} GPBWireFormat;
enum {
GPBWireFormatMessageSetItem = 1,
GPBWireFormatMessageSetTypeId = 2,
GPBWireFormatMessageSetMessage = 3
};
uint32_t GPBWireFormatMakeTag(uint32_t fieldNumber, GPBWireFormat wireType)
__attribute__((const));
GPBWireFormat GPBWireFormatGetTagWireType(uint32_t tag) __attribute__((const));
uint32_t GPBWireFormatGetTagFieldNumber(uint32_t tag) __attribute__((const));
GPBWireFormat GPBWireFormatForType(GPBType type, BOOL isPacked)
__attribute__((const));
#define GPBWireFormatMessageSetItemTag \
(GPBWireFormatMakeTag(GPBWireFormatMessageSetItem, GPBWireFormatStartGroup))
#define GPBWireFormatMessageSetItemEndTag \
(GPBWireFormatMakeTag(GPBWireFormatMessageSetItem, GPBWireFormatEndGroup))
#define GPBWireFormatMessageSetTypeIdTag \
(GPBWireFormatMakeTag(GPBWireFormatMessageSetTypeId, GPBWireFormatVarint))
#define GPBWireFormatMessageSetMessageTag \
(GPBWireFormatMakeTag(GPBWireFormatMessageSetMessage, \
GPBWireFormatLengthDelimited))
CF_EXTERN_C_END

@ -0,0 +1,78 @@
// 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 "GPBWireFormat.h"
#import "GPBUtilities_PackagePrivate.h"
enum {
GPBWireFormatTagTypeBits = 3,
GPBWireFormatTagTypeMask = 7 /* = (1 << GPBWireFormatTagTypeBits) - 1 */,
};
uint32_t GPBWireFormatMakeTag(uint32_t fieldNumber, GPBWireFormat wireType) {
return (fieldNumber << GPBWireFormatTagTypeBits) | wireType;
}
GPBWireFormat GPBWireFormatGetTagWireType(uint32_t tag) {
return (GPBWireFormat)(tag & GPBWireFormatTagTypeMask);
}
uint32_t GPBWireFormatGetTagFieldNumber(uint32_t tag) {
return GPBLogicalRightShift32(tag, GPBWireFormatTagTypeBits);
}
GPBWireFormat GPBWireFormatForType(GPBType type, BOOL isPacked) {
if (isPacked) {
return GPBWireFormatLengthDelimited;
}
static const GPBWireFormat format[GPBTypeCount] = {
GPBWireFormatVarint, // GPBTypeBool
GPBWireFormatFixed32, // GPBTypeFixed32
GPBWireFormatFixed32, // GPBTypeSFixed32
GPBWireFormatFixed32, // GPBTypeFloat
GPBWireFormatFixed64, // GPBTypeFixed64
GPBWireFormatFixed64, // GPBTypeSFixed64
GPBWireFormatFixed64, // GPBTypeDouble
GPBWireFormatVarint, // GPBTypeInt32
GPBWireFormatVarint, // GPBTypeInt64
GPBWireFormatVarint, // GPBTypeSInt32
GPBWireFormatVarint, // GPBTypeSInt64
GPBWireFormatVarint, // GPBTypeUInt32
GPBWireFormatVarint, // GPBTypeUInt64
GPBWireFormatLengthDelimited, // GPBTypeBytes
GPBWireFormatLengthDelimited, // GPBTypeString
GPBWireFormatLengthDelimited, // GPBTypeMessage
GPBWireFormatStartGroup, // GPBTypeGroup
GPBWireFormatVarint // GPBTypeEnum
};
return format[type];
}

@ -0,0 +1,919 @@
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 47;
objects = {
/* Begin PBXAggregateTarget section */
8BD3981414BE4AE70081D629 /* Compile_Protos */ = {
isa = PBXAggregateTarget;
buildConfigurationList = 8BD3981714BE4AE70081D629 /* Build configuration list for PBXAggregateTarget "Compile_Protos" */;
buildPhases = (
8BD3981814BE4AF30081D629 /* ShellScript */,
);
dependencies = (
);
name = Compile_Protos;
productName = Compile_Protos;
};
/* End PBXAggregateTarget section */
/* Begin PBXBuildFile section */
2CFB390415C718CE00CBF84D /* Descriptor.pbobjc.m in Sources */ = {isa = PBXBuildFile; fileRef = 8BD3982214BE5B0C0081D629 /* Descriptor.pbobjc.m */; };
5102DABC1891A073002037B6 /* GPBConcurrencyTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 5102DABB1891A052002037B6 /* GPBConcurrencyTests.m */; };
7461B5360F94FB4600A0C422 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D30AB110D05D00D00671497 /* Foundation.framework */; };
7461B53C0F94FB4E00A0C422 /* GPBCodedInputStream.m in Sources */ = {isa = PBXBuildFile; fileRef = 7461B48F0F94F99000A0C422 /* GPBCodedInputStream.m */; };
7461B53D0F94FB4E00A0C422 /* GPBCodedOutputStream.m in Sources */ = {isa = PBXBuildFile; fileRef = 7461B4910F94F99000A0C422 /* GPBCodedOutputStream.m */; };
7461B5490F94FB4E00A0C422 /* GPBExtensionRegistry.m in Sources */ = {isa = PBXBuildFile; fileRef = 7461B4A90F94F99000A0C422 /* GPBExtensionRegistry.m */; };
7461B54C0F94FB4E00A0C422 /* GPBField.m in Sources */ = {isa = PBXBuildFile; fileRef = 7461B4AF0F94F99000A0C422 /* GPBField.m */; };
7461B5530F94FB4E00A0C422 /* GPBMessage.m in Sources */ = {isa = PBXBuildFile; fileRef = 7461B4BF0F94F99000A0C422 /* GPBMessage.m */; };
7461B5610F94FB4E00A0C422 /* GPBUnknownFieldSet.m in Sources */ = {isa = PBXBuildFile; fileRef = 7461B4E20F94F99000A0C422 /* GPBUnknownFieldSet.m */; };
7461B5630F94FB4E00A0C422 /* GPBUtilities.m in Sources */ = {isa = PBXBuildFile; fileRef = 7461B4E60F94F99000A0C422 /* GPBUtilities.m */; };
7461B5640F94FB4E00A0C422 /* GPBWireFormat.m in Sources */ = {isa = PBXBuildFile; fileRef = 7461B4E80F94F99000A0C422 /* GPBWireFormat.m */; };
8B210CCE159383D60032D72D /* golden_message in Resources */ = {isa = PBXBuildFile; fileRef = 8B210CCD159383D60032D72D /* golden_message */; };
8B210CD0159386920032D72D /* golden_packed_fields_message in Resources */ = {isa = PBXBuildFile; fileRef = 8B210CCF159386920032D72D /* golden_packed_fields_message */; };
8B4248BB1A8C256A00BC1EC6 /* GPBSwiftTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8B4248BA1A8C256A00BC1EC6 /* GPBSwiftTests.swift */; };
8B4248D21A927E1500BC1EC6 /* GPBWellKnownTypes.m in Sources */ = {isa = PBXBuildFile; fileRef = 8B4248D01A927E1500BC1EC6 /* GPBWellKnownTypes.m */; };
8B4248DC1A92933A00BC1EC6 /* GPBWellKnownTypesTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 8B4248DB1A92933A00BC1EC6 /* GPBWellKnownTypesTest.m */; };
8B79657B14992E3F002FFBFC /* GPBRootObject.m in Sources */ = {isa = PBXBuildFile; fileRef = 8B79657914992E3E002FFBFC /* GPBRootObject.m */; };
8B79657D14992E3F002FFBFC /* GPBRootObject.m in Sources */ = {isa = PBXBuildFile; fileRef = 8B79657914992E3E002FFBFC /* GPBRootObject.m */; };
8B8B615D17DF7056002EE618 /* GPBARCUnittestProtos.m in Sources */ = {isa = PBXBuildFile; fileRef = 8B8B615C17DF7056002EE618 /* GPBARCUnittestProtos.m */; settings = {COMPILER_FLAGS = "-fobjc-arc"; }; };
8B96157414C8C38C00A2AC0B /* GPBDescriptor.m in Sources */ = {isa = PBXBuildFile; fileRef = 8B96157314C8C38C00A2AC0B /* GPBDescriptor.m */; };
8B96157514CA019D00A2AC0B /* Descriptor.pbobjc.m in Sources */ = {isa = PBXBuildFile; fileRef = 8BD3982214BE5B0C0081D629 /* Descriptor.pbobjc.m */; };
8BA9364518DA5F4C0056FA2A /* GPBStringTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 8BA9364418DA5F4B0056FA2A /* GPBStringTests.m */; };
8BBEA4A9147C727D00C4ADB7 /* GPBCodedInputStreamTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 7461B69B0F94FDF800A0C422 /* GPBCodedInputStreamTests.m */; };
8BBEA4AA147C727D00C4ADB7 /* GPBCodedOuputStreamTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 7461B69D0F94FDF800A0C422 /* GPBCodedOuputStreamTests.m */; };
8BBEA4AC147C727D00C4ADB7 /* GPBMessageTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 7461B6A30F94FDF800A0C422 /* GPBMessageTests.m */; };
8BBEA4B0147C727D00C4ADB7 /* GPBTestUtilities.m in Sources */ = {isa = PBXBuildFile; fileRef = 7461B6AC0F94FDF800A0C422 /* GPBTestUtilities.m */; };
8BBEA4B6147C727D00C4ADB7 /* GPBUnknownFieldSetTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 7461B6B80F94FDF900A0C422 /* GPBUnknownFieldSetTest.m */; };
8BBEA4B7147C727D00C4ADB7 /* GPBUtilitiesTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 7461B6BA0F94FDF900A0C422 /* GPBUtilitiesTests.m */; };
8BBEA4B8147C727D00C4ADB7 /* GPBWireFormatTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 7461B6BC0F94FDF900A0C422 /* GPBWireFormatTests.m */; };
8BBEA4BB147C729200C4ADB7 /* libProtocolBuffers.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 7461B52E0F94FAF800A0C422 /* libProtocolBuffers.a */; };
8BCC29BF16FD09A000F29F4A /* GPBFilteredMessageTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 8BCC29BE16FD09A000F29F4A /* GPBFilteredMessageTests.m */; };
8BD3981F14BE59D70081D629 /* GPBUnittestProtos.m in Sources */ = {isa = PBXBuildFile; fileRef = 8BD3981E14BE59D70081D629 /* GPBUnittestProtos.m */; };
8BF8193514A0DDA600A2C982 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D30AB110D05D00D00671497 /* Foundation.framework */; };
F401DC2D1A8D444600FCC765 /* GPBArray.m in Sources */ = {isa = PBXBuildFile; fileRef = F401DC2B1A8D444600FCC765 /* GPBArray.m */; };
F401DC331A8E5C0200FCC765 /* GPBArrayTests.m in Sources */ = {isa = PBXBuildFile; fileRef = F401DC321A8E5C0200FCC765 /* GPBArrayTests.m */; };
F41C175D1833D3310064ED4D /* GPBPerfTests.m in Sources */ = {isa = PBXBuildFile; fileRef = F41C175C1833D3310064ED4D /* GPBPerfTests.m */; };
F4353D1D1AB8822D005A6198 /* GPBDescriptorTests.m in Sources */ = {isa = PBXBuildFile; fileRef = F4353D1C1AB8822D005A6198 /* GPBDescriptorTests.m */; };
F4353D231ABB1537005A6198 /* GPBDictionary.m in Sources */ = {isa = PBXBuildFile; fileRef = F4353D211ABB1537005A6198 /* GPBDictionary.m */; };
F4353D341AC06F10005A6198 /* GPBDictionaryTests+Bool.m in Sources */ = {isa = PBXBuildFile; fileRef = F4353D2D1AC06F10005A6198 /* GPBDictionaryTests+Bool.m */; };
F4353D351AC06F10005A6198 /* GPBDictionaryTests+Int32.m in Sources */ = {isa = PBXBuildFile; fileRef = F4353D2E1AC06F10005A6198 /* GPBDictionaryTests+Int32.m */; };
F4353D361AC06F10005A6198 /* GPBDictionaryTests+Int64.m in Sources */ = {isa = PBXBuildFile; fileRef = F4353D2F1AC06F10005A6198 /* GPBDictionaryTests+Int64.m */; };
F4353D371AC06F10005A6198 /* GPBDictionaryTests+String.m in Sources */ = {isa = PBXBuildFile; fileRef = F4353D301AC06F10005A6198 /* GPBDictionaryTests+String.m */; };
F4353D381AC06F10005A6198 /* GPBDictionaryTests+UInt32.m in Sources */ = {isa = PBXBuildFile; fileRef = F4353D311AC06F10005A6198 /* GPBDictionaryTests+UInt32.m */; };
F4353D391AC06F10005A6198 /* GPBDictionaryTests+UInt64.m in Sources */ = {isa = PBXBuildFile; fileRef = F4353D321AC06F10005A6198 /* GPBDictionaryTests+UInt64.m */; };
F43C88D0191D77FC009E917D /* text_format_unittest_data.txt in Resources */ = {isa = PBXBuildFile; fileRef = F43C88CF191D77FC009E917D /* text_format_unittest_data.txt */; };
F4487C4D1A9F8E0200531423 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D30AB110D05D00D00671497 /* Foundation.framework */; };
F4487C521A9F8E4D00531423 /* GPBProtocolBuffers.m in Sources */ = {isa = PBXBuildFile; fileRef = 8BCF338814ED799900BC5317 /* GPBProtocolBuffers.m */; };
F4487C751AADF7F500531423 /* GPBMessageTests+Runtime.m in Sources */ = {isa = PBXBuildFile; fileRef = F4487C741AADF7F500531423 /* GPBMessageTests+Runtime.m */; };
F4487C7F1AAF62CD00531423 /* GPBMessageTests+Serialization.m in Sources */ = {isa = PBXBuildFile; fileRef = F4487C7E1AAF62CD00531423 /* GPBMessageTests+Serialization.m */; };
F4487C831AAF6AB300531423 /* GPBMessageTests+Merge.m in Sources */ = {isa = PBXBuildFile; fileRef = F4487C821AAF6AB300531423 /* GPBMessageTests+Merge.m */; };
F45C69CC16DFD08D0081955B /* GPBExtensionField.m in Sources */ = {isa = PBXBuildFile; fileRef = F45C69CB16DFD08D0081955B /* GPBExtensionField.m */; };
F45E57C71AE6DC6A000B7D99 /* text_format_map_unittest_data.txt in Resources */ = {isa = PBXBuildFile; fileRef = F45E57C61AE6DC6A000B7D99 /* text_format_map_unittest_data.txt */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
8BBEA4BC147C729A00C4ADB7 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */;
proxyType = 1;
remoteGlobalIDString = 7461B52D0F94FAF800A0C422;
remoteInfo = ProtocolBuffers;
};
8BD3982014BE59EB0081D629 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */;
proxyType = 1;
remoteGlobalIDString = 8BD3981414BE4AE70081D629;
remoteInfo = Compile_Protos;
};
/* End PBXContainerItemProxy section */
/* Begin PBXFileReference section */
1D30AB110D05D00D00671497 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
5102DABB1891A052002037B6 /* GPBConcurrencyTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = GPBConcurrencyTests.m; sourceTree = "<group>"; };
51457B5F18D0B7AF00CCC606 /* GPBCodedInputStream_PackagePrivate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GPBCodedInputStream_PackagePrivate.h; sourceTree = "<group>"; };
515B840C18B7DEE30031753B /* GPBDescriptor_PackagePrivate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GPBDescriptor_PackagePrivate.h; sourceTree = "<group>"; };
5196A06918CE16B000B759E2 /* GPBMessage_PackagePrivate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GPBMessage_PackagePrivate.h; sourceTree = "<group>"; };
7401C1A90F950347006D8281 /* UnitTests-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "UnitTests-Info.plist"; sourceTree = "<group>"; };
7461B48D0F94F99000A0C422 /* GPBBootstrap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GPBBootstrap.h; sourceTree = "<group>"; };
7461B48E0F94F99000A0C422 /* GPBCodedInputStream.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GPBCodedInputStream.h; sourceTree = "<group>"; };
7461B48F0F94F99000A0C422 /* GPBCodedInputStream.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; path = GPBCodedInputStream.m; sourceTree = "<group>"; };
7461B4900F94F99000A0C422 /* GPBCodedOutputStream.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GPBCodedOutputStream.h; sourceTree = "<group>"; };
7461B4910F94F99000A0C422 /* GPBCodedOutputStream.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GPBCodedOutputStream.m; sourceTree = "<group>"; };
7461B4A80F94F99000A0C422 /* GPBExtensionRegistry.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GPBExtensionRegistry.h; sourceTree = "<group>"; };
7461B4A90F94F99000A0C422 /* GPBExtensionRegistry.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GPBExtensionRegistry.m; sourceTree = "<group>"; };
7461B4AE0F94F99000A0C422 /* GPBField.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GPBField.h; sourceTree = "<group>"; };
7461B4AF0F94F99000A0C422 /* GPBField.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GPBField.m; sourceTree = "<group>"; };
7461B4BE0F94F99000A0C422 /* GPBMessage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GPBMessage.h; sourceTree = "<group>"; };
7461B4BF0F94F99000A0C422 /* GPBMessage.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GPBMessage.m; sourceTree = "<group>"; };
7461B4CD0F94F99000A0C422 /* GPBProtocolBuffers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GPBProtocolBuffers.h; sourceTree = "<group>"; };
7461B4E10F94F99000A0C422 /* GPBUnknownFieldSet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GPBUnknownFieldSet.h; sourceTree = "<group>"; };
7461B4E20F94F99000A0C422 /* GPBUnknownFieldSet.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GPBUnknownFieldSet.m; sourceTree = "<group>"; };
7461B4E50F94F99000A0C422 /* GPBUtilities.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GPBUtilities.h; sourceTree = "<group>"; };
7461B4E60F94F99000A0C422 /* GPBUtilities.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GPBUtilities.m; sourceTree = "<group>"; };
7461B4E70F94F99000A0C422 /* GPBWireFormat.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GPBWireFormat.h; sourceTree = "<group>"; };
7461B4E80F94F99000A0C422 /* GPBWireFormat.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GPBWireFormat.m; sourceTree = "<group>"; };
7461B52E0F94FAF800A0C422 /* libProtocolBuffers.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libProtocolBuffers.a; sourceTree = BUILT_PRODUCTS_DIR; };
7461B69B0F94FDF800A0C422 /* GPBCodedInputStreamTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GPBCodedInputStreamTests.m; sourceTree = "<group>"; };
7461B69D0F94FDF800A0C422 /* GPBCodedOuputStreamTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GPBCodedOuputStreamTests.m; sourceTree = "<group>"; };
7461B6A30F94FDF800A0C422 /* GPBMessageTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GPBMessageTests.m; sourceTree = "<group>"; };
7461B6AB0F94FDF800A0C422 /* GPBTestUtilities.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GPBTestUtilities.h; sourceTree = "<group>"; };
7461B6AC0F94FDF800A0C422 /* GPBTestUtilities.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GPBTestUtilities.m; sourceTree = "<group>"; };
7461B6B80F94FDF900A0C422 /* GPBUnknownFieldSetTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GPBUnknownFieldSetTest.m; sourceTree = "<group>"; };
7461B6BA0F94FDF900A0C422 /* GPBUtilitiesTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GPBUtilitiesTests.m; sourceTree = "<group>"; };
7461B6BC0F94FDF900A0C422 /* GPBWireFormatTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GPBWireFormatTests.m; sourceTree = "<group>"; };
748F0CAF0FD70602000858A9 /* GPBExtensionField.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GPBExtensionField.h; sourceTree = "<group>"; };
8B09AAF614B663A7007B4184 /* unittest_objc.proto */ = {isa = PBXFileReference; lastKnownFileType = text; path = unittest_objc.proto; sourceTree = "<group>"; };
8B20A9A816F1BBFA00BE3EAD /* Filter1.txt */ = {isa = PBXFileReference; lastKnownFileType = text; path = Filter1.txt; sourceTree = "<group>"; };
8B20A9A916F1BC0600BE3EAD /* unittest_filter.proto */ = {isa = PBXFileReference; lastKnownFileType = text; path = unittest_filter.proto; sourceTree = "<group>"; };
8B210CCD159383D60032D72D /* golden_message */ = {isa = PBXFileReference; lastKnownFileType = file; path = golden_message; sourceTree = "<group>"; };
8B210CCF159386920032D72D /* golden_packed_fields_message */ = {isa = PBXFileReference; lastKnownFileType = file; path = golden_packed_fields_message; sourceTree = "<group>"; };
8B4248B81A8C254000BC1EC6 /* protobuf */ = {isa = PBXFileReference; lastKnownFileType = text; name = protobuf; path = ../../Intermediates/ProtocolBuffers_OSX.build/DerivedSources/protos/google/protobuf; sourceTree = BUILT_PRODUCTS_DIR; };
8B4248B91A8C256900BC1EC6 /* UnitTests-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "UnitTests-Bridging-Header.h"; sourceTree = "<group>"; };
8B4248BA1A8C256A00BC1EC6 /* GPBSwiftTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GPBSwiftTests.swift; sourceTree = "<group>"; };
8B4248CF1A927E1500BC1EC6 /* GPBWellKnownTypes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GPBWellKnownTypes.h; sourceTree = "<group>"; };
8B4248D01A927E1500BC1EC6 /* GPBWellKnownTypes.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GPBWellKnownTypes.m; sourceTree = "<group>"; };
8B4248D31A92826400BC1EC6 /* Duration.pbobjc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Duration.pbobjc.h; path = google/protobuf/Duration.pbobjc.h; sourceTree = "<group>"; };
8B4248D41A92826400BC1EC6 /* Duration.pbobjc.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = Duration.pbobjc.m; path = google/protobuf/Duration.pbobjc.m; sourceTree = "<group>"; };
8B4248D51A92826400BC1EC6 /* Timestamp.pbobjc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Timestamp.pbobjc.h; path = google/protobuf/Timestamp.pbobjc.h; sourceTree = "<group>"; };
8B4248D61A92826400BC1EC6 /* Timestamp.pbobjc.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = Timestamp.pbobjc.m; path = google/protobuf/Timestamp.pbobjc.m; sourceTree = "<group>"; };
8B4248DB1A92933A00BC1EC6 /* GPBWellKnownTypesTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GPBWellKnownTypesTest.m; sourceTree = "<group>"; };
8B42494B1A92A16600BC1EC6 /* descriptor.proto */ = {isa = PBXFileReference; lastKnownFileType = text; name = descriptor.proto; path = ../src/google/protobuf/descriptor.proto; sourceTree = "<group>"; };
8B42494C1A92A16600BC1EC6 /* duration.proto */ = {isa = PBXFileReference; lastKnownFileType = text; name = duration.proto; path = ../src/google/protobuf/duration.proto; sourceTree = "<group>"; };
8B42494D1A92A16600BC1EC6 /* timestamp.proto */ = {isa = PBXFileReference; lastKnownFileType = text; name = timestamp.proto; path = ../src/google/protobuf/timestamp.proto; sourceTree = "<group>"; };
8B54585814DCC34E003D7338 /* Descriptor.pbobjc.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = Descriptor.pbobjc.h; path = google/protobuf/Descriptor.pbobjc.h; sourceTree = SOURCE_ROOT; };
8B79657814992E3E002FFBFC /* GPBRootObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GPBRootObject.h; sourceTree = "<group>"; };
8B79657914992E3E002FFBFC /* GPBRootObject.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GPBRootObject.m; sourceTree = "<group>"; };
8B7E6A7414893DBA00F8884A /* unittest_custom_options.proto */ = {isa = PBXFileReference; lastKnownFileType = text; name = unittest_custom_options.proto; path = ../../src/google/protobuf/unittest_custom_options.proto; sourceTree = "<group>"; };
8B7E6A7514893DBA00F8884A /* unittest_embed_optimize_for.proto */ = {isa = PBXFileReference; lastKnownFileType = text; name = unittest_embed_optimize_for.proto; path = ../../src/google/protobuf/unittest_embed_optimize_for.proto; sourceTree = "<group>"; };
8B7E6A7614893DBA00F8884A /* unittest_empty.proto */ = {isa = PBXFileReference; lastKnownFileType = text; name = unittest_empty.proto; path = ../../src/google/protobuf/unittest_empty.proto; sourceTree = "<group>"; };
8B7E6A7814893DBB00F8884A /* unittest_import.proto */ = {isa = PBXFileReference; lastKnownFileType = text; name = unittest_import.proto; path = ../../src/google/protobuf/unittest_import.proto; sourceTree = "<group>"; };
8B7E6A7B14893DBC00F8884A /* unittest_mset.proto */ = {isa = PBXFileReference; lastKnownFileType = text; name = unittest_mset.proto; path = ../../src/google/protobuf/unittest_mset.proto; sourceTree = "<group>"; };
8B7E6A7C14893DBC00F8884A /* unittest_no_generic_services.proto */ = {isa = PBXFileReference; lastKnownFileType = text; name = unittest_no_generic_services.proto; path = ../../src/google/protobuf/unittest_no_generic_services.proto; sourceTree = "<group>"; };
8B7E6A7D14893DBC00F8884A /* unittest_optimize_for.proto */ = {isa = PBXFileReference; lastKnownFileType = text; name = unittest_optimize_for.proto; path = ../../src/google/protobuf/unittest_optimize_for.proto; sourceTree = "<group>"; };
8B7E6A7E14893DBC00F8884A /* unittest.proto */ = {isa = PBXFileReference; lastKnownFileType = text; name = unittest.proto; path = ../../src/google/protobuf/unittest.proto; sourceTree = "<group>"; };
8B8B615C17DF7056002EE618 /* GPBARCUnittestProtos.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GPBARCUnittestProtos.m; sourceTree = "<group>"; };
8B96157214C8B06000A2AC0B /* GPBDescriptor.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GPBDescriptor.h; sourceTree = "<group>"; };
8B96157314C8C38C00A2AC0B /* GPBDescriptor.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GPBDescriptor.m; sourceTree = "<group>"; };
8BA9364418DA5F4B0056FA2A /* GPBStringTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GPBStringTests.m; sourceTree = "<group>"; };
8BBD9DB016DD1DC8008E1EC1 /* unittest_lite.proto */ = {isa = PBXFileReference; lastKnownFileType = text; name = unittest_lite.proto; path = ../../src/google/protobuf/unittest_lite.proto; sourceTree = "<group>"; };
8BBEA4A6147C727100C4ADB7 /* UnitTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = UnitTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
8BCC29BE16FD09A000F29F4A /* GPBFilteredMessageTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GPBFilteredMessageTests.m; sourceTree = "<group>"; };
8BCF338814ED799900BC5317 /* GPBProtocolBuffers.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = GPBProtocolBuffers.m; sourceTree = "<group>"; };
8BD3981D14BE54220081D629 /* unittest_enormous_descriptor.proto */ = {isa = PBXFileReference; lastKnownFileType = text; name = unittest_enormous_descriptor.proto; path = ../../src/google/protobuf/unittest_enormous_descriptor.proto; sourceTree = "<group>"; };
8BD3981E14BE59D70081D629 /* GPBUnittestProtos.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GPBUnittestProtos.m; sourceTree = "<group>"; };
8BD3982214BE5B0C0081D629 /* Descriptor.pbobjc.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = Descriptor.pbobjc.m; path = google/protobuf/Descriptor.pbobjc.m; sourceTree = SOURCE_ROOT; };
8BEB5AE01498033E0078BF9D /* GPBTypes.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GPBTypes.h; sourceTree = "<group>"; };
F401DC2A1A8D444600FCC765 /* GPBArray.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GPBArray.h; sourceTree = "<group>"; };
F401DC2B1A8D444600FCC765 /* GPBArray.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GPBArray.m; sourceTree = "<group>"; };
F401DC321A8E5C0200FCC765 /* GPBArrayTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GPBArrayTests.m; sourceTree = "<group>"; };
F41C175C1833D3310064ED4D /* GPBPerfTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GPBPerfTests.m; sourceTree = "<group>"; };
F4353D1C1AB8822D005A6198 /* GPBDescriptorTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GPBDescriptorTests.m; sourceTree = "<group>"; };
F4353D201ABB1537005A6198 /* GPBDictionary.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GPBDictionary.h; sourceTree = "<group>"; };
F4353D211ABB1537005A6198 /* GPBDictionary.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GPBDictionary.m; sourceTree = "<group>"; };
F4353D2C1AC06F10005A6198 /* GPBDictionaryTests.pddm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = GPBDictionaryTests.pddm; sourceTree = "<group>"; };
F4353D2D1AC06F10005A6198 /* GPBDictionaryTests+Bool.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "GPBDictionaryTests+Bool.m"; sourceTree = "<group>"; };
F4353D2E1AC06F10005A6198 /* GPBDictionaryTests+Int32.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "GPBDictionaryTests+Int32.m"; sourceTree = "<group>"; };
F4353D2F1AC06F10005A6198 /* GPBDictionaryTests+Int64.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "GPBDictionaryTests+Int64.m"; sourceTree = "<group>"; };
F4353D301AC06F10005A6198 /* GPBDictionaryTests+String.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "GPBDictionaryTests+String.m"; sourceTree = "<group>"; };
F4353D311AC06F10005A6198 /* GPBDictionaryTests+UInt32.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "GPBDictionaryTests+UInt32.m"; sourceTree = "<group>"; };
F4353D321AC06F10005A6198 /* GPBDictionaryTests+UInt64.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "GPBDictionaryTests+UInt64.m"; sourceTree = "<group>"; };
F43725911AC9832D004DCAFB /* GPBDictionary_PackagePrivate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GPBDictionary_PackagePrivate.h; sourceTree = "<group>"; };
F43C88CF191D77FC009E917D /* text_format_unittest_data.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = text_format_unittest_data.txt; sourceTree = "<group>"; };
F4411BE71AF12FD700324B4A /* GPBArray_PackagePrivate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GPBArray_PackagePrivate.h; sourceTree = "<group>"; };
F4487C511A9F8E0200531423 /* libTestSingleSourceBuild.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libTestSingleSourceBuild.a; sourceTree = BUILT_PRODUCTS_DIR; };
F4487C741AADF7F500531423 /* GPBMessageTests+Runtime.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "GPBMessageTests+Runtime.m"; sourceTree = "<group>"; };
F4487C781AADFB3100531423 /* unittest_runtime_proto2.proto */ = {isa = PBXFileReference; lastKnownFileType = text; path = unittest_runtime_proto2.proto; sourceTree = "<group>"; };
F4487C791AADFB3200531423 /* unittest_runtime_proto3.proto */ = {isa = PBXFileReference; lastKnownFileType = text; path = unittest_runtime_proto3.proto; sourceTree = "<group>"; };
F4487C7C1AAE06AC00531423 /* GPBUtilities_PackagePrivate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GPBUtilities_PackagePrivate.h; sourceTree = "<group>"; };
F4487C7E1AAF62CD00531423 /* GPBMessageTests+Serialization.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "GPBMessageTests+Serialization.m"; sourceTree = "<group>"; };
F4487C821AAF6AB300531423 /* GPBMessageTests+Merge.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "GPBMessageTests+Merge.m"; sourceTree = "<group>"; };
F44B25D81A729803005CCF68 /* Filter2.txt */ = {isa = PBXFileReference; lastKnownFileType = text; path = Filter2.txt; sourceTree = "<group>"; };
F451D3F51A8AAE8700B8A22C /* GPBProtocolBuffers_RuntimeSupport.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GPBProtocolBuffers_RuntimeSupport.h; sourceTree = "<group>"; };
F45C69CB16DFD08D0081955B /* GPBExtensionField.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GPBExtensionField.m; sourceTree = "<group>"; };
F45E57C61AE6DC6A000B7D99 /* text_format_map_unittest_data.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = text_format_map_unittest_data.txt; sourceTree = "<group>"; };
F4AC9E1D1A8BEB3500BD6E83 /* unittest_cycle.proto */ = {isa = PBXFileReference; lastKnownFileType = text; path = unittest_cycle.proto; sourceTree = "<group>"; };
F4B6B8AF1A9CC98000892426 /* GPBField_PackagePrivate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GPBField_PackagePrivate.h; sourceTree = "<group>"; };
F4B6B8B21A9CCBDA00892426 /* GPBUnknownFieldSet_PackagePrivate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GPBUnknownFieldSet_PackagePrivate.h; sourceTree = "<group>"; };
F4B6B8B61A9CD1DE00892426 /* GPBExtensionField_PackagePrivate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GPBExtensionField_PackagePrivate.h; sourceTree = "<group>"; };
F4B6B8B71A9CD1DE00892426 /* GPBExtensionRegistry_PackagePrivate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GPBExtensionRegistry_PackagePrivate.h; sourceTree = "<group>"; };
F4B6B8B81A9CD1DE00892426 /* GPBRootObject_PackagePrivate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GPBRootObject_PackagePrivate.h; sourceTree = "<group>"; };
F4B6B8B91A9D338B00892426 /* unittest_name_mangling.proto */ = {isa = PBXFileReference; lastKnownFileType = text; path = unittest_name_mangling.proto; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
7461B52C0F94FAF800A0C422 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
7461B5360F94FB4600A0C422 /* Foundation.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
8BBEA4A3147C727100C4ADB7 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
8BBEA4BB147C729200C4ADB7 /* libProtocolBuffers.a in Frameworks */,
8BF8193514A0DDA600A2C982 /* Foundation.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
F4487C4C1A9F8E0200531423 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
F4487C4D1A9F8E0200531423 /* Foundation.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
080E96DDFE201D6D7F000001 /* Core Source */ = {
isa = PBXGroup;
children = (
7461B4CD0F94F99000A0C422 /* GPBProtocolBuffers.h */,
F451D3F51A8AAE8700B8A22C /* GPBProtocolBuffers_RuntimeSupport.h */,
8BCF338814ED799900BC5317 /* GPBProtocolBuffers.m */,
7461B3C50F94F84100A0C422 /* Extensions */,
7461B4850F94F96600A0C422 /* Fields */,
7461B4860F94F96B00A0C422 /* IO */,
7461B5150F94FA7300A0C422 /* Messages */,
8BCF334414ED727300BC5317 /* Support */,
29B97315FDCFA39411CA2CEA /* Generated */,
);
name = "Core Source";
sourceTree = "<group>";
};
19C28FACFE9D520D11CA2CBB /* Products */ = {
isa = PBXGroup;
children = (
7461B52E0F94FAF800A0C422 /* libProtocolBuffers.a */,
8BBEA4A6147C727100C4ADB7 /* UnitTests.xctest */,
F4487C511A9F8E0200531423 /* libTestSingleSourceBuild.a */,
);
name = Products;
sourceTree = "<group>";
};
29B97314FDCFA39411CA2CEA /* CustomTemplate */ = {
isa = PBXGroup;
children = (
080E96DDFE201D6D7F000001 /* Core Source */,
7461B6940F94FDDD00A0C422 /* Tests */,
29B97323FDCFA39411CA2CEA /* Frameworks */,
19C28FACFE9D520D11CA2CBB /* Products */,
);
name = CustomTemplate;
sourceTree = "<group>";
};
29B97315FDCFA39411CA2CEA /* Generated */ = {
isa = PBXGroup;
children = (
8B42494B1A92A16600BC1EC6 /* descriptor.proto */,
8BD3982214BE5B0C0081D629 /* Descriptor.pbobjc.m */,
8B54585814DCC34E003D7338 /* Descriptor.pbobjc.h */,
8B42494C1A92A16600BC1EC6 /* duration.proto */,
8B4248D31A92826400BC1EC6 /* Duration.pbobjc.h */,
8B4248D41A92826400BC1EC6 /* Duration.pbobjc.m */,
8B42494D1A92A16600BC1EC6 /* timestamp.proto */,
8B4248D51A92826400BC1EC6 /* Timestamp.pbobjc.h */,
8B4248D61A92826400BC1EC6 /* Timestamp.pbobjc.m */,
);
name = Generated;
sourceTree = "<group>";
};
29B97323FDCFA39411CA2CEA /* Frameworks */ = {
isa = PBXGroup;
children = (
1D30AB110D05D00D00671497 /* Foundation.framework */,
);
name = Frameworks;
sourceTree = "<group>";
};
7461B3C50F94F84100A0C422 /* Extensions */ = {
isa = PBXGroup;
children = (
F4B6B8B61A9CD1DE00892426 /* GPBExtensionField_PackagePrivate.h */,
748F0CAF0FD70602000858A9 /* GPBExtensionField.h */,
F45C69CB16DFD08D0081955B /* GPBExtensionField.m */,
F4B6B8B71A9CD1DE00892426 /* GPBExtensionRegistry_PackagePrivate.h */,
7461B4A80F94F99000A0C422 /* GPBExtensionRegistry.h */,
7461B4A90F94F99000A0C422 /* GPBExtensionRegistry.m */,
F4B6B8B81A9CD1DE00892426 /* GPBRootObject_PackagePrivate.h */,
8B79657814992E3E002FFBFC /* GPBRootObject.h */,
8B79657914992E3E002FFBFC /* GPBRootObject.m */,
);
name = Extensions;
sourceTree = "<group>";
};
7461B4850F94F96600A0C422 /* Fields */ = {
isa = PBXGroup;
children = (
F4B6B8AF1A9CC98000892426 /* GPBField_PackagePrivate.h */,
7461B4AE0F94F99000A0C422 /* GPBField.h */,
7461B4AF0F94F99000A0C422 /* GPBField.m */,
F4B6B8B21A9CCBDA00892426 /* GPBUnknownFieldSet_PackagePrivate.h */,
7461B4E10F94F99000A0C422 /* GPBUnknownFieldSet.h */,
7461B4E20F94F99000A0C422 /* GPBUnknownFieldSet.m */,
);
name = Fields;
sourceTree = "<group>";
};
7461B4860F94F96B00A0C422 /* IO */ = {
isa = PBXGroup;
children = (
7461B48E0F94F99000A0C422 /* GPBCodedInputStream.h */,
51457B5F18D0B7AF00CCC606 /* GPBCodedInputStream_PackagePrivate.h */,
7461B48F0F94F99000A0C422 /* GPBCodedInputStream.m */,
7461B4900F94F99000A0C422 /* GPBCodedOutputStream.h */,
7461B4910F94F99000A0C422 /* GPBCodedOutputStream.m */,
7461B4E70F94F99000A0C422 /* GPBWireFormat.h */,
7461B4E80F94F99000A0C422 /* GPBWireFormat.m */,
);
name = IO;
sourceTree = "<group>";
};
7461B5150F94FA7300A0C422 /* Messages */ = {
isa = PBXGroup;
children = (
515B840C18B7DEE30031753B /* GPBDescriptor_PackagePrivate.h */,
8B96157214C8B06000A2AC0B /* GPBDescriptor.h */,
8B96157314C8C38C00A2AC0B /* GPBDescriptor.m */,
7461B4BE0F94F99000A0C422 /* GPBMessage.h */,
5196A06918CE16B000B759E2 /* GPBMessage_PackagePrivate.h */,
7461B4BF0F94F99000A0C422 /* GPBMessage.m */,
);
name = Messages;
sourceTree = "<group>";
};
7461B6940F94FDDD00A0C422 /* Tests */ = {
isa = PBXGroup;
children = (
8B4248B81A8C254000BC1EC6 /* protobuf */,
8B20A9A816F1BBFA00BE3EAD /* Filter1.txt */,
F44B25D81A729803005CCF68 /* Filter2.txt */,
8B210CCD159383D60032D72D /* golden_message */,
8B210CCF159386920032D72D /* golden_packed_fields_message */,
8B8B615C17DF7056002EE618 /* GPBARCUnittestProtos.m */,
F401DC321A8E5C0200FCC765 /* GPBArrayTests.m */,
7461B69B0F94FDF800A0C422 /* GPBCodedInputStreamTests.m */,
7461B69D0F94FDF800A0C422 /* GPBCodedOuputStreamTests.m */,
5102DABB1891A052002037B6 /* GPBConcurrencyTests.m */,
F4353D1C1AB8822D005A6198 /* GPBDescriptorTests.m */,
F4353D2C1AC06F10005A6198 /* GPBDictionaryTests.pddm */,
F4353D2D1AC06F10005A6198 /* GPBDictionaryTests+Bool.m */,
F4353D2E1AC06F10005A6198 /* GPBDictionaryTests+Int32.m */,
F4353D2F1AC06F10005A6198 /* GPBDictionaryTests+Int64.m */,
F4353D301AC06F10005A6198 /* GPBDictionaryTests+String.m */,
F4353D311AC06F10005A6198 /* GPBDictionaryTests+UInt32.m */,
F4353D321AC06F10005A6198 /* GPBDictionaryTests+UInt64.m */,
8BCC29BE16FD09A000F29F4A /* GPBFilteredMessageTests.m */,
7461B6A30F94FDF800A0C422 /* GPBMessageTests.m */,
F4487C821AAF6AB300531423 /* GPBMessageTests+Merge.m */,
F4487C741AADF7F500531423 /* GPBMessageTests+Runtime.m */,
F4487C7E1AAF62CD00531423 /* GPBMessageTests+Serialization.m */,
F41C175C1833D3310064ED4D /* GPBPerfTests.m */,
8BA9364418DA5F4B0056FA2A /* GPBStringTests.m */,
8B4248BA1A8C256A00BC1EC6 /* GPBSwiftTests.swift */,
7461B6AB0F94FDF800A0C422 /* GPBTestUtilities.h */,
7461B6AC0F94FDF800A0C422 /* GPBTestUtilities.m */,
8BD3981E14BE59D70081D629 /* GPBUnittestProtos.m */,
7461B6B80F94FDF900A0C422 /* GPBUnknownFieldSetTest.m */,
7461B6BA0F94FDF900A0C422 /* GPBUtilitiesTests.m */,
8B4248DB1A92933A00BC1EC6 /* GPBWellKnownTypesTest.m */,
7461B6BC0F94FDF900A0C422 /* GPBWireFormatTests.m */,
F43C88CF191D77FC009E917D /* text_format_unittest_data.txt */,
F45E57C61AE6DC6A000B7D99 /* text_format_map_unittest_data.txt */,
8B7E6A7414893DBA00F8884A /* unittest_custom_options.proto */,
F4AC9E1D1A8BEB3500BD6E83 /* unittest_cycle.proto */,
8B7E6A7514893DBA00F8884A /* unittest_embed_optimize_for.proto */,
8B7E6A7614893DBA00F8884A /* unittest_empty.proto */,
8BD3981D14BE54220081D629 /* unittest_enormous_descriptor.proto */,
8B20A9A916F1BC0600BE3EAD /* unittest_filter.proto */,
8B7E6A7814893DBB00F8884A /* unittest_import.proto */,
8BBD9DB016DD1DC8008E1EC1 /* unittest_lite.proto */,
8B7E6A7B14893DBC00F8884A /* unittest_mset.proto */,
F4B6B8B91A9D338B00892426 /* unittest_name_mangling.proto */,
8B7E6A7C14893DBC00F8884A /* unittest_no_generic_services.proto */,
8B09AAF614B663A7007B4184 /* unittest_objc.proto */,
8B7E6A7D14893DBC00F8884A /* unittest_optimize_for.proto */,
F4487C781AADFB3100531423 /* unittest_runtime_proto2.proto */,
F4487C791AADFB3200531423 /* unittest_runtime_proto3.proto */,
8B7E6A7E14893DBC00F8884A /* unittest.proto */,
8B4248B91A8C256900BC1EC6 /* UnitTests-Bridging-Header.h */,
7401C1A90F950347006D8281 /* UnitTests-Info.plist */,
);
path = Tests;
sourceTree = "<group>";
};
8BCF334414ED727300BC5317 /* Support */ = {
isa = PBXGroup;
children = (
F4411BE71AF12FD700324B4A /* GPBArray_PackagePrivate.h */,
F401DC2A1A8D444600FCC765 /* GPBArray.h */,
F401DC2B1A8D444600FCC765 /* GPBArray.m */,
7461B48D0F94F99000A0C422 /* GPBBootstrap.h */,
F43725911AC9832D004DCAFB /* GPBDictionary_PackagePrivate.h */,
F4353D201ABB1537005A6198 /* GPBDictionary.h */,
F4353D211ABB1537005A6198 /* GPBDictionary.m */,
8BEB5AE01498033E0078BF9D /* GPBTypes.h */,
F4487C7C1AAE06AC00531423 /* GPBUtilities_PackagePrivate.h */,
7461B4E50F94F99000A0C422 /* GPBUtilities.h */,
7461B4E60F94F99000A0C422 /* GPBUtilities.m */,
8B4248CF1A927E1500BC1EC6 /* GPBWellKnownTypes.h */,
8B4248D01A927E1500BC1EC6 /* GPBWellKnownTypes.m */,
);
name = Support;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXHeadersBuildPhase section */
7461B52A0F94FAF800A0C422 /* Headers */ = {
isa = PBXHeadersBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
F4487C391A9F8E0200531423 /* Headers */ = {
isa = PBXHeadersBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXHeadersBuildPhase section */
/* Begin PBXNativeTarget section */
7461B52D0F94FAF800A0C422 /* ProtocolBuffers */ = {
isa = PBXNativeTarget;
buildConfigurationList = 7461B5330F94FAFD00A0C422 /* Build configuration list for PBXNativeTarget "ProtocolBuffers" */;
buildPhases = (
7461B52A0F94FAF800A0C422 /* Headers */,
7461B52B0F94FAF800A0C422 /* Sources */,
7461B52C0F94FAF800A0C422 /* Frameworks */,
);
buildRules = (
);
dependencies = (
);
name = ProtocolBuffers;
productName = "ProtocolBuffers-iPhoneDevice";
productReference = 7461B52E0F94FAF800A0C422 /* libProtocolBuffers.a */;
productType = "com.apple.product-type.library.static";
};
8BBEA4A5147C727100C4ADB7 /* UnitTests */ = {
isa = PBXNativeTarget;
buildConfigurationList = 8BBEA4BA147C728600C4ADB7 /* Build configuration list for PBXNativeTarget "UnitTests" */;
buildPhases = (
F4B62A781AF91F6000AFCEDC /* Script: Check Runtime Stamps */,
8BBEA4A1147C727100C4ADB7 /* Resources */,
8BBEA4A2147C727100C4ADB7 /* Sources */,
8BBEA4A3147C727100C4ADB7 /* Frameworks */,
);
buildRules = (
);
dependencies = (
8BBEA4BD147C729A00C4ADB7 /* PBXTargetDependency */,
8BD3982114BE59EB0081D629 /* PBXTargetDependency */,
);
name = UnitTests;
productName = UnitTests;
productReference = 8BBEA4A6147C727100C4ADB7 /* UnitTests.xctest */;
productType = "com.apple.product-type.bundle.unit-test";
};
F4487C381A9F8E0200531423 /* TestSingleSourceBuild */ = {
isa = PBXNativeTarget;
buildConfigurationList = F4487C4E1A9F8E0200531423 /* Build configuration list for PBXNativeTarget "TestSingleSourceBuild" */;
buildPhases = (
F4487C391A9F8E0200531423 /* Headers */,
F4487C3D1A9F8E0200531423 /* Sources */,
F4487C4C1A9F8E0200531423 /* Frameworks */,
);
buildRules = (
);
dependencies = (
);
name = TestSingleSourceBuild;
productName = "ProtocolBuffers-iPhoneDevice";
productReference = F4487C511A9F8E0200531423 /* libTestSingleSourceBuild.a */;
productType = "com.apple.product-type.library.static";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
29B97313FDCFA39411CA2CEA /* Project object */ = {
isa = PBXProject;
attributes = {
LastTestingUpgradeCheck = 0600;
LastUpgradeCheck = 0620;
TargetAttributes = {
8BBEA4A5147C727100C4ADB7 = {
TestTargetID = 8B9A5EA41831993600A9D33B;
};
};
};
buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "ProtocolBuffers_OSX" */;
compatibilityVersion = "Xcode 6.3";
developmentRegion = English;
hasScannedForEncodings = 1;
knownRegions = (
en,
);
mainGroup = 29B97314FDCFA39411CA2CEA /* CustomTemplate */;
projectDirPath = "";
projectRoot = "";
targets = (
7461B52D0F94FAF800A0C422 /* ProtocolBuffers */,
8BBEA4A5147C727100C4ADB7 /* UnitTests */,
8BD3981414BE4AE70081D629 /* Compile_Protos */,
F4487C381A9F8E0200531423 /* TestSingleSourceBuild */,
);
};
/* End PBXProject section */
/* Begin PBXResourcesBuildPhase section */
8BBEA4A1147C727100C4ADB7 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
8B210CCE159383D60032D72D /* golden_message in Resources */,
F43C88D0191D77FC009E917D /* text_format_unittest_data.txt in Resources */,
8B210CD0159386920032D72D /* golden_packed_fields_message in Resources */,
F45E57C71AE6DC6A000B7D99 /* text_format_map_unittest_data.txt in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXShellScriptBuildPhase section */
8BD3981814BE4AF30081D629 /* ShellScript */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
"$(SRCROOT)/../src/google/protobuf/unittest_custom_options.proto",
"$(SRCROOT)/../src/google/protobuf/unittest_embed_optimize_for.proto",
"$(SRCROOT)/../src/google/protobuf/unittest_empty.proto",
"$(SRCROOT)/../src/google/protobuf/unittest_enormous_descriptor.proto",
"$(SRCROOT)/../src/google/protobuf/unittest_import_lite.proto",
"$(SRCROOT)/../src/google/protobuf/unittest_import.proto",
"$(SRCROOT)/../src/google/protobuf/unittest_lite_imports_nonlite.proto",
"$(SRCROOT)/../src/google/protobuf/unittest_lite.proto",
"$(SRCROOT)/../src/google/protobuf/unittest_mset.proto",
"$(SRCROOT)/../src/google/protobuf/unittest_no_generic_services.proto",
"$(SRCROOT)/../src/google/protobuf/unittest.proto",
"$(SRCROOT)/Tests/unittest_objc.proto",
"$(SRCROOT)/../src/.libs/libprotoc.10.dylib",
"$(SRCROOT)/../src/google/protobuf/unittest_import_public_lite.proto",
"$(SRCROOT)/../src/google/protobuf/unittest_import_public.proto",
"$(SRCROOT)/Tests/unittest_filter.proto",
"$(SRCROOT)/../src/.libs/libprotobuf.10.dylib",
"$(SRCROOT)/../src/.libs/protoc",
"$(SRCROOT)/Tests/Filter1.txt",
"$(SRCROOT)/Tests/Filter2.txt",
"$(SRCROOT)/Tests/unittest_cycle.proto",
"$(SRCROOT)/Tests/unittest_name_mangling.proto",
"$(SRCROOT)/Tests/unittest_runtime_proto2.proto",
"$(SRCROOT)/Tests/unittest_runtime_proto3.proto",
"$(SRCROOT)/../src/google/protobuf/unittest_drop_unknown_fields.proto",
"$(SRCROOT)/../src/google/protobuf/unittest_preserve_unknown_enum.proto",
"$(SRCROOT)/../src/google/protobuf/map_lite_unittest.proto",
"$(SRCROOT)/../src/google/protobuf/map_proto2_unittest.proto",
"$(SRCROOT)/../src/google/protobuf/map_unittest.proto",
);
outputPaths = (
"$(PROJECT_DERIVED_FILE_DIR)/protos/google/protobuf/Unittest.pbobjc.h",
"$(PROJECT_DERIVED_FILE_DIR)/protos/google/protobuf/Unittest.pbobjc.m",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/bash;
shellScript = "set -eu\nmkdir -p \"${PROJECT_DERIVED_FILE_DIR}/protos\"\nexport PATH=\"${PATH}:.\"\ncd \"${SRCROOT}\"/../src\n\nPROTOC=./protoc\n$PROTOC --objc_out=\"${PROJECT_DERIVED_FILE_DIR}/protos/google/protobuf\" --proto_path=google/protobuf/ --proto_path=. google/protobuf/unittest_custom_options.proto\n$PROTOC --objc_out=\"${PROJECT_DERIVED_FILE_DIR}/protos/google/protobuf\" --proto_path=google/protobuf/ --proto_path=. google/protobuf/unittest_enormous_descriptor.proto\n$PROTOC --objc_out=\"${PROJECT_DERIVED_FILE_DIR}/protos/google/protobuf\" --proto_path=google/protobuf/ --proto_path=. google/protobuf/unittest_embed_optimize_for.proto\n$PROTOC --objc_out=\"${PROJECT_DERIVED_FILE_DIR}/protos/google/protobuf\" --proto_path=google/protobuf/ --proto_path=. google/protobuf/unittest_empty.proto\n$PROTOC --objc_out=\"${PROJECT_DERIVED_FILE_DIR}/protos/google/protobuf\" --proto_path=google/protobuf/ --proto_path=. google/protobuf/unittest_import.proto\n$PROTOC --objc_out=\"${PROJECT_DERIVED_FILE_DIR}/protos/google/protobuf\" --proto_path=google/protobuf/ --proto_path=. google/protobuf/unittest_import_lite.proto\n$PROTOC --objc_out=\"${PROJECT_DERIVED_FILE_DIR}/protos/google/protobuf\" --proto_path=google/protobuf/ --proto_path=. google/protobuf/unittest_lite.proto\n$PROTOC --objc_out=\"${PROJECT_DERIVED_FILE_DIR}/protos/google/protobuf\" --proto_path=google/protobuf/ --proto_path=. google/protobuf/unittest_mset.proto\n$PROTOC --objc_out=\"${PROJECT_DERIVED_FILE_DIR}/protos/google/protobuf\" --proto_path=google/protobuf/ --proto_path=. google/protobuf/unittest_no_generic_services.proto\n$PROTOC --objc_out=\"${PROJECT_DERIVED_FILE_DIR}/protos/google/protobuf\" --proto_path=google/protobuf/ --proto_path=. google/protobuf/unittest_optimize_for.proto\n$PROTOC --objc_out=\"${PROJECT_DERIVED_FILE_DIR}/protos/google/protobuf\" --proto_path=google/protobuf/ --proto_path=. google/protobuf/unittest.proto\n$PROTOC --objc_out=\"${PROJECT_DERIVED_FILE_DIR}/protos/google/protobuf\" --proto_path=google/protobuf/ --proto_path=. google/protobuf/unittest_import_public.proto\n$PROTOC --objc_out=\"${PROJECT_DERIVED_FILE_DIR}/protos/google/protobuf\" --proto_path=google/protobuf/ --proto_path=. google/protobuf/unittest_import_public_lite.proto\n$PROTOC --objc_out=\"${PROJECT_DERIVED_FILE_DIR}/protos/google/protobuf\" --proto_path=google/protobuf/ --proto_path=. google/protobuf/unittest_drop_unknown_fields.proto\n$PROTOC --objc_out=\"${PROJECT_DERIVED_FILE_DIR}/protos/google/protobuf\" --proto_path=google/protobuf/ --proto_path=. google/protobuf/unittest_preserve_unknown_enum.proto\n$PROTOC --objc_out=\"${PROJECT_DERIVED_FILE_DIR}/protos/google/protobuf\" --proto_path=google/protobuf/ --proto_path=. google/protobuf/map_lite_unittest.proto\n$PROTOC --objc_out=\"${PROJECT_DERIVED_FILE_DIR}/protos/google/protobuf\" --proto_path=google/protobuf/ --proto_path=. google/protobuf/map_proto2_unittest.proto\n$PROTOC --objc_out=\"${PROJECT_DERIVED_FILE_DIR}/protos/google/protobuf\" --proto_path=google/protobuf/ --proto_path=. google/protobuf/map_unittest.proto\n\n$PROTOC --objc_out=\"${PROJECT_DERIVED_FILE_DIR}/protos/google/protobuf\" --proto_path=google/protobuf/ --proto_path=. --proto_path=\"${SRCROOT}\"/Tests \"${SRCROOT}\"/Tests/unittest_objc.proto\n\n$PROTOC --objc_out=\"${PROJECT_DERIVED_FILE_DIR}/protos/google/protobuf\" --proto_path=\"${SRCROOT}\"/Tests \"${SRCROOT}\"/Tests/unittest_cycle.proto\n$PROTOC --objc_out=\"${PROJECT_DERIVED_FILE_DIR}/protos/google/protobuf\" --proto_path=\"${SRCROOT}\"/Tests \"${SRCROOT}\"/Tests/unittest_name_mangling.proto\n$PROTOC --objc_out=\"${PROJECT_DERIVED_FILE_DIR}/protos/google/protobuf\" --proto_path=\"${SRCROOT}\"/Tests \"${SRCROOT}\"/Tests/unittest_runtime_proto2.proto\n$PROTOC --objc_out=\"${PROJECT_DERIVED_FILE_DIR}/protos/google/protobuf\" --proto_path=\"${SRCROOT}\"/Tests \"${SRCROOT}\"/Tests/unittest_runtime_proto3.proto\n\nexport GPB_CLASSLIST_PATH=\"${PROJECT_DERIVED_FILE_DIR}/ClassList.txt\"\nexport GPB_OBJC_CLASS_WHITELIST_PATHS=\"${SRCROOT}/Tests/Filter1.txt;${SRCROOT}/Tests/Filter2.txt\"\n\nif [ -e ${GPB_CLASSLIST_PATH} ]; then\nrm ${GPB_CLASSLIST_PATH}\nfi\n\n$PROTOC --objc_out=\"${PROJECT_DERIVED_FILE_DIR}/protos/google/protobuf\" --proto_path=\"${SRCROOT}\"/Tests \"${SRCROOT}\"/Tests/unittest_filter.proto\n\n";
showEnvVarsInLog = 0;
};
F4B62A781AF91F6000AFCEDC /* Script: Check Runtime Stamps */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "Script: Check Runtime Stamps";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "set -eu\nexec \"${SOURCE_ROOT}/DevTools/check_version_stamps.sh\"\n";
showEnvVarsInLog = 0;
};
/* End PBXShellScriptBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
7461B52B0F94FAF800A0C422 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
2CFB390415C718CE00CBF84D /* Descriptor.pbobjc.m in Sources */,
7461B53C0F94FB4E00A0C422 /* GPBCodedInputStream.m in Sources */,
7461B53D0F94FB4E00A0C422 /* GPBCodedOutputStream.m in Sources */,
F401DC2D1A8D444600FCC765 /* GPBArray.m in Sources */,
7461B5490F94FB4E00A0C422 /* GPBExtensionRegistry.m in Sources */,
7461B54C0F94FB4E00A0C422 /* GPBField.m in Sources */,
7461B5530F94FB4E00A0C422 /* GPBMessage.m in Sources */,
7461B5610F94FB4E00A0C422 /* GPBUnknownFieldSet.m in Sources */,
7461B5630F94FB4E00A0C422 /* GPBUtilities.m in Sources */,
7461B5640F94FB4E00A0C422 /* GPBWireFormat.m in Sources */,
F4353D231ABB1537005A6198 /* GPBDictionary.m in Sources */,
8B79657B14992E3F002FFBFC /* GPBRootObject.m in Sources */,
8B96157414C8C38C00A2AC0B /* GPBDescriptor.m in Sources */,
F45C69CC16DFD08D0081955B /* GPBExtensionField.m in Sources */,
8B4248D21A927E1500BC1EC6 /* GPBWellKnownTypes.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
8BBEA4A2147C727100C4ADB7 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
8BBEA4A9147C727D00C4ADB7 /* GPBCodedInputStreamTests.m in Sources */,
F401DC331A8E5C0200FCC765 /* GPBArrayTests.m in Sources */,
F4353D361AC06F10005A6198 /* GPBDictionaryTests+Int64.m in Sources */,
F4353D391AC06F10005A6198 /* GPBDictionaryTests+UInt64.m in Sources */,
8BBEA4AA147C727D00C4ADB7 /* GPBCodedOuputStreamTests.m in Sources */,
8BBEA4AC147C727D00C4ADB7 /* GPBMessageTests.m in Sources */,
F4487C7F1AAF62CD00531423 /* GPBMessageTests+Serialization.m in Sources */,
8B4248DC1A92933A00BC1EC6 /* GPBWellKnownTypesTest.m in Sources */,
F4353D1D1AB8822D005A6198 /* GPBDescriptorTests.m in Sources */,
8B4248BB1A8C256A00BC1EC6 /* GPBSwiftTests.swift in Sources */,
5102DABC1891A073002037B6 /* GPBConcurrencyTests.m in Sources */,
F4487C751AADF7F500531423 /* GPBMessageTests+Runtime.m in Sources */,
F4353D351AC06F10005A6198 /* GPBDictionaryTests+Int32.m in Sources */,
8BBEA4B0147C727D00C4ADB7 /* GPBTestUtilities.m in Sources */,
F41C175D1833D3310064ED4D /* GPBPerfTests.m in Sources */,
F4353D341AC06F10005A6198 /* GPBDictionaryTests+Bool.m in Sources */,
F4487C831AAF6AB300531423 /* GPBMessageTests+Merge.m in Sources */,
8BA9364518DA5F4C0056FA2A /* GPBStringTests.m in Sources */,
8BBEA4B6147C727D00C4ADB7 /* GPBUnknownFieldSetTest.m in Sources */,
F4353D371AC06F10005A6198 /* GPBDictionaryTests+String.m in Sources */,
F4353D381AC06F10005A6198 /* GPBDictionaryTests+UInt32.m in Sources */,
8BBEA4B7147C727D00C4ADB7 /* GPBUtilitiesTests.m in Sources */,
8BBEA4B8147C727D00C4ADB7 /* GPBWireFormatTests.m in Sources */,
8B79657D14992E3F002FFBFC /* GPBRootObject.m in Sources */,
8BD3981F14BE59D70081D629 /* GPBUnittestProtos.m in Sources */,
8B96157514CA019D00A2AC0B /* Descriptor.pbobjc.m in Sources */,
8BCC29BF16FD09A000F29F4A /* GPBFilteredMessageTests.m in Sources */,
8B8B615D17DF7056002EE618 /* GPBARCUnittestProtos.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
F4487C3D1A9F8E0200531423 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
F4487C521A9F8E4D00531423 /* GPBProtocolBuffers.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin PBXTargetDependency section */
8BBEA4BD147C729A00C4ADB7 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = 7461B52D0F94FAF800A0C422 /* ProtocolBuffers */;
targetProxy = 8BBEA4BC147C729A00C4ADB7 /* PBXContainerItemProxy */;
};
8BD3982114BE59EB0081D629 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = 8BD3981414BE4AE70081D629 /* Compile_Protos */;
targetProxy = 8BD3982014BE59EB0081D629 /* PBXContainerItemProxy */;
};
/* End PBXTargetDependency section */
/* Begin XCBuildConfiguration section */
7461B52F0F94FAFA00A0C422 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
COMBINE_HIDPI_IMAGES = YES;
HEADER_SEARCH_PATHS = "$(SRCROOT)";
PRODUCT_NAME = ProtocolBuffers;
};
name = Debug;
};
7461B5300F94FAFA00A0C422 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
COMBINE_HIDPI_IMAGES = YES;
HEADER_SEARCH_PATHS = "$(SRCROOT)";
PRODUCT_NAME = ProtocolBuffers;
};
name = Release;
};
8BBEA4A7147C727100C4ADB7 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
CLANG_ENABLE_MODULES = YES;
COMBINE_HIDPI_IMAGES = YES;
HEADER_SEARCH_PATHS = (
"${PROJECT_DERIVED_FILE_DIR}/protos",
"$(SRCROOT)",
);
INFOPLIST_FILE = "Tests/UnitTests-Info.plist";
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks";
PRODUCT_NAME = UnitTests;
SWIFT_OBJC_BRIDGING_HEADER = "Tests/UnitTests-Bridging-Header.h";
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
};
name = Debug;
};
8BBEA4A8147C727100C4ADB7 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
CLANG_ENABLE_MODULES = YES;
COMBINE_HIDPI_IMAGES = YES;
HEADER_SEARCH_PATHS = (
"${PROJECT_DERIVED_FILE_DIR}/protos",
"$(SRCROOT)",
);
INFOPLIST_FILE = "Tests/UnitTests-Info.plist";
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks";
PRODUCT_NAME = UnitTests;
SWIFT_OBJC_BRIDGING_HEADER = "Tests/UnitTests-Bridging-Header.h";
};
name = Release;
};
8BD3981514BE4AE70081D629 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
PRODUCT_NAME = "$(TARGET_NAME)";
};
name = Debug;
};
8BD3981614BE4AE70081D629 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
PRODUCT_NAME = "$(TARGET_NAME)";
};
name = Release;
};
C01FCF4F08A954540054247B /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = YES;
CLANG_ANALYZER_SECURITY_FLOATLOOPCOUNTER = YES;
CLANG_ANALYZER_SECURITY_INSECUREAPI_RAND = YES;
CLANG_ANALYZER_SECURITY_INSECUREAPI_STRCPY = YES;
CLANG_STATIC_ANALYZER_MODE = deep;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_OBJC_IMPLICIT_ATOMIC_PROPERTIES = YES;
CLANG_WARN_OBJC_MISSING_PROPERTY_SYNTHESIS = YES;
CLANG_WARN_SUSPICIOUS_IMPLICIT_CONVERSION = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
GCC_C_LANGUAGE_STANDARD = c99;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = "DEBUG=1";
GCC_TREAT_IMPLICIT_FUNCTION_DECLARATIONS_AS_ERRORS = YES;
GCC_TREAT_INCOMPATIBLE_POINTER_TYPE_WARNINGS_AS_ERRORS = YES;
GCC_TREAT_WARNINGS_AS_ERRORS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_MISSING_FIELD_INITIALIZERS = YES;
GCC_WARN_ABOUT_MISSING_NEWLINE = YES;
GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_HIDDEN_VIRTUAL_FUNCTIONS = YES;
GCC_WARN_INITIALIZER_NOT_FULLY_BRACKETED = YES;
GCC_WARN_MISSING_PARENTHESES = YES;
GCC_WARN_NON_VIRTUAL_DESTRUCTOR = YES;
GCC_WARN_SHADOW = YES;
GCC_WARN_SIGN_COMPARE = YES;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNKNOWN_PRAGMAS = YES;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_LABEL = YES;
GCC_WARN_UNUSED_PARAMETER = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
GENERATE_PROFILING_CODE = NO;
MACOSX_DEPLOYMENT_TARGET = 10.9;
ONLY_ACTIVE_ARCH = YES;
RUN_CLANG_STATIC_ANALYZER = YES;
SDKROOT = macosx;
};
name = Debug;
};
C01FCF5008A954540054247B /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = YES;
CLANG_ANALYZER_SECURITY_FLOATLOOPCOUNTER = YES;
CLANG_ANALYZER_SECURITY_INSECUREAPI_RAND = YES;
CLANG_ANALYZER_SECURITY_INSECUREAPI_STRCPY = YES;
CLANG_STATIC_ANALYZER_MODE = deep;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_OBJC_IMPLICIT_ATOMIC_PROPERTIES = YES;
CLANG_WARN_OBJC_MISSING_PROPERTY_SYNTHESIS = YES;
CLANG_WARN_SUSPICIOUS_IMPLICIT_CONVERSION = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
GCC_C_LANGUAGE_STANDARD = c99;
GCC_TREAT_IMPLICIT_FUNCTION_DECLARATIONS_AS_ERRORS = YES;
GCC_TREAT_INCOMPATIBLE_POINTER_TYPE_WARNINGS_AS_ERRORS = YES;
GCC_TREAT_WARNINGS_AS_ERRORS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_MISSING_FIELD_INITIALIZERS = YES;
GCC_WARN_ABOUT_MISSING_NEWLINE = YES;
GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_HIDDEN_VIRTUAL_FUNCTIONS = YES;
GCC_WARN_INITIALIZER_NOT_FULLY_BRACKETED = YES;
GCC_WARN_MISSING_PARENTHESES = YES;
GCC_WARN_NON_VIRTUAL_DESTRUCTOR = YES;
GCC_WARN_SHADOW = YES;
GCC_WARN_SIGN_COMPARE = YES;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNKNOWN_PRAGMAS = YES;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_LABEL = YES;
GCC_WARN_UNUSED_PARAMETER = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
GENERATE_PROFILING_CODE = NO;
MACOSX_DEPLOYMENT_TARGET = 10.9;
RUN_CLANG_STATIC_ANALYZER = YES;
SDKROOT = macosx;
};
name = Release;
};
F4487C4F1A9F8E0200531423 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
COMBINE_HIDPI_IMAGES = YES;
HEADER_SEARCH_PATHS = "$(SRCROOT)";
PRODUCT_NAME = TestSingleSourceBuild;
};
name = Debug;
};
F4487C501A9F8E0200531423 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
COMBINE_HIDPI_IMAGES = YES;
HEADER_SEARCH_PATHS = "$(SRCROOT)";
PRODUCT_NAME = TestSingleSourceBuild;
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
7461B5330F94FAFD00A0C422 /* Build configuration list for PBXNativeTarget "ProtocolBuffers" */ = {
isa = XCConfigurationList;
buildConfigurations = (
7461B52F0F94FAFA00A0C422 /* Debug */,
7461B5300F94FAFA00A0C422 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
8BBEA4BA147C728600C4ADB7 /* Build configuration list for PBXNativeTarget "UnitTests" */ = {
isa = XCConfigurationList;
buildConfigurations = (
8BBEA4A7147C727100C4ADB7 /* Debug */,
8BBEA4A8147C727100C4ADB7 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
8BD3981714BE4AE70081D629 /* Build configuration list for PBXAggregateTarget "Compile_Protos" */ = {
isa = XCConfigurationList;
buildConfigurations = (
8BD3981514BE4AE70081D629 /* Debug */,
8BD3981614BE4AE70081D629 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
C01FCF4E08A954540054247B /* Build configuration list for PBXProject "ProtocolBuffers_OSX" */ = {
isa = XCConfigurationList;
buildConfigurations = (
C01FCF4F08A954540054247B /* Debug */,
C01FCF5008A954540054247B /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
F4487C4E1A9F8E0200531423 /* Build configuration list for PBXNativeTarget "TestSingleSourceBuild" */ = {
isa = XCConfigurationList;
buildConfigurations = (
F4487C4F1A9F8E0200531423 /* Debug */,
F4487C501A9F8E0200531423 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};
rootObject = 29B97313FDCFA39411CA2CEA /* Project object */;
}

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "self:ProtocolBuffers_OSX.xcodeproj">
</FileRef>
</Workspace>

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IDEWorkspaceSharedSettings_AutocreateContextsIfNeeded</key>
<false/>
</dict>
</plist>

@ -0,0 +1,125 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0620"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "7461B52D0F94FAF800A0C422"
BuildableName = "libProtocolBuffers.a"
BlueprintName = "ProtocolBuffers"
ReferencedContainer = "container:ProtocolBuffers_OSX.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES"
buildConfiguration = "Release">
<Testables>
<TestableReference
skipped = "NO">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "8BBEA4A5147C727100C4ADB7"
BuildableName = "UnitTests.xctest"
BlueprintName = "UnitTests"
ReferencedContainer = "container:ProtocolBuffers_OSX.xcodeproj">
</BuildableReference>
<SkippedTests>
<Test
Identifier = "ArrayTests">
</Test>
<Test
Identifier = "CodedInputStreamTests">
</Test>
<Test
Identifier = "CodedOutputStreamTests">
</Test>
<Test
Identifier = "ConcurrencyTests">
</Test>
<Test
Identifier = "FilteredMessageTests">
</Test>
<Test
Identifier = "GPBStringTests">
</Test>
<Test
Identifier = "GPBTestCase">
</Test>
<Test
Identifier = "GeneratedMessageTests">
</Test>
<Test
Identifier = "MessageTests">
</Test>
<Test
Identifier = "UnknownFieldSetTest">
</Test>
<Test
Identifier = "UtilitiesTests">
</Test>
<Test
Identifier = "WireFormatTests">
</Test>
</SkippedTests>
</TestableReference>
</Testables>
</TestAction>
<LaunchAction
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
buildConfiguration = "Release"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
allowLocationSimulation = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "7461B52D0F94FAF800A0C422"
BuildableName = "libProtocolBuffers.a"
BlueprintName = "ProtocolBuffers"
ReferencedContainer = "container:ProtocolBuffers_OSX.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
buildConfiguration = "Release"
debugDocumentVersioning = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "7461B52D0F94FAF800A0C422"
BuildableName = "libProtocolBuffers.a"
BlueprintName = "ProtocolBuffers"
ReferencedContainer = "container:ProtocolBuffers_OSX.xcodeproj">
</BuildableReference>
</MacroExpansion>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Release">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>

@ -0,0 +1,115 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0620"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "NO">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "7461B52D0F94FAF800A0C422"
BuildableName = "libProtocolBuffers.a"
BlueprintName = "ProtocolBuffers"
ReferencedContainer = "container:ProtocolBuffers_OSX.xcodeproj">
</BuildableReference>
</BuildActionEntry>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "NO"
buildForArchiving = "NO"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "F4487C381A9F8E0200531423"
BuildableName = "libTestSingleSourceBuild.a"
BlueprintName = "TestSingleSourceBuild"
ReferencedContainer = "container:ProtocolBuffers_OSX.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES"
buildConfiguration = "Debug">
<Testables>
<TestableReference
skipped = "NO">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "8BBEA4A5147C727100C4ADB7"
BuildableName = "UnitTests.xctest"
BlueprintName = "UnitTests"
ReferencedContainer = "container:ProtocolBuffers_OSX.xcodeproj">
</BuildableReference>
<SkippedTests>
<Test
Identifier = "PerfTests">
</Test>
</SkippedTests>
</TestableReference>
</Testables>
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "7461B52D0F94FAF800A0C422"
BuildableName = "libProtocolBuffers.a"
BlueprintName = "ProtocolBuffers"
ReferencedContainer = "container:ProtocolBuffers_OSX.xcodeproj">
</BuildableReference>
</MacroExpansion>
</TestAction>
<LaunchAction
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
buildConfiguration = "Debug"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
allowLocationSimulation = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "7461B52D0F94FAF800A0C422"
BuildableName = "libProtocolBuffers.a"
BlueprintName = "ProtocolBuffers"
ReferencedContainer = "container:ProtocolBuffers_OSX.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
buildConfiguration = "Release"
debugDocumentVersioning = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "7461B52D0F94FAF800A0C422"
BuildableName = "libProtocolBuffers.a"
BlueprintName = "ProtocolBuffers"
ReferencedContainer = "container:ProtocolBuffers_OSX.xcodeproj">
</BuildableReference>
</MacroExpansion>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>

File diff suppressed because it is too large Load Diff

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "self:ProtocolBuffers_iOS.xcodeproj">
</FileRef>
</Workspace>

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IDEWorkspaceSharedSettings_AutocreateContextsIfNeeded</key>
<false/>
</dict>
</plist>

@ -0,0 +1,62 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>classNames</key>
<dict>
<key>PerfTests</key>
<dict>
<key>testExtensionsPerformance</key>
<dict>
<key>com.apple.XCTPerformanceMetric_WallClockTime</key>
<dict>
<key>baselineAverage</key>
<real>0.9</real>
<key>baselineIntegrationDisplayName</key>
<string>Feb 5, 2015, 9:42:41 AM</string>
</dict>
</dict>
<key>testHas</key>
<dict>
<key>com.apple.XCTPerformanceMetric_WallClockTime</key>
<dict>
<key>baselineAverage</key>
<real>0.09</real>
<key>baselineIntegrationDisplayName</key>
<string>Feb 5, 2015, 9:42:35 AM</string>
</dict>
</dict>
<key>testMessagePerformance</key>
<dict>
<key>com.apple.XCTPerformanceMetric_WallClockTime</key>
<dict>
<key>baselineAverage</key>
<real>0.57</real>
<key>baselineIntegrationDisplayName</key>
<string>Feb 5, 2015, 9:42:47 AM</string>
</dict>
</dict>
<key>testPackedExtensionsPerformance</key>
<dict>
<key>com.apple.XCTPerformanceMetric_WallClockTime</key>
<dict>
<key>baselineAverage</key>
<real>0.75</real>
<key>baselineIntegrationDisplayName</key>
<string>Feb 5, 2015, 9:42:51 AM</string>
</dict>
</dict>
<key>testPackedTypesPerformance</key>
<dict>
<key>com.apple.XCTPerformanceMetric_WallClockTime</key>
<dict>
<key>baselineAverage</key>
<real>0.26</real>
<key>baselineIntegrationDisplayName</key>
<string>Feb 5, 2015, 9:42:55 AM</string>
</dict>
</dict>
</dict>
</dict>
</dict>
</plist>

@ -0,0 +1,21 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>runDestinationsByUUID</key>
<dict>
<key>FFE465CA-0E74-40E8-9F09-500B66B7DCB2</key>
<dict>
<key>targetArchitecture</key>
<string>arm64</string>
<key>targetDevice</key>
<dict>
<key>modelCode</key>
<string>iPhone7,1</string>
<key>platformIdentifier</key>
<string>com.apple.platform.iphoneos</string>
</dict>
</dict>
</dict>
</dict>
</plist>

@ -0,0 +1,134 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0610"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "7461B52D0F94FAF800A0C422"
BuildableName = "libProtocolBuffers.a"
BlueprintName = "ProtocolBuffers"
ReferencedContainer = "container:ProtocolBuffers_iOS.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES"
buildConfiguration = "Release">
<Testables>
<TestableReference
skipped = "NO">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "8BBEA4A5147C727100C4ADB7"
BuildableName = "UnitTests.xctest"
BlueprintName = "UnitTests"
ReferencedContainer = "container:ProtocolBuffers_iOS.xcodeproj">
</BuildableReference>
<SkippedTests>
<Test
Identifier = "ArrayTests">
</Test>
<Test
Identifier = "CodedInputStreamTests">
</Test>
<Test
Identifier = "CodedOutputStreamTests">
</Test>
<Test
Identifier = "ConcurrencyTests">
</Test>
<Test
Identifier = "FilteredMessageTests">
</Test>
<Test
Identifier = "GPBStringTests">
</Test>
<Test
Identifier = "GPBTestCase">
</Test>
<Test
Identifier = "GeneratedMessageTests">
</Test>
<Test
Identifier = "MessageTests">
</Test>
<Test
Identifier = "UnknownFieldSetTest">
</Test>
<Test
Identifier = "UtilitiesTests">
</Test>
<Test
Identifier = "WireFormatTests">
</Test>
</SkippedTests>
</TestableReference>
</Testables>
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "8B9A5EA41831993600A9D33B"
BuildableName = "iOSTestHarness.app"
BlueprintName = "iOSTestHarness"
ReferencedContainer = "container:ProtocolBuffers_iOS.xcodeproj">
</BuildableReference>
</MacroExpansion>
</TestAction>
<LaunchAction
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
buildConfiguration = "Release"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
allowLocationSimulation = "YES">
<BuildableProductRunnable>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "8B9A5EA41831993600A9D33B"
BuildableName = "iOSTestHarness.app"
BlueprintName = "iOSTestHarness"
ReferencedContainer = "container:ProtocolBuffers_iOS.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
buildConfiguration = "Release"
debugDocumentVersioning = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "7461B52D0F94FAF800A0C422"
BuildableName = "libProtocolBuffers.a"
BlueprintName = "ProtocolBuffers"
ReferencedContainer = "container:ProtocolBuffers_iOS.xcodeproj">
</BuildableReference>
</MacroExpansion>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Release">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>

@ -0,0 +1,116 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0610"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "NO">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "7461B52D0F94FAF800A0C422"
BuildableName = "libProtocolBuffers.a"
BlueprintName = "ProtocolBuffers"
ReferencedContainer = "container:ProtocolBuffers_iOS.xcodeproj">
</BuildableReference>
</BuildActionEntry>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "NO"
buildForArchiving = "NO"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "F4487C551A9F8F8100531423"
BuildableName = "libTestSingleSourceBuild.a"
BlueprintName = "TestSingleSourceBuild"
ReferencedContainer = "container:ProtocolBuffers_iOS.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES"
buildConfiguration = "Debug">
<Testables>
<TestableReference
skipped = "NO">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "8BBEA4A5147C727100C4ADB7"
BuildableName = "UnitTests.xctest"
BlueprintName = "UnitTests"
ReferencedContainer = "container:ProtocolBuffers_iOS.xcodeproj">
</BuildableReference>
<SkippedTests>
<Test
Identifier = "PerfTests">
</Test>
</SkippedTests>
</TestableReference>
</Testables>
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "8B9A5EA41831993600A9D33B"
BuildableName = "iOSTestHarness.app"
BlueprintName = "iOSTestHarness"
ReferencedContainer = "container:ProtocolBuffers_iOS.xcodeproj">
</BuildableReference>
</MacroExpansion>
</TestAction>
<LaunchAction
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
buildConfiguration = "Debug"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
allowLocationSimulation = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "8B9A5EA41831993600A9D33B"
BuildableName = "iOSTestHarness.app"
BlueprintName = "iOSTestHarness"
ReferencedContainer = "container:ProtocolBuffers_iOS.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
buildConfiguration = "Release"
debugDocumentVersioning = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "7461B52D0F94FAF800A0C422"
BuildableName = "libProtocolBuffers.a"
BlueprintName = "ProtocolBuffers"
ReferencedContainer = "container:ProtocolBuffers_iOS.xcodeproj">
</BuildableReference>
</MacroExpansion>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>

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

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

@ -0,0 +1,57 @@
#if !defined(__has_feature) || !__has_feature(objc_arc)
#error "This file requires ARC support."
#endif
// 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.
// Makes sure all the generated headers compile with ARC on.
#import "google/protobuf/Unittest.pbobjc.h"
#import "google/protobuf/UnittestCustomOptions.pbobjc.h"
#import "google/protobuf/UnittestCycle.pbobjc.h"
#import "google/protobuf/UnittestDropUnknownFields.pbobjc.h"
#import "google/protobuf/UnittestEmbedOptimizeFor.pbobjc.h"
#import "google/protobuf/UnittestEmpty.pbobjc.h"
#import "google/protobuf/UnittestEnormousDescriptor.pbobjc.h"
#import "google/protobuf/UnittestFilter.pbobjc.h"
#import "google/protobuf/UnittestImport.pbobjc.h"
#import "google/protobuf/UnittestImportLite.pbobjc.h"
#import "google/protobuf/UnittestImportPublic.pbobjc.h"
#import "google/protobuf/UnittestImportPublicLite.pbobjc.h"
#import "google/protobuf/UnittestLite.pbobjc.h"
#import "google/protobuf/UnittestMset.pbobjc.h"
#import "google/protobuf/UnittestNameMangling.pbobjc.h"
#import "google/protobuf/UnittestNoGenericServices.pbobjc.h"
#import "google/protobuf/UnittestObjc.pbobjc.h"
#import "google/protobuf/UnittestOptimizeFor.pbobjc.h"
#import "google/protobuf/UnittestPreserveUnknownEnum.pbobjc.h"
#import "google/protobuf/UnittestRuntimeProto2.pbobjc.h"
#import "google/protobuf/UnittestRuntimeProto3.pbobjc.h"

File diff suppressed because it is too large Load Diff

@ -0,0 +1,290 @@
// 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 "GPBTestUtilities.h"
#import "GPBCodedInputStream.h"
#import "GPBCodedOutputStream.h"
#import "GPBUnknownFieldSet_PackagePrivate.h"
#import "GPBUtilities_PackagePrivate.h"
#import "google/protobuf/Unittest.pbobjc.h"
@interface CodedInputStreamTests : GPBTestCase
@end
@implementation CodedInputStreamTests
- (NSData*)bytes_with_sentinel:(int32_t)unused, ... {
va_list list;
va_start(list, unused);
NSMutableData* values = [NSMutableData dataWithCapacity:0];
int32_t i;
while ((i = va_arg(list, int32_t)) != 256) {
NSAssert(i >= 0 && i < 256, @"");
uint8_t u = (uint8_t)i;
[values appendBytes:&u length:1];
}
va_end(list);
return values;
}
#define bytes(...) [self bytes_with_sentinel:0, __VA_ARGS__, 256]
- (void)testDecodeZigZag {
XCTAssertEqual(0, GPBDecodeZigZag32(0));
XCTAssertEqual(-1, GPBDecodeZigZag32(1));
XCTAssertEqual(1, GPBDecodeZigZag32(2));
XCTAssertEqual(-2, GPBDecodeZigZag32(3));
XCTAssertEqual((int32_t)0x3FFFFFFF, GPBDecodeZigZag32(0x7FFFFFFE));
XCTAssertEqual((int32_t)0xC0000000, GPBDecodeZigZag32(0x7FFFFFFF));
XCTAssertEqual((int32_t)0x7FFFFFFF, GPBDecodeZigZag32(0xFFFFFFFE));
XCTAssertEqual((int32_t)0x80000000, GPBDecodeZigZag32(0xFFFFFFFF));
XCTAssertEqual((int64_t)0, GPBDecodeZigZag64(0));
XCTAssertEqual((int64_t)-1, GPBDecodeZigZag64(1));
XCTAssertEqual((int64_t)1, GPBDecodeZigZag64(2));
XCTAssertEqual((int64_t)-2, GPBDecodeZigZag64(3));
XCTAssertEqual((int64_t)0x000000003FFFFFFFL,
GPBDecodeZigZag64(0x000000007FFFFFFEL));
XCTAssertEqual((int64_t)0xFFFFFFFFC0000000L,
GPBDecodeZigZag64(0x000000007FFFFFFFL));
XCTAssertEqual((int64_t)0x000000007FFFFFFFL,
GPBDecodeZigZag64(0x00000000FFFFFFFEL));
XCTAssertEqual((int64_t)0xFFFFFFFF80000000L,
GPBDecodeZigZag64(0x00000000FFFFFFFFL));
XCTAssertEqual((int64_t)0x7FFFFFFFFFFFFFFFL,
GPBDecodeZigZag64(0xFFFFFFFFFFFFFFFEL));
XCTAssertEqual((int64_t)0x8000000000000000L,
GPBDecodeZigZag64(0xFFFFFFFFFFFFFFFFL));
}
- (void)assertReadVarint:(NSData*)data value:(int64_t)value {
{
GPBCodedInputStream* input = [GPBCodedInputStream streamWithData:data];
XCTAssertEqual((int32_t)value, [input readInt32]);
}
{
GPBCodedInputStream* input = [GPBCodedInputStream streamWithData:data];
XCTAssertEqual(value, [input readInt64]);
}
}
- (void)assertReadLittleEndian32:(NSData*)data value:(int32_t)value {
GPBCodedInputStream* input = [GPBCodedInputStream streamWithData:data];
XCTAssertEqual(value, [input readSFixed32]);
}
- (void)assertReadLittleEndian64:(NSData*)data value:(int64_t)value {
GPBCodedInputStream* input = [GPBCodedInputStream streamWithData:data];
XCTAssertEqual(value, [input readSFixed64]);
}
- (void)assertReadVarintFailure:(NSData*)data {
{
GPBCodedInputStream* input = [GPBCodedInputStream streamWithData:data];
XCTAssertThrows([input readInt32]);
}
{
GPBCodedInputStream* input = [GPBCodedInputStream streamWithData:data];
XCTAssertThrows([input readInt64]);
}
}
- (void)testBytes {
NSData* data = bytes(0xa2, 0x74);
XCTAssertEqual(data.length, (NSUInteger)2);
XCTAssertEqual(((uint8_t*)data.bytes)[0], (uint8_t)0xa2);
XCTAssertEqual(((uint8_t*)data.bytes)[1], (uint8_t)0x74);
}
- (void)testReadVarint {
[self assertReadVarint:bytes(0x00) value:0];
[self assertReadVarint:bytes(0x01) value:1];
[self assertReadVarint:bytes(0x7f) value:127];
// 14882
[self assertReadVarint:bytes(0xa2, 0x74) value:(0x22 << 0) | (0x74 << 7)];
// 2961488830
[self assertReadVarint:bytes(0xbe, 0xf7, 0x92, 0x84, 0x0b)
value:(0x3e << 0) | (0x77 << 7) | (0x12 << 14) |
(0x04 << 21) | (0x0bLL << 28)];
// 64-bit
// 7256456126
[self assertReadVarint:bytes(0xbe, 0xf7, 0x92, 0x84, 0x1b)
value:(0x3e << 0) | (0x77 << 7) | (0x12 << 14) |
(0x04 << 21) | (0x1bLL << 28)];
// 41256202580718336
[self assertReadVarint:bytes(0x80, 0xe6, 0xeb, 0x9c, 0xc3, 0xc9, 0xa4, 0x49)
value:(0x00 << 0) | (0x66 << 7) | (0x6b << 14) |
(0x1c << 21) | (0x43LL << 28) | (0x49LL << 35) |
(0x24LL << 42) | (0x49LL << 49)];
// 11964378330978735131
[self
assertReadVarint:bytes(0x9b, 0xa8, 0xf9, 0xc2, 0xbb, 0xd6, 0x80, 0x85,
0xa6, 0x01)
value:(0x1b << 0) | (0x28 << 7) | (0x79 << 14) | (0x42 << 21) |
(0x3bLL << 28) | (0x56LL << 35) | (0x00LL << 42) |
(0x05LL << 49) | (0x26LL << 56) | (0x01LL << 63)];
// Failures
[self assertReadVarintFailure:bytes(0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
0x80, 0x80, 0x80, 0x00)];
[self assertReadVarintFailure:bytes(0x80)];
}
- (void)testReadLittleEndian {
[self assertReadLittleEndian32:bytes(0x78, 0x56, 0x34, 0x12)
value:0x12345678];
[self assertReadLittleEndian32:bytes(0xf0, 0xde, 0xbc, 0x9a)
value:0x9abcdef0];
[self assertReadLittleEndian64:bytes(0xf0, 0xde, 0xbc, 0x9a, 0x78, 0x56, 0x34,
0x12)
value:0x123456789abcdef0LL];
[self assertReadLittleEndian64:bytes(0x78, 0x56, 0x34, 0x12, 0xf0, 0xde, 0xbc,
0x9a)
value:0x9abcdef012345678LL];
}
- (void)testReadWholeMessage {
TestAllTypes* message = [self allSetRepeatedCount:kGPBDefaultRepeatCount];
NSData* rawBytes = message.data;
XCTAssertEqual(message.serializedSize, (size_t)rawBytes.length);
TestAllTypes* message2 =
[TestAllTypes parseFromData:rawBytes extensionRegistry:nil];
[self assertAllFieldsSet:message2 repeatedCount:kGPBDefaultRepeatCount];
}
- (void)testSkipWholeMessage {
TestAllTypes* message = [self allSetRepeatedCount:kGPBDefaultRepeatCount];
NSData* rawBytes = message.data;
// Create two parallel inputs. Parse one as unknown fields while using
// skipField() to skip each field on the other. Expect the same tags.
GPBCodedInputStream* input1 = [GPBCodedInputStream streamWithData:rawBytes];
GPBCodedInputStream* input2 = [GPBCodedInputStream streamWithData:rawBytes];
GPBUnknownFieldSet* unknownFields =
[[[GPBUnknownFieldSet alloc] init] autorelease];
while (YES) {
int32_t tag = [input1 readTag];
XCTAssertEqual(tag, [input2 readTag]);
if (tag == 0) {
break;
}
[unknownFields mergeFieldFrom:tag input:input1];
[input2 skipField:tag];
}
}
- (void)testReadHugeBlob {
// Allocate and initialize a 1MB blob.
NSMutableData* blob = [NSMutableData dataWithLength:1 << 20];
for (NSUInteger i = 0; i < blob.length; i++) {
((uint8_t*)blob.mutableBytes)[i] = (uint8_t)i;
}
// Make a message containing it.
TestAllTypes* message = [TestAllTypes message];
[self setAllFields:message repeatedCount:kGPBDefaultRepeatCount];
[message setOptionalBytes:blob];
// Serialize and parse it. Make sure to parse from an InputStream, not
// directly from a ByteString, so that CodedInputStream uses buffered
// reading.
GPBCodedInputStream* stream =
[GPBCodedInputStream streamWithData:message.data];
TestAllTypes* message2 =
[TestAllTypes parseFromCodedInputStream:stream extensionRegistry:nil];
XCTAssertEqualObjects(message.optionalBytes, message2.optionalBytes);
// Make sure all the other fields were parsed correctly.
TestAllTypes* message3 = [[message2 copy] autorelease];
TestAllTypes* types = [self allSetRepeatedCount:kGPBDefaultRepeatCount];
NSData* data = [types optionalBytes];
[message3 setOptionalBytes:data];
[self assertAllFieldsSet:message3 repeatedCount:kGPBDefaultRepeatCount];
}
- (void)testReadMaliciouslyLargeBlob {
NSOutputStream* rawOutput = [NSOutputStream outputStreamToMemory];
GPBCodedOutputStream* output =
[GPBCodedOutputStream streamWithOutputStream:rawOutput];
int32_t tag = GPBWireFormatMakeTag(1, GPBWireFormatLengthDelimited);
[output writeRawVarint32:tag];
[output writeRawVarint32:0x7FFFFFFF];
uint8_t bytes[32] = {0};
[output writeRawData:[NSData dataWithBytes:bytes length:32]];
[output flush];
NSData* data =
[rawOutput propertyForKey:NSStreamDataWrittenToMemoryStreamKey];
GPBCodedInputStream* input =
[GPBCodedInputStream streamWithData:[NSMutableData dataWithData:data]];
XCTAssertEqual(tag, [input readTag]);
XCTAssertThrows([input readData]);
}
// Verifies fix for b/10315336.
- (void)testReadMalformedString {
NSOutputStream* rawOutput = [NSOutputStream outputStreamToMemory];
GPBCodedOutputStream* output =
[GPBCodedOutputStream streamWithOutputStream:rawOutput];
int32_t tag = GPBWireFormatMakeTag(TestAllTypes_FieldNumber_DefaultString,
GPBWireFormatLengthDelimited);
[output writeRawVarint32:tag];
[output writeRawVarint32:5];
// Create an invalid utf-8 byte array.
uint8_t bytes[5] = {0xc2, 0xf2};
[output writeRawData:[NSData dataWithBytes:bytes length:sizeof(bytes)]];
[output flush];
NSData* data =
[rawOutput propertyForKey:NSStreamDataWrittenToMemoryStreamKey];
GPBCodedInputStream* input = [GPBCodedInputStream streamWithData:data];
TestAllTypes* message =
[TestAllTypes parseFromCodedInputStream:input extensionRegistry:nil];
// Make sure we can read string properties twice without crashing.
XCTAssertEqual([message.defaultString length], (NSUInteger)0);
XCTAssertEqualObjects(@"", message.defaultString);
}
@end

@ -0,0 +1,321 @@
// 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 "GPBTestUtilities.h"
#import "GPBCodedOutputStream.h"
#import "GPBCodedInputStream.h"
#import "GPBUtilities_PackagePrivate.h"
#import "google/protobuf/Unittest.pbobjc.h"
@interface CodedOutputStreamTests : GPBTestCase
@end
@implementation CodedOutputStreamTests
- (NSData*)bytes_with_sentinel:(int32_t)unused, ... {
va_list list;
va_start(list, unused);
NSMutableData* values = [NSMutableData dataWithCapacity:0];
int32_t i;
while ((i = va_arg(list, int32_t)) != 256) {
NSAssert(i >= 0 && i < 256, @"");
uint8_t u = (uint8_t)i;
[values appendBytes:&u length:1];
}
va_end(list);
return values;
}
#define bytes(...) [self bytes_with_sentinel:0, __VA_ARGS__, 256]
- (void)assertWriteLittleEndian32:(NSData*)data value:(int32_t)value {
NSOutputStream* rawOutput = [NSOutputStream outputStreamToMemory];
GPBCodedOutputStream* output =
[GPBCodedOutputStream streamWithOutputStream:rawOutput];
[output writeRawLittleEndian32:(int32_t)value];
[output flush];
NSData* actual =
[rawOutput propertyForKey:NSStreamDataWrittenToMemoryStreamKey];
XCTAssertEqualObjects(data, actual);
// Try different block sizes.
for (int blockSize = 1; blockSize <= 16; blockSize *= 2) {
rawOutput = [NSOutputStream outputStreamToMemory];
output = [GPBCodedOutputStream streamWithOutputStream:rawOutput
bufferSize:blockSize];
[output writeRawLittleEndian32:(int32_t)value];
[output flush];
actual = [rawOutput propertyForKey:NSStreamDataWrittenToMemoryStreamKey];
XCTAssertEqualObjects(data, actual);
}
}
- (void)assertWriteLittleEndian64:(NSData*)data value:(int64_t)value {
NSOutputStream* rawOutput = [NSOutputStream outputStreamToMemory];
GPBCodedOutputStream* output =
[GPBCodedOutputStream streamWithOutputStream:rawOutput];
[output writeRawLittleEndian64:value];
[output flush];
NSData* actual =
[rawOutput propertyForKey:NSStreamDataWrittenToMemoryStreamKey];
XCTAssertEqualObjects(data, actual);
// Try different block sizes.
for (int blockSize = 1; blockSize <= 16; blockSize *= 2) {
rawOutput = [NSOutputStream outputStreamToMemory];
output = [GPBCodedOutputStream streamWithOutputStream:rawOutput
bufferSize:blockSize];
[output writeRawLittleEndian64:value];
[output flush];
actual = [rawOutput propertyForKey:NSStreamDataWrittenToMemoryStreamKey];
XCTAssertEqualObjects(data, actual);
}
}
- (void)assertWriteVarint:(NSData*)data value:(int64_t)value {
// Only do 32-bit write if the value fits in 32 bits.
if (GPBLogicalRightShift64(value, 32) == 0) {
NSOutputStream* rawOutput = [NSOutputStream outputStreamToMemory];
GPBCodedOutputStream* output =
[GPBCodedOutputStream streamWithOutputStream:rawOutput];
[output writeRawVarint32:(int32_t)value];
[output flush];
NSData* actual =
[rawOutput propertyForKey:NSStreamDataWrittenToMemoryStreamKey];
XCTAssertEqualObjects(data, actual);
// Also try computing size.
XCTAssertEqual(GPBComputeRawVarint32Size((int32_t)value),
(size_t)data.length);
}
{
NSOutputStream* rawOutput = [NSOutputStream outputStreamToMemory];
GPBCodedOutputStream* output =
[GPBCodedOutputStream streamWithOutputStream:rawOutput];
[output writeRawVarint64:value];
[output flush];
NSData* actual =
[rawOutput propertyForKey:NSStreamDataWrittenToMemoryStreamKey];
XCTAssertEqualObjects(data, actual);
// Also try computing size.
XCTAssertEqual(GPBComputeRawVarint64Size(value), (size_t)data.length);
}
// Try different block sizes.
for (int blockSize = 1; blockSize <= 16; blockSize *= 2) {
// Only do 32-bit write if the value fits in 32 bits.
if (GPBLogicalRightShift64(value, 32) == 0) {
NSOutputStream* rawOutput = [NSOutputStream outputStreamToMemory];
GPBCodedOutputStream* output =
[GPBCodedOutputStream streamWithOutputStream:rawOutput
bufferSize:blockSize];
[output writeRawVarint32:(int32_t)value];
[output flush];
NSData* actual =
[rawOutput propertyForKey:NSStreamDataWrittenToMemoryStreamKey];
XCTAssertEqualObjects(data, actual);
}
{
NSOutputStream* rawOutput = [NSOutputStream outputStreamToMemory];
GPBCodedOutputStream* output =
[GPBCodedOutputStream streamWithOutputStream:rawOutput
bufferSize:blockSize];
[output writeRawVarint64:value];
[output flush];
NSData* actual =
[rawOutput propertyForKey:NSStreamDataWrittenToMemoryStreamKey];
XCTAssertEqualObjects(data, actual);
}
}
}
- (void)testWriteVarint1 {
[self assertWriteVarint:bytes(0x00) value:0];
}
- (void)testWriteVarint2 {
[self assertWriteVarint:bytes(0x01) value:1];
}
- (void)testWriteVarint3 {
[self assertWriteVarint:bytes(0x7f) value:127];
}
- (void)testWriteVarint4 {
// 14882
[self assertWriteVarint:bytes(0xa2, 0x74) value:(0x22 << 0) | (0x74 << 7)];
}
- (void)testWriteVarint5 {
// 2961488830
[self assertWriteVarint:bytes(0xbe, 0xf7, 0x92, 0x84, 0x0b)
value:(0x3e << 0) | (0x77 << 7) | (0x12 << 14) |
(0x04 << 21) | (0x0bLL << 28)];
}
- (void)testWriteVarint6 {
// 64-bit
// 7256456126
[self assertWriteVarint:bytes(0xbe, 0xf7, 0x92, 0x84, 0x1b)
value:(0x3e << 0) | (0x77 << 7) | (0x12 << 14) |
(0x04 << 21) | (0x1bLL << 28)];
}
- (void)testWriteVarint7 {
// 41256202580718336
[self assertWriteVarint:bytes(0x80, 0xe6, 0xeb, 0x9c, 0xc3, 0xc9, 0xa4, 0x49)
value:(0x00 << 0) | (0x66 << 7) | (0x6b << 14) |
(0x1c << 21) | (0x43LL << 28) | (0x49LL << 35) |
(0x24LL << 42) | (0x49LL << 49)];
}
- (void)testWriteVarint8 {
// 11964378330978735131
[self assertWriteVarint:bytes(0x9b, 0xa8, 0xf9, 0xc2, 0xbb, 0xd6, 0x80, 0x85,
0xa6, 0x01)
value:(0x1b << 0) | (0x28 << 7) | (0x79 << 14) |
(0x42 << 21) | (0x3bLL << 28) | (0x56LL << 35) |
(0x00LL << 42) | (0x05LL << 49) | (0x26LL << 56) |
(0x01LL << 63)];
}
- (void)testWriteLittleEndian {
[self assertWriteLittleEndian32:bytes(0x78, 0x56, 0x34, 0x12)
value:0x12345678];
[self assertWriteLittleEndian32:bytes(0xf0, 0xde, 0xbc, 0x9a)
value:0x9abcdef0];
[self assertWriteLittleEndian64:bytes(0xf0, 0xde, 0xbc, 0x9a, 0x78, 0x56,
0x34, 0x12)
value:0x123456789abcdef0LL];
[self assertWriteLittleEndian64:bytes(0x78, 0x56, 0x34, 0x12, 0xf0, 0xde,
0xbc, 0x9a)
value:0x9abcdef012345678LL];
}
- (void)testEncodeZigZag {
XCTAssertEqual(0U, GPBEncodeZigZag32(0));
XCTAssertEqual(1U, GPBEncodeZigZag32(-1));
XCTAssertEqual(2U, GPBEncodeZigZag32(1));
XCTAssertEqual(3U, GPBEncodeZigZag32(-2));
XCTAssertEqual(0x7FFFFFFEU, GPBEncodeZigZag32(0x3FFFFFFF));
XCTAssertEqual(0x7FFFFFFFU, GPBEncodeZigZag32(0xC0000000));
XCTAssertEqual(0xFFFFFFFEU, GPBEncodeZigZag32(0x7FFFFFFF));
XCTAssertEqual(0xFFFFFFFFU, GPBEncodeZigZag32(0x80000000));
XCTAssertEqual(0ULL, GPBEncodeZigZag64(0));
XCTAssertEqual(1ULL, GPBEncodeZigZag64(-1));
XCTAssertEqual(2ULL, GPBEncodeZigZag64(1));
XCTAssertEqual(3ULL, GPBEncodeZigZag64(-2));
XCTAssertEqual(0x000000007FFFFFFEULL,
GPBEncodeZigZag64(0x000000003FFFFFFFLL));
XCTAssertEqual(0x000000007FFFFFFFULL,
GPBEncodeZigZag64(0xFFFFFFFFC0000000LL));
XCTAssertEqual(0x00000000FFFFFFFEULL,
GPBEncodeZigZag64(0x000000007FFFFFFFLL));
XCTAssertEqual(0x00000000FFFFFFFFULL,
GPBEncodeZigZag64(0xFFFFFFFF80000000LL));
XCTAssertEqual(0xFFFFFFFFFFFFFFFEULL,
GPBEncodeZigZag64(0x7FFFFFFFFFFFFFFFLL));
XCTAssertEqual(0xFFFFFFFFFFFFFFFFULL,
GPBEncodeZigZag64(0x8000000000000000LL));
// Some easier-to-verify round-trip tests. The inputs (other than 0, 1, -1)
// were chosen semi-randomly via keyboard bashing.
XCTAssertEqual(0U, GPBEncodeZigZag32(GPBDecodeZigZag32(0)));
XCTAssertEqual(1U, GPBEncodeZigZag32(GPBDecodeZigZag32(1)));
XCTAssertEqual(-1U, GPBEncodeZigZag32(GPBDecodeZigZag32(-1)));
XCTAssertEqual(14927U, GPBEncodeZigZag32(GPBDecodeZigZag32(14927)));
XCTAssertEqual(-3612U, GPBEncodeZigZag32(GPBDecodeZigZag32(-3612)));
XCTAssertEqual(0ULL, GPBEncodeZigZag64(GPBDecodeZigZag64(0)));
XCTAssertEqual(1ULL, GPBEncodeZigZag64(GPBDecodeZigZag64(1)));
XCTAssertEqual(-1ULL, GPBEncodeZigZag64(GPBDecodeZigZag64(-1)));
XCTAssertEqual(14927ULL, GPBEncodeZigZag64(GPBDecodeZigZag64(14927)));
XCTAssertEqual(-3612ULL, GPBEncodeZigZag64(GPBDecodeZigZag64(-3612)));
XCTAssertEqual(856912304801416ULL,
GPBEncodeZigZag64(GPBDecodeZigZag64(856912304801416LL)));
XCTAssertEqual(-75123905439571256ULL,
GPBEncodeZigZag64(GPBDecodeZigZag64(-75123905439571256LL)));
}
- (void)testWriteWholeMessage {
// Not kGPBDefaultRepeatCount because we are comparing to a golden master file
// that was generated with 2.
TestAllTypes* message = [self allSetRepeatedCount:2];
NSData* rawBytes = message.data;
NSData* goldenData =
[self getDataFileNamed:@"golden_message" dataToWrite:rawBytes];
XCTAssertEqualObjects(rawBytes, goldenData);
// Try different block sizes.
for (int blockSize = 1; blockSize < 256; blockSize *= 2) {
NSOutputStream* rawOutput = [NSOutputStream outputStreamToMemory];
GPBCodedOutputStream* output =
[GPBCodedOutputStream streamWithOutputStream:rawOutput
bufferSize:blockSize];
[message writeToCodedOutputStream:output];
[output flush];
NSData* actual =
[rawOutput propertyForKey:NSStreamDataWrittenToMemoryStreamKey];
XCTAssertEqualObjects(rawBytes, actual);
}
// Not kGPBDefaultRepeatCount because we are comparing to a golden master file
// that was generated with 2.
TestAllExtensions* extensions = [self allExtensionsSetRepeatedCount:2];
rawBytes = extensions.data;
goldenData = [self getDataFileNamed:@"golden_packed_fields_message"
dataToWrite:rawBytes];
XCTAssertEqualObjects(rawBytes, goldenData);
}
@end

@ -0,0 +1,157 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2014 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#import "GPBTestUtilities.h"
#import "google/protobuf/Unittest.pbobjc.h"
static const int kNumThreads = 100;
static const int kNumMessages = 100;
@interface ConcurrencyTests : GPBTestCase
@end
@implementation ConcurrencyTests
- (NSArray *)createThreadsWithSelector:(SEL)selector object:(id)object {
NSMutableArray *array = [NSMutableArray array];
for (NSUInteger i = 0; i < kNumThreads; i++) {
NSThread *thread =
[[NSThread alloc] initWithTarget:self selector:selector object:object];
[array addObject:thread];
[thread release];
}
return array;
}
- (NSArray *)createMessagesWithType:(Class)msgType {
NSMutableArray *array = [NSMutableArray array];
for (NSUInteger i = 0; i < kNumMessages; i++) {
[array addObject:[msgType message]];
}
return array;
}
- (void)startThreads:(NSArray *)threads {
for (NSThread *thread in threads) {
[thread start];
}
}
- (void)joinThreads:(NSArray *)threads {
for (NSThread *thread in threads) {
while (![thread isFinished])
;
}
}
- (void)readForeignMessage:(NSArray *)messages {
for (NSUInteger i = 0; i < 10; i++) {
for (TestAllTypes *message in messages) {
XCTAssertEqual(message.optionalForeignMessage.c, 0);
}
}
}
- (void)testConcurrentReadOfUnsetMessageField {
NSArray *messages = [self createMessagesWithType:[TestAllTypes class]];
NSArray *threads =
[self createThreadsWithSelector:@selector(readForeignMessage:)
object:messages];
[self startThreads:threads];
[self joinThreads:threads];
for (TestAllTypes *message in messages) {
XCTAssertFalse(message.hasOptionalForeignMessage);
}
}
- (void)readRepeatedInt32:(NSArray *)messages {
for (int i = 0; i < 10; i++) {
for (TestAllTypes *message in messages) {
XCTAssertEqual([message.repeatedInt32Array count], (NSUInteger)0);
}
}
}
- (void)testConcurrentReadOfUnsetRepeatedIntField {
NSArray *messages = [self createMessagesWithType:[TestAllTypes class]];
NSArray *threads =
[self createThreadsWithSelector:@selector(readRepeatedInt32:)
object:messages];
[self startThreads:threads];
[self joinThreads:threads];
for (TestAllTypes *message in messages) {
XCTAssertEqual([message.repeatedInt32Array count], (NSUInteger)0);
}
}
- (void)readRepeatedString:(NSArray *)messages {
for (int i = 0; i < 10; i++) {
for (TestAllTypes *message in messages) {
XCTAssertEqual([message.repeatedStringArray count], (NSUInteger)0);
}
}
}
- (void)testConcurrentReadOfUnsetRepeatedStringField {
NSArray *messages = [self createMessagesWithType:[TestAllTypes class]];
NSArray *threads =
[self createThreadsWithSelector:@selector(readRepeatedString:)
object:messages];
[self startThreads:threads];
[self joinThreads:threads];
for (TestAllTypes *message in messages) {
XCTAssertEqual([message.repeatedStringArray count], (NSUInteger)0);
}
}
- (void)readOptionalForeignMessageExtension:(NSArray *)messages {
for (int i = 0; i < 10; i++) {
for (TestAllExtensions *message in messages) {
ForeignMessage *foreign =
[message getExtension:[UnittestRoot optionalForeignMessageExtension]];
XCTAssertEqual(foreign.c, 0);
}
}
}
- (void)testConcurrentReadOfUnsetExtensionField {
NSArray *messages = [self createMessagesWithType:[TestAllExtensions class]];
SEL sel = @selector(readOptionalForeignMessageExtension:);
NSArray *threads = [self createThreadsWithSelector:sel object:messages];
[self startThreads:threads];
[self joinThreads:threads];
GPBExtensionField *extension = [UnittestRoot optionalForeignMessageExtension];
for (TestAllExtensions *message in messages) {
XCTAssertFalse([message hasExtension:extension]);
}
}
@end

@ -0,0 +1,232 @@
// 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 "GPBTestUtilities.h"
#import <objc/runtime.h>
#import "GPBDescriptor.h"
#import "google/protobuf/Unittest.pbobjc.h"
@interface DescriptorTests : GPBTestCase
@end
@implementation DescriptorTests
- (void)testFieldDescriptor {
GPBDescriptor *descriptor = [TestAllTypes descriptor];
// Nested Enum
GPBFieldDescriptor *fieldDescriptorWithName =
[descriptor fieldWithName:@"optionalNestedEnum"];
XCTAssertNotNil(fieldDescriptorWithName);
GPBFieldDescriptor *fieldDescriptorWithNumber =
[descriptor fieldWithNumber:21];
XCTAssertNotNil(fieldDescriptorWithNumber);
XCTAssertEqual(fieldDescriptorWithName, fieldDescriptorWithNumber);
XCTAssertNotNil(fieldDescriptorWithNumber.enumDescriptor);
XCTAssertEqualObjects(fieldDescriptorWithNumber.enumDescriptor.name,
@"TestAllTypes_NestedEnum");
// Foreign Enum
fieldDescriptorWithName = [descriptor fieldWithName:@"optionalForeignEnum"];
XCTAssertNotNil(fieldDescriptorWithName);
fieldDescriptorWithNumber = [descriptor fieldWithNumber:22];
XCTAssertNotNil(fieldDescriptorWithNumber);
XCTAssertEqual(fieldDescriptorWithName, fieldDescriptorWithNumber);
XCTAssertNotNil(fieldDescriptorWithNumber.enumDescriptor);
XCTAssertEqualObjects(fieldDescriptorWithNumber.enumDescriptor.name,
@"ForeignEnum");
// Import Enum
fieldDescriptorWithName = [descriptor fieldWithName:@"optionalImportEnum"];
XCTAssertNotNil(fieldDescriptorWithName);
fieldDescriptorWithNumber = [descriptor fieldWithNumber:23];
XCTAssertNotNil(fieldDescriptorWithNumber);
XCTAssertEqual(fieldDescriptorWithName, fieldDescriptorWithNumber);
XCTAssertNotNil(fieldDescriptorWithNumber.enumDescriptor);
XCTAssertEqualObjects(fieldDescriptorWithNumber.enumDescriptor.name,
@"ImportEnum");
// Nested Message
fieldDescriptorWithName = [descriptor fieldWithName:@"optionalNestedMessage"];
XCTAssertNotNil(fieldDescriptorWithName);
fieldDescriptorWithNumber = [descriptor fieldWithNumber:18];
XCTAssertNotNil(fieldDescriptorWithNumber);
XCTAssertEqual(fieldDescriptorWithName, fieldDescriptorWithNumber);
XCTAssertNil(fieldDescriptorWithNumber.enumDescriptor);
// Foreign Message
fieldDescriptorWithName =
[descriptor fieldWithName:@"optionalForeignMessage"];
XCTAssertNotNil(fieldDescriptorWithName);
fieldDescriptorWithNumber = [descriptor fieldWithNumber:19];
XCTAssertNotNil(fieldDescriptorWithNumber);
XCTAssertEqual(fieldDescriptorWithName, fieldDescriptorWithNumber);
XCTAssertNil(fieldDescriptorWithNumber.enumDescriptor);
// Import Message
fieldDescriptorWithName = [descriptor fieldWithName:@"optionalImportMessage"];
XCTAssertNotNil(fieldDescriptorWithName);
fieldDescriptorWithNumber = [descriptor fieldWithNumber:20];
XCTAssertNotNil(fieldDescriptorWithNumber);
XCTAssertEqual(fieldDescriptorWithName, fieldDescriptorWithNumber);
XCTAssertNil(fieldDescriptorWithNumber.enumDescriptor);
}
- (void)testEnumDescriptor {
GPBEnumDescriptor *descriptor = TestAllTypes_NestedEnum_EnumDescriptor();
NSString *enumName = [descriptor enumNameForValue:1];
XCTAssertNotNil(enumName);
int32_t value;
XCTAssertTrue(
[descriptor getValue:&value forEnumName:@"TestAllTypes_NestedEnum_Foo"]);
XCTAssertTrue(
[descriptor getValue:NULL forEnumName:@"TestAllTypes_NestedEnum_Foo"]);
XCTAssertEqual(value, TestAllTypes_NestedEnum_Foo);
enumName = [descriptor enumNameForValue:2];
XCTAssertNotNil(enumName);
XCTAssertTrue(
[descriptor getValue:&value forEnumName:@"TestAllTypes_NestedEnum_Bar"]);
XCTAssertEqual(value, TestAllTypes_NestedEnum_Bar);
enumName = [descriptor enumNameForValue:3];
XCTAssertNotNil(enumName);
XCTAssertTrue(
[descriptor getValue:&value forEnumName:@"TestAllTypes_NestedEnum_Baz"]);
XCTAssertEqual(value, TestAllTypes_NestedEnum_Baz);
// Bad values
enumName = [descriptor enumNameForValue:0];
XCTAssertNil(enumName);
XCTAssertFalse([descriptor getValue:&value forEnumName:@"Unknown"]);
XCTAssertFalse([descriptor getValue:NULL forEnumName:@"Unknown"]);
XCTAssertFalse([descriptor getValue:&value
forEnumName:@"TestAllTypes_NestedEnum_Unknown"]);
XCTAssertFalse([descriptor getValue:NULL
forEnumName:@"TestAllTypes_NestedEnum_Unknown"]);
}
- (void)testEnumValueValidator {
GPBDescriptor *descriptor = [TestAllTypes descriptor];
GPBFieldDescriptor *fieldDescriptor =
[descriptor fieldWithName:@"optionalNestedEnum"];
// Valid values
XCTAssertTrue([fieldDescriptor isValidEnumValue:1]);
XCTAssertTrue([fieldDescriptor isValidEnumValue:2]);
XCTAssertTrue([fieldDescriptor isValidEnumValue:3]);
XCTAssertTrue([fieldDescriptor isValidEnumValue:-1]);
// Invalid values
XCTAssertFalse([fieldDescriptor isValidEnumValue:4]);
XCTAssertFalse([fieldDescriptor isValidEnumValue:0]);
XCTAssertFalse([fieldDescriptor isValidEnumValue:-2]);
}
- (void)testEnumDescriptorLookup {
GPBDescriptor *descriptor = [TestAllTypes descriptor];
GPBEnumDescriptor *enumDescriptor =
[descriptor enumWithName:@"TestAllTypes_NestedEnum"];
XCTAssertNotNil(enumDescriptor);
// Descriptor cannot find foreign or imported enums.
enumDescriptor = [descriptor enumWithName:@"ForeignEnumEnum"];
XCTAssertNil(enumDescriptor);
enumDescriptor = [descriptor enumWithName:@"ImportEnumEnum"];
XCTAssertNil(enumDescriptor);
}
- (void)testOneofDescriptor {
GPBDescriptor *descriptor = [TestOneof2 descriptor];
// All fields should be listed.
XCTAssertEqual(descriptor.fields.count, 17U);
// There are two oneofs in there.
XCTAssertEqual(descriptor.oneofs.count, 2U);
GPBFieldDescriptor *fooStringField =
[descriptor fieldWithNumber:TestOneof2_FieldNumber_FooString];
XCTAssertNotNil(fooStringField);
GPBFieldDescriptor *barStringField =
[descriptor fieldWithNumber:TestOneof2_FieldNumber_BarString];
XCTAssertNotNil(barStringField);
// Check the oneofs to have what is expected.
GPBOneofDescriptor *oneofFoo = [descriptor oneofWithName:@"foo"];
XCTAssertNotNil(oneofFoo);
XCTAssertEqual(oneofFoo.fields.count, 9U);
// Pointer comparisons.
XCTAssertEqual([oneofFoo fieldWithNumber:TestOneof2_FieldNumber_FooString],
fooStringField);
XCTAssertEqual([oneofFoo fieldWithName:@"fooString"], fooStringField);
GPBOneofDescriptor *oneofBar = [descriptor oneofWithName:@"bar"];
XCTAssertNotNil(oneofBar);
XCTAssertEqual(oneofBar.fields.count, 6U);
// Pointer comparisons.
XCTAssertEqual([oneofBar fieldWithNumber:TestOneof2_FieldNumber_BarString],
barStringField);
XCTAssertEqual([oneofBar fieldWithName:@"barString"], barStringField);
// Unknown oneof not found.
XCTAssertNil([descriptor oneofWithName:@"mumble"]);
XCTAssertNil([descriptor oneofWithName:@"Foo"]);
// Unknown oneof item.
XCTAssertNil([oneofFoo fieldWithName:@"mumble"]);
XCTAssertNil([oneofFoo fieldWithNumber:666]);
// Field exists, but not in this oneof.
XCTAssertNil([oneofFoo fieldWithName:@"barString"]);
XCTAssertNil([oneofFoo fieldWithNumber:TestOneof2_FieldNumber_BarString]);
XCTAssertNil([oneofBar fieldWithName:@"fooString"]);
XCTAssertNil([oneofBar fieldWithNumber:TestOneof2_FieldNumber_FooString]);
// Check pointers back to the enclosing oneofs.
// (pointer comparisions)
XCTAssertEqual(fooStringField.containingOneof, oneofFoo);
XCTAssertEqual(barStringField.containingOneof, oneofBar);
GPBFieldDescriptor *bazString =
[descriptor fieldWithNumber:TestOneof2_FieldNumber_BazString];
XCTAssertNotNil(bazString);
XCTAssertNil(bazString.containingOneof);
}
@end

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save