Free cookie consent management tool by TermsFeed Policy Generator

source: branches/PersistenceOverhaul/HeuristicLab.ExtLibs/HeuristicLab.ProtobufCS/2.4.1/ProtobufCS/src/ProtoGen/FieldGeneratorBase.cs @ 13957

Last change on this file since 13957 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: 15.6 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.Globalization;
39using System.Text;
40using Google.ProtocolBuffers.Descriptors;
41
42namespace Google.ProtocolBuffers.ProtoGen
43{
44    internal abstract class FieldGeneratorBase : SourceGeneratorBase<FieldDescriptor>
45    {
46        private readonly int _fieldOrdinal;
47
48        protected FieldGeneratorBase(FieldDescriptor descriptor, int fieldOrdinal)
49            : base(descriptor)
50        {
51            _fieldOrdinal = fieldOrdinal;
52        }
53
54        public abstract void WriteHash(TextGenerator writer);
55        public abstract void WriteEquals(TextGenerator writer);
56        public abstract void WriteToString(TextGenerator writer);
57
58        public int FieldOrdinal
59        {
60            get { return _fieldOrdinal; }
61        }
62
63        private static bool AllPrintableAscii(string text)
64        {
65            foreach (char c in text)
66            {
67                if (c < 0x20 || c > 0x7e)
68                {
69                    return false;
70                }
71            }
72            return true;
73        }
74
75        /// <summary>
76        /// This returns true if the field has a non-default default value.  For instance this returns
77        /// false for numerics with a default of zero '0', or booleans with a default of false.
78        /// </summary>
79        protected bool HasDefaultValue
80        {
81            get
82            {
83                switch (Descriptor.FieldType)
84                {
85                    case FieldType.Float:
86                    case FieldType.Double:
87                    case FieldType.Int32:
88                    case FieldType.Int64:
89                    case FieldType.SInt32:
90                    case FieldType.SInt64:
91                    case FieldType.SFixed32:
92                    case FieldType.SFixed64:
93                    case FieldType.UInt32:
94                    case FieldType.UInt64:
95                    case FieldType.Fixed32:
96                    case FieldType.Fixed64:
97                        {
98                            IConvertible value = (IConvertible) Descriptor.DefaultValue;
99                            return value.ToString(CultureInfo.InvariantCulture) != "0";
100                        }
101                    case FieldType.Bool:
102                        return ((bool) Descriptor.DefaultValue) == true;
103                    default:
104                        return true;
105                }
106            }
107        }
108
109        /// <remarks>Copy exists in ExtensionGenerator.cs</remarks>
110        protected string DefaultValue
111        {
112            get
113            {
114                string suffix = "";
115                switch (Descriptor.FieldType)
116                {
117                    case FieldType.Float:
118                        suffix = "F";
119                        break;
120                    case FieldType.Double:
121                        suffix = "D";
122                        break;
123                    case FieldType.Int64:
124                        suffix = "L";
125                        break;
126                    case FieldType.UInt64:
127                        suffix = "UL";
128                        break;
129                }
130                switch (Descriptor.FieldType)
131                {
132                    case FieldType.Float:
133                    case FieldType.Double:
134                    case FieldType.Int32:
135                    case FieldType.Int64:
136                    case FieldType.SInt32:
137                    case FieldType.SInt64:
138                    case FieldType.SFixed32:
139                    case FieldType.SFixed64:
140                    case FieldType.UInt32:
141                    case FieldType.UInt64:
142                    case FieldType.Fixed32:
143                    case FieldType.Fixed64:
144                        {
145                            // The simple Object.ToString converts using the current culture.
146                            // We want to always use the invariant culture so it's predictable.
147                            IConvertible value = (IConvertible) Descriptor.DefaultValue;
148                            //a few things that must be handled explicitly
149                            if (Descriptor.FieldType == FieldType.Double && value is double)
150                            {
151                                if (double.IsNaN((double) value))
152                                {
153                                    return "double.NaN";
154                                }
155                                if (double.IsPositiveInfinity((double) value))
156                                {
157                                    return "double.PositiveInfinity";
158                                }
159                                if (double.IsNegativeInfinity((double) value))
160                                {
161                                    return "double.NegativeInfinity";
162                                }
163                            }
164                            else if (Descriptor.FieldType == FieldType.Float && value is float)
165                            {
166                                if (float.IsNaN((float) value))
167                                {
168                                    return "float.NaN";
169                                }
170                                if (float.IsPositiveInfinity((float) value))
171                                {
172                                    return "float.PositiveInfinity";
173                                }
174                                if (float.IsNegativeInfinity((float) value))
175                                {
176                                    return "float.NegativeInfinity";
177                                }
178                            }
179                            return value.ToString(CultureInfo.InvariantCulture) + suffix;
180                        }
181                    case FieldType.Bool:
182                        return (bool) Descriptor.DefaultValue ? "true" : "false";
183
184                    case FieldType.Bytes:
185                        if (!Descriptor.HasDefaultValue)
186                        {
187                            return "pb::ByteString.Empty";
188                        }
189                        if (UseLiteRuntime && Descriptor.DefaultValue is ByteString)
190                        {
191                            string temp = (((ByteString) Descriptor.DefaultValue).ToBase64());
192                            return String.Format("pb::ByteString.FromBase64(\"{0}\")", temp);
193                        }
194                        return string.Format("(pb::ByteString) {0}.Descriptor.Fields[{1}].DefaultValue",
195                                             GetClassName(Descriptor.ContainingType), Descriptor.Index);
196                    case FieldType.String:
197                        if (AllPrintableAscii(Descriptor.Proto.DefaultValue))
198                        {
199                            // All chars are ASCII and printable.  In this case we only
200                            // need to escape quotes and backslashes.
201                            return "\"" + Descriptor.Proto.DefaultValue
202                                              .Replace("\\", "\\\\")
203                                              .Replace("'", "\\'")
204                                              .Replace("\"", "\\\"")
205                                   + "\"";
206                        }
207                        if (UseLiteRuntime && Descriptor.DefaultValue is String)
208                        {
209                            string temp = Convert.ToBase64String(
210                                    Encoding.UTF8.GetBytes((String) Descriptor.DefaultValue));
211                            return String.Format("pb::ByteString.FromBase64(\"{0}\").ToStringUtf8()", temp);
212                        }
213                        return string.Format("(string) {0}.Descriptor.Fields[{1}].DefaultValue",
214                                             GetClassName(Descriptor.ContainingType), Descriptor.Index);
215                    case FieldType.Enum:
216                        return TypeName + "." + ((EnumValueDescriptor) Descriptor.DefaultValue).Name;
217                    case FieldType.Message:
218                    case FieldType.Group:
219                        return TypeName + ".DefaultInstance";
220                    default:
221                        throw new InvalidOperationException("Invalid field descriptor type");
222                }
223            }
224        }
225
226        protected string PropertyName
227        {
228            get { return Descriptor.CSharpOptions.PropertyName; }
229        }
230
231        protected string Name
232        {
233            get { return NameHelpers.UnderscoresToCamelCase(GetFieldName(Descriptor)); }
234        }
235
236        protected int Number
237        {
238            get { return Descriptor.FieldNumber; }
239        }
240
241        protected void AddNullCheck(TextGenerator writer)
242        {
243            AddNullCheck(writer, "value");
244        }
245
246        protected void AddNullCheck(TextGenerator writer, string name)
247        {
248            if (IsNullableType)
249            {
250                writer.WriteLine("  pb::ThrowHelper.ThrowIfNull({0}, \"{0}\");", name);
251            }
252        }
253
254        protected void AddPublicMemberAttributes(TextGenerator writer)
255        {
256            AddDeprecatedFlag(writer);
257            AddClsComplianceCheck(writer);
258        }
259
260        protected void AddClsComplianceCheck(TextGenerator writer)
261        {
262            if (!Descriptor.IsCLSCompliant && Descriptor.File.CSharpOptions.ClsCompliance)
263            {
264                writer.WriteLine("[global::System.CLSCompliant(false)]");
265            }
266        }
267
268        protected bool IsObsolete { get { return Descriptor.Options.Deprecated; } }
269
270        /// <summary>
271        /// Writes [global::System.ObsoleteAttribute()] if the member is obsolete
272        /// </summary>
273        protected void AddDeprecatedFlag(TextGenerator writer)
274        {
275            if (IsObsolete)
276            {
277                writer.WriteLine("[global::System.ObsoleteAttribute()]");
278            }
279        }
280
281        /// <summary>
282        /// For encodings with fixed sizes, returns that size in bytes.  Otherwise
283        /// returns -1. TODO(jonskeet): Make this less ugly.
284        /// </summary>
285        protected int FixedSize
286        {
287            get
288            {
289                switch (Descriptor.FieldType)
290                {
291                    case FieldType.UInt32:
292                    case FieldType.UInt64:
293                    case FieldType.Int32:
294                    case FieldType.Int64:
295                    case FieldType.SInt32:
296                    case FieldType.SInt64:
297                    case FieldType.Enum:
298                    case FieldType.Bytes:
299                    case FieldType.String:
300                    case FieldType.Message:
301                    case FieldType.Group:
302                        return -1;
303                    case FieldType.Float:
304                        return WireFormat.FloatSize;
305                    case FieldType.SFixed32:
306                        return WireFormat.SFixed32Size;
307                    case FieldType.Fixed32:
308                        return WireFormat.Fixed32Size;
309                    case FieldType.Double:
310                        return WireFormat.DoubleSize;
311                    case FieldType.SFixed64:
312                        return WireFormat.SFixed64Size;
313                    case FieldType.Fixed64:
314                        return WireFormat.Fixed64Size;
315                    case FieldType.Bool:
316                        return WireFormat.BoolSize;
317                    default:
318                        throw new InvalidOperationException("Invalid field descriptor type");
319                }
320            }
321        }
322
323        protected bool IsNullableType
324        {
325            get
326            {
327                switch (Descriptor.FieldType)
328                {
329                    case FieldType.Float:
330                    case FieldType.Double:
331                    case FieldType.Int32:
332                    case FieldType.Int64:
333                    case FieldType.SInt32:
334                    case FieldType.SInt64:
335                    case FieldType.SFixed32:
336                    case FieldType.SFixed64:
337                    case FieldType.UInt32:
338                    case FieldType.UInt64:
339                    case FieldType.Fixed32:
340                    case FieldType.Fixed64:
341                    case FieldType.Bool:
342                    case FieldType.Enum:
343                        return false;
344                    case FieldType.Bytes:
345                    case FieldType.String:
346                    case FieldType.Message:
347                    case FieldType.Group:
348                        return true;
349                    default:
350                        throw new InvalidOperationException("Invalid field descriptor type");
351                }
352            }
353        }
354
355        protected string TypeName
356        {
357            get
358            {
359                switch (Descriptor.FieldType)
360                {
361                    case FieldType.Enum:
362                        return GetClassName(Descriptor.EnumType);
363                    case FieldType.Message:
364                    case FieldType.Group:
365                        return GetClassName(Descriptor.MessageType);
366                    default:
367                        return DescriptorUtil.GetMappedTypeName(Descriptor.MappedType);
368                }
369            }
370        }
371
372        protected string MessageOrGroup
373        {
374            get { return Descriptor.FieldType == FieldType.Group ? "Group" : "Message"; }
375        }
376
377        /// <summary>
378        /// Returns the type name as used in CodedInputStream method names: SFixed32, UInt32 etc.
379        /// </summary>
380        protected string CapitalizedTypeName
381        {
382            get
383            {
384                // Our enum names match perfectly. How serendipitous.
385                return Descriptor.FieldType.ToString();
386            }
387        }
388    }
389}
Note: See TracBrowser for help on using the repository browser.