-
Notifications
You must be signed in to change notification settings - Fork 39
fix: accumulate protobuf descriptors #192
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -49,10 +49,8 @@ object DescriptorSet { | |
| @SuppressWarnings(Array("org.wartremover.warts.Throw")) | ||
| def fileDescriptors( | ||
| file: File | ||
| ): Either[CannotOpen, Iterable[Either[ReadFailure, Descriptors.FileDescriptor]]] = | ||
| Using[FileInputStream, Either[CannotOpen, Iterable[ | ||
| Either[ReadFailure, Descriptors.FileDescriptor] | ||
| ]]]( | ||
| ): Either[CannotOpen, Either[ReadFailure, Iterable[Descriptors.FileDescriptor]]] = | ||
| Using[FileInputStream, Either[CannotOpen, Either[ReadFailure, Iterable[Descriptors.FileDescriptor]]]]( | ||
| new FileInputStream(file) | ||
| ) { fis => | ||
| val registry = ExtensionRegistry.newInstance() | ||
|
|
@@ -64,15 +62,12 @@ object DescriptorSet { | |
| val descriptorProtos = | ||
| DescriptorProtos.FileDescriptorSet.parseFrom(fis, registry).getFileList.asScala | ||
|
|
||
| for (descriptorProto <- descriptorProtos) | ||
| yield try Right(Descriptors.FileDescriptor.buildFrom(descriptorProto, Array.empty, true)) | ||
| catch { | ||
| case e: Descriptors.DescriptorValidationException => | ||
| Left(CannotValidate(e)) | ||
| } | ||
| val empty: Either[ReadFailure, Iterable[Descriptors.FileDescriptor]] = | ||
| Right(Array[Descriptors.FileDescriptor]()) | ||
| descriptorProtos.foldLeft(empty)((acc, file) => accumulatedBuildFrom(acc, file)) | ||
| } catch { | ||
| case e: IOException => | ||
| List(Left(CannotRead(e))) | ||
| Left(CannotRead(e)) | ||
| }) | ||
| } match { | ||
| case Success(result) => result | ||
|
|
@@ -83,4 +78,28 @@ object DescriptorSet { | |
| private val descriptorslogger = Logger.getLogger(classOf[Descriptors].getName) | ||
| descriptorslogger.setLevel(Level.OFF); // Silence protobuf | ||
|
|
||
| /** | ||
| * This method accumulates `FileDescriptor`s to provide | ||
| * all the necessary dependencies for each call to FileDescriptor.buildFrom. | ||
| * Otherwise placeholders (mocked references) get created instead and | ||
| * these can't function as proper dependencies. Chiefly as imports. | ||
| * | ||
| * see allowUnknownDependencies per https://github.com/protocolbuffers/protobuf/blob/ae26a81918fa9e16f64ac27b5a2fb2b110b7aa1b/java/core/src/main/java/com/google/protobuf/Descriptors.java#L286 | ||
| **/ | ||
| private def accumulatedBuildFrom( | ||
| reads: Either[ReadFailure, Iterable[Descriptors.FileDescriptor]], | ||
| file: DescriptorProtos.FileDescriptorProto | ||
| ): Either[ReadFailure, Iterable[Descriptors.FileDescriptor]] = { | ||
| reads match { | ||
| case Left(_) => reads | ||
| case Right(fileDescriptors) => | ||
| try { | ||
| Right(fileDescriptors ++ List(Descriptors.FileDescriptor.buildFrom(file, fileDescriptors.toArray, true))) | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. So we have to pass 'depended-upon' descriptors when parsing 'depending' descriptors - meaning the files must be accumulated in the 'right order'. How do we make sure they are in the right order?
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not sure they have to be in the right order, but maybe we should
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Whatever descriptor is the first one will be called with an empty
I'm not sure, I guess you could have unknown dependencies (like external proto annotations that we don't care about) that we could allow?
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This comment is what I expected, but the API doesn't seem to allow us to first accumulate the descriptors and after that trigger linking. I assume |
||
| } catch { | ||
| case e: Descriptors.DescriptorValidationException => | ||
| Left(CannotValidate(e)) | ||
| } | ||
| } | ||
| } | ||
|
|
||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So now if we fail to read one file we throw away all results? That might be OK if we're sure we need all of them anyway
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We bail out on any error now, before it could live with certain descriptors failing.