1// Protocol Buffers - Google's data interchange format 2// Copyright 2015 Google Inc. All rights reserved. 3// 4// Use of this source code is governed by a BSD-style 5// license that can be found in the LICENSE file or at 6// https://developers.google.com/open-source/licenses/bsd 7 8#import <objc/runtime.h> 9 10#import "GPBDescriptor_PackagePrivate.h" 11#import "GPBExtensionRegistry.h" 12#import "GPBMessage.h" 13#import "GPBRootObject_PackagePrivate.h" 14#import "GPBTestUtilities.h" 15 16#pragma clang diagnostic push 17#pragma clang diagnostic ignored "-Wdeprecated-declarations" 18 19// Support classes for tests using old class name (vs classrefs) interfaces. 20GPB_FINAL @interface MessageLackingClazzRoot : GPBRootObject 21@end 22 23@interface MessageLackingClazzRoot (DynamicMethods) 24+ (GPBExtensionDescriptor *)ext1; 25@end 26 27GPB_FINAL @interface MessageLackingClazz : GPBMessage 28@property(copy, nonatomic) NSString *foo; 29@end 30 31@implementation MessageLackingClazz 32 33@dynamic foo; 34 35typedef struct MessageLackingClazz_storage_ { 36 uint32_t _has_storage_[1]; 37 NSString *foo; 38} MessageLackingClazz_storage_; 39 40+ (GPBDescriptor *)descriptor { 41 static GPBDescriptor *descriptor = nil; 42 if (!descriptor) { 43 static GPBMessageFieldDescription fields[] = { 44 { 45 .name = "foo", 46 .dataTypeSpecific.className = "NSString", 47 .number = 1, 48 .hasIndex = 0, 49 .offset = (uint32_t)offsetof(MessageLackingClazz_storage_, foo), 50 .flags = (GPBFieldFlags)(GPBFieldOptional), 51 .dataType = GPBDataTypeMessage, 52 }, 53 }; 54 GPBFileDescriptor *desc = 55 [[[GPBFileDescriptor alloc] initWithPackage:@"test" 56 objcPrefix:@"TEST" 57 syntax:GPBFileSyntaxProto3] autorelease]; 58 59 // GPBDescriptorInitializationFlag_UsesClassRefs intentionally not set here 60 descriptor = [GPBDescriptor 61 allocDescriptorForClass:[MessageLackingClazz class] 62 rootClass:[MessageLackingClazzRoot class] 63 file:desc 64 fields:fields 65 fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription)) 66 storageSize:sizeof(MessageLackingClazz_storage_) 67 flags:GPBDescriptorInitializationFlag_None]; 68 [descriptor setupContainingMessageClassName:"MessageLackingClazz"]; 69 } 70 return descriptor; 71} 72@end 73 74@implementation MessageLackingClazzRoot 75 76+ (GPBExtensionRegistry *)extensionRegistry { 77 // This is called by +initialize so there is no need to worry 78 // about thread safety and initialization of registry. 79 static GPBExtensionRegistry *registry = nil; 80 if (!registry) { 81 registry = [[GPBExtensionRegistry alloc] init]; 82 static GPBExtensionDescription descriptions[] = { 83 { 84 .defaultValue.valueMessage = NULL, 85 .singletonName = "MessageLackingClazzRoot_ext1", 86 .extendedClass.name = "MessageLackingClazz", 87 .messageOrGroupClass.name = "MessageLackingClazz", 88 .enumDescriptorFunc = NULL, 89 .fieldNumber = 1, 90 .dataType = GPBDataTypeMessage, 91 // GPBExtensionUsesClazz Intentionally not set 92 .options = 0, 93 }, 94 }; 95 for (size_t i = 0; i < sizeof(descriptions) / sizeof(descriptions[0]); ++i) { 96 // Intentionall using `-initWithExtensionDescription:` and not ` 97 // -initWithExtensionDescription:usesClassRefs:` to test backwards 98 // compatibility 99 GPBExtensionDescriptor *extension = 100 [[GPBExtensionDescriptor alloc] initWithExtensionDescription:&descriptions[i]]; 101 [registry addExtension:extension]; 102 [self globallyRegisterExtension:extension]; 103 [extension release]; 104 } 105 // None of the imports (direct or indirect) defined extensions, so no need to add 106 // them to this registry. 107 } 108 return registry; 109} 110@end 111 112#pragma clang diagnostic pop 113 114@interface MessageClassNameTests : GPBTestCase 115@end 116 117@implementation MessageClassNameTests 118 119- (void)testClassNameSupported { 120 // This tests backwards compatibility to make sure we support older sources 121 // that use class names instead of references. 122 GPBDescriptor *desc = [MessageLackingClazz descriptor]; 123 GPBFieldDescriptor *fieldDesc = [desc fieldWithName:@"foo"]; 124 XCTAssertEqualObjects(fieldDesc.msgClass, [NSString class]); 125} 126 127- (void)testSetupContainingMessageClassNameSupported { 128 // This tests backwards compatibility to make sure we support older sources 129 // that use class names instead of references. 130 GPBDescriptor *desc = [MessageLackingClazz descriptor]; 131 GPBDescriptor *container = [desc containingType]; 132 XCTAssertEqualObjects(container.messageClass, [MessageLackingClazz class]); 133} 134 135- (void)testExtensionsNameSupported { 136 // This tests backwards compatibility to make sure we support older sources 137 // that use class names instead of references. 138 GPBExtensionDescriptor *desc = [MessageLackingClazzRoot ext1]; 139 Class containerClass = [desc containingMessageClass]; 140 XCTAssertEqualObjects(containerClass, [MessageLackingClazz class]); 141 Class msgClass = [desc msgClass]; 142 XCTAssertEqualObjects(msgClass, [MessageLackingClazz class]); 143} 144 145@end 146