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