1b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer#ifndef __GOOGLE_PROTOBUF_PHP_PROTOBUF_H__
2b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer#define __GOOGLE_PROTOBUF_PHP_PROTOBUF_H__
3b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer
4b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer#include <php.h>
5b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer
6b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer#include "upb.h"
7b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer
8b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer#define PHP_PROTOBUF_EXTNAME "protobuf"
9b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer#define PHP_PROTOBUF_VERSION "0.01"
10b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer
11b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer// Forward decls.
12b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammerstruct DescriptorPool;
13b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammerstruct Descriptor;
14b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammerstruct FieldDescriptor;
15b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammerstruct EnumDescriptor;
16b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammerstruct MessageLayout;
17b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammerstruct MessageField;
18b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammerstruct MessageHeader;
19b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammerstruct MessageBuilderContext;
20b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammerstruct EnumBuilderContext;
21b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer
22b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammertypedef struct DescriptorPool DescriptorPool;
23b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammertypedef struct Descriptor Descriptor;
24b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammertypedef struct FieldDescriptor FieldDescriptor;
25b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammertypedef struct OneofDescriptor OneofDescriptor;
26b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammertypedef struct EnumDescriptor EnumDescriptor;
27b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammertypedef struct MessageLayout MessageLayout;
28b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammertypedef struct MessageField MessageField;
29b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammertypedef struct MessageHeader MessageHeader;
30b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammertypedef struct MessageBuilderContext MessageBuilderContext;
31b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammertypedef struct OneofBuilderContext OneofBuilderContext;
32b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammertypedef struct EnumBuilderContext EnumBuilderContext;
33b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer
34b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammerextern zend_class_entry* builder_type;
35b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammerextern zend_class_entry* descriptor_type;
36b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammerextern zend_class_entry* message_builder_context_type;
37b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer
38b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammerextern DescriptorPool* generated_pool;  // The actual generated pool
39b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer
40b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas BerghammerZEND_BEGIN_MODULE_GLOBALS(protobuf)
41b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer  zval* generated_pool;
42b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer  zend_object_handlers* message_handlers;
43b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer  HashTable upb_def_to_php_obj_map;
44b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas BerghammerZEND_END_MODULE_GLOBALS(protobuf)
45b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer
46b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas BerghammerZEND_DECLARE_MODULE_GLOBALS(protobuf)
47b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer
48b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer#ifdef ZTS
49b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer#define PROTOBUF_G(v) TSRMG(protobuf_globals_id, zend_protobuf_globals*, v)
50b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer#else
51b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer#define PROTOBUF_G(v) (protobuf_globals.v)
52b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer#endif
53b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer
54b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer// -----------------------------------------------------------------------------
55b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer// PHP functions and global variables.
56b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer// -----------------------------------------------------------------------------
57b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer
58b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas BerghammerPHP_MINIT_FUNCTION(protobuf);
59b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer
60b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer// -----------------------------------------------------------------------------
61b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer// PHP class structure.
62b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer// -----------------------------------------------------------------------------
63b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer
64b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammerstruct DescriptorPool {
65b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer  zend_object std;
66b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer  upb_symtab* symtab;
67b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer  HashTable* pending_list;
68b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer};
69b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer
70b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammerstruct Descriptor {
71b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer  zend_object std;
72b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer  const upb_msgdef* msgdef;
73b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer  MessageLayout* layout;
74b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer  // zval* klass;  // begins as NULL
75b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer  // const upb_handlers* fill_handlers;
76b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer  // const upb_pbdecodermethod* fill_method;
77b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer  const upb_handlers* pb_serialize_handlers;
78b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer  // const upb_handlers* json_serialize_handlers;
79b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer  // Handlers hold type class references for sub-message fields directly in some
80b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer  // cases. We need to keep these rooted because they might otherwise be
81b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer  // collected.
82b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer  // zval_array typeclass_references;
83b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer};
84b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer
85b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammerstruct FieldDescriptor {
86b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer  zend_object std;
87b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer  const upb_fielddef* fielddef;
88b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer};
89b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer
90b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammerstruct OneofDescriptor {
91b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer  zend_object std;
92b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer  const upb_oneofdef* oneofdef;
93b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer};
94b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer
95b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammerstruct EnumDescriptor {
96b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer  zend_object std;
97b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer  const upb_enumdef* enumdef;
98b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer  // zval* module;  // begins as NULL
99b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer};
100b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer
101b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer// -----------------------------------------------------------------------------
102b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer// Native slot storage abstraction.
103b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer// -----------------------------------------------------------------------------
104b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer
105b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer#define NATIVE_SLOT_MAX_SIZE sizeof(uint64_t)
106b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer
107b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammersize_t native_slot_size(upb_fieldtype_t type);
108b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer
109b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer#define MAP_KEY_FIELD 1
110b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer#define MAP_VALUE_FIELD 2
111b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer
112b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer// Oneof case slot value to indicate that no oneof case is set. The value `0` is
113b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer// safe because field numbers are used as case identifiers, and no field can
114b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer// have a number of 0.
115b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer#define ONEOF_CASE_NONE 0
116b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer
117b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer// These operate on a map field (i.e., a repeated field of submessages whose
118b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer// submessage type is a map-entry msgdef).
119b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammerbool is_map_field(const upb_fielddef* field);
120b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammerconst upb_fielddef* map_field_key(const upb_fielddef* field);
121b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammerconst upb_fielddef* map_field_value(const upb_fielddef* field);
122b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer
123b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer// These operate on a map-entry msgdef.
124b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammerconst upb_fielddef* map_entry_key(const upb_msgdef* msgdef);
125b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammerconst upb_fielddef* map_entry_value(const upb_msgdef* msgdef);
126b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer
127b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer// -----------------------------------------------------------------------------
128b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer// Message layout / storage.
129b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer// -----------------------------------------------------------------------------
130b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer
131b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer#define MESSAGE_FIELD_NO_CASE ((size_t)-1)
132b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer
133b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammerstruct MessageField {
134b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer  size_t offset;
135b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer  size_t case_offset;  // for oneofs, a uint32. Else, MESSAGE_FIELD_NO_CASE.
136b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer};
137b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer
138b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammerstruct MessageLayout {
139b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer  const upb_msgdef* msgdef;
140b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer  MessageField* fields;
141b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer  size_t size;
142b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer};
143b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer
144b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammervoid layout_init(MessageLayout* layout, void* storage);
145b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammerzval* layout_get(MessageLayout* layout, const void* storage,
146b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer                 const upb_fielddef* field TSRMLS_DC);
147b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas BerghammerMessageLayout* create_layout(const upb_msgdef* msgdef);
148b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammervoid free_layout(MessageLayout* layout);
149b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammerzval* native_slot_get(upb_fieldtype_t type, /*VALUE type_class,*/
150b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer                      const void* memory TSRMLS_DC);
151b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer
152b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer// -----------------------------------------------------------------------------
153b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer// Message class creation.
154b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer// -----------------------------------------------------------------------------
155b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer
156b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammerstruct MessageHeader {
157b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer  zend_object std;
158b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer  Descriptor* descriptor;  // kept alive by self.class.descriptor reference.
159b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer                           // Data comes after this.
160b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer};
161b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer
162b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammerstruct MessageBuilderContext {
163b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer  zend_object std;
164b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer  zval* descriptor;
165b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer  zval* pool;
166b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer};
167b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer
168b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammerstruct OneofBuilderContext {
169b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer  zend_object std;
170b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer  // VALUE descriptor;
171b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer  // VALUE builder;
172b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer};
173b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer
174b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammerstruct EnumBuilderContext {
175b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer  zend_object std;
176b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer  // VALUE enumdesc;
177b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer};
178b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer
179b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer// Forward-declare all of the PHP method implementations.
180b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer
181b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas BerghammerDescriptorPool* php_to_descriptor_pool(zval* value TSRMLS_DC);
182b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammerzend_object_value descriptor_pool_create(zend_class_entry *ce TSRMLS_DC);
183b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammervoid descriptor_pool_free_c(DescriptorPool* object TSRMLS_DC);
184b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammervoid descriptor_pool_free(void* object TSRMLS_DC);
185b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammervoid descriptor_pool_init_c_instance(DescriptorPool* pool TSRMLS_DC);
186b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas BerghammerPHP_METHOD(DescriptorPool, addMessage);
187b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas BerghammerPHP_METHOD(DescriptorPool, finalize);
188b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer
189b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas BerghammerDescriptor* php_to_descriptor(zval* value TSRMLS_DC);
190b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammerzend_object_value descriptor_create(zend_class_entry *ce TSRMLS_DC);
191b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammervoid descriptor_init_c_instance(Descriptor* intern TSRMLS_DC);
192b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammervoid descriptor_free_c(Descriptor* object TSRMLS_DC);
193b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammervoid descriptor_free(void* object TSRMLS_DC);
194b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammervoid descriptor_name_set(Descriptor *desc, const char *name);
195b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer
196b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas BerghammerMessageBuilderContext* php_to_message_builder_context(zval* value TSRMLS_DC);
197b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammerzend_object_value message_builder_context_create(
198b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer    zend_class_entry* ce TSRMLS_DC);
199b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammervoid message_builder_context_init_c_instance(
200b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer    MessageBuilderContext* intern TSRMLS_DC);
201b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammervoid message_builder_context_free_c(MessageBuilderContext* object TSRMLS_DC);
202b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammervoid message_builder_context_free(void* object TSRMLS_DC);
203b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas BerghammerPHP_METHOD(MessageBuilderContext, optional);
204b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas BerghammerPHP_METHOD(MessageBuilderContext, finalizeToPool);
205b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer
206b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas BerghammerPHP_METHOD(Message, encode);
207b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammerconst zend_class_entry* build_class_from_descriptor(
208b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer    zval* php_descriptor TSRMLS_DC);
209b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer
210b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas BerghammerPHP_FUNCTION(get_generated_pool);
211b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer
212b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer// -----------------------------------------------------------------------------
213b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer// Global map from upb {msg,enum}defs to wrapper Descriptor/EnumDescriptor
214b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer// instances.
215b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer// ----------------------------------------------------------------------------
216b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer
217b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammervoid add_def_obj(const void* def, zval* value);
218b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammerzval* get_def_obj(const void* def);
219b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer
220b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer// -----------------------------------------------------------------------------
221b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer// Utilities.
222b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer// -----------------------------------------------------------------------------
223b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer
224b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer// PHP Array utils.
225b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer#define Z_ARRVAL_SIZE_P(zval_p) zend_hash_num_elements(Z_ARRVAL_P(zval_p))
226b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer#define Z_ARRVAL_BEGIN_P(zval_p) Z_ARRVAL_P(zval_p)->pListHead
227b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer#define Z_BUCKET_NEXT_PP(bucket_pp) *bucket_pp = (*bucket_pp)->pListNext
228b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer
229b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer#define DEFINE_PHP_OBJECT(class_name, class_name_lower, name) \
230b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer  do {                                                        \
231b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer    zval* name;                                               \
232b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer    MAKE_STD_ZVAL(name);                                      \
233b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer    object_init_ex(name, class_name_lower##_type);            \
234b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer  } while (0)
235b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer
236b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer#define DEFINE_PHP_WRAPPER(class_name, class_name_lower, name, intern) \
237b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer  zval* name;                                                          \
238b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer  MAKE_STD_ZVAL(name);                                                 \
239b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer  object_init_ex(name, class_name_lower##_type);                       \
240b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer  Z_OBJVAL_P(name)                                                     \
241b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer      .handle = zend_objects_store_put(                                \
242b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer      intern, (zend_objects_store_dtor_t)zend_objects_destroy_object,  \
243b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer      class_name_lower##_free, NULL TSRMLS_CC);
244b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer
245b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer#define DEFINE_PHP_ZVAL(name) \
246b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer  do {                        \
247b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer    zval* name;               \
248b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer    MAKE_STD_ZVAL(name);      \
249b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer  } while (0)
250b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer
251b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer#define DEFINE_PHP_STRING(name, value) \
252b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer  do {                                 \
253b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer    zval* name;                        \
254b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer    MAKE_STD_ZVAL(name);               \
255b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer    ZVAL_STRING(name, value, 1);       \
256b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer  } while (0)
257b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer
258b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer// Upb Utilities
259b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer
260b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammervoid check_upb_status(const upb_status* status, const char* msg);
261b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer
262b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer#define CHECK_UPB(code, msg)             \
263b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer  do {                                   \
264b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer    upb_status status = UPB_STATUS_INIT; \
265b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer    code;                                \
266b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer    check_upb_status(&status, msg);      \
267b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer  } while (0)
268b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer
269b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer// Memory management
270b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer
271b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer#define ALLOC(class_name) (class_name*) emalloc(sizeof(class_name))
272b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer#define ALLOC_N(class_name, n) (class_name*) emalloc(sizeof(class_name) * n)
273b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer#define FREE(object) efree(object)
274b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer
275b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer// Type Checking
276b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer#define CHECK_TYPE(field, type)             \
277b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer  if (Z_TYPE_P(field) != type) {            \
278b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer    zend_error(E_ERROR, "Unexpected type"); \
279b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer  }
280b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer
281b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer#endif  // __GOOGLE_PROTOBUF_PHP_PROTOBUF_H__
282