• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2008 Google Inc.  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 GOOGLE_PROTOBUF_PYTHON_CPP_MESSAGE_FACTORY_H__
9 #define GOOGLE_PROTOBUF_PYTHON_CPP_MESSAGE_FACTORY_H__
10 
11 #define PY_SSIZE_T_CLEAN
12 #include <Python.h>
13 
14 #include <unordered_map>
15 #include "google/protobuf/descriptor.h"
16 #include "google/protobuf/pyext/descriptor_pool.h"
17 
18 namespace google {
19 namespace protobuf {
20 class MessageFactory;
21 
22 namespace python {
23 
24 // The (meta) type of all Messages classes.
25 struct CMessageClass;
26 
27 struct PyMessageFactory {
28   PyObject_HEAD
29 
30   // DynamicMessageFactory used to create C++ instances of messages.
31   // This object cache the descriptors that were used, so the DescriptorPool
32   // needs to get rid of it before it can delete itself.
33   //
34   // Note: A C++ MessageFactory is different from the PyMessageFactory.
35   // The C++ one creates messages, when the Python one creates classes.
36   MessageFactory* message_factory;
37 
38   // Owned reference to a Python DescriptorPool.
39   // This reference must stay until the message_factory is destructed.
40   PyDescriptorPool* pool;
41 
42   // Make our own mapping to retrieve Python classes from C++ descriptors.
43   //
44   // Descriptor pointers stored here are owned by the DescriptorPool above.
45   // Python references to classes are owned by this PyDescriptorPool.
46   typedef std::unordered_map<const Descriptor*, CMessageClass*>
47       ClassesByMessageMap;
48   ClassesByMessageMap* classes_by_descriptor;
49 };
50 
51 extern PyTypeObject PyMessageFactory_Type;
52 
53 namespace message_factory {
54 
55 // Creates a new MessageFactory instance.
56 PyMessageFactory* NewMessageFactory(PyTypeObject* type, PyDescriptorPool* pool);
57 
58 // Registers a new Python class for the given message descriptor.
59 // On error, returns -1 with a Python exception set.
60 int RegisterMessageClass(PyMessageFactory* self,
61                          const Descriptor* message_descriptor,
62                          CMessageClass* message_class);
63 // Retrieves the Python class registered with the given message descriptor, or
64 // fail with a TypeError. Returns a *borrowed* reference.
65 CMessageClass* GetMessageClass(PyMessageFactory* self,
66                                const Descriptor* message_descriptor);
67 // Retrieves the Python class registered with the given message descriptor.
68 // The class is created if not done yet. Returns a *new* reference.
69 CMessageClass* GetOrCreateMessageClass(PyMessageFactory* self,
70                                        const Descriptor* message_descriptor);
71 }  // namespace message_factory
72 
73 // Initialize objects used by this module.
74 // On error, returns false with a Python exception set.
75 bool InitMessageFactory();
76 
77 }  // namespace python
78 }  // namespace protobuf
79 }  // namespace google
80 
81 #endif  // GOOGLE_PROTOBUF_PYTHON_CPP_MESSAGE_FACTORY_H__
82