1fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Protocol Buffers - Google's data interchange format
2fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Copyright 2008 Google Inc.  All rights reserved.
3afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidson// https://developers.google.com/protocol-buffers/
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>
38a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson#include <memory>
39a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson#include <set>
40a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson#include <utility>
41fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <vector>
42fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <google/protobuf/compiler/cpp/cpp_message.h>
43fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <google/protobuf/compiler/cpp/cpp_field.h>
44fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <google/protobuf/compiler/cpp/cpp_enum.h>
45fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <google/protobuf/compiler/cpp/cpp_extension.h>
46fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <google/protobuf/compiler/cpp/cpp_helpers.h>
47fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <google/protobuf/stubs/strutil.h>
48fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <google/protobuf/io/printer.h>
49fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <google/protobuf/io/coded_stream.h>
50fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <google/protobuf/wire_format.h>
51fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <google/protobuf/descriptor.pb.h>
52fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
53a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
54fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillenamespace google {
55fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillenamespace protobuf {
56fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillenamespace compiler {
57fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillenamespace cpp {
58fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
59fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleusing internal::WireFormat;
60fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleusing internal::WireFormatLite;
61fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
62fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillenamespace {
63fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
64fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid PrintFieldComment(io::Printer* printer, const FieldDescriptor* field) {
65fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // Print the field's proto-syntax definition as a comment.  We don't want to
66fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // print group bodies so we cut off after the first line.
67fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  string def = field->DebugString();
68fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Print("// $def$\n",
69fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "def", def.substr(0, def.find_first_of('\n')));
70fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
71fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
72fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillestruct FieldOrderingByNumber {
73fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  inline bool operator()(const FieldDescriptor* a,
74fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville                         const FieldDescriptor* b) const {
75fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return a->number() < b->number();
76fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
77fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville};
78fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
79fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Sort the fields of the given Descriptor by number into a new[]'d array
80fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// and return it.
81fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleconst FieldDescriptor** SortFieldsByNumber(const Descriptor* descriptor) {
82fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  const FieldDescriptor** fields =
83fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    new const FieldDescriptor*[descriptor->field_count()];
84fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  for (int i = 0; i < descriptor->field_count(); i++) {
85fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    fields[i] = descriptor->field(i);
86fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
87fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  sort(fields, fields + descriptor->field_count(),
88fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville       FieldOrderingByNumber());
89fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  return fields;
90fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
91fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
92fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Functor for sorting extension ranges by their "start" field number.
93fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillestruct ExtensionRangeSorter {
94fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  bool operator()(const Descriptor::ExtensionRange* left,
95fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville                  const Descriptor::ExtensionRange* right) const {
96fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return left->start < right->start;
97fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
98fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville};
99fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
100a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson// Returns true if the "required" restriction check should be ignored for the
101a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson// given field.
102a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidsoninline static bool ShouldIgnoreRequiredFieldCheck(
103a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    const FieldDescriptor* field) {
104a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  return false;
105a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson}
106a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
107fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Returns true if the message type has any required fields.  If it doesn't,
108fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// we can optimize out calls to its IsInitialized() method.
109fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville//
110fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// already_seen is used to avoid checking the same type multiple times
111fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// (and also to protect against recursion).
112fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillestatic bool HasRequiredFields(
113fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    const Descriptor* type,
114fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    hash_set<const Descriptor*>* already_seen) {
115fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (already_seen->count(type) > 0) {
116fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // Since the first occurrence of a required field causes the whole
117fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // function to return true, we can assume that if the type is already
118fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // in the cache it didn't have any required fields.
119fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return false;
120fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
121fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  already_seen->insert(type);
122fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
123fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // If the type has extensions, an extension with message type could contain
124fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // required fields, so we have to be conservative and assume such an
125fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // extension exists.
126fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (type->extension_range_count() > 0) return true;
127fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
128fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  for (int i = 0; i < type->field_count(); i++) {
129fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    const FieldDescriptor* field = type->field(i);
130fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    if (field->is_required()) {
131fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      return true;
132fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
133a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE &&
134a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        !ShouldIgnoreRequiredFieldCheck(field)) {
135fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      if (HasRequiredFields(field->message_type(), already_seen)) {
136fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        return true;
137fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      }
138fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
139fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
140fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
141fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  return false;
142fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
143fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
144fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillestatic bool HasRequiredFields(const Descriptor* type) {
145fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  hash_set<const Descriptor*> already_seen;
146fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  return HasRequiredFields(type, &already_seen);
147fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
148fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
149a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson// This returns an estimate of the compiler's alignment for the field.  This
150a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson// can't guarantee to be correct because the generated code could be compiled on
151a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson// different systems with different alignment rules.  The estimates below assume
152a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson// 64-bit pointers.
153a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidsonint EstimateAlignmentSize(const FieldDescriptor* field) {
154a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  if (field == NULL) return 0;
155a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  if (field->is_repeated()) return 8;
156a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  switch (field->cpp_type()) {
157a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    case FieldDescriptor::CPPTYPE_BOOL:
158a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      return 1;
159a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
160a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    case FieldDescriptor::CPPTYPE_INT32:
161a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    case FieldDescriptor::CPPTYPE_UINT32:
162a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    case FieldDescriptor::CPPTYPE_ENUM:
163a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    case FieldDescriptor::CPPTYPE_FLOAT:
164a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      return 4;
165a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
166a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    case FieldDescriptor::CPPTYPE_INT64:
167a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    case FieldDescriptor::CPPTYPE_UINT64:
168a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    case FieldDescriptor::CPPTYPE_DOUBLE:
169a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    case FieldDescriptor::CPPTYPE_STRING:
170a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    case FieldDescriptor::CPPTYPE_MESSAGE:
171a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      return 8;
172a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  }
173a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  GOOGLE_LOG(FATAL) << "Can't get here.";
174a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  return -1;  // Make compiler happy.
175a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson}
176a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
177a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson// FieldGroup is just a helper for OptimizePadding below.  It holds a vector of
178a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson// fields that are grouped together because they have compatible alignment, and
179a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson// a preferred location in the final field ordering.
180a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidsonclass FieldGroup {
181a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson public:
182a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  FieldGroup()
183a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      : preferred_location_(0) {}
184a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
185a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  // A group with a single field.
186a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  FieldGroup(float preferred_location, const FieldDescriptor* field)
187a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      : preferred_location_(preferred_location),
188a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        fields_(1, field) {}
189a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
190a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  // Append the fields in 'other' to this group.
191a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  void Append(const FieldGroup& other) {
192a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    if (other.fields_.empty()) {
193a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      return;
194a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    }
195a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    // Preferred location is the average among all the fields, so we weight by
196a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    // the number of fields on each FieldGroup object.
197a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    preferred_location_ =
198a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        (preferred_location_ * fields_.size() +
199a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson         (other.preferred_location_ * other.fields_.size())) /
200a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        (fields_.size() + other.fields_.size());
201a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    fields_.insert(fields_.end(), other.fields_.begin(), other.fields_.end());
202a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  }
203a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
204a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  void SetPreferredLocation(float location) { preferred_location_ = location; }
205a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  const vector<const FieldDescriptor*>& fields() const { return fields_; }
206a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
207a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  // FieldGroup objects sort by their preferred location.
208a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  bool operator<(const FieldGroup& other) const {
209a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    return preferred_location_ < other.preferred_location_;
210a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  }
211a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
212a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson private:
213a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  // "preferred_location_" is an estimate of where this group should go in the
214a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  // final list of fields.  We compute this by taking the average index of each
215a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  // field in this group in the original ordering of fields.  This is very
216a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  // approximate, but should put this group close to where its member fields
217a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  // originally went.
218a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  float preferred_location_;
219a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  vector<const FieldDescriptor*> fields_;
220a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  // We rely on the default copy constructor and operator= so this type can be
221a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  // used in a vector.
222a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson};
223a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
224a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson// Reorder 'fields' so that if the fields are output into a c++ class in the new
225a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson// order, the alignment padding is minimized.  We try to do this while keeping
226a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson// each field as close as possible to its original position so that we don't
227a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson// reduce cache locality much for function that access each field in order.
228a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidsonvoid OptimizePadding(vector<const FieldDescriptor*>* fields) {
229a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  // First divide fields into those that align to 1 byte, 4 bytes or 8 bytes.
230a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  vector<FieldGroup> aligned_to_1, aligned_to_4, aligned_to_8;
231a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  for (int i = 0; i < fields->size(); ++i) {
232a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    switch (EstimateAlignmentSize((*fields)[i])) {
233a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      case 1: aligned_to_1.push_back(FieldGroup(i, (*fields)[i])); break;
234a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      case 4: aligned_to_4.push_back(FieldGroup(i, (*fields)[i])); break;
235a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      case 8: aligned_to_8.push_back(FieldGroup(i, (*fields)[i])); break;
236a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      default:
237a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        GOOGLE_LOG(FATAL) << "Unknown alignment size.";
238a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    }
239a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  }
240a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
241a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  // Now group fields aligned to 1 byte into sets of 4, and treat those like a
242a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  // single field aligned to 4 bytes.
243a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  for (int i = 0; i < aligned_to_1.size(); i += 4) {
244a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    FieldGroup field_group;
245a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    for (int j = i; j < aligned_to_1.size() && j < i + 4; ++j) {
246a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      field_group.Append(aligned_to_1[j]);
247a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    }
248a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    aligned_to_4.push_back(field_group);
249a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  }
250a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  // Sort by preferred location to keep fields as close to their original
251a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  // location as possible.  Using stable_sort ensures that the output is
252a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  // consistent across runs.
253a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  stable_sort(aligned_to_4.begin(), aligned_to_4.end());
254a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
255a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  // Now group fields aligned to 4 bytes (or the 4-field groups created above)
256a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  // into pairs, and treat those like a single field aligned to 8 bytes.
257a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  for (int i = 0; i < aligned_to_4.size(); i += 2) {
258a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    FieldGroup field_group;
259a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    for (int j = i; j < aligned_to_4.size() && j < i + 2; ++j) {
260a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      field_group.Append(aligned_to_4[j]);
261a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    }
262a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    if (i == aligned_to_4.size() - 1) {
263a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      // Move incomplete 4-byte block to the end.
264a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      field_group.SetPreferredLocation(fields->size() + 1);
265a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    }
266a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    aligned_to_8.push_back(field_group);
267a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  }
268a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  // Sort by preferred location.
269a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  stable_sort(aligned_to_8.begin(), aligned_to_8.end());
270a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
271a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  // Now pull out all the FieldDescriptors in order.
272a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  fields->clear();
273a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  for (int i = 0; i < aligned_to_8.size(); ++i) {
274a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    fields->insert(fields->end(),
275a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson                   aligned_to_8[i].fields().begin(),
276a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson                   aligned_to_8[i].fields().end());
277a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  }
278a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson}
279a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
280a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidsonstring MessageTypeProtoName(const FieldDescriptor* field) {
281a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  return field->message_type()->full_name();
282a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson}
283a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
284fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
285fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
286fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// ===================================================================
287fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
288fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleMessageGenerator::MessageGenerator(const Descriptor* descriptor,
289a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson                                   const Options& options)
290a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    : descriptor_(descriptor),
291a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      classname_(ClassName(descriptor, false)),
292a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      options_(options),
293a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      field_generators_(descriptor, options),
294a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      nested_generators_(new scoped_ptr<
295a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson          MessageGenerator>[descriptor->nested_type_count()]),
296a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      enum_generators_(
297a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson          new scoped_ptr<EnumGenerator>[descriptor->enum_type_count()]),
298a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      extension_generators_(new scoped_ptr<
299a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson          ExtensionGenerator>[descriptor->extension_count()]) {
300fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
301fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  for (int i = 0; i < descriptor->nested_type_count(); i++) {
302fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    nested_generators_[i].reset(
303a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      new MessageGenerator(descriptor->nested_type(i), options));
304fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
305fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
306fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  for (int i = 0; i < descriptor->enum_type_count(); i++) {
307fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    enum_generators_[i].reset(
308a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      new EnumGenerator(descriptor->enum_type(i), options));
309fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
310fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
311fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  for (int i = 0; i < descriptor->extension_count(); i++) {
312fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    extension_generators_[i].reset(
313a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      new ExtensionGenerator(descriptor->extension(i), options));
314fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
315fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
316fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
317fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleMessageGenerator::~MessageGenerator() {}
318fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
319fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid MessageGenerator::
320fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleGenerateForwardDeclaration(io::Printer* printer) {
321fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Print("class $classname$;\n",
322fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville                 "classname", classname_);
323fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
324fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  for (int i = 0; i < descriptor_->nested_type_count(); i++) {
325fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    nested_generators_[i]->GenerateForwardDeclaration(printer);
326fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
327fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
328fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
329fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid MessageGenerator::
330fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleGenerateEnumDefinitions(io::Printer* printer) {
331fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  for (int i = 0; i < descriptor_->nested_type_count(); i++) {
332fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    nested_generators_[i]->GenerateEnumDefinitions(printer);
333fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
334fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
335fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  for (int i = 0; i < descriptor_->enum_type_count(); i++) {
336fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    enum_generators_[i]->GenerateDefinition(printer);
337fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
338fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
339fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
340fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid MessageGenerator::
341fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleGenerateGetEnumDescriptorSpecializations(io::Printer* printer) {
342fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  for (int i = 0; i < descriptor_->nested_type_count(); i++) {
343fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    nested_generators_[i]->GenerateGetEnumDescriptorSpecializations(printer);
344fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
345fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  for (int i = 0; i < descriptor_->enum_type_count(); i++) {
346fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    enum_generators_[i]->GenerateGetEnumDescriptorSpecializations(printer);
347fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
348fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
349fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
350fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid MessageGenerator::
351fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleGenerateFieldAccessorDeclarations(io::Printer* printer) {
352fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  for (int i = 0; i < descriptor_->field_count(); i++) {
353fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    const FieldDescriptor* field = descriptor_->field(i);
354fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
355fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    PrintFieldComment(printer, field);
356fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
357fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    map<string, string> vars;
358a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    SetCommonFieldVariables(field, &vars, options_);
359fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    vars["constant_name"] = FieldConstantName(field);
360fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
361fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    if (field->is_repeated()) {
362fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      printer->Print(vars, "inline int $name$_size() const$deprecation$;\n");
363fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    } else {
364fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      printer->Print(vars, "inline bool has_$name$() const$deprecation$;\n");
365fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
366fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
367fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print(vars, "inline void clear_$name$()$deprecation$;\n");
368fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print(vars, "static const int $constant_name$ = $number$;\n");
369fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
370fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // Generate type-specific accessor declarations.
371fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    field_generators_.get(field).GenerateAccessorDeclarations(printer);
372fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
373fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print("\n");
374fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
375fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
376fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (descriptor_->extension_range_count() > 0) {
377fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // Generate accessors for extensions.  We just call a macro located in
378fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // extension_set.h since the accessors about 80 lines of static code.
379fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print(
380fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "GOOGLE_PROTOBUF_EXTENSION_ACCESSORS($classname$)\n",
381fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "classname", classname_);
382fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
383a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
384a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
385a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    printer->Print(
386a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        "inline $camel_oneof_name$Case $oneof_name$_case() const;\n",
387a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        "camel_oneof_name",
388a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        UnderscoresToCamelCase(descriptor_->oneof_decl(i)->name(), true),
389a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        "oneof_name", descriptor_->oneof_decl(i)->name());
390a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  }
391fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
392fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
393fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid MessageGenerator::
394fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleGenerateFieldAccessorDefinitions(io::Printer* printer) {
395fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Print("// $classname$\n\n", "classname", classname_);
396fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
397fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  for (int i = 0; i < descriptor_->field_count(); i++) {
398fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    const FieldDescriptor* field = descriptor_->field(i);
399fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
400fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    PrintFieldComment(printer, field);
401fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
402fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    map<string, string> vars;
403a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    SetCommonFieldVariables(field, &vars, options_);
404fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
405fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // Generate has_$name$() or $name$_size().
406fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    if (field->is_repeated()) {
407fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      printer->Print(vars,
408fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        "inline int $classname$::$name$_size() const {\n"
409fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        "  return $name$_.size();\n"
410fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        "}\n");
411a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    } else if (field->containing_oneof()) {
412a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      // Singular field in a oneof
413a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      vars["field_name"] = UnderscoresToCamelCase(field->name(), true);
414a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      vars["oneof_name"] = field->containing_oneof()->name();
415a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      vars["oneof_index"] = SimpleItoa(field->containing_oneof()->index());
416a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      printer->Print(vars,
417a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        "inline bool $classname$::has_$name$() const {\n"
418a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        "  return $oneof_name$_case() == k$field_name$;\n"
419a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        "}\n"
420a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        "inline void $classname$::set_has_$name$() {\n"
421a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        "  _oneof_case_[$oneof_index$] = k$field_name$;\n"
422a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        "}\n");
423fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    } else {
424fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      // Singular field.
425a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      char buffer[kFastToBufferSize];
426a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      vars["has_array_index"] = SimpleItoa(field->index() / 32);
427a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      vars["has_mask"] = FastHex32ToBuffer(1u << (field->index() % 32), buffer);
428fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      printer->Print(vars,
429fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        "inline bool $classname$::has_$name$() const {\n"
430a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        "  return (_has_bits_[$has_array_index$] & 0x$has_mask$u) != 0;\n"
431a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        "}\n"
432a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        "inline void $classname$::set_has_$name$() {\n"
433a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        "  _has_bits_[$has_array_index$] |= 0x$has_mask$u;\n"
434a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        "}\n"
435a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        "inline void $classname$::clear_has_$name$() {\n"
436a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        "  _has_bits_[$has_array_index$] &= ~0x$has_mask$u;\n"
437a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        "}\n"
438a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        );
439fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
440fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
441fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // Generate clear_$name$()
442fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print(vars,
443fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "inline void $classname$::clear_$name$() {\n");
444fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
445fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Indent();
446fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
447a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    if (field->containing_oneof()) {
448a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      // Clear this field only if it is the active field in this oneof,
449a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      // otherwise ignore
450a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      printer->Print(vars,
451a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        "if (has_$name$()) {\n");
452a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      printer->Indent();
453a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      field_generators_.get(field).GenerateClearingCode(printer);
454a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      printer->Print(vars,
455a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        "clear_has_$oneof_name$();\n");
456a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      printer->Outdent();
457a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      printer->Print("}\n");
458a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    } else {
459a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      field_generators_.get(field).GenerateClearingCode(printer);
460a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      if (!field->is_repeated()) {
461a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        printer->Print(vars,
462a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson                       "clear_has_$name$();\n");
463a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      }
464fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
465fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
466a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    printer->Outdent();
467fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print("}\n");
468fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
469fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // Generate type-specific accessors.
470fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    field_generators_.get(field).GenerateInlineAccessorDefinitions(printer);
471fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
472fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print("\n");
473fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
474a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
475a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  // Generate has_$name$() and clear_has_$name$() functions for oneofs
476a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
477a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    map<string, string> vars;
478a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    vars["oneof_name"] = descriptor_->oneof_decl(i)->name();
479a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    vars["oneof_index"] = SimpleItoa(descriptor_->oneof_decl(i)->index());
480a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    vars["cap_oneof_name"] =
481a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        ToUpper(descriptor_->oneof_decl(i)->name());
482a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    vars["classname"] = classname_;
483a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    printer->Print(
484a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      vars,
485a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      "inline bool $classname$::has_$oneof_name$() {\n"
486a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      "  return $oneof_name$_case() != $cap_oneof_name$_NOT_SET;\n"
487a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      "}\n"
488a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      "inline void $classname$::clear_has_$oneof_name$() {\n"
489a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      "  _oneof_case_[$oneof_index$] = $cap_oneof_name$_NOT_SET;\n"
490a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      "}\n");
491a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  }
492a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson}
493a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
494a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson// Helper for the code that emits the Clear() method.
495a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidsonstatic bool CanClearByZeroing(const FieldDescriptor* field) {
496a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  if (field->is_repeated() || field->is_extension()) return false;
497a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  switch (field->cpp_type()) {
498a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    case internal::WireFormatLite::CPPTYPE_ENUM:
499a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      return field->default_value_enum()->number() == 0;
500a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    case internal::WireFormatLite::CPPTYPE_INT32:
501a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      return field->default_value_int32() == 0;
502a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    case internal::WireFormatLite::CPPTYPE_INT64:
503a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      return field->default_value_int64() == 0;
504a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    case internal::WireFormatLite::CPPTYPE_UINT32:
505a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      return field->default_value_uint32() == 0;
506a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    case internal::WireFormatLite::CPPTYPE_UINT64:
507a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      return field->default_value_uint64() == 0;
508a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    case internal::WireFormatLite::CPPTYPE_FLOAT:
509a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      return field->default_value_float() == 0;
510a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    case internal::WireFormatLite::CPPTYPE_DOUBLE:
511a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      return field->default_value_double() == 0;
512a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    case internal::WireFormatLite::CPPTYPE_BOOL:
513a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      return field->default_value_bool() == false;
514a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    default:
515a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      return false;
516a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  }
517fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
518fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
519fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid MessageGenerator::
520fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleGenerateClassDefinition(io::Printer* printer) {
521fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  for (int i = 0; i < descriptor_->nested_type_count(); i++) {
522fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    nested_generators_[i]->GenerateClassDefinition(printer);
523fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print("\n");
524fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print(kThinSeparator);
525fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print("\n");
526fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
527fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
528fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  map<string, string> vars;
529fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  vars["classname"] = classname_;
530fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  vars["field_count"] = SimpleItoa(descriptor_->field_count());
531a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  vars["oneof_decl_count"] = SimpleItoa(descriptor_->oneof_decl_count());
532a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  if (options_.dllexport_decl.empty()) {
533fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    vars["dllexport"] = "";
534fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  } else {
535a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    vars["dllexport"] = options_.dllexport_decl + " ";
536fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
537d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  vars["superclass"] = SuperClassName(descriptor_);
538fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
539fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Print(vars,
540d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    "class $dllexport$$classname$ : public $superclass$ {\n"
541fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    " public:\n");
542fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Indent();
543fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
544fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Print(vars,
545fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "$classname$();\n"
546fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "virtual ~$classname$();\n"
547fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "\n"
548fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "$classname$(const $classname$& from);\n"
549fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "\n"
550fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "inline $classname$& operator=(const $classname$& from) {\n"
551fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "  CopyFrom(from);\n"
552fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "  return *this;\n"
553fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "}\n"
554fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "\n");
555fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
556a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  if (UseUnknownFieldSet(descriptor_->file())) {
557fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print(
558fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {\n"
559fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "  return _unknown_fields_;\n"
560fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "}\n"
561fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "\n"
562fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {\n"
563fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "  return &_unknown_fields_;\n"
564fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "}\n"
565fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "\n");
566a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  } else {
567a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    printer->Print(
568a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      "inline const ::std::string& unknown_fields() const {\n"
569a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      "  return _unknown_fields_;\n"
570a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      "}\n"
571a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      "\n"
572a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      "inline ::std::string* mutable_unknown_fields() {\n"
573a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      "  return &_unknown_fields_;\n"
574a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      "}\n"
575a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      "\n");
576fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
577fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
578fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // Only generate this member if it's not disabled.
579fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (HasDescriptorMethods(descriptor_->file()) &&
580fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      !descriptor_->options().no_standard_descriptor_accessor()) {
581fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print(vars,
582fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "static const ::google::protobuf::Descriptor* descriptor();\n");
583fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
584fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
585fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Print(vars,
586fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "static const $classname$& default_instance();\n"
587d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    "\n");
588d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville
589a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  // Generate enum values for every field in oneofs. One list is generated for
590a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  // each oneof with an additional *_NOT_SET value.
591a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
592a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    printer->Print(
593a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        "enum $camel_oneof_name$Case {\n",
594a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        "camel_oneof_name",
595a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        UnderscoresToCamelCase(descriptor_->oneof_decl(i)->name(), true));
596a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    printer->Indent();
597a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    for (int j = 0; j < descriptor_->oneof_decl(i)->field_count(); j++) {
598a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      printer->Print(
599a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson          "k$field_name$ = $field_number$,\n",
600a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson          "field_name",
601a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson          UnderscoresToCamelCase(
602a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson              descriptor_->oneof_decl(i)->field(j)->name(), true),
603a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson          "field_number",
604a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson          SimpleItoa(descriptor_->oneof_decl(i)->field(j)->number()));
605a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    }
606a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    printer->Print(
607a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        "$cap_oneof_name$_NOT_SET = 0,\n",
608a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        "cap_oneof_name",
609a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        ToUpper(descriptor_->oneof_decl(i)->name()));
610a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    printer->Outdent();
611a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    printer->Print(
612a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        "};\n"
613a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        "\n");
614a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  }
615a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
616a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  if (!StaticInitializersForced(descriptor_->file())) {
617a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    printer->Print(vars,
618a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      "#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER\n"
619a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      "// Returns the internal default instance pointer. This function can\n"
620a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      "// return NULL thus should not be used by the user. This is intended\n"
621a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      "// for Protobuf internal code. Please use default_instance() declared\n"
622a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      "// above instead.\n"
623a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      "static inline const $classname$* internal_default_instance() {\n"
624a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      "  return default_instance_;\n"
625a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      "}\n"
626a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      "#endif\n"
627a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      "\n");
628a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  }
629a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
630d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville
631d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  printer->Print(vars,
632fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "void Swap($classname$* other);\n"
633fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "\n"
634fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "// implements Message ----------------------------------------------\n"
635fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "\n"
636fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "$classname$* New() const;\n");
637fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
638fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (HasGeneratedMethods(descriptor_->file())) {
639fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    if (HasDescriptorMethods(descriptor_->file())) {
640fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      printer->Print(vars,
641fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        "void CopyFrom(const ::google::protobuf::Message& from);\n"
642fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        "void MergeFrom(const ::google::protobuf::Message& from);\n");
643fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    } else {
644fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      printer->Print(vars,
645fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        "void CheckTypeAndMergeFrom(const ::google::protobuf::MessageLite& from);\n");
646fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
647fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
648fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print(vars,
649fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "void CopyFrom(const $classname$& from);\n"
650fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "void MergeFrom(const $classname$& from);\n"
651fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "void Clear();\n"
652fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "bool IsInitialized() const;\n"
653fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "\n"
654fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "int ByteSize() const;\n"
655fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "bool MergePartialFromCodedStream(\n"
656fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "    ::google::protobuf::io::CodedInputStream* input);\n"
657fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "void SerializeWithCachedSizes(\n"
658fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "    ::google::protobuf::io::CodedOutputStream* output) const;\n");
659a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    // DiscardUnknownFields() is implemented in message.cc using reflections. We
660a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    // need to implement this function in generated code for messages.
661a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    if (!UseUnknownFieldSet(descriptor_->file())) {
662a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      printer->Print(
663a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        "void DiscardUnknownFields();\n");
664a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    }
665fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    if (HasFastArraySerialization(descriptor_->file())) {
666fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      printer->Print(
667fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        "::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;\n");
668fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
669fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
670fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
671a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  // Check all FieldDescriptors including those in oneofs to estimate
672a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  // whether ::std::string is likely to be used, and depending on that
673a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  // estimate, set uses_string_ to true or false.  That contols
674a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  // whether to force initialization of empty_string_ in SharedCtor().
675a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  // It's often advantageous to do so to keep "is empty_string_
676a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  // inited?" code from appearing all over the place.
677a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  vector<const FieldDescriptor*> descriptors;
678a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  for (int i = 0; i < descriptor_->field_count(); i++) {
679a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    descriptors.push_back(descriptor_->field(i));
680a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  }
681a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
682a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    for (int j = 0; j < descriptor_->oneof_decl(i)->field_count(); j++) {
683a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      descriptors.push_back(descriptor_->oneof_decl(i)->field(j));
684a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    }
685a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  }
686a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  uses_string_ = false;
687a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  for (int i = 0; i < descriptors.size(); i++) {
688a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    const FieldDescriptor* field = descriptors[i];
689a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    if (field->cpp_type() == FieldDescriptor::CPPTYPE_STRING) {
690a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      switch (field->options().ctype()) {
691a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        default: uses_string_ = true; break;
692a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      }
693a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    }
694a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  }
695a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
696a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  printer->Print(
697fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "int GetCachedSize() const { return _cached_size_; }\n"
698fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "private:\n"
699fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "void SharedCtor();\n"
700fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "void SharedDtor();\n"
701d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    "void SetCachedSize(int size) const;\n"
702a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    "public:\n");
703fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
704fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (HasDescriptorMethods(descriptor_->file())) {
705fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print(
706fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "::google::protobuf::Metadata GetMetadata() const;\n"
707fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "\n");
708fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  } else {
709fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print(
710fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "::std::string GetTypeName() const;\n"
711fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "\n");
712fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
713fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
714fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Print(
715fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "// nested types ----------------------------------------------------\n"
716fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "\n");
717fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
718fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // Import all nested message classes into this class's scope with typedefs.
719fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  for (int i = 0; i < descriptor_->nested_type_count(); i++) {
720fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    const Descriptor* nested_type = descriptor_->nested_type(i);
721fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print("typedef $nested_full_name$ $nested_name$;\n",
722fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville                   "nested_name", nested_type->name(),
723fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville                   "nested_full_name", ClassName(nested_type, false));
724fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
725fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
726fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (descriptor_->nested_type_count() > 0) {
727fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print("\n");
728fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
729fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
730fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // Import all nested enums and their values into this class's scope with
731fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // typedefs and constants.
732fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  for (int i = 0; i < descriptor_->enum_type_count(); i++) {
733fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    enum_generators_[i]->GenerateSymbolImports(printer);
734fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print("\n");
735fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
736fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
737fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Print(
738fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "// accessors -------------------------------------------------------\n"
739fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "\n");
740fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
741fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // Generate accessor methods for all fields.
742fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  GenerateFieldAccessorDeclarations(printer);
743fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
744fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // Declare extension identifiers.
745fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  for (int i = 0; i < descriptor_->extension_count(); i++) {
746fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    extension_generators_[i]->GenerateDeclaration(printer);
747fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
748fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
749d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville
750d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  printer->Print(
751d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    "// @@protoc_insertion_point(class_scope:$full_name$)\n",
752d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    "full_name", descriptor_->full_name());
753d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville
754a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  // Generate private members.
755fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Outdent();
756fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Print(" private:\n");
757fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Indent();
758fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
759a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
760a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  for (int i = 0; i < descriptor_->field_count(); i++) {
761a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    if (!descriptor_->field(i)->is_repeated()) {
762a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      printer->Print(
763a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        "inline void set_has_$name$();\n",
764a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        "name", FieldName(descriptor_->field(i)));
765a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      if (!descriptor_->field(i)->containing_oneof()) {
766a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        printer->Print(
767a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson          "inline void clear_has_$name$();\n",
768a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson          "name", FieldName(descriptor_->field(i)));
769a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      }
770a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    }
771a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  }
772a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  printer->Print("\n");
773a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
774a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  // Generate oneof function declarations
775a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
776a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    printer->Print(
777a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        "inline bool has_$oneof_name$();\n"
778a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        "void clear_$oneof_name$();\n"
779a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        "inline void clear_has_$oneof_name$();\n\n",
780a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        "oneof_name", descriptor_->oneof_decl(i)->name());
781a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  }
782a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
783a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  // Prepare decls for _cached_size_ and _has_bits_.  Their position in the
784a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  // output will be determined later.
785a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
786a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  bool need_to_emit_cached_size = true;
787a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  // TODO(kenton):  Make _cached_size_ an atomic<int> when C++ supports it.
788a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  const string cached_size_decl = "mutable int _cached_size_;\n";
789a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
790a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  // TODO(jieluo) - Optimize _has_bits_ for repeated and oneof fields.
791a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  size_t sizeof_has_bits = (descriptor_->field_count() + 31) / 32 * 4;
792a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  if (descriptor_->field_count() == 0) {
793a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    // Zero-size arrays aren't technically allowed, and MSVC in particular
794a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    // doesn't like them.  We still need to declare these arrays to make
795a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    // other code compile.  Since this is an uncommon case, we'll just declare
796a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    // them with size 1 and waste some space.  Oh well.
797a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    sizeof_has_bits = 4;
798a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  }
799a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  const string has_bits_decl = sizeof_has_bits == 0 ? "" :
800a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      "::google::protobuf::uint32 _has_bits_[" + SimpleItoa(sizeof_has_bits / 4) + "];\n";
801a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
802a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
803a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  // To minimize padding, data members are divided into three sections:
804a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  // (1) members assumed to align to 8 bytes
805a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  // (2) members corresponding to message fields, re-ordered to optimize
806a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  //     alignment.
807a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  // (3) members assumed to align to 4 bytes.
808a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
809a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  // Members assumed to align to 8 bytes:
810a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
811fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (descriptor_->extension_range_count() > 0) {
812fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print(
813a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      "::google::protobuf::internal::ExtensionSet _extensions_;\n"
814a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      "\n");
815fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
816fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
817a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  if (UseUnknownFieldSet(descriptor_->file())) {
818fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print(
819a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      "::google::protobuf::UnknownFieldSet _unknown_fields_;\n"
820a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      "\n");
821a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  } else {
822a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    printer->Print(
823a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      "::std::string _unknown_fields_;\n"
824a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      "\n");
825fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
826fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
827a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  // _has_bits_ is frequently accessed, so to reduce code size and improve
828a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  // speed, it should be close to the start of the object.  But, try not to
829a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  // waste space:_has_bits_ by itself always makes sense if its size is a
830a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  // multiple of 8, but, otherwise, maybe _has_bits_ and cached_size_ together
831a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  // will work well.
832a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  printer->Print(has_bits_decl.c_str());
833a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  if ((sizeof_has_bits % 8) != 0) {
834a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    printer->Print(cached_size_decl.c_str());
835a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    need_to_emit_cached_size = false;
836a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  }
837a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
838a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  // Field members:
839a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
840a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  // List fields which doesn't belong to any oneof
841a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  vector<const FieldDescriptor*> fields;
842a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  hash_map<string, int> fieldname_to_chunk;
843fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  for (int i = 0; i < descriptor_->field_count(); i++) {
844a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    if (!descriptor_->field(i)->containing_oneof()) {
845a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      const FieldDescriptor* field = descriptor_->field(i);
846a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      fields.push_back(field);
847a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      fieldname_to_chunk[FieldName(field)] = i / 8;
848a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    }
849a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  }
850a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  OptimizePadding(&fields);
851a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  // Emit some private and static members
852a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  runs_of_fields_ = vector< vector<string> >(1);
853a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  for (int i = 0; i < fields.size(); ++i) {
854a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    const FieldDescriptor* field = fields[i];
855a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    const FieldGenerator& generator = field_generators_.get(field);
856a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    generator.GenerateStaticMembers(printer);
857a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    generator.GeneratePrivateMembers(printer);
858a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    if (CanClearByZeroing(field)) {
859a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      const string& fieldname = FieldName(field);
860a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      if (!runs_of_fields_.back().empty() &&
861a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson          (fieldname_to_chunk[runs_of_fields_.back().back()] !=
862a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson           fieldname_to_chunk[fieldname])) {
863a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        runs_of_fields_.push_back(vector<string>());
864a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      }
865a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      runs_of_fields_.back().push_back(fieldname);
866a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    } else if (!runs_of_fields_.back().empty()) {
867a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      runs_of_fields_.push_back(vector<string>());
868a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    }
869a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  }
870a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
871a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  // For each oneof generate a union
872a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
873a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    printer->Print(
874a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        "union $camel_oneof_name$Union {\n",
875a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        "camel_oneof_name",
876a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        UnderscoresToCamelCase(descriptor_->oneof_decl(i)->name(), true));
877a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    printer->Indent();
878a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    for (int j = 0; j < descriptor_->oneof_decl(i)->field_count(); j++) {
879a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      field_generators_.get(descriptor_->oneof_decl(i)->
880a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson                            field(j)).GeneratePrivateMembers(printer);
881a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    }
882a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    printer->Outdent();
883a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    printer->Print(
884a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        "} $oneof_name$_;\n",
885a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        "oneof_name", descriptor_->oneof_decl(i)->name());
886a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    for (int j = 0; j < descriptor_->oneof_decl(i)->field_count(); j++) {
887a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      field_generators_.get(descriptor_->oneof_decl(i)->
888a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson                            field(j)).GenerateStaticMembers(printer);
889a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    }
890a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  }
891a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
892a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  // Members assumed to align to 4 bytes:
893a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
894a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  if (need_to_emit_cached_size) {
895a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    printer->Print(cached_size_decl.c_str());
896a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    need_to_emit_cached_size = false;
897a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  }
898a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
899a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  // Generate _oneof_case_.
900a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  if (descriptor_->oneof_decl_count() > 0) {
901a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    printer->Print(vars,
902a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      "::google::protobuf::uint32 _oneof_case_[$oneof_decl_count$];\n"
903a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      "\n");
904fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
905fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
906fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // Declare AddDescriptors(), BuildDescriptors(), and ShutdownFile() as
907fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // friends so that they can access private static variables like
908fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // default_instance_ and reflection_.
909a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  PrintHandlingOptionalStaticInitializers(
910a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    descriptor_->file(), printer,
911a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    // With static initializers.
912fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "friend void $dllexport_decl$ $adddescriptorsname$();\n",
913a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    // Without.
914a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    "friend void $dllexport_decl$ $adddescriptorsname$_impl();\n",
915a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    // Vars.
916a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    "dllexport_decl", options_.dllexport_decl,
917fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "adddescriptorsname",
918a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    GlobalAddDescriptorsName(descriptor_->file()->name()));
919a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
920fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Print(
921fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "friend void $assigndescriptorsname$();\n"
922fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "friend void $shutdownfilename$();\n"
923fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "\n",
924fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "assigndescriptorsname",
925fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      GlobalAssignDescriptorsName(descriptor_->file()->name()),
926fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "shutdownfilename", GlobalShutdownFileName(descriptor_->file()->name()));
927fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
928fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Print(
929fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "void InitAsDefaultInstance();\n"
930fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "static $classname$* default_instance_;\n",
931fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "classname", classname_);
932fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
933fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Outdent();
934fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Print(vars, "};");
935a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  GOOGLE_DCHECK(!need_to_emit_cached_size);
936fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
937fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
938fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid MessageGenerator::
939fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleGenerateInlineMethods(io::Printer* printer) {
940fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  for (int i = 0; i < descriptor_->nested_type_count(); i++) {
941fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    nested_generators_[i]->GenerateInlineMethods(printer);
942fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print(kThinSeparator);
943fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print("\n");
944fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
945fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
946fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  GenerateFieldAccessorDefinitions(printer);
947a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
948a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  // Generate oneof_case() functions.
949a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
950a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    map<string, string> vars;
951a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    vars["class_name"] = classname_;
952a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    vars["camel_oneof_name"] = UnderscoresToCamelCase(
953a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        descriptor_->oneof_decl(i)->name(), true);
954a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    vars["oneof_name"] = descriptor_->oneof_decl(i)->name();
955a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    vars["oneof_index"] = SimpleItoa(descriptor_->oneof_decl(i)->index());
956a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    printer->Print(
957a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        vars,
958a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        "inline $class_name$::$camel_oneof_name$Case $class_name$::"
959a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        "$oneof_name$_case() const {\n"
960a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        "  return $class_name$::$camel_oneof_name$Case("
961a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        "_oneof_case_[$oneof_index$]);\n"
962a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        "}\n");
963a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  }
964fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
965fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
966fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid MessageGenerator::
967fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleGenerateDescriptorDeclarations(io::Printer* printer) {
968fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Print(
969fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "const ::google::protobuf::Descriptor* $name$_descriptor_ = NULL;\n"
970fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "const ::google::protobuf::internal::GeneratedMessageReflection*\n"
971fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "  $name$_reflection_ = NULL;\n",
972fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "name", classname_);
973fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
974a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  // Generate oneof default instance for reflection usage.
975a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  if (descriptor_->oneof_decl_count() > 0) {
976a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    printer->Print("struct $name$OneofInstance {\n",
977a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson                   "name", classname_);
978a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
979a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      for (int j = 0; j < descriptor_->oneof_decl(i)->field_count(); j++) {
980a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        const FieldDescriptor* field = descriptor_->oneof_decl(i)->field(j);
981a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        printer->Print("  ");
982a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        if (IsStringOrMessage(field)) {
983a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson          printer->Print("const ");
984a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        }
985a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        field_generators_.get(field).GeneratePrivateMembers(printer);
986a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      }
987a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    }
988a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
989a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    printer->Print("}* $name$_default_oneof_instance_ = NULL;\n",
990a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson                   "name", classname_);
991a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  }
992a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
993fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  for (int i = 0; i < descriptor_->nested_type_count(); i++) {
994fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    nested_generators_[i]->GenerateDescriptorDeclarations(printer);
995fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
996fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
997fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  for (int i = 0; i < descriptor_->enum_type_count(); i++) {
998fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print(
999fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "const ::google::protobuf::EnumDescriptor* $name$_descriptor_ = NULL;\n",
1000fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "name", ClassName(descriptor_->enum_type(i), false));
1001fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
1002fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
1003fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1004fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid MessageGenerator::
1005fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleGenerateDescriptorInitializer(io::Printer* printer, int index) {
1006fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // TODO(kenton):  Passing the index to this method is redundant; just use
1007fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  //   descriptor_->index() instead.
1008fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  map<string, string> vars;
1009fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  vars["classname"] = classname_;
1010fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  vars["index"] = SimpleItoa(index);
1011fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1012fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // Obtain the descriptor from the parent's descriptor.
1013fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (descriptor_->containing_type() == NULL) {
1014fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print(vars,
1015fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "$classname$_descriptor_ = file->message_type($index$);\n");
1016fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  } else {
1017fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    vars["parent"] = ClassName(descriptor_->containing_type(), false);
1018fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print(vars,
1019fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "$classname$_descriptor_ = "
1020fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        "$parent$_descriptor_->nested_type($index$);\n");
1021fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
1022fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1023fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // Generate the offsets.
1024fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  GenerateOffsets(printer);
1025fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1026fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // Construct the reflection object.
1027fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Print(vars,
1028fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "$classname$_reflection_ =\n"
1029fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "  new ::google::protobuf::internal::GeneratedMessageReflection(\n"
1030fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "    $classname$_descriptor_,\n"
1031fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "    $classname$::default_instance_,\n"
1032fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "    $classname$_offsets_,\n"
1033fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET($classname$, _has_bits_[0]),\n"
1034fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET("
1035fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "$classname$, _unknown_fields_),\n");
1036fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (descriptor_->extension_range_count() > 0) {
1037fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print(vars,
1038fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET("
1039fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        "$classname$, _extensions_),\n");
1040fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  } else {
1041fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // No extensions.
1042fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print(vars,
1043fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "    -1,\n");
1044fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
1045a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
1046a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  if (descriptor_->oneof_decl_count() > 0) {
1047a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    printer->Print(vars,
1048a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    "    $classname$_default_oneof_instance_,\n"
1049a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    "    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET("
1050a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      "$classname$, _oneof_case_[0]),\n");
1051a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  }
1052a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
1053a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  printer->Print(
1054a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    "    ::google::protobuf::DescriptorPool::generated_pool(),\n");
1055a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  printer->Print(vars,
1056a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    "    ::google::protobuf::MessageFactory::generated_factory(),\n");
1057fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Print(vars,
1058fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "    sizeof($classname$));\n");
1059fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1060fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // Handle nested types.
1061fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  for (int i = 0; i < descriptor_->nested_type_count(); i++) {
1062fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    nested_generators_[i]->GenerateDescriptorInitializer(printer, i);
1063fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
1064fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1065fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  for (int i = 0; i < descriptor_->enum_type_count(); i++) {
1066fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    enum_generators_[i]->GenerateDescriptorInitializer(printer, i);
1067fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
1068fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
1069fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1070fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid MessageGenerator::
1071fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleGenerateTypeRegistrations(io::Printer* printer) {
1072fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // Register this message type with the message factory.
1073fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Print(
1074fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(\n"
1075fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "  $classname$_descriptor_, &$classname$::default_instance());\n",
1076fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "classname", classname_);
1077fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1078fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // Handle nested types.
1079fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  for (int i = 0; i < descriptor_->nested_type_count(); i++) {
1080fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    nested_generators_[i]->GenerateTypeRegistrations(printer);
1081fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
1082fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
1083fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1084fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid MessageGenerator::
1085fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleGenerateDefaultInstanceAllocator(io::Printer* printer) {
1086a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  // Construct the default instances of all fields, as they will be used
1087a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  // when creating the default instance of the entire message.
1088a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  for (int i = 0; i < descriptor_->field_count(); i++) {
1089a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    field_generators_.get(descriptor_->field(i))
1090a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson                     .GenerateDefaultInstanceAllocator(printer);
1091a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  }
1092a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
1093fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // Construct the default instance.  We can't call InitAsDefaultInstance() yet
1094fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // because we need to make sure all default instances that this one might
1095fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // depend on are constructed first.
1096fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Print(
1097fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "$classname$::default_instance_ = new $classname$();\n",
1098fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "classname", classname_);
1099fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1100a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  if ((descriptor_->oneof_decl_count() > 0) &&
1101a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      HasDescriptorMethods(descriptor_->file())) {
1102a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    printer->Print(
1103a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    "$classname$_default_oneof_instance_ = new $classname$OneofInstance;\n",
1104a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    "classname", classname_);
1105a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  }
1106a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
1107fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // Handle nested types.
1108fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  for (int i = 0; i < descriptor_->nested_type_count(); i++) {
1109fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    nested_generators_[i]->GenerateDefaultInstanceAllocator(printer);
1110fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
1111d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville
1112fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
1113fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1114fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid MessageGenerator::
1115fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleGenerateDefaultInstanceInitializer(io::Printer* printer) {
1116fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Print(
1117fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "$classname$::default_instance_->InitAsDefaultInstance();\n",
1118fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "classname", classname_);
1119fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1120fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // Register extensions.
1121fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  for (int i = 0; i < descriptor_->extension_count(); i++) {
1122fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    extension_generators_[i]->GenerateRegistration(printer);
1123fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
1124fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1125fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // Handle nested types.
1126fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  for (int i = 0; i < descriptor_->nested_type_count(); i++) {
1127fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    nested_generators_[i]->GenerateDefaultInstanceInitializer(printer);
1128fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
1129fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
1130fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1131fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid MessageGenerator::
1132fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleGenerateShutdownCode(io::Printer* printer) {
1133fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Print(
1134fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "delete $classname$::default_instance_;\n",
1135fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "classname", classname_);
1136fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1137fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (HasDescriptorMethods(descriptor_->file())) {
1138a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    if (descriptor_->oneof_decl_count() > 0) {
1139a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      printer->Print(
1140a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        "delete $classname$_default_oneof_instance_;\n",
1141a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        "classname", classname_);
1142a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    }
1143fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print(
1144fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "delete $classname$_reflection_;\n",
1145fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "classname", classname_);
1146fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
1147fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1148a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  // Handle default instances of fields.
1149a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  for (int i = 0; i < descriptor_->field_count(); i++) {
1150a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    field_generators_.get(descriptor_->field(i))
1151a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson                     .GenerateShutdownCode(printer);
1152a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  }
1153a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
1154fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // Handle nested types.
1155fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  for (int i = 0; i < descriptor_->nested_type_count(); i++) {
1156fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    nested_generators_[i]->GenerateShutdownCode(printer);
1157fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
1158fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
1159fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1160fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid MessageGenerator::
1161fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleGenerateClassMethods(io::Printer* printer) {
1162fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  for (int i = 0; i < descriptor_->enum_type_count(); i++) {
1163fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    enum_generators_[i]->GenerateMethods(printer);
1164fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
1165fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1166fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  for (int i = 0; i < descriptor_->nested_type_count(); i++) {
1167fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    nested_generators_[i]->GenerateClassMethods(printer);
1168fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print("\n");
1169fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print(kThinSeparator);
1170fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print("\n");
1171fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
1172fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1173fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // Generate non-inline field definitions.
1174fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  for (int i = 0; i < descriptor_->field_count(); i++) {
1175fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    field_generators_.get(descriptor_->field(i))
1176fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville                     .GenerateNonInlineAccessorDefinitions(printer);
1177fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
1178fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1179fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // Generate field number constants.
1180fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Print("#ifndef _MSC_VER\n");
1181fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  for (int i = 0; i < descriptor_->field_count(); i++) {
1182fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    const FieldDescriptor *field = descriptor_->field(i);
1183fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print(
1184fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "const int $classname$::$constant_name$;\n",
1185fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "classname", ClassName(FieldScope(field), false),
1186fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "constant_name", FieldConstantName(field));
1187fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
1188fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Print(
1189fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "#endif  // !_MSC_VER\n"
1190fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "\n");
1191fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1192fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // Define extension identifiers.
1193fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  for (int i = 0; i < descriptor_->extension_count(); i++) {
1194fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    extension_generators_[i]->GenerateDefinition(printer);
1195fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
1196fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1197fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  GenerateStructors(printer);
1198fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Print("\n");
1199fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1200a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  if (descriptor_->oneof_decl_count() > 0) {
1201a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    GenerateOneofClear(printer);
1202a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    printer->Print("\n");
1203a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  }
1204a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
1205fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (HasGeneratedMethods(descriptor_->file())) {
1206fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    GenerateClear(printer);
1207fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print("\n");
1208fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1209fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    GenerateMergeFromCodedStream(printer);
1210fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print("\n");
1211fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1212fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    GenerateSerializeWithCachedSizes(printer);
1213fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print("\n");
1214fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1215fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    if (HasFastArraySerialization(descriptor_->file())) {
1216fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      GenerateSerializeWithCachedSizesToArray(printer);
1217fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      printer->Print("\n");
1218fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
1219fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1220fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    GenerateByteSize(printer);
1221fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print("\n");
1222fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1223fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    GenerateMergeFrom(printer);
1224fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print("\n");
1225fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1226fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    GenerateCopyFrom(printer);
1227fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print("\n");
1228fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1229fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    GenerateIsInitialized(printer);
1230fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print("\n");
1231fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
1232fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1233fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  GenerateSwap(printer);
1234fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Print("\n");
1235fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1236fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (HasDescriptorMethods(descriptor_->file())) {
1237fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print(
1238fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "::google::protobuf::Metadata $classname$::GetMetadata() const {\n"
1239fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "  protobuf_AssignDescriptorsOnce();\n"
1240fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "  ::google::protobuf::Metadata metadata;\n"
1241fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "  metadata.descriptor = $classname$_descriptor_;\n"
1242fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "  metadata.reflection = $classname$_reflection_;\n"
1243fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "  return metadata;\n"
1244fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "}\n"
1245fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "\n",
1246fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "classname", classname_);
1247fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  } else {
1248fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print(
1249fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "::std::string $classname$::GetTypeName() const {\n"
1250fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "  return \"$type_name$\";\n"
1251fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "}\n"
1252fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "\n",
1253fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "classname", classname_,
1254fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "type_name", descriptor_->full_name());
1255fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
1256d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville
1257fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
1258fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1259fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid MessageGenerator::
1260fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleGenerateOffsets(io::Printer* printer) {
1261fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Print(
1262fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "static const int $classname$_offsets_[$field_count$] = {\n",
1263fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "classname", classname_,
1264a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    "field_count", SimpleItoa(max(
1265a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        1, descriptor_->field_count() + descriptor_->oneof_decl_count())));
1266fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Indent();
1267fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1268fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  for (int i = 0; i < descriptor_->field_count(); i++) {
1269fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    const FieldDescriptor* field = descriptor_->field(i);
1270a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    if (field->containing_oneof()) {
1271a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      printer->Print(
1272a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson          "PROTO2_GENERATED_DEFAULT_ONEOF_FIELD_OFFSET("
1273a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson          "$classname$_default_oneof_instance_, $name$_),\n",
1274a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson          "classname", classname_,
1275a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson          "name", FieldName(field));
1276a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    } else {
1277a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      printer->Print(
1278a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson          "GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET($classname$, "
1279a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson                                                 "$name$_),\n",
1280a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson          "classname", classname_,
1281a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson          "name", FieldName(field));
1282a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    }
1283a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  }
1284a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
1285a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
1286a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    const OneofDescriptor* oneof = descriptor_->oneof_decl(i);
1287fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print(
1288fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET($classname$, $name$_),\n",
1289fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "classname", classname_,
1290a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      "name", oneof->name());
1291fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
1292fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1293fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Outdent();
1294fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Print("};\n");
1295fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
1296fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1297fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid MessageGenerator::
1298fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleGenerateSharedConstructorCode(io::Printer* printer) {
1299fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Print(
1300fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "void $classname$::SharedCtor() {\n",
1301fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "classname", classname_);
1302fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Indent();
1303fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1304a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  printer->Print(StrCat(
1305a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      uses_string_ ? "::google::protobuf::internal::GetEmptyString();\n" : "",
1306a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      "_cached_size_ = 0;\n").c_str());
1307fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1308fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  for (int i = 0; i < descriptor_->field_count(); i++) {
1309a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    if (!descriptor_->field(i)->containing_oneof()) {
1310a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      field_generators_.get(descriptor_->field(i))
1311a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson          .GenerateConstructorCode(printer);
1312a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    }
1313fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
1314fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1315fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Print(
1316fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "::memset(_has_bits_, 0, sizeof(_has_bits_));\n");
1317fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1318a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
1319a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    printer->Print(
1320a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        "clear_has_$oneof_name$();\n",
1321a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        "oneof_name", descriptor_->oneof_decl(i)->name());
1322a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  }
1323a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
1324fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Outdent();
1325fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Print("}\n\n");
1326fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
1327fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1328fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid MessageGenerator::
1329fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleGenerateSharedDestructorCode(io::Printer* printer) {
1330fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Print(
1331fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "void $classname$::SharedDtor() {\n",
1332fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "classname", classname_);
1333fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Indent();
1334a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  // Write the destructors for each field except oneof members.
1335fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  for (int i = 0; i < descriptor_->field_count(); i++) {
1336a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    if (!descriptor_->field(i)->containing_oneof()) {
1337a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      field_generators_.get(descriptor_->field(i))
1338a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson                       .GenerateDestructorCode(printer);
1339a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    }
1340fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
1341fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1342a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  // Generate code to destruct oneofs. Clearing should do the work.
1343a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
1344a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    printer->Print(
1345a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        "if (has_$oneof_name$()) {\n"
1346a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        "  clear_$oneof_name$();\n"
1347a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        "}\n",
1348a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        "oneof_name", descriptor_->oneof_decl(i)->name());
1349a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  }
1350a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
1351a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  PrintHandlingOptionalStaticInitializers(
1352a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    descriptor_->file(), printer,
1353a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    // With static initializers.
1354a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    "if (this != default_instance_) {\n",
1355a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    // Without.
1356a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    "if (this != &default_instance()) {\n");
1357fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1358fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // We need to delete all embedded messages.
1359fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // TODO(kenton):  If we make unset messages point at default instances
1360fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  //   instead of NULL, then it would make sense to move this code into
1361fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  //   MessageFieldGenerator::GenerateDestructorCode().
1362fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  for (int i = 0; i < descriptor_->field_count(); i++) {
1363fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    const FieldDescriptor* field = descriptor_->field(i);
1364fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1365fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    if (!field->is_repeated() &&
1366fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
1367a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      // Skip oneof members
1368a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      if (!field->containing_oneof()) {
1369a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        printer->Print(
1370a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson            "  delete $name$_;\n",
1371a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson            "name", FieldName(field));
1372a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      }
1373fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
1374fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
1375fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1376fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Outdent();
1377fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Print(
1378fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "  }\n"
1379fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "}\n"
1380fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "\n");
1381fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
1382fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1383fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid MessageGenerator::
1384fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleGenerateStructors(io::Printer* printer) {
1385d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  string superclass = SuperClassName(descriptor_);
1386d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville
1387fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // Generate the default constructor.
1388fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Print(
1389d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    "$classname$::$classname$()\n"
1390d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    "  : $superclass$() {\n"
1391fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "  SharedCtor();\n"
1392a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    "  // @@protoc_insertion_point(constructor:$full_name$)\n"
1393fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "}\n",
1394d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    "classname", classname_,
1395a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    "superclass", superclass,
1396a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    "full_name", descriptor_->full_name());
1397fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1398fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Print(
1399fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "\n"
1400fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "void $classname$::InitAsDefaultInstance() {\n",
1401fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "classname", classname_);
1402fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1403fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // The default instance needs all of its embedded message pointers
1404fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // cross-linked to other default instances.  We can't do this initialization
1405fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // in the constructor because some other default instances may not have been
1406fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // constructed yet at that time.
1407fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // TODO(kenton):  Maybe all message fields (even for non-default messages)
1408fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  //   should be initialized to point at default instances rather than NULL?
1409fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  for (int i = 0; i < descriptor_->field_count(); i++) {
1410fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    const FieldDescriptor* field = descriptor_->field(i);
1411fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1412fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    if (!field->is_repeated() &&
1413a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE &&
1414a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        (field->containing_oneof() == NULL ||
1415a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson         HasDescriptorMethods(descriptor_->file()))) {
1416a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      string name;
1417a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      if (field->containing_oneof()) {
1418a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        name = classname_ + "_default_oneof_instance_->";
1419a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      }
1420a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      name += FieldName(field);
1421a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      PrintHandlingOptionalStaticInitializers(
1422a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        descriptor_->file(), printer,
1423a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        // With static initializers.
1424a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        "  $name$_ = const_cast< $type$*>(&$type$::default_instance());\n",
1425a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        // Without.
1426a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        "  $name$_ = const_cast< $type$*>(\n"
1427a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        "      $type$::internal_default_instance());\n",
1428a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        // Vars.
1429a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        "name", name,
1430a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        "type", FieldMessageTypeName(field));
1431a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    } else if (field->containing_oneof() &&
1432a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson               HasDescriptorMethods(descriptor_->file())) {
1433a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      field_generators_.get(descriptor_->field(i))
1434a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson          .GenerateConstructorCode(printer);
1435fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
1436fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
1437fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Print(
1438fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "}\n"
1439fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "\n");
1440fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1441fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // Generate the copy constructor.
1442fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Print(
1443d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    "$classname$::$classname$(const $classname$& from)\n"
1444d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    "  : $superclass$() {\n"
1445fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "  SharedCtor();\n"
1446fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "  MergeFrom(from);\n"
1447a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    "  // @@protoc_insertion_point(copy_constructor:$full_name$)\n"
1448fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "}\n"
1449fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "\n",
1450d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    "classname", classname_,
1451a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    "superclass", superclass,
1452a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    "full_name", descriptor_->full_name());
1453fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1454fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // Generate the shared constructor code.
1455fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  GenerateSharedConstructorCode(printer);
1456fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1457fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // Generate the destructor.
1458fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Print(
1459fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "$classname$::~$classname$() {\n"
1460a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    "  // @@protoc_insertion_point(destructor:$full_name$)\n"
1461fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "  SharedDtor();\n"
1462fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "}\n"
1463fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "\n",
1464a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    "classname", classname_,
1465a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    "full_name", descriptor_->full_name());
1466fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1467fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // Generate the shared destructor code.
1468fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  GenerateSharedDestructorCode(printer);
1469fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1470d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  // Generate SetCachedSize.
1471d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  printer->Print(
1472d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    "void $classname$::SetCachedSize(int size) const {\n"
1473d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    "  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();\n"
1474d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    "  _cached_size_ = size;\n"
1475d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    "  GOOGLE_SAFE_CONCURRENT_WRITES_END();\n"
1476d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    "}\n",
1477d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    "classname", classname_);
1478d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville
1479fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // Only generate this member if it's not disabled.
1480fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (HasDescriptorMethods(descriptor_->file()) &&
1481fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      !descriptor_->options().no_standard_descriptor_accessor()) {
1482fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print(
1483fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "const ::google::protobuf::Descriptor* $classname$::descriptor() {\n"
1484fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "  protobuf_AssignDescriptorsOnce();\n"
1485fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "  return $classname$_descriptor_;\n"
1486fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "}\n"
1487fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "\n",
1488fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "classname", classname_,
1489fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "adddescriptorsname",
1490fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      GlobalAddDescriptorsName(descriptor_->file()->name()));
1491fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
1492fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1493fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Print(
1494a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    "const $classname$& $classname$::default_instance() {\n",
1495a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    "classname", classname_);
1496a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
1497a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  PrintHandlingOptionalStaticInitializers(
1498a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    descriptor_->file(), printer,
1499a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    // With static initializers.
1500a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    "  if (default_instance_ == NULL) $adddescriptorsname$();\n",
1501a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    // Without.
1502a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    "  $adddescriptorsname$();\n",
1503a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    // Vars.
1504a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    "adddescriptorsname",
1505a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    GlobalAddDescriptorsName(descriptor_->file()->name()));
1506a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
1507a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  printer->Print(
1508fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "  return *default_instance_;\n"
1509fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "}\n"
1510fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "\n"
1511fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "$classname$* $classname$::default_instance_ = NULL;\n"
1512a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    "\n",
1513a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    "classname", classname_);
1514a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
1515a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  printer->Print(
1516fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "$classname$* $classname$::New() const {\n"
1517fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "  return new $classname$;\n"
1518fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "}\n",
1519a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    "classname", classname_);
1520d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville
1521fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
1522fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1523a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson// Return the number of bits set in n, a non-negative integer.
1524a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidsonstatic int popcnt(uint32 n) {
1525a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  int result = 0;
1526a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  while (n != 0) {
1527a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    result += (n & 1);
1528a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    n = n / 2;
1529a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  }
1530a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  return result;
1531a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson}
1532a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
1533fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid MessageGenerator::
1534fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleGenerateClear(io::Printer* printer) {
1535fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Print("void $classname$::Clear() {\n",
1536fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville                 "classname", classname_);
1537fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Indent();
1538fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1539a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  // Step 1: Extensions
1540fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (descriptor_->extension_range_count() > 0) {
1541fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print("_extensions_.Clear();\n");
1542fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
1543fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1544a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  // Step 2: Everything but extensions, repeateds, unions.
1545a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  // These are handled in chunks of 8.  The first chunk is
1546a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  // the non-extensions-non-repeateds-non-unions in
1547a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  //  descriptor_->field(0), descriptor_->field(1), ... descriptor_->field(7),
1548a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  // and the second chunk is the same for
1549a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  //  descriptor_->field(8), descriptor_->field(9), ... descriptor_->field(15),
1550a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  // etc.
1551a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  set<int> step2_indices;
1552a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  hash_map<string, int> fieldname_to_chunk;
1553a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  hash_map<int, string> memsets_for_chunk;
1554a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  hash_map<int, int> memset_field_count_for_chunk;
1555a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  hash_set<string> handled;  // fields that appear anywhere in memsets_for_chunk
1556a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  hash_map<int, uint32> fields_mask_for_chunk;
1557fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  for (int i = 0; i < descriptor_->field_count(); i++) {
1558fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    const FieldDescriptor* field = descriptor_->field(i);
1559a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    if (!field->is_repeated() && !field->containing_oneof()) {
1560a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      step2_indices.insert(i);
1561a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      int chunk = i / 8;
1562a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      fieldname_to_chunk[FieldName(field)] = chunk;
1563a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      fields_mask_for_chunk[chunk] |= static_cast<uint32>(1) << (i % 32);
1564a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    }
1565a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  }
1566fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1567a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  // Step 2a: Greedily seek runs of fields that can be cleared by memset-to-0.
1568a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  // The generated code uses two macros to help it clear runs of fields:
1569a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  // OFFSET_OF_FIELD_ computes the offset (in bytes) of a field in the Message.
1570a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  // ZR_ zeroes a non-empty range of fields via memset.
1571a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  const char* macros =
1572a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      "#define OFFSET_OF_FIELD_(f) (reinterpret_cast<char*>(      \\\n"
1573a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      "  &reinterpret_cast<$classname$*>(16)->f) - \\\n"
1574a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      "   reinterpret_cast<char*>(16))\n\n"
1575a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      "#define ZR_(first, last) do {                              \\\n"
1576a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      "    size_t f = OFFSET_OF_FIELD_(first);                    \\\n"
1577a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      "    size_t n = OFFSET_OF_FIELD_(last) - f + sizeof(last);  \\\n"
1578a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      "    ::memset(&first, 0, n);                                \\\n"
1579a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      "  } while (0)\n\n";
1580a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  for (int i = 0; i < runs_of_fields_.size(); i++) {
1581a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    const vector<string>& run = runs_of_fields_[i];
1582a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    if (run.size() < 2) continue;
1583a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    const string& first_field_name = run[0];
1584a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    const string& last_field_name = run.back();
1585a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    int chunk = fieldname_to_chunk[run[0]];
1586a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    memsets_for_chunk[chunk].append(
1587a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      "ZR_(" + first_field_name + "_, " + last_field_name + "_);\n");
1588a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    for (int j = 0; j < run.size(); j++) {
1589a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      GOOGLE_DCHECK_EQ(chunk, fieldname_to_chunk[run[j]]);
1590a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      handled.insert(run[j]);
1591a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    }
1592a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    memset_field_count_for_chunk[chunk] += run.size();
1593a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  }
1594a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  const bool macros_are_needed = handled.size() > 0;
1595a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  if (macros_are_needed) {
1596a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    printer->Outdent();
1597a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    printer->Print(macros,
1598a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson                   "classname", classname_);
1599a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    printer->Indent();
1600a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  }
1601a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  // Step 2b: Finish step 2, ignoring fields handled in step 2a.
1602a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  int last_index = -1;
1603a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  bool chunk_block_in_progress = false;
1604a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  for (int i = 0; i < descriptor_->field_count(); i++) {
1605a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    if (step2_indices.count(i) == 0) continue;
1606a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    const FieldDescriptor* field = descriptor_->field(i);
1607a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    const string fieldname = FieldName(field);
1608a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    if (i / 8 != last_index / 8 || last_index < 0) {
1609a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      // End previous chunk, if there was one.
1610a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      if (chunk_block_in_progress) {
1611a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        printer->Outdent();
1612a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        printer->Print("}\n");
1613a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        chunk_block_in_progress = false;
1614fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      }
1615a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      // Start chunk.
1616a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      const string& memsets = memsets_for_chunk[i / 8];
1617a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      uint32 mask = fields_mask_for_chunk[i / 8];
1618a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      int count = popcnt(mask);
1619a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      if (count == 1 ||
1620a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson          (count <= 4 && count == memset_field_count_for_chunk[i / 8])) {
1621a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        // No "if" here because the chunk is trivial.
1622a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      } else {
1623a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        printer->Print(
1624a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson          "if (_has_bits_[$index$ / 32] & $mask$) {\n",
1625a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson          "index", SimpleItoa(i / 8 * 8),
1626a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson          "mask", SimpleItoa(mask));
1627fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        printer->Indent();
1628a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        chunk_block_in_progress = true;
1629fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      }
1630a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      printer->Print(memsets.c_str());
1631a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    }
1632a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    last_index = i;
1633a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    if (handled.count(fieldname) > 0) continue;
1634a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
1635a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    // It's faster to just overwrite primitive types, but we should
1636a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    // only clear strings and messages if they were set.
1637a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    // TODO(kenton):  Let the CppFieldGenerator decide this somehow.
1638a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    bool should_check_bit =
1639a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE ||
1640a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      field->cpp_type() == FieldDescriptor::CPPTYPE_STRING;
1641a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
1642a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    if (should_check_bit) {
1643a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      printer->Print("if (has_$name$()) {\n", "name", fieldname);
1644a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      printer->Indent();
1645a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    }
1646fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1647a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    field_generators_.get(field).GenerateClearingCode(printer);
1648fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1649a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    if (should_check_bit) {
1650a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      printer->Outdent();
1651a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      printer->Print("}\n");
1652fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
1653fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
1654fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1655a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  if (chunk_block_in_progress) {
1656fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Outdent();
1657fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print("}\n");
1658fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
1659a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  if (macros_are_needed) {
1660a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    printer->Outdent();
1661a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    printer->Print("\n#undef OFFSET_OF_FIELD_\n#undef ZR_\n\n");
1662a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    printer->Indent();
1663a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  }
1664fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1665a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  // Step 3: Repeated fields don't use _has_bits_; emit code to clear them here.
1666fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  for (int i = 0; i < descriptor_->field_count(); i++) {
1667fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    const FieldDescriptor* field = descriptor_->field(i);
1668fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1669fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    if (field->is_repeated()) {
1670fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      field_generators_.get(field).GenerateClearingCode(printer);
1671fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
1672fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
1673fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1674a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  // Step 4: Unions.
1675a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
1676a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    printer->Print(
1677a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        "clear_$oneof_name$();\n",
1678a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        "oneof_name", descriptor_->oneof_decl(i)->name());
1679a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  }
1680a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
1681a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  // Step 5: Everything else.
1682fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Print(
1683fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "::memset(_has_bits_, 0, sizeof(_has_bits_));\n");
1684fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1685a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  if (UseUnknownFieldSet(descriptor_->file())) {
1686fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print(
1687fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "mutable_unknown_fields()->Clear();\n");
1688a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  } else {
1689a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    printer->Print(
1690a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      "mutable_unknown_fields()->clear();\n");
1691fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
1692fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1693fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Outdent();
1694fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Print("}\n");
1695fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
1696fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1697fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid MessageGenerator::
1698a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff DavidsonGenerateOneofClear(io::Printer* printer) {
1699a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  // Generated function clears the active field and union case (e.g. foo_case_).
1700a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
1701a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    printer->Print(
1702a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        "void $classname$::clear_$oneofname$() {\n",
1703a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        "classname", classname_,
1704a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        "oneofname", descriptor_->oneof_decl(i)->name());
1705a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    printer->Indent();
1706a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    printer->Print(
1707a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        "switch($oneofname$_case()) {\n",
1708a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        "oneofname", descriptor_->oneof_decl(i)->name());
1709a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    printer->Indent();
1710a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    for (int j = 0; j < descriptor_->oneof_decl(i)->field_count(); j++) {
1711a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      const FieldDescriptor* field = descriptor_->oneof_decl(i)->field(j);
1712a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      printer->Print(
1713a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson          "case k$field_name$: {\n",
1714a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson          "field_name", UnderscoresToCamelCase(field->name(), true));
1715a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      printer->Indent();
1716a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      // We clear only allocated objects in oneofs
1717a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      if (!IsStringOrMessage(field)) {
1718a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        printer->Print(
1719a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson            "// No need to clear\n");
1720a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      } else {
1721a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        field_generators_.get(field).GenerateClearingCode(printer);
1722a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      }
1723a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      printer->Print(
1724a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson          "break;\n");
1725a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      printer->Outdent();
1726a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      printer->Print(
1727a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson          "}\n");
1728a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    }
1729a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    printer->Print(
1730a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        "case $cap_oneof_name$_NOT_SET: {\n"
1731a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        "  break;\n"
1732a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        "}\n",
1733a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        "cap_oneof_name",
1734a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        ToUpper(descriptor_->oneof_decl(i)->name()));
1735a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    printer->Outdent();
1736a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    printer->Print(
1737a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        "}\n"
1738a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        "_oneof_case_[$oneof_index$] = $cap_oneof_name$_NOT_SET;\n",
1739a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        "oneof_index", SimpleItoa(i),
1740a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        "cap_oneof_name",
1741a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        ToUpper(descriptor_->oneof_decl(i)->name()));
1742a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    printer->Outdent();
1743a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    printer->Print(
1744a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        "}\n"
1745a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        "\n");
1746a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  }
1747a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson}
1748a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
1749a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidsonvoid MessageGenerator::
1750fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleGenerateSwap(io::Printer* printer) {
1751fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // Generate the Swap member function.
1752fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Print("void $classname$::Swap($classname$* other) {\n",
1753fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville                 "classname", classname_);
1754fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Indent();
1755fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Print("if (other != this) {\n");
1756fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Indent();
1757fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1758fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (HasGeneratedMethods(descriptor_->file())) {
1759fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    for (int i = 0; i < descriptor_->field_count(); i++) {
1760fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      const FieldDescriptor* field = descriptor_->field(i);
1761fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      field_generators_.get(field).GenerateSwappingCode(printer);
1762fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
1763fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1764a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
1765a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      printer->Print(
1766a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        "std::swap($oneof_name$_, other->$oneof_name$_);\n"
1767a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        "std::swap(_oneof_case_[$i$], other->_oneof_case_[$i$]);\n",
1768a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        "oneof_name", descriptor_->oneof_decl(i)->name(),
1769a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        "i", SimpleItoa(i));
1770a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    }
1771a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
1772fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    for (int i = 0; i < (descriptor_->field_count() + 31) / 32; ++i) {
1773fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      printer->Print("std::swap(_has_bits_[$i$], other->_has_bits_[$i$]);\n",
1774fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville                     "i", SimpleItoa(i));
1775fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
1776fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1777a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    if (UseUnknownFieldSet(descriptor_->file())) {
1778fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      printer->Print("_unknown_fields_.Swap(&other->_unknown_fields_);\n");
1779a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    } else {
1780a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      printer->Print("_unknown_fields_.swap(other->_unknown_fields_);\n");
1781fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
1782fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print("std::swap(_cached_size_, other->_cached_size_);\n");
1783fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    if (descriptor_->extension_range_count() > 0) {
1784fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      printer->Print("_extensions_.Swap(&other->_extensions_);\n");
1785fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
1786fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  } else {
1787fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print("GetReflection()->Swap(this, other);");
1788fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
1789fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1790fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Outdent();
1791fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Print("}\n");
1792fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Outdent();
1793fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Print("}\n");
1794fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
1795fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1796fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid MessageGenerator::
1797fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleGenerateMergeFrom(io::Printer* printer) {
1798fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (HasDescriptorMethods(descriptor_->file())) {
1799fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // Generate the generalized MergeFrom (aka that which takes in the Message
1800fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // base class as a parameter).
1801fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print(
1802fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "void $classname$::MergeFrom(const ::google::protobuf::Message& from) {\n"
1803fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "  GOOGLE_CHECK_NE(&from, this);\n",
1804fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "classname", classname_);
1805fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Indent();
1806fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1807fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // Cast the message to the proper type. If we find that the message is
1808fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // *not* of the proper type, we can still call Merge via the reflection
1809fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // system, as the GOOGLE_CHECK above ensured that we have the same descriptor
1810fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // for each message.
1811fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print(
1812fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "const $classname$* source =\n"
1813fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "  ::google::protobuf::internal::dynamic_cast_if_available<const $classname$*>(\n"
1814fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "    &from);\n"
1815fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "if (source == NULL) {\n"
1816fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "  ::google::protobuf::internal::ReflectionOps::Merge(from, this);\n"
1817fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "} else {\n"
1818fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "  MergeFrom(*source);\n"
1819fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "}\n",
1820fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "classname", classname_);
1821fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1822fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Outdent();
1823fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print("}\n\n");
1824fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  } else {
1825fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // Generate CheckTypeAndMergeFrom().
1826fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print(
1827fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "void $classname$::CheckTypeAndMergeFrom(\n"
1828fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "    const ::google::protobuf::MessageLite& from) {\n"
1829fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "  MergeFrom(*::google::protobuf::down_cast<const $classname$*>(&from));\n"
1830fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "}\n"
1831fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "\n",
1832fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "classname", classname_);
1833fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
1834fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1835fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // Generate the class-specific MergeFrom, which avoids the GOOGLE_CHECK and cast.
1836fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Print(
1837fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "void $classname$::MergeFrom(const $classname$& from) {\n"
1838fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "  GOOGLE_CHECK_NE(&from, this);\n",
1839fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "classname", classname_);
1840fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Indent();
1841fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1842fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // Merge Repeated fields. These fields do not require a
1843fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // check as we can simply iterate over them.
1844fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  for (int i = 0; i < descriptor_->field_count(); ++i) {
1845fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    const FieldDescriptor* field = descriptor_->field(i);
1846fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1847fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    if (field->is_repeated()) {
1848fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      field_generators_.get(field).GenerateMergingCode(printer);
1849fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
1850fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
1851fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1852a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  // Merge oneof fields. Oneof field requires oneof case check.
1853a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  for (int i = 0; i < descriptor_->oneof_decl_count(); ++i) {
1854a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    printer->Print(
1855a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        "switch (from.$oneofname$_case()) {\n",
1856a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        "oneofname", descriptor_->oneof_decl(i)->name());
1857a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    printer->Indent();
1858a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    for (int j = 0; j < descriptor_->oneof_decl(i)->field_count(); j++) {
1859a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      const FieldDescriptor* field = descriptor_->oneof_decl(i)->field(j);
1860a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      printer->Print(
1861a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson          "case k$field_name$: {\n",
1862a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson          "field_name", UnderscoresToCamelCase(field->name(), true));
1863a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      printer->Indent();
1864a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      field_generators_.get(field).GenerateMergingCode(printer);
1865a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      printer->Print(
1866a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson          "break;\n");
1867a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      printer->Outdent();
1868a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      printer->Print(
1869a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson          "}\n");
1870a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    }
1871a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    printer->Print(
1872a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        "case $cap_oneof_name$_NOT_SET: {\n"
1873a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        "  break;\n"
1874a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        "}\n",
1875a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        "cap_oneof_name",
1876a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        ToUpper(descriptor_->oneof_decl(i)->name()));
1877a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    printer->Outdent();
1878a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    printer->Print(
1879a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        "}\n");
1880a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  }
1881a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
1882fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // Merge Optional and Required fields (after a _has_bit check).
1883fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  int last_index = -1;
1884fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1885fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  for (int i = 0; i < descriptor_->field_count(); ++i) {
1886fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    const FieldDescriptor* field = descriptor_->field(i);
1887fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1888a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    if (!field->is_repeated() && !field->containing_oneof()) {
1889fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      // See above in GenerateClear for an explanation of this.
1890fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      if (i / 8 != last_index / 8 || last_index < 0) {
1891fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        if (last_index >= 0) {
1892fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville          printer->Outdent();
1893fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville          printer->Print("}\n");
1894fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        }
1895a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        printer->Print(
1896a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson          "if (from._has_bits_[$index$ / 32] & (0xffu << ($index$ % 32))) {\n",
1897a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson          "index", SimpleItoa(field->index()));
1898fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        printer->Indent();
1899fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      }
1900fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1901fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      last_index = i;
1902fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1903a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      printer->Print(
1904a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        "if (from.has_$name$()) {\n",
1905a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        "name", FieldName(field));
1906fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      printer->Indent();
1907fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1908fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      field_generators_.get(field).GenerateMergingCode(printer);
1909fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1910fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      printer->Outdent();
1911fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      printer->Print("}\n");
1912fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
1913fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
1914fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1915fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (last_index >= 0) {
1916fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Outdent();
1917fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print("}\n");
1918fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
1919fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1920fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (descriptor_->extension_range_count() > 0) {
1921fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print("_extensions_.MergeFrom(from._extensions_);\n");
1922fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
1923fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1924a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  if (UseUnknownFieldSet(descriptor_->file())) {
1925fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print(
1926fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "mutable_unknown_fields()->MergeFrom(from.unknown_fields());\n");
1927a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  } else {
1928a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    printer->Print(
1929a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      "mutable_unknown_fields()->append(from.unknown_fields());\n");
1930fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
1931fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1932fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Outdent();
1933fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Print("}\n");
1934fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
1935fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1936fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid MessageGenerator::
1937fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleGenerateCopyFrom(io::Printer* printer) {
1938fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (HasDescriptorMethods(descriptor_->file())) {
1939fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // Generate the generalized CopyFrom (aka that which takes in the Message
1940fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // base class as a parameter).
1941fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print(
1942fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "void $classname$::CopyFrom(const ::google::protobuf::Message& from) {\n",
1943fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "classname", classname_);
1944fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Indent();
1945fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1946fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print(
1947fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "if (&from == this) return;\n"
1948fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "Clear();\n"
1949fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "MergeFrom(from);\n");
1950fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1951fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Outdent();
1952fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print("}\n\n");
1953fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
1954fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1955fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // Generate the class-specific CopyFrom.
1956fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Print(
1957fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "void $classname$::CopyFrom(const $classname$& from) {\n",
1958fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "classname", classname_);
1959fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Indent();
1960fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1961fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Print(
1962fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "if (&from == this) return;\n"
1963fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "Clear();\n"
1964fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "MergeFrom(from);\n");
1965fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1966fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Outdent();
1967fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Print("}\n");
1968fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
1969fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1970fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid MessageGenerator::
1971fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleGenerateMergeFromCodedStream(io::Printer* printer) {
1972fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (descriptor_->options().message_set_wire_format()) {
1973fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // Special-case MessageSet.
1974fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print(
1975fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "bool $classname$::MergePartialFromCodedStream(\n"
1976a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      "    ::google::protobuf::io::CodedInputStream* input) {\n",
1977a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      "classname", classname_);
1978a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
1979a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    PrintHandlingOptionalStaticInitializers(
1980a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      descriptor_->file(), printer,
1981a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      // With static initializers.
1982fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "  return _extensions_.ParseMessageSet(input, default_instance_,\n"
1983a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      "                                      mutable_unknown_fields());\n",
1984a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      // Without.
1985a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      "  return _extensions_.ParseMessageSet(input, &default_instance(),\n"
1986a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      "                                      mutable_unknown_fields());\n",
1987a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      // Vars.
1988fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "classname", classname_);
1989a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
1990a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    printer->Print(
1991a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      "}\n");
1992fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return;
1993fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
1994fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1995fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Print(
1996fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "bool $classname$::MergePartialFromCodedStream(\n"
1997fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "    ::google::protobuf::io::CodedInputStream* input) {\n"
1998a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    "#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure\n"
1999a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    "  ::google::protobuf::uint32 tag;\n",
2000fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "classname", classname_);
2001fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
2002a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  if (!UseUnknownFieldSet(descriptor_->file())) {
2003a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    printer->Print(
2004a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      "  ::google::protobuf::io::StringOutputStream unknown_fields_string(\n"
2005a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      "      mutable_unknown_fields());\n"
2006a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      "  ::google::protobuf::io::CodedOutputStream unknown_fields_stream(\n"
2007a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      "      &unknown_fields_string);\n");
2008a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  }
2009a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
2010a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  printer->Print(
2011a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    "  // @@protoc_insertion_point(parse_start:$full_name$)\n",
2012a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    "full_name", descriptor_->full_name());
2013a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
2014fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Indent();
2015a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  printer->Print("for (;;) {\n");
2016fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Indent();
2017fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
2018a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  scoped_array<const FieldDescriptor*> ordered_fields(
2019a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      SortFieldsByNumber(descriptor_));
2020a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  uint32 maxtag = descriptor_->field_count() == 0 ? 0 :
2021a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      WireFormat::MakeTag(ordered_fields[descriptor_->field_count() - 1]);
2022a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  const int kCutoff0 = 127;               // fits in 1-byte varint
2023a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  const int kCutoff1 = (127 << 7) + 127;  // fits in 2-byte varint
2024a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  printer->Print("::std::pair< ::google::protobuf::uint32, bool> p = "
2025a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson                 "input->ReadTagWithCutoff($max$);\n"
2026a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson                 "tag = p.first;\n"
2027a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson                 "if (!p.second) goto handle_unusual;\n",
2028a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson                 "max", SimpleItoa(maxtag <= kCutoff0 ? kCutoff0 :
2029a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson                                   (maxtag <= kCutoff1 ? kCutoff1 :
2030a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson                                    maxtag)));
2031fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (descriptor_->field_count() > 0) {
2032fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // We don't even want to print the switch() if we have no fields because
2033fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // MSVC dislikes switch() statements that contain only a default value.
2034fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
2035fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // Note:  If we just switched on the tag rather than the field number, we
2036fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // could avoid the need for the if() to check the wire type at the beginning
2037fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // of each case.  However, this is actually a bit slower in practice as it
2038fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // creates a jump table that is 8x larger and sparser, and meanwhile the
2039fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // if()s are highly predictable.
2040a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    printer->Print("switch (::google::protobuf::internal::WireFormatLite::"
2041a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson                   "GetTagFieldNumber(tag)) {\n");
2042fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
2043fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Indent();
2044fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
2045fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    for (int i = 0; i < descriptor_->field_count(); i++) {
2046fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      const FieldDescriptor* field = ordered_fields[i];
2047fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
2048fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      PrintFieldComment(printer, field);
2049fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
2050fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      printer->Print(
2051d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville        "case $number$: {\n",
2052d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville        "number", SimpleItoa(field->number()));
2053d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville      printer->Indent();
2054d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville      const FieldGenerator& field_generator = field_generators_.get(field);
2055d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville
2056d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville      // Emit code to parse the common, expected case.
2057a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      printer->Print("if (tag == $commontag$) {\n",
2058a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson                     "commontag", SimpleItoa(WireFormat::MakeTag(field)));
2059fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
2060fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      if (i > 0 || (field->is_repeated() && !field->options().packed())) {
2061fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        printer->Print(
2062fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville          " parse_$name$:\n",
2063fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville          "name", field->name());
2064fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      }
2065fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
2066fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      printer->Indent();
2067d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville      if (field->options().packed()) {
2068d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville        field_generator.GenerateMergeFromCodedStreamWithPacking(printer);
2069d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville      } else {
2070d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville        field_generator.GenerateMergeFromCodedStream(printer);
2071d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville      }
2072d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville      printer->Outdent();
2073fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
2074d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville      // Emit code to parse unexpectedly packed or unpacked values.
2075d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville      if (field->is_packable() && field->options().packed()) {
2076a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        internal::WireFormatLite::WireType wiretype =
2077a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson            WireFormat::WireTypeForFieldType(field->type());
2078a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        printer->Print("} else if (tag == $uncommontag$) {\n",
2079a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson                       "uncommontag", SimpleItoa(
2080a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson                           internal::WireFormatLite::MakeTag(
2081a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson                               field->number(), wiretype)));
2082d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville        printer->Indent();
2083d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville        field_generator.GenerateMergeFromCodedStream(printer);
2084d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville        printer->Outdent();
2085d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville      } else if (field->is_packable() && !field->options().packed()) {
2086a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        internal::WireFormatLite::WireType wiretype =
2087a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson            internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED;
2088a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        printer->Print("} else if (tag == $uncommontag$) {\n",
2089a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson                       "uncommontag", SimpleItoa(
2090a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson                           internal::WireFormatLite::MakeTag(
2091a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson                               field->number(), wiretype)));
2092d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville        printer->Indent();
2093d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville        field_generator.GenerateMergeFromCodedStreamWithPacking(printer);
2094d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville        printer->Outdent();
2095d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville      }
2096d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville
2097d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville      printer->Print(
2098d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville        "} else {\n"
2099a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        "  goto handle_unusual;\n"
2100d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville        "}\n");
2101fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
2102fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      // switch() is slow since it can't be predicted well.  Insert some if()s
2103fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      // here that attempt to predict the next tag.
2104fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      if (field->is_repeated() && !field->options().packed()) {
2105fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        // Expect repeats of this field.
2106fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        printer->Print(
2107fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville          "if (input->ExpectTag($tag$)) goto parse_$name$;\n",
2108fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville          "tag", SimpleItoa(WireFormat::MakeTag(field)),
2109fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville          "name", field->name());
2110fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      }
2111fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
2112fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      if (i + 1 < descriptor_->field_count()) {
2113fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        // Expect the next field in order.
2114fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        const FieldDescriptor* next_field = ordered_fields[i + 1];
2115fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        printer->Print(
2116fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville          "if (input->ExpectTag($next_tag$)) goto parse_$next_name$;\n",
2117fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville          "next_tag", SimpleItoa(WireFormat::MakeTag(next_field)),
2118fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville          "next_name", next_field->name());
2119fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      } else {
2120fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        // Expect EOF.
2121fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        // TODO(kenton):  Expect group end-tag?
2122fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        printer->Print(
2123a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson          "if (input->ExpectAtEnd()) goto success;\n");
2124fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      }
2125fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
2126fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      printer->Print(
2127fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        "break;\n");
2128fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
2129fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      printer->Outdent();
2130fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      printer->Print("}\n\n");
2131fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
2132fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
2133a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    printer->Print("default: {\n");
2134fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Indent();
2135fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
2136fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
2137a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  printer->Outdent();
2138a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  printer->Print("handle_unusual:\n");
2139a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  printer->Indent();
2140a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  // If tag is 0 or an end-group tag then this must be the end of the message.
2141fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Print(
2142a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    "if (tag == 0 ||\n"
2143a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    "    ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==\n"
2144fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "    ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {\n"
2145a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    "  goto success;\n"
2146fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "}\n");
2147fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
2148fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // Handle extension ranges.
2149fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (descriptor_->extension_range_count() > 0) {
2150fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print(
2151fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "if (");
2152fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    for (int i = 0; i < descriptor_->extension_range_count(); i++) {
2153fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      const Descriptor::ExtensionRange* range =
2154fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        descriptor_->extension_range(i);
2155fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      if (i > 0) printer->Print(" ||\n    ");
2156fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
2157fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      uint32 start_tag = WireFormatLite::MakeTag(
2158fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        range->start, static_cast<WireFormatLite::WireType>(0));
2159fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      uint32 end_tag = WireFormatLite::MakeTag(
2160fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        range->end, static_cast<WireFormatLite::WireType>(0));
2161fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
2162fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      if (range->end > FieldDescriptor::kMaxNumber) {
2163fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        printer->Print(
2164fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville          "($start$u <= tag)",
2165fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville          "start", SimpleItoa(start_tag));
2166fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      } else {
2167fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        printer->Print(
2168fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville          "($start$u <= tag && tag < $end$u)",
2169fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville          "start", SimpleItoa(start_tag),
2170fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville          "end", SimpleItoa(end_tag));
2171fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      }
2172fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
2173fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print(") {\n");
2174a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    if (UseUnknownFieldSet(descriptor_->file())) {
2175a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      PrintHandlingOptionalStaticInitializers(
2176a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        descriptor_->file(), printer,
2177a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        // With static initializers.
2178fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        "  DO_(_extensions_.ParseField(tag, input, default_instance_,\n"
2179a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        "                              mutable_unknown_fields()));\n",
2180a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        // Without.
2181a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        "  DO_(_extensions_.ParseField(tag, input, &default_instance(),\n"
2182fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        "                              mutable_unknown_fields()));\n");
2183fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    } else {
2184a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      PrintHandlingOptionalStaticInitializers(
2185a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        descriptor_->file(), printer,
2186a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        // With static initializers.
2187a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        "  DO_(_extensions_.ParseField(tag, input, default_instance_,\n"
2188a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        "                              &unknown_fields_stream));\n",
2189a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        // Without.
2190a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        "  DO_(_extensions_.ParseField(tag, input, &default_instance(),\n"
2191a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        "                              &unknown_fields_stream));\n");
2192fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
2193fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print(
2194fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "  continue;\n"
2195fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "}\n");
2196fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
2197fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
2198fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // We really don't recognize this tag.  Skip it.
2199a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  if (UseUnknownFieldSet(descriptor_->file())) {
2200fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print(
2201fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "DO_(::google::protobuf::internal::WireFormat::SkipField(\n"
2202fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "      input, tag, mutable_unknown_fields()));\n");
2203fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  } else {
2204fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print(
2205a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      "DO_(::google::protobuf::internal::WireFormatLite::SkipField(\n"
2206a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      "    input, tag, &unknown_fields_stream));\n");
2207fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
2208fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
2209fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (descriptor_->field_count() > 0) {
2210fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print("break;\n");
2211fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Outdent();
2212fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print("}\n");    // default:
2213fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Outdent();
2214fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print("}\n");    // switch
2215fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
2216fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
2217fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Outdent();
2218fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Outdent();
2219fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Print(
2220a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    "  }\n"                   // for (;;)
2221a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    "success:\n"
2222a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    "  // @@protoc_insertion_point(parse_success:$full_name$)\n"
2223fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "  return true;\n"
2224a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    "failure:\n"
2225a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    "  // @@protoc_insertion_point(parse_failure:$full_name$)\n"
2226a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    "  return false;\n"
2227fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "#undef DO_\n"
2228a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    "}\n", "full_name", descriptor_->full_name());
2229fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
2230fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
2231fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid MessageGenerator::GenerateSerializeOneField(
2232fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    io::Printer* printer, const FieldDescriptor* field, bool to_array) {
2233fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  PrintFieldComment(printer, field);
2234fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
2235fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (!field->is_repeated()) {
2236fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print(
2237a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      "if (has_$name$()) {\n",
2238a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      "name", FieldName(field));
2239fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Indent();
2240fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
2241fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
2242fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (to_array) {
2243fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    field_generators_.get(field).GenerateSerializeWithCachedSizesToArray(
2244fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        printer);
2245fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  } else {
2246fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    field_generators_.get(field).GenerateSerializeWithCachedSizes(printer);
2247fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
2248fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
2249fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (!field->is_repeated()) {
2250fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Outdent();
2251fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print("}\n");
2252fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
2253fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Print("\n");
2254fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
2255fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
2256fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid MessageGenerator::GenerateSerializeOneExtensionRange(
2257fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    io::Printer* printer, const Descriptor::ExtensionRange* range,
2258fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    bool to_array) {
2259fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  map<string, string> vars;
2260fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  vars["start"] = SimpleItoa(range->start);
2261fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  vars["end"] = SimpleItoa(range->end);
2262fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Print(vars,
2263fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "// Extension range [$start$, $end$)\n");
2264fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (to_array) {
2265fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print(vars,
2266fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "target = _extensions_.SerializeWithCachedSizesToArray(\n"
2267fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "    $start$, $end$, target);\n\n");
2268fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  } else {
2269fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print(vars,
2270fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "_extensions_.SerializeWithCachedSizes(\n"
2271fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "    $start$, $end$, output);\n\n");
2272fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
2273fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
2274fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
2275fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid MessageGenerator::
2276fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleGenerateSerializeWithCachedSizes(io::Printer* printer) {
2277fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (descriptor_->options().message_set_wire_format()) {
2278fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // Special-case MessageSet.
2279fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print(
2280fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "void $classname$::SerializeWithCachedSizes(\n"
2281fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "    ::google::protobuf::io::CodedOutputStream* output) const {\n"
2282fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "  _extensions_.SerializeMessageSetWithCachedSizes(output);\n",
2283fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "classname", classname_);
2284a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    GOOGLE_CHECK(UseUnknownFieldSet(descriptor_->file()));
2285a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    printer->Print(
2286a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      "  ::google::protobuf::internal::WireFormat::SerializeUnknownMessageSetItems(\n"
2287a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      "      unknown_fields(), output);\n");
2288fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print(
2289fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "}\n");
2290fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return;
2291fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
2292fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
2293fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Print(
2294fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "void $classname$::SerializeWithCachedSizes(\n"
2295fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "    ::google::protobuf::io::CodedOutputStream* output) const {\n",
2296fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "classname", classname_);
2297fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Indent();
2298fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
2299a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  printer->Print(
2300a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    "// @@protoc_insertion_point(serialize_start:$full_name$)\n",
2301a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    "full_name", descriptor_->full_name());
2302a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
2303fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  GenerateSerializeWithCachedSizesBody(printer, false);
2304fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
2305a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  printer->Print(
2306a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    "// @@protoc_insertion_point(serialize_end:$full_name$)\n",
2307a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    "full_name", descriptor_->full_name());
2308a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
2309fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Outdent();
2310fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Print(
2311fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "}\n");
2312fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
2313fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
2314fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid MessageGenerator::
2315fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleGenerateSerializeWithCachedSizesToArray(io::Printer* printer) {
2316fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (descriptor_->options().message_set_wire_format()) {
2317fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // Special-case MessageSet.
2318fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print(
2319fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "::google::protobuf::uint8* $classname$::SerializeWithCachedSizesToArray(\n"
2320fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "    ::google::protobuf::uint8* target) const {\n"
2321fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "  target =\n"
2322fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "      _extensions_.SerializeMessageSetWithCachedSizesToArray(target);\n",
2323fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "classname", classname_);
2324a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    GOOGLE_CHECK(UseUnknownFieldSet(descriptor_->file()));
2325a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    printer->Print(
2326a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      "  target = ::google::protobuf::internal::WireFormat::\n"
2327a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      "             SerializeUnknownMessageSetItemsToArray(\n"
2328a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      "               unknown_fields(), target);\n");
2329fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print(
2330fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "  return target;\n"
2331fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "}\n");
2332fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return;
2333fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
2334fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
2335fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Print(
2336fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "::google::protobuf::uint8* $classname$::SerializeWithCachedSizesToArray(\n"
2337fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "    ::google::protobuf::uint8* target) const {\n",
2338fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "classname", classname_);
2339fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Indent();
2340fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
2341a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  printer->Print(
2342a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    "// @@protoc_insertion_point(serialize_to_array_start:$full_name$)\n",
2343a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    "full_name", descriptor_->full_name());
2344a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
2345fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  GenerateSerializeWithCachedSizesBody(printer, true);
2346fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
2347a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  printer->Print(
2348a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    "// @@protoc_insertion_point(serialize_to_array_end:$full_name$)\n",
2349a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    "full_name", descriptor_->full_name());
2350a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
2351fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Outdent();
2352fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Print(
2353fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "  return target;\n"
2354fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "}\n");
2355fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
2356fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
2357fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid MessageGenerator::
2358fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleGenerateSerializeWithCachedSizesBody(io::Printer* printer, bool to_array) {
2359fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  scoped_array<const FieldDescriptor*> ordered_fields(
2360a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      SortFieldsByNumber(descriptor_));
2361fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
2362fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  vector<const Descriptor::ExtensionRange*> sorted_extensions;
2363fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  for (int i = 0; i < descriptor_->extension_range_count(); ++i) {
2364fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    sorted_extensions.push_back(descriptor_->extension_range(i));
2365fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
2366fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  sort(sorted_extensions.begin(), sorted_extensions.end(),
2367fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville       ExtensionRangeSorter());
2368fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
2369fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // Merge the fields and the extension ranges, both sorted by field number.
2370fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  int i, j;
2371fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  for (i = 0, j = 0;
2372fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville       i < descriptor_->field_count() || j < sorted_extensions.size();
2373fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville       ) {
2374fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    if (i == descriptor_->field_count()) {
2375fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      GenerateSerializeOneExtensionRange(printer,
2376fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville                                         sorted_extensions[j++],
2377fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville                                         to_array);
2378fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    } else if (j == sorted_extensions.size()) {
2379fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      GenerateSerializeOneField(printer, ordered_fields[i++], to_array);
2380fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    } else if (ordered_fields[i]->number() < sorted_extensions[j]->start) {
2381fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      GenerateSerializeOneField(printer, ordered_fields[i++], to_array);
2382fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    } else {
2383fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      GenerateSerializeOneExtensionRange(printer,
2384fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville                                         sorted_extensions[j++],
2385fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville                                         to_array);
2386fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
2387fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
2388fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
2389a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  if (UseUnknownFieldSet(descriptor_->file())) {
2390fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print("if (!unknown_fields().empty()) {\n");
2391fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Indent();
2392fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    if (to_array) {
2393fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      printer->Print(
2394fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        "target = "
2395fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville            "::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(\n"
2396fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        "    unknown_fields(), target);\n");
2397fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    } else {
2398fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      printer->Print(
2399fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        "::google::protobuf::internal::WireFormat::SerializeUnknownFields(\n"
2400fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        "    unknown_fields(), output);\n");
2401fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
2402fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Outdent();
2403fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
2404fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print(
2405fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "}\n");
2406a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  } else {
2407a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    printer->Print(
2408a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      "output->WriteRaw(unknown_fields().data(),\n"
2409a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      "                 unknown_fields().size());\n");
2410fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
2411fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
2412fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
2413fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid MessageGenerator::
2414fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleGenerateByteSize(io::Printer* printer) {
2415fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (descriptor_->options().message_set_wire_format()) {
2416fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // Special-case MessageSet.
2417fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print(
2418fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "int $classname$::ByteSize() const {\n"
2419fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "  int total_size = _extensions_.MessageSetByteSize();\n",
2420fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "classname", classname_);
2421a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    GOOGLE_CHECK(UseUnknownFieldSet(descriptor_->file()));
2422a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    printer->Print(
2423a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      "  total_size += ::google::protobuf::internal::WireFormat::\n"
2424a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      "      ComputeUnknownMessageSetItemsSize(unknown_fields());\n");
2425fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print(
2426d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville      "  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();\n"
2427fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "  _cached_size_ = total_size;\n"
2428d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville      "  GOOGLE_SAFE_CONCURRENT_WRITES_END();\n"
2429fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "  return total_size;\n"
2430fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "}\n");
2431fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return;
2432fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
2433fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
2434fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Print(
2435fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "int $classname$::ByteSize() const {\n",
2436fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "classname", classname_);
2437fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Indent();
2438fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Print(
2439fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "int total_size = 0;\n"
2440fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "\n");
2441fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
2442fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  int last_index = -1;
2443fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
2444fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  for (int i = 0; i < descriptor_->field_count(); i++) {
2445fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    const FieldDescriptor* field = descriptor_->field(i);
2446fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
2447a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    if (!field->is_repeated() && !field->containing_oneof()) {
2448fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      // See above in GenerateClear for an explanation of this.
2449fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      // TODO(kenton):  Share code?  Unclear how to do so without
2450fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      //   over-engineering.
2451fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      if ((i / 8) != (last_index / 8) ||
2452fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville          last_index < 0) {
2453fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        if (last_index >= 0) {
2454fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville          printer->Outdent();
2455fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville          printer->Print("}\n");
2456fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        }
2457fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        printer->Print(
2458fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville          "if (_has_bits_[$index$ / 32] & (0xffu << ($index$ % 32))) {\n",
2459fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville          "index", SimpleItoa(field->index()));
2460fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        printer->Indent();
2461fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      }
2462fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      last_index = i;
2463fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
2464fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      PrintFieldComment(printer, field);
2465fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
2466fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      printer->Print(
2467fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        "if (has_$name$()) {\n",
2468fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        "name", FieldName(field));
2469fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      printer->Indent();
2470fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
2471fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      field_generators_.get(field).GenerateByteSize(printer);
2472fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
2473fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      printer->Outdent();
2474fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      printer->Print(
2475fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        "}\n"
2476fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        "\n");
2477fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
2478fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
2479fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
2480fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (last_index >= 0) {
2481fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Outdent();
2482fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print("}\n");
2483fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
2484fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
2485fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // Repeated fields don't use _has_bits_ so we count them in a separate
2486fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // pass.
2487fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  for (int i = 0; i < descriptor_->field_count(); i++) {
2488fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    const FieldDescriptor* field = descriptor_->field(i);
2489fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
2490fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    if (field->is_repeated()) {
2491fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      PrintFieldComment(printer, field);
2492fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      field_generators_.get(field).GenerateByteSize(printer);
2493fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      printer->Print("\n");
2494fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
2495fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
2496fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
2497a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  // Fields inside a oneof don't use _has_bits_ so we count them in a separate
2498a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  // pass.
2499a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
2500a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    printer->Print(
2501a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        "switch ($oneofname$_case()) {\n",
2502a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        "oneofname", descriptor_->oneof_decl(i)->name());
2503a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    printer->Indent();
2504a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    for (int j = 0; j < descriptor_->oneof_decl(i)->field_count(); j++) {
2505a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      const FieldDescriptor* field = descriptor_->oneof_decl(i)->field(j);
2506a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      PrintFieldComment(printer, field);
2507a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      printer->Print(
2508a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson          "case k$field_name$: {\n",
2509a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson          "field_name", UnderscoresToCamelCase(field->name(), true));
2510a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      printer->Indent();
2511a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      field_generators_.get(field).GenerateByteSize(printer);
2512a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      printer->Print(
2513a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson          "break;\n");
2514a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      printer->Outdent();
2515a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      printer->Print(
2516a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson          "}\n");
2517a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    }
2518a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    printer->Print(
2519a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        "case $cap_oneof_name$_NOT_SET: {\n"
2520a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        "  break;\n"
2521a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        "}\n",
2522a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        "cap_oneof_name",
2523a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        ToUpper(descriptor_->oneof_decl(i)->name()));
2524a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    printer->Outdent();
2525a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    printer->Print(
2526a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        "}\n");
2527a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  }
2528a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
2529fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (descriptor_->extension_range_count() > 0) {
2530fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print(
2531fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "total_size += _extensions_.ByteSize();\n"
2532fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "\n");
2533fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
2534fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
2535a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  if (UseUnknownFieldSet(descriptor_->file())) {
2536fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print("if (!unknown_fields().empty()) {\n");
2537fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Indent();
2538fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print(
2539fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "total_size +=\n"
2540fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "  ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(\n"
2541fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "    unknown_fields());\n");
2542fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Outdent();
2543fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print("}\n");
2544a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  } else {
2545a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    printer->Print(
2546a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      "total_size += unknown_fields().size();\n"
2547a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      "\n");
2548fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
2549fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
2550fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // We update _cached_size_ even though this is a const method.  In theory,
2551fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // this is not thread-compatible, because concurrent writes have undefined
2552fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // results.  In practice, since any concurrent writes will be writing the
2553fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // exact same value, it works on all common processors.  In a future version
2554fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // of C++, _cached_size_ should be made into an atomic<int>.
2555fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Print(
2556d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    "GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();\n"
2557fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "_cached_size_ = total_size;\n"
2558d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    "GOOGLE_SAFE_CONCURRENT_WRITES_END();\n"
2559fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "return total_size;\n");
2560fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
2561fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Outdent();
2562fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Print("}\n");
2563fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
2564fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
2565fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid MessageGenerator::
2566fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleGenerateIsInitialized(io::Printer* printer) {
2567fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Print(
2568fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "bool $classname$::IsInitialized() const {\n",
2569fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "classname", classname_);
2570fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Indent();
2571fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
2572fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // Check that all required fields in this message are set.  We can do this
2573fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // most efficiently by checking 32 "has bits" at a time.
2574fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  int has_bits_array_size = (descriptor_->field_count() + 31) / 32;
2575fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  for (int i = 0; i < has_bits_array_size; i++) {
2576fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    uint32 mask = 0;
2577fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    for (int bit = 0; bit < 32; bit++) {
2578fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      int index = i * 32 + bit;
2579fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      if (index >= descriptor_->field_count()) break;
2580fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      const FieldDescriptor* field = descriptor_->field(index);
2581fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
2582fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      if (field->is_required()) {
2583fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        mask |= 1 << bit;
2584fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      }
2585fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
2586fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
2587fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    if (mask != 0) {
2588fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      char buffer[kFastToBufferSize];
2589fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      printer->Print(
2590fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        "if ((_has_bits_[$i$] & 0x$mask$) != 0x$mask$) return false;\n",
2591fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        "i", SimpleItoa(i),
2592fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        "mask", FastHex32ToBuffer(mask, buffer));
2593fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
2594fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
2595fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
2596fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // Now check that all embedded messages are initialized.
2597fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Print("\n");
2598fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  for (int i = 0; i < descriptor_->field_count(); i++) {
2599fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    const FieldDescriptor* field = descriptor_->field(i);
2600fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE &&
2601a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        !ShouldIgnoreRequiredFieldCheck(field) &&
2602fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        HasRequiredFields(field->message_type())) {
2603fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      if (field->is_repeated()) {
2604fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        printer->Print(
2605a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson          "if (!::google::protobuf::internal::AllAreInitialized(this->$name$()))"
2606a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson          " return false;\n",
2607fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville          "name", FieldName(field));
2608fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      } else {
2609a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        if (field->options().weak()) {
2610a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson          // For weak fields, use the data member (google::protobuf::Message*) instead
2611a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson          // of the getter to avoid a link dependency on the weak message type
2612a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson          // which is only forward declared.
2613a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson          printer->Print(
2614a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson            "if (has_$name$()) {\n"
2615a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson            "  if (!this->$name$_->IsInitialized()) return false;\n"
2616a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson            "}\n",
2617a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson            "name", FieldName(field));
2618a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        } else {
2619a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson          printer->Print(
2620a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson            "if (has_$name$()) {\n"
2621a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson            "  if (!this->$name$().IsInitialized()) return false;\n"
2622a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson            "}\n",
2623a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson            "name", FieldName(field));
2624a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        }
2625fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      }
2626fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
2627fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
2628fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
2629fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (descriptor_->extension_range_count() > 0) {
2630fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print(
2631fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "\n"
2632fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "if (!_extensions_.IsInitialized()) return false;");
2633fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
2634fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
2635fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Outdent();
2636fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Print(
2637fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "  return true;\n"
2638fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "}\n");
2639fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
2640fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
2641d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville
2642fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}  // namespace cpp
2643fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}  // namespace compiler
2644fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}  // namespace protobuf
2645fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}  // namespace google
2646