diff options
-rw-r--r-- | buildscripts/idl/idl/generator.py | 35 | ||||
-rw-r--r-- | buildscripts/idl/idl/syntax.py | 2 | ||||
-rw-r--r-- | buildscripts/idl/tests/test_binder.py | 39 | ||||
-rw-r--r-- | src/mongo/idl/unittest.idl | 1 |
4 files changed, 64 insertions, 13 deletions
diff --git a/buildscripts/idl/idl/generator.py b/buildscripts/idl/idl/generator.py index 35e250998b7..40a81f18aab 100644 --- a/buildscripts/idl/idl/generator.py +++ b/buildscripts/idl/idl/generator.py @@ -236,8 +236,13 @@ class _FastFieldUsageChecker(_FieldUsageCheckerBase): with writer.IndentedScopedBlock(self._writer, 'if (!usedFields[%s]) {' % (_gen_field_usage_constant(field)), '}'): if field.default: - self._writer.write_line('%s = %s;' % - (_get_field_member_name(field), field.default)) + if field.chained_struct_field: + self._writer.write_line('%s.%s(%s);' % ( + _get_field_member_name(field.chained_struct_field), + _get_field_member_setter_name(field), field.default)) + else: + self._writer.write_line( + '%s = %s;' % (_get_field_member_name(field), field.default)) else: self._writer.write_line('ctxt.throwMissingField(%s);' % (_get_field_constant_name(field))) @@ -817,7 +822,12 @@ class _CppSourceFileWriter(_CppFileWriterBase): self._writer.write_line('++expectedFieldNumber;') - self._writer.write_line('%s = std::move(values);' % (_get_field_member_name(field))) + if field.chained_struct_field: + self._writer.write_line('%s.%s(std::move(values));' % + (_get_field_member_name(field.chained_struct_field), + _get_field_member_setter_name(field))) + else: + self._writer.write_line('%s = std::move(values);' % (_get_field_member_name(field))) def gen_field_deserializer(self, field, bson_object): # type: (ast.Field, unicode) -> None @@ -976,7 +986,7 @@ class _CppSourceFileWriter(_CppFileWriterBase): first_field = True for field in struct.fields: # Do not parse chained fields as fields since they are actually chained types. - if field.chained: + if field.chained and not field.chained_struct_field: continue field_predicate = 'fieldName == %s' % (_get_field_constant_name(field)) @@ -1009,15 +1019,16 @@ class _CppSourceFileWriter(_CppFileWriterBase): with self._predicate(command_predicate): self._writer.write_line('ctxt.throwUnknownField(fieldName);') - # Parse chained types if not inlined - if not struct.inline_chained_structs: - for field in struct.fields: - if not field.chained: - continue + # Parse chained structs if not inlined + # Parse chained types always here + for field in struct.fields: + if not field.chained or \ + (field.chained and field.struct_type and struct.inline_chained_structs): + continue - # Simply generate deserializers since these are all 'any' types - self.gen_field_deserializer(field, bson_object) - self._writer.write_empty_line() + # Simply generate deserializers since these are all 'any' types + self.gen_field_deserializer(field, bson_object) + self._writer.write_empty_line() self._writer.write_empty_line() diff --git a/buildscripts/idl/idl/syntax.py b/buildscripts/idl/idl/syntax.py index df355084555..dabcad44800 100644 --- a/buildscripts/idl/idl/syntax.py +++ b/buildscripts/idl/idl/syntax.py @@ -342,7 +342,7 @@ class Struct(common.SourceLocation): self.description = None # type: unicode self.strict = True # type: bool self.immutable = False # type: bool - self.inline_chained_structs = False # type: bool + self.inline_chained_structs = True # type: bool self.generate_comparison_operators = False # type: bool self.chained_types = None # type: List[ChainedType] self.chained_structs = None # type: List[ChainedStruct] diff --git a/buildscripts/idl/tests/test_binder.py b/buildscripts/idl/tests/test_binder.py index 5a086885b5b..b11d2d2984d 100644 --- a/buildscripts/idl/tests/test_binder.py +++ b/buildscripts/idl/tests/test_binder.py @@ -994,6 +994,44 @@ class TestBinder(testcase.IDLTestcase): foo1: string """))) + # Inline Chained struct with strict true + self.assert_bind(test_preamble + indent_text(1, + textwrap.dedent(""" + bar1: + description: foo + strict: true + fields: + field1: string + + foobar: + description: foo + strict: false + inline_chained_structs: true + chained_structs: + bar1: alias + fields: + f1: string + + """))) + + # Inline Chained struct with strict true and inline_chained_structs defaulted + self.assert_bind(test_preamble + indent_text(1, + textwrap.dedent(""" + bar1: + description: foo + strict: true + fields: + field1: string + + foobar: + description: foo + strict: false + chained_structs: + bar1: alias + fields: + f1: string + """))) + def test_chained_struct_negative(self): # type: () -> None """Negative parser chaining test cases.""" @@ -1096,6 +1134,7 @@ class TestBinder(testcase.IDLTestcase): foobar: description: foo strict: false + inline_chained_structs: false chained_structs: bar1: alias fields: diff --git a/src/mongo/idl/unittest.idl b/src/mongo/idl/unittest.idl index f2e43c056c7..8c621daa1d0 100644 --- a/src/mongo/idl/unittest.idl +++ b/src/mongo/idl/unittest.idl @@ -445,6 +445,7 @@ structs: chained_struct_mixed: description: Chained struct with chained structs and fields strict: true + inline_chained_structs: false chained_structs: chained_any_basic_type : chained_any_basic_type chained_object_basic_type : ChainedObjectBasicType |