// 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 <stdint.h>
#include <protobuf.h>
#include <Zend/zend.h>

#include "utf8.h"

// -----------------------------------------------------------------------------
// Native slot storage.
// -----------------------------------------------------------------------------

#define DEREF(memory, type) *(type*)(memory)

size_t native_slot_size(upb_fieldtype_t type) {
  switch (type) {
    case UPB_TYPE_FLOAT: return 4;
    case UPB_TYPE_DOUBLE: return 8;
    case UPB_TYPE_BOOL: return 1;
    case UPB_TYPE_STRING: return sizeof(void*);
    case UPB_TYPE_BYTES: return sizeof(void*);
    case UPB_TYPE_MESSAGE: return sizeof(void*);
    case UPB_TYPE_ENUM: return 4;
    case UPB_TYPE_INT32: return 4;
    case UPB_TYPE_INT64: return 8;
    case UPB_TYPE_UINT32: return 4;
    case UPB_TYPE_UINT64: return 8;
    default: return 0;
  }
}

static bool native_slot_is_default(upb_fieldtype_t type, const void* memory) {
  switch (type) {
#define CASE_TYPE(upb_type, c_type)    \
  case UPB_TYPE_##upb_type: {          \
    return DEREF(memory, c_type) == 0; \
  }
    CASE_TYPE(INT32,  int32_t )
    CASE_TYPE(UINT32, uint32_t)
    CASE_TYPE(ENUM,   int32_t )
    CASE_TYPE(INT64,  int64_t )
    CASE_TYPE(UINT64, uint64_t)
    CASE_TYPE(FLOAT,  float   )
    CASE_TYPE(DOUBLE, double  )
    CASE_TYPE(BOOL,   int8_t  )

#undef CASE_TYPE
    case UPB_TYPE_STRING:
    case UPB_TYPE_BYTES:
      return Z_STRLEN_P(CACHED_PTR_TO_ZVAL_PTR(DEREF(memory, CACHED_VALUE*))) ==
             0;
    case UPB_TYPE_MESSAGE:
      return Z_TYPE_P(CACHED_PTR_TO_ZVAL_PTR(DEREF(memory, CACHED_VALUE*))) ==
             IS_NULL;
    default: return false;
  }
}

bool native_slot_set(upb_fieldtype_t type, const zend_class_entry* klass,
                     void* memory, zval* value PHP_PROTO_TSRMLS_DC) {
  switch (type) {
    case UPB_TYPE_STRING:
    case UPB_TYPE_BYTES: {
      if (!protobuf_convert_to_string(value)) {
        return false;
      }
      if (type == UPB_TYPE_STRING &&
          !is_structurally_valid_utf8(Z_STRVAL_P(value), Z_STRLEN_P(value))) {
        zend_error(E_USER_ERROR, "Given string is not UTF8 encoded.");
        return false;
      }

      zval* cached_zval = CACHED_PTR_TO_ZVAL_PTR((CACHED_VALUE*)memory);
      if (EXPECTED(cached_zval != NULL)) {
#if PHP_MAJOR_VERSION < 7
        REPLACE_ZVAL_VALUE((zval**)memory, value, 1);
#else
        zend_assign_to_variable(cached_zval, value, IS_CV);
#endif
      }
      break;
    }
    case UPB_TYPE_MESSAGE: {
      if (Z_TYPE_P(value) != IS_OBJECT && Z_TYPE_P(value) != IS_NULL) {
        zend_error(E_USER_ERROR, "Given value is not message.");
        return false;
      }
      if (Z_TYPE_P(value) == IS_OBJECT && klass != Z_OBJCE_P(value)) {
        zend_error(E_USER_ERROR, "Given message does not have correct class.");
        return false;
      }

      zval* property_ptr = CACHED_PTR_TO_ZVAL_PTR((CACHED_VALUE*)memory);
      if (EXPECTED(property_ptr != value)) {
        php_proto_zval_ptr_dtor(property_ptr);
      }

#if PHP_MAJOR_VERSION < 7
      DEREF(memory, zval*) = value;
      Z_ADDREF_P(value);
#else
      ZVAL_ZVAL(property_ptr, value, 1, 0);
#endif
      break;
    }

#define CASE_TYPE(upb_type, type, c_type, php_type)              \
  case UPB_TYPE_##upb_type: {                                    \
    c_type type##_value;                                         \
    if (protobuf_convert_to_##type(value, &type##_value)) {      \
      DEREF(memory, c_type) = type##_value;                      \
    }                                                            \
    break;                                                       \
  }
      CASE_TYPE(INT32,  int32,  int32_t,  LONG)
      CASE_TYPE(UINT32, uint32, uint32_t, LONG)
      CASE_TYPE(ENUM,   int32,  int32_t,  LONG)
      CASE_TYPE(INT64,  int64,  int64_t,  LONG)
      CASE_TYPE(UINT64, uint64, uint64_t, LONG)
      CASE_TYPE(FLOAT,  float,  float,    DOUBLE)
      CASE_TYPE(DOUBLE, double, double,   DOUBLE)
      CASE_TYPE(BOOL,   bool,   int8_t,   BOOL)

#undef CASE_TYPE

    default:
      break;
  }

  return true;
}

