private void validateTypesAndTags() {
        //only validate if the optional ArtifactDefinitions is non-null
        if (artifactDefinitions != null) {
            //for each entry in the shapes map
            for (Map.Entry<ShapeId, List<ShapeLink>> entry : shapes.entrySet()) {
                //for each ShapeLink in entry's List<ShapeLink>
                for (ShapeLink link : entry.getValue()) {
                    //checking if link's type is in artifactDefinitions
                    if (!artifactDefinitions.getTypes().containsKey(link.getType())) {
                        throw new ExpectationNotMetException(entry.getKey().toString()
                                + " contains types that aren't in definitions.", SourceLocation.none());
                    }

                    //checking if link's tags are all in artifactDefinitions
                    List<String> tags = link.getTags();
                    for (String tag : tags) {
                        if (!artifactDefinitions.getTags().containsKey(tag)) {
                            throw new ExpectationNotMetException(entry.getKey().toString() + " " + tag
                                    + " is a tag that isn't in definitions.", SourceLocation.none());
                        }
                    }
                }
            }
        }
    }
Throws an error if any ShapeLink object contains a tag or type that is not in artifactDefinition's.
This method should be called after creating a TraceFile object to verify that all the types and tags
in shapes have been defined in artifactDefinition's. This TraceFile's ArtifactDefinitions object
MUST be defined prior to calling this method.

@throws ExpectationNotMetException if a type or tag in shapes is not in artifactDefinitions.
smithy-codegen-core/src/main/java/software/amazon/smithy/codegen/core/trace/TraceFile.java