// 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 <php.h>
#include <Zend/zend_exceptions.h>

#include "protobuf.h"
#include "utf8.h"

/* stringsink *****************************************************************/

static void *stringsink_start(void *_sink, const void *hd, size_t size_hint) {
  stringsink *sink = _sink;
  sink->len = 0;
  return sink;
}

size_t stringsink_string(void *_sink, const void *hd, const char *ptr,
                         size_t len, const upb_bufhandle *handle) {
  stringsink *sink = _sink;
  size_t new_size = sink->size;

  PHP_PROTO_UNUSED(hd);
  PHP_PROTO_UNUSED(handle);

  while (sink->len + len > new_size) {
    new_size *= 2;
  }

  if (new_size != sink->size) {
    sink->ptr = realloc(sink->ptr, new_size);
    sink->size = new_size;
  }

  memcpy(sink->ptr + sink->len, ptr, len);
  sink->len += len;

  return len;
}

void stringsink_init(stringsink *sink) {
  upb_byteshandler_init(&sink->handler);
  upb_byteshandler_setstartstr(&sink->handler, stringsink_start, NULL);
  upb_byteshandler_setstring(&sink->handler, stringsink_string, NULL);

  upb_bytessink_reset(&sink->sink, &sink->handler, sink);

  sink->size = 32;
  sink->ptr = malloc(sink->size);
  PHP_PROTO_ASSERT(sink->ptr != NULL);
  sink->len = 0;
}

void stringsink_uninit(stringsink *sink) { free(sink->ptr); }

void stringsink_uninit_opaque(void *sink) { stringsink_uninit(sink); }

/* stackenv *****************************************************************/

// Stack-allocated context during an encode/decode operation. Contains the upb
// environment and its stack-based allocator, an initial buffer for allocations
// to avoid malloc() when possible, and a template for PHP exception messages
// if any error occurs.
#define STACK_ENV_STACKBYTES 4096
typedef struct {
  upb_arena *arena;
  upb_status status;
  const char *php_error_template;
  char allocbuf[STACK_ENV_STACKBYTES];
} stackenv;


static void stackenv_init(stackenv* se, const char* errmsg);
static void stackenv_uninit(stackenv* se);

static void stackenv_init(stackenv* se, const char* errmsg) {
  se->php_error_template = errmsg;
  se->arena = upb_arena_new();
  upb_status_clear(&se->status);
}

static void stackenv_uninit(stackenv* se) {
  upb_arena_free(se->arena);

  if (!upb_ok(&se->status)) {
    // TODO(teboring): have a way to verify that this is actually a parse error,
    // instead of just throwing "parse error" unconditionally.
    TSRMLS_FETCH();
    zend_throw_exception_ex(NULL, 0 TSRMLS_CC, se->php_error_template,
                            upb_status_errmsg(&se->status));
  }
}

// -----------------------------------------------------------------------------
// Parsing.
// -----------------------------------------------------------------------------

bool is_wrapper_msg(const upb_msgdef* m) {
  switch (upb_msgdef_wellknowntype(m)) {
    case UPB_WELLKNOWN_DOUBLEVALUE:
    case UPB_WELLKNOWN_FLOATVALUE:
    case UPB_WELLKNOWN_INT64VALUE:
    case UPB_WELLKNOWN_UINT64VALUE:
    case UPB_WELLKNOWN_INT32VALUE:
    case UPB_WELLKNOWN_UINT32VALUE:
    case UPB_WELLKNOWN_STRINGVALUE:
    case UPB_WELLKNOWN_BYTESVALUE:
    case UPB_WELLKNOWN_BOOLVALUE:
      return true;
    default:
      return false;
  }
}

typedef struct {
  void* closure;
  void* submsg;
  bool is_msg;
} wrapperfields_parseframe_t;

#define DEREF(msg, ofs, type) *(type*)(((uint8_t *)msg) + ofs)

// Creates a handlerdata that simply contains the offset for this field.
static const void* newhandlerdata(upb_handlers* h, uint32_t ofs) {
  size_t* hd_ofs = (size_t*)malloc(sizeof(size_t));
  PHP_PROTO_ASSERT(hd_ofs != NULL);
  *hd_ofs = ofs;
  upb_handlers_addcleanup(h, hd_ofs, free);
  return hd_ofs;
}

static const void* newhandlerfielddata(
    upb_handlers* h, const upb_fielddef* field) {
  const void** hd_field = malloc(sizeof(void*));
  PHP_PROTO_ASSERT(hd_field != NULL);
  *hd_field = field;
  upb_handlers_addcleanup(h, hd_field, free);
  return hd_field;
}

typedef struct {
  void* closure;
  stringsink sink;
} stringfields_parseframe_t;

typedef size_t (*encodeunknown_handlerfunc)(void* _sink, const void* hd,
                                            const char* ptr, size_t len,
                                            const upb_bufhandle* handle);

typedef struct {
  encodeunknown_handlerfunc handler;
} unknownfields_handlerdata_t;

// Creates a handlerdata for unknown fields.
static const void *newunknownfieldshandlerdata(upb_handlers* h) {
  unknownfields_handlerdata_t* hd =
      (unknownfields_handlerdata_t*)malloc(sizeof(unknownfields_handlerdata_t));
  PHP_PROTO_ASSERT(hd != NULL);
  hd->handler = stringsink_string;
  upb_handlers_addcleanup(h, hd, free);
  return hd;
}

typedef struct {
  const upb_fielddef *fd;
  size_t ofs;
  const upb_msgdef *md;
} submsg_handlerdata_t;

// Creates a handlerdata that contains field and submessage type information.
static const void *newsubmsghandlerdata(upb_handlers* h, uint32_t ofs,
                                        const upb_fielddef* f) {
  submsg_handlerdata_t* hd =
      (submsg_handlerdata_t*)malloc(sizeof(submsg_handlerdata_t));
  PHP_PROTO_ASSERT(hd != NULL);
  hd->fd = f;
  hd->ofs = ofs;
  hd->md = upb_fielddef_msgsubdef(f);
  upb_handlers_addcleanup(h, hd, free);
  return hd;
}

typedef struct {
  size_t ofs;              // union data slot
  size_t case_ofs;         // oneof_case field
  int property_ofs;        // properties table cache
  uint32_t oneof_case_num; // oneof-case number to place in oneof_case field
  const upb_msgdef *md;    // msgdef, for oneof submessage handler
  const upb_msgdef *parent_md;  // msgdef, for parent submessage
} oneof_handlerdata_t;

static const void *newoneofhandlerdata(upb_handlers *h,
                                       uint32_t ofs,
                                       uint32_t case_ofs,
                                       int property_ofs,
                                       const upb_msgdef *m,
                                       const upb_fielddef *f) {
  oneof_handlerdata_t* hd =
      (oneof_handlerdata_t*)malloc(sizeof(oneof_handlerdata_t));
  PHP_PROTO_ASSERT(hd != NULL);
  hd->ofs = ofs;
  hd->case_ofs = case_ofs;
  hd->property_ofs = property_ofs;
  hd->parent_md = m;
  // We reuse the field tag number as a oneof union discriminant tag. Note that
  // we don't expose these numbers to the user, so the only requirement is that
  // we have some unique ID for each union case/possibility. The field tag
  // numbers are already present and are easy to use so there's no reason to
  // create a separate ID space. In addition, using the field tag number here
  // lets us easily look up the field in the oneof accessor.
  hd->oneof_case_num = upb_fielddef_number(f);
  if (upb_fielddef_type(f) == UPB_TYPE_MESSAGE) {
    hd->md = upb_fielddef_msgsubdef(f);
  } else {
    hd->md = NULL;
  }
  upb_handlers_addcleanup(h, hd, free);
  return hd;
}

// A handler that starts a repeated field.  Gets the Repeated*Field instance for
// this field (such an instance always exists even in an empty message).
static void *startseq_handler(void* closure, const void* hd) {
  MessageHeader* msg = closure;
  const upb_fielddef** field = (const upb_fielddef**) hd;
  CACHED_VALUE* cache = find_zval_property(msg, *field);
  TSRMLS_FETCH();
  repeated_field_ensure_created(*field, cache PHP_PROTO_TSRMLS_CC);
  return CACHED_PTR_TO_ZVAL_PTR(cache);
}

// Handlers that append primitive values to a repeated field.
#define DEFINE_APPEND_HANDLER(type, ctype)                          \
  static bool append##type##_handler(void* closure, const void* hd, \
                                     ctype val) {                   \
    zval* array = (zval*)closure;                                   \
    TSRMLS_FETCH();                                                 \
    RepeatedField* intern = UNBOX(RepeatedField, array);            \
    repeated_field_push_native(intern, &val);                       \
    return true;                                                    \
  }

DEFINE_APPEND_HANDLER(bool,   bool)
DEFINE_APPEND_HANDLER(int32,  int32_t)
DEFINE_APPEND_HANDLER(uint32, uint32_t)
DEFINE_APPEND_HANDLER(float,  float)
DEFINE_APPEND_HANDLER(int64,  int64_t)
DEFINE_APPEND_HANDLER(uint64, uint64_t)
DEFINE_APPEND_HANDLER(double, double)

// Appends a string or 'bytes' string to a repeated field.
static void* appendstr_handler(void *closure,
                               const void *hd,
                               size_t size_hint) {
  PHP_PROTO_UNUSED(hd);

  stringfields_parseframe_t* frame =
      (stringfields_parseframe_t*)malloc(sizeof(stringfields_parseframe_t));
  PHP_PROTO_ASSERT(frame != NULL);
  frame->closure = closure;
  stringsink_init(&frame->sink);

  return frame;
}

static bool appendstr_end_handler(void *closure, const void *hd) {
  stringfields_parseframe_t* frame = closure;

  zval* array = (zval*)frame->closure;
  TSRMLS_FETCH();
  RepeatedField* intern = UNBOX(RepeatedField, array);

#if PHP_MAJOR_VERSION < 7
  zval* str;
  MAKE_STD_ZVAL(str);
  PHP_PROTO_ZVAL_STRINGL(str, frame->sink.ptr, frame->sink.len, 1);
  repeated_field_push_native(intern, &str);
#else
  zend_string* str = zend_string_init(frame->sink.ptr, frame->sink.len, 1);
  repeated_field_push_native(intern, &str);
#endif

  stringsink_uninit(&frame->sink);
  free(frame);

  return true;
}

// Handlers that append primitive values to a repeated field.
#define DEFINE_SINGULAR_HANDLER(type, ctype)                \
  static bool type##_handler(void* closure, const void* hd, \
                                     ctype val) {           \
    MessageHeader* msg = (MessageHeader*)closure;           \
    const size_t *ofs = hd;                                 \
    DEREF(message_data(msg), *ofs, ctype) = val;            \
    return true;                                            \
  }

DEFINE_SINGULAR_HANDLER(bool,   bool)
DEFINE_SINGULAR_HANDLER(int32,  int32_t)
DEFINE_SINGULAR_HANDLER(uint32, uint32_t)
DEFINE_SINGULAR_HANDLER(float,  float)
DEFINE_SINGULAR_HANDLER(int64,  int64_t)
DEFINE_SINGULAR_HANDLER(uint64, uint64_t)
DEFINE_SINGULAR_HANDLER(double, double)

#undef DEFINE_SINGULAR_HANDLER

