summaryrefslogtreecommitdiff
path: root/buildscripts
diff options
context:
space:
mode:
authorJason Chan <jason.chan@mongodb.com>2022-08-15 14:15:39 +0000
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2022-08-15 15:32:50 +0000
commitabca3f700aa1da45ea14c8f2dc6ab52f952e3945 (patch)
tree47e72b505dc1663f929d56e625bc650df27ad305 /buildscripts
parentcf52d18cc9aa016ae978786f4b9e99c12d1b582b (diff)
downloadmongo-abca3f700aa1da45ea14c8f2dc6ab52f952e3945.tar.gz
Revert "SERVER-67826 Ensure parsed IDL types own or preserve the lifetime of their data"
This reverts commit de251a83a41566723a895bf1106c66d9f19d1540.
Diffstat (limited to 'buildscripts')
-rw-r--r--buildscripts/idl/idl/generator.py120
-rw-r--r--buildscripts/idl/idl/struct_types.py55
2 files changed, 27 insertions, 148 deletions
diff --git a/buildscripts/idl/idl/generator.py b/buildscripts/idl/idl/generator.py
index 79928b29ab9..a4ea20a4a33 100644
--- a/buildscripts/idl/idl/generator.py
+++ b/buildscripts/idl/idl/generator.py
@@ -36,21 +36,12 @@ import re
import sys
import textwrap
from abc import ABCMeta, abstractmethod
-from enum import Enum
from typing import Dict, Iterable, List, Mapping, Tuple, Union, cast
from . import (ast, bson, common, cpp_types, enum_types, generic_field_list_types, struct_types,
writer)
-class _StructDataOwnership(Enum):
- """Enumerates the ways a struct may participate in ownership of it's data."""
-
- VIEW = 1 # Doesn't participate in ownership
- SHARED = 2 # Participates in non-exclusive ownership
- OWNER = 3 # Takes ownership of underlying data
-
-
def _get_field_member_name(field):
# type: (ast.Field) -> str
"""Get the C++ class member name for a field."""
@@ -479,64 +470,26 @@ class _CppHeaderFileWriter(_CppFileWriterBase):
def gen_serializer_methods(self, struct):
# type: (ast.Struct) -> None
- """Generate serializer method declarations."""
- struct_type_info = struct_types.get_struct_info(struct)
- self._writer.write_line(struct_type_info.get_serializer_method().get_declaration())
+ """Generate a serializer method declarations."""
- maybe_op_msg_serializer = struct_type_info.get_op_msg_request_serializer_method()
- if maybe_op_msg_serializer:
- self._writer.write_line(maybe_op_msg_serializer.get_declaration())
+ struct_type_info = struct_types.get_struct_info(struct)
- self._writer.write_line(struct_type_info.get_to_bson_method().get_declaration())
+ parse_method = struct_type_info.get_deserializer_static_method()
+ if parse_method:
+ self._writer.write_line(parse_method.get_declaration())
- self._writer.write_empty_line()
+ parse_method = struct_type_info.get_op_msg_request_deserializer_static_method()
+ if parse_method:
+ self._writer.write_line(parse_method.get_declaration())
- def gen_deserializer_methods(self, struct):
- # type: (ast.Struct) -> None
- """Generate deserializer method declarations."""
- struct_type_info = struct_types.get_struct_info(struct)
- possible_deserializer_methods = [
- struct_type_info.get_deserializer_static_method(),
- struct_type_info.get_owned_deserializer_static_method(),
- struct_type_info.get_sharing_deserializer_static_method(),
- struct_type_info.get_op_msg_request_deserializer_static_method()
- ]
- for maybe_parse_method in possible_deserializer_methods:
- if maybe_parse_method:
- comment = maybe_parse_method.get_desc_for_comment()
- if comment:
- self.gen_description_comment(comment)
- self._writer.write_line(maybe_parse_method.get_declaration())
+ self._writer.write_line(struct_type_info.get_serializer_method().get_declaration())
- self._writer.write_empty_line()
+ parse_method = struct_type_info.get_op_msg_request_serializer_method()
+ if parse_method:
+ self._writer.write_line(parse_method.get_declaration())
- def gen_ownership_getter(self):
- # type: () -> None
- """Generate a getter that returns true if this IDL object owns its underlying data."""
- self.gen_description_comment(
- textwrap.dedent("""\
- An IDL struct can either provide a view onto some underlying BSON data, or it can
- participate in owning that data. This function returns true if the struct participates in
- owning the underlying data.
-
- Note that the underlying data is not synchronized with the IDL struct over its lifetime; to
- generate a BSON representation of an IDL struct, use its `serialize` member functions.
- Participating in ownership of the underlying data merely allows the struct to ensure that
- struct members that are pointers-into-BSON (i.e. BSONElement and BSONObject) are valid for
- the lifetime of the struct itself."""))
- self._writer.write_line("bool isOwned() const { return _anchorObj.isOwned(); }")
-
- def gen_private_ownership_setters(self):
- # type: () -> None
- """Generate a setter that can be used to allow this IDL struct to particpate in the ownership of some BSON that the struct's members refer to."""
- with self._block('void setAnchor(const BSONObj& obj) {', '}'):
- self._writer.write_line("invariant(obj.isOwned());")
- self._writer.write_line("_anchorObj = obj;")
- self._writer.write_empty_line()
+ self._writer.write_line(struct_type_info.get_to_bson_method().get_declaration())
- with self._block('void setAnchor(BSONObj&& obj) {', '}'):
- self._writer.write_line("invariant(obj.isOwned());")
- self._writer.write_line("_anchorObj = std::move(obj);")
self._writer.write_empty_line()
def gen_protected_serializer_methods(self, struct):
@@ -1122,14 +1075,9 @@ class _CppHeaderFileWriter(_CppFileWriterBase):
# Write serialization
self.gen_serializer_methods(struct)
- # Write deserialization
- self.gen_deserializer_methods(struct)
-
if isinstance(struct, ast.Command):
self.gen_op_msg_request_methods(struct)
- self.gen_ownership_getter()
-
# Write getters & setters
for field in struct.fields:
if not field.ignore:
@@ -1155,8 +1103,6 @@ class _CppHeaderFileWriter(_CppFileWriterBase):
self.write_unindented_line('private:')
- self.gen_private_ownership_setters()
-
if struct.generate_comparison_operators:
self.gen_comparison_operators_declarations(struct)
@@ -1172,8 +1118,6 @@ class _CppHeaderFileWriter(_CppFileWriterBase):
if not field.ignore and not field.chained_struct_field:
self.gen_member(field)
- self._writer.write_line("BSONObj _anchorObj;")
-
# Write serializer member variables
# Note: we write these out second to ensure the bit fields can be packed by
# the compiler.
@@ -1759,9 +1703,8 @@ class _CppSourceFileWriter(_CppFileWriterBase):
return field_usage_check
- def get_bson_deserializer_static_common(self, struct, static_method_info, method_info,
- ownership):
- # type: (ast.Struct, struct_types.MethodInfo, struct_types.MethodInfo, _StructDataOwnership) -> None
+ def get_bson_deserializer_static_common(self, struct, static_method_info, method_info):
+ # type: (ast.Struct, struct_types.MethodInfo, struct_types.MethodInfo) -> None
"""Generate the C++ deserializer static method."""
# pylint: disable=invalid-name
func_def = static_method_info.get_definition()
@@ -1795,17 +1738,8 @@ class _CppSourceFileWriter(_CppFileWriterBase):
common.title_case(struct.cpp_name))
self._writer.write_line(method_info.get_call('object'))
-
- if ownership == _StructDataOwnership.OWNER:
- self._writer.write_line('object.setAnchor(std::move(bsonObject));')
-
- elif ownership == _StructDataOwnership.SHARED:
- self._writer.write_line('object.setAnchor(bsonObject);')
-
self._writer.write_line('return object;')
- self.write_empty_line()
-
def _compare_and_return_status(self, op, limit, field, optional_param):
# type: (str, ast.Expression, ast.Field, str) -> None
"""Throw an error on comparison failure."""
@@ -1865,29 +1799,20 @@ class _CppSourceFileWriter(_CppFileWriterBase):
# type: (ast.Struct) -> None
"""Generate the C++ deserializer method definitions."""
struct_type_info = struct_types.get_struct_info(struct)
- method = struct_type_info.get_deserializer_method()
self.get_bson_deserializer_static_common(struct,
struct_type_info.get_deserializer_static_method(),
- method, _StructDataOwnership.VIEW)
- self.get_bson_deserializer_static_common(
- struct, struct_type_info.get_sharing_deserializer_static_method(), method,
- _StructDataOwnership.SHARED)
- self.get_bson_deserializer_static_common(
- struct, struct_type_info.get_owned_deserializer_static_method(), method,
- _StructDataOwnership.OWNER)
-
- func_def = method.get_definition()
-
- # Name of the variable that we are deserialzing from
- variable_name = "bsonObject"
+ struct_type_info.get_deserializer_method())
+ func_def = struct_type_info.get_deserializer_method().get_definition()
with self._block('%s {' % (func_def), '}'):
+
# If the struct contains no fields, there's nothing to deserialize, so we write an empty function stub.
if not struct.fields:
return
- field_usage_check = self._gen_fields_deserializer_common(struct, variable_name)
+ # Deserialize all the fields
+ field_usage_check = self._gen_fields_deserializer_common(struct, "bsonObject")
# Check for required fields
field_usage_check.add_final_checks()
@@ -1896,7 +1821,7 @@ class _CppSourceFileWriter(_CppFileWriterBase):
if struct.cpp_validator_func is not None:
self._writer.write_line(struct.cpp_validator_func + "(this);")
- self._gen_command_deserializer(struct, variable_name)
+ self._gen_command_deserializer(struct, "bsonObject")
def gen_op_msg_request_deserializer_methods(self, struct):
# type: (ast.Struct) -> None
@@ -1911,7 +1836,7 @@ class _CppSourceFileWriter(_CppFileWriterBase):
self.get_bson_deserializer_static_common(
struct, struct_type_info.get_op_msg_request_deserializer_static_method(),
- struct_type_info.get_op_msg_request_deserializer_method(), _StructDataOwnership.VIEW)
+ struct_type_info.get_op_msg_request_deserializer_method())
func_def = struct_type_info.get_op_msg_request_deserializer_method().get_definition()
with self._block('%s {' % (func_def), '}'):
@@ -2785,6 +2710,7 @@ class _CppSourceFileWriter(_CppFileWriterBase):
self.gen_field_validators(struct)
self.write_empty_line()
+ # Write deserializers
self.gen_bson_deserializer_methods(struct)
self.write_empty_line()
diff --git a/buildscripts/idl/idl/struct_types.py b/buildscripts/idl/idl/struct_types.py
index 339defab4e2..6aeb1760db0 100644
--- a/buildscripts/idl/idl/struct_types.py
+++ b/buildscripts/idl/idl/struct_types.py
@@ -27,7 +27,6 @@
#
"""Provide code generation information for structs and commands in a polymorphic way."""
-import textwrap
from abc import ABCMeta, abstractmethod
from typing import Optional, List
@@ -81,11 +80,9 @@ class ArgumentInfo(object):
class MethodInfo(object):
"""Class that encapslates information about a method and how to declare, define, and call it."""
- # pylint: disable=too-many-instance-attributes
-
def __init__(self, class_name, method_name, args, return_type=None, static=False, const=False,
- explicit=False, desc_for_comment=None):
- # type: (str, str, List[str], str, bool, bool, bool, Optional[str]) -> None
+ explicit=False):
+ # type: (str, str, List[str], str, bool, bool, bool) -> None
# pylint: disable=too-many-arguments
"""Create a MethodInfo instance."""
self.class_name = class_name
@@ -95,7 +92,6 @@ class MethodInfo(object):
self.static = static
self.const = const
self.explicit = explicit
- self.desc_for_comment = desc_for_comment
def get_declaration(self):
# type: () -> str
@@ -142,7 +138,7 @@ class MethodInfo(object):
def get_call(self, obj):
# type: (Optional[str]) -> str
- """Generate a simple call to the method using the defined args list."""
+ """Generate a simply call to the method using the defined args list."""
args = ', '.join([arg.name for arg in self.args])
@@ -153,11 +149,6 @@ class MethodInfo(object):
return common.template_args("${method_name}(${args});", method_name=self.method_name,
args=args)
- def get_desc_for_comment(self):
- # type: () -> Optional[str]
- """Get the description of this method suitable for commenting it."""
- return self.desc_for_comment
-
class StructTypeInfoBase(object, metaclass=ABCMeta):
"""Base class for struct and command code generation."""
@@ -193,18 +184,6 @@ class StructTypeInfoBase(object, metaclass=ABCMeta):
pass
@abstractmethod
- def get_sharing_deserializer_static_method(self):
- # type: () -> MethodInfo
- """Get the public static deserializer method for a struct that participates in shared ownership of underlying data we are deserializing from."""
- pass
-
- @abstractmethod
- def get_owned_deserializer_static_method(self):
- # type: () -> MethodInfo
- """Get the public static deserializer method for a struct that takes exclusive ownership of underlying data we are deserializing from."""
- pass
-
- @abstractmethod
def get_deserializer_method(self):
# type: () -> MethodInfo
"""Get the protected deserializer method for a struct."""
@@ -274,38 +253,12 @@ class _StructTypeInfo(StructTypeInfoBase):
class_name = common.title_case(self._struct.cpp_name)
return MethodInfo(class_name, class_name, _get_required_parameters(self._struct))
- def get_sharing_deserializer_static_method(self):
- # type: () -> MethodInfo
- class_name = common.title_case(self._struct.cpp_name)
- comment = textwrap.dedent(f"""\
- Factory function that parses a {class_name} from a BSONObj. A {class_name} parsed
- this way participates in ownership of the data underlying the BSONObj.""")
- return MethodInfo(class_name, 'parseSharingOwnership',
- ['const IDLParserContext& ctxt', 'const BSONObj& bsonObject'], class_name,
- static=True, desc_for_comment=comment)
-
- def get_owned_deserializer_static_method(self):
- # type: () -> MethodInfo
- class_name = common.title_case(self._struct.cpp_name)
- comment = textwrap.dedent(f"""\
- Factory function that parses a {class_name} from a BSONObj. A {class_name} parsed
- this way takes ownership of the data underlying the BSONObj.""")
- return MethodInfo(class_name, 'parseOwned',
- ['const IDLParserContext& ctxt', 'BSONObj&& bsonObject'], class_name,
- static=True, desc_for_comment=comment)
-
def get_deserializer_static_method(self):
# type: () -> MethodInfo
class_name = common.title_case(self._struct.cpp_name)
- comment = textwrap.dedent(f"""\
- Factory function that parses a {class_name} from a BSONObj. A {class_name} parsed
- this way is strictly a view onto that BSONObj; the BSONObj must be kept valid to
- ensure the validity any members of this struct that point-into the BSONObj (i.e.
- unowned
- objects).""")
return MethodInfo(class_name, 'parse',
['const IDLParserContext& ctxt', 'const BSONObj& bsonObject'], class_name,
- static=True, desc_for_comment=comment)
+ static=True)
def get_deserializer_method(self):
# type: () -> MethodInfo