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