blob: 94ed2c396aa631315daef2dd8bdf434116a71e60 [file] [log] [blame]
Bo Yang5db21732015-05-21 14:28:59 -07001// Protocol Buffers - Google's data interchange format
2// Copyright 2008 Google Inc. All rights reserved.
3// https://developers.google.com/protocol-buffers/
4//
5// Redistribution and use in source and binary forms, with or without
6// modification, are permitted provided that the following conditions are
7// met:
8//
9// * Redistributions of source code must retain the above copyright
10// notice, this list of conditions and the following disclaimer.
11// * Redistributions in binary form must reproduce the above
12// copyright notice, this list of conditions and the following disclaimer
13// in the documentation and/or other materials provided with the
14// distribution.
15// * Neither the name of Google Inc. nor the names of its
16// contributors may be used to endorse or promote products derived from
17// this software without specific prior written permission.
18//
19// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
31// Author: dweis@google.com (Daniel Weis)
32// Based on original Protocol Buffers design by
33// Sanjay Ghemawat, Jeff Dean, and others.
34
35#include <google/protobuf/compiler/java/java_message_lite.h>
36
37#include <algorithm>
38#include <google/protobuf/stubs/hash.h>
39#include <map>
40#include <memory>
41#ifndef _SHARED_PTR_H
42#include <google/protobuf/stubs/shared_ptr.h>
43#endif
44#include <vector>
45
46#include <google/protobuf/compiler/java/java_context.h>
47#include <google/protobuf/compiler/java/java_doc_comment.h>
Feng Xiaoeee38b02015-08-22 18:25:48 -070048#include <google/protobuf/compiler/java/java_enum_lite.h>
Bo Yang5db21732015-05-21 14:28:59 -070049#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
62namespace google {
63namespace protobuf {
64namespace compiler {
65namespace java {
66
67using internal::WireFormat;
68using internal::WireFormatLite;
69
70namespace {
71bool GenerateHasBits(const Descriptor* descriptor) {
72 return SupportFieldPresence(descriptor->file()) ||
73 HasRepeatedFields(descriptor);
74}
75
76string 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// ===================================================================
85ImmutableMessageLiteGenerator::ImmutableMessageLiteGenerator(
86 const Descriptor* descriptor, Context* context)
87 : MessageGenerator(descriptor), context_(context),
88 name_resolver_(context->GetNameResolver()),
89 field_generators_(descriptor, context_) {
90 GOOGLE_CHECK_EQ(
91 FileOptions::LITE_RUNTIME, descriptor->file()->options().optimize_for());
92}
93
94ImmutableMessageLiteGenerator::~ImmutableMessageLiteGenerator() {}
95
96void ImmutableMessageLiteGenerator::GenerateStaticVariables(
97 io::Printer* printer) {
98 // Generate static members for all nested types.
99 for (int i = 0; i < descriptor_->nested_type_count(); i++) {
100 // TODO(kenton): Reuse MessageGenerator objects?
101 ImmutableMessageLiteGenerator(descriptor_->nested_type(i), context_)
102 .GenerateStaticVariables(printer);
103 }
104}
105
106int ImmutableMessageLiteGenerator::GenerateStaticVariableInitializers(
107 io::Printer* printer) {
108 int bytecode_estimate = 0;
109 // Generate static member initializers for all nested types.
110 for (int i = 0; i < descriptor_->nested_type_count(); i++) {
111 // TODO(kenton): Reuse MessageGenerator objects?
112 bytecode_estimate +=
113 ImmutableMessageLiteGenerator(descriptor_->nested_type(i), context_)
114 .GenerateStaticVariableInitializers(printer);
115 }
116 return bytecode_estimate;
117}
118
119// ===================================================================
120
121void ImmutableMessageLiteGenerator::GenerateInterface(io::Printer* printer) {
122 if (descriptor_->extension_range_count() > 0) {
123 printer->Print(
124 "public interface $classname$OrBuilder extends \n"
125 " $extra_interfaces$\n"
126 " com.google.protobuf.GeneratedMessageLite.\n"
127 " ExtendableMessageOrBuilder<\n"
128 " $classname$, $classname$.Builder> {\n",
129 "extra_interfaces", ExtraMessageOrBuilderInterfaces(descriptor_),
130 "classname", descriptor_->name());
131 } else {
132 printer->Print(
133 "public interface $classname$OrBuilder extends\n"
134 " $extra_interfaces$\n"
135 " com.google.protobuf.MessageLiteOrBuilder {\n",
136 "extra_interfaces", ExtraMessageOrBuilderInterfaces(descriptor_),
137 "classname", descriptor_->name());
138 }
139
140 printer->Indent();
141 for (int i = 0; i < descriptor_->field_count(); i++) {
142 printer->Print("\n");
143 field_generators_.get(descriptor_->field(i))
144 .GenerateInterfaceMembers(printer);
145 }
Feng Xiaoeee38b02015-08-22 18:25:48 -0700146 for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
147 printer->Print(
148 "\n"
149 "public $classname$.$oneof_capitalized_name$Case "
150 "get$oneof_capitalized_name$Case();\n",
151 "oneof_capitalized_name",
152 context_->GetOneofGeneratorInfo(
153 descriptor_->oneof_decl(i))->capitalized_name,
154 "classname",
155 context_->GetNameResolver()->GetImmutableClassName(descriptor_));
156 }
Bo Yang5db21732015-05-21 14:28:59 -0700157 printer->Outdent();
158
159 printer->Print("}\n");
160}
161
162// ===================================================================
163
164void ImmutableMessageLiteGenerator::Generate(io::Printer* printer) {
165 bool is_own_file =
166 descriptor_->containing_type() == NULL &&
167 MultipleJavaFiles(descriptor_->file(), /* immutable = */ true);
168
169 map<string, string> variables;
170 variables["static"] = is_own_file ? " " : " static ";
171 variables["classname"] = descriptor_->name();
172 variables["extra_interfaces"] = ExtraMessageInterfaces(descriptor_);
173
174 WriteMessageDocComment(printer, descriptor_);
175
176 // The builder_type stores the super type name of the nested Builder class.
177 string builder_type;
178 if (descriptor_->extension_range_count() > 0) {
179 printer->Print(variables,
180 "public $static$final class $classname$ extends\n"
181 " com.google.protobuf.GeneratedMessageLite.ExtendableMessage<\n"
182 " $classname$, $classname$.Builder> implements\n"
183 " $extra_interfaces$\n"
184 " $classname$OrBuilder {\n");
185 builder_type = strings::Substitute(
186 "com.google.protobuf.GeneratedMessageLite.ExtendableBuilder<$0, ?>",
187 name_resolver_->GetImmutableClassName(descriptor_));
188 } else {
189 printer->Print(variables,
190 "public $static$final class $classname$ extends\n"
191 " com.google.protobuf.GeneratedMessageLite<\n"
192 " $classname$, $classname$.Builder> implements\n"
193 " $extra_interfaces$\n"
194 " $classname$OrBuilder {\n");
195
196 builder_type = "com.google.protobuf.GeneratedMessageLite.Builder";
197 }
198 printer->Indent();
199
200 GenerateParsingConstructor(printer);
201
202 // Nested types
203 for (int i = 0; i < descriptor_->enum_type_count(); i++) {
Feng Xiaoeee38b02015-08-22 18:25:48 -0700204 EnumLiteGenerator(descriptor_->enum_type(i), true, context_)
Bo Yang5db21732015-05-21 14:28:59 -0700205 .Generate(printer);
206 }
207
208 for (int i = 0; i < descriptor_->nested_type_count(); i++) {
209 // Don't generate Java classes for map entry messages.
210 if (IsMapEntry(descriptor_->nested_type(i))) continue;
211 ImmutableMessageLiteGenerator messageGenerator(
212 descriptor_->nested_type(i), context_);
213 messageGenerator.GenerateInterface(printer);
214 messageGenerator.Generate(printer);
215 }
216
217 if (GenerateHasBits(descriptor_)) {
218 // Integers for bit fields.
219 int totalBits = 0;
220 for (int i = 0; i < descriptor_->field_count(); i++) {
221 totalBits += field_generators_.get(descriptor_->field(i))
222 .GetNumBitsForMessage();
223 }
224 int totalInts = (totalBits + 31) / 32;
225 for (int i = 0; i < totalInts; i++) {
226 printer->Print("private int $bit_field_name$;\n",
227 "bit_field_name", GetBitFieldName(i));
228 }
229 }
230
231 // oneof
232 map<string, string> vars;
233 for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
234 vars["oneof_name"] = context_->GetOneofGeneratorInfo(
235 descriptor_->oneof_decl(i))->name;
236 vars["oneof_capitalized_name"] = context_->GetOneofGeneratorInfo(
237 descriptor_->oneof_decl(i))->capitalized_name;
238 vars["oneof_index"] = SimpleItoa(descriptor_->oneof_decl(i)->index());
239 // oneofCase_ and oneof_
240 printer->Print(vars,
241 "private int $oneof_name$Case_ = 0;\n"
242 "private java.lang.Object $oneof_name$_;\n");
243 // OneofCase enum
244 printer->Print(vars,
245 "public enum $oneof_capitalized_name$Case\n"
246 " implements com.google.protobuf.Internal.EnumLite {\n");
247 printer->Indent();
248 for (int j = 0; j < descriptor_->oneof_decl(i)->field_count(); j++) {
249 const FieldDescriptor* field = descriptor_->oneof_decl(i)->field(j);
250 printer->Print(
251 "$field_name$($field_number$),\n",
252 "field_name",
253 ToUpper(field->name()),
254 "field_number",
255 SimpleItoa(field->number()));
256 }
257 printer->Print(
258 "$cap_oneof_name$_NOT_SET(0);\n",
259 "cap_oneof_name",
260 ToUpper(vars["oneof_name"]));
261 printer->Print(vars,
262 "private int value = 0;\n"
263 "private $oneof_capitalized_name$Case(int value) {\n"
264 " this.value = value;\n"
265 "}\n");
266 printer->Print(vars,
267 "public static $oneof_capitalized_name$Case valueOf(int value) {\n"
268 " switch (value) {\n");
269 for (int j = 0; j < descriptor_->oneof_decl(i)->field_count(); j++) {
270 const FieldDescriptor* field = descriptor_->oneof_decl(i)->field(j);
271 printer->Print(
272 " case $field_number$: return $field_name$;\n",
273 "field_number",
274 SimpleItoa(field->number()),
275 "field_name",
276 ToUpper(field->name()));
277 }
278 printer->Print(
279 " case 0: return $cap_oneof_name$_NOT_SET;\n"
280 " default: throw new java.lang.IllegalArgumentException(\n"
281 " \"Value is undefined for this oneof enum.\");\n"
282 " }\n"
283 "}\n"
284 "public int getNumber() {\n"
285 " return this.value;\n"
286 "}\n",
287 "cap_oneof_name", ToUpper(vars["oneof_name"]));
288 printer->Outdent();
289 printer->Print("};\n\n");
290 // oneofCase()
291 printer->Print(vars,
292 "public $oneof_capitalized_name$Case\n"
293 "get$oneof_capitalized_name$Case() {\n"
294 " return $oneof_capitalized_name$Case.valueOf(\n"
295 " $oneof_name$Case_);\n"
296 "}\n"
297 "\n"
298 "private void clear$oneof_capitalized_name$() {\n"
299 " $oneof_name$Case_ = 0;\n"
300 " $oneof_name$_ = null;\n"
301 "}\n"
302 "\n");
303 }
304
305 // Fields
306 for (int i = 0; i < descriptor_->field_count(); i++) {
307 printer->Print("public static final int $constant_name$ = $number$;\n",
308 "constant_name", FieldConstantName(descriptor_->field(i)),
309 "number", SimpleItoa(descriptor_->field(i)->number()));
310 field_generators_.get(descriptor_->field(i)).GenerateMembers(printer);
311 printer->Print("\n");
312 }
313
314 GenerateMessageSerializationMethods(printer);
315
316 if (HasEqualsAndHashCode(descriptor_)) {
317 GenerateEqualsAndHashCode(printer);
318 }
319
320
321 GenerateParseFromMethods(printer);
322 GenerateBuilder(printer);
323
324 if (HasRequiredFields(descriptor_)) {
325 // Memoizes whether the protocol buffer is fully initialized (has all
326 // required fields). -1 means not yet computed. 0 means false and 1 means
327 // true.
328 printer->Print(
329 "private byte memoizedIsInitialized = -1;\n");
330 }
331
332 printer->Print(
333 "protected final Object dynamicMethod(\n"
334 " com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,\n"
Feng Xiaoeee38b02015-08-22 18:25:48 -0700335 " Object arg0, Object arg1) {\n"
Bo Yang5db21732015-05-21 14:28:59 -0700336 " switch (method) {\n"
337 " case PARSE_PARTIAL_FROM: {\n"
338 " return new $classname$("
Feng Xiaoeee38b02015-08-22 18:25:48 -0700339 " (com.google.protobuf.CodedInputStream) arg0,\n"
340 " (com.google.protobuf.ExtensionRegistryLite) arg1);\n"
Bo Yang5db21732015-05-21 14:28:59 -0700341 " }\n"
342 " case NEW_INSTANCE: {\n"
343 " return new $classname$(\n"
344 " com.google.protobuf.Internal.EMPTY_CODED_INPUT_STREAM,\n"
345 " com.google.protobuf.ExtensionRegistryLite\n"
346 " .getEmptyRegistry());\n"
347 " }\n",
348 "classname", name_resolver_->GetImmutableClassName(descriptor_));
349
350 printer->Indent();
351 printer->Indent();
352
353 printer->Print(
354 "case IS_INITIALIZED: {\n");
355 printer->Indent();
356 GenerateDynamicMethodIsInitialized(printer);
357 printer->Outdent();
358
359 printer->Print(
360 "}\n"
361 "case MAKE_IMMUTABLE: {\n");
362
363 printer->Indent();
364 GenerateDynamicMethodMakeImmutable(printer);
365 printer->Outdent();
366
367 printer->Print(
368 "}\n"
369 "case NEW_BUILDER: {\n");
370
371 printer->Indent();
372 GenerateDynamicMethodNewBuilder(printer);
373 printer->Outdent();
374
375 printer->Print(
376 "}\n"
377 "case MERGE_FROM: {\n");
378
379 printer->Indent();
380 GenerateDynamicMethodMergeFrom(printer);
381 printer->Outdent();
382
383 printer->Print(
Feng Xiaoeee38b02015-08-22 18:25:48 -0700384 "}\n"
385 "case GET_DEFAULT_INSTANCE: {\n"
386 " return DEFAULT_INSTANCE;\n"
387 "}\n"
388 "case GET_PARSER: {\n"
389 // Generally one would use the lazy initialization holder pattern for
390 // manipulating static fields but that has exceptional cost on Android as
391 // it will generate an extra class for every message. Instead, use the
392 // double-check locking pattern which works just as well.
393 " if (PARSER == null) {"
394 " synchronized ($classname$.class) {\n"
395 " if (PARSER == null) {\n"
396 " PARSER = new DefaultInstanceBasedParser(DEFAULT_INSTANCE);\n"
397 " }\n"
398 " }\n"
399 " }\n"
400 " return PARSER;\n"
401 "}\n",
402 "classname", name_resolver_->GetImmutableClassName(descriptor_));
Bo Yang5db21732015-05-21 14:28:59 -0700403
404 printer->Outdent();
405 printer->Outdent();
406
407 printer->Print(
408 " }\n"
409 " throw new UnsupportedOperationException();\n"
410 "}\n"
411 "\n",
412 "classname", name_resolver_->GetImmutableClassName(descriptor_));
413
414 printer->Print(
415 "\n"
416 "// @@protoc_insertion_point(class_scope:$full_name$)\n",
417 "full_name", descriptor_->full_name());
418
419
420 // Carefully initialize the default instance in such a way that it doesn't
421 // conflict with other initialization.
422 printer->Print(
423 "private static final $classname$ DEFAULT_INSTANCE;\n",
424 "classname", name_resolver_->GetImmutableClassName(descriptor_));
425
426 printer->Print(
427 "static {\n"
428 " DEFAULT_INSTANCE = new $classname$(\n"
429 " com.google.protobuf.Internal\n"
430 " .EMPTY_CODED_INPUT_STREAM,\n"
431 " com.google.protobuf.ExtensionRegistryLite\n"
432 " .getEmptyRegistry());\n"
433 "}\n"
434 "\n",
435 "classname", descriptor_->name());
436 printer->Print(
437 "public static $classname$ getDefaultInstance() {\n"
438 " return DEFAULT_INSTANCE;\n"
439 "}\n"
440 "\n",
441 "classname", name_resolver_->GetImmutableClassName(descriptor_));
442
443 GenerateParser(printer);
444
Bo Yang5db21732015-05-21 14:28:59 -0700445 // Extensions must be declared after the DEFAULT_INSTANCE is initialized
446 // because the DEFAULT_INSTANCE is used by the extension to lazily retrieve
447 // the outer class's FileDescriptor.
448 for (int i = 0; i < descriptor_->extension_count(); i++) {
449 ImmutableExtensionGenerator(descriptor_->extension(i), context_)
450 .Generate(printer);
451 }
452
453 printer->Outdent();
454 printer->Print("}\n\n");
455}
456
457// ===================================================================
458
459void ImmutableMessageLiteGenerator::
460GenerateMessageSerializationMethods(io::Printer* printer) {
461 google::protobuf::scoped_array<const FieldDescriptor * > sorted_fields(
462 SortFieldsByNumber(descriptor_));
463
464 vector<const Descriptor::ExtensionRange*> sorted_extensions;
465 for (int i = 0; i < descriptor_->extension_range_count(); ++i) {
466 sorted_extensions.push_back(descriptor_->extension_range(i));
467 }
468 std::sort(sorted_extensions.begin(), sorted_extensions.end(),
469 ExtensionRangeOrdering());
470
471 printer->Print(
472 "public void writeTo(com.google.protobuf.CodedOutputStream output)\n"
473 " throws java.io.IOException {\n");
474 printer->Indent();
475 if (HasPackedFields(descriptor_)) {
476 // writeTo(CodedOutputStream output) might be invoked without
477 // getSerializedSize() ever being called, but we need the memoized
478 // sizes in case this message has packed fields. Rather than emit checks for
479 // each packed field, just call getSerializedSize() up front.
480 // In most cases, getSerializedSize() will have already been called anyway
481 // by one of the wrapper writeTo() methods, making this call cheap.
482 printer->Print(
483 "getSerializedSize();\n");
484 }
485
486 if (descriptor_->extension_range_count() > 0) {
487 if (descriptor_->options().message_set_wire_format()) {
488 printer->Print(
489 "com.google.protobuf.GeneratedMessageLite\n"
490 " .ExtendableMessage<$classname$, $classname$.Builder>\n"
491 " .ExtensionWriter extensionWriter =\n"
492 " newMessageSetExtensionWriter();\n",
493 "classname", name_resolver_->GetImmutableClassName(descriptor_));
494 } else {
495 printer->Print(
496 "com.google.protobuf.GeneratedMessageLite\n"
497 " .ExtendableMessage<$classname$, $classname$.Builder>\n"
498 " .ExtensionWriter extensionWriter =\n"
499 " newExtensionWriter();\n",
500 "classname", name_resolver_->GetImmutableClassName(descriptor_));
501 }
502 }
503
504 // Merge the fields and the extension ranges, both sorted by field number.
505 for (int i = 0, j = 0;
506 i < descriptor_->field_count() || j < sorted_extensions.size();
507 ) {
508 if (i == descriptor_->field_count()) {
509 GenerateSerializeOneExtensionRange(printer, sorted_extensions[j++]);
510 } else if (j == sorted_extensions.size()) {
511 GenerateSerializeOneField(printer, sorted_fields[i++]);
512 } else if (sorted_fields[i]->number() < sorted_extensions[j]->start) {
513 GenerateSerializeOneField(printer, sorted_fields[i++]);
514 } else {
515 GenerateSerializeOneExtensionRange(printer, sorted_extensions[j++]);
516 }
517 }
518
519 if (PreserveUnknownFields(descriptor_)) {
520 printer->Print(
521 "unknownFields.writeTo(output);\n");
522 }
523
524 printer->Outdent();
525 printer->Print(
526 "}\n"
527 "\n"
528 "public int getSerializedSize() {\n"
529 " int size = memoizedSerializedSize;\n"
530 " if (size != -1) return size;\n"
531 "\n"
532 " size = 0;\n");
533 printer->Indent();
534
535 for (int i = 0; i < descriptor_->field_count(); i++) {
536 field_generators_.get(sorted_fields[i]).GenerateSerializedSizeCode(printer);
537 }
538
539 if (descriptor_->extension_range_count() > 0) {
540 if (descriptor_->options().message_set_wire_format()) {
541 printer->Print(
542 "size += extensionsSerializedSizeAsMessageSet();\n");
543 } else {
544 printer->Print(
545 "size += extensionsSerializedSize();\n");
546 }
547 }
548
549 if (PreserveUnknownFields(descriptor_)) {
550 printer->Print(
551 "size += unknownFields.getSerializedSize();\n");
552 }
553
554 printer->Outdent();
555 printer->Print(
556 " memoizedSerializedSize = size;\n"
557 " return size;\n"
558 "}\n"
559 "\n");
560
561 printer->Print(
562 "private static final long serialVersionUID = 0L;\n");
563}
564
565void ImmutableMessageLiteGenerator::
566GenerateParseFromMethods(io::Printer* printer) {
567 // Note: These are separate from GenerateMessageSerializationMethods()
568 // because they need to be generated even for messages that are optimized
569 // for code size.
570 printer->Print(
571 "public static $classname$ parseFrom(\n"
572 " com.google.protobuf.ByteString data)\n"
573 " throws com.google.protobuf.InvalidProtocolBufferException {\n"
Feng Xiaoeee38b02015-08-22 18:25:48 -0700574 " return parser().parseFrom(data);\n"
Bo Yang5db21732015-05-21 14:28:59 -0700575 "}\n"
576 "public static $classname$ parseFrom(\n"
577 " com.google.protobuf.ByteString data,\n"
578 " com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n"
579 " throws com.google.protobuf.InvalidProtocolBufferException {\n"
Feng Xiaoeee38b02015-08-22 18:25:48 -0700580 " return parser().parseFrom(data, extensionRegistry);\n"
Bo Yang5db21732015-05-21 14:28:59 -0700581 "}\n"
582 "public static $classname$ parseFrom(byte[] data)\n"
583 " throws com.google.protobuf.InvalidProtocolBufferException {\n"
Feng Xiaoeee38b02015-08-22 18:25:48 -0700584 " return parser().parseFrom(data);\n"
Bo Yang5db21732015-05-21 14:28:59 -0700585 "}\n"
586 "public static $classname$ parseFrom(\n"
587 " byte[] data,\n"
588 " com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n"
589 " throws com.google.protobuf.InvalidProtocolBufferException {\n"
Feng Xiaoeee38b02015-08-22 18:25:48 -0700590 " return parser().parseFrom(data, extensionRegistry);\n"
Bo Yang5db21732015-05-21 14:28:59 -0700591 "}\n"
592 "public static $classname$ parseFrom(java.io.InputStream input)\n"
593 " throws java.io.IOException {\n"
Feng Xiaoeee38b02015-08-22 18:25:48 -0700594 " return parser().parseFrom(input);\n"
Bo Yang5db21732015-05-21 14:28:59 -0700595 "}\n"
596 "public static $classname$ parseFrom(\n"
597 " java.io.InputStream input,\n"
598 " com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n"
599 " throws java.io.IOException {\n"
Feng Xiaoeee38b02015-08-22 18:25:48 -0700600 " return parser().parseFrom(input, extensionRegistry);\n"
Bo Yang5db21732015-05-21 14:28:59 -0700601 "}\n"
602 "public static $classname$ parseDelimitedFrom(java.io.InputStream input)\n"
603 " throws java.io.IOException {\n"
Feng Xiaoeee38b02015-08-22 18:25:48 -0700604 " return parser().parseDelimitedFrom(input);\n"
Bo Yang5db21732015-05-21 14:28:59 -0700605 "}\n"
606 "public static $classname$ parseDelimitedFrom(\n"
607 " java.io.InputStream input,\n"
608 " com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n"
609 " throws java.io.IOException {\n"
Feng Xiaoeee38b02015-08-22 18:25:48 -0700610 " return parser().parseDelimitedFrom(input, extensionRegistry);\n"
Bo Yang5db21732015-05-21 14:28:59 -0700611 "}\n"
612 "public static $classname$ parseFrom(\n"
613 " com.google.protobuf.CodedInputStream input)\n"
614 " throws java.io.IOException {\n"
Feng Xiaoeee38b02015-08-22 18:25:48 -0700615 " return parser().parseFrom(input);\n"
Bo Yang5db21732015-05-21 14:28:59 -0700616 "}\n"
617 "public static $classname$ parseFrom(\n"
618 " com.google.protobuf.CodedInputStream input,\n"
619 " com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n"
620 " throws java.io.IOException {\n"
Feng Xiaoeee38b02015-08-22 18:25:48 -0700621 " return parser().parseFrom(input, extensionRegistry);\n"
Bo Yang5db21732015-05-21 14:28:59 -0700622 "}\n"
623 "\n",
624 "classname", name_resolver_->GetImmutableClassName(descriptor_));
625}
626
627void ImmutableMessageLiteGenerator::GenerateSerializeOneField(
628 io::Printer* printer, const FieldDescriptor* field) {
629 field_generators_.get(field).GenerateSerializationCode(printer);
630}
631
632void ImmutableMessageLiteGenerator::GenerateSerializeOneExtensionRange(
633 io::Printer* printer, const Descriptor::ExtensionRange* range) {
634 printer->Print(
635 "extensionWriter.writeUntil($end$, output);\n",
636 "end", SimpleItoa(range->end));
637}
638
639// ===================================================================
640
641void ImmutableMessageLiteGenerator::GenerateBuilder(io::Printer* printer) {
642 printer->Print(
643 "public static Builder newBuilder() {\n"
644 " return DEFAULT_INSTANCE.toBuilder();\n"
645 "}\n"
646 "public static Builder newBuilder($classname$ prototype) {\n"
647 " return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);\n"
648 "}\n"
649 "\n",
650 "classname", name_resolver_->GetImmutableClassName(descriptor_));
651
652 MessageBuilderLiteGenerator builderGenerator(descriptor_, context_);
653 builderGenerator.Generate(printer);
654}
655
656// ===================================================================
657
658void ImmutableMessageLiteGenerator::GenerateDynamicMethodIsInitialized(
659 io::Printer* printer) {
660 // Returns null for false, DEFAULT_INSTANCE for true.
661 if (!HasRequiredFields(descriptor_)) {
662 printer->Print("return DEFAULT_INSTANCE;\n");
663 return;
664 }
665
666 // Don't directly compare to -1 to avoid an Android x86 JIT bug.
667 printer->Print(
668 "byte isInitialized = memoizedIsInitialized;\n"
669 "if (isInitialized == 1) return DEFAULT_INSTANCE;\n"
670 "if (isInitialized == 0) return null;\n"
671 "\n"
Feng Xiaoeee38b02015-08-22 18:25:48 -0700672 "boolean shouldMemoize = ((Boolean) arg0).booleanValue();\n");
Bo Yang5db21732015-05-21 14:28:59 -0700673
674 // Check that all required fields in this message are set.
675 // TODO(kenton): We can optimize this when we switch to putting all the
676 // "has" fields into a single bitfield.
677 for (int i = 0; i < descriptor_->field_count(); i++) {
678 const FieldDescriptor* field = descriptor_->field(i);
679 const FieldGeneratorInfo* info = context_->GetFieldGeneratorInfo(field);
680
681 if (field->is_required()) {
682 printer->Print(
683 "if (!has$name$()) {\n"
684 " if (shouldMemoize) {\n"
685 " memoizedIsInitialized = 0;\n"
686 " }\n"
687 " return null;\n"
688 "}\n",
689 "name", info->capitalized_name);
690 }
691 }
692
693 // Now check that all embedded messages are initialized.
694 for (int i = 0; i < descriptor_->field_count(); i++) {
695 const FieldDescriptor* field = descriptor_->field(i);
696 const FieldGeneratorInfo* info = context_->GetFieldGeneratorInfo(field);
697 if (GetJavaType(field) == JAVATYPE_MESSAGE &&
698 HasRequiredFields(field->message_type())) {
699 switch (field->label()) {
700 case FieldDescriptor::LABEL_REQUIRED:
701 printer->Print(
702 "if (!get$name$().isInitialized()) {\n"
703 " if (shouldMemoize) {\n"
704 " memoizedIsInitialized = 0;\n"
705 " }\n"
706 " return null;\n"
707 "}\n",
708 "type", name_resolver_->GetImmutableClassName(
709 field->message_type()),
710 "name", info->capitalized_name);
711 break;
712 case FieldDescriptor::LABEL_OPTIONAL:
713 if (!SupportFieldPresence(descriptor_->file()) &&
714 field->containing_oneof() != NULL) {
715 const OneofDescriptor* oneof = field->containing_oneof();
716 const OneofGeneratorInfo* oneof_info =
717 context_->GetOneofGeneratorInfo(oneof);
718 printer->Print(
719 "if ($oneof_name$Case_ == $field_number$) {\n",
720 "oneof_name", oneof_info->name,
721 "field_number", SimpleItoa(field->number()));
722 } else {
723 printer->Print(
724 "if (has$name$()) {\n",
725 "name", info->capitalized_name);
726 }
727 printer->Print(
728 " if (!get$name$().isInitialized()) {\n"
729 " if (shouldMemoize) {\n"
730 " memoizedIsInitialized = 0;\n"
731 " }\n"
732 " return null;\n"
733 " }\n"
734 "}\n",
735 "name", info->capitalized_name);
736 break;
737 case FieldDescriptor::LABEL_REPEATED:
738 if (IsMapEntry(field->message_type())) {
739 printer->Print(
740 "for ($type$ item : get$name$().values()) {\n"
741 " if (!item.isInitialized()) {\n"
742 " if (shouldMemoize) {\n"
743 " memoizedIsInitialized = 0;\n"
744 " }\n"
745 " return null;\n"
746 " }\n"
747 "}\n",
748 "type", MapValueImmutableClassdName(field->message_type(),
749 name_resolver_),
750 "name", info->capitalized_name);
751 } else {
752 printer->Print(
753 "for (int i = 0; i < get$name$Count(); i++) {\n"
754 " if (!get$name$(i).isInitialized()) {\n"
755 " if (shouldMemoize) {\n"
756 " memoizedIsInitialized = 0;\n"
757 " }\n"
758 " return null;\n"
759 " }\n"
760 "}\n",
761 "type", name_resolver_->GetImmutableClassName(
762 field->message_type()),
763 "name", info->capitalized_name);
764 }
765 break;
766 }
767 }
768 }
769
770 if (descriptor_->extension_range_count() > 0) {
771 printer->Print(
772 "if (!extensionsAreInitialized()) {\n"
773 " if (shouldMemoize) {\n"
774 " memoizedIsInitialized = 0;\n"
775 " }\n"
776 " return null;\n"
777 "}\n");
778 }
779
780 printer->Print(
781 "if (shouldMemoize) memoizedIsInitialized = 1;\n");
782
783 printer->Print(
784 "return DEFAULT_INSTANCE;\n"
785 "\n");
786}
787
788// ===================================================================
789
790void ImmutableMessageLiteGenerator::GenerateDynamicMethodMakeImmutable(
791 io::Printer* printer) {
792 // Output generation code for each field.
793 for (int i = 0; i < descriptor_->field_count(); i++) {
794 field_generators_.get(descriptor_->field(i))
795 .GenerateDynamicMethodMakeImmutableCode(printer);
796 }
797 printer->Print(
Feng Xiaoeee38b02015-08-22 18:25:48 -0700798 "return null;\n");
Bo Yang5db21732015-05-21 14:28:59 -0700799}
800
801// ===================================================================
802
803void ImmutableMessageLiteGenerator::GenerateDynamicMethodNewBuilder(
804 io::Printer* printer) {
805 printer->Print(
Feng Xiaoeee38b02015-08-22 18:25:48 -0700806 "return new Builder();\n");
Bo Yang5db21732015-05-21 14:28:59 -0700807}
808
809// ===================================================================
810
811void ImmutableMessageLiteGenerator::GenerateDynamicMethodMergeFrom(
812 io::Printer* printer) {
813 printer->Print(
814 // Optimization: If other is the default instance, we know none of its
815 // fields are set so we can skip the merge.
Feng Xiaoeee38b02015-08-22 18:25:48 -0700816 "if (arg0 == $classname$.getDefaultInstance()) return this;\n"
817 "$classname$ other = ($classname$) arg0;\n",
Bo Yang5db21732015-05-21 14:28:59 -0700818 "classname", name_resolver_->GetImmutableClassName(descriptor_));
819
820 for (int i = 0; i < descriptor_->field_count(); i++) {
821 if (!descriptor_->field(i)->containing_oneof()) {
822 field_generators_.get(
823 descriptor_->field(i)).GenerateMergingCode(printer);
824 }
825 }
826
827 // Merge oneof fields.
828 for (int i = 0; i < descriptor_->oneof_decl_count(); ++i) {
829 printer->Print(
830 "switch (other.get$oneof_capitalized_name$Case()) {\n",
831 "oneof_capitalized_name",
832 context_->GetOneofGeneratorInfo(
833 descriptor_->oneof_decl(i))->capitalized_name);
834 printer->Indent();
835 for (int j = 0; j < descriptor_->oneof_decl(i)->field_count(); j++) {
836 const FieldDescriptor* field = descriptor_->oneof_decl(i)->field(j);
837 printer->Print(
838 "case $field_name$: {\n",
839 "field_name",
840 ToUpper(field->name()));
841 printer->Indent();
842 field_generators_.get(field).GenerateMergingCode(printer);
843 printer->Print(
844 "break;\n");
845 printer->Outdent();
846 printer->Print(
847 "}\n");
848 }
849 printer->Print(
850 "case $cap_oneof_name$_NOT_SET: {\n"
851 " break;\n"
852 "}\n",
853 "cap_oneof_name",
854 ToUpper(context_->GetOneofGeneratorInfo(
855 descriptor_->oneof_decl(i))->name));
856 printer->Outdent();
857 printer->Print(
858 "}\n");
859 }
860
861 // if message type has extensions
862 if (descriptor_->extension_range_count() > 0) {
863 printer->Print(
864 "this.mergeExtensionFields(other);\n");
865 }
866
867 if (PreserveUnknownFields(descriptor_)) {
868 printer->Print(
869 "this.mergeUnknownFields(other.unknownFields);\n");
870 }
871
872 printer->Print(
873 "return this;\n");
874}
875
876// ===================================================================
877
878namespace {
879bool CheckHasBitsForEqualsAndHashCode(const FieldDescriptor* field) {
880 if (field->is_repeated()) {
881 return false;
882 }
883 if (SupportFieldPresence(field->file())) {
884 return true;
885 }
886 return GetJavaType(field) == JAVATYPE_MESSAGE &&
887 field->containing_oneof() == NULL;
888}
889} // namespace
890
891void ImmutableMessageLiteGenerator::
892GenerateEqualsAndHashCode(io::Printer* printer) {
893 printer->Print(
894 "@java.lang.Override\n"
895 "public boolean equals(final java.lang.Object obj) {\n");
896 printer->Indent();
897 printer->Print(
898 "if (obj == this) {\n"
899 " return true;\n"
900 "}\n"
901 "if (!(obj instanceof $classname$)) {\n"
902 " return super.equals(obj);\n"
903 "}\n"
904 "$classname$ other = ($classname$) obj;\n"
905 "\n",
906 "classname", name_resolver_->GetImmutableClassName(descriptor_));
907
908 printer->Print("boolean result = true;\n");
909 for (int i = 0; i < descriptor_->field_count(); i++) {
910 const FieldDescriptor* field = descriptor_->field(i);
911 const FieldGeneratorInfo* info = context_->GetFieldGeneratorInfo(field);
912 bool check_has_bits = CheckHasBitsForEqualsAndHashCode(field);
913 if (check_has_bits) {
914 printer->Print(
915 "result = result && (has$name$() == other.has$name$());\n"
916 "if (has$name$()) {\n",
917 "name", info->capitalized_name);
918 printer->Indent();
919 }
920 field_generators_.get(field).GenerateEqualsCode(printer);
921 if (check_has_bits) {
922 printer->Outdent();
923 printer->Print(
924 "}\n");
925 }
926 }
927 if (PreserveUnknownFields(descriptor_)) {
928 // Always consider unknown fields for equality. This will sometimes return
929 // false for non-canonical ordering when running in LITE_RUNTIME but it's
930 // the best we can do.
931 printer->Print(
932 "result = result && unknownFields.equals(other.unknownFields);\n");
933 }
934 printer->Print(
935 "return result;\n");
936 printer->Outdent();
937 printer->Print(
938 "}\n"
939 "\n");
940
941 printer->Print(
942 "@java.lang.Override\n"
943 "public int hashCode() {\n");
944 printer->Indent();
945 printer->Print(
946 "if (memoizedHashCode != 0) {\n");
947 printer->Indent();
948 printer->Print(
949 "return memoizedHashCode;\n");
950 printer->Outdent();
951 printer->Print(
952 "}\n"
953 "int hash = 41;\n");
954
955 // Include the hash of the class so that two objects with different types
956 // but the same field values will probably have different hashes.
957 printer->Print("hash = (19 * hash) + $classname$.class.hashCode();\n",
958 "classname", name_resolver_->GetImmutableClassName(descriptor_));
959
960 for (int i = 0; i < descriptor_->field_count(); i++) {
961 const FieldDescriptor* field = descriptor_->field(i);
962 const FieldGeneratorInfo* info = context_->GetFieldGeneratorInfo(field);
963 bool check_has_bits = CheckHasBitsForEqualsAndHashCode(field);
964 if (check_has_bits) {
965 printer->Print(
966 "if (has$name$()) {\n",
967 "name", info->capitalized_name);
968 printer->Indent();
969 }
970 field_generators_.get(field).GenerateHashCode(printer);
971 if (check_has_bits) {
972 printer->Outdent();
973 printer->Print("}\n");
974 }
975 }
976
977 printer->Print(
978 "hash = (29 * hash) + unknownFields.hashCode();\n");
979 printer->Print(
980 "memoizedHashCode = hash;\n"
981 "return hash;\n");
982 printer->Outdent();
983 printer->Print(
984 "}\n"
985 "\n");
986}
987
988// ===================================================================
989
990void ImmutableMessageLiteGenerator::
991GenerateExtensionRegistrationCode(io::Printer* printer) {
992 for (int i = 0; i < descriptor_->extension_count(); i++) {
993 ImmutableExtensionGenerator(descriptor_->extension(i), context_)
994 .GenerateRegistrationCode(printer);
995 }
996
997 for (int i = 0; i < descriptor_->nested_type_count(); i++) {
998 ImmutableMessageLiteGenerator(descriptor_->nested_type(i), context_)
999 .GenerateExtensionRegistrationCode(printer);
1000 }
1001}
1002
1003// ===================================================================
1004void ImmutableMessageLiteGenerator::
1005GenerateParsingConstructor(io::Printer* printer) {
1006 google::protobuf::scoped_array<const FieldDescriptor * > sorted_fields(
1007 SortFieldsByNumber(descriptor_));
1008
1009 printer->Print(
1010 "private $classname$(\n"
1011 " com.google.protobuf.CodedInputStream input,\n"
1012 " com.google.protobuf.ExtensionRegistryLite extensionRegistry) {\n",
1013 "classname", descriptor_->name());
1014 printer->Indent();
1015
1016 // Initialize all fields to default.
1017 GenerateInitializers(printer);
1018
1019 // Use builder bits to track mutable repeated fields.
1020 int totalBuilderBits = 0;
1021 for (int i = 0; i < descriptor_->field_count(); i++) {
1022 const ImmutableFieldLiteGenerator& field =
1023 field_generators_.get(descriptor_->field(i));
1024 totalBuilderBits += field.GetNumBitsForBuilder();
1025 }
1026 int totalBuilderInts = (totalBuilderBits + 31) / 32;
1027 for (int i = 0; i < totalBuilderInts; i++) {
1028 printer->Print("int mutable_$bit_field_name$ = 0;\n",
1029 "bit_field_name", GetBitFieldName(i));
1030 }
1031
Bo Yang5db21732015-05-21 14:28:59 -07001032 printer->Print(
1033 "try {\n");
1034 printer->Indent();
1035
1036 printer->Print(
1037 "boolean done = false;\n"
1038 "while (!done) {\n");
1039 printer->Indent();
1040
1041 printer->Print(
1042 "int tag = input.readTag();\n"
1043 "switch (tag) {\n");
1044 printer->Indent();
1045
1046 printer->Print(
1047 "case 0:\n" // zero signals EOF / limit reached
1048 " done = true;\n"
1049 " break;\n");
1050
1051 if (PreserveUnknownFields(descriptor_)) {
1052 if (descriptor_->extension_range_count() > 0) {
Bo Yang5db21732015-05-21 14:28:59 -07001053 printer->Print(
1054 "default: {\n"
Jisi Liu46e8ff62015-10-05 11:59:43 -07001055 " if (!parseUnknownField(getDefaultInstanceForType(),\n"
1056 " input, extensionRegistry, tag)) {\n"
Bo Yang5db21732015-05-21 14:28:59 -07001057 " done = true;\n" // it's an endgroup tag
1058 " }\n"
1059 " break;\n"
1060 "}\n");
1061 } else {
1062 printer->Print(
1063 "default: {\n"
Jisi Liu46e8ff62015-10-05 11:59:43 -07001064 " if (!parseUnknownField(tag, input)) {\n"
Bo Yang5db21732015-05-21 14:28:59 -07001065 " done = true;\n" // it's an endgroup tag
1066 " }\n"
1067 " break;\n"
1068 "}\n");
1069 }
1070 } else {
1071 printer->Print(
1072 "default: {\n"
1073 " if (!input.skipField(tag)) {\n"
1074 " done = true;\n" // it's an endgroup tag
1075 " }\n"
1076 " break;\n"
1077 "}\n");
1078 }
1079
1080 for (int i = 0; i < descriptor_->field_count(); i++) {
1081 const FieldDescriptor* field = sorted_fields[i];
1082 uint32 tag = WireFormatLite::MakeTag(field->number(),
1083 WireFormat::WireTypeForFieldType(field->type()));
1084
1085 printer->Print(
1086 "case $tag$: {\n",
1087 "tag", SimpleItoa(tag));
1088 printer->Indent();
1089
1090 field_generators_.get(field).GenerateParsingCode(printer);
1091
1092 printer->Outdent();
1093 printer->Print(
1094 " break;\n"
1095 "}\n");
1096
1097 if (field->is_packable()) {
1098 // To make packed = true wire compatible, we generate parsing code from a
1099 // packed version of this field regardless of field->options().packed().
1100 uint32 packed_tag = WireFormatLite::MakeTag(field->number(),
1101 WireFormatLite::WIRETYPE_LENGTH_DELIMITED);
1102 printer->Print(
1103 "case $tag$: {\n",
1104 "tag", SimpleItoa(packed_tag));
1105 printer->Indent();
1106
1107 field_generators_.get(field).GenerateParsingCodeFromPacked(printer);
1108
1109 printer->Outdent();
1110 printer->Print(
1111 " break;\n"
1112 "}\n");
1113 }
1114 }
1115
1116 printer->Outdent();
1117 printer->Outdent();
1118 printer->Print(
1119 " }\n" // switch (tag)
1120 "}\n"); // while (!done)
1121
1122 printer->Outdent();
1123 printer->Print(
1124 "} catch (com.google.protobuf.InvalidProtocolBufferException e) {\n"
1125 " throw new RuntimeException(e.setUnfinishedMessage(this));\n"
1126 "} catch (java.io.IOException e) {\n"
1127 " throw new RuntimeException(\n"
1128 " new com.google.protobuf.InvalidProtocolBufferException(\n"
1129 " e.getMessage()).setUnfinishedMessage(this));\n"
1130 "} finally {\n");
1131 printer->Indent();
1132
1133 // Make repeated field list immutable.
1134 for (int i = 0; i < descriptor_->field_count(); i++) {
1135 const FieldDescriptor* field = sorted_fields[i];
1136 field_generators_.get(field).GenerateParsingDoneCode(printer);
1137 }
1138
Jisi Liu46e8ff62015-10-05 11:59:43 -07001139 printer->Print(
1140 "doneParsing();\n");
Bo Yang5db21732015-05-21 14:28:59 -07001141
1142 printer->Outdent();
1143 printer->Outdent();
1144 printer->Print(
1145 " }\n" // finally
1146 "}\n");
1147}
1148
1149// ===================================================================
1150void ImmutableMessageLiteGenerator::GenerateParser(io::Printer* printer) {
1151 printer->Print(
Feng Xiaoeee38b02015-08-22 18:25:48 -07001152 "private static volatile com.google.protobuf.Parser<$classname$> PARSER;\n"
1153 "\n"
1154 "public static com.google.protobuf.Parser<$classname$> parser() {\n"
1155 " return DEFAULT_INSTANCE.getParserForType();\n"
1156 "}\n",
Bo Yang5db21732015-05-21 14:28:59 -07001157 "classname", descriptor_->name());
1158}
1159
1160// ===================================================================
1161void ImmutableMessageLiteGenerator::GenerateInitializers(io::Printer* printer) {
1162 for (int i = 0; i < descriptor_->field_count(); i++) {
1163 if (!descriptor_->field(i)->containing_oneof()) {
1164 field_generators_.get(descriptor_->field(i))
1165 .GenerateInitializationCode(printer);
1166 }
1167 }
1168}
1169
1170
1171} // namespace java
1172} // namespace compiler
1173} // namespace protobuf
1174} // namespace google