All Downloads are FREE. Search and download functionalities are using the official Maven repository.

software.amazon.smithy.model.validation.validators.EnumTraitValidator Maven / Gradle / Ivy

/*
 * 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.model.validation.validators;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.regex.Pattern;
import software.amazon.smithy.model.Model;
import software.amazon.smithy.model.shapes.Shape;
import software.amazon.smithy.model.traits.EnumDefinition;
import software.amazon.smithy.model.traits.EnumTrait;
import software.amazon.smithy.model.validation.AbstractValidator;
import software.amazon.smithy.model.validation.ValidationEvent;

/**
 * Ensures that enum traits are valid.
 *
 * 

If one enum definition contains a name, then all definitions must contain * a name. All enum values and names must be unique across the list of * definitions. */ public final class EnumTraitValidator extends AbstractValidator { private static final Pattern RECOMMENDED_NAME_PATTERN = Pattern.compile("^[A-Z]+[A-Z_0-9]*$"); @Override public List validate(Model model) { List events = new ArrayList<>(); for (Shape shape : model.getShapesWithTrait(EnumTrait.class)) { events.addAll(validateEnumTrait(shape, shape.expectTrait(EnumTrait.class))); } return events; } private List validateEnumTrait(Shape shape, EnumTrait trait) { List events = new ArrayList<>(); Set names = new HashSet<>(); Set values = new HashSet<>(); // Ensure that values are unique. for (EnumDefinition definition : trait.getValues()) { if (!values.add(definition.getValue())) { events.add(error(shape, trait, String.format( "Duplicate enum trait values found with the same `value` property of '%s'", definition.getValue()))); } } // Ensure that names are unique. for (EnumDefinition definition : trait.getValues()) { if (definition.getName().isPresent()) { String name = definition.getName().get(); if (!names.add(name)) { events.add(error(shape, trait, String.format( "Duplicate enum trait values found with the same `name` property of '%s'", name))); } if (!RECOMMENDED_NAME_PATTERN.matcher(name).find()) { events.add(warning( shape, trait, String.format("The name `%s` does not match the recommended enum name format of beginning " + "with an uppercase letter, followed by any number of uppercase letters, numbers, " + "or underscores.", name), name) ); } } } if (!names.isEmpty()) { // If one enum definition has a name, then they all must have names. for (EnumDefinition definition : trait.getValues()) { if (!definition.getName().isPresent()) { events.add(error(shape, trait, String.format( "`%s` enum value body is missing the `name` property; if any enum trait value contains a " + "`name` property, then all values must contain the `name` property.", definition.getValue()))); } } } else { // Enums SHOULD have names, so warn if there are none. ValidationEvent event = warning(shape, trait, "Enums should define the `name` property to allow rich " + "types to be generated in code generators."); // Change the id of the event so that it can be suppressed separately. events.add(event.toBuilder().id("EnumNamesPresent").build()); } return events; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy