ProjectType computeProjectionType(bool hasFindSlice,
                                  bool hasElemMatch,
                                  bool hasMeta,
                                  const ProjectionPolicies& policies,
                                  bool idIncludedEntirely,
                                  bool idExcludedEntirely) {
    if (hasFindSlice) {
        // If there's a find $slice then the presence of an {_id: 1} overrides, regardless of other
        // find() expressions. If there's no _id, then it defaults to exclusion.
        if (idIncludedEntirely) {
            return ProjectType::kInclusion;
        } else {
            // Either _id is explicitly excluded _or_ not mentioned at all, in which case we
            // default to exclusion.
            return ProjectType::kExclusion;
        }
    } else if (hasElemMatch) {
        // If there's an $elemMatch (but no $slice) then it's an inclusion projection. Note that
        // this is _regardless_ of what value is provided for _id. This is consistent with the
        // behavior of most expressions: for an arbitrary $func expression, the rule is that {foo:
        // {$func: ...}}, {_id: 0, foo: {$func: ...}}, and {_id: 1, foo: {$func: ...}} are all
        // inclusions.
        return ProjectType::kInclusion;
    } else if (hasMeta) {
        if (policies.findOnlyFeaturesAllowed()) {
            // In find, {_id: 0, x: {$meta: ...}} is considered exclusion.
            if (idExcludedEntirely) {
                return ProjectType::kExclusion;
            }

            // In find, {_id: 1, x: {$meta: ...}} is considered inclusion.
            if (idIncludedEntirely) {
                return ProjectType::kInclusion;
            }

            // Just $meta by itself is exclusion.
            return ProjectType::kExclusion;
        } else {
            // In aggregate(), any projection with a $meta is an inclusion projection.
            return ProjectType::kInclusion;
        }
    } else if (idIncludedEntirely) {
        // There were no expressions. So this is an {_id: 1} projection. It is an
        // inclusion. The ParseContext's type field was not marked as an inclusion, because a
        // projection {_id: 1, a: 0} is also valid, but considered exclusion.
        return ProjectType::kInclusion;
    } else if (idExcludedEntirely) {
        // There were no expressions, but there is an {_id: 0} element. This is an exclusion.  The
        // ParseContext's 'type' field was not marked as an exclusion because a projection {_id: 0,
        // a: 1} is valid but considered inclusion.
        return ProjectType::kExclusion;
    }

    // Default is exclusion otherwise.
    return ProjectType::kExclusion;
}
ProjectType computeProjectionType(bool hasFindSlice,
                                  bool hasElemMatch,
                                  bool hasMeta,
                                  const ProjectionPolicies& policies,
                                  bool idIncludedEntirely,
                                  bool idExcludedEntirely) {
    if (hasFindSlice) {
         
         
        if (idIncludedEntirely) {
            return ProjectType::kInclusion;
        } else {
             
             
            return ProjectType::kExclusion;
        }
    } else if (hasElemMatch) {
         
         
         
         
         
        return ProjectType::kInclusion;
    } else if (hasMeta) {
        if (policies.findOnlyFeaturesAllowed()) {
             
            if (idExcludedEntirely) {
                return ProjectType::kExclusion;
            }

             
            if (idIncludedEntirely) {
                return ProjectType::kInclusion;
            }

             
            return ProjectType::kExclusion;
        } else {
             
            return ProjectType::kInclusion;
        }
    } else if (idIncludedEntirely) {
         
         
         
        return ProjectType::kInclusion;
    } else if (idExcludedEntirely) {
         
         
         
        return ProjectType::kExclusion;
    }

     
    return ProjectType::kExclusion;
}