#if PHP_MAJOR_VERSION < 7
static void new_php_string(zval** value_ptr, const char* str, size_t len) {
  SEPARATE_ZVAL_IF_NOT_REF(value_ptr);
  if (Z_TYPE_PP(value_ptr) == IS_STRING &&
      !IS_INTERNED(Z_STRVAL_PP(value_ptr))) {
    FREE(Z_STRVAL_PP(value_ptr));
  }
  ZVAL_STRINGL(*value_ptr, str, len, 1);
}
#else
static void new_php_string(zval* value_ptr, const char* str, size_t len) {
  if (Z_TYPE_P(value_ptr) == IS_STRING) {
    zend_string_release(Z_STR_P(value_ptr));
  }
  ZVAL_NEW_STR(value_ptr, zend_string_init(str, len, 0));
}
#endif

// Sets a non-repeated string/bytes field in a message.
static void* str_handler(void *closure,
                         const void *hd,
                         size_t size_hint) {
  PHP_PROTO_UNUSED(hd);

  stringfields_parseframe_t* frame =
      (stringfields_parseframe_t*)malloc(sizeof(stringfields_parseframe_t));
  PHP_PROTO_ASSERT(frame != NULL);
  frame->closure = closure;
  stringsink_init(&frame->sink);

  return frame;
}

static bool str_end_handler(void *closure, const void *hd) {
  stringfields_parseframe_t* frame = closure;
  const upb_fielddef **field = (const upb_fielddef **) hd;
  MessageHeader* msg = (MessageHeader*)frame->closure;

  CACHED_VALUE* cached = find_zval_property(msg, *field);

  new_php_string(cached, frame->sink.ptr, frame->sink.len);

  stringsink_uninit(&frame->sink);
  free(frame);

  return true;
}

static bool map_str_end_handler(void *closure, const void *hd) {
  stringfields_parseframe_t* frame = closure;
  const size_t *ofs = hd;
  MessageHeader* msg = (MessageHeader*)frame->closure;

  new_php_string(DEREF(message_data(msg), *ofs, CACHED_VALUE*),
                 frame->sink.ptr, frame->sink.len);

  stringsink_uninit(&frame->sink);
  free(frame);

  return true;
}

static size_t stringdata_handler(void* closure, const void* hd,
                                 const char* str, size_t len,
                                 const upb_bufhandle* handle) {
  stringfields_parseframe_t* frame = closure;
  return stringsink_string(&frame->sink, hd, str, len, handle);
}

// Appends a submessage to a repeated field.
static void *appendsubmsg_handler(void *closure, const void *hd) {
  zval* array = (zval*)closure;
  TSRMLS_FETCH();
  RepeatedField* intern = UNBOX(RepeatedField, array);

  const submsg_handlerdata_t *submsgdata = hd;
  DescriptorInternal* subdesc = get_msgdef_desc(submsgdata->md);
  register_class(subdesc, false TSRMLS_CC);
  zend_class_entry* subklass = subdesc->klass;
  MessageHeader* submsg;

#if PHP_MAJOR_VERSION < 7
  zval* val = NULL;
  MAKE_STD_ZVAL(val);
  ZVAL_OBJ(val, subklass->create_object(subklass TSRMLS_CC));
  repeated_field_push_native(intern, &val);
  submsg = UNBOX(MessageHeader, val);
#else
  zend_object* obj = subklass->create_object(subklass TSRMLS_CC);
  repeated_field_push_native(intern, &obj);
  submsg = (MessageHeader*)((char*)obj - XtOffsetOf(MessageHeader, std));
#endif
  custom_data_init(subklass, submsg PHP_PROTO_TSRMLS_CC);

  return submsg;
}

// Appends a wrapper submessage to a repeated field.
static void *appendwrappersubmsg_handler(void *closure, const void *hd) {
  zval* array = (zval*)closure;
  TSRMLS_FETCH();
  RepeatedField* intern = UNBOX(RepeatedField, array);

  const submsg_handlerdata_t *submsgdata = hd;
  DescriptorInternal* subdesc = get_msgdef_desc(submsgdata->md);
  register_class(subdesc, false TSRMLS_CC);
  zend_class_entry* subklass = subdesc->klass;
  MessageHeader* submsg;
  wrapperfields_parseframe_t* frame =
      (wrapperfields_parseframe_t*)malloc(sizeof(wrapperfields_parseframe_t));

#if PHP_MAJOR_VERSION < 7
  zval* val = NULL;
  MAKE_STD_ZVAL(val);
  ZVAL_OBJ(val, subklass->create_object(subklass TSRMLS_CC));
  repeated_field_push_native(intern, &val);
  submsg = UNBOX(MessageHeader, val);
#else
  zend_object* obj = subklass->create_object(subklass TSRMLS_CC);
  repeated_field_push_native(intern, &obj);
  submsg = (MessageHeader*)((char*)obj - XtOffsetOf(MessageHeader, std));
#endif
  custom_data_init(subklass, submsg PHP_PROTO_TSRMLS_CC);

  frame->closure = closure;
  frame->submsg = submsg;
  frame->is_msg = true;

  return frame;
}

// Sets a non-repeated submessage field in a message.
static void *submsg_handler(void *closure, const void *hd) {
  MessageHeader* msg = closure;
  const submsg_handlerdata_t* submsgdata = hd;
  TSRMLS_FETCH();
  DescriptorInternal* subdesc = get_msgdef_desc(submsgdata->md);
  register_class(subdesc, false TSRMLS_CC);
  zend_class_entry* subklass = subdesc->klass;
  zval* submsg_php;
  MessageHeader* submsg;

  CACHED_VALUE* cached = find_zval_property(msg, submsgdata->fd);

  if (Z_TYPE_P(CACHED_PTR_TO_ZVAL_PTR(cached)) == IS_NULL) {
#if PHP_MAJOR_VERSION < 7
    zval val;
    ZVAL_OBJ(&val, subklass->create_object(subklass TSRMLS_CC));
    MessageHeader* intern = UNBOX(MessageHeader, &val);
    custom_data_init(subklass, intern PHP_PROTO_TSRMLS_CC);
    REPLACE_ZVAL_VALUE(cached, &val, 1);
    zval_dtor(&val);
#else
    zend_object* obj = subklass->create_object(subklass TSRMLS_CC);
    ZVAL_OBJ(cached, obj);
    MessageHeader* intern = UNBOX_HASHTABLE_VALUE(MessageHeader, obj);
    custom_data_init(subklass, intern PHP_PROTO_TSRMLS_CC);
#endif
  }

  submsg_php = CACHED_PTR_TO_ZVAL_PTR(cached);

  submsg = UNBOX(MessageHeader, submsg_php);
  return submsg;
}

static void *map_submsg_handler(void *closure, const void *hd) {
  MessageHeader* msg = closure;
  const submsg_handlerdata_t* submsgdata = hd;
  TSRMLS_FETCH();
  DescriptorInternal* subdesc = get_msgdef_desc(submsgdata->md);
  register_class(subdesc, false TSRMLS_CC);
  zend_class_entry* subklass = subdesc->klass;
  zval* submsg_php;
  MessageHeader* submsg;

  CACHED_VALUE* cached =
      DEREF(message_data(msg), submsgdata->ofs, CACHED_VALUE*);

  if (Z_TYPE_P(CACHED_PTR_TO_ZVAL_PTR(cached)) == IS_NULL) {
#if PHP_MAJOR_VERSION < 7
    zval val;
    ZVAL_OBJ(&val, subklass->create_object(subklass TSRMLS_CC));
    MessageHeader* intern = UNBOX(MessageHeader, &val);
    custom_data_init(subklass, intern PHP_PROTO_TSRMLS_CC);
    REPLACE_ZVAL_VALUE(cached, &val, 1);
    zval_dtor(&val);
#else
    zend_object* obj = subklass->create_object(subklass TSRMLS_CC);
    ZVAL_OBJ(cached, obj);
    MessageHeader* intern = UNBOX_HASHTABLE_VALUE(MessageHeader, obj);
    custom_data_init(subklass, intern PHP_PROTO_TSRMLS_CC);
#endif
  }

  submsg_php = CACHED_PTR_TO_ZVAL_PTR(cached);

  submsg = UNBOX(MessageHeader, submsg_php);
  return submsg;
}

static void *map_wrapper_submsg_handler(void *closure, const void *hd) {
  MessageHeader* msg = closure;
  const submsg_handlerdata_t* submsgdata = hd;
  TSRMLS_FETCH();
  DescriptorInternal* subdesc = get_msgdef_desc(submsgdata->md);
  register_class(subdesc, false TSRMLS_CC);
  zend_class_entry* subklass = subdesc->klass;
  zval* submsg_php;
  MessageHeader* submsg;
  wrapperfields_parseframe_t* frame =
      (wrapperfields_parseframe_t*)malloc(sizeof(wrapperfields_parseframe_t));

  CACHED_VALUE* cached =
      DEREF(message_data(msg), submsgdata->ofs, CACHED_VALUE*);

  if (Z_TYPE_P(CACHED_PTR_TO_ZVAL_PTR(cached)) == IS_NULL) {
#if PHP_MAJOR_VERSION < 7
    zval val;
    ZVAL_OBJ(&val, subklass->create_object(subklass TSRMLS_CC));
    MessageHeader* intern = UNBOX(MessageHeader, &val);
    custom_data_init(subklass, intern PHP_PROTO_TSRMLS_CC);
    REPLACE_ZVAL_VALUE(cached, &val, 1);
    zval_dtor(&val);
#else
    zend_object* obj = subklass->create_object(subklass TSRMLS_CC);
    ZVAL_OBJ(cached, obj);
    MessageHeader* intern = UNBOX_HASHTABLE_VALUE(MessageHeader, obj);
    custom_data_init(subklass, intern PHP_PROTO_TSRMLS_CC);
#endif
  }

  submsg_php = CACHED_PTR_TO_ZVAL_PTR(cached);

  submsg = UNBOX(MessageHeader, submsg_php);
  frame->closure = closure;
  frame->submsg = submsg;
  frame->is_msg = true;
  return frame;
}

// Handler data for startmap/endmap handlers.
typedef struct {
  const upb_fielddef* fd;
  const upb_msgdef* value_md;
  upb_fieldtype_t key_field_type;
  upb_fieldtype_t value_field_type;
} map_handlerdata_t;

// Temporary frame for map parsing: at the beginning of a map entry message, a
// submsg handler allocates a frame to hold (i) a reference to the Map object
// into which this message will be inserted and (ii) storage slots to
// temporarily hold the key and value for this map entry until the end of the
// submessage. When the submessage ends, another handler is called to insert the
// value into the map.
typedef struct {
  char key_storage[NATIVE_SLOT_MAX_SIZE];
  char value_storage[NATIVE_SLOT_MAX_SIZE];
} map_parse_frame_data_t;

PHP_PROTO_WRAP_OBJECT_START(map_parse_frame_t)
  map_parse_frame_data_t* data;  // Place needs to be consistent with
                                 // MessageHeader.
  zval* map;
  // In php7, we cannot allocate zval dynamically. So we need to add zval here
  // to help decoding.
  zval key_zval;
  zval value_zval;
PHP_PROTO_WRAP_OBJECT_END
typedef struct map_parse_frame_t map_parse_frame_t;

