code: private Object retainAll(Schema schema, MarkSet markSet, ProtoType type, Object o) {
      if (!markSet.contains(type)) {
        return null; // Prune this type.
  
      } else if (o instanceof Map) {
        ImmutableMap.Builder<ProtoMember, Object> builder = ImmutableMap.builder();
        for (Map.Entry<?, ?> entry : ((Map<?, ?>) o).entrySet()) {
          ProtoMember protoMember = (ProtoMember) entry.getKey();
          if (!markSet.contains(protoMember)) continue; // Prune this field.
          Field field = schema.getField(protoMember);
          Object retainedValue = retainAll(schema, markSet, field.type(), entry.getValue());
          if (retainedValue != null) {
            builder.put(protoMember, retainedValue); // This retained field is non-empty.
          }
        }
        ImmutableMap<ProtoMember, Object> map = builder.build();
        return !map.isEmpty() ? map : null;
  
      } else if (o instanceof List) {
        ImmutableList.Builder<Object> builder = ImmutableList.builder();
        for (Object value : ((List) o)) {
          Object retainedValue = retainAll(schema, markSet, type, value);
          if (retainedValue != null) {
            builder.add(retainedValue); // This retained value is non-empty.
          }
        }
        ImmutableList<Object> list = builder.build();
        return !list.isEmpty() ? list : null;
  
      } else {
        return o;
      }
    }
docs: Returns an object of the same type as {@code o}, or null if it is not retained.