bool native_slot_set_by_array(upb_fieldtype_t type,
                              const zend_class_entry* klass, void* memory,
                              zval* value TSRMLS_DC) {
  switch (type) {
    case UPB_TYPE_STRING:
    case UPB_TYPE_BYTES: {
      if (!protobuf_convert_to_string(value)) {
        return false;
      }
      if (type == UPB_TYPE_STRING &&
          !is_structurally_valid_utf8(Z_STRVAL_P(value), Z_STRLEN_P(value))) {
        zend_error(E_USER_ERROR, "Given string is not UTF8 encoded.");
        return false;
      }

      // Handles repeated/map string field. Memory provided by
      // RepeatedField/Map is not initialized.
#if PHP_MAJOR_VERSION < 7
      MAKE_STD_ZVAL(DEREF(memory, zval*));
      PHP_PROTO_ZVAL_STRINGL(DEREF(memory, zval*), Z_STRVAL_P(value),
                             Z_STRLEN_P(value), 1);
#else
      *(zend_string**)memory = zend_string_dup(Z_STR_P(value), 0);
#endif
      break;
    }
    case UPB_TYPE_MESSAGE: {
      if (Z_TYPE_P(value) != IS_OBJECT) {
        zend_error(E_USER_ERROR, "Given value is not message.");
        return false;
      }
      if (Z_TYPE_P(value) == IS_OBJECT && klass != Z_OBJCE_P(value)) {
        zend_error(E_USER_ERROR, "Given message does not have correct class.");
        return false;
      }
#if PHP_MAJOR_VERSION < 7
      if (EXPECTED(DEREF(memory, zval*) != value)) {
        DEREF(memory, zval*) = value;
        Z_ADDREF_P(value);
      }
#else
      DEREF(memory, zval*) = value;
      GC_ADDREF(Z_OBJ_P(value));
#endif
      break;
    }
    default:
      return native_slot_set(type, klass, memory, value TSRMLS_CC);
  }
  return true;
}

bool native_slot_set_by_map(upb_fieldtype_t type, const zend_class_entry* klass,
                            void* memory, zval* value TSRMLS_DC) {
  switch (type) {
    case UPB_TYPE_STRING:
    case UPB_TYPE_BYTES: {
      if (!protobuf_convert_to_string(value)) {
        return false;
      }
      if (type == UPB_TYPE_STRING &&
          !is_structurally_valid_utf8(Z_STRVAL_P(value), Z_STRLEN_P(value))) {
        zend_error(E_USER_ERROR, "Given string is not UTF8 encoded.");
        return false;
      }

      // Handles repeated/map string field. Memory provided by
      // RepeatedField/Map is not initialized.
#if PHP_MAJOR_VERSION < 7
      MAKE_STD_ZVAL(DEREF(memory, zval*));
      PHP_PROTO_ZVAL_STRINGL(DEREF(memory, zval*), Z_STRVAL_P(value),
                             Z_STRLEN_P(value), 1);
#else
      *(zend_string**)memory = zend_string_dup(Z_STR_P(value), 0);
#endif
      break;
    }
    case UPB_TYPE_MESSAGE: {
      if (Z_TYPE_P(value) != IS_OBJECT) {
        zend_error(E_USER_ERROR, "Given value is not message.");
        return false;
      }
      if (Z_TYPE_P(value) == IS_OBJECT && klass != Z_OBJCE_P(value)) {
        zend_error(E_USER_ERROR, "Given message does not have correct class.");
        return false;
      }
#if PHP_MAJOR_VERSION < 7
      if (EXPECTED(DEREF(memory, zval*) != value)) {
        DEREF(memory, zval*) = value;
        Z_ADDREF_P(value);
      }
#else
      DEREF(memory, zend_object*) = Z_OBJ_P(value);
      GC_ADDREF(Z_OBJ_P(value));
#endif
      break;
    }
    default:
      return native_slot_set(type, klass, memory, value TSRMLS_CC);
  }
  return true;
}

void native_slot_init(upb_fieldtype_t type, void* memory, CACHED_VALUE* cache) {
  zval* tmp = NULL;
  switch (type) {
    case UPB_TYPE_FLOAT:
      DEREF(memory, float) = 0.0;
      break;
    case UPB_TYPE_DOUBLE:
      DEREF(memory, double) = 0.0;
      break;
    case UPB_TYPE_BOOL:
      DEREF(memory, int8_t) = 0;
      break;
    case UPB_TYPE_STRING:
    case UPB_TYPE_BYTES:
    case UPB_TYPE_MESSAGE:
      DEREF(memory, CACHED_VALUE*) = cache;
      break;
    case UPB_TYPE_ENUM:
    case UPB_TYPE_INT32:
      DEREF(memory, int32_t) = 0;
      break;
    case UPB_TYPE_INT64:
      DEREF(memory, int64_t) = 0;
      break;
    case UPB_TYPE_UINT32:
      DEREF(memory, uint32_t) = 0;
      break;
    case UPB_TYPE_UINT64:
      DEREF(memory, uint64_t) = 0;
      break;
    default:
      break;
  }
}

void native_slot_get(upb_fieldtype_t type, const void* memory,
                     CACHED_VALUE* cache TSRMLS_DC) {
  switch (type) {
#define CASE(upb_type, php_type, c_type)                                   \
  case UPB_TYPE_##upb_type:                                                \
    PHP_PROTO_SEPARATE_ZVAL_IF_NOT_REF(cache);                             \
    ZVAL_##php_type(CACHED_PTR_TO_ZVAL_PTR(cache), DEREF(memory, c_type)); \
    return;

    CASE(FLOAT, DOUBLE, float)
    CASE(DOUBLE, DOUBLE, double)
    CASE(BOOL, BOOL, int8_t)
    CASE(INT32, LONG, int32_t)
    CASE(ENUM, LONG, uint32_t)

#undef CASE

#if SIZEOF_LONG == 4
#define CASE(upb_type, c_type)                                       \
  case UPB_TYPE_##upb_type: {                                        \
    PHP_PROTO_SEPARATE_ZVAL_IF_NOT_REF(cache);                       \
    char buffer[MAX_LENGTH_OF_INT64];                                \
    sprintf(buffer, "%lld", DEREF(memory, c_type));                  \
    PHP_PROTO_ZVAL_STRING(CACHED_PTR_TO_ZVAL_PTR(cache), buffer, 1); \
    return;                                                          \
  }
#else
#define CASE(upb_type, c_type)                                       \
  case UPB_TYPE_##upb_type: {                                        \
    PHP_PROTO_SEPARATE_ZVAL_IF_NOT_REF(cache);                       \
    ZVAL_LONG(CACHED_PTR_TO_ZVAL_PTR(cache), DEREF(memory, c_type)); \
    return;                                                          \
  }
