aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJan Tattermusch <jtattermusch@google.com>2015-04-13 16:12:29 -0700
committerJan Tattermusch <jtattermusch@google.com>2015-04-13 16:12:29 -0700
commit5ac8de5b46a7b2adb81f957dfb78c612137d9ffb (patch)
treeead863ed6166845aa263f291924dd7b579fdc43d /src
parentdb9060dc61ce72f3747197644f31a57b9ddbf6a4 (diff)
downloadprotobuf-5ac8de5b46a7b2adb81f957dfb78c612137d9ffb.tar.gz
protobuf-5ac8de5b46a7b2adb81f957dfb78c612137d9ffb.tar.bz2
protobuf-5ac8de5b46a7b2adb81f957dfb78c612137d9ffb.zip
implemented HasRequiredFields logic
Diffstat (limited to 'src')
-rw-r--r--src/google/protobuf/compiler/csharp/csharp_helpers.cc39
1 files changed, 37 insertions, 2 deletions
diff --git a/src/google/protobuf/compiler/csharp/csharp_helpers.cc b/src/google/protobuf/compiler/csharp/csharp_helpers.cc
index 5829c61e..fd6e3722 100644
--- a/src/google/protobuf/compiler/csharp/csharp_helpers.cc
+++ b/src/google/protobuf/compiler/csharp/csharp_helpers.cc
@@ -363,9 +363,44 @@ FieldGeneratorBase* CreateFieldGenerator(const FieldDescriptor* descriptor,
}
}
+bool HasRequiredFields(const Descriptor* descriptor, std::set<const Descriptor*>* already_seen) {
+ if (already_seen->find(descriptor) != already_seen->end()) {
+ // The type is already in 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;
+ }
+ already_seen->insert(descriptor);
+
+ // If the type has extensions, an extension with message type could contain
+ // required fields, so we have to be conservative and assume such an
+ // extension exists.
+ if (descriptor->extension_count() > 0) {
+ return true;
+ }
+
+ for (int i = 0; i < descriptor->field_count(); i++) {
+ const FieldDescriptor* field = descriptor->field(i);
+ if (field->is_required()) {
+ return true;
+ }
+ if (GetCSharpType(field->type()) == CSHARPTYPE_MESSAGE) {
+ if (HasRequiredFields(field->message_type(), already_seen)) {
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
bool HasRequiredFields(const Descriptor* descriptor) {
- // TODO(jtattermusch): implement HasRequiredFields logic.
- return true;
+ std::set<const Descriptor*> already_seen;
+ return HasRequiredFields(descriptor, &already_seen);
}
} // namespace java