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