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