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