| OLD | NEW |
| 1 // Protocol Buffers - Google's data interchange format | 1 // Protocol Buffers - Google's data interchange format |
| 2 // Copyright 2008 Google Inc. All rights reserved. | 2 // Copyright 2008 Google Inc. All rights reserved. |
| 3 // https://developers.google.com/protocol-buffers/ | 3 // https://developers.google.com/protocol-buffers/ |
| 4 // | 4 // |
| 5 // Redistribution and use in source and binary forms, with or without | 5 // Redistribution and use in source and binary forms, with or without |
| 6 // modification, are permitted provided that the following conditions are | 6 // modification, are permitted provided that the following conditions are |
| 7 // met: | 7 // met: |
| 8 // | 8 // |
| 9 // * Redistributions of source code must retain the above copyright | 9 // * Redistributions of source code must retain the above copyright |
| 10 // notice, this list of conditions and the following disclaimer. | 10 // notice, this list of conditions and the following disclaimer. |
| (...skipping 18 matching lines...) Expand all Loading... |
| 29 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 29 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 30 | 30 |
| 31 #import "GPBDescriptor_PackagePrivate.h" | 31 #import "GPBDescriptor_PackagePrivate.h" |
| 32 | 32 |
| 33 #import <objc/runtime.h> | 33 #import <objc/runtime.h> |
| 34 | 34 |
| 35 #import "GPBUtilities_PackagePrivate.h" | 35 #import "GPBUtilities_PackagePrivate.h" |
| 36 #import "GPBWireFormat.h" | 36 #import "GPBWireFormat.h" |
| 37 #import "GPBMessage_PackagePrivate.h" | 37 #import "GPBMessage_PackagePrivate.h" |
| 38 | 38 |
| 39 // Direct access is use for speed, to avoid even internally declaring things | 39 // The address of this variable is used as a key for obj_getAssociatedObject. |
| 40 // read/write, etc. The warning is enabled in the project to ensure code calling | |
| 41 // protos can turn on -Wdirect-ivar-access without issues. | |
| 42 #pragma clang diagnostic push | |
| 43 #pragma clang diagnostic ignored "-Wdirect-ivar-access" | |
| 44 | |
| 45 // The addresses of these variables are used as keys for objc_getAssociatedObjec
t. | |
| 46 static const char kTextFormatExtraValueKey = 0; | 40 static const char kTextFormatExtraValueKey = 0; |
| 47 static const char kParentClassNameValueKey = 0; | |
| 48 static const char kClassNameSuffixKey = 0; | |
| 49 | 41 |
| 50 // Utility function to generate selectors on the fly. | 42 // Utility function to generate selectors on the fly. |
| 51 static SEL SelFromStrings(const char *prefix, const char *middle, | 43 static SEL SelFromStrings(const char *prefix, const char *middle, |
| 52 const char *suffix, BOOL takesArg) { | 44 const char *suffix, BOOL takesArg) { |
| 53 if (prefix == NULL && suffix == NULL && !takesArg) { | 45 if (prefix == NULL && suffix == NULL && !takesArg) { |
| 54 return sel_getUid(middle); | 46 return sel_getUid(middle); |
| 55 } | 47 } |
| 56 const size_t prefixLen = prefix != NULL ? strlen(prefix) : 0; | 48 const size_t prefixLen = prefix != NULL ? strlen(prefix) : 0; |
| 57 const size_t middleLen = strlen(middle); | 49 const size_t middleLen = strlen(middle); |
| 58 const size_t suffixLen = suffix != NULL ? strlen(suffix) : 0; | 50 const size_t suffixLen = suffix != NULL ? strlen(suffix) : 0; |
| (...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 210 } | 202 } |
| 211 } | 203 } |
| 212 } | 204 } |
| 213 } | 205 } |
| 214 | 206 |
| 215 - (void)setupExtensionRanges:(const GPBExtensionRange *)ranges count:(int32_t)co
unt { | 207 - (void)setupExtensionRanges:(const GPBExtensionRange *)ranges count:(int32_t)co
unt { |
| 216 extensionRanges_ = ranges; | 208 extensionRanges_ = ranges; |
| 217 extensionRangesCount_ = count; | 209 extensionRangesCount_ = count; |
| 218 } | 210 } |
| 219 | 211 |
| 220 - (void)setupContainingMessageClassName:(const char *)msgClassName { | |
| 221 // Note: Only fetch the class here, can't send messages to it because | |
| 222 // that could cause cycles back to this class within +initialize if | |
| 223 // two messages have each other in fields (i.e. - they build a graph). | |
| 224 NSAssert(objc_getClass(msgClassName), @"Class %s not defined", msgClassName); | |
| 225 NSValue *parentNameValue = [NSValue valueWithPointer:msgClassName]; | |
| 226 objc_setAssociatedObject(self, &kParentClassNameValueKey, | |
| 227 parentNameValue, | |
| 228 OBJC_ASSOCIATION_RETAIN_NONATOMIC); | |
| 229 } | |
| 230 | |
| 231 - (void)setupMessageClassNameSuffix:(NSString *)suffix { | |
| 232 if (suffix.length) { | |
| 233 objc_setAssociatedObject(self, &kClassNameSuffixKey, | |
| 234 suffix, | |
| 235 OBJC_ASSOCIATION_RETAIN_NONATOMIC); | |
| 236 } | |
| 237 } | |
| 238 | |
| 239 - (NSString *)name { | 212 - (NSString *)name { |
| 240 return NSStringFromClass(messageClass_); | 213 return NSStringFromClass(messageClass_); |
| 241 } | 214 } |
| 242 | 215 |
| 243 - (GPBDescriptor *)containingType { | |
| 244 NSValue *parentNameValue = | |
| 245 objc_getAssociatedObject(self, &kParentClassNameValueKey); | |
| 246 if (!parentNameValue) { | |
| 247 return nil; | |
| 248 } | |
| 249 const char *parentName = [parentNameValue pointerValue]; | |
| 250 Class parentClass = objc_getClass(parentName); | |
| 251 NSAssert(parentClass, @"Class %s not defined", parentName); | |
| 252 return [parentClass descriptor]; | |
| 253 } | |
| 254 | |
| 255 - (NSString *)fullName { | |
| 256 NSString *className = NSStringFromClass(self.messageClass); | |
| 257 GPBFileDescriptor *file = self.file; | |
| 258 NSString *objcPrefix = file.objcPrefix; | |
| 259 if (objcPrefix && ![className hasPrefix:objcPrefix]) { | |
| 260 NSAssert(0, | |
| 261 @"Class didn't have correct prefix? (%@ - %@)", | |
| 262 className, objcPrefix); | |
| 263 return nil; | |
| 264 } | |
| 265 GPBDescriptor *parent = self.containingType; | |
| 266 | |
| 267 NSString *name = nil; | |
| 268 if (parent) { | |
| 269 NSString *parentClassName = NSStringFromClass(parent.messageClass); | |
| 270 // The generator will add _Class to avoid reserved words, drop it. | |
| 271 NSString *suffix = objc_getAssociatedObject(parent, &kClassNameSuffixKey); | |
| 272 if (suffix) { | |
| 273 if (![parentClassName hasSuffix:suffix]) { | |
| 274 NSAssert(0, | |
| 275 @"ParentMessage class didn't have correct suffix? (%@ - %@)", | |
| 276 className, suffix); | |
| 277 return nil; | |
| 278 } | |
| 279 parentClassName = | |
| 280 [parentClassName substringToIndex:(parentClassName.length - suffix.len
gth)]; | |
| 281 } | |
| 282 NSString *parentPrefix = [parentClassName stringByAppendingString:@"_"]; | |
| 283 if (![className hasPrefix:parentPrefix]) { | |
| 284 NSAssert(0, | |
| 285 @"Class didn't have the correct parent name prefix? (%@ - %@)", | |
| 286 parentPrefix, className); | |
| 287 return nil; | |
| 288 } | |
| 289 name = [className substringFromIndex:parentPrefix.length]; | |
| 290 } else { | |
| 291 name = [className substringFromIndex:objcPrefix.length]; | |
| 292 } | |
| 293 | |
| 294 // The generator will add _Class to avoid reserved words, drop it. | |
| 295 NSString *suffix = objc_getAssociatedObject(self, &kClassNameSuffixKey); | |
| 296 if (suffix) { | |
| 297 if (![name hasSuffix:suffix]) { | |
| 298 NSAssert(0, | |
| 299 @"Message class didn't have correct suffix? (%@ - %@)", | |
| 300 name, suffix); | |
| 301 return nil; | |
| 302 } | |
| 303 name = [name substringToIndex:(name.length - suffix.length)]; | |
| 304 } | |
| 305 | |
| 306 NSString *prefix = (parent != nil ? parent.fullName : file.package); | |
| 307 NSString *result; | |
| 308 if (prefix.length > 0) { | |
| 309 result = [NSString stringWithFormat:@"%@.%@", prefix, name]; | |
| 310 } else { | |
| 311 result = name; | |
| 312 } | |
| 313 return result; | |
| 314 } | |
| 315 | |
| 316 - (id)copyWithZone:(NSZone *)zone { | 216 - (id)copyWithZone:(NSZone *)zone { |
| 317 #pragma unused(zone) | 217 #pragma unused(zone) |
| 318 return [self retain]; | 218 return [self retain]; |
| 319 } | 219 } |
| 320 | 220 |
| 321 - (GPBFieldDescriptor *)fieldWithNumber:(uint32_t)fieldNumber { | 221 - (GPBFieldDescriptor *)fieldWithNumber:(uint32_t)fieldNumber { |
| 322 for (GPBFieldDescriptor *descriptor in fields_) { | 222 for (GPBFieldDescriptor *descriptor in fields_) { |
| 323 if (GPBFieldNumber(descriptor) == fieldNumber) { | 223 if (GPBFieldNumber(descriptor) == fieldNumber) { |
| 324 return descriptor; | 224 return descriptor; |
| 325 } | 225 } |
| (...skipping 16 matching lines...) Expand all Loading... |
| 342 return descriptor; | 242 return descriptor; |
| 343 } | 243 } |
| 344 } | 244 } |
| 345 return nil; | 245 return nil; |
| 346 } | 246 } |
| 347 | 247 |
| 348 @end | 248 @end |
| 349 | 249 |
| 350 @implementation GPBFileDescriptor { | 250 @implementation GPBFileDescriptor { |
| 351 NSString *package_; | 251 NSString *package_; |
| 352 NSString *objcPrefix_; | |
| 353 GPBFileSyntax syntax_; | 252 GPBFileSyntax syntax_; |
| 354 } | 253 } |
| 355 | 254 |
| 356 @synthesize package = package_; | 255 @synthesize package = package_; |
| 357 @synthesize objcPrefix = objcPrefix_; | |
| 358 @synthesize syntax = syntax_; | 256 @synthesize syntax = syntax_; |
| 359 | 257 |
| 360 - (instancetype)initWithPackage:(NSString *)package | 258 - (instancetype)initWithPackage:(NSString *)package |
| 361 objcPrefix:(NSString *)objcPrefix | |
| 362 syntax:(GPBFileSyntax)syntax { | |
| 363 self = [super init]; | |
| 364 if (self) { | |
| 365 package_ = [package copy]; | |
| 366 objcPrefix_ = [objcPrefix copy]; | |
| 367 syntax_ = syntax; | |
| 368 } | |
| 369 return self; | |
| 370 } | |
| 371 | |
| 372 - (instancetype)initWithPackage:(NSString *)package | |
| 373 syntax:(GPBFileSyntax)syntax { | 259 syntax:(GPBFileSyntax)syntax { |
| 374 self = [super init]; | 260 self = [super init]; |
| 375 if (self) { | 261 if (self) { |
| 376 package_ = [package copy]; | 262 package_ = [package copy]; |
| 377 syntax_ = syntax; | 263 syntax_ = syntax; |
| 378 } | 264 } |
| 379 return self; | 265 return self; |
| 380 } | 266 } |
| 381 | 267 |
| 382 - (void)dealloc { | |
| 383 [package_ release]; | |
| 384 [objcPrefix_ release]; | |
| 385 [super dealloc]; | |
| 386 } | |
| 387 | |
| 388 @end | 268 @end |
| 389 | 269 |
| 390 @implementation GPBOneofDescriptor | 270 @implementation GPBOneofDescriptor |
| 391 | 271 |
| 392 @synthesize fields = fields_; | 272 @synthesize fields = fields_; |
| 393 | 273 |
| 394 - (instancetype)initWithName:(const char *)name fields:(NSArray *)fields { | 274 - (instancetype)initWithName:(const char *)name fields:(NSArray *)fields { |
| 395 self = [super init]; | 275 self = [super init]; |
| 396 if (self) { | 276 if (self) { |
| 397 name_ = name; | 277 name_ = name; |
| (...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 518 (coreDesc->hasIndex != GPBNoHasBit) && | 398 (coreDesc->hasIndex != GPBNoHasBit) && |
| 519 ((syntax != GPBFileSyntaxProto3) || isMessage)) { | 399 ((syntax != GPBFileSyntaxProto3) || isMessage)) { |
| 520 hasOrCountSel_ = SelFromStrings("has", coreDesc->name, NULL, NO); | 400 hasOrCountSel_ = SelFromStrings("has", coreDesc->name, NULL, NO); |
| 521 setHasSel_ = SelFromStrings("setHas", coreDesc->name, NULL, YES); | 401 setHasSel_ = SelFromStrings("setHas", coreDesc->name, NULL, YES); |
| 522 } | 402 } |
| 523 } | 403 } |
| 524 | 404 |
| 525 // Extra type specific data. | 405 // Extra type specific data. |
| 526 if (isMessage) { | 406 if (isMessage) { |
| 527 const char *className = coreDesc->dataTypeSpecific.className; | 407 const char *className = coreDesc->dataTypeSpecific.className; |
| 528 // Note: Only fetch the class here, can't send messages to it because | |
| 529 // that could cause cycles back to this class within +initialize if | |
| 530 // two messages have each other in fields (i.e. - they build a graph). | |
| 531 msgClass_ = objc_getClass(className); | 408 msgClass_ = objc_getClass(className); |
| 532 NSAssert(msgClass_, @"Class %s not defined", className); | 409 NSAssert(msgClass_, @"Class %s not defined", className); |
| 533 } else if (dataType == GPBDataTypeEnum) { | 410 } else if (dataType == GPBDataTypeEnum) { |
| 534 if ((coreDesc->flags & GPBFieldHasEnumDescriptor) != 0) { | 411 if ((coreDesc->flags & GPBFieldHasEnumDescriptor) != 0) { |
| 535 enumHandling_.enumDescriptor_ = | 412 enumHandling_.enumDescriptor_ = |
| 536 coreDesc->dataTypeSpecific.enumDescFunc(); | 413 coreDesc->dataTypeSpecific.enumDescFunc(); |
| 537 } else { | 414 } else { |
| 538 enumHandling_.enumVerifier_ = | 415 enumHandling_.enumVerifier_ = |
| 539 coreDesc->dataTypeSpecific.enumVerifier; | 416 coreDesc->dataTypeSpecific.enumVerifier; |
| 540 } | 417 } |
| (...skipping 320 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 861 if (strcmp(nameAsCStr, valueName) == 0) { | 738 if (strcmp(nameAsCStr, valueName) == 0) { |
| 862 if (outValue) { | 739 if (outValue) { |
| 863 *outValue = values_[i]; | 740 *outValue = values_[i]; |
| 864 } | 741 } |
| 865 return YES; | 742 return YES; |
| 866 } | 743 } |
| 867 } | 744 } |
| 868 return NO; | 745 return NO; |
| 869 } | 746 } |
| 870 | 747 |
| 871 - (BOOL)getValue:(int32_t *)outValue forEnumTextFormatName:(NSString *)textForma
tName { | |
| 872 if (nameOffsets_ == NULL) [self calcValueNameOffsets]; | |
| 873 | |
| 874 for (uint32_t i = 0; i < valueCount_; ++i) { | |
| 875 int32_t value = values_[i]; | |
| 876 NSString *valueTextFormatName = [self textFormatNameForValue:value]; | |
| 877 if ([valueTextFormatName isEqual:textFormatName]) { | |
| 878 if (outValue) { | |
| 879 *outValue = value; | |
| 880 } | |
| 881 return YES; | |
| 882 } | |
| 883 } | |
| 884 return NO; | |
| 885 } | |
| 886 | |
| 887 - (NSString *)textFormatNameForValue:(int32_t)number { | 748 - (NSString *)textFormatNameForValue:(int32_t)number { |
| 888 if (nameOffsets_ == NULL) [self calcValueNameOffsets]; | 749 if (nameOffsets_ == NULL) [self calcValueNameOffsets]; |
| 889 | 750 |
| 890 // Find the EnumValue descriptor and its index. | 751 // Find the EnumValue descriptor and its index. |
| 891 BOOL foundIt = NO; | 752 BOOL foundIt = NO; |
| 892 uint32_t valueDescriptorIndex; | 753 uint32_t valueDescriptorIndex; |
| 893 for (valueDescriptorIndex = 0; valueDescriptorIndex < valueCount_; | 754 for (valueDescriptorIndex = 0; valueDescriptorIndex < valueCount_; |
| 894 ++valueDescriptorIndex) { | 755 ++valueDescriptorIndex) { |
| 895 if (values_[valueDescriptorIndex] == number) { | 756 if (values_[valueDescriptorIndex] == number) { |
| 896 foundIt = YES; | 757 foundIt = YES; |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 935 GPBGenericValue defaultValue_; | 796 GPBGenericValue defaultValue_; |
| 936 } | 797 } |
| 937 | 798 |
| 938 @synthesize containingMessageClass = containingMessageClass_; | 799 @synthesize containingMessageClass = containingMessageClass_; |
| 939 | 800 |
| 940 - (instancetype)initWithExtensionDescription: | 801 - (instancetype)initWithExtensionDescription: |
| 941 (GPBExtensionDescription *)description { | 802 (GPBExtensionDescription *)description { |
| 942 if ((self = [super init])) { | 803 if ((self = [super init])) { |
| 943 description_ = description; | 804 description_ = description; |
| 944 | 805 |
| 945 #if defined(DEBUG) && DEBUG | 806 #if DEBUG |
| 946 const char *className = description->messageOrGroupClassName; | 807 const char *className = description->messageOrGroupClassName; |
| 947 if (className) { | 808 if (className) { |
| 948 NSAssert(objc_lookUpClass(className) != Nil, | 809 NSAssert(objc_lookUpClass(className) != Nil, |
| 949 @"Class %s not defined", className); | 810 @"Class %s not defined", className); |
| 950 } | 811 } |
| 951 #endif | 812 #endif |
| 952 | 813 |
| 953 if (description->extendedClass) { | 814 if (description->extendedClass) { |
| 954 Class containingClass = objc_lookUpClass(description->extendedClass); | 815 Class containingClass = objc_lookUpClass(description->extendedClass); |
| 955 NSAssert(containingClass, @"Class %s not defined", | 816 NSAssert(containingClass, @"Class %s not defined", |
| (...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1093 if (selfNumber < otherNumber) { | 954 if (selfNumber < otherNumber) { |
| 1094 return NSOrderedAscending; | 955 return NSOrderedAscending; |
| 1095 } else if (selfNumber == otherNumber) { | 956 } else if (selfNumber == otherNumber) { |
| 1096 return NSOrderedSame; | 957 return NSOrderedSame; |
| 1097 } else { | 958 } else { |
| 1098 return NSOrderedDescending; | 959 return NSOrderedDescending; |
| 1099 } | 960 } |
| 1100 } | 961 } |
| 1101 | 962 |
| 1102 @end | 963 @end |
| 1103 | |
| 1104 #pragma clang diagnostic pop | |
| OLD | NEW |