summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMark Benvenuto <mark.benvenuto@mongodb.com>2017-11-20 13:57:09 -0500
committerMark Benvenuto <mark.benvenuto@mongodb.com>2017-11-20 13:57:09 -0500
commit015781fb73e66e99abcb2ceb998d22a79d915227 (patch)
tree01ab53ed7a365790ec70817aeb099bb65bc1dd7d /src
parent88b413760e2fa91b03267412c8d36a207975fd9e (diff)
downloadmongo-015781fb73e66e99abcb2ceb998d22a79d915227.tar.gz
SERVER-32005 IDL augment code with compiler likely macro
Diffstat (limited to 'src')
-rw-r--r--src/mongo/idl/idl_parser.cpp31
-rw-r--r--src/mongo/idl/idl_parser.h26
-rw-r--r--src/mongo/idl/idl_test.cpp40
3 files changed, 78 insertions, 19 deletions
diff --git a/src/mongo/idl/idl_parser.cpp b/src/mongo/idl/idl_parser.cpp
index 1de7730b780..888ea2894bd 100644
--- a/src/mongo/idl/idl_parser.cpp
+++ b/src/mongo/idl/idl_parser.cpp
@@ -63,29 +63,26 @@ std::string toCommaDelimitedList(const std::vector<BSONType>& types) {
constexpr StringData IDLParserErrorContext::kOpMsgDollarDBDefault;
constexpr StringData IDLParserErrorContext::kOpMsgDollarDB;
-bool IDLParserErrorContext::checkAndAssertType(const BSONElement& element, BSONType type) const {
+bool IDLParserErrorContext::checkAndAssertTypeSlowPath(const BSONElement& element,
+ BSONType type) const {
auto elementType = element.type();
- if (elementType != type) {
- // If the type is wrong, ignore Null and Undefined values
- if (elementType == jstNULL || elementType == Undefined) {
- return false;
- }
-
- std::string path = getElementPath(element);
- uasserted(ErrorCodes::TypeMismatch,
- str::stream() << "BSON field '" << path << "' is the wrong type '"
- << typeName(element.type())
- << "', expected type '"
- << typeName(type)
- << "'");
+ // If the type is wrong, ignore Null and Undefined values
+ if (elementType == jstNULL || elementType == Undefined) {
+ return false;
}
- return true;
+ std::string path = getElementPath(element);
+ uasserted(ErrorCodes::TypeMismatch,
+ str::stream() << "BSON field '" << path << "' is the wrong type '"
+ << typeName(elementType)
+ << "', expected type '"
+ << typeName(type)
+ << "'");
}
-bool IDLParserErrorContext::checkAndAssertBinDataType(const BSONElement& element,
- BinDataType type) const {
+bool IDLParserErrorContext::checkAndAssertBinDataTypeSlowPath(const BSONElement& element,
+ BinDataType type) const {
bool isBinDataType = checkAndAssertType(element, BinData);
if (!isBinDataType) {
return false;
diff --git a/src/mongo/idl/idl_parser.h b/src/mongo/idl/idl_parser.h
index f5f6ba0f90e..fe3d614a255 100644
--- a/src/mongo/idl/idl_parser.h
+++ b/src/mongo/idl/idl_parser.h
@@ -72,7 +72,13 @@ public:
* processed.
* Throws an exception if the BSON element's type is wrong.
*/
- bool checkAndAssertType(const BSONElement& element, BSONType type) const;
+ bool checkAndAssertType(const BSONElement& element, BSONType type) const {
+ if (MONGO_likely(element.type() == type)) {
+ return true;
+ }
+
+ return checkAndAssertTypeSlowPath(element, type);
+ }
/**
* Check that BSON element is a bin data type, and has the specified bin data subtype, or
@@ -83,7 +89,13 @@ public:
* processed.
* Throws an exception if the BSON element's type is wrong.
*/
- bool checkAndAssertBinDataType(const BSONElement& element, BinDataType type) const;
+ bool checkAndAssertBinDataType(const BSONElement& element, BinDataType type) const {
+ if (MONGO_likely(element.type() == BinData && element.binDataType() == type)) {
+ return true;
+ }
+
+ return checkAndAssertBinDataTypeSlowPath(element, type);
+ }
/**
* Check that BSON element is one of a given type or whether the field should be skipped.
@@ -157,6 +169,16 @@ private:
*/
std::string getElementPath(StringData fieldName) const;
+ /**
+ * See comment on checkAndAssertType.
+ */
+ bool checkAndAssertTypeSlowPath(const BSONElement& element, BSONType type) const;
+
+ /**
+ * See comment on checkAndAssertBinDataType.
+ */
+ bool checkAndAssertBinDataTypeSlowPath(const BSONElement& element, BinDataType type) const;
+
private:
// Name of the current field that is being parsed.
const StringData _currentField;
diff --git a/src/mongo/idl/idl_test.cpp b/src/mongo/idl/idl_test.cpp
index 9723f802d46..1d3ac995b47 100644
--- a/src/mongo/idl/idl_test.cpp
+++ b/src/mongo/idl/idl_test.cpp
@@ -2172,5 +2172,45 @@ TEST(IDLCommand, TestKnownFieldDuplicate) {
}
+// Positive: Test an inline nested chain struct works
+TEST(IDLChainedStruct, TestInline) {
+ IDLParserErrorContext ctxt("root");
+
+ auto testDoc = BSON("stringField"
+ << "bar"
+ << "field3"
+ << "foo");
+
+ auto testStruct = Chained_struct_inline::parse(ctxt, testDoc);
+ ASSERT_EQUALS(testStruct.getChained_string_inline_basic_type().getStringField(), "bar");
+ ASSERT_EQUALS(testStruct.getField3(), "foo");
+
+ assert_same_types<decltype(testStruct.getChained_string_inline_basic_type().getStringField()),
+ const StringData>();
+ assert_same_types<decltype(testStruct.getField3()), const StringData>();
+
+ // Positive: Test we can round trip to a document from the just parsed document
+ {
+ BSONObj loopbackDoc = testStruct.toBSON();
+
+ ASSERT_BSONOBJ_EQ(testDoc, loopbackDoc);
+ }
+
+ // Positive: Test we can serialize from nothing the same document
+ {
+ BSONObjBuilder builder;
+ Chained_struct_inline one_new;
+ one_new.setField3("foo");
+
+ Chained_string_inline_basic_type f1;
+ f1.setStringField("bar");
+ one_new.setChained_string_inline_basic_type(f1);
+
+ BSONObj loopbackDoc = one_new.toBSON();
+
+ ASSERT_BSONOBJ_EQ(testDoc, loopbackDoc);
+ }
+}
+
} // namespace
} // namespace mongo