Topic Text   Topic Comments (1)   Topic Properties   Topic Information xx@sof...
Topic title: Protobuf Saturday January 31, 2009 08:26:15

Download topic text | View in monospace font | Tab width set to 4 (change to 8)

Files in topic: (view all files)  
descriptor_database.cc   {+291,-0}

[Add General Comment] to topic.

File descriptor_database.cc (Revision 1.0) [Add File Comment] [Top]
 
1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2008 Google Inc.
3 // http://code.google.com/p/protobuf/
4 //
5 // Licensed under the Apache License, Version 2.0 (the "License");
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
8 //
9 // http://www.apache.org/licenses/LICENSE-2.0
10 //
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
16
17 // Author: kenton@google.com (Kenton Varda)
18 // Based on original Protocol Buffers design by
19 // Sanjay Ghemawat, Jeff Dean, and others.
20
21 #include <google/protobuf/descriptor_database.h>
22 #include <google/protobuf/descriptor.pb.h>
23 #include <google/protobuf/stubs/stl_util-inl.h>
24 #include <google/protobuf/stubs/map-util.h>
25
26 namespace google {
27 namespace protobuf {
28
29 DescriptorDatabase::~DescriptorDatabase() {}
30
31 // ===================================================================
32
33 SimpleDescriptorDatabase::SimpleDescriptorDatabase() {}
34 SimpleDescriptorDatabase::~SimpleDescriptorDatabase() {
35 STLDeleteElements(&files_to_delete_);
36 }
37
38 void SimpleDescriptorDatabase::Add(const FileDescriptorProto& file) {
39 FileDescriptorProto* new_file = new FileDescriptorProto;
40 new_file->CopyFrom(file);
41 AddAndOwn(new_file);
42 }
43
44 void SimpleDescriptorDatabase::AddAndOwn(const FileDescriptorProto* file) {
45 files_to_delete_.push_back(file);
46 InsertOrUpdate(&files_by_name_, file->name(), file);
47
48 string path = file->package();
49 if (!path.empty()) path += '.';
50
51 for (int i = 0; i < file->message_type_size(); i++) {
52 AddMessage(path, file->message_type(i), file);
53 }
54 for (int i = 0; i < file->enum_type_size(); i++) {
55 AddEnum(path, file->enum_type(i), file);
56 }
57 for (int i = 0; i < file->extension_size(); i++) {
58 AddField(path, file->extension(i), file);
59 }
60 for (int i = 0; i < file->service_size(); i++) {
61 AddService(path, file->service(i), file);
62 }
63 }
64
65 void SimpleDescriptorDatabase::AddMessage(
66 const string& path,
67 const DescriptorProto& message_type,
68 const FileDescriptorProto* file) {
69 string full_name = path + message_type.name();
70 InsertOrUpdate(&files_by_symbol_, full_name, file);
71
72 string sub_path = full_name + '.';
73 for (int i = 0; i < message_type.nested_type_size(); i++) {
74 AddMessage(sub_path, message_type.nested_type(i), file);
75 }
76 for (int i = 0; i < message_type.enum_type_size(); i++) {
77 AddEnum(sub_path, message_type.enum_type(i), file);
78 }
79 for (int i = 0; i < message_type.field_size(); i++) {
80 AddField(sub_path, message_type.field(i), file);
81 }
82 for (int i = 0; i < message_type.extension_size(); i++) {
83 AddField(sub_path, message_type.extension(i), file);
84 }
85 }
86
87 void SimpleDescriptorDatabase::AddField(
88 const string& path,
89 const FieldDescriptorProto& field,
90 const FileDescriptorProto* file) {
91 string full_name = path + field.name();
92 InsertOrUpdate(&files_by_symbol_, full_name, file);
93
94 if (field.has_extendee()) {
95 // This field is an extension.
96 if (!field.extendee().empty() && field.extendee()[0] == '.') {
97 // The extension is fully-qualified. We can use it as a lookup key in
98 // the files_by_symbol_ table.
99 InsertOrUpdate(&files_by_extension_,
100 make_pair(field.extendee().substr(1), field.number()),
101 file);
102 } else {
103 // Not fully-qualified. We can't really do anything here, unfortunately.
104 }
105 }
106 }
107
108 void SimpleDescriptorDatabase::AddEnum(
109 const string& path,
110 const EnumDescriptorProto& enum_type,
111 const FileDescriptorProto* file) {
112 string full_name = path + enum_type.name();
113 InsertOrUpdate(&files_by_symbol_, full_name, file);
114
115 string sub_path = full_name + '.';
116 for (int i = 0; i < enum_type.value_size(); i++) {
117 InsertOrUpdate(&files_by_symbol_,
118 sub_path + enum_type.value(i).name(),
119 file);
120 }
121 }
122
123 void SimpleDescriptorDatabase::AddService(
124 const string& path,
125 const ServiceDescriptorProto& service,
126 const FileDescriptorProto* file) {
127 string full_name = path + service.name();
128 InsertOrUpdate(&files_by_symbol_, full_name, file);
129
130 string sub_path = full_name + '.';
131 for (int i = 0; i < service.method_size(); i++) {
132 InsertOrUpdate(&files_by_symbol_,
133 sub_path + service.method(i).name(),
134 file);
135 }
136 }
137
138 bool SimpleDescriptorDatabase::FindFileByName(
139 const string& filename,
140 FileDescriptorProto* output) {
141 const FileDescriptorProto* result = FindPtrOrNull(files_by_name_, filename);
142 if (result == NULL) {
143 return false;
144 } else {
145 output->CopyFrom(*result);
146 return true;
147 }
148 }
149
150 bool SimpleDescriptorDatabase::FindFileContainingSymbol(
151 const string& symbol_name,
152 FileDescriptorProto* output) {
153 const FileDescriptorProto* result =
154 FindPtrOrNull(files_by_symbol_, symbol_name);
155 if (result == NULL) {
156 return false;
157 } else {
158 output->CopyFrom(*result);
159 return true;
160 }
161 }
162
163 bool SimpleDescriptorDatabase::FindFileContainingExtension(
164 const string& containing_type,
165 int field_number,
166 FileDescriptorProto* output) {
167 const FileDescriptorProto* result =
168 FindPtrOrNull(files_by_extension_,
169 make_pair(containing_type, field_number));
170 if (result == NULL) {
171 return false;
172 } else {
173 output->CopyFrom(*result);
174 return true;
175 }
176 }
177
178 // ===================================================================
179
180 DescriptorPoolDatabase::DescriptorPoolDatabase(const DescriptorPool& pool)
181 : pool_(pool) {}
182 DescriptorPoolDatabase::~DescriptorPoolDatabase() {}
183
184 bool DescriptorPoolDatabase::FindFileByName(
185 const string& filename,
186 FileDescriptorProto* output) {
187 const FileDescriptor* file = pool_.FindFileByName(filename);
188 if (file == NULL) return false;
189 output->Clear();
190 file->CopyTo(output);
191 return true;
192 }
193
194 bool DescriptorPoolDatabase::FindFileContainingSymbol(
195 const string& symbol_name,
196 FileDescriptorProto* output) {
197 const FileDescriptor* file = pool_.FindFileContainingSymbol(symbol_name);
198 if (file == NULL) return false;
199 output->Clear();
200 file->CopyTo(output);
201 return true;
202 }
203
204 bool DescriptorPoolDatabase::FindFileContainingExtension(
205 const string& containing_type,
206 int field_number,
207 FileDescriptorProto* output) {
208 const Descriptor* extendee = pool_.FindMessageTypeByName(containing_type);
209 if (extendee == NULL) return false;
210
211 const FieldDescriptor* extension =
212 pool_.FindExtensionByNumber(extendee, field_number);
213 if (extension == NULL) return false;
214
215 output->Clear();
216 extension->file()->CopyTo(output);
217 return true;
218 }
219
220 // ===================================================================
221
222 MergedDescriptorDatabase::MergedDescriptorDatabase(
223 DescriptorDatabase* source1,
224 DescriptorDatabase* source2) {
225 sources_.push_back(source1);
226 sources_.push_back(source2);
227 }
228 MergedDescriptorDatabase::MergedDescriptorDatabase(
229 const vector<DescriptorDatabase*>& sources)
230 : sources_(sources) {}
231 MergedDescriptorDatabase::~MergedDescriptorDatabase() {}
232
233 bool MergedDescriptorDatabase::FindFileByName(
234 const string& filename,
235 FileDescriptorProto* output) {
236 for (int i = 0; i < sources_.size(); i++) {
237 if (sources_[i]->FindFileByName(filename, output)) {
238 return true;
239 }
240 }
241 return false;
242 }
243
244 bool MergedDescriptorDatabase::FindFileContainingSymbol(
245 const string& symbol_name,
246 FileDescriptorProto* output) {
247 for (int i = 0; i < sources_.size(); i++) {
248 if (sources_[i]->FindFileContainingSymbol(symbol_name, output)) {
249 // The symbol was found in source i. However, if one of the previous
250 // sources defines a file with the same name (which presumably doesn't
251 // contain the symbol, since it wasn't found in that source), then we
252 // must hide it from the caller.
253 FileDescriptorProto temp;
254 for (int j = 0; j < i; j++) {
255 if (sources_[j]->FindFileByName(output->name(), &temp)) {
256 // Found conflicting file in a previous source.
257 return false;
258 }
259 }
260 return true;
261 }
262 }
263 return false;
264 }
265
266 bool MergedDescriptorDatabase::FindFileContainingExtension(
267 const string& containing_type,
268 int field_number,
269 FileDescriptorProto* output) {
270 for (int i = 0; i < sources_.size(); i++) {
271 if (sources_[i]->FindFileContainingExtension(
272 containing_type, field_number, output)) {
273 // The symbol was found in source i. However, if one of the previous
274 // sources defines a file with the same name (which presumably doesn't
275 // contain the symbol, since it wasn't found in that source), then we
276 // must hide it from the caller.
277 FileDescriptorProto temp;
278 for (int j = 0; j < i; j++) {
279 if (sources_[j]->FindFileByName(output->name(), &temp)) {
280 // Found conflicting file in a previous source.
281 return false;
282 }
283 }
284 return true;
285 }
286 }
287 return false;
288 }
289
290 } // namespace protobuf
291 } // namespace google
 
File descriptor_database.cc (Revision 1.0) [Add File Comment] [Top]
  
Legend:
Removed 
Changed
 Added

[Add General Comment] to topic.