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: kenton@google.com (Kenton Varda)
32 // Based on original Protocol Buffers design by
33 // Sanjay Ghemawat, Jeff Dean, and others.
34
35 #include <google/protobuf/compiler/java/java_message.h>
36
37 #include <algorithm>
38 #include <google/protobuf/stubs/hash.h>
39 #include <map>
40 #include <memory>
41 #include <vector>
42
43 #include <google/protobuf/compiler/java/java_context.h>
44 #include <google/protobuf/compiler/java/java_doc_comment.h>
45 #include <google/protobuf/compiler/java/java_enum.h>
46 #include <google/protobuf/compiler/java/java_extension.h>
47 #include <google/protobuf/compiler/java/java_generator_factory.h>
48 #include <google/protobuf/compiler/java/java_helpers.h>
49 #include <google/protobuf/compiler/java/java_name_resolver.h>
50 #include <google/protobuf/io/coded_stream.h>
51 #include <google/protobuf/io/printer.h>
52 #include <google/protobuf/descriptor.pb.h>
53 #include <google/protobuf/wire_format.h>
54 #include <google/protobuf/stubs/strutil.h>
55 #include <google/protobuf/stubs/substitute.h>
56
57 namespace google {
58 namespace protobuf {
59 namespace compiler {
60 namespace java {
61
62 using internal::WireFormat;
63 using internal::WireFormatLite;
64
65 namespace {
GenerateHasBits(const Descriptor * descriptor)66 bool GenerateHasBits(const Descriptor* descriptor) {
67 return SupportFieldPresence(descriptor->file()) ||
68 HasRepeatedFields(descriptor);
69 }
70 } // namespace
71
72 // ===================================================================
73
MessageGenerator(const Descriptor * descriptor)74 MessageGenerator::MessageGenerator(const Descriptor* descriptor)
75 : descriptor_(descriptor) {}
76
~MessageGenerator()77 MessageGenerator::~MessageGenerator() {}
78
79 // ===================================================================
80 // TODO(api): Move this class to a separate immutable_message.cc file.
ImmutableMessageGenerator(const Descriptor * descriptor,Context * context)81 ImmutableMessageGenerator::ImmutableMessageGenerator(
82 const Descriptor* descriptor, Context* context)
83 : MessageGenerator(descriptor), context_(context),
84 name_resolver_(context->GetNameResolver()),
85 field_generators_(descriptor, context_) {
86 }
87
~ImmutableMessageGenerator()88 ImmutableMessageGenerator::~ImmutableMessageGenerator() {}
89
GenerateStaticVariables(io::Printer * printer)90 void ImmutableMessageGenerator::GenerateStaticVariables(io::Printer* printer) {
91 if (HasDescriptorMethods(descriptor_)) {
92 // Because descriptor.proto (com.google.protobuf.DescriptorProtos) is
93 // used in the construction of descriptors, we have a tricky bootstrapping
94 // problem. To help control static initialization order, we make sure all
95 // descriptors and other static data that depends on them are members of
96 // the outermost class in the file. This way, they will be initialized in
97 // a deterministic order.
98
99 map<string, string> vars;
100 vars["identifier"] = UniqueFileScopeIdentifier(descriptor_);
101 vars["index"] = SimpleItoa(descriptor_->index());
102 vars["classname"] = name_resolver_->GetImmutableClassName(descriptor_);
103 if (descriptor_->containing_type() != NULL) {
104 vars["parent"] = UniqueFileScopeIdentifier(
105 descriptor_->containing_type());
106 }
107 if (MultipleJavaFiles(descriptor_->file(), /* immutable = */ true)) {
108 // We can only make these package-private since the classes that use them
109 // are in separate files.
110 vars["private"] = "";
111 } else {
112 vars["private"] = "private ";
113 }
114
115 // The descriptor for this type.
116 printer->Print(vars,
117 "$private$static final com.google.protobuf.Descriptors.Descriptor\n"
118 " internal_$identifier$_descriptor;\n");
119
120 // And the FieldAccessorTable.
121 GenerateFieldAccessorTable(printer);
122 }
123
124 // Generate static members for all nested types.
125 for (int i = 0; i < descriptor_->nested_type_count(); i++) {
126 // TODO(kenton): Reuse MessageGenerator objects?
127 ImmutableMessageGenerator(descriptor_->nested_type(i), context_)
128 .GenerateStaticVariables(printer);
129 }
130 }
131
GenerateStaticVariableInitializers(io::Printer * printer)132 void ImmutableMessageGenerator::GenerateStaticVariableInitializers(
133 io::Printer* printer) {
134 if (HasDescriptorMethods(descriptor_)) {
135 map<string, string> vars;
136 vars["identifier"] = UniqueFileScopeIdentifier(descriptor_);
137 vars["index"] = SimpleItoa(descriptor_->index());
138 vars["classname"] = name_resolver_->GetImmutableClassName(descriptor_);
139 if (descriptor_->containing_type() != NULL) {
140 vars["parent"] = UniqueFileScopeIdentifier(
141 descriptor_->containing_type());
142 }
143
144 // The descriptor for this type.
145 if (descriptor_->containing_type() == NULL) {
146 printer->Print(vars,
147 "internal_$identifier$_descriptor =\n"
148 " getDescriptor().getMessageTypes().get($index$);\n");
149 } else {
150 printer->Print(vars,
151 "internal_$identifier$_descriptor =\n"
152 " internal_$parent$_descriptor.getNestedTypes().get($index$);\n");
153 }
154
155 // And the FieldAccessorTable.
156 GenerateFieldAccessorTableInitializer(printer);
157 }
158
159 // Generate static member initializers for all nested types.
160 for (int i = 0; i < descriptor_->nested_type_count(); i++) {
161 // TODO(kenton): Reuse MessageGenerator objects?
162 ImmutableMessageGenerator(descriptor_->nested_type(i), context_)
163 .GenerateStaticVariableInitializers(printer);
164 }
165 }
166
167 void ImmutableMessageGenerator::
GenerateFieldAccessorTable(io::Printer * printer)168 GenerateFieldAccessorTable(io::Printer* printer) {
169 map<string, string> vars;
170 vars["identifier"] = UniqueFileScopeIdentifier(descriptor_);
171 if (MultipleJavaFiles(descriptor_->file(), /* immutable = */ true)) {
172 // We can only make these package-private since the classes that use them
173 // are in separate files.
174 vars["private"] = "";
175 } else {
176 vars["private"] = "private ";
177 }
178 printer->Print(vars,
179 "$private$static\n"
180 " com.google.protobuf.GeneratedMessage.FieldAccessorTable\n"
181 " internal_$identifier$_fieldAccessorTable;\n");
182 }
183
184 void ImmutableMessageGenerator::
GenerateFieldAccessorTableInitializer(io::Printer * printer)185 GenerateFieldAccessorTableInitializer(io::Printer* printer) {
186 printer->Print(
187 "internal_$identifier$_fieldAccessorTable = new\n"
188 " com.google.protobuf.GeneratedMessage.FieldAccessorTable(\n"
189 " internal_$identifier$_descriptor,\n"
190 " new java.lang.String[] { ",
191 "identifier",
192 UniqueFileScopeIdentifier(descriptor_));
193 for (int i = 0; i < descriptor_->field_count(); i++) {
194 const FieldDescriptor* field = descriptor_->field(i);
195 const FieldGeneratorInfo* info = context_->GetFieldGeneratorInfo(field);
196 printer->Print(
197 "\"$field_name$\", ",
198 "field_name", info->capitalized_name);
199 }
200 for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
201 const OneofDescriptor* oneof = descriptor_->oneof_decl(i);
202 const OneofGeneratorInfo* info = context_->GetOneofGeneratorInfo(oneof);
203 printer->Print(
204 "\"$oneof_name$\", ",
205 "oneof_name", info->capitalized_name);
206 }
207 printer->Print("});\n");
208 }
209
210 // ===================================================================
211
GenerateInterface(io::Printer * printer)212 void ImmutableMessageGenerator::GenerateInterface(io::Printer* printer) {
213 if (descriptor_->extension_range_count() > 0) {
214 if (HasDescriptorMethods(descriptor_)) {
215 printer->Print(
216 "public interface $classname$OrBuilder extends\n"
217 " $extra_interfaces$\n"
218 " com.google.protobuf.GeneratedMessage.\n"
219 " ExtendableMessageOrBuilder<$classname$> {\n",
220 "extra_interfaces", ExtraMessageOrBuilderInterfaces(descriptor_),
221 "classname", descriptor_->name());
222 } else {
223 printer->Print(
224 "public interface $classname$OrBuilder extends \n"
225 " $extra_interfaces$\n"
226 " com.google.protobuf.GeneratedMessageLite.\n"
227 " ExtendableMessageOrBuilder<$classname$> {\n",
228 "extra_interfaces", ExtraMessageOrBuilderInterfaces(descriptor_),
229 "classname", descriptor_->name());
230 }
231 } else {
232 if (HasDescriptorMethods(descriptor_)) {
233 printer->Print(
234 "public interface $classname$OrBuilder extends\n"
235 " $extra_interfaces$\n"
236 " com.google.protobuf.MessageOrBuilder {\n",
237 "extra_interfaces", ExtraMessageOrBuilderInterfaces(descriptor_),
238 "classname", descriptor_->name());
239 } else {
240 printer->Print(
241 "public interface $classname$OrBuilder extends\n"
242 " $extra_interfaces$\n"
243 " com.google.protobuf.MessageLiteOrBuilder {\n",
244 "extra_interfaces", ExtraMessageOrBuilderInterfaces(descriptor_),
245 "classname", descriptor_->name());
246 }
247 }
248
249 printer->Indent();
250 for (int i = 0; i < descriptor_->field_count(); i++) {
251 printer->Print("\n");
252 field_generators_.get(descriptor_->field(i))
253 .GenerateInterfaceMembers(printer);
254 }
255 printer->Outdent();
256
257 printer->Print("}\n");
258 }
259
260 // ===================================================================
261
Generate(io::Printer * printer)262 void ImmutableMessageGenerator::Generate(io::Printer* printer) {
263 bool is_own_file =
264 descriptor_->containing_type() == NULL &&
265 MultipleJavaFiles(descriptor_->file(), /* immutable = */ true);
266
267 WriteMessageDocComment(printer, descriptor_);
268
269 // The builder_type stores the super type name of the nested Builder class.
270 string builder_type;
271 if (descriptor_->extension_range_count() > 0) {
272 if (HasDescriptorMethods(descriptor_)) {
273 printer->Print(
274 "public$static$final class $classname$ extends\n"
275 " com.google.protobuf.GeneratedMessage.ExtendableMessage<\n"
276 " $classname$> implements\n"
277 " $extra_interfaces$\n"
278 " $classname$OrBuilder {\n",
279 "static", is_own_file ? " " : " static ",
280 "classname", descriptor_->name(),
281 "extra_interfaces", ExtraMessageInterfaces(descriptor_));
282 builder_type = strings::Substitute(
283 "com.google.protobuf.GeneratedMessage.ExtendableBuilder<$0, ?>",
284 name_resolver_->GetImmutableClassName(descriptor_));
285 } else {
286 printer->Print(
287 "public$static$final class $classname$ extends\n"
288 " com.google.protobuf.GeneratedMessageLite.ExtendableMessage<\n"
289 " $classname$> implements\n"
290 " $extra_interfaces$\n"
291 " $classname$OrBuilder {\n",
292 "static", is_own_file ? " " : " static ",
293 "classname", descriptor_->name(),
294 "extra_interfaces", ExtraMessageInterfaces(descriptor_));
295 builder_type = strings::Substitute(
296 "com.google.protobuf.GeneratedMessageLite.ExtendableBuilder<$0, ?>",
297 name_resolver_->GetImmutableClassName(descriptor_));
298 }
299 } else {
300 if (HasDescriptorMethods(descriptor_)) {
301 printer->Print(
302 "public$static$final class $classname$ extends\n"
303 " com.google.protobuf.GeneratedMessage implements\n"
304 " $extra_interfaces$\n"
305 " $classname$OrBuilder {\n",
306 "static", is_own_file ? " " : " static ",
307 "classname", descriptor_->name(),
308 "extra_interfaces", ExtraMessageInterfaces(descriptor_));
309 builder_type = "com.google.protobuf.GeneratedMessage.Builder<?>";
310 } else {
311 printer->Print(
312 "public$static$final class $classname$ extends\n"
313 " com.google.protobuf.GeneratedMessageLite implements\n"
314 " $extra_interfaces$\n"
315 " $classname$OrBuilder {\n",
316 "static", is_own_file ? " " : " static ",
317 "classname", descriptor_->name(),
318 "extra_interfaces", ExtraMessageInterfaces(descriptor_));
319 builder_type = "com.google.protobuf.GeneratedMessageLite.Builder";
320 }
321 }
322 printer->Indent();
323 // Using builder_type, instead of Builder, prevents the Builder class from
324 // being loaded into PermGen space when the default instance is created.
325 // This optimizes the PermGen space usage for clients that do not modify
326 // messages.
327 printer->Print(
328 "// Use $classname$.newBuilder() to construct.\n"
329 "private $classname$($buildertype$ builder) {\n"
330 " super(builder);\n"
331 "$set_unknown_fields$\n"
332 "}\n",
333 "classname", descriptor_->name(),
334 "buildertype", builder_type,
335 "set_unknown_fields",
336 " this.unknownFields = builder.getUnknownFields();");
337 printer->Print(
338 // Used when constructing the default instance, which cannot be initialized
339 // immediately because it may cyclically refer to other default instances.
340 "private $classname$(boolean noInit) {$set_default_unknown_fields$}\n"
341 "\n"
342 "private static final $classname$ defaultInstance;\n"
343 "public static $classname$ getDefaultInstance() {\n"
344 " return defaultInstance;\n"
345 "}\n"
346 "\n"
347 "public $classname$ getDefaultInstanceForType() {\n"
348 " return defaultInstance;\n"
349 "}\n"
350 "\n",
351 "classname", descriptor_->name(),
352 "set_default_unknown_fields", UseUnknownFieldSet(descriptor_)
353 ? " this.unknownFields ="
354 " com.google.protobuf.UnknownFieldSet.getDefaultInstance(); "
355 : " this.unknownFields = com.google.protobuf.ByteString.EMPTY;");
356
357 if (UseUnknownFieldSet(descriptor_)) {
358 printer->Print(
359 "private final com.google.protobuf.UnknownFieldSet unknownFields;\n"
360 ""
361 "@java.lang.Override\n"
362 "public final com.google.protobuf.UnknownFieldSet\n"
363 " getUnknownFields() {\n"
364 " return this.unknownFields;\n"
365 "}\n");
366 } else {
367 printer->Print(
368 "private final com.google.protobuf.ByteString unknownFields;\n");
369 }
370
371 if (HasGeneratedMethods(descriptor_)) {
372 GenerateParsingConstructor(printer);
373 }
374
375 GenerateDescriptorMethods(printer);
376 GenerateParser(printer);
377
378 // Nested types
379 for (int i = 0; i < descriptor_->enum_type_count(); i++) {
380 EnumGenerator(descriptor_->enum_type(i), true, context_)
381 .Generate(printer);
382 }
383
384 for (int i = 0; i < descriptor_->nested_type_count(); i++) {
385 ImmutableMessageGenerator messageGenerator(
386 descriptor_->nested_type(i), context_);
387 messageGenerator.GenerateInterface(printer);
388 messageGenerator.Generate(printer);
389 }
390
391 if (GenerateHasBits(descriptor_)) {
392 // Integers for bit fields.
393 int totalBits = 0;
394 for (int i = 0; i < descriptor_->field_count(); i++) {
395 totalBits += field_generators_.get(descriptor_->field(i))
396 .GetNumBitsForMessage();
397 }
398 int totalInts = (totalBits + 31) / 32;
399 for (int i = 0; i < totalInts; i++) {
400 printer->Print("private int $bit_field_name$;\n",
401 "bit_field_name", GetBitFieldName(i));
402 }
403 }
404
405 // oneof
406 map<string, string> vars;
407 for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
408 vars["oneof_name"] = context_->GetOneofGeneratorInfo(
409 descriptor_->oneof_decl(i))->name;
410 vars["oneof_capitalized_name"] = context_->GetOneofGeneratorInfo(
411 descriptor_->oneof_decl(i))->capitalized_name;
412 vars["oneof_index"] = SimpleItoa(descriptor_->oneof_decl(i)->index());
413 // oneofCase_ and oneof_
414 printer->Print(vars,
415 "private int $oneof_name$Case_ = 0;\n"
416 "private java.lang.Object $oneof_name$_;\n");
417 // OneofCase enum
418 printer->Print(vars,
419 "public enum $oneof_capitalized_name$Case\n"
420 " implements com.google.protobuf.Internal.EnumLite {\n");
421 printer->Indent();
422 for (int j = 0; j < descriptor_->oneof_decl(i)->field_count(); j++) {
423 const FieldDescriptor* field = descriptor_->oneof_decl(i)->field(j);
424 printer->Print(
425 "$field_name$($field_number$),\n",
426 "field_name",
427 ToUpper(field->name()),
428 "field_number",
429 SimpleItoa(field->number()));
430 }
431 printer->Print(
432 "$cap_oneof_name$_NOT_SET(0);\n",
433 "cap_oneof_name",
434 ToUpper(vars["oneof_name"]));
435 printer->Print(vars,
436 "private int value = 0;\n"
437 "private $oneof_capitalized_name$Case(int value) {\n"
438 " this.value = value;\n"
439 "}\n");
440 printer->Print(vars,
441 "public static $oneof_capitalized_name$Case valueOf(int value) {\n"
442 " switch (value) {\n");
443 for (int j = 0; j < descriptor_->oneof_decl(i)->field_count(); j++) {
444 const FieldDescriptor* field = descriptor_->oneof_decl(i)->field(j);
445 printer->Print(
446 " case $field_number$: return $field_name$;\n",
447 "field_number",
448 SimpleItoa(field->number()),
449 "field_name",
450 ToUpper(field->name()));
451 }
452 printer->Print(
453 " case 0: return $cap_oneof_name$_NOT_SET;\n"
454 " default: throw new java.lang.IllegalArgumentException(\n"
455 " \"Value is undefined for this oneof enum.\");\n"
456 " }\n"
457 "}\n"
458 "public int getNumber() {\n"
459 " return this.value;\n"
460 "}\n",
461 "cap_oneof_name", ToUpper(vars["oneof_name"]));
462 printer->Outdent();
463 printer->Print("};\n\n");
464 // oneofCase()
465 printer->Print(vars,
466 "public $oneof_capitalized_name$Case\n"
467 "get$oneof_capitalized_name$Case() {\n"
468 " return $oneof_capitalized_name$Case.valueOf(\n"
469 " $oneof_name$Case_);\n"
470 "}\n"
471 "\n");
472 }
473
474 // Fields
475 for (int i = 0; i < descriptor_->field_count(); i++) {
476 printer->Print("public static final int $constant_name$ = $number$;\n",
477 "constant_name", FieldConstantName(descriptor_->field(i)),
478 "number", SimpleItoa(descriptor_->field(i)->number()));
479 field_generators_.get(descriptor_->field(i)).GenerateMembers(printer);
480 printer->Print("\n");
481 }
482
483 // Called by the constructor, except in the case of the default instance,
484 // in which case this is called by static init code later on.
485 printer->Print("private void initFields() {\n");
486 printer->Indent();
487 for (int i = 0; i < descriptor_->field_count(); i++) {
488 if (!descriptor_->field(i)->containing_oneof()) {
489 field_generators_.get(descriptor_->field(i))
490 .GenerateInitializationCode(printer);
491 }
492 }
493
494 printer->Outdent();
495 printer->Print("}\n");
496
497 if (HasGeneratedMethods(descriptor_)) {
498 GenerateIsInitialized(printer, MEMOIZE);
499 GenerateMessageSerializationMethods(printer);
500 }
501
502 if (HasEqualsAndHashCode(descriptor_)) {
503 GenerateEqualsAndHashCode(printer);
504 }
505
506
507 GenerateParseFromMethods(printer);
508 GenerateBuilder(printer);
509
510 // Carefully initialize the default instance in such a way that it doesn't
511 // conflict with other initialization.
512 printer->Print(
513 "\n"
514 "static {\n"
515 " defaultInstance = new $classname$(true);\n"
516 " defaultInstance.initFields();\n"
517 "}\n"
518 "\n"
519 "// @@protoc_insertion_point(class_scope:$full_name$)\n",
520 "classname", descriptor_->name(),
521 "full_name", descriptor_->full_name());
522
523 // Extensions must be declared after the defaultInstance is initialized
524 // because the defaultInstance is used by the extension to lazily retrieve
525 // the outer class's FileDescriptor.
526 for (int i = 0; i < descriptor_->extension_count(); i++) {
527 ImmutableExtensionGenerator(descriptor_->extension(i), context_)
528 .Generate(printer);
529 }
530
531 printer->Outdent();
532 printer->Print("}\n\n");
533 }
534
535
536 // ===================================================================
537
538 void ImmutableMessageGenerator::
GenerateMessageSerializationMethods(io::Printer * printer)539 GenerateMessageSerializationMethods(io::Printer* printer) {
540 scoped_array<const FieldDescriptor*> sorted_fields(
541 SortFieldsByNumber(descriptor_));
542
543 vector<const Descriptor::ExtensionRange*> sorted_extensions;
544 for (int i = 0; i < descriptor_->extension_range_count(); ++i) {
545 sorted_extensions.push_back(descriptor_->extension_range(i));
546 }
547 sort(sorted_extensions.begin(), sorted_extensions.end(),
548 ExtensionRangeOrdering());
549
550 printer->Print(
551 "public void writeTo(com.google.protobuf.CodedOutputStream output)\n"
552 " throws java.io.IOException {\n");
553 printer->Indent();
554 // writeTo(CodedOutputStream output) might be invoked without
555 // getSerializedSize() ever being called, but we need the memoized
556 // sizes in case this message has packed fields. Rather than emit checks for
557 // each packed field, just call getSerializedSize() up front for all messages.
558 // In most cases, getSerializedSize() will have already been called anyway by
559 // one of the wrapper writeTo() methods, making this call cheap.
560 printer->Print(
561 "getSerializedSize();\n");
562
563 if (descriptor_->extension_range_count() > 0) {
564 if (descriptor_->options().message_set_wire_format()) {
565 printer->Print(
566 "com.google.protobuf.GeneratedMessage$lite$\n"
567 " .ExtendableMessage<$classname$>.ExtensionWriter extensionWriter =\n"
568 " newMessageSetExtensionWriter();\n",
569 "lite", HasDescriptorMethods(descriptor_) ? "" : "Lite",
570 "classname", name_resolver_->GetImmutableClassName(descriptor_));
571 } else {
572 printer->Print(
573 "com.google.protobuf.GeneratedMessage$lite$\n"
574 " .ExtendableMessage<$classname$>.ExtensionWriter extensionWriter =\n"
575 " newExtensionWriter();\n",
576 "lite", HasDescriptorMethods(descriptor_) ? "" : "Lite",
577 "classname", name_resolver_->GetImmutableClassName(descriptor_));
578 }
579 }
580
581 // Merge the fields and the extension ranges, both sorted by field number.
582 for (int i = 0, j = 0;
583 i < descriptor_->field_count() || j < sorted_extensions.size();
584 ) {
585 if (i == descriptor_->field_count()) {
586 GenerateSerializeOneExtensionRange(printer, sorted_extensions[j++]);
587 } else if (j == sorted_extensions.size()) {
588 GenerateSerializeOneField(printer, sorted_fields[i++]);
589 } else if (sorted_fields[i]->number() < sorted_extensions[j]->start) {
590 GenerateSerializeOneField(printer, sorted_fields[i++]);
591 } else {
592 GenerateSerializeOneExtensionRange(printer, sorted_extensions[j++]);
593 }
594 }
595
596 if (UseUnknownFieldSet(descriptor_)) {
597 if (descriptor_->options().message_set_wire_format()) {
598 printer->Print(
599 "getUnknownFields().writeAsMessageSetTo(output);\n");
600 } else {
601 printer->Print(
602 "getUnknownFields().writeTo(output);\n");
603 }
604 } else {
605 printer->Print(
606 "output.writeRawBytes(unknownFields);\n");
607 }
608
609 printer->Outdent();
610 printer->Print(
611 "}\n"
612 "\n"
613 "private int memoizedSerializedSize = -1;\n"
614 "public int getSerializedSize() {\n"
615 " int size = memoizedSerializedSize;\n"
616 " if (size != -1) return size;\n"
617 "\n"
618 " size = 0;\n");
619 printer->Indent();
620
621 for (int i = 0; i < descriptor_->field_count(); i++) {
622 field_generators_.get(sorted_fields[i]).GenerateSerializedSizeCode(printer);
623 }
624
625 if (descriptor_->extension_range_count() > 0) {
626 if (descriptor_->options().message_set_wire_format()) {
627 printer->Print(
628 "size += extensionsSerializedSizeAsMessageSet();\n");
629 } else {
630 printer->Print(
631 "size += extensionsSerializedSize();\n");
632 }
633 }
634
635 if (UseUnknownFieldSet(descriptor_)) {
636 if (descriptor_->options().message_set_wire_format()) {
637 printer->Print(
638 "size += getUnknownFields().getSerializedSizeAsMessageSet();\n");
639 } else {
640 printer->Print(
641 "size += getUnknownFields().getSerializedSize();\n");
642 }
643 } else {
644 printer->Print(
645 "size += unknownFields.size();\n");
646 }
647
648 printer->Outdent();
649 printer->Print(
650 " memoizedSerializedSize = size;\n"
651 " return size;\n"
652 "}\n"
653 "\n");
654
655 printer->Print(
656 "private static final long serialVersionUID = 0L;\n"
657 "@java.lang.Override\n"
658 "protected java.lang.Object writeReplace()\n"
659 " throws java.io.ObjectStreamException {\n"
660 " return super.writeReplace();\n"
661 "}\n"
662 "\n");
663 }
664
665 void ImmutableMessageGenerator::
GenerateParseFromMethods(io::Printer * printer)666 GenerateParseFromMethods(io::Printer* printer) {
667 // Note: These are separate from GenerateMessageSerializationMethods()
668 // because they need to be generated even for messages that are optimized
669 // for code size.
670 printer->Print(
671 "public static $classname$ parseFrom(\n"
672 " com.google.protobuf.ByteString data)\n"
673 " throws com.google.protobuf.InvalidProtocolBufferException {\n"
674 " return PARSER.parseFrom(data);\n"
675 "}\n"
676 "public static $classname$ parseFrom(\n"
677 " com.google.protobuf.ByteString data,\n"
678 " com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n"
679 " throws com.google.protobuf.InvalidProtocolBufferException {\n"
680 " return PARSER.parseFrom(data, extensionRegistry);\n"
681 "}\n"
682 "public static $classname$ parseFrom(byte[] data)\n"
683 " throws com.google.protobuf.InvalidProtocolBufferException {\n"
684 " return PARSER.parseFrom(data);\n"
685 "}\n"
686 "public static $classname$ parseFrom(\n"
687 " byte[] data,\n"
688 " com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n"
689 " throws com.google.protobuf.InvalidProtocolBufferException {\n"
690 " return PARSER.parseFrom(data, extensionRegistry);\n"
691 "}\n"
692 "public static $classname$ parseFrom(java.io.InputStream input)\n"
693 " throws java.io.IOException {\n"
694 " return PARSER.parseFrom(input);\n"
695 "}\n"
696 "public static $classname$ parseFrom(\n"
697 " java.io.InputStream input,\n"
698 " com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n"
699 " throws java.io.IOException {\n"
700 " return PARSER.parseFrom(input, extensionRegistry);\n"
701 "}\n"
702 "public static $classname$ parseDelimitedFrom(java.io.InputStream input)\n"
703 " throws java.io.IOException {\n"
704 " return PARSER.parseDelimitedFrom(input);\n"
705 "}\n"
706 "public static $classname$ parseDelimitedFrom(\n"
707 " java.io.InputStream input,\n"
708 " com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n"
709 " throws java.io.IOException {\n"
710 " return PARSER.parseDelimitedFrom(input, extensionRegistry);\n"
711 "}\n"
712 "public static $classname$ parseFrom(\n"
713 " com.google.protobuf.CodedInputStream input)\n"
714 " throws java.io.IOException {\n"
715 " return PARSER.parseFrom(input);\n"
716 "}\n"
717 "public static $classname$ parseFrom(\n"
718 " com.google.protobuf.CodedInputStream input,\n"
719 " com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n"
720 " throws java.io.IOException {\n"
721 " return PARSER.parseFrom(input, extensionRegistry);\n"
722 "}\n"
723 "\n",
724 "classname", name_resolver_->GetImmutableClassName(descriptor_));
725 }
726
GenerateSerializeOneField(io::Printer * printer,const FieldDescriptor * field)727 void ImmutableMessageGenerator::GenerateSerializeOneField(
728 io::Printer* printer, const FieldDescriptor* field) {
729 field_generators_.get(field).GenerateSerializationCode(printer);
730 }
731
GenerateSerializeOneExtensionRange(io::Printer * printer,const Descriptor::ExtensionRange * range)732 void ImmutableMessageGenerator::GenerateSerializeOneExtensionRange(
733 io::Printer* printer, const Descriptor::ExtensionRange* range) {
734 printer->Print(
735 "extensionWriter.writeUntil($end$, output);\n",
736 "end", SimpleItoa(range->end));
737 }
738
739 // ===================================================================
740
GenerateBuilder(io::Printer * printer)741 void ImmutableMessageGenerator::GenerateBuilder(io::Printer* printer) {
742 printer->Print(
743 "public static Builder newBuilder() { return Builder.create(); }\n"
744 "public Builder newBuilderForType() { return newBuilder(); }\n"
745 "public static Builder newBuilder($classname$ prototype) {\n"
746 " return newBuilder().mergeFrom(prototype);\n"
747 "}\n"
748 "public Builder toBuilder() { return newBuilder(this); }\n"
749 "\n",
750 "classname", name_resolver_->GetImmutableClassName(descriptor_));
751
752 if (HasNestedBuilders(descriptor_)) {
753 printer->Print(
754 "@java.lang.Override\n"
755 "protected Builder newBuilderForType(\n"
756 " com.google.protobuf.GeneratedMessage.BuilderParent parent) {\n"
757 " Builder builder = new Builder(parent);\n"
758 " return builder;\n"
759 "}\n");
760 }
761
762 WriteMessageDocComment(printer, descriptor_);
763
764 if (descriptor_->extension_range_count() > 0) {
765 if (HasDescriptorMethods(descriptor_)) {
766 printer->Print(
767 "public static final class Builder extends\n"
768 " com.google.protobuf.GeneratedMessage.ExtendableBuilder<\n"
769 " $classname$, Builder> implements\n"
770 " $extra_interfaces$\n"
771 " $classname$OrBuilder {\n",
772 "classname", name_resolver_->GetImmutableClassName(descriptor_),
773 "extra_interfaces", ExtraBuilderInterfaces(descriptor_));
774 } else {
775 printer->Print(
776 "public static final class Builder extends\n"
777 " com.google.protobuf.GeneratedMessageLite.ExtendableBuilder<\n"
778 " $classname$, Builder> implements\n"
779 " $extra_interfaces$\n"
780 " $classname$OrBuilder {\n",
781 "classname", name_resolver_->GetImmutableClassName(descriptor_),
782 "extra_interfaces", ExtraBuilderInterfaces(descriptor_));
783 }
784 } else {
785 if (HasDescriptorMethods(descriptor_)) {
786 printer->Print(
787 "public static final class Builder extends\n"
788 " com.google.protobuf.GeneratedMessage.Builder<Builder> implements\n"
789 " $extra_interfaces$\n"
790 " $classname$OrBuilder {\n",
791 "classname", name_resolver_->GetImmutableClassName(descriptor_),
792 "extra_interfaces", ExtraBuilderInterfaces(descriptor_));
793 } else {
794 printer->Print(
795 "public static final class Builder extends\n"
796 " com.google.protobuf.GeneratedMessageLite.Builder<\n"
797 " $classname$, Builder>\n"
798 " implements\n"
799 " $extra_interfaces$\n"
800 " $classname$OrBuilder {\n",
801 "classname", name_resolver_->GetImmutableClassName(descriptor_),
802 "extra_interfaces", ExtraBuilderInterfaces(descriptor_));
803 }
804 }
805 printer->Indent();
806
807 GenerateDescriptorMethods(printer);
808 GenerateCommonBuilderMethods(printer);
809
810 if (HasGeneratedMethods(descriptor_)) {
811 GenerateIsInitialized(printer, DONT_MEMOIZE);
812 GenerateBuilderParsingMethods(printer);
813 }
814
815 // oneof
816 map<string, string> vars;
817 for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
818 vars["oneof_name"] = context_->GetOneofGeneratorInfo(
819 descriptor_->oneof_decl(i))->name;
820 vars["oneof_capitalized_name"] = context_->GetOneofGeneratorInfo(
821 descriptor_->oneof_decl(i))->capitalized_name;
822 vars["oneof_index"] = SimpleItoa(descriptor_->oneof_decl(i)->index());
823 // oneofCase_ and oneof_
824 printer->Print(vars,
825 "private int $oneof_name$Case_ = 0;\n"
826 "private java.lang.Object $oneof_name$_;\n");
827 // oneofCase() and clearOneof()
828 printer->Print(vars,
829 "public $oneof_capitalized_name$Case\n"
830 " get$oneof_capitalized_name$Case() {\n"
831 " return $oneof_capitalized_name$Case.valueOf(\n"
832 " $oneof_name$Case_);\n"
833 "}\n"
834 "\n"
835 "public Builder clear$oneof_capitalized_name$() {\n"
836 " $oneof_name$Case_ = 0;\n"
837 " $oneof_name$_ = null;\n");
838 if (HasDescriptorMethods(descriptor_)) {
839 printer->Print(" onChanged();\n");
840 }
841 printer->Print(
842 " return this;\n"
843 "}\n"
844 "\n");
845 }
846
847 if (GenerateHasBits(descriptor_)) {
848 // Integers for bit fields.
849 int totalBits = 0;
850 for (int i = 0; i < descriptor_->field_count(); i++) {
851 totalBits += field_generators_.get(descriptor_->field(i))
852 .GetNumBitsForBuilder();
853 }
854 int totalInts = (totalBits + 31) / 32;
855 for (int i = 0; i < totalInts; i++) {
856 printer->Print("private int $bit_field_name$;\n",
857 "bit_field_name", GetBitFieldName(i));
858 }
859 }
860
861 for (int i = 0; i < descriptor_->field_count(); i++) {
862 printer->Print("\n");
863 field_generators_.get(descriptor_->field(i))
864 .GenerateBuilderMembers(printer);
865 }
866
867 printer->Print(
868 "\n"
869 "// @@protoc_insertion_point(builder_scope:$full_name$)\n",
870 "full_name", descriptor_->full_name());
871
872 printer->Outdent();
873 printer->Print("}\n");
874 }
875
876 void ImmutableMessageGenerator::
GenerateDescriptorMethods(io::Printer * printer)877 GenerateDescriptorMethods(io::Printer* printer) {
878 if (HasDescriptorMethods(descriptor_)) {
879 if (!descriptor_->options().no_standard_descriptor_accessor()) {
880 printer->Print(
881 "public static final com.google.protobuf.Descriptors.Descriptor\n"
882 " getDescriptor() {\n"
883 " return $fileclass$.internal_$identifier$_descriptor;\n"
884 "}\n"
885 "\n",
886 "fileclass", name_resolver_->GetImmutableClassName(descriptor_->file()),
887 "identifier", UniqueFileScopeIdentifier(descriptor_));
888 }
889 printer->Print(
890 "protected com.google.protobuf.GeneratedMessage.FieldAccessorTable\n"
891 " internalGetFieldAccessorTable() {\n"
892 " return $fileclass$.internal_$identifier$_fieldAccessorTable\n"
893 " .ensureFieldAccessorsInitialized(\n"
894 " $classname$.class, $classname$.Builder.class);\n"
895 "}\n"
896 "\n",
897 "classname", name_resolver_->GetImmutableClassName(descriptor_),
898 "fileclass", name_resolver_->GetImmutableClassName(descriptor_->file()),
899 "identifier", UniqueFileScopeIdentifier(descriptor_));
900 }
901 }
902
903 // ===================================================================
904
905 void ImmutableMessageGenerator::
GenerateCommonBuilderMethods(io::Printer * printer)906 GenerateCommonBuilderMethods(io::Printer* printer) {
907 printer->Print(
908 "// Construct using $classname$.newBuilder()\n"
909 "private Builder() {\n"
910 " maybeForceBuilderInitialization();\n"
911 "}\n"
912 "\n",
913 "classname", name_resolver_->GetImmutableClassName(descriptor_));
914
915 if (HasDescriptorMethods(descriptor_)) {
916 printer->Print(
917 "private Builder(\n"
918 " com.google.protobuf.GeneratedMessage.BuilderParent parent) {\n"
919 " super(parent);\n"
920 " maybeForceBuilderInitialization();\n"
921 "}\n",
922 "classname", name_resolver_->GetImmutableClassName(descriptor_));
923 }
924
925
926 if (HasNestedBuilders(descriptor_)) {
927 printer->Print(
928 "private void maybeForceBuilderInitialization() {\n"
929 " if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {\n");
930
931 printer->Indent();
932 printer->Indent();
933 for (int i = 0; i < descriptor_->field_count(); i++) {
934 if (!descriptor_->field(i)->containing_oneof()) {
935 field_generators_.get(descriptor_->field(i))
936 .GenerateFieldBuilderInitializationCode(printer);
937 }
938 }
939 printer->Outdent();
940 printer->Outdent();
941
942 printer->Print(
943 " }\n"
944 "}\n");
945 } else {
946 printer->Print(
947 "private void maybeForceBuilderInitialization() {\n"
948 "}\n");
949 }
950
951 printer->Print(
952 "private static Builder create() {\n"
953 " return new Builder();\n"
954 "}\n"
955 "\n"
956 "public Builder clear() {\n"
957 " super.clear();\n",
958 "classname", name_resolver_->GetImmutableClassName(descriptor_));
959
960 printer->Indent();
961
962 for (int i = 0; i < descriptor_->field_count(); i++) {
963 if (!descriptor_->field(i)->containing_oneof()) {
964 field_generators_.get(descriptor_->field(i))
965 .GenerateBuilderClearCode(printer);
966 }
967 }
968
969 for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
970 printer->Print(
971 "$oneof_name$Case_ = 0;\n"
972 "$oneof_name$_ = null;\n",
973 "oneof_name", context_->GetOneofGeneratorInfo(
974 descriptor_->oneof_decl(i))->name);
975 }
976
977 printer->Outdent();
978
979 printer->Print(
980 " return this;\n"
981 "}\n"
982 "\n"
983 "public Builder clone() {\n"
984 " return create().mergeFrom(buildPartial());\n"
985 "}\n"
986 "\n",
987 "classname", name_resolver_->GetImmutableClassName(descriptor_));
988 if (HasDescriptorMethods(descriptor_)) {
989 printer->Print(
990 "public com.google.protobuf.Descriptors.Descriptor\n"
991 " getDescriptorForType() {\n"
992 " return $fileclass$.internal_$identifier$_descriptor;\n"
993 "}\n"
994 "\n",
995 "fileclass", name_resolver_->GetImmutableClassName(descriptor_->file()),
996 "identifier", UniqueFileScopeIdentifier(descriptor_));
997 }
998 printer->Print(
999 "public $classname$ getDefaultInstanceForType() {\n"
1000 " return $classname$.getDefaultInstance();\n"
1001 "}\n"
1002 "\n",
1003 "classname", name_resolver_->GetImmutableClassName(descriptor_));
1004
1005 // -----------------------------------------------------------------
1006
1007 printer->Print(
1008 "public $classname$ build() {\n"
1009 " $classname$ result = buildPartial();\n"
1010 " if (!result.isInitialized()) {\n"
1011 " throw newUninitializedMessageException(result);\n"
1012 " }\n"
1013 " return result;\n"
1014 "}\n"
1015 "\n"
1016 "public $classname$ buildPartial() {\n"
1017 " $classname$ result = new $classname$(this);\n",
1018 "classname", name_resolver_->GetImmutableClassName(descriptor_));
1019
1020 printer->Indent();
1021
1022 int totalBuilderBits = 0;
1023 int totalMessageBits = 0;
1024 for (int i = 0; i < descriptor_->field_count(); i++) {
1025 const ImmutableFieldGenerator& field =
1026 field_generators_.get(descriptor_->field(i));
1027 totalBuilderBits += field.GetNumBitsForBuilder();
1028 totalMessageBits += field.GetNumBitsForMessage();
1029 }
1030 int totalBuilderInts = (totalBuilderBits + 31) / 32;
1031 int totalMessageInts = (totalMessageBits + 31) / 32;
1032
1033 if (GenerateHasBits(descriptor_)) {
1034 // Local vars for from and to bit fields to avoid accessing the builder and
1035 // message over and over for these fields. Seems to provide a slight
1036 // perforamance improvement in micro benchmark and this is also what proto1
1037 // code does.
1038 for (int i = 0; i < totalBuilderInts; i++) {
1039 printer->Print("int from_$bit_field_name$ = $bit_field_name$;\n",
1040 "bit_field_name", GetBitFieldName(i));
1041 }
1042 for (int i = 0; i < totalMessageInts; i++) {
1043 printer->Print("int to_$bit_field_name$ = 0;\n",
1044 "bit_field_name", GetBitFieldName(i));
1045 }
1046 }
1047
1048 // Output generation code for each field.
1049 for (int i = 0; i < descriptor_->field_count(); i++) {
1050 field_generators_.get(descriptor_->field(i)).GenerateBuildingCode(printer);
1051 }
1052
1053 if (GenerateHasBits(descriptor_)) {
1054 // Copy the bit field results to the generated message
1055 for (int i = 0; i < totalMessageInts; i++) {
1056 printer->Print("result.$bit_field_name$ = to_$bit_field_name$;\n",
1057 "bit_field_name", GetBitFieldName(i));
1058 }
1059 }
1060
1061 for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
1062 printer->Print("result.$oneof_name$Case_ = $oneof_name$Case_;\n",
1063 "oneof_name", context_->GetOneofGeneratorInfo(
1064 descriptor_->oneof_decl(i))->name);
1065 }
1066
1067 printer->Outdent();
1068
1069 if (HasDescriptorMethods(descriptor_)) {
1070 printer->Print(
1071 " onBuilt();\n");
1072 }
1073
1074 printer->Print(
1075 " return result;\n"
1076 "}\n"
1077 "\n",
1078 "classname", name_resolver_->GetImmutableClassName(descriptor_));
1079
1080 // -----------------------------------------------------------------
1081
1082 if (HasGeneratedMethods(descriptor_)) {
1083 // MergeFrom(Message other) requires the ability to distinguish the other
1084 // messages type by its descriptor.
1085 if (HasDescriptorMethods(descriptor_)) {
1086 printer->Print(
1087 "public Builder mergeFrom(com.google.protobuf.Message other) {\n"
1088 " if (other instanceof $classname$) {\n"
1089 " return mergeFrom(($classname$)other);\n"
1090 " } else {\n"
1091 " super.mergeFrom(other);\n"
1092 " return this;\n"
1093 " }\n"
1094 "}\n"
1095 "\n",
1096 "classname", name_resolver_->GetImmutableClassName(descriptor_));
1097 }
1098
1099 printer->Print(
1100 "public Builder mergeFrom($classname$ other) {\n"
1101 // Optimization: If other is the default instance, we know none of its
1102 // fields are set so we can skip the merge.
1103 " if (other == $classname$.getDefaultInstance()) return this;\n",
1104 "classname", name_resolver_->GetImmutableClassName(descriptor_));
1105 printer->Indent();
1106
1107 for (int i = 0; i < descriptor_->field_count(); i++) {
1108 if (!descriptor_->field(i)->containing_oneof()) {
1109 field_generators_.get(
1110 descriptor_->field(i)).GenerateMergingCode(printer);
1111 }
1112 }
1113
1114 // Merge oneof fields.
1115 for (int i = 0; i < descriptor_->oneof_decl_count(); ++i) {
1116 printer->Print(
1117 "switch (other.get$oneof_capitalized_name$Case()) {\n",
1118 "oneof_capitalized_name",
1119 context_->GetOneofGeneratorInfo(
1120 descriptor_->oneof_decl(i))->capitalized_name);
1121 printer->Indent();
1122 for (int j = 0; j < descriptor_->oneof_decl(i)->field_count(); j++) {
1123 const FieldDescriptor* field = descriptor_->oneof_decl(i)->field(j);
1124 printer->Print(
1125 "case $field_name$: {\n",
1126 "field_name",
1127 ToUpper(field->name()));
1128 printer->Indent();
1129 field_generators_.get(field).GenerateMergingCode(printer);
1130 printer->Print(
1131 "break;\n");
1132 printer->Outdent();
1133 printer->Print(
1134 "}\n");
1135 }
1136 printer->Print(
1137 "case $cap_oneof_name$_NOT_SET: {\n"
1138 " break;\n"
1139 "}\n",
1140 "cap_oneof_name",
1141 ToUpper(context_->GetOneofGeneratorInfo(
1142 descriptor_->oneof_decl(i))->name));
1143 printer->Outdent();
1144 printer->Print(
1145 "}\n");
1146 }
1147
1148 printer->Outdent();
1149
1150 // if message type has extensions
1151 if (descriptor_->extension_range_count() > 0) {
1152 printer->Print(
1153 " this.mergeExtensionFields(other);\n");
1154 }
1155
1156 if (UseUnknownFieldSet(descriptor_)) {
1157 printer->Print(
1158 " this.mergeUnknownFields(other.getUnknownFields());\n");
1159 } else {
1160 printer->Print(
1161 " setUnknownFields(\n"
1162 " getUnknownFields().concat(other.unknownFields));\n");
1163 }
1164
1165 printer->Print(
1166 " return this;\n"
1167 "}\n"
1168 "\n");
1169 }
1170 }
1171
1172 // ===================================================================
1173
1174 void ImmutableMessageGenerator::
GenerateBuilderParsingMethods(io::Printer * printer)1175 GenerateBuilderParsingMethods(io::Printer* printer) {
1176 printer->Print(
1177 "public Builder mergeFrom(\n"
1178 " com.google.protobuf.CodedInputStream input,\n"
1179 " com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n"
1180 " throws java.io.IOException {\n"
1181 " $classname$ parsedMessage = null;\n"
1182 " try {\n"
1183 " parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);\n"
1184 " } catch (com.google.protobuf.InvalidProtocolBufferException e) {\n"
1185 " parsedMessage = ($classname$) e.getUnfinishedMessage();\n"
1186 " throw e;\n"
1187 " } finally {\n"
1188 " if (parsedMessage != null) {\n"
1189 " mergeFrom(parsedMessage);\n"
1190 " }\n"
1191 " }\n"
1192 " return this;\n"
1193 "}\n",
1194 "classname", name_resolver_->GetImmutableClassName(descriptor_));
1195 }
1196
1197 // ===================================================================
1198
GenerateIsInitialized(io::Printer * printer,UseMemoization useMemoization)1199 void ImmutableMessageGenerator::GenerateIsInitialized(
1200 io::Printer* printer, UseMemoization useMemoization) {
1201 bool memoization = useMemoization == MEMOIZE;
1202 if (memoization) {
1203 // Memoizes whether the protocol buffer is fully initialized (has all
1204 // required fields). -1 means not yet computed. 0 means false and 1 means
1205 // true.
1206 printer->Print(
1207 "private byte memoizedIsInitialized = -1;\n");
1208 }
1209 printer->Print(
1210 "public final boolean isInitialized() {\n");
1211 printer->Indent();
1212
1213 if (memoization) {
1214 // Don't directly compare to -1 to avoid an Android x86 JIT bug.
1215 printer->Print(
1216 "byte isInitialized = memoizedIsInitialized;\n"
1217 "if (isInitialized == 1) return true;\n"
1218 "if (isInitialized == 0) return false;\n"
1219 "\n");
1220 }
1221
1222 // Check that all required fields in this message are set.
1223 // TODO(kenton): We can optimize this when we switch to putting all the
1224 // "has" fields into a single bitfield.
1225 for (int i = 0; i < descriptor_->field_count(); i++) {
1226 const FieldDescriptor* field = descriptor_->field(i);
1227 const FieldGeneratorInfo* info = context_->GetFieldGeneratorInfo(field);
1228
1229 if (field->is_required()) {
1230 printer->Print(
1231 "if (!has$name$()) {\n"
1232 " $memoize$\n"
1233 " return false;\n"
1234 "}\n",
1235 "name", info->capitalized_name,
1236 "memoize", memoization ? "memoizedIsInitialized = 0;" : "");
1237 }
1238 }
1239
1240 // Now check that all embedded messages are initialized.
1241 for (int i = 0; i < descriptor_->field_count(); i++) {
1242 const FieldDescriptor* field = descriptor_->field(i);
1243 const FieldGeneratorInfo* info = context_->GetFieldGeneratorInfo(field);
1244 if (GetJavaType(field) == JAVATYPE_MESSAGE &&
1245 HasRequiredFields(field->message_type())) {
1246 switch (field->label()) {
1247 case FieldDescriptor::LABEL_REQUIRED:
1248 printer->Print(
1249 "if (!get$name$().isInitialized()) {\n"
1250 " $memoize$\n"
1251 " return false;\n"
1252 "}\n",
1253 "type", name_resolver_->GetImmutableClassName(
1254 field->message_type()),
1255 "name", info->capitalized_name,
1256 "memoize", memoization ? "memoizedIsInitialized = 0;" : "");
1257 break;
1258 case FieldDescriptor::LABEL_OPTIONAL:
1259 printer->Print(
1260 "if (has$name$()) {\n"
1261 " if (!get$name$().isInitialized()) {\n"
1262 " $memoize$\n"
1263 " return false;\n"
1264 " }\n"
1265 "}\n",
1266 "type", name_resolver_->GetImmutableClassName(
1267 field->message_type()),
1268 "name", info->capitalized_name,
1269 "memoize", memoization ? "memoizedIsInitialized = 0;" : "");
1270 break;
1271 case FieldDescriptor::LABEL_REPEATED:
1272 printer->Print(
1273 "for (int i = 0; i < get$name$Count(); i++) {\n"
1274 " if (!get$name$(i).isInitialized()) {\n"
1275 " $memoize$\n"
1276 " return false;\n"
1277 " }\n"
1278 "}\n",
1279 "type", name_resolver_->GetImmutableClassName(
1280 field->message_type()),
1281 "name", info->capitalized_name,
1282 "memoize", memoization ? "memoizedIsInitialized = 0;" : "");
1283 break;
1284 }
1285 }
1286 }
1287
1288 if (descriptor_->extension_range_count() > 0) {
1289 printer->Print(
1290 "if (!extensionsAreInitialized()) {\n"
1291 " $memoize$\n"
1292 " return false;\n"
1293 "}\n",
1294 "memoize", memoization ? "memoizedIsInitialized = 0;" : "");
1295 }
1296
1297 printer->Outdent();
1298
1299 if (memoization) {
1300 printer->Print(
1301 " memoizedIsInitialized = 1;\n");
1302 }
1303
1304 printer->Print(
1305 " return true;\n"
1306 "}\n"
1307 "\n");
1308 }
1309
1310 // ===================================================================
1311
1312 namespace {
CheckHasBitsForEqualsAndHashCode(const FieldDescriptor * field)1313 bool CheckHasBitsForEqualsAndHashCode(const FieldDescriptor* field) {
1314 if (field->is_repeated()) {
1315 return false;
1316 }
1317 if (SupportFieldPresence(field->file())) {
1318 return true;
1319 }
1320 return GetJavaType(field) == JAVATYPE_MESSAGE &&
1321 field->containing_oneof() == NULL;
1322 }
1323 } // namespace
1324
1325 void ImmutableMessageGenerator::
GenerateEqualsAndHashCode(io::Printer * printer)1326 GenerateEqualsAndHashCode(io::Printer* printer) {
1327 printer->Print(
1328 "@java.lang.Override\n"
1329 "public boolean equals(final java.lang.Object obj) {\n");
1330 printer->Indent();
1331 printer->Print(
1332 "if (obj == this) {\n"
1333 " return true;\n"
1334 "}\n"
1335 "if (!(obj instanceof $classname$)) {\n"
1336 " return super.equals(obj);\n"
1337 "}\n"
1338 "$classname$ other = ($classname$) obj;\n"
1339 "\n",
1340 "classname", name_resolver_->GetImmutableClassName(descriptor_));
1341
1342 printer->Print("boolean result = true;\n");
1343 for (int i = 0; i < descriptor_->field_count(); i++) {
1344 const FieldDescriptor* field = descriptor_->field(i);
1345 const FieldGeneratorInfo* info = context_->GetFieldGeneratorInfo(field);
1346 bool check_has_bits = CheckHasBitsForEqualsAndHashCode(field);
1347 if (check_has_bits) {
1348 printer->Print(
1349 "result = result && (has$name$() == other.has$name$());\n"
1350 "if (has$name$()) {\n",
1351 "name", info->capitalized_name);
1352 printer->Indent();
1353 }
1354 field_generators_.get(field).GenerateEqualsCode(printer);
1355 if (check_has_bits) {
1356 printer->Outdent();
1357 printer->Print(
1358 "}\n");
1359 }
1360 }
1361 if (HasDescriptorMethods(descriptor_)) {
1362 printer->Print(
1363 "result = result &&\n"
1364 " getUnknownFields().equals(other.getUnknownFields());\n");
1365 if (descriptor_->extension_range_count() > 0) {
1366 printer->Print(
1367 "result = result &&\n"
1368 " getExtensionFields().equals(other.getExtensionFields());\n");
1369 }
1370 }
1371 printer->Print(
1372 "return result;\n");
1373 printer->Outdent();
1374 printer->Print(
1375 "}\n"
1376 "\n");
1377
1378 printer->Print(
1379 "@java.lang.Override\n"
1380 "public int hashCode() {\n");
1381 printer->Indent();
1382 printer->Print(
1383 "if (memoizedHashCode != 0) {\n");
1384 printer->Indent();
1385 printer->Print(
1386 "return memoizedHashCode;\n");
1387 printer->Outdent();
1388 printer->Print(
1389 "}\n"
1390 "int hash = 41;\n");
1391
1392 if (HasDescriptorMethods(descriptor_)) {
1393 printer->Print("hash = (19 * hash) + getDescriptorForType().hashCode();\n");
1394 } else {
1395 // Include the hash of the class so that two objects with different types
1396 // but the same field values will probably have different hashes.
1397 printer->Print("hash = (19 * hash) + $classname$.class.hashCode();\n",
1398 "classname", name_resolver_->GetImmutableClassName(descriptor_));
1399 }
1400
1401 for (int i = 0; i < descriptor_->field_count(); i++) {
1402 const FieldDescriptor* field = descriptor_->field(i);
1403 const FieldGeneratorInfo* info = context_->GetFieldGeneratorInfo(field);
1404 bool check_has_bits = CheckHasBitsForEqualsAndHashCode(field);
1405 if (check_has_bits) {
1406 printer->Print(
1407 "if (has$name$()) {\n",
1408 "name", info->capitalized_name);
1409 printer->Indent();
1410 }
1411 field_generators_.get(field).GenerateHashCode(printer);
1412 if (check_has_bits) {
1413 printer->Outdent();
1414 printer->Print("}\n");
1415 }
1416 }
1417 if (HasDescriptorMethods(descriptor_)) {
1418 if (descriptor_->extension_range_count() > 0) {
1419 printer->Print(
1420 "hash = hashFields(hash, getExtensionFields());\n");
1421 }
1422 }
1423
1424 if (UseUnknownFieldSet(descriptor_)) {
1425 printer->Print(
1426 "hash = (29 * hash) + getUnknownFields().hashCode();\n");
1427 } else {
1428 printer->Print(
1429 "hash = (29 * hash) + unknownFields.hashCode();\n");
1430 }
1431 printer->Print(
1432 "memoizedHashCode = hash;\n"
1433 "return hash;\n");
1434 printer->Outdent();
1435 printer->Print(
1436 "}\n"
1437 "\n");
1438 }
1439
1440 // ===================================================================
1441
1442 void ImmutableMessageGenerator::
GenerateExtensionRegistrationCode(io::Printer * printer)1443 GenerateExtensionRegistrationCode(io::Printer* printer) {
1444 for (int i = 0; i < descriptor_->extension_count(); i++) {
1445 ImmutableExtensionGenerator(descriptor_->extension(i), context_)
1446 .GenerateRegistrationCode(printer);
1447 }
1448
1449 for (int i = 0; i < descriptor_->nested_type_count(); i++) {
1450 ImmutableMessageGenerator(descriptor_->nested_type(i), context_)
1451 .GenerateExtensionRegistrationCode(printer);
1452 }
1453 }
1454
1455 // ===================================================================
1456 void ImmutableMessageGenerator::
GenerateParsingConstructor(io::Printer * printer)1457 GenerateParsingConstructor(io::Printer* printer) {
1458 scoped_array<const FieldDescriptor*> sorted_fields(
1459 SortFieldsByNumber(descriptor_));
1460
1461 printer->Print(
1462 "private $classname$(\n"
1463 " com.google.protobuf.CodedInputStream input,\n"
1464 " com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n"
1465 " throws com.google.protobuf.InvalidProtocolBufferException {\n",
1466 "classname", descriptor_->name());
1467 printer->Indent();
1468
1469 // Initialize all fields to default.
1470 printer->Print(
1471 "initFields();\n");
1472
1473 // Use builder bits to track mutable repeated fields.
1474 int totalBuilderBits = 0;
1475 for (int i = 0; i < descriptor_->field_count(); i++) {
1476 const ImmutableFieldGenerator& field =
1477 field_generators_.get(descriptor_->field(i));
1478 totalBuilderBits += field.GetNumBitsForBuilder();
1479 }
1480 int totalBuilderInts = (totalBuilderBits + 31) / 32;
1481 for (int i = 0; i < totalBuilderInts; i++) {
1482 printer->Print("int mutable_$bit_field_name$ = 0;\n",
1483 "bit_field_name", GetBitFieldName(i));
1484 }
1485
1486 if (UseUnknownFieldSet(descriptor_)) {
1487 printer->Print(
1488 "com.google.protobuf.UnknownFieldSet.Builder unknownFields =\n"
1489 " com.google.protobuf.UnknownFieldSet.newBuilder();\n");
1490 } else {
1491 printer->Print(
1492 "com.google.protobuf.ByteString.Output unknownFieldsOutput =\n"
1493 " com.google.protobuf.ByteString.newOutput();\n"
1494 "com.google.protobuf.CodedOutputStream unknownFieldsCodedOutput =\n"
1495 " com.google.protobuf.CodedOutputStream.newInstance(\n"
1496 " unknownFieldsOutput);\n");
1497 }
1498
1499 printer->Print(
1500 "try {\n");
1501 printer->Indent();
1502
1503 printer->Print(
1504 "boolean done = false;\n"
1505 "while (!done) {\n");
1506 printer->Indent();
1507
1508 printer->Print(
1509 "int tag = input.readTag();\n"
1510 "switch (tag) {\n");
1511 printer->Indent();
1512
1513 printer->Print(
1514 "case 0:\n" // zero signals EOF / limit reached
1515 " done = true;\n"
1516 " break;\n"
1517 "default: {\n"
1518 " if (!parseUnknownField(input,$unknown_fields$\n"
1519 " extensionRegistry, tag)) {\n"
1520 " done = true;\n" // it's an endgroup tag
1521 " }\n"
1522 " break;\n"
1523 "}\n",
1524 "unknown_fields", UseUnknownFieldSet(descriptor_)
1525 ? " unknownFields," : " unknownFieldsCodedOutput,");
1526
1527 for (int i = 0; i < descriptor_->field_count(); i++) {
1528 const FieldDescriptor* field = sorted_fields[i];
1529 uint32 tag = WireFormatLite::MakeTag(field->number(),
1530 WireFormat::WireTypeForFieldType(field->type()));
1531
1532 printer->Print(
1533 "case $tag$: {\n",
1534 "tag", SimpleItoa(tag));
1535 printer->Indent();
1536
1537 field_generators_.get(field).GenerateParsingCode(printer);
1538
1539 printer->Outdent();
1540 printer->Print(
1541 " break;\n"
1542 "}\n");
1543
1544 if (field->is_packable()) {
1545 // To make packed = true wire compatible, we generate parsing code from a
1546 // packed version of this field regardless of field->options().packed().
1547 uint32 packed_tag = WireFormatLite::MakeTag(field->number(),
1548 WireFormatLite::WIRETYPE_LENGTH_DELIMITED);
1549 printer->Print(
1550 "case $tag$: {\n",
1551 "tag", SimpleItoa(packed_tag));
1552 printer->Indent();
1553
1554 field_generators_.get(field).GenerateParsingCodeFromPacked(printer);
1555
1556 printer->Outdent();
1557 printer->Print(
1558 " break;\n"
1559 "}\n");
1560 }
1561 }
1562
1563 printer->Outdent();
1564 printer->Outdent();
1565 printer->Print(
1566 " }\n" // switch (tag)
1567 "}\n"); // while (!done)
1568
1569 printer->Outdent();
1570 printer->Print(
1571 "} catch (com.google.protobuf.InvalidProtocolBufferException e) {\n"
1572 " throw e.setUnfinishedMessage(this);\n"
1573 "} catch (java.io.IOException e) {\n"
1574 " throw new com.google.protobuf.InvalidProtocolBufferException(\n"
1575 " e.getMessage()).setUnfinishedMessage(this);\n"
1576 "} finally {\n");
1577 printer->Indent();
1578
1579 // Make repeated field list immutable.
1580 for (int i = 0; i < descriptor_->field_count(); i++) {
1581 const FieldDescriptor* field = sorted_fields[i];
1582 field_generators_.get(field).GenerateParsingDoneCode(printer);
1583 }
1584
1585 // Make unknown fields immutable.
1586 if (UseUnknownFieldSet(descriptor_)) {
1587 printer->Print(
1588 "this.unknownFields = unknownFields.build();\n");
1589 } else {
1590 printer->Print(
1591 "try {\n"
1592 " unknownFieldsCodedOutput.flush();\n"
1593 "} catch (java.io.IOException e) {\n"
1594 "// Should not happen\n"
1595 "} finally {\n"
1596 " unknownFields = unknownFieldsOutput.toByteString();\n"
1597 "}\n");
1598 }
1599
1600 // Make extensions immutable.
1601 printer->Print(
1602 "makeExtensionsImmutable();\n");
1603
1604 printer->Outdent();
1605 printer->Outdent();
1606 printer->Print(
1607 " }\n" // finally
1608 "}\n");
1609 }
1610
1611 // ===================================================================
GenerateParser(io::Printer * printer)1612 void ImmutableMessageGenerator::GenerateParser(io::Printer* printer) {
1613 printer->Print(
1614 "public static com.google.protobuf.Parser<$classname$> PARSER =\n"
1615 " new com.google.protobuf.AbstractParser<$classname$>() {\n",
1616 "classname", descriptor_->name());
1617 printer->Indent();
1618 printer->Print(
1619 "public $classname$ parsePartialFrom(\n"
1620 " com.google.protobuf.CodedInputStream input,\n"
1621 " com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n"
1622 " throws com.google.protobuf.InvalidProtocolBufferException {\n",
1623 "classname", descriptor_->name());
1624 if (HasGeneratedMethods(descriptor_)) {
1625 printer->Print(
1626 " return new $classname$(input, extensionRegistry);\n",
1627 "classname", descriptor_->name());
1628 } else {
1629 // When parsing constructor isn't generated, use builder to parse messages.
1630 // Note, will fallback to use reflection based mergeFieldFrom() in
1631 // AbstractMessage.Builder.
1632 printer->Indent();
1633 printer->Print(
1634 "Builder builder = newBuilder();\n"
1635 "try {\n"
1636 " builder.mergeFrom(input, extensionRegistry);\n"
1637 "} catch (com.google.protobuf.InvalidProtocolBufferException e) {\n"
1638 " throw e.setUnfinishedMessage(builder.buildPartial());\n"
1639 "} catch (java.io.IOException e) {\n"
1640 " throw new com.google.protobuf.InvalidProtocolBufferException(\n"
1641 " e.getMessage()).setUnfinishedMessage(builder.buildPartial());\n"
1642 "}\n"
1643 "return builder.buildPartial();\n");
1644 printer->Outdent();
1645 }
1646 printer->Print(
1647 "}\n");
1648 printer->Outdent();
1649 printer->Print(
1650 "};\n"
1651 "\n");
1652
1653 printer->Print(
1654 "@java.lang.Override\n"
1655 "public com.google.protobuf.Parser<$classname$> getParserForType() {\n"
1656 " return PARSER;\n"
1657 "}\n"
1658 "\n",
1659 "classname", descriptor_->name());
1660 }
1661
1662
1663 } // namespace java
1664 } // namespace compiler
1665 } // namespace protobuf
1666 } // namespace google
1667