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