Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(10)

Side by Side Diff: third_party/protobuf/python/google/protobuf/pyext/extension_dict.cc

Issue 2590803003: Revert "third_party/protobuf: Update to HEAD (83d681ee2c)" (Closed)
Patch Set: Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Protocol Buffers - Google's data interchange format 1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2008 Google Inc. All rights reserved. 2 // Copyright 2008 Google Inc. All rights reserved.
3 // https://developers.google.com/protocol-buffers/ 3 // https://developers.google.com/protocol-buffers/
4 // 4 //
5 // Redistribution and use in source and binary forms, with or without 5 // Redistribution and use in source and binary forms, with or without
6 // modification, are permitted provided that the following conditions are 6 // modification, are permitted provided that the following conditions are
7 // met: 7 // met:
8 // 8 //
9 // * Redistributions of source code must retain the above copyright 9 // * Redistributions of source code must retain the above copyright
10 // notice, this list of conditions and the following disclaimer. 10 // notice, this list of conditions and the following disclaimer.
(...skipping 20 matching lines...) Expand all
31 // Author: anuraag@google.com (Anuraag Agrawal) 31 // Author: anuraag@google.com (Anuraag Agrawal)
32 // Author: tibell@google.com (Johan Tibell) 32 // Author: tibell@google.com (Johan Tibell)
33 33
34 #include <google/protobuf/pyext/extension_dict.h> 34 #include <google/protobuf/pyext/extension_dict.h>
35 35
36 #include <google/protobuf/stubs/logging.h> 36 #include <google/protobuf/stubs/logging.h>
37 #include <google/protobuf/stubs/common.h> 37 #include <google/protobuf/stubs/common.h>
38 #include <google/protobuf/descriptor.h> 38 #include <google/protobuf/descriptor.h>
39 #include <google/protobuf/dynamic_message.h> 39 #include <google/protobuf/dynamic_message.h>
40 #include <google/protobuf/message.h> 40 #include <google/protobuf/message.h>
41 #include <google/protobuf/descriptor.pb.h>
42 #include <google/protobuf/pyext/descriptor.h> 41 #include <google/protobuf/pyext/descriptor.h>
42 #include <google/protobuf/pyext/descriptor_pool.h>
43 #include <google/protobuf/pyext/message.h> 43 #include <google/protobuf/pyext/message.h>
44 #include <google/protobuf/pyext/message_factory.h>
45 #include <google/protobuf/pyext/repeated_composite_container.h> 44 #include <google/protobuf/pyext/repeated_composite_container.h>
46 #include <google/protobuf/pyext/repeated_scalar_container.h> 45 #include <google/protobuf/pyext/repeated_scalar_container.h>
47 #include <google/protobuf/pyext/scoped_pyobject_ptr.h> 46 #include <google/protobuf/pyext/scoped_pyobject_ptr.h>
48 #include <google/protobuf/stubs/shared_ptr.h> 47 #include <google/protobuf/stubs/shared_ptr.h>
49 48
50 #if PY_MAJOR_VERSION >= 3
51 #if PY_VERSION_HEX < 0x03030000
52 #error "Python 3.0 - 3.2 are not supported."
53 #endif
54 #define PyString_AsStringAndSize(ob, charpp, sizep) \
55 (PyUnicode_Check(ob)? \
56 ((*(charpp) = PyUnicode_AsUTF8AndSize(ob, (sizep))) == NULL? -1: 0): \
57 PyBytes_AsStringAndSize(ob, (charpp), (sizep)))
58 #endif
59
60 namespace google { 49 namespace google {
61 namespace protobuf { 50 namespace protobuf {
62 namespace python { 51 namespace python {
63 52
64 namespace extension_dict { 53 namespace extension_dict {
65 54
66 PyObject* len(ExtensionDict* self) { 55 PyObject* len(ExtensionDict* self) {
67 #if PY_MAJOR_VERSION >= 3 56 #if PY_MAJOR_VERSION >= 3
68 return PyLong_FromLong(PyDict_Size(self->values)); 57 return PyLong_FromLong(PyDict_Size(self->values));
69 #else 58 #else
70 return PyInt_FromLong(PyDict_Size(self->values)); 59 return PyInt_FromLong(PyDict_Size(self->values));
71 #endif 60 #endif
72 } 61 }
73 62
63 // TODO(tibell): Use VisitCompositeField.
64 int ReleaseExtension(ExtensionDict* self,
65 PyObject* extension,
66 const FieldDescriptor* descriptor) {
67 if (descriptor->label() == FieldDescriptor::LABEL_REPEATED) {
68 if (descriptor->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
69 if (repeated_composite_container::Release(
70 reinterpret_cast<RepeatedCompositeContainer*>(
71 extension)) < 0) {
72 return -1;
73 }
74 } else {
75 if (repeated_scalar_container::Release(
76 reinterpret_cast<RepeatedScalarContainer*>(
77 extension)) < 0) {
78 return -1;
79 }
80 }
81 } else if (descriptor->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
82 if (cmessage::ReleaseSubMessage(
83 self->parent, descriptor,
84 reinterpret_cast<CMessage*>(extension)) < 0) {
85 return -1;
86 }
87 }
88
89 return 0;
90 }
91
74 PyObject* subscript(ExtensionDict* self, PyObject* key) { 92 PyObject* subscript(ExtensionDict* self, PyObject* key) {
75 const FieldDescriptor* descriptor = cmessage::GetExtensionDescriptor(key); 93 const FieldDescriptor* descriptor = cmessage::GetExtensionDescriptor(key);
76 if (descriptor == NULL) { 94 if (descriptor == NULL) {
77 return NULL; 95 return NULL;
78 } 96 }
79 if (!CheckFieldBelongsToMessage(descriptor, self->message)) { 97 if (!CheckFieldBelongsToMessage(descriptor, self->message)) {
80 return NULL; 98 return NULL;
81 } 99 }
82 100
83 if (descriptor->label() != FieldDescriptor::LABEL_REPEATED && 101 if (descriptor->label() != FieldDescriptor::LABEL_REPEATED &&
(...skipping 10 matching lines...) Expand all
94 if (self->parent == NULL) { 112 if (self->parent == NULL) {
95 // We are in "detached" state. Don't allow further modifications. 113 // We are in "detached" state. Don't allow further modifications.
96 // TODO(amauryfa): Support adding non-scalars to a detached extension dict. 114 // TODO(amauryfa): Support adding non-scalars to a detached extension dict.
97 // This probably requires to store the type of the main message. 115 // This probably requires to store the type of the main message.
98 PyErr_SetObject(PyExc_KeyError, key); 116 PyErr_SetObject(PyExc_KeyError, key);
99 return NULL; 117 return NULL;
100 } 118 }
101 119
102 if (descriptor->label() != FieldDescriptor::LABEL_REPEATED && 120 if (descriptor->label() != FieldDescriptor::LABEL_REPEATED &&
103 descriptor->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { 121 descriptor->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
104 // TODO(plabatut): consider building the class on the fly!
105 PyObject* sub_message = cmessage::InternalGetSubMessage( 122 PyObject* sub_message = cmessage::InternalGetSubMessage(
106 self->parent, descriptor); 123 self->parent, descriptor);
107 if (sub_message == NULL) { 124 if (sub_message == NULL) {
108 return NULL; 125 return NULL;
109 } 126 }
110 PyDict_SetItem(self->values, key, sub_message); 127 PyDict_SetItem(self->values, key, sub_message);
111 return sub_message; 128 return sub_message;
112 } 129 }
113 130
114 if (descriptor->label() == FieldDescriptor::LABEL_REPEATED) { 131 if (descriptor->label() == FieldDescriptor::LABEL_REPEATED) {
115 if (descriptor->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { 132 if (descriptor->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
116 // On the fly message class creation is needed to support the following 133 CMessageClass* message_class = cdescriptor_pool::GetMessageClass(
117 // situation: 134 cmessage::GetDescriptorPoolForMessage(self->parent),
118 // 1- add FileDescriptor to the pool that contains extensions of a message
119 // defined by another proto file. Do not create any message classes.
120 // 2- instantiate an extended message, and access the extension using
121 // the field descriptor.
122 // 3- the extension submessage fails to be returned, because no class has
123 // been created.
124 // It happens when deserializing text proto format, or when enumerating
125 // fields of a deserialized message.
126 CMessageClass* message_class = message_factory::GetOrCreateMessageClass(
127 cmessage::GetFactoryForMessage(self->parent),
128 descriptor->message_type()); 135 descriptor->message_type());
129 if (message_class == NULL) { 136 if (message_class == NULL) {
130 return NULL; 137 return NULL;
131 } 138 }
132 PyObject* py_container = repeated_composite_container::NewContainer( 139 PyObject* py_container = repeated_composite_container::NewContainer(
133 self->parent, descriptor, message_class); 140 self->parent, descriptor, message_class);
134 if (py_container == NULL) { 141 if (py_container == NULL) {
135 return NULL; 142 return NULL;
136 } 143 }
137 PyDict_SetItem(self->values, key, py_container); 144 PyDict_SetItem(self->values, key, py_container);
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
169 cmessage::AssureWritable(self->parent); 176 cmessage::AssureWritable(self->parent);
170 if (cmessage::InternalSetScalar(self->parent, descriptor, value) < 0) { 177 if (cmessage::InternalSetScalar(self->parent, descriptor, value) < 0) {
171 return -1; 178 return -1;
172 } 179 }
173 } 180 }
174 // TODO(tibell): We shouldn't write scalars to the cache. 181 // TODO(tibell): We shouldn't write scalars to the cache.
175 PyDict_SetItem(self->values, key, value); 182 PyDict_SetItem(self->values, key, value);
176 return 0; 183 return 0;
177 } 184 }
178 185
179 PyObject* _FindExtensionByName(ExtensionDict* self, PyObject* arg) { 186 PyObject* ClearExtension(ExtensionDict* self, PyObject* extension) {
180 char* name; 187 const FieldDescriptor* descriptor =
181 Py_ssize_t name_size; 188 cmessage::GetExtensionDescriptor(extension);
182 if (PyString_AsStringAndSize(arg, &name, &name_size) < 0) { 189 if (descriptor == NULL) {
183 return NULL; 190 return NULL;
184 } 191 }
185 192 PyObject* value = PyDict_GetItem(self->values, extension);
186 PyDescriptorPool* pool = cmessage::GetFactoryForMessage(self->parent)->pool; 193 if (self->parent) {
187 const FieldDescriptor* message_extension = 194 if (value != NULL) {
188 pool->pool->FindExtensionByName(string(name, name_size)); 195 if (ReleaseExtension(self, value, descriptor) < 0) {
189 if (message_extension == NULL) { 196 return NULL;
190 // Is is the name of a message set extension?
191 const Descriptor* message_descriptor = pool->pool->FindMessageTypeByName(
192 string(name, name_size));
193 if (message_descriptor && message_descriptor->extension_count() > 0) {
194 const FieldDescriptor* extension = message_descriptor->extension(0);
195 if (extension->is_extension() &&
196 extension->containing_type()->options().message_set_wire_format() &&
197 extension->type() == FieldDescriptor::TYPE_MESSAGE &&
198 extension->label() == FieldDescriptor::LABEL_OPTIONAL) {
199 message_extension = extension;
200 } 197 }
201 } 198 }
199 if (ScopedPyObjectPtr(cmessage::ClearFieldByDescriptor(
200 self->parent, descriptor)) == NULL) {
201 return NULL;
202 }
202 } 203 }
203 if (message_extension == NULL) { 204 if (PyDict_DelItem(self->values, extension) < 0) {
204 Py_RETURN_NONE; 205 PyErr_Clear();
205 } 206 }
206 207 Py_RETURN_NONE;
207 return PyFieldDescriptor_FromDescriptor(message_extension);
208 } 208 }
209 209
210 PyObject* _FindExtensionByNumber(ExtensionDict* self, PyObject* arg) { 210 PyObject* HasExtension(ExtensionDict* self, PyObject* extension) {
211 int64 number = PyLong_AsLong(arg); 211 const FieldDescriptor* descriptor =
212 if (number == -1 && PyErr_Occurred()) { 212 cmessage::GetExtensionDescriptor(extension);
213 if (descriptor == NULL) {
213 return NULL; 214 return NULL;
214 } 215 }
216 if (self->parent) {
217 return cmessage::HasFieldByDescriptor(self->parent, descriptor);
218 } else {
219 int exists = PyDict_Contains(self->values, extension);
220 if (exists < 0) {
221 return NULL;
222 }
223 return PyBool_FromLong(exists);
224 }
225 }
215 226
216 PyDescriptorPool* pool = cmessage::GetFactoryForMessage(self->parent)->pool; 227 PyObject* _FindExtensionByName(ExtensionDict* self, PyObject* name) {
217 const FieldDescriptor* message_extension = pool->pool->FindExtensionByNumber( 228 ScopedPyObjectPtr extensions_by_name(PyObject_GetAttrString(
218 self->parent->message->GetDescriptor(), number); 229 reinterpret_cast<PyObject*>(self->parent), "_extensions_by_name"));
219 if (message_extension == NULL) { 230 if (extensions_by_name == NULL) {
231 return NULL;
232 }
233 PyObject* result = PyDict_GetItem(extensions_by_name.get(), name);
234 if (result == NULL) {
220 Py_RETURN_NONE; 235 Py_RETURN_NONE;
236 } else {
237 Py_INCREF(result);
238 return result;
221 } 239 }
240 }
222 241
223 return PyFieldDescriptor_FromDescriptor(message_extension); 242 PyObject* _FindExtensionByNumber(ExtensionDict* self, PyObject* number) {
243 ScopedPyObjectPtr extensions_by_number(PyObject_GetAttrString(
244 reinterpret_cast<PyObject*>(self->parent), "_extensions_by_number"));
245 if (extensions_by_number == NULL) {
246 return NULL;
247 }
248 PyObject* result = PyDict_GetItem(extensions_by_number.get(), number);
249 if (result == NULL) {
250 Py_RETURN_NONE;
251 } else {
252 Py_INCREF(result);
253 return result;
254 }
224 } 255 }
225 256
226 ExtensionDict* NewExtensionDict(CMessage *parent) { 257 ExtensionDict* NewExtensionDict(CMessage *parent) {
227 ExtensionDict* self = reinterpret_cast<ExtensionDict*>( 258 ExtensionDict* self = reinterpret_cast<ExtensionDict*>(
228 PyType_GenericAlloc(&ExtensionDict_Type, 0)); 259 PyType_GenericAlloc(&ExtensionDict_Type, 0));
229 if (self == NULL) { 260 if (self == NULL) {
230 return NULL; 261 return NULL;
231 } 262 }
232 263
233 self->parent = parent; // Store a borrowed reference. 264 self->parent = parent; // Store a borrowed reference.
(...skipping 10 matching lines...) Expand all
244 } 275 }
245 276
246 static PyMappingMethods MpMethods = { 277 static PyMappingMethods MpMethods = {
247 (lenfunc)len, /* mp_length */ 278 (lenfunc)len, /* mp_length */
248 (binaryfunc)subscript, /* mp_subscript */ 279 (binaryfunc)subscript, /* mp_subscript */
249 (objobjargproc)ass_subscript,/* mp_ass_subscript */ 280 (objobjargproc)ass_subscript,/* mp_ass_subscript */
250 }; 281 };
251 282
252 #define EDMETHOD(name, args, doc) { #name, (PyCFunction)name, args, doc } 283 #define EDMETHOD(name, args, doc) { #name, (PyCFunction)name, args, doc }
253 static PyMethodDef Methods[] = { 284 static PyMethodDef Methods[] = {
285 EDMETHOD(ClearExtension, METH_O, "Clears an extension from the object."),
286 EDMETHOD(HasExtension, METH_O, "Checks if the object has an extension."),
254 EDMETHOD(_FindExtensionByName, METH_O, 287 EDMETHOD(_FindExtensionByName, METH_O,
255 "Finds an extension by name."), 288 "Finds an extension by name."),
256 EDMETHOD(_FindExtensionByNumber, METH_O, 289 EDMETHOD(_FindExtensionByNumber, METH_O,
257 "Finds an extension by field number."), 290 "Finds an extension by field number."),
258 { NULL, NULL } 291 { NULL, NULL }
259 }; 292 };
260 293
261 } // namespace extension_dict 294 } // namespace extension_dict
262 295
263 PyTypeObject ExtensionDict_Type = { 296 PyTypeObject ExtensionDict_Type = {
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
295 0, // tp_dict 328 0, // tp_dict
296 0, // tp_descr_get 329 0, // tp_descr_get
297 0, // tp_descr_set 330 0, // tp_descr_set
298 0, // tp_dictoffset 331 0, // tp_dictoffset
299 0, // tp_init 332 0, // tp_init
300 }; 333 };
301 334
302 } // namespace python 335 } // namespace python
303 } // namespace protobuf 336 } // namespace protobuf
304 } // namespace google 337 } // namespace google
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698