|
|
|
@ -45,28 +45,24 @@ |
|
|
|
|
#pragma clang diagnostic push |
|
|
|
|
#pragma clang diagnostic ignored "-Wdirect-ivar-access" |
|
|
|
|
|
|
|
|
|
static void AppendTextFormatForMessage(GPBMessage *message, |
|
|
|
|
NSMutableString *toStr, |
|
|
|
|
static void AppendTextFormatForMessage(GPBMessage *message, NSMutableString *toStr, |
|
|
|
|
NSString *lineIndent); |
|
|
|
|
|
|
|
|
|
// Are two datatypes the same basic type representation (ex Int32 and SInt32). |
|
|
|
|
// Marked unused because currently only called from asserts/debug. |
|
|
|
|
static BOOL DataTypesEquivalent(GPBDataType type1, |
|
|
|
|
GPBDataType type2) __attribute__ ((unused)); |
|
|
|
|
static BOOL DataTypesEquivalent(GPBDataType type1, GPBDataType type2) __attribute__((unused)); |
|
|
|
|
|
|
|
|
|
// Basic type representation for a type (ex: for SInt32 it is Int32). |
|
|
|
|
// Marked unused because currently only called from asserts/debug. |
|
|
|
|
static GPBDataType BaseDataType(GPBDataType type) __attribute__ ((unused)); |
|
|
|
|
static GPBDataType BaseDataType(GPBDataType type) __attribute__((unused)); |
|
|
|
|
|
|
|
|
|
// String name for a data type. |
|
|
|
|
// Marked unused because currently only called from asserts/debug. |
|
|
|
|
static NSString *TypeToString(GPBDataType dataType) __attribute__ ((unused)); |
|
|
|
|
static NSString *TypeToString(GPBDataType dataType) __attribute__((unused)); |
|
|
|
|
|
|
|
|
|
// Helper for clearing oneofs. |
|
|
|
|
static void GPBMaybeClearOneofPrivate(GPBMessage *self, |
|
|
|
|
GPBOneofDescriptor *oneof, |
|
|
|
|
int32_t oneofHasIndex, |
|
|
|
|
uint32_t fieldNumberNotToClear); |
|
|
|
|
static void GPBMaybeClearOneofPrivate(GPBMessage *self, GPBOneofDescriptor *oneof, |
|
|
|
|
int32_t oneofHasIndex, uint32_t fieldNumberNotToClear); |
|
|
|
|
|
|
|
|
|
NSData *GPBEmptyNSData(void) { |
|
|
|
|
static dispatch_once_t onceToken; |
|
|
|
@ -118,50 +114,56 @@ void GPBMessageDropUnknownFieldsRecursively(GPBMessage *initialMessage) { |
|
|
|
|
id rawFieldMap = GPBGetObjectIvarWithFieldNoAutocreate(msg, field); |
|
|
|
|
switch (field.mapKeyDataType) { |
|
|
|
|
case GPBDataTypeBool: |
|
|
|
|
[(GPBBoolObjectDictionary*)rawFieldMap enumerateKeysAndObjectsUsingBlock:^( |
|
|
|
|
BOOL key, id _Nonnull object, BOOL * _Nonnull stop) { |
|
|
|
|
#pragma unused(key, stop) |
|
|
|
|
[(GPBBoolObjectDictionary *)rawFieldMap |
|
|
|
|
enumerateKeysAndObjectsUsingBlock:^(BOOL key, id _Nonnull object, |
|
|
|
|
BOOL *_Nonnull stop) { |
|
|
|
|
#pragma unused(key, stop) |
|
|
|
|
[todo addObject:object]; |
|
|
|
|
}]; |
|
|
|
|
break; |
|
|
|
|
case GPBDataTypeFixed32: |
|
|
|
|
case GPBDataTypeUInt32: |
|
|
|
|
[(GPBUInt32ObjectDictionary*)rawFieldMap enumerateKeysAndObjectsUsingBlock:^( |
|
|
|
|
uint32_t key, id _Nonnull object, BOOL * _Nonnull stop) { |
|
|
|
|
#pragma unused(key, stop) |
|
|
|
|
[(GPBUInt32ObjectDictionary *)rawFieldMap |
|
|
|
|
enumerateKeysAndObjectsUsingBlock:^(uint32_t key, id _Nonnull object, |
|
|
|
|
BOOL *_Nonnull stop) { |
|
|
|
|
#pragma unused(key, stop) |
|
|
|
|
[todo addObject:object]; |
|
|
|
|
}]; |
|
|
|
|
break; |
|
|
|
|
case GPBDataTypeInt32: |
|
|
|
|
case GPBDataTypeSFixed32: |
|
|
|
|
case GPBDataTypeSInt32: |
|
|
|
|
[(GPBInt32ObjectDictionary*)rawFieldMap enumerateKeysAndObjectsUsingBlock:^( |
|
|
|
|
int32_t key, id _Nonnull object, BOOL * _Nonnull stop) { |
|
|
|
|
#pragma unused(key, stop) |
|
|
|
|
[(GPBInt32ObjectDictionary *)rawFieldMap |
|
|
|
|
enumerateKeysAndObjectsUsingBlock:^(int32_t key, id _Nonnull object, |
|
|
|
|
BOOL *_Nonnull stop) { |
|
|
|
|
#pragma unused(key, stop) |
|
|
|
|
[todo addObject:object]; |
|
|
|
|
}]; |
|
|
|
|
break; |
|
|
|
|
case GPBDataTypeFixed64: |
|
|
|
|
case GPBDataTypeUInt64: |
|
|
|
|
[(GPBUInt64ObjectDictionary*)rawFieldMap enumerateKeysAndObjectsUsingBlock:^( |
|
|
|
|
uint64_t key, id _Nonnull object, BOOL * _Nonnull stop) { |
|
|
|
|
#pragma unused(key, stop) |
|
|
|
|
[(GPBUInt64ObjectDictionary *)rawFieldMap |
|
|
|
|
enumerateKeysAndObjectsUsingBlock:^(uint64_t key, id _Nonnull object, |
|
|
|
|
BOOL *_Nonnull stop) { |
|
|
|
|
#pragma unused(key, stop) |
|
|
|
|
[todo addObject:object]; |
|
|
|
|
}]; |
|
|
|
|
break; |
|
|
|
|
case GPBDataTypeInt64: |
|
|
|
|
case GPBDataTypeSFixed64: |
|
|
|
|
case GPBDataTypeSInt64: |
|
|
|
|
[(GPBInt64ObjectDictionary*)rawFieldMap enumerateKeysAndObjectsUsingBlock:^( |
|
|
|
|
int64_t key, id _Nonnull object, BOOL * _Nonnull stop) { |
|
|
|
|
#pragma unused(key, stop) |
|
|
|
|
[(GPBInt64ObjectDictionary *)rawFieldMap |
|
|
|
|
enumerateKeysAndObjectsUsingBlock:^(int64_t key, id _Nonnull object, |
|
|
|
|
BOOL *_Nonnull stop) { |
|
|
|
|
#pragma unused(key, stop) |
|
|
|
|
[todo addObject:object]; |
|
|
|
|
}]; |
|
|
|
|
break; |
|
|
|
|
case GPBDataTypeString: |
|
|
|
|
[(NSDictionary*)rawFieldMap enumerateKeysAndObjectsUsingBlock:^( |
|
|
|
|
NSString * _Nonnull key, GPBMessage * _Nonnull obj, BOOL * _Nonnull stop) { |
|
|
|
|
#pragma unused(key, stop) |
|
|
|
|
[(NSDictionary *)rawFieldMap |
|
|
|
|
enumerateKeysAndObjectsUsingBlock:^( |
|
|
|
|
NSString *_Nonnull key, GPBMessage *_Nonnull obj, BOOL *_Nonnull stop) { |
|
|
|
|
#pragma unused(key, stop) |
|
|
|
|
[todo addObject:obj]; |
|
|
|
|
}]; |
|
|
|
|
break; |
|
|
|
@ -195,7 +197,6 @@ void GPBMessageDropUnknownFieldsRecursively(GPBMessage *initialMessage) { |
|
|
|
|
} // while(todo.count) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// -- About Version Checks -- |
|
|
|
|
// There's actually 3 places these checks all come into play: |
|
|
|
|
// 1. When the generated source is compile into .o files, the header check |
|
|
|
@ -228,8 +229,7 @@ void GPBCheckRuntimeVersionSupport(int32_t objcRuntimeVersion) { |
|
|
|
|
format:@"Proto generation source compiled against runtime" |
|
|
|
|
@" version %d, but this version of the runtime only" |
|
|
|
|
@" supports back to %d!", |
|
|
|
|
objcRuntimeVersion, |
|
|
|
|
GOOGLE_PROTOBUF_OBJC_MIN_SUPPORTED_VERSION]; |
|
|
|
|
objcRuntimeVersion, GOOGLE_PROTOBUF_OBJC_MIN_SUPPORTED_VERSION]; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -288,18 +288,16 @@ void GPBClearMessageField(GPBMessage *self, GPBFieldDescriptor *field) { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void GPBClearOneof(GPBMessage *self, GPBOneofDescriptor *oneof) { |
|
|
|
|
#if defined(DEBUG) && DEBUG |
|
|
|
|
#if defined(DEBUG) && DEBUG |
|
|
|
|
NSCAssert([[self descriptor] oneofWithName:oneof.name] == oneof, |
|
|
|
|
@"OneofDescriptor %@ doesn't appear to be for %@ messages.", |
|
|
|
|
oneof.name, [self class]); |
|
|
|
|
#endif |
|
|
|
|
@"OneofDescriptor %@ doesn't appear to be for %@ messages.", oneof.name, [self class]); |
|
|
|
|
#endif |
|
|
|
|
GPBFieldDescriptor *firstField = oneof->fields_[0]; |
|
|
|
|
GPBMaybeClearOneofPrivate(self, oneof, firstField->description_->hasIndex, 0); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
BOOL GPBGetHasIvar(GPBMessage *self, int32_t idx, uint32_t fieldNumber) { |
|
|
|
|
NSCAssert(self->messageStorage_ != NULL, |
|
|
|
|
@"%@: All messages should have storage (from init)", |
|
|
|
|
NSCAssert(self->messageStorage_ != NULL, @"%@: All messages should have storage (from init)", |
|
|
|
|
[self class]); |
|
|
|
|
if (idx < 0) { |
|
|
|
|
NSCAssert(fieldNumber != 0, @"Invalid field number."); |
|
|
|
@ -309,21 +307,18 @@ BOOL GPBGetHasIvar(GPBMessage *self, int32_t idx, uint32_t fieldNumber) { |
|
|
|
|
NSCAssert(idx != GPBNoHasBit, @"Invalid has bit."); |
|
|
|
|
uint32_t byteIndex = idx / 32; |
|
|
|
|
uint32_t bitMask = (1U << (idx % 32)); |
|
|
|
|
BOOL hasIvar = |
|
|
|
|
(self->messageStorage_->_has_storage_[byteIndex] & bitMask) ? YES : NO; |
|
|
|
|
BOOL hasIvar = (self->messageStorage_->_has_storage_[byteIndex] & bitMask) ? YES : NO; |
|
|
|
|
return hasIvar; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
uint32_t GPBGetHasOneof(GPBMessage *self, int32_t idx) { |
|
|
|
|
NSCAssert(idx < 0, @"%@: invalid index (%d) for oneof.", |
|
|
|
|
[self class], idx); |
|
|
|
|
NSCAssert(idx < 0, @"%@: invalid index (%d) for oneof.", [self class], idx); |
|
|
|
|
uint32_t result = self->messageStorage_->_has_storage_[-idx]; |
|
|
|
|
return result; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void GPBSetHasIvar(GPBMessage *self, int32_t idx, uint32_t fieldNumber, |
|
|
|
|
BOOL value) { |
|
|
|
|
void GPBSetHasIvar(GPBMessage *self, int32_t idx, uint32_t fieldNumber, BOOL value) { |
|
|
|
|
if (idx < 0) { |
|
|
|
|
NSCAssert(fieldNumber != 0, @"Invalid field number."); |
|
|
|
|
uint32_t *has_storage = self->messageStorage_->_has_storage_; |
|
|
|
@ -341,10 +336,8 @@ void GPBSetHasIvar(GPBMessage *self, int32_t idx, uint32_t fieldNumber, |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void GPBMaybeClearOneofPrivate(GPBMessage *self, |
|
|
|
|
GPBOneofDescriptor *oneof, |
|
|
|
|
int32_t oneofHasIndex, |
|
|
|
|
uint32_t fieldNumberNotToClear) { |
|
|
|
|
static void GPBMaybeClearOneofPrivate(GPBMessage *self, GPBOneofDescriptor *oneof, |
|
|
|
|
int32_t oneofHasIndex, uint32_t fieldNumberNotToClear) { |
|
|
|
|
uint32_t fieldNumberSet = GPBGetHasOneof(self, oneofHasIndex); |
|
|
|
|
if ((fieldNumberSet == fieldNumberNotToClear) || (fieldNumberSet == 0)) { |
|
|
|
|
// Do nothing/nothing set in the oneof. |
|
|
|
@ -354,9 +347,8 @@ static void GPBMaybeClearOneofPrivate(GPBMessage *self, |
|
|
|
|
// Like GPBClearMessageField(), free the memory if an objecttype is set, |
|
|
|
|
// pod types don't need to do anything. |
|
|
|
|
GPBFieldDescriptor *fieldSet = [oneof fieldWithNumber:fieldNumberSet]; |
|
|
|
|
NSCAssert(fieldSet, |
|
|
|
|
@"%@: oneof set to something (%u) not in the oneof?", |
|
|
|
|
[self class], fieldNumberSet); |
|
|
|
|
NSCAssert(fieldSet, @"%@: oneof set to something (%u) not in the oneof?", [self class], |
|
|
|
|
fieldNumberSet); |
|
|
|
|
if (fieldSet && GPBFieldStoresObject(fieldSet)) { |
|
|
|
|
uint8_t *storage = (uint8_t *)self->messageStorage_; |
|
|
|
|
id *typePtr = (id *)&storage[fieldSet->description_->offset]; |
|
|
|
@ -508,8 +500,7 @@ static void GPBMaybeClearOneofPrivate(GPBMessage *self, |
|
|
|
|
// Object types are handled slightly differently, they need to be released |
|
|
|
|
// and retained. |
|
|
|
|
|
|
|
|
|
void GPBClearAutocreatedMessageIvarWithField(GPBMessage *self, |
|
|
|
|
GPBFieldDescriptor *field) { |
|
|
|
|
void GPBClearAutocreatedMessageIvarWithField(GPBMessage *self, GPBFieldDescriptor *field) { |
|
|
|
|
if (GPBGetHasIvarField(self, field)) { |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
@ -522,14 +513,12 @@ void GPBClearAutocreatedMessageIvarWithField(GPBMessage *self, |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// This exists only for bridging some aliased types, nothing else should use it. |
|
|
|
|
static void GPBSetObjectIvarWithField(GPBMessage *self, |
|
|
|
|
GPBFieldDescriptor *field, id value) { |
|
|
|
|
static void GPBSetObjectIvarWithField(GPBMessage *self, GPBFieldDescriptor *field, id value) { |
|
|
|
|
if (self == nil || field == nil) return; |
|
|
|
|
GPBSetRetainedObjectIvarWithFieldPrivate(self, field, [value retain]); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void GPBSetCopyObjectIvarWithField(GPBMessage *self, |
|
|
|
|
GPBFieldDescriptor *field, id value); |
|
|
|
|
static void GPBSetCopyObjectIvarWithField(GPBMessage *self, GPBFieldDescriptor *field, id value); |
|
|
|
|
|
|
|
|
|
// GPBSetCopyObjectIvarWithField is blocked from the analyzer because it flags |
|
|
|
|
// a leak for the -copy even though GPBSetRetainedObjectIvarWithFieldPrivate |
|
|
|
@ -537,23 +526,19 @@ static void GPBSetCopyObjectIvarWithField(GPBMessage *self, |
|
|
|
|
// with the -retain in GPBSetObjectIvarWithField. |
|
|
|
|
#if !defined(__clang_analyzer__) |
|
|
|
|
// This exists only for bridging some aliased types, nothing else should use it. |
|
|
|
|
static void GPBSetCopyObjectIvarWithField(GPBMessage *self, |
|
|
|
|
GPBFieldDescriptor *field, id value) { |
|
|
|
|
static void GPBSetCopyObjectIvarWithField(GPBMessage *self, GPBFieldDescriptor *field, id value) { |
|
|
|
|
if (self == nil || field == nil) return; |
|
|
|
|
GPBSetRetainedObjectIvarWithFieldPrivate(self, field, [value copy]); |
|
|
|
|
} |
|
|
|
|
#endif // !defined(__clang_analyzer__) |
|
|
|
|
|
|
|
|
|
void GPBSetObjectIvarWithFieldPrivate(GPBMessage *self, |
|
|
|
|
GPBFieldDescriptor *field, id value) { |
|
|
|
|
void GPBSetObjectIvarWithFieldPrivate(GPBMessage *self, GPBFieldDescriptor *field, id value) { |
|
|
|
|
GPBSetRetainedObjectIvarWithFieldPrivate(self, field, [value retain]); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void GPBSetRetainedObjectIvarWithFieldPrivate(GPBMessage *self, |
|
|
|
|
GPBFieldDescriptor *field, |
|
|
|
|
void GPBSetRetainedObjectIvarWithFieldPrivate(GPBMessage *self, GPBFieldDescriptor *field, |
|
|
|
|
id value) { |
|
|
|
|
NSCAssert(self->messageStorage_ != NULL, |
|
|
|
|
@"%@: All messages should have storage (from init)", |
|
|
|
|
NSCAssert(self->messageStorage_ != NULL, @"%@: All messages should have storage (from init)", |
|
|
|
|
[self class]); |
|
|
|
|
#if defined(__clang_analyzer__) |
|
|
|
|
if (self->messageStorage_ == NULL) return; |
|
|
|
@ -562,8 +547,7 @@ void GPBSetRetainedObjectIvarWithFieldPrivate(GPBMessage *self, |
|
|
|
|
BOOL isMapOrArray = GPBFieldIsMapOrArray(field); |
|
|
|
|
BOOL fieldIsMessage = GPBDataTypeIsMessage(fieldType); |
|
|
|
|
#if defined(DEBUG) && DEBUG |
|
|
|
|
if (value == nil && !isMapOrArray && !fieldIsMessage && |
|
|
|
|
field.hasDefaultValue) { |
|
|
|
|
if (value == nil && !isMapOrArray && !fieldIsMessage && field.hasDefaultValue) { |
|
|
|
|
// Setting a message to nil is an obvious way to "clear" the value |
|
|
|
|
// as there is no way to set a non-empty default value for messages. |
|
|
|
|
// |
|
|
|
@ -584,8 +568,8 @@ void GPBSetRetainedObjectIvarWithFieldPrivate(GPBMessage *self, |
|
|
|
|
@"empty, or call '%@.%@ = NO' to reset it to it's default value of " |
|
|
|
|
@"'%@'. Defaulting to resetting default value.", |
|
|
|
|
className, propName, className, propName, |
|
|
|
|
(fieldType == GPBDataTypeString) ? @"@\"\"" : @"GPBEmptyNSData()", |
|
|
|
|
className, hasSel, field.defaultValue.valueString); |
|
|
|
|
(fieldType == GPBDataTypeString) ? @"@\"\"" : @"GPBEmptyNSData()", className, hasSel, |
|
|
|
|
field.defaultValue.valueString); |
|
|
|
|
// Note: valueString, depending on the type, it could easily be |
|
|
|
|
// valueData/valueMessage. |
|
|
|
|
} |
|
|
|
@ -602,8 +586,7 @@ void GPBSetRetainedObjectIvarWithFieldPrivate(GPBMessage *self, |
|
|
|
|
BOOL setHasValue = (value != nil); |
|
|
|
|
// If the field should clear on a "zero" value, then check if the string/data |
|
|
|
|
// was zero length, and clear instead. |
|
|
|
|
if (((fieldDesc->flags & GPBFieldClearHasIvarOnZero) != 0) && |
|
|
|
|
([value length] == 0)) { |
|
|
|
|
if (((fieldDesc->flags & GPBFieldClearHasIvarOnZero) != 0) && ([value length] == 0)) { |
|
|
|
|
setHasValue = NO; |
|
|
|
|
// The value passed in was retained, it must be released since we |
|
|
|
|
// aren't saving anything in the field. |
|
|
|
@ -639,8 +622,7 @@ void GPBSetRetainedObjectIvarWithFieldPrivate(GPBMessage *self, |
|
|
|
|
} |
|
|
|
|
} else { // GPBFieldTypeMap |
|
|
|
|
// If the old map was autocreated by us, then clear it. |
|
|
|
|
if ((field.mapKeyDataType == GPBDataTypeString) && |
|
|
|
|
GPBDataTypeIsObject(fieldType)) { |
|
|
|
|
if ((field.mapKeyDataType == GPBDataTypeString) && GPBDataTypeIsObject(fieldType)) { |
|
|
|
|
if ([oldValue isKindOfClass:[GPBAutocreatedDictionary class]]) { |
|
|
|
|
GPBAutocreatedDictionary *autoDict = oldValue; |
|
|
|
|
if (autoDict->_autocreator == self) { |
|
|
|
@ -668,8 +650,7 @@ void GPBSetRetainedObjectIvarWithFieldPrivate(GPBMessage *self, |
|
|
|
|
GPBBecomeVisibleToAutocreator(self); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
id GPBGetObjectIvarWithFieldNoAutocreate(GPBMessage *self, |
|
|
|
|
GPBFieldDescriptor *field) { |
|
|
|
|
id GPBGetObjectIvarWithFieldNoAutocreate(GPBMessage *self, GPBFieldDescriptor *field) { |
|
|
|
|
if (self->messageStorage_ == nil) { |
|
|
|
|
return nil; |
|
|
|
|
} |
|
|
|
@ -680,80 +661,68 @@ id GPBGetObjectIvarWithFieldNoAutocreate(GPBMessage *self, |
|
|
|
|
|
|
|
|
|
// Only exists for public api, no core code should use this. |
|
|
|
|
int32_t GPBGetMessageEnumField(GPBMessage *self, GPBFieldDescriptor *field) { |
|
|
|
|
#if defined(DEBUG) && DEBUG |
|
|
|
|
#if defined(DEBUG) && DEBUG |
|
|
|
|
NSCAssert([[self descriptor] fieldWithNumber:field.number] == field, |
|
|
|
|
@"FieldDescriptor %@ doesn't appear to be for %@ messages.", |
|
|
|
|
field.name, [self class]); |
|
|
|
|
@"FieldDescriptor %@ doesn't appear to be for %@ messages.", field.name, [self class]); |
|
|
|
|
NSCAssert(GPBGetFieldDataType(field) == GPBDataTypeEnum, |
|
|
|
|
@"Attempting to get value of type Enum from field %@ " |
|
|
|
|
@"of %@ which is of type %@.", |
|
|
|
|
[self class], field.name, |
|
|
|
|
TypeToString(GPBGetFieldDataType(field))); |
|
|
|
|
#endif |
|
|
|
|
[self class], field.name, TypeToString(GPBGetFieldDataType(field))); |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
int32_t result = GPBGetMessageInt32Field(self, field); |
|
|
|
|
// If this is presevering unknown enums, make sure the value is valid before |
|
|
|
|
// returning it. |
|
|
|
|
|
|
|
|
|
GPBFileSyntax syntax = [self descriptor].file.syntax; |
|
|
|
|
if (GPBHasPreservingUnknownEnumSemantics(syntax) && |
|
|
|
|
![field isValidEnumValue:result]) { |
|
|
|
|
if (GPBHasPreservingUnknownEnumSemantics(syntax) && ![field isValidEnumValue:result]) { |
|
|
|
|
result = kGPBUnrecognizedEnumeratorValue; |
|
|
|
|
} |
|
|
|
|
return result; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Only exists for public api, no core code should use this. |
|
|
|
|
void GPBSetMessageEnumField(GPBMessage *self, GPBFieldDescriptor *field, |
|
|
|
|
int32_t value) { |
|
|
|
|
#if defined(DEBUG) && DEBUG |
|
|
|
|
void GPBSetMessageEnumField(GPBMessage *self, GPBFieldDescriptor *field, int32_t value) { |
|
|
|
|
#if defined(DEBUG) && DEBUG |
|
|
|
|
NSCAssert([[self descriptor] fieldWithNumber:field.number] == field, |
|
|
|
|
@"FieldDescriptor %@ doesn't appear to be for %@ messages.", |
|
|
|
|
field.name, [self class]); |
|
|
|
|
@"FieldDescriptor %@ doesn't appear to be for %@ messages.", field.name, [self class]); |
|
|
|
|
NSCAssert(GPBGetFieldDataType(field) == GPBDataTypeEnum, |
|
|
|
|
@"Attempting to set field %@ of %@ which is of type %@ with " |
|
|
|
|
@"value of type Enum.", |
|
|
|
|
[self class], field.name, |
|
|
|
|
TypeToString(GPBGetFieldDataType(field))); |
|
|
|
|
#endif |
|
|
|
|
[self class], field.name, TypeToString(GPBGetFieldDataType(field))); |
|
|
|
|
#endif |
|
|
|
|
GPBSetEnumIvarWithFieldPrivate(self, field, value); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void GPBSetEnumIvarWithFieldPrivate(GPBMessage *self, |
|
|
|
|
GPBFieldDescriptor *field, int32_t value) { |
|
|
|
|
void GPBSetEnumIvarWithFieldPrivate(GPBMessage *self, GPBFieldDescriptor *field, int32_t value) { |
|
|
|
|
// Don't allow in unknown values. Proto3 can use the Raw method. |
|
|
|
|
if (![field isValidEnumValue:value]) { |
|
|
|
|
[NSException raise:NSInvalidArgumentException |
|
|
|
|
format:@"%@.%@: Attempt to set an unknown enum value (%d)", |
|
|
|
|
[self class], field.name, value]; |
|
|
|
|
format:@"%@.%@: Attempt to set an unknown enum value (%d)", [self class], |
|
|
|
|
field.name, value]; |
|
|
|
|
} |
|
|
|
|
GPBSetInt32IvarWithFieldPrivate(self, field, value); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Only exists for public api, no core code should use this. |
|
|
|
|
int32_t GPBGetMessageRawEnumField(GPBMessage *self, |
|
|
|
|
GPBFieldDescriptor *field) { |
|
|
|
|
int32_t GPBGetMessageRawEnumField(GPBMessage *self, GPBFieldDescriptor *field) { |
|
|
|
|
int32_t result = GPBGetMessageInt32Field(self, field); |
|
|
|
|
return result; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Only exists for public api, no core code should use this. |
|
|
|
|
void GPBSetMessageRawEnumField(GPBMessage *self, GPBFieldDescriptor *field, |
|
|
|
|
int32_t value) { |
|
|
|
|
void GPBSetMessageRawEnumField(GPBMessage *self, GPBFieldDescriptor *field, int32_t value) { |
|
|
|
|
GPBSetInt32IvarWithFieldPrivate(self, field, value); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
BOOL GPBGetMessageBoolField(GPBMessage *self, |
|
|
|
|
GPBFieldDescriptor *field) { |
|
|
|
|
BOOL GPBGetMessageBoolField(GPBMessage *self, GPBFieldDescriptor *field) { |
|
|
|
|
#if defined(DEBUG) && DEBUG |
|
|
|
|
NSCAssert([[self descriptor] fieldWithNumber:field.number] == field, |
|
|
|
|
@"FieldDescriptor %@ doesn't appear to be for %@ messages.", |
|
|
|
|
field.name, [self class]); |
|
|
|
|
@"FieldDescriptor %@ doesn't appear to be for %@ messages.", field.name, [self class]); |
|
|
|
|
NSCAssert(DataTypesEquivalent(GPBGetFieldDataType(field), GPBDataTypeBool), |
|
|
|
|
@"Attempting to get value of type bool from field %@ " |
|
|
|
|
@"of %@ which is of type %@.", |
|
|
|
|
[self class], field.name, |
|
|
|
|
TypeToString(GPBGetFieldDataType(field))); |
|
|
|
|
[self class], field.name, TypeToString(GPBGetFieldDataType(field))); |
|
|
|
|
#endif |
|
|
|
|
if (GPBGetHasIvarField(self, field)) { |
|
|
|
|
// Bools are stored in the has bits to avoid needing explicit space in the |
|
|
|
@ -768,26 +737,20 @@ BOOL GPBGetMessageBoolField(GPBMessage *self, |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Only exists for public api, no core code should use this. |
|
|
|
|
void GPBSetMessageBoolField(GPBMessage *self, |
|
|
|
|
GPBFieldDescriptor *field, |
|
|
|
|
BOOL value) { |
|
|
|
|
void GPBSetMessageBoolField(GPBMessage *self, GPBFieldDescriptor *field, BOOL value) { |
|
|
|
|
if (self == nil || field == nil) return; |
|
|
|
|
#if defined(DEBUG) && DEBUG |
|
|
|
|
#if defined(DEBUG) && DEBUG |
|
|
|
|
NSCAssert([[self descriptor] fieldWithNumber:field.number] == field, |
|
|
|
|
@"FieldDescriptor %@ doesn't appear to be for %@ messages.", |
|
|
|
|
field.name, [self class]); |
|
|
|
|
@"FieldDescriptor %@ doesn't appear to be for %@ messages.", field.name, [self class]); |
|
|
|
|
NSCAssert(DataTypesEquivalent(GPBGetFieldDataType(field), GPBDataTypeBool), |
|
|
|
|
@"Attempting to set field %@ of %@ which is of type %@ with " |
|
|
|
|
@"value of type bool.", |
|
|
|
|
[self class], field.name, |
|
|
|
|
TypeToString(GPBGetFieldDataType(field))); |
|
|
|
|
#endif |
|
|
|
|
[self class], field.name, TypeToString(GPBGetFieldDataType(field))); |
|
|
|
|
#endif |
|
|
|
|
GPBSetBoolIvarWithFieldPrivate(self, field, value); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void GPBSetBoolIvarWithFieldPrivate(GPBMessage *self, |
|
|
|
|
GPBFieldDescriptor *field, |
|
|
|
|
BOOL value) { |
|
|
|
|
void GPBSetBoolIvarWithFieldPrivate(GPBMessage *self, GPBFieldDescriptor *field, BOOL value) { |
|
|
|
|
GPBMessageFieldDescription *fieldDesc = field->description_; |
|
|
|
|
GPBOneofDescriptor *oneof = field->containingOneof_; |
|
|
|
|
if (oneof) { |
|
|
|
@ -802,8 +765,7 @@ void GPBSetBoolIvarWithFieldPrivate(GPBMessage *self, |
|
|
|
|
|
|
|
|
|
// If the value is zero, then we only count the field as "set" if the field |
|
|
|
|
// shouldn't auto clear on zero. |
|
|
|
|
BOOL hasValue = ((value != (BOOL)0) |
|
|
|
|
|| ((fieldDesc->flags & GPBFieldClearHasIvarOnZero) == 0)); |
|
|
|
|
BOOL hasValue = ((value != (BOOL)0) || ((fieldDesc->flags & GPBFieldClearHasIvarOnZero) == 0)); |
|
|
|
|
GPBSetHasIvar(self, fieldDesc->hasIndex, fieldDesc->number, hasValue); |
|
|
|
|
GPBBecomeVisibleToAutocreator(self); |
|
|
|
|
} |
|
|
|
@ -1379,8 +1341,7 @@ void GPBSetMessageRepeatedField(GPBMessage *self, GPBFieldDescriptor *field, id |
|
|
|
|
#if defined(DEBUG) && DEBUG |
|
|
|
|
if (field.fieldType != GPBFieldTypeRepeated) { |
|
|
|
|
[NSException raise:NSInvalidArgumentException |
|
|
|
|
format:@"%@.%@ is not a repeated field.", |
|
|
|
|
[self class], field.name]; |
|
|
|
|
format:@"%@.%@ is not a repeated field.", [self class], field.name]; |
|
|
|
|
} |
|
|
|
|
Class expectedClass = Nil; |
|
|
|
|
switch (GPBGetFieldDataType(field)) { |
|
|
|
@ -1423,8 +1384,8 @@ void GPBSetMessageRepeatedField(GPBMessage *self, GPBFieldDescriptor *field, id |
|
|
|
|
} |
|
|
|
|
if (array && ![array isKindOfClass:expectedClass]) { |
|
|
|
|
[NSException raise:NSInvalidArgumentException |
|
|
|
|
format:@"%@.%@: Expected %@ object, got %@.", |
|
|
|
|
[self class], field.name, expectedClass, [array class]]; |
|
|
|
|
format:@"%@.%@: Expected %@ object, got %@.", [self class], field.name, |
|
|
|
|
expectedClass, [array class]]; |
|
|
|
|
} |
|
|
|
|
#endif |
|
|
|
|
GPBSetObjectIvarWithField(self, field, array); |
|
|
|
@ -1498,13 +1459,11 @@ static NSString *TypeToString(GPBDataType dataType) { |
|
|
|
|
// GPBGetMessageMapField is defined in GPBMessage.m |
|
|
|
|
|
|
|
|
|
// Only exists for public api, no core code should use this. |
|
|
|
|
void GPBSetMessageMapField(GPBMessage *self, GPBFieldDescriptor *field, |
|
|
|
|
id dictionary) { |
|
|
|
|
void GPBSetMessageMapField(GPBMessage *self, GPBFieldDescriptor *field, id dictionary) { |
|
|
|
|
#if defined(DEBUG) && DEBUG |
|
|
|
|
if (field.fieldType != GPBFieldTypeMap) { |
|
|
|
|
[NSException raise:NSInvalidArgumentException |
|
|
|
|
format:@"%@.%@ is not a map<> field.", |
|
|
|
|
[self class], field.name]; |
|
|
|
|
format:@"%@.%@ is not a map<> field.", [self class], field.name]; |
|
|
|
|
} |
|
|
|
|
if (dictionary) { |
|
|
|
|
GPBDataType keyDataType = field.mapKeyDataType; |
|
|
|
@ -1515,20 +1474,17 @@ void GPBSetMessageMapField(GPBMessage *self, GPBFieldDescriptor *field, |
|
|
|
|
keyStr = @"String"; |
|
|
|
|
} |
|
|
|
|
Class expectedClass = Nil; |
|
|
|
|
if ((keyDataType == GPBDataTypeString) && |
|
|
|
|
GPBDataTypeIsObject(valueDataType)) { |
|
|
|
|
if ((keyDataType == GPBDataTypeString) && GPBDataTypeIsObject(valueDataType)) { |
|
|
|
|
expectedClass = [NSMutableDictionary class]; |
|
|
|
|
} else { |
|
|
|
|
NSString *className = |
|
|
|
|
[NSString stringWithFormat:@"GPB%@%@Dictionary", keyStr, valueStr]; |
|
|
|
|
NSString *className = [NSString stringWithFormat:@"GPB%@%@Dictionary", keyStr, valueStr]; |
|
|
|
|
expectedClass = NSClassFromString(className); |
|
|
|
|
NSCAssert(expectedClass, @"Missing a class (%@)?", expectedClass); |
|
|
|
|
} |
|
|
|
|
if (![dictionary isKindOfClass:expectedClass]) { |
|
|
|
|
[NSException raise:NSInvalidArgumentException |
|
|
|
|
format:@"%@.%@: Expected %@ object, got %@.", |
|
|
|
|
[self class], field.name, expectedClass, |
|
|
|
|
[dictionary class]]; |
|
|
|
|
format:@"%@.%@: Expected %@ object, got %@.", [self class], field.name, |
|
|
|
|
expectedClass, [dictionary class]]; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
#endif |
|
|
|
@ -1538,13 +1494,12 @@ void GPBSetMessageMapField(GPBMessage *self, GPBFieldDescriptor *field, |
|
|
|
|
#pragma mark - Misc Dynamic Runtime Utils |
|
|
|
|
|
|
|
|
|
const char *GPBMessageEncodingForSelector(SEL selector, BOOL instanceSel) { |
|
|
|
|
Protocol *protocol = |
|
|
|
|
objc_getProtocol(GPBStringifySymbol(GPBMessageSignatureProtocol)); |
|
|
|
|
Protocol *protocol = objc_getProtocol(GPBStringifySymbol(GPBMessageSignatureProtocol)); |
|
|
|
|
NSCAssert(protocol, @"Missing GPBMessageSignatureProtocol"); |
|
|
|
|
struct objc_method_description description = |
|
|
|
|
protocol_getMethodDescription(protocol, selector, NO, instanceSel); |
|
|
|
|
NSCAssert(description.name != Nil && description.types != nil, |
|
|
|
|
@"Missing method for selector %@", NSStringFromSelector(selector)); |
|
|
|
|
NSCAssert(description.name != Nil && description.types != nil, @"Missing method for selector %@", |
|
|
|
|
NSStringFromSelector(selector)); |
|
|
|
|
return description.types; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -1556,19 +1511,30 @@ static void AppendStringEscaped(NSString *toPrint, NSMutableString *destStr) { |
|
|
|
|
for (NSUInteger i = 0; i < len; ++i) { |
|
|
|
|
unichar aChar = [toPrint characterAtIndex:i]; |
|
|
|
|
switch (aChar) { |
|
|
|
|
case '\n': [destStr appendString:@"\\n"]; break; |
|
|
|
|
case '\r': [destStr appendString:@"\\r"]; break; |
|
|
|
|
case '\t': [destStr appendString:@"\\t"]; break; |
|
|
|
|
case '\"': [destStr appendString:@"\\\""]; break; |
|
|
|
|
case '\'': [destStr appendString:@"\\\'"]; break; |
|
|
|
|
case '\\': [destStr appendString:@"\\\\"]; break; |
|
|
|
|
case '\n': |
|
|
|
|
[destStr appendString:@"\\n"]; |
|
|
|
|
break; |
|
|
|
|
case '\r': |
|
|
|
|
[destStr appendString:@"\\r"]; |
|
|
|
|
break; |
|
|
|
|
case '\t': |
|
|
|
|
[destStr appendString:@"\\t"]; |
|
|
|
|
break; |
|
|
|
|
case '\"': |
|
|
|
|
[destStr appendString:@"\\\""]; |
|
|
|
|
break; |
|
|
|
|
case '\'': |
|
|
|
|
[destStr appendString:@"\\\'"]; |
|
|
|
|
break; |
|
|
|
|
case '\\': |
|
|
|
|
[destStr appendString:@"\\\\"]; |
|
|
|
|
break; |
|
|
|
|
default: |
|
|
|
|
// This differs slightly from the C++ code in that the C++ doesn't |
|
|
|
|
// generate UTF8; it looks at the string in UTF8, but escapes every |
|
|
|
|
// byte > 0x7E. |
|
|
|
|
if (aChar < 0x20) { |
|
|
|
|
[destStr appendFormat:@"\\%d%d%d", |
|
|
|
|
(aChar / 64), ((aChar % 64) / 8), (aChar % 8)]; |
|
|
|
|
[destStr appendFormat:@"\\%d%d%d", (aChar / 64), ((aChar % 64) / 8), (aChar % 8)]; |
|
|
|
|
} else { |
|
|
|
|
[destStr appendFormat:@"%C", aChar]; |
|
|
|
|
} |
|
|
|
@ -1584,12 +1550,24 @@ static void AppendBufferAsString(NSData *buffer, NSMutableString *destStr) { |
|
|
|
|
[destStr appendString:@"\""]; |
|
|
|
|
for (const char *srcEnd = src + srcLen; src < srcEnd; src++) { |
|
|
|
|
switch (*src) { |
|
|
|
|
case '\n': [destStr appendString:@"\\n"]; break; |
|
|
|
|
case '\r': [destStr appendString:@"\\r"]; break; |
|
|
|
|
case '\t': [destStr appendString:@"\\t"]; break; |
|
|
|
|
case '\"': [destStr appendString:@"\\\""]; break; |
|
|
|
|
case '\'': [destStr appendString:@"\\\'"]; break; |
|
|
|
|
case '\\': [destStr appendString:@"\\\\"]; break; |
|
|
|
|
case '\n': |
|
|
|
|
[destStr appendString:@"\\n"]; |
|
|
|
|
break; |
|
|
|
|
case '\r': |
|
|
|
|
[destStr appendString:@"\\r"]; |
|
|
|
|
break; |
|
|
|
|
case '\t': |
|
|
|
|
[destStr appendString:@"\\t"]; |
|
|
|
|
break; |
|
|
|
|
case '\"': |
|
|
|
|
[destStr appendString:@"\\\""]; |
|
|
|
|
break; |
|
|
|
|
case '\'': |
|
|
|
|
[destStr appendString:@"\\\'"]; |
|
|
|
|
break; |
|
|
|
|
case '\\': |
|
|
|
|
[destStr appendString:@"\\\\"]; |
|
|
|
|
break; |
|
|
|
|
default: |
|
|
|
|
if (isprint(*src)) { |
|
|
|
|
[destStr appendFormat:@"%c", *src]; |
|
|
|
@ -1605,31 +1583,29 @@ static void AppendBufferAsString(NSData *buffer, NSMutableString *destStr) { |
|
|
|
|
[destStr appendString:@"\""]; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void AppendTextFormatForMapMessageField( |
|
|
|
|
id map, GPBFieldDescriptor *field, NSMutableString *toStr, |
|
|
|
|
NSString *lineIndent, NSString *fieldName, NSString *lineEnding) { |
|
|
|
|
static void AppendTextFormatForMapMessageField(id map, GPBFieldDescriptor *field, |
|
|
|
|
NSMutableString *toStr, NSString *lineIndent, |
|
|
|
|
NSString *fieldName, NSString *lineEnding) { |
|
|
|
|
GPBDataType keyDataType = field.mapKeyDataType; |
|
|
|
|
GPBDataType valueDataType = GPBGetFieldDataType(field); |
|
|
|
|
BOOL isMessageValue = GPBDataTypeIsMessage(valueDataType); |
|
|
|
|
|
|
|
|
|
NSString *msgStartFirst = |
|
|
|
|
[NSString stringWithFormat:@"%@%@ {%@\n", lineIndent, fieldName, lineEnding]; |
|
|
|
|
NSString *msgStart = |
|
|
|
|
[NSString stringWithFormat:@"%@%@ {\n", lineIndent, fieldName]; |
|
|
|
|
NSString *msgStart = [NSString stringWithFormat:@"%@%@ {\n", lineIndent, fieldName]; |
|
|
|
|
NSString *msgEnd = [NSString stringWithFormat:@"%@}\n", lineIndent]; |
|
|
|
|
|
|
|
|
|
NSString *keyLine = [NSString stringWithFormat:@"%@ key: ", lineIndent]; |
|
|
|
|
NSString *valueLine = [NSString stringWithFormat:@"%@ value%s ", lineIndent, |
|
|
|
|
(isMessageValue ? "" : ":")]; |
|
|
|
|
NSString *valueLine = |
|
|
|
|
[NSString stringWithFormat:@"%@ value%s ", lineIndent, (isMessageValue ? "" : ":")]; |
|
|
|
|
|
|
|
|
|
__block BOOL isFirst = YES; |
|
|
|
|
|
|
|
|
|
if ((keyDataType == GPBDataTypeString) && |
|
|
|
|
GPBDataTypeIsObject(valueDataType)) { |
|
|
|
|
if ((keyDataType == GPBDataTypeString) && GPBDataTypeIsObject(valueDataType)) { |
|
|
|
|
// map is an NSDictionary. |
|
|
|
|
NSDictionary *dict = map; |
|
|
|
|
[dict enumerateKeysAndObjectsUsingBlock:^(NSString *key, id value, BOOL *stop) { |
|
|
|
|
#pragma unused(stop) |
|
|
|
|
#pragma unused(stop) |
|
|
|
|
[toStr appendString:(isFirst ? msgStartFirst : msgStart)]; |
|
|
|
|
isFirst = NO; |
|
|
|
|
|
|
|
|
@ -1729,10 +1705,8 @@ static void AppendTextFormatForMapMessageField( |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void AppendTextFormatForMessageField(GPBMessage *message, |
|
|
|
|
GPBFieldDescriptor *field, |
|
|
|
|
NSMutableString *toStr, |
|
|
|
|
NSString *lineIndent) { |
|
|
|
|
static void AppendTextFormatForMessageField(GPBMessage *message, GPBFieldDescriptor *field, |
|
|
|
|
NSMutableString *toStr, NSString *lineIndent) { |
|
|
|
|
id arrayOrMap; |
|
|
|
|
NSUInteger count; |
|
|
|
|
GPBFieldType fieldType = field.fieldType; |
|
|
|
@ -1780,8 +1754,7 @@ static void AppendTextFormatForMessageField(GPBMessage *message, |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (fieldType == GPBFieldTypeMap) { |
|
|
|
|
AppendTextFormatForMapMessageField(arrayOrMap, field, toStr, lineIndent, |
|
|
|
|
fieldName, lineEnding); |
|
|
|
|
AppendTextFormatForMapMessageField(arrayOrMap, field, toStr, lineIndent, fieldName, lineEnding); |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -1792,8 +1765,7 @@ static void AppendTextFormatForMessageField(GPBMessage *message, |
|
|
|
|
BOOL isMessageField = GPBDataTypeIsMessage(fieldDataType); |
|
|
|
|
for (NSUInteger j = 0; j < count; ++j) { |
|
|
|
|
// Start the line. |
|
|
|
|
[toStr appendFormat:@"%@%@%s ", lineIndent, fieldName, |
|
|
|
|
(isMessageField ? "" : ":")]; |
|
|
|
|
[toStr appendFormat:@"%@%@%s ", lineIndent, fieldName, (isMessageField ? "" : ":")]; |
|
|
|
|
|
|
|
|
|
// The value. |
|
|
|
|
switch (fieldDataType) { |
|
|
|
@ -1859,8 +1831,7 @@ static void AppendTextFormatForMessageField(GPBMessage *message, |
|
|
|
|
|
|
|
|
|
case GPBDataTypeGroup: |
|
|
|
|
case GPBDataTypeMessage: { |
|
|
|
|
GPBMessage *v = |
|
|
|
|
(isRepeated ? [(NSArray *)array objectAtIndex:j] |
|
|
|
|
GPBMessage *v = (isRepeated ? [(NSArray *)array objectAtIndex:j] |
|
|
|
|
: GPBGetObjectIvarWithField(message, field)); |
|
|
|
|
[toStr appendFormat:@"{%@\n", lineEnding]; |
|
|
|
|
NSString *subIndent = [lineIndent stringByAppendingString:@" "]; |
|
|
|
@ -1878,11 +1849,9 @@ static void AppendTextFormatForMessageField(GPBMessage *message, |
|
|
|
|
} // for(count) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void AppendTextFormatForMessageExtensionRange(GPBMessage *message, |
|
|
|
|
NSArray *activeExtensions, |
|
|
|
|
static void AppendTextFormatForMessageExtensionRange(GPBMessage *message, NSArray *activeExtensions, |
|
|
|
|
GPBExtensionRange range, |
|
|
|
|
NSMutableString *toStr, |
|
|
|
|
NSString *lineIndent) { |
|
|
|
|
NSMutableString *toStr, NSString *lineIndent) { |
|
|
|
|
uint32_t start = range.start; |
|
|
|
|
uint32_t end = range.end; |
|
|
|
|
for (GPBExtensionDescriptor *extension in activeExtensions) { |
|
|
|
@ -1951,8 +1920,7 @@ static void AppendTextFormatForMessageExtensionRange(GPBMessage *message, |
|
|
|
|
#undef FIELD_CASE |
|
|
|
|
|
|
|
|
|
case GPBDataTypeBool: |
|
|
|
|
[toStr appendString:([(NSNumber *)curValue boolValue] ? @"true" |
|
|
|
|
: @"false")]; |
|
|
|
|
[toStr appendString:([(NSNumber *)curValue boolValue] ? @"true" : @"false")]; |
|
|
|
|
break; |
|
|
|
|
|
|
|
|
|
case GPBDataTypeString: |
|
|
|
@ -1983,32 +1951,29 @@ static void AppendTextFormatForMessageExtensionRange(GPBMessage *message, |
|
|
|
|
} // for..in(activeExtensions) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void AppendTextFormatForMessage(GPBMessage *message, |
|
|
|
|
NSMutableString *toStr, |
|
|
|
|
static void AppendTextFormatForMessage(GPBMessage *message, NSMutableString *toStr, |
|
|
|
|
NSString *lineIndent) { |
|
|
|
|
GPBDescriptor *descriptor = [message descriptor]; |
|
|
|
|
NSArray *fieldsArray = descriptor->fields_; |
|
|
|
|
NSUInteger fieldCount = fieldsArray.count; |
|
|
|
|
const GPBExtensionRange *extensionRanges = descriptor.extensionRanges; |
|
|
|
|
NSUInteger extensionRangesCount = descriptor.extensionRangesCount; |
|
|
|
|
NSArray *activeExtensions = [[message extensionsCurrentlySet] |
|
|
|
|
sortedArrayUsingSelector:@selector(compareByFieldNumber:)]; |
|
|
|
|
NSArray *activeExtensions = |
|
|
|
|
[[message extensionsCurrentlySet] sortedArrayUsingSelector:@selector(compareByFieldNumber:)]; |
|
|
|
|
for (NSUInteger i = 0, j = 0; i < fieldCount || j < extensionRangesCount;) { |
|
|
|
|
if (i == fieldCount) { |
|
|
|
|
AppendTextFormatForMessageExtensionRange( |
|
|
|
|
message, activeExtensions, extensionRanges[j++], toStr, lineIndent); |
|
|
|
|
AppendTextFormatForMessageExtensionRange(message, activeExtensions, extensionRanges[j++], |
|
|
|
|
toStr, lineIndent); |
|
|
|
|
} else if (j == extensionRangesCount || |
|
|
|
|
GPBFieldNumber(fieldsArray[i]) < extensionRanges[j].start) { |
|
|
|
|
AppendTextFormatForMessageField(message, fieldsArray[i++], toStr, |
|
|
|
|
lineIndent); |
|
|
|
|
AppendTextFormatForMessageField(message, fieldsArray[i++], toStr, lineIndent); |
|
|
|
|
} else { |
|
|
|
|
AppendTextFormatForMessageExtensionRange( |
|
|
|
|
message, activeExtensions, extensionRanges[j++], toStr, lineIndent); |
|
|
|
|
AppendTextFormatForMessageExtensionRange(message, activeExtensions, extensionRanges[j++], |
|
|
|
|
toStr, lineIndent); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
NSString *unknownFieldsStr = |
|
|
|
|
GPBTextFormatForUnknownFieldSet(message.unknownFields, lineIndent); |
|
|
|
|
NSString *unknownFieldsStr = GPBTextFormatForUnknownFieldSet(message.unknownFields, lineIndent); |
|
|
|
|
if ([unknownFieldsStr length] > 0) { |
|
|
|
|
[toStr appendFormat:@"%@# --- Unknown fields ---\n", lineIndent]; |
|
|
|
|
[toStr appendString:unknownFieldsStr]; |
|
|
|
@ -2024,8 +1989,7 @@ NSString *GPBTextFormatForMessage(GPBMessage *message, NSString *lineIndent) { |
|
|
|
|
return buildString; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
NSString *GPBTextFormatForUnknownFieldSet(GPBUnknownFieldSet *unknownSet, |
|
|
|
|
NSString *lineIndent) { |
|
|
|
|
NSString *GPBTextFormatForUnknownFieldSet(GPBUnknownFieldSet *unknownSet, NSString *lineIndent) { |
|
|
|
|
if (unknownSet == nil) return @""; |
|
|
|
|
if (lineIndent == nil) lineIndent = @""; |
|
|
|
|
|
|
|
|
@ -2034,11 +1998,9 @@ NSString *GPBTextFormatForUnknownFieldSet(GPBUnknownFieldSet *unknownSet, |
|
|
|
|
int32_t fieldNumber = [field number]; |
|
|
|
|
|
|
|
|
|
#define PRINT_LOOP(PROPNAME, CTYPE, FORMAT) \ |
|
|
|
|
[field.PROPNAME \ |
|
|
|
|
enumerateValuesWithBlock:^(CTYPE value, NSUInteger idx, BOOL * stop) { \ |
|
|
|
|
[field.PROPNAME enumerateValuesWithBlock:^(CTYPE value, NSUInteger idx, BOOL * stop) { \ |
|
|
|
|
_Pragma("unused(idx, stop)"); \ |
|
|
|
|
[result \ |
|
|
|
|
appendFormat:@"%@%d: " FORMAT "\n", lineIndent, fieldNumber, value]; \ |
|
|
|
|
[result appendFormat:@"%@%d: " FORMAT "\n", lineIndent, fieldNumber, value]; \ |
|
|
|
|
}]; |
|
|
|
|
|
|
|
|
|
PRINT_LOOP(varintList, uint64_t, "%llu"); |
|
|
|
@ -2058,8 +2020,7 @@ NSString *GPBTextFormatForUnknownFieldSet(GPBUnknownFieldSet *unknownSet, |
|
|
|
|
for (GPBUnknownFieldSet *subUnknownSet in field.groupList) { |
|
|
|
|
[result appendFormat:@"%@%d: {\n", lineIndent, fieldNumber]; |
|
|
|
|
NSString *subIndent = [lineIndent stringByAppendingString:@" "]; |
|
|
|
|
NSString *subUnknownSetStr = |
|
|
|
|
GPBTextFormatForUnknownFieldSet(subUnknownSet, subIndent); |
|
|
|
|
NSString *subUnknownSetStr = GPBTextFormatForUnknownFieldSet(subUnknownSet, subIndent); |
|
|
|
|
[result appendString:subUnknownSetStr]; |
|
|
|
|
[result appendFormat:@"%@}\n", lineIndent]; |
|
|
|
|
} |
|
|
|
@ -2102,8 +2063,7 @@ static int32_t ReadRawVarint32FromData(const uint8_t **data) { |
|
|
|
|
return result; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
[NSException raise:NSParseErrorException |
|
|
|
|
format:@"Unable to read varint32"]; |
|
|
|
|
[NSException raise:NSParseErrorException format:@"Unable to read varint32"]; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
@ -2111,8 +2071,7 @@ static int32_t ReadRawVarint32FromData(const uint8_t **data) { |
|
|
|
|
return result; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
NSString *GPBDecodeTextFormatName(const uint8_t *decodeData, int32_t key, |
|
|
|
|
NSString *inputStr) { |
|
|
|
|
NSString *GPBDecodeTextFormatName(const uint8_t *decodeData, int32_t key, NSString *inputStr) { |
|
|
|
|
// decodData form: |
|
|
|
|
// varint32: num entries |
|
|
|
|
// for each entry: |
|
|
|
@ -2170,8 +2129,7 @@ NSString *GPBDecodeTextFormatName(const uint8_t *decodeData, int32_t key, |
|
|
|
|
return result; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
NSMutableString *result = |
|
|
|
|
[NSMutableString stringWithCapacity:[inputStr length]]; |
|
|
|
|
NSMutableString *result = [NSMutableString stringWithCapacity:[inputStr length]]; |
|
|
|
|
|
|
|
|
|
const uint8_t kAddUnderscore = 0b10000000; |
|
|
|
|
const uint8_t kOpMask = 0b01100000; |
|
|
|
@ -2221,26 +2179,23 @@ NSString *GPBDecodeTextFormatName(const uint8_t *decodeData, int32_t key, |
|
|
|
|
#pragma mark Legacy methods old generated code calls |
|
|
|
|
|
|
|
|
|
// Shim from the older generated code into the runtime. |
|
|
|
|
void GPBSetInt32IvarWithFieldInternal(GPBMessage *self, |
|
|
|
|
GPBFieldDescriptor *field, |
|
|
|
|
int32_t value, |
|
|
|
|
void GPBSetInt32IvarWithFieldInternal(GPBMessage *self, GPBFieldDescriptor *field, int32_t value, |
|
|
|
|
GPBFileSyntax syntax) { |
|
|
|
|
#pragma unused(syntax) |
|
|
|
|
GPBSetMessageInt32Field(self, field, value); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void GPBMaybeClearOneof(GPBMessage *self, GPBOneofDescriptor *oneof, |
|
|
|
|
int32_t oneofHasIndex, uint32_t fieldNumberNotToClear) { |
|
|
|
|
void GPBMaybeClearOneof(GPBMessage *self, GPBOneofDescriptor *oneof, int32_t oneofHasIndex, |
|
|
|
|
uint32_t fieldNumberNotToClear) { |
|
|
|
|
#pragma unused(fieldNumberNotToClear) |
|
|
|
|
#if defined(DEBUG) && DEBUG |
|
|
|
|
#if defined(DEBUG) && DEBUG |
|
|
|
|
NSCAssert([[self descriptor] oneofWithName:oneof.name] == oneof, |
|
|
|
|
@"OneofDescriptor %@ doesn't appear to be for %@ messages.", |
|
|
|
|
oneof.name, [self class]); |
|
|
|
|
@"OneofDescriptor %@ doesn't appear to be for %@ messages.", oneof.name, [self class]); |
|
|
|
|
GPBFieldDescriptor *firstField __unused = oneof->fields_[0]; |
|
|
|
|
NSCAssert(firstField->description_->hasIndex == oneofHasIndex, |
|
|
|
|
@"Internal error, oneofHasIndex (%d) doesn't match (%d).", |
|
|
|
|
firstField->description_->hasIndex, oneofHasIndex); |
|
|
|
|
#endif |
|
|
|
|
#endif |
|
|
|
|
GPBMaybeClearOneofPrivate(self, oneof, oneofHasIndex, 0); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|