Commit d846b0b0 authored by Thomas Van Lenten's avatar Thomas Van Lenten

Beta quality drop of Objective C Support.

- Add more to the ObjC dir readme.
- Merge the ExtensionField and ExtensionDescriptor to reduce overhead.
- Fix an initialization race.
- Clean up the Xcode schemes.
- Remove the class/enum filter.
- Remove some forced inline that were bloating things without proof of performance wins.
- Rename some internal types to avoid conflicts with the well know types protos.
- Drop the use of ApplyFunctions to the compiler/optimizer can do what it wants.
- Better document some possible future improvements.
- Add missing support for parsing repeated primitive fields in packed or unpacked forms.
- Improve -hash.
- Add *Count for repeated and map<> fields to avoid auto create when checking for them being set.
parent 3f9be70d
...@@ -506,14 +506,10 @@ objectivec_EXTRA_DIST= \ ...@@ -506,14 +506,10 @@ objectivec_EXTRA_DIST= \
objectivec/GPBDictionary.h \ objectivec/GPBDictionary.h \
objectivec/GPBDictionary.m \ objectivec/GPBDictionary.m \
objectivec/GPBDictionary_PackagePrivate.h \ objectivec/GPBDictionary_PackagePrivate.h \
objectivec/GPBExtensionField.h \ objectivec/GPBExtensionInternals.h \
objectivec/GPBExtensionField.m \ objectivec/GPBExtensionInternals.m \
objectivec/GPBExtensionField_PackagePrivate.h \
objectivec/GPBExtensionRegistry.h \ objectivec/GPBExtensionRegistry.h \
objectivec/GPBExtensionRegistry.m \ objectivec/GPBExtensionRegistry.m \
objectivec/GPBField.h \
objectivec/GPBField.m \
objectivec/GPBField_PackagePrivate.h \
objectivec/GPBMessage.h \ objectivec/GPBMessage.h \
objectivec/GPBMessage.m \ objectivec/GPBMessage.m \
objectivec/GPBMessage_PackagePrivate.h \ objectivec/GPBMessage_PackagePrivate.h \
...@@ -523,7 +519,10 @@ objectivec_EXTRA_DIST= \ ...@@ -523,7 +519,10 @@ objectivec_EXTRA_DIST= \
objectivec/GPBRootObject.h \ objectivec/GPBRootObject.h \
objectivec/GPBRootObject.m \ objectivec/GPBRootObject.m \
objectivec/GPBRootObject_PackagePrivate.h \ objectivec/GPBRootObject_PackagePrivate.h \
objectivec/GPBTypes.h \ objectivec/GPBRuntimeTypes.h \
objectivec/GPBUnknownField.h \
objectivec/GPBUnknownField.m \
objectivec/GPBUnknownField_PackagePrivate.h \
objectivec/GPBUnknownFieldSet.h \ objectivec/GPBUnknownFieldSet.h \
objectivec/GPBUnknownFieldSet.m \ objectivec/GPBUnknownFieldSet.m \
objectivec/GPBUnknownFieldSet_PackagePrivate.h \ objectivec/GPBUnknownFieldSet_PackagePrivate.h \
...@@ -547,8 +546,6 @@ objectivec_EXTRA_DIST= \ ...@@ -547,8 +546,6 @@ objectivec_EXTRA_DIST= \
objectivec/ProtocolBuffers_OSX.xcodeproj/xcshareddata/xcschemes/PerformanceTests.xcscheme \ objectivec/ProtocolBuffers_OSX.xcodeproj/xcshareddata/xcschemes/PerformanceTests.xcscheme \
objectivec/ProtocolBuffers_OSX.xcodeproj/xcshareddata/xcschemes/ProtocolBuffers.xcscheme \ objectivec/ProtocolBuffers_OSX.xcodeproj/xcshareddata/xcschemes/ProtocolBuffers.xcscheme \
objectivec/README.md \ objectivec/README.md \
objectivec/Tests/Filter1.txt \
objectivec/Tests/Filter2.txt \
objectivec/Tests/golden_message \ objectivec/Tests/golden_message \
objectivec/Tests/golden_packed_fields_message \ objectivec/Tests/golden_packed_fields_message \
objectivec/Tests/GPBARCUnittestProtos.m \ objectivec/Tests/GPBARCUnittestProtos.m \
...@@ -564,7 +561,6 @@ objectivec_EXTRA_DIST= \ ...@@ -564,7 +561,6 @@ objectivec_EXTRA_DIST= \
objectivec/Tests/GPBDictionaryTests+UInt32.m \ objectivec/Tests/GPBDictionaryTests+UInt32.m \
objectivec/Tests/GPBDictionaryTests+UInt64.m \ objectivec/Tests/GPBDictionaryTests+UInt64.m \
objectivec/Tests/GPBDictionaryTests.pddm \ objectivec/Tests/GPBDictionaryTests.pddm \
objectivec/Tests/GPBFilteredMessageTests.m \
objectivec/Tests/GPBMessageTests+Merge.m \ objectivec/Tests/GPBMessageTests+Merge.m \
objectivec/Tests/GPBMessageTests+Runtime.m \ objectivec/Tests/GPBMessageTests+Runtime.m \
objectivec/Tests/GPBMessageTests+Serialization.m \ objectivec/Tests/GPBMessageTests+Serialization.m \
...@@ -596,8 +592,6 @@ objectivec_EXTRA_DIST= \ ...@@ -596,8 +592,6 @@ objectivec_EXTRA_DIST= \
objectivec/Tests/text_format_map_unittest_data.txt \ objectivec/Tests/text_format_map_unittest_data.txt \
objectivec/Tests/text_format_unittest_data.txt \ objectivec/Tests/text_format_unittest_data.txt \
objectivec/Tests/unittest_cycle.proto \ objectivec/Tests/unittest_cycle.proto \
objectivec/Tests/unittest_filter.proto \
objectivec/Tests/unittest_name_mangling.proto \
objectivec/Tests/unittest_objc.proto \ objectivec/Tests/unittest_objc.proto \
objectivec/Tests/unittest_runtime_proto2.proto \ objectivec/Tests/unittest_runtime_proto2.proto \
objectivec/Tests/unittest_runtime_proto3.proto \ objectivec/Tests/unittest_runtime_proto3.proto \
......
#!/bin/bash
# Invoked by the Xcode projects to build the protos needed for the unittests.
set -eu
readonly OUTPUT_DIR="${PROJECT_DERIVED_FILE_DIR}/protos"
# Helper for bailing.
die() {
echo "Error: $1"
exit 2
}
# What to do.
case "${ACTION}" in
"")
# Build, fall thru
;;
"clean")
rm -rf "${OUTPUT_DIR}"
exit 0
;;
*)
die "Unknown action requested: ${ACTION}"
;;
esac
# Move to the top of the protobuf directories.
cd "${SRCROOT}/.."
[[ -x src/protoc ]] || \
die "Could not find the protoc binary; make sure you have built it (objectivec/DevTools/full_mac_build.sh -h)."
RUN_PROTOC=no
if [[ ! -d "${OUTPUT_DIR}" ]] ; then
RUN_PROTOC=yes
else
# Find the newest input file (protos, compiler, and this script).
# (these patterns catch some extra stuff, but better to over sample than
# under)
readonly NewestInput=$(find \
src/google/protobuf/*.proto \
objectivec/Tests/*.proto \
src/.libs src/*.la src/protoc \
objectivec/DevTools/compile_testing_protos.sh \
-type f -print0 \
| xargs -0 stat -f "%m %N" \
| sort -n | tail -n1 | cut -f2- -d" ")
# Find the oldest output file.
readonly OldestOutput=$(find \
"${OUTPUT_DIR}" \
-type f -print0 \
| xargs -0 stat -f "%m %N" \
| sort -n -r | tail -n1 | cut -f2- -d" ")
# If the newest input is newer than the oldest output, regenerate.
if [[ "${NewestInput}" -nt "${OldestOutput}" ]] ; then
RUN_PROTOC=yes
fi
fi
if [[ "${RUN_PROTOC}" != "yes" ]] ; then
# Up to date.
exit 0
fi
# Ensure the output dir exists
mkdir -p "${OUTPUT_DIR}/google/protobuf"
CORE_PROTO_FILES=( \
src/google/protobuf/unittest_custom_options.proto \
src/google/protobuf/unittest_enormous_descriptor.proto \
src/google/protobuf/unittest_embed_optimize_for.proto \
src/google/protobuf/unittest_empty.proto \
src/google/protobuf/unittest_import.proto \
src/google/protobuf/unittest_import_lite.proto \
src/google/protobuf/unittest_lite.proto \
src/google/protobuf/unittest_mset.proto \
src/google/protobuf/unittest_no_generic_services.proto \
src/google/protobuf/unittest_optimize_for.proto \
src/google/protobuf/unittest.proto \
src/google/protobuf/unittest_import_public.proto \
src/google/protobuf/unittest_import_public_lite.proto \
src/google/protobuf/unittest_drop_unknown_fields.proto \
src/google/protobuf/unittest_preserve_unknown_enum.proto \
src/google/protobuf/map_lite_unittest.proto \
src/google/protobuf/map_proto2_unittest.proto \
src/google/protobuf/map_unittest.proto \
)
compile_proto() {
src/protoc \
--objc_out="${OUTPUT_DIR}/google/protobuf" \
--proto_path=src/google/protobuf/ \
--proto_path=src \
$*
}
for a_proto in "${CORE_PROTO_FILES[@]}" ; do
compile_proto "${a_proto}"
done
OBJC_PROTO_FILES=( \
objectivec/Tests/unittest_cycle.proto \
objectivec/Tests/unittest_runtime_proto2.proto \
objectivec/Tests/unittest_runtime_proto3.proto \
objectivec/Tests/unittest_objc.proto \
objectivec/Tests/unittest_objc_startup.proto \
)
for a_proto in "${OBJC_PROTO_FILES[@]}" ; do
compile_proto --proto_path="objectivec/Tests" "${a_proto}"
done
...@@ -162,7 +162,7 @@ wrapped_make -j "${NUM_MAKE_JOBS}" all ...@@ -162,7 +162,7 @@ wrapped_make -j "${NUM_MAKE_JOBS}" all
wrapped_make -j "${NUM_MAKE_JOBS}" check wrapped_make -j "${NUM_MAKE_JOBS}" check
header "Ensuring the ObjC descriptors are current." header "Ensuring the ObjC descriptors are current."
# Find the newest input file (protos, compiler, and this script). # Find the newest input file (protos, compiler, and the generator script).
# (these patterns catch some extra stuff, but better to over sample than under) # (these patterns catch some extra stuff, but better to over sample than under)
readonly NewestInput=$(find \ readonly NewestInput=$(find \
src/google/protobuf/*.proto \ src/google/protobuf/*.proto \
......
...@@ -30,7 +30,7 @@ ...@@ -30,7 +30,7 @@
#import <Foundation/Foundation.h> #import <Foundation/Foundation.h>
#import "GPBTypes.h" #import "GPBRuntimeTypes.h"
// These classes are used for repeated fields of basic data types. They are used because // These classes are used for repeated fields of basic data types. They are used because
// they perform better than boxing into NSNumbers in NSArrays. // they perform better than boxing into NSNumbers in NSArrays.
......
...@@ -60,7 +60,7 @@ ...@@ -60,7 +60,7 @@
- (int64_t)readSInt64; - (int64_t)readSInt64;
- (BOOL)readBool; - (BOOL)readBool;
- (NSString *)readString; - (NSString *)readString;
- (NSData *)readData; - (NSData *)readBytes;
// Read an embedded message field value from the stream. // Read an embedded message field value from the stream.
- (void)readMessage:(GPBMessage *)message - (void)readMessage:(GPBMessage *)message
......
...@@ -38,7 +38,7 @@ ...@@ -38,7 +38,7 @@
static const NSUInteger kDefaultRecursionLimit = 64; static const NSUInteger kDefaultRecursionLimit = 64;
static inline void CheckSize(GPBCodedInputStreamState *state, size_t size) { static void CheckSize(GPBCodedInputStreamState *state, size_t size) {
size_t newSize = state->bufferPos + size; size_t newSize = state->bufferPos + size;
if (newSize > state->bufferSize) { if (newSize > state->bufferSize) {
[NSException raise:NSParseErrorException format:@""]; [NSException raise:NSParseErrorException format:@""];
...@@ -50,26 +50,26 @@ static inline void CheckSize(GPBCodedInputStreamState *state, size_t size) { ...@@ -50,26 +50,26 @@ static inline void CheckSize(GPBCodedInputStreamState *state, size_t size) {
} }
} }
static inline int8_t ReadRawByte(GPBCodedInputStreamState *state) { static int8_t ReadRawByte(GPBCodedInputStreamState *state) {
CheckSize(state, sizeof(int8_t)); CheckSize(state, sizeof(int8_t));
return ((int8_t *)state->bytes)[state->bufferPos++]; return ((int8_t *)state->bytes)[state->bufferPos++];
} }
static inline int32_t ReadRawLittleEndian32(GPBCodedInputStreamState *state) { static int32_t ReadRawLittleEndian32(GPBCodedInputStreamState *state) {
CheckSize(state, sizeof(int32_t)); CheckSize(state, sizeof(int32_t));
int32_t value = OSReadLittleInt32(state->bytes, state->bufferPos); int32_t value = OSReadLittleInt32(state->bytes, state->bufferPos);
state->bufferPos += sizeof(int32_t); state->bufferPos += sizeof(int32_t);
return value; return value;
} }
static inline int64_t ReadRawLittleEndian64(GPBCodedInputStreamState *state) { static int64_t ReadRawLittleEndian64(GPBCodedInputStreamState *state) {
CheckSize(state, sizeof(int64_t)); CheckSize(state, sizeof(int64_t));
int64_t value = OSReadLittleInt64(state->bytes, state->bufferPos); int64_t value = OSReadLittleInt64(state->bytes, state->bufferPos);
state->bufferPos += sizeof(int64_t); state->bufferPos += sizeof(int64_t);
return value; return value;
} }
static inline int32_t ReadRawVarint32(GPBCodedInputStreamState *state) { static int32_t ReadRawVarint32(GPBCodedInputStreamState *state) {
int8_t tmp = ReadRawByte(state); int8_t tmp = ReadRawByte(state);
if (tmp >= 0) { if (tmp >= 0) {
return tmp; return tmp;
...@@ -104,7 +104,7 @@ static inline int32_t ReadRawVarint32(GPBCodedInputStreamState *state) { ...@@ -104,7 +104,7 @@ static inline int32_t ReadRawVarint32(GPBCodedInputStreamState *state) {
return result; return result;
} }
static inline int64_t ReadRawVarint64(GPBCodedInputStreamState *state) { static int64_t ReadRawVarint64(GPBCodedInputStreamState *state) {
int32_t shift = 0; int32_t shift = 0;
int64_t result = 0; int64_t result = 0;
while (shift < 64) { while (shift < 64) {
...@@ -119,7 +119,7 @@ static inline int64_t ReadRawVarint64(GPBCodedInputStreamState *state) { ...@@ -119,7 +119,7 @@ static inline int64_t ReadRawVarint64(GPBCodedInputStreamState *state) {
return 0; return 0;
} }
static inline void SkipRawData(GPBCodedInputStreamState *state, size_t size) { static void SkipRawData(GPBCodedInputStreamState *state, size_t size) {
CheckSize(state, size); CheckSize(state, size);
state->bufferPos += size; state->bufferPos += size;
} }
...@@ -222,7 +222,7 @@ NSString *GPBCodedInputStreamReadRetainedString( ...@@ -222,7 +222,7 @@ NSString *GPBCodedInputStreamReadRetainedString(
return result; return result;
} }
NSData *GPBCodedInputStreamReadRetainedData(GPBCodedInputStreamState *state) { NSData *GPBCodedInputStreamReadRetainedBytes(GPBCodedInputStreamState *state) {
int32_t size = ReadRawVarint32(state); int32_t size = ReadRawVarint32(state);
if (size < 0) return nil; if (size < 0) return nil;
CheckSize(state, size); CheckSize(state, size);
...@@ -232,7 +232,7 @@ NSData *GPBCodedInputStreamReadRetainedData(GPBCodedInputStreamState *state) { ...@@ -232,7 +232,7 @@ NSData *GPBCodedInputStreamReadRetainedData(GPBCodedInputStreamState *state) {
return result; return result;
} }
NSData *GPBCodedInputStreamReadRetainedDataNoCopy( NSData *GPBCodedInputStreamReadRetainedBytesNoCopy(
GPBCodedInputStreamState *state) { GPBCodedInputStreamState *state) {
int32_t size = ReadRawVarint32(state); int32_t size = ReadRawVarint32(state);
if (size < 0) return nil; if (size < 0) return nil;
...@@ -453,8 +453,8 @@ void GPBCodedInputStreamCheckLastTagWas(GPBCodedInputStreamState *state, ...@@ -453,8 +453,8 @@ void GPBCodedInputStreamCheckLastTagWas(GPBCodedInputStreamState *state,
GPBCodedInputStreamPopLimit(&state_, oldLimit); GPBCodedInputStreamPopLimit(&state_, oldLimit);
} }
- (NSData *)readData { - (NSData *)readBytes {
return [GPBCodedInputStreamReadRetainedData(&state_) autorelease]; return [GPBCodedInputStreamReadRetainedBytes(&state_) autorelease];
} }
- (uint32_t)readUInt32 { - (uint32_t)readUInt32 {
...@@ -499,7 +499,7 @@ void GPBCodedInputStreamCheckLastTagWas(GPBCodedInputStreamState *state, ...@@ -499,7 +499,7 @@ void GPBCodedInputStreamCheckLastTagWas(GPBCodedInputStreamState *state,
// Returns true if the passed in bytes are 7 bit ascii. // Returns true if the passed in bytes are 7 bit ascii.
// This routine needs to be fast. // This routine needs to be fast.
static inline bool AreBytesIn7BitASCII(const uint8_t *bytes, NSUInteger len) { static bool AreBytesIn7BitASCII(const uint8_t *bytes, NSUInteger len) {
// In the loops below, it's more efficient to collect rather than do // In the loops below, it's more efficient to collect rather than do
// conditional at every step. // conditional at every step.
#if __LP64__ #if __LP64__
...@@ -587,7 +587,7 @@ static inline bool AreBytesIn7BitASCII(const uint8_t *bytes, NSUInteger len) { ...@@ -587,7 +587,7 @@ static inline bool AreBytesIn7BitASCII(const uint8_t *bytes, NSUInteger len) {
return true; return true;
} }
static inline void GPBStringInitStringValue(GPBString *string) { static void GPBStringInitStringValue(GPBString *string) {
OSSpinLockLock(&string->lock_); OSSpinLockLock(&string->lock_);
GPBStringInitStringValueAlreadyLocked(string); GPBStringInitStringValueAlreadyLocked(string);
OSSpinLockUnlock(&string->lock_); OSSpinLockUnlock(&string->lock_);
......
...@@ -114,9 +114,9 @@ int64_t GPBCodedInputStreamReadSInt64(GPBCodedInputStreamState *state); ...@@ -114,9 +114,9 @@ int64_t GPBCodedInputStreamReadSInt64(GPBCodedInputStreamState *state);
BOOL GPBCodedInputStreamReadBool(GPBCodedInputStreamState *state); BOOL GPBCodedInputStreamReadBool(GPBCodedInputStreamState *state);
NSString *GPBCodedInputStreamReadRetainedString(GPBCodedInputStreamState *state) NSString *GPBCodedInputStreamReadRetainedString(GPBCodedInputStreamState *state)
__attribute((ns_returns_retained)); __attribute((ns_returns_retained));
NSData *GPBCodedInputStreamReadRetainedData(GPBCodedInputStreamState *state) NSData *GPBCodedInputStreamReadRetainedBytes(GPBCodedInputStreamState *state)
__attribute((ns_returns_retained)); __attribute((ns_returns_retained));
NSData *GPBCodedInputStreamReadRetainedDataNoCopy( NSData *GPBCodedInputStreamReadRetainedBytesNoCopy(
GPBCodedInputStreamState *state) __attribute((ns_returns_retained)); GPBCodedInputStreamState *state) __attribute((ns_returns_retained));
size_t GPBCodedInputStreamPushLimit(GPBCodedInputStreamState *state, size_t GPBCodedInputStreamPushLimit(GPBCodedInputStreamState *state,
......
This diff is collapsed.
This diff is collapsed.
...@@ -30,7 +30,7 @@ ...@@ -30,7 +30,7 @@
#import <Foundation/Foundation.h> #import <Foundation/Foundation.h>
#import "GPBTypes.h" #import "GPBRuntimeTypes.h"
@class GPBEnumDescriptor; @class GPBEnumDescriptor;
@class GPBFieldDescriptor; @class GPBFieldDescriptor;
...@@ -89,14 +89,14 @@ typedef NS_ENUM(NSInteger, GPBFieldType) { ...@@ -89,14 +89,14 @@ typedef NS_ENUM(NSInteger, GPBFieldType) {
@property(nonatomic, readonly, copy) NSString *name; @property(nonatomic, readonly, copy) NSString *name;
@property(nonatomic, readonly) uint32_t number; @property(nonatomic, readonly) uint32_t number;
@property(nonatomic, readonly) GPBType type; @property(nonatomic, readonly) GPBDataType dataType;
@property(nonatomic, readonly) BOOL hasDefaultValue; @property(nonatomic, readonly) BOOL hasDefaultValue;
@property(nonatomic, readonly) GPBValue defaultValue; @property(nonatomic, readonly) GPBGenericValue defaultValue;
@property(nonatomic, readonly, getter=isRequired) BOOL required; @property(nonatomic, readonly, getter=isRequired) BOOL required;
@property(nonatomic, readonly, getter=isOptional) BOOL optional; @property(nonatomic, readonly, getter=isOptional) BOOL optional;
@property(nonatomic, readonly) GPBFieldType fieldType; @property(nonatomic, readonly) GPBFieldType fieldType;
// If it is a map, the value type is in -type. // If it is a map, the value type is in -type.
@property(nonatomic, readonly) GPBType mapKeyType; @property(nonatomic, readonly) GPBDataType mapKeyDataType;
@property(nonatomic, readonly, getter=isPackable) BOOL packable; @property(nonatomic, readonly, getter=isPackable) BOOL packable;
@property(nonatomic, readonly, assign) GPBOneofDescriptor *containingOneof; @property(nonatomic, readonly, assign) GPBOneofDescriptor *containingOneof;
...@@ -129,12 +129,14 @@ typedef NS_ENUM(NSInteger, GPBFieldType) { ...@@ -129,12 +129,14 @@ typedef NS_ENUM(NSInteger, GPBFieldType) {
@end @end
@interface GPBExtensionDescriptor : NSObject @interface GPBExtensionDescriptor : NSObject<NSCopying>
@property(nonatomic, readonly) uint32_t fieldNumber; @property(nonatomic, readonly) uint32_t fieldNumber;
@property(nonatomic, readonly) GPBType type; @property(nonatomic, readonly) Class containingMessageClass;
@property(nonatomic, readonly) GPBDataType dataType;
@property(nonatomic, readonly, getter=isRepeated) BOOL repeated; @property(nonatomic, readonly, getter=isRepeated) BOOL repeated;
@property(nonatomic, readonly, getter=isPackable) BOOL packable; @property(nonatomic, readonly, getter=isPackable) BOOL packable;
@property(nonatomic, readonly, assign) Class msgClass; @property(nonatomic, readonly, assign) Class msgClass;
@property(nonatomic, readonly) NSString *singletonName; @property(nonatomic, readonly) NSString *singletonName;
@property(nonatomic, readonly, strong) GPBEnumDescriptor *enumDescriptor; @property(nonatomic, readonly, strong) GPBEnumDescriptor *enumDescriptor;
@property(nonatomic, readonly) id defaultValue;
@end @end
This diff is collapsed.
...@@ -33,6 +33,7 @@ ...@@ -33,6 +33,7 @@
// subject to change at any time without notice. // subject to change at any time without notice.
#import "GPBDescriptor.h" #import "GPBDescriptor.h"
#import "GPBWireFormat.h"
// Describes attributes of the field. // Describes attributes of the field.
typedef NS_OPTIONS(uint32_t, GPBFieldFlags) { typedef NS_OPTIONS(uint32_t, GPBFieldFlags) {
...@@ -66,8 +67,6 @@ typedef NS_OPTIONS(uint32_t, GPBFieldFlags) { ...@@ -66,8 +67,6 @@ typedef NS_OPTIONS(uint32_t, GPBFieldFlags) {
// set, the name can be derived from the ObjC name. // set, the name can be derived from the ObjC name.
GPBFieldTextFormatNameCustom = 1 << 16, GPBFieldTextFormatNameCustom = 1 << 16,
// Indicates the field has an enum descriptor. // 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, GPBFieldHasEnumDescriptor = 1 << 17,
}; };
...@@ -84,21 +83,21 @@ typedef struct GPBMessageFieldDescription { ...@@ -84,21 +83,21 @@ typedef struct GPBMessageFieldDescription {
int32_t hasIndex; int32_t hasIndex;
// Field flags. Use accessor functions below. // Field flags. Use accessor functions below.
GPBFieldFlags flags; GPBFieldFlags flags;
// Type of the ivar. // Data type of the ivar.
GPBType type; GPBDataType dataType;
// Offset of the variable into it's structure struct. // Offset of the variable into it's structure struct.
size_t offset; size_t offset;
// FieldOptions protobuf, serialized as string. // FieldOptions protobuf, serialized as string.
const char *fieldOptions; const char *fieldOptions;
GPBValue defaultValue; // Default value for the ivar. GPBGenericValue defaultValue; // Default value for the ivar.
union { union {
const char *className; // Name for message class. const char *className; // Name for message class.
// For enums only: If EnumDescriptors are compiled in, it will be that, // For enums only: If EnumDescriptors are compiled in, it will be that,
// otherwise it will be the verifier. // otherwise it will be the verifier.
GPBEnumDescriptorFunc enumDescFunc; GPBEnumDescriptorFunc enumDescFunc;
GPBEnumValidationFunc enumVerifier; GPBEnumValidationFunc enumVerifier;
} typeSpecific; } dataTypeSpecific;
} GPBMessageFieldDescription; } GPBMessageFieldDescription;
// Describes a oneof. // Describes a oneof.
...@@ -133,10 +132,10 @@ typedef NS_OPTIONS(uint32_t, GPBExtensionOptions) { ...@@ -133,10 +132,10 @@ typedef NS_OPTIONS(uint32_t, GPBExtensionOptions) {
// An extension // An extension
typedef struct GPBExtensionDescription { typedef struct GPBExtensionDescription {
const char *singletonName; const char *singletonName;
GPBType type; GPBDataType dataType;
const char *extendedClass; const char *extendedClass;
int32_t fieldNumber; int32_t fieldNumber;
GPBValue defaultValue; GPBGenericValue defaultValue;
const char *messageOrGroupClassName; const char *messageOrGroupClassName;
GPBExtensionOptions options; GPBExtensionOptions options;
GPBEnumDescriptorFunc enumDescriptorFunc; GPBEnumDescriptorFunc enumDescriptorFunc;
...@@ -217,7 +216,7 @@ typedef struct GPBExtensionDescription { ...@@ -217,7 +216,7 @@ typedef struct GPBExtensionDescription {
SEL getSel_; SEL getSel_;
SEL setSel_; SEL setSel_;
SEL hasSel_; SEL hasOrCountSel_; // *Count for map<>/repeated fields, has* otherwise.
SEL setHasSel_; SEL setHasSel_;
} }
...@@ -254,10 +253,18 @@ typedef struct GPBExtensionDescription { ...@@ -254,10 +253,18 @@ typedef struct GPBExtensionDescription {
@package @package
GPBExtensionDescription *description_; GPBExtensionDescription *description_;
} }
@property(nonatomic, readonly) GPBWireFormat wireType;
// For repeated extensions, alternateWireType is the wireType with the opposite
// value for the packable property. i.e. - if the extension was marked packed
// it would be the wire type for unpacked; if the extension was marked unpacked,
// it would be the wire type for packed.
@property(nonatomic, readonly) GPBWireFormat alternateWireType;
// description has to be long lived, it is held as a raw pointer. // description has to be long lived, it is held as a raw pointer.
- (instancetype)initWithExtensionDescription: - (instancetype)initWithExtensionDescription:
(GPBExtensionDescription *)description; (GPBExtensionDescription *)description;
- (NSComparisonResult)compareByFieldNumber:(GPBExtensionDescriptor *)other;
@end @end
CF_EXTERN_C_BEGIN CF_EXTERN_C_BEGIN
...@@ -267,8 +274,8 @@ GPB_INLINE BOOL GPBFieldIsMapOrArray(GPBFieldDescriptor *field) { ...@@ -267,8 +274,8 @@ GPB_INLINE BOOL GPBFieldIsMapOrArray(GPBFieldDescriptor *field) {
(GPBFieldRepeated | GPBFieldMapKeyMask)) != 0; (GPBFieldRepeated | GPBFieldMapKeyMask)) != 0;
} }
GPB_INLINE GPBType GPBGetFieldType(GPBFieldDescriptor *field) { GPB_INLINE GPBDataType GPBGetFieldDataType(GPBFieldDescriptor *field) {
return field->description_->type; return field->description_->dataType;
} }
GPB_INLINE int32_t GPBFieldHasIndex(GPBFieldDescriptor *field) { GPB_INLINE int32_t GPBFieldHasIndex(GPBFieldDescriptor *field) {
...@@ -281,6 +288,12 @@ GPB_INLINE uint32_t GPBFieldNumber(GPBFieldDescriptor *field) { ...@@ -281,6 +288,12 @@ GPB_INLINE uint32_t GPBFieldNumber(GPBFieldDescriptor *field) {
uint32_t GPBFieldTag(GPBFieldDescriptor *self); uint32_t GPBFieldTag(GPBFieldDescriptor *self);
// For repeated fields, alternateWireType is the wireType with the opposite
// value for the packable property. i.e. - if the field was marked packed it
// would be the wire type for unpacked; if the field was marked unpacked, it
// would be the wire type for packed.
uint32_t GPBFieldAlternateTag(GPBFieldDescriptor *self);
GPB_INLINE BOOL GPBPreserveUnknownFields(GPBFileSyntax syntax) { GPB_INLINE BOOL GPBPreserveUnknownFields(GPBFileSyntax syntax) {
return syntax != GPBFileSyntaxProto3; return syntax != GPBFileSyntaxProto3;
} }
...@@ -289,4 +302,17 @@ GPB_INLINE BOOL GPBHasPreservingUnknownEnumSemantics(GPBFileSyntax syntax) { ...@@ -289,4 +302,17 @@ GPB_INLINE BOOL GPBHasPreservingUnknownEnumSemantics(GPBFileSyntax syntax) {
return syntax == GPBFileSyntaxProto3; return syntax == GPBFileSyntaxProto3;
} }
GPB_INLINE BOOL GPBExtensionIsRepeated(GPBExtensionDescription *description) {
return (description->options & GPBExtensionRepeated) != 0;
}
GPB_INLINE BOOL GPBExtensionIsPacked(GPBExtensionDescription *description) {
return (description->options & GPBExtensionPacked) != 0;
}
GPB_INLINE BOOL GPBExtensionIsWireFormat(GPBExtensionDescription *description) {
return (description->options & GPBExtensionSetWireFormat) != 0;
}
CF_EXTERN_C_END CF_EXTERN_C_END
...@@ -30,7 +30,7 @@ ...@@ -30,7 +30,7 @@
#import <Foundation/Foundation.h> #import <Foundation/Foundation.h>
#import "GPBTypes.h" #import "GPBRuntimeTypes.h"
// These classes are used for map fields of basic data types. They are used because // These classes are used for map fields of basic data types. They are used because
// they perform better than boxing into NSNumbers in NSDictionaries. // they perform better than boxing into NSNumbers in NSDictionaries.
......
This diff is collapsed.
...@@ -41,7 +41,8 @@ ...@@ -41,7 +41,8 @@
- (size_t)computeSerializedSizeAsField:(GPBFieldDescriptor *)field; - (size_t)computeSerializedSizeAsField:(GPBFieldDescriptor *)field;
- (void)writeToCodedOutputStream:(GPBCodedOutputStream *)outputStream - (void)writeToCodedOutputStream:(GPBCodedOutputStream *)outputStream
asField:(GPBFieldDescriptor *)field; asField:(GPBFieldDescriptor *)field;
- (void)setGPBValue:(GPBValue *)value forGPBValueKey:(GPBValue *)key; - (void)setGPBGenericValue:(GPBGenericValue *)value
forGPBGenericValueKey:(GPBGenericValue *)key;
- (void)enumerateForTextFormat:(void (^)(id keyObj, id valueObj))block; - (void)enumerateForTextFormat:(void (^)(id keyObj, id valueObj))block;
@end @end
...@@ -75,8 +76,8 @@ ...@@ -75,8 +76,8 @@
//% //%
//%PDDM-DEFINE EXTRA_DICTIONARY_PRIVATE_INTERFACES_Enum() //%PDDM-DEFINE EXTRA_DICTIONARY_PRIVATE_INTERFACES_Enum()
//%- (NSData *)serializedDataForUnknownValue:(int32_t)value //%- (NSData *)serializedDataForUnknownValue:(int32_t)value
//% forKey:(GPBValue *)key //% forKey:(GPBGenericValue *)key
//% keyType:(GPBType)keyType; //% keyDataType:(GPBDataType)keyDataType;
//% //%
//%PDDM-EXPAND DICTIONARY_PRIV_INTERFACES_FOR_POD_KEY(UInt32) //%PDDM-EXPAND DICTIONARY_PRIV_INTERFACES_FOR_POD_KEY(UInt32)
...@@ -129,8 +130,8 @@ ...@@ -129,8 +130,8 @@
GPB_UNSAFE_UNRETAINED GPBMessage *_autocreator; GPB_UNSAFE_UNRETAINED GPBMessage *_autocreator;
} }
- (NSData *)serializedDataForUnknownValue:(int32_t)value - (NSData *)serializedDataForUnknownValue:(int32_t)value
forKey:(GPBValue *)key forKey:(GPBGenericValue *)key
keyType:(GPBType)keyType; keyDataType:(GPBDataType)keyDataType;
@end @end
@interface GPBUInt32ObjectDictionary () <GPBDictionaryInternalsProtocol> { @interface GPBUInt32ObjectDictionary () <GPBDictionaryInternalsProtocol> {
...@@ -192,8 +193,8 @@ ...@@ -192,8 +193,8 @@
GPB_UNSAFE_UNRETAINED GPBMessage *_autocreator; GPB_UNSAFE_UNRETAINED GPBMessage *_autocreator;
} }
- (NSData *)serializedDataForUnknownValue:(int32_t)value - (NSData *)serializedDataForUnknownValue:(int32_t)value
forKey:(GPBValue *)key forKey:(GPBGenericValue *)key
keyType:(GPBType)keyType; keyDataType:(GPBDataType)keyDataType;
@end @end
@interface GPBInt32ObjectDictionary () <GPBDictionaryInternalsProtocol> { @interface GPBInt32ObjectDictionary () <GPBDictionaryInternalsProtocol> {
...@@ -255,8 +256,8 @@ ...@@ -255,8 +256,8 @@
GPB_UNSAFE_UNRETAINED GPBMessage *_autocreator; GPB_UNSAFE_UNRETAINED GPBMessage *_autocreator;
} }
- (NSData *)serializedDataForUnknownValue:(int32_t)value - (NSData *)serializedDataForUnknownValue:(int32_t)value
forKey:(GPBValue *)key forKey:(GPBGenericValue *)key
keyType:(GPBType)keyType; keyDataType:(GPBDataType)keyDataType;
@end @end
@interface GPBUInt64ObjectDictionary () <GPBDictionaryInternalsProtocol> { @interface GPBUInt64ObjectDictionary () <GPBDictionaryInternalsProtocol> {
...@@ -318,8 +319,8 @@ ...@@ -318,8 +319,8 @@
GPB_UNSAFE_UNRETAINED GPBMessage *_autocreator; GPB_UNSAFE_UNRETAINED GPBMessage *_autocreator;
} }
- (NSData *)serializedDataForUnknownValue:(int32_t)value - (NSData *)serializedDataForUnknownValue:(int32_t)value
forKey:(GPBValue *)key forKey:(GPBGenericValue *)key
keyType:(GPBType)keyType; keyDataType:(GPBDataType)keyDataType;
@end @end
@interface GPBInt64ObjectDictionary () <GPBDictionaryInternalsProtocol> { @interface GPBInt64ObjectDictionary () <GPBDictionaryInternalsProtocol> {
...@@ -381,8 +382,8 @@ ...@@ -381,8 +382,8 @@
GPB_UNSAFE_UNRETAINED GPBMessage *_autocreator; GPB_UNSAFE_UNRETAINED GPBMessage *_autocreator;
} }
- (NSData *)serializedDataForUnknownValue:(int32_t)value - (NSData *)serializedDataForUnknownValue:(int32_t)value
forKey:(GPBValue *)key forKey:(GPBGenericValue *)key
keyType:(GPBType)keyType; keyDataType:(GPBDataType)keyDataType;
@end @end
@interface GPBBoolObjectDictionary () <GPBDictionaryInternalsProtocol> { @interface GPBBoolObjectDictionary () <GPBDictionaryInternalsProtocol> {
...@@ -444,8 +445,8 @@ ...@@ -444,8 +445,8 @@
GPB_UNSAFE_UNRETAINED GPBMessage *_autocreator; GPB_UNSAFE_UNRETAINED GPBMessage *_autocreator;
} }
- (NSData *)serializedDataForUnknownValue:(int32_t)value - (NSData *)serializedDataForUnknownValue:(int32_t)value
forKey:(GPBValue *)key forKey:(GPBGenericValue *)key
keyType:(GPBType)keyType; keyDataType:(GPBDataType)keyDataType;
@end @end
//%PDDM-EXPAND-END (6 expansions) //%PDDM-EXPAND-END (6 expansions)
......
// 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
...@@ -30,22 +30,21 @@ ...@@ -30,22 +30,21 @@
#import <Foundation/Foundation.h> #import <Foundation/Foundation.h>
#import "GPBWireFormat.h" #import "GPBDescriptor.h"
#import "GPBTypes.h"
@class GPBCodedInputStream; @class GPBCodedInputStream;
@class GPBCodedOutputStream; @class GPBCodedOutputStream;
@class GPBExtensionRegistry; @class GPBExtensionRegistry;
@class GPBDescriptor;
@class GPBExtensionDescriptor;
@interface GPBExtensionField : NSObject<NSCopying> void GPBExtensionMergeFromInputStream(GPBExtensionDescriptor *extension,
BOOL isPackedOnStream,
GPBCodedInputStream *input,
GPBExtensionRegistry *extensionRegistry,
GPBMessage *message);
@property(nonatomic, readonly) int32_t fieldNumber; size_t GPBComputeExtensionSerializedSizeIncludingTag(
@property(nonatomic, readonly) GPBWireFormat wireType; GPBExtensionDescriptor *extension, id value);
@property(nonatomic, readonly) BOOL isRepeated;
@property(nonatomic, readonly) GPBDescriptor *containingType;
@property(nonatomic, readonly) id defaultValue;
@property(nonatomic, readonly) GPBExtensionDescriptor *descriptor;
@end void GPBWriteExtensionValueToOutputStream(GPBExtensionDescriptor *extension,
id value,
GPBCodedOutputStream *output);
...@@ -31,7 +31,7 @@ ...@@ -31,7 +31,7 @@
#import <Foundation/Foundation.h> #import <Foundation/Foundation.h>
@class GPBDescriptor; @class GPBDescriptor;
@class GPBExtensionField; @class GPBExtensionDescriptor;
// A table of known extensions, searchable by name or field number. When // A table of known extensions, searchable by name or field number. When
// parsing a protocol message that might have extensions, you must provide an // parsing a protocol message that might have extensions, you must provide an
...@@ -54,10 +54,10 @@ ...@@ -54,10 +54,10 @@
// //
@interface GPBExtensionRegistry : NSObject<NSCopying> @interface GPBExtensionRegistry : NSObject<NSCopying>
- (void)addExtension:(GPBExtensionField *)extension; - (void)addExtension:(GPBExtensionDescriptor *)extension;
- (void)addExtensions:(GPBExtensionRegistry *)registry; - (void)addExtensions:(GPBExtensionRegistry *)registry;
- (GPBExtensionField *)getExtension:(GPBDescriptor *)containingType - (GPBExtensionDescriptor *)extensionForDescriptor:(GPBDescriptor *)descriptor
fieldNumber:(NSInteger)fieldNumber; fieldNumber:(NSInteger)fieldNumber;
@end @end
...@@ -32,7 +32,6 @@ ...@@ -32,7 +32,6 @@
#import "GPBBootstrap.h" #import "GPBBootstrap.h"
#import "GPBDescriptor.h" #import "GPBDescriptor.h"
#import "GPBExtensionField.h"
@implementation GPBExtensionRegistry { @implementation GPBExtensionRegistry {
// TODO(dmaclach): Reimplement with CFDictionaries that don't use // TODO(dmaclach): Reimplement with CFDictionaries that don't use
...@@ -60,31 +59,34 @@ ...@@ -60,31 +59,34 @@
return result; return result;
} }
- (NSMutableDictionary *)extensionMapForContainingType: - (NSMutableDictionary *)extensionMapForContainingMessageClass:
(GPBDescriptor *)containingType { (Class)containingMessageClass {
NSMutableDictionary *extensionMap = NSMutableDictionary *extensionMap =
[mutableClassMap_ objectForKey:containingType]; [mutableClassMap_ objectForKey:containingMessageClass];
if (extensionMap == nil) { if (extensionMap == nil) {
extensionMap = [NSMutableDictionary dictionary]; extensionMap = [NSMutableDictionary dictionary];
[mutableClassMap_ setObject:extensionMap forKey:containingType]; [mutableClassMap_ setObject:extensionMap
forKey:(id<NSCopying>)containingMessageClass];
} }
return extensionMap; return extensionMap;
} }
- (void)addExtension:(GPBExtensionField *)extension { - (void)addExtension:(GPBExtensionDescriptor *)extension {
if (extension == nil) { if (extension == nil) {
return; return;
} }
GPBDescriptor *containingType = [extension containingType]; Class containingMessageClass = extension.containingMessageClass;
NSMutableDictionary *extensionMap = NSMutableDictionary *extensionMap =
[self extensionMapForContainingType:containingType]; [self extensionMapForContainingMessageClass:containingMessageClass];
[extensionMap setObject:extension forKey:@([extension fieldNumber])]; [extensionMap setObject:extension forKey:@(extension.fieldNumber)];
} }
- (GPBExtensionField *)getExtension:(GPBDescriptor *)containingType - (GPBExtensionDescriptor *)extensionForDescriptor:(GPBDescriptor *)descriptor
fieldNumber:(NSInteger)fieldNumber { fieldNumber:(NSInteger)fieldNumber {
NSDictionary *extensionMap = [mutableClassMap_ objectForKey:containingType]; Class messageClass = descriptor.messageClass;
NSDictionary *extensionMap =
[mutableClassMap_ objectForKey:messageClass];
return [extensionMap objectForKey:@(fieldNumber)]; return [extensionMap objectForKey:@(fieldNumber)];
} }
...@@ -94,11 +96,11 @@ ...@@ -94,11 +96,11 @@
return; return;
} }
NSMutableDictionary *otherClassMap = registry->mutableClassMap_; NSMutableDictionary *otherClassMap = registry->mutableClassMap_;
for (GPBDescriptor *containingType in otherClassMap) { for (Class containingMessageClass in otherClassMap) {
NSMutableDictionary *extensionMap = NSMutableDictionary *extensionMap =
[self extensionMapForContainingType:containingType]; [self extensionMapForContainingMessageClass:containingMessageClass];
NSMutableDictionary *otherExtensionMap = NSMutableDictionary *otherExtensionMap =
[registry extensionMapForContainingType:containingType]; [registry extensionMapForContainingMessageClass:containingMessageClass];
[extensionMap addEntriesFromDictionary:otherExtensionMap]; [extensionMap addEntriesFromDictionary:otherExtensionMap];
} }
} }
......
...@@ -35,7 +35,7 @@ ...@@ -35,7 +35,7 @@
@class GPBDescriptor; @class GPBDescriptor;
@class GPBCodedInputStream; @class GPBCodedInputStream;
@class GPBCodedOutputStream; @class GPBCodedOutputStream;
@class GPBExtensionField; @class GPBExtensionDescriptor;
@class GPBExtensionRegistry; @class GPBExtensionRegistry;
@class GPBFieldDescriptor; @class GPBFieldDescriptor;
@class GPBUnknownFieldSet; @class GPBUnknownFieldSet;
...@@ -148,14 +148,14 @@ CF_EXTERN_C_END ...@@ -148,14 +148,14 @@ CF_EXTERN_C_END
// Extensions use boxed values (NSNumbers) for PODs, NSMutableArrays for // Extensions use boxed values (NSNumbers) for PODs, NSMutableArrays for
// repeated. If the extension is a Message one will be auto created for you // repeated. If the extension is a Message one will be auto created for you
// and returned similar to fields. // and returned similar to fields.
- (BOOL)hasExtension:(GPBExtensionField *)extension; - (BOOL)hasExtension:(GPBExtensionDescriptor *)extension;
- (id)getExtension:(GPBExtensionField *)extension; - (id)getExtension:(GPBExtensionDescriptor *)extension;
- (void)setExtension:(GPBExtensionField *)extension value:(id)value; - (void)setExtension:(GPBExtensionDescriptor *)extension value:(id)value;
- (void)addExtension:(GPBExtensionField *)extension value:(id)value; - (void)addExtension:(GPBExtensionDescriptor *)extension value:(id)value;
- (void)setExtension:(GPBExtensionField *)extension - (void)setExtension:(GPBExtensionDescriptor *)extension
index:(NSUInteger)index index:(NSUInteger)index
value:(id)value; value:(id)value;
- (void)clearExtension:(GPBExtensionField *)extension; - (void)clearExtension:(GPBExtensionDescriptor *)extension;
- (void)setUnknownFields:(GPBUnknownFieldSet *)unknownFields; - (void)setUnknownFields:(GPBUnknownFieldSet *)unknownFields;
......
This diff is collapsed.
...@@ -67,9 +67,9 @@ typedef struct GPBMessage_Storage *GPBMessage_StoragePtr; ...@@ -67,9 +67,9 @@ typedef struct GPBMessage_Storage *GPBMessage_StoragePtr;
// Gets an extension value without autocreating the result if not found. (i.e. // Gets an extension value without autocreating the result if not found. (i.e.
// returns nil if the extension is not set) // returns nil if the extension is not set)
- (id)getExistingExtension:(GPBExtensionField *)extension; - (id)getExistingExtension:(GPBExtensionDescriptor *)extension;
// Returns an array of GPBExtensionField* for all the extensions currently // Returns an array of GPBExtensionDescriptor* for all the extensions currently
// in use on the message. They are sorted by field number. // in use on the message. They are sorted by field number.
- (NSArray *)sortedExtensionsInUse; - (NSArray *)sortedExtensionsInUse;
......
...@@ -35,11 +35,10 @@ ...@@ -35,11 +35,10 @@
#import "GPBCodedOutputStream.h" #import "GPBCodedOutputStream.h"
#import "GPBDescriptor.h" #import "GPBDescriptor.h"
#import "GPBDictionary.h" #import "GPBDictionary.h"
#import "GPBExtensionField.h"
#import "GPBExtensionRegistry.h" #import "GPBExtensionRegistry.h"
#import "GPBField.h"
#import "GPBMessage.h" #import "GPBMessage.h"
#import "GPBRootObject.h" #import "GPBRootObject.h"
#import "GPBUnknownField.h"
#import "GPBUnknownFieldSet.h" #import "GPBUnknownFieldSet.h"
#import "GPBUtilities.h" #import "GPBUtilities.h"
#import "GPBWireFormat.h" #import "GPBWireFormat.h"
...@@ -36,14 +36,27 @@ ...@@ -36,14 +36,27 @@
#import "GPBCodedOutputStream.m" #import "GPBCodedOutputStream.m"
#import "GPBDescriptor.m" #import "GPBDescriptor.m"
#import "GPBDictionary.m" #import "GPBDictionary.m"
#import "GPBExtensionField.m" #import "GPBExtensionInternals.m"
#import "GPBExtensionRegistry.m" #import "GPBExtensionRegistry.m"
#import "GPBField.m"
#import "GPBMessage.m" #import "GPBMessage.m"
#import "GPBRootObject.m" #import "GPBRootObject.m"
#import "GPBUnknownField.m"
#import "GPBUnknownFieldSet.m" #import "GPBUnknownFieldSet.m"
#import "GPBUtilities.m" #import "GPBUtilities.m"
#import "GPBWellKnownTypes.m" #import "GPBWellKnownTypes.m"
#import "GPBWireFormat.m" #import "GPBWireFormat.m"
#import "google/protobuf/Descriptor.pbobjc.m" #import "google/protobuf/Descriptor.pbobjc.m"
// Duration and Timestamp are #imported into GPBWellKnownTypes.m to the
// Objective C categories added will always be linked in with the classes.
#import "google/protobuf/Any.pbobjc.m"
#import "google/protobuf/Api.pbobjc.m"
// #import "google/protobuf/Duration.pbobjc.m"
#import "google/protobuf/Empty.pbobjc.m"
#import "google/protobuf/FieldMask.pbobjc.m"
#import "google/protobuf/SourceContext.pbobjc.m"
#import "google/protobuf/Struct.pbobjc.m"
// #import "google/protobuf/Timestamp.pbobjc.m"
#import "google/protobuf/Type.pbobjc.m"
#import "google/protobuf/Wrappers.pbobjc.m"
...@@ -34,8 +34,7 @@ ...@@ -34,8 +34,7 @@
#import "GPBProtocolBuffers.h" #import "GPBProtocolBuffers.h"
#import "GPBDescriptor_PackagePrivate.h" #import "GPBDescriptor_PackagePrivate.h"
#import "GPBExtensionField_PackagePrivate.h" #import "GPBExtensionInternals.h"
#import "GPBExtensionRegistry.h"
#import "GPBMessage_PackagePrivate.h" #import "GPBMessage_PackagePrivate.h"
#import "GPBRootObject_PackagePrivate.h" #import "GPBRootObject_PackagePrivate.h"
#import "GPBUtilities_PackagePrivate.h" #import "GPBUtilities_PackagePrivate.h"
...@@ -36,7 +36,6 @@ ...@@ -36,7 +36,6 @@
#import <CoreFoundation/CoreFoundation.h> #import <CoreFoundation/CoreFoundation.h>
#import "GPBDescriptor.h" #import "GPBDescriptor.h"
#import "GPBExtensionField.h"
#import "GPBUtilities_PackagePrivate.h" #import "GPBUtilities_PackagePrivate.h"
@interface GPBExtensionDescriptor (GPBRootObject) @interface GPBExtensionDescriptor (GPBRootObject)
...@@ -130,14 +129,14 @@ static CFMutableDictionaryRef gExtensionSingletonDictionary = NULL; ...@@ -130,14 +129,14 @@ static CFMutableDictionaryRef gExtensionSingletonDictionary = NULL;
return nil; return nil;
} }
+ (void)globallyRegisterExtension:(GPBExtensionField *)field { + (void)globallyRegisterExtension:(GPBExtensionDescriptor *)field {
const char *key = [field.descriptor singletonNameC]; const char *key = [field singletonNameC];
OSSpinLockLock(&gExtensionSingletonDictionaryLock_); OSSpinLockLock(&gExtensionSingletonDictionaryLock_);
CFDictionarySetValue(gExtensionSingletonDictionary, key, field); CFDictionarySetValue(gExtensionSingletonDictionary, key, field);
OSSpinLockUnlock(&gExtensionSingletonDictionaryLock_); OSSpinLockUnlock(&gExtensionSingletonDictionaryLock_);
} }
GPB_INLINE id ExtensionForName(id self, SEL _cmd) { static id ExtensionForName(id self, SEL _cmd) {
// Really fast way of doing "classname_selName". // Really fast way of doing "classname_selName".
// This came up as a hotspot (creation of NSString *) when accessing a // This came up as a hotspot (creation of NSString *) when accessing a
// lot of extensions. // lot of extensions.
......
...@@ -32,12 +32,12 @@ ...@@ -32,12 +32,12 @@
#import "GPBRootObject.h" #import "GPBRootObject.h"
@class GPBExtensionField; @class GPBExtensionDescriptor;
@interface GPBRootObject () @interface GPBRootObject ()
// Globally register. // Globally register.
+ (void)globallyRegisterExtension:(GPBExtensionField *)field; + (void)globallyRegisterExtension:(GPBExtensionDescriptor *)field;
@end @end
......
...@@ -63,36 +63,36 @@ typedef union { ...@@ -63,36 +63,36 @@ typedef union {
GPB_UNSAFE_UNRETAINED NSString *valueString; GPB_UNSAFE_UNRETAINED NSString *valueString;
GPB_UNSAFE_UNRETAINED GPBMessage *valueMessage; GPB_UNSAFE_UNRETAINED GPBMessage *valueMessage;
int32_t valueEnum; int32_t valueEnum;
} GPBValue; } GPBGenericValue;
// Do not change the order of this enum (or add things to it) without thinking // 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. // about it very carefully. There are several things that depend on the order.
typedef enum { typedef enum {
GPBTypeBool = 0, GPBDataTypeBool = 0,
GPBTypeFixed32, GPBDataTypeFixed32,
GPBTypeSFixed32, GPBDataTypeSFixed32,
GPBTypeFloat, GPBDataTypeFloat,
GPBTypeFixed64, GPBDataTypeFixed64,
GPBTypeSFixed64, GPBDataTypeSFixed64,
GPBTypeDouble, GPBDataTypeDouble,
GPBTypeInt32, GPBDataTypeInt32,
GPBTypeInt64, GPBDataTypeInt64,
GPBTypeSInt32, GPBDataTypeSInt32,
GPBTypeSInt64, GPBDataTypeSInt64,
GPBTypeUInt32, GPBDataTypeUInt32,
GPBTypeUInt64, GPBDataTypeUInt64,
GPBTypeData, // Maps to Bytes Protobuf type GPBDataTypeBytes,
GPBTypeString, GPBDataTypeString,
GPBTypeMessage, GPBDataTypeMessage,
GPBTypeGroup, GPBDataTypeGroup,
GPBTypeEnum, GPBDataTypeEnum,
} GPBType; } GPBDataType;
enum { enum {
// A count of the number of types in GPBType. Separated out from the GPBType // A count of the number of types in GPBDataType. Separated out from the
// enum to avoid warnings regarding not handling GPBTypeCount in switch // GPBDataType enum to avoid warnings regarding not handling
// statements. // GPBDataType_Count in switch statements.
GPBTypeCount = GPBTypeEnum + 1 GPBDataType_Count = GPBDataTypeEnum + 1
}; };
// An extension range. // An extension range.
......
...@@ -35,7 +35,7 @@ ...@@ -35,7 +35,7 @@
@class GPBUInt64Array; @class GPBUInt64Array;
@class GPBUnknownFieldSet; @class GPBUnknownFieldSet;
@interface GPBField : NSObject<NSCopying> @interface GPBUnknownField : NSObject<NSCopying>
@property(nonatomic, readonly, assign) int32_t number; @property(nonatomic, readonly, assign) int32_t number;
...@@ -43,8 +43,8 @@ ...@@ -43,8 +43,8 @@
@property(nonatomic, readonly, strong) GPBUInt64Array *varintList; @property(nonatomic, readonly, strong) GPBUInt64Array *varintList;
@property(nonatomic, readonly, strong) GPBUInt32Array *fixed32List; @property(nonatomic, readonly, strong) GPBUInt32Array *fixed32List;
@property(nonatomic, readonly, strong) GPBUInt64Array *fixed64List; @property(nonatomic, readonly, strong) GPBUInt64Array *fixed64List;
@property(nonatomic, readonly, strong) NSArray *lengthDelimitedList; @property(nonatomic, readonly, strong) NSArray *lengthDelimitedList; // NSData
@property(nonatomic, readonly, strong) NSArray *groupList; @property(nonatomic, readonly, strong) NSArray *groupList; // GPBUnknownFieldSet
// Only one of these should be used per Field. // Only one of these should be used per Field.
- (void)addVarint:(uint64_t)value; - (void)addVarint:(uint64_t)value;
......
...@@ -28,12 +28,12 @@ ...@@ -28,12 +28,12 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#import "GPBField_PackagePrivate.h" #import "GPBUnknownField_PackagePrivate.h"
#import "GPBArray.h" #import "GPBArray.h"
#import "GPBCodedOutputStream.h" #import "GPBCodedOutputStream.h"
@interface GPBField () { @implementation GPBUnknownField {
@protected @protected
int32_t number_; int32_t number_;
GPBUInt64Array *mutableVarintList_; GPBUInt64Array *mutableVarintList_;
...@@ -42,9 +42,6 @@ ...@@ -42,9 +42,6 @@
NSMutableArray *mutableLengthDelimitedList_; NSMutableArray *mutableLengthDelimitedList_;
NSMutableArray *mutableGroupList_; NSMutableArray *mutableGroupList_;
} }
@end
@implementation GPBField
@synthesize number = number_; @synthesize number = number_;
@synthesize varintList = mutableVarintList_; @synthesize varintList = mutableVarintList_;
...@@ -71,7 +68,8 @@ ...@@ -71,7 +68,8 @@
} }
- (id)copyWithZone:(NSZone *)zone { - (id)copyWithZone:(NSZone *)zone {
GPBField *result = [[GPBField allocWithZone:zone] initWithNumber:number_]; GPBUnknownField *result =
[[GPBUnknownField allocWithZone:zone] initWithNumber:number_];
result->mutableFixed32List_ = [mutableFixed32List_ copyWithZone:zone]; result->mutableFixed32List_ = [mutableFixed32List_ copyWithZone:zone];
result->mutableFixed64List_ = [mutableFixed64List_ copyWithZone:zone]; result->mutableFixed64List_ = [mutableFixed64List_ copyWithZone:zone];
result->mutableLengthDelimitedList_ = result->mutableLengthDelimitedList_ =
...@@ -91,8 +89,8 @@ ...@@ -91,8 +89,8 @@
- (BOOL)isEqual:(id)object { - (BOOL)isEqual:(id)object {
if (self == object) return YES; if (self == object) return YES;
if (![object isKindOfClass:[GPBField class]]) return NO; if (![object isKindOfClass:[GPBUnknownField class]]) return NO;
GPBField *field = (GPBField *)object; GPBUnknownField *field = (GPBUnknownField *)object;
BOOL equalVarint = BOOL equalVarint =
(mutableVarintList_.count == 0 && field->mutableVarintList_.count == 0) || (mutableVarintList_.count == 0 && field->mutableVarintList_.count == 0) ||
[mutableVarintList_ isEqual:field->mutableVarintList_]; [mutableVarintList_ isEqual:field->mutableVarintList_];
...@@ -131,23 +129,23 @@ ...@@ -131,23 +129,23 @@
- (void)writeToOutput:(GPBCodedOutputStream *)output { - (void)writeToOutput:(GPBCodedOutputStream *)output {
NSUInteger count = mutableVarintList_.count; NSUInteger count = mutableVarintList_.count;
if (count > 0) { if (count > 0) {
[output writeUInt64s:number_ values:mutableVarintList_ tag:0]; [output writeUInt64Array:number_ values:mutableVarintList_ tag:0];
} }
count = mutableFixed32List_.count; count = mutableFixed32List_.count;
if (count > 0) { if (count > 0) {
[output writeFixed32s:number_ values:mutableFixed32List_ tag:0]; [output writeFixed32Array:number_ values:mutableFixed32List_ tag:0];
} }
count = mutableFixed64List_.count; count = mutableFixed64List_.count;
if (count > 0) { if (count > 0) {
[output writeFixed64s:number_ values:mutableFixed64List_ tag:0]; [output writeFixed64Array:number_ values:mutableFixed64List_ tag:0];
} }
count = mutableLengthDelimitedList_.count; count = mutableLengthDelimitedList_.count;
if (count > 0) { if (count > 0) {
[output writeDatas:number_ values:mutableLengthDelimitedList_]; [output writeBytesArray:number_ values:mutableLengthDelimitedList_];
} }
count = mutableGroupList_.count; count = mutableGroupList_.count;
if (count > 0) { if (count > 0) {
[output writeUnknownGroups:number_ values:mutableGroupList_]; [output writeUnknownGroupArray:number_ values:mutableGroupList_];
} }
} }
...@@ -173,7 +171,7 @@ ...@@ -173,7 +171,7 @@
}]; }];
for (NSData *data in mutableLengthDelimitedList_) { for (NSData *data in mutableLengthDelimitedList_) {
result += GPBComputeDataSize(number, data); result += GPBComputeBytesSize(number, data);
} }
for (GPBUnknownFieldSet *set in mutableGroupList_) { for (GPBUnknownFieldSet *set in mutableGroupList_) {
...@@ -229,7 +227,7 @@ ...@@ -229,7 +227,7 @@
return description; return description;
} }
- (void)mergeFromField:(GPBField *)other { - (void)mergeFromField:(GPBUnknownField *)other {
GPBUInt64Array *otherVarintList = other.varintList; GPBUInt64Array *otherVarintList = other.varintList;
if (otherVarintList.count > 0) { if (otherVarintList.count > 0) {
if (mutableVarintList_ == nil) { if (mutableVarintList_ == nil) {
......
...@@ -30,15 +30,15 @@ ...@@ -30,15 +30,15 @@
#import <Foundation/Foundation.h> #import <Foundation/Foundation.h>
@class GPBField; @class GPBUnknownField;
@interface GPBUnknownFieldSet : NSObject<NSCopying> @interface GPBUnknownFieldSet : NSObject<NSCopying>
- (BOOL)hasField:(int32_t)number; - (BOOL)hasField:(int32_t)number;
- (GPBField *)getField:(int32_t)number; - (GPBUnknownField *)getField:(int32_t)number;
- (NSUInteger)countOfFields; - (NSUInteger)countOfFields;
- (void)addField:(GPBField *)field; - (void)addField:(GPBUnknownField *)field;
// Returns an NSArray of the GPBFields sorted by the field numbers. // Returns an NSArray of the GPBFields sorted by the field numbers.
- (NSArray *)sortedFields; - (NSArray *)sortedFields;
......
...@@ -32,7 +32,7 @@ ...@@ -32,7 +32,7 @@
#import "GPBCodedInputStream_PackagePrivate.h" #import "GPBCodedInputStream_PackagePrivate.h"
#import "GPBCodedOutputStream.h" #import "GPBCodedOutputStream.h"
#import "GPBField_PackagePrivate.h" #import "GPBUnknownField_PackagePrivate.h"
#import "GPBUtilities.h" #import "GPBUtilities.h"
#import "GPBWireFormat.h" #import "GPBWireFormat.h"
...@@ -85,10 +85,10 @@ static void checkNumber(int32_t number) { ...@@ -85,10 +85,10 @@ static void checkNumber(int32_t number) {
static void CopyWorker(const void *key, const void *value, void *context) { static void CopyWorker(const void *key, const void *value, void *context) {
#pragma unused(key) #pragma unused(key)
GPBField *field = value; GPBUnknownField *field = value;
GPBUnknownFieldSet *result = context; GPBUnknownFieldSet *result = context;
GPBField *copied = [field copy]; GPBUnknownField *copied = [field copy];
[result addField:copied]; [result addField:copied];
[copied release]; [copied release];
} }
...@@ -136,9 +136,10 @@ static void CopyWorker(const void *key, const void *value, void *context) { ...@@ -136,9 +136,10 @@ static void CopyWorker(const void *key, const void *value, void *context) {
return fields_ ? (CFDictionaryGetValue(fields_, (void *)key) != nil) : NO; return fields_ ? (CFDictionaryGetValue(fields_, (void *)key) != nil) : NO;
} }
- (GPBField *)getField:(int32_t)number { - (GPBUnknownField *)getField:(int32_t)number {
ssize_t key = number; ssize_t key = number;
GPBField *result = fields_ ? CFDictionaryGetValue(fields_, (void *)key) : nil; GPBUnknownField *result =
fields_ ? CFDictionaryGetValue(fields_, (void *)key) : nil;
return result; return result;
} }
...@@ -150,12 +151,12 @@ static void CopyWorker(const void *key, const void *value, void *context) { ...@@ -150,12 +151,12 @@ static void CopyWorker(const void *key, const void *value, void *context) {
if (!fields_) return nil; if (!fields_) return nil;
size_t count = CFDictionaryGetCount(fields_); size_t count = CFDictionaryGetCount(fields_);
ssize_t keys[count]; ssize_t keys[count];
GPBField *values[count]; GPBUnknownField *values[count];
CFDictionaryGetKeysAndValues(fields_, (const void **)keys, CFDictionaryGetKeysAndValues(fields_, (const void **)keys,
(const void **)values); (const void **)values);
struct GPBFieldPair { struct GPBFieldPair {
ssize_t key; ssize_t key;
GPBField *value; GPBUnknownField *value;
} pairs[count]; } pairs[count];
for (size_t i = 0; i < count; ++i) { for (size_t i = 0; i < count; ++i) {
pairs[i].key = keys[i]; pairs[i].key = keys[i];
...@@ -179,13 +180,13 @@ static void CopyWorker(const void *key, const void *value, void *context) { ...@@ -179,13 +180,13 @@ static void CopyWorker(const void *key, const void *value, void *context) {
if (!fields_) return; if (!fields_) return;
size_t count = CFDictionaryGetCount(fields_); size_t count = CFDictionaryGetCount(fields_);
ssize_t keys[count]; ssize_t keys[count];
GPBField *values[count]; GPBUnknownField *values[count];
CFDictionaryGetKeysAndValues(fields_, (const void **)keys, CFDictionaryGetKeysAndValues(fields_, (const void **)keys,
(const void **)values); (const void **)values);
if (count > 1) { if (count > 1) {
struct GPBFieldPair { struct GPBFieldPair {
ssize_t key; ssize_t key;
GPBField *value; GPBUnknownField *value;
} pairs[count]; } pairs[count];
for (size_t i = 0; i < count; ++i) { for (size_t i = 0; i < count; ++i) {
...@@ -199,7 +200,7 @@ static void CopyWorker(const void *key, const void *value, void *context) { ...@@ -199,7 +200,7 @@ static void CopyWorker(const void *key, const void *value, void *context) {
return (a->key > b->key) ? 1 : ((a->key == b->key) ? 0 : -1); return (a->key > b->key) ? 1 : ((a->key == b->key) ? 0 : -1);
}); });
for (size_t i = 0; i < count; ++i) { for (size_t i = 0; i < count; ++i) {
GPBField *value = pairs[i].value; GPBUnknownField *value = pairs[i].value;
[value writeToOutput:output]; [value writeToOutput:output];
} }
} else { } else {
...@@ -219,7 +220,7 @@ static void CopyWorker(const void *key, const void *value, void *context) { ...@@ -219,7 +220,7 @@ static void CopyWorker(const void *key, const void *value, void *context) {
static void GPBUnknownFieldSetSerializedSize(const void *key, const void *value, static void GPBUnknownFieldSetSerializedSize(const void *key, const void *value,
void *context) { void *context) {
#pragma unused(key) #pragma unused(key)
GPBField *field = value; GPBUnknownField *field = value;
size_t *result = context; size_t *result = context;
*result += [field serializedSize]; *result += [field serializedSize];
} }
...@@ -237,7 +238,7 @@ static void GPBUnknownFieldSetWriteAsMessageSetTo(const void *key, ...@@ -237,7 +238,7 @@ static void GPBUnknownFieldSetWriteAsMessageSetTo(const void *key,
const void *value, const void *value,
void *context) { void *context) {
#pragma unused(key) #pragma unused(key)
GPBField *field = value; GPBUnknownField *field = value;
GPBCodedOutputStream *output = context; GPBCodedOutputStream *output = context;
[field writeAsMessageSetExtensionToOutput:output]; [field writeAsMessageSetExtensionToOutput:output];
} }
...@@ -253,7 +254,7 @@ static void GPBUnknownFieldSetSerializedSizeAsMessageSet(const void *key, ...@@ -253,7 +254,7 @@ static void GPBUnknownFieldSetSerializedSizeAsMessageSet(const void *key,
const void *value, const void *value,
void *context) { void *context) {
#pragma unused(key) #pragma unused(key)
GPBField *field = value; GPBUnknownField *field = value;
size_t *result = context; size_t *result = context;
*result += [field serializedSizeAsMessageSetExtension]; *result += [field serializedSizeAsMessageSetExtension];
} }
...@@ -280,7 +281,7 @@ static void GPBUnknownFieldSetSerializedSizeAsMessageSet(const void *key, ...@@ -280,7 +281,7 @@ static void GPBUnknownFieldSetSerializedSizeAsMessageSet(const void *key,
return GPBWireFormatGetTagWireType(tag) != GPBWireFormatEndGroup; return GPBWireFormatGetTagWireType(tag) != GPBWireFormatEndGroup;
} }
- (void)addField:(GPBField *)field { - (void)addField:(GPBUnknownField *)field {
int32_t number = [field number]; int32_t number = [field number];
checkNumber(number); checkNumber(number);
if (!fields_) { if (!fields_) {
...@@ -297,12 +298,12 @@ static void GPBUnknownFieldSetSerializedSizeAsMessageSet(const void *key, ...@@ -297,12 +298,12 @@ static void GPBUnknownFieldSetSerializedSizeAsMessageSet(const void *key,
CFDictionarySetValue(fields_, (const void *)key, field); CFDictionarySetValue(fields_, (const void *)key, field);
} }
- (GPBField *)mutableFieldForNumber:(int32_t)number create:(BOOL)create { - (GPBUnknownField *)mutableFieldForNumber:(int32_t)number create:(BOOL)create {
ssize_t key = number; ssize_t key = number;
GPBField *existing = GPBUnknownField *existing =
fields_ ? CFDictionaryGetValue(fields_, (const void *)key) : nil; fields_ ? CFDictionaryGetValue(fields_, (const void *)key) : nil;
if (!existing && create) { if (!existing && create) {
existing = [[GPBField alloc] initWithNumber:number]; existing = [[GPBUnknownField alloc] initWithNumber:number];
// This retains existing. // This retains existing.
[self addField:existing]; [self addField:existing];
[existing release]; [existing release];
...@@ -314,19 +315,19 @@ static void GPBUnknownFieldSetMergeUnknownFields(const void *key, ...@@ -314,19 +315,19 @@ static void GPBUnknownFieldSetMergeUnknownFields(const void *key,
const void *value, const void *value,
void *context) { void *context) {
#pragma unused(key) #pragma unused(key)
GPBField *field = value; GPBUnknownField *field = value;
GPBUnknownFieldSet *self = context; GPBUnknownFieldSet *self = context;
int32_t number = [field number]; int32_t number = [field number];
checkNumber(number); checkNumber(number);
GPBField *oldField = [self mutableFieldForNumber:number create:NO]; GPBUnknownField *oldField = [self mutableFieldForNumber:number create:NO];
if (oldField) { if (oldField) {
[oldField mergeFromField:field]; [oldField mergeFromField:field];
} else { } else {
// Merge only comes from GPBMessage's mergeFrom:, so it means we are on // 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 message and are an mutable instance, so make sure we need
// mutable fields. // mutable fields.
GPBField *fieldCopy = [field copy]; GPBUnknownField *fieldCopy = [field copy];
[self addField:fieldCopy]; [self addField:fieldCopy];
[fieldCopy release]; [fieldCopy release];
} }
...@@ -356,18 +357,18 @@ static void GPBUnknownFieldSetMergeUnknownFields(const void *key, ...@@ -356,18 +357,18 @@ static void GPBUnknownFieldSetMergeUnknownFields(const void *key,
GPBCodedInputStreamState *state = &input->state_; GPBCodedInputStreamState *state = &input->state_;
switch (GPBWireFormatGetTagWireType(tag)) { switch (GPBWireFormatGetTagWireType(tag)) {
case GPBWireFormatVarint: { case GPBWireFormatVarint: {
GPBField *field = [self mutableFieldForNumber:number create:YES]; GPBUnknownField *field = [self mutableFieldForNumber:number create:YES];
[field addVarint:GPBCodedInputStreamReadInt64(state)]; [field addVarint:GPBCodedInputStreamReadInt64(state)];
return YES; return YES;
} }
case GPBWireFormatFixed64: { case GPBWireFormatFixed64: {
GPBField *field = [self mutableFieldForNumber:number create:YES]; GPBUnknownField *field = [self mutableFieldForNumber:number create:YES];
[field addFixed64:GPBCodedInputStreamReadFixed64(state)]; [field addFixed64:GPBCodedInputStreamReadFixed64(state)];
return YES; return YES;
} }
case GPBWireFormatLengthDelimited: { case GPBWireFormatLengthDelimited: {
NSData *data = GPBCodedInputStreamReadRetainedData(state); NSData *data = GPBCodedInputStreamReadRetainedBytes(state);
GPBField *field = [self mutableFieldForNumber:number create:YES]; GPBUnknownField *field = [self mutableFieldForNumber:number create:YES];
[field addLengthDelimited:data]; [field addLengthDelimited:data];
[data release]; [data release];
return YES; return YES;
...@@ -375,7 +376,7 @@ static void GPBUnknownFieldSetMergeUnknownFields(const void *key, ...@@ -375,7 +376,7 @@ static void GPBUnknownFieldSetMergeUnknownFields(const void *key,
case GPBWireFormatStartGroup: { case GPBWireFormatStartGroup: {
GPBUnknownFieldSet *unknownFieldSet = [[GPBUnknownFieldSet alloc] init]; GPBUnknownFieldSet *unknownFieldSet = [[GPBUnknownFieldSet alloc] init];
[input readUnknownGroup:number message:unknownFieldSet]; [input readUnknownGroup:number message:unknownFieldSet];
GPBField *field = [self mutableFieldForNumber:number create:YES]; GPBUnknownField *field = [self mutableFieldForNumber:number create:YES];
[field addGroup:unknownFieldSet]; [field addGroup:unknownFieldSet];
[unknownFieldSet release]; [unknownFieldSet release];
return YES; return YES;
...@@ -383,7 +384,7 @@ static void GPBUnknownFieldSetMergeUnknownFields(const void *key, ...@@ -383,7 +384,7 @@ static void GPBUnknownFieldSetMergeUnknownFields(const void *key,
case GPBWireFormatEndGroup: case GPBWireFormatEndGroup:
return NO; return NO;
case GPBWireFormatFixed32: { case GPBWireFormatFixed32: {
GPBField *field = [self mutableFieldForNumber:number create:YES]; GPBUnknownField *field = [self mutableFieldForNumber:number create:YES];
[field addFixed32:GPBCodedInputStreamReadFixed32(state)]; [field addFixed32:GPBCodedInputStreamReadFixed32(state)];
return YES; return YES;
} }
...@@ -396,7 +397,7 @@ static void GPBUnknownFieldSetMergeUnknownFields(const void *key, ...@@ -396,7 +397,7 @@ static void GPBUnknownFieldSetMergeUnknownFields(const void *key,
} }
- (void)addUnknownMapEntry:(int32_t)fieldNum value:(NSData *)data { - (void)addUnknownMapEntry:(int32_t)fieldNum value:(NSData *)data {
GPBField *field = [self mutableFieldForNumber:fieldNum create:YES]; GPBUnknownField *field = [self mutableFieldForNumber:fieldNum create:YES];
[field addLengthDelimited:data]; [field addLengthDelimited:data];
} }
......
...@@ -30,11 +30,11 @@ ...@@ -30,11 +30,11 @@
#import <Foundation/Foundation.h> #import <Foundation/Foundation.h>
#import "GPBField.h" #import "GPBUnknownField.h"
@class GPBCodedOutputStream; @class GPBCodedOutputStream;
@interface GPBField () @interface GPBUnknownField ()
- (instancetype)initWithNumber:(int32_t)number; - (instancetype)initWithNumber:(int32_t)number;
...@@ -44,6 +44,6 @@ ...@@ -44,6 +44,6 @@
- (void)writeAsMessageSetExtensionToOutput:(GPBCodedOutputStream *)output; - (void)writeAsMessageSetExtensionToOutput:(GPBCodedOutputStream *)output;
- (size_t)serializedSizeAsMessageSetExtension; - (size_t)serializedSizeAsMessageSetExtension;
- (void)mergeFromField:(GPBField *)other; - (void)mergeFromField:(GPBUnknownField *)other;
@end @end
This diff is collapsed.
This diff is collapsed.
...@@ -48,6 +48,15 @@ ...@@ -48,6 +48,15 @@
CF_EXTERN_C_BEGIN CF_EXTERN_C_BEGIN
// These two are used to inject a runtime check for version mismatch into the
// generated sources to make sure they are linked with a supporting runtime.
void GPBCheckRuntimeVersionInternal(int32_t version);
GPB_INLINE void GPBDebugCheckRuntimeVersion() {
#if DEBUG
GPBCheckRuntimeVersionInternal(GOOGLE_PROTOBUF_OBJC_GEN_VERSION);
#endif
}
// Conversion functions for de/serializing floating point types. // Conversion functions for de/serializing floating point types.
GPB_INLINE int64_t GPBConvertDoubleToInt64(double v) { GPB_INLINE int64_t GPBConvertDoubleToInt64(double v) {
...@@ -116,40 +125,38 @@ GPB_INLINE uint64_t GPBEncodeZigZag64(int64_t n) { ...@@ -116,40 +125,38 @@ GPB_INLINE uint64_t GPBEncodeZigZag64(int64_t n) {
return (n << 1) ^ (n >> 63); return (n << 1) ^ (n >> 63);
} }
GPB_INLINE BOOL GPBTypeIsObject(GPBType type) { GPB_INLINE BOOL GPBDataTypeIsObject(GPBDataType type) {
switch (type) { switch (type) {
case GPBTypeData: case GPBDataTypeBytes:
case GPBTypeString: case GPBDataTypeString:
case GPBTypeMessage: case GPBDataTypeMessage:
case GPBTypeGroup: case GPBDataTypeGroup:
return YES; return YES;
default: default:
return NO; return NO;
} }
} }
GPB_INLINE BOOL GPBTypeIsMessage(GPBType type) { GPB_INLINE BOOL GPBDataTypeIsMessage(GPBDataType type) {
switch (type) { switch (type) {
case GPBTypeMessage: case GPBDataTypeMessage:
case GPBTypeGroup: case GPBDataTypeGroup:
return YES; return YES;
default: default:
return NO; return NO;
} }
} }
GPB_INLINE BOOL GPBTypeIsEnum(GPBType type) { return type == GPBTypeEnum; } GPB_INLINE BOOL GPBFieldDataTypeIsMessage(GPBFieldDescriptor *field) {
return GPBDataTypeIsMessage(field->description_->dataType);
GPB_INLINE BOOL GPBFieldTypeIsMessage(GPBFieldDescriptor *field) {
return GPBTypeIsMessage(field->description_->type);
} }
GPB_INLINE BOOL GPBFieldTypeIsObject(GPBFieldDescriptor *field) { GPB_INLINE BOOL GPBFieldDataTypeIsObject(GPBFieldDescriptor *field) {
return GPBTypeIsObject(field->description_->type); return GPBDataTypeIsObject(field->description_->dataType);
} }
GPB_INLINE BOOL GPBExtensionIsMessage(GPBExtensionDescriptor *ext) { GPB_INLINE BOOL GPBExtensionIsMessage(GPBExtensionDescriptor *ext) {
return GPBTypeIsMessage(ext->description_->type); return GPBDataTypeIsMessage(ext->description_->dataType);
} }
// The field is an array/map or it has an object value. // The field is an array/map or it has an object value.
...@@ -158,7 +165,7 @@ GPB_INLINE BOOL GPBFieldStoresObject(GPBFieldDescriptor *field) { ...@@ -158,7 +165,7 @@ GPB_INLINE BOOL GPBFieldStoresObject(GPBFieldDescriptor *field) {
if ((desc->flags & (GPBFieldRepeated | GPBFieldMapKeyMask)) != 0) { if ((desc->flags & (GPBFieldRepeated | GPBFieldMapKeyMask)) != 0) {
return YES; return YES;
} }
return GPBTypeIsObject(desc->type); return GPBDataTypeIsObject(desc->dataType);
} }
BOOL GPBGetHasIvar(GPBMessage *self, int32_t index, uint32_t fieldNumber); BOOL GPBGetHasIvar(GPBMessage *self, int32_t index, uint32_t fieldNumber);
...@@ -272,109 +279,6 @@ void GPBSetAutocreatedRetainedObjectIvarWithField( ...@@ -272,109 +279,6 @@ void GPBSetAutocreatedRetainedObjectIvarWithField(
void GPBClearAutocreatedMessageIvarWithField(GPBMessage *self, void GPBClearAutocreatedMessageIvarWithField(GPBMessage *self,
GPBFieldDescriptor *field); 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 // Returns an Objective C encoding for |selector|. |instanceSel| should be
// YES if it's an instance selector (as opposed to a class selector). // YES if it's an instance selector (as opposed to a class selector).
// |selector| must be a selector from MessageSignatureProtocol. // |selector| must be a selector from MessageSignatureProtocol.
...@@ -410,7 +314,7 @@ GPB_MESSAGE_SIGNATURE_ENTRY(int32_t, SInt32) ...@@ -410,7 +314,7 @@ GPB_MESSAGE_SIGNATURE_ENTRY(int32_t, SInt32)
GPB_MESSAGE_SIGNATURE_ENTRY(int64_t, SInt64) GPB_MESSAGE_SIGNATURE_ENTRY(int64_t, SInt64)
GPB_MESSAGE_SIGNATURE_ENTRY(uint32_t, UInt32) GPB_MESSAGE_SIGNATURE_ENTRY(uint32_t, UInt32)
GPB_MESSAGE_SIGNATURE_ENTRY(uint64_t, UInt64) GPB_MESSAGE_SIGNATURE_ENTRY(uint64_t, UInt64)
GPB_MESSAGE_SIGNATURE_ENTRY(NSData *, Data) GPB_MESSAGE_SIGNATURE_ENTRY(NSData *, Bytes)
GPB_MESSAGE_SIGNATURE_ENTRY(NSString *, String) GPB_MESSAGE_SIGNATURE_ENTRY(NSString *, String)
GPB_MESSAGE_SIGNATURE_ENTRY(GPBMessage *, Message) GPB_MESSAGE_SIGNATURE_ENTRY(GPBMessage *, Message)
GPB_MESSAGE_SIGNATURE_ENTRY(GPBMessage *, Group) GPB_MESSAGE_SIGNATURE_ENTRY(GPBMessage *, Group)
...@@ -419,6 +323,7 @@ GPB_MESSAGE_SIGNATURE_ENTRY(int32_t, Enum) ...@@ -419,6 +323,7 @@ GPB_MESSAGE_SIGNATURE_ENTRY(int32_t, Enum)
#undef GPB_MESSAGE_SIGNATURE_ENTRY #undef GPB_MESSAGE_SIGNATURE_ENTRY
- (id)getArray; - (id)getArray;
- (NSUInteger)getArrayCount;
- (void)setArray:(NSArray *)array; - (void)setArray:(NSArray *)array;
+ (id)getClassValue; + (id)getClassValue;
@end @end
......
...@@ -28,7 +28,7 @@ ...@@ -28,7 +28,7 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#import "GPBTypes.h" #import "GPBRuntimeTypes.h"
CF_EXTERN_C_BEGIN CF_EXTERN_C_BEGIN
...@@ -52,7 +52,7 @@ uint32_t GPBWireFormatMakeTag(uint32_t fieldNumber, GPBWireFormat wireType) ...@@ -52,7 +52,7 @@ uint32_t GPBWireFormatMakeTag(uint32_t fieldNumber, GPBWireFormat wireType)
GPBWireFormat GPBWireFormatGetTagWireType(uint32_t tag) __attribute__((const)); GPBWireFormat GPBWireFormatGetTagWireType(uint32_t tag) __attribute__((const));
uint32_t GPBWireFormatGetTagFieldNumber(uint32_t tag) __attribute__((const)); uint32_t GPBWireFormatGetTagFieldNumber(uint32_t tag) __attribute__((const));
GPBWireFormat GPBWireFormatForType(GPBType type, BOOL isPacked) GPBWireFormat GPBWireFormatForType(GPBDataType dataType, BOOL isPacked)
__attribute__((const)); __attribute__((const));
#define GPBWireFormatMessageSetItemTag \ #define GPBWireFormatMessageSetItemTag \
......
...@@ -49,30 +49,30 @@ uint32_t GPBWireFormatGetTagFieldNumber(uint32_t tag) { ...@@ -49,30 +49,30 @@ uint32_t GPBWireFormatGetTagFieldNumber(uint32_t tag) {
return GPBLogicalRightShift32(tag, GPBWireFormatTagTypeBits); return GPBLogicalRightShift32(tag, GPBWireFormatTagTypeBits);
} }
GPBWireFormat GPBWireFormatForType(GPBType type, BOOL isPacked) { GPBWireFormat GPBWireFormatForType(GPBDataType type, BOOL isPacked) {
if (isPacked) { if (isPacked) {
return GPBWireFormatLengthDelimited; return GPBWireFormatLengthDelimited;
} }
static const GPBWireFormat format[GPBTypeCount] = { static const GPBWireFormat format[GPBDataType_Count] = {
GPBWireFormatVarint, // GPBTypeBool GPBWireFormatVarint, // GPBDataTypeBool
GPBWireFormatFixed32, // GPBTypeFixed32 GPBWireFormatFixed32, // GPBDataTypeFixed32
GPBWireFormatFixed32, // GPBTypeSFixed32 GPBWireFormatFixed32, // GPBDataTypeSFixed32
GPBWireFormatFixed32, // GPBTypeFloat GPBWireFormatFixed32, // GPBDataTypeFloat
GPBWireFormatFixed64, // GPBTypeFixed64 GPBWireFormatFixed64, // GPBDataTypeFixed64
GPBWireFormatFixed64, // GPBTypeSFixed64 GPBWireFormatFixed64, // GPBDataTypeSFixed64
GPBWireFormatFixed64, // GPBTypeDouble GPBWireFormatFixed64, // GPBDataTypeDouble
GPBWireFormatVarint, // GPBTypeInt32 GPBWireFormatVarint, // GPBDataTypeInt32
GPBWireFormatVarint, // GPBTypeInt64 GPBWireFormatVarint, // GPBDataTypeInt64
GPBWireFormatVarint, // GPBTypeSInt32 GPBWireFormatVarint, // GPBDataTypeSInt32
GPBWireFormatVarint, // GPBTypeSInt64 GPBWireFormatVarint, // GPBDataTypeSInt64
GPBWireFormatVarint, // GPBTypeUInt32 GPBWireFormatVarint, // GPBDataTypeUInt32
GPBWireFormatVarint, // GPBTypeUInt64 GPBWireFormatVarint, // GPBDataTypeUInt64
GPBWireFormatLengthDelimited, // GPBTypeBytes GPBWireFormatLengthDelimited, // GPBDataTypeBytes
GPBWireFormatLengthDelimited, // GPBTypeString GPBWireFormatLengthDelimited, // GPBDataTypeString
GPBWireFormatLengthDelimited, // GPBTypeMessage GPBWireFormatLengthDelimited, // GPBDataTypeMessage
GPBWireFormatStartGroup, // GPBTypeGroup GPBWireFormatStartGroup, // GPBDataTypeGroup
GPBWireFormatVarint // GPBTypeEnum GPBWireFormatVarint // GPBDataTypeEnum
}; };
return format[type]; return format[type];
} }
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<Scheme <Scheme
LastUpgradeVersion = "0620" LastUpgradeVersion = "0630"
version = "1.3"> version = "1.3">
<BuildAction <BuildAction
parallelizeBuildables = "YES" parallelizeBuildables = "YES"
......
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<Scheme <Scheme
LastUpgradeVersion = "0610" LastUpgradeVersion = "0630"
version = "1.3"> version = "1.3">
<BuildAction <BuildAction
parallelizeBuildables = "YES" parallelizeBuildables = "YES"
......
...@@ -21,15 +21,15 @@ Installation ...@@ -21,15 +21,15 @@ Installation
------------ ------------
The full distribution pulled from github includes the sources for both the The full distribution pulled from github includes the sources for both the
compiler (protoc) and the runtime (this directory). To build the compiler compiler (protoc) and the runtime (this directory). To build the compiler
and run the runtime tests, you can use: and run the runtime tests, you can use:
$ objectivec/DevTools/full_mac_build.sh $ objectivec/DevTools/full_mac_build.sh
This will generate the `src/protoc` binary. This will generate the `src/protoc` binary.
Usage Building
----- --------
There are two ways to include the Runtime sources in your project: There are two ways to include the Runtime sources in your project:
...@@ -47,6 +47,80 @@ If the target is using ARC, remember to turn off ARC (`-fno-objc-arc`) for the ...@@ -47,6 +47,80 @@ If the target is using ARC, remember to turn off ARC (`-fno-objc-arc`) for the
The files generated by `protoc` for the `*.proto` files (`\*.pbobjc.h' and The files generated by `protoc` for the `*.proto` files (`\*.pbobjc.h' and
`\*.pbobjc.m`) are then also added to the target. `\*.pbobjc.m`) are then also added to the target.
Usage
-----
The objects generated for messages should work like any other Objective C
object. They are mutable objects, but if you don't change them, they are safe
to share between threads (similar to passing an NSMutableDictionary between
threads/queues; as long as no one mutates it, things are fine).
There are a few behaviors worth calling out:
A property that is type NSString\* will never return nil. If the value is
unset, it will return an empty string (@""). This is inpart to align things
with the Protocol Buffers spec which says the default for strings is an empty
string, but also so you can always safely pass them to isEqual:/compare:, etc.
and have deterministic results.
A property that is type NSData\* also won't return nil, it will return an empty
data ([NSData data]). The reasoning is the same as for NSString not returning
nil.
A property that is another GPBMessage class also will not return nil. If the
field wasn't already set, you will get a instance of the correct class. This
instance will be a temporary instance unless you mutate it, at which point it
will be attached to its parent object. We call this pattern *autocreators*.
Similar to NSString and NSData properties it makes things a little safer when
using them with isEqual:/etc.; but more importantly, this allows you to write
code that uses Objective C's property dot notation to walk into nested objects
and access and/or assign things without having to check that they are not nil
and create them each step along the way. You can write this:
```
- (void)updateRecord:(MyMessage *)msg {
...
// Note: You don't have to check subMessage and otherMessage for nil and
// alloc/init/assign them back along the way.
msg.subMessage.otherMessage.lastName = @"Smith";
...
}
```
If you want to check if a GPBMessage property is present, there is always as
`has\[NAME\]` property to go with the main property to check if it is set.
A property that is of an Array or Dictionary type also provides *autocreator*
behavior and will never return nil. This provides all the same benefits you
see for the message properties. Again, you can write:
```
- (void)updateRecord:(MyMessage *)msg {
...
// Note: Just like above, you don't have to check subMessage and otherMessage
// for nil and alloc/init/assign them back along the way. You also don't have
// to create the siblingsArray, you can safely just append to it.
[msg.subMessage.otherMessage.siblingsArray addObject:@"Pat"];
...
}
```
If you are inspecting a message you got from some other place (server, disk,
etc), you may want to check if the Array or Dictionary has entries without
causing it to be created for you. For this, there is always a `\[NAME\]_Count`
property also provided that can return zero or the real count, but won't trigger
the creation.
For primitive type fields (ints, floats, bools, enum) in messages defined in a
`.proto` file that use *proto2* syntax there are conceptual differences between
having an *explicit* and *default* value. You can always get the value of the
property. In the case that it hasn't been set you will get the default. In
cases where you need to know whether it was set explicitly or you are just
getting the default, you can use the `has\[NAME\]` property. If the value has
been set, and you want to clear it, you can set the `has\[NAME\]` to `NO`.
*proto3* syntax messages do away with this concept, thus the default values are
never included when the message is encoded.
The Objective C classes/enums can be used from Swift code. The Objective C classes/enums can be used from Swift code.
Objective C Generator Options Objective C Generator Options
...@@ -55,18 +129,19 @@ Objective C Generator Options ...@@ -55,18 +129,19 @@ Objective C Generator Options
**objc_class_prefix=\<prefix\>** (no default) **objc_class_prefix=\<prefix\>** (no default)
Since Objective C uses a global namespace for all of its classes, there can Since Objective C uses a global namespace for all of its classes, there can
be collisions. This option provides a prefix that will be added to the Enums be collisions. This option provides a prefix that will be added to the Enums
and Objects (for messages) generated from the proto. Convention is to base and Objects (for messages) generated from the proto. Convention is to base
the prefix on the package the proto is in. the prefix on the package the proto is in.
Contributing Contributing
------------ ------------
Please make updates to the tests along with changes. If just changing the Please make updates to the tests along with changes. If just changing the
runtime, the Xcode projects can be used to build and run tests. If change also runtime, the Xcode projects can be used to build and run tests. If your change
require changes to the generated code, `objectivec/DevTools/full_mac_build.sh` also requires changes to the generated code,
can be used to easily rebuild and test changes. Passing `-h` to the script will `objectivec/DevTools/full_mac_build.sh` can be used to easily rebuild and test
show the addition options that could be useful. changes. Passing `-h` to the script will show the addition options that could
be useful.
Documentation Documentation
------------- -------------
......
// 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
...@@ -41,16 +41,15 @@ ...@@ -41,16 +41,15 @@
#import "google/protobuf/UnittestEmbedOptimizeFor.pbobjc.h" #import "google/protobuf/UnittestEmbedOptimizeFor.pbobjc.h"
#import "google/protobuf/UnittestEmpty.pbobjc.h" #import "google/protobuf/UnittestEmpty.pbobjc.h"
#import "google/protobuf/UnittestEnormousDescriptor.pbobjc.h" #import "google/protobuf/UnittestEnormousDescriptor.pbobjc.h"
#import "google/protobuf/UnittestFilter.pbobjc.h"
#import "google/protobuf/UnittestImport.pbobjc.h" #import "google/protobuf/UnittestImport.pbobjc.h"
#import "google/protobuf/UnittestImportLite.pbobjc.h" #import "google/protobuf/UnittestImportLite.pbobjc.h"
#import "google/protobuf/UnittestImportPublic.pbobjc.h" #import "google/protobuf/UnittestImportPublic.pbobjc.h"
#import "google/protobuf/UnittestImportPublicLite.pbobjc.h" #import "google/protobuf/UnittestImportPublicLite.pbobjc.h"
#import "google/protobuf/UnittestLite.pbobjc.h" #import "google/protobuf/UnittestLite.pbobjc.h"
#import "google/protobuf/UnittestMset.pbobjc.h" #import "google/protobuf/UnittestMset.pbobjc.h"
#import "google/protobuf/UnittestNameMangling.pbobjc.h"
#import "google/protobuf/UnittestNoGenericServices.pbobjc.h" #import "google/protobuf/UnittestNoGenericServices.pbobjc.h"
#import "google/protobuf/UnittestObjc.pbobjc.h" #import "google/protobuf/UnittestObjc.pbobjc.h"
#import "google/protobuf/UnittestObjcStartup.pbobjc.h"
#import "google/protobuf/UnittestOptimizeFor.pbobjc.h" #import "google/protobuf/UnittestOptimizeFor.pbobjc.h"
#import "google/protobuf/UnittestPreserveUnknownEnum.pbobjc.h" #import "google/protobuf/UnittestPreserveUnknownEnum.pbobjc.h"
#import "google/protobuf/UnittestRuntimeProto2.pbobjc.h" #import "google/protobuf/UnittestRuntimeProto2.pbobjc.h"
......
...@@ -260,7 +260,7 @@ ...@@ -260,7 +260,7 @@
[GPBCodedInputStream streamWithData:[NSMutableData dataWithData:data]]; [GPBCodedInputStream streamWithData:[NSMutableData dataWithData:data]];
XCTAssertEqual(tag, [input readTag]); XCTAssertEqual(tag, [input readTag]);
XCTAssertThrows([input readData]); XCTAssertThrows([input readBytes]);
} }
// Verifies fix for b/10315336. // Verifies fix for b/10315336.
......
...@@ -196,7 +196,8 @@ static const int kNumMessages = 100; ...@@ -196,7 +196,8 @@ static const int kNumMessages = 100;
NSArray *threads = [self createThreadsWithSelector:sel object:messages]; NSArray *threads = [self createThreadsWithSelector:sel object:messages];
[self startThreads:threads]; [self startThreads:threads];
[self joinThreads:threads]; [self joinThreads:threads];
GPBExtensionField *extension = [UnittestRoot optionalForeignMessageExtension]; GPBExtensionDescriptor *extension =
[UnittestRoot optionalForeignMessageExtension];
for (TestAllExtensions *message in messages) { for (TestAllExtensions *message in messages) {
XCTAssertFalse([message hasExtension:extension]); XCTAssertFalse([message hasExtension:extension]);
} }
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
...@@ -35,6 +35,8 @@ ...@@ -35,6 +35,8 @@
@class TestMap; @class TestMap;
@class TestPackedTypes; @class TestPackedTypes;
@class TestPackedExtensions; @class TestPackedExtensions;
@class TestUnpackedTypes;
@class TestUnpackedExtensions;
@class GPBExtensionRegistry; @class GPBExtensionRegistry;
...@@ -55,8 +57,12 @@ extern const uint32_t kGPBDefaultRepeatCount; ...@@ -55,8 +57,12 @@ extern const uint32_t kGPBDefaultRepeatCount;
repeatedCount:(uint32_t)count; repeatedCount:(uint32_t)count;
- (void)setPackedFields:(TestPackedTypes *)message - (void)setPackedFields:(TestPackedTypes *)message
repeatedCount:(uint32_t)count; repeatedCount:(uint32_t)count;
- (void)setUnpackedFields:(TestUnpackedTypes *)message
repeatedCount:(uint32_t)count;
- (void)setPackedExtensions:(TestPackedExtensions *)message - (void)setPackedExtensions:(TestPackedExtensions *)message
repeatedCount:(uint32_t)count; repeatedCount:(uint32_t)count;
- (void)setUnpackedExtensions:(TestUnpackedExtensions *)message
repeatedCount:(uint32_t)count;
- (void)setAllMapFields:(TestMap *)message numEntries:(uint32_t)count; - (void)setAllMapFields:(TestMap *)message numEntries:(uint32_t)count;
- (TestAllTypes *)allSetRepeatedCount:(uint32_t)count; - (TestAllTypes *)allSetRepeatedCount:(uint32_t)count;
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
...@@ -152,6 +152,7 @@ typedef GPB_ENUM(GPBFieldMask_FieldNumber) { ...@@ -152,6 +152,7 @@ typedef GPB_ENUM(GPBFieldMask_FieldNumber) {
// The set of field mask paths. // The set of field mask paths.
// |pathsArray| contains |NSString| // |pathsArray| contains |NSString|
@property(nonatomic, readwrite, strong) NSMutableArray *pathsArray; @property(nonatomic, readwrite, strong) NSMutableArray *pathsArray;
@property(nonatomic, readonly) NSUInteger pathsArray_Count;
@end @end
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment