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