15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Protocol Buffers - Google's data interchange format 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright 2008 Google Inc. All rights reserved. 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// http://code.google.com/p/protobuf/ 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Redistribution and use in source and binary forms, with or without 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// modification, are permitted provided that the following conditions are 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// met: 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// * Redistributions of source code must retain the above copyright 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// notice, this list of conditions and the following disclaimer. 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// * Redistributions in binary form must reproduce the above 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// copyright notice, this list of conditions and the following disclaimer 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// in the documentation and/or other materials provided with the 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// distribution. 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// * Neither the name of Google Inc. nor the names of its 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// contributors may be used to endorse or promote products derived from 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// this software without specific prior written permission. 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Author: kenton@google.com (Kenton Varda) 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Based on original Protocol Buffers design by 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Sanjay Ghemawat, Jeff Dean, and others. 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <algorithm> 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <google/protobuf/stubs/hash.h> 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <map> 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <utility> 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <vector> 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <google/protobuf/compiler/cpp/cpp_message.h> 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <google/protobuf/compiler/cpp/cpp_field.h> 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <google/protobuf/compiler/cpp/cpp_enum.h> 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <google/protobuf/compiler/cpp/cpp_extension.h> 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <google/protobuf/compiler/cpp/cpp_helpers.h> 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <google/protobuf/stubs/strutil.h> 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <google/protobuf/io/printer.h> 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <google/protobuf/io/coded_stream.h> 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <google/protobuf/wire_format.h> 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <google/protobuf/descriptor.pb.h> 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 513d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace google { 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace protobuf { 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace compiler { 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace cpp { 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using internal::WireFormat; 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using internal::WireFormatLite; 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PrintFieldComment(io::Printer* printer, const FieldDescriptor* field) { 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Print the field's proto-syntax definition as a comment. We don't want to 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // print group bodies so we cut off after the first line. 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string def = field->DebugString(); 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print("// $def$\n", 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "def", def.substr(0, def.find_first_of('\n'))); 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct FieldOrderingByNumber { 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline bool operator()(const FieldDescriptor* a, 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const FieldDescriptor* b) const { 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return a->number() < b->number(); 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char* kWireTypeNames[] = { 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "VARINT", 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "FIXED64", 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "LENGTH_DELIMITED", 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "START_GROUP", 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "END_GROUP", 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "FIXED32", 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Sort the fields of the given Descriptor by number into a new[]'d array 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// and return it. 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const FieldDescriptor** SortFieldsByNumber(const Descriptor* descriptor) { 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const FieldDescriptor** fields = 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new const FieldDescriptor*[descriptor->field_count()]; 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < descriptor->field_count(); i++) { 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fields[i] = descriptor->field(i); 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sort(fields, fields + descriptor->field_count(), 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FieldOrderingByNumber()); 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return fields; 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Functor for sorting extension ranges by their "start" field number. 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct ExtensionRangeSorter { 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool operator()(const Descriptor::ExtensionRange* left, 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Descriptor::ExtensionRange* right) const { 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return left->start < right->start; 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1073d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch// Returns true if the "required" restriction check should be ignored for the 1083d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch// given field. 1093d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdochinline static bool ShouldIgnoreRequiredFieldCheck( 1103d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch const FieldDescriptor* field) { 1113d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch return false; 1123d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch} 1133d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Returns true if the message type has any required fields. If it doesn't, 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// we can optimize out calls to its IsInitialized() method. 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// already_seen is used to avoid checking the same type multiple times 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// (and also to protect against recursion). 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static bool HasRequiredFields( 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Descriptor* type, 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hash_set<const Descriptor*>* already_seen) { 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (already_seen->count(type) > 0) { 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Since the first occurrence of a required field causes the whole 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // function to return true, we can assume that if the type is already 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // in the cache it didn't have any required fields. 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) already_seen->insert(type); 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If the type has extensions, an extension with message type could contain 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // required fields, so we have to be conservative and assume such an 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // extension exists. 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (type->extension_range_count() > 0) return true; 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < type->field_count(); i++) { 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const FieldDescriptor* field = type->field(i); 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (field->is_required()) { 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1403d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE && 1413d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch !ShouldIgnoreRequiredFieldCheck(field)) { 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (HasRequiredFields(field->message_type(), already_seen)) { 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static bool HasRequiredFields(const Descriptor* type) { 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hash_set<const Descriptor*> already_seen; 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return HasRequiredFields(type, &already_seen); 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This returns an estimate of the compiler's alignment for the field. This 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// can't guarantee to be correct because the generated code could be compiled on 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// different systems with different alignment rules. The estimates below assume 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 64-bit pointers. 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int EstimateAlignmentSize(const FieldDescriptor* field) { 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (field == NULL) return 0; 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (field->is_repeated()) return 8; 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (field->cpp_type()) { 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case FieldDescriptor::CPPTYPE_BOOL: 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 1; 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case FieldDescriptor::CPPTYPE_INT32: 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case FieldDescriptor::CPPTYPE_UINT32: 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case FieldDescriptor::CPPTYPE_ENUM: 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case FieldDescriptor::CPPTYPE_FLOAT: 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 4; 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case FieldDescriptor::CPPTYPE_INT64: 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case FieldDescriptor::CPPTYPE_UINT64: 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case FieldDescriptor::CPPTYPE_DOUBLE: 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case FieldDescriptor::CPPTYPE_STRING: 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case FieldDescriptor::CPPTYPE_MESSAGE: 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 8; 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GOOGLE_LOG(FATAL) << "Can't get here."; 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return -1; // Make compiler happy. 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// FieldGroup is just a helper for OptimizePadding below. It holds a vector of 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// fields that are grouped together because they have compatible alignment, and 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// a preferred location in the final field ordering. 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class FieldGroup { 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FieldGroup() 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : preferred_location_(0) {} 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // A group with a single field. 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FieldGroup(float preferred_location, const FieldDescriptor* field) 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : preferred_location_(preferred_location), 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fields_(1, field) {} 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Append the fields in 'other' to this group. 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void Append(const FieldGroup& other) { 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (other.fields_.empty()) { 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Preferred location is the average among all the fields, so we weight by 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the number of fields on each FieldGroup object. 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) preferred_location_ = 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (preferred_location_ * fields_.size() + 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (other.preferred_location_ * other.fields_.size())) / 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (fields_.size() + other.fields_.size()); 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fields_.insert(fields_.end(), other.fields_.begin(), other.fields_.end()); 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void SetPreferredLocation(float location) { preferred_location_ = location; } 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const vector<const FieldDescriptor*>& fields() const { return fields_; } 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // FieldGroup objects sort by their preferred location. 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool operator<(const FieldGroup& other) const { 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return preferred_location_ < other.preferred_location_; 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // "preferred_location_" is an estimate of where this group should go in the 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // final list of fields. We compute this by taking the average index of each 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // field in this group in the original ordering of fields. This is very 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // approximate, but should put this group close to where its member fields 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // originally went. 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) float preferred_location_; 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) vector<const FieldDescriptor*> fields_; 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We rely on the default copy constructor and operator= so this type can be 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // used in a vector. 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Reorder 'fields' so that if the fields are output into a c++ class in the new 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// order, the alignment padding is minimized. We try to do this while keeping 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// each field as close as possible to its original position so that we don't 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// reduce cache locality much for function that access each field in order. 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void OptimizePadding(vector<const FieldDescriptor*>* fields) { 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // First divide fields into those that align to 1 byte, 4 bytes or 8 bytes. 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) vector<FieldGroup> aligned_to_1, aligned_to_4, aligned_to_8; 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < fields->size(); ++i) { 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (EstimateAlignmentSize((*fields)[i])) { 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 1: aligned_to_1.push_back(FieldGroup(i, (*fields)[i])); break; 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 4: aligned_to_4.push_back(FieldGroup(i, (*fields)[i])); break; 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 8: aligned_to_8.push_back(FieldGroup(i, (*fields)[i])); break; 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GOOGLE_LOG(FATAL) << "Unknown alignment size."; 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Now group fields aligned to 1 byte into sets of 4, and treat those like a 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // single field aligned to 4 bytes. 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < aligned_to_1.size(); i += 4) { 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FieldGroup field_group; 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int j = i; j < aligned_to_1.size() && j < i + 4; ++j) { 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) field_group.Append(aligned_to_1[j]); 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) aligned_to_4.push_back(field_group); 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Sort by preferred location to keep fields as close to their original 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // location as possible. 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sort(aligned_to_4.begin(), aligned_to_4.end()); 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Now group fields aligned to 4 bytes (or the 4-field groups created above) 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // into pairs, and treat those like a single field aligned to 8 bytes. 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < aligned_to_4.size(); i += 2) { 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FieldGroup field_group; 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int j = i; j < aligned_to_4.size() && j < i + 2; ++j) { 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) field_group.Append(aligned_to_4[j]); 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (i == aligned_to_4.size() - 1) { 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Move incomplete 4-byte block to the end. 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) field_group.SetPreferredLocation(fields->size() + 1); 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) aligned_to_8.push_back(field_group); 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Sort by preferred location to keep fields as close to their original 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // location as possible. 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sort(aligned_to_8.begin(), aligned_to_8.end()); 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Now pull out all the FieldDescriptors in order. 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fields->clear(); 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < aligned_to_8.size(); ++i) { 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fields->insert(fields->end(), 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) aligned_to_8[i].fields().begin(), 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) aligned_to_8[i].fields().end()); 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// =================================================================== 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)MessageGenerator::MessageGenerator(const Descriptor* descriptor, 2923d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch const Options& options) 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : descriptor_(descriptor), 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) classname_(ClassName(descriptor, false)), 2953d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch options_(options), 2963d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch field_generators_(descriptor, options), 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nested_generators_(new scoped_ptr<MessageGenerator>[ 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) descriptor->nested_type_count()]), 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) enum_generators_(new scoped_ptr<EnumGenerator>[ 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) descriptor->enum_type_count()]), 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extension_generators_(new scoped_ptr<ExtensionGenerator>[ 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) descriptor->extension_count()]) { 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < descriptor->nested_type_count(); i++) { 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nested_generators_[i].reset( 3063d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch new MessageGenerator(descriptor->nested_type(i), options)); 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < descriptor->enum_type_count(); i++) { 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) enum_generators_[i].reset( 3113d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch new EnumGenerator(descriptor->enum_type(i), options)); 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < descriptor->extension_count(); i++) { 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extension_generators_[i].reset( 3163d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch new ExtensionGenerator(descriptor->extension(i), options)); 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)MessageGenerator::~MessageGenerator() {} 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MessageGenerator:: 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GenerateForwardDeclaration(io::Printer* printer) { 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print("class $classname$;\n", 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "classname", classname_); 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < descriptor_->nested_type_count(); i++) { 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nested_generators_[i]->GenerateForwardDeclaration(printer); 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MessageGenerator:: 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GenerateEnumDefinitions(io::Printer* printer) { 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < descriptor_->nested_type_count(); i++) { 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nested_generators_[i]->GenerateEnumDefinitions(printer); 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < descriptor_->enum_type_count(); i++) { 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) enum_generators_[i]->GenerateDefinition(printer); 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MessageGenerator:: 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GenerateGetEnumDescriptorSpecializations(io::Printer* printer) { 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < descriptor_->nested_type_count(); i++) { 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nested_generators_[i]->GenerateGetEnumDescriptorSpecializations(printer); 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < descriptor_->enum_type_count(); i++) { 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) enum_generators_[i]->GenerateGetEnumDescriptorSpecializations(printer); 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MessageGenerator:: 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GenerateFieldAccessorDeclarations(io::Printer* printer) { 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < descriptor_->field_count(); i++) { 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const FieldDescriptor* field = descriptor_->field(i); 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PrintFieldComment(printer, field); 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) map<string, string> vars; 3613d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch SetCommonFieldVariables(field, &vars, options_); 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) vars["constant_name"] = FieldConstantName(field); 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (field->is_repeated()) { 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print(vars, "inline int $name$_size() const$deprecation$;\n"); 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print(vars, "inline bool has_$name$() const$deprecation$;\n"); 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print(vars, "inline void clear_$name$()$deprecation$;\n"); 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print(vars, "static const int $constant_name$ = $number$;\n"); 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Generate type-specific accessor declarations. 3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) field_generators_.get(field).GenerateAccessorDeclarations(printer); 3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print("\n"); 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (descriptor_->extension_range_count() > 0) { 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Generate accessors for extensions. We just call a macro located in 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // extension_set.h since the accessors about 80 lines of static code. 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print( 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "GOOGLE_PROTOBUF_EXTENSION_ACCESSORS($classname$)\n", 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "classname", classname_); 3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MessageGenerator:: 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GenerateFieldAccessorDefinitions(io::Printer* printer) { 3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print("// $classname$\n\n", "classname", classname_); 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < descriptor_->field_count(); i++) { 3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const FieldDescriptor* field = descriptor_->field(i); 3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PrintFieldComment(printer, field); 3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) map<string, string> vars; 3983d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch SetCommonFieldVariables(field, &vars, options_); 3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Generate has_$name$() or $name$_size(). 4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (field->is_repeated()) { 4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print(vars, 4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "inline int $classname$::$name$_size() const {\n" 4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " return $name$_.size();\n" 4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "}\n"); 4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Singular field. 4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char buffer[kFastToBufferSize]; 4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) vars["has_array_index"] = SimpleItoa(field->index() / 32); 4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) vars["has_mask"] = FastHex32ToBuffer(1u << (field->index() % 32), buffer); 4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print(vars, 4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "inline bool $classname$::has_$name$() const {\n" 4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " return (_has_bits_[$has_array_index$] & 0x$has_mask$u) != 0;\n" 4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "}\n" 4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "inline void $classname$::set_has_$name$() {\n" 4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " _has_bits_[$has_array_index$] |= 0x$has_mask$u;\n" 4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "}\n" 4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "inline void $classname$::clear_has_$name$() {\n" 4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " _has_bits_[$has_array_index$] &= ~0x$has_mask$u;\n" 4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "}\n" 4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ); 4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Generate clear_$name$() 4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print(vars, 4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "inline void $classname$::clear_$name$() {\n"); 4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Indent(); 4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) field_generators_.get(field).GenerateClearingCode(printer); 4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Outdent(); 4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!field->is_repeated()) { 4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print(vars, 4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " clear_has_$name$();\n"); 4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print("}\n"); 4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Generate type-specific accessors. 4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) field_generators_.get(field).GenerateInlineAccessorDefinitions(printer); 4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print("\n"); 4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MessageGenerator:: 4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GenerateClassDefinition(io::Printer* printer) { 4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < descriptor_->nested_type_count(); i++) { 4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nested_generators_[i]->GenerateClassDefinition(printer); 4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print("\n"); 4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print(kThinSeparator); 4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print("\n"); 4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) map<string, string> vars; 4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) vars["classname"] = classname_; 4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) vars["field_count"] = SimpleItoa(descriptor_->field_count()); 4583d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch if (options_.dllexport_decl.empty()) { 4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) vars["dllexport"] = ""; 4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 4613d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch vars["dllexport"] = options_.dllexport_decl + " "; 4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) vars["superclass"] = SuperClassName(descriptor_); 4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print(vars, 4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "class $dllexport$$classname$ : public $superclass$ {\n" 4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " public:\n"); 4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Indent(); 4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print(vars, 4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "$classname$();\n" 4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "virtual ~$classname$();\n" 4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "\n" 4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "$classname$(const $classname$& from);\n" 4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "\n" 4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "inline $classname$& operator=(const $classname$& from) {\n" 4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " CopyFrom(from);\n" 4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " return *this;\n" 4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "}\n" 4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "\n"); 4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (HasUnknownFields(descriptor_->file())) { 4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print( 4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {\n" 4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " return _unknown_fields_;\n" 4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "}\n" 4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "\n" 4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {\n" 4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " return &_unknown_fields_;\n" 4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "}\n" 4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "\n"); 4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Only generate this member if it's not disabled. 4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (HasDescriptorMethods(descriptor_->file()) && 4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) !descriptor_->options().no_standard_descriptor_accessor()) { 4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print(vars, 4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "static const ::google::protobuf::Descriptor* descriptor();\n"); 4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print(vars, 5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "static const $classname$& default_instance();\n" 5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "\n"); 5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!StaticInitializersForced(descriptor_->file())) { 5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print(vars, 5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER\n" 5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "// Returns the internal default instance pointer. This function can\n" 5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "// return NULL thus should not be used by the user. This is intended\n" 5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "// for Protobuf internal code. Please use default_instance() declared\n" 5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "// above instead.\n" 5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "static inline const $classname$* internal_default_instance() {\n" 5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " return default_instance_;\n" 5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "}\n" 5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "#endif\n" 5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "\n"); 5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5193d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch 5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print(vars, 5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "void Swap($classname$* other);\n" 5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "\n" 5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "// implements Message ----------------------------------------------\n" 5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "\n" 5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "$classname$* New() const;\n"); 5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (HasGeneratedMethods(descriptor_->file())) { 5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (HasDescriptorMethods(descriptor_->file())) { 5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print(vars, 5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "void CopyFrom(const ::google::protobuf::Message& from);\n" 5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "void MergeFrom(const ::google::protobuf::Message& from);\n"); 5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print(vars, 5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "void CheckTypeAndMergeFrom(const ::google::protobuf::MessageLite& from);\n"); 5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print(vars, 5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "void CopyFrom(const $classname$& from);\n" 5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "void MergeFrom(const $classname$& from);\n" 5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "void Clear();\n" 5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "bool IsInitialized() const;\n" 5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "\n" 5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "int ByteSize() const;\n" 5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "bool MergePartialFromCodedStream(\n" 5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " ::google::protobuf::io::CodedInputStream* input);\n" 5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "void SerializeWithCachedSizes(\n" 5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " ::google::protobuf::io::CodedOutputStream* output) const;\n"); 5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (HasFastArraySerialization(descriptor_->file())) { 5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print( 5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;\n"); 5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print(vars, 5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "int GetCachedSize() const { return _cached_size_; }\n" 5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "private:\n" 5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "void SharedCtor();\n" 5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "void SharedDtor();\n" 5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "void SetCachedSize(int size) const;\n" 5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "public:\n" 5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "\n"); 5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (HasDescriptorMethods(descriptor_->file())) { 5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print( 5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "::google::protobuf::Metadata GetMetadata() const;\n" 5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "\n"); 5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print( 5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "::std::string GetTypeName() const;\n" 5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "\n"); 5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print( 5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "// nested types ----------------------------------------------------\n" 5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "\n"); 5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Import all nested message classes into this class's scope with typedefs. 5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < descriptor_->nested_type_count(); i++) { 5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Descriptor* nested_type = descriptor_->nested_type(i); 5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print("typedef $nested_full_name$ $nested_name$;\n", 5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "nested_name", nested_type->name(), 5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "nested_full_name", ClassName(nested_type, false)); 5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (descriptor_->nested_type_count() > 0) { 5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print("\n"); 5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Import all nested enums and their values into this class's scope with 5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // typedefs and constants. 5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < descriptor_->enum_type_count(); i++) { 5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) enum_generators_[i]->GenerateSymbolImports(printer); 5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print("\n"); 5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print( 5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "// accessors -------------------------------------------------------\n" 5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "\n"); 5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Generate accessor methods for all fields. 6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GenerateFieldAccessorDeclarations(printer); 6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Declare extension identifiers. 6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < descriptor_->extension_count(); i++) { 6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extension_generators_[i]->GenerateDeclaration(printer); 6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print( 6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "// @@protoc_insertion_point(class_scope:$full_name$)\n", 6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "full_name", descriptor_->full_name()); 6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Generate private members. 6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Outdent(); 6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print(" private:\n"); 6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Indent(); 6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6183d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch 6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < descriptor_->field_count(); i++) { 6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!descriptor_->field(i)->is_repeated()) { 6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print( 6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "inline void set_has_$name$();\n", 6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "name", FieldName(descriptor_->field(i))); 6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print( 6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "inline void clear_has_$name$();\n", 6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "name", FieldName(descriptor_->field(i))); 6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print("\n"); 6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // To minimize padding, data members are divided into three sections: 6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // (1) members assumed to align to 8 bytes 6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // (2) members corresponding to message fields, re-ordered to optimize 6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // alignment. 6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // (3) members assumed to align to 4 bytes. 6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Members assumed to align to 8 bytes: 6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (descriptor_->extension_range_count() > 0) { 6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print( 6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "::google::protobuf::internal::ExtensionSet _extensions_;\n" 6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "\n"); 6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (HasUnknownFields(descriptor_->file())) { 6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print( 6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "::google::protobuf::UnknownFieldSet _unknown_fields_;\n" 6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "\n"); 6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Field members: 6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) vector<const FieldDescriptor*> fields; 6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < descriptor_->field_count(); i++) { 6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fields.push_back(descriptor_->field(i)); 6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OptimizePadding(&fields); 6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < fields.size(); ++i) { 6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) field_generators_.get(fields[i]).GeneratePrivateMembers(printer); 6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Members assumed to align to 4 bytes: 6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(kenton): Make _cached_size_ an atomic<int> when C++ supports it. 6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print( 6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "\n" 6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "mutable int _cached_size_;\n"); 6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Generate _has_bits_. 6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (descriptor_->field_count() > 0) { 6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print(vars, 6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "::google::protobuf::uint32 _has_bits_[($field_count$ + 31) / 32];\n" 6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "\n"); 6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Zero-size arrays aren't technically allowed, and MSVC in particular 6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // doesn't like them. We still need to declare these arrays to make 6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // other code compile. Since this is an uncommon case, we'll just declare 6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // them with size 1 and waste some space. Oh well. 6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print( 6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "::google::protobuf::uint32 _has_bits_[1];\n" 6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "\n"); 6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Declare AddDescriptors(), BuildDescriptors(), and ShutdownFile() as 6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // friends so that they can access private static variables like 6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // default_instance_ and reflection_. 6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PrintHandlingOptionalStaticInitializers( 6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) descriptor_->file(), printer, 6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // With static initializers. 6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "friend void $dllexport_decl$ $adddescriptorsname$();\n", 6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Without. 6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "friend void $dllexport_decl$ $adddescriptorsname$_impl();\n", 6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Vars. 6943d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch "dllexport_decl", options_.dllexport_decl, 6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "adddescriptorsname", 6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GlobalAddDescriptorsName(descriptor_->file()->name())); 6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print( 6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "friend void $assigndescriptorsname$();\n" 7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "friend void $shutdownfilename$();\n" 7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "\n", 7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "assigndescriptorsname", 7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GlobalAssignDescriptorsName(descriptor_->file()->name()), 7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "shutdownfilename", GlobalShutdownFileName(descriptor_->file()->name())); 7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print( 7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "void InitAsDefaultInstance();\n" 7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "static $classname$* default_instance_;\n", 7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "classname", classname_); 7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Outdent(); 7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print(vars, "};"); 7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MessageGenerator:: 7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GenerateInlineMethods(io::Printer* printer) { 7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < descriptor_->nested_type_count(); i++) { 7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nested_generators_[i]->GenerateInlineMethods(printer); 7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print(kThinSeparator); 7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print("\n"); 7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GenerateFieldAccessorDefinitions(printer); 7245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MessageGenerator:: 7275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GenerateDescriptorDeclarations(io::Printer* printer) { 7285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print( 7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "const ::google::protobuf::Descriptor* $name$_descriptor_ = NULL;\n" 7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "const ::google::protobuf::internal::GeneratedMessageReflection*\n" 7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " $name$_reflection_ = NULL;\n", 7325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "name", classname_); 7335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < descriptor_->nested_type_count(); i++) { 7355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nested_generators_[i]->GenerateDescriptorDeclarations(printer); 7365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < descriptor_->enum_type_count(); i++) { 7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print( 7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "const ::google::protobuf::EnumDescriptor* $name$_descriptor_ = NULL;\n", 7415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "name", ClassName(descriptor_->enum_type(i), false)); 7425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MessageGenerator:: 7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GenerateDescriptorInitializer(io::Printer* printer, int index) { 7475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(kenton): Passing the index to this method is redundant; just use 7485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // descriptor_->index() instead. 7495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) map<string, string> vars; 7505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) vars["classname"] = classname_; 7515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) vars["index"] = SimpleItoa(index); 7525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Obtain the descriptor from the parent's descriptor. 7545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (descriptor_->containing_type() == NULL) { 7555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print(vars, 7565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "$classname$_descriptor_ = file->message_type($index$);\n"); 7575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 7585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) vars["parent"] = ClassName(descriptor_->containing_type(), false); 7595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print(vars, 7605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "$classname$_descriptor_ = " 7615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "$parent$_descriptor_->nested_type($index$);\n"); 7625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Generate the offsets. 7655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GenerateOffsets(printer); 7665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Construct the reflection object. 7685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print(vars, 7695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "$classname$_reflection_ =\n" 7705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " new ::google::protobuf::internal::GeneratedMessageReflection(\n" 7715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " $classname$_descriptor_,\n" 7725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " $classname$::default_instance_,\n" 7735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " $classname$_offsets_,\n" 7745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET($classname$, _has_bits_[0]),\n" 7755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(" 7765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "$classname$, _unknown_fields_),\n"); 7775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (descriptor_->extension_range_count() > 0) { 7785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print(vars, 7795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(" 7805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "$classname$, _extensions_),\n"); 7815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 7825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // No extensions. 7835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print(vars, 7845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " -1,\n"); 7855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7863d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch printer->Print( 7873d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch " ::google::protobuf::DescriptorPool::generated_pool(),\n"); 7883d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch printer->Print(vars, 7893d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch " ::google::protobuf::MessageFactory::generated_factory(),\n"); 7905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print(vars, 7915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " sizeof($classname$));\n"); 7925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Handle nested types. 7945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < descriptor_->nested_type_count(); i++) { 7955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nested_generators_[i]->GenerateDescriptorInitializer(printer, i); 7965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < descriptor_->enum_type_count(); i++) { 7995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) enum_generators_[i]->GenerateDescriptorInitializer(printer, i); 8005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MessageGenerator:: 8045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GenerateTypeRegistrations(io::Printer* printer) { 8055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Register this message type with the message factory. 8065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print( 8075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(\n" 8085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " $classname$_descriptor_, &$classname$::default_instance());\n", 8095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "classname", classname_); 8105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Handle nested types. 8125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < descriptor_->nested_type_count(); i++) { 8135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nested_generators_[i]->GenerateTypeRegistrations(printer); 8145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MessageGenerator:: 8185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GenerateDefaultInstanceAllocator(io::Printer* printer) { 8193d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch // Construct the default instances of all fields, as they will be used 8203d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch // when creating the default instance of the entire message. 8213d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch for (int i = 0; i < descriptor_->field_count(); i++) { 8223d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch field_generators_.get(descriptor_->field(i)) 8233d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch .GenerateDefaultInstanceAllocator(printer); 8243d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch } 8253d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch 8265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Construct the default instance. We can't call InitAsDefaultInstance() yet 8275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // because we need to make sure all default instances that this one might 8285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // depend on are constructed first. 8295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print( 8305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "$classname$::default_instance_ = new $classname$();\n", 8315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "classname", classname_); 8325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Handle nested types. 8345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < descriptor_->nested_type_count(); i++) { 8355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nested_generators_[i]->GenerateDefaultInstanceAllocator(printer); 8365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MessageGenerator:: 8415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GenerateDefaultInstanceInitializer(io::Printer* printer) { 8425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print( 8435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "$classname$::default_instance_->InitAsDefaultInstance();\n", 8445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "classname", classname_); 8455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Register extensions. 8475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < descriptor_->extension_count(); i++) { 8485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extension_generators_[i]->GenerateRegistration(printer); 8495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Handle nested types. 8525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < descriptor_->nested_type_count(); i++) { 8535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nested_generators_[i]->GenerateDefaultInstanceInitializer(printer); 8545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MessageGenerator:: 8585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GenerateShutdownCode(io::Printer* printer) { 8595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print( 8605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "delete $classname$::default_instance_;\n", 8615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "classname", classname_); 8625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (HasDescriptorMethods(descriptor_->file())) { 8645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print( 8655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "delete $classname$_reflection_;\n", 8665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "classname", classname_); 8675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8693d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch // Handle default instances of fields. 8703d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch for (int i = 0; i < descriptor_->field_count(); i++) { 8713d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch field_generators_.get(descriptor_->field(i)) 8723d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch .GenerateShutdownCode(printer); 8733d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch } 8743d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch 8755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Handle nested types. 8765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < descriptor_->nested_type_count(); i++) { 8775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nested_generators_[i]->GenerateShutdownCode(printer); 8785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MessageGenerator:: 8825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GenerateClassMethods(io::Printer* printer) { 8835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < descriptor_->enum_type_count(); i++) { 8845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) enum_generators_[i]->GenerateMethods(printer); 8855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < descriptor_->nested_type_count(); i++) { 8885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nested_generators_[i]->GenerateClassMethods(printer); 8895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print("\n"); 8905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print(kThinSeparator); 8915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print("\n"); 8925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Generate non-inline field definitions. 8955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < descriptor_->field_count(); i++) { 8965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) field_generators_.get(descriptor_->field(i)) 8975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .GenerateNonInlineAccessorDefinitions(printer); 8985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Generate field number constants. 9015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print("#ifndef _MSC_VER\n"); 9025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < descriptor_->field_count(); i++) { 9035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const FieldDescriptor *field = descriptor_->field(i); 9045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print( 9055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "const int $classname$::$constant_name$;\n", 9065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "classname", ClassName(FieldScope(field), false), 9075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "constant_name", FieldConstantName(field)); 9085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print( 9105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "#endif // !_MSC_VER\n" 9115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "\n"); 9125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Define extension identifiers. 9145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < descriptor_->extension_count(); i++) { 9155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extension_generators_[i]->GenerateDefinition(printer); 9165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GenerateStructors(printer); 9195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print("\n"); 9205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (HasGeneratedMethods(descriptor_->file())) { 9225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GenerateClear(printer); 9235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print("\n"); 9245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GenerateMergeFromCodedStream(printer); 9265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print("\n"); 9275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GenerateSerializeWithCachedSizes(printer); 9295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print("\n"); 9305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (HasFastArraySerialization(descriptor_->file())) { 9325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GenerateSerializeWithCachedSizesToArray(printer); 9335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print("\n"); 9345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GenerateByteSize(printer); 9375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print("\n"); 9385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GenerateMergeFrom(printer); 9405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print("\n"); 9415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GenerateCopyFrom(printer); 9435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print("\n"); 9445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GenerateIsInitialized(printer); 9465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print("\n"); 9475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GenerateSwap(printer); 9505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print("\n"); 9515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (HasDescriptorMethods(descriptor_->file())) { 9535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print( 9545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "::google::protobuf::Metadata $classname$::GetMetadata() const {\n" 9555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " protobuf_AssignDescriptorsOnce();\n" 9565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " ::google::protobuf::Metadata metadata;\n" 9575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " metadata.descriptor = $classname$_descriptor_;\n" 9585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " metadata.reflection = $classname$_reflection_;\n" 9595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " return metadata;\n" 9605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "}\n" 9615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "\n", 9625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "classname", classname_); 9635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 9645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print( 9655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "::std::string $classname$::GetTypeName() const {\n" 9665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " return \"$type_name$\";\n" 9675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "}\n" 9685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "\n", 9695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "classname", classname_, 9705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "type_name", descriptor_->full_name()); 9715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MessageGenerator:: 9765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GenerateOffsets(io::Printer* printer) { 9775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print( 9785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "static const int $classname$_offsets_[$field_count$] = {\n", 9795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "classname", classname_, 9805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "field_count", SimpleItoa(max(1, descriptor_->field_count()))); 9815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Indent(); 9825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < descriptor_->field_count(); i++) { 9845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const FieldDescriptor* field = descriptor_->field(i); 9855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print( 9865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET($classname$, $name$_),\n", 9875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "classname", classname_, 9885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "name", FieldName(field)); 9895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Outdent(); 9925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print("};\n"); 9935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MessageGenerator:: 9965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GenerateSharedConstructorCode(io::Printer* printer) { 9975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print( 9985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "void $classname$::SharedCtor() {\n", 9995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "classname", classname_); 10005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Indent(); 10015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print( 10035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "_cached_size_ = 0;\n"); 10045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < descriptor_->field_count(); i++) { 10065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) field_generators_.get(descriptor_->field(i)) 10075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .GenerateConstructorCode(printer); 10085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print( 10115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "::memset(_has_bits_, 0, sizeof(_has_bits_));\n"); 10125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Outdent(); 10145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print("}\n\n"); 10155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 10165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MessageGenerator:: 10185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GenerateSharedDestructorCode(io::Printer* printer) { 10195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print( 10205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "void $classname$::SharedDtor() {\n", 10215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "classname", classname_); 10225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Indent(); 10235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Write the destructors for each field. 10245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < descriptor_->field_count(); i++) { 10255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) field_generators_.get(descriptor_->field(i)) 10265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .GenerateDestructorCode(printer); 10275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PrintHandlingOptionalStaticInitializers( 10305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) descriptor_->file(), printer, 10315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // With static initializers. 10325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "if (this != default_instance_) {\n", 10335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Without. 10345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "if (this != &default_instance()) {\n"); 10355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We need to delete all embedded messages. 10375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(kenton): If we make unset messages point at default instances 10385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // instead of NULL, then it would make sense to move this code into 10395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // MessageFieldGenerator::GenerateDestructorCode(). 10405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < descriptor_->field_count(); i++) { 10415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const FieldDescriptor* field = descriptor_->field(i); 10425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!field->is_repeated() && 10445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { 10455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print(" delete $name$_;\n", 10465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "name", FieldName(field)); 10475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Outdent(); 10515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print( 10525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " }\n" 10535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "}\n" 10545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "\n"); 10555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 10565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MessageGenerator:: 10585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GenerateStructors(io::Printer* printer) { 10595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string superclass = SuperClassName(descriptor_); 10605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Generate the default constructor. 10625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print( 10635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "$classname$::$classname$()\n" 10645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " : $superclass$() {\n" 10655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " SharedCtor();\n" 10665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "}\n", 10675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "classname", classname_, 10685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "superclass", superclass); 10695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print( 10715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "\n" 10725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "void $classname$::InitAsDefaultInstance() {\n", 10735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "classname", classname_); 10745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The default instance needs all of its embedded message pointers 10765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // cross-linked to other default instances. We can't do this initialization 10775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // in the constructor because some other default instances may not have been 10785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // constructed yet at that time. 10795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(kenton): Maybe all message fields (even for non-default messages) 10805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // should be initialized to point at default instances rather than NULL? 10815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < descriptor_->field_count(); i++) { 10825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const FieldDescriptor* field = descriptor_->field(i); 10835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!field->is_repeated() && 10855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { 10865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PrintHandlingOptionalStaticInitializers( 10875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) descriptor_->file(), printer, 10885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // With static initializers. 10895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " $name$_ = const_cast< $type$*>(&$type$::default_instance());\n", 10905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Without. 10915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " $name$_ = const_cast< $type$*>(\n" 10925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " $type$::internal_default_instance());\n", 10935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Vars. 10945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "name", FieldName(field), 10955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "type", FieldMessageTypeName(field)); 10965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print( 10995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "}\n" 11005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "\n"); 11015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Generate the copy constructor. 11035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print( 11045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "$classname$::$classname$(const $classname$& from)\n" 11055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " : $superclass$() {\n" 11065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " SharedCtor();\n" 11075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " MergeFrom(from);\n" 11085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "}\n" 11095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "\n", 11105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "classname", classname_, 11115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "superclass", superclass); 11125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Generate the shared constructor code. 11145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GenerateSharedConstructorCode(printer); 11155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Generate the destructor. 11175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print( 11185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "$classname$::~$classname$() {\n" 11195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " SharedDtor();\n" 11205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "}\n" 11215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "\n", 11225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "classname", classname_); 11235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Generate the shared destructor code. 11255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GenerateSharedDestructorCode(printer); 11265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Generate SetCachedSize. 11285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print( 11295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "void $classname$::SetCachedSize(int size) const {\n" 11305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();\n" 11315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " _cached_size_ = size;\n" 11325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " GOOGLE_SAFE_CONCURRENT_WRITES_END();\n" 11335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "}\n", 11345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "classname", classname_); 11355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Only generate this member if it's not disabled. 11375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (HasDescriptorMethods(descriptor_->file()) && 11385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) !descriptor_->options().no_standard_descriptor_accessor()) { 11395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print( 11405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "const ::google::protobuf::Descriptor* $classname$::descriptor() {\n" 11415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " protobuf_AssignDescriptorsOnce();\n" 11425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " return $classname$_descriptor_;\n" 11435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "}\n" 11445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "\n", 11455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "classname", classname_, 11465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "adddescriptorsname", 11475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GlobalAddDescriptorsName(descriptor_->file()->name())); 11485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print( 11515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "const $classname$& $classname$::default_instance() {\n", 11525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "classname", classname_); 11535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PrintHandlingOptionalStaticInitializers( 11555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) descriptor_->file(), printer, 11565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // With static initializers. 11575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " if (default_instance_ == NULL) $adddescriptorsname$();\n", 11585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Without. 11595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " $adddescriptorsname$();\n", 11605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Vars. 11615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "adddescriptorsname", 11625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GlobalAddDescriptorsName(descriptor_->file()->name())); 11635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print( 11655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " return *default_instance_;\n" 11665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "}\n" 11675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "\n" 11685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "$classname$* $classname$::default_instance_ = NULL;\n" 11695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "\n" 11705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "$classname$* $classname$::New() const {\n" 11715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " return new $classname$;\n" 11725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "}\n", 11735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "classname", classname_, 11745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "adddescriptorsname", 11755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GlobalAddDescriptorsName(descriptor_->file()->name())); 11765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 11775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MessageGenerator:: 11795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GenerateClear(io::Printer* printer) { 11805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print("void $classname$::Clear() {\n", 11815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "classname", classname_); 11825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Indent(); 11835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int last_index = -1; 11855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (descriptor_->extension_range_count() > 0) { 11875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print("_extensions_.Clear();\n"); 11885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < descriptor_->field_count(); i++) { 11915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const FieldDescriptor* field = descriptor_->field(i); 11925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!field->is_repeated()) { 11945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We can use the fact that _has_bits_ is a giant bitfield to our 11955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // advantage: We can check up to 32 bits at a time for equality to 11965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // zero, and skip the whole range if so. This can improve the speed 11975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // of Clear() for messages which contain a very large number of 11985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // optional fields of which only a few are used at a time. Here, 11995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // we've chosen to check 8 bits at a time rather than 32. 12005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (i / 8 != last_index / 8 || last_index < 0) { 12015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (last_index >= 0) { 12025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Outdent(); 12035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print("}\n"); 12045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print( 12065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "if (_has_bits_[$index$ / 32] & (0xffu << ($index$ % 32))) {\n", 12075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "index", SimpleItoa(field->index())); 12085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Indent(); 12095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) last_index = i; 12115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // It's faster to just overwrite primitive types, but we should 12135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // only clear strings and messages if they were set. 12145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(kenton): Let the CppFieldGenerator decide this somehow. 12155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool should_check_bit = 12165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE || 12175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) field->cpp_type() == FieldDescriptor::CPPTYPE_STRING; 12185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (should_check_bit) { 12205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print( 12215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "if (has_$name$()) {\n", 12225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "name", FieldName(field)); 12235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Indent(); 12245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) field_generators_.get(field).GenerateClearingCode(printer); 12275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (should_check_bit) { 12295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Outdent(); 12305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print("}\n"); 12315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (last_index >= 0) { 12365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Outdent(); 12375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print("}\n"); 12385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Repeated fields don't use _has_bits_ so we clear them in a separate 12415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // pass. 12425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < descriptor_->field_count(); i++) { 12435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const FieldDescriptor* field = descriptor_->field(i); 12445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (field->is_repeated()) { 12465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) field_generators_.get(field).GenerateClearingCode(printer); 12475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print( 12515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "::memset(_has_bits_, 0, sizeof(_has_bits_));\n"); 12525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (HasUnknownFields(descriptor_->file())) { 12545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print( 12555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "mutable_unknown_fields()->Clear();\n"); 12565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Outdent(); 12595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print("}\n"); 12605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 12615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MessageGenerator:: 12635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GenerateSwap(io::Printer* printer) { 12645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Generate the Swap member function. 12655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print("void $classname$::Swap($classname$* other) {\n", 12665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "classname", classname_); 12675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Indent(); 12685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print("if (other != this) {\n"); 12695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Indent(); 12705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (HasGeneratedMethods(descriptor_->file())) { 12725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < descriptor_->field_count(); i++) { 12735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const FieldDescriptor* field = descriptor_->field(i); 12745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) field_generators_.get(field).GenerateSwappingCode(printer); 12755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < (descriptor_->field_count() + 31) / 32; ++i) { 12785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print("std::swap(_has_bits_[$i$], other->_has_bits_[$i$]);\n", 12795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "i", SimpleItoa(i)); 12805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (HasUnknownFields(descriptor_->file())) { 12835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print("_unknown_fields_.Swap(&other->_unknown_fields_);\n"); 12845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print("std::swap(_cached_size_, other->_cached_size_);\n"); 12865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (descriptor_->extension_range_count() > 0) { 12875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print("_extensions_.Swap(&other->_extensions_);\n"); 12885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 12905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print("GetReflection()->Swap(this, other);"); 12915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Outdent(); 12945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print("}\n"); 12955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Outdent(); 12965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print("}\n"); 12975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 12985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MessageGenerator:: 13005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GenerateMergeFrom(io::Printer* printer) { 13015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (HasDescriptorMethods(descriptor_->file())) { 13025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Generate the generalized MergeFrom (aka that which takes in the Message 13035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // base class as a parameter). 13045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print( 13055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "void $classname$::MergeFrom(const ::google::protobuf::Message& from) {\n" 13065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " GOOGLE_CHECK_NE(&from, this);\n", 13075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "classname", classname_); 13085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Indent(); 13095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Cast the message to the proper type. If we find that the message is 13115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // *not* of the proper type, we can still call Merge via the reflection 13125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // system, as the GOOGLE_CHECK above ensured that we have the same descriptor 13135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // for each message. 13145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print( 13155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "const $classname$* source =\n" 13165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " ::google::protobuf::internal::dynamic_cast_if_available<const $classname$*>(\n" 13175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " &from);\n" 13185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "if (source == NULL) {\n" 13195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " ::google::protobuf::internal::ReflectionOps::Merge(from, this);\n" 13205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "} else {\n" 13215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " MergeFrom(*source);\n" 13225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "}\n", 13235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "classname", classname_); 13245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Outdent(); 13265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print("}\n\n"); 13275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 13285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Generate CheckTypeAndMergeFrom(). 13295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print( 13305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "void $classname$::CheckTypeAndMergeFrom(\n" 13315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " const ::google::protobuf::MessageLite& from) {\n" 13325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " MergeFrom(*::google::protobuf::down_cast<const $classname$*>(&from));\n" 13335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "}\n" 13345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "\n", 13355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "classname", classname_); 13365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Generate the class-specific MergeFrom, which avoids the GOOGLE_CHECK and cast. 13395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print( 13405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "void $classname$::MergeFrom(const $classname$& from) {\n" 13415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " GOOGLE_CHECK_NE(&from, this);\n", 13425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "classname", classname_); 13435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Indent(); 13445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Merge Repeated fields. These fields do not require a 13465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // check as we can simply iterate over them. 13475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < descriptor_->field_count(); ++i) { 13485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const FieldDescriptor* field = descriptor_->field(i); 13495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (field->is_repeated()) { 13515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) field_generators_.get(field).GenerateMergingCode(printer); 13525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Merge Optional and Required fields (after a _has_bit check). 13565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int last_index = -1; 13575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < descriptor_->field_count(); ++i) { 13595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const FieldDescriptor* field = descriptor_->field(i); 13605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!field->is_repeated()) { 13625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // See above in GenerateClear for an explanation of this. 13635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (i / 8 != last_index / 8 || last_index < 0) { 13645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (last_index >= 0) { 13655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Outdent(); 13665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print("}\n"); 13675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print( 13695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "if (from._has_bits_[$index$ / 32] & (0xffu << ($index$ % 32))) {\n", 13705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "index", SimpleItoa(field->index())); 13715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Indent(); 13725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) last_index = i; 13755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print( 13775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "if (from.has_$name$()) {\n", 13785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "name", FieldName(field)); 13795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Indent(); 13805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) field_generators_.get(field).GenerateMergingCode(printer); 13825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Outdent(); 13845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print("}\n"); 13855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (last_index >= 0) { 13895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Outdent(); 13905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print("}\n"); 13915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (descriptor_->extension_range_count() > 0) { 13945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print("_extensions_.MergeFrom(from._extensions_);\n"); 13955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (HasUnknownFields(descriptor_->file())) { 13985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print( 13995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "mutable_unknown_fields()->MergeFrom(from.unknown_fields());\n"); 14005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 14015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Outdent(); 14035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print("}\n"); 14045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 14055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MessageGenerator:: 14075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GenerateCopyFrom(io::Printer* printer) { 14085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (HasDescriptorMethods(descriptor_->file())) { 14095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Generate the generalized CopyFrom (aka that which takes in the Message 14105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // base class as a parameter). 14115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print( 14125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "void $classname$::CopyFrom(const ::google::protobuf::Message& from) {\n", 14135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "classname", classname_); 14145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Indent(); 14155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print( 14175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "if (&from == this) return;\n" 14185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "Clear();\n" 14195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "MergeFrom(from);\n"); 14205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Outdent(); 14225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print("}\n\n"); 14235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 14245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Generate the class-specific CopyFrom. 14265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print( 14275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "void $classname$::CopyFrom(const $classname$& from) {\n", 14285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "classname", classname_); 14295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Indent(); 14305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print( 14325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "if (&from == this) return;\n" 14335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "Clear();\n" 14345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "MergeFrom(from);\n"); 14355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Outdent(); 14375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print("}\n"); 14385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 14395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MessageGenerator:: 14415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GenerateMergeFromCodedStream(io::Printer* printer) { 14425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (descriptor_->options().message_set_wire_format()) { 14435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Special-case MessageSet. 14445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print( 14455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "bool $classname$::MergePartialFromCodedStream(\n" 14465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " ::google::protobuf::io::CodedInputStream* input) {\n", 14475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "classname", classname_); 14485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PrintHandlingOptionalStaticInitializers( 14505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) descriptor_->file(), printer, 14515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // With static initializers. 14525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " return _extensions_.ParseMessageSet(input, default_instance_,\n" 14535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " mutable_unknown_fields());\n", 14545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Without. 14555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " return _extensions_.ParseMessageSet(input, &default_instance(),\n" 14565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " mutable_unknown_fields());\n", 14575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Vars. 14585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "classname", classname_); 14595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print( 14615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "}\n"); 14625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 14635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 14645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print( 14665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "bool $classname$::MergePartialFromCodedStream(\n" 14675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " ::google::protobuf::io::CodedInputStream* input) {\n" 14685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "#define DO_(EXPRESSION) if (!(EXPRESSION)) return false\n" 14695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " ::google::protobuf::uint32 tag;\n" 14705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " while ((tag = input->ReadTag()) != 0) {\n", 14715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "classname", classname_); 14725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Indent(); 14745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Indent(); 14755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (descriptor_->field_count() > 0) { 14775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We don't even want to print the switch() if we have no fields because 14785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // MSVC dislikes switch() statements that contain only a default value. 14795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Note: If we just switched on the tag rather than the field number, we 14815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // could avoid the need for the if() to check the wire type at the beginning 14825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // of each case. However, this is actually a bit slower in practice as it 14835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // creates a jump table that is 8x larger and sparser, and meanwhile the 14845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // if()s are highly predictable. 14855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print( 14865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {\n"); 14875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Indent(); 14895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_array<const FieldDescriptor*> ordered_fields( 14915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SortFieldsByNumber(descriptor_)); 14925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < descriptor_->field_count(); i++) { 14945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const FieldDescriptor* field = ordered_fields[i]; 14955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PrintFieldComment(printer, field); 14975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print( 14995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "case $number$: {\n", 15005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "number", SimpleItoa(field->number())); 15015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Indent(); 15025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const FieldGenerator& field_generator = field_generators_.get(field); 15035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Emit code to parse the common, expected case. 15055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print( 15065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==\n" 15075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " ::google::protobuf::internal::WireFormatLite::WIRETYPE_$wiretype$) {\n", 15085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "wiretype", kWireTypeNames[WireFormat::WireTypeForField(field)]); 15095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (i > 0 || (field->is_repeated() && !field->options().packed())) { 15115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print( 15125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " parse_$name$:\n", 15135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "name", field->name()); 15145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 15155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Indent(); 15175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (field->options().packed()) { 15185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) field_generator.GenerateMergeFromCodedStreamWithPacking(printer); 15195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 15205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) field_generator.GenerateMergeFromCodedStream(printer); 15215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 15225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Outdent(); 15235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Emit code to parse unexpectedly packed or unpacked values. 15255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (field->is_packable() && field->options().packed()) { 15265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print( 15275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "} else if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag)\n" 15285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " == ::google::protobuf::internal::WireFormatLite::\n" 15295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " WIRETYPE_$wiretype$) {\n", 15305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "wiretype", 15315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kWireTypeNames[WireFormat::WireTypeForFieldType(field->type())]); 15325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Indent(); 15335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) field_generator.GenerateMergeFromCodedStream(printer); 15345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Outdent(); 15355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (field->is_packable() && !field->options().packed()) { 15365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print( 15375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "} else if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag)\n" 15385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " == ::google::protobuf::internal::WireFormatLite::\n" 15395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " WIRETYPE_LENGTH_DELIMITED) {\n"); 15405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Indent(); 15415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) field_generator.GenerateMergeFromCodedStreamWithPacking(printer); 15425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Outdent(); 15435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 15445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print( 15465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "} else {\n" 15475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " goto handle_uninterpreted;\n" 15485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "}\n"); 15495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // switch() is slow since it can't be predicted well. Insert some if()s 15515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // here that attempt to predict the next tag. 15525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (field->is_repeated() && !field->options().packed()) { 15535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Expect repeats of this field. 15545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print( 15555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "if (input->ExpectTag($tag$)) goto parse_$name$;\n", 15565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "tag", SimpleItoa(WireFormat::MakeTag(field)), 15575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "name", field->name()); 15585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 15595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (i + 1 < descriptor_->field_count()) { 15615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Expect the next field in order. 15625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const FieldDescriptor* next_field = ordered_fields[i + 1]; 15635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print( 15645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "if (input->ExpectTag($next_tag$)) goto parse_$next_name$;\n", 15655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "next_tag", SimpleItoa(WireFormat::MakeTag(next_field)), 15665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "next_name", next_field->name()); 15675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 15685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Expect EOF. 15695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(kenton): Expect group end-tag? 15705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print( 15715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "if (input->ExpectAtEnd()) return true;\n"); 15725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 15735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print( 15755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "break;\n"); 15765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Outdent(); 15785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print("}\n\n"); 15795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 15805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print( 15825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "default: {\n" 15835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "handle_uninterpreted:\n"); 15845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Indent(); 15855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 15865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Is this an end-group tag? If so, this must be the end of the message. 15885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print( 15895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==\n" 15905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {\n" 15915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " return true;\n" 15925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "}\n"); 15935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Handle extension ranges. 15955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (descriptor_->extension_range_count() > 0) { 15965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print( 15975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "if ("); 15985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < descriptor_->extension_range_count(); i++) { 15995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Descriptor::ExtensionRange* range = 16005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) descriptor_->extension_range(i); 16015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (i > 0) printer->Print(" ||\n "); 16025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32 start_tag = WireFormatLite::MakeTag( 16045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) range->start, static_cast<WireFormatLite::WireType>(0)); 16055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32 end_tag = WireFormatLite::MakeTag( 16065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) range->end, static_cast<WireFormatLite::WireType>(0)); 16075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (range->end > FieldDescriptor::kMaxNumber) { 16095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print( 16105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "($start$u <= tag)", 16115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "start", SimpleItoa(start_tag)); 16125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 16135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print( 16145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "($start$u <= tag && tag < $end$u)", 16155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "start", SimpleItoa(start_tag), 16165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "end", SimpleItoa(end_tag)); 16175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 16185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 16195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print(") {\n"); 16205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (HasUnknownFields(descriptor_->file())) { 16215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PrintHandlingOptionalStaticInitializers( 16225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) descriptor_->file(), printer, 16235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // With static initializers. 16245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " DO_(_extensions_.ParseField(tag, input, default_instance_,\n" 16255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " mutable_unknown_fields()));\n", 16265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Without. 16275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " DO_(_extensions_.ParseField(tag, input, &default_instance(),\n" 16285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " mutable_unknown_fields()));\n"); 16295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 16305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PrintHandlingOptionalStaticInitializers( 16315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) descriptor_->file(), printer, 16325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // With static initializers. 16335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " DO_(_extensions_.ParseField(tag, input, default_instance_, NULL));\n", 16345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Without. 16355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " DO_(_extensions_.ParseField(tag, input, &default_instance(), NULL));\n"); 16365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 16375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print( 16385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " continue;\n" 16395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "}\n"); 16405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 16415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We really don't recognize this tag. Skip it. 16435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (HasUnknownFields(descriptor_->file())) { 16445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print( 16455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "DO_(::google::protobuf::internal::WireFormatLite::SkipField(input, tag, mutable_unknown_fields()));\n"); 16465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 16475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print( 16485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "DO_(::google::protobuf::internal::WireFormatLite::SkipField(input, tag, NULL));\n"); 16495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 16505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (descriptor_->field_count() > 0) { 16525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print("break;\n"); 16535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Outdent(); 16545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print("}\n"); // default: 16555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Outdent(); 16565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print("}\n"); // switch 16575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 16585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Outdent(); 16605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Outdent(); 16615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print( 16625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " }\n" // while 16635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " return true;\n" 16645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "#undef DO_\n" 16655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "}\n"); 16665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 16675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MessageGenerator::GenerateSerializeOneField( 16695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) io::Printer* printer, const FieldDescriptor* field, bool to_array) { 16705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PrintFieldComment(printer, field); 16715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!field->is_repeated()) { 16735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print( 16745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "if (has_$name$()) {\n", 16755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "name", FieldName(field)); 16765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Indent(); 16775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 16785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (to_array) { 16805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) field_generators_.get(field).GenerateSerializeWithCachedSizesToArray( 16815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer); 16825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 16835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) field_generators_.get(field).GenerateSerializeWithCachedSizes(printer); 16845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 16855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!field->is_repeated()) { 16875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Outdent(); 16885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print("}\n"); 16895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 16905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print("\n"); 16915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 16925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MessageGenerator::GenerateSerializeOneExtensionRange( 16945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) io::Printer* printer, const Descriptor::ExtensionRange* range, 16955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool to_array) { 16965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) map<string, string> vars; 16975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) vars["start"] = SimpleItoa(range->start); 16985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) vars["end"] = SimpleItoa(range->end); 16995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print(vars, 17005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "// Extension range [$start$, $end$)\n"); 17015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (to_array) { 17025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print(vars, 17035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "target = _extensions_.SerializeWithCachedSizesToArray(\n" 17045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " $start$, $end$, target);\n\n"); 17055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 17065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print(vars, 17075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "_extensions_.SerializeWithCachedSizes(\n" 17085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " $start$, $end$, output);\n\n"); 17095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 17105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 17115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MessageGenerator:: 17135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GenerateSerializeWithCachedSizes(io::Printer* printer) { 17145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (descriptor_->options().message_set_wire_format()) { 17155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Special-case MessageSet. 17165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print( 17175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "void $classname$::SerializeWithCachedSizes(\n" 17185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " ::google::protobuf::io::CodedOutputStream* output) const {\n" 17195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " _extensions_.SerializeMessageSetWithCachedSizes(output);\n", 17205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "classname", classname_); 17215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (HasUnknownFields(descriptor_->file())) { 17225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print( 17235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " ::google::protobuf::internal::WireFormatLite::SerializeUnknownMessageSetItems(\n" 17245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " unknown_fields(), output);\n"); 17255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 17265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print( 17275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "}\n"); 17285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 17295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 17305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print( 17325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "void $classname$::SerializeWithCachedSizes(\n" 17335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " ::google::protobuf::io::CodedOutputStream* output) const {\n", 17345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "classname", classname_); 17355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Indent(); 17365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GenerateSerializeWithCachedSizesBody(printer, false); 17385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Outdent(); 17405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print( 17415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "}\n"); 17425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 17435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MessageGenerator:: 17455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GenerateSerializeWithCachedSizesToArray(io::Printer* printer) { 17465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (descriptor_->options().message_set_wire_format()) { 17475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Special-case MessageSet. 17485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print( 17495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "::google::protobuf::uint8* $classname$::SerializeWithCachedSizesToArray(\n" 17505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " ::google::protobuf::uint8* target) const {\n" 17515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " target =\n" 17525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " _extensions_.SerializeMessageSetWithCachedSizesToArray(target);\n", 17535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "classname", classname_); 17545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (HasUnknownFields(descriptor_->file())) { 17555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print( 17565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " target = ::google::protobuf::internal::WireFormatLite::\n" 17575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " SerializeUnknownMessageSetItemsToArray(\n" 17585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " unknown_fields(), target);\n"); 17595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 17605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print( 17615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " return target;\n" 17625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "}\n"); 17635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 17645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 17655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print( 17675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "::google::protobuf::uint8* $classname$::SerializeWithCachedSizesToArray(\n" 17685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " ::google::protobuf::uint8* target) const {\n", 17695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "classname", classname_); 17705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Indent(); 17715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GenerateSerializeWithCachedSizesBody(printer, true); 17735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Outdent(); 17755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print( 17765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " return target;\n" 17775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "}\n"); 17785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 17795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MessageGenerator:: 17815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GenerateSerializeWithCachedSizesBody(io::Printer* printer, bool to_array) { 17825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_array<const FieldDescriptor*> ordered_fields( 17835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SortFieldsByNumber(descriptor_)); 17845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) vector<const Descriptor::ExtensionRange*> sorted_extensions; 17865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < descriptor_->extension_range_count(); ++i) { 17875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sorted_extensions.push_back(descriptor_->extension_range(i)); 17885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 17895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sort(sorted_extensions.begin(), sorted_extensions.end(), 17905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExtensionRangeSorter()); 17915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Merge the fields and the extension ranges, both sorted by field number. 17935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int i, j; 17945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0, j = 0; 17955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) i < descriptor_->field_count() || j < sorted_extensions.size(); 17965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ) { 17975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (i == descriptor_->field_count()) { 17985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GenerateSerializeOneExtensionRange(printer, 17995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sorted_extensions[j++], 18005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) to_array); 18015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (j == sorted_extensions.size()) { 18025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GenerateSerializeOneField(printer, ordered_fields[i++], to_array); 18035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (ordered_fields[i]->number() < sorted_extensions[j]->start) { 18045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GenerateSerializeOneField(printer, ordered_fields[i++], to_array); 18055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 18065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GenerateSerializeOneExtensionRange(printer, 18075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sorted_extensions[j++], 18085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) to_array); 18095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 18105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 18115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (HasUnknownFields(descriptor_->file())) { 18135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print("if (!unknown_fields().empty()) {\n"); 18145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Indent(); 18155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (to_array) { 18165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print( 18175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "target = " 18185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "::google::protobuf::internal::WireFormatLite::SerializeUnknownFieldsToArray(\n" 18195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " unknown_fields(), target);\n"); 18205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 18215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print( 18225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "::google::protobuf::internal::WireFormatLite::SerializeUnknownFields(\n" 18235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " unknown_fields(), output);\n"); 18245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 18255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Outdent(); 18265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print( 18285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "}\n"); 18295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 18305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 18315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MessageGenerator:: 18335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GenerateByteSize(io::Printer* printer) { 18345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (descriptor_->options().message_set_wire_format()) { 18355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Special-case MessageSet. 18365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print( 18375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "int $classname$::ByteSize() const {\n" 18385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " int total_size = _extensions_.MessageSetByteSize();\n", 18395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "classname", classname_); 18405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (HasUnknownFields(descriptor_->file())) { 18415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print( 18425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " total_size += ::google::protobuf::internal::WireFormatLite::\n" 18435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " ComputeUnknownMessageSetItemsSize(unknown_fields());\n"); 18445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 18455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print( 18465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();\n" 18475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " _cached_size_ = total_size;\n" 18485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " GOOGLE_SAFE_CONCURRENT_WRITES_END();\n" 18495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " return total_size;\n" 18505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "}\n"); 18515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 18525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 18535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print( 18555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "int $classname$::ByteSize() const {\n", 18565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "classname", classname_); 18575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Indent(); 18585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print( 18595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "int total_size = 0;\n" 18605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "\n"); 18615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int last_index = -1; 18635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < descriptor_->field_count(); i++) { 18655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const FieldDescriptor* field = descriptor_->field(i); 18665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!field->is_repeated()) { 18685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // See above in GenerateClear for an explanation of this. 18695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(kenton): Share code? Unclear how to do so without 18705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // over-engineering. 18715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((i / 8) != (last_index / 8) || 18725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) last_index < 0) { 18735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (last_index >= 0) { 18745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Outdent(); 18755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print("}\n"); 18765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 18775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print( 18785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "if (_has_bits_[$index$ / 32] & (0xffu << ($index$ % 32))) {\n", 18795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "index", SimpleItoa(field->index())); 18805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Indent(); 18815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 18825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) last_index = i; 18835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PrintFieldComment(printer, field); 18855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print( 18875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "if (has_$name$()) {\n", 18885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "name", FieldName(field)); 18895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Indent(); 18905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) field_generators_.get(field).GenerateByteSize(printer); 18925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Outdent(); 18945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print( 18955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "}\n" 18965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "\n"); 18975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 18985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 18995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (last_index >= 0) { 19015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Outdent(); 19025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print("}\n"); 19035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 19045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Repeated fields don't use _has_bits_ so we count them in a separate 19065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // pass. 19075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < descriptor_->field_count(); i++) { 19085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const FieldDescriptor* field = descriptor_->field(i); 19095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (field->is_repeated()) { 19115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PrintFieldComment(printer, field); 19125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) field_generators_.get(field).GenerateByteSize(printer); 19135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print("\n"); 19145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 19155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 19165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (descriptor_->extension_range_count() > 0) { 19185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print( 19195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "total_size += _extensions_.ByteSize();\n" 19205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "\n"); 19215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 19225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (HasUnknownFields(descriptor_->file())) { 19245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print("if (!unknown_fields().empty()) {\n"); 19255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Indent(); 19265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print( 19275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "total_size +=\n" 19285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " ::google::protobuf::internal::WireFormatLite::ComputeUnknownFieldsSize(\n" 19295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " unknown_fields());\n"); 19305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Outdent(); 19315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print("}\n"); 19325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 19335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We update _cached_size_ even though this is a const method. In theory, 19355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // this is not thread-compatible, because concurrent writes have undefined 19365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // results. In practice, since any concurrent writes will be writing the 19375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // exact same value, it works on all common processors. In a future version 19385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // of C++, _cached_size_ should be made into an atomic<int>. 19395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print( 19405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();\n" 19415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "_cached_size_ = total_size;\n" 19425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "GOOGLE_SAFE_CONCURRENT_WRITES_END();\n" 19435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "return total_size;\n"); 19445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Outdent(); 19465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print("}\n"); 19475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 19485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MessageGenerator:: 19505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GenerateIsInitialized(io::Printer* printer) { 19515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print( 19525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "bool $classname$::IsInitialized() const {\n", 19535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "classname", classname_); 19545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Indent(); 19555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Check that all required fields in this message are set. We can do this 19575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // most efficiently by checking 32 "has bits" at a time. 19585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int has_bits_array_size = (descriptor_->field_count() + 31) / 32; 19595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < has_bits_array_size; i++) { 19605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32 mask = 0; 19615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int bit = 0; bit < 32; bit++) { 19625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int index = i * 32 + bit; 19635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (index >= descriptor_->field_count()) break; 19645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const FieldDescriptor* field = descriptor_->field(index); 19655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (field->is_required()) { 19675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mask |= 1 << bit; 19685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 19695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 19705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (mask != 0) { 19725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char buffer[kFastToBufferSize]; 19735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print( 19745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "if ((_has_bits_[$i$] & 0x$mask$) != 0x$mask$) return false;\n", 19755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "i", SimpleItoa(i), 19765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "mask", FastHex32ToBuffer(mask, buffer)); 19775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 19785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 19795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Now check that all embedded messages are initialized. 19815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print("\n"); 19825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < descriptor_->field_count(); i++) { 19835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const FieldDescriptor* field = descriptor_->field(i); 19845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE && 19853d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch !ShouldIgnoreRequiredFieldCheck(field) && 19865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HasRequiredFields(field->message_type())) { 19875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (field->is_repeated()) { 19885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print( 19895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "for (int i = 0; i < $name$_size(); i++) {\n" 19905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " if (!this->$name$(i).IsInitialized()) return false;\n" 19915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "}\n", 19925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "name", FieldName(field)); 19935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 19945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print( 19955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "if (has_$name$()) {\n" 19965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " if (!this->$name$().IsInitialized()) return false;\n" 19975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "}\n", 19985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "name", FieldName(field)); 19995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 20005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 20015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 20025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 20035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (descriptor_->extension_range_count() > 0) { 20045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print( 20055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "\n" 20065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "if (!_extensions_.IsInitialized()) return false;"); 20075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 20085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 20095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Outdent(); 20105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print( 20115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " return true;\n" 20125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "}\n"); 20135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 20145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 20155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 20165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace cpp 20175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace compiler 20185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace protobuf 20195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace google 2020