• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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(7, $desc->getFieldCount());
87
88        $this->assertInstanceOf('\Google\Protobuf\OneofDescriptor', $desc->getOneofDecl(0));
89        $this->assertSame(1, $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
184        // Oneof int field
185        // Tested further in testOneofDescriptor()
186        $fieldDesc = $fieldDescMap[51];
187        $this->assertSame('oneof_int32', $fieldDesc->getName());
188        $this->assertSame(51, $fieldDesc->getNumber());
189        $this->assertSame(self::GPBLABEL_OPTIONAL, $fieldDesc->getLabel());
190        $this->assertSame(self::GPBTYPE_INT32, $fieldDesc->getType());
191        $this->assertFalse($fieldDesc->isMap());
192
193        // Map int-enum field
194        $fieldDesc = $fieldDescMap[71];
195        $this->assertSame('map_int32_enum', $fieldDesc->getName());
196        $this->assertSame(71, $fieldDesc->getNumber());
197        $this->assertSame(self::GPBLABEL_REPEATED, $fieldDesc->getLabel());
198        $this->assertSame(self::GPBTYPE_MESSAGE, $fieldDesc->getType());
199        $this->assertTrue($fieldDesc->isMap());
200        $mapDesc = $fieldDesc->getMessageType();
201        $this->assertSame('descriptors.TestDescriptorsMessage.MapInt32EnumEntry', $mapDesc->getFullName());
202        $this->assertSame(self::GPBTYPE_INT32, $mapDesc->getField(0)->getType());
203        $this->assertSame(self::GPBTYPE_ENUM, $mapDesc->getField(1)->getType());
204    }
205
206    public function testFieldDescriptorEnumException()
207    {
208        $this->expectException(Exception::class);
209
210        $pool = DescriptorPool::getGeneratedPool();
211        $desc = $pool->getDescriptorByClassName(get_class(new TestDescriptorsMessage()));
212        $fieldDesc = $desc->getField(0);
213        $fieldDesc->getEnumType();
214    }
215
216    public function testFieldDescriptorMessageException()
217    {
218        $this->expectException(Exception::class);
219
220        $pool = DescriptorPool::getGeneratedPool();
221        $desc = $pool->getDescriptorByClassName(get_class(new TestDescriptorsMessage()));
222        $fieldDesc = $desc->getField(0);
223        $fieldDesc->getMessageType();
224    }
225
226    #########################################################
227    # Test oneof descriptor.
228    #########################################################
229
230    public function testOneofDescriptor()
231    {
232        $pool = DescriptorPool::getGeneratedPool();
233        $desc = $pool->getDescriptorByClassName(get_class(new TestDescriptorsMessage()));
234
235        $fieldDescMap = $this->buildFieldMap($desc);
236        $fieldDesc = $fieldDescMap[51];
237
238        $oneofDesc = $desc->getOneofDecl(0);
239
240        $this->assertSame('my_oneof', $oneofDesc->getName());
241        $fieldDescFromOneof = $oneofDesc->getField(0);
242        $this->assertSame($fieldDesc, $fieldDescFromOneof);
243        $this->assertSame(1, $oneofDesc->getFieldCount());
244    }
245
246    private function buildFieldMap($desc)
247    {
248        $fieldDescMap = [];
249        for ($i = 0; $i < $desc->getFieldCount(); $i++) {
250            $fieldDesc = $desc->getField($i);
251            $fieldDescMap[$fieldDesc->getNumber()] = $fieldDesc;
252        }
253        return $fieldDescMap;
254    }
255}
256