#endif
CASE(UINT64, uint64_t)
CASE(INT64,  int64_t)
#undef CASE

    case UPB_TYPE_UINT32: {
      // Prepend bit-1 for negative numbers, so that uint32 value will be
      // consistent on both 32-bit and 64-bit architectures.
      PHP_PROTO_SEPARATE_ZVAL_IF_NOT_REF(cache);
      int value = DEREF(memory, int32_t);
      if (sizeof(int) == 8) {
        value |= (-((value >> 31) & 0x1) & 0xFFFFFFFF00000000);
      }
      ZVAL_LONG(CACHED_PTR_TO_ZVAL_PTR(cache), value);
      return;
    }

    case UPB_TYPE_STRING:
    case UPB_TYPE_BYTES: {
      // For optional string/bytes/message fields, the cache is owned by the
      // containing message and should have been updated during
      // setting/decoding. However, oneof accessor call this function by
      // providing the return value directly, which is not the same as the cache
      // value.
      zval* value = CACHED_PTR_TO_ZVAL_PTR((CACHED_VALUE*)memory);
      if (CACHED_PTR_TO_ZVAL_PTR(cache) != value) {
        PHP_PROTO_ZVAL_STRINGL(CACHED_PTR_TO_ZVAL_PTR(cache), Z_STRVAL_P(value),
                               Z_STRLEN_P(value), 1);
      }
      break;
    }
    case UPB_TYPE_MESSAGE: {
      // Same as above for string/bytes fields.
      zval* value = CACHED_PTR_TO_ZVAL_PTR((CACHED_VALUE*)memory);
      if (CACHED_PTR_TO_ZVAL_PTR(cache) != value) {
        ZVAL_ZVAL(CACHED_PTR_TO_ZVAL_PTR(cache), value, 1, 0);
      }
      return;
    }
    default:
      return;
  }
}

void native_slot_get_by_array(upb_fieldtype_t type, const void* memory,
                              CACHED_VALUE* cache TSRMLS_DC) {
  switch (type) {
    case UPB_TYPE_STRING:
    case UPB_TYPE_BYTES: {
#if PHP_MAJOR_VERSION < 7
      zval* value = CACHED_PTR_TO_ZVAL_PTR((CACHED_VALUE*)memory);
      if (EXPECTED(CACHED_PTR_TO_ZVAL_PTR(cache) != value)) {
        PHP_PROTO_ZVAL_STRINGL(CACHED_PTR_TO_ZVAL_PTR(cache),
                               Z_STRVAL_P(value), Z_STRLEN_P(value), 1);
      }
#else
      ZVAL_NEW_STR(cache, zend_string_dup(*(zend_string**)memory, 0));
#endif
      return;
    }
    case UPB_TYPE_MESSAGE: {
#if PHP_MAJOR_VERSION < 7
      zval* value = CACHED_PTR_TO_ZVAL_PTR((CACHED_VALUE*)memory);
      if (EXPECTED(CACHED_PTR_TO_ZVAL_PTR(cache) != value)) {
        ZVAL_ZVAL(CACHED_PTR_TO_ZVAL_PTR(cache), value, 1, 0);
      }
#else
      ZVAL_COPY(CACHED_PTR_TO_ZVAL_PTR(cache), memory);
#endif
      return;
    }
    default:
      native_slot_get(type, memory, cache TSRMLS_CC);
  }
}

void native_slot_get_by_map_key(upb_fieldtype_t type, const void* memory,
                                int length, CACHED_VALUE* cache TSRMLS_DC) {
  switch (type) {
    case UPB_TYPE_STRING:
    case UPB_TYPE_BYTES: {
      PHP_PROTO_ZVAL_STRINGL(CACHED_PTR_TO_ZVAL_PTR(cache), memory, length, 1);
      return;
    }
    default:
      native_slot_get(type, memory, cache TSRMLS_CC);
  }
}

void native_slot_get_by_map_value(upb_fieldtype_t type, const void* memory,
                              CACHED_VALUE* cache TSRMLS_DC) {
  switch (type) {
    case UPB_TYPE_MESSAGE: {
#if PHP_MAJOR_VERSION < 7
      zval* value = CACHED_PTR_TO_ZVAL_PTR((CACHED_VALUE*)memory);
      if (EXPECTED(CACHED_PTR_TO_ZVAL_PTR(cache) != value)) {
        ZVAL_ZVAL(CACHED_PTR_TO_ZVAL_PTR(cache), value, 1, 0);
      }
#else
      GC_ADDREF(*(zend_object**)memory);
      ZVAL_OBJ(cache, *(zend_object**)memory);
#endif
      return;
    }
    default:
      native_slot_get_by_array(type, memory, cache TSRMLS_CC);
  }
}

void native_slot_get_default(upb_fieldtype_t type,
                             CACHED_VALUE* cache TSRMLS_DC) {
  switch (type) {
#define CASE(upb_type, php_type)                       \
  case UPB_TYPE_##upb_type:                            \
    PHP_PROTO_SEPARATE_ZVAL_IF_NOT_REF(cache);         \
    ZVAL_##php_type(CACHED_PTR_TO_ZVAL_PTR(cache), 0); \
    return;

    CASE(FLOAT, DOUBLE)
    CASE(DOUBLE, DOUBLE)
    CASE(BOOL, BOOL)
    CASE(INT32, LONG)
    CASE(UINT32, LONG)
    CASE(ENUM, LONG)

#undef CASE

#if SIZEOF_LONG == 4
#define CASE(upb_type)                                            \
  case UPB_TYPE_##upb_type: {                                     \
    PHP_PROTO_SEPARATE_ZVAL_IF_NOT_REF(cache);                    \
    PHP_PROTO_ZVAL_STRING(CACHED_PTR_TO_ZVAL_PTR(cache), "0", 1); \
    return;                                                       \
  }
#else
#define CASE(upb_type)                           \
  case UPB_TYPE_##upb_type: {                    \
    PHP_PROTO_SEPARATE_ZVAL_IF_NOT_REF(cache);   \
    ZVAL_LONG(CACHED_PTR_TO_ZVAL_PTR(cache), 0); \
    return;                                      \
  }
