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/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
62namespace google {
63namespace protobuf {
64namespace compiler {
65namespace java {
66
67using internal::WireFormat;
68using internal::WireFormatLite;
69
70// ===================================================================
71ImmutableMessageLiteGenerator::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: descriptor_->field(index: i))) {
82 oneofs_.insert(x: descriptor_->field(index: i)->containing_oneof());
83 }
84 }
85}
86
87ImmutableMessageLiteGenerator::~ImmutableMessageLiteGenerator() {}
88
89void 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(index: i), context_)
95 .GenerateStaticVariables(printer, bytecode_estimate);
96 }
97}
98
99int 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(index: i), context_)
107 .GenerateStaticVariableInitializers(printer);
108 }
109 return bytecode_estimate;
110}
111
112// ===================================================================
113
114void ImmutableMessageLiteGenerator::GenerateInterface(io::Printer* printer) {
115 MaybePrintGeneratedAnnotation(context: context_, printer, descriptor: descriptor_,
116 /* immutable = */ true, suffix: "OrBuilder");
117 if (descriptor_->extension_range_count() > 0) {
118 printer->Print(
119 text: "$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 args: "deprecation",
125 args: descriptor_->options().deprecated() ? "@java.lang.Deprecated " : "",
126 args: "extra_interfaces", args: ExtraMessageOrBuilderInterfaces(descriptor: descriptor_),
127 args: "classname", args: descriptor_->name(), args: "{", args: "", args: "}", args: "");
128 } else {
129 printer->Print(
130 text: "$deprecation$public interface ${$$classname$OrBuilder$}$ extends\n"
131 " $extra_interfaces$\n"
132 " com.google.protobuf.MessageLiteOrBuilder {\n",
133 args: "deprecation",
134 args: descriptor_->options().deprecated() ? "@java.lang.Deprecated " : "",
135 args: "extra_interfaces", args: ExtraMessageOrBuilderInterfaces(descriptor: descriptor_),
136 args: "classname", args: descriptor_->name(), args: "{", args: "", args: "}", args: "");
137 }
138 printer->Annotate(begin_varname: "{", end_varname: "}", descriptor: descriptor_);
139
140 printer->Indent();
141 for (int i = 0; i < descriptor_->field_count(); i++) {
142 printer->Print(text: "\n");
143 field_generators_.get(field: descriptor_->field(index: i))
144 .GenerateInterfaceMembers(printer);
145 }
146 for (auto oneof : oneofs_) {
147 printer->Print(
148 text: "\n"
149 "public $classname$.$oneof_capitalized_name$Case "
150 "get$oneof_capitalized_name$Case();\n",
151 args: "oneof_capitalized_name",
152 args: context_->GetOneofGeneratorInfo(oneof)->capitalized_name, args: "classname",
153 args: context_->GetNameResolver()->GetImmutableClassName(descriptor: descriptor_));
154 }
155 printer->Outdent();
156
157 printer->Print(text: "}\n");
158}
159
160// ===================================================================
161
162void ImmutableMessageLiteGenerator::Generate(io::Printer* printer) {
163 bool is_own_file = IsOwnFile(descriptor: 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: descriptor_);
169 variables["deprecation"] =
170 descriptor_->options().deprecated() ? "@java.lang.Deprecated " : "";
171
172 WriteMessageDocComment(printer, message: descriptor_);
173 MaybePrintGeneratedAnnotation(context: context_, printer, descriptor: 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 text: "$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 format: "com.google.protobuf.GeneratedMessageLite.ExtendableBuilder<$0, ?>",
189 arg0: name_resolver_->GetImmutableClassName(descriptor: descriptor_));
190 } else {
191 printer->Print(
192 variables,
193 text: "$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(index: 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: descriptor_->nested_type(index: i))) continue;
214 ImmutableMessageLiteGenerator messageGenerator(descriptor_->nested_type(index: 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(field: descriptor_->field(index: i)).GetNumBitsForMessage();
225 }
226 int totalInts = (totalBits + 31) / 32;
227 for (int i = 0; i < totalInts; i++) {
228 printer->Print(text: "private int $bit_field_name$;\n", args: "bit_field_name",
229 args: GetBitFieldName(index: 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(a: (oneof)->index());
239 // oneofCase_ and oneof_
240 printer->Print(variables: vars,
241 text: "private int $oneof_name$Case_ = 0;\n"
242 "private java.lang.Object $oneof_name$_;\n");
243 // OneofCase enum
244 printer->Print(variables: vars, text: "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(index: j);
248 printer->Print(text: "$field_name$($field_number$),\n", args: "field_name",
249 args: ToUpper(s: field->name()), args: "field_number",
250 args: StrCat(a: field->number()));
251 }
252 printer->Print(text: "$cap_oneof_name$_NOT_SET(0);\n", args: "cap_oneof_name",
253 args: ToUpper(s: vars["oneof_name"]));
254 printer->Print(variables: vars,
255 text: "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 variables: vars,
261 text: "/**\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(index: j);
273 printer->Print(text: " case $field_number$: return $field_name$;\n",
274 args: "field_number", args: StrCat(a: field->number()),
275 args: "field_name", args: ToUpper(s: field->name()));
276 }
277 printer->Print(
278 text: " 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 args: "cap_oneof_name", args: ToUpper(s: vars["oneof_name"]));
288 printer->Outdent();
289 printer->Print(text: "};\n\n");
290 // oneofCase()
291 printer->Print(variables: vars,
292 text: "@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(text: "public static final int $constant_name$ = $number$;\n",
309 args: "constant_name", args: FieldConstantName(field: descriptor_->field(index: i)),
310 args: "number", args: StrCat(a: descriptor_->field(index: i)->number()));
311 field_generators_.get(field: descriptor_->field(index: i)).GenerateMembers(printer);
312 printer->Print(text: "\n");
313 }
314
315 GenerateParseFromMethods(printer);
316 GenerateBuilder(printer);
317
318 if (HasRequiredFields(descriptor: 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(text: "private byte memoizedIsInitialized = 2;\n");
323 }
324
325 printer->Print(
326 text: "@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 args: "classname", args: name_resolver_->GetImmutableClassName(descriptor: descriptor_));
336
337 printer->Indent();
338 printer->Indent();
339
340 printer->Print(text: "case NEW_BUILDER: {\n");
341
342 printer->Indent();
343 GenerateDynamicMethodNewBuilder(printer);
344 printer->Outdent();
345
346 printer->Print(
347 text: "}\n"
348 "case BUILD_MESSAGE_INFO: {\n");
349
350 printer->Indent();
351 GenerateDynamicMethodNewBuildMessageInfo(printer);
352 printer->Outdent();
353
354 printer->Print(
355 text: "}\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 args: "classname", args: name_resolver_->GetImmutableClassName(descriptor: descriptor_));
382
383 printer->Outdent();
384
385 if (HasRequiredFields(descriptor: descriptor_)) {
386 printer->Print(
387 text: "}\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 text: "}\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 text: " }\n"
409 " throw new UnsupportedOperationException();\n"
410 "}\n"
411 "\n",
412 args: "classname", args: name_resolver_->GetImmutableClassName(descriptor: descriptor_));
413
414 printer->Print(
415 text: "\n"
416 "// @@protoc_insertion_point(class_scope:$full_name$)\n",
417 args: "full_name", args: 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(text: "private static final $classname$ DEFAULT_INSTANCE;\n",
422 args: "classname",
423 args: name_resolver_->GetImmutableClassName(descriptor: descriptor_));
424
425 printer->Print(
426 text: "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 args: "classname", args: descriptor_->name());
439
440 printer->Print(
441 text: "public static $classname$ getDefaultInstance() {\n"
442 " return DEFAULT_INSTANCE;\n"
443 "}\n"
444 "\n",
445 args: "classname", args: name_resolver_->GetImmutableClassName(descriptor: descriptor_));
446
447 // 'of' method for Wrappers
448 if (IsWrappersProtoFile(descriptor: descriptor_->file())) {
449 printer->Print(
450 text: "public static $classname$ of($field_type$ value) {\n"
451 " return newBuilder().setValue(value).build();\n"
452 "}\n"
453 "\n",
454 args: "classname", args: name_resolver_->GetImmutableClassName(descriptor: descriptor_),
455 args: "field_type", args: PrimitiveTypeName(type: GetJavaType(field: descriptor_->field(index: 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(index: i), context_)
465 .Generate(printer);
466 }
467
468 printer->Outdent();
469 printer->Print(text: "}\n\n");
470}
471
472void 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: descriptor_->file())) {
482 flags |= 0x1;
483 }
484 if (descriptor_->options().message_set_wire_format()) {
485 flags |= 0x2;
486 }
487 WriteIntToUtf16CharSequence(value: flags, output: &chars);
488 WriteIntToUtf16CharSequence(value: descriptor_->field_count(), output: &chars);
489
490 if (descriptor_->field_count() == 0) {
491 printer->Print(text: "java.lang.Object[] objects = null;");
492 } else {
493 // A single array of all fields (including oneof, oneofCase, hasBits).
494 printer->Print(text: "java.lang.Object[] objects = new java.lang.Object[] {\n");
495 printer->Indent();
496
497 // Record the number of oneofs.
498 WriteIntToUtf16CharSequence(value: oneofs_.size(), output: &chars);
499 for (auto oneof : oneofs_) {
500 printer->Print(
501 text: "\"$oneof_name$_\",\n"
502 "\"$oneof_name$Case_\",\n",
503 args: "oneof_name", args: 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(field: descriptor_->field(index: i)).GetNumBitsForMessage();
511 }
512 int total_ints = (total_bits + 31) / 32;
513 for (int i = 0; i < total_ints; i++) {
514 printer->Print(text: "\"$bit_field_name$\",\n", args: "bit_field_name",
515 args: GetBitFieldName(index: i));
516 }
517 WriteIntToUtf16CharSequence(value: total_ints, output: &chars);
518
519 int map_count = 0;
520 int repeated_count = 0;
521 std::unique_ptr<const FieldDescriptor*[]> sorted_fields(
522 SortFieldsByNumber(descriptor: 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(value: sorted_fields[0]->number(), output: &chars);
533 WriteIntToUtf16CharSequence(
534 value: sorted_fields[descriptor_->field_count() - 1]->number(), output: &chars);
535 WriteIntToUtf16CharSequence(value: descriptor_->field_count(), output: &chars);
536 WriteIntToUtf16CharSequence(value: map_count, output: &chars);
537 WriteIntToUtf16CharSequence(value: repeated_count, output: &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(index: i)->is_required() ||
542 (GetJavaType(field: descriptor_->field(index: i)) == JAVATYPE_MESSAGE &&
543 HasRequiredFields(descriptor: descriptor_->field(index: i)->message_type()))) {
544 fields_for_is_initialized_check.push_back(x: descriptor_->field(index: i));
545 }
546 }
547 WriteIntToUtf16CharSequence(value: fields_for_is_initialized_check.size(), output: &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, output: &chars);
552 }
553 printer->Outdent();
554 printer->Print(text: "};\n");
555 }
556
557 printer->Print(text: "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, output: &line);
562 if (line.size() >= 80) {
563 printer->Print(text: " \"$string$\" +\n", args: "string", args: line);
564 line.clear();
565 }
566 }
567 printer->Print(text: " \"$string$\";\n", args: "string", args: line);
568
569 printer->Print(text: "return newMessageInfo(DEFAULT_INSTANCE, info, objects);\n");
570 printer->Outdent();
571}
572
573// ===================================================================
574
575void ImmutableMessageLiteGenerator::GenerateParseFromMethods(
576 io::Printer* printer) {
577 printer->Print(
578 text: "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 args: "classname", args: name_resolver_->GetImmutableClassName(descriptor: descriptor_));
655}
656
657// ===================================================================
658
659void ImmutableMessageLiteGenerator::GenerateBuilder(io::Printer* printer) {
660 printer->Print(
661 text: "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 args: "classname", args: name_resolver_->GetImmutableClassName(descriptor: descriptor_));
669
670 MessageBuilderLiteGenerator builderGenerator(descriptor_, context_);
671 builderGenerator.Generate(printer);
672}
673
674// ===================================================================
675
676void ImmutableMessageLiteGenerator::GenerateDynamicMethodNewBuilder(
677 io::Printer* printer) {
678 printer->Print(text: "return new Builder();\n");
679}
680
681// ===================================================================
682
683void ImmutableMessageLiteGenerator::GenerateExtensionRegistrationCode(
684 io::Printer* printer) {
685 for (int i = 0; i < descriptor_->extension_count(); i++) {
686 ImmutableExtensionLiteGenerator(descriptor_->extension(index: i), context_)
687 .GenerateRegistrationCode(printer);
688 }
689
690 for (int i = 0; i < descriptor_->nested_type_count(); i++) {
691 ImmutableMessageLiteGenerator(descriptor_->nested_type(index: i), context_)
692 .GenerateExtensionRegistrationCode(printer);
693 }
694}
695
696// ===================================================================
697void ImmutableMessageLiteGenerator::GenerateConstructor(io::Printer* printer) {
698 printer->Print(text: "private $classname$() {\n", args: "classname", args: descriptor_->name());
699 printer->Indent();
700
701 // Initialize all fields to default.
702 GenerateInitializers(printer);
703
704 printer->Outdent();
705 printer->Print(text: "}\n");
706}
707
708// ===================================================================
709void ImmutableMessageLiteGenerator::GenerateParser(io::Printer* printer) {
710 printer->Print(
711 text: "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 args: "classname", args: descriptor_->name());
718}
719
720// ===================================================================
721void ImmutableMessageLiteGenerator::GenerateInitializers(io::Printer* printer) {
722 for (int i = 0; i < descriptor_->field_count(); i++) {
723 if (!IsRealOneof(descriptor: descriptor_->field(index: i))) {
724 field_generators_.get(field: descriptor_->field(index: i))
725 .GenerateInitializationCode(printer);
726 }
727 }
728}
729
730void ImmutableMessageLiteGenerator::GenerateKotlinDsl(
731 io::Printer* printer) const {
732 printer->Print(
733 text: "@kotlin.OptIn"
734 "(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)\n"
735 "@com.google.protobuf.kotlin.ProtoDslMarker\n");
736 printer->Print(
737 text: "class Dsl private constructor(\n"
738 " private val _builder: $message$.Builder\n"
739 ") {\n"
740 " 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 args: "message", args: name_resolver_->GetClassName(descriptor: descriptor_, immutable: true));
751
752 printer->Indent();
753
754 for (int i = 0; i < descriptor_->field_count(); i++) {
755 printer->Print(text: "\n");
756 field_generators_.get(field: descriptor_->field(index: i))
757 .GenerateKotlinDslMembers(printer);
758 }
759
760 for (auto oneof : oneofs_) {
761 printer->Print(
762 text: "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 "fun clear$oneof_capitalized_name$() {\n"
766 " _builder.clear$oneof_capitalized_name$()\n"
767 "}\n",
768 args: "oneof_name", args: context_->GetOneofGeneratorInfo(oneof)->name,
769 args: "oneof_capitalized_name",
770 args: context_->GetOneofGeneratorInfo(oneof)->capitalized_name, args: "message",
771 args: name_resolver_->GetClassName(descriptor: descriptor_, immutable: true));
772 }
773
774 if (descriptor_->extension_range_count() > 0) {
775 GenerateKotlinExtensions(printer);
776 }
777
778 printer->Outdent();
779 printer->Print(text: "}\n");
780}
781
782void ImmutableMessageLiteGenerator::GenerateKotlinMembers(
783 io::Printer* printer) const {
784 printer->Print(
785 text: "@kotlin.jvm.JvmName(\"-initialize$camelcase_name$\")\n"
786 "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 args: "camelcase_name", args: name_resolver_->GetKotlinFactoryName(descriptor: descriptor_),
792 args: "message_kt", args: name_resolver_->GetKotlinExtensionsClassName(descriptor: descriptor_),
793 args: "message", args: name_resolver_->GetClassName(descriptor: descriptor_, immutable: true));
794
795 printer->Print(text: "object $name$Kt {\n", args: "name", args: descriptor_->name());
796 printer->Indent();
797 GenerateKotlinDsl(printer);
798 for (int i = 0; i < descriptor_->nested_type_count(); i++) {
799 if (IsMapEntry(descriptor: descriptor_->nested_type(index: i))) continue;
800 ImmutableMessageLiteGenerator(descriptor_->nested_type(index: i), context_)
801 .GenerateKotlinMembers(printer);
802 }
803 printer->Outdent();
804 printer->Print(text: "}\n");
805}
806
807void ImmutableMessageLiteGenerator::GenerateTopLevelKotlinMembers(
808 io::Printer* printer) const {
809 printer->Print(
810 text: "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 args: "message", args: name_resolver_->GetClassName(descriptor: descriptor_, immutable: true), args: "message_kt",
816 args: name_resolver_->GetKotlinExtensionsClassName(descriptor: descriptor_));
817
818 for (int i = 0; i < descriptor_->nested_type_count(); i++) {
819 if (IsMapEntry(descriptor: descriptor_->nested_type(index: i))) continue;
820 ImmutableMessageLiteGenerator(descriptor_->nested_type(index: i), context_)
821 .GenerateTopLevelKotlinMembers(printer);
822 }
823
824 GenerateKotlinOrNull(printer);
825}
826
827void 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(index: i);
831 if (field->has_presence() && GetJavaType(field) == JAVATYPE_MESSAGE) {
832 printer->Print(
833 text: "val $full_classname$OrBuilder.$camelcase_name$OrNull: "
834 "$full_name$?\n"
835 " get() = if (has$name$()) get$name$() else null\n\n",
836 args: "full_classname", args: name_resolver_->GetClassName(descriptor: descriptor_, immutable: true),
837 args: "camelcase_name", args: context_->GetFieldGeneratorInfo(field)->name,
838 args: "full_name",
839 args: name_resolver_->GetImmutableClassName(descriptor: field->message_type()), args: "name",
840 args: context_->GetFieldGeneratorInfo(field)->capitalized_name);
841 }
842 }
843}
844
845void ImmutableMessageLiteGenerator::GenerateKotlinExtensions(
846 io::Printer* printer) const {
847 std::string message_name = name_resolver_->GetClassName(descriptor: descriptor_, immutable: true);
848
849 printer->Print(
850 text: "@Suppress(\"UNCHECKED_CAST\")\n"
851 "@kotlin.jvm.JvmSynthetic\n"
852 "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 args: "message", args: message_name);
862
863 printer->Print(
864 text: "@kotlin.jvm.JvmSynthetic\n"
865 "@kotlin.OptIn"
866 "(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)\n"
867 "@kotlin.jvm.JvmName(\"-getRepeatedExtension\")\n"
868 "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 args: "message", args: message_name);
875
876 printer->Print(
877 text: "@kotlin.jvm.JvmSynthetic\n"
878 "operator fun contains(extension: "
879 "com.google.protobuf.ExtensionLite<$message$, *>): "
880 "Boolean {\n"
881 " return _builder.hasExtension(extension)\n"
882 "}\n\n",
883 args: "message", args: message_name);
884
885 printer->Print(
886 text: "@kotlin.jvm.JvmSynthetic\n"
887 "fun clear(extension: "
888 "com.google.protobuf.ExtensionLite<$message$, *>) "
889 "{\n"
890 " _builder.clearExtension(extension)\n"
891 "}\n\n",
892 args: "message", args: message_name);
893
894 printer->Print(
895 text: "@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 args: "message", args: message_name);
903
904 printer->Print(
905 text: "@kotlin.jvm.JvmSynthetic\n"
906 "@Suppress(\"NOTHING_TO_INLINE\")\n"
907 "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 args: "message", args: message_name);
914
915 printer->Print(
916 text: "@kotlin.jvm.JvmSynthetic\n"
917 "@Suppress(\"NOTHING_TO_INLINE\")\n"
918 "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 args: "message", args: message_name);
926
927 printer->Print(
928 text: "@kotlin.jvm.JvmSynthetic\n"
929 "@Suppress(\"NOTHING_TO_INLINE\")\n"
930 "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 args: "message", args: message_name);
937
938 printer->Print(
939 text: "@kotlin.jvm.JvmSynthetic\n"
940 "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 args: "message", args: message_name);
945
946 printer->Print(
947 text: "@kotlin.jvm.JvmSynthetic\n"
948 "@Suppress(\"NOTHING_TO_INLINE\")\n"
949 "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 args: "message", args: message_name);
956
957 printer->Print(
958 text: "@kotlin.jvm.JvmSynthetic\n"
959 "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 args: "message", args: message_name);
966
967 printer->Print(
968 text: "@kotlin.jvm.JvmSynthetic\n"
969 "@Suppress(\"NOTHING_TO_INLINE\")\n"
970 "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 args: "message", args: message_name);
977
978 printer->Print(
979 text: "@kotlin.jvm.JvmSynthetic\n"
980 "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 args: "message", args: message_name);
987
988 printer->Print(
989 text: "@kotlin.jvm.JvmSynthetic\n"
990 "@Suppress(\"NOTHING_TO_INLINE\")\n"
991 "inline fun com.google.protobuf.kotlin.ExtensionList<*, "
992 "$message$>.clear() {\n"
993 " clear(extension)\n"
994 "}\n\n",
995 args: "message", args: 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