• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 // Author: anuraag@google.com (Anuraag Agrawal)
32 // Author: tibell@google.com (Johan Tibell)
33 
34 #ifndef GOOGLE_PROTOBUF_PYTHON_CPP_REPEATED_COMPOSITE_CONTAINER_H__
35 #define GOOGLE_PROTOBUF_PYTHON_CPP_REPEATED_COMPOSITE_CONTAINER_H__
36 
37 #include <Python.h>
38 
39 #include <memory>
40 #ifndef _SHARED_PTR_H
41 #include <google/protobuf/stubs/shared_ptr.h>
42 #endif
43 #include <string>
44 #include <vector>
45 
46 namespace google {
47 namespace protobuf {
48 
49 class FieldDescriptor;
50 class Message;
51 
52 #ifdef _SHARED_PTR_H
53 using std::shared_ptr;
54 #else
55 using internal::shared_ptr;
56 #endif
57 
58 namespace python {
59 
60 struct CMessage;
61 struct CMessageClass;
62 
63 // A RepeatedCompositeContainer can be in one of two states: attached
64 // or released.
65 //
66 // When in the attached state all modifications to the container are
67 // done both on the 'message' and on the 'child_messages'
68 // list.  In this state all Messages referred to by the children in
69 // 'child_messages' are owner by the 'owner'.
70 //
71 // When in the released state 'message', 'owner', 'parent', and
72 // 'parent_field_descriptor' are NULL.
73 typedef struct RepeatedCompositeContainer {
74   PyObject_HEAD;
75 
76   // This is the top-level C++ Message object that owns the whole
77   // proto tree.  Every Python RepeatedCompositeContainer holds a
78   // reference to it in order to keep it alive as long as there's a
79   // Python object that references any part of the tree.
80   shared_ptr<Message> owner;
81 
82   // Weak reference to parent object. May be NULL. Used to make sure
83   // the parent is writable before modifying the
84   // RepeatedCompositeContainer.
85   CMessage* parent;
86 
87   // A descriptor used to modify the underlying 'message'.
88   // The pointer is owned by the global DescriptorPool.
89   const FieldDescriptor* parent_field_descriptor;
90 
91   // Pointer to the C++ Message that contains this container.  The
92   // RepeatedCompositeContainer does not own this pointer.
93   //
94   // If NULL, this message has been released from its parent (by
95   // calling Clear() or ClearField() on the parent.
96   Message* message;
97 
98   // The type used to create new child messages.
99   CMessageClass* child_message_class;
100 
101   // A list of child messages.
102   PyObject* child_messages;
103 } RepeatedCompositeContainer;
104 
105 extern PyTypeObject RepeatedCompositeContainer_Type;
106 
107 namespace repeated_composite_container {
108 
109 // Builds a RepeatedCompositeContainer object, from a parent message and a
110 // field descriptor.
111 PyObject *NewContainer(
112     CMessage* parent,
113     const FieldDescriptor* parent_field_descriptor,
114     CMessageClass *child_message_class);
115 
116 // Appends a new CMessage to the container and returns it.  The
117 // CMessage is initialized using the content of kwargs.
118 //
119 // Returns a new reference if successful; returns NULL and sets an
120 // exception if unsuccessful.
121 PyObject* Add(RepeatedCompositeContainer* self,
122               PyObject* args,
123               PyObject* kwargs);
124 
125 // Appends all the CMessages in the input iterator to the container.
126 //
127 // Returns None if successful; returns NULL and sets an exception if
128 // unsuccessful.
129 PyObject* Extend(RepeatedCompositeContainer* self, PyObject* value);
130 
131 // Appends a new message to the container for each message in the
132 // input iterator, merging each data element in. Equivalent to extend.
133 //
134 // Returns None if successful; returns NULL and sets an exception if
135 // unsuccessful.
136 PyObject* MergeFrom(RepeatedCompositeContainer* self, PyObject* other);
137 
138 // Accesses messages in the container.
139 //
140 // Returns a new reference to the message for an integer parameter.
141 // Returns a new reference to a list of messages for a slice.
142 PyObject* Subscript(RepeatedCompositeContainer* self, PyObject* slice);
143 
144 // Deletes items from the container (cannot be used for assignment).
145 //
146 // Returns 0 on success, -1 on failure.
147 int AssignSubscript(RepeatedCompositeContainer* self,
148                     PyObject* slice,
149                     PyObject* value);
150 
151 // Releases the messages in the container to the given message.
152 //
153 // Returns 0 on success, -1 on failure.
154 int ReleaseToMessage(RepeatedCompositeContainer* self, Message* new_message);
155 
156 // Releases the messages in the container to a new message.
157 //
158 // Returns 0 on success, -1 on failure.
159 int Release(RepeatedCompositeContainer* self);
160 
161 // Returns 0 on success, -1 on failure.
162 int SetOwner(RepeatedCompositeContainer* self,
163              const shared_ptr<Message>& new_owner);
164 
165 // Removes the last element of the repeated message field 'field' on
166 // the Message 'parent', and transfers the ownership of the released
167 // Message to 'target'.
168 //
169 // Corresponds to reflection api method ReleaseMessage.
170 void ReleaseLastTo(CMessage* parent,
171                    const FieldDescriptor* field,
172                    CMessage* target);
173 
174 }  // namespace repeated_composite_container
175 }  // namespace python
176 }  // namespace protobuf
177 
178 }  // namespace google
179 #endif  // GOOGLE_PROTOBUF_PYTHON_CPP_REPEATED_COMPOSITE_CONTAINER_H__
180