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
31#ifndef GOOGLE_PROTOBUF_PYTHON_CPP_DESCRIPTOR_POOL_H__
32#define GOOGLE_PROTOBUF_PYTHON_CPP_DESCRIPTOR_POOL_H__
33
34#include <Python.h>
35
36#include <unordered_map>
37#include <google/protobuf/descriptor.h>
38
39namespace google {
40namespace protobuf {
41namespace python {
42
43struct PyMessageFactory;
44
45// The (meta) type of all Messages classes.
46struct CMessageClass;
47
48// Wraps operations to the global DescriptorPool which contains information
49// about all messages and fields.
50//
51// There is normally one pool per process. We make it a Python object only
52// because it contains many Python references.
53//
54// "Methods" that interacts with this DescriptorPool are in the cdescriptor_pool
55// namespace.
56typedef struct PyDescriptorPool {
57  PyObject_HEAD
58
59  // The C++ pool containing Descriptors.
60  DescriptorPool* pool;
61
62  // The error collector to store error info. Can be NULL. This pointer is
63  // owned.
64  DescriptorPool::ErrorCollector* error_collector;
65
66  // The C++ pool acting as an underlay. Can be NULL.
67  // This pointer is not owned and must stay alive.
68  const DescriptorPool* underlay;
69
70  // The C++ descriptor database used to fetch unknown protos. Can be NULL.
71  // This pointer is owned.
72  const DescriptorDatabase* database;
73
74  // The preferred MessageFactory to be used by descriptors.
75  // TODO(amauryfa): Don't create the Factory from the DescriptorPool, but
76  // use the one passed while creating message classes. And remove this member.
77  PyMessageFactory* py_message_factory;
78
79  // Cache the options for any kind of descriptor.
80  // Descriptor pointers are owned by the DescriptorPool above.
81  // Python objects are owned by the map.
82  std::unordered_map<const void*, PyObject*>* descriptor_options;
83} PyDescriptorPool;
84
85
86extern PyTypeObject PyDescriptorPool_Type;
87
88namespace cdescriptor_pool {
89
90
91// The functions below are also exposed as methods of the DescriptorPool type.
92
93// Looks up a field by name. Returns a PyFieldDescriptor corresponding to
94// the field on success, or NULL on failure.
95//
96// Returns a new reference.
97PyObject* FindFieldByName(PyDescriptorPool* self, PyObject* name);
98
99// Looks up an extension by name. Returns a PyFieldDescriptor corresponding
100// to the field on success, or NULL on failure.
101//
102// Returns a new reference.
103PyObject* FindExtensionByName(PyDescriptorPool* self, PyObject* arg);
104
105// Looks up an enum type by name. Returns a PyEnumDescriptor corresponding
106// to the field on success, or NULL on failure.
107//
108// Returns a new reference.
109PyObject* FindEnumTypeByName(PyDescriptorPool* self, PyObject* arg);
110
111// Looks up a oneof by name. Returns a COneofDescriptor corresponding
112// to the oneof on success, or NULL on failure.
113//
114// Returns a new reference.
115PyObject* FindOneofByName(PyDescriptorPool* self, PyObject* arg);
116
117}  // namespace cdescriptor_pool
118
119// Retrieve the global descriptor pool owned by the _message module.
120// This is the one used by pb2.py generated modules.
121// Returns a *borrowed* reference.
122// "Default" pool used to register messages from _pb2.py modules.
123PyDescriptorPool* GetDefaultDescriptorPool();
124
125// Retrieve the python descriptor pool owning a C++ descriptor pool.
126// Returns a *borrowed* reference.
127PyDescriptorPool* GetDescriptorPool_FromPool(const DescriptorPool* pool);
128
129// Initialize objects used by this module.
130bool InitDescriptorPool();
131
132}  // namespace python
133}  // namespace protobuf
134}  // namespace google
135
136#endif  // GOOGLE_PROTOBUF_PYTHON_CPP_DESCRIPTOR_POOL_H__
137