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 #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.h>
49 #include <google/protobuf/compiler/java/java_extension.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 // ===================================================================
85
MessageGenerator(const Descriptor * descriptor)86 MessageGenerator::MessageGenerator(const Descriptor* descriptor)
87 : descriptor_(descriptor) {}
88
~MessageGenerator()89 MessageGenerator::~MessageGenerator() {}
90
91 // ===================================================================
ImmutableMessageGenerator(const Descriptor * descriptor,Context * context)92 ImmutableMessageGenerator::ImmutableMessageGenerator(
93 const Descriptor* descriptor, Context* context)
94 : MessageGenerator(descriptor), context_(context),
95 name_resolver_(context->GetNameResolver()),
96 field_generators_(descriptor, context_) {
97 GOOGLE_CHECK(HasDescriptorMethods(descriptor->file(), context->EnforceLite()))
98 << "Generator factory error: A non-lite message generator is used to "
99 "generate lite messages.";
100 }
101
~ImmutableMessageGenerator()102 ImmutableMessageGenerator::~ImmutableMessageGenerator() {}
103
GenerateStaticVariables(io::Printer * printer,int * bytecode_estimate)104 void ImmutableMessageGenerator::GenerateStaticVariables(
105 io::Printer* printer, int* bytecode_estimate) {
106 // Because descriptor.proto (com.google.protobuf.DescriptorProtos) is
107 // used in the construction of descriptors, we have a tricky bootstrapping
108 // problem. To help control static initialization order, we make sure all
109 // descriptors and other static data that depends on them are members of
110 // the outermost class in the file. This way, they will be initialized in
111 // a deterministic order.
112
113 map<string, string> vars;
114 vars["identifier"] = UniqueFileScopeIdentifier(descriptor_);
115 vars["index"] = SimpleItoa(descriptor_->index());
116 vars["classname"] = name_resolver_->GetImmutableClassName(descriptor_);
117 if (descriptor_->containing_type() != NULL) {
118 vars["parent"] = UniqueFileScopeIdentifier(
119 descriptor_->containing_type());
120 }
121 if (MultipleJavaFiles(descriptor_->file(), /* immutable = */ true)) {
122 // We can only make these package-private since the classes that use them
123 // are in separate files.
124 vars["private"] = "";
125 } else {
126 vars["private"] = "private ";
127 }
128 if (*bytecode_estimate <= kMaxStaticSize) {
129 vars["final"] = "final ";
130 } else {
131 vars["final"] = "";
132 }
133
134 // The descriptor for this type.
135 printer->Print(vars,
136 // TODO(teboring): final needs to be added back. The way to fix it is to
137 // generate methods that can construct the types, and then still declare the
138 // types, and then init them in clinit with the new method calls.
139 "$private$static $final$com.google.protobuf.Descriptors.Descriptor\n"
140 " internal_$identifier$_descriptor;\n");
141 *bytecode_estimate += 30;
142
143 // And the FieldAccessorTable.
144 GenerateFieldAccessorTable(printer, bytecode_estimate);
145
146 // Generate static members for all nested types.
147 for (int i = 0; i < descriptor_->nested_type_count(); i++) {
148 // TODO(kenton): Reuse MessageGenerator objects?
149 ImmutableMessageGenerator(descriptor_->nested_type(i), context_)
150 .GenerateStaticVariables(printer, bytecode_estimate);
151 }
152 }
153
GenerateStaticVariableInitializers(io::Printer * printer)154 int ImmutableMessageGenerator::GenerateStaticVariableInitializers(
155 io::Printer* printer) {
156 int bytecode_estimate = 0;
157 map<string, string> vars;
158 vars["identifier"] = UniqueFileScopeIdentifier(descriptor_);
159 vars["index"] = SimpleItoa(descriptor_->index());
160 vars["classname"] = name_resolver_->GetImmutableClassName(descriptor_);
161 if (descriptor_->containing_type() != NULL) {
162 vars["parent"] = UniqueFileScopeIdentifier(
163 descriptor_->containing_type());
164 }
165
166 // The descriptor for this type.
167 if (descriptor_->containing_type() == NULL) {
168 printer->Print(vars,
169 "internal_$identifier$_descriptor =\n"
170 " getDescriptor().getMessageTypes().get($index$);\n");
171 bytecode_estimate += 30;
172 } else {
173 printer->Print(vars,
174 "internal_$identifier$_descriptor =\n"
175 " internal_$parent$_descriptor.getNestedTypes().get($index$);\n");
176 bytecode_estimate += 30;
177 }
178
179 // And the FieldAccessorTable.
180 bytecode_estimate += GenerateFieldAccessorTableInitializer(printer);
181
182 // Generate static member initializers for all nested types.
183 for (int i = 0; i < descriptor_->nested_type_count(); i++) {
184 // TODO(kenton): Reuse MessageGenerator objects?
185 bytecode_estimate +=
186 ImmutableMessageGenerator(descriptor_->nested_type(i), context_)
187 .GenerateStaticVariableInitializers(printer);
188 }
189 return bytecode_estimate;
190 }
191
192 void ImmutableMessageGenerator::
GenerateFieldAccessorTable(io::Printer * printer,int * bytecode_estimate)193 GenerateFieldAccessorTable(io::Printer* printer, int* bytecode_estimate) {
194 map<string, string> vars;
195 vars["identifier"] = UniqueFileScopeIdentifier(descriptor_);
196 if (MultipleJavaFiles(descriptor_->file(), /* immutable = */ true)) {
197 // We can only make these package-private since the classes that use them
198 // are in separate files.
199 vars["private"] = "";
200 } else {
201 vars["private"] = "private ";
202 }
203 if (*bytecode_estimate <= kMaxStaticSize) {
204 vars["final"] = "final ";
205 } else {
206 vars["final"] = "";
207 }
208 vars["ver"] = GeneratedCodeVersionSuffix();
209 printer->Print(vars,
210 "$private$static $final$\n"
211 " com.google.protobuf.GeneratedMessage$ver$.FieldAccessorTable\n"
212 " internal_$identifier$_fieldAccessorTable;\n");
213
214 // 6 bytes per field and oneof
215 *bytecode_estimate += 10 + 6 * descriptor_->field_count()
216 + 6 * descriptor_->oneof_decl_count();
217 }
218
219 int ImmutableMessageGenerator::
GenerateFieldAccessorTableInitializer(io::Printer * printer)220 GenerateFieldAccessorTableInitializer(io::Printer* printer) {
221 int bytecode_estimate = 10;
222 printer->Print(
223 "internal_$identifier$_fieldAccessorTable = new\n"
224 " com.google.protobuf.GeneratedMessage$ver$.FieldAccessorTable(\n"
225 " internal_$identifier$_descriptor,\n"
226 " new java.lang.String[] { ",
227 "identifier", UniqueFileScopeIdentifier(descriptor_),
228 "ver", GeneratedCodeVersionSuffix());
229 for (int i = 0; i < descriptor_->field_count(); i++) {
230 const FieldDescriptor* field = descriptor_->field(i);
231 const FieldGeneratorInfo* info = context_->GetFieldGeneratorInfo(field);
232 bytecode_estimate += 6;
233 printer->Print(
234 "\"$field_name$\", ",
235 "field_name", info->capitalized_name);
236 }
237 for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
238 const OneofDescriptor* oneof = descriptor_->oneof_decl(i);
239 const OneofGeneratorInfo* info = context_->GetOneofGeneratorInfo(oneof);
240 bytecode_estimate += 6;
241 printer->Print(
242 "\"$oneof_name$\", ",
243 "oneof_name", info->capitalized_name);
244 }
245 printer->Print("});\n");
246 return bytecode_estimate;
247 }
248
249 // ===================================================================
250
GenerateInterface(io::Printer * printer)251 void ImmutableMessageGenerator::GenerateInterface(io::Printer* printer) {
252 MaybePrintGeneratedAnnotation(context_, printer, descriptor_,
253 /* immutable = */ true, "OrBuilder");
254 if (descriptor_->extension_range_count() > 0) {
255 printer->Print(
256 "public interface $classname$OrBuilder$idend$ extends\n"
257 " $extra_interfaces$\n"
258 " com.google.protobuf.GeneratedMessage$ver$.\n"
259 " ExtendableMessageOrBuilder<$classname$> {\n",
260 "extra_interfaces", ExtraMessageOrBuilderInterfaces(descriptor_),
261 "classname", descriptor_->name(),
262 "idend", "", "ver", GeneratedCodeVersionSuffix());
263 } else {
264 printer->Print(
265 "public interface $classname$OrBuilder$idend$ extends\n"
266 " $extra_interfaces$\n"
267 " com.google.protobuf.MessageOrBuilder {\n",
268 "extra_interfaces", ExtraMessageOrBuilderInterfaces(descriptor_),
269 "classname", descriptor_->name(),
270 "idend", "");
271 }
272 printer->Annotate("classname", "idend", descriptor_);
273
274 printer->Indent();
275 for (int i = 0; i < descriptor_->field_count(); i++) {
276 printer->Print("\n");
277 field_generators_.get(descriptor_->field(i))
278 .GenerateInterfaceMembers(printer);
279 }
280 for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
281 printer->Print(
282 "\n"
283 "public $classname$.$oneof_capitalized_name$Case "
284 "get$oneof_capitalized_name$Case();\n",
285 "oneof_capitalized_name",
286 context_->GetOneofGeneratorInfo(
287 descriptor_->oneof_decl(i))->capitalized_name,
288 "classname",
289 context_->GetNameResolver()->GetImmutableClassName(
290 descriptor_));
291 }
292 printer->Outdent();
293
294 printer->Print("}\n");
295 }
296
297 // ===================================================================
298
Generate(io::Printer * printer)299 void ImmutableMessageGenerator::Generate(io::Printer* printer) {
300 bool is_own_file = IsOwnFile(descriptor_, /* immutable = */ true);
301
302 map<string, string> variables;
303 variables["static"] = is_own_file ? " " : " static ";
304 variables["classname"] = descriptor_->name();
305 variables["extra_interfaces"] = ExtraMessageInterfaces(descriptor_);
306 variables["ver"] = GeneratedCodeVersionSuffix();
307
308 WriteMessageDocComment(printer, descriptor_);
309 MaybePrintGeneratedAnnotation(context_, printer, descriptor_,
310 /* immutable = */ true);
311
312 // The builder_type stores the super type name of the nested Builder class.
313 string builder_type;
314 if (descriptor_->extension_range_count() > 0) {
315 printer->Print(variables,
316 "public $static$final class $classname$ extends\n");
317 printer->Annotate("classname", descriptor_);
318 printer->Print(
319 variables,
320 " com.google.protobuf.GeneratedMessage$ver$.ExtendableMessage<\n"
321 " $classname$> implements\n"
322 " $extra_interfaces$\n"
323 " $classname$OrBuilder {\n");
324 builder_type = strings::Substitute(
325 "com.google.protobuf.GeneratedMessage$1.ExtendableBuilder<$0, ?>",
326 name_resolver_->GetImmutableClassName(descriptor_),
327 GeneratedCodeVersionSuffix());
328 } else {
329 printer->Print(variables,
330 "public $static$final class $classname$ extends\n");
331 printer->Annotate("classname", descriptor_);
332 printer->Print(variables,
333 " com.google.protobuf.GeneratedMessage$ver$ implements\n"
334 " $extra_interfaces$\n"
335 " $classname$OrBuilder {\n");
336 builder_type = strings::Substitute(
337 "com.google.protobuf.GeneratedMessage$0.Builder<?>",
338 GeneratedCodeVersionSuffix());
339 }
340 printer->Indent();
341 // Using builder_type, instead of Builder, prevents the Builder class from
342 // being loaded into PermGen space when the default instance is created.
343 // This optimizes the PermGen space usage for clients that do not modify
344 // messages.
345 printer->Print(
346 "// Use $classname$.newBuilder() to construct.\n"
347 "private $classname$($buildertype$ builder) {\n"
348 " super(builder);\n"
349 "}\n",
350 "classname", descriptor_->name(),
351 "buildertype", builder_type);
352 printer->Print(
353 "private $classname$() {\n",
354 "classname", descriptor_->name());
355 printer->Indent();
356 GenerateInitializers(printer);
357 printer->Outdent();
358 printer->Print(
359 "}\n"
360 "\n");
361
362 printer->Print(
363 "@java.lang.Override\n"
364 "public final com.google.protobuf.UnknownFieldSet\n"
365 "getUnknownFields() {\n");
366 if (PreserveUnknownFields(descriptor_)) {
367 printer->Print(
368 " return this.unknownFields;\n");
369 } else {
370 printer->Print(
371 " return com.google.protobuf.UnknownFieldSet.getDefaultInstance();\n");
372 }
373 printer->Print(
374 "}\n");
375
376 if (context_->HasGeneratedMethods(descriptor_)) {
377 GenerateParsingConstructor(printer);
378 }
379
380 GenerateDescriptorMethods(printer);
381
382 // Nested types
383 for (int i = 0; i < descriptor_->enum_type_count(); i++) {
384 EnumGenerator(descriptor_->enum_type(i), true, context_)
385 .Generate(printer);
386 }
387
388 for (int i = 0; i < descriptor_->nested_type_count(); i++) {
389 // Don't generate Java classes for map entry messages.
390 if (IsMapEntry(descriptor_->nested_type(i))) continue;
391 ImmutableMessageGenerator messageGenerator(
392 descriptor_->nested_type(i), context_);
393 messageGenerator.GenerateInterface(printer);
394 messageGenerator.Generate(printer);
395 }
396
397 if (GenerateHasBits(descriptor_)) {
398 // Integers for bit fields.
399 int totalBits = 0;
400 for (int i = 0; i < descriptor_->field_count(); i++) {
401 totalBits += field_generators_.get(descriptor_->field(i))
402 .GetNumBitsForMessage();
403 }
404 int totalInts = (totalBits + 31) / 32;
405 for (int i = 0; i < totalInts; i++) {
406 printer->Print("private int $bit_field_name$;\n",
407 "bit_field_name", GetBitFieldName(i));
408 }
409 }
410
411 // oneof
412 map<string, string> vars;
413 for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
414 vars["oneof_name"] = context_->GetOneofGeneratorInfo(
415 descriptor_->oneof_decl(i))->name;
416 vars["oneof_capitalized_name"] = context_->GetOneofGeneratorInfo(
417 descriptor_->oneof_decl(i))->capitalized_name;
418 vars["oneof_index"] = SimpleItoa(descriptor_->oneof_decl(i)->index());
419 // oneofCase_ and oneof_
420 printer->Print(vars,
421 "private int $oneof_name$Case_ = 0;\n"
422 "private java.lang.Object $oneof_name$_;\n");
423 // OneofCase enum
424 printer->Print(vars,
425 "public enum $oneof_capitalized_name$Case\n"
426 " implements com.google.protobuf.Internal.EnumLite {\n");
427 printer->Indent();
428 for (int j = 0; j < descriptor_->oneof_decl(i)->field_count(); j++) {
429 const FieldDescriptor* field = descriptor_->oneof_decl(i)->field(j);
430 printer->Print(
431 "$field_name$($field_number$),\n",
432 "field_name",
433 ToUpper(field->name()),
434 "field_number",
435 SimpleItoa(field->number()));
436 }
437 printer->Print(
438 "$cap_oneof_name$_NOT_SET(0);\n",
439 "cap_oneof_name",
440 ToUpper(vars["oneof_name"]));
441 printer->Print(vars,
442 "private final int value;\n"
443 "private $oneof_capitalized_name$Case(int value) {\n"
444 " this.value = value;\n"
445 "}\n");
446 printer->Print(vars,
447 "/**\n"
448 " * @deprecated Use {@link #forNumber(int)} instead.\n"
449 " */\n"
450 "@java.lang.Deprecated\n"
451 "public static $oneof_capitalized_name$Case valueOf(int value) {\n"
452 " return forNumber(value);\n"
453 "}\n"
454 "\n"
455 "public static $oneof_capitalized_name$Case forNumber(int value) {\n"
456 " switch (value) {\n");
457 for (int j = 0; j < descriptor_->oneof_decl(i)->field_count(); j++) {
458 const FieldDescriptor* field = descriptor_->oneof_decl(i)->field(j);
459 printer->Print(
460 " case $field_number$: return $field_name$;\n",
461 "field_number",
462 SimpleItoa(field->number()),
463 "field_name",
464 ToUpper(field->name()));
465 }
466 printer->Print(
467 " case 0: return $cap_oneof_name$_NOT_SET;\n"
468 " default: return null;\n"
469 " }\n"
470 "}\n"
471 "public int getNumber() {\n"
472 " return this.value;\n"
473 "}\n",
474 "cap_oneof_name", ToUpper(vars["oneof_name"]));
475 printer->Outdent();
476 printer->Print("};\n\n");
477 // oneofCase()
478 printer->Print(vars,
479 "public $oneof_capitalized_name$Case\n"
480 "get$oneof_capitalized_name$Case() {\n"
481 " return $oneof_capitalized_name$Case.forNumber(\n"
482 " $oneof_name$Case_);\n"
483 "}\n"
484 "\n");
485 }
486
487 if (IsAnyMessage(descriptor_)) {
488 GenerateAnyMethods(printer);
489 }
490
491 // Fields
492 for (int i = 0; i < descriptor_->field_count(); i++) {
493 printer->Print("public static final int $constant_name$ = $number$;\n",
494 "constant_name", FieldConstantName(descriptor_->field(i)),
495 "number", SimpleItoa(descriptor_->field(i)->number()));
496 field_generators_.get(descriptor_->field(i)).GenerateMembers(printer);
497 printer->Print("\n");
498 }
499
500 if (context_->HasGeneratedMethods(descriptor_)) {
501 GenerateIsInitialized(printer);
502 GenerateMessageSerializationMethods(printer);
503 GenerateEqualsAndHashCode(printer);
504 }
505
506
507 GenerateParseFromMethods(printer);
508 GenerateBuilder(printer);
509
510 printer->Print(
511 "\n"
512 "// @@protoc_insertion_point(class_scope:$full_name$)\n",
513 "full_name", descriptor_->full_name());
514
515
516 // Carefully initialize the default instance in such a way that it doesn't
517 // conflict with other initialization.
518 printer->Print(
519 "private static final $classname$ DEFAULT_INSTANCE;\n",
520 "classname", name_resolver_->GetImmutableClassName(descriptor_));
521 printer->Print(
522 "static {\n"
523 " DEFAULT_INSTANCE = new $classname$();\n"
524 "}\n"
525 "\n",
526 "classname", name_resolver_->GetImmutableClassName(descriptor_));
527
528 printer->Print(
529 "public static $classname$ getDefaultInstance() {\n"
530 " return DEFAULT_INSTANCE;\n"
531 "}\n"
532 "\n",
533 "classname", name_resolver_->GetImmutableClassName(descriptor_));
534
535 GenerateParser(printer);
536
537 printer->Print(
538 "public $classname$ getDefaultInstanceForType() {\n"
539 " return DEFAULT_INSTANCE;\n"
540 "}\n"
541 "\n",
542 "classname", name_resolver_->GetImmutableClassName(descriptor_));
543
544 // Extensions must be declared after the DEFAULT_INSTANCE is initialized
545 // because the DEFAULT_INSTANCE is used by the extension to lazily retrieve
546 // the outer class's FileDescriptor.
547 for (int i = 0; i < descriptor_->extension_count(); i++) {
548 ImmutableExtensionGenerator(descriptor_->extension(i), context_)
549 .Generate(printer);
550 }
551
552 printer->Outdent();
553 printer->Print("}\n\n");
554 }
555
556
557 // ===================================================================
558
559 void ImmutableMessageGenerator::
GenerateMessageSerializationMethods(io::Printer * printer)560 GenerateMessageSerializationMethods(io::Printer* printer) {
561 google::protobuf::scoped_array<const FieldDescriptor * > sorted_fields(
562 SortFieldsByNumber(descriptor_));
563
564 vector<const Descriptor::ExtensionRange*> sorted_extensions;
565 for (int i = 0; i < descriptor_->extension_range_count(); ++i) {
566 sorted_extensions.push_back(descriptor_->extension_range(i));
567 }
568 std::sort(sorted_extensions.begin(), sorted_extensions.end(),
569 ExtensionRangeOrdering());
570
571 printer->Print(
572 "public void writeTo(com.google.protobuf.CodedOutputStream output)\n"
573 " throws java.io.IOException {\n");
574 printer->Indent();
575 if (HasPackedFields(descriptor_)) {
576 // writeTo(CodedOutputStream output) might be invoked without
577 // getSerializedSize() ever being called, but we need the memoized
578 // sizes in case this message has packed fields. Rather than emit checks for
579 // each packed field, just call getSerializedSize() up front.
580 // In most cases, getSerializedSize() will have already been called anyway
581 // by one of the wrapper writeTo() methods, making this call cheap.
582 printer->Print(
583 "getSerializedSize();\n");
584 }
585
586 if (descriptor_->extension_range_count() > 0) {
587 if (descriptor_->options().message_set_wire_format()) {
588 printer->Print(
589 "com.google.protobuf.GeneratedMessage$ver$\n"
590 " .ExtendableMessage<$classname$>.ExtensionWriter\n"
591 " extensionWriter = newMessageSetExtensionWriter();\n",
592 "classname", name_resolver_->GetImmutableClassName(descriptor_),
593 "ver", GeneratedCodeVersionSuffix());
594 } else {
595 printer->Print(
596 "com.google.protobuf.GeneratedMessage$ver$\n"
597 " .ExtendableMessage<$classname$>.ExtensionWriter\n"
598 " extensionWriter = newExtensionWriter();\n",
599 "classname", name_resolver_->GetImmutableClassName(descriptor_),
600 "ver", GeneratedCodeVersionSuffix());
601 }
602 }
603
604 // Merge the fields and the extension ranges, both sorted by field number.
605 for (int i = 0, j = 0;
606 i < descriptor_->field_count() || j < sorted_extensions.size();
607 ) {
608 if (i == descriptor_->field_count()) {
609 GenerateSerializeOneExtensionRange(printer, sorted_extensions[j++]);
610 } else if (j == sorted_extensions.size()) {
611 GenerateSerializeOneField(printer, sorted_fields[i++]);
612 } else if (sorted_fields[i]->number() < sorted_extensions[j]->start) {
613 GenerateSerializeOneField(printer, sorted_fields[i++]);
614 } else {
615 GenerateSerializeOneExtensionRange(printer, sorted_extensions[j++]);
616 }
617 }
618
619 if (PreserveUnknownFields(descriptor_)) {
620 if (descriptor_->options().message_set_wire_format()) {
621 printer->Print(
622 "unknownFields.writeAsMessageSetTo(output);\n");
623 } else {
624 printer->Print(
625 "unknownFields.writeTo(output);\n");
626 }
627 }
628
629 printer->Outdent();
630 printer->Print(
631 "}\n"
632 "\n"
633 "public int getSerializedSize() {\n"
634 " int size = memoizedSize;\n"
635 " if (size != -1) return size;\n"
636 "\n"
637 " size = 0;\n");
638 printer->Indent();
639
640 for (int i = 0; i < descriptor_->field_count(); i++) {
641 field_generators_.get(sorted_fields[i]).GenerateSerializedSizeCode(printer);
642 }
643
644 if (descriptor_->extension_range_count() > 0) {
645 if (descriptor_->options().message_set_wire_format()) {
646 printer->Print(
647 "size += extensionsSerializedSizeAsMessageSet();\n");
648 } else {
649 printer->Print(
650 "size += extensionsSerializedSize();\n");
651 }
652 }
653
654 if (PreserveUnknownFields(descriptor_)) {
655 if (descriptor_->options().message_set_wire_format()) {
656 printer->Print(
657 "size += unknownFields.getSerializedSizeAsMessageSet();\n");
658 } else {
659 printer->Print(
660 "size += unknownFields.getSerializedSize();\n");
661 }
662 }
663
664 printer->Outdent();
665 printer->Print(
666 " memoizedSize = size;\n"
667 " return size;\n"
668 "}\n"
669 "\n");
670
671 printer->Print(
672 "private static final long serialVersionUID = 0L;\n");
673 }
674
675 void ImmutableMessageGenerator::
GenerateParseFromMethods(io::Printer * printer)676 GenerateParseFromMethods(io::Printer* printer) {
677 // Note: These are separate from GenerateMessageSerializationMethods()
678 // because they need to be generated even for messages that are optimized
679 // for code size.
680 printer->Print(
681 "public static $classname$ parseFrom(\n"
682 " com.google.protobuf.ByteString data)\n"
683 " throws com.google.protobuf.InvalidProtocolBufferException {\n"
684 " return PARSER.parseFrom(data);\n"
685 "}\n"
686 "public static $classname$ parseFrom(\n"
687 " com.google.protobuf.ByteString 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(byte[] data)\n"
693 " throws com.google.protobuf.InvalidProtocolBufferException {\n"
694 " return PARSER.parseFrom(data);\n"
695 "}\n"
696 "public static $classname$ parseFrom(\n"
697 " byte[] data,\n"
698 " com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n"
699 " throws com.google.protobuf.InvalidProtocolBufferException {\n"
700 " return PARSER.parseFrom(data, extensionRegistry);\n"
701 "}\n"
702 "public static $classname$ parseFrom(java.io.InputStream input)\n"
703 " throws java.io.IOException {\n"
704 " return com.google.protobuf.GeneratedMessage$ver$\n"
705 " .parseWithIOException(PARSER, input);\n"
706 "}\n"
707 "public static $classname$ parseFrom(\n"
708 " java.io.InputStream input,\n"
709 " com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n"
710 " throws java.io.IOException {\n"
711 " return com.google.protobuf.GeneratedMessage$ver$\n"
712 " .parseWithIOException(PARSER, input, extensionRegistry);\n"
713 "}\n"
714 "public static $classname$ parseDelimitedFrom(java.io.InputStream input)\n"
715 " throws java.io.IOException {\n"
716 " return com.google.protobuf.GeneratedMessage$ver$\n"
717 " .parseDelimitedWithIOException(PARSER, input);\n"
718 "}\n"
719 "public static $classname$ parseDelimitedFrom(\n"
720 " java.io.InputStream input,\n"
721 " com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n"
722 " throws java.io.IOException {\n"
723 " return com.google.protobuf.GeneratedMessage$ver$\n"
724 " .parseDelimitedWithIOException(PARSER, input, extensionRegistry);\n"
725 "}\n"
726 "public static $classname$ parseFrom(\n"
727 " com.google.protobuf.CodedInputStream input)\n"
728 " throws java.io.IOException {\n"
729 " return com.google.protobuf.GeneratedMessage$ver$\n"
730 " .parseWithIOException(PARSER, input);\n"
731 "}\n"
732 "public static $classname$ parseFrom(\n"
733 " com.google.protobuf.CodedInputStream input,\n"
734 " com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n"
735 " throws java.io.IOException {\n"
736 " return com.google.protobuf.GeneratedMessage$ver$\n"
737 " .parseWithIOException(PARSER, input, extensionRegistry);\n"
738 "}\n"
739 "\n",
740 "classname", name_resolver_->GetImmutableClassName(descriptor_),
741 "ver", GeneratedCodeVersionSuffix());
742 }
743
GenerateSerializeOneField(io::Printer * printer,const FieldDescriptor * field)744 void ImmutableMessageGenerator::GenerateSerializeOneField(
745 io::Printer* printer, const FieldDescriptor* field) {
746 field_generators_.get(field).GenerateSerializationCode(printer);
747 }
748
GenerateSerializeOneExtensionRange(io::Printer * printer,const Descriptor::ExtensionRange * range)749 void ImmutableMessageGenerator::GenerateSerializeOneExtensionRange(
750 io::Printer* printer, const Descriptor::ExtensionRange* range) {
751 printer->Print(
752 "extensionWriter.writeUntil($end$, output);\n",
753 "end", SimpleItoa(range->end));
754 }
755
756 // ===================================================================
757
GenerateBuilder(io::Printer * printer)758 void ImmutableMessageGenerator::GenerateBuilder(io::Printer* printer) {
759 // LITE_RUNTIME implements this at the GeneratedMessageLite level.
760 printer->Print(
761 "public Builder newBuilderForType() { return newBuilder(); }\n");
762
763 printer->Print(
764 "public static Builder newBuilder() {\n"
765 " return DEFAULT_INSTANCE.toBuilder();\n"
766 "}\n"
767 "public static Builder newBuilder($classname$ prototype) {\n"
768 " return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);\n"
769 "}\n"
770 "public Builder toBuilder() {\n"
771 " return this == DEFAULT_INSTANCE\n"
772 " ? new Builder() : new Builder().mergeFrom(this);\n"
773 "}\n"
774 "\n",
775 "classname", name_resolver_->GetImmutableClassName(descriptor_));
776
777 printer->Print(
778 "@java.lang.Override\n"
779 "protected Builder newBuilderForType(\n"
780 " com.google.protobuf.GeneratedMessage$ver$.BuilderParent parent) {\n"
781 " Builder builder = new Builder(parent);\n"
782 " return builder;\n"
783 "}\n",
784 "ver", GeneratedCodeVersionSuffix());
785
786 MessageBuilderGenerator builderGenerator(descriptor_, context_);
787 builderGenerator.Generate(printer);
788 }
789
790 void ImmutableMessageGenerator::
GenerateDescriptorMethods(io::Printer * printer)791 GenerateDescriptorMethods(io::Printer* printer) {
792 if (!descriptor_->options().no_standard_descriptor_accessor()) {
793 printer->Print(
794 "public static final com.google.protobuf.Descriptors.Descriptor\n"
795 " getDescriptor() {\n"
796 " return $fileclass$.internal_$identifier$_descriptor;\n"
797 "}\n"
798 "\n",
799 "fileclass", name_resolver_->GetImmutableClassName(descriptor_->file()),
800 "identifier", UniqueFileScopeIdentifier(descriptor_));
801 }
802 vector<const FieldDescriptor*> map_fields;
803 for (int i = 0; i < descriptor_->field_count(); i++) {
804 const FieldDescriptor* field = descriptor_->field(i);
805 if (GetJavaType(field) == JAVATYPE_MESSAGE &&
806 IsMapEntry(field->message_type())) {
807 map_fields.push_back(field);
808 }
809 }
810 if (!map_fields.empty()) {
811 printer->Print(
812 "@SuppressWarnings({\"rawtypes\"})\n"
813 "protected com.google.protobuf.MapField internalGetMapField(\n"
814 " int number) {\n"
815 " switch (number) {\n");
816 printer->Indent();
817 printer->Indent();
818 for (int i = 0; i < map_fields.size(); ++i) {
819 const FieldDescriptor* field = map_fields[i];
820 const FieldGeneratorInfo* info = context_->GetFieldGeneratorInfo(field);
821 printer->Print(
822 "case $number$:\n"
823 " return internalGet$capitalized_name$();\n",
824 "number", SimpleItoa(field->number()),
825 "capitalized_name", info->capitalized_name);
826 }
827 printer->Print(
828 "default:\n"
829 " throw new RuntimeException(\n"
830 " \"Invalid map field number: \" + number);\n");
831 printer->Outdent();
832 printer->Outdent();
833 printer->Print(
834 " }\n"
835 "}\n");
836 }
837 printer->Print(
838 "protected com.google.protobuf.GeneratedMessage$ver$.FieldAccessorTable\n"
839 " internalGetFieldAccessorTable() {\n"
840 " return $fileclass$.internal_$identifier$_fieldAccessorTable\n"
841 " .ensureFieldAccessorsInitialized(\n"
842 " $classname$.class, $classname$.Builder.class);\n"
843 "}\n"
844 "\n",
845 "classname", name_resolver_->GetImmutableClassName(descriptor_),
846 "fileclass", name_resolver_->GetImmutableClassName(descriptor_->file()),
847 "identifier", UniqueFileScopeIdentifier(descriptor_),
848 "ver", GeneratedCodeVersionSuffix());
849 }
850
851 // ===================================================================
852
GenerateIsInitialized(io::Printer * printer)853 void ImmutableMessageGenerator::GenerateIsInitialized(
854 io::Printer* printer) {
855 // Memoizes whether the protocol buffer is fully initialized (has all
856 // required fields). -1 means not yet computed. 0 means false and 1 means
857 // true.
858 printer->Print(
859 "private byte memoizedIsInitialized = -1;\n");
860 printer->Print(
861 "public final boolean isInitialized() {\n");
862 printer->Indent();
863
864 // Don't directly compare to -1 to avoid an Android x86 JIT bug.
865 printer->Print(
866 "byte isInitialized = memoizedIsInitialized;\n"
867 "if (isInitialized == 1) return true;\n"
868 "if (isInitialized == 0) return false;\n"
869 "\n");
870
871 // Check that all required fields in this message are set.
872 // TODO(kenton): We can optimize this when we switch to putting all the
873 // "has" fields into a single bitfield.
874 for (int i = 0; i < descriptor_->field_count(); i++) {
875 const FieldDescriptor* field = descriptor_->field(i);
876 const FieldGeneratorInfo* info = context_->GetFieldGeneratorInfo(field);
877
878 if (field->is_required()) {
879 printer->Print(
880 "if (!has$name$()) {\n"
881 " memoizedIsInitialized = 0;\n"
882 " return false;\n"
883 "}\n",
884 "name", info->capitalized_name);
885 }
886 }
887
888 // Now check that all embedded messages are initialized.
889 for (int i = 0; i < descriptor_->field_count(); i++) {
890 const FieldDescriptor* field = descriptor_->field(i);
891 const FieldGeneratorInfo* info = context_->GetFieldGeneratorInfo(field);
892 if (GetJavaType(field) == JAVATYPE_MESSAGE &&
893 HasRequiredFields(field->message_type())) {
894 switch (field->label()) {
895 case FieldDescriptor::LABEL_REQUIRED:
896 printer->Print(
897 "if (!get$name$().isInitialized()) {\n"
898 " memoizedIsInitialized = 0;\n"
899 " return false;\n"
900 "}\n",
901 "type", name_resolver_->GetImmutableClassName(
902 field->message_type()),
903 "name", info->capitalized_name);
904 break;
905 case FieldDescriptor::LABEL_OPTIONAL:
906 if (!SupportFieldPresence(descriptor_->file()) &&
907 field->containing_oneof() != NULL) {
908 const OneofDescriptor* oneof = field->containing_oneof();
909 const OneofGeneratorInfo* oneof_info =
910 context_->GetOneofGeneratorInfo(oneof);
911 printer->Print(
912 "if ($oneof_name$Case_ == $field_number$) {\n",
913 "oneof_name", oneof_info->name,
914 "field_number", SimpleItoa(field->number()));
915 } else {
916 printer->Print(
917 "if (has$name$()) {\n",
918 "name", info->capitalized_name);
919 }
920 printer->Print(
921 " if (!get$name$().isInitialized()) {\n"
922 " memoizedIsInitialized = 0;\n"
923 " return false;\n"
924 " }\n"
925 "}\n",
926 "name", info->capitalized_name);
927 break;
928 case FieldDescriptor::LABEL_REPEATED:
929 if (IsMapEntry(field->message_type())) {
930 printer->Print(
931 "for ($type$ item : get$name$().values()) {\n"
932 " if (!item.isInitialized()) {\n"
933 " memoizedIsInitialized = 0;\n"
934 " return false;\n"
935 " }\n"
936 "}\n",
937 "type", MapValueImmutableClassdName(field->message_type(),
938 name_resolver_),
939 "name", info->capitalized_name);
940 } else {
941 printer->Print(
942 "for (int i = 0; i < get$name$Count(); i++) {\n"
943 " if (!get$name$(i).isInitialized()) {\n"
944 " memoizedIsInitialized = 0;\n"
945 " return false;\n"
946 " }\n"
947 "}\n",
948 "type", name_resolver_->GetImmutableClassName(
949 field->message_type()),
950 "name", info->capitalized_name);
951 }
952 break;
953 }
954 }
955 }
956
957 if (descriptor_->extension_range_count() > 0) {
958 printer->Print(
959 "if (!extensionsAreInitialized()) {\n"
960 " memoizedIsInitialized = 0;\n"
961 " return false;\n"
962 "}\n");
963 }
964
965 printer->Outdent();
966
967 printer->Print(
968 " memoizedIsInitialized = 1;\n");
969
970 printer->Print(
971 " return true;\n"
972 "}\n"
973 "\n");
974 }
975
976 // ===================================================================
977
978 namespace {
CheckHasBitsForEqualsAndHashCode(const FieldDescriptor * field)979 bool CheckHasBitsForEqualsAndHashCode(const FieldDescriptor* field) {
980 if (field->is_repeated()) {
981 return false;
982 }
983 if (SupportFieldPresence(field->file())) {
984 return true;
985 }
986 return GetJavaType(field) == JAVATYPE_MESSAGE &&
987 field->containing_oneof() == NULL;
988 }
989 } // namespace
990
991 void ImmutableMessageGenerator::
GenerateEqualsAndHashCode(io::Printer * printer)992 GenerateEqualsAndHashCode(io::Printer* printer) {
993 printer->Print(
994 "@java.lang.Override\n"
995 "public boolean equals(final java.lang.Object obj) {\n");
996 printer->Indent();
997 printer->Print(
998 "if (obj == this) {\n"
999 " return true;\n"
1000 "}\n"
1001 "if (!(obj instanceof $classname$)) {\n"
1002 " return super.equals(obj);\n"
1003 "}\n"
1004 "$classname$ other = ($classname$) obj;\n"
1005 "\n",
1006 "classname", name_resolver_->GetImmutableClassName(descriptor_));
1007
1008 printer->Print("boolean result = true;\n");
1009 for (int i = 0; i < descriptor_->field_count(); i++) {
1010 const FieldDescriptor* field = descriptor_->field(i);
1011 if (field->containing_oneof() == NULL) {
1012 const FieldGeneratorInfo* info = context_->GetFieldGeneratorInfo(field);
1013 bool check_has_bits = CheckHasBitsForEqualsAndHashCode(field);
1014 if (check_has_bits) {
1015 printer->Print(
1016 "result = result && (has$name$() == other.has$name$());\n"
1017 "if (has$name$()) {\n",
1018 "name", info->capitalized_name);
1019 printer->Indent();
1020 }
1021 field_generators_.get(field).GenerateEqualsCode(printer);
1022 if (check_has_bits) {
1023 printer->Outdent();
1024 printer->Print(
1025 "}\n");
1026 }
1027 }
1028 }
1029
1030 // Compare oneofs.
1031 for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
1032 printer->Print(
1033 "result = result && get$oneof_capitalized_name$Case().equals(\n"
1034 " other.get$oneof_capitalized_name$Case());\n",
1035 "oneof_capitalized_name",
1036 context_->GetOneofGeneratorInfo(
1037 descriptor_->oneof_decl(i))->capitalized_name);
1038 printer->Print(
1039 "if (!result) return false;\n"
1040 "switch ($oneof_name$Case_) {\n",
1041 "oneof_name",
1042 context_->GetOneofGeneratorInfo(
1043 descriptor_->oneof_decl(i))->name);
1044 printer->Indent();
1045 for (int j = 0; j < descriptor_->oneof_decl(i)->field_count(); j++) {
1046 const FieldDescriptor* field = descriptor_->oneof_decl(i)->field(j);
1047 printer->Print(
1048 "case $field_number$:\n",
1049 "field_number",
1050 SimpleItoa(field->number()));
1051 printer->Indent();
1052 field_generators_.get(field).GenerateEqualsCode(printer);
1053 printer->Print("break;\n");
1054 printer->Outdent();
1055 }
1056 printer->Print(
1057 "case 0:\n"
1058 "default:\n");
1059 printer->Outdent();
1060 printer->Print("}\n");
1061 }
1062
1063 if (PreserveUnknownFields(descriptor_)) {
1064 // Always consider unknown fields for equality. This will sometimes return
1065 // false for non-canonical ordering when running in LITE_RUNTIME but it's
1066 // the best we can do.
1067 printer->Print(
1068 "result = result && unknownFields.equals(other.unknownFields);\n");
1069 }
1070 if (descriptor_->extension_range_count() > 0) {
1071 printer->Print(
1072 "result = result &&\n"
1073 " getExtensionFields().equals(other.getExtensionFields());\n");
1074 }
1075 printer->Print(
1076 "return result;\n");
1077 printer->Outdent();
1078 printer->Print(
1079 "}\n"
1080 "\n");
1081
1082 printer->Print(
1083 "@java.lang.Override\n"
1084 "public int hashCode() {\n");
1085 printer->Indent();
1086 printer->Print(
1087 "if (memoizedHashCode != 0) {\n");
1088 printer->Indent();
1089 printer->Print(
1090 "return memoizedHashCode;\n");
1091 printer->Outdent();
1092 printer->Print(
1093 "}\n"
1094 "int hash = 41;\n");
1095
1096 printer->Print("hash = (19 * hash) + getDescriptorForType().hashCode();\n");
1097
1098 // hashCode non-oneofs.
1099 for (int i = 0; i < descriptor_->field_count(); i++) {
1100 const FieldDescriptor* field = descriptor_->field(i);
1101 if (field->containing_oneof() == NULL) {
1102 const FieldGeneratorInfo* info = context_->GetFieldGeneratorInfo(field);
1103 bool check_has_bits = CheckHasBitsForEqualsAndHashCode(field);
1104 if (check_has_bits) {
1105 printer->Print(
1106 "if (has$name$()) {\n",
1107 "name", info->capitalized_name);
1108 printer->Indent();
1109 }
1110 field_generators_.get(field).GenerateHashCode(printer);
1111 if (check_has_bits) {
1112 printer->Outdent();
1113 printer->Print("}\n");
1114 }
1115 }
1116 }
1117
1118 // hashCode oneofs.
1119 for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
1120 printer->Print(
1121 "switch ($oneof_name$Case_) {\n",
1122 "oneof_name",
1123 context_->GetOneofGeneratorInfo(
1124 descriptor_->oneof_decl(i))->name);
1125 printer->Indent();
1126 for (int j = 0; j < descriptor_->oneof_decl(i)->field_count(); j++) {
1127 const FieldDescriptor* field = descriptor_->oneof_decl(i)->field(j);
1128 printer->Print(
1129 "case $field_number$:\n",
1130 "field_number",
1131 SimpleItoa(field->number()));
1132 printer->Indent();
1133 field_generators_.get(field).GenerateHashCode(printer);
1134 printer->Print("break;\n");
1135 printer->Outdent();
1136 }
1137 printer->Print(
1138 "case 0:\n"
1139 "default:\n");
1140 printer->Outdent();
1141 printer->Print("}\n");
1142 }
1143
1144 if (descriptor_->extension_range_count() > 0) {
1145 printer->Print(
1146 "hash = hashFields(hash, getExtensionFields());\n");
1147 }
1148
1149 printer->Print(
1150 "hash = (29 * hash) + unknownFields.hashCode();\n");
1151 printer->Print(
1152 "memoizedHashCode = hash;\n"
1153 "return hash;\n");
1154 printer->Outdent();
1155 printer->Print(
1156 "}\n"
1157 "\n");
1158 }
1159
1160 // ===================================================================
1161
1162 void ImmutableMessageGenerator::
GenerateExtensionRegistrationCode(io::Printer * printer)1163 GenerateExtensionRegistrationCode(io::Printer* printer) {
1164 for (int i = 0; i < descriptor_->extension_count(); i++) {
1165 ImmutableExtensionGenerator(descriptor_->extension(i), context_)
1166 .GenerateRegistrationCode(printer);
1167 }
1168
1169 for (int i = 0; i < descriptor_->nested_type_count(); i++) {
1170 ImmutableMessageGenerator(descriptor_->nested_type(i), context_)
1171 .GenerateExtensionRegistrationCode(printer);
1172 }
1173 }
1174
1175 // ===================================================================
1176 void ImmutableMessageGenerator::
GenerateParsingConstructor(io::Printer * printer)1177 GenerateParsingConstructor(io::Printer* printer) {
1178 google::protobuf::scoped_array<const FieldDescriptor * > sorted_fields(
1179 SortFieldsByNumber(descriptor_));
1180
1181 printer->Print(
1182 "private $classname$(\n"
1183 " com.google.protobuf.CodedInputStream input,\n"
1184 " com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n"
1185 " throws com.google.protobuf.InvalidProtocolBufferException {\n",
1186 "classname", descriptor_->name());
1187 printer->Indent();
1188
1189 // Initialize all fields to default.
1190 printer->Print(
1191 "this();\n");
1192
1193 // Use builder bits to track mutable repeated fields.
1194 int totalBuilderBits = 0;
1195 for (int i = 0; i < descriptor_->field_count(); i++) {
1196 const ImmutableFieldGenerator& field =
1197 field_generators_.get(descriptor_->field(i));
1198 totalBuilderBits += field.GetNumBitsForBuilder();
1199 }
1200 int totalBuilderInts = (totalBuilderBits + 31) / 32;
1201 for (int i = 0; i < totalBuilderInts; i++) {
1202 printer->Print("int mutable_$bit_field_name$ = 0;\n",
1203 "bit_field_name", GetBitFieldName(i));
1204 }
1205
1206 if (PreserveUnknownFields(descriptor_)) {
1207 printer->Print(
1208 "com.google.protobuf.UnknownFieldSet.Builder unknownFields =\n"
1209 " com.google.protobuf.UnknownFieldSet.newBuilder();\n");
1210 }
1211
1212 printer->Print(
1213 "try {\n");
1214 printer->Indent();
1215
1216 printer->Print(
1217 "boolean done = false;\n"
1218 "while (!done) {\n");
1219 printer->Indent();
1220
1221 printer->Print(
1222 "int tag = input.readTag();\n"
1223 "switch (tag) {\n");
1224 printer->Indent();
1225
1226 printer->Print(
1227 "case 0:\n" // zero signals EOF / limit reached
1228 " done = true;\n"
1229 " break;\n");
1230
1231 if (PreserveUnknownFields(descriptor_)) {
1232 printer->Print(
1233 "default: {\n"
1234 " if (!parseUnknownField(input, unknownFields,\n"
1235 " extensionRegistry, tag)) {\n"
1236 " done = true;\n" // it's an endgroup tag
1237 " }\n"
1238 " break;\n"
1239 "}\n");
1240 } else {
1241 printer->Print(
1242 "default: {\n"
1243 " if (!input.skipField(tag)) {\n"
1244 " done = true;\n" // it's an endgroup tag
1245 " }\n"
1246 " break;\n"
1247 "}\n");
1248 }
1249
1250 for (int i = 0; i < descriptor_->field_count(); i++) {
1251 const FieldDescriptor* field = sorted_fields[i];
1252 uint32 tag = WireFormatLite::MakeTag(field->number(),
1253 WireFormat::WireTypeForFieldType(field->type()));
1254
1255 printer->Print(
1256 "case $tag$: {\n",
1257 "tag", SimpleItoa(tag));
1258 printer->Indent();
1259
1260 field_generators_.get(field).GenerateParsingCode(printer);
1261
1262 printer->Outdent();
1263 printer->Print(
1264 " break;\n"
1265 "}\n");
1266
1267 if (field->is_packable()) {
1268 // To make packed = true wire compatible, we generate parsing code from a
1269 // packed version of this field regardless of field->options().packed().
1270 uint32 packed_tag = WireFormatLite::MakeTag(field->number(),
1271 WireFormatLite::WIRETYPE_LENGTH_DELIMITED);
1272 printer->Print(
1273 "case $tag$: {\n",
1274 "tag", SimpleItoa(packed_tag));
1275 printer->Indent();
1276
1277 field_generators_.get(field).GenerateParsingCodeFromPacked(printer);
1278
1279 printer->Outdent();
1280 printer->Print(
1281 " break;\n"
1282 "}\n");
1283 }
1284 }
1285
1286 printer->Outdent();
1287 printer->Outdent();
1288 printer->Print(
1289 " }\n" // switch (tag)
1290 "}\n"); // while (!done)
1291
1292 printer->Outdent();
1293 printer->Print(
1294 "} catch (com.google.protobuf.InvalidProtocolBufferException e) {\n"
1295 " throw e.setUnfinishedMessage(this);\n"
1296 "} catch (java.io.IOException e) {\n"
1297 " throw new com.google.protobuf.InvalidProtocolBufferException(\n"
1298 " e).setUnfinishedMessage(this);\n"
1299 "} finally {\n");
1300 printer->Indent();
1301
1302 // Make repeated field list immutable.
1303 for (int i = 0; i < descriptor_->field_count(); i++) {
1304 const FieldDescriptor* field = sorted_fields[i];
1305 field_generators_.get(field).GenerateParsingDoneCode(printer);
1306 }
1307
1308 if (PreserveUnknownFields(descriptor_)) {
1309 // Make unknown fields immutable.
1310 printer->Print("this.unknownFields = unknownFields.build();\n");
1311 }
1312
1313 // Make extensions immutable.
1314 printer->Print(
1315 "makeExtensionsImmutable();\n");
1316
1317 printer->Outdent();
1318 printer->Outdent();
1319 printer->Print(
1320 " }\n" // finally
1321 "}\n");
1322 }
1323
1324 // ===================================================================
GenerateParser(io::Printer * printer)1325 void ImmutableMessageGenerator::GenerateParser(io::Printer* printer) {
1326 printer->Print(
1327 "$visibility$ static final com.google.protobuf.Parser<$classname$>\n"
1328 " PARSER = new com.google.protobuf.AbstractParser<$classname$>() {\n",
1329 "visibility",
1330 ExposePublicParser(descriptor_->file()) ? "@java.lang.Deprecated public"
1331 : "private",
1332 "classname", descriptor_->name());
1333 printer->Indent();
1334 printer->Print(
1335 "public $classname$ parsePartialFrom(\n"
1336 " com.google.protobuf.CodedInputStream input,\n"
1337 " com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n"
1338 " throws com.google.protobuf.InvalidProtocolBufferException {\n",
1339 "classname", descriptor_->name());
1340 if (context_->HasGeneratedMethods(descriptor_)) {
1341 printer->Print(
1342 " return new $classname$(input, extensionRegistry);\n",
1343 "classname", descriptor_->name());
1344 } else {
1345 // When parsing constructor isn't generated, use builder to parse
1346 // messages. Note, will fallback to use reflection based mergeFieldFrom()
1347 // in AbstractMessage.Builder.
1348 printer->Indent();
1349 printer->Print(
1350 "Builder builder = newBuilder();\n"
1351 "try {\n"
1352 " builder.mergeFrom(input, extensionRegistry);\n"
1353 "} catch (com.google.protobuf.InvalidProtocolBufferException e) {\n"
1354 " throw e.setUnfinishedMessage(builder.buildPartial());\n"
1355 "} catch (java.io.IOException e) {\n"
1356 " throw new com.google.protobuf.InvalidProtocolBufferException(\n"
1357 " e.getMessage()).setUnfinishedMessage(\n"
1358 " builder.buildPartial());\n"
1359 "}\n"
1360 "return builder.buildPartial();\n");
1361 printer->Outdent();
1362 }
1363 printer->Print(
1364 "}\n");
1365 printer->Outdent();
1366 printer->Print(
1367 "};\n"
1368 "\n");
1369
1370 printer->Print(
1371 "public static com.google.protobuf.Parser<$classname$> parser() {\n"
1372 " return PARSER;\n"
1373 "}\n"
1374 "\n"
1375 "@java.lang.Override\n"
1376 "public com.google.protobuf.Parser<$classname$> getParserForType() {\n"
1377 " return PARSER;\n"
1378 "}\n"
1379 "\n",
1380 "classname", descriptor_->name());
1381 }
1382
1383 // ===================================================================
GenerateInitializers(io::Printer * printer)1384 void ImmutableMessageGenerator::GenerateInitializers(io::Printer* printer) {
1385 for (int i = 0; i < descriptor_->field_count(); i++) {
1386 if (!descriptor_->field(i)->containing_oneof()) {
1387 field_generators_.get(descriptor_->field(i))
1388 .GenerateInitializationCode(printer);
1389 }
1390 }
1391 }
1392
1393
GenerateAnyMethods(io::Printer * printer)1394 void ImmutableMessageGenerator::GenerateAnyMethods(io::Printer* printer) {
1395 printer->Print(
1396 "private static String getTypeUrl(\n"
1397 " java.lang.String typeUrlPrefix,\n"
1398 " com.google.protobuf.Descriptors.Descriptor descriptor) {\n"
1399 " return typeUrlPrefix.endsWith(\"/\")\n"
1400 " ? typeUrlPrefix + descriptor.getFullName()\n"
1401 " : typeUrlPrefix + \"/\" + descriptor.getFullName();\n"
1402 "}\n"
1403 "\n"
1404 "private static String getTypeNameFromTypeUrl(\n"
1405 " java.lang.String typeUrl) {\n"
1406 " int pos = typeUrl.lastIndexOf('/');\n"
1407 " return pos == -1 ? \"\" : typeUrl.substring(pos + 1);\n"
1408 "}\n"
1409 "\n"
1410 "public static <T extends com.google.protobuf.Message> Any pack(\n"
1411 " T message) {\n"
1412 " return Any.newBuilder()\n"
1413 " .setTypeUrl(getTypeUrl(\"type.googleapis.com\",\n"
1414 " message.getDescriptorForType()))\n"
1415 " .setValue(message.toByteString())\n"
1416 " .build();\n"
1417 "}\n"
1418 "\n"
1419 "/**\n"
1420 " * Packs a message uisng the given type URL prefix. The type URL will\n"
1421 " * be constructed by concatenating the message type's full name to the\n"
1422 " * prefix with an optional \"/\" separator if the prefix doesn't end\n"
1423 " * with \"/\" already.\n"
1424 " */\n"
1425 "public static <T extends com.google.protobuf.Message> Any pack(\n"
1426 " T message, java.lang.String typeUrlPrefix) {\n"
1427 " return Any.newBuilder()\n"
1428 " .setTypeUrl(getTypeUrl(typeUrlPrefix,\n"
1429 " message.getDescriptorForType()))\n"
1430 " .setValue(message.toByteString())\n"
1431 " .build();\n"
1432 "}\n"
1433 "\n"
1434 "public <T extends com.google.protobuf.Message> boolean is(\n"
1435 " java.lang.Class<T> clazz) {\n"
1436 " T defaultInstance =\n"
1437 " com.google.protobuf.Internal.getDefaultInstance(clazz);\n"
1438 " return getTypeNameFromTypeUrl(getTypeUrl()).equals(\n"
1439 " defaultInstance.getDescriptorForType().getFullName());\n"
1440 "}\n"
1441 "\n"
1442 "private volatile com.google.protobuf.Message cachedUnpackValue;\n"
1443 "\n"
1444 "public <T extends com.google.protobuf.Message> T unpack(\n"
1445 " java.lang.Class<T> clazz)\n"
1446 " throws com.google.protobuf.InvalidProtocolBufferException {\n"
1447 " if (!is(clazz)) {\n"
1448 " throw new com.google.protobuf.InvalidProtocolBufferException(\n"
1449 " \"Type of the Any message does not match the given class.\");\n"
1450 " }\n"
1451 " if (cachedUnpackValue != null) {\n"
1452 " return (T) cachedUnpackValue;\n"
1453 " }\n"
1454 " T defaultInstance =\n"
1455 " com.google.protobuf.Internal.getDefaultInstance(clazz);\n"
1456 " T result = (T) defaultInstance.getParserForType()\n"
1457 " .parseFrom(getValue());\n"
1458 " cachedUnpackValue = result;\n"
1459 " return result;\n"
1460 "}\n");
1461 }
1462
1463 } // namespace java
1464 } // namespace compiler
1465 } // namespace protobuf
1466 } // namespace google
1467