static void map_slot_init(
    void* memory, upb_fieldtype_t type, zval* cache,
    const upb_msgdef* value_msg PHP_PROTO_TSRMLS_DC) {
  switch (type) {
    case UPB_TYPE_STRING:
    case UPB_TYPE_BYTES: {
#if PHP_MAJOR_VERSION < 7
      // Store zval** in memory in order to be consistent with the layout of
      // singular fields.
      zval** holder = ALLOC(zval*);
      *(zval***)memory = holder;
      zval* tmp;
      MAKE_STD_ZVAL(tmp);
      PHP_PROTO_ZVAL_STRINGL(tmp, "", 0, 1);
      *holder = tmp;
#else
      *(zval**)memory = cache;
      PHP_PROTO_ZVAL_STRINGL(*(zval**)memory, "", 0, 1);
#endif
      break;
    }
    case UPB_TYPE_MESSAGE: {
      DescriptorInternal* subdesc = get_msgdef_desc(value_msg);
      register_class(subdesc, false TSRMLS_CC);
      zend_class_entry* subklass = subdesc->klass;
      MessageHeader* submsg;
#if PHP_MAJOR_VERSION < 7
      zval** holder = ALLOC(zval*);
      zval* tmp;
      MAKE_STD_ZVAL(tmp);
      ZVAL_OBJ(tmp, subklass->create_object(subklass TSRMLS_CC));
      submsg = UNBOX(MessageHeader, tmp);
      custom_data_init(subklass, submsg PHP_PROTO_TSRMLS_CC);
      *holder = tmp;
      *(zval***)memory = holder;
#else
      *(zval**)memory = cache;
      ZVAL_OBJ(*(zval**)memory, subklass->create_object(subklass TSRMLS_CC));
      submsg = UNBOX(MessageHeader, cache);
      custom_data_init(subklass, submsg PHP_PROTO_TSRMLS_CC);
#endif
      break;
    }
    default:
      native_slot_init(type, memory, NULL);
  }
}

static void map_slot_uninit(void* memory, upb_fieldtype_t type) {
  switch (type) {
    case UPB_TYPE_MESSAGE:
    case UPB_TYPE_STRING:
    case UPB_TYPE_BYTES: {
#if PHP_MAJOR_VERSION < 7
      zval** holder = *(zval***)memory;
      zval_ptr_dtor(holder);
      FREE(holder);
#else
      php_proto_zval_ptr_dtor(*(zval**)memory);
#endif
      break;
    }
    default:
      break;
  }
}

static void map_slot_key(upb_fieldtype_t type, const void* from,
                         const char** keyval,
                         size_t* length) {
  if (type == UPB_TYPE_STRING) {
#if PHP_MAJOR_VERSION < 7
    zval* key_php = **(zval***)from;
#else
    zval* key_php = *(zval**)from;
#endif
    *keyval = Z_STRVAL_P(key_php);
    *length = Z_STRLEN_P(key_php);
  } else {
    *keyval = from;
    *length = native_slot_size(type);
  }
}

static void map_slot_value(upb_fieldtype_t type, const void* from,
                           upb_value* v) {
  size_t len;
  void* to = upb_value_memory(v);
#ifndef NDEBUG
  v->ctype = UPB_CTYPE_UINT64;
#endif

  memset(to, 0, native_slot_size(type));

  switch (type) {
#if PHP_MAJOR_VERSION < 7
    case UPB_TYPE_STRING:
    case UPB_TYPE_BYTES:
    case UPB_TYPE_MESSAGE: {
      *(zval**)to = **(zval***)from;
      Z_ADDREF_PP((zval**)to);
      break;
    }
#else
    case UPB_TYPE_STRING:
    case UPB_TYPE_BYTES:
      *(zend_string**)to = Z_STR_P(*(zval**)from);
      zend_string_addref(*(zend_string**)to);
      break;
    case UPB_TYPE_MESSAGE:
      if (!ZVAL_IS_NULL(*(zval**)from)) {
        *(zend_object**)to = Z_OBJ_P(*(zval**)from);
        GC_ADDREF(*(zend_object**)to);
      }
      break;
#endif
    default:
      len = native_slot_size(type);
      memcpy(to, from, len);
  }
}

// Handler to begin a map entry: allocates a temporary frame. This is the
// 'startsubmsg' handler on the msgdef that contains the map field.
static void *startmapentry_handler(void *closure, const void *hd) {
  MessageHeader* msg = closure;
  const map_handlerdata_t* mapdata = hd;
  CACHED_VALUE* cache = find_zval_property(msg, mapdata->fd);
  TSRMLS_FETCH();
  map_field_ensure_created(mapdata->fd, cache PHP_PROTO_TSRMLS_CC);
  zval* map = CACHED_PTR_TO_ZVAL_PTR(cache);

  map_parse_frame_t* frame = ALLOC(map_parse_frame_t);
  frame->data = ALLOC(map_parse_frame_data_t);
  frame->map = map;

  map_slot_init(&frame->data->key_storage, mapdata->key_field_type,
                &frame->key_zval, NULL PHP_PROTO_TSRMLS_CC);
  map_slot_init(&frame->data->value_storage, mapdata->value_field_type,
                &frame->value_zval, mapdata->value_md PHP_PROTO_TSRMLS_CC);

  return frame;
}

// Handler to end a map entry: inserts the value defined during the message into
// the map. This is the 'endmsg' handler on the map entry msgdef.
static bool endmap_handler(void* closure, const void* hd, upb_status* s) {
  map_parse_frame_t* frame = closure;
  const map_handlerdata_t* mapdata = hd;

  TSRMLS_FETCH();
  Map *map = UNBOX(Map, frame->map);

  const char* keyval = NULL;
  upb_value v;
  size_t length;

  map_slot_key(map->key_type, &frame->data->key_storage, &keyval, &length);
  map_slot_value(map->value_type, &frame->data->value_storage, &v);

  map_index_set(map, keyval, length, v);

  map_slot_uninit(&frame->data->key_storage, mapdata->key_field_type);
  map_slot_uninit(&frame->data->value_storage, mapdata->value_field_type);
  FREE(frame->data);
  FREE(frame);

  return true;
}

// Allocates a new map_handlerdata_t given the map entry message definition. If
// the offset of the field within the parent message is also given, that is
// added to the handler data as well. Note that this is called *twice* per map
// field: once in the parent message handler setup when setting the startsubmsg
// handler and once in the map entry message handler setup when setting the
// key/value and endmsg handlers. The reason is that there is no easy way to
// pass the handlerdata down to the sub-message handler setup.
static map_handlerdata_t* new_map_handlerdata(
    const upb_fielddef* field,
    const upb_msgdef* mapentry_def) {
  const upb_fielddef* key_field;
  const upb_fielddef* value_field;
  // TODO(teboring): Use emalloc and efree.
  map_handlerdata_t* hd =
      (map_handlerdata_t*)malloc(sizeof(map_handlerdata_t));
  PHP_PROTO_ASSERT(hd != NULL);
  hd->fd = field;
  key_field = upb_msgdef_itof(mapentry_def, MAP_KEY_FIELD);
  PHP_PROTO_ASSERT(key_field != NULL);
  hd->key_field_type = upb_fielddef_type(key_field);
  value_field = upb_msgdef_itof(mapentry_def, MAP_VALUE_FIELD);
  PHP_PROTO_ASSERT(value_field != NULL);
  hd->value_field_type = upb_fielddef_type(value_field);
  if (upb_fielddef_type(value_field) == UPB_TYPE_MESSAGE) {
    hd->value_md = upb_fielddef_msgsubdef(value_field);
  } else {
    hd->value_md = NULL;
  }

  return hd;
}

// Handlers that set primitive values in oneofs.
#define DEFINE_ONEOF_HANDLER(type, ctype)                          \
  static bool oneof##type##_handler(void* closure, const void* hd, \
                                    ctype val) {                   \
    const oneof_handlerdata_t* oneofdata = hd;                     \
    DEREF(message_data(closure), oneofdata->case_ofs, uint32_t) =  \
        oneofdata->oneof_case_num;                                 \
    DEREF(message_data(closure), oneofdata->ofs, ctype) = val;     \
    return true;                                                   \
  }

DEFINE_ONEOF_HANDLER(bool,   bool)
DEFINE_ONEOF_HANDLER(int32,  int32_t)
DEFINE_ONEOF_HANDLER(uint32, uint32_t)
DEFINE_ONEOF_HANDLER(float,  float)
DEFINE_ONEOF_HANDLER(int64,  int64_t)
DEFINE_ONEOF_HANDLER(uint64, uint64_t)
DEFINE_ONEOF_HANDLER(double, double)

#undef DEFINE_ONEOF_HANDLER

static void oneof_cleanup(MessageHeader* msg,
                          const oneof_handlerdata_t* oneofdata) {
  uint32_t old_case_num =
      DEREF(message_data(msg), oneofdata->case_ofs, uint32_t);
  if (old_case_num == 0) {
    return;
  }

  const upb_fielddef* old_field =
      upb_msgdef_itof(oneofdata->parent_md, old_case_num);
  bool need_clean = false;

  switch (upb_fielddef_type(old_field)) {
    case UPB_TYPE_STRING:
    case UPB_TYPE_BYTES:
      need_clean = true;
      break;
    case UPB_TYPE_MESSAGE:
      if (oneofdata->oneof_case_num != old_case_num) {
        need_clean = true;
      }
      break;
    default:
      break;
  }

  if (need_clean) {
#if PHP_MAJOR_VERSION < 7
    SEPARATE_ZVAL_IF_NOT_REF(
        DEREF(message_data(msg), oneofdata->ofs, CACHED_VALUE*));
    php_proto_zval_ptr_dtor(
        *DEREF(message_data(msg), oneofdata->ofs, CACHED_VALUE*));
    MAKE_STD_ZVAL(*DEREF(message_data(msg), oneofdata->ofs, CACHED_VALUE*));
    ZVAL_NULL(*DEREF(message_data(msg), oneofdata->ofs, CACHED_VALUE*));
#endif
  }
}

// Handlers for string/bytes in a oneof.
static bool oneofstr_end_handler(void *closure, const void *hd) {
  stringfields_parseframe_t* frame = closure;
  MessageHeader* msg = (MessageHeader*)frame->closure;
  const oneof_handlerdata_t *oneofdata = hd;

  oneof_cleanup(msg, oneofdata);

  DEREF(message_data(msg), oneofdata->case_ofs, uint32_t) =
      oneofdata->oneof_case_num;
  DEREF(message_data(msg), oneofdata->ofs, CACHED_VALUE*) =
      OBJ_PROP(&msg->std, oneofdata->property_ofs);

  new_php_string(DEREF(message_data(msg), oneofdata->ofs, CACHED_VALUE*),
                 frame->sink.ptr, frame->sink.len);

  stringsink_uninit(&frame->sink);
  free(frame);

  return true;
}

static void *oneofstr_handler(void *closure,
                              const void *hd,
                              size_t size_hint) {
  PHP_PROTO_UNUSED(hd);

  stringfields_parseframe_t* frame =
      (stringfields_parseframe_t*)malloc(sizeof(stringfields_parseframe_t));
  PHP_PROTO_ASSERT(frame != NULL);
  frame->closure = closure;
  stringsink_init(&frame->sink);

  return frame;
}

