• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1<?php
2
3require_once('test_base.php');
4require_once('test_util.php');
5
6use Google\Protobuf\Internal\RepeatedField;
7use Google\Protobuf\Internal\MapField;
8use Google\Protobuf\Internal\GPBType;
9use Bar\TestLegacyMessage;
10use Bar\TestLegacyMessage_NestedEnum;
11use Bar\TestLegacyMessage_NestedMessage;
12use Foo\Test32Fields;
13use Foo\TestEnum;
14use Foo\TestIncludeNamespaceMessage;
15use Foo\TestIncludePrefixMessage;
16use Foo\TestMessage;
17use Foo\TestMessage\Sub;
18use Foo\TestMessage_Sub;
19use Foo\TestMessage\NestedEnum;
20use Foo\TestReverseFieldOrder;
21use Foo\testLowerCaseMessage;
22use Foo\testLowerCaseEnum;
23use PBEmpty\PBEcho\TestEmptyPackage;
24use Php\Test\TestNamespace;
25
26# This is not allowed, but we at least shouldn't crash.
27class C extends \Google\Protobuf\Internal\Message {
28    public function __construct($data = null) {
29        parent::__construct($data);
30    }
31}
32
33class GeneratedClassTest extends TestBase
34{
35
36    #########################################################
37    # Test field accessors.
38    #########################################################
39
40    public function testSetterGetter()
41    {
42        $m = new TestMessage();
43        $m->setOptionalInt32(1);
44        $this->assertSame(1, $m->getOptionalInt32());
45    }
46
47    #########################################################
48    # Test int32 field.
49    #########################################################
50
51    public function testInt32Field()
52    {
53        $m = new TestMessage();
54
55        // Set integer.
56        $m->setOptionalInt32(MAX_INT32);
57        $this->assertSame(MAX_INT32, $m->getOptionalInt32());
58        $m->setOptionalInt32(MIN_INT32);
59        $this->assertSame(MIN_INT32, $m->getOptionalInt32());
60
61        // Set float.
62        $m->setOptionalInt32(1.1);
63        $this->assertSame(1, $m->getOptionalInt32());
64        $m->setOptionalInt32(MAX_INT32_FLOAT);
65        $this->assertSame(MAX_INT32, $m->getOptionalInt32());
66        $m->setOptionalInt32(MIN_INT32_FLOAT);
67        $this->assertSame(MIN_INT32, $m->getOptionalInt32());
68
69        // Set string.
70        $m->setOptionalInt32('2');
71        $this->assertSame(2, $m->getOptionalInt32());
72        $m->setOptionalInt32('3.1');
73        $this->assertSame(3, $m->getOptionalInt32());
74        $m->setOptionalInt32(MAX_INT32_STRING);
75        $this->assertSame(MAX_INT32, $m->getOptionalInt32());
76        $m->setOptionalInt32(MIN_INT32_STRING);
77        $this->assertSame(MIN_INT32, $m->getOptionalInt32());
78    }
79
80    #########################################################
81    # Test deprecated int32 field.
82    #########################################################
83
84    public function testDeprecatedInt32Field()
85    {
86        $m = new TestMessage();
87
88        // temporarily change error handler to capture the deprecated errors
89        $deprecationCount = 0;
90        set_error_handler(function ($errno, $errstr) use (&$deprecationCount) {
91            if ($errstr === 'deprecated_optional_int32 is deprecated.') {
92                $deprecationCount++;
93            }
94        }, E_USER_DEPRECATED);
95
96        // default test set
97        $m->setDeprecatedOptionalInt32(MAX_INT32);
98        $this->assertSame(MAX_INT32, $m->getDeprecatedOptionalInt32());
99        $m->setDeprecatedOptionalInt32(MIN_INT32);
100        $this->assertSame(MIN_INT32, $m->getDeprecatedOptionalInt32());
101
102        restore_error_handler();
103
104        $this->assertSame(4, $deprecationCount);
105    }
106
107    #########################################################
108    # Test optional int32 field.
109    #########################################################
110
111    public function testOptionalInt32Field()
112    {
113        $m = new TestMessage();
114
115        $this->assertFalse($m->hasTrueOptionalInt32());
116        $this->assertSame(0, $m->getTrueOptionalInt32());
117
118        // Set integer.
119        $m->setTrueOptionalInt32(MAX_INT32);
120        $this->assertTrue($m->hasTrueOptionalInt32());
121        $this->assertSame(MAX_INT32, $m->getTrueOptionalInt32());
122
123        // Clear integer.
124        $m->clearTrueOptionalInt32();
125        $this->assertFalse($m->hasTrueOptionalInt32());
126        $this->assertSame(0, $m->getTrueOptionalInt32());
127    }
128
129    #########################################################
130    # Test uint32 field.
131    #########################################################
132
133    public function testUint32Field()
134    {
135        $m = new TestMessage();
136
137        // Set integer.
138        $m->setOptionalUint32(MAX_UINT32);
139        $this->assertSame(-1, $m->getOptionalUint32());
140        $m->setOptionalUint32(-1);
141        $this->assertSame(-1, $m->getOptionalUint32());
142        $m->setOptionalUint32(MIN_UINT32);
143        $this->assertSame(MIN_INT32, $m->getOptionalUint32());
144
145        // Set float.
146        $m->setOptionalUint32(1.1);
147        $this->assertSame(1, $m->getOptionalUint32());
148        $m->setOptionalUint32(MAX_UINT32_FLOAT);
149        $this->assertSame(-1, $m->getOptionalUint32());
150        $m->setOptionalUint32(-1.0);
151        $this->assertSame(-1, $m->getOptionalUint32());
152        $m->setOptionalUint32(MIN_UINT32_FLOAT);
153        $this->assertSame(MIN_INT32, $m->getOptionalUint32());
154
155        // Set string.
156        $m->setOptionalUint32('2');
157        $this->assertSame(2, $m->getOptionalUint32());
158        $m->setOptionalUint32('3.1');
159        $this->assertSame(3, $m->getOptionalUint32());
160        $m->setOptionalUint32(MAX_UINT32_STRING);
161        $this->assertSame(-1, $m->getOptionalUint32());
162        $m->setOptionalUint32('-1.0');
163        $this->assertSame(-1, $m->getOptionalUint32());
164        $m->setOptionalUint32(MIN_UINT32_STRING);
165        $this->assertSame(MIN_INT32, $m->getOptionalUint32());
166    }
167
168    #########################################################
169    # Test int64 field.
170    #########################################################
171
172    public function testInt64Field()
173    {
174        $m = new TestMessage();
175
176        // Set integer.
177        $m->setOptionalInt64(MAX_INT64);
178        $this->assertSame(MAX_INT64, $m->getOptionalInt64());
179        $m->setOptionalInt64(MIN_INT64);
180        $this->assertEquals(MIN_INT64, $m->getOptionalInt64());
181
182        // Set float.
183        $m->setOptionalInt64(1.1);
184        if (PHP_INT_SIZE == 4) {
185            $this->assertSame('1', $m->getOptionalInt64());
186        } else {
187            $this->assertSame(1, $m->getOptionalInt64());
188        }
189
190        // Set string.
191        $m->setOptionalInt64('2');
192        if (PHP_INT_SIZE == 4) {
193            $this->assertSame('2', $m->getOptionalInt64());
194        } else {
195            $this->assertSame(2, $m->getOptionalInt64());
196        }
197
198        $m->setOptionalInt64('3.1');
199        if (PHP_INT_SIZE == 4) {
200            $this->assertSame('3', $m->getOptionalInt64());
201        } else {
202            $this->assertSame(3, $m->getOptionalInt64());
203        }
204
205        $m->setOptionalInt64(MAX_INT64_STRING);
206        if (PHP_INT_SIZE == 4) {
207            $this->assertSame(MAX_INT64_STRING, $m->getOptionalInt64());
208        } else {
209            $this->assertSame(MAX_INT64, $m->getOptionalInt64());
210        }
211
212        $m->setOptionalInt64(MIN_INT64_STRING);
213        if (PHP_INT_SIZE == 4) {
214            $this->assertSame(MIN_INT64_STRING, $m->getOptionalInt64());
215        } else {
216            $this->assertSame(MIN_INT64, $m->getOptionalInt64());
217        }
218    }
219
220    #########################################################
221    # Test uint64 field.
222    #########################################################
223
224    public function testUint64Field()
225    {
226        $m = new TestMessage();
227
228        // Set integer.
229        $m->setOptionalUint64(MAX_UINT64);
230        if (PHP_INT_SIZE == 4) {
231            $this->assertSame(MAX_UINT64_STRING, $m->getOptionalUint64());
232        } else {
233            $this->assertSame(MAX_UINT64, $m->getOptionalUint64());
234        }
235
236        // Set float.
237        $m->setOptionalUint64(1.1);
238        if (PHP_INT_SIZE == 4) {
239            $this->assertSame('1', $m->getOptionalUint64());
240        } else {
241            $this->assertSame(1, $m->getOptionalUint64());
242        }
243
244        // Set string.
245        $m->setOptionalUint64('2');
246        if (PHP_INT_SIZE == 4) {
247            $this->assertSame('2', $m->getOptionalUint64());
248        } else {
249            $this->assertSame(2, $m->getOptionalUint64());
250        }
251
252        $m->setOptionalUint64('3.1');
253        if (PHP_INT_SIZE == 4) {
254            $this->assertSame('3', $m->getOptionalUint64());
255        } else {
256            $this->assertSame(3, $m->getOptionalUint64());
257        }
258
259        $m->setOptionalUint64(MAX_UINT64_STRING);
260        if (PHP_INT_SIZE == 4) {
261            $this->assertSame(MAX_UINT64_STRING, $m->getOptionalUint64());
262        } else {
263            $this->assertSame(MAX_UINT64, $m->getOptionalUint64());
264        }
265    }
266
267    #########################################################
268    # Test enum field.
269    #########################################################
270
271    public function testEnumField()
272    {
273        $m = new TestMessage();
274
275        // Set enum.
276        $m->setOptionalEnum(TestEnum::ONE);
277        $this->assertEquals(TestEnum::ONE, $m->getOptionalEnum());
278
279        // Set integer.
280        $m->setOptionalEnum(1);
281        $this->assertEquals(TestEnum::ONE, $m->getOptionalEnum());
282
283        // Set float.
284        $m->setOptionalEnum(1.1);
285        $this->assertEquals(TestEnum::ONE, $m->getOptionalEnum());
286
287        // Set string.
288        $m->setOptionalEnum("1");
289        $this->assertEquals(TestEnum::ONE, $m->getOptionalEnum());
290
291        // Test Enum methods
292        $this->assertEquals('ONE', TestEnum::name(1));
293        $this->assertEquals(1, TestEnum::value('ONE'));
294    }
295
296    public function testInvalidEnumValueThrowsException()
297    {
298        $this->expectException(UnexpectedValueException::class);
299        $this->expectExceptionMessage(
300            'Enum Foo\TestEnum has no name defined for value -1');
301
302        TestEnum::name(-1);
303    }
304
305    public function testInvalidEnumNameThrowsException()
306    {
307        $this->expectException(UnexpectedValueException::class);
308        $this->expectExceptionMessage(
309            'Enum Foo\TestEnum has no value defined for name DOES_NOT_EXIST');
310
311        TestEnum::value('DOES_NOT_EXIST');
312    }
313
314    public function testNestedEnum()
315    {
316        $m = new TestMessage();
317        $m->setOptionalNestedEnum(NestedEnum::ZERO);
318        $this->assertTrue(true);
319    }
320
321    public function testLegacyNestedEnum()
322    {
323        $m = new TestMessage();
324        $m->setOptionalNestedEnum(\Foo\TestMessage_NestedEnum::ZERO);
325        $this->assertTrue(true);
326    }
327
328    public function testLegacyTypehintWithNestedEnums()
329    {
330        $this->legacyEnum(new TestLegacyMessage\NestedEnum);
331    }
332
333    private function legacyEnum(TestLegacyMessage_NestedEnum $enum)
334    {
335        // If we made it here without a PHP Fatal error, the typehint worked
336        $this->assertTrue(true);
337    }
338
339    #########################################################
340    # Test float field.
341    #########################################################
342
343    public function testFloatField()
344    {
345        $m = new TestMessage();
346
347        // Set integer.
348        $m->setOptionalFloat(1);
349        $this->assertFloatEquals(1.0, $m->getOptionalFloat(), MAX_FLOAT_DIFF);
350
351        // Set float.
352        $m->setOptionalFloat(1.1);
353        $this->assertFloatEquals(1.1, $m->getOptionalFloat(), MAX_FLOAT_DIFF);
354
355        // Set string.
356        $m->setOptionalFloat('2');
357        $this->assertFloatEquals(2.0, $m->getOptionalFloat(), MAX_FLOAT_DIFF);
358        $m->setOptionalFloat('3.1');
359        $this->assertFloatEquals(3.1, $m->getOptionalFloat(), MAX_FLOAT_DIFF);
360    }
361
362    #########################################################
363    # Test double field.
364    #########################################################
365
366    public function testDoubleField()
367    {
368        $m = new TestMessage();
369
370        // Set integer.
371        $m->setOptionalDouble(1);
372        $this->assertFloatEquals(1.0, $m->getOptionalDouble(), MAX_FLOAT_DIFF);
373
374        // Set float.
375        $m->setOptionalDouble(1.1);
376        $this->assertFloatEquals(1.1, $m->getOptionalDouble(), MAX_FLOAT_DIFF);
377
378        // Set string.
379        $m->setOptionalDouble('2');
380        $this->assertFloatEquals(2.0, $m->getOptionalDouble(), MAX_FLOAT_DIFF);
381        $m->setOptionalDouble('3.1');
382        $this->assertFloatEquals(3.1, $m->getOptionalDouble(), MAX_FLOAT_DIFF);
383    }
384
385    #########################################################
386    # Test bool field.
387    #########################################################
388
389    public function testBoolField()
390    {
391        $m = new TestMessage();
392
393        // Set bool.
394        $m->setOptionalBool(true);
395        $this->assertSame(true, $m->getOptionalBool());
396
397        // Set integer.
398        $m->setOptionalBool(-1);
399        $this->assertSame(true, $m->getOptionalBool());
400
401        // Set float.
402        $m->setOptionalBool(1.1);
403        $this->assertSame(true, $m->getOptionalBool());
404
405        // Set string.
406        $m->setOptionalBool('');
407        $this->assertSame(false, $m->getOptionalBool());
408    }
409
410    #########################################################
411    # Test string field.
412    #########################################################
413
414    public function testStringField()
415    {
416        $m = new TestMessage();
417
418        // Set string.
419        $m->setOptionalString('abc');
420        $this->assertSame('abc', $m->getOptionalString());
421
422        // Set integer.
423        $m->setOptionalString(1);
424        $this->assertSame('1', $m->getOptionalString());
425
426        // Set double.
427        $m->setOptionalString(1.1);
428        $this->assertSame('1.1', $m->getOptionalString());
429
430        // Set bool.
431        $m->setOptionalString(true);
432        $this->assertSame('1', $m->getOptionalString());
433    }
434
435    #########################################################
436    # Test bytes field.
437    #########################################################
438
439    public function testBytesField()
440    {
441        $m = new TestMessage();
442
443        // Set string.
444        $m->setOptionalBytes('abc');
445        $this->assertSame('abc', $m->getOptionalBytes());
446
447        // Set integer.
448        $m->setOptionalBytes(1);
449        $this->assertSame('1', $m->getOptionalBytes());
450
451        // Set double.
452        $m->setOptionalBytes(1.1);
453        $this->assertSame('1.1', $m->getOptionalBytes());
454
455        // Set bool.
456        $m->setOptionalBytes(true);
457        $this->assertSame('1', $m->getOptionalBytes());
458    }
459
460      public function testBytesFieldInvalidUTF8Success()
461      {
462          $m = new TestMessage();
463          $hex = hex2bin("ff");
464          $m->setOptionalBytes($hex);
465          $this->assertTrue(true);
466      }
467
468    #########################################################
469    # Test message field.
470    #########################################################
471
472    public function testMessageField()
473    {
474        $m = new TestMessage();
475
476        $this->assertNull($m->getOptionalMessage());
477
478        $sub_m = new Sub();
479        $sub_m->setA(1);
480        $m->setOptionalMessage($sub_m);
481        $this->assertSame(1, $m->getOptionalMessage()->getA());
482        $this->assertTrue($m->hasOptionalMessage());
483
484        $null = null;
485        $m->setOptionalMessage($null);
486        $this->assertNull($m->getOptionalMessage());
487        $this->assertFalse($m->hasOptionalMessage());
488    }
489
490    public function testLegacyMessageField()
491    {
492        $m = new TestMessage();
493
494        $sub_m = new TestMessage_Sub();
495        $sub_m->setA(1);
496        $m->setOptionalMessage($sub_m);
497        $this->assertSame(1, $m->getOptionalMessage()->getA());
498
499        $null = null;
500        $m->setOptionalMessage($null);
501        $this->assertNull($m->getOptionalMessage());
502    }
503
504    public function testLegacyTypehintWithNestedMessages()
505    {
506        $this->legacyMessage(new TestLegacyMessage\NestedMessage);
507    }
508
509    private function legacyMessage(TestLegacyMessage_NestedMessage $sub)
510    {
511        // If we made it here without a PHP Fatal error, the typehint worked
512        $this->assertTrue(true);
513    }
514
515    #########################################################
516    # Test repeated field.
517    #########################################################
518
519    public function testRepeatedField()
520    {
521        $m = new TestMessage();
522
523        $repeated_int32 = new RepeatedField(GPBType::INT32);
524        $m->setRepeatedInt32($repeated_int32);
525        $this->assertSame($repeated_int32, $m->getRepeatedInt32());
526    }
527
528    public function testRepeatedFieldViaArray()
529    {
530        $m = new TestMessage();
531
532        $arr = array();
533        $m->setRepeatedInt32($arr);
534        $this->assertSame(0, count($m->getRepeatedInt32()));
535
536        $arr = array(1, 2.1, "3");
537        $m->setRepeatedInt32($arr);
538        $this->assertTrue($m->getRepeatedInt32() instanceof RepeatedField);
539        $this->assertSame("Google\Protobuf\Internal\RepeatedField",
540                          get_class($m->getRepeatedInt32()));
541        $this->assertSame(3, count($m->getRepeatedInt32()));
542        $this->assertSame(1, $m->getRepeatedInt32()[0]);
543        $this->assertSame(2, $m->getRepeatedInt32()[1]);
544        $this->assertSame(3, $m->getRepeatedInt32()[2]);
545        $this->assertFalse($arr instanceof RepeatedField);
546    }
547
548    #########################################################
549    # Test map field.
550    #########################################################
551
552    public function testMapField()
553    {
554        $m = new TestMessage();
555
556        $map_int32_int32 = new MapField(GPBType::INT32, GPBType::INT32);
557        $m->setMapInt32Int32($map_int32_int32);
558        $this->assertSame($map_int32_int32, $m->getMapInt32Int32());
559    }
560
561    public function testMapFieldViaArray()
562    {
563        $m = new TestMessage();
564
565        $dict = array();
566        $m->setMapInt32Int32($dict);
567        $this->assertSame(0, count($m->getMapInt32Int32()));
568
569        $dict = array(5 => 5, 6 => 6.1, "7" => "7");
570        $m->setMapInt32Int32($dict);
571        $this->assertTrue($m->getMapInt32Int32() instanceof MapField);
572        $this->assertSame(3, count($m->getMapInt32Int32()));
573        $this->assertSame(5, $m->getMapInt32Int32()[5]);
574        $this->assertSame(6, $m->getMapInt32Int32()[6]);
575        $this->assertSame(7, $m->getMapInt32Int32()[7]);
576        $this->assertFalse($dict instanceof MapField);
577    }
578
579    #########################################################
580    # Test oneof field.
581    #########################################################
582
583    public function testOneofField() {
584        $m = new TestMessage();
585
586        $this->assertSame("", $m->getMyOneof());
587
588        $m->setOneofInt32(1);
589        $this->assertSame(1, $m->getOneofInt32());
590        $this->assertSame(0.0, $m->getOneofFloat());
591        $this->assertSame('', $m->getOneofString());
592        $this->assertSame(NULL, $m->getOneofMessage());
593        $this->assertSame("oneof_int32", $m->getMyOneof());
594
595        $m->setOneofFloat(2.0);
596        $this->assertSame(0, $m->getOneofInt32());
597        $this->assertSame(2.0, $m->getOneofFloat());
598        $this->assertSame('', $m->getOneofString());
599        $this->assertSame(NULL, $m->getOneofMessage());
600        $this->assertSame("oneof_float", $m->getMyOneof());
601
602        $m->setOneofString('abc');
603        $this->assertSame(0, $m->getOneofInt32());
604        $this->assertSame(0.0, $m->getOneofFloat());
605        $this->assertSame('abc', $m->getOneofString());
606        $this->assertSame(NULL, $m->getOneofMessage());
607        $this->assertSame("oneof_string", $m->getMyOneof());
608
609        $sub_m = new Sub();
610        $sub_m->setA(1);
611        $m->setOneofMessage($sub_m);
612        $this->assertSame(0, $m->getOneofInt32());
613        $this->assertSame(0.0, $m->getOneofFloat());
614        $this->assertSame('', $m->getOneofString());
615        $this->assertSame(1, $m->getOneofMessage()->getA());
616        $this->assertSame("oneof_message", $m->getMyOneof());
617    }
618
619    #########################################################
620    # Test clear method.
621    #########################################################
622
623    public function testMessageClear()
624    {
625        $m = new TestMessage();
626        $this->setFields($m);
627        $this->expectFields($m);
628        $m->clear();
629        $this->expectEmptyFields($m);
630    }
631
632    #########################################################
633    # Test mergeFrom method.
634    #########################################################
635
636    public function testMessageMergeFrom()
637    {
638        $m = new TestMessage();
639        $this->setFields($m);
640        $this->expectFields($m);
641        $arr = $m->getOptionalMessage()->getB();
642        $arr[] = 1;
643
644        $n = new TestMessage();
645
646        // Singular
647        $n->setOptionalInt32(100);
648        $sub1 = new Sub();
649        $sub1->setA(101);
650
651        $b = $sub1->getB();
652        $b[] = 102;
653        $sub1->setB($b);
654
655        $n->setOptionalMessage($sub1);
656
657        // Repeated
658        $repeatedInt32 = $n->getRepeatedInt32();
659        $repeatedInt32[] = 200;
660        $n->setRepeatedInt32($repeatedInt32);
661
662        $repeatedString = $n->getRepeatedString();
663        $repeatedString[] = 'abc';
664        $n->setRepeatedString($repeatedString);
665
666        $sub2 = new Sub();
667        $sub2->setA(201);
668        $repeatedMessage = $n->getRepeatedMessage();
669        $repeatedMessage[] = $sub2;
670        $n->setRepeatedMessage($repeatedMessage);
671
672        // Map
673        $mapInt32Int32 = $n->getMapInt32Int32();
674        $mapInt32Int32[1] = 300;
675        $mapInt32Int32[-62] = 301;
676        $n->setMapInt32Int32($mapInt32Int32);
677
678        $mapStringString = $n->getMapStringString();
679        $mapStringString['def'] = 'def';
680        $n->setMapStringString($mapStringString);
681
682        $mapInt32Message = $n->getMapInt32Message();
683        $mapInt32Message[1] = new Sub();
684        $mapInt32Message[1]->setA(302);
685        $mapInt32Message[2] = new Sub();
686        $mapInt32Message[2]->setA(303);
687        $n->setMapInt32Message($mapInt32Message);
688
689        $m->mergeFrom($n);
690
691        $this->assertSame(100, $m->getOptionalInt32());
692        $this->assertSame(42, $m->getOptionalUint32());
693        $this->assertSame(101, $m->getOptionalMessage()->getA());
694        $this->assertSame(2, count($m->getOptionalMessage()->getB()));
695        $this->assertSame(1, $m->getOptionalMessage()->getB()[0]);
696        $this->assertSame(102, $m->getOptionalMessage()->getB()[1]);
697
698        $this->assertSame(3, count($m->getRepeatedInt32()));
699        $this->assertSame(200, $m->getRepeatedInt32()[2]);
700        $this->assertSame(2, count($m->getRepeatedUint32()));
701        $this->assertSame(3, count($m->getRepeatedString()));
702        $this->assertSame('abc', $m->getRepeatedString()[2]);
703        $this->assertSame(3, count($m->getRepeatedMessage()));
704        $this->assertSame(201, $m->getRepeatedMessage()[2]->getA());
705
706        $this->assertSame(2, count($m->getMapInt32Int32()));
707        $this->assertSame(300, $m->getMapInt32Int32()[1]);
708        $this->assertSame(301, $m->getMapInt32Int32()[-62]);
709        $this->assertSame(1, count($m->getMapUint32Uint32()));
710        $this->assertSame(2, count($m->getMapStringString()));
711        $this->assertSame('def', $m->getMapStringString()['def']);
712
713        $this->assertSame(2, count($m->getMapInt32Message()));
714        $this->assertSame(302, $m->getMapInt32Message()[1]->getA());
715        $this->assertSame(303, $m->getMapInt32Message()[2]->getA());
716
717        $this->assertSame("", $m->getMyOneof());
718
719        // Check sub-messages are copied by value.
720        $n->getOptionalMessage()->setA(-101);
721        $this->assertSame(101, $m->getOptionalMessage()->getA());
722
723        $repeatedMessage = $n->getRepeatedMessage();
724        $repeatedMessage[0]->setA(-201);
725        $n->setRepeatedMessage($repeatedMessage);
726        $this->assertSame(201, $m->getRepeatedMessage()[2]->getA());
727
728        $mapInt32Message = $n->getMapInt32Message();
729        $mapInt32Message[1]->setA(-302);
730        $n->setMapInt32Message($mapInt32Message);
731
732        $this->assertSame(302, $m->getMapInt32Message()[1]->getA());
733
734        // Test merge oneof.
735        $m = new TestMessage();
736
737        $n = new TestMessage();
738        $n->setOneofInt32(1);
739        $m->mergeFrom($n);
740        $this->assertSame(1, $m->getOneofInt32());
741
742        $sub = new Sub();
743        $n->setOneofMessage($sub);
744        $n->getOneofMessage()->setA(400);
745        $m->mergeFrom($n);
746        $this->assertSame(400, $m->getOneofMessage()->getA());
747        $n->getOneofMessage()->setA(-400);
748        $this->assertSame(400, $m->getOneofMessage()->getA());
749
750        // Test all fields
751        $m = new TestMessage();
752        $n = new TestMessage();
753        $this->setFields($m);
754        $n->mergeFrom($m);
755        $this->expectFields($n);
756    }
757
758    #########################################################
759    # Test message/enum without namespace.
760    #########################################################
761
762    public function testMessageWithoutNamespace()
763    {
764        $m = new TestMessage();
765        $n = new NoNamespaceMessage();
766        $m->setOptionalNoNamespaceMessage($n);
767        $repeatedNoNamespaceMessage = $m->getRepeatedNoNamespaceMessage();
768        $repeatedNoNamespaceMessage[] = new NoNamespaceMessage();
769        $m->setRepeatedNoNamespaceMessage($repeatedNoNamespaceMessage);
770
771        // test nested messages
772        $sub = new NoNamespaceMessage\NestedMessage();
773        $n->setNestedMessage($sub);
774
775        $this->assertTrue(true);
776    }
777
778    public function testEnumWithoutNamespace()
779    {
780        $m = new TestMessage();
781        $m->setOptionalNoNamespaceEnum(NoNamespaceEnum::VALUE_A);
782        $repeatedNoNamespaceEnum = $m->getRepeatedNoNamespaceEnum();
783        $repeatedNoNamespaceEnum[] = NoNamespaceEnum::VALUE_A;
784        $m->setRepeatedNoNamespaceEnum($repeatedNoNamespaceEnum);
785        $this->assertTrue(true);
786    }
787
788    #########################################################
789    # Test message with given namespace.
790    #########################################################
791
792    public function testNestedMessagesAndEnums()
793    {
794        $m = new TestMessage();
795        $n = new TestMessage\Sub();
796        $m->setOptionalMessage($n);
797        $m->setOptionalNestedEnum(TestMessage\NestedEnum::ZERO);
798        $this->assertSame($n, $m->getOptionalMessage());
799        $this->assertSame(TestMessage\NestedEnum::ZERO, $m->getOptionalNestedEnum());
800    }
801
802    public function testMessagesAndEnumsWithPrefix()
803    {
804        // Test message prefix
805        $m = new TestIncludePrefixMessage();
806        $n = new PrefixTestPrefix();
807        $n->setA(1);
808        $m->setPrefixMessage($n);
809        $this->assertSame(1, $m->getPrefixMessage()->getA());
810
811        // Test nested message prefix
812        $o = new PrefixTestPrefix();
813        $p = new PrefixTestPrefix\PrefixNestedMessage();
814        $o->setNestedMessage($p);
815        $o->setNestedEnum(PrefixTestPrefix\PrefixNestedEnum::ZERO);
816        $this->assertSame($p, $o->getNestedMessage());
817        $this->assertSame(PrefixTestPrefix\PrefixNestedEnum::ZERO, $o->getNestedEnum());
818    }
819
820    public function testMessagesAndEnumsWithPhpNamespace()
821    {
822        $m = new TestNamespace();
823        $n = new TestNamespace\NestedMessage();
824        $m->setNestedMessage($n);
825        $m->setNestedEnum(TestNamespace\NestedEnum::ZERO);
826        $this->assertSame($n, $m->getNestedMessage());
827        $this->assertSame(TestNamespace\NestedEnum::ZERO, $m->getNestedEnum());
828    }
829
830    public function testMesssagesAndEnumsWithEmptyPhpNamespace()
831    {
832        $m = new TestEmptyNamespace();
833        $n = new TestEmptyNamespace\NestedMessage();
834        $m->setNestedMessage($n);
835        $m->setNestedEnum(TestEmptyNamespace\NestedEnum::ZERO);
836        $this->assertSame($n, $m->getNestedMessage());
837        $this->assertSame(TestEmptyNamespace\NestedEnum::ZERO, $m->getNestedEnum());
838    }
839
840    public function testMessagesAndEnumsWithNoNamespace()
841    {
842        $m = new NoNamespaceMessage();
843        $n = new NoNamespaceMessage\NestedMessage();
844        $m->setNestedMessage($n);
845        $m->setNestedEnum(NoNamespaceMessage\NestedEnum::ZERO);
846        $this->assertSame($n, $m->getNestedMessage());
847        $this->assertSame(NoNamespaceMessage\NestedEnum::ZERO, $m->getNestedEnum());
848    }
849
850    public function testReservedWordsInPackageName()
851    {
852        $m = new TestEmptyPackage();
853        $n = new TestEmptyPackage\NestedMessage();
854        $m->setNestedMessage($n);
855        $m->setNestedEnum(TestEmptyPackage\NestedEnum::ZERO);
856        $this->assertSame($n, $m->getNestedMessage());
857        $this->assertSame(TestEmptyPackage\NestedEnum::ZERO, $m->getNestedEnum());
858    }
859
860    public function testReservedWordsInNamespace()
861    {
862        $m = new TestNamespace();
863        $n = new TestNamespace\PBEmpty();
864        $o = new TestNamespace\PBEmpty\NestedMessage();
865        $n->setNestedMessage($o);
866        $n->setNestedEnum(TestNamespace\PBEmpty\NestedEnum::ZERO);
867        $m->setReservedName($n);
868        $this->assertSame($n, $m->getReservedName());
869        $this->assertSame($o, $n->getNestedMessage());
870        $this->assertSame(
871            TestNamespace\PBEmpty\NestedEnum::ZERO,
872            $n->getNestedEnum()
873        );
874    }
875
876    #########################################################
877    # Test prefix for reserved words.
878    #########################################################
879
880    public function testPrefixForReservedWords()
881    {
882        $m = new \Foo\TestMessage\PBEmpty();
883        $m = new \Foo\PBEmpty();
884        $m = new \PrefixEmpty();
885        $m = new \Foo\PBARRAY();
886
887        $m = new \Lower\PBabstract();
888        $m = new \Lower\PBand();
889        $m = new \Lower\PBarray();
890        $m = new \Lower\PBas();
891        $m = new \Lower\PBbreak();
892        $m = new \Lower\PBcallable();
893        $m = new \Lower\PBcase();
894        $m = new \Lower\PBcatch();
895        $m = new \Lower\PBclass();
896        $m = new \Lower\PBclone();
897        $m = new \Lower\PBconst();
898        $m = new \Lower\PBcontinue();
899        $m = new \Lower\PBdeclare();
900        $m = new \Lower\PBdefault();
901        $m = new \Lower\PBdie();
902        $m = new \Lower\PBdo();
903        $m = new \Lower\PBecho();
904        $m = new \Lower\PBelse();
905        $m = new \Lower\PBelseif();
906        $m = new \Lower\PBempty();
907        $m = new \Lower\PBenddeclare();
908        $m = new \Lower\PBendfor();
909        $m = new \Lower\PBendforeach();
910        $m = new \Lower\PBendif();
911        $m = new \Lower\PBendswitch();
912        $m = new \Lower\PBendwhile();
913        $m = new \Lower\PBeval();
914        $m = new \Lower\PBexit();
915        $m = new \Lower\PBextends();
916        $m = new \Lower\PBfinal();
917        $m = new \Lower\PBfinally();
918        $m = new \Lower\PBfn();
919        $m = new \Lower\PBfor();
920        $m = new \Lower\PBforeach();
921        $m = new \Lower\PBfunction();
922        $m = new \Lower\PBglobal();
923        $m = new \Lower\PBgoto();
924        $m = new \Lower\PBif();
925        $m = new \Lower\PBimplements();
926        $m = new \Lower\PBinclude();
927        $m = new \Lower\PBinclude_once();
928        $m = new \Lower\PBinstanceof();
929        $m = new \Lower\PBinsteadof();
930        $m = new \Lower\PBinterface();
931        $m = new \Lower\PBisset();
932        $m = new \Lower\PBlist();
933        $m = new \Lower\PBmatch();
934        $m = new \Lower\PBnamespace();
935        $m = new \Lower\PBnew();
936        $m = new \Lower\PBor();
937        $m = new \Lower\PBparent();
938        $m = new \Lower\PBprint();
939        $m = new \Lower\PBprivate();
940        $m = new \Lower\PBprotected();
941        $m = new \Lower\PBpublic();
942        $m = new \Lower\PBrequire();
943        $m = new \Lower\PBrequire_once();
944        $m = new \Lower\PBreturn();
945        $m = new \Lower\PBself();
946        $m = new \Lower\PBstatic();
947        $m = new \Lower\PBswitch();
948        $m = new \Lower\PBthrow();
949        $m = new \Lower\PBtrait();
950        $m = new \Lower\PBtry();
951        $m = new \Lower\PBunset();
952        $m = new \Lower\PBuse();
953        $m = new \Lower\PBvar();
954        $m = new \Lower\PBwhile();
955        $m = new \Lower\PBxor();
956        $m = new \Lower\PByield();
957        $m = new \Lower\PBint();
958        $m = new \Lower\PBfloat();
959        $m = new \Lower\PBbool();
960        $m = new \Lower\PBstring();
961        $m = new \Lower\PBtrue();
962        $m = new \Lower\PBfalse();
963        $m = new \Lower\PBnull();
964        $m = new \Lower\PBvoid();
965        $m = new \Lower\PBiterable();
966
967        $m = new \Upper\PBABSTRACT();
968        $m = new \Upper\PBAND();
969        $m = new \Upper\PBARRAY();
970        $m = new \Upper\PBAS();
971        $m = new \Upper\PBBREAK();
972        $m = new \Upper\PBCALLABLE();
973        $m = new \Upper\PBCASE();
974        $m = new \Upper\PBCATCH();
975        $m = new \Upper\PBCLASS();
976        $m = new \Upper\PBCLONE();
977        $m = new \Upper\PBCONST();
978        $m = new \Upper\PBCONTINUE();
979        $m = new \Upper\PBDECLARE();
980        $m = new \Upper\PBDEFAULT();
981        $m = new \Upper\PBDIE();
982        $m = new \Upper\PBDO();
983        $m = new \Upper\PBECHO();
984        $m = new \Upper\PBELSE();
985        $m = new \Upper\PBELSEIF();
986        $m = new \Upper\PBEMPTY();
987        $m = new \Upper\PBENDDECLARE();
988        $m = new \Upper\PBENDFOR();
989        $m = new \Upper\PBENDFOREACH();
990        $m = new \Upper\PBENDIF();
991        $m = new \Upper\PBENDSWITCH();
992        $m = new \Upper\PBENDWHILE();
993        $m = new \Upper\PBEVAL();
994        $m = new \Upper\PBEXIT();
995        $m = new \Upper\PBEXTENDS();
996        $m = new \Upper\PBFINAL();
997        $m = new \Upper\PBFINALLY();
998        $m = new \Upper\PBFN();
999        $m = new \Upper\PBFOR();
1000        $m = new \Upper\PBFOREACH();
1001        $m = new \Upper\PBFUNCTION();
1002        $m = new \Upper\PBGLOBAL();
1003        $m = new \Upper\PBGOTO();
1004        $m = new \Upper\PBIF();
1005        $m = new \Upper\PBIMPLEMENTS();
1006        $m = new \Upper\PBINCLUDE();
1007        $m = new \Upper\PBINCLUDE_ONCE();
1008        $m = new \Upper\PBINSTANCEOF();
1009        $m = new \Upper\PBINSTEADOF();
1010        $m = new \Upper\PBINTERFACE();
1011        $m = new \Upper\PBISSET();
1012        $m = new \Upper\PBLIST();
1013        $m = new \Upper\PBMATCH();
1014        $m = new \Upper\PBNAMESPACE();
1015        $m = new \Upper\PBNEW();
1016        $m = new \Upper\PBOR();
1017        $m = new \Upper\PBPARENT();
1018        $m = new \Upper\PBPRINT();
1019        $m = new \Upper\PBPRIVATE();
1020        $m = new \Upper\PBPROTECTED();
1021        $m = new \Upper\PBPUBLIC();
1022        $m = new \Upper\PBREQUIRE();
1023        $m = new \Upper\PBREQUIRE_ONCE();
1024        $m = new \Upper\PBRETURN();
1025        $m = new \Upper\PBSELF();
1026        $m = new \Upper\PBSTATIC();
1027        $m = new \Upper\PBSWITCH();
1028        $m = new \Upper\PBTHROW();
1029        $m = new \Upper\PBTRAIT();
1030        $m = new \Upper\PBTRY();
1031        $m = new \Upper\PBUNSET();
1032        $m = new \Upper\PBUSE();
1033        $m = new \Upper\PBVAR();
1034        $m = new \Upper\PBWHILE();
1035        $m = new \Upper\PBXOR();
1036        $m = new \Upper\PBYIELD();
1037        $m = new \Upper\PBINT();
1038        $m = new \Upper\PBFLOAT();
1039        $m = new \Upper\PBBOOL();
1040        $m = new \Upper\PBSTRING();
1041        $m = new \Upper\PBTRUE();
1042        $m = new \Upper\PBFALSE();
1043        $m = new \Upper\PBNULL();
1044        $m = new \Upper\PBVOID();
1045        $m = new \Upper\PBITERABLE();
1046
1047        $m = new \Lower_enum\PBabstract();
1048        $m = new \Lower_enum\PBand();
1049        $m = new \Lower_enum\PBarray();
1050        $m = new \Lower_enum\PBas();
1051        $m = new \Lower_enum\PBbreak();
1052        $m = new \Lower_enum\PBcallable();
1053        $m = new \Lower_enum\PBcase();
1054        $m = new \Lower_enum\PBcatch();
1055        $m = new \Lower_enum\PBclass();
1056        $m = new \Lower_enum\PBclone();
1057        $m = new \Lower_enum\PBconst();
1058        $m = new \Lower_enum\PBcontinue();
1059        $m = new \Lower_enum\PBdeclare();
1060        $m = new \Lower_enum\PBdefault();
1061        $m = new \Lower_enum\PBdie();
1062        $m = new \Lower_enum\PBdo();
1063        $m = new \Lower_enum\PBecho();
1064        $m = new \Lower_enum\PBelse();
1065        $m = new \Lower_enum\PBelseif();
1066        $m = new \Lower_enum\PBempty();
1067        $m = new \Lower_enum\PBenddeclare();
1068        $m = new \Lower_enum\PBendfor();
1069        $m = new \Lower_enum\PBendforeach();
1070        $m = new \Lower_enum\PBendif();
1071        $m = new \Lower_enum\PBendswitch();
1072        $m = new \Lower_enum\PBendwhile();
1073        $m = new \Lower_enum\PBeval();
1074        $m = new \Lower_enum\PBexit();
1075        $m = new \Lower_enum\PBextends();
1076        $m = new \Lower_enum\PBfinal();
1077        $m = new \Lower_enum\PBfinally();
1078        $m = new \Lower_enum\PBfn();
1079        $m = new \Lower_enum\PBfor();
1080        $m = new \Lower_enum\PBforeach();
1081        $m = new \Lower_enum\PBfunction();
1082        $m = new \Lower_enum\PBglobal();
1083        $m = new \Lower_enum\PBgoto();
1084        $m = new \Lower_enum\PBif();
1085        $m = new \Lower_enum\PBimplements();
1086        $m = new \Lower_enum\PBinclude();
1087        $m = new \Lower_enum\PBinclude_once();
1088        $m = new \Lower_enum\PBinstanceof();
1089        $m = new \Lower_enum\PBinsteadof();
1090        $m = new \Lower_enum\PBinterface();
1091        $m = new \Lower_enum\PBisset();
1092        $m = new \Lower_enum\PBlist();
1093        $m = new \Lower_enum\PBmatch();
1094        $m = new \Lower_enum\PBnamespace();
1095        $m = new \Lower_enum\PBnew();
1096        $m = new \Lower_enum\PBor();
1097        $m = new \Lower_enum\PBparent();
1098        $m = new \Lower_enum\PBprint();
1099        $m = new \Lower_enum\PBprivate();
1100        $m = new \Lower_enum\PBprotected();
1101        $m = new \Lower_enum\PBpublic();
1102        $m = new \Lower_enum\PBrequire();
1103        $m = new \Lower_enum\PBrequire_once();
1104        $m = new \Lower_enum\PBreturn();
1105        $m = new \Lower_enum\PBself();
1106        $m = new \Lower_enum\PBstatic();
1107        $m = new \Lower_enum\PBswitch();
1108        $m = new \Lower_enum\PBthrow();
1109        $m = new \Lower_enum\PBtrait();
1110        $m = new \Lower_enum\PBtry();
1111        $m = new \Lower_enum\PBunset();
1112        $m = new \Lower_enum\PBuse();
1113        $m = new \Lower_enum\PBvar();
1114        $m = new \Lower_enum\PBwhile();
1115        $m = new \Lower_enum\PBxor();
1116        $m = new \Lower_enum\PByield();
1117        $m = new \Lower_enum\PBint();
1118        $m = new \Lower_enum\PBfloat();
1119        $m = new \Lower_enum\PBbool();
1120        $m = new \Lower_enum\PBstring();
1121        $m = new \Lower_enum\PBtrue();
1122        $m = new \Lower_enum\PBfalse();
1123        $m = new \Lower_enum\PBnull();
1124        $m = new \Lower_enum\PBvoid();
1125        $m = new \Lower_enum\PBiterable();
1126
1127        $m = new \Upper_enum\PBABSTRACT();
1128        $m = new \Upper_enum\PBAND();
1129        $m = new \Upper_enum\PBARRAY();
1130        $m = new \Upper_enum\PBAS();
1131        $m = new \Upper_enum\PBBREAK();
1132        $m = new \Upper_enum\PBCALLABLE();
1133        $m = new \Upper_enum\PBCASE();
1134        $m = new \Upper_enum\PBCATCH();
1135        $m = new \Upper_enum\PBCLASS();
1136        $m = new \Upper_enum\PBCLONE();
1137        $m = new \Upper_enum\PBCONST();
1138        $m = new \Upper_enum\PBCONTINUE();
1139        $m = new \Upper_enum\PBDECLARE();
1140        $m = new \Upper_enum\PBDEFAULT();
1141        $m = new \Upper_enum\PBDIE();
1142        $m = new \Upper_enum\PBDO();
1143        $m = new \Upper_enum\PBECHO();
1144        $m = new \Upper_enum\PBELSE();
1145        $m = new \Upper_enum\PBELSEIF();
1146        $m = new \Upper_enum\PBEMPTY();
1147        $m = new \Upper_enum\PBENDDECLARE();
1148        $m = new \Upper_enum\PBENDFOR();
1149        $m = new \Upper_enum\PBENDFOREACH();
1150        $m = new \Upper_enum\PBENDIF();
1151        $m = new \Upper_enum\PBENDSWITCH();
1152        $m = new \Upper_enum\PBENDWHILE();
1153        $m = new \Upper_enum\PBEVAL();
1154        $m = new \Upper_enum\PBEXIT();
1155        $m = new \Upper_enum\PBEXTENDS();
1156        $m = new \Upper_enum\PBFINAL();
1157        $m = new \Upper_enum\PBFINALLY();
1158        $m = new \Upper_enum\PBFN();
1159        $m = new \Upper_enum\PBFOR();
1160        $m = new \Upper_enum\PBFOREACH();
1161        $m = new \Upper_enum\PBFUNCTION();
1162        $m = new \Upper_enum\PBGLOBAL();
1163        $m = new \Upper_enum\PBGOTO();
1164        $m = new \Upper_enum\PBIF();
1165        $m = new \Upper_enum\PBIMPLEMENTS();
1166        $m = new \Upper_enum\PBINCLUDE();
1167        $m = new \Upper_enum\PBINCLUDE_ONCE();
1168        $m = new \Upper_enum\PBINSTANCEOF();
1169        $m = new \Upper_enum\PBINSTEADOF();
1170        $m = new \Upper_enum\PBINTERFACE();
1171        $m = new \Upper_enum\PBISSET();
1172        $m = new \Upper_enum\PBLIST();
1173        $m = new \Upper_enum\PBMATCH();
1174        $m = new \Upper_enum\PBNAMESPACE();
1175        $m = new \Upper_enum\PBNEW();
1176        $m = new \Upper_enum\PBOR();
1177        $m = new \Upper_enum\PBPARENT();
1178        $m = new \Upper_enum\PBPRINT();
1179        $m = new \Upper_enum\PBPRIVATE();
1180        $m = new \Upper_enum\PBPROTECTED();
1181        $m = new \Upper_enum\PBPUBLIC();
1182        $m = new \Upper_enum\PBREQUIRE();
1183        $m = new \Upper_enum\PBREQUIRE_ONCE();
1184        $m = new \Upper_enum\PBRETURN();
1185        $m = new \Upper_enum\PBSELF();
1186        $m = new \Upper_enum\PBSTATIC();
1187        $m = new \Upper_enum\PBSWITCH();
1188        $m = new \Upper_enum\PBTHROW();
1189        $m = new \Upper_enum\PBTRAIT();
1190        $m = new \Upper_enum\PBTRY();
1191        $m = new \Upper_enum\PBUNSET();
1192        $m = new \Upper_enum\PBUSE();
1193        $m = new \Upper_enum\PBVAR();
1194        $m = new \Upper_enum\PBWHILE();
1195        $m = new \Upper_enum\PBXOR();
1196        $m = new \Upper_enum\PBYIELD();
1197        $m = new \Upper_enum\PBINT();
1198        $m = new \Upper_enum\PBFLOAT();
1199        $m = new \Upper_enum\PBBOOL();
1200        $m = new \Upper_enum\PBSTRING();
1201        $m = new \Upper_enum\PBTRUE();
1202        $m = new \Upper_enum\PBFALSE();
1203        $m = new \Upper_enum\PBNULL();
1204        $m = new \Upper_enum\PBVOID();
1205        $m = new \Upper_enum\PBITERABLE();
1206
1207        $m = \Lower_enum_value\NotAllowed::PBabstract;
1208        $m = \Lower_enum_value\NotAllowed::PBand;
1209        $m = \Lower_enum_value\NotAllowed::PBarray;
1210        $m = \Lower_enum_value\NotAllowed::PBas;
1211        $m = \Lower_enum_value\NotAllowed::PBbreak;
1212        $m = \Lower_enum_value\NotAllowed::PBcallable;
1213        $m = \Lower_enum_value\NotAllowed::PBcase;
1214        $m = \Lower_enum_value\NotAllowed::PBcatch;
1215        $m = \Lower_enum_value\NotAllowed::PBclass;
1216        $m = \Lower_enum_value\NotAllowed::PBclone;
1217        $m = \Lower_enum_value\NotAllowed::PBconst;
1218        $m = \Lower_enum_value\NotAllowed::PBcontinue;
1219        $m = \Lower_enum_value\NotAllowed::PBdeclare;
1220        $m = \Lower_enum_value\NotAllowed::PBdefault;
1221        $m = \Lower_enum_value\NotAllowed::PBdie;
1222        $m = \Lower_enum_value\NotAllowed::PBdo;
1223        $m = \Lower_enum_value\NotAllowed::PBecho;
1224        $m = \Lower_enum_value\NotAllowed::PBelse;
1225        $m = \Lower_enum_value\NotAllowed::PBelseif;
1226        $m = \Lower_enum_value\NotAllowed::PBempty;
1227        $m = \Lower_enum_value\NotAllowed::PBenddeclare;
1228        $m = \Lower_enum_value\NotAllowed::PBendfor;
1229        $m = \Lower_enum_value\NotAllowed::PBendforeach;
1230        $m = \Lower_enum_value\NotAllowed::PBendif;
1231        $m = \Lower_enum_value\NotAllowed::PBendswitch;
1232        $m = \Lower_enum_value\NotAllowed::PBendwhile;
1233        $m = \Lower_enum_value\NotAllowed::PBeval;
1234        $m = \Lower_enum_value\NotAllowed::PBexit;
1235        $m = \Lower_enum_value\NotAllowed::PBextends;
1236        $m = \Lower_enum_value\NotAllowed::PBfinal;
1237        $m = \Lower_enum_value\NotAllowed::PBfinally;
1238        $m = \Lower_enum_value\NotAllowed::PBfn;
1239        $m = \Lower_enum_value\NotAllowed::PBfor;
1240        $m = \Lower_enum_value\NotAllowed::PBforeach;
1241        $m = \Lower_enum_value\NotAllowed::PBfunction;
1242        $m = \Lower_enum_value\NotAllowed::PBglobal;
1243        $m = \Lower_enum_value\NotAllowed::PBgoto;
1244        $m = \Lower_enum_value\NotAllowed::PBif;
1245        $m = \Lower_enum_value\NotAllowed::PBimplements;
1246        $m = \Lower_enum_value\NotAllowed::PBinclude;
1247        $m = \Lower_enum_value\NotAllowed::PBinclude_once;
1248        $m = \Lower_enum_value\NotAllowed::PBinstanceof;
1249        $m = \Lower_enum_value\NotAllowed::PBinsteadof;
1250        $m = \Lower_enum_value\NotAllowed::PBinterface;
1251        $m = \Lower_enum_value\NotAllowed::PBisset;
1252        $m = \Lower_enum_value\NotAllowed::PBlist;
1253        $m = \Lower_enum_value\NotAllowed::PBmatch;
1254        $m = \Lower_enum_value\NotAllowed::PBnamespace;
1255        $m = \Lower_enum_value\NotAllowed::PBnew;
1256        $m = \Lower_enum_value\NotAllowed::PBor;
1257        $m = \Lower_enum_value\NotAllowed::PBprint;
1258        $m = \Lower_enum_value\NotAllowed::PBprivate;
1259        $m = \Lower_enum_value\NotAllowed::PBprotected;
1260        $m = \Lower_enum_value\NotAllowed::PBpublic;
1261        $m = \Lower_enum_value\NotAllowed::PBrequire;
1262        $m = \Lower_enum_value\NotAllowed::PBrequire_once;
1263        $m = \Lower_enum_value\NotAllowed::PBreturn;
1264        $m = \Lower_enum_value\NotAllowed::PBstatic;
1265        $m = \Lower_enum_value\NotAllowed::PBswitch;
1266        $m = \Lower_enum_value\NotAllowed::PBthrow;
1267        $m = \Lower_enum_value\NotAllowed::PBtrait;
1268        $m = \Lower_enum_value\NotAllowed::PBtry;
1269        $m = \Lower_enum_value\NotAllowed::PBunset;
1270        $m = \Lower_enum_value\NotAllowed::PBuse;
1271        $m = \Lower_enum_value\NotAllowed::PBvar;
1272        $m = \Lower_enum_value\NotAllowed::PBwhile;
1273        $m = \Lower_enum_value\NotAllowed::PBxor;
1274        $m = \Lower_enum_value\NotAllowed::PByield;
1275        $m = \Lower_enum_value\NotAllowed::int;
1276        $m = \Lower_enum_value\NotAllowed::float;
1277        $m = \Lower_enum_value\NotAllowed::bool;
1278        $m = \Lower_enum_value\NotAllowed::string;
1279        $m = \Lower_enum_value\NotAllowed::true;
1280        $m = \Lower_enum_value\NotAllowed::false;
1281        $m = \Lower_enum_value\NotAllowed::null;
1282        $m = \Lower_enum_value\NotAllowed::void;
1283        $m = \Lower_enum_value\NotAllowed::iterable;
1284        $m = \Lower_enum_value\NotAllowed::parent;
1285        $m = \Lower_enum_value\NotAllowed::self;
1286
1287        $m = \Upper_enum_value\NotAllowed::PBABSTRACT;
1288        $m = \Upper_enum_value\NotAllowed::PBAND;
1289        $m = \Upper_enum_value\NotAllowed::PBARRAY;
1290        $m = \Upper_enum_value\NotAllowed::PBAS;
1291        $m = \Upper_enum_value\NotAllowed::PBBREAK;
1292        $m = \Upper_enum_value\NotAllowed::PBCALLABLE;
1293        $m = \Upper_enum_value\NotAllowed::PBCASE;
1294        $m = \Upper_enum_value\NotAllowed::PBCATCH;
1295        $m = \Upper_enum_value\NotAllowed::PBCLASS;
1296        $m = \Upper_enum_value\NotAllowed::PBCLONE;
1297        $m = \Upper_enum_value\NotAllowed::PBCONST;
1298        $m = \Upper_enum_value\NotAllowed::PBCONTINUE;
1299        $m = \Upper_enum_value\NotAllowed::PBDECLARE;
1300        $m = \Upper_enum_value\NotAllowed::PBDEFAULT;
1301        $m = \Upper_enum_value\NotAllowed::PBDIE;
1302        $m = \Upper_enum_value\NotAllowed::PBDO;
1303        $m = \Upper_enum_value\NotAllowed::PBECHO;
1304        $m = \Upper_enum_value\NotAllowed::PBELSE;
1305        $m = \Upper_enum_value\NotAllowed::PBELSEIF;
1306        $m = \Upper_enum_value\NotAllowed::PBEMPTY;
1307        $m = \Upper_enum_value\NotAllowed::PBENDDECLARE;
1308        $m = \Upper_enum_value\NotAllowed::PBENDFOR;
1309        $m = \Upper_enum_value\NotAllowed::PBENDFOREACH;
1310        $m = \Upper_enum_value\NotAllowed::PBENDIF;
1311        $m = \Upper_enum_value\NotAllowed::PBENDSWITCH;
1312        $m = \Upper_enum_value\NotAllowed::PBENDWHILE;
1313        $m = \Upper_enum_value\NotAllowed::PBEVAL;
1314        $m = \Upper_enum_value\NotAllowed::PBEXIT;
1315        $m = \Upper_enum_value\NotAllowed::PBEXTENDS;
1316        $m = \Upper_enum_value\NotAllowed::PBFINAL;
1317        $m = \Upper_enum_value\NotAllowed::PBFINALLY;
1318        $m = \Upper_enum_value\NotAllowed::PBFN;
1319        $m = \Upper_enum_value\NotAllowed::PBFOR;
1320        $m = \Upper_enum_value\NotAllowed::PBFOREACH;
1321        $m = \Upper_enum_value\NotAllowed::PBFUNCTION;
1322        $m = \Upper_enum_value\NotAllowed::PBGLOBAL;
1323        $m = \Upper_enum_value\NotAllowed::PBGOTO;
1324        $m = \Upper_enum_value\NotAllowed::PBIF;
1325        $m = \Upper_enum_value\NotAllowed::PBIMPLEMENTS;
1326        $m = \Upper_enum_value\NotAllowed::PBINCLUDE;
1327        $m = \Upper_enum_value\NotAllowed::PBINCLUDE_ONCE;
1328        $m = \Upper_enum_value\NotAllowed::PBINSTANCEOF;
1329        $m = \Upper_enum_value\NotAllowed::PBINSTEADOF;
1330        $m = \Upper_enum_value\NotAllowed::PBINTERFACE;
1331        $m = \Upper_enum_value\NotAllowed::PBISSET;
1332        $m = \Upper_enum_value\NotAllowed::PBLIST;
1333        $m = \Upper_enum_value\NotAllowed::PBMATCH;
1334        $m = \Upper_enum_value\NotAllowed::PBNAMESPACE;
1335        $m = \Upper_enum_value\NotAllowed::PBNEW;
1336        $m = \Upper_enum_value\NotAllowed::PBOR;
1337        $m = \Upper_enum_value\NotAllowed::PBPRINT;
1338        $m = \Upper_enum_value\NotAllowed::PBPRIVATE;
1339        $m = \Upper_enum_value\NotAllowed::PBPROTECTED;
1340        $m = \Upper_enum_value\NotAllowed::PBPUBLIC;
1341        $m = \Upper_enum_value\NotAllowed::PBREQUIRE;
1342        $m = \Upper_enum_value\NotAllowed::PBREQUIRE_ONCE;
1343        $m = \Upper_enum_value\NotAllowed::PBRETURN;
1344        $m = \Upper_enum_value\NotAllowed::PBSTATIC;
1345        $m = \Upper_enum_value\NotAllowed::PBSWITCH;
1346        $m = \Upper_enum_value\NotAllowed::PBTHROW;
1347        $m = \Upper_enum_value\NotAllowed::PBTRAIT;
1348        $m = \Upper_enum_value\NotAllowed::PBTRY;
1349        $m = \Upper_enum_value\NotAllowed::PBUNSET;
1350        $m = \Upper_enum_value\NotAllowed::PBUSE;
1351        $m = \Upper_enum_value\NotAllowed::PBVAR;
1352        $m = \Upper_enum_value\NotAllowed::PBWHILE;
1353        $m = \Upper_enum_value\NotAllowed::PBXOR;
1354        $m = \Upper_enum_value\NotAllowed::PBYIELD;
1355        $m = \Upper_enum_value\NotAllowed::INT;
1356        $m = \Upper_enum_value\NotAllowed::FLOAT;
1357        $m = \Upper_enum_value\NotAllowed::BOOL;
1358        $m = \Upper_enum_value\NotAllowed::STRING;
1359        $m = \Upper_enum_value\NotAllowed::TRUE;
1360        $m = \Upper_enum_value\NotAllowed::FALSE;
1361        $m = \Upper_enum_value\NotAllowed::NULL;
1362        $m = \Upper_enum_value\NotAllowed::VOID;
1363        $m = \Upper_enum_value\NotAllowed::ITERABLE;
1364        $m = \Upper_enum_value\NotAllowed::PARENT;
1365        $m = \Upper_enum_value\NotAllowed::SELF;
1366
1367        $this->assertTrue(true);
1368    }
1369
1370    #########################################################
1371    # Test fluent setters.
1372    #########################################################
1373
1374    public function testFluentSetters()
1375    {
1376        $m = (new TestMessage())
1377            ->setOptionalInt32(1)
1378            ->setOptionalUInt32(2);
1379        $this->assertSame(1, $m->getOptionalInt32());
1380        $this->assertSame(2, $m->getOptionalUInt32());
1381    }
1382
1383    #########################################################
1384    # Test Reverse Field Order.
1385    #########################################################
1386
1387    public function testReverseFieldOrder()
1388    {
1389        $m = new TestReverseFieldOrder();
1390        $m->setB("abc");
1391        $this->assertSame("abc", $m->getB());
1392        $this->assertNotSame("abc", $m->getA());
1393    }
1394
1395    #########################################################
1396    # Test Reverse Field Order.
1397    #########################################################
1398
1399    public function testLowerCase()
1400    {
1401        $m = new testLowerCaseMessage();
1402        $n = testLowerCaseEnum::VALUE;
1403        $this->assertTrue(true);
1404    }
1405
1406    #########################################################
1407    # Test Array Constructor.
1408    #########################################################
1409
1410    public function testArrayConstructor()
1411    {
1412        $m = new TestMessage([
1413            'optional_int32' => -42,
1414            'optional_int64' => -43,
1415            'optional_uint32' => 42,
1416            'optional_uint64' => 43,
1417            'optional_sint32' => -44,
1418            'optional_sint64' => -45,
1419            'optional_fixed32' => 46,
1420            'optional_fixed64' => 47,
1421            'optional_sfixed32' => -46,
1422            'optional_sfixed64' => -47,
1423            'optional_float' => 1.5,
1424            'optional_double' => 1.6,
1425            'optional_bool' => true,
1426            'optional_string' => 'a',
1427            'optional_bytes' => 'bbbb',
1428            'optional_enum' => TestEnum::ONE,
1429            'optional_message' => new Sub([
1430                'a' => 33
1431            ]),
1432            'repeated_int32' => [-42, -52],
1433            'repeated_int64' => [-43, -53],
1434            'repeated_uint32' => [42, 52],
1435            'repeated_uint64' => [43, 53],
1436            'repeated_sint32' => [-44, -54],
1437            'repeated_sint64' => [-45, -55],
1438            'repeated_fixed32' => [46, 56],
1439            'repeated_fixed64' => [47, 57],
1440            'repeated_sfixed32' => [-46, -56],
1441            'repeated_sfixed64' => [-47, -57],
1442            'repeated_float' => [1.5, 2.5],
1443            'repeated_double' => [1.6, 2.6],
1444            'repeated_bool' => [true, false],
1445            'repeated_string' => ['a', 'c'],
1446            'repeated_bytes' => ['bbbb', 'dddd'],
1447            'repeated_enum' => [TestEnum::ZERO, TestEnum::ONE],
1448            'repeated_message' => [new Sub(['a' => 34]),
1449                                   new Sub(['a' => 35])],
1450            'map_int32_int32' => [-62 => -62],
1451            'map_int64_int64' => [-63 => -63],
1452            'map_uint32_uint32' => [62 => 62],
1453            'map_uint64_uint64' => [63 => 63],
1454            'map_sint32_sint32' => [-64 => -64],
1455            'map_sint64_sint64' => [-65 => -65],
1456            'map_fixed32_fixed32' => [66 => 66],
1457            'map_fixed64_fixed64' => [67 => 67],
1458            'map_sfixed32_sfixed32' => [-68 => -68],
1459            'map_sfixed64_sfixed64' => [-69 => -69],
1460            'map_int32_float' => [1 => 3.5],
1461            'map_int32_double' => [1 => 3.6],
1462            'map_bool_bool' => [true => true],
1463            'map_string_string' => ['e' => 'e'],
1464            'map_int32_bytes' => [1 => 'ffff'],
1465            'map_int32_enum' => [1 => TestEnum::ONE],
1466            'map_int32_message' => [1 => new Sub(['a' => 36])],
1467        ]);
1468
1469        TestUtil::assertTestMessage($m);
1470        $this->assertTrue(true);
1471    }
1472
1473    public function testReferenceInArrayConstructor()
1474    {
1475        $keys = [[
1476                    'optional_bool' => true,
1477                    'repeated_bool' => [true],
1478                    'map_bool_bool' => [true => true],
1479                    'optional_double' => 1.0,
1480                    'repeated_double' => [1.0],
1481                    'map_int32_double' => [1 => 1.0],
1482                    'optional_int32' => 1,
1483                    'repeated_int32' => [1],
1484                    'map_int32_int32' => [1 => 1],
1485                    'optional_string' => 'a',
1486                    'repeated_string' => ['a'],
1487                    'map_string_string' => ['a' => 'a'],
1488                    'optional_message' => ['a' => 1],
1489                    'repeated_message' => [['a' => 1]],
1490                    'map_int32_message' => [1 => ['a' => 1]],
1491                ]];
1492
1493        foreach ($keys as &$key) {
1494            foreach ($key as $id => &$value) {
1495                if ($id === 'repeated_bool') {
1496                    foreach ($value as &$element) {
1497                    }
1498                }
1499                if ($id === 'map_bool_bool') {
1500                    foreach ($value as $mapKey => &$element) {
1501                    }
1502                }
1503                if ($id === 'repeated_double') {
1504                    foreach ($value as &$element) {
1505                    }
1506                }
1507                if ($id === 'map_int32_double') {
1508                    foreach ($value as $mapKey => &$element) {
1509                    }
1510                }
1511                if ($id === 'repeated_int32') {
1512                    foreach ($value as &$element) {
1513                    }
1514                }
1515                if ($id === 'map_int32_int32') {
1516                    foreach ($value as $mapKey => &$element) {
1517                    }
1518                }
1519                if ($id === 'repeated_string') {
1520                    foreach ($value as &$element) {
1521                    }
1522                }
1523                if ($id === 'map_string_string') {
1524                    foreach ($value as $mapKey => &$element) {
1525                    }
1526                }
1527                if ($id === 'optional_message') {
1528                    $value = new Sub($value);
1529                }
1530                if ($id === 'repeated_message') {
1531                    foreach ($value as &$element) {
1532                        $element = new Sub($element);
1533                    }
1534                }
1535                if ($id === 'map_int32_message') {
1536                    foreach ($value as $mapKey => &$element) {
1537                        $element = new Sub($element);
1538                    }
1539                }
1540            }
1541            $key = new TestMessage($key);
1542        }
1543
1544        $this->assertTrue(true);
1545    }
1546
1547    public function testOneofMessageInArrayConstructor()
1548    {
1549        $m = new TestMessage([
1550            'oneof_message' => new Sub(),
1551        ]);
1552        $this->assertSame('oneof_message', $m->getMyOneof());
1553        $this->assertNotNull($m->getOneofMessage());
1554
1555        $this->assertTrue(true);
1556    }
1557
1558    public function testOneofStringInArrayConstructor()
1559    {
1560        $m = new TestMessage([
1561            'oneof_string' => 'abc',
1562        ]);
1563
1564        $this->assertTrue(true);
1565    }
1566
1567    #########################################################
1568    # Test clone.
1569    #########################################################
1570
1571    public function testClone()
1572    {
1573        $m = new TestMessage([
1574            'optional_int32' => -42,
1575            'optional_int64' => -43,
1576            'optional_message' => new Sub([
1577                'a' => 33
1578            ]),
1579            'map_int32_message' => [1 => new Sub(['a' => 36])],
1580        ]);
1581        $m2 = clone $m;
1582        $this->assertEquals($m->getOptionalInt32(), $m2->getOptionalInt32());
1583        $this->assertEquals($m->getOptionalInt64(), $m2->getOptionalInt64());
1584        $this->assertSame($m->getOptionalMessage(), $m2->getOptionalMessage());
1585        $this->assertSame($m->getMapInt32Message()[1], $m2->getMapInt32Message()[1]);
1586        $this->assertEquals($m->serializeToJsonString(), $m2->serializeToJsonString());
1587    }
1588
1589    #########################################################
1590    # Test message equals.
1591    #########################################################
1592
1593    public function testMessageEquals()
1594    {
1595        $m = new TestMessage();
1596        TestUtil::setTestMessage($m);
1597        $n = new TestMessage();
1598        TestUtil::setTestMessage($n);
1599        $this->assertEquals($m, $n);
1600    }
1601
1602    #########################################################
1603    # Test reference of value
1604    #########################################################
1605
1606    public function testValueIsReference()
1607    {
1608        // Bool element
1609        $values = [true];
1610        array_walk($values, function (&$value) {});
1611        $m = new TestMessage();
1612        $m->setOptionalBool($values[0]);
1613
1614        // Int32 element
1615        $values = [1];
1616        array_walk($values, function (&$value) {});
1617        $m = new TestMessage();
1618        $m->setOptionalInt32($values[0]);
1619
1620        // Double element
1621        $values = [1.0];
1622        array_walk($values, function (&$value) {});
1623        $m = new TestMessage();
1624        $m->setOptionalDouble($values[0]);
1625
1626        // String element
1627        $values = ['a'];
1628        array_walk($values, function (&$value) {});
1629        $m = new TestMessage();
1630        $m->setOptionalString($values[0]);
1631
1632        $this->assertTrue(true);
1633    }
1634
1635    #########################################################
1636    # Test equality
1637    #########################################################
1638
1639    public function testShallowEquality()
1640    {
1641        $m1 = new TestMessage([
1642            'optional_int32' => -42,
1643            'optional_int64' => -43,
1644            'optional_uint32' => 42,
1645            'optional_uint64' => 43,
1646            'optional_sint32' => -44,
1647            'optional_sint64' => -45,
1648            'optional_fixed32' => 46,
1649            'optional_fixed64' => 47,
1650            'optional_sfixed32' => -46,
1651            'optional_sfixed64' => -47,
1652            'optional_float' => 1.5,
1653            'optional_double' => 1.6,
1654            'optional_bool' => true,
1655            'optional_string' => 'a',
1656            'optional_bytes' => 'bbbb',
1657            'optional_enum' => TestEnum::ONE,
1658            ]);
1659        $data = $m1->serializeToString();
1660        $m2 = new TestMessage();
1661        $m2->mergeFromString($data);
1662        $this->assertTrue($m1 == $m2);
1663
1664        $m1->setOptionalInt32(1234);
1665        $this->assertTrue($m1 != $m2);
1666    }
1667
1668    public function testDeepEquality()
1669    {
1670        $m1 = new TestMessage([
1671            'optional_int32' => -42,
1672            'optional_int64' => -43,
1673            'optional_uint32' => 42,
1674            'optional_uint64' => 43,
1675            'optional_sint32' => -44,
1676            'optional_sint64' => -45,
1677            'optional_fixed32' => 46,
1678            'optional_fixed64' => 47,
1679            'optional_sfixed32' => -46,
1680            'optional_sfixed64' => -47,
1681            'optional_float' => 1.5,
1682            'optional_double' => 1.6,
1683            'optional_bool' => true,
1684            'optional_string' => 'a',
1685            'optional_bytes' => 'bbbb',
1686            'optional_enum' => TestEnum::ONE,
1687            'optional_message' => new Sub([
1688                'a' => 33
1689            ]),
1690            'repeated_int32' => [-42, -52],
1691            'repeated_int64' => [-43, -53],
1692            'repeated_uint32' => [42, 52],
1693            'repeated_uint64' => [43, 53],
1694            'repeated_sint32' => [-44, -54],
1695            'repeated_sint64' => [-45, -55],
1696            'repeated_fixed32' => [46, 56],
1697            'repeated_fixed64' => [47, 57],
1698            'repeated_sfixed32' => [-46, -56],
1699            'repeated_sfixed64' => [-47, -57],
1700            'repeated_float' => [1.5, 2.5],
1701            'repeated_double' => [1.6, 2.6],
1702            'repeated_bool' => [true, false],
1703            'repeated_string' => ['a', 'c'],
1704            'repeated_bytes' => ['bbbb', 'dddd'],
1705            'repeated_enum' => [TestEnum::ZERO, TestEnum::ONE],
1706            'repeated_message' => [new Sub(['a' => 34]),
1707                                   new Sub(['a' => 35])],
1708            'map_int32_int32' => [-62 => -62],
1709            'map_int64_int64' => [-63 => -63],
1710            'map_uint32_uint32' => [62 => 62],
1711            'map_uint64_uint64' => [63 => 63],
1712            'map_sint32_sint32' => [-64 => -64],
1713            'map_sint64_sint64' => [-65 => -65],
1714            'map_fixed32_fixed32' => [66 => 66],
1715            'map_fixed64_fixed64' => [67 => 67],
1716            'map_sfixed32_sfixed32' => [-68 => -68],
1717            'map_sfixed64_sfixed64' => [-69 => -69],
1718            'map_int32_float' => [1 => 3.5],
1719            'map_int32_double' => [1 => 3.6],
1720            'map_bool_bool' => [true => true],
1721            'map_string_string' => ['e' => 'e'],
1722            'map_int32_bytes' => [1 => 'ffff'],
1723            'map_int32_enum' => [1 => TestEnum::ONE],
1724            'map_int32_message' => [1 => new Sub(['a' => 36])],
1725        ]);
1726        $data = $m1->serializeToString();
1727
1728        $m2 = new TestMessage();
1729        $m2->mergeFromString($data);
1730        $this->assertTrue($m1 == $m2);
1731
1732        # Nested sub-message is checked.
1733        $m2 = new TestMessage();
1734        $m2->mergeFromString($data);
1735        $m2->getOptionalMessage()->setA(1234);
1736        $this->assertTrue($m1 != $m2);
1737
1738        # Repeated field element is checked.
1739        $m2 = new TestMessage();
1740        $m2->mergeFromString($data);
1741        $m2->getRepeatedInt32()[0] = 1234;
1742        $this->assertTrue($m1 != $m2);
1743
1744        # Repeated field length is checked.
1745        $m2 = new TestMessage();
1746        $m2->mergeFromString($data);
1747        $m2->getRepeatedInt32()[] = 1234;
1748        $this->assertTrue($m1 != $m2);
1749
1750        # SubMessage inside repeated field is checked.
1751        $m2 = new TestMessage();
1752        $m2->mergeFromString($data);
1753        $m2->getRepeatedMessage()[0]->setA(1234);
1754        $this->assertTrue($m1 != $m2);
1755
1756        # Map value is checked.
1757        $m2 = new TestMessage();
1758        $m2->mergeFromString($data);
1759        $m2->getMapInt32Int32()[-62] = 1234;
1760        $this->assertTrue($m1 != $m2);
1761
1762        # Map size is checked.
1763        $m2 = new TestMessage();
1764        $m2->mergeFromString($data);
1765        $m2->getMapInt32Int32()[1234] = 1234;
1766        $this->assertTrue($m1 != $m2);
1767
1768        # SubMessage inside map field is checked.
1769        $m2 = new TestMessage();
1770        $m2->mergeFromString($data);
1771        $m2->getMapInt32Message()[1]->setA(1234);
1772        $this->assertTrue($m1 != $m2);
1773
1774        # TODO: what about unknown fields?
1775    }
1776
1777    #########################################################
1778    # Test hasOneof<Field> methods exists and working
1779    #########################################################
1780
1781    public function testHasOneof() {
1782        $m = new TestMessage();
1783        $this->assertFalse($m->hasOneofInt32());
1784        $m->setOneofInt32(42);
1785        $this->assertTrue($m->hasOneofInt32());
1786        $m->setOneofString("bar");
1787        $this->assertFalse($m->hasOneofInt32());
1788        $this->assertTrue($m->hasOneofString());
1789        $m->clear();
1790        $this->assertFalse($m->hasOneofInt32());
1791        $this->assertFalse($m->hasOneofString());
1792
1793        $sub_m = new Sub();
1794        $sub_m->setA(1);
1795        $m->setOneofMessage($sub_m);
1796        $this->assertTrue($m->hasOneofMessage());
1797        $m->setOneofMessage(null);
1798        $this->assertFalse($m->hasOneofMessage());
1799    }
1800
1801    #########################################################
1802    # Test that we don't crash if users create their own messages.
1803    #########################################################
1804
1805    public function testUserDefinedClass() {
1806        if (getenv("USE_ZEND_ALLOC") === "0") {
1807            // We're running a memory test. This test appears to leak in a way
1808            // we cannot control, PHP bug?
1809            //
1810            // TODO: investigate further.
1811            $this->markTestSkipped();
1812            return;
1813        }
1814
1815        # This is not allowed, but at least we shouldn't crash.
1816        $this->expectException(Exception::class);
1817        new C();
1818    }
1819
1820    #########################################################
1821    # Test no segfault when error happens
1822    #########################################################
1823
1824    function throwIntendedException()
1825    {
1826        throw new Exception('Intended');
1827    }
1828    public function testNoSegfaultWithError()
1829    {
1830        if (getenv("USE_ZEND_ALLOC") === "0") {
1831            // We're running a memory test. This test appears to leak in a way
1832            // we cannot control, PHP bug?
1833            //
1834            // TODO: investigate further.
1835            $this->markTestSkipped();
1836            return;
1837        }
1838        $this->expectException(Exception::class);
1839
1840        new TestMessage(['optional_int32' => $this->throwIntendedException()]);
1841    }
1842
1843    public function testNoExceptionWithVarDump()
1844    {
1845        $m = new Sub(['a' => 1]);
1846        /*
1847         * This line currently segfaults on macOS with:
1848         *
1849         *    frame #0: 0x00000001029936cc xdebug.so`xdebug_zend_hash_is_recursive + 4
1850         *    frame #1: 0x00000001029a6736 xdebug.so`xdebug_var_export_text_ansi + 1006
1851         *    frame #2: 0x00000001029a715d xdebug.so`xdebug_get_zval_value_text_ansi + 273
1852         *    frame #3: 0x000000010298a441 xdebug.so`zif_xdebug_var_dump + 297
1853         *    frame #4: 0x000000010298d558 xdebug.so`xdebug_execute_internal + 640
1854         *    frame #5: 0x000000010046d47f php`ZEND_DO_FCALL_SPEC_RETVAL_UNUSED_HANDLER + 364
1855         *    frame #6: 0x000000010043cabc php`execute_ex + 44
1856         *    frame #7: 0x000000010298d151 xdebug.so`xdebug_execute_ex + 1662
1857         *    frame #8: 0x000000010046d865 php`ZEND_DO_FCALL_SPEC_RETVAL_USED_HANDLER + 426
1858         *
1859         * The value we are passing to var_dump() appears to be corrupt somehow.
1860         */
1861        /* var_dump($m); */
1862
1863        $this->assertTrue(true);
1864    }
1865
1866    public function testIssue9440()
1867    {
1868        $m = new Test32Fields();
1869        $m->setId(8);
1870        $this->assertEquals(8, $m->getId());
1871        $m->setVersion('1');
1872        $this->assertEquals(8, $m->getId());
1873    }
1874}
1875