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