// Handler for a submessage field in a oneof.
static void* oneofsubmsg_handler(void* closure, const void* hd) {
  MessageHeader* msg = closure;
  const oneof_handlerdata_t *oneofdata = hd;
  uint32_t oldcase = DEREF(message_data(msg), oneofdata->case_ofs, uint32_t);
  TSRMLS_FETCH();
  DescriptorInternal* subdesc = get_msgdef_desc(oneofdata->md);
  register_class(subdesc, false TSRMLS_CC);
  zend_class_entry* subklass = subdesc->klass;
  zval* submsg_php;
  MessageHeader* submsg;

  if (oldcase != oneofdata->oneof_case_num) {
    oneof_cleanup(msg, oneofdata);

    // Create new message.
    DEREF(message_data(msg), oneofdata->ofs, CACHED_VALUE*) =
        OBJ_PROP(&msg->std, oneofdata->property_ofs);
#if PHP_MAJOR_VERSION < 7
    zval val;
    ZVAL_OBJ(&val, subklass->create_object(subklass TSRMLS_CC));
    REPLACE_ZVAL_VALUE(DEREF(message_data(msg), oneofdata->ofs, zval**),
                       &val, 1);
    zval_dtor(&val);
#else
    zend_object* obj = subklass->create_object(subklass TSRMLS_CC);
    ZVAL_OBJ(DEREF(message_data(msg), oneofdata->ofs, zval*), obj);
#endif
  }

  DEREF(message_data(msg), oneofdata->case_ofs, uint32_t) =
      oneofdata->oneof_case_num;

  submsg_php = CACHED_PTR_TO_ZVAL_PTR(
      DEREF(message_data(msg), oneofdata->ofs, CACHED_VALUE*));
  submsg = UNBOX(MessageHeader, submsg_php);
  custom_data_init(subklass, submsg PHP_PROTO_TSRMLS_CC);
  return submsg;
}

// Sets a non-repeated wrapper submessage field in a message.
static void* wrapper_submsg_handler(void* closure, const void* hd) {
  MessageHeader* msg = closure;
  const submsg_handlerdata_t* submsgdata = hd;
  TSRMLS_FETCH();
  DescriptorInternal* subdesc = get_msgdef_desc(submsgdata->md);
  register_class(subdesc, false TSRMLS_CC);
  zval* submsg_php;
  MessageHeader* submsg;
  wrapperfields_parseframe_t* frame =
      (wrapperfields_parseframe_t*)malloc(sizeof(wrapperfields_parseframe_t));

  CACHED_VALUE* cached = find_zval_property(msg, submsgdata->fd);
  submsg_php = CACHED_PTR_TO_ZVAL_PTR(cached);
  frame->closure = closure;

  if (Z_TYPE_P(CACHED_PTR_TO_ZVAL_PTR(cached)) == IS_OBJECT) {
    submsg = UNBOX(MessageHeader, submsg_php);
    frame->submsg = submsg;
    frame->is_msg = true;
  } else {
    if (Z_TYPE_P(CACHED_PTR_TO_ZVAL_PTR(cached)) == IS_NULL) {
      // Needs to initiate the wrapper message
      const upb_msgdef* msgdef = subdesc->msgdef;
      const upb_fielddef* f = upb_msgdef_itof(msgdef, 1);
      native_slot_get_default(upb_fielddef_type(f), cached TSRMLS_CC);
    }
    // In this case, wrapper message hasn't been created and value will be
    // stored in cache directly.
    frame->submsg = cached;
    frame->is_msg = false;
  }

  return frame;
}

// Handler for a wrapper submessage field in a oneof.
static void* wrapper_oneofsubmsg_handler(void* closure, const void* hd) {
  MessageHeader* msg = closure;
  const oneof_handlerdata_t *oneofdata = hd;
  uint32_t oldcase = DEREF(message_data(msg), oneofdata->case_ofs, uint32_t);
  TSRMLS_FETCH();
  DescriptorInternal* subdesc = get_msgdef_desc(oneofdata->md);
  register_class(subdesc, false TSRMLS_CC);
  wrapperfields_parseframe_t* frame =
      (wrapperfields_parseframe_t*)malloc(sizeof(wrapperfields_parseframe_t));
  CACHED_VALUE* cached = OBJ_PROP(&msg->std, oneofdata->property_ofs);
  MessageHeader* submsg;

  if (oldcase != oneofdata->oneof_case_num) {
    oneof_cleanup(msg, oneofdata);
    if (Z_TYPE_P(CACHED_PTR_TO_ZVAL_PTR(cached)) == IS_NULL) {
      // Needs to initiate the wrapper message
      const upb_msgdef* msgdef = subdesc->msgdef;
      const upb_fielddef* f = upb_msgdef_itof(msgdef, 1);
      native_slot_get_default(upb_fielddef_type(f), cached TSRMLS_CC);
    }
    frame->submsg = cached;
    frame->is_msg = false;
  } else if (Z_TYPE_P(CACHED_PTR_TO_ZVAL_PTR(cached)) == IS_OBJECT) {
    submsg = UNBOX(MessageHeader, CACHED_PTR_TO_ZVAL_PTR(cached));
    frame->submsg = submsg;
    frame->is_msg = true;
  } else {
    // In this case, wrapper message hasn't been created and value will be
    // stored in cache directly.
    frame->submsg = cached;
    frame->is_msg = false;
  }

  DEREF(message_data(msg), oneofdata->case_ofs, uint32_t) =
      oneofdata->oneof_case_num;

  return frame;
}

static bool wrapper_submsg_end_handler(void *closure, const void *hd) {
  wrapperfields_parseframe_t* frame = closure;
  free(frame);
  return true;
}

// Set up handlers for a repeated field.
static void add_handlers_for_repeated_field(upb_handlers *h,
                                            const upb_fielddef *f,
                                            size_t offset) {
  upb_handlerattr attr = UPB_HANDLERATTR_INIT;
  attr.handler_data = newhandlerfielddata(h, f);
  upb_handlers_setstartseq(h, f, startseq_handler, &attr);

  switch (upb_fielddef_type(f)) {

#define SET_HANDLER(utype, ltype)                                 \
  case utype:                                                     \
    upb_handlers_set##ltype(h, f, append##ltype##_handler, NULL); \
    break;

    SET_HANDLER(UPB_TYPE_BOOL,   bool);
    SET_HANDLER(UPB_TYPE_INT32,  int32);
    SET_HANDLER(UPB_TYPE_UINT32, uint32);
    SET_HANDLER(UPB_TYPE_ENUM,   int32);
    SET_HANDLER(UPB_TYPE_FLOAT,  float);
    SET_HANDLER(UPB_TYPE_INT64,  int64);
    SET_HANDLER(UPB_TYPE_UINT64, uint64);
    SET_HANDLER(UPB_TYPE_DOUBLE, double);

#undef SET_HANDLER

    case UPB_TYPE_STRING:
    case UPB_TYPE_BYTES: {
      upb_handlers_setstartstr(h, f, appendstr_handler, NULL);
      upb_handlers_setstring(h, f, stringdata_handler, NULL);
      upb_handlers_setendstr(h, f, appendstr_end_handler, &attr);
      break;
    }
    case UPB_TYPE_MESSAGE: {
      upb_handlerattr attr = UPB_HANDLERATTR_INIT;
      attr.handler_data = newsubmsghandlerdata(h, 0, f);
      if (is_wrapper_msg(upb_fielddef_msgsubdef(f))) {
        upb_handlers_setstartsubmsg(h, f, appendwrappersubmsg_handler, &attr);
        upb_handlers_setendsubmsg(h, f, wrapper_submsg_end_handler, &attr);
      } else {
        upb_handlers_setstartsubmsg(h, f, appendsubmsg_handler, &attr);
      }
      break;
    }
  }
}

// Set up handlers for a singular field.
static void add_handlers_for_singular_field(upb_handlers *h,
                                            const upb_fielddef *f,
                                            size_t offset, bool is_map) {
  switch (upb_fielddef_type(f)) {
#define SET_HANDLER(utype, ltype)                          \
  case utype: {                                            \
    upb_handlerattr attr = UPB_HANDLERATTR_INIT;           \
    attr.handler_data = newhandlerdata(h, offset);         \
    upb_handlers_set##ltype(h, f, ltype##_handler, &attr); \
    break;                                                 \
  }

    SET_HANDLER(UPB_TYPE_BOOL,   bool);
    SET_HANDLER(UPB_TYPE_INT32,  int32);
    SET_HANDLER(UPB_TYPE_UINT32, uint32);
    SET_HANDLER(UPB_TYPE_ENUM,   int32);
    SET_HANDLER(UPB_TYPE_FLOAT,  float);
    SET_HANDLER(UPB_TYPE_INT64,  int64);
    SET_HANDLER(UPB_TYPE_UINT64, uint64);
    SET_HANDLER(UPB_TYPE_DOUBLE, double);

#undef SET_HANDLER

    case UPB_TYPE_STRING:
    case UPB_TYPE_BYTES: {
      upb_handlerattr attr = UPB_HANDLERATTR_INIT;
      if (is_map) {
        attr.handler_data = newhandlerdata(h, offset);
      } else {
        attr.handler_data = newhandlerfielddata(h, f);
      }
      upb_handlers_setstartstr(h, f, str_handler, &attr);
      upb_handlers_setstring(h, f, stringdata_handler, &attr);
      if (is_map) {
        upb_handlers_setendstr(h, f, map_str_end_handler, &attr);
      } else {
        upb_handlers_setendstr(h, f, str_end_handler, &attr);
      }
      break;
    }
    case UPB_TYPE_MESSAGE: {
      upb_handlerattr attr = UPB_HANDLERATTR_INIT;
      if (is_map) {
        attr.handler_data = newsubmsghandlerdata(h, offset, f);
        if (is_wrapper_msg(upb_fielddef_msgsubdef(f))) {
          upb_handlers_setstartsubmsg(h, f, map_wrapper_submsg_handler, &attr);
          upb_handlers_setendsubmsg(h, f, wrapper_submsg_end_handler, &attr);
        } else {
          upb_handlers_setstartsubmsg(h, f, map_submsg_handler, &attr);
        }
      } else if (is_wrapper_msg(upb_fielddef_msgsubdef(f))) {
        attr.handler_data = newsubmsghandlerdata(h, 0, f);
        upb_handlers_setstartsubmsg(h, f, wrapper_submsg_handler, &attr);
        upb_handlers_setendsubmsg(h, f, wrapper_submsg_end_handler, &attr);
      } else {
        attr.handler_data = newsubmsghandlerdata(h, 0, f);
        upb_handlers_setstartsubmsg(h, f, submsg_handler, &attr);
      }
      break;
    }
  }
}

// Adds handlers to a map field.
static void add_handlers_for_mapfield(upb_handlers* h,
                                      const upb_fielddef* fielddef,
                                      size_t offset) {
  const upb_msgdef* map_msgdef = upb_fielddef_msgsubdef(fielddef);
  map_handlerdata_t* hd = new_map_handlerdata(fielddef, map_msgdef);
  upb_handlerattr attr = UPB_HANDLERATTR_INIT;

  upb_handlers_addcleanup(h, hd, free);
  attr.handler_data = hd;
  upb_handlers_setstartsubmsg(h, fielddef, startmapentry_handler, &attr);
}

// Adds handlers to a map-entry msgdef.
static void add_handlers_for_mapentry(
    const upb_msgdef* msgdef, upb_handlers* h) {
  const upb_fielddef* key_field = map_entry_key(msgdef);
  const upb_fielddef* value_field = map_entry_value(msgdef);
  map_handlerdata_t* hd = new_map_handlerdata(0, msgdef);
  upb_handlerattr attr = UPB_HANDLERATTR_INIT;

  upb_handlers_addcleanup(h, hd, free);
  attr.handler_data = hd;
  upb_handlers_setendmsg(h, endmap_handler, &attr);

  add_handlers_for_singular_field(h, key_field,
                                  offsetof(map_parse_frame_data_t,
                                           key_storage), true);
  add_handlers_for_singular_field(h, value_field,
                                  offsetof(map_parse_frame_data_t,
                                           value_storage), true);
}

