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