diff options
author | Mark Benvenuto <mark.benvenuto@mongodb.com> | 2017-11-20 13:57:09 -0500 |
---|---|---|
committer | Mark Benvenuto <mark.benvenuto@mongodb.com> | 2017-11-20 13:57:09 -0500 |
commit | 015781fb73e66e99abcb2ceb998d22a79d915227 (patch) | |
tree | 01ab53ed7a365790ec70817aeb099bb65bc1dd7d /src | |
parent | 88b413760e2fa91b03267412c8d36a207975fd9e (diff) | |
download | mongo-015781fb73e66e99abcb2ceb998d22a79d915227.tar.gz |
SERVER-32005 IDL augment code with compiler likely macro
Diffstat (limited to 'src')
-rw-r--r-- | src/mongo/idl/idl_parser.cpp | 31 | ||||
-rw-r--r-- | src/mongo/idl/idl_parser.h | 26 | ||||
-rw-r--r-- | src/mongo/idl/idl_test.cpp | 40 |
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 |