Oneof field should be serialized even it's equal to default. (#3153)

pull/3255/head
Paul Yang 8 years ago committed by Bo Yang
parent dba8928ff5
commit c344fe8caa
  1. 4
      php/ext/google/protobuf/encode_decode.c
  2. 7
      php/src/Google/Protobuf/Internal/Message.php
  3. 7
      php/tests/encode_decode_test.php

@ -1167,6 +1167,7 @@ static void putrawmsg(MessageHeader* msg, const Descriptor* desc,
upb_msg_field_next(&i)) { upb_msg_field_next(&i)) {
upb_fielddef* f = upb_msg_iter_field(&i); upb_fielddef* f = upb_msg_iter_field(&i);
uint32_t offset = desc->layout->fields[upb_fielddef_index(f)].offset; uint32_t offset = desc->layout->fields[upb_fielddef_index(f)].offset;
bool containing_oneof = false;
if (upb_fielddef_containingoneof(f)) { if (upb_fielddef_containingoneof(f)) {
uint32_t oneof_case_offset = uint32_t oneof_case_offset =
@ -1179,6 +1180,7 @@ static void putrawmsg(MessageHeader* msg, const Descriptor* desc,
} }
// Otherwise, fall through to the appropriate singular-field handler // Otherwise, fall through to the appropriate singular-field handler
// below. // below.
containing_oneof = true;
} }
if (is_map_field(f)) { if (is_map_field(f)) {
@ -1209,7 +1211,7 @@ static void putrawmsg(MessageHeader* msg, const Descriptor* desc,
#define T(upbtypeconst, upbtype, ctype, default_value) \ #define T(upbtypeconst, upbtype, ctype, default_value) \
case upbtypeconst: { \ case upbtypeconst: { \
ctype value = DEREF(message_data(msg), offset, ctype); \ ctype value = DEREF(message_data(msg), offset, ctype); \
if (value != default_value) { \ if (containing_oneof || value != default_value) { \
upb_sink_put##upbtype(sink, sel, value); \ upb_sink_put##upbtype(sink, sel, value); \
} \ } \
} break; } break;

@ -739,6 +739,13 @@ class Message
*/ */
private function existField($field) private function existField($field)
{ {
$oneof_index = $field->getOneofIndex();
if ($oneof_index !== -1) {
$oneof = $this->desc->getOneofDecl()[$oneof_index];
$oneof_name = $oneof->getName();
return $this->$oneof_name->getNumber() === $field->getNumber();
}
$getter = $field->getGetter(); $getter = $field->getGetter();
$value = $this->$getter(); $value = $this->$getter();
return $value !== $this->defaultValue($field); return $value !== $this->defaultValue($field);

@ -88,6 +88,13 @@ class EncodeDecodeTest extends TestBase
$n = new TestMessage(); $n = new TestMessage();
$n->mergeFromString($data); $n->mergeFromString($data);
$this->assertSame(1, $n->getOneofMessage()->getA()); $this->assertSame(1, $n->getOneofMessage()->getA());
// Encode default value
$m->setOneofEnum(TestEnum::ZERO);
$data = $m->serializeToString();
$n = new TestMessage();
$n->mergeFromString($data);
$this->assertSame("oneof_enum", $n->getMyOneof());
} }
public function testPackedEncode() public function testPackedEncode()

Loading…
Cancel
Save