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 <google/protobuf/stubs/hash.h>
39 #include <map>
40 #include <memory>
41 #ifndef _SHARED_PTR_H
42 #include <google/protobuf/stubs/shared_ptr.h>
43 #endif
44 #include <vector>
45
46 #include <google/protobuf/compiler/java/java_context.h>
47 #include <google/protobuf/compiler/java/java_doc_comment.h>
48 #include <google/protobuf/compiler/java/java_enum_lite.h>
49 #include <google/protobuf/compiler/java/java_extension_lite.h>
50 #include <google/protobuf/compiler/java/java_generator_factory.h>
51 #include <google/protobuf/compiler/java/java_helpers.h>
52 #include <google/protobuf/compiler/java/java_message_builder.h>
53 #include <google/protobuf/compiler/java/java_message_builder_lite.h>
54 #include <google/protobuf/compiler/java/java_name_resolver.h>
55 #include <google/protobuf/io/coded_stream.h>
56 #include <google/protobuf/io/printer.h>
57 #include <google/protobuf/descriptor.pb.h>
58 #include <google/protobuf/wire_format.h>
59 #include <google/protobuf/stubs/strutil.h>
60 #include <google/protobuf/stubs/substitute.h>
61
62 namespace google {
63 namespace protobuf {
64 namespace compiler {
65 namespace java {
66
67 using internal::WireFormat;
68 using internal::WireFormatLite;
69
70 namespace {
GenerateHasBits(const Descriptor * descriptor)71 bool GenerateHasBits(const Descriptor* descriptor) {
72 return SupportFieldPresence(descriptor->file()) ||
73 HasRepeatedFields(descriptor);
74 }
75
MapValueImmutableClassdName(const Descriptor * descriptor,ClassNameResolver * name_resolver)76 string MapValueImmutableClassdName(const Descriptor* descriptor,
77 ClassNameResolver* name_resolver) {
78 const FieldDescriptor* value_field = descriptor->FindFieldByName("value");
79 GOOGLE_CHECK_EQ(FieldDescriptor::TYPE_MESSAGE, value_field->type());
80 return name_resolver->GetImmutableClassName(value_field->message_type());
81 }
82 } // namespace
83
84 // ===================================================================
ImmutableMessageLiteGenerator(const Descriptor * descriptor,Context * context)85 ImmutableMessageLiteGenerator::ImmutableMessageLiteGenerator(
86 const Descriptor* descriptor, Context* context)
87 : MessageGenerator(descriptor), context_(context),
88 name_resolver_(context->GetNameResolver()),
89 field_generators_(descriptor, context_) {
90 GOOGLE_CHECK(!HasDescriptorMethods(descriptor->file(), context->EnforceLite()))
91 << "Generator factory error: A lite message generator is used to "
92 "generate non-lite messages.";
93 }
94
~ImmutableMessageLiteGenerator()95 ImmutableMessageLiteGenerator::~ImmutableMessageLiteGenerator() {}
96
GenerateStaticVariables(io::Printer * printer,int * bytecode_estimate)97 void ImmutableMessageLiteGenerator::GenerateStaticVariables(
98 io::Printer* printer, int* bytecode_estimate) {
99 // Generate static members for all nested types.
100 for (int i = 0; i < descriptor_->nested_type_count(); i++) {
101 // TODO(kenton): Reuse MessageGenerator objects?
102 ImmutableMessageLiteGenerator(descriptor_->nested_type(i), context_)
103 .GenerateStaticVariables(printer, bytecode_estimate);
104 }
105 }
106
GenerateStaticVariableInitializers(io::Printer * printer)107 int ImmutableMessageLiteGenerator::GenerateStaticVariableInitializers(
108 io::Printer* printer) {
109 int bytecode_estimate = 0;
110 // Generate static member initializers for all nested types.
111 for (int i = 0; i < descriptor_->nested_type_count(); i++) {
112 // TODO(kenton): Reuse MessageGenerator objects?
113 bytecode_estimate +=
114 ImmutableMessageLiteGenerator(descriptor_->nested_type(i), context_)
115 .GenerateStaticVariableInitializers(printer);
116 }
117 return bytecode_estimate;
118 }
119
120 // ===================================================================
121
GenerateInterface(io::Printer * printer)122 void ImmutableMessageLiteGenerator::GenerateInterface(io::Printer* printer) {
123 MaybePrintGeneratedAnnotation(context_, printer, descriptor_,
124 /* immutable = */ true, "OrBuilder");
125 if (descriptor_->extension_range_count() > 0) {
126 printer->Print(
127 "public interface $classname$OrBuilder$idend$ extends \n"
128 " $extra_interfaces$\n"
129 " com.google.protobuf.GeneratedMessageLite.\n"
130 " ExtendableMessageOrBuilder<\n"
131 " $classname$, $classname$.Builder> {\n",
132 "extra_interfaces", ExtraMessageOrBuilderInterfaces(descriptor_),
133 "classname", descriptor_->name(),
134 "idend", "");
135 } else {
136 printer->Print(
137 "public interface $classname$OrBuilder$idend$ extends\n"
138 " $extra_interfaces$\n"
139 " com.google.protobuf.MessageLiteOrBuilder {\n",
140 "extra_interfaces", ExtraMessageOrBuilderInterfaces(descriptor_),
141 "classname", descriptor_->name(),
142 "idend", "");
143 }
144 printer->Annotate("classname", "idend", descriptor_);
145
146 printer->Indent();
147 for (int i = 0; i < descriptor_->field_count(); i++) {
148 printer->Print("\n");
149 field_generators_.get(descriptor_->field(i))
150 .GenerateInterfaceMembers(printer);
151 }
152 for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
153 printer->Print(
154 "\n"
155 "public $classname$.$oneof_capitalized_name$Case "
156 "get$oneof_capitalized_name$Case();\n",
157 "oneof_capitalized_name",
158 context_->GetOneofGeneratorInfo(
159 descriptor_->oneof_decl(i))->capitalized_name,
160 "classname",
161 context_->GetNameResolver()->GetImmutableClassName(descriptor_));
162 }
163 printer->Outdent();
164
165 printer->Print("}\n");
166 }
167
168 // ===================================================================
169
Generate(io::Printer * printer)170 void ImmutableMessageLiteGenerator::Generate(io::Printer* printer) {
171 bool is_own_file = IsOwnFile(descriptor_, /* immutable = */ true);
172
173 map<string, string> variables;
174 variables["static"] = is_own_file ? " " : " static ";
175 variables["classname"] = descriptor_->name();
176 variables["extra_interfaces"] = ExtraMessageInterfaces(descriptor_);
177
178 WriteMessageDocComment(printer, descriptor_);
179 MaybePrintGeneratedAnnotation(context_, printer, descriptor_,
180 /* immutable = */ true);
181
182 // The builder_type stores the super type name of the nested Builder class.
183 string builder_type;
184 if (descriptor_->extension_range_count() > 0) {
185 printer->Print(variables,
186 "public $static$final class $classname$ extends\n"
187 " com.google.protobuf.GeneratedMessageLite.ExtendableMessage<\n"
188 " $classname$, $classname$.Builder> implements\n"
189 " $extra_interfaces$\n"
190 " $classname$OrBuilder {\n");
191 builder_type = strings::Substitute(
192 "com.google.protobuf.GeneratedMessageLite.ExtendableBuilder<$0, ?>",
193 name_resolver_->GetImmutableClassName(descriptor_));
194 } else {
195 printer->Print(variables,
196 "public $static$final class $classname$ extends\n"
197 " com.google.protobuf.GeneratedMessageLite<\n"
198 " $classname$, $classname$.Builder> implements\n"
199 " $extra_interfaces$\n"
200 " $classname$OrBuilder {\n");
201
202 builder_type = "com.google.protobuf.GeneratedMessageLite.Builder";
203 }
204 printer->Indent();
205
206
207 GenerateConstructor(printer);
208
209 // Nested types
210 for (int i = 0; i < descriptor_->enum_type_count(); i++) {
211 EnumLiteGenerator(descriptor_->enum_type(i), true, context_)
212 .Generate(printer);
213 }
214
215 for (int i = 0; i < descriptor_->nested_type_count(); i++) {
216 // Don't generate Java classes for map entry messages.
217 if (IsMapEntry(descriptor_->nested_type(i))) continue;
218 ImmutableMessageLiteGenerator messageGenerator(
219 descriptor_->nested_type(i), context_);
220 messageGenerator.GenerateInterface(printer);
221 messageGenerator.Generate(printer);
222 }
223
224 if (GenerateHasBits(descriptor_)) {
225 // Integers for bit fields.
226 int totalBits = 0;
227 for (int i = 0; i < descriptor_->field_count(); i++) {
228 totalBits += field_generators_.get(descriptor_->field(i))
229 .GetNumBitsForMessage();
230 }
231 int totalInts = (totalBits + 31) / 32;
232 for (int i = 0; i < totalInts; i++) {
233 printer->Print("private int $bit_field_name$;\n",
234 "bit_field_name", GetBitFieldName(i));
235 }
236 }
237
238 // oneof
239 map<string, string> vars;
240 for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
241 vars["oneof_name"] = context_->GetOneofGeneratorInfo(
242 descriptor_->oneof_decl(i))->name;
243 vars["oneof_capitalized_name"] = context_->GetOneofGeneratorInfo(
244 descriptor_->oneof_decl(i))->capitalized_name;
245 vars["oneof_index"] = SimpleItoa(descriptor_->oneof_decl(i)->index());
246 // oneofCase_ and oneof_
247 printer->Print(vars,
248 "private int $oneof_name$Case_ = 0;\n"
249 "private java.lang.Object $oneof_name$_;\n");
250 // OneofCase enum
251 printer->Print(vars,
252 "public enum $oneof_capitalized_name$Case\n"
253 " implements com.google.protobuf.Internal.EnumLite {\n");
254 printer->Indent();
255 for (int j = 0; j < descriptor_->oneof_decl(i)->field_count(); j++) {
256 const FieldDescriptor* field = descriptor_->oneof_decl(i)->field(j);
257 printer->Print(
258 "$field_name$($field_number$),\n",
259 "field_name",
260 ToUpper(field->name()),
261 "field_number",
262 SimpleItoa(field->number()));
263 }
264 printer->Print(
265 "$cap_oneof_name$_NOT_SET(0);\n",
266 "cap_oneof_name",
267 ToUpper(vars["oneof_name"]));
268 printer->Print(vars,
269 "private final int value;\n"
270 "private $oneof_capitalized_name$Case(int value) {\n"
271 " this.value = value;\n"
272 "}\n");
273 printer->Print(vars,
274 "/**\n"
275 " * @deprecated Use {@link #forNumber(int)} instead.\n"
276 " */\n"
277 "@java.lang.Deprecated\n"
278 "public static $oneof_capitalized_name$Case valueOf(int value) {\n"
279 " return forNumber(value);\n"
280 "}\n"
281 "\n"
282 "public static $oneof_capitalized_name$Case forNumber(int value) {\n"
283 " switch (value) {\n");
284 for (int j = 0; j < descriptor_->oneof_decl(i)->field_count(); j++) {
285 const FieldDescriptor* field = descriptor_->oneof_decl(i)->field(j);
286 printer->Print(
287 " case $field_number$: return $field_name$;\n",
288 "field_number",
289 SimpleItoa(field->number()),
290 "field_name",
291 ToUpper(field->name()));
292 }
293 printer->Print(
294 " case 0: return $cap_oneof_name$_NOT_SET;\n"
295 " default: return null;\n"
296 " }\n"
297 "}\n"
298 "public int getNumber() {\n"
299 " return this.value;\n"
300 "}\n",
301 "cap_oneof_name", ToUpper(vars["oneof_name"]));
302 printer->Outdent();
303 printer->Print("};\n\n");
304 // oneofCase()
305 printer->Print(vars,
306 "public $oneof_capitalized_name$Case\n"
307 "get$oneof_capitalized_name$Case() {\n"
308 " return $oneof_capitalized_name$Case.forNumber(\n"
309 " $oneof_name$Case_);\n"
310 "}\n"
311 "\n"
312 "private void clear$oneof_capitalized_name$() {\n"
313 " $oneof_name$Case_ = 0;\n"
314 " $oneof_name$_ = null;\n"
315 "}\n"
316 "\n");
317 }
318
319 // Fields
320 for (int i = 0; i < descriptor_->field_count(); i++) {
321 printer->Print("public static final int $constant_name$ = $number$;\n",
322 "constant_name", FieldConstantName(descriptor_->field(i)),
323 "number", SimpleItoa(descriptor_->field(i)->number()));
324 field_generators_.get(descriptor_->field(i)).GenerateMembers(printer);
325 printer->Print("\n");
326 }
327
328 GenerateMessageSerializationMethods(printer);
329
330 GenerateParseFromMethods(printer);
331 GenerateBuilder(printer);
332
333 if (HasRequiredFields(descriptor_)) {
334 // Memoizes whether the protocol buffer is fully initialized (has all
335 // required fields). -1 means not yet computed. 0 means false and 1 means
336 // true.
337 printer->Print(
338 "private byte memoizedIsInitialized = -1;\n");
339 }
340
341 printer->Print(
342 "protected final Object dynamicMethod(\n"
343 " com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,\n"
344 " Object arg0, Object arg1) {\n"
345 " switch (method) {\n"
346 " case NEW_MUTABLE_INSTANCE: {\n"
347 " return new $classname$();\n"
348 " }\n",
349 "classname", name_resolver_->GetImmutableClassName(descriptor_));
350
351 printer->Indent();
352 printer->Indent();
353
354 printer->Print(
355 "case IS_INITIALIZED: {\n");
356 printer->Indent();
357 GenerateDynamicMethodIsInitialized(printer);
358 printer->Outdent();
359
360 printer->Print(
361 "}\n"
362 "case MAKE_IMMUTABLE: {\n");
363
364 printer->Indent();
365 GenerateDynamicMethodMakeImmutable(printer);
366 printer->Outdent();
367
368 printer->Print(
369 "}\n"
370 "case NEW_BUILDER: {\n");
371
372 printer->Indent();
373 GenerateDynamicMethodNewBuilder(printer);
374 printer->Outdent();
375
376 printer->Print(
377 "}\n"
378 "case VISIT: {\n");
379
380 printer->Indent();
381 GenerateDynamicMethodVisit(printer);
382 printer->Outdent();
383
384 printer->Print(
385 "}\n"
386 "case MERGE_FROM_STREAM: {\n");
387
388 printer->Indent();
389 GenerateDynamicMethodMergeFromStream(printer);
390 printer->Outdent();
391
392 printer->Print(
393 "}\n"
394 "case GET_DEFAULT_INSTANCE: {\n"
395 " return DEFAULT_INSTANCE;\n"
396 "}\n"
397 "case GET_PARSER: {\n"
398 // Generally one would use the lazy initialization holder pattern for
399 // manipulating static fields but that has exceptional cost on Android as
400 // it will generate an extra class for every message. Instead, use the
401 // double-check locking pattern which works just as well.
402 " if (PARSER == null) {"
403 " synchronized ($classname$.class) {\n"
404 " if (PARSER == null) {\n"
405 " PARSER = new DefaultInstanceBasedParser(DEFAULT_INSTANCE);\n"
406 " }\n"
407 " }\n"
408 " }\n"
409 " return PARSER;\n"
410 "}\n",
411 "classname", name_resolver_->GetImmutableClassName(descriptor_));
412
413 printer->Outdent();
414 printer->Outdent();
415
416 printer->Print(
417 " }\n"
418 " throw new UnsupportedOperationException();\n"
419 "}\n"
420 "\n",
421 "classname", name_resolver_->GetImmutableClassName(descriptor_));
422
423 printer->Print(
424 "\n"
425 "// @@protoc_insertion_point(class_scope:$full_name$)\n",
426 "full_name", descriptor_->full_name());
427
428
429 // Carefully initialize the default instance in such a way that it doesn't
430 // conflict with other initialization.
431 printer->Print(
432 "private static final $classname$ DEFAULT_INSTANCE;\n",
433 "classname", name_resolver_->GetImmutableClassName(descriptor_));
434
435 printer->Print(
436 "static {\n"
437 " DEFAULT_INSTANCE = new $classname$();\n"
438 " DEFAULT_INSTANCE.makeImmutable();\n"
439 "}\n"
440 "\n",
441 "classname", descriptor_->name());
442 printer->Print(
443 "public static $classname$ getDefaultInstance() {\n"
444 " return DEFAULT_INSTANCE;\n"
445 "}\n"
446 "\n",
447 "classname", name_resolver_->GetImmutableClassName(descriptor_));
448
449 GenerateParser(printer);
450
451 // Extensions must be declared after the DEFAULT_INSTANCE is initialized
452 // because the DEFAULT_INSTANCE is used by the extension to lazily retrieve
453 // the outer class's FileDescriptor.
454 for (int i = 0; i < descriptor_->extension_count(); i++) {
455 ImmutableExtensionLiteGenerator(descriptor_->extension(i), context_)
456 .Generate(printer);
457 }
458
459 printer->Outdent();
460 printer->Print("}\n\n");
461 }
462
463 // ===================================================================
464
465 void ImmutableMessageLiteGenerator::
GenerateMessageSerializationMethods(io::Printer * printer)466 GenerateMessageSerializationMethods(io::Printer* printer) {
467 google::protobuf::scoped_array<const FieldDescriptor * > sorted_fields(
468 SortFieldsByNumber(descriptor_));
469
470 vector<const Descriptor::ExtensionRange*> sorted_extensions;
471 for (int i = 0; i < descriptor_->extension_range_count(); ++i) {
472 sorted_extensions.push_back(descriptor_->extension_range(i));
473 }
474 std::sort(sorted_extensions.begin(), sorted_extensions.end(),
475 ExtensionRangeOrdering());
476
477 printer->Print(
478 "public void writeTo(com.google.protobuf.CodedOutputStream output)\n"
479 " throws java.io.IOException {\n");
480 printer->Indent();
481 if (HasPackedFields(descriptor_)) {
482 // writeTo(CodedOutputStream output) might be invoked without
483 // getSerializedSize() ever being called, but we need the memoized
484 // sizes in case this message has packed fields. Rather than emit checks for
485 // each packed field, just call getSerializedSize() up front.
486 // In most cases, getSerializedSize() will have already been called anyway
487 // by one of the wrapper writeTo() methods, making this call cheap.
488 printer->Print(
489 "getSerializedSize();\n");
490 }
491
492 if (descriptor_->extension_range_count() > 0) {
493 if (descriptor_->options().message_set_wire_format()) {
494 printer->Print(
495 "com.google.protobuf.GeneratedMessageLite\n"
496 " .ExtendableMessage<$classname$, $classname$.Builder>\n"
497 " .ExtensionWriter extensionWriter =\n"
498 " newMessageSetExtensionWriter();\n",
499 "classname", name_resolver_->GetImmutableClassName(descriptor_));
500 } else {
501 printer->Print(
502 "com.google.protobuf.GeneratedMessageLite\n"
503 " .ExtendableMessage<$classname$, $classname$.Builder>\n"
504 " .ExtensionWriter extensionWriter =\n"
505 " newExtensionWriter();\n",
506 "classname", name_resolver_->GetImmutableClassName(descriptor_));
507 }
508 }
509
510 // Merge the fields and the extension ranges, both sorted by field number.
511 for (int i = 0, j = 0;
512 i < descriptor_->field_count() || j < sorted_extensions.size();
513 ) {
514 if (i == descriptor_->field_count()) {
515 GenerateSerializeOneExtensionRange(printer, sorted_extensions[j++]);
516 } else if (j == sorted_extensions.size()) {
517 GenerateSerializeOneField(printer, sorted_fields[i++]);
518 } else if (sorted_fields[i]->number() < sorted_extensions[j]->start) {
519 GenerateSerializeOneField(printer, sorted_fields[i++]);
520 } else {
521 GenerateSerializeOneExtensionRange(printer, sorted_extensions[j++]);
522 }
523 }
524
525 if (PreserveUnknownFields(descriptor_)) {
526 printer->Print(
527 "unknownFields.writeTo(output);\n");
528 }
529
530 printer->Outdent();
531 printer->Print(
532 "}\n"
533 "\n"
534 "public int getSerializedSize() {\n"
535 " int size = memoizedSerializedSize;\n"
536 " if (size != -1) return size;\n"
537 "\n"
538 " size = 0;\n");
539 printer->Indent();
540
541 for (int i = 0; i < descriptor_->field_count(); i++) {
542 field_generators_.get(sorted_fields[i]).GenerateSerializedSizeCode(printer);
543 }
544
545 if (descriptor_->extension_range_count() > 0) {
546 if (descriptor_->options().message_set_wire_format()) {
547 printer->Print(
548 "size += extensionsSerializedSizeAsMessageSet();\n");
549 } else {
550 printer->Print(
551 "size += extensionsSerializedSize();\n");
552 }
553 }
554
555 if (PreserveUnknownFields(descriptor_)) {
556 printer->Print(
557 "size += unknownFields.getSerializedSize();\n");
558 }
559
560 printer->Outdent();
561 printer->Print(
562 " memoizedSerializedSize = size;\n"
563 " return size;\n"
564 "}\n"
565 "\n");
566 }
567
568 void ImmutableMessageLiteGenerator::
GenerateParseFromMethods(io::Printer * printer)569 GenerateParseFromMethods(io::Printer* printer) {
570 // Note: These are separate from GenerateMessageSerializationMethods()
571 // because they need to be generated even for messages that are optimized
572 // for code size.
573 printer->Print(
574 "public static $classname$ parseFrom(\n"
575 " com.google.protobuf.ByteString 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 " com.google.protobuf.ByteString 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(byte[] data)\n"
588 " throws com.google.protobuf.InvalidProtocolBufferException {\n"
589 " return com.google.protobuf.GeneratedMessageLite.parseFrom(\n"
590 " DEFAULT_INSTANCE, data);\n"
591 "}\n"
592 "public static $classname$ parseFrom(\n"
593 " byte[] data,\n"
594 " com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n"
595 " throws com.google.protobuf.InvalidProtocolBufferException {\n"
596 " return com.google.protobuf.GeneratedMessageLite.parseFrom(\n"
597 " DEFAULT_INSTANCE, data, extensionRegistry);\n"
598 "}\n"
599 "public static $classname$ parseFrom(java.io.InputStream input)\n"
600 " throws java.io.IOException {\n"
601 " return com.google.protobuf.GeneratedMessageLite.parseFrom(\n"
602 " DEFAULT_INSTANCE, input);\n"
603 "}\n"
604 "public static $classname$ parseFrom(\n"
605 " java.io.InputStream input,\n"
606 " com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n"
607 " throws java.io.IOException {\n"
608 " return com.google.protobuf.GeneratedMessageLite.parseFrom(\n"
609 " DEFAULT_INSTANCE, input, extensionRegistry);\n"
610 "}\n"
611 "public static $classname$ parseDelimitedFrom(java.io.InputStream input)\n"
612 " throws java.io.IOException {\n"
613 " return parseDelimitedFrom(DEFAULT_INSTANCE, input);\n"
614 "}\n"
615 "public static $classname$ parseDelimitedFrom(\n"
616 " java.io.InputStream input,\n"
617 " com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n"
618 " throws java.io.IOException {\n"
619 " return parseDelimitedFrom(DEFAULT_INSTANCE, input, extensionRegistry);\n"
620 "}\n"
621 "public static $classname$ parseFrom(\n"
622 " com.google.protobuf.CodedInputStream input)\n"
623 " throws java.io.IOException {\n"
624 " return com.google.protobuf.GeneratedMessageLite.parseFrom(\n"
625 " DEFAULT_INSTANCE, input);\n"
626 "}\n"
627 "public static $classname$ parseFrom(\n"
628 " com.google.protobuf.CodedInputStream input,\n"
629 " com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n"
630 " throws java.io.IOException {\n"
631 " return com.google.protobuf.GeneratedMessageLite.parseFrom(\n"
632 " DEFAULT_INSTANCE, input, extensionRegistry);\n"
633 "}\n"
634 "\n",
635 "classname", name_resolver_->GetImmutableClassName(descriptor_));
636 }
637
GenerateSerializeOneField(io::Printer * printer,const FieldDescriptor * field)638 void ImmutableMessageLiteGenerator::GenerateSerializeOneField(
639 io::Printer* printer, const FieldDescriptor* field) {
640 field_generators_.get(field).GenerateSerializationCode(printer);
641 }
642
GenerateSerializeOneExtensionRange(io::Printer * printer,const Descriptor::ExtensionRange * range)643 void ImmutableMessageLiteGenerator::GenerateSerializeOneExtensionRange(
644 io::Printer* printer, const Descriptor::ExtensionRange* range) {
645 printer->Print(
646 "extensionWriter.writeUntil($end$, output);\n",
647 "end", SimpleItoa(range->end));
648 }
649
650 // ===================================================================
651
GenerateBuilder(io::Printer * printer)652 void ImmutableMessageLiteGenerator::GenerateBuilder(io::Printer* printer) {
653 printer->Print(
654 "public static Builder newBuilder() {\n"
655 " return DEFAULT_INSTANCE.toBuilder();\n"
656 "}\n"
657 "public static Builder newBuilder($classname$ prototype) {\n"
658 " return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);\n"
659 "}\n"
660 "\n",
661 "classname", name_resolver_->GetImmutableClassName(descriptor_));
662
663 MessageBuilderLiteGenerator builderGenerator(descriptor_, context_);
664 builderGenerator.Generate(printer);
665 }
666
667 // ===================================================================
668
GenerateDynamicMethodIsInitialized(io::Printer * printer)669 void ImmutableMessageLiteGenerator::GenerateDynamicMethodIsInitialized(
670 io::Printer* printer) {
671 // Returns null for false, DEFAULT_INSTANCE for true.
672 if (!HasRequiredFields(descriptor_)) {
673 printer->Print("return DEFAULT_INSTANCE;\n");
674 return;
675 }
676
677 // Don't directly compare to -1 to avoid an Android x86 JIT bug.
678 printer->Print(
679 "byte isInitialized = memoizedIsInitialized;\n"
680 "if (isInitialized == 1) return DEFAULT_INSTANCE;\n"
681 "if (isInitialized == 0) return null;\n"
682 "\n"
683 "boolean shouldMemoize = ((Boolean) arg0).booleanValue();\n");
684
685 // Check that all required fields in this message are set.
686 // TODO(kenton): We can optimize this when we switch to putting all the
687 // "has" fields into a single bitfield.
688 for (int i = 0; i < descriptor_->field_count(); i++) {
689 const FieldDescriptor* field = descriptor_->field(i);
690 const FieldGeneratorInfo* info = context_->GetFieldGeneratorInfo(field);
691
692 if (field->is_required()) {
693 printer->Print(
694 "if (!has$name$()) {\n"
695 " if (shouldMemoize) {\n"
696 " memoizedIsInitialized = 0;\n"
697 " }\n"
698 " return null;\n"
699 "}\n",
700 "name", info->capitalized_name);
701 }
702 }
703
704 // Now check that all embedded messages are initialized.
705 for (int i = 0; i < descriptor_->field_count(); i++) {
706 const FieldDescriptor* field = descriptor_->field(i);
707 const FieldGeneratorInfo* info = context_->GetFieldGeneratorInfo(field);
708 if (GetJavaType(field) == JAVATYPE_MESSAGE &&
709 HasRequiredFields(field->message_type())) {
710 switch (field->label()) {
711 case FieldDescriptor::LABEL_REQUIRED:
712 printer->Print(
713 "if (!get$name$().isInitialized()) {\n"
714 " if (shouldMemoize) {\n"
715 " memoizedIsInitialized = 0;\n"
716 " }\n"
717 " return null;\n"
718 "}\n",
719 "type", name_resolver_->GetImmutableClassName(
720 field->message_type()),
721 "name", info->capitalized_name);
722 break;
723 case FieldDescriptor::LABEL_OPTIONAL:
724 if (!SupportFieldPresence(descriptor_->file()) &&
725 field->containing_oneof() != NULL) {
726 const OneofDescriptor* oneof = field->containing_oneof();
727 const OneofGeneratorInfo* oneof_info =
728 context_->GetOneofGeneratorInfo(oneof);
729 printer->Print(
730 "if ($oneof_name$Case_ == $field_number$) {\n",
731 "oneof_name", oneof_info->name,
732 "field_number", SimpleItoa(field->number()));
733 } else {
734 printer->Print(
735 "if (has$name$()) {\n",
736 "name", info->capitalized_name);
737 }
738 printer->Print(
739 " if (!get$name$().isInitialized()) {\n"
740 " if (shouldMemoize) {\n"
741 " memoizedIsInitialized = 0;\n"
742 " }\n"
743 " return null;\n"
744 " }\n"
745 "}\n",
746 "name", info->capitalized_name);
747 break;
748 case FieldDescriptor::LABEL_REPEATED:
749 if (IsMapEntry(field->message_type())) {
750 printer->Print(
751 "for ($type$ item : get$name$().values()) {\n"
752 " if (!item.isInitialized()) {\n"
753 " if (shouldMemoize) {\n"
754 " memoizedIsInitialized = 0;\n"
755 " }\n"
756 " return null;\n"
757 " }\n"
758 "}\n",
759 "type", MapValueImmutableClassdName(field->message_type(),
760 name_resolver_),
761 "name", info->capitalized_name);
762 } else {
763 printer->Print(
764 "for (int i = 0; i < get$name$Count(); i++) {\n"
765 " if (!get$name$(i).isInitialized()) {\n"
766 " if (shouldMemoize) {\n"
767 " memoizedIsInitialized = 0;\n"
768 " }\n"
769 " return null;\n"
770 " }\n"
771 "}\n",
772 "type", name_resolver_->GetImmutableClassName(
773 field->message_type()),
774 "name", info->capitalized_name);
775 }
776 break;
777 }
778 }
779 }
780
781 if (descriptor_->extension_range_count() > 0) {
782 printer->Print(
783 "if (!extensionsAreInitialized()) {\n"
784 " if (shouldMemoize) {\n"
785 " memoizedIsInitialized = 0;\n"
786 " }\n"
787 " return null;\n"
788 "}\n");
789 }
790
791 printer->Print(
792 "if (shouldMemoize) memoizedIsInitialized = 1;\n");
793
794 printer->Print(
795 "return DEFAULT_INSTANCE;\n"
796 "\n");
797 }
798
799 // ===================================================================
800
GenerateDynamicMethodMakeImmutable(io::Printer * printer)801 void ImmutableMessageLiteGenerator::GenerateDynamicMethodMakeImmutable(
802 io::Printer* printer) {
803
804 // Output generation code for each field.
805 for (int i = 0; i < descriptor_->field_count(); i++) {
806 field_generators_.get(descriptor_->field(i))
807 .GenerateDynamicMethodMakeImmutableCode(printer);
808 }
809
810 printer->Print(
811 "return null;\n");
812 }
813
814 // ===================================================================
815
GenerateDynamicMethodNewBuilder(io::Printer * printer)816 void ImmutableMessageLiteGenerator::GenerateDynamicMethodNewBuilder(
817 io::Printer* printer) {
818 printer->Print(
819 "return new Builder();\n");
820 }
821
822 // ===================================================================
823
GenerateDynamicMethodVisit(io::Printer * printer)824 void ImmutableMessageLiteGenerator::GenerateDynamicMethodVisit(
825 io::Printer* printer) {
826 printer->Print(
827 "Visitor visitor = (Visitor) arg0;\n"
828 "$classname$ other = ($classname$) arg1;\n",
829 "classname", name_resolver_->GetImmutableClassName(descriptor_));
830
831 for (int i = 0; i < descriptor_->field_count(); i++) {
832 if (!descriptor_->field(i)->containing_oneof()) {
833 field_generators_.get(
834 descriptor_->field(i)).GenerateVisitCode(printer);
835 }
836 }
837
838 // Merge oneof fields.
839 for (int i = 0; i < descriptor_->oneof_decl_count(); ++i) {
840 printer->Print(
841 "switch (other.get$oneof_capitalized_name$Case()) {\n",
842 "oneof_capitalized_name",
843 context_->GetOneofGeneratorInfo(
844 descriptor_->oneof_decl(i))->capitalized_name);
845 printer->Indent();
846 for (int j = 0; j < descriptor_->oneof_decl(i)->field_count(); j++) {
847 const FieldDescriptor* field = descriptor_->oneof_decl(i)->field(j);
848 printer->Print(
849 "case $field_name$: {\n",
850 "field_name",
851 ToUpper(field->name()));
852 printer->Indent();
853 field_generators_.get(field).GenerateVisitCode(printer);
854 printer->Print(
855 "break;\n");
856 printer->Outdent();
857 printer->Print(
858 "}\n");
859 }
860 printer->Print(
861 "case $cap_oneof_name$_NOT_SET: {\n"
862 " visitor.visitOneofNotSet($oneof_name$Case_ != 0);\n"
863 " break;\n"
864 "}\n",
865 "cap_oneof_name",
866 ToUpper(context_->GetOneofGeneratorInfo(
867 descriptor_->oneof_decl(i))->name),
868 "oneof_name",
869 context_->GetOneofGeneratorInfo(
870 descriptor_->oneof_decl(i))->name);
871 printer->Outdent();
872 printer->Print(
873 "}\n");
874 }
875
876 printer->Print(
877 "if (visitor == com.google.protobuf.GeneratedMessageLite.MergeFromVisitor\n"
878 " .INSTANCE) {\n");
879 printer->Indent();
880 for (int i = 0; i < descriptor_->oneof_decl_count(); ++i) {
881 const OneofDescriptor* field = descriptor_->oneof_decl(i);
882 printer->Print(
883 "if (other.$oneof_name$Case_ != 0) {\n"
884 " $oneof_name$Case_ = other.$oneof_name$Case_;\n"
885 "}\n",
886 "oneof_name", context_->GetOneofGeneratorInfo(field)->name);
887 }
888
889 if (GenerateHasBits(descriptor_)) {
890 // Integers for bit fields.
891 int totalBits = 0;
892 for (int i = 0; i < descriptor_->field_count(); i++) {
893 totalBits += field_generators_.get(descriptor_->field(i))
894 .GetNumBitsForMessage();
895 }
896 int totalInts = (totalBits + 31) / 32;
897
898 for (int i = 0; i < totalInts; i++) {
899 printer->Print(
900 "$bit_field_name$ |= other.$bit_field_name$;\n",
901 "bit_field_name", GetBitFieldName(i));
902 }
903 }
904 printer->Outdent();
905 printer->Print(
906 "}\n");
907
908
909 printer->Print(
910 "return this;\n");
911 }
912
913 // ===================================================================
914
GenerateDynamicMethodMergeFromStream(io::Printer * printer)915 void ImmutableMessageLiteGenerator::GenerateDynamicMethodMergeFromStream(
916 io::Printer* printer) {
917 printer->Print(
918 "com.google.protobuf.CodedInputStream input =\n"
919 " (com.google.protobuf.CodedInputStream) arg0;\n"
920 "com.google.protobuf.ExtensionRegistryLite extensionRegistry =\n"
921 " (com.google.protobuf.ExtensionRegistryLite) arg1;\n"
922 "try {\n");
923 printer->Indent();
924
925 printer->Print(
926 "boolean done = false;\n"
927 "while (!done) {\n");
928 printer->Indent();
929
930 printer->Print(
931 "int tag = input.readTag();\n"
932 "switch (tag) {\n");
933 printer->Indent();
934
935 printer->Print(
936 "case 0:\n" // zero signals EOF / limit reached
937 " done = true;\n"
938 " break;\n");
939
940 if (PreserveUnknownFields(descriptor_)) {
941 if (descriptor_->extension_range_count() > 0) {
942 printer->Print(
943 "default: {\n"
944 " if (!parseUnknownField(getDefaultInstanceForType(),\n"
945 " input, extensionRegistry, tag)) {\n"
946 " done = true;\n" // it's an endgroup tag
947 " }\n"
948 " break;\n"
949 "}\n");
950 } else {
951 printer->Print(
952 "default: {\n"
953 " if (!parseUnknownField(tag, input)) {\n"
954 " done = true;\n" // it's an endgroup tag
955 " }\n"
956 " break;\n"
957 "}\n");
958 }
959 } else {
960 printer->Print(
961 "default: {\n"
962 " if (!input.skipField(tag)) {\n"
963 " done = true;\n" // it's an endgroup tag
964 " }\n"
965 " break;\n"
966 "}\n");
967 }
968
969 google::protobuf::scoped_array<const FieldDescriptor * > sorted_fields(
970 SortFieldsByNumber(descriptor_));
971 for (int i = 0; i < descriptor_->field_count(); i++) {
972 const FieldDescriptor* field = sorted_fields[i];
973 uint32 tag = WireFormatLite::MakeTag(field->number(),
974 WireFormat::WireTypeForFieldType(field->type()));
975
976 printer->Print(
977 "case $tag$: {\n",
978 "tag", SimpleItoa(tag));
979 printer->Indent();
980
981 field_generators_.get(field).GenerateParsingCode(printer);
982
983 printer->Outdent();
984 printer->Print(
985 " break;\n"
986 "}\n");
987
988 if (field->is_packable()) {
989 // To make packed = true wire compatible, we generate parsing code from a
990 // packed version of this field regardless of field->options().packed().
991 uint32 packed_tag = WireFormatLite::MakeTag(field->number(),
992 WireFormatLite::WIRETYPE_LENGTH_DELIMITED);
993 printer->Print(
994 "case $tag$: {\n",
995 "tag", SimpleItoa(packed_tag));
996 printer->Indent();
997
998 field_generators_.get(field).GenerateParsingCodeFromPacked(printer);
999
1000 printer->Outdent();
1001 printer->Print(
1002 " break;\n"
1003 "}\n");
1004 }
1005 }
1006
1007 printer->Outdent();
1008 printer->Outdent();
1009 printer->Print(
1010 " }\n" // switch (tag)
1011 "}\n"); // while (!done)
1012
1013 printer->Outdent();
1014 printer->Print(
1015 "} catch (com.google.protobuf.InvalidProtocolBufferException e) {\n"
1016 " throw new RuntimeException(e.setUnfinishedMessage(this));\n"
1017 "} catch (java.io.IOException e) {\n"
1018 " throw new RuntimeException(\n"
1019 " new com.google.protobuf.InvalidProtocolBufferException(\n"
1020 " e.getMessage()).setUnfinishedMessage(this));\n"
1021 "} finally {\n");
1022 printer->Indent();
1023
1024 printer->Outdent();
1025 printer->Print(
1026 "}\n"); // finally
1027 }
1028
1029 // ===================================================================
1030
1031 namespace {
CheckHasBitsForEqualsAndHashCode(const FieldDescriptor * field)1032 bool CheckHasBitsForEqualsAndHashCode(const FieldDescriptor* field) {
1033 if (field->is_repeated()) {
1034 return false;
1035 }
1036 if (SupportFieldPresence(field->file())) {
1037 return true;
1038 }
1039 return GetJavaType(field) == JAVATYPE_MESSAGE &&
1040 field->containing_oneof() == NULL;
1041 }
1042 } // namespace
1043
1044 // ===================================================================
1045
1046 void ImmutableMessageLiteGenerator::
GenerateExtensionRegistrationCode(io::Printer * printer)1047 GenerateExtensionRegistrationCode(io::Printer* printer) {
1048 for (int i = 0; i < descriptor_->extension_count(); i++) {
1049 ImmutableExtensionLiteGenerator(descriptor_->extension(i), context_)
1050 .GenerateRegistrationCode(printer);
1051 }
1052
1053 for (int i = 0; i < descriptor_->nested_type_count(); i++) {
1054 ImmutableMessageLiteGenerator(descriptor_->nested_type(i), context_)
1055 .GenerateExtensionRegistrationCode(printer);
1056 }
1057 }
1058
1059 // ===================================================================
1060 void ImmutableMessageLiteGenerator::
GenerateConstructor(io::Printer * printer)1061 GenerateConstructor(io::Printer* printer) {
1062 printer->Print(
1063 "private $classname$() {\n",
1064 "classname", descriptor_->name());
1065 printer->Indent();
1066
1067 // Initialize all fields to default.
1068 GenerateInitializers(printer);
1069
1070 printer->Outdent();
1071 printer->Print(
1072 "}\n");
1073 }
1074
1075 // ===================================================================
GenerateParser(io::Printer * printer)1076 void ImmutableMessageLiteGenerator::GenerateParser(io::Printer* printer) {
1077 printer->Print(
1078 "private static volatile com.google.protobuf.Parser<$classname$> PARSER;\n"
1079 "\n"
1080 "public static com.google.protobuf.Parser<$classname$> parser() {\n"
1081 " return DEFAULT_INSTANCE.getParserForType();\n"
1082 "}\n",
1083 "classname", descriptor_->name());
1084 }
1085
1086 // ===================================================================
GenerateInitializers(io::Printer * printer)1087 void ImmutableMessageLiteGenerator::GenerateInitializers(io::Printer* printer) {
1088 for (int i = 0; i < descriptor_->field_count(); i++) {
1089 if (!descriptor_->field(i)->containing_oneof()) {
1090 field_generators_.get(descriptor_->field(i))
1091 .GenerateInitializationCode(printer);
1092 }
1093 }
1094 }
1095
1096 } // namespace java
1097 } // namespace compiler
1098 } // namespace protobuf
1099 } // namespace google
1100