// Copyright 2014 The Bazel Authors. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package com.google.devtools.build.lib.rules.objc; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSetMultimap; import com.google.common.collect.Multimap; import com.google.devtools.build.lib.actions.Artifact; import com.google.devtools.build.lib.util.FileType; import com.google.devtools.build.lib.vfs.PathFragment; import java.util.Collection; import java.util.Map; /** * Utility code for getting information specific to xcdatamodels for a single rule. */ class Xcdatamodels { private Xcdatamodels() {} static final ImmutableList<FileType> CONTAINER_TYPES = ImmutableList.of(FileType.of(".xcdatamodeld"), FileType.of(".xcdatamodel")); static Iterable<PathFragment> datamodelDirs(Iterable<Artifact> xcdatamodels) { ImmutableSet.Builder<PathFragment> result = new ImmutableSet.Builder<>(); for (Collection<Artifact> artifacts : byContainer(xcdatamodels).asMap().values()) { result.addAll(ObjcCommon.uniqueContainers(artifacts, FileType.of(".xcdatamodel"))); } return result.build(); } static Iterable<Xcdatamodel> xcdatamodels( IntermediateArtifacts intermediateArtifacts, Iterable<Artifact> xcdatamodels) { ImmutableSet.Builder<Xcdatamodel> result = new ImmutableSet.Builder<>(); Multimap<PathFragment, Artifact> artifactsByContainer = byContainer(xcdatamodels); for (Map.Entry<PathFragment, Collection<Artifact>> modelDirEntry : artifactsByContainer.asMap().entrySet()) { PathFragment container = modelDirEntry.getKey(); Artifact outputZip = intermediateArtifacts.compiledMomZipArtifact(container); result.add( new Xcdatamodel(outputZip, ImmutableSet.copyOf(modelDirEntry.getValue()), container)); } return result.build(); } /** * Arrange a sequence of artifacts into entries of a multimap by their nearest container * directory, preferring {@code .xcdatamodeld} over {@code .xcdatamodel}. * If an artifact is not inside any containing directory, then it is not present in the returned * map. */ static Multimap<PathFragment, Artifact> byContainer(Iterable<Artifact> artifacts) { ImmutableSetMultimap.Builder<PathFragment, Artifact> result = new ImmutableSetMultimap.Builder<>(); for (Artifact artifact : artifacts) { for (PathFragment modelDir : ObjcCommon.nearestContainerMatching(CONTAINER_TYPES, artifact).asSet()) { result.put(modelDir, artifact); } } return result.build(); } }