Search in sources :

Example 36 with DescriptorSet

use of com.spotify.protoman.descriptor.DescriptorSet in project protoman by spotify.

the class SchemaRegistry method buildDescriptorSets.

private BuildDescriptorsResult buildDescriptorSets(final SchemaStorage.Transaction tx, final ImmutableList<SchemaFile> schemaFiles) throws DescriptorBuilderException {
    final long snapshotVersion = tx.getLatestSnapshotVersion();
    // Paths of all updated files
    final ImmutableSet<Path> updatedPaths = schemaFiles.stream().map(SchemaFile::path).collect(toImmutableSet());
    final ImmutableSet<Path> updatedAndDependencies = resolveDependencies(tx, snapshotVersion, updatedPaths);
    try (final DescriptorBuilder descriptorBuilder = descriptorBuilderFactory.newDescriptorBuilder()) {
        // Seed descriptor builder with all files from registry
        // Builder DescriptorSet for what is currently in the registry for the files being updated
        final ImmutableMap<Path, SchemaFile> currentSchemata = updatedAndDependencies.stream().map(path -> tx.schemaFile(snapshotVersion, path)).collect(toImmutableMap(SchemaFile::path, Function.identity()));
        for (SchemaFile file : currentSchemata.values()) {
            descriptorBuilder.setProtoFile(file.path(), file.content());
        }
        // NOTE(staffan): As it is right now, we need compile ALL descriptors to catch breaking
        // changes.
        // NOTE(fredrikd): Not compiling all any more, but keeping this message until
        // tests are added
        // 
        // Consider the case where the following files exists in the repository:
        // 
        // herp/derp.proto:
        // package herp;
        // message Derp {}
        // foo/bar.proto
        // package foo;
        // import "herp/derp.proto"
        // message Bar {
        // Derp derp = 1;
        // }
        // 
        // And a publish request that changes "herp/derp.proto" to:
        // package herp {}
        // message Herpaderp {} // Derp was removed/renamed!
        // 
        // 
        // That change will break "foo/bar.proto" -- BUT protoc will succeeded if we only run it
        // with foo/bar.proto as the input.
        // 
        // So, we either need to either:
        // - Run protoc will ALL files as input, or
        // - Run protoc will ALL files that DEPEND ON a file being changed as input, or
        // - Track dependencies are ensured that types in use are not removed
        final DescriptorBuilder.Result currentResult = descriptorBuilder.buildDescriptor(currentSchemata.keySet().stream());
        @Nullable final DescriptorSet currentDs = createFilteredDescriptorSet(currentResult.fileDescriptorSet(), updatedPaths);
        // Build DescriptorSet for the updated files
        for (SchemaFile schemaFile : schemaFiles) {
            descriptorBuilder.setProtoFile(schemaFile.path(), schemaFile.content());
        }
        final DescriptorBuilder.Result candidateResult = descriptorBuilder.buildDescriptor(Stream.concat(currentSchemata.keySet().stream(), schemaFiles.stream().map(SchemaFile::path)).collect(toImmutableSet()).stream());
        @Nullable final DescriptorSet candidateDs = createFilteredDescriptorSet(candidateResult.fileDescriptorSet(), updatedPaths);
        return BuildDescriptorsResult.create(currentDs, candidateDs, currentResult.compilationError(), candidateResult.compilationError());
    }
}
Also used : Path(java.nio.file.Path) DescriptorProtos(com.google.protobuf.DescriptorProtos) DescriptorBuilder(com.spotify.protoman.descriptor.DescriptorBuilder) LoggerFactory(org.slf4j.LoggerFactory) HashMap(java.util.HashMap) SchemaValidator(com.spotify.protoman.validation.SchemaValidator) Function(java.util.function.Function) ImmutableList(com.google.common.collect.ImmutableList) Map(java.util.Map) ImmutableSet.toImmutableSet(com.google.common.collect.ImmutableSet.toImmutableSet) Path(java.nio.file.Path) Nullable(javax.annotation.Nullable) ImmutableSet(com.google.common.collect.ImmutableSet) Logger(org.slf4j.Logger) ImmutableMap(com.google.common.collect.ImmutableMap) ValidationViolation(com.spotify.protoman.validation.ValidationViolation) FileDescriptor(com.spotify.protoman.descriptor.FileDescriptor) Set(java.util.Set) Collectors(java.util.stream.Collectors) Sets(com.google.common.collect.Sets) Objects(java.util.Objects) DescriptorBuilderException(com.spotify.protoman.descriptor.DescriptorBuilderException) ImmutableMap.toImmutableMap(com.google.common.collect.ImmutableMap.toImmutableMap) List(java.util.List) Stream(java.util.stream.Stream) SchemaStorage(com.spotify.protoman.registry.storage.SchemaStorage) AutoValue(com.google.auto.value.AutoValue) Optional(java.util.Optional) Queue(java.util.Queue) ArrayDeque(java.util.ArrayDeque) DescriptorSet(com.spotify.protoman.descriptor.DescriptorSet) DescriptorBuilder(com.spotify.protoman.descriptor.DescriptorBuilder) DescriptorSet(com.spotify.protoman.descriptor.DescriptorSet) Nullable(javax.annotation.Nullable)

