1fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Protocol Buffers - Google's data interchange format 2fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Copyright 2008 Google Inc. All rights reserved. 3fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// http://code.google.com/p/protobuf/ 4fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// 5fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Redistribution and use in source and binary forms, with or without 6fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// modification, are permitted provided that the following conditions are 7fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// met: 8fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// 9fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// * Redistributions of source code must retain the above copyright 10fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// notice, this list of conditions and the following disclaimer. 11fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// * Redistributions in binary form must reproduce the above 12fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// copyright notice, this list of conditions and the following disclaimer 13fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// in the documentation and/or other materials provided with the 14fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// distribution. 15fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// * Neither the name of Google Inc. nor the names of its 16fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// contributors may be used to endorse or promote products derived from 17fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// this software without specific prior written permission. 18fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// 19fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 31fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Author: kenton@google.com (Kenton Varda) 32fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Based on original Protocol Buffers design by 33fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Sanjay Ghemawat, Jeff Dean, and others. 34fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 35fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <google/protobuf/reflection_ops.h> 36fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <google/protobuf/descriptor.h> 37fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <google/protobuf/unknown_field_set.h> 38fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <google/protobuf/stubs/strutil.h> 39fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 40fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillenamespace google { 41fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillenamespace protobuf { 42fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillenamespace internal { 43fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 44fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid ReflectionOps::Copy(const Message& from, Message* to) { 45fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (&from == to) return; 46fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville Clear(to); 47fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville Merge(from, to); 48fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 49fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 50fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid ReflectionOps::Merge(const Message& from, Message* to) { 51fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville GOOGLE_CHECK_NE(&from, to); 52fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 53fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const Descriptor* descriptor = from.GetDescriptor(); 54fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville GOOGLE_CHECK_EQ(to->GetDescriptor(), descriptor) 55fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville << "Tried to merge messages of different types."; 56fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 57fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const Reflection* from_reflection = from.GetReflection(); 58fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const Reflection* to_reflection = to->GetReflection(); 59fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 60fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville vector<const FieldDescriptor*> fields; 61fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville from_reflection->ListFields(from, &fields); 62fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville for (int i = 0; i < fields.size(); i++) { 63fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const FieldDescriptor* field = fields[i]; 64fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 65fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (field->is_repeated()) { 66fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville int count = from_reflection->FieldSize(from, field); 67fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville for (int j = 0; j < count; j++) { 68fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville switch (field->cpp_type()) { 69fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#define HANDLE_TYPE(CPPTYPE, METHOD) \ 70fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville case FieldDescriptor::CPPTYPE_##CPPTYPE: \ 71fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville to_reflection->Add##METHOD(to, field, \ 72fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville from_reflection->GetRepeated##METHOD(from, field, j)); \ 73fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville break; 74fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 75fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville HANDLE_TYPE(INT32 , Int32 ); 76fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville HANDLE_TYPE(INT64 , Int64 ); 77fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville HANDLE_TYPE(UINT32, UInt32); 78fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville HANDLE_TYPE(UINT64, UInt64); 79fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville HANDLE_TYPE(FLOAT , Float ); 80fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville HANDLE_TYPE(DOUBLE, Double); 81fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville HANDLE_TYPE(BOOL , Bool ); 82fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville HANDLE_TYPE(STRING, String); 83fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville HANDLE_TYPE(ENUM , Enum ); 84fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#undef HANDLE_TYPE 85fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 86fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville case FieldDescriptor::CPPTYPE_MESSAGE: 87fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville to_reflection->AddMessage(to, field)->MergeFrom( 88fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville from_reflection->GetRepeatedMessage(from, field, j)); 89fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville break; 90fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 91fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 92fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else { 93fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville switch (field->cpp_type()) { 94fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#define HANDLE_TYPE(CPPTYPE, METHOD) \ 95fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville case FieldDescriptor::CPPTYPE_##CPPTYPE: \ 96fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville to_reflection->Set##METHOD(to, field, \ 97fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville from_reflection->Get##METHOD(from, field)); \ 98fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville break; 99fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 100fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville HANDLE_TYPE(INT32 , Int32 ); 101fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville HANDLE_TYPE(INT64 , Int64 ); 102fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville HANDLE_TYPE(UINT32, UInt32); 103fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville HANDLE_TYPE(UINT64, UInt64); 104fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville HANDLE_TYPE(FLOAT , Float ); 105fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville HANDLE_TYPE(DOUBLE, Double); 106fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville HANDLE_TYPE(BOOL , Bool ); 107fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville HANDLE_TYPE(STRING, String); 108fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville HANDLE_TYPE(ENUM , Enum ); 109fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#undef HANDLE_TYPE 110fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 111fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville case FieldDescriptor::CPPTYPE_MESSAGE: 112fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville to_reflection->MutableMessage(to, field)->MergeFrom( 113fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville from_reflection->GetMessage(from, field)); 114fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville break; 115fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 116fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 117fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 118fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 119fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville to_reflection->MutableUnknownFields(to)->MergeFrom( 120fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville from_reflection->GetUnknownFields(from)); 121fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 122fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 123fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid ReflectionOps::Clear(Message* message) { 124fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const Reflection* reflection = message->GetReflection(); 125fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 126fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville vector<const FieldDescriptor*> fields; 127fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville reflection->ListFields(*message, &fields); 128fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville for (int i = 0; i < fields.size(); i++) { 129fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville reflection->ClearField(message, fields[i]); 130fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 131fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 132fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville reflection->MutableUnknownFields(message)->Clear(); 133fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 134fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 135fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillebool ReflectionOps::IsInitialized(const Message& message) { 136fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const Descriptor* descriptor = message.GetDescriptor(); 137fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const Reflection* reflection = message.GetReflection(); 138fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 139fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Check required fields of this message. 140fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville for (int i = 0; i < descriptor->field_count(); i++) { 141fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (descriptor->field(i)->is_required()) { 142fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (!reflection->HasField(message, descriptor->field(i))) { 143fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return false; 144fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 145fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 146fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 147fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 148fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Check that sub-messages are initialized. 149fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville vector<const FieldDescriptor*> fields; 150fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville reflection->ListFields(message, &fields); 151fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville for (int i = 0; i < fields.size(); i++) { 152fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const FieldDescriptor* field = fields[i]; 153fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { 154fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (field->is_repeated()) { 155fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville int size = reflection->FieldSize(message, field); 156fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 157fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville for (int i = 0; i < size; i++) { 158fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (!reflection->GetRepeatedMessage(message, field, i) 159fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville .IsInitialized()) { 160fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return false; 161fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 162fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 163fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else { 164fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (!reflection->GetMessage(message, field).IsInitialized()) { 165fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return false; 166fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 167fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 168fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 169fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 170fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 171fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return true; 172fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 173fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 174fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid ReflectionOps::DiscardUnknownFields(Message* message) { 175fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const Reflection* reflection = message->GetReflection(); 176fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 177fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville reflection->MutableUnknownFields(message)->Clear(); 178fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 179fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville vector<const FieldDescriptor*> fields; 180fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville reflection->ListFields(*message, &fields); 181fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville for (int i = 0; i < fields.size(); i++) { 182fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const FieldDescriptor* field = fields[i]; 183fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { 184fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (field->is_repeated()) { 185fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville int size = reflection->FieldSize(*message, field); 186fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville for (int i = 0; i < size; i++) { 187fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville reflection->MutableRepeatedMessage(message, field, i) 188fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ->DiscardUnknownFields(); 189fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 190fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else { 191fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville reflection->MutableMessage(message, field)->DiscardUnknownFields(); 192fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 193fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 194fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 195fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 196fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 197fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillestatic string SubMessagePrefix(const string& prefix, 198fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const FieldDescriptor* field, 199fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville int index) { 200fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville string result(prefix); 201fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (field->is_extension()) { 202fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville result.append("("); 203fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville result.append(field->full_name()); 204fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville result.append(")"); 205fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else { 206fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville result.append(field->name()); 207fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 208fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (index != -1) { 209fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville result.append("["); 210fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville result.append(SimpleItoa(index)); 211fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville result.append("]"); 212fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 213fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville result.append("."); 214fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return result; 215fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 216fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 217fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid ReflectionOps::FindInitializationErrors( 218fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const Message& message, 219fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const string& prefix, 220fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville vector<string>* errors) { 221fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const Descriptor* descriptor = message.GetDescriptor(); 222fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const Reflection* reflection = message.GetReflection(); 223fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 224fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Check required fields of this message. 225fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville for (int i = 0; i < descriptor->field_count(); i++) { 226fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (descriptor->field(i)->is_required()) { 227fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (!reflection->HasField(message, descriptor->field(i))) { 228fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville errors->push_back(prefix + descriptor->field(i)->name()); 229fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 230fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 231fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 232fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 233fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Check sub-messages. 234fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville vector<const FieldDescriptor*> fields; 235fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville reflection->ListFields(message, &fields); 236fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville for (int i = 0; i < fields.size(); i++) { 237fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const FieldDescriptor* field = fields[i]; 238fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { 239fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 240fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (field->is_repeated()) { 241fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville int size = reflection->FieldSize(message, field); 242fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 243fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville for (int i = 0; i < size; i++) { 244fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const Message& sub_message = 245fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville reflection->GetRepeatedMessage(message, field, i); 246fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville FindInitializationErrors(sub_message, 247fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville SubMessagePrefix(prefix, field, i), 248fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville errors); 249fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 250fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else { 251fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const Message& sub_message = reflection->GetMessage(message, field); 252fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville FindInitializationErrors(sub_message, 253fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville SubMessagePrefix(prefix, field, -1), 254fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville errors); 255fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 256fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 257fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 258fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 259fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 260fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} // namespace internal 261fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} // namespace protobuf 262fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} // namespace google 263