1ffe3c632Sopenharmony_ci// Protocol Buffers - Google's data interchange format 2ffe3c632Sopenharmony_ci// Copyright 2015 Google Inc. All rights reserved. 3ffe3c632Sopenharmony_ci// https://developers.google.com/protocol-buffers/ 4ffe3c632Sopenharmony_ci// 5ffe3c632Sopenharmony_ci// Redistribution and use in source and binary forms, with or without 6ffe3c632Sopenharmony_ci// modification, are permitted provided that the following conditions are 7ffe3c632Sopenharmony_ci// met: 8ffe3c632Sopenharmony_ci// 9ffe3c632Sopenharmony_ci// * Redistributions of source code must retain the above copyright 10ffe3c632Sopenharmony_ci// notice, this list of conditions and the following disclaimer. 11ffe3c632Sopenharmony_ci// * Redistributions in binary form must reproduce the above 12ffe3c632Sopenharmony_ci// copyright notice, this list of conditions and the following disclaimer 13ffe3c632Sopenharmony_ci// in the documentation and/or other materials provided with the 14ffe3c632Sopenharmony_ci// distribution. 15ffe3c632Sopenharmony_ci// * Neither the name of Google Inc. nor the names of its 16ffe3c632Sopenharmony_ci// contributors may be used to endorse or promote products derived from 17ffe3c632Sopenharmony_ci// this software without specific prior written permission. 18ffe3c632Sopenharmony_ci// 19ffe3c632Sopenharmony_ci// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20ffe3c632Sopenharmony_ci// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21ffe3c632Sopenharmony_ci// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22ffe3c632Sopenharmony_ci// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23ffe3c632Sopenharmony_ci// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24ffe3c632Sopenharmony_ci// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25ffe3c632Sopenharmony_ci// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26ffe3c632Sopenharmony_ci// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27ffe3c632Sopenharmony_ci// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28ffe3c632Sopenharmony_ci// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29ffe3c632Sopenharmony_ci// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30ffe3c632Sopenharmony_ci 31ffe3c632Sopenharmony_ci#import "GPBTestUtilities.h" 32ffe3c632Sopenharmony_ci 33ffe3c632Sopenharmony_ci#import <objc/runtime.h> 34ffe3c632Sopenharmony_ci 35ffe3c632Sopenharmony_ci#import "GPBDescriptor_PackagePrivate.h" 36ffe3c632Sopenharmony_ci#import "GPBExtensionRegistry.h" 37ffe3c632Sopenharmony_ci#import "GPBMessage.h" 38ffe3c632Sopenharmony_ci#import "GPBRootObject_PackagePrivate.h" 39ffe3c632Sopenharmony_ci 40ffe3c632Sopenharmony_ci// Support classes for tests using old class name (vs classrefs) interfaces. 41ffe3c632Sopenharmony_ciGPB_FINAL @interface MessageLackingClazzRoot : GPBRootObject 42ffe3c632Sopenharmony_ci@end 43ffe3c632Sopenharmony_ci 44ffe3c632Sopenharmony_ci@interface MessageLackingClazzRoot (DynamicMethods) 45ffe3c632Sopenharmony_ci+ (GPBExtensionDescriptor *)ext1; 46ffe3c632Sopenharmony_ci@end 47ffe3c632Sopenharmony_ci 48ffe3c632Sopenharmony_ciGPB_FINAL @interface MessageLackingClazz : GPBMessage 49ffe3c632Sopenharmony_ci@property(copy, nonatomic) NSString *foo; 50ffe3c632Sopenharmony_ci@end 51ffe3c632Sopenharmony_ci 52ffe3c632Sopenharmony_ci@implementation MessageLackingClazz 53ffe3c632Sopenharmony_ci 54ffe3c632Sopenharmony_ci@dynamic foo; 55ffe3c632Sopenharmony_ci 56ffe3c632Sopenharmony_citypedef struct MessageLackingClazz_storage_ { 57ffe3c632Sopenharmony_ci uint32_t _has_storage_[1]; 58ffe3c632Sopenharmony_ci NSString *foo; 59ffe3c632Sopenharmony_ci} MessageLackingClazz_storage_; 60ffe3c632Sopenharmony_ci 61ffe3c632Sopenharmony_ci+ (GPBDescriptor *)descriptor { 62ffe3c632Sopenharmony_ci static GPBDescriptor *descriptor = nil; 63ffe3c632Sopenharmony_ci if (!descriptor) { 64ffe3c632Sopenharmony_ci static GPBMessageFieldDescription fields[] = { 65ffe3c632Sopenharmony_ci { 66ffe3c632Sopenharmony_ci .name = "foo", 67ffe3c632Sopenharmony_ci .dataTypeSpecific.className = "NSString", 68ffe3c632Sopenharmony_ci .number = 1, 69ffe3c632Sopenharmony_ci .hasIndex = 0, 70ffe3c632Sopenharmony_ci .offset = (uint32_t)offsetof(MessageLackingClazz_storage_, foo), 71ffe3c632Sopenharmony_ci .flags = (GPBFieldFlags)(GPBFieldOptional), 72ffe3c632Sopenharmony_ci .dataType = GPBDataTypeMessage, 73ffe3c632Sopenharmony_ci }, 74ffe3c632Sopenharmony_ci }; 75ffe3c632Sopenharmony_ci GPBFileDescriptor *desc = 76ffe3c632Sopenharmony_ci [[[GPBFileDescriptor alloc] initWithPackage:@"test" 77ffe3c632Sopenharmony_ci objcPrefix:@"TEST" 78ffe3c632Sopenharmony_ci syntax:GPBFileSyntaxProto3] autorelease]; 79ffe3c632Sopenharmony_ci 80ffe3c632Sopenharmony_ci // GPBDescriptorInitializationFlag_UsesClassRefs intentionally not set here 81ffe3c632Sopenharmony_ci descriptor = 82ffe3c632Sopenharmony_ci [GPBDescriptor allocDescriptorForClass:[MessageLackingClazz class] 83ffe3c632Sopenharmony_ci rootClass:[MessageLackingClazzRoot class] 84ffe3c632Sopenharmony_ci file:desc 85ffe3c632Sopenharmony_ci fields:fields 86ffe3c632Sopenharmony_ci fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription)) 87ffe3c632Sopenharmony_ci storageSize:sizeof(MessageLackingClazz_storage_) 88ffe3c632Sopenharmony_ci flags:GPBDescriptorInitializationFlag_None]; 89ffe3c632Sopenharmony_ci [descriptor setupContainingMessageClassName:"MessageLackingClazz"]; 90ffe3c632Sopenharmony_ci } 91ffe3c632Sopenharmony_ci return descriptor; 92ffe3c632Sopenharmony_ci} 93ffe3c632Sopenharmony_ci@end 94ffe3c632Sopenharmony_ci 95ffe3c632Sopenharmony_ci@implementation MessageLackingClazzRoot 96ffe3c632Sopenharmony_ci 97ffe3c632Sopenharmony_ci+ (GPBExtensionRegistry*)extensionRegistry { 98ffe3c632Sopenharmony_ci // This is called by +initialize so there is no need to worry 99ffe3c632Sopenharmony_ci // about thread safety and initialization of registry. 100ffe3c632Sopenharmony_ci static GPBExtensionRegistry* registry = nil; 101ffe3c632Sopenharmony_ci if (!registry) { 102ffe3c632Sopenharmony_ci registry = [[GPBExtensionRegistry alloc] init]; 103ffe3c632Sopenharmony_ci static GPBExtensionDescription descriptions[] = { 104ffe3c632Sopenharmony_ci { 105ffe3c632Sopenharmony_ci .defaultValue.valueMessage = NULL, 106ffe3c632Sopenharmony_ci .singletonName = "MessageLackingClazzRoot_ext1", 107ffe3c632Sopenharmony_ci .extendedClass.name = "MessageLackingClazz", 108ffe3c632Sopenharmony_ci .messageOrGroupClass.name = "MessageLackingClazz", 109ffe3c632Sopenharmony_ci .enumDescriptorFunc = NULL, 110ffe3c632Sopenharmony_ci .fieldNumber = 1, 111ffe3c632Sopenharmony_ci .dataType = GPBDataTypeMessage, 112ffe3c632Sopenharmony_ci // GPBExtensionUsesClazz Intentionally not set 113ffe3c632Sopenharmony_ci .options = 0, 114ffe3c632Sopenharmony_ci }, 115ffe3c632Sopenharmony_ci }; 116ffe3c632Sopenharmony_ci for (size_t i = 0; i < sizeof(descriptions) / sizeof(descriptions[0]); ++i) { 117ffe3c632Sopenharmony_ci // Intentionall using `-initWithExtensionDescription:` and not ` 118ffe3c632Sopenharmony_ci // -initWithExtensionDescription:usesClassRefs:` to test backwards 119ffe3c632Sopenharmony_ci // compatibility 120ffe3c632Sopenharmony_ci GPBExtensionDescriptor *extension = 121ffe3c632Sopenharmony_ci [[GPBExtensionDescriptor alloc] initWithExtensionDescription:&descriptions[i]]; 122ffe3c632Sopenharmony_ci [registry addExtension:extension]; 123ffe3c632Sopenharmony_ci [self globallyRegisterExtension:extension]; 124ffe3c632Sopenharmony_ci [extension release]; 125ffe3c632Sopenharmony_ci } 126ffe3c632Sopenharmony_ci // None of the imports (direct or indirect) defined extensions, so no need to add 127ffe3c632Sopenharmony_ci // them to this registry. 128ffe3c632Sopenharmony_ci } 129ffe3c632Sopenharmony_ci return registry; 130ffe3c632Sopenharmony_ci} 131ffe3c632Sopenharmony_ci@end 132ffe3c632Sopenharmony_ci 133ffe3c632Sopenharmony_ci@interface MessageClassNameTests : GPBTestCase 134ffe3c632Sopenharmony_ci@end 135ffe3c632Sopenharmony_ci 136ffe3c632Sopenharmony_ci@implementation MessageClassNameTests 137ffe3c632Sopenharmony_ci 138ffe3c632Sopenharmony_ci- (void)testClassNameSupported { 139ffe3c632Sopenharmony_ci // This tests backwards compatibility to make sure we support older sources 140ffe3c632Sopenharmony_ci // that use class names instead of references. 141ffe3c632Sopenharmony_ci GPBDescriptor *desc = [MessageLackingClazz descriptor]; 142ffe3c632Sopenharmony_ci GPBFieldDescriptor *fieldDesc = [desc fieldWithName:@"foo"]; 143ffe3c632Sopenharmony_ci XCTAssertEqualObjects(fieldDesc.msgClass, [NSString class]); 144ffe3c632Sopenharmony_ci} 145ffe3c632Sopenharmony_ci 146ffe3c632Sopenharmony_ci- (void)testSetupContainingMessageClassNameSupported { 147ffe3c632Sopenharmony_ci // This tests backwards compatibility to make sure we support older sources 148ffe3c632Sopenharmony_ci // that use class names instead of references. 149ffe3c632Sopenharmony_ci GPBDescriptor *desc = [MessageLackingClazz descriptor]; 150ffe3c632Sopenharmony_ci GPBDescriptor *container = [desc containingType]; 151ffe3c632Sopenharmony_ci XCTAssertEqualObjects(container.messageClass, [MessageLackingClazz class]); 152ffe3c632Sopenharmony_ci} 153ffe3c632Sopenharmony_ci 154ffe3c632Sopenharmony_ci- (void)testExtensionsNameSupported { 155ffe3c632Sopenharmony_ci // This tests backwards compatibility to make sure we support older sources 156ffe3c632Sopenharmony_ci // that use class names instead of references. 157ffe3c632Sopenharmony_ci GPBExtensionDescriptor *desc = [MessageLackingClazzRoot ext1]; 158ffe3c632Sopenharmony_ci Class containerClass = [desc containingMessageClass]; 159ffe3c632Sopenharmony_ci XCTAssertEqualObjects(containerClass, [MessageLackingClazz class]); 160ffe3c632Sopenharmony_ci Class msgClass = [desc msgClass]; 161ffe3c632Sopenharmony_ci XCTAssertEqualObjects(msgClass, [MessageLackingClazz class]); 162ffe3c632Sopenharmony_ci} 163ffe3c632Sopenharmony_ci 164ffe3c632Sopenharmony_ci@end 165