Internal changes
[google-protobuf.git] / objectivec / Tests / GPBUnknownFieldsTest.m
blob24cae7781a8d15f352b8deabefd2a7c204e2687c
1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2024 Google Inc.  All rights reserved.
3 //
4 // Use of this source code is governed by a BSD-style
5 // license that can be found in the LICENSE file or at
6 // https://developers.google.com/open-source/licenses/bsd
8 #import <Foundation/Foundation.h>
10 #import "GPBTestUtilities.h"
11 #import "GPBUnknownField.h"
12 #import "GPBUnknownFields.h"
13 #import "GPBUnknownFields_PackagePrivate.h"
14 #import "objectivec/Tests/Unittest.pbobjc.h"
16 @interface UnknownFieldsTest : GPBTestCase
17 @end
19 @implementation UnknownFieldsTest
21 - (void)testEmptyAndClear {
22   GPBUnknownFields* ufs = [[[GPBUnknownFields alloc] init] autorelease];
23   XCTAssertTrue(ufs.empty);
25   [ufs addFieldNumber:1 varint:1];
26   XCTAssertFalse(ufs.empty);
27   [ufs clear];
28   XCTAssertTrue(ufs.empty);
30   [ufs addFieldNumber:1 fixed32:1];
31   XCTAssertFalse(ufs.empty);
32   [ufs clear];
33   XCTAssertTrue(ufs.empty);
35   [ufs addFieldNumber:1 fixed64:1];
36   XCTAssertFalse(ufs.empty);
37   [ufs clear];
38   XCTAssertTrue(ufs.empty);
40   [ufs addFieldNumber:1 lengthDelimited:[NSData data]];
41   XCTAssertFalse(ufs.empty);
42   [ufs clear];
43   XCTAssertTrue(ufs.empty);
45   GPBUnknownFields* group = [ufs addGroupWithFieldNumber:1];
46   XCTAssertNotNil(group);
47   XCTAssertFalse(ufs.empty);
50 - (void)testEqualityAndHash {
51   // This also calls the methods on the `GPBUnknownField` objects for completeness and to
52   // make any failure in that class easier to notice/debug.
54   // Empty
56   GPBUnknownFields* ufs1 = [[[GPBUnknownFields alloc] init] autorelease];
57   XCTAssertTrue([ufs1 isEqual:ufs1]);
58   XCTAssertFalse([ufs1 isEqual:@"foo"]);
59   GPBUnknownFields* ufs2 = [[[GPBUnknownFields alloc] init] autorelease];
60   XCTAssertEqualObjects(ufs1, ufs2);
61   XCTAssertEqual([ufs1 hash], [ufs2 hash]);
63   // Varint
65   [ufs1 addFieldNumber:1 varint:1];
66   XCTAssertNotEqualObjects(ufs1, ufs2);
67   [ufs2 addFieldNumber:1 varint:1];
68   XCTAssertEqualObjects(ufs1, ufs2);
69   XCTAssertEqual([ufs1 hash], [ufs2 hash]);
70   GPBUnknownField* field1 = [[ufs1 fields:1] firstObject];
71   XCTAssertNotNil(field1);
72   GPBUnknownField* field2 = [[ufs2 fields:1] firstObject];
73   XCTAssertNotNil(field2);
74   XCTAssertEqualObjects(field1, field2);
75   XCTAssertTrue(field1 != field2);  // Different objects.
76   XCTAssertEqual([field1 hash], [field2 hash]);
78   // Fixed32
80   [ufs1 addFieldNumber:2 fixed32:1];
81   XCTAssertNotEqualObjects(ufs1, ufs2);
82   [ufs2 addFieldNumber:2 fixed32:1];
83   XCTAssertEqualObjects(ufs1, ufs2);
84   XCTAssertEqual([ufs1 hash], [ufs2 hash]);
85   field1 = [[ufs1 fields:2] firstObject];
86   XCTAssertNotNil(field1);
87   field2 = [[ufs2 fields:2] firstObject];
88   XCTAssertNotNil(field2);
89   XCTAssertEqualObjects(field1, field2);
90   XCTAssertTrue(field1 != field2);  // Different objects.
91   XCTAssertEqual([field1 hash], [field2 hash]);
93   // Fixed64
95   [ufs1 addFieldNumber:3 fixed64:1];
96   XCTAssertNotEqualObjects(ufs1, ufs2);
97   [ufs2 addFieldNumber:3 fixed64:1];
98   XCTAssertEqualObjects(ufs1, ufs2);
99   XCTAssertEqual([ufs1 hash], [ufs2 hash]);
100   field1 = [[ufs1 fields:3] firstObject];
101   XCTAssertNotNil(field1);
102   field2 = [[ufs2 fields:3] firstObject];
103   XCTAssertNotNil(field2);
104   XCTAssertEqualObjects(field1, field2);
105   XCTAssertTrue(field1 != field2);  // Different objects.
106   XCTAssertEqual([field1 hash], [field2 hash]);
108   // LengthDelimited
110   [ufs1 addFieldNumber:4 lengthDelimited:DataFromCStr("foo")];
111   XCTAssertNotEqualObjects(ufs1, ufs2);
112   [ufs2 addFieldNumber:4 lengthDelimited:DataFromCStr("foo")];
113   XCTAssertEqualObjects(ufs1, ufs2);
114   XCTAssertEqual([ufs1 hash], [ufs2 hash]);
115   field1 = [[ufs1 fields:4] firstObject];
116   XCTAssertNotNil(field1);
117   field2 = [[ufs2 fields:4] firstObject];
118   XCTAssertNotNil(field2);
119   XCTAssertEqualObjects(field1, field2);
120   XCTAssertTrue(field1 != field2);  // Different objects.
121   XCTAssertEqual([field1 hash], [field2 hash]);
123   // Group
125   GPBUnknownFields* group1 = [ufs1 addGroupWithFieldNumber:5];
126   [group1 addFieldNumber:10 varint:10];
127   XCTAssertNotEqualObjects(ufs1, ufs2);
128   GPBUnknownFields* group2 = [ufs2 addGroupWithFieldNumber:5];
129   [group2 addFieldNumber:10 varint:10];
130   XCTAssertEqualObjects(ufs1, ufs2);
131   XCTAssertEqual([ufs1 hash], [ufs2 hash]);
132   field1 = [[ufs1 fields:5] firstObject];
133   XCTAssertNotNil(field1);
134   field2 = [[ufs2 fields:5] firstObject];
135   XCTAssertNotNil(field2);
136   XCTAssertEqualObjects(field1, field2);
137   XCTAssertTrue(field1 != field2);  // Different objects.
138   XCTAssertEqual([field1 hash], [field2 hash]);
141 - (void)testInequality_Values {
142   // Same field number and type, different values.
144   // This also calls the methods on the `GPBUnknownField` objects for completeness and to
145   // make any failure in that class easier to notice/debug.
147   GPBUnknownFields* ufs1 = [[[GPBUnknownFields alloc] init] autorelease];
148   GPBUnknownFields* ufs2 = [[[GPBUnknownFields alloc] init] autorelease];
150   [ufs1 addFieldNumber:1 varint:1];
151   [ufs2 addFieldNumber:1 varint:2];
152   XCTAssertNotEqualObjects(ufs1, ufs2);
153   GPBUnknownField* field1 = [[ufs1 fields:1] firstObject];
154   XCTAssertNotNil(field1);
155   GPBUnknownField* field2 = [[ufs2 fields:1] firstObject];
156   XCTAssertNotNil(field2);
157   XCTAssertNotEqualObjects(field1, field2);
158   XCTAssertTrue(field1 != field2);  // Different objects.
160   [ufs1 clear];
161   [ufs2 clear];
162   XCTAssertEqualObjects(ufs1, ufs2);
164   [ufs1 addFieldNumber:1 fixed32:1];
165   [ufs2 addFieldNumber:1 fixed32:2];
166   XCTAssertNotEqualObjects(ufs1, ufs2);
167   field1 = [[ufs1 fields:1] firstObject];
168   XCTAssertNotNil(field1);
169   field2 = [[ufs2 fields:1] firstObject];
170   XCTAssertNotNil(field2);
171   XCTAssertNotEqualObjects(field1, field2);
172   XCTAssertTrue(field1 != field2);  // Different objects.
174   [ufs1 clear];
175   [ufs2 clear];
176   XCTAssertEqualObjects(ufs1, ufs2);
178   [ufs1 addFieldNumber:1 fixed64:1];
179   [ufs2 addFieldNumber:1 fixed64:2];
180   XCTAssertNotEqualObjects(ufs1, ufs2);
181   field1 = [[ufs1 fields:1] firstObject];
182   XCTAssertNotNil(field1);
183   field2 = [[ufs2 fields:1] firstObject];
184   XCTAssertNotNil(field2);
185   XCTAssertNotEqualObjects(field1, field2);
186   XCTAssertTrue(field1 != field2);  // Different objects.
188   [ufs1 clear];
189   [ufs2 clear];
190   XCTAssertEqualObjects(ufs1, ufs2);
192   [ufs1 addFieldNumber:1 lengthDelimited:DataFromCStr("foo")];
193   [ufs2 addFieldNumber:1 lengthDelimited:DataFromCStr("bar")];
194   XCTAssertNotEqualObjects(ufs1, ufs2);
195   field1 = [[ufs1 fields:1] firstObject];
196   XCTAssertNotNil(field1);
197   field2 = [[ufs2 fields:1] firstObject];
198   XCTAssertNotNil(field2);
199   XCTAssertNotEqualObjects(field1, field2);
200   XCTAssertTrue(field1 != field2);  // Different objects.
202   [ufs1 clear];
203   [ufs2 clear];
204   XCTAssertEqualObjects(ufs1, ufs2);
206   GPBUnknownFields* group1 = [ufs1 addGroupWithFieldNumber:1];
207   GPBUnknownFields* group2 = [ufs2 addGroupWithFieldNumber:1];
208   [group1 addFieldNumber:10 varint:10];
209   [group2 addFieldNumber:10 varint:20];
210   XCTAssertNotEqualObjects(ufs1, ufs2);
211   XCTAssertNotEqualObjects(group1, group2);
212   field1 = [[ufs1 fields:1] firstObject];
213   XCTAssertNotNil(field1);
214   field2 = [[ufs2 fields:1] firstObject];
215   XCTAssertNotNil(field2);
216   XCTAssertNotEqualObjects(field1, field2);
217   XCTAssertTrue(field1 != field2);  // Different objects.
220 - (void)testInequality_FieldNumbers {
221   // Same type and value, different field numbers.
223   // This also calls the methods on the `GPBUnknownField` objects for completeness and to
224   // make any failure in that class easier to notice/debug.
226   GPBUnknownFields* ufs1 = [[[GPBUnknownFields alloc] init] autorelease];
227   GPBUnknownFields* ufs2 = [[[GPBUnknownFields alloc] init] autorelease];
229   [ufs1 addFieldNumber:1 varint:1];
230   [ufs2 addFieldNumber:2 varint:1];
231   XCTAssertNotEqualObjects(ufs1, ufs2);
232   GPBUnknownField* field1 = [[ufs1 fields:1] firstObject];
233   XCTAssertNotNil(field1);
234   GPBUnknownField* field2 = [[ufs2 fields:2] firstObject];
235   XCTAssertNotNil(field2);
236   XCTAssertNotEqualObjects(field1, field2);
237   XCTAssertTrue(field1 != field2);  // Different objects.
239   [ufs1 clear];
240   [ufs2 clear];
241   XCTAssertEqualObjects(ufs1, ufs2);
243   [ufs1 addFieldNumber:1 fixed32:1];
244   [ufs2 addFieldNumber:2 fixed32:1];
245   XCTAssertNotEqualObjects(ufs1, ufs2);
246   field1 = [[ufs1 fields:1] firstObject];
247   XCTAssertNotNil(field1);
248   field2 = [[ufs2 fields:2] firstObject];
249   XCTAssertNotNil(field2);
250   XCTAssertNotEqualObjects(field1, field2);
251   XCTAssertTrue(field1 != field2);  // Different objects.
253   [ufs1 clear];
254   [ufs2 clear];
255   XCTAssertEqualObjects(ufs1, ufs2);
257   [ufs1 addFieldNumber:1 fixed64:1];
258   [ufs2 addFieldNumber:2 fixed64:1];
259   XCTAssertNotEqualObjects(ufs1, ufs2);
260   field1 = [[ufs1 fields:1] firstObject];
261   XCTAssertNotNil(field1);
262   field2 = [[ufs2 fields:2] firstObject];
263   XCTAssertNotNil(field2);
264   XCTAssertNotEqualObjects(field1, field2);
265   XCTAssertTrue(field1 != field2);  // Different objects.
267   [ufs1 clear];
268   [ufs2 clear];
269   XCTAssertEqualObjects(ufs1, ufs2);
271   [ufs1 addFieldNumber:1 lengthDelimited:DataFromCStr("foo")];
272   [ufs2 addFieldNumber:2 lengthDelimited:DataFromCStr("fod")];
273   XCTAssertNotEqualObjects(ufs1, ufs2);
274   field1 = [[ufs1 fields:1] firstObject];
275   XCTAssertNotNil(field1);
276   field2 = [[ufs2 fields:2] firstObject];
277   XCTAssertNotNil(field2);
278   XCTAssertNotEqualObjects(field1, field2);
279   XCTAssertTrue(field1 != field2);  // Different objects.
281   [ufs1 clear];
282   [ufs2 clear];
283   XCTAssertEqualObjects(ufs1, ufs2);
285   GPBUnknownFields* group1 = [ufs1 addGroupWithFieldNumber:1];
286   GPBUnknownFields* group2 = [ufs2 addGroupWithFieldNumber:2];
287   [group1 addFieldNumber:10 varint:10];
288   [group2 addFieldNumber:10 varint:10];
289   XCTAssertNotEqualObjects(ufs1, ufs2);
290   XCTAssertEqualObjects(group1, group2);
291   field1 = [[ufs1 fields:1] firstObject];
292   XCTAssertNotNil(field1);
293   field2 = [[ufs2 fields:2] firstObject];
294   XCTAssertNotNil(field2);
295   XCTAssertNotEqualObjects(field1, field2);
296   XCTAssertTrue(field1 != field2);  // Different objects.
299 - (void)testInequality_Types {
300   // Same field number and value when possible, different types.
302   // This also calls the methods on the `GPBUnknownField` objects for completeness and to
303   // make any failure in that class easier to notice/debug.
305   GPBUnknownFields* ufs1 = [[[GPBUnknownFields alloc] init] autorelease];
306   GPBUnknownFields* ufs2 = [[[GPBUnknownFields alloc] init] autorelease];
308   [ufs1 addFieldNumber:1 varint:1];
309   [ufs2 addFieldNumber:1 fixed32:1];
310   XCTAssertNotEqualObjects(ufs1, ufs2);
311   GPBUnknownField* field1 = [[ufs1 fields:1] firstObject];
312   XCTAssertNotNil(field1);
313   GPBUnknownField* field2 = [[ufs2 fields:1] firstObject];
314   XCTAssertNotNil(field2);
315   XCTAssertNotEqualObjects(field1, field2);
316   XCTAssertTrue(field1 != field2);  // Different objects.
318   [ufs1 clear];
319   [ufs2 clear];
320   XCTAssertEqualObjects(ufs1, ufs2);
322   [ufs1 addFieldNumber:1 fixed32:1];
323   [ufs2 addFieldNumber:1 fixed64:1];
324   XCTAssertNotEqualObjects(ufs1, ufs2);
325   field1 = [[ufs1 fields:1] firstObject];
326   XCTAssertNotNil(field1);
327   field2 = [[ufs2 fields:1] firstObject];
328   XCTAssertNotNil(field2);
329   XCTAssertNotEqualObjects(field1, field2);
330   XCTAssertTrue(field1 != field2);  // Different objects.
332   [ufs1 clear];
333   [ufs2 clear];
334   XCTAssertEqualObjects(ufs1, ufs2);
336   [ufs1 addFieldNumber:1 fixed64:1];
337   [ufs2 addFieldNumber:1 varint:1];
338   XCTAssertNotEqualObjects(ufs1, ufs2);
339   field1 = [[ufs1 fields:1] firstObject];
340   XCTAssertNotNil(field1);
341   field2 = [[ufs2 fields:1] firstObject];
342   XCTAssertNotNil(field2);
343   XCTAssertNotEqualObjects(field1, field2);
344   XCTAssertTrue(field1 != field2);  // Different objects.
346   [ufs1 clear];
347   [ufs2 clear];
348   XCTAssertEqualObjects(ufs1, ufs2);
350   [ufs1 addFieldNumber:1 lengthDelimited:DataFromCStr("foo")];
351   [ufs2 addFieldNumber:1 varint:1];
352   XCTAssertNotEqualObjects(ufs1, ufs2);
353   field1 = [[ufs1 fields:1] firstObject];
354   XCTAssertNotNil(field1);
355   field2 = [[ufs2 fields:1] firstObject];
356   XCTAssertNotNil(field2);
357   XCTAssertNotEqualObjects(field1, field2);
358   XCTAssertTrue(field1 != field2);  // Different objects.
360   [ufs1 clear];
361   [ufs2 clear];
362   XCTAssertEqualObjects(ufs1, ufs2);
364   GPBUnknownFields* group1 = [ufs1 addGroupWithFieldNumber:1];
365   [group1 addFieldNumber:10 varint:10];
366   [ufs2 addFieldNumber:1 varint:1];
367   XCTAssertNotEqualObjects(ufs1, ufs2);
368   field1 = [[ufs1 fields:1] firstObject];
369   XCTAssertNotNil(field1);
370   field2 = [[ufs2 fields:1] firstObject];
371   XCTAssertNotNil(field2);
372   XCTAssertNotEqualObjects(field1, field2);
373   XCTAssertTrue(field1 != field2);  // Different objects.
376 - (void)testGetFirst {
377   GPBUnknownFields* ufs = [[[GPBUnknownFields alloc] init] autorelease];
378   XCTAssertEqual(0U, ufs.count);
379   [ufs addFieldNumber:1 varint:1];
380   XCTAssertEqual(1U, ufs.count);
381   [ufs addFieldNumber:1 varint:2];
382   XCTAssertEqual(2U, ufs.count);
383   [ufs addFieldNumber:1 fixed32:3];
384   XCTAssertEqual(3U, ufs.count);
385   [ufs addFieldNumber:1 fixed32:4];
386   XCTAssertEqual(4U, ufs.count);
387   [ufs addFieldNumber:1 fixed64:5];
388   XCTAssertEqual(5U, ufs.count);
389   [ufs addFieldNumber:1 fixed64:6];
390   XCTAssertEqual(6U, ufs.count);
391   [ufs addFieldNumber:1 lengthDelimited:DataFromCStr("foo")];
392   XCTAssertEqual(7U, ufs.count);
393   [ufs addFieldNumber:1 lengthDelimited:DataFromCStr("bar")];
394   XCTAssertEqual(8U, ufs.count);
395   GPBUnknownFields* group1 = [ufs addGroupWithFieldNumber:1];
396   XCTAssertNotNil(group1);
397   XCTAssertEqual(9U, ufs.count);
398   GPBUnknownFields* group2 = [ufs addGroupWithFieldNumber:1];
399   XCTAssertNotNil(group2);
400   XCTAssertTrue(group1 != group2);  // Different objects
401   XCTAssertEqual(10U, ufs.count);
403   [ufs addFieldNumber:11 varint:11];
404   [ufs addFieldNumber:12 fixed32:12];
405   [ufs addFieldNumber:13 fixed64:13];
406   [ufs addFieldNumber:14 lengthDelimited:DataFromCStr("foo2")];
407   GPBUnknownFields* group3 = [ufs addGroupWithFieldNumber:15];
408   XCTAssertNotNil(group3);
409   XCTAssertTrue(group3 != group1);  // Different objects
410   XCTAssertTrue(group3 != group2);  // Different objects
411   XCTAssertEqual(15U, ufs.count);
413   uint64_t varint = 0;
414   XCTAssertTrue([ufs getFirst:1 varint:&varint]);
415   XCTAssertEqual(1U, varint);
416   XCTAssertTrue([ufs getFirst:11 varint:&varint]);
417   XCTAssertEqual(11U, varint);
418   XCTAssertFalse([ufs getFirst:12 varint:&varint]);  // Different type
419   XCTAssertFalse([ufs getFirst:99 varint:&varint]);  // Not present
421   uint32_t fixed32 = 0;
422   XCTAssertTrue([ufs getFirst:1 fixed32:&fixed32]);
423   XCTAssertEqual(3U, fixed32);
424   XCTAssertTrue([ufs getFirst:12 fixed32:&fixed32]);
425   XCTAssertEqual(12U, fixed32);
426   XCTAssertFalse([ufs getFirst:11 fixed32:&fixed32]);  // Different type
427   XCTAssertFalse([ufs getFirst:99 fixed32:&fixed32]);  // Not present
429   uint64_t fixed64 = 0;
430   XCTAssertTrue([ufs getFirst:1 fixed64:&fixed64]);
431   XCTAssertEqual(5U, fixed64);
432   XCTAssertTrue([ufs getFirst:13 fixed64:&fixed64]);
433   XCTAssertEqual(13U, fixed64);
434   XCTAssertFalse([ufs getFirst:11 fixed64:&fixed64]);  // Different type
435   XCTAssertFalse([ufs getFirst:99 fixed64:&fixed64]);  // Not present
437   XCTAssertEqualObjects(DataFromCStr("foo"), [ufs firstLengthDelimited:1]);
438   XCTAssertEqualObjects(DataFromCStr("foo2"), [ufs firstLengthDelimited:14]);
439   XCTAssertNil([ufs firstLengthDelimited:11]);  // Different type
440   XCTAssertNil([ufs firstLengthDelimited:99]);  // Not present
442   XCTAssertTrue(group1 == [ufs firstGroup:1]);   // Testing ptr, exact object
443   XCTAssertTrue(group3 == [ufs firstGroup:15]);  // Testing ptr, exact object
444   XCTAssertNil([ufs firstGroup:11]);             // Different type
445   XCTAssertNil([ufs firstGroup:99]);             // Not present
448 - (void)testGetFields {
449   GPBUnknownFields* ufs = [[[GPBUnknownFields alloc] init] autorelease];
450   [ufs addFieldNumber:1 varint:1];
451   [ufs addFieldNumber:2 varint:2];
452   [ufs addFieldNumber:1 fixed32:3];
453   [ufs addFieldNumber:2 fixed32:4];
454   [ufs addFieldNumber:1 fixed64:5];
455   [ufs addFieldNumber:3 fixed64:6];
456   [ufs addFieldNumber:1 lengthDelimited:DataFromCStr("foo")];
457   [ufs addFieldNumber:2 lengthDelimited:DataFromCStr("bar")];
458   GPBUnknownFields* group1 = [ufs addGroupWithFieldNumber:1];
459   GPBUnknownFields* group2 = [ufs addGroupWithFieldNumber:3];
461   NSArray<GPBUnknownField*>* fields1 = [ufs fields:1];
462   XCTAssertEqual(fields1.count, 5);
463   GPBUnknownField* field = fields1[0];
464   XCTAssertEqual(field.number, 1);
465   XCTAssertEqual(field.type, GPBUnknownFieldTypeVarint);
466   XCTAssertEqual(field.varint, 1);
467   field = fields1[1];
468   XCTAssertEqual(field.number, 1);
469   XCTAssertEqual(field.type, GPBUnknownFieldTypeFixed32);
470   XCTAssertEqual(field.fixed32, 3);
471   field = fields1[2];
472   XCTAssertEqual(field.number, 1);
473   XCTAssertEqual(field.type, GPBUnknownFieldTypeFixed64);
474   XCTAssertEqual(field.fixed64, 5);
475   field = fields1[3];
476   XCTAssertEqual(field.number, 1);
477   XCTAssertEqual(field.type, GPBUnknownFieldTypeLengthDelimited);
478   XCTAssertEqualObjects(field.lengthDelimited, DataFromCStr("foo"));
479   field = fields1[4];
480   XCTAssertEqual(field.number, 1);
481   XCTAssertEqual(field.type, GPBUnknownFieldTypeGroup);
482   XCTAssertTrue(field.group == group1);  // Exact object.
484   NSArray<GPBUnknownField*>* fields2 = [ufs fields:2];
485   XCTAssertEqual(fields2.count, 3);
486   field = fields2[0];
487   XCTAssertEqual(field.number, 2);
488   XCTAssertEqual(field.type, GPBUnknownFieldTypeVarint);
489   XCTAssertEqual(field.varint, 2);
490   field = fields2[1];
491   XCTAssertEqual(field.number, 2);
492   XCTAssertEqual(field.type, GPBUnknownFieldTypeFixed32);
493   XCTAssertEqual(field.fixed32, 4);
494   field = fields2[2];
495   XCTAssertEqual(field.number, 2);
496   XCTAssertEqual(field.type, GPBUnknownFieldTypeLengthDelimited);
497   XCTAssertEqualObjects(field.lengthDelimited, DataFromCStr("bar"));
499   NSArray<GPBUnknownField*>* fields3 = [ufs fields:3];
500   XCTAssertEqual(fields3.count, 2);
501   field = fields3[0];
502   XCTAssertEqual(field.number, 3);
503   XCTAssertEqual(field.type, GPBUnknownFieldTypeFixed64);
504   XCTAssertEqual(field.fixed64, 6);
505   field = fields3[1];
506   XCTAssertEqual(field.number, 3);
507   XCTAssertEqual(field.type, GPBUnknownFieldTypeGroup);
508   XCTAssertTrue(field.group == group2);  // Exact object.
510   XCTAssertNil([ufs fields:99]);  // Not present
513 - (void)testRemoveField {
514   GPBUnknownFields* ufs = [[[GPBUnknownFields alloc] init] autorelease];
515   [ufs addFieldNumber:1 varint:1];
516   [ufs addFieldNumber:1 fixed32:1];
517   [ufs addFieldNumber:1 fixed64:1];
518   XCTAssertEqual(ufs.count, 3);
520   NSArray<GPBUnknownField*>* fields = [ufs fields:1];
521   XCTAssertEqual(fields.count, 3);
522   GPBUnknownField* field = fields[0];
523   XCTAssertEqual(field.number, 1);
524   XCTAssertEqual(field.type, GPBUnknownFieldTypeVarint);
525   XCTAssertEqual(field.varint, 1);
526   [ufs removeField:field];  // Remove first (varint)
527   XCTAssertEqual(ufs.count, 2);
529   fields = [ufs fields:1];
530   XCTAssertEqual(fields.count, 2);
531   field = fields[0];
532   XCTAssertEqual(field.number, 1);
533   XCTAssertEqual(field.type, GPBUnknownFieldTypeFixed32);
534   field = fields[1];
535   XCTAssertEqual(field.number, 1);
536   XCTAssertEqual(field.type, GPBUnknownFieldTypeFixed64);
537   [ufs removeField:field];  // Remove the second (fixed64)
538   XCTAssertEqual(ufs.count, 1);
540   fields = [ufs fields:1];
541   XCTAssertEqual(fields.count, 1);
542   field = fields[0];
543   XCTAssertEqual(field.number, 1);
544   XCTAssertEqual(field.type, GPBUnknownFieldTypeFixed32);
546   field = [[field retain] autorelease];  // Hold on to this last one.
547   [ufs removeField:field];               // Remove the last one (fixed32)
548   XCTAssertEqual(ufs.count, 0);
550   // Trying to remove something not in the set should fail.
551   XCTAssertThrowsSpecificNamed([ufs removeField:field], NSException, NSInvalidArgumentException);
554 - (void)testClearFieldNumber {
555   GPBUnknownFields* ufs = [[[GPBUnknownFields alloc] init] autorelease];
556   [ufs addFieldNumber:1 varint:1];
557   [ufs addFieldNumber:2 fixed32:2];
558   [ufs addFieldNumber:1 fixed64:1];
559   [ufs addFieldNumber:3 varint:3];
560   XCTAssertEqual(ufs.count, 4);
562   [ufs clearFieldNumber:999];  // Not present, noop.
563   XCTAssertEqual(ufs.count, 4);
565   [ufs clearFieldNumber:1];  // Should remove slot zero and slot two.
566   XCTAssertEqual(ufs.count, 2);
567   NSArray<GPBUnknownField*>* fields = [ufs fields:2];
568   XCTAssertEqual(fields.count, 1);
569   GPBUnknownField* field = fields[0];
570   XCTAssertEqual(field.number, 2);
571   XCTAssertEqual(field.type, GPBUnknownFieldTypeFixed32);
572   XCTAssertEqual(field.fixed32, 2);
573   fields = [ufs fields:3];
574   XCTAssertEqual(fields.count, 1);
575   field = fields[0];
576   XCTAssertEqual(field.number, 3);
577   XCTAssertEqual(field.type, GPBUnknownFieldTypeVarint);
578   XCTAssertEqual(field.varint, 3);
580   [ufs clearFieldNumber:2];  // Should remove slot one.
581   fields = [ufs fields:3];
582   XCTAssertEqual(fields.count, 1);
583   field = fields[0];
584   XCTAssertEqual(field.number, 3);
585   XCTAssertEqual(field.type, GPBUnknownFieldTypeVarint);
586   XCTAssertEqual(field.varint, 3);
589 - (void)testFastEnumeration {
590   GPBUnknownFields* ufs = [[[GPBUnknownFields alloc] init] autorelease];
591   [ufs addFieldNumber:1 varint:1];
592   [ufs addFieldNumber:2 varint:2];
593   [ufs addFieldNumber:1 fixed32:3];
594   [ufs addFieldNumber:2 fixed32:4];
595   [ufs addFieldNumber:1 fixed64:5];
596   [ufs addFieldNumber:3 fixed64:6];
597   [ufs addFieldNumber:1 lengthDelimited:DataFromCStr("foo")];
598   [ufs addFieldNumber:2 lengthDelimited:DataFromCStr("bar")];
599   GPBUnknownFields* group1 = [ufs addGroupWithFieldNumber:1];
600   GPBUnknownFields* group2 = [ufs addGroupWithFieldNumber:3];
602   // The order added nothing to do with field numbers.
603   NSInteger loop = 0;
604   for (GPBUnknownField* field in ufs) {
605     ++loop;
606     switch (loop) {
607       case 1:
608         XCTAssertEqual(field.number, 1);
609         XCTAssertEqual(field.type, GPBUnknownFieldTypeVarint);
610         XCTAssertEqual(field.varint, 1);
611         break;
612       case 2:
613         XCTAssertEqual(field.number, 2);
614         XCTAssertEqual(field.type, GPBUnknownFieldTypeVarint);
615         XCTAssertEqual(field.varint, 2);
616         break;
617       case 3:
618         XCTAssertEqual(field.number, 1);
619         XCTAssertEqual(field.type, GPBUnknownFieldTypeFixed32);
620         XCTAssertEqual(field.fixed32, 3);
621         break;
622       case 4:
623         XCTAssertEqual(field.number, 2);
624         XCTAssertEqual(field.type, GPBUnknownFieldTypeFixed32);
625         XCTAssertEqual(field.fixed32, 4);
626         break;
627       case 5:
628         XCTAssertEqual(field.number, 1);
629         XCTAssertEqual(field.type, GPBUnknownFieldTypeFixed64);
630         XCTAssertEqual(field.fixed64, 5);
631         break;
632       case 6:
633         XCTAssertEqual(field.number, 3);
634         XCTAssertEqual(field.type, GPBUnknownFieldTypeFixed64);
635         XCTAssertEqual(field.fixed64, 6);
636         break;
637       case 7:
638         XCTAssertEqual(field.number, 1);
639         XCTAssertEqual(field.type, GPBUnknownFieldTypeLengthDelimited);
640         XCTAssertEqualObjects(field.lengthDelimited, DataFromCStr("foo"));
641         break;
642       case 8:
643         XCTAssertEqual(field.number, 2);
644         XCTAssertEqual(field.type, GPBUnknownFieldTypeLengthDelimited);
645         XCTAssertEqualObjects(field.lengthDelimited, DataFromCStr("bar"));
646         break;
647       case 9:
648         XCTAssertEqual(field.number, 1);
649         XCTAssertEqual(field.type, GPBUnknownFieldTypeGroup);
650         XCTAssertTrue(field.group == group1);  // Exact object.
651         break;
652       case 10:
653         XCTAssertEqual(field.number, 3);
654         XCTAssertEqual(field.type, GPBUnknownFieldTypeGroup);
655         XCTAssertTrue(field.group == group2);  // Exact object.
656         break;
657       default:
658         XCTFail(@"Unexpected");
659         break;
660     }
661   }
662   XCTAssertEqual(loop, 10);
665 - (void)testAddCopyOfField {
666   GPBUnknownFields* ufs = [[[GPBUnknownFields alloc] init] autorelease];
667   [ufs addFieldNumber:1 varint:10];
668   [ufs addFieldNumber:2 fixed32:11];
669   [ufs addFieldNumber:3 fixed64:12];
670   [ufs addFieldNumber:4 lengthDelimited:DataFromCStr("foo")];
671   GPBUnknownFields* group = [ufs addGroupWithFieldNumber:5];
672   [group addFieldNumber:10 varint:100];
673   GPBUnknownFields* subGroup = [group addGroupWithFieldNumber:100];
674   [subGroup addFieldNumber:50 varint:50];
676   GPBUnknownFields* ufs2 = [[[GPBUnknownFields alloc] init] autorelease];
677   for (GPBUnknownField* field in ufs) {
678     GPBUnknownField* field2 = [ufs2 addCopyOfField:field];
679     XCTAssertEqualObjects(field, field2);
680     if (field.type == GPBUnknownFieldTypeGroup) {
681       // Group does a copy because the `.group` value is mutable.
682       XCTAssertTrue(field != field2);        // Pointer comparison.
683       XCTAssertTrue(group != field2.group);  // Pointer comparison.
684       XCTAssertEqualObjects(group, field2.group);
685       GPBUnknownFields* subGroupAdded = [field2.group firstGroup:100];
686       XCTAssertTrue(subGroupAdded != subGroup);  // Pointer comparison.
687       XCTAssertEqualObjects(subGroupAdded, subGroup);
688     } else {
689       // All other types are immutable, so they use the same object.
690       XCTAssertTrue(field == field2);  // Pointer comparision.
691     }
692   }
693   XCTAssertEqualObjects(ufs, ufs2);
696 - (void)testDescriptions {
697   // Exercise description for completeness.
698   GPBUnknownFields* ufs = [[[GPBUnknownFields alloc] init] autorelease];
699   [ufs addFieldNumber:1 varint:1];
700   [ufs addFieldNumber:2 fixed32:1];
701   [ufs addFieldNumber:1 fixed64:1];
702   [ufs addFieldNumber:4 lengthDelimited:DataFromCStr("foo")];
703   [[ufs addGroupWithFieldNumber:5] addFieldNumber:10 varint:10];
704   XCTAssertTrue(ufs.description.length > 10);
705   for (GPBUnknownField* field in ufs) {
706     XCTAssertTrue(field.description.length > 10);
707   }
710 - (void)testCopy {
711   GPBUnknownFields* ufs = [[[GPBUnknownFields alloc] init] autorelease];
712   [ufs addFieldNumber:1 varint:1];
713   [ufs addFieldNumber:2 fixed32:2];
714   [ufs addFieldNumber:3 fixed64:3];
715   [ufs addFieldNumber:4 lengthDelimited:DataFromCStr("foo")];
716   GPBUnknownFields* group = [ufs addGroupWithFieldNumber:5];
717   [group addFieldNumber:10 varint:10];
718   GPBUnknownFields* subGroup = [group addGroupWithFieldNumber:100];
719   [subGroup addFieldNumber:20 varint:20];
721   GPBUnknownFields* ufs2 = [[ufs copy] autorelease];
722   XCTAssertTrue(ufs != ufs2);        // Different objects
723   XCTAssertEqualObjects(ufs, ufs2);  // Equal contents
724   // All field objects but the group should be the same since they are immutable.
725   XCTAssertTrue([[ufs fields:1] firstObject] == [[ufs2 fields:1] firstObject]);  // Same object
726   XCTAssertTrue([[ufs fields:2] firstObject] == [[ufs2 fields:2] firstObject]);  // Same object
727   XCTAssertTrue([[ufs fields:3] firstObject] == [[ufs2 fields:3] firstObject]);  // Same object
728   XCTAssertTrue([[ufs fields:4] firstObject] == [[ufs2 fields:4] firstObject]);  // Same object
729   XCTAssertTrue([[ufs fields:4] firstObject].lengthDelimited ==
730                 [[ufs2 fields:4] firstObject].lengthDelimited);  // Same object
731   // Since the group holds another `GPBUnknownFields` object (which is mutable), it will be a
732   // different object.
733   XCTAssertTrue([[ufs fields:5] firstObject] != [[ufs2 fields:5] firstObject]);
734   XCTAssertTrue(group != [[ufs2 fields:5] firstObject].group);
735   XCTAssertEqualObjects(group, [[ufs2 fields:5] firstObject].group);
736   // And confirm that copy went deep so the nested group also is a different object.
737   GPBUnknownFields* groupCopied = [[ufs2 fields:5] firstObject].group;
738   XCTAssertTrue([[group fields:100] firstObject] != [[groupCopied fields:100] firstObject]);
739   XCTAssertTrue(subGroup != [[groupCopied fields:100] firstObject].group);
740   XCTAssertEqualObjects(subGroup, [[groupCopied fields:100] firstObject].group);
743 - (void)testInvalidFieldNumbers {
744   GPBUnknownFields* ufs = [[[GPBUnknownFields alloc] init] autorelease];
746   XCTAssertThrowsSpecificNamed([ufs addFieldNumber:0 varint:1], NSException,
747                                NSInvalidArgumentException);
748   XCTAssertThrowsSpecificNamed([ufs addFieldNumber:0 fixed32:1], NSException,
749                                NSInvalidArgumentException);
750   XCTAssertThrowsSpecificNamed([ufs addFieldNumber:0 fixed64:1], NSException,
751                                NSInvalidArgumentException);
752   XCTAssertThrowsSpecificNamed([ufs addFieldNumber:0 lengthDelimited:[NSData data]], NSException,
753                                NSInvalidArgumentException);
754   XCTAssertThrowsSpecificNamed([ufs addGroupWithFieldNumber:0], NSException,
755                                NSInvalidArgumentException);
757   XCTAssertThrowsSpecificNamed([ufs addFieldNumber:-1 varint:1], NSException,
758                                NSInvalidArgumentException);
759   XCTAssertThrowsSpecificNamed([ufs addFieldNumber:-1 fixed32:1], NSException,
760                                NSInvalidArgumentException);
761   XCTAssertThrowsSpecificNamed([ufs addFieldNumber:-1 fixed64:1], NSException,
762                                NSInvalidArgumentException);
763   XCTAssertThrowsSpecificNamed([ufs addFieldNumber:-1 lengthDelimited:[NSData data]], NSException,
764                                NSInvalidArgumentException);
765   XCTAssertThrowsSpecificNamed([ufs addGroupWithFieldNumber:-1], NSException,
766                                NSInvalidArgumentException);
768   uint64_t varint;
769   uint32_t fixed32;
770   uint64_t fixed64;
771   XCTAssertThrowsSpecificNamed([ufs getFirst:0 varint:&varint], NSException,
772                                NSInvalidArgumentException);
773   XCTAssertThrowsSpecificNamed([ufs getFirst:0 fixed32:&fixed32], NSException,
774                                NSInvalidArgumentException);
775   XCTAssertThrowsSpecificNamed([ufs getFirst:0 fixed64:&fixed64], NSException,
776                                NSInvalidArgumentException);
777   XCTAssertThrowsSpecificNamed([ufs firstLengthDelimited:0], NSException,
778                                NSInvalidArgumentException);
779   XCTAssertThrowsSpecificNamed([ufs firstGroup:0], NSException, NSInvalidArgumentException);
781   XCTAssertThrowsSpecificNamed([ufs getFirst:-1 varint:&varint], NSException,
782                                NSInvalidArgumentException);
783   XCTAssertThrowsSpecificNamed([ufs getFirst:-1 fixed32:&fixed32], NSException,
784                                NSInvalidArgumentException);
785   XCTAssertThrowsSpecificNamed([ufs getFirst:-1 fixed64:&fixed64], NSException,
786                                NSInvalidArgumentException);
787   XCTAssertThrowsSpecificNamed([ufs firstLengthDelimited:-1], NSException,
788                                NSInvalidArgumentException);
789   XCTAssertThrowsSpecificNamed([ufs firstGroup:-1], NSException, NSInvalidArgumentException);
790   XCTAssertThrowsSpecificNamed([ufs fields:0], NSException, NSInvalidArgumentException);
791   XCTAssertThrowsSpecificNamed([ufs fields:-1], NSException, NSInvalidArgumentException);
794 - (void)testSerialize {
795   // Don't need to test CodedOutputStream, just make sure things basically end up there.
796   {
797     GPBUnknownFields* ufs = [[[GPBUnknownFields alloc] init] autorelease];
798     XCTAssertEqualObjects([ufs serializeAsData], [NSData data]);
799   }
800   {
801     GPBUnknownFields* ufs = [[[GPBUnknownFields alloc] init] autorelease];
802     [ufs addFieldNumber:1 varint:1];
803     XCTAssertEqualObjects([ufs serializeAsData], DataFromBytes(0x08, 0x01));
804   }
805   {
806     GPBUnknownFields* ufs = [[[GPBUnknownFields alloc] init] autorelease];
807     [ufs addFieldNumber:1 fixed32:1];
808     XCTAssertEqualObjects([ufs serializeAsData], DataFromBytes(0x0d, 0x01, 0x00, 0x00, 0x00));
809   }
810   {
811     GPBUnknownFields* ufs = [[[GPBUnknownFields alloc] init] autorelease];
812     [ufs addFieldNumber:1 fixed64:1];
813     XCTAssertEqualObjects([ufs serializeAsData],
814                           DataFromBytes(0x09, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00));
815   }
816   {
817     GPBUnknownFields* ufs = [[[GPBUnknownFields alloc] init] autorelease];
818     [ufs addFieldNumber:1 lengthDelimited:DataFromCStr("foo")];
819     XCTAssertEqualObjects([ufs serializeAsData], DataFromBytes(0x0a, 0x03, 0x66, 0x6f, 0x6f));
820   }
821   {
822     GPBUnknownFields* ufs = [[[GPBUnknownFields alloc] init] autorelease];
823     [ufs addGroupWithFieldNumber:1];  // Empty group
824     XCTAssertEqualObjects([ufs serializeAsData], DataFromBytes(0x0b, 0x0c));
825   }
826   {
827     GPBUnknownFields* ufs = [[[GPBUnknownFields alloc] init] autorelease];
828     GPBUnknownFields* group = [ufs addGroupWithFieldNumber:1];  // With some fields
829     [group addFieldNumber:10 varint:10];
830     [group addFieldNumber:11 fixed32:32];
831     [group addFieldNumber:12 fixed32:32];
832     XCTAssertEqualObjects([ufs serializeAsData],
833                           DataFromBytes(0x0b, 0x50, 0x0a, 0x5d, 0x20, 0x00, 0x00, 0x00, 0x65, 0x20,
834                                         0x00, 0x00, 0x00, 0x0c));
835   }
838 - (void)testMessageMergeUnknowns {
839   GPBUnknownFields* ufs = [[[GPBUnknownFields alloc] init] autorelease];
840   [ufs addFieldNumber:TestAllTypes_FieldNumber_OptionalInt64 varint:100];
841   [ufs addFieldNumber:TestAllTypes_FieldNumber_OptionalFixed32 fixed32:200];
842   [ufs addFieldNumber:TestAllTypes_FieldNumber_OptionalFixed64 fixed64:300];
843   [ufs addFieldNumber:TestAllTypes_FieldNumber_OptionalBytes lengthDelimited:DataFromCStr("foo")];
844   GPBUnknownFields* group = [ufs addGroupWithFieldNumber:TestAllTypes_FieldNumber_OptionalGroup];
845   [group addFieldNumber:TestAllTypes_OptionalGroup_FieldNumber_A varint:55];
846   [ufs addFieldNumber:123456 varint:4321];
847   [group addFieldNumber:123456 varint:5432];
849   TestAllTypes* msg = [TestAllTypes message];
850   XCTAssertTrue([msg mergeUnknownFields:ufs extensionRegistry:nil error:NULL]);
851   XCTAssertEqual(msg.optionalInt64, 100);
852   XCTAssertEqual(msg.optionalFixed32, 200);
853   XCTAssertEqual(msg.optionalFixed64, 300);
854   XCTAssertEqualObjects(msg.optionalBytes, DataFromCStr("foo"));
855   XCTAssertEqual(msg.optionalGroup.a, 55);
856   GPBUnknownFields* ufs2 = [[[GPBUnknownFields alloc] initFromMessage:msg] autorelease];
857   XCTAssertEqual(ufs2.count, 1);  // The unknown at the root
858   uint64_t varint = 0;
859   XCTAssertTrue([ufs2 getFirst:123456 varint:&varint]);
860   XCTAssertEqual(varint, 4321);
861   GPBUnknownFields* ufs2group =
862       [[[GPBUnknownFields alloc] initFromMessage:msg.optionalGroup] autorelease];
863   XCTAssertEqual(ufs2group.count, 1);  // The unknown at in group
864   XCTAssertTrue([ufs2group getFirst:123456 varint:&varint]);
865   XCTAssertEqual(varint, 5432);
867   TestEmptyMessage* emptyMessage = [TestEmptyMessage message];
868   XCTAssertTrue([emptyMessage mergeUnknownFields:ufs extensionRegistry:nil error:NULL]);
869   GPBUnknownFields* ufs3 = [[[GPBUnknownFields alloc] initFromMessage:emptyMessage] autorelease];
870   XCTAssertEqualObjects(ufs3, ufs);  // Round trip through an empty message got us same fields back.
871   XCTAssertTrue(ufs3 != ufs);        // But they are different objects.
874 - (void)testRoundTripLotsOfFields {
875   // Usage a message with everything, into an empty message to get a lot of unknown fields,
876   // and confirm it comes back to match.
877   TestAllTypes* allFields = [self allSetRepeatedCount:kGPBDefaultRepeatCount];
878   NSData* allFieldsData = [allFields data];
879   TestEmptyMessage* emptyMessage = [TestEmptyMessage parseFromData:allFieldsData error:NULL];
880   GPBUnknownFields* ufs = [[[GPBUnknownFields alloc] initFromMessage:emptyMessage] autorelease];
881   TestAllTypes* allFields2 = [TestAllTypes message];
882   XCTAssertTrue([allFields2 mergeUnknownFields:ufs extensionRegistry:nil error:NULL]);
883   XCTAssertEqualObjects(allFields2, allFields);
885   // Confirm that the they still all end up in unknowns when parsed into a message with extensions
886   // support for the field numbers (but no registry).
887   {
888     TestEmptyMessageWithExtensions* msgWithExts =
889         [TestEmptyMessageWithExtensions parseFromData:allFieldsData error:NULL];
890     GPBUnknownFields* ufs2 = [[[GPBUnknownFields alloc] initFromMessage:msgWithExts] autorelease];
891     XCTAssertEqualObjects(ufs2, ufs);
892   }
894   // Sanity check that with the registry, they go into the extension fields.
895   {
896     TestAllExtensions* msgWithExts =
897         [TestAllExtensions parseFromData:allFieldsData
898                        extensionRegistry:[UnittestRoot extensionRegistry]
899                                    error:NULL];
900     GPBUnknownFields* ufs2 = [[[GPBUnknownFields alloc] initFromMessage:msgWithExts] autorelease];
901     XCTAssertEqual(ufs2.count, 0);
902   }
905 - (void)testMismatchedFieldTypes {
906   // Start with a valid set of field data, and map it into unknown fields.
907   TestAllTypes* allFields = [self allSetRepeatedCount:kGPBDefaultRepeatCount];
908   NSData* allFieldsData = [allFields data];
909   TestEmptyMessage* emptyMessage = [TestEmptyMessage parseFromData:allFieldsData error:NULL];
910   GPBUnknownFields* ufsRightTypes =
911       [[[GPBUnknownFields alloc] initFromMessage:emptyMessage] autorelease];
913   // Now build a new set of unknown fields where all the data types are wrong for the original
914   // fields.
915   GPBUnknownFields* ufsWrongTypes = [[[GPBUnknownFields alloc] init] autorelease];
916   for (GPBUnknownField* field in ufsRightTypes) {
917     if (field.type != GPBUnknownFieldTypeVarint) {
918       // Original field is not a varint, so use a varint.
919       [ufsWrongTypes addFieldNumber:field.number varint:1];
920     } else {
921       // Original field *is* a varint, so use something else.
922       [ufsWrongTypes addFieldNumber:field.number fixed32:1];
923     }
924   }
926   // Parse into a message with the field numbers, the wrong types should force everything into
927   // unknown fields again.
928   {
929     TestAllTypes* msg = [TestAllTypes message];
930     XCTAssertTrue([msg mergeUnknownFields:ufsWrongTypes extensionRegistry:nil error:NULL]);
931     GPBUnknownFields* ufs2 = [[[GPBUnknownFields alloc] initFromMessage:msg] autorelease];
932     XCTAssertFalse(ufs2.empty);
933     XCTAssertEqualObjects(ufs2, ufsWrongTypes);  // All back as unknown fields.
934   }
936   // Parse into a message with extension registiry, the wrong types should still force everything
937   // into unknown fields.
938   {
939     TestAllExtensions* msg = [TestAllExtensions message];
940     XCTAssertTrue([msg mergeUnknownFields:ufsWrongTypes
941                         extensionRegistry:[UnittestRoot extensionRegistry]
942                                     error:NULL]);
943     GPBUnknownFields* ufs2 = [[[GPBUnknownFields alloc] initFromMessage:msg] autorelease];
944     XCTAssertFalse(ufs2.empty);
945     XCTAssertEqualObjects(ufs2, ufsWrongTypes);  // All back as unknown fields.
946   }
949 - (void)testMergeFailures {
950   // Valid data, pushes to the fields just fine.
951   {
952     GPBUnknownFields* ufs = [[[GPBUnknownFields alloc] init] autorelease];
953     [ufs addFieldNumber:TestAllTypes_FieldNumber_OptionalString
954         lengthDelimited:DataFromCStr("abc")];
955     [ufs addFieldNumber:TestAllTypes_FieldNumber_RepeatedInt32Array
956         lengthDelimited:DataFromBytes(0x01, 0x02)];
957     [ufs addFieldNumber:TestAllTypes_FieldNumber_RepeatedFixed32Array
958         lengthDelimited:DataFromBytes(0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00)];
959     [ufs addFieldNumber:TestAllTypes_FieldNumber_RepeatedFixed64Array
960         lengthDelimited:DataFromBytes(0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00,
961                                       0x00, 0x00, 0x00, 0x00, 0x00, 0x00)];
962     TestAllTypes* msg = [TestAllTypes message];
963     NSError* error = nil;
964     XCTAssertTrue([msg mergeUnknownFields:ufs extensionRegistry:nil error:&error]);
965     XCTAssertNil(error);
966     XCTAssertEqualObjects(msg.optionalString, @"abc");
967     XCTAssertEqual(msg.repeatedInt32Array.count, 2);
968     XCTAssertEqual([msg.repeatedInt32Array valueAtIndex:0], 1);
969     XCTAssertEqual([msg.repeatedInt32Array valueAtIndex:1], 2);
970     XCTAssertEqual(msg.repeatedFixed32Array.count, 2);
971     XCTAssertEqual([msg.repeatedFixed32Array valueAtIndex:0], 3);
972     XCTAssertEqual([msg.repeatedFixed32Array valueAtIndex:1], 4);
973     XCTAssertEqual(msg.repeatedFixed64Array.count, 2);
974     XCTAssertEqual([msg.repeatedFixed64Array valueAtIndex:0], 5);
975     XCTAssertEqual([msg.repeatedFixed64Array valueAtIndex:1], 6);
976   }
978   // Invalid UTF-8 causes a failure when pushed to the message.
979   {
980     GPBUnknownFields* ufs = [[[GPBUnknownFields alloc] init] autorelease];
981     [ufs addFieldNumber:TestAllTypes_FieldNumber_OptionalString
982         lengthDelimited:DataFromBytes(0xC2, 0xF2, 0x0, 0x0, 0x0)];
983     TestAllTypes* msg = [TestAllTypes message];
984     NSError* error = nil;
985     XCTAssertFalse([msg mergeUnknownFields:ufs extensionRegistry:nil error:&error]);
986     XCTAssertNotNil(error);
987   }
989   // Invalid packed varint causes a failure when pushed to the message.
990   {
991     GPBUnknownFields* ufs = [[[GPBUnknownFields alloc] init] autorelease];
992     [ufs addFieldNumber:TestAllTypes_FieldNumber_RepeatedInt32Array
993         lengthDelimited:DataFromBytes(0xff)];  // Invalid varint
994     TestAllTypes* msg = [TestAllTypes message];
995     NSError* error = nil;
996     XCTAssertFalse([msg mergeUnknownFields:ufs extensionRegistry:nil error:&error]);
997     XCTAssertNotNil(error);
998   }
1000   // Invalid packed fixed32 causes a failure when pushed to the message.
1001   {
1002     GPBUnknownFields* ufs = [[[GPBUnknownFields alloc] init] autorelease];
1003     [ufs addFieldNumber:TestAllTypes_FieldNumber_RepeatedFixed32Array
1004         lengthDelimited:DataFromBytes(0x01, 0x00, 0x00)];  // Truncated fixed32
1005     TestAllTypes* msg = [TestAllTypes message];
1006     NSError* error = nil;
1007     XCTAssertFalse([msg mergeUnknownFields:ufs extensionRegistry:nil error:&error]);
1008     XCTAssertNotNil(error);
1009   }
1011   // Invalid packed fixed64 causes a failure when pushed to the message.
1012   {
1013     GPBUnknownFields* ufs = [[[GPBUnknownFields alloc] init] autorelease];
1014     [ufs addFieldNumber:TestAllTypes_FieldNumber_RepeatedFixed64Array
1015         lengthDelimited:DataFromBytes(0x01, 0x00, 0x00, 0x00, 0x00)];  // Truncated fixed64
1016     TestAllTypes* msg = [TestAllTypes message];
1017     NSError* error = nil;
1018     XCTAssertFalse([msg mergeUnknownFields:ufs extensionRegistry:nil error:&error]);
1019     XCTAssertNotNil(error);
1020   }
1023 - (void)testLargeVarint {
1024   GPBUnknownFields* ufs = [[[GPBUnknownFields alloc] init] autorelease];
1025   [ufs addFieldNumber:1 varint:0x7FFFFFFFFFFFFFFFL];
1027   TestEmptyMessage* emptyMessage = [TestEmptyMessage message];
1028   XCTAssertTrue([emptyMessage mergeUnknownFields:ufs extensionRegistry:nil error:NULL]);
1030   GPBUnknownFields* ufsParsed =
1031       [[[GPBUnknownFields alloc] initFromMessage:emptyMessage] autorelease];
1032   XCTAssertEqual(ufsParsed.count, 1);
1033   uint64_t varint = 0;
1034   XCTAssertTrue([ufsParsed getFirst:1 varint:&varint]);
1035   XCTAssertEqual(varint, 0x7FFFFFFFFFFFFFFFL);
1038 static NSData* DataForGroupsOfDepth(NSUInteger depth) {
1039   NSMutableData* data = [NSMutableData dataWithCapacity:0];
1041   uint32_t byte = 35;  // 35 = 0b100011 -> field 4/start group
1042   for (NSUInteger i = 0; i < depth; ++i) {
1043     [data appendBytes:&byte length:1];
1044   }
1046   byte = 8;  // 8 = 0b1000, -> field 1/varint
1047   [data appendBytes:&byte length:1];
1048   byte = 1;  // 1 -> varint value of 1
1049   [data appendBytes:&byte length:1];
1051   byte = 36;  // 36 = 0b100100 -> field 4/end group
1052   for (NSUInteger i = 0; i < depth; ++i) {
1053     [data appendBytes:&byte length:1];
1054   }
1055   return data;
1058 - (void)testParsingNestingGroupData {
1059   // 35 = 0b100011 -> field 4/start group
1060   // 36 = 0b100100 -> field 4/end group
1061   // 43 = 0b101011 -> field 5/end group
1062   // 44 = 0b101100 -> field 5/end group
1063   // 8 = 0b1000, 1 -> field 1/varint, value of 1
1064   // 21 = 0b10101, 0x78, 0x56, 0x34, 0x12 -> field 2/fixed32, value of 0x12345678
1065   // 25 = 0b11001, 0xf0, 0xde, 0xbc, 0x9a, 0x78, 0x56, 0x34, 0x12 -> field 3/fixed64,
1066   //                                                                 value of 0x123456789abcdef0LL
1067   // 50 = 0b110010, 0x0 -> field 6/length delimited, length 0
1068   // 50 = 0b110010, 0x1, 42 -> field 6/length delimited, length 1, byte 42
1069   // 0 -> field 0 which is invalid/varint
1070   // 15 = 0b1111 -> field 1, wire type 7 which is invalid
1072   TestEmptyMessage* m = [TestEmptyMessage parseFromData:DataFromBytes(35, 36)
1073                                                   error:NULL];  // empty group
1074   GPBUnknownFields* ufs = [[[GPBUnknownFields alloc] initFromMessage:m] autorelease];
1075   XCTAssertEqual(ufs.count, (NSUInteger)1);
1076   GPBUnknownFields* group = [ufs firstGroup:4];
1077   XCTAssertTrue(group.empty);
1079   m = [TestEmptyMessage parseFromData:DataFromBytes(35, 8, 1, 36) error:NULL];  // varint
1080   ufs = [[[GPBUnknownFields alloc] initFromMessage:m] autorelease];
1081   XCTAssertEqual(ufs.count, (NSUInteger)1);
1082   group = [ufs firstGroup:4];
1083   XCTAssertEqual(group.count, (NSUInteger)1);
1084   uint64_t varint = 0;
1085   XCTAssertTrue([group getFirst:1 varint:&varint]);
1086   XCTAssertEqual(varint, 1);
1088   m = [TestEmptyMessage parseFromData:DataFromBytes(35, 21, 0x78, 0x56, 0x34, 0x12, 36)
1089                                 error:NULL];  // fixed32
1090   ufs = [[[GPBUnknownFields alloc] initFromMessage:m] autorelease];
1091   XCTAssertEqual(ufs.count, (NSUInteger)1);
1092   group = [ufs firstGroup:4];
1093   XCTAssertEqual(group.count, (NSUInteger)1);
1094   uint32_t fixed32 = 0;
1095   XCTAssertTrue([group getFirst:2 fixed32:&fixed32]);
1096   XCTAssertEqual(fixed32, 0x12345678);
1098   m = [TestEmptyMessage
1099       parseFromData:DataFromBytes(35, 25, 0xf0, 0xde, 0xbc, 0x9a, 0x78, 0x56, 0x34, 0x12,
1100                                   36)
1101               error:NULL];  // fixed64
1102   ufs = [[[GPBUnknownFields alloc] initFromMessage:m] autorelease];
1103   XCTAssertEqual(ufs.count, (NSUInteger)1);
1104   group = [ufs firstGroup:4];
1105   XCTAssertEqual(group.count, (NSUInteger)1);
1106   uint64_t fixed64 = 0;
1107   XCTAssertTrue([group getFirst:3 fixed64:&fixed64]);
1108   XCTAssertEqual(fixed64, 0x123456789abcdef0LL);
1110   m = [TestEmptyMessage parseFromData:DataFromBytes(35, 50, 0, 36)
1111                                 error:NULL];  // length delimited, length 0
1112   ufs = [[[GPBUnknownFields alloc] initFromMessage:m] autorelease];
1113   XCTAssertEqual(ufs.count, (NSUInteger)1);
1114   group = [ufs firstGroup:4];
1115   XCTAssertEqual(group.count, (NSUInteger)1);
1116   NSData* lengthDelimited = [group firstLengthDelimited:6];
1117   XCTAssertEqualObjects(lengthDelimited, [NSData data]);
1119   m = [TestEmptyMessage parseFromData:DataFromBytes(35, 50, 1, 42, 36)
1120                                 error:NULL];  // length delimited, length 1, byte 42
1121   ufs = [[[GPBUnknownFields alloc] initFromMessage:m] autorelease];
1122   XCTAssertEqual(ufs.count, (NSUInteger)1);
1123   group = [ufs firstGroup:4];
1124   XCTAssertEqual(group.count, (NSUInteger)1);
1125   lengthDelimited = [group firstLengthDelimited:6];
1126   XCTAssertEqualObjects(lengthDelimited, DataFromBytes(42));
1128   m = [TestEmptyMessage parseFromData:DataFromBytes(35, 43, 44, 36) error:NULL];  // Sub group
1129   ufs = [[[GPBUnknownFields alloc] initFromMessage:m] autorelease];
1130   XCTAssertEqual(ufs.count, (NSUInteger)1);
1131   group = [ufs firstGroup:4];
1132   XCTAssertEqual(group.count, (NSUInteger)1);
1133   group = [group firstGroup:5];
1134   XCTAssertTrue(group.empty);
1136   m = [TestEmptyMessage parseFromData:DataFromBytes(35, 8, 1, 43, 8, 2, 44, 36)
1137                                 error:NULL];  // varint and sub group with varint
1138   ufs = [[[GPBUnknownFields alloc] initFromMessage:m] autorelease];
1139   XCTAssertEqual(ufs.count, (NSUInteger)1);
1140   group = [ufs firstGroup:4];
1141   XCTAssertEqual(group.count, (NSUInteger)2);
1142   varint = 0;
1143   XCTAssertTrue([group getFirst:1 varint:&varint]);
1144   XCTAssertEqual(varint, 1);
1145   group = [group firstGroup:5];
1146   XCTAssertEqual(group.count, (NSUInteger)1);
1147   XCTAssertTrue([group getFirst:1 varint:&varint]);
1148   XCTAssertEqual(varint, 2);
1150   XCTAssertNil([TestEmptyMessage parseFromData:DataFromBytes(35, 0, 36)
1151                                          error:NULL]);  // Invalid field number
1152   XCTAssertNil([TestEmptyMessage parseFromData:DataFromBytes(35, 15, 36)
1153                                          error:NULL]);  // Invalid wire type
1154   XCTAssertNil([TestEmptyMessage parseFromData:DataFromBytes(35, 21, 0x78, 0x56, 0x34)
1155                                          error:NULL]);  // truncated fixed32
1156   XCTAssertNil([TestEmptyMessage
1157       parseFromData:DataFromBytes(35, 25, 0xf0, 0xde, 0xbc, 0x9a, 0x78, 0x56,
1158                                   0x34)
1159               error:NULL]);  // truncated fixed64
1161   // Missing end group
1162   XCTAssertNil([TestEmptyMessage parseFromData:DataFromBytes(35) error:NULL]);
1163   XCTAssertNil([TestEmptyMessage parseFromData:DataFromBytes(35, 8, 1) error:NULL]);
1164   XCTAssertNil([TestEmptyMessage parseFromData:DataFromBytes(35, 43) error:NULL]);
1165   XCTAssertNil([TestEmptyMessage parseFromData:DataFromBytes(35, 43, 8, 1) error:NULL]);
1167   // Wrong end group
1168   XCTAssertNil([TestEmptyMessage parseFromData:DataFromBytes(35, 44) error:NULL]);
1169   XCTAssertNil([TestEmptyMessage parseFromData:DataFromBytes(35, 8, 1, 44) error:NULL]);
1170   XCTAssertNil([TestEmptyMessage parseFromData:DataFromBytes(35, 43, 36) error:NULL]);
1171   XCTAssertNil([TestEmptyMessage parseFromData:DataFromBytes(35, 43, 8, 1, 36) error:NULL]);
1172   XCTAssertNil([TestEmptyMessage parseFromData:DataFromBytes(35, 43, 44, 44) error:NULL]);
1173   XCTAssertNil([TestEmptyMessage parseFromData:DataFromBytes(35, 43, 8, 1, 44, 44) error:NULL]);
1175   // This is the same limit as within GPBCodedInputStream.
1176   const NSUInteger kDefaultRecursionLimit = 100;
1177   // That depth parses.
1178   NSData* testData = DataForGroupsOfDepth(kDefaultRecursionLimit);
1179   m = [TestEmptyMessage parseFromData:testData error:NULL];
1180   ufs = [[[GPBUnknownFields alloc] initFromMessage:m] autorelease];
1181   XCTAssertEqual(ufs.count, (NSUInteger)1);
1182   group = [ufs firstGroup:4];
1183   for (NSUInteger i = 1; i < kDefaultRecursionLimit; ++i) {
1184     XCTAssertEqual(group.count, (NSUInteger)1);
1185     group = [group firstGroup:4];
1186   }
1187   // group is now the inner most group.
1188   XCTAssertEqual(group.count, (NSUInteger)1);
1189   varint = 0;
1190   XCTAssertTrue([group getFirst:1 varint:&varint]);
1191   XCTAssertEqual(varint, 1);
1192   // One more level deep fails.
1193   testData = DataForGroupsOfDepth(kDefaultRecursionLimit + 1);
1194   XCTAssertNil([TestEmptyMessage parseFromData:testData error:NULL]);
1197 @end