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