Search in sources :

Example 1 with NewField

use of no.entur.schema2proto.modifyproto.config.NewField in project schema2proto by entur.

the class ModifyProto method addField.

private void addField(NewField newField, Schema prunedSchema) throws InvalidProtobufException {
    MessageType type = (MessageType) prunedSchema.getType(newField.targetMessageType);
    if (type == null) {
        throw new InvalidProtobufException("Did not find existing type " + newField.targetMessageType);
    } else {
        List<OptionElement> optionElements = new ArrayList<>();
        Options options = new Options(Options.FIELD_OPTIONS, optionElements);
        int tag = newField.fieldNumber;
        String fieldPackage = StringUtils.substringBeforeLast(newField.type, ".");
        if (fieldPackage.equals(newField.type)) {
            // no package
            fieldPackage = null;
        }
        Field.Label label = null;
        if (StringUtils.trimToNull(newField.label) != null) {
            label = Field.Label.valueOf(newField.label.toUpperCase());
        }
        Location location = new Location("", "", -1, -1);
        Field field = new Field(fieldPackage, location, label, newField.name, StringUtils.trimToEmpty(newField.documentation), tag, null, newField.type, options, false, false);
        List<Field> updatedFields = new ArrayList<>(type.fields());
        updatedFields.add(field);
        type.setDeclaredFields(updatedFields);
        String importStatement = StringUtils.trimToNull(newField.importProto);
        if (importStatement != null) {
            String targetPackageName = StringUtils.trimToNull(StringUtils.substringBeforeLast(newField.targetMessageType, "."));
            ProtoFile targetFile = prunedSchema.protoFileForPackage(targetPackageName);
            if (newField.targetMessageType.equals(targetPackageName)) {
                // no package name on target
                targetFile = prunedSchema.protoFileForPackage(null);
            }
            targetFile.imports().add(importStatement);
        }
    }
}
Also used : Options(com.squareup.wire.schema.Options) ArrayList(java.util.ArrayList) ProtoFile(com.squareup.wire.schema.ProtoFile) NewField(no.entur.schema2proto.modifyproto.config.NewField) Field(com.squareup.wire.schema.Field) OptionElement(com.squareup.wire.schema.internal.parser.OptionElement) MessageType(com.squareup.wire.schema.MessageType) Location(com.squareup.wire.schema.Location)

Example 2 with NewField

use of no.entur.schema2proto.modifyproto.config.NewField in project schema2proto by entur.

the class ModifyProtoTest method testAddEnumValue.

@Test
public void testAddEnumValue() throws IOException, InvalidProtobufException, InvalidConfigurationException {
    File expected = new File("src/test/resources/modify/expected/nopackagename").getCanonicalFile();
    File source = new File("src/test/resources/modify/input/nopackagename").getCanonicalFile();
    List<NewField> newFields = new ArrayList<>();
    NewField newField = new NewField();
    newField.targetMessageType = "A";
    // newField.importProto = "importpackage/p.proto";
    newField.label = "repeated";
    newField.fieldNumber = 100;
    newField.name = "new_field";
    newField.type = "B";
    newFields.add(newField);
    ModifyProtoConfiguration configuration = new ModifyProtoConfiguration();
    configuration.inputDirectory = source;
    configuration.newFields = Collections.singletonList(newField);
    modifyProto(configuration);
    compareExpectedAndGenerated(expected, "extrafield.proto", generatedRootFolder, "simple.proto");
}
Also used : ModifyProtoConfiguration(no.entur.schema2proto.modifyproto.config.ModifyProtoConfiguration) NewField(no.entur.schema2proto.modifyproto.config.NewField) ArrayList(java.util.ArrayList) File(java.io.File) AbstractMappingTest(no.entur.schema2proto.AbstractMappingTest) Test(org.junit.jupiter.api.Test)

Example 3 with NewField

use of no.entur.schema2proto.modifyproto.config.NewField in project schema2proto by entur.

the class ModifyProtoTest method testAddField.

@Test
public void testAddField() throws IOException, InvalidProtobufException, InvalidConfigurationException {
    File expected = new File("src/test/resources/modify/expected/nopackagename").getCanonicalFile();
    File source = new File("src/test/resources/modify/input/nopackagename").getCanonicalFile();
    NewField newField = new NewField();
    newField.targetMessageType = "A";
    // newField.importProto = "importpackage/p.proto";
    newField.label = "repeated";
    newField.fieldNumber = 100;
    newField.name = "new_field";
    newField.type = "B";
    ModifyProtoConfiguration configuration = new ModifyProtoConfiguration();
    configuration.inputDirectory = source;
    configuration.newFields = Collections.singletonList(newField);
    modifyProto(configuration);
    compareExpectedAndGenerated(expected, "extrafield.proto", generatedRootFolder, "simple.proto");
}
Also used : ModifyProtoConfiguration(no.entur.schema2proto.modifyproto.config.ModifyProtoConfiguration) NewField(no.entur.schema2proto.modifyproto.config.NewField) File(java.io.File) AbstractMappingTest(no.entur.schema2proto.AbstractMappingTest) Test(org.junit.jupiter.api.Test)

