1fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Protocol Buffers - Google's data interchange format
2fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Copyright 2008 Google Inc.  All rights reserved.
3fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// http://code.google.com/p/protobuf/
4fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville//
5fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Redistribution and use in source and binary forms, with or without
6fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// modification, are permitted provided that the following conditions are
7fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// met:
8fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville//
9fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville//     * Redistributions of source code must retain the above copyright
10fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// notice, this list of conditions and the following disclaimer.
11fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville//     * Redistributions in binary form must reproduce the above
12fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// copyright notice, this list of conditions and the following disclaimer
13fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// in the documentation and/or other materials provided with the
14fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// distribution.
15fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville//     * Neither the name of Google Inc. nor the names of its
16fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// contributors may be used to endorse or promote products derived from
17fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// this software without specific prior written permission.
18fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville//
19fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
31fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Author: kenton@google.com (Kenton Varda)
32fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville//  Based on original Protocol Buffers design by
33fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville//  Sanjay Ghemawat, Jeff Dean, and others.
34fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
35fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <algorithm>
36fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <google/protobuf/stubs/hash.h>
37fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <map>
38fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <vector>
39fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <google/protobuf/compiler/cpp/cpp_message.h>
40fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <google/protobuf/compiler/cpp/cpp_field.h>
41fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <google/protobuf/compiler/cpp/cpp_enum.h>
42fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <google/protobuf/compiler/cpp/cpp_extension.h>
43fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <google/protobuf/compiler/cpp/cpp_helpers.h>
44fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <google/protobuf/stubs/strutil.h>
45fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <google/protobuf/io/printer.h>
46fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <google/protobuf/io/coded_stream.h>
47fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <google/protobuf/wire_format.h>
48fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <google/protobuf/descriptor.pb.h>
49fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
50fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillenamespace google {
51fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillenamespace protobuf {
52fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillenamespace compiler {
53fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillenamespace cpp {
54fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
55fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleusing internal::WireFormat;
56fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleusing internal::WireFormatLite;
57fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
58fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillenamespace {
59fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
60fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid PrintFieldComment(io::Printer* printer, const FieldDescriptor* field) {
61fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // Print the field's proto-syntax definition as a comment.  We don't want to
62fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // print group bodies so we cut off after the first line.
63fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  string def = field->DebugString();
64fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Print("// $def$\n",
65fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "def", def.substr(0, def.find_first_of('\n')));
66fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
67fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
68fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillestruct FieldOrderingByNumber {
69fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  inline bool operator()(const FieldDescriptor* a,
70fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville                         const FieldDescriptor* b) const {
71fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return a->number() < b->number();
72fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
73fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville};
74fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
75fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleconst char* kWireTypeNames[] = {
76fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  "VARINT",
77fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  "FIXED64",
78fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  "LENGTH_DELIMITED",
79fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  "START_GROUP",
80fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  "END_GROUP",
81fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  "FIXED32",
82fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville};
83fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
84fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Sort the fields of the given Descriptor by number into a new[]'d array
85fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// and return it.
86fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleconst FieldDescriptor** SortFieldsByNumber(const Descriptor* descriptor) {
87fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  const FieldDescriptor** fields =
88fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    new const FieldDescriptor*[descriptor->field_count()];
89fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  for (int i = 0; i < descriptor->field_count(); i++) {
90fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    fields[i] = descriptor->field(i);
91fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
92fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  sort(fields, fields + descriptor->field_count(),
93fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville       FieldOrderingByNumber());
94fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  return fields;
95fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
96fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
97fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Functor for sorting extension ranges by their "start" field number.
98fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillestruct ExtensionRangeSorter {
99fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  bool operator()(const Descriptor::ExtensionRange* left,
100fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville                  const Descriptor::ExtensionRange* right) const {
101fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return left->start < right->start;
102fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
103fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville};
104fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
105fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Returns true if the message type has any required fields.  If it doesn't,
106fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// we can optimize out calls to its IsInitialized() method.
107fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville//
108fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// already_seen is used to avoid checking the same type multiple times
109fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// (and also to protect against recursion).
110fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillestatic bool HasRequiredFields(
111fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    const Descriptor* type,
112fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    hash_set<const Descriptor*>* already_seen) {
113fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (already_seen->count(type) > 0) {
114fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // Since the first occurrence of a required field causes the whole
115fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // function to return true, we can assume that if the type is already
116fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // in the cache it didn't have any required fields.
117fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return false;
118fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
119fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  already_seen->insert(type);
120fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
121fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // If the type has extensions, an extension with message type could contain
122fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // required fields, so we have to be conservative and assume such an
123fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // extension exists.
124fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (type->extension_range_count() > 0) return true;
125fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
126fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  for (int i = 0; i < type->field_count(); i++) {
127fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    const FieldDescriptor* field = type->field(i);
128fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    if (field->is_required()) {
129fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      return true;
130fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
131fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
132fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      if (HasRequiredFields(field->message_type(), already_seen)) {
133fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        return true;
134fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      }
135fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
136fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
137fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
138fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  return false;
139fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
140fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
141fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillestatic bool HasRequiredFields(const Descriptor* type) {
142fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  hash_set<const Descriptor*> already_seen;
143fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  return HasRequiredFields(type, &already_seen);
144fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
145fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
146fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
147fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
148fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// ===================================================================
149fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
150fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleMessageGenerator::MessageGenerator(const Descriptor* descriptor,
151fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville                                   const string& dllexport_decl)
152fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  : descriptor_(descriptor),
153fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    classname_(ClassName(descriptor, false)),
154fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    dllexport_decl_(dllexport_decl),
155fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    field_generators_(descriptor),
156fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    nested_generators_(new scoped_ptr<MessageGenerator>[
157fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      descriptor->nested_type_count()]),
158fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    enum_generators_(new scoped_ptr<EnumGenerator>[
159fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      descriptor->enum_type_count()]),
160fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    extension_generators_(new scoped_ptr<ExtensionGenerator>[
161fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      descriptor->extension_count()]) {
162fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
163fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  for (int i = 0; i < descriptor->nested_type_count(); i++) {
164fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    nested_generators_[i].reset(
165fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      new MessageGenerator(descriptor->nested_type(i), dllexport_decl));
166fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
167fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
168fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  for (int i = 0; i < descriptor->enum_type_count(); i++) {
169fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    enum_generators_[i].reset(
170fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      new EnumGenerator(descriptor->enum_type(i), dllexport_decl));
171fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
172fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
173fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  for (int i = 0; i < descriptor->extension_count(); i++) {
174fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    extension_generators_[i].reset(
175fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      new ExtensionGenerator(descriptor->extension(i), dllexport_decl));
176fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
177fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
178fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
179fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleMessageGenerator::~MessageGenerator() {}
180fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
181fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid MessageGenerator::
182fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleGenerateForwardDeclaration(io::Printer* printer) {
183fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Print("class $classname$;\n",
184fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville                 "classname", classname_);
185fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
186fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  for (int i = 0; i < descriptor_->nested_type_count(); i++) {
187fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    nested_generators_[i]->GenerateForwardDeclaration(printer);
188fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
189fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
190fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
191fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid MessageGenerator::
192fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleGenerateEnumDefinitions(io::Printer* printer) {
193fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  for (int i = 0; i < descriptor_->nested_type_count(); i++) {
194fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    nested_generators_[i]->GenerateEnumDefinitions(printer);
195fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
196fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
197fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  for (int i = 0; i < descriptor_->enum_type_count(); i++) {
198fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    enum_generators_[i]->GenerateDefinition(printer);
199fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
200fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
201fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
202fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid MessageGenerator::
203fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleGenerateGetEnumDescriptorSpecializations(io::Printer* printer) {
204fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  for (int i = 0; i < descriptor_->nested_type_count(); i++) {
205fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    nested_generators_[i]->GenerateGetEnumDescriptorSpecializations(printer);
206fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
207fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  for (int i = 0; i < descriptor_->enum_type_count(); i++) {
208fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    enum_generators_[i]->GenerateGetEnumDescriptorSpecializations(printer);
209fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
210fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
211fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
212fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid MessageGenerator::
213fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleGenerateFieldAccessorDeclarations(io::Printer* printer) {
214fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  for (int i = 0; i < descriptor_->field_count(); i++) {
215fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    const FieldDescriptor* field = descriptor_->field(i);
216fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
217fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    PrintFieldComment(printer, field);
218fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
219fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    map<string, string> vars;
220fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    SetCommonFieldVariables(field, &vars);
221fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    vars["constant_name"] = FieldConstantName(field);
222fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
223fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    if (field->is_repeated()) {
224fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      printer->Print(vars, "inline int $name$_size() const$deprecation$;\n");
225fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    } else {
226fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      printer->Print(vars, "inline bool has_$name$() const$deprecation$;\n");
227fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
228fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
229fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print(vars, "inline void clear_$name$()$deprecation$;\n");
230fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print(vars, "static const int $constant_name$ = $number$;\n");
231fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
232fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // Generate type-specific accessor declarations.
233fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    field_generators_.get(field).GenerateAccessorDeclarations(printer);
234fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
235fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print("\n");
236fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
237fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
238fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (descriptor_->extension_range_count() > 0) {
239fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // Generate accessors for extensions.  We just call a macro located in
240fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // extension_set.h since the accessors about 80 lines of static code.
241fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print(
242fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "GOOGLE_PROTOBUF_EXTENSION_ACCESSORS($classname$)\n",
243fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "classname", classname_);
244fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
245fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
246fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
247fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid MessageGenerator::
248fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleGenerateFieldAccessorDefinitions(io::Printer* printer) {
249fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Print("// $classname$\n\n", "classname", classname_);
250fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
251fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  for (int i = 0; i < descriptor_->field_count(); i++) {
252fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    const FieldDescriptor* field = descriptor_->field(i);
253fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
254fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    PrintFieldComment(printer, field);
255fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
256fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    map<string, string> vars;
257fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    SetCommonFieldVariables(field, &vars);
258fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
259fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // Generate has_$name$() or $name$_size().
260fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    if (field->is_repeated()) {
261fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      printer->Print(vars,
262fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        "inline int $classname$::$name$_size() const {\n"
263fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        "  return $name$_.size();\n"
264fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        "}\n");
265fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    } else {
266fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      // Singular field.
267fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      printer->Print(vars,
268fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        "inline bool $classname$::has_$name$() const {\n"
269fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        "  return _has_bit($index$);\n"
270fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        "}\n");
271fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
272fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
273fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // Generate clear_$name$()
274fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print(vars,
275fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "inline void $classname$::clear_$name$() {\n");
276fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
277fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Indent();
278fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    field_generators_.get(field).GenerateClearingCode(printer);
279fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Outdent();
280fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
281fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    if (!field->is_repeated()) {
282fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      printer->Print(vars, "  _clear_bit($index$);\n");
283fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
284fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
285fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print("}\n");
286fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
287fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // Generate type-specific accessors.
288fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    field_generators_.get(field).GenerateInlineAccessorDefinitions(printer);
289fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
290fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print("\n");
291fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
292fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
293fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
294fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid MessageGenerator::
295fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleGenerateClassDefinition(io::Printer* printer) {
296fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  for (int i = 0; i < descriptor_->nested_type_count(); i++) {
297fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    nested_generators_[i]->GenerateClassDefinition(printer);
298fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print("\n");
299fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print(kThinSeparator);
300fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print("\n");
301fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
302fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
303fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  map<string, string> vars;
304fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  vars["classname"] = classname_;
305fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  vars["field_count"] = SimpleItoa(descriptor_->field_count());
306fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (dllexport_decl_.empty()) {
307fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    vars["dllexport"] = "";
308fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  } else {
309fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    vars["dllexport"] = dllexport_decl_ + " ";
310fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
311d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  vars["superclass"] = SuperClassName(descriptor_);
312fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
313fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Print(vars,
314d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    "class $dllexport$$classname$ : public $superclass$ {\n"
315fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    " public:\n");
316fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Indent();
317fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
318fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Print(vars,
319fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "$classname$();\n"
320fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "virtual ~$classname$();\n"
321fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "\n"
322fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "$classname$(const $classname$& from);\n"
323fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "\n"
324fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "inline $classname$& operator=(const $classname$& from) {\n"
325fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "  CopyFrom(from);\n"
326fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "  return *this;\n"
327fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "}\n"
328fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "\n");
329fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
330fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (HasUnknownFields(descriptor_->file())) {
331fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print(
332fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {\n"
333fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "  return _unknown_fields_;\n"
334fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "}\n"
335fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "\n"
336fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {\n"
337fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "  return &_unknown_fields_;\n"
338fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "}\n"
339fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "\n");
340fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
341fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
342fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // Only generate this member if it's not disabled.
343fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (HasDescriptorMethods(descriptor_->file()) &&
344fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      !descriptor_->options().no_standard_descriptor_accessor()) {
345fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print(vars,
346fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "static const ::google::protobuf::Descriptor* descriptor();\n");
347fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
348fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
349fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Print(vars,
350fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "static const $classname$& default_instance();\n"
351d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    "\n");
352d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville
353d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville
354d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  printer->Print(vars,
355fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "void Swap($classname$* other);\n"
356fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "\n"
357fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "// implements Message ----------------------------------------------\n"
358fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "\n"
359fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "$classname$* New() const;\n");
360fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
361fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (HasGeneratedMethods(descriptor_->file())) {
362fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    if (HasDescriptorMethods(descriptor_->file())) {
363fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      printer->Print(vars,
364fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        "void CopyFrom(const ::google::protobuf::Message& from);\n"
365fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        "void MergeFrom(const ::google::protobuf::Message& from);\n");
366fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    } else {
367fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      printer->Print(vars,
368fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        "void CheckTypeAndMergeFrom(const ::google::protobuf::MessageLite& from);\n");
369fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
370fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
371fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print(vars,
372fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "void CopyFrom(const $classname$& from);\n"
373fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "void MergeFrom(const $classname$& from);\n"
374fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "void Clear();\n"
375fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "bool IsInitialized() const;\n"
376fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "\n"
377fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "int ByteSize() const;\n"
378fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "bool MergePartialFromCodedStream(\n"
379fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "    ::google::protobuf::io::CodedInputStream* input);\n"
380fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "void SerializeWithCachedSizes(\n"
381fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "    ::google::protobuf::io::CodedOutputStream* output) const;\n");
382fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    if (HasFastArraySerialization(descriptor_->file())) {
383fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      printer->Print(
384fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        "::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;\n");
385fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
386fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
387fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
388fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Print(vars,
389fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "int GetCachedSize() const { return _cached_size_; }\n"
390fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "private:\n"
391fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "void SharedCtor();\n"
392fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "void SharedDtor();\n"
393d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    "void SetCachedSize(int size) const;\n"
394fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "public:\n"
395fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "\n");
396fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
397fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (HasDescriptorMethods(descriptor_->file())) {
398fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print(
399fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "::google::protobuf::Metadata GetMetadata() const;\n"
400fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "\n");
401fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  } else {
402fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print(
403fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "::std::string GetTypeName() const;\n"
404fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "\n");
405fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
406fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
407fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Print(
408fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "// nested types ----------------------------------------------------\n"
409fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "\n");
410fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
411fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // Import all nested message classes into this class's scope with typedefs.
412fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  for (int i = 0; i < descriptor_->nested_type_count(); i++) {
413fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    const Descriptor* nested_type = descriptor_->nested_type(i);
414fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print("typedef $nested_full_name$ $nested_name$;\n",
415fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville                   "nested_name", nested_type->name(),
416fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville                   "nested_full_name", ClassName(nested_type, false));
417fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
418fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
419fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (descriptor_->nested_type_count() > 0) {
420fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print("\n");
421fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
422fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
423fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // Import all nested enums and their values into this class's scope with
424fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // typedefs and constants.
425fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  for (int i = 0; i < descriptor_->enum_type_count(); i++) {
426fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    enum_generators_[i]->GenerateSymbolImports(printer);
427fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print("\n");
428fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
429fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
430fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Print(
431fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "// accessors -------------------------------------------------------\n"
432fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "\n");
433fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
434fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // Generate accessor methods for all fields.
435fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  GenerateFieldAccessorDeclarations(printer);
436fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
437fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // Declare extension identifiers.
438fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  for (int i = 0; i < descriptor_->extension_count(); i++) {
439fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    extension_generators_[i]->GenerateDeclaration(printer);
440fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
441fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
442d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville
443d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  printer->Print(
444d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    "// @@protoc_insertion_point(class_scope:$full_name$)\n",
445d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    "full_name", descriptor_->full_name());
446d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville
447fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // Generate private members for fields.
448fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Outdent();
449fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Print(" private:\n");
450fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Indent();
451fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
452fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (descriptor_->extension_range_count() > 0) {
453fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print(
454fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "::google::protobuf::internal::ExtensionSet _extensions_;\n");
455fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
456fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
457fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (HasUnknownFields(descriptor_->file())) {
458fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print(
459fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "::google::protobuf::UnknownFieldSet _unknown_fields_;\n");
460fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
461fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
462fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // TODO(kenton):  Make _cached_size_ an atomic<int> when C++ supports it.
463fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Print(
464fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "mutable int _cached_size_;\n"
465fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "\n");
466fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  for (int i = 0; i < descriptor_->field_count(); i++) {
467fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    field_generators_.get(descriptor_->field(i))
468fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville                     .GeneratePrivateMembers(printer);
469fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
470fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
471fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // Declare AddDescriptors(), BuildDescriptors(), and ShutdownFile() as
472fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // friends so that they can access private static variables like
473fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // default_instance_ and reflection_.
474fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Print(
475fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "friend void $dllexport_decl$ $adddescriptorsname$();\n",
476fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "dllexport_decl", dllexport_decl_,
477fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "adddescriptorsname",
478fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      GlobalAddDescriptorsName(descriptor_->file()->name()));
479fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Print(
480fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "friend void $assigndescriptorsname$();\n"
481fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "friend void $shutdownfilename$();\n"
482fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "\n",
483fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "assigndescriptorsname",
484fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      GlobalAssignDescriptorsName(descriptor_->file()->name()),
485fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "shutdownfilename", GlobalShutdownFileName(descriptor_->file()->name()));
486fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
487fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // Generate offsets and _has_bits_ boilerplate.
488fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (descriptor_->field_count() > 0) {
489fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print(vars,
490fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "::google::protobuf::uint32 _has_bits_[($field_count$ + 31) / 32];\n");
491fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  } else {
492fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // Zero-size arrays aren't technically allowed, and MSVC in particular
493fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // doesn't like them.  We still need to declare these arrays to make
494fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // other code compile.  Since this is an uncommon case, we'll just declare
495fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // them with size 1 and waste some space.  Oh well.
496fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print(
497fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "::google::protobuf::uint32 _has_bits_[1];\n");
498fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
499fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
500fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Print(
501fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "\n"
502fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "// WHY DOES & HAVE LOWER PRECEDENCE THAN != !?\n"
503fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "inline bool _has_bit(int index) const {\n"
504fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "  return (_has_bits_[index / 32] & (1u << (index % 32))) != 0;\n"
505fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "}\n"
506fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "inline void _set_bit(int index) {\n"
507fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "  _has_bits_[index / 32] |= (1u << (index % 32));\n"
508fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "}\n"
509fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "inline void _clear_bit(int index) {\n"
510fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "  _has_bits_[index / 32] &= ~(1u << (index % 32));\n"
511fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "}\n"
512fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "\n"
513fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "void InitAsDefaultInstance();\n"
514fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "static $classname$* default_instance_;\n",
515fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "classname", classname_);
516fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
517fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Outdent();
518fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Print(vars, "};");
519fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
520fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
521fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid MessageGenerator::
522fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleGenerateInlineMethods(io::Printer* printer) {
523fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  for (int i = 0; i < descriptor_->nested_type_count(); i++) {
524fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    nested_generators_[i]->GenerateInlineMethods(printer);
525fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print(kThinSeparator);
526fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print("\n");
527fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
528fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
529fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  GenerateFieldAccessorDefinitions(printer);
530fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
531fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
532fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid MessageGenerator::
533fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleGenerateDescriptorDeclarations(io::Printer* printer) {
534fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Print(
535fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "const ::google::protobuf::Descriptor* $name$_descriptor_ = NULL;\n"
536fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "const ::google::protobuf::internal::GeneratedMessageReflection*\n"
537fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "  $name$_reflection_ = NULL;\n",
538fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "name", classname_);
539fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
540fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  for (int i = 0; i < descriptor_->nested_type_count(); i++) {
541fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    nested_generators_[i]->GenerateDescriptorDeclarations(printer);
542fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
543fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
544fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  for (int i = 0; i < descriptor_->enum_type_count(); i++) {
545fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print(
546fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "const ::google::protobuf::EnumDescriptor* $name$_descriptor_ = NULL;\n",
547fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "name", ClassName(descriptor_->enum_type(i), false));
548fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
549fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
550fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
551fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid MessageGenerator::
552fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleGenerateDescriptorInitializer(io::Printer* printer, int index) {
553fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // TODO(kenton):  Passing the index to this method is redundant; just use
554fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  //   descriptor_->index() instead.
555fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  map<string, string> vars;
556fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  vars["classname"] = classname_;
557fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  vars["index"] = SimpleItoa(index);
558fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
559fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // Obtain the descriptor from the parent's descriptor.
560fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (descriptor_->containing_type() == NULL) {
561fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print(vars,
562fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "$classname$_descriptor_ = file->message_type($index$);\n");
563fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  } else {
564fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    vars["parent"] = ClassName(descriptor_->containing_type(), false);
565fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print(vars,
566fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "$classname$_descriptor_ = "
567fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        "$parent$_descriptor_->nested_type($index$);\n");
568fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
569fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
570fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // Generate the offsets.
571fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  GenerateOffsets(printer);
572fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
573fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // Construct the reflection object.
574fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Print(vars,
575fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "$classname$_reflection_ =\n"
576fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "  new ::google::protobuf::internal::GeneratedMessageReflection(\n"
577fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "    $classname$_descriptor_,\n"
578fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "    $classname$::default_instance_,\n"
579fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "    $classname$_offsets_,\n"
580fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET($classname$, _has_bits_[0]),\n"
581fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET("
582fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "$classname$, _unknown_fields_),\n");
583fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (descriptor_->extension_range_count() > 0) {
584fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print(vars,
585fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET("
586fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        "$classname$, _extensions_),\n");
587fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  } else {
588fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // No extensions.
589fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print(vars,
590fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "    -1,\n");
591fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
592fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Print(vars,
593fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "    ::google::protobuf::DescriptorPool::generated_pool(),\n"
594fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "    ::google::protobuf::MessageFactory::generated_factory(),\n"
595fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "    sizeof($classname$));\n");
596fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
597fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // Handle nested types.
598fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  for (int i = 0; i < descriptor_->nested_type_count(); i++) {
599fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    nested_generators_[i]->GenerateDescriptorInitializer(printer, i);
600fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
601fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
602fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  for (int i = 0; i < descriptor_->enum_type_count(); i++) {
603fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    enum_generators_[i]->GenerateDescriptorInitializer(printer, i);
604fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
605fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
606fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
607fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid MessageGenerator::
608fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleGenerateTypeRegistrations(io::Printer* printer) {
609fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // Register this message type with the message factory.
610fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Print(
611fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(\n"
612fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "  $classname$_descriptor_, &$classname$::default_instance());\n",
613fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "classname", classname_);
614fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
615fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // Handle nested types.
616fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  for (int i = 0; i < descriptor_->nested_type_count(); i++) {
617fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    nested_generators_[i]->GenerateTypeRegistrations(printer);
618fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
619fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
620fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
621fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid MessageGenerator::
622fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleGenerateDefaultInstanceAllocator(io::Printer* printer) {
623fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // Construct the default instance.  We can't call InitAsDefaultInstance() yet
624fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // because we need to make sure all default instances that this one might
625fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // depend on are constructed first.
626fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Print(
627fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "$classname$::default_instance_ = new $classname$();\n",
628fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "classname", classname_);
629fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
630fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // Handle nested types.
631fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  for (int i = 0; i < descriptor_->nested_type_count(); i++) {
632fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    nested_generators_[i]->GenerateDefaultInstanceAllocator(printer);
633fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
634d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville
635fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
636fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
637fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid MessageGenerator::
638fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleGenerateDefaultInstanceInitializer(io::Printer* printer) {
639fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Print(
640fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "$classname$::default_instance_->InitAsDefaultInstance();\n",
641fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "classname", classname_);
642fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
643fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // Register extensions.
644fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  for (int i = 0; i < descriptor_->extension_count(); i++) {
645fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    extension_generators_[i]->GenerateRegistration(printer);
646fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
647fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
648fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // Handle nested types.
649fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  for (int i = 0; i < descriptor_->nested_type_count(); i++) {
650fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    nested_generators_[i]->GenerateDefaultInstanceInitializer(printer);
651fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
652fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
653fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
654fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid MessageGenerator::
655fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleGenerateShutdownCode(io::Printer* printer) {
656fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Print(
657fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "delete $classname$::default_instance_;\n",
658fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "classname", classname_);
659fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
660fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (HasDescriptorMethods(descriptor_->file())) {
661fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print(
662fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "delete $classname$_reflection_;\n",
663fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "classname", classname_);
664fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
665fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
666fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // Handle nested types.
667fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  for (int i = 0; i < descriptor_->nested_type_count(); i++) {
668fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    nested_generators_[i]->GenerateShutdownCode(printer);
669fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
670fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
671fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
672fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid MessageGenerator::
673fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleGenerateClassMethods(io::Printer* printer) {
674fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  for (int i = 0; i < descriptor_->enum_type_count(); i++) {
675fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    enum_generators_[i]->GenerateMethods(printer);
676fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
677fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
678fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  for (int i = 0; i < descriptor_->nested_type_count(); i++) {
679fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    nested_generators_[i]->GenerateClassMethods(printer);
680fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print("\n");
681fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print(kThinSeparator);
682fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print("\n");
683fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
684fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
685fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // Generate non-inline field definitions.
686fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  for (int i = 0; i < descriptor_->field_count(); i++) {
687fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    field_generators_.get(descriptor_->field(i))
688fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville                     .GenerateNonInlineAccessorDefinitions(printer);
689fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
690fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
691fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // Generate field number constants.
692fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Print("#ifndef _MSC_VER\n");
693fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  for (int i = 0; i < descriptor_->field_count(); i++) {
694fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    const FieldDescriptor *field = descriptor_->field(i);
695fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print(
696fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "const int $classname$::$constant_name$;\n",
697fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "classname", ClassName(FieldScope(field), false),
698fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "constant_name", FieldConstantName(field));
699fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
700fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Print(
701fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "#endif  // !_MSC_VER\n"
702fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "\n");
703fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
704fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // Define extension identifiers.
705fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  for (int i = 0; i < descriptor_->extension_count(); i++) {
706fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    extension_generators_[i]->GenerateDefinition(printer);
707fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
708fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
709fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  GenerateStructors(printer);
710fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Print("\n");
711fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
712fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (HasGeneratedMethods(descriptor_->file())) {
713fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    GenerateClear(printer);
714fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print("\n");
715fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
716fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    GenerateMergeFromCodedStream(printer);
717fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print("\n");
718fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
719fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    GenerateSerializeWithCachedSizes(printer);
720fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print("\n");
721fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
722fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    if (HasFastArraySerialization(descriptor_->file())) {
723fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      GenerateSerializeWithCachedSizesToArray(printer);
724fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      printer->Print("\n");
725fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
726fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
727fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    GenerateByteSize(printer);
728fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print("\n");
729fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
730fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    GenerateMergeFrom(printer);
731fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print("\n");
732fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
733fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    GenerateCopyFrom(printer);
734fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print("\n");
735fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
736fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    GenerateIsInitialized(printer);
737fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print("\n");
738fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
739fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
740fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  GenerateSwap(printer);
741fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Print("\n");
742fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
743fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (HasDescriptorMethods(descriptor_->file())) {
744fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print(
745fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "::google::protobuf::Metadata $classname$::GetMetadata() const {\n"
746fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "  protobuf_AssignDescriptorsOnce();\n"
747fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "  ::google::protobuf::Metadata metadata;\n"
748fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "  metadata.descriptor = $classname$_descriptor_;\n"
749fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "  metadata.reflection = $classname$_reflection_;\n"
750fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "  return metadata;\n"
751fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "}\n"
752fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "\n",
753fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "classname", classname_);
754fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  } else {
755fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print(
756fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "::std::string $classname$::GetTypeName() const {\n"
757fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "  return \"$type_name$\";\n"
758fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "}\n"
759fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "\n",
760fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "classname", classname_,
761fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "type_name", descriptor_->full_name());
762fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
763d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville
764fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
765fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
766fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid MessageGenerator::
767fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleGenerateOffsets(io::Printer* printer) {
768fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Print(
769fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "static const int $classname$_offsets_[$field_count$] = {\n",
770fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "classname", classname_,
771fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "field_count", SimpleItoa(max(1, descriptor_->field_count())));
772fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Indent();
773fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
774fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  for (int i = 0; i < descriptor_->field_count(); i++) {
775fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    const FieldDescriptor* field = descriptor_->field(i);
776fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print(
777fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET($classname$, $name$_),\n",
778fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "classname", classname_,
779fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "name", FieldName(field));
780fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
781fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
782fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Outdent();
783fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Print("};\n");
784fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
785fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
786fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid MessageGenerator::
787fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleGenerateSharedConstructorCode(io::Printer* printer) {
788fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Print(
789fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "void $classname$::SharedCtor() {\n",
790fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "classname", classname_);
791fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Indent();
792fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
793fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Print(
794fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "_cached_size_ = 0;\n");
795fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
796fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  for (int i = 0; i < descriptor_->field_count(); i++) {
797fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    field_generators_.get(descriptor_->field(i))
798fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville                     .GenerateConstructorCode(printer);
799fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
800fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
801fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Print(
802fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "::memset(_has_bits_, 0, sizeof(_has_bits_));\n");
803fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
804fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Outdent();
805fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Print("}\n\n");
806fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
807fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
808fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid MessageGenerator::
809fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleGenerateSharedDestructorCode(io::Printer* printer) {
810fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Print(
811fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "void $classname$::SharedDtor() {\n",
812fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "classname", classname_);
813fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Indent();
814fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // Write the destructors for each field.
815fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  for (int i = 0; i < descriptor_->field_count(); i++) {
816fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    field_generators_.get(descriptor_->field(i))
817fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville                     .GenerateDestructorCode(printer);
818fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
819fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
820fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Print(
821fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "if (this != default_instance_) {\n");
822fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
823fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // We need to delete all embedded messages.
824fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // TODO(kenton):  If we make unset messages point at default instances
825fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  //   instead of NULL, then it would make sense to move this code into
826fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  //   MessageFieldGenerator::GenerateDestructorCode().
827fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  for (int i = 0; i < descriptor_->field_count(); i++) {
828fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    const FieldDescriptor* field = descriptor_->field(i);
829fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
830fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    if (!field->is_repeated() &&
831fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
832fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      printer->Print("  delete $name$_;\n",
833fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville                     "name", FieldName(field));
834fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
835fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
836fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
837fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Outdent();
838fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Print(
839fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "  }\n"
840fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "}\n"
841fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "\n");
842fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
843fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
844fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid MessageGenerator::
845fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleGenerateStructors(io::Printer* printer) {
846d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  string superclass = SuperClassName(descriptor_);
847d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville
848fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // Generate the default constructor.
849fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Print(
850d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    "$classname$::$classname$()\n"
851d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    "  : $superclass$() {\n"
852fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "  SharedCtor();\n"
853fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "}\n",
854d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    "classname", classname_,
855d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    "superclass", superclass);
856fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
857fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Print(
858fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "\n"
859fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "void $classname$::InitAsDefaultInstance() {\n",
860fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "classname", classname_);
861fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
862fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // The default instance needs all of its embedded message pointers
863fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // cross-linked to other default instances.  We can't do this initialization
864fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // in the constructor because some other default instances may not have been
865fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // constructed yet at that time.
866fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // TODO(kenton):  Maybe all message fields (even for non-default messages)
867fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  //   should be initialized to point at default instances rather than NULL?
868fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  for (int i = 0; i < descriptor_->field_count(); i++) {
869fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    const FieldDescriptor* field = descriptor_->field(i);
870fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
871fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    if (!field->is_repeated() &&
872fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
873fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      printer->Print(
874fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville          "  $name$_ = const_cast< $type$*>(&$type$::default_instance());\n",
875fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville          "name", FieldName(field),
876d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville          "type", FieldMessageTypeName(field));
877fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
878fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
879fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Print(
880fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "}\n"
881fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "\n");
882fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
883fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // Generate the copy constructor.
884fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Print(
885d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    "$classname$::$classname$(const $classname$& from)\n"
886d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    "  : $superclass$() {\n"
887fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "  SharedCtor();\n"
888fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "  MergeFrom(from);\n"
889fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "}\n"
890fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "\n",
891d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    "classname", classname_,
892d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    "superclass", superclass);
893fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
894fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // Generate the shared constructor code.
895fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  GenerateSharedConstructorCode(printer);
896fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
897fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // Generate the destructor.
898fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Print(
899fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "$classname$::~$classname$() {\n"
900fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "  SharedDtor();\n"
901fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "}\n"
902fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "\n",
903fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "classname", classname_);
904fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
905fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // Generate the shared destructor code.
906fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  GenerateSharedDestructorCode(printer);
907fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
908d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  // Generate SetCachedSize.
909d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  printer->Print(
910d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    "void $classname$::SetCachedSize(int size) const {\n"
911d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    "  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();\n"
912d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    "  _cached_size_ = size;\n"
913d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    "  GOOGLE_SAFE_CONCURRENT_WRITES_END();\n"
914d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    "}\n",
915d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    "classname", classname_);
916d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville
917fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // Only generate this member if it's not disabled.
918fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (HasDescriptorMethods(descriptor_->file()) &&
919fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      !descriptor_->options().no_standard_descriptor_accessor()) {
920fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print(
921fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "const ::google::protobuf::Descriptor* $classname$::descriptor() {\n"
922fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "  protobuf_AssignDescriptorsOnce();\n"
923fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "  return $classname$_descriptor_;\n"
924fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "}\n"
925fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "\n",
926fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "classname", classname_,
927fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "adddescriptorsname",
928fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      GlobalAddDescriptorsName(descriptor_->file()->name()));
929fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
930fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
931fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Print(
932fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "const $classname$& $classname$::default_instance() {\n"
933fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "  if (default_instance_ == NULL) $adddescriptorsname$();"
934fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "  return *default_instance_;\n"
935fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "}\n"
936fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "\n"
937fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "$classname$* $classname$::default_instance_ = NULL;\n"
938fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "\n"
939fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "$classname$* $classname$::New() const {\n"
940fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "  return new $classname$;\n"
941fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "}\n",
942fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "classname", classname_,
943fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "adddescriptorsname",
944fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    GlobalAddDescriptorsName(descriptor_->file()->name()));
945d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville
946fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
947fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
948fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid MessageGenerator::
949fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleGenerateClear(io::Printer* printer) {
950fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Print("void $classname$::Clear() {\n",
951fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville                 "classname", classname_);
952fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Indent();
953fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
954fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  int last_index = -1;
955fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
956fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (descriptor_->extension_range_count() > 0) {
957fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print("_extensions_.Clear();\n");
958fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
959fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
960fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  for (int i = 0; i < descriptor_->field_count(); i++) {
961fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    const FieldDescriptor* field = descriptor_->field(i);
962fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
963fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    if (!field->is_repeated()) {
964fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      map<string, string> vars;
965fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      vars["index"] = SimpleItoa(field->index());
966fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
967fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      // We can use the fact that _has_bits_ is a giant bitfield to our
968fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      // advantage:  We can check up to 32 bits at a time for equality to
969fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      // zero, and skip the whole range if so.  This can improve the speed
970fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      // of Clear() for messages which contain a very large number of
971fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      // optional fields of which only a few are used at a time.  Here,
972fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      // we've chosen to check 8 bits at a time rather than 32.
973fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      if (i / 8 != last_index / 8 || last_index < 0) {
974fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        if (last_index >= 0) {
975fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville          printer->Outdent();
976fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville          printer->Print("}\n");
977fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        }
978fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        printer->Print(vars,
979fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville          "if (_has_bits_[$index$ / 32] & (0xffu << ($index$ % 32))) {\n");
980fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        printer->Indent();
981fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      }
982fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      last_index = i;
983fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
984fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      // It's faster to just overwrite primitive types, but we should
985fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      // only clear strings and messages if they were set.
986fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      // TODO(kenton):  Let the CppFieldGenerator decide this somehow.
987fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      bool should_check_bit =
988fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE ||
989fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        field->cpp_type() == FieldDescriptor::CPPTYPE_STRING;
990fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
991fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      if (should_check_bit) {
992fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        printer->Print(vars, "if (_has_bit($index$)) {\n");
993fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        printer->Indent();
994fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      }
995fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
996fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      field_generators_.get(field).GenerateClearingCode(printer);
997fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
998fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      if (should_check_bit) {
999fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        printer->Outdent();
1000fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        printer->Print("}\n");
1001fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      }
1002fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
1003fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
1004fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1005fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (last_index >= 0) {
1006fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Outdent();
1007fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print("}\n");
1008fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
1009fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1010fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // Repeated fields don't use _has_bits_ so we clear them in a separate
1011fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // pass.
1012fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  for (int i = 0; i < descriptor_->field_count(); i++) {
1013fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    const FieldDescriptor* field = descriptor_->field(i);
1014fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1015fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    if (field->is_repeated()) {
1016fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      field_generators_.get(field).GenerateClearingCode(printer);
1017fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
1018fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
1019fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1020fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Print(
1021fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "::memset(_has_bits_, 0, sizeof(_has_bits_));\n");
1022fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1023fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (HasUnknownFields(descriptor_->file())) {
1024fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print(
1025fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "mutable_unknown_fields()->Clear();\n");
1026fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
1027fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1028fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Outdent();
1029fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Print("}\n");
1030fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
1031fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1032fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid MessageGenerator::
1033fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleGenerateSwap(io::Printer* printer) {
1034fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // Generate the Swap member function.
1035fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Print("void $classname$::Swap($classname$* other) {\n",
1036fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville                 "classname", classname_);
1037fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Indent();
1038fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Print("if (other != this) {\n");
1039fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Indent();
1040fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1041fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (HasGeneratedMethods(descriptor_->file())) {
1042fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    for (int i = 0; i < descriptor_->field_count(); i++) {
1043fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      const FieldDescriptor* field = descriptor_->field(i);
1044fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      field_generators_.get(field).GenerateSwappingCode(printer);
1045fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
1046fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1047fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    for (int i = 0; i < (descriptor_->field_count() + 31) / 32; ++i) {
1048fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      printer->Print("std::swap(_has_bits_[$i$], other->_has_bits_[$i$]);\n",
1049fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville                     "i", SimpleItoa(i));
1050fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
1051fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1052fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    if (HasUnknownFields(descriptor_->file())) {
1053fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      printer->Print("_unknown_fields_.Swap(&other->_unknown_fields_);\n");
1054fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
1055fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print("std::swap(_cached_size_, other->_cached_size_);\n");
1056fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    if (descriptor_->extension_range_count() > 0) {
1057fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      printer->Print("_extensions_.Swap(&other->_extensions_);\n");
1058fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
1059fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  } else {
1060fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print("GetReflection()->Swap(this, other);");
1061fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
1062fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1063fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Outdent();
1064fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Print("}\n");
1065fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Outdent();
1066fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Print("}\n");
1067fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
1068fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1069fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid MessageGenerator::
1070fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleGenerateMergeFrom(io::Printer* printer) {
1071fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (HasDescriptorMethods(descriptor_->file())) {
1072fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // Generate the generalized MergeFrom (aka that which takes in the Message
1073fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // base class as a parameter).
1074fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print(
1075fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "void $classname$::MergeFrom(const ::google::protobuf::Message& from) {\n"
1076fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "  GOOGLE_CHECK_NE(&from, this);\n",
1077fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "classname", classname_);
1078fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Indent();
1079fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1080fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // Cast the message to the proper type. If we find that the message is
1081fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // *not* of the proper type, we can still call Merge via the reflection
1082fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // system, as the GOOGLE_CHECK above ensured that we have the same descriptor
1083fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // for each message.
1084fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print(
1085fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "const $classname$* source =\n"
1086fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "  ::google::protobuf::internal::dynamic_cast_if_available<const $classname$*>(\n"
1087fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "    &from);\n"
1088fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "if (source == NULL) {\n"
1089fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "  ::google::protobuf::internal::ReflectionOps::Merge(from, this);\n"
1090fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "} else {\n"
1091fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "  MergeFrom(*source);\n"
1092fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "}\n",
1093fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "classname", classname_);
1094fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1095fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Outdent();
1096fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print("}\n\n");
1097fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  } else {
1098fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // Generate CheckTypeAndMergeFrom().
1099fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print(
1100fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "void $classname$::CheckTypeAndMergeFrom(\n"
1101fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "    const ::google::protobuf::MessageLite& from) {\n"
1102fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "  MergeFrom(*::google::protobuf::down_cast<const $classname$*>(&from));\n"
1103fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "}\n"
1104fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "\n",
1105fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "classname", classname_);
1106fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
1107fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1108fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // Generate the class-specific MergeFrom, which avoids the GOOGLE_CHECK and cast.
1109fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Print(
1110fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "void $classname$::MergeFrom(const $classname$& from) {\n"
1111fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "  GOOGLE_CHECK_NE(&from, this);\n",
1112fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "classname", classname_);
1113fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Indent();
1114fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1115fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // Merge Repeated fields. These fields do not require a
1116fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // check as we can simply iterate over them.
1117fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  for (int i = 0; i < descriptor_->field_count(); ++i) {
1118fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    const FieldDescriptor* field = descriptor_->field(i);
1119fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1120fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    if (field->is_repeated()) {
1121fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      field_generators_.get(field).GenerateMergingCode(printer);
1122fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
1123fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
1124fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1125fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // Merge Optional and Required fields (after a _has_bit check).
1126fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  int last_index = -1;
1127fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1128fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  for (int i = 0; i < descriptor_->field_count(); ++i) {
1129fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    const FieldDescriptor* field = descriptor_->field(i);
1130fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1131fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    if (!field->is_repeated()) {
1132fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      map<string, string> vars;
1133fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      vars["index"] = SimpleItoa(field->index());
1134fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1135fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      // See above in GenerateClear for an explanation of this.
1136fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      if (i / 8 != last_index / 8 || last_index < 0) {
1137fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        if (last_index >= 0) {
1138fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville          printer->Outdent();
1139fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville          printer->Print("}\n");
1140fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        }
1141fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        printer->Print(vars,
1142fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville          "if (from._has_bits_[$index$ / 32] & (0xffu << ($index$ % 32))) {\n");
1143fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        printer->Indent();
1144fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      }
1145fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1146fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      last_index = i;
1147fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1148fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      printer->Print(vars,
1149fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        "if (from._has_bit($index$)) {\n");
1150fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      printer->Indent();
1151fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1152fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      field_generators_.get(field).GenerateMergingCode(printer);
1153fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1154fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      printer->Outdent();
1155fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      printer->Print("}\n");
1156fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
1157fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
1158fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1159fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (last_index >= 0) {
1160fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Outdent();
1161fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print("}\n");
1162fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
1163fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1164fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (descriptor_->extension_range_count() > 0) {
1165fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print("_extensions_.MergeFrom(from._extensions_);\n");
1166fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
1167fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1168fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (HasUnknownFields(descriptor_->file())) {
1169fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print(
1170fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "mutable_unknown_fields()->MergeFrom(from.unknown_fields());\n");
1171fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
1172fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1173fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Outdent();
1174fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Print("}\n");
1175fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
1176fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1177fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid MessageGenerator::
1178fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleGenerateCopyFrom(io::Printer* printer) {
1179fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (HasDescriptorMethods(descriptor_->file())) {
1180fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // Generate the generalized CopyFrom (aka that which takes in the Message
1181fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // base class as a parameter).
1182fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print(
1183fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "void $classname$::CopyFrom(const ::google::protobuf::Message& from) {\n",
1184fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "classname", classname_);
1185fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Indent();
1186fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1187fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print(
1188fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "if (&from == this) return;\n"
1189fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "Clear();\n"
1190fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "MergeFrom(from);\n");
1191fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1192fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Outdent();
1193fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print("}\n\n");
1194fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
1195fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1196fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // Generate the class-specific CopyFrom.
1197fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Print(
1198fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "void $classname$::CopyFrom(const $classname$& from) {\n",
1199fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "classname", classname_);
1200fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Indent();
1201fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1202fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Print(
1203fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "if (&from == this) return;\n"
1204fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "Clear();\n"
1205fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "MergeFrom(from);\n");
1206fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1207fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Outdent();
1208fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Print("}\n");
1209fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
1210fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1211fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid MessageGenerator::
1212fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleGenerateMergeFromCodedStream(io::Printer* printer) {
1213fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (descriptor_->options().message_set_wire_format()) {
1214fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // Special-case MessageSet.
1215fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print(
1216fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "bool $classname$::MergePartialFromCodedStream(\n"
1217fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "    ::google::protobuf::io::CodedInputStream* input) {\n"
1218fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "  return _extensions_.ParseMessageSet(input, default_instance_,\n"
1219fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "                                      mutable_unknown_fields());\n"
1220fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "}\n",
1221fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "classname", classname_);
1222fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return;
1223fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
1224fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1225fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Print(
1226fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "bool $classname$::MergePartialFromCodedStream(\n"
1227fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "    ::google::protobuf::io::CodedInputStream* input) {\n"
1228fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "#define DO_(EXPRESSION) if (!(EXPRESSION)) return false\n"
1229fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "  ::google::protobuf::uint32 tag;\n"
1230fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "  while ((tag = input->ReadTag()) != 0) {\n",
1231fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "classname", classname_);
1232fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1233fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Indent();
1234fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Indent();
1235fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1236fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (descriptor_->field_count() > 0) {
1237fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // We don't even want to print the switch() if we have no fields because
1238fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // MSVC dislikes switch() statements that contain only a default value.
1239fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1240fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // Note:  If we just switched on the tag rather than the field number, we
1241fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // could avoid the need for the if() to check the wire type at the beginning
1242fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // of each case.  However, this is actually a bit slower in practice as it
1243fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // creates a jump table that is 8x larger and sparser, and meanwhile the
1244fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // if()s are highly predictable.
1245fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print(
1246fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {\n");
1247fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1248fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Indent();
1249fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1250fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    scoped_array<const FieldDescriptor*> ordered_fields(
1251fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      SortFieldsByNumber(descriptor_));
1252fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1253fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    for (int i = 0; i < descriptor_->field_count(); i++) {
1254fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      const FieldDescriptor* field = ordered_fields[i];
1255fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1256fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      PrintFieldComment(printer, field);
1257fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1258fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      printer->Print(
1259d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville        "case $number$: {\n",
1260d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville        "number", SimpleItoa(field->number()));
1261d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville      printer->Indent();
1262d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville      const FieldGenerator& field_generator = field_generators_.get(field);
1263d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville
1264d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville      // Emit code to parse the common, expected case.
1265d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville      printer->Print(
1266d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville        "if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==\n"
1267d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville        "    ::google::protobuf::internal::WireFormatLite::WIRETYPE_$wiretype$) {\n",
1268fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        "wiretype", kWireTypeNames[WireFormat::WireTypeForField(field)]);
1269fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1270fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      if (i > 0 || (field->is_repeated() && !field->options().packed())) {
1271fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        printer->Print(
1272fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville          " parse_$name$:\n",
1273fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville          "name", field->name());
1274fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      }
1275fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1276fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      printer->Indent();
1277d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville      if (field->options().packed()) {
1278d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville        field_generator.GenerateMergeFromCodedStreamWithPacking(printer);
1279d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville      } else {
1280d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville        field_generator.GenerateMergeFromCodedStream(printer);
1281d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville      }
1282d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville      printer->Outdent();
1283fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1284d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville      // Emit code to parse unexpectedly packed or unpacked values.
1285d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville      if (field->is_packable() && field->options().packed()) {
1286d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville        printer->Print(
1287d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville          "} else if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag)\n"
1288d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville          "           == ::google::protobuf::internal::WireFormatLite::\n"
1289d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville          "              WIRETYPE_$wiretype$) {\n",
1290d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville          "wiretype",
1291d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville          kWireTypeNames[WireFormat::WireTypeForFieldType(field->type())]);
1292d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville        printer->Indent();
1293d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville        field_generator.GenerateMergeFromCodedStream(printer);
1294d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville        printer->Outdent();
1295d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville      } else if (field->is_packable() && !field->options().packed()) {
1296d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville        printer->Print(
1297d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville          "} else if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag)\n"
1298d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville          "           == ::google::protobuf::internal::WireFormatLite::\n"
1299d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville          "              WIRETYPE_LENGTH_DELIMITED) {\n");
1300d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville        printer->Indent();
1301d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville        field_generator.GenerateMergeFromCodedStreamWithPacking(printer);
1302d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville        printer->Outdent();
1303d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville      }
1304d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville
1305d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville      printer->Print(
1306d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville        "} else {\n"
1307d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville        "  goto handle_uninterpreted;\n"
1308d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville        "}\n");
1309fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1310fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      // switch() is slow since it can't be predicted well.  Insert some if()s
1311fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      // here that attempt to predict the next tag.
1312fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      if (field->is_repeated() && !field->options().packed()) {
1313fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        // Expect repeats of this field.
1314fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        printer->Print(
1315fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville          "if (input->ExpectTag($tag$)) goto parse_$name$;\n",
1316fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville          "tag", SimpleItoa(WireFormat::MakeTag(field)),
1317fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville          "name", field->name());
1318fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      }
1319fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1320fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      if (i + 1 < descriptor_->field_count()) {
1321fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        // Expect the next field in order.
1322fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        const FieldDescriptor* next_field = ordered_fields[i + 1];
1323fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        printer->Print(
1324fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville          "if (input->ExpectTag($next_tag$)) goto parse_$next_name$;\n",
1325fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville          "next_tag", SimpleItoa(WireFormat::MakeTag(next_field)),
1326fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville          "next_name", next_field->name());
1327fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      } else {
1328fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        // Expect EOF.
1329fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        // TODO(kenton):  Expect group end-tag?
1330fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        printer->Print(
1331fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville          "if (input->ExpectAtEnd()) return true;\n");
1332fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      }
1333fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1334fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      printer->Print(
1335fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        "break;\n");
1336fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1337fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      printer->Outdent();
1338fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      printer->Print("}\n\n");
1339fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
1340fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1341fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print(
1342fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "default: {\n"
1343fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "handle_uninterpreted:\n");
1344fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Indent();
1345fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
1346fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1347fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // Is this an end-group tag?  If so, this must be the end of the message.
1348fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Print(
1349fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==\n"
1350fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "    ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {\n"
1351fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "  return true;\n"
1352fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "}\n");
1353fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1354fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // Handle extension ranges.
1355fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (descriptor_->extension_range_count() > 0) {
1356fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print(
1357fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "if (");
1358fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    for (int i = 0; i < descriptor_->extension_range_count(); i++) {
1359fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      const Descriptor::ExtensionRange* range =
1360fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        descriptor_->extension_range(i);
1361fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      if (i > 0) printer->Print(" ||\n    ");
1362fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1363fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      uint32 start_tag = WireFormatLite::MakeTag(
1364fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        range->start, static_cast<WireFormatLite::WireType>(0));
1365fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      uint32 end_tag = WireFormatLite::MakeTag(
1366fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        range->end, static_cast<WireFormatLite::WireType>(0));
1367fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1368fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      if (range->end > FieldDescriptor::kMaxNumber) {
1369fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        printer->Print(
1370fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville          "($start$u <= tag)",
1371fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville          "start", SimpleItoa(start_tag));
1372fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      } else {
1373fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        printer->Print(
1374fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville          "($start$u <= tag && tag < $end$u)",
1375fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville          "start", SimpleItoa(start_tag),
1376fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville          "end", SimpleItoa(end_tag));
1377fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      }
1378fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
1379fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print(") {\n");
1380fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    if (HasUnknownFields(descriptor_->file())) {
1381fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      printer->Print(
1382fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        "  DO_(_extensions_.ParseField(tag, input, default_instance_,\n"
1383fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        "                              mutable_unknown_fields()));\n");
1384fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    } else {
1385fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      printer->Print(
1386fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        "  DO_(_extensions_.ParseField(tag, input, default_instance_));\n");
1387fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
1388fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print(
1389fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "  continue;\n"
1390fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "}\n");
1391fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
1392fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1393fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // We really don't recognize this tag.  Skip it.
1394fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (HasUnknownFields(descriptor_->file())) {
1395fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print(
1396fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "DO_(::google::protobuf::internal::WireFormat::SkipField(\n"
1397fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "      input, tag, mutable_unknown_fields()));\n");
1398fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  } else {
1399fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print(
1400fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "DO_(::google::protobuf::internal::WireFormatLite::SkipField(input, tag));\n");
1401fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
1402fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1403fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (descriptor_->field_count() > 0) {
1404fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print("break;\n");
1405fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Outdent();
1406fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print("}\n");    // default:
1407fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Outdent();
1408fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print("}\n");    // switch
1409fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
1410fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1411fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Outdent();
1412fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Outdent();
1413fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Print(
1414fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "  }\n"                   // while
1415fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "  return true;\n"
1416fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "#undef DO_\n"
1417fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "}\n");
1418fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
1419fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1420fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid MessageGenerator::GenerateSerializeOneField(
1421fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    io::Printer* printer, const FieldDescriptor* field, bool to_array) {
1422fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  PrintFieldComment(printer, field);
1423fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1424fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (!field->is_repeated()) {
1425fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print(
1426fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "if (_has_bit($index$)) {\n",
1427fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "index", SimpleItoa(field->index()));
1428fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Indent();
1429fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
1430fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1431fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (to_array) {
1432fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    field_generators_.get(field).GenerateSerializeWithCachedSizesToArray(
1433fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        printer);
1434fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  } else {
1435fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    field_generators_.get(field).GenerateSerializeWithCachedSizes(printer);
1436fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
1437fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1438fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (!field->is_repeated()) {
1439fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Outdent();
1440fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print("}\n");
1441fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
1442fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Print("\n");
1443fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
1444fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1445fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid MessageGenerator::GenerateSerializeOneExtensionRange(
1446fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    io::Printer* printer, const Descriptor::ExtensionRange* range,
1447fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    bool to_array) {
1448fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  map<string, string> vars;
1449fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  vars["start"] = SimpleItoa(range->start);
1450fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  vars["end"] = SimpleItoa(range->end);
1451fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Print(vars,
1452fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "// Extension range [$start$, $end$)\n");
1453fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (to_array) {
1454fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print(vars,
1455fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "target = _extensions_.SerializeWithCachedSizesToArray(\n"
1456fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "    $start$, $end$, target);\n\n");
1457fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  } else {
1458fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print(vars,
1459fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "_extensions_.SerializeWithCachedSizes(\n"
1460fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "    $start$, $end$, output);\n\n");
1461fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
1462fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
1463fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1464fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid MessageGenerator::
1465fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleGenerateSerializeWithCachedSizes(io::Printer* printer) {
1466fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (descriptor_->options().message_set_wire_format()) {
1467fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // Special-case MessageSet.
1468fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print(
1469fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "void $classname$::SerializeWithCachedSizes(\n"
1470fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "    ::google::protobuf::io::CodedOutputStream* output) const {\n"
1471fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "  _extensions_.SerializeMessageSetWithCachedSizes(output);\n",
1472fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "classname", classname_);
1473fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    if (HasUnknownFields(descriptor_->file())) {
1474fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      printer->Print(
1475fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        "  ::google::protobuf::internal::WireFormat::SerializeUnknownMessageSetItems(\n"
1476fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        "      unknown_fields(), output);\n");
1477fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
1478fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print(
1479fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "}\n");
1480fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return;
1481fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
1482fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1483fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Print(
1484fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "void $classname$::SerializeWithCachedSizes(\n"
1485fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "    ::google::protobuf::io::CodedOutputStream* output) const {\n",
1486fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "classname", classname_);
1487fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Indent();
1488fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1489fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  GenerateSerializeWithCachedSizesBody(printer, false);
1490fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1491fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Outdent();
1492fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Print(
1493fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "}\n");
1494fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
1495fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1496fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid MessageGenerator::
1497fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleGenerateSerializeWithCachedSizesToArray(io::Printer* printer) {
1498fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (descriptor_->options().message_set_wire_format()) {
1499fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // Special-case MessageSet.
1500fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print(
1501fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "::google::protobuf::uint8* $classname$::SerializeWithCachedSizesToArray(\n"
1502fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "    ::google::protobuf::uint8* target) const {\n"
1503fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "  target =\n"
1504fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "      _extensions_.SerializeMessageSetWithCachedSizesToArray(target);\n",
1505fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "classname", classname_);
1506fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    if (HasUnknownFields(descriptor_->file())) {
1507fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      printer->Print(
1508fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        "  target = ::google::protobuf::internal::WireFormat::\n"
1509fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        "             SerializeUnknownMessageSetItemsToArray(\n"
1510fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        "               unknown_fields(), target);\n");
1511fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
1512fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print(
1513fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "  return target;\n"
1514fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "}\n");
1515fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return;
1516fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
1517fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1518fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Print(
1519fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "::google::protobuf::uint8* $classname$::SerializeWithCachedSizesToArray(\n"
1520fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "    ::google::protobuf::uint8* target) const {\n",
1521fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "classname", classname_);
1522fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Indent();
1523fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1524fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  GenerateSerializeWithCachedSizesBody(printer, true);
1525fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1526fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Outdent();
1527fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Print(
1528fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "  return target;\n"
1529fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "}\n");
1530fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
1531fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1532fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid MessageGenerator::
1533fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleGenerateSerializeWithCachedSizesBody(io::Printer* printer, bool to_array) {
1534fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  scoped_array<const FieldDescriptor*> ordered_fields(
1535fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    SortFieldsByNumber(descriptor_));
1536fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1537fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  vector<const Descriptor::ExtensionRange*> sorted_extensions;
1538fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  for (int i = 0; i < descriptor_->extension_range_count(); ++i) {
1539fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    sorted_extensions.push_back(descriptor_->extension_range(i));
1540fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
1541fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  sort(sorted_extensions.begin(), sorted_extensions.end(),
1542fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville       ExtensionRangeSorter());
1543fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1544fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // Merge the fields and the extension ranges, both sorted by field number.
1545fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  int i, j;
1546fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  for (i = 0, j = 0;
1547fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville       i < descriptor_->field_count() || j < sorted_extensions.size();
1548fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville       ) {
1549fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    if (i == descriptor_->field_count()) {
1550fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      GenerateSerializeOneExtensionRange(printer,
1551fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville                                         sorted_extensions[j++],
1552fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville                                         to_array);
1553fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    } else if (j == sorted_extensions.size()) {
1554fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      GenerateSerializeOneField(printer, ordered_fields[i++], to_array);
1555fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    } else if (ordered_fields[i]->number() < sorted_extensions[j]->start) {
1556fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      GenerateSerializeOneField(printer, ordered_fields[i++], to_array);
1557fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    } else {
1558fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      GenerateSerializeOneExtensionRange(printer,
1559fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville                                         sorted_extensions[j++],
1560fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville                                         to_array);
1561fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
1562fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
1563fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1564fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (HasUnknownFields(descriptor_->file())) {
1565fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print("if (!unknown_fields().empty()) {\n");
1566fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Indent();
1567fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    if (to_array) {
1568fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      printer->Print(
1569fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        "target = "
1570fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville            "::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(\n"
1571fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        "    unknown_fields(), target);\n");
1572fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    } else {
1573fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      printer->Print(
1574fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        "::google::protobuf::internal::WireFormat::SerializeUnknownFields(\n"
1575fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        "    unknown_fields(), output);\n");
1576fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
1577fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Outdent();
1578fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1579fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print(
1580fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "}\n");
1581fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
1582fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
1583fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1584fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid MessageGenerator::
1585fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleGenerateByteSize(io::Printer* printer) {
1586fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (descriptor_->options().message_set_wire_format()) {
1587fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // Special-case MessageSet.
1588fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print(
1589fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "int $classname$::ByteSize() const {\n"
1590fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "  int total_size = _extensions_.MessageSetByteSize();\n",
1591fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "classname", classname_);
1592fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    if (HasUnknownFields(descriptor_->file())) {
1593fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      printer->Print(
1594fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        "  total_size += ::google::protobuf::internal::WireFormat::\n"
1595fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        "      ComputeUnknownMessageSetItemsSize(unknown_fields());\n");
1596fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
1597fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print(
1598d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville      "  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();\n"
1599fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "  _cached_size_ = total_size;\n"
1600d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville      "  GOOGLE_SAFE_CONCURRENT_WRITES_END();\n"
1601fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "  return total_size;\n"
1602fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "}\n");
1603fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return;
1604fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
1605fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1606fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Print(
1607fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "int $classname$::ByteSize() const {\n",
1608fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "classname", classname_);
1609fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Indent();
1610fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Print(
1611fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "int total_size = 0;\n"
1612fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "\n");
1613fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1614fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  int last_index = -1;
1615fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1616fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  for (int i = 0; i < descriptor_->field_count(); i++) {
1617fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    const FieldDescriptor* field = descriptor_->field(i);
1618fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1619fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    if (!field->is_repeated()) {
1620fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      // See above in GenerateClear for an explanation of this.
1621fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      // TODO(kenton):  Share code?  Unclear how to do so without
1622fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      //   over-engineering.
1623fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      if ((i / 8) != (last_index / 8) ||
1624fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville          last_index < 0) {
1625fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        if (last_index >= 0) {
1626fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville          printer->Outdent();
1627fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville          printer->Print("}\n");
1628fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        }
1629fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        printer->Print(
1630fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville          "if (_has_bits_[$index$ / 32] & (0xffu << ($index$ % 32))) {\n",
1631fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville          "index", SimpleItoa(field->index()));
1632fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        printer->Indent();
1633fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      }
1634fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      last_index = i;
1635fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1636fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      PrintFieldComment(printer, field);
1637fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1638fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      printer->Print(
1639fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        "if (has_$name$()) {\n",
1640fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        "name", FieldName(field));
1641fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      printer->Indent();
1642fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1643fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      field_generators_.get(field).GenerateByteSize(printer);
1644fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1645fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      printer->Outdent();
1646fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      printer->Print(
1647fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        "}\n"
1648fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        "\n");
1649fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
1650fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
1651fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1652fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (last_index >= 0) {
1653fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Outdent();
1654fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print("}\n");
1655fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
1656fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1657fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // Repeated fields don't use _has_bits_ so we count them in a separate
1658fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // pass.
1659fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  for (int i = 0; i < descriptor_->field_count(); i++) {
1660fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    const FieldDescriptor* field = descriptor_->field(i);
1661fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1662fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    if (field->is_repeated()) {
1663fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      PrintFieldComment(printer, field);
1664fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      field_generators_.get(field).GenerateByteSize(printer);
1665fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      printer->Print("\n");
1666fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
1667fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
1668fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1669fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (descriptor_->extension_range_count() > 0) {
1670fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print(
1671fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "total_size += _extensions_.ByteSize();\n"
1672fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "\n");
1673fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
1674fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1675fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (HasUnknownFields(descriptor_->file())) {
1676fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print("if (!unknown_fields().empty()) {\n");
1677fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Indent();
1678fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print(
1679fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "total_size +=\n"
1680fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "  ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(\n"
1681fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "    unknown_fields());\n");
1682fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Outdent();
1683fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print("}\n");
1684fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
1685fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1686fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // We update _cached_size_ even though this is a const method.  In theory,
1687fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // this is not thread-compatible, because concurrent writes have undefined
1688fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // results.  In practice, since any concurrent writes will be writing the
1689fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // exact same value, it works on all common processors.  In a future version
1690fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // of C++, _cached_size_ should be made into an atomic<int>.
1691fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Print(
1692d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    "GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();\n"
1693fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "_cached_size_ = total_size;\n"
1694d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    "GOOGLE_SAFE_CONCURRENT_WRITES_END();\n"
1695fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "return total_size;\n");
1696fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1697fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Outdent();
1698fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Print("}\n");
1699fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
1700fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1701fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid MessageGenerator::
1702fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleGenerateIsInitialized(io::Printer* printer) {
1703fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Print(
1704fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "bool $classname$::IsInitialized() const {\n",
1705fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "classname", classname_);
1706fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Indent();
1707fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1708fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // Check that all required fields in this message are set.  We can do this
1709fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // most efficiently by checking 32 "has bits" at a time.
1710fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  int has_bits_array_size = (descriptor_->field_count() + 31) / 32;
1711fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  for (int i = 0; i < has_bits_array_size; i++) {
1712fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    uint32 mask = 0;
1713fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    for (int bit = 0; bit < 32; bit++) {
1714fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      int index = i * 32 + bit;
1715fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      if (index >= descriptor_->field_count()) break;
1716fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      const FieldDescriptor* field = descriptor_->field(index);
1717fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1718fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      if (field->is_required()) {
1719fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        mask |= 1 << bit;
1720fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      }
1721fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
1722fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1723fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    if (mask != 0) {
1724fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      char buffer[kFastToBufferSize];
1725fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      printer->Print(
1726fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        "if ((_has_bits_[$i$] & 0x$mask$) != 0x$mask$) return false;\n",
1727fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        "i", SimpleItoa(i),
1728fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        "mask", FastHex32ToBuffer(mask, buffer));
1729fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
1730fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
1731fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1732fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // Now check that all embedded messages are initialized.
1733fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Print("\n");
1734fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  for (int i = 0; i < descriptor_->field_count(); i++) {
1735fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    const FieldDescriptor* field = descriptor_->field(i);
1736fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE &&
1737fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        HasRequiredFields(field->message_type())) {
1738fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      if (field->is_repeated()) {
1739fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        printer->Print(
1740fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville          "for (int i = 0; i < $name$_size(); i++) {\n"
1741fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville          "  if (!this->$name$(i).IsInitialized()) return false;\n"
1742fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville          "}\n",
1743fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville          "name", FieldName(field));
1744fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      } else {
1745fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        printer->Print(
1746fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville          "if (has_$name$()) {\n"
1747fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville          "  if (!this->$name$().IsInitialized()) return false;\n"
1748fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville          "}\n",
1749fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville          "name", FieldName(field));
1750fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      }
1751fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
1752fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
1753fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1754fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (descriptor_->extension_range_count() > 0) {
1755fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print(
1756fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "\n"
1757fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "if (!_extensions_.IsInitialized()) return false;");
1758fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
1759fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1760fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Outdent();
1761fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Print(
1762fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "  return true;\n"
1763fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "}\n");
1764fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
1765fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1766d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville
1767fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}  // namespace cpp
1768fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}  // namespace compiler
1769fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}  // namespace protobuf
1770fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}  // namespace google
1771