Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/sources/HeuristicLab.ExtLibs/HeuristicLab.ProtobufCS/2.4.1/ProtobufCS/src/ProtocolBuffers/UninitializedMessageException.cs @ 13329

Last change on this file since 13329 was 8295, checked in by abeham, 12 years ago

#1897:

  • Removed protocol buffers 0.9.1
  • Added protocol buffers 2.4.1
  • Updated proto processing command
File size: 7.5 KB
Line 
1#region Copyright notice and license
2
3// Protocol Buffers - Google's data interchange format
4// Copyright 2008 Google Inc.  All rights reserved.
5// http://github.com/jskeet/dotnet-protobufs/
6// Original C++/Java/Python code:
7// http://code.google.com/p/protobuf/
8//
9// Redistribution and use in source and binary forms, with or without
10// modification, are permitted provided that the following conditions are
11// met:
12//
13//     * Redistributions of source code must retain the above copyright
14// notice, this list of conditions and the following disclaimer.
15//     * Redistributions in binary form must reproduce the above
16// copyright notice, this list of conditions and the following disclaimer
17// in the documentation and/or other materials provided with the
18// distribution.
19//     * Neither the name of Google Inc. nor the names of its
20// contributors may be used to endorse or promote products derived from
21// this software without specific prior written permission.
22//
23// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
26// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
27// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
28// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
29// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
30// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
31// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
32// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
33// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34
35#endregion
36
37using System;
38using System.Collections;
39using System.Collections.Generic;
40using System.Text;
41
42#if !LITE
43using Google.ProtocolBuffers.Collections;
44using Google.ProtocolBuffers.Descriptors;
45
46#endif
47
48namespace Google.ProtocolBuffers
49{
50    /// <summary>
51    /// TODO(jonskeet): Write summary text.
52    /// </summary>
53    public sealed class UninitializedMessageException : Exception
54    {
55        private readonly IList<string> missingFields;
56
57        private UninitializedMessageException(IList<string> missingFields)
58            : base(BuildDescription(missingFields))
59        {
60            this.missingFields = new List<string>(missingFields);
61        }
62
63        /// <summary>
64        /// Returns a read-only list of human-readable names of
65        /// required fields missing from this message. Each name
66        /// is a full path to a field, e.g. "foo.bar[5].baz"
67        /// </summary>
68        public IList<string> MissingFields
69        {
70            get { return missingFields; }
71        }
72
73        /// <summary>
74        /// Converts this exception into an InvalidProtocolBufferException.
75        /// When a parsed message is missing required fields, this should be thrown
76        /// instead of UninitializedMessageException.
77        /// </summary>
78        public InvalidProtocolBufferException AsInvalidProtocolBufferException()
79        {
80            return new InvalidProtocolBufferException(Message);
81        }
82
83        /// <summary>
84        /// Constructs the description string for a given list of missing fields.
85        /// </summary>
86        private static string BuildDescription(IEnumerable<string> missingFields)
87        {
88            StringBuilder description = new StringBuilder("Message missing required fields: ");
89            bool first = true;
90            foreach (string field in missingFields)
91            {
92                if (first)
93                {
94                    first = false;
95                }
96                else
97                {
98                    description.Append(", ");
99                }
100                description.Append(field);
101            }
102            return description.ToString();
103        }
104
105        /// <summary>
106        /// For Lite exceptions that do not known how to enumerate missing fields
107        /// </summary>
108        public UninitializedMessageException(IMessageLite message)
109            : base(String.Format("Message {0} is missing required fields", message.GetType()))
110        {
111            missingFields = new List<string>();
112        }
113
114#if !LITE
115        public UninitializedMessageException(IMessage message)
116            : this(FindMissingFields(message))
117        {
118        }
119
120        /// <summary>
121        /// Returns a list of the full "paths" of missing required
122        /// fields in the specified message.
123        /// </summary>
124        private static IList<String> FindMissingFields(IMessage message)
125        {
126            List<String> results = new List<String>();
127            FindMissingFields(message, "", results);
128            return results;
129        }
130
131        /// <summary>
132        /// Recursive helper implementing FindMissingFields.
133        /// </summary>
134        private static void FindMissingFields(IMessage message, String prefix, List<String> results)
135        {
136            foreach (FieldDescriptor field in message.DescriptorForType.Fields)
137            {
138                if (field.IsRequired && !message.HasField(field))
139                {
140                    results.Add(prefix + field.Name);
141                }
142            }
143
144            foreach (KeyValuePair<FieldDescriptor, object> entry in message.AllFields)
145            {
146                FieldDescriptor field = entry.Key;
147                object value = entry.Value;
148
149                if (field.MappedType == MappedType.Message)
150                {
151                    if (field.IsRepeated)
152                    {
153                        int i = 0;
154                        foreach (object element in (IEnumerable) value)
155                        {
156                            if (element is IMessage)
157                            {
158                                FindMissingFields((IMessage) element, SubMessagePrefix(prefix, field, i++), results);
159                            }
160                            else
161                            {
162                                results.Add(prefix + field.Name);
163                            }
164                        }
165                    }
166                    else
167                    {
168                        if (message.HasField(field))
169                        {
170                            if (value is IMessage)
171                            {
172                                FindMissingFields((IMessage) value, SubMessagePrefix(prefix, field, -1), results);
173                            }
174                            else
175                            {
176                                results.Add(prefix + field.Name);
177                            }
178                        }
179                    }
180                }
181            }
182        }
183
184        private static String SubMessagePrefix(String prefix, FieldDescriptor field, int index)
185        {
186            StringBuilder result = new StringBuilder(prefix);
187            if (field.IsExtension)
188            {
189                result.Append('(')
190                    .Append(field.FullName)
191                    .Append(')');
192            }
193            else
194            {
195                result.Append(field.Name);
196            }
197            if (index != -1)
198            {
199                result.Append('[')
200                    .Append(index)
201                    .Append(']');
202            }
203            result.Append('.');
204            return result.ToString();
205        }
206#endif
207    }
208}
Note: See TracBrowser for help on using the repository browser.