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 |