blob: 5b2b1facf6e4f7746c1be05c42dfacf3d3fa4e75 [file] [log] [blame]
Adam Cozzette501ecec2023-09-26 14:36:20 -07001// Protocol Buffers - Google's data interchange format
2// Copyright 2023 Google LLC. 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 LLC 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
31#ifndef PYUPB_DESCRIPTOR_CONTAINERS_H__
32#define PYUPB_DESCRIPTOR_CONTAINERS_H__
33
34// This file defines immutable Python containiner types whose data comes from
35// an underlying descriptor (def).
36//
37// Because there are many instances of these types that vend different kinds of
38// data (fields, oneofs, enums, etc) these types accept a "vtable" of function
39// pointers. This saves us from having to define numerous distinct Python types
40// for each kind of data we want to vend.
41//
42// The underlying upb APIs follow a consistent pattern that allows us to use
43// those functions directly inside these vtables, greatly reducing the amount of
44// "adaptor" code we need to write.
45
46#include <stdbool.h>
47
48#include "protobuf.h"
49#include "upb/reflection/def.h"
50
51// -----------------------------------------------------------------------------
52// PyUpb_GenericSequence
53// -----------------------------------------------------------------------------
54
55// A Python object that vends a sequence of descriptors.
56
57typedef struct {
58 // Returns the number of elements in the map.
59 int (*get_elem_count)(const void* parent);
60 // Returns an element by index.
61 const void* (*index)(const void* parent, int idx);
62 // Returns a Python object wrapping this element, caller owns a ref.
63 PyObject* (*get_elem_wrapper)(const void* elem);
64} PyUpb_GenericSequence_Funcs;
65
66// Returns a new GenericSequence. The vtable `funcs` must outlive this object
67// (generally it should be static). The GenericSequence will take a ref on
68// `parent_obj`, which must be sufficient to keep `parent` alive. The object
69// `parent` will be passed as an argument to the functions in `funcs`.
70PyObject* PyUpb_GenericSequence_New(const PyUpb_GenericSequence_Funcs* funcs,
71 const void* parent, PyObject* parent_obj);
72
73// -----------------------------------------------------------------------------
74// PyUpb_ByNameMap
75// -----------------------------------------------------------------------------
76
77// A Python object that vends a name->descriptor map.
78
79typedef struct {
80 PyUpb_GenericSequence_Funcs base;
81 // Looks up by name and returns either a pointer to the element or NULL.
82 const void* (*lookup)(const void* parent, const char* key);
83 // Returns the name associated with this element.
84 const char* (*get_elem_name)(const void* elem);
85} PyUpb_ByNameMap_Funcs;
86
87// Returns a new ByNameMap. The vtable `funcs` must outlive this object
88// (generally it should be static). The ByNameMap will take a ref on
89// `parent_obj`, which must be sufficient to keep `parent` alive. The object
90// `parent` will be passed as an argument to the functions in `funcs`.
91PyObject* PyUpb_ByNameMap_New(const PyUpb_ByNameMap_Funcs* funcs,
92 const void* parent, PyObject* parent_obj);
93
94// -----------------------------------------------------------------------------
95// PyUpb_ByNumberMap
96// -----------------------------------------------------------------------------
97
98// A Python object that vends a number->descriptor map.
99
100typedef struct {
101 PyUpb_GenericSequence_Funcs base;
102 // Looks up by name and returns either a pointer to the element or NULL.
103 const void* (*lookup)(const void* parent, int num);
104 // Returns the name associated with this element.
105 int (*get_elem_num)(const void* elem);
106} PyUpb_ByNumberMap_Funcs;
107
108// Returns a new ByNumberMap. The vtable `funcs` must outlive this object
109// (generally it should be static). The ByNumberMap will take a ref on
110// `parent_obj`, which must be sufficient to keep `parent` alive. The object
111// `parent` will be passed as an argument to the functions in `funcs`.
112PyObject* PyUpb_ByNumberMap_New(const PyUpb_ByNumberMap_Funcs* funcs,
113 const void* parent, PyObject* parent_obj);
114
115bool PyUpb_InitDescriptorContainers(PyObject* m);
116
117#endif // PYUPB_DESCRIPTOR_CONTAINERS_H__