aboutsummaryrefslogtreecommitdiffhomepage
path: root/csharp
diff options
context:
space:
mode:
authorGravatar Jon Skeet <skeet@pobox.com>2008-08-14 20:38:09 +0100
committerGravatar Jon Skeet <skeet@pobox.com>2008-08-14 20:38:09 +0100
commit8f721f5dc76dd96fb8a3db38bf0be759cb4743c1 (patch)
treeed1529bfbe3077ba0de05e106059a1426ac4b8d1 /csharp
parentb01135c485bf6ae179924b2024450d4692e9dc38 (diff)
Experimental (and currently unused) behaviour to determine whether or not a message has any required fields.
Diffstat (limited to 'csharp')
-rw-r--r--csharp/ProtocolBuffers/Descriptors/FileDescriptor.cs4
-rw-r--r--csharp/ProtocolBuffers/Descriptors/MessageDescriptor.cs51
-rw-r--r--csharp/ProtocolBuffers/GeneratedMessage.cs3
3 files changed, 58 insertions, 0 deletions
diff --git a/csharp/ProtocolBuffers/Descriptors/FileDescriptor.cs b/csharp/ProtocolBuffers/Descriptors/FileDescriptor.cs
index b3beea0b..429282b7 100644
--- a/csharp/ProtocolBuffers/Descriptors/FileDescriptor.cs
+++ b/csharp/ProtocolBuffers/Descriptors/FileDescriptor.cs
@@ -221,6 +221,10 @@ namespace Google.ProtocolBuffers.Descriptors {
foreach (FieldDescriptor extension in extensions) {
extension.CrossLink();
}
+
+ foreach (MessageDescriptor message in messageTypes) {
+ message.CheckRequiredFields();
+ }
}
/// <summary>
diff --git a/csharp/ProtocolBuffers/Descriptors/MessageDescriptor.cs b/csharp/ProtocolBuffers/Descriptors/MessageDescriptor.cs
index e3df02fe..f387a325 100644
--- a/csharp/ProtocolBuffers/Descriptors/MessageDescriptor.cs
+++ b/csharp/ProtocolBuffers/Descriptors/MessageDescriptor.cs
@@ -28,6 +28,7 @@ namespace Google.ProtocolBuffers.Descriptors {
private readonly IList<EnumDescriptor> enumTypes;
private readonly IList<FieldDescriptor> fields;
private readonly IList<FieldDescriptor> extensions;
+ private bool hasRequiredFields;
internal MessageDescriptor(DescriptorProto proto, FileDescriptor file, MessageDescriptor parent, int typeIndex)
: base(proto, file, ComputeFullName(file, parent, proto.Name), typeIndex) {
@@ -84,6 +85,16 @@ namespace Google.ProtocolBuffers.Descriptors {
}
/// <summary>
+ /// Returns a pre-computed result as to whether this message
+ /// has required fields. This includes optional fields which are
+ /// message types which in turn have required fields, and any
+ /// extension fields.
+ /// </summary>
+ internal bool HasRequiredFields {
+ get { return hasRequiredFields; }
+ }
+
+ /// <summary>
/// Determines if the given field number is an extension.
/// </summary>
public bool IsExtensionNumber(int number) {
@@ -131,5 +142,45 @@ namespace Google.ProtocolBuffers.Descriptors {
extension.CrossLink();
}
}
+
+ internal void CheckRequiredFields() {
+ IDictionary<MessageDescriptor, byte> alreadySeen = new Dictionary<MessageDescriptor, byte>();
+ hasRequiredFields = CheckRequiredFields(alreadySeen);
+ }
+
+ private bool CheckRequiredFields(IDictionary<MessageDescriptor,byte> alreadySeen) {
+
+ if (alreadySeen.ContainsKey(this)) {
+ // The type is already in the cache. This means that either:
+ // a. The type has no required fields.
+ // b. We are in the midst of checking if the type has required fields,
+ // somewhere up the stack. In this case, we know that if the type
+ // has any required fields, they'll be found when we return to it,
+ // and the whole call to HasRequiredFields() will return true.
+ // Therefore, we don't have to check if this type has required fields
+ // here.
+ return false;
+ }
+ alreadySeen[this] = 0; // Value is irrelevant; we want set semantics
+
+ // If the type allows extensions, an extension with message type could contain
+ // required fields, so we have to be conservative and assume such an
+ // extension exists.
+ if (Proto.ExtensionRangeCount != 0) {
+ return true;
+ }
+
+ foreach (FieldDescriptor field in Fields) {
+ if (field.IsRequired) {
+ return true;
+ }
+ if (field.MappedType == MappedType.Message) {
+ if (field.MessageType.CheckRequiredFields(alreadySeen)) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
}
}
diff --git a/csharp/ProtocolBuffers/GeneratedMessage.cs b/csharp/ProtocolBuffers/GeneratedMessage.cs
index 6198afbf..47722d0b 100644
--- a/csharp/ProtocolBuffers/GeneratedMessage.cs
+++ b/csharp/ProtocolBuffers/GeneratedMessage.cs
@@ -68,6 +68,9 @@ namespace Google.ProtocolBuffers {
public override bool IsInitialized {
get {
+ /* if (!DescriptorForType.HasRequiredFields) {
+ return true;
+ }*/
// Check that all required fields are present.
foreach (FieldDescriptor field in DescriptorForType.Fields) {
if (field.IsRequired && !HasField(field)) {