From 980ba8dcd470ddb964a84da1317028dd81c1d60a Mon Sep 17 00:00:00 2001 From: csharptest Date: Sun, 7 Nov 2010 16:30:39 -0600 Subject: Full rutime working, Lite generator and runtime building but untested --- src/ProtocolBuffers/ByteString.cs | 7 + .../DescriptorProtos/CSharpOptions.cs | 2 +- .../DescriptorProtos/DescriptorProtoFile.cs | 2 +- src/ProtocolBuffers/EnumLite.cs | 71 ++++++++- src/ProtocolBuffers/ExtendableBuilderLite.cs | 172 +++++++++++++++++++++ src/ProtocolBuffers/ExtendableMessageLite.cs | 156 +++++++++++++++++++ src/ProtocolBuffers/GeneratedBuilderLite.cs | 117 ++++++++++++++ src/ProtocolBuffers/GeneratedExtensionLite.cs | 137 ++++++++++++++-- src/ProtocolBuffers/GeneratedMessageLite.cs | 52 +++++++ src/ProtocolBuffers/ProtocolBuffers.csproj | 4 + src/ProtocolBuffers/ProtocolBuffersLite.csproj | 5 + .../UninitializedMessageException.cs | 10 +- 12 files changed, 718 insertions(+), 17 deletions(-) create mode 100644 src/ProtocolBuffers/ExtendableBuilderLite.cs create mode 100644 src/ProtocolBuffers/ExtendableMessageLite.cs create mode 100644 src/ProtocolBuffers/GeneratedBuilderLite.cs create mode 100644 src/ProtocolBuffers/GeneratedMessageLite.cs (limited to 'src/ProtocolBuffers') diff --git a/src/ProtocolBuffers/ByteString.cs b/src/ProtocolBuffers/ByteString.cs index 78b946bb..5add171e 100644 --- a/src/ProtocolBuffers/ByteString.cs +++ b/src/ProtocolBuffers/ByteString.cs @@ -78,6 +78,13 @@ namespace Google.ProtocolBuffers { return (byte[])bytes.Clone(); } + /// + /// Constructs a ByteString from the Base64 Encoded String. + /// + public static ByteString FromBase64(string bytes) { + return new ByteString(System.Convert.FromBase64String(bytes)); + } + /// /// Constructs a ByteString from the given array. The contents /// are copied, so further modifications to the array will not diff --git a/src/ProtocolBuffers/DescriptorProtos/CSharpOptions.cs b/src/ProtocolBuffers/DescriptorProtos/CSharpOptions.cs index ae13b5ac..61d52fdc 100644 --- a/src/ProtocolBuffers/DescriptorProtos/CSharpOptions.cs +++ b/src/ProtocolBuffers/DescriptorProtos/CSharpOptions.cs @@ -1,4 +1,4 @@ -// Generated by the protocol buffer compiler. DO NOT EDIT! +// Generated by ProtoGen, Version=0.9.0.0, Culture=neutral, PublicKeyToken=8fd7408b07f8d2cd. DO NOT EDIT! using pb = global::Google.ProtocolBuffers; using pbc = global::Google.ProtocolBuffers.Collections; diff --git a/src/ProtocolBuffers/DescriptorProtos/DescriptorProtoFile.cs b/src/ProtocolBuffers/DescriptorProtos/DescriptorProtoFile.cs index 4e85b628..09a00c97 100644 --- a/src/ProtocolBuffers/DescriptorProtos/DescriptorProtoFile.cs +++ b/src/ProtocolBuffers/DescriptorProtos/DescriptorProtoFile.cs @@ -1,4 +1,4 @@ -// Generated by the protocol buffer compiler. DO NOT EDIT! +// Generated by ProtoGen, Version=0.9.0.0, Culture=neutral, PublicKeyToken=8fd7408b07f8d2cd. DO NOT EDIT! using pb = global::Google.ProtocolBuffers; using pbc = global::Google.ProtocolBuffers.Collections; diff --git a/src/ProtocolBuffers/EnumLite.cs b/src/ProtocolBuffers/EnumLite.cs index 0c6c9afb..92187b38 100644 --- a/src/ProtocolBuffers/EnumLite.cs +++ b/src/ProtocolBuffers/EnumLite.cs @@ -1,5 +1,40 @@ -using System; +#region Copyright notice and license +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://github.com/jskeet/dotnet-protobufs/ +// Original C++/Java/Python code: +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +#endregion + +using System; using System.Collections.Generic; +using System.Globalization; using System.Text; namespace Google.ProtocolBuffers { @@ -28,4 +63,38 @@ namespace Google.ProtocolBuffers { public interface IEnumLiteMap { bool IsValidValue(IEnumLite value); } + + public class EnumLiteMap : IEnumLiteMap + where TEnum : struct, IComparable, IFormattable, IConvertible { + + struct EnumValue : IEnumLite, IComparable { + int _value; + public EnumValue(int value) { + _value = value; + } + int IEnumLite.Number { + get { return _value; } + } + int IComparable.CompareTo(IEnumLite other) { + return _value.CompareTo(other.Number); + } + } + + private readonly SortedList items; + + public EnumLiteMap() { + items = new SortedList(); + foreach (TEnum evalue in Enum.GetValues(typeof(TEnum))) + items.Add(evalue.ToInt32(CultureInfo.InvariantCulture), new EnumValue(evalue.ToInt32(CultureInfo.InvariantCulture))); + } + + IEnumLite IEnumLiteMap.FindValueByNumber(int number) { + IEnumLite val; + return items.TryGetValue(number, out val) ? val : null; + } + + bool IEnumLiteMap.IsValidValue(IEnumLite value) { + return items.ContainsKey(value.Number); + } + } } diff --git a/src/ProtocolBuffers/ExtendableBuilderLite.cs b/src/ProtocolBuffers/ExtendableBuilderLite.cs new file mode 100644 index 00000000..815b51b3 --- /dev/null +++ b/src/ProtocolBuffers/ExtendableBuilderLite.cs @@ -0,0 +1,172 @@ +#region Copyright notice and license +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://github.com/jskeet/dotnet-protobufs/ +// Original C++/Java/Python code: +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +#endregion + +using System; +using System.Collections.Generic; + +namespace Google.ProtocolBuffers { + public abstract class ExtendableBuilderLite : GeneratedBuilderLite + where TMessage : ExtendableMessageLite + where TBuilder : GeneratedBuilderLite { + + protected ExtendableBuilderLite() { } + + /// + /// Checks if a singular extension is present + /// + public bool HasExtension(GeneratedExtensionLite extension) { + return MessageBeingBuilt.HasExtension(extension); + } + + /// + /// Returns the number of elements in a repeated extension. + /// + public int GetExtensionCount(GeneratedExtensionLite> extension) { + return MessageBeingBuilt.GetExtensionCount(extension); + } + + /// + /// Returns the value of an extension. + /// + public TExtension GetExtension(GeneratedExtensionLite extension) { + return MessageBeingBuilt.GetExtension(extension); + } + + /// + /// Returns one element of a repeated extension. + /// + public TExtension GetExtension(GeneratedExtensionLite> extension, int index) { + return MessageBeingBuilt.GetExtension(extension, index); + } + + /// + /// Sets the value of an extension. + /// + public TBuilder SetExtension(GeneratedExtensionLite extension, TExtension value) { + ExtendableMessageLite message = MessageBeingBuilt; + message.VerifyExtensionContainingType(extension); + message.Extensions[extension.Descriptor] = (value); + return ThisBuilder; + } + + /// + /// Sets the value of one element of a repeated extension. + /// + public TBuilder SetExtension(GeneratedExtensionLite> extension, int index, TExtension value) { + ExtendableMessageLite message = MessageBeingBuilt; + message.VerifyExtensionContainingType(extension); + message.Extensions[extension.Descriptor, index] = (value); + return ThisBuilder; + } + + /// + /// Appends a value to a repeated extension. + /// + public ExtendableBuilderLite AddExtension(GeneratedExtensionLite> extension, TExtension value) { + ExtendableMessageLite message = MessageBeingBuilt; + message.VerifyExtensionContainingType(extension); + message.Extensions.AddRepeatedField(extension.Descriptor, (value)); + return this; + } + + /// + /// Clears an extension. + /// + public ExtendableBuilderLite ClearExtension(GeneratedExtensionLite extension) { + ExtendableMessageLite message = MessageBeingBuilt; + message.VerifyExtensionContainingType(extension); + message.Extensions.ClearField(extension.Descriptor); + return this; + } + + /// + /// Called by subclasses to parse an unknown field or an extension. + /// + /// true unless the tag is an end-group tag + [CLSCompliant(false)] + protected override bool ParseUnknownField(CodedInputStream input, + ExtensionRegistry extensionRegistry, uint tag) { + return input.SkipField(tag); + } + + // --------------------------------------------------------------- + // Reflection + + public object this[IFieldDescriptorLite field, int index] { + set { + if (field.IsExtension) { + ExtendableMessageLite message = MessageBeingBuilt; + message.Extensions[field, index] = value; + } else { + throw new NotSupportedException("Not supported in the lite runtime."); + } + } + } + + public object this[IFieldDescriptorLite field] { + set { + if (field.IsExtension) { + ExtendableMessageLite message = MessageBeingBuilt; + message.Extensions[field] = value; + } else { + throw new NotSupportedException("Not supported in the lite runtime."); + } + } + } + + public TBuilder ClearField(IFieldDescriptorLite field) { + if (field.IsExtension) { + ExtendableMessageLite message = MessageBeingBuilt; + message.Extensions.ClearField(field); + return ThisBuilder; + } else { + throw new NotSupportedException("Not supported in the lite runtime."); + } + } + + public TBuilder AddRepeatedField(IFieldDescriptorLite field, object value) { + if (field.IsExtension) { + ExtendableMessageLite message = MessageBeingBuilt; + message.Extensions.AddRepeatedField(field, value); + return ThisBuilder; + } else { + throw new NotSupportedException("Not supported in the lite runtime."); + } + } + + protected void MergeExtensionFields(ExtendableMessageLite other) { + MessageBeingBuilt.Extensions.MergeFrom(other.Extensions); + } + } +} diff --git a/src/ProtocolBuffers/ExtendableMessageLite.cs b/src/ProtocolBuffers/ExtendableMessageLite.cs new file mode 100644 index 00000000..4cd90e48 --- /dev/null +++ b/src/ProtocolBuffers/ExtendableMessageLite.cs @@ -0,0 +1,156 @@ +#region Copyright notice and license +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://github.com/jskeet/dotnet-protobufs/ +// Original C++/Java/Python code: +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +#endregion + +using System; +using System.Collections.Generic; +namespace Google.ProtocolBuffers { + public abstract class ExtendableMessageLite : GeneratedMessageLite + where TMessage : GeneratedMessageLite + where TBuilder : GeneratedBuilderLite { + + protected ExtendableMessageLite() { } + private readonly FieldSet extensions = FieldSet.CreateInstance(); + + /// + /// Access for the builder. + /// + internal FieldSet Extensions { + get { return extensions; } + } + + /// + /// Checks if a singular extension is present. + /// + public bool HasExtension(GeneratedExtensionLite extension) { + VerifyExtensionContainingType(extension); + return extensions.HasField(extension.Descriptor); + } + + /// + /// Returns the number of elements in a repeated extension. + /// + public int GetExtensionCount(GeneratedExtensionLite> extension) { + VerifyExtensionContainingType(extension); + return extensions.GetRepeatedFieldCount(extension.Descriptor); + } + + /// + /// Returns the value of an extension. + /// + public TExtension GetExtension(GeneratedExtensionLite extension) { + VerifyExtensionContainingType(extension); + object value = extensions[extension.Descriptor]; + if (value == null) { + return extension.DefaultValue; + } else { + return (TExtension)value; + } + } + + /// + /// Returns one element of a repeated extension. + /// + public TExtension GetExtension(GeneratedExtensionLite> extension, int index) { + VerifyExtensionContainingType(extension); + return (TExtension)extensions[extension.Descriptor, index]; + } + + /// + /// Called to check if all extensions are initialized. + /// + protected bool ExtensionsAreInitialized { + get { return extensions.IsInitialized; } + } + + public override bool IsInitialized { + get { + return ExtensionsAreInitialized; + } + } + + /// + /// Used by subclasses to serialize extensions. Extension ranges may be + /// interleaves with field numbers, but we must write them in canonical + /// (sorted by field number) order. This class helps us to write individual + /// ranges of extensions at once. + /// + /// TODO(jonskeet): See if we can improve this in terms of readability. + /// + protected class ExtensionWriter { + readonly IEnumerator> iterator; + readonly FieldSet extensions; + KeyValuePair? next = null; + + internal ExtensionWriter(ExtendableMessageLite message) { + extensions = message.extensions; + iterator = message.extensions.GetEnumerator(); + if (iterator.MoveNext()) { + next = iterator.Current; + } + } + + public void WriteUntil(int end, CodedOutputStream output) { + while (next != null && next.Value.Key.FieldNumber < end) { + extensions.WriteField(next.Value.Key, next.Value.Value, output); + if (iterator.MoveNext()) { + next = iterator.Current; + } else { + next = null; + } + } + } + } + + protected ExtensionWriter CreateExtensionWriter(ExtendableMessageLite message) { + return new ExtensionWriter(message); + } + + /// + /// Called by subclasses to compute the size of extensions. + /// + protected int ExtensionsSerializedSize { + get { return extensions.SerializedSize; } + } + + internal void VerifyExtensionContainingType(GeneratedExtensionLite extension) { + if (!ReferenceEquals(extension.ContainingTypeDefaultInstance, DefaultInstanceForType)) { + // This can only happen if someone uses unchecked operations. + throw new ArgumentException( + String.Format("Extension is for type \"{0}\" which does not match message type \"{1}\".", + extension.ContainingTypeDefaultInstance, DefaultInstanceForType + )); + } + } + } +} diff --git a/src/ProtocolBuffers/GeneratedBuilderLite.cs b/src/ProtocolBuffers/GeneratedBuilderLite.cs new file mode 100644 index 00000000..d721fddd --- /dev/null +++ b/src/ProtocolBuffers/GeneratedBuilderLite.cs @@ -0,0 +1,117 @@ +#region Copyright notice and license +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://github.com/jskeet/dotnet-protobufs/ +// Original C++/Java/Python code: +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +#endregion + +using System; +using System.Collections; +using System.Collections.Generic; + +namespace Google.ProtocolBuffers { + /// + /// All generated protocol message builder classes extend this class. It implements + /// most of the IBuilder interface using reflection. Users can ignore this class + /// as an implementation detail. + /// + public abstract class GeneratedBuilderLite : AbstractBuilderLite + where TMessage : GeneratedMessageLite + where TBuilder : GeneratedBuilderLite { + + /// + /// Returns the message being built at the moment. + /// + protected abstract TMessage MessageBeingBuilt { get; } + + public override TBuilder MergeFrom(IMessageLite other) { + //do nothing, Lite runtime does not support cross-message merges + return ThisBuilder; + } + + public abstract TBuilder MergeFrom(TMessage other); + + public override bool IsInitialized { + get { return MessageBeingBuilt.IsInitialized; } + } + + /// + /// Adds all of the specified values to the given collection. + /// + /// Any element of the list is null + protected void AddRange(IEnumerable source, IList destination) { + ThrowHelper.ThrowIfNull(source); + // We only need to check this for nullable types. + if (default(T) == null) { + ThrowHelper.ThrowIfAnyNull(source); + } + List list = destination as List; + if (list != null) { + list.AddRange(source); + } else { + foreach (T element in source) { + destination.Add(element); + } + } + } + + /// + /// Called by derived classes to parse an unknown field. + /// + /// true unless the tag is an end-group tag + [CLSCompliant(false)] + protected virtual bool ParseUnknownField(CodedInputStream input, + ExtensionRegistry extensionRegistry, uint tag) { + return input.SkipField(tag); + } + + /// + /// Like Build(), but will wrap UninitializedMessageException in + /// InvalidProtocolBufferException. + /// + public TMessage BuildParsed() { + if (!IsInitialized) { + throw new UninitializedMessageException(MessageBeingBuilt).AsInvalidProtocolBufferException(); + } + return BuildPartial(); + } + + /// + /// Implementation of . + /// + public override TMessage Build() { + // If the message is null, we'll throw a more appropriate exception in BuildPartial. + if (MessageBeingBuilt != null && !IsInitialized) { + throw new UninitializedMessageException(MessageBeingBuilt); + } + return BuildPartial(); + } + } +} diff --git a/src/ProtocolBuffers/GeneratedExtensionLite.cs b/src/ProtocolBuffers/GeneratedExtensionLite.cs index da07fb8c..e27dff72 100644 --- a/src/ProtocolBuffers/GeneratedExtensionLite.cs +++ b/src/ProtocolBuffers/GeneratedExtensionLite.cs @@ -1,4 +1,40 @@ -using System; +#region Copyright notice and license +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://github.com/jskeet/dotnet-protobufs/ +// Original C++/Java/Python code: +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +#endregion + +using System; +using System.Collections.Generic; +using Google.ProtocolBuffers.Collections; using Google.ProtocolBuffers.Descriptors; namespace Google.ProtocolBuffers { @@ -9,28 +45,87 @@ namespace Google.ProtocolBuffers { IMessageLite MessageDefaultInstance { get; } } - public class ExtensionDescriptorLite { - private readonly EnumLiteMap enumTypeMap; + public class ExtensionDescriptorLite : IFieldDescriptorLite { + /// + /// Immutable mapping from field type to mapped type. Built using the attributes on + /// FieldType values. + /// + public static readonly IDictionary FieldTypeToMappedTypeMap = MapFieldTypes(); + + private static IDictionary MapFieldTypes() { + var map = new Dictionary(); + foreach (System.Reflection.FieldInfo field in typeof(FieldType).GetFields(System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Public)) { + FieldType fieldType = (FieldType)field.GetValue(null); + FieldMappingAttribute mapping = (FieldMappingAttribute)field.GetCustomAttributes(typeof(FieldMappingAttribute), false)[0]; + map[fieldType] = mapping.MappedType; + } + return Dictionaries.AsReadOnly(map); + } + + private readonly IEnumLiteMap enumTypeMap; private readonly int number; private readonly FieldType type; private readonly bool isRepeated; private readonly bool isPacked; + private readonly MappedType mapType; + private readonly object defaultValue; - public ExtensionDescriptorLite(EnumLiteMap enumTypeMap, int number, FieldType type, bool isRepeated, bool isPacked) { + public ExtensionDescriptorLite(IEnumLiteMap enumTypeMap, int number, FieldType type, object defaultValue, bool isRepeated, bool isPacked) { this.enumTypeMap = enumTypeMap; this.number = number; this.type = type; + this.mapType = FieldTypeToMappedTypeMap[type]; this.isRepeated = isRepeated; this.isPacked = isPacked; + this.defaultValue = defaultValue; } - public int Number { + public bool IsRepeated { + get { return isRepeated; } + } + + public bool IsRequired { + get { return false; } + } + + public bool IsPacked { + get { return isPacked; } + } + + public bool IsExtension { + get { return true; } + } + +#warning ToDo - Discover the meaning and purpose of this durring serialization and return the correct value + public bool MessageSetWireFormat { + get { return true; } + } + + public int FieldNumber { get { return number; } } + + public IEnumLiteMap EnumType { + get { return enumTypeMap; } + } + + public FieldType FieldType { + get { return type; } + } + + public MappedType MappedType { + get { return mapType; } + } + + public object DefaultValue { + get { return defaultValue; } + } + + public int CompareTo(IFieldDescriptorLite other) { + return FieldNumber.CompareTo(other.FieldNumber); + } } - public class EnumLiteMap { } - public class GeneratedExtensionLite : IGeneratedExtensionLite where TContainingType : IMessageLite { @@ -62,11 +157,11 @@ namespace Google.ProtocolBuffers { TContainingType containingTypeDefaultInstance, TExtensionType defaultValue, IMessageLite messageDefaultInstance, - EnumLiteMap enumTypeMap, + IEnumLiteMap enumTypeMap, int number, FieldType type) : this(containingTypeDefaultInstance, defaultValue, messageDefaultInstance, - new ExtensionDescriptorLite(enumTypeMap, number, type, + new ExtensionDescriptorLite(enumTypeMap, number, type, defaultValue, false /* isRepeated */, false /* isPacked */)) { } @@ -75,15 +170,29 @@ namespace Google.ProtocolBuffers { TContainingType containingTypeDefaultInstance, TExtensionType defaultValue, IMessageLite messageDefaultInstance, - EnumLiteMap enumTypeMap, + IEnumLiteMap enumTypeMap, int number, FieldType type, bool isPacked) : this(containingTypeDefaultInstance, defaultValue, messageDefaultInstance, - new ExtensionDescriptorLite(enumTypeMap, number, type, + new ExtensionDescriptorLite(enumTypeMap, number, type, defaultValue, true /* isRepeated */, isPacked)) { } + /// + /// Returns information about this extension + /// + public IFieldDescriptorLite Descriptor { + get { return descriptor; } + } + + /// + /// Returns the default value for this extension + /// + public TExtensionType DefaultValue { + get { return defaultValue; } + } + /// /// used for the extension registry /// @@ -102,7 +211,7 @@ namespace Google.ProtocolBuffers { /** Get the field number. */ public int Number { get { - return descriptor.Number; + return descriptor.FieldNumber; } } /** @@ -114,5 +223,9 @@ namespace Google.ProtocolBuffers { return messageDefaultInstance; } } + + public object SingularFromReflectionType(object value) { + return value; + } } } \ No newline at end of file diff --git a/src/ProtocolBuffers/GeneratedMessageLite.cs b/src/ProtocolBuffers/GeneratedMessageLite.cs new file mode 100644 index 00000000..fd1c6216 --- /dev/null +++ b/src/ProtocolBuffers/GeneratedMessageLite.cs @@ -0,0 +1,52 @@ +#region Copyright notice and license +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://github.com/jskeet/dotnet-protobufs/ +// Original C++/Java/Python code: +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +#endregion + +using System; +using System.Collections.Generic; +using System.Collections; + +namespace Google.ProtocolBuffers { + + /// + /// All generated protocol message classes extend this class. It implements + /// most of the IMessage interface using reflection. Users + /// can ignore this class as an implementation detail. + /// + public abstract class GeneratedMessageLite : AbstractMessageLite + where TMessage : GeneratedMessageLite + where TBuilder : GeneratedBuilderLite { + + protected abstract TMessage ThisMessage { get; } + } +} diff --git a/src/ProtocolBuffers/ProtocolBuffers.csproj b/src/ProtocolBuffers/ProtocolBuffers.csproj index dece65af..4de97f47 100644 --- a/src/ProtocolBuffers/ProtocolBuffers.csproj +++ b/src/ProtocolBuffers/ProtocolBuffers.csproj @@ -92,7 +92,9 @@ + + Code @@ -109,7 +111,9 @@ + + diff --git a/src/ProtocolBuffers/ProtocolBuffersLite.csproj b/src/ProtocolBuffers/ProtocolBuffersLite.csproj index d3d60b24..888791dd 100644 --- a/src/ProtocolBuffers/ProtocolBuffersLite.csproj +++ b/src/ProtocolBuffers/ProtocolBuffersLite.csproj @@ -58,11 +58,16 @@ + + + + + diff --git a/src/ProtocolBuffers/UninitializedMessageException.cs b/src/ProtocolBuffers/UninitializedMessageException.cs index d98987a1..12db07df 100644 --- a/src/ProtocolBuffers/UninitializedMessageException.cs +++ b/src/ProtocolBuffers/UninitializedMessageException.cs @@ -53,8 +53,6 @@ namespace Google.ProtocolBuffers { : base(BuildDescription(missingFields)) { this.missingFields = new List(missingFields); } - - /// /// Returns a read-only list of human-readable names of /// required fields missing from this message. Each name @@ -90,6 +88,14 @@ namespace Google.ProtocolBuffers { return description.ToString(); } + /// + /// For Lite exceptions that do not known how to enumerate missing fields + /// + public UninitializedMessageException(IMessageLite message) + : base(String.Format("Message {0} is missing required fields", message.GetType())) { + missingFields = new List(); + } + #if !LITE public UninitializedMessageException(IMessage message) : this(FindMissingFields(message)) { -- cgit v1.2.3