aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile.am2
-rw-r--r--Protobuf.podspec2
-rw-r--r--csharp/src/Google.Protobuf.Test/Google.Protobuf.Test.csproj1
-rw-r--r--csharp/src/Google.Protobuf.Test/WellKnownTypes/AnyTest.cs66
-rw-r--r--csharp/src/Google.Protobuf/Google.Protobuf.csproj1
-rw-r--r--csharp/src/Google.Protobuf/Reflection/DescriptorPool.cs2
-rw-r--r--csharp/src/Google.Protobuf/WellKnownTypes/AnyPartial.cs79
-rwxr-xr-xgenerate_descriptor_proto.sh5
-rw-r--r--python/google/protobuf/pyext/message.cc16
-rw-r--r--python/google/protobuf/pyext/message_map_container.cc104
-rw-r--r--python/google/protobuf/pyext/message_map_container.h7
-rw-r--r--python/google/protobuf/pyext/scalar_map_container.cc103
-rw-r--r--python/google/protobuf/pyext/scalar_map_container.h7
-rw-r--r--python/tox.ini3
-rw-r--r--src/google/protobuf/compiler/cpp/cpp_file.cc7
-rw-r--r--src/google/protobuf/map_type_handler.h24
-rw-r--r--src/google/protobuf/message.cc8
-rw-r--r--src/google/protobuf/metadata.h2
-rwxr-xr-xsrc/google/protobuf/stubs/hash.h8
-rw-r--r--src/google/protobuf/testing/googletest.cc7
-rwxr-xr-xtravis.sh12
21 files changed, 362 insertions, 104 deletions
diff --git a/Makefile.am b/Makefile.am
index 82ce190d..8b361780 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -95,6 +95,7 @@ csharp_EXTRA_DIST= \
csharp/src/Google.Protobuf.Test/TestProtos/UnittestIssues.cs \
csharp/src/Google.Protobuf.Test/TestProtos/UnittestProto3.cs \
csharp/src/Google.Protobuf.Test/TestProtos/UnittestWellKnownTypes.cs \
+ csharp/src/Google.Protobuf.Test/WellKnownTypes/AnyTest.cs \
csharp/src/Google.Protobuf.Test/WellKnownTypes/DurationTest.cs \
csharp/src/Google.Protobuf.Test/WellKnownTypes/TimestampTest.cs \
csharp/src/Google.Protobuf.Test/WellKnownTypes/WrappersTest.cs \
@@ -149,6 +150,7 @@ csharp_EXTRA_DIST= \
csharp/src/Google.Protobuf/Reflection/ServiceDescriptor.cs \
csharp/src/Google.Protobuf/Reflection/SingleFieldAccessor.cs \
csharp/src/Google.Protobuf/WellKnownTypes/Any.cs \
+ csharp/src/Google.Protobuf/WellKnownTypes/AnyPartial.cs \
csharp/src/Google.Protobuf/WellKnownTypes/Api.cs \
csharp/src/Google.Protobuf/WellKnownTypes/Duration.cs \
csharp/src/Google.Protobuf/WellKnownTypes/DurationPartial.cs \
diff --git a/Protobuf.podspec b/Protobuf.podspec
index 5cfc02b4..698583b9 100644
--- a/Protobuf.podspec
+++ b/Protobuf.podspec
@@ -21,7 +21,7 @@ Pod::Spec.new do |s|
'objectivec/google/protobuf/SourceContext.pbobjc.{h,m}',
'objectivec/google/protobuf/Struct.pbobjc.{h,m}',
'objectivec/google/protobuf/Timestamp.pbobjc.h',
- 'objectivec/google/protobuf/Type.pbobjc.{h,m}'
+ 'objectivec/google/protobuf/Type.pbobjc.{h,m}',
'objectivec/google/protobuf/Wrappers.pbobjc.{h,m}'
# Timestamp.pbobjc.m and Duration.pbobjc.m are #imported by GPBWellKnownTypes.m. So we can't
# compile them (duplicate symbols), but we need them available for the importing:
diff --git a/csharp/src/Google.Protobuf.Test/Google.Protobuf.Test.csproj b/csharp/src/Google.Protobuf.Test/Google.Protobuf.Test.csproj
index d9593828..33be5dae 100644
--- a/csharp/src/Google.Protobuf.Test/Google.Protobuf.Test.csproj
+++ b/csharp/src/Google.Protobuf.Test/Google.Protobuf.Test.csproj
@@ -109,6 +109,7 @@
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="TestCornerCases.cs" />
<Compile Include="TestProtos\UnittestWellKnownTypes.cs" />
+ <Compile Include="WellKnownTypes\AnyTest.cs" />
<Compile Include="WellKnownTypes\DurationTest.cs" />
<Compile Include="WellKnownTypes\TimestampTest.cs" />
<Compile Include="WellKnownTypes\WrappersTest.cs" />
diff --git a/csharp/src/Google.Protobuf.Test/WellKnownTypes/AnyTest.cs b/csharp/src/Google.Protobuf.Test/WellKnownTypes/AnyTest.cs
new file mode 100644
index 00000000..0a2b8b32
--- /dev/null
+++ b/csharp/src/Google.Protobuf.Test/WellKnownTypes/AnyTest.cs
@@ -0,0 +1,66 @@
+#region Copyright notice and license
+// Protocol Buffers - Google's data interchange format
+// Copyright 2015 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#endregion
+
+using Google.Protobuf.TestProtos;
+using NUnit.Framework;
+
+namespace Google.Protobuf.WellKnownTypes
+{
+ public class AnyTest
+ {
+ [Test]
+ public void Pack()
+ {
+ var message = SampleMessages.CreateFullTestAllTypes();
+ var any = Any.Pack(message);
+ Assert.AreEqual("type.googleapis.com/protobuf_unittest.TestAllTypes", any.TypeUrl);
+ Assert.AreEqual(message.CalculateSize(), any.Value.Length);
+ }
+
+ [Test]
+ public void Unpack_WrongType()
+ {
+ var message = SampleMessages.CreateFullTestAllTypes();
+ var any = Any.Pack(message);
+ Assert.Throws<InvalidProtocolBufferException>(() => any.Unpack<TestOneof>());
+ }
+
+ [Test]
+ public void Unpack_Success()
+ {
+ var message = SampleMessages.CreateFullTestAllTypes();
+ var any = Any.Pack(message);
+ var unpacked = any.Unpack<TestAllTypes>();
+ Assert.AreEqual(message, unpacked);
+ }
+ }
+}
diff --git a/csharp/src/Google.Protobuf/Google.Protobuf.csproj b/csharp/src/Google.Protobuf/Google.Protobuf.csproj
index a17bf81c..8c680d46 100644
--- a/csharp/src/Google.Protobuf/Google.Protobuf.csproj
+++ b/csharp/src/Google.Protobuf/Google.Protobuf.csproj
@@ -118,6 +118,7 @@
<Compile Include="Reflection\SingleFieldAccessor.cs" />
<Compile Include="Preconditions.cs" />
<Compile Include="WellKnownTypes\Any.cs" />
+ <Compile Include="WellKnownTypes\AnyPartial.cs" />
<Compile Include="WellKnownTypes\Api.cs" />
<Compile Include="WellKnownTypes\Duration.cs" />
<Compile Include="WellKnownTypes\DurationPartial.cs" />
diff --git a/csharp/src/Google.Protobuf/Reflection/DescriptorPool.cs b/csharp/src/Google.Protobuf/Reflection/DescriptorPool.cs
index 759955e6..99ca4bf3 100644
--- a/csharp/src/Google.Protobuf/Reflection/DescriptorPool.cs
+++ b/csharp/src/Google.Protobuf/Reflection/DescriptorPool.cs
@@ -96,6 +96,8 @@ namespace Google.Protobuf.Reflection
return descriptor;
}
+ // dependencies contains direct dependencies and any *public* dependencies
+ // of those dependencies (transitively)... so we don't need to recurse here.
foreach (FileDescriptor dependency in dependencies)
{
dependency.DescriptorPool.descriptorsByName.TryGetValue(fullName, out result);
diff --git a/csharp/src/Google.Protobuf/WellKnownTypes/AnyPartial.cs b/csharp/src/Google.Protobuf/WellKnownTypes/AnyPartial.cs
new file mode 100644
index 00000000..082f7432
--- /dev/null
+++ b/csharp/src/Google.Protobuf/WellKnownTypes/AnyPartial.cs
@@ -0,0 +1,79 @@
+#region Copyright notice and license
+// Protocol Buffers - Google's data interchange format
+// Copyright 2015 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#endregion
+
+using Google.Protobuf.Reflection;
+
+namespace Google.Protobuf.WellKnownTypes
+{
+ public partial class Any
+ {
+ // This could be moved to MessageDescriptor if we wanted to, but keeping it here means
+ // all the Any-specific code is in the same place.
+ private static string GetTypeUrl(MessageDescriptor descriptor)
+ {
+ return "type.googleapis.com/" + descriptor.FullName;
+ }
+
+ /// <summary>
+ /// Unpacks the content of this Any message into the target message type,
+ /// which must match the type URL within this Any message.
+ /// </summary>
+ /// <typeparam name="T">The type of message to unpack the content into.</typeparam>
+ /// <returns>The unpacked message.</returns>
+ /// <exception cref="InvalidProtocolBufferException">The target message type doesn't match the type URL in this message</exception>
+ public T Unpack<T>() where T : IMessage, new()
+ {
+ // Note: this doesn't perform as well is it might. We could take a MessageParser<T> in an alternative overload,
+ // which would be expected to perform slightly better... although the difference is likely to be negligible.
+ T target = new T();
+ string targetTypeUrl = GetTypeUrl(target.Descriptor);
+ if (TypeUrl != targetTypeUrl)
+ {
+ throw new InvalidProtocolBufferException(string.Format("Type url for {0} is {1}; Any message's type url is {2}",
+ target.Descriptor.Name, targetTypeUrl, TypeUrl));
+ }
+ target.MergeFrom(Value);
+ return target;
+ }
+
+ /// <summary>
+ /// Packs the specified message into an Any message.
+ /// </summary>
+ /// <param name="message">The message to pack.</param>
+ /// <returns>An Any message with the content and type URL of <paramref name="message"/>.</returns>
+ public static Any Pack(IMessage message)
+ {
+ Preconditions.CheckNotNull(message, "message");
+ return new Any { TypeUrl = GetTypeUrl(message.Descriptor), Value = message.ToByteString() };
+ }
+ }
+}
diff --git a/generate_descriptor_proto.sh b/generate_descriptor_proto.sh
index b6e6e07b..cd906896 100755
--- a/generate_descriptor_proto.sh
+++ b/generate_descriptor_proto.sh
@@ -92,3 +92,8 @@ do
PROCESS_ROUND=$((PROCESS_ROUND + 1))
done
cd ..
+
+if test -x objectivec/generate_descriptors_proto.sh; then
+ echo "Generating messages for objc."
+ objectivec/generate_descriptors_proto.sh $@
+fi
diff --git a/python/google/protobuf/pyext/message.cc b/python/google/protobuf/pyext/message.cc
index 62c7c478..04544cad 100644
--- a/python/google/protobuf/pyext/message.cc
+++ b/python/google/protobuf/pyext/message.cc
@@ -2863,6 +2863,14 @@ bool InitProto2MessageModule(PyObject *m) {
}
Py_INCREF(mutable_mapping);
+#if PY_MAJOR_VERSION >= 3
+ PyObject* bases = PyTuple_New(1);
+ PyTuple_SET_ITEM(bases, 0, mutable_mapping.get());
+
+ ScalarMapContainer_Type =
+ PyType_FromSpecWithBases(&ScalarMapContainer_Type_spec, bases);
+ PyModule_AddObject(m, "ScalarMapContainer", ScalarMapContainer_Type);
+#else
ScalarMapContainer_Type.tp_base =
reinterpret_cast<PyTypeObject*>(mutable_mapping.get());
@@ -2872,6 +2880,7 @@ bool InitProto2MessageModule(PyObject *m) {
PyModule_AddObject(m, "ScalarMapContainer",
reinterpret_cast<PyObject*>(&ScalarMapContainer_Type));
+#endif
if (PyType_Ready(&ScalarMapIterator_Type) < 0) {
return false;
@@ -2880,6 +2889,12 @@ bool InitProto2MessageModule(PyObject *m) {
PyModule_AddObject(m, "ScalarMapIterator",
reinterpret_cast<PyObject*>(&ScalarMapIterator_Type));
+
+#if PY_MAJOR_VERSION >= 3
+ MessageMapContainer_Type =
+ PyType_FromSpecWithBases(&MessageMapContainer_Type_spec, bases);
+ PyModule_AddObject(m, "MessageMapContainer", MessageMapContainer_Type);
+#else
Py_INCREF(mutable_mapping);
MessageMapContainer_Type.tp_base =
reinterpret_cast<PyTypeObject*>(mutable_mapping.get());
@@ -2890,6 +2905,7 @@ bool InitProto2MessageModule(PyObject *m) {
PyModule_AddObject(m, "MessageMapContainer",
reinterpret_cast<PyObject*>(&MessageMapContainer_Type));
+#endif
if (PyType_Ready(&MessageMapIterator_Type) < 0) {
return false;
diff --git a/python/google/protobuf/pyext/message_map_container.cc b/python/google/protobuf/pyext/message_map_container.cc
index a4a7fbfe..f54d2015 100644
--- a/python/google/protobuf/pyext/message_map_container.cc
+++ b/python/google/protobuf/pyext/message_map_container.cc
@@ -84,7 +84,12 @@ PyObject* NewContainer(CMessage* parent,
return NULL;
}
+#if PY_MAJOR_VERSION >= 3
+ PyObject* obj = PyType_GenericAlloc(
+ reinterpret_cast<PyTypeObject *>(MessageMapContainer_Type), 0);
+#else
PyObject* obj = PyType_GenericAlloc(&MessageMapContainer_Type, 0);
+#endif
if (obj == NULL) {
return PyErr_Format(PyExc_RuntimeError,
"Could not allocate new container.");
@@ -458,44 +463,67 @@ PyObject* IterNext(PyObject* _self) {
} // namespace message_map_iterator
-PyTypeObject MessageMapContainer_Type = {
- PyVarObject_HEAD_INIT(&PyType_Type, 0)
- FULL_MODULE_NAME ".MessageMapContainer", // tp_name
- sizeof(MessageMapContainer), // tp_basicsize
- 0, // tp_itemsize
- message_map_container::Dealloc, // tp_dealloc
- 0, // tp_print
- 0, // tp_getattr
- 0, // tp_setattr
- 0, // tp_compare
- 0, // tp_repr
- 0, // tp_as_number
- 0, // tp_as_sequence
- &message_map_container::MpMethods, // tp_as_mapping
- 0, // tp_hash
- 0, // tp_call
- 0, // tp_str
- 0, // tp_getattro
- 0, // tp_setattro
- 0, // tp_as_buffer
- Py_TPFLAGS_DEFAULT, // tp_flags
- "A map container for message", // tp_doc
- 0, // tp_traverse
- 0, // tp_clear
- 0, // tp_richcompare
- 0, // tp_weaklistoffset
- message_map_container::GetIterator, // tp_iter
- 0, // tp_iternext
- message_map_container::Methods, // tp_methods
- 0, // tp_members
- 0, // tp_getset
- 0, // tp_base
- 0, // tp_dict
- 0, // tp_descr_get
- 0, // tp_descr_set
- 0, // tp_dictoffset
- 0, // tp_init
-};
+#if PY_MAJOR_VERSION >= 3
+ static PyType_Slot MessageMapContainer_Type_slots[] = {
+ {Py_tp_dealloc, (void *)message_map_container::Dealloc},
+ {Py_mp_length, (void *)message_map_container::Length},
+ {Py_mp_subscript, (void *)message_map_container::GetItem},
+ {Py_mp_ass_subscript, (void *)message_map_container::SetItem},
+ {Py_tp_methods, (void *)message_map_container::Methods},
+ {Py_tp_iter, (void *)message_map_container::GetIterator},
+ {0, 0}
+ };
+
+ PyType_Spec MessageMapContainer_Type_spec = {
+ FULL_MODULE_NAME ".MessageMapContainer",
+ sizeof(MessageMapContainer),
+ 0,
+ Py_TPFLAGS_DEFAULT,
+ MessageMapContainer_Type_slots
+ };
+
+ PyObject *MessageMapContainer_Type;
+
+#else
+ PyTypeObject MessageMapContainer_Type = {
+ PyVarObject_HEAD_INIT(&PyType_Type, 0)
+ FULL_MODULE_NAME ".MessageMapContainer", // tp_name
+ sizeof(MessageMapContainer), // tp_basicsize
+ 0, // tp_itemsize
+ message_map_container::Dealloc, // tp_dealloc
+ 0, // tp_print
+ 0, // tp_getattr
+ 0, // tp_setattr
+ 0, // tp_compare
+ 0, // tp_repr
+ 0, // tp_as_number
+ 0, // tp_as_sequence
+ &message_map_container::MpMethods, // tp_as_mapping
+ 0, // tp_hash
+ 0, // tp_call
+ 0, // tp_str
+ 0, // tp_getattro
+ 0, // tp_setattro
+ 0, // tp_as_buffer
+ Py_TPFLAGS_DEFAULT, // tp_flags
+ "A map container for message", // tp_doc
+ 0, // tp_traverse
+ 0, // tp_clear
+ 0, // tp_richcompare
+ 0, // tp_weaklistoffset
+ message_map_container::GetIterator, // tp_iter
+ 0, // tp_iternext
+ message_map_container::Methods, // tp_methods
+ 0, // tp_members
+ 0, // tp_getset
+ 0, // tp_base
+ 0, // tp_dict
+ 0, // tp_descr_get
+ 0, // tp_descr_set
+ 0, // tp_dictoffset
+ 0, // tp_init
+ };
+#endif
PyTypeObject MessageMapIterator_Type = {
PyVarObject_HEAD_INIT(&PyType_Type, 0)
diff --git a/python/google/protobuf/pyext/message_map_container.h b/python/google/protobuf/pyext/message_map_container.h
index 4ca0aecc..8286ba8a 100644
--- a/python/google/protobuf/pyext/message_map_container.h
+++ b/python/google/protobuf/pyext/message_map_container.h
@@ -89,7 +89,12 @@ struct MessageMapContainer {
uint64 version;
};
-extern PyTypeObject MessageMapContainer_Type;
+#if PY_MAJOR_VERSION >= 3
+ extern PyObject *MessageMapContainer_Type;
+ extern PyType_Spec MessageMapContainer_Type_spec;
+#else
+ extern PyTypeObject MessageMapContainer_Type;
+#endif
extern PyTypeObject MessageMapIterator_Type;
namespace message_map_container {
diff --git a/python/google/protobuf/pyext/scalar_map_container.cc b/python/google/protobuf/pyext/scalar_map_container.cc
index 80d29425..a355edb2 100644
--- a/python/google/protobuf/pyext/scalar_map_container.cc
+++ b/python/google/protobuf/pyext/scalar_map_container.cc
@@ -83,7 +83,12 @@ PyObject *NewContainer(
return NULL;
}
+#if PY_MAJOR_VERSION >= 3
+ ScopedPyObjectPtr obj(PyType_GenericAlloc(
+ reinterpret_cast<PyTypeObject *>(ScalarMapContainer_Type), 0));
+#else
ScopedPyObjectPtr obj(PyType_GenericAlloc(&ScalarMapContainer_Type, 0));
+#endif
if (obj.get() == NULL) {
return PyErr_Format(PyExc_RuntimeError,
"Could not allocate new container.");
@@ -432,44 +437,66 @@ PyObject* IterNext(PyObject* _self) {
} // namespace scalar_map_iterator
-PyTypeObject ScalarMapContainer_Type = {
- PyVarObject_HEAD_INIT(&PyType_Type, 0)
- FULL_MODULE_NAME ".ScalarMapContainer", // tp_name
- sizeof(ScalarMapContainer), // tp_basicsize
- 0, // tp_itemsize
- scalar_map_container::Dealloc, // tp_dealloc
- 0, // tp_print
- 0, // tp_getattr
- 0, // tp_setattr
- 0, // tp_compare
- 0, // tp_repr
- 0, // tp_as_number
- 0, // tp_as_sequence
- &scalar_map_container::MpMethods, // tp_as_mapping
- 0, // tp_hash
- 0, // tp_call
- 0, // tp_str
- 0, // tp_getattro
- 0, // tp_setattro
- 0, // tp_as_buffer
- Py_TPFLAGS_DEFAULT, // tp_flags
- "A scalar map container", // tp_doc
- 0, // tp_traverse
- 0, // tp_clear
- 0, // tp_richcompare
- 0, // tp_weaklistoffset
- scalar_map_container::GetIterator, // tp_iter
- 0, // tp_iternext
- scalar_map_container::Methods, // tp_methods
- 0, // tp_members
- 0, // tp_getset
- 0, // tp_base
- 0, // tp_dict
- 0, // tp_descr_get
- 0, // tp_descr_set
- 0, // tp_dictoffset
- 0, // tp_init
-};
+
+#if PY_MAJOR_VERSION >= 3
+ static PyType_Slot ScalarMapContainer_Type_slots[] = {
+ {Py_tp_dealloc, (void *)scalar_map_container::Dealloc},
+ {Py_mp_length, (void *)scalar_map_container::Length},
+ {Py_mp_subscript, (void *)scalar_map_container::GetItem},
+ {Py_mp_ass_subscript, (void *)scalar_map_container::SetItem},
+ {Py_tp_methods, (void *)scalar_map_container::Methods},
+ {Py_tp_iter, (void *)scalar_map_container::GetIterator},
+ {0, 0},
+ };
+
+ PyType_Spec ScalarMapContainer_Type_spec = {
+ FULL_MODULE_NAME ".ScalarMapContainer",
+ sizeof(ScalarMapContainer),
+ 0,
+ Py_TPFLAGS_DEFAULT,
+ ScalarMapContainer_Type_slots
+ };
+ PyObject *ScalarMapContainer_Type;
+#else
+ PyTypeObject ScalarMapContainer_Type = {
+ PyVarObject_HEAD_INIT(&PyType_Type, 0)
+ FULL_MODULE_NAME ".ScalarMapContainer", // tp_name
+ sizeof(ScalarMapContainer), // tp_basicsize
+ 0, // tp_itemsize
+ scalar_map_container::Dealloc, // tp_dealloc
+ 0, // tp_print
+ 0, // tp_getattr
+ 0, // tp_setattr
+ 0, // tp_compare
+ 0, // tp_repr
+ 0, // tp_as_number
+ 0, // tp_as_sequence
+ &scalar_map_container::MpMethods, // tp_as_mapping
+ 0, // tp_hash
+ 0, // tp_call
+ 0, // tp_str
+ 0, // tp_getattro
+ 0, // tp_setattro
+ 0, // tp_as_buffer
+ Py_TPFLAGS_DEFAULT, // tp_flags
+ "A scalar map container", // tp_doc
+ 0, // tp_traverse
+ 0, // tp_clear
+ 0, // tp_richcompare
+ 0, // tp_weaklistoffset
+ scalar_map_container::GetIterator, // tp_iter
+ 0, // tp_iternext
+ scalar_map_container::Methods, // tp_methods
+ 0, // tp_members
+ 0, // tp_getset
+ 0, // tp_base
+ 0, // tp_dict
+ 0, // tp_descr_get
+ 0, // tp_descr_set
+ 0, // tp_dictoffset
+ 0, // tp_init
+ };
+#endif
PyTypeObject ScalarMapIterator_Type = {
PyVarObject_HEAD_INIT(&PyType_Type, 0)
diff --git a/python/google/protobuf/pyext/scalar_map_container.h b/python/google/protobuf/pyext/scalar_map_container.h
index 254e6e98..aded8d49 100644
--- a/python/google/protobuf/pyext/scalar_map_container.h
+++ b/python/google/protobuf/pyext/scalar_map_container.h
@@ -83,7 +83,12 @@ struct ScalarMapContainer {
uint64 version;
};
-extern PyTypeObject ScalarMapContainer_Type;
+#if PY_MAJOR_VERSION >= 3
+ extern PyObject *ScalarMapContainer_Type;
+ extern PyType_Spec ScalarMapContainer_Type_spec;
+#else
+ extern PyTypeObject ScalarMapContainer_Type;
+#endif
extern PyTypeObject ScalarMapIterator_Type;
namespace scalar_map_container {
diff --git a/python/tox.ini b/python/tox.ini
index d0100758..a6352ef4 100644
--- a/python/tox.ini
+++ b/python/tox.ini
@@ -2,8 +2,7 @@
envlist =
# cpp implementation on py34 is currently broken due to
# changes introduced by http://bugs.python.org/issue22079.
- #py{26,27,33,34}-{cpp,python}
- py{26,27,33}-{cpp,python}, py34-{python}
+ py{26,27,33,34}-{cpp,python}
[testenv]
usedevelop=true
diff --git a/src/google/protobuf/compiler/cpp/cpp_file.cc b/src/google/protobuf/compiler/cpp/cpp_file.cc
index 5dae4cdd..8e8bd8b7 100644
--- a/src/google/protobuf/compiler/cpp/cpp_file.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_file.cc
@@ -598,8 +598,13 @@ void FileGenerator::GenerateBuildDescriptors(io::Printer* printer) {
// bytes in length". Declare a static array of characters rather than use a
// string literal.
if (breakdown_large_file && file_data.size() > 65535) {
+ // This has to be explicitly marked as a signed char because the generated
+ // code puts negative values in the array, and sometimes plain char is
+ // unsigned. That implicit narrowing conversion is not allowed in C++11.
+ // <http://stackoverflow.com/questions/4434140/narrowing-conversions-in-c0x-is-it-just-me-or-does-this-sound-like-a-breakin>
+ // has details on why.
printer->Print(
- "static const char descriptor[] = {\n");
+ "static const signed char descriptor[] = {\n");
printer->Indent();
// Only write 25 bytes per line.
diff --git a/src/google/protobuf/map_type_handler.h b/src/google/protobuf/map_type_handler.h
index 5040e605..f8ad7584 100644
--- a/src/google/protobuf/map_type_handler.h
+++ b/src/google/protobuf/map_type_handler.h
@@ -272,24 +272,24 @@ MapTypeHandler<WireFormatLite::TYPE_MESSAGE, Type>::ByteSize(
return WireFormatLite::MessageSizeNoVirtual(value);
}
-#define BYTE_SIZE(FieldType, DeclaredType) \
+#define GOOGLE_PROTOBUF_BYTE_SIZE(FieldType, DeclaredType) \
template <typename Type> \
inline int MapTypeHandler<WireFormatLite::TYPE_##FieldType, Type>::ByteSize( \
const MapEntryAccessorType& value) { \
return WireFormatLite::DeclaredType##Size(value); \
}
-BYTE_SIZE(STRING, String)
-BYTE_SIZE(BYTES , Bytes)
-BYTE_SIZE(INT64 , Int64)
-BYTE_SIZE(UINT64, UInt64)
-BYTE_SIZE(INT32 , Int32)
-BYTE_SIZE(UINT32, UInt32)
-BYTE_SIZE(SINT64, SInt64)
-BYTE_SIZE(SINT32, SInt32)
-BYTE_SIZE(ENUM , Enum)
-
-#undef BYTE_SIZE
+GOOGLE_PROTOBUF_BYTE_SIZE(STRING, String)
+GOOGLE_PROTOBUF_BYTE_SIZE(BYTES , Bytes)
+GOOGLE_PROTOBUF_BYTE_SIZE(INT64 , Int64)
+GOOGLE_PROTOBUF_BYTE_SIZE(UINT64, UInt64)
+GOOGLE_PROTOBUF_BYTE_SIZE(INT32 , Int32)
+GOOGLE_PROTOBUF_BYTE_SIZE(UINT32, UInt32)
+GOOGLE_PROTOBUF_BYTE_SIZE(SINT64, SInt64)
+GOOGLE_PROTOBUF_BYTE_SIZE(SINT32, SInt32)
+GOOGLE_PROTOBUF_BYTE_SIZE(ENUM , Enum)
+
+#undef GOOGLE_PROTOBUF_BYTE_SIZE
#define FIXED_BYTE_SIZE(FieldType, DeclaredType) \
template <typename Type> \
diff --git a/src/google/protobuf/message.cc b/src/google/protobuf/message.cc
index 2f6416d0..9a586783 100644
--- a/src/google/protobuf/message.cc
+++ b/src/google/protobuf/message.cc
@@ -495,11 +495,19 @@ Message* GenericTypeHandler<Message>::NewFromPrototype(
return prototype->New(arena);
}
template<>
+#if defined(_MSC_VER) && (_MSC_VER >= 1900)
+// Note: force noinline to workaround MSVC 2015 compiler bug, issue #240
+GOOGLE_ATTRIBUTE_NOINLINE
+#endif
google::protobuf::Arena* GenericTypeHandler<Message>::GetArena(
Message* value) {
return value->GetArena();
}
template<>
+#if defined(_MSC_VER) && (_MSC_VER >= 1900)
+// Note: force noinline to workaround MSVC 2015 compiler bug, issue #240
+GOOGLE_ATTRIBUTE_NOINLINE
+#endif
void* GenericTypeHandler<Message>::GetMaybeArenaPointer(
Message* value) {
return value->GetMaybeArenaPointer();
diff --git a/src/google/protobuf/metadata.h b/src/google/protobuf/metadata.h
index fdee150b..219645d3 100644
--- a/src/google/protobuf/metadata.h
+++ b/src/google/protobuf/metadata.h
@@ -56,7 +56,7 @@ namespace internal {
// The tagged pointer uses the LSB to disambiguate cases, and uses bit 0 == 0 to
// indicate an arena pointer and bit 0 == 1 to indicate a UFS+Arena-container
// pointer.
-class LIBPROTOBUF_EXPORT InternalMetadataWithArena {
+class InternalMetadataWithArena {
public:
InternalMetadataWithArena() : ptr_(NULL) {}
explicit InternalMetadataWithArena(Arena* arena)
diff --git a/src/google/protobuf/stubs/hash.h b/src/google/protobuf/stubs/hash.h
index c6f210f0..e7b3771f 100755
--- a/src/google/protobuf/stubs/hash.h
+++ b/src/google/protobuf/stubs/hash.h
@@ -41,10 +41,10 @@
#define GOOGLE_PROTOBUF_HAVE_HASH_MAP 1
#define GOOGLE_PROTOBUF_HAVE_HASH_SET 1
-// Use C++11 unordered_{map|set} if available. Otherwise, libc++ always support
-// unordered_{map|set}
-#if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X) || \
- defined(_LIBCPP_VERSION)
+// Use C++11 unordered_{map|set} if available.
+#if ((_LIBCPP_STD_VER >= 11) || \
+ (((__cplusplus >= 201103L) || defined(__GXX_EXPERIMENTAL_CXX0X)) && \
+ (__GLIBCXX__ > 20090421)))
# define GOOGLE_PROTOBUF_HAS_CXX11_HASH
// For XCode >= 4.6: the compiler is clang with libc++.
diff --git a/src/google/protobuf/testing/googletest.cc b/src/google/protobuf/testing/googletest.cc
index b8bd790b..2b9cddef 100644
--- a/src/google/protobuf/testing/googletest.cc
+++ b/src/google/protobuf/testing/googletest.cc
@@ -94,6 +94,13 @@ string TestSourceDir() {
namespace {
string GetTemporaryDirectoryName() {
+ // Tests run under Bazel "should not" use /tmp. Bazel sets this environment
+ // variable for tests to use instead.
+ char *from_environment = getenv("TEST_TMPDIR");
+ if (from_environment != NULL && from_environment[0] != '\0') {
+ return string(from_environment) + "/protobuf_tmpdir";
+ }
+
// tmpnam() is generally not considered safe but we're only using it for
// testing. We cannot use tmpfile() or mkstemp() since we're creating a
// directory.
diff --git a/travis.sh b/travis.sh
index a5208fe3..b4a908dd 100755
--- a/travis.sh
+++ b/travis.sh
@@ -113,12 +113,14 @@ build_javanano_oracle7() {
internal_install_python_deps() {
sudo pip install tox
- # Only install Python2.6 on Linux.
+ # Only install Python2.6/3.x on Linux.
if [ $(uname -s) == "Linux" ]; then
sudo apt-get install -y python-software-properties # for apt-add-repository
sudo apt-add-repository -y ppa:fkrull/deadsnakes
sudo apt-get update -qq
sudo apt-get install -y python2.6 python2.6-dev
+ sudo apt-get install -y python3.3 python3.3-dev
+ sudo apt-get install -y python3.4 python3.4-dev
fi
}
@@ -127,9 +129,9 @@ build_python() {
internal_build_cpp
internal_install_python_deps
cd python
- # Only test Python 2.6 on Linux
+ # Only test Python 2.6/3.x on Linux
if [ $(uname -s) == "Linux" ]; then
- envlist=py26-python,py27-python
+ envlist=py\{26,27,33,34\}-python
else
envlist=py27-python
fi
@@ -143,9 +145,9 @@ build_python_cpp() {
export LD_LIBRARY_PATH=../src/.libs # for Linux
export DYLD_LIBRARY_PATH=../src/.libs # for OS X
cd python
- # Only test Python 2.6 on Linux
+ # Only test Python 2.6/3.x on Linux
if [ $(uname -s) == "Linux" ]; then
- envlist=py26-cpp,py27-cpp
+ envlist=py\{26,27,33,34\}-cpp
else
envlist=py27-cpp
fi