com.google.javascript.jscomp.IdMappingUtil Maven / Gradle / Ivy
/*
* Copyright 2015 The Closure Compiler Authors.
*
* 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.javascript.jscomp;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Splitter;
import com.google.common.base.Strings;
import com.google.common.collect.BiMap;
import com.google.common.collect.HashBiMap;
import com.google.javascript.jscomp.parsing.parser.util.format.SimpleFormat;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
/**
* A utility class for generating and parsing id mappings held by {@link ReplaceIdGenerators}.
*/
public final class IdMappingUtil {
@VisibleForTesting
static final char NEW_LINE = '\n';
private static final Splitter LINE_SPLITTER = Splitter.on(NEW_LINE).omitEmptyStrings();
// Prevent instantiation.
private IdMappingUtil() {}
/**
* @return The serialize map of generators and their ids and their
* replacements.
*/
static String generateSerializedIdMappings(Map> idGeneratorMaps) {
StringBuilder sb = new StringBuilder();
for (Map.Entry> replacements : idGeneratorMaps.entrySet()) {
if (!replacements.getValue().isEmpty()) {
sb.append('[')
.append(replacements.getKey())
.append(']')
.append(NEW_LINE)
.append(NEW_LINE);
for (Map.Entry replacement :
replacements.getValue().entrySet()) {
sb.append(replacement.getKey())
.append(':')
.append(replacement.getValue())
.append(NEW_LINE);
}
sb.append(NEW_LINE);
}
}
return sb.toString();
}
/**
* The expected format looks like this:
*
* [generatorName1]
* someId1:someFile:theLine:theColumn
* ...
*
*
[[generatorName2]
* someId2:someFile:theLine:theColumn]
* ...
*
*
The returned data is grouped by generator name (the map key). The inner map provides
* mappings from id to content (file, line and column info). In a glimpse, the structure is
* {@code Map>}.
*
* @throws IllegalArgumentException malformed input where there it 1) has duplicate generator
* name, or 2) the line has no ':' for id and its content.
*/
public static Map> parseSerializedIdMappings(String idMappings) {
if (Strings.isNullOrEmpty(idMappings)) {
return Collections.emptyMap();
}
Map> resultMap = new HashMap<>();
BiMap currentSectionMap = null;
int lineIndex = 0;
for (String line : LINE_SPLITTER.split(idMappings)) {
lineIndex++;
if (line.isEmpty()) {
continue;
}
if (line.charAt(0) == '[') {
String currentSection = line.substring(1, line.length() - 1);
currentSectionMap = resultMap.get(currentSection);
if (currentSectionMap == null) {
currentSectionMap = HashBiMap.create();
resultMap.put(currentSection, currentSectionMap);
} else {
throw new IllegalArgumentException(
SimpleFormat.format("Cannot parse id map: %s\n Line: $s, lineIndex: %s",
idMappings, line, lineIndex));
}
} else {
int split = line.indexOf(':');
if (split != -1) {
String name = line.substring(0, split);
String location = line.substring(split + 1, line.length());
currentSectionMap.put(name, location);
} else {
throw new IllegalArgumentException(
SimpleFormat.format("Cannot parse id map: %s\n Line: $s, lineIndex: %s",
idMappings, line, lineIndex));
}
}
}
return resultMap;
}
}