35 #include <google/protobuf/compiler/java/java_file.h>
40 #include <google/protobuf/compiler/java/java_context.h>
41 #include <google/protobuf/compiler/java/java_enum.h>
42 #include <google/protobuf/compiler/java/java_enum_lite.h>
43 #include <google/protobuf/compiler/java/java_extension.h>
44 #include <google/protobuf/compiler/java/java_generator_factory.h>
45 #include <google/protobuf/compiler/java/java_helpers.h>
46 #include <google/protobuf/compiler/java/java_message.h>
47 #include <google/protobuf/compiler/java/java_name_resolver.h>
48 #include <google/protobuf/compiler/java/java_service.h>
49 #include <google/protobuf/compiler/java/java_shared_code_generator.h>
50 #include <google/protobuf/compiler/code_generator.h>
51 #include <google/protobuf/descriptor.pb.h>
52 #include <google/protobuf/io/printer.h>
53 #include <google/protobuf/io/zero_copy_stream.h>
54 #include <google/protobuf/dynamic_message.h>
55 #include <google/protobuf/stubs/strutil.h>
64 struct FieldDescriptorCompare {
72 return f1->full_name() <
f2->full_name();
76 typedef std::set<const FieldDescriptor*, FieldDescriptorCompare>
85 const Reflection* reflection =
message.GetReflection();
88 if (reflection->GetUnknownFields(
message).field_count() > 0)
return false;
90 std::vector<const FieldDescriptor*>
fields;
93 for (
int i = 0;
i <
fields.size();
i++) {
94 if (
fields[i]->is_extension()) {
99 if (
fields[i]->is_repeated()) {
101 for (
int j = 0;
j <
size;
j++) {
104 if (!CollectExtensions(sub_message,
extensions))
return false;
108 if (!CollectExtensions(sub_message,
extensions))
return false;
125 if (!CollectExtensions(file_proto,
extensions)) {
129 const Descriptor* file_proto_desc = alternate_pool.FindMessageTypeByName(
132 <<
"Find unknown fields in FileDescriptorProto when building "
134 <<
". It's likely that those fields are custom options, however, "
135 "descriptor.proto is not in the transitive dependencies. "
136 "This normally should not happen. Please report a bug.";
138 std::unique_ptr<Message> dynamic_file_proto(
139 factory.GetPrototype(file_proto_desc)->New());
148 <<
"Find unknown fields in FileDescriptorProto when building "
150 <<
". It's likely that those fields are custom options, however, "
151 "those options cannot be recognized in the builder pool. "
152 "This normally should not happen. Please report a bug.";
164 void MaybeRestartJavaMethod(
io::Printer* printer,
int* bytecode_estimate,
165 int* method_num,
const char* chain_statement,
166 const char* method_decl) {
173 if ((*bytecode_estimate) > bytesPerMethod) {
175 printer->Print(chain_statement,
"method_num",
StrCat(*method_num));
177 printer->Print(
"}\n");
178 printer->Print(method_decl,
"method_num",
StrCat(*method_num));
180 *bytecode_estimate = 0;
189 message_generators_(
file->message_type_count()),
190 extension_generators_(
file->extension_count()),
192 name_resolver_(
context_->GetNameResolver()),
194 immutable_api_(immutable_api) {
218 ": Cannot generate Java output because the file's outer class name, "
222 "\", matches the name of one of the types declared inside it. "
223 "Please either rename the type or use the java_outer_classname "
224 "option to specify a different outer class name for the .proto file.");
234 <<
"\", matches the name of one of the types declared inside it when "
235 <<
"case is ignored. This can cause compilation issues on Windows / "
236 <<
"MacOS. Please either rename the type or use the "
237 <<
"java_outer_classname option to specify a different outer class "
238 <<
"name for the .proto file to be safe.";
245 <<
"The optimize_for = LITE_RUNTIME option is no longer supported by "
246 <<
"protobuf Java code generator and is ignored--protoc will always "
247 <<
"generate full runtime code for Java. To use Java Lite runtime, "
248 <<
"users should use the Java Lite plugin instead. See:\n"
250 "https://github.com/protocolbuffers/protobuf/blob/master/java/"
260 "// Generated by the protocol buffer compiler. DO NOT EDIT!\n"
261 "// source: $filename$\n"
266 "package $package$;\n"
274 "$deprecation$public final class $classname$ {\n"
275 " private $ctor$() {}\n",
279 printer->Annotate(
"classname",
file_->
name());
285 "public static void registerAllExtensions(\n"
286 " com.google.protobuf.ExtensionRegistryLite registry) {\n");
299 printer->Print(
"}\n");
308 "public static void registerAllExtensions(\n"
309 " com.google.protobuf.ExtensionRegistry registry) {\n"
310 " registerAllExtensions(\n"
311 " (com.google.protobuf.ExtensionRegistryLite) registry);\n"
333 std::unique_ptr<ServiceGenerator> generator(
335 generator->Generate(printer);
349 int static_block_bytecode_estimate = 0;
352 printer, &static_block_bytecode_estimate);
355 printer->Print(
"\n");
364 printer->Print(
"static {\n");
366 int bytecode_estimate = 0;
372 MaybeRestartJavaMethod(
373 printer, &bytecode_estimate, &method_num,
374 "_clinit_autosplit_$method_num$();\n",
375 "private static void _clinit_autosplit_$method_num$() {\n");
379 printer->Print(
"}\n");
384 "// @@protoc_insertion_point(outer_class_scope)\n");
387 printer->Print(
"}\n");
393 "public static com.google.protobuf.Descriptors.FileDescriptor\n"
394 " getDescriptor() {\n"
395 " return descriptor;\n"
397 "private static $final$ com.google.protobuf.Descriptors.FileDescriptor\n"
405 shared_code_generator.GenerateDescriptors(printer);
407 int bytecode_estimate = 0;
413 MaybeRestartJavaMethod(
414 printer, &bytecode_estimate, &method_num,
415 "_clinit_autosplit_dinit_$method_num$();\n",
416 "private static void _clinit_autosplit_dinit_$method_num$() {\n");
421 MaybeRestartJavaMethod(
422 printer, &bytecode_estimate, &method_num,
423 "_clinit_autosplit_dinit_$method_num$();\n",
424 "private static void _clinit_autosplit_dinit_$method_num$() {\n");
445 file_proto.SerializeToString(&
file_data);
453 "com.google.protobuf.ExtensionRegistry registry =\n"
454 " com.google.protobuf.ExtensionRegistry.newInstance();\n");
457 std::unique_ptr<ExtensionGenerator> generator(
459 bytecode_estimate += generator->GenerateRegistrationCode(printer);
460 MaybeRestartJavaMethod(
461 printer, &bytecode_estimate, &method_num,
462 "_clinit_autosplit_dinit_$method_num$(registry);\n",
463 "private static void _clinit_autosplit_dinit_$method_num$(\n"
464 " com.google.protobuf.ExtensionRegistry registry) {\n");
467 "com.google.protobuf.Descriptors.FileDescriptor\n"
468 " .internalUpdateFileDescriptor(descriptor, registry);\n");
476 printer->Print(
"$dependency$.getDescriptor();\n",
"dependency",
482 printer->Print(
"}\n");
488 "public static com.google.protobuf.Descriptors.FileDescriptor\n"
489 " getDescriptor() {\n"
490 " return descriptor;\n"
492 "private static final com.google.protobuf.Descriptors.FileDescriptor\n"
498 "descriptor = $immutable_package$.$descriptor_classname$.descriptor;\n",
514 file_proto.SerializeToString(&
file_data);
527 " java.lang.Class<?> immutableClass = java.lang.Class.forName(\n"
528 " \"$immutable_classname$\");\n"
529 "} catch (java.lang.ClassNotFoundException e) {\n",
536 "com.google.protobuf.ExtensionRegistry registry =\n"
537 " com.google.protobuf.ExtensionRegistry.newInstance();\n"
538 "com.google.protobuf.MessageLite defaultExtensionInstance = null;\n");
543 if (
field->extension_scope() != NULL) {
553 "defaultExtensionInstance = com.google.protobuf.Internal\n"
554 " .getDefaultInstance(\"$class$\");\n"
555 "if (defaultExtensionInstance != null) {\n"
557 " $scope$.getExtensions().get($index$),\n"
558 " (com.google.protobuf.Message) defaultExtensionInstance);\n"
560 "scope", scope,
"index",
StrCat(
field->index()),
"class",
563 printer->Print(
"registry.add($scope$.getExtensions().get($index$));\n",
568 "com.google.protobuf.Descriptors.FileDescriptor\n"
569 " .internalUpdateFileDescriptor(descriptor, registry);\n");
572 printer->Print(
"}\n");
580 printer->Print(
"$dependency$.getDescriptor();\n",
"dependency",
586 printer->Print(
"}\n");
589 template <
typename GeneratorClass,
typename DescriptorClass>
593 std::vector<std::string>*
file_list,
bool annotate_code,
594 std::vector<std::string>* annotation_list,
const std::string& name_suffix,
595 GeneratorClass* generator,
596 void (GeneratorClass::*pfn)(
io::Printer* printer)) {
607 annotate_code ? &annotation_collector : NULL);
610 "// Generated by the protocol buffer compiler. DO NOT EDIT!\n"
611 "// source: $filename$\n"
614 if (!java_package.empty()) {
616 "package $package$;\n"
618 "package", java_package);
621 (generator->*pfn)(&printer);
624 std::unique_ptr<io::ZeroCopyOutputStream> info_output(
625 context->Open(info_full_path));
626 annotations.SerializeToZeroCopyStream(info_output.get());
627 annotation_list->push_back(info_full_path);
634 std::vector<std::string>* annotation_list) {
640 GenerateSibling<EnumGenerator>(
647 GenerateSibling<EnumLiteGenerator>(
655 GenerateSibling<MessageGenerator>(
660 GenerateSibling<MessageGenerator>(
667 std::unique_ptr<ServiceGenerator> generator(
669 GenerateSibling<ServiceGenerator>(
685 std::vector<std::string>* annotation_list) {
690 return std::unique_ptr<io::ZeroCopyOutputStream>(
context->Open(
filename));
704 "//Generated by the protocol buffer compiler. DO NOT EDIT!\n"
705 "// source: $filename$\n"
710 "package $package$;\n"
719 auto info_output = open_file(info_full_path);
720 annotations.SerializeToZeroCopyStream(info_output.get());
721 annotation_list->push_back(info_full_path);
727 bool immutable_api) {