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