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

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

Issue 2495533002: third_party/protobuf: Update to HEAD (83d681ee2c) (Closed)
Patch Set: Make chrome settings proto generated file a component 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>
41 #include <google/protobuf/pyext/descriptor.h> 42 #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>
44 #include <google/protobuf/pyext/repeated_composite_container.h> 45 #include <google/protobuf/pyext/repeated_composite_container.h>
45 #include <google/protobuf/pyext/repeated_scalar_container.h> 46 #include <google/protobuf/pyext/repeated_scalar_container.h>
46 #include <google/protobuf/pyext/scoped_pyobject_ptr.h> 47 #include <google/protobuf/pyext/scoped_pyobject_ptr.h>
47 #include <google/protobuf/stubs/shared_ptr.h> 48 #include <google/protobuf/stubs/shared_ptr.h>
48 49
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
49 namespace google { 60 namespace google {
50 namespace protobuf { 61 namespace protobuf {
51 namespace python { 62 namespace python {
52 63
53 namespace extension_dict { 64 namespace extension_dict {
54 65
55 PyObject* len(ExtensionDict* self) { 66 PyObject* len(ExtensionDict* self) {
56 #if PY_MAJOR_VERSION >= 3 67 #if PY_MAJOR_VERSION >= 3
57 return PyLong_FromLong(PyDict_Size(self->values)); 68 return PyLong_FromLong(PyDict_Size(self->values));
58 #else 69 #else
59 return PyInt_FromLong(PyDict_Size(self->values)); 70 return PyInt_FromLong(PyDict_Size(self->values));
60 #endif 71 #endif
61 } 72 }
62 73
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
92 PyObject* subscript(ExtensionDict* self, PyObject* key) { 74 PyObject* subscript(ExtensionDict* self, PyObject* key) {
93 const FieldDescriptor* descriptor = cmessage::GetExtensionDescriptor(key); 75 const FieldDescriptor* descriptor = cmessage::GetExtensionDescriptor(key);
94 if (descriptor == NULL) { 76 if (descriptor == NULL) {
95 return NULL; 77 return NULL;
96 } 78 }
97 if (!CheckFieldBelongsToMessage(descriptor, self->message)) { 79 if (!CheckFieldBelongsToMessage(descriptor, self->message)) {
98 return NULL; 80 return NULL;
99 } 81 }
100 82
101 if (descriptor->label() != FieldDescriptor::LABEL_REPEATED && 83 if (descriptor->label() != FieldDescriptor::LABEL_REPEATED &&
(...skipping 10 matching lines...) Expand all
112 if (self->parent == NULL) { 94 if (self->parent == NULL) {
113 // We are in "detached" state. Don't allow further modifications. 95 // We are in "detached" state. Don't allow further modifications.
114 // TODO(amauryfa): Support adding non-scalars to a detached extension dict. 96 // TODO(amauryfa): Support adding non-scalars to a detached extension dict.
115 // This probably requires to store the type of the main message. 97 // This probably requires to store the type of the main message.
116 PyErr_SetObject(PyExc_KeyError, key); 98 PyErr_SetObject(PyExc_KeyError, key);
117 return NULL; 99 return NULL;
118 } 100 }
119 101
120 if (descriptor->label() != FieldDescriptor::LABEL_REPEATED && 102 if (descriptor->label() != FieldDescriptor::LABEL_REPEATED &&
121 descriptor->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { 103 descriptor->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
104 // TODO(plabatut): consider building the class on the fly!
122 PyObject* sub_message = cmessage::InternalGetSubMessage( 105 PyObject* sub_message = cmessage::InternalGetSubMessage(
123 self->parent, descriptor); 106 self->parent, descriptor);
124 if (sub_message == NULL) { 107 if (sub_message == NULL) {
125 return NULL; 108 return NULL;
126 } 109 }
127 PyDict_SetItem(self->values, key, sub_message); 110 PyDict_SetItem(self->values, key, sub_message);
128 return sub_message; 111 return sub_message;
129 } 112 }
130 113
131 if (descriptor->label() == FieldDescriptor::LABEL_REPEATED) { 114 if (descriptor->label() == FieldDescriptor::LABEL_REPEATED) {
132 if (descriptor->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { 115 if (descriptor->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
133 CMessageClass* message_class = cdescriptor_pool::GetMessageClass( 116 // On the fly message class creation is needed to support the following
134 cmessage::GetDescriptorPoolForMessage(self->parent), 117 // situation:
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),
135 descriptor->message_type()); 128 descriptor->message_type());
136 if (message_class == NULL) { 129 if (message_class == NULL) {
137 return NULL; 130 return NULL;
138 } 131 }
139 PyObject* py_container = repeated_composite_container::NewContainer( 132 PyObject* py_container = repeated_composite_container::NewContainer(
140 self->parent, descriptor, message_class); 133 self->parent, descriptor, message_class);
141 if (py_container == NULL) { 134 if (py_container == NULL) {
142 return NULL; 135 return NULL;
143 } 136 }
144 PyDict_SetItem(self->values, key, py_container); 137 PyDict_SetItem(self->values, key, py_container);
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
176 cmessage::AssureWritable(self->parent); 169 cmessage::AssureWritable(self->parent);
177 if (cmessage::InternalSetScalar(self->parent, descriptor, value) < 0) { 170 if (cmessage::InternalSetScalar(self->parent, descriptor, value) < 0) {
178 return -1; 171 return -1;
179 } 172 }
180 } 173 }
181 // TODO(tibell): We shouldn't write scalars to the cache. 174 // TODO(tibell): We shouldn't write scalars to the cache.
182 PyDict_SetItem(self->values, key, value); 175 PyDict_SetItem(self->values, key, value);
183 return 0; 176 return 0;
184 } 177 }
185 178
186 PyObject* ClearExtension(ExtensionDict* self, PyObject* extension) { 179 PyObject* _FindExtensionByName(ExtensionDict* self, PyObject* arg) {
187 const FieldDescriptor* descriptor = 180 char* name;
188 cmessage::GetExtensionDescriptor(extension); 181 Py_ssize_t name_size;
189 if (descriptor == NULL) { 182 if (PyString_AsStringAndSize(arg, &name, &name_size) < 0) {
190 return NULL; 183 return NULL;
191 } 184 }
192 PyObject* value = PyDict_GetItem(self->values, extension); 185
193 if (self->parent) { 186 PyDescriptorPool* pool = cmessage::GetFactoryForMessage(self->parent)->pool;
194 if (value != NULL) { 187 const FieldDescriptor* message_extension =
195 if (ReleaseExtension(self, value, descriptor) < 0) { 188 pool->pool->FindExtensionByName(string(name, name_size));
196 return NULL; 189 if (message_extension == 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;
197 } 200 }
198 } 201 }
199 if (ScopedPyObjectPtr(cmessage::ClearFieldByDescriptor(
200 self->parent, descriptor)) == NULL) {
201 return NULL;
202 }
203 } 202 }
204 if (PyDict_DelItem(self->values, extension) < 0) { 203 if (message_extension == NULL) {
205 PyErr_Clear(); 204 Py_RETURN_NONE;
206 } 205 }
207 Py_RETURN_NONE; 206
207 return PyFieldDescriptor_FromDescriptor(message_extension);
208 } 208 }
209 209
210 PyObject* HasExtension(ExtensionDict* self, PyObject* extension) { 210 PyObject* _FindExtensionByNumber(ExtensionDict* self, PyObject* arg) {
211 const FieldDescriptor* descriptor = 211 int64 number = PyLong_AsLong(arg);
212 cmessage::GetExtensionDescriptor(extension); 212 if (number == -1 && PyErr_Occurred()) {
213 if (descriptor == NULL) {
214 return NULL; 213 return NULL;
215 } 214 }
216 if (self->parent) { 215
217 return cmessage::HasFieldByDescriptor(self->parent, descriptor); 216 PyDescriptorPool* pool = cmessage::GetFactoryForMessage(self->parent)->pool;
218 } else { 217 const FieldDescriptor* message_extension = pool->pool->FindExtensionByNumber(
219 int exists = PyDict_Contains(self->values, extension); 218 self->parent->message->GetDescriptor(), number);
220 if (exists < 0) { 219 if (message_extension == NULL) {
221 return NULL; 220 Py_RETURN_NONE;
222 }
223 return PyBool_FromLong(exists);
224 } 221 }
225 }
226 222
227 PyObject* _FindExtensionByName(ExtensionDict* self, PyObject* name) { 223 return PyFieldDescriptor_FromDescriptor(message_extension);
228 ScopedPyObjectPtr extensions_by_name(PyObject_GetAttrString(
229 reinterpret_cast<PyObject*>(self->parent), "_extensions_by_name"));
230 if (extensions_by_name == NULL) {
231 return NULL;
232 }
233 PyObject* result = PyDict_GetItem(extensions_by_name.get(), name);
234 if (result == NULL) {
235 Py_RETURN_NONE;
236 } else {
237 Py_INCREF(result);
238 return result;
239 }
240 }
241
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 }
255 } 224 }
256 225
257 ExtensionDict* NewExtensionDict(CMessage *parent) { 226 ExtensionDict* NewExtensionDict(CMessage *parent) {
258 ExtensionDict* self = reinterpret_cast<ExtensionDict*>( 227 ExtensionDict* self = reinterpret_cast<ExtensionDict*>(
259 PyType_GenericAlloc(&ExtensionDict_Type, 0)); 228 PyType_GenericAlloc(&ExtensionDict_Type, 0));
260 if (self == NULL) { 229 if (self == NULL) {
261 return NULL; 230 return NULL;
262 } 231 }
263 232
264 self->parent = parent; // Store a borrowed reference. 233 self->parent = parent; // Store a borrowed reference.
(...skipping 10 matching lines...) Expand all
275 } 244 }
276 245
277 static PyMappingMethods MpMethods = { 246 static PyMappingMethods MpMethods = {
278 (lenfunc)len, /* mp_length */ 247 (lenfunc)len, /* mp_length */
279 (binaryfunc)subscript, /* mp_subscript */ 248 (binaryfunc)subscript, /* mp_subscript */
280 (objobjargproc)ass_subscript,/* mp_ass_subscript */ 249 (objobjargproc)ass_subscript,/* mp_ass_subscript */
281 }; 250 };
282 251
283 #define EDMETHOD(name, args, doc) { #name, (PyCFunction)name, args, doc } 252 #define EDMETHOD(name, args, doc) { #name, (PyCFunction)name, args, doc }
284 static PyMethodDef Methods[] = { 253 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."),
287 EDMETHOD(_FindExtensionByName, METH_O, 254 EDMETHOD(_FindExtensionByName, METH_O,
288 "Finds an extension by name."), 255 "Finds an extension by name."),
289 EDMETHOD(_FindExtensionByNumber, METH_O, 256 EDMETHOD(_FindExtensionByNumber, METH_O,
290 "Finds an extension by field number."), 257 "Finds an extension by field number."),
291 { NULL, NULL } 258 { NULL, NULL }
292 }; 259 };
293 260
294 } // namespace extension_dict 261 } // namespace extension_dict
295 262
296 PyTypeObject ExtensionDict_Type = { 263 PyTypeObject ExtensionDict_Type = {
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
328 0, // tp_dict 295 0, // tp_dict
329 0, // tp_descr_get 296 0, // tp_descr_get
330 0, // tp_descr_set 297 0, // tp_descr_set
331 0, // tp_dictoffset 298 0, // tp_dictoffset
332 0, // tp_init 299 0, // tp_init
333 }; 300 };
334 301
335 } // namespace python 302 } // namespace python
336 } // namespace protobuf 303 } // namespace protobuf
337 } // namespace google 304 } // namespace google
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698