Browse Source

Down-integrate from internal branch.

Feng Xiao 11 years ago
parent
commit
0971bb0d57

+ 6 - 1
python/google/protobuf/internal/message_test.py

@@ -634,7 +634,12 @@ class MessageTest(basetest.TestCase):
     self.assertTrue(m.HasField('oneof_uint32'))
     self.assertEqual('oneof_uint32', m.WhichOneof('oneof_field'))
 
-
+  def testOneofDeserialize(self):
+    m = unittest_pb2.TestAllTypes()
+    m.oneof_uint32 = 11
+    m2 = unittest_pb2.TestAllTypes()
+    m2.ParseFromString(m.SerializeToString())
+    self.assertEqual('oneof_uint32', m2.WhichOneof('oneof_field'))
 
   def testSortEmptyRepeatedCompositeContainer(self):
     """Exercise a scenario that has led to segfaults in the past.

+ 7 - 3
python/google/protobuf/internal/python_message.py

@@ -95,7 +95,7 @@ def InitMessage(descriptor, cls):
   if (descriptor.has_options and
       descriptor.GetOptions().message_set_wire_format):
     cls._decoders_by_tag[decoder.MESSAGE_SET_ITEM_TAG] = (
-        decoder.MessageSetItemDecoder(cls._extensions_by_number))
+        decoder.MessageSetItemDecoder(cls._extensions_by_number), None)
 
   # Attach stuff to each FieldDescriptor for quick lookup later on.
   for field in descriptor.fields:
@@ -222,7 +222,9 @@ def _AttachFieldHelpers(cls, field_descriptor):
     cls._decoders_by_tag[tag_bytes] = (
         type_checkers.TYPE_TO_DECODER[field_descriptor.type](
             field_descriptor.number, is_repeated, is_packed,
-            field_descriptor, field_descriptor._default_constructor))
+            field_descriptor, field_descriptor._default_constructor),
+        field_descriptor if field_descriptor.containing_oneof is not None
+        else None)
 
   AddDecoder(type_checkers.FIELD_TYPE_TO_WIRE_TYPE[field_descriptor.type],
              False)
@@ -858,7 +860,7 @@ def _AddMergeFromStringMethod(message_descriptor, cls):
     unknown_field_list = self._unknown_fields
     while pos != end:
       (tag_bytes, new_pos) = local_ReadTag(buffer, pos)
-      field_decoder = decoders_by_tag.get(tag_bytes)
+      field_decoder, field_desc = decoders_by_tag.get(tag_bytes, (None, None))
       if field_decoder is None:
         value_start_pos = new_pos
         new_pos = local_SkipField(buffer, new_pos, end, tag_bytes)
@@ -870,6 +872,8 @@ def _AddMergeFromStringMethod(message_descriptor, cls):
         pos = new_pos
       else:
         pos = field_decoder(buffer, new_pos, end, self, field_dict)
+        if field_desc:
+          self._UpdateOneofState(field_desc)
     return pos
   cls._InternalParse = InternalParse
 

+ 7 - 0
python/google/protobuf/internal/text_format_test.py

@@ -587,6 +587,13 @@ class TextFormatTest(basetest.TestCase):
     test_util.SetAllFields(message)
     self.assertEqual(message, parsed_message)
 
+  def testParseOneof(self):
+    m = unittest_pb2.TestAllTypes()
+    m.oneof_uint32 = 11
+    m2 = unittest_pb2.TestAllTypes()
+    text_format.Parse(text_format.MessageToString(m), m2)
+    self.assertEqual('oneof_uint32', m2.WhichOneof('oneof_field'))
+
 
 class TokenizerTest(basetest.TestCase):
 

+ 2 - 2
python/google/protobuf/internal/unknown_fields_test.py

@@ -62,7 +62,7 @@ class UnknownFieldsTest(basetest.TestCase):
     result_dict = {}
     for tag_bytes, value in self.unknown_fields:
       if tag_bytes == field_tag:
-        decoder = unittest_pb2.TestAllTypes._decoders_by_tag[tag_bytes]
+        decoder = unittest_pb2.TestAllTypes._decoders_by_tag[tag_bytes][0]
         decoder(value, 0, len(value), self.all_fields, result_dict)
     return result_dict[field_descriptor]
 
@@ -204,7 +204,7 @@ class UnknownFieldsTest(basetest.TestCase):
     for tag_bytes, value in self.unknown_fields:
       if tag_bytes == field_tag:
         decoder = missing_enum_values_pb2.TestEnumValues._decoders_by_tag[
-          tag_bytes]
+          tag_bytes][0]
         decoder(value, 0, len(value), self.message, result_dict)
     return result_dict[field_descriptor]