use of no.entur.schema2proto.compatibility.BackwardsCompatibilityCheckException in project schema2proto by entur.
the class ProtoSerializer method serialize.
public void serialize(Map<String, ProtoFile> packageToProtoFileMap, List<LocalType> localTypes) throws InvalidXSDException, IOException {
// Remove temporary generated name suffix
replaceGeneratedTypePlaceholder(packageToProtoFileMap, SchemaParser.GENERATED_NAME_PLACEHOLDER, SchemaParser.TYPE_SUFFIX);
// Sort types in files
sortTypesInProtofile(packageToProtoFileMap);
// Reorganize reused embedded types into global types referenced from the
moveReusedLocalTypesToGlobal(packageToProtoFileMap, localTypes);
// Remove unwanted fields
removeUnwantedFields(packageToProtoFileMap);
// Uppercase message names
uppercaseMessageNames(packageToProtoFileMap);
// Add options specified in config file
addConfigurationSpecifiedOptions(packageToProtoFileMap);
// Compute filenames based on package
computeFilenames(packageToProtoFileMap);
// Rewrite type information (replace xsd types with protobuf types/messages)
translateTypes(packageToProtoFileMap);
// Replace types with other. Opposed to translateTypes this method does not change MessageTypes, but only references from Fields
replaceTypes(packageToProtoFileMap);
// Compute imports
computeLocalImports(packageToProtoFileMap);
// Add imports specified in config file - IF they are actually in use
addConfigurationSpecifiedImports(packageToProtoFileMap);
// Find out if a file recursively imports itself
resolveRecursiveImports(packageToProtoFileMap);
// Handle cases where identical field name comes from both attribute and element (but with different case)
handleFieldNameCaseInsensitives(packageToProtoFileMap);
// Rename fields
translateFieldNames(packageToProtoFileMap);
// Combine field.packageName and field.Typename to field.packageName.typeName
moveFieldPackageNameToFieldTypeName(packageToProtoFileMap);
// Add leading '.' to field.elementType if applicable
addLeadingPeriodToElementType(packageToProtoFileMap);
// Adjust to naming standard
underscoreFieldNames(packageToProtoFileMap);
// Escape any field names identical to java reserved keywords
escapeReservedJavaKeywords(packageToProtoFileMap);
// Insert default value, prefix values and possibly escape values
updateEnumValues(packageToProtoFileMap);
// Add packed=true option to repeated enum or number fields
addPackedOptionToRepeatedFields(packageToProtoFileMap, true);
// Add go_package options to all files
if (configuration.includeGoPackageOptions) {
includeGoPackageNameOptions(packageToProtoFileMap);
}
// Try to resolve some backward incompatibilities based on protolock
boolean possibleIncompatibilitiesDetected = false;
if (configuration.protoLockFile != null) {
possibleIncompatibilitiesDetected = resolveBackwardIncompatibilities(packageToProtoFileMap);
}
// Sort fields by tag/id
sortFieldsByTag(packageToProtoFileMap);
// Run included linker to detect problems
// link(packageToProtoFileMap);
// Collect all written proto files for later parsing
List<File> writtenProtoFiles = new ArrayList<>();
if (configuration.outputFilename != null) {
if (packageToProtoFileMap.size() > 1) {
LOGGER.error("Source schema contains multiple namespaces but specifies a single output file");
throw new InvalidXSDException();
} else {
ProtoFile protoFile = packageToProtoFileMap.entrySet().iterator().next().getValue();
File destFolder = createPackageFolderStructure(configuration.outputDirectory, protoFile.packageName());
File outputFile = new File(destFolder, configuration.outputFilename.toLowerCase());
try (Writer writer = new FileWriter(outputFile)) {
writer.write(protoFile.toSchema());
}
writtenProtoFiles.add(outputFile);
}
} else {
for (Entry<String, ProtoFile> entry : packageToProtoFileMap.entrySet()) {
ProtoFile protoFile = entry.getValue();
File destFolder = createPackageFolderStructure(configuration.outputDirectory, protoFile.packageName());
File outputFile = new File(destFolder, protoFile.location().getPath().toLowerCase());
try (Writer writer = new FileWriter(outputFile)) {
writer.write(protoFile.toSchema());
}
writtenProtoFiles.add(outputFile);
}
}
// Parse and verify written proto files
parseWrittenFiles();
if (possibleIncompatibilitiesDetected && configuration.failIfRemovedFields) {
throw new BackwardsCompatibilityCheckException("Possible backwards incompatibility detected. See previous log messages. Re-run with option failIfRemovedFields=false if this is ok");
}
}
use of no.entur.schema2proto.compatibility.BackwardsCompatibilityCheckException 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");
}
}
Aggregations