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