Unverified Commit ce044817 authored by Paul Yang's avatar Paul Yang Committed by GitHub

Use legacy name in php runtime (#4741)

* Use legacy name in php runtime

Old generated code cannot work with new runtime, because the new runtime
assumes new class name for nested message. For details see #4738.

* Remove unused method
parent d6353b48
...@@ -44,6 +44,7 @@ class Descriptor ...@@ -44,6 +44,7 @@ class Descriptor
private $nested_type = []; private $nested_type = [];
private $enum_type = []; private $enum_type = [];
private $klass; private $klass;
private $legacy_klass;
private $options; private $options;
private $oneof_decl = []; private $oneof_decl = [];
...@@ -151,6 +152,16 @@ class Descriptor ...@@ -151,6 +152,16 @@ class Descriptor
return $this->klass; return $this->klass;
} }
public function setLegacyClass($klass)
{
$this->legacy_klass = $klass;
}
public function getLegacyClass()
{
return $this->legacy_klass;
}
public function setOptions($options) public function setOptions($options)
{ {
$this->options = $options; $this->options = $options;
...@@ -167,16 +178,19 @@ class Descriptor ...@@ -167,16 +178,19 @@ class Descriptor
$message_name_without_package = ""; $message_name_without_package = "";
$classname = ""; $classname = "";
$legacy_classname = "";
$fullname = ""; $fullname = "";
GPBUtil::getFullClassName( GPBUtil::getFullClassName(
$proto, $proto,
$containing, $containing,
$file_proto, $file_proto,
$message_name_without_package, $message_name_without_package,
$legacy_classname,
$classname, $classname,
$fullname); $fullname);
$desc->setFullName($fullname); $desc->setFullName($fullname);
$desc->setClass($classname); $desc->setClass($classname);
$desc->setLegacyClass($legacy_classname);
$desc->setOptions($proto->getOptions()); $desc->setOptions($proto->getOptions());
foreach ($proto->getField() as $field_proto) { foreach ($proto->getField() as $field_proto) {
......
...@@ -92,6 +92,7 @@ class DescriptorPool ...@@ -92,6 +92,7 @@ class DescriptorPool
$this->proto_to_class[$descriptor->getFullName()] = $this->proto_to_class[$descriptor->getFullName()] =
$descriptor->getClass(); $descriptor->getClass();
$this->class_to_desc[$descriptor->getClass()] = $descriptor; $this->class_to_desc[$descriptor->getClass()] = $descriptor;
$this->class_to_desc[$descriptor->getLegacyClass()] = $descriptor;
foreach ($descriptor->getNestedType() as $nested_type) { foreach ($descriptor->getNestedType() as $nested_type) {
$this->addDescriptor($nested_type); $this->addDescriptor($nested_type);
} }
...@@ -105,6 +106,7 @@ class DescriptorPool ...@@ -105,6 +106,7 @@ class DescriptorPool
$this->proto_to_class[$descriptor->getFullName()] = $this->proto_to_class[$descriptor->getFullName()] =
$descriptor->getClass(); $descriptor->getClass();
$this->class_to_enum_desc[$descriptor->getClass()] = $descriptor; $this->class_to_enum_desc[$descriptor->getClass()] = $descriptor;
$this->class_to_enum_desc[$descriptor->getLegacyClass()] = $descriptor;
} }
public function getDescriptorByClassName($klass) public function getDescriptorByClassName($klass)
......
...@@ -9,6 +9,7 @@ class EnumDescriptor ...@@ -9,6 +9,7 @@ class EnumDescriptor
use HasPublicDescriptorTrait; use HasPublicDescriptorTrait;
private $klass; private $klass;
private $legacy_klass;
private $full_name; private $full_name;
private $value; private $value;
private $name_to_value; private $name_to_value;
...@@ -66,12 +67,23 @@ class EnumDescriptor ...@@ -66,12 +67,23 @@ class EnumDescriptor
return $this->klass; return $this->klass;
} }
public function setLegacyClass($klass)
{
$this->legacy_klass = $klass;
}
public function getLegacyClass()
{
return $this->legacy_klass;
}
public static function buildFromProto($proto, $file_proto, $containing) public static function buildFromProto($proto, $file_proto, $containing)
{ {
$desc = new EnumDescriptor(); $desc = new EnumDescriptor();
$enum_name_without_package = ""; $enum_name_without_package = "";
$classname = ""; $classname = "";
$legacy_classname = "";
$fullname = ""; $fullname = "";
GPBUtil::getFullClassName( GPBUtil::getFullClassName(
$proto, $proto,
...@@ -79,9 +91,11 @@ class EnumDescriptor ...@@ -79,9 +91,11 @@ class EnumDescriptor
$file_proto, $file_proto,
$enum_name_without_package, $enum_name_without_package,
$classname, $classname,
$legacy_classname,
$fullname); $fullname);
$desc->setFullName($fullname); $desc->setFullName($fullname);
$desc->setClass($classname); $desc->setClass($classname);
$desc->setLegacyClass($legacy_classname);
$values = $proto->getValue(); $values = $proto->getValue();
foreach ($values as $value) { foreach ($values as $value) {
$desc->addValue($value->getNumber(), $value); $desc->addValue($value->getNumber(), $value);
......
...@@ -215,9 +215,10 @@ class GPBUtil ...@@ -215,9 +215,10 @@ class GPBUtil
"Expect repeated field of different type."); "Expect repeated field of different type.");
} }
if ($var->getType() === GPBType::MESSAGE && if ($var->getType() === GPBType::MESSAGE &&
$var->getClass() !== $klass) { $var->getClass() !== $klass &&
$var->getLegacyClass() !== $klass) {
throw new \Exception( throw new \Exception(
"Expect repeated field of different message."); "Expect repeated field of " . $klass . ".");
} }
return $var; return $var;
} }
...@@ -242,9 +243,10 @@ class GPBUtil ...@@ -242,9 +243,10 @@ class GPBUtil
throw new \Exception("Expect map field of value type."); throw new \Exception("Expect map field of value type.");
} }
if ($var->getValueType() === GPBType::MESSAGE && if ($var->getValueType() === GPBType::MESSAGE &&
$var->getValueClass() !== $klass) { $var->getValueClass() !== $klass &&
$var->getLegacyValueClass() !== $klass) {
throw new \Exception( throw new \Exception(
"Expect map field of different value message."); "Expect map field of " . $klass . ".");
} }
return $var; return $var;
} }
...@@ -299,6 +301,14 @@ class GPBUtil ...@@ -299,6 +301,14 @@ class GPBUtil
return ""; return "";
} }
public static function getLegacyClassNameWithoutPackage(
$name,
$file_proto)
{
$classname = implode('_', explode('.', $name));
return static::getClassNamePrefix($classname, $file_proto) . $classname;
}
public static function getClassNameWithoutPackage( public static function getClassNameWithoutPackage(
$name, $name,
$file_proto) $file_proto)
...@@ -316,6 +326,7 @@ class GPBUtil ...@@ -316,6 +326,7 @@ class GPBUtil
$file_proto, $file_proto,
&$message_name_without_package, &$message_name_without_package,
&$classname, &$classname,
&$legacy_classname,
&$fullname) &$fullname)
{ {
// Full name needs to start with '.'. // Full name needs to start with '.'.
...@@ -334,21 +345,28 @@ class GPBUtil ...@@ -334,21 +345,28 @@ class GPBUtil
$class_name_without_package = $class_name_without_package =
static::getClassNameWithoutPackage($message_name_without_package, $file_proto); static::getClassNameWithoutPackage($message_name_without_package, $file_proto);
$legacy_class_name_without_package =
static::getLegacyClassNameWithoutPackage(
$message_name_without_package, $file_proto);
$option = $file_proto->getOptions(); $option = $file_proto->getOptions();
if (!is_null($option) && $option->hasPhpNamespace()) { if (!is_null($option) && $option->hasPhpNamespace()) {
$namespace = $option->getPhpNamespace(); $namespace = $option->getPhpNamespace();
if ($namespace !== "") { if ($namespace !== "") {
$classname = $namespace . "\\" . $class_name_without_package; $classname = $namespace . "\\" . $class_name_without_package;
$legacy_classname =
$namespace . "\\" . $legacy_class_name_without_package;
return; return;
} else { } else {
$classname = $class_name_without_package; $classname = $class_name_without_package;
$legacy_classname = $legacy_class_name_without_package;
return; return;
} }
} }
if ($package === "") { if ($package === "") {
$classname = $class_name_without_package; $classname = $class_name_without_package;
$legacy_classname = $legacy_class_name_without_package;
} else { } else {
$parts = array_map('ucwords', explode('.', $package)); $parts = array_map('ucwords', explode('.', $package));
foreach ($parts as $i => $part) { foreach ($parts as $i => $part) {
...@@ -358,6 +376,9 @@ class GPBUtil ...@@ -358,6 +376,9 @@ class GPBUtil
implode('\\', $parts) . implode('\\', $parts) .
"\\".self::getClassNamePrefix($class_name_without_package,$file_proto). "\\".self::getClassNamePrefix($class_name_without_package,$file_proto).
$class_name_without_package; $class_name_without_package;
$legacy_classname =
implode('\\', array_map('ucwords', explode('.', $package))).
"\\".$legacy_class_name_without_package;
} }
} }
......
...@@ -58,7 +58,11 @@ class MapField implements \ArrayAccess, \IteratorAggregate, \Countable ...@@ -58,7 +58,11 @@ class MapField implements \ArrayAccess, \IteratorAggregate, \Countable
/** /**
* @ignore * @ignore
*/ */
private $value_klass; private $klass;
/**
* @ignore
*/
private $legacy_klass;
/** /**
* Constructs an instance of MapField. * Constructs an instance of MapField.
...@@ -75,6 +79,17 @@ class MapField implements \ArrayAccess, \IteratorAggregate, \Countable ...@@ -75,6 +79,17 @@ class MapField implements \ArrayAccess, \IteratorAggregate, \Countable
$this->key_type = $key_type; $this->key_type = $key_type;
$this->value_type = $value_type; $this->value_type = $value_type;
$this->klass = $klass; $this->klass = $klass;
if ($this->value_type == GPBType::MESSAGE) {
$pool = DescriptorPool::getGeneratedPool();
$desc = $pool->getDescriptorByClassName($klass);
if ($desc == NULL) {
new $klass; // No msg class instance has been created before.
$desc = $pool->getDescriptorByClassName($klass);
}
$this->klass = $desc->getClass();
$this->legacy_klass = $desc->getLegacyClass();
}
} }
/** /**
...@@ -101,6 +116,14 @@ class MapField implements \ArrayAccess, \IteratorAggregate, \Countable ...@@ -101,6 +116,14 @@ class MapField implements \ArrayAccess, \IteratorAggregate, \Countable
return $this->klass; return $this->klass;
} }
/**
* @ignore
*/
public function getLegacyValueClass()
{
return $this->legacy_klass;
}
/** /**
* Return the element at the given key. * Return the element at the given key.
* *
......
...@@ -59,6 +59,10 @@ class RepeatedField implements \ArrayAccess, \IteratorAggregate, \Countable ...@@ -59,6 +59,10 @@ class RepeatedField implements \ArrayAccess, \IteratorAggregate, \Countable
* @ignore * @ignore
*/ */
private $klass; private $klass;
/**
* @ignore
*/
private $legacy_klass;
/** /**
* Constructs an instance of RepeatedField. * Constructs an instance of RepeatedField.
...@@ -71,7 +75,16 @@ class RepeatedField implements \ArrayAccess, \IteratorAggregate, \Countable ...@@ -71,7 +75,16 @@ class RepeatedField implements \ArrayAccess, \IteratorAggregate, \Countable
{ {
$this->container = []; $this->container = [];
$this->type = $type; $this->type = $type;
$this->klass = $klass; if ($this->type == GPBType::MESSAGE) {
$pool = DescriptorPool::getGeneratedPool();
$desc = $pool->getDescriptorByClassName($klass);
if ($desc == NULL) {
new $klass; // No msg class instance has been created before.
$desc = $pool->getDescriptorByClassName($klass);
}
$this->klass = $desc->getClass();
$this->legacy_klass = $desc->getLegacyClass();
}
} }
/** /**
...@@ -90,6 +103,14 @@ class RepeatedField implements \ArrayAccess, \IteratorAggregate, \Countable ...@@ -90,6 +103,14 @@ class RepeatedField implements \ArrayAccess, \IteratorAggregate, \Countable
return $this->klass; return $this->klass;
} }
/**
* @ignore
*/
public function getLegacyClass()
{
return $this->legacy_klass;
}
/** /**
* Return the element at the given index. * Return the element at the given index.
* *
......
...@@ -2,12 +2,14 @@ ...@@ -2,12 +2,14 @@
function use_php() { function use_php() {
VERSION=$1 VERSION=$1
PHP=`which php`
PHP_CONFIG=`which php-config` OLD_PATH=$PATH
PHPIZE=`which phpize` OLD_CPLUS_INCLUDE_PATH=$CPLUS_INCLUDE_PATH
ln -sfn "/usr/local/php-${VERSION}/bin/php" $PHP OLD_C_INCLUDE_PATH=$C_INCLUDE_PATH
ln -sfn "/usr/local/php-${VERSION}/bin/php-config" $PHP_CONFIG
ln -sfn "/usr/local/php-${VERSION}/bin/phpize" $PHPIZE export PATH=/usr/local/php-${VERSION}/bin:$OLD_PATH
export CPLUS_INCLUDE_PATH=/usr/local/php-${VERSION}/include/php/main:/usr/local/php-${VERSION}/include/php/:$OLD_CPLUS_INCLUDE_PATH
export C_INCLUDE_PATH=/usr/local/php-${VERSION}/include/php/main:/usr/local/php-${VERSION}/include/php/:$OLD_C_INCLUDE_PATH
} }
function generate_proto() { function generate_proto() {
...@@ -18,7 +20,22 @@ function generate_proto() { ...@@ -18,7 +20,22 @@ function generate_proto() {
mkdir generated mkdir generated
$PROTOC1 --php_out=generated proto/test_include.proto $PROTOC1 --php_out=generated proto/test_include.proto
$PROTOC2 --php_out=generated proto/test.proto proto/test_no_namespace.proto proto/test_prefix.proto $PROTOC2 --php_out=generated \
proto/test.proto \
proto/test_no_namespace.proto \
proto/test_prefix.proto \
proto/test_php_namespace.proto \
proto/test_empty_php_namespace.proto \
proto/test_reserved_enum_lower.proto \
proto/test_reserved_enum_upper.proto \
proto/test_reserved_enum_value_lower.proto \
proto/test_reserved_enum_value_upper.proto \
proto/test_reserved_message_lower.proto \
proto/test_reserved_message_upper.proto \
proto/test_service.proto \
proto/test_service_namespace.proto \
proto/test_descriptors.proto
pushd ../../src pushd ../../src
$PROTOC2 --php_out=../php/tests/generated -I../php/tests -I. ../php/tests/proto/test_import_descriptor_proto.proto $PROTOC2 --php_out=../php/tests/generated -I../php/tests -I. ../php/tests/proto/test_import_descriptor_proto.proto
popd popd
...@@ -52,9 +69,9 @@ cd $(dirname $0) ...@@ -52,9 +69,9 @@ cd $(dirname $0)
# The old version of protobuf that we are testing compatibility against. # The old version of protobuf that we are testing compatibility against.
case "$1" in case "$1" in
""|3.3.0) ""|3.5.0)
OLD_VERSION=3.3.0 OLD_VERSION=3.5.0
OLD_VERSION_PROTOC=http://repo1.maven.org/maven2/com/google/protobuf/protoc/3.3.0/protoc-3.3.0-linux-x86_64.exe OLD_VERSION_PROTOC=http://repo1.maven.org/maven2/com/google/protobuf/protoc/$OLD_VERSION/protoc-$OLD_VERSION-linux-x86_64.exe
;; ;;
*) *)
echo "[ERROR]: Unknown version number: $1" echo "[ERROR]: Unknown version number: $1"
...@@ -81,7 +98,7 @@ git checkout v$OLD_VERSION ...@@ -81,7 +98,7 @@ git checkout v$OLD_VERSION
popd popd
# Build and copy the new runtime # Build and copy the new runtime
use_php 5.5 use_php 7.1
pushd ../ext/google/protobuf pushd ../ext/google/protobuf
make clean || true make clean || true
phpize && ./configure && make phpize && ./configure && make
...@@ -99,12 +116,12 @@ chmod +x old_protoc ...@@ -99,12 +116,12 @@ chmod +x old_protoc
NEW_PROTOC=`pwd`/../../src/protoc NEW_PROTOC=`pwd`/../../src/protoc
OLD_PROTOC=`pwd`/old_protoc OLD_PROTOC=`pwd`/old_protoc
cd protobuf/php cd protobuf/php
cp -r /usr/local/vendor-5.5 vendor composer install
wget https://phar.phpunit.de/phpunit-4.8.0.phar -O /usr/bin/phpunit
# Remove implementation detail tests. # Remove implementation detail tests.
tests=( array_test.php encode_decode_test.php generated_class_test.php map_field_test.php well_known_test.php ) tests=( array_test.php encode_decode_test.php generated_class_test.php map_field_test.php well_known_test.php )
sed -i.bak '/php_implementation_test.php/d' phpunit.xml sed -i.bak '/php_implementation_test.php/d' phpunit.xml
sed -i.bak '/generated_phpdoc_test.php/d' phpunit.xml
for t in "${tests[@]}" for t in "${tests[@]}"
do do
remove_error_test tests/$t remove_error_test tests/$t
...@@ -118,7 +135,7 @@ cd tests ...@@ -118,7 +135,7 @@ cd tests
generate_proto $OLD_PROTOC $OLD_PROTOC generate_proto $OLD_PROTOC $OLD_PROTOC
./test.sh ./test.sh
pushd .. pushd ..
phpunit ./vendor/bin/phpunit
popd popd
# Test A.2: # Test A.2:
...@@ -127,7 +144,7 @@ popd ...@@ -127,7 +144,7 @@ popd
generate_proto $NEW_PROTOC $OLD_PROTOC generate_proto $NEW_PROTOC $OLD_PROTOC
./test.sh ./test.sh
pushd .. pushd ..
phpunit ./vendor/bin/phpunit
popd popd
# Test A.3: # Test A.3:
...@@ -136,5 +153,5 @@ popd ...@@ -136,5 +153,5 @@ popd
generate_proto $OLD_PROTOC $NEW_PROTOC generate_proto $OLD_PROTOC $NEW_PROTOC
./test.sh ./test.sh
pushd .. pushd ..
phpunit ./vendor/bin/phpunit
popd popd
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment