blob: 111fafbf3f6167e4da6a154dfaed200e6617a65a [file] [log] [blame]
Brian Silverman9c614bc2016-02-15 20:20:02 -05001// 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_MAP_CONTAINER_H__
32#define GOOGLE_PROTOBUF_PYTHON_CPP_MAP_CONTAINER_H__
33
34#include <Python.h>
35
36#include <memory>
Brian Silverman9c614bc2016-02-15 20:20:02 -050037
38#include <google/protobuf/descriptor.h>
39#include <google/protobuf/message.h>
Austin Schuh40c16522018-10-28 20:27:54 -070040#include <google/protobuf/pyext/message.h>
Brian Silverman9c614bc2016-02-15 20:20:02 -050041
42namespace google {
43namespace protobuf {
44
45class Message;
46
Brian Silverman9c614bc2016-02-15 20:20:02 -050047namespace python {
48
Austin Schuh40c16522018-10-28 20:27:54 -070049struct CMessageClass;
Brian Silverman9c614bc2016-02-15 20:20:02 -050050
51// This struct is used directly for ScalarMap, and is the base class of
52// MessageMapContainer, which is used for MessageMap.
53struct MapContainer {
54 PyObject_HEAD;
55
56 // This is the top-level C++ Message object that owns the whole
57 // proto tree. Every Python MapContainer holds a
58 // reference to it in order to keep it alive as long as there's a
59 // Python object that references any part of the tree.
Austin Schuh40c16522018-10-28 20:27:54 -070060 CMessage::OwnerRef owner;
Brian Silverman9c614bc2016-02-15 20:20:02 -050061
62 // Pointer to the C++ Message that contains this container. The
63 // MapContainer does not own this pointer.
64 const Message* message;
65
66 // Use to get a mutable message when necessary.
67 Message* GetMutableMessage();
68
69 // Weak reference to a parent CMessage object (i.e. may be NULL.)
70 //
71 // Used to make sure all ancestors are also mutable when first
72 // modifying the container.
73 CMessage* parent;
74
75 // Pointer to the parent's descriptor that describes this
76 // field. Used together with the parent's message when making a
77 // default message instance mutable.
78 // The pointer is owned by the global DescriptorPool.
79 const FieldDescriptor* parent_field_descriptor;
80 const FieldDescriptor* key_field_descriptor;
81 const FieldDescriptor* value_field_descriptor;
82
83 // We bump this whenever we perform a mutation, to invalidate existing
84 // iterators.
85 uint64 version;
86
87 // Releases the messages in the container to a new message.
88 //
89 // Returns 0 on success, -1 on failure.
90 int Release();
91
92 // Set the owner field of self and any children of self.
Austin Schuh40c16522018-10-28 20:27:54 -070093 void SetOwner(const CMessage::OwnerRef& new_owner) { owner = new_owner; }
Brian Silverman9c614bc2016-02-15 20:20:02 -050094};
95
96struct MessageMapContainer : public MapContainer {
Austin Schuh40c16522018-10-28 20:27:54 -070097 // The type used to create new child messages.
98 CMessageClass* message_class;
Brian Silverman9c614bc2016-02-15 20:20:02 -050099
100 // A dict mapping Message* -> CMessage.
101 PyObject* message_dict;
102};
103
Austin Schuh40c16522018-10-28 20:27:54 -0700104bool InitMapContainers();
Brian Silverman9c614bc2016-02-15 20:20:02 -0500105
Austin Schuh40c16522018-10-28 20:27:54 -0700106extern PyTypeObject* MessageMapContainer_Type;
107extern PyTypeObject* ScalarMapContainer_Type;
Brian Silverman9c614bc2016-02-15 20:20:02 -0500108extern PyTypeObject MapIterator_Type; // Both map types use the same iterator.
109
110// Builds a MapContainer object, from a parent message and a
111// field descriptor.
112extern PyObject* NewScalarMapContainer(
113 CMessage* parent, const FieldDescriptor* parent_field_descriptor);
114
115// Builds a MessageMap object, from a parent message and a
116// field descriptor.
117extern PyObject* NewMessageMapContainer(
118 CMessage* parent, const FieldDescriptor* parent_field_descriptor,
Austin Schuh40c16522018-10-28 20:27:54 -0700119 CMessageClass* message_class);
Brian Silverman9c614bc2016-02-15 20:20:02 -0500120
121} // namespace python
122} // namespace protobuf
123
124} // namespace google
125#endif // GOOGLE_PROTOBUF_PYTHON_CPP_MAP_CONTAINER_H__