diff options
author | michaelbausor <michaelbausor@google.com> | 2018-11-28 16:44:53 -0800 |
---|---|---|
committer | Paul Yang <TeBoring@users.noreply.github.com> | 2018-11-28 16:44:53 -0800 |
commit | 0b9af83daeac04a6e8afa17343f7717c09239add (patch) | |
tree | e254dc6bcf0bdcb7f7340331e6cf58a0da7bfdec /php | |
parent | bfdc2ba0ee776db8fb502d9efa42cd696f765496 (diff) | |
download | protobuf-0b9af83daeac04a6e8afa17343f7717c09239add.tar.gz |
PHP: Add Enum methods for converting to/from strings (#5342)
* adds string-to-int and int-to-string methods to enums
* remove check for valueToName property in EnumTrait
* Remove unused imports
* Update to avoid using EnumTrait
* Remove EnumTrait
* Update enum types
* Move name and value methods into generated classes
* Remove functions from GPBUtil
* Test well known enums
* Implement enum value to/from name in c extension
* Only generate use statement when namespace is present
Diffstat (limited to 'php')
-rw-r--r-- | php/ext/google/protobuf/message.c | 224 | ||||
-rw-r--r-- | php/ext/google/protobuf/protobuf.h | 12 | ||||
-rw-r--r-- | php/src/Google/Protobuf/Field/Cardinality.php | 28 | ||||
-rw-r--r-- | php/src/Google/Protobuf/Field/Kind.php | 43 | ||||
-rw-r--r-- | php/src/Google/Protobuf/Internal/FieldDescriptorProto/Label.php | 27 | ||||
-rw-r--r-- | php/src/Google/Protobuf/Internal/FieldDescriptorProto/Type.php | 42 | ||||
-rw-r--r-- | php/src/Google/Protobuf/Internal/FieldOptions/CType.php | 27 | ||||
-rw-r--r-- | php/src/Google/Protobuf/Internal/FieldOptions/JSType.php | 27 | ||||
-rw-r--r-- | php/src/Google/Protobuf/Internal/FileOptions/OptimizeMode.php | 27 | ||||
-rw-r--r-- | php/src/Google/Protobuf/Internal/MethodOptions/IdempotencyLevel.php | 27 | ||||
-rw-r--r-- | php/src/Google/Protobuf/NullValue.php | 25 | ||||
-rw-r--r-- | php/src/Google/Protobuf/Syntax.php | 26 | ||||
-rw-r--r-- | php/tests/generated_class_test.php | 22 | ||||
-rw-r--r-- | php/tests/well_known_test.php | 23 |
14 files changed, 580 insertions, 0 deletions
diff --git a/php/ext/google/protobuf/message.c b/php/ext/google/protobuf/message.c index b99ca5b79..284332164 100644 --- a/php/ext/google/protobuf/message.c +++ b/php/ext/google/protobuf/message.c @@ -862,6 +862,8 @@ static void init_file_wrappers(TSRMLS_D) { // ----------------------------------------------------------------------------- static zend_function_entry field_cardinality_methods[] = { + PHP_ME(Field_Cardinality, name, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) + PHP_ME(Field_Cardinality, value, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) {NULL, NULL, NULL} }; @@ -886,11 +888,60 @@ PHP_PROTO_INIT_ENUMCLASS_START("Google\\Protobuf\\Field\\Cardinality", #endif PHP_PROTO_INIT_ENUMCLASS_END +PHP_METHOD(Field_Cardinality, name) { + PHP_PROTO_LONG value; + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &value) == + FAILURE) { + return; + } + switch (value) { + case 0: + PHP_PROTO_RETURN_STRING("CARDINALITY_UNKNOWN", 1); + case 1: + PHP_PROTO_RETURN_STRING("CARDINALITY_OPTIONAL", 1); + case 2: + PHP_PROTO_RETURN_STRING("CARDINALITY_REQUIRED", 1); + case 3: + PHP_PROTO_RETURN_STRING("CARDINALITY_REPEATED", 1); + default: + zend_throw_exception( + NULL, + "Enum Google\\Protobuf\\Field_Cardinality has no name " + "defined for value %d.", + value, + 0 TSRMLS_CC); + } +} + +PHP_METHOD(Field_Cardinality, value) { + char *name = NULL; + PHP_PROTO_SIZE name_len; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name, &name_len) == + FAILURE) { + return; + } + + if (strncmp(name, "CARDINALITY_UNKNOWN", name_len) == 0) RETURN_LONG(0); + if (strncmp(name, "CARDINALITY_OPTIONAL", name_len) == 0) RETURN_LONG(1); + if (strncmp(name, "CARDINALITY_REQUIRED", name_len) == 0) RETURN_LONG(2); + if (strncmp(name, "CARDINALITY_REPEATED", name_len) == 0) RETURN_LONG(3); + + zend_throw_exception( + NULL, + "Enum Google\\Protobuf\\Field_Cardinality has no value " + "defined for name %s.", + name, + 0 TSRMLS_CC); +} + // ----------------------------------------------------------------------------- // Field_Kind // ----------------------------------------------------------------------------- static zend_function_entry field_kind_methods[] = { + PHP_ME(Field_Kind, name, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) + PHP_ME(Field_Kind, value, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) {NULL, NULL, NULL} }; @@ -945,11 +996,105 @@ PHP_PROTO_INIT_ENUMCLASS_START("Google\\Protobuf\\Field\\Kind", #endif PHP_PROTO_INIT_ENUMCLASS_END +PHP_METHOD(Field_Kind, name) { + PHP_PROTO_LONG value; + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &value) == + FAILURE) { + return; + } + switch (value) { + case 0: + PHP_PROTO_RETURN_STRING("TYPE_UNKNOWN", 1); + case 1: + PHP_PROTO_RETURN_STRING("TYPE_DOUBLE", 1); + case 2: + PHP_PROTO_RETURN_STRING("TYPE_FLOAT", 1); + case 3: + PHP_PROTO_RETURN_STRING("TYPE_INT64", 1); + case 4: + PHP_PROTO_RETURN_STRING("TYPE_UINT64", 1); + case 5: + PHP_PROTO_RETURN_STRING("TYPE_INT32", 1); + case 6: + PHP_PROTO_RETURN_STRING("TYPE_FIXED64", 1); + case 7: + PHP_PROTO_RETURN_STRING("TYPE_FIXED32", 1); + case 8: + PHP_PROTO_RETURN_STRING("TYPE_BOOL", 1); + case 9: + PHP_PROTO_RETURN_STRING("TYPE_STRING", 1); + case 10: + PHP_PROTO_RETURN_STRING("TYPE_GROUP", 1); + case 11: + PHP_PROTO_RETURN_STRING("TYPE_MESSAGE", 1); + case 12: + PHP_PROTO_RETURN_STRING("TYPE_BYTES", 1); + case 13: + PHP_PROTO_RETURN_STRING("TYPE_UINT32", 1); + case 14: + PHP_PROTO_RETURN_STRING("TYPE_ENUM", 1); + case 15: + PHP_PROTO_RETURN_STRING("TYPE_SFIXED32", 1); + case 16: + PHP_PROTO_RETURN_STRING("TYPE_SFIXED64", 1); + case 17: + PHP_PROTO_RETURN_STRING("TYPE_SINT32", 1); + case 18: + PHP_PROTO_RETURN_STRING("TYPE_SINT64", 1); + default: + zend_throw_exception( + NULL, + "Enum Google\\Protobuf\\Field_Kind has no name " + "defined for value %d.", + value, + 0 TSRMLS_CC); + } +} + +PHP_METHOD(Field_Kind, value) { + char *name = NULL; + PHP_PROTO_SIZE name_len; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name, &name_len) == + FAILURE) { + return; + } + + if (strncmp(name, "TYPE_UNKNOWN", name_len) == 0) RETURN_LONG(0); + if (strncmp(name, "TYPE_DOUBLE", name_len) == 0) RETURN_LONG(1); + if (strncmp(name, "TYPE_FLOAT", name_len) == 0) RETURN_LONG(2); + if (strncmp(name, "TYPE_INT64", name_len) == 0) RETURN_LONG(3); + if (strncmp(name, "TYPE_UINT64", name_len) == 0) RETURN_LONG(4); + if (strncmp(name, "TYPE_INT32", name_len) == 0) RETURN_LONG(5); + if (strncmp(name, "TYPE_FIXED64", name_len) == 0) RETURN_LONG(6); + if (strncmp(name, "TYPE_FIXED32", name_len) == 0) RETURN_LONG(7); + if (strncmp(name, "TYPE_BOOL", name_len) == 0) RETURN_LONG(8); + if (strncmp(name, "TYPE_STRING", name_len) == 0) RETURN_LONG(9); + if (strncmp(name, "TYPE_GROUP", name_len) == 0) RETURN_LONG(10); + if (strncmp(name, "TYPE_MESSAGE", name_len) == 0) RETURN_LONG(11); + if (strncmp(name, "TYPE_BYTES", name_len) == 0) RETURN_LONG(12); + if (strncmp(name, "TYPE_UINT32", name_len) == 0) RETURN_LONG(13); + if (strncmp(name, "TYPE_ENUM", name_len) == 0) RETURN_LONG(14); + if (strncmp(name, "TYPE_SFIXED32", name_len) == 0) RETURN_LONG(15); + if (strncmp(name, "TYPE_SFIXED64", name_len) == 0) RETURN_LONG(16); + if (strncmp(name, "TYPE_SINT32", name_len) == 0) RETURN_LONG(17); + if (strncmp(name, "TYPE_SINT64", name_len) == 0) RETURN_LONG(18); + + zend_throw_exception( + NULL, + "Enum Google\\Protobuf\\Field_Kind has no value " + "defined for name %s.", + name, + 0 TSRMLS_CC); +} + // ----------------------------------------------------------------------------- // NullValue // ----------------------------------------------------------------------------- static zend_function_entry null_value_methods[] = { + PHP_ME(NullValue, name, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) + PHP_ME(NullValue, value, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) {NULL, NULL, NULL} }; @@ -962,11 +1107,51 @@ PHP_PROTO_INIT_ENUMCLASS_START("Google\\Protobuf\\NullValue", "NULL_VALUE", 10, 0 TSRMLS_CC); PHP_PROTO_INIT_ENUMCLASS_END +PHP_METHOD(NullValue, name) { + PHP_PROTO_LONG value; + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &value) == + FAILURE) { + return; + } + switch (value) { + case 0: + PHP_PROTO_RETURN_STRING("NULL_VALUE", 1); + default: + zend_throw_exception( + NULL, + "Enum Google\\Protobuf\\NullValue has no name " + "defined for value %d.", + value, + 0 TSRMLS_CC); + } +} + +PHP_METHOD(NullValue, value) { + char *name = NULL; + PHP_PROTO_SIZE name_len; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name, &name_len) == + FAILURE) { + return; + } + + if (strncmp(name, "NULL_VALUE", name_len) == 0) RETURN_LONG(0); + + zend_throw_exception( + NULL, + "Enum Google\\Protobuf\\NullValue has no value " + "defined for name %s.", + name, + 0 TSRMLS_CC); +} + // ----------------------------------------------------------------------------- // Syntax // ----------------------------------------------------------------------------- static zend_function_entry syntax_methods[] = { + PHP_ME(Syntax, name, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) + PHP_ME(Syntax, value, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) {NULL, NULL, NULL} }; @@ -981,7 +1166,46 @@ PHP_PROTO_INIT_ENUMCLASS_START("Google\\Protobuf\\Syntax", "SYNTAX_PROTO3", 13, 1 TSRMLS_CC); PHP_PROTO_INIT_ENUMCLASS_END +PHP_METHOD(Syntax, name) { + PHP_PROTO_LONG value; + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &value) == + FAILURE) { + return; + } + switch (value) { + case 0: + PHP_PROTO_RETURN_STRING("SYNTAX_PROTO2", 1); + case 1: + PHP_PROTO_RETURN_STRING("SYNTAX_PROTO3", 1); + default: + zend_throw_exception( + NULL, + "Enum Google\\Protobuf\\Syntax has no name " + "defined for value %d.", + value, + 0 TSRMLS_CC); + } +} + +PHP_METHOD(Syntax, value) { + char *name = NULL; + PHP_PROTO_SIZE name_len; + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name, &name_len) == + FAILURE) { + return; + } + + if (strncmp(name, "SYNTAX_PROTO2", name_len) == 0) RETURN_LONG(0); + if (strncmp(name, "SYNTAX_PROTO3", name_len) == 0) RETURN_LONG(1); + + zend_throw_exception( + NULL, + "Enum Google\\Protobuf\\Syntax has no value " + "defined for name %s.", + name, + 0 TSRMLS_CC); +} // ----------------------------------------------------------------------------- // Define message diff --git a/php/ext/google/protobuf/protobuf.h b/php/ext/google/protobuf/protobuf.h index a84feec66..0045358a4 100644 --- a/php/ext/google/protobuf/protobuf.h +++ b/php/ext/google/protobuf/protobuf.h @@ -1301,6 +1301,12 @@ PHP_METHOD(Field, setJsonName); PHP_METHOD(Field, getDefaultValue); PHP_METHOD(Field, setDefaultValue); +PHP_METHOD(Field_Cardinality, name); +PHP_METHOD(Field_Cardinality, value); + +PHP_METHOD(Field_Kind, name); +PHP_METHOD(Field_Kind, value); + PHP_METHOD(FloatValue, __construct); PHP_METHOD(FloatValue, getValue); PHP_METHOD(FloatValue, setValue); @@ -1341,6 +1347,9 @@ PHP_METHOD(Mixin, setName); PHP_METHOD(Mixin, getRoot); PHP_METHOD(Mixin, setRoot); +PHP_METHOD(NullValue, name); +PHP_METHOD(NullValue, value); + PHP_METHOD(Option, __construct); PHP_METHOD(Option, getName); PHP_METHOD(Option, setName); @@ -1359,6 +1368,9 @@ PHP_METHOD(Struct, __construct); PHP_METHOD(Struct, getFields); PHP_METHOD(Struct, setFields); +PHP_METHOD(Syntax, name); +PHP_METHOD(Syntax, value); + PHP_METHOD(Type, __construct); PHP_METHOD(Type, getName); PHP_METHOD(Type, setName); diff --git a/php/src/Google/Protobuf/Field/Cardinality.php b/php/src/Google/Protobuf/Field/Cardinality.php index c887f6d31..479dc0bfc 100644 --- a/php/src/Google/Protobuf/Field/Cardinality.php +++ b/php/src/Google/Protobuf/Field/Cardinality.php @@ -4,6 +4,8 @@ namespace Google\Protobuf\Field; +use UnexpectedValueException; + /** * Whether a field is optional, required, or repeated. * @@ -35,6 +37,32 @@ class Cardinality * Generated from protobuf enum <code>CARDINALITY_REPEATED = 3;</code> */ const CARDINALITY_REPEATED = 3; + + private static $valueToName = [ + self::CARDINALITY_UNKNOWN => 'CARDINALITY_UNKNOWN', + self::CARDINALITY_OPTIONAL => 'CARDINALITY_OPTIONAL', + self::CARDINALITY_REQUIRED => 'CARDINALITY_REQUIRED', + self::CARDINALITY_REPEATED => 'CARDINALITY_REPEATED', + ]; + + public static function name($value) + { + if (!isset(self::$valueToName[$value])) { + throw new UnexpectedValueException(sprintf( + 'Enum %s has no name defined for value %s', __CLASS__, $value)); + } + return self::$valueToName[$value]; + } + + public static function value($name) + { + $const = __CLASS__ . '::' . strtoupper($name); + if (!defined($const)) { + throw new UnexpectedValueException(sprintf( + 'Enum %s has no value defined for name %s', __CLASS__, $name)); + } + return constant($const); + } } // Adding a class alias for backwards compatibility with the previous class name. diff --git a/php/src/Google/Protobuf/Field/Kind.php b/php/src/Google/Protobuf/Field/Kind.php index a2bbbdebb..f30bd2f59 100644 --- a/php/src/Google/Protobuf/Field/Kind.php +++ b/php/src/Google/Protobuf/Field/Kind.php @@ -4,6 +4,8 @@ namespace Google\Protobuf\Field; +use UnexpectedValueException; + /** * Basic field types. * @@ -125,6 +127,47 @@ class Kind * Generated from protobuf enum <code>TYPE_SINT64 = 18;</code> */ const TYPE_SINT64 = 18; + + private static $valueToName = [ + self::TYPE_UNKNOWN => 'TYPE_UNKNOWN', + self::TYPE_DOUBLE => 'TYPE_DOUBLE', + self::TYPE_FLOAT => 'TYPE_FLOAT', + self::TYPE_INT64 => 'TYPE_INT64', + self::TYPE_UINT64 => 'TYPE_UINT64', + self::TYPE_INT32 => 'TYPE_INT32', + self::TYPE_FIXED64 => 'TYPE_FIXED64', + self::TYPE_FIXED32 => 'TYPE_FIXED32', + self::TYPE_BOOL => 'TYPE_BOOL', + self::TYPE_STRING => 'TYPE_STRING', + self::TYPE_GROUP => 'TYPE_GROUP', + self::TYPE_MESSAGE => 'TYPE_MESSAGE', + self::TYPE_BYTES => 'TYPE_BYTES', + self::TYPE_UINT32 => 'TYPE_UINT32', + self::TYPE_ENUM => 'TYPE_ENUM', + self::TYPE_SFIXED32 => 'TYPE_SFIXED32', + self::TYPE_SFIXED64 => 'TYPE_SFIXED64', + self::TYPE_SINT32 => 'TYPE_SINT32', + self::TYPE_SINT64 => 'TYPE_SINT64', + ]; + + public static function name($value) + { + if (!isset(self::$valueToName[$value])) { + throw new UnexpectedValueException(sprintf( + 'Enum %s has no name defined for value %s', __CLASS__, $value)); + } + return self::$valueToName[$value]; + } + + public static function value($name) + { + $const = __CLASS__ . '::' . strtoupper($name); + if (!defined($const)) { + throw new UnexpectedValueException(sprintf( + 'Enum %s has no value defined for name %s', __CLASS__, $name)); + } + return constant($const); + } } // Adding a class alias for backwards compatibility with the previous class name. diff --git a/php/src/Google/Protobuf/Internal/FieldDescriptorProto/Label.php b/php/src/Google/Protobuf/Internal/FieldDescriptorProto/Label.php index b105088e6..f10505724 100644 --- a/php/src/Google/Protobuf/Internal/FieldDescriptorProto/Label.php +++ b/php/src/Google/Protobuf/Internal/FieldDescriptorProto/Label.php @@ -4,6 +4,8 @@ namespace Google\Protobuf\Internal\FieldDescriptorProto; +use UnexpectedValueException; + /** * Protobuf type <code>google.protobuf.FieldDescriptorProto.Label</code> */ @@ -23,6 +25,31 @@ class Label * Generated from protobuf enum <code>LABEL_REPEATED = 3;</code> */ const LABEL_REPEATED = 3; + + private static $valueToName = [ + self::LABEL_OPTIONAL => 'LABEL_OPTIONAL', + self::LABEL_REQUIRED => 'LABEL_REQUIRED', + self::LABEL_REPEATED => 'LABEL_REPEATED', + ]; + + public static function name($value) + { + if (!isset(self::$valueToName[$value])) { + throw new UnexpectedValueException(sprintf( + 'Enum %s has no name defined for value %s', __CLASS__, $value)); + } + return self::$valueToName[$value]; + } + + public static function value($name) + { + $const = __CLASS__ . '::' . strtoupper($name); + if (!defined($const)) { + throw new UnexpectedValueException(sprintf( + 'Enum %s has no value defined for name %s', __CLASS__, $name)); + } + return constant($const); + } } // Adding a class alias for backwards compatibility with the previous class name. diff --git a/php/src/Google/Protobuf/Internal/FieldDescriptorProto/Type.php b/php/src/Google/Protobuf/Internal/FieldDescriptorProto/Type.php index ea228a77f..74559978a 100644 --- a/php/src/Google/Protobuf/Internal/FieldDescriptorProto/Type.php +++ b/php/src/Google/Protobuf/Internal/FieldDescriptorProto/Type.php @@ -4,6 +4,8 @@ namespace Google\Protobuf\Internal\FieldDescriptorProto; +use UnexpectedValueException; + /** * Protobuf type <code>google.protobuf.FieldDescriptorProto.Type</code> */ @@ -103,6 +105,46 @@ class Type * Generated from protobuf enum <code>TYPE_SINT64 = 18;</code> */ const TYPE_SINT64 = 18; + + private static $valueToName = [ + self::TYPE_DOUBLE => 'TYPE_DOUBLE', + self::TYPE_FLOAT => 'TYPE_FLOAT', + self::TYPE_INT64 => 'TYPE_INT64', + self::TYPE_UINT64 => 'TYPE_UINT64', + self::TYPE_INT32 => 'TYPE_INT32', + self::TYPE_FIXED64 => 'TYPE_FIXED64', + self::TYPE_FIXED32 => 'TYPE_FIXED32', + self::TYPE_BOOL => 'TYPE_BOOL', + self::TYPE_STRING => 'TYPE_STRING', + self::TYPE_GROUP => 'TYPE_GROUP', + self::TYPE_MESSAGE => 'TYPE_MESSAGE', + self::TYPE_BYTES => 'TYPE_BYTES', + self::TYPE_UINT32 => 'TYPE_UINT32', + self::TYPE_ENUM => 'TYPE_ENUM', + self::TYPE_SFIXED32 => 'TYPE_SFIXED32', + self::TYPE_SFIXED64 => 'TYPE_SFIXED64', + self::TYPE_SINT32 => 'TYPE_SINT32', + self::TYPE_SINT64 => 'TYPE_SINT64', + ]; + + public static function name($value) + { + if (!isset(self::$valueToName[$value])) { + throw new UnexpectedValueException(sprintf( + 'Enum %s has no name defined for value %s', __CLASS__, $value)); + } + return self::$valueToName[$value]; + } + + public static function value($name) + { + $const = __CLASS__ . '::' . strtoupper($name); + if (!defined($const)) { + throw new UnexpectedValueException(sprintf( + 'Enum %s has no value defined for name %s', __CLASS__, $name)); + } + return constant($const); + } } // Adding a class alias for backwards compatibility with the previous class name. diff --git a/php/src/Google/Protobuf/Internal/FieldOptions/CType.php b/php/src/Google/Protobuf/Internal/FieldOptions/CType.php index 016197acb..9043640cb 100644 --- a/php/src/Google/Protobuf/Internal/FieldOptions/CType.php +++ b/php/src/Google/Protobuf/Internal/FieldOptions/CType.php @@ -4,6 +4,8 @@ namespace Google\Protobuf\Internal\FieldOptions; +use UnexpectedValueException; + /** * Protobuf type <code>google.protobuf.FieldOptions.CType</code> */ @@ -23,6 +25,31 @@ class CType * Generated from protobuf enum <code>STRING_PIECE = 2;</code> */ const STRING_PIECE = 2; + + private static $valueToName = [ + self::STRING => 'STRING', + self::CORD => 'CORD', + self::STRING_PIECE => 'STRING_PIECE', + ]; + + public static function name($value) + { + if (!isset(self::$valueToName[$value])) { + throw new UnexpectedValueException(sprintf( + 'Enum %s has no name defined for value %s', __CLASS__, $value)); + } + return self::$valueToName[$value]; + } + + public static function value($name) + { + $const = __CLASS__ . '::' . strtoupper($name); + if (!defined($const)) { + throw new UnexpectedValueException(sprintf( + 'Enum %s has no value defined for name %s', __CLASS__, $name)); + } + return constant($const); + } } // Adding a class alias for backwards compatibility with the previous class name. diff --git a/php/src/Google/Protobuf/Internal/FieldOptions/JSType.php b/php/src/Google/Protobuf/Internal/FieldOptions/JSType.php index f7b78a1b3..5ff81620e 100644 --- a/php/src/Google/Protobuf/Internal/FieldOptions/JSType.php +++ b/php/src/Google/Protobuf/Internal/FieldOptions/JSType.php @@ -4,6 +4,8 @@ namespace Google\Protobuf\Internal\FieldOptions; +use UnexpectedValueException; + /** * Protobuf type <code>google.protobuf.FieldOptions.JSType</code> */ @@ -27,6 +29,31 @@ class JSType * Generated from protobuf enum <code>JS_NUMBER = 2;</code> */ const JS_NUMBER = 2; + + private static $valueToName = [ + self::JS_NORMAL => 'JS_NORMAL', + self::JS_STRING => 'JS_STRING', + self::JS_NUMBER => 'JS_NUMBER', + ]; + + public static function name($value) + { + if (!isset(self::$valueToName[$value])) { + throw new UnexpectedValueException(sprintf( + 'Enum %s has no name defined for value %s', __CLASS__, $value)); + } + return self::$valueToName[$value]; + } + + public static function value($name) + { + $const = __CLASS__ . '::' . strtoupper($name); + if (!defined($const)) { + throw new UnexpectedValueException(sprintf( + 'Enum %s has no value defined for name %s', __CLASS__, $name)); + } + return constant($const); + } } // Adding a class alias for backwards compatibility with the previous class name. diff --git a/php/src/Google/Protobuf/Internal/FileOptions/OptimizeMode.php b/php/src/Google/Protobuf/Internal/FileOptions/OptimizeMode.php index 3dd60bf6e..119b23a90 100644 --- a/php/src/Google/Protobuf/Internal/FileOptions/OptimizeMode.php +++ b/php/src/Google/Protobuf/Internal/FileOptions/OptimizeMode.php @@ -4,6 +4,8 @@ namespace Google\Protobuf\Internal\FileOptions; +use UnexpectedValueException; + /** * Generated classes can be optimized for speed or code size. * @@ -29,6 +31,31 @@ class OptimizeMode * Generated from protobuf enum <code>LITE_RUNTIME = 3;</code> */ const LITE_RUNTIME = 3; + + private static $valueToName = [ + self::SPEED => 'SPEED', + self::CODE_SIZE => 'CODE_SIZE', + self::LITE_RUNTIME => 'LITE_RUNTIME', + ]; + + public static function name($value) + { + if (!isset(self::$valueToName[$value])) { + throw new UnexpectedValueException(sprintf( + 'Enum %s has no name defined for value %s', __CLASS__, $value)); + } + return self::$valueToName[$value]; + } + + public static function value($name) + { + $const = __CLASS__ . '::' . strtoupper($name); + if (!defined($const)) { + throw new UnexpectedValueException(sprintf( + 'Enum %s has no value defined for name %s', __CLASS__, $name)); + } + return constant($const); + } } // Adding a class alias for backwards compatibility with the previous class name. diff --git a/php/src/Google/Protobuf/Internal/MethodOptions/IdempotencyLevel.php b/php/src/Google/Protobuf/Internal/MethodOptions/IdempotencyLevel.php index dcc30e271..ab94458f7 100644 --- a/php/src/Google/Protobuf/Internal/MethodOptions/IdempotencyLevel.php +++ b/php/src/Google/Protobuf/Internal/MethodOptions/IdempotencyLevel.php @@ -4,6 +4,8 @@ namespace Google\Protobuf\Internal\MethodOptions; +use UnexpectedValueException; + /** * Is this method side-effect-free (or safe in HTTP parlance), or idempotent, * or neither? HTTP based RPC implementation may choose GET verb for safe @@ -29,6 +31,31 @@ class IdempotencyLevel * Generated from protobuf enum <code>IDEMPOTENT = 2;</code> */ const IDEMPOTENT = 2; + + private static $valueToName = [ + self::IDEMPOTENCY_UNKNOWN => 'IDEMPOTENCY_UNKNOWN', + self::NO_SIDE_EFFECTS => 'NO_SIDE_EFFECTS', + self::IDEMPOTENT => 'IDEMPOTENT', + ]; + + public static function name($value) + { + if (!isset(self::$valueToName[$value])) { + throw new UnexpectedValueException(sprintf( + 'Enum %s has no name defined for value %s', __CLASS__, $value)); + } + return self::$valueToName[$value]; + } + + public static function value($name) + { + $const = __CLASS__ . '::' . strtoupper($name); + if (!defined($const)) { + throw new UnexpectedValueException(sprintf( + 'Enum %s has no value defined for name %s', __CLASS__, $name)); + } + return constant($const); + } } // Adding a class alias for backwards compatibility with the previous class name. diff --git a/php/src/Google/Protobuf/NullValue.php b/php/src/Google/Protobuf/NullValue.php index 482b80dde..a72cbb2ed 100644 --- a/php/src/Google/Protobuf/NullValue.php +++ b/php/src/Google/Protobuf/NullValue.php @@ -4,6 +4,8 @@ namespace Google\Protobuf; +use UnexpectedValueException; + /** * `NullValue` is a singleton enumeration to represent the null value for the * `Value` type union. @@ -19,5 +21,28 @@ class NullValue * Generated from protobuf enum <code>NULL_VALUE = 0;</code> */ const NULL_VALUE = 0; + + private static $valueToName = [ + self::NULL_VALUE => 'NULL_VALUE', + ]; + + public static function name($value) + { + if (!isset(self::$valueToName[$value])) { + throw new UnexpectedValueException(sprintf( + 'Enum %s has no name defined for value %s', __CLASS__, $value)); + } + return self::$valueToName[$value]; + } + + public static function value($name) + { + $const = __CLASS__ . '::' . strtoupper($name); + if (!defined($const)) { + throw new UnexpectedValueException(sprintf( + 'Enum %s has no value defined for name %s', __CLASS__, $name)); + } + return constant($const); + } } diff --git a/php/src/Google/Protobuf/Syntax.php b/php/src/Google/Protobuf/Syntax.php index 3a52dc9e1..9812669da 100644 --- a/php/src/Google/Protobuf/Syntax.php +++ b/php/src/Google/Protobuf/Syntax.php @@ -4,6 +4,8 @@ namespace Google\Protobuf; +use UnexpectedValueException; + /** * The syntax in which a protocol buffer element is defined. * @@ -23,5 +25,29 @@ class Syntax * Generated from protobuf enum <code>SYNTAX_PROTO3 = 1;</code> */ const SYNTAX_PROTO3 = 1; + + private static $valueToName = [ + self::SYNTAX_PROTO2 => 'SYNTAX_PROTO2', + self::SYNTAX_PROTO3 => 'SYNTAX_PROTO3', + ]; + + public static function name($value) + { + if (!isset(self::$valueToName[$value])) { + throw new UnexpectedValueException(sprintf( + 'Enum %s has no name defined for value %s', __CLASS__, $value)); + } + return self::$valueToName[$value]; + } + + public static function value($name) + { + $const = __CLASS__ . '::' . strtoupper($name); + if (!defined($const)) { + throw new UnexpectedValueException(sprintf( + 'Enum %s has no value defined for name %s', __CLASS__, $name)); + } + return constant($const); + } } diff --git a/php/tests/generated_class_test.php b/php/tests/generated_class_test.php index 8bac4e5eb..96dad228a 100644 --- a/php/tests/generated_class_test.php +++ b/php/tests/generated_class_test.php @@ -232,6 +232,28 @@ class GeneratedClassTest extends TestBase // Set string. $m->setOptionalEnum("1"); $this->assertEquals(TestEnum::ONE, $m->getOptionalEnum()); + + // Test Enum methods + $this->assertEquals('ONE', TestEnum::name(1)); + $this->assertEquals(1, TestEnum::value('ONE')); + } + + /** + * @expectedException UnexpectedValueException + * @expectedExceptionMessage Enum Foo\TestEnum has no name defined for value -1 + */ + public function testInvalidEnumValueThrowsException() + { + TestEnum::name(-1); + } + + /** + * @expectedException UnexpectedValueException + * @expectedExceptionMessage Enum Foo\TestEnum has no value defined for name DOES_NOT_EXIST + */ + public function testInvalidEnumNameThrowsException() + { + TestEnum::value('DOES_NOT_EXIST'); } public function testNestedEnum() diff --git a/php/tests/well_known_test.php b/php/tests/well_known_test.php index 6a788df29..db5d5a7a0 100644 --- a/php/tests/well_known_test.php +++ b/php/tests/well_known_test.php @@ -392,4 +392,27 @@ class WellKnownTest extends TestBase { $m->setValue("a"); $this->assertSame("a", $m->getValue()); } + + /** + * @dataProvider enumNameValueConversionDataProvider + */ + public function testEnumNameValueConversion($class) + { + $reflectionClass = new ReflectionClass($class); + $constants = $reflectionClass->getConstants(); + foreach ($constants as $k => $v) { + $this->assertSame($k, $class::name($v)); + $this->assertSame($v, $class::value($k)); + } + } + + public function enumNameValueConversionDataProvider() + { + return [ + ['\Google\Protobuf\Field\Cardinality'], + ['\Google\Protobuf\Field\Kind'], + ['\Google\Protobuf\NullValue'], + ['\Google\Protobuf\Syntax'], + ]; + } } |