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