xref: /aosp_15_r20/external/protobuf/php/tests/DescriptorsTest.php (revision 1b3f573f81763fcece89efc2b6a5209149e44ab8)
1<?php
2
3require_once('test_base.php');
4require_once('test_util.php');
5
6use Google\Protobuf\DescriptorPool;
7use Google\Protobuf\Internal\RepeatedField;
8use Google\Protobuf\Internal\MapField;
9use Descriptors\TestDescriptorsEnum;
10use Descriptors\TestDescriptorsMessage;
11use Descriptors\TestDescriptorsMessage\Sub;
12use Foo\TestMessage;
13use Bar\TestInclude;
14
15class DescriptorsTest extends TestBase
16{
17
18    // Redefine these here for compatibility with c extension
19    const GPBLABEL_OPTIONAL = 1;
20    const GPBLABEL_REQUIRED = 2;
21    const GPBLABEL_REPEATED = 3;
22
23    const GPBTYPE_DOUBLE   =  1;
24    const GPBTYPE_FLOAT    =  2;
25    const GPBTYPE_INT64    =  3;
26    const GPBTYPE_UINT64   =  4;
27    const GPBTYPE_INT32    =  5;
28    const GPBTYPE_FIXED64  =  6;
29    const GPBTYPE_FIXED32  =  7;
30    const GPBTYPE_BOOL     =  8;
31    const GPBTYPE_STRING   =  9;
32    const GPBTYPE_GROUP    = 10;
33    const GPBTYPE_MESSAGE  = 11;
34    const GPBTYPE_BYTES    = 12;
35    const GPBTYPE_UINT32   = 13;
36    const GPBTYPE_ENUM     = 14;
37    const GPBTYPE_SFIXED32 = 15;
38    const GPBTYPE_SFIXED64 = 16;
39    const GPBTYPE_SINT32   = 17;
40    const GPBTYPE_SINT64   = 18;
41
42    #########################################################
43    # Test descriptor pool.
44    #########################################################
45
46    public function testDescriptorPool()
47    {
48        $pool = DescriptorPool::getGeneratedPool();
49
50        $desc = $pool->getDescriptorByClassName(get_class(new TestDescriptorsMessage()));
51        $this->assertInstanceOf('\Google\Protobuf\Descriptor', $desc);
52
53        $enumDesc = $pool->getEnumDescriptorByClassName(get_class(new TestDescriptorsEnum()));
54        $this->assertInstanceOf('\Google\Protobuf\EnumDescriptor', $enumDesc);
55    }
56
57    public function testDescriptorPoolIncorrectArgs()
58    {
59        $pool = DescriptorPool::getGeneratedPool();
60
61        $desc = $pool->getDescriptorByClassName('NotAClass');
62        $this->assertNull($desc);
63
64        $desc = $pool->getDescriptorByClassName(get_class(new TestDescriptorsEnum()));
65        $this->assertNull($desc);
66
67        $enumDesc = $pool->getEnumDescriptorByClassName(get_class(new TestDescriptorsMessage()));
68        $this->assertNull($enumDesc);
69    }
70
71    #########################################################
72    # Test descriptor.
73    #########################################################
74
75    public function testDescriptor()
76    {
77        $pool = DescriptorPool::getGeneratedPool();
78        $class = get_class(new TestDescriptorsMessage());
79        $this->assertSame('Descriptors\TestDescriptorsMessage', $class);
80        $desc = $pool->getDescriptorByClassName($class);
81
82        $this->assertSame('descriptors.TestDescriptorsMessage', $desc->getFullName());
83        $this->assertSame($class, $desc->getClass());
84
85        $this->assertInstanceOf('\Google\Protobuf\FieldDescriptor', $desc->getField(0));
86        $this->assertSame(8, $desc->getFieldCount());
87
88        $this->assertInstanceOf('\Google\Protobuf\OneofDescriptor', $desc->getOneofDecl(0));
89        $this->assertSame(2, $desc->getOneofDeclCount());
90    }
91
92    public function testDescriptorForIncludedMessage()
93    {
94        $pool = DescriptorPool::getGeneratedPool();
95        $class = get_class(new TestMessage());
96        $this->assertSame('Foo\TestMessage', $class);
97        $desc = $pool->getDescriptorByClassName($class);
98        $fielddesc = $desc->getField(17);
99        $subdesc = $fielddesc->getMessageType();
100        $this->assertSame('Bar\TestInclude', $subdesc->getClass());
101    }
102
103    #########################################################
104    # Test enum descriptor.
105    #########################################################
106
107    public function testEnumDescriptor()
108    {
109        // WARNING - we need to do this so that TestDescriptorsEnum is registered!!?
110        new TestDescriptorsMessage();
111
112        $pool = DescriptorPool::getGeneratedPool();
113
114        $enumDesc = $pool->getEnumDescriptorByClassName(get_class(new TestDescriptorsEnum()));
115
116        // Build map of enum values
117        $enumDescMap = [];
118        for ($i = 0; $i < $enumDesc->getValueCount(); $i++) {
119            $enumValueDesc = $enumDesc->getValue($i);
120            $this->assertInstanceOf('\Google\Protobuf\EnumValueDescriptor', $enumValueDesc);
121            $enumDescMap[$enumValueDesc->getNumber()] = $enumValueDesc->getName();
122        }
123
124        $this->assertSame('ZERO', $enumDescMap[0]);
125        $this->assertSame('ONE', $enumDescMap[1]);
126
127        $this->assertSame(2, $enumDesc->getValueCount());
128    }
129
130    #########################################################
131    # Test field descriptor.
132    #########################################################
133
134    public function testFieldDescriptor()
135    {
136        $pool = DescriptorPool::getGeneratedPool();
137        $desc = $pool->getDescriptorByClassName(get_class(new TestDescriptorsMessage()));
138
139        $fieldDescMap = $this->buildFieldMap($desc);
140
141        // Optional int field
142        $fieldDesc = $fieldDescMap[1];
143        $this->assertSame('optional_int32', $fieldDesc->getName());
144        $this->assertSame(1, $fieldDesc->getNumber());
145        $this->assertSame(self::GPBLABEL_OPTIONAL, $fieldDesc->getLabel());
146        $this->assertSame(self::GPBTYPE_INT32, $fieldDesc->getType());
147        $this->assertFalse($fieldDesc->isMap());
148
149        // Optional enum field
150        $fieldDesc = $fieldDescMap[16];
151        $this->assertSame('optional_enum', $fieldDesc->getName());
152        $this->assertSame(16, $fieldDesc->getNumber());
153        $this->assertSame(self::GPBLABEL_OPTIONAL, $fieldDesc->getLabel());
154        $this->assertSame(self::GPBTYPE_ENUM, $fieldDesc->getType());
155        $this->assertInstanceOf('\Google\Protobuf\EnumDescriptor', $fieldDesc->getEnumType());
156        $this->assertFalse($fieldDesc->isMap());
157
158        // Optional message field
159        $fieldDesc = $fieldDescMap[17];
160        $this->assertSame('optional_message', $fieldDesc->getName());
161        $this->assertSame(17, $fieldDesc->getNumber());
162        $this->assertSame(self::GPBLABEL_OPTIONAL, $fieldDesc->getLabel());
163        $this->assertSame(self::GPBTYPE_MESSAGE, $fieldDesc->getType());
164        $this->assertInstanceOf('\Google\Protobuf\Descriptor', $fieldDesc->getMessageType());
165        $this->assertFalse($fieldDesc->isMap());
166
167        // Repeated int field
168        $fieldDesc = $fieldDescMap[31];
169        $this->assertSame('repeated_int32', $fieldDesc->getName());
170        $this->assertSame(31, $fieldDesc->getNumber());
171        $this->assertSame(self::GPBLABEL_REPEATED, $fieldDesc->getLabel());
172        $this->assertSame(self::GPBTYPE_INT32, $fieldDesc->getType());
173        $this->assertFalse($fieldDesc->isMap());
174
175        // Repeated message field
176        $fieldDesc = $fieldDescMap[47];
177        $this->assertSame('repeated_message', $fieldDesc->getName());
178        $this->assertSame(47, $fieldDesc->getNumber());
179        $this->assertSame(self::GPBLABEL_REPEATED, $fieldDesc->getLabel());
180        $this->assertSame(self::GPBTYPE_MESSAGE, $fieldDesc->getType());
181        $this->assertInstanceOf('\Google\Protobuf\Descriptor', $fieldDesc->getMessageType());
182        $this->assertFalse($fieldDesc->isMap());
183        $this->assertNull($fieldDesc->getContainingOneof());
184
185        // Oneof int field
186        // Tested further in testOneofDescriptor()
187        $fieldDesc = $fieldDescMap[51];
188        $this->assertSame('oneof_int32', $fieldDesc->getName());
189        $this->assertSame(51, $fieldDesc->getNumber());
190        $this->assertSame(self::GPBLABEL_OPTIONAL, $fieldDesc->getLabel());
191        $this->assertSame(self::GPBTYPE_INT32, $fieldDesc->getType());
192        $this->assertFalse($fieldDesc->isMap());
193        $this->assertSame($fieldDesc->getContainingOneof(), $fieldDesc->getRealContainingOneof());
194
195        $oneofDesc = $fieldDesc->getContainingOneof();
196        $this->assertSame('my_oneof', $oneofDesc->getName());
197
198        // Proto3 optional it field.
199        // Tested further in testOneofDescriptor()
200        $fieldDesc = $fieldDescMap[52];
201        $this->assertSame('proto3_optional_int32', $fieldDesc->getName());
202        $this->assertSame(52, $fieldDesc->getNumber());
203        $this->assertSame(self::GPBLABEL_OPTIONAL, $fieldDesc->getLabel());
204        $this->assertSame(self::GPBTYPE_INT32, $fieldDesc->getType());
205        $this->assertFalse($fieldDesc->isMap());
206        $this->assertNull($fieldDesc->getRealContainingOneof());
207        $this->assertNotNull($fieldDesc->getContainingOneof());
208
209        // Map int-enum field
210        $fieldDesc = $fieldDescMap[71];
211        $this->assertSame('map_int32_enum', $fieldDesc->getName());
212        $this->assertSame(71, $fieldDesc->getNumber());
213        $this->assertSame(self::GPBLABEL_REPEATED, $fieldDesc->getLabel());
214        $this->assertSame(self::GPBTYPE_MESSAGE, $fieldDesc->getType());
215        $this->assertTrue($fieldDesc->isMap());
216        $mapDesc = $fieldDesc->getMessageType();
217        $this->assertSame('descriptors.TestDescriptorsMessage.MapInt32EnumEntry', $mapDesc->getFullName());
218        $this->assertSame(self::GPBTYPE_INT32, $mapDesc->getField(0)->getType());
219        $this->assertSame(self::GPBTYPE_ENUM, $mapDesc->getField(1)->getType());
220    }
221
222    public function testFieldDescriptorEnumException()
223    {
224        $this->expectException(Exception::class);
225
226        $pool = DescriptorPool::getGeneratedPool();
227        $desc = $pool->getDescriptorByClassName(get_class(new TestDescriptorsMessage()));
228        $fieldDesc = $desc->getField(0);
229        $fieldDesc->getEnumType();
230    }
231
232    public function testFieldDescriptorMessageException()
233    {
234        $this->expectException(Exception::class);
235
236        $pool = DescriptorPool::getGeneratedPool();
237        $desc = $pool->getDescriptorByClassName(get_class(new TestDescriptorsMessage()));
238        $fieldDesc = $desc->getField(0);
239        $fieldDesc->getMessageType();
240    }
241
242    #########################################################
243    # Test oneof descriptor.
244    #########################################################
245
246    public function testOneofDescriptor()
247    {
248        $pool = DescriptorPool::getGeneratedPool();
249        $desc = $pool->getDescriptorByClassName(get_class(new TestDescriptorsMessage()));
250
251        $fieldDescMap = $this->buildFieldMap($desc);
252        $fieldDesc = $fieldDescMap[51];
253
254        $oneofDesc = $desc->getOneofDecl(0);
255
256        $this->assertSame('my_oneof', $oneofDesc->getName());
257        $fieldDescFromOneof = $oneofDesc->getField(0);
258        $this->assertSame($fieldDesc, $fieldDescFromOneof);
259        $this->assertSame(1, $oneofDesc->getFieldCount());
260    }
261
262    private function buildFieldMap($desc)
263    {
264        $fieldDescMap = [];
265        for ($i = 0; $i < $desc->getFieldCount(); $i++) {
266            $fieldDesc = $desc->getField($i);
267            $fieldDescMap[$fieldDesc->getNumber()] = $fieldDesc;
268        }
269        return $fieldDescMap;
270    }
271}
272