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