• 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: dweis@google.com (Daniel Weis)
9 //  Based on original Protocol Buffers design by
10 //  Sanjay Ghemawat, Jeff Dean, and others.
11 
12 #include "google/protobuf/compiler/java/lite/message.h"
13 
14 #include <algorithm>
15 #include <cstddef>
16 #include <cstdint>
17 #include <memory>
18 #include <string>
19 #include <utility>
20 #include <vector>
21 
22 #include "absl/container/flat_hash_map.h"
23 #include "absl/log/absl_check.h"
24 #include "absl/strings/ascii.h"
25 #include "absl/strings/str_cat.h"
26 #include "absl/strings/string_view.h"
27 #include "absl/strings/substitute.h"
28 #include "google/protobuf/compiler/java/context.h"
29 #include "google/protobuf/compiler/java/doc_comment.h"
30 #include "google/protobuf/compiler/java/field_common.h"
31 #include "google/protobuf/compiler/java/generator.h"
32 #include "google/protobuf/compiler/java/generator_factory.h"
33 #include "google/protobuf/compiler/java/helpers.h"
34 #include "google/protobuf/compiler/java/lite/enum.h"
35 #include "google/protobuf/compiler/java/lite/extension.h"
36 #include "google/protobuf/compiler/java/lite/make_field_gens.h"
37 #include "google/protobuf/compiler/java/lite/message_builder.h"
38 #include "google/protobuf/compiler/java/name_resolver.h"
39 #include "google/protobuf/descriptor.pb.h"
40 #include "google/protobuf/io/coded_stream.h"
41 #include "google/protobuf/io/printer.h"
42 #include "google/protobuf/wire_format.h"
43 
44 // Must be last.
45 #include "google/protobuf/port_def.inc"
46 
47 namespace google {
48 namespace protobuf {
49 namespace compiler {
50 namespace java {
51 
52 using internal::WireFormat;
53 using internal::WireFormatLite;
54 
55 // ===================================================================
ImmutableMessageLiteGenerator(const Descriptor * descriptor,Context * context)56 ImmutableMessageLiteGenerator::ImmutableMessageLiteGenerator(
57     const Descriptor* descriptor, Context* context)
58     : MessageGenerator(descriptor),
59       context_(context),
60       name_resolver_(context->GetNameResolver()),
61       field_generators_(MakeImmutableFieldLiteGenerators(descriptor, context)) {
62   ABSL_CHECK(!HasDescriptorMethods(descriptor->file(), context->EnforceLite()))
63       << "Generator factory error: A lite message generator is used to "
64          "generate non-lite messages.";
65   for (int i = 0; i < descriptor_->field_count(); i++) {
66     if (IsRealOneof(descriptor_->field(i))) {
67       const OneofDescriptor* oneof = descriptor_->field(i)->containing_oneof();
68       ABSL_CHECK(oneofs_.emplace(oneof->index(), oneof).first->second == oneof);
69     }
70   }
71 }
72 
~ImmutableMessageLiteGenerator()73 ImmutableMessageLiteGenerator::~ImmutableMessageLiteGenerator() {}
74 
GenerateStaticVariables(io::Printer * printer,int * bytecode_estimate)75 void ImmutableMessageLiteGenerator::GenerateStaticVariables(
76     io::Printer* printer, int* bytecode_estimate) {
77   // No-op for lite.
78 }
79 
GenerateStaticVariableInitializers(io::Printer * printer)80 int ImmutableMessageLiteGenerator::GenerateStaticVariableInitializers(
81     io::Printer* printer) {
82   // No-op for lite.
83   return 0;
84 }
85 
86 // ===================================================================
87 
GenerateInterface(io::Printer * printer)88 void ImmutableMessageLiteGenerator::GenerateInterface(io::Printer* printer) {
89   MaybePrintGeneratedAnnotation(context_, printer, descriptor_,
90                                 /* immutable = */ true, "OrBuilder");
91 
92   absl::flat_hash_map<absl::string_view, std::string> variables = {
93       {"{", ""},
94       {"}", ""},
95       {"deprecation",
96        descriptor_->options().deprecated() ? "@java.lang.Deprecated " : ""},
97       {"extra_interfaces", ExtraMessageOrBuilderInterfaces(descriptor_)},
98       {"classname", std::string(descriptor_->name())},
99   };
100 
101   if (!context_->options().opensource_runtime) {
102     printer->Print("@com.google.protobuf.Internal.ProtoNonnullApi\n");
103   }
104   if (descriptor_->extension_range_count() > 0) {
105     printer->Print(
106         variables,
107         "$deprecation$public interface ${$$classname$OrBuilder$}$ extends \n"
108         "    $extra_interfaces$\n"
109         "     com.google.protobuf.GeneratedMessageLite.\n"
110         "          ExtendableMessageOrBuilder<\n"
111         "              $classname$, $classname$.Builder> {\n");
112   } else {
113     printer->Print(
114         variables,
115         "$deprecation$public interface ${$$classname$OrBuilder$}$ extends\n"
116         "    $extra_interfaces$\n"
117         "    com.google.protobuf.MessageLiteOrBuilder {\n");
118   }
119   printer->Annotate("{", "}", descriptor_);
120 
121   printer->Indent();
122   for (int i = 0; i < descriptor_->field_count(); i++) {
123     printer->Print("\n");
124     field_generators_.get(descriptor_->field(i))
125         .GenerateInterfaceMembers(printer);
126   }
127   for (auto& kv : oneofs_) {
128     const OneofDescriptor* oneof = kv.second;
129     variables["oneof_capitalized_name"] =
130         context_->GetOneofGeneratorInfo(oneof)->capitalized_name;
131     variables["classname"] =
132         context_->GetNameResolver()->GetImmutableClassName(descriptor_);
133     printer->Print(variables,
134                    "\n"
135                    "public ${$$classname$.$oneof_capitalized_name$Case$}$ "
136                    "get$oneof_capitalized_name$Case();\n");
137     printer->Annotate("{", "}", oneof);
138   }
139   printer->Outdent();
140 
141   printer->Print("}\n");
142 }
143 
144 // ===================================================================
145 
Generate(io::Printer * printer)146 void ImmutableMessageLiteGenerator::Generate(io::Printer* printer) {
147   bool is_own_file = IsOwnFile(descriptor_, /* immutable = */ true);
148 
149   absl::flat_hash_map<absl::string_view, std::string> variables = {{"{", ""},
150                                                                    {"}", ""}};
151   variables["static"] = is_own_file ? " " : " static ";
152   variables["classname"] = descriptor_->name();
153   variables["extra_interfaces"] = ExtraMessageInterfaces(descriptor_);
154   variables["deprecation"] =
155       descriptor_->options().deprecated() ? "@java.lang.Deprecated " : "";
156 
157   WriteMessageDocComment(printer, descriptor_, context_->options());
158   MaybePrintGeneratedAnnotation(context_, printer, descriptor_,
159                                 /* immutable = */ true);
160 
161 
162   // The builder_type stores the super type name of the nested Builder class.
163   std::string builder_type;
164   if (descriptor_->extension_range_count() > 0) {
165     printer->Print(
166         variables,
167         "$deprecation$public $static$final class ${$$classname$$}$ extends\n"
168         "    com.google.protobuf.GeneratedMessageLite.ExtendableMessage<\n"
169         "      $classname$, $classname$.Builder> implements\n"
170         "    $extra_interfaces$\n"
171         "    $classname$OrBuilder {\n");
172     builder_type = absl::Substitute(
173         "com.google.protobuf.GeneratedMessageLite.ExtendableBuilder<$0, ?>",
174         name_resolver_->GetImmutableClassName(descriptor_));
175   } else {
176     printer->Print(
177         variables,
178         "$deprecation$public $static$final class ${$$classname$$}$ extends\n"
179         "    com.google.protobuf.GeneratedMessageLite<\n"
180         "        $classname$, $classname$.Builder> implements\n"
181         "    $extra_interfaces$\n"
182         "    $classname$OrBuilder {\n");
183 
184     builder_type = "com.google.protobuf.GeneratedMessageLite.Builder";
185   }
186   printer->Annotate("{", "}", descriptor_);
187   printer->Indent();
188 
189   GenerateConstructor(printer);
190 
191   // Nested types
192   for (int i = 0; i < descriptor_->enum_type_count(); i++) {
193     EnumLiteGenerator(descriptor_->enum_type(i), true, context_)
194         .Generate(printer);
195   }
196 
197   for (int i = 0; i < descriptor_->nested_type_count(); i++) {
198     // Don't generate Java classes for map entry messages.
199     if (IsMapEntry(descriptor_->nested_type(i))) continue;
200     ImmutableMessageLiteGenerator messageGenerator(descriptor_->nested_type(i),
201                                                    context_);
202     messageGenerator.GenerateInterface(printer);
203     messageGenerator.Generate(printer);
204   }
205 
206   // Integers for bit fields.
207   int totalBits = 0;
208   for (int i = 0; i < descriptor_->field_count(); i++) {
209     totalBits +=
210         field_generators_.get(descriptor_->field(i)).GetNumBitsForMessage();
211   }
212   int totalInts = (totalBits + 31) / 32;
213   for (int i = 0; i < totalInts; i++) {
214     printer->Print("private int $bit_field_name$;\n", "bit_field_name",
215                    GetBitFieldName(i));
216   }
217 
218   // oneof
219   absl::flat_hash_map<absl::string_view, std::string> vars = {{"{", ""},
220                                                               {"}", ""}};
221   for (auto& kv : oneofs_) {
222     const OneofDescriptor* oneof = kv.second;
223     vars["oneof_name"] = context_->GetOneofGeneratorInfo(oneof)->name;
224     vars["oneof_capitalized_name"] =
225         context_->GetOneofGeneratorInfo(oneof)->capitalized_name;
226     vars["oneof_index"] = absl::StrCat((oneof)->index());
227     if (context_->options().opensource_runtime) {
228       // oneofCase_ and oneof_
229       printer->Print(vars,
230                      "private int $oneof_name$Case_ = 0;\n"
231                      "private java.lang.Object $oneof_name$_;\n");
232     }
233     // OneofCase enum
234     printer->Print(vars, "public enum ${$$oneof_capitalized_name$Case$}$ {\n");
235     printer->Annotate("{", "}", oneof);
236     printer->Indent();
237     for (int j = 0; j < (oneof)->field_count(); j++) {
238       const FieldDescriptor* field = (oneof)->field(j);
239       printer->Print("$field_name$($field_number$),\n", "field_name",
240                      absl::AsciiStrToUpper(field->name()), "field_number",
241                      absl::StrCat(field->number()));
242       printer->Annotate("field_name", field);
243     }
244     printer->Print("$cap_oneof_name$_NOT_SET(0);\n", "cap_oneof_name",
245                    absl::AsciiStrToUpper(vars["oneof_name"]));
246     printer->Print(vars,
247                    "private final int value;\n"
248                    "private $oneof_capitalized_name$Case(int value) {\n"
249                    "  this.value = value;\n"
250                    "}\n");
251     if (context_->options().opensource_runtime) {
252       printer->Print(
253           vars,
254           "/**\n"
255           " * @deprecated Use {@link #forNumber(int)} instead.\n"
256           " */\n"
257           "@java.lang.Deprecated\n"
258           "public static $oneof_capitalized_name$Case valueOf(int value) {\n"
259           "  return forNumber(value);\n"
260           "}\n"
261           "\n");
262     }
263     if (!context_->options().opensource_runtime) {
264       printer->Print(
265           "@com.google.protobuf.Internal.ProtoMethodMayReturnNull\n");
266     }
267     printer->Print(
268         vars,
269         "public static $oneof_capitalized_name$Case forNumber(int value) {\n"
270         "  switch (value) {\n");
271     for (int j = 0; j < (oneof)->field_count(); j++) {
272       const FieldDescriptor* field = (oneof)->field(j);
273       printer->Print("    case $field_number$: return $field_name$;\n",
274                      "field_number", absl::StrCat(field->number()),
275                      "field_name", absl::AsciiStrToUpper(field->name()));
276     }
277     printer->Print(
278         "    case 0: return $cap_oneof_name$_NOT_SET;\n"
279         "    default: return null;\n"
280         "  }\n"
281         "}\n"
282         // TODO: Rename this to "getFieldNumber" or something to
283         // disambiguate it from actual proto enums.
284         "public int getNumber() {\n"
285         "  return this.value;\n"
286         "}\n",
287         "cap_oneof_name", absl::AsciiStrToUpper(vars["oneof_name"]));
288     printer->Outdent();
289     printer->Print("};\n\n");
290     // oneofCase()
291     printer->Print(vars,
292                    "@java.lang.Override\n"
293                    "public $oneof_capitalized_name$Case\n"
294                    "${$get$oneof_capitalized_name$Case$}$() {\n"
295                    "  return $oneof_capitalized_name$Case.forNumber(\n"
296                    "      $oneof_name$Case_);\n"
297                    "}\n");
298     printer->Annotate("{", "}", oneof);
299     printer->Print(vars,
300                    "\n"
301                    "private void ${$clear$oneof_capitalized_name$$}$() {\n"
302                    "  $oneof_name$Case_ = 0;\n"
303                    "  $oneof_name$_ = null;\n"
304                    "}\n"
305                    "\n");
306     printer->Annotate("{", "}", oneof);
307   }
308 
309   // Fields
310   for (int i = 0; i < descriptor_->field_count(); i++) {
311     printer->Print("public static final int $constant_name$ = $number$;\n",
312                    "constant_name", FieldConstantName(descriptor_->field(i)),
313                    "number", absl::StrCat(descriptor_->field(i)->number()));
314     printer->Annotate("constant_name", descriptor_->field(i));
315     field_generators_.get(descriptor_->field(i)).GenerateMembers(printer);
316     printer->Print("\n");
317   }
318 
319   GenerateParseFromMethods(printer);
320   GenerateBuilder(printer);
321 
322   if (HasRequiredFields(descriptor_)) {
323     // Memoizes whether the protocol buffer is fully initialized (has all
324     // required fields). 0 means false, 1 means true, and all other values
325     // mean not yet computed.
326     printer->Print("private byte memoizedIsInitialized = 2;\n");
327   }
328 
329   printer->Print(
330       "@java.lang.Override\n"
331       "@java.lang.SuppressWarnings({\"unchecked\", \"fallthrough\"})\n"
332       "protected final java.lang.Object dynamicMethod(\n"
333       "    com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,\n"
334       "    java.lang.Object arg0, java.lang.Object arg1) {\n"
335       "  switch (method) {\n"
336       "    case NEW_MUTABLE_INSTANCE: {\n"
337       "      return new $classname$();\n"
338       "    }\n",
339       "classname", name_resolver_->GetImmutableClassName(descriptor_));
340 
341   printer->Indent();
342   printer->Indent();
343 
344   printer->Print("case NEW_BUILDER: {\n");
345 
346   printer->Indent();
347   GenerateDynamicMethodNewBuilder(printer);
348   printer->Outdent();
349 
350   printer->Print(
351       "}\n"
352       "case BUILD_MESSAGE_INFO: {\n");
353 
354   printer->Indent();
355   GenerateDynamicMethodNewBuildMessageInfo(printer);
356   printer->Outdent();
357 
358   printer->Print(
359       "}\n"
360       "// fall through\n"
361       "case GET_DEFAULT_INSTANCE: {\n"
362       "  return DEFAULT_INSTANCE;\n"
363       "}\n"
364       "case GET_PARSER: {\n"
365       // Generally one would use the lazy initialization holder pattern for
366       // manipulating static fields but that has exceptional cost on Android as
367       // it will generate an extra class for every message. Instead, use the
368       // double-check locking pattern which works just as well.
369       //
370       // The "parser" temporary mirrors the "PARSER" field to eliminate a read
371       // at the final return statement.
372       "  com.google.protobuf.Parser<$classname$> parser = PARSER;\n"
373       "  if (parser == null) {\n"
374       "    synchronized ($classname$.class) {\n"
375       "      parser = PARSER;\n"
376       "      if (parser == null) {\n"
377       "        parser =\n"
378       "            new DefaultInstanceBasedParser<$classname$>(\n"
379       "                DEFAULT_INSTANCE);\n"
380       "        PARSER = parser;\n"
381       "      }\n"
382       "    }\n"
383       "  }\n"
384       "  return parser;\n",
385       "classname", name_resolver_->GetImmutableClassName(descriptor_));
386 
387   printer->Outdent();
388 
389   if (HasRequiredFields(descriptor_)) {
390     printer->Print(
391         "}\n"
392         "case GET_MEMOIZED_IS_INITIALIZED: {\n"
393         "  return memoizedIsInitialized;\n"
394         "}\n"
395         "case SET_MEMOIZED_IS_INITIALIZED: {\n"
396         "  memoizedIsInitialized = (byte) (arg0 == null ? 0 : 1);\n"
397         "  return null;\n"
398         "}\n");
399   } else {
400     printer->Print(
401         "}\n"
402         "case GET_MEMOIZED_IS_INITIALIZED: {\n"
403         "  return (byte) 1;\n"
404         "}\n"
405         "case SET_MEMOIZED_IS_INITIALIZED: {\n"
406         "  return null;\n"
407         "}\n");
408   }
409 
410   printer->Outdent();
411   printer->Print(
412       "  }\n"
413       "  throw new UnsupportedOperationException();\n"
414       "}\n"
415       "\n",
416       "classname", name_resolver_->GetImmutableClassName(descriptor_));
417 
418   printer->Print(
419       "\n"
420       "// @@protoc_insertion_point(class_scope:$full_name$)\n",
421       "full_name", descriptor_->full_name());
422 
423   // Carefully initialize the default instance in such a way that it doesn't
424   // conflict with other initialization.
425   printer->Print("private static final $classname$ DEFAULT_INSTANCE;\n",
426                  "classname",
427                  name_resolver_->GetImmutableClassName(descriptor_));
428 
429   printer->Print(
430       "static {\n"
431       "  $classname$ defaultInstance = new $classname$();\n"
432       "  // New instances are implicitly immutable so no need to make\n"
433       "  // immutable.\n"
434       "  DEFAULT_INSTANCE = defaultInstance;\n"
435       // Register the default instance in a map. This map will be used by
436       // experimental runtime to lookup default instance given a class instance
437       // without using Java reflection.
438       "  com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(\n"
439       "    $classname$.class, defaultInstance);\n"
440       "}\n"
441       "\n",
442       "classname", descriptor_->name());
443 
444   printer->Print(
445       "public static $classname$ getDefaultInstance() {\n"
446       "  return DEFAULT_INSTANCE;\n"
447       "}\n"
448       "\n",
449       "classname", name_resolver_->GetImmutableClassName(descriptor_));
450 
451   // 'of' method for Wrappers
452   if (IsWrappersProtoFile(descriptor_->file())) {
453     printer->Print(
454         "public static $classname$ of($field_type$ value) {\n"
455         "  return newBuilder().setValue(value).build();\n"
456         "}\n"
457         "\n",
458         "classname", name_resolver_->GetImmutableClassName(descriptor_),
459         "field_type", PrimitiveTypeName(GetJavaType(descriptor_->field(0))));
460   }
461 
462   GenerateParser(printer);
463 
464   // Extensions must be declared after the DEFAULT_INSTANCE is initialized
465   // because the DEFAULT_INSTANCE is used by the extension to lazily retrieve
466   // the outer class's FileDescriptor.
467   for (int i = 0; i < descriptor_->extension_count(); i++) {
468     ImmutableExtensionLiteGenerator(descriptor_->extension(i), context_)
469         .Generate(printer);
470   }
471 
472   printer->Outdent();
473   printer->Print("}\n\n");
474 }
475 
GenerateDynamicMethodNewBuildMessageInfo(io::Printer * printer)476 void ImmutableMessageLiteGenerator::GenerateDynamicMethodNewBuildMessageInfo(
477     io::Printer* printer) {
478   printer->Indent();
479 
480   // Collect field info into a sequence of UTF-16 chars. It will be embedded
481   // as a Java string in the generated code.
482   std::vector<uint16_t> chars;
483 
484   int flags = 0;
485   if (descriptor_->options().message_set_wire_format()) {
486     flags |= 0x2;
487   }
488   if (!context_->options().strip_nonfunctional_codegen) {
489     if (JavaGenerator::GetEdition(*descriptor_->file()) ==
490         Edition::EDITION_PROTO2) {
491       flags |= 0x1;
492     } else if (JavaGenerator::GetEdition(*descriptor_->file()) >=
493                Edition::EDITION_2023) {
494       flags |= 0x4;
495     }
496   }
497 
498   WriteIntToUtf16CharSequence(flags, &chars);
499   WriteIntToUtf16CharSequence(descriptor_->field_count(), &chars);
500 
501   if (descriptor_->field_count() == 0) {
502     printer->Print("java.lang.Object[] objects = null;");
503   } else {
504     // A single array of all fields (including oneof, oneofCase, hasBits).
505     printer->Print("java.lang.Object[] objects = new java.lang.Object[] {\n");
506     printer->Indent();
507 
508     // Record the number of oneofs.
509     WriteIntToUtf16CharSequence(oneofs_.size(), &chars);
510     for (auto& kv : oneofs_) {
511       printer->Print(
512           "\"$oneof_name$_\",\n"
513           "\"$oneof_name$Case_\",\n",
514           "oneof_name", context_->GetOneofGeneratorInfo(kv.second)->name);
515     }
516 
517     // Integers for bit fields.
518     int total_bits = 0;
519     for (int i = 0; i < descriptor_->field_count(); i++) {
520       total_bits +=
521           field_generators_.get(descriptor_->field(i)).GetNumBitsForMessage();
522     }
523     int total_ints = (total_bits + 31) / 32;
524     for (int i = 0; i < total_ints; i++) {
525       printer->Print("\"$bit_field_name$\",\n", "bit_field_name",
526                      GetBitFieldName(i));
527     }
528     WriteIntToUtf16CharSequence(total_ints, &chars);
529 
530     int map_count = 0;
531     int repeated_count = 0;
532     std::unique_ptr<const FieldDescriptor*[]> sorted_fields(
533         SortFieldsByNumber(descriptor_));
534     for (int i = 0; i < descriptor_->field_count(); i++) {
535       const FieldDescriptor* field = sorted_fields[i];
536       if (field->is_map()) {
537         map_count++;
538       } else if (field->is_repeated()) {
539         repeated_count++;
540       }
541     }
542 
543     WriteIntToUtf16CharSequence(sorted_fields[0]->number(), &chars);
544     WriteIntToUtf16CharSequence(
545         sorted_fields[descriptor_->field_count() - 1]->number(), &chars);
546     WriteIntToUtf16CharSequence(descriptor_->field_count(), &chars);
547     WriteIntToUtf16CharSequence(map_count, &chars);
548     WriteIntToUtf16CharSequence(repeated_count, &chars);
549 
550     std::vector<const FieldDescriptor*> fields_for_is_initialized_check;
551     for (int i = 0; i < descriptor_->field_count(); i++) {
552       if (descriptor_->field(i)->is_required() ||
553           (GetJavaType(descriptor_->field(i)) == JAVATYPE_MESSAGE &&
554            HasRequiredFields(descriptor_->field(i)->message_type()))) {
555         fields_for_is_initialized_check.push_back(descriptor_->field(i));
556       }
557     }
558     WriteIntToUtf16CharSequence(fields_for_is_initialized_check.size(), &chars);
559 
560     for (int i = 0; i < descriptor_->field_count(); i++) {
561       const FieldDescriptor* field = sorted_fields[i];
562       field_generators_.get(field).GenerateFieldInfo(printer, &chars);
563     }
564     printer->Outdent();
565     printer->Print("};\n");
566   }
567 
568   printer->Print("java.lang.String info =\n");
569   std::string line;
570   for (size_t i = 0; i < chars.size(); i++) {
571     uint16_t code = chars[i];
572     EscapeUtf16ToString(code, &line);
573     if (line.size() >= 80) {
574       printer->Print("    \"$string$\" +\n", "string", line);
575       line.clear();
576     }
577   }
578   printer->Print("    \"$string$\";\n", "string", line);
579 
580   printer->Print("return newMessageInfo(DEFAULT_INSTANCE, info, objects);\n");
581   printer->Outdent();
582 }
583 
584 // ===================================================================
585 
GenerateParseFromMethods(io::Printer * printer)586 void ImmutableMessageLiteGenerator::GenerateParseFromMethods(
587     io::Printer* printer) {
588   printer->Print(
589       "public static $classname$ parseFrom(\n"
590       "    java.nio.ByteBuffer data)\n"
591       "    throws com.google.protobuf.InvalidProtocolBufferException {\n"
592       "  return com.google.protobuf.GeneratedMessageLite.parseFrom(\n"
593       "      DEFAULT_INSTANCE, data);\n"
594       "}\n"
595       "public static $classname$ parseFrom(\n"
596       "    java.nio.ByteBuffer data,\n"
597       "    com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n"
598       "    throws com.google.protobuf.InvalidProtocolBufferException {\n"
599       "  return com.google.protobuf.GeneratedMessageLite.parseFrom(\n"
600       "      DEFAULT_INSTANCE, data, extensionRegistry);\n"
601       "}\n"
602       "public static $classname$ parseFrom(\n"
603       "    com.google.protobuf.ByteString data)\n"
604       "    throws com.google.protobuf.InvalidProtocolBufferException {\n"
605       "  return com.google.protobuf.GeneratedMessageLite.parseFrom(\n"
606       "      DEFAULT_INSTANCE, data);\n"
607       "}\n"
608       "public static $classname$ parseFrom(\n"
609       "    com.google.protobuf.ByteString data,\n"
610       "    com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n"
611       "    throws com.google.protobuf.InvalidProtocolBufferException {\n"
612       "  return com.google.protobuf.GeneratedMessageLite.parseFrom(\n"
613       "      DEFAULT_INSTANCE, data, extensionRegistry);\n"
614       "}\n"
615       "public static $classname$ parseFrom(byte[] data)\n"
616       "    throws com.google.protobuf.InvalidProtocolBufferException {\n"
617       "  return com.google.protobuf.GeneratedMessageLite.parseFrom(\n"
618       "      DEFAULT_INSTANCE, data);\n"
619       "}\n"
620       "public static $classname$ parseFrom(\n"
621       "    byte[] data,\n"
622       "    com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n"
623       "    throws com.google.protobuf.InvalidProtocolBufferException {\n"
624       "  return com.google.protobuf.GeneratedMessageLite.parseFrom(\n"
625       "      DEFAULT_INSTANCE, data, extensionRegistry);\n"
626       "}\n"
627       "public static $classname$ parseFrom(java.io.InputStream input)\n"
628       "    throws java.io.IOException {\n"
629       "  return com.google.protobuf.GeneratedMessageLite.parseFrom(\n"
630       "      DEFAULT_INSTANCE, input);\n"
631       "}\n"
632       "public static $classname$ parseFrom(\n"
633       "    java.io.InputStream input,\n"
634       "    com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n"
635       "    throws java.io.IOException {\n"
636       "  return com.google.protobuf.GeneratedMessageLite.parseFrom(\n"
637       "      DEFAULT_INSTANCE, input, extensionRegistry);\n"
638       "}\n"
639       "$parsedelimitedreturnannotation$\n"
640       "public static $classname$ parseDelimitedFrom(java.io.InputStream "
641       "input)\n"
642       "    throws java.io.IOException {\n"
643       "  return parseDelimitedFrom(DEFAULT_INSTANCE, input);\n"
644       "}\n"
645       "$parsedelimitedreturnannotation$\n"
646       "public static $classname$ parseDelimitedFrom(\n"
647       "    java.io.InputStream input,\n"
648       "    com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n"
649       "    throws java.io.IOException {\n"
650       "  return parseDelimitedFrom(DEFAULT_INSTANCE, input, "
651       "extensionRegistry);\n"
652       "}\n"
653       "public static $classname$ parseFrom(\n"
654       "    com.google.protobuf.CodedInputStream input)\n"
655       "    throws java.io.IOException {\n"
656       "  return com.google.protobuf.GeneratedMessageLite.parseFrom(\n"
657       "      DEFAULT_INSTANCE, input);\n"
658       "}\n"
659       "public static $classname$ parseFrom(\n"
660       "    com.google.protobuf.CodedInputStream input,\n"
661       "    com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n"
662       "    throws java.io.IOException {\n"
663       "  return com.google.protobuf.GeneratedMessageLite.parseFrom(\n"
664       "      DEFAULT_INSTANCE, input, extensionRegistry);\n"
665       "}\n"
666       "\n",
667       "classname", name_resolver_->GetImmutableClassName(descriptor_),
668       "parsedelimitedreturnannotation",
669       context_->options().opensource_runtime
670           ? ""
671           : "@com.google.protobuf.Internal.ProtoMethodMayReturnNull");
672 }
673 
674 // ===================================================================
675 
GenerateBuilder(io::Printer * printer)676 void ImmutableMessageLiteGenerator::GenerateBuilder(io::Printer* printer) {
677   printer->Print(
678       "public static Builder newBuilder() {\n"
679       "  return (Builder) DEFAULT_INSTANCE.createBuilder();\n"
680       "}\n"
681       "public static Builder newBuilder($classname$ prototype) {\n"
682       "  return DEFAULT_INSTANCE.createBuilder(prototype);\n"
683       "}\n"
684       "\n",
685       "classname", name_resolver_->GetImmutableClassName(descriptor_));
686 
687   MessageBuilderLiteGenerator builderGenerator(descriptor_, context_);
688   builderGenerator.Generate(printer);
689 }
690 
691 // ===================================================================
692 
GenerateDynamicMethodNewBuilder(io::Printer * printer)693 void ImmutableMessageLiteGenerator::GenerateDynamicMethodNewBuilder(
694     io::Printer* printer) {
695   printer->Print("return new Builder();\n");
696 }
697 
698 // ===================================================================
699 
GenerateExtensionRegistrationCode(io::Printer * printer)700 void ImmutableMessageLiteGenerator::GenerateExtensionRegistrationCode(
701     io::Printer* printer) {
702   for (int i = 0; i < descriptor_->extension_count(); i++) {
703     ImmutableExtensionLiteGenerator(descriptor_->extension(i), context_)
704         .GenerateRegistrationCode(printer);
705   }
706 
707   for (int i = 0; i < descriptor_->nested_type_count(); i++) {
708     ImmutableMessageLiteGenerator(descriptor_->nested_type(i), context_)
709         .GenerateExtensionRegistrationCode(printer);
710   }
711 }
712 
713 // ===================================================================
GenerateConstructor(io::Printer * printer)714 void ImmutableMessageLiteGenerator::GenerateConstructor(io::Printer* printer) {
715   printer->Print("private $classname$() {\n", "classname", descriptor_->name());
716   printer->Indent();
717 
718   // Initialize all fields to default.
719   GenerateInitializers(printer);
720 
721   printer->Outdent();
722   printer->Print("}\n");
723 }
724 
725 // ===================================================================
GenerateParser(io::Printer * printer)726 void ImmutableMessageLiteGenerator::GenerateParser(io::Printer* printer) {
727   printer->Print(
728       "private static volatile com.google.protobuf.Parser<$classname$> "
729       "PARSER;\n"
730       "\n"
731       "public static com.google.protobuf.Parser<$classname$> parser() {\n"
732       "  return DEFAULT_INSTANCE.getParserForType();\n"
733       "}\n",
734       "classname", descriptor_->name());
735 }
736 
737 // ===================================================================
GenerateInitializers(io::Printer * printer)738 void ImmutableMessageLiteGenerator::GenerateInitializers(io::Printer* printer) {
739   for (int i = 0; i < descriptor_->field_count(); i++) {
740     if (!IsRealOneof(descriptor_->field(i))) {
741       field_generators_.get(descriptor_->field(i))
742           .GenerateInitializationCode(printer);
743     }
744   }
745 }
746 }  // namespace java
747 }  // namespace compiler
748 }  // namespace protobuf
749 }  // namespace google
750 
751 #include "google/protobuf/port_undef.inc"
752