/proc/self/cwd/external/com_google_protobuf/src/google/protobuf/util/type_resolver_util.cc
Line | Count | Source |
1 | | // Protocol Buffers - Google's data interchange format |
2 | | // Copyright 2008 Google Inc. All rights reserved. |
3 | | // https://developers.google.com/protocol-buffers/ |
4 | | // |
5 | | // Redistribution and use in source and binary forms, with or without |
6 | | // modification, are permitted provided that the following conditions are |
7 | | // met: |
8 | | // |
9 | | // * Redistributions of source code must retain the above copyright |
10 | | // notice, this list of conditions and the following disclaimer. |
11 | | // * Redistributions in binary form must reproduce the above |
12 | | // copyright notice, this list of conditions and the following disclaimer |
13 | | // in the documentation and/or other materials provided with the |
14 | | // distribution. |
15 | | // * Neither the name of Google Inc. nor the names of its |
16 | | // contributors may be used to endorse or promote products derived from |
17 | | // this software without specific prior written permission. |
18 | | // |
19 | | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
20 | | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
21 | | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
22 | | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
23 | | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
24 | | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
25 | | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
26 | | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
27 | | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
28 | | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
29 | | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
30 | | |
31 | | #include <google/protobuf/util/type_resolver_util.h> |
32 | | |
33 | | #include <google/protobuf/type.pb.h> |
34 | | #include <google/protobuf/wrappers.pb.h> |
35 | | #include <google/protobuf/descriptor.pb.h> |
36 | | #include <google/protobuf/descriptor.h> |
37 | | #include <google/protobuf/util/internal/utility.h> |
38 | | #include <google/protobuf/util/type_resolver.h> |
39 | | #include <google/protobuf/stubs/strutil.h> |
40 | | #include <google/protobuf/stubs/status.h> |
41 | | #include <google/protobuf/stubs/status.h> |
42 | | |
43 | | // clang-format off |
44 | | #include <google/protobuf/port_def.inc> |
45 | | // clang-format on |
46 | | |
47 | | namespace google { |
48 | | namespace protobuf { |
49 | | namespace util { |
50 | | namespace { |
51 | | using google::protobuf::Any; |
52 | | using google::protobuf::BoolValue; |
53 | | using google::protobuf::BytesValue; |
54 | | using google::protobuf::DoubleValue; |
55 | | using google::protobuf::Enum; |
56 | | using google::protobuf::EnumValue; |
57 | | using google::protobuf::Field; |
58 | | using google::protobuf::FloatValue; |
59 | | using google::protobuf::Int32Value; |
60 | | using google::protobuf::Int64Value; |
61 | | using google::protobuf::Option; |
62 | | using google::protobuf::StringValue; |
63 | | using google::protobuf::Type; |
64 | | using google::protobuf::UInt32Value; |
65 | | using google::protobuf::UInt64Value; |
66 | | |
67 | | class DescriptorPoolTypeResolver : public TypeResolver { |
68 | | public: |
69 | | DescriptorPoolTypeResolver(const std::string& url_prefix, |
70 | | const DescriptorPool* pool) |
71 | 1 | : url_prefix_(url_prefix), pool_(pool) {} |
72 | | |
73 | | util::Status ResolveMessageType(const std::string& type_url, |
74 | 54.7k | Type* type) override { |
75 | 54.7k | std::string type_name; |
76 | 54.7k | util::Status status = ParseTypeUrl(type_url, &type_name); |
77 | 54.7k | if (!status.ok()) { |
78 | 0 | return status; |
79 | 0 | } |
80 | | |
81 | 54.7k | const Descriptor* descriptor = pool_->FindMessageTypeByName(type_name); |
82 | 54.7k | if (descriptor == NULL) { |
83 | 0 | return util::NotFoundError("Invalid type URL, unknown type: " + |
84 | 0 | type_name); |
85 | 0 | } |
86 | 54.7k | ConvertDescriptor(descriptor, type); |
87 | 54.7k | return util::Status(); |
88 | 54.7k | } |
89 | | |
90 | | util::Status ResolveEnumType(const std::string& type_url, |
91 | 235 | Enum* enum_type) override { |
92 | 235 | std::string type_name; |
93 | 235 | util::Status status = ParseTypeUrl(type_url, &type_name); |
94 | 235 | if (!status.ok()) { |
95 | 0 | return status; |
96 | 0 | } |
97 | | |
98 | 235 | const EnumDescriptor* descriptor = pool_->FindEnumTypeByName(type_name); |
99 | 235 | if (descriptor == NULL) { |
100 | 0 | return util::InvalidArgumentError("Invalid type URL, unknown type: " + |
101 | 0 | type_name); |
102 | 0 | } |
103 | 235 | ConvertEnumDescriptor(descriptor, enum_type); |
104 | 235 | return util::Status(); |
105 | 235 | } |
106 | | |
107 | | private: |
108 | 54.7k | void ConvertDescriptor(const Descriptor* descriptor, Type* type) { |
109 | 54.7k | type->Clear(); |
110 | 54.7k | type->set_name(descriptor->full_name()); |
111 | 181k | for (int i = 0; i < descriptor->field_count(); ++i) { |
112 | 127k | ConvertFieldDescriptor(descriptor->field(i), type->add_fields()); |
113 | 127k | } |
114 | 66.3k | for (int i = 0; i < descriptor->oneof_decl_count(); ++i) { |
115 | 11.5k | type->add_oneofs(descriptor->oneof_decl(i)->name()); |
116 | 11.5k | } |
117 | 54.7k | type->mutable_source_context()->set_file_name(descriptor->file()->name()); |
118 | 54.7k | ConvertMessageOptions(descriptor->options(), type->mutable_options()); |
119 | 54.7k | } |
120 | | |
121 | | void ConvertMessageOptions(const MessageOptions& options, |
122 | 54.7k | RepeatedPtrField<Option>* output) { |
123 | 54.7k | return ConvertOptionsInternal(options, output); |
124 | 54.7k | } |
125 | | |
126 | | void ConvertFieldOptions(const FieldOptions& options, |
127 | 127k | RepeatedPtrField<Option>* output) { |
128 | 127k | return ConvertOptionsInternal(options, output); |
129 | 127k | } |
130 | | |
131 | | void ConvertEnumOptions(const EnumOptions& options, |
132 | 235 | RepeatedPtrField<Option>* output) { |
133 | 235 | return ConvertOptionsInternal(options, output); |
134 | 235 | } |
135 | | |
136 | | void ConvertEnumValueOptions(const EnumValueOptions& options, |
137 | 235 | RepeatedPtrField<Option>* output) { |
138 | 235 | return ConvertOptionsInternal(options, output); |
139 | 235 | } |
140 | | |
141 | | // Implementation details for Convert*Options. |
142 | | void ConvertOptionsInternal(const Message& options, |
143 | 182k | RepeatedPtrField<Option>* output) { |
144 | 182k | const Reflection* reflection = options.GetReflection(); |
145 | 182k | std::vector<const FieldDescriptor*> fields; |
146 | 182k | reflection->ListFields(options, &fields); |
147 | 182k | for (const FieldDescriptor* field : fields) { |
148 | 14.4k | if (field->is_repeated()) { |
149 | 0 | const int size = reflection->FieldSize(options, field); |
150 | 0 | for (int i = 0; i < size; i++) { |
151 | 0 | ConvertOptionField(reflection, options, field, i, output->Add()); |
152 | 0 | } |
153 | 14.4k | } else { |
154 | 14.4k | ConvertOptionField(reflection, options, field, -1, output->Add()); |
155 | 14.4k | } |
156 | 14.4k | } |
157 | 182k | } |
158 | | |
159 | | static void ConvertOptionField(const Reflection* reflection, |
160 | | const Message& options, |
161 | | const FieldDescriptor* field, int index, |
162 | 14.4k | Option* out) { |
163 | 14.4k | out->set_name(field->is_extension() ? field->full_name() : field->name()); |
164 | 14.4k | Any* value = out->mutable_value(); |
165 | 14.4k | switch (field->cpp_type()) { |
166 | 0 | case FieldDescriptor::CPPTYPE_MESSAGE: |
167 | 0 | value->PackFrom( |
168 | 0 | field->is_repeated() |
169 | 0 | ? reflection->GetRepeatedMessage(options, field, index) |
170 | 0 | : reflection->GetMessage(options, field)); |
171 | 0 | return; |
172 | 0 | case FieldDescriptor::CPPTYPE_DOUBLE: |
173 | 0 | value->PackFrom(WrapValue<DoubleValue>( |
174 | 0 | field->is_repeated() |
175 | 0 | ? reflection->GetRepeatedDouble(options, field, index) |
176 | 0 | : reflection->GetDouble(options, field))); |
177 | 0 | return; |
178 | 0 | case FieldDescriptor::CPPTYPE_FLOAT: |
179 | 0 | value->PackFrom(WrapValue<FloatValue>( |
180 | 0 | field->is_repeated() |
181 | 0 | ? reflection->GetRepeatedFloat(options, field, index) |
182 | 0 | : reflection->GetFloat(options, field))); |
183 | 0 | return; |
184 | 0 | case FieldDescriptor::CPPTYPE_INT64: |
185 | 0 | value->PackFrom(WrapValue<Int64Value>( |
186 | 0 | field->is_repeated() |
187 | 0 | ? reflection->GetRepeatedInt64(options, field, index) |
188 | 0 | : reflection->GetInt64(options, field))); |
189 | 0 | return; |
190 | 0 | case FieldDescriptor::CPPTYPE_UINT64: |
191 | 0 | value->PackFrom(WrapValue<UInt64Value>( |
192 | 0 | field->is_repeated() |
193 | 0 | ? reflection->GetRepeatedUInt64(options, field, index) |
194 | 0 | : reflection->GetUInt64(options, field))); |
195 | 0 | return; |
196 | 0 | case FieldDescriptor::CPPTYPE_INT32: |
197 | 0 | value->PackFrom(WrapValue<Int32Value>( |
198 | 0 | field->is_repeated() |
199 | 0 | ? reflection->GetRepeatedInt32(options, field, index) |
200 | 0 | : reflection->GetInt32(options, field))); |
201 | 0 | return; |
202 | 0 | case FieldDescriptor::CPPTYPE_UINT32: |
203 | 0 | value->PackFrom(WrapValue<UInt32Value>( |
204 | 0 | field->is_repeated() |
205 | 0 | ? reflection->GetRepeatedUInt32(options, field, index) |
206 | 0 | : reflection->GetUInt32(options, field))); |
207 | 0 | return; |
208 | 14.4k | case FieldDescriptor::CPPTYPE_BOOL: |
209 | 14.4k | value->PackFrom(WrapValue<BoolValue>( |
210 | 14.4k | field->is_repeated() |
211 | 14.4k | ? reflection->GetRepeatedBool(options, field, index) |
212 | 14.4k | : reflection->GetBool(options, field))); |
213 | 14.4k | return; |
214 | 0 | case FieldDescriptor::CPPTYPE_STRING: { |
215 | 0 | const std::string& val = |
216 | 0 | field->is_repeated() |
217 | 0 | ? reflection->GetRepeatedString(options, field, index) |
218 | 0 | : reflection->GetString(options, field); |
219 | 0 | if (field->type() == FieldDescriptor::TYPE_STRING) { |
220 | 0 | value->PackFrom(WrapValue<StringValue>(val)); |
221 | 0 | } else { |
222 | 0 | value->PackFrom(WrapValue<BytesValue>(val)); |
223 | 0 | } |
224 | 0 | return; |
225 | 0 | } |
226 | 0 | case FieldDescriptor::CPPTYPE_ENUM: { |
227 | 0 | const EnumValueDescriptor* val = |
228 | 0 | field->is_repeated() |
229 | 0 | ? reflection->GetRepeatedEnum(options, field, index) |
230 | 0 | : reflection->GetEnum(options, field); |
231 | 0 | value->PackFrom(WrapValue<Int32Value>(val->number())); |
232 | 0 | return; |
233 | 0 | } |
234 | 14.4k | } |
235 | 14.4k | } |
236 | | |
237 | | template <typename WrapperT, typename T> |
238 | 14.4k | static WrapperT WrapValue(T value) { |
239 | 14.4k | WrapperT wrapper; |
240 | 14.4k | wrapper.set_value(value); |
241 | 14.4k | return wrapper; |
242 | 14.4k | } Unexecuted instantiation: type_resolver_util.cc:google::protobuf::DoubleValue google::protobuf::util::(anonymous namespace)::DescriptorPoolTypeResolver::WrapValue<google::protobuf::DoubleValue, double>(double) Unexecuted instantiation: type_resolver_util.cc:google::protobuf::FloatValue google::protobuf::util::(anonymous namespace)::DescriptorPoolTypeResolver::WrapValue<google::protobuf::FloatValue, float>(float) Unexecuted instantiation: type_resolver_util.cc:google::protobuf::Int64Value google::protobuf::util::(anonymous namespace)::DescriptorPoolTypeResolver::WrapValue<google::protobuf::Int64Value, long>(long) Unexecuted instantiation: type_resolver_util.cc:google::protobuf::UInt64Value google::protobuf::util::(anonymous namespace)::DescriptorPoolTypeResolver::WrapValue<google::protobuf::UInt64Value, unsigned long>(unsigned long) Unexecuted instantiation: type_resolver_util.cc:google::protobuf::Int32Value google::protobuf::util::(anonymous namespace)::DescriptorPoolTypeResolver::WrapValue<google::protobuf::Int32Value, int>(int) Unexecuted instantiation: type_resolver_util.cc:google::protobuf::UInt32Value google::protobuf::util::(anonymous namespace)::DescriptorPoolTypeResolver::WrapValue<google::protobuf::UInt32Value, unsigned int>(unsigned int) type_resolver_util.cc:google::protobuf::BoolValue google::protobuf::util::(anonymous namespace)::DescriptorPoolTypeResolver::WrapValue<google::protobuf::BoolValue, bool>(bool) Line | Count | Source | 238 | 14.4k | static WrapperT WrapValue(T value) { | 239 | 14.4k | WrapperT wrapper; | 240 | 14.4k | wrapper.set_value(value); | 241 | 14.4k | return wrapper; | 242 | 14.4k | } |
Unexecuted instantiation: type_resolver_util.cc:google::protobuf::StringValue google::protobuf::util::(anonymous namespace)::DescriptorPoolTypeResolver::WrapValue<google::protobuf::StringValue, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >) Unexecuted instantiation: type_resolver_util.cc:google::protobuf::BytesValue google::protobuf::util::(anonymous namespace)::DescriptorPoolTypeResolver::WrapValue<google::protobuf::BytesValue, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >) |
243 | | |
244 | 127k | void ConvertFieldDescriptor(const FieldDescriptor* descriptor, Field* field) { |
245 | 127k | field->set_kind(static_cast<Field::Kind>(descriptor->type())); |
246 | 127k | switch (descriptor->label()) { |
247 | 98.3k | case FieldDescriptor::LABEL_OPTIONAL: |
248 | 98.3k | field->set_cardinality(Field::CARDINALITY_OPTIONAL); |
249 | 98.3k | break; |
250 | 28.7k | case FieldDescriptor::LABEL_REPEATED: |
251 | 28.7k | field->set_cardinality(Field::CARDINALITY_REPEATED); |
252 | 28.7k | break; |
253 | 0 | case FieldDescriptor::LABEL_REQUIRED: |
254 | 0 | field->set_cardinality(Field::CARDINALITY_REQUIRED); |
255 | 0 | break; |
256 | 127k | } |
257 | 127k | field->set_number(descriptor->number()); |
258 | 127k | field->set_name(descriptor->name()); |
259 | 127k | field->set_json_name(descriptor->json_name()); |
260 | 127k | if (descriptor->has_default_value()) { |
261 | 0 | field->set_default_value(DefaultValueAsString(descriptor)); |
262 | 0 | } |
263 | 127k | if (descriptor->type() == FieldDescriptor::TYPE_MESSAGE || |
264 | 66.3k | descriptor->type() == FieldDescriptor::TYPE_GROUP) { |
265 | 66.3k | field->set_type_url(GetTypeUrl(descriptor->message_type())); |
266 | 66.3k | } else if (descriptor->type() == FieldDescriptor::TYPE_ENUM) { |
267 | 11.5k | field->set_type_url(GetTypeUrl(descriptor->enum_type())); |
268 | 11.5k | } |
269 | 127k | if (descriptor->containing_oneof() != NULL) { |
270 | 69.4k | field->set_oneof_index(descriptor->containing_oneof()->index() + 1); |
271 | 69.4k | } |
272 | 127k | if (descriptor->is_packed()) { |
273 | 0 | field->set_packed(true); |
274 | 0 | } |
275 | | |
276 | 127k | ConvertFieldOptions(descriptor->options(), field->mutable_options()); |
277 | 127k | } |
278 | | |
279 | | void ConvertEnumDescriptor(const EnumDescriptor* descriptor, |
280 | 235 | Enum* enum_type) { |
281 | 235 | enum_type->Clear(); |
282 | 235 | enum_type->set_name(descriptor->full_name()); |
283 | 235 | enum_type->mutable_source_context()->set_file_name( |
284 | 235 | descriptor->file()->name()); |
285 | 470 | for (int i = 0; i < descriptor->value_count(); ++i) { |
286 | 235 | const EnumValueDescriptor* value_descriptor = descriptor->value(i); |
287 | 235 | EnumValue* value = enum_type->mutable_enumvalue()->Add(); |
288 | 235 | value->set_name(value_descriptor->name()); |
289 | 235 | value->set_number(value_descriptor->number()); |
290 | | |
291 | 235 | ConvertEnumValueOptions(value_descriptor->options(), |
292 | 235 | value->mutable_options()); |
293 | 235 | } |
294 | | |
295 | 235 | ConvertEnumOptions(descriptor->options(), enum_type->mutable_options()); |
296 | 235 | } |
297 | | |
298 | 66.3k | std::string GetTypeUrl(const Descriptor* descriptor) { |
299 | 66.3k | return url_prefix_ + "/" + descriptor->full_name(); |
300 | 66.3k | } |
301 | | |
302 | 11.5k | std::string GetTypeUrl(const EnumDescriptor* descriptor) { |
303 | 11.5k | return url_prefix_ + "/" + descriptor->full_name(); |
304 | 11.5k | } |
305 | | |
306 | | util::Status ParseTypeUrl(const std::string& type_url, |
307 | 55.0k | std::string* type_name) { |
308 | 55.0k | if (type_url.substr(0, url_prefix_.size() + 1) != url_prefix_ + "/") { |
309 | 0 | return util::InvalidArgumentError( |
310 | 0 | StrCat("Invalid type URL, type URLs must be of the form '", |
311 | 0 | url_prefix_, "/<typename>', got: ", type_url)); |
312 | 0 | } |
313 | 55.0k | *type_name = type_url.substr(url_prefix_.size() + 1); |
314 | 55.0k | return util::Status(); |
315 | 55.0k | } |
316 | | |
317 | 0 | std::string DefaultValueAsString(const FieldDescriptor* descriptor) { |
318 | 0 | switch (descriptor->cpp_type()) { |
319 | 0 | case FieldDescriptor::CPPTYPE_INT32: |
320 | 0 | return StrCat(descriptor->default_value_int32()); |
321 | 0 | break; |
322 | 0 | case FieldDescriptor::CPPTYPE_INT64: |
323 | 0 | return StrCat(descriptor->default_value_int64()); |
324 | 0 | break; |
325 | 0 | case FieldDescriptor::CPPTYPE_UINT32: |
326 | 0 | return StrCat(descriptor->default_value_uint32()); |
327 | 0 | break; |
328 | 0 | case FieldDescriptor::CPPTYPE_UINT64: |
329 | 0 | return StrCat(descriptor->default_value_uint64()); |
330 | 0 | break; |
331 | 0 | case FieldDescriptor::CPPTYPE_FLOAT: |
332 | 0 | return SimpleFtoa(descriptor->default_value_float()); |
333 | 0 | break; |
334 | 0 | case FieldDescriptor::CPPTYPE_DOUBLE: |
335 | 0 | return SimpleDtoa(descriptor->default_value_double()); |
336 | 0 | break; |
337 | 0 | case FieldDescriptor::CPPTYPE_BOOL: |
338 | 0 | return descriptor->default_value_bool() ? "true" : "false"; |
339 | 0 | break; |
340 | 0 | case FieldDescriptor::CPPTYPE_STRING: |
341 | 0 | if (descriptor->type() == FieldDescriptor::TYPE_BYTES) { |
342 | 0 | return CEscape(descriptor->default_value_string()); |
343 | 0 | } else { |
344 | 0 | return descriptor->default_value_string(); |
345 | 0 | } |
346 | 0 | break; |
347 | 0 | case FieldDescriptor::CPPTYPE_ENUM: |
348 | 0 | return descriptor->default_value_enum()->name(); |
349 | 0 | break; |
350 | 0 | case FieldDescriptor::CPPTYPE_MESSAGE: |
351 | 0 | GOOGLE_LOG(DFATAL) << "Messages can't have default values!"; |
352 | 0 | break; |
353 | 0 | } |
354 | 0 | return ""; |
355 | 0 | } |
356 | | |
357 | | std::string url_prefix_; |
358 | | const DescriptorPool* pool_; |
359 | | }; |
360 | | |
361 | | } // namespace |
362 | | |
363 | | TypeResolver* NewTypeResolverForDescriptorPool(const std::string& url_prefix, |
364 | 1 | const DescriptorPool* pool) { |
365 | 1 | return new DescriptorPoolTypeResolver(url_prefix, pool); |
366 | 1 | } |
367 | | |
368 | | } // namespace util |
369 | | } // namespace protobuf |
370 | | } // namespace google |