// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc.  All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//     * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#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.
}

ZEND_BEGIN_ARG_INFO_EX(arginfo_getByIndex, 0, 0, 1)
  ZEND_ARG_INFO(0, index)
ZEND_END_ARG_INFO()

// -----------------------------------------------------------------------------
// 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);
}

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
};

// -----------------------------------------------------------------------------
// 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));
    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());
}

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
};

// -----------------------------------------------------------------------------
// 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));
}

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
};

// -----------------------------------------------------------------------------
// 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::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);
}

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, getMessageType, arginfo_void, ZEND_ACC_PUBLIC)
  ZEND_FE_END
};

// -----------------------------------------------------------------------------
// 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) {
  char *classname =
      GetPhpClassname(upb_MessageDef_File(m), upb_MessageDef_FullName(m));
  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);
  return ce;
}

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);
}


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
};

// -----------------------------------------------------------------------------
// 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(teboring): 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);
}

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
};

// -----------------------------------------------------------------------------
// 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());
}

static zend_function_entry InternalDescriptorPool_methods[] = {
  PHP_ME(InternalDescriptorPool, getGeneratedPool, arginfo_void,
         ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
  ZEND_FE_END
};

// -----------------------------------------------------------------------------
// 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
}
