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