#endif
CASE(UINT64)
CASE(INT64)
#undef CASE

    case UPB_TYPE_STRING:
    case UPB_TYPE_BYTES: {
      PHP_PROTO_SEPARATE_ZVAL_IF_NOT_REF(cache);
      PHP_PROTO_ZVAL_STRINGL(CACHED_PTR_TO_ZVAL_PTR(cache), "", 0, 1);
      break;
    }
    case UPB_TYPE_MESSAGE: {
      PHP_PROTO_SEPARATE_ZVAL_IF_NOT_REF(cache);
      ZVAL_NULL(CACHED_PTR_TO_ZVAL_PTR(cache));
      return;
    }
    default:
      return;
  }
}

// -----------------------------------------------------------------------------
// Map field utilities.
// ----------------------------------------------------------------------------

const upb_msgdef* tryget_map_entry_msgdef(const upb_fielddef* field) {
  const upb_msgdef* subdef;
  if (upb_fielddef_label(field) != UPB_LABEL_REPEATED ||
      upb_fielddef_type(field) != UPB_TYPE_MESSAGE) {
    return NULL;
  }
  subdef = upb_fielddef_msgsubdef(field);
  return upb_msgdef_mapentry(subdef) ? subdef : NULL;
}

const upb_msgdef* map_entry_msgdef(const upb_fielddef* field) {
  const upb_msgdef* subdef = tryget_map_entry_msgdef(field);
  assert(subdef);
  return subdef;
}

bool is_map_field(const upb_fielddef* field) {
  return tryget_map_entry_msgdef(field) != NULL;
}

const upb_fielddef* map_field_key(const upb_fielddef* field) {
  const upb_msgdef* subdef = map_entry_msgdef(field);
  return map_entry_key(subdef);
}

const upb_fielddef* map_field_value(const upb_fielddef* field) {
  const upb_msgdef* subdef = map_entry_msgdef(field);
  return map_entry_value(subdef);
}

const upb_fielddef* map_entry_key(const upb_msgdef* msgdef) {
  const upb_fielddef* key_field = upb_msgdef_itof(msgdef, MAP_KEY_FIELD);
  assert(key_field != NULL);
  return key_field;
}

const upb_fielddef* map_entry_value(const upb_msgdef* msgdef) {
  const upb_fielddef* value_field = upb_msgdef_itof(msgdef, MAP_VALUE_FIELD);
  assert(value_field != NULL);
  return value_field;
}

const zend_class_entry* field_type_class(
    const upb_fielddef* field PHP_PROTO_TSRMLS_DC) {
  if (upb_fielddef_type(field) == UPB_TYPE_MESSAGE) {
    Descriptor* desc = UNBOX_HASHTABLE_VALUE(
        Descriptor, get_def_obj(upb_fielddef_subdef(field)));
    return desc->klass;
  } else if (upb_fielddef_type(field) == UPB_TYPE_ENUM) {
    EnumDescriptor* desc = UNBOX_HASHTABLE_VALUE(
        EnumDescriptor, get_def_obj(upb_fielddef_subdef(field)));
    return desc->klass;
  }
  return NULL;
}

// -----------------------------------------------------------------------------
// Memory layout management.
// -----------------------------------------------------------------------------

static size_t align_up_to(size_t offset, size_t granularity) {
  // Granularity must be a power of two.
  return (offset + granularity - 1) & ~(granularity - 1);
}

static uint32_t* slot_oneof_case(MessageLayout* layout, const void* storage,
                                 const upb_fielddef* field) {
  return (uint32_t*)(((uint8_t*)storage) +
                     layout->fields[upb_fielddef_index(field)].case_offset);
}

static int slot_property_cache(MessageLayout* layout, const void* storage,
                               const upb_fielddef* field) {
  return layout->fields[upb_fielddef_index(field)].cache_index;
}

void* slot_memory(MessageLayout* layout, const void* storage,
                         const upb_fielddef* field) {
  return ((uint8_t*)storage) + layout->fields[upb_fielddef_index(field)].offset;
}

