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