1<?php
2
3// Protocol Buffers - Google's data interchange format
4// Copyright 2008 Google Inc.  All rights reserved.
5// https://developers.google.com/protocol-buffers/
6//
7// Redistribution and use in source and binary forms, with or without
8// modification, are permitted provided that the following conditions are
9// met:
10//
11//     * Redistributions of source code must retain the above copyright
12// notice, this list of conditions and the following disclaimer.
13//     * Redistributions in binary form must reproduce the above
14// copyright notice, this list of conditions and the following disclaimer
15// in the documentation and/or other materials provided with the
16// distribution.
17//     * Neither the name of Google Inc. nor the names of its
18// contributors may be used to endorse or promote products derived from
19// this software without specific prior written permission.
20//
21// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32
33namespace Google\Protobuf\Internal;
34
35class Descriptor
36{
37    use HasPublicDescriptorTrait;
38
39    private $full_name;
40    private $field = [];
41    private $json_to_field = [];
42    private $name_to_field = [];
43    private $index_to_field = [];
44    private $nested_type = [];
45    private $enum_type = [];
46    private $klass;
47    private $legacy_klass;
48    private $options;
49    private $oneof_decl = [];
50
51    public function __construct()
52    {
53        $this->public_desc = new \Google\Protobuf\Descriptor($this);
54    }
55
56    public function addOneofDecl($oneof)
57    {
58        $this->oneof_decl[] = $oneof;
59    }
60
61    public function getOneofDecl()
62    {
63        return $this->oneof_decl;
64    }
65
66    public function setFullName($full_name)
67    {
68        $this->full_name = $full_name;
69    }
70
71    public function getFullName()
72    {
73        return $this->full_name;
74    }
75
76    public function addField($field)
77    {
78        $this->field[$field->getNumber()] = $field;
79        $this->json_to_field[$field->getJsonName()] = $field;
80        $this->name_to_field[$field->getName()] = $field;
81        $this->index_to_field[] = $field;
82    }
83
84    public function getField()
85    {
86        return $this->field;
87    }
88
89    public function addNestedType($desc)
90    {
91        $this->nested_type[] = $desc;
92    }
93
94    public function getNestedType()
95    {
96        return $this->nested_type;
97    }
98
99    public function addEnumType($desc)
100    {
101        $this->enum_type[] = $desc;
102    }
103
104    public function getEnumType()
105    {
106        return $this->enum_type;
107    }
108
109    public function getFieldByNumber($number)
110    {
111        if (!isset($this->field[$number])) {
112          return NULL;
113        } else {
114          return $this->field[$number];
115        }
116    }
117
118    public function getFieldByJsonName($json_name)
119    {
120        if (!isset($this->json_to_field[$json_name])) {
121          return NULL;
122        } else {
123          return $this->json_to_field[$json_name];
124        }
125    }
126
127    public function getFieldByName($name)
128    {
129        if (!isset($this->name_to_field[$name])) {
130          return NULL;
131        } else {
132          return $this->name_to_field[$name];
133        }
134    }
135
136    public function getFieldByIndex($index)
137    {
138        if (count($this->index_to_field) <= $index) {
139            return NULL;
140        } else {
141            return $this->index_to_field[$index];
142        }
143    }
144
145    public function setClass($klass)
146    {
147        $this->klass = $klass;
148    }
149
150    public function getClass()
151    {
152        return $this->klass;
153    }
154
155    public function setLegacyClass($klass)
156    {
157        $this->legacy_klass = $klass;
158    }
159
160    public function getLegacyClass()
161    {
162        return $this->legacy_klass;
163    }
164
165    public function setOptions($options)
166    {
167        $this->options = $options;
168    }
169
170    public function getOptions()
171    {
172        return $this->options;
173    }
174
175    public static function buildFromProto($proto, $file_proto, $containing)
176    {
177        $desc = new Descriptor();
178
179        $message_name_without_package  = "";
180        $classname = "";
181        $legacy_classname = "";
182        $fullname = "";
183        GPBUtil::getFullClassName(
184            $proto,
185            $containing,
186            $file_proto,
187            $message_name_without_package,
188            $legacy_classname,
189            $classname,
190            $fullname);
191        $desc->setFullName($fullname);
192        $desc->setClass($classname);
193        $desc->setLegacyClass($legacy_classname);
194        $desc->setOptions($proto->getOptions());
195
196        foreach ($proto->getField() as $field_proto) {
197            $desc->addField(FieldDescriptor::buildFromProto($field_proto));
198        }
199
200        // Handle nested types.
201        foreach ($proto->getNestedType() as $nested_proto) {
202            $desc->addNestedType(Descriptor::buildFromProto(
203              $nested_proto, $file_proto, $message_name_without_package));
204        }
205
206        // Handle nested enum.
207        foreach ($proto->getEnumType() as $enum_proto) {
208            $desc->addEnumType(EnumDescriptor::buildFromProto(
209              $enum_proto, $file_proto, $message_name_without_package));
210        }
211
212        // Handle oneof fields.
213        $index = 0;
214        foreach ($proto->getOneofDecl() as $oneof_proto) {
215            $desc->addOneofDecl(
216                OneofDescriptor::buildFromProto($oneof_proto, $desc, $index));
217            $index++;
218        }
219
220        return $desc;
221    }
222}
223