MessageLayout* create_layout(const upb_msgdef* msgdef) {
  MessageLayout* layout = ALLOC(MessageLayout);
  int nfields = upb_msgdef_numfields(msgdef);
  upb_msg_field_iter it;
  upb_msg_oneof_iter oit;
  size_t off = 0;
  int i = 0;

  // Reserve space for unknown fields.
  off += sizeof(void*);

  TSRMLS_FETCH();
  Descriptor* desc = UNBOX_HASHTABLE_VALUE(Descriptor, get_def_obj(msgdef));
  layout->fields = ALLOC_N(MessageField, nfields);

  for (upb_msg_field_begin(&it, msgdef); !upb_msg_field_done(&it);
       upb_msg_field_next(&it)) {
    const upb_fielddef* field = upb_msg_iter_field(&it);
    size_t field_size;

    if (upb_fielddef_containingoneof(field)) {
      // Oneofs are handled separately below.
      continue;
    }

    // Allocate |field_size| bytes for this field in the layout.
    field_size = 0;
    if (upb_fielddef_label(field) == UPB_LABEL_REPEATED) {
      field_size = sizeof(zval*);
    } else {
      field_size = native_slot_size(upb_fielddef_type(field));
    }

    // Align current offset up to | size | granularity.
    off = align_up_to(off, field_size);
    layout->fields[upb_fielddef_index(field)].offset = off;
    layout->fields[upb_fielddef_index(field)].case_offset =
        MESSAGE_FIELD_NO_CASE;

    const char* fieldname = upb_fielddef_name(field);

#if PHP_MAJOR_VERSION < 7 || (PHP_MAJOR_VERSION == 7 && PHP_MINOR_VERSION == 0)
    zend_class_entry* old_scope = EG(scope);
    EG(scope) = desc->klass;
#else
    zend_class_entry* old_scope = EG(fake_scope);
    EG(fake_scope) = desc->klass;
#endif

#if PHP_MAJOR_VERSION < 7
    zval member;
    ZVAL_STRINGL(&member, fieldname, strlen(fieldname), 0);
    zend_property_info* property_info =
        zend_get_property_info(desc->klass, &member, true TSRMLS_CC);
#else
    zend_string* member = zend_string_init(fieldname, strlen(fieldname), 1);
    zend_property_info* property_info =
        zend_get_property_info(desc->klass, member, true);
    zend_string_release(member);
#endif

#if PHP_MAJOR_VERSION < 7 || (PHP_MAJOR_VERSION == 7 && PHP_MINOR_VERSION == 0)
    EG(scope) = old_scope;
#else
    EG(fake_scope) = old_scope;
#endif

    layout->fields[upb_fielddef_index(field)].cache_index =
        property_info->offset;
    off += field_size;
  }

  // Handle oneofs now -- we iterate over oneofs specifically and allocate only
  // one slot per oneof.
  //
  // We assign all value slots first, then pack the 'case' fields at the end,
  // since in the common case (modern 64-bit platform) these are 8 bytes and 4
  // bytes respectively and we want to avoid alignment overhead.
  //
  // Note that we reserve 4 bytes (a uint32) per 'case' slot because the value
  // space for oneof cases is conceptually as wide as field tag numbers.  In
  // practice, it's unlikely that a oneof would have more than e.g.  256 or 64K
  // members (8 or 16 bits respectively), so conceivably we could assign
  // consecutive case numbers and then pick a smaller oneof case slot size, but
  // the complexity to implement this indirection is probably not worthwhile.
  for (upb_msg_oneof_begin(&oit, msgdef); !upb_msg_oneof_done(&oit);
       upb_msg_oneof_next(&oit)) {
    const upb_oneofdef* oneof = upb_msg_iter_oneof(&oit);
    upb_oneof_iter fit;

    // Always allocate NATIVE_SLOT_MAX_SIZE bytes, but share the slot between
    // all fields.
    size_t field_size = NATIVE_SLOT_MAX_SIZE;
    // Align the offset .
    off = align_up_to( off, field_size);
    // Assign all fields in the oneof this same offset.
    const char* oneofname = upb_oneofdef_name(oneof);
    for (upb_oneof_begin(&fit, oneof); !upb_oneof_done(&fit);
         upb_oneof_next(&fit)) {
      const upb_fielddef* field = upb_oneof_iter_field(&fit);
      layout->fields[upb_fielddef_index(field)].offset = off;

#if PHP_MAJOR_VERSION < 7 || (PHP_MAJOR_VERSION == 7 && PHP_MINOR_VERSION == 0)
      zend_class_entry* old_scope = EG(scope);
      EG(scope) = desc->klass;
#else
      zend_class_entry* old_scope = EG(fake_scope);
      EG(fake_scope) = desc->klass;
#endif

#if PHP_MAJOR_VERSION < 7
      zval member;
      ZVAL_STRINGL(&member, oneofname, strlen(oneofname), 0);
      zend_property_info* property_info =
          zend_get_property_info(desc->klass, &member, true TSRMLS_CC);
#else
      zend_string* member = zend_string_init(oneofname, strlen(oneofname), 1);
      zend_property_info* property_info =
          zend_get_property_info(desc->klass, member, true);
      zend_string_release(member);
#endif

#if PHP_MAJOR_VERSION < 7 || (PHP_MAJOR_VERSION == 7 && PHP_MINOR_VERSION == 0)
      EG(scope) = old_scope;
#else
      EG(fake_scope) = old_scope;
#endif

      layout->fields[upb_fielddef_index(field)].cache_index =
          property_info->offset;
    }
    i++;
    off += field_size;
  }

  // Now the case offset.
  for (upb_msg_oneof_begin(&oit, msgdef); !upb_msg_oneof_done(&oit);
       upb_msg_oneof_next(&oit)) {
    const upb_oneofdef* oneof = upb_msg_iter_oneof(&oit);
    upb_oneof_iter fit;

    size_t field_size = sizeof(uint32_t);
    // Align the offset .
    off = (off + field_size - 1) & ~(field_size - 1);
    // Assign all fields in the oneof this same offset.
    for (upb_oneof_begin(&fit, oneof); !upb_oneof_done(&fit);
         upb_oneof_next(&fit)) {
      const upb_fielddef* field = upb_oneof_iter_field(&fit);
      layout->fields[upb_fielddef_index(field)].case_offset = off;
    }
    off += field_size;
  }

  layout->size = off;

  layout->msgdef = msgdef;
  upb_msgdef_ref(layout->msgdef, &layout->msgdef);

  return layout;
}

void free_layout(MessageLayout* layout) {
  FREE(layout->fields);
  upb_msgdef_unref(layout->msgdef, &layout->msgdef);
  FREE(layout);
}

