use of org.infinispan.protostream.DescriptorParserException in project protostream by infinispan.
the class FileDescriptor method resolveDependencies.
private void resolveDependencies(ResolutionContext resolutionContext, Set<String> processedFiles) throws DescriptorParserException {
if (status == Status.PARSING_ERROR) {
resolutionContext.handleError(this, parsingException);
return;
}
if (status != Status.UNRESOLVED) {
return;
}
if (log.isDebugEnabled()) {
log.debugf("Resolving dependencies of %s", name);
}
try {
List<FileDescriptor> pubDeps = resolveImports(publicDependencies, resolutionContext, processedFiles);
List<FileDescriptor> deps = resolveImports(dependencies, resolutionContext, processedFiles);
if (status.isError()) {
// no point going further if any of the imported files have errors
return;
}
fileNamespace = new FileNamespace(this, pubDeps, deps);
for (FileDescriptor fd : pubDeps) {
fd.dependants.put(name, this);
}
for (FileDescriptor fd : deps) {
fd.dependants.put(name, this);
}
for (Descriptor desc : messageTypes) {
collectDescriptors(desc, resolutionContext);
}
for (EnumDescriptor enumDesc : enumTypes) {
collectEnumDescriptors(enumDesc, resolutionContext);
}
for (ExtendDescriptor extendDescriptor : extendTypes) {
collectExtensions(extendDescriptor);
}
for (Descriptor descriptor : messageTypes) {
resolveFieldTypes(descriptor);
}
for (ExtendDescriptor extendDescriptor : extendTypes) {
resolveExtension(extendDescriptor);
}
status = Status.RESOLVED;
resolutionContext.flush();
resolutionContext.handleSuccess(this);
} catch (DescriptorParserException dpe) {
resolutionContext.handleError(this, dpe);
} catch (Exception e) {
resolutionContext.handleError(this, new DescriptorParserException(e));
} finally {
if (status != Status.RESOLVED) {
resolutionContext.clear();
}
}
}
use of org.infinispan.protostream.DescriptorParserException in project protostream by infinispan.
the class FileDescriptor method resolveImports.
/**
* Resolves imported file names to {@link FileDescriptor}s. Changes the status of current file to ERROR if any of the
* imported files (directly or indirectly) have any errors.
*
* @return the list of resolved {@link FileDescriptor}s
*/
private List<FileDescriptor> resolveImports(List<String> dependencies, ResolutionContext resolutionContext, Set<String> processedFiles) throws DescriptorParserException {
List<FileDescriptor> fileDescriptors = new ArrayList<>(dependencies.size());
Set<String> uniqueDependencies = new HashSet<>(dependencies.size());
for (String dependency : dependencies) {
if (!uniqueDependencies.add(dependency)) {
resolutionContext.handleError(this, new DescriptorParserException("Duplicate import : " + dependency));
continue;
}
FileDescriptor fd = resolutionContext.getFileDescriptorMap().get(dependency);
if (fd == null) {
resolutionContext.handleError(this, new DescriptorParserException("Import '" + dependency + "' not found"));
continue;
}
if (fd.status == Status.UNRESOLVED) {
if (!processedFiles.add(dependency)) {
resolutionContext.handleError(this, new DescriptorParserException("Cyclic import detected at " + name + ", import " + dependency));
continue;
}
fd.resolveDependencies(resolutionContext, processedFiles);
}
if (fd.status.isError()) {
resolutionContext.handleError(this, new DescriptorParserException("File " + name + " imports a file (" + fd.getName() + ") that has errors"));
continue;
}
fileDescriptors.add(fd);
}
return fileDescriptors;
}
use of org.infinispan.protostream.DescriptorParserException in project protostream by infinispan.
the class SquareProtoParser method parse.
/**
* Parses a set of .proto files but does not resolve type dependencies and does not detect semantic errors like
* duplicate type definitions. If the {@link FileDescriptorSource} parameter does not include a progress callback
* parsing will stop on first encountered error. If a callback exists all files will be processed; only one error per
* file is reported and parsing will continue with the next file.
*
* @param fileDescriptorSource the set of descriptors to parse
* @return a map of successfully parsed {@link FileDescriptor} objects keyed by with their names
* @throws DescriptorParserException if parsing errors were encountered and no progress callback was specified in the
* {@link FileDescriptorSource}
*/
public Map<String, FileDescriptor> parse(FileDescriptorSource fileDescriptorSource) throws DescriptorParserException {
Map<String, String> input = fileDescriptorSource.getFiles();
Map<String, FileDescriptor> fileDescriptorMap = new LinkedHashMap<>(input.size());
for (Map.Entry<String, String> entry : input.entrySet()) {
String fileName = entry.getKey();
try {
ProtoFile protoFile = ProtoParser.parse(fileName, new StringReader(entry.getValue()));
checkUniqueFileOptions(protoFile);
FileDescriptor fileDescriptor = PROTOFILE_MAPPER.map(protoFile);
fileDescriptor.setConfiguration(configuration);
fileDescriptorMap.put(fileName, fileDescriptor);
} catch (DescriptorParserException e) {
reportParsingError(fileDescriptorSource, fileDescriptorMap, fileName, e);
} catch (IOException | RuntimeException e) {
reportParsingError(fileDescriptorSource, fileDescriptorMap, fileName, new DescriptorParserException(e));
}
}
return fileDescriptorMap;
}
use of org.infinispan.protostream.DescriptorParserException in project protostream by infinispan.
the class SerializationContextImplTest method testRegisterProtoFiles.
@Test
public void testRegisterProtoFiles() {
SerializationContext ctx = createContext();
String file1 = "syntax = \"proto3\";\n" + "package p;\n" + "message A {\n" + " optional int32 f1 = 1;\n" + "}";
String file2 = "package org.infinispan;\n" + "import \"file1.proto\";\n" + "message B {\n" + " required b.A ma = 1;\n" + "}";
Map<String, DescriptorParserException> failed = new HashMap<>();
List<String> successful = new ArrayList<>();
FileDescriptorSource fileDescriptorSource = new FileDescriptorSource().addProtoFile("file1.proto", file1).addProtoFile("file2.proto", file2).withProgressCallback(new FileDescriptorSource.ProgressCallback() {
@Override
public void handleError(String fileName, DescriptorParserException exception) {
failed.put(fileName, exception);
}
@Override
public void handleSuccess(String fileName) {
successful.add(fileName);
}
});
ctx.registerProtoFiles(fileDescriptorSource);
assertEquals(1, failed.size());
assertEquals(1, successful.size());
DescriptorParserException exception = failed.get("file2.proto");
assertNotNull(exception);
assertEquals("Failed to resolve type of field \"org.infinispan.B.ma\". Type not found : b.A", exception.getMessage());
assertTrue(successful.contains("file1.proto"));
Map<String, FileDescriptor> fileDescriptors = ctx.getFileDescriptors();
assertEquals(3, fileDescriptors.size());
FileDescriptor fd1 = fileDescriptors.get("file1.proto");
assertNotNull(fd1);
assertEquals(1, fd1.getTypes().size());
assertTrue(fd1.getTypes().containsKey("p.A"));
FileDescriptor fd2 = fileDescriptors.get("file2.proto");
assertNotNull(fd2);
try {
fd2.getTypes();
fail("IllegalStateException expected");
} catch (IllegalStateException e) {
assertEquals("File 'file2.proto' is not resolved yet", e.getMessage());
}
}
use of org.infinispan.protostream.DescriptorParserException in project protostream by infinispan.
the class SerializationContextImplTest method testFileCanExistWithSemanticErrors.
@Test
public void testFileCanExistWithSemanticErrors() {
SerializationContext ctx = createContext();
FileDescriptorSource source = FileDescriptorSource.fromString("file1.proto", "import \"no_such_file.proto\";");
try {
ctx.registerProtoFiles(source);
fail("DescriptorParserException expected");
} catch (DescriptorParserException e) {
assertEquals("Import 'no_such_file.proto' not found", e.getMessage());
}
FileDescriptor fileDescriptor = ctx.getFileDescriptors().get("file1.proto");
assertNotNull(fileDescriptor);
assertFalse(fileDescriptor.isResolved());
}
Aggregations