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: 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 <map>
39 #include <memory>
40 #include <vector>
41
42 #include <google/protobuf/compiler/java/java_context.h>
43 #include <google/protobuf/compiler/java/java_doc_comment.h>
44 #include <google/protobuf/compiler/java/java_enum.h>
45 #include <google/protobuf/compiler/java/java_extension.h>
46 #include <google/protobuf/compiler/java/java_generator_factory.h>
47 #include <google/protobuf/compiler/java/java_helpers.h>
48 #include <google/protobuf/compiler/java/java_name_resolver.h>
49 #include <google/protobuf/descriptor.pb.h>
50 #include <google/protobuf/io/coded_stream.h>
51 #include <google/protobuf/io/printer.h>
52 #include <google/protobuf/wire_format.h>
53 #include <google/protobuf/stubs/strutil.h>
54 #include <google/protobuf/stubs/substitute.h>
55
56 namespace google {
57 namespace protobuf {
58 namespace compiler {
59 namespace java {
60
61 using internal::WireFormat;
62 using internal::WireFormatLite;
63
64 namespace {
MapValueImmutableClassdName(const Descriptor * descriptor,ClassNameResolver * name_resolver)65 std::string MapValueImmutableClassdName(const Descriptor* descriptor,
66 ClassNameResolver* name_resolver) {
67 const FieldDescriptor* value_field = descriptor->FindFieldByName("value");
68 GOOGLE_CHECK_EQ(FieldDescriptor::TYPE_MESSAGE, value_field->type());
69 return name_resolver->GetImmutableClassName(value_field->message_type());
70 }
71 } // namespace
72
MessageBuilderGenerator(const Descriptor * descriptor,Context * context)73 MessageBuilderGenerator::MessageBuilderGenerator(const Descriptor* descriptor,
74 Context* context)
75 : descriptor_(descriptor),
76 context_(context),
77 name_resolver_(context->GetNameResolver()),
78 field_generators_(descriptor, context_) {
79 GOOGLE_CHECK(HasDescriptorMethods(descriptor->file(), context->EnforceLite()))
80 << "Generator factory error: A non-lite message generator is used to "
81 "generate lite messages.";
82 for (int i = 0; i < descriptor_->field_count(); i++) {
83 if (IsRealOneof(descriptor_->field(i))) {
84 oneofs_.insert(descriptor_->field(i)->containing_oneof());
85 }
86 }
87 }
88
~MessageBuilderGenerator()89 MessageBuilderGenerator::~MessageBuilderGenerator() {}
90
Generate(io::Printer * printer)91 void MessageBuilderGenerator::Generate(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$ver$.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_), "ver",
102 GeneratedCodeVersionSuffix());
103 } else {
104 printer->Print(
105 "public static final class Builder extends\n"
106 " com.google.protobuf.GeneratedMessage$ver$.Builder<Builder> "
107 "implements\n"
108 " $extra_interfaces$\n"
109 " $classname$OrBuilder {\n",
110 "classname", name_resolver_->GetImmutableClassName(descriptor_),
111 "extra_interfaces", ExtraBuilderInterfaces(descriptor_), "ver",
112 GeneratedCodeVersionSuffix());
113 }
114 printer->Indent();
115
116 GenerateDescriptorMethods(printer);
117 GenerateCommonBuilderMethods(printer);
118
119 if (context_->HasGeneratedMethods(descriptor_)) {
120 GenerateIsInitialized(printer);
121 GenerateBuilderParsingMethods(printer);
122 }
123
124 // oneof
125 std::map<std::string, std::string> vars;
126 for (auto oneof : oneofs_) {
127 vars["oneof_name"] = context_->GetOneofGeneratorInfo(oneof)->name;
128 vars["oneof_capitalized_name"] =
129 context_->GetOneofGeneratorInfo(oneof)->capitalized_name;
130 vars["oneof_index"] = StrCat(oneof->index());
131 // oneofCase_ and oneof_
132 printer->Print(vars,
133 "private int $oneof_name$Case_ = 0;\n"
134 "private java.lang.Object $oneof_name$_;\n");
135 // oneofCase() and clearOneof()
136 printer->Print(vars,
137 "public $oneof_capitalized_name$Case\n"
138 " get$oneof_capitalized_name$Case() {\n"
139 " return $oneof_capitalized_name$Case.forNumber(\n"
140 " $oneof_name$Case_);\n"
141 "}\n"
142 "\n"
143 "public Builder clear$oneof_capitalized_name$() {\n"
144 " $oneof_name$Case_ = 0;\n"
145 " $oneof_name$_ = null;\n");
146 printer->Print(" onChanged();\n");
147 printer->Print(
148 " return this;\n"
149 "}\n"
150 "\n");
151 }
152
153 // Integers for bit fields.
154 int totalBits = 0;
155 for (int i = 0; i < descriptor_->field_count(); i++) {
156 totalBits +=
157 field_generators_.get(descriptor_->field(i)).GetNumBitsForBuilder();
158 }
159 int totalInts = (totalBits + 31) / 32;
160 for (int i = 0; i < totalInts; i++) {
161 printer->Print("private int $bit_field_name$;\n", "bit_field_name",
162 GetBitFieldName(i));
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 // Override methods declared in GeneratedMessage to return the concrete
172 // generated type so callsites won't depend on GeneratedMessage. This
173 // is needed to keep binary compatibility when we change generated code
174 // to subclass a different GeneratedMessage class (e.g., in v3.0.0 release
175 // we changed all generated code to subclass GeneratedMessageV3).
176 printer->Print(
177 "@java.lang.Override\n"
178 "public final Builder setUnknownFields(\n"
179 " final com.google.protobuf.UnknownFieldSet unknownFields) {\n"
180 " return super.setUnknownFields(unknownFields);\n"
181 "}\n"
182 "\n"
183 "@java.lang.Override\n"
184 "public final Builder mergeUnknownFields(\n"
185 " final com.google.protobuf.UnknownFieldSet unknownFields) {\n"
186 " return super.mergeUnknownFields(unknownFields);\n"
187 "}\n"
188 "\n");
189
190 printer->Print(
191 "\n"
192 "// @@protoc_insertion_point(builder_scope:$full_name$)\n",
193 "full_name", descriptor_->full_name());
194
195 printer->Outdent();
196 printer->Print("}\n");
197 }
198
199 // ===================================================================
200
GenerateDescriptorMethods(io::Printer * printer)201 void MessageBuilderGenerator::GenerateDescriptorMethods(io::Printer* printer) {
202 if (!descriptor_->options().no_standard_descriptor_accessor()) {
203 printer->Print(
204 "public static final com.google.protobuf.Descriptors.Descriptor\n"
205 " getDescriptor() {\n"
206 " return $fileclass$.internal_$identifier$_descriptor;\n"
207 "}\n"
208 "\n",
209 "fileclass", name_resolver_->GetImmutableClassName(descriptor_->file()),
210 "identifier", UniqueFileScopeIdentifier(descriptor_));
211 }
212 std::vector<const FieldDescriptor*> map_fields;
213 for (int i = 0; i < descriptor_->field_count(); i++) {
214 const FieldDescriptor* field = descriptor_->field(i);
215 if (GetJavaType(field) == JAVATYPE_MESSAGE &&
216 IsMapEntry(field->message_type())) {
217 map_fields.push_back(field);
218 }
219 }
220 if (!map_fields.empty()) {
221 printer->Print(
222 "@SuppressWarnings({\"rawtypes\"})\n"
223 "protected com.google.protobuf.MapField internalGetMapField(\n"
224 " int number) {\n"
225 " switch (number) {\n");
226 printer->Indent();
227 printer->Indent();
228 for (int i = 0; i < map_fields.size(); ++i) {
229 const FieldDescriptor* field = map_fields[i];
230 const FieldGeneratorInfo* info = context_->GetFieldGeneratorInfo(field);
231 printer->Print(
232 "case $number$:\n"
233 " return internalGet$capitalized_name$();\n",
234 "number", StrCat(field->number()), "capitalized_name",
235 info->capitalized_name);
236 }
237 printer->Print(
238 "default:\n"
239 " throw new RuntimeException(\n"
240 " \"Invalid map field number: \" + number);\n");
241 printer->Outdent();
242 printer->Outdent();
243 printer->Print(
244 " }\n"
245 "}\n");
246 printer->Print(
247 "@SuppressWarnings({\"rawtypes\"})\n"
248 "protected com.google.protobuf.MapField internalGetMutableMapField(\n"
249 " int number) {\n"
250 " switch (number) {\n");
251 printer->Indent();
252 printer->Indent();
253 for (int i = 0; i < map_fields.size(); ++i) {
254 const FieldDescriptor* field = map_fields[i];
255 const FieldGeneratorInfo* info = context_->GetFieldGeneratorInfo(field);
256 printer->Print(
257 "case $number$:\n"
258 " return internalGetMutable$capitalized_name$();\n",
259 "number", StrCat(field->number()), "capitalized_name",
260 info->capitalized_name);
261 }
262 printer->Print(
263 "default:\n"
264 " throw new RuntimeException(\n"
265 " \"Invalid map field number: \" + number);\n");
266 printer->Outdent();
267 printer->Outdent();
268 printer->Print(
269 " }\n"
270 "}\n");
271 }
272 printer->Print(
273 "@java.lang.Override\n"
274 "protected com.google.protobuf.GeneratedMessage$ver$.FieldAccessorTable\n"
275 " internalGetFieldAccessorTable() {\n"
276 " return $fileclass$.internal_$identifier$_fieldAccessorTable\n"
277 " .ensureFieldAccessorsInitialized(\n"
278 " $classname$.class, $classname$.Builder.class);\n"
279 "}\n"
280 "\n",
281 "classname", name_resolver_->GetImmutableClassName(descriptor_),
282 "fileclass", name_resolver_->GetImmutableClassName(descriptor_->file()),
283 "identifier", UniqueFileScopeIdentifier(descriptor_), "ver",
284 GeneratedCodeVersionSuffix());
285 }
286
287 // ===================================================================
288
GenerateCommonBuilderMethods(io::Printer * printer)289 void MessageBuilderGenerator::GenerateCommonBuilderMethods(
290 io::Printer* printer) {
291 // Decide if we really need to have the "maybeForceBuilderInitialization()"
292 // method.
293 // TODO(b/249158148): Remove the need for this entirely
294 bool need_maybe_force_builder_init = false;
295 for (int i = 0; i < descriptor_->field_count(); i++) {
296 if (descriptor_->field(i)->message_type() != nullptr &&
297 !IsRealOneof(descriptor_->field(i)) &&
298 HasHasbit(descriptor_->field(i))) {
299 need_maybe_force_builder_init = true;
300 break;
301 }
302 }
303
304 const char* force_builder_init = need_maybe_force_builder_init
305 ? " maybeForceBuilderInitialization();"
306 : "";
307
308 printer->Print(
309 "// Construct using $classname$.newBuilder()\n"
310 "private Builder() {\n"
311 "$force_builder_init$\n"
312 "}\n"
313 "\n",
314 "classname", name_resolver_->GetImmutableClassName(descriptor_),
315 "force_builder_init", force_builder_init);
316
317 printer->Print(
318 "private Builder(\n"
319 " com.google.protobuf.GeneratedMessage$ver$.BuilderParent parent) {\n"
320 " super(parent);\n"
321 "$force_builder_init$\n"
322 "}\n",
323 "classname", name_resolver_->GetImmutableClassName(descriptor_), "ver",
324 GeneratedCodeVersionSuffix(), "force_builder_init", force_builder_init);
325
326 if (need_maybe_force_builder_init) {
327 printer->Print(
328 "private void maybeForceBuilderInitialization() {\n"
329 " if (com.google.protobuf.GeneratedMessage$ver$\n"
330 " .alwaysUseFieldBuilders) {\n",
331 "ver", GeneratedCodeVersionSuffix());
332
333 printer->Indent();
334 printer->Indent();
335 for (int i = 0; i < descriptor_->field_count(); i++) {
336 if (!IsRealOneof(descriptor_->field(i))) {
337 field_generators_.get(descriptor_->field(i))
338 .GenerateFieldBuilderInitializationCode(printer);
339 }
340 }
341 printer->Outdent();
342 printer->Outdent();
343
344 printer->Print(
345 " }\n"
346 "}\n");
347 }
348
349 printer->Print(
350 "@java.lang.Override\n"
351 "public Builder clear() {\n"
352 " super.clear();\n");
353
354 printer->Indent();
355
356 for (int i = 0; i < descriptor_->field_count(); i++) {
357 field_generators_.get(descriptor_->field(i))
358 .GenerateBuilderClearCode(printer);
359 }
360
361 for (auto oneof : oneofs_) {
362 printer->Print(
363 "$oneof_name$Case_ = 0;\n"
364 "$oneof_name$_ = null;\n",
365 "oneof_name", context_->GetOneofGeneratorInfo(oneof)->name);
366 }
367
368 printer->Outdent();
369
370 printer->Print(
371 " return this;\n"
372 "}\n"
373 "\n");
374
375 printer->Print(
376 "@java.lang.Override\n"
377 "public com.google.protobuf.Descriptors.Descriptor\n"
378 " getDescriptorForType() {\n"
379 " return $fileclass$.internal_$identifier$_descriptor;\n"
380 "}\n"
381 "\n",
382 "fileclass", name_resolver_->GetImmutableClassName(descriptor_->file()),
383 "identifier", UniqueFileScopeIdentifier(descriptor_));
384
385 // LITE runtime implements this in GeneratedMessageLite.
386 printer->Print(
387 "@java.lang.Override\n"
388 "public $classname$ getDefaultInstanceForType() {\n"
389 " return $classname$.getDefaultInstance();\n"
390 "}\n"
391 "\n",
392 "classname", name_resolver_->GetImmutableClassName(descriptor_));
393
394 printer->Print(
395 "@java.lang.Override\n"
396 "public $classname$ build() {\n"
397 " $classname$ result = buildPartial();\n"
398 " if (!result.isInitialized()) {\n"
399 " throw newUninitializedMessageException(result);\n"
400 " }\n"
401 " return result;\n"
402 "}\n"
403 "\n",
404 "classname", name_resolver_->GetImmutableClassName(descriptor_));
405
406 printer->Print(
407 "@java.lang.Override\n"
408 "public $classname$ buildPartial() {\n"
409 " $classname$ result = new $classname$(this);\n",
410 "classname", name_resolver_->GetImmutableClassName(descriptor_));
411
412 printer->Indent();
413
414 int totalBuilderBits = 0;
415 int totalMessageBits = 0;
416 for (int i = 0; i < descriptor_->field_count(); i++) {
417 const ImmutableFieldGenerator& field =
418 field_generators_.get(descriptor_->field(i));
419 totalBuilderBits += field.GetNumBitsForBuilder();
420 totalMessageBits += field.GetNumBitsForMessage();
421 }
422 int totalBuilderInts = (totalBuilderBits + 31) / 32;
423 int totalMessageInts = (totalMessageBits + 31) / 32;
424
425 // Local vars for from and to bit fields to avoid accessing the builder and
426 // message over and over for these fields. Seems to provide a slight
427 // perforamance improvement in micro benchmark and this is also what proto1
428 // code does.
429 for (int i = 0; i < totalBuilderInts; i++) {
430 printer->Print("int from_$bit_field_name$ = $bit_field_name$;\n",
431 "bit_field_name", GetBitFieldName(i));
432 }
433 for (int i = 0; i < totalMessageInts; i++) {
434 printer->Print("int to_$bit_field_name$ = 0;\n", "bit_field_name",
435 GetBitFieldName(i));
436 }
437
438 // Output generation code for each field.
439 for (int i = 0; i < descriptor_->field_count(); i++) {
440 field_generators_.get(descriptor_->field(i)).GenerateBuildingCode(printer);
441 }
442
443 // Copy the bit field results to the generated message
444 for (int i = 0; i < totalMessageInts; i++) {
445 printer->Print("result.$bit_field_name$ = to_$bit_field_name$;\n",
446 "bit_field_name", GetBitFieldName(i));
447 }
448
449 for (auto oneof : oneofs_) {
450 printer->Print("result.$oneof_name$Case_ = $oneof_name$Case_;\n",
451 "oneof_name", context_->GetOneofGeneratorInfo(oneof)->name);
452 }
453
454 printer->Outdent();
455
456 printer->Print(" onBuilt();\n");
457
458 printer->Print(
459 " return result;\n"
460 "}\n"
461 "\n",
462 "classname", name_resolver_->GetImmutableClassName(descriptor_));
463
464 // Override methods declared in GeneratedMessage to return the concrete
465 // generated type so callsites won't depend on GeneratedMessage. This
466 // is needed to keep binary compatibility when we change generated code
467 // to subclass a different GeneratedMessage class (e.g., in v3.0.0 release
468 // we changed all generated code to subclass GeneratedMessageV3).
469 printer->Print(
470 "@java.lang.Override\n"
471 "public Builder clone() {\n"
472 " return super.clone();\n"
473 "}\n"
474 "@java.lang.Override\n"
475 "public Builder setField(\n"
476 " com.google.protobuf.Descriptors.FieldDescriptor field,\n"
477 " java.lang.Object value) {\n"
478 " return super.setField(field, value);\n"
479 "}\n"
480 "@java.lang.Override\n"
481 "public Builder clearField(\n"
482 " com.google.protobuf.Descriptors.FieldDescriptor field) {\n"
483 " return super.clearField(field);\n"
484 "}\n"
485 "@java.lang.Override\n"
486 "public Builder clearOneof(\n"
487 " com.google.protobuf.Descriptors.OneofDescriptor oneof) {\n"
488 " return super.clearOneof(oneof);\n"
489 "}\n"
490 "@java.lang.Override\n"
491 "public Builder setRepeatedField(\n"
492 " com.google.protobuf.Descriptors.FieldDescriptor field,\n"
493 " int index, java.lang.Object value) {\n"
494 " return super.setRepeatedField(field, index, value);\n"
495 "}\n"
496 "@java.lang.Override\n"
497 "public Builder addRepeatedField(\n"
498 " com.google.protobuf.Descriptors.FieldDescriptor field,\n"
499 " java.lang.Object value) {\n"
500 " return super.addRepeatedField(field, value);\n"
501 "}\n");
502
503 if (descriptor_->extension_range_count() > 0) {
504 printer->Print(
505 "@java.lang.Override\n"
506 "public <Type> Builder setExtension(\n"
507 " com.google.protobuf.GeneratedMessage.GeneratedExtension<\n"
508 " $classname$, Type> extension,\n"
509 " Type value) {\n"
510 " return super.setExtension(extension, value);\n"
511 "}\n"
512 "@java.lang.Override\n"
513 "public <Type> Builder setExtension(\n"
514 " com.google.protobuf.GeneratedMessage.GeneratedExtension<\n"
515 " $classname$, java.util.List<Type>> extension,\n"
516 " int index, Type value) {\n"
517 " return super.setExtension(extension, index, value);\n"
518 "}\n"
519 "@java.lang.Override\n"
520 "public <Type> Builder addExtension(\n"
521 " com.google.protobuf.GeneratedMessage.GeneratedExtension<\n"
522 " $classname$, java.util.List<Type>> extension,\n"
523 " Type value) {\n"
524 " return super.addExtension(extension, value);\n"
525 "}\n"
526 "@java.lang.Override\n"
527 "public <Type> Builder clearExtension(\n"
528 " com.google.protobuf.GeneratedMessage.GeneratedExtension<\n"
529 " $classname$, ?> extension) {\n"
530 " return super.clearExtension(extension);\n"
531 "}\n",
532 "classname", name_resolver_->GetImmutableClassName(descriptor_));
533 }
534
535 // -----------------------------------------------------------------
536
537 if (context_->HasGeneratedMethods(descriptor_)) {
538 printer->Print(
539 "@java.lang.Override\n"
540 "public Builder mergeFrom(com.google.protobuf.Message other) {\n"
541 " if (other instanceof $classname$) {\n"
542 " return mergeFrom(($classname$)other);\n"
543 " } else {\n"
544 " super.mergeFrom(other);\n"
545 " return this;\n"
546 " }\n"
547 "}\n"
548 "\n",
549 "classname", name_resolver_->GetImmutableClassName(descriptor_));
550
551 printer->Print(
552 "public Builder mergeFrom($classname$ other) {\n"
553 // Optimization: If other is the default instance, we know none of its
554 // fields are set so we can skip the merge.
555 " if (other == $classname$.getDefaultInstance()) return this;\n",
556 "classname", name_resolver_->GetImmutableClassName(descriptor_));
557 printer->Indent();
558
559 for (int i = 0; i < descriptor_->field_count(); i++) {
560 if (!IsRealOneof(descriptor_->field(i))) {
561 field_generators_.get(descriptor_->field(i))
562 .GenerateMergingCode(printer);
563 }
564 }
565
566 // Merge oneof fields.
567 for (auto oneof : oneofs_) {
568 printer->Print("switch (other.get$oneof_capitalized_name$Case()) {\n",
569 "oneof_capitalized_name",
570 context_->GetOneofGeneratorInfo(oneof)->capitalized_name);
571 printer->Indent();
572 for (int j = 0; j < oneof->field_count(); j++) {
573 const FieldDescriptor* field = oneof->field(j);
574 printer->Print("case $field_name$: {\n", "field_name",
575 ToUpper(field->name()));
576 printer->Indent();
577 field_generators_.get(field).GenerateMergingCode(printer);
578 printer->Print("break;\n");
579 printer->Outdent();
580 printer->Print("}\n");
581 }
582 printer->Print(
583 "case $cap_oneof_name$_NOT_SET: {\n"
584 " break;\n"
585 "}\n",
586 "cap_oneof_name",
587 ToUpper(context_->GetOneofGeneratorInfo(oneof)->name));
588 printer->Outdent();
589 printer->Print("}\n");
590 }
591
592 printer->Outdent();
593
594 // if message type has extensions
595 if (descriptor_->extension_range_count() > 0) {
596 printer->Print(" this.mergeExtensionFields(other);\n");
597 }
598
599 printer->Print(" this.mergeUnknownFields(other.getUnknownFields());\n");
600
601 printer->Print(" onChanged();\n");
602
603 printer->Print(
604 " return this;\n"
605 "}\n"
606 "\n");
607 }
608 }
609
610 // ===================================================================
611
GenerateBuilderParsingMethods(io::Printer * printer)612 void MessageBuilderGenerator::GenerateBuilderParsingMethods(
613 io::Printer* printer) {
614 printer->Print(
615 "@java.lang.Override\n"
616 "public Builder mergeFrom(\n"
617 " com.google.protobuf.CodedInputStream input,\n"
618 " com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n"
619 " throws java.io.IOException {\n"
620 " if (extensionRegistry == null) {\n"
621 " throw new java.lang.NullPointerException();\n"
622 " }\n"
623 " try {\n"
624 " boolean done = false;\n"
625 " while (!done) {\n"
626 " int tag = input.readTag();\n"
627 " switch (tag) {\n"
628 " case 0:\n" // zero signals EOF / limit reached
629 " done = true;\n"
630 " break;\n");
631 printer->Indent(); // method
632 printer->Indent(); // try
633 printer->Indent(); // while
634 printer->Indent(); // switch
635 GenerateBuilderFieldParsingCases(printer);
636 printer->Outdent(); // switch
637 printer->Outdent(); // while
638 printer->Outdent(); // try
639 printer->Outdent(); // method
640 printer->Print(
641 " default: {\n"
642 " if (!super.parseUnknownField(input, extensionRegistry, tag)) "
643 "{\n"
644 " done = true; // was an endgroup tag\n"
645 " }\n"
646 " break;\n"
647 " } // default:\n"
648 " } // switch (tag)\n"
649 " } // while (!done)\n"
650 " } catch (com.google.protobuf.InvalidProtocolBufferException e) {\n"
651 " throw e.unwrapIOException();\n"
652 " } finally {\n"
653 " onChanged();\n"
654 " } // finally\n"
655 " return this;\n"
656 "}\n");
657 }
658
GenerateBuilderFieldParsingCases(io::Printer * printer)659 void MessageBuilderGenerator::GenerateBuilderFieldParsingCases(
660 io::Printer* printer) {
661 std::unique_ptr<const FieldDescriptor*[]> sorted_fields(
662 SortFieldsByNumber(descriptor_));
663 for (int i = 0; i < descriptor_->field_count(); i++) {
664 const FieldDescriptor* field = sorted_fields[i];
665 GenerateBuilderFieldParsingCase(printer, field);
666 if (field->is_packable()) {
667 GenerateBuilderPackedFieldParsingCase(printer, field);
668 }
669 }
670 }
671
GenerateBuilderFieldParsingCase(io::Printer * printer,const FieldDescriptor * field)672 void MessageBuilderGenerator::GenerateBuilderFieldParsingCase(
673 io::Printer* printer, const FieldDescriptor* field) {
674 uint32_t tag = WireFormatLite::MakeTag(
675 field->number(), WireFormat::WireTypeForFieldType(field->type()));
676 std::string tagString = StrCat(static_cast<int32_t>(tag));
677 printer->Print("case $tag$: {\n", "tag", tagString);
678 printer->Indent();
679
680 field_generators_.get(field).GenerateBuilderParsingCode(printer);
681
682 printer->Outdent();
683 printer->Print(
684 " break;\n"
685 "} // case $tag$\n",
686 "tag", tagString);
687 }
688
GenerateBuilderPackedFieldParsingCase(io::Printer * printer,const FieldDescriptor * field)689 void MessageBuilderGenerator::GenerateBuilderPackedFieldParsingCase(
690 io::Printer* printer, const FieldDescriptor* field) {
691 // To make packed = true wire compatible, we generate parsing code from a
692 // packed version of this field regardless of field->options().packed().
693 uint32_t tag = WireFormatLite::MakeTag(
694 field->number(), WireFormatLite::WIRETYPE_LENGTH_DELIMITED);
695 std::string tagString = StrCat(static_cast<int32_t>(tag));
696 printer->Print("case $tag$: {\n", "tag", tagString);
697 printer->Indent();
698
699 field_generators_.get(field).GenerateBuilderParsingCodeFromPacked(printer);
700
701 printer->Outdent();
702 printer->Print(
703 " break;\n"
704 "} // case $tag$\n",
705 "tag", tagString);
706 }
707
708 // ===================================================================
709
GenerateIsInitialized(io::Printer * printer)710 void MessageBuilderGenerator::GenerateIsInitialized(io::Printer* printer) {
711 printer->Print(
712 "@java.lang.Override\n"
713 "public final boolean isInitialized() {\n");
714 printer->Indent();
715
716 // Check that all required fields in this message are set.
717 // TODO(kenton): We can optimize this when we switch to putting all the
718 // "has" fields into a single bitfield.
719 for (int i = 0; i < descriptor_->field_count(); i++) {
720 const FieldDescriptor* field = descriptor_->field(i);
721 const FieldGeneratorInfo* info = context_->GetFieldGeneratorInfo(field);
722
723 if (field->is_required()) {
724 printer->Print(
725 "if (!has$name$()) {\n"
726 " return false;\n"
727 "}\n",
728 "name", info->capitalized_name);
729 }
730 }
731
732 // Now check that all embedded messages are initialized.
733 for (int i = 0; i < descriptor_->field_count(); i++) {
734 const FieldDescriptor* field = descriptor_->field(i);
735 const FieldGeneratorInfo* info = context_->GetFieldGeneratorInfo(field);
736 if (GetJavaType(field) == JAVATYPE_MESSAGE &&
737 HasRequiredFields(field->message_type())) {
738 switch (field->label()) {
739 case FieldDescriptor::LABEL_REQUIRED:
740 printer->Print(
741 "if (!get$name$().isInitialized()) {\n"
742 " return false;\n"
743 "}\n",
744 "type",
745 name_resolver_->GetImmutableClassName(field->message_type()),
746 "name", info->capitalized_name);
747 break;
748 case FieldDescriptor::LABEL_OPTIONAL:
749 printer->Print(
750 "if (has$name$()) {\n"
751 " if (!get$name$().isInitialized()) {\n"
752 " return false;\n"
753 " }\n"
754 "}\n",
755 "name", info->capitalized_name);
756 break;
757 case FieldDescriptor::LABEL_REPEATED:
758 if (IsMapEntry(field->message_type())) {
759 printer->Print(
760 "for ($type$ item : get$name$Map().values()) {\n"
761 " if (!item.isInitialized()) {\n"
762 " return false;\n"
763 " }\n"
764 "}\n",
765 "type",
766 MapValueImmutableClassdName(field->message_type(),
767 name_resolver_),
768 "name", info->capitalized_name);
769 } else {
770 printer->Print(
771 "for (int i = 0; i < get$name$Count(); i++) {\n"
772 " if (!get$name$(i).isInitialized()) {\n"
773 " return false;\n"
774 " }\n"
775 "}\n",
776 "type",
777 name_resolver_->GetImmutableClassName(field->message_type()),
778 "name", info->capitalized_name);
779 }
780 break;
781 }
782 }
783 }
784
785 if (descriptor_->extension_range_count() > 0) {
786 printer->Print(
787 "if (!extensionsAreInitialized()) {\n"
788 " return false;\n"
789 "}\n");
790 }
791
792 printer->Outdent();
793
794 printer->Print(
795 " return true;\n"
796 "}\n"
797 "\n");
798 }
799
800 // ===================================================================
801
802 } // namespace java
803 } // namespace compiler
804 } // namespace protobuf
805 } // namespace google
806