void layout_init(MessageLayout* layout, void* storage,
                 zend_object* object PHP_PROTO_TSRMLS_DC) {
  int i;
  upb_msg_field_iter it;

  // Init unknown fields
  memset(storage, 0, sizeof(void*));

  for (upb_msg_field_begin(&it, layout->msgdef), i = 0; !upb_msg_field_done(&it);
       upb_msg_field_next(&it), i++) {
    const upb_fielddef* field = upb_msg_iter_field(&it);
    void* memory = slot_memory(layout, storage, field);
    uint32_t* oneof_case = slot_oneof_case(layout, storage, field);
    int cache_index = slot_property_cache(layout, storage, field);
    CACHED_VALUE* property_ptr = OBJ_PROP(object, cache_index);

    if (upb_fielddef_containingoneof(field)) {
      memset(memory, 0, NATIVE_SLOT_MAX_SIZE);
      *oneof_case = ONEOF_CASE_NONE;
    } else if (is_map_field(field)) {
      zval_ptr_dtor(property_ptr);
#if PHP_MAJOR_VERSION < 7
      MAKE_STD_ZVAL(*property_ptr);
#endif
      map_field_create_with_field(map_field_type, field,
                                  property_ptr PHP_PROTO_TSRMLS_CC);
      DEREF(memory, CACHED_VALUE*) = property_ptr;
    } else if (upb_fielddef_label(field) == UPB_LABEL_REPEATED) {
      zval_ptr_dtor(property_ptr);
#if PHP_MAJOR_VERSION < 7
      MAKE_STD_ZVAL(*property_ptr);
#endif
      repeated_field_create_with_field(repeated_field_type, field,
                                       property_ptr PHP_PROTO_TSRMLS_CC);
      DEREF(memory, CACHED_VALUE*) = property_ptr;
    } else {
      native_slot_init(upb_fielddef_type(field), memory, property_ptr);
    }
  }
}

// For non-singular fields, the related memory needs to point to the actual
// zval in properties table first.
static void* value_memory(const upb_fielddef* field, void* memory) {
  switch (upb_fielddef_type(field)) {
    case UPB_TYPE_STRING:
    case UPB_TYPE_BYTES:
    case UPB_TYPE_MESSAGE:
      memory = DEREF(memory, CACHED_VALUE*);
      break;
    default:
      // No operation
      break;
  }
  return memory;
}

zval* layout_get(MessageLayout* layout, const void* storage,
                 const upb_fielddef* field, CACHED_VALUE* cache TSRMLS_DC) {
  void* memory = slot_memory(layout, storage, field);
  uint32_t* oneof_case = slot_oneof_case(layout, storage, field);

  if (upb_fielddef_containingoneof(field)) {
    if (*oneof_case != upb_fielddef_number(field)) {
      native_slot_get_default(upb_fielddef_type(field), cache TSRMLS_CC);
    } else {
      native_slot_get(upb_fielddef_type(field), value_memory(field, memory),
                      cache TSRMLS_CC);
    }
    return CACHED_PTR_TO_ZVAL_PTR(cache);
  } else if (upb_fielddef_label(field) == UPB_LABEL_REPEATED) {
    return CACHED_PTR_TO_ZVAL_PTR(cache);
  } else {
    native_slot_get(upb_fielddef_type(field), value_memory(field, memory),
                    cache TSRMLS_CC);
    return CACHED_PTR_TO_ZVAL_PTR(cache);
  }
}

void layout_set(MessageLayout* layout, MessageHeader* header,
                const upb_fielddef* field, zval* val TSRMLS_DC) {
  void* storage = message_data(header);
  void* memory = slot_memory(layout, storage, field);
  uint32_t* oneof_case = slot_oneof_case(layout, storage, field);

  if (upb_fielddef_containingoneof(field)) {
    upb_fieldtype_t type = upb_fielddef_type(field);
    zend_class_entry *ce = NULL;

    // For non-singular fields, the related memory needs to point to the actual
    // zval in properties table first.
    switch (type) {
      case UPB_TYPE_MESSAGE: {
        const upb_msgdef* msg = upb_fielddef_msgsubdef(field);
        Descriptor* desc = UNBOX_HASHTABLE_VALUE(Descriptor, get_def_obj(msg));
        ce = desc->klass;
        // Intentionally fall through.
      }
      case UPB_TYPE_STRING:
      case UPB_TYPE_BYTES: {
        int property_cache_index =
            header->descriptor->layout->fields[upb_fielddef_index(field)]
                .cache_index;
        DEREF(memory, CACHED_VALUE*) =
            OBJ_PROP(&header->std, property_cache_index);
        memory = DEREF(memory, CACHED_VALUE*);
        break;
      }
      default:
        break;
    }

    native_slot_set(type, ce, memory, val TSRMLS_CC);
    *oneof_case = upb_fielddef_number(field);
  } else if (upb_fielddef_label(field) == UPB_LABEL_REPEATED) {
    // Works for both repeated and map fields
    memory = DEREF(memory, void**);
    zval* property_ptr = CACHED_PTR_TO_ZVAL_PTR((CACHED_VALUE*)memory);

    if (EXPECTED(property_ptr != val)) {
      zend_class_entry *subce = NULL;
      zval converted_value;

      if (upb_fielddef_ismap(field)) {
        const upb_msgdef* mapmsg = upb_fielddef_msgsubdef(field);
        const upb_fielddef* keyfield = upb_msgdef_ntof(mapmsg, "key", 3);
        const upb_fielddef* valuefield = upb_msgdef_ntof(mapmsg, "value", 5);
        if (upb_fielddef_descriptortype(valuefield) ==
            UPB_DESCRIPTOR_TYPE_MESSAGE) {
          const upb_msgdef* submsg = upb_fielddef_msgsubdef(valuefield);
          Descriptor* subdesc =
              UNBOX_HASHTABLE_VALUE(Descriptor, get_def_obj(submsg));
          subce = subdesc->klass;
        }
        check_map_field(subce, upb_fielddef_descriptortype(keyfield),
                        upb_fielddef_descriptortype(valuefield), val,
                        &converted_value);
      } else {
        if (upb_fielddef_type(field) == UPB_TYPE_MESSAGE) {
          const upb_msgdef* submsg = upb_fielddef_msgsubdef(field);
          Descriptor* subdesc =
              UNBOX_HASHTABLE_VALUE(Descriptor, get_def_obj(submsg));
          subce = subdesc->klass;
        }

        check_repeated_field(subce, upb_fielddef_descriptortype(field), val,
                             &converted_value);
      }
#if PHP_MAJOR_VERSION < 7
      REPLACE_ZVAL_VALUE((zval**)memory, &converted_value, 1);
#else
      php_proto_zval_ptr_dtor(property_ptr);
      ZVAL_ZVAL(property_ptr, &converted_value, 1, 0);
#endif
      zval_dtor(&converted_value);
    }
  } else {
    upb_fieldtype_t type = upb_fielddef_type(field);
    zend_class_entry *ce = NULL;
    if (type == UPB_TYPE_MESSAGE) {
      const upb_msgdef* msg = upb_fielddef_msgsubdef(field);
      Descriptor* desc = UNBOX_HASHTABLE_VALUE(Descriptor, get_def_obj(msg));
      ce = desc->klass;
    }
    native_slot_set(type, ce, value_memory(field, memory), val TSRMLS_CC);
  }
}

