summaryrefslogtreecommitdiff
path: root/src/mongo/idl
diff options
context:
space:
mode:
authorGeorge Wangensteen <george.wangensteen@mongodb.com>2020-11-12 18:17:00 +0000
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2020-11-18 18:16:32 +0000
commit8124811b60875f50cc7acf9427a6f8ea1a269c3c (patch)
tree42ef8660af3c63eb50e94525d9ac0efba4f982af /src/mongo/idl
parentd5459ded563322d2f7bc45ce4b31bca0d064133e (diff)
downloadmongo-8124811b60875f50cc7acf9427a6f8ea1a269c3c.tar.gz
SERVER-52827 Define an IDL type that accepts any BSON value in basic_types.idl
Diffstat (limited to 'src/mongo/idl')
-rw-r--r--src/mongo/idl/basic_types.h30
-rw-r--r--src/mongo/idl/basic_types.idl7
-rw-r--r--src/mongo/idl/idl_test.cpp33
-rw-r--r--src/mongo/idl/unittest.idl7
4 files changed, 76 insertions, 1 deletions
diff --git a/src/mongo/idl/basic_types.h b/src/mongo/idl/basic_types.h
index 8eb66c53629..01e38a5cb99 100644
--- a/src/mongo/idl/basic_types.h
+++ b/src/mongo/idl/basic_types.h
@@ -104,4 +104,32 @@ private:
boost::optional<bool> _value;
};
-} // namespace mongo
+/**
+ * Class to represent a BSON element with any type from IDL. The caller must ensure that the backing
+ * BSON stays alive while this type is in use.
+ */
+class IDLAnyType {
+public:
+ static IDLAnyType parseFromBSON(const BSONElement& element) {
+ return IDLAnyType(element);
+ }
+
+ IDLAnyType() = default;
+ IDLAnyType(const BSONElement& element) : _element(element) {}
+
+ void serializeToBSON(StringData fieldName, BSONObjBuilder* builder) const {
+ builder->appendAs(_element, fieldName);
+ }
+
+ void serializeToBSON(BSONArrayBuilder* builder) const {
+ builder->append(_element);
+ }
+
+ const BSONElement& getElement() const {
+ return _element;
+ }
+
+private:
+ BSONElement _element;
+};
+} // namespace mongo \ No newline at end of file
diff --git a/src/mongo/idl/basic_types.idl b/src/mongo/idl/basic_types.idl
index 063598e8d5d..27f7a366b51 100644
--- a/src/mongo/idl/basic_types.idl
+++ b/src/mongo/idl/basic_types.idl
@@ -195,6 +195,13 @@ types:
serializer: "::mongo::FeatureCompatibilityVersionParser::serializeVersion"
deserializer: "mongo::FeatureCompatibilityVersionParser::parseVersion"
+ IDLAnyType:
+ bson_serialization_type: any
+ description: "Holds a BSONElement of any type."
+ cpp_type: "mongo::IDLAnyType"
+ serializer: mongo::IDLAnyType::serializeToBSON
+ deserializer: mongo::IDLAnyType::parseFromBSON
+
structs:
OkReply:
diff --git a/src/mongo/idl/idl_test.cpp b/src/mongo/idl/idl_test.cpp
index 206aa0b5aaf..b411ee280ec 100644
--- a/src/mongo/idl/idl_test.cpp
+++ b/src/mongo/idl/idl_test.cpp
@@ -3008,5 +3008,38 @@ TEST(IDLTypeCommand, TestErrorReplyStruct) {
}
}
+TEST(IDLTypeCommand, TestCommandWithIDLAnyTypeField) {
+ IDLParserErrorContext ctxt("root");
+ std::vector<BSONObj> differentTypeObjs = {
+ BSON(CommandWithAnyTypeMember::kCommandName << 1 << "anyTypeField"
+ << "string literal"
+ << "$db"
+ << "db"),
+ BSON(CommandWithAnyTypeMember::kCommandName << 1 << "anyTypeField" << 1234 << "$db"
+ << "db"),
+ BSON(CommandWithAnyTypeMember::kCommandName << 1 << "anyTypeField" << 1234.5 << "$db"
+ << "db"),
+ BSON(CommandWithAnyTypeMember::kCommandName << 1 << "anyTypeField" << OID::max() << "$db"
+ << "db"),
+ BSON(CommandWithAnyTypeMember::kCommandName << 1 << "anyTypeField" << Date_t::now() << "$db"
+ << "db"),
+ BSON(CommandWithAnyTypeMember::kCommandName << 1 << "anyTypeField"
+ << BSON("a"
+ << "b")
+ << "$db"
+ << "db"),
+ BSON(CommandWithAnyTypeMember::kCommandName << 1 << "anyTypeField"
+ << BSON_ARRAY("a"
+ << "b")
+ << "$db"
+ << "db"),
+ BSON(CommandWithAnyTypeMember::kCommandName << 1 << "anyTypeField" << jstNULL << "$db"
+ << "db")};
+ for (auto&& obj : differentTypeObjs) {
+ auto parsed = CommandWithAnyTypeMember::parse(ctxt, obj);
+ ASSERT_BSONELT_EQ(parsed.getAnyTypeField().getElement(), obj["anyTypeField"]);
+ }
+}
+
} // namespace
} // namespace mongo
diff --git a/src/mongo/idl/unittest.idl b/src/mongo/idl/unittest.idl
index e32fc0ce986..0fb236d41f1 100644
--- a/src/mongo/idl/unittest.idl
+++ b/src/mongo/idl/unittest.idl
@@ -811,6 +811,13 @@ commands:
namespace: ignored
reply_type: OkReply
+ CommandWithAnyTypeMember:
+ description: "A mock command to test IDLAnyType"
+ command_name: CommandWithValueTypeMember
+ namespace: ignored
+ reply_type: OkReply
+ fields:
+ anyTypeField: IDLAnyType
##################################################################################################
#