|
|
|
@ -42,8 +42,10 @@ |
|
|
|
|
#pragma clang diagnostic push |
|
|
|
|
#pragma clang diagnostic ignored "-Wdirect-ivar-access" |
|
|
|
|
|
|
|
|
|
// The address of this variable is used as a key for obj_getAssociatedObject. |
|
|
|
|
// The addresses of these variables are used as keys for objc_getAssociatedObject. |
|
|
|
|
static const char kTextFormatExtraValueKey = 0; |
|
|
|
|
static const char kParentClassNameValueKey = 0; |
|
|
|
|
static const char kClassNameSuffixKey = 0; |
|
|
|
|
|
|
|
|
|
// Utility function to generate selectors on the fly. |
|
|
|
|
static SEL SelFromStrings(const char *prefix, const char *middle, |
|
|
|
@ -215,10 +217,102 @@ static NSArray *NewFieldsArrayForHasIndex(int hasIndex, |
|
|
|
|
extensionRangesCount_ = count; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
- (void)setupContainingMessageClassName:(const char *)msgClassName { |
|
|
|
|
// Note: Only fetch the class here, can't send messages to it because |
|
|
|
|
// that could cause cycles back to this class within +initialize if |
|
|
|
|
// two messages have each other in fields (i.e. - they build a graph). |
|
|
|
|
NSAssert(objc_getClass(msgClassName), @"Class %s not defined", msgClassName); |
|
|
|
|
NSValue *parentNameValue = [NSValue valueWithPointer:msgClassName]; |
|
|
|
|
objc_setAssociatedObject(self, &kParentClassNameValueKey, |
|
|
|
|
parentNameValue, |
|
|
|
|
OBJC_ASSOCIATION_RETAIN_NONATOMIC); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
- (void)setupMessageClassNameSuffix:(NSString *)suffix { |
|
|
|
|
if (suffix.length) { |
|
|
|
|
objc_setAssociatedObject(self, &kClassNameSuffixKey, |
|
|
|
|
suffix, |
|
|
|
|
OBJC_ASSOCIATION_RETAIN_NONATOMIC); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
- (NSString *)name { |
|
|
|
|
return NSStringFromClass(messageClass_); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
- (GPBDescriptor *)containingType { |
|
|
|
|
NSValue *parentNameValue = |
|
|
|
|
objc_getAssociatedObject(self, &kParentClassNameValueKey); |
|
|
|
|
if (!parentNameValue) { |
|
|
|
|
return nil; |
|
|
|
|
} |
|
|
|
|
const char *parentName = [parentNameValue pointerValue]; |
|
|
|
|
Class parentClass = objc_getClass(parentName); |
|
|
|
|
NSAssert(parentClass, @"Class %s not defined", parentName); |
|
|
|
|
return [parentClass descriptor]; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
- (NSString *)fullName { |
|
|
|
|
NSString *className = NSStringFromClass(self.messageClass); |
|
|
|
|
GPBFileDescriptor *file = self.file; |
|
|
|
|
NSString *objcPrefix = file.objcPrefix; |
|
|
|
|
if (objcPrefix && ![className hasPrefix:objcPrefix]) { |
|
|
|
|
NSAssert(0, |
|
|
|
|
@"Class didn't have correct prefix? (%@ - %@)", |
|
|
|
|
className, objcPrefix); |
|
|
|
|
return nil; |
|
|
|
|
} |
|
|
|
|
GPBDescriptor *parent = self.containingType; |
|
|
|
|
|
|
|
|
|
NSString *name = nil; |
|
|
|
|
if (parent) { |
|
|
|
|
NSString *parentClassName = NSStringFromClass(parent.messageClass); |
|
|
|
|
// The generator will add _Class to avoid reserved words, drop it. |
|
|
|
|
NSString *suffix = objc_getAssociatedObject(parent, &kClassNameSuffixKey); |
|
|
|
|
if (suffix) { |
|
|
|
|
if (![parentClassName hasSuffix:suffix]) { |
|
|
|
|
NSAssert(0, |
|
|
|
|
@"ParentMessage class didn't have correct suffix? (%@ - %@)", |
|
|
|
|
className, suffix); |
|
|
|
|
return nil; |
|
|
|
|
} |
|
|
|
|
parentClassName = |
|
|
|
|
[parentClassName substringToIndex:(parentClassName.length - suffix.length)]; |
|
|
|
|
} |
|
|
|
|
NSString *parentPrefix = [parentClassName stringByAppendingString:@"_"]; |
|
|
|
|
if (![className hasPrefix:parentPrefix]) { |
|
|
|
|
NSAssert(0, |
|
|
|
|
@"Class didn't have the correct parent name prefix? (%@ - %@)", |
|
|
|
|
parentPrefix, className); |
|
|
|
|
return nil; |
|
|
|
|
} |
|
|
|
|
name = [className substringFromIndex:parentPrefix.length]; |
|
|
|
|
} else { |
|
|
|
|
name = [className substringFromIndex:objcPrefix.length]; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// The generator will add _Class to avoid reserved words, drop it. |
|
|
|
|
NSString *suffix = objc_getAssociatedObject(self, &kClassNameSuffixKey); |
|
|
|
|
if (suffix) { |
|
|
|
|
if (![name hasSuffix:suffix]) { |
|
|
|
|
NSAssert(0, |
|
|
|
|
@"Message class didn't have correct suffix? (%@ - %@)", |
|
|
|
|
name, suffix); |
|
|
|
|
return nil; |
|
|
|
|
} |
|
|
|
|
name = [name substringToIndex:(name.length - suffix.length)]; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
NSString *prefix = (parent != nil ? parent.fullName : file.package); |
|
|
|
|
NSString *result; |
|
|
|
|
if (prefix.length > 0) { |
|
|
|
|
result = [NSString stringWithFormat:@"%@.%@", prefix, name]; |
|
|
|
|
} else { |
|
|
|
|
result = name; |
|
|
|
|
} |
|
|
|
|
return result; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
- (id)copyWithZone:(NSZone *)zone { |
|
|
|
|
#pragma unused(zone) |
|
|
|
|
return [self retain]; |
|
|
|
@ -255,12 +349,26 @@ static NSArray *NewFieldsArrayForHasIndex(int hasIndex, |
|
|
|
|
|
|
|
|
|
@implementation GPBFileDescriptor { |
|
|
|
|
NSString *package_; |
|
|
|
|
NSString *objcPrefix_; |
|
|
|
|
GPBFileSyntax syntax_; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@synthesize package = package_; |
|
|
|
|
@synthesize objcPrefix = objcPrefix_; |
|
|
|
|
@synthesize syntax = syntax_; |
|
|
|
|
|
|
|
|
|
- (instancetype)initWithPackage:(NSString *)package |
|
|
|
|
objcPrefix:(NSString *)objcPrefix |
|
|
|
|
syntax:(GPBFileSyntax)syntax { |
|
|
|
|
self = [super init]; |
|
|
|
|
if (self) { |
|
|
|
|
package_ = [package copy]; |
|
|
|
|
objcPrefix_ = [objcPrefix copy]; |
|
|
|
|
syntax_ = syntax; |
|
|
|
|
} |
|
|
|
|
return self; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
- (instancetype)initWithPackage:(NSString *)package |
|
|
|
|
syntax:(GPBFileSyntax)syntax { |
|
|
|
|
self = [super init]; |
|
|
|
@ -273,6 +381,7 @@ static NSArray *NewFieldsArrayForHasIndex(int hasIndex, |
|
|
|
|
|
|
|
|
|
- (void)dealloc { |
|
|
|
|
[package_ release]; |
|
|
|
|
[objcPrefix_ release]; |
|
|
|
|
[super dealloc]; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -416,6 +525,9 @@ uint32_t GPBFieldAlternateTag(GPBFieldDescriptor *self) { |
|
|
|
|
// Extra type specific data. |
|
|
|
|
if (isMessage) { |
|
|
|
|
const char *className = coreDesc->dataTypeSpecific.className; |
|
|
|
|
// Note: Only fetch the class here, can't send messages to it because |
|
|
|
|
// that could cause cycles back to this class within +initialize if |
|
|
|
|
// two messages have each other in fields (i.e. - they build a graph). |
|
|
|
|
msgClass_ = objc_getClass(className); |
|
|
|
|
NSAssert(msgClass_, @"Class %s not defined", className); |
|
|
|
|
} else if (dataType == GPBDataTypeEnum) { |
|
|
|
|