• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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