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