Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(256)

Side by Side Diff: third_party/protobuf/php/ext/google/protobuf/def.c

Issue 2495533002: third_party/protobuf: Update to HEAD (83d681ee2c) (Closed)
Patch Set: Make chrome settings proto generated file a component Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2008 Google Inc. All rights reserved.
3 // https://developers.google.com/protocol-buffers/
4 //
5 // Redistribution and use in source and binary forms, with or without
6 // modification, are permitted provided that the following conditions are
7 // met:
8 //
9 // * Redistributions of source code must retain the above copyright
10 // notice, this list of conditions and the following disclaimer.
11 // * Redistributions in binary form must reproduce the above
12 // copyright notice, this list of conditions and the following disclaimer
13 // in the documentation and/or other materials provided with the
14 // distribution.
15 // * Neither the name of Google Inc. nor the names of its
16 // contributors may be used to endorse or promote products derived from
17 // this software without specific prior written permission.
18 //
19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
1 #include "protobuf.h" 31 #include "protobuf.h"
2 32
33 // Forward declare.
34 static zend_object_value descriptor_create(zend_class_entry *ce TSRMLS_DC);
35 static void descriptor_init_c_instance(Descriptor* intern TSRMLS_DC);
36 static void descriptor_free_c(Descriptor* object TSRMLS_DC);
37 static void descriptor_free(void* object TSRMLS_DC);
38
39 static zend_object_value enum_descriptor_create(zend_class_entry *ce TSRMLS_DC);
40 static void enum_descriptor_init_c_instance(EnumDescriptor* intern TSRMLS_DC);
41 static void enum_descriptor_free_c(EnumDescriptor* object TSRMLS_DC);
42 static void enum_descriptor_free(void* object TSRMLS_DC);
43
44 static zend_object_value descriptor_pool_create(zend_class_entry *ce TSRMLS_DC);
45 static void descriptor_pool_free_c(DescriptorPool* object TSRMLS_DC);
46 static void descriptor_pool_free(void* object TSRMLS_DC);
47 static void descriptor_pool_init_c_instance(DescriptorPool* pool TSRMLS_DC);
48
3 // ----------------------------------------------------------------------------- 49 // -----------------------------------------------------------------------------
4 // Common Utilities 50 // Common Utilities
5 // ----------------------------------------------------------------------------- 51 // -----------------------------------------------------------------------------
6 52
7 void check_upb_status(const upb_status* status, const char* msg) { 53 static void check_upb_status(const upb_status* status, const char* msg) {
8 if (!upb_ok(status)) { 54 if (!upb_ok(status)) {
9 zend_error("%s: %s\n", msg, upb_status_errmsg(status)); 55 zend_error(E_ERROR, "%s: %s\n", msg, upb_status_errmsg(status));
10 } 56 }
11 } 57 }
12 58
13 59 static void upb_filedef_free(void *r) {
14 static upb_def *check_notfrozen(const upb_def *def) { 60 upb_filedef *f = *(upb_filedef **)r;
15 if (upb_def_isfrozen(def)) { 61 size_t i;
16 zend_error(E_ERROR, 62
17 "Attempt to modify a frozen descriptor. Once descriptors are " 63 for (i = 0; i < upb_filedef_depcount(f); i++) {
18 "added to the descriptor pool, they may not be modified."); 64 upb_filedef_unref(upb_filedef_dep(f, i), f);
19 } 65 }
20 return (upb_def *)def; 66
21 } 67 upb_inttable_uninit(&f->defs);
22 68 upb_inttable_uninit(&f->deps);
23 static upb_msgdef *check_msgdef_notfrozen(const upb_msgdef *def) { 69 upb_gfree((void *)f->name);
24 return upb_downcast_msgdef_mutable(check_notfrozen((const upb_def *)def)); 70 upb_gfree((void *)f->package);
25 } 71 upb_gfree(f);
26 72 }
27 static upb_fielddef *check_fielddef_notfrozen(const upb_fielddef *def) { 73
28 return upb_downcast_fielddef_mutable(check_notfrozen((const upb_def *)def)); 74 // Camel-case the field name and append "Entry" for generated map entry name.
29 } 75 // e.g. map<KeyType, ValueType> foo_map => FooMapEntry
30 76 static void append_map_entry_name(char *result, const char *field_name,
31 #define PROTOBUF_WRAP_INTERN(wrapper, intern, intern_dtor) \ 77 int pos) {
32 Z_TYPE_P(wrapper) = IS_OBJECT; \ 78 bool cap_next = true;
33 Z_OBJVAL_P(wrapper) \ 79 int i;
34 .handle = zend_objects_store_put( \ 80
35 intern, (zend_objects_store_dtor_t)zend_objects_destroy_object, \ 81 for (i = 0; i < strlen(field_name); ++i) {
36 intern_dtor, NULL TSRMLS_CC); \ 82 if (field_name[i] == '_') {
37 Z_OBJVAL_P(wrapper).handlers = zend_get_std_object_handlers(); 83 cap_next = true;
38 84 } else if (cap_next) {
39 #define PROTOBUF_SETUP_ZEND_WRAPPER(class_name, class_name_lower, wrapper, \ 85 // Note: Do not use ctype.h due to locales.
40 intern) \ 86 if ('a' <= field_name[i] && field_name[i] <= 'z') {
41 Z_TYPE_P(wrapper) = IS_OBJECT; \ 87 result[pos++] = field_name[i] - 'a' + 'A';
42 class_name *intern = ALLOC(class_name); \ 88 } else {
43 memset(intern, 0, sizeof(class_name)); \ 89 result[pos++] = field_name[i];
44 class_name_lower##_init_c_instance(intern TSRMLS_CC); \ 90 }
45 Z_OBJVAL_P(wrapper) \ 91 cap_next = false;
46 .handle = zend_objects_store_put(intern, NULL, class_name_lower##_free, \ 92 } else {
47 NULL TSRMLS_CC); \ 93 result[pos++] = field_name[i];
48 Z_OBJVAL_P(wrapper).handlers = zend_get_std_object_handlers(); 94 }
49 95 }
50 #define PROTOBUF_CREATE_ZEND_WRAPPER(class_name, class_name_lower, wrapper, \ 96 strcat(result, "Entry");
51 intern) \ 97 }
52 MAKE_STD_ZVAL(wrapper); \ 98
53 PROTOBUF_SETUP_ZEND_WRAPPER(class_name, class_name_lower, wrapper, intern); 99 #define CHECK_UPB(code, msg) \
54 100 do { \
55 #define DEFINE_CLASS(name, name_lower, string_name) \ 101 upb_status status = UPB_STATUS_INIT; \
56 zend_class_entry *name_lower##_type; \ 102 code; \
103 check_upb_status(&status, msg); \
104 } while (0)
105
106 // Define PHP class
107 #define DEFINE_PROTOBUF_INIT_CLASS(name_lower, string_name) \
57 void name_lower##_init(TSRMLS_D) { \ 108 void name_lower##_init(TSRMLS_D) { \
58 zend_class_entry class_type; \ 109 zend_class_entry class_type; \
59 INIT_CLASS_ENTRY(class_type, string_name, name_lower##_methods); \ 110 INIT_CLASS_ENTRY(class_type, string_name, name_lower##_methods); \
60 name_lower##_type = zend_register_internal_class(&class_type TSRMLS_CC); \ 111 name_lower##_type = zend_register_internal_class(&class_type TSRMLS_CC); \
61 name_lower##_type->create_object = name_lower##_create; \ 112 name_lower##_type->create_object = name_lower##_create; \
62 } \ 113 }
63 name *php_to_##name_lower(zval *val TSRMLS_DC) { \ 114
64 return (name *)zend_object_store_get_object(val TSRMLS_CC); \ 115 #define DEFINE_PROTOBUF_CREATE(name, name_lower) \
65 } \ 116 static zend_object_value name_lower##_create( \
66 void name_lower##_free(void *object TSRMLS_DC) { \ 117 zend_class_entry* ce TSRMLS_DC) { \
67 name *intern = (name *)object; \ 118 zend_object_value return_value; \
68 name_lower##_free_c(intern TSRMLS_CC); \ 119 name* intern = (name*)emalloc(sizeof(name)); \
69 efree(object); \ 120 memset(intern, 0, sizeof(name)); \
70 } \ 121 name_lower##_init_c_instance(intern TSRMLS_CC); \
71 zend_object_value name_lower##_create(zend_class_entry *ce TSRMLS_DC) { \ 122 return_value.handle = zend_objects_store_put( \
72 zend_object_value return_value; \ 123 intern, (zend_objects_store_dtor_t)zend_objects_destroy_object, \
73 name *intern = (name *)emalloc(sizeof(name)); \ 124 name_lower##_free, NULL TSRMLS_CC); \
74 memset(intern, 0, sizeof(name)); \ 125 return_value.handlers = zend_get_std_object_handlers(); \
75 name_lower##_init_c_instance(intern TSRMLS_CC); \ 126 return return_value; \
76 return_value.handle = zend_objects_store_put( \ 127 }
77 intern, (zend_objects_store_dtor_t)zend_objects_destroy_object, \ 128
78 name_lower##_free, NULL TSRMLS_CC); \ 129 #define DEFINE_PROTOBUF_FREE(name, name_lower) \
79 return_value.handlers = zend_get_std_object_handlers(); \ 130 static void name_lower##_free(void* object TSRMLS_DC) { \
80 return return_value; \ 131 name* intern = (name*)object; \
81 } 132 name_lower##_free_c(intern TSRMLS_CC); \
82 133 efree(object); \
83 // ----------------------------------------------------------------------------- 134 }
84 // DescriptorPool 135
85 // ----------------------------------------------------------------------------- 136 #define DEFINE_CLASS(name, name_lower, string_name) \
86 137 zend_class_entry* name_lower##_type; \
87 static zend_function_entry descriptor_pool_methods[] = { 138 DEFINE_PROTOBUF_FREE(name, name_lower) \
88 PHP_ME(DescriptorPool, addMessage, NULL, ZEND_ACC_PUBLIC) 139 DEFINE_PROTOBUF_CREATE(name, name_lower) \
89 PHP_ME(DescriptorPool, finalize, NULL, ZEND_ACC_PUBLIC) 140 DEFINE_PROTOBUF_INIT_CLASS(name_lower, string_name)
141
142 // -----------------------------------------------------------------------------
143 // GPBType
144 // -----------------------------------------------------------------------------
145
146 zend_class_entry* gpb_type_type;
147
148 static zend_function_entry gpb_type_methods[] = {
90 ZEND_FE_END 149 ZEND_FE_END
91 }; 150 };
92 151
152 void gpb_type_init(TSRMLS_D) {
153 zend_class_entry class_type;
154 INIT_CLASS_ENTRY(class_type, "Google\\Protobuf\\Internal\\GPBType",
155 gpb_type_methods);
156 gpb_type_type = zend_register_internal_class(&class_type TSRMLS_CC);
157 zend_declare_class_constant_long(gpb_type_type, STR("DOUBLE"), 1 TSRMLS_CC);
158 zend_declare_class_constant_long(gpb_type_type, STR("FLOAT"), 2 TSRMLS_CC);
159 zend_declare_class_constant_long(gpb_type_type, STR("INT64"), 3 TSRMLS_CC);
160 zend_declare_class_constant_long(gpb_type_type, STR("UINT64"), 4 TSRMLS_CC);
161 zend_declare_class_constant_long(gpb_type_type, STR("INT32"), 5 TSRMLS_CC);
162 zend_declare_class_constant_long(gpb_type_type, STR("FIXED64"), 6 TSRMLS_CC);
163 zend_declare_class_constant_long(gpb_type_type, STR("FIXED32"), 7 TSRMLS_CC);
164 zend_declare_class_constant_long(gpb_type_type, STR("BOOL"), 8 TSRMLS_CC);
165 zend_declare_class_constant_long(gpb_type_type, STR("STRING"), 9 TSRMLS_CC);
166 zend_declare_class_constant_long(gpb_type_type, STR("GROUP"), 10 TSRMLS_CC);
167 zend_declare_class_constant_long(gpb_type_type, STR("MESSAGE"), 11 TSRMLS_CC);
168 zend_declare_class_constant_long(gpb_type_type, STR("BYTES"), 12 TSRMLS_CC);
169 zend_declare_class_constant_long(gpb_type_type, STR("UINT32"), 13 TSRMLS_CC);
170 zend_declare_class_constant_long(gpb_type_type, STR("ENUM"), 14 TSRMLS_CC);
171 zend_declare_class_constant_long(gpb_type_type, STR("SFIXED32"),
172 15 TSRMLS_CC);
173 zend_declare_class_constant_long(gpb_type_type, STR("SFIXED64"),
174 16 TSRMLS_CC);
175 zend_declare_class_constant_long(gpb_type_type, STR("SINT32"), 17 TSRMLS_CC);
176 zend_declare_class_constant_long(gpb_type_type, STR("SINT64"), 18 TSRMLS_CC);
177 }
178
179 // -----------------------------------------------------------------------------
180 // DescriptorPool
181 // -----------------------------------------------------------------------------
182
183 static zend_function_entry descriptor_pool_methods[] = {
184 PHP_ME(DescriptorPool, getGeneratedPool, NULL,
185 ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
186 PHP_ME(DescriptorPool, internalAddGeneratedFile, NULL, ZEND_ACC_PUBLIC)
187 ZEND_FE_END
188 };
189
93 DEFINE_CLASS(DescriptorPool, descriptor_pool, 190 DEFINE_CLASS(DescriptorPool, descriptor_pool,
94 "Google\\Protobuf\\DescriptorPool"); 191 "Google\\Protobuf\\Internal\\DescriptorPool");
95 192
193 zval* generated_pool_php; // wrapper of generated pool
96 DescriptorPool *generated_pool; // The actual generated pool 194 DescriptorPool *generated_pool; // The actual generated pool
97 195
98 ZEND_FUNCTION(get_generated_pool) { 196 static void init_generated_pool_once(TSRMLS_D) {
99 if (PROTOBUF_G(generated_pool) == NULL) { 197 if (generated_pool_php == NULL) {
100 MAKE_STD_ZVAL(PROTOBUF_G(generated_pool)); 198 MAKE_STD_ZVAL(generated_pool_php);
101 Z_TYPE_P(PROTOBUF_G(generated_pool)) = IS_OBJECT; 199 Z_TYPE_P(generated_pool_php) = IS_OBJECT;
102 generated_pool = ALLOC(DescriptorPool); 200 generated_pool = ALLOC(DescriptorPool);
103 descriptor_pool_init_c_instance(generated_pool TSRMLS_CC); 201 descriptor_pool_init_c_instance(generated_pool TSRMLS_CC);
104 Z_OBJ_HANDLE_P(PROTOBUF_G(generated_pool)) = zend_objects_store_put( 202 Z_OBJ_HANDLE_P(generated_pool_php) = zend_objects_store_put(
105 generated_pool, NULL, 203 generated_pool, NULL,
106 (zend_objects_free_object_storage_t)descriptor_pool_free, NULL TSRMLS_CC ); 204 (zend_objects_free_object_storage_t)descriptor_pool_free,
107 Z_OBJ_HT_P(PROTOBUF_G(generated_pool)) = zend_get_std_object_handlers(); 205 NULL TSRMLS_CC);
108 } 206 Z_OBJ_HT_P(generated_pool_php) = zend_get_std_object_handlers();
109 RETURN_ZVAL(PROTOBUF_G(generated_pool), 1, 0); 207 }
110 } 208 }
111 209
112 void descriptor_pool_init_c_instance(DescriptorPool* pool TSRMLS_DC) { 210 static void descriptor_pool_init_c_instance(DescriptorPool *pool TSRMLS_DC) {
113 zend_object_std_init(&pool->std, descriptor_pool_type TSRMLS_CC); 211 zend_object_std_init(&pool->std, descriptor_pool_type TSRMLS_CC);
114 pool->symtab = upb_symtab_new(&pool->symtab); 212 pool->symtab = upb_symtab_new(&pool->symtab);
115 213
116 ALLOC_HASHTABLE(pool->pending_list); 214 ALLOC_HASHTABLE(pool->pending_list);
117 zend_hash_init(pool->pending_list, 1, NULL, ZVAL_PTR_DTOR, 0); 215 zend_hash_init(pool->pending_list, 1, NULL, ZVAL_PTR_DTOR, 0);
118 } 216 }
119 217
120 void descriptor_pool_free_c(DescriptorPool *pool TSRMLS_DC) { 218 static void descriptor_pool_free_c(DescriptorPool *pool TSRMLS_DC) {
121 upb_symtab_unref(pool->symtab, &pool->symtab); 219 upb_symtab_unref(pool->symtab, &pool->symtab);
220
122 zend_hash_destroy(pool->pending_list); 221 zend_hash_destroy(pool->pending_list);
123 FREE_HASHTABLE(pool->pending_list); 222 FREE_HASHTABLE(pool->pending_list);
124 } 223 }
125 224
126 PHP_METHOD(DescriptorPool, addMessage) { 225 static void validate_enumdef(const upb_enumdef *enumdef) {
127 char *name = NULL; 226 // Verify that an entry exists with integer value 0. (This is the default
128 int str_len; 227 // value.)
129 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name, &str_len) == 228 const char *lookup = upb_enumdef_iton(enumdef, 0);
130 FAILURE) { 229 if (lookup == NULL) {
131 return; 230 zend_error(E_USER_ERROR,
231 "Enum definition does not contain a value for '0'.");
132 } 232 }
133
134 zval* retval = NULL;
135 PROTOBUF_CREATE_ZEND_WRAPPER(MessageBuilderContext, message_builder_context,
136 retval, context);
137
138 MAKE_STD_ZVAL(context->pool);
139 ZVAL_ZVAL(context->pool, getThis(), 1, 0);
140
141 Descriptor *desc = php_to_descriptor(context->descriptor TSRMLS_CC);
142 Descriptor_name_set(desc, name);
143
144 RETURN_ZVAL(retval, 0, 1);
145 } 233 }
146 234
147 static void validate_msgdef(const upb_msgdef* msgdef) { 235 static void validate_msgdef(const upb_msgdef* msgdef) {
148 // Verify that no required fields exist. proto3 does not support these. 236 // Verify that no required fields exist. proto3 does not support these.
149 upb_msg_field_iter it; 237 upb_msg_field_iter it;
150 for (upb_msg_field_begin(&it, msgdef); 238 for (upb_msg_field_begin(&it, msgdef);
151 !upb_msg_field_done(&it); 239 !upb_msg_field_done(&it);
152 upb_msg_field_next(&it)) { 240 upb_msg_field_next(&it)) {
153 const upb_fielddef* field = upb_msg_iter_field(&it); 241 const upb_fielddef* field = upb_msg_iter_field(&it);
154 if (upb_fielddef_label(field) == UPB_LABEL_REQUIRED) { 242 if (upb_fielddef_label(field) == UPB_LABEL_REQUIRED) {
155 zend_error(E_ERROR, "Required fields are unsupported in proto3."); 243 zend_error(E_ERROR, "Required fields are unsupported in proto3.");
156 } 244 }
157 } 245 }
158 } 246 }
159 247
160 PHP_METHOD(DescriptorPool, finalize) { 248 PHP_METHOD(DescriptorPool, getGeneratedPool) {
161 DescriptorPool *self = php_to_descriptor_pool(getThis() TSRMLS_CC); 249 init_generated_pool_once(TSRMLS_C);
162 Bucket *temp; 250 RETURN_ZVAL(generated_pool_php, 1, 0);
163 int i, num; 251 }
164 252
165 num = zend_hash_num_elements(self->pending_list); 253 static void convert_to_class_name_inplace(char *class_name,
166 upb_def **defs = emalloc(sizeof(upb_def *) * num); 254 const char* fullname,
255 const char* package_name) {
256 size_t i;
257 bool first_char = false;
258 size_t pkg_name_len = package_name == NULL ? 0 : strlen(package_name);
167 259
168 for (i = 0, temp = self->pending_list->pListHead; temp != NULL; 260 // In php, class name cannot be Empty.
169 temp = temp->pListNext) { 261 if (strcmp("google.protobuf.Empty", fullname) == 0) {
170 zval *def_php = *(zval **)temp->pData; 262 fullname = "google.protobuf.GPBEmpty";
171 Descriptor* desc = php_to_descriptor(def_php TSRMLS_CC);
172 defs[i] = (upb_def *)desc->msgdef;
173 validate_msgdef((const upb_msgdef *)defs[i++]);
174 } 263 }
175 264
176 CHECK_UPB(upb_symtab_add(self->symtab, (upb_def **)defs, num, NULL, &status), 265 if (pkg_name_len == 0) {
177 "Unable to add defs to DescriptorPool"); 266 strcpy(class_name, fullname);
178 267 } else {
179 for (temp = self->pending_list->pListHead; temp != NULL; 268 class_name[0] = '.';
180 temp = temp->pListNext) { 269 strcpy(&class_name[1], fullname);
181 // zval *def_php = *(zval **)temp->pData; 270 for (i = 0; i <= pkg_name_len + 1; i++) {
182 // Descriptor* desc = php_to_descriptor(def_php TSRMLS_CC); 271 // PHP package uses camel case.
183 build_class_from_descriptor((zval *)temp->pDataPtr TSRMLS_CC); 272 if (!first_char && class_name[i] != '.') {
273 first_char = true;
274 class_name[i] += 'A' - 'a';
275 }
276 // php packages are divided by '\'.
277 if (class_name[i] == '.') {
278 first_char = false;
279 class_name[i] = '\\';
280 }
281 }
184 } 282 }
185 283
186 FREE(defs); 284 // Submessage is concatenated with its containing messages by '_'.
187 zend_hash_destroy(self->pending_list); 285 for (i = pkg_name_len; i < strlen(class_name); i++) {
188 zend_hash_init(self->pending_list, 1, NULL, ZVAL_PTR_DTOR, 0); 286 if (class_name[i] == '.') {
287 class_name[i] = '_';
288 }
289 }
290 }
291
292 PHP_METHOD(DescriptorPool, internalAddGeneratedFile) {
293 char *data = NULL;
294 int data_len;
295 upb_filedef **files;
296 size_t i;
297
298 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &data, &data_len) ==
299 FAILURE) {
300 return;
301 }
302
303 DescriptorPool *pool = UNBOX(DescriptorPool, getThis());
304 CHECK_UPB(files = upb_loaddescriptor(data, data_len, &pool, &status),
305 "Parse binary descriptors to internal descriptors failed");
306
307 // This method is called only once in each file.
308 assert(files[0] != NULL);
309 assert(files[1] == NULL);
310
311 CHECK_UPB(upb_symtab_addfile(pool->symtab, files[0], &status),
312 "Unable to add file to DescriptorPool");
313
314 // For each enum/message, we need its PHP class, upb descriptor and its PHP
315 // wrapper. These information are needed later for encoding, decoding and type
316 // checking. However, sometimes we just have one of them. In order to find
317 // them quickly, here, we store the mapping for them.
318 for (i = 0; i < upb_filedef_defcount(files[0]); i++) {
319 const upb_def *def = upb_filedef_def(files[0], i);
320 switch (upb_def_type(def)) {
321 #define CASE_TYPE(def_type, def_type_lower, desc_type, desc_type_lower) \
322 case UPB_DEF_##def_type: { \
323 desc_type *desc; \
324 zval *desc_php; \
325 CREATE(desc_type, desc, desc_type_lower##_init_c_instance); \
326 BOX(desc_type, desc_php, desc, desc_type_lower##_free); \
327 Z_DELREF_P(desc_php); \
328 const upb_##def_type_lower *def_type_lower = \
329 upb_downcast_##def_type_lower(def); \
330 desc->def_type_lower = def_type_lower; \
331 add_def_obj(desc->def_type_lower, desc_php); \
332 /* Unlike other messages, MapEntry is shared by all map fields and doesn't \
333 * have generated PHP class.*/ \
334 if (upb_def_type(def) == UPB_DEF_MSG && \
335 upb_msgdef_mapentry(upb_downcast_msgdef(def))) { \
336 break; \
337 } \
338 /* Prepend '.' to package name to make it absolute. In the 5 additional \
339 * bytes allocated, one for '.', one for trailing 0, and 3 for 'GPB' if \
340 * given message is google.protobuf.Empty.*/ \
341 const char *fullname = upb_##def_type_lower##_fullname(def_type_lower); \
342 char *klass_name = ecalloc(sizeof(char), 5 + strlen(fullname)); \
343 convert_to_class_name_inplace(klass_name, fullname, \
344 upb_filedef_package(files[0])); \
345 zend_class_entry **pce; \
346 if (zend_lookup_class(klass_name, strlen(klass_name), &pce TSRMLS_CC) == \
347 FAILURE) { \
348 zend_error(E_ERROR, "Generated message class %s hasn't been defined", \
349 klass_name); \
350 return; \
351 } else { \
352 desc->klass = *pce; \
353 } \
354 add_ce_obj(desc->klass, desc_php); \
355 efree(klass_name); \
356 break; \
357 }
358
359 CASE_TYPE(MSG, msgdef, Descriptor, descriptor)
360 CASE_TYPE(ENUM, enumdef, EnumDescriptor, enum_descriptor)
361 #undef CASE_TYPE
362
363 default:
364 break;
365 }
366 }
367
368 for (i = 0; i < upb_filedef_defcount(files[0]); i++) {
369 const upb_def *def = upb_filedef_def(files[0], i);
370 if (upb_def_type(def) == UPB_DEF_MSG) {
371 const upb_msgdef *msgdef = upb_downcast_msgdef(def);
372 zval *desc_php = get_def_obj(msgdef);
373 build_class_from_descriptor(desc_php TSRMLS_CC);
374 }
375 }
376
377 upb_filedef_unref(files[0], &pool);
378 upb_gfree(files);
189 } 379 }
190 380
191 // ----------------------------------------------------------------------------- 381 // -----------------------------------------------------------------------------
192 // Descriptor 382 // Descriptor
193 // ----------------------------------------------------------------------------- 383 // -----------------------------------------------------------------------------
194 384
195 static zend_function_entry descriptor_methods[] = { 385 static zend_function_entry descriptor_methods[] = {
196 ZEND_FE_END 386 ZEND_FE_END
197 }; 387 };
198 388
199 DEFINE_CLASS(Descriptor, descriptor, "Google\\Protobuf\\Descriptor"); 389 DEFINE_CLASS(Descriptor, descriptor, "Google\\Protobuf\\Internal\\Descriptor");
200 390
201 void descriptor_free_c(Descriptor *self TSRMLS_DC) { 391 static void descriptor_free_c(Descriptor *self TSRMLS_DC) {
202 upb_msg_field_iter iter;
203 upb_msg_field_begin(&iter, self->msgdef);
204 while (!upb_msg_field_done(&iter)) {
205 upb_fielddef *fielddef = upb_msg_iter_field(&iter);
206 upb_fielddef_unref(fielddef, &fielddef);
207 upb_msg_field_next(&iter);
208 }
209 upb_msgdef_unref(self->msgdef, &self->msgdef);
210 if (self->layout) { 392 if (self->layout) {
211 free_layout(self->layout); 393 free_layout(self->layout);
212 } 394 }
395 if (self->fill_handlers) {
396 upb_handlers_unref(self->fill_handlers, &self->fill_handlers);
397 }
398 if (self->fill_method) {
399 upb_pbdecodermethod_unref(self->fill_method, &self->fill_method);
400 }
401 if (self->pb_serialize_handlers) {
402 upb_handlers_unref(self->pb_serialize_handlers,
403 &self->pb_serialize_handlers);
404 }
213 } 405 }
214 406
215 static void descriptor_add_field(Descriptor *desc, 407 static void descriptor_init_c_instance(Descriptor *desc TSRMLS_DC) {
216 const upb_fielddef *fielddef) {
217 upb_msgdef *mut_def = check_msgdef_notfrozen(desc->msgdef);
218 upb_fielddef *mut_field_def = check_fielddef_notfrozen(fielddef);
219 CHECK_UPB(upb_msgdef_addfield(mut_def, mut_field_def, NULL, &status),
220 "Adding field to Descriptor failed");
221 // add_def_obj(fielddef, obj);
222 }
223
224 void descriptor_init_c_instance(Descriptor* desc TSRMLS_DC) {
225 zend_object_std_init(&desc->std, descriptor_type TSRMLS_CC); 408 zend_object_std_init(&desc->std, descriptor_type TSRMLS_CC);
226 desc->msgdef = upb_msgdef_new(&desc->msgdef); 409 desc->msgdef = NULL;
227 desc->layout = NULL; 410 desc->layout = NULL;
228 // MAKE_STD_ZVAL(intern->klass); 411 desc->klass = NULL;
229 // ZVAL_NULL(intern->klass); 412 desc->fill_handlers = NULL;
413 desc->fill_method = NULL;
230 desc->pb_serialize_handlers = NULL; 414 desc->pb_serialize_handlers = NULL;
231 } 415 }
232 416
233 void Descriptor_name_set(Descriptor *desc, const char *name) { 417 // -----------------------------------------------------------------------------
234 upb_msgdef *mut_def = check_msgdef_notfrozen(desc->msgdef); 418 // EnumDescriptor
235 CHECK_UPB(upb_msgdef_setfullname(mut_def, name, &status), 419 // -----------------------------------------------------------------------------
236 "Error setting Descriptor name"); 420
421 static zend_function_entry enum_descriptor_methods[] = {
422 ZEND_FE_END
423 };
424
425 DEFINE_CLASS(EnumDescriptor, enum_descriptor,
426 "Google\\Protobuf\\Internal\\EnumDescriptor");
427
428 static void enum_descriptor_free_c(EnumDescriptor *self TSRMLS_DC) {
429 }
430
431 static void enum_descriptor_init_c_instance(EnumDescriptor *self TSRMLS_DC) {
432 zend_object_std_init(&self->std, enum_descriptor_type TSRMLS_CC);
433 self->enumdef = NULL;
434 self->klass = NULL;
237 } 435 }
238 436
239 // ----------------------------------------------------------------------------- 437 // -----------------------------------------------------------------------------
240 // FieldDescriptor 438 // FieldDescriptor
241 // ----------------------------------------------------------------------------- 439 // -----------------------------------------------------------------------------
242 440
243 static void field_descriptor_name_set(const upb_fielddef* fielddef, 441 upb_fieldtype_t to_fieldtype(upb_descriptortype_t type) {
244 const char *name) { 442 switch (type) {
245 upb_fielddef *mut_def = check_fielddef_notfrozen(fielddef); 443 #define CASE(descriptor_type, type) \
246 CHECK_UPB(upb_fielddef_setname(mut_def, name, &status), 444 case UPB_DESCRIPTOR_TYPE_##descriptor_type: \
247 "Error setting FieldDescriptor name"); 445 return UPB_TYPE_##type;
248 }
249 446
250 static void field_descriptor_label_set(const upb_fielddef* fielddef, 447 CASE(FLOAT, FLOAT);
251 upb_label_t upb_label) { 448 CASE(DOUBLE, DOUBLE);
252 upb_fielddef *mut_def = check_fielddef_notfrozen(fielddef); 449 CASE(BOOL, BOOL);
253 upb_fielddef_setlabel(mut_def, upb_label); 450 CASE(STRING, STRING);
254 } 451 CASE(BYTES, BYTES);
255 452 CASE(MESSAGE, MESSAGE);
256 upb_fieldtype_t string_to_descriptortype(const char *type) { 453 CASE(GROUP, MESSAGE);
257 #define CONVERT(upb, str) \ 454 CASE(ENUM, ENUM);
258 if (!strcmp(type, str)) { \ 455 CASE(INT32, INT32);
259 return UPB_DESCRIPTOR_TYPE_##upb; \ 456 CASE(INT64, INT64);
260 } 457 CASE(UINT32, UINT32);
261 458 CASE(UINT64, UINT64);
262 CONVERT(FLOAT, "float"); 459 CASE(SINT32, INT32);
263 CONVERT(DOUBLE, "double"); 460 CASE(SINT64, INT64);
264 CONVERT(BOOL, "bool"); 461 CASE(FIXED32, UINT32);
265 CONVERT(STRING, "string"); 462 CASE(FIXED64, UINT64);
266 CONVERT(BYTES, "bytes"); 463 CASE(SFIXED32, INT32);
267 CONVERT(MESSAGE, "message"); 464 CASE(SFIXED64, INT64);
268 CONVERT(GROUP, "group");
269 CONVERT(ENUM, "enum");
270 CONVERT(INT32, "int32");
271 CONVERT(INT64, "int64");
272 CONVERT(UINT32, "uint32");
273 CONVERT(UINT64, "uint64");
274 CONVERT(SINT32, "sint32");
275 CONVERT(SINT64, "sint64");
276 CONVERT(FIXED32, "fixed32");
277 CONVERT(FIXED64, "fixed64");
278 CONVERT(SFIXED32, "sfixed32");
279 CONVERT(SFIXED64, "sfixed64");
280 465
281 #undef CONVERT 466 #undef CONVERT
282 467
468 }
469
283 zend_error(E_ERROR, "Unknown field type."); 470 zend_error(E_ERROR, "Unknown field type.");
284 return 0; 471 return 0;
285 } 472 }
286
287 static void field_descriptor_type_set(const upb_fielddef* fielddef,
288 const char *type) {
289 upb_fielddef *mut_def = check_fielddef_notfrozen(fielddef);
290 upb_fielddef_setdescriptortype(mut_def, string_to_descriptortype(type));
291 }
292
293 static void field_descriptor_number_set(const upb_fielddef* fielddef,
294 int number) {
295 upb_fielddef *mut_def = check_fielddef_notfrozen(fielddef);
296 CHECK_UPB(upb_fielddef_setnumber(mut_def, number, &status),
297 "Error setting field number");
298 }
299
300 // -----------------------------------------------------------------------------
301 // MessageBuilderContext
302 // -----------------------------------------------------------------------------
303
304 static zend_function_entry message_builder_context_methods[] = {
305 PHP_ME(MessageBuilderContext, finalizeToPool, NULL, ZEND_ACC_PUBLIC)
306 PHP_ME(MessageBuilderContext, optional, NULL, ZEND_ACC_PUBLIC)
307 {NULL, NULL, NULL}
308 };
309
310 DEFINE_CLASS(MessageBuilderContext, message_builder_context,
311 "Google\\Protobuf\\Internal\\MessageBuilderContext");
312
313 void message_builder_context_free_c(MessageBuilderContext *context TSRMLS_DC) {
314 zval_ptr_dtor(&context->descriptor);
315 zval_ptr_dtor(&context->pool);
316 }
317
318 void message_builder_context_init_c_instance(
319 MessageBuilderContext *context TSRMLS_DC) {
320 zend_object_std_init(&context->std, message_builder_context_type TSRMLS_CC);
321 PROTOBUF_CREATE_ZEND_WRAPPER(Descriptor, descriptor, context->descriptor,
322 desc);
323 }
324
325 static void msgdef_add_field(Descriptor *desc, upb_label_t upb_label,
326 const char *name, const char *type, int number,
327 const char *type_class) {
328 upb_fielddef *fielddef = upb_fielddef_new(&fielddef);
329 upb_fielddef_setpacked(fielddef, false);
330
331 field_descriptor_label_set(fielddef, upb_label);
332 field_descriptor_name_set(fielddef, name);
333 field_descriptor_type_set(fielddef, type);
334 field_descriptor_number_set(fielddef, number);
335
336 // // if (type_class != Qnil) {
337 // // if (TYPE(type_class) != T_STRING) {
338 // // rb_raise(rb_eArgError, "Expected string for type class");
339 // // }
340 // // // Make it an absolute type name by prepending a dot.
341 // // type_class = rb_str_append(rb_str_new2("."), type_class);
342 // // rb_funcall(fielddef, rb_intern("submsg_name="), 1, type_class);
343 // // }
344 descriptor_add_field(desc, fielddef);
345 }
346
347 PHP_METHOD(MessageBuilderContext, optional) {
348 MessageBuilderContext *self = php_to_message_builder_context(getThis() TSRMLS_ CC);
349 Descriptor *desc = php_to_descriptor(self->descriptor TSRMLS_CC);
350 // VALUE name, type, number, type_class;
351 const char *name, *type, *type_class;
352 int number, name_str_len, type_str_len, type_class_str_len;
353 if (ZEND_NUM_ARGS() == 3) {
354 if (zend_parse_parameters(3 TSRMLS_CC, "ssl", &name,
355 &name_str_len, &type, &type_str_len, &number) == F AILURE) {
356 return;
357 }
358 } else {
359 if (zend_parse_parameters(4 TSRMLS_CC, "ssls", &name,
360 &name_str_len, &type, &type_str_len, &number, &typ e_class,
361 &type_class_str_len) == FAILURE) {
362 return;
363 }
364 }
365
366 msgdef_add_field(desc, UPB_LABEL_OPTIONAL, name, type, number, type_class);
367
368 zval_copy_ctor(getThis());
369 RETURN_ZVAL(getThis(), 1, 0);
370 }
371
372 PHP_METHOD(MessageBuilderContext, finalizeToPool) {
373 MessageBuilderContext *self = php_to_message_builder_context(getThis() TSRMLS_ CC);
374 DescriptorPool *pool = php_to_descriptor_pool(self->pool TSRMLS_CC);
375 Descriptor* desc = php_to_descriptor(self->descriptor TSRMLS_CC);
376
377 Z_ADDREF_P(self->descriptor);
378 zend_hash_next_index_insert(pool->pending_list, &self->descriptor,
379 sizeof(zval *), NULL);
380 RETURN_ZVAL(self->pool, 1, 0);
381 }
OLDNEW
« no previous file with comments | « third_party/protobuf/php/ext/google/protobuf/config.m4 ('k') | third_party/protobuf/php/ext/google/protobuf/encode_decode.c » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698