blob: 1b86d2a9b8f3f8fcbdbf93240aeba19e41ebc7ba [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_builder.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_name_resolver.h>
53#include <google/protobuf/io/coded_stream.h>
54#include <google/protobuf/io/printer.h>
55#include <google/protobuf/descriptor.pb.h>
56#include <google/protobuf/wire_format.h>
57#include <google/protobuf/stubs/strutil.h>
58#include <google/protobuf/stubs/substitute.h>
59
60namespace google {
61namespace protobuf {
62namespace compiler {
63namespace java {
64
65namespace {
66bool GenerateHasBits(const Descriptor* descriptor) {
67 return SupportFieldPresence(descriptor->file()) ||
68 HasRepeatedFields(descriptor);
69}
70
71string MapValueImmutableClassdName(const Descriptor* descriptor,
72 ClassNameResolver* name_resolver) {
73 const FieldDescriptor* value_field = descriptor->FindFieldByName("value");
74 GOOGLE_CHECK_EQ(FieldDescriptor::TYPE_MESSAGE, value_field->type());
75 return name_resolver->GetImmutableClassName(value_field->message_type());
76}
77} // namespace
78
79MessageBuilderGenerator::MessageBuilderGenerator(
80 const Descriptor* descriptor, Context* context)
81 : descriptor_(descriptor), context_(context),
82 name_resolver_(context->GetNameResolver()),
83 field_generators_(descriptor, context_) {
84 GOOGLE_CHECK_NE(
85 FileOptions::LITE_RUNTIME, descriptor->file()->options().optimize_for());
86}
87
88MessageBuilderGenerator::~MessageBuilderGenerator() {}
89
90void MessageBuilderGenerator::
91Generate(io::Printer* printer) {
92 WriteMessageDocComment(printer, descriptor_);
93 if (descriptor_->extension_range_count() > 0) {
94 printer->Print(
95 "public static final class Builder extends\n"
96 " com.google.protobuf.GeneratedMessage.ExtendableBuilder<\n"
97 " $classname$, Builder> implements\n"
98 " $extra_interfaces$\n"
99 " $classname$OrBuilder {\n",
100 "classname", name_resolver_->GetImmutableClassName(descriptor_),
101 "extra_interfaces", ExtraBuilderInterfaces(descriptor_));
102 } else {
103 printer->Print(
104 "public static final class Builder extends\n"
105 " com.google.protobuf.GeneratedMessage.Builder<Builder> implements\n"
106 " $extra_interfaces$\n"
107 " $classname$OrBuilder {\n",
108 "classname", name_resolver_->GetImmutableClassName(descriptor_),
109 "extra_interfaces", ExtraBuilderInterfaces(descriptor_));
110 }
111 printer->Indent();
112
113 GenerateDescriptorMethods(printer);
114 GenerateCommonBuilderMethods(printer);
115
116 if (HasGeneratedMethods(descriptor_)) {
117 GenerateIsInitialized(printer);
118 GenerateBuilderParsingMethods(printer);
119 }
120
121 // oneof
122 map<string, string> vars;
123 for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
124 vars["oneof_name"] = context_->GetOneofGeneratorInfo(
125 descriptor_->oneof_decl(i))->name;
126 vars["oneof_capitalized_name"] = context_->GetOneofGeneratorInfo(
127 descriptor_->oneof_decl(i))->capitalized_name;
128 vars["oneof_index"] = SimpleItoa(descriptor_->oneof_decl(i)->index());
129 // oneofCase_ and oneof_
130 printer->Print(vars,
131 "private int $oneof_name$Case_ = 0;\n"
132 "private java.lang.Object $oneof_name$_;\n");
133 // oneofCase() and clearOneof()
134 printer->Print(vars,
135 "public $oneof_capitalized_name$Case\n"
136 " get$oneof_capitalized_name$Case() {\n"
Jie Luoc6120742016-04-06 14:24:45 -0700137 " return $oneof_capitalized_name$Case.forNumber(\n"
Bo Yang5db21732015-05-21 14:28:59 -0700138 " $oneof_name$Case_);\n"
139 "}\n"
140 "\n"
141 "public Builder clear$oneof_capitalized_name$() {\n"
142 " $oneof_name$Case_ = 0;\n"
143 " $oneof_name$_ = null;\n");
144 printer->Print(" onChanged();\n");
145 printer->Print(
146 " return this;\n"
147 "}\n"
148 "\n");
149 }
150
151 if (GenerateHasBits(descriptor_)) {
152 // Integers for bit fields.
153 int totalBits = 0;
154 for (int i = 0; i < descriptor_->field_count(); i++) {
155 totalBits += field_generators_.get(descriptor_->field(i))
156 .GetNumBitsForBuilder();
157 }
158 int totalInts = (totalBits + 31) / 32;
159 for (int i = 0; i < totalInts; i++) {
160 printer->Print("private int $bit_field_name$;\n",
161 "bit_field_name", GetBitFieldName(i));
162 }
163 }
164
165 for (int i = 0; i < descriptor_->field_count(); i++) {
166 printer->Print("\n");
167 field_generators_.get(descriptor_->field(i))
168 .GenerateBuilderMembers(printer);
169 }
170
171 if (!PreserveUnknownFields(descriptor_)) {
172 printer->Print(
173 "public final Builder setUnknownFields(\n"
174 " final com.google.protobuf.UnknownFieldSet unknownFields) {\n"
175 " return this;\n"
176 "}\n"
177 "\n"
178 "public final Builder mergeUnknownFields(\n"
179 " final com.google.protobuf.UnknownFieldSet unknownFields) {\n"
180 " return this;\n"
181 "}\n"
182 "\n");
183 }
184
185 printer->Print(
186 "\n"
187 "// @@protoc_insertion_point(builder_scope:$full_name$)\n",
188 "full_name", descriptor_->full_name());
189
190 printer->Outdent();
191 printer->Print("}\n");
192}
193
194// ===================================================================
195
196void MessageBuilderGenerator::
197GenerateDescriptorMethods(io::Printer* printer) {
198 if (!descriptor_->options().no_standard_descriptor_accessor()) {
199 printer->Print(
200 "public static final com.google.protobuf.Descriptors.Descriptor\n"
201 " getDescriptor() {\n"
202 " return $fileclass$.internal_$identifier$_descriptor;\n"
203 "}\n"
204 "\n",
205 "fileclass", name_resolver_->GetImmutableClassName(descriptor_->file()),
206 "identifier", UniqueFileScopeIdentifier(descriptor_));
207 }
208 vector<const FieldDescriptor*> map_fields;
209 for (int i = 0; i < descriptor_->field_count(); i++) {
210 const FieldDescriptor* field = descriptor_->field(i);
211 if (GetJavaType(field) == JAVATYPE_MESSAGE &&
212 IsMapEntry(field->message_type())) {
213 map_fields.push_back(field);
214 }
215 }
216 if (!map_fields.empty()) {
217 printer->Print(
218 "@SuppressWarnings({\"rawtypes\"})\n"
219 "protected com.google.protobuf.MapField internalGetMapField(\n"
220 " int number) {\n"
221 " switch (number) {\n");
222 printer->Indent();
223 printer->Indent();
224 for (int i = 0; i < map_fields.size(); ++i) {
225 const FieldDescriptor* field = map_fields[i];
226 const FieldGeneratorInfo* info = context_->GetFieldGeneratorInfo(field);
227 printer->Print(
228 "case $number$:\n"
229 " return internalGet$capitalized_name$();\n",
230 "number", SimpleItoa(field->number()),
231 "capitalized_name", info->capitalized_name);
232 }
233 printer->Print(
234 "default:\n"
235 " throw new RuntimeException(\n"
236 " \"Invalid map field number: \" + number);\n");
237 printer->Outdent();
238 printer->Outdent();
239 printer->Print(
240 " }\n"
241 "}\n");
242 printer->Print(
243 "@SuppressWarnings({\"rawtypes\"})\n"
244 "protected com.google.protobuf.MapField internalGetMutableMapField(\n"
245 " int number) {\n"
246 " switch (number) {\n");
247 printer->Indent();
248 printer->Indent();
249 for (int i = 0; i < map_fields.size(); ++i) {
250 const FieldDescriptor* field = map_fields[i];
251 const FieldGeneratorInfo* info =
252 context_->GetFieldGeneratorInfo(field);
253 printer->Print(
254 "case $number$:\n"
255 " return internalGetMutable$capitalized_name$();\n",
256 "number", SimpleItoa(field->number()),
257 "capitalized_name", info->capitalized_name);
258 }
259 printer->Print(
260 "default:\n"
261 " throw new RuntimeException(\n"
262 " \"Invalid map field number: \" + number);\n");
263 printer->Outdent();
264 printer->Outdent();
265 printer->Print(
266 " }\n"
267 "}\n");
268 }
269 printer->Print(
270 "protected com.google.protobuf.GeneratedMessage.FieldAccessorTable\n"
271 " internalGetFieldAccessorTable() {\n"
272 " return $fileclass$.internal_$identifier$_fieldAccessorTable\n"
273 " .ensureFieldAccessorsInitialized(\n"
274 " $classname$.class, $classname$.Builder.class);\n"
275 "}\n"
276 "\n",
277 "classname", name_resolver_->GetImmutableClassName(descriptor_),
278 "fileclass", name_resolver_->GetImmutableClassName(descriptor_->file()),
279 "identifier", UniqueFileScopeIdentifier(descriptor_));
280}
281
282// ===================================================================
283
284void MessageBuilderGenerator::
285GenerateCommonBuilderMethods(io::Printer* printer) {
286 printer->Print(
287 "// Construct using $classname$.newBuilder()\n"
288 "private Builder() {\n"
289 " maybeForceBuilderInitialization();\n"
290 "}\n"
291 "\n",
292 "classname", name_resolver_->GetImmutableClassName(descriptor_));
293
294 printer->Print(
295 "private Builder(\n"
296 " com.google.protobuf.GeneratedMessage.BuilderParent parent) {\n"
297 " super(parent);\n"
298 " maybeForceBuilderInitialization();\n"
299 "}\n",
300 "classname", name_resolver_->GetImmutableClassName(descriptor_));
301
302 printer->Print(
303 "private void maybeForceBuilderInitialization() {\n"
304 " if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {\n");
305
306 printer->Indent();
307 printer->Indent();
308 for (int i = 0; i < descriptor_->field_count(); i++) {
309 if (!descriptor_->field(i)->containing_oneof()) {
310 field_generators_.get(descriptor_->field(i))
311 .GenerateFieldBuilderInitializationCode(printer);
312 }
313 }
314 printer->Outdent();
315 printer->Outdent();
316
317 printer->Print(
318 " }\n"
319 "}\n");
320
321 printer->Print(
322 "public Builder clear() {\n"
323 " super.clear();\n");
324
325 printer->Indent();
326
327 for (int i = 0; i < descriptor_->field_count(); i++) {
328 if (!descriptor_->field(i)->containing_oneof()) {
329 field_generators_.get(descriptor_->field(i))
330 .GenerateBuilderClearCode(printer);
331 }
332 }
333
334 for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
335 printer->Print(
336 "$oneof_name$Case_ = 0;\n"
337 "$oneof_name$_ = null;\n",
338 "oneof_name", context_->GetOneofGeneratorInfo(
339 descriptor_->oneof_decl(i))->name);
340 }
341
342 printer->Outdent();
343
344 printer->Print(
345 " return this;\n"
346 "}\n"
347 "\n");
348
349 printer->Print(
350 "public com.google.protobuf.Descriptors.Descriptor\n"
351 " getDescriptorForType() {\n"
352 " return $fileclass$.internal_$identifier$_descriptor;\n"
353 "}\n"
354 "\n",
355 "fileclass", name_resolver_->GetImmutableClassName(descriptor_->file()),
356 "identifier", UniqueFileScopeIdentifier(descriptor_));
357
358 // LITE runtime implements this in GeneratedMessageLite.
359 printer->Print(
360 "public $classname$ getDefaultInstanceForType() {\n"
361 " return $classname$.getDefaultInstance();\n"
362 "}\n"
363 "\n",
364 "classname", name_resolver_->GetImmutableClassName(descriptor_));
365
366 printer->Print(
367 "public $classname$ build() {\n"
368 " $classname$ result = buildPartial();\n"
369 " if (!result.isInitialized()) {\n"
370 " throw newUninitializedMessageException(result);\n"
371 " }\n"
372 " return result;\n"
373 "}\n"
374 "\n",
375 "classname", name_resolver_->GetImmutableClassName(descriptor_));
376
377 printer->Print(
378 "public $classname$ buildPartial() {\n"
379 " $classname$ result = new $classname$(this);\n",
380 "classname", name_resolver_->GetImmutableClassName(descriptor_));
381
382 printer->Indent();
383
384 int totalBuilderBits = 0;
385 int totalMessageBits = 0;
386 for (int i = 0; i < descriptor_->field_count(); i++) {
387 const ImmutableFieldGenerator& field =
388 field_generators_.get(descriptor_->field(i));
389 totalBuilderBits += field.GetNumBitsForBuilder();
390 totalMessageBits += field.GetNumBitsForMessage();
391 }
392 int totalBuilderInts = (totalBuilderBits + 31) / 32;
393 int totalMessageInts = (totalMessageBits + 31) / 32;
394
395 if (GenerateHasBits(descriptor_)) {
396 // Local vars for from and to bit fields to avoid accessing the builder and
397 // message over and over for these fields. Seems to provide a slight
398 // perforamance improvement in micro benchmark and this is also what proto1
399 // code does.
400 for (int i = 0; i < totalBuilderInts; i++) {
401 printer->Print("int from_$bit_field_name$ = $bit_field_name$;\n",
402 "bit_field_name", GetBitFieldName(i));
403 }
404 for (int i = 0; i < totalMessageInts; i++) {
405 printer->Print("int to_$bit_field_name$ = 0;\n",
406 "bit_field_name", GetBitFieldName(i));
407 }
408 }
409
410 // Output generation code for each field.
411 for (int i = 0; i < descriptor_->field_count(); i++) {
412 field_generators_.get(descriptor_->field(i)).GenerateBuildingCode(printer);
413 }
414
415 if (GenerateHasBits(descriptor_)) {
416 // Copy the bit field results to the generated message
417 for (int i = 0; i < totalMessageInts; i++) {
418 printer->Print("result.$bit_field_name$ = to_$bit_field_name$;\n",
419 "bit_field_name", GetBitFieldName(i));
420 }
421 }
422
423 for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
424 printer->Print("result.$oneof_name$Case_ = $oneof_name$Case_;\n",
425 "oneof_name", context_->GetOneofGeneratorInfo(
426 descriptor_->oneof_decl(i))->name);
427 }
428
429 printer->Outdent();
430
431 printer->Print(
432 " onBuilt();\n");
433
434 printer->Print(
435 " return result;\n"
436 "}\n"
437 "\n",
438 "classname", name_resolver_->GetImmutableClassName(descriptor_));
439
440 // -----------------------------------------------------------------
441
442 if (HasGeneratedMethods(descriptor_)) {
443 printer->Print(
444 "public Builder mergeFrom(com.google.protobuf.Message other) {\n"
445 " if (other instanceof $classname$) {\n"
446 " return mergeFrom(($classname$)other);\n"
447 " } else {\n"
448 " super.mergeFrom(other);\n"
449 " return this;\n"
450 " }\n"
451 "}\n"
452 "\n",
453 "classname", name_resolver_->GetImmutableClassName(descriptor_));
454
455 printer->Print(
456 "public Builder mergeFrom($classname$ other) {\n"
457 // Optimization: If other is the default instance, we know none of its
458 // fields are set so we can skip the merge.
459 " if (other == $classname$.getDefaultInstance()) return this;\n",
460 "classname", name_resolver_->GetImmutableClassName(descriptor_));
461 printer->Indent();
462
463 for (int i = 0; i < descriptor_->field_count(); i++) {
464 if (!descriptor_->field(i)->containing_oneof()) {
465 field_generators_.get(
466 descriptor_->field(i)).GenerateMergingCode(printer);
467 }
468 }
469
470 // Merge oneof fields.
471 for (int i = 0; i < descriptor_->oneof_decl_count(); ++i) {
472 printer->Print(
473 "switch (other.get$oneof_capitalized_name$Case()) {\n",
474 "oneof_capitalized_name",
475 context_->GetOneofGeneratorInfo(
476 descriptor_->oneof_decl(i))->capitalized_name);
477 printer->Indent();
478 for (int j = 0; j < descriptor_->oneof_decl(i)->field_count(); j++) {
479 const FieldDescriptor* field = descriptor_->oneof_decl(i)->field(j);
480 printer->Print(
481 "case $field_name$: {\n",
482 "field_name",
483 ToUpper(field->name()));
484 printer->Indent();
485 field_generators_.get(field).GenerateMergingCode(printer);
486 printer->Print(
487 "break;\n");
488 printer->Outdent();
489 printer->Print(
490 "}\n");
491 }
492 printer->Print(
493 "case $cap_oneof_name$_NOT_SET: {\n"
494 " break;\n"
495 "}\n",
496 "cap_oneof_name",
497 ToUpper(context_->GetOneofGeneratorInfo(
498 descriptor_->oneof_decl(i))->name));
499 printer->Outdent();
500 printer->Print(
501 "}\n");
502 }
503
504 printer->Outdent();
505
506 // if message type has extensions
507 if (descriptor_->extension_range_count() > 0) {
508 printer->Print(
509 " this.mergeExtensionFields(other);\n");
510 }
511
512 if (PreserveUnknownFields(descriptor_)) {
513 printer->Print(
514 " this.mergeUnknownFields(other.unknownFields);\n");
515 }
516
517 printer->Print(
518 " onChanged();\n");
519
520 printer->Print(
521 " return this;\n"
522 "}\n"
523 "\n");
524 }
525}
526
527// ===================================================================
528
529void MessageBuilderGenerator::
530GenerateBuilderParsingMethods(io::Printer* printer) {
531 printer->Print(
532 "public Builder mergeFrom(\n"
533 " com.google.protobuf.CodedInputStream input,\n"
534 " com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n"
535 " throws java.io.IOException {\n"
536 " $classname$ parsedMessage = null;\n"
537 " try {\n"
538 " parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);\n"
539 " } catch (com.google.protobuf.InvalidProtocolBufferException e) {\n"
540 " parsedMessage = ($classname$) e.getUnfinishedMessage();\n"
541 " throw e;\n"
542 " } finally {\n"
543 " if (parsedMessage != null) {\n"
544 " mergeFrom(parsedMessage);\n"
545 " }\n"
546 " }\n"
547 " return this;\n"
548 "}\n",
549 "classname", name_resolver_->GetImmutableClassName(descriptor_));
550}
551
552// ===================================================================
553
554void MessageBuilderGenerator::GenerateIsInitialized(
555 io::Printer* printer) {
556 printer->Print(
557 "public final boolean isInitialized() {\n");
558 printer->Indent();
559
560 // Check that all required fields in this message are set.
561 // TODO(kenton): We can optimize this when we switch to putting all the
562 // "has" fields into a single bitfield.
563 for (int i = 0; i < descriptor_->field_count(); i++) {
564 const FieldDescriptor* field = descriptor_->field(i);
565 const FieldGeneratorInfo* info = context_->GetFieldGeneratorInfo(field);
566
567 if (field->is_required()) {
568 printer->Print(
569 "if (!has$name$()) {\n"
570 " return false;\n"
571 "}\n",
572 "name", info->capitalized_name);
573 }
574 }
575
576 // Now check that all embedded messages are initialized.
577 for (int i = 0; i < descriptor_->field_count(); i++) {
578 const FieldDescriptor* field = descriptor_->field(i);
579 const FieldGeneratorInfo* info = context_->GetFieldGeneratorInfo(field);
580 if (GetJavaType(field) == JAVATYPE_MESSAGE &&
581 HasRequiredFields(field->message_type())) {
582 switch (field->label()) {
583 case FieldDescriptor::LABEL_REQUIRED:
584 printer->Print(
585 "if (!get$name$().isInitialized()) {\n"
586 " return false;\n"
587 "}\n",
588 "type", name_resolver_->GetImmutableClassName(
589 field->message_type()),
590 "name", info->capitalized_name);
591 break;
592 case FieldDescriptor::LABEL_OPTIONAL:
593 if (!SupportFieldPresence(descriptor_->file()) &&
594 field->containing_oneof() != NULL) {
595 const OneofDescriptor* oneof = field->containing_oneof();
596 const OneofGeneratorInfo* oneof_info =
597 context_->GetOneofGeneratorInfo(oneof);
598 printer->Print(
599 "if ($oneof_name$Case_ == $field_number$) {\n",
600 "oneof_name", oneof_info->name,
601 "field_number", SimpleItoa(field->number()));
602 } else {
603 printer->Print(
604 "if (has$name$()) {\n",
605 "name", info->capitalized_name);
606 }
607 printer->Print(
608 " if (!get$name$().isInitialized()) {\n"
609 " return false;\n"
610 " }\n"
611 "}\n",
612 "name", info->capitalized_name);
613 break;
614 case FieldDescriptor::LABEL_REPEATED:
615 if (IsMapEntry(field->message_type())) {
616 printer->Print(
617 "for ($type$ item : get$name$().values()) {\n"
618 " if (!item.isInitialized()) {\n"
619 " return false;\n"
620 " }\n"
621 "}\n",
622 "type", MapValueImmutableClassdName(field->message_type(),
623 name_resolver_),
624 "name", info->capitalized_name);
625 } else {
626 printer->Print(
627 "for (int i = 0; i < get$name$Count(); i++) {\n"
628 " if (!get$name$(i).isInitialized()) {\n"
629 " return false;\n"
630 " }\n"
631 "}\n",
632 "type", name_resolver_->GetImmutableClassName(
633 field->message_type()),
634 "name", info->capitalized_name);
635 }
636 break;
637 }
638 }
639 }
640
641 if (descriptor_->extension_range_count() > 0) {
642 printer->Print(
643 "if (!extensionsAreInitialized()) {\n"
644 " return false;\n"
645 "}\n");
646 }
647
648 printer->Outdent();
649
650 printer->Print(
651 " return true;\n"
652 "}\n"
653 "\n");
654}
655
656// ===================================================================
657
658} // namespace java
659} // namespace compiler
660} // namespace protobuf
661} // namespace google