• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2023 Google LLC.  All rights reserved.
3 //
4 // Use of this source code is governed by a BSD-style
5 // license that can be found in the LICENSE file or at
6 // https://developers.google.com/open-source/licenses/bsd
7 
8 #ifndef PYUPB_DESCRIPTOR_CONTAINERS_H__
9 #define PYUPB_DESCRIPTOR_CONTAINERS_H__
10 
11 // This file defines immutable Python containiner types whose data comes from
12 // an underlying descriptor (def).
13 //
14 // Because there are many instances of these types that vend different kinds of
15 // data (fields, oneofs, enums, etc) these types accept a "vtable" of function
16 // pointers. This saves us from having to define numerous distinct Python types
17 // for each kind of data we want to vend.
18 //
19 // The underlying upb APIs follow a consistent pattern that allows us to use
20 // those functions directly inside these vtables, greatly reducing the amount of
21 // "adaptor" code we need to write.
22 
23 #include <stdbool.h>
24 
25 #include "protobuf.h"
26 #include "upb/reflection/def.h"
27 
28 // -----------------------------------------------------------------------------
29 // PyUpb_GenericSequence
30 // -----------------------------------------------------------------------------
31 
32 // A Python object that vends a sequence of descriptors.
33 
34 typedef struct {
35   // Returns the number of elements in the map.
36   int (*get_elem_count)(const void* parent);
37   // Returns an element by index.
38   const void* (*index)(const void* parent, int idx);
39   // Returns a Python object wrapping this element, caller owns a ref.
40   PyObject* (*get_elem_wrapper)(const void* elem);
41 } PyUpb_GenericSequence_Funcs;
42 
43 // Returns a new GenericSequence.  The vtable `funcs` must outlive this object
44 // (generally it should be static).  The GenericSequence will take a ref on
45 // `parent_obj`, which must be sufficient to keep `parent` alive.  The object
46 // `parent` will be passed as an argument to the functions in `funcs`.
47 PyObject* PyUpb_GenericSequence_New(const PyUpb_GenericSequence_Funcs* funcs,
48                                     const void* parent, PyObject* parent_obj);
49 
50 // -----------------------------------------------------------------------------
51 // PyUpb_ByNameMap
52 // -----------------------------------------------------------------------------
53 
54 // A Python object that vends a name->descriptor map.
55 
56 typedef struct {
57   PyUpb_GenericSequence_Funcs base;
58   // Looks up by name and returns either a pointer to the element or NULL.
59   const void* (*lookup)(const void* parent, const char* key);
60   // Returns the name associated with this element.
61   const char* (*get_elem_name)(const void* elem);
62 } PyUpb_ByNameMap_Funcs;
63 
64 // Returns a new ByNameMap.  The vtable `funcs` must outlive this object
65 // (generally it should be static).  The ByNameMap will take a ref on
66 // `parent_obj`, which must be sufficient to keep `parent` alive.  The object
67 // `parent` will be passed as an argument to the functions in `funcs`.
68 PyObject* PyUpb_ByNameMap_New(const PyUpb_ByNameMap_Funcs* funcs,
69                               const void* parent, PyObject* parent_obj);
70 
71 // -----------------------------------------------------------------------------
72 // PyUpb_ByNumberMap
73 // -----------------------------------------------------------------------------
74 
75 // A Python object that vends a number->descriptor map.
76 
77 typedef struct {
78   PyUpb_GenericSequence_Funcs base;
79   // Looks up by name and returns either a pointer to the element or NULL.
80   const void* (*lookup)(const void* parent, int num);
81   // Returns the name associated with this element.
82   int (*get_elem_num)(const void* elem);
83 } PyUpb_ByNumberMap_Funcs;
84 
85 // Returns a new ByNumberMap.  The vtable `funcs` must outlive this object
86 // (generally it should be static).  The ByNumberMap will take a ref on
87 // `parent_obj`, which must be sufficient to keep `parent` alive.  The object
88 // `parent` will be passed as an argument to the functions in `funcs`.
89 PyObject* PyUpb_ByNumberMap_New(const PyUpb_ByNumberMap_Funcs* funcs,
90                                 const void* parent, PyObject* parent_obj);
91 
92 bool PyUpb_InitDescriptorContainers(PyObject* m);
93 
94 #endif  // PYUPB_DESCRIPTOR_CONTAINERS_H__
95