summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--buildscripts/idl/idl/generator.py35
-rw-r--r--buildscripts/idl/idl/syntax.py2
-rw-r--r--buildscripts/idl/tests/test_binder.py39
-rw-r--r--src/mongo/idl/unittest.idl1
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