Commit aa510414 authored by Jon Skeet's avatar Jon Skeet

Remove a lot of code which wasn't needed any more.

parent e75a10d8
......@@ -147,17 +147,14 @@ namespace Google.Protobuf
Assert.AreEqual(messageType, primitiveField.ContainingType);
Assert.AreEqual(UnittestProto3.Descriptor, primitiveField.File);
Assert.AreEqual(FieldType.Int32, primitiveField.FieldType);
Assert.AreEqual(MappedType.Int32, primitiveField.MappedType);
Assert.IsNull(primitiveField.Options);
Assert.AreEqual("single_nested_enum", enumField.Name);
Assert.AreEqual(FieldType.Enum, enumField.FieldType);
Assert.AreEqual(MappedType.Enum, enumField.MappedType);
// Assert.AreEqual(TestAllTypes.Types.NestedEnum.DescriptorProtoFile, enumField.EnumType);
Assert.AreEqual("single_foreign_message", messageField.Name);
Assert.AreEqual(FieldType.Message, messageField.FieldType);
Assert.AreEqual(MappedType.Message, messageField.MappedType);
Assert.AreEqual(ForeignMessage.Descriptor, messageField.MessageType);
}
......@@ -169,9 +166,7 @@ namespace Google.Protobuf
FieldDescriptor repeatedField =
TestAllTypes.Descriptor.FindDescriptor<FieldDescriptor>("repeated_int32");
Assert.IsFalse(singleField.IsRequired);
Assert.IsFalse(singleField.IsRepeated);
Assert.IsFalse(repeatedField.IsRequired);
Assert.IsTrue(repeatedField.IsRepeated);
}
......
......@@ -89,7 +89,6 @@
<Compile Include="IssuesTest.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="TestCornerCases.cs" />
<Compile Include="WireFormatTest.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\ProtocolBuffers\ProtocolBuffers.csproj">
......
#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.Reflection;
using Google.Protobuf.Descriptors;
using NUnit.Framework;
namespace Google.Protobuf
{
public class WireFormatTest
{
/// <summary>
/// Keeps the attributes on FieldType and the switch statement in WireFormat in sync.
/// </summary>
[Test]
public void FieldTypeToWireTypeMapping()
{
foreach (FieldInfo field in typeof(FieldType).GetFields(BindingFlags.Static | BindingFlags.Public))
{
FieldType fieldType = (FieldType) field.GetValue(null);
FieldMappingAttribute mapping =
(FieldMappingAttribute) field.GetCustomAttributes(typeof(FieldMappingAttribute), false)[0];
Assert.AreEqual(mapping.WireType, WireFormat.GetWireType(fieldType));
}
}
}
}
\ No newline at end of file
......@@ -59,19 +59,11 @@ namespace Google.Protobuf
}
else
{
ByteCopy(src, srcOffset, dst, dstOffset, count);
}
}
/// <summary>
/// Copy the bytes provided with a for loop, faster when there are only a few bytes to copy
/// </summary>
internal static void ByteCopy(byte[] src, int srcOffset, byte[] dst, int dstOffset, int count)
{
int stop = srcOffset + count;
for (int i = srcOffset; i < stop; i++)
{
dst[dstOffset++] = src[i];
int stop = srcOffset + count;
for (int i = srcOffset; i < stop; i++)
{
dst[dstOffset++] = src[i];
}
}
}
......
......@@ -264,38 +264,6 @@ namespace Google.Protobuf
return true;
}
/// <summary>
/// Builder for ByteStrings which allows them to be created without extra
/// copying being involved. This has to be a nested type in order to have access
/// to the private ByteString constructor.
/// </summary>
internal sealed class CodedBuilder
{
private readonly CodedOutputStream output;
private readonly byte[] buffer;
internal CodedBuilder(int size)
{
buffer = new byte[size];
output = CodedOutputStream.CreateInstance(buffer);
}
internal ByteString Build()
{
output.CheckNoSpaceLeft();
// We can be confident that the CodedOutputStream will not modify the
// underlying bytes anymore because it already wrote all of them. So,
// no need to make a copy.
return new ByteString(buffer);
}
internal CodedOutputStream CodedOutput
{
get { return output; }
}
}
/// <summary>
/// Used internally by CodedOutputStream to avoid creating a copy for the write
/// </summary>
......
// 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.
using System;
using System.Collections;
using System.Collections.Generic;
namespace Google.Protobuf.Collections
{
/// <summary>
/// Utility class for dictionaries.
/// </summary>
public static class Dictionaries
{
/// <summary>
/// Compares two dictionaries for equality. Each value is compared with equality using Equals
/// for non-IEnumerable implementations, and using EnumerableEquals otherwise.
/// TODO(jonskeet): This is clearly pretty slow, and involves lots of boxing/unboxing...
/// </summary>
public static bool Equals<TKey, TValue>(IDictionary<TKey, TValue> left, IDictionary<TKey, TValue> right)
{
if (left.Count != right.Count)
{
return false;
}
foreach (KeyValuePair<TKey, TValue> leftEntry in left)
{
TValue rightValue;
if (!right.TryGetValue(leftEntry.Key, out rightValue))
{
return false;
}
IEnumerable leftEnumerable = leftEntry.Value as IEnumerable;
IEnumerable rightEnumerable = rightValue as IEnumerable;
if (leftEnumerable == null || rightEnumerable == null)
{
if (!Equals(leftEntry.Value, rightValue))
{
return false;
}
}
else
{
if (!Enumerables.Equals(leftEnumerable, rightEnumerable))
{
return false;
}
}
}
return true;
}
public static IDictionary<TKey, TValue> AsReadOnly<TKey, TValue>(IDictionary<TKey, TValue> dictionary)
{
return dictionary.IsReadOnly ? dictionary : new ReadOnlyDictionary<TKey, TValue>(dictionary);
}
/// <summary>
/// Creates a hashcode for a dictionary by XORing the hashcodes of all the fields
/// and values. (By XORing, we avoid ordering issues.)
/// TODO(jonskeet): Currently XORs other stuff too, and assumes non-null values.
/// </summary>
public static int GetHashCode<TKey, TValue>(IDictionary<TKey, TValue> dictionary)
{
int ret = 31;
foreach (KeyValuePair<TKey, TValue> entry in dictionary)
{
int hash = entry.Key.GetHashCode() ^ GetDeepHashCode(entry.Value);
ret ^= hash;
}
return ret;
}
/// <summary>
/// Determines the hash of a value by either taking it directly or hashing all the elements
/// for IEnumerable implementations.
/// </summary>
private static int GetDeepHashCode(object value)
{
IEnumerable iterable = value as IEnumerable;
if (iterable == null)
{
return value.GetHashCode();
}
int hash = 29;
foreach (object element in iterable)
{
hash = hash*37 + element.GetHashCode();
}
return hash;
}
}
}
\ No newline at end of file
// 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.
using System;
using System.Collections;
namespace Google.Protobuf.Collections
{
/// <summary>
/// Utility class for IEnumerable (and potentially the generic version in the future).
/// </summary>
public static class Enumerables
{
public static bool Equals(IEnumerable left, IEnumerable right)
{
IEnumerator leftEnumerator = left.GetEnumerator();
try
{
foreach (object rightObject in right)
{
if (!leftEnumerator.MoveNext())
{
return false;
}
if (!Equals(leftEnumerator.Current, rightObject))
{
return false;
}
}
if (leftEnumerator.MoveNext())
{
return false;
}
}
finally
{
IDisposable leftEnumeratorDisposable = leftEnumerator as IDisposable;
if (leftEnumeratorDisposable != null)
{
leftEnumeratorDisposable.Dispose();
}
}
return true;
}
}
}
\ No newline at end of file
// 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.
using System.Collections.Generic;
using System.Collections.ObjectModel;
namespace Google.Protobuf.Collections
{
/// <summary>
/// Utility non-generic class for calling into Lists{T} using type inference.
/// </summary>
public static class Lists
{
/// <summary>
/// Returns a read-only view of the specified list.
/// </summary>
public static IList<T> AsReadOnly<T>(IList<T> list)
{
return Lists<T>.AsReadOnly(list);
}
public static bool Equals<T>(IList<T> left, IList<T> right)
{
if (left == right)
{
return true;
}
if (left == null || right == null)
{
return false;
}
if (left.Count != right.Count)
{
return false;
}
IEqualityComparer<T> comparer = EqualityComparer<T>.Default;
for (int i = 0; i < left.Count; i++)
{
if (!comparer.Equals(left[i], right[i]))
{
return false;
}
}
return true;
}
public static int GetHashCode<T>(IList<T> list)
{
int hash = 31;
foreach (T element in list)
{
hash = hash*29 + element.GetHashCode();
}
return hash;
}
}
/// <summary>
/// Utility class for dealing with lists.
/// </summary>
public static class Lists<T>
{
private static readonly ReadOnlyCollection<T> empty = new ReadOnlyCollection<T>(new T[0]);
/// <summary>
/// Returns an immutable empty list.
/// </summary>
public static ReadOnlyCollection<T> Empty
{
get { return empty; }
}
/// <summary>
/// Returns either the original reference if it's already read-only,
/// or a new ReadOnlyCollection wrapping the original list.
/// </summary>
public static IList<T> AsReadOnly(IList<T> list)
{
return list.IsReadOnly ? list : new ReadOnlyCollection<T>(list);
}
}
}
\ No newline at end of file
......@@ -298,6 +298,16 @@ namespace Google.Protobuf.Collections
}
}
internal uint CalculateSize(Func<T, int> sizeComputer)
{
int size = 0;
for (int i = 0; i < count; i++)
{
size += sizeComputer(array[i]);
}
return (uint)size;
}
public struct Enumerator : IEnumerator<T>
{
private int index;
......
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Google.Protobuf.Collections
{
public static class RepeatedFieldExtensions
{
internal static uint CalculateSize<T>(this RepeatedField<T> list, Func<T, int> sizeComputer)
{
int size = 0;
foreach (var item in list)
{
size += sizeComputer(item);
}
return (uint)size;
}
/*
/// <summary>
/// Calculates the serialized data size, including one tag per value.
/// </summary>
public static int CalculateTotalSize<T>(this RepeatedField<T> list, int tagSize, Func<T, int> sizeComputer)
{
if (list.Count == 0)
{
return 0;
}
return (int)(dataSize + tagSize * list.Count);
}
/// <summary>
/// Calculates the serialized data size, as a packed array (tag, length, data).
/// </summary>
public static int CalculateTotalPackedSize(int tagSize)
{
if (Count == 0)
{
return 0;
}
uint dataSize = CalculateSize();
return tagSize + CodedOutputStream.ComputeRawVarint32Size(dataSize) + (int)dataSize;
}
*/
}
}
......@@ -30,7 +30,7 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
using System.Collections.Generic;
using Google.Protobuf.Collections;
using System.Collections.ObjectModel;
namespace Google.Protobuf.Descriptors
{
......@@ -58,7 +58,7 @@ namespace Google.Protobuf.Descriptors
{
array[i] = converter(input[i], i);
}
return Lists<TOutput>.AsReadOnly(array);
return new ReadOnlyCollection<TOutput>(array);
}
}
}
\ No newline at end of file
// 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.
using System;
using System.Collections.Generic;
using System.Reflection;
using Google.Protobuf.Collections;
namespace Google.Protobuf.Descriptors
{
/// <summary>
/// Defined specifically for the <see cref="FieldType" /> enumeration,
/// this allows each field type to specify the mapped type and wire type.
/// </summary>
[AttributeUsage(AttributeTargets.Field)]
public sealed class FieldMappingAttribute : Attribute
{
public FieldMappingAttribute(MappedType mappedType, WireFormat.WireType wireType)
{
MappedType = mappedType;
WireType = wireType;
}
public MappedType MappedType { get; private set; }
public WireFormat.WireType WireType { get; private set; }
/// <summary>
/// Immutable mapping from field type to mapped type. Built using the attributes on
/// FieldType values.
/// </summary>
private static readonly IDictionary<FieldType, FieldMappingAttribute> FieldTypeToMappedTypeMap = MapFieldTypes();
private static IDictionary<FieldType, FieldMappingAttribute> MapFieldTypes()
{
var map = new Dictionary<FieldType, FieldMappingAttribute>();
foreach (FieldInfo field in typeof(FieldType).GetFields(BindingFlags.Static | BindingFlags.Public))
{
FieldType fieldType = (FieldType) field.GetValue(null);
FieldMappingAttribute mapping =
(FieldMappingAttribute) field.GetCustomAttributes(typeof(FieldMappingAttribute), false)[0];
map[fieldType] = mapping;
}
return Dictionaries.AsReadOnly(map);
}
internal static MappedType MappedTypeFromFieldType(FieldType type)
{
return FieldTypeToMappedTypeMap[type].MappedType;
}
internal static WireFormat.WireType WireTypeFromFieldType(FieldType type, bool packed)
{
return packed ? WireFormat.WireType.LengthDelimited : FieldTypeToMappedTypeMap[type].WireType;
}
}
}
\ No newline at end of file
......@@ -38,23 +38,23 @@ namespace Google.Protobuf.Descriptors
/// </summary>
public enum FieldType
{
[FieldMapping(MappedType.Double, WireFormat.WireType.Fixed64)] Double,
[FieldMapping(MappedType.Single, WireFormat.WireType.Fixed32)] Float,
[FieldMapping(MappedType.Int64, WireFormat.WireType.Varint)] Int64,
[FieldMapping(MappedType.UInt64, WireFormat.WireType.Varint)] UInt64,
[FieldMapping(MappedType.Int32, WireFormat.WireType.Varint)] Int32,
[FieldMapping(MappedType.UInt64, WireFormat.WireType.Fixed64)] Fixed64,
[FieldMapping(MappedType.UInt32, WireFormat.WireType.Fixed32)] Fixed32,
[FieldMapping(MappedType.Boolean, WireFormat.WireType.Varint)] Bool,
[FieldMapping(MappedType.String, WireFormat.WireType.LengthDelimited)] String,
[FieldMapping(MappedType.Message, WireFormat.WireType.StartGroup)] Group,
[FieldMapping(MappedType.Message, WireFormat.WireType.LengthDelimited)] Message,
[FieldMapping(MappedType.ByteString, WireFormat.WireType.LengthDelimited)] Bytes,
[FieldMapping(MappedType.UInt32, WireFormat.WireType.Varint)] UInt32,
[FieldMapping(MappedType.Int32, WireFormat.WireType.Fixed32)] SFixed32,
[FieldMapping(MappedType.Int64, WireFormat.WireType.Fixed64)] SFixed64,
[FieldMapping(MappedType.Int32, WireFormat.WireType.Varint)] SInt32,
[FieldMapping(MappedType.Int64, WireFormat.WireType.Varint)] SInt64,
[FieldMapping(MappedType.Enum, WireFormat.WireType.Varint)] Enum
Double,
Float,
Int64,
UInt64,
Int32,
Fixed64,
Fixed32,
Bool,
String,
Group,
Message,
Bytes,
UInt32,
SFixed32,
SFixed64,
SInt32,
SInt64,
Enum
}
}
\ No newline at end of file
......@@ -45,11 +45,10 @@ namespace Google.Protobuf.Descriptors
/// </summary>
public sealed class FileDescriptor : IDescriptor<FileDescriptorProto>
{
private FileDescriptorProto proto;
private readonly FileDescriptorProto proto;
private readonly IList<MessageDescriptor> messageTypes;
private readonly IList<EnumDescriptor> enumTypes;
private readonly IList<ServiceDescriptor> services;
private readonly IList<FieldDescriptor> extensions;
private readonly IList<FileDescriptor> dependencies;
private readonly IList<FileDescriptor> publicDependencies;
private readonly DescriptorPool pool;
......@@ -86,10 +85,6 @@ namespace Google.Protobuf.Descriptors
services = DescriptorUtil.ConvertAndMakeReadOnly(proto.Service,
(service, index) =>
new ServiceDescriptor(service, this, index));
extensions = DescriptorUtil.ConvertAndMakeReadOnly(proto.Extension,
(field, index) =>
new FieldDescriptor(field, this, null, index, true));
}
/// <summary>
......@@ -129,9 +124,6 @@ namespace Google.Protobuf.Descriptors
return new ReadOnlyCollection<FileDescriptor>(publicDependencies);
}
static readonly char[] PathSeperators = new char[] { '/', '\\' };
/// <value>
/// The descriptor in its protocol message representation.
/// </value>
......@@ -189,14 +181,6 @@ namespace Google.Protobuf.Descriptors
get { return services; }
}
/// <value>
/// Unmodifiable list of top-level extensions declared in this file.
/// </value>
public IList<FieldDescriptor> Extensions
{
get { return extensions; }
}
/// <value>
/// Unmodifiable list of this file's dependencies (imports).
/// </value>
......@@ -350,16 +334,6 @@ namespace Google.Protobuf.Descriptors
{
service.CrossLink();
}
foreach (FieldDescriptor extension in extensions)
{
extension.CrossLink();
}
foreach (MessageDescriptor message in messageTypes)
{
message.CheckRequiredFields();
}
}
/// <summary>
......@@ -415,42 +389,7 @@ namespace Google.Protobuf.Descriptors
descriptorAssigner(result);
return result;
}
/// <summary>
/// Replace our FileDescriptorProto with the given one, which is
/// identical except that it might contain extensions that weren't present
/// in the original. This method is needed for bootstrapping when a file
/// defines custom options. The options may be defined in the file itself,
/// so we can't actually parse them until we've constructed the descriptors,
/// but to construct the decsriptors we have to have parsed the descriptor
/// protos. So, we have to parse the descriptor protos a second time after
/// constructing the descriptors.
/// </summary>
private void ReplaceProto(FileDescriptorProto newProto)
{
proto = newProto;
for (int i = 0; i < messageTypes.Count; i++)
{
messageTypes[i].ReplaceProto(proto.MessageType[i]);
}
for (int i = 0; i < enumTypes.Count; i++)
{
enumTypes[i].ReplaceProto(proto.EnumType[i]);
}
for (int i = 0; i < services.Count; i++)
{
services[i].ReplaceProto(proto.Service[i]);
}
for (int i = 0; i < extensions.Count; i++)
{
extensions[i].ReplaceProto(proto.Extension[i]);
}
}
public override string ToString()
{
return "FileDescriptor for " + proto.Name;
......
// 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.
namespace Google.Protobuf.Descriptors
{
/// <summary>
/// Type as it's mapped onto a .NET type.
/// </summary>
public enum MappedType
{
Int32,
Int64,
UInt32,
UInt64,
Single,
Double,
Boolean,
String,
ByteString,
Message,
Enum
}
}
\ No newline at end of file
......@@ -44,10 +44,8 @@ namespace Google.Protobuf.Descriptors
private readonly IList<MessageDescriptor> nestedTypes;
private readonly IList<EnumDescriptor> enumTypes;
private readonly IList<FieldDescriptor> fields;
private readonly IList<FieldDescriptor> extensions;
private readonly IList<OneofDescriptor> oneofs;
private bool hasRequiredFields;
internal MessageDescriptor(DescriptorProto proto, FileDescriptor file, MessageDescriptor parent, int typeIndex)
: base(proto, file, ComputeFullName(file, parent, proto.Name), typeIndex)
{
......@@ -68,11 +66,7 @@ namespace Google.Protobuf.Descriptors
// TODO(jonskeet): Sort fields first?
fields = DescriptorUtil.ConvertAndMakeReadOnly(proto.Field,
(field, index) =>
new FieldDescriptor(field, file, this, index, false));
extensions = DescriptorUtil.ConvertAndMakeReadOnly(proto.Extension,
(field, index) =>
new FieldDescriptor(field, file, this, index, true));
new FieldDescriptor(field, file, this, index));
for (int i = 0; i < proto.OneofDecl.Count; i++)
{
......@@ -106,14 +100,6 @@ namespace Google.Protobuf.Descriptors
get { return fields; }
}
/// <value>
/// An unmodifiable list of this message type's extensions.
/// </value>
public IList<FieldDescriptor> Extensions
{
get { return extensions; }
}
/// <value>
/// An unmodifiable list of this message type's nested types.
/// </value>
......@@ -135,32 +121,6 @@ namespace Google.Protobuf.Descriptors
get { return oneofs; }
}
/// <summary>
/// Returns a pre-computed result as to whether this message
/// has required fields. This includes optional fields which are
/// message types which in turn have required fields, and any
/// extension fields.
/// </summary>
internal bool HasRequiredFields
{
get { return hasRequiredFields; }
}
/// <summary>
/// Determines if the given field number is an extension.
/// </summary>
public bool IsExtensionNumber(int number)
{
foreach (DescriptorProto.Types.ExtensionRange range in Proto.ExtensionRange)
{
if (range.Start <= number && number < range.End)
{
return true;
}
}
return false;
}
/// <summary>
/// Finds a field by field name.
/// </summary>
......@@ -194,7 +154,7 @@ namespace Google.Protobuf.Descriptors
}
/// <summary>
/// Looks up and cross-links all fields, nested types, and extensions.
/// Looks up and cross-links all fields and nested types.
/// </summary>
internal void CrossLink()
{
......@@ -208,62 +168,11 @@ namespace Google.Protobuf.Descriptors
field.CrossLink();
}
foreach (FieldDescriptor extension in extensions)
{
extension.CrossLink();
}
foreach (OneofDescriptor oneof in oneofs)
{
// oneof.C
}
}
internal void CheckRequiredFields()
{
IDictionary<MessageDescriptor, byte> alreadySeen = new Dictionary<MessageDescriptor, byte>();
hasRequiredFields = CheckRequiredFields(alreadySeen);
}
private bool CheckRequiredFields(IDictionary<MessageDescriptor, byte> alreadySeen)
{
if (alreadySeen.ContainsKey(this))
{
// The type is already in the cache. This means that either:
// a. The type has no required fields.
// b. We are in the midst of checking if the type has required fields,
// somewhere up the stack. In this case, we know that if the type
// has any required fields, they'll be found when we return to it,
// and the whole call to HasRequiredFields() will return true.
// Therefore, we don't have to check if this type has required fields
// here.
return false;
}
alreadySeen[this] = 0; // Value is irrelevant; we want set semantics
// If the type allows extensions, an extension with message type could contain
// required fields, so we have to be conservative and assume such an
// extension exists.
if (Proto.ExtensionRange.Count != 0)
{
return true;
// TODO(jonskeet): Do we need to do this?
// oneof.C
}
foreach (FieldDescriptor field in Fields)
{
if (field.IsRequired)
{
return true;
}
if (field.MappedType == MappedType.Message)
{
if (field.MessageType.CheckRequiredFields(alreadySeen))
{
return true;
}
}
}
return false;
}
/// <summary>
......@@ -287,11 +196,6 @@ namespace Google.Protobuf.Descriptors
{
fields[i].ReplaceProto(newProto.Field[i]);
}
for (int i = 0; i < extensions.Count; i++)
{
extensions[i].ReplaceProto(newProto.Extension[i]);
}
}
}
}
\ No newline at end of file
......@@ -69,7 +69,6 @@ namespace Google.Protobuf.FieldAccess
get
{
FieldDescriptor field = descriptor.FindFieldByNumber(fieldNumber);
// TODO: Handle extensions.
return accessors[field.Index];
}
}
......@@ -82,12 +81,6 @@ namespace Google.Protobuf.FieldAccess
{
throw new ArgumentException("FieldDescriptor does not match message type.");
}
else if (field.IsExtension)
{
// If this type had extensions, it would subclass ExtendableMessage,
// which overrides the reflection interface to handle extensions.
throw new ArgumentException("This type does not have extensions.");
}
return accessors[field.Index];
}
}
......
......@@ -54,16 +54,12 @@
<ItemGroup>
<Compile Include="ByteArray.cs" />
<Compile Include="ByteString.cs" />
<Compile Include="Collections\Enumerables.cs" />
<Compile Include="CodedOutputStream.ComputeSize.cs" />
<Compile Include="CodedInputStream.cs" />
<Compile Include="CodedOutputStream.cs" />
<Compile Include="Collections\Dictionaries.cs" />
<Compile Include="Collections\Lists.cs" />
<Compile Include="Collections\MapField.cs" />
<Compile Include="Collections\ReadOnlyDictionary.cs" />
<Compile Include="Collections\RepeatedField.cs" />
<Compile Include="Collections\RepeatedFieldExtensions.cs" />
<Compile Include="DescriptorProtos\DescriptorProtoFile.cs" />
<Compile Include="DescriptorProtos\IDescriptorProto.cs" />
<Compile Include="DescriptorProtos\PartialClasses.cs" />
......@@ -74,13 +70,11 @@
<Compile Include="Descriptors\EnumDescriptor.cs" />
<Compile Include="Descriptors\EnumValueDescriptor.cs" />
<Compile Include="Descriptors\FieldDescriptor.cs" />
<Compile Include="Descriptors\FieldMappingAttribute.cs" />
<Compile Include="Descriptors\FieldType.cs" />
<Compile Include="Descriptors\FileDescriptor.cs" />
<Compile Include="Descriptors\OneofDescriptor.cs" />
<Compile Include="Descriptors\IDescriptor.cs" />
<Compile Include="Descriptors\IndexedDescriptorBase.cs" />
<Compile Include="Descriptors\MappedType.cs" />
<Compile Include="Descriptors\MessageDescriptor.cs" />
<Compile Include="Descriptors\MethodDescriptor.cs" />
<Compile Include="Descriptors\PackageDescriptor.cs" />
......@@ -101,7 +95,6 @@
<Compile Include="LimitedInputStream.cs" />
<Compile Include="MessageParser.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="TextGenerator.cs" />
<Compile Include="ThrowHelper.cs" />
<Compile Include="WireFormat.cs" />
</ItemGroup>
......
#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.IO;
using System.Text;
namespace Google.Protobuf
{
/// <summary>
/// Helper class to control indentation. Used for TextFormat and by ProtoGen.
/// </summary>
public sealed class TextGenerator
{
/// <summary>
/// The string to use at the end of each line. We assume that "Print" is only called using \n
/// to indicate a line break; that's what we use to detect when we need to indent etc, and
/// *just* the \n is replaced with the contents of lineBreak.
/// </summary>
private readonly string lineBreak;
/// <summary>
/// Writer to write formatted text to.
/// </summary>
private readonly TextWriter writer;
/// <summary>
/// Keeps track of whether the next piece of text should be indented
/// </summary>
private bool atStartOfLine = true;
/// <summary>
/// Keeps track of the current level of indentation
/// </summary>
private readonly StringBuilder indent = new StringBuilder();
/// <summary>
/// Creates a generator writing to the given writer. The writer
/// is not closed by this class.
/// </summary>
public TextGenerator(TextWriter writer, string lineBreak)
{
this.writer = writer;
this.lineBreak = lineBreak;
}
/// <summary>
/// Indents text by two spaces. After calling Indent(), two spaces
/// will be inserted at the beginning of each line of text. Indent() may
/// be called multiple times to produce deeper indents.
/// </summary>
public void Indent()
{
indent.Append(" ");
}
/// <summary>
/// Reduces the current indent level by two spaces.
/// </summary>
public void Outdent()
{
if (indent.Length == 0)
{
throw new InvalidOperationException("Too many calls to Outdent()");
}
indent.Length -= 2;
}
public void WriteLine(string text)
{
Print(text);
Print("\n");
}
public void WriteLine(string format, params object[] args)
{
WriteLine(string.Format(format, args));
}
public void WriteLine()
{
WriteLine("");
}
/// <summary>
/// Prints the given text to the output stream, indenting at line boundaries.
/// </summary>
/// <param name="text"></param>
public void Print(string text)
{
int pos = 0;
for (int i = 0; i < text.Length; i++)
{
if (text[i] == '\n')
{
// Strip off the \n from what we write
Write(text.Substring(pos, i - pos));
Write(lineBreak);
pos = i + 1;
atStartOfLine = true;
}
}
Write(text.Substring(pos));
}
public void Write(string format, params object[] args)
{
Write(string.Format(format, args));
}
private void Write(string data)
{
if (data.Length == 0)
{
return;
}
if (atStartOfLine)
{
atStartOfLine = false;
writer.Write(indent);
}
writer.Write(data);
}
}
}
\ No newline at end of file
......@@ -35,7 +35,6 @@
#endregion
using System;
using System.Collections.Generic;
namespace Google.Protobuf
{
......@@ -54,30 +53,5 @@ namespace Google.Protobuf
throw new ArgumentNullException(name);
}
}
/// <summary>
/// Throws an ArgumentNullException if the given value is null.
/// </summary>
internal static void ThrowIfNull(object value)
{
if (value == null)
{
throw new ArgumentNullException();
}
}
/// <summary>
/// Throws an ArgumentNullException if the given value or any element within it is null.
/// </summary>
internal static void ThrowIfAnyNull<T>(IEnumerable<T> sequence)
{
foreach (T t in sequence)
{
if (t == null)
{
throw new ArgumentNullException();
}
}
}
}
}
\ No newline at end of file
......@@ -114,7 +114,6 @@ namespace Google.Protobuf
/// <summary>
/// Makes a tag value given a field number and wire type.
/// TODO(jonskeet): Should we just have a Tag structure?
/// </summary>
public static uint MakeTag(int fieldNumber, WireType wireType)
{
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment