function _rawCreateSegment({ shim, spec, parent, transaction }) {
  // When parent exists and is opaque, no new segment will be created
  // by tracer.createSegment and the parent will be returned. We bail
  // out early so we do not risk modifying the parent segment.
  if (parent?.opaque) {
    shim.logger.trace(spec, 'Did not create segment because parent is opaque')
    return parent
  }

  const segment = shim.tracer.createSegment({
    name: spec.name,
    recorder: spec.recorder,
    parent,
    transaction
  })
  if (segment) {
    segment.internal = spec.internal
    segment.opaque = spec.opaque
    segment.shimId = shim.id

    if (hasOwnProperty(spec, 'parameters')) {
      shim.copySegmentParameters(segment, spec.parameters)
    }
    shim.logger.trace(spec, 'Created segment')
  } else {
    shim.logger.debug(spec, 'Failed to create segment')
  }

  return segment
}
@private
@param {object} params to function
@param {Shim} params.shim instance of shim
@param {Transaction} params.transaction active transaction
@param {TraceSegment} params.parent the segment that will be the parent of the newly created segment
@param {string|specs.SegmentSpec} params.spec options for creating segment
@returns {?TraceSegment} A new trace segment if a transaction is active, else
 `null` is returned.