From bcbaabe53a8d661f5a473d2a157a4278ad8bf579 Mon Sep 17 00:00:00 2001 From: Paul Yang Date: Wed, 1 Mar 2017 10:39:48 -0800 Subject: Add mergeFrom method on Message (#2766) This method merges the contents of the specified message into the current message. Singular fields that are set in the specified message overwrite the corresponding fields in the current message. Repeated fields are appended. Map fields key-value pairs are overritten. Singular/Oneof sub-messages are recursively merged. All overritten sub-messages are deep-copied. --- php/src/Google/Protobuf/Internal/Message.php | 68 ++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) (limited to 'php/src/Google/Protobuf') diff --git a/php/src/Google/Protobuf/Internal/Message.php b/php/src/Google/Protobuf/Internal/Message.php index 9e162a22..17ef8536 100644 --- a/php/src/Google/Protobuf/Internal/Message.php +++ b/php/src/Google/Protobuf/Internal/Message.php @@ -490,6 +490,74 @@ class Message } } + /** + * Merges the contents of the specified message into current message. + * + * This method merges the contents of the specified message into the + * current message. Singular fields that are set in the specified message + * overwrite the corresponding fields in the current message. Repeated + * fields are appended. Map fields key-value pairs are overritten. + * Singular/Oneof sub-messages are recursively merged. All overritten + * sub-messages are deep-copied. + * + * @param object $msg Protobuf message to be merged from. + * @return null. + */ + public function mergeFrom($msg) + { + if (get_class($this) !== get_class($msg)) { + user_error("Cannot merge messages with different class."); + return; + } + + foreach ($this->desc->getField() as $field) { + $setter = $field->getSetter(); + $getter = $field->getGetter(); + if ($field->isMap()) { + if (count($msg->$getter()) != 0) { + $value_field = $field->getMessageType()->getFieldByNumber(2); + foreach ($msg->$getter() as $key => $value) { + if ($value_field->getType() == GPBType::MESSAGE) { + $klass = $value_field->getMessageType()->getClass(); + $copy = new $klass; + $copy->mergeFrom($value); + $this->$getter()[$key] = $copy; + } else { + $this->$getter()[$key] = $value; + } + } + } + } else if ($field->getLabel() === GPBLabel::REPEATED) { + if (count($msg->$getter()) != 0) { + foreach ($msg->$getter() as $tmp) { + if ($field->getType() == GPBType::MESSAGE) { + $klass = $field->getMessageType()->getClass(); + $copy = new $klass; + $copy->mergeFrom($tmp); + $this->$getter()[] = $copy; + } else { + $this->$getter()[] = $tmp; + } + } + } + } else if ($field->getLabel() === GPBLabel::OPTIONAL) { + if($msg->$getter() !== $this->defaultValue($field)) { + $tmp = $msg->$getter(); + if ($field->getType() == GPBType::MESSAGE) { + if (is_null($this->$getter())) { + $klass = $field->getMessageType()->getClass(); + $new_msg = new $klass; + $this->$setter($new_msg); + } + $this->$getter()->mergeFrom($tmp); + } else { + $this->$setter($tmp); + } + } + } + } + } + /** * Parses a protocol buffer contained in a string. * -- cgit v1.2.3