Example 37 with DescriptorSet

use of com.spotify.protoman.descriptor.DescriptorSet in project protoman by spotify.

the class DescriptorSetUtils method buildDescriptorSetPair.

public static DescriptorSetPair buildDescriptorSetPair(final Path root, final Predicate<Path> filter) throws IOException, URISyntaxException, DescriptorBuilderException {
    final DescriptorSet current = buildDescriptorSet(root.resolve("current"), filter);
    final DescriptorSet candidate = buildDescriptorSet(root.resolve("candidate"), filter);
    return DescriptorSetPair.create(current, candidate);
}
Also used : DescriptorSet(com.spotify.protoman.descriptor.DescriptorSet)

Example 38 with DescriptorSet

use of com.spotify.protoman.descriptor.DescriptorSet in project protoman by spotify.

the class EnumDefaultValueTest method testDisallowedName.

@Parameters(method = "disallowedNames")
@Test
public void testDisallowedName(final String name) throws Exception {
    final DescriptorSet candidate = DescriptorSetUtils.buildDescriptorSet("a.proto", String.format(TEMPLATE, name));
    final ImmutableList<ValidationViolation> violations = schemaValidator.validate(DescriptorSet.empty(), candidate);
    assertThat(violations, contains(validationViolation().description(equalTo("enum value 0 should be used for unknown value, e.g. AN_ENUM_UNSPECIFIED")).type(equalTo(ViolationType.BEST_PRACTICE_VIOLATION)).current(nullValue(GenericDescriptor.class)).candidate(genericDescriptor().sourceCodeInfo(optionalWithValue(sourceCodeInfo().start(filePosition().line(2).column(1)))))));
}
Also used : ValidationViolation(com.spotify.protoman.validation.ValidationViolation) DescriptorSet(com.spotify.protoman.descriptor.DescriptorSet) Parameters(junitparams.Parameters) Test(org.junit.Test)

Example 39 with DescriptorSet

use of com.spotify.protoman.descriptor.DescriptorSet in project protoman by spotify.

the class EnumNamingRuleTest method testDisallowedName_existing.

@Parameters(method = "disallowedNames")
@Test
public void testDisallowedName_existing(final String name) throws Exception {
    final DescriptorSet candidate = DescriptorSetUtils.buildDescriptorSet("a.proto", String.format(TEMPLATE, name));
    final ImmutableList<ValidationViolation> violations = schemaValidator.validate(candidate, candidate);
    assertThat(violations, is(empty()));
}
Also used : ValidationViolation(com.spotify.protoman.validation.ValidationViolation) DescriptorSet(com.spotify.protoman.descriptor.DescriptorSet) Parameters(junitparams.Parameters) Test(org.junit.Test)

Example 40 with DescriptorSet

use of com.spotify.protoman.descriptor.DescriptorSet in project protoman by spotify.

the class EnumValueNamingRuleTest method testAllowedName_new.

@Parameters(method = "allowedNames")
@Test
public void testAllowedName_new(final String name) throws Exception {
    final DescriptorSet current = DescriptorSet.empty();
    final DescriptorSet candidate = DescriptorSetUtils.buildDescriptorSet("a.proto", "syntax = 'proto3';\n" + "enum EnumWithNewValue {\n" + String.format("  %s = 0;\n", name) + "}");
    final ImmutableList<ValidationViolation> violations = schemaValidator.validate(current, candidate);
    assertThat(violations, is(empty()));
}
Also used : ValidationViolation(com.spotify.protoman.validation.ValidationViolation) DescriptorSet(com.spotify.protoman.descriptor.DescriptorSet) Parameters(junitparams.Parameters) Test(org.junit.Test)

Aggregations

DescriptorSet (com.spotify.protoman.descriptor.DescriptorSet)79 ValidationViolation (com.spotify.protoman.validation.ValidationViolation)76 Test (org.junit.Test)74 Parameters (junitparams.Parameters)43 ImmutableMap (com.google.common.collect.ImmutableMap)3 ImmutableMap.toImmutableMap (com.google.common.collect.ImmutableMap.toImmutableMap)3 DescriptorProtos (com.google.protobuf.DescriptorProtos)3 FileDescriptor (com.spotify.protoman.descriptor.FileDescriptor)3 Objects (java.util.Objects)3 Function (java.util.function.Function)3 Nullable (javax.annotation.Nullable)3 VisibleForTesting (com.google.common.annotations.VisibleForTesting)2 Preconditions (com.google.common.base.Preconditions)2 DescriptorBuilderException (com.spotify.protoman.descriptor.DescriptorBuilderException)2 SchemaStorage (com.spotify.protoman.registry.storage.SchemaStorage)2 Path (java.nio.file.Path)2 Predicate (java.util.function.Predicate)2 Matcher (java.util.regex.Matcher)2 Pattern (java.util.regex.Pattern)2 AutoValue (com.google.auto.value.AutoValue)1