|
|
|
@ -37,12 +37,27 @@ const int kReservedNamesSize = 3; |
|
|
|
|
static void descriptor_init_c_instance(Descriptor* intern TSRMLS_DC); |
|
|
|
|
static void descriptor_free_c(Descriptor* object TSRMLS_DC); |
|
|
|
|
|
|
|
|
|
static void field_descriptor_init_c_instance(FieldDescriptor* intern TSRMLS_DC); |
|
|
|
|
static void field_descriptor_free_c(FieldDescriptor* object TSRMLS_DC); |
|
|
|
|
|
|
|
|
|
static void enum_descriptor_init_c_instance(EnumDescriptor* intern TSRMLS_DC); |
|
|
|
|
static void enum_descriptor_free_c(EnumDescriptor* object TSRMLS_DC); |
|
|
|
|
|
|
|
|
|
static void enum_value_descriptor_init_c_instance( |
|
|
|
|
EnumValueDescriptor *intern TSRMLS_DC); |
|
|
|
|
static void enum_value_descriptor_free_c(EnumValueDescriptor *object TSRMLS_DC); |
|
|
|
|
|
|
|
|
|
static void descriptor_pool_free_c(DescriptorPool* object TSRMLS_DC); |
|
|
|
|
static void descriptor_pool_init_c_instance(DescriptorPool* pool TSRMLS_DC); |
|
|
|
|
|
|
|
|
|
static void internal_descriptor_pool_free_c( |
|
|
|
|
InternalDescriptorPool *object TSRMLS_DC); |
|
|
|
|
static void internal_descriptor_pool_init_c_instance( |
|
|
|
|
InternalDescriptorPool *pool TSRMLS_DC); |
|
|
|
|
|
|
|
|
|
static void oneof_descriptor_free_c(Oneof* object TSRMLS_DC); |
|
|
|
|
static void oneof_descriptor_init_c_instance(Oneof* pool TSRMLS_DC); |
|
|
|
|
|
|
|
|
|
// -----------------------------------------------------------------------------
|
|
|
|
|
// Common Utilities
|
|
|
|
|
// -----------------------------------------------------------------------------
|
|
|
|
@ -169,10 +184,16 @@ void gpb_type_init(TSRMLS_D) { |
|
|
|
|
// -----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
static zend_function_entry descriptor_methods[] = { |
|
|
|
|
PHP_ME(Descriptor, getClass, NULL, ZEND_ACC_PUBLIC) |
|
|
|
|
PHP_ME(Descriptor, getFullName, NULL, ZEND_ACC_PUBLIC) |
|
|
|
|
PHP_ME(Descriptor, getField, NULL, ZEND_ACC_PUBLIC) |
|
|
|
|
PHP_ME(Descriptor, getFieldCount, NULL, ZEND_ACC_PUBLIC) |
|
|
|
|
PHP_ME(Descriptor, getOneofDecl, NULL, ZEND_ACC_PUBLIC) |
|
|
|
|
PHP_ME(Descriptor, getOneofDeclCount, NULL, ZEND_ACC_PUBLIC) |
|
|
|
|
ZEND_FE_END |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
DEFINE_CLASS(Descriptor, descriptor, "Google\\Protobuf\\Internal\\Descriptor"); |
|
|
|
|
DEFINE_CLASS(Descriptor, descriptor, "Google\\Protobuf\\Descriptor"); |
|
|
|
|
|
|
|
|
|
static void descriptor_free_c(Descriptor *self TSRMLS_DC) { |
|
|
|
|
if (self->layout) { |
|
|
|
@ -203,7 +224,6 @@ static void descriptor_free_c(Descriptor *self TSRMLS_DC) { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void descriptor_init_c_instance(Descriptor *desc TSRMLS_DC) { |
|
|
|
|
// zend_object_std_init(&desc->std, descriptor_type TSRMLS_CC);
|
|
|
|
|
desc->msgdef = NULL; |
|
|
|
|
desc->layout = NULL; |
|
|
|
|
desc->klass = NULL; |
|
|
|
@ -215,30 +235,217 @@ static void descriptor_init_c_instance(Descriptor *desc TSRMLS_DC) { |
|
|
|
|
desc->json_serialize_handlers_preserve = NULL; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
PHP_METHOD(Descriptor, getClass) { |
|
|
|
|
Descriptor *intern = UNBOX(Descriptor, getThis()); |
|
|
|
|
#if PHP_MAJOR_VERSION < 7 |
|
|
|
|
const char* classname = intern->klass->name; |
|
|
|
|
#else |
|
|
|
|
const char* classname = ZSTR_VAL(intern->klass->name); |
|
|
|
|
#endif |
|
|
|
|
PHP_PROTO_RETVAL_STRINGL(classname, strlen(classname), 1); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
PHP_METHOD(Descriptor, getFullName) { |
|
|
|
|
Descriptor *intern = UNBOX(Descriptor, getThis()); |
|
|
|
|
const char* fullname = upb_msgdef_fullname(intern->msgdef); |
|
|
|
|
PHP_PROTO_RETVAL_STRINGL(fullname, strlen(fullname), 1); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
PHP_METHOD(Descriptor, getField) { |
|
|
|
|
long index; |
|
|
|
|
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &index) == |
|
|
|
|
FAILURE) { |
|
|
|
|
zend_error(E_USER_ERROR, "Expect integer for index.\n"); |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
Descriptor *intern = UNBOX(Descriptor, getThis()); |
|
|
|
|
int field_num = upb_msgdef_numfields(intern->msgdef); |
|
|
|
|
if (index < 0 || index >= field_num) { |
|
|
|
|
zend_error(E_USER_ERROR, "Cannot get element at %ld.\n", index); |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
upb_msg_field_iter iter; |
|
|
|
|
int i; |
|
|
|
|
for(upb_msg_field_begin(&iter, intern->msgdef), i = 0; |
|
|
|
|
!upb_msg_field_done(&iter) && i < index; |
|
|
|
|
upb_msg_field_next(&iter), i++); |
|
|
|
|
const upb_fielddef *field = upb_msg_iter_field(&iter); |
|
|
|
|
|
|
|
|
|
PHP_PROTO_HASHTABLE_VALUE field_hashtable_value = get_def_obj(field); |
|
|
|
|
if (field_hashtable_value == NULL) { |
|
|
|
|
#if PHP_MAJOR_VERSION < 7 |
|
|
|
|
MAKE_STD_ZVAL(field_hashtable_value); |
|
|
|
|
ZVAL_OBJ(field_hashtable_value, field_descriptor_type->create_object( |
|
|
|
|
field_descriptor_type TSRMLS_CC)); |
|
|
|
|
#else |
|
|
|
|
field_hashtable_value = |
|
|
|
|
field_descriptor_type->create_object(field_descriptor_type TSRMLS_CC); |
|
|
|
|
#endif |
|
|
|
|
FieldDescriptor *field_php = |
|
|
|
|
UNBOX_HASHTABLE_VALUE(FieldDescriptor, field_hashtable_value); |
|
|
|
|
field_php->fielddef = field; |
|
|
|
|
add_def_obj(field, field_hashtable_value); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
#if PHP_MAJOR_VERSION < 7 |
|
|
|
|
RETURN_ZVAL(field_hashtable_value, 1, 0); |
|
|
|
|
#else |
|
|
|
|
++GC_REFCOUNT(field_hashtable_value); |
|
|
|
|
RETURN_OBJ(field_hashtable_value); |
|
|
|
|
#endif |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
PHP_METHOD(Descriptor, getFieldCount) { |
|
|
|
|
Descriptor *intern = UNBOX(Descriptor, getThis()); |
|
|
|
|
RETURN_LONG(upb_msgdef_numfields(intern->msgdef)); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
PHP_METHOD(Descriptor, getOneofDecl) { |
|
|
|
|
long index; |
|
|
|
|
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &index) == |
|
|
|
|
FAILURE) { |
|
|
|
|
zend_error(E_USER_ERROR, "Expect integer for index.\n"); |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
Descriptor *intern = UNBOX(Descriptor, getThis()); |
|
|
|
|
int field_num = upb_msgdef_numoneofs(intern->msgdef); |
|
|
|
|
if (index < 0 || index >= field_num) { |
|
|
|
|
zend_error(E_USER_ERROR, "Cannot get element at %ld.\n", index); |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
upb_msg_oneof_iter iter; |
|
|
|
|
int i; |
|
|
|
|
for(upb_msg_oneof_begin(&iter, intern->msgdef), i = 0; |
|
|
|
|
!upb_msg_oneof_done(&iter) && i < index; |
|
|
|
|
upb_msg_oneof_next(&iter), i++); |
|
|
|
|
upb_oneofdef *oneof = upb_msg_iter_oneof(&iter); |
|
|
|
|
|
|
|
|
|
ZVAL_OBJ(return_value, oneof_descriptor_type->create_object( |
|
|
|
|
oneof_descriptor_type TSRMLS_CC)); |
|
|
|
|
Oneof *oneof_php = UNBOX(Oneof, return_value); |
|
|
|
|
oneof_php->oneofdef = oneof; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
PHP_METHOD(Descriptor, getOneofDeclCount) { |
|
|
|
|
Descriptor *intern = UNBOX(Descriptor, getThis()); |
|
|
|
|
RETURN_LONG(upb_msgdef_numoneofs(intern->msgdef)); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// -----------------------------------------------------------------------------
|
|
|
|
|
// EnumDescriptor
|
|
|
|
|
// -----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
static zend_function_entry enum_descriptor_methods[] = { |
|
|
|
|
PHP_ME(EnumDescriptor, getValue, NULL, ZEND_ACC_PUBLIC) |
|
|
|
|
PHP_ME(EnumDescriptor, getValueCount, NULL, ZEND_ACC_PUBLIC) |
|
|
|
|
ZEND_FE_END |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
DEFINE_CLASS(EnumDescriptor, enum_descriptor, |
|
|
|
|
"Google\\Protobuf\\Internal\\EnumDescriptor"); |
|
|
|
|
"Google\\Protobuf\\EnumDescriptor"); |
|
|
|
|
|
|
|
|
|
static void enum_descriptor_free_c(EnumDescriptor *self TSRMLS_DC) { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void enum_descriptor_init_c_instance(EnumDescriptor *self TSRMLS_DC) { |
|
|
|
|
// zend_object_std_init(&self->std, enum_descriptor_type TSRMLS_CC);
|
|
|
|
|
self->enumdef = NULL; |
|
|
|
|
self->klass = NULL; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
PHP_METHOD(EnumDescriptor, getValue) { |
|
|
|
|
long index; |
|
|
|
|
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &index) == |
|
|
|
|
FAILURE) { |
|
|
|
|
zend_error(E_USER_ERROR, "Expect integer for index.\n"); |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
EnumDescriptor *intern = UNBOX(EnumDescriptor, getThis()); |
|
|
|
|
int field_num = upb_enumdef_numvals(intern->enumdef); |
|
|
|
|
if (index < 0 || index >= field_num) { |
|
|
|
|
zend_error(E_USER_ERROR, "Cannot get element at %ld.\n", index); |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
upb_enum_iter iter; |
|
|
|
|
int i; |
|
|
|
|
for(upb_enum_begin(&iter, intern->enumdef), i = 0; |
|
|
|
|
!upb_enum_done(&iter) && i < index; |
|
|
|
|
upb_enum_next(&iter), i++); |
|
|
|
|
|
|
|
|
|
ZVAL_OBJ(return_value, enum_value_descriptor_type->create_object( |
|
|
|
|
enum_value_descriptor_type TSRMLS_CC)); |
|
|
|
|
EnumValueDescriptor *enum_value_php = |
|
|
|
|
UNBOX(EnumValueDescriptor, return_value); |
|
|
|
|
enum_value_php->name = upb_enum_iter_name(&iter); |
|
|
|
|
enum_value_php->number = upb_enum_iter_number(&iter); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
PHP_METHOD(EnumDescriptor, getValueCount) { |
|
|
|
|
EnumDescriptor *intern = UNBOX(EnumDescriptor, getThis()); |
|
|
|
|
RETURN_LONG(upb_enumdef_numvals(intern->enumdef)); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// -----------------------------------------------------------------------------
|
|
|
|
|
// EnumValueDescriptor
|
|
|
|
|
// -----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
static zend_function_entry enum_value_descriptor_methods[] = { |
|
|
|
|
PHP_ME(EnumValueDescriptor, getName, NULL, ZEND_ACC_PUBLIC) |
|
|
|
|
PHP_ME(EnumValueDescriptor, getNumber, NULL, ZEND_ACC_PUBLIC) |
|
|
|
|
ZEND_FE_END |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
DEFINE_CLASS(EnumValueDescriptor, enum_value_descriptor, |
|
|
|
|
"Google\\Protobuf\\EnumValueDescriptor"); |
|
|
|
|
|
|
|
|
|
static void enum_value_descriptor_free_c(EnumValueDescriptor *self TSRMLS_DC) { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void enum_value_descriptor_init_c_instance(EnumValueDescriptor *self TSRMLS_DC) { |
|
|
|
|
self->name = NULL; |
|
|
|
|
self->number = 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
PHP_METHOD(EnumValueDescriptor, getName) { |
|
|
|
|
EnumValueDescriptor *intern = UNBOX(EnumValueDescriptor, getThis()); |
|
|
|
|
PHP_PROTO_RETVAL_STRINGL(intern->name, strlen(intern->name), 1); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
PHP_METHOD(EnumValueDescriptor, getNumber) { |
|
|
|
|
EnumValueDescriptor *intern = UNBOX(EnumValueDescriptor, getThis()); |
|
|
|
|
RETURN_LONG(intern->number); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// -----------------------------------------------------------------------------
|
|
|
|
|
// FieldDescriptor
|
|
|
|
|
// -----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
static zend_function_entry field_descriptor_methods[] = { |
|
|
|
|
PHP_ME(FieldDescriptor, getName, NULL, ZEND_ACC_PUBLIC) |
|
|
|
|
PHP_ME(FieldDescriptor, getNumber, NULL, ZEND_ACC_PUBLIC) |
|
|
|
|
PHP_ME(FieldDescriptor, getLabel, NULL, ZEND_ACC_PUBLIC) |
|
|
|
|
PHP_ME(FieldDescriptor, getType, NULL, ZEND_ACC_PUBLIC) |
|
|
|
|
PHP_ME(FieldDescriptor, isMap, NULL, ZEND_ACC_PUBLIC) |
|
|
|
|
PHP_ME(FieldDescriptor, getEnumType, NULL, ZEND_ACC_PUBLIC) |
|
|
|
|
PHP_ME(FieldDescriptor, getMessageType, NULL, ZEND_ACC_PUBLIC) |
|
|
|
|
ZEND_FE_END |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
DEFINE_CLASS(FieldDescriptor, field_descriptor, |
|
|
|
|
"Google\\Protobuf\\FieldDescriptor"); |
|
|
|
|
|
|
|
|
|
static void field_descriptor_free_c(FieldDescriptor *self TSRMLS_DC) { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void field_descriptor_init_c_instance(FieldDescriptor *self TSRMLS_DC) { |
|
|
|
|
self->fielddef = NULL; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
upb_fieldtype_t to_fieldtype(upb_descriptortype_t type) { |
|
|
|
|
switch (type) { |
|
|
|
|
#define CASE(descriptor_type, type) \ |
|
|
|
@ -272,6 +479,150 @@ upb_fieldtype_t to_fieldtype(upb_descriptortype_t type) { |
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
PHP_METHOD(FieldDescriptor, getName) { |
|
|
|
|
FieldDescriptor *intern = UNBOX(FieldDescriptor, getThis()); |
|
|
|
|
const char* name = upb_fielddef_name(intern->fielddef); |
|
|
|
|
PHP_PROTO_RETVAL_STRINGL(name, strlen(name), 1); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
PHP_METHOD(FieldDescriptor, getNumber) { |
|
|
|
|
FieldDescriptor *intern = UNBOX(FieldDescriptor, getThis()); |
|
|
|
|
RETURN_LONG(upb_fielddef_number(intern->fielddef)); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
PHP_METHOD(FieldDescriptor, getLabel) { |
|
|
|
|
FieldDescriptor *intern = UNBOX(FieldDescriptor, getThis()); |
|
|
|
|
RETURN_LONG(upb_fielddef_label(intern->fielddef)); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
PHP_METHOD(FieldDescriptor, getType) { |
|
|
|
|
FieldDescriptor *intern = UNBOX(FieldDescriptor, getThis()); |
|
|
|
|
RETURN_LONG(upb_fielddef_descriptortype(intern->fielddef)); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
PHP_METHOD(FieldDescriptor, isMap) { |
|
|
|
|
FieldDescriptor *intern = UNBOX(FieldDescriptor, getThis()); |
|
|
|
|
RETURN_BOOL(upb_fielddef_ismap(intern->fielddef)); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
PHP_METHOD(FieldDescriptor, getEnumType) { |
|
|
|
|
FieldDescriptor *intern = UNBOX(FieldDescriptor, getThis()); |
|
|
|
|
const upb_enumdef *enumdef = upb_fielddef_enumsubdef(intern->fielddef); |
|
|
|
|
if (enumdef == NULL) { |
|
|
|
|
char error_msg[100]; |
|
|
|
|
sprintf(error_msg, "Cannot get enum type for non-enum field '%s'", |
|
|
|
|
upb_fielddef_name(intern->fielddef)); |
|
|
|
|
zend_throw_exception(NULL, error_msg, 0 TSRMLS_CC); |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
PHP_PROTO_HASHTABLE_VALUE desc = get_def_obj(enumdef); |
|
|
|
|
|
|
|
|
|
#if PHP_MAJOR_VERSION < 7 |
|
|
|
|
RETURN_ZVAL(desc, 1, 0); |
|
|
|
|
#else |
|
|
|
|
++GC_REFCOUNT(desc); |
|
|
|
|
RETURN_OBJ(desc); |
|
|
|
|
#endif |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
PHP_METHOD(FieldDescriptor, getMessageType) { |
|
|
|
|
FieldDescriptor *intern = UNBOX(FieldDescriptor, getThis()); |
|
|
|
|
const upb_msgdef *msgdef = upb_fielddef_msgsubdef(intern->fielddef); |
|
|
|
|
if (msgdef == NULL) { |
|
|
|
|
char error_msg[100]; |
|
|
|
|
sprintf(error_msg, "Cannot get message type for non-message field '%s'", |
|
|
|
|
upb_fielddef_name(intern->fielddef)); |
|
|
|
|
zend_throw_exception(NULL, error_msg, 0 TSRMLS_CC); |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
PHP_PROTO_HASHTABLE_VALUE desc = get_def_obj(msgdef); |
|
|
|
|
|
|
|
|
|
#if PHP_MAJOR_VERSION < 7 |
|
|
|
|
RETURN_ZVAL(desc, 1, 0); |
|
|
|
|
#else |
|
|
|
|
++GC_REFCOUNT(desc); |
|
|
|
|
RETURN_OBJ(desc); |
|
|
|
|
#endif |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// -----------------------------------------------------------------------------
|
|
|
|
|
// Oneof
|
|
|
|
|
// -----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
static zend_function_entry oneof_descriptor_methods[] = { |
|
|
|
|
PHP_ME(Oneof, getName, NULL, ZEND_ACC_PUBLIC) |
|
|
|
|
PHP_ME(Oneof, getField, NULL, ZEND_ACC_PUBLIC) |
|
|
|
|
PHP_ME(Oneof, getFieldCount, NULL, ZEND_ACC_PUBLIC) |
|
|
|
|
ZEND_FE_END |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
DEFINE_CLASS(Oneof, oneof_descriptor, |
|
|
|
|
"Google\\Protobuf\\OneofDescriptor"); |
|
|
|
|
|
|
|
|
|
static void oneof_descriptor_free_c(Oneof *self TSRMLS_DC) { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void oneof_descriptor_init_c_instance(Oneof *self TSRMLS_DC) { |
|
|
|
|
self->oneofdef = NULL; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
PHP_METHOD(Oneof, getName) { |
|
|
|
|
Oneof *intern = UNBOX(Oneof, getThis()); |
|
|
|
|
const char *name = upb_oneofdef_name(intern->oneofdef); |
|
|
|
|
PHP_PROTO_RETVAL_STRINGL(name, strlen(name), 1); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
PHP_METHOD(Oneof, getField) { |
|
|
|
|
long index; |
|
|
|
|
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &index) == |
|
|
|
|
FAILURE) { |
|
|
|
|
zend_error(E_USER_ERROR, "Expect integer for index.\n"); |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
Oneof *intern = UNBOX(Oneof, getThis()); |
|
|
|
|
int field_num = upb_oneofdef_numfields(intern->oneofdef); |
|
|
|
|
if (index < 0 || index >= field_num) { |
|
|
|
|
zend_error(E_USER_ERROR, "Cannot get element at %ld.\n", index); |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
upb_oneof_iter iter; |
|
|
|
|
int i; |
|
|
|
|
for(upb_oneof_begin(&iter, intern->oneofdef), i = 0; |
|
|
|
|
!upb_oneof_done(&iter) && i < index; |
|
|
|
|
upb_oneof_next(&iter), i++); |
|
|
|
|
const upb_fielddef *field = upb_oneof_iter_field(&iter); |
|
|
|
|
|
|
|
|
|
PHP_PROTO_HASHTABLE_VALUE field_hashtable_value = get_def_obj(field); |
|
|
|
|
if (field_hashtable_value == NULL) { |
|
|
|
|
#if PHP_MAJOR_VERSION < 7 |
|
|
|
|
MAKE_STD_ZVAL(field_hashtable_value); |
|
|
|
|
ZVAL_OBJ(field_hashtable_value, field_descriptor_type->create_object( |
|
|
|
|
field_descriptor_type TSRMLS_CC)); |
|
|
|
|
#else |
|
|
|
|
field_hashtable_value = |
|
|
|
|
field_descriptor_type->create_object(field_descriptor_type TSRMLS_CC); |
|
|
|
|
#endif |
|
|
|
|
FieldDescriptor *field_php = |
|
|
|
|
UNBOX_HASHTABLE_VALUE(FieldDescriptor, field_hashtable_value); |
|
|
|
|
field_php->fielddef = field; |
|
|
|
|
add_def_obj(field, field_hashtable_value); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
#if PHP_MAJOR_VERSION < 7 |
|
|
|
|
RETURN_ZVAL(field_hashtable_value, 1, 0); |
|
|
|
|
#else |
|
|
|
|
++GC_REFCOUNT(field_hashtable_value); |
|
|
|
|
RETURN_OBJ(field_hashtable_value); |
|
|
|
|
#endif |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
PHP_METHOD(Oneof, getFieldCount) { |
|
|
|
|
Oneof *intern = UNBOX(Oneof, getThis()); |
|
|
|
|
RETURN_LONG(upb_oneofdef_numfields(intern->oneofdef)); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// -----------------------------------------------------------------------------
|
|
|
|
|
// DescriptorPool
|
|
|
|
|
// -----------------------------------------------------------------------------
|
|
|
|
@ -279,52 +630,79 @@ upb_fieldtype_t to_fieldtype(upb_descriptortype_t type) { |
|
|
|
|
static zend_function_entry descriptor_pool_methods[] = { |
|
|
|
|
PHP_ME(DescriptorPool, getGeneratedPool, NULL, |
|
|
|
|
ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) |
|
|
|
|
PHP_ME(DescriptorPool, internalAddGeneratedFile, NULL, ZEND_ACC_PUBLIC) |
|
|
|
|
PHP_ME(DescriptorPool, getDescriptorByClassName, NULL, ZEND_ACC_PUBLIC) |
|
|
|
|
PHP_ME(DescriptorPool, getEnumDescriptorByClassName, NULL, ZEND_ACC_PUBLIC) |
|
|
|
|
ZEND_FE_END |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
static zend_function_entry internal_descriptor_pool_methods[] = { |
|
|
|
|
PHP_ME(InternalDescriptorPool, getGeneratedPool, NULL, |
|
|
|
|
ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) |
|
|
|
|
PHP_ME(InternalDescriptorPool, internalAddGeneratedFile, NULL, ZEND_ACC_PUBLIC) |
|
|
|
|
ZEND_FE_END |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
DEFINE_CLASS(DescriptorPool, descriptor_pool, |
|
|
|
|
"Google\\Protobuf\\DescriptorPool"); |
|
|
|
|
DEFINE_CLASS(InternalDescriptorPool, internal_descriptor_pool, |
|
|
|
|
"Google\\Protobuf\\Internal\\DescriptorPool"); |
|
|
|
|
|
|
|
|
|
// wrapper of generated pool
|
|
|
|
|
#if PHP_MAJOR_VERSION < 7 |
|
|
|
|
zval* generated_pool_php; |
|
|
|
|
zval* internal_generated_pool_php; |
|
|
|
|
#else |
|
|
|
|
zend_object *generated_pool_php; |
|
|
|
|
zend_object *internal_generated_pool_php; |
|
|
|
|
#endif |
|
|
|
|
DescriptorPool *generated_pool; // The actual generated pool
|
|
|
|
|
InternalDescriptorPool *generated_pool; // The actual generated pool
|
|
|
|
|
|
|
|
|
|
static void init_generated_pool_once(TSRMLS_D) { |
|
|
|
|
if (generated_pool_php == NULL) { |
|
|
|
|
if (generated_pool == NULL) { |
|
|
|
|
#if PHP_MAJOR_VERSION < 7 |
|
|
|
|
MAKE_STD_ZVAL(generated_pool_php); |
|
|
|
|
MAKE_STD_ZVAL(internal_generated_pool_php); |
|
|
|
|
ZVAL_OBJ(internal_generated_pool_php, |
|
|
|
|
internal_descriptor_pool_type->create_object( |
|
|
|
|
internal_descriptor_pool_type TSRMLS_CC)); |
|
|
|
|
generated_pool = UNBOX(InternalDescriptorPool, internal_generated_pool_php); |
|
|
|
|
ZVAL_OBJ(generated_pool_php, descriptor_pool_type->create_object( |
|
|
|
|
descriptor_pool_type TSRMLS_CC)); |
|
|
|
|
generated_pool = UNBOX(DescriptorPool, generated_pool_php); |
|
|
|
|
#else |
|
|
|
|
internal_generated_pool_php = internal_descriptor_pool_type->create_object( |
|
|
|
|
internal_descriptor_pool_type TSRMLS_CC); |
|
|
|
|
generated_pool = (InternalDescriptorPool *)((char *)internal_generated_pool_php - |
|
|
|
|
XtOffsetOf(InternalDescriptorPool, std)); |
|
|
|
|
generated_pool_php = |
|
|
|
|
descriptor_pool_type->create_object(descriptor_pool_type TSRMLS_CC); |
|
|
|
|
generated_pool = (DescriptorPool *)((char *)generated_pool_php - |
|
|
|
|
XtOffsetOf(DescriptorPool, std)); |
|
|
|
|
#endif |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void descriptor_pool_init_c_instance(DescriptorPool *pool TSRMLS_DC) { |
|
|
|
|
// zend_object_std_init(&pool->std, descriptor_pool_type TSRMLS_CC);
|
|
|
|
|
static void internal_descriptor_pool_init_c_instance( |
|
|
|
|
InternalDescriptorPool *pool TSRMLS_DC) { |
|
|
|
|
pool->symtab = upb_symtab_new(); |
|
|
|
|
|
|
|
|
|
ALLOC_HASHTABLE(pool->pending_list); |
|
|
|
|
zend_hash_init(pool->pending_list, 1, NULL, ZVAL_PTR_DTOR, 0); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void descriptor_pool_free_c(DescriptorPool *pool TSRMLS_DC) { |
|
|
|
|
static void internal_descriptor_pool_free_c( |
|
|
|
|
InternalDescriptorPool *pool TSRMLS_DC) { |
|
|
|
|
upb_symtab_free(pool->symtab); |
|
|
|
|
|
|
|
|
|
zend_hash_destroy(pool->pending_list); |
|
|
|
|
FREE_HASHTABLE(pool->pending_list); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void descriptor_pool_init_c_instance(DescriptorPool *pool TSRMLS_DC) { |
|
|
|
|
assert(generated_pool != NULL); |
|
|
|
|
pool->intern = generated_pool; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void descriptor_pool_free_c(DescriptorPool *pool TSRMLS_DC) { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void validate_enumdef(const upb_enumdef *enumdef) { |
|
|
|
|
// Verify that an entry exists with integer value 0. (This is the default
|
|
|
|
|
// value.)
|
|
|
|
@ -358,6 +736,16 @@ PHP_METHOD(DescriptorPool, getGeneratedPool) { |
|
|
|
|
#endif |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
PHP_METHOD(InternalDescriptorPool, getGeneratedPool) { |
|
|
|
|
init_generated_pool_once(TSRMLS_C); |
|
|
|
|
#if PHP_MAJOR_VERSION < 7 |
|
|
|
|
RETURN_ZVAL(internal_generated_pool_php, 1, 0); |
|
|
|
|
#else |
|
|
|
|
++GC_REFCOUNT(internal_generated_pool_php); |
|
|
|
|
RETURN_OBJ(internal_generated_pool_php); |
|
|
|
|
#endif |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void classname_no_prefix(const char *fullname, const char *package_name, |
|
|
|
|
char *class_name) { |
|
|
|
|
size_t i = 0, j; |
|
|
|
@ -455,7 +843,7 @@ static void convert_to_class_name_inplace(const char *package, |
|
|
|
|
memcpy(classname + i, prefix, prefix_len); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
PHP_METHOD(DescriptorPool, internalAddGeneratedFile) { |
|
|
|
|
PHP_METHOD(InternalDescriptorPool, internalAddGeneratedFile) { |
|
|
|
|
char *data = NULL; |
|
|
|
|
PHP_PROTO_SIZE data_len; |
|
|
|
|
upb_filedef **files; |
|
|
|
@ -466,7 +854,7 @@ PHP_METHOD(DescriptorPool, internalAddGeneratedFile) { |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
DescriptorPool *pool = UNBOX(DescriptorPool, getThis()); |
|
|
|
|
InternalDescriptorPool *pool = UNBOX(InternalDescriptorPool, getThis()); |
|
|
|
|
CHECK_UPB(files = upb_loaddescriptor(data, data_len, &pool, &status), |
|
|
|
|
"Parse binary descriptors to internal descriptors failed"); |
|
|
|
|
|
|
|
|
@ -550,3 +938,77 @@ PHP_METHOD(DescriptorPool, internalAddGeneratedFile) { |
|
|
|
|
upb_filedef_unref(files[0], &pool); |
|
|
|
|
upb_gfree(files); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
PHP_METHOD(DescriptorPool, getDescriptorByClassName) { |
|
|
|
|
DescriptorPool *public_pool = UNBOX(DescriptorPool, getThis()); |
|
|
|
|
InternalDescriptorPool *pool = public_pool->intern; |
|
|
|
|
|
|
|
|
|
char *classname = NULL; |
|
|
|
|
PHP_PROTO_SIZE classname_len; |
|
|
|
|
|
|
|
|
|
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &classname, |
|
|
|
|
&classname_len) == FAILURE) { |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
PHP_PROTO_CE_DECLARE pce; |
|
|
|
|
if (php_proto_zend_lookup_class(classname, classname_len, &pce) == |
|
|
|
|
FAILURE) { |
|
|
|
|
RETURN_NULL(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
PHP_PROTO_HASHTABLE_VALUE desc = get_ce_obj(PHP_PROTO_CE_UNREF(pce)); |
|
|
|
|
if (desc == NULL) { |
|
|
|
|
RETURN_NULL(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
zend_class_entry* instance_ce = HASHTABLE_VALUE_CE(desc); |
|
|
|
|
|
|
|
|
|
if (!instanceof_function(instance_ce, descriptor_type TSRMLS_CC)) { |
|
|
|
|
RETURN_NULL(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
#if PHP_MAJOR_VERSION < 7 |
|
|
|
|
RETURN_ZVAL(desc, 1, 0); |
|
|
|
|
#else |
|
|
|
|
++GC_REFCOUNT(desc); |
|
|
|
|
RETURN_OBJ(desc); |
|
|
|
|
#endif |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
PHP_METHOD(DescriptorPool, getEnumDescriptorByClassName) { |
|
|
|
|
DescriptorPool *public_pool = UNBOX(DescriptorPool, getThis()); |
|
|
|
|
InternalDescriptorPool *pool = public_pool->intern; |
|
|
|
|
|
|
|
|
|
char *classname = NULL; |
|
|
|
|
PHP_PROTO_SIZE classname_len; |
|
|
|
|
|
|
|
|
|
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &classname, |
|
|
|
|
&classname_len) == FAILURE) { |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
PHP_PROTO_CE_DECLARE pce; |
|
|
|
|
if (php_proto_zend_lookup_class(classname, classname_len, &pce) == |
|
|
|
|
FAILURE) { |
|
|
|
|
RETURN_NULL(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
PHP_PROTO_HASHTABLE_VALUE desc = get_ce_obj(PHP_PROTO_CE_UNREF(pce)); |
|
|
|
|
if (desc == NULL) { |
|
|
|
|
RETURN_NULL(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
zend_class_entry* instance_ce = HASHTABLE_VALUE_CE(desc); |
|
|
|
|
|
|
|
|
|
if (!instanceof_function(instance_ce, enum_descriptor_type TSRMLS_CC)) { |
|
|
|
|
RETURN_NULL(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
#if PHP_MAJOR_VERSION < 7 |
|
|
|
|
RETURN_ZVAL(desc, 1, 0); |
|
|
|
|
#else |
|
|
|
|
++GC_REFCOUNT(desc); |
|
|
|
|
RETURN_OBJ(desc); |
|
|
|
|
#endif |
|
|
|
|
} |
|
|
|
|