1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2008 Google Inc. All rights reserved.
3 // http://code.google.com/p/protobuf/
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 <algorithm>
36 #include <google/protobuf/stubs/hash.h>
37 #include <google/protobuf/compiler/java/java_message.h>
38 #include <google/protobuf/compiler/java/java_enum.h>
39 #include <google/protobuf/compiler/java/java_extension.h>
40 #include <google/protobuf/compiler/java/java_helpers.h>
41 #include <google/protobuf/stubs/strutil.h>
42 #include <google/protobuf/io/printer.h>
43 #include <google/protobuf/io/coded_stream.h>
44 #include <google/protobuf/wire_format.h>
45 #include <google/protobuf/descriptor.pb.h>
46
47 namespace google {
48 namespace protobuf {
49 namespace compiler {
50 namespace java {
51
52 using internal::WireFormat;
53 using internal::WireFormatLite;
54
55 namespace {
56
PrintFieldComment(io::Printer * printer,const FieldDescriptor * field)57 void PrintFieldComment(io::Printer* printer, const FieldDescriptor* field) {
58 // Print the field's proto-syntax definition as a comment. We don't want to
59 // print group bodies so we cut off after the first line.
60 string def = field->DebugString();
61 printer->Print("// $def$\n",
62 "def", def.substr(0, def.find_first_of('\n')));
63 }
64
65 struct FieldOrderingByNumber {
operator ()google::protobuf::compiler::java::__anon3033efac0111::FieldOrderingByNumber66 inline bool operator()(const FieldDescriptor* a,
67 const FieldDescriptor* b) const {
68 return a->number() < b->number();
69 }
70 };
71
72 struct ExtensionRangeOrdering {
operator ()google::protobuf::compiler::java::__anon3033efac0111::ExtensionRangeOrdering73 bool operator()(const Descriptor::ExtensionRange* a,
74 const Descriptor::ExtensionRange* b) const {
75 return a->start < b->start;
76 }
77 };
78
79 // Sort the fields of the given Descriptor by number into a new[]'d array
80 // and return it.
SortFieldsByNumber(const Descriptor * descriptor)81 const FieldDescriptor** SortFieldsByNumber(const Descriptor* descriptor) {
82 const FieldDescriptor** fields =
83 new const FieldDescriptor*[descriptor->field_count()];
84 for (int i = 0; i < descriptor->field_count(); i++) {
85 fields[i] = descriptor->field(i);
86 }
87 sort(fields, fields + descriptor->field_count(),
88 FieldOrderingByNumber());
89 return fields;
90 }
91
92 // Get an identifier that uniquely identifies this type within the file.
93 // This is used to declare static variables related to this type at the
94 // outermost file scope.
UniqueFileScopeIdentifier(const Descriptor * descriptor)95 string UniqueFileScopeIdentifier(const Descriptor* descriptor) {
96 return "static_" + StringReplace(descriptor->full_name(), ".", "_", true);
97 }
98
99 // Returns true if the message type has any required fields. If it doesn't,
100 // we can optimize out calls to its isInitialized() method.
101 //
102 // already_seen is used to avoid checking the same type multiple times
103 // (and also to protect against recursion).
HasRequiredFields(const Descriptor * type,hash_set<const Descriptor * > * already_seen)104 static bool HasRequiredFields(
105 const Descriptor* type,
106 hash_set<const Descriptor*>* already_seen) {
107 if (already_seen->count(type) > 0) {
108 // The type is already in cache. This means that either:
109 // a. The type has no required fields.
110 // b. We are in the midst of checking if the type has required fields,
111 // somewhere up the stack. In this case, we know that if the type
112 // has any required fields, they'll be found when we return to it,
113 // and the whole call to HasRequiredFields() will return true.
114 // Therefore, we don't have to check if this type has required fields
115 // here.
116 return false;
117 }
118 already_seen->insert(type);
119
120 // If the type has extensions, an extension with message type could contain
121 // required fields, so we have to be conservative and assume such an
122 // extension exists.
123 if (type->extension_range_count() > 0) return true;
124
125 for (int i = 0; i < type->field_count(); i++) {
126 const FieldDescriptor* field = type->field(i);
127 if (field->is_required()) {
128 return true;
129 }
130 if (GetJavaType(field) == JAVATYPE_MESSAGE) {
131 if (HasRequiredFields(field->message_type(), already_seen)) {
132 return true;
133 }
134 }
135 }
136
137 return false;
138 }
139
HasRequiredFields(const Descriptor * type)140 static bool HasRequiredFields(const Descriptor* type) {
141 hash_set<const Descriptor*> already_seen;
142 return HasRequiredFields(type, &already_seen);
143 }
144
145 } // namespace
146
147 // ===================================================================
148
MessageGenerator(const Descriptor * descriptor)149 MessageGenerator::MessageGenerator(const Descriptor* descriptor)
150 : descriptor_(descriptor),
151 field_generators_(descriptor) {
152 }
153
~MessageGenerator()154 MessageGenerator::~MessageGenerator() {}
155
GenerateStaticVariables(io::Printer * printer)156 void MessageGenerator::GenerateStaticVariables(io::Printer* printer) {
157 if (HasDescriptorMethods(descriptor_)) {
158 // Because descriptor.proto (com.google.protobuf.DescriptorProtos) is
159 // used in the construction of descriptors, we have a tricky bootstrapping
160 // problem. To help control static initialization order, we make sure all
161 // descriptors and other static data that depends on them are members of
162 // the outermost class in the file. This way, they will be initialized in
163 // a deterministic order.
164
165 map<string, string> vars;
166 vars["identifier"] = UniqueFileScopeIdentifier(descriptor_);
167 vars["index"] = SimpleItoa(descriptor_->index());
168 vars["classname"] = ClassName(descriptor_);
169 if (descriptor_->containing_type() != NULL) {
170 vars["parent"] = UniqueFileScopeIdentifier(
171 descriptor_->containing_type());
172 }
173 if (descriptor_->file()->options().java_multiple_files()) {
174 // We can only make these package-private since the classes that use them
175 // are in separate files.
176 vars["private"] = "";
177 } else {
178 vars["private"] = "private ";
179 }
180
181 // The descriptor for this type.
182 printer->Print(vars,
183 "$private$static com.google.protobuf.Descriptors.Descriptor\n"
184 " internal_$identifier$_descriptor;\n");
185
186 // And the FieldAccessorTable.
187 printer->Print(vars,
188 "$private$static\n"
189 " com.google.protobuf.GeneratedMessage.FieldAccessorTable\n"
190 " internal_$identifier$_fieldAccessorTable;\n");
191 }
192
193 // Generate static members for all nested types.
194 for (int i = 0; i < descriptor_->nested_type_count(); i++) {
195 // TODO(kenton): Reuse MessageGenerator objects?
196 MessageGenerator(descriptor_->nested_type(i))
197 .GenerateStaticVariables(printer);
198 }
199 }
200
GenerateStaticVariableInitializers(io::Printer * printer)201 void MessageGenerator::GenerateStaticVariableInitializers(
202 io::Printer* printer) {
203 if (HasDescriptorMethods(descriptor_)) {
204 map<string, string> vars;
205 vars["identifier"] = UniqueFileScopeIdentifier(descriptor_);
206 vars["index"] = SimpleItoa(descriptor_->index());
207 vars["classname"] = ClassName(descriptor_);
208 if (descriptor_->containing_type() != NULL) {
209 vars["parent"] = UniqueFileScopeIdentifier(
210 descriptor_->containing_type());
211 }
212
213 // The descriptor for this type.
214 if (descriptor_->containing_type() == NULL) {
215 printer->Print(vars,
216 "internal_$identifier$_descriptor =\n"
217 " getDescriptor().getMessageTypes().get($index$);\n");
218 } else {
219 printer->Print(vars,
220 "internal_$identifier$_descriptor =\n"
221 " internal_$parent$_descriptor.getNestedTypes().get($index$);\n");
222 }
223
224 // And the FieldAccessorTable.
225 printer->Print(vars,
226 "internal_$identifier$_fieldAccessorTable = new\n"
227 " com.google.protobuf.GeneratedMessage.FieldAccessorTable(\n"
228 " internal_$identifier$_descriptor,\n"
229 " new java.lang.String[] { ");
230 for (int i = 0; i < descriptor_->field_count(); i++) {
231 printer->Print(
232 "\"$field_name$\", ",
233 "field_name",
234 UnderscoresToCapitalizedCamelCase(descriptor_->field(i)));
235 }
236 printer->Print("},\n"
237 " $classname$.class,\n"
238 " $classname$.Builder.class);\n",
239 "classname", ClassName(descriptor_));
240 }
241
242 // Generate static member initializers for all nested types.
243 for (int i = 0; i < descriptor_->nested_type_count(); i++) {
244 // TODO(kenton): Reuse MessageGenerator objects?
245 MessageGenerator(descriptor_->nested_type(i))
246 .GenerateStaticVariableInitializers(printer);
247 }
248
249 for (int i = 0; i < descriptor_->extension_count(); i++) {
250 // TODO(kenton): Reuse ExtensionGenerator objects?
251 ExtensionGenerator(descriptor_->extension(i))
252 .GenerateInitializationCode(printer);
253 }
254 }
255
Generate(io::Printer * printer)256 void MessageGenerator::Generate(io::Printer* printer) {
257 bool is_own_file =
258 descriptor_->containing_type() == NULL &&
259 descriptor_->file()->options().java_multiple_files();
260
261 if (descriptor_->extension_range_count() > 0) {
262 if (HasDescriptorMethods(descriptor_)) {
263 printer->Print(
264 "public $static$ final class $classname$ extends\n"
265 " com.google.protobuf.GeneratedMessage.ExtendableMessage<\n"
266 " $classname$> {\n",
267 "static", is_own_file ? "" : "static",
268 "classname", descriptor_->name());
269 } else {
270 printer->Print(
271 "public $static$ final class $classname$ extends\n"
272 " com.google.protobuf.GeneratedMessageLite.ExtendableMessage<\n"
273 " $classname$> {\n",
274 "static", is_own_file ? "" : "static",
275 "classname", descriptor_->name());
276 }
277 } else {
278 if (HasDescriptorMethods(descriptor_)) {
279 printer->Print(
280 "public $static$ final class $classname$ extends\n"
281 " com.google.protobuf.GeneratedMessage {\n",
282 "static", is_own_file ? "" : "static",
283 "classname", descriptor_->name());
284 } else {
285 printer->Print(
286 "public $static$ final class $classname$ extends\n"
287 " com.google.protobuf.GeneratedMessageLite {\n",
288 "static", is_own_file ? "" : "static",
289 "classname", descriptor_->name());
290 }
291 }
292 printer->Indent();
293 printer->Print(
294 "// Use $classname$.newBuilder() to construct.\n"
295 "private $classname$() {\n"
296 " initFields();\n"
297 "}\n"
298 // Used when constructing the default instance, which cannot be initialized
299 // immediately because it may cyclically refer to other default instances.
300 "private $classname$(boolean noInit) {}\n"
301 "\n"
302 "private static final $classname$ defaultInstance;\n"
303 "public static $classname$ getDefaultInstance() {\n"
304 " return defaultInstance;\n"
305 "}\n"
306 "\n"
307 "public $classname$ getDefaultInstanceForType() {\n"
308 " return defaultInstance;\n"
309 "}\n"
310 "\n",
311 "classname", descriptor_->name());
312
313 if (HasDescriptorMethods(descriptor_)) {
314 printer->Print(
315 "public static final com.google.protobuf.Descriptors.Descriptor\n"
316 " getDescriptor() {\n"
317 " return $fileclass$.internal_$identifier$_descriptor;\n"
318 "}\n"
319 "\n"
320 "protected com.google.protobuf.GeneratedMessage.FieldAccessorTable\n"
321 " internalGetFieldAccessorTable() {\n"
322 " return $fileclass$.internal_$identifier$_fieldAccessorTable;\n"
323 "}\n"
324 "\n",
325 "fileclass", ClassName(descriptor_->file()),
326 "identifier", UniqueFileScopeIdentifier(descriptor_));
327 }
328
329 // Nested types and extensions
330 for (int i = 0; i < descriptor_->enum_type_count(); i++) {
331 EnumGenerator(descriptor_->enum_type(i)).Generate(printer);
332 }
333
334 for (int i = 0; i < descriptor_->nested_type_count(); i++) {
335 MessageGenerator(descriptor_->nested_type(i)).Generate(printer);
336 }
337
338 for (int i = 0; i < descriptor_->extension_count(); i++) {
339 ExtensionGenerator(descriptor_->extension(i)).Generate(printer);
340 }
341
342 // Fields
343 for (int i = 0; i < descriptor_->field_count(); i++) {
344 PrintFieldComment(printer, descriptor_->field(i));
345 printer->Print("public static final int $constant_name$ = $number$;\n",
346 "constant_name", FieldConstantName(descriptor_->field(i)),
347 "number", SimpleItoa(descriptor_->field(i)->number()));
348 field_generators_.get(descriptor_->field(i)).GenerateMembers(printer);
349 printer->Print("\n");
350 }
351
352 // Called by the constructor, except in the case of the default instance,
353 // in which case this is called by static init code later on.
354 printer->Print("private void initFields() {\n");
355 printer->Indent();
356 for (int i = 0; i < descriptor_->field_count(); i++) {
357 field_generators_.get(descriptor_->field(i))
358 .GenerateInitializationCode(printer);
359 }
360 printer->Outdent();
361 printer->Print("}\n");
362
363 if (HasGeneratedMethods(descriptor_)) {
364 GenerateIsInitialized(printer);
365 GenerateMessageSerializationMethods(printer);
366 }
367
368 GenerateParseFromMethods(printer);
369 GenerateBuilder(printer);
370
371 // Force initialization of outer class. Otherwise, nested extensions may
372 // not be initialized. Also carefully initialize the default instance in
373 // such a way that it doesn't conflict with other initialization.
374 printer->Print(
375 "\n"
376 "static {\n"
377 " defaultInstance = new $classname$(true);\n"
378 " $file$.internalForceInit();\n"
379 " defaultInstance.initFields();\n"
380 "}\n",
381 "file", ClassName(descriptor_->file()),
382 "classname", descriptor_->name());
383
384 printer->Print(
385 "\n"
386 "// @@protoc_insertion_point(class_scope:$full_name$)\n",
387 "full_name", descriptor_->full_name());
388
389 printer->Outdent();
390 printer->Print("}\n\n");
391 }
392
393 // ===================================================================
394
395 void MessageGenerator::
GenerateMessageSerializationMethods(io::Printer * printer)396 GenerateMessageSerializationMethods(io::Printer* printer) {
397 scoped_array<const FieldDescriptor*> sorted_fields(
398 SortFieldsByNumber(descriptor_));
399
400 vector<const Descriptor::ExtensionRange*> sorted_extensions;
401 for (int i = 0; i < descriptor_->extension_range_count(); ++i) {
402 sorted_extensions.push_back(descriptor_->extension_range(i));
403 }
404 sort(sorted_extensions.begin(), sorted_extensions.end(),
405 ExtensionRangeOrdering());
406
407 printer->Print(
408 "public void writeTo(com.google.protobuf.CodedOutputStream output)\n"
409 " throws java.io.IOException {\n");
410 printer->Indent();
411 // writeTo(CodedOutputStream output) might be invoked without
412 // getSerializedSize() ever being called, but we need the memoized
413 // sizes in case this message has packed fields. Rather than emit checks for
414 // each packed field, just call getSerializedSize() up front for all messages.
415 // In most cases, getSerializedSize() will have already been called anyway by
416 // one of the wrapper writeTo() methods, making this call cheap.
417 printer->Print(
418 "getSerializedSize();\n");
419
420 if (descriptor_->extension_range_count() > 0) {
421 if (descriptor_->options().message_set_wire_format()) {
422 printer->Print(
423 "com.google.protobuf.GeneratedMessage$lite$.ExtendableMessage\n"
424 " .ExtensionWriter extensionWriter =\n"
425 " newMessageSetExtensionWriter();\n",
426 "lite", HasDescriptorMethods(descriptor_) ? "" : "Lite");
427 } else {
428 printer->Print(
429 "com.google.protobuf.GeneratedMessage$lite$.ExtendableMessage\n"
430 " .ExtensionWriter extensionWriter = newExtensionWriter();\n",
431 "lite", HasDescriptorMethods(descriptor_) ? "" : "Lite");
432 }
433 }
434
435 // Merge the fields and the extension ranges, both sorted by field number.
436 for (int i = 0, j = 0;
437 i < descriptor_->field_count() || j < sorted_extensions.size();
438 ) {
439 if (i == descriptor_->field_count()) {
440 GenerateSerializeOneExtensionRange(printer, sorted_extensions[j++]);
441 } else if (j == sorted_extensions.size()) {
442 GenerateSerializeOneField(printer, sorted_fields[i++]);
443 } else if (sorted_fields[i]->number() < sorted_extensions[j]->start) {
444 GenerateSerializeOneField(printer, sorted_fields[i++]);
445 } else {
446 GenerateSerializeOneExtensionRange(printer, sorted_extensions[j++]);
447 }
448 }
449
450 if (HasUnknownFields(descriptor_)) {
451 if (descriptor_->options().message_set_wire_format()) {
452 printer->Print(
453 "getUnknownFields().writeAsMessageSetTo(output);\n");
454 } else {
455 printer->Print(
456 "getUnknownFields().writeTo(output);\n");
457 }
458 }
459
460 printer->Outdent();
461 printer->Print(
462 "}\n"
463 "\n"
464 "private int memoizedSerializedSize = -1;\n"
465 "public int getSerializedSize() {\n"
466 " int size = memoizedSerializedSize;\n"
467 " if (size != -1) return size;\n"
468 "\n"
469 " size = 0;\n");
470 printer->Indent();
471
472 for (int i = 0; i < descriptor_->field_count(); i++) {
473 field_generators_.get(sorted_fields[i]).GenerateSerializedSizeCode(printer);
474 }
475
476 if (descriptor_->extension_range_count() > 0) {
477 if (descriptor_->options().message_set_wire_format()) {
478 printer->Print(
479 "size += extensionsSerializedSizeAsMessageSet();\n");
480 } else {
481 printer->Print(
482 "size += extensionsSerializedSize();\n");
483 }
484 }
485
486 if (HasUnknownFields(descriptor_)) {
487 if (descriptor_->options().message_set_wire_format()) {
488 printer->Print(
489 "size += getUnknownFields().getSerializedSizeAsMessageSet();\n");
490 } else {
491 printer->Print(
492 "size += getUnknownFields().getSerializedSize();\n");
493 }
494 }
495
496 printer->Outdent();
497 printer->Print(
498 " memoizedSerializedSize = size;\n"
499 " return size;\n"
500 "}\n"
501 "\n");
502 }
503
504 void MessageGenerator::
GenerateParseFromMethods(io::Printer * printer)505 GenerateParseFromMethods(io::Printer* printer) {
506 // Note: These are separate from GenerateMessageSerializationMethods()
507 // because they need to be generated even for messages that are optimized
508 // for code size.
509 printer->Print(
510 "public static $classname$ parseFrom(\n"
511 " com.google.protobuf.ByteString data)\n"
512 " throws com.google.protobuf.InvalidProtocolBufferException {\n"
513 " return newBuilder().mergeFrom(data).buildParsed();\n"
514 "}\n"
515 "public static $classname$ parseFrom(\n"
516 " com.google.protobuf.ByteString data,\n"
517 " com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n"
518 " throws com.google.protobuf.InvalidProtocolBufferException {\n"
519 " return newBuilder().mergeFrom(data, extensionRegistry)\n"
520 " .buildParsed();\n"
521 "}\n"
522 "public static $classname$ parseFrom(byte[] data)\n"
523 " throws com.google.protobuf.InvalidProtocolBufferException {\n"
524 " return newBuilder().mergeFrom(data).buildParsed();\n"
525 "}\n"
526 "public static $classname$ parseFrom(\n"
527 " byte[] data,\n"
528 " com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n"
529 " throws com.google.protobuf.InvalidProtocolBufferException {\n"
530 " return newBuilder().mergeFrom(data, extensionRegistry)\n"
531 " .buildParsed();\n"
532 "}\n"
533 "public static $classname$ parseFrom(java.io.InputStream input)\n"
534 " throws java.io.IOException {\n"
535 " return newBuilder().mergeFrom(input).buildParsed();\n"
536 "}\n"
537 "public static $classname$ parseFrom(\n"
538 " java.io.InputStream input,\n"
539 " com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n"
540 " throws java.io.IOException {\n"
541 " return newBuilder().mergeFrom(input, extensionRegistry)\n"
542 " .buildParsed();\n"
543 "}\n"
544 "public static $classname$ parseDelimitedFrom(java.io.InputStream input)\n"
545 " throws java.io.IOException {\n"
546 " Builder builder = newBuilder();\n"
547 " if (builder.mergeDelimitedFrom(input)) {\n"
548 " return builder.buildParsed();\n"
549 " } else {\n"
550 " return null;\n"
551 " }\n"
552 "}\n"
553 "public static $classname$ parseDelimitedFrom(\n"
554 " java.io.InputStream input,\n"
555 " com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n"
556 " throws java.io.IOException {\n"
557 " Builder builder = newBuilder();\n"
558 " if (builder.mergeDelimitedFrom(input, extensionRegistry)) {\n"
559 " return builder.buildParsed();\n"
560 " } else {\n"
561 " return null;\n"
562 " }\n"
563 "}\n"
564 "public static $classname$ parseFrom(\n"
565 " com.google.protobuf.CodedInputStream input)\n"
566 " throws java.io.IOException {\n"
567 " return newBuilder().mergeFrom(input).buildParsed();\n"
568 "}\n"
569 "public static $classname$ parseFrom(\n"
570 " com.google.protobuf.CodedInputStream input,\n"
571 " com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n"
572 " throws java.io.IOException {\n"
573 " return newBuilder().mergeFrom(input, extensionRegistry)\n"
574 " .buildParsed();\n"
575 "}\n"
576 "\n",
577 "classname", ClassName(descriptor_));
578 }
579
GenerateSerializeOneField(io::Printer * printer,const FieldDescriptor * field)580 void MessageGenerator::GenerateSerializeOneField(
581 io::Printer* printer, const FieldDescriptor* field) {
582 field_generators_.get(field).GenerateSerializationCode(printer);
583 }
584
GenerateSerializeOneExtensionRange(io::Printer * printer,const Descriptor::ExtensionRange * range)585 void MessageGenerator::GenerateSerializeOneExtensionRange(
586 io::Printer* printer, const Descriptor::ExtensionRange* range) {
587 printer->Print(
588 "extensionWriter.writeUntil($end$, output);\n",
589 "end", SimpleItoa(range->end));
590 }
591
592 // ===================================================================
593
GenerateBuilder(io::Printer * printer)594 void MessageGenerator::GenerateBuilder(io::Printer* printer) {
595 printer->Print(
596 "public static Builder newBuilder() { return Builder.create(); }\n"
597 "public Builder newBuilderForType() { return newBuilder(); }\n"
598 "public static Builder newBuilder($classname$ prototype) {\n"
599 " return newBuilder().mergeFrom(prototype);\n"
600 "}\n"
601 "public Builder toBuilder() { return newBuilder(this); }\n"
602 "\n",
603 "classname", ClassName(descriptor_));
604
605 if (descriptor_->extension_range_count() > 0) {
606 if (HasDescriptorMethods(descriptor_)) {
607 printer->Print(
608 "public static final class Builder extends\n"
609 " com.google.protobuf.GeneratedMessage.ExtendableBuilder<\n"
610 " $classname$, Builder> {\n",
611 "classname", ClassName(descriptor_));
612 } else {
613 printer->Print(
614 "public static final class Builder extends\n"
615 " com.google.protobuf.GeneratedMessageLite.ExtendableBuilder<\n"
616 " $classname$, Builder> {\n",
617 "classname", ClassName(descriptor_));
618 }
619 } else {
620 if (HasDescriptorMethods(descriptor_)) {
621 printer->Print(
622 "public static final class Builder extends\n"
623 " com.google.protobuf.GeneratedMessage.Builder<Builder> {\n",
624 "classname", ClassName(descriptor_));
625 } else {
626 printer->Print(
627 "public static final class Builder extends\n"
628 " com.google.protobuf.GeneratedMessageLite.Builder<\n"
629 " $classname$, Builder> {\n",
630 "classname", ClassName(descriptor_));
631 }
632 }
633 printer->Indent();
634
635 GenerateCommonBuilderMethods(printer);
636
637 if (HasGeneratedMethods(descriptor_)) {
638 GenerateBuilderParsingMethods(printer);
639 }
640
641 for (int i = 0; i < descriptor_->field_count(); i++) {
642 printer->Print("\n");
643 PrintFieldComment(printer, descriptor_->field(i));
644 field_generators_.get(descriptor_->field(i))
645 .GenerateBuilderMembers(printer);
646 }
647
648 printer->Print(
649 "\n"
650 "// @@protoc_insertion_point(builder_scope:$full_name$)\n",
651 "full_name", descriptor_->full_name());
652
653 printer->Outdent();
654 printer->Print("}\n");
655 }
656
657 // ===================================================================
658
GenerateCommonBuilderMethods(io::Printer * printer)659 void MessageGenerator::GenerateCommonBuilderMethods(io::Printer* printer) {
660 printer->Print(
661 "private $classname$ result;\n"
662 "\n"
663 "// Construct using $classname$.newBuilder()\n"
664 "private Builder() {}\n"
665 "\n"
666 "private static Builder create() {\n"
667 " Builder builder = new Builder();\n"
668 " builder.result = new $classname$();\n"
669 " return builder;\n"
670 "}\n"
671 "\n"
672 "protected $classname$ internalGetResult() {\n"
673 " return result;\n"
674 "}\n"
675 "\n"
676 "public Builder clear() {\n"
677 " if (result == null) {\n"
678 " throw new IllegalStateException(\n"
679 " \"Cannot call clear() after build().\");\n"
680 " }\n"
681 " result = new $classname$();\n"
682 " return this;\n"
683 "}\n"
684 "\n"
685 "public Builder clone() {\n"
686 " return create().mergeFrom(result);\n"
687 "}\n"
688 "\n",
689 "classname", ClassName(descriptor_));
690 if (HasDescriptorMethods(descriptor_)) {
691 printer->Print(
692 "public com.google.protobuf.Descriptors.Descriptor\n"
693 " getDescriptorForType() {\n"
694 " return $classname$.getDescriptor();\n"
695 "}\n"
696 "\n",
697 "classname", ClassName(descriptor_));
698 }
699 printer->Print(
700 "public $classname$ getDefaultInstanceForType() {\n"
701 " return $classname$.getDefaultInstance();\n"
702 "}\n"
703 "\n"
704 "public boolean isInitialized() {\n"
705 " return result.isInitialized();\n"
706 "}\n",
707 "classname", ClassName(descriptor_));
708
709 // -----------------------------------------------------------------
710
711 printer->Print(
712 "public $classname$ build() {\n"
713 // If result == null, we'll throw an appropriate exception later.
714 " if (result != null && !isInitialized()) {\n"
715 " throw newUninitializedMessageException(result);\n"
716 " }\n"
717 " return buildPartial();\n"
718 "}\n"
719 "\n"
720 "private $classname$ buildParsed()\n"
721 " throws com.google.protobuf.InvalidProtocolBufferException {\n"
722 " if (!isInitialized()) {\n"
723 " throw newUninitializedMessageException(\n"
724 " result).asInvalidProtocolBufferException();\n"
725 " }\n"
726 " return buildPartial();\n"
727 "}\n"
728 "\n"
729 "public $classname$ buildPartial() {\n"
730 " if (result == null) {\n"
731 " throw new IllegalStateException(\n"
732 " \"build() has already been called on this Builder.\");\n"
733 " }\n",
734 "classname", ClassName(descriptor_));
735 printer->Indent();
736
737 for (int i = 0; i < descriptor_->field_count(); i++) {
738 field_generators_.get(descriptor_->field(i)).GenerateBuildingCode(printer);
739 }
740
741 printer->Outdent();
742 printer->Print(
743 " $classname$ returnMe = result;\n"
744 " result = null;\n"
745 " return returnMe;\n"
746 "}\n"
747 "\n",
748 "classname", ClassName(descriptor_));
749
750 // -----------------------------------------------------------------
751
752 if (HasGeneratedMethods(descriptor_)) {
753 // MergeFrom(Message other) requires the ability to distinguish the other
754 // messages type by its descriptor.
755 if (HasDescriptorMethods(descriptor_)) {
756 printer->Print(
757 "public Builder mergeFrom(com.google.protobuf.Message other) {\n"
758 " if (other instanceof $classname$) {\n"
759 " return mergeFrom(($classname$)other);\n"
760 " } else {\n"
761 " super.mergeFrom(other);\n"
762 " return this;\n"
763 " }\n"
764 "}\n"
765 "\n",
766 "classname", ClassName(descriptor_));
767 }
768
769 printer->Print(
770 "public Builder mergeFrom($classname$ other) {\n"
771 // Optimization: If other is the default instance, we know none of its
772 // fields are set so we can skip the merge.
773 " if (other == $classname$.getDefaultInstance()) return this;\n",
774 "classname", ClassName(descriptor_));
775 printer->Indent();
776
777 for (int i = 0; i < descriptor_->field_count(); i++) {
778 field_generators_.get(descriptor_->field(i)).GenerateMergingCode(printer);
779 }
780
781 printer->Outdent();
782
783 // if message type has extensions
784 if (descriptor_->extension_range_count() > 0) {
785 printer->Print(
786 " this.mergeExtensionFields(other);\n");
787 }
788
789 if (HasUnknownFields(descriptor_)) {
790 printer->Print(
791 " this.mergeUnknownFields(other.getUnknownFields());\n");
792 }
793
794 printer->Print(
795 " return this;\n"
796 "}\n"
797 "\n");
798 }
799 }
800
801 // ===================================================================
802
GenerateBuilderParsingMethods(io::Printer * printer)803 void MessageGenerator::GenerateBuilderParsingMethods(io::Printer* printer) {
804 scoped_array<const FieldDescriptor*> sorted_fields(
805 SortFieldsByNumber(descriptor_));
806
807 printer->Print(
808 "public Builder mergeFrom(\n"
809 " com.google.protobuf.CodedInputStream input,\n"
810 " com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n"
811 " throws java.io.IOException {\n");
812 printer->Indent();
813
814 if (HasUnknownFields(descriptor_)) {
815 printer->Print(
816 "com.google.protobuf.UnknownFieldSet.Builder unknownFields =\n"
817 " com.google.protobuf.UnknownFieldSet.newBuilder(\n"
818 " this.getUnknownFields());\n");
819 }
820
821 printer->Print(
822 "while (true) {\n");
823 printer->Indent();
824
825 printer->Print(
826 "int tag = input.readTag();\n"
827 "switch (tag) {\n");
828 printer->Indent();
829
830 if (HasUnknownFields(descriptor_)) {
831 printer->Print(
832 "case 0:\n" // zero signals EOF / limit reached
833 " this.setUnknownFields(unknownFields.build());\n"
834 " return this;\n"
835 "default: {\n"
836 " if (!parseUnknownField(input, unknownFields,\n"
837 " extensionRegistry, tag)) {\n"
838 " this.setUnknownFields(unknownFields.build());\n"
839 " return this;\n" // it's an endgroup tag
840 " }\n"
841 " break;\n"
842 "}\n");
843 } else {
844 printer->Print(
845 "case 0:\n" // zero signals EOF / limit reached
846 " return this;\n"
847 "default: {\n"
848 " if (!parseUnknownField(input, extensionRegistry, tag)) {\n"
849 " return this;\n" // it's an endgroup tag
850 " }\n"
851 " break;\n"
852 "}\n");
853 }
854
855 for (int i = 0; i < descriptor_->field_count(); i++) {
856 const FieldDescriptor* field = sorted_fields[i];
857 uint32 tag = WireFormatLite::MakeTag(field->number(),
858 WireFormat::WireTypeForFieldType(field->type()));
859
860 printer->Print(
861 "case $tag$: {\n",
862 "tag", SimpleItoa(tag));
863 printer->Indent();
864
865 field_generators_.get(field).GenerateParsingCode(printer);
866
867 printer->Outdent();
868 printer->Print(
869 " break;\n"
870 "}\n");
871
872 if (field->is_packable()) {
873 // To make packed = true wire compatible, we generate parsing code from a
874 // packed version of this field regardless of field->options().packed().
875 uint32 packed_tag = WireFormatLite::MakeTag(field->number(),
876 WireFormatLite::WIRETYPE_LENGTH_DELIMITED);
877 printer->Print(
878 "case $tag$: {\n",
879 "tag", SimpleItoa(packed_tag));
880 printer->Indent();
881
882 field_generators_.get(field).GenerateParsingCodeFromPacked(printer);
883
884 printer->Outdent();
885 printer->Print(
886 " break;\n"
887 "}\n");
888 }
889 }
890
891 printer->Outdent();
892 printer->Outdent();
893 printer->Outdent();
894 printer->Print(
895 " }\n" // switch (tag)
896 " }\n" // while (true)
897 "}\n"
898 "\n");
899 }
900
901 // ===================================================================
902
GenerateIsInitialized(io::Printer * printer)903 void MessageGenerator::GenerateIsInitialized(io::Printer* printer) {
904 printer->Print(
905 "public final boolean isInitialized() {\n");
906 printer->Indent();
907
908 // Check that all required fields in this message are set.
909 // TODO(kenton): We can optimize this when we switch to putting all the
910 // "has" fields into a single bitfield.
911 for (int i = 0; i < descriptor_->field_count(); i++) {
912 const FieldDescriptor* field = descriptor_->field(i);
913
914 if (field->is_required()) {
915 printer->Print(
916 "if (!has$name$) return false;\n",
917 "name", UnderscoresToCapitalizedCamelCase(field));
918 }
919 }
920
921 // Now check that all embedded messages are initialized.
922 for (int i = 0; i < descriptor_->field_count(); i++) {
923 const FieldDescriptor* field = descriptor_->field(i);
924 if (GetJavaType(field) == JAVATYPE_MESSAGE &&
925 HasRequiredFields(field->message_type())) {
926 switch (field->label()) {
927 case FieldDescriptor::LABEL_REQUIRED:
928 printer->Print(
929 "if (!get$name$().isInitialized()) return false;\n",
930 "type", ClassName(field->message_type()),
931 "name", UnderscoresToCapitalizedCamelCase(field));
932 break;
933 case FieldDescriptor::LABEL_OPTIONAL:
934 printer->Print(
935 "if (has$name$()) {\n"
936 " if (!get$name$().isInitialized()) return false;\n"
937 "}\n",
938 "type", ClassName(field->message_type()),
939 "name", UnderscoresToCapitalizedCamelCase(field));
940 break;
941 case FieldDescriptor::LABEL_REPEATED:
942 printer->Print(
943 "for ($type$ element : get$name$List()) {\n"
944 " if (!element.isInitialized()) return false;\n"
945 "}\n",
946 "type", ClassName(field->message_type()),
947 "name", UnderscoresToCapitalizedCamelCase(field));
948 break;
949 }
950 }
951 }
952
953 if (descriptor_->extension_range_count() > 0) {
954 printer->Print(
955 "if (!extensionsAreInitialized()) return false;\n");
956 }
957
958 printer->Outdent();
959 printer->Print(
960 " return true;\n"
961 "}\n"
962 "\n");
963 }
964
965 // ===================================================================
966
GenerateExtensionRegistrationCode(io::Printer * printer)967 void MessageGenerator::GenerateExtensionRegistrationCode(io::Printer* printer) {
968 for (int i = 0; i < descriptor_->extension_count(); i++) {
969 ExtensionGenerator(descriptor_->extension(i))
970 .GenerateRegistrationCode(printer);
971 }
972
973 for (int i = 0; i < descriptor_->nested_type_count(); i++) {
974 MessageGenerator(descriptor_->nested_type(i))
975 .GenerateExtensionRegistrationCode(printer);
976 }
977 }
978
979 } // namespace java
980 } // namespace compiler
981 } // namespace protobuf
982 } // namespace google
983