• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_message.h>
36 
37 #include <algorithm>
38 #include <map>
39 #include <memory>
40 #include <vector>
41 
42 #include <google/protobuf/compiler/java/java_context.h>
43 #include <google/protobuf/compiler/java/java_doc_comment.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_builder.h>
49 #include <google/protobuf/compiler/java/java_message_builder_lite.h>
50 #include <google/protobuf/compiler/java/java_name_resolver.h>
51 #include <google/protobuf/descriptor.pb.h>
52 #include <google/protobuf/io/coded_stream.h>
53 #include <google/protobuf/io/printer.h>
54 #include <google/protobuf/descriptor.h>
55 #include <google/protobuf/wire_format.h>
56 #include <google/protobuf/stubs/strutil.h>
57 #include <google/protobuf/stubs/substitute.h>
58 
59 namespace google {
60 namespace protobuf {
61 namespace compiler {
62 namespace java {
63 
64 using internal::WireFormat;
65 using internal::WireFormatLite;
66 
67 namespace {
MapValueImmutableClassdName(const Descriptor * descriptor,ClassNameResolver * name_resolver)68 std::string MapValueImmutableClassdName(const Descriptor* descriptor,
69                                         ClassNameResolver* name_resolver) {
70   const FieldDescriptor* value_field = descriptor->FindFieldByName("value");
71   GOOGLE_CHECK_EQ(FieldDescriptor::TYPE_MESSAGE, value_field->type());
72   return name_resolver->GetImmutableClassName(value_field->message_type());
73 }
74 }  // namespace
75 
76 // ===================================================================
77 
MessageGenerator(const Descriptor * descriptor)78 MessageGenerator::MessageGenerator(const Descriptor* descriptor)
79     : descriptor_(descriptor) {
80   for (int i = 0; i < descriptor_->field_count(); i++) {
81     if (IsRealOneof(descriptor_->field(i))) {
82       oneofs_.insert(descriptor_->field(i)->containing_oneof());
83     }
84   }
85 }
86 
~MessageGenerator()87 MessageGenerator::~MessageGenerator() {}
88 
89 // ===================================================================
ImmutableMessageGenerator(const Descriptor * descriptor,Context * context)90 ImmutableMessageGenerator::ImmutableMessageGenerator(
91     const Descriptor* descriptor, Context* context)
92     : MessageGenerator(descriptor),
93       context_(context),
94       name_resolver_(context->GetNameResolver()),
95       field_generators_(descriptor, context_) {
96   GOOGLE_CHECK(HasDescriptorMethods(descriptor->file(), context->EnforceLite()))
97       << "Generator factory error: A non-lite message generator is used to "
98          "generate lite messages.";
99 }
100 
~ImmutableMessageGenerator()101 ImmutableMessageGenerator::~ImmutableMessageGenerator() {}
102 
GenerateStaticVariables(io::Printer * printer,int * bytecode_estimate)103 void ImmutableMessageGenerator::GenerateStaticVariables(
104     io::Printer* printer, int* bytecode_estimate) {
105   // Because descriptor.proto (com.google.protobuf.DescriptorProtos) is
106   // used in the construction of descriptors, we have a tricky bootstrapping
107   // problem.  To help control static initialization order, we make sure all
108   // descriptors and other static data that depends on them are members of
109   // the outermost class in the file.  This way, they will be initialized in
110   // a deterministic order.
111 
112   std::map<std::string, std::string> vars;
113   vars["identifier"] = UniqueFileScopeIdentifier(descriptor_);
114   vars["index"] = StrCat(descriptor_->index());
115   vars["classname"] = name_resolver_->GetImmutableClassName(descriptor_);
116   if (descriptor_->containing_type() != NULL) {
117     vars["parent"] = UniqueFileScopeIdentifier(descriptor_->containing_type());
118   }
119   if (MultipleJavaFiles(descriptor_->file(), /* immutable = */ true)) {
120     // We can only make these package-private since the classes that use them
121     // are in separate files.
122     vars["private"] = "";
123   } else {
124     vars["private"] = "private ";
125   }
126   if (*bytecode_estimate <= kMaxStaticSize) {
127     vars["final"] = "final ";
128   } else {
129     vars["final"] = "";
130   }
131 
132   // The descriptor for this type.
133   printer->Print(
134       vars,
135       // TODO(teboring): final needs to be added back. The way to fix it is to
136       // generate methods that can construct the types, and then still declare
137       // the types, and then init them in clinit with the new method calls.
138       "$private$static $final$com.google.protobuf.Descriptors.Descriptor\n"
139       "  internal_$identifier$_descriptor;\n");
140   *bytecode_estimate += 30;
141 
142   // And the FieldAccessorTable.
143   GenerateFieldAccessorTable(printer, bytecode_estimate);
144 
145   // Generate static members for all nested types.
146   for (int i = 0; i < descriptor_->nested_type_count(); i++) {
147     // TODO(kenton):  Reuse MessageGenerator objects?
148     ImmutableMessageGenerator(descriptor_->nested_type(i), context_)
149         .GenerateStaticVariables(printer, bytecode_estimate);
150   }
151 }
152 
GenerateStaticVariableInitializers(io::Printer * printer)153 int ImmutableMessageGenerator::GenerateStaticVariableInitializers(
154     io::Printer* printer) {
155   int bytecode_estimate = 0;
156   std::map<std::string, std::string> vars;
157   vars["identifier"] = UniqueFileScopeIdentifier(descriptor_);
158   vars["index"] = StrCat(descriptor_->index());
159   vars["classname"] = name_resolver_->GetImmutableClassName(descriptor_);
160   if (descriptor_->containing_type() != NULL) {
161     vars["parent"] = UniqueFileScopeIdentifier(descriptor_->containing_type());
162   }
163 
164   // The descriptor for this type.
165   if (descriptor_->containing_type() == NULL) {
166     printer->Print(vars,
167                    "internal_$identifier$_descriptor =\n"
168                    "  getDescriptor().getMessageTypes().get($index$);\n");
169     bytecode_estimate += 30;
170   } else {
171     printer->Print(
172         vars,
173         "internal_$identifier$_descriptor =\n"
174         "  internal_$parent$_descriptor.getNestedTypes().get($index$);\n");
175     bytecode_estimate += 30;
176   }
177 
178   // And the FieldAccessorTable.
179   bytecode_estimate += GenerateFieldAccessorTableInitializer(printer);
180 
181   // Generate static member initializers for all nested types.
182   for (int i = 0; i < descriptor_->nested_type_count(); i++) {
183     // TODO(kenton):  Reuse MessageGenerator objects?
184     bytecode_estimate +=
185         ImmutableMessageGenerator(descriptor_->nested_type(i), context_)
186             .GenerateStaticVariableInitializers(printer);
187   }
188   return bytecode_estimate;
189 }
190 
GenerateFieldAccessorTable(io::Printer * printer,int * bytecode_estimate)191 void ImmutableMessageGenerator::GenerateFieldAccessorTable(
192     io::Printer* printer, int* bytecode_estimate) {
193   std::map<std::string, std::string> vars;
194   vars["identifier"] = UniqueFileScopeIdentifier(descriptor_);
195   if (MultipleJavaFiles(descriptor_->file(), /* immutable = */ true)) {
196     // We can only make these package-private since the classes that use them
197     // are in separate files.
198     vars["private"] = "";
199   } else {
200     vars["private"] = "private ";
201   }
202   if (*bytecode_estimate <= kMaxStaticSize) {
203     vars["final"] = "final ";
204   } else {
205     vars["final"] = "";
206   }
207   vars["ver"] = GeneratedCodeVersionSuffix();
208   printer->Print(
209       vars,
210       "$private$static $final$\n"
211       "  com.google.protobuf.GeneratedMessage$ver$.FieldAccessorTable\n"
212       "    internal_$identifier$_fieldAccessorTable;\n");
213 
214   // 6 bytes per field and oneof
215   *bytecode_estimate +=
216       10 + 6 * descriptor_->field_count() + 6 * oneofs_.size();
217 }
218 
GenerateFieldAccessorTableInitializer(io::Printer * printer)219 int ImmutableMessageGenerator::GenerateFieldAccessorTableInitializer(
220     io::Printer* printer) {
221   int bytecode_estimate = 10;
222   printer->Print(
223       "internal_$identifier$_fieldAccessorTable = new\n"
224       "  com.google.protobuf.GeneratedMessage$ver$.FieldAccessorTable(\n"
225       "    internal_$identifier$_descriptor,\n"
226       "    new java.lang.String[] { ",
227       "identifier", UniqueFileScopeIdentifier(descriptor_), "ver",
228       GeneratedCodeVersionSuffix());
229   for (int i = 0; i < descriptor_->field_count(); i++) {
230     const FieldDescriptor* field = descriptor_->field(i);
231     const FieldGeneratorInfo* info = context_->GetFieldGeneratorInfo(field);
232     bytecode_estimate += 6;
233     printer->Print("\"$field_name$\", ", "field_name", info->capitalized_name);
234   }
235   // We reproduce synthetic oneofs here since proto reflection needs these.
236   for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
237     const OneofDescriptor* oneof = descriptor_->oneof_decl(i);
238     const OneofGeneratorInfo* info = context_->GetOneofGeneratorInfo(oneof);
239     bytecode_estimate += 6;
240     printer->Print("\"$oneof_name$\", ", "oneof_name", info->capitalized_name);
241   }
242   printer->Print("});\n");
243   return bytecode_estimate;
244 }
245 
246 // ===================================================================
247 
GenerateInterface(io::Printer * printer)248 void ImmutableMessageGenerator::GenerateInterface(io::Printer* printer) {
249   MaybePrintGeneratedAnnotation(context_, printer, descriptor_,
250                                 /* immutable = */ true, "OrBuilder");
251   if (descriptor_->extension_range_count() > 0) {
252     printer->Print(
253         "$deprecation$public interface ${$$classname$OrBuilder$}$ extends\n"
254         "    $extra_interfaces$\n"
255         "    com.google.protobuf.GeneratedMessage$ver$.\n"
256         "        ExtendableMessageOrBuilder<$classname$> {\n",
257         "deprecation",
258         descriptor_->options().deprecated() ? "@java.lang.Deprecated " : "",
259         "extra_interfaces", ExtraMessageOrBuilderInterfaces(descriptor_),
260         "classname", descriptor_->name(), "{", "", "}", "", "ver",
261         GeneratedCodeVersionSuffix());
262   } else {
263     printer->Print(
264         "$deprecation$public interface ${$$classname$OrBuilder$}$ extends\n"
265         "    $extra_interfaces$\n"
266         "    com.google.protobuf.MessageOrBuilder {\n",
267         "deprecation",
268         descriptor_->options().deprecated() ? "@java.lang.Deprecated " : "",
269         "extra_interfaces", ExtraMessageOrBuilderInterfaces(descriptor_),
270         "classname", descriptor_->name(), "{", "", "}", "");
271   }
272   printer->Annotate("{", "}", descriptor_);
273 
274   printer->Indent();
275   for (int i = 0; i < descriptor_->field_count(); i++) {
276     printer->Print("\n");
277     field_generators_.get(descriptor_->field(i))
278         .GenerateInterfaceMembers(printer);
279   }
280   for (auto oneof : oneofs_) {
281     printer->Print(
282         "\n"
283         "public $classname$.$oneof_capitalized_name$Case "
284         "get$oneof_capitalized_name$Case();\n",
285         "oneof_capitalized_name",
286         context_->GetOneofGeneratorInfo(oneof)->capitalized_name, "classname",
287         context_->GetNameResolver()->GetImmutableClassName(descriptor_));
288   }
289   printer->Outdent();
290 
291   printer->Print("}\n");
292 }
293 
294 // ===================================================================
295 
Generate(io::Printer * printer)296 void ImmutableMessageGenerator::Generate(io::Printer* printer) {
297   bool is_own_file = IsOwnFile(descriptor_, /* immutable = */ true);
298 
299   std::map<std::string, std::string> variables;
300   variables["static"] = is_own_file ? "" : "static ";
301   variables["classname"] = descriptor_->name();
302   variables["extra_interfaces"] = ExtraMessageInterfaces(descriptor_);
303   variables["ver"] = GeneratedCodeVersionSuffix();
304   variables["deprecation"] =
305       descriptor_->options().deprecated() ? "@java.lang.Deprecated " : "";
306 
307   WriteMessageDocComment(printer, descriptor_);
308   MaybePrintGeneratedAnnotation(context_, printer, descriptor_,
309                                 /* immutable = */ true);
310 
311   // The builder_type stores the super type name of the nested Builder class.
312   std::string builder_type;
313   if (descriptor_->extension_range_count() > 0) {
314     printer->Print(
315         variables,
316         "$deprecation$public $static$final class $classname$ extends\n");
317     printer->Annotate("classname", descriptor_);
318     printer->Print(
319         variables,
320         "    com.google.protobuf.GeneratedMessage$ver$.ExtendableMessage<\n"
321         "      $classname$> implements\n"
322         "    $extra_interfaces$\n"
323         "    $classname$OrBuilder {\n");
324     builder_type = strings::Substitute(
325         "com.google.protobuf.GeneratedMessage$1.ExtendableBuilder<$0, ?>",
326         name_resolver_->GetImmutableClassName(descriptor_),
327         GeneratedCodeVersionSuffix());
328   } else {
329     printer->Print(
330         variables,
331         "$deprecation$public $static$final class $classname$ extends\n");
332     printer->Annotate("classname", descriptor_);
333     printer->Print(variables,
334                    "    com.google.protobuf.GeneratedMessage$ver$ implements\n"
335                    "    $extra_interfaces$\n"
336                    "    $classname$OrBuilder {\n");
337     builder_type =
338         strings::Substitute("com.google.protobuf.GeneratedMessage$0.Builder<?>",
339                          GeneratedCodeVersionSuffix());
340   }
341   printer->Print("private static final long serialVersionUID = 0L;\n");
342 
343   printer->Indent();
344   // Using builder_type, instead of Builder, prevents the Builder class from
345   // being loaded into PermGen space when the default instance is created.
346   // This optimizes the PermGen space usage for clients that do not modify
347   // messages.
348   printer->Print(
349       "// Use $classname$.newBuilder() to construct.\n"
350       "private $classname$($buildertype$ builder) {\n"
351       "  super(builder);\n"
352       "}\n",
353       "classname", descriptor_->name(), "buildertype", builder_type);
354   printer->Print("private $classname$() {\n", "classname", descriptor_->name());
355   printer->Indent();
356   GenerateInitializers(printer);
357   printer->Outdent();
358   printer->Print(
359       "}\n"
360       "\n");
361 
362   printer->Print(variables,
363                  "@java.lang.Override\n"
364                  "@SuppressWarnings({\"unused\"})\n"
365                  "protected java.lang.Object newInstance(\n"
366                  "    UnusedPrivateParameter unused) {\n"
367                  "  return new $classname$();\n"
368                  "}\n"
369                  "\n");
370 
371   // TODO(b/248149118): Remove this superfluous override.
372   printer->Print(
373       "@java.lang.Override\n"
374       "public final com.google.protobuf.UnknownFieldSet\n"
375       "getUnknownFields() {\n"
376       "  return this.unknownFields;\n"
377       "}\n");
378 
379   GenerateDescriptorMethods(printer);
380 
381   // Nested types
382   for (int i = 0; i < descriptor_->enum_type_count(); i++) {
383     EnumGenerator(descriptor_->enum_type(i), true, context_).Generate(printer);
384   }
385 
386   for (int i = 0; i < descriptor_->nested_type_count(); i++) {
387     // Don't generate Java classes for map entry messages.
388     if (IsMapEntry(descriptor_->nested_type(i))) continue;
389     ImmutableMessageGenerator messageGenerator(descriptor_->nested_type(i),
390                                                context_);
391     messageGenerator.GenerateInterface(printer);
392     messageGenerator.Generate(printer);
393   }
394 
395   // Integers for bit fields.
396   int totalBits = 0;
397   for (int i = 0; i < descriptor_->field_count(); i++) {
398     totalBits +=
399         field_generators_.get(descriptor_->field(i)).GetNumBitsForMessage();
400   }
401   int totalInts = (totalBits + 31) / 32;
402   for (int i = 0; i < totalInts; i++) {
403     printer->Print("private int $bit_field_name$;\n", "bit_field_name",
404                    GetBitFieldName(i));
405   }
406 
407   // oneof
408   std::map<std::string, std::string> vars;
409   for (auto oneof : oneofs_) {
410     vars["oneof_name"] = context_->GetOneofGeneratorInfo(oneof)->name;
411     vars["oneof_capitalized_name"] =
412         context_->GetOneofGeneratorInfo(oneof)->capitalized_name;
413     vars["oneof_index"] = StrCat((oneof)->index());
414     // oneofCase_ and oneof_
415     printer->Print(vars,
416                    "private int $oneof_name$Case_ = 0;\n"
417                    "private java.lang.Object $oneof_name$_;\n");
418     // OneofCase enum
419     printer->Print(
420         vars,
421         "public enum $oneof_capitalized_name$Case\n"
422         // TODO(dweis): Remove EnumLite when we want to break compatibility with
423         // 3.x users
424         "    implements com.google.protobuf.Internal.EnumLite,\n"
425         "        com.google.protobuf.AbstractMessage.InternalOneOfEnum {\n");
426     printer->Indent();
427     for (int j = 0; j < (oneof)->field_count(); j++) {
428       const FieldDescriptor* field = (oneof)->field(j);
429       printer->Print(
430           "$deprecation$$field_name$($field_number$),\n", "deprecation",
431           field->options().deprecated() ? "@java.lang.Deprecated " : "",
432           "field_name", ToUpper(field->name()), "field_number",
433           StrCat(field->number()));
434     }
435     printer->Print("$cap_oneof_name$_NOT_SET(0);\n", "cap_oneof_name",
436                    ToUpper(vars["oneof_name"]));
437     printer->Print(vars,
438                    "private final int value;\n"
439                    "private $oneof_capitalized_name$Case(int value) {\n"
440                    "  this.value = value;\n"
441                    "}\n");
442     printer->Print(
443         vars,
444         "/**\n"
445         " * @param value The number of the enum to look for.\n"
446         " * @return The enum associated with the given number.\n"
447         " * @deprecated Use {@link #forNumber(int)} instead.\n"
448         " */\n"
449         "@java.lang.Deprecated\n"
450         "public static $oneof_capitalized_name$Case valueOf(int value) {\n"
451         "  return forNumber(value);\n"
452         "}\n"
453         "\n"
454         "public static $oneof_capitalized_name$Case forNumber(int value) {\n"
455         "  switch (value) {\n");
456     for (int j = 0; j < (oneof)->field_count(); j++) {
457       const FieldDescriptor* field = (oneof)->field(j);
458       printer->Print("    case $field_number$: return $field_name$;\n",
459                      "field_number", StrCat(field->number()),
460                      "field_name", ToUpper(field->name()));
461     }
462     printer->Print(
463         "    case 0: return $cap_oneof_name$_NOT_SET;\n"
464         "    default: return null;\n"
465         "  }\n"
466         "}\n"
467         "public int getNumber() {\n"
468         "  return this.value;\n"
469         "}\n",
470         "cap_oneof_name", ToUpper(vars["oneof_name"]));
471     printer->Outdent();
472     printer->Print("};\n\n");
473     // oneofCase()
474     printer->Print(vars,
475                    "public $oneof_capitalized_name$Case\n"
476                    "get$oneof_capitalized_name$Case() {\n"
477                    "  return $oneof_capitalized_name$Case.forNumber(\n"
478                    "      $oneof_name$Case_);\n"
479                    "}\n"
480                    "\n");
481   }
482 
483   if (IsAnyMessage(descriptor_)) {
484     GenerateAnyMethods(printer);
485   }
486 
487   // Fields
488   for (int i = 0; i < descriptor_->field_count(); i++) {
489     printer->Print("public static final int $constant_name$ = $number$;\n",
490                    "constant_name", FieldConstantName(descriptor_->field(i)),
491                    "number", StrCat(descriptor_->field(i)->number()));
492     field_generators_.get(descriptor_->field(i)).GenerateMembers(printer);
493     printer->Print("\n");
494   }
495 
496   if (context_->HasGeneratedMethods(descriptor_)) {
497     GenerateIsInitialized(printer);
498     GenerateMessageSerializationMethods(printer);
499     GenerateEqualsAndHashCode(printer);
500   }
501 
502 
503   GenerateParseFromMethods(printer);
504   GenerateBuilder(printer);
505 
506   printer->Print(
507       "\n"
508       "// @@protoc_insertion_point(class_scope:$full_name$)\n",
509       "full_name", descriptor_->full_name());
510 
511   // Carefully initialize the default instance in such a way that it doesn't
512   // conflict with other initialization.
513   printer->Print("private static final $classname$ DEFAULT_INSTANCE;\n",
514                  "classname",
515                  name_resolver_->GetImmutableClassName(descriptor_));
516   printer->Print(
517       "static {\n"
518       "  DEFAULT_INSTANCE = new $classname$();\n"
519       "}\n"
520       "\n",
521       "classname", name_resolver_->GetImmutableClassName(descriptor_));
522 
523   printer->Print(
524       "public static $classname$ getDefaultInstance() {\n"
525       "  return DEFAULT_INSTANCE;\n"
526       "}\n"
527       "\n",
528       "classname", name_resolver_->GetImmutableClassName(descriptor_));
529 
530   // 'of' method for Wrappers
531   if (IsWrappersProtoFile(descriptor_->file())) {
532     printer->Print(
533         "public static $classname$ of($field_type$ value) {\n"
534         "  return newBuilder().setValue(value).build();\n"
535         "}\n"
536         "\n",
537         "classname", name_resolver_->GetImmutableClassName(descriptor_),
538         "field_type", PrimitiveTypeName(GetJavaType(descriptor_->field(0))));
539   }
540 
541   GenerateParser(printer);
542 
543   printer->Print(
544       "@java.lang.Override\n"
545       "public $classname$ getDefaultInstanceForType() {\n"
546       "  return DEFAULT_INSTANCE;\n"
547       "}\n"
548       "\n",
549       "classname", name_resolver_->GetImmutableClassName(descriptor_));
550 
551   // Extensions must be declared after the DEFAULT_INSTANCE is initialized
552   // because the DEFAULT_INSTANCE is used by the extension to lazily retrieve
553   // the outer class's FileDescriptor.
554   for (int i = 0; i < descriptor_->extension_count(); i++) {
555     ImmutableExtensionGenerator(descriptor_->extension(i), context_)
556         .Generate(printer);
557   }
558 
559   printer->Outdent();
560   printer->Print("}\n\n");
561 }
562 
563 // ===================================================================
564 
GenerateMessageSerializationMethods(io::Printer * printer)565 void ImmutableMessageGenerator::GenerateMessageSerializationMethods(
566     io::Printer* printer) {
567   std::unique_ptr<const FieldDescriptor*[]> sorted_fields(
568       SortFieldsByNumber(descriptor_));
569 
570   std::vector<const Descriptor::ExtensionRange*> sorted_extensions;
571   for (int i = 0; i < descriptor_->extension_range_count(); ++i) {
572     sorted_extensions.push_back(descriptor_->extension_range(i));
573   }
574   std::sort(sorted_extensions.begin(), sorted_extensions.end(),
575             ExtensionRangeOrdering());
576   printer->Print(
577       "@java.lang.Override\n"
578       "public void writeTo(com.google.protobuf.CodedOutputStream output)\n"
579       "                    throws java.io.IOException {\n");
580   printer->Indent();
581 
582   if (HasPackedFields(descriptor_)) {
583     // writeTo(CodedOutputStream output) might be invoked without
584     // getSerializedSize() ever being called, but we need the memoized
585     // sizes in case this message has packed fields. Rather than emit checks
586     // for each packed field, just call getSerializedSize() up front. In most
587     // cases, getSerializedSize() will have already been called anyway by one
588     // of the wrapper writeTo() methods, making this call cheap.
589     printer->Print("getSerializedSize();\n");
590   }
591 
592   if (descriptor_->extension_range_count() > 0) {
593     if (descriptor_->options().message_set_wire_format()) {
594       printer->Print(
595           "com.google.protobuf.GeneratedMessage$ver$\n"
596           "  .ExtendableMessage<$classname$>.ExtensionWriter\n"
597           "    extensionWriter = newMessageSetExtensionWriter();\n",
598           "classname", name_resolver_->GetImmutableClassName(descriptor_),
599           "ver", GeneratedCodeVersionSuffix());
600     } else {
601       printer->Print(
602           "com.google.protobuf.GeneratedMessage$ver$\n"
603           "  .ExtendableMessage<$classname$>.ExtensionWriter\n"
604           "    extensionWriter = newExtensionWriter();\n",
605           "classname", name_resolver_->GetImmutableClassName(descriptor_),
606           "ver", GeneratedCodeVersionSuffix());
607     }
608   }
609 
610   // Merge the fields and the extension ranges, both sorted by field number.
611   for (int i = 0, j = 0;
612        i < descriptor_->field_count() || j < sorted_extensions.size();) {
613     if (i == descriptor_->field_count()) {
614       GenerateSerializeOneExtensionRange(printer, sorted_extensions[j++]);
615     } else if (j == sorted_extensions.size()) {
616       GenerateSerializeOneField(printer, sorted_fields[i++]);
617     } else if (sorted_fields[i]->number() < sorted_extensions[j]->start) {
618       GenerateSerializeOneField(printer, sorted_fields[i++]);
619     } else {
620       GenerateSerializeOneExtensionRange(printer, sorted_extensions[j++]);
621     }
622   }
623 
624   if (descriptor_->options().message_set_wire_format()) {
625     printer->Print("getUnknownFields().writeAsMessageSetTo(output);\n");
626   } else {
627     printer->Print("getUnknownFields().writeTo(output);\n");
628   }
629 
630   printer->Outdent();
631   printer->Print(
632       "}\n"
633       "\n"
634       "@java.lang.Override\n"
635       "public int getSerializedSize() {\n"
636       "  int size = memoizedSize;\n"
637       "  if (size != -1) return size;\n"
638       "\n");
639   printer->Indent();
640 
641   printer->Print("size = 0;\n");
642 
643   for (int i = 0; i < descriptor_->field_count(); i++) {
644     field_generators_.get(sorted_fields[i]).GenerateSerializedSizeCode(printer);
645   }
646 
647   if (descriptor_->extension_range_count() > 0) {
648     if (descriptor_->options().message_set_wire_format()) {
649       printer->Print("size += extensionsSerializedSizeAsMessageSet();\n");
650     } else {
651       printer->Print("size += extensionsSerializedSize();\n");
652     }
653   }
654 
655   if (descriptor_->options().message_set_wire_format()) {
656     printer->Print(
657         "size += getUnknownFields().getSerializedSizeAsMessageSet();\n");
658   } else {
659     printer->Print("size += getUnknownFields().getSerializedSize();\n");
660   }
661 
662   printer->Print(
663       "memoizedSize = size;\n"
664       "return size;\n");
665 
666   printer->Outdent();
667   printer->Print(
668       "}\n"
669       "\n");
670 }
671 
GenerateParseFromMethods(io::Printer * printer)672 void ImmutableMessageGenerator::GenerateParseFromMethods(io::Printer* printer) {
673   // Note:  These are separate from GenerateMessageSerializationMethods()
674   //   because they need to be generated even for messages that are optimized
675   //   for code size.
676   printer->Print(
677       "public static $classname$ parseFrom(\n"
678       "    java.nio.ByteBuffer data)\n"
679       "    throws com.google.protobuf.InvalidProtocolBufferException {\n"
680       "  return PARSER.parseFrom(data);\n"
681       "}\n"
682       "public static $classname$ parseFrom(\n"
683       "    java.nio.ByteBuffer data,\n"
684       "    com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n"
685       "    throws com.google.protobuf.InvalidProtocolBufferException {\n"
686       "  return PARSER.parseFrom(data, extensionRegistry);\n"
687       "}\n"
688       "public static $classname$ parseFrom(\n"
689       "    com.google.protobuf.ByteString data)\n"
690       "    throws com.google.protobuf.InvalidProtocolBufferException {\n"
691       "  return PARSER.parseFrom(data);\n"
692       "}\n"
693       "public static $classname$ parseFrom(\n"
694       "    com.google.protobuf.ByteString data,\n"
695       "    com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n"
696       "    throws com.google.protobuf.InvalidProtocolBufferException {\n"
697       "  return PARSER.parseFrom(data, extensionRegistry);\n"
698       "}\n"
699       "public static $classname$ parseFrom(byte[] data)\n"
700       "    throws com.google.protobuf.InvalidProtocolBufferException {\n"
701       "  return PARSER.parseFrom(data);\n"
702       "}\n"
703       "public static $classname$ parseFrom(\n"
704       "    byte[] data,\n"
705       "    com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n"
706       "    throws com.google.protobuf.InvalidProtocolBufferException {\n"
707       "  return PARSER.parseFrom(data, extensionRegistry);\n"
708       "}\n"
709       "public static $classname$ parseFrom(java.io.InputStream input)\n"
710       "    throws java.io.IOException {\n"
711       "  return com.google.protobuf.GeneratedMessage$ver$\n"
712       "      .parseWithIOException(PARSER, input);\n"
713       "}\n"
714       "public static $classname$ parseFrom(\n"
715       "    java.io.InputStream input,\n"
716       "    com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n"
717       "    throws java.io.IOException {\n"
718       "  return com.google.protobuf.GeneratedMessage$ver$\n"
719       "      .parseWithIOException(PARSER, input, extensionRegistry);\n"
720       "}\n"
721       "public static $classname$ parseDelimitedFrom(java.io.InputStream "
722       "input)\n"
723       "    throws java.io.IOException {\n"
724       "  return com.google.protobuf.GeneratedMessage$ver$\n"
725       "      .parseDelimitedWithIOException(PARSER, input);\n"
726       "}\n"
727       "public static $classname$ parseDelimitedFrom(\n"
728       "    java.io.InputStream input,\n"
729       "    com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n"
730       "    throws java.io.IOException {\n"
731       "  return com.google.protobuf.GeneratedMessage$ver$\n"
732       "      .parseDelimitedWithIOException(PARSER, input, "
733       "extensionRegistry);\n"
734       "}\n"
735       "public static $classname$ parseFrom(\n"
736       "    com.google.protobuf.CodedInputStream input)\n"
737       "    throws java.io.IOException {\n"
738       "  return com.google.protobuf.GeneratedMessage$ver$\n"
739       "      .parseWithIOException(PARSER, input);\n"
740       "}\n"
741       "public static $classname$ parseFrom(\n"
742       "    com.google.protobuf.CodedInputStream input,\n"
743       "    com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n"
744       "    throws java.io.IOException {\n"
745       "  return com.google.protobuf.GeneratedMessage$ver$\n"
746       "      .parseWithIOException(PARSER, input, extensionRegistry);\n"
747       "}\n"
748       "\n",
749       "classname", name_resolver_->GetImmutableClassName(descriptor_), "ver",
750       GeneratedCodeVersionSuffix());
751 }
752 
GenerateSerializeOneField(io::Printer * printer,const FieldDescriptor * field)753 void ImmutableMessageGenerator::GenerateSerializeOneField(
754     io::Printer* printer, const FieldDescriptor* field) {
755   field_generators_.get(field).GenerateSerializationCode(printer);
756 }
757 
GenerateSerializeOneExtensionRange(io::Printer * printer,const Descriptor::ExtensionRange * range)758 void ImmutableMessageGenerator::GenerateSerializeOneExtensionRange(
759     io::Printer* printer, const Descriptor::ExtensionRange* range) {
760   printer->Print("extensionWriter.writeUntil($end$, output);\n", "end",
761                  StrCat(range->end));
762 }
763 
764 // ===================================================================
765 
GenerateBuilder(io::Printer * printer)766 void ImmutableMessageGenerator::GenerateBuilder(io::Printer* printer) {
767   // LITE_RUNTIME implements this at the GeneratedMessageLite level.
768   printer->Print(
769       "@java.lang.Override\n"
770       "public Builder newBuilderForType() { return newBuilder(); }\n");
771 
772   printer->Print(
773       "public static Builder newBuilder() {\n"
774       "  return DEFAULT_INSTANCE.toBuilder();\n"
775       "}\n"
776       "public static Builder newBuilder($classname$ prototype) {\n"
777       "  return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);\n"
778       "}\n"
779       "@java.lang.Override\n"
780       "public Builder toBuilder() {\n"
781       "  return this == DEFAULT_INSTANCE\n"
782       "      ? new Builder() : new Builder().mergeFrom(this);\n"
783       "}\n"
784       "\n",
785       "classname", name_resolver_->GetImmutableClassName(descriptor_));
786 
787   printer->Print(
788       "@java.lang.Override\n"
789       "protected Builder newBuilderForType(\n"
790       "    com.google.protobuf.GeneratedMessage$ver$.BuilderParent parent) {\n"
791       "  Builder builder = new Builder(parent);\n"
792       "  return builder;\n"
793       "}\n",
794       "ver", GeneratedCodeVersionSuffix());
795 
796   MessageBuilderGenerator builderGenerator(descriptor_, context_);
797   builderGenerator.Generate(printer);
798 }
799 
GenerateDescriptorMethods(io::Printer * printer)800 void ImmutableMessageGenerator::GenerateDescriptorMethods(
801     io::Printer* printer) {
802   if (!descriptor_->options().no_standard_descriptor_accessor()) {
803     printer->Print(
804         "public static final com.google.protobuf.Descriptors.Descriptor\n"
805         "    getDescriptor() {\n"
806         "  return $fileclass$.internal_$identifier$_descriptor;\n"
807         "}\n"
808         "\n",
809         "fileclass", name_resolver_->GetImmutableClassName(descriptor_->file()),
810         "identifier", UniqueFileScopeIdentifier(descriptor_));
811   }
812   std::vector<const FieldDescriptor*> map_fields;
813   for (int i = 0; i < descriptor_->field_count(); i++) {
814     const FieldDescriptor* field = descriptor_->field(i);
815     if (GetJavaType(field) == JAVATYPE_MESSAGE &&
816         IsMapEntry(field->message_type())) {
817       map_fields.push_back(field);
818     }
819   }
820   if (!map_fields.empty()) {
821     printer->Print(
822         "@SuppressWarnings({\"rawtypes\"})\n"
823         "@java.lang.Override\n"
824         "protected com.google.protobuf.MapField internalGetMapField(\n"
825         "    int number) {\n"
826         "  switch (number) {\n");
827     printer->Indent();
828     printer->Indent();
829     for (int i = 0; i < map_fields.size(); ++i) {
830       const FieldDescriptor* field = map_fields[i];
831       const FieldGeneratorInfo* info = context_->GetFieldGeneratorInfo(field);
832       printer->Print(
833           "case $number$:\n"
834           "  return internalGet$capitalized_name$();\n",
835           "number", StrCat(field->number()), "capitalized_name",
836           info->capitalized_name);
837     }
838     printer->Print(
839         "default:\n"
840         "  throw new RuntimeException(\n"
841         "      \"Invalid map field number: \" + number);\n");
842     printer->Outdent();
843     printer->Outdent();
844     printer->Print(
845         "  }\n"
846         "}\n");
847   }
848   printer->Print(
849       "@java.lang.Override\n"
850       "protected com.google.protobuf.GeneratedMessage$ver$.FieldAccessorTable\n"
851       "    internalGetFieldAccessorTable() {\n"
852       "  return $fileclass$.internal_$identifier$_fieldAccessorTable\n"
853       "      .ensureFieldAccessorsInitialized(\n"
854       "          $classname$.class, $classname$.Builder.class);\n"
855       "}\n"
856       "\n",
857       "classname", name_resolver_->GetImmutableClassName(descriptor_),
858       "fileclass", name_resolver_->GetImmutableClassName(descriptor_->file()),
859       "identifier", UniqueFileScopeIdentifier(descriptor_), "ver",
860       GeneratedCodeVersionSuffix());
861 }
862 
863 // ===================================================================
864 
GenerateIsInitialized(io::Printer * printer)865 void ImmutableMessageGenerator::GenerateIsInitialized(io::Printer* printer) {
866   // Memoizes whether the protocol buffer is fully initialized (has all
867   // required fields). -1 means not yet computed. 0 means false and 1 means
868   // true.
869   printer->Print("private byte memoizedIsInitialized = -1;\n");
870   printer->Print(
871       "@java.lang.Override\n"
872       "public final boolean isInitialized() {\n");
873   printer->Indent();
874 
875   // Don't directly compare to -1 to avoid an Android x86 JIT bug.
876   printer->Print(
877       "byte isInitialized = memoizedIsInitialized;\n"
878       "if (isInitialized == 1) return true;\n"
879       "if (isInitialized == 0) return false;\n"
880       "\n");
881 
882   // Check that all required fields in this message are set.
883   // TODO(kenton):  We can optimize this when we switch to putting all the
884   //   "has" fields into a single bitfield.
885   for (int i = 0; i < descriptor_->field_count(); i++) {
886     const FieldDescriptor* field = descriptor_->field(i);
887     const FieldGeneratorInfo* info = context_->GetFieldGeneratorInfo(field);
888 
889     if (field->is_required()) {
890       printer->Print(
891           "if (!has$name$()) {\n"
892           "  memoizedIsInitialized = 0;\n"
893           "  return false;\n"
894           "}\n",
895           "name", info->capitalized_name);
896     }
897   }
898 
899   // Now check that all embedded messages are initialized.
900   for (int i = 0; i < descriptor_->field_count(); i++) {
901     const FieldDescriptor* field = descriptor_->field(i);
902     const FieldGeneratorInfo* info = context_->GetFieldGeneratorInfo(field);
903     if (GetJavaType(field) == JAVATYPE_MESSAGE &&
904         HasRequiredFields(field->message_type())) {
905       switch (field->label()) {
906         case FieldDescriptor::LABEL_REQUIRED:
907           printer->Print(
908               "if (!get$name$().isInitialized()) {\n"
909               "  memoizedIsInitialized = 0;\n"
910               "  return false;\n"
911               "}\n",
912               "type",
913               name_resolver_->GetImmutableClassName(field->message_type()),
914               "name", info->capitalized_name);
915           break;
916         case FieldDescriptor::LABEL_OPTIONAL:
917           printer->Print(
918               "if (has$name$()) {\n"
919               "  if (!get$name$().isInitialized()) {\n"
920               "    memoizedIsInitialized = 0;\n"
921               "    return false;\n"
922               "  }\n"
923               "}\n",
924               "name", info->capitalized_name);
925           break;
926         case FieldDescriptor::LABEL_REPEATED:
927           if (IsMapEntry(field->message_type())) {
928             printer->Print(
929                 "for ($type$ item : get$name$Map().values()) {\n"
930                 "  if (!item.isInitialized()) {\n"
931                 "    memoizedIsInitialized = 0;\n"
932                 "    return false;\n"
933                 "  }\n"
934                 "}\n",
935                 "type",
936                 MapValueImmutableClassdName(field->message_type(),
937                                             name_resolver_),
938                 "name", info->capitalized_name);
939           } else {
940             printer->Print(
941                 "for (int i = 0; i < get$name$Count(); i++) {\n"
942                 "  if (!get$name$(i).isInitialized()) {\n"
943                 "    memoizedIsInitialized = 0;\n"
944                 "    return false;\n"
945                 "  }\n"
946                 "}\n",
947                 "type",
948                 name_resolver_->GetImmutableClassName(field->message_type()),
949                 "name", info->capitalized_name);
950           }
951           break;
952       }
953     }
954   }
955 
956   if (descriptor_->extension_range_count() > 0) {
957     printer->Print(
958         "if (!extensionsAreInitialized()) {\n"
959         "  memoizedIsInitialized = 0;\n"
960         "  return false;\n"
961         "}\n");
962   }
963 
964   printer->Outdent();
965 
966   printer->Print("  memoizedIsInitialized = 1;\n");
967 
968   printer->Print(
969       "  return true;\n"
970       "}\n"
971       "\n");
972 }
973 
974 // ===================================================================
975 
976 namespace {
CheckHasBitsForEqualsAndHashCode(const FieldDescriptor * field)977 bool CheckHasBitsForEqualsAndHashCode(const FieldDescriptor* field) {
978   if (field->is_repeated()) {
979     return false;
980   }
981   if (HasHasbit(field)) {
982     return true;
983   }
984   return GetJavaType(field) == JAVATYPE_MESSAGE && !IsRealOneof(field);
985 }
986 }  // namespace
987 
GenerateEqualsAndHashCode(io::Printer * printer)988 void ImmutableMessageGenerator::GenerateEqualsAndHashCode(
989     io::Printer* printer) {
990   printer->Print(
991       "@java.lang.Override\n"
992       "public boolean equals(");
993   printer->Print("final java.lang.Object obj) {\n");
994   printer->Indent();
995   printer->Print(
996       "if (obj == this) {\n"
997       " return true;\n"
998       "}\n"
999       "if (!(obj instanceof $classname$)) {\n"
1000       "  return super.equals(obj);\n"
1001       "}\n"
1002       "$classname$ other = ($classname$) obj;\n"
1003       "\n",
1004       "classname", name_resolver_->GetImmutableClassName(descriptor_));
1005 
1006   for (int i = 0; i < descriptor_->field_count(); i++) {
1007     const FieldDescriptor* field = descriptor_->field(i);
1008     if (!IsRealOneof(field)) {
1009       const FieldGeneratorInfo* info = context_->GetFieldGeneratorInfo(field);
1010       bool check_has_bits = CheckHasBitsForEqualsAndHashCode(field);
1011       if (check_has_bits) {
1012         printer->Print(
1013             "if (has$name$() != other.has$name$()) return false;\n"
1014             "if (has$name$()) {\n",
1015             "name", info->capitalized_name);
1016         printer->Indent();
1017       }
1018       field_generators_.get(field).GenerateEqualsCode(printer);
1019       if (check_has_bits) {
1020         printer->Outdent();
1021         printer->Print("}\n");
1022       }
1023     }
1024   }
1025 
1026   // Compare oneofs.
1027   for (auto oneof : oneofs_) {
1028     printer->Print(
1029         "if (!get$oneof_capitalized_name$Case().equals("
1030         "other.get$oneof_capitalized_name$Case())) return false;\n",
1031         "oneof_capitalized_name",
1032         context_->GetOneofGeneratorInfo(oneof)->capitalized_name);
1033     printer->Print("switch ($oneof_name$Case_) {\n", "oneof_name",
1034                    context_->GetOneofGeneratorInfo(oneof)->name);
1035     printer->Indent();
1036     for (int j = 0; j < (oneof)->field_count(); j++) {
1037       const FieldDescriptor* field = (oneof)->field(j);
1038       printer->Print("case $field_number$:\n", "field_number",
1039                      StrCat(field->number()));
1040       printer->Indent();
1041       field_generators_.get(field).GenerateEqualsCode(printer);
1042       printer->Print("break;\n");
1043       printer->Outdent();
1044     }
1045     printer->Print(
1046         "case 0:\n"
1047         "default:\n");
1048     printer->Outdent();
1049     printer->Print("}\n");
1050   }
1051 
1052   // Always consider unknown fields for equality. This will sometimes return
1053   // false for non-canonical ordering when running in LITE_RUNTIME but it's
1054   // the best we can do.
1055   printer->Print(
1056       "if (!getUnknownFields().equals(other.getUnknownFields())) return "
1057       "false;\n");
1058   if (descriptor_->extension_range_count() > 0) {
1059     printer->Print(
1060         "if (!getExtensionFields().equals(other.getExtensionFields()))\n"
1061         "  return false;\n");
1062   }
1063   printer->Print("return true;\n");
1064   printer->Outdent();
1065   printer->Print(
1066       "}\n"
1067       "\n");
1068 
1069   printer->Print(
1070       "@java.lang.Override\n"
1071       "public int hashCode() {\n");
1072   printer->Indent();
1073   printer->Print("if (memoizedHashCode != 0) {\n");
1074   printer->Indent();
1075   printer->Print("return memoizedHashCode;\n");
1076   printer->Outdent();
1077   printer->Print(
1078       "}\n"
1079       "int hash = 41;\n");
1080 
1081   // If we output a getDescriptor() method, use that as it is more efficient.
1082   if (descriptor_->options().no_standard_descriptor_accessor()) {
1083     printer->Print("hash = (19 * hash) + getDescriptorForType().hashCode();\n");
1084   } else {
1085     printer->Print("hash = (19 * hash) + getDescriptor().hashCode();\n");
1086   }
1087 
1088   // hashCode non-oneofs.
1089   for (int i = 0; i < descriptor_->field_count(); i++) {
1090     const FieldDescriptor* field = descriptor_->field(i);
1091     if (!IsRealOneof(field)) {
1092       const FieldGeneratorInfo* info = context_->GetFieldGeneratorInfo(field);
1093       bool check_has_bits = CheckHasBitsForEqualsAndHashCode(field);
1094       if (check_has_bits) {
1095         printer->Print("if (has$name$()) {\n", "name", info->capitalized_name);
1096         printer->Indent();
1097       }
1098       field_generators_.get(field).GenerateHashCode(printer);
1099       if (check_has_bits) {
1100         printer->Outdent();
1101         printer->Print("}\n");
1102       }
1103     }
1104   }
1105 
1106   // hashCode oneofs.
1107   for (auto oneof : oneofs_) {
1108     printer->Print("switch ($oneof_name$Case_) {\n", "oneof_name",
1109                    context_->GetOneofGeneratorInfo(oneof)->name);
1110     printer->Indent();
1111     for (int j = 0; j < (oneof)->field_count(); j++) {
1112       const FieldDescriptor* field = (oneof)->field(j);
1113       printer->Print("case $field_number$:\n", "field_number",
1114                      StrCat(field->number()));
1115       printer->Indent();
1116       field_generators_.get(field).GenerateHashCode(printer);
1117       printer->Print("break;\n");
1118       printer->Outdent();
1119     }
1120     printer->Print(
1121         "case 0:\n"
1122         "default:\n");
1123     printer->Outdent();
1124     printer->Print("}\n");
1125   }
1126 
1127   if (descriptor_->extension_range_count() > 0) {
1128     printer->Print("hash = hashFields(hash, getExtensionFields());\n");
1129   }
1130 
1131   printer->Print("hash = (29 * hash) + getUnknownFields().hashCode();\n");
1132   printer->Print(
1133       "memoizedHashCode = hash;\n"
1134       "return hash;\n");
1135   printer->Outdent();
1136   printer->Print(
1137       "}\n"
1138       "\n");
1139 }
1140 
1141 // ===================================================================
1142 
GenerateExtensionRegistrationCode(io::Printer * printer)1143 void ImmutableMessageGenerator::GenerateExtensionRegistrationCode(
1144     io::Printer* printer) {
1145   for (int i = 0; i < descriptor_->extension_count(); i++) {
1146     ImmutableExtensionGenerator(descriptor_->extension(i), context_)
1147         .GenerateRegistrationCode(printer);
1148   }
1149 
1150   for (int i = 0; i < descriptor_->nested_type_count(); i++) {
1151     ImmutableMessageGenerator(descriptor_->nested_type(i), context_)
1152         .GenerateExtensionRegistrationCode(printer);
1153   }
1154 }
1155 
1156 // ===================================================================
GenerateParser(io::Printer * printer)1157 void ImmutableMessageGenerator::GenerateParser(io::Printer* printer) {
1158   printer->Print(
1159       "$visibility$ static final com.google.protobuf.Parser<$classname$>\n"
1160        "    PARSER = new com.google.protobuf.AbstractParser<$classname$>() {\n"
1161        "  @java.lang.Override\n"
1162        "  public $classname$ parsePartialFrom(\n"
1163        "      com.google.protobuf.CodedInputStream input,\n"
1164        "      com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n"
1165        "      throws com.google.protobuf.InvalidProtocolBufferException {\n"
1166        "    Builder builder = newBuilder();\n"
1167        "    try {\n"
1168        "      builder.mergeFrom(input, extensionRegistry);\n"
1169        "    } catch (com.google.protobuf.InvalidProtocolBufferException e) {\n"
1170        "      throw e.setUnfinishedMessage(builder.buildPartial());\n"
1171        "    } catch (com.google.protobuf.UninitializedMessageException e) {\n"
1172        "      throw "
1173        "e.asInvalidProtocolBufferException().setUnfinishedMessage(builder."
1174        "buildPartial());\n"
1175        "    } catch (java.io.IOException e) {\n"
1176        "      throw new com.google.protobuf.InvalidProtocolBufferException(e)\n"
1177        "          .setUnfinishedMessage(builder.buildPartial());\n"
1178        "    }\n"
1179        "    return builder.buildPartial();\n"
1180        "  }\n"
1181       "};\n"
1182       "\n"
1183       "public static com.google.protobuf.Parser<$classname$> parser() {\n"
1184       "  return PARSER;\n"
1185       "}\n"
1186       "\n"
1187       "@java.lang.Override\n"
1188       "public com.google.protobuf.Parser<$classname$> getParserForType() {\n"
1189       "  return PARSER;\n"
1190       "}\n"
1191       "\n",
1192       "visibility",
1193       ExposePublicParser(descriptor_->file()) ? "@java.lang.Deprecated public"
1194                                               : "private",
1195       "classname", descriptor_->name());
1196 }
1197 
1198 // ===================================================================
GenerateInitializers(io::Printer * printer)1199 void ImmutableMessageGenerator::GenerateInitializers(io::Printer* printer) {
1200   for (int i = 0; i < descriptor_->field_count(); i++) {
1201     if (!IsRealOneof(descriptor_->field(i))) {
1202       field_generators_.get(descriptor_->field(i))
1203           .GenerateInitializationCode(printer);
1204     }
1205   }
1206 }
1207 
GenerateAnyMethods(io::Printer * printer)1208 void ImmutableMessageGenerator::GenerateAnyMethods(io::Printer* printer) {
1209   printer->Print(
1210       "private static String getTypeUrl(\n"
1211       "    java.lang.String typeUrlPrefix,\n"
1212       "    com.google.protobuf.Descriptors.Descriptor descriptor) {\n"
1213       "  return typeUrlPrefix.endsWith(\"/\")\n"
1214       "      ? typeUrlPrefix + descriptor.getFullName()\n"
1215       "      : typeUrlPrefix + \"/\" + descriptor.getFullName();\n"
1216       "}\n"
1217       "\n"
1218       "private static String getTypeNameFromTypeUrl(\n"
1219       "    java.lang.String typeUrl) {\n"
1220       "  int pos = typeUrl.lastIndexOf('/');\n"
1221       "  return pos == -1 ? \"\" : typeUrl.substring(pos + 1);\n"
1222       "}\n"
1223       "\n"
1224       "public static <T extends com.google.protobuf.Message> Any pack(\n"
1225       "    T message) {\n"
1226       "  return Any.newBuilder()\n"
1227       "      .setTypeUrl(getTypeUrl(\"type.googleapis.com\",\n"
1228       "                             message.getDescriptorForType()))\n"
1229       "      .setValue(message.toByteString())\n"
1230       "      .build();\n"
1231       "}\n"
1232       "\n"
1233       "/**\n"
1234       " * Packs a message using the given type URL prefix. The type URL will\n"
1235       " * be constructed by concatenating the message type's full name to the\n"
1236       " * prefix with an optional \"/\" separator if the prefix doesn't end\n"
1237       " * with \"/\" already.\n"
1238       " */\n"
1239       "public static <T extends com.google.protobuf.Message> Any pack(\n"
1240       "    T message, java.lang.String typeUrlPrefix) {\n"
1241       "  return Any.newBuilder()\n"
1242       "      .setTypeUrl(getTypeUrl(typeUrlPrefix,\n"
1243       "                             message.getDescriptorForType()))\n"
1244       "      .setValue(message.toByteString())\n"
1245       "      .build();\n"
1246       "}\n"
1247       "\n"
1248       "public <T extends com.google.protobuf.Message> boolean is(\n"
1249       "    java.lang.Class<T> clazz) {\n"
1250       "  T defaultInstance =\n"
1251       "      com.google.protobuf.Internal.getDefaultInstance(clazz);\n"
1252       "  return getTypeNameFromTypeUrl(getTypeUrl()).equals(\n"
1253       "      defaultInstance.getDescriptorForType().getFullName());\n"
1254       "}\n"
1255       "\n"
1256       "private volatile com.google.protobuf.Message cachedUnpackValue;\n"
1257       "\n"
1258       "@java.lang.SuppressWarnings(\"unchecked\")\n"
1259       "public <T extends com.google.protobuf.Message> T unpack(\n"
1260       "    java.lang.Class<T> clazz)\n"
1261       "    throws com.google.protobuf.InvalidProtocolBufferException {\n"
1262       "  boolean invalidClazz = false;\n"
1263       "  if (cachedUnpackValue != null) {\n"
1264       "    if (cachedUnpackValue.getClass() == clazz) {\n"
1265       "      return (T) cachedUnpackValue;\n"
1266       "    }\n"
1267       "    invalidClazz = true;\n"
1268       "  }\n"
1269       "  if (invalidClazz || !is(clazz)) {\n"
1270       "    throw new com.google.protobuf.InvalidProtocolBufferException(\n"
1271       "        \"Type of the Any message does not match the given class.\");\n"
1272       "  }\n"
1273       "  T defaultInstance =\n"
1274       "      com.google.protobuf.Internal.getDefaultInstance(clazz);\n"
1275       "  T result = (T) defaultInstance.getParserForType()\n"
1276       "      .parseFrom(getValue());\n"
1277       "  cachedUnpackValue = result;\n"
1278       "  return result;\n"
1279       "}\n");
1280 }
1281 
1282 }  // namespace java
1283 }  // namespace compiler
1284 }  // namespace protobuf
1285 }  // namespace google
1286