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