static void native_slot_merge(const upb_fielddef* field, const void* from_memory,
                         void* to_memory PHP_PROTO_TSRMLS_DC) {
  upb_fieldtype_t type = upb_fielddef_type(field);
  zend_class_entry* ce = NULL;
  if (!native_slot_is_default(type, from_memory)) {
    switch (type) {
#define CASE_TYPE(upb_type, c_type)                        \
  case UPB_TYPE_##upb_type: {                              \
    DEREF(to_memory, c_type) = DEREF(from_memory, c_type); \
    break;                                                 \
  }
      CASE_TYPE(INT32, int32_t)
      CASE_TYPE(UINT32, uint32_t)
      CASE_TYPE(ENUM, int32_t)
      CASE_TYPE(INT64, int64_t)
      CASE_TYPE(UINT64, uint64_t)
      CASE_TYPE(FLOAT, float)
      CASE_TYPE(DOUBLE, double)
      CASE_TYPE(BOOL, int8_t)

#undef CASE_TYPE
      case UPB_TYPE_STRING:
      case UPB_TYPE_BYTES:
        native_slot_set(type, NULL, value_memory(field, to_memory),
                        CACHED_PTR_TO_ZVAL_PTR(DEREF(
                            from_memory, CACHED_VALUE*)) PHP_PROTO_TSRMLS_CC);
        break;
      case UPB_TYPE_MESSAGE: {
        const upb_msgdef* msg = upb_fielddef_msgsubdef(field);
        Descriptor* desc = UNBOX_HASHTABLE_VALUE(Descriptor, get_def_obj(msg));
        ce = desc->klass;
        if (native_slot_is_default(type, to_memory)) {
#if PHP_MAJOR_VERSION < 7
          SEPARATE_ZVAL_IF_NOT_REF((zval**)value_memory(field, to_memory));
#endif
          CREATE_OBJ_ON_ALLOCATED_ZVAL_PTR(
              CACHED_PTR_TO_ZVAL_PTR(DEREF(to_memory, CACHED_VALUE*)), ce);
          MessageHeader* submsg =
              UNBOX(MessageHeader,
                    CACHED_PTR_TO_ZVAL_PTR(DEREF(to_memory, CACHED_VALUE*)));
          custom_data_init(ce, submsg PHP_PROTO_TSRMLS_CC);
        }

        MessageHeader* sub_from =
            UNBOX(MessageHeader,
                  CACHED_PTR_TO_ZVAL_PTR(DEREF(from_memory, CACHED_VALUE*)));
        MessageHeader* sub_to =
            UNBOX(MessageHeader,
                  CACHED_PTR_TO_ZVAL_PTR(DEREF(to_memory, CACHED_VALUE*)));

        layout_merge(desc->layout, sub_from, sub_to PHP_PROTO_TSRMLS_CC);
        break;
      }
    }
  }
}

static void native_slot_merge_by_array(const upb_fielddef* field, const void* from_memory,
                         void* to_memory PHP_PROTO_TSRMLS_DC) {
  upb_fieldtype_t type = upb_fielddef_type(field);
  switch (type) {
    case UPB_TYPE_STRING:
    case UPB_TYPE_BYTES: {
#if PHP_MAJOR_VERSION < 7
      MAKE_STD_ZVAL(DEREF(to_memory, zval*));
      PHP_PROTO_ZVAL_STRINGL(DEREF(to_memory, zval*),
                             Z_STRVAL_P(*(zval**)from_memory),
                             Z_STRLEN_P(*(zval**)from_memory), 1);
#else
      DEREF(to_memory, zend_string*) =
          zend_string_dup(*(zend_string**)from_memory, 0);
#endif
      break;
    }
    case UPB_TYPE_MESSAGE: {
      const upb_msgdef* msg = upb_fielddef_msgsubdef(field);
      Descriptor* desc = UNBOX_HASHTABLE_VALUE(Descriptor, get_def_obj(msg));
      zend_class_entry* ce = desc->klass;
#if PHP_MAJOR_VERSION < 7
      MAKE_STD_ZVAL(DEREF(to_memory, zval*));
      CREATE_OBJ_ON_ALLOCATED_ZVAL_PTR(DEREF(to_memory, zval*), ce);
#else
      DEREF(to_memory, zend_object*) = ce->create_object(ce TSRMLS_CC);
#endif
      MessageHeader* sub_from = UNBOX_HASHTABLE_VALUE(
          MessageHeader, DEREF(from_memory, PHP_PROTO_HASHTABLE_VALUE));
      MessageHeader* sub_to = UNBOX_HASHTABLE_VALUE(
          MessageHeader, DEREF(to_memory, PHP_PROTO_HASHTABLE_VALUE));
      custom_data_init(ce, sub_to PHP_PROTO_TSRMLS_CC);

      layout_merge(desc->layout, sub_from, sub_to PHP_PROTO_TSRMLS_CC);
      break;
    }
    default:
      native_slot_merge(field, from_memory, to_memory PHP_PROTO_TSRMLS_CC);
      break;
  }
}

