Passes all tests.

pull/7944/head
Joshua Haberman 5 years ago
parent a93d840881
commit cfc0c2b5e0
  1. 21
      php/ext/google/protobuf/def.c
  2. 258
      php/ext/google/protobuf/message.c
  3. 312
      php/ext/google/protobuf/wkt.inc
  4. 11
      php/generate_descriptor_protos.sh
  5. 148
      src/google/protobuf/compiler/php/php_generator.cc

@ -1010,6 +1010,21 @@ static zend_function_entry DescriptorPool_methods[] = {
ZEND_FE_END
};
// -----------------------------------------------------------------------------
// InternalDescriptorPool
// -----------------------------------------------------------------------------
// For the C extension, Google\Protobuf\Internal\DescriptorPool is not a
// separate instantiable object, it just returns a
// Google\Protobuf\DescriptorPool.
zend_class_entry *InternalDescriptorPool_class_entry;
static zend_function_entry InternalDescriptorPool_methods[] = {
PHP_ME(DescriptorPool, getGeneratedPool, NULL,
ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
};
// -----------------------------------------------------------------------------
// GPBType
// -----------------------------------------------------------------------------
@ -1071,7 +1086,7 @@ void Def_ModuleInit() {
h = &FieldDescriptor_object_handlers;
memcpy(h, &std_object_handlers, sizeof(zend_object_handlers));
INIT_CLASS_ENTRY(tmp_ce, "Google\\Protobuf\\Internal\\DescriptorPool",
INIT_CLASS_ENTRY(tmp_ce, "Google\\Protobuf\\DescriptorPool",
DescriptorPool_methods);
DescriptorPool_class_entry = zend_register_internal_class(&tmp_ce);
DescriptorPool_class_entry->ce_flags |= ZEND_ACC_FINAL;
@ -1080,6 +1095,10 @@ void Def_ModuleInit() {
memcpy(h, &std_object_handlers, sizeof(zend_object_handlers));
h->dtor_obj = DescriptorPool_destructor;
INIT_CLASS_ENTRY(tmp_ce, "Google\\Protobuf\\Internal\\DescriptorPool",
InternalDescriptorPool_methods);
InternalDescriptorPool_class_entry = zend_register_internal_class(&tmp_ce);
// GPBType.
#define STR(str) (str), strlen(str)
zend_class_entry class_type;

@ -540,6 +540,12 @@ bool Message_InitFromPhp(upb_msg *msg, const upb_msgdef *m, zval *init,
}
}
static void Message_Initialize(Message *intern, const Descriptor *desc) {
intern->desc = desc;
intern->msg = upb_msg_new(desc->msgdef, Arena_Get(&intern->arena));
ObjCache_Add(intern->msg, &intern->std);
}
/**
* Message::__construct()
*
@ -549,13 +555,10 @@ bool Message_InitFromPhp(upb_msg *msg, const upb_msgdef *m, zval *init,
PHP_METHOD(Message, __construct) {
Message* intern = (Message*)Z_OBJ_P(getThis());
const Descriptor* desc = Descriptor_GetFromClassEntry(Z_OBJCE_P(getThis()));
const upb_msgdef *msgdef = desc->msgdef;
upb_arena *arena = Arena_Get(&intern->arena);
zval *init_arr = NULL;
intern->desc = desc;
intern->msg = upb_msg_new(msgdef, arena);
ObjCache_Add(intern->msg, &intern->std);
Message_Initialize(intern, desc);
if (zend_parse_parameters(ZEND_NUM_ARGS(), "|a!", &init_arr) == FAILURE) {
return;
@ -1024,31 +1027,55 @@ static const char TYPE_URL_PREFIX[] = "type.googleapis.com/";
static upb_msgval Message_getval(Message *intern, const char *field_name) {
const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, field_name);
PBPHP_ASSERT(f);
return upb_msg_get(intern->msg, f);
}
static void Message_setval(Message *intern, const char *field_name,
upb_msgval val) {
const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, field_name);
PBPHP_ASSERT(f);
return upb_msg_set(intern->msg, f, val, Arena_Get(&intern->arena));
}
static upb_msgval StringVal(upb_strview view) {
upb_msgval ret;
ret.str_val = view;
return ret;
}
static bool TryStripUrlPrefix(upb_strview *str) {
size_t size = strlen(TYPE_URL_PREFIX);
if (str->size < size || memcmp(TYPE_URL_PREFIX, str->data, size) != 0) {
return false;
}
str->data += size;
str->size -= size;
return true;
}
static bool StrViewEq(upb_strview view, const char *str) {
size_t size = strlen(str);
return view.size == size && memcmp(view.data, str, size) == 0;
}
PHP_METHOD(google_protobuf_Any, unpack) {
Message* intern = (Message*)Z_OBJ_P(getThis());
upb_strview type_url = Message_getval(intern, "type_url").str_val;
upb_strview value = Message_getval(intern, "value").str_val;
size_t prefix_len = strlen(TYPE_URL_PREFIX);
upb_symtab *symtab = DescriptorPool_GetSymbolTable();
const upb_msgdef *m;
Descriptor *desc;
zend_class_entry *klass;
zval ret;
// Ensure that type_url has TYPE_URL_PREFIX as a prefix.
if (type_url.size < prefix_len ||
strncmp(TYPE_URL_PREFIX, type_url.data, prefix_len) != 0) {
if (!TryStripUrlPrefix(&type_url)) {
zend_throw_exception(
NULL, "Type url needs to be type.googleapis.com/fully-qualified",
0 TSRMLS_CC);
return;
}
type_url.size -= prefix_len;
type_url.data += prefix_len;
m = upb_symtab_lookupmsg2(symtab, type_url.data, type_url.size);
if (m == NULL) {
@ -1059,9 +1086,11 @@ PHP_METHOD(google_protobuf_Any, unpack) {
}
desc = Descriptor_GetFromMessageDef(m);
klass = desc->class_entry;
ZVAL_OBJ(&ret, klass->create_object(klass));
Message *msg = (Message*)Z_OBJ_P(&ret);
PBPHP_ASSERT(desc->class_entry->create_object == Message_create);
zend_object *obj = Message_create(desc->class_entry);
Message *msg = (Message*)obj;
Message_Initialize(msg, desc);
ZVAL_OBJ(&ret, obj);
// Get value.
if (!upb_decode(value.data, value.size, msg->msg,
@ -1076,9 +1105,15 @@ PHP_METHOD(google_protobuf_Any, unpack) {
RETURN_ZVAL(&ret, 1, 0);
}
/*
PHP_METHOD(Any, pack) {
zval* val;
PHP_METHOD(google_protobuf_Any, pack) {
Message* intern = (Message*)Z_OBJ_P(getThis());
upb_arena *arena = Arena_Get(&intern->arena);
zval *val;
Message *msg;
upb_strview value;
upb_strview type_url;
const char *full_name;
char *buf;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o", &val) ==
FAILURE) {
@ -1090,76 +1125,153 @@ PHP_METHOD(Any, pack) {
return;
}
// Set value by serialized data.
zval data;
serialize_to_string(val, &data TSRMLS_CC);
zval member;
PHP_PROTO_ZVAL_STRING(&member, "value", 1);
PHP_PROTO_FAKE_SCOPE_BEGIN(any_type);
message_handlers->write_property(getThis(), &member, &data,
NULL PHP_PROTO_TSRMLS_CC);
zval_dtor(&data);
zval_dtor(&member);
PHP_PROTO_FAKE_SCOPE_END;
// Set type url.
DescriptorInternal* desc = get_ce_desc(Z_OBJCE_P(val));
const char* fully_qualified_name = upb_msgdef_fullname(desc->msgdef);
size_t type_url_len =
strlen(TYPE_URL_PREFIX) + strlen(fully_qualified_name) + 1;
char* type_url = ALLOC_N(char, type_url_len);
sprintf(type_url, "%s%s", TYPE_URL_PREFIX, fully_qualified_name);
zval type_url_php;
PHP_PROTO_ZVAL_STRING(&type_url_php, type_url, 1);
PHP_PROTO_ZVAL_STRING(&member, "type_url", 1);
PHP_PROTO_FAKE_SCOPE_RESTART(any_type);
message_handlers->write_property(getThis(), &member, &type_url_php,
NULL PHP_PROTO_TSRMLS_CC);
zval_dtor(&type_url_php);
zval_dtor(&member);
PHP_PROTO_FAKE_SCOPE_END;
FREE(type_url);
msg = (Message*)Z_OBJ_P(val);
// Serialize and set value.
value.data = upb_encode(msg->msg, upb_msgdef_layout(msg->desc->msgdef), arena,
&value.size);
Message_setval(intern, "value", StringVal(value));
// Set type url: type_url_prefix + fully_qualified_name
full_name = upb_msgdef_fullname(msg->desc->msgdef);
type_url.size = strlen(TYPE_URL_PREFIX) + strlen(full_name);
buf = upb_arena_malloc(arena, type_url.size + 1);
memcpy(buf, TYPE_URL_PREFIX, strlen(TYPE_URL_PREFIX));
memcpy(buf + strlen(TYPE_URL_PREFIX), full_name, strlen(full_name));
type_url.data = buf;
Message_setval(intern, "type_url", StringVal(type_url));
}
PHP_METHOD(Any, is) {
PHP_METHOD(google_protobuf_Any, is) {
Message* intern = (Message*)Z_OBJ_P(getThis());
upb_strview type_url = Message_getval(intern, "type_url").str_val;
zend_class_entry *klass = NULL;
const upb_msgdef *m;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "C", &klass) ==
FAILURE) {
return;
}
DescriptorInternal* desc = get_ce_desc(klass);
if (desc == NULL) {
m = NameMap_GetMessage(klass);
if (m == NULL) {
RETURN_BOOL(false);
}
// Create corresponded type url.
const char* fully_qualified_name = upb_msgdef_fullname(desc->msgdef);
size_t type_url_len =
strlen(TYPE_URL_PREFIX) + strlen(fully_qualified_name) + 1;
char* type_url = ALLOC_N(char, type_url_len);
sprintf(type_url, "%s%s", TYPE_URL_PREFIX, fully_qualified_name);
// Fetch stored type url.
zval member;
PHP_PROTO_ZVAL_STRING(&member, "type_url", 1);
PHP_PROTO_FAKE_SCOPE_BEGIN(any_type);
zval* value =
php_proto_message_read_property(getThis(), &member PHP_PROTO_TSRMLS_CC);
zval_dtor(&member);
PHP_PROTO_FAKE_SCOPE_END;
// Compare two type url.
bool is = strcmp(type_url, Z_STRVAL_P(value)) == 0;
FREE(type_url);
RETURN_BOOL(is);
RETURN_BOOL(TryStripUrlPrefix(&type_url) &&
StrViewEq(type_url, upb_msgdef_fullname(m)));
}
PHP_METHOD(google_protobuf_Timestamp, fromDateTime) {
Message* intern = (Message*)Z_OBJ_P(getThis());
zval* datetime;
const char *classname = "\\DatetimeInterface";
zend_string *classname_str = zend_string_init(classname, strlen(classname), 0);
zend_class_entry *date_interface_ce = zend_lookup_class(classname_str);
if (date_interface_ce == NULL) {
zend_error(E_ERROR, "Make sure date extension is enabled.");
return;
}
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O", &datetime,
date_interface_ce) == FAILURE) {
zend_error(E_USER_ERROR, "Expect DatetimeInterface.");
return;
}
upb_msgval timestamp_seconds;
{
zval retval;
zval function_name;
ZVAL_STRING(&function_name, "date_timestamp_get");
if (call_user_function(EG(function_table), NULL, &function_name, &retval, 1,
datetime) == FAILURE ||
!Convert_PhpToUpb(&retval, &timestamp_seconds, UPB_TYPE_INT64, NULL,
NULL)) {
zend_error(E_ERROR, "Cannot get timestamp from DateTime.");
return;
}
zval_dtor(&retval);
zval_dtor(&function_name);
}
upb_msgval timestamp_nanos;
{
zval retval;
zval function_name;
zval format_string;
ZVAL_STRING(&function_name, "date_format");
ZVAL_STRING(&format_string, "u");
zval params[2] = {
*datetime,
format_string,
};
if (call_user_function(EG(function_table), NULL, &function_name, &retval, 2,
params) == FAILURE ||
!Convert_PhpToUpb(&retval, &timestamp_nanos, UPB_TYPE_INT32, NULL,
NULL)) {
zend_error(E_ERROR, "Cannot format DateTime.");
return;
}
timestamp_nanos.int32_val *= 1000;
zval_dtor(&retval);
zval_dtor(&function_name);
zval_dtor(&format_string);
}
Message_setval(intern, "seconds", timestamp_seconds);
Message_setval(intern, "nanos", timestamp_nanos);
RETURN_NULL();
}
PHP_METHOD(google_protobuf_Timestamp, toDateTime) {
Message* intern = (Message*)Z_OBJ_P(getThis());
upb_msgval seconds = Message_getval(intern, "seconds");
upb_msgval nanos = Message_getval(intern, "nanos");
// Get formatted time string.
char formatted_time[32];
snprintf(formatted_time, sizeof(formatted_time), "%" PRId64 ".%06" PRId32,
seconds.int64_val, nanos.int32_val / 1000);
// Create Datetime object.
zval datetime;
zval function_name;
zval format_string;
zval formatted_time_php;
ZVAL_STRING(&function_name, "date_create_from_format");
ZVAL_STRING(&format_string, "U.u");
ZVAL_STRING(&formatted_time_php, formatted_time);
zval params[2] = {
format_string,
formatted_time_php,
};
if (call_user_function(EG(function_table), NULL, &function_name, &datetime, 2,
params) == FAILURE) {
zend_error(E_ERROR, "Cannot create DateTime.");
return;
}
zval_dtor(&function_name);
zval_dtor(&format_string);
zval_dtor(&formatted_time_php);
ZVAL_OBJ(return_value, Z_OBJ(datetime));
}
*/
#include "wkt.inc"

@ -110,6 +110,8 @@ static zend_function_entry google_protobuf_Timestamp_phpmethods[] = {
PHP_ME(google_protobuf_Timestamp, setSeconds, NULL, ZEND_ACC_PUBLIC)
PHP_ME(google_protobuf_Timestamp, getNanos, NULL, ZEND_ACC_PUBLIC)
PHP_ME(google_protobuf_Timestamp, setNanos, NULL, ZEND_ACC_PUBLIC)
PHP_ME(google_protobuf_Timestamp, fromDateTime, NULL, ZEND_ACC_PUBLIC)
PHP_ME(google_protobuf_Timestamp, toDateTime, NULL, ZEND_ACC_PUBLIC)
ZEND_FE_END
};
@ -724,6 +726,8 @@ static zend_function_entry google_protobuf_Any_phpmethods[] = {
PHP_ME(google_protobuf_Any, setTypeUrl, NULL, ZEND_ACC_PUBLIC)
PHP_ME(google_protobuf_Any, getValue, NULL, ZEND_ACC_PUBLIC)
PHP_ME(google_protobuf_Any, setValue, NULL, ZEND_ACC_PUBLIC)
PHP_ME(google_protobuf_Any, is, NULL, ZEND_ACC_PUBLIC)
PHP_ME(google_protobuf_Any, pack, NULL, ZEND_ACC_PUBLIC)
PHP_ME(google_protobuf_Any, unpack, NULL, ZEND_ACC_PUBLIC)
ZEND_FE_END
};
@ -1979,6 +1983,174 @@ static void google_protobuf_Field_ModuleInit() {
zend_do_inheritance(google_protobuf_Field_ce, message_ce);
}
/* google_protobuf_Field_Kind */
zend_class_entry* google_protobuf_Field_Kind_ce;
PHP_METHOD(google_protobuf_Field_Kind, name) {
google_protobuf_type_proto_AddDescriptor();
const upb_symtab *symtab = DescriptorPool_GetSymbolTable();
const upb_enumdef *e = upb_symtab_lookupenum(symtab, "google.protobuf.Field.Kind");
const char *name;
zend_long value;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &value) ==
FAILURE) {
return;
}
name = upb_enumdef_iton(e, value);
if (!name) {
zend_throw_exception_ex(NULL, 0,
"Google\\Protobuf\\Field\\Kind has no name "
"defined for value " ZEND_LONG_FMT ".",
value);
return;
}
RETURN_STRING(name);
}
PHP_METHOD(google_protobuf_Field_Kind, value) {
google_protobuf_type_proto_AddDescriptor();
const upb_symtab *symtab = DescriptorPool_GetSymbolTable();
const upb_enumdef *e = upb_symtab_lookupenum(symtab, "google.protobuf.Field.Kind");
char *name = NULL;
size_t name_len;
int32_t num;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name,
&name_len) == FAILURE) {
return;
}
if (!upb_enumdef_ntoi(e, name, name_len, &num)) {
zend_throw_exception_ex(NULL, 0,
"Google\\Protobuf\\Field\\Kind has no value "
"defined for name %s.",
name);
return;
}
RETURN_LONG(num);
}
static zend_function_entry google_protobuf_Field_Kind_phpmethods[] = {
PHP_ME(google_protobuf_Field_Kind, name, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
PHP_ME(google_protobuf_Field_Kind, value, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
ZEND_FE_END
};
static void google_protobuf_Field_Kind_ModuleInit() {
zend_class_entry tmp_ce;
INIT_CLASS_ENTRY(tmp_ce, "Google\\Protobuf\\Field\\Kind",
google_protobuf_Field_Kind_phpmethods);
google_protobuf_Field_Kind_ce = zend_register_internal_class(&tmp_ce);
zend_declare_class_constant_long(google_protobuf_Field_Kind_ce, "TYPE_UNKNOWN",
strlen("TYPE_UNKNOWN"), 0);
zend_declare_class_constant_long(google_protobuf_Field_Kind_ce, "TYPE_DOUBLE",
strlen("TYPE_DOUBLE"), 1);
zend_declare_class_constant_long(google_protobuf_Field_Kind_ce, "TYPE_FLOAT",
strlen("TYPE_FLOAT"), 2);
zend_declare_class_constant_long(google_protobuf_Field_Kind_ce, "TYPE_INT64",
strlen("TYPE_INT64"), 3);
zend_declare_class_constant_long(google_protobuf_Field_Kind_ce, "TYPE_UINT64",
strlen("TYPE_UINT64"), 4);
zend_declare_class_constant_long(google_protobuf_Field_Kind_ce, "TYPE_INT32",
strlen("TYPE_INT32"), 5);
zend_declare_class_constant_long(google_protobuf_Field_Kind_ce, "TYPE_FIXED64",
strlen("TYPE_FIXED64"), 6);
zend_declare_class_constant_long(google_protobuf_Field_Kind_ce, "TYPE_FIXED32",
strlen("TYPE_FIXED32"), 7);
zend_declare_class_constant_long(google_protobuf_Field_Kind_ce, "TYPE_BOOL",
strlen("TYPE_BOOL"), 8);
zend_declare_class_constant_long(google_protobuf_Field_Kind_ce, "TYPE_STRING",
strlen("TYPE_STRING"), 9);
zend_declare_class_constant_long(google_protobuf_Field_Kind_ce, "TYPE_GROUP",
strlen("TYPE_GROUP"), 10);
zend_declare_class_constant_long(google_protobuf_Field_Kind_ce, "TYPE_MESSAGE",
strlen("TYPE_MESSAGE"), 11);
zend_declare_class_constant_long(google_protobuf_Field_Kind_ce, "TYPE_BYTES",
strlen("TYPE_BYTES"), 12);
zend_declare_class_constant_long(google_protobuf_Field_Kind_ce, "TYPE_UINT32",
strlen("TYPE_UINT32"), 13);
zend_declare_class_constant_long(google_protobuf_Field_Kind_ce, "TYPE_ENUM",
strlen("TYPE_ENUM"), 14);
zend_declare_class_constant_long(google_protobuf_Field_Kind_ce, "TYPE_SFIXED32",
strlen("TYPE_SFIXED32"), 15);
zend_declare_class_constant_long(google_protobuf_Field_Kind_ce, "TYPE_SFIXED64",
strlen("TYPE_SFIXED64"), 16);
zend_declare_class_constant_long(google_protobuf_Field_Kind_ce, "TYPE_SINT32",
strlen("TYPE_SINT32"), 17);
zend_declare_class_constant_long(google_protobuf_Field_Kind_ce, "TYPE_SINT64",
strlen("TYPE_SINT64"), 18);
}
/* google_protobuf_Field_Cardinality */
zend_class_entry* google_protobuf_Field_Cardinality_ce;
PHP_METHOD(google_protobuf_Field_Cardinality, name) {
google_protobuf_type_proto_AddDescriptor();
const upb_symtab *symtab = DescriptorPool_GetSymbolTable();
const upb_enumdef *e = upb_symtab_lookupenum(symtab, "google.protobuf.Field.Cardinality");
const char *name;
zend_long value;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &value) ==
FAILURE) {
return;
}
name = upb_enumdef_iton(e, value);
if (!name) {
zend_throw_exception_ex(NULL, 0,
"Google\\Protobuf\\Field\\Cardinality has no name "
"defined for value " ZEND_LONG_FMT ".",
value);
return;
}
RETURN_STRING(name);
}
PHP_METHOD(google_protobuf_Field_Cardinality, value) {
google_protobuf_type_proto_AddDescriptor();
const upb_symtab *symtab = DescriptorPool_GetSymbolTable();
const upb_enumdef *e = upb_symtab_lookupenum(symtab, "google.protobuf.Field.Cardinality");
char *name = NULL;
size_t name_len;
int32_t num;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name,
&name_len) == FAILURE) {
return;
}
if (!upb_enumdef_ntoi(e, name, name_len, &num)) {
zend_throw_exception_ex(NULL, 0,
"Google\\Protobuf\\Field\\Cardinality has no value "
"defined for name %s.",
name);
return;
}
RETURN_LONG(num);
}
static zend_function_entry google_protobuf_Field_Cardinality_phpmethods[] = {
PHP_ME(google_protobuf_Field_Cardinality, name, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
PHP_ME(google_protobuf_Field_Cardinality, value, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
ZEND_FE_END
};
static void google_protobuf_Field_Cardinality_ModuleInit() {
zend_class_entry tmp_ce;
INIT_CLASS_ENTRY(tmp_ce, "Google\\Protobuf\\Field\\Cardinality",
google_protobuf_Field_Cardinality_phpmethods);
google_protobuf_Field_Cardinality_ce = zend_register_internal_class(&tmp_ce);
zend_declare_class_constant_long(google_protobuf_Field_Cardinality_ce, "CARDINALITY_UNKNOWN",
strlen("CARDINALITY_UNKNOWN"), 0);
zend_declare_class_constant_long(google_protobuf_Field_Cardinality_ce, "CARDINALITY_OPTIONAL",
strlen("CARDINALITY_OPTIONAL"), 1);
zend_declare_class_constant_long(google_protobuf_Field_Cardinality_ce, "CARDINALITY_REQUIRED",
strlen("CARDINALITY_REQUIRED"), 2);
zend_declare_class_constant_long(google_protobuf_Field_Cardinality_ce, "CARDINALITY_REPEATED",
strlen("CARDINALITY_REPEATED"), 3);
}
/* google_protobuf_Enum */
zend_class_entry* google_protobuf_Enum_ce;
@ -2297,6 +2469,71 @@ static void google_protobuf_Option_ModuleInit() {
zend_do_inheritance(google_protobuf_Option_ce, message_ce);
}
/* google_protobuf_Syntax */
zend_class_entry* google_protobuf_Syntax_ce;
PHP_METHOD(google_protobuf_Syntax, name) {
google_protobuf_type_proto_AddDescriptor();
const upb_symtab *symtab = DescriptorPool_GetSymbolTable();
const upb_enumdef *e = upb_symtab_lookupenum(symtab, "google.protobuf.Syntax");
const char *name;
zend_long value;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &value) ==
FAILURE) {
return;
}
name = upb_enumdef_iton(e, value);
if (!name) {
zend_throw_exception_ex(NULL, 0,
"Google\\Protobuf\\Syntax has no name "
"defined for value " ZEND_LONG_FMT ".",
value);
return;
}
RETURN_STRING(name);
}
PHP_METHOD(google_protobuf_Syntax, value) {
google_protobuf_type_proto_AddDescriptor();
const upb_symtab *symtab = DescriptorPool_GetSymbolTable();
const upb_enumdef *e = upb_symtab_lookupenum(symtab, "google.protobuf.Syntax");
char *name = NULL;
size_t name_len;
int32_t num;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name,
&name_len) == FAILURE) {
return;
}
if (!upb_enumdef_ntoi(e, name, name_len, &num)) {
zend_throw_exception_ex(NULL, 0,
"Google\\Protobuf\\Syntax has no value "
"defined for name %s.",
name);
return;
}
RETURN_LONG(num);
}
static zend_function_entry google_protobuf_Syntax_phpmethods[] = {
PHP_ME(google_protobuf_Syntax, name, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
PHP_ME(google_protobuf_Syntax, value, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
ZEND_FE_END
};
static void google_protobuf_Syntax_ModuleInit() {
zend_class_entry tmp_ce;
INIT_CLASS_ENTRY(tmp_ce, "Google\\Protobuf\\Syntax",
google_protobuf_Syntax_phpmethods);
google_protobuf_Syntax_ce = zend_register_internal_class(&tmp_ce);
zend_declare_class_constant_long(google_protobuf_Syntax_ce, "SYNTAX_PROTO2",
strlen("SYNTAX_PROTO2"), 0);
zend_declare_class_constant_long(google_protobuf_Syntax_ce, "SYNTAX_PROTO3",
strlen("SYNTAX_PROTO3"), 1);
}
/* google/protobuf/struct.proto */
zend_class_entry* GPBMetadata_Google_Protobuf_Struct_ce;
@ -2619,6 +2856,13 @@ static PHP_METHOD(google_protobuf_Value, setListValue) {
RETURN_ZVAL(getThis(), 1, 0);
}
static PHP_METHOD(google_protobuf_Value, getKind) {
Message* intern = (Message*)Z_OBJ_P(getThis());
const upb_oneofdef *oneof = upb_msgdef_ntooz(intern->desc->msgdef,
"kind");
const upb_fielddef *field = upb_msg_whichoneof(intern->msg, oneof);
RETURN_STRING(field ? upb_fielddef_name(field) : "");
}
static zend_function_entry google_protobuf_Value_phpmethods[] = {
PHP_ME(google_protobuf_Value, __construct, NULL, ZEND_ACC_PUBLIC)
PHP_ME(google_protobuf_Value, getNullValue, NULL, ZEND_ACC_PUBLIC)
@ -2633,6 +2877,7 @@ static zend_function_entry google_protobuf_Value_phpmethods[] = {
PHP_ME(google_protobuf_Value, setStructValue, NULL, ZEND_ACC_PUBLIC)
PHP_ME(google_protobuf_Value, getListValue, NULL, ZEND_ACC_PUBLIC)
PHP_ME(google_protobuf_Value, setListValue, NULL, ZEND_ACC_PUBLIC)
PHP_ME(google_protobuf_Value, getKind, NULL, ZEND_ACC_PUBLIC)
ZEND_FE_END
};
@ -2698,6 +2943,69 @@ static void google_protobuf_ListValue_ModuleInit() {
zend_do_inheritance(google_protobuf_ListValue_ce, message_ce);
}
/* google_protobuf_NullValue */
zend_class_entry* google_protobuf_NullValue_ce;
PHP_METHOD(google_protobuf_NullValue, name) {
google_protobuf_struct_proto_AddDescriptor();
const upb_symtab *symtab = DescriptorPool_GetSymbolTable();
const upb_enumdef *e = upb_symtab_lookupenum(symtab, "google.protobuf.NullValue");
const char *name;
zend_long value;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &value) ==
FAILURE) {
return;
}
name = upb_enumdef_iton(e, value);
if (!name) {
zend_throw_exception_ex(NULL, 0,
"Google\\Protobuf\\NullValue has no name "
"defined for value " ZEND_LONG_FMT ".",
value);
return;
}
RETURN_STRING(name);
}
PHP_METHOD(google_protobuf_NullValue, value) {
google_protobuf_struct_proto_AddDescriptor();
const upb_symtab *symtab = DescriptorPool_GetSymbolTable();
const upb_enumdef *e = upb_symtab_lookupenum(symtab, "google.protobuf.NullValue");
char *name = NULL;
size_t name_len;
int32_t num;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name,
&name_len) == FAILURE) {
return;
}
if (!upb_enumdef_ntoi(e, name, name_len, &num)) {
zend_throw_exception_ex(NULL, 0,
"Google\\Protobuf\\NullValue has no value "
"defined for name %s.",
name);
return;
}
RETURN_LONG(num);
}
static zend_function_entry google_protobuf_NullValue_phpmethods[] = {
PHP_ME(google_protobuf_NullValue, name, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
PHP_ME(google_protobuf_NullValue, value, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
ZEND_FE_END
};
static void google_protobuf_NullValue_ModuleInit() {
zend_class_entry tmp_ce;
INIT_CLASS_ENTRY(tmp_ce, "Google\\Protobuf\\NullValue",
google_protobuf_NullValue_phpmethods);
google_protobuf_NullValue_ce = zend_register_internal_class(&tmp_ce);
zend_declare_class_constant_long(google_protobuf_NullValue_ce, "NULL_VALUE",
strlen("NULL_VALUE"), 0);
}
/* google/protobuf/source_context.proto */
zend_class_entry* GPBMetadata_Google_Protobuf_SourceContext_ce;
@ -2905,14 +3213,18 @@ static void WellKnownTypes_ModuleInit() {
GPBMetadata_Google_Protobuf_Type_ModuleInit();
google_protobuf_Type_ModuleInit();
google_protobuf_Field_ModuleInit();
google_protobuf_Field_Kind_ModuleInit();
google_protobuf_Field_Cardinality_ModuleInit();
google_protobuf_Enum_ModuleInit();
google_protobuf_EnumValue_ModuleInit();
google_protobuf_Option_ModuleInit();
google_protobuf_Syntax_ModuleInit();
GPBMetadata_Google_Protobuf_Struct_ModuleInit();
google_protobuf_Struct_ModuleInit();
google_protobuf_Struct_FieldsEntry_ModuleInit();
google_protobuf_Value_ModuleInit();
google_protobuf_ListValue_ModuleInit();
google_protobuf_NullValue_ModuleInit();
GPBMetadata_Google_Protobuf_SourceContext_ModuleInit();
google_protobuf_SourceContext_ModuleInit();
GPBMetadata_Google_Protobuf_FieldMask_ModuleInit();

@ -13,4 +13,15 @@ fi
pushd src
./protoc --php_out=internal:../php/src google/protobuf/descriptor.proto
./protoc --php_out=internal_generate_c_wkt:src \
google/protobuf/any.proto \
google/protobuf/api.proto \
google/protobuf/duration.proto \
google/protobuf/empty.proto \
google/protobuf/field_mask.proto \
google/protobuf/source_context.proto \
google/protobuf/struct.proto \
google/protobuf/type.proto \
google/protobuf/timestamp.proto \
google/protobuf/wrappers.proto
popd

@ -1815,6 +1815,91 @@ std::string FilenameCName(const FileDescriptor* file) {
return c_name;
}
void GenerateCEnum(const EnumDescriptor* desc, io::Printer* printer) {
std::string c_name = desc->full_name();
c_name = StringReplace(c_name, ".", "_", true);
std::string php_name = FullClassName(desc, Options());
php_name = StringReplace(php_name, "\\", "\\\\", true);
printer->Print(
"/* $c_name$ */\n"
"\n"
"zend_class_entry* $c_name$_ce;\n"
"\n"
"PHP_METHOD($c_name$, name) {\n"
" $file_c_name$_AddDescriptor();\n"
" const upb_symtab *symtab = DescriptorPool_GetSymbolTable();\n"
" const upb_enumdef *e = upb_symtab_lookupenum(symtab, \"$name$\");\n"
" const char *name;\n"
" zend_long value;\n"
" if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, \"l\", &value) ==\n"
" FAILURE) {\n"
" return;\n"
" }\n"
" name = upb_enumdef_iton(e, value);\n"
" if (!name) {\n"
" zend_throw_exception_ex(NULL, 0,\n"
" \"$php_name$ has no name \"\n"
" \"defined for value \" ZEND_LONG_FMT \".\",\n"
" value);\n"
" return;\n"
" }\n"
" RETURN_STRING(name);\n"
"}\n"
"\n"
"PHP_METHOD($c_name$, value) {\n"
" $file_c_name$_AddDescriptor();\n"
" const upb_symtab *symtab = DescriptorPool_GetSymbolTable();\n"
" const upb_enumdef *e = upb_symtab_lookupenum(symtab, \"$name$\");\n"
" char *name = NULL;\n"
" size_t name_len;\n"
" int32_t num;\n"
" if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, \"s\", &name,\n"
" &name_len) == FAILURE) {\n"
" return;\n"
" }\n"
" if (!upb_enumdef_ntoi(e, name, name_len, &num)) {\n"
" zend_throw_exception_ex(NULL, 0,\n"
" \"$php_name$ has no value \"\n"
" \"defined for name %s.\",\n"
" name);\n"
" return;\n"
" }\n"
" RETURN_LONG(num);\n"
"}\n"
"\n"
"static zend_function_entry $c_name$_phpmethods[] = {\n"
" PHP_ME($c_name$, name, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)\n"
" PHP_ME($c_name$, value, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)\n"
" ZEND_FE_END\n"
"};\n"
"\n"
"static void $c_name$_ModuleInit() {\n"
" zend_class_entry tmp_ce;\n"
"\n"
" INIT_CLASS_ENTRY(tmp_ce, \"$php_name$\",\n"
" $c_name$_phpmethods);\n"
"\n"
" $c_name$_ce = zend_register_internal_class(&tmp_ce);\n",
"name", desc->full_name(),
"file_c_name", FilenameCName(desc->file()),
"c_name", c_name,
"php_name", php_name);
for (int i = 0; i < desc->value_count(); i++) {
const EnumValueDescriptor* value = desc->value(i);
printer->Print(
" zend_declare_class_constant_long($c_name$_ce, \"$name$\",\n"
" strlen(\"$name$\"), $num$);\n",
"c_name", c_name,
"name", value->name(),
"num", std::to_string(value->number()));
}
printer->Print(
"}\n"
"\n");
}
void GenerateCMessage(const Descriptor* message, io::Printer* printer) {
std::string c_name = message->full_name();
c_name = StringReplace(c_name, ".", "_", true);
@ -1863,6 +1948,21 @@ void GenerateCMessage(const Descriptor* message, io::Printer* printer) {
"camel_name", UnderscoresToCamelCase(field->name(), true));
}
for (int i = 0; i < message->real_oneof_decl_count(); i++) {
auto oneof = message->oneof_decl(i);
printer->Print(
"static PHP_METHOD($c_name$, get$camel_name$) {\n"
" Message* intern = (Message*)Z_OBJ_P(getThis());\n"
" const upb_oneofdef *oneof = upb_msgdef_ntooz(intern->desc->msgdef,\n"
" \"$name$\");\n"
" const upb_fielddef *field = upb_msg_whichoneof(intern->msg, oneof);\n"
" RETURN_STRING(field ? upb_fielddef_name(field) : \"\");\n"
"}\n",
"c_name", c_name,
"name", oneof->name(),
"camel_name", UnderscoresToCamelCase(oneof->name(), true));
}
printer->Print(
"static zend_function_entry $c_name$_phpmethods[] = {\n"
" PHP_ME($c_name$, __construct, NULL, ZEND_ACC_PUBLIC)\n",
@ -1877,12 +1977,33 @@ void GenerateCMessage(const Descriptor* message, io::Printer* printer) {
"camel_name", UnderscoresToCamelCase(field->name(), true));
}
if (message->well_known_type() == Descriptor::WELLKNOWNTYPE_ANY) {
for (int i = 0; i < message->real_oneof_decl_count(); i++) {
auto oneof = message->oneof_decl(i);
printer->Print(
" PHP_ME($c_name$, unpack, NULL, ZEND_ACC_PUBLIC)\n",
"c_name", c_name);
" PHP_ME($c_name$, get$camel_name$, NULL, ZEND_ACC_PUBLIC)\n",
"c_name", c_name,
"camel_name", UnderscoresToCamelCase(oneof->name(), true));
}
// Extra hand-written functions added to the well-known types.
switch (message->well_known_type()) {
case Descriptor::WELLKNOWNTYPE_ANY:
printer->Print(
" PHP_ME($c_name$, is, NULL, ZEND_ACC_PUBLIC)\n"
" PHP_ME($c_name$, pack, NULL, ZEND_ACC_PUBLIC)\n"
" PHP_ME($c_name$, unpack, NULL, ZEND_ACC_PUBLIC)\n",
"c_name", c_name);
break;
case Descriptor::WELLKNOWNTYPE_TIMESTAMP:
printer->Print(
" PHP_ME($c_name$, fromDateTime, NULL, ZEND_ACC_PUBLIC)\n"
" PHP_ME($c_name$, toDateTime, NULL, ZEND_ACC_PUBLIC)\n",
"c_name", c_name);
break;
default:
break;
}
printer->Print(
" ZEND_FE_END\n"
"};\n"
@ -1905,6 +2026,18 @@ void GenerateCMessage(const Descriptor* message, io::Printer* printer) {
for (int i = 0; i < message->nested_type_count(); i++) {
GenerateCMessage(message->nested_type(i), printer);
}
for (int i = 0; i < message->enum_type_count(); i++) {
GenerateCEnum(message->enum_type(i), printer);
}
}
void GenerateEnumCInit(const EnumDescriptor* desc, io::Printer* printer) {
std::string c_name = desc->full_name();
c_name = StringReplace(c_name, ".", "_", true);
printer->Print(
" $c_name$_ModuleInit();\n",
"c_name", c_name);
}
void GenerateCInit(const Descriptor* message, io::Printer* printer) {
@ -1918,6 +2051,9 @@ void GenerateCInit(const Descriptor* message, io::Printer* printer) {
for (int i = 0; i < message->nested_type_count(); i++) {
GenerateCInit(message->nested_type(i), printer);
}
for (int i = 0; i < message->enum_type_count(); i++) {
GenerateEnumCInit(message->enum_type(i), printer);
}
}
void GenerateCWellKnownTypes(const std::vector<const FileDescriptor*>& files,
@ -2011,6 +2147,9 @@ void GenerateCWellKnownTypes(const std::vector<const FileDescriptor*>& files,
for (int i = 0; i < file->message_type_count(); i++) {
GenerateCMessage(file->message_type(i), &printer);
}
for (int i = 0; i < file->enum_type_count(); i++) {
GenerateCEnum(file->enum_type(i), &printer);
}
}
printer.Print(
@ -2027,6 +2166,9 @@ void GenerateCWellKnownTypes(const std::vector<const FileDescriptor*>& files,
for (int i = 0; i < file->message_type_count(); i++) {
GenerateCInit(file->message_type(i), &printer);
}
for (int i = 0; i < file->enum_type_count(); i++) {
GenerateEnumCInit(file->enum_type(i), &printer);
}
}
printer.Print(

Loading…
Cancel
Save