Ejemplo n.º 1
0
 def testIsReference_withValidReferenceType_returnsTrue(self):
   """Test is_reference functionality on valid input."""
   reference = datatypes_pb2.Reference()
   ref_descriptor_proto = self._descriptor_proto_for_descriptor(
       reference.DESCRIPTOR)
   self.assertTrue(annotation_utils.is_reference(reference))
   self.assertTrue(annotation_utils.is_reference(reference.DESCRIPTOR))
   self.assertTrue(annotation_utils.is_reference(ref_descriptor_proto))
Ejemplo n.º 2
0
 def testIsReference_withInvalidReferenceType_returnsFalse(self):
     """Test is_reference functionality on invalid input."""
     boolean = datatypes_pb2.Boolean()
     code = datatypes_pb2.Code()
     self.assertFalse(annotation_utils.is_reference(boolean))
     self.assertFalse(annotation_utils.is_reference(boolean.DESCRIPTOR))
     self.assertFalse(annotation_utils.is_reference(code))
     self.assertFalse(annotation_utils.is_reference(code.DESCRIPTOR))
Ejemplo n.º 3
0
def _validate_field(msg: message.Message, field: descriptor.FieldDescriptor,
                    field_name: str,
                    primitive_handler_: primitive_handler.PrimitiveHandler):
    """Validates that required fields are set, and performs basic temporal checks.

  Args:
    msg: The Message that the field belongs to.
    field: The FieldDescriptor of the field to examine.
    field_name: The name of the field.
    primitive_handler_: Responsible for returning PrimitiveWrappers.

  Raises:
    fhir_errors.InvalidFhirError: In the event that a required field is not set
    or if temporal requirements are not met.
  """
    if annotation_utils.field_is_required(
            field) and not proto_utils.field_is_set(msg, field):
        raise fhir_errors.InvalidFhirError(
            f'Required field `{field.full_name}` is missing.')

    if annotation_utils.is_reference(field.message_type):
        _validate_reference_field(msg, field)
        return

    if field.type == descriptor.FieldDescriptor.TYPE_MESSAGE:
        # Returns the first value only for a singular field
        for i in range(proto_utils.field_content_length(msg, field)):
            submessage = proto_utils.get_value_at_field_index(msg, field, i)
            _validate_fhir_constraints(submessage, field_name,
                                       primitive_handler_)

            # Run extra validation for some types, until FHIRPath validation covers
            # these as well
            if fhir_types.is_period(submessage):
                _validate_period(submessage, field_name)
Ejemplo n.º 4
0
    def merge_value(self, json_value: Any, target: message.Message):
        """Merges the provided json_value into the target Message.

    Args:
      json_value: A Python-native representation of JSON data.
      target: The target Message to merge the JSON data into.
    """
        target_descriptor = target.DESCRIPTOR
        if annotation_utils.is_primitive_type(target_descriptor):
            if isinstance(json_value, dict):
                # This is a primitive type extension. Merge the extension fields into
                # the empty target proto, and tag it as having no value.
                self._merge_message(json_value, target)

                extension_field = target_descriptor.fields_by_name.get(
                    'extension')
                if extension_field is None:
                    raise ValueError(
                        "Invalid primitive. No 'extension' field exists on "
                        f"{target_descriptor.full_name}.")
                primitive_has_no_value = extensions.create_primitive_has_no_value(
                    extension_field.message_type)
                proto_utils.append_value_at_field(target, extension_field,
                                                  primitive_has_no_value)
            else:
                wrapper = self.primitive_handler.primitive_wrapper_from_json_value(
                    json_value,
                    type(target),
                    default_timezone=self.default_timezone)
                wrapper.merge_into(target)
        elif annotation_utils.is_reference(target_descriptor):
            self._merge_message(json_value, target)
            references.split_if_relative_reference(target)
        else:
            if isinstance(json_value, dict):
                # The provided value must be another FHIR element
                self._merge_message(json_value, target)
            elif isinstance(json_value,
                            (tuple, list)) and len(json_value) == 1:
                # Check if the target field is non-repeated, and we're trying to
                # populate it with a single-element array. This is considered valid, and
                # occurs when a profiled resource reduces the size of a repeated FHIR
                # field to a maximum of 1.
                self._merge_message(json_value[0], target)
            else:
                raise ValueError(
                    'Expected a JSON object for field of type: {}.'.format(
                        target_descriptor.full_name))
Ejemplo n.º 5
0
 def _print(self, msg: message.Message):
     """Prints the JSON representation of message to the underlying generator."""
     # TODO: Identify ContainedResource with an annotation
     if msg.DESCRIPTOR.name == 'ContainedResource':
         self._print_contained_resource(msg)
     elif msg.DESCRIPTOR.full_name == any_pb2.Any.DESCRIPTOR.full_name:
         contained_resource = self.primitive_handler.new_contained_resource(
         )
         cast(any_pb2.Any, msg).Unpack(contained_resource)
         self._print_contained_resource(contained_resource)
     elif fhir_types.is_extension(msg):
         self._print_extension(msg)
     elif annotation_utils.is_reference(msg):
         self._print_reference(msg)
     else:
         self._print_message(msg)
Ejemplo n.º 6
0
 def _print(self, msg: message.Message) -> None:
     """Prints the JSON representation of message to the underlying generator."""
     # TODO: Identify ContainedResource with an annotation
     if msg.DESCRIPTOR.name == 'ContainedResource':
         self._print_contained_resource(msg)
     elif msg.DESCRIPTOR.full_name == any_pb2.Any.DESCRIPTOR.full_name:
         contained_resource = self.primitive_handler.new_contained_resource(
         )
         if not cast(any_pb2.Any, msg).Unpack(contained_resource):
             # If we can't unpack the Any, drop it.
             # TODO: Use a registry to determine the correct
             # ContainedResource to unpack to
             return
         self._print_contained_resource(contained_resource)
     elif fhir_types.is_extension(msg):
         self._print_extension(msg)
     elif annotation_utils.is_reference(msg):
         self._print_reference(msg)
     else:
         self._print_message(msg)
Ejemplo n.º 7
0
def _validate_reference(reference: message.Message):
    """Raises a ValueError if the provided Message is not a FHIR reference."""
    if not annotation_utils.is_reference(reference):
        raise ValueError(
            f'Message {reference.DESCRIPTOR.name} is not a FHIR reference.')