void layout_merge(MessageLayout* layout, MessageHeader* from,
                  MessageHeader* to PHP_PROTO_TSRMLS_DC) {
  int i, j;
  upb_msg_field_iter it;

  for (upb_msg_field_begin(&it, layout->msgdef), i = 0; !upb_msg_field_done(&it);
       upb_msg_field_next(&it), i++) {
    const upb_fielddef* field = upb_msg_iter_field(&it);

    void* to_memory = slot_memory(layout, message_data(to), field);
    void* from_memory = slot_memory(layout, message_data(from), field);

    if (upb_fielddef_containingoneof(field)) {
      uint32_t oneof_case_offset =
          layout->fields[upb_fielddef_index(field)].case_offset;
      // For a oneof, check that this field is actually present -- skip all the
      // below if not.
      if (DEREF((message_data(from) + oneof_case_offset), uint32_t) !=
          upb_fielddef_number(field)) {
        continue;
      }
      uint32_t* from_oneof_case = slot_oneof_case(layout, message_data(from), field);
      uint32_t* to_oneof_case = slot_oneof_case(layout, message_data(to), field);

      // For non-singular fields, the related memory needs to point to the
      // actual zval in properties table first.
      switch (upb_fielddef_type(field)) {
        case UPB_TYPE_MESSAGE:
        case UPB_TYPE_STRING:
        case UPB_TYPE_BYTES: {
          int property_cache_index =
              layout->fields[upb_fielddef_index(field)].cache_index;
          DEREF(to_memory, CACHED_VALUE*) =
              OBJ_PROP(&to->std, property_cache_index);
          break;
        }
        default:
          break;
      }

      *to_oneof_case = *from_oneof_case;

      // Otherwise, fall through to the appropriate singular-field handler
      // below.
    }

    if (is_map_field(field)) {
      int size, key_length, value_length;
      MapIter map_it;

      zval* to_map_php =
          CACHED_PTR_TO_ZVAL_PTR(DEREF(to_memory, CACHED_VALUE*));
      zval* from_map_php =
          CACHED_PTR_TO_ZVAL_PTR(DEREF(from_memory, CACHED_VALUE*));
      Map* to_map = UNBOX(Map, to_map_php);
      Map* from_map = UNBOX(Map, from_map_php);

      size = upb_strtable_count(&from_map->table);
      if (size == 0) continue;

      const upb_msgdef *mapentry_def = upb_fielddef_msgsubdef(field);
      const upb_fielddef *value_field = upb_msgdef_itof(mapentry_def, 2);

      for (map_begin(from_map_php, &map_it TSRMLS_CC); !map_done(&map_it);
           map_next(&map_it)) {
        const char* key = map_iter_key(&map_it, &key_length);
        upb_value from_value = map_iter_value(&map_it, &value_length);
        upb_value to_value;
        void* from_mem = upb_value_memory(&from_value);
        void* to_mem = upb_value_memory(&to_value);
        memset(to_mem, 0, native_slot_size(to_map->value_type));

        native_slot_merge_by_array(value_field, from_mem,
                                   to_mem PHP_PROTO_TSRMLS_CC);

        map_index_set(to_map, key, key_length, to_value);
      }

    } else if (upb_fielddef_label(field) == UPB_LABEL_REPEATED) {
      zval* to_array_php = CACHED_PTR_TO_ZVAL_PTR(DEREF(to_memory, CACHED_VALUE*));
      zval* from_array_php = CACHED_PTR_TO_ZVAL_PTR(DEREF(from_memory, CACHED_VALUE*));
      RepeatedField* to_array = UNBOX(RepeatedField, to_array_php);
      RepeatedField* from_array = UNBOX(RepeatedField, from_array_php);

      int size = zend_hash_num_elements(PHP_PROTO_HASH_OF(from_array->array));
      if (size > 0) {
        for (j = 0; j < size; j++) {
          void* from_memory = NULL;
          void* to_memory =
              ALLOC_N(char, native_slot_size(upb_fielddef_type(field)));
          memset(to_memory, 0, native_slot_size(upb_fielddef_type(field)));

          if (to_array->type == UPB_TYPE_MESSAGE) {
            php_proto_zend_hash_index_find_zval(
                PHP_PROTO_HASH_OF(from_array->array), j, (void**)&from_memory);
#if PHP_MAJOR_VERSION >= 7
            from_memory = &Z_OBJ_P((zval*)from_memory);
#endif
          } else {
            php_proto_zend_hash_index_find_mem(
                PHP_PROTO_HASH_OF(from_array->array), j, (void**)&from_memory);
          }

          native_slot_merge_by_array(field, from_memory,
                                     to_memory PHP_PROTO_TSRMLS_CC);
          repeated_field_push_native(to_array, to_memory);
          FREE(to_memory);
        }
      }
    } else {
      native_slot_merge(field, from_memory, to_memory PHP_PROTO_TSRMLS_CC);
    }
  }
}

const char* layout_get_oneof_case(MessageLayout* layout, const void* storage,
                                  const upb_oneofdef* oneof TSRMLS_DC) {
  upb_oneof_iter i;
  const upb_fielddef* first_field;

  // Oneof is guaranteed to have at least one field. Get the first field.
  for(upb_oneof_begin(&i, oneof); !upb_oneof_done(&i); upb_oneof_next(&i)) {
    first_field = upb_oneof_iter_field(&i);
    break;
  }

  uint32_t* oneof_case = slot_oneof_case(layout, storage, first_field);
  if (*oneof_case == 0) {
    return "";
  }
  const upb_fielddef* field = upb_oneofdef_itof(oneof, *oneof_case);
  return upb_fielddef_name(field);
}
