-
Notifications
You must be signed in to change notification settings - Fork 218
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add ReservedWords builder for simpler construction
The ReservedWordsBuilder can be used to more easily construct a ReservedWords implementation, including loading reserved words from a newline delimited file that uses "#" as comments.
- Loading branch information
Showing
11 changed files
with
501 additions
and
14 deletions.
There are no files selected for viewing
42 changes: 42 additions & 0 deletions
42
...-core/src/main/java/software/amazon/smithy/codegen/core/CaseInsensitiveReservedWords.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
/* | ||
* Copyright 2019 Amazon.com, Inc. or its affiliates. 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. | ||
* A copy of the License is located at | ||
* | ||
* http://aws.amazon.com/apache2.0 | ||
* | ||
* or in the "license" file accompanying this file. This file 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 software.amazon.smithy.codegen.core; | ||
|
||
import java.util.Locale; | ||
import java.util.Set; | ||
import java.util.function.Function; | ||
import java.util.stream.Collectors; | ||
|
||
final class CaseInsensitiveReservedWords implements ReservedWords { | ||
|
||
private final Set<String> words; | ||
private final Function<String, String> escaper; | ||
|
||
CaseInsensitiveReservedWords(Set<String> words, Function<String, String> escaper) { | ||
this.words = words.stream().map(word -> word.toLowerCase(Locale.ENGLISH)).collect(Collectors.toSet()); | ||
this.escaper = escaper; | ||
} | ||
|
||
@Override | ||
public String escape(String word) { | ||
return isReserved(word) ? escaper.apply(word) : word; | ||
} | ||
|
||
@Override | ||
public boolean isReserved(String word) { | ||
return words.contains(word.toLowerCase(Locale.ENGLISH)); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
148 changes: 148 additions & 0 deletions
148
...-codegen-core/src/main/java/software/amazon/smithy/codegen/core/ReservedWordsBuilder.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,148 @@ | ||
/* | ||
* Copyright 2019 Amazon.com, Inc. or its affiliates. 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. | ||
* A copy of the License is located at | ||
* | ||
* http://aws.amazon.com/apache2.0 | ||
* | ||
* or in the "license" file accompanying this file. This file 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 software.amazon.smithy.codegen.core; | ||
|
||
import java.io.BufferedReader; | ||
import java.io.IOException; | ||
import java.io.InputStream; | ||
import java.io.InputStreamReader; | ||
import java.io.UncheckedIOException; | ||
import java.net.URL; | ||
import java.nio.charset.StandardCharsets; | ||
import java.util.ArrayList; | ||
import java.util.Collections; | ||
import java.util.HashMap; | ||
import java.util.List; | ||
import java.util.Map; | ||
import java.util.Set; | ||
import java.util.function.Function; | ||
import java.util.stream.Collectors; | ||
import software.amazon.smithy.utils.StringUtils; | ||
|
||
/** | ||
* Builds a {@link ReservedWords} implementation from explicit | ||
* mappings and from line-delimited files that contain reserved words. | ||
*/ | ||
public class ReservedWordsBuilder { | ||
|
||
private final Map<String, String> mappings = new HashMap<>(); | ||
private final List<ReservedWords> delegates = new ArrayList<>(); | ||
|
||
/** | ||
* Builds the reserved words. | ||
* | ||
* @return Returns the created reserved words implementation. | ||
*/ | ||
public ReservedWords build() { | ||
ReservedWords[] words = new ReservedWords[1 + delegates.size()]; | ||
words[0] = new MappedReservedWords(mappings, Collections.emptyMap()); | ||
for (int i = 0; i < delegates.size(); i++) { | ||
words[i + 1] = delegates.get(i); | ||
} | ||
|
||
return ReservedWords.compose(words); | ||
} | ||
|
||
/** | ||
* Add a new reserved words. | ||
* | ||
* @param reservedWord Reserved word to convert. | ||
* @param conversion Word to convert to. | ||
* @return Returns the builder. | ||
*/ | ||
public ReservedWordsBuilder put(String reservedWord, String conversion) { | ||
mappings.put(reservedWord, conversion); | ||
return this; | ||
} | ||
|
||
/** | ||
* Load a list of case-sensitive, line-delimited reserved words from a file. | ||
* | ||
* <p>This method will escape words by prefixing them with "_". Use | ||
* {@link #loadWords(URL, Function)} to customize how words are escaped. | ||
* | ||
* <p>Blank lines and lines that start with # are ignored. | ||
* | ||
* @param location URL of the file to load. | ||
* @return Returns the builder. | ||
*/ | ||
public ReservedWordsBuilder loadWords(URL location) { | ||
return loadWords(location, ReservedWordsBuilder::escapeWithUnderscore); | ||
} | ||
|
||
/** | ||
* Load a list of case-sensitive, line-delimited reserved words from a file. | ||
* | ||
* <p>Blank lines and lines that start with # are ignored. | ||
* | ||
* @param location URL of the file to load. | ||
* @param escaper Function used to escape reserved words. | ||
* @return Returns the builder. | ||
*/ | ||
public ReservedWordsBuilder loadWords(URL location, Function<String, String> escaper) { | ||
for (String word : readNonBlankNonCommentLines(location)) { | ||
put(word, escaper.apply(word)); | ||
} | ||
return this; | ||
} | ||
|
||
/** | ||
* Load a list of case-insensitive, line-delimited reserved words from a file. | ||
* | ||
* <p>This method will escape words by prefixing them with "_". Use | ||
* {@link #loadCaseInsensitiveWords(URL, Function)} to customize how words | ||
* are escaped. | ||
* | ||
* <p>Blank lines and lines that start with # are ignored. | ||
* | ||
* @param location URL of the file to load. | ||
* @return Returns the builder. | ||
*/ | ||
public ReservedWordsBuilder loadCaseInsensitiveWords(URL location) { | ||
return loadCaseInsensitiveWords(location, ReservedWordsBuilder::escapeWithUnderscore); | ||
} | ||
|
||
/** | ||
* Load a list of case-insensitive, line-delimited reserved words from a file. | ||
* | ||
* <p>Blank lines and lines that start with # are ignored. | ||
* | ||
* @param location URL of the file to load. | ||
* @param escaper Function used to escape reserved words. | ||
* @return Returns the builder. | ||
*/ | ||
public ReservedWordsBuilder loadCaseInsensitiveWords(URL location, Function<String, String> escaper) { | ||
delegates.add(new CaseInsensitiveReservedWords(readNonBlankNonCommentLines(location), escaper)); | ||
return this; | ||
} | ||
|
||
private static String escapeWithUnderscore(String word) { | ||
return "_" + word; | ||
} | ||
|
||
private static Set<String> readNonBlankNonCommentLines(URL url) { | ||
try (InputStream is = url.openConnection().getInputStream(); | ||
BufferedReader reader = new BufferedReader(new InputStreamReader(is, StandardCharsets.UTF_8))) { | ||
return reader.lines() | ||
.filter(StringUtils::isNotBlank) | ||
.filter(line -> !line.startsWith("#")) | ||
.map(word -> StringUtils.stripEnd(word, null)) | ||
.collect(Collectors.toSet()); | ||
} catch (IOException e) { | ||
throw new UncheckedIOException("Error loading reserved words from " + url + ": " + e.getMessage(), e); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.