From 3b3c8abb9635eb3ea078a821a99c9ef29d66dff7 Mon Sep 17 00:00:00 2001 From: Jisi Liu Date: Wed, 30 Mar 2016 11:39:59 -0700 Subject: Integrate google internal changes. --- php/ext/google/protobuf/protobuf.h | 281 +++++++++++++++++++++++++++++++++++++ 1 file changed, 281 insertions(+) create mode 100644 php/ext/google/protobuf/protobuf.h (limited to 'php/ext/google/protobuf/protobuf.h') diff --git a/php/ext/google/protobuf/protobuf.h b/php/ext/google/protobuf/protobuf.h new file mode 100644 index 00000000..f9038550 --- /dev/null +++ b/php/ext/google/protobuf/protobuf.h @@ -0,0 +1,281 @@ +#ifndef __GOOGLE_PROTOBUF_PHP_PROTOBUF_H__ +#define __GOOGLE_PROTOBUF_PHP_PROTOBUF_H__ + +#include + +#include "upb.h" + +#define PHP_PROTOBUF_EXTNAME "protobuf" +#define PHP_PROTOBUF_VERSION "0.01" + +// Forward decls. +struct DescriptorPool; +struct Descriptor; +struct FieldDescriptor; +struct EnumDescriptor; +struct MessageLayout; +struct MessageField; +struct MessageHeader; +struct MessageBuilderContext; +struct EnumBuilderContext; + +typedef struct DescriptorPool DescriptorPool; +typedef struct Descriptor Descriptor; +typedef struct FieldDescriptor FieldDescriptor; +typedef struct OneofDescriptor OneofDescriptor; +typedef struct EnumDescriptor EnumDescriptor; +typedef struct MessageLayout MessageLayout; +typedef struct MessageField MessageField; +typedef struct MessageHeader MessageHeader; +typedef struct MessageBuilderContext MessageBuilderContext; +typedef struct OneofBuilderContext OneofBuilderContext; +typedef struct EnumBuilderContext EnumBuilderContext; + +extern zend_class_entry* builder_type; +extern zend_class_entry* descriptor_type; +extern zend_class_entry* message_builder_context_type; + +extern DescriptorPool* generated_pool; // The actual generated pool + +ZEND_BEGIN_MODULE_GLOBALS(protobuf) + zval* generated_pool; + zend_object_handlers* message_handlers; + HashTable upb_def_to_php_obj_map; +ZEND_END_MODULE_GLOBALS(protobuf) + +ZEND_DECLARE_MODULE_GLOBALS(protobuf) + +#ifdef ZTS +#define PROTOBUF_G(v) TSRMG(protobuf_globals_id, zend_protobuf_globals*, v) +#else +#define PROTOBUF_G(v) (protobuf_globals.v) +#endif + +// ----------------------------------------------------------------------------- +// PHP functions and global variables. +// ----------------------------------------------------------------------------- + +PHP_MINIT_FUNCTION(protobuf); + +// ----------------------------------------------------------------------------- +// PHP class structure. +// ----------------------------------------------------------------------------- + +struct DescriptorPool { + zend_object std; + upb_symtab* symtab; + HashTable* pending_list; +}; + +struct Descriptor { + zend_object std; + const upb_msgdef* msgdef; + MessageLayout* layout; + // zval* klass; // begins as NULL + // const upb_handlers* fill_handlers; + // const upb_pbdecodermethod* fill_method; + const upb_handlers* pb_serialize_handlers; + // const upb_handlers* json_serialize_handlers; + // Handlers hold type class references for sub-message fields directly in some + // cases. We need to keep these rooted because they might otherwise be + // collected. + // zval_array typeclass_references; +}; + +struct FieldDescriptor { + zend_object std; + const upb_fielddef* fielddef; +}; + +struct OneofDescriptor { + zend_object std; + const upb_oneofdef* oneofdef; +}; + +struct EnumDescriptor { + zend_object std; + const upb_enumdef* enumdef; + // zval* module; // begins as NULL +}; + +// ----------------------------------------------------------------------------- +// Native slot storage abstraction. +// ----------------------------------------------------------------------------- + +#define NATIVE_SLOT_MAX_SIZE sizeof(uint64_t) + +size_t native_slot_size(upb_fieldtype_t type); + +#define MAP_KEY_FIELD 1 +#define MAP_VALUE_FIELD 2 + +// Oneof case slot value to indicate that no oneof case is set. The value `0` is +// safe because field numbers are used as case identifiers, and no field can +// have a number of 0. +#define ONEOF_CASE_NONE 0 + +// These operate on a map field (i.e., a repeated field of submessages whose +// submessage type is a map-entry msgdef). +bool is_map_field(const upb_fielddef* field); +const upb_fielddef* map_field_key(const upb_fielddef* field); +const upb_fielddef* map_field_value(const upb_fielddef* field); + +// These operate on a map-entry msgdef. +const upb_fielddef* map_entry_key(const upb_msgdef* msgdef); +const upb_fielddef* map_entry_value(const upb_msgdef* msgdef); + +// ----------------------------------------------------------------------------- +// Message layout / storage. +// ----------------------------------------------------------------------------- + +#define MESSAGE_FIELD_NO_CASE ((size_t)-1) + +struct MessageField { + size_t offset; + size_t case_offset; // for oneofs, a uint32. Else, MESSAGE_FIELD_NO_CASE. +}; + +struct MessageLayout { + const upb_msgdef* msgdef; + MessageField* fields; + size_t size; +}; + +void layout_init(MessageLayout* layout, void* storage); +zval* layout_get(MessageLayout* layout, const void* storage, + const upb_fielddef* field TSRMLS_DC); +MessageLayout* create_layout(const upb_msgdef* msgdef); +void free_layout(MessageLayout* layout); +zval* native_slot_get(upb_fieldtype_t type, /*VALUE type_class,*/ + const void* memory TSRMLS_DC); + +// ----------------------------------------------------------------------------- +// Message class creation. +// ----------------------------------------------------------------------------- + +struct MessageHeader { + zend_object std; + Descriptor* descriptor; // kept alive by self.class.descriptor reference. + // Data comes after this. +}; + +struct MessageBuilderContext { + zend_object std; + zval* descriptor; + zval* pool; +}; + +struct OneofBuilderContext { + zend_object std; + // VALUE descriptor; + // VALUE builder; +}; + +struct EnumBuilderContext { + zend_object std; + // VALUE enumdesc; +}; + +// Forward-declare all of the PHP method implementations. + +DescriptorPool* php_to_descriptor_pool(zval* value TSRMLS_DC); +zend_object_value descriptor_pool_create(zend_class_entry *ce TSRMLS_DC); +void descriptor_pool_free_c(DescriptorPool* object TSRMLS_DC); +void descriptor_pool_free(void* object TSRMLS_DC); +void descriptor_pool_init_c_instance(DescriptorPool* pool TSRMLS_DC); +PHP_METHOD(DescriptorPool, addMessage); +PHP_METHOD(DescriptorPool, finalize); + +Descriptor* php_to_descriptor(zval* value TSRMLS_DC); +zend_object_value descriptor_create(zend_class_entry *ce TSRMLS_DC); +void descriptor_init_c_instance(Descriptor* intern TSRMLS_DC); +void descriptor_free_c(Descriptor* object TSRMLS_DC); +void descriptor_free(void* object TSRMLS_DC); +void descriptor_name_set(Descriptor *desc, const char *name); + +MessageBuilderContext* php_to_message_builder_context(zval* value TSRMLS_DC); +zend_object_value message_builder_context_create( + zend_class_entry* ce TSRMLS_DC); +void message_builder_context_init_c_instance( + MessageBuilderContext* intern TSRMLS_DC); +void message_builder_context_free_c(MessageBuilderContext* object TSRMLS_DC); +void message_builder_context_free(void* object TSRMLS_DC); +PHP_METHOD(MessageBuilderContext, optional); +PHP_METHOD(MessageBuilderContext, finalizeToPool); + +PHP_METHOD(Message, encode); +const zend_class_entry* build_class_from_descriptor( + zval* php_descriptor TSRMLS_DC); + +PHP_FUNCTION(get_generated_pool); + +// ----------------------------------------------------------------------------- +// Global map from upb {msg,enum}defs to wrapper Descriptor/EnumDescriptor +// instances. +// ---------------------------------------------------------------------------- + +void add_def_obj(const void* def, zval* value); +zval* get_def_obj(const void* def); + +// ----------------------------------------------------------------------------- +// Utilities. +// ----------------------------------------------------------------------------- + +// PHP Array utils. +#define Z_ARRVAL_SIZE_P(zval_p) zend_hash_num_elements(Z_ARRVAL_P(zval_p)) +#define Z_ARRVAL_BEGIN_P(zval_p) Z_ARRVAL_P(zval_p)->pListHead +#define Z_BUCKET_NEXT_PP(bucket_pp) *bucket_pp = (*bucket_pp)->pListNext + +#define DEFINE_PHP_OBJECT(class_name, class_name_lower, name) \ + do { \ + zval* name; \ + MAKE_STD_ZVAL(name); \ + object_init_ex(name, class_name_lower##_type); \ + } while (0) + +#define DEFINE_PHP_WRAPPER(class_name, class_name_lower, name, intern) \ + zval* name; \ + MAKE_STD_ZVAL(name); \ + object_init_ex(name, class_name_lower##_type); \ + Z_OBJVAL_P(name) \ + .handle = zend_objects_store_put( \ + intern, (zend_objects_store_dtor_t)zend_objects_destroy_object, \ + class_name_lower##_free, NULL TSRMLS_CC); + +#define DEFINE_PHP_ZVAL(name) \ + do { \ + zval* name; \ + MAKE_STD_ZVAL(name); \ + } while (0) + +#define DEFINE_PHP_STRING(name, value) \ + do { \ + zval* name; \ + MAKE_STD_ZVAL(name); \ + ZVAL_STRING(name, value, 1); \ + } while (0) + +// Upb Utilities + +void check_upb_status(const upb_status* status, const char* msg); + +#define CHECK_UPB(code, msg) \ + do { \ + upb_status status = UPB_STATUS_INIT; \ + code; \ + check_upb_status(&status, msg); \ + } while (0) + +// Memory management + +#define ALLOC(class_name) (class_name*) emalloc(sizeof(class_name)) +#define ALLOC_N(class_name, n) (class_name*) emalloc(sizeof(class_name) * n) +#define FREE(object) efree(object) + +// Type Checking +#define CHECK_TYPE(field, type) \ + if (Z_TYPE_P(field) != type) { \ + zend_error(E_ERROR, "Unexpected type"); \ + } + +#endif // __GOOGLE_PROTOBUF_PHP_PROTOBUF_H__ -- cgit v1.2.3