|  | // Protocol Buffers - Google's data interchange format | 
|  | // Copyright 2008 Google Inc.  All rights reserved. | 
|  | // | 
|  | // Use of this source code is governed by a BSD-style | 
|  | // license that can be found in the LICENSE file or at | 
|  | // https://developers.google.com/open-source/licenses/bsd | 
|  |  | 
|  | #include "def.h" | 
|  |  | 
|  | #include <php.h> | 
|  |  | 
|  | // This is not self-contained: it must be after other Zend includes. | 
|  | #include <Zend/zend_exceptions.h> | 
|  |  | 
|  | #include "names.h" | 
|  | #include "php-upb.h" | 
|  | #include "protobuf.h" | 
|  |  | 
|  | static void CheckUpbStatus(const upb_Status* status, const char* msg) { | 
|  | if (!upb_Status_IsOk(status)) { | 
|  | zend_error(E_ERROR, "%s: %s\n", msg, upb_Status_ErrorMessage(status)); | 
|  | } | 
|  | } | 
|  |  | 
|  | static void FieldDescriptor_FromFieldDef(zval* val, const upb_FieldDef* f); | 
|  |  | 
|  | // We use this for objects that should not be created directly from PHP. | 
|  | static zend_object* CreateHandler_ReturnNull(zend_class_entry* class_type) { | 
|  | return NULL;  // Nobody should call this. | 
|  | } | 
|  |  | 
|  | // clang-format off | 
|  | ZEND_BEGIN_ARG_INFO_EX(arginfo_getByIndex, 0, 0, 1) | 
|  | ZEND_ARG_INFO(0, index) | 
|  | ZEND_END_ARG_INFO() | 
|  | // clang-format on | 
|  |  | 
|  | // ----------------------------------------------------------------------------- | 
|  | // EnumValueDescriptor | 
|  | // ----------------------------------------------------------------------------- | 
|  |  | 
|  | typedef struct { | 
|  | zend_object std; | 
|  | const char* name; | 
|  | int32_t number; | 
|  | } EnumValueDescriptor; | 
|  |  | 
|  | zend_class_entry* EnumValueDescriptor_class_entry; | 
|  | static zend_object_handlers EnumValueDescriptor_object_handlers; | 
|  |  | 
|  | /* | 
|  | * EnumValueDescriptor_Make() | 
|  | * | 
|  | * Function to create an EnumValueDescriptor object from C. | 
|  | */ | 
|  | static void EnumValueDescriptor_Make(zval* val, const char* name, | 
|  | int32_t number) { | 
|  | EnumValueDescriptor* intern = emalloc(sizeof(EnumValueDescriptor)); | 
|  | zend_object_std_init(&intern->std, EnumValueDescriptor_class_entry); | 
|  | intern->std.handlers = &EnumValueDescriptor_object_handlers; | 
|  | intern->name = name; | 
|  | intern->number = number; | 
|  | // Skip object_properties_init(), we don't allow derived classes. | 
|  | ZVAL_OBJ(val, &intern->std); | 
|  | } | 
|  |  | 
|  | /* | 
|  | * EnumValueDescriptor::getName() | 
|  | * | 
|  | * Returns the name for this enum value. | 
|  | */ | 
|  | PHP_METHOD(EnumValueDescriptor, getName) { | 
|  | EnumValueDescriptor* intern = (EnumValueDescriptor*)Z_OBJ_P(getThis()); | 
|  | RETURN_STRING(intern->name); | 
|  | } | 
|  |  | 
|  | /* | 
|  | * EnumValueDescriptor::getNumber() | 
|  | * | 
|  | * Returns the number for this enum value. | 
|  | */ | 
|  | PHP_METHOD(EnumValueDescriptor, getNumber) { | 
|  | EnumValueDescriptor* intern = (EnumValueDescriptor*)Z_OBJ_P(getThis()); | 
|  | RETURN_LONG(intern->number); | 
|  | } | 
|  |  | 
|  | // clang-format off | 
|  | static zend_function_entry EnumValueDescriptor_methods[] = { | 
|  | PHP_ME(EnumValueDescriptor, getName, arginfo_void, ZEND_ACC_PUBLIC) | 
|  | PHP_ME(EnumValueDescriptor, getNumber, arginfo_void, ZEND_ACC_PUBLIC) | 
|  | ZEND_FE_END | 
|  | }; | 
|  | // clang-format on | 
|  |  | 
|  | // ----------------------------------------------------------------------------- | 
|  | // EnumDescriptor | 
|  | // ----------------------------------------------------------------------------- | 
|  |  | 
|  | typedef struct { | 
|  | zend_object std; | 
|  | const upb_EnumDef* enumdef; | 
|  | void* cache_key; | 
|  | } EnumDescriptor; | 
|  |  | 
|  | zend_class_entry* EnumDescriptor_class_entry; | 
|  | static zend_object_handlers EnumDescriptor_object_handlers; | 
|  |  | 
|  | static void EnumDescriptor_destructor(zend_object* obj) { | 
|  | EnumDescriptor* intern = (EnumDescriptor*)obj; | 
|  | ObjCache_Delete(intern->cache_key); | 
|  | } | 
|  |  | 
|  | // Caller owns a ref on the returned zval. | 
|  | static void EnumDescriptor_FromClassEntry(zval* val, zend_class_entry* ce) { | 
|  | // To differentiate enums from classes, we pointer-tag the class entry. | 
|  | void* key = (void*)((uintptr_t)ce | 1); | 
|  | PBPHP_ASSERT(key != ce); | 
|  |  | 
|  | if (ce == NULL) { | 
|  | ZVAL_NULL(val); | 
|  | return; | 
|  | } | 
|  |  | 
|  | if (!ObjCache_Get(key, val)) { | 
|  | const upb_EnumDef* e = NameMap_GetEnum(ce); | 
|  | if (!e) { | 
|  | ZVAL_NULL(val); | 
|  | return; | 
|  | } | 
|  | EnumDescriptor* ret = emalloc(sizeof(EnumDescriptor)); | 
|  | zend_object_std_init(&ret->std, EnumDescriptor_class_entry); | 
|  | ret->std.handlers = &EnumDescriptor_object_handlers; | 
|  | ret->enumdef = e; | 
|  | ret->cache_key = key; | 
|  | ObjCache_Add(key, &ret->std); | 
|  | ZVAL_OBJ(val, &ret->std); | 
|  | } | 
|  | } | 
|  |  | 
|  | // Caller owns a ref on the returned zval. | 
|  | static void EnumDescriptor_FromEnumDef(zval* val, const upb_EnumDef* m) { | 
|  | if (!m) { | 
|  | ZVAL_NULL(val); | 
|  | } else { | 
|  | char* classname = | 
|  | GetPhpClassname(upb_EnumDef_File(m), upb_EnumDef_FullName(m), false); | 
|  | zend_string* str = zend_string_init(classname, strlen(classname), 0); | 
|  | zend_class_entry* ce = zend_lookup_class(str);  // May autoload the class. | 
|  |  | 
|  | zend_string_release(str); | 
|  |  | 
|  | if (!ce) { | 
|  | zend_error(E_ERROR, "Couldn't load generated class %s", classname); | 
|  | } | 
|  |  | 
|  | free(classname); | 
|  | EnumDescriptor_FromClassEntry(val, ce); | 
|  | } | 
|  | } | 
|  |  | 
|  | /* | 
|  | * EnumDescriptor::getValue() | 
|  | * | 
|  | * Returns an EnumValueDescriptor for this index. Note: we are not looking | 
|  | * up by numeric enum value, but by the index in the list of enum values. | 
|  | */ | 
|  | PHP_METHOD(EnumDescriptor, getValue) { | 
|  | EnumDescriptor* intern = (EnumDescriptor*)Z_OBJ_P(getThis()); | 
|  | zend_long index; | 
|  | zval ret; | 
|  |  | 
|  | if (zend_parse_parameters(ZEND_NUM_ARGS(), "l", &index) == FAILURE) { | 
|  | zend_error(E_USER_ERROR, "Expect integer for index.\n"); | 
|  | return; | 
|  | } | 
|  |  | 
|  | if (index < 0 || index >= upb_EnumDef_ValueCount(intern->enumdef)) { | 
|  | zend_error(E_USER_ERROR, "Cannot get element at %ld.\n", index); | 
|  | return; | 
|  | } | 
|  |  | 
|  | const upb_EnumValueDef* ev = upb_EnumDef_Value(intern->enumdef, index); | 
|  | EnumValueDescriptor_Make(&ret, upb_EnumValueDef_Name(ev), | 
|  | upb_EnumValueDef_Number(ev)); | 
|  | RETURN_COPY_VALUE(&ret); | 
|  | } | 
|  |  | 
|  | /* | 
|  | * EnumDescriptor::getValueCount() | 
|  | * | 
|  | * Returns the number of values in this enum. | 
|  | */ | 
|  | PHP_METHOD(EnumDescriptor, getValueCount) { | 
|  | EnumDescriptor* intern = (EnumDescriptor*)Z_OBJ_P(getThis()); | 
|  | RETURN_LONG(upb_EnumDef_ValueCount(intern->enumdef)); | 
|  | } | 
|  |  | 
|  | /* | 
|  | * EnumDescriptor::getPublicDescriptor() | 
|  | * | 
|  | * Returns this EnumDescriptor. Unlike the pure-PHP descriptor, we do not | 
|  | * have two separate EnumDescriptor classes. We use a single class for both | 
|  | * the public and private descriptor. | 
|  | */ | 
|  | PHP_METHOD(EnumDescriptor, getPublicDescriptor) { RETURN_COPY(getThis()); } | 
|  |  | 
|  | // clang-format off | 
|  | static zend_function_entry EnumDescriptor_methods[] = { | 
|  | PHP_ME(EnumDescriptor, getPublicDescriptor, arginfo_void, ZEND_ACC_PUBLIC) | 
|  | PHP_ME(EnumDescriptor, getValueCount, arginfo_void, ZEND_ACC_PUBLIC) | 
|  | PHP_ME(EnumDescriptor, getValue, arginfo_getByIndex, ZEND_ACC_PUBLIC) | 
|  | ZEND_FE_END | 
|  | }; | 
|  | // clang-format on | 
|  |  | 
|  | // ----------------------------------------------------------------------------- | 
|  | // Oneof | 
|  | // ----------------------------------------------------------------------------- | 
|  |  | 
|  | typedef struct { | 
|  | zend_object std; | 
|  | const upb_OneofDef* oneofdef; | 
|  | } OneofDescriptor; | 
|  |  | 
|  | zend_class_entry* OneofDescriptor_class_entry; | 
|  | static zend_object_handlers OneofDescriptor_object_handlers; | 
|  |  | 
|  | static void OneofDescriptor_destructor(zend_object* obj) { | 
|  | OneofDescriptor* intern = (OneofDescriptor*)obj; | 
|  | ObjCache_Delete(intern->oneofdef); | 
|  | } | 
|  |  | 
|  | static void OneofDescriptor_FromOneofDef(zval* val, const upb_OneofDef* o) { | 
|  | if (o == NULL) { | 
|  | ZVAL_NULL(val); | 
|  | return; | 
|  | } | 
|  |  | 
|  | if (!ObjCache_Get(o, val)) { | 
|  | OneofDescriptor* ret = emalloc(sizeof(OneofDescriptor)); | 
|  | zend_object_std_init(&ret->std, OneofDescriptor_class_entry); | 
|  | ret->std.handlers = &OneofDescriptor_object_handlers; | 
|  | ret->oneofdef = o; | 
|  | ObjCache_Add(o, &ret->std); | 
|  | ZVAL_OBJ(val, &ret->std); | 
|  | } | 
|  | } | 
|  |  | 
|  | /* | 
|  | * OneofDescriptor::getName() | 
|  | * | 
|  | * Returns the name of this oneof. | 
|  | */ | 
|  | PHP_METHOD(OneofDescriptor, getName) { | 
|  | OneofDescriptor* intern = (OneofDescriptor*)Z_OBJ_P(getThis()); | 
|  | RETURN_STRING(upb_OneofDef_Name(intern->oneofdef)); | 
|  | } | 
|  |  | 
|  | /* | 
|  | * OneofDescriptor::getField() | 
|  | * | 
|  | * Returns a field from this oneof. The given index must be in the range | 
|  | *   [0, getFieldCount() - 1]. | 
|  | */ | 
|  | PHP_METHOD(OneofDescriptor, getField) { | 
|  | OneofDescriptor* intern = (OneofDescriptor*)Z_OBJ_P(getThis()); | 
|  | zend_long index; | 
|  | zval ret; | 
|  |  | 
|  | if (zend_parse_parameters(ZEND_NUM_ARGS(), "l", &index) == FAILURE) { | 
|  | zend_error(E_USER_ERROR, "Expect integer for index.\n"); | 
|  | return; | 
|  | } | 
|  |  | 
|  | if (index < 0 || index >= upb_OneofDef_FieldCount(intern->oneofdef)) { | 
|  | zend_error(E_USER_ERROR, "Cannot get element at %ld.\n", index); | 
|  | return; | 
|  | } | 
|  |  | 
|  | const upb_FieldDef* field = upb_OneofDef_Field(intern->oneofdef, index); | 
|  | FieldDescriptor_FromFieldDef(&ret, field); | 
|  | RETURN_COPY_VALUE(&ret); | 
|  | } | 
|  |  | 
|  | /* | 
|  | * OneofDescriptor::getFieldCount() | 
|  | * | 
|  | * Returns the number of fields in this oneof. | 
|  | */ | 
|  | PHP_METHOD(OneofDescriptor, getFieldCount) { | 
|  | OneofDescriptor* intern = (OneofDescriptor*)Z_OBJ_P(getThis()); | 
|  | RETURN_LONG(upb_OneofDef_FieldCount(intern->oneofdef)); | 
|  | } | 
|  |  | 
|  | // clang-format off | 
|  | static zend_function_entry OneofDescriptor_methods[] = { | 
|  | PHP_ME(OneofDescriptor, getName,  arginfo_void, ZEND_ACC_PUBLIC) | 
|  | PHP_ME(OneofDescriptor, getField, arginfo_getByIndex, ZEND_ACC_PUBLIC) | 
|  | PHP_ME(OneofDescriptor, getFieldCount, arginfo_void, ZEND_ACC_PUBLIC) | 
|  | ZEND_FE_END | 
|  | }; | 
|  | // clang-format on | 
|  |  | 
|  | // ----------------------------------------------------------------------------- | 
|  | // FieldDescriptor | 
|  | // ----------------------------------------------------------------------------- | 
|  |  | 
|  | typedef struct { | 
|  | zend_object std; | 
|  | const upb_FieldDef* fielddef; | 
|  | } FieldDescriptor; | 
|  |  | 
|  | zend_class_entry* FieldDescriptor_class_entry; | 
|  | static zend_object_handlers FieldDescriptor_object_handlers; | 
|  |  | 
|  | static void FieldDescriptor_destructor(zend_object* obj) { | 
|  | FieldDescriptor* intern = (FieldDescriptor*)obj; | 
|  | ObjCache_Delete(intern->fielddef); | 
|  | } | 
|  |  | 
|  | // Caller owns a ref on the returned zval. | 
|  | static void FieldDescriptor_FromFieldDef(zval* val, const upb_FieldDef* f) { | 
|  | if (f == NULL) { | 
|  | ZVAL_NULL(val); | 
|  | return; | 
|  | } | 
|  |  | 
|  | if (!ObjCache_Get(f, val)) { | 
|  | FieldDescriptor* ret = emalloc(sizeof(FieldDescriptor)); | 
|  | zend_object_std_init(&ret->std, FieldDescriptor_class_entry); | 
|  | ret->std.handlers = &FieldDescriptor_object_handlers; | 
|  | ret->fielddef = f; | 
|  | ObjCache_Add(f, &ret->std); | 
|  | ZVAL_OBJ(val, &ret->std); | 
|  | } | 
|  | } | 
|  |  | 
|  | upb_CType to_fieldtype(upb_FieldType type) { | 
|  | switch (type) { | 
|  | #define CASE(descriptor_type, type)      \ | 
|  | case kUpb_FieldType_##descriptor_type: \ | 
|  | return kUpb_CType_##type; | 
|  |  | 
|  | CASE(Float, Float); | 
|  | CASE(Double, Double); | 
|  | CASE(Bool, Bool); | 
|  | CASE(String, String); | 
|  | CASE(Bytes, Bytes); | 
|  | CASE(Message, Message); | 
|  | CASE(Group, Message); | 
|  | CASE(Enum, Enum); | 
|  | CASE(Int32, Int32); | 
|  | CASE(Int64, Int64); | 
|  | CASE(UInt32, UInt32); | 
|  | CASE(UInt64, UInt64); | 
|  | CASE(SInt32, Int32); | 
|  | CASE(SInt64, Int64); | 
|  | CASE(Fixed32, UInt32); | 
|  | CASE(Fixed64, UInt64); | 
|  | CASE(SFixed32, Int32); | 
|  | CASE(SFixed64, Int64); | 
|  |  | 
|  | #undef CONVERT | 
|  | } | 
|  |  | 
|  | zend_error(E_ERROR, "Unknown field type."); | 
|  | return 0; | 
|  | } | 
|  |  | 
|  | /* | 
|  | * FieldDescriptor::getName() | 
|  | * | 
|  | * Returns the name of this field. | 
|  | */ | 
|  | PHP_METHOD(FieldDescriptor, getName) { | 
|  | FieldDescriptor* intern = (FieldDescriptor*)Z_OBJ_P(getThis()); | 
|  | RETURN_STRING(upb_FieldDef_Name(intern->fielddef)); | 
|  | } | 
|  |  | 
|  | /* | 
|  | * FieldDescriptor::getNumber() | 
|  | * | 
|  | * Returns the number of this field. | 
|  | */ | 
|  | PHP_METHOD(FieldDescriptor, getNumber) { | 
|  | FieldDescriptor* intern = (FieldDescriptor*)Z_OBJ_P(getThis()); | 
|  | RETURN_LONG(upb_FieldDef_Number(intern->fielddef)); | 
|  | } | 
|  |  | 
|  | /* | 
|  | * FieldDescriptor::getLabel() | 
|  | * | 
|  | * Returns the label of this field as an integer. | 
|  | */ | 
|  | PHP_METHOD(FieldDescriptor, getLabel) { | 
|  | FieldDescriptor* intern = (FieldDescriptor*)Z_OBJ_P(getThis()); | 
|  | RETURN_LONG(upb_FieldDef_Label(intern->fielddef)); | 
|  | } | 
|  |  | 
|  | /* | 
|  | * FieldDescriptor::getType() | 
|  | * | 
|  | * Returns the type of this field as an integer. | 
|  | */ | 
|  | PHP_METHOD(FieldDescriptor, getType) { | 
|  | FieldDescriptor* intern = (FieldDescriptor*)Z_OBJ_P(getThis()); | 
|  | RETURN_LONG(upb_FieldDef_Type(intern->fielddef)); | 
|  | } | 
|  |  | 
|  | /* | 
|  | * FieldDescriptor::isMap() | 
|  | * | 
|  | * Returns true if this field is a map. | 
|  | */ | 
|  | PHP_METHOD(FieldDescriptor, isMap) { | 
|  | FieldDescriptor* intern = (FieldDescriptor*)Z_OBJ_P(getThis()); | 
|  | RETURN_BOOL(upb_FieldDef_IsMap(intern->fielddef)); | 
|  | } | 
|  |  | 
|  | /* | 
|  | * FieldDescriptor::getEnumType() | 
|  | * | 
|  | * Returns the EnumDescriptor for this field, which must be an enum. | 
|  | */ | 
|  | PHP_METHOD(FieldDescriptor, getEnumType) { | 
|  | FieldDescriptor* intern = (FieldDescriptor*)Z_OBJ_P(getThis()); | 
|  | const upb_EnumDef* e = upb_FieldDef_EnumSubDef(intern->fielddef); | 
|  | zval ret; | 
|  |  | 
|  | if (!e) { | 
|  | zend_throw_exception_ex(NULL, 0, | 
|  | "Cannot get enum type for non-enum field '%s'", | 
|  | upb_FieldDef_Name(intern->fielddef)); | 
|  | return; | 
|  | } | 
|  |  | 
|  | EnumDescriptor_FromEnumDef(&ret, e); | 
|  | RETURN_COPY_VALUE(&ret); | 
|  | } | 
|  |  | 
|  | /* | 
|  | * FieldDescriptor::getContainingOneof() | 
|  | * | 
|  | * Returns the OneofDescriptor for this field, or null if it is not inside | 
|  | * a oneof. | 
|  | */ | 
|  | PHP_METHOD(FieldDescriptor, getContainingOneof) { | 
|  | FieldDescriptor* intern = (FieldDescriptor*)Z_OBJ_P(getThis()); | 
|  | const upb_OneofDef* o = upb_FieldDef_ContainingOneof(intern->fielddef); | 
|  | zval ret; | 
|  |  | 
|  | if (!o) { | 
|  | RETURN_NULL(); | 
|  | } | 
|  |  | 
|  | OneofDescriptor_FromOneofDef(&ret, o); | 
|  | RETURN_COPY_VALUE(&ret); | 
|  | } | 
|  |  | 
|  | /* | 
|  | * FieldDescriptor::getRealContainingOneof() | 
|  | * | 
|  | * Returns the non-synthetic OneofDescriptor for this field, or null if it is | 
|  | * not inside a oneof. | 
|  | */ | 
|  | PHP_METHOD(FieldDescriptor, getRealContainingOneof) { | 
|  | FieldDescriptor* intern = (FieldDescriptor*)Z_OBJ_P(getThis()); | 
|  | const upb_OneofDef* o = upb_FieldDef_RealContainingOneof(intern->fielddef); | 
|  | zval ret; | 
|  |  | 
|  | if (!o) { | 
|  | RETURN_NULL(); | 
|  | } | 
|  |  | 
|  | OneofDescriptor_FromOneofDef(&ret, o); | 
|  | RETURN_COPY_VALUE(&ret); | 
|  | } | 
|  |  | 
|  | /* | 
|  | * FieldDescriptor::getMessageType() | 
|  | * | 
|  | * Returns the Descriptor for this field, which must be a message. | 
|  | */ | 
|  | PHP_METHOD(FieldDescriptor, getMessageType) { | 
|  | FieldDescriptor* intern = (FieldDescriptor*)Z_OBJ_P(getThis()); | 
|  | Descriptor* desc = Descriptor_GetFromFieldDef(intern->fielddef); | 
|  |  | 
|  | if (!desc) { | 
|  | zend_throw_exception_ex( | 
|  | NULL, 0, "Cannot get message type for non-message field '%s'", | 
|  | upb_FieldDef_Name(intern->fielddef)); | 
|  | return; | 
|  | } | 
|  |  | 
|  | RETURN_OBJ_COPY(&desc->std); | 
|  | } | 
|  |  | 
|  | // clang-format off | 
|  | static zend_function_entry FieldDescriptor_methods[] = { | 
|  | PHP_ME(FieldDescriptor, getName,   arginfo_void, ZEND_ACC_PUBLIC) | 
|  | PHP_ME(FieldDescriptor, getNumber, arginfo_void, ZEND_ACC_PUBLIC) | 
|  | PHP_ME(FieldDescriptor, getLabel,  arginfo_void, ZEND_ACC_PUBLIC) | 
|  | PHP_ME(FieldDescriptor, getType,   arginfo_void, ZEND_ACC_PUBLIC) | 
|  | PHP_ME(FieldDescriptor, isMap,     arginfo_void, ZEND_ACC_PUBLIC) | 
|  | PHP_ME(FieldDescriptor, getEnumType, arginfo_void, ZEND_ACC_PUBLIC) | 
|  | PHP_ME(FieldDescriptor, getContainingOneof, arginfo_void, ZEND_ACC_PUBLIC) | 
|  | PHP_ME(FieldDescriptor, getRealContainingOneof, arginfo_void, ZEND_ACC_PUBLIC) | 
|  | PHP_ME(FieldDescriptor, getMessageType, arginfo_void, ZEND_ACC_PUBLIC) | 
|  | ZEND_FE_END | 
|  | }; | 
|  | // clang-format on | 
|  |  | 
|  | // ----------------------------------------------------------------------------- | 
|  | // Descriptor | 
|  | // ----------------------------------------------------------------------------- | 
|  |  | 
|  | zend_class_entry* Descriptor_class_entry; | 
|  | static zend_object_handlers Descriptor_object_handlers; | 
|  |  | 
|  | static void Descriptor_destructor(zend_object* obj) { | 
|  | // We don't really need to do anything here, we don't allow this to be | 
|  | // collected before the end of the request. | 
|  | } | 
|  |  | 
|  | static zend_class_entry* Descriptor_GetGeneratedClass(const upb_MessageDef* m) { | 
|  | for (int i = 0; i < 2; ++i) { | 
|  | char* classname = GetPhpClassname(upb_MessageDef_File(m), | 
|  | upb_MessageDef_FullName(m), (bool)i); | 
|  | zend_string* str = zend_string_init(classname, strlen(classname), 0); | 
|  | zend_class_entry* ce = zend_lookup_class(str);  // May autoload the class. | 
|  |  | 
|  | zend_string_release(str); | 
|  | free(classname); | 
|  |  | 
|  | if (ce) { | 
|  | return ce; | 
|  | } | 
|  | } | 
|  |  | 
|  | char* classname = GetPhpClassname(upb_MessageDef_File(m), | 
|  | upb_MessageDef_FullName(m), false); | 
|  | zend_error(E_ERROR, "Couldn't load generated class %s", classname); | 
|  | return NULL; | 
|  | } | 
|  |  | 
|  | void Descriptor_FromMessageDef(zval* val, const upb_MessageDef* m) { | 
|  | if (m == NULL) { | 
|  | ZVAL_NULL(val); | 
|  | return; | 
|  | } | 
|  |  | 
|  | if (!ObjCache_Get(m, val)) { | 
|  | zend_class_entry* ce = NULL; | 
|  | if (!upb_MessageDef_IsMapEntry(m)) {  // Map entries don't have a class. | 
|  | ce = Descriptor_GetGeneratedClass(m); | 
|  | if (!ce) { | 
|  | ZVAL_NULL(val); | 
|  | return; | 
|  | } | 
|  | } | 
|  | Descriptor* ret = emalloc(sizeof(Descriptor)); | 
|  | zend_object_std_init(&ret->std, Descriptor_class_entry); | 
|  | ret->std.handlers = &Descriptor_object_handlers; | 
|  | ret->class_entry = ce; | 
|  | ret->msgdef = m; | 
|  | ObjCache_Add(m, &ret->std); | 
|  | Descriptors_Add(&ret->std); | 
|  | ZVAL_OBJ(val, &ret->std); | 
|  | } | 
|  | } | 
|  |  | 
|  | static void Descriptor_FromClassEntry(zval* val, zend_class_entry* ce) { | 
|  | if (ce) { | 
|  | Descriptor_FromMessageDef(val, NameMap_GetMessage(ce)); | 
|  | } else { | 
|  | ZVAL_NULL(val); | 
|  | } | 
|  | } | 
|  |  | 
|  | static Descriptor* Descriptor_GetFromZval(zval* val) { | 
|  | if (Z_TYPE_P(val) == IS_NULL) { | 
|  | return NULL; | 
|  | } else { | 
|  | zend_object* ret = Z_OBJ_P(val); | 
|  | zval_ptr_dtor(val); | 
|  | return (Descriptor*)ret; | 
|  | } | 
|  | } | 
|  |  | 
|  | // C Functions from def.h ////////////////////////////////////////////////////// | 
|  |  | 
|  | // These are documented in the header file. | 
|  |  | 
|  | Descriptor* Descriptor_GetFromClassEntry(zend_class_entry* ce) { | 
|  | zval desc; | 
|  | Descriptor_FromClassEntry(&desc, ce); | 
|  | return Descriptor_GetFromZval(&desc); | 
|  | } | 
|  |  | 
|  | Descriptor* Descriptor_GetFromMessageDef(const upb_MessageDef* m) { | 
|  | zval desc; | 
|  | Descriptor_FromMessageDef(&desc, m); | 
|  | return Descriptor_GetFromZval(&desc); | 
|  | } | 
|  |  | 
|  | Descriptor* Descriptor_GetFromFieldDef(const upb_FieldDef* f) { | 
|  | return Descriptor_GetFromMessageDef(upb_FieldDef_MessageSubDef(f)); | 
|  | } | 
|  |  | 
|  | /* | 
|  | * Descriptor::getPublicDescriptor() | 
|  | * | 
|  | * Returns this EnumDescriptor. Unlike the pure-PHP descriptor, we do not | 
|  | * have two separate EnumDescriptor classes. We use a single class for both | 
|  | * the public and private descriptor. | 
|  | */ | 
|  | PHP_METHOD(Descriptor, getPublicDescriptor) { RETURN_COPY(getThis()); } | 
|  |  | 
|  | /* | 
|  | * Descriptor::getFullName() | 
|  | * | 
|  | * Returns the full name for this message type. | 
|  | */ | 
|  | PHP_METHOD(Descriptor, getFullName) { | 
|  | Descriptor* intern = (Descriptor*)Z_OBJ_P(getThis()); | 
|  | RETURN_STRING(upb_MessageDef_FullName(intern->msgdef)); | 
|  | } | 
|  |  | 
|  | /* | 
|  | * Descriptor::getField() | 
|  | * | 
|  | * Returns a FieldDescriptor for the given index, which must be in the range | 
|  | * [0, getFieldCount()-1]. | 
|  | */ | 
|  | PHP_METHOD(Descriptor, getField) { | 
|  | Descriptor* intern = (Descriptor*)Z_OBJ_P(getThis()); | 
|  | int count = upb_MessageDef_FieldCount(intern->msgdef); | 
|  | zval ret; | 
|  | zend_long index; | 
|  |  | 
|  | if (zend_parse_parameters(ZEND_NUM_ARGS(), "l", &index) == FAILURE) { | 
|  | zend_error(E_USER_ERROR, "Expect integer for index.\n"); | 
|  | return; | 
|  | } | 
|  |  | 
|  | if (index < 0 || index >= count) { | 
|  | zend_error(E_USER_ERROR, "Cannot get element at %ld.\n", index); | 
|  | return; | 
|  | } | 
|  |  | 
|  | FieldDescriptor_FromFieldDef(&ret, | 
|  | upb_MessageDef_Field(intern->msgdef, index)); | 
|  | RETURN_COPY_VALUE(&ret); | 
|  | } | 
|  |  | 
|  | /* | 
|  | * Descriptor::getFieldCount() | 
|  | * | 
|  | * Returns the number of fields in this message. | 
|  | */ | 
|  | PHP_METHOD(Descriptor, getFieldCount) { | 
|  | Descriptor* intern = (Descriptor*)Z_OBJ_P(getThis()); | 
|  | RETURN_LONG(upb_MessageDef_FieldCount(intern->msgdef)); | 
|  | } | 
|  |  | 
|  | /* | 
|  | * Descriptor::getOneofDecl() | 
|  | * | 
|  | * Returns a OneofDescriptor for the given index, which must be in the range | 
|  | * [0, getOneofDeclCount()]. | 
|  | */ | 
|  | PHP_METHOD(Descriptor, getOneofDecl) { | 
|  | Descriptor* intern = (Descriptor*)Z_OBJ_P(getThis()); | 
|  | zend_long index; | 
|  | zval ret; | 
|  |  | 
|  | if (zend_parse_parameters(ZEND_NUM_ARGS(), "l", &index) == FAILURE) { | 
|  | zend_error(E_USER_ERROR, "Expect integer for index.\n"); | 
|  | return; | 
|  | } | 
|  |  | 
|  | if (index < 0 || index >= upb_MessageDef_OneofCount(intern->msgdef)) { | 
|  | zend_error(E_USER_ERROR, "Cannot get element at %ld.\n", index); | 
|  | return; | 
|  | } | 
|  |  | 
|  | OneofDescriptor_FromOneofDef(&ret, | 
|  | upb_MessageDef_Oneof(intern->msgdef, index)); | 
|  | RETURN_COPY_VALUE(&ret); | 
|  | } | 
|  |  | 
|  | /* | 
|  | * Descriptor::getOneofDeclCount() | 
|  | * | 
|  | * Returns the number of oneofs in this message. | 
|  | */ | 
|  | PHP_METHOD(Descriptor, getOneofDeclCount) { | 
|  | Descriptor* intern = (Descriptor*)Z_OBJ_P(getThis()); | 
|  | RETURN_LONG(upb_MessageDef_OneofCount(intern->msgdef)); | 
|  | } | 
|  |  | 
|  | /* | 
|  | * Descriptor::getClass() | 
|  | * | 
|  | * Returns the name of the PHP class for this message. | 
|  | */ | 
|  | PHP_METHOD(Descriptor, getClass) { | 
|  | Descriptor* intern = (Descriptor*)Z_OBJ_P(getThis()); | 
|  | const char* classname = ZSTR_VAL(intern->class_entry->name); | 
|  | RETURN_STRING(classname); | 
|  | } | 
|  |  | 
|  | // clang-format off | 
|  | static zend_function_entry Descriptor_methods[] = { | 
|  | PHP_ME(Descriptor, getClass, arginfo_void, ZEND_ACC_PUBLIC) | 
|  | PHP_ME(Descriptor, getFullName, arginfo_void, ZEND_ACC_PUBLIC) | 
|  | PHP_ME(Descriptor, getField, arginfo_getByIndex, ZEND_ACC_PUBLIC) | 
|  | PHP_ME(Descriptor, getFieldCount, arginfo_void, ZEND_ACC_PUBLIC) | 
|  | PHP_ME(Descriptor, getOneofDecl, arginfo_getByIndex, ZEND_ACC_PUBLIC) | 
|  | PHP_ME(Descriptor, getOneofDeclCount, arginfo_void, ZEND_ACC_PUBLIC) | 
|  | PHP_ME(Descriptor, getPublicDescriptor, arginfo_void, ZEND_ACC_PUBLIC) | 
|  | ZEND_FE_END | 
|  | }; | 
|  | // clang-format on | 
|  |  | 
|  | // ----------------------------------------------------------------------------- | 
|  | // DescriptorPool | 
|  | // ----------------------------------------------------------------------------- | 
|  |  | 
|  | typedef struct DescriptorPool { | 
|  | zend_object std; | 
|  | upb_DefPool* symtab; | 
|  | } DescriptorPool; | 
|  |  | 
|  | zend_class_entry* DescriptorPool_class_entry; | 
|  | static zend_object_handlers DescriptorPool_object_handlers; | 
|  |  | 
|  | static DescriptorPool* GetPool(const zval* this_ptr) { | 
|  | return (DescriptorPool*)Z_OBJ_P(this_ptr); | 
|  | } | 
|  |  | 
|  | /** | 
|  | * Object handler to free an DescriptorPool. | 
|  | */ | 
|  | static void DescriptorPool_destructor(zend_object* obj) { | 
|  | DescriptorPool* intern = (DescriptorPool*)obj; | 
|  |  | 
|  | // We can't free our underlying symtab here, because user code may create | 
|  | // messages from destructors that will refer to it. The symtab will be freed | 
|  | // by our RSHUTDOWN() handler in protobuf.c | 
|  |  | 
|  | zend_object_std_dtor(&intern->std); | 
|  | } | 
|  |  | 
|  | void DescriptorPool_CreateWithSymbolTable(zval* zv, upb_DefPool* symtab) { | 
|  | DescriptorPool* intern = emalloc(sizeof(DescriptorPool)); | 
|  | zend_object_std_init(&intern->std, DescriptorPool_class_entry); | 
|  | intern->std.handlers = &DescriptorPool_object_handlers; | 
|  | intern->symtab = symtab; | 
|  |  | 
|  | ZVAL_OBJ(zv, &intern->std); | 
|  | } | 
|  |  | 
|  | upb_DefPool* DescriptorPool_GetSymbolTable() { return get_global_symtab(); } | 
|  |  | 
|  | /* | 
|  | * DescriptorPool::getGeneratedPool() | 
|  | * | 
|  | * Returns the generated DescriptorPool. | 
|  | */ | 
|  | PHP_METHOD(DescriptorPool, getGeneratedPool) { | 
|  | DescriptorPool_CreateWithSymbolTable(return_value, get_global_symtab()); | 
|  | } | 
|  |  | 
|  | /* | 
|  | * DescriptorPool::getDescriptorByClassName() | 
|  | * | 
|  | * Returns a Descriptor object for the given PHP class name. | 
|  | */ | 
|  | PHP_METHOD(DescriptorPool, getDescriptorByClassName) { | 
|  | char* classname = NULL; | 
|  | zend_long classname_len; | 
|  | zend_class_entry* ce; | 
|  | zend_string* str; | 
|  | zval ret; | 
|  |  | 
|  | if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", &classname, &classname_len) == | 
|  | FAILURE) { | 
|  | return; | 
|  | } | 
|  |  | 
|  | str = zend_string_init(classname, strlen(classname), 0); | 
|  | ce = zend_lookup_class(str);  // May autoload the class. | 
|  | zend_string_release(str); | 
|  |  | 
|  | if (!ce) { | 
|  | RETURN_NULL(); | 
|  | } | 
|  |  | 
|  | Descriptor_FromClassEntry(&ret, ce); | 
|  | RETURN_COPY_VALUE(&ret); | 
|  | } | 
|  |  | 
|  | /* | 
|  | * DescriptorPool::getEnumDescriptorByClassName() | 
|  | * | 
|  | * Returns a EnumDescriptor object for the given PHP class name. | 
|  | */ | 
|  | PHP_METHOD(DescriptorPool, getEnumDescriptorByClassName) { | 
|  | char* classname = NULL; | 
|  | zend_long classname_len; | 
|  | zend_class_entry* ce; | 
|  | zend_string* str; | 
|  | zval ret; | 
|  |  | 
|  | if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", &classname, &classname_len) == | 
|  | FAILURE) { | 
|  | return; | 
|  | } | 
|  |  | 
|  | str = zend_string_init(classname, strlen(classname), 0); | 
|  | ce = zend_lookup_class(str);  // May autoload the class. | 
|  | zend_string_release(str); | 
|  |  | 
|  | if (!ce) { | 
|  | RETURN_NULL(); | 
|  | } | 
|  |  | 
|  | EnumDescriptor_FromClassEntry(&ret, ce); | 
|  | RETURN_COPY_VALUE(&ret); | 
|  | } | 
|  |  | 
|  | /* | 
|  | * DescriptorPool::getEnumDescriptorByProtoName() | 
|  | * | 
|  | * Returns a Descriptor object for the given protobuf message name. | 
|  | */ | 
|  | PHP_METHOD(DescriptorPool, getDescriptorByProtoName) { | 
|  | DescriptorPool* intern = GetPool(getThis()); | 
|  | char* protoname = NULL; | 
|  | zend_long protoname_len; | 
|  | const upb_MessageDef* m; | 
|  |  | 
|  | if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", &protoname, &protoname_len) == | 
|  | FAILURE) { | 
|  | return; | 
|  | } | 
|  |  | 
|  | if (*protoname == '.') protoname++; | 
|  |  | 
|  | m = upb_DefPool_FindMessageByName(intern->symtab, protoname); | 
|  |  | 
|  | if (m) { | 
|  | RETURN_OBJ_COPY(&Descriptor_GetFromMessageDef(m)->std); | 
|  | } else { | 
|  | RETURN_NULL(); | 
|  | } | 
|  | } | 
|  |  | 
|  | /* | 
|  | * depends_on_descriptor() | 
|  | * | 
|  | * Returns true if this FileDescriptorProto depends on descriptor.proto. | 
|  | */ | 
|  | bool depends_on_descriptor(const google_protobuf_FileDescriptorProto* file) { | 
|  | const upb_StringView* deps; | 
|  | upb_StringView name = | 
|  | upb_StringView_FromString("google/protobuf/descriptor.proto"); | 
|  | size_t i, n; | 
|  |  | 
|  | deps = google_protobuf_FileDescriptorProto_dependency(file, &n); | 
|  | for (i = 0; i < n; i++) { | 
|  | if (upb_StringView_IsEqual(deps[i], name)) { | 
|  | return true; | 
|  | } | 
|  | } | 
|  |  | 
|  | return false; | 
|  | } | 
|  |  | 
|  | static void add_message_name_mappings(const upb_MessageDef* message) { | 
|  | NameMap_AddMessage(message); | 
|  | int msg_n = upb_MessageDef_NestedMessageCount(message); | 
|  | for (int i = 0; i < msg_n; i++) { | 
|  | add_message_name_mappings(upb_MessageDef_NestedMessage(message, i)); | 
|  | } | 
|  | int enum_n = upb_MessageDef_NestedEnumCount(message); | 
|  | for (int i = 0; i < enum_n; i++) { | 
|  | NameMap_AddEnum(upb_MessageDef_NestedEnum(message, i)); | 
|  | } | 
|  | } | 
|  |  | 
|  | /* | 
|  | * add_name_mappings() | 
|  | * | 
|  | * Adds the messages and enums in this file to the NameMap. | 
|  | */ | 
|  | static void add_name_mappings(const upb_FileDef* file) { | 
|  | for (int i = 0; i < upb_FileDef_TopLevelMessageCount(file); i++) { | 
|  | add_message_name_mappings(upb_FileDef_TopLevelMessage(file, i)); | 
|  | } | 
|  |  | 
|  | for (int i = 0; i < upb_FileDef_TopLevelEnumCount(file); i++) { | 
|  | NameMap_AddEnum(upb_FileDef_TopLevelEnum(file, i)); | 
|  | } | 
|  | } | 
|  |  | 
|  | static void add_descriptor(upb_DefPool* symtab, | 
|  | const google_protobuf_FileDescriptorProto* file) { | 
|  | upb_StringView name = google_protobuf_FileDescriptorProto_name(file); | 
|  | upb_Status status; | 
|  | const upb_FileDef* file_def; | 
|  | upb_Status_Clear(&status); | 
|  |  | 
|  | if (upb_DefPool_FindFileByNameWithSize(symtab, name.data, name.size)) { | 
|  | // Already added. | 
|  | // TODO: Re-enable this warning when aggregate metadata is | 
|  | // deprecated. | 
|  | // zend_error(E_USER_WARNING, | 
|  | //            "proto descriptor was previously loaded (included in multiple | 
|  | //            " "metadata bundles?): " UPB_STRINGVIEW_FORMAT, | 
|  | //            UPB_STRINGVIEW_ARGS(name)); | 
|  | return; | 
|  | } | 
|  |  | 
|  | // The PHP code generator currently special-cases descriptor.proto.  It | 
|  | // doesn't add it as a dependency even if the proto file actually does | 
|  | // depend on it. | 
|  | if (depends_on_descriptor(file)) { | 
|  | google_protobuf_FileDescriptorProto_getmsgdef(symtab); | 
|  | } | 
|  |  | 
|  | file_def = upb_DefPool_AddFile(symtab, file, &status); | 
|  | CheckUpbStatus(&status, "Unable to load descriptor"); | 
|  | add_name_mappings(file_def); | 
|  | } | 
|  |  | 
|  | /* | 
|  | * add_descriptor() | 
|  | * | 
|  | * Adds the given descriptor data to this DescriptorPool. | 
|  | */ | 
|  | static void add_descriptor_set(upb_DefPool* symtab, const char* data, | 
|  | int data_len, upb_Arena* arena) { | 
|  | size_t i, n; | 
|  | google_protobuf_FileDescriptorSet* set; | 
|  | const google_protobuf_FileDescriptorProto* const* files; | 
|  |  | 
|  | set = google_protobuf_FileDescriptorSet_parse(data, data_len, arena); | 
|  |  | 
|  | if (!set) { | 
|  | zend_error(E_ERROR, "Failed to parse binary descriptor\n"); | 
|  | return; | 
|  | } | 
|  |  | 
|  | files = google_protobuf_FileDescriptorSet_file(set, &n); | 
|  |  | 
|  | for (i = 0; i < n; i++) { | 
|  | const google_protobuf_FileDescriptorProto* file = files[i]; | 
|  | add_descriptor(symtab, file); | 
|  | } | 
|  | } | 
|  |  | 
|  | bool DescriptorPool_HasFile(const char* filename) { | 
|  | return upb_DefPool_FindFileByName(get_global_symtab(), filename) != NULL; | 
|  | } | 
|  |  | 
|  | void DescriptorPool_AddDescriptor(const char* filename, const char* data, | 
|  | int size) { | 
|  | upb_Arena* arena = upb_Arena_New(); | 
|  | const google_protobuf_FileDescriptorProto* file = | 
|  | google_protobuf_FileDescriptorProto_parse(data, size, arena); | 
|  |  | 
|  | if (!file) { | 
|  | zend_error(E_ERROR, "Failed to parse binary descriptor for %s\n", filename); | 
|  | return; | 
|  | } | 
|  |  | 
|  | add_descriptor(get_global_symtab(), file); | 
|  | upb_Arena_Free(arena); | 
|  | } | 
|  |  | 
|  | /* | 
|  | * DescriptorPool::internalAddGeneratedFile() | 
|  | * | 
|  | * Adds the given descriptor data to this DescriptorPool. | 
|  | */ | 
|  | PHP_METHOD(DescriptorPool, internalAddGeneratedFile) { | 
|  | DescriptorPool* intern = GetPool(getThis()); | 
|  | char* data = NULL; | 
|  | zend_long data_len; | 
|  | zend_bool use_nested_submsg = false; | 
|  | upb_Arena* arena; | 
|  |  | 
|  | if (zend_parse_parameters(ZEND_NUM_ARGS(), "s|b", &data, &data_len, | 
|  | &use_nested_submsg) != SUCCESS) { | 
|  | return; | 
|  | } | 
|  |  | 
|  | arena = upb_Arena_New(); | 
|  | add_descriptor_set(intern->symtab, data, data_len, arena); | 
|  | upb_Arena_Free(arena); | 
|  | } | 
|  |  | 
|  | // clang-format off | 
|  | ZEND_BEGIN_ARG_INFO_EX(arginfo_lookupByName, 0, 0, 1) | 
|  | ZEND_ARG_INFO(0, name) | 
|  | ZEND_END_ARG_INFO() | 
|  |  | 
|  | ZEND_BEGIN_ARG_INFO_EX(arginfo_addgeneratedfile, 0, 0, 2) | 
|  | ZEND_ARG_INFO(0, data) | 
|  | ZEND_ARG_INFO(0, data_len) | 
|  | ZEND_END_ARG_INFO() | 
|  |  | 
|  | static zend_function_entry DescriptorPool_methods[] = { | 
|  | PHP_ME(DescriptorPool, getGeneratedPool, arginfo_void, | 
|  | ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) | 
|  | PHP_ME(DescriptorPool, getDescriptorByClassName, arginfo_lookupByName, ZEND_ACC_PUBLIC) | 
|  | PHP_ME(DescriptorPool, getDescriptorByProtoName, arginfo_lookupByName, ZEND_ACC_PUBLIC) | 
|  | PHP_ME(DescriptorPool, getEnumDescriptorByClassName, arginfo_lookupByName, ZEND_ACC_PUBLIC) | 
|  | PHP_ME(DescriptorPool, internalAddGeneratedFile, arginfo_addgeneratedfile, ZEND_ACC_PUBLIC) | 
|  | ZEND_FE_END | 
|  | }; | 
|  | // clang-format on | 
|  |  | 
|  | // ----------------------------------------------------------------------------- | 
|  | // 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; | 
|  |  | 
|  | /* | 
|  | * InternalDescriptorPool::getGeneratedPool() | 
|  | * | 
|  | * Returns the generated DescriptorPool. Note that this is identical to | 
|  | * DescriptorPool::getGeneratedPool(), and in fact returns a DescriptorPool | 
|  | * instance. | 
|  | */ | 
|  | PHP_METHOD(InternalDescriptorPool, getGeneratedPool) { | 
|  | DescriptorPool_CreateWithSymbolTable(return_value, get_global_symtab()); | 
|  | } | 
|  |  | 
|  | // clang-format off | 
|  | static zend_function_entry InternalDescriptorPool_methods[] = { | 
|  | PHP_ME(InternalDescriptorPool, getGeneratedPool, arginfo_void, | 
|  | ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) | 
|  | ZEND_FE_END | 
|  | }; | 
|  | // clang-format on | 
|  |  | 
|  | // ----------------------------------------------------------------------------- | 
|  | // GPBType | 
|  | // ----------------------------------------------------------------------------- | 
|  |  | 
|  | zend_class_entry* gpb_type_type; | 
|  |  | 
|  | static zend_function_entry gpb_type_methods[] = {ZEND_FE_END}; | 
|  |  | 
|  | // ----------------------------------------------------------------------------- | 
|  | // Module Init | 
|  | // ----------------------------------------------------------------------------- | 
|  |  | 
|  | void Def_ModuleInit() { | 
|  | zend_class_entry tmp_ce; | 
|  | zend_object_handlers* h; | 
|  |  | 
|  | INIT_CLASS_ENTRY(tmp_ce, "Google\\Protobuf\\OneofDescriptor", | 
|  | OneofDescriptor_methods); | 
|  | OneofDescriptor_class_entry = zend_register_internal_class(&tmp_ce); | 
|  | OneofDescriptor_class_entry->ce_flags |= ZEND_ACC_FINAL; | 
|  | OneofDescriptor_class_entry->create_object = CreateHandler_ReturnNull; | 
|  | h = &OneofDescriptor_object_handlers; | 
|  | memcpy(h, &std_object_handlers, sizeof(zend_object_handlers)); | 
|  | h->dtor_obj = &OneofDescriptor_destructor; | 
|  |  | 
|  | INIT_CLASS_ENTRY(tmp_ce, "Google\\Protobuf\\EnumValueDescriptor", | 
|  | EnumValueDescriptor_methods); | 
|  | EnumValueDescriptor_class_entry = zend_register_internal_class(&tmp_ce); | 
|  | EnumValueDescriptor_class_entry->ce_flags |= ZEND_ACC_FINAL; | 
|  | EnumValueDescriptor_class_entry->create_object = CreateHandler_ReturnNull; | 
|  | h = &EnumValueDescriptor_object_handlers; | 
|  | memcpy(h, &std_object_handlers, sizeof(zend_object_handlers)); | 
|  |  | 
|  | INIT_CLASS_ENTRY(tmp_ce, "Google\\Protobuf\\EnumDescriptor", | 
|  | EnumDescriptor_methods); | 
|  | EnumDescriptor_class_entry = zend_register_internal_class(&tmp_ce); | 
|  | EnumDescriptor_class_entry->ce_flags |= ZEND_ACC_FINAL; | 
|  | EnumDescriptor_class_entry->create_object = CreateHandler_ReturnNull; | 
|  | h = &EnumDescriptor_object_handlers; | 
|  | memcpy(h, &std_object_handlers, sizeof(zend_object_handlers)); | 
|  | h->dtor_obj = &EnumDescriptor_destructor; | 
|  |  | 
|  | INIT_CLASS_ENTRY(tmp_ce, "Google\\Protobuf\\Descriptor", Descriptor_methods); | 
|  |  | 
|  | Descriptor_class_entry = zend_register_internal_class(&tmp_ce); | 
|  | Descriptor_class_entry->ce_flags |= ZEND_ACC_FINAL; | 
|  | Descriptor_class_entry->create_object = CreateHandler_ReturnNull; | 
|  | h = &Descriptor_object_handlers; | 
|  | memcpy(h, &std_object_handlers, sizeof(zend_object_handlers)); | 
|  | h->dtor_obj = Descriptor_destructor; | 
|  |  | 
|  | INIT_CLASS_ENTRY(tmp_ce, "Google\\Protobuf\\FieldDescriptor", | 
|  | FieldDescriptor_methods); | 
|  | FieldDescriptor_class_entry = zend_register_internal_class(&tmp_ce); | 
|  | FieldDescriptor_class_entry->ce_flags |= ZEND_ACC_FINAL; | 
|  | FieldDescriptor_class_entry->create_object = CreateHandler_ReturnNull; | 
|  | h = &FieldDescriptor_object_handlers; | 
|  | memcpy(h, &std_object_handlers, sizeof(zend_object_handlers)); | 
|  | h->dtor_obj = &FieldDescriptor_destructor; | 
|  |  | 
|  | 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; | 
|  | DescriptorPool_class_entry->create_object = CreateHandler_ReturnNull; | 
|  | h = &DescriptorPool_object_handlers; | 
|  | 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; | 
|  | INIT_CLASS_ENTRY(class_type, "Google\\Protobuf\\Internal\\GPBType", | 
|  | gpb_type_methods); | 
|  | gpb_type_type = zend_register_internal_class(&class_type); | 
|  | zend_declare_class_constant_long(gpb_type_type, STR("DOUBLE"), 1); | 
|  | zend_declare_class_constant_long(gpb_type_type, STR("FLOAT"), 2); | 
|  | zend_declare_class_constant_long(gpb_type_type, STR("INT64"), 3); | 
|  | zend_declare_class_constant_long(gpb_type_type, STR("UINT64"), 4); | 
|  | zend_declare_class_constant_long(gpb_type_type, STR("INT32"), 5); | 
|  | zend_declare_class_constant_long(gpb_type_type, STR("FIXED64"), 6); | 
|  | zend_declare_class_constant_long(gpb_type_type, STR("FIXED32"), 7); | 
|  | zend_declare_class_constant_long(gpb_type_type, STR("BOOL"), 8); | 
|  | zend_declare_class_constant_long(gpb_type_type, STR("STRING"), 9); | 
|  | zend_declare_class_constant_long(gpb_type_type, STR("GROUP"), 10); | 
|  | zend_declare_class_constant_long(gpb_type_type, STR("MESSAGE"), 11); | 
|  | zend_declare_class_constant_long(gpb_type_type, STR("BYTES"), 12); | 
|  | zend_declare_class_constant_long(gpb_type_type, STR("UINT32"), 13); | 
|  | zend_declare_class_constant_long(gpb_type_type, STR("ENUM"), 14); | 
|  | zend_declare_class_constant_long(gpb_type_type, STR("SFIXED32"), 15); | 
|  | zend_declare_class_constant_long(gpb_type_type, STR("SFIXED64"), 16); | 
|  | zend_declare_class_constant_long(gpb_type_type, STR("SINT32"), 17); | 
|  | zend_declare_class_constant_long(gpb_type_type, STR("SINT64"), 18); | 
|  | #undef STR | 
|  | } |