// Set up handlers for a oneof field.
static void add_handlers_for_oneof_field(upb_handlers *h,
                                         const upb_msgdef *m,
                                         const upb_fielddef *f,
                                         size_t offset,
                                         size_t oneof_case_offset,
                                         int property_cache_offset) {

  upb_handlerattr attr = UPB_HANDLERATTR_INIT;
  attr.handler_data = newoneofhandlerdata(h, offset, oneof_case_offset,
                                          property_cache_offset, m, f);

  switch (upb_fielddef_type(f)) {

#define SET_HANDLER(utype, ltype)                                 \
  case utype:                                                     \
    upb_handlers_set##ltype(h, f, oneof##ltype##_handler, &attr); \
    break;

    SET_HANDLER(UPB_TYPE_BOOL,   bool);
    SET_HANDLER(UPB_TYPE_INT32,  int32);
    SET_HANDLER(UPB_TYPE_UINT32, uint32);
    SET_HANDLER(UPB_TYPE_ENUM,   int32);
    SET_HANDLER(UPB_TYPE_FLOAT,  float);
    SET_HANDLER(UPB_TYPE_INT64,  int64);
    SET_HANDLER(UPB_TYPE_UINT64, uint64);
    SET_HANDLER(UPB_TYPE_DOUBLE, double);

#undef SET_HANDLER

    case UPB_TYPE_STRING:
    case UPB_TYPE_BYTES: {
      upb_handlers_setstartstr(h, f, oneofstr_handler, &attr);
      upb_handlers_setstring(h, f, stringdata_handler, NULL);
      upb_handlers_setendstr(h, f, oneofstr_end_handler, &attr);
      break;
    }
    case UPB_TYPE_MESSAGE: {
      if (is_wrapper_msg(upb_fielddef_msgsubdef(f))) {
        upb_handlers_setstartsubmsg(h, f, wrapper_oneofsubmsg_handler, &attr);
        upb_handlers_setendsubmsg(h, f, wrapper_submsg_end_handler, &attr);
      } else {
        upb_handlers_setstartsubmsg(h, f, oneofsubmsg_handler, &attr);
      }
      break;
    }
  }
}

#define DEFINE_WRAPPER_HANDLER(utype, type, ctype)           \
  static bool type##wrapper_handler(                         \
      void* closure, const void* hd, ctype val) {            \
    wrapperfields_parseframe_t* frame = closure;             \
    if (frame->is_msg) {                                     \
      MessageHeader* msg = frame->submsg;                    \
      const size_t *ofs = hd;                                \
      DEREF(message_data(msg), *ofs, ctype) = val;           \
    } else {                                                 \
      TSRMLS_FETCH();                                        \
      native_slot_get(utype, &val, frame->submsg TSRMLS_CC); \
    }                                                        \
    return true;                                             \
  }

DEFINE_WRAPPER_HANDLER(UPB_TYPE_BOOL,   bool,   bool)
DEFINE_WRAPPER_HANDLER(UPB_TYPE_INT32,  int32,  int32_t)
DEFINE_WRAPPER_HANDLER(UPB_TYPE_UINT32, uint32, uint32_t)
DEFINE_WRAPPER_HANDLER(UPB_TYPE_FLOAT,  float,  float)
DEFINE_WRAPPER_HANDLER(UPB_TYPE_INT64,  int64,  int64_t)
DEFINE_WRAPPER_HANDLER(UPB_TYPE_UINT64, uint64, uint64_t)
DEFINE_WRAPPER_HANDLER(UPB_TYPE_DOUBLE, double, double)

#undef DEFINE_WRAPPER_HANDLER

static bool strwrapper_end_handler(void *closure, const void *hd) {
  stringfields_parseframe_t* frame = closure;
  const upb_fielddef **field = (const upb_fielddef **) hd;
  wrapperfields_parseframe_t* wrapper_frame = frame->closure;
  MessageHeader* msg;
  CACHED_VALUE* cached;

  if (wrapper_frame->is_msg) {
    msg = wrapper_frame->submsg;
    cached = find_zval_property(msg, *field);
  } else {
    cached = wrapper_frame->submsg;
  }

  new_php_string(cached, frame->sink.ptr, frame->sink.len);

  stringsink_uninit(&frame->sink);
  free(frame);

  return true;
}

static void add_handlers_for_wrapper(const upb_msgdef* msgdef,
                                     upb_handlers* h) {
  const upb_fielddef* f = upb_msgdef_itof(msgdef, 1);
  DescriptorInternal* desc;
  size_t offset;

  TSRMLS_FETCH();
  desc = get_msgdef_desc(msgdef);
  offset = desc->layout->fields[upb_fielddef_index(f)].offset;

  switch (upb_msgdef_wellknowntype(msgdef)) {
#define SET_HANDLER(utype, ltype)                                 \
  case utype: {                                                   \
    upb_handlerattr attr = UPB_HANDLERATTR_INIT;                  \
    attr.handler_data = newhandlerdata(h, offset);                \
    upb_handlers_set##ltype(h, f, ltype##wrapper_handler, &attr); \
    break;                                                        \
  }

    SET_HANDLER(UPB_WELLKNOWN_BOOLVALUE,   bool);
    SET_HANDLER(UPB_WELLKNOWN_INT32VALUE,  int32);
    SET_HANDLER(UPB_WELLKNOWN_UINT32VALUE, uint32);
    SET_HANDLER(UPB_WELLKNOWN_FLOATVALUE,  float);
    SET_HANDLER(UPB_WELLKNOWN_INT64VALUE,  int64);
    SET_HANDLER(UPB_WELLKNOWN_UINT64VALUE, uint64);
    SET_HANDLER(UPB_WELLKNOWN_DOUBLEVALUE, double);

#undef SET_HANDLER

    case UPB_WELLKNOWN_STRINGVALUE:
    case UPB_WELLKNOWN_BYTESVALUE: {
      upb_handlerattr attr = UPB_HANDLERATTR_INIT;
      attr.handler_data = newhandlerfielddata(h, f);

      upb_handlers_setstartstr(h, f, str_handler, &attr);
      upb_handlers_setstring(h, f, stringdata_handler, &attr);
      upb_handlers_setendstr(h, f, strwrapper_end_handler, &attr);
      break;
    }
    default:
      // Cannot reach here.
      break;
  }
}

static bool add_unknown_handler(void* closure, const void* hd, const char* buf,
                         size_t size) {
  encodeunknown_handlerfunc handler =
      ((unknownfields_handlerdata_t*)hd)->handler;

  MessageHeader* msg = (MessageHeader*)closure;
  stringsink* unknown = DEREF(message_data(msg), 0, stringsink*);
  if (unknown == NULL) {
    DEREF(message_data(msg), 0, stringsink*) = ALLOC(stringsink);
    unknown = DEREF(message_data(msg), 0, stringsink*);
    stringsink_init(unknown);
  }

  handler(unknown, NULL, buf, size, NULL);

  return true;
}

void add_handlers_for_message(const void* closure, upb_handlers* h) {
  const upb_msgdef* msgdef = upb_handlers_msgdef(h);
  TSRMLS_FETCH();
  DescriptorInternal* desc = get_msgdef_desc(msgdef);
  register_class(desc, false TSRMLS_CC);
  upb_msg_field_iter i;

  // If this is a mapentry message type, set up a special set of handlers and
  // bail out of the normal (user-defined) message type handling.
  if (upb_msgdef_mapentry(msgdef)) {
    add_handlers_for_mapentry(msgdef, h);
    return;
  }

  // If this is a wrapper message type, set up a special set of handlers and
  // bail out of the normal (user-defined) message type handling.
  if (is_wrapper_msg(msgdef)) {
    add_handlers_for_wrapper(msgdef, h);
    return;
  }

  upb_handlerattr attr = UPB_HANDLERATTR_INIT;
  attr.handler_data = newunknownfieldshandlerdata(h);
  upb_handlers_setunknown(h, add_unknown_handler, &attr);

  for (upb_msg_field_begin(&i, desc->msgdef);
       !upb_msg_field_done(&i);
       upb_msg_field_next(&i)) {
    const upb_fielddef *f = upb_msg_iter_field(&i);
    size_t offset = desc->layout->fields[upb_fielddef_index(f)].offset;

    if (upb_fielddef_containingoneof(f)) {
      size_t oneof_case_offset =
          desc->layout->fields[upb_fielddef_index(f)].case_offset;
      int property_cache_index =
          desc->layout->fields[upb_fielddef_index(f)].cache_index;
      add_handlers_for_oneof_field(h, desc->msgdef, f, offset,
                                   oneof_case_offset, property_cache_index);
    } else if (is_map_field(f)) {
      add_handlers_for_mapfield(h, f, offset);
    } else if (upb_fielddef_isseq(f)) {
      add_handlers_for_repeated_field(h, f, offset);
    } else {
      add_handlers_for_singular_field(h, f, offset, false);
    }
  }
}

// Constructs the handlers for filling a message's data into an in-memory
// object.
const upb_handlers* get_fill_handlers(DescriptorInternal* desc) {
  return upb_handlercache_get(desc->pool->fill_handler_cache, desc->msgdef);
}

static const upb_pbdecodermethod *msgdef_decodermethod(DescriptorInternal* desc) {
  return upb_pbcodecache_get(desc->pool->fill_method_cache, desc->msgdef);
}

static const upb_json_parsermethod *msgdef_jsonparsermethod(DescriptorInternal* desc) {
  return upb_json_codecache_get(desc->pool->json_fill_method_cache, desc->msgdef);
}

// -----------------------------------------------------------------------------
// Serializing.
// -----------------------------------------------------------------------------

static void putmsg(zval* msg, const DescriptorInternal* desc, upb_sink sink,
                   int depth, bool is_json TSRMLS_DC);
static void putrawmsg(MessageHeader* msg, const DescriptorInternal* desc,
                      upb_sink sink, int depth, bool is_json,
                      bool open_msg TSRMLS_DC);
static void putwrappervalue(
    zval* value, const upb_fielddef* f,
    upb_sink sink, int depth, bool is_json TSRMLS_DC);
static void putjsonany(MessageHeader* msg, const DescriptorInternal* desc,
                       upb_sink sink, int depth TSRMLS_DC);
static void putjsonlistvalue(
    MessageHeader* msg, const DescriptorInternal* desc,
    upb_sink sink, int depth TSRMLS_DC);
static void putjsonstruct(
    MessageHeader* msg, const DescriptorInternal* desc,
    upb_sink sink, int depth TSRMLS_DC);

static void putstr(zval* str, const upb_fielddef* f, upb_sink sink,
                   bool force_default);

static void putrawstr(const char* str, int len, const upb_fielddef* f,
                      upb_sink sink, bool force_default);

static void putsubmsg(zval* submsg, const upb_fielddef* f, upb_sink sink,
                      int depth, bool is_json TSRMLS_DC);
static void putrawsubmsg(MessageHeader* submsg, const upb_fielddef* f,
                         upb_sink sink, int depth, bool is_json TSRMLS_DC);

static void putarray(zval* array, const upb_fielddef* f, upb_sink sink,
                     int depth, bool is_json TSRMLS_DC);
