Home | History | Annotate | Download | only in pyext
      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 (at) google.com (Anuraag Agrawal)
     32 // Author: tibell (at) 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