1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2008 Google Inc. All rights reserved.
3 //
4 // Use of this source code is governed by a BSD-style
5 // license that can be found in the LICENSE file or at
6 // https://developers.google.com/open-source/licenses/bsd
7
8 // Author: dweis@google.com (Daniel Weis)
9 // Based on original Protocol Buffers design by
10 // Sanjay Ghemawat, Jeff Dean, and others.
11
12 #include "google/protobuf/compiler/java/lite/message.h"
13
14 #include <algorithm>
15 #include <cstddef>
16 #include <cstdint>
17 #include <memory>
18 #include <string>
19 #include <utility>
20 #include <vector>
21
22 #include "absl/container/flat_hash_map.h"
23 #include "absl/log/absl_check.h"
24 #include "absl/strings/ascii.h"
25 #include "absl/strings/str_cat.h"
26 #include "absl/strings/string_view.h"
27 #include "absl/strings/substitute.h"
28 #include "google/protobuf/compiler/java/context.h"
29 #include "google/protobuf/compiler/java/doc_comment.h"
30 #include "google/protobuf/compiler/java/field_common.h"
31 #include "google/protobuf/compiler/java/generator.h"
32 #include "google/protobuf/compiler/java/generator_factory.h"
33 #include "google/protobuf/compiler/java/helpers.h"
34 #include "google/protobuf/compiler/java/lite/enum.h"
35 #include "google/protobuf/compiler/java/lite/extension.h"
36 #include "google/protobuf/compiler/java/lite/make_field_gens.h"
37 #include "google/protobuf/compiler/java/lite/message_builder.h"
38 #include "google/protobuf/compiler/java/name_resolver.h"
39 #include "google/protobuf/descriptor.pb.h"
40 #include "google/protobuf/io/coded_stream.h"
41 #include "google/protobuf/io/printer.h"
42 #include "google/protobuf/wire_format.h"
43
44 // Must be last.
45 #include "google/protobuf/port_def.inc"
46
47 namespace google {
48 namespace protobuf {
49 namespace compiler {
50 namespace java {
51
52 using internal::WireFormat;
53 using internal::WireFormatLite;
54
55 // ===================================================================
ImmutableMessageLiteGenerator(const Descriptor * descriptor,Context * context)56 ImmutableMessageLiteGenerator::ImmutableMessageLiteGenerator(
57 const Descriptor* descriptor, Context* context)
58 : MessageGenerator(descriptor),
59 context_(context),
60 name_resolver_(context->GetNameResolver()),
61 field_generators_(MakeImmutableFieldLiteGenerators(descriptor, context)) {
62 ABSL_CHECK(!HasDescriptorMethods(descriptor->file(), context->EnforceLite()))
63 << "Generator factory error: A lite message generator is used to "
64 "generate non-lite messages.";
65 for (int i = 0; i < descriptor_->field_count(); i++) {
66 if (IsRealOneof(descriptor_->field(i))) {
67 const OneofDescriptor* oneof = descriptor_->field(i)->containing_oneof();
68 ABSL_CHECK(oneofs_.emplace(oneof->index(), oneof).first->second == oneof);
69 }
70 }
71 }
72
~ImmutableMessageLiteGenerator()73 ImmutableMessageLiteGenerator::~ImmutableMessageLiteGenerator() {}
74
GenerateStaticVariables(io::Printer * printer,int * bytecode_estimate)75 void ImmutableMessageLiteGenerator::GenerateStaticVariables(
76 io::Printer* printer, int* bytecode_estimate) {
77 // No-op for lite.
78 }
79
GenerateStaticVariableInitializers(io::Printer * printer)80 int ImmutableMessageLiteGenerator::GenerateStaticVariableInitializers(
81 io::Printer* printer) {
82 // No-op for lite.
83 return 0;
84 }
85
86 // ===================================================================
87
GenerateInterface(io::Printer * printer)88 void ImmutableMessageLiteGenerator::GenerateInterface(io::Printer* printer) {
89 MaybePrintGeneratedAnnotation(context_, printer, descriptor_,
90 /* immutable = */ true, "OrBuilder");
91
92 absl::flat_hash_map<absl::string_view, std::string> variables = {
93 {"{", ""},
94 {"}", ""},
95 {"deprecation",
96 descriptor_->options().deprecated() ? "@java.lang.Deprecated " : ""},
97 {"extra_interfaces", ExtraMessageOrBuilderInterfaces(descriptor_)},
98 {"classname", std::string(descriptor_->name())},
99 };
100
101 if (!context_->options().opensource_runtime) {
102 printer->Print("@com.google.protobuf.Internal.ProtoNonnullApi\n");
103 }
104 if (descriptor_->extension_range_count() > 0) {
105 printer->Print(
106 variables,
107 "$deprecation$public interface ${$$classname$OrBuilder$}$ extends \n"
108 " $extra_interfaces$\n"
109 " com.google.protobuf.GeneratedMessageLite.\n"
110 " ExtendableMessageOrBuilder<\n"
111 " $classname$, $classname$.Builder> {\n");
112 } else {
113 printer->Print(
114 variables,
115 "$deprecation$public interface ${$$classname$OrBuilder$}$ extends\n"
116 " $extra_interfaces$\n"
117 " com.google.protobuf.MessageLiteOrBuilder {\n");
118 }
119 printer->Annotate("{", "}", descriptor_);
120
121 printer->Indent();
122 for (int i = 0; i < descriptor_->field_count(); i++) {
123 printer->Print("\n");
124 field_generators_.get(descriptor_->field(i))
125 .GenerateInterfaceMembers(printer);
126 }
127 for (auto& kv : oneofs_) {
128 const OneofDescriptor* oneof = kv.second;
129 variables["oneof_capitalized_name"] =
130 context_->GetOneofGeneratorInfo(oneof)->capitalized_name;
131 variables["classname"] =
132 context_->GetNameResolver()->GetImmutableClassName(descriptor_);
133 printer->Print(variables,
134 "\n"
135 "public ${$$classname$.$oneof_capitalized_name$Case$}$ "
136 "get$oneof_capitalized_name$Case();\n");
137 printer->Annotate("{", "}", oneof);
138 }
139 printer->Outdent();
140
141 printer->Print("}\n");
142 }
143
144 // ===================================================================
145
Generate(io::Printer * printer)146 void ImmutableMessageLiteGenerator::Generate(io::Printer* printer) {
147 bool is_own_file = IsOwnFile(descriptor_, /* immutable = */ true);
148
149 absl::flat_hash_map<absl::string_view, std::string> variables = {{"{", ""},
150 {"}", ""}};
151 variables["static"] = is_own_file ? " " : " static ";
152 variables["classname"] = descriptor_->name();
153 variables["extra_interfaces"] = ExtraMessageInterfaces(descriptor_);
154 variables["deprecation"] =
155 descriptor_->options().deprecated() ? "@java.lang.Deprecated " : "";
156
157 WriteMessageDocComment(printer, descriptor_, context_->options());
158 MaybePrintGeneratedAnnotation(context_, printer, descriptor_,
159 /* immutable = */ true);
160
161
162 // The builder_type stores the super type name of the nested Builder class.
163 std::string builder_type;
164 if (descriptor_->extension_range_count() > 0) {
165 printer->Print(
166 variables,
167 "$deprecation$public $static$final class ${$$classname$$}$ extends\n"
168 " com.google.protobuf.GeneratedMessageLite.ExtendableMessage<\n"
169 " $classname$, $classname$.Builder> implements\n"
170 " $extra_interfaces$\n"
171 " $classname$OrBuilder {\n");
172 builder_type = absl::Substitute(
173 "com.google.protobuf.GeneratedMessageLite.ExtendableBuilder<$0, ?>",
174 name_resolver_->GetImmutableClassName(descriptor_));
175 } else {
176 printer->Print(
177 variables,
178 "$deprecation$public $static$final class ${$$classname$$}$ extends\n"
179 " com.google.protobuf.GeneratedMessageLite<\n"
180 " $classname$, $classname$.Builder> implements\n"
181 " $extra_interfaces$\n"
182 " $classname$OrBuilder {\n");
183
184 builder_type = "com.google.protobuf.GeneratedMessageLite.Builder";
185 }
186 printer->Annotate("{", "}", descriptor_);
187 printer->Indent();
188
189 GenerateConstructor(printer);
190
191 // Nested types
192 for (int i = 0; i < descriptor_->enum_type_count(); i++) {
193 EnumLiteGenerator(descriptor_->enum_type(i), true, context_)
194 .Generate(printer);
195 }
196
197 for (int i = 0; i < descriptor_->nested_type_count(); i++) {
198 // Don't generate Java classes for map entry messages.
199 if (IsMapEntry(descriptor_->nested_type(i))) continue;
200 ImmutableMessageLiteGenerator messageGenerator(descriptor_->nested_type(i),
201 context_);
202 messageGenerator.GenerateInterface(printer);
203 messageGenerator.Generate(printer);
204 }
205
206 // Integers for bit fields.
207 int totalBits = 0;
208 for (int i = 0; i < descriptor_->field_count(); i++) {
209 totalBits +=
210 field_generators_.get(descriptor_->field(i)).GetNumBitsForMessage();
211 }
212 int totalInts = (totalBits + 31) / 32;
213 for (int i = 0; i < totalInts; i++) {
214 printer->Print("private int $bit_field_name$;\n", "bit_field_name",
215 GetBitFieldName(i));
216 }
217
218 // oneof
219 absl::flat_hash_map<absl::string_view, std::string> vars = {{"{", ""},
220 {"}", ""}};
221 for (auto& kv : oneofs_) {
222 const OneofDescriptor* oneof = kv.second;
223 vars["oneof_name"] = context_->GetOneofGeneratorInfo(oneof)->name;
224 vars["oneof_capitalized_name"] =
225 context_->GetOneofGeneratorInfo(oneof)->capitalized_name;
226 vars["oneof_index"] = absl::StrCat((oneof)->index());
227 if (context_->options().opensource_runtime) {
228 // oneofCase_ and oneof_
229 printer->Print(vars,
230 "private int $oneof_name$Case_ = 0;\n"
231 "private java.lang.Object $oneof_name$_;\n");
232 }
233 // OneofCase enum
234 printer->Print(vars, "public enum ${$$oneof_capitalized_name$Case$}$ {\n");
235 printer->Annotate("{", "}", oneof);
236 printer->Indent();
237 for (int j = 0; j < (oneof)->field_count(); j++) {
238 const FieldDescriptor* field = (oneof)->field(j);
239 printer->Print("$field_name$($field_number$),\n", "field_name",
240 absl::AsciiStrToUpper(field->name()), "field_number",
241 absl::StrCat(field->number()));
242 printer->Annotate("field_name", field);
243 }
244 printer->Print("$cap_oneof_name$_NOT_SET(0);\n", "cap_oneof_name",
245 absl::AsciiStrToUpper(vars["oneof_name"]));
246 printer->Print(vars,
247 "private final int value;\n"
248 "private $oneof_capitalized_name$Case(int value) {\n"
249 " this.value = value;\n"
250 "}\n");
251 if (context_->options().opensource_runtime) {
252 printer->Print(
253 vars,
254 "/**\n"
255 " * @deprecated Use {@link #forNumber(int)} instead.\n"
256 " */\n"
257 "@java.lang.Deprecated\n"
258 "public static $oneof_capitalized_name$Case valueOf(int value) {\n"
259 " return forNumber(value);\n"
260 "}\n"
261 "\n");
262 }
263 if (!context_->options().opensource_runtime) {
264 printer->Print(
265 "@com.google.protobuf.Internal.ProtoMethodMayReturnNull\n");
266 }
267 printer->Print(
268 vars,
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", absl::StrCat(field->number()),
275 "field_name", absl::AsciiStrToUpper(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: 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", absl::AsciiStrToUpper(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 printer->Annotate("{", "}", oneof);
299 printer->Print(vars,
300 "\n"
301 "private void ${$clear$oneof_capitalized_name$$}$() {\n"
302 " $oneof_name$Case_ = 0;\n"
303 " $oneof_name$_ = null;\n"
304 "}\n"
305 "\n");
306 printer->Annotate("{", "}", oneof);
307 }
308
309 // Fields
310 for (int i = 0; i < descriptor_->field_count(); i++) {
311 printer->Print("public static final int $constant_name$ = $number$;\n",
312 "constant_name", FieldConstantName(descriptor_->field(i)),
313 "number", absl::StrCat(descriptor_->field(i)->number()));
314 printer->Annotate("constant_name", descriptor_->field(i));
315 field_generators_.get(descriptor_->field(i)).GenerateMembers(printer);
316 printer->Print("\n");
317 }
318
319 GenerateParseFromMethods(printer);
320 GenerateBuilder(printer);
321
322 if (HasRequiredFields(descriptor_)) {
323 // Memoizes whether the protocol buffer is fully initialized (has all
324 // required fields). 0 means false, 1 means true, and all other values
325 // mean not yet computed.
326 printer->Print("private byte memoizedIsInitialized = 2;\n");
327 }
328
329 printer->Print(
330 "@java.lang.Override\n"
331 "@java.lang.SuppressWarnings({\"unchecked\", \"fallthrough\"})\n"
332 "protected final java.lang.Object dynamicMethod(\n"
333 " com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,\n"
334 " java.lang.Object arg0, java.lang.Object arg1) {\n"
335 " switch (method) {\n"
336 " case NEW_MUTABLE_INSTANCE: {\n"
337 " return new $classname$();\n"
338 " }\n",
339 "classname", name_resolver_->GetImmutableClassName(descriptor_));
340
341 printer->Indent();
342 printer->Indent();
343
344 printer->Print("case NEW_BUILDER: {\n");
345
346 printer->Indent();
347 GenerateDynamicMethodNewBuilder(printer);
348 printer->Outdent();
349
350 printer->Print(
351 "}\n"
352 "case BUILD_MESSAGE_INFO: {\n");
353
354 printer->Indent();
355 GenerateDynamicMethodNewBuildMessageInfo(printer);
356 printer->Outdent();
357
358 printer->Print(
359 "}\n"
360 "// fall through\n"
361 "case GET_DEFAULT_INSTANCE: {\n"
362 " return DEFAULT_INSTANCE;\n"
363 "}\n"
364 "case GET_PARSER: {\n"
365 // Generally one would use the lazy initialization holder pattern for
366 // manipulating static fields but that has exceptional cost on Android as
367 // it will generate an extra class for every message. Instead, use the
368 // double-check locking pattern which works just as well.
369 //
370 // The "parser" temporary mirrors the "PARSER" field to eliminate a read
371 // at the final return statement.
372 " com.google.protobuf.Parser<$classname$> parser = PARSER;\n"
373 " if (parser == null) {\n"
374 " synchronized ($classname$.class) {\n"
375 " parser = PARSER;\n"
376 " if (parser == null) {\n"
377 " parser =\n"
378 " new DefaultInstanceBasedParser<$classname$>(\n"
379 " DEFAULT_INSTANCE);\n"
380 " PARSER = parser;\n"
381 " }\n"
382 " }\n"
383 " }\n"
384 " return parser;\n",
385 "classname", name_resolver_->GetImmutableClassName(descriptor_));
386
387 printer->Outdent();
388
389 if (HasRequiredFields(descriptor_)) {
390 printer->Print(
391 "}\n"
392 "case GET_MEMOIZED_IS_INITIALIZED: {\n"
393 " return memoizedIsInitialized;\n"
394 "}\n"
395 "case SET_MEMOIZED_IS_INITIALIZED: {\n"
396 " memoizedIsInitialized = (byte) (arg0 == null ? 0 : 1);\n"
397 " return null;\n"
398 "}\n");
399 } else {
400 printer->Print(
401 "}\n"
402 "case GET_MEMOIZED_IS_INITIALIZED: {\n"
403 " return (byte) 1;\n"
404 "}\n"
405 "case SET_MEMOIZED_IS_INITIALIZED: {\n"
406 " return null;\n"
407 "}\n");
408 }
409
410 printer->Outdent();
411 printer->Print(
412 " }\n"
413 " throw new UnsupportedOperationException();\n"
414 "}\n"
415 "\n",
416 "classname", name_resolver_->GetImmutableClassName(descriptor_));
417
418 printer->Print(
419 "\n"
420 "// @@protoc_insertion_point(class_scope:$full_name$)\n",
421 "full_name", descriptor_->full_name());
422
423 // Carefully initialize the default instance in such a way that it doesn't
424 // conflict with other initialization.
425 printer->Print("private static final $classname$ DEFAULT_INSTANCE;\n",
426 "classname",
427 name_resolver_->GetImmutableClassName(descriptor_));
428
429 printer->Print(
430 "static {\n"
431 " $classname$ defaultInstance = new $classname$();\n"
432 " // New instances are implicitly immutable so no need to make\n"
433 " // immutable.\n"
434 " DEFAULT_INSTANCE = defaultInstance;\n"
435 // Register the default instance in a map. This map will be used by
436 // experimental runtime to lookup default instance given a class instance
437 // without using Java reflection.
438 " com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(\n"
439 " $classname$.class, defaultInstance);\n"
440 "}\n"
441 "\n",
442 "classname", descriptor_->name());
443
444 printer->Print(
445 "public static $classname$ getDefaultInstance() {\n"
446 " return DEFAULT_INSTANCE;\n"
447 "}\n"
448 "\n",
449 "classname", name_resolver_->GetImmutableClassName(descriptor_));
450
451 // 'of' method for Wrappers
452 if (IsWrappersProtoFile(descriptor_->file())) {
453 printer->Print(
454 "public static $classname$ of($field_type$ value) {\n"
455 " return newBuilder().setValue(value).build();\n"
456 "}\n"
457 "\n",
458 "classname", name_resolver_->GetImmutableClassName(descriptor_),
459 "field_type", PrimitiveTypeName(GetJavaType(descriptor_->field(0))));
460 }
461
462 GenerateParser(printer);
463
464 // Extensions must be declared after the DEFAULT_INSTANCE is initialized
465 // because the DEFAULT_INSTANCE is used by the extension to lazily retrieve
466 // the outer class's FileDescriptor.
467 for (int i = 0; i < descriptor_->extension_count(); i++) {
468 ImmutableExtensionLiteGenerator(descriptor_->extension(i), context_)
469 .Generate(printer);
470 }
471
472 printer->Outdent();
473 printer->Print("}\n\n");
474 }
475
GenerateDynamicMethodNewBuildMessageInfo(io::Printer * printer)476 void ImmutableMessageLiteGenerator::GenerateDynamicMethodNewBuildMessageInfo(
477 io::Printer* printer) {
478 printer->Indent();
479
480 // Collect field info into a sequence of UTF-16 chars. It will be embedded
481 // as a Java string in the generated code.
482 std::vector<uint16_t> chars;
483
484 int flags = 0;
485 if (descriptor_->options().message_set_wire_format()) {
486 flags |= 0x2;
487 }
488 if (!context_->options().strip_nonfunctional_codegen) {
489 if (JavaGenerator::GetEdition(*descriptor_->file()) ==
490 Edition::EDITION_PROTO2) {
491 flags |= 0x1;
492 } else if (JavaGenerator::GetEdition(*descriptor_->file()) >=
493 Edition::EDITION_2023) {
494 flags |= 0x4;
495 }
496 }
497
498 WriteIntToUtf16CharSequence(flags, &chars);
499 WriteIntToUtf16CharSequence(descriptor_->field_count(), &chars);
500
501 if (descriptor_->field_count() == 0) {
502 printer->Print("java.lang.Object[] objects = null;");
503 } else {
504 // A single array of all fields (including oneof, oneofCase, hasBits).
505 printer->Print("java.lang.Object[] objects = new java.lang.Object[] {\n");
506 printer->Indent();
507
508 // Record the number of oneofs.
509 WriteIntToUtf16CharSequence(oneofs_.size(), &chars);
510 for (auto& kv : oneofs_) {
511 printer->Print(
512 "\"$oneof_name$_\",\n"
513 "\"$oneof_name$Case_\",\n",
514 "oneof_name", context_->GetOneofGeneratorInfo(kv.second)->name);
515 }
516
517 // Integers for bit fields.
518 int total_bits = 0;
519 for (int i = 0; i < descriptor_->field_count(); i++) {
520 total_bits +=
521 field_generators_.get(descriptor_->field(i)).GetNumBitsForMessage();
522 }
523 int total_ints = (total_bits + 31) / 32;
524 for (int i = 0; i < total_ints; i++) {
525 printer->Print("\"$bit_field_name$\",\n", "bit_field_name",
526 GetBitFieldName(i));
527 }
528 WriteIntToUtf16CharSequence(total_ints, &chars);
529
530 int map_count = 0;
531 int repeated_count = 0;
532 std::unique_ptr<const FieldDescriptor*[]> sorted_fields(
533 SortFieldsByNumber(descriptor_));
534 for (int i = 0; i < descriptor_->field_count(); i++) {
535 const FieldDescriptor* field = sorted_fields[i];
536 if (field->is_map()) {
537 map_count++;
538 } else if (field->is_repeated()) {
539 repeated_count++;
540 }
541 }
542
543 WriteIntToUtf16CharSequence(sorted_fields[0]->number(), &chars);
544 WriteIntToUtf16CharSequence(
545 sorted_fields[descriptor_->field_count() - 1]->number(), &chars);
546 WriteIntToUtf16CharSequence(descriptor_->field_count(), &chars);
547 WriteIntToUtf16CharSequence(map_count, &chars);
548 WriteIntToUtf16CharSequence(repeated_count, &chars);
549
550 std::vector<const FieldDescriptor*> fields_for_is_initialized_check;
551 for (int i = 0; i < descriptor_->field_count(); i++) {
552 if (descriptor_->field(i)->is_required() ||
553 (GetJavaType(descriptor_->field(i)) == JAVATYPE_MESSAGE &&
554 HasRequiredFields(descriptor_->field(i)->message_type()))) {
555 fields_for_is_initialized_check.push_back(descriptor_->field(i));
556 }
557 }
558 WriteIntToUtf16CharSequence(fields_for_is_initialized_check.size(), &chars);
559
560 for (int i = 0; i < descriptor_->field_count(); i++) {
561 const FieldDescriptor* field = sorted_fields[i];
562 field_generators_.get(field).GenerateFieldInfo(printer, &chars);
563 }
564 printer->Outdent();
565 printer->Print("};\n");
566 }
567
568 printer->Print("java.lang.String info =\n");
569 std::string line;
570 for (size_t i = 0; i < chars.size(); i++) {
571 uint16_t code = chars[i];
572 EscapeUtf16ToString(code, &line);
573 if (line.size() >= 80) {
574 printer->Print(" \"$string$\" +\n", "string", line);
575 line.clear();
576 }
577 }
578 printer->Print(" \"$string$\";\n", "string", line);
579
580 printer->Print("return newMessageInfo(DEFAULT_INSTANCE, info, objects);\n");
581 printer->Outdent();
582 }
583
584 // ===================================================================
585
GenerateParseFromMethods(io::Printer * printer)586 void ImmutableMessageLiteGenerator::GenerateParseFromMethods(
587 io::Printer* printer) {
588 printer->Print(
589 "public static $classname$ parseFrom(\n"
590 " java.nio.ByteBuffer data)\n"
591 " throws com.google.protobuf.InvalidProtocolBufferException {\n"
592 " return com.google.protobuf.GeneratedMessageLite.parseFrom(\n"
593 " DEFAULT_INSTANCE, data);\n"
594 "}\n"
595 "public static $classname$ parseFrom(\n"
596 " java.nio.ByteBuffer data,\n"
597 " com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n"
598 " throws com.google.protobuf.InvalidProtocolBufferException {\n"
599 " return com.google.protobuf.GeneratedMessageLite.parseFrom(\n"
600 " DEFAULT_INSTANCE, data, extensionRegistry);\n"
601 "}\n"
602 "public static $classname$ parseFrom(\n"
603 " com.google.protobuf.ByteString data)\n"
604 " throws com.google.protobuf.InvalidProtocolBufferException {\n"
605 " return com.google.protobuf.GeneratedMessageLite.parseFrom(\n"
606 " DEFAULT_INSTANCE, data);\n"
607 "}\n"
608 "public static $classname$ parseFrom(\n"
609 " com.google.protobuf.ByteString data,\n"
610 " com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n"
611 " throws com.google.protobuf.InvalidProtocolBufferException {\n"
612 " return com.google.protobuf.GeneratedMessageLite.parseFrom(\n"
613 " DEFAULT_INSTANCE, data, extensionRegistry);\n"
614 "}\n"
615 "public static $classname$ parseFrom(byte[] data)\n"
616 " throws com.google.protobuf.InvalidProtocolBufferException {\n"
617 " return com.google.protobuf.GeneratedMessageLite.parseFrom(\n"
618 " DEFAULT_INSTANCE, data);\n"
619 "}\n"
620 "public static $classname$ parseFrom(\n"
621 " byte[] data,\n"
622 " com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n"
623 " throws com.google.protobuf.InvalidProtocolBufferException {\n"
624 " return com.google.protobuf.GeneratedMessageLite.parseFrom(\n"
625 " DEFAULT_INSTANCE, data, extensionRegistry);\n"
626 "}\n"
627 "public static $classname$ parseFrom(java.io.InputStream input)\n"
628 " throws java.io.IOException {\n"
629 " return com.google.protobuf.GeneratedMessageLite.parseFrom(\n"
630 " DEFAULT_INSTANCE, input);\n"
631 "}\n"
632 "public static $classname$ parseFrom(\n"
633 " java.io.InputStream input,\n"
634 " com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n"
635 " throws java.io.IOException {\n"
636 " return com.google.protobuf.GeneratedMessageLite.parseFrom(\n"
637 " DEFAULT_INSTANCE, input, extensionRegistry);\n"
638 "}\n"
639 "$parsedelimitedreturnannotation$\n"
640 "public static $classname$ parseDelimitedFrom(java.io.InputStream "
641 "input)\n"
642 " throws java.io.IOException {\n"
643 " return parseDelimitedFrom(DEFAULT_INSTANCE, input);\n"
644 "}\n"
645 "$parsedelimitedreturnannotation$\n"
646 "public static $classname$ parseDelimitedFrom(\n"
647 " java.io.InputStream input,\n"
648 " com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n"
649 " throws java.io.IOException {\n"
650 " return parseDelimitedFrom(DEFAULT_INSTANCE, input, "
651 "extensionRegistry);\n"
652 "}\n"
653 "public static $classname$ parseFrom(\n"
654 " com.google.protobuf.CodedInputStream input)\n"
655 " throws java.io.IOException {\n"
656 " return com.google.protobuf.GeneratedMessageLite.parseFrom(\n"
657 " DEFAULT_INSTANCE, input);\n"
658 "}\n"
659 "public static $classname$ parseFrom(\n"
660 " com.google.protobuf.CodedInputStream input,\n"
661 " com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n"
662 " throws java.io.IOException {\n"
663 " return com.google.protobuf.GeneratedMessageLite.parseFrom(\n"
664 " DEFAULT_INSTANCE, input, extensionRegistry);\n"
665 "}\n"
666 "\n",
667 "classname", name_resolver_->GetImmutableClassName(descriptor_),
668 "parsedelimitedreturnannotation",
669 context_->options().opensource_runtime
670 ? ""
671 : "@com.google.protobuf.Internal.ProtoMethodMayReturnNull");
672 }
673
674 // ===================================================================
675
GenerateBuilder(io::Printer * printer)676 void ImmutableMessageLiteGenerator::GenerateBuilder(io::Printer* printer) {
677 printer->Print(
678 "public static Builder newBuilder() {\n"
679 " return (Builder) DEFAULT_INSTANCE.createBuilder();\n"
680 "}\n"
681 "public static Builder newBuilder($classname$ prototype) {\n"
682 " return DEFAULT_INSTANCE.createBuilder(prototype);\n"
683 "}\n"
684 "\n",
685 "classname", name_resolver_->GetImmutableClassName(descriptor_));
686
687 MessageBuilderLiteGenerator builderGenerator(descriptor_, context_);
688 builderGenerator.Generate(printer);
689 }
690
691 // ===================================================================
692
GenerateDynamicMethodNewBuilder(io::Printer * printer)693 void ImmutableMessageLiteGenerator::GenerateDynamicMethodNewBuilder(
694 io::Printer* printer) {
695 printer->Print("return new Builder();\n");
696 }
697
698 // ===================================================================
699
GenerateExtensionRegistrationCode(io::Printer * printer)700 void ImmutableMessageLiteGenerator::GenerateExtensionRegistrationCode(
701 io::Printer* printer) {
702 for (int i = 0; i < descriptor_->extension_count(); i++) {
703 ImmutableExtensionLiteGenerator(descriptor_->extension(i), context_)
704 .GenerateRegistrationCode(printer);
705 }
706
707 for (int i = 0; i < descriptor_->nested_type_count(); i++) {
708 ImmutableMessageLiteGenerator(descriptor_->nested_type(i), context_)
709 .GenerateExtensionRegistrationCode(printer);
710 }
711 }
712
713 // ===================================================================
GenerateConstructor(io::Printer * printer)714 void ImmutableMessageLiteGenerator::GenerateConstructor(io::Printer* printer) {
715 printer->Print("private $classname$() {\n", "classname", descriptor_->name());
716 printer->Indent();
717
718 // Initialize all fields to default.
719 GenerateInitializers(printer);
720
721 printer->Outdent();
722 printer->Print("}\n");
723 }
724
725 // ===================================================================
GenerateParser(io::Printer * printer)726 void ImmutableMessageLiteGenerator::GenerateParser(io::Printer* printer) {
727 printer->Print(
728 "private static volatile com.google.protobuf.Parser<$classname$> "
729 "PARSER;\n"
730 "\n"
731 "public static com.google.protobuf.Parser<$classname$> parser() {\n"
732 " return DEFAULT_INSTANCE.getParserForType();\n"
733 "}\n",
734 "classname", descriptor_->name());
735 }
736
737 // ===================================================================
GenerateInitializers(io::Printer * printer)738 void ImmutableMessageLiteGenerator::GenerateInitializers(io::Printer* printer) {
739 for (int i = 0; i < descriptor_->field_count(); i++) {
740 if (!IsRealOneof(descriptor_->field(i))) {
741 field_generators_.get(descriptor_->field(i))
742 .GenerateInitializationCode(printer);
743 }
744 }
745 }
746 } // namespace java
747 } // namespace compiler
748 } // namespace protobuf
749 } // namespace google
750
751 #include "google/protobuf/port_undef.inc"
752