• 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 <cstdint>
39 #include <map>
40 #include <memory>
41 #include <vector>
42 
43 #include <google/protobuf/io/coded_stream.h>
44 #include <google/protobuf/io/printer.h>
45 #include <google/protobuf/wire_format.h>
46 #include <google/protobuf/stubs/strutil.h>
47 #include <google/protobuf/stubs/substitute.h>
48 #include <google/protobuf/compiler/java/java_context.h>
49 #include <google/protobuf/compiler/java/java_doc_comment.h>
50 #include <google/protobuf/compiler/java/java_enum_lite.h>
51 #include <google/protobuf/compiler/java/java_extension_lite.h>
52 #include <google/protobuf/compiler/java/java_generator_factory.h>
53 #include <google/protobuf/compiler/java/java_helpers.h>
54 #include <google/protobuf/compiler/java/java_message_builder.h>
55 #include <google/protobuf/compiler/java/java_message_builder_lite.h>
56 #include <google/protobuf/compiler/java/java_name_resolver.h>
57 #include <google/protobuf/descriptor.pb.h>
58 
59 namespace google {
60 namespace protobuf {
61 namespace compiler {
62 namespace java {
63 
64 using internal::WireFormat;
65 using internal::WireFormatLite;
66 
67 // ===================================================================
ImmutableMessageLiteGenerator(const Descriptor * descriptor,Context * context)68 ImmutableMessageLiteGenerator::ImmutableMessageLiteGenerator(
69     const Descriptor* descriptor, Context* context)
70     : MessageGenerator(descriptor),
71       context_(context),
72       name_resolver_(context->GetNameResolver()),
73       field_generators_(descriptor, context_) {
74   GOOGLE_CHECK(!HasDescriptorMethods(descriptor->file(), context->EnforceLite()))
75       << "Generator factory error: A lite message generator is used to "
76          "generate non-lite messages.";
77   for (int i = 0; i < descriptor_->field_count(); i++) {
78     if (IsRealOneof(descriptor_->field(i))) {
79       oneofs_.insert(descriptor_->field(i)->containing_oneof());
80     }
81   }
82 }
83 
~ImmutableMessageLiteGenerator()84 ImmutableMessageLiteGenerator::~ImmutableMessageLiteGenerator() {}
85 
GenerateStaticVariables(io::Printer * printer,int * bytecode_estimate)86 void ImmutableMessageLiteGenerator::GenerateStaticVariables(
87     io::Printer* printer, int* bytecode_estimate) {
88   // Generate static members for all nested types.
89   for (int i = 0; i < descriptor_->nested_type_count(); i++) {
90     // TODO(kenton):  Reuse MessageGenerator objects?
91     ImmutableMessageLiteGenerator(descriptor_->nested_type(i), context_)
92         .GenerateStaticVariables(printer, bytecode_estimate);
93   }
94 }
95 
GenerateStaticVariableInitializers(io::Printer * printer)96 int ImmutableMessageLiteGenerator::GenerateStaticVariableInitializers(
97     io::Printer* printer) {
98   int bytecode_estimate = 0;
99   // Generate static member initializers for all nested types.
100   for (int i = 0; i < descriptor_->nested_type_count(); i++) {
101     // TODO(kenton):  Reuse MessageGenerator objects?
102     bytecode_estimate +=
103         ImmutableMessageLiteGenerator(descriptor_->nested_type(i), context_)
104             .GenerateStaticVariableInitializers(printer);
105   }
106   return bytecode_estimate;
107 }
108 
109 // ===================================================================
110 
GenerateInterface(io::Printer * printer)111 void ImmutableMessageLiteGenerator::GenerateInterface(io::Printer* printer) {
112   MaybePrintGeneratedAnnotation(context_, printer, descriptor_,
113                                 /* immutable = */ true, "OrBuilder");
114   if (descriptor_->extension_range_count() > 0) {
115     printer->Print(
116         "$deprecation$public interface ${$$classname$OrBuilder$}$ extends \n"
117         "    $extra_interfaces$\n"
118         "     com.google.protobuf.GeneratedMessageLite.\n"
119         "          ExtendableMessageOrBuilder<\n"
120         "              $classname$, $classname$.Builder> {\n",
121         "deprecation",
122         descriptor_->options().deprecated() ? "@java.lang.Deprecated " : "",
123         "extra_interfaces", ExtraMessageOrBuilderInterfaces(descriptor_),
124         "classname", descriptor_->name(), "{", "", "}", "");
125   } else {
126     printer->Print(
127         "$deprecation$public interface ${$$classname$OrBuilder$}$ extends\n"
128         "    $extra_interfaces$\n"
129         "    com.google.protobuf.MessageLiteOrBuilder {\n",
130         "deprecation",
131         descriptor_->options().deprecated() ? "@java.lang.Deprecated " : "",
132         "extra_interfaces", ExtraMessageOrBuilderInterfaces(descriptor_),
133         "classname", descriptor_->name(), "{", "", "}", "");
134   }
135   printer->Annotate("{", "}", descriptor_);
136 
137   printer->Indent();
138   for (int i = 0; i < descriptor_->field_count(); i++) {
139     printer->Print("\n");
140     field_generators_.get(descriptor_->field(i))
141         .GenerateInterfaceMembers(printer);
142   }
143   for (auto oneof : oneofs_) {
144     printer->Print(
145         "\n"
146         "public $classname$.$oneof_capitalized_name$Case "
147         "get$oneof_capitalized_name$Case();\n",
148         "oneof_capitalized_name",
149         context_->GetOneofGeneratorInfo(oneof)->capitalized_name, "classname",
150         context_->GetNameResolver()->GetImmutableClassName(descriptor_));
151   }
152   printer->Outdent();
153 
154   printer->Print("}\n");
155 }
156 
157 // ===================================================================
158 
Generate(io::Printer * printer)159 void ImmutableMessageLiteGenerator::Generate(io::Printer* printer) {
160   bool is_own_file = IsOwnFile(descriptor_, /* immutable = */ true);
161 
162   std::map<std::string, std::string> variables;
163   variables["static"] = is_own_file ? " " : " static ";
164   variables["classname"] = descriptor_->name();
165   variables["extra_interfaces"] = ExtraMessageInterfaces(descriptor_);
166   variables["deprecation"] =
167       descriptor_->options().deprecated() ? "@java.lang.Deprecated " : "";
168 
169   WriteMessageDocComment(printer, descriptor_);
170   MaybePrintGeneratedAnnotation(context_, printer, descriptor_,
171                                 /* immutable = */ true);
172 
173 
174   // The builder_type stores the super type name of the nested Builder class.
175   std::string builder_type;
176   if (descriptor_->extension_range_count() > 0) {
177     printer->Print(
178         variables,
179         "$deprecation$public $static$final class $classname$ extends\n"
180         "    com.google.protobuf.GeneratedMessageLite.ExtendableMessage<\n"
181         "      $classname$, $classname$.Builder> implements\n"
182         "    $extra_interfaces$\n"
183         "    $classname$OrBuilder {\n");
184     builder_type = strings::Substitute(
185         "com.google.protobuf.GeneratedMessageLite.ExtendableBuilder<$0, ?>",
186         name_resolver_->GetImmutableClassName(descriptor_));
187   } else {
188     printer->Print(
189         variables,
190         "$deprecation$public $static$final class $classname$ extends\n"
191         "    com.google.protobuf.GeneratedMessageLite<\n"
192         "        $classname$, $classname$.Builder> implements\n"
193         "    $extra_interfaces$\n"
194         "    $classname$OrBuilder {\n");
195 
196     builder_type = "com.google.protobuf.GeneratedMessageLite.Builder";
197   }
198   printer->Indent();
199 
200   GenerateConstructor(printer);
201 
202   // Nested types
203   for (int i = 0; i < descriptor_->enum_type_count(); i++) {
204     EnumLiteGenerator(descriptor_->enum_type(i), true, context_)
205         .Generate(printer);
206   }
207 
208   for (int i = 0; i < descriptor_->nested_type_count(); i++) {
209     // Don't generate Java classes for map entry messages.
210     if (IsMapEntry(descriptor_->nested_type(i))) continue;
211     ImmutableMessageLiteGenerator messageGenerator(descriptor_->nested_type(i),
212                                                    context_);
213     messageGenerator.GenerateInterface(printer);
214     messageGenerator.Generate(printer);
215   }
216 
217   // Integers for bit fields.
218   int totalBits = 0;
219   for (int i = 0; i < descriptor_->field_count(); i++) {
220     totalBits +=
221         field_generators_.get(descriptor_->field(i)).GetNumBitsForMessage();
222   }
223   int totalInts = (totalBits + 31) / 32;
224   for (int i = 0; i < totalInts; i++) {
225     printer->Print("private int $bit_field_name$;\n", "bit_field_name",
226                    GetBitFieldName(i));
227   }
228 
229   // oneof
230   std::map<std::string, std::string> vars;
231   for (auto oneof : oneofs_) {
232     vars["oneof_name"] = context_->GetOneofGeneratorInfo(oneof)->name;
233     vars["oneof_capitalized_name"] =
234         context_->GetOneofGeneratorInfo(oneof)->capitalized_name;
235     vars["oneof_index"] = StrCat((oneof)->index());
236     // oneofCase_ and oneof_
237     printer->Print(vars,
238                    "private int $oneof_name$Case_ = 0;\n"
239                    "private java.lang.Object $oneof_name$_;\n");
240     // OneofCase enum
241     printer->Print(vars, "public enum $oneof_capitalized_name$Case {\n");
242     printer->Indent();
243     for (int j = 0; j < (oneof)->field_count(); j++) {
244       const FieldDescriptor* field = (oneof)->field(j);
245       printer->Print("$field_name$($field_number$),\n", "field_name",
246                      ToUpper(field->name()), "field_number",
247                      StrCat(field->number()));
248     }
249     printer->Print("$cap_oneof_name$_NOT_SET(0);\n", "cap_oneof_name",
250                    ToUpper(vars["oneof_name"]));
251     printer->Print(vars,
252                    "private final int value;\n"
253                    "private $oneof_capitalized_name$Case(int value) {\n"
254                    "  this.value = value;\n"
255                    "}\n");
256     printer->Print(
257         vars,
258         "/**\n"
259         " * @deprecated Use {@link #forNumber(int)} instead.\n"
260         " */\n"
261         "@java.lang.Deprecated\n"
262         "public static $oneof_capitalized_name$Case valueOf(int value) {\n"
263         "  return forNumber(value);\n"
264         "}\n"
265         "\n"
266         "public static $oneof_capitalized_name$Case forNumber(int value) {\n"
267         "  switch (value) {\n");
268     for (int j = 0; j < (oneof)->field_count(); j++) {
269       const FieldDescriptor* field = (oneof)->field(j);
270       printer->Print("    case $field_number$: return $field_name$;\n",
271                      "field_number", StrCat(field->number()),
272                      "field_name", ToUpper(field->name()));
273     }
274     printer->Print(
275         "    case 0: return $cap_oneof_name$_NOT_SET;\n"
276         "    default: return null;\n"
277         "  }\n"
278         "}\n"
279         // TODO(b/135620659): Rename this to "getFieldNumber" or something to
280         // disambiguate it from actual proto enums.
281         "public int getNumber() {\n"
282         "  return this.value;\n"
283         "}\n",
284         "cap_oneof_name", ToUpper(vars["oneof_name"]));
285     printer->Outdent();
286     printer->Print("};\n\n");
287     // oneofCase()
288     printer->Print(vars,
289                    "@java.lang.Override\n"
290                    "public $oneof_capitalized_name$Case\n"
291                    "get$oneof_capitalized_name$Case() {\n"
292                    "  return $oneof_capitalized_name$Case.forNumber(\n"
293                    "      $oneof_name$Case_);\n"
294                    "}\n"
295                    "\n"
296                    "private void clear$oneof_capitalized_name$() {\n"
297                    "  $oneof_name$Case_ = 0;\n"
298                    "  $oneof_name$_ = null;\n"
299                    "}\n"
300                    "\n");
301   }
302 
303   // Fields
304   for (int i = 0; i < descriptor_->field_count(); i++) {
305     printer->Print("public static final int $constant_name$ = $number$;\n",
306                    "constant_name", FieldConstantName(descriptor_->field(i)),
307                    "number", StrCat(descriptor_->field(i)->number()));
308     field_generators_.get(descriptor_->field(i)).GenerateMembers(printer);
309     printer->Print("\n");
310   }
311 
312   GenerateParseFromMethods(printer);
313   GenerateBuilder(printer);
314 
315   if (HasRequiredFields(descriptor_)) {
316     // Memoizes whether the protocol buffer is fully initialized (has all
317     // required fields). 0 means false, 1 means true, and all other values
318     // mean not yet computed.
319     printer->Print("private byte memoizedIsInitialized = 2;\n");
320   }
321 
322   printer->Print(
323       "@java.lang.Override\n"
324       "@java.lang.SuppressWarnings({\"unchecked\", \"fallthrough\"})\n"
325       "protected final java.lang.Object dynamicMethod(\n"
326       "    com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,\n"
327       "    java.lang.Object arg0, java.lang.Object arg1) {\n"
328       "  switch (method) {\n"
329       "    case NEW_MUTABLE_INSTANCE: {\n"
330       "      return new $classname$();\n"
331       "    }\n",
332       "classname", name_resolver_->GetImmutableClassName(descriptor_));
333 
334   printer->Indent();
335   printer->Indent();
336 
337   printer->Print("case NEW_BUILDER: {\n");
338 
339   printer->Indent();
340   GenerateDynamicMethodNewBuilder(printer);
341   printer->Outdent();
342 
343   printer->Print(
344       "}\n"
345       "case BUILD_MESSAGE_INFO: {\n");
346 
347   printer->Indent();
348   GenerateDynamicMethodNewBuildMessageInfo(printer);
349   printer->Outdent();
350 
351   printer->Print(
352       "}\n"
353       "// fall through\n"
354       "case GET_DEFAULT_INSTANCE: {\n"
355       "  return DEFAULT_INSTANCE;\n"
356       "}\n"
357       "case GET_PARSER: {\n"
358       // Generally one would use the lazy initialization holder pattern for
359       // manipulating static fields but that has exceptional cost on Android as
360       // it will generate an extra class for every message. Instead, use the
361       // double-check locking pattern which works just as well.
362       //
363       // The "parser" temporary mirrors the "PARSER" field to eliminate a read
364       // at the final return statement.
365       "  com.google.protobuf.Parser<$classname$> parser = PARSER;\n"
366       "  if (parser == null) {\n"
367       "    synchronized ($classname$.class) {\n"
368       "      parser = PARSER;\n"
369       "      if (parser == null) {\n"
370       "        parser =\n"
371       "            new DefaultInstanceBasedParser<$classname$>(\n"
372       "                DEFAULT_INSTANCE);\n"
373       "        PARSER = parser;\n"
374       "      }\n"
375       "    }\n"
376       "  }\n"
377       "  return parser;\n",
378       "classname", name_resolver_->GetImmutableClassName(descriptor_));
379 
380   printer->Outdent();
381 
382   if (HasRequiredFields(descriptor_)) {
383     printer->Print(
384         "}\n"
385         "case GET_MEMOIZED_IS_INITIALIZED: {\n"
386         "  return memoizedIsInitialized;\n"
387         "}\n"
388         "case SET_MEMOIZED_IS_INITIALIZED: {\n"
389         "  memoizedIsInitialized = (byte) (arg0 == null ? 0 : 1);\n"
390         "  return null;\n"
391         "}\n");
392   } else {
393     printer->Print(
394         "}\n"
395         "case GET_MEMOIZED_IS_INITIALIZED: {\n"
396         "  return (byte) 1;\n"
397         "}\n"
398         "case SET_MEMOIZED_IS_INITIALIZED: {\n"
399         "  return null;\n"
400         "}\n");
401   }
402 
403   printer->Outdent();
404   printer->Print(
405       "  }\n"
406       "  throw new UnsupportedOperationException();\n"
407       "}\n"
408       "\n",
409       "classname", name_resolver_->GetImmutableClassName(descriptor_));
410 
411   printer->Print(
412       "\n"
413       "// @@protoc_insertion_point(class_scope:$full_name$)\n",
414       "full_name", descriptor_->full_name());
415 
416   // Carefully initialize the default instance in such a way that it doesn't
417   // conflict with other initialization.
418   printer->Print("private static final $classname$ DEFAULT_INSTANCE;\n",
419                  "classname",
420                  name_resolver_->GetImmutableClassName(descriptor_));
421 
422   printer->Print(
423       "static {\n"
424       "  $classname$ defaultInstance = new $classname$();\n"
425       "  // New instances are implicitly immutable so no need to make\n"
426       "  // immutable.\n"
427       "  DEFAULT_INSTANCE = defaultInstance;\n"
428       // Register the default instance in a map. This map will be used by
429       // experimental runtime to lookup default instance given a class instance
430       // without using Java reflection.
431       "  com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(\n"
432       "    $classname$.class, defaultInstance);\n"
433       "}\n"
434       "\n",
435       "classname", descriptor_->name());
436 
437   printer->Print(
438       "public static $classname$ getDefaultInstance() {\n"
439       "  return DEFAULT_INSTANCE;\n"
440       "}\n"
441       "\n",
442       "classname", name_resolver_->GetImmutableClassName(descriptor_));
443 
444   // 'of' method for Wrappers
445   if (IsWrappersProtoFile(descriptor_->file())) {
446     printer->Print(
447         "public static $classname$ of($field_type$ value) {\n"
448         "  return newBuilder().setValue(value).build();\n"
449         "}\n"
450         "\n",
451         "classname", name_resolver_->GetImmutableClassName(descriptor_),
452         "field_type", PrimitiveTypeName(GetJavaType(descriptor_->field(0))));
453   }
454 
455   GenerateParser(printer);
456 
457   // Extensions must be declared after the DEFAULT_INSTANCE is initialized
458   // because the DEFAULT_INSTANCE is used by the extension to lazily retrieve
459   // the outer class's FileDescriptor.
460   for (int i = 0; i < descriptor_->extension_count(); i++) {
461     ImmutableExtensionLiteGenerator(descriptor_->extension(i), context_)
462         .Generate(printer);
463   }
464 
465   printer->Outdent();
466   printer->Print("}\n\n");
467 }
468 
GenerateDynamicMethodNewBuildMessageInfo(io::Printer * printer)469 void ImmutableMessageLiteGenerator::GenerateDynamicMethodNewBuildMessageInfo(
470     io::Printer* printer) {
471   printer->Indent();
472 
473   // Collect field info into a sequence of UTF-16 chars. It will be embedded
474   // as a Java string in the generated code.
475   std::vector<uint16_t> chars;
476 
477   int flags = 0;
478   if (IsProto2(descriptor_->file())) {
479     flags |= 0x1;
480   }
481   if (descriptor_->options().message_set_wire_format()) {
482     flags |= 0x2;
483   }
484   WriteIntToUtf16CharSequence(flags, &chars);
485   WriteIntToUtf16CharSequence(descriptor_->field_count(), &chars);
486 
487   if (descriptor_->field_count() == 0) {
488     printer->Print("java.lang.Object[] objects = null;");
489   } else {
490     // A single array of all fields (including oneof, oneofCase, hasBits).
491     printer->Print("java.lang.Object[] objects = new java.lang.Object[] {\n");
492     printer->Indent();
493 
494     // Record the number of oneofs.
495     WriteIntToUtf16CharSequence(oneofs_.size(), &chars);
496     for (auto oneof : oneofs_) {
497       printer->Print(
498           "\"$oneof_name$_\",\n"
499           "\"$oneof_name$Case_\",\n",
500           "oneof_name", context_->GetOneofGeneratorInfo(oneof)->name);
501     }
502 
503     // Integers for bit fields.
504     int total_bits = 0;
505     for (int i = 0; i < descriptor_->field_count(); i++) {
506       total_bits +=
507           field_generators_.get(descriptor_->field(i)).GetNumBitsForMessage();
508     }
509     int total_ints = (total_bits + 31) / 32;
510     for (int i = 0; i < total_ints; i++) {
511       printer->Print("\"$bit_field_name$\",\n", "bit_field_name",
512                      GetBitFieldName(i));
513     }
514     WriteIntToUtf16CharSequence(total_ints, &chars);
515 
516     int map_count = 0;
517     int repeated_count = 0;
518     std::unique_ptr<const FieldDescriptor*[]> sorted_fields(
519         SortFieldsByNumber(descriptor_));
520     for (int i = 0; i < descriptor_->field_count(); i++) {
521       const FieldDescriptor* field = sorted_fields[i];
522       if (field->is_map()) {
523         map_count++;
524       } else if (field->is_repeated()) {
525         repeated_count++;
526       }
527     }
528 
529     WriteIntToUtf16CharSequence(sorted_fields[0]->number(), &chars);
530     WriteIntToUtf16CharSequence(
531         sorted_fields[descriptor_->field_count() - 1]->number(), &chars);
532     WriteIntToUtf16CharSequence(descriptor_->field_count(), &chars);
533     WriteIntToUtf16CharSequence(map_count, &chars);
534     WriteIntToUtf16CharSequence(repeated_count, &chars);
535 
536     std::vector<const FieldDescriptor*> fields_for_is_initialized_check;
537     for (int i = 0; i < descriptor_->field_count(); i++) {
538       if (descriptor_->field(i)->is_required() ||
539           (GetJavaType(descriptor_->field(i)) == JAVATYPE_MESSAGE &&
540            HasRequiredFields(descriptor_->field(i)->message_type()))) {
541         fields_for_is_initialized_check.push_back(descriptor_->field(i));
542       }
543     }
544     WriteIntToUtf16CharSequence(fields_for_is_initialized_check.size(), &chars);
545 
546     for (int i = 0; i < descriptor_->field_count(); i++) {
547       const FieldDescriptor* field = sorted_fields[i];
548       field_generators_.get(field).GenerateFieldInfo(printer, &chars);
549     }
550     printer->Outdent();
551     printer->Print("};\n");
552   }
553 
554   printer->Print("java.lang.String info =\n");
555   std::string line;
556   for (size_t i = 0; i < chars.size(); i++) {
557     uint16_t code = chars[i];
558     EscapeUtf16ToString(code, &line);
559     if (line.size() >= 80) {
560       printer->Print("    \"$string$\" +\n", "string", line);
561       line.clear();
562     }
563   }
564   printer->Print("    \"$string$\";\n", "string", line);
565 
566   printer->Print("return newMessageInfo(DEFAULT_INSTANCE, info, objects);\n");
567   printer->Outdent();
568 }
569 
570 // ===================================================================
571 
GenerateParseFromMethods(io::Printer * printer)572 void ImmutableMessageLiteGenerator::GenerateParseFromMethods(
573     io::Printer* printer) {
574   printer->Print(
575       "public static $classname$ parseFrom(\n"
576       "    java.nio.ByteBuffer data)\n"
577       "    throws com.google.protobuf.InvalidProtocolBufferException {\n"
578       "  return com.google.protobuf.GeneratedMessageLite.parseFrom(\n"
579       "      DEFAULT_INSTANCE, data);\n"
580       "}\n"
581       "public static $classname$ parseFrom(\n"
582       "    java.nio.ByteBuffer data,\n"
583       "    com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n"
584       "    throws com.google.protobuf.InvalidProtocolBufferException {\n"
585       "  return com.google.protobuf.GeneratedMessageLite.parseFrom(\n"
586       "      DEFAULT_INSTANCE, data, extensionRegistry);\n"
587       "}\n"
588       "public static $classname$ parseFrom(\n"
589       "    com.google.protobuf.ByteString data)\n"
590       "    throws com.google.protobuf.InvalidProtocolBufferException {\n"
591       "  return com.google.protobuf.GeneratedMessageLite.parseFrom(\n"
592       "      DEFAULT_INSTANCE, data);\n"
593       "}\n"
594       "public static $classname$ parseFrom(\n"
595       "    com.google.protobuf.ByteString data,\n"
596       "    com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n"
597       "    throws com.google.protobuf.InvalidProtocolBufferException {\n"
598       "  return com.google.protobuf.GeneratedMessageLite.parseFrom(\n"
599       "      DEFAULT_INSTANCE, data, extensionRegistry);\n"
600       "}\n"
601       "public static $classname$ parseFrom(byte[] data)\n"
602       "    throws com.google.protobuf.InvalidProtocolBufferException {\n"
603       "  return com.google.protobuf.GeneratedMessageLite.parseFrom(\n"
604       "      DEFAULT_INSTANCE, data);\n"
605       "}\n"
606       "public static $classname$ parseFrom(\n"
607       "    byte[] data,\n"
608       "    com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n"
609       "    throws com.google.protobuf.InvalidProtocolBufferException {\n"
610       "  return com.google.protobuf.GeneratedMessageLite.parseFrom(\n"
611       "      DEFAULT_INSTANCE, data, extensionRegistry);\n"
612       "}\n"
613       "public static $classname$ parseFrom(java.io.InputStream input)\n"
614       "    throws java.io.IOException {\n"
615       "  return com.google.protobuf.GeneratedMessageLite.parseFrom(\n"
616       "      DEFAULT_INSTANCE, input);\n"
617       "}\n"
618       "public static $classname$ parseFrom(\n"
619       "    java.io.InputStream input,\n"
620       "    com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n"
621       "    throws java.io.IOException {\n"
622       "  return com.google.protobuf.GeneratedMessageLite.parseFrom(\n"
623       "      DEFAULT_INSTANCE, input, extensionRegistry);\n"
624       "}\n"
625       "public static $classname$ parseDelimitedFrom(java.io.InputStream "
626       "input)\n"
627       "    throws java.io.IOException {\n"
628       "  return parseDelimitedFrom(DEFAULT_INSTANCE, input);\n"
629       "}\n"
630       "public static $classname$ parseDelimitedFrom(\n"
631       "    java.io.InputStream input,\n"
632       "    com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n"
633       "    throws java.io.IOException {\n"
634       "  return parseDelimitedFrom(DEFAULT_INSTANCE, input, "
635       "extensionRegistry);\n"
636       "}\n"
637       "public static $classname$ parseFrom(\n"
638       "    com.google.protobuf.CodedInputStream input)\n"
639       "    throws java.io.IOException {\n"
640       "  return com.google.protobuf.GeneratedMessageLite.parseFrom(\n"
641       "      DEFAULT_INSTANCE, input);\n"
642       "}\n"
643       "public static $classname$ parseFrom(\n"
644       "    com.google.protobuf.CodedInputStream input,\n"
645       "    com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n"
646       "    throws java.io.IOException {\n"
647       "  return com.google.protobuf.GeneratedMessageLite.parseFrom(\n"
648       "      DEFAULT_INSTANCE, input, extensionRegistry);\n"
649       "}\n"
650       "\n",
651       "classname", name_resolver_->GetImmutableClassName(descriptor_));
652 }
653 
654 // ===================================================================
655 
GenerateBuilder(io::Printer * printer)656 void ImmutableMessageLiteGenerator::GenerateBuilder(io::Printer* printer) {
657   printer->Print(
658       "public static Builder newBuilder() {\n"
659       "  return (Builder) DEFAULT_INSTANCE.createBuilder();\n"
660       "}\n"
661       "public static Builder newBuilder($classname$ prototype) {\n"
662       "  return (Builder) DEFAULT_INSTANCE.createBuilder(prototype);\n"
663       "}\n"
664       "\n",
665       "classname", name_resolver_->GetImmutableClassName(descriptor_));
666 
667   MessageBuilderLiteGenerator builderGenerator(descriptor_, context_);
668   builderGenerator.Generate(printer);
669 }
670 
671 // ===================================================================
672 
GenerateDynamicMethodNewBuilder(io::Printer * printer)673 void ImmutableMessageLiteGenerator::GenerateDynamicMethodNewBuilder(
674     io::Printer* printer) {
675   printer->Print("return new Builder();\n");
676 }
677 
678 // ===================================================================
679 
GenerateExtensionRegistrationCode(io::Printer * printer)680 void ImmutableMessageLiteGenerator::GenerateExtensionRegistrationCode(
681     io::Printer* printer) {
682   for (int i = 0; i < descriptor_->extension_count(); i++) {
683     ImmutableExtensionLiteGenerator(descriptor_->extension(i), context_)
684         .GenerateRegistrationCode(printer);
685   }
686 
687   for (int i = 0; i < descriptor_->nested_type_count(); i++) {
688     ImmutableMessageLiteGenerator(descriptor_->nested_type(i), context_)
689         .GenerateExtensionRegistrationCode(printer);
690   }
691 }
692 
693 // ===================================================================
GenerateConstructor(io::Printer * printer)694 void ImmutableMessageLiteGenerator::GenerateConstructor(io::Printer* printer) {
695   printer->Print("private $classname$() {\n", "classname", descriptor_->name());
696   printer->Indent();
697 
698   // Initialize all fields to default.
699   GenerateInitializers(printer);
700 
701   printer->Outdent();
702   printer->Print("}\n");
703 }
704 
705 // ===================================================================
GenerateParser(io::Printer * printer)706 void ImmutableMessageLiteGenerator::GenerateParser(io::Printer* printer) {
707   printer->Print(
708       "private static volatile com.google.protobuf.Parser<$classname$> "
709       "PARSER;\n"
710       "\n"
711       "public static com.google.protobuf.Parser<$classname$> parser() {\n"
712       "  return DEFAULT_INSTANCE.getParserForType();\n"
713       "}\n",
714       "classname", descriptor_->name());
715 }
716 
717 // ===================================================================
GenerateInitializers(io::Printer * printer)718 void ImmutableMessageLiteGenerator::GenerateInitializers(io::Printer* printer) {
719   for (int i = 0; i < descriptor_->field_count(); i++) {
720     if (!IsRealOneof(descriptor_->field(i))) {
721       field_generators_.get(descriptor_->field(i))
722           .GenerateInitializationCode(printer);
723     }
724   }
725 }
726 
GenerateKotlinDsl(io::Printer * printer) const727 void ImmutableMessageLiteGenerator::GenerateKotlinDsl(
728     io::Printer* printer) const {
729   printer->Print(
730       "@kotlin.OptIn"
731       "(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)\n"
732       "@com.google.protobuf.kotlin.ProtoDslMarker\n");
733   printer->Print(
734       "public class Dsl private constructor(\n"
735       "  private val _builder: $message$.Builder\n"
736       ") {\n"
737       "  public companion object {\n"
738       "    @kotlin.jvm.JvmSynthetic\n"
739       "    @kotlin.PublishedApi\n"
740       "    internal fun _create(builder: $message$.Builder): Dsl = "
741       "Dsl(builder)\n"
742       "  }\n"
743       "\n"
744       "  @kotlin.jvm.JvmSynthetic\n"
745       "  @kotlin.PublishedApi\n"
746       "  internal fun _build(): $message$ = _builder.build()\n",
747       "message", name_resolver_->GetClassName(descriptor_, true));
748 
749   printer->Indent();
750 
751   for (int i = 0; i < descriptor_->field_count(); i++) {
752     printer->Print("\n");
753     field_generators_.get(descriptor_->field(i))
754         .GenerateKotlinDslMembers(printer);
755   }
756 
757   for (auto oneof : oneofs_) {
758     printer->Print(
759         "public val $oneof_name$Case: $message$.$oneof_capitalized_name$Case\n"
760         "  @JvmName(\"get$oneof_capitalized_name$Case\")\n"
761         "  get() = _builder.get$oneof_capitalized_name$Case()\n\n"
762         "public fun clear$oneof_capitalized_name$() {\n"
763         "  _builder.clear$oneof_capitalized_name$()\n"
764         "}\n",
765         "oneof_name", context_->GetOneofGeneratorInfo(oneof)->name,
766         "oneof_capitalized_name",
767         context_->GetOneofGeneratorInfo(oneof)->capitalized_name, "message",
768         name_resolver_->GetClassName(descriptor_, true));
769   }
770 
771   if (descriptor_->extension_range_count() > 0) {
772     GenerateKotlinExtensions(printer);
773   }
774 
775   printer->Outdent();
776   printer->Print("}\n");
777 }
778 
GenerateKotlinMembers(io::Printer * printer) const779 void ImmutableMessageLiteGenerator::GenerateKotlinMembers(
780     io::Printer* printer) const {
781   printer->Print(
782       "@kotlin.jvm.JvmName(\"-initialize$camelcase_name$\")\n"
783       "public inline fun $camelcase_name$(block: $message_kt$.Dsl.() -> "
784       "kotlin.Unit): "
785       "$message$ =\n"
786       "  $message_kt$.Dsl._create($message$.newBuilder()).apply { block() "
787       "}._build()\n",
788       "camelcase_name", name_resolver_->GetKotlinFactoryName(descriptor_),
789       "message_kt", name_resolver_->GetKotlinExtensionsClassName(descriptor_),
790       "message", name_resolver_->GetClassName(descriptor_, true));
791 
792   printer->Print("public object $name$Kt {\n", "name", descriptor_->name());
793   printer->Indent();
794   GenerateKotlinDsl(printer);
795   for (int i = 0; i < descriptor_->nested_type_count(); i++) {
796     if (IsMapEntry(descriptor_->nested_type(i))) continue;
797     ImmutableMessageLiteGenerator(descriptor_->nested_type(i), context_)
798         .GenerateKotlinMembers(printer);
799   }
800   printer->Outdent();
801   printer->Print("}\n");
802 }
803 
GenerateTopLevelKotlinMembers(io::Printer * printer) const804 void ImmutableMessageLiteGenerator::GenerateTopLevelKotlinMembers(
805     io::Printer* printer) const {
806   printer->Print(
807       "public inline fun $message$.copy(block: $message_kt$.Dsl.() -> "
808       "kotlin.Unit): "
809       "$message$ =\n"
810       "  $message_kt$.Dsl._create(this.toBuilder()).apply { block() "
811       "}._build()\n\n",
812       "message", name_resolver_->GetClassName(descriptor_, true), "message_kt",
813       name_resolver_->GetKotlinExtensionsClassName(descriptor_));
814 
815   for (int i = 0; i < descriptor_->nested_type_count(); i++) {
816     if (IsMapEntry(descriptor_->nested_type(i))) continue;
817     ImmutableMessageLiteGenerator(descriptor_->nested_type(i), context_)
818         .GenerateTopLevelKotlinMembers(printer);
819   }
820 
821   GenerateKotlinOrNull(printer);
822 }
823 
GenerateKotlinOrNull(io::Printer * printer) const824 void ImmutableMessageLiteGenerator::GenerateKotlinOrNull(io::Printer* printer) const {
825   // Generate getFieldOrNull getters for all optional message fields.
826   for (int i = 0; i < descriptor_->field_count(); i++) {
827     const FieldDescriptor* field = descriptor_->field(i);
828     if (field->has_presence() && GetJavaType(field) == JAVATYPE_MESSAGE) {
829       printer->Print(
830           "val $full_classname$OrBuilder.$camelcase_name$OrNull: "
831           "$full_name$?\n"
832           "  get() = if (has$name$()) get$name$() else null\n\n",
833           "full_classname", name_resolver_->GetClassName(descriptor_, true),
834           "camelcase_name", context_->GetFieldGeneratorInfo(field)->name,
835           "full_name",
836           name_resolver_->GetImmutableClassName(field->message_type()), "name",
837           context_->GetFieldGeneratorInfo(field)->capitalized_name);
838     }
839   }
840 }
841 
GenerateKotlinExtensions(io::Printer * printer) const842 void ImmutableMessageLiteGenerator::GenerateKotlinExtensions(
843     io::Printer* printer) const {
844   std::string message_name = name_resolver_->GetClassName(descriptor_, true);
845 
846   printer->Print(
847       "@Suppress(\"UNCHECKED_CAST\")\n"
848       "@kotlin.jvm.JvmSynthetic\n"
849       "public operator fun <T : kotlin.Any> get(extension: "
850       "com.google.protobuf.ExtensionLite<$message$, T>): T {\n"
851       "  return if (extension.isRepeated) {\n"
852       "    get(extension as com.google.protobuf.ExtensionLite<$message$, "
853       "List<*>>) as T\n"
854       "  } else {\n"
855       "    _builder.getExtension(extension)\n"
856       "  }\n"
857       "}\n\n",
858       "message", message_name);
859 
860   printer->Print(
861       "@kotlin.jvm.JvmSynthetic\n"
862       "@kotlin.OptIn"
863       "(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)\n"
864       "@kotlin.jvm.JvmName(\"-getRepeatedExtension\")\n"
865       "public operator fun <E : kotlin.Any> get(\n"
866       "  extension: com.google.protobuf.ExtensionLite<$message$, List<E>>\n"
867       "): com.google.protobuf.kotlin.ExtensionList<E, $message$> {\n"
868       "  return com.google.protobuf.kotlin.ExtensionList(extension, "
869       "_builder.getExtension(extension))\n"
870       "}\n\n",
871       "message", message_name);
872 
873   printer->Print(
874       "@kotlin.jvm.JvmSynthetic\n"
875       "public operator fun contains(extension: "
876       "com.google.protobuf.ExtensionLite<$message$, *>): "
877       "Boolean {\n"
878       "  return _builder.hasExtension(extension)\n"
879       "}\n\n",
880       "message", message_name);
881 
882   printer->Print(
883       "@kotlin.jvm.JvmSynthetic\n"
884       "public fun clear(extension: "
885       "com.google.protobuf.ExtensionLite<$message$, *>) "
886       "{\n"
887       "  _builder.clearExtension(extension)\n"
888       "}\n\n",
889       "message", message_name);
890 
891   printer->Print(
892       "@kotlin.jvm.JvmSynthetic\n"
893       "@kotlin.PublishedApi\n"
894       "internal fun <T : kotlin.Any> setExtension(extension: "
895       "com.google.protobuf.ExtensionLite<$message$, T>, "
896       "value: T) {\n"
897       "  _builder.setExtension(extension, value)\n"
898       "}\n\n",
899       "message", message_name);
900 
901   printer->Print(
902       "@kotlin.jvm.JvmSynthetic\n"
903       "@Suppress(\"NOTHING_TO_INLINE\")\n"
904       "public inline operator fun <T : Comparable<T>> set(\n"
905       "  extension: com.google.protobuf.ExtensionLite<$message$, T>,\n"
906       "  value: T\n"
907       ") {\n"
908       "  setExtension(extension, value)\n"
909       "}\n\n",
910       "message", message_name);
911 
912   printer->Print(
913       "@kotlin.jvm.JvmSynthetic\n"
914       "@Suppress(\"NOTHING_TO_INLINE\")\n"
915       "public inline operator fun set(\n"
916       "  extension: com.google.protobuf.ExtensionLite<$message$, "
917       "com.google.protobuf.ByteString>,\n"
918       "  value: com.google.protobuf.ByteString\n"
919       ") {\n"
920       "  setExtension(extension, value)\n"
921       "}\n\n",
922       "message", message_name);
923 
924   printer->Print(
925       "@kotlin.jvm.JvmSynthetic\n"
926       "@Suppress(\"NOTHING_TO_INLINE\")\n"
927       "public inline operator fun <T : com.google.protobuf.MessageLite> set(\n"
928       "  extension: com.google.protobuf.ExtensionLite<$message$, T>,\n"
929       "  value: T\n"
930       ") {\n"
931       "  setExtension(extension, value)\n"
932       "}\n\n",
933       "message", message_name);
934 
935   printer->Print(
936       "@kotlin.jvm.JvmSynthetic\n"
937       "public fun<E : kotlin.Any> com.google.protobuf.kotlin.ExtensionList<E, "
938       "$message$>.add(value: E) {\n"
939       "  _builder.addExtension(this.extension, value)\n"
940       "}\n\n",
941       "message", message_name);
942 
943   printer->Print(
944       "@kotlin.jvm.JvmSynthetic\n"
945       "@Suppress(\"NOTHING_TO_INLINE\")\n"
946       "public inline operator fun <E : kotlin.Any> "
947       "com.google.protobuf.kotlin.ExtensionList<E, "
948       "$message$>.plusAssign"
949       "(value: E) {\n"
950       "  add(value)\n"
951       "}\n\n",
952       "message", message_name);
953 
954   printer->Print(
955       "@kotlin.jvm.JvmSynthetic\n"
956       "public fun<E : kotlin.Any> com.google.protobuf.kotlin.ExtensionList<E, "
957       "$message$>.addAll(values: Iterable<E>) {\n"
958       "  for (value in values) {\n"
959       "    add(value)\n"
960       "  }\n"
961       "}\n\n",
962       "message", message_name);
963 
964   printer->Print(
965       "@kotlin.jvm.JvmSynthetic\n"
966       "@Suppress(\"NOTHING_TO_INLINE\")\n"
967       "public inline operator fun <E : kotlin.Any> "
968       "com.google.protobuf.kotlin.ExtensionList<E, "
969       "$message$>.plusAssign(values: "
970       "Iterable<E>) {\n"
971       "  addAll(values)\n"
972       "}\n\n",
973       "message", message_name);
974 
975   printer->Print(
976       "@kotlin.jvm.JvmSynthetic\n"
977       "public operator fun <E : kotlin.Any> "
978       "com.google.protobuf.kotlin.ExtensionList<E, "
979       "$message$>.set(index: Int, value: "
980       "E) {\n"
981       "  _builder.setExtension(this.extension, index, value)\n"
982       "}\n\n",
983       "message", message_name);
984 
985   printer->Print(
986       "@kotlin.jvm.JvmSynthetic\n"
987       "@Suppress(\"NOTHING_TO_INLINE\")\n"
988       "public inline fun com.google.protobuf.kotlin.ExtensionList<*, "
989       "$message$>.clear() {\n"
990       "  clear(extension)\n"
991       "}\n\n",
992       "message", message_name);
993 }
994 
995 }  // namespace java
996 }  // namespace compiler
997 }  // namespace protobuf
998 }  // namespace google
999