Browse Source

Implemented AbstractMethod and split the descriptors into a new package

Jon Skeet 17 years ago
parent
commit
fe7bb26214

+ 177 - 0
csharp/ProtocolBuffers/AbstractMessage.cs

@@ -0,0 +1,177 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.
+// http://code.google.com/p/protobuf/
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.IO;
+using System.Text;
+using Google.ProtocolBuffers.Descriptors;
+
+namespace Google.ProtocolBuffers {
+  /// <summary>
+  /// Implementation of the non-generic IMessage interface as far as possible.
+  /// </summary>
+  public abstract class AbstractMessage : IMessage {
+    // TODO(jonskeet): Cleaner to use a Nullable<int>?
+    /// <summary>
+    /// The serialized size if it's already been computed, or -1
+    /// if we haven't computed it yet.
+    /// </summary>
+    private int memoizedSize = -1;
+
+    #region Unimplemented members of IMessage
+    public abstract MessageDescriptor DescriptorForType { get; }
+    public abstract IDictionary<Descriptors.FieldDescriptor, object> AllFields { get; }
+    public abstract bool HasField(Descriptors.FieldDescriptor field);
+    public abstract object this[Descriptors.FieldDescriptor field] { get; }
+    public abstract int GetRepeatedFieldCount(Descriptors.FieldDescriptor field);
+    public abstract object this[Descriptors.FieldDescriptor field, int index] { get; }
+    public abstract UnknownFieldSet UnknownFields { get; }
+    public abstract IMessage DefaultInstanceForType { get; }
+    #endregion
+
+    public bool IsInitialized {
+      get {
+        // Check that all required fields are present.
+        foreach (FieldDescriptor field in DescriptorForType.Fields) {
+          if (field.IsRequired && !HasField(field)) {
+            return false;
+          }
+        }
+
+        // Check that embedded messages are initialized.
+        foreach (KeyValuePair<FieldDescriptor, object> entry in AllFields) {
+          FieldDescriptor field = entry.Key;
+          if (field.MappedType == MappedType.Message) {
+            if (field.IsRepeated) {
+              // We know it's an IList<T>, but not the exact type - so
+              // IEnumerable is the best we can do. (C# generics aren't covariant yet.)
+              foreach (IMessage element in (IEnumerable)entry.Value) {
+                if (!element.IsInitialized) {
+                  return false;
+                }
+              }
+            } else {
+              if (!((IMessage)entry.Value).IsInitialized) {
+                return false;
+              }
+            }
+          }
+        }
+        return true;
+      }
+    }
+
+    public sealed override string ToString() {
+      return TextFormat.PrintToString(this);
+    }
+
+    public void WriteTo(CodedOutputStream output) {
+      foreach (KeyValuePair<FieldDescriptor, object> entry in AllFields) {
+        FieldDescriptor field = entry.Key;
+        if (field.IsRepeated) {
+          // We know it's an IList<T>, but not the exact type - so
+          // IEnumerable is the best we can do. (C# generics aren't covariant yet.)
+          foreach (object element in (IEnumerable)entry.Value) {
+            output.WriteField(field.FieldType, field.FieldNumber, element);
+          }
+        } else {
+          output.WriteField(field.FieldType, field.FieldNumber, entry.Value);
+        }
+      }
+
+      UnknownFieldSet unknownFields = UnknownFields;
+      if (DescriptorForType.Options.IsMessageSetWireFormat) {
+        unknownFields.WriteAsMessageSetTo(output);
+      } else {
+        unknownFields.WriteTo(output);
+      }
+    }
+
+    public int SerializedSize {
+      get {
+        int size = memoizedSize;
+        if (size != -1) {
+          return size;
+        }
+
+        size = 0;
+        foreach (KeyValuePair<FieldDescriptor, object> entry in AllFields) {
+          FieldDescriptor field = entry.Key;
+          if (field.IsRepeated) {
+            foreach (object element in (IEnumerable)entry.Value) {
+              size += CodedOutputStream.ComputeFieldSize(field.FieldType, field.FieldNumber, element);
+            }
+          } else {
+            size += CodedOutputStream.ComputeFieldSize(field.FieldType, field.FieldNumber, entry.Value);
+          }
+        }
+
+        UnknownFieldSet unknownFields = UnknownFields;
+        if (DescriptorForType.Options.IsMessageSetWireFormat) {
+          size += unknownFields.SerializedSizeAsMessageSet;
+        } else {
+          size += unknownFields.SerializedSize;
+        }
+
+        memoizedSize = size;
+        return size;
+      }
+    }
+
+    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 abstract IBuilder CreateBuilderForType();
+
+    public override bool Equals(object other) {
+      if (other == this) {
+        return true;
+      }
+      IMessage otherMessage = other as IMessage;
+      if (otherMessage == null || otherMessage.DescriptorForType != DescriptorForType) {
+        return false;
+      }
+      // TODO(jonskeet): Check that dictionaries support equality appropriately
+      // (I suspect they don't!)
+      return AllFields.Equals(otherMessage.AllFields);
+    }
+
+    public override int GetHashCode() {
+      int hash = 41;
+      hash = (19 * hash) + DescriptorForType.GetHashCode();
+      hash = (53 * hash) + AllFields.GetHashCode();
+      return hash;
+    }
+  }
+}

