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