Example 4 with NewField

use of no.entur.schema2proto.modifyproto.config.NewField in project schema2proto by entur.

the class ModifyProto method modifyProto.

public void modifyProto(ModifyProtoConfiguration configuration) throws IOException, InvalidProtobufException, InvalidConfigurationException {
    SchemaLoader schemaLoader = new SchemaLoader();
    // Collect source proto files (but not dependencies). Used to know which files should be written to .proto and which that should remain a dependency.
    Collection<File> protoFiles = FileUtils.listFiles(configuration.inputDirectory, new String[] { "proto" }, true);
    List<String> protosLoaded = protoFiles.stream().map(e -> configuration.inputDirectory.toURI().relativize(e.toURI()).getPath()).collect(Collectors.toList());
    for (String importRootFolder : configuration.customImportLocations) {
        schemaLoader.addSource(new File(configuration.basedir, importRootFolder).toPath());
    }
    schemaLoader.addSource(configuration.inputDirectory);
    for (Path s : schemaLoader.sources()) {
        LOGGER.info("Linking proto from path {}", s);
    }
    for (String s : schemaLoader.protos()) {
        LOGGER.info("Linking proto {}", s);
    }
    Schema schema = schemaLoader.load();
    // First run initial pruning, then look at the results and add referenced types from xsd.base_type
    IdentifierSet.Builder initialIdentifierSet = new IdentifierSet.Builder();
    initialIdentifierSet.exclude(configuration.excludes);
    initialIdentifierSet.include(configuration.includes);
    IdentifierSet finalIterationIdentifiers;
    if (configuration.includeBaseTypes) {
        finalIterationIdentifiers = followOneMoreLevel(initialIdentifierSet, schema);
    } else {
        finalIterationIdentifiers = initialIdentifierSet.build();
    }
    Schema prunedSchema = schema.prune(finalIterationIdentifiers);
    for (String s : finalIterationIdentifiers.unusedExcludes()) {
        LOGGER.warn("Unused exclude: {} (already excluded elsewhere or explicitly included?)", s);
    }
    for (String s : finalIterationIdentifiers.unusedIncludes()) {
        LOGGER.warn("Unused include: {} (already included elsewhere or explicitly excluded?) ", s);
    }
    for (NewField newField : configuration.newFields) {
        addField(newField, prunedSchema);
    }
    for (NewEnumConstant newEnumValue : configuration.newEnumConstants) {
        addEnumConstant(newEnumValue, prunedSchema);
    }
    for (MergeFrom mergeFrom : configuration.mergeFrom) {
        mergeFromFile(mergeFrom, prunedSchema, configuration);
    }
    for (FieldOption fieldOption : configuration.fieldOptions) {
        addFieldOption(fieldOption, prunedSchema);
    }
    Set<Boolean> possibleIncompatibilitiesDetected = new HashSet<>();
    if (configuration.protoLockFile != null) {
        try {
            ProtolockBackwardsCompatibilityChecker backwardsCompatibilityChecker = new ProtolockBackwardsCompatibilityChecker();
            backwardsCompatibilityChecker.init(configuration.protoLockFile);
            ImmutableList<ProtoFile> files = prunedSchema.protoFiles();
            files.stream().forEach(file -> possibleIncompatibilitiesDetected.add(backwardsCompatibilityChecker.resolveBackwardIncompatibilities(file)));
        } catch (FileNotFoundException e) {
            throw new InvalidConfigurationException("Could not find proto.lock file, check configuration");
        }
    }
    if (configuration.includeGoPackageOptions) {
        includeGoPackageNameOptions(prunedSchema.protoFiles(), configuration.goPackageSourcePrefix);
    }
    Set<String> emptyImportLocations = protosLoaded.stream().map(prunedSchema::protoFile).filter(Objects::nonNull).filter(this::isEmptyFile).map(p -> p.location().getPath()).collect(Collectors.toSet());
    protosLoaded.stream().map(prunedSchema::protoFile).filter(Objects::nonNull).filter(p -> !isEmptyFile(p)).forEach(file -> {
        file.imports().removeIf(emptyImportLocations::contains);
        file.publicImports().removeIf(emptyImportLocations::contains);
        File outputFile = new File(configuration.outputDirectory, file.location().getPath());
        outputFile.getParentFile().mkdirs();
        try (Writer writer = new FileWriter(outputFile)) {
            writer.write(file.toSchema());
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        LOGGER.info("Wrote file {}", outputFile.getPath());
    });
    if (configuration.failIfRemovedFields && possibleIncompatibilitiesDetected.contains(Boolean.TRUE)) {
        throw new BackwardsCompatibilityCheckException("Backwards incompatibilities detected. Check warnings messages above. To ignore warnings, rerun with -DfailIfRemovedFields=false");
    }
}
Also used : Schema(com.squareup.wire.schema.Schema) LoggerFactory(org.slf4j.LoggerFactory) OptionElement(com.squareup.wire.schema.internal.parser.OptionElement) MergeFrom(no.entur.schema2proto.modifyproto.config.MergeFrom) StringUtils(org.apache.commons.lang3.StringUtils) ArrayList(java.util.ArrayList) Yaml(org.yaml.snakeyaml.Yaml) HashSet(java.util.HashSet) Location(com.squareup.wire.schema.Location) ImmutableList(com.google.common.collect.ImmutableList) Type(com.squareup.wire.schema.Type) GoPackageNameHelper.packageNameToGoPackageName(no.entur.schema2proto.generateproto.GoPackageNameHelper.packageNameToGoPackageName) Path(java.nio.file.Path) InvalidConfigurationException(no.entur.schema2proto.InvalidConfigurationException) MessageType(com.squareup.wire.schema.MessageType) FieldOption(no.entur.schema2proto.modifyproto.config.FieldOption) OptionReader(com.squareup.wire.schema.internal.parser.OptionReader) NewField(no.entur.schema2proto.modifyproto.config.NewField) Logger(org.slf4j.Logger) Files(java.nio.file.Files) BackwardsCompatibilityCheckException(no.entur.schema2proto.compatibility.BackwardsCompatibilityCheckException) Constructor(org.yaml.snakeyaml.constructor.Constructor) ProtoFile(com.squareup.wire.schema.ProtoFile) Collection(java.util.Collection) FileWriter(java.io.FileWriter) SyntaxReader(com.squareup.wire.schema.internal.parser.SyntaxReader) Set(java.util.Set) IdentifierSet(com.squareup.wire.schema.IdentifierSet) IOException(java.io.IOException) FileUtils(org.apache.commons.io.FileUtils) Collectors(java.util.stream.Collectors) ProtolockBackwardsCompatibilityChecker(no.entur.schema2proto.compatibility.ProtolockBackwardsCompatibilityChecker) ModifyProtoConfiguration(no.entur.schema2proto.modifyproto.config.ModifyProtoConfiguration) File(java.io.File) FileNotFoundException(java.io.FileNotFoundException) EnumConstant(com.squareup.wire.schema.EnumConstant) NewEnumConstant(no.entur.schema2proto.modifyproto.config.NewEnumConstant) Objects(java.util.Objects) List(java.util.List) SchemaLoader(com.squareup.wire.schema.SchemaLoader) Writer(java.io.Writer) Optional(java.util.Optional) Field(com.squareup.wire.schema.Field) TypeDescription(org.yaml.snakeyaml.TypeDescription) Options(com.squareup.wire.schema.Options) EnumType(com.squareup.wire.schema.EnumType) InputStream(java.io.InputStream) SchemaLoader(com.squareup.wire.schema.SchemaLoader) MergeFrom(no.entur.schema2proto.modifyproto.config.MergeFrom) Schema(com.squareup.wire.schema.Schema) FileWriter(java.io.FileWriter) ProtoFile(com.squareup.wire.schema.ProtoFile) FileNotFoundException(java.io.FileNotFoundException) IdentifierSet(com.squareup.wire.schema.IdentifierSet) InvalidConfigurationException(no.entur.schema2proto.InvalidConfigurationException) NewField(no.entur.schema2proto.modifyproto.config.NewField) HashSet(java.util.HashSet) Path(java.nio.file.Path) FieldOption(no.entur.schema2proto.modifyproto.config.FieldOption) IOException(java.io.IOException) BackwardsCompatibilityCheckException(no.entur.schema2proto.compatibility.BackwardsCompatibilityCheckException) Objects(java.util.Objects) NewEnumConstant(no.entur.schema2proto.modifyproto.config.NewEnumConstant) ProtolockBackwardsCompatibilityChecker(no.entur.schema2proto.compatibility.ProtolockBackwardsCompatibilityChecker) ProtoFile(com.squareup.wire.schema.ProtoFile) File(java.io.File) FileWriter(java.io.FileWriter) Writer(java.io.Writer)

Aggregations

NewField (no.entur.schema2proto.modifyproto.config.NewField)4 File (java.io.File)3 ArrayList (java.util.ArrayList)3 ModifyProtoConfiguration (no.entur.schema2proto.modifyproto.config.ModifyProtoConfiguration)3 Field (com.squareup.wire.schema.Field)2 Location (com.squareup.wire.schema.Location)2 MessageType (com.squareup.wire.schema.MessageType)2 Options (com.squareup.wire.schema.Options)2 ProtoFile (com.squareup.wire.schema.ProtoFile)2 OptionElement (com.squareup.wire.schema.internal.parser.OptionElement)2 AbstractMappingTest (no.entur.schema2proto.AbstractMappingTest)2 Test (org.junit.jupiter.api.Test)2 ImmutableList (com.google.common.collect.ImmutableList)1 EnumConstant (com.squareup.wire.schema.EnumConstant)1 EnumType (com.squareup.wire.schema.EnumType)1 IdentifierSet (com.squareup.wire.schema.IdentifierSet)1 Schema (com.squareup.wire.schema.Schema)1 SchemaLoader (com.squareup.wire.schema.SchemaLoader)1 Type (com.squareup.wire.schema.Type)1 OptionReader (com.squareup.wire.schema.internal.parser.OptionReader)1