xref: /aosp_15_r20/external/protobuf/objectivec/Tests/GPBMessageTests.m (revision 1b3f573f81763fcece89efc2b6a5209149e44ab8)
1// Protocol Buffers - Google's data interchange format
2// Copyright 2008 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
31#import "GPBTestUtilities.h"
32
33#import <objc/runtime.h>
34
35#import "GPBArray_PackagePrivate.h"
36#import "GPBDescriptor.h"
37#import "GPBDictionary_PackagePrivate.h"
38#import "GPBMessage_PackagePrivate.h"
39#import "GPBUnknownField_PackagePrivate.h"
40#import "GPBUnknownFieldSet_PackagePrivate.h"
41#import "google/protobuf/Unittest.pbobjc.h"
42#import "google/protobuf/UnittestObjc.pbobjc.h"
43#import "google/protobuf/UnittestObjcOptions.pbobjc.h"
44#import "google/protobuf/UnittestImport.pbobjc.h"
45
46// Helper class to test KVO.
47@interface GPBKVOTestObserver : NSObject {
48  id observee_;
49  NSString *keyPath_;
50}
51
52@property (nonatomic) BOOL didObserve;
53- (id)initWithObservee:(id)observee keyPath:(NSString *)keyPath;
54@end
55
56@implementation GPBKVOTestObserver
57
58@synthesize didObserve;
59
60- (id)initWithObservee:(id)observee keyPath:(NSString *)keyPath {
61  if (self = [super init]) {
62    observee_ = [observee retain];
63    keyPath_ = [keyPath copy];
64    [observee_ addObserver:self forKeyPath:keyPath_ options:0 context:NULL];
65  }
66  return self;
67}
68
69- (void)dealloc {
70  [observee_ removeObserver:self forKeyPath:keyPath_];
71  [observee_ release];
72  [keyPath_ release];
73  [super dealloc];
74}
75
76- (void)observeValueForKeyPath:(NSString *)keyPath
77                      ofObject:(id)object
78                        change:(NSDictionary *)change
79                       context:(void *)context
80{
81#pragma unused(object)
82#pragma unused(change)
83#pragma unused(context)
84  if ([keyPath isEqualToString:keyPath_]) {
85    self.didObserve = YES;
86  }
87}
88
89@end
90
91@interface MessageTests : GPBTestCase
92@end
93
94@implementation MessageTests
95
96// TODO(thomasvl): this should get split into a few files of logic junks, it is
97// a jumble of things at the moment (and the testutils have a bunch of the real
98// assertions).
99
100- (TestAllTypes *)mergeSource {
101  TestAllTypes *message = [TestAllTypes message];
102  [message setOptionalInt32:1];
103  [message setOptionalString:@"foo"];
104  [message setOptionalForeignMessage:[ForeignMessage message]];
105  [message.repeatedStringArray addObject:@"bar"];
106  return message;
107}
108
109- (TestAllTypes *)mergeDestination {
110  TestAllTypes *message = [TestAllTypes message];
111  [message setOptionalInt64:2];
112  [message setOptionalString:@"baz"];
113  ForeignMessage *foreignMessage = [ForeignMessage message];
114  [foreignMessage setC:3];
115  [message setOptionalForeignMessage:foreignMessage];
116  [message.repeatedStringArray addObject:@"qux"];
117  return message;
118}
119
120- (TestAllTypes *)mergeDestinationWithoutForeignMessageIvar {
121  TestAllTypes *message = [TestAllTypes message];
122  [message setOptionalInt64:2];
123  [message setOptionalString:@"baz"];
124  [message.repeatedStringArray addObject:@"qux"];
125  return message;
126}
127
128- (TestAllTypes *)mergeResult {
129  TestAllTypes *message = [TestAllTypes message];
130  [message setOptionalInt32:1];
131  [message setOptionalInt64:2];
132  [message setOptionalString:@"foo"];
133  ForeignMessage *foreignMessage = [ForeignMessage message];
134  [foreignMessage setC:3];
135  [message setOptionalForeignMessage:foreignMessage];
136  [message.repeatedStringArray addObject:@"qux"];
137  [message.repeatedStringArray addObject:@"bar"];
138  return message;
139}
140
141- (TestAllTypes *)mergeResultForDestinationWithoutForeignMessageIvar {
142  TestAllTypes *message = [TestAllTypes message];
143  [message setOptionalInt32:1];
144  [message setOptionalInt64:2];
145  [message setOptionalString:@"foo"];
146  ForeignMessage *foreignMessage = [ForeignMessage message];
147  [message setOptionalForeignMessage:foreignMessage];
148  [message.repeatedStringArray addObject:@"qux"];
149  [message.repeatedStringArray addObject:@"bar"];
150  return message;
151}
152
153- (TestAllExtensions *)mergeExtensionsDestination {
154  TestAllExtensions *message = [TestAllExtensions message];
155  [message setExtension:[UnittestRoot optionalInt32Extension] value:@5];
156  [message setExtension:[UnittestRoot optionalStringExtension] value:@"foo"];
157  ForeignMessage *foreignMessage = [ForeignMessage message];
158  foreignMessage.c = 4;
159  [message setExtension:[UnittestRoot optionalForeignMessageExtension]
160                  value:foreignMessage];
161  TestAllTypes_NestedMessage *nestedMessage =
162      [TestAllTypes_NestedMessage message];
163  [message setExtension:[UnittestRoot optionalNestedMessageExtension]
164                  value:nestedMessage];
165  return message;
166}
167
168- (TestAllExtensions *)mergeExtensionsSource {
169  TestAllExtensions *message = [TestAllExtensions message];
170  [message setExtension:[UnittestRoot optionalInt64Extension] value:@6];
171  [message setExtension:[UnittestRoot optionalStringExtension] value:@"bar"];
172  ForeignMessage *foreignMessage = [ForeignMessage message];
173  [message setExtension:[UnittestRoot optionalForeignMessageExtension]
174                  value:foreignMessage];
175  TestAllTypes_NestedMessage *nestedMessage =
176      [TestAllTypes_NestedMessage message];
177  nestedMessage.bb = 7;
178  [message setExtension:[UnittestRoot optionalNestedMessageExtension]
179                  value:nestedMessage];
180  return message;
181}
182
183- (TestAllExtensions *)mergeExtensionsResult {
184  TestAllExtensions *message = [TestAllExtensions message];
185  [message setExtension:[UnittestRoot optionalInt32Extension] value:@5];
186  [message setExtension:[UnittestRoot optionalInt64Extension] value:@6];
187  [message setExtension:[UnittestRoot optionalStringExtension] value:@"bar"];
188  ForeignMessage *foreignMessage = [ForeignMessage message];
189  foreignMessage.c = 4;
190  [message setExtension:[UnittestRoot optionalForeignMessageExtension]
191                  value:foreignMessage];
192  TestAllTypes_NestedMessage *nestedMessage =
193      [TestAllTypes_NestedMessage message];
194  nestedMessage.bb = 7;
195  [message setExtension:[UnittestRoot optionalNestedMessageExtension]
196                  value:nestedMessage];
197  return message;
198}
199
200- (void)testMergeFrom {
201  TestAllTypes *result = [[self.mergeDestination copy] autorelease];
202  [result mergeFrom:self.mergeSource];
203  NSData *resultData = [result data];
204  NSData *mergeResultData = [self.mergeResult data];
205  XCTAssertEqualObjects(resultData, mergeResultData);
206  XCTAssertEqualObjects(result, self.mergeResult);
207
208  // Test when destination does not have an Ivar (type is an object) but source
209  // has such Ivar.
210  // The result must has the Ivar which is same as the one in source.
211  result = [[self.mergeDestinationWithoutForeignMessageIvar copy] autorelease];
212  [result mergeFrom:self.mergeSource];
213  resultData = [result data];
214  mergeResultData =
215      [self.mergeResultForDestinationWithoutForeignMessageIvar data];
216  XCTAssertEqualObjects(resultData, mergeResultData);
217  XCTAssertEqualObjects(
218      result, self.mergeResultForDestinationWithoutForeignMessageIvar);
219
220  // Test when destination is empty.
221  // The result must is same as the source.
222  result = [TestAllTypes message];
223  [result mergeFrom:self.mergeSource];
224  resultData = [result data];
225  mergeResultData = [self.mergeSource data];
226  XCTAssertEqualObjects(resultData, mergeResultData);
227  XCTAssertEqualObjects(result, self.mergeSource);
228}
229
230- (void)testMergeFromWithExtensions {
231  TestAllExtensions *result = [self mergeExtensionsDestination];
232  [result mergeFrom:[self mergeExtensionsSource]];
233  NSData *resultData = [result data];
234  NSData *mergeResultData = [[self mergeExtensionsResult] data];
235  XCTAssertEqualObjects(resultData, mergeResultData);
236  XCTAssertEqualObjects(result, [self mergeExtensionsResult]);
237
238  // Test merging from data.
239  result = [self mergeExtensionsDestination];
240  NSData *data = [[self mergeExtensionsSource] data];
241  XCTAssertNotNil(data);
242  [result mergeFromData:data
243      extensionRegistry:[UnittestRoot extensionRegistry]];
244  resultData = [result data];
245  XCTAssertEqualObjects(resultData, mergeResultData);
246  XCTAssertEqualObjects(result, [self mergeExtensionsResult]);
247}
248
249- (void)testIsEquals {
250  TestAllTypes *result = [[self.mergeDestination copy] autorelease];
251  [result mergeFrom:self.mergeSource];
252  XCTAssertEqualObjects(result.data, self.mergeResult.data);
253  XCTAssertEqualObjects(result, self.mergeResult);
254  TestAllTypes *result2 = [[self.mergeDestination copy] autorelease];
255  XCTAssertNotEqualObjects(result2.data, self.mergeResult.data);
256  XCTAssertNotEqualObjects(result2, self.mergeResult);
257}
258
259// =================================================================
260// Required-field-related tests.
261
262- (TestRequired *)testRequiredInitialized {
263  TestRequired *message = [TestRequired message];
264  [message setA:1];
265  [message setB:2];
266  [message setC:3];
267  return message;
268}
269
270- (void)testRequired {
271  TestRequired *message = [TestRequired message];
272
273  XCTAssertFalse(message.initialized);
274  [message setA:1];
275  XCTAssertFalse(message.initialized);
276  [message setB:1];
277  XCTAssertFalse(message.initialized);
278  [message setC:1];
279  XCTAssertTrue(message.initialized);
280}
281
282- (void)testRequiredForeign {
283  TestRequiredForeign *message = [TestRequiredForeign message];
284
285  XCTAssertTrue(message.initialized);
286
287  [message setOptionalMessage:[TestRequired message]];
288  XCTAssertFalse(message.initialized);
289
290  [message setOptionalMessage:self.testRequiredInitialized];
291  XCTAssertTrue(message.initialized);
292
293  [message.repeatedMessageArray addObject:[TestRequired message]];
294  XCTAssertFalse(message.initialized);
295
296  [message.repeatedMessageArray removeAllObjects];
297  [message.repeatedMessageArray addObject:self.testRequiredInitialized];
298  XCTAssertTrue(message.initialized);
299}
300
301- (void)testRequiredExtension {
302  TestAllExtensions *message = [TestAllExtensions message];
303
304  XCTAssertTrue(message.initialized);
305
306  [message setExtension:[TestRequired single] value:[TestRequired message]];
307  XCTAssertFalse(message.initialized);
308
309  [message setExtension:[TestRequired single]
310                  value:self.testRequiredInitialized];
311  XCTAssertTrue(message.initialized);
312
313  [message addExtension:[TestRequired multi] value:[TestRequired message]];
314  XCTAssertFalse(message.initialized);
315
316  [message setExtension:[TestRequired multi]
317                  index:0
318                  value:self.testRequiredInitialized];
319  XCTAssertTrue(message.initialized);
320}
321
322- (void)testDataFromUninitialized {
323  TestRequired *message = [TestRequired message];
324  NSData *data = [message data];
325  // In DEBUG, the data generation will fail, but in non DEBUG, it passes
326  // because the check isn't done (for speed).
327#ifdef DEBUG
328  XCTAssertNil(data);
329#else
330  XCTAssertNotNil(data);
331  XCTAssertFalse(message.initialized);
332#endif  // DEBUG
333}
334
335- (void)testInitialized {
336  // We're mostly testing that no exception is thrown.
337  TestRequired *message = [TestRequired message];
338  XCTAssertFalse(message.initialized);
339}
340
341- (void)testDataFromNestedUninitialized {
342  TestRequiredForeign *message = [TestRequiredForeign message];
343  [message setOptionalMessage:[TestRequired message]];
344  [message.repeatedMessageArray addObject:[TestRequired message]];
345  [message.repeatedMessageArray addObject:[TestRequired message]];
346  NSData *data = [message data];
347  // In DEBUG, the data generation will fail, but in non DEBUG, it passes
348  // because the check isn't done (for speed).
349#ifdef DEBUG
350  XCTAssertNil(data);
351#else
352  XCTAssertNotNil(data);
353  XCTAssertFalse(message.initialized);
354#endif  // DEBUG
355}
356
357- (void)testNestedInitialized {
358  // We're mostly testing that no exception is thrown.
359
360  TestRequiredForeign *message = [TestRequiredForeign message];
361  [message setOptionalMessage:[TestRequired message]];
362  [message.repeatedMessageArray addObject:[TestRequired message]];
363  [message.repeatedMessageArray addObject:[TestRequired message]];
364
365  XCTAssertFalse(message.initialized);
366}
367
368- (void)testParseUninitialized {
369  NSError *error = nil;
370  TestRequired *msg =
371      [TestRequired parseFromData:GPBEmptyNSData() error:&error];
372  // In DEBUG, the parse will fail, but in non DEBUG, it passes because
373  // the check isn't done (for speed).
374#ifdef DEBUG
375  XCTAssertNil(msg);
376  XCTAssertNotNil(error);
377  XCTAssertEqualObjects(error.domain, GPBMessageErrorDomain);
378  XCTAssertEqual(error.code, GPBMessageErrorCodeMissingRequiredField);
379#else
380  XCTAssertNotNil(msg);
381  XCTAssertNil(error);
382  XCTAssertFalse(msg.initialized);
383#endif  // DEBUG
384}
385
386#pragma clang diagnostic push
387#pragma clang diagnostic ignored "-Wdeprecated-declarations"
388
389- (void)testCoding {
390  GPBMessage *original = [self mergeResult];
391  NSData *data =
392      [NSKeyedArchiver archivedDataWithRootObject:original];
393  id unarchivedObject = [NSKeyedUnarchiver unarchiveObjectWithData:data];
394
395  XCTAssertEqualObjects(unarchivedObject, original);
396
397  // Intentionally doing a pointer comparison.
398  XCTAssertNotEqual(unarchivedObject, original);
399}
400
401- (void)testSecureCoding {
402  GPBMessage *original = [self mergeResult];
403
404  NSString *key = @"testing123";
405
406  NSMutableData *data = [NSMutableData data];
407  NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:data];
408  [archiver setRequiresSecureCoding:YES];
409  [archiver encodeObject:original forKey:key];
410  [archiver finishEncoding];
411
412  NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:data];
413  [unarchiver setRequiresSecureCoding:YES];
414  id unarchivedObject = [unarchiver decodeObjectOfClass:[GPBMessage class]
415                                                 forKey:key];
416  [unarchiver finishDecoding];
417
418  XCTAssertEqualObjects(unarchivedObject, original);
419
420  // Intentionally doing a pointer comparison.
421  XCTAssertNotEqual(unarchivedObject, original);
422}
423
424#pragma clang diagnostic pop
425
426- (void)testObjectReset {
427  // Tests a failure where clearing out defaults values caused an over release.
428  TestAllTypes *message = [TestAllTypes message];
429  message.hasOptionalNestedMessage = NO;
430  [message setOptionalNestedMessage:[TestAllTypes_NestedMessage message]];
431  message.hasOptionalNestedMessage = NO;
432  [message setOptionalNestedMessage:[TestAllTypes_NestedMessage message]];
433  [message setOptionalNestedMessage:nil];
434  message.hasOptionalNestedMessage = NO;
435}
436
437- (void)testSettingHasToYes {
438  TestAllTypes *message = [TestAllTypes message];
439  XCTAssertThrows([message setHasOptionalNestedMessage:YES]);
440}
441
442- (void)testRoot {
443  XCTAssertNotNil([UnittestRoot extensionRegistry]);
444}
445
446- (void)testGPBMessageSize {
447  // See the note in GPBMessage_PackagePrivate.h about why we want to keep the
448  // base instance size pointer size aligned.
449  size_t messageSize = class_getInstanceSize([GPBMessage class]);
450  XCTAssertEqual((messageSize % sizeof(void *)), (size_t)0,
451                 @"Base size isn't pointer size aligned");
452
453  // Since we add storage ourselves (see +allocWithZone: in GPBMessage), confirm
454  // that the size of some generated classes is still the same as the base for
455  // that logic to work as desired.
456  size_t testMessageSize = class_getInstanceSize([TestAllTypes class]);
457  XCTAssertEqual(testMessageSize, messageSize);
458}
459
460- (void)testInit {
461  TestAllTypes *message = [TestAllTypes message];
462  [self assertClear:message];
463}
464
465- (void)testAccessors {
466  TestAllTypes *message = [TestAllTypes message];
467  [self setAllFields:message repeatedCount:kGPBDefaultRepeatCount];
468  [self assertAllFieldsSet:message repeatedCount:kGPBDefaultRepeatCount];
469}
470
471- (void)testKVC_ValueForKey {
472  TestAllTypes *message = [TestAllTypes message];
473  [self setAllFields:message repeatedCount:kGPBDefaultRepeatCount];
474  [self assertAllFieldsKVCMatch:message];
475}
476
477- (void)testKVC_SetValue_ForKey {
478  TestAllTypes *message = [TestAllTypes message];
479  [self setAllFieldsViaKVC:message repeatedCount:kGPBDefaultRepeatCount];
480  [self assertAllFieldsKVCMatch:message];
481  [self assertAllFieldsSet:message repeatedCount:kGPBDefaultRepeatCount];
482  [self assertAllFieldsKVCMatch:message];
483}
484
485- (void)testKVOBasic {
486  TestAllTypes *message = [TestAllTypes message];
487  GPBKVOTestObserver *observer =
488      [[[GPBKVOTestObserver alloc] initWithObservee:message
489                                            keyPath:@"optionalString"]
490       autorelease];
491  XCTAssertFalse(observer.didObserve);
492  message.defaultString = @"Hello";
493  XCTAssertFalse(observer.didObserve);
494  message.optionalString = @"Hello";
495  XCTAssertTrue(observer.didObserve);
496}
497
498- (void)testKVOAutocreate {
499  TestAllTypes *message = [TestAllTypes message];
500  GPBKVOTestObserver *autocreateObserver =
501      [[[GPBKVOTestObserver alloc] initWithObservee:message
502                                            keyPath:@"optionalImportMessage"]
503       autorelease];
504 GPBKVOTestObserver *innerFieldObserver =
505     [[[GPBKVOTestObserver alloc] initWithObservee:message
506                                           keyPath:@"optionalImportMessage.d"]
507      autorelease];
508  XCTAssertFalse(autocreateObserver.didObserve);
509  XCTAssertFalse(innerFieldObserver.didObserve);
510
511  int a = message.optionalImportMessage.d;
512  XCTAssertEqual(a, 0);
513
514  // Autocreation of fields is not observed by KVO when getting values.
515  XCTAssertFalse(autocreateObserver.didObserve);
516  XCTAssertFalse(innerFieldObserver.didObserve);
517
518  message.optionalImportMessage.d = 2;
519
520  // Autocreation of fields is not observed by KVO.
521  // This is undefined behavior. The library makes no guarantees with regards
522  // to KVO firing if an autocreation occurs as part of a setter.
523  // This test exists just to be aware if the behavior changes.
524  XCTAssertFalse(autocreateObserver.didObserve);
525
526  // Values set inside of an autocreated field are observed.
527  XCTAssertTrue(innerFieldObserver.didObserve);
528
529  // Explicit setting of a message field is observed.
530  message.optionalImportMessage = [ImportMessage message];
531  XCTAssertTrue(autocreateObserver.didObserve);
532}
533
534- (void)testDescription {
535  // No real test, just exercise code
536  TestAllTypes *message = [TestAllTypes message];
537  [self setAllFields:message repeatedCount:kGPBDefaultRepeatCount];
538
539  GPBUnknownFieldSet *unknownFields =
540      [[[GPBUnknownFieldSet alloc] init] autorelease];
541  GPBUnknownField *field =
542      [[[GPBUnknownField alloc] initWithNumber:2] autorelease];
543  [field addVarint:2];
544  [unknownFields addField:field];
545  field = [[[GPBUnknownField alloc] initWithNumber:3] autorelease];
546  [field addVarint:4];
547  [unknownFields addField:field];
548
549  [message setUnknownFields:unknownFields];
550
551  NSString *description = [message description];
552  XCTAssertGreaterThan([description length], 0U);
553
554  GPBMessage *message2 = [TestAllExtensions message];
555  [message2 setExtension:[UnittestRoot optionalInt32Extension] value:@1];
556
557  [message2 addExtension:[UnittestRoot repeatedInt32Extension] value:@2];
558
559  description = [message2 description];
560  XCTAssertGreaterThan([description length], 0U);
561}
562
563- (void)testSetter {
564  // Test to make sure that if we set a value that has a default value
565  // with the default, that the has is set, and the value gets put into the
566  // message correctly.
567  TestAllTypes *message = [TestAllTypes message];
568  GPBDescriptor *descriptor = [[message class] descriptor];
569  XCTAssertNotNil(descriptor);
570  GPBFieldDescriptor *fieldDescriptor =
571      [descriptor fieldWithName:@"defaultInt32"];
572  XCTAssertNotNil(fieldDescriptor);
573  GPBGenericValue defaultValue = [fieldDescriptor defaultValue];
574  [message setDefaultInt32:defaultValue.valueInt32];
575  XCTAssertTrue(message.hasDefaultInt32);
576  XCTAssertEqual(message.defaultInt32, defaultValue.valueInt32);
577
578  // Do the same thing with an object type.
579  message = [TestAllTypes message];
580  fieldDescriptor = [descriptor fieldWithName:@"defaultString"];
581  XCTAssertNotNil(fieldDescriptor);
582  defaultValue = [fieldDescriptor defaultValue];
583  [message setDefaultString:defaultValue.valueString];
584  XCTAssertTrue(message.hasDefaultString);
585  XCTAssertEqualObjects(message.defaultString, defaultValue.valueString);
586
587  // Test default string type.
588  message = [TestAllTypes message];
589  XCTAssertEqualObjects(message.defaultString, @"hello");
590  XCTAssertFalse(message.hasDefaultString);
591  fieldDescriptor = [descriptor fieldWithName:@"defaultString"];
592  XCTAssertNotNil(fieldDescriptor);
593  defaultValue = [fieldDescriptor defaultValue];
594  [message setDefaultString:defaultValue.valueString];
595  XCTAssertEqualObjects(message.defaultString, @"hello");
596  XCTAssertTrue(message.hasDefaultString);
597  [message setDefaultString:nil];
598  XCTAssertEqualObjects(message.defaultString, @"hello");
599  XCTAssertFalse(message.hasDefaultString);
600  message.hasDefaultString = NO;
601  XCTAssertFalse(message.hasDefaultString);
602  XCTAssertEqualObjects(message.defaultString, @"hello");
603
604  // Test default bytes type.
605  NSData *defaultBytes = [@"world" dataUsingEncoding:NSUTF8StringEncoding];
606  XCTAssertEqualObjects(message.defaultBytes, defaultBytes);
607  XCTAssertFalse(message.hasDefaultString);
608  fieldDescriptor = [descriptor fieldWithName:@"defaultBytes"];
609  XCTAssertNotNil(fieldDescriptor);
610  defaultValue = [fieldDescriptor defaultValue];
611  [message setDefaultBytes:defaultValue.valueData];
612  XCTAssertEqualObjects(message.defaultBytes, defaultBytes);
613  XCTAssertTrue(message.hasDefaultBytes);
614  [message setDefaultBytes:nil];
615  XCTAssertEqualObjects(message.defaultBytes, defaultBytes);
616  XCTAssertFalse(message.hasDefaultBytes);
617  message.hasDefaultBytes = NO;
618  XCTAssertFalse(message.hasDefaultBytes);
619  XCTAssertEqualObjects(message.defaultBytes, defaultBytes);
620
621  // Test optional string.
622  XCTAssertFalse(message.hasOptionalString);
623  XCTAssertEqualObjects(message.optionalString, @"");
624  XCTAssertFalse(message.hasOptionalString);
625  message.optionalString = nil;
626  XCTAssertFalse(message.hasOptionalString);
627  XCTAssertEqualObjects(message.optionalString, @"");
628  NSString *string = @"string";
629  message.optionalString = string;
630  XCTAssertEqualObjects(message.optionalString, string);
631  XCTAssertTrue(message.hasOptionalString);
632  message.optionalString = nil;
633  XCTAssertFalse(message.hasOptionalString);
634  XCTAssertEqualObjects(message.optionalString, @"");
635
636  // Test optional data.
637  XCTAssertFalse(message.hasOptionalBytes);
638  XCTAssertEqualObjects(message.optionalBytes, GPBEmptyNSData());
639  XCTAssertFalse(message.hasOptionalBytes);
640  message.optionalBytes = nil;
641  XCTAssertFalse(message.hasOptionalBytes);
642  XCTAssertEqualObjects(message.optionalBytes, GPBEmptyNSData());
643  NSData *data = [@"bytes" dataUsingEncoding:NSUTF8StringEncoding];
644  message.optionalBytes = data;
645  XCTAssertEqualObjects(message.optionalBytes, data);
646  XCTAssertTrue(message.hasOptionalBytes);
647  message.optionalBytes = nil;
648  XCTAssertFalse(message.hasOptionalBytes);
649  XCTAssertEqualObjects(message.optionalBytes, GPBEmptyNSData());
650
651  // Test lazy message setting
652  XCTAssertFalse(message.hasOptionalLazyMessage);
653  XCTAssertNotNil(message.optionalLazyMessage);
654  XCTAssertFalse(message.hasOptionalLazyMessage);
655  message.hasOptionalLazyMessage = NO;
656  XCTAssertFalse(message.hasOptionalLazyMessage);
657  XCTAssertNotNil(message.optionalLazyMessage);
658  XCTAssertFalse(message.hasOptionalLazyMessage);
659  message.optionalLazyMessage = nil;
660  XCTAssertFalse(message.hasOptionalLazyMessage);
661
662  // Test nested messages
663  XCTAssertFalse(message.hasOptionalLazyMessage);
664  message.optionalLazyMessage.bb = 1;
665  XCTAssertTrue(message.hasOptionalLazyMessage);
666  XCTAssertEqual(message.optionalLazyMessage.bb, 1);
667  XCTAssertNotNil(message.optionalLazyMessage);
668  message.optionalLazyMessage = nil;
669  XCTAssertFalse(message.hasOptionalLazyMessage);
670  XCTAssertEqual(message.optionalLazyMessage.bb, 0);
671  XCTAssertFalse(message.hasOptionalLazyMessage);
672  XCTAssertNotNil(message.optionalLazyMessage);
673
674  // -testDefaultSubMessages tests the "defaulting" handling of fields
675  // containing messages.
676}
677
678- (void)testRepeatedSetters {
679  TestAllTypes *message = [TestAllTypes message];
680  [self setAllFields:message repeatedCount:kGPBDefaultRepeatCount];
681  [self modifyRepeatedFields:message];
682  [self assertRepeatedFieldsModified:message
683                       repeatedCount:kGPBDefaultRepeatCount];
684}
685
686- (void)testClear {
687  TestAllTypes *message = [TestAllTypes message];
688  [self setAllFields:message repeatedCount:kGPBDefaultRepeatCount];
689  [self clearAllFields:message];
690  [self assertClear:message];
691  TestAllTypes *message2 = [TestAllTypes message];
692  XCTAssertEqualObjects(message, message2);
693}
694
695- (void)testClearKVC {
696  TestAllTypes *message = [TestAllTypes message];
697  [self setAllFields:message repeatedCount:kGPBDefaultRepeatCount];
698  [self clearAllFields:message];
699  [self assertClear:message];
700  [self assertClearKVC:message];
701}
702
703- (void)testClearExtension {
704  // clearExtension() is not actually used in TestUtil, so try it manually.
705  GPBMessage *message1 = [TestAllExtensions message];
706  [message1 setExtension:[UnittestRoot optionalInt32Extension] value:@1];
707
708  XCTAssertTrue([message1 hasExtension:[UnittestRoot optionalInt32Extension]]);
709  [message1 clearExtension:[UnittestRoot optionalInt32Extension]];
710  XCTAssertFalse([message1 hasExtension:[UnittestRoot optionalInt32Extension]]);
711
712  GPBMessage *message2 = [TestAllExtensions message];
713  [message2 addExtension:[UnittestRoot repeatedInt32Extension] value:@1];
714
715  XCTAssertEqual(
716      [[message2 getExtension:[UnittestRoot repeatedInt32Extension]] count],
717      (NSUInteger)1);
718  [message2 clearExtension:[UnittestRoot repeatedInt32Extension]];
719  XCTAssertEqual(
720      [[message2 getExtension:[UnittestRoot repeatedInt32Extension]] count],
721      (NSUInteger)0);
722
723  // Clearing an unset extension field shouldn't make the target message
724  // visible.
725  GPBMessage *message3 = [TestAllExtensions message];
726  GPBMessage *extension_msg =
727      [message3 getExtension:[UnittestObjcRoot recursiveExtension]];
728  XCTAssertFalse([message3 hasExtension:[UnittestObjcRoot recursiveExtension]]);
729  [extension_msg clearExtension:[UnittestRoot optionalInt32Extension]];
730  XCTAssertFalse([message3 hasExtension:[UnittestObjcRoot recursiveExtension]]);
731}
732
733- (void)testDefaultingSubMessages {
734  TestAllTypes *message = [TestAllTypes message];
735
736  // Initially they should all not have values.
737
738  XCTAssertFalse(message.hasOptionalGroup);
739  XCTAssertFalse(message.hasOptionalNestedMessage);
740  XCTAssertFalse(message.hasOptionalForeignMessage);
741  XCTAssertFalse(message.hasOptionalImportMessage);
742  XCTAssertFalse(message.hasOptionalPublicImportMessage);
743  XCTAssertFalse(message.hasOptionalLazyMessage);
744
745  // They should auto create something when fetched.
746
747  TestAllTypes_OptionalGroup *optionalGroup = [message.optionalGroup retain];
748  TestAllTypes_NestedMessage *optionalNestedMessage =
749      [message.optionalNestedMessage retain];
750  ForeignMessage *optionalForeignMessage =
751      [message.optionalForeignMessage retain];
752  ImportMessage *optionalImportMessage = [message.optionalImportMessage retain];
753  PublicImportMessage *optionalPublicImportMessage =
754      [message.optionalPublicImportMessage retain];
755  TestAllTypes_NestedMessage *optionalLazyMessage =
756      [message.optionalLazyMessage retain];
757
758  XCTAssertNotNil(optionalGroup);
759  XCTAssertNotNil(optionalNestedMessage);
760  XCTAssertNotNil(optionalForeignMessage);
761  XCTAssertNotNil(optionalImportMessage);
762  XCTAssertNotNil(optionalPublicImportMessage);
763  XCTAssertNotNil(optionalLazyMessage);
764
765  // Although they were created, they should not respond to hasValue until that
766  // submessage is mutated.
767
768  XCTAssertFalse(message.hasOptionalGroup);
769  XCTAssertFalse(message.hasOptionalNestedMessage);
770  XCTAssertFalse(message.hasOptionalForeignMessage);
771  XCTAssertFalse(message.hasOptionalImportMessage);
772  XCTAssertFalse(message.hasOptionalPublicImportMessage);
773  XCTAssertFalse(message.hasOptionalLazyMessage);
774
775  // And they set that value back in to the message since the value created was
776  // mutable (so a second fetch should give the same object).
777
778  XCTAssertEqual(message.optionalGroup, optionalGroup);
779  XCTAssertEqual(message.optionalNestedMessage, optionalNestedMessage);
780  XCTAssertEqual(message.optionalForeignMessage, optionalForeignMessage);
781  XCTAssertEqual(message.optionalImportMessage, optionalImportMessage);
782  XCTAssertEqual(message.optionalPublicImportMessage,
783                 optionalPublicImportMessage);
784  XCTAssertEqual(message.optionalLazyMessage, optionalLazyMessage);
785
786  // And the default objects for a second message should be distinct (again,
787  // since they are mutable, each needs their own copy).
788
789  TestAllTypes *message2 = [TestAllTypes message];
790
791  // Intentionally doing a pointer comparison.
792  XCTAssertNotEqual(message2.optionalGroup, optionalGroup);
793  XCTAssertNotEqual(message2.optionalNestedMessage, optionalNestedMessage);
794  XCTAssertNotEqual(message2.optionalForeignMessage, optionalForeignMessage);
795  XCTAssertNotEqual(message2.optionalImportMessage, optionalImportMessage);
796  XCTAssertNotEqual(message2.optionalPublicImportMessage,
797                    optionalPublicImportMessage);
798  XCTAssertNotEqual(message2.optionalLazyMessage, optionalLazyMessage);
799
800  // Setting the values to nil will clear the has flag, and on next access you
801  // get back new submessages.
802
803  message.optionalGroup = nil;
804  message.optionalNestedMessage = nil;
805  message.optionalForeignMessage = nil;
806  message.optionalImportMessage = nil;
807  message.optionalPublicImportMessage = nil;
808  message.optionalLazyMessage = nil;
809
810  XCTAssertFalse(message.hasOptionalGroup);
811  XCTAssertFalse(message.hasOptionalNestedMessage);
812  XCTAssertFalse(message.hasOptionalForeignMessage);
813  XCTAssertFalse(message.hasOptionalImportMessage);
814  XCTAssertFalse(message.hasOptionalPublicImportMessage);
815  XCTAssertFalse(message.hasOptionalLazyMessage);
816
817  // Intentionally doing a pointer comparison.
818  XCTAssertNotEqual(message.optionalGroup, optionalGroup);
819  XCTAssertNotEqual(message.optionalNestedMessage, optionalNestedMessage);
820  XCTAssertNotEqual(message.optionalForeignMessage, optionalForeignMessage);
821  XCTAssertNotEqual(message.optionalImportMessage, optionalImportMessage);
822  XCTAssertNotEqual(message.optionalPublicImportMessage,
823                    optionalPublicImportMessage);
824  XCTAssertNotEqual(message.optionalLazyMessage, optionalLazyMessage);
825
826  [optionalGroup release];
827  [optionalNestedMessage release];
828  [optionalForeignMessage release];
829  [optionalImportMessage release];
830  [optionalPublicImportMessage release];
831  [optionalLazyMessage release];
832}
833
834- (void)testMultiplePointersToAutocreatedMessage {
835  // Multiple objects pointing to the same autocreated message.
836  TestAllTypes *message = [TestAllTypes message];
837  TestAllTypes *message2 = [TestAllTypes message];
838  message2.optionalGroup = message.optionalGroup;
839  XCTAssertTrue([message2 hasOptionalGroup]);
840  XCTAssertFalse([message hasOptionalGroup]);
841  message2.optionalGroup.a = 42;
842  XCTAssertTrue([message hasOptionalGroup]);
843  XCTAssertTrue([message2 hasOptionalGroup]);
844}
845
846- (void)testCopyWithAutocreatedMessage {
847  // Mutable copy should not copy autocreated messages.
848  TestAllTypes *message = [TestAllTypes message];
849  message.optionalGroup.a = 42;
850  XCTAssertNotNil(message.optionalNestedMessage);
851  TestAllTypes *message2 = [[message copy] autorelease];
852  XCTAssertTrue([message2 hasOptionalGroup]);
853  XCTAssertFalse([message2 hasOptionalNestedMessage]);
854
855  // Intentionally doing a pointer comparison.
856  XCTAssertNotEqual(message.optionalNestedMessage,
857                    message2.optionalNestedMessage);
858}
859
860- (void)testClearAutocreatedSubmessage {
861  // Call clear on an intermediate submessage should cause it to get recreated
862  // on the next call.
863  TestRecursiveMessage *message = [TestRecursiveMessage message];
864  TestRecursiveMessage *message_inner = [message.a.a.a retain];
865  XCTAssertNotNil(message_inner);
866  XCTAssertTrue(GPBWasMessageAutocreatedBy(message_inner, message.a.a));
867  [message.a.a clear];
868  XCTAssertFalse(GPBWasMessageAutocreatedBy(message_inner, message.a.a));
869
870  // Intentionally doing a pointer comparison.
871  XCTAssertNotEqual(message.a.a.a, message_inner);
872  [message_inner release];
873}
874
875- (void)testRetainAutocreatedSubmessage {
876  // Should be able to retain autocreated submessage while the creator is
877  // dealloced.
878  TestAllTypes *message = [TestAllTypes message];
879
880  ForeignMessage *subMessage;
881  @autoreleasepool {
882    TestAllTypes *message2 = [TestAllTypes message];
883    subMessage = message2.optionalForeignMessage; // Autocreated
884    message.optionalForeignMessage = subMessage;
885    XCTAssertTrue(GPBWasMessageAutocreatedBy(message.optionalForeignMessage,
886                                             message2));
887  }
888
889  // Should be the same object, and should still be live.
890  XCTAssertEqual(message.optionalForeignMessage, subMessage);
891  XCTAssertNotNil([subMessage description]);
892}
893
894- (void)testSetNilAutocreatedSubmessage {
895  TestRecursiveMessage *message = [TestRecursiveMessage message];
896  TestRecursiveMessage *message_inner = [message.a.a retain];
897  XCTAssertFalse([message hasA]);
898  XCTAssertFalse([message.a hasA]);
899  message.a.a = nil;
900
901  // |message.a| has to be made visible, but |message.a.a| was set to nil so
902  // shouldn't be.
903  XCTAssertTrue([message hasA]);
904  XCTAssertFalse([message.a hasA]);
905
906  // Setting submessage to nil should cause it to lose its creator.
907  XCTAssertFalse(GPBWasMessageAutocreatedBy(message_inner, message.a));
908
909  // After setting to nil, getting it again should create a new autocreated
910  // message.
911  // Intentionally doing a pointer comparison.
912  XCTAssertNotEqual(message.a.a, message_inner);
913
914  [message_inner release];
915}
916
917- (void)testSetDoesntHaveAutocreatedSubmessage {
918  // Clearing submessage (set has == NO) should NOT cause it to lose its
919  // creator.
920  TestAllTypes *message = [TestAllTypes message];
921  TestAllTypes_NestedMessage *nestedMessage = message.optionalNestedMessage;
922  XCTAssertFalse([message hasOptionalNestedMessage]);
923  [message setHasOptionalNestedMessage:NO];
924  XCTAssertFalse([message hasOptionalNestedMessage]);
925  XCTAssertEqual(message.optionalNestedMessage, nestedMessage);
926}
927
928- (void)testSetAutocreatedMessageBecomesVisible {
929  // Setting a value should cause the submessage to appear to its creator.
930  // Test this several levels deep.
931  TestRecursiveMessage *message = [TestRecursiveMessage message];
932  message.a.a.a.a.i = 42;
933  XCTAssertTrue([message hasA]);
934  XCTAssertTrue([message.a hasA]);
935  XCTAssertTrue([message.a.a hasA]);
936  XCTAssertTrue([message.a.a.a hasA]);
937  XCTAssertFalse([message.a.a.a.a hasA]);
938  XCTAssertEqual(message.a.a.a.a.i, 42);
939}
940
941- (void)testClearUnsetFieldOfAutocreatedMessage {
942  // Clearing an unset field should not cause the submessage to appear to its
943  // creator.
944  TestRecursiveMessage *message = [TestRecursiveMessage message];
945  message.a.a.a.a.hasI = NO;
946  XCTAssertFalse([message hasA]);
947  XCTAssertFalse([message.a hasA]);
948  XCTAssertFalse([message.a.a hasA]);
949  XCTAssertFalse([message.a.a.a hasA]);
950}
951
952- (void)testAutocreatedSubmessageAssignSkip {
953  TestRecursiveMessage *message = [TestRecursiveMessage message];
954  TestRecursiveMessage *messageLevel1 = [message.a retain];
955  TestRecursiveMessage *messageLevel2 = [message.a.a retain];
956  TestRecursiveMessage *messageLevel3 = [message.a.a.a retain];
957  TestRecursiveMessage *messageLevel4 = [message.a.a.a.a retain];
958  XCTAssertTrue(GPBWasMessageAutocreatedBy(messageLevel1, message));
959  XCTAssertTrue(GPBWasMessageAutocreatedBy(messageLevel2, messageLevel1));
960  XCTAssertTrue(GPBWasMessageAutocreatedBy(messageLevel3, messageLevel2));
961  XCTAssertTrue(GPBWasMessageAutocreatedBy(messageLevel4, messageLevel3));
962
963  // Test skipping over an autocreated submessage and ensure it gets unset.
964  message.a = message.a.a;
965  XCTAssertEqual(message.a, messageLevel2);
966  XCTAssertTrue([message hasA]);
967  XCTAssertEqual(message.a.a, messageLevel3);
968  XCTAssertFalse([message.a hasA]);
969  XCTAssertEqual(message.a.a.a, messageLevel4);
970  XCTAssertFalse(GPBWasMessageAutocreatedBy(messageLevel1,
971                                            message));  // Because it was orphaned.
972  XCTAssertTrue(GPBWasMessageAutocreatedBy(messageLevel2, messageLevel1));
973  XCTAssertTrue(GPBWasMessageAutocreatedBy(messageLevel3, messageLevel2));
974
975  [messageLevel1 release];
976  [messageLevel2 release];
977  [messageLevel3 release];
978  [messageLevel4 release];
979}
980
981- (void)testAutocreatedSubmessageAssignLoop {
982  TestRecursiveMessage *message = [TestRecursiveMessage message];
983  TestRecursiveMessage *messageLevel1 = [message.a retain];
984  TestRecursiveMessage *messageLevel2 = [message.a.a retain];
985  TestRecursiveMessage *messageLevel3 = [message.a.a.a retain];
986  TestRecursiveMessage *messageLevel4 = [message.a.a.a.a retain];
987  XCTAssertTrue(GPBWasMessageAutocreatedBy(messageLevel1, message));
988  XCTAssertTrue(GPBWasMessageAutocreatedBy(messageLevel2, messageLevel1));
989  XCTAssertTrue(GPBWasMessageAutocreatedBy(messageLevel3, messageLevel2));
990  XCTAssertTrue(GPBWasMessageAutocreatedBy(messageLevel4, messageLevel3));
991
992  // Test a property with a loop. You'd never do this but at least ensure the
993  // autocreated submessages behave sanely.
994  message.a.a = message.a;
995  XCTAssertTrue([message hasA]);
996  XCTAssertEqual(message.a, messageLevel1);
997  XCTAssertTrue([message.a hasA]);
998  XCTAssertEqual(message.a.a, messageLevel1);
999  XCTAssertTrue([message.a.a hasA]);
1000  XCTAssertEqual(message.a.a.a, messageLevel1);
1001  XCTAssertFalse(GPBWasMessageAutocreatedBy(messageLevel1,
1002                                            message));  // Because it was assigned.
1003  XCTAssertFalse(GPBWasMessageAutocreatedBy(messageLevel2,
1004                                            messageLevel1));  // Because it was orphaned.
1005  XCTAssertFalse([messageLevel2 hasA]);
1006
1007  // Break the retain loop.
1008  message.a.a = nil;
1009  XCTAssertTrue([message hasA]);
1010  XCTAssertFalse([message.a hasA]);
1011
1012  [messageLevel1 release];
1013  [messageLevel2 release];
1014  [messageLevel3 release];
1015  [messageLevel4 release];
1016}
1017
1018- (void)testSetAutocreatedSubmessage {
1019  // Setting autocreated submessage to another value should cause the old one to
1020  // lose its creator.
1021  TestAllTypes *message = [TestAllTypes message];
1022  TestAllTypes_NestedMessage *nestedMessage =
1023      [message.optionalNestedMessage retain];
1024
1025  message.optionalNestedMessage = [TestAllTypes_NestedMessage message];
1026  XCTAssertTrue([message hasOptionalNestedMessage]);
1027  XCTAssertTrue(message.optionalNestedMessage != nestedMessage);
1028  XCTAssertFalse(GPBWasMessageAutocreatedBy(nestedMessage, message));
1029
1030  [nestedMessage release];
1031}
1032
1033- (void)testAutocreatedUnknownFields {
1034  // Doing anything with (except reading) unknown fields should cause the
1035  // submessage to become visible.
1036  TestAllTypes *message = [TestAllTypes message];
1037  XCTAssertNotNil(message.optionalNestedMessage);
1038  XCTAssertFalse([message hasOptionalNestedMessage]);
1039  XCTAssertNil(message.optionalNestedMessage.unknownFields);
1040  XCTAssertFalse([message hasOptionalNestedMessage]);
1041
1042  GPBUnknownFieldSet *unknownFields =
1043      [[[GPBUnknownFieldSet alloc] init] autorelease];
1044  message.optionalNestedMessage.unknownFields = unknownFields;
1045  XCTAssertTrue([message hasOptionalNestedMessage]);
1046
1047  message.optionalNestedMessage = nil;
1048  XCTAssertFalse([message hasOptionalNestedMessage]);
1049  [message.optionalNestedMessage setUnknownFields:unknownFields];
1050  XCTAssertTrue([message hasOptionalNestedMessage]);
1051}
1052
1053- (void)testSetAutocreatedSubmessageToSelf {
1054  // Setting submessage to itself should cause it to become visible.
1055  TestAllTypes *message = [TestAllTypes message];
1056  XCTAssertNotNil(message.optionalNestedMessage);
1057  XCTAssertFalse([message hasOptionalNestedMessage]);
1058  message.optionalNestedMessage = message.optionalNestedMessage;
1059  XCTAssertTrue([message hasOptionalNestedMessage]);
1060}
1061
1062- (void)testAutocreatedSubmessageMemoryLeaks {
1063  // Test for memory leaks with autocreated submessages.
1064  TestRecursiveMessage *message;
1065  TestRecursiveMessage *messageLevel1;
1066  TestRecursiveMessage *messageLevel2;
1067  TestRecursiveMessage *messageLevel3;
1068  TestRecursiveMessage *messageLevel4;
1069  @autoreleasepool {
1070    message = [[TestRecursiveMessage alloc] init];
1071    messageLevel1 = [message.a retain];
1072    messageLevel2 = [message.a.a retain];
1073    messageLevel3 = [message.a.a.a retain];
1074    messageLevel4 = [message.a.a.a.a retain];
1075    message.a.i = 1;
1076  }
1077
1078  XCTAssertEqual(message.retainCount, (NSUInteger)1);
1079  [message release];
1080  XCTAssertEqual(messageLevel1.retainCount, (NSUInteger)1);
1081  [messageLevel1 release];
1082  XCTAssertEqual(messageLevel2.retainCount, (NSUInteger)1);
1083  [messageLevel2 release];
1084  XCTAssertEqual(messageLevel3.retainCount, (NSUInteger)1);
1085  [messageLevel3 release];
1086  XCTAssertEqual(messageLevel4.retainCount, (NSUInteger)1);
1087  [messageLevel4 release];
1088}
1089
1090- (void)testDefaultingArrays {
1091  // Basic tests for default creation of arrays in a message.
1092  TestRecursiveMessageWithRepeatedField *message =
1093      [TestRecursiveMessageWithRepeatedField message];
1094  TestRecursiveMessageWithRepeatedField *message2 =
1095      [TestRecursiveMessageWithRepeatedField message];
1096
1097  // Simply accessing the array should not make any fields visible.
1098  XCTAssertNotNil(message.a.a.iArray);
1099  XCTAssertFalse([message hasA]);
1100  XCTAssertFalse([message.a hasA]);
1101  XCTAssertNotNil(message2.a.a.strArray);
1102  XCTAssertFalse([message2 hasA]);
1103  XCTAssertFalse([message2.a hasA]);
1104
1105  // But adding an element to the array should.
1106  [message.a.a.iArray addValue:42];
1107  XCTAssertTrue([message hasA]);
1108  XCTAssertTrue([message.a hasA]);
1109  XCTAssertEqual([message.a.a.iArray count], (NSUInteger)1);
1110  [message2.a.a.strArray addObject:@"foo"];
1111  XCTAssertTrue([message2 hasA]);
1112  XCTAssertTrue([message2.a hasA]);
1113  XCTAssertEqual([message2.a.a.strArray count], (NSUInteger)1);
1114}
1115
1116- (void)testAutocreatedArrayShared {
1117  // Multiple objects pointing to the same array.
1118  TestRecursiveMessageWithRepeatedField *message1a =
1119      [TestRecursiveMessageWithRepeatedField message];
1120  TestRecursiveMessageWithRepeatedField *message1b =
1121      [TestRecursiveMessageWithRepeatedField message];
1122  message1a.a.iArray = message1b.a.iArray;
1123  XCTAssertTrue([message1a hasA]);
1124  XCTAssertFalse([message1b hasA]);
1125  [message1a.a.iArray addValue:1];
1126  XCTAssertTrue([message1a hasA]);
1127  XCTAssertTrue([message1b hasA]);
1128  XCTAssertEqual(message1a.a.iArray, message1b.a.iArray);
1129
1130  TestRecursiveMessageWithRepeatedField *message2a =
1131      [TestRecursiveMessageWithRepeatedField message];
1132  TestRecursiveMessageWithRepeatedField *message2b =
1133      [TestRecursiveMessageWithRepeatedField message];
1134  message2a.a.strArray = message2b.a.strArray;
1135  XCTAssertTrue([message2a hasA]);
1136  XCTAssertFalse([message2b hasA]);
1137  [message2a.a.strArray addObject:@"bar"];
1138  XCTAssertTrue([message2a hasA]);
1139  XCTAssertTrue([message2b hasA]);
1140  XCTAssertEqual(message2a.a.strArray, message2b.a.strArray);
1141}
1142
1143- (void)testAutocreatedArrayCopy {
1144  // Copy should not copy autocreated arrays.
1145  TestAllTypes *message = [TestAllTypes message];
1146  XCTAssertNotNil(message.repeatedStringArray);
1147  XCTAssertNotNil(message.repeatedInt32Array);
1148  TestAllTypes *message2 = [[message copy] autorelease];
1149  // Pointer conparisions.
1150  XCTAssertNotEqual(message.repeatedStringArray, message2.repeatedStringArray);
1151  XCTAssertNotEqual(message.repeatedInt32Array, message2.repeatedInt32Array);
1152
1153  // Mutable copy should copy empty arrays that were explicitly set (end up
1154  // with different objects that are equal).
1155  TestAllTypes *message3 = [TestAllTypes message];
1156  message3.repeatedInt32Array = [GPBInt32Array arrayWithValue:42];
1157  message3.repeatedStringArray = [NSMutableArray arrayWithObject:@"wee"];
1158  XCTAssertNotNil(message.repeatedInt32Array);
1159  XCTAssertNotNil(message.repeatedStringArray);
1160  TestAllTypes *message4 = [[message3 copy] autorelease];
1161  XCTAssertNotEqual(message3.repeatedInt32Array, message4.repeatedInt32Array);
1162  XCTAssertEqualObjects(message3.repeatedInt32Array,
1163                        message4.repeatedInt32Array);
1164  XCTAssertNotEqual(message3.repeatedStringArray, message4.repeatedStringArray);
1165  XCTAssertEqualObjects(message3.repeatedStringArray,
1166                        message4.repeatedStringArray);
1167}
1168
1169- (void)testAutocreatedArrayRetain {
1170  // Should be able to retain autocreated array while the creator is dealloced.
1171  TestAllTypes *message = [TestAllTypes message];
1172
1173  @autoreleasepool {
1174    TestAllTypes *message2 = [TestAllTypes message];
1175    message.repeatedInt32Array = message2.repeatedInt32Array;
1176    message.repeatedStringArray = message2.repeatedStringArray;
1177    // Pointer conparision
1178    XCTAssertEqual(message.repeatedInt32Array->_autocreator, message2);
1179    XCTAssertTrue([message.repeatedStringArray
1180        isKindOfClass:[GPBAutocreatedArray class]]);
1181    XCTAssertEqual(
1182        ((GPBAutocreatedArray *)message.repeatedStringArray)->_autocreator,
1183        message2);
1184  }
1185
1186  XCTAssertNil(message.repeatedInt32Array->_autocreator);
1187  XCTAssertTrue(
1188      [message.repeatedStringArray isKindOfClass:[GPBAutocreatedArray class]]);
1189  XCTAssertNil(
1190      ((GPBAutocreatedArray *)message.repeatedStringArray)->_autocreator);
1191}
1192
1193- (void)testSetNilAutocreatedArray {
1194  // Setting array to nil should cause it to lose its delegate.
1195  TestAllTypes *message = [TestAllTypes message];
1196  GPBInt32Array *repeatedInt32Array = [message.repeatedInt32Array retain];
1197  GPBAutocreatedArray *repeatedStringArray =
1198      (GPBAutocreatedArray *)[message.repeatedStringArray retain];
1199  XCTAssertTrue([repeatedStringArray isKindOfClass:[GPBAutocreatedArray class]]);
1200  XCTAssertEqual(repeatedInt32Array->_autocreator, message);
1201  XCTAssertEqual(repeatedStringArray->_autocreator, message);
1202  message.repeatedInt32Array = nil;
1203  message.repeatedStringArray = nil;
1204  XCTAssertNil(repeatedInt32Array->_autocreator);
1205  XCTAssertNil(repeatedStringArray->_autocreator);
1206  [repeatedInt32Array release];
1207  [repeatedStringArray release];
1208}
1209
1210- (void)testSetOverAutocreatedArrayAndSetAgain {
1211  // Ensure when dealing with replacing an array it is handled being either
1212  // an autocreated one or a straight NSArray.
1213
1214  // The real test here is that nothing crashes while doing the work.
1215  TestAllTypes *message = [TestAllTypes message];
1216  [message.repeatedStringArray addObject:@"foo"];
1217  XCTAssertEqual(message.repeatedStringArray_Count, (NSUInteger)1);
1218  message.repeatedStringArray = [NSMutableArray arrayWithObjects:@"bar", @"bar2", nil];
1219  XCTAssertEqual(message.repeatedStringArray_Count, (NSUInteger)2);
1220  message.repeatedStringArray = [NSMutableArray arrayWithObject:@"baz"];
1221  XCTAssertEqual(message.repeatedStringArray_Count, (NSUInteger)1);
1222}
1223
1224- (void)testReplaceAutocreatedArray {
1225  // Replacing array should orphan the old one and cause its creator to become
1226  // visible.
1227  {
1228    TestRecursiveMessageWithRepeatedField *message =
1229        [TestRecursiveMessageWithRepeatedField message];
1230    XCTAssertNotNil(message.a);
1231    XCTAssertNotNil(message.a.iArray);
1232    XCTAssertFalse([message hasA]);
1233    GPBInt32Array *iArray = [message.a.iArray retain];
1234    XCTAssertEqual(iArray->_autocreator, message.a);  // Pointer comparison
1235    message.a.iArray = [GPBInt32Array arrayWithValue:1];
1236    XCTAssertTrue([message hasA]);
1237    XCTAssertNotEqual(message.a.iArray, iArray);  // Pointer comparison
1238    XCTAssertNil(iArray->_autocreator);
1239    [iArray release];
1240  }
1241
1242  {
1243    TestRecursiveMessageWithRepeatedField *message =
1244        [TestRecursiveMessageWithRepeatedField message];
1245    XCTAssertNotNil(message.a);
1246    XCTAssertNotNil(message.a.strArray);
1247    XCTAssertFalse([message hasA]);
1248    GPBAutocreatedArray *strArray =
1249        (GPBAutocreatedArray *)[message.a.strArray retain];
1250    XCTAssertTrue([strArray isKindOfClass:[GPBAutocreatedArray class]]);
1251    XCTAssertEqual(strArray->_autocreator, message.a);  // Pointer comparison
1252    message.a.strArray = [NSMutableArray arrayWithObject:@"foo"];
1253    XCTAssertTrue([message hasA]);
1254    XCTAssertNotEqual(message.a.strArray, strArray);  // Pointer comparison
1255    XCTAssertNil(strArray->_autocreator);
1256    [strArray release];
1257  }
1258}
1259
1260- (void)testSetAutocreatedArrayToSelf {
1261  // Setting array to itself should cause it to become visible.
1262  {
1263    TestRecursiveMessageWithRepeatedField *message =
1264        [TestRecursiveMessageWithRepeatedField message];
1265    XCTAssertNotNil(message.a);
1266    XCTAssertNotNil(message.a.iArray);
1267    XCTAssertFalse([message hasA]);
1268    message.a.iArray = message.a.iArray;
1269    XCTAssertTrue([message hasA]);
1270    XCTAssertNil(message.a.iArray->_autocreator);
1271  }
1272
1273  {
1274    TestRecursiveMessageWithRepeatedField *message =
1275        [TestRecursiveMessageWithRepeatedField message];
1276    XCTAssertNotNil(message.a);
1277    XCTAssertNotNil(message.a.strArray);
1278    XCTAssertFalse([message hasA]);
1279    message.a.strArray = message.a.strArray;
1280    XCTAssertTrue([message hasA]);
1281    XCTAssertTrue([message.a.strArray isKindOfClass:[GPBAutocreatedArray class]]);
1282    XCTAssertNil(((GPBAutocreatedArray *)message.a.strArray)->_autocreator);
1283  }
1284}
1285
1286- (void)testAutocreatedArrayRemoveAllValues {
1287  // Calling removeAllValues on autocreated array should not cause it to be
1288  // visible.
1289  TestRecursiveMessageWithRepeatedField *message =
1290      [TestRecursiveMessageWithRepeatedField message];
1291  [message.a.iArray removeAll];
1292  XCTAssertFalse([message hasA]);
1293  [message.a.strArray removeAllObjects];
1294  XCTAssertFalse([message hasA]);
1295}
1296
1297- (void)testDefaultingMaps {
1298  // Basic tests for default creation of maps in a message.
1299  TestRecursiveMessageWithRepeatedField *message =
1300      [TestRecursiveMessageWithRepeatedField message];
1301  TestRecursiveMessageWithRepeatedField *message2 =
1302      [TestRecursiveMessageWithRepeatedField message];
1303
1304  // Simply accessing the map should not make any fields visible.
1305  XCTAssertNotNil(message.a.a.iToI);
1306  XCTAssertFalse([message hasA]);
1307  XCTAssertFalse([message.a hasA]);
1308  XCTAssertNotNil(message2.a.a.strToStr);
1309  XCTAssertFalse([message2 hasA]);
1310  XCTAssertFalse([message2.a hasA]);
1311
1312  // But adding an element to the map should.
1313  [message.a.a.iToI setInt32:100 forKey:200];
1314  XCTAssertTrue([message hasA]);
1315  XCTAssertTrue([message.a hasA]);
1316  XCTAssertEqual([message.a.a.iToI count], (NSUInteger)1);
1317  [message2.a.a.strToStr setObject:@"foo" forKey:@"bar"];
1318  XCTAssertTrue([message2 hasA]);
1319  XCTAssertTrue([message2.a hasA]);
1320  XCTAssertEqual([message2.a.a.strToStr count], (NSUInteger)1);
1321}
1322
1323- (void)testAutocreatedMapShared {
1324  // Multiple objects pointing to the same map.
1325  TestRecursiveMessageWithRepeatedField *message1a =
1326      [TestRecursiveMessageWithRepeatedField message];
1327  TestRecursiveMessageWithRepeatedField *message1b =
1328      [TestRecursiveMessageWithRepeatedField message];
1329  message1a.a.iToI = message1b.a.iToI;
1330  XCTAssertTrue([message1a hasA]);
1331  XCTAssertFalse([message1b hasA]);
1332  [message1a.a.iToI setInt32:1 forKey:2];
1333  XCTAssertTrue([message1a hasA]);
1334  XCTAssertTrue([message1b hasA]);
1335  XCTAssertEqual(message1a.a.iToI, message1b.a.iToI);
1336
1337  TestRecursiveMessageWithRepeatedField *message2a =
1338      [TestRecursiveMessageWithRepeatedField message];
1339  TestRecursiveMessageWithRepeatedField *message2b =
1340      [TestRecursiveMessageWithRepeatedField message];
1341  message2a.a.strToStr = message2b.a.strToStr;
1342  XCTAssertTrue([message2a hasA]);
1343  XCTAssertFalse([message2b hasA]);
1344  [message2a.a.strToStr setObject:@"bar" forKey:@"foo"];
1345  XCTAssertTrue([message2a hasA]);
1346  XCTAssertTrue([message2b hasA]);
1347  XCTAssertEqual(message2a.a.strToStr, message2b.a.strToStr);
1348}
1349
1350- (void)testAutocreatedMapCopy {
1351  // Copy should not copy autocreated maps.
1352  TestRecursiveMessageWithRepeatedField *message =
1353      [TestRecursiveMessageWithRepeatedField message];
1354  XCTAssertNotNil(message.strToStr);
1355  XCTAssertNotNil(message.iToI);
1356  TestRecursiveMessageWithRepeatedField *message2 =
1357      [[message copy] autorelease];
1358  // Pointer conparisions.
1359  XCTAssertNotEqual(message.strToStr, message2.strToStr);
1360  XCTAssertNotEqual(message.iToI, message2.iToI);
1361
1362  // Mutable copy should copy empty arrays that were explicitly set (end up
1363  // with different objects that are equal).
1364  TestRecursiveMessageWithRepeatedField *message3 =
1365      [TestRecursiveMessageWithRepeatedField message];
1366  message3.iToI = [[[GPBInt32Int32Dictionary alloc] init] autorelease];
1367  [message3.iToI setInt32:10 forKey:20];
1368  message3.strToStr =
1369      [NSMutableDictionary dictionaryWithObject:@"abc" forKey:@"123"];
1370  XCTAssertNotNil(message.iToI);
1371  XCTAssertNotNil(message.iToI);
1372  TestRecursiveMessageWithRepeatedField *message4 =
1373      [[message3 copy] autorelease];
1374  XCTAssertNotEqual(message3.iToI, message4.iToI);
1375  XCTAssertEqualObjects(message3.iToI, message4.iToI);
1376  XCTAssertNotEqual(message3.strToStr, message4.strToStr);
1377  XCTAssertEqualObjects(message3.strToStr, message4.strToStr);
1378}
1379
1380- (void)testAutocreatedMapRetain {
1381  // Should be able to retain autocreated map while the creator is dealloced.
1382  TestRecursiveMessageWithRepeatedField *message =
1383      [TestRecursiveMessageWithRepeatedField message];
1384
1385  @autoreleasepool {
1386    TestRecursiveMessageWithRepeatedField *message2 =
1387        [TestRecursiveMessageWithRepeatedField message];
1388    message.iToI = message2.iToI;
1389    message.strToStr = message2.strToStr;
1390    // Pointer conparision
1391    XCTAssertEqual(message.iToI->_autocreator, message2);
1392    XCTAssertTrue([message.strToStr
1393        isKindOfClass:[GPBAutocreatedDictionary class]]);
1394    XCTAssertEqual(
1395        ((GPBAutocreatedDictionary *)message.strToStr)->_autocreator,
1396        message2);
1397  }
1398
1399  XCTAssertNil(message.iToI->_autocreator);
1400  XCTAssertTrue(
1401      [message.strToStr isKindOfClass:[GPBAutocreatedDictionary class]]);
1402  XCTAssertNil(
1403      ((GPBAutocreatedDictionary *)message.strToStr)->_autocreator);
1404}
1405
1406- (void)testSetNilAutocreatedMap {
1407  // Setting map to nil should cause it to lose its delegate.
1408  TestRecursiveMessageWithRepeatedField *message =
1409      [TestRecursiveMessageWithRepeatedField message];
1410  GPBInt32Int32Dictionary *iToI = [message.iToI retain];
1411  GPBAutocreatedDictionary *strToStr =
1412      (GPBAutocreatedDictionary *)[message.strToStr retain];
1413  XCTAssertTrue([strToStr isKindOfClass:[GPBAutocreatedDictionary class]]);
1414  XCTAssertEqual(iToI->_autocreator, message);
1415  XCTAssertEqual(strToStr->_autocreator, message);
1416  message.iToI = nil;
1417  message.strToStr = nil;
1418  XCTAssertNil(iToI->_autocreator);
1419  XCTAssertNil(strToStr->_autocreator);
1420  [iToI release];
1421  [strToStr release];
1422}
1423
1424- (void)testSetOverAutocreatedMapAndSetAgain {
1425  // Ensure when dealing with replacing a map it is handled being either
1426  // an autocreated one or a straight NSDictionary.
1427
1428  // The real test here is that nothing crashes while doing the work.
1429  TestRecursiveMessageWithRepeatedField *message =
1430      [TestRecursiveMessageWithRepeatedField message];
1431  message.strToStr[@"foo"] = @"bar";
1432  XCTAssertEqual(message.strToStr_Count, (NSUInteger)1);
1433  message.strToStr =
1434      [NSMutableDictionary dictionaryWithObjectsAndKeys:@"bar", @"key1", @"baz", @"key2", nil];
1435  XCTAssertEqual(message.strToStr_Count, (NSUInteger)2);
1436  message.strToStr =
1437      [NSMutableDictionary dictionaryWithObject:@"baz" forKey:@"mumble"];
1438  XCTAssertEqual(message.strToStr_Count, (NSUInteger)1);
1439}
1440
1441- (void)testReplaceAutocreatedMap {
1442  // Replacing map should orphan the old one and cause its creator to become
1443  // visible.
1444  {
1445    TestRecursiveMessageWithRepeatedField *message =
1446        [TestRecursiveMessageWithRepeatedField message];
1447    XCTAssertNotNil(message.a);
1448    XCTAssertNotNil(message.a.iToI);
1449    XCTAssertFalse([message hasA]);
1450    GPBInt32Int32Dictionary *iToI = [message.a.iToI retain];
1451    XCTAssertEqual(iToI->_autocreator, message.a);  // Pointer comparison
1452    message.a.iToI = [[[GPBInt32Int32Dictionary alloc] init] autorelease];
1453    [message.a.iToI setInt32:6 forKey:7];
1454    XCTAssertTrue([message hasA]);
1455    XCTAssertNotEqual(message.a.iToI, iToI);  // Pointer comparison
1456    XCTAssertNil(iToI->_autocreator);
1457    [iToI release];
1458  }
1459
1460  {
1461    TestRecursiveMessageWithRepeatedField *message =
1462        [TestRecursiveMessageWithRepeatedField message];
1463    XCTAssertNotNil(message.a);
1464    XCTAssertNotNil(message.a.strToStr);
1465    XCTAssertFalse([message hasA]);
1466    GPBAutocreatedDictionary *strToStr =
1467        (GPBAutocreatedDictionary *)[message.a.strToStr retain];
1468    XCTAssertTrue([strToStr isKindOfClass:[GPBAutocreatedDictionary class]]);
1469    XCTAssertEqual(strToStr->_autocreator, message.a);  // Pointer comparison
1470    message.a.strToStr =
1471        [NSMutableDictionary dictionaryWithObject:@"abc" forKey:@"def"];
1472    XCTAssertTrue([message hasA]);
1473    XCTAssertNotEqual(message.a.strToStr, strToStr);  // Pointer comparison
1474    XCTAssertNil(strToStr->_autocreator);
1475    [strToStr release];
1476  }
1477}
1478
1479- (void)testSetAutocreatedMapToSelf {
1480  // Setting map to itself should cause it to become visible.
1481  {
1482    TestRecursiveMessageWithRepeatedField *message =
1483        [TestRecursiveMessageWithRepeatedField message];
1484    XCTAssertNotNil(message.a);
1485    XCTAssertNotNil(message.a.iToI);
1486    XCTAssertFalse([message hasA]);
1487    message.a.iToI = message.a.iToI;
1488    XCTAssertTrue([message hasA]);
1489    XCTAssertNil(message.a.iToI->_autocreator);
1490  }
1491
1492  {
1493    TestRecursiveMessageWithRepeatedField *message =
1494        [TestRecursiveMessageWithRepeatedField message];
1495    XCTAssertNotNil(message.a);
1496    XCTAssertNotNil(message.a.strToStr);
1497    XCTAssertFalse([message hasA]);
1498    message.a.strToStr = message.a.strToStr;
1499    XCTAssertTrue([message hasA]);
1500    XCTAssertTrue([message.a.strToStr isKindOfClass:[GPBAutocreatedDictionary class]]);
1501    XCTAssertNil(((GPBAutocreatedDictionary *)message.a.strToStr)->_autocreator);
1502  }
1503}
1504
1505- (void)testAutocreatedMapRemoveAllValues {
1506  // Calling removeAll on autocreated map should not cause it to be visible.
1507  TestRecursiveMessageWithRepeatedField *message =
1508      [TestRecursiveMessageWithRepeatedField message];
1509  [message.a.iToI removeAll];
1510  XCTAssertFalse([message hasA]);
1511  [message.a.strToStr removeAllObjects];
1512  XCTAssertFalse([message hasA]);
1513}
1514
1515- (void)testExtensionAccessors {
1516  TestAllExtensions *message = [TestAllExtensions message];
1517  [self setAllExtensions:message repeatedCount:kGPBDefaultRepeatCount];
1518  [self assertAllExtensionsSet:message repeatedCount:kGPBDefaultRepeatCount];
1519}
1520
1521- (void)testExtensionRepeatedSetters {
1522  TestAllExtensions *message = [TestAllExtensions message];
1523  [self setAllExtensions:message repeatedCount:kGPBDefaultRepeatCount];
1524  [self modifyRepeatedExtensions:message];
1525  [self assertRepeatedExtensionsModified:message
1526                           repeatedCount:kGPBDefaultRepeatCount];
1527}
1528
1529- (void)testExtensionDefaults {
1530  [self assertExtensionsClear:[TestAllExtensions message]];
1531}
1532
1533- (void)testExtensionIsEquals {
1534  TestAllExtensions *message = [TestAllExtensions message];
1535  [self setAllExtensions:message repeatedCount:kGPBDefaultRepeatCount];
1536  [self modifyRepeatedExtensions:message];
1537  TestAllExtensions *message2 = [TestAllExtensions message];
1538  [self setAllExtensions:message2 repeatedCount:kGPBDefaultRepeatCount];
1539  XCTAssertFalse([message isEqual:message2]);
1540  message2 = [TestAllExtensions message];
1541  [self setAllExtensions:message2 repeatedCount:kGPBDefaultRepeatCount];
1542  [self modifyRepeatedExtensions:message2];
1543  XCTAssertEqualObjects(message, message2);
1544}
1545
1546- (void)testExtensionsMergeFrom {
1547  TestAllExtensions *message = [TestAllExtensions message];
1548  [self setAllExtensions:message repeatedCount:kGPBDefaultRepeatCount];
1549  [self modifyRepeatedExtensions:message];
1550
1551  message = [TestAllExtensions message];
1552  [self setAllExtensions:message repeatedCount:kGPBDefaultRepeatCount];
1553  TestAllExtensions *message2 = [TestAllExtensions message];
1554  [self modifyRepeatedExtensions:message2];
1555  [message2 mergeFrom:message];
1556
1557  XCTAssertEqualObjects(message, message2);
1558}
1559
1560- (void)testDefaultingExtensionMessages {
1561  TestAllExtensions *message = [TestAllExtensions message];
1562
1563  // Initially they should all not have values.
1564
1565  XCTAssertFalse([message hasExtension:[UnittestRoot optionalGroupExtension]]);
1566  XCTAssertFalse([message hasExtension:[UnittestRoot optionalGroupExtension]]);
1567  XCTAssertFalse(
1568      [message hasExtension:[UnittestRoot optionalNestedMessageExtension]]);
1569  XCTAssertFalse(
1570      [message hasExtension:[UnittestRoot optionalForeignMessageExtension]]);
1571  XCTAssertFalse(
1572      [message hasExtension:[UnittestRoot optionalImportMessageExtension]]);
1573  XCTAssertFalse([message
1574      hasExtension:[UnittestRoot optionalPublicImportMessageExtension]]);
1575  XCTAssertFalse(
1576      [message hasExtension:[UnittestRoot optionalLazyMessageExtension]]);
1577
1578  // They should auto create something when fetched.
1579
1580  TestAllTypes_OptionalGroup *optionalGroup =
1581      [message getExtension:[UnittestRoot optionalGroupExtension]];
1582  TestAllTypes_NestedMessage *optionalNestedMessage =
1583      [message getExtension:[UnittestRoot optionalNestedMessageExtension]];
1584  ForeignMessage *optionalForeignMessage =
1585      [message getExtension:[UnittestRoot optionalForeignMessageExtension]];
1586  ImportMessage *optionalImportMessage =
1587      [message getExtension:[UnittestRoot optionalImportMessageExtension]];
1588  PublicImportMessage *optionalPublicImportMessage = [message
1589      getExtension:[UnittestRoot optionalPublicImportMessageExtension]];
1590  TestAllTypes_NestedMessage *optionalLazyMessage =
1591      [message getExtension:[UnittestRoot optionalLazyMessageExtension]];
1592
1593  XCTAssertNotNil(optionalGroup);
1594  XCTAssertNotNil(optionalNestedMessage);
1595  XCTAssertNotNil(optionalForeignMessage);
1596  XCTAssertNotNil(optionalImportMessage);
1597  XCTAssertNotNil(optionalPublicImportMessage);
1598  XCTAssertNotNil(optionalLazyMessage);
1599
1600  // Although it auto-created empty messages, it should not show that it has
1601  // them.
1602
1603  XCTAssertFalse([message hasExtension:[UnittestRoot optionalGroupExtension]]);
1604  XCTAssertFalse([message hasExtension:[UnittestRoot optionalGroupExtension]]);
1605  XCTAssertFalse([message hasExtension:[UnittestRoot optionalNestedMessageExtension]]);
1606  XCTAssertFalse([message hasExtension:[UnittestRoot optionalForeignMessageExtension]]);
1607  XCTAssertFalse([message hasExtension:[UnittestRoot optionalImportMessageExtension]]);
1608  XCTAssertFalse([message hasExtension:[UnittestRoot optionalPublicImportMessageExtension]]);
1609  XCTAssertFalse([message hasExtension:[UnittestRoot optionalLazyMessageExtension]]);
1610
1611  // And they set that value back in to the message since the value created was
1612  // mutable (so a second fetch should give the same object).
1613
1614  XCTAssertEqual([message getExtension:[UnittestRoot optionalGroupExtension]],
1615                 optionalGroup);
1616  XCTAssertEqual(
1617      [message getExtension:[UnittestRoot optionalNestedMessageExtension]],
1618      optionalNestedMessage);
1619  XCTAssertEqual(
1620      [message getExtension:[UnittestRoot optionalForeignMessageExtension]],
1621      optionalForeignMessage);
1622  XCTAssertEqual(
1623      [message getExtension:[UnittestRoot optionalImportMessageExtension]],
1624      optionalImportMessage);
1625  XCTAssertEqual(
1626      [message getExtension:[UnittestRoot optionalPublicImportMessageExtension]],
1627      optionalPublicImportMessage);
1628  XCTAssertEqual(
1629      [message getExtension:[UnittestRoot optionalLazyMessageExtension]],
1630      optionalLazyMessage);
1631
1632  // And the default objects for a second message should be distinct (again,
1633  // since they are mutable, each needs their own copy).
1634
1635  TestAllExtensions *message2 = [TestAllExtensions message];
1636
1637  // Intentionally doing a pointer comparison.
1638  XCTAssertNotEqual(
1639      [message2 getExtension:[UnittestRoot optionalGroupExtension]],
1640      optionalGroup);
1641  XCTAssertNotEqual(
1642      [message2 getExtension:[UnittestRoot optionalNestedMessageExtension]],
1643      optionalNestedMessage);
1644  XCTAssertNotEqual(
1645      [message2 getExtension:[UnittestRoot optionalForeignMessageExtension]],
1646      optionalForeignMessage);
1647  XCTAssertNotEqual(
1648      [message2 getExtension:[UnittestRoot optionalImportMessageExtension]],
1649      optionalImportMessage);
1650  XCTAssertNotEqual(
1651      [message2 getExtension:[UnittestRoot optionalPublicImportMessageExtension]],
1652      optionalPublicImportMessage);
1653  XCTAssertNotEqual(
1654      [message2 getExtension:[UnittestRoot optionalLazyMessageExtension]],
1655      optionalLazyMessage);
1656
1657  // Clear values, and on next access you get back new submessages.
1658
1659  [message setExtension:[UnittestRoot optionalGroupExtension] value:nil];
1660  [message setExtension:[UnittestRoot optionalGroupExtension] value:nil];
1661  [message setExtension:[UnittestRoot optionalNestedMessageExtension]
1662                  value:nil];
1663  [message setExtension:[UnittestRoot optionalForeignMessageExtension]
1664                  value:nil];
1665  [message setExtension:[UnittestRoot optionalImportMessageExtension]
1666                  value:nil];
1667  [message setExtension:[UnittestRoot optionalPublicImportMessageExtension]
1668                  value:nil];
1669  [message setExtension:[UnittestRoot optionalLazyMessageExtension] value:nil];
1670
1671  XCTAssertFalse([message hasExtension:[UnittestRoot optionalGroupExtension]]);
1672  XCTAssertFalse([message hasExtension:[UnittestRoot optionalGroupExtension]]);
1673  XCTAssertFalse(
1674      [message hasExtension:[UnittestRoot optionalNestedMessageExtension]]);
1675  XCTAssertFalse(
1676      [message hasExtension:[UnittestRoot optionalForeignMessageExtension]]);
1677  XCTAssertFalse(
1678      [message hasExtension:[UnittestRoot optionalImportMessageExtension]]);
1679  XCTAssertFalse([message
1680      hasExtension:[UnittestRoot optionalPublicImportMessageExtension]]);
1681  XCTAssertFalse(
1682      [message hasExtension:[UnittestRoot optionalLazyMessageExtension]]);
1683
1684  XCTAssertEqual([message getExtension:[UnittestRoot optionalGroupExtension]],
1685                 optionalGroup);
1686  XCTAssertEqual(
1687      [message getExtension:[UnittestRoot optionalNestedMessageExtension]],
1688      optionalNestedMessage);
1689  XCTAssertEqual(
1690      [message getExtension:[UnittestRoot optionalForeignMessageExtension]],
1691      optionalForeignMessage);
1692  XCTAssertEqual(
1693      [message getExtension:[UnittestRoot optionalImportMessageExtension]],
1694      optionalImportMessage);
1695  XCTAssertEqual(
1696      [message
1697          getExtension:[UnittestRoot optionalPublicImportMessageExtension]],
1698      optionalPublicImportMessage);
1699  XCTAssertEqual(
1700      [message getExtension:[UnittestRoot optionalLazyMessageExtension]],
1701      optionalLazyMessage);
1702}
1703
1704- (void)testMultiplePointersToAutocreatedExtension {
1705  // 2 objects point to the same auto-created extension. One should "has" it.
1706  // The other should not.
1707  TestAllExtensions *message = [TestAllExtensions message];
1708  TestAllExtensions *message2 = [TestAllExtensions message];
1709  GPBExtensionDescriptor *extension = [UnittestRoot optionalGroupExtension];
1710  [message setExtension:extension value:[message2 getExtension:extension]];
1711  XCTAssertEqual([message getExtension:extension],
1712                 [message2 getExtension:extension]);
1713  XCTAssertFalse([message2 hasExtension:extension]);
1714  XCTAssertTrue([message hasExtension:extension]);
1715
1716  TestAllTypes_OptionalGroup *extensionValue =
1717      [message2 getExtension:extension];
1718  extensionValue.a = 1;
1719  XCTAssertTrue([message2 hasExtension:extension]);
1720  XCTAssertTrue([message hasExtension:extension]);
1721}
1722
1723- (void)testCopyWithAutocreatedExtension {
1724  // Mutable copy shouldn't copy autocreated extensions.
1725  TestAllExtensions *message = [TestAllExtensions message];
1726  GPBExtensionDescriptor *optionalGroupExtension =
1727      [UnittestRoot optionalGroupExtension];
1728  GPBExtensionDescriptor *optionalNestedMessageExtesion =
1729      [UnittestRoot optionalNestedMessageExtension];
1730  TestAllTypes_OptionalGroup *optionalGroup =
1731      [message getExtension:optionalGroupExtension];
1732  optionalGroup.a = 42;
1733  XCTAssertNotNil(optionalGroup);
1734  XCTAssertNotNil([message getExtension:optionalNestedMessageExtesion]);
1735  XCTAssertTrue([message hasExtension:optionalGroupExtension]);
1736  XCTAssertFalse([message hasExtension:optionalNestedMessageExtesion]);
1737
1738  TestAllExtensions *message2 = [[message copy] autorelease];
1739
1740  // message2 should end up with its own copy of the optional group.
1741  XCTAssertTrue([message2 hasExtension:optionalGroupExtension]);
1742  XCTAssertEqualObjects([message getExtension:optionalGroupExtension],
1743                        [message2 getExtension:optionalGroupExtension]);
1744  // Intentionally doing a pointer comparison.
1745  XCTAssertNotEqual([message getExtension:optionalGroupExtension],
1746                    [message2 getExtension:optionalGroupExtension]);
1747
1748  XCTAssertFalse([message2 hasExtension:optionalNestedMessageExtesion]);
1749  // Intentionally doing a pointer comparison (auto creation should be
1750  // different)
1751  XCTAssertNotEqual([message getExtension:optionalNestedMessageExtesion],
1752                    [message2 getExtension:optionalNestedMessageExtesion]);
1753}
1754
1755- (void)testClearMessageAutocreatedExtension {
1756  // Call clear should cause it to recreate its autocreated extensions.
1757  TestAllExtensions *message = [TestAllExtensions message];
1758  GPBExtensionDescriptor *optionalGroupExtension =
1759      [UnittestRoot optionalGroupExtension];
1760  TestAllTypes_OptionalGroup *optionalGroup =
1761      [[message getExtension:optionalGroupExtension] retain];
1762  [message clear];
1763  TestAllTypes_OptionalGroup *optionalGroupNew =
1764      [message getExtension:optionalGroupExtension];
1765
1766  // Intentionally doing a pointer comparison.
1767  XCTAssertNotEqual(optionalGroup, optionalGroupNew);
1768  [optionalGroup release];
1769}
1770
1771- (void)testRetainAutocreatedExtension {
1772  // Should be able to retain autocreated extension while the creator is
1773  // dealloced.
1774  TestAllExtensions *message = [TestAllExtensions message];
1775  GPBExtensionDescriptor *optionalGroupExtension =
1776      [UnittestRoot optionalGroupExtension];
1777
1778  @autoreleasepool {
1779    TestAllExtensions *message2 = [TestAllExtensions message];
1780    [message setExtension:optionalGroupExtension
1781                    value:[message2 getExtension:optionalGroupExtension]];
1782    XCTAssertTrue(GPBWasMessageAutocreatedBy(
1783        [message getExtension:optionalGroupExtension], message2));
1784  }
1785
1786  XCTAssertFalse(GPBWasMessageAutocreatedBy(
1787      [message getExtension:optionalGroupExtension], message));
1788}
1789
1790- (void)testClearAutocreatedExtension {
1791  // Clearing autocreated extension should NOT cause it to lose its creator.
1792  TestAllExtensions *message = [TestAllExtensions message];
1793  GPBExtensionDescriptor *optionalGroupExtension =
1794      [UnittestRoot optionalGroupExtension];
1795  TestAllTypes_OptionalGroup *optionalGroup =
1796      [[message getExtension:optionalGroupExtension] retain];
1797  [message clearExtension:optionalGroupExtension];
1798  TestAllTypes_OptionalGroup *optionalGroupNew =
1799      [message getExtension:optionalGroupExtension];
1800  XCTAssertEqual(optionalGroup, optionalGroupNew);
1801  XCTAssertFalse([message hasExtension:optionalGroupExtension]);
1802  [optionalGroup release];
1803
1804  // Clearing autocreated extension should not cause its creator to become
1805  // visible
1806  GPBExtensionDescriptor *recursiveExtension =
1807      [UnittestObjcRoot recursiveExtension];
1808  TestAllExtensions *message_lvl2 = [message getExtension:recursiveExtension];
1809  TestAllExtensions *message_lvl3 =
1810      [message_lvl2 getExtension:recursiveExtension];
1811  [message_lvl3 clearExtension:recursiveExtension];
1812  XCTAssertFalse([message hasExtension:recursiveExtension]);
1813}
1814
1815- (void)testSetAutocreatedExtensionBecomesVisible {
1816  // Setting an extension should cause the extension to appear to its creator.
1817  // Test this several levels deep.
1818  TestAllExtensions *message = [TestAllExtensions message];
1819  GPBExtensionDescriptor *recursiveExtension =
1820      [UnittestObjcRoot recursiveExtension];
1821  TestAllExtensions *message_lvl2 = [message getExtension:recursiveExtension];
1822  TestAllExtensions *message_lvl3 =
1823      [message_lvl2 getExtension:recursiveExtension];
1824  TestAllExtensions *message_lvl4 =
1825      [message_lvl3 getExtension:recursiveExtension];
1826  XCTAssertFalse([message hasExtension:recursiveExtension]);
1827  XCTAssertFalse([message_lvl2 hasExtension:recursiveExtension]);
1828  XCTAssertFalse([message_lvl3 hasExtension:recursiveExtension]);
1829  XCTAssertFalse([message_lvl4 hasExtension:recursiveExtension]);
1830  [message_lvl4 setExtension:[UnittestRoot optionalInt32Extension] value:@(1)];
1831  XCTAssertTrue([message hasExtension:recursiveExtension]);
1832  XCTAssertTrue([message_lvl2 hasExtension:recursiveExtension]);
1833  XCTAssertTrue([message_lvl3 hasExtension:recursiveExtension]);
1834  XCTAssertFalse([message_lvl4 hasExtension:recursiveExtension]);
1835  XCTAssertFalse(GPBWasMessageAutocreatedBy(message_lvl4, message_lvl3));
1836  XCTAssertFalse(GPBWasMessageAutocreatedBy(message_lvl3, message_lvl2));
1837  XCTAssertFalse(GPBWasMessageAutocreatedBy(message_lvl2, message));
1838}
1839
1840- (void)testSetAutocreatedExtensionToSelf {
1841  // Setting extension to itself should cause it to become visible.
1842  TestAllExtensions *message = [TestAllExtensions message];
1843  GPBExtensionDescriptor *optionalGroupExtension =
1844      [UnittestRoot optionalGroupExtension];
1845  XCTAssertNotNil([message getExtension:optionalGroupExtension]);
1846  XCTAssertFalse([message hasExtension:optionalGroupExtension]);
1847  [message setExtension:optionalGroupExtension
1848                  value:[message getExtension:optionalGroupExtension]];
1849  XCTAssertTrue([message hasExtension:optionalGroupExtension]);
1850}
1851
1852- (void)testAutocreatedExtensionMemoryLeaks {
1853  GPBExtensionDescriptor *recursiveExtension =
1854      [UnittestObjcRoot recursiveExtension];
1855
1856  // Test for memory leaks with autocreated extensions.
1857  TestAllExtensions *message;
1858  TestAllExtensions *message_lvl2;
1859  TestAllExtensions *message_lvl3;
1860  TestAllExtensions *message_lvl4;
1861  @autoreleasepool {
1862    message = [[TestAllExtensions alloc] init];
1863    message_lvl2 = [[message getExtension:recursiveExtension] retain];
1864    message_lvl3 = [[message_lvl2 getExtension:recursiveExtension] retain];
1865    message_lvl4 = [[message_lvl3 getExtension:recursiveExtension] retain];
1866    [message_lvl2 setExtension:[UnittestRoot optionalInt32Extension]
1867                         value:@(1)];
1868  }
1869
1870  XCTAssertEqual(message.retainCount, (NSUInteger)1);
1871  @autoreleasepool {
1872    [message release];
1873  }
1874  XCTAssertEqual(message_lvl2.retainCount, (NSUInteger)1);
1875  @autoreleasepool {
1876    [message_lvl2 release];
1877  }
1878  XCTAssertEqual(message_lvl3.retainCount, (NSUInteger)1);
1879  @autoreleasepool {
1880    [message_lvl3 release];
1881  }
1882  XCTAssertEqual(message_lvl4.retainCount, (NSUInteger)1);
1883  [message_lvl4 release];
1884}
1885
1886- (void)testSetExtensionWithAutocreatedValue {
1887  GPBExtensionDescriptor *recursiveExtension =
1888      [UnittestObjcRoot recursiveExtension];
1889
1890  TestAllExtensions *message;
1891  @autoreleasepool {
1892    message = [[TestAllExtensions alloc] init];
1893    [message getExtension:recursiveExtension];
1894  }
1895
1896  // This statements checks that the extension value isn't accidentally
1897  // dealloced when removing it from the autocreated map.
1898  [message setExtension:recursiveExtension
1899                  value:[message getExtension:recursiveExtension]];
1900  XCTAssertTrue([message hasExtension:recursiveExtension]);
1901  [message release];
1902}
1903
1904- (void)testRecursion {
1905  TestRecursiveMessage *message = [TestRecursiveMessage message];
1906  XCTAssertNotNil(message.a);
1907  XCTAssertNotNil(message.a.a);
1908  XCTAssertEqual(message.a.a.i, 0);
1909}
1910
1911- (void)testGenerateAndParseUnknownMessage {
1912  GPBUnknownFieldSet *unknowns =
1913      [[[GPBUnknownFieldSet alloc] init] autorelease];
1914  [unknowns mergeVarintField:123 value:456];
1915  GPBMessage *message = [GPBMessage message];
1916  [message setUnknownFields:unknowns];
1917  NSData *data = [message data];
1918  GPBMessage *message2 =
1919      [GPBMessage parseFromData:data extensionRegistry:nil error:NULL];
1920  XCTAssertEqualObjects(message, message2);
1921}
1922
1923- (void)testDelimitedWriteAndParseMultipleMessages {
1924  GPBUnknownFieldSet *unknowns1 =
1925      [[[GPBUnknownFieldSet alloc] init] autorelease];
1926  [unknowns1 mergeVarintField:123 value:456];
1927  GPBMessage *message1 = [GPBMessage message];
1928  [message1 setUnknownFields:unknowns1];
1929
1930  GPBUnknownFieldSet *unknowns2 =
1931      [[[GPBUnknownFieldSet alloc] init] autorelease];
1932  [unknowns2 mergeVarintField:789 value:987];
1933  [unknowns2 mergeVarintField:654 value:321];
1934  GPBMessage *message2 = [GPBMessage message];
1935  [message2 setUnknownFields:unknowns2];
1936
1937  NSMutableData *delimitedData = [NSMutableData data];
1938  [delimitedData appendData:[message1 delimitedData]];
1939  [delimitedData appendData:[message2 delimitedData]];
1940  GPBCodedInputStream *input =
1941      [GPBCodedInputStream streamWithData:delimitedData];
1942  GPBMessage *message3 = [GPBMessage parseDelimitedFromCodedInputStream:input
1943                                                      extensionRegistry:nil
1944                                                                  error:NULL];
1945  GPBMessage *message4 = [GPBMessage parseDelimitedFromCodedInputStream:input
1946                                                      extensionRegistry:nil
1947                                                                  error:NULL];
1948  XCTAssertEqualObjects(message1, message3);
1949  XCTAssertEqualObjects(message2, message4);
1950}
1951
1952- (void)testDuplicateEnums {
1953  XCTAssertEqual(TestEnumWithDupValue_Foo1, TestEnumWithDupValue_Foo2);
1954}
1955
1956- (void)testWeirdDefaults {
1957  ObjcWeirdDefaults *message = [ObjcWeirdDefaults message];
1958  GPBDescriptor *descriptor = [[message class] descriptor];
1959  GPBFieldDescriptor *fieldDesc = [descriptor fieldWithName:@"foo"];
1960  XCTAssertNotNil(fieldDesc);
1961  XCTAssertTrue(fieldDesc.hasDefaultValue);
1962  XCTAssertFalse(message.hasFoo);
1963  XCTAssertEqualObjects(message.foo, @"");
1964
1965  fieldDesc = [descriptor fieldWithName:@"bar"];
1966  XCTAssertNotNil(fieldDesc);
1967  XCTAssertTrue(fieldDesc.hasDefaultValue);
1968  XCTAssertFalse(message.hasBar);
1969  XCTAssertEqualObjects(message.bar, GPBEmptyNSData());
1970}
1971
1972- (void)testEnumDescriptorFromExtensionDescriptor {
1973  GPBExtensionDescriptor *extDescriptor =
1974      [UnittestRoot optionalForeignEnumExtension];
1975  XCTAssertEqual(extDescriptor.dataType, GPBDataTypeEnum);
1976  GPBEnumDescriptor *enumDescriptor = extDescriptor.enumDescriptor;
1977  GPBEnumDescriptor *expectedDescriptor = ForeignEnum_EnumDescriptor();
1978  XCTAssertEqualObjects(enumDescriptor, expectedDescriptor);
1979}
1980
1981- (void)testPropertyNaming {
1982  // objectivec_helpers.cc has some special handing to get proper all caps
1983  // for a few cases to meet objc developer expectations.
1984  //
1985  // This "test" confirms that the expected names are generated, otherwise the
1986  // test itself will fail to compile.
1987  ObjCPropertyNaming *msg = [ObjCPropertyNaming message];
1988  // On their own, at the end, in the middle.
1989  msg.URL = @"good";
1990  msg.thumbnailURL = @"good";
1991  msg.URLFoo = @"good";
1992  msg.someURLBlah = @"good";
1993  msg.HTTP = @"good";
1994  msg.HTTPS = @"good";
1995  // No caps since it was "urls".
1996  [msg.urlsArray addObject:@"good"];
1997}
1998
1999- (void)testEnumNaming {
2000  // objectivec_helpers.cc has some interesting cases to deal with in
2001  // EnumValueName/EnumValueShortName.  Confirm that things generated as
2002  // expected.
2003
2004  // This block just has to compile to confirm we got the expected types/names.
2005  // The *_IsValidValue() calls are just there to keep the projects warnings
2006  // flags happy by providing use of the variables/values.
2007
2008  Foo aFoo = Foo_SerializedSize;
2009  Foo_IsValidValue(aFoo);
2010  aFoo = Foo_Size;
2011  Foo_IsValidValue(aFoo);
2012
2013  Category_Enum aCat = Category_Enum_Red;
2014  Category_Enum_IsValidValue(aCat);
2015
2016  Time aTime = Time_Base;
2017  Time_IsValidValue(aTime);
2018  aTime = Time_SomethingElse;
2019  Time_IsValidValue(aTime);
2020
2021  // This block confirms the names in the descriptors is what we wanted.
2022
2023  GPBEnumDescriptor *descriptor;
2024  NSString *valueName;
2025
2026  descriptor = Foo_EnumDescriptor();
2027  XCTAssertNotNil(descriptor);
2028  XCTAssertEqualObjects(@"Foo", descriptor.name);
2029  valueName = [descriptor enumNameForValue:Foo_SerializedSize];
2030  XCTAssertEqualObjects(@"Foo_SerializedSize", valueName);
2031  valueName = [descriptor enumNameForValue:Foo_Size];
2032  XCTAssertEqualObjects(@"Foo_Size", valueName);
2033
2034  descriptor = Category_Enum_EnumDescriptor();
2035  XCTAssertNotNil(descriptor);
2036  XCTAssertEqualObjects(@"Category_Enum", descriptor.name);
2037  valueName = [descriptor enumNameForValue:Category_Enum_Red];
2038  XCTAssertEqualObjects(@"Category_Enum_Red", valueName);
2039
2040  descriptor = Time_EnumDescriptor();
2041  XCTAssertNotNil(descriptor);
2042  XCTAssertEqualObjects(@"Time", descriptor.name);
2043  valueName = [descriptor enumNameForValue:Time_Base];
2044  XCTAssertEqualObjects(@"Time_Base", valueName);
2045  valueName = [descriptor enumNameForValue:Time_SomethingElse];
2046  XCTAssertEqualObjects(@"Time_SomethingElse", valueName);
2047}
2048
2049- (void)testNegativeEnums {
2050  EnumTestMsg *msg = [EnumTestMsg message];
2051
2052  // Defaults
2053  XCTAssertEqual(msg.foo, EnumTestMsg_MyEnum_Zero);
2054  XCTAssertEqual(msg.bar, EnumTestMsg_MyEnum_One);
2055  XCTAssertEqual(msg.baz, EnumTestMsg_MyEnum_NegOne);
2056  // Bounce to wire and back.
2057  NSData *data = [msg data];
2058  XCTAssertNotNil(data);
2059  EnumTestMsg *msgPrime = [EnumTestMsg parseFromData:data error:NULL];
2060  XCTAssertEqualObjects(msgPrime, msg);
2061  XCTAssertEqual(msgPrime.foo, EnumTestMsg_MyEnum_Zero);
2062  XCTAssertEqual(msgPrime.bar, EnumTestMsg_MyEnum_One);
2063  XCTAssertEqual(msgPrime.baz, EnumTestMsg_MyEnum_NegOne);
2064
2065  // Other values
2066  msg.bar = EnumTestMsg_MyEnum_Two;
2067  msg.baz = EnumTestMsg_MyEnum_NegTwo;
2068  XCTAssertEqual(msg.bar, EnumTestMsg_MyEnum_Two);
2069  XCTAssertEqual(msg.baz, EnumTestMsg_MyEnum_NegTwo);
2070  // Bounce to wire and back.
2071  data = [msg data];
2072  XCTAssertNotNil(data);
2073  msgPrime = [EnumTestMsg parseFromData:data error:NULL];
2074  XCTAssertEqualObjects(msgPrime, msg);
2075  XCTAssertEqual(msgPrime.foo, EnumTestMsg_MyEnum_Zero);
2076  XCTAssertEqual(msgPrime.bar, EnumTestMsg_MyEnum_Two);
2077  XCTAssertEqual(msgPrime.baz, EnumTestMsg_MyEnum_NegTwo);
2078
2079  // Repeated field (shouldn't ever be an issue since developer has to use the
2080  // right GPBArray methods themselves).
2081  msg.mumbleArray = [GPBEnumArray
2082      arrayWithValidationFunction:EnumTestMsg_MyEnum_IsValidValue];
2083  [msg.mumbleArray addValue:EnumTestMsg_MyEnum_Zero];
2084  [msg.mumbleArray addValue:EnumTestMsg_MyEnum_One];
2085  [msg.mumbleArray addValue:EnumTestMsg_MyEnum_Two];
2086  [msg.mumbleArray addValue:EnumTestMsg_MyEnum_NegOne];
2087  [msg.mumbleArray addValue:EnumTestMsg_MyEnum_NegTwo];
2088  XCTAssertEqual([msg.mumbleArray valueAtIndex:0], EnumTestMsg_MyEnum_Zero);
2089  XCTAssertEqual([msg.mumbleArray valueAtIndex:1], EnumTestMsg_MyEnum_One);
2090  XCTAssertEqual([msg.mumbleArray valueAtIndex:2], EnumTestMsg_MyEnum_Two);
2091  XCTAssertEqual([msg.mumbleArray valueAtIndex:3], EnumTestMsg_MyEnum_NegOne);
2092  XCTAssertEqual([msg.mumbleArray valueAtIndex:4], EnumTestMsg_MyEnum_NegTwo);
2093  // Bounce to wire and back.
2094  data = [msg data];
2095  XCTAssertNotNil(data);
2096  msgPrime = [EnumTestMsg parseFromData:data error:NULL];
2097  XCTAssertEqualObjects(msgPrime, msg);
2098  XCTAssertEqual([msgPrime.mumbleArray valueAtIndex:0],
2099                 EnumTestMsg_MyEnum_Zero);
2100  XCTAssertEqual([msgPrime.mumbleArray valueAtIndex:1], EnumTestMsg_MyEnum_One);
2101  XCTAssertEqual([msgPrime.mumbleArray valueAtIndex:2], EnumTestMsg_MyEnum_Two);
2102  XCTAssertEqual([msgPrime.mumbleArray valueAtIndex:3],
2103                 EnumTestMsg_MyEnum_NegOne);
2104  XCTAssertEqual([msgPrime.mumbleArray valueAtIndex:4],
2105                 EnumTestMsg_MyEnum_NegTwo);
2106}
2107
2108- (void)testReservedWordNaming {
2109  // objectivec_helpers.cc has some special handing to make sure that
2110  // some "reserved" objc names get renamed in a way so they
2111  // don't conflict.
2112  //
2113  // This "test" confirms that the expected names are generated,
2114  // otherwise the test itself will fail to compile.
2115  self_Class *msg = [self_Class message];
2116
2117  // Some ObjC/C/C++ keywords.
2118  msg.className_p = msg.hasClassName_p;
2119  msg.cmd = msg.hasCmd;
2120  msg.nullable_p = msg.hasNullable_p;
2121  msg.typeof_p = msg.hasTypeof_p;
2122  msg.instancetype_p = msg.hasInstancetype_p;
2123  msg.nil_p = msg.hasNil_p;
2124  msg.instancetype_p = msg.hasInstancetype_p;
2125  msg.public_p = msg.hasPublic_p;
2126
2127  // Some that would override NSObject methods
2128  msg.camltype = msg.hasCamltype;
2129  msg.isNsdictionary = msg.hasIsNsdictionary;
2130  msg.dealloc_p = msg.hasDealloc_p;
2131  msg.zone_p = msg.hasZone_p;
2132  msg.accessibilityLabel_p = msg.hasAccessibilityLabel_p;
2133
2134  // Some that we shouldn't need to handle.
2135  msg.atomic = msg.hasAtomic;
2136  msg.nonatomic = msg.hasNonatomic;
2137  msg.strong = msg.hasStrong;
2138  msg.nullResettable = msg.hasNullResettable;
2139
2140  // Some that would override GPBMessage methods
2141  msg.clear_p = msg.hasClear_p;
2142  msg.data_p = msg.hasData_p;
2143
2144  // Some MacTypes
2145  msg.fixed = msg.hasFixed;
2146  msg.style = msg.hasStyle;
2147
2148  // Some C Identifiers
2149  msg.generic = msg.hasGeneric;
2150  msg.block = msg.hasBlock;
2151}
2152
2153- (void)testOneBasedEnumHolder {
2154  // Test case for https://github.com/protocolbuffers/protobuf/issues/1453
2155  // Message with no explicit defaults, but a non zero default for an enum.
2156  MessageWithOneBasedEnum *enumMsg = [MessageWithOneBasedEnum message];
2157  XCTAssertEqual(enumMsg.enumField, MessageWithOneBasedEnum_OneBasedEnum_One);
2158}
2159
2160- (void)testBoolOffsetUsage {
2161  // Bools use storage within has_bits; this test ensures that this is honored
2162  // in all places where things should crash or fail based on reading out of
2163  // field storage instead.
2164  BoolOnlyMessage *msg1 = [BoolOnlyMessage message];
2165  BoolOnlyMessage *msg2 = [BoolOnlyMessage message];
2166
2167  msg1.boolField1 = YES;
2168  msg2.boolField1 = YES;
2169  msg1.boolField3 = YES;
2170  msg2.boolField3 = YES;
2171  msg1.boolField5 = YES;
2172  msg2.boolField5 = YES;
2173  msg1.boolField7 = YES;
2174  msg2.boolField7 = YES;
2175  msg1.boolField9 = YES;
2176  msg2.boolField9 = YES;
2177  msg1.boolField11 = YES;
2178  msg2.boolField11 = YES;
2179  msg1.boolField13 = YES;
2180  msg2.boolField13 = YES;
2181  msg1.boolField15 = YES;
2182  msg2.boolField15 = YES;
2183  msg1.boolField17 = YES;
2184  msg2.boolField17 = YES;
2185  msg1.boolField19 = YES;
2186  msg2.boolField19 = YES;
2187  msg1.boolField21 = YES;
2188  msg2.boolField21 = YES;
2189  msg1.boolField23 = YES;
2190  msg2.boolField23 = YES;
2191  msg1.boolField25 = YES;
2192  msg2.boolField25 = YES;
2193  msg1.boolField27 = YES;
2194  msg2.boolField27 = YES;
2195  msg1.boolField29 = YES;
2196  msg2.boolField29 = YES;
2197  msg1.boolField31 = YES;
2198  msg2.boolField31 = YES;
2199
2200  msg1.boolField32 = YES;
2201  msg2.boolField32 = YES;
2202
2203  XCTAssertTrue(msg1 != msg2); // Different pointers.
2204  XCTAssertEqual([msg1 hash], [msg2 hash]);
2205  XCTAssertEqualObjects(msg1, msg2);
2206
2207  BoolOnlyMessage *msg1Prime = [[msg1 copy] autorelease];
2208  XCTAssertTrue(msg1Prime != msg1); // Different pointers.
2209  XCTAssertEqual([msg1 hash], [msg1Prime hash]);
2210  XCTAssertEqualObjects(msg1, msg1Prime);
2211
2212  // Field set in one, but not the other means they don't match (even if
2213  // set to default value).
2214  msg1Prime.boolField2 = NO;
2215  XCTAssertNotEqualObjects(msg1Prime, msg1);
2216  // And when set to different values.
2217  msg1.boolField2 = YES;
2218  XCTAssertNotEqualObjects(msg1Prime, msg1);
2219  // And then they match again.
2220  msg1.boolField2 = NO;
2221  XCTAssertEqualObjects(msg1Prime, msg1);
2222  XCTAssertEqual([msg1 hash], [msg1Prime hash]);
2223}
2224
2225- (void)testCopyingMapFields {
2226  TestMessageOfMaps *msg = [TestMessageOfMaps message];
2227
2228  msg.strToStr[@"foo"] = @"bar";
2229
2230  [msg.strToInt setInt32:1 forKey:@"mumble"];
2231  [msg.intToStr setObject:@"wee" forKey:42];
2232  [msg.intToInt setInt32:123 forKey:321];
2233
2234  [msg.strToBool setBool:YES forKey:@"one"];
2235  [msg.boolToStr setObject:@"something" forKey:YES];
2236  [msg.boolToBool setBool:YES forKey:NO];
2237
2238  [msg.intToBool setBool:YES forKey:13];
2239  [msg.boolToInt setInt32:111 forKey:NO];
2240
2241  TestAllTypes *subMsg1 = [TestAllTypes message];
2242  subMsg1.optionalInt32 = 1;
2243  TestAllTypes *subMsg2 = [TestAllTypes message];
2244  subMsg1.optionalInt32 = 2;
2245  TestAllTypes *subMsg3 = [TestAllTypes message];
2246  subMsg1.optionalInt32 = 3;
2247
2248  msg.strToMsg[@"baz"] = subMsg1;
2249  [msg.intToMsg setObject:subMsg2 forKey:222];
2250  [msg.boolToMsg setObject:subMsg3 forKey:YES];
2251
2252  TestMessageOfMaps *msg2 = [[msg copy] autorelease];
2253  XCTAssertNotNil(msg2);
2254  XCTAssertEqualObjects(msg2, msg);
2255  XCTAssertTrue(msg2 != msg);  // ptr compare
2256  XCTAssertTrue(msg.strToStr != msg2.strToStr);  // ptr compare
2257  XCTAssertTrue(msg.intToStr != msg2.intToStr);  // ptr compare
2258  XCTAssertTrue(msg.intToInt != msg2.intToInt);  // ptr compare
2259  XCTAssertTrue(msg.strToBool != msg2.strToBool);  // ptr compare
2260  XCTAssertTrue(msg.boolToStr != msg2.boolToStr);  // ptr compare
2261  XCTAssertTrue(msg.boolToBool != msg2.boolToBool);  // ptr compare
2262  XCTAssertTrue(msg.intToBool != msg2.intToBool);  // ptr compare
2263  XCTAssertTrue(msg.boolToInt != msg2.boolToInt);  // ptr compare
2264  XCTAssertTrue(msg.strToMsg != msg2.strToMsg);  // ptr compare
2265  XCTAssertTrue(msg.intToMsg != msg2.intToMsg);  // ptr compare
2266  XCTAssertTrue(msg.boolToMsg != msg2.boolToMsg);  // ptr compare
2267
2268  XCTAssertTrue(msg.strToMsg[@"baz"] != msg2.strToMsg[@"baz"]);  // ptr compare
2269  XCTAssertEqualObjects(msg.strToMsg[@"baz"], msg2.strToMsg[@"baz"]);
2270  XCTAssertTrue([msg.intToMsg objectForKey:222] != [msg2.intToMsg objectForKey:222]);  // ptr compare
2271  XCTAssertEqualObjects([msg.intToMsg objectForKey:222], [msg2.intToMsg objectForKey:222]);
2272  XCTAssertTrue([msg.boolToMsg objectForKey:YES] != [msg2.boolToMsg objectForKey:YES]);  // ptr compare
2273  XCTAssertEqualObjects([msg.boolToMsg objectForKey:YES], [msg2.boolToMsg objectForKey:YES]);
2274}
2275
2276- (void)testPrefixedNames {
2277  // The fact that this compiles is sufficient as a test.
2278  // The assertions are just there to avoid "not-used" warnings.
2279
2280  // Verify that enum types and values get the prefix.
2281  GPBTESTTestObjcProtoPrefixEnum value = GPBTESTTestObjcProtoPrefixEnum_Value;
2282  XCTAssertNotEqual(value, 0);
2283
2284  // Verify that roots get the prefix.
2285  GPBTESTUnittestObjcOptionsRoot *root = nil;
2286  XCTAssertNil(root);
2287
2288  // Verify that messages that don't already have the prefix get a prefix.
2289  GPBTESTTestObjcProtoPrefixMessage *prefixedMessage = nil;
2290  XCTAssertNil(prefixedMessage);
2291
2292  // Verify that messages that already have a prefix aren't prefixed twice.
2293  GPBTESTTestHasAPrefixMessage *alreadyPrefixedMessage = nil;
2294  XCTAssertNil(alreadyPrefixedMessage);
2295
2296  // Verify that enums that already have a prefix aren't prefixed twice.
2297  GPBTESTTestHasAPrefixEnum prefixedValue = GPBTESTTestHasAPrefixEnum_ValueB;
2298  XCTAssertNotEqual(prefixedValue, 0);
2299
2300  // Verify that classes named the same as prefixes are prefixed.
2301  GPBTESTGPBTEST *prefixMessage = nil;
2302  XCTAssertNil(prefixMessage);
2303
2304  // Verify that classes that have the prefix followed by a lowercase
2305  // letter DO get the prefix.
2306  GPBTESTGPBTESTshouldGetAPrefixMessage *shouldGetAPrefixMessage = nil;
2307  XCTAssertNil(shouldGetAPrefixMessage);
2308}
2309
2310@end
2311