aboutsummaryrefslogtreecommitdiffhomepage
path: root/php/ext
diff options
context:
space:
mode:
Diffstat (limited to 'php/ext')
-rw-r--r--php/ext/google/protobuf/def.c57
-rw-r--r--php/ext/google/protobuf/encode_decode.c85
-rw-r--r--php/ext/google/protobuf/message.c1747
-rw-r--r--php/ext/google/protobuf/protobuf.c70
-rw-r--r--php/ext/google/protobuf/protobuf.h527
-rw-r--r--php/ext/google/protobuf/storage.c54
-rw-r--r--php/ext/google/protobuf/type_check.c37
-rw-r--r--php/ext/google/protobuf/upb.c2004
-rw-r--r--php/ext/google/protobuf/upb.h815
9 files changed, 4446 insertions, 950 deletions
diff --git a/php/ext/google/protobuf/def.c b/php/ext/google/protobuf/def.c
index d07c664c..13f7cdd6 100644
--- a/php/ext/google/protobuf/def.c
+++ b/php/ext/google/protobuf/def.c
@@ -112,33 +112,6 @@ static void append_map_entry_name(char *result, const char *field_name,
check_upb_status(&status, msg); \
} while (0)
-// Define PHP class
-#define DEFINE_PROTOBUF_INIT_CLASS(CLASSNAME, CAMELNAME, LOWERNAME) \
- PHP_PROTO_INIT_CLASS_START(CLASSNAME, CAMELNAME, LOWERNAME) \
- PHP_PROTO_INIT_CLASS_END
-
-#define DEFINE_PROTOBUF_CREATE(NAME, LOWERNAME) \
- PHP_PROTO_OBJECT_CREATE_START(NAME, LOWERNAME) \
- LOWERNAME##_init_c_instance(intern TSRMLS_CC); \
- PHP_PROTO_OBJECT_CREATE_END(NAME, LOWERNAME)
-
-#define DEFINE_PROTOBUF_FREE(CAMELNAME, LOWERNAME) \
- PHP_PROTO_OBJECT_FREE_START(CAMELNAME, LOWERNAME) \
- LOWERNAME##_free_c(intern TSRMLS_CC); \
- PHP_PROTO_OBJECT_FREE_END
-
-#define DEFINE_PROTOBUF_DTOR(CAMELNAME, LOWERNAME) \
- PHP_PROTO_OBJECT_DTOR_START(CAMELNAME, LOWERNAME) \
- PHP_PROTO_OBJECT_DTOR_END
-
-#define DEFINE_CLASS(NAME, LOWERNAME, string_name) \
- zend_class_entry *LOWERNAME##_type; \
- zend_object_handlers *LOWERNAME##_handlers; \
- DEFINE_PROTOBUF_FREE(NAME, LOWERNAME) \
- DEFINE_PROTOBUF_DTOR(NAME, LOWERNAME) \
- DEFINE_PROTOBUF_CREATE(NAME, LOWERNAME) \
- DEFINE_PROTOBUF_INIT_CLASS(string_name, NAME, LOWERNAME)
-
// -----------------------------------------------------------------------------
// GPBType
// -----------------------------------------------------------------------------
@@ -654,7 +627,7 @@ zend_object *internal_generated_pool_php;
#endif
InternalDescriptorPool *generated_pool; // The actual generated pool
-static void init_generated_pool_once(TSRMLS_D) {
+void init_generated_pool_once(TSRMLS_D) {
if (generated_pool == NULL) {
#if PHP_MAJOR_VERSION < 7
MAKE_STD_ZVAL(generated_pool_php);
@@ -844,18 +817,11 @@ static void convert_to_class_name_inplace(const char *package,
memcpy(classname + i, prefix, prefix_len);
}
-PHP_METHOD(InternalDescriptorPool, internalAddGeneratedFile) {
- char *data = NULL;
- PHP_PROTO_SIZE data_len;
+void internal_add_generated_file(const char *data, PHP_PROTO_SIZE data_len,
+ InternalDescriptorPool *pool TSRMLS_DC) {
upb_filedef **files;
size_t i;
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &data, &data_len) ==
- FAILURE) {
- return;
- }
-
- InternalDescriptorPool *pool = UNBOX(InternalDescriptorPool, getThis());
CHECK_UPB(files = upb_loaddescriptor(data, data_len, &pool, &status),
"Parse binary descriptors to internal descriptors failed");
@@ -914,6 +880,8 @@ PHP_METHOD(InternalDescriptorPool, internalAddGeneratedFile) {
desc->klass = PHP_PROTO_CE_UNREF(pce); \
} \
add_ce_obj(desc->klass, desc_php); \
+ add_proto_obj(upb_##def_type_lower##_fullname(desc->def_type_lower), \
+ desc_php); \
efree(classname); \
break; \
}
@@ -940,6 +908,21 @@ PHP_METHOD(InternalDescriptorPool, internalAddGeneratedFile) {
upb_gfree(files);
}
+PHP_METHOD(InternalDescriptorPool, internalAddGeneratedFile) {
+ char *data = NULL;
+ PHP_PROTO_SIZE data_len;
+ upb_filedef **files;
+ size_t i;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &data, &data_len) ==
+ FAILURE) {
+ return;
+ }
+
+ InternalDescriptorPool *pool = UNBOX(InternalDescriptorPool, getThis());
+ internal_add_generated_file(data, data_len, pool TSRMLS_CC);
+}
+
PHP_METHOD(DescriptorPool, getDescriptorByClassName) {
DescriptorPool *public_pool = UNBOX(DescriptorPool, getThis());
InternalDescriptorPool *pool = public_pool->intern;
diff --git a/php/ext/google/protobuf/encode_decode.c b/php/ext/google/protobuf/encode_decode.c
index 89e75d6a..7e2b3ae6 100644
--- a/php/ext/google/protobuf/encode_decode.c
+++ b/php/ext/google/protobuf/encode_decode.c
@@ -142,6 +142,23 @@ static const void* newhandlerdata(upb_handlers* h, uint32_t ofs) {
return hd_ofs;
}
+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));
+ hd->handler = stringsink_string;
+ upb_handlers_addcleanup(h, hd, free);
+ return hd;
+}
+
typedef struct {
size_t ofs;
const upb_msgdef *md;
@@ -944,6 +961,24 @@ static void add_handlers_for_oneof_field(upb_handlers *h,
upb_handlerattr_uninit(&attr);
}
+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;
+}
+
static void add_handlers_for_message(const void* closure,
upb_handlers* h) {
const upb_msgdef* msgdef = upb_handlers_msgdef(h);
@@ -967,6 +1002,10 @@ static void add_handlers_for_message(const void* closure,
desc->layout = create_layout(desc->msgdef);
}
+ upb_handlerattr attr = UPB_HANDLERATTR_INITIALIZER;
+ upb_handlerattr_sethandlerdata(&attr, 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)) {
@@ -1278,6 +1317,11 @@ static void putrawmsg(MessageHeader* msg, const Descriptor* desc,
}
}
+ stringsink* unknown = DEREF(message_data(msg), 0, stringsink*);
+ if (unknown != NULL) {
+ upb_sink_putunknown(sink, unknown->ptr, unknown->len);
+ }
+
upb_sink_endmsg(sink, &status);
}
@@ -1445,9 +1489,9 @@ static const upb_handlers* msgdef_json_serialize_handlers(
// PHP encode/decode methods
// -----------------------------------------------------------------------------
-PHP_METHOD(Message, serializeToString) {
+void serialize_to_string(zval* val, zval* return_value TSRMLS_DC) {
Descriptor* desc =
- UNBOX_HASHTABLE_VALUE(Descriptor, get_ce_obj(Z_OBJCE_P(getThis())));
+ UNBOX_HASHTABLE_VALUE(Descriptor, get_ce_obj(Z_OBJCE_P(val)));
stringsink sink;
stringsink_init(&sink);
@@ -1461,7 +1505,7 @@ PHP_METHOD(Message, serializeToString) {
stackenv_init(&se, "Error occurred during encoding: %s");
encoder = upb_pb_encoder_create(&se.env, serialize_handlers, &sink.sink);
- putmsg(getThis(), desc, upb_pb_encoder_input(encoder), 0 TSRMLS_CC);
+ putmsg(val, desc, upb_pb_encoder_input(encoder), 0 TSRMLS_CC);
PHP_PROTO_RETVAL_STRINGL(sink.ptr, sink.len, 1);
@@ -1470,6 +1514,26 @@ PHP_METHOD(Message, serializeToString) {
}
}
+PHP_METHOD(Message, serializeToString) {
+ serialize_to_string(getThis(), return_value TSRMLS_CC);
+}
+
+void merge_from_string(const char* data, int data_len, const Descriptor* 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;
+ stackenv_init(&se, "Error occurred during parsing: %s");
+
+ upb_sink_reset(&sink, h, msg);
+ decoder = upb_pbdecoder_create(&se.env, method, &sink);
+ upb_bufsrc_putbuf(data, data_len, upb_pbdecoder_input(decoder));
+
+ stackenv_uninit(&se);
+}
+
PHP_METHOD(Message, mergeFromString) {
Descriptor* desc =
UNBOX_HASHTABLE_VALUE(Descriptor, get_ce_obj(Z_OBJCE_P(getThis())));
@@ -1483,20 +1547,7 @@ PHP_METHOD(Message, mergeFromString) {
return;
}
- {
- const upb_pbdecodermethod* method = msgdef_decodermethod(desc);
- const upb_handlers* h = upb_pbdecodermethod_desthandlers(method);
- stackenv se;
- upb_sink sink;
- upb_pbdecoder* decoder;
- stackenv_init(&se, "Error occurred during parsing: %s");
-
- upb_sink_reset(&sink, h, msg);
- decoder = upb_pbdecoder_create(&se.env, method, &sink);
- upb_bufsrc_putbuf(data, data_len, upb_pbdecoder_input(decoder));
-
- stackenv_uninit(&se);
- }
+ merge_from_string(data, data_len, desc, msg);
}
PHP_METHOD(Message, serializeToJsonString) {
diff --git a/php/ext/google/protobuf/message.c b/php/ext/google/protobuf/message.c
index 519786dd..291f5c24 100644
--- a/php/ext/google/protobuf/message.c
+++ b/php/ext/google/protobuf/message.c
@@ -29,12 +29,16 @@
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <php.h>
+#include <ext/date/php_date.h>
#include <stdlib.h>
#include "protobuf.h"
+#include "utf8.h"
-static zend_class_entry* message_type;
+zend_class_entry* message_type;
zend_object_handlers* message_handlers;
+static const char TYPE_URL_PREFIX[] = "type.googleapis.com/";
+static void hex_to_binary(const char* hex, char** binary, int* binary_len);
static zend_function_entry message_methods[] = {
PHP_ME(Message, clear, NULL, ZEND_ACC_PUBLIC)
@@ -77,6 +81,10 @@ static HashTable* message_get_properties(zval* object TSRMLS_DC);
// Define object free method.
PHP_PROTO_OBJECT_FREE_START(MessageHeader, message)
+ if (*(void**)intern->data != NULL) {
+ stringsink_uninit(*(void**)intern->data);
+ FREE(*(void**)intern->data);
+ }
FREE(intern->data);
PHP_PROTO_OBJECT_FREE_END
@@ -103,6 +111,20 @@ PHP_PROTO_INIT_CLASS_START("Google\\Protobuf\\Internal\\Message",
message_handlers->get_gc = message_get_gc;
PHP_PROTO_INIT_CLASS_END
+static void message_set_property_internal(zval* object, zval* member,
+ zval* value TSRMLS_DC) {
+ const upb_fielddef* field;
+
+ MessageHeader* self = UNBOX(MessageHeader, object);
+
+ field = upb_msgdef_ntofz(self->descriptor->msgdef, Z_STRVAL_P(member));
+ if (field == NULL) {
+ zend_error(E_USER_ERROR, "Unknown field: %s", Z_STRVAL_P(member));
+ }
+
+ layout_set(self->descriptor->layout, self, field, value TSRMLS_CC);
+}
+
#if PHP_MAJOR_VERSION < 7
static void message_set_property(zval* object, zval* member, zval* value,
php_proto_zend_literal key TSRMLS_DC) {
@@ -125,16 +147,42 @@ static void message_set_property(zval* object, zval* member, zval* value,
return;
}
- const upb_fielddef* field;
+ message_set_property_internal(object, member, value TSRMLS_CC);
+}
+static zval* message_get_property_internal(zval* object,
+ zval* member TSRMLS_DC) {
MessageHeader* self = UNBOX(MessageHeader, object);
+ const upb_fielddef* field;
+ field = upb_msgdef_ntofz(self->descriptor->msgdef, Z_STRVAL_P(member));
+ if (field == NULL) {
+ return PHP_PROTO_GLOBAL_UNINITIALIZED_ZVAL;
+ }
+
+ zend_property_info* property_info;
+#if PHP_MAJOR_VERSION < 7
+ property_info =
+ zend_get_property_info(Z_OBJCE_P(object), member, true TSRMLS_CC);
+#else
+ property_info =
+ zend_get_property_info(Z_OBJCE_P(object), Z_STR_P(member), true);
+#endif
+ return layout_get(
+ self->descriptor->layout, message_data(self), field,
+ OBJ_PROP(Z_OBJ_P(object), property_info->offset) TSRMLS_CC);
+}
+static void message_get_oneof_property_internal(zval* object, zval* member,
+ zval* return_value TSRMLS_DC) {
+ MessageHeader* self = UNBOX(MessageHeader, object);
+ const upb_fielddef* field;
field = upb_msgdef_ntofz(self->descriptor->msgdef, Z_STRVAL_P(member));
if (field == NULL) {
- zend_error(E_USER_ERROR, "Unknown field: %s", Z_STRVAL_P(member));
+ return;
}
- layout_set(self->descriptor->layout, self, field, value TSRMLS_CC);
+ layout_get(self->descriptor->layout, message_data(self), field,
+ ZVAL_PTR_TO_CACHED_PTR(return_value) TSRMLS_CC);
}
#if PHP_MAJOR_VERSION < 7
@@ -159,27 +207,7 @@ static zval* message_get_property(zval* object, zval* member, int type,
return PHP_PROTO_GLOBAL_UNINITIALIZED_ZVAL;
}
- MessageHeader* self = UNBOX(MessageHeader, object);
- const upb_fielddef* field;
- field = upb_msgdef_ntofz(self->descriptor->msgdef, Z_STRVAL_P(member));
- if (field == NULL) {
- return PHP_PROTO_GLOBAL_UNINITIALIZED_ZVAL;
- }
-
- zend_property_info* property_info;
-#if PHP_MAJOR_VERSION < 7
- property_info =
- zend_get_property_info(Z_OBJCE_P(object), member, true TSRMLS_CC);
- return layout_get(
- self->descriptor->layout, message_data(self), field,
- OBJ_PROP(Z_OBJ_P(object), property_info->offset) TSRMLS_CC);
-#else
- property_info =
- zend_get_property_info(Z_OBJCE_P(object), Z_STR_P(member), true);
- return layout_get(
- self->descriptor->layout, message_data(self), field,
- OBJ_PROP(Z_OBJ_P(object), property_info->offset) TSRMLS_CC);
-#endif
+ return message_get_property_internal(object, member TSRMLS_CC);
}
#if PHP_MAJOR_VERSION < 7
@@ -298,11 +326,6 @@ PHP_METHOD(Message, readOneof) {
const upb_fielddef* field = upb_msgdef_itof(msg->descriptor->msgdef, index);
- int property_cache_index =
- msg->descriptor->layout->fields[upb_fielddef_index(field)].cache_index;
- zval* property_ptr = CACHED_PTR_TO_ZVAL_PTR(
- OBJ_PROP(Z_OBJ_P(getThis()), property_cache_index));
-
// Unlike singular fields, oneof fields share cached property. So we cannot
// let lay_get modify the cached property. Instead, we pass in the return
// value directly.
@@ -342,3 +365,1667 @@ PHP_METHOD(Message, whichOneof) {
msg->descriptor->layout, message_data(msg), oneof TSRMLS_CC);
PHP_PROTO_RETURN_STRING(oneof_case_name, 1);
}
+
+// -----------------------------------------------------------------------------
+// Well Known Types Support
+// -----------------------------------------------------------------------------
+
+#define PHP_PROTO_FIELD_ACCESSORS(UPPER_CLASS, LOWER_CLASS, UPPER_FIELD, \
+ LOWER_FIELD) \
+ PHP_METHOD(UPPER_CLASS, get##UPPER_FIELD) { \
+ zval member; \
+ PHP_PROTO_ZVAL_STRING(&member, LOWER_FIELD, 1); \
+ PHP_PROTO_FAKE_SCOPE_BEGIN(LOWER_CLASS##_type); \
+ zval* value = message_get_property_internal(getThis(), &member TSRMLS_CC); \
+ PHP_PROTO_FAKE_SCOPE_END; \
+ PHP_PROTO_RETVAL_ZVAL(value); \
+ } \
+ PHP_METHOD(UPPER_CLASS, set##UPPER_FIELD) { \
+ zval* value = NULL; \
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &value) == \
+ FAILURE) { \
+ return; \
+ } \
+ zval member; \
+ PHP_PROTO_ZVAL_STRING(&member, LOWER_FIELD, 1); \
+ message_set_property_internal(getThis(), &member, value TSRMLS_CC); \
+ PHP_PROTO_RETVAL_ZVAL(getThis()); \
+ }
+
+#define PHP_PROTO_ONEOF_FIELD_ACCESSORS(UPPER_CLASS, LOWER_CLASS, UPPER_FIELD, \
+ LOWER_FIELD) \
+ PHP_METHOD(UPPER_CLASS, get##UPPER_FIELD) { \
+ zval member; \
+ PHP_PROTO_ZVAL_STRING(&member, LOWER_FIELD, 1); \
+ PHP_PROTO_FAKE_SCOPE_BEGIN(LOWER_CLASS##_type); \
+ message_get_oneof_property_internal(getThis(), &member, \
+ return_value TSRMLS_CC); \
+ PHP_PROTO_FAKE_SCOPE_END; \
+ } \
+ PHP_METHOD(UPPER_CLASS, set##UPPER_FIELD) { \
+ zval* value = NULL; \
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &value) == \
+ FAILURE) { \
+ return; \
+ } \
+ zval member; \
+ PHP_PROTO_ZVAL_STRING(&member, LOWER_FIELD, 1); \
+ message_set_property_internal(getThis(), &member, value TSRMLS_CC); \
+ PHP_PROTO_RETVAL_ZVAL(getThis()); \
+ }
+
+#define PHP_PROTO_ONEOF_ACCESSORS(UPPER_CLASS, LOWER_CLASS, UPPER_FIELD, \
+ LOWER_FIELD) \
+ PHP_METHOD(UPPER_CLASS, get##UPPER_FIELD) { \
+ MessageHeader* msg = UNBOX(MessageHeader, getThis()); \
+ PHP_PROTO_FAKE_SCOPE_BEGIN(LOWER_CLASS##_type); \
+ const upb_oneofdef* oneof = upb_msgdef_ntoo( \
+ msg->descriptor->msgdef, LOWER_FIELD, strlen(LOWER_FIELD)); \
+ const char* oneof_case_name = layout_get_oneof_case( \
+ msg->descriptor->layout, message_data(msg), oneof TSRMLS_CC); \
+ PHP_PROTO_FAKE_SCOPE_END; \
+ PHP_PROTO_RETURN_STRING(oneof_case_name, 1); \
+ }
+
+// Forward declare file init functions
+static void init_file_any(TSRMLS_D);
+static void init_file_api(TSRMLS_D);
+static void init_file_duration(TSRMLS_D);
+static void init_file_field_mask(TSRMLS_D);
+static void init_file_empty(TSRMLS_D);
+static void init_file_source_context(TSRMLS_D);
+static void init_file_struct(TSRMLS_D);
+static void init_file_timestamp(TSRMLS_D);
+static void init_file_type(TSRMLS_D);
+static void init_file_wrappers(TSRMLS_D);
+
+// Define file init functions
+static void init_file_any(TSRMLS_D) {
+ static bool is_initialized = false;
+ if (is_initialized) return;
+ init_generated_pool_once(TSRMLS_C);
+ const char* generated_file =
+ "0acd010a19676f6f676c652f70726f746f6275662f616e792e70726f746f"
+ "120f676f6f676c652e70726f746f62756622260a03416e7912100a087479"
+ "70655f75726c180120012809120d0a0576616c756518022001280c426f0a"
+ "13636f6d2e676f6f676c652e70726f746f6275664208416e7950726f746f"
+ "50015a256769746875622e636f6d2f676f6c616e672f70726f746f627566"
+ "2f7074797065732f616e79a20203475042aa021e476f6f676c652e50726f"
+ "746f6275662e57656c6c4b6e6f776e5479706573620670726f746f33";
+ char* binary;
+ int binary_len;
+ hex_to_binary(generated_file, &binary, &binary_len);
+ internal_add_generated_file(binary, binary_len, generated_pool TSRMLS_CC);
+ FREE(binary);
+ is_initialized = true;
+}
+
+static void init_file_api(TSRMLS_D) {
+ static bool is_initialized = false;
+ if (is_initialized) return;
+ init_file_source_context(TSRMLS_C);
+ init_file_type(TSRMLS_C);
+ init_generated_pool_once(TSRMLS_C);
+ const char* generated_file =
+ "0aee050a19676f6f676c652f70726f746f6275662f6170692e70726f746f"
+ "120f676f6f676c652e70726f746f6275661a24676f6f676c652f70726f74"
+ "6f6275662f736f757263655f636f6e746578742e70726f746f1a1a676f6f"
+ "676c652f70726f746f6275662f747970652e70726f746f2281020a034170"
+ "69120c0a046e616d6518012001280912280a076d6574686f647318022003"
+ "280b32172e676f6f676c652e70726f746f6275662e4d6574686f6412280a"
+ "076f7074696f6e7318032003280b32172e676f6f676c652e70726f746f62"
+ "75662e4f7074696f6e120f0a0776657273696f6e18042001280912360a0e"
+ "736f757263655f636f6e7465787418052001280b321e2e676f6f676c652e"
+ "70726f746f6275662e536f75726365436f6e7465787412260a066d697869"
+ "6e7318062003280b32162e676f6f676c652e70726f746f6275662e4d6978"
+ "696e12270a0673796e74617818072001280e32172e676f6f676c652e7072"
+ "6f746f6275662e53796e74617822d5010a064d6574686f64120c0a046e61"
+ "6d6518012001280912180a10726571756573745f747970655f75726c1802"
+ "2001280912190a11726571756573745f73747265616d696e671803200128"
+ "0812190a11726573706f6e73655f747970655f75726c180420012809121a"
+ "0a12726573706f6e73655f73747265616d696e6718052001280812280a07"
+ "6f7074696f6e7318062003280b32172e676f6f676c652e70726f746f6275"
+ "662e4f7074696f6e12270a0673796e74617818072001280e32172e676f6f"
+ "676c652e70726f746f6275662e53796e74617822230a054d6978696e120c"
+ "0a046e616d65180120012809120c0a04726f6f7418022001280942750a13"
+ "636f6d2e676f6f676c652e70726f746f627566420841706950726f746f50"
+ "015a2b676f6f676c652e676f6c616e672e6f72672f67656e70726f746f2f"
+ "70726f746f6275662f6170693b617069a20203475042aa021e476f6f676c"
+ "652e50726f746f6275662e57656c6c4b6e6f776e5479706573620670726f"
+ "746f33";
+ char* binary;
+ int binary_len;
+ hex_to_binary(generated_file, &binary, &binary_len);
+ internal_add_generated_file(binary, binary_len, generated_pool TSRMLS_CC);
+ FREE(binary);
+ is_initialized = true;
+}
+
+static void init_file_duration(TSRMLS_D) {
+ static bool is_initialized = false;
+ if (is_initialized) return;
+ init_generated_pool_once(TSRMLS_C);
+ const char* generated_file =
+ "0ae3010a1e676f6f676c652f70726f746f6275662f6475726174696f6e2e"
+ "70726f746f120f676f6f676c652e70726f746f627566222a0a0844757261"
+ "74696f6e120f0a077365636f6e6473180120012803120d0a056e616e6f73"
+ "180220012805427c0a13636f6d2e676f6f676c652e70726f746f62756642"
+ "0d4475726174696f6e50726f746f50015a2a6769746875622e636f6d2f67"
+ "6f6c616e672f70726f746f6275662f7074797065732f6475726174696f6e"
+ "f80101a20203475042aa021e476f6f676c652e50726f746f6275662e5765"
+ "6c6c4b6e6f776e5479706573620670726f746f33";
+ char* binary;
+ int binary_len;
+ hex_to_binary(generated_file, &binary, &binary_len);
+ internal_add_generated_file(binary, binary_len, generated_pool TSRMLS_CC);
+ FREE(binary);
+ is_initialized = true;
+}
+
+static void init_file_field_mask(TSRMLS_D) {
+ static bool is_initialized = false;
+ if (is_initialized) return;
+ init_generated_pool_once(TSRMLS_C);
+ const char* generated_file =
+ "0ae3010a20676f6f676c652f70726f746f6275662f6669656c645f6d6173"
+ "6b2e70726f746f120f676f6f676c652e70726f746f627566221a0a094669"
+ "656c644d61736b120d0a0570617468731801200328094289010a13636f6d"
+ "2e676f6f676c652e70726f746f627566420e4669656c644d61736b50726f"
+ "746f50015a39676f6f676c652e676f6c616e672e6f72672f67656e70726f"
+ "746f2f70726f746f6275662f6669656c645f6d61736b3b6669656c645f6d"
+ "61736ba20203475042aa021e476f6f676c652e50726f746f6275662e5765"
+ "6c6c4b6e6f776e5479706573620670726f746f33";
+ char* binary;
+ int binary_len;
+ hex_to_binary(generated_file, &binary, &binary_len);
+ internal_add_generated_file(binary, binary_len, generated_pool TSRMLS_CC);
+ FREE(binary);
+ is_initialized = true;
+}
+
+static void init_file_empty(TSRMLS_D) {
+ static bool is_initialized = false;
+ if (is_initialized) return;
+ init_generated_pool_once(TSRMLS_C);
+ const char* generated_file =
+ "0ab7010a1b676f6f676c652f70726f746f6275662f656d7074792e70726f"
+ "746f120f676f6f676c652e70726f746f62756622070a05456d7074794276"
+ "0a13636f6d2e676f6f676c652e70726f746f627566420a456d7074795072"
+ "6f746f50015a276769746875622e636f6d2f676f6c616e672f70726f746f"
+ "6275662f7074797065732f656d707479f80101a20203475042aa021e476f"
+ "6f676c652e50726f746f6275662e57656c6c4b6e6f776e54797065736206"
+ "70726f746f33";
+ char* binary;
+ int binary_len;
+ hex_to_binary(generated_file, &binary, &binary_len);
+ internal_add_generated_file(binary, binary_len, generated_pool TSRMLS_CC);
+ FREE(binary);
+ is_initialized = true;
+}
+
+static void init_file_source_context(TSRMLS_D) {
+ static bool is_initialized = false;
+ if (is_initialized) return;
+ init_generated_pool_once(TSRMLS_C);
+ const char* generated_file =
+ "0afb010a24676f6f676c652f70726f746f6275662f736f757263655f636f"
+ "6e746578742e70726f746f120f676f6f676c652e70726f746f6275662222"
+ "0a0d536f75726365436f6e7465787412110a0966696c655f6e616d651801"
+ "200128094295010a13636f6d2e676f6f676c652e70726f746f6275664212"
+ "536f75726365436f6e7465787450726f746f50015a41676f6f676c652e67"
+ "6f6c616e672e6f72672f67656e70726f746f2f70726f746f6275662f736f"
+ "757263655f636f6e746578743b736f757263655f636f6e74657874a20203"
+ "475042aa021e476f6f676c652e50726f746f6275662e57656c6c4b6e6f77"
+ "6e5479706573620670726f746f33";
+ char* binary;
+ int binary_len;
+ hex_to_binary(generated_file, &binary, &binary_len);
+ internal_add_generated_file(binary, binary_len, generated_pool TSRMLS_CC);
+ FREE(binary);
+ is_initialized = true;
+}
+
+static void init_file_struct(TSRMLS_D) {
+ static bool is_initialized = false;
+ if (is_initialized) return;
+ init_generated_pool_once(TSRMLS_C);
+ const char* generated_file =
+ "0a81050a1c676f6f676c652f70726f746f6275662f7374727563742e7072"
+ "6f746f120f676f6f676c652e70726f746f6275662284010a065374727563"
+ "7412330a066669656c647318012003280b32232e676f6f676c652e70726f"
+ "746f6275662e5374727563742e4669656c6473456e7472791a450a0b4669"
+ "656c6473456e747279120b0a036b657918012001280912250a0576616c75"
+ "6518022001280b32162e676f6f676c652e70726f746f6275662e56616c75"
+ "653a02380122ea010a0556616c756512300a0a6e756c6c5f76616c756518"
+ "012001280e321a2e676f6f676c652e70726f746f6275662e4e756c6c5661"
+ "6c7565480012160a0c6e756d6265725f76616c7565180220012801480012"
+ "160a0c737472696e675f76616c7565180320012809480012140a0a626f6f"
+ "6c5f76616c75651804200128084800122f0a0c7374727563745f76616c75"
+ "6518052001280b32172e676f6f676c652e70726f746f6275662e53747275"
+ "6374480012300a0a6c6973745f76616c756518062001280b321a2e676f6f"
+ "676c652e70726f746f6275662e4c69737456616c7565480042060a046b69"
+ "6e6422330a094c69737456616c756512260a0676616c7565731801200328"
+ "0b32162e676f6f676c652e70726f746f6275662e56616c75652a1b0a094e"
+ "756c6c56616c7565120e0a0a4e554c4c5f56414c554510004281010a1363"
+ "6f6d2e676f6f676c652e70726f746f627566420b53747275637450726f74"
+ "6f50015a316769746875622e636f6d2f676f6c616e672f70726f746f6275"
+ "662f7074797065732f7374727563743b7374727563747062f80101a20203"
+ "475042aa021e476f6f676c652e50726f746f6275662e57656c6c4b6e6f77"
+ "6e5479706573620670726f746f33";
+ char* binary;
+ int binary_len;
+ hex_to_binary(generated_file, &binary, &binary_len);
+ internal_add_generated_file(binary, binary_len, generated_pool TSRMLS_CC);
+ FREE(binary);
+ is_initialized = true;
+}
+
+static void init_file_timestamp(TSRMLS_D) {
+ static bool is_initialized = false;
+ if (is_initialized) return;
+ init_generated_pool_once(TSRMLS_C);
+ const char* generated_file =
+ "0ae7010a1f676f6f676c652f70726f746f6275662f74696d657374616d70"
+ "2e70726f746f120f676f6f676c652e70726f746f627566222b0a0954696d"
+ "657374616d70120f0a077365636f6e6473180120012803120d0a056e616e"
+ "6f73180220012805427e0a13636f6d2e676f6f676c652e70726f746f6275"
+ "66420e54696d657374616d7050726f746f50015a2b6769746875622e636f"
+ "6d2f676f6c616e672f70726f746f6275662f7074797065732f74696d6573"
+ "74616d70f80101a20203475042aa021e476f6f676c652e50726f746f6275"
+ "662e57656c6c4b6e6f776e5479706573620670726f746f33";
+ char* binary;
+ int binary_len;
+ hex_to_binary(generated_file, &binary, &binary_len);
+ internal_add_generated_file(binary, binary_len, generated_pool TSRMLS_CC);
+ FREE(binary);
+ is_initialized = true;
+}
+
+static void init_file_type(TSRMLS_D) {
+ static bool is_initialized = false;
+ if (is_initialized) return;
+ init_file_any(TSRMLS_C);
+ init_file_source_context(TSRMLS_C);
+ init_generated_pool_once(TSRMLS_C);
+ const char* generated_file =
+ "0aba0c0a1a676f6f676c652f70726f746f6275662f747970652e70726f74"
+ "6f120f676f6f676c652e70726f746f6275661a19676f6f676c652f70726f"
+ "746f6275662f616e792e70726f746f1a24676f6f676c652f70726f746f62"
+ "75662f736f757263655f636f6e746578742e70726f746f22d7010a045479"
+ "7065120c0a046e616d6518012001280912260a066669656c647318022003"
+ "280b32162e676f6f676c652e70726f746f6275662e4669656c64120e0a06"
+ "6f6e656f667318032003280912280a076f7074696f6e7318042003280b32"
+ "172e676f6f676c652e70726f746f6275662e4f7074696f6e12360a0e736f"
+ "757263655f636f6e7465787418052001280b321e2e676f6f676c652e7072"
+ "6f746f6275662e536f75726365436f6e7465787412270a0673796e746178"
+ "18062001280e32172e676f6f676c652e70726f746f6275662e53796e7461"
+ "7822d5050a054669656c6412290a046b696e6418012001280e321b2e676f"
+ "6f676c652e70726f746f6275662e4669656c642e4b696e6412370a0b6361"
+ "7264696e616c69747918022001280e32222e676f6f676c652e70726f746f"
+ "6275662e4669656c642e43617264696e616c697479120e0a066e756d6265"
+ "72180320012805120c0a046e616d6518042001280912100a08747970655f"
+ "75726c18062001280912130a0b6f6e656f665f696e646578180720012805"
+ "120e0a067061636b656418082001280812280a076f7074696f6e73180920"
+ "03280b32172e676f6f676c652e70726f746f6275662e4f7074696f6e1211"
+ "0a096a736f6e5f6e616d65180a2001280912150a0d64656661756c745f76"
+ "616c7565180b2001280922c8020a044b696e6412100a0c545950455f554e"
+ "4b4e4f574e1000120f0a0b545950455f444f55424c451001120e0a0a5459"
+ "50455f464c4f41541002120e0a0a545950455f494e5436341003120f0a0b"
+ "545950455f55494e5436341004120e0a0a545950455f494e543332100512"
+ "100a0c545950455f46495845443634100612100a0c545950455f46495845"
+ "4433321007120d0a09545950455f424f4f4c1008120f0a0b545950455f53"
+ "5452494e471009120e0a0a545950455f47524f5550100a12100a0c545950"
+ "455f4d455353414745100b120e0a0a545950455f4259544553100c120f0a"
+ "0b545950455f55494e543332100d120d0a09545950455f454e554d100e12"
+ "110a0d545950455f5346495845443332100f12110a0d545950455f534649"
+ "58454436341010120f0a0b545950455f53494e5433321011120f0a0b5459"
+ "50455f53494e543634101222740a0b43617264696e616c69747912170a13"
+ "43415244494e414c4954595f554e4b4e4f574e100012180a144341524449"
+ "4e414c4954595f4f5054494f4e414c100112180a1443415244494e414c49"
+ "54595f5245515549524544100212180a1443415244494e414c4954595f52"
+ "45504541544544100322ce010a04456e756d120c0a046e616d6518012001"
+ "2809122d0a09656e756d76616c756518022003280b321a2e676f6f676c65"
+ "2e70726f746f6275662e456e756d56616c756512280a076f7074696f6e73"
+ "18032003280b32172e676f6f676c652e70726f746f6275662e4f7074696f"
+ "6e12360a0e736f757263655f636f6e7465787418042001280b321e2e676f"
+ "6f676c652e70726f746f6275662e536f75726365436f6e7465787412270a"
+ "0673796e74617818052001280e32172e676f6f676c652e70726f746f6275"
+ "662e53796e74617822530a09456e756d56616c7565120c0a046e616d6518"
+ "0120012809120e0a066e756d62657218022001280512280a076f7074696f"
+ "6e7318032003280b32172e676f6f676c652e70726f746f6275662e4f7074"
+ "696f6e223b0a064f7074696f6e120c0a046e616d6518012001280912230a"
+ "0576616c756518022001280b32142e676f6f676c652e70726f746f627566"
+ "2e416e792a2e0a0653796e74617812110a0d53594e5441585f50524f544f"
+ "32100012110a0d53594e5441585f50524f544f331001427d0a13636f6d2e"
+ "676f6f676c652e70726f746f62756642095479706550726f746f50015a2f"
+ "676f6f676c652e676f6c616e672e6f72672f67656e70726f746f2f70726f"
+ "746f6275662f70747970653b7074797065f80101a20203475042aa021e47"
+ "6f6f676c652e50726f746f6275662e57656c6c4b6e6f776e547970657362"
+ "0670726f746f33";
+ char* binary;
+ int binary_len;
+ hex_to_binary(generated_file, &binary, &binary_len);
+ internal_add_generated_file(binary, binary_len, generated_pool TSRMLS_CC);
+ FREE(binary);
+ is_initialized = true;
+}
+
+static void init_file_wrappers(TSRMLS_D) {
+ static bool is_initialized = false;
+ if (is_initialized) return;
+ init_generated_pool_once(TSRMLS_C);
+ const char* generated_file =
+ "0abf030a1e676f6f676c652f70726f746f6275662f77726170706572732e"
+ "70726f746f120f676f6f676c652e70726f746f627566221c0a0b446f7562"
+ "6c6556616c7565120d0a0576616c7565180120012801221b0a0a466c6f61"
+ "7456616c7565120d0a0576616c7565180120012802221b0a0a496e743634"
+ "56616c7565120d0a0576616c7565180120012803221c0a0b55496e743634"
+ "56616c7565120d0a0576616c7565180120012804221b0a0a496e74333256"
+ "616c7565120d0a0576616c7565180120012805221c0a0b55496e74333256"
+ "616c7565120d0a0576616c756518012001280d221a0a09426f6f6c56616c"
+ "7565120d0a0576616c7565180120012808221c0a0b537472696e6756616c"
+ "7565120d0a0576616c7565180120012809221b0a0a427974657356616c75"
+ "65120d0a0576616c756518012001280c427c0a13636f6d2e676f6f676c65"
+ "2e70726f746f627566420d577261707065727350726f746f50015a2a6769"
+ "746875622e636f6d2f676f6c616e672f70726f746f6275662f7074797065"
+ "732f7772617070657273f80101a20203475042aa021e476f6f676c652e50"
+ "726f746f6275662e57656c6c4b6e6f776e5479706573620670726f746f33";
+ char* binary;
+ int binary_len;
+ hex_to_binary(generated_file, &binary, &binary_len);
+ internal_add_generated_file(binary, binary_len, generated_pool TSRMLS_CC);
+ FREE(binary);
+ is_initialized = true;
+}
+
+// -----------------------------------------------------------------------------
+// Define enum
+// -----------------------------------------------------------------------------
+
+// -----------------------------------------------------------------------------
+// Field_Cardinality
+// -----------------------------------------------------------------------------
+
+static zend_function_entry field_cardinality_methods[] = {
+ {NULL, NULL, NULL}
+};
+
+zend_class_entry* field_cardinality_type;
+
+// Init class entry.
+PHP_PROTO_INIT_ENUMCLASS_START("Google\\Protobuf\\Field_Cardinality",
+ Field_Cardinality, field_cardinality)
+ zend_declare_class_constant_long(field_cardinality_type,
+ "CARDINALITY_UNKNOWN", 19, 0 TSRMLS_CC);
+ zend_declare_class_constant_long(field_cardinality_type,
+ "CARDINALITY_OPTIONAL", 20, 1 TSRMLS_CC);
+ zend_declare_class_constant_long(field_cardinality_type,
+ "CARDINALITY_REQUIRED", 20, 2 TSRMLS_CC);
+ zend_declare_class_constant_long(field_cardinality_type,
+ "CARDINALITY_REPEATED", 20, 3 TSRMLS_CC);
+PHP_PROTO_INIT_ENUMCLASS_END
+
+// -----------------------------------------------------------------------------
+// Field_Kind
+// -----------------------------------------------------------------------------
+
+static zend_function_entry field_kind_methods[] = {
+ {NULL, NULL, NULL}
+};
+
+zend_class_entry* field_kind_type;
+
+// Init class entry.
+PHP_PROTO_INIT_ENUMCLASS_START("Google\\Protobuf\\Field_Kind",
+ Field_Kind, field_kind)
+ zend_declare_class_constant_long(field_kind_type,
+ "TYPE_UNKNOWN", 12, 0 TSRMLS_CC);
+ zend_declare_class_constant_long(field_kind_type,
+ "TYPE_DOUBLE", 11, 1 TSRMLS_CC);
+ zend_declare_class_constant_long(field_kind_type,
+ "TYPE_FLOAT", 10, 2 TSRMLS_CC);
+ zend_declare_class_constant_long(field_kind_type,
+ "TYPE_INT64", 10, 3 TSRMLS_CC);
+ zend_declare_class_constant_long(field_kind_type,
+ "TYPE_UINT64", 11, 4 TSRMLS_CC);
+ zend_declare_class_constant_long(field_kind_type,
+ "TYPE_INT32", 10, 5 TSRMLS_CC);
+ zend_declare_class_constant_long(field_kind_type,
+ "TYPE_FIXED64", 12, 6 TSRMLS_CC);
+ zend_declare_class_constant_long(field_kind_type,
+ "TYPE_FIXED32", 12, 7 TSRMLS_CC);
+ zend_declare_class_constant_long(field_kind_type,
+ "TYPE_BOOL", 9, 8 TSRMLS_CC);
+ zend_declare_class_constant_long(field_kind_type,
+ "TYPE_STRING", 11, 9 TSRMLS_CC);
+ zend_declare_class_constant_long(field_kind_type,
+ "TYPE_GROUP", 10, 10 TSRMLS_CC);
+ zend_declare_class_constant_long(field_kind_type,
+ "TYPE_MESSAGE", 12, 11 TSRMLS_CC);
+ zend_declare_class_constant_long(field_kind_type,
+ "TYPE_BYTES", 10, 12 TSRMLS_CC);
+ zend_declare_class_constant_long(field_kind_type,
+ "TYPE_UINT32", 11, 13 TSRMLS_CC);
+ zend_declare_class_constant_long(field_kind_type,
+ "TYPE_ENUM", 9, 14 TSRMLS_CC);
+ zend_declare_class_constant_long(field_kind_type,
+ "TYPE_SFIXED32", 13, 15 TSRMLS_CC);
+ zend_declare_class_constant_long(field_kind_type,
+ "TYPE_SFIXED64", 13, 16 TSRMLS_CC);
+ zend_declare_class_constant_long(field_kind_type,
+ "TYPE_SINT32", 11, 17 TSRMLS_CC);
+ zend_declare_class_constant_long(field_kind_type,
+ "TYPE_SINT64", 11, 18 TSRMLS_CC);
+PHP_PROTO_INIT_ENUMCLASS_END
+
+// -----------------------------------------------------------------------------
+// NullValue
+// -----------------------------------------------------------------------------
+
+static zend_function_entry null_value_methods[] = {
+ {NULL, NULL, NULL}
+};
+
+zend_class_entry* null_value_type;
+
+// Init class entry.
+PHP_PROTO_INIT_ENUMCLASS_START("Google\\Protobuf\\NullValue",
+ NullValue, null_value)
+ zend_declare_class_constant_long(null_value_type,
+ "NULL_VALUE", 10, 0 TSRMLS_CC);
+PHP_PROTO_INIT_ENUMCLASS_END
+
+// -----------------------------------------------------------------------------
+// Syntax
+// -----------------------------------------------------------------------------
+
+static zend_function_entry syntax_methods[] = {
+ {NULL, NULL, NULL}
+};
+
+zend_class_entry* syntax_type;
+
+// Init class entry.
+PHP_PROTO_INIT_ENUMCLASS_START("Google\\Protobuf\\Syntax",
+ Syntax, syntax)
+ zend_declare_class_constant_long(syntax_type,
+ "SYNTAX_PROTO2", 13, 0 TSRMLS_CC);
+ zend_declare_class_constant_long(syntax_type,
+ "SYNTAX_PROTO3", 13, 1 TSRMLS_CC);
+PHP_PROTO_INIT_ENUMCLASS_END
+
+
+
+// -----------------------------------------------------------------------------
+// Define message
+// -----------------------------------------------------------------------------
+
+// -----------------------------------------------------------------------------
+// Any
+// -----------------------------------------------------------------------------
+
+static zend_function_entry any_methods[] = {
+ PHP_ME(Any, __construct, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(Any, getTypeUrl, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(Any, setTypeUrl, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(Any, getValue, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(Any, setValue, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(Any, pack, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(Any, unpack, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(Any, is, NULL, ZEND_ACC_PUBLIC)
+ {NULL, NULL, NULL}
+};
+
+zend_class_entry* any_type;
+
+// Init class entry.
+PHP_PROTO_INIT_SUBMSGCLASS_START("Google\\Protobuf\\Any", Any, any)
+ zend_class_implements(any_type TSRMLS_CC, 1, message_type);
+ zend_declare_property_string(any_type, "type_url", strlen("type_url"),
+ "" ,ZEND_ACC_PRIVATE TSRMLS_CC);
+ zend_declare_property_string(any_type, "value", strlen("value"),
+ "" ,ZEND_ACC_PRIVATE TSRMLS_CC);
+PHP_PROTO_INIT_SUBMSGCLASS_END
+
+static void hex_to_binary(const char* hex, char** binary, int* binary_len) {
+ int i;
+ int hex_len = strlen(hex);
+ *binary_len = hex_len / 2;
+ *binary = ALLOC_N(char, *binary_len);
+ for (i = 0; i < *binary_len; i++) {
+ char value = 0;
+ if (hex[i * 2] >= '0' && hex[i * 2] <= '9') {
+ value += (hex[i * 2] - '0') * 16;
+ } else {
+ value += (hex[i * 2] - 'a' + 10) * 16;
+ }
+ if (hex[i * 2 + 1] >= '0' && hex[i * 2 + 1] <= '9') {
+ value += hex[i * 2 + 1] - '0';
+ } else {
+ value += hex[i * 2 + 1] - 'a' + 10;
+ }
+ (*binary)[i] = value;
+ }
+}
+
+PHP_METHOD(Any, __construct) {
+ init_file_any(TSRMLS_C);
+ MessageHeader* intern = UNBOX(MessageHeader, getThis());
+ custom_data_init(any_type, intern PHP_PROTO_TSRMLS_CC);
+}
+
+PHP_PROTO_FIELD_ACCESSORS(Any, any, TypeUrl, "type_url")
+PHP_PROTO_FIELD_ACCESSORS(Any, any, Value, "value")
+
+PHP_METHOD(Any, unpack) {
+ // Get type url.
+ zval type_url_member;
+ PHP_PROTO_ZVAL_STRING(&type_url_member, "type_url", 1);
+ PHP_PROTO_FAKE_SCOPE_BEGIN(any_type);
+ zval* type_url_php = php_proto_message_read_property(
+ getThis(), &type_url_member PHP_PROTO_TSRMLS_CC);
+ PHP_PROTO_FAKE_SCOPE_END;
+
+ // Get fully-qualified name from type url.
+ size_t url_prefix_len = strlen(TYPE_URL_PREFIX);
+ const char* type_url = Z_STRVAL_P(type_url_php);
+ size_t type_url_len = Z_STRLEN_P(type_url_php);
+
+ if (url_prefix_len > type_url_len ||
+ strncmp(TYPE_URL_PREFIX, type_url, url_prefix_len) != 0) {
+ zend_throw_exception(
+ NULL, "Type url needs to be type.googleapis.com/fully-qulified",
+ 0 TSRMLS_CC);
+ return;
+ }
+
+ const char* fully_qualified_name = type_url + url_prefix_len;
+ PHP_PROTO_HASHTABLE_VALUE desc_php = get_proto_obj(fully_qualified_name);
+ if (desc_php == NULL) {
+ zend_throw_exception(
+ NULL, "Specified message in any hasn't been added to descriptor pool",
+ 0 TSRMLS_CC);
+ return;
+ }
+ Descriptor* desc = UNBOX_HASHTABLE_VALUE(Descriptor, desc_php);
+ zend_class_entry* klass = desc->klass;
+ ZVAL_OBJ(return_value, klass->create_object(klass TSRMLS_CC));
+ MessageHeader* msg = UNBOX(MessageHeader, return_value);
+ custom_data_init(klass, msg PHP_PROTO_TSRMLS_CC);
+
+ // Get value.
+ zval value_member;
+ PHP_PROTO_ZVAL_STRING(&value_member, "value", 1);
+ PHP_PROTO_FAKE_SCOPE_RESTART(any_type);
+ zval* value = php_proto_message_read_property(
+ getThis(), &value_member PHP_PROTO_TSRMLS_CC);
+ PHP_PROTO_FAKE_SCOPE_END;
+
+ merge_from_string(Z_STRVAL_P(value), Z_STRLEN_P(value), desc, msg);
+}
+
+PHP_METHOD(Any, pack) {
+ zval* val;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o", &val) ==
+ FAILURE) {
+ return;
+ }
+
+ if (!instanceof_function(Z_OBJCE_P(val), message_type TSRMLS_CC)) {
+ zend_error(E_USER_ERROR, "Given value is not an instance of Message.");
+ return;
+ }
+
+ // Set value by serialized data.
+ zval data;
+ serialize_to_string(val, &data TSRMLS_CC);
+
+ zval member;
+ PHP_PROTO_ZVAL_STRING(&member, "value", 1);
+
+ PHP_PROTO_FAKE_SCOPE_BEGIN(any_type);
+ message_handlers->write_property(getThis(), &member, &data,
+ NULL PHP_PROTO_TSRMLS_CC);
+ PHP_PROTO_FAKE_SCOPE_END;
+
+ // Set type url.
+ Descriptor* desc =
+ UNBOX_HASHTABLE_VALUE(Descriptor, get_ce_obj(Z_OBJCE_P(val)));
+ const char* fully_qualified_name = upb_msgdef_fullname(desc->msgdef);
+ size_t type_url_len =
+ strlen(TYPE_URL_PREFIX) + strlen(fully_qualified_name) + 1;
+ char* type_url = ALLOC_N(char, type_url_len);
+ sprintf(type_url, "%s%s", TYPE_URL_PREFIX, fully_qualified_name);
+ zval type_url_php;
+ PHP_PROTO_ZVAL_STRING(&type_url_php, type_url, 1);
+ PHP_PROTO_ZVAL_STRING(&member, "type_url", 1);
+
+ PHP_PROTO_FAKE_SCOPE_RESTART(any_type);
+ message_handlers->write_property(getThis(), &member, &type_url_php,
+ NULL PHP_PROTO_TSRMLS_CC);
+ PHP_PROTO_FAKE_SCOPE_END;
+ FREE(type_url);
+}
+
+PHP_METHOD(Any, is) {
+ zend_class_entry *klass = NULL;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "C", &klass) ==
+ FAILURE) {
+ return;
+ }
+
+ PHP_PROTO_HASHTABLE_VALUE desc_php = get_ce_obj(klass);
+ if (desc_php == NULL) {
+ RETURN_BOOL(false);
+ }
+
+ // Create corresponded type url.
+ Descriptor* desc =
+ UNBOX_HASHTABLE_VALUE(Descriptor, get_ce_obj(klass));
+ const char* fully_qualified_name = upb_msgdef_fullname(desc->msgdef);
+ size_t type_url_len =
+ strlen(TYPE_URL_PREFIX) + strlen(fully_qualified_name) + 1;
+ char* type_url = ALLOC_N(char, type_url_len);
+ sprintf(type_url, "%s%s", TYPE_URL_PREFIX, fully_qualified_name);
+
+ // Fetch stored type url.
+ zval member;
+ PHP_PROTO_ZVAL_STRING(&member, "type_url", 1);
+ PHP_PROTO_FAKE_SCOPE_BEGIN(any_type);
+ zval* value =
+ php_proto_message_read_property(getThis(), &member PHP_PROTO_TSRMLS_CC);
+ PHP_PROTO_FAKE_SCOPE_END;
+
+ // Compare two type url.
+ bool is = strcmp(type_url, Z_STRVAL_P(value)) == 0;
+ FREE(type_url);
+
+ RETURN_BOOL(is);
+}
+
+// -----------------------------------------------------------------------------
+// Duration
+// -----------------------------------------------------------------------------
+
+static zend_function_entry duration_methods[] = {
+ PHP_ME(Duration, __construct, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(Duration, getSeconds, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(Duration, setSeconds, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(Duration, getNanos, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(Duration, setNanos, NULL, ZEND_ACC_PUBLIC)
+ {NULL, NULL, NULL}
+};
+
+zend_class_entry* duration_type;
+
+// Init class entry.
+PHP_PROTO_INIT_SUBMSGCLASS_START("Google\\Protobuf\\Duration",
+ Duration, duration)
+ zend_class_implements(duration_type TSRMLS_CC, 1, message_type);
+ zend_declare_property_long(duration_type, "seconds", strlen("seconds"),
+ 0 ,ZEND_ACC_PRIVATE TSRMLS_CC);
+ zend_declare_property_long(duration_type, "nanos", strlen("nanos"),
+ 0 ,ZEND_ACC_PRIVATE TSRMLS_CC);
+PHP_PROTO_INIT_SUBMSGCLASS_END
+
+PHP_METHOD(Duration, __construct) {
+ init_file_duration(TSRMLS_C);
+ MessageHeader* intern = UNBOX(MessageHeader, getThis());
+ custom_data_init(duration_type, intern PHP_PROTO_TSRMLS_CC);
+}
+
+PHP_PROTO_FIELD_ACCESSORS(Duration, duration, Seconds, "seconds")
+PHP_PROTO_FIELD_ACCESSORS(Duration, duration, Nanos, "nanos")
+
+// -----------------------------------------------------------------------------
+// Timestamp
+// -----------------------------------------------------------------------------
+
+static zend_function_entry timestamp_methods[] = {
+ PHP_ME(Timestamp, __construct, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(Timestamp, fromDateTime, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(Timestamp, toDateTime, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(Timestamp, getSeconds, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(Timestamp, setSeconds, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(Timestamp, getNanos, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(Timestamp, setNanos, NULL, ZEND_ACC_PUBLIC)
+ {NULL, NULL, NULL}
+};
+
+zend_class_entry* timestamp_type;
+
+// Init class entry.
+PHP_PROTO_INIT_SUBMSGCLASS_START("Google\\Protobuf\\Timestamp",
+ Timestamp, timestamp)
+ zend_class_implements(timestamp_type TSRMLS_CC, 1, message_type);
+ zend_declare_property_long(timestamp_type, "seconds", strlen("seconds"),
+ 0 ,ZEND_ACC_PRIVATE TSRMLS_CC);
+ zend_declare_property_long(timestamp_type, "nanos", strlen("nanos"),
+ 0 ,ZEND_ACC_PRIVATE TSRMLS_CC);
+PHP_PROTO_INIT_SUBMSGCLASS_END
+
+PHP_METHOD(Timestamp, __construct) {
+ init_file_timestamp(TSRMLS_C);
+ MessageHeader* intern = UNBOX(MessageHeader, getThis());
+ custom_data_init(timestamp_type, intern PHP_PROTO_TSRMLS_CC);
+}
+
+PHP_PROTO_FIELD_ACCESSORS(Timestamp, timestamp, Seconds, "seconds")
+PHP_PROTO_FIELD_ACCESSORS(Timestamp, timestamp, Nanos, "nanos")
+
+PHP_METHOD(Timestamp, fromDateTime) {
+ zval* datetime;
+ zval member;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O", &datetime,
+ php_date_get_date_ce()) == FAILURE) {
+ return;
+ }
+
+ php_date_obj* dateobj = UNBOX(php_date_obj, datetime);
+ if (!dateobj->time->sse_uptodate) {
+ timelib_update_ts(dateobj->time, NULL);
+ }
+
+ int64_t timestamp = dateobj->time->sse;
+
+ // Set seconds
+ MessageHeader* self = UNBOX(MessageHeader, getThis());
+ const upb_fielddef* field =
+ upb_msgdef_ntofz(self->descriptor->msgdef, "seconds");
+ void* storage = message_data(self);
+ void* memory = slot_memory(self->descriptor->layout, storage, field);
+ *(int64_t*)memory = dateobj->time->sse;
+
+ // Set nanos
+ field = upb_msgdef_ntofz(self->descriptor->msgdef, "nanos");
+ storage = message_data(self);
+ memory = slot_memory(self->descriptor->layout, storage, field);
+ *(int32_t*)memory = 0;
+}
+
+PHP_METHOD(Timestamp, toDateTime) {
+ zval datetime;
+ php_date_instantiate(php_date_get_date_ce(), &datetime TSRMLS_CC);
+ php_date_obj* dateobj = UNBOX(php_date_obj, &datetime);
+
+ // Get seconds
+ MessageHeader* self = UNBOX(MessageHeader, getThis());
+ const upb_fielddef* field =
+ upb_msgdef_ntofz(self->descriptor->msgdef, "seconds");
+ void* storage = message_data(self);
+ void* memory = slot_memory(self->descriptor->layout, storage, field);
+ int64_t seconds = *(int64_t*)memory;
+
+ // Get nanos
+ field = upb_msgdef_ntofz(self->descriptor->msgdef, "nanos");
+ memory = slot_memory(self->descriptor->layout, storage, field);
+ int32_t nanos = *(int32_t*)memory;
+
+ // Get formated time string.
+ char formated_time[50];
+ time_t raw_time = seconds;
+ struct tm *utc_time = gmtime(&raw_time);
+ strftime(formated_time, sizeof(formated_time), "%Y-%m-%dT%H:%M:%SUTC",
+ utc_time);
+
+ if (!php_date_initialize(dateobj, formated_time, strlen(formated_time), NULL,
+ NULL, 0 TSRMLS_CC)) {
+ zval_dtor(&datetime);
+ RETURN_NULL();
+ }
+
+ zval* datetime_ptr = &datetime;
+ PHP_PROTO_RETVAL_ZVAL(datetime_ptr);
+}
+
+// -----------------------------------------------------------------------------
+// Api
+// -----------------------------------------------------------------------------
+
+static zend_function_entry api_methods[] = {
+ PHP_ME(Api, __construct, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(Api, getName, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(Api, setName, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(Api, getMethods, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(Api, setMethods, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(Api, getOptions, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(Api, setOptions, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(Api, getVersion, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(Api, setVersion, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(Api, getSourceContext, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(Api, setSourceContext, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(Api, getMixins, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(Api, setMixins, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(Api, getSyntax, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(Api, setSyntax, NULL, ZEND_ACC_PUBLIC)
+ {NULL, NULL, NULL}
+};
+
+zend_class_entry* api_type;
+
+// Init class entry.
+PHP_PROTO_INIT_SUBMSGCLASS_START("Google\\Protobuf\\Api",
+ Api, api)
+ zend_class_implements(api_type TSRMLS_CC, 1, message_type);
+ zend_declare_property_null(api_type, "name", strlen("name"),
+ ZEND_ACC_PRIVATE TSRMLS_CC);
+ zend_declare_property_null(api_type, "methods", strlen("methods"),
+ ZEND_ACC_PRIVATE TSRMLS_CC);
+ zend_declare_property_null(api_type, "options", strlen("options"),
+ ZEND_ACC_PRIVATE TSRMLS_CC);
+ zend_declare_property_null(api_type, "version", strlen("version"),
+ ZEND_ACC_PRIVATE TSRMLS_CC);
+ zend_declare_property_null(api_type, "source_context", strlen("source_context"),
+ ZEND_ACC_PRIVATE TSRMLS_CC);
+ zend_declare_property_null(api_type, "mixins", strlen("mixins"),
+ ZEND_ACC_PRIVATE TSRMLS_CC);
+ zend_declare_property_null(api_type, "syntax", strlen("syntax"),
+ ZEND_ACC_PRIVATE TSRMLS_CC);
+PHP_PROTO_INIT_SUBMSGCLASS_END
+
+PHP_METHOD(Api, __construct) {
+ init_file_api(TSRMLS_C);
+ MessageHeader* intern = UNBOX(MessageHeader, getThis());
+ custom_data_init(api_type, intern PHP_PROTO_TSRMLS_CC);
+}
+
+PHP_PROTO_FIELD_ACCESSORS(Api, api, Name, "name")
+PHP_PROTO_FIELD_ACCESSORS(Api, api, Methods, "methods")
+PHP_PROTO_FIELD_ACCESSORS(Api, api, Options, "options")
+PHP_PROTO_FIELD_ACCESSORS(Api, api, Version, "version")
+PHP_PROTO_FIELD_ACCESSORS(Api, api, SourceContext, "source_context")
+PHP_PROTO_FIELD_ACCESSORS(Api, api, Mixins, "mixins")
+PHP_PROTO_FIELD_ACCESSORS(Api, api, Syntax, "syntax")
+
+// -----------------------------------------------------------------------------
+// BoolValue
+// -----------------------------------------------------------------------------
+
+static zend_function_entry bool_value_methods[] = {
+ PHP_ME(BoolValue, __construct, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(BoolValue, getValue, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(BoolValue, setValue, NULL, ZEND_ACC_PUBLIC)
+ {NULL, NULL, NULL}
+};
+
+zend_class_entry* bool_value_type;
+
+// Init class entry.
+PHP_PROTO_INIT_SUBMSGCLASS_START("Google\\Protobuf\\BoolValue",
+ BoolValue, bool_value)
+ zend_class_implements(bool_value_type TSRMLS_CC, 1, message_type);
+ zend_declare_property_null(bool_value_type, "value", strlen("value"),
+ ZEND_ACC_PRIVATE TSRMLS_CC);
+PHP_PROTO_INIT_SUBMSGCLASS_END
+
+PHP_METHOD(BoolValue, __construct) {
+ init_file_wrappers(TSRMLS_C);
+ MessageHeader* intern = UNBOX(MessageHeader, getThis());
+ custom_data_init(bool_value_type, intern PHP_PROTO_TSRMLS_CC);
+}
+
+PHP_PROTO_FIELD_ACCESSORS(BoolValue, bool_value, Value, "value")
+
+// -----------------------------------------------------------------------------
+// BytesValue
+// -----------------------------------------------------------------------------
+
+static zend_function_entry bytes_value_methods[] = {
+ PHP_ME(BytesValue, __construct, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(BytesValue, getValue, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(BytesValue, setValue, NULL, ZEND_ACC_PUBLIC)
+ {NULL, NULL, NULL}
+};
+
+zend_class_entry* bytes_value_type;
+
+// Init class entry.
+PHP_PROTO_INIT_SUBMSGCLASS_START("Google\\Protobuf\\BytesValue",
+ BytesValue, bytes_value)
+ zend_class_implements(bytes_value_type TSRMLS_CC, 1, message_type);
+ zend_declare_property_null(bytes_value_type, "value", strlen("value"),
+ ZEND_ACC_PRIVATE TSRMLS_CC);
+PHP_PROTO_INIT_SUBMSGCLASS_END
+
+PHP_METHOD(BytesValue, __construct) {
+ init_file_wrappers(TSRMLS_C);
+ MessageHeader* intern = UNBOX(MessageHeader, getThis());
+ custom_data_init(bytes_value_type, intern PHP_PROTO_TSRMLS_CC);
+}
+
+PHP_PROTO_FIELD_ACCESSORS(BytesValue, bytes_value, Value, "value")
+
+// -----------------------------------------------------------------------------
+// DoubleValue
+// -----------------------------------------------------------------------------
+
+static zend_function_entry double_value_methods[] = {
+ PHP_ME(DoubleValue, __construct, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(DoubleValue, getValue, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(DoubleValue, setValue, NULL, ZEND_ACC_PUBLIC)
+ {NULL, NULL, NULL}
+};
+
+zend_class_entry* double_value_type;
+
+// Init class entry.
+PHP_PROTO_INIT_SUBMSGCLASS_START("Google\\Protobuf\\DoubleValue",
+ DoubleValue, double_value)
+ zend_class_implements(double_value_type TSRMLS_CC, 1, message_type);
+ zend_declare_property_null(double_value_type, "value", strlen("value"),
+ ZEND_ACC_PRIVATE TSRMLS_CC);
+PHP_PROTO_INIT_SUBMSGCLASS_END
+
+PHP_METHOD(DoubleValue, __construct) {
+ init_file_wrappers(TSRMLS_C);
+ MessageHeader* intern = UNBOX(MessageHeader, getThis());
+ custom_data_init(double_value_type, intern PHP_PROTO_TSRMLS_CC);
+}
+
+PHP_PROTO_FIELD_ACCESSORS(DoubleValue, double_value, Value, "value")
+
+// -----------------------------------------------------------------------------
+// Enum
+// -----------------------------------------------------------------------------
+
+static zend_function_entry enum_methods[] = {
+ PHP_ME(Enum, __construct, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(Enum, getName, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(Enum, setName, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(Enum, getEnumvalue, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(Enum, setEnumvalue, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(Enum, getOptions, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(Enum, setOptions, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(Enum, getSourceContext, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(Enum, setSourceContext, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(Enum, getSyntax, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(Enum, setSyntax, NULL, ZEND_ACC_PUBLIC)
+ {NULL, NULL, NULL}
+};
+
+zend_class_entry* enum_type;
+
+// Init class entry.
+PHP_PROTO_INIT_SUBMSGCLASS_START("Google\\Protobuf\\Enum",
+ Enum, enum)
+ zend_class_implements(enum_type TSRMLS_CC, 1, message_type);
+ zend_declare_property_null(enum_type, "name", strlen("name"),
+ ZEND_ACC_PRIVATE TSRMLS_CC);
+ zend_declare_property_null(enum_type, "enumvalue", strlen("enumvalue"),
+ ZEND_ACC_PRIVATE TSRMLS_CC);
+ zend_declare_property_null(enum_type, "options", strlen("options"),
+ ZEND_ACC_PRIVATE TSRMLS_CC);
+ zend_declare_property_null(enum_type, "source_context", strlen("source_context"),
+ ZEND_ACC_PRIVATE TSRMLS_CC);
+ zend_declare_property_null(enum_type, "syntax", strlen("syntax"),
+ ZEND_ACC_PRIVATE TSRMLS_CC);
+PHP_PROTO_INIT_SUBMSGCLASS_END
+
+PHP_METHOD(Enum, __construct) {
+ init_file_type(TSRMLS_C);
+ MessageHeader* intern = UNBOX(MessageHeader, getThis());
+ custom_data_init(enum_type, intern PHP_PROTO_TSRMLS_CC);
+}
+
+PHP_PROTO_FIELD_ACCESSORS(Enum, enum, Name, "name")
+PHP_PROTO_FIELD_ACCESSORS(Enum, enum, Enumvalue, "enumvalue")
+PHP_PROTO_FIELD_ACCESSORS(Enum, enum, Options, "options")
+PHP_PROTO_FIELD_ACCESSORS(Enum, enum, SourceContext, "source_context")
+PHP_PROTO_FIELD_ACCESSORS(Enum, enum, Syntax, "syntax")
+
+// -----------------------------------------------------------------------------
+// EnumValue
+// -----------------------------------------------------------------------------
+
+static zend_function_entry enum_value_methods[] = {
+ PHP_ME(EnumValue, __construct, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(EnumValue, getName, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(EnumValue, setName, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(EnumValue, getNumber, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(EnumValue, setNumber, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(EnumValue, getOptions, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(EnumValue, setOptions, NULL, ZEND_ACC_PUBLIC)
+ {NULL, NULL, NULL}
+};
+
+zend_class_entry* enum_value_type;
+
+// Init class entry.
+PHP_PROTO_INIT_SUBMSGCLASS_START("Google\\Protobuf\\EnumValue",
+ EnumValue, enum_value)
+ zend_class_implements(enum_value_type TSRMLS_CC, 1, message_type);
+ zend_declare_property_null(enum_value_type, "name", strlen("name"),
+ ZEND_ACC_PRIVATE TSRMLS_CC);
+ zend_declare_property_null(enum_value_type, "number", strlen("number"),
+ ZEND_ACC_PRIVATE TSRMLS_CC);
+ zend_declare_property_null(enum_value_type, "options", strlen("options"),
+ ZEND_ACC_PRIVATE TSRMLS_CC);
+PHP_PROTO_INIT_SUBMSGCLASS_END
+
+PHP_METHOD(EnumValue, __construct) {
+ init_file_type(TSRMLS_C);
+ MessageHeader* intern = UNBOX(MessageHeader, getThis());
+ custom_data_init(enum_value_type, intern PHP_PROTO_TSRMLS_CC);
+}
+
+PHP_PROTO_FIELD_ACCESSORS(EnumValue, enum_value, Name, "name")
+PHP_PROTO_FIELD_ACCESSORS(EnumValue, enum_value, Number, "number")
+PHP_PROTO_FIELD_ACCESSORS(EnumValue, enum_value, Options, "options")
+
+// -----------------------------------------------------------------------------
+// FieldMask
+// -----------------------------------------------------------------------------
+
+static zend_function_entry field_mask_methods[] = {
+ PHP_ME(FieldMask, __construct, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(FieldMask, getPaths, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(FieldMask, setPaths, NULL, ZEND_ACC_PUBLIC)
+ {NULL, NULL, NULL}
+};
+
+zend_class_entry* field_mask_type;
+
+// Init class entry.
+PHP_PROTO_INIT_SUBMSGCLASS_START("Google\\Protobuf\\FieldMask",
+ FieldMask, field_mask)
+ zend_class_implements(field_mask_type TSRMLS_CC, 1, message_type);
+ zend_declare_property_null(field_mask_type, "paths", strlen("paths"),
+ ZEND_ACC_PRIVATE TSRMLS_CC);
+PHP_PROTO_INIT_SUBMSGCLASS_END
+
+PHP_METHOD(FieldMask, __construct) {
+ init_file_field_mask(TSRMLS_C);
+ MessageHeader* intern = UNBOX(MessageHeader, getThis());
+ custom_data_init(field_mask_type, intern PHP_PROTO_TSRMLS_CC);
+}
+
+PHP_PROTO_FIELD_ACCESSORS(FieldMask, field_mask, Paths, "paths")
+
+// -----------------------------------------------------------------------------
+// Field
+// -----------------------------------------------------------------------------
+
+static zend_function_entry field_methods[] = {
+ PHP_ME(Field, __construct, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(Field, getKind, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(Field, setKind, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(Field, getCardinality, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(Field, setCardinality, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(Field, getNumber, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(Field, setNumber, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(Field, getName, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(Field, setName, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(Field, getTypeUrl, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(Field, setTypeUrl, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(Field, getOneofIndex, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(Field, setOneofIndex, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(Field, getPacked, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(Field, setPacked, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(Field, getOptions, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(Field, setOptions, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(Field, getJsonName, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(Field, setJsonName, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(Field, getDefaultValue, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(Field, setDefaultValue, NULL, ZEND_ACC_PUBLIC)
+ {NULL, NULL, NULL}
+};
+
+zend_class_entry* field_type;
+
+// Init class entry.
+PHP_PROTO_INIT_SUBMSGCLASS_START("Google\\Protobuf\\Field",
+ Field, field)
+ zend_class_implements(field_type TSRMLS_CC, 1, message_type);
+ zend_declare_property_null(field_type, "kind", strlen("kind"),
+ ZEND_ACC_PRIVATE TSRMLS_CC);
+ zend_declare_property_null(field_type, "cardinality", strlen("cardinality"),
+ ZEND_ACC_PRIVATE TSRMLS_CC);
+ zend_declare_property_null(field_type, "number", strlen("number"),
+ ZEND_ACC_PRIVATE TSRMLS_CC);
+ zend_declare_property_null(field_type, "name", strlen("name"),
+ ZEND_ACC_PRIVATE TSRMLS_CC);
+ zend_declare_property_null(field_type, "type_url", strlen("type_url"),
+ ZEND_ACC_PRIVATE TSRMLS_CC);
+ zend_declare_property_null(field_type, "oneof_index", strlen("oneof_index"),
+ ZEND_ACC_PRIVATE TSRMLS_CC);
+ zend_declare_property_null(field_type, "packed", strlen("packed"),
+ ZEND_ACC_PRIVATE TSRMLS_CC);
+ zend_declare_property_null(field_type, "options", strlen("options"),
+ ZEND_ACC_PRIVATE TSRMLS_CC);
+ zend_declare_property_null(field_type, "json_name", strlen("json_name"),
+ ZEND_ACC_PRIVATE TSRMLS_CC);
+ zend_declare_property_null(field_type, "default_value", strlen("default_value"),
+ ZEND_ACC_PRIVATE TSRMLS_CC);
+PHP_PROTO_INIT_SUBMSGCLASS_END
+
+PHP_METHOD(Field, __construct) {
+ init_file_type(TSRMLS_C);
+ MessageHeader* intern = UNBOX(MessageHeader, getThis());
+ custom_data_init(field_type, intern PHP_PROTO_TSRMLS_CC);
+}
+
+PHP_PROTO_FIELD_ACCESSORS(Field, field, Kind, "kind")
+PHP_PROTO_FIELD_ACCESSORS(Field, field, Cardinality, "cardinality")
+PHP_PROTO_FIELD_ACCESSORS(Field, field, Number, "number")
+PHP_PROTO_FIELD_ACCESSORS(Field, field, Name, "name")
+PHP_PROTO_FIELD_ACCESSORS(Field, field, TypeUrl, "type_url")
+PHP_PROTO_FIELD_ACCESSORS(Field, field, OneofIndex, "oneof_index")
+PHP_PROTO_FIELD_ACCESSORS(Field, field, Packed, "packed")
+PHP_PROTO_FIELD_ACCESSORS(Field, field, Options, "options")
+PHP_PROTO_FIELD_ACCESSORS(Field, field, JsonName, "json_name")
+PHP_PROTO_FIELD_ACCESSORS(Field, field, DefaultValue, "default_value")
+
+// -----------------------------------------------------------------------------
+// FloatValue
+// -----------------------------------------------------------------------------
+
+static zend_function_entry float_value_methods[] = {
+ PHP_ME(FloatValue, __construct, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(FloatValue, getValue, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(FloatValue, setValue, NULL, ZEND_ACC_PUBLIC)
+ {NULL, NULL, NULL}
+};
+
+zend_class_entry* float_value_type;
+
+// Init class entry.
+PHP_PROTO_INIT_SUBMSGCLASS_START("Google\\Protobuf\\FloatValue",
+ FloatValue, float_value)
+ zend_class_implements(float_value_type TSRMLS_CC, 1, message_type);
+ zend_declare_property_null(float_value_type, "value", strlen("value"),
+ ZEND_ACC_PRIVATE TSRMLS_CC);
+PHP_PROTO_INIT_SUBMSGCLASS_END
+
+PHP_METHOD(FloatValue, __construct) {
+ init_file_wrappers(TSRMLS_C);
+ MessageHeader* intern = UNBOX(MessageHeader, getThis());
+ custom_data_init(float_value_type, intern PHP_PROTO_TSRMLS_CC);
+}
+
+PHP_PROTO_FIELD_ACCESSORS(FloatValue, float_value, Value, "value")
+
+// -----------------------------------------------------------------------------
+// GPBEmpty
+// -----------------------------------------------------------------------------
+
+static zend_function_entry empty_methods[] = {
+ PHP_ME(GPBEmpty, __construct, NULL, ZEND_ACC_PUBLIC)
+ {NULL, NULL, NULL}
+};
+
+zend_class_entry* empty_type;
+
+// Init class entry.
+PHP_PROTO_INIT_SUBMSGCLASS_START("Google\\Protobuf\\GPBEmpty",
+ GPBEmpty, empty)
+ zend_class_implements(empty_type TSRMLS_CC, 1, message_type);
+PHP_PROTO_INIT_SUBMSGCLASS_END
+
+PHP_METHOD(GPBEmpty, __construct) {
+ init_file_empty(TSRMLS_C);
+ MessageHeader* intern = UNBOX(MessageHeader, getThis());
+ custom_data_init(empty_type, intern PHP_PROTO_TSRMLS_CC);
+}
+
+
+// -----------------------------------------------------------------------------
+// Int32Value
+// -----------------------------------------------------------------------------
+
+static zend_function_entry int32_value_methods[] = {
+ PHP_ME(Int32Value, __construct, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(Int32Value, getValue, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(Int32Value, setValue, NULL, ZEND_ACC_PUBLIC)
+ {NULL, NULL, NULL}
+};
+
+zend_class_entry* int32_value_type;
+
+// Init class entry.
+PHP_PROTO_INIT_SUBMSGCLASS_START("Google\\Protobuf\\Int32Value",
+ Int32Value, int32_value)
+ zend_class_implements(int32_value_type TSRMLS_CC, 1, message_type);
+ zend_declare_property_null(int32_value_type, "value", strlen("value"),
+ ZEND_ACC_PRIVATE TSRMLS_CC);
+PHP_PROTO_INIT_SUBMSGCLASS_END
+
+PHP_METHOD(Int32Value, __construct) {
+ init_file_wrappers(TSRMLS_C);
+ MessageHeader* intern = UNBOX(MessageHeader, getThis());
+ custom_data_init(int32_value_type, intern PHP_PROTO_TSRMLS_CC);
+}
+
+PHP_PROTO_FIELD_ACCESSORS(Int32Value, int32_value, Value, "value")
+
+// -----------------------------------------------------------------------------
+// Int64Value
+// -----------------------------------------------------------------------------
+
+static zend_function_entry int64_value_methods[] = {
+ PHP_ME(Int64Value, __construct, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(Int64Value, getValue, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(Int64Value, setValue, NULL, ZEND_ACC_PUBLIC)
+ {NULL, NULL, NULL}
+};
+
+zend_class_entry* int64_value_type;
+
+// Init class entry.
+PHP_PROTO_INIT_SUBMSGCLASS_START("Google\\Protobuf\\Int64Value",
+ Int64Value, int64_value)
+ zend_class_implements(int64_value_type TSRMLS_CC, 1, message_type);
+ zend_declare_property_null(int64_value_type, "value", strlen("value"),
+ ZEND_ACC_PRIVATE TSRMLS_CC);
+PHP_PROTO_INIT_SUBMSGCLASS_END
+
+PHP_METHOD(Int64Value, __construct) {
+ init_file_wrappers(TSRMLS_C);
+ MessageHeader* intern = UNBOX(MessageHeader, getThis());
+ custom_data_init(int64_value_type, intern PHP_PROTO_TSRMLS_CC);
+}
+
+PHP_PROTO_FIELD_ACCESSORS(Int64Value, int64_value, Value, "value")
+
+// -----------------------------------------------------------------------------
+// ListValue
+// -----------------------------------------------------------------------------
+
+static zend_function_entry list_value_methods[] = {
+ PHP_ME(ListValue, __construct, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(ListValue, getValues, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(ListValue, setValues, NULL, ZEND_ACC_PUBLIC)
+ {NULL, NULL, NULL}
+};
+
+zend_class_entry* list_value_type;
+
+// Init class entry.
+PHP_PROTO_INIT_SUBMSGCLASS_START("Google\\Protobuf\\ListValue",
+ ListValue, list_value)
+ zend_class_implements(list_value_type TSRMLS_CC, 1, message_type);
+ zend_declare_property_null(list_value_type, "values", strlen("values"),
+ ZEND_ACC_PRIVATE TSRMLS_CC);
+PHP_PROTO_INIT_SUBMSGCLASS_END
+
+PHP_METHOD(ListValue, __construct) {
+ init_file_struct(TSRMLS_C);
+ MessageHeader* intern = UNBOX(MessageHeader, getThis());
+ custom_data_init(list_value_type, intern PHP_PROTO_TSRMLS_CC);
+}
+
+PHP_PROTO_FIELD_ACCESSORS(ListValue, list_value, Values, "values")
+
+// -----------------------------------------------------------------------------
+// Method
+// -----------------------------------------------------------------------------
+
+static zend_function_entry method_methods[] = {
+ PHP_ME(Method, __construct, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(Method, getName, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(Method, setName, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(Method, getRequestTypeUrl, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(Method, setRequestTypeUrl, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(Method, getRequestStreaming, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(Method, setRequestStreaming, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(Method, getResponseTypeUrl, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(Method, setResponseTypeUrl, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(Method, getResponseStreaming, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(Method, setResponseStreaming, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(Method, getOptions, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(Method, setOptions, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(Method, getSyntax, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(Method, setSyntax, NULL, ZEND_ACC_PUBLIC)
+ {NULL, NULL, NULL}
+};
+
+zend_class_entry* method_type;
+
+// Init class entry.
+PHP_PROTO_INIT_SUBMSGCLASS_START("Google\\Protobuf\\Method",
+ Method, method)
+ zend_class_implements(method_type TSRMLS_CC, 1, message_type);
+ zend_declare_property_null(method_type, "name", strlen("name"),
+ ZEND_ACC_PRIVATE TSRMLS_CC);
+ zend_declare_property_null(method_type, "request_type_url", strlen("request_type_url"),
+ ZEND_ACC_PRIVATE TSRMLS_CC);
+ zend_declare_property_null(method_type, "request_streaming", strlen("request_streaming"),
+ ZEND_ACC_PRIVATE TSRMLS_CC);
+ zend_declare_property_null(method_type, "response_type_url", strlen("response_type_url"),
+ ZEND_ACC_PRIVATE TSRMLS_CC);
+ zend_declare_property_null(method_type, "response_streaming", strlen("response_streaming"),
+ ZEND_ACC_PRIVATE TSRMLS_CC);
+ zend_declare_property_null(method_type, "options", strlen("options"),
+ ZEND_ACC_PRIVATE TSRMLS_CC);
+ zend_declare_property_null(method_type, "syntax", strlen("syntax"),
+ ZEND_ACC_PRIVATE TSRMLS_CC);
+PHP_PROTO_INIT_SUBMSGCLASS_END
+
+PHP_METHOD(Method, __construct) {
+ init_file_api(TSRMLS_C);
+ MessageHeader* intern = UNBOX(MessageHeader, getThis());
+ custom_data_init(method_type, intern PHP_PROTO_TSRMLS_CC);
+}
+
+PHP_PROTO_FIELD_ACCESSORS(Method, method, Name, "name")
+PHP_PROTO_FIELD_ACCESSORS(Method, method, RequestTypeUrl, "request_type_url")
+PHP_PROTO_FIELD_ACCESSORS(Method, method, RequestStreaming, "request_streaming")
+PHP_PROTO_FIELD_ACCESSORS(Method, method, ResponseTypeUrl, "response_type_url")
+PHP_PROTO_FIELD_ACCESSORS(Method, method, ResponseStreaming, "response_streaming")
+PHP_PROTO_FIELD_ACCESSORS(Method, method, Options, "options")
+PHP_PROTO_FIELD_ACCESSORS(Method, method, Syntax, "syntax")
+
+// -----------------------------------------------------------------------------
+// Mixin
+// -----------------------------------------------------------------------------
+
+static zend_function_entry mixin_methods[] = {
+ PHP_ME(Mixin, __construct, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(Mixin, getName, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(Mixin, setName, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(Mixin, getRoot, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(Mixin, setRoot, NULL, ZEND_ACC_PUBLIC)
+ {NULL, NULL, NULL}
+};
+
+zend_class_entry* mixin_type;
+
+// Init class entry.
+PHP_PROTO_INIT_SUBMSGCLASS_START("Google\\Protobuf\\Mixin",
+ Mixin, mixin)
+ zend_class_implements(mixin_type TSRMLS_CC, 1, message_type);
+ zend_declare_property_null(mixin_type, "name", strlen("name"),
+ ZEND_ACC_PRIVATE TSRMLS_CC);
+ zend_declare_property_null(mixin_type, "root", strlen("root"),
+ ZEND_ACC_PRIVATE TSRMLS_CC);
+PHP_PROTO_INIT_SUBMSGCLASS_END
+
+PHP_METHOD(Mixin, __construct) {
+ init_file_api(TSRMLS_C);
+ MessageHeader* intern = UNBOX(MessageHeader, getThis());
+ custom_data_init(mixin_type, intern PHP_PROTO_TSRMLS_CC);
+}
+
+PHP_PROTO_FIELD_ACCESSORS(Mixin, mixin, Name, "name")
+PHP_PROTO_FIELD_ACCESSORS(Mixin, mixin, Root, "root")
+
+// -----------------------------------------------------------------------------
+// Option
+// -----------------------------------------------------------------------------
+
+static zend_function_entry option_methods[] = {
+ PHP_ME(Option, __construct, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(Option, getName, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(Option, setName, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(Option, getValue, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(Option, setValue, NULL, ZEND_ACC_PUBLIC)
+ {NULL, NULL, NULL}
+};
+
+zend_class_entry* option_type;
+
+// Init class entry.
+PHP_PROTO_INIT_SUBMSGCLASS_START("Google\\Protobuf\\Option",
+ Option, option)
+ zend_class_implements(option_type TSRMLS_CC, 1, message_type);
+ zend_declare_property_null(option_type, "name", strlen("name"),
+ ZEND_ACC_PRIVATE TSRMLS_CC);
+ zend_declare_property_null(option_type, "value", strlen("value"),
+ ZEND_ACC_PRIVATE TSRMLS_CC);
+PHP_PROTO_INIT_SUBMSGCLASS_END
+
+PHP_METHOD(Option, __construct) {
+ init_file_type(TSRMLS_C);
+ MessageHeader* intern = UNBOX(MessageHeader, getThis());
+ custom_data_init(option_type, intern PHP_PROTO_TSRMLS_CC);
+}
+
+PHP_PROTO_FIELD_ACCESSORS(Option, option, Name, "name")
+PHP_PROTO_FIELD_ACCESSORS(Option, option, Value, "value")
+
+// -----------------------------------------------------------------------------
+// SourceContext
+// -----------------------------------------------------------------------------
+
+static zend_function_entry source_context_methods[] = {
+ PHP_ME(SourceContext, __construct, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(SourceContext, getFileName, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(SourceContext, setFileName, NULL, ZEND_ACC_PUBLIC)
+ {NULL, NULL, NULL}
+};
+
+zend_class_entry* source_context_type;
+
+// Init class entry.
+PHP_PROTO_INIT_SUBMSGCLASS_START("Google\\Protobuf\\SourceContext",
+ SourceContext, source_context)
+ zend_class_implements(source_context_type TSRMLS_CC, 1, message_type);
+ zend_declare_property_null(source_context_type, "file_name", strlen("file_name"),
+ ZEND_ACC_PRIVATE TSRMLS_CC);
+PHP_PROTO_INIT_SUBMSGCLASS_END
+
+PHP_METHOD(SourceContext, __construct) {
+ init_file_source_context(TSRMLS_C);
+ MessageHeader* intern = UNBOX(MessageHeader, getThis());
+ custom_data_init(source_context_type, intern PHP_PROTO_TSRMLS_CC);
+}
+
+PHP_PROTO_FIELD_ACCESSORS(SourceContext, source_context, FileName, "file_name")
+
+// -----------------------------------------------------------------------------
+// StringValue
+// -----------------------------------------------------------------------------
+
+static zend_function_entry string_value_methods[] = {
+ PHP_ME(StringValue, __construct, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(StringValue, getValue, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(StringValue, setValue, NULL, ZEND_ACC_PUBLIC)
+ {NULL, NULL, NULL}
+};
+
+zend_class_entry* string_value_type;
+
+// Init class entry.
+PHP_PROTO_INIT_SUBMSGCLASS_START("Google\\Protobuf\\StringValue",
+ StringValue, string_value)
+ zend_class_implements(string_value_type TSRMLS_CC, 1, message_type);
+ zend_declare_property_null(string_value_type, "value", strlen("value"),
+ ZEND_ACC_PRIVATE TSRMLS_CC);
+PHP_PROTO_INIT_SUBMSGCLASS_END
+
+PHP_METHOD(StringValue, __construct) {
+ init_file_wrappers(TSRMLS_C);
+ MessageHeader* intern = UNBOX(MessageHeader, getThis());
+ custom_data_init(string_value_type, intern PHP_PROTO_TSRMLS_CC);
+}
+
+PHP_PROTO_FIELD_ACCESSORS(StringValue, string_value, Value, "value")
+
+// -----------------------------------------------------------------------------
+// Struct
+// -----------------------------------------------------------------------------
+
+static zend_function_entry struct_methods[] = {
+ PHP_ME(Struct, __construct, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(Struct, getFields, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(Struct, setFields, NULL, ZEND_ACC_PUBLIC)
+ {NULL, NULL, NULL}
+};
+
+zend_class_entry* struct_type;
+
+// Init class entry.
+PHP_PROTO_INIT_SUBMSGCLASS_START("Google\\Protobuf\\Struct",
+ Struct, struct)
+ zend_class_implements(struct_type TSRMLS_CC, 1, message_type);
+ zend_declare_property_null(struct_type, "fields", strlen("fields"),
+ ZEND_ACC_PRIVATE TSRMLS_CC);
+PHP_PROTO_INIT_SUBMSGCLASS_END
+
+PHP_METHOD(Struct, __construct) {
+ init_file_struct(TSRMLS_C);
+ MessageHeader* intern = UNBOX(MessageHeader, getThis());
+ custom_data_init(struct_type, intern PHP_PROTO_TSRMLS_CC);
+}
+
+PHP_PROTO_FIELD_ACCESSORS(Struct, struct, Fields, "fields")
+
+// -----------------------------------------------------------------------------
+// Type
+// -----------------------------------------------------------------------------
+
+static zend_function_entry type_methods[] = {
+ PHP_ME(Type, __construct, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(Type, getName, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(Type, setName, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(Type, getFields, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(Type, setFields, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(Type, getOneofs, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(Type, setOneofs, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(Type, getOptions, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(Type, setOptions, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(Type, getSourceContext, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(Type, setSourceContext, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(Type, getSyntax, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(Type, setSyntax, NULL, ZEND_ACC_PUBLIC)
+ {NULL, NULL, NULL}
+};
+
+zend_class_entry* type_type;
+
+// Init class entry.
+PHP_PROTO_INIT_SUBMSGCLASS_START("Google\\Protobuf\\Type",
+ Type, type)
+ zend_class_implements(type_type TSRMLS_CC, 1, message_type);
+ zend_declare_property_null(type_type, "name", strlen("name"),
+ ZEND_ACC_PRIVATE TSRMLS_CC);
+ zend_declare_property_null(type_type, "fields", strlen("fields"),
+ ZEND_ACC_PRIVATE TSRMLS_CC);
+ zend_declare_property_null(type_type, "oneofs", strlen("oneofs"),
+ ZEND_ACC_PRIVATE TSRMLS_CC);
+ zend_declare_property_null(type_type, "options", strlen("options"),
+ ZEND_ACC_PRIVATE TSRMLS_CC);
+ zend_declare_property_null(type_type, "source_context", strlen("source_context"),
+ ZEND_ACC_PRIVATE TSRMLS_CC);
+ zend_declare_property_null(type_type, "syntax", strlen("syntax"),
+ ZEND_ACC_PRIVATE TSRMLS_CC);
+PHP_PROTO_INIT_SUBMSGCLASS_END
+
+PHP_METHOD(Type, __construct) {
+ init_file_type(TSRMLS_C);
+ MessageHeader* intern = UNBOX(MessageHeader, getThis());
+ custom_data_init(type_type, intern PHP_PROTO_TSRMLS_CC);
+}
+
+PHP_PROTO_FIELD_ACCESSORS(Type, type, Name, "name")
+PHP_PROTO_FIELD_ACCESSORS(Type, type, Fields, "fields")
+PHP_PROTO_FIELD_ACCESSORS(Type, type, Oneofs, "oneofs")
+PHP_PROTO_FIELD_ACCESSORS(Type, type, Options, "options")
+PHP_PROTO_FIELD_ACCESSORS(Type, type, SourceContext, "source_context")
+PHP_PROTO_FIELD_ACCESSORS(Type, type, Syntax, "syntax")
+
+// -----------------------------------------------------------------------------
+// UInt32Value
+// -----------------------------------------------------------------------------
+
+static zend_function_entry u_int32_value_methods[] = {
+ PHP_ME(UInt32Value, __construct, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(UInt32Value, getValue, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(UInt32Value, setValue, NULL, ZEND_ACC_PUBLIC)
+ {NULL, NULL, NULL}
+};
+
+zend_class_entry* u_int32_value_type;
+
+// Init class entry.
+PHP_PROTO_INIT_SUBMSGCLASS_START("Google\\Protobuf\\UInt32Value",
+ UInt32Value, u_int32_value)
+ zend_class_implements(u_int32_value_type TSRMLS_CC, 1, message_type);
+ zend_declare_property_null(u_int32_value_type, "value", strlen("value"),
+ ZEND_ACC_PRIVATE TSRMLS_CC);
+PHP_PROTO_INIT_SUBMSGCLASS_END
+
+PHP_METHOD(UInt32Value, __construct) {
+ init_file_wrappers(TSRMLS_C);
+ MessageHeader* intern = UNBOX(MessageHeader, getThis());
+ custom_data_init(u_int32_value_type, intern PHP_PROTO_TSRMLS_CC);
+}
+
+PHP_PROTO_FIELD_ACCESSORS(UInt32Value, u_int32_value, Value, "value")
+
+// -----------------------------------------------------------------------------
+// UInt64Value
+// -----------------------------------------------------------------------------
+
+static zend_function_entry u_int64_value_methods[] = {
+ PHP_ME(UInt64Value, __construct, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(UInt64Value, getValue, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(UInt64Value, setValue, NULL, ZEND_ACC_PUBLIC)
+ {NULL, NULL, NULL}
+};
+
+zend_class_entry* u_int64_value_type;
+
+// Init class entry.
+PHP_PROTO_INIT_SUBMSGCLASS_START("Google\\Protobuf\\UInt64Value",
+ UInt64Value, u_int64_value)
+ zend_class_implements(u_int64_value_type TSRMLS_CC, 1, message_type);
+ zend_declare_property_null(u_int64_value_type, "value", strlen("value"),
+ ZEND_ACC_PRIVATE TSRMLS_CC);
+PHP_PROTO_INIT_SUBMSGCLASS_END
+
+PHP_METHOD(UInt64Value, __construct) {
+ init_file_wrappers(TSRMLS_C);
+ MessageHeader* intern = UNBOX(MessageHeader, getThis());
+ custom_data_init(u_int64_value_type, intern PHP_PROTO_TSRMLS_CC);
+}
+
+PHP_PROTO_FIELD_ACCESSORS(UInt64Value, u_int64_value, Value, "value")
+
+// -----------------------------------------------------------------------------
+// Value
+// -----------------------------------------------------------------------------
+
+static zend_function_entry value_methods[] = {
+ PHP_ME(Value, __construct, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(Value, getNullValue, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(Value, setNullValue, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(Value, getNumberValue, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(Value, setNumberValue, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(Value, getStringValue, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(Value, setStringValue, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(Value, getBoolValue, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(Value, setBoolValue, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(Value, getStructValue, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(Value, setStructValue, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(Value, getListValue, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(Value, setListValue, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(Value, getKind, NULL, ZEND_ACC_PUBLIC)
+ {NULL, NULL, NULL}
+};
+
+zend_class_entry* value_type;
+
+// Init class entry.
+PHP_PROTO_INIT_SUBMSGCLASS_START("Google\\Protobuf\\Value",
+ Value, value)
+ zend_class_implements(value_type TSRMLS_CC, 1, message_type);
+ zend_declare_property_null(value_type, "kind", strlen("kind"),
+ ZEND_ACC_PRIVATE TSRMLS_CC);
+PHP_PROTO_INIT_SUBMSGCLASS_END
+
+PHP_METHOD(Value, __construct) {
+ init_file_struct(TSRMLS_C);
+ MessageHeader* intern = UNBOX(MessageHeader, getThis());
+ custom_data_init(value_type, intern PHP_PROTO_TSRMLS_CC);
+}
+
+PHP_PROTO_ONEOF_FIELD_ACCESSORS(Value, value, NullValue, "null_value")
+PHP_PROTO_ONEOF_FIELD_ACCESSORS(Value, value, NumberValue, "number_value")
+PHP_PROTO_ONEOF_FIELD_ACCESSORS(Value, value, StringValue, "string_value")
+PHP_PROTO_ONEOF_FIELD_ACCESSORS(Value, value, BoolValue, "bool_value")
+PHP_PROTO_ONEOF_FIELD_ACCESSORS(Value, value, StructValue, "struct_value")
+PHP_PROTO_ONEOF_FIELD_ACCESSORS(Value, value, ListValue, "list_value")
+PHP_PROTO_ONEOF_ACCESSORS(Value, value, Kind, "kind")
diff --git a/php/ext/google/protobuf/protobuf.c b/php/ext/google/protobuf/protobuf.c
index 43b4e584..b67089e0 100644
--- a/php/ext/google/protobuf/protobuf.c
+++ b/php/ext/google/protobuf/protobuf.c
@@ -46,6 +46,9 @@ static HashTable* upb_def_to_php_obj_map;
// Global map from message/enum's php class entry to corresponding wrapper
// Descriptor/EnumDescriptor instances.
static HashTable* ce_to_php_obj_map;
+// Global map from message/enum's proto fully-qualified name to corresponding
+// wrapper Descriptor/EnumDescriptor instances.
+static HashTable* proto_to_php_obj_map;
static HashTable* reserved_names;
// -----------------------------------------------------------------------------
@@ -81,6 +84,22 @@ static void add_to_list(HashTable* t, void* value) {
(void**)&pDest);
}
+static void add_to_strtable(HashTable* t, const char* key, int key_size,
+ void* value) {
+ zval* pDest = NULL;
+ php_proto_zend_hash_update_mem(t, key, key_size, &value, sizeof(void*),
+ (void**)&pDest);
+}
+
+static void* get_from_strtable(const HashTable* t, const char* key, int key_size) {
+ void** value;
+ if (php_proto_zend_hash_find_mem(t, key, key_size, (void**)&value) ==
+ FAILURE) {
+ return NULL;
+ }
+ return *value;
+}
+
void add_def_obj(const void* def, PHP_PROTO_HASHTABLE_VALUE value) {
#if PHP_MAJOR_VERSION < 7
Z_ADDREF_P(value);
@@ -111,6 +130,20 @@ bool class_added(const void* ce) {
return exist_in_table(ce_to_php_obj_map, ce);
}
+void add_proto_obj(const char* proto, PHP_PROTO_HASHTABLE_VALUE value) {
+#if PHP_MAJOR_VERSION < 7
+ Z_ADDREF_P(value);
+#else
+ ++GC_REFCOUNT(value);
+#endif
+ add_to_strtable(proto_to_php_obj_map, proto, strlen(proto), value);
+}
+
+PHP_PROTO_HASHTABLE_VALUE get_proto_obj(const char* proto) {
+ return (PHP_PROTO_HASHTABLE_VALUE)get_from_strtable(proto_to_php_obj_map,
+ proto, strlen(proto));
+}
+
// -----------------------------------------------------------------------------
// Reserved Name.
// -----------------------------------------------------------------------------
@@ -196,6 +229,9 @@ static PHP_RINIT_FUNCTION(protobuf) {
ALLOC_HASHTABLE(ce_to_php_obj_map);
zend_hash_init(ce_to_php_obj_map, 16, NULL, HASHTABLE_VALUE_DTOR, 0);
+ ALLOC_HASHTABLE(proto_to_php_obj_map);
+ zend_hash_init(proto_to_php_obj_map, 16, NULL, HASHTABLE_VALUE_DTOR, 0);
+
ALLOC_HASHTABLE(reserved_names);
zend_hash_init(reserved_names, 16, NULL, NULL, 0);
for (i = 0; i < kReservedNamesSize; i++) {
@@ -217,6 +253,9 @@ static PHP_RSHUTDOWN_FUNCTION(protobuf) {
zend_hash_destroy(ce_to_php_obj_map);
FREE_HASHTABLE(ce_to_php_obj_map);
+ zend_hash_destroy(proto_to_php_obj_map);
+ FREE_HASHTABLE(proto_to_php_obj_map);
+
zend_hash_destroy(reserved_names);
FREE_HASHTABLE(reserved_names);
@@ -261,6 +300,37 @@ static PHP_MINIT_FUNCTION(protobuf) {
repeated_field_iter_init(TSRMLS_C);
util_init(TSRMLS_C);
+ any_init(TSRMLS_C);
+ api_init(TSRMLS_C);
+ bool_value_init(TSRMLS_C);
+ bytes_value_init(TSRMLS_C);
+ double_value_init(TSRMLS_C);
+ duration_init(TSRMLS_C);
+ enum_init(TSRMLS_C);
+ enum_value_init(TSRMLS_C);
+ field_cardinality_init(TSRMLS_C);
+ field_init(TSRMLS_C);
+ field_kind_init(TSRMLS_C);
+ field_mask_init(TSRMLS_C);
+ float_value_init(TSRMLS_C);
+ empty_init(TSRMLS_C);
+ int32_value_init(TSRMLS_C);
+ int64_value_init(TSRMLS_C);
+ list_value_init(TSRMLS_C);
+ method_init(TSRMLS_C);
+ mixin_init(TSRMLS_C);
+ null_value_init(TSRMLS_C);
+ option_init(TSRMLS_C);
+ source_context_init(TSRMLS_C);
+ string_value_init(TSRMLS_C);
+ struct_init(TSRMLS_C);
+ syntax_init(TSRMLS_C);
+ timestamp_init(TSRMLS_C);
+ type_init(TSRMLS_C);
+ u_int32_value_init(TSRMLS_C);
+ u_int64_value_init(TSRMLS_C);
+ value_init(TSRMLS_C);
+
return 0;
}
diff --git a/php/ext/google/protobuf/protobuf.h b/php/ext/google/protobuf/protobuf.h
index 23c51c64..cb098747 100644
--- a/php/ext/google/protobuf/protobuf.h
+++ b/php/ext/google/protobuf/protobuf.h
@@ -77,12 +77,19 @@
#define php_proto_zend_hash_index_update_zval(ht, h, pData) \
zend_hash_index_update(ht, h, &(pData), sizeof(void*), NULL)
+#define php_proto_zend_hash_update_zval(ht, key, key_len, value) \
+ zend_hash_update(ht, key, key_len, value, sizeof(void*), NULL)
+
#define php_proto_zend_hash_update(ht, key, key_len) \
zend_hash_update(ht, key, key_len, 0, 0, NULL)
#define php_proto_zend_hash_index_update_mem(ht, h, pData, nDataSize, pDest) \
zend_hash_index_update(ht, h, pData, nDataSize, pDest)
+#define php_proto_zend_hash_update_mem(ht, key, key_len, pData, nDataSize, \
+ pDest) \
+ zend_hash_update(ht, key, key_len, pData, nDataSize, pDest)
+
#define php_proto_zend_hash_index_find_zval(ht, h, pDest) \
zend_hash_index_find(ht, h, pDest)
@@ -92,6 +99,12 @@
#define php_proto_zend_hash_index_find_mem(ht, h, pDest) \
zend_hash_index_find(ht, h, pDest)
+#define php_proto_zend_hash_find_zval(ht, key, key_len, pDest) \
+ zend_hash_find(ht, key, key_len, pDest)
+
+#define php_proto_zend_hash_find_mem(ht, key, key_len, pDest) \
+ zend_hash_find(ht, key, key_len, pDest)
+
#define php_proto_zend_hash_next_index_insert_zval(ht, pData) \
zend_hash_next_index_insert(ht, pData, sizeof(void*), NULL)
@@ -109,6 +122,27 @@
#define PHP_PROTO_WRAP_OBJECT_END \
};
+#define PHP_PROTO_INIT_SUBMSGCLASS_START(CLASSNAME, CAMELNAME, LOWWERNAME) \
+ void LOWWERNAME##_init(TSRMLS_D) { \
+ zend_class_entry class_type; \
+ const char* class_name = CLASSNAME; \
+ INIT_CLASS_ENTRY_EX(class_type, CLASSNAME, strlen(CLASSNAME), \
+ LOWWERNAME##_methods); \
+ LOWWERNAME##_type = zend_register_internal_class(&class_type TSRMLS_CC); \
+ LOWWERNAME##_type->create_object = message_create;
+#define PHP_PROTO_INIT_SUBMSGCLASS_END \
+ }
+
+#define PHP_PROTO_INIT_ENUMCLASS_START(CLASSNAME, CAMELNAME, LOWWERNAME) \
+ void LOWWERNAME##_init(TSRMLS_D) { \
+ zend_class_entry class_type; \
+ const char* class_name = CLASSNAME; \
+ INIT_CLASS_ENTRY_EX(class_type, CLASSNAME, strlen(CLASSNAME), \
+ LOWWERNAME##_methods); \
+ LOWWERNAME##_type = zend_register_internal_class(&class_type TSRMLS_CC);
+#define PHP_PROTO_INIT_ENUMCLASS_END \
+ }
+
#define PHP_PROTO_INIT_CLASS_START(CLASSNAME, CAMELNAME, LOWWERNAME) \
void LOWWERNAME##_init(TSRMLS_D) { \
zend_class_entry class_type; \
@@ -208,6 +242,8 @@
#define php_proto_zend_lookup_class(name, name_length, ce) \
zend_lookup_class(name, name_length, ce TSRMLS_CC)
+#define PHP_PROTO_RETVAL_ZVAL(value) ZVAL_ZVAL(return_value, value, 1, 0)
+
#else // PHP_MAJOR_VERSION >= 7
#define php_proto_zend_literal void**
@@ -258,6 +294,23 @@ static inline int php_proto_zend_hash_index_update_mem(HashTable* ht, ulong h,
return result != NULL ? SUCCESS : FAILURE;
}
+static inline int php_proto_zend_hash_update_zval(HashTable* ht,
+ const char* key, uint key_len,
+ zval* pData) {
+ zend_string* internal_key = zend_string_init(key, key_len, 0);
+ zend_hash_update(ht, internal_key, pData);
+}
+
+static inline int php_proto_zend_hash_update_mem(HashTable* ht, const char* key,
+ uint key_len, void* pData,
+ uint nDataSize, void** pDest) {
+ zend_string* internal_key = zend_string_init(key, key_len, 0);
+ void* result = zend_hash_update_mem(ht, internal_key, pData, nDataSize);
+ zend_string_release(internal_key);
+ if (pDest != NULL) *pDest = result;
+ return result != NULL ? SUCCESS : FAILURE;
+}
+
static inline int php_proto_zend_hash_index_find_zval(const HashTable* ht,
ulong h, void** pDest) {
zval* result = zend_hash_index_find(ht, h);
@@ -280,6 +333,25 @@ static inline int php_proto_zend_hash_index_find_mem(const HashTable* ht,
return result != NULL ? SUCCESS : FAILURE;
}
+static inline int php_proto_zend_hash_find_zval(const HashTable* ht,
+ const char* key, uint key_len,
+ void** pDest) {
+ zend_string* internal_key = zend_string_init(key, key_len, 1);
+ zval* result = zend_hash_find(ht, internal_key);
+ if (pDest != NULL) *pDest = result;
+ return result != NULL ? SUCCESS : FAILURE;
+}
+
+static inline int php_proto_zend_hash_find_mem(const HashTable* ht,
+ const char* key, uint key_len,
+ void** pDest) {
+ zend_string* internal_key = zend_string_init(key, key_len, 1);
+ void* result = zend_hash_find_ptr(ht, internal_key);
+ zend_string_release(internal_key);
+ if (pDest != NULL) *pDest = result;
+ return result != NULL ? SUCCESS : FAILURE;
+}
+
static inline int php_proto_zend_hash_next_index_insert_zval(HashTable* ht,
void* pData) {
zval tmp;
@@ -314,6 +386,27 @@ static inline int php_proto_zend_hash_get_current_data_ex(HashTable* ht,
zend_object std; \
};
+#define PHP_PROTO_INIT_SUBMSGCLASS_START(CLASSNAME, CAMELNAME, LOWWERNAME) \
+ void LOWWERNAME##_init(TSRMLS_D) { \
+ zend_class_entry class_type; \
+ const char* class_name = CLASSNAME; \
+ INIT_CLASS_ENTRY_EX(class_type, CLASSNAME, strlen(CLASSNAME), \
+ LOWWERNAME##_methods); \
+ LOWWERNAME##_type = zend_register_internal_class(&class_type TSRMLS_CC); \
+ LOWWERNAME##_type->create_object = message_create;
+#define PHP_PROTO_INIT_SUBMSGCLASS_END \
+ }
+
+#define PHP_PROTO_INIT_ENUMCLASS_START(CLASSNAME, CAMELNAME, LOWWERNAME) \
+ void LOWWERNAME##_init(TSRMLS_D) { \
+ zend_class_entry class_type; \
+ const char* class_name = CLASSNAME; \
+ INIT_CLASS_ENTRY_EX(class_type, CLASSNAME, strlen(CLASSNAME), \
+ LOWWERNAME##_methods); \
+ LOWWERNAME##_type = zend_register_internal_class(&class_type TSRMLS_CC);
+#define PHP_PROTO_INIT_ENUMCLASS_END \
+ }
+
#define PHP_PROTO_INIT_CLASS_START(CLASSNAME, CAMELNAME, LOWWERNAME) \
void LOWWERNAME##_init(TSRMLS_D) { \
zend_class_entry class_type; \
@@ -412,41 +505,162 @@ static inline int php_proto_zend_lookup_class(
return *ce != NULL ? SUCCESS : FAILURE;
}
+#define PHP_PROTO_RETVAL_ZVAL(value) ZVAL_COPY(return_value, value)
+
#endif // PHP_MAJOR_VERSION >= 7
+#if PHP_MAJOR_VERSION < 7 || (PHP_MAJOR_VERSION == 7 && PHP_MINOR_VERSION == 0)
+#define PHP_PROTO_FAKE_SCOPE_BEGIN(klass) \
+ zend_class_entry* old_scope = EG(scope); \
+ EG(scope) = klass;
+#define PHP_PROTO_FAKE_SCOPE_RESTART(klass) \
+ old_scope = EG(scope); \
+ EG(scope) = klass;
+#define PHP_PROTO_FAKE_SCOPE_END EG(scope) = old_scope;
+#else
+#define PHP_PROTO_FAKE_SCOPE_BEGIN(klass) \
+ zend_class_entry* old_scope = EG(fake_scope); \
+ EG(fake_scope) = klass;
+#define PHP_PROTO_FAKE_SCOPE_RESTART(klass) \
+ old_scope = EG(fake_scope); \
+ EG(fake_scope) = klass;
+#define PHP_PROTO_FAKE_SCOPE_END EG(fake_scope) = old_scope;
+#endif
+
+// Define PHP class
+#define DEFINE_PROTOBUF_INIT_CLASS(CLASSNAME, CAMELNAME, LOWERNAME) \
+ PHP_PROTO_INIT_CLASS_START(CLASSNAME, CAMELNAME, LOWERNAME) \
+ PHP_PROTO_INIT_CLASS_END
+
+#define DEFINE_PROTOBUF_CREATE(NAME, LOWERNAME) \
+ PHP_PROTO_OBJECT_CREATE_START(NAME, LOWERNAME) \
+ LOWERNAME##_init_c_instance(intern TSRMLS_CC); \
+ PHP_PROTO_OBJECT_CREATE_END(NAME, LOWERNAME)
+
+#define DEFINE_PROTOBUF_FREE(CAMELNAME, LOWERNAME) \
+ PHP_PROTO_OBJECT_FREE_START(CAMELNAME, LOWERNAME) \
+ LOWERNAME##_free_c(intern TSRMLS_CC); \
+ PHP_PROTO_OBJECT_FREE_END
+
+#define DEFINE_PROTOBUF_DTOR(CAMELNAME, LOWERNAME) \
+ PHP_PROTO_OBJECT_DTOR_START(CAMELNAME, LOWERNAME) \
+ PHP_PROTO_OBJECT_DTOR_END
+
+#define DEFINE_CLASS(NAME, LOWERNAME, string_name) \
+ zend_class_entry *LOWERNAME##_type; \
+ zend_object_handlers *LOWERNAME##_handlers; \
+ DEFINE_PROTOBUF_FREE(NAME, LOWERNAME) \
+ DEFINE_PROTOBUF_DTOR(NAME, LOWERNAME) \
+ DEFINE_PROTOBUF_CREATE(NAME, LOWERNAME) \
+ DEFINE_PROTOBUF_INIT_CLASS(string_name, NAME, LOWERNAME)
+
// -----------------------------------------------------------------------------
// Forward Declaration
// ----------------------------------------------------------------------------
-struct DescriptorPool;
+struct Any;
+struct Api;
+struct BoolValue;
+struct BytesValue;
struct Descriptor;
+struct DescriptorPool;
+struct DoubleValue;
+struct Duration;
+struct Enum;
struct EnumDescriptor;
+struct EnumValue;
struct EnumValueDescriptor;
+struct Field;
struct FieldDescriptor;
+struct FieldMask;
+struct Field_Cardinality;
+struct Field_Kind;
+struct FloatValue;
+struct GPBEmpty;
+struct Int32Value;
+struct Int64Value;
struct InternalDescriptorPool;
+struct ListValue;
+struct Map;
+struct MapIter;
struct MessageField;
struct MessageHeader;
struct MessageLayout;
+struct Method;
+struct Mixin;
+struct NullValue;
+struct Oneof;
+struct Option;
struct RepeatedField;
struct RepeatedFieldIter;
-struct Map;
-struct MapIter;
-struct Oneof;
-
-typedef struct DescriptorPool DescriptorPool;
+struct SourceContext;
+struct StringValue;
+struct Struct;
+struct Syntax;
+struct Timestamp;
+struct Type;
+struct UInt32Value;
+struct UInt64Value;
+struct Value;
+
+typedef struct Any Any;
+typedef struct Api Api;
+typedef struct BoolValue BoolValue;
+typedef struct BytesValue BytesValue;
typedef struct Descriptor Descriptor;
+typedef struct Descriptor Descriptor;
+typedef struct DescriptorPool DescriptorPool;
+typedef struct DescriptorPool DescriptorPool;
+typedef struct DoubleValue DoubleValue;
+typedef struct Duration Duration;
+typedef struct Enum Enum;
+typedef struct EnumDescriptor EnumDescriptor;
typedef struct EnumDescriptor EnumDescriptor;
+typedef struct EnumValue EnumValue;
typedef struct EnumValueDescriptor EnumValueDescriptor;
+typedef struct EnumValueDescriptor EnumValueDescriptor;
+typedef struct Field Field;
+typedef struct FieldDescriptor FieldDescriptor;
typedef struct FieldDescriptor FieldDescriptor;
+typedef struct FieldMask FieldMask;
+typedef struct Field_Cardinality Field_Cardinality;
+typedef struct Field_Kind Field_Kind;
+typedef struct FloatValue FloatValue;
+typedef struct GPBEmpty GPBEmpty;
+typedef struct Int32Value Int32Value;
+typedef struct Int64Value Int64Value;
+typedef struct InternalDescriptorPool InternalDescriptorPool;
typedef struct InternalDescriptorPool InternalDescriptorPool;
+typedef struct ListValue ListValue;
+typedef struct Map Map;
+typedef struct Map Map;
+typedef struct MapIter MapIter;
+typedef struct MapIter MapIter;
+typedef struct MessageField MessageField;
typedef struct MessageField MessageField;
typedef struct MessageHeader MessageHeader;
+typedef struct MessageHeader MessageHeader;
typedef struct MessageLayout MessageLayout;
+typedef struct MessageLayout MessageLayout;
+typedef struct Method Method;
+typedef struct Mixin Mixin;
+typedef struct NullValue NullValue;
+typedef struct Oneof Oneof;
+typedef struct Oneof Oneof;
+typedef struct Option Option;
+typedef struct RepeatedField RepeatedField;
typedef struct RepeatedField RepeatedField;
typedef struct RepeatedFieldIter RepeatedFieldIter;
-typedef struct Map Map;
-typedef struct MapIter MapIter;
-typedef struct Oneof Oneof;
+typedef struct RepeatedFieldIter RepeatedFieldIter;
+typedef struct SourceContext SourceContext;
+typedef struct StringValue StringValue;
+typedef struct Struct Struct;
+typedef struct Syntax Syntax;
+typedef struct Timestamp Timestamp;
+typedef struct Type Type;
+typedef struct UInt32Value UInt32Value;
+typedef struct UInt64Value UInt64Value;
+typedef struct Value Value;
// -----------------------------------------------------------------------------
// Globals.
@@ -456,19 +670,49 @@ ZEND_BEGIN_MODULE_GLOBALS(protobuf)
ZEND_END_MODULE_GLOBALS(protobuf)
// Init module and PHP classes.
+void any_init(TSRMLS_D);
+void api_init(TSRMLS_D);
+void bool_value_init(TSRMLS_D);
+void bytes_value_init(TSRMLS_D);
void descriptor_init(TSRMLS_D);
-void enum_descriptor_init(TSRMLS_D);
void descriptor_pool_init(TSRMLS_D);
-void internal_descriptor_pool_init(TSRMLS_D);
+void double_value_init(TSRMLS_D);
+void duration_init(TSRMLS_D);
+void empty_init(TSRMLS_D);
+void enum_descriptor_init(TSRMLS_D);
+void enum_init(TSRMLS_D);
+void enum_value_init(TSRMLS_D);
+void field_cardinality_init(TSRMLS_D);
void field_descriptor_init(TSRMLS_D);
+void field_init(TSRMLS_D);
+void field_kind_init(TSRMLS_D);
+void field_mask_init(TSRMLS_D);
+void float_value_init(TSRMLS_D);
void gpb_type_init(TSRMLS_D);
+void int32_value_init(TSRMLS_D);
+void int64_value_init(TSRMLS_D);
+void internal_descriptor_pool_init(TSRMLS_D);
+void list_value_init(TSRMLS_D);
void map_field_init(TSRMLS_D);
void map_field_iter_init(TSRMLS_D);
+void message_init(TSRMLS_D);
+void method_init(TSRMLS_D);
+void mixin_init(TSRMLS_D);
+void null_value_init(TSRMLS_D);
void oneof_descriptor_init(TSRMLS_D);
+void option_init(TSRMLS_D);
void repeated_field_init(TSRMLS_D);
void repeated_field_iter_init(TSRMLS_D);
+void source_context_init(TSRMLS_D);
+void string_value_init(TSRMLS_D);
+void struct_init(TSRMLS_D);
+void syntax_init(TSRMLS_D);
+void timestamp_init(TSRMLS_D);
+void type_init(TSRMLS_D);
+void uint32_value_init(TSRMLS_D);
+void uint64_value_init(TSRMLS_D);
void util_init(TSRMLS_D);
-void message_init(TSRMLS_D);
+void value_init(TSRMLS_D);
// Global map from upb {msg,enum}defs to wrapper Descriptor/EnumDescriptor
// instances.
@@ -481,6 +725,11 @@ void add_ce_obj(const void* ce, PHP_PROTO_HASHTABLE_VALUE value);
PHP_PROTO_HASHTABLE_VALUE get_ce_obj(const void* ce);
bool class_added(const void* ce);
+// Global map from message/enum's proto fully-qualified name to corresponding
+// wrapper Descriptor/EnumDescriptor instances.
+void add_proto_obj(const char* proto, PHP_PROTO_HASHTABLE_VALUE value);
+PHP_PROTO_HASHTABLE_VALUE get_proto_obj(const char* proto);
+
extern zend_class_entry* map_field_type;
extern zend_class_entry* repeated_field_type;
@@ -504,6 +753,10 @@ PHP_PROTO_WRAP_OBJECT_END
PHP_METHOD(InternalDescriptorPool, getGeneratedPool);
PHP_METHOD(InternalDescriptorPool, internalAddGeneratedFile);
+void internal_add_generated_file(const char* data, PHP_PROTO_SIZE data_len,
+ InternalDescriptorPool* pool TSRMLS_DC);
+void init_generated_pool_once(TSRMLS_D);
+
// wrapper of generated pool
#if PHP_MAJOR_VERSION < 7
extern zval* generated_pool_php;
@@ -589,6 +842,7 @@ void custom_data_init(const zend_class_entry* ce,
void build_class_from_descriptor(
PHP_PROTO_HASHTABLE_VALUE php_descriptor TSRMLS_DC);
+extern zend_class_entry* message_type;
extern zend_object_handlers* message_handlers;
// -----------------------------------------------------------------------------
@@ -676,6 +930,8 @@ void layout_merge(MessageLayout* layout, MessageHeader* from,
const char* layout_get_oneof_case(MessageLayout* layout, const void* storage,
const upb_oneofdef* oneof TSRMLS_DC);
void free_layout(MessageLayout* layout);
+void* slot_memory(MessageLayout* layout, const void* storage,
+ const upb_fielddef* field);
PHP_METHOD(Message, clear);
PHP_METHOD(Message, mergeFrom);
@@ -696,6 +952,9 @@ PHP_METHOD(Message, __construct);
// This is called from the message class creation code.
const upb_pbdecodermethod *new_fillmsg_decodermethod(Descriptor *desc,
const void *owner);
+void serialize_to_string(zval* val, zval* return_value TSRMLS_DC);
+void merge_from_string(const char* data, int data_len, const Descriptor* desc,
+ MessageHeader* msg);
PHP_METHOD(Message, serializeToString);
PHP_METHOD(Message, mergeFromString);
@@ -715,6 +974,11 @@ bool protobuf_convert_to_double(zval* from, double* to);
bool protobuf_convert_to_bool(zval* from, int8_t* to);
bool protobuf_convert_to_string(zval* from);
+void check_repeated_field(const zend_class_entry* klass, PHP_PROTO_LONG type,
+ zval* val, zval* return_value);
+void check_map_field(const zend_class_entry* klass, PHP_PROTO_LONG key_type,
+ PHP_PROTO_LONG value_type, zval* val, zval* return_value);
+
PHP_METHOD(Util, checkInt32);
PHP_METHOD(Util, checkUint32);
PHP_METHOD(Util, checkInt64);
@@ -903,6 +1167,233 @@ extern zend_class_entry* oneof_descriptor_type;
#define ONEOF_CASE_NONE 0
// -----------------------------------------------------------------------------
+// Well Known Type.
+// -----------------------------------------------------------------------------
+
+PHP_METHOD(Any, __construct);
+PHP_METHOD(Any, getTypeUrl);
+PHP_METHOD(Any, setTypeUrl);
+PHP_METHOD(Any, getValue);
+PHP_METHOD(Any, setValue);
+PHP_METHOD(Any, unpack);
+PHP_METHOD(Any, pack);
+PHP_METHOD(Any, is);
+
+PHP_METHOD(Duration, __construct);
+PHP_METHOD(Duration, getSeconds);
+PHP_METHOD(Duration, setSeconds);
+PHP_METHOD(Duration, getNanos);
+PHP_METHOD(Duration, setNanos);
+
+PHP_METHOD(Timestamp, __construct);
+PHP_METHOD(Timestamp, fromDateTime);
+PHP_METHOD(Timestamp, toDateTime);
+PHP_METHOD(Timestamp, getSeconds);
+PHP_METHOD(Timestamp, setSeconds);
+PHP_METHOD(Timestamp, getNanos);
+PHP_METHOD(Timestamp, setNanos);
+
+PHP_METHOD(Api, __construct);
+PHP_METHOD(Api, getName);
+PHP_METHOD(Api, setName);
+PHP_METHOD(Api, getMethods);
+PHP_METHOD(Api, setMethods);
+PHP_METHOD(Api, getOptions);
+PHP_METHOD(Api, setOptions);
+PHP_METHOD(Api, getVersion);
+PHP_METHOD(Api, setVersion);
+PHP_METHOD(Api, getSourceContext);
+PHP_METHOD(Api, setSourceContext);
+PHP_METHOD(Api, getMixins);
+PHP_METHOD(Api, setMixins);
+PHP_METHOD(Api, getSyntax);
+PHP_METHOD(Api, setSyntax);
+
+PHP_METHOD(BoolValue, __construct);
+PHP_METHOD(BoolValue, getValue);
+PHP_METHOD(BoolValue, setValue);
+
+PHP_METHOD(BytesValue, __construct);
+PHP_METHOD(BytesValue, getValue);
+PHP_METHOD(BytesValue, setValue);
+
+PHP_METHOD(DoubleValue, __construct);
+PHP_METHOD(DoubleValue, getValue);
+PHP_METHOD(DoubleValue, setValue);
+
+PHP_METHOD(Enum, __construct);
+PHP_METHOD(Enum, getName);
+PHP_METHOD(Enum, setName);
+PHP_METHOD(Enum, getEnumvalue);
+PHP_METHOD(Enum, setEnumvalue);
+PHP_METHOD(Enum, getOptions);
+PHP_METHOD(Enum, setOptions);
+PHP_METHOD(Enum, getSourceContext);
+PHP_METHOD(Enum, setSourceContext);
+PHP_METHOD(Enum, getSyntax);
+PHP_METHOD(Enum, setSyntax);
+
+PHP_METHOD(EnumValue, __construct);
+PHP_METHOD(EnumValue, getName);
+PHP_METHOD(EnumValue, setName);
+PHP_METHOD(EnumValue, getNumber);
+PHP_METHOD(EnumValue, setNumber);
+PHP_METHOD(EnumValue, getOptions);
+PHP_METHOD(EnumValue, setOptions);
+
+PHP_METHOD(FieldMask, __construct);
+PHP_METHOD(FieldMask, getPaths);
+PHP_METHOD(FieldMask, setPaths);
+
+PHP_METHOD(Field, __construct);
+PHP_METHOD(Field, getKind);
+PHP_METHOD(Field, setKind);
+PHP_METHOD(Field, getCardinality);
+PHP_METHOD(Field, setCardinality);
+PHP_METHOD(Field, getNumber);
+PHP_METHOD(Field, setNumber);
+PHP_METHOD(Field, getName);
+PHP_METHOD(Field, setName);
+PHP_METHOD(Field, getTypeUrl);
+PHP_METHOD(Field, setTypeUrl);
+PHP_METHOD(Field, getOneofIndex);
+PHP_METHOD(Field, setOneofIndex);
+PHP_METHOD(Field, getPacked);
+PHP_METHOD(Field, setPacked);
+PHP_METHOD(Field, getOptions);
+PHP_METHOD(Field, setOptions);
+PHP_METHOD(Field, getJsonName);
+PHP_METHOD(Field, setJsonName);
+PHP_METHOD(Field, getDefaultValue);
+PHP_METHOD(Field, setDefaultValue);
+
+PHP_METHOD(FloatValue, __construct);
+PHP_METHOD(FloatValue, getValue);
+PHP_METHOD(FloatValue, setValue);
+
+PHP_METHOD(GPBEmpty, __construct);
+
+PHP_METHOD(Int32Value, __construct);
+PHP_METHOD(Int32Value, getValue);
+PHP_METHOD(Int32Value, setValue);
+
+PHP_METHOD(Int64Value, __construct);
+PHP_METHOD(Int64Value, getValue);
+PHP_METHOD(Int64Value, setValue);
+
+PHP_METHOD(ListValue, __construct);
+PHP_METHOD(ListValue, getValues);
+PHP_METHOD(ListValue, setValues);
+
+PHP_METHOD(Method, __construct);
+PHP_METHOD(Method, getName);
+PHP_METHOD(Method, setName);
+PHP_METHOD(Method, getRequestTypeUrl);
+PHP_METHOD(Method, setRequestTypeUrl);
+PHP_METHOD(Method, getRequestStreaming);
+PHP_METHOD(Method, setRequestStreaming);
+PHP_METHOD(Method, getResponseTypeUrl);
+PHP_METHOD(Method, setResponseTypeUrl);
+PHP_METHOD(Method, getResponseStreaming);
+PHP_METHOD(Method, setResponseStreaming);
+PHP_METHOD(Method, getOptions);
+PHP_METHOD(Method, setOptions);
+PHP_METHOD(Method, getSyntax);
+PHP_METHOD(Method, setSyntax);
+
+PHP_METHOD(Mixin, __construct);
+PHP_METHOD(Mixin, getName);
+PHP_METHOD(Mixin, setName);
+PHP_METHOD(Mixin, getRoot);
+PHP_METHOD(Mixin, setRoot);
+
+PHP_METHOD(Option, __construct);
+PHP_METHOD(Option, getName);
+PHP_METHOD(Option, setName);
+PHP_METHOD(Option, getValue);
+PHP_METHOD(Option, setValue);
+
+PHP_METHOD(SourceContext, __construct);
+PHP_METHOD(SourceContext, getFileName);
+PHP_METHOD(SourceContext, setFileName);
+
+PHP_METHOD(StringValue, __construct);
+PHP_METHOD(StringValue, getValue);
+PHP_METHOD(StringValue, setValue);
+
+PHP_METHOD(Struct, __construct);
+PHP_METHOD(Struct, getFields);
+PHP_METHOD(Struct, setFields);
+
+PHP_METHOD(Type, __construct);
+PHP_METHOD(Type, getName);
+PHP_METHOD(Type, setName);
+PHP_METHOD(Type, getFields);
+PHP_METHOD(Type, setFields);
+PHP_METHOD(Type, getOneofs);
+PHP_METHOD(Type, setOneofs);
+PHP_METHOD(Type, getOptions);
+PHP_METHOD(Type, setOptions);
+PHP_METHOD(Type, getSourceContext);
+PHP_METHOD(Type, setSourceContext);
+PHP_METHOD(Type, getSyntax);
+PHP_METHOD(Type, setSyntax);
+
+PHP_METHOD(UInt32Value, __construct);
+PHP_METHOD(UInt32Value, getValue);
+PHP_METHOD(UInt32Value, setValue);
+
+PHP_METHOD(UInt64Value, __construct);
+PHP_METHOD(UInt64Value, getValue);
+PHP_METHOD(UInt64Value, setValue);
+
+PHP_METHOD(Value, __construct);
+PHP_METHOD(Value, getNullValue);
+PHP_METHOD(Value, setNullValue);
+PHP_METHOD(Value, getNumberValue);
+PHP_METHOD(Value, setNumberValue);
+PHP_METHOD(Value, getStringValue);
+PHP_METHOD(Value, setStringValue);
+PHP_METHOD(Value, getBoolValue);
+PHP_METHOD(Value, setBoolValue);
+PHP_METHOD(Value, getStructValue);
+PHP_METHOD(Value, setStructValue);
+PHP_METHOD(Value, getListValue);
+PHP_METHOD(Value, setListValue);
+PHP_METHOD(Value, getKind);
+
+extern zend_class_entry* any_type;
+extern zend_class_entry* api_type;
+extern zend_class_entry* bool_value_type;
+extern zend_class_entry* bytes_value_type;
+extern zend_class_entry* double_value_type;
+extern zend_class_entry* duration_type;
+extern zend_class_entry* empty_type;
+extern zend_class_entry* enum_type;
+extern zend_class_entry* enum_value_type;
+extern zend_class_entry* field_cardinality_type;
+extern zend_class_entry* field_kind_type;
+extern zend_class_entry* field_mask_type;
+extern zend_class_entry* field_type;
+extern zend_class_entry* float_value_type;
+extern zend_class_entry* int32_value_type;
+extern zend_class_entry* int64_value_type;
+extern zend_class_entry* list_value_type;
+extern zend_class_entry* method_type;
+extern zend_class_entry* mixin_type;
+extern zend_class_entry* null_value_type;
+extern zend_class_entry* option_type;
+extern zend_class_entry* source_context_type;
+extern zend_class_entry* string_value_type;
+extern zend_class_entry* struct_type;
+extern zend_class_entry* syntax_type;
+extern zend_class_entry* timestamp_type;
+extern zend_class_entry* type_type;
+extern zend_class_entry* uint32_value_type;
+extern zend_class_entry* uint64_value_type;
+extern zend_class_entry* value_type;
+
+// -----------------------------------------------------------------------------
// Upb.
// -----------------------------------------------------------------------------
@@ -932,6 +1423,18 @@ const zend_class_entry* field_type_class(
.bucket.obj.object))
#endif
+// Message handler
+static inline zval* php_proto_message_read_property(
+ zval* msg, zval* member PHP_PROTO_TSRMLS_DC) {
+#if PHP_MAJOR_VERSION < 7
+ return message_handlers->read_property(msg, member, BP_VAR_R,
+ NULL PHP_PROTO_TSRMLS_CC);
+#else
+ return message_handlers->read_property(msg, member, BP_VAR_R, NULL,
+ NULL PHP_PROTO_TSRMLS_CC);
+#endif
+}
+
// Reserved name
bool is_reserved_name(const char* name);
bool is_valid_constant_name(const char* name);
diff --git a/php/ext/google/protobuf/storage.c b/php/ext/google/protobuf/storage.c
index 4830e15f..e7910c85 100644
--- a/php/ext/google/protobuf/storage.c
+++ b/php/ext/google/protobuf/storage.c
@@ -560,11 +560,6 @@ static size_t align_up_to(size_t offset, size_t granularity) {
return (offset + granularity - 1) & ~(granularity - 1);
}
-static void* slot_memory(MessageLayout* layout, const void* storage,
- const upb_fielddef* field) {
- return ((uint8_t*)storage) + layout->fields[upb_fielddef_index(field)].offset;
-}
-
static uint32_t* slot_oneof_case(MessageLayout* layout, const void* storage,
const upb_fielddef* field) {
return (uint32_t*)(((uint8_t*)storage) +
@@ -576,6 +571,11 @@ static int slot_property_cache(MessageLayout* layout, const void* storage,
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);
@@ -583,9 +583,12 @@ MessageLayout* create_layout(const upb_msgdef* msgdef) {
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);
@@ -744,6 +747,10 @@ 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);
@@ -856,12 +863,41 @@ void layout_set(MessageLayout* layout, MessageHeader* header,
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, val, 1);
+ REPLACE_ZVAL_VALUE((zval**)memory, &converted_value, 1);
#else
- php_proto_zval_ptr_dtor(property_ptr);
- ZVAL_ZVAL(property_ptr, val, 1, 0);
+ 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);
diff --git a/php/ext/google/protobuf/type_check.c b/php/ext/google/protobuf/type_check.c
index fada8d6a..f588774c 100644
--- a/php/ext/google/protobuf/type_check.c
+++ b/php/ext/google/protobuf/type_check.c
@@ -428,21 +428,15 @@ PHP_METHOD(Util, checkMessage) {
RETURN_ZVAL(val, 1, 0);
}
-PHP_METHOD(Util, checkRepeatedField) {
- zval* val;
- PHP_PROTO_LONG type;
- const zend_class_entry* klass = NULL;
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zl|C", &val, &type,
- &klass) == FAILURE) {
- return;
- }
-
+void check_repeated_field(const zend_class_entry* klass, PHP_PROTO_LONG type,
+ zval* val, zval* return_value) {
#if PHP_MAJOR_VERSION >= 7
if (Z_ISREF_P(val)) {
ZVAL_DEREF(val);
}
#endif
+ TSRMLS_FETCH();
if (Z_TYPE_P(val) == IS_ARRAY) {
HashTable* table = HASH_OF(val);
HashPosition pointer;
@@ -492,24 +486,28 @@ PHP_METHOD(Util, checkRepeatedField) {
zend_error(E_USER_ERROR, "Incorrect repeated field type.");
return;
}
-
}
-PHP_METHOD(Util, checkMapField) {
+PHP_METHOD(Util, checkRepeatedField) {
zval* val;
- PHP_PROTO_LONG key_type, value_type;
+ PHP_PROTO_LONG type;
const zend_class_entry* klass = NULL;
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zll|C", &val, &key_type,
- &value_type, &klass) == FAILURE) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zl|C", &val, &type,
+ &klass) == FAILURE) {
return;
}
+ RETURN_ZVAL(val, 1, 0);
+}
+void check_map_field(const zend_class_entry* klass, PHP_PROTO_LONG key_type,
+ PHP_PROTO_LONG value_type, zval* val, zval* return_value) {
#if PHP_MAJOR_VERSION >= 7
if (Z_ISREF_P(val)) {
ZVAL_DEREF(val);
}
#endif
+ TSRMLS_FETCH();
if (Z_TYPE_P(val) == IS_ARRAY) {
HashTable* table = Z_ARRVAL_P(val);
HashPosition pointer;
@@ -565,3 +563,14 @@ PHP_METHOD(Util, checkMapField) {
return;
}
}
+
+PHP_METHOD(Util, checkMapField) {
+ zval* val;
+ PHP_PROTO_LONG key_type, value_type;
+ const zend_class_entry* klass = NULL;
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zll|C", &val, &key_type,
+ &value_type, &klass) == FAILURE) {
+ return;
+ }
+ RETURN_ZVAL(val, 1, 0);
+}
diff --git a/php/ext/google/protobuf/upb.c b/php/ext/google/protobuf/upb.c
index d701dcba..c02a5ce4 100644
--- a/php/ext/google/protobuf/upb.c
+++ b/php/ext/google/protobuf/upb.c
@@ -2,6 +2,585 @@
#include "upb.h"
+/* Maps descriptor type -> upb field type. */
+static const uint8_t upb_desctype_to_fieldtype[] = {
+ UPB_WIRE_TYPE_END_GROUP, /* ENDGROUP */
+ UPB_TYPE_DOUBLE, /* DOUBLE */
+ UPB_TYPE_FLOAT, /* FLOAT */
+ UPB_TYPE_INT64, /* INT64 */
+ UPB_TYPE_UINT64, /* UINT64 */
+ UPB_TYPE_INT32, /* INT32 */
+ UPB_TYPE_UINT64, /* FIXED64 */
+ UPB_TYPE_UINT32, /* FIXED32 */
+ UPB_TYPE_BOOL, /* BOOL */
+ UPB_TYPE_STRING, /* STRING */
+ UPB_TYPE_MESSAGE, /* GROUP */
+ UPB_TYPE_MESSAGE, /* MESSAGE */
+ UPB_TYPE_BYTES, /* BYTES */
+ UPB_TYPE_UINT32, /* UINT32 */
+ UPB_TYPE_ENUM, /* ENUM */
+ UPB_TYPE_INT32, /* SFIXED32 */
+ UPB_TYPE_INT64, /* SFIXED64 */
+ UPB_TYPE_INT32, /* SINT32 */
+ UPB_TYPE_INT64, /* SINT64 */
+};
+
+/* Data pertaining to the parse. */
+typedef struct {
+ upb_env *env;
+ /* Current decoding pointer. Points to the beginning of a field until we
+ * have finished decoding the whole field. */
+ const char *ptr;
+} upb_decstate;
+
+/* Data pertaining to a single message frame. */
+typedef struct {
+ const char *limit;
+ int32_t group_number; /* 0 if we are not parsing a group. */
+
+ /* These members are unset for an unknown group frame. */
+ char *msg;
+ const upb_msglayout_msginit_v1 *m;
+} upb_decframe;
+
+#define CHK(x) if (!(x)) { return false; }
+
+static bool upb_skip_unknowngroup(upb_decstate *d, int field_number,
+ const char *limit);
+static bool upb_decode_message(upb_decstate *d, const char *limit,
+ int group_number, char *msg,
+ const upb_msglayout_msginit_v1 *l);
+
+static bool upb_decode_varint(const char **ptr, const char *limit,
+ uint64_t *val) {
+ uint8_t byte;
+ int bitpos = 0;
+ const char *p = *ptr;
+ *val = 0;
+
+ do {
+ CHK(bitpos < 70 && p < limit);
+ byte = *p;
+ *val |= (uint64_t)(byte & 0x7F) << bitpos;
+ p++;
+ bitpos += 7;
+ } while (byte & 0x80);
+
+ *ptr = p;
+ return true;
+}
+
+static bool upb_decode_varint32(const char **ptr, const char *limit,
+ uint32_t *val) {
+ uint64_t u64;
+ CHK(upb_decode_varint(ptr, limit, &u64) && u64 <= UINT32_MAX);
+ *val = u64;
+ return true;
+}
+
+static bool upb_decode_64bit(const char **ptr, const char *limit,
+ uint64_t *val) {
+ CHK(limit - *ptr >= 8);
+ memcpy(val, *ptr, 8);
+ *ptr += 8;
+ return true;
+}
+
+static bool upb_decode_32bit(const char **ptr, const char *limit,
+ uint32_t *val) {
+ CHK(limit - *ptr >= 4);
+ memcpy(val, *ptr, 4);
+ *ptr += 4;
+ return true;
+}
+
+static bool upb_decode_tag(const char **ptr, const char *limit,
+ int *field_number, int *wire_type) {
+ uint32_t tag = 0;
+ CHK(upb_decode_varint32(ptr, limit, &tag));
+ *field_number = tag >> 3;
+ *wire_type = tag & 7;
+ return true;
+}
+
+static int32_t upb_zzdecode_32(uint32_t n) {
+ return (n >> 1) ^ -(int32_t)(n & 1);
+}
+
+static int64_t upb_zzdecode_64(uint64_t n) {
+ return (n >> 1) ^ -(int64_t)(n & 1);
+}
+
+static bool upb_decode_string(const char **ptr, const char *limit,
+ upb_stringview *val) {
+ uint32_t len;
+
+ CHK(upb_decode_varint32(ptr, limit, &len) &&
+ len < INT32_MAX &&
+ limit - *ptr >= (int32_t)len);
+
+ *val = upb_stringview_make(*ptr, len);
+ *ptr += len;
+ return true;
+}
+
+static void upb_set32(void *msg, size_t ofs, uint32_t val) {
+ memcpy((char*)msg + ofs, &val, sizeof(val));
+}
+
+static bool upb_append_unknown(upb_decstate *d, upb_decframe *frame,
+ const char *start) {
+ UPB_UNUSED(d);
+ UPB_UNUSED(frame);
+ UPB_UNUSED(start);
+ return true;
+}
+
+static bool upb_skip_unknownfielddata(upb_decstate *d, upb_decframe *frame,
+ int field_number, int wire_type) {
+ switch (wire_type) {
+ case UPB_WIRE_TYPE_VARINT: {
+ uint64_t val;
+ return upb_decode_varint(&d->ptr, frame->limit, &val);
+ }
+ case UPB_WIRE_TYPE_32BIT: {
+ uint32_t val;
+ return upb_decode_32bit(&d->ptr, frame->limit, &val);
+ }
+ case UPB_WIRE_TYPE_64BIT: {
+ uint64_t val;
+ return upb_decode_64bit(&d->ptr, frame->limit, &val);
+ }
+ case UPB_WIRE_TYPE_DELIMITED: {
+ upb_stringview val;
+ return upb_decode_string(&d->ptr, frame->limit, &val);
+ }
+ case UPB_WIRE_TYPE_START_GROUP:
+ return upb_skip_unknowngroup(d, field_number, frame->limit);
+ case UPB_WIRE_TYPE_END_GROUP:
+ CHK(field_number == frame->group_number);
+ frame->limit = d->ptr;
+ return true;
+ }
+ return false;
+}
+
+static bool upb_array_grow(upb_array *arr, size_t elements) {
+ size_t needed = arr->len + elements;
+ size_t new_size = UPB_MAX(arr->size, 8);
+ size_t new_bytes;
+ size_t old_bytes;
+ void *new_data;
+
+ while (new_size < needed) {
+ new_size *= 2;
+ }
+
+ old_bytes = arr->len * arr->element_size;
+ new_bytes = new_size * arr->element_size;
+ new_data = upb_realloc(arr->alloc, arr->data, old_bytes, new_bytes);
+ CHK(new_data);
+
+ arr->data = new_data;
+ arr->size = new_size;
+ return true;
+}
+
+static void *upb_array_reserve(upb_array *arr, size_t elements) {
+ if (arr->size - arr->len < elements) {
+ CHK(upb_array_grow(arr, elements));
+ }
+ return (char*)arr->data + (arr->len * arr->element_size);
+}
+
+static void *upb_array_add(upb_array *arr, size_t elements) {
+ void *ret = upb_array_reserve(arr, elements);
+ arr->len += elements;
+ return ret;
+}
+
+static upb_array *upb_getarr(upb_decframe *frame,
+ const upb_msglayout_fieldinit_v1 *field) {
+ UPB_ASSERT(field->label == UPB_LABEL_REPEATED);
+ return *(upb_array**)&frame->msg[field->offset];
+}
+
+static upb_array *upb_getorcreatearr(upb_decstate *d,
+ upb_decframe *frame,
+ const upb_msglayout_fieldinit_v1 *field) {
+ upb_array *arr = upb_getarr(frame, field);
+
+ if (!arr) {
+ arr = upb_env_malloc(d->env, sizeof(*arr));
+ if (!arr) {
+ return NULL;
+ }
+ upb_array_init(arr, upb_desctype_to_fieldtype[field->type],
+ upb_arena_alloc(upb_env_arena(d->env)));
+ *(upb_array**)&frame->msg[field->offset] = arr;
+ }
+
+ return arr;
+}
+
+static void upb_sethasbit(upb_decframe *frame,
+ const upb_msglayout_fieldinit_v1 *field) {
+ UPB_ASSERT(field->hasbit != UPB_NO_HASBIT);
+ frame->msg[field->hasbit / 8] |= (1 << (field->hasbit % 8));
+}
+
+static void upb_setoneofcase(upb_decframe *frame,
+ const upb_msglayout_fieldinit_v1 *field) {
+ UPB_ASSERT(field->oneof_index != UPB_NOT_IN_ONEOF);
+ upb_set32(frame->msg, frame->m->oneofs[field->oneof_index].case_offset,
+ field->number);
+}
+
+static char *upb_decode_prepareslot(upb_decstate *d,
+ upb_decframe *frame,
+ const upb_msglayout_fieldinit_v1 *field) {
+ char *field_mem = frame->msg + field->offset;
+ upb_array *arr;
+
+ if (field->label == UPB_LABEL_REPEATED) {
+ arr = upb_getorcreatearr(d, frame, field);
+ field_mem = upb_array_reserve(arr, 1);
+ }
+
+ return field_mem;
+}
+
+static void upb_decode_setpresent(upb_decframe *frame,
+ const upb_msglayout_fieldinit_v1 *field) {
+ if (field->label == UPB_LABEL_REPEATED) {
+ upb_array *arr = upb_getarr(frame, field);
+ UPB_ASSERT(arr->len < arr->size);
+ arr->len++;
+ } else if (field->oneof_index != UPB_NOT_IN_ONEOF) {
+ upb_setoneofcase(frame, field);
+ } else if (field->hasbit != UPB_NO_HASBIT) {
+ upb_sethasbit(frame, field);
+ }
+}
+
+static bool upb_decode_submsg(upb_decstate *d,
+ upb_decframe *frame,
+ const char *limit,
+ const upb_msglayout_fieldinit_v1 *field,
+ int group_number) {
+ char *submsg = *(void**)&frame->msg[field->offset];
+ const upb_msglayout_msginit_v1 *subm;
+
+ UPB_ASSERT(field->submsg_index != UPB_NO_SUBMSG);
+ subm = frame->m->submsgs[field->submsg_index];
+ UPB_ASSERT(subm);
+
+ if (!submsg) {
+ submsg = upb_env_malloc(d->env, upb_msg_sizeof((upb_msglayout *)subm));
+ CHK(submsg);
+ submsg = upb_msg_init(
+ submsg, (upb_msglayout*)subm, upb_arena_alloc(upb_env_arena(d->env)));
+ *(void**)&frame->msg[field->offset] = submsg;
+ }
+
+ upb_decode_message(d, limit, group_number, submsg, subm);
+
+ return true;
+}
+
+static bool upb_decode_varintfield(upb_decstate *d, upb_decframe *frame,
+ const char *field_start,
+ const upb_msglayout_fieldinit_v1 *field) {
+ uint64_t val;
+ void *field_mem;
+
+ field_mem = upb_decode_prepareslot(d, frame, field);
+ CHK(field_mem);
+ CHK(upb_decode_varint(&d->ptr, frame->limit, &val));
+
+ switch ((upb_descriptortype_t)field->type) {
+ case UPB_DESCRIPTOR_TYPE_INT64:
+ case UPB_DESCRIPTOR_TYPE_UINT64:
+ memcpy(field_mem, &val, sizeof(val));
+ break;
+ case UPB_DESCRIPTOR_TYPE_INT32:
+ case UPB_DESCRIPTOR_TYPE_UINT32:
+ case UPB_DESCRIPTOR_TYPE_ENUM: {
+ uint32_t val32 = val;
+ memcpy(field_mem, &val32, sizeof(val32));
+ break;
+ }
+ case UPB_DESCRIPTOR_TYPE_BOOL: {
+ bool valbool = val != 0;
+ memcpy(field_mem, &valbool, sizeof(valbool));
+ break;
+ }
+ case UPB_DESCRIPTOR_TYPE_SINT32: {
+ int32_t decoded = upb_zzdecode_32(val);
+ memcpy(field_mem, &decoded, sizeof(decoded));
+ break;
+ }
+ case UPB_DESCRIPTOR_TYPE_SINT64: {
+ int64_t decoded = upb_zzdecode_64(val);
+ memcpy(field_mem, &decoded, sizeof(decoded));
+ break;
+ }
+ default:
+ return upb_append_unknown(d, frame, field_start);
+ }
+
+ upb_decode_setpresent(frame, field);
+ return true;
+}
+
+static bool upb_decode_64bitfield(upb_decstate *d, upb_decframe *frame,
+ const char *field_start,
+ const upb_msglayout_fieldinit_v1 *field) {
+ void *field_mem;
+ uint64_t val;
+
+ field_mem = upb_decode_prepareslot(d, frame, field);
+ CHK(field_mem);
+ CHK(upb_decode_64bit(&d->ptr, frame->limit, &val));
+
+ switch ((upb_descriptortype_t)field->type) {
+ case UPB_DESCRIPTOR_TYPE_DOUBLE:
+ case UPB_DESCRIPTOR_TYPE_FIXED64:
+ case UPB_DESCRIPTOR_TYPE_SFIXED64:
+ memcpy(field_mem, &val, sizeof(val));
+ break;
+ default:
+ return upb_append_unknown(d, frame, field_start);
+ }
+
+ upb_decode_setpresent(frame, field);
+ return true;
+}
+
+static bool upb_decode_32bitfield(upb_decstate *d, upb_decframe *frame,
+ const char *field_start,
+ const upb_msglayout_fieldinit_v1 *field) {
+ void *field_mem;
+ uint32_t val;
+
+ field_mem = upb_decode_prepareslot(d, frame, field);
+ CHK(field_mem);
+ CHK(upb_decode_32bit(&d->ptr, frame->limit, &val));
+
+ switch ((upb_descriptortype_t)field->type) {
+ case UPB_DESCRIPTOR_TYPE_FLOAT:
+ case UPB_DESCRIPTOR_TYPE_FIXED32:
+ case UPB_DESCRIPTOR_TYPE_SFIXED32:
+ memcpy(field_mem, &val, sizeof(val));
+ break;
+ default:
+ return upb_append_unknown(d, frame, field_start);
+ }
+
+ upb_decode_setpresent(frame, field);
+ return true;
+}
+
+static bool upb_decode_fixedpacked(upb_array *arr, upb_stringview data,
+ int elem_size) {
+ int elements = data.size / elem_size;
+ void *field_mem;
+
+ CHK((size_t)(elements * elem_size) == data.size);
+ field_mem = upb_array_add(arr, elements);
+ CHK(field_mem);
+ memcpy(field_mem, data.data, data.size);
+ return true;
+}
+
+static bool upb_decode_toarray(upb_decstate *d, upb_decframe *frame,
+ const char *field_start,
+ const upb_msglayout_fieldinit_v1 *field,
+ upb_stringview val) {
+ upb_array *arr = upb_getorcreatearr(d, frame, field);
+
+#define VARINT_CASE(ctype, decode) { \
+ const char *ptr = val.data; \
+ const char *limit = ptr + val.size; \
+ while (ptr < limit) { \
+ uint64_t val; \
+ void *field_mem; \
+ ctype decoded; \
+ CHK(upb_decode_varint(&ptr, limit, &val)); \
+ decoded = (decode)(val); \
+ field_mem = upb_array_add(arr, 1); \
+ CHK(field_mem); \
+ memcpy(field_mem, &decoded, sizeof(ctype)); \
+ } \
+ return true; \
+}
+
+ switch ((upb_descriptortype_t)field->type) {
+ case UPB_DESCRIPTOR_TYPE_STRING:
+ case UPB_DESCRIPTOR_TYPE_BYTES: {
+ void *field_mem = upb_array_add(arr, 1);
+ CHK(field_mem);
+ memcpy(field_mem, &val, sizeof(val));
+ return true;
+ }
+ case UPB_DESCRIPTOR_TYPE_FLOAT:
+ case UPB_DESCRIPTOR_TYPE_FIXED32:
+ case UPB_DESCRIPTOR_TYPE_SFIXED32:
+ return upb_decode_fixedpacked(arr, val, sizeof(int32_t));
+ case UPB_DESCRIPTOR_TYPE_DOUBLE:
+ case UPB_DESCRIPTOR_TYPE_FIXED64:
+ case UPB_DESCRIPTOR_TYPE_SFIXED64:
+ return upb_decode_fixedpacked(arr, val, sizeof(int64_t));
+ case UPB_DESCRIPTOR_TYPE_INT32:
+ case UPB_DESCRIPTOR_TYPE_UINT32:
+ case UPB_DESCRIPTOR_TYPE_ENUM:
+ /* TODO: proto2 enum field that isn't in the enum. */
+ VARINT_CASE(uint32_t, uint32_t);
+ case UPB_DESCRIPTOR_TYPE_INT64:
+ case UPB_DESCRIPTOR_TYPE_UINT64:
+ VARINT_CASE(uint64_t, uint64_t);
+ case UPB_DESCRIPTOR_TYPE_BOOL:
+ VARINT_CASE(bool, bool);
+ case UPB_DESCRIPTOR_TYPE_SINT32:
+ VARINT_CASE(int32_t, upb_zzdecode_32);
+ case UPB_DESCRIPTOR_TYPE_SINT64:
+ VARINT_CASE(int64_t, upb_zzdecode_64);
+ case UPB_DESCRIPTOR_TYPE_MESSAGE:
+ CHK(val.size <= (size_t)(frame->limit - val.data));
+ return upb_decode_submsg(d, frame, val.data + val.size, field, 0);
+ case UPB_DESCRIPTOR_TYPE_GROUP:
+ return upb_append_unknown(d, frame, field_start);
+ }
+#undef VARINT_CASE
+ UPB_UNREACHABLE();
+}
+
+static bool upb_decode_delimitedfield(upb_decstate *d, upb_decframe *frame,
+ const char *field_start,
+ const upb_msglayout_fieldinit_v1 *field) {
+ upb_stringview val;
+
+ CHK(upb_decode_string(&d->ptr, frame->limit, &val));
+
+ if (field->label == UPB_LABEL_REPEATED) {
+ return upb_decode_toarray(d, frame, field_start, field, val);
+ } else {
+ switch ((upb_descriptortype_t)field->type) {
+ case UPB_DESCRIPTOR_TYPE_STRING:
+ case UPB_DESCRIPTOR_TYPE_BYTES: {
+ void *field_mem = upb_decode_prepareslot(d, frame, field);
+ CHK(field_mem);
+ memcpy(field_mem, &val, sizeof(val));
+ break;
+ }
+ case UPB_DESCRIPTOR_TYPE_MESSAGE:
+ CHK(val.size <= (size_t)(frame->limit - val.data));
+ CHK(upb_decode_submsg(d, frame, val.data + val.size, field, 0));
+ break;
+ default:
+ /* TODO(haberman): should we accept the last element of a packed? */
+ return upb_append_unknown(d, frame, field_start);
+ }
+ upb_decode_setpresent(frame, field);
+ return true;
+ }
+}
+
+static const upb_msglayout_fieldinit_v1 *upb_find_field(
+ const upb_msglayout_msginit_v1 *l, uint32_t field_number) {
+ /* Lots of optimization opportunities here. */
+ int i;
+ for (i = 0; i < l->field_count; i++) {
+ if (l->fields[i].number == field_number) {
+ return &l->fields[i];
+ }
+ }
+
+ return NULL; /* Unknown field. */
+}
+
+static bool upb_decode_field(upb_decstate *d, upb_decframe *frame) {
+ int field_number;
+ int wire_type;
+ const char *field_start = d->ptr;
+ const upb_msglayout_fieldinit_v1 *field;
+
+ CHK(upb_decode_tag(&d->ptr, frame->limit, &field_number, &wire_type));
+ field = upb_find_field(frame->m, field_number);
+
+ if (field) {
+ switch (wire_type) {
+ case UPB_WIRE_TYPE_VARINT:
+ return upb_decode_varintfield(d, frame, field_start, field);
+ case UPB_WIRE_TYPE_32BIT:
+ return upb_decode_32bitfield(d, frame, field_start, field);
+ case UPB_WIRE_TYPE_64BIT:
+ return upb_decode_64bitfield(d, frame, field_start, field);
+ case UPB_WIRE_TYPE_DELIMITED:
+ return upb_decode_delimitedfield(d, frame, field_start, field);
+ case UPB_WIRE_TYPE_START_GROUP:
+ CHK(field->type == UPB_DESCRIPTOR_TYPE_GROUP);
+ return upb_decode_submsg(d, frame, frame->limit, field, field_number);
+ case UPB_WIRE_TYPE_END_GROUP:
+ CHK(frame->group_number == field_number)
+ frame->limit = d->ptr;
+ return true;
+ default:
+ return false;
+ }
+ } else {
+ CHK(field_number != 0);
+ return upb_skip_unknownfielddata(d, frame, field_number, wire_type);
+ }
+}
+
+static bool upb_skip_unknowngroup(upb_decstate *d, int field_number,
+ const char *limit) {
+ upb_decframe frame;
+ frame.msg = NULL;
+ frame.m = NULL;
+ frame.group_number = field_number;
+ frame.limit = limit;
+
+ while (d->ptr < frame.limit) {
+ int wire_type;
+ int field_number;
+
+ CHK(upb_decode_tag(&d->ptr, frame.limit, &field_number, &wire_type));
+ CHK(upb_skip_unknownfielddata(d, &frame, field_number, wire_type));
+ }
+
+ return true;
+}
+
+static bool upb_decode_message(upb_decstate *d, const char *limit,
+ int group_number, char *msg,
+ const upb_msglayout_msginit_v1 *l) {
+ upb_decframe frame;
+ frame.group_number = group_number;
+ frame.limit = limit;
+ frame.msg = msg;
+ frame.m = l;
+
+ while (d->ptr < frame.limit) {
+ CHK(upb_decode_field(d, &frame));
+ }
+
+ return true;
+}
+
+bool upb_decode(upb_stringview buf, void *msg,
+ const upb_msglayout_msginit_v1 *l, upb_env *env) {
+ upb_decstate state;
+ state.ptr = buf.data;
+ state.env = env;
+
+ return upb_decode_message(&state, buf.data + buf.size, 0, msg, l);
+}
+
+#undef CHK
+
+
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
@@ -326,6 +905,7 @@ static bool assign_msg_indices(upb_msgdef *m, upb_status *s) {
v = upb_value_bool(true);
upb_inttable_insert(&t, UPB_STARTMSG_SELECTOR, v);
upb_inttable_insert(&t, UPB_ENDMSG_SELECTOR, v);
+ upb_inttable_insert(&t, UPB_UNKNOWN_SELECTOR, v);
for(upb_msg_field_begin(&j, m);
!upb_msg_field_done(&j);
upb_msg_field_next(&j)) {
@@ -2359,6 +2939,397 @@ bool upb_symtab_done(const upb_symtab_iter *iter) {
const upb_def *upb_symtab_iter_def(const upb_symtab_iter *iter) {
return upb_value_getptr(upb_strtable_iter_value(&iter->iter));
}
+/* We encode backwards, to avoid pre-computing lengths (one-pass encode). */
+
+
+#define UPB_PB_VARINT_MAX_LEN 10
+#define CHK(x) do { if (!(x)) { return false; } } while(0)
+
+/* Maps descriptor type -> upb field type. */
+static const uint8_t upb_desctype_to_fieldtype2[] = {
+ UPB_WIRE_TYPE_END_GROUP, /* ENDGROUP */
+ UPB_TYPE_DOUBLE, /* DOUBLE */
+ UPB_TYPE_FLOAT, /* FLOAT */
+ UPB_TYPE_INT64, /* INT64 */
+ UPB_TYPE_UINT64, /* UINT64 */
+ UPB_TYPE_INT32, /* INT32 */
+ UPB_TYPE_UINT64, /* FIXED64 */
+ UPB_TYPE_UINT32, /* FIXED32 */
+ UPB_TYPE_BOOL, /* BOOL */
+ UPB_TYPE_STRING, /* STRING */
+ UPB_TYPE_MESSAGE, /* GROUP */
+ UPB_TYPE_MESSAGE, /* MESSAGE */
+ UPB_TYPE_BYTES, /* BYTES */
+ UPB_TYPE_UINT32, /* UINT32 */
+ UPB_TYPE_ENUM, /* ENUM */
+ UPB_TYPE_INT32, /* SFIXED32 */
+ UPB_TYPE_INT64, /* SFIXED64 */
+ UPB_TYPE_INT32, /* SINT32 */
+ UPB_TYPE_INT64, /* SINT64 */
+};
+
+static size_t upb_encode_varint(uint64_t val, char *buf) {
+ size_t i;
+ if (val < 128) { buf[0] = val; return 1; }
+ i = 0;
+ while (val) {
+ uint8_t byte = val & 0x7fU;
+ val >>= 7;
+ if (val) byte |= 0x80U;
+ buf[i++] = byte;
+ }
+ return i;
+}
+
+static uint32_t upb_zzencode_32(int32_t n) { return (n << 1) ^ (n >> 31); }
+static uint64_t upb_zzencode_64(int64_t n) { return (n << 1) ^ (n >> 63); }
+
+typedef struct {
+ upb_env *env;
+ char *buf, *ptr, *limit;
+} upb_encstate;
+
+static size_t upb_roundup_pow2(size_t bytes) {
+ size_t ret = 128;
+ while (ret < bytes) {
+ ret *= 2;
+ }
+ return ret;
+}
+
+static bool upb_encode_growbuffer(upb_encstate *e, size_t bytes) {
+ size_t old_size = e->limit - e->buf;
+ size_t new_size = upb_roundup_pow2(bytes + (e->limit - e->ptr));
+ char *new_buf = upb_env_realloc(e->env, e->buf, old_size, new_size);
+ CHK(new_buf);
+
+ /* We want previous data at the end, realloc() put it at the beginning. */
+ memmove(e->limit - old_size, e->buf, old_size);
+
+ e->ptr = new_buf + new_size - (e->limit - e->ptr);
+ e->limit = new_buf + new_size;
+ e->buf = new_buf;
+ return true;
+}
+
+/* Call to ensure that at least "bytes" bytes are available for writing at
+ * e->ptr. Returns false if the bytes could not be allocated. */
+static bool upb_encode_reserve(upb_encstate *e, size_t bytes) {
+ CHK(UPB_LIKELY((size_t)(e->ptr - e->buf) >= bytes) ||
+ upb_encode_growbuffer(e, bytes));
+
+ e->ptr -= bytes;
+ return true;
+}
+
+/* Writes the given bytes to the buffer, handling reserve/advance. */
+static bool upb_put_bytes(upb_encstate *e, const void *data, size_t len) {
+ CHK(upb_encode_reserve(e, len));
+ memcpy(e->ptr, data, len);
+ return true;
+}
+
+static bool upb_put_fixed64(upb_encstate *e, uint64_t val) {
+ /* TODO(haberman): byte-swap for big endian. */
+ return upb_put_bytes(e, &val, sizeof(uint64_t));
+}
+
+static bool upb_put_fixed32(upb_encstate *e, uint32_t val) {
+ /* TODO(haberman): byte-swap for big endian. */
+ return upb_put_bytes(e, &val, sizeof(uint32_t));
+}
+
+static bool upb_put_varint(upb_encstate *e, uint64_t val) {
+ size_t len;
+ char *start;
+ CHK(upb_encode_reserve(e, UPB_PB_VARINT_MAX_LEN));
+ len = upb_encode_varint(val, e->ptr);
+ start = e->ptr + UPB_PB_VARINT_MAX_LEN - len;
+ memmove(start, e->ptr, len);
+ e->ptr = start;
+ return true;
+}
+
+static bool upb_put_double(upb_encstate *e, double d) {
+ uint64_t u64;
+ UPB_ASSERT(sizeof(double) == sizeof(uint64_t));
+ memcpy(&u64, &d, sizeof(uint64_t));
+ return upb_put_fixed64(e, u64);
+}
+
+static bool upb_put_float(upb_encstate *e, float d) {
+ uint32_t u32;
+ UPB_ASSERT(sizeof(float) == sizeof(uint32_t));
+ memcpy(&u32, &d, sizeof(uint32_t));
+ return upb_put_fixed32(e, u32);
+}
+
+static uint32_t upb_readcase(const char *msg, const upb_msglayout_msginit_v1 *m,
+ int oneof_index) {
+ uint32_t ret;
+ memcpy(&ret, msg + m->oneofs[oneof_index].case_offset, sizeof(ret));
+ return ret;
+}
+
+static bool upb_readhasbit(const char *msg,
+ const upb_msglayout_fieldinit_v1 *f) {
+ UPB_ASSERT(f->hasbit != UPB_NO_HASBIT);
+ return msg[f->hasbit / 8] & (1 << (f->hasbit % 8));
+}
+
+static bool upb_put_tag(upb_encstate *e, int field_number, int wire_type) {
+ return upb_put_varint(e, (field_number << 3) | wire_type);
+}
+
+static bool upb_put_fixedarray(upb_encstate *e, const upb_array *arr,
+ size_t size) {
+ size_t bytes = arr->len * size;
+ return upb_put_bytes(e, arr->data, bytes) && upb_put_varint(e, bytes);
+}
+
+bool upb_encode_message(upb_encstate *e, const char *msg,
+ const upb_msglayout_msginit_v1 *m,
+ size_t *size);
+
+static bool upb_encode_array(upb_encstate *e, const char *field_mem,
+ const upb_msglayout_msginit_v1 *m,
+ const upb_msglayout_fieldinit_v1 *f) {
+ const upb_array *arr = *(const upb_array**)field_mem;
+
+ if (arr == NULL || arr->len == 0) {
+ return true;
+ }
+
+ UPB_ASSERT(arr->type == upb_desctype_to_fieldtype2[f->type]);
+
+#define VARINT_CASE(ctype, encode) { \
+ ctype *start = arr->data; \
+ ctype *ptr = start + arr->len; \
+ size_t pre_len = e->limit - e->ptr; \
+ do { \
+ ptr--; \
+ CHK(upb_put_varint(e, encode)); \
+ } while (ptr != start); \
+ CHK(upb_put_varint(e, e->limit - e->ptr - pre_len)); \
+} \
+break; \
+do { ; } while(0)
+
+ switch (f->type) {
+ case UPB_DESCRIPTOR_TYPE_DOUBLE:
+ CHK(upb_put_fixedarray(e, arr, sizeof(double)));
+ break;
+ case UPB_DESCRIPTOR_TYPE_FLOAT:
+ CHK(upb_put_fixedarray(e, arr, sizeof(float)));
+ break;
+ case UPB_DESCRIPTOR_TYPE_SFIXED64:
+ case UPB_DESCRIPTOR_TYPE_FIXED64:
+ CHK(upb_put_fixedarray(e, arr, sizeof(uint64_t)));
+ break;
+ case UPB_DESCRIPTOR_TYPE_FIXED32:
+ case UPB_DESCRIPTOR_TYPE_SFIXED32:
+ CHK(upb_put_fixedarray(e, arr, sizeof(uint32_t)));
+ break;
+ case UPB_DESCRIPTOR_TYPE_INT64:
+ case UPB_DESCRIPTOR_TYPE_UINT64:
+ VARINT_CASE(uint64_t, *ptr);
+ case UPB_DESCRIPTOR_TYPE_UINT32:
+ case UPB_DESCRIPTOR_TYPE_INT32:
+ case UPB_DESCRIPTOR_TYPE_ENUM:
+ VARINT_CASE(uint32_t, *ptr);
+ case UPB_DESCRIPTOR_TYPE_BOOL:
+ VARINT_CASE(bool, *ptr);
+ case UPB_DESCRIPTOR_TYPE_SINT32:
+ VARINT_CASE(int32_t, upb_zzencode_32(*ptr));
+ case UPB_DESCRIPTOR_TYPE_SINT64:
+ VARINT_CASE(int64_t, upb_zzencode_64(*ptr));
+ case UPB_DESCRIPTOR_TYPE_STRING:
+ case UPB_DESCRIPTOR_TYPE_BYTES: {
+ upb_stringview *start = arr->data;
+ upb_stringview *ptr = start + arr->len;
+ do {
+ ptr--;
+ CHK(upb_put_bytes(e, ptr->data, ptr->size) &&
+ upb_put_varint(e, ptr->size) &&
+ upb_put_tag(e, f->number, UPB_WIRE_TYPE_DELIMITED));
+ } while (ptr != start);
+ return true;
+ }
+ case UPB_DESCRIPTOR_TYPE_GROUP: {
+ void **start = arr->data;
+ void **ptr = start + arr->len;
+ const upb_msglayout_msginit_v1 *subm = m->submsgs[f->submsg_index];
+ do {
+ size_t size;
+ ptr--;
+ CHK(upb_put_tag(e, f->number, UPB_WIRE_TYPE_END_GROUP) &&
+ upb_encode_message(e, *ptr, subm, &size) &&
+ upb_put_tag(e, f->number, UPB_WIRE_TYPE_START_GROUP));
+ } while (ptr != start);
+ return true;
+ }
+ case UPB_DESCRIPTOR_TYPE_MESSAGE: {
+ void **start = arr->data;
+ void **ptr = start + arr->len;
+ const upb_msglayout_msginit_v1 *subm = m->submsgs[f->submsg_index];
+ do {
+ size_t size;
+ ptr--;
+ CHK(upb_encode_message(e, *ptr, subm, &size) &&
+ upb_put_varint(e, size) &&
+ upb_put_tag(e, f->number, UPB_WIRE_TYPE_DELIMITED));
+ } while (ptr != start);
+ return true;
+ }
+ }
+#undef VARINT_CASE
+
+ /* We encode all primitive arrays as packed, regardless of what was specified
+ * in the .proto file. Could special case 1-sized arrays. */
+ CHK(upb_put_tag(e, f->number, UPB_WIRE_TYPE_DELIMITED));
+ return true;
+}
+
+static bool upb_encode_scalarfield(upb_encstate *e, const char *field_mem,
+ const upb_msglayout_msginit_v1 *m,
+ const upb_msglayout_fieldinit_v1 *f,
+ bool is_proto3) {
+ bool skip_zero_value = is_proto3 && f->oneof_index == UPB_NOT_IN_ONEOF;
+
+#define CASE(ctype, type, wire_type, encodeval) do { \
+ ctype val = *(ctype*)field_mem; \
+ if (skip_zero_value && val == 0) { \
+ return true; \
+ } \
+ return upb_put_ ## type(e, encodeval) && \
+ upb_put_tag(e, f->number, wire_type); \
+} while(0)
+
+ switch (f->type) {
+ case UPB_DESCRIPTOR_TYPE_DOUBLE:
+ CASE(double, double, UPB_WIRE_TYPE_64BIT, val);
+ case UPB_DESCRIPTOR_TYPE_FLOAT:
+ CASE(float, float, UPB_WIRE_TYPE_32BIT, val);
+ case UPB_DESCRIPTOR_TYPE_INT64:
+ case UPB_DESCRIPTOR_TYPE_UINT64:
+ CASE(uint64_t, varint, UPB_WIRE_TYPE_VARINT, val);
+ case UPB_DESCRIPTOR_TYPE_UINT32:
+ case UPB_DESCRIPTOR_TYPE_INT32:
+ case UPB_DESCRIPTOR_TYPE_ENUM:
+ CASE(uint32_t, varint, UPB_WIRE_TYPE_VARINT, val);
+ case UPB_DESCRIPTOR_TYPE_SFIXED64:
+ case UPB_DESCRIPTOR_TYPE_FIXED64:
+ CASE(uint64_t, fixed64, UPB_WIRE_TYPE_64BIT, val);
+ case UPB_DESCRIPTOR_TYPE_FIXED32:
+ case UPB_DESCRIPTOR_TYPE_SFIXED32:
+ CASE(uint32_t, fixed32, UPB_WIRE_TYPE_32BIT, val);
+ case UPB_DESCRIPTOR_TYPE_BOOL:
+ CASE(bool, varint, UPB_WIRE_TYPE_VARINT, val);
+ case UPB_DESCRIPTOR_TYPE_SINT32:
+ CASE(int32_t, varint, UPB_WIRE_TYPE_VARINT, upb_zzencode_32(val));
+ case UPB_DESCRIPTOR_TYPE_SINT64:
+ CASE(int64_t, varint, UPB_WIRE_TYPE_VARINT, upb_zzencode_64(val));
+ case UPB_DESCRIPTOR_TYPE_STRING:
+ case UPB_DESCRIPTOR_TYPE_BYTES: {
+ upb_stringview view = *(upb_stringview*)field_mem;
+ if (skip_zero_value && view.size == 0) {
+ return true;
+ }
+ return upb_put_bytes(e, view.data, view.size) &&
+ upb_put_varint(e, view.size) &&
+ upb_put_tag(e, f->number, UPB_WIRE_TYPE_DELIMITED);
+ }
+ case UPB_DESCRIPTOR_TYPE_GROUP: {
+ size_t size;
+ void *submsg = *(void**)field_mem;
+ const upb_msglayout_msginit_v1 *subm = m->submsgs[f->submsg_index];
+ if (skip_zero_value && submsg == NULL) {
+ return true;
+ }
+ return upb_put_tag(e, f->number, UPB_WIRE_TYPE_END_GROUP) &&
+ upb_encode_message(e, submsg, subm, &size) &&
+ upb_put_tag(e, f->number, UPB_WIRE_TYPE_START_GROUP);
+ }
+ case UPB_DESCRIPTOR_TYPE_MESSAGE: {
+ size_t size;
+ void *submsg = *(void**)field_mem;
+ const upb_msglayout_msginit_v1 *subm = m->submsgs[f->submsg_index];
+ if (skip_zero_value && submsg == NULL) {
+ return true;
+ }
+ return upb_encode_message(e, submsg, subm, &size) &&
+ upb_put_varint(e, size) &&
+ upb_put_tag(e, f->number, UPB_WIRE_TYPE_DELIMITED);
+ }
+ }
+#undef CASE
+ UPB_UNREACHABLE();
+}
+
+bool upb_encode_hasscalarfield(const char *msg,
+ const upb_msglayout_msginit_v1 *m,
+ const upb_msglayout_fieldinit_v1 *f) {
+ if (f->oneof_index != UPB_NOT_IN_ONEOF) {
+ return upb_readcase(msg, m, f->oneof_index) == f->number;
+ } else if (m->is_proto2) {
+ return upb_readhasbit(msg, f);
+ } else {
+ /* For proto3, we'll test for the field being empty later. */
+ return true;
+ }
+}
+
+bool upb_encode_message(upb_encstate* e, const char *msg,
+ const upb_msglayout_msginit_v1 *m,
+ size_t *size) {
+ int i;
+ char *buf_end = e->ptr;
+
+ if (msg == NULL) {
+ return true;
+ }
+
+ for (i = m->field_count - 1; i >= 0; i--) {
+ const upb_msglayout_fieldinit_v1 *f = &m->fields[i];
+
+ if (f->label == UPB_LABEL_REPEATED) {
+ CHK(upb_encode_array(e, msg + f->offset, m, f));
+ } else {
+ if (upb_encode_hasscalarfield(msg, m, f)) {
+ CHK(upb_encode_scalarfield(e, msg + f->offset, m, f, !m->is_proto2));
+ }
+ }
+ }
+
+ *size = buf_end - e->ptr;
+ return true;
+}
+
+char *upb_encode(const void *msg, const upb_msglayout_msginit_v1 *m,
+ upb_env *env, size_t *size) {
+ upb_encstate e;
+ e.env = env;
+ e.buf = NULL;
+ e.limit = NULL;
+ e.ptr = NULL;
+
+ if (!upb_encode_message(&e, msg, m, size)) {
+ *size = 0;
+ return NULL;
+ }
+
+ *size = e.limit - e.ptr;
+
+ if (*size == 0) {
+ static char ch;
+ return &ch;
+ } else {
+ UPB_ASSERT(e.ptr);
+ return e.ptr;
+ }
+}
+
+#undef CHK
/*
** TODO(haberman): it's unclear whether a lot of the consistency checks should
** UPB_ASSERT() or return false.
@@ -2730,6 +3701,12 @@ SETTER(endseq, upb_endfield_handlerfunc*, UPB_HANDLER_ENDSEQ)
#undef SETTER
+bool upb_handlers_setunknown(upb_handlers *h, upb_unknown_handlerfunc *func,
+ upb_handlerattr *attr) {
+ return doset(h, UPB_UNKNOWN_SELECTOR, NULL, UPB_HANDLER_INT32,
+ (upb_func *)func, attr);
+}
+
bool upb_handlers_setstartmsg(upb_handlers *h, upb_startmsg_handlerfunc *func,
upb_handlerattr *attr) {
return doset(h, UPB_STARTMSG_SELECTOR, NULL, UPB_HANDLER_INT32,
@@ -3079,7 +4056,8 @@ bool upb_fieldtype_mapkeyok(upb_fieldtype_t type) {
void *upb_array_pack(const upb_array *arr, void *p, size_t *ofs, size_t size);
void *upb_map_pack(const upb_map *map, void *p, size_t *ofs, size_t size);
-#define CHARPTR_AT(msg, ofs) ((char*)msg + ofs)
+#define PTR_AT(msg, ofs, type) (type*)((char*)msg + ofs)
+#define VOIDPTR_AT(msg, ofs) PTR_AT(msg, ofs, void)
#define ENCODE_MAX_NESTING 64
#define CHECK_TRUE(x) if (!(x)) { return false; }
@@ -3121,12 +4099,20 @@ static size_t upb_msgval_sizeof(upb_fieldtype_t type) {
case UPB_TYPE_MESSAGE:
return sizeof(void*);
case UPB_TYPE_STRING:
- return sizeof(char*) + sizeof(size_t);
+ return sizeof(upb_stringview);
}
UPB_UNREACHABLE();
}
-static uint8_t upb_msg_fieldsize(const upb_fielddef *f) {
+static uint8_t upb_msg_fieldsize(const upb_msglayout_fieldinit_v1 *field) {
+ if (field->label == UPB_LABEL_REPEATED) {
+ return sizeof(void*);
+ } else {
+ return upb_msgval_sizeof(field->type);
+ }
+}
+
+static uint8_t upb_msg_fielddefsize(const upb_fielddef *f) {
if (upb_fielddef_isseq(f)) {
return sizeof(void*);
} else {
@@ -3170,7 +4156,6 @@ static upb_ctype_t upb_fieldtotabtype(upb_fieldtype_t type) {
}
static upb_msgval upb_msgval_fromdefault(const upb_fielddef *f) {
- /* TODO(haberman): improve/optimize this (maybe use upb_msgval in fielddef) */
switch (upb_fielddef_type(f)) {
case UPB_TYPE_FLOAT:
return upb_msgval_float(upb_fielddef_defaultfloat(f));
@@ -3182,7 +4167,7 @@ static upb_msgval upb_msgval_fromdefault(const upb_fielddef *f) {
case UPB_TYPE_BYTES: {
size_t len;
const char *ptr = upb_fielddef_defaultstr(f, &len);
- return upb_msgval_str(ptr, len);
+ return upb_msgval_makestr(ptr, len);
}
case UPB_TYPE_MESSAGE:
return upb_msgval_msg(NULL);
@@ -3205,63 +4190,44 @@ static upb_msgval upb_msgval_fromdefault(const upb_fielddef *f) {
/** upb_msglayout *************************************************************/
struct upb_msglayout {
- upb_msgfactory *factory;
- const upb_msgdef *msgdef;
- size_t size;
- size_t extdict_offset;
- void *default_msg;
- uint32_t *field_offsets;
- uint32_t *case_offsets;
- uint32_t *hasbits;
- bool has_extdict;
- uint8_t align;
+ struct upb_msglayout_msginit_v1 data;
};
-static void upb_msg_checkfield(const upb_msglayout *l, const upb_fielddef *f) {
- UPB_ASSERT(l->msgdef == upb_fielddef_containingtype(f));
-}
-
static void upb_msglayout_free(upb_msglayout *l) {
- upb_gfree(l->default_msg);
+ upb_gfree(l->data.default_msg);
upb_gfree(l);
}
-const upb_msgdef *upb_msglayout_msgdef(const upb_msglayout *l) {
- return l->msgdef;
-}
-
static size_t upb_msglayout_place(upb_msglayout *l, size_t size) {
size_t ret;
- l->size = align_up(l->size, size);
- l->align = align_up(l->align, size);
- ret = l->size;
- l->size += size;
+ l->data.size = align_up(l->data.size, size);
+ ret = l->data.size;
+ l->data.size += size;
return ret;
}
static uint32_t upb_msglayout_offset(const upb_msglayout *l,
const upb_fielddef *f) {
- return l->field_offsets[upb_fielddef_index(f)];
+ return l->data.fields[upb_fielddef_index(f)].offset;
}
static uint32_t upb_msglayout_hasbit(const upb_msglayout *l,
const upb_fielddef *f) {
- return l->hasbits[upb_fielddef_index(f)];
+ return l->data.fields[upb_fielddef_index(f)].hasbit;
}
-static bool upb_msglayout_initdefault(upb_msglayout *l) {
- const upb_msgdef *m = l->msgdef;
+static bool upb_msglayout_initdefault(upb_msglayout *l, const upb_msgdef *m) {
upb_msg_field_iter it;
- if (upb_msgdef_syntax(m) == UPB_SYNTAX_PROTO2 && l->size) {
+ if (upb_msgdef_syntax(m) == UPB_SYNTAX_PROTO2 && l->data.size) {
/* Allocate default message and set default values in it. */
- l->default_msg = upb_gmalloc(l->size);
- if (!l->default_msg) {
+ l->data.default_msg = upb_gmalloc(l->data.size);
+ if (!l->data.default_msg) {
return false;
}
- memset(l->default_msg, 0, l->size);
+ memset(l->data.default_msg, 0, l->data.size);
for (upb_msg_field_begin(&it, m); !upb_msg_field_done(&it);
upb_msg_field_next(&it)) {
@@ -3271,10 +4237,14 @@ static bool upb_msglayout_initdefault(upb_msglayout *l) {
continue;
}
+ /* TODO(haberman): handle strings. */
if (!upb_fielddef_isstring(f) &&
!upb_fielddef_issubmsg(f) &&
!upb_fielddef_isseq(f)) {
- upb_msg_set(l->default_msg, f, upb_msgval_fromdefault(f), l);
+ upb_msg_set(l->data.default_msg,
+ upb_fielddef_index(f),
+ upb_msgval_fromdefault(f),
+ l);
}
}
}
@@ -3287,22 +4257,46 @@ static upb_msglayout *upb_msglayout_new(const upb_msgdef *m) {
upb_msg_oneof_iter oit;
upb_msglayout *l;
size_t hasbit;
- size_t array_size = upb_msgdef_numfields(m) + upb_msgdef_numoneofs(m);
+ size_t submsg_count = 0;
+ const upb_msglayout_msginit_v1 **submsgs;
+ upb_msglayout_fieldinit_v1 *fields;
+ upb_msglayout_oneofinit_v1 *oneofs;
- if (upb_msgdef_syntax(m) == UPB_SYNTAX_PROTO2) {
- array_size += upb_msgdef_numfields(m); /* hasbits. */
+ for (upb_msg_field_begin(&it, m);
+ !upb_msg_field_done(&it);
+ upb_msg_field_next(&it)) {
+ const upb_fielddef* f = upb_msg_iter_field(&it);
+ if (upb_fielddef_issubmsg(f)) {
+ submsg_count++;
+ }
}
- l = upb_gmalloc(sizeof(*l) + (sizeof(uint32_t) * array_size));
+ l = upb_gmalloc(sizeof(*l));
if (!l) return NULL;
memset(l, 0, sizeof(*l));
- l->msgdef = m;
- l->align = 1;
- l->field_offsets = (uint32_t*)CHARPTR_AT(l, sizeof(*l));
- l->case_offsets = l->field_offsets + upb_msgdef_numfields(m);
- l->hasbits = l->case_offsets + upb_msgdef_numoneofs(m);
+ fields = upb_gmalloc(upb_msgdef_numfields(m) * sizeof(*fields));
+ submsgs = upb_gmalloc(submsg_count * sizeof(*submsgs));
+ oneofs = upb_gmalloc(upb_msgdef_numoneofs(m) * sizeof(*oneofs));
+
+ if ((!fields && upb_msgdef_numfields(m)) ||
+ (!submsgs && submsg_count) ||
+ (!oneofs && upb_msgdef_numoneofs(m))) {
+ /* OOM. */
+ upb_gfree(l);
+ upb_gfree(fields);
+ upb_gfree(submsgs);
+ upb_gfree(oneofs);
+ return NULL;
+ }
+
+ l->data.field_count = upb_msgdef_numfields(m);
+ l->data.oneof_count = upb_msgdef_numoneofs(m);
+ l->data.fields = fields;
+ l->data.submsgs = submsgs;
+ l->data.oneofs = oneofs;
+ l->data.is_proto2 = (upb_msgdef_syntax(m) == UPB_SYNTAX_PROTO2);
/* Allocate data offsets in three stages:
*
@@ -3313,74 +4307,75 @@ static upb_msglayout *upb_msglayout_new(const upb_msgdef *m) {
* OPT: There is a lot of room for optimization here to minimize the size.
*/
- /* Allocate hasbits. Start at sizeof(void*) for upb_alloc*. */
- for (upb_msg_field_begin(&it, m), hasbit = sizeof(void*) * 8;
+ /* Allocate hasbits and set basic field attributes. */
+ for (upb_msg_field_begin(&it, m), hasbit = 0;
!upb_msg_field_done(&it);
upb_msg_field_next(&it)) {
const upb_fielddef* f = upb_msg_iter_field(&it);
+ upb_msglayout_fieldinit_v1 *field = &fields[upb_fielddef_index(f)];
+
+ field->number = upb_fielddef_number(f);
+ field->type = upb_fielddef_type(f);
+ field->label = upb_fielddef_label(f);
+
+ if (upb_fielddef_containingoneof(f)) {
+ field->oneof_index = upb_oneofdef_index(upb_fielddef_containingoneof(f));
+ } else {
+ field->oneof_index = UPB_NOT_IN_ONEOF;
+ }
if (upb_fielddef_haspresence(f) && !upb_fielddef_containingoneof(f)) {
- l->hasbits[upb_fielddef_index(f)] = hasbit++;
+ field->hasbit = hasbit++;
}
}
/* Account for space used by hasbits. */
- l->size = div_round_up(hasbit, 8);
+ l->data.size = div_round_up(hasbit, 8);
/* Allocate non-oneof fields. */
for (upb_msg_field_begin(&it, m); !upb_msg_field_done(&it);
upb_msg_field_next(&it)) {
const upb_fielddef* f = upb_msg_iter_field(&it);
- size_t field_size = upb_msg_fieldsize(f);
+ size_t field_size = upb_msg_fielddefsize(f);
size_t index = upb_fielddef_index(f);
-
if (upb_fielddef_containingoneof(f)) {
/* Oneofs are handled separately below. */
continue;
}
- l->field_offsets[index] = upb_msglayout_place(l, field_size);
+ fields[index].offset = upb_msglayout_place(l, field_size);
}
/* Allocate oneof fields. Each oneof field consists of a uint32 for the case
* and space for the actual data. */
for (upb_msg_oneof_begin(&oit, m); !upb_msg_oneof_done(&oit);
upb_msg_oneof_next(&oit)) {
- const upb_oneofdef* oneof = upb_msg_iter_oneof(&oit);
+ const upb_oneofdef* o = upb_msg_iter_oneof(&oit);
upb_oneof_iter fit;
+
size_t case_size = sizeof(uint32_t); /* Could potentially optimize this. */
+ upb_msglayout_oneofinit_v1 *oneof = &oneofs[upb_oneofdef_index(o)];
size_t field_size = 0;
- size_t case_offset;
- size_t val_offset;
/* Calculate field size: the max of all field sizes. */
- for (upb_oneof_begin(&fit, oneof);
+ for (upb_oneof_begin(&fit, o);
!upb_oneof_done(&fit);
upb_oneof_next(&fit)) {
const upb_fielddef* f = upb_oneof_iter_field(&fit);
- field_size = UPB_MAX(field_size, upb_msg_fieldsize(f));
+ field_size = UPB_MAX(field_size, upb_msg_fielddefsize(f));
}
/* Align and allocate case offset. */
- case_offset = upb_msglayout_place(l, case_size);
- val_offset = upb_msglayout_place(l, field_size);
-
- l->case_offsets[upb_oneofdef_index(oneof)] = case_offset;
-
- /* 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* f = upb_oneof_iter_field(&fit);
- l->field_offsets[upb_fielddef_index(f)] = val_offset;
- }
+ oneof->case_offset = upb_msglayout_place(l, case_size);
+ oneof->data_offset = upb_msglayout_place(l, field_size);
}
/* Size of the entire structure should be a multiple of its greatest
- * alignment. */
- l->size = align_up(l->size, l->align);
+ * alignment. TODO: track overall alignment for real? */
+ l->data.size = align_up(l->data.size, 8);
- if (upb_msglayout_initdefault(l)) {
+ if (upb_msglayout_initdefault(l, m)) {
return l;
} else {
upb_msglayout_free(l);
@@ -3388,10 +4383,6 @@ static upb_msglayout *upb_msglayout_new(const upb_msgdef *m) {
}
}
-upb_msgfactory *upb_msglayout_factory(const upb_msglayout *layout) {
- return layout->factory;
-}
-
/** upb_msgfactory ************************************************************/
@@ -3448,7 +4439,6 @@ const upb_msglayout *upb_msgfactory_getlayout(upb_msgfactory *f,
upb_msglayout *l = upb_msglayout_new(m);
upb_inttable_insertptr(&mutable_f->layouts, m, upb_value_ptr(l));
UPB_ASSERT(l);
- l->factory = f;
return l;
}
}
@@ -3457,16 +4447,15 @@ const upb_msglayout *upb_msgfactory_getlayout(upb_msgfactory *f,
void *upb_msg_startstr(void *msg, const void *hd, size_t size_hint) {
uint32_t ofs = (uintptr_t)hd;
- /* We pass NULL here because we know we can get away with it. */
- upb_alloc *alloc = upb_msg_alloc(msg, NULL);
+ upb_alloc *alloc = upb_msg_alloc(msg);
upb_msgval val;
UPB_UNUSED(size_hint);
val = upb_msgval_read(msg, ofs, upb_msgval_sizeof(UPB_TYPE_STRING));
- upb_free(alloc, (void*)val.str.ptr);
- val.str.ptr = NULL;
- val.str.len = 0;
+ upb_free(alloc, (void*)val.str.data);
+ val.str.data = NULL;
+ val.str.size = 0;
upb_msgval_write(msg, ofs, val, upb_msgval_sizeof(UPB_TYPE_STRING));
return msg;
@@ -3475,23 +4464,22 @@ void *upb_msg_startstr(void *msg, const void *hd, size_t size_hint) {
size_t upb_msg_str(void *msg, const void *hd, const char *ptr, size_t size,
const upb_bufhandle *handle) {
uint32_t ofs = (uintptr_t)hd;
- /* We pass NULL here because we know we can get away with it. */
- upb_alloc *alloc = upb_msg_alloc(msg, NULL);
+ upb_alloc *alloc = upb_msg_alloc(msg);
upb_msgval val;
size_t newsize;
UPB_UNUSED(handle);
val = upb_msgval_read(msg, ofs, upb_msgval_sizeof(UPB_TYPE_STRING));
- newsize = val.str.len + size;
- val.str.ptr = upb_realloc(alloc, (void*)val.str.ptr, val.str.len, newsize);
+ newsize = val.str.size + size;
+ val.str.data = upb_realloc(alloc, (void*)val.str.data, val.str.size, newsize);
- if (!val.str.ptr) {
+ if (!val.str.data) {
return false;
}
- memcpy((char*)val.str.ptr + val.str.len, ptr, size);
- val.str.len = newsize;
+ memcpy((char*)val.str.data + val.str.size, ptr, size);
+ val.str.size = newsize;
upb_msgval_write(msg, ofs, val, upb_msgval_sizeof(UPB_TYPE_STRING));
return size;
}
@@ -3556,13 +4544,14 @@ static upb_selector_t getsel2(const upb_fielddef *f, upb_handlertype_t type) {
static bool upb_visitor_hasfield(const upb_msg *msg, const upb_fielddef *f,
const upb_msglayout *layout) {
+ int field_index = upb_fielddef_index(f);
if (upb_fielddef_isseq(f)) {
- return upb_msgval_getarr(upb_msg_get(msg, f, layout)) != NULL;
+ return upb_msgval_getarr(upb_msg_get(msg, field_index, layout)) != NULL;
} else if (upb_msgdef_syntax(upb_fielddef_containingtype(f)) ==
UPB_SYNTAX_PROTO2) {
- return upb_msg_has(msg, f, layout);
+ return upb_msg_has(msg, field_index, layout);
} else {
- upb_msgval val = upb_msg_get(msg, f, layout);
+ upb_msgval val = upb_msg_get(msg, field_index, layout);
switch (upb_fielddef_type(f)) {
case UPB_TYPE_FLOAT:
return upb_msgval_getfloat(val) != 0;
@@ -3581,7 +4570,7 @@ static bool upb_visitor_hasfield(const upb_msg *msg, const upb_fielddef *f,
return upb_msgval_getuint64(val) != 0;
case UPB_TYPE_STRING:
case UPB_TYPE_BYTES:
- return upb_msgval_getstr(val) && upb_msgval_getstrlen(val) > 0;
+ return upb_msgval_getstr(val).size > 0;
case UPB_TYPE_MESSAGE:
return upb_msgval_getmsg(val) != NULL;
}
@@ -3592,7 +4581,7 @@ static bool upb_visitor_hasfield(const upb_msg *msg, const upb_fielddef *f,
static bool upb_visitor_visitmsg2(const upb_msg *msg,
const upb_msglayout *layout, upb_sink *sink,
int depth) {
- const upb_msgdef *md = upb_msglayout_msgdef(layout);
+ const upb_msgdef *md = upb_handlers_msgdef(sink->handlers);
upb_msg_field_iter i;
upb_status status;
@@ -3614,7 +4603,7 @@ static bool upb_visitor_visitmsg2(const upb_msg *msg,
continue;
}
- val = upb_msg_get(msg, f, layout);
+ val = upb_msg_get(msg, upb_fielddef_index(f), layout);
if (upb_fielddef_isseq(f)) {
const upb_array *arr = upb_msgval_getarr(val);
@@ -3683,194 +4672,160 @@ bool upb_visitor_visitmsg(upb_visitor *visitor, const upb_msg *msg) {
/* If we always read/write as a consistent type to each address, this shouldn't
* violate aliasing.
*/
-#define DEREF(msg, ofs, type) *(type*)CHARPTR_AT(msg, ofs)
-
-static upb_inttable *upb_msg_trygetextdict(const upb_msg *msg,
- const upb_msglayout *l) {
- return l->has_extdict ? DEREF(msg, l->extdict_offset, upb_inttable*) : NULL;
-}
+#define DEREF(msg, ofs, type) *PTR_AT(msg, ofs, type)
-static upb_inttable *upb_msg_getextdict(upb_msg *msg,
- const upb_msglayout *l,
- upb_alloc *a) {
- upb_inttable *ext_dict;
- UPB_ASSERT(l->has_extdict);
+/* Internal members of a upb_msg. We can change this without breaking binary
+ * compatibility. We put these before the user's data. The user's upb_msg*
+ * points after the upb_msg_internal. */
- ext_dict = upb_msg_trygetextdict(msg, l);
+/* Used when a message is not extendable. */
+typedef struct {
+ /* TODO(haberman): add unknown fields. */
+ upb_alloc *alloc;
+} upb_msg_internal;
- if (!ext_dict) {
- ext_dict = upb_malloc(a, sizeof(upb_inttable));
+/* Used when a message is extendable. */
+typedef struct {
+ upb_inttable *extdict;
+ upb_msg_internal base;
+} upb_msg_internal_withext;
- if (!ext_dict) {
- return NULL;
- }
+static int upb_msg_internalsize(const upb_msglayout *l) {
+ return sizeof(upb_msg_internal) - l->data.extendable * sizeof(void*);
+}
- /* Use an 8-byte type to ensure all bytes are copied. */
- if (!upb_inttable_init2(ext_dict, UPB_CTYPE_INT64, a)) {
- upb_free(a, ext_dict);
- return NULL;
- }
+static upb_msg_internal *upb_msg_getinternal(upb_msg *msg) {
+ return VOIDPTR_AT(msg, -sizeof(upb_msg_internal));
+}
- DEREF(msg, l->extdict_offset, upb_inttable*) = ext_dict;
- }
+static const upb_msg_internal *upb_msg_getinternal_const(const upb_msg *msg) {
+ return VOIDPTR_AT(msg, -sizeof(upb_msg_internal));
+}
- return ext_dict;
+static upb_msg_internal_withext *upb_msg_getinternalwithext(
+ upb_msg *msg, const upb_msglayout *l) {
+ UPB_ASSERT(l->data.extendable);
+ return VOIDPTR_AT(msg, -sizeof(upb_msg_internal_withext));
}
-static uint32_t upb_msg_getoneofint(const upb_msg *msg,
- const upb_oneofdef *o,
- const upb_msglayout *l) {
- size_t oneof_ofs = l->case_offsets[upb_oneofdef_index(o)];
- return DEREF(msg, oneof_ofs, uint8_t);
+static const upb_msglayout_fieldinit_v1 *upb_msg_checkfield(
+ int field_index, const upb_msglayout *l) {
+ UPB_ASSERT(field_index >= 0 && field_index < l->data.field_count);
+ return &l->data.fields[field_index];
}
-static void upb_msg_setoneofcase(const upb_msg *msg,
- const upb_oneofdef *o,
- const upb_msglayout *l,
- uint32_t val) {
- size_t oneof_ofs = l->case_offsets[upb_oneofdef_index(o)];
- DEREF(msg, oneof_ofs, uint8_t) = val;
+static bool upb_msg_inoneof(const upb_msglayout_fieldinit_v1 *field) {
+ return field->oneof_index != UPB_NOT_IN_ONEOF;
}
+static uint32_t *upb_msg_oneofcase(const upb_msg *msg, int field_index,
+ const upb_msglayout *l) {
+ const upb_msglayout_fieldinit_v1 *field = upb_msg_checkfield(field_index, l);
+ UPB_ASSERT(upb_msg_inoneof(field));
+ return PTR_AT(msg, l->data.oneofs[field->oneof_index].case_offset, uint32_t);
+}
-static bool upb_msg_oneofis(const upb_msg *msg, const upb_msglayout *l,
- const upb_oneofdef *o, const upb_fielddef *f) {
- return upb_msg_getoneofint(msg, o, l) == upb_fielddef_number(f);
+size_t upb_msg_sizeof(const upb_msglayout *l) {
+ return l->data.size + upb_msg_internalsize(l);
}
-size_t upb_msg_sizeof(const upb_msglayout *l) { return l->size; }
+upb_msg *upb_msg_init(void *mem, const upb_msglayout *l, upb_alloc *a) {
+ upb_msg *msg = VOIDPTR_AT(mem, upb_msg_internalsize(l));
-void upb_msg_init(upb_msg *msg, const upb_msglayout *l, upb_alloc *a) {
- if (l->default_msg) {
- memcpy(msg, l->default_msg, l->size);
+ /* Initialize normal members. */
+ if (l->data.default_msg) {
+ memcpy(msg, l->data.default_msg, l->data.size);
} else {
- memset(msg, 0, l->size);
+ memset(msg, 0, l->data.size);
}
- /* Set arena pointer. */
- memcpy(msg, &a, sizeof(a));
-}
+ /* Initialize internal members. */
+ upb_msg_getinternal(msg)->alloc = a;
-void upb_msg_uninit(upb_msg *msg, const upb_msglayout *l) {
- upb_inttable *ext_dict = upb_msg_trygetextdict(msg, l);
- if (ext_dict) {
- upb_inttable_uninit2(ext_dict, upb_msg_alloc(msg, l));
+ if (l->data.extendable) {
+ upb_msg_getinternalwithext(msg, l)->extdict = NULL;
}
-}
-upb_msg *upb_msg_new(const upb_msglayout *l, upb_alloc *a) {
- upb_msg *msg = upb_malloc(a, upb_msg_sizeof(l));
+ return msg;
+}
- if (msg) {
- upb_msg_init(msg, l, a);
+void *upb_msg_uninit(upb_msg *msg, const upb_msglayout *l) {
+ if (l->data.extendable) {
+ upb_inttable *ext_dict = upb_msg_getinternalwithext(msg, l)->extdict;
+ if (ext_dict) {
+ upb_inttable_uninit2(ext_dict, upb_msg_alloc(msg));
+ upb_free(upb_msg_alloc(msg), ext_dict);
+ }
}
- return msg;
+ return VOIDPTR_AT(msg, -upb_msg_internalsize(l));
+}
+
+upb_msg *upb_msg_new(const upb_msglayout *l, upb_alloc *a) {
+ void *mem = upb_malloc(a, upb_msg_sizeof(l));
+ return mem ? upb_msg_init(mem, l, a) : NULL;
}
void upb_msg_free(upb_msg *msg, const upb_msglayout *l) {
- upb_msg_uninit(msg, l);
- upb_free(upb_msg_alloc(msg, l), msg);
+ upb_free(upb_msg_alloc(msg), upb_msg_uninit(msg, l));
}
-upb_alloc *upb_msg_alloc(const upb_msg *msg, const upb_msglayout *l) {
- upb_alloc *alloc;
- UPB_UNUSED(l);
- memcpy(&alloc, msg, sizeof(alloc));
- return alloc;
+upb_alloc *upb_msg_alloc(const upb_msg *msg) {
+ return upb_msg_getinternal_const(msg)->alloc;
}
bool upb_msg_has(const upb_msg *msg,
- const upb_fielddef *f,
+ int field_index,
const upb_msglayout *l) {
- const upb_oneofdef *o;
- upb_msg_checkfield(l, f);
- UPB_ASSERT(upb_fielddef_haspresence(f));
+ const upb_msglayout_fieldinit_v1 *field = upb_msg_checkfield(field_index, l);
- if (upb_fielddef_isextension(f)) {
- /* Extensions are set when they are present in the extension dict. */
- upb_inttable *ext_dict = upb_msg_trygetextdict(msg, l);
- upb_value v;
- return ext_dict != NULL &&
- upb_inttable_lookup32(ext_dict, upb_fielddef_number(f), &v);
- } else if ((o = upb_fielddef_containingoneof(f)) != NULL) {
+ UPB_ASSERT(l->data.is_proto2);
+
+ if (upb_msg_inoneof(field)) {
/* Oneofs are set when the oneof number is set to this field. */
- return upb_msg_getoneofint(msg, o, l) == upb_fielddef_number(f);
+ return *upb_msg_oneofcase(msg, field_index, l) == field->number;
} else {
/* Other fields are set when their hasbit is set. */
- uint32_t hasbit = l->hasbits[upb_fielddef_index(f)];
+ uint32_t hasbit = l->data.fields[field_index].hasbit;
return DEREF(msg, hasbit / 8, char) | (1 << (hasbit % 8));
}
}
-upb_msgval upb_msg_get(const upb_msg *msg, const upb_fielddef *f,
+upb_msgval upb_msg_get(const upb_msg *msg, int field_index,
const upb_msglayout *l) {
- upb_msg_checkfield(l, f);
+ const upb_msglayout_fieldinit_v1 *field = upb_msg_checkfield(field_index, l);
+ int size = upb_msg_fieldsize(field);
- if (upb_fielddef_isextension(f)) {
- upb_inttable *ext_dict = upb_msg_trygetextdict(msg, l);
- upb_value val;
- if (upb_inttable_lookup32(ext_dict, upb_fielddef_number(f), &val)) {
- return upb_msgval_fromval(val);
+ if (upb_msg_inoneof(field)) {
+ if (*upb_msg_oneofcase(msg, field_index, l) == field->number) {
+ size_t ofs = l->data.oneofs[field->oneof_index].data_offset;
+ return upb_msgval_read(msg, ofs, size);
} else {
- return upb_msgval_fromdefault(f);
+ /* Return default. */
+ return upb_msgval_read(l->data.default_msg, field->offset, size);
}
} else {
- size_t ofs = l->field_offsets[upb_fielddef_index(f)];
- const upb_oneofdef *o = upb_fielddef_containingoneof(f);
- upb_msgval ret;
-
- if (o && !upb_msg_oneofis(msg, l, o, f)) {
- /* Oneof defaults can't come from the message because the memory is reused
- * by all types in the oneof. */
- return upb_msgval_fromdefault(f);
- }
-
- ret = upb_msgval_read(msg, ofs, upb_msg_fieldsize(f));
- return ret;
+ return upb_msgval_read(msg, field->offset, size);
}
}
-bool upb_msg_set(upb_msg *msg,
- const upb_fielddef *f,
- upb_msgval val,
+void upb_msg_set(upb_msg *msg, int field_index, upb_msgval val,
const upb_msglayout *l) {
- upb_alloc *a = upb_msg_alloc(msg, l);
- upb_msg_checkfield(l, f);
-
- if (upb_fielddef_isextension(f)) {
- /* TODO(haberman): introduce table API that can do this in one call. */
- upb_inttable *ext = upb_msg_getextdict(msg, l, a);
- upb_value val2 = upb_toval(val);
- if (!upb_inttable_replace(ext, upb_fielddef_number(f), val2) &&
- !upb_inttable_insert2(ext, upb_fielddef_number(f), val2, a)) {
- return false;
- }
- } else {
- size_t ofs = l->field_offsets[upb_fielddef_index(f)];
- const upb_oneofdef *o = upb_fielddef_containingoneof(f);
-
- if (o) {
- upb_msg_setoneofcase(msg, o, l, upb_fielddef_number(f));
- }
+ const upb_msglayout_fieldinit_v1 *field = upb_msg_checkfield(field_index, l);
+ int size = upb_msg_fieldsize(field);
- upb_msgval_write(msg, ofs, val, upb_msg_fieldsize(f));
+ if (upb_msg_inoneof(field)) {
+ size_t ofs = l->data.oneofs[field->oneof_index].data_offset;
+ *upb_msg_oneofcase(msg, field_index, l) = field->number;
+ upb_msgval_write(msg, ofs, val, size);
+ } else {
+ upb_msgval_write(msg, field->offset, val, size);
}
- return true;
}
/** upb_array *****************************************************************/
-struct upb_array {
- upb_fieldtype_t type;
- uint8_t element_size;
- void *data; /* Each element is element_size. */
- size_t len; /* Measured in elements. */
- size_t size; /* Measured in elements. */
- upb_alloc *alloc;
-};
-
#define DEREF_ARR(arr, i, type) ((type*)arr->data)[i]
size_t upb_array_sizeof(upb_fieldtype_t type) {
@@ -3965,8 +4920,8 @@ static void upb_map_tokey(upb_fieldtype_t type, upb_msgval *key,
switch (type) {
case UPB_TYPE_STRING:
/* Point to string data of the input key. */
- *out_key = key->str.ptr;
- *out_len = key->str.len;
+ *out_key = key->str.data;
+ *out_len = key->str.size;
return;
case UPB_TYPE_BOOL:
case UPB_TYPE_INT32:
@@ -3991,7 +4946,7 @@ static upb_msgval upb_map_fromkey(upb_fieldtype_t type, const char *key,
size_t len) {
switch (type) {
case UPB_TYPE_STRING:
- return upb_msgval_str(key, len);
+ return upb_msgval_makestr(key, len);
case UPB_TYPE_BOOL:
case UPB_TYPE_INT32:
case UPB_TYPE_UINT32:
@@ -6451,138 +7406,138 @@ static upb_inttable reftables[268];
#endif
static const upb_msgdef msgs[22] = {
- UPB_MSGDEF_INIT("google.protobuf.DescriptorProto", 40, 8, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[0], 11, 10), UPB_STRTABLE_INIT(10, 15, UPB_CTYPE_PTR, 4, &strentries[0]), false, UPB_SYNTAX_PROTO2, &reftables[0], &reftables[1]),
- UPB_MSGDEF_INIT("google.protobuf.DescriptorProto.ExtensionRange", 4, 0, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[11], 3, 2), UPB_STRTABLE_INIT(2, 3, UPB_CTYPE_PTR, 2, &strentries[16]), false, UPB_SYNTAX_PROTO2, &reftables[2], &reftables[3]),
- UPB_MSGDEF_INIT("google.protobuf.DescriptorProto.ReservedRange", 4, 0, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[14], 3, 2), UPB_STRTABLE_INIT(2, 3, UPB_CTYPE_PTR, 2, &strentries[20]), false, UPB_SYNTAX_PROTO2, &reftables[4], &reftables[5]),
- UPB_MSGDEF_INIT("google.protobuf.EnumDescriptorProto", 11, 2, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[17], 4, 3), UPB_STRTABLE_INIT(3, 3, UPB_CTYPE_PTR, 2, &strentries[24]), false, UPB_SYNTAX_PROTO2, &reftables[6], &reftables[7]),
- UPB_MSGDEF_INIT("google.protobuf.EnumOptions", 8, 1, UPB_INTTABLE_INIT(1, 1, UPB_CTYPE_PTR, 1, &intentries[0], &arrays[21], 4, 2), UPB_STRTABLE_INIT(3, 3, UPB_CTYPE_PTR, 2, &strentries[28]), false, UPB_SYNTAX_PROTO2, &reftables[8], &reftables[9]),
- UPB_MSGDEF_INIT("google.protobuf.EnumValueDescriptorProto", 8, 1, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[25], 4, 3), UPB_STRTABLE_INIT(3, 3, UPB_CTYPE_PTR, 2, &strentries[32]), false, UPB_SYNTAX_PROTO2, &reftables[10], &reftables[11]),
- UPB_MSGDEF_INIT("google.protobuf.EnumValueOptions", 7, 1, UPB_INTTABLE_INIT(1, 1, UPB_CTYPE_PTR, 1, &intentries[2], &arrays[29], 2, 1), UPB_STRTABLE_INIT(2, 3, UPB_CTYPE_PTR, 2, &strentries[36]), false, UPB_SYNTAX_PROTO2, &reftables[12], &reftables[13]),
- UPB_MSGDEF_INIT("google.protobuf.FieldDescriptorProto", 23, 1, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[31], 11, 10), UPB_STRTABLE_INIT(10, 15, UPB_CTYPE_PTR, 4, &strentries[40]), false, UPB_SYNTAX_PROTO2, &reftables[14], &reftables[15]),
- UPB_MSGDEF_INIT("google.protobuf.FieldOptions", 12, 1, UPB_INTTABLE_INIT(1, 1, UPB_CTYPE_PTR, 1, &intentries[4], &arrays[42], 11, 6), UPB_STRTABLE_INIT(7, 15, UPB_CTYPE_PTR, 4, &strentries[56]), false, UPB_SYNTAX_PROTO2, &reftables[16], &reftables[17]),
- UPB_MSGDEF_INIT("google.protobuf.FileDescriptorProto", 42, 6, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[53], 13, 12), UPB_STRTABLE_INIT(12, 15, UPB_CTYPE_PTR, 4, &strentries[72]), false, UPB_SYNTAX_PROTO2, &reftables[18], &reftables[19]),
- UPB_MSGDEF_INIT("google.protobuf.FileDescriptorSet", 6, 1, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[66], 2, 1), UPB_STRTABLE_INIT(1, 3, UPB_CTYPE_PTR, 2, &strentries[88]), false, UPB_SYNTAX_PROTO2, &reftables[20], &reftables[21]),
- UPB_MSGDEF_INIT("google.protobuf.FileOptions", 37, 1, UPB_INTTABLE_INIT(1, 1, UPB_CTYPE_PTR, 1, &intentries[6], &arrays[68], 42, 17), UPB_STRTABLE_INIT(18, 31, UPB_CTYPE_PTR, 5, &strentries[92]), false, UPB_SYNTAX_PROTO2, &reftables[22], &reftables[23]),
- UPB_MSGDEF_INIT("google.protobuf.MessageOptions", 10, 1, UPB_INTTABLE_INIT(1, 1, UPB_CTYPE_PTR, 1, &intentries[8], &arrays[110], 8, 4), UPB_STRTABLE_INIT(5, 7, UPB_CTYPE_PTR, 3, &strentries[124]), false, UPB_SYNTAX_PROTO2, &reftables[24], &reftables[25]),
- UPB_MSGDEF_INIT("google.protobuf.MethodDescriptorProto", 15, 1, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[118], 7, 6), UPB_STRTABLE_INIT(6, 7, UPB_CTYPE_PTR, 3, &strentries[132]), false, UPB_SYNTAX_PROTO2, &reftables[26], &reftables[27]),
- UPB_MSGDEF_INIT("google.protobuf.MethodOptions", 7, 1, UPB_INTTABLE_INIT(2, 3, UPB_CTYPE_PTR, 2, &intentries[10], &arrays[125], 1, 0), UPB_STRTABLE_INIT(2, 3, UPB_CTYPE_PTR, 2, &strentries[140]), false, UPB_SYNTAX_PROTO2, &reftables[28], &reftables[29]),
- UPB_MSGDEF_INIT("google.protobuf.OneofDescriptorProto", 5, 0, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[126], 2, 1), UPB_STRTABLE_INIT(1, 3, UPB_CTYPE_PTR, 2, &strentries[144]), false, UPB_SYNTAX_PROTO2, &reftables[30], &reftables[31]),
- UPB_MSGDEF_INIT("google.protobuf.ServiceDescriptorProto", 11, 2, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[128], 4, 3), UPB_STRTABLE_INIT(3, 3, UPB_CTYPE_PTR, 2, &strentries[148]), false, UPB_SYNTAX_PROTO2, &reftables[32], &reftables[33]),
- UPB_MSGDEF_INIT("google.protobuf.ServiceOptions", 7, 1, UPB_INTTABLE_INIT(2, 3, UPB_CTYPE_PTR, 2, &intentries[14], &arrays[132], 1, 0), UPB_STRTABLE_INIT(2, 3, UPB_CTYPE_PTR, 2, &strentries[152]), false, UPB_SYNTAX_PROTO2, &reftables[34], &reftables[35]),
- UPB_MSGDEF_INIT("google.protobuf.SourceCodeInfo", 6, 1, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[133], 2, 1), UPB_STRTABLE_INIT(1, 3, UPB_CTYPE_PTR, 2, &strentries[156]), false, UPB_SYNTAX_PROTO2, &reftables[36], &reftables[37]),
- UPB_MSGDEF_INIT("google.protobuf.SourceCodeInfo.Location", 19, 0, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[135], 7, 5), UPB_STRTABLE_INIT(5, 7, UPB_CTYPE_PTR, 3, &strentries[160]), false, UPB_SYNTAX_PROTO2, &reftables[38], &reftables[39]),
- UPB_MSGDEF_INIT("google.protobuf.UninterpretedOption", 18, 1, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[142], 9, 7), UPB_STRTABLE_INIT(7, 15, UPB_CTYPE_PTR, 4, &strentries[168]), false, UPB_SYNTAX_PROTO2, &reftables[40], &reftables[41]),
- UPB_MSGDEF_INIT("google.protobuf.UninterpretedOption.NamePart", 6, 0, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[151], 3, 2), UPB_STRTABLE_INIT(2, 3, UPB_CTYPE_PTR, 2, &strentries[184]), false, UPB_SYNTAX_PROTO2, &reftables[42], &reftables[43]),
+ UPB_MSGDEF_INIT("google.protobuf.DescriptorProto", 41, 8, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[0], 11, 10), UPB_STRTABLE_INIT(10, 15, UPB_CTYPE_PTR, 4, &strentries[0]), false, UPB_SYNTAX_PROTO2, &reftables[0], &reftables[1]),
+ UPB_MSGDEF_INIT("google.protobuf.DescriptorProto.ExtensionRange", 5, 0, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[11], 3, 2), UPB_STRTABLE_INIT(2, 3, UPB_CTYPE_PTR, 2, &strentries[16]), false, UPB_SYNTAX_PROTO2, &reftables[2], &reftables[3]),
+ UPB_MSGDEF_INIT("google.protobuf.DescriptorProto.ReservedRange", 5, 0, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[14], 3, 2), UPB_STRTABLE_INIT(2, 3, UPB_CTYPE_PTR, 2, &strentries[20]), false, UPB_SYNTAX_PROTO2, &reftables[4], &reftables[5]),
+ UPB_MSGDEF_INIT("google.protobuf.EnumDescriptorProto", 12, 2, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[17], 4, 3), UPB_STRTABLE_INIT(3, 3, UPB_CTYPE_PTR, 2, &strentries[24]), false, UPB_SYNTAX_PROTO2, &reftables[6], &reftables[7]),
+ UPB_MSGDEF_INIT("google.protobuf.EnumOptions", 9, 1, UPB_INTTABLE_INIT(1, 1, UPB_CTYPE_PTR, 1, &intentries[0], &arrays[21], 4, 2), UPB_STRTABLE_INIT(3, 3, UPB_CTYPE_PTR, 2, &strentries[28]), false, UPB_SYNTAX_PROTO2, &reftables[8], &reftables[9]),
+ UPB_MSGDEF_INIT("google.protobuf.EnumValueDescriptorProto", 9, 1, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[25], 4, 3), UPB_STRTABLE_INIT(3, 3, UPB_CTYPE_PTR, 2, &strentries[32]), false, UPB_SYNTAX_PROTO2, &reftables[10], &reftables[11]),
+ UPB_MSGDEF_INIT("google.protobuf.EnumValueOptions", 8, 1, UPB_INTTABLE_INIT(1, 1, UPB_CTYPE_PTR, 1, &intentries[2], &arrays[29], 2, 1), UPB_STRTABLE_INIT(2, 3, UPB_CTYPE_PTR, 2, &strentries[36]), false, UPB_SYNTAX_PROTO2, &reftables[12], &reftables[13]),
+ UPB_MSGDEF_INIT("google.protobuf.FieldDescriptorProto", 24, 1, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[31], 11, 10), UPB_STRTABLE_INIT(10, 15, UPB_CTYPE_PTR, 4, &strentries[40]), false, UPB_SYNTAX_PROTO2, &reftables[14], &reftables[15]),
+ UPB_MSGDEF_INIT("google.protobuf.FieldOptions", 13, 1, UPB_INTTABLE_INIT(1, 1, UPB_CTYPE_PTR, 1, &intentries[4], &arrays[42], 11, 6), UPB_STRTABLE_INIT(7, 15, UPB_CTYPE_PTR, 4, &strentries[56]), false, UPB_SYNTAX_PROTO2, &reftables[16], &reftables[17]),
+ UPB_MSGDEF_INIT("google.protobuf.FileDescriptorProto", 43, 6, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[53], 13, 12), UPB_STRTABLE_INIT(12, 15, UPB_CTYPE_PTR, 4, &strentries[72]), false, UPB_SYNTAX_PROTO2, &reftables[18], &reftables[19]),
+ UPB_MSGDEF_INIT("google.protobuf.FileDescriptorSet", 7, 1, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[66], 2, 1), UPB_STRTABLE_INIT(1, 3, UPB_CTYPE_PTR, 2, &strentries[88]), false, UPB_SYNTAX_PROTO2, &reftables[20], &reftables[21]),
+ UPB_MSGDEF_INIT("google.protobuf.FileOptions", 38, 1, UPB_INTTABLE_INIT(1, 1, UPB_CTYPE_PTR, 1, &intentries[6], &arrays[68], 42, 17), UPB_STRTABLE_INIT(18, 31, UPB_CTYPE_PTR, 5, &strentries[92]), false, UPB_SYNTAX_PROTO2, &reftables[22], &reftables[23]),
+ UPB_MSGDEF_INIT("google.protobuf.MessageOptions", 11, 1, UPB_INTTABLE_INIT(1, 1, UPB_CTYPE_PTR, 1, &intentries[8], &arrays[110], 8, 4), UPB_STRTABLE_INIT(5, 7, UPB_CTYPE_PTR, 3, &strentries[124]), false, UPB_SYNTAX_PROTO2, &reftables[24], &reftables[25]),
+ UPB_MSGDEF_INIT("google.protobuf.MethodDescriptorProto", 16, 1, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[118], 7, 6), UPB_STRTABLE_INIT(6, 7, UPB_CTYPE_PTR, 3, &strentries[132]), false, UPB_SYNTAX_PROTO2, &reftables[26], &reftables[27]),
+ UPB_MSGDEF_INIT("google.protobuf.MethodOptions", 8, 1, UPB_INTTABLE_INIT(2, 3, UPB_CTYPE_PTR, 2, &intentries[10], &arrays[125], 1, 0), UPB_STRTABLE_INIT(2, 3, UPB_CTYPE_PTR, 2, &strentries[140]), false, UPB_SYNTAX_PROTO2, &reftables[28], &reftables[29]),
+ UPB_MSGDEF_INIT("google.protobuf.OneofDescriptorProto", 6, 0, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[126], 2, 1), UPB_STRTABLE_INIT(1, 3, UPB_CTYPE_PTR, 2, &strentries[144]), false, UPB_SYNTAX_PROTO2, &reftables[30], &reftables[31]),
+ UPB_MSGDEF_INIT("google.protobuf.ServiceDescriptorProto", 12, 2, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[128], 4, 3), UPB_STRTABLE_INIT(3, 3, UPB_CTYPE_PTR, 2, &strentries[148]), false, UPB_SYNTAX_PROTO2, &reftables[32], &reftables[33]),
+ UPB_MSGDEF_INIT("google.protobuf.ServiceOptions", 8, 1, UPB_INTTABLE_INIT(2, 3, UPB_CTYPE_PTR, 2, &intentries[14], &arrays[132], 1, 0), UPB_STRTABLE_INIT(2, 3, UPB_CTYPE_PTR, 2, &strentries[152]), false, UPB_SYNTAX_PROTO2, &reftables[34], &reftables[35]),
+ UPB_MSGDEF_INIT("google.protobuf.SourceCodeInfo", 7, 1, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[133], 2, 1), UPB_STRTABLE_INIT(1, 3, UPB_CTYPE_PTR, 2, &strentries[156]), false, UPB_SYNTAX_PROTO2, &reftables[36], &reftables[37]),
+ UPB_MSGDEF_INIT("google.protobuf.SourceCodeInfo.Location", 20, 0, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[135], 7, 5), UPB_STRTABLE_INIT(5, 7, UPB_CTYPE_PTR, 3, &strentries[160]), false, UPB_SYNTAX_PROTO2, &reftables[38], &reftables[39]),
+ UPB_MSGDEF_INIT("google.protobuf.UninterpretedOption", 19, 1, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[142], 9, 7), UPB_STRTABLE_INIT(7, 15, UPB_CTYPE_PTR, 4, &strentries[168]), false, UPB_SYNTAX_PROTO2, &reftables[40], &reftables[41]),
+ UPB_MSGDEF_INIT("google.protobuf.UninterpretedOption.NamePart", 7, 0, UPB_INTTABLE_INIT(0, 0, UPB_CTYPE_PTR, 0, NULL, &arrays[151], 3, 2), UPB_STRTABLE_INIT(2, 3, UPB_CTYPE_PTR, 2, &strentries[184]), false, UPB_SYNTAX_PROTO2, &reftables[42], &reftables[43]),
};
static const upb_fielddef fields[107] = {
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "aggregate_value", 8, &msgs[20], NULL, 15, 6, {0},&reftables[44], &reftables[45]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "allow_alias", 2, &msgs[4], NULL, 6, 1, {0},&reftables[46], &reftables[47]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "cc_enable_arenas", 31, &msgs[11], NULL, 23, 12, {0},&reftables[48], &reftables[49]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "cc_generic_services", 16, &msgs[11], NULL, 17, 6, {0},&reftables[50], &reftables[51]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "client_streaming", 5, &msgs[13], NULL, 13, 4, {0},&reftables[52], &reftables[53]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "csharp_namespace", 37, &msgs[11], NULL, 27, 14, {0},&reftables[54], &reftables[55]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_ENUM, 0, false, false, false, false, "ctype", 1, &msgs[8], (const upb_def*)(&enums[2]), 6, 1, {0},&reftables[56], &reftables[57]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "default_value", 7, &msgs[7], NULL, 16, 7, {0},&reftables[58], &reftables[59]),
- UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_STRING, 0, false, false, false, false, "dependency", 3, &msgs[9], NULL, 30, 8, {0},&reftables[60], &reftables[61]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "deprecated", 3, &msgs[8], NULL, 8, 3, {0},&reftables[62], &reftables[63]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "deprecated", 33, &msgs[14], NULL, 6, 1, {0},&reftables[64], &reftables[65]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "deprecated", 3, &msgs[12], NULL, 8, 3, {0},&reftables[66], &reftables[67]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "deprecated", 23, &msgs[11], NULL, 21, 10, {0},&reftables[68], &reftables[69]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "deprecated", 1, &msgs[6], NULL, 6, 1, {0},&reftables[70], &reftables[71]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "deprecated", 3, &msgs[4], NULL, 7, 2, {0},&reftables[72], &reftables[73]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "deprecated", 33, &msgs[17], NULL, 6, 1, {0},&reftables[74], &reftables[75]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_DOUBLE, 0, false, false, false, false, "double_value", 6, &msgs[20], NULL, 11, 4, {0},&reftables[76], &reftables[77]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_INT32, UPB_INTFMT_VARIABLE, false, false, false, false, "end", 2, &msgs[2], NULL, 3, 1, {0},&reftables[78], &reftables[79]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_INT32, UPB_INTFMT_VARIABLE, false, false, false, false, "end", 2, &msgs[1], NULL, 3, 1, {0},&reftables[80], &reftables[81]),
- UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "enum_type", 5, &msgs[9], (const upb_def*)(&msgs[3]), 13, 1, {0},&reftables[82], &reftables[83]),
- UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "enum_type", 4, &msgs[0], (const upb_def*)(&msgs[3]), 18, 2, {0},&reftables[84], &reftables[85]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "extendee", 2, &msgs[7], NULL, 7, 2, {0},&reftables[86], &reftables[87]),
- UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "extension", 6, &msgs[0], (const upb_def*)(&msgs[7]), 24, 4, {0},&reftables[88], &reftables[89]),
- UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "extension", 7, &msgs[9], (const upb_def*)(&msgs[7]), 19, 3, {0},&reftables[90], &reftables[91]),
- UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "extension_range", 5, &msgs[0], (const upb_def*)(&msgs[1]), 21, 3, {0},&reftables[92], &reftables[93]),
- UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "field", 2, &msgs[0], (const upb_def*)(&msgs[7]), 12, 0, {0},&reftables[94], &reftables[95]),
- UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "file", 1, &msgs[10], (const upb_def*)(&msgs[9]), 5, 0, {0},&reftables[96], &reftables[97]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "go_package", 11, &msgs[11], NULL, 14, 5, {0},&reftables[98], &reftables[99]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "identifier_value", 3, &msgs[20], NULL, 6, 1, {0},&reftables[100], &reftables[101]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "input_type", 2, &msgs[13], NULL, 7, 2, {0},&reftables[102], &reftables[103]),
- UPB_FIELDDEF_INIT(UPB_LABEL_REQUIRED, UPB_TYPE_BOOL, 0, false, false, false, false, "is_extension", 2, &msgs[21], NULL, 5, 1, {0},&reftables[104], &reftables[105]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "java_generate_equals_and_hash", 20, &msgs[11], NULL, 20, 9, {0},&reftables[106], &reftables[107]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "java_generic_services", 17, &msgs[11], NULL, 18, 7, {0},&reftables[108], &reftables[109]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "java_multiple_files", 10, &msgs[11], NULL, 13, 4, {0},&reftables[110], &reftables[111]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "java_outer_classname", 8, &msgs[11], NULL, 9, 2, {0},&reftables[112], &reftables[113]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "java_package", 1, &msgs[11], NULL, 6, 1, {0},&reftables[114], &reftables[115]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "java_string_check_utf8", 27, &msgs[11], NULL, 22, 11, {0},&reftables[116], &reftables[117]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "javanano_use_deprecated_package", 38, &msgs[11], NULL, 30, 15, {0},&reftables[118], &reftables[119]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "json_name", 10, &msgs[7], NULL, 20, 9, {0},&reftables[120], &reftables[121]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_ENUM, 0, false, false, false, false, "jstype", 6, &msgs[8], (const upb_def*)(&enums[3]), 10, 5, {0},&reftables[122], &reftables[123]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_ENUM, 0, false, false, false, false, "label", 4, &msgs[7], (const upb_def*)(&enums[0]), 11, 4, {0},&reftables[124], &reftables[125]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "lazy", 5, &msgs[8], NULL, 9, 4, {0},&reftables[126], &reftables[127]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "leading_comments", 3, &msgs[19], NULL, 8, 2, {0},&reftables[128], &reftables[129]),
- UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_STRING, 0, false, false, false, false, "leading_detached_comments", 6, &msgs[19], NULL, 16, 4, {0},&reftables[130], &reftables[131]),
- UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "location", 1, &msgs[18], (const upb_def*)(&msgs[19]), 5, 0, {0},&reftables[132], &reftables[133]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "map_entry", 7, &msgs[12], NULL, 9, 4, {0},&reftables[134], &reftables[135]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "message_set_wire_format", 1, &msgs[12], NULL, 6, 1, {0},&reftables[136], &reftables[137]),
- UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "message_type", 4, &msgs[9], (const upb_def*)(&msgs[0]), 10, 0, {0},&reftables[138], &reftables[139]),
- UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "method", 2, &msgs[16], (const upb_def*)(&msgs[13]), 6, 0, {0},&reftables[140], &reftables[141]),
- UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "name", 2, &msgs[20], (const upb_def*)(&msgs[21]), 5, 0, {0},&reftables[142], &reftables[143]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "name", 1, &msgs[5], NULL, 4, 1, {0},&reftables[144], &reftables[145]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "name", 1, &msgs[9], NULL, 22, 6, {0},&reftables[146], &reftables[147]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "name", 1, &msgs[3], NULL, 8, 2, {0},&reftables[148], &reftables[149]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "name", 1, &msgs[16], NULL, 8, 2, {0},&reftables[150], &reftables[151]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "name", 1, &msgs[15], NULL, 2, 0, {0},&reftables[152], &reftables[153]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "name", 1, &msgs[13], NULL, 4, 1, {0},&reftables[154], &reftables[155]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "name", 1, &msgs[7], NULL, 4, 1, {0},&reftables[156], &reftables[157]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "name", 1, &msgs[0], NULL, 32, 8, {0},&reftables[158], &reftables[159]),
- UPB_FIELDDEF_INIT(UPB_LABEL_REQUIRED, UPB_TYPE_STRING, 0, false, false, false, false, "name_part", 1, &msgs[21], NULL, 2, 0, {0},&reftables[160], &reftables[161]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_INT64, UPB_INTFMT_VARIABLE, false, false, false, false, "negative_int_value", 5, &msgs[20], NULL, 10, 3, {0},&reftables[162], &reftables[163]),
- UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "nested_type", 3, &msgs[0], (const upb_def*)(&msgs[0]), 15, 1, {0},&reftables[164], &reftables[165]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "no_standard_descriptor_accessor", 2, &msgs[12], NULL, 7, 2, {0},&reftables[166], &reftables[167]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_INT32, UPB_INTFMT_VARIABLE, false, false, false, false, "number", 3, &msgs[7], NULL, 10, 3, {0},&reftables[168], &reftables[169]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_INT32, UPB_INTFMT_VARIABLE, false, false, false, false, "number", 2, &msgs[5], NULL, 7, 2, {0},&reftables[170], &reftables[171]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "objc_class_prefix", 36, &msgs[11], NULL, 24, 13, {0},&reftables[172], &reftables[173]),
- UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "oneof_decl", 8, &msgs[0], (const upb_def*)(&msgs[15]), 28, 6, {0},&reftables[174], &reftables[175]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_INT32, UPB_INTFMT_VARIABLE, false, false, false, false, "oneof_index", 9, &msgs[7], NULL, 19, 8, {0},&reftables[176], &reftables[177]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_ENUM, 0, false, false, false, false, "optimize_for", 9, &msgs[11], (const upb_def*)(&enums[4]), 12, 3, {0},&reftables[178], &reftables[179]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_MESSAGE, 0, false, false, false, false, "options", 7, &msgs[0], (const upb_def*)(&msgs[12]), 25, 5, {0},&reftables[180], &reftables[181]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_MESSAGE, 0, false, false, false, false, "options", 8, &msgs[9], (const upb_def*)(&msgs[11]), 20, 4, {0},&reftables[182], &reftables[183]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_MESSAGE, 0, false, false, false, false, "options", 8, &msgs[7], (const upb_def*)(&msgs[8]), 3, 0, {0},&reftables[184], &reftables[185]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_MESSAGE, 0, false, false, false, false, "options", 4, &msgs[13], (const upb_def*)(&msgs[14]), 3, 0, {0},&reftables[186], &reftables[187]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_MESSAGE, 0, false, false, false, false, "options", 3, &msgs[16], (const upb_def*)(&msgs[17]), 7, 1, {0},&reftables[188], &reftables[189]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_MESSAGE, 0, false, false, false, false, "options", 3, &msgs[3], (const upb_def*)(&msgs[4]), 7, 1, {0},&reftables[190], &reftables[191]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_MESSAGE, 0, false, false, false, false, "options", 3, &msgs[5], (const upb_def*)(&msgs[6]), 3, 0, {0},&reftables[192], &reftables[193]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "output_type", 3, &msgs[13], NULL, 10, 3, {0},&reftables[194], &reftables[195]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "package", 2, &msgs[9], NULL, 25, 7, {0},&reftables[196], &reftables[197]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "packed", 2, &msgs[8], NULL, 7, 2, {0},&reftables[198], &reftables[199]),
- UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_INT32, UPB_INTFMT_VARIABLE, false, false, false, true, "path", 1, &msgs[19], NULL, 4, 0, {0},&reftables[200], &reftables[201]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "php_class_prefix", 40, &msgs[11], NULL, 31, 16, {0},&reftables[202], &reftables[203]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "php_namespace", 41, &msgs[11], NULL, 34, 17, {0},&reftables[204], &reftables[205]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_UINT64, UPB_INTFMT_VARIABLE, false, false, false, false, "positive_int_value", 4, &msgs[20], NULL, 9, 2, {0},&reftables[206], &reftables[207]),
- UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_INT32, UPB_INTFMT_VARIABLE, false, false, false, false, "public_dependency", 10, &msgs[9], NULL, 35, 9, {0},&reftables[208], &reftables[209]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "py_generic_services", 18, &msgs[11], NULL, 19, 8, {0},&reftables[210], &reftables[211]),
- UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_STRING, 0, false, false, false, false, "reserved_name", 10, &msgs[0], NULL, 37, 9, {0},&reftables[212], &reftables[213]),
- UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "reserved_range", 9, &msgs[0], (const upb_def*)(&msgs[2]), 31, 7, {0},&reftables[214], &reftables[215]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "server_streaming", 6, &msgs[13], NULL, 14, 5, {0},&reftables[216], &reftables[217]),
- UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "service", 6, &msgs[9], (const upb_def*)(&msgs[16]), 16, 2, {0},&reftables[218], &reftables[219]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_MESSAGE, 0, false, false, false, false, "source_code_info", 9, &msgs[9], (const upb_def*)(&msgs[18]), 21, 5, {0},&reftables[220], &reftables[221]),
- UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_INT32, UPB_INTFMT_VARIABLE, false, false, false, true, "span", 2, &msgs[19], NULL, 7, 1, {0},&reftables[222], &reftables[223]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_INT32, UPB_INTFMT_VARIABLE, false, false, false, false, "start", 1, &msgs[2], NULL, 2, 0, {0},&reftables[224], &reftables[225]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_INT32, UPB_INTFMT_VARIABLE, false, false, false, false, "start", 1, &msgs[1], NULL, 2, 0, {0},&reftables[226], &reftables[227]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BYTES, 0, false, false, false, false, "string_value", 7, &msgs[20], NULL, 12, 5, {0},&reftables[228], &reftables[229]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "syntax", 12, &msgs[9], NULL, 39, 11, {0},&reftables[230], &reftables[231]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "trailing_comments", 4, &msgs[19], NULL, 11, 3, {0},&reftables[232], &reftables[233]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_ENUM, 0, false, false, false, false, "type", 5, &msgs[7], (const upb_def*)(&enums[1]), 12, 5, {0},&reftables[234], &reftables[235]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "type_name", 6, &msgs[7], NULL, 13, 6, {0},&reftables[236], &reftables[237]),
- UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "uninterpreted_option", 999, &msgs[12], (const upb_def*)(&msgs[20]), 5, 0, {0},&reftables[238], &reftables[239]),
- UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "uninterpreted_option", 999, &msgs[17], (const upb_def*)(&msgs[20]), 5, 0, {0},&reftables[240], &reftables[241]),
- UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "uninterpreted_option", 999, &msgs[11], (const upb_def*)(&msgs[20]), 5, 0, {0},&reftables[242], &reftables[243]),
- UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "uninterpreted_option", 999, &msgs[14], (const upb_def*)(&msgs[20]), 5, 0, {0},&reftables[244], &reftables[245]),
- UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "uninterpreted_option", 999, &msgs[8], (const upb_def*)(&msgs[20]), 5, 0, {0},&reftables[246], &reftables[247]),
- UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "uninterpreted_option", 999, &msgs[6], (const upb_def*)(&msgs[20]), 5, 0, {0},&reftables[248], &reftables[249]),
- UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "uninterpreted_option", 999, &msgs[4], (const upb_def*)(&msgs[20]), 5, 0, {0},&reftables[250], &reftables[251]),
- UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "value", 2, &msgs[3], (const upb_def*)(&msgs[5]), 6, 0, {0},&reftables[252], &reftables[253]),
- UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "weak", 10, &msgs[8], NULL, 11, 6, {0},&reftables[254], &reftables[255]),
- UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_INT32, UPB_INTFMT_VARIABLE, false, false, false, false, "weak_dependency", 11, &msgs[9], NULL, 38, 10, {0},&reftables[256], &reftables[257]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "aggregate_value", 8, &msgs[20], NULL, 16, 6, {0},&reftables[44], &reftables[45]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "allow_alias", 2, &msgs[4], NULL, 7, 1, {0},&reftables[46], &reftables[47]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "cc_enable_arenas", 31, &msgs[11], NULL, 24, 12, {0},&reftables[48], &reftables[49]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "cc_generic_services", 16, &msgs[11], NULL, 18, 6, {0},&reftables[50], &reftables[51]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "client_streaming", 5, &msgs[13], NULL, 14, 4, {0},&reftables[52], &reftables[53]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "csharp_namespace", 37, &msgs[11], NULL, 28, 14, {0},&reftables[54], &reftables[55]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_ENUM, 0, false, false, false, false, "ctype", 1, &msgs[8], (const upb_def*)(&enums[2]), 7, 1, {0},&reftables[56], &reftables[57]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "default_value", 7, &msgs[7], NULL, 17, 7, {0},&reftables[58], &reftables[59]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_STRING, 0, false, false, false, false, "dependency", 3, &msgs[9], NULL, 31, 8, {0},&reftables[60], &reftables[61]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "deprecated", 3, &msgs[8], NULL, 9, 3, {0},&reftables[62], &reftables[63]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "deprecated", 33, &msgs[14], NULL, 7, 1, {0},&reftables[64], &reftables[65]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "deprecated", 3, &msgs[12], NULL, 9, 3, {0},&reftables[66], &reftables[67]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "deprecated", 23, &msgs[11], NULL, 22, 10, {0},&reftables[68], &reftables[69]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "deprecated", 1, &msgs[6], NULL, 7, 1, {0},&reftables[70], &reftables[71]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "deprecated", 3, &msgs[4], NULL, 8, 2, {0},&reftables[72], &reftables[73]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "deprecated", 33, &msgs[17], NULL, 7, 1, {0},&reftables[74], &reftables[75]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_DOUBLE, 0, false, false, false, false, "double_value", 6, &msgs[20], NULL, 12, 4, {0},&reftables[76], &reftables[77]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_INT32, UPB_INTFMT_VARIABLE, false, false, false, false, "end", 2, &msgs[2], NULL, 4, 1, {0},&reftables[78], &reftables[79]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_INT32, UPB_INTFMT_VARIABLE, false, false, false, false, "end", 2, &msgs[1], NULL, 4, 1, {0},&reftables[80], &reftables[81]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "enum_type", 5, &msgs[9], (const upb_def*)(&msgs[3]), 14, 1, {0},&reftables[82], &reftables[83]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "enum_type", 4, &msgs[0], (const upb_def*)(&msgs[3]), 19, 2, {0},&reftables[84], &reftables[85]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "extendee", 2, &msgs[7], NULL, 8, 2, {0},&reftables[86], &reftables[87]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "extension", 6, &msgs[0], (const upb_def*)(&msgs[7]), 25, 4, {0},&reftables[88], &reftables[89]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "extension", 7, &msgs[9], (const upb_def*)(&msgs[7]), 20, 3, {0},&reftables[90], &reftables[91]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "extension_range", 5, &msgs[0], (const upb_def*)(&msgs[1]), 22, 3, {0},&reftables[92], &reftables[93]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "field", 2, &msgs[0], (const upb_def*)(&msgs[7]), 13, 0, {0},&reftables[94], &reftables[95]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "file", 1, &msgs[10], (const upb_def*)(&msgs[9]), 6, 0, {0},&reftables[96], &reftables[97]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "go_package", 11, &msgs[11], NULL, 15, 5, {0},&reftables[98], &reftables[99]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "identifier_value", 3, &msgs[20], NULL, 7, 1, {0},&reftables[100], &reftables[101]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "input_type", 2, &msgs[13], NULL, 8, 2, {0},&reftables[102], &reftables[103]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_REQUIRED, UPB_TYPE_BOOL, 0, false, false, false, false, "is_extension", 2, &msgs[21], NULL, 6, 1, {0},&reftables[104], &reftables[105]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "java_generate_equals_and_hash", 20, &msgs[11], NULL, 21, 9, {0},&reftables[106], &reftables[107]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "java_generic_services", 17, &msgs[11], NULL, 19, 7, {0},&reftables[108], &reftables[109]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "java_multiple_files", 10, &msgs[11], NULL, 14, 4, {0},&reftables[110], &reftables[111]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "java_outer_classname", 8, &msgs[11], NULL, 10, 2, {0},&reftables[112], &reftables[113]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "java_package", 1, &msgs[11], NULL, 7, 1, {0},&reftables[114], &reftables[115]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "java_string_check_utf8", 27, &msgs[11], NULL, 23, 11, {0},&reftables[116], &reftables[117]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "javanano_use_deprecated_package", 38, &msgs[11], NULL, 31, 15, {0},&reftables[118], &reftables[119]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "json_name", 10, &msgs[7], NULL, 21, 9, {0},&reftables[120], &reftables[121]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_ENUM, 0, false, false, false, false, "jstype", 6, &msgs[8], (const upb_def*)(&enums[3]), 11, 5, {0},&reftables[122], &reftables[123]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_ENUM, 0, false, false, false, false, "label", 4, &msgs[7], (const upb_def*)(&enums[0]), 12, 4, {0},&reftables[124], &reftables[125]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "lazy", 5, &msgs[8], NULL, 10, 4, {0},&reftables[126], &reftables[127]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "leading_comments", 3, &msgs[19], NULL, 9, 2, {0},&reftables[128], &reftables[129]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_STRING, 0, false, false, false, false, "leading_detached_comments", 6, &msgs[19], NULL, 17, 4, {0},&reftables[130], &reftables[131]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "location", 1, &msgs[18], (const upb_def*)(&msgs[19]), 6, 0, {0},&reftables[132], &reftables[133]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "map_entry", 7, &msgs[12], NULL, 10, 4, {0},&reftables[134], &reftables[135]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "message_set_wire_format", 1, &msgs[12], NULL, 7, 1, {0},&reftables[136], &reftables[137]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "message_type", 4, &msgs[9], (const upb_def*)(&msgs[0]), 11, 0, {0},&reftables[138], &reftables[139]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "method", 2, &msgs[16], (const upb_def*)(&msgs[13]), 7, 0, {0},&reftables[140], &reftables[141]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "name", 2, &msgs[20], (const upb_def*)(&msgs[21]), 6, 0, {0},&reftables[142], &reftables[143]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "name", 1, &msgs[5], NULL, 5, 1, {0},&reftables[144], &reftables[145]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "name", 1, &msgs[9], NULL, 23, 6, {0},&reftables[146], &reftables[147]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "name", 1, &msgs[3], NULL, 9, 2, {0},&reftables[148], &reftables[149]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "name", 1, &msgs[16], NULL, 9, 2, {0},&reftables[150], &reftables[151]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "name", 1, &msgs[15], NULL, 3, 0, {0},&reftables[152], &reftables[153]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "name", 1, &msgs[13], NULL, 5, 1, {0},&reftables[154], &reftables[155]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "name", 1, &msgs[7], NULL, 5, 1, {0},&reftables[156], &reftables[157]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "name", 1, &msgs[0], NULL, 33, 8, {0},&reftables[158], &reftables[159]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_REQUIRED, UPB_TYPE_STRING, 0, false, false, false, false, "name_part", 1, &msgs[21], NULL, 3, 0, {0},&reftables[160], &reftables[161]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_INT64, UPB_INTFMT_VARIABLE, false, false, false, false, "negative_int_value", 5, &msgs[20], NULL, 11, 3, {0},&reftables[162], &reftables[163]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "nested_type", 3, &msgs[0], (const upb_def*)(&msgs[0]), 16, 1, {0},&reftables[164], &reftables[165]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "no_standard_descriptor_accessor", 2, &msgs[12], NULL, 8, 2, {0},&reftables[166], &reftables[167]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_INT32, UPB_INTFMT_VARIABLE, false, false, false, false, "number", 3, &msgs[7], NULL, 11, 3, {0},&reftables[168], &reftables[169]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_INT32, UPB_INTFMT_VARIABLE, false, false, false, false, "number", 2, &msgs[5], NULL, 8, 2, {0},&reftables[170], &reftables[171]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "objc_class_prefix", 36, &msgs[11], NULL, 25, 13, {0},&reftables[172], &reftables[173]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "oneof_decl", 8, &msgs[0], (const upb_def*)(&msgs[15]), 29, 6, {0},&reftables[174], &reftables[175]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_INT32, UPB_INTFMT_VARIABLE, false, false, false, false, "oneof_index", 9, &msgs[7], NULL, 20, 8, {0},&reftables[176], &reftables[177]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_ENUM, 0, false, false, false, false, "optimize_for", 9, &msgs[11], (const upb_def*)(&enums[4]), 13, 3, {0},&reftables[178], &reftables[179]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_MESSAGE, 0, false, false, false, false, "options", 7, &msgs[0], (const upb_def*)(&msgs[12]), 26, 5, {0},&reftables[180], &reftables[181]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_MESSAGE, 0, false, false, false, false, "options", 8, &msgs[9], (const upb_def*)(&msgs[11]), 21, 4, {0},&reftables[182], &reftables[183]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_MESSAGE, 0, false, false, false, false, "options", 8, &msgs[7], (const upb_def*)(&msgs[8]), 4, 0, {0},&reftables[184], &reftables[185]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_MESSAGE, 0, false, false, false, false, "options", 4, &msgs[13], (const upb_def*)(&msgs[14]), 4, 0, {0},&reftables[186], &reftables[187]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_MESSAGE, 0, false, false, false, false, "options", 3, &msgs[16], (const upb_def*)(&msgs[17]), 8, 1, {0},&reftables[188], &reftables[189]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_MESSAGE, 0, false, false, false, false, "options", 3, &msgs[3], (const upb_def*)(&msgs[4]), 8, 1, {0},&reftables[190], &reftables[191]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_MESSAGE, 0, false, false, false, false, "options", 3, &msgs[5], (const upb_def*)(&msgs[6]), 4, 0, {0},&reftables[192], &reftables[193]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "output_type", 3, &msgs[13], NULL, 11, 3, {0},&reftables[194], &reftables[195]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "package", 2, &msgs[9], NULL, 26, 7, {0},&reftables[196], &reftables[197]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "packed", 2, &msgs[8], NULL, 8, 2, {0},&reftables[198], &reftables[199]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_INT32, UPB_INTFMT_VARIABLE, false, false, false, true, "path", 1, &msgs[19], NULL, 5, 0, {0},&reftables[200], &reftables[201]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "php_class_prefix", 40, &msgs[11], NULL, 32, 16, {0},&reftables[202], &reftables[203]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "php_namespace", 41, &msgs[11], NULL, 35, 17, {0},&reftables[204], &reftables[205]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_UINT64, UPB_INTFMT_VARIABLE, false, false, false, false, "positive_int_value", 4, &msgs[20], NULL, 10, 2, {0},&reftables[206], &reftables[207]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_INT32, UPB_INTFMT_VARIABLE, false, false, false, false, "public_dependency", 10, &msgs[9], NULL, 36, 9, {0},&reftables[208], &reftables[209]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "py_generic_services", 18, &msgs[11], NULL, 20, 8, {0},&reftables[210], &reftables[211]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_STRING, 0, false, false, false, false, "reserved_name", 10, &msgs[0], NULL, 38, 9, {0},&reftables[212], &reftables[213]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "reserved_range", 9, &msgs[0], (const upb_def*)(&msgs[2]), 32, 7, {0},&reftables[214], &reftables[215]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "server_streaming", 6, &msgs[13], NULL, 15, 5, {0},&reftables[216], &reftables[217]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "service", 6, &msgs[9], (const upb_def*)(&msgs[16]), 17, 2, {0},&reftables[218], &reftables[219]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_MESSAGE, 0, false, false, false, false, "source_code_info", 9, &msgs[9], (const upb_def*)(&msgs[18]), 22, 5, {0},&reftables[220], &reftables[221]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_INT32, UPB_INTFMT_VARIABLE, false, false, false, true, "span", 2, &msgs[19], NULL, 8, 1, {0},&reftables[222], &reftables[223]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_INT32, UPB_INTFMT_VARIABLE, false, false, false, false, "start", 1, &msgs[2], NULL, 3, 0, {0},&reftables[224], &reftables[225]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_INT32, UPB_INTFMT_VARIABLE, false, false, false, false, "start", 1, &msgs[1], NULL, 3, 0, {0},&reftables[226], &reftables[227]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BYTES, 0, false, false, false, false, "string_value", 7, &msgs[20], NULL, 13, 5, {0},&reftables[228], &reftables[229]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "syntax", 12, &msgs[9], NULL, 40, 11, {0},&reftables[230], &reftables[231]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "trailing_comments", 4, &msgs[19], NULL, 12, 3, {0},&reftables[232], &reftables[233]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_ENUM, 0, false, false, false, false, "type", 5, &msgs[7], (const upb_def*)(&enums[1]), 13, 5, {0},&reftables[234], &reftables[235]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_STRING, 0, false, false, false, false, "type_name", 6, &msgs[7], NULL, 14, 6, {0},&reftables[236], &reftables[237]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "uninterpreted_option", 999, &msgs[12], (const upb_def*)(&msgs[20]), 6, 0, {0},&reftables[238], &reftables[239]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "uninterpreted_option", 999, &msgs[17], (const upb_def*)(&msgs[20]), 6, 0, {0},&reftables[240], &reftables[241]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "uninterpreted_option", 999, &msgs[11], (const upb_def*)(&msgs[20]), 6, 0, {0},&reftables[242], &reftables[243]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "uninterpreted_option", 999, &msgs[14], (const upb_def*)(&msgs[20]), 6, 0, {0},&reftables[244], &reftables[245]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "uninterpreted_option", 999, &msgs[8], (const upb_def*)(&msgs[20]), 6, 0, {0},&reftables[246], &reftables[247]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "uninterpreted_option", 999, &msgs[6], (const upb_def*)(&msgs[20]), 6, 0, {0},&reftables[248], &reftables[249]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "uninterpreted_option", 999, &msgs[4], (const upb_def*)(&msgs[20]), 6, 0, {0},&reftables[250], &reftables[251]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_MESSAGE, 0, false, false, false, false, "value", 2, &msgs[3], (const upb_def*)(&msgs[5]), 7, 0, {0},&reftables[252], &reftables[253]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_OPTIONAL, UPB_TYPE_BOOL, 0, false, false, false, false, "weak", 10, &msgs[8], NULL, 12, 6, {0},&reftables[254], &reftables[255]),
+ UPB_FIELDDEF_INIT(UPB_LABEL_REPEATED, UPB_TYPE_INT32, UPB_INTFMT_VARIABLE, false, false, false, false, "weak_dependency", 11, &msgs[9], NULL, 39, 10, {0},&reftables[256], &reftables[257]),
};
static const upb_enumdef enums[5] = {
@@ -7401,6 +8356,7 @@ typedef struct {
struct upb_descreader {
upb_sink sink;
upb_inttable files;
+ upb_strtable files_by_name;
upb_filedef *file; /* The last file in files. */
upb_descreader_frame stack[UPB_MAX_MESSAGE_NESTING];
int stack_len;
@@ -7567,6 +8523,7 @@ static size_t file_onname(void *closure, const void *hd, const char *buf,
UPB_UNUSED(handle);
name = upb_gstrndup(buf, n);
+ upb_strtable_insert(&r->files_by_name, name, upb_value_ptr(r->file));
/* XXX: see comment at the top of the file. */
ok = upb_filedef_setname(r->file, name, NULL);
upb_gfree(name);
@@ -7680,6 +8637,18 @@ static void *file_startext(void *closure, const void *hd) {
return r;
}
+static size_t file_ondep(void *closure, const void *hd, const char *buf,
+ size_t n, const upb_bufhandle *handle) {
+ upb_descreader *r = closure;
+ upb_value val;
+ if (upb_strtable_lookup2(&r->files_by_name, buf, n, &val)) {
+ upb_filedef_adddep(r->file, upb_value_getptr(val));
+ }
+ UPB_UNUSED(hd);
+ UPB_UNUSED(handle);
+ return n;
+}
+
/** Handlers for google.protobuf.EnumValueDescriptorProto. *********************/
static bool enumval_startmsg(void *closure, const void *hd) {
@@ -8124,6 +9093,8 @@ static void reghandlers(const void *closure, upb_handlers *h) {
&file_startenum, NULL);
upb_handlers_setstartsubmsg(h, F(FileDescriptorProto, extension),
&file_startext, NULL);
+ upb_handlers_setstring(h, F(FileDescriptorProto, dependency),
+ &file_ondep, NULL);
} else if (upbdefs_google_protobuf_EnumValueDescriptorProto_is(m)) {
upb_handlers_setstartmsg(h, &enumval_startmsg, NULL);
upb_handlers_setendmsg(h, &enumval_endmsg, NULL);
@@ -8183,6 +9154,7 @@ void descreader_cleanup(void *_r) {
upb_gfree(r->name);
upb_inttable_uninit(&r->files);
+ upb_strtable_uninit(&r->files_by_name);
upb_inttable_uninit(&r->oneofs);
upb_gfree(r->default_string);
while (r->stack_len > 0) {
@@ -8201,6 +9173,7 @@ upb_descreader *upb_descreader_create(upb_env *e, const upb_handlers *h) {
}
upb_inttable_init(&r->files, UPB_CTYPE_PTR);
+ upb_strtable_init(&r->files_by_name, UPB_CTYPE_PTR);
upb_inttable_init(&r->oneofs, UPB_CTYPE_PTR);
upb_sink_reset(upb_descreader_input(r), h, r);
r->stack_len = 0;
@@ -8500,7 +9473,7 @@ static void put32(compiler *c, uint32_t v) {
*c->pc++ = v;
}
-static void putop(compiler *c, opcode op, ...) {
+static void putop(compiler *c, int op, ...) {
va_list ap;
va_start(ap, op);
@@ -9783,7 +10756,6 @@ have_tag:
return upb_pbdecoder_suspend(d);
}
- /* TODO: deliver to unknown field callback. */
switch (wire_type) {
case UPB_WIRE_TYPE_32BIT:
CHECK_RETURN(skip(d, 4));
@@ -9821,6 +10793,8 @@ have_tag:
}
if (d->top->groupnum >= 0) {
+ /* TODO: More code needed for handling unknown groups. */
+ upb_sink_putunknown(&d->top->sink, d->checkpoint, d->ptr - d->checkpoint);
return DECODE_OK;
}
@@ -10676,6 +11650,12 @@ static void *encode_startdelimfield(void *c, const void *hd) {
return ok ? c : UPB_BREAK;
}
+static bool encode_unknown(void *c, const void *hd, const char *buf,
+ size_t len) {
+ UPB_UNUSED(hd);
+ return encode_bytes(c, buf, len) && commit(c);
+}
+
static bool encode_enddelimfield(void *c, const void *hd) {
UPB_UNUSED(hd);
return end_delim(c);
@@ -10738,6 +11718,7 @@ static void newhandlers_callback(const void *closure, upb_handlers *h) {
upb_handlers_setstartmsg(h, startmsg, NULL);
upb_handlers_setendmsg(h, endmsg, NULL);
+ upb_handlers_setunknown(h, encode_unknown, NULL);
m = upb_handlers_msgdef(h);
for(upb_msg_field_begin(&i, m);
@@ -11350,8 +12331,9 @@ done:
** - handling of keys/escape-sequences/etc that span input buffers.
*/
-#include <assert.h>
#include <errno.h>
+#include <float.h>
+#include <math.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
@@ -11936,103 +12918,160 @@ static void start_number(upb_json_parser *p, const char *ptr) {
capture_begin(p, ptr);
}
-static bool parse_number(upb_json_parser *p);
+static bool parse_number(upb_json_parser *p, bool is_quoted);
static bool end_number(upb_json_parser *p, const char *ptr) {
if (!capture_end(p, ptr)) {
return false;
}
- return parse_number(p);
+ return parse_number(p, false);
}
-static bool parse_number(upb_json_parser *p) {
- size_t len;
- const char *buf;
- const char *myend;
+/* |buf| is NULL-terminated. |buf| itself will never include quotes;
+ * |is_quoted| tells us whether this text originally appeared inside quotes. */
+static bool parse_number_from_buffer(upb_json_parser *p, const char *buf,
+ bool is_quoted) {
+ size_t len = strlen(buf);
+ const char *bufend = buf + len;
char *end;
+ upb_fieldtype_t type = upb_fielddef_type(p->top->f);
+ double val;
+ double dummy;
+ double inf = 1.0 / 0.0; /* C89 does not have an INFINITY macro. */
- /* strtol() and friends unfortunately do not support specifying the length of
- * the input string, so we need to force a copy into a NULL-terminated buffer. */
- if (!multipart_text(p, "\0", 1, false)) {
+ errno = 0;
+
+ if (len == 0 || buf[0] == ' ') {
return false;
}
- buf = accumulate_getptr(p, &len);
- myend = buf + len - 1; /* One for NULL. */
-
- /* XXX: We are using strtol to parse integers, but this is wrong as even
- * integers can be represented as 1e6 (for example), which strtol can't
- * handle correctly.
- *
- * XXX: Also, we can't handle large integers properly because strto[u]ll
- * isn't in C89.
- *
- * XXX: Also, we don't properly check floats for overflow, since strtof
- * isn't in C89. */
- switch (upb_fielddef_type(p->top->f)) {
+ /* For integer types, first try parsing with integer-specific routines.
+ * If these succeed, they will be more accurate for int64/uint64 than
+ * strtod().
+ */
+ switch (type) {
case UPB_TYPE_ENUM:
case UPB_TYPE_INT32: {
- long val = strtol(p->accumulated, &end, 0);
- if (val > INT32_MAX || val < INT32_MIN || errno == ERANGE || end != myend)
- goto err;
- else
+ long val = strtol(buf, &end, 0);
+ if (errno == ERANGE || end != bufend) {
+ break;
+ } else if (val > INT32_MAX || val < INT32_MIN) {
+ return false;
+ } else {
upb_sink_putint32(&p->top->sink, parser_getsel(p), val);
- break;
- }
- case UPB_TYPE_INT64: {
- long long val = strtol(p->accumulated, &end, 0);
- if (val > INT64_MAX || val < INT64_MIN || errno == ERANGE || end != myend)
- goto err;
- else
- upb_sink_putint64(&p->top->sink, parser_getsel(p), val);
- break;
+ return true;
+ }
}
case UPB_TYPE_UINT32: {
- unsigned long val = strtoul(p->accumulated, &end, 0);
- if (val > UINT32_MAX || errno == ERANGE || end != myend)
- goto err;
- else
+ unsigned long val = strtoul(buf, &end, 0);
+ if (end != bufend) {
+ break;
+ } else if (val > UINT32_MAX || errno == ERANGE) {
+ return false;
+ } else {
upb_sink_putuint32(&p->top->sink, parser_getsel(p), val);
- break;
+ return true;
+ }
+ }
+ /* XXX: We can't handle [u]int64 properly on 32-bit machines because
+ * strto[u]ll isn't in C89. */
+ case UPB_TYPE_INT64: {
+ long val = strtol(buf, &end, 0);
+ if (errno == ERANGE || end != bufend) {
+ break;
+ } else {
+ upb_sink_putint64(&p->top->sink, parser_getsel(p), val);
+ return true;
+ }
}
case UPB_TYPE_UINT64: {
- unsigned long long val = strtoul(p->accumulated, &end, 0);
- if (val > UINT64_MAX || errno == ERANGE || end != myend)
- goto err;
- else
+ unsigned long val = strtoul(p->accumulated, &end, 0);
+ if (end != bufend) {
+ break;
+ } else if (errno == ERANGE) {
+ return false;
+ } else {
upb_sink_putuint64(&p->top->sink, parser_getsel(p), val);
- break;
+ return true;
+ }
}
- case UPB_TYPE_DOUBLE: {
- double val = strtod(p->accumulated, &end);
- if (errno == ERANGE || end != myend)
- goto err;
- else
- upb_sink_putdouble(&p->top->sink, parser_getsel(p), val);
+ default:
break;
+ }
+
+ if (type != UPB_TYPE_DOUBLE && type != UPB_TYPE_FLOAT && is_quoted) {
+ /* Quoted numbers for integer types are not allowed to be in double form. */
+ return false;
+ }
+
+ if (len == strlen("Infinity") && strcmp(buf, "Infinity") == 0) {
+ /* C89 does not have an INFINITY macro. */
+ val = inf;
+ } else if (len == strlen("-Infinity") && strcmp(buf, "-Infinity") == 0) {
+ val = -inf;
+ } else {
+ val = strtod(buf, &end);
+ if (errno == ERANGE || end != bufend) {
+ return false;
}
- case UPB_TYPE_FLOAT: {
- float val = strtod(p->accumulated, &end);
- if (errno == ERANGE || end != myend)
- goto err;
- else
- upb_sink_putfloat(&p->top->sink, parser_getsel(p), val);
- break;
+ }
+
+ switch (type) {
+#define CASE(capitaltype, smalltype, ctype, min, max) \
+ case UPB_TYPE_ ## capitaltype: { \
+ if (modf(val, &dummy) != 0 || val > max || val < min) { \
+ return false; \
+ } else { \
+ upb_sink_put ## smalltype(&p->top->sink, parser_getsel(p), \
+ (ctype)val); \
+ return true; \
+ } \
+ break; \
}
+ case UPB_TYPE_ENUM:
+ CASE(INT32, int32, int32_t, INT32_MIN, INT32_MAX);
+ CASE(INT64, int64, int64_t, INT64_MIN, INT64_MAX);
+ CASE(UINT32, uint32, uint32_t, 0, UINT32_MAX);
+ CASE(UINT64, uint64, uint64_t, 0, UINT64_MAX);
+#undef CASE
+
+ case UPB_TYPE_DOUBLE:
+ upb_sink_putdouble(&p->top->sink, parser_getsel(p), val);
+ return true;
+ case UPB_TYPE_FLOAT:
+ if ((val > FLT_MAX || val < -FLT_MAX) && val != inf && val != -inf) {
+ return false;
+ } else {
+ upb_sink_putfloat(&p->top->sink, parser_getsel(p), val);
+ return true;
+ }
default:
- UPB_ASSERT(false);
+ return false;
}
+}
- multipart_end(p);
+static bool parse_number(upb_json_parser *p, bool is_quoted) {
+ size_t len;
+ const char *buf;
- return true;
+ /* strtol() and friends unfortunately do not support specifying the length of
+ * the input string, so we need to force a copy into a NULL-terminated buffer. */
+ if (!multipart_text(p, "\0", 1, false)) {
+ return false;
+ }
-err:
- upb_status_seterrf(&p->status, "error parsing number: %s", buf);
- upb_env_reporterror(p->env, &p->status);
- multipart_end(p);
- return false;
+ buf = accumulate_getptr(p, &len);
+
+ if (parse_number_from_buffer(p, buf, is_quoted)) {
+ multipart_end(p);
+ return true;
+ } else {
+ upb_status_seterrf(&p->status, "error parsing number: %s", buf);
+ upb_env_reporterror(p->env, &p->status);
+ multipart_end(p);
+ return false;
+ }
}
static bool parser_putbool(upb_json_parser *p, bool val) {
@@ -12085,17 +13124,16 @@ static bool start_stringval(upb_json_parser *p) {
multipart_startaccum(p);
return true;
}
- } else if (upb_fielddef_type(p->top->f) == UPB_TYPE_ENUM) {
- /* No need to push a frame -- symbolic enum names in quotes remain in the
- * current parser frame.
- *
- * Enum string values must accumulate so we can look up the value in a table
- * once it is complete. */
+ } else if (upb_fielddef_type(p->top->f) != UPB_TYPE_BOOL &&
+ upb_fielddef_type(p->top->f) != UPB_TYPE_MESSAGE) {
+ /* No need to push a frame -- numeric values in quotes remain in the
+ * current parser frame. These values must accmulate so we can convert
+ * them all at once at the end. */
multipart_startaccum(p);
return true;
} else {
upb_status_seterrf(&p->status,
- "String specified for non-string/non-enum field: %s",
+ "String specified for bool or submessage field: %s",
upb_fielddef_name(p->top->f));
upb_env_reporterror(p->env, &p->status);
return false;
@@ -12142,6 +13180,15 @@ static bool end_stringval(upb_json_parser *p) {
break;
}
+ case UPB_TYPE_INT32:
+ case UPB_TYPE_INT64:
+ case UPB_TYPE_UINT32:
+ case UPB_TYPE_UINT64:
+ case UPB_TYPE_DOUBLE:
+ case UPB_TYPE_FLOAT:
+ ok = parse_number(p, true);
+ break;
+
default:
UPB_ASSERT(false);
upb_status_seterrmsg(&p->status, "Internal error in JSON decoder");
@@ -12185,7 +13232,7 @@ static bool parse_mapentry_key(upb_json_parser *p) {
case UPB_TYPE_UINT32:
case UPB_TYPE_UINT64:
/* Invoke end_number. The accum buffer has the number's text already. */
- if (!parse_number(p)) {
+ if (!parse_number(p, true)) {
return false;
}
break;
@@ -12476,11 +13523,11 @@ static void end_object(upb_json_parser *p) {
* final state once, when the closing '"' is seen. */
-#line 1244 "upb/json/parser.rl"
+#line 1310 "upb/json/parser.rl"
-#line 1156 "upb/json/parser.c"
+#line 1222 "upb/json/parser.c"
static const char _json_actions[] = {
0, 1, 0, 1, 2, 1, 3, 1,
5, 1, 6, 1, 7, 1, 8, 1,
@@ -12629,7 +13676,7 @@ static const int json_en_value_machine = 27;
static const int json_en_main = 1;
-#line 1247 "upb/json/parser.rl"
+#line 1313 "upb/json/parser.rl"
size_t parse(void *closure, const void *hd, const char *buf, size_t size,
const upb_bufhandle *handle) {
@@ -12651,7 +13698,7 @@ size_t parse(void *closure, const void *hd, const char *buf, size_t size,
capture_resume(parser, buf);
-#line 1327 "upb/json/parser.c"
+#line 1393 "upb/json/parser.c"
{
int _klen;
unsigned int _trans;
@@ -12726,118 +13773,118 @@ _match:
switch ( *_acts++ )
{
case 0:
-#line 1159 "upb/json/parser.rl"
+#line 1225 "upb/json/parser.rl"
{ p--; {cs = stack[--top]; goto _again;} }
break;
case 1:
-#line 1160 "upb/json/parser.rl"
+#line 1226 "upb/json/parser.rl"
{ p--; {stack[top++] = cs; cs = 10; goto _again;} }
break;
case 2:
-#line 1164 "upb/json/parser.rl"
+#line 1230 "upb/json/parser.rl"
{ start_text(parser, p); }
break;
case 3:
-#line 1165 "upb/json/parser.rl"
+#line 1231 "upb/json/parser.rl"
{ CHECK_RETURN_TOP(end_text(parser, p)); }
break;
case 4:
-#line 1171 "upb/json/parser.rl"
+#line 1237 "upb/json/parser.rl"
{ start_hex(parser); }
break;
case 5:
-#line 1172 "upb/json/parser.rl"
+#line 1238 "upb/json/parser.rl"
{ hexdigit(parser, p); }
break;
case 6:
-#line 1173 "upb/json/parser.rl"
+#line 1239 "upb/json/parser.rl"
{ CHECK_RETURN_TOP(end_hex(parser)); }
break;
case 7:
-#line 1179 "upb/json/parser.rl"
+#line 1245 "upb/json/parser.rl"
{ CHECK_RETURN_TOP(escape(parser, p)); }
break;
case 8:
-#line 1185 "upb/json/parser.rl"
+#line 1251 "upb/json/parser.rl"
{ p--; {cs = stack[--top]; goto _again;} }
break;
case 9:
-#line 1188 "upb/json/parser.rl"
+#line 1254 "upb/json/parser.rl"
{ {stack[top++] = cs; cs = 19; goto _again;} }
break;
case 10:
-#line 1190 "upb/json/parser.rl"
+#line 1256 "upb/json/parser.rl"
{ p--; {stack[top++] = cs; cs = 27; goto _again;} }
break;
case 11:
-#line 1195 "upb/json/parser.rl"
+#line 1261 "upb/json/parser.rl"
{ start_member(parser); }
break;
case 12:
-#line 1196 "upb/json/parser.rl"
+#line 1262 "upb/json/parser.rl"
{ CHECK_RETURN_TOP(end_membername(parser)); }
break;
case 13:
-#line 1199 "upb/json/parser.rl"
+#line 1265 "upb/json/parser.rl"
{ end_member(parser); }
break;
case 14:
-#line 1205 "upb/json/parser.rl"
+#line 1271 "upb/json/parser.rl"
{ start_object(parser); }
break;
case 15:
-#line 1208 "upb/json/parser.rl"
+#line 1274 "upb/json/parser.rl"
{ end_object(parser); }
break;
case 16:
-#line 1214 "upb/json/parser.rl"
+#line 1280 "upb/json/parser.rl"
{ CHECK_RETURN_TOP(start_array(parser)); }
break;
case 17:
-#line 1218 "upb/json/parser.rl"
+#line 1284 "upb/json/parser.rl"
{ end_array(parser); }
break;
case 18:
-#line 1223 "upb/json/parser.rl"
+#line 1289 "upb/json/parser.rl"
{ start_number(parser, p); }
break;
case 19:
-#line 1224 "upb/json/parser.rl"
+#line 1290 "upb/json/parser.rl"
{ CHECK_RETURN_TOP(end_number(parser, p)); }
break;
case 20:
-#line 1226 "upb/json/parser.rl"
+#line 1292 "upb/json/parser.rl"
{ CHECK_RETURN_TOP(start_stringval(parser)); }
break;
case 21:
-#line 1227 "upb/json/parser.rl"
+#line 1293 "upb/json/parser.rl"
{ CHECK_RETURN_TOP(end_stringval(parser)); }
break;
case 22:
-#line 1229 "upb/json/parser.rl"
+#line 1295 "upb/json/parser.rl"
{ CHECK_RETURN_TOP(parser_putbool(parser, true)); }
break;
case 23:
-#line 1231 "upb/json/parser.rl"
+#line 1297 "upb/json/parser.rl"
{ CHECK_RETURN_TOP(parser_putbool(parser, false)); }
break;
case 24:
-#line 1233 "upb/json/parser.rl"
+#line 1299 "upb/json/parser.rl"
{ /* null value */ }
break;
case 25:
-#line 1235 "upb/json/parser.rl"
+#line 1301 "upb/json/parser.rl"
{ CHECK_RETURN_TOP(start_subobject(parser)); }
break;
case 26:
-#line 1236 "upb/json/parser.rl"
+#line 1302 "upb/json/parser.rl"
{ end_subobject(parser); }
break;
case 27:
-#line 1241 "upb/json/parser.rl"
+#line 1307 "upb/json/parser.rl"
{ p--; {cs = stack[--top]; goto _again;} }
break;
-#line 1513 "upb/json/parser.c"
+#line 1579 "upb/json/parser.c"
}
}
@@ -12850,7 +13897,7 @@ _again:
_out: {}
}
-#line 1268 "upb/json/parser.rl"
+#line 1334 "upb/json/parser.rl"
if (p != pe) {
upb_status_seterrf(&parser->status, "Parse error at '%.*s'\n", pe - p, p);
@@ -12891,13 +13938,13 @@ static void json_parser_reset(upb_json_parser *p) {
/* Emit Ragel initialization of the parser. */
-#line 1567 "upb/json/parser.c"
+#line 1633 "upb/json/parser.c"
{
cs = json_start;
top = 0;
}
-#line 1308 "upb/json/parser.rl"
+#line 1374 "upb/json/parser.rl"
p->current_state = cs;
p->parser_top = top;
accumulate_clear(p);
@@ -13194,10 +14241,23 @@ static void putstring(upb_json_printer *p, const char *buf, unsigned int len) {
* Right now we use %.8g and %.17g for float/double, respectively, to match
* proto2::util::JsonFormat's defaults. May want to change this later. */
+const char neginf[] = "\"-Infinity\"";
+const char inf[] = "\"Infinity\"";
+
static size_t fmt_double(double val, char* buf, size_t length) {
- size_t n = _upb_snprintf(buf, length, "%.17g", val);
- CHKLENGTH(n > 0 && n < length);
- return n;
+ if (val == (1.0 / 0.0)) {
+ CHKLENGTH(length >= strlen(inf));
+ strcpy(buf, inf);
+ return strlen(inf);
+ } else if (val == (-1.0 / 0.0)) {
+ CHKLENGTH(length >= strlen(neginf));
+ strcpy(buf, neginf);
+ return strlen(neginf);
+ } else {
+ size_t n = _upb_snprintf(buf, length, "%.17g", val);
+ CHKLENGTH(n > 0 && n < length);
+ return n;
+ }
}
static size_t fmt_float(float val, char* buf, size_t length) {
diff --git a/php/ext/google/protobuf/upb.h b/php/ext/google/protobuf/upb.h
index 4b51275d..10371e8b 100644
--- a/php/ext/google/protobuf/upb.h
+++ b/php/ext/google/protobuf/upb.h
@@ -1,66 +1,13 @@
// Amalgamated source file
/*
-** Defs are upb's internal representation of the constructs that can appear
-** in a .proto file:
-**
-** - upb::MessageDef (upb_msgdef): describes a "message" construct.
-** - upb::FieldDef (upb_fielddef): describes a message field.
-** - upb::FileDef (upb_filedef): describes a .proto file and its defs.
-** - upb::EnumDef (upb_enumdef): describes an enum.
-** - upb::OneofDef (upb_oneofdef): describes a oneof.
-** - upb::Def (upb_def): base class of all the others.
-**
-** TODO: definitions of services.
-**
-** Like upb_refcounted objects, defs are mutable only until frozen, and are
-** only thread-safe once frozen.
-**
-** This is a mixed C/C++ interface that offers a full API to both languages.
-** See the top-level README for more information.
-*/
-
-#ifndef UPB_DEF_H_
-#define UPB_DEF_H_
-
-/*
-** upb::RefCounted (upb_refcounted)
-**
-** A refcounting scheme that supports circular refs. It accomplishes this by
-** partitioning the set of objects into groups such that no cycle spans groups;
-** we can then reference-count the group as a whole and ignore refs within the
-** group. When objects are mutable, these groups are computed very
-** conservatively; we group any objects that have ever had a link between them.
-** When objects are frozen, we compute strongly-connected components which
-** allows us to be precise and only group objects that are actually cyclic.
+** This file contains shared definitions that are widely used across upb.
**
** This is a mixed C/C++ interface that offers a full API to both languages.
** See the top-level README for more information.
*/
-#ifndef UPB_REFCOUNTED_H_
-#define UPB_REFCOUNTED_H_
-
-/*
-** upb_table
-**
-** This header is INTERNAL-ONLY! Its interfaces are not public or stable!
-** This file defines very fast int->upb_value (inttable) and string->upb_value
-** (strtable) hash tables.
-**
-** The table uses chained scatter with Brent's variation (inspired by the Lua
-** implementation of hash tables). The hash function for strings is Austin
-** Appleby's "MurmurHash."
-**
-** The inttable uses uintptr_t as its key, which guarantees it can be used to
-** store pointers or integers of at least 32 bits (upb isn't really useful on
-** systems where sizeof(void*) < 4).
-**
-** The table must be homogenous (all values of the same type). In debug
-** mode, we check this on insert and lookup.
-*/
-
-#ifndef UPB_TABLE_H_
-#define UPB_TABLE_H_
+#ifndef UPB_H_
+#define UPB_H_
// php.h intentionally defined NDEBUG. We have to define this macro in order to
// be used together with php.h
@@ -68,18 +15,6 @@
#define NDEBUG
#endif
-#include <stdint.h>
-#include <string.h>
-/*
-** This file contains shared definitions that are widely used across upb.
-**
-** This is a mixed C/C++ interface that offers a full API to both languages.
-** See the top-level README for more information.
-*/
-
-#ifndef UPB_H_
-#define UPB_H_
-
#include <assert.h>
#include <stdarg.h>
#include <stdbool.h>
@@ -106,6 +41,9 @@ template <int N> class InlinedEnvironment;
#define UPB_INLINE static
#endif
+/* Hints to the compiler about likely/unlikely branches. */
+#define UPB_LIKELY(x) __builtin_expect((x),1)
+
/* Define UPB_BIG_ENDIAN manually if you're on big endian and your compiler
* doesn't provide these preprocessor symbols. */
#if defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)
@@ -367,6 +305,16 @@ class PointerBase2 : public PointerBase<T, Base> {
#endif
+/* A list of types as they are encoded on-the-wire. */
+typedef enum {
+ UPB_WIRE_TYPE_VARINT = 0,
+ UPB_WIRE_TYPE_64BIT = 1,
+ UPB_WIRE_TYPE_DELIMITED = 2,
+ UPB_WIRE_TYPE_START_GROUP = 3,
+ UPB_WIRE_TYPE_END_GROUP = 4,
+ UPB_WIRE_TYPE_32BIT = 5
+} upb_wiretype_t;
+
/* upb::ErrorSpace ************************************************************/
@@ -695,7 +643,7 @@ void upb_env_uninit(upb_env *e);
void upb_env_initonly(upb_env *e);
-upb_arena *upb_env_arena(upb_env *e);
+UPB_INLINE upb_arena *upb_env_arena(upb_env *e) { return (upb_arena*)e; }
bool upb_env_ok(const upb_env *e);
void upb_env_seterrorfunc(upb_env *e, upb_error_func *func, void *ud);
@@ -795,6 +743,106 @@ template <int N> class upb::InlinedEnvironment : public upb::Environment {
#endif /* UPB_H_ */
+/*
+** upb_decode: parsing into a upb_msg using a upb_msglayout.
+*/
+
+#ifndef UPB_DECODE_H_
+#define UPB_DECODE_H_
+
+/*
+** upb::Message is a representation for protobuf messages.
+**
+** However it differs from other common representations like
+** google::protobuf::Message in one key way: it does not prescribe any
+** ownership between messages and submessages, and it relies on the
+** client to delete each message/submessage/array/map at the appropriate
+** time.
+**
+** A client can access a upb::Message without knowing anything about
+** ownership semantics, but to create or mutate a message a user needs
+** to implement the memory management themselves.
+**
+** Currently all messages, arrays, and maps store a upb_alloc* internally.
+** Mutating operations use this when they require dynamically-allocated
+** memory. We could potentially eliminate this size overhead later by
+** letting the user flip a bit on the factory that prevents this from
+** being stored. The user would then need to use separate functions where
+** the upb_alloc* is passed explicitly. However for handlers to populate
+** such structures, they would need a place to store this upb_alloc* during
+** parsing; upb_handlers don't currently have a good way to accommodate this.
+**
+** TODO: UTF-8 checking?
+**/
+
+#ifndef UPB_MSG_H_
+#define UPB_MSG_H_
+
+/*
+** Defs are upb's internal representation of the constructs that can appear
+** in a .proto file:
+**
+** - upb::MessageDef (upb_msgdef): describes a "message" construct.
+** - upb::FieldDef (upb_fielddef): describes a message field.
+** - upb::FileDef (upb_filedef): describes a .proto file and its defs.
+** - upb::EnumDef (upb_enumdef): describes an enum.
+** - upb::OneofDef (upb_oneofdef): describes a oneof.
+** - upb::Def (upb_def): base class of all the others.
+**
+** TODO: definitions of services.
+**
+** Like upb_refcounted objects, defs are mutable only until frozen, and are
+** only thread-safe once frozen.
+**
+** This is a mixed C/C++ interface that offers a full API to both languages.
+** See the top-level README for more information.
+*/
+
+#ifndef UPB_DEF_H_
+#define UPB_DEF_H_
+
+/*
+** upb::RefCounted (upb_refcounted)
+**
+** A refcounting scheme that supports circular refs. It accomplishes this by
+** partitioning the set of objects into groups such that no cycle spans groups;
+** we can then reference-count the group as a whole and ignore refs within the
+** group. When objects are mutable, these groups are computed very
+** conservatively; we group any objects that have ever had a link between them.
+** When objects are frozen, we compute strongly-connected components which
+** allows us to be precise and only group objects that are actually cyclic.
+**
+** This is a mixed C/C++ interface that offers a full API to both languages.
+** See the top-level README for more information.
+*/
+
+#ifndef UPB_REFCOUNTED_H_
+#define UPB_REFCOUNTED_H_
+
+/*
+** upb_table
+**
+** This header is INTERNAL-ONLY! Its interfaces are not public or stable!
+** This file defines very fast int->upb_value (inttable) and string->upb_value
+** (strtable) hash tables.
+**
+** The table uses chained scatter with Brent's variation (inspired by the Lua
+** implementation of hash tables). The hash function for strings is Austin
+** Appleby's "MurmurHash."
+**
+** The inttable uses uintptr_t as its key, which guarantees it can be used to
+** store pointers or integers of at least 32 bits (upb isn't really useful on
+** systems where sizeof(void*) < 4).
+**
+** The table must be homogenous (all values of the same type). In debug
+** mode, we check this on insert and lookup.
+*/
+
+#ifndef UPB_TABLE_H_
+#define UPB_TABLE_H_
+
+#include <stdint.h>
+#include <string.h>
#ifdef __cplusplus
extern "C" {
@@ -3857,196 +3905,6 @@ inline bool FileDef::AddDependency(const FileDef* file) {
#endif /* UPB_DEF_H_ */
/*
-** This file contains definitions of structs that should be considered private
-** and NOT stable across versions of upb.
-**
-** The only reason they are declared here and not in .c files is to allow upb
-** and the application (if desired) to embed statically-initialized instances
-** of structures like defs.
-**
-** If you include this file, all guarantees of ABI compatibility go out the
-** window! Any code that includes this file needs to recompile against the
-** exact same version of upb that they are linking against.
-**
-** You also need to recompile if you change the value of the UPB_DEBUG_REFS
-** flag.
-*/
-
-
-#ifndef UPB_STATICINIT_H_
-#define UPB_STATICINIT_H_
-
-#ifdef __cplusplus
-/* Because of how we do our typedefs, this header can't be included from C++. */
-#error This file cannot be included from C++
-#endif
-
-/* upb_refcounted *************************************************************/
-
-
-/* upb_def ********************************************************************/
-
-struct upb_def {
- upb_refcounted base;
-
- const char *fullname;
- const upb_filedef* file;
- char type; /* A upb_deftype_t (char to save space) */
-
- /* Used as a flag during the def's mutable stage. Must be false unless
- * it is currently being used by a function on the stack. This allows
- * us to easily determine which defs were passed into the function's
- * current invocation. */
- bool came_from_user;
-};
-
-#define UPB_DEF_INIT(name, type, vtbl, refs, ref2s) \
- { UPB_REFCOUNT_INIT(vtbl, refs, ref2s), name, NULL, type, false }
-
-
-/* upb_fielddef ***************************************************************/
-
-struct upb_fielddef {
- upb_def base;
-
- union {
- int64_t sint;
- uint64_t uint;
- double dbl;
- float flt;
- void *bytes;
- } defaultval;
- union {
- const upb_msgdef *def; /* If !msg_is_symbolic. */
- char *name; /* If msg_is_symbolic. */
- } msg;
- union {
- const upb_def *def; /* If !subdef_is_symbolic. */
- char *name; /* If subdef_is_symbolic. */
- } sub; /* The msgdef or enumdef for this field, if upb_hassubdef(f). */
- bool subdef_is_symbolic;
- bool msg_is_symbolic;
- const upb_oneofdef *oneof;
- bool default_is_string;
- bool type_is_set_; /* False until type is explicitly set. */
- bool is_extension_;
- bool lazy_;
- bool packed_;
- upb_intfmt_t intfmt;
- bool tagdelim;
- upb_fieldtype_t type_;
- upb_label_t label_;
- uint32_t number_;
- uint32_t selector_base; /* Used to index into a upb::Handlers table. */
- uint32_t index_;
-};
-
-extern const struct upb_refcounted_vtbl upb_fielddef_vtbl;
-
-#define UPB_FIELDDEF_INIT(label, type, intfmt, tagdelim, is_extension, lazy, \
- packed, name, num, msgdef, subdef, selector_base, \
- index, defaultval, refs, ref2s) \
- { \
- UPB_DEF_INIT(name, UPB_DEF_FIELD, &upb_fielddef_vtbl, refs, ref2s), \
- defaultval, {msgdef}, {subdef}, NULL, false, false, \
- type == UPB_TYPE_STRING || type == UPB_TYPE_BYTES, true, is_extension, \
- lazy, packed, intfmt, tagdelim, type, label, num, selector_base, index \
- }
-
-
-/* upb_msgdef *****************************************************************/
-
-struct upb_msgdef {
- upb_def base;
-
- size_t selector_count;
- uint32_t submsg_field_count;
-
- /* Tables for looking up fields by number and name. */
- upb_inttable itof; /* int to field */
- upb_strtable ntof; /* name to field/oneof */
-
- /* Is this a map-entry message? */
- bool map_entry;
-
- /* Whether this message has proto2 or proto3 semantics. */
- upb_syntax_t syntax;
-
- /* TODO(haberman): proper extension ranges (there can be multiple). */
-};
-
-extern const struct upb_refcounted_vtbl upb_msgdef_vtbl;
-
-/* TODO: also support static initialization of the oneofs table. This will be
- * needed if we compile in descriptors that contain oneofs. */
-#define UPB_MSGDEF_INIT(name, selector_count, submsg_field_count, itof, ntof, \
- map_entry, syntax, refs, ref2s) \
- { \
- UPB_DEF_INIT(name, UPB_DEF_MSG, &upb_fielddef_vtbl, refs, ref2s), \
- selector_count, submsg_field_count, itof, ntof, map_entry, syntax \
- }
-
-
-/* upb_enumdef ****************************************************************/
-
-struct upb_enumdef {
- upb_def base;
-
- upb_strtable ntoi;
- upb_inttable iton;
- int32_t defaultval;
-};
-
-extern const struct upb_refcounted_vtbl upb_enumdef_vtbl;
-
-#define UPB_ENUMDEF_INIT(name, ntoi, iton, defaultval, refs, ref2s) \
- { UPB_DEF_INIT(name, UPB_DEF_ENUM, &upb_enumdef_vtbl, refs, ref2s), ntoi, \
- iton, defaultval }
-
-
-/* upb_oneofdef ***************************************************************/
-
-struct upb_oneofdef {
- upb_refcounted base;
-
- uint32_t index; /* Index within oneofs. */
- const char *name;
- upb_strtable ntof;
- upb_inttable itof;
- const upb_msgdef *parent;
-};
-
-extern const struct upb_refcounted_vtbl upb_oneofdef_vtbl;
-
-#define UPB_ONEOFDEF_INIT(name, ntof, itof, refs, ref2s) \
- { UPB_REFCOUNT_INIT(&upb_oneofdef_vtbl, refs, ref2s), 0, name, ntof, itof }
-
-
-/* upb_symtab *****************************************************************/
-
-struct upb_symtab {
- upb_refcounted base;
-
- upb_strtable symtab;
-};
-
-struct upb_filedef {
- upb_refcounted base;
-
- const char *name;
- const char *package;
- const char *phpprefix;
- const char *phpnamespace;
- upb_syntax_t syntax;
-
- upb_inttable defs;
- upb_inttable deps;
-};
-
-extern const struct upb_refcounted_vtbl upb_filedef_vtbl;
-
-#endif /* UPB_STATICINIT_H_ */
-/*
** upb::Handlers (upb_handlers)
**
** A upb_handlers is like a virtual table for a upb_msgdef. Each field of the
@@ -4150,7 +4008,8 @@ UPB_END_EXTERN_C
/* Static selectors for upb::Handlers. */
#define UPB_STARTMSG_SELECTOR 0
#define UPB_ENDMSG_SELECTOR 1
-#define UPB_STATIC_SELECTOR_COUNT 2
+#define UPB_UNKNOWN_SELECTOR 2
+#define UPB_STATIC_SELECTOR_COUNT 3
/* Static selectors for upb::BytesHandler. */
#define UPB_STARTSTR_SELECTOR 0
@@ -4679,6 +4538,8 @@ UPB_BEGIN_EXTERN_C
/* Native C API. */
/* Handler function typedefs. */
+typedef bool upb_unknown_handlerfunc(void *c, const void *hd, const char *buf,
+ size_t n);
typedef bool upb_startmsg_handlerfunc(void *c, const void*);
typedef bool upb_endmsg_handlerfunc(void *c, const void *, upb_status *status);
typedef void* upb_startfield_handlerfunc(void *c, const void *hd);
@@ -4732,6 +4593,8 @@ const upb_status *upb_handlers_status(upb_handlers *h);
void upb_handlers_clearerr(upb_handlers *h);
const upb_msgdef *upb_handlers_msgdef(const upb_handlers *h);
bool upb_handlers_addcleanup(upb_handlers *h, void *p, upb_handlerfree *hfree);
+bool upb_handlers_setunknown(upb_handlers *h, upb_unknown_handlerfunc *func,
+ upb_handlerattr *attr);
bool upb_handlers_setstartmsg(upb_handlers *h, upb_startmsg_handlerfunc *func,
upb_handlerattr *attr);
@@ -6301,6 +6164,18 @@ UPB_INLINE size_t upb_sink_putstring(upb_sink *s, upb_selector_t sel,
return handler(s->closure, hd, buf, n, handle);
}
+UPB_INLINE bool upb_sink_putunknown(upb_sink *s, const char *buf, size_t n) {
+ typedef upb_unknown_handlerfunc func;
+ func *handler;
+ const void *hd;
+ if (!s->handlers) return true;
+ handler = (func *)upb_handlers_gethandler(s->handlers, UPB_UNKNOWN_SELECTOR);
+
+ if (!handler) return n;
+ hd = upb_handlers_gethandlerdata(s->handlers, UPB_UNKNOWN_SELECTOR);
+ return handler(s->closure, hd, buf, n);
+}
+
UPB_INLINE bool upb_sink_startmsg(upb_sink *s) {
typedef upb_startmsg_handlerfunc func;
func *startmsg;
@@ -6505,34 +6380,6 @@ inline bool BufferSource::PutBuffer(const char *buf, size_t len,
#endif
#endif
-/*
-** upb::Message is a representation for protobuf messages.
-**
-** However it differs from other common representations like
-** google::protobuf::Message in one key way: it does not prescribe any
-** ownership between messages and submessages, and it relies on the
-** client to delete each message/submessage/array/map at the appropriate
-** time.
-**
-** A client can access a upb::Message without knowing anything about
-** ownership semantics, but to create or mutate a message a user needs
-** to implement the memory management themselves.
-**
-** Currently all messages, arrays, and maps store a upb_alloc* internally.
-** Mutating operations use this when they require dynamically-allocated
-** memory. We could potentially eliminate this size overhead later by
-** letting the user flip a bit on the factory that prevents this from
-** being stored. The user would then need to use separate functions where
-** the upb_alloc* is passed explicitly. However for handlers to populate
-** such structures, they would need a place to store this upb_alloc* during
-** parsing; upb_handlers don't currently have a good way to accommodate this.
-**
-** TODO: UTF-8 checking?
-**/
-
-#ifndef UPB_MSG_H_
-#define UPB_MSG_H_
-
#ifdef __cplusplus
@@ -6569,21 +6416,6 @@ typedef void upb_msg;
* instances of this from a upb_msgfactory, and the factory always owns the
* msglayout. */
-/* Gets the factory for this layout */
-upb_msgfactory *upb_msglayout_factory(const upb_msglayout *l);
-
-/* Get the msglayout for a submessage. This requires that this field is a
- * submessage, ie. upb_fielddef_issubmsg(upb_msglayout_msgdef(l)) == true.
- *
- * Since map entry messages don't have layouts, if upb_fielddef_ismap(f) == true
- * then this function will return the layout for the map's value. It requires
- * that the value type of the map field is a submessage. */
-const upb_msglayout *upb_msglayout_sublayout(const upb_msglayout *l,
- const upb_fielddef *f);
-
-/* Returns the msgdef for this msglayout. */
-const upb_msgdef *upb_msglayout_msgdef(const upb_msglayout *l);
-
/** upb_visitor ***************************************************************/
@@ -6629,6 +6461,23 @@ const upb_visitorplan *upb_msgfactory_getvisitorplan(upb_msgfactory *f,
const upb_handlers *h);
+/** upb_stringview ************************************************************/
+
+typedef struct {
+ const char *data;
+ size_t size;
+} upb_stringview;
+
+UPB_INLINE upb_stringview upb_stringview_make(const char *data, size_t size) {
+ upb_stringview ret;
+ ret.data = data;
+ ret.size = size;
+ return ret;
+}
+
+#define UPB_STRINGVIEW_INIT(ptr, len) {ptr, len}
+
+
/** upb_msgval ****************************************************************/
/* A union representing all possible protobuf values. Used for generic get/set
@@ -6646,10 +6495,7 @@ typedef union {
const upb_msg* msg;
const upb_array* arr;
const void* ptr;
- struct {
- const char *ptr;
- size_t len;
- } str;
+ upb_stringview str;
} upb_msgval;
#define ACCESSORS(name, membername, ctype) \
@@ -6676,22 +6522,12 @@ ACCESSORS(map, map, const upb_map*)
ACCESSORS(msg, msg, const upb_msg*)
ACCESSORS(ptr, ptr, const void*)
ACCESSORS(arr, arr, const upb_array*)
+ACCESSORS(str, str, upb_stringview)
#undef ACCESSORS
-UPB_INLINE upb_msgval upb_msgval_str(const char *ptr, size_t len) {
- upb_msgval ret;
- ret.str.ptr = ptr;
- ret.str.len = len;
- return ret;
-}
-
-UPB_INLINE const char* upb_msgval_getstr(upb_msgval val) {
- return val.str.ptr;
-}
-
-UPB_INLINE size_t upb_msgval_getstrlen(upb_msgval val) {
- return val.str.len;
+UPB_INLINE upb_msgval upb_msgval_makestr(const char *data, size_t size) {
+ return upb_msgval_str(upb_stringview_make(data, size));
}
@@ -6716,19 +6552,29 @@ size_t upb_msg_sizeof(const upb_msglayout *l);
* upb_msg_uninit() must be called to release internally-allocated memory
* unless the allocator is an arena that does not require freeing.
*
+ * Please note that upb_msg_init() may return a value that is different than
+ * |msg|, so you must assign the return value and not cast your memory block
+ * to upb_msg* directly!
+ *
* Please note that upb_msg_uninit() does *not* free any submessages, maps,
* or arrays referred to by this message's fields. You must free them manually
- * yourself. */
-void upb_msg_init(upb_msg *msg, const upb_msglayout *l, upb_alloc *a);
-void upb_msg_uninit(upb_msg *msg, const upb_msglayout *l);
+ * yourself.
+ *
+ * upb_msg_uninit returns the original memory block, which may be useful if
+ * you dynamically allocated it (though upb_msg_new() would normally be more
+ * appropriate in this case). */
+upb_msg *upb_msg_init(void *msg, const upb_msglayout *l, upb_alloc *a);
+void *upb_msg_uninit(upb_msg *msg, const upb_msglayout *l);
/* Like upb_msg_init() / upb_msg_uninit(), except the message's memory is
* allocated / freed from the given upb_alloc. */
upb_msg *upb_msg_new(const upb_msglayout *l, upb_alloc *a);
void upb_msg_free(upb_msg *msg, const upb_msglayout *l);
-/* Returns the upb_alloc for the given message. */
-upb_alloc *upb_msg_alloc(const upb_msg *msg, const upb_msglayout *l);
+/* Returns the upb_alloc for the given message.
+ * TODO(haberman): get rid of this? Not sure we want to be storing this
+ * for every message. */
+upb_alloc *upb_msg_alloc(const upb_msg *msg);
/* Packs the tree of messages rooted at "msg" into a single hunk of memory,
* allocated from the given allocator. */
@@ -6748,25 +6594,14 @@ void *upb_msg_pack(const upb_msg *msg, const upb_msglayout *l,
* arenas).
*/
upb_msgval upb_msg_get(const upb_msg *msg,
- const upb_fielddef *f,
+ int field_index,
const upb_msglayout *l);
/* May only be called for fields where upb_fielddef_haspresence(f) == true. */
bool upb_msg_has(const upb_msg *msg,
- const upb_fielddef *f,
+ int field_index,
const upb_msglayout *l);
-/* Returns NULL if no field in the oneof is set. */
-const upb_fielddef *upb_msg_getoneofcase(const upb_msg *msg,
- const upb_oneofdef *o,
- const upb_msglayout *l);
-
-/* Returns true if any field in the oneof is set. */
-bool upb_msg_hasoneof(const upb_msg *msg,
- const upb_oneofdef *o,
- const upb_msglayout *l);
-
-
/* Mutable message API. May only be called by the owner of the message who
* knows its ownership scheme and how to keep it consistent. */
@@ -6774,8 +6609,8 @@ bool upb_msg_hasoneof(const upb_msg *msg,
* management: if you overwrite a pointer to a msg/array/map/string without
* cleaning it up (or using an arena) it will leak.
*/
-bool upb_msg_set(upb_msg *msg,
- const upb_fielddef *f,
+void upb_msg_set(upb_msg *msg,
+ int field_index,
upb_msgval val,
const upb_msglayout *l);
@@ -6786,12 +6621,7 @@ bool upb_msg_set(upb_msg *msg,
* arrays/maps/strings/msgs that this field may have pointed to.
*/
bool upb_msg_clearfield(upb_msg *msg,
- const upb_fielddef *f,
- const upb_msglayout *l);
-
-/* Clears all fields in the oneof such that none of them are set. */
-bool upb_msg_clearoneof(upb_msg *msg,
- const upb_oneofdef *o,
+ int field_index,
const upb_msglayout *l);
/* TODO(haberman): copyfrom()/mergefrom()? */
@@ -6904,9 +6734,288 @@ bool upb_msg_getscalarhandlerdata(const upb_handlers *h,
size_t *offset,
int32_t *hasbit);
+
+/** Interfaces for generated code *********************************************/
+
+#define UPB_NOT_IN_ONEOF UINT16_MAX
+#define UPB_NO_HASBIT UINT16_MAX
+#define UPB_NO_SUBMSG UINT16_MAX
+
+typedef struct {
+ uint32_t number;
+ uint32_t offset; /* If in a oneof, offset of default in default_msg below. */
+ uint16_t hasbit; /* UPB_NO_HASBIT if no hasbit. */
+ uint16_t oneof_index; /* UPB_NOT_IN_ONEOF if not in a oneof. */
+ uint16_t submsg_index; /* UPB_NO_SUBMSG if no submsg. */
+ uint8_t type;
+ uint8_t label;
+} upb_msglayout_fieldinit_v1;
+
+typedef struct {
+ uint32_t data_offset;
+ uint32_t case_offset;
+} upb_msglayout_oneofinit_v1;
+
+typedef struct upb_msglayout_msginit_v1 {
+ const struct upb_msglayout_msginit_v1 *const* submsgs;
+ const upb_msglayout_fieldinit_v1 *fields;
+ const upb_msglayout_oneofinit_v1 *oneofs;
+ void *default_msg;
+ /* Must be aligned to sizeof(void*). Doesn't include internal members like
+ * unknown fields, extension dict, pointer to msglayout, etc. */
+ uint32_t size;
+ uint16_t field_count;
+ uint16_t oneof_count;
+ bool extendable;
+ bool is_proto2;
+} upb_msglayout_msginit_v1;
+
+#define UPB_ALIGN_UP_TO(val, align) ((val + (align - 1)) & -align)
+#define UPB_ALIGNED_SIZEOF(type) UPB_ALIGN_UP_TO(sizeof(type), sizeof(void*))
+
+/* Initialize/uninitialize a msglayout from a msginit. If upb uses v1
+ * internally, this will not allocate any memory. Should only be used by
+ * generated code. */
+upb_msglayout *upb_msglayout_frominit_v1(
+ const upb_msglayout_msginit_v1 *init, upb_alloc *a);
+void upb_msglayout_uninit_v1(upb_msglayout *layout, upb_alloc *a);
+
UPB_END_EXTERN_C
#endif /* UPB_MSG_H_ */
+
+UPB_BEGIN_EXTERN_C
+
+bool upb_decode(upb_stringview buf, void *msg,
+ const upb_msglayout_msginit_v1 *l, upb_env *env);
+
+UPB_END_EXTERN_C
+
+#endif /* UPB_DECODE_H_ */
+/*
+** structs.int.h: structures definitions that are internal to upb.
+*/
+
+#ifndef UPB_STRUCTS_H_
+#define UPB_STRUCTS_H_
+
+struct upb_array {
+ upb_fieldtype_t type;
+ uint8_t element_size;
+ void *data; /* Each element is element_size. */
+ size_t len; /* Measured in elements. */
+ size_t size; /* Measured in elements. */
+ upb_alloc *alloc;
+};
+
+#endif /* UPB_STRUCTS_H_ */
+
+/*
+** This file contains definitions of structs that should be considered private
+** and NOT stable across versions of upb.
+**
+** The only reason they are declared here and not in .c files is to allow upb
+** and the application (if desired) to embed statically-initialized instances
+** of structures like defs.
+**
+** If you include this file, all guarantees of ABI compatibility go out the
+** window! Any code that includes this file needs to recompile against the
+** exact same version of upb that they are linking against.
+**
+** You also need to recompile if you change the value of the UPB_DEBUG_REFS
+** flag.
+*/
+
+
+#ifndef UPB_STATICINIT_H_
+#define UPB_STATICINIT_H_
+
+#ifdef __cplusplus
+/* Because of how we do our typedefs, this header can't be included from C++. */
+#error This file cannot be included from C++
+#endif
+
+/* upb_refcounted *************************************************************/
+
+
+/* upb_def ********************************************************************/
+
+struct upb_def {
+ upb_refcounted base;
+
+ const char *fullname;
+ const upb_filedef* file;
+ char type; /* A upb_deftype_t (char to save space) */
+
+ /* Used as a flag during the def's mutable stage. Must be false unless
+ * it is currently being used by a function on the stack. This allows
+ * us to easily determine which defs were passed into the function's
+ * current invocation. */
+ bool came_from_user;
+};
+
+#define UPB_DEF_INIT(name, type, vtbl, refs, ref2s) \
+ { UPB_REFCOUNT_INIT(vtbl, refs, ref2s), name, NULL, type, false }
+
+
+/* upb_fielddef ***************************************************************/
+
+struct upb_fielddef {
+ upb_def base;
+
+ union {
+ int64_t sint;
+ uint64_t uint;
+ double dbl;
+ float flt;
+ void *bytes;
+ } defaultval;
+ union {
+ const upb_msgdef *def; /* If !msg_is_symbolic. */
+ char *name; /* If msg_is_symbolic. */
+ } msg;
+ union {
+ const upb_def *def; /* If !subdef_is_symbolic. */
+ char *name; /* If subdef_is_symbolic. */
+ } sub; /* The msgdef or enumdef for this field, if upb_hassubdef(f). */
+ bool subdef_is_symbolic;
+ bool msg_is_symbolic;
+ const upb_oneofdef *oneof;
+ bool default_is_string;
+ bool type_is_set_; /* False until type is explicitly set. */
+ bool is_extension_;
+ bool lazy_;
+ bool packed_;
+ upb_intfmt_t intfmt;
+ bool tagdelim;
+ upb_fieldtype_t type_;
+ upb_label_t label_;
+ uint32_t number_;
+ uint32_t selector_base; /* Used to index into a upb::Handlers table. */
+ uint32_t index_;
+};
+
+extern const struct upb_refcounted_vtbl upb_fielddef_vtbl;
+
+#define UPB_FIELDDEF_INIT(label, type, intfmt, tagdelim, is_extension, lazy, \
+ packed, name, num, msgdef, subdef, selector_base, \
+ index, defaultval, refs, ref2s) \
+ { \
+ UPB_DEF_INIT(name, UPB_DEF_FIELD, &upb_fielddef_vtbl, refs, ref2s), \
+ defaultval, {msgdef}, {subdef}, NULL, false, false, \
+ type == UPB_TYPE_STRING || type == UPB_TYPE_BYTES, true, is_extension, \
+ lazy, packed, intfmt, tagdelim, type, label, num, selector_base, index \
+ }
+
+
+/* upb_msgdef *****************************************************************/
+
+struct upb_msgdef {
+ upb_def base;
+
+ size_t selector_count;
+ uint32_t submsg_field_count;
+
+ /* Tables for looking up fields by number and name. */
+ upb_inttable itof; /* int to field */
+ upb_strtable ntof; /* name to field/oneof */
+
+ /* Is this a map-entry message? */
+ bool map_entry;
+
+ /* Whether this message has proto2 or proto3 semantics. */
+ upb_syntax_t syntax;
+
+ /* TODO(haberman): proper extension ranges (there can be multiple). */
+};
+
+extern const struct upb_refcounted_vtbl upb_msgdef_vtbl;
+
+/* TODO: also support static initialization of the oneofs table. This will be
+ * needed if we compile in descriptors that contain oneofs. */
+#define UPB_MSGDEF_INIT(name, selector_count, submsg_field_count, itof, ntof, \
+ map_entry, syntax, refs, ref2s) \
+ { \
+ UPB_DEF_INIT(name, UPB_DEF_MSG, &upb_fielddef_vtbl, refs, ref2s), \
+ selector_count, submsg_field_count, itof, ntof, map_entry, syntax \
+ }
+
+
+/* upb_enumdef ****************************************************************/
+
+struct upb_enumdef {
+ upb_def base;
+
+ upb_strtable ntoi;
+ upb_inttable iton;
+ int32_t defaultval;
+};
+
+extern const struct upb_refcounted_vtbl upb_enumdef_vtbl;
+
+#define UPB_ENUMDEF_INIT(name, ntoi, iton, defaultval, refs, ref2s) \
+ { UPB_DEF_INIT(name, UPB_DEF_ENUM, &upb_enumdef_vtbl, refs, ref2s), ntoi, \
+ iton, defaultval }
+
+
+/* upb_oneofdef ***************************************************************/
+
+struct upb_oneofdef {
+ upb_refcounted base;
+
+ uint32_t index; /* Index within oneofs. */
+ const char *name;
+ upb_strtable ntof;
+ upb_inttable itof;
+ const upb_msgdef *parent;
+};
+
+extern const struct upb_refcounted_vtbl upb_oneofdef_vtbl;
+
+#define UPB_ONEOFDEF_INIT(name, ntof, itof, refs, ref2s) \
+ { UPB_REFCOUNT_INIT(&upb_oneofdef_vtbl, refs, ref2s), 0, name, ntof, itof }
+
+
+/* upb_symtab *****************************************************************/
+
+struct upb_symtab {
+ upb_refcounted base;
+
+ upb_strtable symtab;
+};
+
+struct upb_filedef {
+ upb_refcounted base;
+
+ const char *name;
+ const char *package;
+ const char *phpprefix;
+ const char *phpnamespace;
+ upb_syntax_t syntax;
+
+ upb_inttable defs;
+ upb_inttable deps;
+};
+
+extern const struct upb_refcounted_vtbl upb_filedef_vtbl;
+
+#endif /* UPB_STATICINIT_H_ */
+/*
+** upb_encode: parsing into a upb_msg using a upb_msglayout.
+*/
+
+#ifndef UPB_ENCODE_H_
+#define UPB_ENCODE_H_
+
+
+UPB_BEGIN_EXTERN_C
+
+char *upb_encode(const void *msg, const upb_msglayout_msginit_v1 *l,
+ upb_env *env, size_t *size);
+
+UPB_END_EXTERN_C
+
+#endif /* UPB_ENCODE_H_ */
/*
** upb::descriptor::Reader (upb_descreader)
**
@@ -8296,21 +8405,9 @@ UPB_INLINE void upb_pbdecoder_unpackdispatch(uint64_t dispatch, uint64_t *ofs,
extern "C" {
#endif
-/* A list of types as they are encoded on-the-wire. */
-typedef enum {
- UPB_WIRE_TYPE_VARINT = 0,
- UPB_WIRE_TYPE_64BIT = 1,
- UPB_WIRE_TYPE_DELIMITED = 2,
- UPB_WIRE_TYPE_START_GROUP = 3,
- UPB_WIRE_TYPE_END_GROUP = 4,
- UPB_WIRE_TYPE_32BIT = 5
-} upb_wiretype_t;
-
#define UPB_MAX_WIRE_TYPE 5
-/* The maximum number of bytes that it takes to encode a 64-bit varint.
- * Note that with a better encoding this could be 9 (TODO: write up a
- * wiki document about this). */
+/* The maximum number of bytes that it takes to encode a 64-bit varint. */
#define UPB_PB_VARINT_MAX_LEN 10
/* Array of the "native" (ie. non-packed-repeated) wire type for the given a