xref: /aosp_15_r20/external/protobuf/php/src/Google/Protobuf/Internal/AnyBase.php (revision 1b3f573f81763fcece89efc2b6a5209149e44ab8)
1<?php
2
3namespace Google\Protobuf\Internal;
4
5/**
6 * Base class for Google\Protobuf\Any, this contains hand-written convenience
7 * methods like pack() and unpack().
8 */
9class AnyBase extends \Google\Protobuf\Internal\Message
10{
11    const TYPE_URL_PREFIX = 'type.googleapis.com/';
12
13    /**
14     * This method will try to resolve the type_url in Any message to get the
15     * targeted message type. If failed, an error will be thrown. Otherwise,
16     * the method will create a message of the targeted type and fill it with
17     * the decoded value in Any.
18     * @return Message unpacked message
19     * @throws \Exception Type url needs to be type.googleapis.com/fully-qualified.
20     * @throws \Exception Class hasn't been added to descriptor pool.
21     * @throws \Exception cannot decode data in value field.
22     */
23    public function unpack()
24    {
25        // Get fully qualified name from type url.
26        $url_prifix_len = strlen(GPBUtil::TYPE_URL_PREFIX);
27        if (substr($this->type_url, 0, $url_prifix_len) !=
28                GPBUtil::TYPE_URL_PREFIX) {
29            throw new \Exception(
30                "Type url needs to be type.googleapis.com/fully-qulified");
31        }
32        $fully_qualifed_name =
33            substr($this->type_url, $url_prifix_len);
34
35        // Create message according to fully qualified name.
36        $pool = \Google\Protobuf\Internal\DescriptorPool::getGeneratedPool();
37        $desc = $pool->getDescriptorByProtoName($fully_qualifed_name);
38        if (is_null($desc)) {
39            throw new \Exception("Class ".$fully_qualifed_name
40                                     ." hasn't been added to descriptor pool");
41        }
42        $klass = $desc->getClass();
43        $msg = new $klass();
44
45        // Merge data into message.
46        $msg->mergeFromString($this->value);
47        return $msg;
48    }
49
50    /**
51     * The type_url will be created according to the given message’s type and
52     * the value is encoded data from the given message..
53     * @param message: A proto message.
54     */
55    public function pack($msg)
56    {
57        if (!$msg instanceof Message) {
58            trigger_error("Given parameter is not a message instance.",
59                          E_USER_ERROR);
60            return;
61        }
62
63        // Set value using serialized message.
64        $this->value = $msg->serializeToString();
65
66        // Set type url.
67        $pool = \Google\Protobuf\Internal\DescriptorPool::getGeneratedPool();
68        $desc = $pool->getDescriptorByClassName(get_class($msg));
69        $fully_qualifed_name = $desc->getFullName();
70        $this->type_url = GPBUtil::TYPE_URL_PREFIX . $fully_qualifed_name;
71    }
72
73    /**
74     * This method returns whether the type_url in any_message is corresponded
75     * to the given class.
76     * @param klass: The fully qualified PHP class name of a proto message type.
77     */
78    public function is($klass)
79    {
80        $pool = \Google\Protobuf\Internal\DescriptorPool::getGeneratedPool();
81        $desc = $pool->getDescriptorByClassName($klass);
82        $fully_qualifed_name = $desc->getFullName();
83        $type_url = GPBUtil::TYPE_URL_PREFIX . $fully_qualifed_name;
84        return $this->type_url === $type_url;
85    }
86}
87