static void putmap(zval* map, const upb_fielddef* f, upb_sink sink,
                   int depth, bool is_json TSRMLS_DC);

static upb_selector_t getsel(const upb_fielddef* f, upb_handlertype_t type) {
  upb_selector_t ret;
  bool ok = upb_handlers_getselector(f, type, &ret);
  PHP_PROTO_ASSERT(ok);
  return ret;
}

static void put_optional_value(const void* memory, int len,
                               const upb_fielddef* f,
                               int depth, upb_sink sink,
                               bool is_json TSRMLS_DC) {
  PHP_PROTO_ASSERT(upb_fielddef_label(f) == UPB_LABEL_OPTIONAL);

  switch (upb_fielddef_type(f)) {
#define T(upbtypeconst, upbtype, ctype, default_value)                         \
  case upbtypeconst: {                                                         \
    ctype value = DEREF(memory, 0, ctype);                                     \
    if (is_json || value != default_value) {                                   \
      upb_selector_t sel = getsel(f, upb_handlers_getprimitivehandlertype(f)); \
      upb_sink_put##upbtype(sink, sel, value);                                 \
    }                                                                          \
  } break;

    T(UPB_TYPE_FLOAT, float, float, 0.0)
    T(UPB_TYPE_DOUBLE, double, double, 0.0)
    T(UPB_TYPE_BOOL, bool, uint8_t, 0)
    T(UPB_TYPE_ENUM, int32, int32_t, 0)
    T(UPB_TYPE_INT32, int32, int32_t, 0)
    T(UPB_TYPE_UINT32, uint32, uint32_t, 0)
    T(UPB_TYPE_INT64, int64, int64_t, 0)
    T(UPB_TYPE_UINT64, uint64, uint64_t, 0)

#undef T
    case UPB_TYPE_STRING:
    case UPB_TYPE_BYTES:
      putrawstr(memory, len, f, sink, is_json);
      break;
    case UPB_TYPE_MESSAGE: {
#if PHP_MAJOR_VERSION < 7
      MessageHeader *submsg = UNBOX(MessageHeader, *(zval**)memory);
#else
      MessageHeader *submsg =
          (MessageHeader*)((char*)(*(zend_object**)memory) -
              XtOffsetOf(MessageHeader, std));
#endif
      putrawsubmsg(submsg, f, sink, depth, is_json TSRMLS_CC);
      break;
    }
    default:
      PHP_PROTO_ASSERT(false);
  }
}

// Only string/bytes fields are stored as zval.
static const char* raw_value(void* memory, const upb_fielddef* f) {
  switch (upb_fielddef_type(f)) {
    case UPB_TYPE_STRING:
    case UPB_TYPE_BYTES:
#if PHP_MAJOR_VERSION < 7
      return Z_STRVAL_PP((zval**)memory);
#else
      return ZSTR_VAL(*(zend_string**)memory);
#endif
      break;
    default:
      return memory;
  }
}

static int raw_value_len(void* memory, int len, const upb_fielddef* f) {
  switch (upb_fielddef_type(f)) {
    case UPB_TYPE_STRING:
    case UPB_TYPE_BYTES:
#if PHP_MAJOR_VERSION < 7
      return Z_STRLEN_PP((zval**)memory);
#else
      return ZSTR_LEN(*(zend_string**)memory);
#endif
    default:
      return len;
  }
}

static void putmap(zval* map, const upb_fielddef* f, upb_sink sink,
                   int depth, bool is_json TSRMLS_DC) {
  upb_sink subsink;
  const upb_fielddef* key_field;
  const upb_fielddef* value_field;
  MapIter it;
  int len, size;

  PHP_PROTO_ASSERT(map != NULL);
  Map* intern = UNBOX(Map, map);
  size = upb_strtable_count(&intern->table);
  if (size == 0) return;

  upb_sink_startseq(sink, getsel(f, UPB_HANDLER_STARTSEQ), &subsink);

  PHP_PROTO_ASSERT(upb_fielddef_type(f) == UPB_TYPE_MESSAGE);
  key_field = map_field_key(f);
  value_field = map_field_value(f);

  for (map_begin(map, &it TSRMLS_CC); !map_done(&it); map_next(&it)) {
    upb_status status;

    upb_sink entry_sink;
    upb_sink_startsubmsg(subsink, getsel(f, UPB_HANDLER_STARTSUBMSG),
                         &entry_sink);
    upb_sink_startmsg(entry_sink);

    // Serialize key.
    const char *key = map_iter_key(&it, &len);
    put_optional_value(key, len, key_field, depth + 1,
                       entry_sink, is_json TSRMLS_CC);

    // Serialize value.
    upb_value value = map_iter_value(&it, &len);
    put_optional_value(raw_value(upb_value_memory(&value), value_field),
                       raw_value_len(upb_value_memory(&value), len, value_field),
                       value_field, depth + 1, entry_sink, is_json TSRMLS_CC);

    upb_sink_endmsg(entry_sink, &status);
    upb_sink_endsubmsg(subsink, entry_sink, getsel(f, UPB_HANDLER_ENDSUBMSG));
  }

  upb_sink_endseq(sink, getsel(f, UPB_HANDLER_ENDSEQ));
}

static void putmsg(zval* msg_php, const DescriptorInternal* desc, upb_sink sink,
                   int depth, bool is_json TSRMLS_DC) {
  MessageHeader* msg = UNBOX(MessageHeader, msg_php);
  putrawmsg(msg, desc, sink, depth, is_json, true TSRMLS_CC);
}

static const upb_handlers* msgdef_json_serialize_handlers(
    DescriptorInternal* desc, bool preserve_proto_fieldnames);

static void putjsonany(MessageHeader* msg, const DescriptorInternal* desc,
                       upb_sink sink, int depth TSRMLS_DC) {
  upb_status status;
  const upb_fielddef* type_field = upb_msgdef_itof(desc->msgdef, UPB_ANY_TYPE);
  const upb_fielddef* value_field = upb_msgdef_itof(desc->msgdef, UPB_ANY_VALUE);

  zval* type_url_php_str;
  const upb_msgdef *payload_type = NULL;

  upb_sink_startmsg(sink);

  /* Handle type url */
  type_url_php_str = CACHED_PTR_TO_ZVAL_PTR(find_zval_property(msg, type_field));
  if (Z_STRLEN_P(type_url_php_str) > 0) {
    putstr(type_url_php_str, type_field, sink, false);
  }

  {
    const char* type_url_str = Z_STRVAL_P(type_url_php_str);
    size_t type_url_len = Z_STRLEN_P(type_url_php_str);
    if (type_url_len <= 20 ||
        strncmp(type_url_str, "type.googleapis.com/", 20) != 0) {
      zend_error(E_ERROR, "Invalid type url: %s", type_url_str);
    }

    /* Resolve type url */
    type_url_str += 20;
    type_url_len -= 20;

    payload_type = upb_symtab_lookupmsg2(
        generated_pool->symtab, type_url_str, type_url_len);
    if (payload_type == NULL) {
      zend_error(E_ERROR, "Unknown type: %s", type_url_str);
      return;
    }
  }

  {
    zval* value_php_str;
    const char* value_str;
    size_t value_len;

    value_php_str = CACHED_PTR_TO_ZVAL_PTR(find_zval_property(msg, value_field));
    value_str = Z_STRVAL_P(value_php_str);
    value_len = Z_STRLEN_P(value_php_str);

    if (value_len > 0) {
      DescriptorInternal* payload_desc = get_msgdef_desc(payload_type);
      register_class(payload_desc, false TSRMLS_CC);
      zend_class_entry* payload_klass = payload_desc->klass;
      zval val;
      upb_sink subsink;
      bool is_wellknown;

      /* Create message of the payload type. */
      ZVAL_OBJ(&val, payload_klass->create_object(payload_klass TSRMLS_CC));
      MessageHeader* intern = UNBOX(MessageHeader, &val);
      custom_data_init(payload_klass, intern PHP_PROTO_TSRMLS_CC);

      merge_from_string(value_str, value_len, payload_desc, intern);

      is_wellknown =
          upb_msgdef_wellknowntype(payload_desc->msgdef) !=
              UPB_WELLKNOWN_UNSPECIFIED;
      if (is_wellknown) {
        upb_sink_startstr(sink, getsel(value_field, UPB_HANDLER_STARTSTR), 0,
                          &subsink);
      }

      subsink.handlers =
          msgdef_json_serialize_handlers(payload_desc, true);
      subsink.closure = sink.closure;
      putrawmsg(intern, payload_desc, subsink, depth, true,
                is_wellknown TSRMLS_CC);

      zval_dtor(&val);
    }
  }

  upb_sink_endmsg(sink, &status);
}

static void putjsonlistvalue(
    MessageHeader* msg, const DescriptorInternal* desc,
    upb_sink sink, int depth TSRMLS_DC) {
  upb_status status;
  upb_sink subsink;
  const upb_fielddef* f = upb_msgdef_itof(desc->msgdef, 1);
  zval* array;
  RepeatedField* intern;
  HashTable *ht;
  int size;

  upb_sink_startmsg(sink);

  array = CACHED_PTR_TO_ZVAL_PTR(find_zval_property(msg, f));
  if (ZVAL_IS_NULL(array)) {
    upb_sink_startseq(sink, getsel(f, UPB_HANDLER_STARTSEQ), &subsink);
    upb_sink_endseq(sink, getsel(f, UPB_HANDLER_ENDSEQ));
  } else {
    intern = UNBOX(RepeatedField, array);
    ht = PHP_PROTO_HASH_OF(intern->array);
    size = zend_hash_num_elements(ht);

    if (size == 0) {
      upb_sink_startseq(sink, getsel(f, UPB_HANDLER_STARTSEQ), &subsink);
      upb_sink_endseq(sink, getsel(f, UPB_HANDLER_ENDSEQ));
    } else {
      putarray(array, f, sink, depth, true TSRMLS_CC);
    }
  }

  upb_sink_endmsg(sink, &status);
}

static void putjsonstruct(
    MessageHeader* msg, const DescriptorInternal* desc,
    upb_sink sink, int depth TSRMLS_DC) {
  upb_status status;
  upb_sink subsink;
  const upb_fielddef* f = upb_msgdef_itof(desc->msgdef, 1);
  zval* map;
  Map* intern;
  int size;

  upb_sink_startmsg(sink);

  map = CACHED_PTR_TO_ZVAL_PTR(find_zval_property(msg, f));
  if (ZVAL_IS_NULL(map)) {
    upb_sink_startseq(sink, getsel(f, UPB_HANDLER_STARTSEQ), &subsink);
    upb_sink_endseq(sink, getsel(f, UPB_HANDLER_ENDSEQ));
  } else {
    intern = UNBOX(Map, map);
    size = upb_strtable_count(&intern->table);

    if (size == 0) {
      upb_sink_startseq(sink, getsel(f, UPB_HANDLER_STARTSEQ), &subsink);
      upb_sink_endseq(sink, getsel(f, UPB_HANDLER_ENDSEQ));
    } else {
      putmap(map, f, sink, depth, true TSRMLS_CC);
    }
  }

  upb_sink_endmsg(sink, &status);
}

