aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJon Skeet <jonskeet@google.com>2015-08-07 13:37:21 +0100
committerJon Skeet <jonskeet@google.com>2015-08-08 07:27:58 +0100
commit547d8e8221b8ea7ff7010cbc601f4e5742ff1e51 (patch)
treee0daca67c1ac8c80bd92253f29a6031d7f246a37
parente58cdbd2146bc8e2e2f5bf4bc8a7576f82535ae6 (diff)
downloadprotobuf-547d8e8221b8ea7ff7010cbc601f4e5742ff1e51.tar.gz
protobuf-547d8e8221b8ea7ff7010cbc601f4e5742ff1e51.tar.bz2
protobuf-547d8e8221b8ea7ff7010cbc601f4e5742ff1e51.zip
Make FieldDescriptor.IsPacked work appropriately.
This is a bit of a grotty hack, as we need to sort of fake proto2 field presence, but with only a proto3 version of the descriptor messages (a bit like oneof detection). Should be okay, but will need to be careful of this if we ever implement proto2.
-rw-r--r--csharp/src/Google.Protobuf.Test/Reflection/FieldAccessTest.cs2
-rw-r--r--csharp/src/Google.Protobuf/Reflection/FieldDescriptor.cs8
-rw-r--r--csharp/src/Google.Protobuf/Reflection/PartialClasses.cs12
3 files changed, 18 insertions, 4 deletions
diff --git a/csharp/src/Google.Protobuf.Test/Reflection/FieldAccessTest.cs b/csharp/src/Google.Protobuf.Test/Reflection/FieldAccessTest.cs
index 6e1d804e..936e41c6 100644
--- a/csharp/src/Google.Protobuf.Test/Reflection/FieldAccessTest.cs
+++ b/csharp/src/Google.Protobuf.Test/Reflection/FieldAccessTest.cs
@@ -213,6 +213,6 @@ namespace Google.Protobuf.Reflection
var descriptor = TestAllTypes.Descriptor;
Assert.Throws<KeyNotFoundException>(() => descriptor.Fields[999999].ToString());
Assert.Throws<KeyNotFoundException>(() => descriptor.Fields["not found"].ToString());
- }
+ }
}
}
diff --git a/csharp/src/Google.Protobuf/Reflection/FieldDescriptor.cs b/csharp/src/Google.Protobuf/Reflection/FieldDescriptor.cs
index bb8e9bbb..901cbf47 100644
--- a/csharp/src/Google.Protobuf/Reflection/FieldDescriptor.cs
+++ b/csharp/src/Google.Protobuf/Reflection/FieldDescriptor.cs
@@ -168,14 +168,16 @@ namespace Google.Protobuf.Reflection
get { return fieldType == FieldType.Message && messageType.Proto.Options != null && messageType.Proto.Options.MapEntry; }
}
- // TODO(jonskeet): Check whether this is correct with proto3, where we default to packed...
-
/// <summary>
/// Returns <c>true</c> if this field is a packed, repeated field; <c>false</c> otherwise.
/// </summary>
public bool IsPacked
{
- get { return Proto.Options != null && Proto.Options.Packed; }
+ // Note the || rather than && here - we're effectively defaulting to packed, because that *is*
+ // the default in proto3, which is all we support. We may give the wrong result for the protos
+ // within descriptor.proto, but that's okay, as they're never exposed and we don't use IsPacked
+ // within the runtime.
+ get { return Proto.Options == null || Proto.Options.Packed; }
}
/// <summary>
diff --git a/csharp/src/Google.Protobuf/Reflection/PartialClasses.cs b/csharp/src/Google.Protobuf/Reflection/PartialClasses.cs
index c7ed4342..8c055d6d 100644
--- a/csharp/src/Google.Protobuf/Reflection/PartialClasses.cs
+++ b/csharp/src/Google.Protobuf/Reflection/PartialClasses.cs
@@ -44,4 +44,16 @@ namespace Google.Protobuf.Reflection
OneofIndex = -1;
}
}
+
+ internal partial class FieldOptions
+ {
+ // We can't tell the difference between "explicitly set to false" and "not set"
+ // in proto3, but we need to tell the difference for FieldDescriptor.IsPacked.
+ // This won't work if we ever need to support proto2, but at that point we'll be
+ // able to remove this hack and use field presence instead.
+ partial void OnConstruction()
+ {
+ Packed = true;
+ }
+ }
} \ No newline at end of file