1ffe3c632Sopenharmony_ci// Protocol Buffers - Google's data interchange format
2ffe3c632Sopenharmony_ci// Copyright 2008 Google Inc.  All rights reserved.
3ffe3c632Sopenharmony_ci// https://developers.google.com/protocol-buffers/
4ffe3c632Sopenharmony_ci//
5ffe3c632Sopenharmony_ci// Redistribution and use in source and binary forms, with or without
6ffe3c632Sopenharmony_ci// modification, are permitted provided that the following conditions are
7ffe3c632Sopenharmony_ci// met:
8ffe3c632Sopenharmony_ci//
9ffe3c632Sopenharmony_ci//     * Redistributions of source code must retain the above copyright
10ffe3c632Sopenharmony_ci// notice, this list of conditions and the following disclaimer.
11ffe3c632Sopenharmony_ci//     * Redistributions in binary form must reproduce the above
12ffe3c632Sopenharmony_ci// copyright notice, this list of conditions and the following disclaimer
13ffe3c632Sopenharmony_ci// in the documentation and/or other materials provided with the
14ffe3c632Sopenharmony_ci// distribution.
15ffe3c632Sopenharmony_ci//     * Neither the name of Google Inc. nor the names of its
16ffe3c632Sopenharmony_ci// contributors may be used to endorse or promote products derived from
17ffe3c632Sopenharmony_ci// this software without specific prior written permission.
18ffe3c632Sopenharmony_ci//
19ffe3c632Sopenharmony_ci// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20ffe3c632Sopenharmony_ci// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21ffe3c632Sopenharmony_ci// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22ffe3c632Sopenharmony_ci// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23ffe3c632Sopenharmony_ci// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24ffe3c632Sopenharmony_ci// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25ffe3c632Sopenharmony_ci// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26ffe3c632Sopenharmony_ci// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27ffe3c632Sopenharmony_ci// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28ffe3c632Sopenharmony_ci// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29ffe3c632Sopenharmony_ci// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30ffe3c632Sopenharmony_ci
31ffe3c632Sopenharmony_ci#include "protobuf.h"
32ffe3c632Sopenharmony_ci
33ffe3c632Sopenharmony_ci#include <php.h>
34ffe3c632Sopenharmony_ci#include <Zend/zend_interfaces.h>
35ffe3c632Sopenharmony_ci
36ffe3c632Sopenharmony_ci#include "arena.h"
37ffe3c632Sopenharmony_ci#include "array.h"
38ffe3c632Sopenharmony_ci#include "bundled_php.h"
39ffe3c632Sopenharmony_ci#include "convert.h"
40ffe3c632Sopenharmony_ci#include "def.h"
41ffe3c632Sopenharmony_ci#include "map.h"
42ffe3c632Sopenharmony_ci#include "message.h"
43ffe3c632Sopenharmony_ci#include "names.h"
44ffe3c632Sopenharmony_ci
45ffe3c632Sopenharmony_ci// -----------------------------------------------------------------------------
46ffe3c632Sopenharmony_ci// Module "globals"
47ffe3c632Sopenharmony_ci// -----------------------------------------------------------------------------
48ffe3c632Sopenharmony_ci
49ffe3c632Sopenharmony_ci// Despite the name, module "globals" are really thread-locals:
50ffe3c632Sopenharmony_ci//  * PROTOBUF_G(var) accesses the thread-local variable for 'var'. Either:
51ffe3c632Sopenharmony_ci//    * PROTOBUF_G(var) -> protobuf_globals.var (Non-ZTS / non-thread-safe)
52ffe3c632Sopenharmony_ci//    * PROTOBUF_G(var) -> <Zend magic>         (ZTS / thread-safe builds)
53ffe3c632Sopenharmony_ci
54ffe3c632Sopenharmony_ci#define PROTOBUF_G(v) ZEND_MODULE_GLOBALS_ACCESSOR(protobuf, v)
55ffe3c632Sopenharmony_ci
56ffe3c632Sopenharmony_ciZEND_BEGIN_MODULE_GLOBALS(protobuf)
57ffe3c632Sopenharmony_ci  // Set by the user to make the descriptor pool persist between requests.
58ffe3c632Sopenharmony_ci  zend_bool keep_descriptor_pool_after_request;
59ffe3c632Sopenharmony_ci
60ffe3c632Sopenharmony_ci  // Currently we make the generated pool a "global", which means that if a user
61ffe3c632Sopenharmony_ci  // does explicitly create threads within their request, the other threads will
62ffe3c632Sopenharmony_ci  // get different results from DescriptorPool::getGeneratedPool(). We require
63ffe3c632Sopenharmony_ci  // that all descriptors are loaded from the main thread.
64ffe3c632Sopenharmony_ci  zval generated_pool;
65ffe3c632Sopenharmony_ci
66ffe3c632Sopenharmony_ci  // A upb_symtab that we are saving for the next request so that we don't have
67ffe3c632Sopenharmony_ci  // to rebuild it from scratch. When keep_descriptor_pool_after_request==true,
68ffe3c632Sopenharmony_ci  // we steal the upb_symtab from the global DescriptorPool object just before
69ffe3c632Sopenharmony_ci  // destroying it.
70ffe3c632Sopenharmony_ci  upb_symtab *saved_symtab;
71ffe3c632Sopenharmony_ci
72ffe3c632Sopenharmony_ci  // Object cache (see interface in protobuf.h).
73ffe3c632Sopenharmony_ci  HashTable object_cache;
74ffe3c632Sopenharmony_ci
75ffe3c632Sopenharmony_ci  // Name cache (see interface in protobuf.h).
76ffe3c632Sopenharmony_ci  HashTable name_msg_cache;
77ffe3c632Sopenharmony_ci  HashTable name_enum_cache;
78ffe3c632Sopenharmony_ciZEND_END_MODULE_GLOBALS(protobuf)
79ffe3c632Sopenharmony_ci
80ffe3c632Sopenharmony_ciZEND_DECLARE_MODULE_GLOBALS(protobuf)
81ffe3c632Sopenharmony_ci
82ffe3c632Sopenharmony_ciconst zval *get_generated_pool() {
83ffe3c632Sopenharmony_ci  return &PROTOBUF_G(generated_pool);
84ffe3c632Sopenharmony_ci}
85ffe3c632Sopenharmony_ci
86ffe3c632Sopenharmony_ci// This is a PHP extension (not a Zend extension). What follows is a summary of
87ffe3c632Sopenharmony_ci// a PHP extension's lifetime and when various handlers are called.
88ffe3c632Sopenharmony_ci//
89ffe3c632Sopenharmony_ci//  * PHP_GINIT_FUNCTION(protobuf) / PHP_GSHUTDOWN_FUNCTION(protobuf)
90ffe3c632Sopenharmony_ci//    are the constructor/destructor for the globals. The sequence over the
91ffe3c632Sopenharmony_ci//    course of a process lifetime is:
92ffe3c632Sopenharmony_ci//
93ffe3c632Sopenharmony_ci//    # Process startup
94ffe3c632Sopenharmony_ci//    GINIT(<Main Thread Globals>)
95ffe3c632Sopenharmony_ci//    MINIT
96ffe3c632Sopenharmony_ci//
97ffe3c632Sopenharmony_ci//    foreach request:
98ffe3c632Sopenharmony_ci//      RINIT
99ffe3c632Sopenharmony_ci//        # Request is processed here.
100ffe3c632Sopenharmony_ci//      RSHUTDOWN
101ffe3c632Sopenharmony_ci//
102ffe3c632Sopenharmony_ci//    foreach thread:
103ffe3c632Sopenharmony_ci//      GINIT(<This Thread Globals>)
104ffe3c632Sopenharmony_ci//        # Code for the thread runs here.
105ffe3c632Sopenharmony_ci//      GSHUTDOWN(<This Thread Globals>)
106ffe3c632Sopenharmony_ci//
107ffe3c632Sopenharmony_ci//    # Process Shutdown
108ffe3c632Sopenharmony_ci//    #
109ffe3c632Sopenharmony_ci//    # These should be running per the docs, but I have not been able to
110ffe3c632Sopenharmony_ci//    # actually get the process-wide shutdown functions to run.
111ffe3c632Sopenharmony_ci//    #
112ffe3c632Sopenharmony_ci//    # MSHUTDOWN
113ffe3c632Sopenharmony_ci//    # GSHUTDOWN(<Main Thread Globals>)
114ffe3c632Sopenharmony_ci//
115ffe3c632Sopenharmony_ci//  * Threads can be created either explicitly by the user, inside a request,
116ffe3c632Sopenharmony_ci//    or implicitly by the runtime, to process multiple requests concurrently.
117ffe3c632Sopenharmony_ci//    If the latter is being used, then the "foreach thread" block above
118ffe3c632Sopenharmony_ci//    actually looks like this:
119ffe3c632Sopenharmony_ci//
120ffe3c632Sopenharmony_ci//    foreach thread:
121ffe3c632Sopenharmony_ci//      GINIT(<This Thread Globals>)
122ffe3c632Sopenharmony_ci//      # A non-main thread will only receive requests when using a threaded
123ffe3c632Sopenharmony_ci//      # MPM with Apache
124ffe3c632Sopenharmony_ci//      foreach request:
125ffe3c632Sopenharmony_ci//        RINIT
126ffe3c632Sopenharmony_ci//          # Request is processed here.
127ffe3c632Sopenharmony_ci//        RSHUTDOWN
128ffe3c632Sopenharmony_ci//      GSHUTDOWN(<This Thread Globals>)
129ffe3c632Sopenharmony_ci//
130ffe3c632Sopenharmony_ci// That said, it appears that few people use threads with PHP:
131ffe3c632Sopenharmony_ci//   * The pthread package documented at
132ffe3c632Sopenharmony_ci//     https://www.php.net/manual/en/class.thread.php nas not been released
133ffe3c632Sopenharmony_ci//     since 2016, and the current release fails to compile against any PHP
134ffe3c632Sopenharmony_ci//     newer than 7.0.33.
135ffe3c632Sopenharmony_ci//     * The GitHub master branch supports 7.2+, but this has not been released
136ffe3c632Sopenharmony_ci//       to PECL.
137ffe3c632Sopenharmony_ci//     * Its owner has disavowed it as "broken by design" and "in an untenable
138ffe3c632Sopenharmony_ci//       position for the future": https://github.com/krakjoe/pthreads/issues/929
139ffe3c632Sopenharmony_ci//   * The only way to use PHP with requests in different threads is to use the
140ffe3c632Sopenharmony_ci//     Apache 2 mod_php with the "worker" MPM. But this is explicitly
141ffe3c632Sopenharmony_ci//     discouraged by the documentation: https://serverfault.com/a/231660
142ffe3c632Sopenharmony_ci
143ffe3c632Sopenharmony_cistatic PHP_GSHUTDOWN_FUNCTION(protobuf) {
144ffe3c632Sopenharmony_ci  if (protobuf_globals->saved_symtab) {
145ffe3c632Sopenharmony_ci    upb_symtab_free(protobuf_globals->saved_symtab);
146ffe3c632Sopenharmony_ci  }
147ffe3c632Sopenharmony_ci}
148ffe3c632Sopenharmony_ci
149ffe3c632Sopenharmony_cistatic PHP_GINIT_FUNCTION(protobuf) {
150ffe3c632Sopenharmony_ci  ZVAL_NULL(&protobuf_globals->generated_pool);
151ffe3c632Sopenharmony_ci  protobuf_globals->saved_symtab = NULL;
152ffe3c632Sopenharmony_ci}
153ffe3c632Sopenharmony_ci
154ffe3c632Sopenharmony_ci/**
155ffe3c632Sopenharmony_ci * PHP_RINIT_FUNCTION(protobuf)
156ffe3c632Sopenharmony_ci *
157ffe3c632Sopenharmony_ci * This function is run at the beginning of processing each request.
158ffe3c632Sopenharmony_ci */
159ffe3c632Sopenharmony_cistatic PHP_RINIT_FUNCTION(protobuf) {
160ffe3c632Sopenharmony_ci  // Create the global generated pool.
161ffe3c632Sopenharmony_ci  // Reuse the symtab (if any) left to us by the last request.
162ffe3c632Sopenharmony_ci  upb_symtab *symtab = PROTOBUF_G(saved_symtab);
163ffe3c632Sopenharmony_ci  DescriptorPool_CreateWithSymbolTable(&PROTOBUF_G(generated_pool), symtab);
164ffe3c632Sopenharmony_ci
165ffe3c632Sopenharmony_ci  // Set up autoloader for bundled sources.
166ffe3c632Sopenharmony_ci  zend_eval_string("spl_autoload_register('protobuf_internal_loadbundled');",
167ffe3c632Sopenharmony_ci                   NULL, "autoload_register.php");
168ffe3c632Sopenharmony_ci
169ffe3c632Sopenharmony_ci  zend_hash_init(&PROTOBUF_G(object_cache), 64, NULL, NULL, 0);
170ffe3c632Sopenharmony_ci  zend_hash_init(&PROTOBUF_G(name_msg_cache), 64, NULL, NULL, 0);
171ffe3c632Sopenharmony_ci  zend_hash_init(&PROTOBUF_G(name_enum_cache), 64, NULL, NULL, 0);
172ffe3c632Sopenharmony_ci
173ffe3c632Sopenharmony_ci  return SUCCESS;
174ffe3c632Sopenharmony_ci}
175ffe3c632Sopenharmony_ci
176ffe3c632Sopenharmony_ci/**
177ffe3c632Sopenharmony_ci * PHP_RSHUTDOWN_FUNCTION(protobuf)
178ffe3c632Sopenharmony_ci *
179ffe3c632Sopenharmony_ci * This function is run at the end of processing each request.
180ffe3c632Sopenharmony_ci */
181ffe3c632Sopenharmony_cistatic PHP_RSHUTDOWN_FUNCTION(protobuf) {
182ffe3c632Sopenharmony_ci  // Preserve the symtab if requested.
183ffe3c632Sopenharmony_ci  if (PROTOBUF_G(keep_descriptor_pool_after_request)) {
184ffe3c632Sopenharmony_ci    zval *zv = &PROTOBUF_G(generated_pool);
185ffe3c632Sopenharmony_ci    PROTOBUF_G(saved_symtab) = DescriptorPool_Steal(zv);
186ffe3c632Sopenharmony_ci  }
187ffe3c632Sopenharmony_ci
188ffe3c632Sopenharmony_ci  zval_dtor(&PROTOBUF_G(generated_pool));
189ffe3c632Sopenharmony_ci  zend_hash_destroy(&PROTOBUF_G(object_cache));
190ffe3c632Sopenharmony_ci  zend_hash_destroy(&PROTOBUF_G(name_msg_cache));
191ffe3c632Sopenharmony_ci  zend_hash_destroy(&PROTOBUF_G(name_enum_cache));
192ffe3c632Sopenharmony_ci
193ffe3c632Sopenharmony_ci  return SUCCESS;
194ffe3c632Sopenharmony_ci}
195ffe3c632Sopenharmony_ci
196ffe3c632Sopenharmony_ci// -----------------------------------------------------------------------------
197ffe3c632Sopenharmony_ci// Bundled PHP sources
198ffe3c632Sopenharmony_ci// -----------------------------------------------------------------------------
199ffe3c632Sopenharmony_ci
200ffe3c632Sopenharmony_ci// We bundle PHP sources for well-known types into the C extension. There is no
201ffe3c632Sopenharmony_ci// need to implement these in C.
202ffe3c632Sopenharmony_ci
203ffe3c632Sopenharmony_cistatic PHP_FUNCTION(protobuf_internal_loadbundled) {
204ffe3c632Sopenharmony_ci  char *name = NULL;
205ffe3c632Sopenharmony_ci  zend_long size;
206ffe3c632Sopenharmony_ci  BundledPhp_File *file;
207ffe3c632Sopenharmony_ci
208ffe3c632Sopenharmony_ci  if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", &name, &size) != SUCCESS) {
209ffe3c632Sopenharmony_ci    return;
210ffe3c632Sopenharmony_ci  }
211ffe3c632Sopenharmony_ci
212ffe3c632Sopenharmony_ci  for (file = bundled_files; file->filename; file++) {
213ffe3c632Sopenharmony_ci    if (strcmp(file->filename, name) == 0) {
214ffe3c632Sopenharmony_ci      zend_eval_string((char*)file->contents, NULL, (char*)file->filename);
215ffe3c632Sopenharmony_ci      return;
216ffe3c632Sopenharmony_ci    }
217ffe3c632Sopenharmony_ci  }
218ffe3c632Sopenharmony_ci}
219ffe3c632Sopenharmony_ci
220ffe3c632Sopenharmony_ciZEND_BEGIN_ARG_INFO_EX(arginfo_load_bundled_source, 0, 0, 1)
221ffe3c632Sopenharmony_ci  ZEND_ARG_INFO(0, class_name)
222ffe3c632Sopenharmony_ciZEND_END_ARG_INFO()
223ffe3c632Sopenharmony_ci
224ffe3c632Sopenharmony_ci// -----------------------------------------------------------------------------
225ffe3c632Sopenharmony_ci// Object Cache.
226ffe3c632Sopenharmony_ci// -----------------------------------------------------------------------------
227ffe3c632Sopenharmony_ci
228ffe3c632Sopenharmony_civoid ObjCache_Add(const void *upb_obj, zend_object *php_obj) {
229ffe3c632Sopenharmony_ci  zend_ulong k = (zend_ulong)upb_obj;
230ffe3c632Sopenharmony_ci  zend_hash_index_add_ptr(&PROTOBUF_G(object_cache), k, php_obj);
231ffe3c632Sopenharmony_ci}
232ffe3c632Sopenharmony_ci
233ffe3c632Sopenharmony_civoid ObjCache_Delete(const void *upb_obj) {
234ffe3c632Sopenharmony_ci  if (upb_obj) {
235ffe3c632Sopenharmony_ci    zend_ulong k = (zend_ulong)upb_obj;
236ffe3c632Sopenharmony_ci    int ret = zend_hash_index_del(&PROTOBUF_G(object_cache), k);
237ffe3c632Sopenharmony_ci    PBPHP_ASSERT(ret == SUCCESS);
238ffe3c632Sopenharmony_ci  }
239ffe3c632Sopenharmony_ci}
240ffe3c632Sopenharmony_ci
241ffe3c632Sopenharmony_cibool ObjCache_Get(const void *upb_obj, zval *val) {
242ffe3c632Sopenharmony_ci  zend_ulong k = (zend_ulong)upb_obj;
243ffe3c632Sopenharmony_ci  zend_object *obj = zend_hash_index_find_ptr(&PROTOBUF_G(object_cache), k);
244ffe3c632Sopenharmony_ci
245ffe3c632Sopenharmony_ci  if (obj) {
246ffe3c632Sopenharmony_ci    GC_ADDREF(obj);
247ffe3c632Sopenharmony_ci    ZVAL_OBJ(val, obj);
248ffe3c632Sopenharmony_ci    return true;
249ffe3c632Sopenharmony_ci  } else {
250ffe3c632Sopenharmony_ci    ZVAL_NULL(val);
251ffe3c632Sopenharmony_ci    return false;
252ffe3c632Sopenharmony_ci  }
253ffe3c632Sopenharmony_ci}
254ffe3c632Sopenharmony_ci
255ffe3c632Sopenharmony_ci// -----------------------------------------------------------------------------
256ffe3c632Sopenharmony_ci// Name Cache.
257ffe3c632Sopenharmony_ci// -----------------------------------------------------------------------------
258ffe3c632Sopenharmony_ci
259ffe3c632Sopenharmony_civoid NameMap_AddMessage(const upb_msgdef *m) {
260ffe3c632Sopenharmony_ci  char *k = GetPhpClassname(upb_msgdef_file(m), upb_msgdef_fullname(m));
261ffe3c632Sopenharmony_ci  zend_hash_str_add_ptr(&PROTOBUF_G(name_msg_cache), k, strlen(k), (void*)m);
262ffe3c632Sopenharmony_ci  free(k);
263ffe3c632Sopenharmony_ci}
264ffe3c632Sopenharmony_ci
265ffe3c632Sopenharmony_civoid NameMap_AddEnum(const upb_enumdef *e) {
266ffe3c632Sopenharmony_ci  char *k = GetPhpClassname(upb_enumdef_file(e), upb_enumdef_fullname(e));
267ffe3c632Sopenharmony_ci  zend_hash_str_add_ptr(&PROTOBUF_G(name_enum_cache), k, strlen(k), (void*)e);
268ffe3c632Sopenharmony_ci  free(k);
269ffe3c632Sopenharmony_ci}
270ffe3c632Sopenharmony_ci
271ffe3c632Sopenharmony_ciconst upb_msgdef *NameMap_GetMessage(zend_class_entry *ce) {
272ffe3c632Sopenharmony_ci  const upb_msgdef *ret =
273ffe3c632Sopenharmony_ci      zend_hash_find_ptr(&PROTOBUF_G(name_msg_cache), ce->name);
274ffe3c632Sopenharmony_ci
275ffe3c632Sopenharmony_ci  if (!ret && ce->create_object) {
276ffe3c632Sopenharmony_ci#if PHP_VERSION_ID < 80000
277ffe3c632Sopenharmony_ci    zval tmp;
278ffe3c632Sopenharmony_ci    zval zv;
279ffe3c632Sopenharmony_ci    ZVAL_OBJ(&tmp, ce->create_object(ce));
280ffe3c632Sopenharmony_ci    zend_call_method_with_0_params(&tmp, ce, NULL, "__construct", &zv);
281ffe3c632Sopenharmony_ci    zval_ptr_dtor(&tmp);
282ffe3c632Sopenharmony_ci#else
283ffe3c632Sopenharmony_ci    zval zv;
284ffe3c632Sopenharmony_ci    zend_object *tmp = ce->create_object(ce);
285ffe3c632Sopenharmony_ci    zend_call_method_with_0_params(tmp, ce, NULL, "__construct", &zv);
286ffe3c632Sopenharmony_ci    OBJ_RELEASE(tmp);
287ffe3c632Sopenharmony_ci#endif
288ffe3c632Sopenharmony_ci    zval_ptr_dtor(&zv);
289ffe3c632Sopenharmony_ci    ret = zend_hash_find_ptr(&PROTOBUF_G(name_msg_cache), ce->name);
290ffe3c632Sopenharmony_ci  }
291ffe3c632Sopenharmony_ci
292ffe3c632Sopenharmony_ci  return ret;
293ffe3c632Sopenharmony_ci}
294ffe3c632Sopenharmony_ci
295ffe3c632Sopenharmony_ciconst upb_enumdef *NameMap_GetEnum(zend_class_entry *ce) {
296ffe3c632Sopenharmony_ci  const upb_enumdef *ret =
297ffe3c632Sopenharmony_ci      zend_hash_find_ptr(&PROTOBUF_G(name_enum_cache), ce->name);
298ffe3c632Sopenharmony_ci  return ret;
299ffe3c632Sopenharmony_ci}
300ffe3c632Sopenharmony_ci
301ffe3c632Sopenharmony_ci// -----------------------------------------------------------------------------
302ffe3c632Sopenharmony_ci// Module init.
303ffe3c632Sopenharmony_ci// -----------------------------------------------------------------------------
304ffe3c632Sopenharmony_ci
305ffe3c632Sopenharmony_cizend_function_entry protobuf_functions[] = {
306ffe3c632Sopenharmony_ci  PHP_FE(protobuf_internal_loadbundled, arginfo_load_bundled_source)
307ffe3c632Sopenharmony_ci  ZEND_FE_END
308ffe3c632Sopenharmony_ci};
309ffe3c632Sopenharmony_ci
310ffe3c632Sopenharmony_cistatic const zend_module_dep protobuf_deps[] = {
311ffe3c632Sopenharmony_ci  ZEND_MOD_OPTIONAL("date")
312ffe3c632Sopenharmony_ci  ZEND_MOD_END
313ffe3c632Sopenharmony_ci};
314ffe3c632Sopenharmony_ci
315ffe3c632Sopenharmony_ciPHP_INI_BEGIN()
316ffe3c632Sopenharmony_ciSTD_PHP_INI_ENTRY("protobuf.keep_descriptor_pool_after_request", "0",
317ffe3c632Sopenharmony_ci                  PHP_INI_SYSTEM, OnUpdateBool,
318ffe3c632Sopenharmony_ci                  keep_descriptor_pool_after_request, zend_protobuf_globals,
319ffe3c632Sopenharmony_ci                  protobuf_globals)
320ffe3c632Sopenharmony_ciPHP_INI_END()
321ffe3c632Sopenharmony_ci
322ffe3c632Sopenharmony_cistatic PHP_MINIT_FUNCTION(protobuf) {
323ffe3c632Sopenharmony_ci  REGISTER_INI_ENTRIES();
324ffe3c632Sopenharmony_ci  Arena_ModuleInit();
325ffe3c632Sopenharmony_ci  Array_ModuleInit();
326ffe3c632Sopenharmony_ci  Convert_ModuleInit();
327ffe3c632Sopenharmony_ci  Def_ModuleInit();
328ffe3c632Sopenharmony_ci  Map_ModuleInit();
329ffe3c632Sopenharmony_ci  Message_ModuleInit();
330ffe3c632Sopenharmony_ci  return SUCCESS;
331ffe3c632Sopenharmony_ci}
332ffe3c632Sopenharmony_ci
333ffe3c632Sopenharmony_cistatic PHP_MSHUTDOWN_FUNCTION(protobuf) {
334ffe3c632Sopenharmony_ci  return SUCCESS;
335ffe3c632Sopenharmony_ci}
336ffe3c632Sopenharmony_ci
337ffe3c632Sopenharmony_cizend_module_entry protobuf_module_entry = {
338ffe3c632Sopenharmony_ci  STANDARD_MODULE_HEADER_EX,
339ffe3c632Sopenharmony_ci  NULL,
340ffe3c632Sopenharmony_ci  protobuf_deps,
341ffe3c632Sopenharmony_ci  "protobuf",               // extension name
342ffe3c632Sopenharmony_ci  protobuf_functions,       // function list
343ffe3c632Sopenharmony_ci  PHP_MINIT(protobuf),      // process startup
344ffe3c632Sopenharmony_ci  PHP_MSHUTDOWN(protobuf),  // process shutdown
345ffe3c632Sopenharmony_ci  PHP_RINIT(protobuf),      // request shutdown
346ffe3c632Sopenharmony_ci  PHP_RSHUTDOWN(protobuf),  // request shutdown
347ffe3c632Sopenharmony_ci  NULL,                     // extension info
348ffe3c632Sopenharmony_ci  "3.13.0",                 // extension version
349ffe3c632Sopenharmony_ci  PHP_MODULE_GLOBALS(protobuf),  // globals descriptor
350ffe3c632Sopenharmony_ci  PHP_GINIT(protobuf),      // globals ctor
351ffe3c632Sopenharmony_ci  PHP_GSHUTDOWN(protobuf),  // globals dtor
352ffe3c632Sopenharmony_ci  NULL,                     // post deactivate
353ffe3c632Sopenharmony_ci  STANDARD_MODULE_PROPERTIES_EX
354ffe3c632Sopenharmony_ci};
355ffe3c632Sopenharmony_ci
356ffe3c632Sopenharmony_ciZEND_GET_MODULE(protobuf)
357