+ 9 - 0
csharp/ProtocolBuffers/Autogenerated.cs

@@ -0,0 +1,9 @@
+// This file contains quick hacks to represent code that will be autogenerated.
+
+namespace Google.ProtocolBuffers {
+  public class DescriptorProtos {
+    public class MessageOptions {
+      public bool IsMessageSetWireFormat;
+    }
+  }
+}

+ 30 - 1
csharp/ProtocolBuffers/ByteString.cs

@@ -106,6 +106,35 @@ namespace Google.ProtocolBuffers {
     }
 
     // TODO(jonskeet): CopyTo, Equals, GetHashCode if they turn out to be required
-    // TODO(jonskeet): Input/Output stuff
+
+    /// <summary>
+    /// Builder for ByteStrings which allows them to be created without extra
+    /// copying being involved. This has to be a nested type in order to have access
+    /// to the private ByteString constructor.
+    /// </summary>
+    internal class CodedBuilder {
+      private readonly CodedOutputStream output;
+      private readonly byte[] buffer;
+
+      internal CodedBuilder(int size) {
+        buffer = new byte[size];
+        output = CodedOutputStream.CreateInstance(buffer);
+      }
+
+      public ByteString Build() {
+        output.CheckNoSpaceLeft();
+
+        // We can be confident that the CodedOutputStream will not modify the
+        // underlying bytes anymore because it already wrote all of them.  So,
+        // no need to make a copy.
+        return new ByteString(buffer);
+      }
+
+      public CodedOutputStream CodedOutput {
+        get {
+          return output;
+        }
+      }
+    }
   }
 }

+ 20 - 19
csharp/ProtocolBuffers/CodedInputStream.cs

@@ -17,6 +17,7 @@ using System;
 using System.Collections.Generic;
 using System.IO;
 using System.Text;
