GPBMessageTests+ClassNames.m 6.4 KB

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