static void putrawmsg(MessageHeader* msg, const DescriptorInternal* desc,
                      upb_sink sink, int depth, bool is_json,
                      bool open_msg TSRMLS_DC) {
  upb_msg_field_iter i;
  upb_status status;

  if (is_json &&
      upb_msgdef_wellknowntype(desc->msgdef) == UPB_WELLKNOWN_ANY) {
    putjsonany(msg, desc, sink, depth TSRMLS_CC);
    return;
  }

  if (is_json &&
      upb_msgdef_wellknowntype(desc->msgdef) == UPB_WELLKNOWN_LISTVALUE) {
    putjsonlistvalue(msg, desc, sink, depth TSRMLS_CC);
    return;
  }

  if (is_json &&
      upb_msgdef_wellknowntype(desc->msgdef) == UPB_WELLKNOWN_STRUCT) {
    putjsonstruct(msg, desc, sink, depth TSRMLS_CC);
    return;
  }

  if (open_msg) {
    upb_sink_startmsg(sink);
  }

  // Protect against cycles (possible because users may freely reassign message
  // and repeated fields) by imposing a maximum recursion depth.
  if (depth > ENCODE_MAX_NESTING) {
    zend_error(E_ERROR,
             "Maximum recursion depth exceeded during encoding.");
  }

  for (upb_msg_field_begin(&i, desc->msgdef); !upb_msg_field_done(&i);
       upb_msg_field_next(&i)) {
    upb_fielddef* f = upb_msg_iter_field(&i);
    uint32_t offset = desc->layout->fields[upb_fielddef_index(f)].offset;
    bool containing_oneof = false;

    if (upb_fielddef_containingoneof(f)) {
      uint32_t oneof_case_offset =
          desc->layout->fields[upb_fielddef_index(f)].case_offset;
      // For a oneof, check that this field is actually present -- skip all the
      // below if not.
      if (DEREF(message_data(msg), oneof_case_offset, uint32_t) !=
          upb_fielddef_number(f)) {
        continue;
      }
      // Otherwise, fall through to the appropriate singular-field handler
      // below.
      containing_oneof = true;
    }

    if (is_map_field(f)) {
      zval* map = CACHED_PTR_TO_ZVAL_PTR(find_zval_property(msg, f));
      if (!ZVAL_IS_NULL(map)) {
        putmap(map, f, sink, depth, is_json TSRMLS_CC);
      }
    } else if (upb_fielddef_isseq(f)) {
      zval* array = CACHED_PTR_TO_ZVAL_PTR(find_zval_property(msg, f));
      if (!ZVAL_IS_NULL(array)) {
        putarray(array, f, sink, depth, is_json TSRMLS_CC);
      }
    } else if (upb_fielddef_isstring(f)) {
      zval* str = CACHED_PTR_TO_ZVAL_PTR(find_zval_property(msg, f));
      if (containing_oneof || (is_json && is_wrapper_msg(desc->msgdef)) ||
          Z_STRLEN_P(str) > 0) {
        putstr(str, f, sink, is_json && is_wrapper_msg(desc->msgdef));
      }
    } else if (upb_fielddef_issubmsg(f)) {
      zval* submsg = CACHED_PTR_TO_ZVAL_PTR(find_zval_property(msg, f));
      if (is_wrapper_msg(upb_fielddef_msgsubdef(f)) &&
          Z_TYPE_P(submsg) != IS_NULL && Z_TYPE_P(submsg) != IS_OBJECT) {
        putwrappervalue(submsg, f, sink, depth, is_json TSRMLS_CC);
      } else {
        putsubmsg(submsg, f, sink, depth, is_json TSRMLS_CC);
      }
    } else {
      upb_selector_t sel = getsel(f, upb_handlers_getprimitivehandlertype(f));

#define T(upbtypeconst, upbtype, ctype, default_value)     \
  case upbtypeconst: {                                     \
    ctype value = DEREF(message_data(msg), offset, ctype); \
    if (containing_oneof ||                                \
        (is_json && is_wrapper_msg(desc->msgdef)) ||       \
        value != default_value) {                          \
      upb_sink_put##upbtype(sink, sel, value);             \
    }                                                      \
  } break;

      switch (upb_fielddef_type(f)) {
        T(UPB_TYPE_FLOAT, float, float, 0.0)
        T(UPB_TYPE_DOUBLE, double, double, 0.0)
        T(UPB_TYPE_BOOL, bool, uint8_t, 0)
        case UPB_TYPE_ENUM:
        T(UPB_TYPE_INT32, int32, int32_t, 0)
        T(UPB_TYPE_UINT32, uint32, uint32_t, 0)
        T(UPB_TYPE_INT64, int64, int64_t, 0)
        T(UPB_TYPE_UINT64, uint64, uint64_t, 0)

        case UPB_TYPE_STRING:
        case UPB_TYPE_BYTES:
        case UPB_TYPE_MESSAGE:
          zend_error(E_ERROR, "Internal error.");
      }

#undef T
    }
  }

  stringsink* unknown = DEREF(message_data(msg), 0, stringsink*);
  if (unknown != NULL) {
    upb_sink_putunknown(sink, unknown->ptr, unknown->len);
  }

  if (open_msg) {
    upb_sink_endmsg(sink, &status);
  }
}

static void putstr(zval* str, const upb_fielddef *f,
                   upb_sink sink, bool force_default) {
  upb_sink subsink;

  if (ZVAL_IS_NULL(str)) return;

  PHP_PROTO_ASSERT(Z_TYPE_P(str) == IS_STRING);

  upb_sink_startstr(sink, getsel(f, UPB_HANDLER_STARTSTR), Z_STRLEN_P(str),
                    &subsink);

  // For oneof string field, we may get here with string length is zero.
  if (Z_STRLEN_P(str) > 0 || force_default) {
    // Ensure that the string has the correct encoding. We also check at
    // field-set time, but the user may have mutated the string object since
    // then.
    if (upb_fielddef_type(f) == UPB_TYPE_STRING &&
        !is_structurally_valid_utf8(Z_STRVAL_P(str), Z_STRLEN_P(str))) {
      zend_error(E_USER_ERROR, "Given string is not UTF8 encoded.");
      return;
    }
    upb_sink_putstring(subsink, getsel(f, UPB_HANDLER_STRING), Z_STRVAL_P(str),
                       Z_STRLEN_P(str), NULL);
  }

  upb_sink_endstr(sink, getsel(f, UPB_HANDLER_ENDSTR));
}

static void putrawstr(const char* str, int len, const upb_fielddef* f,
                      upb_sink sink, bool force_default) {
  upb_sink subsink;

  if (len == 0 && !force_default) return;

  // Ensure that the string has the correct encoding. We also check at field-set
  // time, but the user may have mutated the string object since then.
  if (upb_fielddef_type(f) == UPB_TYPE_STRING &&
      !is_structurally_valid_utf8(str, len)) {
    zend_error(E_USER_ERROR, "Given string is not UTF8 encoded.");
    return;
  }

  upb_sink_startstr(sink, getsel(f, UPB_HANDLER_STARTSTR), len, &subsink);
  upb_sink_putstring(subsink, getsel(f, UPB_HANDLER_STRING), str, len, NULL);
  upb_sink_endstr(sink, getsel(f, UPB_HANDLER_ENDSTR));
}

static void putsubmsg(zval* submsg_php, const upb_fielddef* f, upb_sink sink,
                      int depth, bool is_json TSRMLS_DC) {
  if (Z_TYPE_P(submsg_php) == IS_NULL) return;

  MessageHeader *submsg = UNBOX(MessageHeader, submsg_php);
  putrawsubmsg(submsg, f, sink, depth, is_json TSRMLS_CC);
}

static void putwrappervalue(
    zval* value, const upb_fielddef* f,
    upb_sink sink, int depth, bool is_json TSRMLS_DC) {
  upb_sink subsink;
  const upb_msgdef* msgdef = upb_fielddef_msgsubdef(f);
  const upb_fielddef* value_field = upb_msgdef_itof(msgdef, 1);
  upb_selector_t sel =
      getsel(value_field, upb_handlers_getprimitivehandlertype(value_field));

  upb_sink_startsubmsg(sink, getsel(f, UPB_HANDLER_STARTSUBMSG), &subsink);

#define T(upbtypeconst, upbtype, ctype, default_value)      \
  case upbtypeconst: {                                      \
    ctype value_raw;                                        \
    native_slot_set(upb_fielddef_type(value_field), NULL,   \
                    &value_raw, value PHP_PROTO_TSRMLS_CC); \
    if ((is_json && is_wrapper_msg(msgdef)) ||              \
        value_raw != default_value) {                       \
      upb_sink_put##upbtype(subsink, sel, value_raw);       \
    }                                                       \
  } break;

  switch (upb_fielddef_type(value_field)) {
    T(UPB_TYPE_FLOAT, float, float, 0.0)
    T(UPB_TYPE_DOUBLE, double, double, 0.0)
    T(UPB_TYPE_BOOL, bool, uint8_t, 0)
    T(UPB_TYPE_INT32, int32, int32_t, 0)
    T(UPB_TYPE_UINT32, uint32, uint32_t, 0)
    T(UPB_TYPE_INT64, int64, int64_t, 0)
    T(UPB_TYPE_UINT64, uint64, uint64_t, 0)
    case UPB_TYPE_STRING:
    case UPB_TYPE_BYTES: {
      if ((is_json && is_wrapper_msg(msgdef)) ||
          Z_STRLEN_P(value) > 0) {
        putstr(value, value_field, subsink, is_json && is_wrapper_msg(msgdef));
      }
      break;
    }
    case UPB_TYPE_ENUM:
    case UPB_TYPE_MESSAGE:
      zend_error(E_ERROR, "Internal error.");
  }

#undef T

  upb_sink_endsubmsg(sink, subsink, getsel(f, UPB_HANDLER_ENDSUBMSG));
}

static void putrawsubmsg(MessageHeader* submsg, const upb_fielddef* f,
                         upb_sink sink, int depth, bool is_json TSRMLS_DC) {
  upb_sink subsink;

  const upb_msgdef* m = upb_fielddef_msgsubdef(f);
  DescriptorInternal* subdesc = get_msgdef_desc(m);

  upb_sink_startsubmsg(sink, getsel(f, UPB_HANDLER_STARTSUBMSG), &subsink);
  putrawmsg(submsg, subdesc, subsink, depth + 1, is_json, true TSRMLS_CC);
  upb_sink_endsubmsg(sink, subsink, getsel(f, UPB_HANDLER_ENDSUBMSG));
}

