From d9c59e66131b34833f04c591fa8fe8719afa0b47 Mon Sep 17 00:00:00 2001 From: csharptest Date: Thu, 4 Nov 2010 19:36:28 -0500 Subject: [PATCH] First pass at interface breakup --- src/ProtoGen/UmbrellaClassGenerator.cs | 4 - src/ProtocolBuffers.sln | 8 ++ src/ProtocolBuffers/AbstractBuilder.cs | 80 +++++++++-- src/ProtocolBuffers/AbstractMessage.cs | 11 ++ src/ProtocolBuffers/CodedInputStream.cs | 18 ++- src/ProtocolBuffers/CodedOutputStream.cs | 36 +++-- src/ProtocolBuffers/DynamicMessage.cs | 2 +- src/ProtocolBuffers/ExtensionInfo.cs | 18 ++- src/ProtocolBuffers/ExtensionRegistry.cs | 58 ++------ src/ProtocolBuffers/ExtensionRegistryLite.cs | 130 +++++------------ src/ProtocolBuffers/GeneratedExtensionBase.cs | 5 + src/ProtocolBuffers/GeneratedExtensionLite.cs | 24 ++++ src/ProtocolBuffers/IBuilder.cs | 62 ++++---- src/ProtocolBuffers/IBuilderLite.cs | 134 +++--------------- src/ProtocolBuffers/IMessage.cs | 38 ++--- src/ProtocolBuffers/IMessageLite.cs | 78 ++-------- src/ProtocolBuffers/ProtocolBuffers.csproj | 10 +- .../UninitializedMessageException.cs | 14 +- src/ProtocolBuffers/UnknownField.cs | 4 + src/ProtocolBuffers/UnknownFieldSet.cs | 94 +++++++++++- src/ProtocolBuffers/WireFormat.cs | 4 + 21 files changed, 410 insertions(+), 422 deletions(-) create mode 100644 src/ProtocolBuffers/GeneratedExtensionLite.cs diff --git a/src/ProtoGen/UmbrellaClassGenerator.cs b/src/ProtoGen/UmbrellaClassGenerator.cs index cdc275c68c..6f987048e7 100644 --- a/src/ProtoGen/UmbrellaClassGenerator.cs +++ b/src/ProtoGen/UmbrellaClassGenerator.cs @@ -74,10 +74,6 @@ namespace Google.ProtocolBuffers.ProtoGen { return false; } - public string UmbrellaClassName { - get { throw new NotImplementedException(); } - } - public void Generate(TextGenerator writer) { WriteIntroduction(writer); WriteExtensionRegistration(writer); diff --git a/src/ProtocolBuffers.sln b/src/ProtocolBuffers.sln index 3ad5dc2542..50d4375a08 100644 --- a/src/ProtocolBuffers.sln +++ b/src/ProtocolBuffers.sln @@ -25,6 +25,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "proto", "proto", "{1F896D5C ..\todo.txt = ..\todo.txt EndProjectSection EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ProtocolBuffersLite", "ProtocolBuffers\ProtocolBuffersLite.csproj", "{6969BDCE-D925-43F3-94AC-A531E6DF2591}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -80,6 +82,12 @@ Global {D7282E99-2DC3-405B-946F-177DB2FD2AE2}.Release|Any CPU.Build.0 = Release|Any CPU {D7282E99-2DC3-405B-946F-177DB2FD2AE2}.Silverlight2|Any CPU.ActiveCfg = Silverlight2|Any CPU {D7282E99-2DC3-405B-946F-177DB2FD2AE2}.Silverlight2|Any CPU.Build.0 = Silverlight2|Any CPU + {6969BDCE-D925-43F3-94AC-A531E6DF2591}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {6969BDCE-D925-43F3-94AC-A531E6DF2591}.Debug|Any CPU.Build.0 = Debug|Any CPU + {6969BDCE-D925-43F3-94AC-A531E6DF2591}.Release|Any CPU.ActiveCfg = Release|Any CPU + {6969BDCE-D925-43F3-94AC-A531E6DF2591}.Release|Any CPU.Build.0 = Release|Any CPU + {6969BDCE-D925-43F3-94AC-A531E6DF2591}.Silverlight2|Any CPU.ActiveCfg = Silverlight2|Any CPU + {6969BDCE-D925-43F3-94AC-A531E6DF2591}.Silverlight2|Any CPU.Build.0 = Silverlight2|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/src/ProtocolBuffers/AbstractBuilder.cs b/src/ProtocolBuffers/AbstractBuilder.cs index a60ff0aaf2..2ba9855a5f 100644 --- a/src/ProtocolBuffers/AbstractBuilder.cs +++ b/src/ProtocolBuffers/AbstractBuilder.cs @@ -88,7 +88,7 @@ namespace Google.ProtocolBuffers { return MergeFrom(input); } - public IBuilder WeakMergeFrom(CodedInputStream input, ExtensionRegistry registry) { + public IBuilder WeakMergeFrom(CodedInputStream input, ExtensionRegistryLite registry) { return MergeFrom(input, registry); } @@ -96,7 +96,7 @@ namespace Google.ProtocolBuffers { return MergeFrom(data); } - public IBuilder WeakMergeFrom(ByteString data, ExtensionRegistry registry) { + public IBuilder WeakMergeFrom(ByteString data, ExtensionRegistryLite registry) { return MergeFrom(data, registry); } @@ -173,6 +173,10 @@ namespace Google.ProtocolBuffers { } public virtual TBuilder MergeFrom(CodedInputStream input, ExtensionRegistry extensionRegistry) { + return MergeFrom(input, (ExtensionRegistryLite)extensionRegistry); + } + + public virtual TBuilder MergeFrom(CodedInputStream input, ExtensionRegistryLite extensionRegistry) { UnknownFieldSet.Builder unknownFields = UnknownFieldSet.CreateBuilder(UnknownFields); unknownFields.MergeFrom(input, extensionRegistry, this); UnknownFields = unknownFields.Build(); @@ -194,6 +198,10 @@ namespace Google.ProtocolBuffers { } public virtual TBuilder MergeFrom(ByteString data, ExtensionRegistry extensionRegistry) { + return MergeFrom(data, (ExtensionRegistryLite)extensionRegistry); + } + + public virtual TBuilder MergeFrom(ByteString data, ExtensionRegistryLite extensionRegistry) { CodedInputStream input = data.CreateCodedInput(); MergeFrom(input, extensionRegistry); input.CheckLastTagWas(0); @@ -208,6 +216,10 @@ namespace Google.ProtocolBuffers { } public virtual TBuilder MergeFrom(byte[] data, ExtensionRegistry extensionRegistry) { + return MergeFrom(data, (ExtensionRegistryLite)extensionRegistry); + } + + public virtual TBuilder MergeFrom(byte[] data, ExtensionRegistryLite extensionRegistry) { CodedInputStream input = CodedInputStream.CreateInstance(data); MergeFrom(input, extensionRegistry); input.CheckLastTagWas(0); @@ -222,6 +234,10 @@ namespace Google.ProtocolBuffers { } public virtual TBuilder MergeFrom(Stream input, ExtensionRegistry extensionRegistry) { + return MergeFrom(input, (ExtensionRegistryLite)extensionRegistry); + } + + public virtual TBuilder MergeFrom(Stream input, ExtensionRegistryLite extensionRegistry) { CodedInputStream codedInput = CodedInputStream.CreateInstance(input); MergeFrom(codedInput, extensionRegistry); codedInput.CheckLastTagWas(0); @@ -229,6 +245,10 @@ namespace Google.ProtocolBuffers { } public TBuilder MergeDelimitedFrom(Stream input, ExtensionRegistry extensionRegistry) { + return MergeDelimitedFrom(input, (ExtensionRegistryLite)extensionRegistry); + } + + public TBuilder MergeDelimitedFrom(Stream input, ExtensionRegistryLite extensionRegistry) { int size = (int) CodedInputStream.ReadRawVarint32(input); Stream limitedStream = new LimitedInputStream(input, size); return MergeFrom(limitedStream, extensionRegistry); @@ -279,15 +299,15 @@ namespace Google.ProtocolBuffers { } public override long Length { - get { throw new NotImplementedException(); } + get { throw new NotSupportedException(); } } public override long Position { get { - throw new NotImplementedException(); + throw new NotSupportedException(); } set { - throw new NotImplementedException(); + throw new NotSupportedException(); } } @@ -301,16 +321,60 @@ namespace Google.ProtocolBuffers { } public override long Seek(long offset, SeekOrigin origin) { - throw new NotImplementedException(); + throw new NotSupportedException(); } public override void SetLength(long value) { - throw new NotImplementedException(); + throw new NotSupportedException(); } public override void Write(byte[] buffer, int offset, int count) { - throw new NotImplementedException(); + throw new NotSupportedException(); } } + + IBuilderLite IBuilderLite.WeakClear() { + return WeakClear(); + } + + public IBuilderLite WeakMergeFrom(IMessageLite message) { + return MergeFrom(message); + } + + IBuilderLite IBuilderLite.WeakMergeFrom(ByteString data) { + return WeakMergeFrom(data); + } + + IBuilderLite IBuilderLite.WeakMergeFrom(ByteString data, ExtensionRegistryLite registry) { + throw new NotImplementedException(); + } + + IBuilderLite IBuilderLite.WeakMergeFrom(CodedInputStream input) { + return WeakMergeFrom(input); + } + + IBuilderLite IBuilderLite.WeakMergeFrom(CodedInputStream input, ExtensionRegistryLite registry) { + throw new NotImplementedException(); + } + + IMessageLite IBuilderLite.WeakBuild() { + return WeakBuild(); + } + + IMessageLite IBuilderLite.WeakBuildPartial() { + return WeakBuildPartial(); + } + + IBuilderLite IBuilderLite.WeakClone() { + return WeakClone(); + } + + IMessageLite IBuilderLite.WeakDefaultInstanceForType { + get { return WeakDefaultInstanceForType; } + } + + public TBuilder MergeFrom(IMessageLite other) { + throw new NotImplementedException(); + } } } diff --git a/src/ProtocolBuffers/AbstractMessage.cs b/src/ProtocolBuffers/AbstractMessage.cs index 086aac82e4..9cb38c3c79 100644 --- a/src/ProtocolBuffers/AbstractMessage.cs +++ b/src/ProtocolBuffers/AbstractMessage.cs @@ -72,6 +72,10 @@ namespace Google.ProtocolBuffers { return ToBuilder(); } + IMessageLite IMessageLite.WeakDefaultInstanceForType { + get { return DefaultInstanceForType; } + } + public IMessage WeakDefaultInstanceForType { get { return DefaultInstanceForType; } } @@ -233,5 +237,12 @@ namespace Google.ProtocolBuffers { hash = (29 * hash) + UnknownFields.GetHashCode(); return hash; } + + IBuilderLite IMessageLite.WeakCreateBuilderForType() { + return WeakCreateBuilderForType(); } + + IBuilderLite IMessageLite.WeakToBuilder() { + return WeakToBuilder(); + } } } diff --git a/src/ProtocolBuffers/CodedInputStream.cs b/src/ProtocolBuffers/CodedInputStream.cs index 3306f309d4..9173423cb0 100644 --- a/src/ProtocolBuffers/CodedInputStream.cs +++ b/src/ProtocolBuffers/CodedInputStream.cs @@ -36,7 +36,9 @@ using System; using System.Collections.Generic; using System.IO; using System.Text; +#if !LITE using Google.ProtocolBuffers.Descriptors; +#endif namespace Google.ProtocolBuffers { @@ -258,8 +260,8 @@ namespace Google.ProtocolBuffers { /// /// Reads a group field value from the stream. /// - public void ReadGroup(int fieldNumber, IBuilder builder, - ExtensionRegistry extensionRegistry) { + public void ReadGroup(int fieldNumber, IBuilderLite builder, + ExtensionRegistryLite extensionRegistry) { if (recursionDepth >= recursionLimit) { throw InvalidProtocolBufferException.RecursionLimitExceeded(); } @@ -273,12 +275,14 @@ namespace Google.ProtocolBuffers { /// Reads a group field value from the stream and merges it into the given /// UnknownFieldSet. /// - public void ReadUnknownGroup(int fieldNumber, UnknownFieldSet.Builder builder) { + [Obsolete] + public void ReadUnknownGroup(int fieldNumber, IBuilderLite builder) + { if (recursionDepth >= recursionLimit) { throw InvalidProtocolBufferException.RecursionLimitExceeded(); } ++recursionDepth; - builder.MergeFrom(this); + builder.WeakMergeFrom(this); CheckLastTagWas(WireFormat.MakeTag(fieldNumber, WireFormat.WireType.EndGroup)); --recursionDepth; } @@ -286,7 +290,7 @@ namespace Google.ProtocolBuffers { /// /// Reads an embedded message field value from the stream. /// - public void ReadMessage(IBuilder builder, ExtensionRegistry extensionRegistry) { + public void ReadMessage(IBuilderLite builder, ExtensionRegistryLite extensionRegistry) { int length = (int) ReadRawVarint32(); if (recursionDepth >= recursionLimit) { throw InvalidProtocolBufferException.RecursionLimitExceeded(); @@ -359,7 +363,7 @@ namespace Google.ProtocolBuffers { public long ReadSInt64() { return DecodeZigZag64(ReadRawVarint64()); } - +#if !LITE /// /// Reads a field of any primitive type. Enums, groups and embedded /// messages are not handled by this method. @@ -393,7 +397,7 @@ namespace Google.ProtocolBuffers { throw new ArgumentOutOfRangeException("Invalid field type " + fieldType); } } - +#endif #endregion #region Underlying reading primitives diff --git a/src/ProtocolBuffers/CodedOutputStream.cs b/src/ProtocolBuffers/CodedOutputStream.cs index a7e1eca6a2..b261375c19 100644 --- a/src/ProtocolBuffers/CodedOutputStream.cs +++ b/src/ProtocolBuffers/CodedOutputStream.cs @@ -35,8 +35,9 @@ using System; using System.IO; using System.Text; +#if !LITE using Google.ProtocolBuffers.Descriptors; - +#endif namespace Google.ProtocolBuffers { /// @@ -206,19 +207,20 @@ namespace Google.ProtocolBuffers { /// /// Writes a group field value, including tag, to the stream. /// - public void WriteGroup(int fieldNumber, IMessage value) { + public void WriteGroup(int fieldNumber, IMessageLite value) { WriteTag(fieldNumber, WireFormat.WireType.StartGroup); value.WriteTo(this); WriteTag(fieldNumber, WireFormat.WireType.EndGroup); } - public void WriteUnknownGroup(int fieldNumber, UnknownFieldSet value) { + [Obsolete] + public void WriteUnknownGroup(int fieldNumber, IMessageLite value) { WriteTag(fieldNumber, WireFormat.WireType.StartGroup); value.WriteTo(this); WriteTag(fieldNumber, WireFormat.WireType.EndGroup); } - public void WriteMessage(int fieldNumber, IMessage value) { + public void WriteMessage(int fieldNumber, IMessageLite value) { WriteTag(fieldNumber, WireFormat.WireType.LengthDelimited); WriteRawVarint32((uint)value.SerializedSize); value.WriteTo(this); @@ -263,7 +265,7 @@ namespace Google.ProtocolBuffers { WriteRawVarint64(EncodeZigZag64(value)); } - public void WriteMessageSetExtension(int fieldNumber, IMessage value) { + public void WriteMessageSetExtension(int fieldNumber, IMessageLite value) { WriteTag(WireFormat.MessageSetField.Item, WireFormat.WireType.StartGroup); WriteUInt32(WireFormat.MessageSetField.TypeID, (uint)fieldNumber); WriteMessage(WireFormat.MessageSetField.Message, value); @@ -277,6 +279,7 @@ namespace Google.ProtocolBuffers { WriteTag(WireFormat.MessageSetField.Item, WireFormat.WireType.EndGroup); } +#if !LITE public void WriteField(FieldType fieldType, int fieldNumber, object value) { switch (fieldType) { case FieldType.Double: WriteDouble(fieldNumber, (double)value); break; @@ -324,6 +327,7 @@ namespace Google.ProtocolBuffers { break; } } +#endif #endregion #region Writing of values without tags @@ -420,11 +424,11 @@ namespace Google.ProtocolBuffers { /// /// Writes a group field value, without a tag, to the stream. /// - public void WriteGroupNoTag(IMessage value) { + public void WriteGroupNoTag(IMessageLite value) { value.WriteTo(this); } - public void WriteMessageNoTag(IMessage value) { + public void WriteMessageNoTag(IMessageLite value) { WriteRawVarint32((uint)value.SerializedSize); value.WriteTo(this); } @@ -685,7 +689,7 @@ namespace Google.ProtocolBuffers { /// Compute the number of bytes that would be needed to encode a /// group field, including the tag. /// - public static int ComputeGroupSize(int fieldNumber, IMessage value) { + public static int ComputeGroupSize(int fieldNumber, IMessageLite value) { return ComputeTagSize(fieldNumber) * 2 + value.SerializedSize; } @@ -693,8 +697,9 @@ namespace Google.ProtocolBuffers { /// Compute the number of bytes that would be needed to encode a /// group field represented by an UnknownFieldSet, including the tag. /// + [Obsolete] public static int ComputeUnknownGroupSize(int fieldNumber, - UnknownFieldSet value) { + IMessageLite value) { return ComputeTagSize(fieldNumber) * 2 + value.SerializedSize; } @@ -702,7 +707,7 @@ namespace Google.ProtocolBuffers { /// Compute the number of bytes that would be needed to encode an /// embedded message field, including the tag. /// - public static int ComputeMessageSize(int fieldNumber, IMessage value) { + public static int ComputeMessageSize(int fieldNumber, IMessageLite value) { int size = value.SerializedSize; return ComputeTagSize(fieldNumber) + ComputeRawVarint32Size((uint)size) + size; } @@ -853,7 +858,7 @@ namespace Google.ProtocolBuffers { /// Compute the number of bytes that would be needed to encode a /// group field, including the tag. /// - public static int ComputeGroupSizeNoTag(IMessage value) { + public static int ComputeGroupSizeNoTag(IMessageLite value) { return value.SerializedSize; } @@ -861,7 +866,8 @@ namespace Google.ProtocolBuffers { /// Compute the number of bytes that would be needed to encode a /// group field represented by an UnknownFieldSet, including the tag. /// - public static int ComputeUnknownGroupSizeNoTag(UnknownFieldSet value) { + [Obsolete] + public static int ComputeUnknownGroupSizeNoTag(IMessageLite value) { return value.SerializedSize; } @@ -869,7 +875,7 @@ namespace Google.ProtocolBuffers { /// Compute the number of bytes that would be needed to encode an /// embedded message field, including the tag. /// - public static int ComputeMessageSizeNoTag(IMessage value) { + public static int ComputeMessageSizeNoTag(IMessageLite value) { int size = value.SerializedSize; return ComputeRawVarint32Size((uint)size) + size; } @@ -943,7 +949,7 @@ namespace Google.ProtocolBuffers { /// MessageSet extension to the stream. For historical reasons, /// the wire format differs from normal fields. /// - public static int ComputeMessageSetExtensionSize(int fieldNumber, IMessage value) { + public static int ComputeMessageSetExtensionSize(int fieldNumber, IMessageLite value) { return ComputeTagSize(WireFormat.MessageSetField.Item) * 2 + ComputeUInt32Size(WireFormat.MessageSetField.TypeID, (uint) fieldNumber) + ComputeMessageSize(WireFormat.MessageSetField.Message, value); @@ -989,6 +995,7 @@ namespace Google.ProtocolBuffers { return 10; } +#if !LITE /// /// Compute the number of bytes that would be needed to encode a /// field of arbitrary type, including the tag, to the stream. @@ -1046,6 +1053,7 @@ namespace Google.ProtocolBuffers { throw new ArgumentOutOfRangeException("Invalid field type " + fieldType); } } +#endif /// /// Compute the number of bytes that would be needed to encode a tag. diff --git a/src/ProtocolBuffers/DynamicMessage.cs b/src/ProtocolBuffers/DynamicMessage.cs index 12f2186cf4..0653fcf421 100644 --- a/src/ProtocolBuffers/DynamicMessage.cs +++ b/src/ProtocolBuffers/DynamicMessage.cs @@ -338,7 +338,7 @@ namespace Google.ProtocolBuffers { get { return fields.IsInitializedWithRespectTo(type); } } - public override Builder MergeFrom(CodedInputStream input, ExtensionRegistry extensionRegistry) { + public override Builder MergeFrom(CodedInputStream input, ExtensionRegistryLite extensionRegistry) { UnknownFieldSet.Builder unknownFieldsBuilder = UnknownFieldSet.CreateBuilder(unknownFields); unknownFieldsBuilder.MergeFrom(input, extensionRegistry, this); unknownFields = unknownFieldsBuilder.Build(); diff --git a/src/ProtocolBuffers/ExtensionInfo.cs b/src/ProtocolBuffers/ExtensionInfo.cs index 4c877ab8fd..43dd5158f3 100644 --- a/src/ProtocolBuffers/ExtensionInfo.cs +++ b/src/ProtocolBuffers/ExtensionInfo.cs @@ -36,7 +36,7 @@ using Google.ProtocolBuffers.Descriptors; namespace Google.ProtocolBuffers { - public sealed class ExtensionInfo { + public sealed class ExtensionInfo : IGeneratedExtensionLite { /// /// The extension's descriptor /// @@ -55,5 +55,21 @@ namespace Google.ProtocolBuffers Descriptor = descriptor; DefaultInstance = defaultInstance; } + + #region IGeneratedExtensionLite Members + + int IGeneratedExtensionLite.Number { + get { return Descriptor.FieldNumber; } + } + + object IGeneratedExtensionLite.ContainingType { + get { return Descriptor; } + } + + IMessageLite IGeneratedExtensionLite.MessageDefaultInstance { + get { return DefaultInstance; } + } + + #endregion } } \ No newline at end of file diff --git a/src/ProtocolBuffers/ExtensionRegistry.cs b/src/ProtocolBuffers/ExtensionRegistry.cs index 154b690277..02cd4631c5 100644 --- a/src/ProtocolBuffers/ExtensionRegistry.cs +++ b/src/ProtocolBuffers/ExtensionRegistry.cs @@ -88,41 +88,38 @@ namespace Google.ProtocolBuffers { /// could take advantage of this to inject a mutable object into a message /// belonging to privileged code and create mischief. /// - public sealed class ExtensionRegistry { + public sealed class ExtensionRegistry : ExtensionRegistryLite { private static readonly ExtensionRegistry empty = new ExtensionRegistry( new Dictionary(), - new Dictionary(), + new Dictionary(), true); private readonly IDictionary extensionsByName; - private readonly IDictionary extensionsByNumber; - private readonly bool readOnly; private ExtensionRegistry(IDictionary extensionsByName, - IDictionary extensionsByNumber, - bool readOnly) { + IDictionary extensionsByNumber, + bool readOnly) + : base(extensionsByNumber, readOnly) { this.extensionsByName = extensionsByName; - this.extensionsByNumber = extensionsByNumber; - this.readOnly = readOnly; } /// /// Construct a new, empty instance. /// - public static ExtensionRegistry CreateInstance() { + public static new ExtensionRegistry CreateInstance() { return new ExtensionRegistry(new Dictionary(), - new Dictionary(), false); + new Dictionary(), false); } /// /// Get the unmodifiable singleton empty instance. /// - public static ExtensionRegistry Empty { + public new static ExtensionRegistry Empty { get { return empty; } } - public ExtensionRegistry AsReadOnly() { + public override ExtensionRegistryLite AsReadOnly() { return new ExtensionRegistry(extensionsByName, extensionsByNumber, true); } @@ -146,9 +143,9 @@ namespace Google.ProtocolBuffers { /// public ExtensionInfo this[MessageDescriptor containingType, int fieldNumber] { get { - ExtensionInfo ret; - extensionsByNumber.TryGetValue(new DescriptorIntPair(containingType, fieldNumber), out ret); - return ret; + IGeneratedExtensionLite ret; + extensionsByNumber.TryGetValue(new ExtensionIntPair(containingType, fieldNumber), out ret); + return ret as ExtensionInfo; } } @@ -198,7 +195,7 @@ namespace Google.ProtocolBuffers { } extensionsByName[extension.Descriptor.FullName] = extension; - extensionsByNumber[new DescriptorIntPair(extension.Descriptor.ContainingType, + extensionsByNumber[new ExtensionIntPair(extension.Descriptor.ContainingType, extension.Descriptor.FieldNumber)] = extension; FieldDescriptor field = extension.Descriptor; @@ -212,34 +209,5 @@ namespace Google.ProtocolBuffers { extensionsByName[field.MessageType.FullName] = extension; } } - - /// - /// Nested type just used to represent a pair of MessageDescriptor and int, as - /// the key into the "by number" map. - /// - private struct DescriptorIntPair : IEquatable { - readonly MessageDescriptor descriptor; - readonly int number; - - internal DescriptorIntPair(MessageDescriptor descriptor, int number) { - this.descriptor = descriptor; - this.number = number; - } - - public override int GetHashCode() { - return descriptor.GetHashCode() * ((1 << 16) - 1) + number; - } - - public override bool Equals(object obj) { - if (!(obj is DescriptorIntPair)) { - return false; - } - return Equals((DescriptorIntPair)obj); - } - - public bool Equals(DescriptorIntPair other) { - return descriptor == other.descriptor && number == other.number; - } - } } } diff --git a/src/ProtocolBuffers/ExtensionRegistryLite.cs b/src/ProtocolBuffers/ExtensionRegistryLite.cs index 154b690277..693aeb2cea 100644 --- a/src/ProtocolBuffers/ExtensionRegistryLite.cs +++ b/src/ProtocolBuffers/ExtensionRegistryLite.cs @@ -33,14 +33,15 @@ #endregion using System.Collections.Generic; -using Google.ProtocolBuffers.Descriptors; using System; namespace Google.ProtocolBuffers { + + /// /// A table of known extensions, searchable by name or field number. When /// parsing a protocol message that might have extensions, you must provide - /// an in which you have registered any extensions + /// an in which you have registered any extensions /// that you want to be able to parse. Otherwise, those extensions will just /// be treated like unknown fields. /// @@ -61,7 +62,7 @@ namespace Google.ProtocolBuffers { /// Then you might write code like: /// /// - /// ExtensionRegistry registry = ExtensionRegistry.CreateInstance(); + /// ExtensionRegistryLite registry = ExtensionRegistryLite.CreateInstance(); /// registry.Add(MyProto.Bar); /// MyProto.Foo message = MyProto.Foo.ParseFrom(input, registry); /// @@ -88,21 +89,17 @@ namespace Google.ProtocolBuffers { /// could take advantage of this to inject a mutable object into a message /// belonging to privileged code and create mischief. /// - public sealed class ExtensionRegistry { + public class ExtensionRegistryLite { - private static readonly ExtensionRegistry empty = new ExtensionRegistry( - new Dictionary(), - new Dictionary(), + private static readonly ExtensionRegistryLite empty = new ExtensionRegistryLite( + new Dictionary(), true); - private readonly IDictionary extensionsByName; - private readonly IDictionary extensionsByNumber; - private readonly bool readOnly; + protected readonly IDictionary extensionsByNumber; + protected readonly bool readOnly; - private ExtensionRegistry(IDictionary extensionsByName, - IDictionary extensionsByNumber, + protected ExtensionRegistryLite(IDictionary extensionsByNumber, bool readOnly) { - this.extensionsByName = extensionsByName; this.extensionsByNumber = extensionsByNumber; this.readOnly = readOnly; } @@ -110,44 +107,30 @@ namespace Google.ProtocolBuffers { /// /// Construct a new, empty instance. /// - public static ExtensionRegistry CreateInstance() { - return new ExtensionRegistry(new Dictionary(), - new Dictionary(), false); + public static ExtensionRegistryLite CreateInstance() { + return new ExtensionRegistryLite( + new Dictionary(), false); } /// /// Get the unmodifiable singleton empty instance. /// - public static ExtensionRegistry Empty { + public static ExtensionRegistryLite Empty { get { return empty; } } - public ExtensionRegistry AsReadOnly() { - return new ExtensionRegistry(extensionsByName, extensionsByNumber, true); - } - - /// - /// Finds an extension by fully-qualified field name, in the - /// proto namespace, i.e. result.Descriptor.FullName will match - /// if a match is found. A null - /// reference is returned if the extension can't be found. - /// - public ExtensionInfo this[string fullName] { - get { - ExtensionInfo ret; - extensionsByName.TryGetValue(fullName, out ret); - return ret; - } + public virtual ExtensionRegistryLite AsReadOnly() { + return new ExtensionRegistryLite(extensionsByNumber, true); } /// /// Finds an extension by containing type and field number. /// A null reference is returned if the extension can't be found. /// - public ExtensionInfo this[MessageDescriptor containingType, int fieldNumber] { + public IGeneratedExtensionLite this[IMessageLite containingType, int fieldNumber] { get { - ExtensionInfo ret; - extensionsByNumber.TryGetValue(new DescriptorIntPair(containingType, fieldNumber), out ret); + IGeneratedExtensionLite ret; + extensionsByNumber.TryGetValue(new ExtensionIntPair(containingType, fieldNumber), out ret); return ret; } } @@ -155,90 +138,41 @@ namespace Google.ProtocolBuffers { /// /// Add an extension from a generated file to the registry. /// - public void Add (GeneratedExtensionBase extension) { - if (extension.Descriptor.MappedType == MappedType.Message) { - Add(new ExtensionInfo(extension.Descriptor, extension.MessageDefaultInstance)); - } else { - Add(new ExtensionInfo(extension.Descriptor, null)); - } - } - - /// - /// Adds a non-message-type extension to the registry by descriptor. - /// - /// - public void Add(FieldDescriptor type) { - if (type.MappedType == MappedType.Message) { - throw new ArgumentException("ExtensionRegistry.Add() must be provided a default instance " - + "when adding an embedded message extension."); - } - Add(new ExtensionInfo(type, null)); - } - - /// - /// Adds a message-type-extension to the registry by descriptor. - /// - /// - /// - public void Add(FieldDescriptor type, IMessage defaultInstance) { - if (type.MappedType != MappedType.Message) { - throw new ArgumentException("ExtensionRegistry.Add() provided a default instance for a " - + "non-message extension."); - } - Add(new ExtensionInfo(type, defaultInstance)); - } - - private void Add(ExtensionInfo extension) { + public virtual void Add(IGeneratedExtensionLite extension) { if (readOnly) { throw new InvalidOperationException("Cannot add entries to a read-only extension registry"); } - if (!extension.Descriptor.IsExtension) { - throw new ArgumentException("ExtensionRegistry.add() was given a FieldDescriptor for a " - + "regular (non-extension) field."); - } - - extensionsByName[extension.Descriptor.FullName] = extension; - extensionsByNumber[new DescriptorIntPair(extension.Descriptor.ContainingType, - extension.Descriptor.FieldNumber)] = extension; - - FieldDescriptor field = extension.Descriptor; - if (field.ContainingType.Options.MessageSetWireFormat - && field.FieldType == FieldType.Message - && field.IsOptional - && field.ExtensionScope == field.MessageType) { - // This is an extension of a MessageSet type defined within the extension - // type's own scope. For backwards-compatibility, allow it to be looked - // up by type name. - extensionsByName[field.MessageType.FullName] = extension; - } + extensionsByNumber.Add( + new ExtensionIntPair(extension.ContainingType, extension.Number), + extension); } /// /// Nested type just used to represent a pair of MessageDescriptor and int, as /// the key into the "by number" map. /// - private struct DescriptorIntPair : IEquatable { - readonly MessageDescriptor descriptor; + protected struct ExtensionIntPair : IEquatable { + readonly object msgType; readonly int number; - internal DescriptorIntPair(MessageDescriptor descriptor, int number) { - this.descriptor = descriptor; + internal ExtensionIntPair(object msgType, int number) { + this.msgType = msgType; this.number = number; } public override int GetHashCode() { - return descriptor.GetHashCode() * ((1 << 16) - 1) + number; + return msgType.GetHashCode() * ((1 << 16) - 1) + number; } public override bool Equals(object obj) { - if (!(obj is DescriptorIntPair)) { + if (!(obj is ExtensionIntPair)) { return false; } - return Equals((DescriptorIntPair)obj); + return Equals((ExtensionIntPair)obj); } - public bool Equals(DescriptorIntPair other) { - return descriptor == other.descriptor && number == other.number; + public bool Equals(ExtensionIntPair other) { + return msgType.Equals(other.msgType) && number == other.number; } } } diff --git a/src/ProtocolBuffers/GeneratedExtensionBase.cs b/src/ProtocolBuffers/GeneratedExtensionBase.cs index 813f69cf97..9896a462bd 100644 --- a/src/ProtocolBuffers/GeneratedExtensionBase.cs +++ b/src/ProtocolBuffers/GeneratedExtensionBase.cs @@ -39,6 +39,7 @@ using System.Reflection; using Google.ProtocolBuffers.Descriptors; namespace Google.ProtocolBuffers { + /// /// Base type for all generated extensions. /// @@ -87,6 +88,10 @@ namespace Google.ProtocolBuffers { get { return descriptor; } } + public int Number { + get { return Descriptor.FieldNumber; } + } + /// /// Returns the default message instance for extensions which are message types. /// diff --git a/src/ProtocolBuffers/GeneratedExtensionLite.cs b/src/ProtocolBuffers/GeneratedExtensionLite.cs new file mode 100644 index 0000000000..267945145a --- /dev/null +++ b/src/ProtocolBuffers/GeneratedExtensionLite.cs @@ -0,0 +1,24 @@ +using System; + +namespace Google.ProtocolBuffers { + + public interface IGeneratedExtensionLite { + int Number { get; } + object ContainingType { get; } + IMessageLite MessageDefaultInstance { get; } + } + + public class GeneratedExtensionLite : IGeneratedExtensionLite { + public int Number { + get { throw new NotImplementedException(); } + } + + public object ContainingType { + get { throw new NotImplementedException(); } + } + + public IMessageLite MessageDefaultInstance { + get { throw new NotImplementedException(); } + } + } +} \ No newline at end of file diff --git a/src/ProtocolBuffers/IBuilder.cs b/src/ProtocolBuffers/IBuilder.cs index b1aa4fb1d4..f8d828ad77 100644 --- a/src/ProtocolBuffers/IBuilder.cs +++ b/src/ProtocolBuffers/IBuilder.cs @@ -47,12 +47,12 @@ namespace Google.ProtocolBuffers { /// use explicit interface implemenation for the non-generic form. This mirrors /// how IEnumerable and IEnumerable<T> work. /// - public interface IBuilder { + public interface IBuilder : IBuilderLite { /// /// Returns true iff all required fields in the message and all /// embedded messages are set. /// - bool IsInitialized { get; } + new bool IsInitialized { get; } /// /// Only present in the nongeneric interface - useful for tests, but @@ -119,17 +119,17 @@ namespace Google.ProtocolBuffers { #region Methods which are like those of the generic form, but without any knowledge of the type parameters IBuilder WeakAddRepeatedField(FieldDescriptor field, object value); - IBuilder WeakClear(); + new IBuilder WeakClear(); IBuilder WeakClearField(FieldDescriptor field); IBuilder WeakMergeFrom(IMessage message); - IBuilder WeakMergeFrom(ByteString data); - IBuilder WeakMergeFrom(ByteString data, ExtensionRegistry registry); - IBuilder WeakMergeFrom(CodedInputStream input); - IBuilder WeakMergeFrom(CodedInputStream input, ExtensionRegistry registry); - IMessage WeakBuild(); - IMessage WeakBuildPartial(); - IBuilder WeakClone(); - IMessage WeakDefaultInstanceForType { get; } + new IBuilder WeakMergeFrom(ByteString data); + new IBuilder WeakMergeFrom(ByteString data, ExtensionRegistryLite registry); + new IBuilder WeakMergeFrom(CodedInputStream input); + new IBuilder WeakMergeFrom(CodedInputStream input, ExtensionRegistryLite registry); + new IMessage WeakBuild(); + new IMessage WeakBuildPartial(); + new IBuilder WeakClone(); + new IMessage WeakDefaultInstanceForType { get; } #endregion } @@ -139,7 +139,7 @@ namespace Google.ProtocolBuffers { /// /// Type of message /// Type of builder - public interface IBuilder : IBuilder + public interface IBuilder : IBuilder, IBuilderLite where TMessage : IMessage where TBuilder : IBuilder { @@ -148,7 +148,7 @@ namespace Google.ProtocolBuffers { /// /// Resets all fields to their default values. /// - TBuilder Clear(); + new TBuilder Clear(); /// /// Merge the specified other message into the message being @@ -163,7 +163,7 @@ namespace Google.ProtocolBuffers { /// /// /// - TBuilder MergeFrom(TMessage other); + new TBuilder MergeFrom(TMessage other); /// /// Merge the specified other message which may be a different implementation of @@ -180,19 +180,19 @@ namespace Google.ProtocolBuffers { /// the message /// is missing one or more required fields; use BuildPartial to bypass /// this check - TMessage Build(); + new TMessage Build(); /// /// Like Build(), but does not throw an exception if the message is missing /// required fields. Instead, a partial message is returned. /// - TMessage BuildPartial(); + new TMessage BuildPartial(); /// /// Clones this builder. /// TODO(jonskeet): Explain depth of clone. /// - TBuilder Clone(); + new TBuilder Clone(); /// /// Parses a message of this type from the input and merges it with this @@ -213,7 +213,7 @@ namespace Google.ProtocolBuffers { /// Use BuildPartial to build, which ignores missing required fields. /// /// - TBuilder MergeFrom(CodedInputStream input); + new TBuilder MergeFrom(CodedInputStream input); /// /// Like MergeFrom(CodedInputStream), but also parses extensions. @@ -221,13 +221,13 @@ namespace Google.ProtocolBuffers { /// in . Extensions not in the registry /// will be treated as unknown fields. /// - TBuilder MergeFrom(CodedInputStream input, ExtensionRegistry extensionRegistry); + new TBuilder MergeFrom(CodedInputStream input, ExtensionRegistryLite extensionRegistry); /// /// Get's the message's type's default instance. /// /// - TMessage DefaultInstanceForType { get; } + new TMessage DefaultInstanceForType { get; } /// /// Clears the field. This is exactly equivalent to calling the generated @@ -258,12 +258,12 @@ namespace Google.ProtocolBuffers { /// write messages in this format. /// /// - TBuilder MergeDelimitedFrom(Stream input); + new TBuilder MergeDelimitedFrom(Stream input); /// /// Like MergeDelimitedFrom(Stream) but supporting extensions. /// - TBuilder MergeDelimitedFrom(Stream input, ExtensionRegistry extensionRegistry); + new TBuilder MergeDelimitedFrom(Stream input, ExtensionRegistryLite extensionRegistry); #region Convenience methods /// @@ -271,28 +271,28 @@ namespace Google.ProtocolBuffers { /// it with the message being built. This is just a small wrapper around /// MergeFrom(CodedInputStream). /// - TBuilder MergeFrom(ByteString data); + new TBuilder MergeFrom(ByteString data); /// /// Parse as a message of this type and merge /// it with the message being built. This is just a small wrapper around - /// MergeFrom(CodedInputStream, ExtensionRegistry). + /// MergeFrom(CodedInputStream, ExtensionRegistryLite). /// - TBuilder MergeFrom(ByteString data, ExtensionRegistry extensionRegistry); + new TBuilder MergeFrom(ByteString data, ExtensionRegistryLite extensionRegistry); /// /// Parse as a message of this type and merge /// it with the message being built. This is just a small wrapper around /// MergeFrom(CodedInputStream). /// - TBuilder MergeFrom(byte[] data); + new TBuilder MergeFrom(byte[] data); /// /// Parse as a message of this type and merge /// it with the message being built. This is just a small wrapper around - /// MergeFrom(CodedInputStream, ExtensionRegistry). + /// MergeFrom(CodedInputStream, ExtensionRegistryLite). /// - TBuilder MergeFrom(byte[] data, ExtensionRegistry extensionRegistry); + new TBuilder MergeFrom(byte[] data, ExtensionRegistryLite extensionRegistry); /// /// Parse as a message of this type and merge @@ -304,14 +304,14 @@ namespace Google.ProtocolBuffers { /// to write your message and MmergeDelimitedFrom(Stream) to read it. /// Despite usually reading the entire stream, this method never closes the stream. /// - TBuilder MergeFrom(Stream input); + new TBuilder MergeFrom(Stream input); /// /// Parse as a message of this type and merge /// it with the message being built. This is just a small wrapper around - /// MergeFrom(CodedInputStream, ExtensionRegistry). + /// MergeFrom(CodedInputStream, ExtensionRegistryLite). /// - TBuilder MergeFrom(Stream input, ExtensionRegistry extensionRegistry); + new TBuilder MergeFrom(Stream input, ExtensionRegistryLite extensionRegistry); #endregion } } diff --git a/src/ProtocolBuffers/IBuilderLite.cs b/src/ProtocolBuffers/IBuilderLite.cs index b1aa4fb1d4..459d6938cb 100644 --- a/src/ProtocolBuffers/IBuilderLite.cs +++ b/src/ProtocolBuffers/IBuilderLite.cs @@ -35,7 +35,6 @@ using System; using System.Collections.Generic; using System.IO; -using Google.ProtocolBuffers.Descriptors; namespace Google.ProtocolBuffers { @@ -47,90 +46,23 @@ namespace Google.ProtocolBuffers { /// use explicit interface implemenation for the non-generic form. This mirrors /// how IEnumerable and IEnumerable<T> work. /// - public interface IBuilder { + public interface IBuilderLite { /// /// Returns true iff all required fields in the message and all /// embedded messages are set. /// bool IsInitialized { get; } - /// - /// Only present in the nongeneric interface - useful for tests, but - /// not as much in real life. - /// - IBuilder SetField(FieldDescriptor field, object value); - - /// - /// Only present in the nongeneric interface - useful for tests, but - /// not as much in real life. - /// - IBuilder SetRepeatedField(FieldDescriptor field, int index, object value); - - /// - /// Behaves like the equivalent property in IMessage<T>. - /// The returned map may or may not reflect future changes to the builder. - /// Either way, the returned map is unmodifiable. - /// - IDictionary AllFields { get; } - - /// - /// Allows getting and setting of a field. - /// - /// - /// - /// - object this[FieldDescriptor field] { get; set; } - - /// - /// Get the message's type descriptor. - /// - /// - MessageDescriptor DescriptorForType { get; } - - /// - /// - /// - /// - /// - int GetRepeatedFieldCount(FieldDescriptor field); - - /// - /// Allows getting and setting of a repeated field value. - /// - /// - object this[FieldDescriptor field, int index] { get; set; } - - /// - /// - /// - bool HasField(FieldDescriptor field); - - /// - /// - /// - UnknownFieldSet UnknownFields { get; set; } - - /// - /// Create a builder for messages of the appropriate type for the given field. - /// Messages built with this can then be passed to the various mutation properties - /// and methods. - /// - IBuilder CreateBuilderForField(FieldDescriptor field); - - #region Methods which are like those of the generic form, but without any knowledge of the type parameters - IBuilder WeakAddRepeatedField(FieldDescriptor field, object value); - IBuilder WeakClear(); - IBuilder WeakClearField(FieldDescriptor field); - IBuilder WeakMergeFrom(IMessage message); - IBuilder WeakMergeFrom(ByteString data); - IBuilder WeakMergeFrom(ByteString data, ExtensionRegistry registry); - IBuilder WeakMergeFrom(CodedInputStream input); - IBuilder WeakMergeFrom(CodedInputStream input, ExtensionRegistry registry); - IMessage WeakBuild(); - IMessage WeakBuildPartial(); - IBuilder WeakClone(); - IMessage WeakDefaultInstanceForType { get; } - #endregion + IBuilderLite WeakClear(); + IBuilderLite WeakMergeFrom(IMessageLite message); + IBuilderLite WeakMergeFrom(ByteString data); + IBuilderLite WeakMergeFrom(ByteString data, ExtensionRegistryLite registry); + IBuilderLite WeakMergeFrom(CodedInputStream input); + IBuilderLite WeakMergeFrom(CodedInputStream input, ExtensionRegistryLite registry); + IMessageLite WeakBuild(); + IMessageLite WeakBuildPartial(); + IBuilderLite WeakClone(); + IMessageLite WeakDefaultInstanceForType { get; } } /// @@ -139,11 +71,9 @@ namespace Google.ProtocolBuffers { /// /// Type of message /// Type of builder - public interface IBuilder : IBuilder - where TMessage : IMessage - where TBuilder : IBuilder { - - TBuilder SetUnknownFields(UnknownFieldSet unknownFields); + public interface IBuilderLite : IBuilderLite + where TMessage : IMessageLite + where TBuilder : IBuilderLite { /// /// Resets all fields to their default values. @@ -169,7 +99,7 @@ namespace Google.ProtocolBuffers { /// Merge the specified other message which may be a different implementation of /// the same message descriptor. /// - TBuilder MergeFrom(IMessage other); + TBuilder MergeFrom(IMessageLite other); /// /// Constructs the final message. Once this is called, this Builder instance @@ -221,36 +151,14 @@ namespace Google.ProtocolBuffers { /// in . Extensions not in the registry /// will be treated as unknown fields. /// - TBuilder MergeFrom(CodedInputStream input, ExtensionRegistry extensionRegistry); + TBuilder MergeFrom(CodedInputStream input, ExtensionRegistryLite extensionRegistry); /// /// Get's the message's type's default instance. - /// + /// /// TMessage DefaultInstanceForType { get; } - /// - /// Clears the field. This is exactly equivalent to calling the generated - /// Clear method corresponding to the field. - /// - /// - /// - TBuilder ClearField(FieldDescriptor field); - - /// - /// Appends the given value as a new element for the specified repeated field. - /// - /// the field is not a repeated field, - /// the field does not belong to this builder's type, or the value is - /// of the incorrect type - /// - TBuilder AddRepeatedField(FieldDescriptor field, object value); - - /// - /// Merge some unknown fields into the set for this message. - /// - TBuilder MergeUnknownFields(UnknownFieldSet unknownFields); - /// /// Like MergeFrom(Stream), but does not read until the end of the file. /// Instead, the size of the message (encoded as a varint) is read first, @@ -263,7 +171,7 @@ namespace Google.ProtocolBuffers { /// /// Like MergeDelimitedFrom(Stream) but supporting extensions. /// - TBuilder MergeDelimitedFrom(Stream input, ExtensionRegistry extensionRegistry); + TBuilder MergeDelimitedFrom(Stream input, ExtensionRegistryLite extensionRegistry); #region Convenience methods /// @@ -278,7 +186,7 @@ namespace Google.ProtocolBuffers { /// it with the message being built. This is just a small wrapper around /// MergeFrom(CodedInputStream, ExtensionRegistry). /// - TBuilder MergeFrom(ByteString data, ExtensionRegistry extensionRegistry); + TBuilder MergeFrom(ByteString data, ExtensionRegistryLite extensionRegistry); /// /// Parse as a message of this type and merge @@ -292,7 +200,7 @@ namespace Google.ProtocolBuffers { /// it with the message being built. This is just a small wrapper around /// MergeFrom(CodedInputStream, ExtensionRegistry). /// - TBuilder MergeFrom(byte[] data, ExtensionRegistry extensionRegistry); + TBuilder MergeFrom(byte[] data, ExtensionRegistryLite extensionRegistry); /// /// Parse as a message of this type and merge @@ -311,7 +219,7 @@ namespace Google.ProtocolBuffers { /// it with the message being built. This is just a small wrapper around /// MergeFrom(CodedInputStream, ExtensionRegistry). /// - TBuilder MergeFrom(Stream input, ExtensionRegistry extensionRegistry); + TBuilder MergeFrom(Stream input, ExtensionRegistryLite extensionRegistry); #endregion } } diff --git a/src/ProtocolBuffers/IMessage.cs b/src/ProtocolBuffers/IMessage.cs index ec955c6d39..4d37a8d2a2 100644 --- a/src/ProtocolBuffers/IMessage.cs +++ b/src/ProtocolBuffers/IMessage.cs @@ -43,7 +43,7 @@ namespace Google.ProtocolBuffers { /// Non-generic interface used for all parts of the API which don't require /// any type knowledge. /// - public interface IMessage { + public interface IMessage : IMessageLite { /// /// Returns the message's type's descriptor. This differs from the /// Descriptor property of each generated message class in that this @@ -110,7 +110,7 @@ namespace Google.ProtocolBuffers { /// Returns true iff all required fields in the message and all embedded /// messages are set. /// - bool IsInitialized { get; } + new bool IsInitialized { get; } /// /// Serializes the message and writes it to the given output stream. @@ -124,7 +124,7 @@ namespace Google.ProtocolBuffers { /// of the message before the data, then making sure you limit the input to /// that size when receiving the data. Alternatively, use WriteDelimitedTo(Stream). /// - void WriteTo(CodedOutputStream output); + new void WriteTo(CodedOutputStream output); /// /// Like WriteTo(Stream) but writes the size of the message as a varint before @@ -134,13 +134,13 @@ namespace Google.ProtocolBuffers { /// YourMessageType.ParseDelimitedFrom(Stream) to parse messages written by this method. /// /// - void WriteDelimitedTo(Stream output); + new void WriteDelimitedTo(Stream output); /// /// Returns the number of bytes required to encode this message. /// The result is only computed on the first call and memoized after that. /// - int SerializedSize { get; } + new int SerializedSize { get; } #region Comparison and hashing /// @@ -149,13 +149,13 @@ namespace Google.ProtocolBuffers { /// (as defined by DescriptorForType) and has identical values /// for all its fields. /// - bool Equals(object other); + new bool Equals(object other); /// /// Returns the hash code value for this message. /// TODO(jonskeet): Specify the hash algorithm, but better than the Java one! /// - int GetHashCode(); + new int GetHashCode(); #endregion #region Convenience methods @@ -163,19 +163,19 @@ namespace Google.ProtocolBuffers { /// Converts the message to a string in protocol buffer text format. /// This is just a trivial wrapper around TextFormat.PrintToString. /// - string ToString(); + new string ToString(); /// /// Serializes the message to a ByteString. This is a trivial wrapper /// around WriteTo(CodedOutputStream). /// - ByteString ToByteString(); + new ByteString ToByteString(); /// /// Serializes the message to a byte array. This is a trivial wrapper /// around WriteTo(CodedOutputStream). /// - byte[] ToByteArray(); + new byte[] ToByteArray(); /// /// Serializes the message and writes it to the given stream. @@ -183,7 +183,7 @@ namespace Google.ProtocolBuffers { /// does not flush or close the stream. /// /// - void WriteTo(Stream output); + new void WriteTo(Stream output); #endregion /// @@ -191,19 +191,19 @@ namespace Google.ProtocolBuffers { /// is typically implemented by strongly typed messages by just returning /// the result of CreateBuilderForType. /// - IBuilder WeakCreateBuilderForType(); + new IBuilder WeakCreateBuilderForType(); /// /// Creates a builder with the same contents as this message. This /// is typically implemented by strongly typed messages by just returning /// the result of ToBuilder. /// - IBuilder WeakToBuilder(); + new IBuilder WeakToBuilder(); - IMessage WeakDefaultInstanceForType { get; } + new IMessage WeakDefaultInstanceForType { get; } } - public interface IMessage : IMessage { + public interface IMessage : IMessage, IMessageLite { /// /// Returns an instance of this message type with all fields set to /// their default values. This may or may not be a singleton. This differs @@ -211,26 +211,26 @@ namespace Google.ProtocolBuffers { /// method is an abstract method of IMessage whereas DefaultInstance is /// a static property of a specific class. They return the same thing. /// - TMessage DefaultInstanceForType { get; } + new TMessage DefaultInstanceForType { get; } } /// /// Type-safe interface for all generated messages to implement. /// - public interface IMessage : IMessage + public interface IMessage : IMessage, IMessageLite where TMessage : IMessage where TBuilder : IBuilder { #region Builders /// /// Constructs a new builder for a message of the same type as this message. /// - TBuilder CreateBuilderForType(); + new TBuilder CreateBuilderForType(); /// /// Creates a builder with the same contents as this current instance. /// This is typically implemented by strongly typed messages by just /// returning the result of ToBuilder(). /// - TBuilder ToBuilder(); + new TBuilder ToBuilder(); #endregion } } diff --git a/src/ProtocolBuffers/IMessageLite.cs b/src/ProtocolBuffers/IMessageLite.cs index ec955c6d39..cb64e02142 100644 --- a/src/ProtocolBuffers/IMessageLite.cs +++ b/src/ProtocolBuffers/IMessageLite.cs @@ -35,7 +35,6 @@ using System; using System.Collections.Generic; using System.IO; -using Google.ProtocolBuffers.Descriptors; namespace Google.ProtocolBuffers { @@ -43,68 +42,7 @@ namespace Google.ProtocolBuffers { /// Non-generic interface used for all parts of the API which don't require /// any type knowledge. /// - public interface IMessage { - /// - /// Returns the message's type's descriptor. This differs from the - /// Descriptor property of each generated message class in that this - /// method is an abstract method of IMessage whereas Descriptor is - /// a static property of a specific class. They return the same thing. - /// - MessageDescriptor DescriptorForType { get; } - /// - /// Returns a collection of all the fields in this message which are set - /// and their corresponding values. A singular ("required" or "optional") - /// field is set iff HasField() returns true for that field. A "repeated" - /// field is set iff GetRepeatedFieldSize() is greater than zero. The - /// values are exactly what would be returned by calling - /// GetField(FieldDescriptor) for each field. The map - /// is guaranteed to be a sorted map, so iterating over it will return fields - /// in order by field number. - /// - IDictionary AllFields { get; } - - /// - /// Returns true if the given field is set. This is exactly equivalent - /// to calling the generated "Has" property corresponding to the field. - /// - /// the field is a repeated field, - /// or it's not a field of this type - bool HasField(FieldDescriptor field); - - /// - /// Obtains the value of the given field, or the default value if - /// it isn't set. For value type fields, the boxed value is returned. - /// For enum fields, the EnumValueDescriptor for the enum is returned. - /// For embedded message fields, the sub-message - /// is returned. For repeated fields, an IList<T> is returned. - /// - object this[FieldDescriptor field] { get; } - - /// - /// Returns the number of elements of a repeated field. This is - /// exactly equivalent to calling the generated "Count" property - /// corresponding to the field. - /// - /// the field is not a repeated field, - /// or it's not a field of this type - int GetRepeatedFieldCount(FieldDescriptor field); - - /// - /// Gets an element of a repeated field. For value type fields - /// excluding enums, the boxed value is returned. For embedded - /// message fields, the sub-message is returned. For enums, the - /// relevant EnumValueDescriptor is returned. - /// - /// the field is not a repeated field, - /// or it's not a field of this type - /// the index is out of - /// range for the repeated field's value - object this[FieldDescriptor field, int index] { get; } - - /// - /// Returns the unknown fields for this message. - /// - UnknownFieldSet UnknownFields { get; } + public interface IMessageLite { /// /// Returns true iff all required fields in the message and all embedded @@ -191,19 +129,19 @@ namespace Google.ProtocolBuffers { /// is typically implemented by strongly typed messages by just returning /// the result of CreateBuilderForType. /// - IBuilder WeakCreateBuilderForType(); + IBuilderLite WeakCreateBuilderForType(); /// /// Creates a builder with the same contents as this message. This /// is typically implemented by strongly typed messages by just returning /// the result of ToBuilder. /// - IBuilder WeakToBuilder(); + IBuilderLite WeakToBuilder(); - IMessage WeakDefaultInstanceForType { get; } + IMessageLite WeakDefaultInstanceForType { get; } } - public interface IMessage : IMessage { + public interface IMessageLite : IMessageLite { /// /// Returns an instance of this message type with all fields set to /// their default values. This may or may not be a singleton. This differs @@ -217,9 +155,9 @@ namespace Google.ProtocolBuffers { /// /// Type-safe interface for all generated messages to implement. /// - public interface IMessage : IMessage - where TMessage : IMessage - where TBuilder : IBuilder { + public interface IMessageLite : IMessageLite + where TMessage : IMessageLite + where TBuilder : IBuilderLite { #region Builders /// /// Constructs a new builder for a message of the same type as this message. diff --git a/src/ProtocolBuffers/ProtocolBuffers.csproj b/src/ProtocolBuffers/ProtocolBuffers.csproj index 703a8235d4..f4fbfe42a9 100644 --- a/src/ProtocolBuffers/ProtocolBuffers.csproj +++ b/src/ProtocolBuffers/ProtocolBuffers.csproj @@ -84,8 +84,11 @@ - + + Code + + @@ -97,12 +100,17 @@ + + + Code + + diff --git a/src/ProtocolBuffers/UninitializedMessageException.cs b/src/ProtocolBuffers/UninitializedMessageException.cs index 2fa5ef1d72..d98987a16b 100644 --- a/src/ProtocolBuffers/UninitializedMessageException.cs +++ b/src/ProtocolBuffers/UninitializedMessageException.cs @@ -36,8 +36,10 @@ using System; using System.Collections; using System.Collections.Generic; using System.Text; +#if !LITE using Google.ProtocolBuffers.Collections; using Google.ProtocolBuffers.Descriptors; +#endif namespace Google.ProtocolBuffers { /// @@ -47,13 +49,9 @@ namespace Google.ProtocolBuffers { private readonly IList missingFields; - public UninitializedMessageException(IMessage message) - : this(FindMissingFields(message)) { - } - private UninitializedMessageException(IList missingFields) : base(BuildDescription(missingFields)) { - this.missingFields = Lists.AsReadOnly(missingFields); + this.missingFields = new List(missingFields); } @@ -92,6 +90,11 @@ namespace Google.ProtocolBuffers { return description.ToString(); } +#if !LITE + public UninitializedMessageException(IMessage message) + : this(FindMissingFields(message)) { + } + /// /// Returns a list of the full "paths" of missing required /// fields in the specified message. @@ -148,5 +151,6 @@ namespace Google.ProtocolBuffers { result.Append('.'); return result.ToString(); } +#endif } } diff --git a/src/ProtocolBuffers/UnknownField.cs b/src/ProtocolBuffers/UnknownField.cs index fdc0065074..ad1b59b412 100644 --- a/src/ProtocolBuffers/UnknownField.cs +++ b/src/ProtocolBuffers/UnknownField.cs @@ -172,7 +172,9 @@ namespace Google.ProtocolBuffers { output.WriteBytes(fieldNumber, value); } foreach (UnknownFieldSet value in groupList) { +#pragma warning disable 0612 output.WriteUnknownGroup(fieldNumber, value); +#pragma warning restore 0612 } } @@ -195,7 +197,9 @@ namespace Google.ProtocolBuffers { result += CodedOutputStream.ComputeBytesSize(fieldNumber, value); } foreach (UnknownFieldSet value in groupList) { +#pragma warning disable 0612 result += CodedOutputStream.ComputeUnknownGroupSize(fieldNumber, value); +#pragma warning restore 0612 } return result; } diff --git a/src/ProtocolBuffers/UnknownFieldSet.cs b/src/ProtocolBuffers/UnknownFieldSet.cs index 49c1fa32ce..e982e311b5 100644 --- a/src/ProtocolBuffers/UnknownFieldSet.cs +++ b/src/ProtocolBuffers/UnknownFieldSet.cs @@ -51,7 +51,7 @@ namespace Google.ProtocolBuffers { /// /// Most users will never need to use this class directly. /// - public sealed class UnknownFieldSet { + public sealed class UnknownFieldSet : IMessageLite { private static readonly UnknownFieldSet defaultInstance = new UnknownFieldSet(new Dictionary()); @@ -237,16 +237,43 @@ namespace Google.ProtocolBuffers { return CreateBuilder().MergeFrom(input).Build(); } + #region IMessageLite Members + + public bool IsInitialized { + get { return fields != null; } + } + + public void WriteDelimitedTo(Stream output) { + CodedOutputStream codedOutput = CodedOutputStream.CreateInstance(output); + codedOutput.WriteRawVarint32((uint) SerializedSize); + WriteTo(codedOutput); + codedOutput.Flush(); + } + + public IBuilderLite WeakCreateBuilderForType() { + return new Builder(); + } + + public IBuilderLite WeakToBuilder() { + return new Builder(fields); + } + + public IMessageLite WeakDefaultInstanceForType { + get { return defaultInstance; } + } + + #endregion + /// /// Builder for UnknownFieldSets. /// - public sealed class Builder + public sealed class Builder : IBuilderLite { /// /// Mapping from number to field. Note that by using a SortedList we ensure /// that the fields will be serialized in ascending order. /// - private IDictionary fields = new SortedList(); + private IDictionary fields; // Optimization: We keep around a builder for the last field that was // modified so that we can efficiently add to it multiple times in a // row (important when parsing an unknown repeated field). @@ -254,6 +281,11 @@ namespace Google.ProtocolBuffers { private UnknownField.Builder lastField; internal Builder() { + fields = new SortedList(); + } + + internal Builder(IDictionary dictionary) { + fields = new SortedList(dictionary); } /// @@ -356,7 +388,9 @@ namespace Google.ProtocolBuffers { return true; case WireFormat.WireType.StartGroup: { Builder subBuilder = CreateBuilder(); +#pragma warning disable 0612 input.ReadUnknownGroup(number, subBuilder); +#pragma warning restore 0612 GetFieldBuilder(number).AddGroup(subBuilder.Build()); return true; } @@ -463,12 +497,14 @@ namespace Google.ProtocolBuffers { return this; } - internal void MergeFrom(CodedInputStream input, ExtensionRegistry extensionRegistry, IBuilder builder) { + internal void MergeFrom(CodedInputStream input, ExtensionRegistryLite extensionRegistryLite, IBuilder builder) { while (true) { uint tag = input.ReadTag(); if (tag == 0) { break; } + + ExtensionRegistry extensionRegistry = (extensionRegistryLite as ExtensionRegistry) ?? ExtensionRegistry.CreateInstance(); if (!MergeFieldFrom(input, extensionRegistry, builder, tag)) { // end group tag break; @@ -485,7 +521,7 @@ namespace Google.ProtocolBuffers { /// Builder to merge field into, if it's a known field /// The tag, which should already have been read from the input /// true unless the tag is an end-group tag - internal bool MergeFieldFrom(CodedInputStream input, + internal bool MergeFieldFrom(CodedInputStream input, ExtensionRegistry extensionRegistry, IBuilder builder, uint tag) { MessageDescriptor type = builder.DescriptorForType; @@ -672,6 +708,54 @@ namespace Google.ProtocolBuffers { builder[field] = subBuilder.WeakBuild(); } } + + #region IBuilderLite Members + + bool IBuilderLite.IsInitialized { + get { return fields != null; } + } + + IBuilderLite IBuilderLite.WeakClear() { + return Clear(); + } + + IBuilderLite IBuilderLite.WeakMergeFrom(IMessageLite message) { + return MergeFrom((UnknownFieldSet)message); + } + + IBuilderLite IBuilderLite.WeakMergeFrom(ByteString data) { + return MergeFrom(data); + } + + IBuilderLite IBuilderLite.WeakMergeFrom(ByteString data, ExtensionRegistryLite registry) { + return MergeFrom(data); + } + + IBuilderLite IBuilderLite.WeakMergeFrom(CodedInputStream input) { + return MergeFrom(input); + } + + IBuilderLite IBuilderLite.WeakMergeFrom(CodedInputStream input, ExtensionRegistryLite registry) { + return MergeFrom(input); + } + + IMessageLite IBuilderLite.WeakBuild() { + return Build(); + } + + IMessageLite IBuilderLite.WeakBuildPartial() { + return Build(); + } + + IBuilderLite IBuilderLite.WeakClone() { + return Build().WeakToBuilder(); + } + + IMessageLite IBuilderLite.WeakDefaultInstanceForType { + get { return DefaultInstance; } + } + + #endregion } } } diff --git a/src/ProtocolBuffers/WireFormat.cs b/src/ProtocolBuffers/WireFormat.cs index 22346460d1..508f1b485d 100644 --- a/src/ProtocolBuffers/WireFormat.cs +++ b/src/ProtocolBuffers/WireFormat.cs @@ -33,7 +33,9 @@ #endregion using System; +#if !LITE using Google.ProtocolBuffers.Descriptors; +#endif namespace Google.ProtocolBuffers { @@ -115,6 +117,7 @@ namespace Google.ProtocolBuffers { return (uint) (fieldNumber << TagTypeBits) | (uint) wireType; } +#if !LITE [CLSCompliant(false)] public static uint MakeTag(FieldDescriptor field) { return MakeTag(field.FieldNumber, GetWireType(field)); @@ -170,5 +173,6 @@ namespace Google.ProtocolBuffers { throw new ArgumentOutOfRangeException("No such field type"); } } +#endif } }