blob: 442ce7e3fd713c92694a35782e428d56e7fdc2d2 [file] [log] [blame]
jieluo@google.combde4a322014-08-12 21:10:30 +00001// Protocol Buffers - Google's data interchange format
2// Copyright 2008 Google Inc. All rights reserved.
Feng Xiaoe4288622014-10-01 16:26:23 -07003// https://developers.google.com/protocol-buffers/
jieluo@google.combde4a322014-08-12 21:10:30 +00004//
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
jieluo@google.combde4a322014-08-12 21:10:30 +000046namespace google {
47namespace protobuf {
48
49class FieldDescriptor;
50class Message;
51
Manjunath Kudlur3f9b4f22015-12-07 14:15:29 -080052#ifdef _SHARED_PTR_H
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070053using shared_ptr;
Manjunath Kudlur96537c42015-12-09 07:40:30 -080054#else
55using internal::shared_ptr;
Manjunath Kudlur3f9b4f22015-12-07 14:15:29 -080056#endif
jieluo@google.combde4a322014-08-12 21:10:30 +000057
58namespace python {
59
60struct CMessage;
jieluo@google.combde4a322014-08-12 21:10:30 +000061
62// A RepeatedCompositeContainer can be in one of two states: attached
63// or released.
64//
65// When in the attached state all modifications to the container are
66// done both on the 'message' and on the 'child_messages'
Veres Lajosc7680722014-11-08 22:59:34 +000067// list. In this state all Messages referred to by the children in
jieluo@google.combde4a322014-08-12 21:10:30 +000068// 'child_messages' are owner by the 'owner'.
69//
70// When in the released state 'message', 'owner', 'parent', and
Feng Xiao6ef984a2014-11-10 17:34:54 -080071// 'parent_field_descriptor' are NULL.
jieluo@google.combde4a322014-08-12 21:10:30 +000072typedef struct RepeatedCompositeContainer {
73 PyObject_HEAD;
74
75 // This is the top-level C++ Message object that owns the whole
76 // proto tree. Every Python RepeatedCompositeContainer holds a
77 // reference to it in order to keep it alive as long as there's a
78 // Python object that references any part of the tree.
79 shared_ptr<Message> owner;
80
81 // Weak reference to parent object. May be NULL. Used to make sure
82 // the parent is writable before modifying the
83 // RepeatedCompositeContainer.
84 CMessage* parent;
85
86 // A descriptor used to modify the underlying 'message'.
Feng Xiao6ef984a2014-11-10 17:34:54 -080087 // The pointer is owned by the global DescriptorPool.
Jisi Liuada65562015-02-25 16:39:11 -080088 const FieldDescriptor* parent_field_descriptor;
jieluo@google.combde4a322014-08-12 21:10:30 +000089
90 // Pointer to the C++ Message that contains this container. The
91 // RepeatedCompositeContainer does not own this pointer.
92 //
93 // If NULL, this message has been released from its parent (by
94 // calling Clear() or ClearField() on the parent.
95 Message* message;
96
97 // A callable that is used to create new child messages.
98 PyObject* subclass_init;
99
100 // A list of child messages.
101 PyObject* child_messages;
102} RepeatedCompositeContainer;
103
104extern PyTypeObject RepeatedCompositeContainer_Type;
105
106namespace repeated_composite_container {
107
Feng Xiao6ef984a2014-11-10 17:34:54 -0800108// Builds a RepeatedCompositeContainer object, from a parent message and a
109// field descriptor.
110PyObject *NewContainer(
111 CMessage* parent,
Jisi Liuada65562015-02-25 16:39:11 -0800112 const FieldDescriptor* parent_field_descriptor,
Feng Xiao6ef984a2014-11-10 17:34:54 -0800113 PyObject *concrete_class);
114
jieluo@google.combde4a322014-08-12 21:10:30 +0000115// Appends a new CMessage to the container and returns it. The
116// CMessage is initialized using the content of kwargs.
117//
118// Returns a new reference if successful; returns NULL and sets an
119// exception if unsuccessful.
120PyObject* Add(RepeatedCompositeContainer* self,
121 PyObject* args,
122 PyObject* kwargs);
123
124// Appends all the CMessages in the input iterator to the container.
125//
126// Returns None if successful; returns NULL and sets an exception if
127// unsuccessful.
128PyObject* Extend(RepeatedCompositeContainer* self, PyObject* value);
129
130// Appends a new message to the container for each message in the
131// input iterator, merging each data element in. Equivalent to extend.
132//
133// Returns None if successful; returns NULL and sets an exception if
134// unsuccessful.
135PyObject* MergeFrom(RepeatedCompositeContainer* self, PyObject* other);
136
137// Accesses messages in the container.
138//
139// Returns a new reference to the message for an integer parameter.
140// Returns a new reference to a list of messages for a slice.
141PyObject* Subscript(RepeatedCompositeContainer* self, PyObject* slice);
142
143// Deletes items from the container (cannot be used for assignment).
144//
145// Returns 0 on success, -1 on failure.
146int AssignSubscript(RepeatedCompositeContainer* self,
147 PyObject* slice,
148 PyObject* value);
149
150// Releases the messages in the container to the given message.
151//
152// Returns 0 on success, -1 on failure.
Jisi Liuada65562015-02-25 16:39:11 -0800153int ReleaseToMessage(RepeatedCompositeContainer* self, Message* new_message);
jieluo@google.combde4a322014-08-12 21:10:30 +0000154
155// Releases the messages in the container to a new message.
156//
157// Returns 0 on success, -1 on failure.
158int Release(RepeatedCompositeContainer* self);
159
160// Returns 0 on success, -1 on failure.
161int SetOwner(RepeatedCompositeContainer* self,
162 const shared_ptr<Message>& new_owner);
163
164// Removes the last element of the repeated message field 'field' on
Bo Yang5db21732015-05-21 14:28:59 -0700165// the Message 'parent', and transfers the ownership of the released
166// Message to 'target'.
jieluo@google.combde4a322014-08-12 21:10:30 +0000167//
168// Corresponds to reflection api method ReleaseMessage.
Bo Yang5db21732015-05-21 14:28:59 -0700169void ReleaseLastTo(CMessage* parent,
170 const FieldDescriptor* field,
171 CMessage* target);
jieluo@google.combde4a322014-08-12 21:10:30 +0000172
173} // namespace repeated_composite_container
174} // namespace python
175} // namespace protobuf
176
177} // namespace google
178#endif // GOOGLE_PROTOBUF_PYTHON_CPP_REPEATED_COMPOSITE_CONTAINER_H__