Line data Source code
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 : // Author: kenton@google.com (Kenton Varda)
32 : // Based on original Protocol Buffers design by
33 : // Sanjay Ghemawat, Jeff Dean, and others.
34 :
35 : #include <google/protobuf/compiler/java/java_file.h>
36 :
37 : #include <memory>
38 : #ifndef _SHARED_PTR_H
39 : #include <google/protobuf/stubs/shared_ptr.h>
40 : #endif
41 : #include <set>
42 :
43 : #include <google/protobuf/compiler/java/java_context.h>
44 : #include <google/protobuf/compiler/java/java_enum.h>
45 : #include <google/protobuf/compiler/java/java_extension.h>
46 : #include <google/protobuf/compiler/java/java_generator_factory.h>
47 : #include <google/protobuf/compiler/java/java_helpers.h>
48 : #include <google/protobuf/compiler/java/java_message.h>
49 : #include <google/protobuf/compiler/java/java_name_resolver.h>
50 : #include <google/protobuf/compiler/java/java_service.h>
51 : #include <google/protobuf/compiler/java/java_shared_code_generator.h>
52 : #include <google/protobuf/compiler/code_generator.h>
53 : #include <google/protobuf/io/printer.h>
54 : #include <google/protobuf/io/zero_copy_stream.h>
55 : #include <google/protobuf/descriptor.pb.h>
56 : #include <google/protobuf/dynamic_message.h>
57 : #include <google/protobuf/stubs/strutil.h>
58 :
59 : namespace google {
60 : namespace protobuf {
61 : namespace compiler {
62 : namespace java {
63 :
64 : namespace {
65 :
66 : struct FieldDescriptorCompare {
67 0 : bool operator ()(const FieldDescriptor* f1, const FieldDescriptor* f2) {
68 0 : if(f1 == NULL) {
69 : return false;
70 : }
71 0 : if(f2 == NULL) {
72 : return true;
73 : }
74 0 : return f1->full_name() < f2->full_name();
75 : }
76 : };
77 :
78 : typedef std::set<const FieldDescriptor*, FieldDescriptorCompare> FieldDescriptorSet;
79 :
80 : // Recursively searches the given message to collect extensions.
81 : // Returns true if all the extensions can be recognized. The extensions will be
82 : // appended in to the extensions parameter.
83 : // Returns false when there are unknown fields, in which case the data in the
84 : // extensions output parameter is not reliable and should be discarded.
85 0 : bool CollectExtensions(const Message& message,
86 : FieldDescriptorSet* extensions) {
87 0 : const Reflection* reflection = message.GetReflection();
88 :
89 : // There are unknown fields that could be extensions, thus this call fails.
90 0 : if (reflection->GetUnknownFields(message).field_count() > 0) return false;
91 :
92 : vector<const FieldDescriptor*> fields;
93 0 : reflection->ListFields(message, &fields);
94 :
95 0 : for (int i = 0; i < fields.size(); i++) {
96 0 : if (fields[i]->is_extension()) extensions->insert(fields[i]);
97 :
98 0 : if (GetJavaType(fields[i]) == JAVATYPE_MESSAGE) {
99 0 : if (fields[i]->is_repeated()) {
100 0 : int size = reflection->FieldSize(message, fields[i]);
101 0 : for (int j = 0; j < size; j++) {
102 : const Message& sub_message =
103 0 : reflection->GetRepeatedMessage(message, fields[i], j);
104 0 : if (!CollectExtensions(sub_message, extensions)) return false;
105 : }
106 : } else {
107 0 : const Message& sub_message = reflection->GetMessage(message, fields[i]);
108 0 : if (!CollectExtensions(sub_message, extensions)) return false;
109 : }
110 : }
111 : }
112 :
113 : return true;
114 : }
115 :
116 : // Finds all extensions in the given message and its sub-messages. If the
117 : // message contains unknown fields (which could be extensions), then those
118 : // extensions are defined in alternate_pool.
119 : // The message will be converted to a DynamicMessage backed by alternate_pool
120 : // in order to handle this case.
121 0 : void CollectExtensions(const FileDescriptorProto& file_proto,
122 : const DescriptorPool& alternate_pool,
123 : FieldDescriptorSet* extensions,
124 : const string& file_data) {
125 0 : if (!CollectExtensions(file_proto, extensions)) {
126 : // There are unknown fields in the file_proto, which are probably
127 : // extensions. We need to parse the data into a dynamic message based on the
128 : // builder-pool to find out all extensions.
129 : const Descriptor* file_proto_desc = alternate_pool.FindMessageTypeByName(
130 0 : file_proto.GetDescriptor()->full_name());
131 0 : GOOGLE_CHECK(file_proto_desc)
132 0 : << "Find unknown fields in FileDescriptorProto when building "
133 0 : << file_proto.name()
134 : << ". It's likely that those fields are custom options, however, "
135 : "descriptor.proto is not in the transitive dependencies. "
136 0 : "This normally should not happen. Please report a bug.";
137 0 : DynamicMessageFactory factory;
138 : google::protobuf::scoped_ptr<Message> dynamic_file_proto(
139 0 : factory.GetPrototype(file_proto_desc)->New());
140 0 : GOOGLE_CHECK(dynamic_file_proto.get() != NULL);
141 0 : GOOGLE_CHECK(dynamic_file_proto->ParseFromString(file_data));
142 :
143 : // Collect the extensions again from the dynamic message. There should be no
144 : // more unknown fields this time, i.e. all the custom options should be
145 : // parsed as extensions now.
146 : extensions->clear();
147 0 : GOOGLE_CHECK(CollectExtensions(*dynamic_file_proto, extensions))
148 0 : << "Find unknown fields in FileDescriptorProto when building "
149 0 : << file_proto.name()
150 : << ". It's likely that those fields are custom options, however, "
151 : "those options cannot be recognized in the builder pool. "
152 0 : "This normally should not happen. Please report a bug.";
153 : }
154 0 : }
155 :
156 : // Compare two field descriptors, returning true if the first should come
157 : // before the second.
158 : bool CompareFieldsByName(const FieldDescriptor *a, const FieldDescriptor *b) {
159 : return a->full_name() < b->full_name();
160 : }
161 :
162 : // Our static initialization methods can become very, very large.
163 : // So large that if we aren't careful we end up blowing the JVM's
164 : // 64K bytes of bytecode/method. Fortunately, since these static
165 : // methods are executed only once near the beginning of a program,
166 : // there's usually plenty of stack space available and we can
167 : // extend our methods by simply chaining them to another method
168 : // with a tail call. This inserts the sequence call-next-method,
169 : // end this one, begin-next-method as needed.
170 0 : void MaybeRestartJavaMethod(io::Printer* printer,
171 : int *bytecode_estimate,
172 : int *method_num,
173 : const char *chain_statement,
174 : const char *method_decl) {
175 : // The goal here is to stay under 64K bytes of jvm bytecode/method,
176 : // since otherwise we hit a hardcoded limit in the jvm and javac will
177 : // then fail with the error "code too large". This limit lets our
178 : // estimates be off by a factor of two and still we're okay.
179 : static const int bytesPerMethod = 1<<15; // aka 32K
180 :
181 0 : if ((*bytecode_estimate) > bytesPerMethod) {
182 0 : ++(*method_num);
183 0 : printer->Print(chain_statement, "method_num", SimpleItoa(*method_num));
184 0 : printer->Outdent();
185 0 : printer->Print("}\n");
186 0 : printer->Print(method_decl, "method_num", SimpleItoa(*method_num));
187 0 : printer->Indent();
188 0 : *bytecode_estimate = 0;
189 : }
190 0 : }
191 :
192 :
193 : } // namespace
194 :
195 0 : FileGenerator::FileGenerator(const FileDescriptor* file, bool immutable_api)
196 : : file_(file),
197 : java_package_(FileJavaPackage(file, immutable_api)),
198 : message_generators_(
199 0 : new google::protobuf::scoped_ptr<MessageGenerator>[file->message_type_count()]),
200 : extension_generators_(
201 0 : new google::protobuf::scoped_ptr<ExtensionGenerator>[file->extension_count()]),
202 0 : context_(new Context(file)),
203 0 : name_resolver_(context_->GetNameResolver()),
204 0 : immutable_api_(immutable_api) {
205 0 : classname_ = name_resolver_->GetFileClassName(file, immutable_api);
206 : generator_factory_.reset(
207 0 : new ImmutableGeneratorFactory(context_.get()));
208 0 : for (int i = 0; i < file_->message_type_count(); ++i) {
209 0 : message_generators_[i].reset(
210 0 : generator_factory_->NewMessageGenerator(file_->message_type(i)));
211 : }
212 0 : for (int i = 0; i < file_->extension_count(); ++i) {
213 0 : extension_generators_[i].reset(
214 0 : generator_factory_->NewExtensionGenerator(file_->extension(i)));
215 : }
216 0 : }
217 :
218 0 : FileGenerator::~FileGenerator() {}
219 :
220 0 : bool FileGenerator::Validate(string* error) {
221 : // Check that no class name matches the file's class name. This is a common
222 : // problem that leads to Java compile errors that can be hard to understand.
223 : // It's especially bad when using the java_multiple_files, since we would
224 : // end up overwriting the outer class with one of the inner ones.
225 0 : if (name_resolver_->HasConflictingClassName(file_, classname_)) {
226 0 : error->assign(file_->name());
227 : error->append(
228 0 : ": Cannot generate Java output because the file's outer class name, \"");
229 0 : error->append(classname_);
230 : error->append(
231 : "\", matches the name of one of the types declared inside it. "
232 : "Please either rename the type or use the java_outer_classname "
233 0 : "option to specify a different outer class name for the .proto file.");
234 0 : return false;
235 : }
236 : return true;
237 : }
238 :
239 0 : void FileGenerator::Generate(io::Printer* printer) {
240 : // We don't import anything because we refer to all classes by their
241 : // fully-qualified names in the generated source.
242 : printer->Print(
243 : "// Generated by the protocol buffer compiler. DO NOT EDIT!\n"
244 : "// source: $filename$\n"
245 : "\n",
246 0 : "filename", file_->name());
247 0 : if (!java_package_.empty()) {
248 : printer->Print(
249 : "package $package$;\n"
250 : "\n",
251 0 : "package", java_package_);
252 : }
253 : printer->Print(
254 : "public final class $classname$ {\n"
255 : " private $classname$() {}\n",
256 0 : "classname", classname_);
257 0 : printer->Indent();
258 :
259 : // -----------------------------------------------------------------
260 :
261 : printer->Print(
262 : "public static void registerAllExtensions(\n"
263 : " com.google.protobuf.ExtensionRegistry$lite$ registry) {\n",
264 0 : "lite", HasDescriptorMethods(file_) ? "" : "Lite");
265 :
266 0 : printer->Indent();
267 :
268 0 : for (int i = 0; i < file_->extension_count(); i++) {
269 0 : extension_generators_[i]->GenerateRegistrationCode(printer);
270 : }
271 :
272 0 : for (int i = 0; i < file_->message_type_count(); i++) {
273 0 : message_generators_[i]->GenerateExtensionRegistrationCode(printer);
274 : }
275 :
276 0 : printer->Outdent();
277 : printer->Print(
278 0 : "}\n");
279 :
280 : // -----------------------------------------------------------------
281 :
282 0 : if (!MultipleJavaFiles(file_, immutable_api_)) {
283 0 : for (int i = 0; i < file_->enum_type_count(); i++) {
284 : EnumGenerator(file_->enum_type(i), immutable_api_, context_.get())
285 0 : .Generate(printer);
286 : }
287 0 : for (int i = 0; i < file_->message_type_count(); i++) {
288 0 : message_generators_[i]->GenerateInterface(printer);
289 0 : message_generators_[i]->Generate(printer);
290 : }
291 0 : if (HasGenericServices(file_)) {
292 0 : for (int i = 0; i < file_->service_count(); i++) {
293 : google::protobuf::scoped_ptr<ServiceGenerator> generator(
294 0 : generator_factory_->NewServiceGenerator(file_->service(i)));
295 0 : generator->Generate(printer);
296 : }
297 : }
298 : }
299 :
300 : // Extensions must be generated in the outer class since they are values,
301 : // not classes.
302 0 : for (int i = 0; i < file_->extension_count(); i++) {
303 0 : extension_generators_[i]->Generate(printer);
304 : }
305 :
306 : // Static variables.
307 0 : for (int i = 0; i < file_->message_type_count(); i++) {
308 0 : message_generators_[i]->GenerateStaticVariables(printer);
309 : }
310 :
311 0 : printer->Print("\n");
312 :
313 0 : if (HasDescriptorMethods(file_)) {
314 0 : if (immutable_api_) {
315 0 : GenerateDescriptorInitializationCodeForImmutable(printer);
316 : } else {
317 0 : GenerateDescriptorInitializationCodeForMutable(printer);
318 : }
319 : } else {
320 : printer->Print(
321 0 : "static {\n");
322 0 : printer->Indent();
323 0 : int bytecode_estimate = 0;
324 0 : int method_num = 0;
325 :
326 0 : for (int i = 0; i < file_->message_type_count(); i++) {
327 0 : bytecode_estimate += message_generators_[i]->GenerateStaticVariableInitializers(printer);
328 : MaybeRestartJavaMethod(
329 : printer,
330 : &bytecode_estimate, &method_num,
331 : "_clinit_autosplit_$method_num$();\n",
332 0 : "private static void _clinit_autosplit_$method_num$() {\n");
333 : }
334 :
335 0 : printer->Outdent();
336 : printer->Print(
337 0 : "}\n");
338 : }
339 :
340 : printer->Print(
341 : "\n"
342 0 : "// @@protoc_insertion_point(outer_class_scope)\n");
343 :
344 0 : printer->Outdent();
345 0 : printer->Print("}\n");
346 0 : }
347 :
348 0 : void FileGenerator::GenerateDescriptorInitializationCodeForImmutable(
349 : io::Printer* printer) {
350 : printer->Print(
351 : "public static com.google.protobuf.Descriptors.FileDescriptor\n"
352 : " getDescriptor() {\n"
353 : " return descriptor;\n"
354 : "}\n"
355 : "private static com.google.protobuf.Descriptors.FileDescriptor\n"
356 : " descriptor;\n"
357 0 : "static {\n");
358 0 : printer->Indent();
359 :
360 0 : SharedCodeGenerator shared_code_generator(file_);
361 0 : shared_code_generator.GenerateDescriptors(printer);
362 :
363 0 : int bytecode_estimate = 0;
364 0 : int method_num = 0;
365 :
366 0 : for (int i = 0; i < file_->message_type_count(); i++) {
367 0 : bytecode_estimate += message_generators_[i]->GenerateStaticVariableInitializers(printer);
368 : MaybeRestartJavaMethod(
369 : printer,
370 : &bytecode_estimate, &method_num,
371 : "_clinit_autosplit_dinit_$method_num$();\n",
372 0 : "private static void _clinit_autosplit_dinit_$method_num$() {\n");
373 : }
374 0 : for (int i = 0; i < file_->extension_count(); i++) {
375 0 : bytecode_estimate += extension_generators_[i]->GenerateNonNestedInitializationCode(printer);
376 : MaybeRestartJavaMethod(
377 : printer,
378 : &bytecode_estimate, &method_num,
379 : "_clinit_autosplit_dinit_$method_num$();\n",
380 0 : "private static void _clinit_autosplit_dinit_$method_num$() {\n");
381 : }
382 :
383 : // Proto compiler builds a DescriptorPool, which holds all the descriptors to
384 : // generate, when processing the ".proto" files. We call this DescriptorPool
385 : // the parsed pool (a.k.a. file_->pool()).
386 : //
387 : // Note that when users try to extend the (.*)DescriptorProto in their
388 : // ".proto" files, it does not affect the pre-built FileDescriptorProto class
389 : // in proto compiler. When we put the descriptor data in the file_proto, those
390 : // extensions become unknown fields.
391 : //
392 : // Now we need to find out all the extension value to the (.*)DescriptorProto
393 : // in the file_proto message, and prepare an ExtensionRegistry to return.
394 : //
395 : // To find those extensions, we need to parse the data into a dynamic message
396 : // of the FileDescriptor based on the builder-pool, then we can use
397 : // reflections to find all extension fields
398 0 : FileDescriptorProto file_proto;
399 0 : file_->CopyTo(&file_proto);
400 : string file_data;
401 0 : file_proto.SerializeToString(&file_data);
402 : FieldDescriptorSet extensions;
403 0 : CollectExtensions(file_proto, *file_->pool(), &extensions, file_data);
404 :
405 0 : if (extensions.size() > 0) {
406 : // Must construct an ExtensionRegistry containing all existing extensions
407 : // and use it to parse the descriptor data again to recognize extensions.
408 : printer->Print(
409 : "com.google.protobuf.ExtensionRegistry registry =\n"
410 0 : " com.google.protobuf.ExtensionRegistry.newInstance();\n");
411 : FieldDescriptorSet::iterator it;
412 0 : for (it = extensions.begin(); it != extensions.end(); it++) {
413 : google::protobuf::scoped_ptr<ExtensionGenerator> generator(
414 0 : generator_factory_->NewExtensionGenerator(*it));
415 0 : bytecode_estimate += generator->GenerateRegistrationCode(printer);
416 : MaybeRestartJavaMethod(
417 : printer,
418 : &bytecode_estimate, &method_num,
419 : "_clinit_autosplit_dinit_$method_num$(registry);\n",
420 : "private static void _clinit_autosplit_dinit_$method_num$(\n"
421 0 : " com.google.protobuf.ExtensionRegistry registry) {\n");
422 : }
423 : printer->Print(
424 : "com.google.protobuf.Descriptors.FileDescriptor\n"
425 0 : " .internalUpdateFileDescriptor(descriptor, registry);\n");
426 : }
427 :
428 : // Force descriptor initialization of all dependencies.
429 0 : for (int i = 0; i < file_->dependency_count(); i++) {
430 0 : if (ShouldIncludeDependency(file_->dependency(i), true)) {
431 : string dependency =
432 0 : name_resolver_->GetImmutableClassName(file_->dependency(i));
433 : printer->Print(
434 : "$dependency$.getDescriptor();\n",
435 0 : "dependency", dependency);
436 : }
437 : }
438 :
439 0 : printer->Outdent();
440 : printer->Print(
441 0 : "}\n");
442 0 : }
443 :
444 0 : void FileGenerator::GenerateDescriptorInitializationCodeForMutable(io::Printer* printer) {
445 : printer->Print(
446 : "public static com.google.protobuf.Descriptors.FileDescriptor\n"
447 : " getDescriptor() {\n"
448 : " return descriptor;\n"
449 : "}\n"
450 : "private static com.google.protobuf.Descriptors.FileDescriptor\n"
451 : " descriptor;\n"
452 0 : "static {\n");
453 0 : printer->Indent();
454 :
455 : printer->Print(
456 : "descriptor = $immutable_package$.$descriptor_classname$.descriptor;\n",
457 : "immutable_package", FileJavaPackage(file_, true),
458 0 : "descriptor_classname", name_resolver_->GetDescriptorClassName(file_));
459 :
460 0 : for (int i = 0; i < file_->message_type_count(); i++) {
461 0 : message_generators_[i]->GenerateStaticVariableInitializers(printer);
462 : }
463 0 : for (int i = 0; i < file_->extension_count(); i++) {
464 0 : extension_generators_[i]->GenerateNonNestedInitializationCode(printer);
465 : }
466 :
467 : // Check if custom options exist. If any, try to load immutable classes since
468 : // custom options are only represented with immutable messages.
469 0 : FileDescriptorProto file_proto;
470 0 : file_->CopyTo(&file_proto);
471 : string file_data;
472 0 : file_proto.SerializeToString(&file_data);
473 : FieldDescriptorSet extensions;
474 0 : CollectExtensions(file_proto, *file_->pool(), &extensions, file_data);
475 :
476 0 : if (extensions.size() > 0) {
477 : // Try to load immutable messages' outer class. Its initialization code
478 : // will take care of interpreting custom options.
479 : printer->Print(
480 : "try {\n"
481 : // Note that we have to load the immutable class dynamically here as
482 : // we want the mutable code to be independent from the immutable code
483 : // at compile time. It is required to implement dual-compile for
484 : // mutable and immutable API in blaze.
485 : " java.lang.Class immutableClass = java.lang.Class.forName(\n"
486 : " \"$immutable_classname$\");\n"
487 : "} catch (java.lang.ClassNotFoundException e) {\n"
488 : // The immutable class can not be found. Custom options are left
489 : // as unknown fields.
490 : // TODO(xiaofeng): inform the user with a warning?
491 : "}\n",
492 0 : "immutable_classname", name_resolver_->GetImmutableClassName(file_));
493 : }
494 :
495 : // Force descriptor initialization of all dependencies.
496 0 : for (int i = 0; i < file_->dependency_count(); i++) {
497 0 : if (ShouldIncludeDependency(file_->dependency(i), false)) {
498 : string dependency = name_resolver_->GetMutableClassName(
499 0 : file_->dependency(i));
500 : printer->Print(
501 : "$dependency$.getDescriptor();\n",
502 0 : "dependency", dependency);
503 : }
504 : }
505 :
506 0 : printer->Outdent();
507 : printer->Print(
508 0 : "}\n");
509 0 : }
510 :
511 : template<typename GeneratorClass, typename DescriptorClass>
512 0 : static void GenerateSibling(const string& package_dir,
513 : const string& java_package,
514 0 : const DescriptorClass* descriptor,
515 : GeneratorContext* context,
516 : vector<string>* file_list,
517 : const string& name_suffix,
518 : GeneratorClass* generator,
519 : void (GeneratorClass::*pfn)(io::Printer* printer)) {
520 0 : string filename = package_dir + descriptor->name() + name_suffix + ".java";
521 0 : file_list->push_back(filename);
522 :
523 0 : google::protobuf::scoped_ptr<io::ZeroCopyOutputStream> output(context->Open(filename));
524 0 : io::Printer printer(output.get(), '$');
525 :
526 0 : printer.Print(
527 : "// Generated by the protocol buffer compiler. DO NOT EDIT!\n"
528 : "// source: $filename$\n"
529 : "\n",
530 : "filename", descriptor->file()->name());
531 0 : if (!java_package.empty()) {
532 0 : printer.Print(
533 : "package $package$;\n"
534 : "\n",
535 : "package", java_package);
536 : }
537 :
538 0 : (generator->*pfn)(&printer);
539 0 : }
540 :
541 0 : void FileGenerator::GenerateSiblings(const string& package_dir,
542 : GeneratorContext* context,
543 : vector<string>* file_list) {
544 0 : if (MultipleJavaFiles(file_, immutable_api_)) {
545 0 : for (int i = 0; i < file_->enum_type_count(); i++) {
546 : EnumGenerator generator(file_->enum_type(i), immutable_api_,
547 0 : context_.get());
548 : GenerateSibling<EnumGenerator>(package_dir, java_package_,
549 : file_->enum_type(i),
550 : context, file_list, "",
551 : &generator,
552 0 : &EnumGenerator::Generate);
553 0 : }
554 0 : for (int i = 0; i < file_->message_type_count(); i++) {
555 0 : if (immutable_api_) {
556 : GenerateSibling<MessageGenerator>(package_dir, java_package_,
557 : file_->message_type(i),
558 : context, file_list,
559 : "OrBuilder",
560 0 : message_generators_[i].get(),
561 0 : &MessageGenerator::GenerateInterface);
562 : }
563 : GenerateSibling<MessageGenerator>(package_dir, java_package_,
564 : file_->message_type(i),
565 : context, file_list, "",
566 0 : message_generators_[i].get(),
567 0 : &MessageGenerator::Generate);
568 : }
569 0 : if (HasGenericServices(file_)) {
570 0 : for (int i = 0; i < file_->service_count(); i++) {
571 : google::protobuf::scoped_ptr<ServiceGenerator> generator(
572 0 : generator_factory_->NewServiceGenerator(file_->service(i)));
573 : GenerateSibling<ServiceGenerator>(package_dir, java_package_,
574 : file_->service(i),
575 : context, file_list, "",
576 : generator.get(),
577 0 : &ServiceGenerator::Generate);
578 : }
579 : }
580 : }
581 0 : }
582 :
583 0 : bool FileGenerator::ShouldIncludeDependency(
584 : const FileDescriptor* descriptor, bool immutable_api) {
585 0 : return true;
586 : }
587 :
588 : } // namespace java
589 : } // namespace compiler
590 : } // namespace protobuf
591 : } // namespace google
|