• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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