| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124 | // Protocol Buffers - Google's data interchange format// Copyright 2008 Google Inc.// http://code.google.com/p/protobuf///// Licensed under the Apache License, Version 2.0 (the "License");// you may not use this file except in compliance with the License.// You may obtain a copy of the License at////      http://www.apache.org/licenses/LICENSE-2.0//// Unless required by applicable law or agreed to in writing, software// distributed under the License is distributed on an "AS IS" BASIS,// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.// See the License for the specific language governing permissions and// limitations under the License.using System;using System.Collections;using System.Collections.Generic;using System.Text;using Google.ProtocolBuffers.Collections;using Google.ProtocolBuffers.Descriptors;namespace Google.ProtocolBuffers {  public sealed class UninitializedMessageException : Exception {    private readonly IList<string> missingFields;    public UninitializedMessageException(IMessage message)        : this(FindMissingFields(message)) {    }    private UninitializedMessageException(IList<string> missingFields)        : base(BuildDescription(missingFields)) {      this.missingFields = Lists.AsReadOnly(missingFields);    }    /// <summary>    /// Converts this exception into an InvalidProtocolBufferException.    /// When a parsed message is missing required fields, this should be thrown    /// instead of UninitializedMessageException.    /// </summary>    public InvalidProtocolBufferException AsInvalidProtocolBufferException() {      return new InvalidProtocolBufferException(Message);    }    /// <summary>    /// Constructs the description string for a given list of missing fields.    /// </summary>    private static string BuildDescription(IEnumerable<string> missingFields) {      StringBuilder description = new StringBuilder("Message missing required fields: ");      bool first = true;      foreach(string field in missingFields) {        if (first) {          first = false;        } else {          description.Append(", ");        }        description.Append(field);      }      return description.ToString();    }    /// <summary>    /// Returns a list of the full "paths" of missing required    /// fields in the specified message.    /// </summary>    private static IList<String> FindMissingFields(IMessage message) {      List<String> results = new List<String>();      FindMissingFields(message, "", results);      return results;    }    /// <summary>    /// Recursive helper implementing FindMissingFields.    /// </summary>    private static void FindMissingFields(IMessage message, String prefix, List<String> results) {      foreach (FieldDescriptor field in message.DescriptorForType.Fields) {        if (field.IsRequired && !message.HasField(field)) {          results.Add(prefix + field.Name);        }      }      foreach (KeyValuePair<FieldDescriptor, object> entry in message.AllFields) {        FieldDescriptor field = entry.Key;        object value = entry.Value;        if (field.MappedType == MappedType.Message) {          if (field.IsRepeated) {            int i = 0;            foreach (object element in (IEnumerable) value) {              FindMissingFields((IMessage) element, SubMessagePrefix(prefix, field, i++), results);            }          } else {            if (message.HasField(field)) {              FindMissingFields((IMessage) value, SubMessagePrefix(prefix, field, -1), results);            }          }        }      }    }    private static String SubMessagePrefix(String prefix, FieldDescriptor field, int index) {      StringBuilder result = new StringBuilder(prefix);      if (field.IsExtension) {        result.Append('(')              .Append(field.FullName)              .Append(')');      } else {        result.Append(field.Name);      }      if (index != -1) {        result.Append('[')              .Append(index)              .Append(']');      }      result.Append('.');      return result.ToString();    }  }}  
 |