// Copyright 2015 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.syntax;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
import com.google.devtools.build.lib.events.Location;
import com.google.devtools.build.lib.skylarkinterface.SkylarkPrintable;
import com.google.devtools.build.lib.skylarkinterface.SkylarkPrinter;
import com.google.devtools.build.lib.skylarkinterface.SkylarkValue;
import com.google.devtools.build.lib.syntax.SkylarkList.Tuple;
import java.io.IOException;
import java.util.Arrays;
import java.util.Formattable;
import java.util.Formatter;
import java.util.List;
import java.util.Map;
import java.util.MissingFormatWidthException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.annotation.Nullable;
/** (Pretty) Printing of Skylark values */
public class Printer {
public static final char SKYLARK_QUOTATION_MARK = '"';
/*
* Suggested maximum number of list elements that should be printed via printAbbreviatedList().
* By default, this setting is not considered and no limitation takes place.
*/
public static final int SUGGESTED_CRITICAL_LIST_ELEMENTS_COUNT = 4;
/*
* Suggested limit for printAbbreviatedList() to shorten the values of list elements when
* their combined string length reaches this value.
* By default, this setting is not considered and no limitation takes place.
*/
public static final int SUGGESTED_CRITICAL_LIST_ELEMENTS_STRING_LENGTH = 32;
/**
* Creates an instance of {@link BasePrinter} that wraps an existing buffer.
*
* @param buffer an {@link Appendable}
* @return new {@link BasePrinter}
*/
static BasePrinter getPrinter(Appendable buffer) {
return new BasePrinter(buffer);
}
/**
* Creates an instance of {@link BasePrinter} with an empty buffer.
*
* @return new {@link BasePrinter}
*/
public static BasePrinter getPrinter() {
return getPrinter(new StringBuilder());
}
private Printer() {}
// These static methods proxy to the similar methods of BasePrinter
/**
* Format an object with Skylark's {@code str}.
*/
public static String str(Object x) {
return getPrinter().str(x).toString();
}
/**
* Format an object with Skylark's {@code repr}.
*/
public static String repr(Object x) {
return getPrinter().repr(x).toString();
}
/**
* Print a list of object representations.
*
*
The length of the output will be limited when both {@code maxItemsToPrint} and
* {@code criticalItemsStringLength} have values greater than zero.
*
* @param list the list of objects to repr (each as with repr)
* @param before a string to print before the list
* @param separator a separator to print between each object
* @param after a string to print after the list
* @param singletonTerminator null or a string to print after the list if it is a singleton The
* singleton case is notably relied upon in python syntax to distinguish a tuple of size one
* such as ("foo",) from a merely parenthesized object such as ("foo").
* @param maxItemsToPrint the maximum number of elements to be printed.
* @param criticalItemsStringLength a soft limit for the total string length of all arguments.
* 'Soft' means that this limit may be exceeded because of formatting.
* @return string representation.
*/
public static String printAbbreviatedList(
Iterable> list,
String before,
String separator,
String after,
@Nullable String singletonTerminator,
int maxItemsToPrint,
int criticalItemsStringLength) {
return new LengthLimitedPrinter()
.printAbbreviatedList(
list,
before,
separator,
after,
singletonTerminator,
maxItemsToPrint,
criticalItemsStringLength)
.toString();
}
/**
* Print a list of object representations.
*
* @param list the list of objects to repr (each as with repr)
* @param before a string to print before the list
* @param separator a separator to print between each object
* @param after a string to print after the list
* @param singletonTerminator null or a string to print after the list if it is a singleton The
* singleton case is notably relied upon in python syntax to distinguish a tuple of size one
* such as ("foo",) from a merely parenthesized object such as ("foo").
* @return string representation.
*/
public static String printAbbreviatedList(
Iterable> list,
String before,
String separator,
String after,
@Nullable String singletonTerminator) {
return printAbbreviatedList(list, before, separator, after, singletonTerminator,
SUGGESTED_CRITICAL_LIST_ELEMENTS_COUNT, SUGGESTED_CRITICAL_LIST_ELEMENTS_STRING_LENGTH);
}
/**
* Print a list of object representations.
*
*
The length of the output will be limited when both {@code maxItemsToPrint} and
* {@code criticalItemsStringLength} have values greater than zero.
*
* @param list the list of objects to repr (each as with repr)
* @param isTuple if true the list will be formatted with parentheses and with a trailing comma
* in case of one-element tuples.
* @param maxItemsToPrint the maximum number of elements to be printed.
* @param criticalItemsStringLength a soft limit for the total string length of all arguments.
* 'Soft' means that this limit may be exceeded because of formatting.
* @return string representation.
*/
public static String printAbbreviatedList(
Iterable> list,
boolean isTuple,
int maxItemsToPrint,
int criticalItemsStringLength) {
return new LengthLimitedPrinter()
.printAbbreviatedList(list, isTuple, maxItemsToPrint, criticalItemsStringLength)
.toString();
}
/**
* Perform Python-style string formatting, as per pattern % tuple Limitations: only %d %s %r %%
* are supported.
*
* @param pattern a format string.
* @param arguments an array containing positional arguments.
* @return the formatted string.
*/
public static String format(String pattern, Object... arguments) {
return getPrinter().format(pattern, arguments).toString();
}
/**
* Perform Python-style string formatting, as per pattern % tuple Limitations: only %d %s %r %%
* are supported.
*
* @param pattern a format string.
* @param arguments a tuple containing positional arguments.
* @return the formatted string.
*/
public static String formatWithList(String pattern, List> arguments) {
return getPrinter().formatWithList(pattern, arguments).toString();
}
/**
* Perform Python-style string formatting, lazily.
*
* @param pattern a format string.
* @param arguments positional arguments.
* @return the formatted string.
*/
public static Formattable formattable(final String pattern, Object... arguments) {
final List