static void putarray(zval* array, const upb_fielddef* f, upb_sink sink,
                     int depth, bool is_json TSRMLS_DC) {
  upb_sink subsink;
  upb_fieldtype_t type = upb_fielddef_type(f);
  upb_selector_t sel = 0;
  int size, i;

  PHP_PROTO_ASSERT(array != NULL);
  RepeatedField* intern = UNBOX(RepeatedField, array);
  HashTable *ht = PHP_PROTO_HASH_OF(intern->array);
  size = zend_hash_num_elements(ht);
  if (size == 0) return;

  upb_sink_startseq(sink, getsel(f, UPB_HANDLER_STARTSEQ), &subsink);

  if (upb_fielddef_isprimitive(f)) {
    sel = getsel(f, upb_handlers_getprimitivehandlertype(f));
  }

  for (i = 0; i < size; i++) {
    void* memory = repeated_field_index_native(intern, i TSRMLS_CC);
    switch (type) {
#define T(upbtypeconst, upbtype, ctype)                      \
  case upbtypeconst:                                         \
    upb_sink_put##upbtype(subsink, sel, *((ctype*)memory)); \
    break;

      T(UPB_TYPE_FLOAT, float, float)
      T(UPB_TYPE_DOUBLE, double, double)
      T(UPB_TYPE_BOOL, bool, int8_t)
      case UPB_TYPE_ENUM:
        T(UPB_TYPE_INT32, int32, int32_t)
        T(UPB_TYPE_UINT32, uint32, uint32_t)
        T(UPB_TYPE_INT64, int64, int64_t)
        T(UPB_TYPE_UINT64, uint64, uint64_t)

      case UPB_TYPE_STRING:
      case UPB_TYPE_BYTES: {
#if PHP_MAJOR_VERSION < 7
        const char* rawstr = Z_STRVAL_P(*(zval**)memory);
        int len = Z_STRLEN_P(*(zval**)memory);
#else
        const char* rawstr = ZSTR_VAL(*(zend_string**)memory);
        int len = ZSTR_LEN(*(zend_string**)memory);
#endif
        putrawstr(rawstr, len, f, subsink,
                  is_json && is_wrapper_msg(upb_fielddef_containingtype(f)));
        break;
      }
      case UPB_TYPE_MESSAGE: {
#if PHP_MAJOR_VERSION < 7
        MessageHeader *submsg = UNBOX(MessageHeader, *(zval**)memory);
#else
        MessageHeader *submsg =
            (MessageHeader*)((char*)(Z_OBJ_P((zval*)memory)) -
                XtOffsetOf(MessageHeader, std));
#endif
        putrawsubmsg(submsg, f, subsink, depth, is_json TSRMLS_CC);
        break;
      }

#undef T
    }
  }
  upb_sink_endseq(sink, getsel(f, UPB_HANDLER_ENDSEQ));
}

static const upb_handlers* msgdef_pb_serialize_handlers(DescriptorInternal* desc) {
  return upb_handlercache_get(desc->pool->pb_serialize_handler_cache,
                              desc->msgdef);
}

static const upb_handlers* msgdef_json_serialize_handlers(
    DescriptorInternal* desc, bool preserve_proto_fieldnames) {
  if (preserve_proto_fieldnames) {
    return upb_handlercache_get(
        desc->pool->json_serialize_handler_preserve_cache, desc->msgdef);
  } else {
    return upb_handlercache_get(desc->pool->json_serialize_handler_cache,
                                desc->msgdef);
  }
}

// -----------------------------------------------------------------------------
// PHP encode/decode methods
// -----------------------------------------------------------------------------

void serialize_to_string(zval* val, zval* return_value TSRMLS_DC) {
  DescriptorInternal* desc = get_ce_desc(Z_OBJCE_P(val));

  stringsink sink;
  stringsink_init(&sink);

  {
    const upb_handlers* serialize_handlers = msgdef_pb_serialize_handlers(desc);

    stackenv se;
    upb_pb_encoder* encoder;

    stackenv_init(&se, "Error occurred during encoding: %s");
    encoder = upb_pb_encoder_create(se.arena, serialize_handlers, sink.sink);

    putmsg(val, desc, upb_pb_encoder_input(encoder), 0, false TSRMLS_CC);

    PHP_PROTO_RETVAL_STRINGL(sink.ptr, sink.len, 1);

    stackenv_uninit(&se);
    stringsink_uninit(&sink);
  }
}

PHP_METHOD(Message, serializeToString) {
  serialize_to_string(getThis(), return_value TSRMLS_CC);
}

void merge_from_string(const char* data, int data_len, DescriptorInternal* desc,
                       MessageHeader* msg) {
  const upb_pbdecodermethod* method = msgdef_decodermethod(desc);
  const upb_handlers* h = upb_pbdecodermethod_desthandlers(method);
  stackenv se;
  upb_sink sink;
  upb_pbdecoder* decoder;
  void* closure;
  stackenv_init(&se, "Error occurred during parsing: %s");

  if (is_wrapper_msg(desc->msgdef)) {
    wrapperfields_parseframe_t* frame =
        (wrapperfields_parseframe_t*)malloc(
            sizeof(wrapperfields_parseframe_t));
    frame->submsg = msg;
    frame->is_msg = true;
    closure = frame;
  } else {
    closure = msg;
  }

  upb_sink_reset(&sink, h, closure);
  decoder = upb_pbdecoder_create(se.arena, method, sink, &se.status);
  upb_bufsrc_putbuf(data, data_len, upb_pbdecoder_input(decoder));

  if (is_wrapper_msg(desc->msgdef)) {
    free((wrapperfields_parseframe_t*)closure);
  }

  stackenv_uninit(&se);
}

PHP_METHOD(Message, mergeFromString) {
  DescriptorInternal* desc = get_ce_desc(Z_OBJCE_P(getThis()));
  MessageHeader* msg = UNBOX(MessageHeader, getThis());

  char *data = NULL;
  PHP_PROTO_SIZE data_len;

  if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &data, &data_len) ==
      FAILURE) {
    return;
  }

  merge_from_string(data, data_len, desc, msg);
}

PHP_METHOD(Message, serializeToJsonString) {
  DescriptorInternal* desc = get_ce_desc(Z_OBJCE_P(getThis()));

  zend_bool preserve_proto_fieldnames = false;
  if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|b",
                            &preserve_proto_fieldnames) == FAILURE) {
    return;
  }

  stringsink sink;
  stringsink_init(&sink);

  {
    const upb_handlers* serialize_handlers =
        msgdef_json_serialize_handlers(desc, preserve_proto_fieldnames);
    upb_json_printer* printer;
    stackenv se;

    stackenv_init(&se, "Error occurred during encoding: %s");
    printer = upb_json_printer_create(se.arena, serialize_handlers, sink.sink);

    putmsg(getThis(), desc, upb_json_printer_input(printer), 0, true TSRMLS_CC);

    PHP_PROTO_RETVAL_STRINGL(sink.ptr, sink.len, 1);

    stackenv_uninit(&se);
    stringsink_uninit(&sink);
  }
}

PHP_METHOD(Message, mergeFromJsonString) {
  DescriptorInternal* desc = get_ce_desc(Z_OBJCE_P(getThis()));
  MessageHeader* msg = UNBOX(MessageHeader, getThis());

  char *data = NULL;
  PHP_PROTO_SIZE data_len;
  zend_bool ignore_json_unknown = false;

  if (zend_parse_parameters(
          ZEND_NUM_ARGS() TSRMLS_CC, "s|b", &data, &data_len,
          &ignore_json_unknown) ==
      FAILURE) {
    return;
  }

  // TODO(teboring): Check and respect string encoding. If not UTF-8, we need to
  // convert, because string handlers pass data directly to message string
  // fields.

  // TODO(teboring): Clear message.

  {
    const upb_json_parsermethod* method = msgdef_jsonparsermethod(desc);
    stackenv se;
    upb_sink sink;
    upb_json_parser* parser;
    void* closure;
    stackenv_init(&se, "Error occurred during parsing: %s");

    if (is_wrapper_msg(desc->msgdef)) {
      wrapperfields_parseframe_t* frame =
          (wrapperfields_parseframe_t*)malloc(
              sizeof(wrapperfields_parseframe_t));
      frame->submsg = msg;
      frame->is_msg = true;
      closure = frame;
    } else {
      closure = msg;
    }

    upb_sink_reset(&sink, get_fill_handlers(desc), closure);
    parser = upb_json_parser_create(se.arena, method, generated_pool->symtab,
                                    sink, &se.status, ignore_json_unknown);
    upb_bufsrc_putbuf(data, data_len, upb_json_parser_input(parser));

    if (is_wrapper_msg(desc->msgdef)) {
      free((wrapperfields_parseframe_t*)closure);
    }
    stackenv_uninit(&se);
  }
}

// TODO(teboring): refactoring with putrawmsg
static void discard_unknown_fields(MessageHeader* msg) {
  upb_msg_field_iter it;

  stringsink* unknown = DEREF(message_data(msg), 0, stringsink*);
  if (unknown != NULL) {
    stringsink_uninit(unknown);
    FREE(unknown);
    DEREF(message_data(msg), 0, stringsink*) = NULL;
  }

  // Recursively discard unknown fields of submessages.
  DescriptorInternal* desc = msg->descriptor;
  TSRMLS_FETCH();
  for (upb_msg_field_begin(&it, desc->msgdef);
       !upb_msg_field_done(&it);
       upb_msg_field_next(&it)) {
    upb_fielddef* f = upb_msg_iter_field(&it);

    if (upb_fielddef_containingoneof(f)) {
      uint32_t oneof_case_offset =
          desc->layout->fields[upb_fielddef_index(f)].case_offset;
      // For a oneof, check that this field is actually present -- skip all the
      // below if not.
      if (DEREF(message_data(msg), oneof_case_offset, uint32_t) !=
          upb_fielddef_number(f)) {
        continue;
      }
      // Otherwise, fall through to the appropriate singular-field handler
      // below.
    }

    if (is_map_field(f)) {
      MapIter map_it;
      int len;
      const upb_fielddef* value_field;

      value_field = map_field_value(f);
      if (!upb_fielddef_issubmsg(value_field)) continue;

      zval* map_php = CACHED_PTR_TO_ZVAL_PTR(find_zval_property(msg, f));
      if (ZVAL_IS_NULL(map_php)) continue;

      for (map_begin(map_php, &map_it TSRMLS_CC);
           !map_done(&map_it); map_next(&map_it)) {
        upb_value value = map_iter_value(&map_it, &len);
        const void* memory = raw_value(upb_value_memory(&value), value_field);
#if PHP_MAJOR_VERSION < 7
        MessageHeader *submsg = UNBOX(MessageHeader, *(zval**)memory);
#else
        MessageHeader *submsg =
            (MessageHeader*)((char*)(Z_OBJ_P((zval*)memory)) -
                XtOffsetOf(MessageHeader, std));
#endif
        discard_unknown_fields(submsg);
      }
    } else if (upb_fielddef_isseq(f)) {
      if (!upb_fielddef_issubmsg(f)) continue;

      zval* array_php = CACHED_PTR_TO_ZVAL_PTR(find_zval_property(msg, f));
      if (ZVAL_IS_NULL(array_php)) continue;

      int size, i;
      RepeatedField* intern = UNBOX(RepeatedField, array_php);
      HashTable *ht = PHP_PROTO_HASH_OF(intern->array);
      size = zend_hash_num_elements(ht);
      if (size == 0) continue;

      for (i = 0; i < size; i++) {
        void* memory = repeated_field_index_native(intern, i TSRMLS_CC);
#if PHP_MAJOR_VERSION < 7
        MessageHeader *submsg = UNBOX(MessageHeader, *(zval**)memory);
#else
        MessageHeader *submsg =
            (MessageHeader*)((char*)(Z_OBJ_P((zval*)memory)) -
                XtOffsetOf(MessageHeader, std));
#endif
        discard_unknown_fields(submsg);
      }
    } else if (upb_fielddef_issubmsg(f)) {
      zval* submsg_php = CACHED_PTR_TO_ZVAL_PTR(find_zval_property(msg, f));
      if (Z_TYPE_P(submsg_php) == IS_NULL) continue;
      MessageHeader* submsg = UNBOX(MessageHeader, submsg_php);
      discard_unknown_fields(submsg);
    }
  }
}

PHP_METHOD(Message, discardUnknownFields) {
  MessageHeader* msg = UNBOX(MessageHeader, getThis());
  discard_unknown_fields(msg);
}
