Procházet zdrojové kódy

Completed abstract lite builder and message

csharptest před 15 roky
rodič
revize
80e73b922e

+ 47 - 233
src/ProtocolBuffers/AbstractBuilder.cs

@@ -42,93 +42,54 @@ namespace Google.ProtocolBuffers {
   /// <summary>
   /// Implementation of the non-generic IMessage interface as far as possible.
   /// </summary>
-  public abstract class AbstractBuilder<TMessage, TBuilder> : IBuilder<TMessage, TBuilder> 
+  public abstract class AbstractBuilder<TMessage, TBuilder> : AbstractBuilderLite<TMessage, TBuilder>, IBuilder<TMessage, TBuilder> 
       where TMessage : AbstractMessage<TMessage, TBuilder>
       where TBuilder : AbstractBuilder<TMessage, TBuilder> {
 
-    protected abstract TBuilder ThisBuilder { get; }
-    
     #region Unimplemented members of IBuilder
     public abstract UnknownFieldSet UnknownFields { get; set; }
-    public abstract TBuilder MergeFrom(TMessage other);
-    public abstract bool IsInitialized { get; }
     public abstract IDictionary<FieldDescriptor, object> AllFields { get; }
     public abstract object this[FieldDescriptor field] { get; set; }
     public abstract MessageDescriptor DescriptorForType { get; }
     public abstract int GetRepeatedFieldCount(FieldDescriptor field);
     public abstract object this[FieldDescriptor field, int index] { get; set; }
     public abstract bool HasField(FieldDescriptor field);
-    public abstract TMessage Build();
-    public abstract TMessage BuildPartial();
-    public abstract TBuilder Clone();
-    public abstract TMessage DefaultInstanceForType { get; }
     public abstract IBuilder CreateBuilderForField(FieldDescriptor field);
     public abstract TBuilder ClearField(FieldDescriptor field);
     public abstract TBuilder AddRepeatedField(FieldDescriptor field, object value);
     #endregion
 
-    #region Implementation of methods which don't require type parameter information
-    public IMessage WeakBuild() {
-      return Build();
-    }
-
-    public IBuilder WeakAddRepeatedField(FieldDescriptor field, object value) {
-      return AddRepeatedField(field, value);
-    }
-
-    public IBuilder WeakClear() {
-      return Clear();
-    }
-
-    public IBuilder WeakMergeFrom(IMessage message) {
-      return MergeFrom(message);
-    }
-
-    public IBuilder WeakMergeFrom(CodedInputStream input) {
-      return MergeFrom(input);
-    }
-
-    public IBuilder WeakMergeFrom(CodedInputStream input, ExtensionRegistryLite registry) {
-      return MergeFrom(input, registry);
-    }
-
-    public IBuilder WeakMergeFrom(ByteString data) {
-      return MergeFrom(data);
-    }
-
-    public IBuilder WeakMergeFrom(ByteString data, ExtensionRegistryLite registry) {
-      return MergeFrom(data, registry);
-    }
-
-    public IMessage WeakBuildPartial() {
-      return BuildPartial();
-    }
-
-    public IBuilder WeakClone() {
-      return Clone();
-    }
-
-    public IMessage WeakDefaultInstanceForType {
-      get { return DefaultInstanceForType; } 
-    }
-
-    public IBuilder WeakClearField(FieldDescriptor field) {
-      return ClearField(field);
-    }
-    #endregion
-
     public TBuilder SetUnknownFields(UnknownFieldSet fields) {
       UnknownFields = fields;
       return ThisBuilder;
     }
 
-    public virtual TBuilder Clear() {
+    public override TBuilder Clear() {
       foreach(FieldDescriptor field in AllFields.Keys) {
         ClearField(field);
       }
       return ThisBuilder;
     }
 
+    public sealed override TBuilder MergeFrom(IMessageLite other) {
+      return MergeFrom((IMessage)other);
+    }
+
+    /// <summary>
+    /// Merge the specified other message into the message being
+    /// built. Merging occurs as follows. For each field:
+    /// For singular primitive fields, if the field is set in <paramref name="other"/>,
+    /// then <paramref name="other"/>'s value overwrites the value in this message.
+    /// For singular message fields, if the field is set in <paramref name="other"/>,
+    /// it is merged into the corresponding sub-message of this message using the same
+    /// merging rules.
+    /// For repeated fields, the elements in <paramref name="other"/> are concatenated
+    /// with the elements in this message.
+    /// </summary>
+    /// <param name="other"></param>
+    /// <returns></returns>
+    public abstract TBuilder MergeFrom(TMessage other);
+
     public virtual TBuilder MergeFrom(IMessage other) {
       if (other.DescriptorForType != DescriptorForType) {
         throw new ArgumentException("MergeFrom(IMessage) can only merge messages of the same type.");
@@ -168,11 +129,7 @@ namespace Google.ProtocolBuffers {
       return ThisBuilder;
     }
 
-    public virtual TBuilder MergeFrom(CodedInputStream input) {
-      return MergeFrom(input, ExtensionRegistry.Empty);
-    }
-
-    public virtual TBuilder MergeFrom(CodedInputStream input, ExtensionRegistry extensionRegistry) {
+    public override TBuilder MergeFrom(CodedInputStream input, ExtensionRegistry extensionRegistry) {
       UnknownFieldSet.Builder unknownFields = UnknownFieldSet.CreateBuilder(UnknownFields);
       unknownFields.MergeFrom(input, extensionRegistry, this);
       UnknownFields = unknownFields.Build();
@@ -186,62 +143,6 @@ namespace Google.ProtocolBuffers {
       return ThisBuilder;
     }
 
-    public virtual TBuilder MergeFrom(ByteString data) {
-      CodedInputStream input = data.CreateCodedInput();
-      MergeFrom(input);
-      input.CheckLastTagWas(0);
-      return ThisBuilder;
-    }
-
-    public virtual TBuilder MergeFrom(ByteString data, ExtensionRegistry extensionRegistry) {
-      CodedInputStream input = data.CreateCodedInput();
-      MergeFrom(input, extensionRegistry);
-      input.CheckLastTagWas(0);
-      return ThisBuilder;
-    }
-
-    public virtual TBuilder MergeFrom(byte[] data) {
-      CodedInputStream input = CodedInputStream.CreateInstance(data);
-      MergeFrom(input);
-      input.CheckLastTagWas(0);
-      return ThisBuilder;
-    }
-
-    public virtual TBuilder MergeFrom(byte[] data, ExtensionRegistry extensionRegistry) {
-      CodedInputStream input = CodedInputStream.CreateInstance(data);
-      MergeFrom(input, extensionRegistry);
-      input.CheckLastTagWas(0);
-      return ThisBuilder;
-    }
-
-    public virtual TBuilder MergeFrom(Stream input) {
-      CodedInputStream codedInput = CodedInputStream.CreateInstance(input);
-      MergeFrom(codedInput);
-      codedInput.CheckLastTagWas(0);
-      return ThisBuilder;
-    }
-
-    public virtual TBuilder MergeFrom(Stream input, ExtensionRegistry extensionRegistry) {
-      CodedInputStream codedInput = CodedInputStream.CreateInstance(input);
-      MergeFrom(codedInput, extensionRegistry);
-      codedInput.CheckLastTagWas(0);
-      return ThisBuilder;
-    }
-
-    public TBuilder MergeDelimitedFrom(Stream input, ExtensionRegistry extensionRegistry) {
-      return Lite.MergeDelimitedFrom(input, extensionRegistry);
-    }
-
-    public TBuilder MergeDelimitedFrom(Stream input, ExtensionRegistryLite extensionRegistry) {
-      int size = (int) CodedInputStream.ReadRawVarint32(input);
-      Stream limitedStream = new LimitedInputStream(input, size);
-      return MergeFrom(limitedStream, extensionRegistry);
-    }
-
-    public TBuilder MergeDelimitedFrom(Stream input) {
-      return MergeDelimitedFrom(input, ExtensionRegistry.Empty);
-    }
-
     public virtual IBuilder SetField(FieldDescriptor field, object value) {
       this[field] = value;
       return ThisBuilder;
@@ -252,142 +153,55 @@ namespace Google.ProtocolBuffers {
       return ThisBuilder;
 	  }
 
+    #region Explicit Implementations
 
-    /// <summary>
-    /// used internally to explicitly resolve lite edition methods
-    /// </summary>
-    protected IBuilderLite<TMessage, TBuilder> Lite { get { return this; } }
-
-    public virtual TBuilder MergeFrom(IMessageLite other) {
-#warning Not implemented for Lite edition
-      return MergeFrom((IMessage)other);
-    }
-
-    public virtual TBuilder MergeFrom(CodedInputStream input, ExtensionRegistryLite extensionRegistry) {
-#warning Not implemented for Lite edition
-      return MergeFrom(input, (ExtensionRegistry)extensionRegistry);
-    }
-
-    public virtual TBuilder MergeFrom(ByteString data, ExtensionRegistryLite extensionRegistry) {
-#warning Not implemented for Lite edition
-      return MergeFrom(data, (ExtensionRegistry)extensionRegistry);
-    }
-
-    public virtual TBuilder MergeFrom(byte[] data, ExtensionRegistryLite extensionRegistry) {
-#warning Not implemented for Lite edition
-      return MergeFrom(data, (ExtensionRegistry)extensionRegistry);
+    IMessage IBuilder.WeakBuild() {
+      return Build();
     }
 
-    public virtual TBuilder MergeFrom(Stream input, ExtensionRegistryLite extensionRegistry) {
-#warning Not implemented for Lite edition
-      return MergeFrom(input, (ExtensionRegistry)extensionRegistry);
+    IBuilder IBuilder.WeakAddRepeatedField(FieldDescriptor field, object value) {
+      return AddRepeatedField(field, value);
     }
 
-    IBuilderLite IBuilderLite.WeakClear() {
-      return WeakClear();
+    IBuilder IBuilder.WeakClear() {
+      return Clear();
     }
 
-    public IBuilderLite WeakMergeFrom(IMessageLite message) {
+    IBuilder IBuilder.WeakMergeFrom(IMessage message) {
       return MergeFrom(message);
     }
 
-    IBuilderLite IBuilderLite.WeakMergeFrom(ByteString data) {
-      return WeakMergeFrom(data); 
+    IBuilder IBuilder.WeakMergeFrom(CodedInputStream input) {
+      return MergeFrom(input);
     }
 
-    IBuilderLite IBuilderLite.WeakMergeFrom(ByteString data, ExtensionRegistryLite registry) {
-      return WeakMergeFrom(data, registry);
+    IBuilder IBuilder.WeakMergeFrom(CodedInputStream input, ExtensionRegistry registry) {
+      return MergeFrom(input, registry);
     }
 
-    IBuilderLite IBuilderLite.WeakMergeFrom(CodedInputStream input) {
-      return WeakMergeFrom(input);
+    IBuilder IBuilder.WeakMergeFrom(ByteString data) {
+      return MergeFrom(data);
     }
 
-    IBuilderLite IBuilderLite.WeakMergeFrom(CodedInputStream input, ExtensionRegistryLite registry) {
-      return WeakMergeFrom(input, registry);
+    IBuilder IBuilder.WeakMergeFrom(ByteString data, ExtensionRegistry registry) {
+      return MergeFrom(data, registry);
     }
 
-    IMessageLite IBuilderLite.WeakBuild() {
-      return WeakBuild(); 
+    IMessage IBuilder.WeakBuildPartial() {
+      return BuildPartial();
     }
 
-    IMessageLite IBuilderLite.WeakBuildPartial() {
-      return WeakBuildPartial(); 
+    IBuilder IBuilder.WeakClone() {
+      return Clone();
     }
 
-    IBuilderLite IBuilderLite.WeakClone() {
-      return WeakClone(); 
+    IMessage IBuilder.WeakDefaultInstanceForType {
+      get { return DefaultInstanceForType; }
     }
 
-    IMessageLite IBuilderLite.WeakDefaultInstanceForType {
-      get { return WeakDefaultInstanceForType; }
+    IBuilder IBuilder.WeakClearField(FieldDescriptor field) {
+      return ClearField(field);
     }
-
-	#region LimitedInputStream
-	/// <summary>
-    /// Stream implementation which proxies another stream, only allowing a certain amount
-    /// of data to be read. Note that this is only used to read delimited streams, so it
-    /// doesn't attempt to implement everything.
-    /// </summary>
-    private class LimitedInputStream : Stream {
-
-      private readonly Stream proxied;
-      private int bytesLeft;
-
-      internal LimitedInputStream(Stream proxied, int size) {
-        this.proxied = proxied;
-        bytesLeft = size;
-      }
-
-      public override bool CanRead {
-        get { return true; }
-      }
-
-      public override bool CanSeek {
-        get { return false; }
-      }
-
-      public override bool CanWrite {
-        get { return false; }
-      }
-
-      public override void Flush() {
-      }
-
-      public override long Length {
-        get { throw new NotSupportedException(); }
-      }
-
-      public override long Position {
-        get {
-          throw new NotSupportedException();
-        }
-        set {
-          throw new NotSupportedException();
-        }
-      }
-
-      public override int Read(byte[] buffer, int offset, int count) {
-        if (bytesLeft > 0) {
-          int bytesRead = proxied.Read(buffer, offset, Math.Min(bytesLeft, count));
-          bytesLeft -= bytesRead;
-          return bytesRead;
-        }
-        return 0;
-      }
-
-      public override long Seek(long offset, SeekOrigin origin) {
-        throw new NotSupportedException();
-      }
-
-      public override void SetLength(long value) {
-        throw new NotSupportedException();
-      }
-
-      public override void Write(byte[] buffer, int offset, int count) {
-        throw new NotSupportedException();
-      }
-	}
-	#endregion
+    #endregion
   }
 }

+ 47 - 54
src/ProtocolBuffers/AbstractMessage.cs

@@ -42,7 +42,7 @@ namespace Google.ProtocolBuffers {
   /// <summary>
   /// Implementation of the non-generic IMessage interface as far as possible.
   /// </summary>
-  public abstract class AbstractMessage<TMessage, TBuilder> : IMessage<TMessage, TBuilder> 
+  public abstract class AbstractMessage<TMessage, TBuilder> : AbstractMessageLite<TMessage, TBuilder>, IMessage<TMessage, TBuilder> 
       where TMessage : AbstractMessage<TMessage, TBuilder> 
       where TBuilder : AbstractBuilder<TMessage, TBuilder> {
     /// <summary>
@@ -59,28 +59,13 @@ namespace Google.ProtocolBuffers {
     public abstract int GetRepeatedFieldCount(FieldDescriptor field);
     public abstract object this[FieldDescriptor field, int index] { get; }
     public abstract UnknownFieldSet UnknownFields { get; }
-    public abstract TMessage DefaultInstanceForType { get; }
-    public abstract TBuilder CreateBuilderForType();
-    public abstract TBuilder ToBuilder();
     #endregion
-    
-    public IBuilder WeakCreateBuilderForType() {
-      return CreateBuilderForType();
-    }
-
-    public IBuilder WeakToBuilder() {
-      return ToBuilder();
-    }
-
-    IMessageLite IMessageLite.WeakDefaultInstanceForType {
-      get { return DefaultInstanceForType; }
-    }
-
-    public IMessage WeakDefaultInstanceForType {
-      get { return DefaultInstanceForType; }
-    }
 
-    public virtual bool IsInitialized {
+    /// <summary>
+    /// Returns true iff all required fields in the message and all embedded
+    /// messages are set.
+    /// </summary>
+    public override bool IsInitialized {
       get {
         // Check that all required fields are present.
         foreach (FieldDescriptor field in DescriptorForType.Fields) {
@@ -116,7 +101,19 @@ namespace Google.ProtocolBuffers {
       return TextFormat.PrintToString(this);
     }
 
-    public virtual void WriteTo(CodedOutputStream output) {
+    /// <summary>
+    /// Serializes the message and writes it to the given output stream.
+    /// This does not flush or close the stream.
+    /// </summary>
+    /// <remarks>
+    /// Protocol Buffers are not self-delimiting. Therefore, if you write
+    /// any more data to the stream after the message, you must somehow ensure
+    /// that the parser on the receiving end does not interpret this as being
+    /// part of the protocol message. One way of doing this is by writing the size
+    /// of the message before the data, then making sure you limit the input to
+    /// that size when receiving the data. Alternatively, use WriteDelimitedTo(Stream).
+    /// </remarks>
+    public override void WriteTo(CodedOutputStream output) {
       foreach (KeyValuePair<FieldDescriptor, object> entry in AllFields) {
         FieldDescriptor field = entry.Key;
         if (field.IsRepeated) {
@@ -151,7 +148,11 @@ namespace Google.ProtocolBuffers {
       }
     }
 
-    public virtual int SerializedSize {
+    /// <summary>
+    /// Returns the number of bytes required to encode this message.
+    /// The result is only computed on the first call and memoized after that.
+    /// </summary>
+    public override int SerializedSize {
       get {
         if (memoizedSize != null) {
           return memoizedSize.Value;
@@ -192,33 +193,12 @@ namespace Google.ProtocolBuffers {
       }
     }
 
-    public ByteString ToByteString() {
-      ByteString.CodedBuilder output = new ByteString.CodedBuilder(SerializedSize);
-      WriteTo(output.CodedOutput);
-      return output.Build();
-    }
-
-    public byte[] ToByteArray() {
-      byte[] result = new byte[SerializedSize];
-      CodedOutputStream output = CodedOutputStream.CreateInstance(result);
-      WriteTo(output);
-      output.CheckNoSpaceLeft();
-      return result;
-    }
-
-    public void WriteTo(Stream output) {
-      CodedOutputStream codedOutput = CodedOutputStream.CreateInstance(output);
-      WriteTo(codedOutput);
-      codedOutput.Flush();
-    }
-
-    public void WriteDelimitedTo(Stream output) {
-      CodedOutputStream codedOutput = CodedOutputStream.CreateInstance(output);
-      codedOutput.WriteRawVarint32((uint) SerializedSize);
-      WriteTo(codedOutput);
-      codedOutput.Flush();
-    }
-
+    /// <summary>
+    /// Compares the specified object with this message for equality.
+    /// Returns true iff the given object is a message of the same type
+    /// (as defined by DescriptorForType) and has identical values
+    /// for all its fields.
+    /// </summary>
     public override bool Equals(object other) {
       if (other == this) {
         return true;
@@ -230,6 +210,10 @@ namespace Google.ProtocolBuffers {
       return Dictionaries.Equals(AllFields, otherMessage.AllFields) && UnknownFields.Equals(otherMessage.UnknownFields);
     }
 
+    /// <summary>
+    /// Returns the hash code value for this message.
+    /// TODO(jonskeet): Specify the hash algorithm, but better than the Java one!
+    /// </summary>
     public override int GetHashCode() {
       int hash = 41;
       hash = (19 * hash) + DescriptorForType.GetHashCode();
@@ -238,11 +222,20 @@ namespace Google.ProtocolBuffers {
       return hash;
     }
 
-    IBuilderLite IMessageLite.WeakCreateBuilderForType() {
-      return WeakCreateBuilderForType(); }
+    #region Explicit Members
+    
+    IBuilder IMessage.WeakCreateBuilderForType() {
+      return CreateBuilderForType();
+    }
 
-    IBuilderLite IMessageLite.WeakToBuilder() {
-      return WeakToBuilder();
+    IBuilder IMessage.WeakToBuilder() {
+      return ToBuilder();
     }
+
+    IMessage IMessage.WeakDefaultInstanceForType {
+      get { return DefaultInstanceForType; }
+    }
+
+    #endregion
   }
 }

+ 2 - 2
src/ProtocolBuffers/CodedInputStream.cs

@@ -261,7 +261,7 @@ namespace Google.ProtocolBuffers {
     /// Reads a group field value from the stream.
     /// </summary>    
     public void ReadGroup(int fieldNumber, IBuilderLite builder,
-                          ExtensionRegistryLite extensionRegistry) {
+                          ExtensionRegistry extensionRegistry) {
       if (recursionDepth >= recursionLimit) {
         throw InvalidProtocolBufferException.RecursionLimitExceeded();
       }
@@ -290,7 +290,7 @@ namespace Google.ProtocolBuffers {
     /// <summary>
     /// Reads an embedded message field value from the stream.
     /// </summary>   
-    public void ReadMessage(IBuilderLite builder, ExtensionRegistryLite extensionRegistry) {
+    public void ReadMessage(IBuilderLite builder, ExtensionRegistry extensionRegistry) {
       int length = (int) ReadRawVarint32();
       if (recursionDepth >= recursionLimit) {
         throw InvalidProtocolBufferException.RecursionLimitExceeded();

+ 5 - 14
src/ProtocolBuffers/ExtensionRegistry.cs

@@ -88,8 +88,8 @@ namespace Google.ProtocolBuffers {
   /// could take advantage of this to inject a mutable object into a message
   /// belonging to privileged code and create mischief.</para>
   /// </remarks>
-  public sealed class ExtensionRegistry : ExtensionRegistryLite {
-
+  public sealed partial class ExtensionRegistry {
+#if !LITE
     private static readonly ExtensionRegistry empty = new ExtensionRegistry(
         new Dictionary<string, ExtensionInfo>(),
         new Dictionary<ExtensionIntPair, IGeneratedExtensionLite>(),
@@ -100,7 +100,7 @@ namespace Google.ProtocolBuffers {
     private ExtensionRegistry(IDictionary<String, ExtensionInfo> extensionsByName,
         IDictionary<ExtensionIntPair, IGeneratedExtensionLite> extensionsByNumber,
         bool readOnly)
-      : base(extensionsByNumber, readOnly) {
+      : this(extensionsByNumber, readOnly) {
       this.extensionsByName = extensionsByName;
     }
 
@@ -112,19 +112,10 @@ namespace Google.ProtocolBuffers {
         new Dictionary<ExtensionIntPair, IGeneratedExtensionLite>(), false);
     }
 
-    /// <summary>
-    /// Get the unmodifiable singleton empty instance.
-    /// </summary>
-    public static ExtensionRegistry Empty {
-      get { return empty; }
-    }
-
-    public new ExtensionRegistry AsReadOnly() {
+    public ExtensionRegistry AsReadOnly() {
       return new ExtensionRegistry(extensionsByName, extensionsByNumber, true);
     }
-    protected override ExtensionRegistryLite MakeReadOnly() {
-      return AsReadOnly();
-    }
+#endif
 
     /// <summary>
     /// Finds an extension by fully-qualified field name, in the

+ 21 - 25
src/ProtocolBuffers/ExtensionRegistryLite.cs

@@ -37,11 +37,10 @@ using System;
 
 namespace Google.ProtocolBuffers {
 
-
   /// <summary>
   /// A table of known extensions, searchable by name or field number.  When
   /// parsing a protocol message that might have extensions, you must provide
-  /// an <see cref="ExtensionRegistryLite"/> in which you have registered any extensions
+  /// an <see cref="ExtensionRegistry"/> 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.
   /// </summary>
@@ -62,7 +61,7 @@ namespace Google.ProtocolBuffers {
   /// Then you might write code like:
   ///
   /// <code>
-  /// ExtensionRegistryLite registry = ExtensionRegistryLite.CreateInstance();
+  /// extensionRegistry registry = extensionRegistry.CreateInstance();
   /// registry.Add(MyProto.Bar);
   /// MyProto.Foo message = MyProto.Foo.ParseFrom(input, registry);
   /// </code>
@@ -89,43 +88,40 @@ namespace Google.ProtocolBuffers {
   /// could take advantage of this to inject a mutable object into a message
   /// belonging to privileged code and create mischief.</para>
   /// </remarks>
-  public class ExtensionRegistryLite {
-
-    private static readonly ExtensionRegistryLite empty = new ExtensionRegistryLite(
-        new Dictionary<ExtensionIntPair, IGeneratedExtensionLite>(),
-        true);
+  public sealed partial class ExtensionRegistry {
+    private readonly IDictionary<ExtensionIntPair, IGeneratedExtensionLite> extensionsByNumber;
+    private readonly bool readOnly;
 
-    protected readonly IDictionary<ExtensionIntPair, IGeneratedExtensionLite> extensionsByNumber;
-    protected readonly bool readOnly;
-
-    protected ExtensionRegistryLite(IDictionary<ExtensionIntPair, IGeneratedExtensionLite> extensionsByNumber,
+    private ExtensionRegistry(IDictionary<ExtensionIntPair, IGeneratedExtensionLite> extensionsByNumber,
         bool readOnly) {
       this.extensionsByNumber = extensionsByNumber;
       this.readOnly = readOnly;
     }
+
 #if LITE
+    private static readonly ExtensionRegistry empty = new ExtensionRegistry(
+        new Dictionary<ExtensionIntPair, IGeneratedExtensionLite>(),
+        true);
+
     /// <summary>
     /// Construct a new, empty instance.
     /// </summary>
-    public static ExtensionRegistryLite CreateInstance() {
-      return new ExtensionRegistryLite(
+    public static ExtensionRegistry CreateInstance() {
+      return new ExtensionRegistry(
         new Dictionary<ExtensionIntPair, IGeneratedExtensionLite>(), false);
     }
+    public ExtensionRegistry AsReadOnly() {
+      return new ExtensionRegistry(extensionsByNumber, true);
+    }
+
+#endif
 
     /// <summary>
     /// Get the unmodifiable singleton empty instance.
     /// </summary>
-    public static ExtensionRegistryLite Empty {
+    public static ExtensionRegistry Empty {
       get { return empty; }
     }
-#endif
-    public ExtensionRegistryLite AsReadOnly() {
-      return MakeReadOnly();
-    }
-
-    protected virtual ExtensionRegistryLite MakeReadOnly() {
-      return new ExtensionRegistryLite(extensionsByNumber, true);
-    }
 
     /// <summary>
     /// Finds an extension by containing type and field number.
@@ -142,7 +138,7 @@ namespace Google.ProtocolBuffers {
     /// <summary>
     /// Add an extension from a generated file to the registry.
     /// </summary>
-    public virtual void Add(IGeneratedExtensionLite extension) {
+    public void Add(IGeneratedExtensionLite extension) {
       if (readOnly) {
         throw new InvalidOperationException("Cannot add entries to a read-only extension registry");
       }
@@ -155,7 +151,7 @@ namespace Google.ProtocolBuffers {
     /// Nested type just used to represent a pair of MessageDescriptor and int, as
     /// the key into the "by number" map.
     /// </summary>
-    protected struct ExtensionIntPair : IEquatable<ExtensionIntPair> {
+    private struct ExtensionIntPair : IEquatable<ExtensionIntPair> {
       readonly object msgType;
       readonly int number;
 

+ 10 - 25
src/ProtocolBuffers/IBuilder.cs

@@ -123,9 +123,9 @@ namespace Google.ProtocolBuffers {
     IBuilder WeakClearField(FieldDescriptor field);
     IBuilder WeakMergeFrom(IMessage message);
     new IBuilder WeakMergeFrom(ByteString data);
-    new IBuilder WeakMergeFrom(ByteString data, ExtensionRegistryLite registry);
+    new IBuilder WeakMergeFrom(ByteString data, ExtensionRegistry registry);
     new IBuilder WeakMergeFrom(CodedInputStream input);
-    new IBuilder WeakMergeFrom(CodedInputStream input, ExtensionRegistryLite registry);
+    new IBuilder WeakMergeFrom(CodedInputStream input, ExtensionRegistry registry);
     new IMessage WeakBuild();
     new IMessage WeakBuildPartial();
     new IBuilder WeakClone();
@@ -150,21 +150,6 @@ namespace Google.ProtocolBuffers {
     /// </summary>
     new TBuilder Clear();
 
-    /// <summary>
-    /// Merge the specified other message into the message being
-    /// built. Merging occurs as follows. For each field:
-    /// For singular primitive fields, if the field is set in <paramref name="other"/>,
-    /// then <paramref name="other"/>'s value overwrites the value in this message.
-    /// For singular message fields, if the field is set in <paramref name="other"/>,
-    /// it is merged into the corresponding sub-message of this message using the same
-    /// merging rules.
-    /// For repeated fields, the elements in <paramref name="other"/> are concatenated
-    /// with the elements in this message.
-    /// </summary>
-    /// <param name="other"></param>
-    /// <returns></returns>
-    new TBuilder MergeFrom(TMessage other);
-
     /// <summary>
     /// Merge the specified other message which may be a different implementation of
     /// the same message descriptor.
@@ -221,7 +206,7 @@ namespace Google.ProtocolBuffers {
     /// in <paramref name="extensionRegistry"/>. Extensions not in the registry
     /// will be treated as unknown fields.
     /// </summary>
-    new TBuilder MergeFrom(CodedInputStream input, ExtensionRegistryLite extensionRegistry);
+    new TBuilder MergeFrom(CodedInputStream input, ExtensionRegistry extensionRegistry);
 
     /// <summary>
     /// Get's the message's type's default instance.
@@ -263,7 +248,7 @@ namespace Google.ProtocolBuffers {
     /// <summary>
     /// Like MergeDelimitedFrom(Stream) but supporting extensions.
     /// </summary>
-    new TBuilder MergeDelimitedFrom(Stream input, ExtensionRegistryLite extensionRegistry);
+    new TBuilder MergeDelimitedFrom(Stream input, ExtensionRegistry extensionRegistry);
 
     #region Convenience methods
     /// <summary>
@@ -276,9 +261,9 @@ namespace Google.ProtocolBuffers {
     /// <summary>
     /// Parse <paramref name="data"/> as a message of this type and merge
     /// it with the message being built. This is just a small wrapper around
-    /// MergeFrom(CodedInputStream, ExtensionRegistryLite).
+    /// MergeFrom(CodedInputStream, extensionRegistry).
     /// </summary>
-    new TBuilder MergeFrom(ByteString data, ExtensionRegistryLite extensionRegistry);
+    new TBuilder MergeFrom(ByteString data, ExtensionRegistry extensionRegistry);
 
     /// <summary>
     /// Parse <paramref name="data"/> as a message of this type and merge
@@ -290,9 +275,9 @@ namespace Google.ProtocolBuffers {
     /// <summary>
     /// Parse <paramref name="data"/> as a message of this type and merge
     /// it with the message being built. This is just a small wrapper around
-    /// MergeFrom(CodedInputStream, ExtensionRegistryLite).
+    /// MergeFrom(CodedInputStream, extensionRegistry).
     /// </summary>
-    new TBuilder MergeFrom(byte[] data, ExtensionRegistryLite extensionRegistry);
+    new TBuilder MergeFrom(byte[] data, ExtensionRegistry extensionRegistry);
 
     /// <summary>
     /// Parse <paramref name="input"/> as a message of this type and merge
@@ -309,9 +294,9 @@ namespace Google.ProtocolBuffers {
     /// <summary>
     /// Parse <paramref name="input"/> as a message of this type and merge
     /// it with the message being built. This is just a small wrapper around
-    /// MergeFrom(CodedInputStream, ExtensionRegistryLite).
+    /// MergeFrom(CodedInputStream, extensionRegistry).
     /// </summary>
-    new TBuilder MergeFrom(Stream input, ExtensionRegistryLite extensionRegistry);
+    new TBuilder MergeFrom(Stream input, ExtensionRegistry extensionRegistry);
     #endregion
   }
 }

+ 7 - 22
src/ProtocolBuffers/IBuilderLite.cs

@@ -56,9 +56,9 @@ namespace Google.ProtocolBuffers {
     IBuilderLite WeakClear();
     IBuilderLite WeakMergeFrom(IMessageLite message);
     IBuilderLite WeakMergeFrom(ByteString data);
-    IBuilderLite WeakMergeFrom(ByteString data, ExtensionRegistryLite registry);
+    IBuilderLite WeakMergeFrom(ByteString data, ExtensionRegistry registry);
     IBuilderLite WeakMergeFrom(CodedInputStream input);
-    IBuilderLite WeakMergeFrom(CodedInputStream input, ExtensionRegistryLite registry);
+    IBuilderLite WeakMergeFrom(CodedInputStream input, ExtensionRegistry registry);
     IMessageLite WeakBuild();
     IMessageLite WeakBuildPartial();
     IBuilderLite WeakClone();
@@ -80,21 +80,6 @@ namespace Google.ProtocolBuffers {
     /// </summary>
     TBuilder Clear();
 
-    /// <summary>
-    /// Merge the specified other message into the message being
-    /// built. Merging occurs as follows. For each field:
-    /// For singular primitive fields, if the field is set in <paramref name="other"/>,
-    /// then <paramref name="other"/>'s value overwrites the value in this message.
-    /// For singular message fields, if the field is set in <paramref name="other"/>,
-    /// it is merged into the corresponding sub-message of this message using the same
-    /// merging rules.
-    /// For repeated fields, the elements in <paramref name="other"/> are concatenated
-    /// with the elements in this message.
-    /// </summary>
-    /// <param name="other"></param>
-    /// <returns></returns>
-    TBuilder MergeFrom(TMessage other);
-
     /// <summary>
     /// Merge the specified other message which may be a different implementation of
     /// the same message descriptor.
@@ -151,7 +136,7 @@ namespace Google.ProtocolBuffers {
     /// in <paramref name="extensionRegistry"/>. Extensions not in the registry
     /// will be treated as unknown fields.
     /// </summary>
-    TBuilder MergeFrom(CodedInputStream input, ExtensionRegistryLite extensionRegistry);
+    TBuilder MergeFrom(CodedInputStream input, ExtensionRegistry extensionRegistry);
 
     /// <summary>
     /// Get's the message's type's default instance.
@@ -171,7 +156,7 @@ namespace Google.ProtocolBuffers {
     /// <summary>
     /// Like MergeDelimitedFrom(Stream) but supporting extensions.
     /// </summary>
-    TBuilder MergeDelimitedFrom(Stream input, ExtensionRegistryLite extensionRegistry);
+    TBuilder MergeDelimitedFrom(Stream input, ExtensionRegistry extensionRegistry);
 
     #region Convenience methods
     /// <summary>
@@ -186,7 +171,7 @@ namespace Google.ProtocolBuffers {
     /// it with the message being built. This is just a small wrapper around
     /// MergeFrom(CodedInputStream, ExtensionRegistry).
     /// </summary>
-    TBuilder MergeFrom(ByteString data, ExtensionRegistryLite extensionRegistry);
+    TBuilder MergeFrom(ByteString data, ExtensionRegistry extensionRegistry);
 
     /// <summary>
     /// Parse <paramref name="data"/> as a message of this type and merge
@@ -200,7 +185,7 @@ namespace Google.ProtocolBuffers {
     /// it with the message being built. This is just a small wrapper around
     /// MergeFrom(CodedInputStream, ExtensionRegistry).
     /// </summary>
-    TBuilder MergeFrom(byte[] data, ExtensionRegistryLite extensionRegistry);
+    TBuilder MergeFrom(byte[] data, ExtensionRegistry extensionRegistry);
 
     /// <summary>
     /// Parse <paramref name="input"/> as a message of this type and merge
@@ -219,7 +204,7 @@ namespace Google.ProtocolBuffers {
     /// it with the message being built. This is just a small wrapper around
     /// MergeFrom(CodedInputStream, ExtensionRegistry).
     /// </summary>
-    TBuilder MergeFrom(Stream input, ExtensionRegistryLite extensionRegistry);
+    TBuilder MergeFrom(Stream input, ExtensionRegistry extensionRegistry);
     #endregion
   }
 }

+ 8 - 0
src/ProtocolBuffers/ProtocolBuffers.csproj

@@ -46,10 +46,18 @@
   <ItemGroup>
     <Reference Include="mscorlib" />
     <Reference Include="System" />
+    <Reference Include="System.Data" />
+    <Reference Include="System.Xml" />
   </ItemGroup>
   <ItemGroup>
     <Compile Include="AbstractBuilder.cs" />
+    <Compile Include="AbstractBuilderLite.cs">
+      <SubType>Code</SubType>
+    </Compile>
     <Compile Include="AbstractMessage.cs" />
+    <Compile Include="AbstractMessageLite.cs">
+      <SubType>Code</SubType>
+    </Compile>
     <Compile Include="ByteString.cs" />
     <Compile Include="Collections\Enumerables.cs" />
     <Compile Include="Collections\IPopsicleList.cs" />

+ 2 - 0
src/ProtocolBuffers/ProtocolBuffersLite.csproj

@@ -53,6 +53,8 @@
     <None Include="Properties\Google.ProtocolBuffers.snk" />
   </ItemGroup>
   <ItemGroup>
+    <Compile Include="AbstractBuilderLite.cs" />
+    <Compile Include="AbstractMessageLite.cs" />
     <Compile Include="GeneratedExtensionLite.cs" />
     <Compile Include="Properties\AssemblyInfo.cs" />
     <Compile Include="ByteString.cs" />

+ 3 - 4
src/ProtocolBuffers/UnknownFieldSet.cs

@@ -497,14 +497,13 @@ namespace Google.ProtocolBuffers {
         return this;
       }
 
-      internal void MergeFrom(CodedInputStream input, ExtensionRegistryLite extensionRegistryLite, IBuilder builder) {
+      internal void MergeFrom(CodedInputStream input, ExtensionRegistry extensionRegistry, IBuilder builder) {
         while (true) {
           uint tag = input.ReadTag();
           if (tag == 0) {
             break;
           }
 
-          ExtensionRegistry extensionRegistry = (ExtensionRegistry)extensionRegistryLite;
           if (!MergeFieldFrom(input, extensionRegistry, builder, tag)) {
             // end group tag
             break;
@@ -727,7 +726,7 @@ namespace Google.ProtocolBuffers {
         return MergeFrom(data);
       }
 
-      IBuilderLite IBuilderLite.WeakMergeFrom(ByteString data, ExtensionRegistryLite registry) {
+      IBuilderLite IBuilderLite.WeakMergeFrom(ByteString data, ExtensionRegistry registry) {
         return MergeFrom(data);
       }
 
@@ -735,7 +734,7 @@ namespace Google.ProtocolBuffers {
         return MergeFrom(input);
       }
 
-      IBuilderLite IBuilderLite.WeakMergeFrom(CodedInputStream input, ExtensionRegistryLite registry) {
+      IBuilderLite IBuilderLite.WeakMergeFrom(CodedInputStream input, ExtensionRegistry registry) {
         return MergeFrom(input);
       }