diff --git a/Makefile.am b/Makefile.am
index 6279b2de1a..fafe1d252f 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -597,6 +597,12 @@ php_EXTRA_DIST= \
php/ext/google/protobuf/upb.c \
php/ext/google/protobuf/protobuf.c \
php/src/phpdoc.dist.xml \
+ php/src/Google/Protobuf/Descriptor.php \
+ php/src/Google/Protobuf/DescriptorPool.php \
+ php/src/Google/Protobuf/EnumDescriptor.php \
+ php/src/Google/Protobuf/EnumValueDescriptor.php \
+ php/src/Google/Protobuf/FieldDescriptor.php \
+ php/src/Google/Protobuf/OneofDescriptor.php \
php/src/Google/Protobuf/Internal/CodedInputStream.php \
php/src/Google/Protobuf/Internal/CodedOutputStream.php \
php/src/Google/Protobuf/Internal/DescriptorPool.php \
@@ -609,7 +615,6 @@ php_EXTRA_DIST= \
php/src/Google/Protobuf/Internal/EnumDescriptorProto.php \
php/src/Google/Protobuf/Internal/EnumOptions.php \
php/src/Google/Protobuf/Internal/EnumValueDescriptorProto.php \
- php/src/Google/Protobuf/Internal/EnumValueDescriptor.php \
php/src/Google/Protobuf/Internal/EnumValueOptions.php \
php/src/Google/Protobuf/Internal/FieldDescriptorProto_Label.php \
php/src/Google/Protobuf/Internal/FieldDescriptorProto.php \
@@ -625,6 +630,7 @@ php_EXTRA_DIST= \
php/src/Google/Protobuf/Internal/FileOptions.php \
php/src/Google/Protobuf/Internal/GeneratedCodeInfo_Annotation.php \
php/src/Google/Protobuf/Internal/GeneratedCodeInfo.php \
+ php/src/Google/Protobuf/Internal/GetPublicDescriptorTrait.php \
php/src/Google/Protobuf/Internal/GPBDecodeException.php \
php/src/Google/Protobuf/Internal/GPBJsonWire.php \
php/src/Google/Protobuf/Internal/GPBLabel.php \
@@ -632,6 +638,7 @@ php_EXTRA_DIST= \
php/src/Google/Protobuf/Internal/GPBUtil.php \
php/src/Google/Protobuf/Internal/GPBWireType.php \
php/src/Google/Protobuf/Internal/GPBWire.php \
+ php/src/Google/Protobuf/Internal/HasPublicDescriptorTrait.php \
php/src/Google/Protobuf/Internal/MapEntry.php \
php/src/Google/Protobuf/Internal/MapFieldIter.php \
php/src/Google/Protobuf/Internal/MapField.php \
diff --git a/composer.json b/composer.json
index 80d90eabf3..2c64ad220f 100644
--- a/composer.json
+++ b/composer.json
@@ -16,8 +16,8 @@
},
"autoload": {
"psr-4": {
- "Google\\Protobuf\\Internal\\": "php/src/Google/Protobuf/Internal",
- "GPBMetadata\\Google\\Protobuf\\Internal\\": "php/src/GPBMetadata/Google/Protobuf/Internal"
+ "Google\\Protobuf\\": "php/src/Google/Protobuf",
+ "GPBMetadata\\Google\\Protobuf\\": "php/src/GPBMetadata/Google/Protobuf"
}
}
}
diff --git a/php/composer.json b/php/composer.json
index 724a45dd88..34e0447c80 100644
--- a/php/composer.json
+++ b/php/composer.json
@@ -13,12 +13,8 @@
},
"autoload": {
"psr-4": {
- "Foo\\": "tests/generated/Foo",
- "Bar\\": "tests/generated/Bar",
- "Google\\Protobuf\\": "tests/generated/Google/Protobuf",
- "Google\\Protobuf\\Internal\\": "src/Google/Protobuf/Internal",
- "GPBMetadata\\": "tests/generated/GPBMetadata",
- "GPBMetadata\\Google\\Protobuf\\Internal\\": "src/GPBMetadata/Google/Protobuf/Internal",
+ "Google\\Protobuf\\": "src/Google/Protobuf",
+ "GPBMetadata\\Google\\Protobuf\\": "src/GPBMetadata/Google/Protobuf",
"": "tests/generated"
}
}
diff --git a/php/phpunit.xml b/php/phpunit.xml
index 637467bec2..d7077038dd 100644
--- a/php/phpunit.xml
+++ b/php/phpunit.xml
@@ -10,6 +10,7 @@
tests/generated_phpdoc_test.php
tests/map_field_test.php
tests/well_known_test.php
+ tests/descriptors_test.php
tests/generated_service_test.php
diff --git a/php/src/Google/Protobuf/Descriptor.php b/php/src/Google/Protobuf/Descriptor.php
new file mode 100644
index 0000000000..986b81e12d
--- /dev/null
+++ b/php/src/Google/Protobuf/Descriptor.php
@@ -0,0 +1,100 @@
+internal_desc = $internal_desc;
+ }
+
+ /**
+ * @return string Full protobuf message name
+ */
+ public function getFullName()
+ {
+ return trim($this->internal_desc->getFullName(), ".");
+ }
+
+ /**
+ * @return string PHP class name
+ */
+ public function getClass()
+ {
+ return $this->internal_desc->getClass();
+ }
+
+ /**
+ * @param int $index Must be >= 0 and < getFieldCount()
+ * @return FieldDescriptor
+ */
+ public function getField($index)
+ {
+ return $this->getPublicDescriptor($this->internal_desc->getFieldByIndex($index));
+ }
+
+ /**
+ * @return int Number of fields in message
+ */
+ public function getFieldCount()
+ {
+ return count($this->internal_desc->getField());
+ }
+
+ /**
+ * @param int $index Must be >= 0 and < getOneofDeclCount()
+ * @return OneofDescriptor
+ */
+ public function getOneofDecl($index)
+ {
+ return $this->getPublicDescriptor($this->internal_desc->getOneofDecl()[$index]);
+ }
+
+ /**
+ * @return int Number of oneofs in message
+ */
+ public function getOneofDeclCount()
+ {
+ return count($this->internal_desc->getOneofDecl());
+ }
+}
diff --git a/php/src/Google/Protobuf/DescriptorPool.php b/php/src/Google/Protobuf/DescriptorPool.php
new file mode 100644
index 0000000000..119f0e2e60
--- /dev/null
+++ b/php/src/Google/Protobuf/DescriptorPool.php
@@ -0,0 +1,76 @@
+internal_pool = $internal_pool;
+ }
+
+ /**
+ * @param string $className A fully qualified protobuf class name
+ * @return Descriptor
+ */
+ public function getDescriptorByClassName($className)
+ {
+ $desc = $this->internal_pool->getDescriptorByClassName($className);
+ return is_null($desc) ? null : $desc->getPublicDescriptor();
+ }
+
+ /**
+ * @param string $className A fully qualified protobuf class name
+ * @return EnumDescriptor
+ */
+ public function getEnumDescriptorByClassName($className)
+ {
+ $desc = $this->internal_pool->getEnumDescriptorByClassName($className);
+ return is_null($desc) ? null : $desc->getPublicDescriptor();
+ }
+}
diff --git a/php/src/Google/Protobuf/EnumDescriptor.php b/php/src/Google/Protobuf/EnumDescriptor.php
new file mode 100644
index 0000000000..a8b56c0d46
--- /dev/null
+++ b/php/src/Google/Protobuf/EnumDescriptor.php
@@ -0,0 +1,79 @@
+internal_desc = $internal_desc;
+ }
+
+ /**
+ * @return string Full protobuf message name
+ */
+ public function getFullName()
+ {
+ return $this->internal_desc->getFullName();
+ }
+
+ /**
+ * @return string PHP class name
+ */
+ public function getClass()
+ {
+ return $this->internal_desc->getClass();
+ }
+
+ /**
+ * @param int $index Must be >= 0 and < getValueCount()
+ * @return EnumValueDescriptor
+ */
+ public function getValue($index)
+ {
+ return $this->internal_desc->getValueDescriptorByIndex($index);
+ }
+
+ /**
+ * @return int Number of values in enum
+ */
+ public function getValueCount()
+ {
+ return $this->internal_desc->getValueCount();
+ }
+}
diff --git a/php/src/Google/Protobuf/Internal/EnumValueDescriptor.php b/php/src/Google/Protobuf/EnumValueDescriptor.php
similarity index 91%
rename from php/src/Google/Protobuf/Internal/EnumValueDescriptor.php
rename to php/src/Google/Protobuf/EnumValueDescriptor.php
index 549766e3ae..e76e199718 100644
--- a/php/src/Google/Protobuf/Internal/EnumValueDescriptor.php
+++ b/php/src/Google/Protobuf/EnumValueDescriptor.php
@@ -30,28 +30,33 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-namespace Google\Protobuf\Internal;
+namespace Google\Protobuf;
class EnumValueDescriptor
{
private $name;
private $number;
- public function setName($name)
+ /**
+ * @internal
+ */
+ public function __construct($name, $number)
{
$this->name = $name;
+ $this->number = $number;
}
+ /**
+ * @return string
+ */
public function getName()
{
return $this->name;
}
- public function setNumber($number)
- {
- $this->number = $number;
- }
-
+ /**
+ * @return int
+ */
public function getNumber()
{
return $this->number;
diff --git a/php/src/Google/Protobuf/FieldDescriptor.php b/php/src/Google/Protobuf/FieldDescriptor.php
new file mode 100644
index 0000000000..ac9271f98b
--- /dev/null
+++ b/php/src/Google/Protobuf/FieldDescriptor.php
@@ -0,0 +1,117 @@
+internal_desc = $internal_desc;
+ }
+
+ /**
+ * @return string Field name
+ */
+ public function getName()
+ {
+ return $this->internal_desc->getName();
+ }
+
+ /**
+ * @return int Protobuf field number
+ */
+ public function getNumber()
+ {
+ return $this->internal_desc->getNumber();
+ }
+
+ /**
+ * @return int
+ */
+ public function getLabel()
+ {
+ return $this->internal_desc->getLabel();
+ }
+
+ /**
+ * @return int
+ */
+ public function getType()
+ {
+ return $this->internal_desc->getType();
+ }
+
+ /**
+ * @return Descriptor Returns a descriptor for the field type if the field type is a message, otherwise throws \Exception
+ * @throws \Exception
+ */
+ public function getMessageType()
+ {
+ if ($this->getType() == GPBType::MESSAGE) {
+ return $this->getPublicDescriptor($this->internal_desc->getMessageType());
+ } else {
+ throw new \Exception("Cannot get message type for non-message field '" . $this->getName() . "'");
+ }
+ }
+
+ /**
+ * @return EnumDescriptor Returns an enum descriptor if the field type is an enum, otherwise throws \Exception
+ * @throws \Exception
+ */
+ public function getEnumType()
+ {
+ if ($this->getType() == GPBType::ENUM) {
+ return $this->getPublicDescriptor($this->internal_desc->getEnumType());
+ } else {
+ throw new \Exception("Cannot get enum type for non-enum field '" . $this->getName() . "'");
+ }
+ }
+
+ /**
+ * @return boolean
+ */
+ public function isMap()
+ {
+ return $this->internal_desc->isMap();
+ }
+}
diff --git a/php/src/Google/Protobuf/Internal/Descriptor.php b/php/src/Google/Protobuf/Internal/Descriptor.php
index 44225ad276..ee3a8bdec5 100644
--- a/php/src/Google/Protobuf/Internal/Descriptor.php
+++ b/php/src/Google/Protobuf/Internal/Descriptor.php
@@ -34,17 +34,24 @@ namespace Google\Protobuf\Internal;
class Descriptor
{
+ use HasPublicDescriptorTrait;
private $full_name;
private $field = [];
private $json_to_field = [];
private $name_to_field = [];
+ private $index_to_field = [];
private $nested_type = [];
private $enum_type = [];
private $klass;
private $options;
private $oneof_decl = [];
+ public function __construct()
+ {
+ $this->public_desc = new \Google\Protobuf\Descriptor($this);
+ }
+
public function addOneofDecl($oneof)
{
$this->oneof_decl[] = $oneof;
@@ -70,6 +77,7 @@ class Descriptor
$this->field[$field->getNumber()] = $field;
$this->json_to_field[$field->getJsonName()] = $field;
$this->name_to_field[$field->getName()] = $field;
+ $this->index_to_field[] = $field;
}
public function getField()
@@ -124,6 +132,15 @@ class Descriptor
}
}
+ public function getFieldByIndex($index)
+ {
+ if (count($this->index_to_field) <= $index) {
+ return NULL;
+ } else {
+ return $this->index_to_field[$index];
+ }
+ }
+
public function setClass($klass)
{
$this->klass = $klass;
@@ -179,9 +196,11 @@ class Descriptor
}
// Handle oneof fields.
+ $index = 0;
foreach ($proto->getOneofDecl() as $oneof_proto) {
$desc->addOneofDecl(
- OneofDescriptor::buildFromProto($oneof_proto, $desc));
+ OneofDescriptor::buildFromProto($oneof_proto, $desc, $index));
+ $index++;
}
return $desc;
diff --git a/php/src/Google/Protobuf/Internal/EnumBuilderContext.php b/php/src/Google/Protobuf/Internal/EnumBuilderContext.php
index c1dac24dd8..08397284e9 100644
--- a/php/src/Google/Protobuf/Internal/EnumBuilderContext.php
+++ b/php/src/Google/Protobuf/Internal/EnumBuilderContext.php
@@ -33,7 +33,7 @@
namespace Google\Protobuf\Internal;
use Google\Protobuf\Internal\EnumDescriptor;
-use Google\Protobuf\Internal\EnumValueDescriptor;
+use Google\Protobuf\EnumValueDescriptor;
class EnumBuilderContext
{
@@ -51,7 +51,7 @@ class EnumBuilderContext
public function value($name, $number)
{
- $value = new EnumValueDescriptor();
+ $value = new EnumValueDescriptor($name, $number);
$this->descriptor->addValue($number, $value);
return $this;
}
diff --git a/php/src/Google/Protobuf/Internal/EnumDescriptor.php b/php/src/Google/Protobuf/Internal/EnumDescriptor.php
index 33a55a4a6c..01649fec4f 100644
--- a/php/src/Google/Protobuf/Internal/EnumDescriptor.php
+++ b/php/src/Google/Protobuf/Internal/EnumDescriptor.php
@@ -2,13 +2,22 @@
namespace Google\Protobuf\Internal;
+use Google\Protobuf\EnumValueDescriptor;
+
class EnumDescriptor
{
+ use HasPublicDescriptorTrait;
private $klass;
private $full_name;
private $value;
private $name_to_value;
+ private $value_descriptor = [];
+
+ public function __construct()
+ {
+ $this->public_desc = new \Google\Protobuf\EnumDescriptor($this);
+ }
public function setFullName($full_name)
{
@@ -24,6 +33,7 @@ class EnumDescriptor
{
$this->value[$number] = $value;
$this->name_to_value[$value->getName()] = $value;
+ $this->value_descriptor[] = new EnumValueDescriptor($value->getName(), $number);
}
public function getValueByNumber($number)
@@ -36,6 +46,16 @@ class EnumDescriptor
return $this->name_to_value[$name];
}
+ public function getValueDescriptorByIndex($index)
+ {
+ return $this->value_descriptor[$index];
+ }
+
+ public function getValueCount()
+ {
+ return count($this->value);
+ }
+
public function setClass($klass)
{
$this->klass = $klass;
diff --git a/php/src/Google/Protobuf/Internal/FieldDescriptor.php b/php/src/Google/Protobuf/Internal/FieldDescriptor.php
index f18bf810af..1443c6fd0b 100644
--- a/php/src/Google/Protobuf/Internal/FieldDescriptor.php
+++ b/php/src/Google/Protobuf/Internal/FieldDescriptor.php
@@ -34,6 +34,7 @@ namespace Google\Protobuf\Internal;
class FieldDescriptor
{
+ use HasPublicDescriptorTrait;
private $name;
private $json_name;
@@ -48,6 +49,11 @@ class FieldDescriptor
private $is_map;
private $oneof_index = -1;
+ public function __construct()
+ {
+ $this->public_desc = new \Google\Protobuf\FieldDescriptor($this);
+ }
+
public function setOneofIndex($index)
{
$this->oneof_index = $index;
diff --git a/php/src/Google/Protobuf/Internal/GetPublicDescriptorTrait.php b/php/src/Google/Protobuf/Internal/GetPublicDescriptorTrait.php
new file mode 100644
index 0000000000..d22bc305b2
--- /dev/null
+++ b/php/src/Google/Protobuf/Internal/GetPublicDescriptorTrait.php
@@ -0,0 +1,41 @@
+getPublicDescriptor();
+ }
+}
diff --git a/php/src/Google/Protobuf/Internal/HasPublicDescriptorTrait.php b/php/src/Google/Protobuf/Internal/HasPublicDescriptorTrait.php
new file mode 100644
index 0000000000..ed5d1660ba
--- /dev/null
+++ b/php/src/Google/Protobuf/Internal/HasPublicDescriptorTrait.php
@@ -0,0 +1,43 @@
+public_desc;
+ }
+}
diff --git a/php/src/Google/Protobuf/Internal/OneofDescriptor.php b/php/src/Google/Protobuf/Internal/OneofDescriptor.php
index 57961f394d..67b107f6a4 100644
--- a/php/src/Google/Protobuf/Internal/OneofDescriptor.php
+++ b/php/src/Google/Protobuf/Internal/OneofDescriptor.php
@@ -34,10 +34,16 @@ namespace Google\Protobuf\Internal;
class OneofDescriptor
{
+ use HasPublicDescriptorTrait;
private $name;
private $fields;
+ public function __construct()
+ {
+ $this->public_desc = new \Google\Protobuf\OneofDescriptor($this);
+ }
+
public function setName($name)
{
$this->name = $name;
@@ -48,7 +54,7 @@ class OneofDescriptor
return $this->name;
}
- public function addField(Descriptor $field)
+ public function addField(FieldDescriptor $field)
{
$this->fields[] = $field;
}
@@ -58,10 +64,15 @@ class OneofDescriptor
return $this->fields;
}
- public static function buildFromProto($oneof_proto)
+ public static function buildFromProto($oneof_proto, $desc, $index)
{
$oneof = new OneofDescriptor();
$oneof->setName($oneof_proto->getName());
+ foreach ($desc->getField() as $field) {
+ if ($field->getOneofIndex() == $index) {
+ $oneof->addField($field);
+ }
+ }
return $oneof;
}
}
diff --git a/php/src/Google/Protobuf/OneofDescriptor.php b/php/src/Google/Protobuf/OneofDescriptor.php
new file mode 100644
index 0000000000..d9736634e3
--- /dev/null
+++ b/php/src/Google/Protobuf/OneofDescriptor.php
@@ -0,0 +1,75 @@
+internal_desc = $internal_desc;
+ }
+
+ /**
+ * @return string The name of the oneof
+ */
+ public function getName()
+ {
+ return $this->internal_desc->getName();
+ }
+
+ /**
+ * @param int $index Must be >= 0 and < getFieldCount()
+ * @return FieldDescriptor
+ */
+ public function getField($index)
+ {
+ return $this->getPublicDescriptor($this->internal_desc->getFields()[$index]);
+ }
+
+ /**
+ * @return int Number of fields in the oneof
+ */
+ public function getFieldCount()
+ {
+ return count($this->internal_desc->getFields());
+ }
+}