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