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