aboutsummaryrefslogtreecommitdiff
path: root/src/ProtocolBuffers
diff options
context:
space:
mode:
authorcsharptest <roger@csharptest.net>2010-11-07 10:49:33 -0600
committercsharptest <roger@csharptest.net>2010-11-07 10:49:33 -0600
commit804b6d842e9202cd79039cd8e7aa899426d37f78 (patch)
treee0fe5bb1fcca18f49ae4909081a6cfd3291d947c /src/ProtocolBuffers
parent64bfac2825d69c0359e40c876ec4130e23f53fb7 (diff)
downloadprotobuf-804b6d842e9202cd79039cd8e7aa899426d37f78.tar.gz
protobuf-804b6d842e9202cd79039cd8e7aa899426d37f78.tar.bz2
protobuf-804b6d842e9202cd79039cd8e7aa899426d37f78.zip
Implementation work for Lite runtime and generator
Diffstat (limited to 'src/ProtocolBuffers')
-rw-r--r--src/ProtocolBuffers/CodedInputStream.cs5
-rw-r--r--src/ProtocolBuffers/CodedOutputStream.cs31
-rw-r--r--src/ProtocolBuffers/Descriptors/EnumDescriptor.cs11
-rw-r--r--src/ProtocolBuffers/Descriptors/EnumValueDescriptor.cs2
-rw-r--r--src/ProtocolBuffers/Descriptors/FieldDescriptor.cs21
-rw-r--r--src/ProtocolBuffers/DynamicMessage.cs8
-rw-r--r--src/ProtocolBuffers/EnumLite.cs31
-rw-r--r--src/ProtocolBuffers/ExtendableMessage.cs8
-rw-r--r--src/ProtocolBuffers/FieldSet.cs196
-rw-r--r--src/ProtocolBuffers/GeneratedExtensionLite.cs108
-rw-r--r--src/ProtocolBuffers/ProtocolBuffers.csproj1
-rw-r--r--src/ProtocolBuffers/ProtocolBuffersLite.csproj13
12 files changed, 319 insertions, 116 deletions
diff --git a/src/ProtocolBuffers/CodedInputStream.cs b/src/ProtocolBuffers/CodedInputStream.cs
index df177161..922957f2 100644
--- a/src/ProtocolBuffers/CodedInputStream.cs
+++ b/src/ProtocolBuffers/CodedInputStream.cs
@@ -36,9 +36,7 @@ using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
-#if !LITE
using Google.ProtocolBuffers.Descriptors;
-#endif
namespace Google.ProtocolBuffers {
@@ -363,7 +361,7 @@ namespace Google.ProtocolBuffers {
public long ReadSInt64() {
return DecodeZigZag64(ReadRawVarint64());
}
-#if !LITE
+
/// <summary>
/// Reads a field of any primitive type. Enums, groups and embedded
/// messages are not handled by this method.
@@ -397,7 +395,6 @@ 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 b261375c..264ca6ef 100644
--- a/src/ProtocolBuffers/CodedOutputStream.cs
+++ b/src/ProtocolBuffers/CodedOutputStream.cs
@@ -35,9 +35,8 @@
using System;
using System.IO;
using System.Text;
-#if !LITE
using Google.ProtocolBuffers.Descriptors;
-#endif
+
namespace Google.ProtocolBuffers {
/// <summary>
@@ -279,7 +278,6 @@ 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;
@@ -291,15 +289,15 @@ namespace Google.ProtocolBuffers {
case FieldType.Fixed32: WriteFixed32(fieldNumber, (uint)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.Group: WriteGroup(fieldNumber, (IMessageLite)value); break;
+ case FieldType.Message: WriteMessage(fieldNumber, (IMessageLite)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, ((EnumValueDescriptor)value).Number);
+ case FieldType.Enum: WriteEnum(fieldNumber, ((IEnumLite)value).Number);
break;
}
}
@@ -315,19 +313,18 @@ namespace Google.ProtocolBuffers {
case FieldType.Fixed32: WriteFixed32NoTag((uint)value); break;
case FieldType.Bool: WriteBoolNoTag((bool)value); break;
case FieldType.String: WriteStringNoTag((string)value); break;
- case FieldType.Group: WriteGroupNoTag((IMessage)value); break;
- case FieldType.Message: WriteMessageNoTag((IMessage)value); break;
+ case FieldType.Group: WriteGroupNoTag((IMessageLite)value); break;
+ case FieldType.Message: WriteMessageNoTag((IMessageLite)value); break;
case FieldType.Bytes: WriteBytesNoTag((ByteString)value); break;
case FieldType.UInt32: WriteUInt32NoTag((uint)value); break;
case FieldType.SFixed32: WriteSFixed32NoTag((int)value); break;
case FieldType.SFixed64: WriteSFixed64NoTag((long)value); break;
case FieldType.SInt32: WriteSInt32NoTag((int)value); break;
case FieldType.SInt64: WriteSInt64NoTag((long)value); break;
- case FieldType.Enum: WriteEnumNoTag(((EnumValueDescriptor)value).Number);
+ case FieldType.Enum: WriteEnumNoTag(((IEnumLite)value).Number);
break;
}
}
-#endif
#endregion
#region Writing of values without tags
@@ -995,7 +992,6 @@ namespace Google.ProtocolBuffers {
return 10;
}
-#if !LITE
/// <summary>
/// Compute the number of bytes that would be needed to encode a
/// field of arbitrary type, including the tag, to the stream.
@@ -1011,15 +1007,15 @@ namespace Google.ProtocolBuffers {
case FieldType.Fixed32: return ComputeFixed32Size(fieldNumber, (uint)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.Group: return ComputeGroupSize(fieldNumber, (IMessageLite)value);
+ case FieldType.Message: return ComputeMessageSize(fieldNumber, (IMessageLite)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, ((EnumValueDescriptor)value).Number);
+ case FieldType.Enum: return ComputeEnumSize(fieldNumber, ((IEnumLite)value).Number);
default:
throw new ArgumentOutOfRangeException("Invalid field type " + fieldType);
}
@@ -1040,20 +1036,19 @@ namespace Google.ProtocolBuffers {
case FieldType.Fixed32: return ComputeFixed32SizeNoTag((uint)value);
case FieldType.Bool: return ComputeBoolSizeNoTag((bool)value);
case FieldType.String: return ComputeStringSizeNoTag((string)value);
- case FieldType.Group: return ComputeGroupSizeNoTag((IMessage)value);
- case FieldType.Message: return ComputeMessageSizeNoTag((IMessage)value);
+ case FieldType.Group: return ComputeGroupSizeNoTag((IMessageLite)value);
+ case FieldType.Message: return ComputeMessageSizeNoTag((IMessageLite)value);
case FieldType.Bytes: return ComputeBytesSizeNoTag((ByteString)value);
case FieldType.UInt32: return ComputeUInt32SizeNoTag((uint)value);
case FieldType.SFixed32: return ComputeSFixed32SizeNoTag((int)value);
case FieldType.SFixed64: return ComputeSFixed64SizeNoTag((long)value);
case FieldType.SInt32: return ComputeSInt32SizeNoTag((int)value);
case FieldType.SInt64: return ComputeSInt64SizeNoTag((long)value);
- case FieldType.Enum: return ComputeEnumSizeNoTag(((EnumValueDescriptor)value).Number);
+ case FieldType.Enum: return ComputeEnumSizeNoTag(((IEnumLite)value).Number);
default:
throw new ArgumentOutOfRangeException("Invalid field type " + fieldType);
}
}
-#endif
/// <summary>
/// Compute the number of bytes that would be needed to encode a tag.
diff --git a/src/ProtocolBuffers/Descriptors/EnumDescriptor.cs b/src/ProtocolBuffers/Descriptors/EnumDescriptor.cs
index 2fa18d9a..c121c7e6 100644
--- a/src/ProtocolBuffers/Descriptors/EnumDescriptor.cs
+++ b/src/ProtocolBuffers/Descriptors/EnumDescriptor.cs
@@ -37,7 +37,7 @@ namespace Google.ProtocolBuffers.Descriptors {
/// <summary>
/// Descriptor for an enum type in a .proto file.
/// </summary>
- public sealed class EnumDescriptor : IndexedDescriptorBase<EnumDescriptorProto, EnumOptions> {
+ public sealed class EnumDescriptor : IndexedDescriptorBase<EnumDescriptorProto, EnumOptions>, IEnumLiteMap<EnumValueDescriptor> {
private readonly MessageDescriptor containingType;
private readonly IList<EnumValueDescriptor> values;
@@ -73,10 +73,17 @@ namespace Google.ProtocolBuffers.Descriptors {
}
/// <summary>
+ /// Logic moved from FieldSet to continue current behavior
+ /// </summary>
+ public bool IsValidValue(IEnumLite value) {
+ return value is EnumValueDescriptor && ((EnumValueDescriptor)value).EnumDescriptor == this;
+ }
+
+ /// <summary>
/// Finds an enum value by number. If multiple enum values have the
/// same number, this returns the first defined value with that number.
/// </summary>
- internal EnumValueDescriptor FindValueByNumber(int number) {
+ public EnumValueDescriptor FindValueByNumber(int number) {
return File.DescriptorPool.FindEnumValueByNumber(this, number);
}
diff --git a/src/ProtocolBuffers/Descriptors/EnumValueDescriptor.cs b/src/ProtocolBuffers/Descriptors/EnumValueDescriptor.cs
index 4125814d..732dec06 100644
--- a/src/ProtocolBuffers/Descriptors/EnumValueDescriptor.cs
+++ b/src/ProtocolBuffers/Descriptors/EnumValueDescriptor.cs
@@ -36,7 +36,7 @@ namespace Google.ProtocolBuffers.Descriptors {
/// <summary>
/// Descriptor for a single enum value within an enum in a .proto file.
/// </summary>
- public sealed class EnumValueDescriptor : IndexedDescriptorBase<EnumValueDescriptorProto, EnumValueOptions> {
+ public sealed class EnumValueDescriptor : IndexedDescriptorBase<EnumValueDescriptorProto, EnumValueOptions>, IEnumLite {
private readonly EnumDescriptor enumDescriptor;
diff --git a/src/ProtocolBuffers/Descriptors/FieldDescriptor.cs b/src/ProtocolBuffers/Descriptors/FieldDescriptor.cs
index 7d99ed21..854b3a89 100644
--- a/src/ProtocolBuffers/Descriptors/FieldDescriptor.cs
+++ b/src/ProtocolBuffers/Descriptors/FieldDescriptor.cs
@@ -40,7 +40,7 @@ namespace Google.ProtocolBuffers.Descriptors {
/// <summary>
/// Descriptor for a field or extension within a message in a .proto file.
/// </summary>
- public sealed class FieldDescriptor : IndexedDescriptorBase<FieldDescriptorProto, FieldOptions>, IComparable<FieldDescriptor> {
+ public sealed class FieldDescriptor : IndexedDescriptorBase<FieldDescriptorProto, FieldOptions>, IComparable<FieldDescriptor>, IFieldDescriptorLite {
private readonly MessageDescriptor extensionScope;
private EnumDescriptor enumType;
@@ -299,9 +299,26 @@ namespace Google.ProtocolBuffers.Descriptors {
}
return FieldNumber - other.FieldNumber;
}
-
/// <summary>
+ /// Compares this descriptor with another one, ordering in "canonical" order
+ /// which simply means ascending order by field number. <paramref name="other"/>
+ /// must be a field of the same type, i.e. the <see cref="ContainingType"/> of
+ /// both fields must be the same.
+ /// </summary>
+ public int CompareTo(IFieldDescriptorLite other) {
+ return FieldNumber - other.FieldNumber;
+ }
+
+ IEnumLiteMap IFieldDescriptorLite.EnumType {
+ get { return EnumType; }
+ }
+
+ bool IFieldDescriptorLite.MessageSetWireFormat {
+ get { return ContainingType.Options.MessageSetWireFormat; }
+ }
+
+ /// <summary>
/// For enum fields, returns the field's type.
/// </summary>
public EnumDescriptor EnumType {
diff --git a/src/ProtocolBuffers/DynamicMessage.cs b/src/ProtocolBuffers/DynamicMessage.cs
index 12f2186c..34a50c5b 100644
--- a/src/ProtocolBuffers/DynamicMessage.cs
+++ b/src/ProtocolBuffers/DynamicMessage.cs
@@ -180,7 +180,7 @@ namespace Google.ProtocolBuffers {
}
public override IDictionary<FieldDescriptor, object> AllFields {
- get { return fields.AllFields; }
+ get { return fields.AllFieldDescriptors; }
}
public override bool HasField(FieldDescriptor field) {
@@ -216,7 +216,7 @@ namespace Google.ProtocolBuffers {
}
public bool Initialized {
- get { return fields.IsInitializedWithRespectTo(type); }
+ get { return fields.IsInitializedWithRespectTo(type.Fields); }
}
public override void WriteTo(CodedOutputStream output) {
@@ -335,7 +335,7 @@ namespace Google.ProtocolBuffers {
}
public override bool IsInitialized {
- get { return fields.IsInitializedWithRespectTo(type); }
+ get { return fields.IsInitializedWithRespectTo(type.Fields); }
}
public override Builder MergeFrom(CodedInputStream input, ExtensionRegistry extensionRegistry) {
@@ -354,7 +354,7 @@ namespace Google.ProtocolBuffers {
}
public override IDictionary<FieldDescriptor, object> AllFields {
- get { return fields.AllFields; }
+ get { return fields.AllFieldDescriptors; }
}
public override IBuilder CreateBuilderForField(FieldDescriptor field) {
diff --git a/src/ProtocolBuffers/EnumLite.cs b/src/ProtocolBuffers/EnumLite.cs
new file mode 100644
index 00000000..0c6c9afb
--- /dev/null
+++ b/src/ProtocolBuffers/EnumLite.cs
@@ -0,0 +1,31 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace Google.ProtocolBuffers {
+
+ ///<summary>
+ ///Interface for an enum value or value descriptor, to be used in FieldSet.
+ ///The lite library stores enum values directly in FieldSets but the full
+ ///library stores EnumValueDescriptors in order to better support reflection.
+ ///</summary>
+ public interface IEnumLite {
+ int Number { get; }
+ }
+
+ ///<summary>
+ ///Interface for an object which maps integers to {@link EnumLite}s.
+ ///{@link Descriptors.EnumDescriptor} implements this interface by mapping
+ ///numbers to {@link Descriptors.EnumValueDescriptor}s. Additionally,
+ ///every generated enum type has a static method internalGetValueMap() which
+ ///returns an implementation of this type that maps numbers to enum values.
+ ///</summary>
+ public interface IEnumLiteMap<T> : IEnumLiteMap
+ where T : IEnumLite {
+ T FindValueByNumber(int number);
+ }
+
+ public interface IEnumLiteMap {
+ bool IsValidValue(IEnumLite value);
+ }
+}
diff --git a/src/ProtocolBuffers/ExtendableMessage.cs b/src/ProtocolBuffers/ExtendableMessage.cs
index 4450f4f9..c67b5a1d 100644
--- a/src/ProtocolBuffers/ExtendableMessage.cs
+++ b/src/ProtocolBuffers/ExtendableMessage.cs
@@ -102,8 +102,8 @@ namespace Google.ProtocolBuffers {
public override IDictionary<FieldDescriptor, object> AllFields {
get {
IDictionary<FieldDescriptor, object> result = GetMutableFieldMap();
- foreach(KeyValuePair<FieldDescriptor, object> entry in extensions.AllFields) {
- result[entry.Key] = entry.Value;
+ foreach(KeyValuePair<IFieldDescriptorLite, object> entry in extensions.AllFields) {
+ result[(FieldDescriptor)entry.Key] = entry.Value;
}
return Dictionaries.AsReadOnly(result);
}
@@ -173,9 +173,9 @@ namespace Google.ProtocolBuffers {
/// TODO(jonskeet): See if we can improve this in terms of readability.
/// </summary>
protected class ExtensionWriter {
- readonly IEnumerator<KeyValuePair<FieldDescriptor, object>> iterator;
+ readonly IEnumerator<KeyValuePair<IFieldDescriptorLite, object>> iterator;
readonly FieldSet extensions;
- KeyValuePair<FieldDescriptor, object>? next = null;
+ KeyValuePair<IFieldDescriptorLite, object>? next = null;
internal ExtensionWriter(ExtendableMessage<TMessage, TBuilder> message) {
extensions = message.extensions;
diff --git a/src/ProtocolBuffers/FieldSet.cs b/src/ProtocolBuffers/FieldSet.cs
index 7c373b95..3ac3e3d3 100644
--- a/src/ProtocolBuffers/FieldSet.cs
+++ b/src/ProtocolBuffers/FieldSet.cs
@@ -39,6 +39,20 @@ using Google.ProtocolBuffers.Collections;
using Google.ProtocolBuffers.Descriptors;
namespace Google.ProtocolBuffers {
+
+ public interface IFieldDescriptorLite : IComparable<IFieldDescriptorLite> {
+ bool IsRepeated { get; }
+ bool IsRequired { get; }
+ bool IsPacked { get; }
+ bool IsExtension { get; }
+ bool MessageSetWireFormat { get; } //field.ContainingType.Options.MessageSetWireFormat
+ int FieldNumber { get; }
+ IEnumLiteMap EnumType { get; }
+ FieldType FieldType { get; }
+ MappedType MappedType { get; }
+ object DefaultValue { get; }
+ }
+
/// <summary>
/// A class which represents an arbitrary set of fields of some message type.
/// This is used to implement DynamicMessage, and also to represent extensions
@@ -56,17 +70,17 @@ namespace Google.ProtocolBuffers {
/// </summary>
internal sealed class FieldSet {
- private static readonly FieldSet defaultInstance = new FieldSet(new Dictionary<FieldDescriptor, object>()).MakeImmutable();
+ private static readonly FieldSet defaultInstance = new FieldSet(new Dictionary<IFieldDescriptorLite, object>()).MakeImmutable();
- private IDictionary<FieldDescriptor, object> fields;
+ private IDictionary<IFieldDescriptorLite, object> fields;
- private FieldSet(IDictionary<FieldDescriptor, object> fields) {
+ private FieldSet(IDictionary<IFieldDescriptorLite, object> fields) {
this.fields = fields;
}
public static FieldSet CreateInstance() {
// Use SortedList to keep fields in the canonical order
- return new FieldSet(new SortedList<FieldDescriptor, object>());
+ return new FieldSet(new SortedList<IFieldDescriptorLite, object>());
}
/// <summary>
@@ -85,8 +99,8 @@ namespace Google.ProtocolBuffers {
}
if (hasRepeats) {
- var tmp = new SortedList<FieldDescriptor, object>();
- foreach (KeyValuePair<FieldDescriptor, object> entry in fields) {
+ var tmp = new SortedList<IFieldDescriptorLite, object>();
+ foreach (KeyValuePair<IFieldDescriptorLite, object> entry in fields) {
IList<object> list = entry.Value as IList<object>;
tmp[entry.Key] = list == null ? entry.Value : Lists.AsReadOnly(list);
}
@@ -110,14 +124,26 @@ namespace Google.ProtocolBuffers {
/// is immutable, the entries may not be (i.e. any repeated values are represented by
/// mutable lists). The behaviour is not specified if the contents are mutated.
/// </summary>
- internal IDictionary<FieldDescriptor, object> AllFields {
+ internal IDictionary<IFieldDescriptorLite, object> AllFields {
get { return Dictionaries.AsReadOnly(fields); }
}
-
+#if !LITE
+ /// <summary>
+ /// Force coercion to full descriptor dictionary.
+ /// </summary>
+ internal IDictionary<Descriptors.FieldDescriptor, object> AllFieldDescriptors {
+ get {
+ SortedList<Descriptors.FieldDescriptor, object> copy = new SortedList<Google.ProtocolBuffers.Descriptors.FieldDescriptor, object>();
+ foreach (KeyValuePair<IFieldDescriptorLite, object> fd in fields)
+ copy.Add((Descriptors.FieldDescriptor)fd.Key, fd.Value);
+ return Dictionaries.AsReadOnly(copy);
+ }
+ }
+#endif
/// <summary>
- /// See <see cref="IMessage.HasField"/>.
+ /// See <see cref="IMessageLite.HasField"/>.
/// </summary>
- public bool HasField(FieldDescriptor field) {
+ public bool HasField(IFieldDescriptorLite field) {
if (field.IsRepeated) {
throw new ArgumentException("HasField() can only be called on non-repeated fields.");
}
@@ -133,7 +159,7 @@ namespace Google.ProtocolBuffers {
}
/// <summary>
- /// See <see cref="IMessage.Item(FieldDescriptor)"/>
+ /// See <see cref="IMessageLite.Item(IFieldDescriptorLite)"/>
/// </summary>
/// <remarks>
/// If the field is not set, the behaviour when fetching this property varies by field type:
@@ -153,7 +179,7 @@ namespace Google.ProtocolBuffers {
/// to ensure it is of an appropriate type.
/// </remarks>
///
- internal object this[FieldDescriptor field] {
+ internal object this[IFieldDescriptorLite field] {
get {
object result;
if (fields.TryGetValue(field, out result)) {
@@ -191,9 +217,9 @@ namespace Google.ProtocolBuffers {
}
/// <summary>
- /// See <see cref="IMessage.Item(FieldDescriptor,int)" />
+ /// See <see cref="IMessageLite.Item(IFieldDescriptorLite,int)" />
/// </summary>
- internal object this[FieldDescriptor field, int index] {
+ internal object this[IFieldDescriptorLite field, int index] {
get {
if (!field.IsRepeated) {
throw new ArgumentException("Indexer specifying field and index can only be called on repeated fields.");
@@ -217,7 +243,7 @@ namespace Google.ProtocolBuffers {
/// <summary>
/// See <see cref="IBuilder{TMessage, TBuilder}.AddRepeatedField" />
/// </summary>
- internal void AddRepeatedField(FieldDescriptor field, object value) {
+ internal void AddRepeatedField(IFieldDescriptorLite field, object value) {
if (!field.IsRepeated) {
throw new ArgumentException("AddRepeatedField can only be called on repeated fields.");
}
@@ -233,12 +259,12 @@ namespace Google.ProtocolBuffers {
/// <summary>
/// Returns an enumerator for the field map. Used to write the fields out.
/// </summary>
- internal IEnumerator<KeyValuePair<FieldDescriptor, object>> GetEnumerator() {
+ internal IEnumerator<KeyValuePair<IFieldDescriptorLite, object>> GetEnumerator() {
return fields.GetEnumerator();
}
/// <summary>
- /// See <see cref="IMessage.IsInitialized" />
+ /// See <see cref="IMessageLite.IsInitialized" />
/// </summary>
/// <remarks>
/// Since FieldSet itself does not have any way of knowing about
@@ -248,17 +274,17 @@ namespace Google.ProtocolBuffers {
/// </remarks>
internal bool IsInitialized {
get {
- foreach (KeyValuePair<FieldDescriptor, object> entry in fields) {
- FieldDescriptor field = entry.Key;
+ foreach (KeyValuePair<IFieldDescriptorLite, object> entry in fields) {
+ IFieldDescriptorLite field = entry.Key;
if (field.MappedType == MappedType.Message) {
if (field.IsRepeated) {
- foreach(IMessage message in (IEnumerable) entry.Value) {
+ foreach(IMessageLite message in (IEnumerable) entry.Value) {
if (!message.IsInitialized) {
return false;
}
}
} else {
- if (!((IMessage) entry.Value).IsInitialized) {
+ if (!((IMessageLite)entry.Value).IsInitialized) {
return false;
}
}
@@ -273,8 +299,8 @@ namespace Google.ProtocolBuffers {
/// descriptor are present in this field set, as well as whether
/// all the embedded messages are themselves initialized.
/// </summary>
- internal bool IsInitializedWithRespectTo(MessageDescriptor type) {
- foreach (FieldDescriptor field in type.Fields) {
+ internal bool IsInitializedWithRespectTo(IEnumerable typeFields) {
+ foreach (IFieldDescriptorLite field in typeFields) {
if (field.IsRequired && !HasField(field)) {
return false;
}
@@ -285,14 +311,14 @@ namespace Google.ProtocolBuffers {
/// <summary>
/// See <see cref="IBuilder{TMessage, TBuilder}.ClearField" />
/// </summary>
- public void ClearField(FieldDescriptor field) {
+ public void ClearField(IFieldDescriptorLite field) {
fields.Remove(field);
}
/// <summary>
- /// See <see cref="IMessage.GetRepeatedFieldCount" />
+ /// See <see cref="IMessageLite.GetRepeatedFieldCount" />
/// </summary>
- public int GetRepeatedFieldCount(FieldDescriptor field) {
+ public int GetRepeatedFieldCount(IFieldDescriptorLite field) {
if (!field.IsRepeated) {
throw new ArgumentException("GetRepeatedFieldCount() can only be called on repeated fields.");
}
@@ -300,64 +326,63 @@ namespace Google.ProtocolBuffers {
return ((IList<object>) this[field]).Count;
}
+#if !LITE
+ /// <summary>
+ /// See <see cref="IBuilder{TMessage, TBuilder}.MergeFrom(IMessageLite)" />
+ /// </summary>
+ public void MergeFrom(IMessage other) {
+ foreach (KeyValuePair<Descriptors.FieldDescriptor, object> fd in other.AllFields)
+ MergeField(fd.Key, fd.Value);
+ }
+#endif
+
/// <summary>
/// Implementation of both <c>MergeFrom</c> methods.
/// </summary>
/// <param name="otherFields"></param>
- private void MergeFields(IEnumerable<KeyValuePair<FieldDescriptor, object>> otherFields) {
+ public void MergeFrom(FieldSet other) {
// Note: We don't attempt to verify that other's fields have valid
// types. Doing so would be a losing battle. We'd have to verify
// all sub-messages as well, and we'd have to make copies of all of
// them to insure that they don't change after verification (since
- // the IMessage interface itself cannot enforce immutability of
+ // the IMessageLite interface itself cannot enforce immutability of
// implementations).
// TODO(jonskeet): Provide a function somewhere called MakeDeepCopy()
// which allows people to make secure deep copies of messages.
- foreach (KeyValuePair<FieldDescriptor, object> entry in otherFields) {
- FieldDescriptor field = entry.Key;
- object existingValue;
- fields.TryGetValue(field, out existingValue);
- if (field.IsRepeated) {
- if (existingValue == null) {
- existingValue = new List<object>();
- fields[field] = existingValue;
- }
- IList<object> list = (IList<object>) existingValue;
- foreach (object otherValue in (IEnumerable) entry.Value) {
- list.Add(otherValue);
- }
- } else if (field.MappedType == MappedType.Message && existingValue != null) {
- IMessage existingMessage = (IMessage)existingValue;
- IMessage merged = existingMessage.WeakToBuilder()
- .WeakMergeFrom((IMessage) entry.Value)
- .WeakBuild();
- this[field] = merged;
- } else {
- this[field] = entry.Value;
- }
+ foreach (KeyValuePair<IFieldDescriptorLite, object> entry in other.fields) {
+ MergeField(entry.Key, entry.Value);
}
}
- /// <summary>
- /// See <see cref="IBuilder{TMessage, TBuilder}.MergeFrom(IMessage)" />
- /// </summary>
- public void MergeFrom(IMessage other) {
- MergeFields(other.AllFields);
- }
-
- /// <summary>
- /// Like <see cref="MergeFrom(IMessage)"/>, but merges from another <c>FieldSet</c>.
- /// </summary>
- public void MergeFrom(FieldSet other) {
- MergeFields(other.fields);
+ private void MergeField(IFieldDescriptorLite field, object mergeValue) {
+ object existingValue;
+ fields.TryGetValue(field, out existingValue);
+ if (field.IsRepeated) {
+ if (existingValue == null) {
+ existingValue = new List<object>();
+ fields[field] = existingValue;
+ }
+ IList<object> list = (IList<object>) existingValue;
+ foreach (object otherValue in (IEnumerable)mergeValue) {
+ list.Add(otherValue);
+ }
+ } else if (field.MappedType == MappedType.Message && existingValue != null) {
+ IMessageLite existingMessage = (IMessageLite)existingValue;
+ IMessageLite merged = existingMessage.WeakToBuilder()
+ .WeakMergeFrom((IMessageLite)mergeValue)
+ .WeakBuild();
+ this[field] = merged;
+ } else {
+ this[field] = mergeValue;
+ }
}
/// <summary>
- /// See <see cref="IMessage.WriteTo(CodedOutputStream)" />.
+ /// See <see cref="IMessageLite.WriteTo(CodedOutputStream)" />.
/// </summary>
public void WriteTo(CodedOutputStream output) {
- foreach (KeyValuePair<FieldDescriptor, object> entry in fields) {
+ foreach (KeyValuePair<IFieldDescriptorLite, object> entry in fields) {
WriteField(entry.Key, entry.Value, output);
}
}
@@ -365,9 +390,9 @@ namespace Google.ProtocolBuffers {
/// <summary>
/// Writes a single field to a CodedOutputStream.
/// </summary>
- public void WriteField(FieldDescriptor field, Object value, CodedOutputStream output) {
- if (field.IsExtension && field.ContainingType.Options.MessageSetWireFormat) {
- output.WriteMessageSetExtension(field.FieldNumber, (IMessage) value);
+ public void WriteField(IFieldDescriptorLite field, Object value, CodedOutputStream output) {
+ if (field.IsExtension && field.MessageSetWireFormat) {
+ output.WriteMessageSetExtension(field.FieldNumber, (IMessageLite) value);
} else {
if (field.IsRepeated) {
IEnumerable valueList = (IEnumerable) value;
@@ -395,18 +420,18 @@ namespace Google.ProtocolBuffers {
}
/// <summary>
- /// See <see cref="IMessage.SerializedSize" />. It's up to the caller to
+ /// See <see cref="IMessageLite.SerializedSize" />. It's up to the caller to
/// cache the resulting size if desired.
/// </summary>
public int SerializedSize {
get {
int size = 0;
- foreach (KeyValuePair<FieldDescriptor, object> entry in fields) {
- FieldDescriptor field = entry.Key;
+ foreach (KeyValuePair<IFieldDescriptorLite, object> entry in fields) {
+ IFieldDescriptorLite field = entry.Key;
object value = entry.Value;
- if (field.IsExtension && field.ContainingType.Options.MessageSetWireFormat) {
- size += CodedOutputStream.ComputeMessageSetExtensionSize(field.FieldNumber, (IMessage)value);
+ if (field.IsExtension && field.MessageSetWireFormat) {
+ size += CodedOutputStream.ComputeMessageSetExtensionSize(field.FieldNumber, (IMessageLite)value);
} else {
if (field.IsRepeated) {
IEnumerable valueList = (IEnumerable)value;
@@ -440,7 +465,7 @@ namespace Google.ProtocolBuffers {
/// </remarks>
/// <exception cref="ArgumentException">The value is not of the right type.</exception>
/// <exception cref="ArgumentNullException">The value is null.</exception>
- private static void VerifyType(FieldDescriptor field, object value) {
+ private static void VerifyType(IFieldDescriptorLite field, object value) {
ThrowHelper.ThrowIfNull(value, "value");
bool isValid = false;
switch (field.MappedType) {
@@ -454,12 +479,15 @@ namespace Google.ProtocolBuffers {
case MappedType.String: isValid = value is string; break;
case MappedType.ByteString: isValid = value is ByteString; break;
case MappedType.Enum:
- EnumValueDescriptor enumValue = value as EnumValueDescriptor;
- isValid = enumValue != null && enumValue.EnumDescriptor == field.EnumType;
+ IEnumLite enumValue = value as IEnumLite;
+ isValid = enumValue != null && field.EnumType.IsValidValue(enumValue);
break;
case MappedType.Message:
- IMessage messageValue = value as IMessage;
- isValid = messageValue != null && messageValue.DescriptorForType == field.MessageType;
+ IMessageLite messageValue = value as IMessageLite;
+ isValid = messageValue != null;
+#if !LITE
+ isValid = isValid && ((IMessage)messageValue).DescriptorForType == ((Google.ProtocolBuffers.Descriptors.FieldDescriptor)field).MessageType;
+#endif
break;
}
@@ -468,10 +496,16 @@ namespace Google.ProtocolBuffers {
// the stack trace which exact call failed, since the whole chain is
// considered one line of code. So, let's make sure to include the
// field name and other useful info in the exception.
- throw new ArgumentException("Wrong object type used with protocol message reflection. "
- + "Message type \"" + field.ContainingType.FullName
- + "\", field \"" + (field.IsExtension ? field.FullName : field.Name)
- + "\", value was type \"" + value.GetType().Name + "\".");
+ string message = "Wrong object type used with protocol message reflection.";
+#if !LITE
+ Google.ProtocolBuffers.Descriptors.FieldDescriptor fieldinfo = field as Google.ProtocolBuffers.Descriptors.FieldDescriptor;
+ if (fieldinfo != null) {
+ message += "Message type \"" + fieldinfo.ContainingType.FullName;
+ message += "\", field \"" + (fieldinfo.IsExtension ? fieldinfo.FullName : fieldinfo.Name);
+ message += "\", value was type \"" + value.GetType().Name + "\".";
+ }
+#endif
+ throw new ArgumentException(message);
}
}
}
diff --git a/src/ProtocolBuffers/GeneratedExtensionLite.cs b/src/ProtocolBuffers/GeneratedExtensionLite.cs
index 9b3cf504..da07fb8c 100644
--- a/src/ProtocolBuffers/GeneratedExtensionLite.cs
+++ b/src/ProtocolBuffers/GeneratedExtensionLite.cs
@@ -1,4 +1,5 @@
using System;
+using Google.ProtocolBuffers.Descriptors;
namespace Google.ProtocolBuffers {
@@ -7,4 +8,111 @@ namespace Google.ProtocolBuffers {
object ContainingType { get; }
IMessageLite MessageDefaultInstance { get; }
}
+
+ public class ExtensionDescriptorLite {
+ private readonly EnumLiteMap enumTypeMap;
+ private readonly int number;
+ private readonly FieldType type;
+ private readonly bool isRepeated;
+ private readonly bool isPacked;
+
+ public ExtensionDescriptorLite(EnumLiteMap enumTypeMap, int number, FieldType type, bool isRepeated, bool isPacked) {
+ this.enumTypeMap = enumTypeMap;
+ this.number = number;
+ this.type = type;
+ this.isRepeated = isRepeated;
+ this.isPacked = isPacked;
+ }
+
+ public int Number {
+ get { return number; }
+ }
+ }
+
+ public class EnumLiteMap { }
+
+ public class GeneratedExtensionLite<TContainingType, TExtensionType> : IGeneratedExtensionLite
+ where TContainingType : IMessageLite {
+
+ private readonly TContainingType containingTypeDefaultInstance;
+ private readonly TExtensionType defaultValue;
+ private readonly IMessageLite messageDefaultInstance;
+ private readonly ExtensionDescriptorLite descriptor;
+
+ // We can't always initialize a GeneratedExtension when we first construct
+ // it due to initialization order difficulties (namely, the default
+ // instances may not have been constructed yet). So, we construct an
+ // uninitialized GeneratedExtension once, then call internalInit() on it
+ // later. Generated code will always call internalInit() on all extensions
+ // as part of the static initialization code, and internalInit() throws an
+ // exception if called more than once, so this method is useless to users.
+ protected GeneratedExtensionLite(
+ TContainingType containingTypeDefaultInstance,
+ TExtensionType defaultValue,
+ IMessageLite messageDefaultInstance,
+ ExtensionDescriptorLite descriptor) {
+ this.containingTypeDefaultInstance = containingTypeDefaultInstance;
+ this.messageDefaultInstance = messageDefaultInstance;
+ this.defaultValue = defaultValue;
+ this.descriptor = descriptor;
+ }
+
+ /** For use by generated code only. */
+ public GeneratedExtensionLite(
+ TContainingType containingTypeDefaultInstance,
+ TExtensionType defaultValue,
+ IMessageLite messageDefaultInstance,
+ EnumLiteMap enumTypeMap,
+ int number,
+ FieldType type)
+ : this(containingTypeDefaultInstance, defaultValue, messageDefaultInstance,
+ new ExtensionDescriptorLite(enumTypeMap, number, type,
+ false /* isRepeated */, false /* isPacked */)) {
+ }
+
+ /** For use by generated code only. */
+ public GeneratedExtensionLite(
+ TContainingType containingTypeDefaultInstance,
+ TExtensionType defaultValue,
+ IMessageLite messageDefaultInstance,
+ EnumLiteMap enumTypeMap,
+ int number,
+ FieldType type,
+ bool isPacked)
+ : this(containingTypeDefaultInstance, defaultValue, messageDefaultInstance,
+ new ExtensionDescriptorLite(enumTypeMap, number, type,
+ true /* isRepeated */, isPacked)) {
+ }
+
+ /// <summary>
+ /// used for the extension registry
+ /// </summary>
+ object IGeneratedExtensionLite.ContainingType {
+ get { return ContainingTypeDefaultInstance; }
+ }
+ /**
+ * Default instance of the type being extended, used to identify that type.
+ */
+ public TContainingType ContainingTypeDefaultInstance {
+ get {
+ return containingTypeDefaultInstance;
+ }
+ }
+
+ /** Get the field number. */
+ public int Number {
+ get {
+ return descriptor.Number;
+ }
+ }
+ /**
+ * If the extension is an embedded message, this is the default instance of
+ * that type.
+ */
+ public IMessageLite MessageDefaultInstance {
+ get {
+ return messageDefaultInstance;
+ }
+ }
+ }
} \ No newline at end of file
diff --git a/src/ProtocolBuffers/ProtocolBuffers.csproj b/src/ProtocolBuffers/ProtocolBuffers.csproj
index 59dfaa08..dece65af 100644
--- a/src/ProtocolBuffers/ProtocolBuffers.csproj
+++ b/src/ProtocolBuffers/ProtocolBuffers.csproj
@@ -90,6 +90,7 @@
<Compile Include="Descriptors\PackageDescriptor.cs" />
<Compile Include="Descriptors\ServiceDescriptor.cs" />
<Compile Include="DynamicMessage.cs" />
+ <Compile Include="EnumLite.cs" />
<Compile Include="ExtendableBuilder.cs" />
<Compile Include="ExtendableMessage.cs" />
<Compile Include="ExtensionInfo.cs">
diff --git a/src/ProtocolBuffers/ProtocolBuffersLite.csproj b/src/ProtocolBuffers/ProtocolBuffersLite.csproj
index a08b024b..d3d60b24 100644
--- a/src/ProtocolBuffers/ProtocolBuffersLite.csproj
+++ b/src/ProtocolBuffers/ProtocolBuffersLite.csproj
@@ -46,6 +46,8 @@
<ItemGroup>
<Reference Include="mscorlib" />
<Reference Include="System" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
</ItemGroup>
@@ -55,7 +57,17 @@
<ItemGroup>
<Compile Include="AbstractBuilderLite.cs" />
<Compile Include="AbstractMessageLite.cs" />
+ <Compile Include="Collections\Dictionaries.cs" />
+ <Compile Include="Collections\Lists.cs" />
+ <Compile Include="Descriptors\FieldMappingAttribute.cs" />
+ <Compile Include="Descriptors\FieldType.cs" />
+ <Compile Include="Descriptors\MappedType.cs" />
+ <Compile Include="EnumLite.cs" />
+ <Compile Include="ExtendableMessageLite.cs" />
+ <Compile Include="FieldSet.cs" />
+ <Compile Include="GeneratedBuilderLite.cs" />
<Compile Include="GeneratedExtensionLite.cs" />
+ <Compile Include="GeneratedMessageLite.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="ByteString.cs" />
<Compile Include="CodedInputStream.cs" />
@@ -66,6 +78,7 @@
<SubType>Code</SubType>
</Compile>
<Compile Include="InvalidProtocolBufferException.cs" />
+ <Compile Include="ThrowHelper.cs" />
<Compile Include="UninitializedMessageException.cs" />
<Compile Include="WireFormat.cs" />
</ItemGroup>