+using Google.ProtocolBuffers.Descriptors;
 
 namespace Google.ProtocolBuffers {
 
@@ -320,30 +321,30 @@ namespace Google.ProtocolBuffers {
     /// Reads a field of any primitive type. Enums, groups and embedded
     /// messages are not handled by this method.
     /// </summary>
-    public object readPrimitiveField(Descriptors.FieldDescriptor.Type fieldType) {
+    public object readPrimitiveField(FieldType fieldType) {
       switch (fieldType) {
-        case Descriptors.FieldDescriptor.Type.Double:   return ReadDouble();
-        case Descriptors.FieldDescriptor.Type.Float:    return ReadFloat();
-        case Descriptors.FieldDescriptor.Type.Int64:    return ReadInt64();
-        case Descriptors.FieldDescriptor.Type.UInt64:   return ReadUInt64();
-        case Descriptors.FieldDescriptor.Type.Int32:    return ReadInt32();
-        case Descriptors.FieldDescriptor.Type.Fixed64:  return ReadFixed64();
-        case Descriptors.FieldDescriptor.Type.Fixed32:  return ReadFixed32();
-        case Descriptors.FieldDescriptor.Type.Bool:     return ReadBool();
-        case Descriptors.FieldDescriptor.Type.String:   return ReadString();
-        case Descriptors.FieldDescriptor.Type.Bytes:    return ReadBytes();
-        case Descriptors.FieldDescriptor.Type.UInt32:   return ReadUInt32();
-        case Descriptors.FieldDescriptor.Type.SFixed32: return ReadSFixed32();
-        case Descriptors.FieldDescriptor.Type.SFixed64: return ReadSFixed64();
-        case Descriptors.FieldDescriptor.Type.SInt32:   return ReadSInt32();
-        case Descriptors.FieldDescriptor.Type.SInt64:   return ReadSInt64();
-        case Descriptors.FieldDescriptor.Type.Group:
+        case FieldType.Double:   return ReadDouble();
+        case FieldType.Float:    return ReadFloat();
+        case FieldType.Int64:    return ReadInt64();
+        case FieldType.UInt64:   return ReadUInt64();
+        case FieldType.Int32:    return ReadInt32();
+        case FieldType.Fixed64:  return ReadFixed64();
+        case FieldType.Fixed32:  return ReadFixed32();
+        case FieldType.Bool:     return ReadBool();
+        case FieldType.String:   return ReadString();
+        case FieldType.Bytes:    return ReadBytes();
+        case FieldType.UInt32:   return ReadUInt32();
+        case FieldType.SFixed32: return ReadSFixed32();
+        case FieldType.SFixed64: return ReadSFixed64();
+        case FieldType.SInt32:   return ReadSInt32();
+        case FieldType.SInt64:   return ReadSInt64();
+        case FieldType.Group:
             throw new ArgumentException("ReadPrimitiveField() cannot handle nested groups.");
-        case Descriptors.FieldDescriptor.Type.Message:
+        case FieldType.Message:
             throw new ArgumentException("ReadPrimitiveField() cannot handle embedded messages.");
         // We don't handle enums because we don't know what to do if the
         // value is not recognized.
-        case Descriptors.FieldDescriptor.Type.Enum:
+        case FieldType.Enum:
             throw new ArgumentException("ReadPrimitiveField() cannot handle enums.");
         default:
           throw new ArgumentOutOfRangeException("Invalid field type " + fieldType);

+ 67 - 38
csharp/ProtocolBuffers/CodedOutputStream.cs

@@ -16,6 +16,7 @@
 using System;
 using System.IO;
 using System.Text;
+using Google.ProtocolBuffers.Descriptors;
 
 namespace Google.ProtocolBuffers {
 
@@ -251,26 +252,26 @@ namespace Google.ProtocolBuffers {
       WriteTag(WireFormat.MessageSetField.Item, WireFormat.WireType.EndGroup);
     }
 
-    public void WriteField(Descriptors.FieldDescriptor.Type fieldType, int fieldNumber, object value) {
+    public void WriteField(FieldType fieldType, int fieldNumber, object value) {
       switch (fieldType) {
-        case Descriptors.FieldDescriptor.Type.Double: WriteDouble(fieldNumber, (double)value); break;
-        case Descriptors.FieldDescriptor.Type.Float: WriteFloat(fieldNumber, (float)value); break;
-        case Descriptors.FieldDescriptor.Type.Int64: WriteInt64(fieldNumber, (long)value); break;
-        case Descriptors.FieldDescriptor.Type.UInt64: WriteUInt64(fieldNumber, (ulong)value); break;
-        case Descriptors.FieldDescriptor.Type.Int32: WriteInt32(fieldNumber, (int)value); break;
-        case Descriptors.FieldDescriptor.Type.Fixed64: WriteFixed64(fieldNumber, (long)value); break;
-        case Descriptors.FieldDescriptor.Type.Fixed32: WriteFixed32(fieldNumber, (int)value); break;
-        case Descriptors.FieldDescriptor.Type.Bool: WriteBool(fieldNumber, (bool)value); break;
-        case Descriptors.FieldDescriptor.Type.String: WriteString(fieldNumber, (string)value); break;
-        case Descriptors.FieldDescriptor.Type.Group: WriteGroup(fieldNumber, (IMessage)value); break;
-        case Descriptors.FieldDescriptor.Type.Message: WriteMessage(fieldNumber, (IMessage)value); break;
-        case Descriptors.FieldDescriptor.Type.Bytes: WriteBytes(fieldNumber, (ByteString)value); break;
-        case Descriptors.FieldDescriptor.Type.UInt32: WriteUInt32(fieldNumber, (uint)value); break;
-        case Descriptors.FieldDescriptor.Type.SFixed32: WriteSFixed32(fieldNumber, (int)value); break;
-        case Descriptors.FieldDescriptor.Type.SFixed64: WriteSFixed64(fieldNumber, (long)value); break;
-        case Descriptors.FieldDescriptor.Type.SInt32: WriteSInt32(fieldNumber, (int)value); break;
-        case Descriptors.FieldDescriptor.Type.SInt64: WriteSInt64(fieldNumber, (long)value); break;
-        case Descriptors.FieldDescriptor.Type.Enum: WriteEnum(fieldNumber, ((Descriptors.EnumValueDescriptor)value).Number);
+        case FieldType.Double: WriteDouble(fieldNumber, (double)value); break;
+        case FieldType.Float: WriteFloat(fieldNumber, (float)value); break;
+        case FieldType.Int64: WriteInt64(fieldNumber, (long)value); break;
+        case FieldType.UInt64: WriteUInt64(fieldNumber, (ulong)value); break;
+        case FieldType.Int32: WriteInt32(fieldNumber, (int)value); break;
+        case FieldType.Fixed64: WriteFixed64(fieldNumber, (long)value); break;
+        case FieldType.Fixed32: WriteFixed32(fieldNumber, (int)value); break;
+        case FieldType.Bool: WriteBool(fieldNumber, (bool)value); break;
+        case FieldType.String: WriteString(fieldNumber, (string)value); break;
+        case FieldType.Group: WriteGroup(fieldNumber, (IMessage)value); break;
+        case FieldType.Message: WriteMessage(fieldNumber, (IMessage)value); break;
+        case FieldType.Bytes: WriteBytes(fieldNumber, (ByteString)value); break;
+        case FieldType.UInt32: WriteUInt32(fieldNumber, (uint)value); break;
+        case FieldType.SFixed32: WriteSFixed32(fieldNumber, (int)value); break;
+        case FieldType.SFixed64: WriteSFixed64(fieldNumber, (long)value); break;
+        case FieldType.SInt32: WriteSInt32(fieldNumber, (int)value); break;
+        case FieldType.SInt64: WriteSInt64(fieldNumber, (long)value); break;
+        case FieldType.Enum: WriteEnum(fieldNumber, ((Descriptors.EnumValueDescriptor)value).Number);
           break;
       }
     }
@@ -617,26 +618,26 @@ namespace Google.ProtocolBuffers {
      *               {@link Message#getField(Descriptors.FieldDescriptor)} for
      *               this field.
      */
-    public static int ComputeFieldSize(Descriptors.FieldDescriptor.Type fieldType, int fieldNumber, Object value) {
+    public static int ComputeFieldSize(FieldType fieldType, int fieldNumber, Object value) {
       switch (fieldType) {
-        case Descriptors.FieldDescriptor.Type.Double: return ComputeDoubleSize(fieldNumber, (double)value);
-        case Descriptors.FieldDescriptor.Type.Float: return ComputeFloatSize(fieldNumber, (float)value);
-        case Descriptors.FieldDescriptor.Type.Int64: return ComputeInt64Size(fieldNumber, (long)value);
-        case Descriptors.FieldDescriptor.Type.UInt64: return ComputeUInt64Size(fieldNumber, (ulong)value);
-        case Descriptors.FieldDescriptor.Type.Int32: return ComputeInt32Size(fieldNumber, (int)value);
-        case Descriptors.FieldDescriptor.Type.Fixed64: return ComputeFixed64Size(fieldNumber, (long)value);
-        case Descriptors.FieldDescriptor.Type.Fixed32: return ComputeFixed32Size(fieldNumber, (int)value);
-        case Descriptors.FieldDescriptor.Type.Bool: return ComputeBoolSize(fieldNumber, (bool)value);
-        case Descriptors.FieldDescriptor.Type.String: return ComputeStringSize(fieldNumber, (string)value);
-        case Descriptors.FieldDescriptor.Type.Group: return ComputeGroupSize(fieldNumber, (IMessage)value);
-        case Descriptors.FieldDescriptor.Type.Message: return ComputeMessageSize(fieldNumber, (IMessage)value);
-        case Descriptors.FieldDescriptor.Type.Bytes: return ComputeBytesSize(fieldNumber, (ByteString)value);
-        case Descriptors.FieldDescriptor.Type.UInt32: return ComputeUInt32Size(fieldNumber, (uint)value);
-        case Descriptors.FieldDescriptor.Type.SFixed32: return ComputeSFixed32Size(fieldNumber, (int)value);
-        case Descriptors.FieldDescriptor.Type.SFixed64: return ComputeSFixed64Size(fieldNumber, (long)value);
-        case Descriptors.FieldDescriptor.Type.SInt32: return ComputeSInt32Size(fieldNumber, (int)value);
-        case Descriptors.FieldDescriptor.Type.SInt64: return ComputeSInt64Size(fieldNumber, (long)value);
-        case Descriptors.FieldDescriptor.Type.Enum: return ComputeEnumSize(fieldNumber, ((Descriptors.EnumValueDescriptor)value).Number);
+        case FieldType.Double: return ComputeDoubleSize(fieldNumber, (double)value);
+        case FieldType.Float: return ComputeFloatSize(fieldNumber, (float)value);
+        case FieldType.Int64: return ComputeInt64Size(fieldNumber, (long)value);
+        case FieldType.UInt64: return ComputeUInt64Size(fieldNumber, (ulong)value);
+        case FieldType.Int32: return ComputeInt32Size(fieldNumber, (int)value);
+        case FieldType.Fixed64: return ComputeFixed64Size(fieldNumber, (long)value);
+        case FieldType.Fixed32: return ComputeFixed32Size(fieldNumber, (int)value);
+        case FieldType.Bool: return ComputeBoolSize(fieldNumber, (bool)value);
+        case FieldType.String: return ComputeStringSize(fieldNumber, (string)value);
+        case FieldType.Group: return ComputeGroupSize(fieldNumber, (IMessage)value);
+        case FieldType.Message: return ComputeMessageSize(fieldNumber, (IMessage)value);
+        case FieldType.Bytes: return ComputeBytesSize(fieldNumber, (ByteString)value);
+        case FieldType.UInt32: return ComputeUInt32Size(fieldNumber, (uint)value);
+        case FieldType.SFixed32: return ComputeSFixed32Size(fieldNumber, (int)value);
+        case FieldType.SFixed64: return ComputeSFixed64Size(fieldNumber, (long)value);
+        case FieldType.SInt32: return ComputeSInt32Size(fieldNumber, (int)value);
+        case FieldType.SInt64: return ComputeSInt64Size(fieldNumber, (long)value);
+        case FieldType.Enum: return ComputeEnumSize(fieldNumber, ((Descriptors.EnumValueDescriptor)value).Number);
         default:
           throw new ArgumentOutOfRangeException("Invalid field type " + fieldType);
       }
@@ -704,5 +705,33 @@ namespace Google.ProtocolBuffers {
         RefreshBuffer();
       }
     }
+
+    /// <summary>
+    /// Verifies that SpaceLeft returns zero. It's common to create a byte array
+    /// that is exactly big enough to hold a message, then write to it with
+    /// a CodedOutputStream. Calling CheckNoSpaceLeft after writing verifies that
+    /// the message was actually as big as expected, which can help bugs.
+    /// </summary>
+    public void CheckNoSpaceLeft() {
+      if (SpaceLeft != 0) {
+        throw new InvalidOperationException("Did not write as much data as expected.");
+      }
+    }
+
+    /// <summary>
+    /// If writing to a flat array, returns the space left in the array. Otherwise,
+    /// throws an InvalidOperationException.
+    /// </summary>
+    public int SpaceLeft {
+      get {
+        if (output == null) {
+          return limit - position;
+        } else {
+          throw new InvalidOperationException(
+            "SpaceLeft can only be called on CodedOutputStreams that are " +
+            "writing to a flat array.");
+        }
+      }
+    }
   }
 }

+ 0 - 53
csharp/ProtocolBuffers/Descriptors.cs

@@ -1,53 +0,0 @@
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 Google Inc.
-// http://code.google.com/p/protobuf/
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-using System;
-
-namespace Google.ProtocolBuffers {
-  public class Descriptors {
-    public class Descriptor {
-    }
-    public class FieldDescriptor {
-      public enum Type {
-        Double,
-        Float,
-        Int64,
-        UInt64,
-        Int32,
-        Fixed64,
-        Fixed32,
-        Bool,
-        String,
-        Group,
-        Message,
-        Bytes,
-        UInt32,
-        SFixed32,
-        SFixed64,
-        SInt32,
-        SInt64,
-        Enum
-      }
-    }
-
-    public class EnumValueDescriptor
-    {
-      public int Number
-      {
-        get { throw new NotImplementedException(); }
-      }
-    }
-  }
-}

+ 9 - 0
csharp/ProtocolBuffers/Descriptors/EnumValueDescriptor.cs

@@ -0,0 +1,9 @@
+using System;
+
+namespace Google.ProtocolBuffers.Descriptors {
+  public class EnumValueDescriptor {
+    public int Number {
+      get { throw new NotImplementedException(); }
+    }
+  }
+}

+ 17 - 0
csharp/ProtocolBuffers/Descriptors/FieldDescriptor.cs

@@ -0,0 +1,17 @@
+
+namespace Google.ProtocolBuffers.Descriptors {
+  public class FieldDescriptor {
+
+    public bool IsRequired {
+      get;
+      set;
+    }
+
+    public MappedType MappedType { get; set; }
+
+    public bool IsRepeated { get; set; }
+
+    public FieldType FieldType { get; set; }
+    public int FieldNumber { get; set; }
+  }
+}

+ 23 - 0
csharp/ProtocolBuffers/Descriptors/FieldType.cs

@@ -0,0 +1,23 @@
+
+namespace Google.ProtocolBuffers.Descriptors {
+  public enum FieldType {
+    Double,
+    Float,
+    Int64,
+    UInt64,
+    Int32,
+    Fixed64,
+    Fixed32,
+    Bool,
+    String,
+    Group,
+    Message,
+    Bytes,
+    UInt32,
+    SFixed32,
+    SFixed64,
+    SInt32,
+    SInt64,
+    Enum
+  }
+}

+ 12 - 0
csharp/ProtocolBuffers/Descriptors/MappedType.cs

@@ -0,0 +1,12 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace Google.ProtocolBuffers.Descriptors {
+  /// <summary>
+  /// Type as it's mapped onto a .NET type.
+  /// </summary>
+  public enum MappedType {
+    Message
+  }
+}

+ 9 - 0
csharp/ProtocolBuffers/Descriptors/MessageDescriptor.cs

@@ -0,0 +1,9 @@
+
+using System.Collections.Generic;
+
+namespace Google.ProtocolBuffers.Descriptors {
+  public class MessageDescriptor {
+    public IList<FieldDescriptor> Fields;
+    public DescriptorProtos.MessageOptions Options;
+  }
+}

+ 2 - 1
csharp/ProtocolBuffers/IBuilder.cs

@@ -16,6 +16,7 @@
 using System;
 using System.Collections.Generic;
 using System.IO;
+using Google.ProtocolBuffers.Descriptors;
 
 namespace Google.ProtocolBuffers {
 
@@ -54,7 +55,7 @@ namespace Google.ProtocolBuffers {
     /// Get the message's type's descriptor.
     /// <see cref="IMessage{T}.DescriptorForType"/>
     /// </summary>
-    Descriptors.Descriptor DescriptorForType { get; }
+    MessageDescriptor DescriptorForType { get; }
 
     /// <summary>
     /// <see cref="IMessage{T}.GetRepeatedFieldCount"/>

+ 5 - 5
csharp/ProtocolBuffers/IMessage.cs

@@ -16,6 +16,7 @@
 using System;
 using System.Collections.Generic;
 using System.IO;
+using Google.ProtocolBuffers.Descriptors;
 
 namespace Google.ProtocolBuffers {
 
@@ -33,7 +34,7 @@ namespace Google.ProtocolBuffers {
     /// method is an abstract method of IMessage whereas Descriptor is
     /// a static property of a specific class. They return the same thing.
     /// </summary>
-    Descriptors.Descriptor DescriptorForType { get; }
+    MessageDescriptor DescriptorForType { get; }
     /// <summary>
     /// Returns a collection of all the fields in this message which are set
     /// and their corresponding values.  A singular ("required" or "optional")
@@ -91,7 +92,7 @@ namespace Google.ProtocolBuffers {
     /// Returns true iff all required fields in the message and all embedded
     /// messages are set.
     /// </summary>
-    bool Initialized { get; }
+    bool IsInitialized { get; }
 
     /// <summary>
     /// Serializes the message and writes it to the given output stream.
@@ -119,7 +120,6 @@ namespace Google.ProtocolBuffers {
     /// Returns the hash code value for this message.
     /// TODO(jonskeet): Specify the hash algorithm, but better than the Java one!
     /// </summary>
-    /// <returns></returns>
     int GetHashCode();
     #endregion
 
@@ -164,7 +164,7 @@ namespace Google.ProtocolBuffers {
     /// <summary>
     /// Constructs a new builder for a message of the same type as this message.
     /// </summary>
-    IBuilder NewBuilderForType();
+    IBuilder CreateBuilderForType();
     #endregion
   }
 
@@ -186,7 +186,7 @@ namespace Google.ProtocolBuffers {
     /// <summary>
     /// Constructs a new builder for a message of the same type as this message.
     /// </summary>
-    new IBuilder<T> NewBuilderForType();
+    new IBuilder<T> CreateBuilderForType();
     #endregion
   }
 }

+ 7 - 1
csharp/ProtocolBuffers/ProtocolBuffers.csproj

@@ -37,15 +37,21 @@
   </ItemGroup>
   <ItemGroup>
     <Compile Include="AbstractMessage.cs" />
+    <Compile Include="Autogenerated.cs" />
     <Compile Include="ByteString.cs" />
     <Compile Include="CodedInputStream.cs" />
     <Compile Include="CodedOutputStream.cs" />
-    <Compile Include="Descriptors.cs" />
+    <Compile Include="Descriptors\EnumValueDescriptor.cs" />
+    <Compile Include="Descriptors\FieldDescriptor.cs" />
+    <Compile Include="Descriptors\FieldType.cs" />
+    <Compile Include="Descriptors\MappedType.cs" />
+    <Compile Include="Descriptors\MessageDescriptor.cs" />
     <Compile Include="ExtensionRegistry.cs" />
     <Compile Include="IBuilder.cs" />
     <Compile Include="IMessage.cs" />
     <Compile Include="InvalidProtocolBufferException.cs" />
     <Compile Include="Properties\AssemblyInfo.cs" />
+    <Compile Include="TextFormat.cs" />
     <Compile Include="UninitializedMessageException.cs" />
     <Compile Include="UnknownFieldSet.cs" />
     <Compile Include="WireFormat.cs" />

+ 11 - 0
csharp/ProtocolBuffers/TextFormat.cs

@@ -0,0 +1,11 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace Google.ProtocolBuffers {
+  public class TextFormat {
+    public static string PrintToString(IMessage message) {
+      throw new NotImplementedException();
+    }
+  }
+}

+ 6 - 0
csharp/ProtocolBuffers/UnknownFieldSet.cs

@@ -17,6 +17,8 @@ using System;
 
 namespace Google.ProtocolBuffers {
   public class UnknownFieldSet {
+    public int SerializedSizeAsMessageSet;
+
     public void WriteTo(CodedOutputStream output) {
       throw new NotImplementedException();
     }
@@ -29,5 +31,9 @@ namespace Google.ProtocolBuffers {
         throw new NotImplementedException();
       }
     }
+
+    internal void WriteAsMessageSetTo(CodedOutputStream output) {
+      throw new NotImplementedException();
+    }
   }
 }